Mantid
Loading...
Searching...
No Matches
PaalmanPingsAbsorptionCorrection.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2020 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidAPI/Run.h"
11#include "MantidAPI/Sample.h"
23#include "MantidHistogramData/Interpolate.h"
26#include "MantidKernel/Unit.h"
28
29namespace Mantid::Algorithms {
30
31// Register the algorithm into the AlgorithmFactory
32DECLARE_ALGORITHM(PaalmanPingsAbsorptionCorrection)
33
34using namespace API;
35using namespace Geometry;
36using HistogramData::interpolateLinearInplace;
37using namespace Kernel;
38using namespace Mantid::DataObjects;
41
42namespace {
43// the maximum number of elements to combine at once in the pairwise summation
44constexpr size_t MAX_INTEGRATION_LENGTH{1000};
45
46inline size_t findMiddle(const size_t start, const size_t stop) {
47 auto half = static_cast<size_t>(floor(.5 * (static_cast<double>(stop - start))));
48 return start + half;
49}
50
51} // namespace
52
54 : API::Algorithm(), m_inputWS(), m_sampleObject(nullptr), m_containerObject(nullptr), m_sampleL1s(),
55 m_sample_containerL1s(), m_sampleElementVolumes(), m_sampleElementPositions(), m_numSampleVolumeElements(0),
56 m_sampleVolume(0.0), m_containerL1s(), m_container_sampleL1s(), m_containerElementVolumes(),
57 m_containerElementPositions(), m_numContainerVolumeElements(0), m_containerVolume(0.0),
58 m_ampleLinearCoefTotScatt(0), m_containerLinearCoefTotScatt(0), m_num_lambda(0), m_xStep(0),
59 m_cubeSideSample(0.0), m_cubeSideContainer(0.0) {}
60
62
63 // The input workspace must have an instrument and units of wavelength
64 auto wsValidator = std::make_shared<CompositeValidator>();
65 wsValidator->add<WorkspaceUnitValidator>("Wavelength");
66 wsValidator->add<InstrumentValidator>();
67
68 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input, wsValidator),
69 "The X values for the input workspace must be in units of wavelength");
70 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>("OutputWorkspace", "", Direction::Output),
71 "Output workspace name");
72
73 auto positiveInt = std::make_shared<BoundedValidator<int64_t>>();
74 positiveInt->setLower(1);
75 declareProperty("NumberOfWavelengthPoints", static_cast<int64_t>(EMPTY_INT()), positiveInt,
76 "The number of wavelength points for which the numerical integral is\n"
77 "calculated (default: all points)");
78
79 auto moreThanZero = std::make_shared<BoundedValidator<double>>();
80 moreThanZero->setLower(0.001);
81 declareProperty("ElementSize", 1.0, moreThanZero, "The size of one side of an integration element cube in mm");
82
83 declareProperty("ContainerElementSize", EMPTY_DBL(),
84 "The size of one side of an integration element cube in mm for container."
85 "Default to be the same as ElementSize.");
86}
87
88std::map<std::string, std::string> PaalmanPingsAbsorptionCorrection::validateInputs() {
89 std::map<std::string, std::string> result;
90
91 // verify that the container information is there if requested
92 API::MatrixWorkspace_const_sptr wksp = getProperty("InputWorkspace");
93 const auto &sample = wksp->sample();
94 if (sample.hasEnvironment()) {
95 const auto numComponents = sample.getEnvironment().nelements();
96 // first element is assumed to be the container
97 if (numComponents == 0) {
98 result["InputWorkspace"] = "Sample does not have a container defined";
99 }
100 } else {
101 result["InputWorkspace"] = "Sample does not have a container defined";
102 }
103 return result;
104}
105
107 // Retrieve the input workspace
108 m_inputWS = getProperty("InputWorkspace");
109 // Cache the beam direction
110 m_beamDirection = m_inputWS->getInstrument()->getBeamDirection();
111
112 // Get the input parameters
114
115 // Create the output workspaces
116
117 // A_s,s - absorption factor for scattering and self-absorption in sample
118 MatrixWorkspace_sptr ass = create<HistoWorkspace>(*m_inputWS);
119 ass->setDistribution(true); // The output of this is a distribution
120 ass->setYUnit(""); // Need to explicitly set YUnit to nothing
121 ass->setYUnitLabel("Attenuation factor");
122 // A_s,sc - absorption factor for scattering in sample and absorption in both
123 // sample and container
124 MatrixWorkspace_sptr assc = create<HistoWorkspace>(*m_inputWS);
125 assc->setDistribution(true); // The output of this is a distribution
126 assc->setYUnit(""); // Need to explicitly set YUnit to nothing
127 assc->setYUnitLabel("Attenuation factor");
128 // A_c,c - absorption factor for scattering and self-absorption in container
129 MatrixWorkspace_sptr acc = create<HistoWorkspace>(*m_inputWS);
130 acc->setDistribution(true); // The output of this is a distribution
131 acc->setYUnit(""); // Need to explicitly set YUnit to nothing
132 acc->setYUnitLabel("Attenuation factor");
133 // A_c,sc - absorption factor for scattering in container and absorption in
134 // both sample and container
135 MatrixWorkspace_sptr acsc = create<HistoWorkspace>(*m_inputWS);
136 acsc->setDistribution(true); // The output of this is a distribution
137 acsc->setYUnit(""); // Need to explicitly set YUnit to nothing
138 acsc->setYUnitLabel("Attenuation factor");
139
140 constructSample(m_inputWS->mutableSample());
141
142 const auto numHists = static_cast<int64_t>(m_inputWS->getNumberHistograms());
143 const auto specSize = static_cast<int64_t>(m_inputWS->blocksize());
144
145 // If the number of wavelength points has not been given, use them all
147 m_num_lambda = specSize;
148 m_xStep = specSize / m_num_lambda; // Bin step between points to calculate
149
150 if (m_xStep == 0) // Number of wavelength points >number of histogram points
151 m_xStep = 1;
152
153 std::ostringstream message;
154 message << "Numerical integration performed every " << m_xStep << " wavelength points";
155 g_log.information(message.str());
156 message.str("");
157
158 // Calculate the cached values of L1, element volumes, and geometry size
160 if (m_sampleL1s.empty() || m_containerL1s.empty()) {
161 throw std::runtime_error("Failed to define any initial scattering gauge volume for geometry");
162 }
163
164 const auto &spectrumInfo = m_inputWS->spectrumInfo();
165 Progress prog(this, 0.0, 1.0, numHists);
166 // Loop over the spectra
167 PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *ass, *assc, *acc, *acsc))
168 for (int64_t i = 0; i < int64_t(numHists); ++i) {
170 // Copy over bins
171 ass->setSharedX(i, m_inputWS->sharedX(i));
172 assc->setSharedX(i, m_inputWS->sharedX(i));
173 acc->setSharedX(i, m_inputWS->sharedX(i));
174 acsc->setSharedX(i, m_inputWS->sharedX(i));
175
176 if (!spectrumInfo.hasDetectors(i)) {
177 g_log.information() << "Spectrum " << i << " does not have a detector defined for it\n";
178 continue;
179 }
180 if (spectrumInfo.isMasked(i)) {
181 continue;
182 }
183 const auto &det = spectrumInfo.detector(i);
184
185 // scattering and self-absorption in sample L2 distances, used for A_s,s and
186 // A_s,sc
187 std::vector<double> sample_L2s(m_numSampleVolumeElements);
188 // scattering in sample and absorption in both sample and container L2
189 // distance, used for A_s,sc
190 std::vector<double> sample_container_L2s(m_numSampleVolumeElements);
191 // absorption factor for scattering and self-absorption in container L2
192 // distances, used for A_c,c and A_c,sc
193 std::vector<double> container_L2s(m_numContainerVolumeElements);
194 // scattering in container and absorption in both sample and container L2
195 // distances, used for A_c,sc
196 std::vector<double> container_sample_L2s(m_numContainerVolumeElements);
197
198 calculateDistances(det, sample_L2s, sample_container_L2s, container_L2s, container_sample_L2s);
199
200 const auto wavelengths = m_inputWS->points(i);
201 // these need to have the minus sign applied still
202 const auto sampleLinearCoefAbs = m_material.linearAbsorpCoef(wavelengths.cbegin(), wavelengths.cend());
203 const auto containerLinearCoefAbs = m_containerMaterial.linearAbsorpCoef(wavelengths.cbegin(), wavelengths.cend());
204
205 // Get a reference to the Y's in the output WS for storing the factors
206 auto &assY = ass->mutableY(i);
207 auto &asscY = assc->mutableY(i);
208 auto &accY = acc->mutableY(i);
209 auto &acscY = acsc->mutableY(i);
210
211 // Loop through the bins in the current spectrum every m_xStep
212 for (int64_t j = 0; j < specSize; j = j + m_xStep) {
213 double integral = 0.0;
214 double crossIntegral = 0.0;
215
216 doIntegration(integral, crossIntegral, -sampleLinearCoefAbs[j], m_ampleLinearCoefTotScatt, m_sampleElementVolumes,
217 m_sampleL1s, sample_L2s, -containerLinearCoefAbs[j], m_containerLinearCoefTotScatt,
218 m_sample_containerL1s, sample_container_L2s, 0, m_numSampleVolumeElements);
219 assY[j] = integral / m_sampleVolume; // Divide by total volume of the shape
220 asscY[j] = crossIntegral / m_sampleVolume; // Divide by total volume of the shape
221
222 integral = 0.0;
223 crossIntegral = 0.0;
224 doIntegration(integral, crossIntegral, -containerLinearCoefAbs[j], m_containerLinearCoefTotScatt,
225 m_containerElementVolumes, m_containerL1s, container_L2s, -sampleLinearCoefAbs[j],
226 m_ampleLinearCoefTotScatt, m_container_sampleL1s, container_sample_L2s, 0,
228 accY[j] = integral / m_containerVolume; // Divide by total volume of the shape
229 acscY[j] = crossIntegral / m_containerVolume; // Divide by total volume of the shape
230
231 // Make certain that last point is calculated
232 if (m_xStep > 1 && j + m_xStep >= specSize && j + 1 != specSize) {
233 j = specSize - m_xStep - 1;
234 }
235 }
236
237 // Interpolate linearly between points separated by m_xStep,
238 // last point required
239 if (m_xStep > 1) {
240 auto histnew = ass->histogram(i);
241 interpolateLinearInplace(histnew, m_xStep);
242 ass->setHistogram(i, histnew);
243 auto histnew2 = assc->histogram(i);
244 interpolateLinearInplace(histnew2, m_xStep);
245 assc->setHistogram(i, histnew2);
246 auto histnew3 = acc->histogram(i);
247 interpolateLinearInplace(histnew3, m_xStep);
248 acc->setHistogram(i, histnew3);
249 auto histnew4 = acsc->histogram(i);
250 interpolateLinearInplace(histnew4, m_xStep);
251 acsc->setHistogram(i, histnew4);
252 }
253
254 prog.report();
255
257 }
259
260 g_log.information() << "Total number of elements in the integration was " << m_sampleL1s.size() << '\n';
261
262 const std::string outWSName = getProperty("OutputWorkspace");
263
264 std::vector<std::string> names;
265 names.emplace_back(outWSName + "_ass");
266 API::AnalysisDataService::Instance().addOrReplace(names.back(), ass);
267 names.emplace_back(outWSName + "_assc");
268 API::AnalysisDataService::Instance().addOrReplace(names.back(), assc);
269 names.emplace_back(outWSName + "_acc");
270 API::AnalysisDataService::Instance().addOrReplace(names.back(), acc);
271 names.emplace_back(outWSName + "_acsc");
272 API::AnalysisDataService::Instance().addOrReplace(names.back(), acsc);
273
274 auto group = createChildAlgorithm("GroupWorkspaces");
275 group->initialize();
276 group->setProperty("InputWorkspaces", names);
277 group->setProperty("OutputWorkspace", outWSName);
278 group->execute();
279 API::WorkspaceGroup_sptr outWS = group->getProperty("OutputWorkspace");
280
281 setProperty("OutputWorkspace", outWS);
282}
283
285 IObject_const_sptr integrationVolume;
286 if (m_inputWS->run().hasProperty("GaugeVolume")) {
287 integrationVolume = constructGaugeVolume();
288 } else {
289 try {
290 auto beamProfile = BeamProfileFactory::createBeamProfile(*m_inputWS->getInstrument(), Mantid::API::Sample());
291 integrationVolume = beamProfile->getIntersectionWithSample(*object);
292 } catch (const std::invalid_argument &) {
293 // If createBeamProfile fails, the beam parameters are not defined
294 // If getIntersectionWithSample fails, the beam misses the object
295 // In either case we will just fall back to using the whole sample below.
296 }
297 if (integrationVolume == nullptr) {
298 // If the beam profile is not defined, use the sample object
299 integrationVolume = std::shared_ptr<const IObject>(object->clone());
300 }
301 }
302
303 return Geometry::Rasterize::calculate(m_beamDirection, *integrationVolume, *object, m_cubeSideSample);
304}
305
310 auto raster = rasterize(m_sampleObject);
311 m_sampleVolume = raster.totalvolume;
312 if (raster.l1.size() == 0)
313 throw std::runtime_error("Failed to rasterize sample shape");
314 // move over the information
315 m_numSampleVolumeElements = raster.l1.size();
316 m_sampleL1s = std::move(raster.l1);
317 m_sampleElementPositions = std::move(raster.position);
318 m_sampleElementVolumes = std::move(raster.volume);
319 // now for the container
321 m_containerVolume = raster.totalvolume;
322 if (raster.l1.size() == 0)
323 throw std::runtime_error("Failed to rasterize container shape");
324 // move over the information
325 m_numContainerVolumeElements = raster.l1.size();
326 m_containerL1s = std::move(raster.l1);
327 m_containerElementPositions = std::move(raster.position);
328 m_containerElementVolumes = std::move(raster.volume);
329
330 // Get the L1s for the cross terms
331
332 // L1s for absorbed by the container to be scattered by the sample
334 for (size_t i = 0; i < m_numSampleVolumeElements; ++i) {
338 }
339
340 // L1s for absorbed by the sample to be scattered by the container
342 for (size_t i = 0; i < m_numContainerVolumeElements; ++i) {
346 }
347}
348
349std::shared_ptr<const Geometry::IObject> PaalmanPingsAbsorptionCorrection::constructGaugeVolume() {
350 g_log.information("Calculating scattering within the gauge volume defined on "
351 "the input workspace");
352
353 // Retrieve and create the gauge volume shape
354 std::shared_ptr<const Geometry::IObject> volume =
355 ShapeFactory().createShape(m_inputWS->run().getProperty("GaugeVolume")->value());
356
357 return volume;
358}
359
362
363 // get the material from the correct component
364 const auto &sampleObj = m_inputWS->sample();
365 m_material = sampleObj.getShape().material();
366 m_containerMaterial = sampleObj.getEnvironment().getContainer().material();
367
368 // NOTE: the angstrom^-2 to barns and the angstrom^-1 to cm^-1
369 // will cancel for mu to give units: cm^-1
373
374 m_num_lambda = getProperty("NumberOfWavelengthPoints");
375
376 // Call the virtual function for any further properties
377 m_cubeSideSample = getProperty("ElementSize"); // in mm
378 m_cubeSideSample *= 0.001; // now in m
379 // use the same elementsize for container if not specified, otherwise use the specified value
380 m_cubeSideContainer = getProperty("ContainerElementSize"); // in mm
381 m_cubeSideContainer = isDefault("ContainerElementSize") ? m_cubeSideSample : m_cubeSideContainer * 1e-3;
382}
383
386 m_sampleObject = &sample.getShape();
388
389 // Check there is one, and fail if not
391 const std::string mess("No shape has been defined for the sample in the input workspace");
392 g_log.error(mess);
393 throw std::invalid_argument(mess);
394 }
395 // Check there is one, and fail if not
397 const std::string mess("No shape has been defined for the container in the input workspace");
398 g_log.error(mess);
399 throw std::invalid_argument(mess);
400 }
401}
402
404void PaalmanPingsAbsorptionCorrection::calculateDistances(const IDetector &detector, std::vector<double> &sample_L2s,
405 std::vector<double> &sample_container_L2s,
406 std::vector<double> &container_L2s,
407 std::vector<double> &container_sample_L2s) const {
408 V3D detectorPos(detector.getPos());
409 if (detector.nDets() > 1) {
410 // We need to make sure this is right for grouped detectors - should use
411 // average theta & phi
412 detectorPos.spherical(detectorPos.norm(), detector.getTwoTheta(V3D(), V3D(0, 0, 1)) * 180.0 / M_PI,
413 detector.getPhi() * 180.0 / M_PI);
414 }
415
416 for (size_t i = 0; i < m_numSampleVolumeElements; ++i) {
417 // Create track for distance between scattering point in sample and detector
418 const V3D direction = normalize(detectorPos - m_sampleElementPositions[i]);
419 Track outgoing(m_sampleElementPositions[i], direction);
420
421 // find distance in sample
423 sample_L2s[i] = outgoing.totalDistInsideObject();
424
425 outgoing.clearIntersectionResults();
426
427 // find distance in container
429 sample_container_L2s[i] = outgoing.totalDistInsideObject();
430 }
431
432 for (size_t i = 0; i < m_numContainerVolumeElements; ++i) {
433 // Create track for distance between scattering point in container and
434 // detector
435 const V3D direction = normalize(detectorPos - m_containerElementPositions[i]);
436 Track outgoing(m_containerElementPositions[i], direction);
437
438 // find distance in container
440 container_L2s[i] = outgoing.totalDistInsideObject();
441
442 outgoing.clearIntersectionResults();
443
444 // find distance in sample
446 container_sample_L2s[i] = outgoing.totalDistInsideObject();
447 }
448}
449
450// the integrations are done using pairwise summation to reduce
451// issues from adding lots of little numbers together
452// https://en.wikipedia.org/wiki/Pairwise_summation
453
456
457void PaalmanPingsAbsorptionCorrection::doIntegration(double &integral, double &crossIntegral,
458 const double linearCoefAbs, const double linearCoefTotScatt,
459 const std::vector<double> &elementVolumes,
460 const std::vector<double> &L1s, const std::vector<double> &L2s,
461 const double linearCoefAbs2, const double linearCoefTotScatt2,
462 const std::vector<double> &L1s2, const std::vector<double> &L2s2,
463 const size_t startIndex, const size_t endIndex) const {
464 if (endIndex - startIndex > MAX_INTEGRATION_LENGTH) {
465 size_t middle = findMiddle(startIndex, endIndex);
466
467 doIntegration(integral, crossIntegral, linearCoefAbs, linearCoefTotScatt, elementVolumes, L1s, L2s, linearCoefAbs2,
468 linearCoefTotScatt2, L1s2, L2s2, startIndex, middle);
469 doIntegration(integral, crossIntegral, linearCoefAbs, linearCoefTotScatt, elementVolumes, L1s, L2s, linearCoefAbs2,
470 linearCoefTotScatt2, L1s2, L2s2, middle, endIndex);
471 } else {
472
473 // Iterate over all the elements, summing up the integral
474 for (size_t i = startIndex; i < endIndex; ++i) {
475 double exponent = (linearCoefAbs + linearCoefTotScatt) * (L1s[i] + L2s[i]);
476 integral += (exp(exponent) * (elementVolumes[i]));
477 exponent += (linearCoefAbs2 + linearCoefTotScatt2) * (L1s2[i] + L2s2[i]);
478 crossIntegral += (exp(exponent) * (elementVolumes[i]));
479 }
480 }
481}
482
483} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#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.
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:76
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
bool isDefault(const std::string &name) const
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
This class stores information about the sample used in particular run.
Definition Sample.h:33
const Geometry::IObject & getShape() const
Return the sample shape.
Definition Sample.cpp:101
const Geometry::SampleEnvironment & getEnvironment() const
Get a reference to the sample's environment.
Definition Sample.cpp:135
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)
Geometry::Raster rasterize(const Geometry::IObject *object)
API::MatrixWorkspace_sptr m_inputWS
A pointer to the input workspace.
void constructSample(API::Sample &sample)
Create the sample object using the Geometry classes, or use the existing one.
std::vector< double > m_sampleL1s
Cached sample L1 distances.
double m_containerLinearCoefTotScatt
The total scattering cross-section in 1/m for the container.
void initialiseCachedDistances()
Calculate the distances for L1 (for both self-absorption and absorption by other object) and element ...
std::vector< double > m_containerL1s
Cached container L1 distances.
size_t m_numContainerVolumeElements
The number of container volume elements.
std::vector< double > m_sample_containerL1s
Cached L1 distances through container hitting sample.
void retrieveBaseProperties()
Fetch the properties and set the appropriate member variables.
void calculateDistances(const Geometry::IDetector &detector, std::vector< double > &sample_L2s, std::vector< double > &sample_container_L2s, std::vector< double > &container_L2s, std::vector< double > &container_sample_L2s) const
Calculate the distances traversed by the neutrons within the sample.
std::vector< Kernel::V3D > m_sampleElementPositions
Cached sample element positions.
const Geometry::IObject * m_sampleObject
Local cache of sample object.
std::shared_ptr< const Geometry::IObject > constructGaugeVolume()
Create the gague volume for the correction.
int64_t m_num_lambda
The number of points in wavelength, the rest is.
size_t m_numSampleVolumeElements
The number of sample volume elements.
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
const Geometry::IObject * m_containerObject
Local cache of container object.
std::vector< Kernel::V3D > m_containerElementPositions
Cached container element positions.
double m_cubeSideContainer
The length of the side of an element cube in m.
double m_cubeSideSample
The length of the side of an element cube in m.
void doIntegration(double &integral, double &crossIntegral, const double linearCoefAbs, const double linearCoefTotScatt, const std::vector< double > &elementVolumes, const std::vector< double > &L1s, const std::vector< double > &L2s, const double linearCoefAbs2, const double linearCoefTotScatt2, const std::vector< double > &L1s2, const std::vector< double > &L2s2, const size_t startIndex, const size_t endIndex) const
Carries out the numerical integration over the sample for elastic instruments.
std::vector< double > m_containerElementVolumes
Cached container element volumes.
std::vector< double > m_container_sampleL1s
Cached L1 distances through sample hitting container.
double m_ampleLinearCoefTotScatt
The total scattering cross-section in 1/m for the sample.
std::vector< double > m_sampleElementVolumes
Cached sample element volumes.
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
Interface class for detector objects.
Definition IDetector.h:43
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.
Definition IObject.h:42
virtual int interceptSurface(Geometry::Track &) const =0
virtual IObject * clone() const =0
virtual bool hasValidShape() const =0
const Container & getContainer() const
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...
Defines a track as a start point and a direction.
Definition Track.h:165
void clearIntersectionResults()
Clear the current set of intersection results.
Definition Track.cpp:55
double totalDistInsideObject() const
Returns the sum of all the links distInsideObject in the track.
Definition Track.cpp:254
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
double numberDensityEffective() const
Get the effective number density.
Definition Material.cpp:195
double linearAbsorpCoef(const double lambda=PhysicalConstants::NeutronAtom::ReferenceLambda) const
Returns the linear coefficient of absorption for the material in units of cm^-1 this should match the...
Definition Material.cpp:309
double totalScatterXSection() const
Return the total scattering cross section for a given wavelength in barns.
Definition Material.cpp:252
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Class for 3D vectors.
Definition V3D.h:34
void spherical(const double R, const double theta, const double phi) noexcept
Sets the vector position based on spherical coordinates.
Definition V3D.cpp:56
double norm() const noexcept
Definition V3D.h:269
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
MANTID_GEOMETRY_DLL Raster calculate(const Kernel::V3D &beamDirection, const IObject &integShape, const IObject &sampleShape, const double cubeSizeInMetre)
std::shared_ptr< const IObject > IObject_const_sptr
Typdef for a shared pointer to a const object.
Definition IObject.h:95
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.
Definition V3D.h:352
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
Holds the information used for doing numerical integrations of object in the beam.
Definition Rasterize.h:21
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54