Mantid
Loading...
Searching...
No Matches
SetSampleMaterial.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 +
10#include "MantidAPI/Sample.h"
11#include "MantidAPI/Workspace.h"
13#include "MantidKernel/Atom.h"
20
21using namespace Mantid::PhysicalConstants;
22
23namespace Mantid::DataHandling {
24// Register the algorithm into the AlgorithmFactory
26
27const std::string SetSampleMaterial::name() const { return "SetSampleMaterial"; }
28
29int SetSampleMaterial::version() const { return (1); }
30
31const std::string SetSampleMaterial::category() const { return "Sample"; }
32
33using namespace Mantid::DataHandling;
34using namespace Mantid::API;
35using namespace Kernel;
36
41 using namespace Mantid::Kernel;
42 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::InOut),
43 "The workspace with which to associate the sample ");
44 declareProperty("ChemicalFormula", "", "The chemical formula, see examples in documentation");
45 declareProperty("AtomicNumber", 0, "The atomic number");
46 declareProperty("MassNumber", 0, "Mass number if ion (use 0 for default mass number)");
47 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
48 mustBePositive->setLower(0.0);
49 declareProperty("SampleNumberDensity", EMPTY_DBL(), mustBePositive,
50 "This number density of the sample in number of "
51 "atoms or formula units per cubic Angstrom will be used instead of "
52 "calculated");
53 declareProperty("SampleEffectiveNumberDensity", EMPTY_DBL(), mustBePositive,
54 "Defines the effective number density of the sample, which is "
55 "related to the number density and packing fraction.");
56 declareProperty("SamplePackingFraction", EMPTY_DBL(), mustBePositive,
57 "Defines the packing fraction of the sample which can be used "
58 "to calculate the number density and the effective number density");
59 declareProperty("ZParameter", EMPTY_DBL(), mustBePositive, "Number of formula units in unit cell");
60 declareProperty("UnitCellVolume", EMPTY_DBL(), mustBePositive,
61 "Unit cell volume in Angstoms^3. Will be calculated from the "
62 "OrientedLattice if not supplied.");
63 declareProperty("CoherentXSection", EMPTY_DBL(), mustBePositive,
64 "This coherent cross-section for the sample "
65 "material in barns will be used instead of tabulated");
66 declareProperty("IncoherentXSection", EMPTY_DBL(), mustBePositive,
67 "This incoherent cross-section for the sample "
68 "material in barns will be used instead of tabulated");
69 declareProperty("AttenuationXSection", EMPTY_DBL(), mustBePositive,
70 "This absorption cross-section for the sample "
71 "material in barns will be used instead of tabulated");
72 declareProperty("ScatteringXSection", EMPTY_DBL(), mustBePositive,
73 "Optional: This total scattering cross-section (coherent + "
74 "incoherent) for the sample material in barns will be used "
75 "instead of tabulated");
76 const std::vector<std::string> extensions{".DAT"};
77 declareProperty(std::make_unique<FileProperty>("AttenuationProfile", "", FileProperty::OptionalLoad, extensions),
78 "The path name of the file containing the attenuation profile");
79
80 declareProperty(std::make_unique<FileProperty>("XRayAttenuationProfile", "", FileProperty::OptionalLoad, extensions),
81 "The path name of the file containing the Xray attenuation profile");
82
83 declareProperty("SampleMassDensity", EMPTY_DBL(), mustBePositive,
84 "Measured mass density in g/cubic cm of the sample "
85 "to be used to calculate the effective number density.");
86 declareProperty("SampleMass", EMPTY_DBL(), mustBePositive,
87 "Measured mass in g of the sample. This is used with the SampleVolume "
88 "to calculate the number density.");
89 declareProperty("SampleVolume", EMPTY_DBL(), mustBePositive,
90 "Measured volume in gm^3 of the sample. This is used with the SampleMass "
91 "to calculate the number density.");
92 const std::vector<std::string> units({"Atoms", "Formula Units"});
93 declareProperty("NumberDensityUnit", units.front(), std::make_shared<StringListValidator>(units),
94 "Choose which units SampleNumberDensity referes to.");
95
96 // Perform Group Associations.
97 std::string formulaGrp("By Formula or Atomic Number");
98 setPropertyGroup("ChemicalFormula", formulaGrp);
99 setPropertyGroup("AtomicNumber", formulaGrp);
100 setPropertyGroup("MassNumber", formulaGrp);
101
102 std::string densityGrp("Sample Density");
103 setPropertyGroup("SampleNumberDensity", densityGrp);
104 setPropertyGroup("SampleEffectiveNumberDensity", densityGrp);
105 setPropertyGroup("SamplePackingFraction", densityGrp);
106 setPropertyGroup("NumberDensityUnit", densityGrp);
107 setPropertyGroup("ZParameter", densityGrp);
108 setPropertyGroup("UnitCellVolume", densityGrp);
109 setPropertyGroup("SampleMassDensity", densityGrp);
110 setPropertyGroup("SampleMass", densityGrp);
111 setPropertyGroup("SampleVolume", densityGrp);
112
113 std::string specificValuesGrp("Override Cross Section Values");
114 setPropertyGroup("CoherentXSection", specificValuesGrp);
115 setPropertyGroup("IncoherentXSection", specificValuesGrp);
116 setPropertyGroup("AttenuationXSection", specificValuesGrp);
117 setPropertyGroup("ScatteringXSection", specificValuesGrp);
118 setPropertyGroup("AttenuationProfile", specificValuesGrp);
119 setPropertyGroup("XRayAttenuationProfile", specificValuesGrp);
120
121 // Extra property settings
122 setPropertySettings("ChemicalFormula",
123 std::make_unique<Kernel::EnabledWhenProperty>("AtomicNumber", Kernel::IS_DEFAULT));
124 setPropertySettings("AtomicNumber",
125 std::make_unique<Kernel::EnabledWhenProperty>("ChemicalFormula", Kernel::IS_DEFAULT));
126 setPropertySettings("MassNumber",
127 std::make_unique<Kernel::EnabledWhenProperty>("ChemicalFormula", Kernel::IS_DEFAULT));
128 setPropertySettings("NumberDensityUnit",
129 std::make_unique<Kernel::EnabledWhenProperty>("SampleNumberDensity", Kernel::IS_NOT_DEFAULT));
130}
131
132std::map<std::string, std::string> SetSampleMaterial::validateInputs() {
133 params.chemicalSymbol = getPropertyValue("ChemicalFormula");
134 params.atomicNumber = getProperty("AtomicNumber");
135 params.massNumber = getProperty("MassNumber");
136 params.numberDensity = getProperty("SampleNumberDensity");
137 params.numberDensityEffective = getProperty("SampleEffectiveNumberDensity");
138 params.packingFraction = getProperty("SamplePackingFraction");
139 params.zParameter = getProperty("ZParameter");
140 params.unitCellVolume = getProperty("UnitCellVolume");
141 params.massDensity = getProperty("SampleMassDensity");
142 params.mass = getProperty("SampleMass");
143 params.volume = getProperty("SampleVolume");
144 params.coherentXSection = getProperty("CoherentXSection");
145 params.incoherentXSection = getProperty("IncoherentXSection");
146 params.attenuationXSection = getProperty("AttenuationXSection");
147 params.scatteringXSection = getProperty("ScatteringXSection");
148 params.attenuationProfileFileName = getPropertyValue("AttenuationProfile");
149 params.xRayAttenuationProfileFileName = getPropertyValue("XRayAttenuationProfile");
150 const std::string numberDensityUnit = getProperty("NumberDensityUnit");
151 if (numberDensityUnit == "Atoms") {
153 } else {
155 }
157
158 return result;
159}
160
171void SetSampleMaterial::fixNeutron(NeutronAtom &neutron, double coh_xs, double inc_xs, double abs_xs, double tot_xs) {
172 if (!isEmpty(coh_xs))
173 neutron.coh_scatt_xs = coh_xs;
174 if (!isEmpty(inc_xs))
175 neutron.inc_scatt_xs = inc_xs;
176 if (!isEmpty(abs_xs))
177 neutron.abs_scatt_xs = abs_xs;
178 if (!isEmpty(tot_xs))
179 neutron.tot_scatt_xs = tot_xs;
180}
181
186 // Get the input workspace
187 Workspace_sptr workspace = getProperty("InputWorkspace");
188 // an ExperimentInfo object has a sample
189 ExperimentInfo_sptr expInfo = std::dynamic_pointer_cast<ExperimentInfo>(workspace);
190 if (!expInfo) {
191 throw std::runtime_error("InputWorkspace does not have a sample object");
192 }
193
194 ReadMaterial reader;
196
197 // get the scattering information - this will override table values
198 // create the material
199 auto material = reader.buildMaterial();
200
201 // calculate derived values
202 const double bcoh_avg_sq = material->cohScatterLengthSqrd(); // <b>
203 const double btot_sq_avg = material->totalScatterLengthSqrd(); // <b^2>
204 double normalizedLaue = (btot_sq_avg - bcoh_avg_sq) / bcoh_avg_sq;
205 if (btot_sq_avg == bcoh_avg_sq)
206 normalizedLaue = 0.;
207
208 // set the material but leave the geometry unchanged
209 auto shapeObject = std::shared_ptr<Geometry::IObject>(expInfo->sample().getShape().cloneWithMaterial(*material));
210 expInfo->mutableSample().setShape(shapeObject);
211 g_log.information() << "Sample number density ";
212 if (isEmpty(material->numberDensity())) {
213 g_log.information() << "was not specified\n";
214 } else {
215 g_log.information() << "= " << material->numberDensity() << " atoms/Angstrom^3\n";
216 }
217 g_log.information() << "Cross sections for wavelength = " << NeutronAtom::ReferenceLambda << " Angstroms\n"
218 << " Coherent " << material->cohScatterXSection() << " barns\n"
219 << " Incoherent " << material->incohScatterXSection() << " barns\n"
220 << " Total " << material->totalScatterXSection() << " barns\n"
221 << " Absorption " << material->absorbXSection() << " barns\n"
222 << "PDF terms\n"
223 << " <b_coh>^2 = " << bcoh_avg_sq << "\n"
224 << " <b_tot^2> = " << btot_sq_avg << "\n"
225 << " L = " << normalizedLaue << "\n";
226
227 if (isDefault("SampleNumberDensity") && isDefault("SampleMassDensity")) {
228 g_log.information("Unknown value for number density");
229 } else {
230 const double rho = material->numberDensity();
231 double smu = material->totalScatterXSection() * rho;
232 double amu = material->absorbXSection(NeutronAtom::ReferenceLambda) * rho;
233 g_log.information() << "Anvred LinearScatteringCoef = " << smu << " 1/cm\n"
234 << "Anvred LinearAbsorptionCoef = " << amu << " 1/cm\n";
235 }
236 // Done!
237 progress(1);
238}
239} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
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
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
bool isDefault(const std::string &name) const
Definition: Algorithm.cpp:2084
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Definition: FileProperty.h:53
A property class for workspaces.
This class contains code for interpreting a material input for SetSampleMaterial, validating the para...
Definition: ReadMaterial.h:26
std::unique_ptr< Kernel::Material > buildMaterial()
Construct the material,.
void setMaterialParameters(const MaterialParameters &params)
Set the parameters to build the material to the builder, taking into account which values were and we...
static ValidationErrors validateInputs(const MaterialParameters &params)
Validate the parameters to build the material from, this returns any errors in the inputs.
This class allows the shape of the sample to be defined by using the allowed XML expressions.
void exec() override
Execution code.
ReadMaterial::MaterialParameters params
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
void init() override
Initialisation code.
void fixNeutron(PhysicalConstants::NeutronAtom &neutron, double coh_xs, double inc_xs, double abs_xs, double tot_xs)
Print out the list of information for the material.
int version() const override
Algorithm's version.
const std::string category() const override
Algorithm's category for identification.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
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
STL namespace.
double numberDensity
The sample number density to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:40
double coherentXSection
The coherent scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:56
int massNumber
The mass number to set, defaults to 0.
Definition: ReadMaterial.h:38
double mass
The sample mass to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:52
double packingFraction
The sample packing fraction.
Definition: ReadMaterial.h:44
double attenuationXSection
The absorption cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:60
Kernel::MaterialBuilder::NumberDensityUnit numberDensityUnit
A flag indicating the unit of sampleNumberDensity.
Definition: ReadMaterial.h:68
double volume
The sample volume to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:54
double massDensity
The sample mass density to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:50
double scatteringXSection
The total scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:62
double incoherentXSection
The incoherent scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:58
double zParameter
The zParameter to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:46
std::string chemicalSymbol
The chemical formula to set, defaults to the empty string.
Definition: ReadMaterial.h:34
double numberDensityEffective
The sample effective number density.
Definition: ReadMaterial.h:42
std::string xRayAttenuationProfileFileName
The name or path of a file containing an x ray attenuation profile.
Definition: ReadMaterial.h:66
double unitCellVolume
The unit cell volume to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:48
int atomicNumber
The atomic number to set, defaults to 0.
Definition: ReadMaterial.h:36
std::string attenuationProfileFileName
The name or path of a file containing an attenuation profile.
Definition: ReadMaterial.h:64
@ InOut
Both an input & output workspace.
Definition: Property.h:55
Structure to store neutronic scattering information for the various elements.
Definition: NeutronAtom.h:22
double inc_scatt_xs
The incoherent scattering cross section in barns.
Definition: NeutronAtom.h:66
double tot_scatt_xs
The total scattering cross section in barns.
Definition: NeutronAtom.h:69
double abs_scatt_xs
The absorption cross section for 2200m/s neutrons in barns.
Definition: NeutronAtom.h:72
double coh_scatt_xs
The coherent scattering cross section in barns.
Definition: NeutronAtom.h:63
static const double ReferenceLambda
The reference wavelength value for absorption cross sections.
Definition: NeutronAtom.h:25