35 "Name of the input data MDEventWorkspace from which the raw "
36 "values are retrieved.");
39 "Name of the input monitor MDEventWorkspace paired with "
40 "input data workspace. ");
43 "Name of the output MatrixWorkspace containing the raw data required.");
45 std::array<std::string, 3> vecmode = {{
"Pt.",
"Detector",
"Sample Log"}};
46 auto modevalidator = std::make_shared<ListValidator<std::string>>(vecmode);
47 declareProperty(
"Mode",
"Detector", modevalidator,
48 "Mode selector. (1) Pt.: get the raw detectors' signal of the "
50 "(2) Detector: get one detector's signals along all experiment points; "
51 "(3) Sample Log: get the value of a sample log along all experiment "
54 declareProperty(
"XLabel",
"",
55 "Label for the X-values of the output MatrixWorkspace. "
56 "For mode 'Pt.', it won't take value. The output of X-axis is always "
58 "For mode 'Detector', if it is left blank, "
59 "the default then will be 2-theta value of detector's position. "
60 "For mode 'Sample Log', the default value is 'Pt.'. "
61 "In the later 2 modes, XLabel can be any supported sample log's name.");
64 "Experiment point number (i.e., run_number in MDEventWorkspace "
65 "of the detectors' counts to be exported. "
66 "It is used in mode 'Pt.' only. ");
68 declareProperty(
"DetectorID",
EMPTY_INT(),
69 "Detector ID of the detector whose raw counts "
70 "will be exported for all experiment points."
71 "It is used in mode 'Detector' only. ");
73 declareProperty(
"SampleLogName",
"",
74 "Name of the sample log whose value to be exported. "
75 "It is used in mode 'Sample Log' only. ");
77 declareProperty(
"NormalizeByMonitorCounts",
true,
78 "If specified as true, all the output detectors' counts will "
79 "be normalized by their monitor counts. ");
90 bool donormalize =
getProperty(
"NormalizeByMonitorCounts");
94 std::vector<double> vecX;
95 std::vector<double> vecY;
101 throw std::runtime_error(
"For 'Pt.', value of 'Pt.' must be specified.");
102 exportDetCountsOfRun(datamdws, monitormdws, runnumber, vecX, vecY, xlabel, ylabel, donormalize);
103 }
else if (mode ==
"Detector") {
106 throw std::runtime_error(
"For mode 'Detector', value of 'DetectorID' must be specified.");
108 }
else if (mode ==
"Sample Log") {
109 std::string samplelogname =
getProperty(
"SampleLogName");
110 if (samplelogname.empty())
111 throw std::runtime_error(
"For mode 'Sample Log', value of 'SampleLogName' must be specified.");
115 std::stringstream ess;
116 ess <<
"Mode " << mode <<
" is not supported.";
117 throw std::runtime_error(ess.str());
139 const int runnumber, std::vector<double> &vecX,
140 std::vector<double> &vecY, std::string &xlabel,
141 std::string &ylabel,
bool donormalize) {
143 std::vector<double> vec2theta;
144 std::vector<double> vecDetCounts;
146 getDetCounts(datamdws, runnumber, detid, vec2theta, vecDetCounts,
true);
147 if (vec2theta.size() != vecDetCounts.size())
148 throw std::runtime_error(
"Logic error! Vector of 2theta must have same size as "
149 "vector of detectors' counts.");
152 std::vector<double> vec2thetaMon;
153 std::vector<double> vecMonitorCounts;
156 getDetCounts(monitormdws, runnumber, detid, vec2thetaMon, vecMonitorCounts,
false);
158 if (vecDetCounts.size() != vecMonitorCounts.size())
159 throw std::runtime_error(
"Number of detectors' counts' is different from that of "
162 for (
size_t i = 0; i < vecDetCounts.size(); ++i)
163 if (vecMonitorCounts[i] > 1.0E-9)
164 vecDetCounts[i] = vecDetCounts[i] / vecMonitorCounts[i];
166 vecDetCounts[i] = 0.;
170 const size_t numdets = vecDetCounts.size();
171 std::vector<std::pair<double, double>> vecPair(numdets);
172 for (
size_t i = 0; i < numdets; ++i) {
173 vecPair[i] = std::make_pair(vec2theta[i], vecDetCounts[i]);
175 std::sort(vecPair.begin(), vecPair.end());
178 vecX.resize(numdets);
179 vecY.resize(numdets);
180 for (
size_t i = 0; i < numdets; ++i) {
181 vecX[i] = vecPair[i].first;
182 vecY[i] = vecPair[i].second;
188 ylabel =
"Noramlized Intensity";
207 const int detid, std::vector<double> &vecX,
208 std::vector<double> &vecY, std::string &xlabel,
209 std::string &ylabel,
const bool &donormalize) {
211 std::vector<double> vecSampleLog;
212 std::vector<double> vecDetCounts;
214 bool get2theta =
false;
215 if (xlabel.empty()) {
219 getDetCounts(datamdws, runnumber, detid, vecSampleLog, vecDetCounts, get2theta);
223 if (vecSampleLog.size() != vecDetCounts.size())
224 throw std::runtime_error(
"Logic error! number of sample logs should be "
225 "same as number of detector's counts.");
228 std::vector<double> vec2thetaMon;
229 std::vector<double> vecMonitorCounts;
233 getDetCounts(monitormdws, runnumber, detid, vec2thetaMon, vecMonitorCounts,
false);
234 if (vecDetCounts.size() != vecMonitorCounts.size())
235 throw std::runtime_error(
"Number of detectors' counts' is different from that of "
238 for (
size_t i = 0; i < vecDetCounts.size(); ++i)
239 if (vecMonitorCounts[i] > 1.0E-9)
240 vecDetCounts[i] = vecDetCounts[i] / vecMonitorCounts[i];
242 vecDetCounts[i] = 0.;
246 const size_t numpts = vecDetCounts.size();
247 std::vector<std::pair<double, double>> vecPair(numpts);
248 for (
size_t i = 0; i < numpts; ++i) {
249 vecPair[i] = std::make_pair(vecSampleLog[i], vecDetCounts[i]);
251 std::sort(vecPair.begin(), vecPair.end());
256 for (
size_t i = 0; i < numpts; ++i) {
257 vecX[i] = vecPair[i].first;
258 vecY[i] = vecPair[i].second;
265 ylabel =
"Noramlized Intensity";
281 const std::string &samplelogname, std::vector<double> &vecX,
282 std::vector<double> &vecY, std::string &xlabel,
283 std::string &ylabel) {
291 ylabel = samplelogname;
294 if (xlabel.empty()) {
300 if (vecX.size() != vecY.size())
301 throw std::runtime_error(
"It is not correct to have two different sizes vectors.");
304 const size_t numpts = vecX.size();
305 std::vector<std::pair<double, double>> vecPair(numpts);
306 for (
size_t i = 0; i < numpts; ++i) {
307 vecPair[i] = std::make_pair(vecX[i], vecY[i]);
309 std::sort(vecPair.begin(), vecPair.end());
314 for (
size_t i = 0; i < numpts; ++i) {
315 vecX[i] = vecPair[i].first;
316 vecY[i] = vecPair[i].second;
333 const int &detid, std::vector<double> &vecX, std::vector<double> &vecY,
336 if (mdws->getNumExperimentInfo() == 0)
337 throw std::runtime_error(
"There is no ExperimentInfo object that has been set to "
338 "input MDEventWorkspace!");
346 samplepos = sample->getPos();
347 g_log.
debug() <<
"Sample position is " << samplepos.
X() <<
", " << samplepos.
Y() <<
", " << samplepos.
Z() <<
"\n";
350 sourcepos = source->getPos();
351 g_log.
debug() <<
"Source position is " << sourcepos.
X() <<
"," << sourcepos.
Y() <<
", " << sourcepos.
Z() <<
"\n";
357 auto mditer = mdws->createIterator();
359 bool scancell =
true;
360 size_t nextindex = 1;
363 size_t numev2 = mditer->getNumEvents();
364 g_log.
debug() <<
"MDWorkspace " << mdws->getName() <<
" Cell " << nextindex - 1 <<
": Number of events = " << numev2
365 <<
" Does NEXT cell exist = " << mditer->next() <<
"\n";
368 for (
size_t iev = 0; iev < numev2; ++iev) {
372 int thisrunnumber = mditer->getInnerExpInfoIndex(iev);
373 if (runnumber >= 0 && thisrunnumber != runnumber)
376 int thisdetid = mditer->getInnerDetectorID(iev);
377 if (detid >= 0 && thisdetid != detid)
382 double tempx = mditer->getInnerPosition(iev, 0);
383 double tempy = mditer->getInnerPosition(iev, 1);
384 double tempz = mditer->getInnerPosition(iev, 2);
388 double twotheta = v_det_sample.
angle(v_sample_src) / M_PI * 180.;
389 vecX.emplace_back(twotheta);
393 double signal = mditer->getInnerSignal(iev);
394 vecY.emplace_back(signal);
398 if (mditer->next()) {
400 mditer->jumpTo(nextindex);
418 const std::string &samplelogname,
const int runnumber,
419 std::vector<double> &vecSampleLog) {
421 vecSampleLog.clear();
424 uint16_t numexpinfo = mdws->getNumExperimentInfo();
425 for (uint16_t iexp = 0; iexp < numexpinfo; ++iexp) {
429 int thisrunnumber = expinfo->getRunNumber();
430 if (thisrunnumber < 0)
434 if (runnumber >= 0 && thisrunnumber != runnumber)
437 if (!expinfo->run().hasProperty(samplelogname)) {
438 std::stringstream ess;
439 ess <<
"Workspace " << mdws->getName() <<
"'s " << iexp
440 <<
"-th ExperimentInfo with "
442 << thisrunnumber <<
" does not have specified property " << samplelogname;
443 throw std::runtime_error(ess.str());
446 double logvalue = expinfo->run().getPropertyAsSingleValue(samplelogname);
447 vecSampleLog.emplace_back(logvalue);
448 g_log.
debug() <<
"Add sample log (" << samplelogname <<
") " << logvalue <<
" of " << iexp <<
"-th ExperimentInfo "
463 const std::vector<double> &vecY,
464 const std::string &xlabel,
465 const std::string &ylabel) {
467 size_t sizex = vecX.size();
468 size_t sizey = vecY.size();
469 if (sizex != sizey || sizex == 0)
470 throw std::runtime_error(
"Unable to create output matrix workspace.");
475 throw std::runtime_error(
"Failed to create output matrix workspace.");
478 outws->setHistogram(0, Points(vecX), Counts(vecY));
479 auto &dataE = outws->mutableE(0);
481 dataE.begin(), dataE.end(), [](
double val) { return val < 1.0; }, 1.0);
484 outws->setYUnitLabel(ylabel);
485 if (!xlabel.empty()) {
487 outws->getAxis(0)->setUnit(xlabel);
490 <<
" for X-axis is not a unit "
#define DECLARE_ALGORITHM(classname)
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A property class for workspaces.
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 information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
double angle(const V3D &) const
Angle between this and another vector.
constexpr double Z() const noexcept
Get z.
GetSpiceDataRawCountsFromMD : Export raw detectors' counts or sample log values from IMDEventWorkspac...
void getSampleLogValues(const API::IMDEventWorkspace_const_sptr &mdws, const std::string &samplelogname, const int runnumber, std::vector< double > &vecSampleLog)
Get sample log values.
void getDetCounts(const API::IMDEventWorkspace_const_sptr &mdws, const int &runnumber, const int &detid, std::vector< double > &vecX, std::vector< double > &vecY, bool formX)
Get detectors' counts.
API::MatrixWorkspace_sptr createOutputWorkspace(const std::vector< double > &vecX, const std::vector< double > &vecY, const std::string &xlabel, const std::string &ylabel)
Create output workspace.
void exportDetCountsOfRun(const API::IMDEventWorkspace_const_sptr &datamdws, const API::IMDEventWorkspace_const_sptr &monitormdws, const int runnumber, std::vector< double > &vecX, std::vector< double > &vecY, std::string &xlabel, std::string &ylabel, bool donormalize)
Export all detectors' counts for a run.
void exportIndividualDetCounts(const API::IMDEventWorkspace_const_sptr &datamdws, const API::IMDEventWorkspace_const_sptr &monitormdws, const int detid, std::vector< double > &vecX, std::vector< double > &vecY, std::string &xlabel, std::string &ylabel, const bool &donormalize)
Export a detector's counts accross all runs.
void exportSampleLogValue(const API::IMDEventWorkspace_const_sptr &datamdws, const std::string &samplelogname, std::vector< double > &vecX, std::vector< double > &vecY, std::string &xlabel, std::string &ylabel)
Export sample log values accross all runs.
void exec() override
Execution code.
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< const IMDEventWorkspace > IMDEventWorkspace_const_sptr
Shared pointer to Mantid::API::IMDEventWorkspace (const version)
std::shared_ptr< const ExperimentInfo > ExperimentInfo_const_sptr
Shared pointer to const ExperimentInfo.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
@ Input
An input workspace.
@ Output
An output workspace.