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"
18#include <boost/regex.hpp>
19#include <ctime>
20#include <fstream>
21#include <string>
22#include <string_view>
23#include <utility>
24
25namespace Mantid::Geometry {
26namespace {
27Kernel::Logger g_log("XMLInstrumentParameter");
28}
29
30using namespace Kernel;
31
57XMLInstrumentParameter::XMLInstrumentParameter(std::string logfileID, std::string value,
58 std::shared_ptr<Kernel::Interpolation> interpolation,
59 std::string formula, std::string formulaUnit, std::string resultUnit,
60 std::string paramName, std::string type, std::string tie,
61 std::vector<std::string> constraint, std::string &penaltyFactor,
62 std::string fitFunc, std::string extractSingleValueAs, std::string eq,
63 const Geometry::IComponent *comp, double angleConvertConst,
64 const std::string &description, std::string visible)
65 : m_logfileID(std::move(logfileID)), m_value(std::move(value)), m_paramName(std::move(paramName)),
66 m_type(std::move(type)), m_tie(std::move(tie)), m_constraint(std::move(constraint)),
67 m_penaltyFactor(penaltyFactor), m_fittingFunction(std::move(fitFunc)), m_formula(std::move(formula)),
68 m_formulaUnit(std::move(formulaUnit)), m_resultUnit(std::move(resultUnit)),
69 m_interpolation(std::move(interpolation)), m_extractSingleValueAs(std::move(extractSingleValueAs)),
70 m_eq(std::move(eq)), m_component(comp), m_angleConvertConst(angleConvertConst), m_description(""),
71 m_visible(std::move(visible)) {
72 if (!description.empty()) { // remove multiple spaces
73 static const boost::regex re("\\s+");
74 std::string desc = boost::regex_replace(description, re, " ");
75 (const_cast<std::string *>(&m_description))->assign(desc);
76 }
77}
78
95 const Kernel::TimeROI *roi) const {
96 // If this parameter is a <look-up-table> or <formula> return 0.0. Such
97 // parameter types are
98 // associated with 'fitting' parameters. In some sense this method should
99 // never be called
100 // for such parameters since they return values from other attributes and only
101 // during (or just
102 // before) 'fitting'. But include the statement below for safety.
103
104 if (!m_formula.empty() || m_interpolation->containData())
105 return 0.0;
106
107 // also this method should not be called when parameter is of 'string' type.
108 // Display
109 // an error and return 0.0
110
111 if (m_type == "string") {
112 g_log.error() << "XMLInstrumentParameter::createParamValue has been called "
113 "with a 'string' parameters.\n"
114 << "Return meaningless zere value.";
115 return 0.0;
116 }
117
118 double extractedValue = 0.0;
119
120 // Get value either as directly specified by user using the 'value' attribute
121 // or through
122 // a logfile as specified using the 'logfile-id' attribute. Note if both
123 // specified 'logfile-id'
124 // takes precedence over the 'value' attribute
125
126 if (!m_logfileID.empty()) {
127 // get value from time series
128
129 using StatisticsMapType = std::map<std::string, Kernel::Math::StatisticType>;
130 StatisticsMapType statistics_types;
131 statistics_types.emplace("first_value", Kernel::Math::FirstValue);
132 statistics_types.emplace("last_value", Kernel::Math::LastValue);
133 statistics_types.emplace("maximum", Kernel::Math::Maximum);
134 // statistics_types.emplace("mean", Kernel::Math::Mean);
135 // //TODO, would conflict with the existing "mean" flag, which corresponds
136 // to time_averaged_mean
137 statistics_types.emplace("median", Kernel::Math::Median);
138 statistics_types.emplace("minimum", Kernel::Math::Minimum);
139 StatisticsMapType::const_iterator statisics_choice = statistics_types.find(m_extractSingleValueAs);
140 const bool bUsingStandardStatistics = statisics_choice != statistics_types.end();
141
142 if (m_extractSingleValueAs == "mean") {
143 extractedValue = timeMean(logData);
144 } else if (bUsingStandardStatistics) {
145 extractedValue = logData->extractStatistic((*statisics_choice).second, roi);
146 }
147 // Looking for string: "position n", where n is an integer and is a 1-based
148 // index
149 else if (m_extractSingleValueAs.starts_with("position") && m_extractSingleValueAs.size() >= 10) {
150 std::stringstream extractPosition(m_extractSingleValueAs);
151 std::string dummy;
152 int position;
153 extractPosition >> dummy >> position;
154
155 extractedValue = logData->nthValue(position - 1);
156 } else {
158 std::string("extract-single-value-as attribute for <parameter>") + " element (eq=" + m_eq +
159 ") in instrument definition file is not recognised.");
160 }
161 } else {
162 try {
163 extractedValue = boost::lexical_cast<double>(m_value);
164 } catch (boost::bad_lexical_cast &) {
165 throw Kernel::Exception::InstrumentDefinitionError(std::string("<parameter> with name ") + m_paramName +
166 " much be set to a number,\n" +
167 "unless it is meant to be a 'string' parameter.");
168 }
169 }
170
171 // Check if m_eq is specified if yes evaluate this equation
172
173 if (m_eq.empty())
174 return extractedValue;
175
176 size_t found;
177 std::string equationStr = m_eq;
178 found = equationStr.find("value");
179 if (found == std::string::npos) {
181 std::string("Equation attribute for <parameter>") + " element (eq=" + m_eq +
182 ") in instrument definition file must contain the string: \"value\"." +
183 ". \"value\" is replaced by a value from the logfile.");
184 }
185
186 std::stringstream readDouble;
187 readDouble << extractedValue;
188 std::string extractedValueStr = readDouble.str();
189 equationStr.replace(found, 5, extractedValueStr);
190
191 // check if more than one 'value' in m_eq
192
193 while (equationStr.find("value") != std::string::npos) {
194 found = equationStr.find("value");
195 equationStr.replace(found, 5, extractedValueStr);
196 }
197
198 try {
199 mu::Parser p;
200 p.SetExpr(equationStr);
201 return p.Eval();
202 } catch (mu::Parser::exception_type &e) {
204 std::string("Equation attribute for <parameter>") + " element (eq=" + m_eq +
205 ") in instrument definition file cannot be parsed." + ". Muparser error message is: " + e.GetMsg());
206 }
207}
208
209} // 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:53
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
double createParamValue(const Mantid::Kernel::TimeSeriesProperty< double > *logData, const Kernel::TimeROI *) const
Returns parameter value as generated using possibly equation expression etc.
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)
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:108
TimeROI : Object that holds information about when the time measurement was active.
Definition TimeROI.h:18
A specialised Property class for holding a series of time-value pairs.
double extractStatistic(Math::StatisticType selection, const TimeROI *roi=nullptr) const override
Calculate a particular statistical quantity from the values of the time series.
virtual 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, const TimeROI *roi=nullptr)
Returns the mean value if the property is TimeSeriesProperty<double>
STL namespace.