27const std::string pNRLabel(
"PNR");
29const std::string pALabel(
"PA");
31const std::string crhoLabel(
"Rho");
33const std::string cppLabel(
"Pp");
35const std::string cAlphaLabel(
"Alpha");
37const std::string cApLabel(
"Ap");
39const std::string efficienciesLabel(
"Efficiencies");
41std::vector<std::string> modes() {
42 std::vector<std::string> modes;
43 modes.emplace_back(pALabel);
44 modes.emplace_back(pNRLabel);
49 if (groupWS->
size() == 0) {
50 throw std::invalid_argument(
"Input group workspace has no children.");
54 return matrixWS->getInstrument();
59 for (
size_t i = 0; i < ws->size(); ++i) {
66 auto wsUnit = ws2d->getAxis(0)->unit();
68 if (wsUnit->unitID() != expectedUnit.unitID()) {
69 throw std::invalid_argument(
"Input workspaces must have units of Wavelength");
74 if (lastWS->getNumberHistograms() != ws2d->getNumberHistograms()) {
75 throw std::invalid_argument(
"Not all workspaces in the "
76 "InputWorkspace WorkspaceGroup have the "
77 "same number of spectrum");
79 if (lastWS->blocksize() != ws2d->blocksize()) {
80 throw std::invalid_argument(
"Number of bins do not match between all "
81 "workspaces in the InputWorkspace "
85 auto ¤tX = ws2d->x(0);
86 auto &lastX = lastWS->x(0);
87 auto xMatches = std::equal(lastX.cbegin(), lastX.cend(), currentX.cbegin());
89 throw std::invalid_argument(
"X-arrays do not match between all "
90 "workspaces in the InputWorkspace "
99 std::stringstream messageBuffer;
100 messageBuffer <<
"Item with index: " << i <<
"in the InputWorkspace is not a MatrixWorkspace";
101 throw std::invalid_argument(messageBuffer.str());
128 return "Makes corrections for polarization efficiencies of the polarizer and "
129 "analyzer in a reflectometry neutron spectrometer.";
140 auto rhsWS = std::make_shared<DataObjects::WorkspaceSingleValue>(
rhs);
142 multiply->setProperty(
"LHSWorkspace", lhsWS);
143 multiply->setProperty(
"RHSWorkspace", rhsWS);
157 auto rhsWS = std::make_shared<DataObjects::WorkspaceSingleValue>(
rhs);
159 plus->setProperty(
"LHSWorkspace", lhsWS);
160 plus->setProperty(
"RHSWorkspace", rhsWS);
172 "An input workspace to process.");
174 auto propOptions = modes();
175 declareProperty(
"PolarizationAnalysis",
"PA", std::make_shared<StringListValidator>(propOptions),
176 "What Polarization mode will be used?\n"
177 "PNR: Polarized Neutron Reflectivity mode\n"
178 "PA: Full Polarization Analysis PNR-PA");
182 "A workspace containing the efficiency factors Pp, Ap, Rho and Alpha "
187 "An output workspace.");
192 size_t itemIndex = 0;
193 MatrixWorkspace_sptr Ipp = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
194 MatrixWorkspace_sptr Ipa = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
195 MatrixWorkspace_sptr Iap = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
196 MatrixWorkspace_sptr Iaa = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
198 Ipp->setTitle(
"Ipp");
199 Iaa->setTitle(
"Iaa");
200 Ipa->setTitle(
"Ipa");
201 Iap->setTitle(
"Iap");
208 const auto A0 = (Iaa * pp * ap) + (Ipa * ap *
rho * pp) + (Iap * ap * alpha * pp) + (Ipp * ap * alpha *
rho * pp);
209 const auto A1 = Iaa * pp;
210 const auto A2 = Iap * pp;
211 const auto A3 = Iaa * ap;
212 const auto A4 = Ipa * ap;
213 const auto A5 = Ipp * ap * alpha;
214 const auto A6 = Iap * ap * alpha;
215 const auto A7 = Ipp * pp *
rho;
216 const auto A8 = Ipa * pp *
rho;
218 const auto D = pp * ap * (
rho + alpha + 1.0 + (
rho * alpha));
220 const auto nIpp = (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D;
221 const auto nIaa = (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D;
222 const auto nIap = (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D;
223 const auto nIpa = (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D;
226 dataOut->addWorkspace(nIpp);
227 dataOut->addWorkspace(nIpa);
228 dataOut->addWorkspace(nIap);
229 dataOut->addWorkspace(nIaa);
230 size_t totalGroupEntries(dataOut->getNumberOfEntries());
231 for (
size_t i = 1; i < totalGroupEntries; i++) {
233 alg->setProperty(
"InputWorkspace", dataOut->getItem(i));
234 alg->setProperty(
"OutputWorkspace",
"dataOut_" +
std::to_string(i));
235 alg->setProperty(
"NaNValue", 0.0);
236 alg->setProperty(
"NaNError", 0.0);
237 alg->setProperty(
"InfinityValue", 0.0);
238 alg->setProperty(
"InfinityError", 0.0);
242 nIpp->history().addHistory(Ipp->getHistory());
243 nIaa->history().addHistory(Iaa->getHistory());
244 nIpa->history().addHistory(Ipa->getHistory());
245 nIap->history().addHistory(Iap->getHistory());
251 size_t itemIndex = 0;
252 MatrixWorkspace_sptr Ip = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
253 MatrixWorkspace_sptr Ia = std::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
258 const auto D = pp * (
rho + 1);
260 const auto nIp = (Ip * (
rho * pp + 1.0) + Ia * (pp - 1.0)) / D;
261 const auto nIa = (Ip * (
rho * pp - 1.0) + Ia * (pp + 1.0)) / D;
264 nIp->history().addHistory(Ip->getHistory());
265 nIa->history().addHistory(Ia->getHistory());
268 dataOut->addWorkspace(nIp);
269 dataOut->addWorkspace(nIa);
278std::shared_ptr<Mantid::API::MatrixWorkspace>
281 auto const &axis =
dynamic_cast<TextAxis &
>(*efficiencies->getAxis(1));
282 size_t index = axis.length();
283 for (
size_t i = 0; i < axis.length(); ++i) {
284 if (axis.label(i) == label) {
290 if (
index == axis.length()) {
293 static std::map<std::string, std::string> loadableProperties{
294 {crhoLabel,
"crho"}, {cppLabel,
"cPp"}, {cApLabel,
"cAp"}, {cAlphaLabel,
"calpha"}};
297 auto vals = instrument->getStringParameter(loadableProperties[label]);
299 throw std::invalid_argument(
"Efficiencey property not found: " + label);
302 extract->initialize();
303 extract->setProperty(
"InputWorkspace", efficiencies);
304 extract->setProperty(label, vals.front());
310 extract->initialize();
311 extract->setProperty(
"InputWorkspace", efficiencies);
312 extract->setProperty(
"WorkspaceIndex",
static_cast<int>(
index));
324 const std::string analysisMode =
getProperty(
"PolarizationAnalysis");
325 const size_t nWorkspaces = inWS->size();
327 validateInputWorkspace(inWS);
330 if (analysisMode == pALabel) {
331 if (nWorkspaces != 4) {
332 throw std::invalid_argument(
"For PA analysis, input group must have 4 periods.");
336 }
else if (analysisMode == pNRLabel) {
337 if (nWorkspaces != 2) {
338 throw std::invalid_argument(
"For PNR analysis, input group must have 2 periods.");
#define DECLARE_ALGORITHM(classname)
const std::vector< double > & rhs
std::map< DeltaEMode::Type, std::string > index
std::vector< double > VecDouble
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.
Class to represent a text axis of a workspace.
Class to hold a set of workspaces.
Workspace_sptr getItem(const size_t index) const
Return the ith workspace.
size_t size() const
Return the size of the group, so it is more like a container.
A property class for workspaces.
PolarizationCorrectionFredrikze : Algorithm to perform polarisation corrections on multi-period group...
std::shared_ptr< Mantid::API::WorkspaceGroup > execPA(const std::shared_ptr< Mantid::API::WorkspaceGroup > &inWS)
std::shared_ptr< Mantid::API::MatrixWorkspace > add(std::shared_ptr< Mantid::API::MatrixWorkspace > &lhsWS, const double &rhs)
Add a constant value to a workspace.
void init() override
Initialize the algorithm's properties.
std::shared_ptr< Mantid::API::WorkspaceGroup > execPNR(const std::shared_ptr< Mantid::API::WorkspaceGroup > &inWS)
std::shared_ptr< Mantid::API::MatrixWorkspace > getEfficiencyWorkspace(const std::string &label)
Extract a spectrum from the Efficiencies workspace as a 1D workspace.
int version() const override
Algorithm's version for identification.
const std::string summary() const override
std::shared_ptr< Mantid::API::MatrixWorkspace > multiply(std::shared_ptr< Mantid::API::MatrixWorkspace > &lhsWS, const double &rhs)
Multiply a workspace by a constant value.
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.