Mantid
Loading...
Searching...
No Matches
PolarizationCorrectionsHelpers.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2024 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 +
7
8#pragma once
9
13#include "MantidAlgorithms/DllConfig.h"
15#include <Eigen/Dense>
16#include <optional>
17#include <unsupported/Eigen/AutoDiff>
18
19namespace Mantid::Algorithms {
20namespace PolarizationCorrectionsHelpers {
22 const std::string &spinStateOrder,
23 const std::string &targetSpinState);
24} // namespace PolarizationCorrectionsHelpers
25
26namespace FlipperConfigurations {
27static const std::string OFF_ON = "01";
28static const std::string ON_OFF = "10";
29static const std::string OFF_OFF = "00";
30static const std::string ON_ON = "11";
31static const std::string OFF = "0";
32static const std::string ON = "1";
33} // namespace FlipperConfigurations
34
35namespace SpinStateConfigurationsFredrikze {
36static const std::string PARA_ANTI = "pa";
37static const std::string ANTI_PARA = "ap";
38static const std::string PARA_PARA = "pp";
39static const std::string ANTI_ANTI = "aa";
40static const std::string PARA = "p";
41static const std::string ANTI = "a";
42} // namespace SpinStateConfigurationsFredrikze
43
44namespace SpinStateConfigurationsWildes {
45static const std::string MINUS_PLUS = "-+";
46static const std::string PLUS_MINUS = "+-";
47static const std::string MINUS_MINUS = "--";
48static const std::string PLUS_PLUS = "++";
49static const std::string MINUS = "-";
50static const std::string PLUS = "+";
51} // namespace SpinStateConfigurationsWildes
52
53namespace SpinStatesORSO {
54/*
55 * Polarization constants and helper methods to support the Reflectometry ORSO file format
56 */
57static const std::string PP = "pp";
58static const std::string PM = "pm";
59static const std::string MP = "mp";
60static const std::string MM = "mm";
61static const std::string PO = "po";
62static const std::string MO = "mo";
63
64static const std::string LOG_NAME = "spin_state_ORSO";
65
66MANTID_ALGORITHMS_DLL const std::string &getORSONotationForSpinState(const std::string &spinState);
67MANTID_ALGORITHMS_DLL void addORSOLogForSpinState(const Mantid::API::MatrixWorkspace_sptr &ws,
68 const std::string &spinState);
69} // namespace SpinStatesORSO
70
71namespace Arithmetic {
72
73template <size_t N> class ErrorTypeHelper {
74public:
75 using DerType = Eigen::Matrix<double, N, 1>;
77 using ADScalar = Eigen::AutoDiffScalar<DerType>;
78};
79
80template <size_t N, typename Func> class ErrorPropagation {
81public:
83 using DerType = Types::DerType;
84 using ADScalar = Types::ADScalar;
85 using InputArray = Types::InputArray;
86 ErrorPropagation(Func func) : computeFunc(std::move(func)) {}
87
89 double value;
90 double error;
91 Eigen::Array<double, N, 1> derivatives;
92 };
93
94 AutoDevResult evaluate(const InputArray &values, const InputArray &errors) const {
95 std::array<ADScalar, N> x;
96 for (size_t i = 0; i < N; ++i) {
97 x[i] = ADScalar(values[i], DerType::Unit(N, i));
98 }
99 const ADScalar y = computeFunc(x);
100 const auto &derivatives = y.derivatives();
101 return {y.value(), std::sqrt((derivatives.array().square() * errors.array().square()).sum()), derivatives};
102 }
103
104 template <std::same_as<API::MatrixWorkspace_sptr>... Ts>
105 API::MatrixWorkspace_sptr evaluateWorkspaces(const bool outputWorkspaceDistribution, Ts... args) const {
106 return evaluateWorkspacesImpl(outputWorkspaceDistribution, std::forward<Ts>(args)...);
107 }
108
109 template <std::same_as<API::MatrixWorkspace_sptr>... Ts>
111 return evaluateWorkspacesImpl(std::nullopt, std::forward<Ts>(args)...);
112 }
113
114private:
116
117 template <std::same_as<API::MatrixWorkspace_sptr>... Ts>
118 API::MatrixWorkspace_sptr evaluateWorkspacesImpl(std::optional<bool> outputWorkspaceDistribution, Ts... args) const {
119 const auto firstWs = std::get<0>(std::forward_as_tuple(args...));
120 API::MatrixWorkspace_sptr outWs = firstWs->clone();
121
122 if (outWs->id() == "EventWorkspace") {
123 outWs = convertToWorkspace2D(outWs);
124 }
125
126 const size_t numSpec = outWs->getNumberHistograms();
127 const size_t specSize = outWs->blocksize();
128
129 // cppcheck-suppress unreadVariable
130 const bool isThreadSafe = Kernel::threadSafe((*args)..., *outWs);
131 // cppcheck-suppress unreadVariable
132 const bool specOverBins = numSpec > specSize;
133
134 PARALLEL_FOR_IF(isThreadSafe && specOverBins)
135 for (int64_t i = 0; i < static_cast<int64_t>(numSpec); i++) {
136 auto &yOut = outWs->mutableY(i);
137 auto &eOut = outWs->mutableE(i);
138
139 PARALLEL_FOR_IF(isThreadSafe && !specOverBins)
140 for (int64_t j = 0; j < static_cast<int64_t>(specSize); ++j) {
141 const auto result = evaluate(InputArray{args->y(i)[j]...}, InputArray(args->e(i)[j]...));
142 yOut[j] = result.value;
143 eOut[j] = result.error;
144 }
145 }
146
147 if (outputWorkspaceDistribution.has_value()) {
148 outWs->setDistribution(outputWorkspaceDistribution.value());
149 }
150 return outWs;
151 }
152
154 const std::string &algName) const {
155 auto conversionAlg = API::AlgorithmManager::Instance().create(algName);
156 conversionAlg->initialize();
157 conversionAlg->setChild(true);
158 conversionAlg->setProperty("InputWorkspace", workspace);
159 conversionAlg->setProperty("OutputWorkspace", workspace->getName());
160 conversionAlg->execute();
161 return conversionAlg->getProperty("OutputWorkspace");
162 }
163
168};
169
170template <size_t N, typename Func> auto makeErrorPropagation(Func &&func) {
171 return ErrorPropagation<N, std::decay_t<Func>>(std::forward<Func>(func));
172}
173
174} // namespace Arithmetic
175} // namespace Mantid::Algorithms
IPeaksWorkspace_sptr workspace
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
AutoDevResult evaluate(const InputArray &values, const InputArray &errors) const
API::MatrixWorkspace_sptr runWorkspaceConversionAlg(const API::MatrixWorkspace_sptr &workspace, const std::string &algName) const
API::MatrixWorkspace_sptr evaluateWorkspaces(Ts... args) const
API::MatrixWorkspace_sptr evaluateWorkspacesImpl(std::optional< bool > outputWorkspaceDistribution, Ts... args) const
API::MatrixWorkspace_sptr evaluateWorkspaces(const bool outputWorkspaceDistribution, Ts... args) const
API::MatrixWorkspace_sptr convertToWorkspace2D(const API::MatrixWorkspace_sptr &workspace) const
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
MANTID_ALGORITHMS_DLL API::MatrixWorkspace_sptr workspaceForSpinState(const API::WorkspaceGroup_sptr &group, const std::string &spinStateOrder, const std::string &targetSpinState)
Returns the workspace in the group associated with the given targetSpinState according to the order d...
MANTID_ALGORITHMS_DLL void addORSOLogForSpinState(const Mantid::API::MatrixWorkspace_sptr &ws, const std::string &spinState)
MANTID_ALGORITHMS_DLL const std::string & getORSONotationForSpinState(const std::string &spinState)
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.
STL namespace.