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"
23
24using namespace Mantid::Kernel;
25using namespace Mantid::API;
26using namespace Mantid::Geometry;
27
28namespace Mantid::Algorithms {
29
30// Register the algorithm into the AlgorithmFactory
31DECLARE_ALGORITHM(NormaliseByDetector)
32
33//----------------------------------------------------------------------------------------------
36NormaliseByDetector::NormaliseByDetector(bool parallelExecution) : m_parallelExecution(parallelExecution) {}
37
38//----------------------------------------------------------------------------------------------
40const std::string NormaliseByDetector::name() const { return "NormaliseByDetector"; }
41
43int NormaliseByDetector::version() const { return 1; }
44
46const std::string NormaliseByDetector::category() const { return "CorrectionFunctions\\NormalisationCorrections"; }
47
48//----------------------------------------------------------------------------------------------
49
50//----------------------------------------------------------------------------------------------
54 auto compositeValidator = std::make_shared<CompositeValidator>();
55 compositeValidator->add(std::make_shared<API::WorkspaceUnitValidator>("Wavelength"));
56 compositeValidator->add(std::make_shared<API::HistogramValidator>());
57
59 std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input, compositeValidator),
60 "An input workspace in wavelength");
61
62 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
63 "An output workspace.");
64}
65
67 const Geometry::IDetector &det) {
68 if (parameter == nullptr) {
69 std::stringstream stream;
70 stream << det.getName()
71 << " and all of it's parent components, have no "
72 "fitting type parameters. This algorithm "
73 "cannot be run without fitting parameters. See "
74 "wiki help for details on setup.";
75 this->g_log.warning(stream.str());
76 throw std::runtime_error(stream.str());
77 }
78 return parameter->value<Geometry::FitParameter>();
79}
80
94 const MatrixWorkspace_sptr &denominatorWS, Progress &prog) {
95 const auto &paramMap = inWS->constInstrumentParameters();
96 const auto &spectrumInfo = inWS->spectrumInfo();
97 const auto &det = spectrumInfo.detector(wsIndex);
98 const std::string type = "fitting";
99 Geometry::Parameter_sptr foundParam = paramMap.getRecursiveByType(&det, type);
100
101 const Geometry::FitParameter &foundFittingParam = tryParseFunctionParameter(foundParam, det);
102
103 const std::string &fitFunctionName = foundFittingParam.getFunction();
104 IFunction_sptr function = FunctionFactory::Instance().createFunction(fitFunctionName);
105 using ParamNames = std::vector<std::string>;
106 ParamNames allParamNames = function->getParameterNames();
107
108 // Lookup each parameter name.
109 for (auto &name : allParamNames) {
110 Geometry::Parameter_sptr param = paramMap.getRecursive(&det, name, type);
111
112 const Geometry::FitParameter &fitParam = tryParseFunctionParameter(param, det);
113
114 if (fitParam.getFormula().empty()) {
115 throw std::runtime_error("A Forumla has not been provided for a fit function");
116 } else {
117 const std::string &resultUnitStr = fitParam.getResultUnit();
118 if (!resultUnitStr.empty() && resultUnitStr != "Wavelength") {
119 throw std::runtime_error("Units for function parameters must be in Wavelength");
120 }
121 }
122 mu::Parser p;
123 p.SetExpr(fitParam.getFormula());
124 double paramValue = p.Eval();
125 // Set the function coeffiecents.
126 function->setParameter(fitParam.getName(), paramValue);
127 }
128
129 auto wavelengths = inWS->points(wsIndex);
130 FunctionDomain1DVector domain(wavelengths.rawData());
131 FunctionValues values(domain);
132 function->function(domain, values);
133
134 auto &Y = denominatorWS->mutableY(wsIndex);
135 for (size_t i = 0; i < domain.size(); ++i) {
136 Y[i] = values[i];
137 }
138
139 denominatorWS->mutableE(wsIndex) = 0.0;
140
141 prog.report();
142}
143
151 const size_t nHistograms = inWS->getNumberHistograms();
152 const auto progress_items = static_cast<size_t>(double(nHistograms) * 1.2);
153 Progress prog(this, 0.0, 1.0, progress_items);
154 // Clone the input workspace to create a template for the denominator
155 // workspace.
156 auto cloneAlg = createChildAlgorithm("CloneWorkspace", 0.0, 0.1, true);
157 cloneAlg->setProperty("InputWorkspace", inWS);
158 cloneAlg->setPropertyValue("OutputWorkspace", "temp");
159 cloneAlg->executeAsChildAlg();
160 Workspace_sptr temp = cloneAlg->getProperty("OutputWorkspace");
161 MatrixWorkspace_sptr denominatorWS = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
162
163 // Choose between parallel execution and sequential execution then, process
164 // histograms accordingly.
166 PARALLEL_FOR_IF(Kernel::threadSafe(*inWS, *denominatorWS))
167 for (int wsIndex = 0; wsIndex < static_cast<int>(nHistograms); ++wsIndex) {
169 this->processHistogram(wsIndex, inWS, denominatorWS, prog);
171 }
173 } else {
174 for (size_t wsIndex = 0; wsIndex < nHistograms; ++wsIndex) {
175 this->processHistogram(wsIndex, inWS, denominatorWS, prog);
176 }
177 }
178
179 return denominatorWS;
180}
181
182//----------------------------------------------------------------------------------------------
186 MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
187
188 // Do the work of extracting functions and applying them to each bin on each
189 // histogram. The denominator workspace is mutable.
190 MatrixWorkspace_sptr denominatorWS = processHistograms(inWS);
191
192 // Perform the normalisation.
193 auto divideAlg = createChildAlgorithm("Divide", 0.9, 1.0, true);
194 divideAlg->setRethrows(true);
195 divideAlg->setProperty("LHSWorkspace", inWS);
196 divideAlg->setProperty("RHSWorkspace", denominatorWS);
197 divideAlg->executeAsChildAlg();
198 MatrixWorkspace_sptr outputWS = divideAlg->getProperty("OutputWorkspace");
199 setProperty("OutputWorkspace", outputWS);
200}
201
202} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#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...
Definition: MultiThreaded.h:94
#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.
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
Kernel::Logger & g_log
Definition: Algorithm.h:451
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.
const Mantid::Geometry::FitParameter tryParseFunctionParameter(const Mantid::Geometry::Parameter_sptr &parameter, const Geometry::IDetector &det)
Try to parse a function parameter and extract the correctly typed parameter.
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.
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.
Definition: FitParameter.h:26
const std::string & getName() const
get name
Definition: FitParameter.h:70
const std::string & getFormula() const
get formula
Definition: FitParameter.h:54
const std::string & getFunction() const
get function
Definition: FitParameter.h:66
const std::string & getResultUnit() const
get result formula unit, and Empty string is no unit has been specified
Definition: FitParameter.h:62
virtual std::string getName() const =0
Get the IComponent name.
Interface class for detector objects.
Definition: IDetector.h:43
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:86
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
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:732
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
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.
Definition: MultiThreaded.h:22
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54