Mantid
Loading...
Searching...
No Matches
MDNormDirectSC.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 +
8
14
15namespace Mantid::MDAlgorithms {
16
19using namespace Mantid::DataObjects;
20using namespace Mantid::API;
21using namespace Mantid::Kernel;
22
23// Register the algorithm into the AlgorithmFactory
24DECLARE_ALGORITHM(MDNormDirectSC)
25
26
27int MDNormDirectSC::version() const { return 1; }
28
30const std::string MDNormDirectSC::category() const { return "MDAlgorithms\\Normalisation"; }
31
33const std::string MDNormDirectSC::summary() const {
34 return "Calculate normalization for an MDEvent workspace for single crystal "
35 "direct geometry inelastic measurement.";
36}
37
39const std::string MDNormDirectSC::name() const { return "MDNormDirectSC"; }
40
45 declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("InputWorkspace", "", Direction::Input),
46 "An input MDWorkspace.");
47
48 std::string dimChars = getDimensionChars();
49 // --------------- Axis-aligned properties
50 // ---------------------------------------
51 for (size_t i = 0; i < dimChars.size(); i++) {
52 std::string dim(" ");
53 dim[0] = dimChars[i];
54 std::string propName = "AlignedDim" + dim;
56 "Binning parameters for the " + Strings::toString(i) +
57 "th dimension.\n"
58 "Enter it as a comma-separated list of values with the format: "
59 "'name,minimum,maximum,number_of_bins'. Leave blank for NONE.");
60 }
61
62 auto solidAngleValidator = std::make_shared<CompositeValidator>();
63 solidAngleValidator->add<InstrumentValidator>();
64 solidAngleValidator->add<CommonBinsValidator>();
65
66 m_progress = std::make_unique<API::Progress>(this, 0, 1, 1);
67
68 declareProperty(std::make_unique<WorkspaceProperty<>>("SolidAngleWorkspace", "", Direction::Input,
69 PropertyMode::Optional, solidAngleValidator),
70 "An input workspace containing integrated vanadium (a measure of the "
71 "solid angle).");
72
73 declareProperty(std::make_unique<PropertyWithValue<bool>>("SkipSafetyCheck", false, Direction::Input),
74 "If set to true, the algorithm does "
75 "not check history if the workspace was modified since the"
76 "ConvertToMD algorithm was run, and assume that the direct "
77 "geometry inelastic mode is used.");
78
79 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("TemporaryNormalizationWorkspace", "",
81 "An input MDHistoWorkspace used to accumulate normalization "
82 "from multiple MDEventWorkspaces. If unspecified a blank "
83 "MDHistoWorkspace will be created.");
84
85 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("TemporaryDataWorkspace", "", Direction::Input,
87 "An input MDHistoWorkspace used to accumulate data from "
88 "multiple MDEventWorkspaces. If unspecified a blank "
89 "MDHistoWorkspace will be created.");
90
91 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputWorkspace", "", Direction::Output),
92 "A name for the output data MDHistoWorkspace.");
93 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("OutputNormalizationWorkspace", "", Direction::Output),
94 "A name for the output normalization MDHistoWorkspace.");
95}
96
97//----------------------------------------------------------------------------------------------
102 cacheInputs();
103 auto outputWS = binInputWS();
104 m_convention = Kernel::ConfigService::Instance().getString("Q.convention");
105 outputWS->setDisplayNormalization(Mantid::API::NoNormalization);
106 setProperty<Workspace_sptr>("OutputWorkspace", outputWS);
107 createNormalizationWS(*outputWS);
108 m_normWS->setDisplayNormalization(Mantid::API::NoNormalization);
109 setProperty("OutputNormalizationWorkspace", m_normWS);
110 m_diffraction = false;
111
112 m_numExptInfos = outputWS->getNumExperimentInfo();
113 m_signalArray = std::vector<std::atomic<signal_t>>(m_normWS->getNPoints());
114 // loop over all experiment infos
115 m_progress->resetNumSteps(m_numExptInfos, 0.3, 1.0);
116 for (uint16_t expInfoIndex = 0; expInfoIndex < m_numExptInfos; expInfoIndex++) {
117 const auto &currentExptInfo = *(m_inputWS->getExperimentInfo(expInfoIndex));
118 if (!currentExptInfo.run().hasProperty("RUBW_MATRIX")) {
119 throw std::runtime_error("Wokspace does not contain a log entry for the RUBW matrix."
120 "Cannot continue.");
121 }
122 // Check for other dimensions if we could measure anything in the original
123 // data
124 bool skipNormalization = false;
125 const std::vector<coord_t> otherValues = getValuesFromOtherDimensions(skipNormalization, expInfoIndex);
126 findIntegratedDimensions(otherValues, skipNormalization);
128
129 if (!skipNormalization) {
130 if (currentExptInfo.run().hasProperty("useLogTimes")) {
131 calculateNormContinuous(otherValues, expInfoIndex);
132 } else {
133 calculateNormalization(otherValues, expInfoIndex);
134 }
135 } else {
136 g_log.warning("Binning limits are outside the limits of the MDWorkspace. "
137 "Not applying normalization.");
138 }
139 m_progress->report();
140 }
141 if (m_accumulate) {
142 std::transform(m_signalArray.cbegin(), m_signalArray.cend(), m_normWS->getSignalArray(),
143 m_normWS->mutableSignalArray(),
144 [](const std::atomic<signal_t> &a, const signal_t &b) { return a + b; });
145 } else {
146 std::copy(m_signalArray.cbegin(), m_signalArray.cend(), m_normWS->mutableSignalArray());
147 }
148
149 // Set the display normalization based on the input workspace
150 outputWS->setDisplayNormalization(m_inputWS->displayNormalizationHisto());
151}
152
157 m_inputWS = getProperty("InputWorkspace");
158 bool skipCheck = getProperty("SkipSafetyCheck");
159 if (!skipCheck && (inputEnergyMode() != "Direct")) {
160 throw std::invalid_argument("Invalid energy transfer mode. Algorithm only "
161 "supports direct geometry spectrometers.");
162 }
163 // Min/max dimension values
164 const auto hdim(m_inputWS->getDimension(0)), kdim(m_inputWS->getDimension(1)), ldim(m_inputWS->getDimension(2)),
165 edim(m_inputWS->getDimension(3));
166 m_hmin = hdim->getMinimum();
167 m_kmin = kdim->getMinimum();
168 m_lmin = ldim->getMinimum();
169 m_dEmin = edim->getMinimum();
170 m_hmax = hdim->getMaximum();
171 m_kmax = kdim->getMaximum();
172 m_lmax = ldim->getMaximum();
173 m_dEmax = edim->getMaximum();
174
175 const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0));
176 auto source = exptInfoZero.getInstrument()->getSource();
177 auto sample = exptInfoZero.getInstrument()->getSample();
178 if (source == nullptr || sample == nullptr) {
180 "Instrument not sufficiently defined: failed to get source and/or "
181 "sample");
182 }
183 m_samplePos = sample->getPos();
184 m_beamDir = normalize(m_samplePos - source->getPos());
185
186 double originaldEmin = exptInfoZero.run().getBinBoundaries().front();
187 double originaldEmax = exptInfoZero.run().getBinBoundaries().back();
188 if (exptInfoZero.run().hasProperty("Ei")) {
189 m_Ei = exptInfoZero.run().getPropertyValueAsType<double>("Ei");
190 if (m_Ei <= 0) {
191 throw std::invalid_argument("Ei stored in the workspace is not positive");
192 }
193 } else {
194 throw std::invalid_argument("Could not find Ei value in the workspace.");
195 }
196 double eps = 1e-7;
197 if (m_Ei - originaldEmin < eps) {
198 originaldEmin = m_Ei - eps;
199 }
200 if (m_Ei - originaldEmax < eps) {
201 originaldEmax = m_Ei - 1e-7;
202 }
203 if (originaldEmin == originaldEmax) {
204 throw std::runtime_error("The limits of the original workspace used in "
205 "ConvertToMD are incorrect");
206 }
207 const double energyToK = 8.0 * M_PI * M_PI * PhysicalConstants::NeutronMass * PhysicalConstants::meV * 1e-20 /
209 m_ki = std::sqrt(energyToK * m_Ei);
210 m_kfmin = std::sqrt(energyToK * (m_Ei - originaldEmin));
211 m_kfmax = std::sqrt(energyToK * (m_Ei - originaldEmax));
212}
213
214} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:542
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.
Kernel::Logger & g_log
Definition Algorithm.h:423
A validator which provides a TENTATIVE check that a workspace contains common bins in each spectrum.
A validator which checks that a workspace has a valid instrument.
A property class for workspaces.
Exception for errors associated with the instrument definition.
Definition Exception.h:220
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
The concrete, templated class for properties.
API::IMDEventWorkspace_sptr m_inputWS
Input workspace.
Definition MDNormBase.h:69
void createNormalizationWS(const DataObjects::MDHistoWorkspace &dataWS)
Create & cached the normalization workspace.
bool m_diffraction
Flag indicating if the input workspace is from diffraction.
Definition MDNormBase.h:100
static std::string getDimensionChars()
Definition MDNormBase.h:36
void cacheDimensionXValues()
Stores the X values from each H,K,L,E dimension as member variables Energy dimension is transformed t...
void findIntegratedDimensions(const std::vector< coord_t > &otherDimValues, bool &skipNormalization)
Checks the normalization workspace against the indices of the original dimensions.
void calculateNormalization(const std::vector< coord_t > &otherValues, uint16_t expInfoIndex)
Computed the normalization for the input workspace (for MDNormSCD/MDNormDirectSC).
DataObjects::MDHistoWorkspace_sptr m_normWS
Normalization workspace.
Definition MDNormBase.h:71
Kernel::V3D m_samplePos
Sample position.
Definition MDNormBase.h:92
std::vector< coord_t > getValuesFromOtherDimensions(bool &skipNormalization, uint16_t expInfoIndex=0) const
Retrieve logged values from non-HKL dimensions.
std::vector< std::atomic< signal_t > > m_signalArray
internal array to accumulate signals to avoid copying (serial) each loop
Definition MDNormBase.h:106
bool m_accumulate
Flag to accumulate normalization.
Definition MDNormBase.h:102
DataObjects::MDHistoWorkspace_sptr binInputWS()
Runs the BinMD algorithm on the input to provide the output workspace All slicing algorithm propertie...
uint16_t m_numExptInfos
number of experiment infos
Definition MDNormBase.h:98
Kernel::V3D m_beamDir
Beam direction.
Definition MDNormBase.h:94
coord_t m_hmin
limits for h,k,l, dE dimensions
Definition MDNormBase.h:76
std::unique_ptr< API::Progress > m_progress
Progress bar.
Definition MDNormBase.h:104
void calculateNormContinuous(const std::vector< coord_t > &otherValues, uint16_t expInfoIndex, const Geometry::SymmetryOperation *so=nullptr)
Computes the normalization for the input workspace for the case of a continous rotation.
std::string inputEnergyMode() const
Currently looks for the ConvertToMD algorithm in the history.
std::string m_convention
ki-kf for Inelastic convention; kf-ki for Crystallography convention
Definition MDNormBase.h:96
double m_Ei
cached values for incident energy and momentum, final momentum min/max
Definition MDNormBase.h:78
MDNormDirectSC : Generate MD normalization for single crystal direct geometry inelastic.
const std::string name() const override
Algorithm's name for use in the GUI and help.
void cacheInputs()
Set up starting values for cached variables.
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
@ NoNormalization
Don't normalize = return raw counts.
Definition IMDIterator.h:27
std::string toString(const T &value)
Convert a number to a string.
Definition Strings.cpp:734
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
Definition V3D.h:352
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h
Planck constant in J*s.
static constexpr double meV
1 meV in Joules.
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition MDTypes.h:36
Describes the direction (within an algorithm) of a Property.
Definition Property.h:50
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54