Mantid
Loading...
Searching...
No Matches
FlipperEfficiency.cpp
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#include <filesystem>
8
9#include "MantidAPI/Axis.h"
18#include "MantidKernel/Unit.h"
19
20namespace {
22namespace PropNames {
23auto constexpr INPUT_WS{"InputWorkspace"};
24auto constexpr OUTPUT_WS{"OutputWorkspace"};
25auto constexpr OUTPUT_FILE{"OutputFilePath"};
26auto constexpr SPIN_STATES{"SpinStates"};
27auto constexpr FLIPPER_LOC{"Flipper"};
28auto constexpr POS_OPTIONS = {"Polarizer", "Analyzer"};
29} // namespace PropNames
30
31auto constexpr FILE_EXTENSION{".nxs"};
32auto constexpr INITIAL_SPIN{"11,10,01,00"};
33} // namespace
34
35namespace Mantid::Algorithms {
36
37using namespace API;
38using namespace Kernel;
40
41// Register the algorithm in the AlgorithmFactory
42DECLARE_ALGORITHM(FlipperEfficiency)
43
44std::string const FlipperEfficiency::summary() const {
45 return "Calculate the efficiency of the polarization or analyzer flipper.";
46}
47
50 std::make_unique<WorkspaceProperty<WorkspaceGroup>>(PropNames::INPUT_WS, "", Direction::Input,
51 std::make_shared<Mantid::API::PolSANSWorkspaceValidator>()),
52 "Group workspace containing flipper transmissions for all 4 polarization states.");
53 auto const spinValidator = std::make_shared<SpinStateValidator>(std::unordered_set<int>{4});
54 declareProperty(PropNames::FLIPPER_LOC, *PropNames::POS_OPTIONS.begin(),
55 std::make_shared<StringListValidator>(PropNames::POS_OPTIONS)),
56 declareProperty(PropNames::SPIN_STATES, INITIAL_SPIN, spinValidator,
57 "Order of individual flipper configurations in the input group workspace, e.g. \"01,11,00,10\"");
58 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(PropNames::OUTPUT_WS, "", Direction::Output,
60 "Workspace containing the wavelength-dependent efficiency for the flipper.");
61 declareProperty(std::make_unique<FileProperty>(PropNames::OUTPUT_FILE, "", FileProperty::OptionalSave),
62 "File name or path for the output to be saved to.");
63}
64
65namespace {
66double calculateErrorValue(const std::vector<double> &TijY, const std::vector<double> &TijE) {
67 double const denom_1 = std::pow(TijY[0] + TijY[1], 2) * (TijY[3] - TijY[2]);
68 double const denom_0 = (TijY[0] + TijY[1]) * std::pow(TijY[3] - TijY[2], 2);
69
70 double const deff_dt11 = (TijY[1] * (TijY[3] + TijY[2])) / denom_1;
71 double const deff_dt10 = (-TijY[0] * (TijY[3] + TijY[2])) / denom_1;
72 double const deff_dt00 = (TijY[2] * (TijY[1] - TijY[0])) / denom_0;
73 double const deff_dt01 = (TijY[3] * (TijY[0] - TijY[1])) / denom_0;
74
75 double const sigma_squared = std::pow(deff_dt11 * TijE[0], 2) + std::pow(deff_dt00 * TijE[3], 2) +
76 std::pow(deff_dt10 * TijE[1], 2) + std::pow(deff_dt01 * TijE[2], 2);
77
78 return std::sqrt(sigma_squared);
79}
80} // namespace
81
82std::map<std::string, std::string> FlipperEfficiency::validateInputs() {
83 std::map<std::string, std::string> problems;
84
85 // Check outputs.
86 auto const &outputWs = getPropertyValue(PropNames::OUTPUT_WS);
87 auto const &outputFile = getPropertyValue(PropNames::OUTPUT_FILE);
88 if (outputWs.empty() && outputFile.empty()) {
89 problems[PropNames::OUTPUT_FILE] = "Either an output workspace or output file must be provided.";
90 problems[PropNames::OUTPUT_WS] = "Either an output workspace or output file must be provided.";
91 }
92 return problems;
93}
94
96 WorkspaceGroup_sptr const &groupWs = getProperty(PropNames::INPUT_WS);
97 auto const &efficiency = calculateEfficiency(groupWs, !isDefault(PropNames::FLIPPER_LOC));
98
99 auto const &filename = getPropertyValue(PropNames::OUTPUT_FILE);
100 if (!filename.empty()) {
101 saveToFile(efficiency, filename);
102 }
103
104 auto const &outputWsName = getPropertyValue(PropNames::OUTPUT_WS);
105 if (!outputWsName.empty()) {
106 setProperty(PropNames::OUTPUT_WS, efficiency);
107 }
108}
109
111 bool const isFlipperAnalyser) {
112 using namespace FlipperConfigurations;
113 auto const &spinConfig = getPropertyValue(PropNames::SPIN_STATES);
114 std::vector<MatrixWorkspace_sptr> Tij;
115 for (auto const &flipperConf : {ON_ON, ON_OFF, OFF_ON, OFF_OFF}) {
116 Tij.push_back(workspaceForSpinState(groupWs, spinConfig, flipperConf));
117 }
118
119 auto const &numerator = (Tij[0] * Tij[3]) - (Tij[2] * Tij[1]);
120 auto const &denominator =
121 isFlipperAnalyser ? (Tij[0] + Tij[2]) * (Tij[3] - Tij[1]) : (Tij[0] + Tij[1]) * (Tij[3] - Tij[2]);
122 auto const &efficiency = numerator / denominator;
123
124 // Calculate the errors
125 auto &efficiencyE = efficiency->mutableE(0);
126 auto const numBins = efficiencyE.size();
127 for (size_t i = 0; i < numBins; ++i) {
128 std::vector<double> tVec, tVecE;
129 for (auto const &wk : Tij) {
130 tVec.push_back(wk->y(0)[i]);
131 tVecE.push_back(wk->e(0)[i]);
132 }
133 if (isFlipperAnalyser) {
134 std::swap(tVec[1], tVec[2]);
135 std::swap(tVecE[1], tVecE[2]);
136 }
137 efficiencyE[i] = calculateErrorValue(tVec, tVecE);
138 }
139 return efficiency;
140}
141
142void FlipperEfficiency::saveToFile(MatrixWorkspace_sptr const &workspace, std::string const &filePathStr) {
143 std::filesystem::path filePath = filePathStr;
144 // Add the nexus extension if it's not been applied already.
145 if (filePath.extension() != FILE_EXTENSION) {
146 filePath.replace_extension(FILE_EXTENSION);
147 }
148 auto saveAlg = createChildAlgorithm("SaveNexus");
149 saveAlg->initialize();
150 saveAlg->setProperty("Filename", filePath.string());
151 saveAlg->setProperty("InputWorkspace", workspace);
152 saveAlg->execute();
153}
154
155} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
IPeaksWorkspace_sptr workspace
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
@ OptionalSave
to specify a file to write to but an empty string is
A property class for workspaces.
void exec() override
Execute the algorithm with the provided properties.
void init() override
Setup the algorithm's properties and prepare constants.
void saveToFile(API::MatrixWorkspace_sptr const &workspace, std::string const &filePathStr)
Save the given workspace to a given path as Nexus, applying the relevant extension if necessary.
API::MatrixWorkspace_sptr calculateEfficiency(API::WorkspaceGroup_sptr const &groupWs, bool const isFlipperAnalyser=false)
Perform the main calculation for determining the efficiency on the given group.
std::map< std::string, std::string > validateInputs() override
Check that the inputs to the algorithm are valid.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
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...
STL namespace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54