Mantid
Loading...
Searching...
No Matches
SpinStateValidator.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
9
11#include <boost/algorithm/string.hpp>
12#include <sstream>
13
14namespace Mantid::Kernel {
15
16SpinStateValidator::SpinStateValidator(std::unordered_set<int> allowedNumbersOfSpins, const bool acceptSingleStates,
17 const std::string &paraIndicator, const std::string &antiIndicator,
18 const bool optional, const std::string &extraIndicator)
19 : SpinStateValidator(std::move(allowedNumbersOfSpins), acceptSingleStates, paraIndicator, antiIndicator, optional,
20 extraIndicator, true) {}
21
22SpinStateValidator::SpinStateValidator(std::unordered_set<int> allowedNumbersOfSpins, const bool acceptSingleStates,
23 const std::string &paraIndicator, const std::string &antiIndicator,
24 const bool optional, const std::string &extraIndicator,
25 const bool rejectRepeatedSpinStates)
26 : TypedValidator<std::string>(), m_allowedNumbersOfSpins(std::move(allowedNumbersOfSpins)),
27 m_acceptSingleStates(acceptSingleStates), m_para(paraIndicator), m_anti(antiIndicator), m_optional(optional),
28 m_extra(extraIndicator), m_rejectRepeatedSpinStates(rejectRepeatedSpinStates) {}
29
34
35std::string SpinStateValidator::checkValidity(const std::string &input) const {
36 if (input.empty()) {
37 if (m_optional) {
38 return "";
39 }
40 std::ostringstream msg;
41 msg << "Enter a spin state string, it should be a comma-separated list, e.g. ";
42 msg << m_para << m_anti << "," << m_para << m_para << "," << m_anti << m_para << ',' << m_anti << m_anti << ".";
43 return msg.str();
44 }
45
46 const auto &allowedPairs = getAllowedPairStates();
47 const auto &allowedSingles = getAllowedSingleStates();
48
49 auto spinStates = SpinStateHelpers::splitSpinStateString(input);
50
51 int numberSpinStates = static_cast<int>(spinStates.size());
52 if (m_allowedNumbersOfSpins.find(numberSpinStates) == m_allowedNumbersOfSpins.cend())
53 return "The number of spin states specified is not an allowed value";
54
55 // First check that the spin states are valid entries
56 if (std::any_of(spinStates.cbegin(), spinStates.cend(), [&](const std::string &spinState) {
57 const bool isPair = setContains(allowedPairs, spinState);
58 const bool isSingle = m_acceptSingleStates && setContains(allowedSingles, spinState);
59 return !isPair && !isSingle;
60 })) {
61 std::ostringstream msg;
62 msg << "The format for the spin states is invalid, every comma separated value should contain ";
63 msg << (m_acceptSingleStates ? "either one or two spin states " : "two spin states ") << "from the set " << m_para
64 << "," << m_anti << (!m_extra.empty() ? "," + m_extra : "") << ".";
65
66 return msg.str();
67 }
68
69 // Single digits can't mix with pairs
71 bool containsAnySingles = SpinStateValidator::anyOfIsInSet(spinStates, allowedSingles);
72
73 bool containsAnyPairs = SpinStateValidator::anyOfIsInSet(spinStates, allowedPairs);
74 if (!(containsAnyPairs ^ containsAnySingles)) {
75 return "Single and paired spin states cannot be mixed";
76 }
77 }
78
79 // Check that each spin state only appears once
81 std::sort(spinStates.begin(), spinStates.end());
82 auto it = std::unique(spinStates.begin(), spinStates.end());
83 auto numberOfUniqueStates = static_cast<int>(std::distance(spinStates.begin(), it));
84 if (numberOfUniqueStates < numberSpinStates)
85 return "Each spin state must only appear once";
86 }
87
88 return "";
89}
90
91bool SpinStateValidator::anyOfIsInSet(const std::vector<std::string> &anyOf,
92 const std::unordered_set<std::string> &set) {
93 return std::any_of(anyOf.cbegin(), anyOf.cend(),
94 [&set](const std::string &stringPair) { return setContains(set, stringPair); });
95}
96
97const std::unordered_set<std::string> SpinStateValidator::getAllowedPairStates() const {
98 std::unordered_set<std::string> allowedPairs = {m_para + m_para, m_para + m_anti, m_anti + m_para, m_anti + m_anti};
99 if (!m_extra.empty()) {
100 allowedPairs.insert(
102 }
103 return allowedPairs;
104}
105
106const std::unordered_set<std::string> SpinStateValidator::getAllowedSingleStates() const {
107 std::unordered_set<std::string> allowedSinglePairs = {m_para, m_anti};
108 if (!m_extra.empty()) {
109 allowedSinglePairs.emplace(m_extra);
110 }
111 return allowedSinglePairs;
112}
113
114} // namespace Mantid::Kernel
static bool anyOfIsInSet(const std::vector< std::string > &anyOf, const std::unordered_set< std::string > &set)
std::unordered_set< int > m_allowedNumbersOfSpins
const std::unordered_set< std::string > getAllowedSingleStates() const
SpinStateValidator(std::unordered_set< int > allowedNumbersOfSpins, const bool acceptSingleStates=false, const std::string &paraIndicator="0", const std::string &antiIndicator="1", const bool optional=false, const std::string &extraIndicator="")
std::string checkValidity(const std::string &input) const override
const std::unordered_set< std::string > getAllowedPairStates() const
Kernel::IValidator_sptr clone() const override
MANTID_KERNEL_DLL std::vector< std::string > splitSpinStateString(const std::string &spinStates)
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
Definition IValidator.h:26
STL namespace.