23#include "MantidHistogramData/Histogram.h"
44using Types::Core::DateAndTime;
62 : m_eventWS(), m_splittersWorkspace(), m_splitterTableWorkspace(), m_matrixSplitterWS(), m_detCorrectWorkspace(),
63 m_useSplittersWorkspace(false), m_useArbTableSplitters(false), m_targetWorkspaceIndexSet(), m_splitters(),
64 m_outputWorkspacesMap(), m_wsNames(), m_detTofOffsets(), m_detTofFactors(), m_filterByPulseTime(false),
65 m_informationWS(), m_hasInfoWS(), m_progress(0.), m_outputWSNameBase(), m_toGroupWS(false), m_vecSplitterTime(),
66 m_vecSplitterGroup(), m_splitSampleLogs(false), m_useDBSpectrum(false), m_dbWSIndex(-1),
67 m_tofCorrType(NoneCorrect), m_specSkipType(), m_vecSkip(), m_isSplittersRelativeTime(false), m_filterStartTime(0),
74 "An input event workspace");
77 "An input SpilltersWorskpace for filtering");
80 "The base name to use for the output workspace. The output "
81 "workspace names are a combination of this and the index in "
86 "Optional output for the information of each splitter "
91 "Name of output workspace for TOF correction factor. ");
94 "Filter the event by its pulse time only for slow sample "
95 "environment log. This option can make execution of "
96 "algorithm faster. But it lowers precision.");
99 "Option to group all the output "
100 "workspaces. Group name will be "
101 "OutputWorkspaceBaseName.");
104 "If selected, the minimum output workspace is indexed from 1 "
108 vector<string> corrtypes{
"None",
"Customized",
"Direct",
"Elastic",
"Indirect"};
109 declareProperty(
"CorrectionToSample",
"None", std::make_shared<StringListValidator>(corrtypes),
110 "Type of correction on neutron events to sample time from "
115 "Name of table workspace containing the log "
116 "time correction factor for each detector. ");
118 std::make_unique<VisibleWhenProperty>(
"CorrectionToSample",
IS_EQUAL_TO,
"Customized"));
120 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
121 mustBePositive->setLower(0.0);
123 "Value of incident energy (Ei) in meV in direct mode.");
125 std::make_unique<VisibleWhenProperty>(
"CorrectionToSample",
IS_EQUAL_TO,
"Direct"));
128 vector<string> spec_no_det{
"Skip",
"Skip only if TOF correction"};
129 declareProperty(
"SpectrumWithoutDetector",
"Skip", std::make_shared<StringListValidator>(spec_no_det),
130 "Approach to deal with spectrum without detectors. ");
133 "If selected, all sample logs will be splitted by the "
134 "event splitters. It is not recommended for fast event "
142 "List of output workspaces names");
145 "Flag to indicate that in the input Matrix splitting workspace,"
146 "the time indicated by X-vector is relative to either run start time or "
147 "some indicted time.");
149 declareProperty(
"FilterStartTime",
"",
"Start time for splitters that can be parsed to DateAndTime.");
152 "List of name of sample logs of TimeSeriesProperty format. "
153 "They will be either excluded from splitting if ExcludedSpecifiedLogs is "
154 "specified as True. Or "
155 "They will be the only TimeSeriesProperty sample logs that will be split "
156 "to child workspaces.");
159 "If true, all the TimeSeriesProperty logs listed will be "
160 "excluded from duplicating. "
161 "Otherwise, only those specified logs will be split.");
164 "If selected, the names of the output workspaces will "
165 "include information about each slice.");
169 const std::string SPLITER_PROP_NAME =
"SplitterWorkspace";
170 std::map<std::string, std::string> result;
175 if (
bool(std::dynamic_pointer_cast<const SplittersWorkspace>(splitter))) {
176 if (std::dynamic_pointer_cast<const SplittersWorkspace>(splitter)->rowCount() == 0)
177 result[SPLITER_PROP_NAME] =
"SplittersWorkspace must have rows defined";
179 const auto table = std::dynamic_pointer_cast<const TableWorkspace>(splitter);
180 const auto matrix = std::dynamic_pointer_cast<const MatrixWorkspace>(splitter);
182 if (table->columnCount() != 3)
183 result[SPLITER_PROP_NAME] =
"TableWorkspace must have 3 columns";
184 else if (table->rowCount() == 0)
185 result[SPLITER_PROP_NAME] =
"TableWorkspace must have rows defined";
186 }
else if (
bool(matrix)) {
187 if (matrix->getNumberHistograms() == 1) {
188 if (!matrix->isHistogramData())
189 result[SPLITER_PROP_NAME] =
"MatrixWorkspace must be histogram";
191 result[SPLITER_PROP_NAME] =
"MatrixWorkspace can have only one histogram";
194 result[SPLITER_PROP_NAME] =
"Incompatible workspace type";
199 if (correctiontype ==
"Direct") {
203 if (!inputWS->run().hasProperty(
"Ei")) {
204 const string msg(
"InputWorkspace does not have Ei. Must specify IncidentEnergy");
205 result[
"CorrectionToSample"] = msg;
206 result[
"IncidentEnergy"] = msg;
209 }
else if (correctiontype ==
"Customized") {
212 const string msg(
"Must specify correction workspace with CorrectionToSample=Custom");
213 result[
"CorrectionToSample"] = msg;
214 result[
"DetectorTOFCorrectionWorkspace"] = msg;
252 std::vector<Kernel::TimeSeriesProperty<int> *> int_tsp_vector;
253 std::vector<Kernel::TimeSeriesProperty<double> *> dbl_tsp_vector;
254 std::vector<Kernel::TimeSeriesProperty<bool> *> bool_tsp_vector;
255 std::vector<Kernel::TimeSeriesProperty<string> *> string_tsp_vector;
256 copyNoneSplitLogs(int_tsp_vector, dbl_tsp_vector, bool_tsp_vector, string_tsp_vector);
266 double progressamount;
268 progressamount = 0.6;
270 progressamount = 0.7;
273 std::vector<std::unique_ptr<Kernel::TimeSeriesProperty<int>>> split_tsp_vector;
291 std::vector<std::string> outputwsnames;
296 ws_i->mutableRun().setGoniometer(inputGonio,
true);
297 }
catch (std::runtime_error &) {
300 outputwsnames.emplace_back(miter.second->getName());
302 setProperty(
"OutputWorkspaceNames", outputwsnames);
315 size_t numhist =
m_eventWS->getNumberHistograms();
321 g_log.
warning(
"By user's choice, No spectrum will be skipped even if it has "
326 size_t numskipspec = 0;
327 size_t numeventsskip = 0;
329 const auto &spectrumInfo =
m_eventWS->spectrumInfo();
330 for (
size_t i = 0; i < numhist; ++i) {
331 if (!spectrumInfo.hasDetectors(i)) {
338 if (numskipspec % 10 == 0)
345 if (numskipspec > 0) {
346 g_log.
warning() <<
"There are " << numskipspec <<
" spectra that do not have detectors. "
347 <<
"They will be skipped during filtering. There are total " << numeventsskip
348 <<
" events in those spectra. \nList of these specta is as below:\n"
349 << msgss.str() <<
"\n";
351 g_log.
notice(
"There is no spectrum that does not have detectors.");
372 errss <<
"Inputworkspace is not event workspace. ";
374 throw std::invalid_argument(errss.str());
391 throw runtime_error(
"Invalid type of input workspace, neither "
392 "SplittersWorkspace nor MatrixWorkspace.");
409 std::stringstream errss;
410 errss <<
"It is not allowed to group output workspaces into the same name "
411 "(i..e, OutputWorkspaceBaseName = "
413 throw std::invalid_argument(errss.str());
421 if (correctiontype ==
"None")
423 else if (correctiontype ==
"Customized")
425 else if (correctiontype ==
"Direct")
427 else if (correctiontype ==
"Elastic")
429 else if (correctiontype ==
"Indirect")
432 g_log.
error() <<
"Correction type '" << correctiontype <<
"' is not supported. \n";
433 throw runtime_error(
"Impossible situation!");
438 if (skipappr ==
"Skip")
440 else if (skipappr ==
"Skip only if TOF correction")
443 throw runtime_error(
"An unrecognized option for SpectrumWithoutDetector");
453 bool start_time_set =
false;
457 start_time_set =
true;
458 }
catch (std::runtime_error &) {
465 std::string start_time_str =
getProperty(
"FilterStartTime");
466 if (!start_time_str.empty()) {
468 Types::Core::DateAndTime temp_shift_time(start_time_str);
472 if (start_time_set) {
475 throw std::runtime_error(
"Input event workspace does not have property run_start. "
476 "User does not specifiy filter start time."
477 "Splitters cannot be in reltive time.");
498 groupws->setAlwaysStoreInADS(
true);
499 groupws->setProperty(
"InputWorkspaces",
m_wsNames);
500 groupws->setProperty(
"OutputWorkspace", groupname);
502 if (!groupws->isExecuted()) {
503 g_log.
error(
"Grouping all output workspaces fails.");
511 "Name of the workspace to be created as the output of grouping ");
516 if (!workspace_group) {
517 g_log.
error(
"Unable to retrieve output workspace from algorithm GroupWorkspaces");
541 bool exclude_listed_logs =
getProperty(
"ExcludeSpecifiedLogs");
542 std::vector<std::string> tsp_logs =
getProperty(
"TimeSeriesPropertyLogs");
544 std::set<std::string> tsp_logs_set(tsp_logs.begin(), tsp_logs.end());
546 std::set<std::string>::iterator set_iter;
548 int_tsp_name_vector.clear();
549 dbl_tsp_name_vector.clear();
550 bool_tsp_name_vector.clear();
552 std::vector<Property *> prop_vector =
m_eventWS->run().getProperties();
553 for (
auto *prop_i : prop_vector) {
555 std::string name_i = prop_i->name();
564 if (dbl_prop || int_prop || bool_prop || string_prop) {
566 set_iter = tsp_logs_set.find(name_i);
567 if (exclude_listed_logs && set_iter != tsp_logs_set.end()) {
570 g_log.
warning() <<
"Skip splitting sample log " << name_i <<
"\n";
572 }
else if (!exclude_listed_logs && set_iter == tsp_logs_set.end()) {
576 g_log.
warning() <<
"Skip splitting sample log " << name_i <<
"\n";
583 dbl_tsp_name_vector.emplace_back(dbl_prop);
584 }
else if (int_prop) {
586 int_tsp_name_vector.emplace_back(int_prop);
587 }
else if (bool_prop) {
589 bool_tsp_name_vector.emplace_back(bool_prop);
591 }
else if (string_prop) {
593 string_tsp_vector.emplace_back(string_prop);
599 std::map<int, DataObjects::EventWorkspace_sptr>::iterator ws_iter;
602 std::string value_i = prop_i->value();
606 ws_iter->second->mutableRun().addProperty(name_i, double_v,
true);
608 ws_iter->second->mutableRun().addProperty(name_i, int_v,
true);
610 ws_iter->second->mutableRun().addProperty(name_i, value_i,
true);
631 std::vector<Types::Core::DateAndTime> split_datetime_vec;
643 split_datetime_vec[i] = split_time;
647 std::set<int>::iterator target_iter;
648 int max_target_index = 0;
650 if (*target_iter > max_target_index)
651 max_target_index = *target_iter;
653 g_log.
information() <<
"Maximum target index = " << max_target_index <<
"\n";
660 for (
const auto &int_tsp : int_tsp_vector) {
665 for (
const auto &dbl_tsp : dbl_tsp_vector) {
670 for (
const auto &bool_tsp : bool_tsp_vector) {
675 for (
const auto &string_tsp : string_tsp_vector) {
680 for (
int tindex = 0; tindex <= max_target_index; ++tindex) {
682 std::map<int, DataObjects::EventWorkspace_sptr>::iterator wsiter;
685 g_log.
information() <<
"Workspace target (indexed as " << tindex <<
") does not have workspace associated.\n";
688 if (ws_i->run().hasProperty(
"proton_charge")) {
689 ws_i->mutableRun().integrateProtonCharge();
704template <
typename TYPE>
706 std::vector<Types::Core::DateAndTime> &split_datetime_vec,
707 const int max_target_index) {
710 const std::string &property_name = tsp->
name();
712 std::vector<std::unique_ptr<TimeSeriesProperty<TYPE>>> output_vector;
713 for (
int tindex = 0; tindex <= max_target_index; ++tindex) {
714 auto new_property = std::make_unique<TimeSeriesProperty<TYPE>>(property_name);
715 new_property->setUnits(tsp->
units());
716 output_vector.emplace_back(std::move(new_property));
720 if (tsp->
size() == 1) {
722 for (
size_t i_out = 0; i_out < output_vector.size(); ++i_out) {
727 std::vector<TimeSeriesProperty<TYPE> *> split_properties(output_vector.size());
729 std::transform(output_vector.begin(), output_vector.end(), split_properties.begin(),
735 for (
int tindex = 0; tindex <= max_target_index; ++tindex) {
740 g_log.
information() <<
"Workspace target (" << tindex <<
") does not have workspace associated."
745 ws_i->mutableRun().addProperty(std::move(output_vector[tindex]),
true);
769 for (
size_t i = 0; i < numsplitters; i++) {
796 <<
") than input information workspaces (" <<
m_informationWS->rowCount() <<
"). "
797 <<
" Information may not be accurate. \n";
822 int64_t last_entry_time(0);
825 for (
size_t i_splitter = 0; i_splitter < num_splitters; ++i_splitter) {
828 int64_t start_time_i64 = splitter.
start().totalNanoseconds();
829 int64_t stop_time_i64 = splitter.
stop().totalNanoseconds();
835 }
else if (abs(last_entry_time - start_time_i64) <
TOLERANCE) {
839 }
else if (start_time_i64 > last_entry_time +
TOLERANCE) {
847 std::stringstream errorss;
848 errorss <<
"New start time " << start_time_i64 <<
" is before last entry's time " << last_entry_time;
849 throw std::runtime_error(errorss.str());
884 const size_t sizex =
X.size();
885 const size_t sizey =
Y.size();
892 for (
size_t i = 0; i < sizex; ++i) {
900 for (
size_t i = 0; i < sizex; ++i)
905 uint32_t max_target_index = 1;
907 for (
size_t i = 0; i < sizey; ++i) {
909 auto y_index =
static_cast<int>(
Y[i]);
919 int_target = max_target_index;
932 uint32_t target_index = mapiter->second;
945int64_t timeInSecondsToNanoseconds(
const int64_t offset_ns,
const double time_sec) {
946 return offset_ns +
static_cast<int64_t
>(time_sec * 1.E9);
963 throw std::runtime_error(
"Splitters given in TableWorkspace must have 3 columns.");
969 bool found_undefined_splitter =
false;
972 int64_t filter_shift_time(0);
976 int max_target_index = 1;
980 for (
size_t irow = 0; irow < num_rows; ++irow) {
982 const auto start_time =
984 const auto stop_time =
998 found_undefined_splitter =
true;
1005 throw std::runtime_error(
"Input table workspace does not have splitters "
1006 "set up in order, which is a requirement.");
1014 int_target = mapiter->second;
1017 int_target = max_target_index;
1033 if (found_undefined_splitter) {
1048 const auto startTime = std::chrono::high_resolution_clock::now();
1051 std::map<int, std::string> infomap;
1055 infomap.emplace(row.
Int(0), row.
String(1));
1062 if (left >= 0 && right >= 0)
1063 return left < right;
1069 g_log.
debug() <<
"Min WS Group = " << minwsgroup <<
"\n";
1071 const bool from1 =
getProperty(
"OutputWorkspaceIndexedFrom1");
1072 int delta_wsindex = 0;
1074 delta_wsindex = 1 - minwsgroup;
1078 int numoutputws = 0;
1080 double wsgindex = 0.;
1085 bool descriptiveNames =
getProperty(
"DescriptiveOutputNames");
1087 if (descriptiveNames) {
1088 if ((
m_hasInfoWS && infomap[0].find(
"Log") != std::string::npos) ||
1093 std::shared_ptr<EventWorkspace> prototype_ws = create<EventWorkspace>(*
m_eventWS);
1097 bool add2output =
true;
1098 std::stringstream wsname;
1103 auto startTimeInSeconds =
1104 Mantid::Types::Core::DateAndTime::secondsFromDuration(splitter.start() -
m_runStartTime);
1105 auto stopTimeInSeconds =
1106 Mantid::Types::Core::DateAndTime::secondsFromDuration(splitter.stop() -
m_runStartTime);
1107 wsname << startTimeInSeconds <<
"_" << stopTimeInSeconds;
1108 }
else if (descriptiveNames) {
1109 auto infoiter = infomap.find(wsgroup);
1110 if (infoiter != infomap.end()) {
1111 std::string
name = infoiter->second;
1115 wsname << wsgroup + delta_wsindex;
1118 wsname << wsgroup + delta_wsindex;
1121 wsname <<
"unfiltered";
1126 std::shared_ptr<EventWorkspace> optws = prototype_ws->clone();
1128 optws->setSharedRun(Kernel::make_cow<Run>());
1135 info =
"Events that are filtered out. ";
1137 std::map<int, std::string>::iterator infoiter;
1138 infoiter = infomap.find(wsgroup);
1139 if (infoiter != infomap.end()) {
1140 info = infoiter->second;
1142 info =
"This workspace has no information provided. ";
1145 optws->setComment(info);
1146 optws->setTitle(info);
1153 std::stringstream propertynamess;
1154 if (wsgroup == -1) {
1155 propertynamess <<
"OutputWorkspace_unfiltered";
1157 propertynamess <<
"OutputWorkspace_" << wsgroup;
1177 g_log.
debug() <<
"Created output Workspace of group = " << wsgroup <<
" Property Name = " << propertynamess.str()
1178 <<
" Workspace name = " << wsname.str() <<
" with Number of events = " << optws->getNumberEvents()
1182 m_progress = 0.1 + 0.1 * wsgindex / numnewws;
1190 addTimer(
"createOutputWorkspacesSplitters", startTime, std::chrono::high_resolution_clock::now());
1207 g_log.
error(
"createOutputWorkspacesMatrixCase() is applied to "
1208 "MatrixWorkspace splitters only!");
1209 throw std::runtime_error(
"Wrong call!");
1216 size_t wsgindex = 0;
1217 bool descriptiveNames =
getProperty(
"DescriptiveOutputNames");
1219 std::shared_ptr<EventWorkspace> prototype_ws = create<EventWorkspace>(*
m_eventWS);
1223 throw std::runtime_error(
"It is not possible to have split-target group "
1224 "index < 0 in MatrixWorkspace case.");
1227 std::stringstream wsname;
1229 if (descriptiveNames) {
1243 std::shared_ptr<EventWorkspace> optws = prototype_ws->clone();
1245 optws->setSharedRun(Kernel::make_cow<Run>());
1249 std::stringstream propertynamess;
1251 propertynamess <<
"OutputWorkspace_unfiltered";
1253 propertynamess <<
"OutputWorkspace_" << wsgroup;
1260 g_log.
debug() <<
"Created output Workspace of group = " << wsgroup <<
" Workspace name = " << wsname.str()
1261 <<
" with Number of events = " << optws->getNumberEvents() <<
"\n";
1272 g_log.
debug() <<
" Property Name = " << propertynamess.str() <<
"\n";
1278 m_progress = 0.1 + 0.1 *
static_cast<double>(wsgindex) /
static_cast<double>(numoutputws);
1284 g_log.
debug() <<
"Output workspace number: " << numoutputws <<
"\n";
1285 setProperty(
"NumberOutputWS",
static_cast<int>(numoutputws));
1302 g_log.
error(
"createOutputWorkspacesTableSplitterCase() is applied to "
1303 "TableWorkspace splitters only!");
1304 throw std::runtime_error(
"Wrong call!");
1309 size_t wsgindex = 0;
1311 std::shared_ptr<EventWorkspace> prototype_ws = create<EventWorkspace>(*
m_eventWS);
1315 throw std::runtime_error(
"It is not possible to have split-target group "
1316 "index < 0 in TableWorkspace case.");
1319 std::stringstream wsname;
1320 bool descriptiveNames =
getProperty(
"DescriptiveOutputNames");
1323 if (descriptiveNames) {
1324 size_t startIndex = 0;
1342 std::shared_ptr<EventWorkspace> optws = prototype_ws->clone();
1344 optws->setSharedRun(Kernel::make_cow<Run>());
1357 g_log.
debug() <<
"Created output Workspace of group = " << wsgroup <<
" Workspace name = " << wsname.str()
1358 <<
" with Number of events = " << optws->getNumberEvents() <<
"\n";
1361 std::stringstream propertynamess;
1363 propertynamess <<
"OutputWorkspace_unfiltered";
1365 propertynamess <<
"OutputWorkspace_" << wsgroup;
1374 g_log.
debug() <<
" Property Name = " << propertynamess.str() <<
"\n";
1380 m_progress = 0.1 + 0.1 *
static_cast<double>(wsgindex) /
static_cast<double>(numoutputws);
1386 g_log.
debug() <<
"Output workspace number: " << numoutputws <<
"\n";
1387 setProperty(
"NumberOutputWS",
static_cast<int>(numoutputws));
1400 const size_t numhist =
m_eventWS->getNumberHistograms();
1402 setProperty(
"OutputTOFCorrectionWorkspace", corrws);
1409 std::unique_ptr<TimeAtSampleStrategy> strategy;
1424 for (
size_t i = 0; i < numhist; ++i) {
1427 Correction correction = strategy->calculate(i);
1431 corrws->mutableY(i)[0] = correction.
factor;
1432 corrws->mutableY(i)[1] = correction.
offset;
1448 if (
m_eventWS->run().hasProperty(
"Ei")) {
1449 ei =
m_eventWS->run().getLogAsSingleValue(
"Ei");
1450 g_log.
debug() <<
"Using stored Ei value " << ei <<
"\n";
1452 throw std::invalid_argument(
"No Ei value has been set or stored within the run information.");
1455 g_log.
debug() <<
"Using user-input Ei value " << ei <<
"\n";
1476 bool hasshift =
false;
1477 if (colnames.size() < 2)
1478 throw runtime_error(
"Input table workspace is not valide.");
1479 else if (colnames.size() >= 3)
1483 if (colnames[0] ==
"DetectorID")
1485 else if (colnames[0] ==
"Spectrum")
1489 errss <<
"First column must be either DetectorID or Spectrum. " << colnames[0] <<
" is not supported. ";
1490 throw runtime_error(errss.str());
1495 map<detid_t, double> toffactormap;
1496 map<detid_t, double> tofshiftmap;
1498 for (
size_t i = 0; i < numrows; ++i) {
1503 double offset_factor;
1504 row >> detid >> offset_factor;
1505 if (offset_factor >= 0 && offset_factor <= 1) {
1507 toffactormap.emplace(detid, offset_factor);
1511 errss <<
"Correction (i.e., offset) equal to " << offset_factor <<
" of row "
1512 <<
"is out of range [0, 1].";
1513 throw runtime_error(errss.str());
1520 tofshiftmap.emplace(detid, shift);
1525 size_t numhist =
m_eventWS->getNumberHistograms();
1526 if (toffactormap.size() > numhist) {
1527 g_log.
warning() <<
"Input correction table workspace has more detectors (" << toffactormap.size()
1528 <<
") than input workspace " <<
m_eventWS->getName() <<
"'s spectra number (" << numhist <<
".\n";
1529 }
else if (toffactormap.size() < numhist) {
1531 errss <<
"Input correction table workspace has more detectors (" << toffactormap.size() <<
") than input workspace "
1532 <<
m_eventWS->getName() <<
"'s spectra number (" << numhist <<
".\n";
1533 throw runtime_error(errss.str());
1539 vector<detid_t> vecDetIDs(numhist, 0);
1541 for (
size_t i = 0; i < numhist; ++i) {
1547 if (detids.size() != 1) {
1550 errss <<
"The assumption is that one spectrum has one and only one "
1552 <<
"Error is found at spectrum " << i <<
". It has " << detids.size() <<
" detectors.";
1553 throw runtime_error(errss.str());
1555 vecDetIDs[i] = *detids.begin();
1559 map<detid_t, double>::iterator fiter;
1560 for (
size_t i = 0; i < numhist; ++i) {
1563 fiter = toffactormap.find(detid);
1564 if (fiter != toffactormap.end())
1568 errss <<
"Detector "
1569 <<
"w/ ID << " << detid <<
" of spectrum " << i <<
" in Eventworkspace " <<
m_eventWS->getName()
1570 <<
" cannot be found in input TOF calibration workspace. ";
1571 throw runtime_error(errss.str());
1574 fiter = tofshiftmap.find(detid);
1575 if (fiter != tofshiftmap.end())
1580 map<detid_t, double>::iterator fiter;
1582 for (fiter = toffactormap.begin(); fiter != toffactormap.end(); ++fiter) {
1583 auto wsindex =
static_cast<size_t>(fiter->first);
1584 if (wsindex < numhist)
1588 errss <<
"Workspace index " << wsindex <<
" is out of range.";
1589 throw runtime_error(errss.str());
1593 for (fiter = tofshiftmap.begin(); fiter != tofshiftmap.end(); ++fiter) {
1594 auto wsindex =
static_cast<size_t>(fiter->first);
1595 if (wsindex < numhist)
1599 errss <<
"Workspace index " << wsindex <<
" is out of range.";
1600 throw runtime_error(errss.str());
1610 const auto startTime = std::chrono::high_resolution_clock::now();
1611 size_t numberOfSpectra =
m_eventWS->getNumberHistograms();
1615 g_log.
debug() <<
"Number of spectra in input/source EventWorkspace = " << numberOfSpectra <<
".\n";
1619 for (int64_t iws = 0; iws < int64_t(numberOfSpectra); ++iws) {
1625 std::map<int, DataObjects::EventList *> outputs;
1628 int index = ws.first;
1629 auto &output_el = ws.second->getSpectrum(iws);
1630 outputs.emplace(
index, &output_el);
1652 progress(0.1 + progressamount,
"Splitting logs");
1654 addTimer(
"filterEventsBySplitters", startTime, std::chrono::high_resolution_clock::now());
1660 size_t numberOfSpectra =
m_eventWS->getNumberHistograms();
1665 g_log.
notice() <<
"Filter by vector splitters: Number of spectra in "
1666 "input/source EventWorkspace = "
1667 << numberOfSpectra <<
".\n";
1671 size_t num_proton_charges =
m_eventWS->run().getProperty(
"proton_charge")->size();
1674 std::stringstream errmsg;
1675 errmsg <<
"It is not proper to split fast event 'By PulseTime'', when "
1679 <<
") than pulse time "
1681 << num_proton_charges <<
")";
1682 throw runtime_error(errmsg.str());
1684 g_log.
warning(
"User should understand the inaccurancy to filter events "
1689 for (int64_t iws = 0; iws < int64_t(numberOfSpectra); ++iws) {
1695 map<int, DataObjects::EventList *> outputs;
1698 int index = ws.first;
1699 auto &output_el = ws.second->getSpectrum(iws);
1700 outputs.emplace(
index, &output_el);
1707 bool printdetail =
false;
1709 printdetail = (iws ==
static_cast<int64_t
>(
m_dbWSIndex));
1713 std::string logmessage;
1732 progress(0.1 + progressamount,
"Splitting logs");
1734 g_log.
notice(
"Splitters in format of Matrixworkspace are not recommended to "
1735 "split sample logs. ");
1740 std::set<int>::iterator target_iter;
1741 int max_target_index = 0;
1743 if (*target_iter > max_target_index)
1744 max_target_index = *target_iter;
1760 split_tsp_vec.clear();
1764 auto split_tsp = std::make_unique<Kernel::TimeSeriesProperty<int>>(
"splitter");
1767 split_tsp->addValue(Types::Core::DateAndTime(
m_runStartTime), 0);
1768 split_tsp_vec.emplace_back(std::move(split_tsp));
1790 if (curr_tsp->
size() != 1) {
1791 std::stringstream
error;
1792 error <<
"Splitter TSP for target workspace " << itarget <<
" must have 1 and only 1 entry "
1793 <<
"if there is a splitter right at its run start time.";
1794 throw std::runtime_error(
error.str());
1798 std::stringstream
error;
1799 error <<
"Splitter TSP for target workspace " << itarget <<
" must have 1 and only 1 entry "
1800 <<
"with value as 0 but not " << curr_tsp->
firstValue() <<
" if there is a splitter "
1801 <<
"right at its run start time.";
1802 throw std::runtime_error(
error.str());
1826 split_tsp_vec.clear();
1833 throw std::runtime_error(
"Maximum target index cannot be negative.");
1837 auto split_tsp = std::make_unique<Kernel::TimeSeriesProperty<int>>(
"splitter");
1839 split_tsp_vec.emplace_back(std::move(split_tsp));
1843 int itarget = splitter.index();
1844 if (itarget >=
static_cast<int>(split_tsp_vec.size()))
1845 throw std::runtime_error(
"Target workspace index is out of range!");
1849 if (split_tsp_vec[itarget]->size() != 1) {
1850 throw std::runtime_error(
"Splitter must have 1 value with initialization.");
1852 split_tsp_vec[itarget]->clear();
1854 split_tsp_vec[itarget]->addValue(splitter.start(), 1);
1855 split_tsp_vec[itarget]->addValue(splitter.stop(), 0);
1867 g_log.
debug() <<
"There are " << split_tsp_vec.size() <<
" TimeSeriesPropeties.\n"
1871 g_log.
warning() <<
"Number of Splitter vector (" << split_tsp_vec.size()
1876 for (
int itarget = 0; itarget < static_cast<int>(split_tsp_vec.size()); ++itarget) {
1878 std::map<int, DataObjects::EventWorkspace_sptr>::iterator ws_iter;
1883 g_log.
warning() <<
"iTarget " << itarget <<
" does not have any workspace associated.\n";
1895 outws->mutableRun().addProperty(duration_property,
true);
1898 outws->mutableRun().addProperty(std::move(split_tsp_vec[itarget]),
true);
1912 std::vector<int> split_values = splitter_tsp->valuesAsVector();
1913 std::vector<DateAndTime> split_time = splitter_tsp->timesAsVector();
1915 double duration = 0.;
1916 for (
size_t i = 0; i < split_values.size() - 1; ++i) {
1919 if (split_values[i] == 1) {
1921 double sub_duration =
1922 1.E-9 *
static_cast<double>(split_time[i + 1].totalNanoseconds() - split_time[i].totalNanoseconds());
1924 duration += sub_duration;
1935 std::vector<std::string> lognames;
1937 const std::vector<Kernel::Property *> allprop =
m_eventWS->mutableRun().getProperties();
1938 for (
auto ip : allprop) {
1945 if (dbltimeprop || inttimeprop || booltimeprop) {
1946 const std::string &pname = ip->
name();
1947 lognames.emplace_back(pname);
#define DECLARE_ALGORITHM(classname)
const uint32_t UNDEFINED_SPLITTING_TARGET(0)
(integer) splitting target for undefined region, which will be recorded in m_splitterGroup
const int64_t TOLERANCE(1000000)
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_FOR_NO_WSP_CHECK()
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void splitByTime(std::vector< Kernel::SplittingInterval > &, std::vector< Kernel::PropertyManager * >) const override
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
void addTimer(const std::string &name, const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end)
The Analysis data service stores instances of the Workspace objects and anything that derives from te...
const std::set< detid_t > & getDetectorIDs() const
Get a const reference to the detector IDs set.
TableRow represents a row in a TableWorkspace.
std::string & String(size_t col)
Returns a reference to the element in position col if its type is std::string.
int & Int(size_t col)
Returns a reference to the element in position col if its type is int.
A property class for workspaces.
FilterEvents : Filter Events in EventWorkspace to multiple EventsWorkspace by Splitters.
std::vector< std::string > m_wsNames
bool m_isSplittersRelativeTime
void processAlgorithmProperties()
Process user input properties.
DataObjects::SplittersWorkspace_sptr m_splittersWorkspace
std::vector< std::string > getTimeSeriesLogNames()
get the names of all the time series properties in the input workspace's Run object
std::vector< double > m_detTofOffsets
void generateSplitterTSPalpha(std::vector< std::unique_ptr< Kernel::TimeSeriesProperty< int > > > &split_tsp_vec)
Generate the splitter's time series property (log) the splitters workspace.
Kernel::TimeSplitterType m_splitters
void processSplittersWorkspace()
process splitters given by a SplittersWorkspace
void mapSplitterTSPtoWorkspaces(std::vector< std::unique_ptr< Kernel::TimeSeriesProperty< int > > > &split_tsp_vec)
Add time series property 'Splitter' to each child workspace.
std::vector< bool > m_vecSkip
Vector for skip information.
void createOutputWorkspacesSplitters()
create output workspaces if the splitters are given in SplittersWorkspace
std::map< int, std::string > m_wsGroupIndexTargetMap
void splitTimeSeriesProperty(Kernel::TimeSeriesProperty< TYPE > *tsp, std::vector< Types::Core::DateAndTime > &split_datetime_vec, const int max_target_index)
split one single time-series property (template)
std::vector< double > m_detTofFactors
bool m_useArbTableSplitters
Types::Core::DateAndTime m_filterStartTime
TimeAtSampleStrategy * setupIndirectTOFCorrection() const
Set up detector calibration parameters for indirect inelastic scattering instrument.
bool m_toGroupWS
Flag to group workspace.
void filterEventsBySplitters(double progressamount)
Filter events by splitters in format of Splitter.
bool m_useDBSpectrum
Debug.
std::set< int > m_targetWorkspaceIndexSet
std::map< int, DataObjects::EventWorkspace_sptr > m_outputWorkspacesMap
void examineAndSortEventWS()
Examine workspace.
std::map< std::string, int > m_targetIndexMap
TableWorkspace splitters: from target map to vector workspace group-index These 2 maps are compliment...
std::map< int, uint32_t > m_yIndexMap
MatrixWorkspace splitters:
void copyNoneSplitLogs(std::vector< Kernel::TimeSeriesProperty< int > * > &int_tsp_name_vector, std::vector< Kernel::TimeSeriesProperty< double > * > &dbl_tsp_name_vector, std::vector< Kernel::TimeSeriesProperty< bool > * > &bool_tsp_name_vector, std::vector< Kernel::TimeSeriesProperty< std::string > * > &string_tsp_vector)
Clone the sample logs that will not be split, including single-value and add all the TimeSeriesProper...
void generateSplitterTSP(std::vector< std::unique_ptr< Kernel::TimeSeriesProperty< int > > > &split_tsp_vec)
Generate a vector of integer time series property for each splitter corresponding to each target (in ...
void exec() override
Execution body.
std::vector< int > m_vecSplitterGroup
Vector for splitting group.
void splitTimeSeriesLogs(const std::vector< Kernel::TimeSeriesProperty< int > * > &int_tsp_vector, const std::vector< Kernel::TimeSeriesProperty< double > * > &dbl_tsp_vector, const std::vector< Kernel::TimeSeriesProperty< bool > * > &bool_tsp_vector, const std::vector< Kernel::TimeSeriesProperty< std::string > * > &string_tsp_vector)
Split ALL the TimeSeriesProperty sample logs to all the output workspace.
void groupOutputWorkspace()
group output workspaces
void setupDetectorTOFCalibration()
Set up detector calibration parameters.
void setupCustomizedTOFCorrection()
Set up detector calibration parameters from customized values.
std::string m_outputWSNameBase
Base of output workspace's name.
void createOutputWorkspacesTableSplitterCase()
create output workspaces in the case of using TableWorlspace for splitters
void createOutputWorkspacesMatrixCase()
create output workspaces in the case of using MatrixWorkspace for splitters
void processMatrixSplitterWorkspace()
process splitters given by a MatrixWorkspace
void filterEventsByVectorSplitters(double progressamount)
Filter events by splitters in format of vector.
@ EventFilterSkipNoDetTOFCorr
EVENTFILTERSKIP m_specSkipType
Spectrum skip type.
API::MatrixWorkspace_const_sptr m_matrixSplitterWS
std::vector< int64_t > m_vecSplitterTime
Vector for splitting time FIXME - shall we convert this to DateAndTime???.
std::map< uint32_t, int > m_wsGroupdYMap
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
DataObjects::TableWorkspace_sptr m_informationWS
TOFCorrectionType m_tofCorrType
TOF detector/sample correction type.
TimeAtSampleStrategy * setupElasticTOFCorrection() const
Set up detector calibration parameters for elastic scattering instrument.
Types::Core::DateAndTime m_runStartTime
DataObjects::TableWorkspace_sptr m_detCorrectWorkspace
DataObjects::EventWorkspace_sptr m_eventWS
bool m_useSplittersWorkspace
Flag to use matrix splitters or table splitters.
bool m_splitSampleLogs
Flag to split sample logs.
DataObjects::TableWorkspace_sptr m_splitterTableWorkspace
TimeAtSampleStrategy * setupDirectTOFCorrection() const
Set up detector calibration parmaeters for direct inelastic scattering instrument.
double calculate_duration(std::unique_ptr< Kernel::TimeSeriesProperty< int > > &splitter_tsp)
calculate split-workspace's duration according to splitter time series property
void convertSplittersWorkspaceToVectors()
Convert SplittersWorkspace to vector of time and vector of target (itarget)
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
void init() override
Declare Inputs.
void processTableSplittersWorkspace()
process the input splitters given by a TableWorkspace The method will transfer the start/stop time to...
TimeAtSampleStrategyDirect : Determine the Time at Sample corrections for a Direct Geometry instrumen...
TimeAtSampleStrategyElastic : Time at sample stragegy for elastic scattering.
TimeAtSampleStrategyIndirect : Determine Time At Sample for an indirect instrument setup.
TimeAtSampleStrategy : Strategy (technique dependent) for determining Time At Sample.
std::size_t getNumberEvents() const override
Return the number of events in the list.
void splitByFullTime(Kernel::TimeSplitterType &splitter, std::map< int, EventList * > outputs, bool docorrection, double toffactor, double tofshift) const
Split the event list into n outputs by event's full time (tof + pulse time)
void splitByPulseTime(Kernel::TimeSplitterType &splitter, std::map< int, EventList * > outputs) const
Split events by pulse time.
std::string splitByFullTimeMatrixSplitter(const std::vector< int64_t > &vec_splitters_time, const std::vector< int > &vecgroups, std::map< int, EventList * > vec_outputEventList, bool docorrection, double toffactor, double tofshift) const
Split ...
Class to represent a particular goniometer setting, which is described by the rotation matrix.
Support for a property that holds an array of values.
std::shared_ptr< T > retrieve(const std::string &name) const
Get a shared pointer to a stored data object.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
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.
The concrete, templated class for properties.
virtual const std::string & units() const
Returns the units of the property, if any, as a string.
const std::string & name() const
Get the property's name.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class holding a start/end time and a destination for splitting event lists and logs.
Types::Core::DateAndTime stop() const
Return the stop time.
int index() const
Return the index (destination of this split time block)
Types::Core::DateAndTime start() const
Return the start time.
A specialised Property class for holding a series of time-value pairs.
int size() const override
Returns the number of values at UNIQUE time intervals in the time series.
Types::Core::DateAndTime firstTime() const
Returns the first time regardless of filter.
TYPE firstValue() const
Returns the first value regardless of filter.
void addValue(const Types::Core::DateAndTime &time, const TYPE &value)
Add a value to the map using a DateAndTime object.
void clear() override
Deletes the series of values in the property.
void splitByTimeVector(const std::vector< Types::Core::DateAndTime > &splitter_time_vec, const std::vector< int > &target_vec, const std::vector< TimeSeriesProperty * > &outputs)
New split method.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const Workspace > Workspace_const_sptr
shared pointer to Mantid::API::Workspace (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< const TableWorkspace > TableWorkspace_const_sptr
shared pointer to Mantid::DataObjects::TableWorkspace (const version)
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
MANTID_KERNEL_DLL std::string removeSpace(const std::string &CLine)
strip all spaces
int convert(const std::string &A, T &out)
Convert a string into a number.
Helper class which provides the Collimation Length for SANS instruments.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
int32_t detid_t
Typedef for a detector ID.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
The Correction struct to be applied as factor * TOF + offset offset:: TOF offset in unit of TOF facto...
@ Input
An input workspace.
@ Output
An output workspace.