19#pragma warning(disable : 4180)
21#include "tbb/parallel_sort.h"
23#pragma warning(default : 4180)
34using std::runtime_error;
39using Types::Core::DateAndTime;
40using Types::Event::TofEvent;
45const double SEC_TO_NANO = 1.e9;
54template <
typename EventType>
55int64_t calculateCorrectedFullTime(
const EventType &event,
const double tofFactor,
const double tofShift) {
56 return event.pulseTime().totalNanoseconds() +
57 static_cast<int64_t
>(tofFactor * (
event.tof() * 1.0E3) + (tofShift * 1.0E9));
63template <
typename EventType>
class CompareTimeAtSample {
69 CompareTimeAtSample(
const double tofFactor,
const double tofShift) :
m_tofFactor(tofFactor),
m_tofShift(tofShift) {}
81 const auto tAtSample1 = calculateCorrectedFullTime(e1, m_tofFactor, m_tofShift);
82 const auto tAtSample2 = calculateCorrectedFullTime(e2, m_tofFactor, m_tofShift);
83 return (tAtSample1 < tAtSample2);
105 if (e1.pulseTime() < e2.pulseTime()) {
107 }
else if ((e1.pulseTime() == e2.pulseTime()) && (e1.tof() < e2.tof())) {
117 :
startNano(start.totalNanoseconds()),
deltaNano(static_cast<int64_t>(seconds * SEC_TO_NANO)) {}
125 if (e1Pulse < e2Pulse) {
127 }
else if ((e1Pulse == e2Pulse) && (e1.tof() < e2.tof())) {
141 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), eventType(
TOF),
150 m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), eventType(
TOF),
164 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), eventType(
TOF),
174 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), mru(nullptr) {
183 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), mru(nullptr) {
230 int MaxEventsPerBin) {
238 if (
Y.size() + 1 !=
X.size())
239 throw std::runtime_error(
"Expected a histogram (X vector should be 1 longer than the Y vector)");
248 for (
size_t i = 0; i <
X.size() - 1; i++) {
249 double weight =
Y[i];
250 if ((weight != 0.0 || GenerateZeros) && std::isfinite(weight)) {
253 if (std::isfinite(
error)) {
254 if (GenerateMultipleEvents) {
258 double val = weight / E[i];
273 for (
size_t j = 0; j < size_t(
numEvents); j++) {
274 double tof =
X[i] + tofStep * (0.5 + double(j));
282 double tof = (
X[i] +
X[i + 1]) / 2.0;
284 double errorSquared = E[i];
285 errorSquared *= errorSquared;
312 IEventList::operator=(
rhs);
332 this->events.emplace_back(event);
359 this->events.insert(this->events.end(), more_events.begin(), more_events.end());
366 for (
const auto &event : more_events) {
375 for (
const auto &more_event : more_events)
423 for (
const auto &event : more_events) {
512 std::transform(more_events.cbegin(), more_events.cend(), std::back_inserter(
events),
513 [](
const auto &ev) { return T1(ev.tof(), ev.pulseTime(), ev.weight() * (-1.0), ev.errorSquared()); });
525 if (
this == &more_events) {
603 const int64_t tolPulse)
const {
615 if (!this->events[i].
equals(
rhs.events[i], tolTof, tolPulse))
653 throw std::runtime_error(
"EventList::switchTo() called on an EventList "
654 "with weights to go down to TofEvent's. This "
655 "would remove weight information and therefore "
682 throw std::runtime_error(
"EventList::switchToWeightedEvents() called on an "
683 "EventList with WeightedEventNoTime's. It has "
684 "lost the pulse time information and can't go "
685 "back to WeightedEvent's.");
750 throw std::runtime_error(
"EventList: invalid event type value was found.");
767 throw std::runtime_error(
"EventList::getEvents() called for an EventList "
768 "that has weights. Use getWeightedEvents() or "
769 "getWeightedEventsNoTime().");
782 throw std::runtime_error(
"EventList::getEvents() called for an EventList "
783 "that has weights. Use getWeightedEvents() or "
784 "getWeightedEventsNoTime().");
797 throw std::runtime_error(
"EventList::getWeightedEvents() called for an "
798 "EventList not of type WeightedEvent. Use "
799 "getEvents() or getWeightedEventsNoTime().");
812 throw std::runtime_error(
"EventList::getWeightedEvents() called for an "
813 "EventList not of type WeightedEvent. Use "
814 "getEvents() or getWeightedEventsNoTime().");
825 throw std::runtime_error(
"EventList::getWeightedEvents() called for an "
826 "EventList not of type WeightedEventNoTime. Use "
827 "getEvents() or getWeightedEvents().");
838 throw std::runtime_error(
"EventList::getWeightedEventsNoTime() called for "
839 "an EventList not of type WeightedEventNoTime. "
840 "Use getEvents() or getWeightedEvents().");
850 this->events.clear();
851 std::vector<TofEvent>().swap(this->events);
866 this->events.clear();
867 std::vector<TofEvent>().swap(this->events);
898 this->events.reserve(num);
927 throw std::invalid_argument(
"sorting by pulse time with delta requires "
928 "extra parameters. Use sortPulseTimeTOFDelta "
931 throw std::invalid_argument(
"sorting by time at sample requires extra "
932 "parameters. Use sortTimeAtSample instead.");
934 throw runtime_error(
"Invalid sort type in EventList::sort(EventSortType)");
996 CompareTimeAtSample<TofEvent> comparitor(tofFactor, tofShift);
997 tbb::parallel_sort(
events.begin(),
events.end(), comparitor);
1000 CompareTimeAtSample<WeightedEvent> comparitor(tofFactor, tofShift);
1004 CompareTimeAtSample<WeightedEventNoTime> comparitor(tofFactor, tofShift);
1085 tbb::parallel_sort(
events.begin(),
events.end(), comparator);
1115 std::reverse(
x.begin(),
x.end());
1121 std::reverse(this->events.begin(), this->events.end());
1124 std::reverse(this->
weightedEvents.begin(), this->weightedEvents.end());
1146 return this->events.size();
1152 throw std::runtime_error(
"EventList: invalid event type value was found.");
1161 return this->events.empty();
1167 throw std::runtime_error(
"EventList: invalid event type value was found.");
1180 return this->events.capacity() *
sizeof(TofEvent) +
sizeof(
EventList);
1186 throw std::runtime_error(
"EventList: invalid event type value was found.");
1193 size_t x_size =
readX().size();
1283 return histogram().countStandardDeviations();
1291 return histogram().frequencyStandardDeviations();
1296 throw std::runtime_error(
"'EventList::y()' called with no MRU set. This is not allowed.");
1302 throw std::runtime_error(
"'EventList::e()' called with no MRU set. This is not allowed.");
1324 yData = Kernel::make_cow<HistogramData::HistogramY>(std::move(
Y));
1329 auto eData = Kernel::make_cow<HistogramData::HistogramE>(std::move(E));
1353 eData = Kernel::make_cow<HistogramData::HistogramE>(std::move(E));
1368 throw std::runtime_error(
"'EventList::dataY()' called with no MRU set. This is not allowed.");
1382 throw std::runtime_error(
"'EventList::dataE()' called with no MRU set. This is not allowed.");
1390inline double calcNorm(
const double errorSquared) {
1391 if (errorSquared == 0.)
1393 else if (errorSquared == 1.)
1396 return 1. / std::sqrt(errorSquared);
1415 out.reserve(
events.size() / 20);
1418 double lastTof = std::numeric_limits<double>::lowest();
1420 double totalTof = 0;
1424 double errorSquared = 0;
1425 double normalization = 0.;
1427 for (
auto it =
events.cbegin(); it !=
events.cend(); it++) {
1428 if ((it->m_tof - lastTof) <=
tolerance) {
1430 weight += it->weight();
1431 errorSquared += it->errorSquared();
1434 const double norm = calcNorm(it->errorSquared());
1435 normalization += norm;
1436 totalTof += it->m_tof * norm;
1443 out.emplace_back(lastTof, weight, errorSquared);
1444 }
else if (num > 1) {
1445 out.emplace_back(totalTof / normalization, weight, errorSquared);
1449 const double norm = calcNorm(it->errorSquared());
1450 normalization = norm;
1451 totalTof = it->m_tof * norm;
1452 weight = it->weight();
1453 errorSquared = it->errorSquared();
1454 lastTof = it->m_tof;
1462 out.emplace_back(lastTof, weight, errorSquared);
1463 }
else if (num > 1) {
1464 out.emplace_back(totalTof / normalization, weight, errorSquared);
1468 size_t excess_limit = out.size() / 20;
1469 if ((out.capacity() - out.size()) > excess_limit) {
1470 out.shrink_to_fit();
1489 std::vector<std::vector<WeightedEventNoTime>> outputs(numThreads);
1491 size_t numPerBlock =
events.size() / numThreads;
1495 for (
int thread = 0; thread < numThreads; thread++) {
1497 std::vector<WeightedEventNoTime> &localOut = outputs[thread];
1500 localOut.reserve(numPerBlock / 20);
1503 double lastTof = std::numeric_limits<double>::lowest();
1505 double totalTof = 0;
1509 double errorSquared = 0;
1510 double normalization = 0.;
1513 typename std::vector<T>::const_iterator it =
events.begin() + thread * numPerBlock;
1514 typename std::vector<T>::const_iterator it_end =
events.begin() + (thread + 1) * numPerBlock;
1515 if (thread == numThreads - 1)
1517 for (; it != it_end; ++it) {
1518 if ((it->m_tof - lastTof) <=
tolerance) {
1520 weight += it->weight();
1521 errorSquared += it->errorSquared();
1524 const double norm = calcNorm(it->errorSquared());
1525 normalization += norm;
1526 totalTof += it->m_tof * norm;
1532 localOut.emplace_back(totalTof / normalization, weight, errorSquared);
1536 const double norm = calcNorm(it->errorSquared());
1537 normalization = norm;
1538 totalTof = it->m_tof * norm;
1539 weight = it->weight();
1540 errorSquared = it->errorSquared();
1541 lastTof = it->m_tof;
1549 localOut.emplace_back(totalTof / normalization, weight, errorSquared);
1556 for (
int thread = 0; thread < numThreads; thread++)
1561 for (
int thread = 0; thread < numThreads; thread++)
1562 out.insert(out.end(), outputs[thread].begin(), outputs[thread].end());
1567 const double tolerance,
const Types::Core::DateAndTime &timeStart,
1568 const double seconds) {
1572 out.reserve(
events.size() / 20);
1575 double lastTof = std::numeric_limits<double>::lowest();
1577 double totalTof = 0;
1581 const int64_t pulsetimeStart = timeStart.totalNanoseconds();
1582 const auto pulsetimeDelta =
static_cast<int64_t
>(seconds * SEC_TO_NANO);
1585 std::vector<DateAndTime> pulsetimes;
1586 std::vector<double> pulsetimeWeights;
1590 double errorSquared = 0.;
1591 double tofNormalization = 0.;
1597 auto it =
events.cbegin();
1598 for (; it !=
events.cend(); ++it) {
1599 if (it->m_pulsetime >= timeStart)
1604 int64_t lastPulseBin = (it->m_pulsetime.totalNanoseconds() - pulsetimeStart) / pulsetimeDelta;
1606 for (; it !=
events.cend(); ++it) {
1607 const int64_t eventPulseBin = (it->m_pulsetime.totalNanoseconds() - pulsetimeStart) / pulsetimeDelta;
1608 if ((eventPulseBin <= lastPulseBin) && (std::fabs(it->m_tof - lastTof) <=
tolerance)) {
1610 weight += it->weight();
1611 errorSquared += it->errorSquared();
1612 double norm = calcNorm(it->errorSquared());
1613 tofNormalization += norm;
1615 totalTof += it->m_tof * norm;
1617 pulsetimes.emplace_back(it->m_pulsetime);
1618 pulsetimeWeights.emplace_back(norm);
1621 if (!pulsetimes.empty()) {
1624 if (pulsetimes.size() == 1) {
1625 out.emplace_back(lastTof, pulsetimes.front(), weight, errorSquared);
1627 out.emplace_back(totalTof / tofNormalization,
1633 double norm = calcNorm(it->errorSquared());
1634 totalTof = it->m_tof * norm;
1635 weight = it->weight();
1636 errorSquared = it->errorSquared();
1637 tofNormalization = norm;
1638 lastTof = it->m_tof;
1639 lastPulseBin = eventPulseBin;
1641 pulsetimes.emplace_back(it->m_pulsetime);
1642 pulsetimeWeights.clear();
1643 pulsetimeWeights.emplace_back(norm);
1648 if (!pulsetimes.empty()) {
1651 if (pulsetimes.size() == 1) {
1652 out.emplace_back(lastTof, pulsetimes.front(), weight, errorSquared);
1654 out.emplace_back(totalTof / tofNormalization,
1660 size_t excess_limit = out.size() / 20;
1661 if ((out.capacity() - out.size()) > excess_limit) {
1662 out.shrink_to_fit();
1677 if (!this->
empty()) {
1698 if (destination ==
this) {
1700 std::vector<WeightedEventNoTime> out;
1728 const double seconds,
EventList *destination) {
1731 if (!this->
empty()) {
1734 throw std::invalid_argument(
"Cannot compress events that do not have pulsetime");
1741 if (destination ==
this) {
1743 std::vector<WeightedEvent> out;
1772typename std::vector<T>::const_iterator
static findFirstEvent(
const std::vector<T> &events, T seek_tof) {
1773 return std::find_if_not(events.cbegin(), events.cend(), [seek_tof](
const T &
x) { return x < seek_tof; });
1788 const double seek_pulsetime) {
1789 auto itev =
events.begin();
1790 auto itev_end =
events.end();
1793 while ((itev != itev_end) && (
static_cast<double>(itev->pulseTime().totalNanoseconds()) < seek_pulsetime))
1814typename std::vector<T>::const_iterator
1816 const double &tofOffset)
const {
1817 auto itev =
events.cbegin();
1818 auto itev_end =
events.cend();
1821 while ((itev != itev_end) &&
1822 (
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset)) < seek_time))
1839template <
class T>
typename std::vector<T>::iterator
static findFirstEvent(std::vector<T> &events, T seek_tof) {
1840 return std::find_if_not(events.begin(), events.end(), [seek_tof](
const T &
x) { return x < seek_tof; });
1857 size_t x_size =
X.size();
1867 bool mustFill = (
Y.size() == x_size - 1);
1869 Y.resize(x_size - 1, 0.0);
1872 E.resize(x_size - 1, 0.0);
1876 std::fill(
Y.begin(),
Y.end(), 0.0);
1877 std::fill(E.begin(), E.end(), 0.0);
1887 auto itev_end =
events.cend();
1890 if (itev == itev_end)
1897 double tof = itev->tof();
1898 while (bin < x_size - 1) {
1900 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
1903 Y[bin] += double(itev->m_weight);
1904 E[bin] += double(itev->m_errorSquared);
1913 while ((itev != itev_end) && (bin < x_size - 1)) {
1915 while (bin < x_size - 1) {
1919 if (tof <
X[bin + 1]) {
1922 Y[bin] += double(itev->m_weight);
1923 E[bin] += double(itev->m_errorSquared);
1933 std::transform(E.begin(), E.end(), E.begin(),
static_cast<double (*)(
double)
>(sqrt));
1959 throw std::runtime_error(
"Cannot histogram by pulse time on Weighted "
1960 "Events currently");
1963 throw std::runtime_error(
"Cannot histogram by pulse time on Weighted Events NoTime");
1979 const double &tofOffset,
bool skipError)
const {
1992 throw std::runtime_error(
"Cannot histogram by time at sample on Weighted "
1993 "Events currently");
1996 throw std::runtime_error(
"Cannot histogram by time at sample on Weighted Events NoTime");
2042 size_t x_size =
X.size();
2053 Y.resize(x_size - 1, 0);
2058 if (!this->events.empty()) {
2061 auto itev_end =
events.cend();
2064 if (itev == itev_end)
2072 double pulsetime =
static_cast<double>(itev->pulseTime().totalNanoseconds());
2073 while (bin < x_size - 1) {
2075 if ((pulsetime >=
X[bin]) && (pulsetime <
X[bin + 1])) {
2085 while ((itev != itev_end) && (bin < x_size - 1)) {
2086 pulsetime =
static_cast<double>(itev->pulseTime().totalNanoseconds());
2087 while (bin < x_size - 1) {
2089 if ((pulsetime >=
X[bin]) && (pulsetime <
X[bin + 1])) {
2115 const double TOF_min,
const double TOF_max)
const {
2117 if (this->events.empty())
2120 size_t nBins =
Y.size();
2125 double step = (xMax - xMin) /
static_cast<double>(nBins);
2127 for (
const TofEvent &ev : this->events) {
2128 double pulsetime =
static_cast<double>(ev.pulseTime().totalNanoseconds());
2129 if (pulsetime < xMin || pulsetime >= xMax)
2131 if (ev.tof() < TOF_min || ev.tof() >= TOF_max)
2134 auto n_bin =
static_cast<size_t>((pulsetime - xMin) / step);
2149 const double &tofOffset)
const {
2151 const size_t x_size =
X.size();
2162 Y.resize(x_size - 1, 0);
2167 if (!this->events.empty()) {
2170 std::vector<TofEvent>::const_iterator itev_end =
events.end();
2173 if (itev == itev_end)
2179 auto tAtSample =
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset));
2180 while (bin < x_size - 1) {
2182 if ((tAtSample >=
X[bin]) && (tAtSample <
X[bin + 1])) {
2192 while ((itev != itev_end) && (bin < x_size - 1)) {
2193 tAtSample =
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset));
2194 while (bin < x_size - 1) {
2196 if ((tAtSample >=
X[bin]) && (tAtSample <
X[bin + 1])) {
2215 size_t x_size =
X.size();
2226 Y.resize(x_size - 1, 0);
2232 if (!this->events.empty()) {
2237 for (
auto itx =
X.cbegin(); itev !=
events.end(); ++itev) {
2238 double tof = itev->tof();
2239 itx = std::find_if(itx,
X.cend(), [tof](
const double x) { return tof < x; });
2240 if (itx ==
X.cend()) {
2243 auto bin = std::max(std::distance(
X.cbegin(), itx) - 1, std::ptrdiff_t{0});
2259 E.resize(
Y.size(), 0);
2262 std::transform(
Y.begin(),
Y.end(), E.begin(),
static_cast<double (*)(
double)
>(sqrt));
2276 const bool entireRange) {
2277 double sum(0),
error(0);
2294 double &sum,
double &
error) {
2302 typename std::vector<T>::iterator lowit, highit;
2313 if (lowit->tof() < minX)
2314 lowit = std::lower_bound(
events.begin(),
events.end(), minX);
2316 if ((highit - 1)->tof() > maxX) {
2317 highit = std::upper_bound(lowit,
events.end(), T(maxX));
2322 for (
auto it = lowit; it != highit; ++it) {
2323 sum += it->weight();
2324 error += it->errorSquared();
2339 double sum(0),
error(0);
2355 double &
error)
const {
2375 throw std::runtime_error(
"EventList: invalid event type value was found.");
2393 transform(
x.begin(),
x.end(),
x.begin(), func);
2426 ev.m_tof = func(ev.m_tof);
2472 for (
auto &event :
events) {
2473 event.m_tof =
event.m_tof * factor + offset;
2501 for (
auto &event :
events) {
2502 event.m_pulsetime += seconds;
2513 auto eventIterEnd{
events.end()};
2514 auto secondsIter{seconds.cbegin()};
2515 for (
auto eventIter =
events.begin(); eventIter < eventIterEnd; ++eventIter, ++secondsIter) {
2516 eventIter->m_pulsetime += *secondsIter;
2538 throw std::runtime_error(
"EventList::addPulsetime() called on an event "
2539 "list with no pulse times. You must call this "
2540 "algorithm BEFORE CompressEvents.");
2554 throw std::runtime_error(
"");
2566 throw std::runtime_error(
"EventList::addPulsetime() called on an event "
2567 "list with no pulse times. You must call this "
2568 "algorithm BEFORE CompressEvents.");
2584 if (tofMin >
events.rbegin()->tof())
2586 if (tofMax <
events.begin()->tof())
2590 auto it_first = std::lower_bound(
events.begin(),
events.end(), tofMin);
2591 if ((it_first !=
events.end()) && (it_first->tof() < tofMax)) {
2594 auto it_last = std::upper_bound(it_first,
events.end(), T(tofMax));
2596 if (it_first >= it_last) {
2597 throw std::runtime_error(
"Event filter is all messed up");
2600 size_t tmp = (it_last - it_first);
2603 events.erase(it_first, it_last);
2620 if (tofMax <= tofMin)
2621 throw std::runtime_error(
"EventList::maskTof: tofMax must be > tofMin");
2635 numOrig = this->events.size();
2648 if (numDel >= numOrig)
2663 auto itm = std::find(mask.begin(), mask.end(),
false);
2664 auto first =
events.begin() + (itm - mask.begin());
2666 if (itm != mask.end()) {
2667 for (
auto ite = first; ++ite !=
events.end() && ++itm != mask.end();) {
2668 if (*itm !=
false) {
2669 *first++ = std::move(*ite);
2674 auto n =
events.end() - first;
2691 throw std::runtime_error(
"EventList::maskTof: tofMax must be > tofMin");
2702 numOrig = this->events.size();
2715 if (numDel >= numOrig)
2727 for (
auto itev =
events.cbegin(); itev !=
events.cend(); ++itev)
2728 tofs.emplace_back(itev->m_tof);
2757 std::vector<double> tofs;
2770 weights.reserve(
events.size());
2771 std::transform(
events.cbegin(),
events.cend(), std::back_inserter(weights),
2772 [](
const auto &event) { return event.weight(); });
2802 std::vector<double> weights;
2815 weightErrors.clear();
2816 weightErrors.reserve(
events.size());
2817 std::transform(
events.cbegin(),
events.cend(), std::back_inserter(weightErrors),
2818 [](
const auto &event) { return event.error(); });
2848 std::vector<double> weightErrors;
2850 return weightErrors;
2861 std::vector<Mantid::Types::Core::DateAndTime> ×) {
2863 times.reserve(
events.size());
2864 std::transform(
events.cbegin(),
events.cend(), std::back_inserter(times),
2865 [](
const auto &event) { return event.pulseTime(); });
2873 std::vector<Mantid::Types::Core::DateAndTime> times;
2898 double tMin = std::numeric_limits<double>::max();
2908 return this->events.begin()->tof();
2919 for (
size_t i = 0; i <
numEvents; i++) {
2922 temp = this->events[i].tof();
2942 double tMax = std::numeric_limits<double>::lowest();
2952 return this->events.rbegin()->tof();
2963 for (
size_t i = 0; i <
numEvents; i++) {
2966 temp = this->events[i].tof();
2987 DateAndTime tMin = DateAndTime::maximum();
2997 return this->events.begin()->pulseTime();
3006 DateAndTime temp = tMin;
3008 for (
size_t i = 0; i <
numEvents; i++) {
3011 temp = this->events[i].pulseTime();
3031 DateAndTime tMax = DateAndTime::minimum();
3041 return this->events.rbegin()->pulseTime();
3051 DateAndTime temp = tMax;
3052 for (
size_t i = 0; i <
numEvents; i++) {
3055 temp = this->events[i].pulseTime();
3071 Mantid::Types::Core::DateAndTime &tMax)
const {
3073 tMax = DateAndTime::minimum();
3074 tMin = DateAndTime::maximum();
3084 tMin = this->events.begin()->pulseTime();
3085 tMax = this->events.rbegin()->pulseTime();
3100 DateAndTime temp = tMax;
3101 for (
size_t i = 0; i <
numEvents; i++) {
3104 temp = this->events[i].pulseTime();
3122 DateAndTime tMax = DateAndTime::minimum();
3132 return calculateCorrectedFullTime(*(this->events.rbegin()), tofFactor, tofOffset);
3134 return calculateCorrectedFullTime(*(this->
weightedEvents.rbegin()), tofFactor, tofOffset);
3136 return calculateCorrectedFullTime(*(this->
weightedEventsNoTime.rbegin()), tofFactor, tofOffset);
3142 DateAndTime temp = tMax;
3143 for (
size_t i = 0; i <
numEvents; i++) {
3146 temp = calculateCorrectedFullTime(this->events[i], tofFactor, tofOffset);
3149 temp = calculateCorrectedFullTime(this->
weightedEvents[i], tofFactor, tofOffset);
3163 DateAndTime tMin = DateAndTime::maximum();
3173 return calculateCorrectedFullTime(*(this->events.begin()), tofFactor, tofOffset);
3175 return calculateCorrectedFullTime(*(this->
weightedEvents.begin()), tofFactor, tofOffset);
3177 return calculateCorrectedFullTime(*(this->
weightedEventsNoTime.begin()), tofFactor, tofOffset);
3183 DateAndTime temp = tMin;
3184 for (
size_t i = 0; i <
numEvents; i++) {
3187 temp = calculateCorrectedFullTime(this->events[i], tofFactor, tofOffset);
3190 temp = calculateCorrectedFullTime(this->
weightedEvents[i], tofFactor, tofOffset);
3212 size_t x_size = tofs.size();
3213 if (
events.size() != x_size)
3216 for (
size_t i = 0; i < x_size; ++i)
3217 events[i].m_tof = tofs[i];
3260 auto itev_end =
events.end();
3264 for (
auto itev =
events.begin(); itev != itev_end; itev++) {
3265 itev->m_errorSquared =
static_cast<float>(itev->m_errorSquared * valueSquared);
3266 itev->m_weight *=
static_cast<float>(
value);
3270 for (
auto itev =
events.begin(); itev != itev_end; itev++) {
3271 itev->m_errorSquared =
3272 static_cast<float>(itev->m_errorSquared * valueSquared + errorSquared * itev->m_weight * itev->m_weight);
3273 itev->m_weight *=
static_cast<float>(
value);
3358 if ((
X.size() < 2) || (
Y.size() != E.size()) || (
X.size() != 1 +
Y.size())) {
3359 std::stringstream msg;
3360 msg <<
"EventList::multiply() was given invalid size or "
3361 "inconsistent histogram arrays: X["
3363 <<
"Y[" <<
Y.size() <<
" E[" << E.size() <<
"]";
3364 throw std::invalid_argument(msg.str());
3367 size_t x_size =
X.size();
3371 auto itev_end =
events.end();
3374 if (itev == itev_end)
3383 double valueSquared;
3384 double errorSquared;
3388 double tof = itev->tof();
3389 while (bin < x_size - 1) {
3391 if ((tof >=
X[bin]) && (tof <
X[bin + 1]))
3403 while ((itev != itev_end) && (bin < x_size - 1)) {
3405 while (bin < x_size - 1) {
3407 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
3409 itev->m_errorSquared =
3410 static_cast<float>(itev->m_errorSquared * valueSquared + errorSquared * itev->m_weight * itev->m_weight);
3411 itev->m_weight *=
static_cast<float>(
value);
3415 if (bin >= x_size - 1)
3483 if ((
X.size() < 2) || (
Y.size() != E.size()) || (
X.size() != 1 +
Y.size())) {
3484 std::stringstream msg;
3485 msg <<
"EventList::divide() was given invalid size or "
3486 "inconsistent histogram arrays: X["
3488 <<
"Y[" <<
Y.size() <<
" E[" << E.size() <<
"]";
3489 throw std::invalid_argument(msg.str());
3492 size_t x_size =
X.size();
3496 auto itev_end =
events.end();
3499 if (itev == itev_end)
3508 double valError_over_value_squared;
3512 double tof = itev->tof();
3513 while (bin < x_size - 1) {
3515 if ((tof >=
X[bin]) && (tof <
X[bin + 1]))
3526 value = std::numeric_limits<float>::quiet_NaN();
3527 valError_over_value_squared = 0;
3532 while ((itev !=
events.end()) && (bin < x_size - 1)) {
3534 while (bin < x_size - 1) {
3536 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
3538 double newWeight = itev->m_weight /
value;
3539 itev->m_errorSquared =
static_cast<float>(
3540 newWeight * newWeight *
3541 ((itev->m_errorSquared / (itev->m_weight * itev->m_weight)) + valError_over_value_squared));
3542 itev->m_weight =
static_cast<float>(newWeight);
3546 if (bin >= x_size - 1)
3555 value = std::numeric_limits<float>::quiet_NaN();
3556 valError_over_value_squared = 0;
3618 throw std::invalid_argument(
"EventList::divide() called with value of 0.0. Cannot divide by zero.");
3635 throw std::invalid_argument(
"EventList::divide() called with value of 0.0. Cannot divide by zero.");
3641 double invValue = 1.0 /
value;
3643 double invError = (
error /
value) * invValue;
3645 this->
multiply(invValue, invError);
3660 std::vector<T> &output) {
3661 auto itev =
events.begin();
3662 auto itev_end =
events.end();
3664 while ((itev != itev_end) && (itev->m_pulsetime < start))
3667 while ((itev != itev_end) && (itev->m_pulsetime < stop)) {
3669 output.emplace_back(*itev);
3685 double tofFactor,
double tofOffset, std::vector<T> &output) {
3686 auto itev =
events.begin();
3687 auto itev_end =
events.end();
3689 while ((itev != itev_end) && (calculateCorrectedFullTime(*itev, tofFactor, tofOffset) < start.totalNanoseconds()))
3692 while ((itev != itev_end) && (calculateCorrectedFullTime(*itev, tofFactor, tofOffset) < stop.totalNanoseconds())) {
3694 output.emplace_back(*itev);
3710 if (
this == &output) {
3711 throw std::invalid_argument(
"In-place filtering is not allowed");
3733 throw std::runtime_error(
"EventList::filterByPulseTime() called on an "
3734 "EventList that no longer has time information.");
3740 double tofOffset,
EventList &output)
const {
3741 if (
this == &output) {
3742 throw std::invalid_argument(
"In-place filtering is not allowed");
3764 throw std::runtime_error(
"EventList::filterByTimeAtSample() called on an "
3765 "EventList that no longer has full time "
3783 auto itspl = splitter.begin();
3784 auto itspl_end = splitter.end();
3785 DateAndTime start, stop;
3788 auto itev =
events.begin();
3789 auto itev_end =
events.end();
3793 auto itOut =
events.begin();
3796 while (itspl != itspl_end) {
3798 start = itspl->start();
3799 stop = itspl->stop();
3800 const int index = itspl->index();
3803 while ((itev != itev_end) && (itev->m_pulsetime < start))
3807 bool copyingInPlace = (itOut == itev);
3808 if (copyingInPlace) {
3809 while ((itev != itev_end) && (itev->m_pulsetime < stop))
3815 while ((itev != itev_end) && (itev->m_pulsetime < stop)) {
3832 if (itspl == itspl_end)
3836 if (itev == itev_end)
3865 throw std::runtime_error(
"EventList::filterInPlace() called on an "
3866 "EventList that no longer has time information.");
3885 typename std::vector<T> &events)
const {
3886 size_t numOutputs = outputs.size();
3889 auto itspl = splitter.begin();
3890 auto itspl_end = splitter.end();
3891 DateAndTime start, stop;
3894 auto itev =
events.begin();
3895 auto itev_end =
events.end();
3898 while (itspl != itspl_end) {
3900 start = itspl->start();
3901 stop = itspl->stop();
3902 const size_t index = itspl->index();
3905 while ((itev != itev_end) && (itev->m_pulsetime < start))
3909 while ((itev != itev_end) && (itev->m_pulsetime < stop)) {
3911 const T eventCopy(*itev);
3912 if (
index < numOutputs) {
3923 if (itspl == itspl_end)
3927 if (itev == itev_end)
3943 throw std::runtime_error(
"EventList::splitByTime() called on an EventList "
3944 "that no longer has time information.");
3950 size_t numOutputs = outputs.size();
3951 for (
size_t i = 0; i < numOutputs; i++) {
3952 outputs[i]->clear();
3960 if (splitter.empty())
3993 typename std::vector<T> &events,
bool docorrection,
double toffactor,
3994 double tofshift)
const {
3996 auto itspl = splitter.begin();
3997 auto itspl_end = splitter.end();
4000 auto itev =
events.begin();
4001 auto itev_end =
events.end();
4004 while (itspl != itspl_end) {
4006 int64_t start = itspl->start().totalNanoseconds();
4007 int64_t stop = itspl->stop().totalNanoseconds();
4008 const int index = itspl->index();
4013 while (itev != itev_end) {
4016 fulltime = calculateCorrectedFullTime(*itev, toffactor, tofshift);
4018 fulltime = itev->m_pulsetime.totalNanoseconds() +
static_cast<int64_t
>(itev->m_tof * 1000);
4019 if (fulltime < start) {
4021 const T eventCopy(*itev);
4030 while (itev != itev_end) {
4033 fulltime = itev->m_pulsetime.totalNanoseconds() +
4034 static_cast<int64_t
>(toffactor * itev->m_tof * 1000 + tofshift * 1.0E9);
4036 fulltime = itev->m_pulsetime.totalNanoseconds() +
static_cast<int64_t
>(itev->m_tof * 1000);
4037 if (fulltime < stop) {
4039 outputs[
index]->addEventQuickly(*itev);
4049 if (itspl == itspl_end)
4053 if (itev == itev_end)
4071 bool docorrection,
double toffactor,
double tofshift)
const {
4073 throw std::runtime_error(
"EventList::splitByTime() called on an EventList "
4074 "that no longer has time information.");
4080 std::map<int, EventList *>::iterator outiter;
4081 for (outiter = outputs.begin(); outiter != outputs.end(); ++outiter) {
4082 EventList *opeventlist = outiter->second;
4083 opeventlist->
clear();
4091 if (splitter.empty()) {
4093 (*outputs[-1]) = (*
this);
4133 std::map<int, EventList *> outputs,
typename std::vector<T> &vecEvents,
4134 bool docorrection,
double toffactor,
double tofshift)
const {
4137 typename std::vector<T>::iterator eviter;
4138 std::stringstream msgss;
4141 for (eviter = vecEvents.begin(); eviter != vecEvents.end(); ++eviter) {
4143 int64_t evabstimens;
4145 evabstimens = eviter->m_pulsetime.totalNanoseconds() +
4146 static_cast<int64_t
>(toffactor * eviter->m_tof * 1000 + tofshift * 1.0E9);
4148 evabstimens = eviter->m_pulsetime.totalNanoseconds() +
static_cast<int64_t
>(eviter->m_tof * 1000);
4151 int index =
static_cast<int>(lower_bound(vectimes.begin(), vectimes.end(), evabstimens) - vectimes.begin());
4155 if (
index == 0 ||
index >
static_cast<int>(vectimes.size() - 1)) {
4159 group = vecgroups[
index - 1];
4165 std::stringstream errss;
4166 errss <<
"Group " << group <<
" has a NULL output EventList. "
4168 msgss << errss.str();
4170 const T eventCopy(*eviter);
4175 return (msgss.str());
4200 const std::vector<int> &vecgroups,
4201 std::map<int, EventList *> outputs,
4202 typename std::vector<T> &vecEvents,
bool docorrection,
4203 double toffactor,
double tofshift)
const {
4207 std::stringstream msgss;
4209 size_t num_splitters = vecgroups.size();
4211 auto iter_events = vecEvents.begin();
4212 auto iter_events_end = vecEvents.end();
4217 for (
size_t i = 0; i < num_splitters; ++i) {
4219 int64_t start_i64 = vectimes[i];
4220 int64_t stop_i64 = vectimes[i + 1];
4221 int group = vecgroups[i];
4226 while (iter_events != iter_events_end) {
4227 int64_t absolute_time;
4229 absolute_time = iter_events->m_pulsetime.totalNanoseconds() +
4230 static_cast<int64_t
>(toffactor * iter_events->m_tof * 1000 + tofshift * 1.0E9);
4232 absolute_time = iter_events->m_pulsetime.totalNanoseconds() +
static_cast<int64_t
>(iter_events->m_tof * 1000);
4237 if (absolute_time < start_i64) {
4244 if (absolute_time < stop_i64) {
4246 const T eventCopy(*iter_events);
4251 std::stringstream errss;
4252 errss <<
"Group " << group <<
" has a NULL output EventList. "
4254 msgss << errss.str();
4255 throw std::runtime_error(errss.str());
4268 if (iter_events == iter_events_end)
4274 return (msgss.str());
4291 const std::vector<int> &vecgroups,
4292 std::map<int, EventList *> vec_outputEventList,
bool docorrection,
4293 double toffactor,
double tofshift)
const {
4296 throw std::runtime_error(
"EventList::splitByTime() called on an EventList "
4297 "that no longer has time information.");
4304 std::map<int, EventList *>::iterator outiter;
4305 for (outiter = vec_outputEventList.begin(); outiter != vec_outputEventList.end(); ++outiter) {
4306 EventList *opeventlist = outiter->second;
4307 opeventlist->
clear();
4314 std::string debugmessage;
4317 if (vecgroups.empty()) {
4319 (*vec_outputEventList[-1]) = (*
this);
4326 bool sparse_splitter = vec_splitters_time.size() < this->
getNumberEvents();
4330 if (sparse_splitter)
4332 this->events, docorrection, toffactor, tofshift);
4335 this->events, docorrection, toffactor, tofshift);
4338 if (sparse_splitter)
4347 debugmessage =
"TOF type is weighted no time. Impossible to split. ";
4352 return debugmessage;
4361 typename std::vector<T> &events)
const {
4363 auto itspl = splitter.begin();
4364 auto itspl_end = splitter.end();
4365 Types::Core::DateAndTime start, stop;
4368 auto itev =
events.begin();
4369 auto itev_end =
events.end();
4372 while (itspl != itspl_end) {
4374 start = itspl->start().totalNanoseconds();
4375 stop = itspl->stop().totalNanoseconds();
4376 const int index = itspl->index();
4381 while (itev != itev_end) {
4382 if (itev->m_pulsetime < start) {
4384 const T eventCopy(*itev);
4394 while (itev != itev_end) {
4396 if (itev->m_pulsetime < stop) {
4397 outputs[
index]->addEventQuickly(*itev);
4408 if (itspl == itspl_end)
4412 if (itev == itev_end)
4423 throw std::runtime_error(
"EventList::splitByTime() called on an EventList "
4424 "that no longer has time information.");
4430 std::map<int, EventList *>::iterator outiter;
4431 for (outiter = outputs.begin(); outiter != outputs.end(); ++outiter) {
4432 EventList *opeventlist = outiter->second;
4433 opeventlist->
clear();
4441 if (splitter.empty()) {
4443 (*outputs[-1]) = (*
this);
4464 std::map<int, EventList *> outputs)
const {
4467 throw std::runtime_error(
"EventList::splitByTime() called on an EventList "
4468 "that no longer has time information.");
4474 std::map<int, EventList *>::iterator outiter;
4475 for (outiter = outputs.begin(); outiter != outputs.end(); ++outiter) {
4476 EventList *opeventlist = outiter->second;
4477 opeventlist->
clear();
4485 if (vec_target.empty()) {
4487 (*outputs[-1]) = (*
this);
4505 const std::vector<int> &vec_split_target,
4506 std::map<int, EventList *> outputs,
4507 typename std::vector<T> &events)
const {
4509 if (vec_split_times.size() != vec_split_target.size() + 1)
4510 throw std::runtime_error(
"Splitter time vector size and splitter target "
4511 "vector size are not correct.");
4514 auto itev =
events.begin();
4515 auto itev_end =
events.end();
4518 for (
size_t i_target = 0; i_target < vec_split_target.size(); ++i_target) {
4520 int64_t start = vec_split_times[i_target];
4521 int64_t stop = vec_split_times[i_target + 1];
4522 const int index = vec_split_target[i_target];
4527 while (itev != itev_end) {
4528 if (itev->m_pulsetime < start) {
4530 const T eventCopy(*itev);
4540 while (itev != itev_end) {
4542 if (itev->m_pulsetime < stop) {
4543 outputs[
index]->addEventQuickly(*itev);
4552 if (itev == itev_end)
4609 auto itev =
events.begin();
4610 auto itev_end =
events.end();
4611 for (; itev != itev_end; itev++) {
4629 if (!fromUnit || !toUnit)
4630 throw std::runtime_error(
"EventList::convertUnitsViaTof(): one of the units is NULL!");
4632 throw std::runtime_error(
"EventList::convertUnitsViaTof(): fromUnit is not initialized!");
4634 throw std::runtime_error(
"EventList::convertUnitsViaTof(): toUnit is not initialized!");
4658 for (
auto &event :
events) {
4660 event.m_tof = factor * std::pow(event.m_tof, power);
4691 if (
histogram.xMode() != HistogramData::Histogram::XMode::BinEdges)
4692 throw std::runtime_error(
"EventList: setting histogram with storage mode "
4693 "other than BinEdges is not possible");
4695 throw std::runtime_error(
"EventList: setting histogram data with non-null "
4696 "Y or E data is not possible");
4698 if (
histogram.yMode() == HistogramData::Histogram::YMode::Uninitialized)
4701 throw std::runtime_error(
"EventList: setting histogram data with different "
4702 "YMode is not possible");
4706 throw std::runtime_error(
"EventList: setting Points as X data is not "
4707 "possible, only BinEdges are supported");
4711 throw std::runtime_error(
"EventList: Cannot set Y or E data, these data are "
4712 "generated automatically based on the events");
const std::vector< double > & rhs
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_THREAD_NUMBER
#define PARALLEL_FOR_NO_WSP_CHECK()
#define PARALLEL_GET_MAX_THREADS
IEventList : Interface to Mantid::DataObjects::EventList class, used to expose to PythonAPI.
A "spectrum" is an object that holds the data for a particular spectrum, in particular:
void setHistogram(T &&...data)
Sets the Histogram associated with this spectrum.
void addDetectorIDs(const std::set< detid_t > &detIDs)
Add a set of detector IDs to the set of detector IDs.
virtual const MantidVec & readX() const =0
void setDetectorIDs(const std::set< detid_t > &detIDs)
Set the detector IDs to be the set given.
virtual const MantidVec & readE() const
Deprecated, use e() instead. Returns the y error data const.
void clearDetectorIDs()
Clear the detector IDs set.
void copyInfoFrom(const ISpectrum &other)
Copy spectrum number and detector IDs, but not X vector, from another ISpectrum.
virtual const MantidVec & readY() const
Deprecated, use y() instead. Returns the y data const.
const std::set< detid_t > & getDetectorIDs() const
Get a const reference to the detector IDs set.
virtual void copyDataInto(DataObjects::EventList &) const
Override in child classes for polymorphic copying of data.
virtual Kernel::cow_ptr< HistogramData::HistogramX > ptrX() const =0
HistogramData::HistogramX & mutableX() &
void sortTimeAtSample(const double &tofFactor, const double &tofShift, bool forceResort=false) const
Sort events by time at sample.
size_t getMemorySize() const override
Memory used by this event list.
static void getWeightErrorsHelper(const std::vector< T > &events, std::vector< double > &weightErrors)
Get the weight error member of all events in a list.
void addPulsetimes(const std::vector< double > &seconds) override
Add an offset to the pulsetime (wall-clock time) of each event in the list.
void convertUnitsViaTof(Mantid::Kernel::Unit *fromUnit, Mantid::Kernel::Unit *toUnit)
Converts the X units in each event by going through TOF.
Mantid::Types::Core::DateAndTime getTimeAtSampleMax(const double &tofFactor, const double &tofOffset) const override
Get the maximum time at sample.
std::vector< Mantid::Types::Core::DateAndTime > getPulseTimes() const override
Get the pulse times of each event in this EventList.
void setTofs(const MantidVec &tofs) override
Set a list of TOFs to the current event list.
void compressEventsParallelHelper(const std::vector< T > &events, std::vector< WeightedEventNoTime > &out, double tolerance)
Compress the event list by grouping events with the same TOF.
void maskTof(const double tofMin, const double tofMax) override
Mask out events that have a tof between tofMin and tofMax (inclusively).
void multiply(const double value, const double error=0.0) override
Multiply the weights in this event list by a scalar variable with an error; though the error can be 0...
void checkWorksWithPoints() const override
HistogramData::CountStandardDeviations countStandardDeviations() const override
void switchToWeightedEvents()
Switch the EventList to use WeightedEvents instead of TofEvent.
EventList & operator=(const EventList &)
Copy into this event list from another.
void compressFatEvents(const double tolerance, const Types::Core::DateAndTime &timeStart, const double seconds, EventList *destination)
HistogramData::Histogram & mutableHistogramRef() override
HistogramData::Counts counts() const override
std::vector< double > getWeights() const override
Return the list of event weight values.
void convertUnitsViaTofHelper(typename std::vector< T > &events, Mantid::Kernel::Unit *fromUnit, Mantid::Kernel::Unit *toUnit)
Helper function for the conversion to TOF.
void convertUnitsQuickly(const double &factor, const double &power)
Convert the event's TOF (x) value according to a simple output = a * (input^b) relationship.
EventList()
Constructor (empty)
void compressEvents(double tolerance, EventList *destination)
Compress the event list by grouping events with the same TOF (within a given tolerance).
double getTofMax() const override
virtual size_t histogram_size() const
Return the size of the histogram data.
HistogramData::Histogram histogram() const override
Returns the Histogram associated with this spectrum.
void generateHistogram(const MantidVec &X, MantidVec &Y, MantidVec &E, bool skipError=false) const override
Generates both the Y and E (error) histograms w.r.t TOF for an EventList with or without WeightedEven...
static void filterByTimeAtSampleHelper(std::vector< T > &events, Types::Core::DateAndTime start, Types::Core::DateAndTime stop, double tofFactor, double tofOffset, std::vector< T > &output)
~EventList() override
Destructor.
std::vector< Types::Event::TofEvent > & getEvents()
Return the list of TofEvents contained.
std::vector< WeightedEventNoTime > weightedEventsNoTime
List of WeightedEvent's.
void splitByTimeHelper(Kernel::TimeSplitterType &splitter, std::vector< EventList * > outputs, typename std::vector< T > &events) const
Split the event list into n outputs, operating on a vector of either TofEvent's or WeightedEvent's On...
HistogramData::FrequencyStandardDeviations frequencyStandardDeviations() const override
void setSortOrder(const EventSortType order) const
Manually set the event list sort order value.
HistogramData::Histogram m_histogram
Histogram object holding the histogram data. Currently only X.
void generateCountsHistogramPulseTime(const double &xMin, const double &xMax, MantidVec &Y, const double TofMin=std::numeric_limits< double >::lowest(), const double TofMax=std::numeric_limits< double >::max()) const
With respect to PulseTime fill a histogram given equal histogram bins.
void generateErrorsHistogram(const MantidVec &Y, MantidVec &E) const
Generate the Error histogram for the provided counts histogram.
double getTofMin() const override
static void compressEventsHelper(const std::vector< T > &events, std::vector< WeightedEventNoTime > &out, double tolerance)
Compress the event list by grouping events with the same TOF.
static void getPulseTimesHelper(const std::vector< T > &events, std::vector< Mantid::Types::Core::DateAndTime > ×)
Get the pulsetimes of all events in a list.
Mantid::API::EventType eventType
What type of event is in our list.
EventSortType getSortType() const
Return the type of sorting used in this event list.
void filterByTimeAtSample(Types::Core::DateAndTime start, Types::Core::DateAndTime stop, double tofFactor, double tofOffset, EventList &output) const
void switchToWeightedEventsNoTime()
Switch the EventList to use WeightedEventNoTime's instead of TofEvent.
static void setTofsHelper(std::vector< T > &events, const std::vector< double > &tofs)
Set a list of TOFs to the current event list.
void addTof(const double offset) override
Add an offset to the TOF of each event in the list.
bool equals(const EventList &rhs, const double tolTof, const double tolWeight, const int64_t tolPulse) const
Kernel::cow_ptr< HistogramData::HistogramE > sharedE() const override
static std::size_t maskConditionHelper(std::vector< T > &events, const std::vector< bool > &mask)
Mask out events by the condition vector.
EventList & operator/=(const double value)
Operator to divide the weights in this EventList by an error-less scalar.
void checkAndSanitizeHistogram(HistogramData::Histogram &histogram) override
void copyDataInto(EventList &sink) const override
Used by copyDataFrom for dynamic dispatch for its source.
const HistogramData::HistogramY & y() const override
HistogramData::Frequencies frequencies() const override
std::vector< Types::Event::TofEvent > events
List of TofEvent (no weights).
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 generateCountsHistogram(const MantidVec &X, MantidVec &Y) const
Fill a histogram given specified histogram bounds.
Mantid::API::EventType getEventType() const override
Return the type of Event vector contained within.
const MantidVec & readDx() const override
Deprecated, use dx() instead.
void scaleTof(const double factor) override
Convert the units in the TofEvent's m_tof field to some other value, by scaling by a multiplier.
void getPulseTimeMinMax(Mantid::Types::Core::DateAndTime &tMin, Mantid::Types::Core::DateAndTime &tM) const
static void multiplyHelper(std::vector< T > &events, const double value, const double error=0.0)
Helper method for multiplying an event list by a scalar value with/without error.
HistogramData::FrequencyVariances frequencyVariances() const override
std::vector< WeightedEventNoTime > & getWeightedEventsNoTime()
Return the list of WeightedEvent contained.
void setMRU(EventWorkspaceMRU *newMRU)
Sets the MRU list for this event list.
EventWorkspaceMRU * mru
MRU lists of the parent EventWorkspace.
static void integrateHelper(std::vector< T > &events, const double minX, const double maxX, const bool entireRange, double &sum, double &error)
Integrate the events between a range of X values, or all events.
void filterInPlace(Kernel::TimeSplitterType &splitter)
Use a TimeSplitterType to filter the event list in place.
static void multiplyHistogramHelper(std::vector< T > &events, const MantidVec &X, const MantidVec &Y, const MantidVec &E)
Helper method for multiplying an event list by a histogram with error.
Mantid::Types::Core::DateAndTime getPulseTimeMax() const override
Kernel::cow_ptr< HistogramData::HistogramX > ptrX() const override
Deprecated, use sharedX() instead. Returns a pointer to the x data.
MantidVec & dataX() override
Deprecated, use mutableX() instead.
void clearUnused()
Clear any unused event lists (the ones that do not match the currently used type).
MantidVec & dataDx() override
Deprecated, use mutableDx() instead.
bool operator==(const EventList &rhs) const
Equality operator between EventList's.
EventSortType order
Last sorting order.
void convertTofHelper(std::vector< T > &events, const std::function< double(double)> &func)
void clearData() override
Mask the spectrum to this value. Removes all events.
EventList & operator+=(const Types::Event::TofEvent &event)
std::string splitByFullTimeVectorSplitterHelper(const std::vector< int64_t > &vectimes, const std::vector< int > &vecgroups, std::map< int, EventList * > outputs, typename std::vector< T > &vecEvents, bool docorrection, double toffactor, double tofshift) const
Split the event list into n outputs, operating on a vector of either TofEvent's or WeightedEvent's Th...
static void minusHelper(std::vector< T1 > &events, const std::vector< T2 > &more_events)
SUBTRACT another EventList from this event list.
void splitByPulseTimeHelper(Kernel::TimeSplitterType &splitter, std::map< int, EventList * > outputs, typename std::vector< T > &events) const
Split events by pulse time.
void addPulsetimesHelper(std::vector< T > &events, const std::vector< double > &seconds)
Add an offset per event to the pulsetime (wall-clock time) of each event in the list.
void filterInPlaceHelper(Kernel::TimeSplitterType &splitter, typename std::vector< T > &events)
Perform an in-place filtering on a vector of either TofEvent's or WeightedEvent's.
void addPulsetime(const double seconds) override
Add an offset to the pulsetime (wall-clock time) of each event in the list.
void reserve(size_t num) override
Reserve a certain number of entries in event list of the specified eventType.
void setX(const Kernel::cow_ptr< HistogramData::HistogramX > &X) override
Deprecated, use setSharedX() instead.
std::vector< double > getWeightErrors() const override
Return the list of event weight error values.
void sortTof() const
Sort events by TOF in one thread.
HistogramData::CountVariances countVariances() const override
std::string splitByFullTimeSparseVectorSplitterHelper(const std::vector< int64_t > &vectimes, const std::vector< int > &vecgroups, std::map< int, EventList * > outputs, typename std::vector< T > &vecEvents, bool docorrection, double toffactor, double tofshift) const
Split the event list into n outputs, operating on a vector of either TofEvent's or WeightedEvent's Th...
MantidVec & dataE() override
Deprecated, use mutableE() instead.
void splitByPulseTime(Kernel::TimeSplitterType &splitter, std::map< int, EventList * > outputs) const
Split events by pulse time.
static void compressFatEventsHelper(const std::vector< T > &events, std::vector< WeightedEvent > &out, const double tolerance, const Mantid::Types::Core::DateAndTime &timeStart, const double seconds)
MantidVec & dataY() override
Deprecated, use mutableY() instead.
Mantid::Types::Core::DateAndTime getTimeAtSampleMin(const double &tofFactor, const double &tofOffset) const override
Get the minimum time at sample.
const HistogramData::HistogramE & e() const override
bool isSortedByTof() const override
Return true if the event list is sorted by TOF.
bool operator!=(const EventList &rhs) const
Inequality comparator.
std::mutex m_sortMutex
Mutex that is locked while sorting an event list.
static void filterByPulseTimeHelper(std::vector< T > &events, Types::Core::DateAndTime start, Types::Core::DateAndTime stop, std::vector< T > &output)
void generateCountsHistogramTimeAtSample(const MantidVec &X, MantidVec &Y, const double &tofFactor, const double &tofOffset) const
With respect to Time at Sample, fill a histogram given specified histogram bounds.
void reverse()
Reverse the histogram boundaries and the associated events if they are sorted by time-of-flight.
void switchTo(Mantid::API::EventType newType) override
Switch the EventList to use the given EventType (TOF, WEIGHTED, or WEIGHTED_NOTIME)
void splitByPulseTimeWithMatrix(const std::vector< int64_t > &vec_times, const std::vector< int > &vec_target, std::map< int, EventList * > outputs) const
Split events by pulse time with Matrix splitters.
static void divideHistogramHelper(std::vector< T > &events, const MantidVec &X, const MantidVec &Y, const MantidVec &E)
Helper method for dividing an event list by a histogram with error.
static void histogramForWeightsHelper(const std::vector< T > &events, const MantidVec &X, MantidVec &Y, MantidVec &E)
Generates both the Y and E (error) histograms for an EventList with WeightedEvents.
bool empty() const
Much like stl containers, returns true if there is nothing in the event list.
std::vector< WeightedEvent > weightedEvents
List of WeightedEvent's.
const MantidVec & readX() const override
Deprecated, use x() instead. Returns the x data const.
WeightedEvent getEvent(size_t event_number)
Return the given event in the list.
void integrate(const double minX, const double maxX, const bool entireRange, double &sum, double &error) const
Integrate the events between a range of X values, or all events.
Kernel::cow_ptr< HistogramData::HistogramY > sharedY() const override
void generateHistogramTimeAtSample(const MantidVec &X, MantidVec &Y, MantidVec &E, const double &tofFactor, const double &tofOffset, bool skipError=false) const override
Generates both the Y and E (error) histograms w.r.t Time at sample position.
void createFromHistogram(const ISpectrum *inSpec, bool GenerateZeros, bool GenerateMultipleEvents, int MaxEventsPerBin)
Create an EventList from a histogram.
void convertUnitsQuicklyHelper(typename std::vector< T > &events, const double &factor, const double &power)
Convert the event's TOF (x) value according to a simple output = a * (input^b) relationship.
void splitByFullTimeHelper(Kernel::TimeSplitterType &splitter, std::map< int, EventList * > outputs, typename std::vector< T > &events, bool docorrection, double toffactor, double tofshift) const
Split the event list into n outputs, operating on a vector of either TofEvent's or WeightedEvent's Th...
MantidVec * makeDataE() const
Calculates and returns a pointer to the E histogrammed data.
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 ...
void checkIsYAndEWritable() const override
void generateHistogramPulseTime(const MantidVec &X, MantidVec &Y, MantidVec &E, bool skipError=false) const override
Generates both the Y and E (error) histograms w.r.t Pulse Time for an EventList with or without Weigh...
void sortPulseTimeTOF() const
void copyDataFrom(const ISpectrum &source) override
Copy data from another EventList, via ISpectrum reference.
void splitByTime(Kernel::TimeSplitterType &splitter, std::vector< EventList * > outputs) const
Split the event list into n outputs.
void filterByPulseTime(Types::Core::DateAndTime start, Types::Core::DateAndTime stop, EventList &output) const
Filter this EventList into an output EventList, using keeping only events within the >= start and < e...
void addPulsetimeHelper(std::vector< T > &events, const double seconds)
Add an offset to the pulsetime (wall-clock time) of each event in the list.
std::vector< double > getTofs() const override
Get the times-of-flight of each event in this EventList.
EventList & operator*=(const double value)
Operator to multiply the weights in this EventList by an error-less scalar.
void convertTof(std::function< double(double)> func, const int sorting=0) override
Mantid::Types::Core::DateAndTime getPulseTimeMin() const override
static void getWeightsHelper(const std::vector< T > &events, std::vector< double > &weights)
Get the weight member of all events in a list.
void maskCondition(const std::vector< bool > &mask) override
Mask out events by the condition vector.
void sortPulseTime() const
Sort events by Frame.
std::vector< T >::const_iterator findFirstTimeAtSampleEvent(const std::vector< T > &events, const double seek_time, const double &tofFactor, const double &tofOffset) const
Utility function: Returns the iterator into events of the first TofEvent with time at sample > seek_t...
void sortPulseTimeTOFDelta(const Types::Core::DateAndTime &start, const double seconds) const
Sort by the pulse time with a tolerance.
void splitByPulseTimeWithMatrixHelper(const std::vector< int64_t > &vec_split_times, const std::vector< int > &vec_split_target, std::map< int, EventList * > outputs, typename std::vector< T > &events) const
Split events (template) by pulse time with matrix splitters.
static std::size_t maskTofHelper(std::vector< T > &events, const double tofMin, const double tofMax)
Mask out events that have a tof between tofMin and tofMax (inclusively).
void addEventQuickly(const Types::Event::TofEvent &event)
Append an event to the histogram, without clearing the cache, to make it faster.
static std::vector< T >::const_iterator findFirstPulseEvent(const std::vector< T > &events, const double seek_pulsetime)
Utility function: Returns the iterator into events of the first TofEvent with pulsetime() > seek_puls...
EventList & operator-=(const EventList &more_events)
SUBTRACT another EventList from this event list.
void sort(const EventSortType order) const
Sort events by TOF or Frame.
MantidVec * makeDataY() const
Calculates and returns a pointer to the Y histogrammed data.
static void getTofsHelper(const std::vector< T > &events, std::vector< double > &tofs)
Get the m_tof member of all events in a list.
void clear(const bool removeDetIDs=true) override
Clear the list of events and any associated detector ID's.
std::vector< WeightedEvent > & getWeightedEvents()
Return the list of WeightedEvent contained.
void divide(const double value, const double error=0.0) override
Divide the weights in this event list by a scalar with an (optional) error.
This is a container for the MRU (most-recently-used) list of generated histograms.
void insertY(size_t thread_num, YType data, const EventList *index)
Insert a new histogram into the MRU.
EType findE(size_t thread_num, const EventList *index)
Find a Y histogram in the MRU.
void insertE(size_t thread_num, EType data, const EventList *index)
Insert a new histogram into the MRU.
void ensureEnoughBuffersE(size_t thread_num) const
This function makes sure that there are enough data buffers (MRU's) for E for the number of threads r...
YType findY(size_t thread_num, const EventList *index)
Find a Y histogram in the MRU.
void deleteIndex(const EventList *index)
Delete any entries in the MRU at the given index.
void ensureEnoughBuffersY(size_t thread_num) const
This function makes sure that there are enough data buffers (MRU's) for Y for the number of threads r...
1D histogram implementation.
Info about a single neutron detection event, including a weight and error value, but excluding the pu...
Info about a single neutron detection event, including a weight and error value:
The base units (abstract) class.
virtual double singleToTOF(const double x) const =0
Convert a single X value to TOF.
virtual double singleFromTOF(const double tof) const =0
Convert a single tof value to this unit.
bool isInitialized() const
Implements a copy on write data template.
EventType
What kind of event list is being stored.
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
DLLExport void getEventsFrom(EventList &el, std::vector< Types::Event::TofEvent > *&events)
bool compareEventPulseTime(const TofEvent &e1, const TofEvent &e2)
Compare two events' FRAME id, return true if e1 should be before e2.
static std::vector< T >::const_iterator findFirstEvent(const std::vector< T > &events, T seek_tof)
Utility function: Returns the iterator into events of the first TofEvent with tof() > seek_tof Will r...
EventSortType
How the event list is sorted.
@ PULSETIMETOF_DELTA_SORT
bool compareEventPulseTimeTOF(const TofEvent &e1, const TofEvent &e2)
Compare two events' FRAME id, return true if e1 should be before e2.
MANTID_KERNEL_DLL Types::Core::DateAndTime averageSorted(const std::vector< Types::Core::DateAndTime > ×)
averageSorted Assuming that the vector is sorted, find the average time
std::vector< SplittingInterval > TimeSplitterType
A typedef for splitting events according their pulse time.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
int32_t specnum_t
Typedef for a spectrum Number.
bool operator()(const TofEvent &e1, const TofEvent &e2)
comparePulseTimeTOFDelta(const Types::Core::DateAndTime &start, const double seconds)