27const std::string NumberType(
"NumberType");
28const std::vector<std::string> typeOptions{
"AutoDetect",
"Int",
"Double"};
29enum class TypeMode { AUTO_DETECT, INT, DOUBLE, enum_count };
32const std::string LogType(
"LogType");
33const std::vector<std::string> propOptions{
"String",
"Number",
"Number Series"};
34enum class LogMode { STRING_LOG, NUMBER_LOG, NUMBER_SERIES_LOG, enum_count };
43using namespace Kernel;
45using Types::Core::DateAndTime;
49 "Workspace to add the log entry to");
51 "The name that will identify the log entry");
56 "The type that the log data will be.");
60 "Force LogText to be interpreted as a number of type 'int' "
66 "Optional workspace contain the data");
67 declareProperty(
"WorkspaceIndex", 0,
"The workspace index of the TimeSeriesWorkspace to be imported.");
69 "If it is specified as true, then all the meta data "
70 "information will be retrieved from the input workspace. It "
71 "will be used with algorithm ExportTimeSeriesProperty.");
73 std::vector<std::string> time_units{
"Second",
"Nanosecond"};
74 declareProperty(
"TimeUnit",
"Second", std::make_shared<Kernel::StringListValidator>(time_units),
75 "The unit of the time of the input workspace");
77 "If specified as True, then then the "
78 "time stamps are relative to the run "
79 "start time of the target workspace.");
81 "Update instrument parameters to account for new log. "
82 "This will update detector positions that depend on motors, for example.");
91 auto expinfo_ws = std::dynamic_pointer_cast<ExperimentInfo>(target_workspace);
94 auto infos = std::dynamic_pointer_cast<MultipleExperimentInfos>(target_workspace);
96 throw std::invalid_argument(
"Input workspace does not support sample logs");
98 if (infos->getNumExperimentInfo() < 1) {
100 infos->addExperimentInfo(info);
102 expinfo_ws = infos->getExperimentInfo(0);
106 Run &theRun = expinfo_ws->mutableRun();
115 if ((propNumberType != TypeMode::AUTO_DETECT) && (propType == LogMode::STRING_LOG)) {
116 throw std::invalid_argument(
"You may only use NumberType 'Int' or 'Double' options if "
117 "LogType is 'Number' or 'Number Series'");
126 if (propType == LogMode::STRING_LOG) {
129 }
else if (propType == LogMode::NUMBER_SERIES_LOG) {
143 const bool updateInstrumentParams =
getProperty(
"UpdateInstrumentParameters");
144 if (updateInstrumentParams && expinfo_ws->getInstrument()->isParametrized())
145 expinfo_ws->populateInstrumentParameters();
157 const std::string &propUnit,
const std::string &propNumberType) {
159 bool value_is_int(
false);
160 TYPEMODE propType = propNumberType;
161 if (propType != TypeMode::AUTO_DETECT) {
162 value_is_int = (propType == TypeMode::INT);
175 if (convert_to_int == 0) {
177 g_log.
error() <<
"Error interpreting string '" << propValue <<
"' as NumberType Int.";
178 throw std::runtime_error(
"Invalie integer input");
185 if (convert_to_dbl == 0) {
186 g_log.
error() <<
"Error interpreting string '" << propValue <<
"' as NumberType Double.";
187 throw std::runtime_error(
"Invalid double input.");
190 g_log.
information() <<
"added property " << propName <<
" with value " << dblVal <<
"\n";
207 const std::string &propUnit) {
222 const std::string &prop_unit,
const std::string &prop_number_type) {
224 bool is_int_series(
false);
225 TYPEMODE propType = prop_number_type;
226 if (propType == TypeMode::INT) {
228 is_int_series =
true;
229 }
else if (propType == TypeMode::AUTO_DETECT) {
231 if (prop_value.empty())
232 g_log.
warning(
"For sample log in TimeSeriesProperty and values are given "
233 "by MarixWorkspace, the default data type "
239 is_int_series =
true;
242 }
else if (propType != TypeMode::DOUBLE) {
244 g_log.
error() <<
"TimeSeriesProperty with data type " << prop_number_type <<
" is not supported.\n";
245 throw std::runtime_error(
"Unsupported TimeSeriesProperty type.");
250 bool use_ws = !tsp_ws_name.empty();
251 bool use_single_value = !prop_value.empty();
252 if (use_ws && use_single_value) {
253 throw std::runtime_error(
"Both TimeSeries workspace and sing value are "
254 "specified. It is not allowed.");
255 }
else if (!use_ws && !use_single_value) {
256 throw std::runtime_error(
"Neither TimeSeries workspace or sing value are "
257 "specified. It is not allowed.");
262 Types::Core::DateAndTime startTime =
getRunStart(run_obj);
266 auto tsp = std::make_unique<TimeSeriesProperty<int>>(prop_name);
267 if (use_single_value) {
270 tsp->addValue(startTime, intVal);
272 throw std::invalid_argument(
"Input value cannot be converted to an integer value.");
277 auto tsp = std::make_unique<TimeSeriesProperty<double>>(prop_name);
278 if (use_single_value) {
281 tsp->addValue(startTime, dblVal);
283 throw std::invalid_argument(
"Input value cannot be converted to a double number.");
305 if (ws_index < 0 || ws_index >
static_cast<int>(data_ws->getNumberHistograms()))
306 throw std::runtime_error(
"Input workspace index is out of range");
309 bool epochtime(
false);
310 std::string timeunit;
312 bool is_second = timeunit ==
"Second";
315 std::vector<DateAndTime> time_vec =
getTimes(data_ws, ws_index, epochtime, is_second, run_obj);
319 std::vector<int> value_vec =
getIntValues(data_ws, ws_index);
320 int_prop->addValues(time_vec, value_vec);
324 std::vector<double> value_vec =
getDblValues(data_ws, ws_index);
325 int_prop->addValues(time_vec, value_vec);
342 int workspace_index,
bool is_epoch,
bool is_second,
345 int64_t timeshift(0);
348 Types::Core::DateAndTime run_start_time =
getRunStart(run_obj);
349 timeshift = run_start_time.totalNanoseconds();
353 std::vector<Types::Core::DateAndTime> timevec;
354 size_t vecsize = dataws->readX(workspace_index).size();
355 for (
size_t i = 0; i < vecsize; ++i) {
356 double timedbl = dataws->readX(workspace_index)[i];
359 auto entry_i64 =
static_cast<int64_t
>(timedbl);
360 Types::Core::DateAndTime entry(timeshift + entry_i64);
361 timevec.emplace_back(entry);
375 Types::Core::DateAndTime runstart(0);
378 }
catch (
const std::runtime_error &) {
393 std::vector<double> valuevec;
394 size_t vecsize = dataws->readY(workspace_index).size();
395 for (
size_t i = 0; i < vecsize; ++i)
396 valuevec.emplace_back(dataws->readY(workspace_index)[i]);
409 std::vector<int> valuevec;
410 size_t vecsize = dataws->readY(workspace_index).size();
411 for (
size_t i = 0; i < vecsize; ++i)
412 valuevec.emplace_back(
static_cast<int>(dataws->readY(workspace_index)[i]));
427 std::string epochtimestr = dataws->run().getProperty(
"IsEpochTime")->value();
428 epochtime = epochtimestr ==
"true";
429 timeunit = dataws->run().getProperty(
"TimeUnit")->value();
#define DECLARE_ALGORITHM(classname)
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.
This class is shared by a few Workspace types and holds information related to a particular experimen...
void addLogData(Kernel::Property *p)
Add a log entry.
bool hasProperty(const std::string &name) const
Does the property exist on the object.
const Types::Core::DateAndTime startTime() const
Return the run start time.
Kernel::Property * getProperty(const std::string &name) const
Returns the named property as a pointer.
void removeLogData(const std::string &name, const bool delproperty=true)
Remove a named log entry.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
void addSingleValueProperty(API::Run &theRun, const std::string &propName, const std::string &propValue, const std::string &propUnit, const std::string &propNumberType)
Add a single value property.
std::vector< Types::Core::DateAndTime > getTimes(const API::MatrixWorkspace_const_sptr &dataws, int workspace_index, bool is_epoch, bool is_second, const API::Run &run_obj)
get the vector of times of the TimeSeriesProperty entries
void exec() override
Execution code.
void init() override
Initialisation code.
void addStringLog(API::Run &theRun, const std::string &propName, const std::string &propValue, const std::string &propUnit)
Add a sample log (property) with value as string.
std::vector< double > getDblValues(const API::MatrixWorkspace_const_sptr &dataws, int workspace_index)
get value vector of the double TimeSeriesProperty entries
void getMetaData(const API::MatrixWorkspace_const_sptr &dataws, bool &epochtime, std::string &timeunit)
get meta data from input workspace or user input
Types::Core::DateAndTime getRunStart(const API::Run &run_obj)
get run start time
std::vector< int > getIntValues(const API::MatrixWorkspace_const_sptr &dataws, int workspace_index)
get value vector of the integer TimeSeriesProperty entries
void setTimeSeriesData(const API::Run &run_obj, const std::string &property_name, bool value_is_int)
set the time series property's entries to the newly added TimeSeriesProperty
void addTimeSeriesProperty(API::Run &run_obj, const std::string &prop_name, const std::string &prop_value, const std::string &prop_unit, const std::string &prop_number_type)
Add a sample log as a TimeSeriesProperty.
A concrete property based on user options of a finite list of strings.
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.
Validator to check that a property is not left empty.
The concrete, templated class for properties.
virtual void setUnits(const std::string &unit)
Sets the units of the property, as a string.
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.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
int convert(const std::string &A, T &out)
Convert a string into a number.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.