39constexpr int DEFAULT_NEVENTS = 1000;
40constexpr int DEFAULT_SEED = 123456789;
41constexpr int NLAMBDA = 1;
50 "An input/output peaks workspace that the path distances will be added "
52 declareProperty(
"UseSinglePath",
false,
"Use a single path with a scatter point at the sample position.");
53 auto positiveInt = std::make_shared<Kernel::BoundedValidator<int>>();
54 positiveInt->setLower(1);
56 "The number of \"neutron\" events to generate per peak");
57 declareProperty(
"SeedValue", DEFAULT_SEED, positiveInt,
"Seed the random number generator with this value");
59 "Maximum number of tries made to generate a scattering point "
60 "within the sample. Objects with "
61 "holes in them, e.g. a thin annulus can cause problems "
62 "if this number is too low.\n"
63 "If a scattering point cannot be generated by increasing "
64 "this value then there is most likely a problem with "
65 "the sample geometry.");
67 std::make_unique<EnabledWhenProperty>(
"UseSinglePath", ePropertyCriterion::IS_DEFAULT));
69 std::make_unique<EnabledWhenProperty>(
"UseSinglePath", ePropertyCriterion::IS_DEFAULT));
71 std::make_unique<EnabledWhenProperty>(
"UseSinglePath", ePropertyCriterion::IS_DEFAULT));
73 "Calculate the attenuation/transmission and apply it to the integrated intensity and uncertainty.");
78 std::map<std::string, std::string> issues;
79 auto sample = inputWS->sample();
80 if (!sample.hasShape()) {
81 issues[
"InputWorkspace"] =
"Input workspace does not have a sample shape";
83 if (inputWS->sample().hasEnvironment()) {
84 issues[
"InputWorkspace"] =
"Sample must not have a sample environment";
87 if (inputWS->sample().getMaterial().numberDensity() == 0) {
88 issues[
"InputWorkspace"] =
"Sample must have a material set up with a non-zero number density";
101 const int maxScatterPtAttempts =
getProperty(
"MaxScatterPtAttempts");
104 if (!inputWS->getInstrument()->hasSource()) {
107 detector->
setPos(0.0, 0.0, 0.0);
109 inst->markAsDetector(detector);
111 source->
setPos(0.0, 0.0, -1.0);
113 inst->markAsSource(source);
114 inputWS->setInstrument(inst);
117 auto instrument = inputWS->getInstrument();
121 std::shared_ptr<IMCInteractionVolume> interactionVol =
126 bool applyCorrection =
getProperty(
"ApplyCorrection");
127 const auto npeaks = inputWS->getNumberPeaks();
130 Progress prog(
this, 0.0, 1.0, npeaks);
132 const std::string reportMsg =
"Computing path lengths";
135 for (
int i = 0; i < npeaks; ++i) {
137 IPeak &peak = inputWS->getPeak(i);
140 std::vector<double> lambdas{peakWavelength}, absFactors(NLAMBDA);
142 const auto R = peak.getGoniometerMatrix();
143 const auto sourcePos = R * peak.getSourceDirectionSampleFrame();
144 const auto detectorPos = R * peak.getDetectorDirectionSampleFrame();
145 const auto samplePos = peak.getSamplePos();
148 const auto reverseBeamDir =
normalize(samplePos - sourcePos);
149 const IObject *sampleShape = &(inputWS->sample().getShape());
151 Track beforeScatter(samplePos, reverseBeamDir);
153 const auto detDir =
normalize(detectorPos - samplePos);
154 Track afterScatter(samplePos, detDir);
163 detID = peak.getDetectorID();
168 std::vector<double> absFactorErrors(NLAMBDA);
169 strategy.
calculate(rng, detectorPos, lambdas, peakWavelength, absFactors, absFactorErrors, detStatistics);
171 if (
g_log.
is(Kernel::Logger::Priority::PRIO_DEBUG)) {
176 double mu = inputWS->sample().getMaterial().attenuationCoefficient(peakWavelength);
177 double absWeightedPathLength = -log(absFactors[0]) /
mu;
178 peak.setAbsorptionWeightedPathLength(absWeightedPathLength * 100);
179 if (applyCorrection) {
180 peak.setIntensity(peak.getIntensity() / absFactors[0]);
181 peak.setSigmaIntensity(peak.getSigmaIntensity() / absFactors[0]);
#define DECLARE_ALGORITHM(classname)
#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.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Helper class for reporting progress from algorithms.
A property class for workspaces.
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
void init() override
Initialise the properties.
void exec() override
Run the algorithm.
static std::unique_ptr< IBeamProfile > createBeamProfile(const Geometry::Instrument &instrument, const API::Sample &sample)
Implements the algorithm for calculating the correction factor for self-attenuation and single wavele...
virtual void calculate(Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &finalPos, const std::vector< double > &lambdas, const double lambdaFixed, std::vector< double > &attenuationFactors, std::vector< double > &attFactorErrors, MCInteractionStatistics &stats) override
Compute the correction for a final position of the neutron and wavelengths before and after scatterin...
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.
void setPos(double, double, double) override
Set the IComponent position, x, y, z respective to parent (if present)
This class represents a detector - i.e.
IObject : Interface for geometry objects.
virtual int interceptSurface(Geometry::Track &) const =0
Structure describing a single-crystal peak.
virtual double getWavelength() const =0
Object Component class, this class brings together the physical attributes of the component to the po...
Defines a track as a start point and a direction.
virtual double calculateAttenuation(double lambda) const
Calculate attenuation across all links.
Marks code as not implemented yet.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug 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.
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
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.
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
@ InOut
Both an input & output workspace.