Mantid
Loading...
Searching...
No Matches
XMLInstrumentParameter.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 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
15#include "MantidKernel/Logger.h"
17#include <boost/regex.hpp>
18#include <ctime>
19#include <fstream>
20#include <utility>
21
22namespace Mantid::Geometry {
23namespace {
24Kernel::Logger g_log("XMLInstrumentParameter");
25}
26
27using namespace Kernel;
28
54XMLInstrumentParameter::XMLInstrumentParameter(std::string logfileID, std::string value,
55 std::shared_ptr<Kernel::Interpolation> interpolation,
56 std::string formula, std::string formulaUnit, std::string resultUnit,
57 std::string paramName, std::string type, std::string tie,
58 std::vector<std::string> constraint, std::string &penaltyFactor,
59 std::string fitFunc, std::string extractSingleValueAs, std::string eq,
60 const Geometry::IComponent *comp, double angleConvertConst,
61 const std::string &description, std::string visible)
62 : m_logfileID(std::move(logfileID)), m_value(std::move(value)), m_paramName(std::move(paramName)),
63 m_type(std::move(type)), m_tie(std::move(tie)), m_constraint(std::move(constraint)),
64 m_penaltyFactor(penaltyFactor), m_fittingFunction(std::move(fitFunc)), m_formula(std::move(formula)),
65 m_formulaUnit(std::move(formulaUnit)), m_resultUnit(std::move(resultUnit)),
66 m_interpolation(std::move(interpolation)), m_extractSingleValueAs(std::move(extractSingleValueAs)),
67 m_eq(std::move(eq)), m_component(comp), m_angleConvertConst(angleConvertConst), m_description(""),
68 m_visible(std::move(visible)) {
69 if (!description.empty()) { // remove multiple spaces
70 static const boost::regex re("\\s+");
71 std::string desc = boost::regex_replace(description, re, " ");
72 (const_cast<std::string *>(&m_description))->assign(desc);
73 }
74}
75
91 // If this parameter is a <look-up-table> or <formula> return 0.0. Such
92 // parameter types are
93 // associated with 'fitting' parameters. In some sense this method should
94 // never be called
95 // for such parameters since they return values from other attributes and only
96 // during (or just
97 // before) 'fitting'. But include the statement below for safety.
98
99 if (!m_formula.empty() || m_interpolation->containData())
100 return 0.0;
101
102 // also this method should not be called when parameter is of 'string' type.
103 // Display
104 // an error and return 0.0
105
106 if (m_type == "string") {
107 g_log.error() << "XMLInstrumentParameter::createParamValue has been called "
108 "with a 'string' parameters.\n"
109 << "Return meaningless zere value.";
110 return 0.0;
111 }
112
113 double extractedValue = 0.0;
114
115 // Get value either as directly specified by user using the 'value' attribute
116 // or through
117 // a logfile as specified using the 'logfile-id' attribute. Note if both
118 // specified 'logfile-id'
119 // takes precedence over the 'value' attribute
120
121 if (!m_logfileID.empty()) {
122 // get value from time series
123
124 using StatisticsMapType = std::map<std::string, Kernel::Math::StatisticType>;
125 StatisticsMapType statistics_types;
126 statistics_types.emplace("first_value", Kernel::Math::FirstValue);
127 statistics_types.emplace("last_value", Kernel::Math::LastValue);
128 statistics_types.emplace("maximum", Kernel::Math::Maximum);
129 // statistics_types.emplace("mean", Kernel::Math::Mean);
130 // //TODO, would conflict with the existing "mean" flag, which corresponds
131 // to time_averaged_mean
132 statistics_types.emplace("median", Kernel::Math::Median);
133 statistics_types.emplace("minimum", Kernel::Math::Minimum);
134 StatisticsMapType::const_iterator statisics_choice = statistics_types.find(m_extractSingleValueAs);
135 const bool bUsingStandardStatistics = statisics_choice != statistics_types.end();
136
137 if (m_extractSingleValueAs == "mean") {
138 extractedValue = timeMean(logData);
139 } else if (bUsingStandardStatistics) {
140 extractedValue = Kernel::filterByStatistic(logData, (*statisics_choice).second);
141 }
142 // Looking for string: "position n", where n is an integer and is a 1-based
143 // index
144 else if (m_extractSingleValueAs.find("position") == 0 && m_extractSingleValueAs.size() >= 10) {
145 std::stringstream extractPosition(m_extractSingleValueAs);
146 std::string dummy;
147 int position;
148 extractPosition >> dummy >> position;
149
150 extractedValue = logData->nthValue(position - 1);
151 } else {
153 std::string("extract-single-value-as attribute for <parameter>") + " element (eq=" + m_eq +
154 ") in instrument definition file is not recognised.");
155 }
156 } else {
157 try {
158 extractedValue = boost::lexical_cast<double>(m_value);
159 } catch (boost::bad_lexical_cast &) {
160 throw Kernel::Exception::InstrumentDefinitionError(std::string("<parameter> with name ") + m_paramName +
161 " much be set to a number,\n" +
162 "unless it is meant to be a 'string' parameter.");
163 }
164 }
165
166 // Check if m_eq is specified if yes evaluate this equation
167
168 if (m_eq.empty())
169 return extractedValue;
170
171 size_t found;
172 std::string equationStr = m_eq;
173 found = equationStr.find("value");
174 if (found == std::string::npos) {
176 std::string("Equation attribute for <parameter>") + " element (eq=" + m_eq +
177 ") in instrument definition file must contain the string: \"value\"." +
178 ". \"value\" is replaced by a value from the logfile.");
179 }
180
181 std::stringstream readDouble;
182 readDouble << extractedValue;
183 std::string extractedValueStr = readDouble.str();
184 equationStr.replace(found, 5, extractedValueStr);
185
186 // check if more than one 'value' in m_eq
187
188 while (equationStr.find("value") != std::string::npos) {
189 found = equationStr.find("value");
190 equationStr.replace(found, 5, extractedValueStr);
191 }
192
193 try {
194 mu::Parser p;
195 p.SetExpr(equationStr);
196 return p.Eval();
197 } catch (mu::Parser::exception_type &e) {
199 std::string("Equation attribute for <parameter>") + " element (eq=" + m_eq +
200 ") in instrument definition file cannot be parsed." + ". Muparser error message is: " + e.GetMsg());
201 }
202}
203
204} // namespace Mantid::Geometry
const std::string & m_value
Definition: Algorithm.cpp:71
double value
The value of the point.
Definition: FitMW.cpp:51
double position
Definition: GetAllEi.cpp:154
base class for Geometric IComponent
Definition: IComponent.h:51
const std::string m_value
rather then extracting value from logfile,
const std::string m_paramName
specify a value directly
XMLInstrumentParameter(std::string logfileID, std::string value, std::shared_ptr< Kernel::Interpolation > interpolation, std::string formula, std::string formulaUnit, std::string resultUnit, std::string paramName, std::string type, std::string tie, std::vector< std::string > constraint, std::string &penaltyFactor, std::string fitFunc, std::string extractSingleValueAs, std::string eq, const Geometry::IComponent *comp, double angleConvertConst, const std::string &description, std::string visible)
Default constructor.
const std::string m_type
type of the data, e.g. int, double or string
const std::string m_description
if present, contains help string, describing the parameter
std::shared_ptr< Kernel::Interpolation > m_interpolation
evaluating the formula
const std::string m_formula
specify fitting function
const std::string m_eq
single value from the log file( average, first number, etc)
double createParamValue(Mantid::Kernel::TimeSeriesProperty< double > *logData) const
Returns parameter value as generated using possibly equation expression etc.
const std::string m_extractSingleValueAs
describes the way to extract a
Exception for errors associated with the instrument definition.
Definition: Exception.h:220
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
A specialised Property class for holding a series of time-value pairs.
TYPE nthValue(int n) const
Returns n-th value of n-th interval in an incredibly inefficient way.
Mantid::Kernel::Logger g_log("Goniometer")
MANTID_KERNEL_DLL double timeMean(const Kernel::Property *p)
Returns the mean value if the property is TimeSeriesProperty<double>
Definition: LogParser.cpp:312
double DLLExport filterByStatistic(TimeSeriesProperty< double > const *const propertyToFilter, Kernel::Math::StatisticType statisticType)
Function filtering double TimeSeriesProperties according to the requested statistics.
STL namespace.