15#include "MantidHistogramData/Histogram.h"
25using Mantid::Types::Core::DateAndTime;
37 m_intInfoMap(), m_dblInfoMap(), m_log(
nullptr), m_timeVec(), m_valueVec(), m_starttime(), m_endtime(),
38 m_ignoreNegativeTime(false) {
39 this->deprecatedDate(
"2025-11-21");
47 "Input EventWorkspace. Each spectrum corresponds to 1 pixel");
50 "Name of the workspace of log delta T distribution. ");
53 "Name of optional log statistic information output Tableworkspace.");
57 std::vector<std::string> timeoptions{
"Absolute Time (nano second)",
"Relative Time (second)"};
58 declareProperty(
"TimeRangeOption",
"Relative Time (second)", std::make_shared<StringListValidator>(timeoptions),
59 "User defined time range (T0, Tf) is of absolute time (second). ");
62 "Earliest time of the events to be selected. "
63 "It can be absolute time (ns), relative time (second) or percentage.");
65 "Latest time of the events to be selected. "
66 "It can be absolute time (ns), relative time (second) or percentage.");
68 declareProperty(
"TimeStepBinResolution", 0.0001,
"Time resolution (second) for time stamp delta T disibution. ");
71 "If true, then the time interval with negative number will "
72 "be neglected in doing statistic.");
81 throw runtime_error(
"Inputworkspace cannot be parsed to a MatrixWorkspace.");
86 throw runtime_error(
"Input log value cannot be an empty string. ");
91 errmsg <<
"Property " << logname <<
" does not exit in sample of workspace " <<
m_dataWS->getName() <<
".";
93 throw std::invalid_argument(errmsg.str());
98 errmsg <<
"Log " << logname <<
" is found, but is not a double type time series log";
100 throw std::invalid_argument(errmsg.str());
119 double resolution =
getProperty(
"TimeStepBinResolution");
127 double userinputdt = 1 / 240.1;
135 this->
setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<MatrixWorkspace>(timestatws));
154 string timeoption = this->
getProperty(
"TimeRangeOption");
156 if (timeoption ==
"Absolute Time (nano second)")
158 else if (timeoption ==
"Relative Time (second)")
163 double duration =
static_cast<double>(
m_timeVec.back().totalNanoseconds() -
m_timeVec[0].totalNanoseconds()) * 1.0E-9;
183 throw runtime_error(
"Coding error!");
207 throw runtime_error(
"Coding error!");
215 errmsg <<
"User defined filter starting time @ " <<
mFilterT0 <<
" (T = " << t0r
216 <<
") is later than or equal to filer ending time @ " <<
mFilterTf <<
" (T = " << tfr <<
").";
218 throw std::invalid_argument(errmsg.str());
227 DateAndTime temptime(
static_cast<int64_t
>(abstimens));
236 int64_t totaltime =
m_starttime.totalNanoseconds() +
static_cast<int64_t
>(deltatime * 1.0E9);
237 DateAndTime abstime(totaltime);
245 auto tablews = std::make_shared<TableWorkspace>();
247 tablews->addColumn(
"str",
"Name");
248 tablews->addColumn(
"double",
"Value");
252 string text = intmapiter.first;
253 size_t value = intmapiter.second;
255 TableRow newrow = tablews->appendRow();
256 newrow << text << static_cast<double>(
value);
260 map<string, double>::iterator dblmapiter;
262 string text = dblmapiter->first;
263 double value = dblmapiter->second;
265 TableRow newrow = tablews->appendRow();
266 newrow << text <<
value;
282 std::string outputdir =
getProperty(
"OutputDirectory");
283 if (!outputdir.empty() && outputdir.back() !=
'/')
286 std::string ofilename = outputdir +
"errordeltatime.txt";
289 ofs.open(ofilename.c_str(), std::ios::out);
291 Types::Core::DateAndTime t0(ws->run().getProperty(
"run_start")->value());
293 for (
size_t i = 1; i < abstimevec.size(); i++) {
295 static_cast<double>(abstimevec[i].totalNanoseconds() - abstimevec[i - 1].totalNanoseconds()) * 1.0E-9;
296 double dev = (tempdts - dts) / dts;
298 if (
fabs(dev) > 0.5) {
299 double deltapulsetimeSec1 =
300 static_cast<double>(abstimevec[i - 1].totalNanoseconds() - t0.totalNanoseconds()) * 1.0E-9;
301 double deltapulsetimeSec2 =
302 static_cast<double>(abstimevec[i].totalNanoseconds() - t0.totalNanoseconds()) * 1.0E-9;
303 auto index1 =
static_cast<int>(deltapulsetimeSec1 * 60);
304 auto index2 =
static_cast<int>(deltapulsetimeSec2 * 60);
306 ofs <<
"Error d(T) = " << tempdts <<
" vs Correct d(T) = " << dts <<
'\n';
307 ofs << index1 <<
"\t\t" << abstimevec[i - 1].totalNanoseconds() <<
"\t\t" << index2 <<
"\t\t"
308 << abstimevec[i].totalNanoseconds() <<
'\n';
324 double dtmin =
static_cast<double>(timevec.back().totalNanoseconds() - timevec[0].totalNanoseconds()) * 1.0E-9;
327 vector<double> vecdt(timevec.size() - 1, 0.0);
328 for (
size_t i = 1; i < timevec.size(); ++i) {
329 vecdt[i - 1] =
static_cast<double>(timevec[i].totalNanoseconds() - timevec[i - 1].totalNanoseconds()) * 1.0E-9;
330 if (vecdt[i - 1] < dtmin)
331 dtmin = vecdt[i - 1];
332 else if (vecdt[i - 1] > dtmax)
333 dtmax = vecdt[i - 1];
339 numbins =
static_cast<size_t>(ceil((dtmax) / stepsize)) + 2;
341 numbins =
static_cast<size_t>(ceil((dtmax - dtmin) / stepsize)) + 2;
344 g_log.
notice() <<
"Distribution has " << numbins <<
" bins. Delta T = (" << dtmin <<
", " << dtmax <<
")\n";
347 auto &vecDeltaT = distws->mutableX(0);
348 auto &vecCount = distws->mutableY(0);
350 double countmin = dtmin;
354 for (
size_t i = 0; i < numbins; ++i)
355 vecDeltaT[i] = countmin + (
static_cast<double>(i) - 1) * stepsize;
356 for (
size_t i = 0; i < numbins; ++i)
360 for (
double dt : vecdt) {
365 auto viter = lower_bound(vecDeltaT.begin(), vecDeltaT.end(), dt);
366 index =
static_cast<int>(viter - vecDeltaT.begin());
367 if (
index >=
static_cast<int>(vecDeltaT.size())) {
369 g_log.
error() <<
"Find index = " <<
index <<
" > vecX.size = " << vecDeltaT.size() <<
".\n";
370 }
else if (dt < vecDeltaT[
index]) {
375 throw runtime_error(
"How can this happen.");
377 vecCount[
index] += 1;
387 size_t countsame = 0;
388 size_t countinverse = 0;
389 for (
size_t i = 1; i <
m_timeVec.size(); i++) {
390 Types::Core::DateAndTime tprev =
m_timeVec[i - 1];
391 Types::Core::DateAndTime tpres =
m_timeVec[i];
394 else if (tprev > tpres)
406 m_intInfoMap.emplace(
"Number of Equal Time Stamps", countsame);
407 m_intInfoMap.emplace(
"Number of Reversed Time Stamps", countinverse);
410 double runduration_sec =
static_cast<double>(
m_endtime.totalNanoseconds() -
m_starttime.totalNanoseconds()) * 1.0E-9;
411 if (runduration_sec < 0.0) {
412 g_log.
warning() <<
"It shows that the run duration is not right. "
413 <<
"Run start = " <<
m_starttime.toFormattedString() <<
"; "
414 <<
"Run End = " <<
m_endtime.toFormattedString() <<
".\n";
416 <<
"Log end time = " <<
m_timeVec.back().toFormattedString() <<
".\n";
419 double sum_deltaT1 = 0.0;
420 double sum_deltaT2 = 0.0;
423 if (runduration_sec > 0)
424 min_dt = runduration_sec;
427 for (
size_t i = 0; i < numpts - 1; ++i) {
429 double dt =
static_cast<double>(dtns) * 1.0E-9;
432 g_log.
warning() <<
"Reversed dT: dt = " << dt <<
" between " <<
m_timeVec[i].toFormattedString() <<
" and "
433 <<
m_timeVec[i + 1].toFormattedString() <<
" @ index = " << i <<
".\n";
437 sum_deltaT2 += dt * dt;
445 double avg_dt = sum_deltaT1 /
static_cast<double>(numpts - 1);
446 double std_dt = sqrt(sum_deltaT2 /
static_cast<double>(numpts - 1) - avg_dt * avg_dt);
505 const vector<double> &values,
double delta) {
506 std::stringstream ss;
507 ss <<
"Alternating Threashold = " <<
delta <<
'\n';
509 size_t numchange = 0;
510 for (
size_t i = 1; i < values.size(); i++) {
511 double tempdelta = values[i] - values[i - 1];
517 ss <<
"@ " << i <<
"\tDelta = " << tempdelta <<
"\t\tTime From " << timevec[i - 1].totalNanoseconds() <<
" to "
518 << timevec[i].totalNanoseconds() <<
'\n';
522 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.
Class for marking algorithms as deprecated.
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.