15#include "MantidHistogramData/Histogram.h"
25using Mantid::Types::Core::DateAndTime;
36 :
API::
Algorithm(), m_dataWS(), mRunStartTime(), mFilterT0(), mFilterTf(), m_intInfoMap(), m_dblInfoMap(),
37 m_log(
nullptr), m_timeVec(), m_valueVec(), m_starttime(), m_endtime(), m_ignoreNegativeTime(false) {}
44 "Input EventWorkspace. Each spectrum corresponds to 1 pixel");
47 "Name of the workspace of log delta T distribution. ");
50 "Name of optional log statistic information output Tableworkspace.");
54 std::vector<std::string> timeoptions{
"Absolute Time (nano second)",
"Relative Time (second)"};
55 declareProperty(
"TimeRangeOption",
"Relative Time (second)", std::make_shared<StringListValidator>(timeoptions),
56 "User defined time range (T0, Tf) is of absolute time (second). ");
59 "Earliest time of the events to be selected. "
60 "It can be absolute time (ns), relative time (second) or percentage.");
62 "Latest time of the events to be selected. "
63 "It can be absolute time (ns), relative time (second) or percentage.");
65 declareProperty(
"TimeStepBinResolution", 0.0001,
"Time resolution (second) for time stamp delta T disibution. ");
68 "If true, then the time interval with negative number will "
69 "be neglected in doing statistic.");
78 throw runtime_error(
"Inputworkspace cannot be parsed to a MatrixWorkspace.");
83 throw runtime_error(
"Input log value cannot be an empty string. ");
88 errmsg <<
"Property " << logname <<
" does not exit in sample of workspace " <<
m_dataWS->getName() <<
".";
90 throw std::invalid_argument(errmsg.str());
95 errmsg <<
"Log " << logname <<
" is found, but is not a double type time series log";
97 throw std::invalid_argument(errmsg.str());
116 double resolution =
getProperty(
"TimeStepBinResolution");
124 double userinputdt = 1 / 240.1;
132 this->
setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<MatrixWorkspace>(timestatws));
151 string timeoption = this->
getProperty(
"TimeRangeOption");
153 if (timeoption ==
"Absolute Time (nano second)")
155 else if (timeoption ==
"Relative Time (second)")
160 double duration =
static_cast<double>(
m_timeVec.back().totalNanoseconds() -
m_timeVec[0].totalNanoseconds()) * 1.0E-9;
180 throw runtime_error(
"Coding error!");
204 throw runtime_error(
"Coding error!");
212 errmsg <<
"User defined filter starting time @ " <<
mFilterT0 <<
" (T = " << t0r
213 <<
") is later than or equal to filer ending time @ " <<
mFilterTf <<
" (T = " << tfr <<
").";
215 throw std::invalid_argument(errmsg.str());
224 DateAndTime temptime(
static_cast<int64_t
>(abstimens));
233 int64_t totaltime =
m_starttime.totalNanoseconds() +
static_cast<int64_t
>(deltatime * 1.0E9);
234 DateAndTime abstime(totaltime);
242 auto tablews = std::make_shared<TableWorkspace>();
244 tablews->addColumn(
"str",
"Name");
245 tablews->addColumn(
"double",
"Value");
249 string name = intmapiter.first;
250 size_t value = intmapiter.second;
252 TableRow newrow = tablews->appendRow();
253 newrow << name << static_cast<double>(
value);
257 map<string, double>::iterator dblmapiter;
259 string name = dblmapiter->first;
260 double value = dblmapiter->second;
262 TableRow newrow = tablews->appendRow();
279 std::string outputdir =
getProperty(
"OutputDirectory");
280 if (!outputdir.empty() && outputdir.back() !=
'/')
283 std::string ofilename = outputdir +
"errordeltatime.txt";
286 ofs.open(ofilename.c_str(), std::ios::out);
288 Types::Core::DateAndTime t0(ws->run().getProperty(
"run_start")->value());
290 for (
size_t i = 1; i < abstimevec.size(); i++) {
292 static_cast<double>(abstimevec[i].totalNanoseconds() - abstimevec[i - 1].totalNanoseconds()) * 1.0E-9;
293 double dev = (tempdts - dts) / dts;
295 if (
fabs(dev) > 0.5) {
296 double deltapulsetimeSec1 =
297 static_cast<double>(abstimevec[i - 1].totalNanoseconds() - t0.totalNanoseconds()) * 1.0E-9;
298 double deltapulsetimeSec2 =
299 static_cast<double>(abstimevec[i].totalNanoseconds() - t0.totalNanoseconds()) * 1.0E-9;
300 auto index1 =
static_cast<int>(deltapulsetimeSec1 * 60);
301 auto index2 =
static_cast<int>(deltapulsetimeSec2 * 60);
303 ofs <<
"Error d(T) = " << tempdts <<
" vs Correct d(T) = " << dts <<
'\n';
304 ofs << index1 <<
"\t\t" << abstimevec[i - 1].totalNanoseconds() <<
"\t\t" << index2 <<
"\t\t"
305 << abstimevec[i].totalNanoseconds() <<
'\n';
321 double dtmin =
static_cast<double>(timevec.back().totalNanoseconds() - timevec[0].totalNanoseconds()) * 1.0E-9;
324 vector<double> vecdt(timevec.size() - 1, 0.0);
325 for (
size_t i = 1; i < timevec.size(); ++i) {
326 vecdt[i - 1] =
static_cast<double>(timevec[i].totalNanoseconds() - timevec[i - 1].totalNanoseconds()) * 1.0E-9;
327 if (vecdt[i - 1] < dtmin)
328 dtmin = vecdt[i - 1];
329 else if (vecdt[i - 1] > dtmax)
330 dtmax = vecdt[i - 1];
336 numbins =
static_cast<size_t>(ceil((dtmax) / stepsize)) + 2;
338 numbins =
static_cast<size_t>(ceil((dtmax - dtmin) / stepsize)) + 2;
341 g_log.
notice() <<
"Distribution has " << numbins <<
" bins. Delta T = (" << dtmin <<
", " << dtmax <<
")\n";
344 auto &vecDeltaT = distws->mutableX(0);
345 auto &vecCount = distws->mutableY(0);
347 double countmin = dtmin;
351 for (
size_t i = 0; i < numbins; ++i)
352 vecDeltaT[i] = countmin + (
static_cast<double>(i) - 1) * stepsize;
353 for (
size_t i = 0; i < numbins; ++i)
357 for (
double dt : vecdt) {
362 auto viter = lower_bound(vecDeltaT.begin(), vecDeltaT.end(), dt);
363 index =
static_cast<int>(viter - vecDeltaT.begin());
364 if (
index >=
static_cast<int>(vecDeltaT.size())) {
366 g_log.
error() <<
"Find index = " <<
index <<
" > vecX.size = " << vecDeltaT.size() <<
".\n";
367 }
else if (dt < vecDeltaT[
index]) {
372 throw runtime_error(
"How can this happen.");
374 vecCount[
index] += 1;
384 size_t countsame = 0;
385 size_t countinverse = 0;
386 for (
size_t i = 1; i <
m_timeVec.size(); i++) {
387 Types::Core::DateAndTime tprev =
m_timeVec[i - 1];
388 Types::Core::DateAndTime tpres =
m_timeVec[i];
391 else if (tprev > tpres)
403 m_intInfoMap.emplace(
"Number of Equal Time Stamps", countsame);
404 m_intInfoMap.emplace(
"Number of Reversed Time Stamps", countinverse);
407 double runduration_sec =
static_cast<double>(
m_endtime.totalNanoseconds() -
m_starttime.totalNanoseconds()) * 1.0E-9;
408 if (runduration_sec < 0.0) {
409 g_log.
warning() <<
"It shows that the run duration is not right. "
410 <<
"Run start = " <<
m_starttime.toFormattedString() <<
"; "
411 <<
"Run End = " <<
m_endtime.toFormattedString() <<
".\n";
413 <<
"Log end time = " <<
m_timeVec.back().toFormattedString() <<
".\n";
416 double sum_deltaT1 = 0.0;
417 double sum_deltaT2 = 0.0;
420 if (runduration_sec > 0)
421 min_dt = runduration_sec;
424 for (
size_t i = 0; i < numpts - 1; ++i) {
426 double dt =
static_cast<double>(dtns) * 1.0E-9;
429 g_log.
warning() <<
"Reversed dT: dt = " << dt <<
" between " <<
m_timeVec[i].toFormattedString() <<
" and "
430 <<
m_timeVec[i + 1].toFormattedString() <<
" @ index = " << i <<
".\n";
434 sum_deltaT2 += dt * dt;
442 double avg_dt = sum_deltaT1 /
static_cast<double>(numpts - 1);
443 double std_dt = sqrt(sum_deltaT2 /
static_cast<double>(numpts - 1) - avg_dt * avg_dt);
503 std::stringstream ss;
504 ss <<
"Alternating Threashold = " <<
delta <<
'\n';
506 size_t numchange = 0;
507 for (
size_t i = 1; i < values.size(); i++) {
508 double tempdelta = values[i] - values[i - 1];
514 ss <<
"@ " << i <<
"\tDelta = " << tempdelta <<
"\t\tTime From " << timevec[i - 1].totalNanoseconds() <<
" to "
515 << timevec[i].totalNanoseconds() <<
'\n';
519 m_intInfoMap.insert(make_pair(
"Number of adjacent time stamp w/o value change", numchange));
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
TableRow represents a row in a TableWorkspace.
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 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.
Base class for properties.
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.
std::vector< TYPE > valuesAsVector() const
Return the time series's values (unfiltered) as a vector<TYPE>
std::vector< Types::Core::DateAndTime > timesAsVector() const override
Return the time series's times as a vector<DateAndTime>
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ InOut
Both an input & output workspace.
@ Output
An output workspace.