Mantid
Loading...
Searching...
No Matches
NormaliseByDetector.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 +
12#include "MantidAPI/IFunction.h"
24
25using namespace Mantid::Kernel;
26using namespace Mantid::API;
27using namespace Mantid::Geometry;
28
29namespace Mantid::Algorithms {
30
31// Register the algorithm into the AlgorithmFactory
32DECLARE_ALGORITHM(NormaliseByDetector)
33
34//----------------------------------------------------------------------------------------------
37NormaliseByDetector::NormaliseByDetector(bool parallelExecution) : m_parallelExecution(parallelExecution) {}
38
39//----------------------------------------------------------------------------------------------
41const std::string NormaliseByDetector::name() const { return "NormaliseByDetector"; }
42
44int NormaliseByDetector::version() const { return 1; }
45
47const std::string NormaliseByDetector::category() const { return "CorrectionFunctions\\NormalisationCorrections"; }
48
49//----------------------------------------------------------------------------------------------
50
51//----------------------------------------------------------------------------------------------
55 auto compositeValidator = std::make_shared<CompositeValidator>();
56 compositeValidator->add(std::make_shared<API::WorkspaceUnitValidator>("Wavelength"));
57 compositeValidator->add(std::make_shared<API::HistogramValidator>());
58
60 std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input, compositeValidator),
61 "An input workspace in wavelength");
62
63 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
64 "An output workspace.");
65}
66
68NormaliseByDetector::tryParseFunctionParameter(const std::shared_ptr<const Geometry::Parameter> &parameter,
69 const std::string &detectorName) {
70 if (parameter == nullptr) {
71 std::stringstream stream;
72 stream << detectorName
73 << " and all of it's parent components, have no "
74 "fitting type parameters. This algorithm "
75 "cannot be run without fitting parameters. See "
76 "wiki help for details on setup.";
77 this->g_log.warning(stream.str());
78 throw std::runtime_error(stream.str());
79 }
80 return parameter->value<Geometry::FitParameter>();
81}
82
96 const MatrixWorkspace_sptr &denominatorWS, Progress &prog) {
97 const auto &componentInfo = inWS->componentInfo();
98 const auto &spectrumInfo = inWS->spectrumInfo();
99 // A spectrum of several detectors has no parameters of its own
100 const bool hasParameters = spectrumInfo.hasUniqueDetector(wsIndex);
101 const auto detIndex = spectrumInfo.spectrumDefinition(wsIndex)[0].first;
102 const auto &detName = componentInfo.name(detIndex);
103 const std::string type = "fitting";
104 const auto foundParam = hasParameters ? componentInfo.parameterByType(detIndex, type) : nullptr;
105
106 const Geometry::FitParameter &foundFittingParam = tryParseFunctionParameter(foundParam, detName);
107
108 const std::string &fitFunctionName = foundFittingParam.getFunction();
109 IFunction_sptr function = FunctionFactory::Instance().createFunction(fitFunctionName);
110 using ParamNames = std::vector<std::string>;
111 ParamNames allParamNames = function->getParameterNames();
112
113 // Lookup each parameter name.
114 for (auto &paramName : allParamNames) {
115 const auto param = componentInfo.parameter(detIndex, paramName, type);
116
117 const Geometry::FitParameter &fitParam = tryParseFunctionParameter(param, detName);
118
119 if (fitParam.getFormula().empty()) {
120 throw std::runtime_error("A Forumla has not been provided for a fit function");
121 } else {
122 const std::string &resultUnitStr = fitParam.getResultUnit();
123 if (!resultUnitStr.empty() && resultUnitStr != "Wavelength") {
124 throw std::runtime_error("Units for function parameters must be in Wavelength");
125 }
126 }
127 mu::Parser p;
128 p.SetExpr(fitParam.getFormula());
129 double paramValue = p.Eval();
130 // Set the function coeffiecents.
131 function->setParameter(fitParam.getName(), paramValue);
132 }
133
134 // const so that binding it to a std::span does not detach the cow_ptr
135 auto const wavelengths = inWS->points(wsIndex);
136 FunctionDomain1DVector domain(wavelengths);
137 FunctionValues values(domain);
138 function->function(domain, values);
139
140 auto &Y = denominatorWS->mutableY(wsIndex);
141 for (size_t i = 0; i < domain.size(); ++i) {
142 Y[i] = values[i];
143 }
144
145 denominatorWS->mutableE(wsIndex) = 0.0;
146
147 prog.report();
148}
149
157 const size_t nHistograms = inWS->getNumberHistograms();
158 const auto progress_items = static_cast<size_t>(double(nHistograms) * 1.2);
159 Progress prog(this, 0.0, 1.0, progress_items);
160 // Clone the input workspace to create a template for the denominator
161 // workspace.
162 auto cloneAlg = createChildAlgorithm("CloneWorkspace", 0.0, 0.1, true);
163 cloneAlg->setProperty("InputWorkspace", inWS);
164 cloneAlg->setPropertyValue("OutputWorkspace", "temp");
165 cloneAlg->executeAsChildAlg();
166 Workspace_sptr temp = cloneAlg->getProperty("OutputWorkspace");
167 MatrixWorkspace_sptr denominatorWS = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
168
169 // Choose between parallel execution and sequential execution then, process
170 // histograms accordingly.
172 PARALLEL_FOR_IF(Kernel::threadSafe(*inWS, *denominatorWS))
173 for (int wsIndex = 0; wsIndex < static_cast<int>(nHistograms); ++wsIndex) {
175 this->processHistogram(wsIndex, inWS, denominatorWS, prog);
177 }
179 } else {
180 for (size_t wsIndex = 0; wsIndex < nHistograms; ++wsIndex) {
181 this->processHistogram(wsIndex, inWS, denominatorWS, prog);
182 }
183 }
184
185 return denominatorWS;
186}
187
188//----------------------------------------------------------------------------------------------
192 MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
193
194 // Do the work of extracting functions and applying them to each bin on each
195 // histogram. The denominator workspace is mutable.
196 MatrixWorkspace_sptr denominatorWS = processHistograms(inWS);
197
198 // Perform the normalisation.
199 auto divideAlg = createChildAlgorithm("Divide", 0.9, 1.0, true);
200 divideAlg->setRethrows(true);
201 divideAlg->setProperty("LHSWorkspace", inWS);
202 divideAlg->setProperty("RHSWorkspace", denominatorWS);
203 divideAlg->executeAsChildAlg();
204 MatrixWorkspace_sptr outputWS = divideAlg->getProperty("OutputWorkspace");
205 setProperty("OutputWorkspace", outputWS);
206}
207
208} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
#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.
Kernel::Logger & g_log
Definition Algorithm.h:426
Implements FunctionDomain1D with its own storage in form of a std::vector.
size_t size() const override
Return the number of arguments in the domain.
A class to store values calculated by a function.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
NormaliseByDetector : Normalises a workspace with respect to the detector efficiency function stored ...
std::shared_ptr< Mantid::API::MatrixWorkspace > processHistograms(const std::shared_ptr< Mantid::API::MatrixWorkspace > &inWS)
Block to process histograms.
void exec() override
Execute the algorithm.
void init() override
Initialize the algorithm's properties.
const std::string category() const override
Algorithm's category for identification.
void processHistogram(size_t wsIndex, const std::shared_ptr< const Mantid::API::MatrixWorkspace > &inWS, const std::shared_ptr< Mantid::API::MatrixWorkspace > &denominatorWS, Mantid::API::Progress &prog)
Process indivdual histogram.
const bool m_parallelExecution
Flag to indicate that the histograms should be processed in parallel.
const Mantid::Geometry::FitParameter tryParseFunctionParameter(const std::shared_ptr< const Mantid::Geometry::Parameter > &parameter, const std::string &detectorName)
Try to parse a function parameter and extract the correctly typed parameter.
int version() const override
Algorithm's version for identification.
const std::string name() const override
Algorithm's name for identification.
Store information about a fitting parameter such as its value if it is constrained or tied.
const std::string & getName() const
get name
const std::string & getFormula() const
get formula
const std::string & getFunction() const
get function
const std::string & getResultUnit() const
get result formula unit, and Empty string is no unit has been specified
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
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:749
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.
@ Input
An input workspace.
Definition Property.h:54
@ Output
An output workspace.
Definition Property.h:55