Mantid
Loading...
Searching...
No Matches
SphericalAbsorption.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 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 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
12#include "MantidAPI/Sample.h"
24
25using namespace Mantid::PhysicalConstants;
26
27namespace Mantid::Algorithms {
28
29// Register the algorithm into the AlgorithmFactory
30DECLARE_ALGORITHM(SphericalAbsorption)
31
32using namespace Kernel;
33using namespace Geometry;
34using namespace API;
35using namespace DataObjects;
36
38 : API::Algorithm(), m_inputWS(), m_sampleObject(nullptr), m_beamDirection(), m_L1s(), m_elementVolumes(),
39 m_elementPositions(), m_numVolumeElements(0), m_sampleVolume(0.), m_refAtten(0.0), m_scattering(0.), n_lambda(0),
40 x_step(0), m_emode(0), m_lambdaFixed(0.) {}
41
43 // The input workspace must have an instrument and units of wavelength
44 auto wsValidator = std::make_shared<CompositeValidator>();
45 wsValidator->add<WorkspaceUnitValidator>("Wavelength");
46 wsValidator->add<InstrumentValidator>();
47
48 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input, wsValidator),
49 "The X values for the input workspace must be in units of wavelength");
50 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
51 "Output workspace name");
52
53 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
54 mustBePositive->setLower(0.0);
55 declareProperty("AttenuationXSection", EMPTY_DBL(), mustBePositive,
56 "The '''absorption''' cross-section, at 1.8 Angstroms, for "
57 "the sample material in barns, if not set with "
58 "SetSampleMaterial.");
59 declareProperty("ScatteringXSection", EMPTY_DBL(), mustBePositive,
60 "The (coherent + incoherent) scattering cross-section for "
61 "the sample material in barns, if not set with "
62 "SetSampleMaterial.");
63 declareProperty("SampleNumberDensity", EMPTY_DBL(), mustBePositive,
64 "The number density of the sample in number of atoms per "
65 "cubic angstrom, if not set with SetSampleMaterial");
66 declareProperty("SphericalSampleRadius", EMPTY_DBL(), mustBePositive,
67 "The radius of the spherical sample in centimetresif "
68 "not set with SetSample.");
69}
70
72 // Retrieve the input workspace
73 m_inputWS = getProperty("InputWorkspace");
74
75 // Get the input parameters
77
78 // Create the output workspace
79 MatrixWorkspace_sptr correctionFactors = WorkspaceFactory::Instance().create(m_inputWS);
80 correctionFactors->setDistribution(true); // The output of this is a distribution
81 correctionFactors->setYUnit(""); // Need to explicitly set YUnit to nothing
82 correctionFactors->setYUnitLabel("Attenuation factor");
83 double m_sphRadius = getProperty("SphericalSampleRadius"); // in cm
84
85 Progress progress(this, 0.0, 1.0, 2);
86
87 progress.report("AnvredCorrection");
88
89 auto anvred = createChildAlgorithm("AnvredCorrection");
90 anvred->setProperty<MatrixWorkspace_sptr>("InputWorkspace", m_inputWS);
91 anvred->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", correctionFactors);
92 anvred->setProperty("PreserveEvents", true);
93 anvred->setProperty("ReturnTransmissionOnly", true);
94 anvred->setProperty("LinearScatteringCoef", m_scattering);
95 anvred->setProperty("LinearAbsorptionCoef", m_refAtten);
96 anvred->setProperty("Radius", m_sphRadius);
97 anvred->executeAsChildAlg();
98
99 progress.report();
100
101 // Get back the result
102 correctionFactors = anvred->getProperty("OutputWorkspace");
103 setProperty("OutputWorkspace", correctionFactors);
104}
105
108 double sigma_atten = getProperty("AttenuationXSection"); // in barns
109 double sigma_s = getProperty("ScatteringXSection"); // in barns
110 double rho = getProperty("SampleNumberDensity"); // in Angstroms-3
111 const Material &sampleMaterial = m_inputWS->sample().getMaterial();
112 if (sampleMaterial.totalScatterXSection() != 0.0) {
113 if (rho == EMPTY_DBL())
114 rho = sampleMaterial.numberDensity();
115 if (sigma_s == EMPTY_DBL())
116 sigma_s = sampleMaterial.totalScatterXSection();
117 if (sigma_atten == EMPTY_DBL())
118 sigma_atten = sampleMaterial.absorbXSection(NeutronAtom::ReferenceLambda);
119 } else // Save input in Sample with wrong atomic number and name
120 {
121 NeutronAtom neutron(0, 0, 0.0, 0.0, sigma_s, 0.0, sigma_s, sigma_atten);
122 auto shape = std::shared_ptr<IObject>(
123 m_inputWS->sample().getShape().cloneWithMaterial(Material("SetInSphericalAbsorption", neutron, rho)));
124 m_inputWS->mutableSample().setShape(shape);
125 }
126
127 m_refAtten = sigma_atten * rho;
128 m_scattering = sigma_s * rho;
129}
130
131} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
double m_scattering
The scattering cross-section in 1/m.
API::MatrixWorkspace_sptr m_inputWS
A pointer to the input workspace.
void retrieveBaseProperties()
Fetch the properties and set the appropriate member variables.
double m_refAtten
The attenuation cross-section in 1/m at 1.8A.
void init() override
Initialisation code.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition: Material.h:50
double numberDensity() const
Get the number density.
Definition: Material.cpp:189
double absorbXSection(const double lambda=PhysicalConstants::NeutronAtom::ReferenceLambda) const
Get the absorption cross section at a given wavelength in barns.
Definition: Material.cpp:260
double totalScatterXSection() const
Return the total scattering cross section for a given wavelength in barns.
Definition: Material.cpp:252
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
A namespace containing physical constants that are required by algorithms and unit routines.
Definition: Atom.h:14
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54
Structure to store neutronic scattering information for the various elements.
Definition: NeutronAtom.h:22
static const double ReferenceLambda
The reference wavelength value for absorption cross sections.
Definition: NeutronAtom.h:25