Mantid
Loading...
Searching...
No Matches
SetInstrumentParameter.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 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 +
18
19#include <boost/algorithm/string.hpp>
20#include <deque>
21
22namespace Mantid::Algorithms {
23
24// Register the algorithm into the AlgorithmFactory
25DECLARE_ALGORITHM(SetInstrumentParameter)
26
27using namespace Kernel;
28using namespace Geometry;
29using namespace API;
30
31//----------------------------------------------------------------------------------------------
33const std::string SetInstrumentParameter::name() const { return "SetInstrumentParameter"; }
34
36int SetInstrumentParameter::version() const { return 1; }
37
39const std::string SetInstrumentParameter::category() const { return "DataHandling\\Instrument"; }
40
41//----------------------------------------------------------------------------------------------
42
43//----------------------------------------------------------------------------------------------
47 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("Workspace", "", Direction::InOut,
48 std::make_shared<InstrumentValidator>()),
49 "Workspace to add the log entry to");
50 declareProperty("ComponentName", "",
51 "The name of the component to attach "
52 "the parameter to. Default: the whole "
53 "instrument");
54 declareProperty(std::make_unique<ArrayProperty<detid_t>>("DetectorList"),
55 "The detector ID list to attach the parameter to. If set "
56 "this will override any ComponentName");
57 declareProperty("ParameterName", "", std::make_shared<MandatoryValidator<std::string>>(),
58 "The name that will identify the parameter");
59
60 std::vector<std::string> propOptions{"String", "Number", "Bool"};
61 declareProperty("ParameterType", "String", std::make_shared<StringListValidator>(propOptions),
62 "The type that the parameter value will be.");
63
64 declareProperty("Value", "", "The content of the Parameter");
65}
66
68std::map<std::string, std::string> SetInstrumentParameter::validateInputs() {
69 std::map<std::string, std::string> errors;
70 const std::set<std::string> allowedBoolValues{"1", "0", "true", "false"};
71 const std::string type = getPropertyValue("ParameterType");
72 std::string val = getPropertyValue("Value");
73
74 if (type == "Bool") {
75 boost::algorithm::to_lower(val);
76 if (allowedBoolValues.find(val) == allowedBoolValues.end()) {
77 errors["Value"] = "Invalid value for Bool type.";
78 }
79 } else if (type == "Number") {
80 int intVal;
81 double dblVal;
82 if (!Strings::convert(val, intVal) && !Strings::convert(val, dblVal)) {
83 errors["Value"] = "Invalid value for Number type.";
84 }
85 }
86
87 return errors;
88}
89
90//----------------------------------------------------------------------------------------------
94 // A pointer to the workspace to add a log to
95 Workspace_sptr ws = getProperty("Workspace");
96 MatrixWorkspace_sptr inputW = std::dynamic_pointer_cast<MatrixWorkspace>(ws);
97 DataObjects::PeaksWorkspace_sptr inputP = std::dynamic_pointer_cast<DataObjects::PeaksWorkspace>(ws);
98 ExperimentInfo_sptr experimentInfo;
99 if (inputW) {
100 experimentInfo = inputW;
101 } else if (inputP) {
102 experimentInfo = inputP;
103 } else {
104 throw std::runtime_error("Could not get a valid instrument from the "
105 "workspace which does not seem to be valid as "
106 "input (must be either MatrixWorkspace or "
107 "PeaksWorkspace");
108 }
109 auto &componentInfo = experimentInfo->mutableComponentInfo();
110
111 // get the data that the user wants to add
112 std::string cmptName = getProperty("ComponentName");
113 const std::vector<detid_t> detectorList = getProperty("DetectorList");
114 std::string paramName = getProperty("ParameterName");
115 std::string paramType = getProperty("ParameterType");
116 std::string paramValue = getPropertyValue("Value");
117
118 Strings::strip(cmptName);
119 Strings::strip(paramName);
120 Strings::strip(paramValue);
121
122 // set default to whole instrument
123 std::vector<size_t> componentIndices{componentInfo.root()};
124 if (!detectorList.empty()) {
125 const auto &detectorInfo = experimentInfo->detectorInfo();
126 componentIndices.clear();
127 for (const auto detID : detectorList) {
128 try {
129 // Detector indices are also component indices
130 componentIndices.emplace_back(detectorInfo.indexOf(detID));
131 } catch (const std::out_of_range &) {
132 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + std::to_string(detID) + " not found.",
133 "");
134 }
135 }
136 } else if (cmptName.length() > 0) {
137 // get all matching cmpts
138 componentIndices = componentsWithName(componentInfo, cmptName);
139 }
140
141 if (componentIndices.empty()) {
142 g_log.warning("Could not find the component requested.");
143 }
144 for (const auto componentIndex : componentIndices) {
145 addParameter(componentInfo, componentIndex, paramName, paramType, paramValue);
146 }
147}
148
155std::vector<size_t> SetInstrumentParameter::componentsWithName(const ComponentInfo &componentInfo,
156 const std::string &name) {
157 std::vector<size_t> matches;
158 const auto root = componentInfo.root();
159 if (componentInfo.name(root) == name) {
160 matches.emplace_back(root);
161 }
162 std::deque<size_t> toSearch{root};
163 while (!toSearch.empty()) {
164 const auto index = toSearch.front();
165 toSearch.pop_front();
166 for (const auto child : componentInfo.children(index)) {
167 if (componentInfo.name(child) == name) {
168 matches.emplace_back(child);
169 } else {
170 toSearch.emplace_back(child);
171 }
172 }
173 }
174 return matches;
175}
176
184void SetInstrumentParameter::addParameter(ComponentInfo &componentInfo, const size_t componentIndex,
185 const std::string &paramName, const std::string &paramType,
186 const std::string &paramValue) const {
187
188 // remove existing parameters first
189 componentInfo.clearParameter(componentIndex, paramName);
190 // then add the new one
191 if (paramType == "String") {
192 componentInfo.addString(componentIndex, paramName, paramValue);
193 } else if (paramType == "Number") {
194 int intVal;
195 if (Strings::convert(paramValue, intVal)) {
196 componentInfo.addInt(componentIndex, paramName, intVal);
197 } else {
198 double dblVal;
199 Strings::convert(paramValue, dblVal);
200 componentInfo.addDouble(componentIndex, paramName, dblVal);
201 }
202 } else if (paramType == "Bool") {
203 std::string paramValueLower(paramValue);
204 boost::algorithm::to_lower(paramValueLower);
205 bool paramBoolValue = (paramValueLower == "true" || paramValue == "1");
206 componentInfo.addBool(componentIndex, paramName, paramBoolValue);
207 }
208}
209
210} // namespace Mantid::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
std::map< DeltaEMode::Type, std::string > index
IntArray detectorList
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.
Kernel::Logger & g_log
Definition Algorithm.h:426
A property class for workspaces.
void exec() override
Execute the algorithm.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
static std::vector< size_t > componentsWithName(const Mantid::Geometry::ComponentInfo &componentInfo, const std::string &name)
The components with the given name, as Instrument::getAllComponentsWithName() finds them: in breadth-...
void addParameter(Mantid::Geometry::ComponentInfo &componentInfo, const size_t componentIndex, const std::string &paramName, const std::string &paramType, const std::string &paramValue) const
Adds a parameter to the component.
void init() override
Initialize the algorithm's properties.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
const std::string name() const override
Algorithm's name for identification.
ComponentInfo : Provides a component centric view on to the instrument.
void clearParameter(const size_t componentIndex, const std::string &name)
Remove every parameter of this name from this component.
const std::vector< size_t > & children(size_t componentIndex) const
void addString(const size_t componentIndex, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named string parameter at a specific component index.
void addInt(const size_t componentIndex, const std::string &name, int value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named integer parameter at a specific component index.
const std::string & name(const size_t componentIndex) const
void addDouble(const size_t componentIndex, const std::string &name, double value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named double parameter at a specific component index.
void addBool(const size_t componentIndex, const std::string &name, bool value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named boolean parameter at a specific component index.
Support for a property that holds an array of values.
Exception for when an item is not found in a collection.
Definition Exception.h:145
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Validator to check that a property is not left empty.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
Definition Strings.cpp:420
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition Strings.cpp:697
std::string to_string(const wide_integer< Bits, Signed > &n)
@ InOut
Both an input & output workspace.
Definition Property.h:56