41constexpr int DEFAULT_NEVENTS = 1000;
42constexpr int DEFAULT_SEED = 123456789;
43constexpr int DEFAULT_LATITUDINAL_DETS = 5;
44constexpr int DEFAULT_LONGITUDINAL_DETS = 10;
47inline double toWavelength(
double energy) {
48 static const double factor =
50 return factor / sqrt(
energy);
53struct EFixedProvider {
64 return m_expt.getEFixed(detID);
88 auto wsValidator = std::make_shared<CompositeValidator>();
93 "The name of the input workspace. The input workspace must "
94 "have X units of wavelength.");
96 "The name to use for the output workspace.");
98 auto positiveInt = std::make_shared<Kernel::BoundedValidator<int>>();
99 positiveInt->setLower(1);
100 declareProperty(
"NumberOfWavelengthPoints",
EMPTY_INT(), positiveInt,
101 "The number of wavelength points for which a simulation is "
102 "attempted if ResimulateTracksForDifferentWavelengths=true");
103 declareProperty(
"EventsPerPoint", DEFAULT_NEVENTS, positiveInt,
104 "The number of \"neutron\" events to generate per simulated point");
105 declareProperty(
"SeedValue", DEFAULT_SEED, positiveInt,
"Seed the random number generator with this value");
107 auto interpolateOpt = createInterpolateOption();
108 declareProperty(interpolateOpt->property(), interpolateOpt->propertyDoc());
109 declareProperty(
"SparseInstrument",
false,
110 "Enable simulation on special "
111 "instrument with a sparse grid of "
112 "detectors interpolating the "
113 "results to the real instrument.");
114 auto threeOrMore = std::make_shared<Kernel::BoundedValidator<int>>();
115 threeOrMore->setLower(3);
116 declareProperty(
"NumberOfDetectorRows", DEFAULT_LATITUDINAL_DETS, threeOrMore,
117 "Number of detector rows in the detector grid of the sparse instrument.");
118 setPropertySettings(
"NumberOfDetectorRows",
119 std::make_unique<EnabledWhenProperty>(
"SparseInstrument", ePropertyCriterion::IS_NOT_DEFAULT));
120 auto twoOrMore = std::make_shared<Kernel::BoundedValidator<int>>();
121 twoOrMore->setLower(2);
122 declareProperty(
"NumberOfDetectorColumns", DEFAULT_LONGITUDINAL_DETS, twoOrMore,
123 "Number of detector columns in the detector grid "
124 "of the sparse instrument.");
125 setPropertySettings(
"NumberOfDetectorColumns",
126 std::make_unique<EnabledWhenProperty>(
"SparseInstrument", ePropertyCriterion::IS_NOT_DEFAULT));
130 declareProperty(
"MaxScatterPtAttempts", 5000, positiveInt,
131 "Maximum number of tries made to generate a scattering point "
132 "within the sample (+ optional container etc). Objects with "
133 "holes in them, e.g. a thin annulus can cause problems "
134 "if this number is too low.\n"
135 "If a scattering point cannot be generated by increasing "
136 "this value then there is most likely a problem with "
137 "the sample geometry.");
138 declareProperty(
"ResimulateTracksForDifferentWavelengths",
false,
"Resimulate tracks for each wavelength point.");
139 setPropertySettings(
"NumberOfWavelengthPoints",
140 std::make_unique<EnabledWhenProperty>(
"ResimulateTracksForDifferentWavelengths",
141 ePropertyCriterion::IS_NOT_DEFAULT));
142 auto scatteringOptionValidator = std::make_shared<StringListValidator>();
143 scatteringOptionValidator->addAllowedValue(
"SampleAndEnvironment");
144 scatteringOptionValidator->addAllowedValue(
"SampleOnly");
145 scatteringOptionValidator->addAllowedValue(
"EnvironmentOnly");
146 declareProperty(
"SimulateScatteringPointIn",
"SampleAndEnvironment",
147 "Simulate the scattering point in the vicinity of the sample or its "
148 "environment or both (default).",
149 scatteringOptionValidator);
158 const bool resimulateTracks =
getProperty(
"ResimulateTracksForDifferentWavelengths");
162 const bool useSparseInstrument =
getProperty(
"SparseInstrument");
163 const int maxScatterPtAttempts =
getProperty(
"MaxScatterPtAttempts");
165 const auto pointsInProperty =
getPropertyValue(
"SimulateScatteringPointIn");
166 if (pointsInProperty ==
"SampleOnly") {
168 }
else if (pointsInProperty ==
"EnvironmentOnly") {
171 auto outputWS =
doSimulation(*inputWS,
static_cast<size_t>(nevents), resimulateTracks, seed, interpolateOpt,
172 useSparseInstrument,
static_cast<size_t>(maxScatterPtAttempts), simulatePointsIn);
173 setProperty(
"OutputWorkspace", std::move(outputWS));
181 std::map<std::string, std::string> issues;
182 const bool resimulateTracksForDiffWavelengths =
getProperty(
"ResimulateTracksForDifferentWavelengths");
184 if (resimulateTracksForDiffWavelengths) {
185 const int nlambda =
getProperty(
"NumberOfWavelengthPoints");
188 interpOpt.
set(interpValue,
true, resimulateTracksForDiffWavelengths);
190 if (!nlambdaIssue.empty()) {
191 issues[
"NumberOfWavelengthPoints"] = nlambdaIssue;
211std::shared_ptr<IMCAbsorptionStrategy>
214 const size_t nevents,
const size_t maxScatterPtAttempts,
215 const bool regenerateTracksForEachLambda) {
216 return std::make_shared<MCAbsorptionStrategy>(interactionVol, beamProfile, EMode, nevents, maxScatterPtAttempts,
217 regenerateTracksForEachLambda);
230 const size_t wavelengthPoints,
231 const size_t rows,
const size_t columns) {
232 auto sparseWS = std::make_shared<SparseWorkspace>(modelWS, wavelengthPoints, rows, columns);
242 auto interpolationOpt = std::make_unique<InterpolationOption>();
243 return interpolationOpt;
261 const bool resimulateTracksForDiffWavelengths,
const int seed,
263 const bool useSparseInstrument,
264 const size_t maxScatterPtAttempts,
267 const auto inputNbins =
static_cast<int>(inputWS.
blocksize());
270 if (resimulateTracksForDiffWavelengths) {
272 if (
isEmpty(nlambda) || nlambda > inputNbins) {
274 g_log.
warning() <<
"The requested number of wavelength points is larger "
275 "than the spectra size. "
276 "Defaulting to spectra size.\n";
278 nlambda = inputNbins;
281 nlambda = inputNbins;
284 if (useSparseInstrument) {
285 const int latitudinalDets =
getProperty(
"NumberOfDetectorRows");
286 const int longitudinalDets =
getProperty(
"NumberOfDetectorColumns");
289 MatrixWorkspace &simulationWS = useSparseInstrument ? *sparseWS : *outputWS;
290 const MatrixWorkspace &instrumentWS = useSparseInstrument ? simulationWS : inputWS;
295 EFixedProvider
efixed(instrumentWS);
299 Progress prog(
this, 0.0, 1.0, nhists);
301 const std::string reportMsg =
"Computing corrections";
305 bool hasGaugeVol =
false;
311 }
catch (
const std::exception &) {
318 g_log.
warning(
"Gauge Volume found. Scattering Points limited to Sample Only.");
324 std::shared_ptr<IMCInteractionVolume> interactionVolume =
329 std::shared_ptr<IMCAbsorptionStrategy> strategy =
330 createStrategy(std::move(interactionVolume), *beamProfile,
efixed.emode(), nevents, maxScatterPtAttempts,
331 resimulateTracksForDiffWavelengths);
336 for (int64_t i = 0; i < nhists; ++i) {
339 auto &outE = simulationWS.
mutableE(i);
343 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMasked(i)) {
347 const auto &detPos = spectrumInfo.position(i);
348 const double lambdaFixed = toWavelength(
efixed.value(spectrumInfo.detector(i).getID()));
351 const auto lambdas = simulationWS.
points(i).rawData();
353 const auto nbins = lambdas.size();
354 const size_t lambdaStepSize = nbins / nlambda;
356 std::vector<double> packedLambdas;
357 std::vector<double> packedAttFactors;
358 std::vector<double> packedAttFactorErrors;
360 for (
size_t j = 0; j < nbins; j += lambdaStepSize) {
361 packedLambdas.push_back(lambdas[j]);
362 packedAttFactors.push_back(0);
363 packedAttFactorErrors.push_back(0);
365 if (lambdaStepSize > 1 && j + lambdaStepSize >= nbins && j + 1 != nbins) {
366 j = nbins - lambdaStepSize - 1;
371 strategy->calculate(rng, detPos, packedLambdas, lambdaFixed, packedAttFactors, packedAttFactorErrors,
374 if (
g_log.
is(Kernel::Logger::Priority::PRIO_DEBUG)) {
378 for (
size_t j = 0; j < packedLambdas.size(); j++) {
379 auto idx = simulationWS.
yIndexOfX(packedLambdas[j], i);
387 if (!useSparseInstrument && lambdaStepSize > 1) {
388 auto histnew = simulationWS.
histogram(i);
390 if (lambdaStepSize < nbins) {
393 std::fill(histnew.mutableY().begin() + 1, histnew.mutableY().end(), histnew.y()[0]);
395 outputWS->setHistogram(i, histnew);
404 if (useSparseInstrument) {
415 outputWS->setDistribution(
true);
416 outputWS->setYUnit(
"");
417 outputWS->setYUnitLabel(
"Attenuation factor");
424 const auto refFrame = targetWS.
getInstrument()->getReferenceFrame();
426 for (int64_t i = 0; i < static_cast<decltype(i)>(spectrumInfo.size()); ++i) {
428 if (spectrumInfo.hasDetectors(i)) {
430 std::tie(lat, lon) = spectrumInfo.geographicalAngles(i);
432 if (spatiallyInterpHisto.size() > 1) {
433 auto targetHisto = targetWS.
histogram(i);
434 interpOpt.
applyInPlace(spatiallyInterpHisto, targetHisto);
437 targetWS.
mutableY(i) = spatiallyInterpHisto.y().front();
const std::string & m_value
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
This class is shared by a few Workspace types and holds information related to a particular experimen...
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
const Run & run() const
Run details object access.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
const Sample & sample() const
Sample accessors.
virtual MantidVec & dataY()=0
virtual MantidVec & dataE()=0
A validator which checks that a workspace has a valid instrument.
Kernel::Property * getProperty(const std::string &name) const
Returns the named property as a pointer.
Base MatrixWorkspace Abstract Class.
virtual ISpectrum & getSpectrum(const size_t index)=0
Return the underlying ISpectrum ptr at the given workspace index.
HistogramData::Points points(const size_t index) const
virtual std::size_t blocksize() const =0
Returns the size of each block of data returned by the dataY accessors.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
void setHistogram(const size_t index, T &&...data) &
std::size_t yIndexOfX(const double xValue, const std::size_t &index=0, const double tolerance=0.0) const
Returns the y index which corresponds to the X Value provided.
HistogramData::Histogram histogram(const size_t index) const
Returns the Histogram at the given workspace index.
HistogramData::HistogramE & mutableE(const size_t index) &
HistogramData::HistogramY & mutableY(const size_t index) &
Helper class for reporting progress from algorithms.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
static std::unique_ptr< IBeamProfile > createBeamProfile(const Geometry::Instrument &instrument, const API::Sample &sample)
Base class for all classes defining a beam profile.
Class to provide a consistent interface to an interpolation option on algorithms.
std::string validateInputSize(const size_t size) const
Validate the size of input histogram.
void applyInPlace(const HistogramData::Histogram &in, HistogramData::Histogram &out) const
Apply the interpolation method to the output histogram.
void set(const Value &kind, const bool calculateErrors, const bool independentErrors)
Set the interpolation option.
void applyInplace(HistogramData::Histogram &inOut, size_t stepSize) const
Apply the interpolation method to the given histogram.
Stores statistics relating to the tracks generated in MCInteractionVolume for a specific detector.
std::string generateScatterPointStats()
Log a debug string summarising which parts of the environment the simulated scatter points occurred i...
static std::shared_ptr< IMCInteractionVolume > create(const API::Sample &sample, const size_t maxScatterAttempts=5000, const ScatteringPointVicinity pointsIn=ScatteringPointVicinity::SAMPLEANDENVIRONMENT, Geometry::IObject_sptr gaugeVolume=nullptr)
Factory Method for constructing the volume encompassing the sample + any environment kit.
Calculates attenuation due to absorption and scattering in a sample + its environment using a Monte C...
virtual std::shared_ptr< IMCAbsorptionStrategy > createStrategy(std::shared_ptr< IMCInteractionVolume > interactionVol, const IBeamProfile &beamProfile, Kernel::DeltaEMode::Type EMode, const size_t nevents, const size_t maxScatterPtAttempts, const bool regenerateTracksForEachLambda)
Factory method to return an instance of the required absorption strategy class.
void exec() override
Execution code.
void interpolateFromSparse(API::MatrixWorkspace &targetWS, const SparseWorkspace &sparseWS, const Mantid::Algorithms::InterpolationOption &interpOpt)
virtual std::shared_ptr< SparseWorkspace > createSparseWorkspace(const API::MatrixWorkspace &modelWS, const size_t wavelengthPoints, const size_t rows, const size_t columns)
Factory method to return an instance of the required SparseInstrument class.
API::MatrixWorkspace_uptr doSimulation(const API::MatrixWorkspace &inputWS, const size_t nevents, const bool simulateTracksForEachWavelength, const int seed, const InterpolationOption &interpolateOpt, const bool useSparseInstrument, const size_t maxScatterPtAttempts, MCInteractionVolume::ScatteringPointVicinity pointsIn)
Run the simulation over the whole input workspace.
API::MatrixWorkspace_uptr createOutputWorkspace(const API::MatrixWorkspace &inputWS) const
std::map< std::string, std::string > validateInputs() override
Validate the input properties.
virtual std::unique_ptr< InterpolationOption > createInterpolateOption()
Factory method to return an instance of the required InterpolationOption class.
Defines functions and utilities to create and deal with sparse instruments.
virtual HistogramData::Histogram bilinearInterpolateFromDetectorGrid(const double lat, const double lon) const
Spatially interpolate a single histogram from nearby detectors using bilinear interpolation method.
Concrete workspace implementation.
Class originally intended to be used with the DataHandling 'LoadInstrument' algorithm.
std::shared_ptr< CSGObject > createShape(Poco::XML::Element *pElem)
Creates a geometric object from a DOM-element-node pointing to an element whose child nodes contain t...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
bool is(int level) const
Returns true if at least the given log level is set.
This implements the Mersenne Twister 19937 pseudo-random number generator algorithm as a specialzatio...
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
void setNotifyStep(double notifyStepPct)
Override the frequency at which notifications are sent out.
virtual std::string value() const =0
Returns the value of the property as a string.
std::unique_ptr< MatrixWorkspace > MatrixWorkspace_uptr
unique pointer to Mantid::API::MatrixWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< SparseWorkspace > SparseWorkspace_sptr
std::shared_ptr< IObject > IObject_sptr
Typdef for a shared pointer.
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
A namespace containing physical constants that are required by algorithms and unit routines.
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h
Planck constant in J*s.
static constexpr double meV
1 meV in Joules.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
int32_t detid_t
Typedef for a detector ID.
Type
Define the available energy transfer modes It is important to assign enums proper numbers,...
@ Input
An input workspace.
@ Output
An output workspace.