22#include "MantidHistogramData/Interpolate.h"
30using namespace Geometry;
31using namespace Kernel;
34using HistogramData::interpolateLinearInplace;
40constexpr int64_t MAX_INTEGRATION_LENGTH{1000};
42static constexpr double RAD2DEG = 180.0 / M_PI;
44inline int64_t findMiddle(
const int64_t start,
const int64_t stop) {
45 auto half =
static_cast<int64_t
>(floor(.5 * (
static_cast<double>(stop - start))));
49inline size_t calcLinearIdxFromUpperTriangular(
const size_t N,
const size_t row_idx,
const size_t col_idx) {
52 assert(row_idx < col_idx);
53 return N * (N - 1) / 2 - (N - row_idx) * (N - row_idx - 1) / 2 + col_idx - row_idx - 1;
57inline const V3D getDirection(
const V3D &posInitial,
const V3D &posFinal) {
return normalize(posFinal - posInitial); }
60inline double getDistanceInsideObject(
const IObject &shape,
Track &track) {
68inline double checkzero(
const double x) {
return std::abs(
x) < std::numeric_limits<float>::min() ? 0.0 :
x; }
77 auto wsValidator = std::make_shared<CompositeValidator>();
84 "The X values for the input workspace must be in units of wavelength");
86 auto positiveInt = std::make_shared<BoundedValidator<int64_t>>();
87 positiveInt->setLower(1);
89 "The number of wavelength points for which the numerical integral is\n"
90 "calculated (default: all points)");
92 auto moreThanZero = std::make_shared<BoundedValidator<double>>();
93 moreThanZero->setLower(0.001);
94 declareProperty(
"ElementSize", 1.0, moreThanZero,
"The size of one side of an integration element cube in mm");
97 "The size of one side of an integration element cube in mm for container."
98 "Default to be the same as ElementSize.");
100 std::vector<std::string> methodOptions{
"SampleOnly",
"SampleAndContainer"};
101 declareProperty(
"Method",
"SampleOnly", std::make_shared<StringListValidator>(methodOptions),
102 "Correction method, use either SampleOnly or SampleAndContainer.");
105 "Output workspace name. "
106 "A Workspace2D containing the correction matrix that can be directly applied to the corresponding "
107 "Event workspace for multiple scattering correction.");
116 std::map<std::string, std::string> result;
122 const auto &sample =
m_inputWS->sample();
123 if (!sample.getShape().hasValidShape()) {
124 result[
"InputWorkspace"] =
"The input workspace must have a valid sample shape";
129 if (method ==
"SampleAndContainer") {
130 const auto &containerShape =
m_inputWS->sample().getEnvironment().getContainer();
131 if (!containerShape.hasValidShape()) {
132 result[
"Method"] =
"SampleAndContainer requires a valid container shape.";
149 if (method ==
"SampleOnly") {
154 ws_sampleOnly->setYUnit(
"");
155 ws_sampleOnly->setDistribution(
true);
156 ws_sampleOnly->setYUnitLabel(
"Multiple Scattering Correction factor");
158 const auto &sampleShape =
m_inputWS->sample().getShape();
161 const std::string outWSName =
getProperty(
"OutputWorkspace");
162 std::vector<std::string> names;
163 names.emplace_back(outWSName +
"_sampleOnly");
168 group->setProperty(
"InputWorkspaces", names);
169 group->setProperty(
"OutputWorkspace", outWSName);
177 }
else if (method ==
"SampleAndContainer") {
184 ws_containerOnly->setYUnit(
"");
185 ws_containerOnly->setDistribution(
true);
186 ws_containerOnly->setYUnitLabel(
"Multiple Scattering Correction factor");
187 const auto &containerShape =
m_inputWS->sample().getEnvironment().getContainer();
191 ws_sampleAndContainer->setYUnit(
"");
192 ws_sampleAndContainer->setDistribution(
true);
193 ws_sampleAndContainer->setYUnitLabel(
"Multiple Scattering Correction factor");
196 const std::string outWSName =
getProperty(
"OutputWorkspace");
197 std::vector<std::string> names;
198 names.emplace_back(outWSName +
"_containerOnly");
200 names.emplace_back(outWSName +
"_sampleAndContainer");
205 group->setProperty(
"InputWorkspaces", names);
206 group->setProperty(
"OutputWorkspace", outWSName);
214 throw std::invalid_argument(
"Invalid method: " + method);
233 const auto specSize =
static_cast<int64_t
>(
m_inputWS->blocksize());
236 std::ostringstream msg;
237 msg <<
"Numerical integration performed every " <<
m_xStep <<
" wavelength points";
257 const auto material = shape.
material();
267 std::vector<double> LS1s(numVolumeElements, 0.0);
274 const int64_t len_l12 = numVolumeElements * (numVolumeElements - 1) / 2;
275 std::vector<double> L12s(len_l12, 0.0);
286 const double rho = material.numberDensityEffective();
287 const double sigma_s = material.totalScatterXSection();
288 const double unit_scaling = 1e2;
289 const double totScatterCoeff =
rho * sigma_s * unit_scaling;
292 const auto &spectrumInfo =
m_inputWS->spectrumInfo();
293 const auto numHists =
static_cast<int64_t
>(
m_inputWS->getNumberHistograms());
294 const auto specSize =
static_cast<int64_t
>(
m_inputWS->blocksize());
295 Progress prog(
this, 0.0, 1.0, numHists);
298 for (int64_t workspaceIndex = 0; workspaceIndex < numHists; ++workspaceIndex) {
301 if (!spectrumInfo.hasDetectors(workspaceIndex)) {
302 g_log.
information() <<
"Spectrum " << workspaceIndex <<
" does not have a detector defined for it\n";
305 const auto &det = spectrumInfo.detector(workspaceIndex);
308 std::vector<double> L2Ds(numVolumeElements, 0.0);
311 const auto wavelengths =
m_inputWS->points(workspaceIndex);
314 const auto LinearCoefAbs = material.linearAbsorpCoef(wavelengths.cbegin(), wavelengths.cend());
316 auto &output = outws->mutableY(workspaceIndex);
318 for (int64_t wvBinsIndex = 0; wvBinsIndex < specSize; wvBinsIndex +=
m_xStep) {
322 pairWiseSum(A1, A2, -LinearCoefAbs[wvBinsIndex], distGraber, LS1s, L12s, L2Ds, 0, numVolumeElements);
326 output[wvBinsIndex] = totScatterCoeff / (4 * M_PI) * (A2 / A1);
330 std::ostringstream msg_debug;
331 msg_debug <<
"Det_" << workspaceIndex <<
"@spectrum_" << wvBinsIndex <<
'\n'
332 <<
"\trho = " <<
rho <<
", sigma_s = " << sigma_s <<
'\n'
333 <<
"\tA1 = " << A1 <<
'\n'
334 <<
"\tA2 = " << A2 <<
'\n'
335 <<
"\tms_factor = " << output[wvBinsIndex] <<
'\n';
340 if (
m_xStep > 1 && wvBinsIndex +
m_xStep >= specSize && wvBinsIndex + 1 != specSize) {
341 wvBinsIndex = specSize -
m_xStep - 1;
348 auto histNew = outws->histogram(workspaceIndex);
349 interpolateLinearInplace(histNew,
m_xStep);
350 outws->setHistogram(workspaceIndex, histNew);
370 const auto &sample =
m_inputWS->sample();
371 const auto &sampleMaterial = sample.getShape().material();
372 const auto &containerMaterial = sample.getEnvironment().getContainer().material();
375 const auto &sampleShape = sample.getShape();
376 const auto &containerShape = sample.getEnvironment().getContainer();
386 const int64_t numVolumeElements = numVolumeElementsSample + numVolumeElementsContainer;
387 g_log.
information() <<
"numVolumeElementsSample=" << numVolumeElementsSample
388 <<
", numVolumeElementsContainer=" << numVolumeElementsContainer <<
"\n";
399 std::vector<double> LS1_container(numVolumeElements, 0.0);
400 std::vector<double> LS1_sample(numVolumeElements, 0.0);
401 calculateLS1s(distGraberContainer, distGraberSample, LS1_container, LS1_sample, containerShape, sampleShape);
417 const int64_t len_l12 = numVolumeElements * (numVolumeElements - 1) / 2;
418 std::vector<double> L12_container(len_l12, 0.0);
419 std::vector<double> L12_sample(len_l12, 0.0);
420 calculateL12s(distGraberContainer, distGraberSample, L12_container, L12_sample, containerShape, sampleShape);
422 for (
size_t i = 0; i < size_t(numVolumeElements); ++i) {
423 for (
size_t j = i + 1; j < size_t(numVolumeElements); ++j) {
424 const auto idx = calcLinearIdxFromUpperTriangular(numVolumeElements, i, j);
425 const auto l12 = L12_container[idx] + L12_sample[idx];
427 g_log.
notice() <<
"L12_container(" << i <<
"," << j <<
")=" << L12_container[idx] <<
'\n'
428 <<
"L12_sample(" << i <<
"," << j <<
")=" << L12_sample[idx] <<
'\n';
435 std::vector<double> elementVolumes(distGraberContainer.
m_elementVolumes.begin(),
437 elementVolumes.insert(elementVolumes.end(), distGraberSample.
m_elementVolumes.begin(),
440 for (
size_t i = 0; i < elementVolumes.size(); ++i) {
441 if (elementVolumes[i] < 1e-16) {
442 g_log.
notice() <<
"Element_" << i <<
" has near zero volume: " << elementVolumes[i] <<
'\n';
459 const double unit_scaling = 1e2;
460 const double rho_sample = sampleMaterial.numberDensityEffective();
461 const double sigma_s_sample = sampleMaterial.totalScatterXSection();
462 const double rho_container = containerMaterial.numberDensityEffective();
463 const double sigma_s_container = containerMaterial.totalScatterXSection();
464 const double totScatterCoef_container = rho_container * sigma_s_container * unit_scaling;
465 const double totScatterCoef_sample = rho_sample * sigma_s_sample * unit_scaling;
468 const auto &spectrumInfo =
m_inputWS->spectrumInfo();
469 const auto numHists =
static_cast<int64_t
>(
m_inputWS->getNumberHistograms());
470 const auto specSize =
static_cast<int64_t
>(
m_inputWS->blocksize());
471 Progress prog(
this, 0.0, 1.0, numHists);
474 for (int64_t workspaceIndex = 0; workspaceIndex < numHists; ++workspaceIndex) {
477 if (!spectrumInfo.hasDetectors(workspaceIndex)) {
478 g_log.
information() <<
"Spectrum " << workspaceIndex <<
" does not have a detector defined for it\n";
481 const auto &det = spectrumInfo.detector(workspaceIndex);
485 std::vector<double> L2D_container(numVolumeElements, 0.0);
486 std::vector<double> L2D_sample(numVolumeElements, 0.0);
487 calculateL2Ds(distGraberContainer, distGraberSample, det, L2D_container, L2D_sample, containerShape, sampleShape);
490 const auto wavelengths =
m_inputWS->points(workspaceIndex);
491 const auto sampleLinearCoefAbs = sampleMaterial.linearAbsorpCoef(wavelengths.cbegin(), wavelengths.cend());
492 const auto containerLinearCoefAbs = containerMaterial.linearAbsorpCoef(wavelengths.cbegin(), wavelengths.cend());
494 auto &output = outws->mutableY(workspaceIndex);
495 for (int64_t wvBinsIndex = 0; wvBinsIndex < specSize; wvBinsIndex +=
m_xStep) {
501 -containerLinearCoefAbs[wvBinsIndex], -sampleLinearCoefAbs[wvBinsIndex],
502 numVolumeElementsContainer, numVolumeElements,
503 totScatterCoef_container, totScatterCoef_sample,
505 LS1_container, LS1_sample,
506 L12_container, L12_sample,
507 L2D_container, L2D_sample,
508 0, numVolumeElements);
510 output[wvBinsIndex] = (A2 / A1) / (4.0 * M_PI);
514 std::ostringstream msg_debug;
515 msg_debug <<
"Det_" << workspaceIndex <<
"@spectrum_" << wvBinsIndex <<
'\n'
516 <<
"-containerLinearCoefAbs[wvBinsIndex] = " << -containerLinearCoefAbs[wvBinsIndex] <<
'\n'
517 <<
"-sampleLinearCoefAbs[wvBinsIndex] = " << -sampleLinearCoefAbs[wvBinsIndex] <<
'\n'
518 <<
"numVolumeElementsContainer = " << numVolumeElementsContainer <<
'\n'
519 <<
"numVolumeElements = " << numVolumeElements <<
'\n'
520 <<
"totScatterCoef_container = " << totScatterCoef_container <<
'\n'
521 <<
"totScatterCoef_sample = " << totScatterCoef_sample <<
'\n'
522 <<
"\tA1 = " << A1 <<
'\n'
523 <<
"\tA2 = " << A2 <<
'\n'
524 <<
"\tms_factor = " << output[wvBinsIndex] <<
'\n';
529 if (
m_xStep > 1 && wvBinsIndex +
m_xStep >= specSize && wvBinsIndex + 1 != specSize) {
530 wvBinsIndex = specSize -
m_xStep - 1;
536 auto histNew = outws->histogram(workspaceIndex);
537 interpolateLinearInplace(histNew,
m_xStep);
538 outws->setHistogram(workspaceIndex, histNew);
555 std::vector<double> &LS1s,
557 const auto &sourcePos =
m_inputWS->getInstrument()->getSource()->getPos();
561 for (int64_t idx = 0; idx < numVolumeElements; ++idx) {
563 const auto vec = getDirection(pos, sourcePos);
565 trackerLS1.reset(pos, vec);
566 trackerLS1.clearIntersectionResults();
567 LS1s[idx] = getDistanceInsideObject(shape, trackerLS1);
583 std::vector<double> &LS1sContainer,
584 std::vector<double> &LS1sSample,
596 const int64_t numVolumeElements = numVolumeElementsSample + numVolumeElementsContainer;
597 const auto sourcePos =
m_inputWS->getInstrument()->getSource()->getPos();
599 for (int64_t idx = 0; idx < numVolumeElements; ++idx) {
600 const auto pos = idx < numVolumeElementsContainer
603 const auto vec = getDirection(pos, sourcePos);
605 trackerLS1.reset(pos, vec);
606 trackerLS1.clearIntersectionResults();
607 LS1sContainer[idx] = getDistanceInsideObject(shapeContainer, trackerLS1);
608 trackerLS1.reset(pos, vec);
609 trackerLS1.clearIntersectionResults();
610 LS1sSample[idx] = getDistanceInsideObject(shapeSample, trackerLS1);
613 std::ostringstream msg_debug;
614 msg_debug <<
"idx=" << idx <<
", pos=" << pos <<
", vec=" << vec <<
'\n';
615 if (idx < numVolumeElementsContainer) {
616 msg_debug <<
"Container element " << idx <<
'\n';
618 msg_debug <<
"Sample element " << idx - numVolumeElementsContainer <<
'\n';
620 msg_debug <<
"LS1_container=" << LS1sContainer[idx] <<
", LS1_sample=" << LS1sSample[idx] <<
'\n';
634 std::vector<double> &L12s,
643 for (int64_t indexTo = 0; indexTo < numVolumeElements; ++indexTo) {
648 for (int64_t indexFrom = indexTo + 1; indexFrom < numVolumeElements; ++indexFrom) {
654 const int64_t idx = calcLinearIdxFromUpperTriangular(numVolumeElements, indexTo, indexFrom);
657 const V3D unitVector = getDirection(posFrom, posTo);
660 track.
reset(posFrom, unitVector);
662 const auto rayLengthOne1 = getDistanceInsideObject(shape, track);
664 track.
reset(posTo, unitVector);
666 const auto rayLengthOne2 = getDistanceInsideObject(shape, track);
670 L12s[idx] = checkzero(rayLengthOne1 - rayLengthOne2);
680 std::vector<double> &L12sContainer,
681 std::vector<double> &L12sSample,
686 const int64_t numVolumeElements = numVolumeElementsSample + numVolumeElementsContainer;
702 for (int64_t indexTo = 0; indexTo < numVolumeElements; ++indexTo) {
705 const auto posTo = indexTo < numVolumeElementsContainer
711 for (int64_t indexFrom = indexTo + 1; indexFrom < numVolumeElements; ++indexFrom) {
712 const int64_t idx = calcLinearIdxFromUpperTriangular(numVolumeElements, indexTo, indexFrom);
713 const auto posFrom = indexFrom < numVolumeElementsContainer
716 const V3D unitVector = getDirection(posFrom, posTo);
720 track.
reset(posFrom, unitVector);
721 const auto rayLen1_container = getDistanceInsideObject(shapeContainer, track);
723 track.
reset(posFrom, unitVector);
724 const auto rayLen1_sample = getDistanceInsideObject(shapeSample, track);
726 track.
reset(posTo, unitVector);
727 const auto rayLen2_container = getDistanceInsideObject(shapeContainer, track);
729 track.
reset(posTo, unitVector);
730 const auto rayLen2_sample = getDistanceInsideObject(shapeSample, track);
732 L12sContainer[idx] = checkzero(rayLen1_container - rayLen2_container);
733 L12sSample[idx] = checkzero(rayLen1_sample - rayLen2_sample);
749 const IDetector &detector, std::vector<double> &L2Ds,
752 if (detector.
nDets() > 1) {
756 detector.
getPhi() * RAD2DEG);
763 TwoToDetector.
reset(elementPos, getDirection(elementPos, detectorPos));
766 L2Ds[i] = getDistanceInsideObject(shape, TwoToDetector);
773 std::vector<double> &container_L2Ds,
774 std::vector<double> &sample_L2Ds,
778 if (detector.
nDets() > 1) {
782 detector.
getPhi() * RAD2DEG);
787 const int64_t numVolumeElements = numVolumeElementsSample + numVolumeElementsContainer;
797 for (int64_t idx = 0; idx < numVolumeElements; ++idx) {
798 const auto pos = idx < numVolumeElementsContainer
801 const auto vec = getDirection(pos, detectorPos);
803 trackerL2D.reset(pos, vec);
804 trackerL2D.clearIntersectionResults();
805 container_L2Ds[idx] = getDistanceInsideObject(shapeContainer, trackerL2D);
806 trackerL2D.reset(pos, vec);
807 trackerL2D.clearIntersectionResults();
808 sample_L2Ds[idx] = getDistanceInsideObject(shapeSample, trackerL2D);
813 const double linearCoefAbs,
815 const std::vector<double> &LS1s,
816 const std::vector<double> &L12s,
817 const std::vector<double> &L2Ds,
818 const int64_t startIndex,
const int64_t endIndex)
const {
819 if (endIndex - startIndex > MAX_INTEGRATION_LENGTH) {
820 int64_t middle = findMiddle(startIndex, endIndex);
823 pairWiseSum(A1, A2, linearCoefAbs, distGraber, LS1s, L12s, L2Ds, startIndex, middle);
824 pairWiseSum(A1, A2, linearCoefAbs, distGraber, LS1s, L12s, L2Ds, middle, endIndex);
829 for (int64_t i = startIndex; i < endIndex; ++i) {
831 double exponent = (LS1s[i] + L2Ds[i]) * linearCoefAbs;
832 A1 += exp(exponent) * elementVolumes[i];
835 for (int64_t j = 0; j < int64_t(nElements); ++j) {
841 size_t idx_l12 = i < j ? calcLinearIdxFromUpperTriangular(nElements, i, j)
842 : calcLinearIdxFromUpperTriangular(nElements, j, i);
844 const auto l12 = L12s[idx_l12];
846 exponent = (LS1s[i] + L12s[idx_l12] + L2Ds[j]) * linearCoefAbs;
847 a2 += exp(exponent) * elementVolumes[j] / (L12s[idx_l12] * L12s[idx_l12]);
850 A2 += a2 * elementVolumes[i];
856 double &A1,
double &A2,
857 const double linearCoefAbsContainer,
const double linearCoefAbsSample,
858 const int64_t numVolumeElementsContainer,
const int64_t numVolumeElementsTotal,
859 const double totScatterCoefContainer,
860 const double totScatterCoefSample,
861 const std::vector<double> &elementVolumes,
862 const std::vector<double> &LS1sContainer,
const std::vector<double> &LS1sSample,
863 const std::vector<double> &L12sContainer,
const std::vector<double> &L12sSample,
864 const std::vector<double> &L2DsContainer,
const std::vector<double> &L2DsSample,
865 const int64_t startIndex,
const int64_t endIndex)
const {
866 if (endIndex - startIndex > MAX_INTEGRATION_LENGTH) {
867 int64_t middle = findMiddle(startIndex, endIndex);
869 pairWiseSum(A1, A2, linearCoefAbsContainer, linearCoefAbsSample, numVolumeElementsContainer, numVolumeElementsTotal,
870 totScatterCoefContainer, totScatterCoefSample, elementVolumes, LS1sContainer, LS1sSample, L12sContainer,
871 L12sSample, L2DsContainer, L2DsSample, startIndex, middle);
872 pairWiseSum(A1, A2, linearCoefAbsContainer, linearCoefAbsSample, numVolumeElementsContainer, numVolumeElementsTotal,
873 totScatterCoefContainer, totScatterCoefSample, elementVolumes, LS1sContainer, LS1sSample, L12sContainer,
874 L12sSample, L2DsContainer, L2DsSample, middle, endIndex);
877 for (int64_t i = startIndex; i < endIndex; ++i) {
878 const double factor_i = i > numVolumeElementsContainer ? totScatterCoefSample : totScatterCoefContainer;
880 double exponent = (LS1sContainer[i] + L2DsContainer[i]) * linearCoefAbsContainer +
881 (LS1sSample[i] + L2DsSample[i]) * linearCoefAbsSample;
882 A1 += exp(exponent) * factor_i * elementVolumes[i];
885 for (int64_t j = 0; j < numVolumeElementsTotal; ++j) {
890 const double factor_j = j > numVolumeElementsContainer ? totScatterCoefSample : totScatterCoefContainer;
892 size_t idx_l12 = i < j ? calcLinearIdxFromUpperTriangular(numVolumeElementsTotal, i, j)
893 : calcLinearIdxFromUpperTriangular(numVolumeElementsTotal, j, i);
894 const double l12 = L12sContainer[idx_l12] + L12sSample[idx_l12];
896 exponent = (LS1sContainer[i] + L12sContainer[idx_l12] + L2DsContainer[j]) * linearCoefAbsContainer +
897 (LS1sSample[i] + L12sSample[idx_l12] + L2DsSample[j]) * linearCoefAbsSample;
898 a2 += exp(exponent) * factor_j * elementVolumes[j] / (l12 * l12);
901 A2 += a2 * factor_i * elementVolumes[i];
#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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
bool isDefault(const std::string &name) const
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
A validator which checks that sample has the required properties.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
MultipleScatteringCorrectionDistGraber : This is a helper class to calculate the distance from source...
size_t m_numVolumeElements
The number of volume elements.
std::vector< double > m_elementVolumes
Cached element volumes.
std::vector< Kernel::V3D > m_elementPositions
Cached element positions.
void cacheLS1(const Mantid::Kernel::V3D &beamDirection)
pre-calculate the distance from source to L1 for all the voxels in the sample
void calculateLS1s(const MultipleScatteringCorrectionDistGraber &distGraber, std::vector< double > &LS1s, const Geometry::IObject &shape) const
compute LS1s within given shape for single component case
void exec() override
execute the algorithm
void calculateSingleComponent(const API::MatrixWorkspace_sptr &outws, const Geometry::IObject &shape, const double elementSize)
calculate the correction factor per detector for sample only case
void parseInputs()
parse and assign corresponding values from input properties
void pairWiseSum(double &A1, double &A2, const double linearCoefAbs, const MultipleScatteringCorrectionDistGraber &distGraber, const std::vector< double > &LS1s, const std::vector< double > &L12s, const std::vector< double > &L2Ds, const int64_t startIndex, const int64_t endIndex) const
double m_sampleElementSize
The size of the integration element for sample in meters.
void calculateSampleAndContainer(const API::MatrixWorkspace_sptr &outws)
calculate the multiple scattering factor (0, 1) for sample and container case
API::MatrixWorkspace_sptr m_inputWS
A pointer to the input workspace.
void calculateL2Ds(const MultipleScatteringCorrectionDistGraber &distGraber, const IDetector &detector, std::vector< double > &L2Ds, const Geometry::IObject &shape) const
Calculate distance between exiting element to the detector for single component case.
Kernel::V3D m_beamDirection
The direction of the beam.
int64_t m_num_lambda
The number of points in wavelength, the rest is interpolated linearly.
int64_t m_xStep
The step in bin number between adjacent points for linear interpolation.
void init() override
interface initialisation method
std::map< std::string, std::string > validateInputs() override
validate the inputs
void calculateL12s(const MultipleScatteringCorrectionDistGraber &distGraber, std::vector< double > &L12s, const Geometry::IObject &shape)
calculate L12 for single component case
double m_containerElementSize
the size of the integration element for container in meters
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
Interface class for detector objects.
virtual double getPhi() const =0
Gives the phi of this detector object in radians.
virtual std::size_t nDets() const =0
Get the number of physical detectors this object represents.
virtual double getTwoTheta(const Kernel::V3D &observer, const Kernel::V3D &axis) const =0
Gives the angle of this detector object with respect to an axis.
IObject : Interface for geometry objects.
virtual int interceptSurface(Geometry::Track &) const =0
virtual const Kernel::Material & material() const =0
Defines a track as a start point and a direction.
void clearIntersectionResults()
Clear the current set of intersection results.
double totalDistInsideObject() const
Returns the sum of all the links distInsideObject in the track.
void reset(const Kernel::V3D &startPoint, const Kernel::V3D &direction)
Set a starting point and direction.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void spherical(const double R, const double theta, const double phi) noexcept
Sets the vector position based on spherical coordinates.
double norm() const noexcept
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
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.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.