19#include <boost/algorithm/string/classification.hpp>
20#include <boost/algorithm/string/split.hpp>
40 auto threeVthree = std::make_shared<ArrayLengthValidator<double>>(9);
41 std::vector<double> zeroes(9, 0.);
44 "An workspace that will be modified with the new goniometer created.");
46 std::vector<std::string> gonOptions{
"None, Specify Individually",
"Universal"};
47 declareProperty(
"Goniometers", gonOptions[0], std::make_shared<StringListValidator>(gonOptions),
48 "Set the axes and motor names according to goniometers that "
49 "we define in the code (Universal defined for SNS)");
51 std::string axisHelp =
": name, x,y,z, 1/-1 (1 for ccw, -1 for cw rotation). "
52 "A number of degrees can be used instead of name. "
53 "Leave blank for no axis";
54 for (
size_t i = 0; i <
NUM_AXES; i++) {
55 std::ostringstream propName;
56 propName <<
"Axis" << i;
58 propName.str() + axisHelp);
61 "Use the average value of the log, if false a separate "
62 "goniometer will be created for each value in the logs");
65 "Directly set the goniometer rotation matrix. Input should be in the form of a flattened 3x3 matrix");
66 for (
size_t i = 0; i <
NUM_AXES; i++) {
67 std::ostringstream propName;
68 propName <<
"Axis" << i;
74 std::vector<double> Gvec =
getProperty(
"GoniometerMatrix");
75 std::map<std::string, std::string> issues;
80 for (
size_t i = 0; i <
NUM_AXES; i++) {
81 std::ostringstream propName;
82 propName <<
"Axis" << i;
84 issues[propName.str()] =
"Can't provide a goniometer axis if a matrix string has also been provided";
91 issues[
"GoniometerMatrix"] =
"Supplied Goniometer Matrix is not a proper rotation";
95 issues[
"GoniometerMatrix"] =
"Supplied Goniometer Matrix is not a proper rotation: Matrix is not Square";
105 auto ei = std::dynamic_pointer_cast<ExperimentInfo>(ws);
109 auto infos = std::dynamic_pointer_cast<MultipleExperimentInfos>(ws);
111 throw std::invalid_argument(
"Input workspace does not support Goniometer");
113 if (infos->getNumExperimentInfo() < 1) {
115 infos->addExperimentInfo(info);
117 ei = infos->getExperimentInfo(0);
125 if (gonioDefined ==
"Universal")
128 for (
size_t i = 0; i <
NUM_AXES; i++) {
129 std::ostringstream propName;
130 propName <<
"Axis" << i;
133 if (!axisDesc.empty()) {
134 std::vector<std::string> tokens;
135 boost::split(tokens, axisDesc, boost::algorithm::detail::is_any_ofF<char>(
","));
136 if (tokens.size() != 5)
137 throw std::invalid_argument(
"Wrong number of arguments to parameter " + propName.str() +
138 ". Expected 5 comma-separated arguments.");
140 std::string axisName = tokens[0];
142 if (axisName.empty())
143 throw std::invalid_argument(
"The name must not be empty");
148 g_log.
information() <<
"Axis " << i <<
" - create a new log value GoniometerAxis" << i <<
"_FixedValue\n";
151 Types::Core::DateAndTime now = Types::Core::DateAndTime::getCurrentTime();
153 tsp->addValue(now, angle);
154 tsp->setUnits(
"degree");
155 if (ei->mutableRun().hasProperty(axisName)) {
156 ei->mutableRun().removeLogData(axisName);
158 ei->mutableRun().addLogData(tsp);
164 double x = 0,
y = 0,
z = 0;
166 throw std::invalid_argument(
"Error converting string '" + tokens[1] +
"' to a number.");
168 throw std::invalid_argument(
"Error converting string '" + tokens[2] +
"' to a number.");
170 throw std::invalid_argument(
"Error converting string '" + tokens[3] +
"' to a number.");
172 if (
vec.norm() < 1e-4)
173 throw std::invalid_argument(
"Rotation axis vector should be non-zero!");
177 if (ccw != 1 && ccw != -1)
178 throw std::invalid_argument(
"The ccw parameter must be 1 (ccw) or -1 "
179 "(cw) but no other value.");
186 g_log.
warning() <<
"Empty goniometer created; will always return an "
187 "identity rotation matrix.\n";
193 ei->mutableRun().setGoniometer(gon,
true);
195 ei->mutableRun().setGoniometers(gon);
196 }
catch (std::runtime_error &) {
200 const std::vector<double> gonVec =
getProperty(
"GoniometerMatrix");
202 ei->mutableRun().setGoniometer(
Goniometer(gonMat),
false);
#define DECLARE_ALGORITHM(classname)
std::vector< T > const * vec
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.
bool isDefault(const std::string &name) const
This class is shared by a few Workspace types and holds information related to a particular experimen...
A property class for workspaces.
void init() override
Initialise the properties.
void exec() override
Run the algorithm.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
size_t getNumberAxes() const
void makeUniversalGoniometer()
Make a default universal goniometer with phi,chi,omega angles according to SNS convention.
void pushAxis(const std::string &name, double axisx, double axisy, double axisz, double angle=0., int sense=CCW, int angUnit=angDegrees)
Add an additional axis to the goniometer, closer to the sample.
Support for a property that holds an array of values.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
bool isRotation() const
Check if a matrix represents a proper rotation @ return :: true/false.
size_t numRows() const
Return the number of rows in the matrix.
size_t numCols() const
Return the number of columns in the matrix.
The concrete, templated class for properties.
A specialised Property class for holding a series of time-value pairs.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
const size_t NUM_AXES
How many axes (max) to define.
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
int convert(const std::string &A, T &out)
Convert a string into a number.
std::string toString(const T &value)
Convert a number to a string.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.