23auto constexpr INPUT_WS{
"InputWorkspace"};
24auto constexpr OUTPUT_WS{
"OutputWorkspace"};
25auto constexpr OUTPUT_FILE{
"OutputFilePath"};
27auto constexpr FLIPPER_LOC{
"Flipper"};
28auto constexpr POS_OPTIONS = {
"Polarizer",
"Analyzer"};
31auto constexpr FILE_EXTENSION{
".nxs"};
32auto constexpr INITIAL_SPIN{
"11,10,01,00"};
38using namespace Kernel;
45 return "Calculate the efficiency of the polarization or analyzer flipper.";
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)),
57 "Order of individual flipper configurations in the input group workspace, e.g. \"01,11,00,10\"");
60 "Workspace containing the wavelength-dependent efficiency for the flipper.");
62 "File name or path for the output to be saved to.");
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);
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;
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);
78 return std::sqrt(sigma_squared);
83 std::map<std::string, std::string> problems;
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.";
100 if (!filename.empty()) {
105 if (!outputWsName.empty()) {
111 bool const isFlipperAnalyser) {
112 using namespace FlipperConfigurations;
114 std::vector<MatrixWorkspace_sptr> Tij;
116 Tij.push_back(workspaceForSpinState(groupWs, spinConfig, flipperConf));
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;
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]);
133 if (isFlipperAnalyser) {
134 std::swap(tVec[1], tVec[2]);
135 std::swap(tVecE[1], tVecE[2]);
137 efficiencyE[i] = calculateErrorValue(tVec, tVecE);
143 std::filesystem::path filePath = filePathStr;
145 if (filePath.extension() != FILE_EXTENSION) {
146 filePath.replace_extension(FILE_EXTENSION);
149 saveAlg->initialize();
150 saveAlg->setProperty(
"Filename", filePath.string());
151 saveAlg->setProperty(
"InputWorkspace",
workspace);
#define DECLARE_ALGORITHM(classname)
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
static const std::string ON_OFF
static const std::string OFF_ON
static const std::string OFF_OFF
static const std::string ON_ON
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...
constexpr auto SPIN_STATES
@ Input
An input workspace.
@ Output
An output workspace.