Mantid
Loading...
Searching...
No Matches
FlippingRatioCorrectionMD.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2019 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 +
9#include "MantidAPI/Run.h"
17
18#include <muParser.h>
19
20namespace Mantid::MDAlgorithms {
21using namespace Mantid::API;
22using namespace Mantid::DataObjects;
25
26// Register the algorithm into the AlgorithmFactory
27DECLARE_ALGORITHM(FlippingRatioCorrectionMD)
28
29//----------------------------------------------------------------------------------------------
30
31
32const std::string FlippingRatioCorrectionMD::name() const { return "FlippingRatioCorrectionMD"; }
33
35int FlippingRatioCorrectionMD::version() const { return 1; }
36
38const std::string FlippingRatioCorrectionMD::category() const { return "MDAlgorithms\\Transforms"; }
39
41const std::string FlippingRatioCorrectionMD::summary() const {
42 return "Creates MDEvent workspaces with polarization flipping ratio "
43 "corrections."
44 "The polarization might be angle dependent.";
45}
46
47//----------------------------------------------------------------------------------------------
52 std::make_unique<WorkspaceProperty<API::IMDEventWorkspace>>("InputWorkspace", "", Kernel::Direction::Input),
53 "An input MDEventWorkspace.");
56 "FlippingRatio", "", std::make_shared<Mantid::Kernel::MandatoryValidator<std::string>>(), Direction::Input),
57 "Formula to define the flipping ratio. It can depend on the variables in "
58 "the list "
59 "of sample logs defined below");
61 "Comma separated list of sample logs that can appear in the formula for "
62 "flipping ratio");
63 declareProperty(std::make_unique<WorkspaceProperty<API::Workspace>>("OutputWorkspace1", "", Direction::Output),
64 "Output workspace 1. Equal to Input workspace multiplied by FR/(FR-1).");
65 declareProperty(std::make_unique<WorkspaceProperty<API::Workspace>>("OutputWorkspace2", "", Direction::Output),
66 "Output workspace 2. Equal to Input workspace multiplied by 1/(FR-1).");
67}
68
69//----------------------------------------------------------------------------------------------
72std::map<std::string, std::string> FlippingRatioCorrectionMD::validateInputs() {
73 std::map<std::string, std::string> errors;
74 if (getPropertyValue("OutputWorkspace1") == getPropertyValue("OutputWorkspace2")) {
75 const std::string message("The two output workspace names must be different");
76 errors.emplace("OutputWorkspace1", message);
77 errors.emplace("OutputWorkspace2", message);
78 }
79 return errors;
80}
81
82//----------------------------------------------------------------------------------------------
87 inWS = getProperty("InputWorkspace");
88 std::string inputFormula = getProperty("FlippingRatio");
89 std::vector<std::string> sampleLogStrings = getProperty("SampleLogs");
90
91 std::vector<double> flippingRatio, C1, C2; // C1=FR/(FR-1.), C2=1./(FR-1.)
92
93 for (uint16_t i = 0; i < inWS->getNumExperimentInfo(); i++) {
94 const auto &currentRun = inWS->getExperimentInfo(i)->run();
95 std::vector<double> sampleLogs(sampleLogStrings.size());
96 mu::Parser muParser;
97 for (size_t j = 0; j < sampleLogStrings.size(); j++) {
98 std::string s = sampleLogStrings[j];
99 double val = currentRun.getLogAsSingleValue(s, Kernel::Math::TimeAveragedMean);
100 sampleLogs[j] = val;
101 muParser.DefineVar(s, &sampleLogs[j]);
102 }
103 muParser.DefineConst("pi", M_PI);
104 muParser.SetExpr(inputFormula);
105 try {
106 flippingRatio.emplace_back(muParser.Eval());
107 } catch (mu::Parser::exception_type &e) {
108 g_log.error() << "Parsing error in experiment info " << i << "\n"
109 << e.GetMsg() << std::endl
110 << "Formula: " << inputFormula << std::endl;
111 throw std::runtime_error("Parsing error");
112 }
113 }
114 for (const auto &fr : flippingRatio) {
115 C1.emplace_back(fr / (fr - 1.));
116 C2.emplace_back(1. / (fr - 1.));
117 }
118 // Create workspaces by cloning
119 API::IMDWorkspace_sptr outputWS1, outputWS2;
120 auto cloneMD = createChildAlgorithm("CloneMDWorkspace", 0, 0.25, true);
121 cloneMD->setRethrows(true);
122 cloneMD->setProperty("InputWorkspace", inWS);
123 cloneMD->setProperty("OutputWorkspace", getPropertyValue("OutputWorkspace1"));
124 cloneMD->executeAsChildAlg();
125 outputWS1 = cloneMD->getProperty("OutputWorkspace");
126 API::IMDEventWorkspace_sptr event1 = std::dynamic_pointer_cast<API::IMDEventWorkspace>(outputWS1);
127 cloneMD->setProperty("OutputWorkspace", getPropertyValue("OutputWorkspace2"));
128 cloneMD->setChildStartProgress(0.25);
129 cloneMD->setChildEndProgress(0.5);
130 cloneMD->executeAsChildAlg();
131 outputWS2 = cloneMD->getProperty("OutputWorkspace");
132 API::IMDEventWorkspace_sptr event2 = std::dynamic_pointer_cast<API::IMDEventWorkspace>(outputWS2);
133
134 if (event1) {
135 m_factor = C1;
137 this->setProperty("OutputWorkspace1", event1);
138 } else {
139 throw std::runtime_error("Could not clone the workspace for first "
140 "correction (OutputWorkspace1)");
141 }
142 if (event2) {
143 m_factor = C2;
145 this->setProperty("OutputWorkspace2", event2);
146 } else {
147 throw std::runtime_error("Could not clone the workspace for second "
148 "correction (OutputWorkspace2)");
149 }
150}
151
152template <typename MDE, size_t nd>
154 // Get all the MDBoxes contained
155 DataObjects::MDBoxBase<MDE, nd> *parentBox = ws->getBox();
156 std::vector<API::IMDNode *> boxes;
157 // getBoxes(boxes, maxDepth, leafOnly)
158 parentBox->getBoxes(boxes, 1000, true);
159
160 const bool fileBackedTarget = ws->isFileBacked();
161 Kernel::DiskBuffer *dbuff(nullptr);
162 if (fileBackedTarget) {
163 dbuff = ws->getBoxController()->getFileIO();
164 }
165 for (const auto &boxe : boxes) {
166 auto *box = dynamic_cast<DataObjects::MDBox<MDE, nd> *>(boxe);
167 if (box) {
168 auto &events = box->getEvents();
169 const bool hasEvents = !events.empty();
170 for (auto &event : events) {
171 const auto ind = static_cast<size_t>(event.getExpInfoIndex());
172 const auto scalar = static_cast<float>(m_factor[ind]);
173 const auto scalarSquared = static_cast<float>(m_factor[ind] * m_factor[ind]);
174 // Multiply weight by a scalar, propagating error
175 const float oldSignal = event.getSignal();
176 const float signal = oldSignal * scalar;
177 const float errorSquared = scalarSquared * event.getErrorSquared();
178 event.setSignal(signal);
179 event.setErrorSquared(errorSquared);
180 }
181 box->releaseEvents();
182 if (fileBackedTarget && hasEvents) {
183 Kernel::ISaveable *const pSaver(box->getISaveable());
184 dbuff->toWrite(pSaver);
185 }
186 }
187 }
188 // Recalculate the totals
189 ws->refreshCache();
190 // Mark file-backed workspace as dirty
191 ws->setFileNeedsUpdating(true);
192}
193
194} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
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
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
void setFileNeedsUpdating(bool value)
Sets the marker set to true when a file-backed workspace needs its back-end file updated (by calling ...
virtual void getBoxes(std::vector< IMDNode * > &boxes, size_t maxDepth, bool leafOnly)=0
Fill a vector with all the boxes who are the childred of this one up to a certain depth.
A property class for workspaces.
Templated super-class of a multi-dimensional event "box".
Definition: MDBoxBase.h:50
Templated class for a multi-dimensional event "box".
Definition: MDBox.h:45
std::vector< MDE > & getEvents()
Get vector of events to change.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
void refreshCache() override
Refresh the cache (integrated signal of each box)
Mantid::API::BoxController_sptr getBoxController() override
Returns the BoxController used in this workspace.
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
Buffer objects that need to be written out to disk so as to optimize writing operations.
Definition: DiskBuffer.h:42
void toWrite(ISaveable *item)
Call this method when an object is ready to be written out to disk.
Definition: DiskBuffer.cpp:47
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
An interface for objects that can be cached or saved to disk.
Definition: ISaveable.h:28
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
Validator to check that a property is not left empty.
The concrete, templated class for properties.
FlippingRatioCorrectionMD : Algorithm to correct MDEvents for flipping ratio.
int version() const override
Algorithm's version for identification.
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.
std::map< std::string, std::string > validateInputs() override
Validate inputs.
void init() override
Initialize the algorithm's properties.
void executeTemplatedMDE(typename Mantid::DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
Definition: IMDWorkspace.h:146
STL namespace.
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