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 +
9
11#include "MantidAPI/Axis.h"
21
22#include <Eigen/Dense>
23#include <boost/math/special_functions/pow.hpp>
24
25namespace {
26
28namespace Prop {
29static const std::string FLIPPERS{"Flippers"};
30static const std::string OUTPUT_WILDES_SPIN_STATES{"SpinStatesOutWildes"};
31static const std::string POLARIZATION_ANALYSIS{"PolarizationAnalysis"};
32static const std::string EFFICIENCIES{"Efficiencies"};
33static const std::string INPUT_WORKSPACES{"InputWorkspaces"};
34static const std::string INPUT_WORKSPACE_GROUP{"InputWorkspaceGroup"};
35static const std::string OUTPUT_WORKSPACES{"OutputWorkspace"};
36static const std::string CORRECTION_METHOD{"CorrectionMethod"};
37static const std::string INPUT_FRED_SPIN_STATES{"SpinStatesInFredrikze"};
38static const std::string OUTPUT_FRED_SPIN_STATES{"SpinStatesOutFredrikze"};
39static const std::string ADD_SPIN_STATE_LOG{"AddSpinStateToLog"};
40} // namespace Prop
41
43static const std::string WILDES{"Wildes"};
44static const std::string FREDRIKZE{"Fredrikze"};
45} // namespace CorrectionMethod
46
47} // namespace
48
49namespace Mantid::Algorithms {
50
51using namespace API;
52using namespace Kernel;
53
54// Register the algorithm into the AlgorithmFactory
55DECLARE_ALGORITHM(PolarizationEfficiencyCor)
56
57//----------------------------------------------------------------------------------------------
58
59
60const std::string PolarizationEfficiencyCor::name() const { return "PolarizationEfficiencyCor"; }
61
63int PolarizationEfficiencyCor::version() const { return 1; }
64
66const std::string PolarizationEfficiencyCor::category() const { return "Reflectometry"; }
67
69const std::string PolarizationEfficiencyCor::summary() const {
70 return "Corrects a group of polarization analysis workspaces for polarizer "
71 "and analyzer efficiencies.";
72}
73
74//----------------------------------------------------------------------------------------------
78 bool const allowMultiSelection = true;
79 bool const isOptional = true;
81 Prop::INPUT_WORKSPACES, "", std::make_shared<ADSValidator>(allowMultiSelection, isOptional),
83 "A list of names of workspaces to be corrected.");
84
85 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>(Prop::INPUT_WORKSPACE_GROUP, "",
87 "A group of workspaces to be corrected.");
88
89 const std::vector<std::string> methods{CorrectionMethod::WILDES, CorrectionMethod::FREDRIKZE};
90 declareProperty(Prop::CORRECTION_METHOD, CorrectionMethod::WILDES,
91 std::make_shared<Kernel::ListValidator<std::string>>(methods), "Correction method.");
92
95 "A workspace containing the efficiency factors as "
96 "histograms: P1, P2, F1 and F2 in the Wildes method and Pp, "
97 "Ap, Rho and Alpha for Fredrikze.");
98
99 const auto wildesFlipperValidator =
100 std::make_shared<SpinStateValidator>(std::unordered_set<int>{1, 2, 3, 4}, true, "0", "1", true);
101 declareProperty(Prop::FLIPPERS, "", wildesFlipperValidator,
102 "Flipper configurations of the input workspaces (Wildes method only)");
103
104 const auto spinStateValidator =
105 std::make_shared<SpinStateValidator>(std::unordered_set<int>{0, 2, 4}, true, "+", "-", true);
106 declareProperty(Prop::OUTPUT_WILDES_SPIN_STATES, "", spinStateValidator,
107 "The order of the spin states in the output workspace. (Wildes method only).");
108
109 std::vector<std::string> propOptions{"", "PA", "PNR"};
110 declareProperty("PolarizationAnalysis", "", std::make_shared<StringListValidator>(propOptions),
111 "What Polarization mode will be used?\n"
112 "PNR: Polarized Neutron Reflectivity mode\n"
113 "PA: Full Polarization Analysis PNR-PA "
114 "(Fredrikze method only)");
115
116 const auto fredrikzeSpinStateValidator =
117 std::make_shared<SpinStateValidator>(std::unordered_set<int>{2, 4}, true, "p", "a", true);
118
119 declareProperty(Prop::INPUT_FRED_SPIN_STATES, "", fredrikzeSpinStateValidator,
120 "The order of spin states in the input workspace group. The possible values are 'pp,pa,ap,aa' or "
121 "'p,a'. (Fredrikze method only).");
122
123 declareProperty(Prop::OUTPUT_FRED_SPIN_STATES, "", fredrikzeSpinStateValidator,
124 "The order of spin states in the output workspace group. The possible values are 'pp,pa,ap,aa' or "
125 "'p,a'. (Fredrikze method only).");
126
128 std::make_unique<WorkspaceProperty<WorkspaceGroup>>(Prop::OUTPUT_WORKSPACES, "", Kernel::Direction::Output),
129 "A group of polarization efficiency corrected workspaces.");
130
132 "Whether to add the final spin state into the sample log of each child workspace in the output "
133 "group.");
134
136 Prop::OUTPUT_WILDES_SPIN_STATES,
137 std::make_unique<EnabledWhenProperty>(Prop::CORRECTION_METHOD, Kernel::IS_EQUAL_TO, CorrectionMethod::WILDES));
138
139 setPropertySettings(Prop::FLIPPERS, std::make_unique<EnabledWhenProperty>(
140 Prop::CORRECTION_METHOD, Kernel::IS_EQUAL_TO, CorrectionMethod::WILDES));
141
143 Prop::INPUT_FRED_SPIN_STATES,
144 std::make_unique<EnabledWhenProperty>(Prop::CORRECTION_METHOD, Kernel::IS_EQUAL_TO, CorrectionMethod::FREDRIKZE));
145
147 Prop::OUTPUT_FRED_SPIN_STATES,
148 std::make_unique<EnabledWhenProperty>(Prop::CORRECTION_METHOD, Kernel::IS_EQUAL_TO, CorrectionMethod::FREDRIKZE));
149
151 "PolarizationAnalysis",
152 std::make_unique<EnabledWhenProperty>(Prop::CORRECTION_METHOD, Kernel::IS_EQUAL_TO, CorrectionMethod::FREDRIKZE));
153}
154
155//----------------------------------------------------------------------------------------------
159 std::string const method = getProperty(Prop::CORRECTION_METHOD);
160 if (method == CorrectionMethod::WILDES) {
161 execWildes();
162 } else {
164 }
165}
166
167//----------------------------------------------------------------------------------------------
170 auto alg = createChildAlgorithm("PolarizationCorrectionWildes");
171 alg->initialize();
172 if (!isDefault(Prop::INPUT_WORKSPACES)) {
173 std::vector<std::string> workspaces = getWorkspaceNameList();
174 alg->setProperty(Prop::INPUT_WORKSPACES, workspaces);
175 } else {
176 auto group = getWorkspaceGroup();
177 alg->setProperty(Prop::INPUT_WORKSPACE_GROUP, group);
178 }
179 MatrixWorkspace_sptr efficiencies = getEfficiencies();
180 alg->setProperty(Prop::EFFICIENCIES, efficiencies);
181 if (!isDefault(Prop::FLIPPERS)) {
182 alg->setPropertyValue("Flippers", getPropertyValue(Prop::FLIPPERS));
183 }
185 alg->setPropertyValue("AddSpinStateToLog", getPropertyValue(Prop::ADD_SPIN_STATE_LOG));
186 }
187 if (!isDefault(Prop::OUTPUT_WILDES_SPIN_STATES)) {
188 alg->setPropertyValue("SpinStates", getPropertyValue(Prop::OUTPUT_WILDES_SPIN_STATES));
189 }
190 auto out = getPropertyValue(Prop::OUTPUT_WORKSPACES);
191 alg->setPropertyValue("OutputWorkspace", out);
192 alg->execute();
193 API::WorkspaceGroup_sptr outWS = alg->getProperty("OutputWorkspace");
194 setProperty(Prop::OUTPUT_WORKSPACES, outWS);
195}
196
197//----------------------------------------------------------------------------------------------
201 MatrixWorkspace_sptr efficiencies = getEfficiencies();
202 auto alg = createChildAlgorithm("PolarizationCorrectionFredrikze");
203 alg->initialize();
204 alg->setProperty("InputWorkspace", group);
205 alg->setProperty("Efficiencies", efficiencies);
206 if (!isDefault(Prop::POLARIZATION_ANALYSIS)) {
207 alg->setPropertyValue("PolarizationAnalysis", getPropertyValue(Prop::POLARIZATION_ANALYSIS));
208 }
209 if (!isDefault(Prop::INPUT_FRED_SPIN_STATES)) {
210 alg->setPropertyValue("InputSpinStates", getPropertyValue(Prop::INPUT_FRED_SPIN_STATES));
211 }
212 if (!isDefault(Prop::OUTPUT_FRED_SPIN_STATES)) {
213 alg->setPropertyValue("OutputSpinStates", getPropertyValue(Prop::OUTPUT_FRED_SPIN_STATES));
214 }
215 alg->setPropertyValue("OutputWorkspace", getPropertyValue(Prop::OUTPUT_WORKSPACES));
216 alg->execute();
217 API::WorkspaceGroup_sptr outWS = alg->getProperty("OutputWorkspace");
218 setProperty(Prop::OUTPUT_WORKSPACES, outWS);
219}
220
221//----------------------------------------------------------------------------------------------
225 if (isDefault(Prop::INPUT_WORKSPACES) && isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
226 throw std::invalid_argument("Input workspaces are missing. Either a "
227 "workspace group or a list of workspace names "
228 "must be given.");
229 }
230 if (!isDefault(Prop::INPUT_WORKSPACES) && !isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
231 throw std::invalid_argument("Input workspaces must be given either as a "
232 "workspace group or a list of names.");
233 }
234}
235
236//----------------------------------------------------------------------------------------------
241
242 if (!isDefault(Prop::POLARIZATION_ANALYSIS)) {
243 throw std::invalid_argument("Property PolarizationAnalysis cannot be used with the Wildes method.");
244 }
245
246 if (!isDefault(Prop::INPUT_FRED_SPIN_STATES)) {
247 throw std::invalid_argument("Property SpinStatesInFredrikze cannot be used with the Wildes method.");
248 }
249
250 if (!isDefault(Prop::OUTPUT_FRED_SPIN_STATES)) {
251 throw std::invalid_argument("Property SpinStatesOutFredrikze cannot be used with the Wildes method.");
252 }
253}
254
255//----------------------------------------------------------------------------------------------
260
261 if (!isDefault(Prop::FLIPPERS)) {
262 throw std::invalid_argument("Property Flippers cannot be used with the Fredrikze method.");
263 }
264 if (!isDefault(Prop::OUTPUT_WILDES_SPIN_STATES)) {
265 throw std::invalid_argument("Property SpinStatesOutWildes cannot be used with the Fredrikze method.");
266 }
267}
268
269//----------------------------------------------------------------------------------------------
272std::vector<std::string> PolarizationEfficiencyCor::getWorkspaceNameList() const {
273 std::vector<std::string> wsNames;
274 if (!isDefault(Prop::INPUT_WORKSPACES)) {
275 wsNames = getProperty(Prop::INPUT_WORKSPACES);
276 if (std::any_of(wsNames.cbegin(), wsNames.cend(), [](const auto &wsName) {
277 return AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName) == nullptr;
278 })) {
279 throw std::invalid_argument(
280 "Only Matrix Workspaces can be added in InputWorkspace property list. If the input is a group, "
281 "use the InputWorkspaceGroup property");
282 }
283 }
284 return wsNames;
285}
286
287//----------------------------------------------------------------------------------------------
292 if (!isDefault(Prop::INPUT_WORKSPACE_GROUP)) {
293 group = getProperty(Prop::INPUT_WORKSPACE_GROUP);
294 } else {
295 throw std::invalid_argument("Input workspaces are required to be in a workspace group.");
296 }
297 return group;
298}
299
300//----------------------------------------------------------------------------------------------
304 MatrixWorkspace const &inWS) const {
305
306 if (!efficiencies.isHistogramData())
307 return true;
308 if (efficiencies.blocksize() != inWS.blocksize())
309 return true;
310
311 auto const &x = inWS.x(0);
312 for (size_t i = 0; i < efficiencies.getNumberHistograms(); ++i) {
313 if (efficiencies.x(i).rawData() != x.rawData())
314 return true;
315 }
316 return false;
317}
318
319//----------------------------------------------------------------------------------------------
322 if (efficiencies->isHistogramData()) {
323 return efficiencies;
324 }
325 auto alg = createChildAlgorithm("ConvertToHistogram");
326 alg->initialize();
327 alg->setProperty("InputWorkspace", efficiencies);
328 alg->setProperty("OutputWorkspace", "dummy");
329 alg->execute();
330 MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace");
331 return result;
332}
333
334//----------------------------------------------------------------------------------------------
337 const MatrixWorkspace_sptr &inWS) {
338
339 efficiencies->setDistribution(true);
340 auto alg = createChildAlgorithm("RebinToWorkspace");
341 alg->initialize();
342 alg->setProperty("WorkspaceToRebin", efficiencies);
343 alg->setProperty("WorkspaceToMatch", inWS);
344 alg->setProperty("OutputWorkspace", "dummy");
345 alg->execute();
346 MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace");
347 return result;
348}
349
350//----------------------------------------------------------------------------------------------
355 if (!isDefault(Prop::INPUT_WORKSPACES)) {
356 std::vector<std::string> const names = getProperty(Prop::INPUT_WORKSPACES);
357 inWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(names.front());
358 } else {
359 WorkspaceGroup_sptr group = getProperty(Prop::INPUT_WORKSPACE_GROUP);
360 inWS = std::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(0));
361 }
363
364 if (!needInterpolation(*efficiencies, *inWS)) {
365 return efficiencies;
366 }
367
368 efficiencies = convertToHistogram(efficiencies);
369 efficiencies = interpolate(efficiencies, inWS);
370
371 return efficiencies;
372}
373
374} // namespace Mantid::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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.
bool isDefault(const std::string &name) const
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 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.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings const > settings)
Add a PropertySettings instance to the chain of settings for a given property.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
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.
static const std::string ADD_SPIN_STATE_LOG
static const std::string EFFICIENCIES
STL namespace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54