Mantid
Loading...
Searching...
No Matches
PolarizationEfficiencyCor.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
10#include "MantidAPI/Axis.h"
18
19#include <Eigen/Dense>
20#include <boost/math/special_functions/pow.hpp>
21
22namespace {
23
25namespace Prop {
26static const std::string FLIPPERS{"Flippers"};
27static const std::string POLARIZATION_ANALYSIS{"PolarizationAnalysis"};
28static const std::string EFFICIENCIES{"Efficiencies"};
29static const std::string INPUT_WORKSPACES{"InputWorkspaces"};
30static const std::string INPUT_WORKSPACE_GROUP{"InputWorkspaceGroup"};
31static const std::string OUTPUT_WORKSPACES{"OutputWorkspace"};
32static const std::string CORRECTION_METHOD{"CorrectionMethod"};
33} // namespace Prop
34
36namespace Flippers {
37static const std::string Off{"0"};
38static const std::string OffOff{"00"};
39static const std::string OffOn{"01"};
40static const std::string On{"1"};
41static const std::string OnOff{"10"};
42static const std::string OnOn{"11"};
43} // namespace Flippers
44
46static const std::string WILDES{"Wildes"};
47static const std::string FREDRIKZE{"Fredrikze"};
48} // namespace CorrectionMethod
49
50} // namespace
51
52namespace Mantid::Algorithms {
53
54using namespace API;
55using namespace Kernel;
56
57// Register the algorithm into the AlgorithmFactory
58DECLARE_ALGORITHM(PolarizationEfficiencyCor)
59
60//----------------------------------------------------------------------------------------------
61
62
63const std::string PolarizationEfficiencyCor::name() const { return "PolarizationEfficiencyCor"; }
64
66int PolarizationEfficiencyCor::version() const { return 1; }
67
69const std::string PolarizationEfficiencyCor::category() const { return "Reflectometry"; }
70
72const std::string PolarizationEfficiencyCor::summary() const {
73 return "Corrects a group of polarization analysis workspaces for polarizer "
74 "and analyzer efficiencies.";
75}
76
77//----------------------------------------------------------------------------------------------
81 bool const allowMultiSelection = true;
82 bool const isOptional = true;
84 Prop::INPUT_WORKSPACES, "", std::make_shared<ADSValidator>(allowMultiSelection, isOptional),
86 "A list of names of workspaces to be corrected.");
87
88 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>(Prop::INPUT_WORKSPACE_GROUP, "",
90 "A group of workspaces to be corrected.");
91
92 const std::vector<std::string> methods{CorrectionMethod::WILDES, CorrectionMethod::FREDRIKZE};
93 declareProperty(Prop::CORRECTION_METHOD, CorrectionMethod::WILDES,
94 std::make_shared<Kernel::ListValidator<std::string>>(methods), "Correction method.");
95
97 std::make_unique<WorkspaceProperty<MatrixWorkspace>>(Prop::EFFICIENCIES, "", Kernel::Direction::Input),
98 "A workspace containing the efficiency factors as "
99 "histograms: P1, P2, F1 and F2 in the Wildes method and Pp, "
100 "Ap, Rho and Alpha for Fredrikze.");
101
102 const std::string full = Flippers::OffOff + ", " + Flippers::OffOn + ", " + Flippers::OnOff + ", " + Flippers::OnOn;
103 const std::string missing01 = Flippers::OffOff + ", " + Flippers::OnOff + ", " + Flippers::OnOn;
104 const std::string missing10 = Flippers::OffOff + ", " + Flippers::OffOn + ", " + Flippers::OnOn;
105 const std::string missing0110 = Flippers::OffOff + ", " + Flippers::OnOn;
106 const std::string noAnalyzer = Flippers::Off + ", " + Flippers::On;
107 const std::string directBeam = Flippers::Off;
108 const std::vector<std::string> setups{{"", full, missing01, missing10, missing0110, noAnalyzer, directBeam}};
109 declareProperty(Prop::FLIPPERS, "", std::make_shared<Kernel::ListValidator<std::string>>(setups),
110 "Flipper configurations of the input workspaces (Wildes method only)");
111
112 std::vector<std::string> propOptions{"", "PA", "PNR"};
113 declareProperty("PolarizationAnalysis", "", std::make_shared<StringListValidator>(propOptions),
114 "What Polarization mode will be used?\n"
115 "PNR: Polarized Neutron Reflectivity mode\n"
116 "PA: Full Polarization Analysis PNR-PA "
117 "(Fredrikze method only)");
118
120 std::make_unique<WorkspaceProperty<WorkspaceGroup>>(Prop::OUTPUT_WORKSPACES, "", Kernel::Direction::Output),
121 "A group of polarization efficiency corrected workspaces.");
122}
123
124//----------------------------------------------------------------------------------------------
128 std::string const method = getProperty(Prop::CORRECTION_METHOD);
129 if (method == CorrectionMethod::WILDES) {
130 execWildes();
131 } else {
133 }
134}
135
136//----------------------------------------------------------------------------------------------
139 std::vector<std::string> workspaces = getWorkspaceNameList();
140
141 MatrixWorkspace_sptr efficiencies = getEfficiencies();
142 auto alg = createChildAlgorithm("PolarizationCorrectionWildes");
143 alg->initialize();
144 alg->setProperty("InputWorkspaces", workspaces);
145 alg->setProperty("Efficiencies", efficiencies);
146 if (!isDefault(Prop::FLIPPERS)) {
147 alg->setPropertyValue("Flippers", getPropertyValue(Prop::FLIPPERS));
148 }
149 auto out = getPropertyValue(Prop::OUTPUT_WORKSPACES);
150 alg->setPropertyValue("OutputWorkspace", out);
151 alg->execute();
152 API::WorkspaceGroup_sptr outWS = alg->getProperty("OutputWorkspace");
153 setProperty(Prop::OUTPUT_WORKSPACES, outWS);
154}
155
156//----------------------------------------------------------------------------------------------
160 MatrixWorkspace_sptr efficiencies = getEfficiencies();
161 auto alg = createChildAlgorithm("PolarizationCorrectionFredrikze");
162 alg->initialize();
163 alg->setProperty("InputWorkspace", group);
164 alg->setProperty("Efficiencies", efficiencies);
165 if (!isDefault(Prop::POLARIZATION_ANALYSIS)) {
166 alg->setPropertyValue("PolarizationAnalysis", getPropertyValue(Prop::POLARIZATION_ANALYSIS));
167 }
168 alg->setPropertyValue("OutputWorkspace", getPropertyValue(Prop::OUTPUT_WORKSPACES));
169 alg->execute();
170 API::WorkspaceGroup_sptr outWS = alg->getProperty("OutputWorkspace");
171 setProperty(Prop::OUTPUT_WORKSPACES, outWS);
172}
173
174//----------------------------------------------------------------------------------------------
178 if (isDefault(Prop::INPUT_WORKSPACES) && isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
179 throw std::invalid_argument("Input workspaces are missing. Either a "
180 "workspace group or a list of workspace names "
181 "must be given.");
182 }
183 if (!isDefault(Prop::INPUT_WORKSPACES) && !isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
184 throw std::invalid_argument("Input workspaces must be given either as a "
185 "workspace group or a list of names.");
186 }
187}
188
189//----------------------------------------------------------------------------------------------
194
195 if (!isDefault(Prop::POLARIZATION_ANALYSIS)) {
196 throw std::invalid_argument("Property PolarizationAnalysis cannot be used with the Wildes method.");
197 }
198}
199
200//----------------------------------------------------------------------------------------------
205
206 if (!isDefault(Prop::FLIPPERS)) {
207 throw std::invalid_argument("Property Flippers cannot be used with the Fredrikze method.");
208 }
209}
210
211//----------------------------------------------------------------------------------------------
214std::vector<std::string> PolarizationEfficiencyCor::getWorkspaceNameList() const {
215 std::vector<std::string> names;
216 if (!isDefault(Prop::INPUT_WORKSPACES)) {
217 names = getProperty(Prop::INPUT_WORKSPACES);
218 } else {
219 WorkspaceGroup_sptr group = getProperty(Prop::INPUT_WORKSPACE_GROUP);
220 auto const n = group->size();
221 for (size_t i = 0; i < n; ++i) {
222 auto ws = group->getItem(i);
223 auto const name = ws->getName();
224 if (name.empty()) {
225 throw std::invalid_argument("Workspace from the input workspace group is not stored in the "
226 "Analysis Data Service which is required by the Wildes method.");
227 }
228 names.emplace_back(name);
229 }
230 }
231 return names;
232}
233
234//----------------------------------------------------------------------------------------------
239 if (!isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
240 group = getProperty(Prop::INPUT_WORKSPACE_GROUP);
241 } else {
242 throw std::invalid_argument("Input workspaces are required to be in a workspace group.");
243 }
244 return group;
245}
246
247//----------------------------------------------------------------------------------------------
251 MatrixWorkspace const &inWS) const {
252
253 if (!efficiencies.isHistogramData())
254 return true;
255 if (efficiencies.blocksize() != inWS.blocksize())
256 return true;
257
258 auto const &x = inWS.x(0);
259 for (size_t i = 0; i < efficiencies.getNumberHistograms(); ++i) {
260 if (efficiencies.x(i).rawData() != x.rawData())
261 return true;
262 }
263 return false;
264}
265
266//----------------------------------------------------------------------------------------------
269 if (efficiencies->isHistogramData()) {
270 return efficiencies;
271 }
272 auto alg = createChildAlgorithm("ConvertToHistogram");
273 alg->initialize();
274 alg->setProperty("InputWorkspace", efficiencies);
275 alg->setProperty("OutputWorkspace", "dummy");
276 alg->execute();
277 MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace");
278 return result;
279}
280
281//----------------------------------------------------------------------------------------------
284 const MatrixWorkspace_sptr &inWS) {
285
286 efficiencies->setDistribution(true);
287 auto alg = createChildAlgorithm("RebinToWorkspace");
288 alg->initialize();
289 alg->setProperty("WorkspaceToRebin", efficiencies);
290 alg->setProperty("WorkspaceToMatch", inWS);
291 alg->setProperty("OutputWorkspace", "dummy");
292 alg->execute();
293 MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace");
294 return result;
295}
296
297//----------------------------------------------------------------------------------------------
302 if (!isDefault(Prop::INPUT_WORKSPACES)) {
303 std::vector<std::string> const names = getProperty(Prop::INPUT_WORKSPACES);
304 inWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(names.front());
305 } else {
306 WorkspaceGroup_sptr group = getProperty(Prop::INPUT_WORKSPACE_GROUP);
307 inWS = std::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(0));
308 }
309 MatrixWorkspace_sptr efficiencies = getProperty(Prop::EFFICIENCIES);
310
311 if (!needInterpolation(*efficiencies, *inWS)) {
312 return efficiencies;
313 }
314
315 efficiencies = convertToHistogram(efficiencies);
316 efficiencies = interpolate(efficiencies, inWS);
317
318 return efficiencies;
319}
320
321} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
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
bool isDefault(const std::string &name) const
Definition: Algorithm.cpp:2084
Base MatrixWorkspace Abstract Class.
virtual std::size_t blocksize() const =0
Returns the size of each block of data returned by the dataY accessors.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const HistogramData::HistogramX & x(const size_t index) const
virtual bool isHistogramData() const
Returns true if the workspace contains data in histogram form (as opposed to point-like)
A property class for workspaces.
PolarizationEfficiencyCor: a generalised polarization correction algorithm.
API::MatrixWorkspace_sptr getEfficiencies()
Prepare and return the efficiencies.
const std::string category() const override
Algorithm's category for identification.
void checkWildesProperties() const
Check that the inputs for the Wildes are correct and consistent.
std::vector< std::string > getWorkspaceNameList() const
Get the input workspaces as a list of names.
API::MatrixWorkspace_sptr convertToHistogram(API::MatrixWorkspace_sptr efficiencies)
Convert the efficiencies to histogram.
API::MatrixWorkspace_sptr interpolate(const API::MatrixWorkspace_sptr &efficiencies, const API::MatrixWorkspace_sptr &inWS)
Convert the efficiencies to histogram.
void checkWorkspaces() const
Check that the inputs workspaces are set.
void init() override
Initialize the algorithm's properties.
API::WorkspaceGroup_sptr getWorkspaceGroup() const
Get the input workspaces as a workspace group.
const std::string name() const override
Algorithms name for identification.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void checkFredrikzeProperties() const
Check that the inputs for the Fredrikze method are correct and consistent.
int version() const override
Algorithm's version for identification.
bool needInterpolation(API::MatrixWorkspace const &efficiencies, API::MatrixWorkspace const &inWS) const
Check if efficiencies workspace needs interpolation.
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
Definition: ListValidator.h:29
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Flipper configurations.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
String constants for algorithm's properties.
STL namespace.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54