26#include <Poco/TemporaryFile.h>
35using Mantid::Types::Core::DateAndTime;
43 "Input table workspace for data.");
46 "Input matrix workspace containing sample logs. "
47 "It can be the RunInfoWorkspace output from LoadSpiceAscii. "
48 "It serves as parent workspace in the algorithm.");
50 declareProperty(
"RunStart",
"",
51 "User specified run start time of the experiment "
52 "in case that the run start time is not specified in the "
53 "input RunInfoWorkspace.");
56 std::array<std::string, 1> allowedinstruments = {{
"HB2A"}};
57 auto instrumentvalidator = std::make_shared<ListValidator<std::string>>(allowedinstruments);
58 declareProperty(
"Instrument",
"HB2A", instrumentvalidator,
"Instrument to be loaded. ");
60 declareProperty(
"DetectorPrefix",
"anode",
"Prefix of the name for detectors. ");
62 declareProperty(
"RunNumberName",
"Pt.",
"Log name for run number/measurement point.");
64 declareProperty(
"RotationAngleLogName",
"2theta",
"Log name for rotation angle as the 2theta value of detector 0.");
66 declareProperty(
"MonitorCountsLogName",
"monitor",
"Name of the sample log to record monitor counts of each run.");
68 declareProperty(
"DurationLogName",
"time",
"Name of the sample log to record the duration of each run.");
71 "Name to use for the output workspace.");
75 "Name to use for the output workspace.");
79 "Name of a table workspace containing the detectors' efficiency.");
91 std::map<detid_t, double> detEffMap;
97 DateAndTime runstart(1000000000);
98 bool hasrunstartset =
false;
99 if (parentWS->run().hasProperty(
"run_start")) {
101 std::string runstartstr = parentWS->run().getProperty(
"run_start")->value();
103 DateAndTime temprunstart(runstartstr);
104 runstart = temprunstart;
105 hasrunstartset =
true;
107 g_log.
warning() <<
"run_start from info matrix workspace is not correct. "
108 <<
"It cannot be convert from '" << runstartstr <<
"'."
114 if (!hasrunstartset) {
118 DateAndTime temprunstart(runstartstr);
119 runstart = temprunstart;
120 hasrunstartset =
true;
122 g_log.
warning() <<
"RunStart from input property is not correct. "
123 <<
"It cannot be convert from '" << runstartstr <<
"'."
129 g_log.
warning(
"Run-start time is not defined either in "
130 "input parent workspace or given by user. 1990-01-01 "
134 std::map<std::string, std::vector<double>> logvecmap;
135 std::vector<Types::Core::DateAndTime> vectimes;
140 for (
size_t i = 0; i < 3; ++i) {
145 std::vector<MatrixWorkspace_sptr> vec_ws2d =
149 if (!detEffMap.empty())
154 for (
size_t d = 0;
d < 3; ++
d) {
167 g_log.
debug(
"About to converting to workspaces done!");
169 std::string monitorlogname =
getProperty(
"MonitorCountsLogName");
180 setProperty(
"OutputMonitorWorkspace", mdMonitorWS);
195 Types::Core::DateAndTime runstart, std::map<std::string, std::vector<double>> &logvecmap,
196 std::vector<Types::Core::DateAndTime> &vectimes) {
198 size_t ipt, irotangle, itime;
199 std::vector<std::pair<size_t, size_t>> anodelist;
200 std::map<std::string, size_t> sampleindexlist;
201 readTableInfo(tablews, ipt, irotangle, itime, anodelist, sampleindexlist);
205 size_t numws = tablews->rowCount();
206 std::vector<MatrixWorkspace_sptr> vecws(numws);
208 vectimes.resize(numws);
209 for (
size_t irow = 0; irow < numws; ++irow) {
210 vecws[irow] =
loadRunToMatrixWS(tablews, irow, parentws, runstart, ipt, irotangle, itime, anodelist, duration);
211 vectimes[irow] = runstart;
212 runstart +=
static_cast<int64_t
>(duration * 1.0E9);
219 g_log.
debug() <<
"Number of matrix workspaces in vector = " << vecws.size() <<
"\n";
231 const std::map<std::string, size_t> &indexlist,
232 std::map<std::string, std::vector<double>> &logvecmap) {
233 size_t numrows = tablews->rowCount();
235 std::map<std::string, size_t>::const_iterator indexiter;
236 for (indexiter = indexlist.begin(); indexiter != indexlist.end(); ++indexiter) {
237 std::string logname = indexiter->first;
238 size_t icol = indexiter->second;
240 g_log.
debug() <<
" Parsing log " << logname <<
"\n";
242 std::vector<double> logvec(numrows);
243 for (
size_t ir = 0; ir < numrows; ++ir) {
244 auto dbltemp = tablews->cell_cast<
double>(ir, icol);
245 logvec[ir] = dbltemp;
248 logvecmap.emplace(logname, logvec);
268 Types::Core::DateAndTime runstart,
size_t ipt,
size_t irotangle,
size_t itime,
269 const std::vector<std::pair<size_t, size_t>> &anodelist,
double &duration) {
274 double twotheta = tablews->cell<
double>(irow, irotangle);
277 prop2theta->addValue(runstart, twotheta);
278 tempws->mutableRun().addProperty(prop2theta);
281 proprunstart->
addValue(runstart, runstart.toISO8601String());
283 g_log.
debug() <<
"Run " << irow <<
": set run start to " << runstart.toISO8601String() <<
"\n";
284 if (tempws->run().hasProperty(
"run_start")) {
286 << tempws->run().getProperty(
"run_start")->value()
287 <<
". It will be replaced by the correct value. "
289 tempws->mutableRun().removeProperty(
"run_start");
291 tempws->mutableRun().addProperty(proprunstart);
293 int pt = tablews->cell<
int>(irow, ipt);
298 instloader->initialize();
301 instloader->setProperty(
"Workspace", tempws);
302 instloader->execute();
304 tempws = instloader->getProperty(
"Workspace");
307 const auto &specInfo = tempws->spectrumInfo();
309 const auto &pos = specInfo.position(i);
310 tempws->mutableX(i)[0] = pos[0] + 0.01;
311 double yvalue = tablews->cell<
double>(irow, anodelist[i].second);
312 tempws->mutableY(i)[0] = yvalue;
313 tempws->mutableE(i)[0] = std::max(sqrt(yvalue), 1.0);
315 for (
size_t d = 0;
d < 3; ++
d) {
324 duration = tablews->cell<
double>(irow, itime);
340 size_t &irotangle,
size_t &itime,
341 std::vector<std::pair<size_t, size_t>> &anodelist,
342 std::map<std::string, size_t> &samplenameindexmap) {
345 std::string anodelogprefix =
getProperty(
"DetectorPrefix");
346 const std::vector<std::string> &colnames = tablews->getColumnNames();
347 for (
size_t icol = 0; icol < colnames.size(); ++icol) {
348 const std::string &colname = colnames[icol];
350 if (boost::starts_with(colname, anodelogprefix)) {
352 std::vector<std::string> terms;
353 boost::split(terms, colname, boost::is_any_of(anodelogprefix));
354 auto anodeid =
static_cast<size_t>(std::stoi(terms.back()));
355 anodelist.emplace_back(anodeid, icol);
357 samplenameindexmap.emplace(colname, icol);
362 if (anodelist.empty()) {
363 std::stringstream errss;
364 errss <<
"There is no log name starting with " << anodelogprefix <<
" for detector. ";
365 throw std::runtime_error(errss.str());
369 std::map<std::string, size_t>::iterator mapiter;
372 std::string monitorlogname =
getProperty(
"MonitorCountsLogName");
373 std::string durationlogname =
getProperty(
"DurationLogName");
374 std::string rotanglelogname =
getProperty(
"RotationAngleLogName");
376 std::vector<std::string> lognames{ptname, monitorlogname, durationlogname, rotanglelogname};
378 std::vector<size_t> ilognames(lognames.size());
380 for (
size_t i = 0; i < lognames.size(); ++i) {
381 const std::string &logname = lognames[i];
382 mapiter = samplenameindexmap.find(logname);
383 if (mapiter != samplenameindexmap.end()) {
384 ilognames[i] = mapiter->second;
386 std::stringstream ess;
387 ess <<
"Essential log name " << logname <<
" cannot be found in data table workspace.";
388 throw std::runtime_error(ess.str());
394 itime = ilognames[2];
395 irotangle = ilognames[3];
398 std::sort(anodelist.begin(), anodelist.end());
409 const std::map<std::string, std::vector<double>> &logvecmap,
410 const std::vector<Types::Core::DateAndTime> &vectimes) {
412 size_t numexpinfo = mdws->getNumExperimentInfo();
414 throw std::runtime_error(
"There is no ExperimentInfo defined for MDWorkspace. "
415 "It is impossible to add any log!");
416 else if (numexpinfo != vectimes.size() + 1)
417 throw std::runtime_error(
"The number of ExperimentInfo should be 1 more than "
418 "the length of vector of time, i.e., number of matrix workspaces.");
420 std::map<std::string, std::vector<double>>::const_iterator miter;
423 std::string runnumlogname =
getProperty(
"RunNumberName");
424 miter = logvecmap.find(runnumlogname);
425 if (miter == logvecmap.end())
426 throw std::runtime_error(
"Impossible not to find Pt. in log vec map.");
427 const std::vector<double> &vecrunno = miter->second;
430 for (
size_t i = 0; i < vectimes.size(); ++i) {
431 Types::Core::DateAndTime runstart = vectimes[i];
432 mdws->getExperimentInfo(
static_cast<uint16_t
>(i))
436 mdws->getExperimentInfo(
static_cast<uint16_t
>(vectimes.size()))
442 ExperimentInfo_sptr eilast = mdws->getExperimentInfo(
static_cast<uint16_t
>(numexpinfo - 1));
444 for (miter = logvecmap.begin(); miter != logvecmap.end(); ++miter) {
445 std::string logname = miter->first;
446 const std::vector<double> &veclogval = miter->second;
449 if (veclogval.size() != vectimes.size()) {
450 g_log.
error() <<
"Log " << logname <<
" has different number of log values (" << veclogval.size()
451 <<
") than number of log entry time (" << vectimes.size() <<
")"
457 for (uint16_t i = 0; i < static_cast<uint16_t>(veclogval.size()); ++i) {
461 int runnumber = std::stoi(tmpei->run().getProperty(
"run_number")->value());
462 if (runnumber !=
static_cast<int>(vecrunno[i]))
463 throw std::runtime_error(
"Run number does not match to Pt. value.");
470 templog->addValues(vectimes, veclogval);
473 eilast->mutableRun().addLogData(templog);
484 const std::vector<API::MatrixWorkspace_sptr> &vec_ws2d) {
486 for (
const auto &ws2d : vec_ws2d) {
490 tmp_expinfo->setInstrument(tmp_inst);
492 int runnumber = std::stoi(ws2d->run().getProperty(
"run_number")->value());
496 mdws->addExperimentInfo(tmp_expinfo);
502 mdws->addExperimentInfo(combine_expinfo);
519 std::vector<std::string> vec_ID(3);
524 std::vector<std::string> vec_name(3);
534 std::string
id = vec_ID[i];
535 std::string
name = vec_name[i];
537 for (
size_t d = 0;
d < 3; ++
d)
546 std::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(outWs);
550 for (
const auto &thisWorkspace : vec_ws2d) {
551 uint16_t runnumber =
static_cast<uint16_t
>(std::stoi(thisWorkspace->run().getProperty(
"run_number")->value()));
555 size_t nHist = thisWorkspace->getNumberHistograms();
556 const auto &specInfo = thisWorkspace->spectrumInfo();
557 for (std::size_t i = 0; i < nHist; ++i) {
558 const auto &vecsignal = thisWorkspace->y(i);
559 const auto &vecerror = thisWorkspace->e(i);
560 auto signal =
static_cast<float>(vecsignal[0]);
561 auto error =
static_cast<float>(vecerror[0]);
562 detid_t detid = specInfo.detector(i).getID() + detindex;
563 const auto &detPos = specInfo.position(i);
565 data[0] =
static_cast<float>(detPos.X());
566 data[1] =
static_cast<float>(detPos.Y());
567 data[2] =
static_cast<float>(detPos.Z());
568 inserter.insertMDEvent(signal,
error *
error, runnumber, 0, detid, data);
584 const std::vector<double> &vecmonitor) {
590 std::vector<std::string> vec_ID(3);
595 std::vector<std::string> vec_name(3);
605 std::string
id = vec_ID[i];
606 std::string
name = vec_name[i];
615 std::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(outWs);
619 for (
size_t iws = 0; iws < vec_ws2d.size(); ++iws) {
621 short unsigned int runnumber =
622 static_cast<short unsigned int>(std::stoi(thisWorkspace->run().getProperty(
"run_number")->value()));
625 auto signal =
static_cast<float>(vecmonitor[iws]);
628 error = std::sqrt(signal);
630 size_t nHist = thisWorkspace->getNumberHistograms();
631 const auto &specInfo = thisWorkspace->spectrumInfo();
632 for (std::size_t i = 0; i < nHist; ++i) {
634 detid_t detid = specInfo.detector(i).getID() + detindex;
635 const auto &detPos = specInfo.position(i);
637 data[0] =
static_cast<float>(detPos.X());
638 data[1] =
static_cast<float>(detPos.Y());
639 data[2] =
static_cast<float>(detPos.Z());
640 inserter.insertMDEvent(signal,
error *
error, runnumber, 0, detid, data);
653std::map<detid_t, double>
655 std::map<detid_t, double> deteffmap;
658 size_t numcols = detefftablews->columnCount();
660 throw std::runtime_error(
"Input tableworkspace must have 2 and only 2 columns.");
663 size_t numrows = detefftablews->rowCount();
664 for (
size_t i = 0; i < numrows; ++i) {
666 double deteff = detefftablews->cell<
double>(i, 1);
667 deteffmap.emplace(detid, deteff);
680 const std::map<detid_t, double> &detEffMap) {
681 std::vector<MatrixWorkspace_sptr>::iterator it;
682 std::map<detid_t, double>::const_iterator detiter;
683 for (it = vec_ws2d.begin(); it != vec_ws2d.end(); ++it) {
685 const auto &specInfo = ws->spectrumInfo();
686 size_t numspec = ws->getNumberHistograms();
687 for (
size_t iws = 0; iws < numspec; ++iws) {
688 detid_t detid = specInfo.detector(iws).getID();
689 detiter = detEffMap.find(detid);
690 if (detiter != detEffMap.end())
691 ws->mutableY(iws)[0] /= detiter->second;
#define DECLARE_ALGORITHM(classname)
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.
A property class for workspaces.
static API::IMDEventWorkspace_sptr CreateMDWorkspace(size_t nd, const std::string &eventType="MDLeanEvent", const Mantid::API::MDNormalization &preferredNormalization=Mantid::API::MDNormalization::VolumeNormalization, const Mantid::API::MDNormalization &preferredNormalizationHisto=Mantid::API::MDNormalization::VolumeNormalization)
Create a MDEventWorkspace of the given type.
MDEventInserter : Helper class that provides a generic interface for adding events to an MDWorkspace ...
Templated class for the multi-dimensional event workspace.
GeneralFrame : Any MDFrame that isn't related to momemtum transfer.
static const std::string GeneralFrameDistance
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug 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.
OptionalBool : Tri-state bool.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
A specialised Property class for holding a series of time-value pairs.
void addValue(const Types::Core::DateAndTime &time, const TYPE &value)
Add a value to the map using a DateAndTime object.
ConvertSpiceDataToRealSpace : Convert data from SPICE file to singals in real space contained in MDEv...
void addExperimentInfos(const API::IMDEventWorkspace_sptr &mdws, const std::vector< API::MatrixWorkspace_sptr > &vec_ws2d)
Append Experiment Info.
size_t m_nDimensions
Dimension of the output MDEventWorkspace.
void readTableInfo(const DataObjects::TableWorkspace_const_sptr &tablews, size_t &ipt, size_t &irotangle, size_t &itime, std::vector< std::pair< size_t, size_t > > &anodelist, std::map< std::string, size_t > &samplenameindexmap)
Read parameter information from table workspace.
std::vector< double > m_extentMaxs
x-y-z value maximum
API::MatrixWorkspace_sptr loadRunToMatrixWS(const DataObjects::TableWorkspace_sptr &tablews, size_t irow, const API::MatrixWorkspace_const_sptr &parentws, Types::Core::DateAndTime runstart, size_t ipt, size_t irotangle, size_t itime, const std::vector< std::pair< size_t, size_t > > &anodelist, double &duration)
Load one run (one pt.) to a matrix workspace.
const std::string name() const override
Algorithm's name.
void appendSampleLogs(const API::IMDEventWorkspace_sptr &mdws, const std::map< std::string, std::vector< double > > &logvecmap, const std::vector< Types::Core::DateAndTime > &vectimes)
Append sample logs to MD workspace.
void correctByDetectorEfficiency(std::vector< API::MatrixWorkspace_sptr > vec_ws2d, const std::map< detid_t, double > &detEffMap)
Apply the detector's efficiency correction to.
std::vector< API::MatrixWorkspace_sptr > convertToMatrixWorkspace(const DataObjects::TableWorkspace_sptr &tablews, const API::MatrixWorkspace_const_sptr &parentws, Types::Core::DateAndTime runstart, std::map< std::string, std::vector< double > > &logvecmap, std::vector< Types::Core::DateAndTime > &vectimes)
Parse data table workspace to a vector of matrix workspaces.
void parseSampleLogs(const DataObjects::TableWorkspace_sptr &tablews, const std::map< std::string, size_t > &indexlist, std::map< std::string, std::vector< double > > &logvecmap)
Return sample logs.
API::IMDEventWorkspace_sptr createMonitorMDWorkspace(const std::vector< API::MatrixWorkspace_sptr > &vec_ws2d, const std::vector< double > &vecmonitor)
Create an MDWorkspace for monitor counts.
size_t m_numSpec
Number of detectors.
std::map< detid_t, double > parseDetectorEfficiencyTable(const DataObjects::TableWorkspace_sptr &detefftablews)
Parse detector efficiency table workspace to map.
std::string m_instrumentName
Name of instrument.
void exec() override
Execution code.
API::IMDEventWorkspace_sptr createDataMDWorkspace(const std::vector< API::MatrixWorkspace_sptr > &vec_ws2d)
Create an MDEventWorspace by converting vector of matrix workspace data.
std::vector< size_t > m_numBins
Number of bins.
std::vector< double > m_extentMins
x-y-z-value minimum
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
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
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< const TableWorkspace > TableWorkspace_const_sptr
shared pointer to Mantid::DataObjects::TableWorkspace (const version)
std::shared_ptr< MDHistoDimension > MDHistoDimension_sptr
Shared pointer to a MDHistoDimension.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
int32_t detid_t
Typedef for a detector ID.
@ Input
An input workspace.
@ Output
An output workspace.