Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Determination of Workspace Order from Output of PolarizationCorrectionWildes #37643

Merged
merged 23 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
be8f164
Distinguish between spin states and flipper configuration
cailafinn Jul 1, 2024
321c603
Allow user to select ordering of output workspaces
cailafinn Jul 2, 2024
3d9a3d5
Fix output order failing for 3 inputs
cailafinn Jul 3, 2024
3d6d0b5
Correctly validate SpinStates parameter
cailafinn Jul 3, 2024
53c9088
Update error messages in validator
cailafinn Jul 4, 2024
bacaf84
Fix missing empty spinstates check
cailafinn Jul 4, 2024
cf81b71
Update documentation
cailafinn Jul 4, 2024
6d4226b
Remove unused states
cailafinn Jul 4, 2024
c68a9e8
Add SpinStates property to wrapper alg
cailafinn Jul 4, 2024
09272fb
Mention new property in wrapper alg
cailafinn Jul 8, 2024
17cf176
Refactor SpinStateValidator to generalize checking
cailafinn Jul 19, 2024
123331a
Fix non-allowed <> tags in doxygen string
cailafinn Jul 29, 2024
a2a8e31
Fix build errors after helper changes
cailafinn Aug 16, 2024
8ce6029
Refactor and simplify pol index correction
cailafinn Aug 16, 2024
542aba2
Make const position consistent
cailafinn Aug 16, 2024
7557939
Make SeeAlso location consistent
cailafinn Aug 19, 2024
29946af
Remove unneeded constsants from validator
cailafinn Aug 21, 2024
29d9fda
Correct allowed output spins
cailafinn Aug 21, 2024
06a6ca1
Limit to two-character spin state outputs
cailafinn Aug 21, 2024
0e375f9
Add a release note
cailafinn Aug 21, 2024
f988e58
Merge branch 'main' into 35067_wildes_flipper_config
rbauststfc Aug 22, 2024
8672d00
Fix formatting of seeAlso method
rbauststfc Aug 22, 2024
0620675
Use new constants in PolarizationEfficienciesWildes
rbauststfc Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class MANTID_ALGORITHMS_DLL PolarizationCorrectionWildes final : public API::Alg
int version() const override;
const std::string category() const override;
const std::string summary() const override;
const std::vector<std::string> seeAlso() const override;

private:
/// A convenience set of workspaces corresponding flipper configurations.
Expand Down Expand Up @@ -64,6 +65,9 @@ class MANTID_ALGORITHMS_DLL PolarizationCorrectionWildes final : public API::Alg
void threeInputsSolve01(WorkspaceMap &inputs, const EfficiencyMap &efficiencies);
void threeInputsSolve10(WorkspaceMap &inputs, const EfficiencyMap &efficiencies);
void twoInputsSolve01And10(WorkspaceMap &fullInputs, const WorkspaceMap &inputs, const EfficiencyMap &efficiencies);
void addSpinStateOutput(std::vector<std::string> &names, const std::string &spinStateOrder,
const std::string &baseName, const API::MatrixWorkspace_sptr &ws,
const std::string &spinState);
};
} // namespace Algorithms
} // namespace Mantid
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,32 @@ MANTID_ALGORITHMS_DLL std::optional<size_t> indexOfWorkspaceForSpinState(const s
std::string targetSpinState);
MANTID_ALGORITHMS_DLL std::vector<std::string> splitSpinStateString(const std::string &spinStates);
} // namespace PolarizationCorrectionsHelpers

namespace FlipperConfigurations {
auto constexpr OFF_ON = "01";
auto constexpr ON_OFF = "10";
auto constexpr OFF_OFF = "00";
auto constexpr ON_ON = "11";
auto constexpr OFF = "0";
auto constexpr ON = "1";
} // namespace FlipperConfigurations

namespace SpinStateConfigurationsFredrikze {
auto constexpr PARA_ANTI = "pa";
auto constexpr ANTI_PARA = "ap";
auto constexpr PARA_PARA = "pp";
auto constexpr ANTI_ANTI = "aa";
auto constexpr PARA = "p";
auto constexpr ANTI = "a";
} // namespace SpinStateConfigurationsFredrikze

namespace SpinStateConfigurationsWildes {
auto constexpr MINUS_PLUS = "-+";
auto constexpr PLUS_MINUS = "+-";
auto constexpr MINUS_MINUS = "--";
auto constexpr PLUS_PLUS = "++";
auto constexpr MINUS = "-";
auto constexpr PLUS = "+";
} // namespace SpinStateConfigurationsWildes

} // namespace Mantid::Algorithms
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ particular ordering.
*/
class MANTID_ALGORITHMS_DLL SpinStateValidator : public Kernel::TypedValidator<std::string> {
public:
SpinStateValidator(std::unordered_set<int> allowedNumbersOfSpins, const bool acceptSingleStates = false);
SpinStateValidator(std::unordered_set<int> allowedNumbersOfSpins, const bool acceptSingleStates = false,
const char paraIndicator = '0', const char antiIndicator = '1', const bool optional = false);
Kernel::IValidator_sptr clone() const override;

static const std::string ZERO_ONE;
Expand All @@ -34,6 +35,13 @@ class MANTID_ALGORITHMS_DLL SpinStateValidator : public Kernel::TypedValidator<s
static const std::string ZERO;
static const std::string ONE;

static const std::string MINUS_PLUS;
cailafinn marked this conversation as resolved.
Show resolved Hide resolved
static const std::string PLUS_MINUS;
static const std::string MINUS_MINUS;
static const std::string PLUS_PLUS;
static const std::string MINUS;
static const std::string PLUS;

static bool anyOfIsInSet(const std::vector<std::string> &anyOf, const std::unordered_set<std::string> &set);
static bool setContains(const std::unordered_set<std::string> &set, const std::string &s) {
return set.find(s) != set.cend();
Expand All @@ -42,6 +50,11 @@ class MANTID_ALGORITHMS_DLL SpinStateValidator : public Kernel::TypedValidator<s
private:
std::string checkValidity(const std::string &input) const override;
std::unordered_set<int> m_allowedNumbersOfSpins = {1, 2, 3, 4};
const std::unordered_set<std::string> getAllowedPairStates() const;
const std::unordered_set<std::string> getAllowedSingleStates() const;
bool m_acceptSingleStates = false;
const std::string m_para;
const std::string m_anti;
bool m_optional = false;
};
} // namespace Mantid::Algorithms
} // namespace Mantid::Algorithms
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class MANTID_ALGORITHMS_DLL PolarizationEfficiencyCor final : public API::Algori
public:
const std::string name() const override;
int version() const override;
const std::vector<std::string> seeAlso() const override { return {"PolarizationCorrectionFredrikze"}; }
const std::vector<std::string> seeAlso() const override {
return {"PolarizationCorrectionWildes", "PolarizationCorrectionFredrikze"};
}
const std::string category() const override;
const std::string summary() const override;

Expand Down
143 changes: 93 additions & 50 deletions Framework/Algorithms/src/PolarizationCorrectionWildes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,12 @@ namespace {
/// Property names.
namespace Prop {
static const std::string FLIPPERS{"Flippers"};
static const std::string SPIN_STATES{"SpinStates"};
static const std::string EFFICIENCIES{"Efficiencies"};
static const std::string INPUT_WS{"InputWorkspaces"};
static const std::string OUTPUT_WS{"OutputWorkspace"};
} // namespace Prop

/// Flipper configurations.
namespace Flippers {
using namespace Mantid::Algorithms;
static const std::string Off{SpinStateValidator::ZERO};
static const std::string OffOff{SpinStateValidator::ZERO_ZERO};
static const std::string OffOn{SpinStateValidator::ZERO_ONE};
static const std::string On{SpinStateValidator::ONE};
static const std::string OnOff{SpinStateValidator::ONE_ZERO};
static const std::string OnOn{SpinStateValidator::ONE_ONE};
} // namespace Flippers

/**
* Throw if given ws is nullptr.
* @param ws a workspace to check
Expand Down Expand Up @@ -313,6 +303,9 @@ const std::string PolarizationCorrectionWildes::summary() const {
"and analyzer efficiencies.";
}

/// Algorithm's related algorithms. @see Algorithm::seeAlso
const std::vector<std::string> PolarizationCorrectionWildes::seeAlso() const { return {"PolarizationEfficiencyCor"}; }

/**
* Count the non-nullptr workspaces
* @return the count on non-nullptr workspaces.
Expand All @@ -333,10 +326,14 @@ void PolarizationCorrectionWildes::init() {
std::make_unique<API::WorkspaceProperty<API::WorkspaceGroup>>(Prop::OUTPUT_WS, "", Kernel::Direction::Output),
"A group of polarization efficiency corrected workspaces.");

const auto spinStateValidator = std::make_shared<SpinStateValidator>(std::unordered_set<int>{1, 2, 3, 4}, true);
const auto flipperConfigValidator = std::make_shared<SpinStateValidator>(std::unordered_set<int>{1, 2, 3, 4}, true);
declareProperty(Prop::FLIPPERS,
Flippers::OffOff + ", " + Flippers::OffOn + ", " + Flippers::OnOff + ", " + Flippers::OnOn,
spinStateValidator, "Flipper configurations of the input workspaces.");
std::string(FlipperConfigurations::OFF_OFF) + ", " + FlipperConfigurations::OFF_ON + ", " +
FlipperConfigurations::ON_OFF + ", " + FlipperConfigurations::ON_ON,
flipperConfigValidator, "Flipper configurations of the input workspaces.");
const auto spinStateValidator =
std::make_shared<SpinStateValidator>(std::unordered_set<int>{0, 1, 2, 4}, true, '+', '-', true);
cailafinn marked this conversation as resolved.
Show resolved Hide resolved
declareProperty(Prop::SPIN_STATES, "", spinStateValidator, "The order of the spin states in the output workspace.");
declareProperty(
std::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(Prop::EFFICIENCIES, "", Kernel::Direction::Input),
"A workspace containing the efficiency factors P1, P2, F1 and F2 as "
Expand Down Expand Up @@ -406,12 +403,28 @@ std::map<std::string, std::string> PolarizationCorrectionWildes::validateInputs(
}
}
const std::vector<std::string> inputs = getProperty(Prop::INPUT_WS);
const std::string flipperProperty = getProperty(Prop::FLIPPERS);
const auto flipperCount = PolarizationCorrectionsHelpers::splitSpinStateString(flipperProperty).size();
const auto flipperConfig = PolarizationCorrectionsHelpers::splitSpinStateString(getPropertyValue(Prop::FLIPPERS));
const auto flipperCount = flipperConfig.size();
if (inputs.size() != flipperCount) {
issues[Prop::FLIPPERS] = "The number of flipper configurations (" + std::to_string(flipperCount) +
") does not match the number of input workspaces (" + std::to_string(inputs.size()) + ")";
}
// SpinStates checks.
const auto spinStates = PolarizationCorrectionsHelpers::splitSpinStateString(getPropertyValue(Prop::SPIN_STATES));
if (inputs.size() == 1 && !spinStates.empty()) {
issues[Prop::SPIN_STATES] = "Output workspace order cannot be set for direct beam calculations.";
} else if (!spinStates.empty()) {
if (flipperConfig.front().size() == 1 && spinStates.size() != 2) {
issues[Prop::SPIN_STATES] =
"Incorrect number of workspaces in output configuration: " + std::to_string(spinStates.size()) +
". Only two output workspaces are produced when an analyzer is not used.";
}
if (flipperConfig.front().size() == 2 && spinStates.size() != 4) {
issues[Prop::SPIN_STATES] =
"Incorrect number of workspaces in output configuration: " + std::to_string(spinStates.size()) +
". Four output workspaces are produced by the corrections.";
}
}
return issues;
}

Expand All @@ -434,16 +447,16 @@ void PolarizationCorrectionWildes::checkConsistentNumberHistograms(const Workspa
}
};
if (inputs.mmWS) {
checkNHist(inputs.mmWS, Flippers::OnOn);
checkNHist(inputs.mmWS, FlipperConfigurations::ON_ON);
}
if (inputs.mpWS) {
checkNHist(inputs.mpWS, Flippers::OnOff);
checkNHist(inputs.mpWS, FlipperConfigurations::ON_OFF);
}
if (inputs.pmWS) {
checkNHist(inputs.pmWS, Flippers::OffOn);
checkNHist(inputs.pmWS, FlipperConfigurations::OFF_ON);
}
if (inputs.ppWS) {
checkNHist(inputs.ppWS, Flippers::OffOff);
checkNHist(inputs.ppWS, FlipperConfigurations::OFF_OFF);
}
}

Expand Down Expand Up @@ -480,16 +493,16 @@ void PolarizationCorrectionWildes::checkConsistentX(const WorkspaceMap &inputs,
}
};
if (inputs.mmWS) {
checkWS(inputs.mmWS, Flippers::OnOn);
checkWS(inputs.mmWS, FlipperConfigurations::ON_ON);
}
if (inputs.mpWS) {
checkWS(inputs.mpWS, Flippers::OnOff);
checkWS(inputs.mpWS, FlipperConfigurations::ON_OFF);
}
if (inputs.pmWS) {
checkWS(inputs.pmWS, Flippers::OffOn);
checkWS(inputs.pmWS, FlipperConfigurations::OFF_ON);
}
if (inputs.ppWS) {
checkWS(inputs.ppWS, Flippers::OffOff);
checkWS(inputs.ppWS, FlipperConfigurations::OFF_OFF);
}
}

Expand All @@ -501,24 +514,26 @@ void PolarizationCorrectionWildes::checkConsistentX(const WorkspaceMap &inputs,
* @return a group workspace
*/
API::WorkspaceGroup_sptr PolarizationCorrectionWildes::groupOutput(const WorkspaceMap &outputs) {
const std::string outWSName = getProperty(Prop::OUTPUT_WS);
const auto &outWSName = getPropertyValue(Prop::OUTPUT_WS);
auto spinStateOrder = getPropertyValue(Prop::SPIN_STATES);
std::vector<std::string> names;
if (!spinStateOrder.empty()) {
names.resize(PolarizationCorrectionsHelpers::splitSpinStateString(spinStateOrder).size());
}

if (outputs.ppWS) {
names.emplace_back(outWSName + "_++");
API::AnalysisDataService::Instance().addOrReplace(names.back(), outputs.ppWS);
addSpinStateOutput(names, spinStateOrder, outWSName, outputs.ppWS, SpinStateConfigurationsWildes::PLUS_PLUS);
}
if (outputs.pmWS) {
names.emplace_back(outWSName + "_+-");
API::AnalysisDataService::Instance().addOrReplace(names.back(), outputs.pmWS);
addSpinStateOutput(names, spinStateOrder, outWSName, outputs.pmWS, SpinStateConfigurationsWildes::PLUS_MINUS);
}
if (outputs.mpWS) {
names.emplace_back(outWSName + "_-+");
API::AnalysisDataService::Instance().addOrReplace(names.back(), outputs.mpWS);
addSpinStateOutput(names, spinStateOrder, outWSName, outputs.mpWS, SpinStateConfigurationsWildes::MINUS_PLUS);
}
if (outputs.mmWS) {
names.emplace_back(outWSName + "_--");
API::AnalysisDataService::Instance().addOrReplace(names.back(), outputs.mmWS);
addSpinStateOutput(names, spinStateOrder, outWSName, outputs.mmWS, SpinStateConfigurationsWildes::MINUS_MINUS);
}

auto group = createChildAlgorithm("GroupWorkspaces");
group->initialize();
group->setProperty("InputWorkspaces", names);
Expand All @@ -528,6 +543,34 @@ API::WorkspaceGroup_sptr PolarizationCorrectionWildes::groupOutput(const Workspa
return outWS;
}

/**
* Add an output name in the correct position in the vector and to the ADS.
* @param names A list of the names of the workspaces the algorithm has generated.
* @param spinStateOrder The order the output should be in.
* @param baseName The base name for the output workspaces ("BASENAME_SPINSTATE" e.g "OUTNAME_+-")
* @param ws The workspace to add to the vector and ADS.
* @param spinState The spin state the workspace represents.
*/
void PolarizationCorrectionWildes::addSpinStateOutput(std::vector<std::string> &names,
const std::string &spinStateOrder, const std::string &baseName,
const API::MatrixWorkspace_sptr &ws,
const std::string &spinState) {
if (spinStateOrder.empty()) {
names.emplace_back(baseName + "_" + spinState);
API::AnalysisDataService::Instance().addOrReplace(names.back(), ws);
} else {
const auto &maybeIndex = PolarizationCorrectionsHelpers::indexOfWorkspaceForSpinState(
PolarizationCorrectionsHelpers::splitSpinStateString(spinStateOrder), spinState);
if (!maybeIndex.has_value()) {
throw std::invalid_argument("Required spin state (" + spinState + ") not found in spin state order (" +
cailafinn marked this conversation as resolved.
Show resolved Hide resolved
spinStateOrder + ").");
}
const auto index = maybeIndex.value();
names[index] = baseName + "_" + spinState;
API::AnalysisDataService::Instance().addOrReplace(names[index], ws);
}
}

/**
* Make a convenience access object to the efficiency factors.
* @return an EfficiencyMap object
Expand Down Expand Up @@ -562,7 +605,7 @@ PolarizationCorrectionWildes::EfficiencyMap PolarizationCorrectionWildes::effici
PolarizationCorrectionWildes::WorkspaceMap
PolarizationCorrectionWildes::directBeamCorrections(const WorkspaceMap &inputs, const EfficiencyMap &efficiencies) {
using namespace boost::math;
checkInputExists(inputs.ppWS, Flippers::Off);
checkInputExists(inputs.ppWS, FlipperConfigurations::OFF);
WorkspaceMap outputs;
outputs.ppWS = createWorkspaceWithHistory(inputs.ppWS);
const size_t nHisto = inputs.ppWS->getNumberHistograms();
Expand Down Expand Up @@ -599,8 +642,8 @@ PolarizationCorrectionWildes::directBeamCorrections(const WorkspaceMap &inputs,
PolarizationCorrectionWildes::WorkspaceMap
PolarizationCorrectionWildes::analyzerlessCorrections(const WorkspaceMap &inputs, const EfficiencyMap &efficiencies) {
using namespace boost::math;
checkInputExists(inputs.mmWS, Flippers::On);
checkInputExists(inputs.ppWS, Flippers::Off);
checkInputExists(inputs.mmWS, FlipperConfigurations::ON);
checkInputExists(inputs.ppWS, FlipperConfigurations::OFF);
WorkspaceMap outputs;
outputs.mmWS = createWorkspaceWithHistory(inputs.mmWS);
outputs.ppWS = createWorkspaceWithHistory(inputs.ppWS);
Expand Down Expand Up @@ -663,8 +706,8 @@ PolarizationCorrectionWildes::analyzerlessCorrections(const WorkspaceMap &inputs
PolarizationCorrectionWildes::WorkspaceMap
PolarizationCorrectionWildes::twoInputCorrections(const WorkspaceMap &inputs, const EfficiencyMap &efficiencies) {
using namespace boost::math;
checkInputExists(inputs.mmWS, Flippers::OnOn);
checkInputExists(inputs.ppWS, Flippers::OffOff);
checkInputExists(inputs.mmWS, FlipperConfigurations::ON_ON);
checkInputExists(inputs.ppWS, FlipperConfigurations::OFF_OFF);
WorkspaceMap fullInputs = inputs;
fullInputs.mpWS = createWorkspaceWithHistory(inputs.mmWS);
fullInputs.pmWS = createWorkspaceWithHistory(inputs.ppWS);
Expand All @@ -684,13 +727,13 @@ PolarizationCorrectionWildes::twoInputCorrections(const WorkspaceMap &inputs, co
PolarizationCorrectionWildes::WorkspaceMap
PolarizationCorrectionWildes::threeInputCorrections(const WorkspaceMap &inputs, const EfficiencyMap &efficiencies) {
WorkspaceMap fullInputs = inputs;
checkInputExists(inputs.mmWS, Flippers::OnOn);
checkInputExists(inputs.ppWS, Flippers::OffOff);
checkInputExists(inputs.mmWS, FlipperConfigurations::ON_ON);
checkInputExists(inputs.ppWS, FlipperConfigurations::OFF_OFF);
if (!inputs.mpWS) {
checkInputExists(inputs.pmWS, Flippers::OffOn);
checkInputExists(inputs.pmWS, FlipperConfigurations::OFF_ON);
threeInputsSolve10(fullInputs, efficiencies);
} else {
checkInputExists(inputs.mpWS, Flippers::OnOff);
checkInputExists(inputs.mpWS, FlipperConfigurations::ON_OFF);
threeInputsSolve01(fullInputs, efficiencies);
}
return fullCorrections(fullInputs, efficiencies);
Expand All @@ -707,10 +750,10 @@ PolarizationCorrectionWildes::threeInputCorrections(const WorkspaceMap &inputs,
PolarizationCorrectionWildes::WorkspaceMap
PolarizationCorrectionWildes::fullCorrections(const WorkspaceMap &inputs, const EfficiencyMap &efficiencies) {
using namespace boost::math;
checkInputExists(inputs.mmWS, Flippers::OnOn);
checkInputExists(inputs.mpWS, Flippers::OnOff);
checkInputExists(inputs.pmWS, Flippers::OffOn);
checkInputExists(inputs.ppWS, Flippers::OffOff);
checkInputExists(inputs.mmWS, FlipperConfigurations::ON_ON);
checkInputExists(inputs.mpWS, FlipperConfigurations::ON_OFF);
checkInputExists(inputs.pmWS, FlipperConfigurations::OFF_ON);
checkInputExists(inputs.ppWS, FlipperConfigurations::OFF_OFF);
WorkspaceMap outputs;
outputs.mmWS = createWorkspaceWithHistory(inputs.mmWS);
outputs.mpWS = createWorkspaceWithHistory(inputs.mpWS);
Expand Down Expand Up @@ -777,13 +820,13 @@ PolarizationCorrectionWildes::mapInputsToDirections(const std::vector<std::strin
throw std::runtime_error("One of the input workspaces doesn't seem to be a MatrixWorkspace.");
}
const auto &f = flippers[i];
if (f == Flippers::OnOn || f == Flippers::On) {
if (f == FlipperConfigurations::ON_ON || f == FlipperConfigurations::ON) {
inputs.mmWS = ws;
} else if (f == Flippers::OnOff) {
} else if (f == FlipperConfigurations::ON_OFF) {
inputs.mpWS = ws;
} else if (f == Flippers::OffOn) {
} else if (f == FlipperConfigurations::OFF_ON) {
inputs.pmWS = ws;
} else if (f == Flippers::OffOff || f == Flippers::Off) {
} else if (f == FlipperConfigurations::OFF_OFF || f == FlipperConfigurations::OFF) {
inputs.ppWS = ws;
} else {
throw std::runtime_error(std::string{"Unknown entry in "} + Prop::FLIPPERS);
Expand Down
Loading
Loading