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;
45constexpr double SEC_TO_NANO{1.e9};
49constexpr size_t MIN_VEC_LENGTH_PARALLEL_SORT{2000};
58template <
typename EventType>
59int64_t calculateCorrectedFullTime(
const EventType &event,
const double tofFactor,
const double tofShift) {
60 return event.pulseTime().totalNanoseconds() +
61 static_cast<int64_t
>(tofFactor * (
event.tof() * 1.0E3) + (tofShift * 1.0E9));
67template <
typename EventType>
class CompareTimeAtSample {
73 CompareTimeAtSample(
const double tofFactor,
const double tofShift) :
m_tofFactor(tofFactor),
m_tofShift(tofShift) {}
85 const auto tAtSample1 = calculateCorrectedFullTime(e1, m_tofFactor, m_tofShift);
86 const auto tAtSample2 = calculateCorrectedFullTime(e2, m_tofFactor, m_tofShift);
87 return (tAtSample1 < tAtSample2);
109 if (e1.pulseTime() < e2.pulseTime()) {
111 }
else if ((e1.pulseTime() == e2.pulseTime()) && (e1.tof() < e2.tof())) {
121 :
startNano(start.totalNanoseconds()),
deltaNano(static_cast<int64_t>(seconds * SEC_TO_NANO)) {}
129 if (e1Pulse < e2Pulse) {
131 }
else if ((e1Pulse == e2Pulse) && (e1.tof() < e2.tof())) {
149 divisor = 1. / log1p(abs(step));
166 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts),
167 eventType(event_type), order(
UNSORTED), mru(nullptr) {
170 this->
events = std::make_unique<std::vector<Mantid::Types::Event::TofEvent>>();
177 this->weightedEvents = std::make_unique<std::vector<WeightedEvent>>();
183 this->weightedEventsNoTime = std::make_unique<std::vector<WeightedEventNoTime>>();
184 this->weightedEventsNoTime =
nullptr;
195 m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts),
196 weightedEvents(nullptr), weightedEventsNoTime(nullptr), eventType(
TOF), order(
UNSORTED), mru(mru) {
197 this->
events = std::make_unique<std::vector<Mantid::Types::Event::TofEvent>>();
211 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts),
212 weightedEvents(nullptr), weightedEventsNoTime(nullptr), eventType(
TOF), mru(nullptr) {
213 this->events = std::make_unique<std::vector<Mantid::Types::Event::TofEvent>>(
events.cbegin(),
events.cend());
221 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), events(nullptr),
222 weightedEventsNoTime(nullptr), mru(nullptr) {
231 : m_histogram(HistogramData::Histogram::XMode::BinEdges, HistogramData::Histogram::YMode::Counts), events(nullptr),
232 weightedEvents(nullptr), mru(nullptr) {
244 }
catch (
const std::runtime_error &) {
262 sink.
events = std::make_unique<std::vector<Types::Event::TofEvent>>(
events->cbegin(),
events->cend());
264 sink.
events = std::make_unique<std::vector<Types::Event::TofEvent>>();
269 sink.
weightedEvents = std::make_unique<std::vector<WeightedEvent>>();
296 int MaxEventsPerBin) {
301 Mantid::HistogramData::HistogramX
const &
X = inSpec->
x();
302 Mantid::HistogramData::HistogramY
const &
Y = inSpec->
y();
303 Mantid::HistogramData::HistogramE
const &E = inSpec->
e();
304 if (
Y.size() + 1 !=
X.size()) {
305 throw std::runtime_error(
"Expected a histogram (X vector should be 1 longer than the Y vector)");
315 for (
size_t i = 0; i <
X.size() - 1; i++) {
316 double weight =
Y[i];
317 if ((weight != 0.0 || GenerateZeros) && std::isfinite(weight)) {
320 if (std::isfinite(
error)) {
321 if (GenerateMultipleEvents) {
325 double val = weight / E[i];
340 for (
size_t j = 0; j < size_t(
numEvents); j++) {
341 double tof =
X[i] + tofStep * (0.5 + double(j));
349 double tof = (
X[i] +
X[i + 1]) / 2.0;
351 double errorSquared = E[i];
352 errorSquared *= errorSquared;
379 IEventList::operator=(
rhs);
381 rhs.copyDataInto(*
this);
395 this->
events->emplace_back(event);
422 this->
events->insert(this->
events->end(), more_events.cbegin(), more_events.cend());
429 std::copy(more_events.cbegin(), more_events.cend(), std::back_inserter(*this->weightedEvents));
436 std::copy(more_events.cbegin(), more_events.cend(), std::back_inserter(*this->weightedEventsNoTime));
483 std::copy(more_events.cbegin(), more_events.cend(), std::back_inserter(*this->weightedEventsNoTime));
527 if (!more_events.
empty()) {
575 std::transform(more_events.cbegin(), more_events.cend(), std::back_inserter(
events),
576 [](
const auto &ev) { return T1(ev.tof(), ev.pulseTime(), ev.weight() * (-1.0), ev.errorSquared()); });
588 if (
this == &more_events) {
644bool vectorPtrEquals(
const std::unique_ptr<std::vector<T>> &
left,
const std::unique_ptr<std::vector<T>> &
right) {
668 if (!vectorPtrEquals(
events,
rhs.events))
686 const int64_t tolPulse)
const {
698 auto leftIter = this->
events->cbegin();
699 auto leftEnd = this->
events->cend();
700 auto rightIter =
rhs.events->cbegin();
701 while (leftIter != leftEnd) {
702 if (!leftIter->equals(*rightIter, tolTof, tolPulse))
704 leftIter = std::next(leftIter);
705 rightIter = std::next(rightIter);
712 auto rightIter =
rhs.weightedEvents->cbegin();
713 while (leftIter != leftEnd) {
714 if (!leftIter->equals(*rightIter, tolTof, tolWeight, tolPulse))
716 leftIter = std::next(leftIter);
717 rightIter = std::next(rightIter);
724 auto rightIter =
rhs.weightedEventsNoTime->cbegin();
725 while (leftIter != leftEnd) {
726 if (!leftIter->equals(*rightIter, tolTof, tolWeight))
728 leftIter = std::next(leftIter);
729 rightIter = std::next(rightIter);
755 throw std::runtime_error(
"EventList::switchTo() called on an EventList with weights to go down to TofEvent's. "
756 "This would remove weight information and therefore is not possible.");
782 throw std::runtime_error(
"EventList::switchToWeightedEvents() called on an EventList with WeightedEventNoTime's. "
783 "It has lost the pulse time information and can't go back to WeightedEvent's.");
857 return WeightedEvent(event.tof(), 0, event.weight(), event.errorSquared());
860 throw std::runtime_error(
"EventList: invalid event type value was found.");
877 throw std::runtime_error(
"EventList::getEvents() called for an EventList that has weights. Use getWeightedEvents() "
878 "or getWeightedEventsNoTime().");
882 throw std::runtime_error(
"unweighted event vector is not initialized");
893 throw std::runtime_error(
"EventList::getEvents() called for an EventList that has weights. Use getWeightedEvents() "
894 "or getWeightedEventsNoTime().");
898 throw std::runtime_error(
"unweighted event vector is not initialized");
910 throw std::runtime_error(
"EventList::getWeightedEvents() called for an EventList not of type WeightedEvent. Use "
911 "getEvents() or getWeightedEventsNoTime().");
915 throw std::runtime_error(
"weighted event vector is not initialized");
927 throw std::runtime_error(
"EventList::getWeightedEvents() called for an EventList not of type WeightedEvent. Use "
928 "getEvents() or getWeightedEventsNoTime().");
932 throw std::runtime_error(
"weighted event vector is not initialed");
942 throw std::runtime_error(
"EventList::getWeightedEventsNoTime() called for an EventList not of type "
943 "WeightedEventNoTime. Use getEvents() or getWeightedEvents().");
947 throw std::runtime_error(
"weighted event no time vector is not initialed");
957 throw std::runtime_error(
"EventList::getWeightedEventsNoTime() called for an EventList not of type "
958 "WeightedEventNoTime. Use getEvents() or getWeightedEvents().");
962 throw std::runtime_error(
"weighted event no time vector is not initialed");
972 }
catch (
const std::runtime_error &) {
981 if (!this->
empty()) {
984 std::vector<TofEvent>().swap(*this->
events);
1034 this->
events->reserve(num);
1063 throw std::invalid_argument(
"sorting by pulse time with delta requires "
1064 "extra parameters. Use sortPulseTimeTOFDelta "
1067 throw std::invalid_argument(
"sorting by time at sample requires extra "
1068 "parameters. Use sortTimeAtSample instead.");
1070 throw runtime_error(
"Invalid sort type in EventList::sort(EventSortType)");
1083template <
class RandomIt>
void switchable_sort(RandomIt first, RandomIt last) {
1084 const auto vec_size =
static_cast<size_t>(std::distance(first, last));
1087 else if (vec_size < MIN_VEC_LENGTH_PARALLEL_SORT)
1088 std::sort(first, last);
1090 tbb::parallel_sort(first, last);
1093template <
class RandomIt,
class Compare>
void switchable_sort(RandomIt first, RandomIt last, Compare comp) {
1094 const auto vec_size =
static_cast<size_t>(std::distance(first, last));
1097 else if (vec_size < MIN_VEC_LENGTH_PARALLEL_SORT)
1098 std::sort(first, last, std::move(comp));
1100 tbb::parallel_sort(first, last, comp);
1155 CompareTimeAtSample<TofEvent> comparitor(tofFactor, tofShift);
1156 switchable_sort(
events->begin(),
events->end(), comparitor);
1159 CompareTimeAtSample<WeightedEvent> comparitor(tofFactor, tofShift);
1163 CompareTimeAtSample<WeightedEventNoTime> comparitor(tofFactor, tofShift);
1244 switchable_sort(
events->begin(),
events->end(), std::move(comparator));
1274 std::reverse(
x.begin(),
x.end());
1280 std::reverse(this->
events->begin(), this->events->end());
1283 std::reverse(this->
weightedEvents->begin(), this->weightedEvents->end());
1311 throw std::runtime_error(
"EventList: invalid event type value was found.");
1321 return this->
events->empty();
1323 throw std::runtime_error(
"TOF events is nullptr");
1328 throw std::runtime_error(
"WEIGHTED events is nullptr");
1333 throw std::runtime_error(
"WEIGHTED_NOTIME events is nullptr");
1335 throw std::runtime_error(
"EventList: invalid event type value was found.");
1348 return this->
events->capacity() *
sizeof(TofEvent) +
sizeof(
EventList);
1354 throw std::runtime_error(
"EventList: invalid event type value was found.");
1361 size_t x_size =
x().size();
1454 return histogram().countStandardDeviations();
1462 return histogram().frequencyStandardDeviations();
1467 throw std::runtime_error(
"'EventList::y()' called with no MRU set. This is not allowed.");
1473 throw std::runtime_error(
"'EventList::e()' called with no MRU set. This is not allowed.");
1486 yData =
mru->
findY(
static_cast<size_t>(thread),
this);
1495 yData = Kernel::make_cow<HistogramData::HistogramY>(std::move(
Y));
1500 auto eData = Kernel::make_cow<HistogramData::HistogramE>(std::move(E));
1524 eData = Kernel::make_cow<HistogramData::HistogramE>(std::move(E));
1539 throw std::runtime_error(
"'EventList::dataY()' called with no MRU set. This is not allowed.");
1553 throw std::runtime_error(
"'EventList::dataE()' called with no MRU set. This is not allowed.");
1561inline double calcNorm(
const double errorSquared) {
1562 if (errorSquared == 0.)
1564 else if (errorSquared == 1.)
1567 return 1. / std::sqrt(errorSquared);
1586 out.reserve(
events.size() / 20);
1589 double lastTof =
events.front().m_tof;
1591 double totalTof = 0;
1595 double errorSquared = 0;
1596 double normalization = 0.;
1598 double bin_end = lastTof;
1599 std::function<bool(
const double,
const double)> compareTof;
1600 std::function<double(
const double,
double)> next_bin;
1604 throw std::runtime_error(
"compressEvents with log binning doesn't work with negative TOF");
1610 compareTof = [](
const double lhs,
const double rhs) {
return lhs <
rhs; };
1611 next_bin = [
tolerance](
const double lastTof,
double bin_end) {
1613 while (lastTof >= bin_end)
1619 compareTof = [](
const double lhs,
const double rhs) {
return lhs <=
rhs; };
1620 next_bin = [
tolerance](
const double lastTof, double) {
return lastTof +
tolerance; };
1624 bin_end = next_bin(lastTof, bin_end);
1626 for (
auto it =
events.cbegin(); it !=
events.cend(); it++) {
1627 if (compareTof(it->m_tof, bin_end)) {
1629 weight += it->weight();
1630 errorSquared += it->errorSquared();
1633 const double norm = calcNorm(it->errorSquared());
1634 normalization += norm;
1635 totalTof += it->m_tof * norm;
1642 out.emplace_back(lastTof, weight, errorSquared);
1643 }
else if (num > 1) {
1644 out.emplace_back(totalTof / normalization, weight, errorSquared);
1648 const double norm = calcNorm(it->errorSquared());
1649 normalization = norm;
1650 totalTof = it->m_tof * norm;
1651 weight = it->weight();
1652 errorSquared = it->errorSquared();
1653 lastTof = it->m_tof;
1655 bin_end = next_bin(lastTof, bin_end);
1663 out.emplace_back(lastTof, weight, errorSquared);
1664 }
else if (num > 1) {
1665 out.emplace_back(totalTof / normalization, weight, errorSquared);
1669 size_t excess_limit = out.size() / 20;
1670 if ((out.capacity() - out.size()) > excess_limit) {
1671 out.shrink_to_fit();
1677 const double tolerance,
const Types::Core::DateAndTime &timeStart,
1678 const double seconds) {
1682 out.reserve(
events.size() / 20);
1685 double lastTof =
events.front().m_tof;
1687 double totalTof = 0;
1691 const int64_t pulsetimeStart = timeStart.totalNanoseconds();
1692 const auto pulsetimeDelta =
static_cast<int64_t
>(seconds * SEC_TO_NANO);
1695 std::vector<DateAndTime> pulsetimes;
1696 std::vector<double> pulsetimeWeights;
1700 double errorSquared = 0.;
1701 double tofNormalization = 0.;
1706 auto it =
events.cbegin();
1707 for (; it !=
events.cend(); ++it) {
1708 if (it->m_pulsetime >= timeStart)
1713 throw std::runtime_error(
"failed to find first pulse time in the events");
1716 int64_t lastPulseBin = (it->m_pulsetime.totalNanoseconds() - pulsetimeStart) / pulsetimeDelta;
1718 double bin_end = lastTof;
1720 std::function<bool(
const double,
const double)> compareTof;
1721 std::function<double(
const double,
double)> next_bin;
1725 compareTof = [](
const double lhs,
const double rhs) {
return lhs <
rhs; };
1726 next_bin = [
tolerance](
const double lastTof,
double bin_end) {
1728 while (lastTof >= bin_end)
1734 const auto event_min = std::min_element(
1735 events.cbegin(),
events.cend(), [](
const auto &
left,
const auto &
right) { return left.tof() < right.tof(); });
1736 bin_end = tof_min = event_min->tof();
1739 throw std::runtime_error(
"compressEvents with log binning doesn't work with negative TOF");
1747 compareTof = [](
const double lhs,
const double rhs) {
return lhs <=
rhs; };
1748 next_bin = [
tolerance](
const double lastTof, double) {
return lastTof +
tolerance; };
1752 bin_end = next_bin(lastTof, bin_end);
1755 for (; it !=
events.cend(); ++it) {
1756 const int64_t eventPulseBin = (it->m_pulsetime.totalNanoseconds() - pulsetimeStart) / pulsetimeDelta;
1757 if ((eventPulseBin <= lastPulseBin) && compareTof(it->m_tof, bin_end)) {
1759 weight += it->weight();
1760 errorSquared += it->errorSquared();
1761 double norm = calcNorm(it->errorSquared());
1762 tofNormalization += norm;
1764 totalTof += it->m_tof * norm;
1766 pulsetimes.emplace_back(it->m_pulsetime);
1767 pulsetimeWeights.emplace_back(norm);
1770 if (!pulsetimes.empty()) {
1773 if (pulsetimes.size() == 1) {
1774 out.emplace_back(lastTof, pulsetimes.front(), weight, errorSquared);
1776 out.emplace_back(totalTof / tofNormalization,
1781 if (
tolerance < 0 && eventPulseBin != lastPulseBin)
1786 double norm = calcNorm(it->errorSquared());
1787 totalTof = it->m_tof * norm;
1788 weight = it->weight();
1789 errorSquared = it->errorSquared();
1790 tofNormalization = norm;
1791 lastTof = it->m_tof;
1792 lastPulseBin = eventPulseBin;
1794 pulsetimes.emplace_back(it->m_pulsetime);
1795 pulsetimeWeights.clear();
1796 pulsetimeWeights.emplace_back(norm);
1798 bin_end = next_bin(lastTof, bin_end);
1803 if (!pulsetimes.empty()) {
1806 if (pulsetimes.size() == 1) {
1807 out.emplace_back(lastTof, pulsetimes.front(), weight, errorSquared);
1809 out.emplace_back(totalTof / tofNormalization,
1815 size_t excess_limit = out.size() / 20;
1816 if ((out.capacity() - out.size()) > excess_limit) {
1817 out.shrink_to_fit();
1832 if (this->
empty()) {
1859 if (destination ==
this) {
1861 auto out = std::make_unique<std::vector<WeightedEventNoTime>>();
1891 const std::vector<T> &weight,
const std::vector<T> &
error) {
1893 for (
size_t i = 0; i < weight.size(); ++i) {
1894 const auto errors =
static_cast<float>(
error[i]);
1896 out.emplace_back(tof[i],
static_cast<float>(weight[i]), errors);
1902 const std::shared_ptr<std::vector<double>> histogram_bin_edges,
1904 const auto NUM_BINS = histogram_bin_edges->size() - 1;
1905 std::vector<double> tof(NUM_BINS, 0.);
1906 std::vector<double> normalization(NUM_BINS, 0.);
1907 std::vector<float> weight(NUM_BINS, 0.);
1908 std::vector<float>
error(NUM_BINS, 0.);
1909 for (
const auto &ev :
events) {
1910 const auto &bin_optional = findBin(*histogram_bin_edges.get(), ev.m_tof,
false);
1912 const auto bin = bin_optional.value();
1913 const double norm = calcNorm(ev.m_errorSquared);
1914 tof[bin] += ev.m_tof * norm;
1915 normalization[bin] += norm;
1916 weight[bin] += ev.m_weight;
1917 error[bin] += ev.m_errorSquared;
1922 std::transform(tof.begin(), tof.end(), normalization.begin(), tof.begin(), std::divides<double>());
1928 const std::shared_ptr<std::vector<double>> histogram_bin_edges) {
1929 if (this->
empty()) {
1934 const auto NUM_BINS = histogram_bin_edges->size() - 1;
1935 const auto xmin =
static_cast<double>(histogram_bin_edges->front());
1941 std::vector<double> tof(NUM_BINS, 0);
1942 std::vector<uint32_t>
count(NUM_BINS, 0);
1943 for (
const auto &ev : *this->
events) {
1944 const auto &bin_optional = findBin(*histogram_bin_edges.get(), ev.m_tof,
false);
1946 const auto bin = bin_optional.value();
1948 tof[bin] += ev.m_tof;
1953 std::transform(tof.begin(), tof.end(),
count.begin(), tof.begin(), std::divides<double>());
1966 if (destination ==
this) {
1968 auto out = std::make_unique<std::vector<WeightedEventNoTime>>();
1990 const double seconds,
EventList *destination) {
1991 if (this->
empty()) {
1994 destination->
weightedEvents = std::make_unique<std::vector<WeightedEvent>>();
1998 throw std::invalid_argument(
"Cannot compress events that do not have pulsetime");
2001 destination->
weightedEvents = std::make_unique<std::vector<WeightedEvent>>();
2006 if (destination ==
this) {
2008 auto out = std::make_unique<std::vector<WeightedEvent>>();
2013 destination->
weightedEvents = std::make_unique<std::vector<WeightedEvent>>();
2038typename std::vector<T>::const_iterator
static findFirstEvent(
const std::vector<T> &events, T seek_tof) {
2039 return std::find_if_not(events.cbegin(), events.cend(), [seek_tof](
const T &
x) { return x < seek_tof; });
2054 const double seek_pulsetime) {
2055 auto itev =
events.cbegin();
2056 auto itev_end =
events.cend();
2059 while ((itev != itev_end) && (
static_cast<double>(itev->pulseTime().totalNanoseconds()) < seek_pulsetime))
2080typename std::vector<T>::const_iterator
2082 const double &tofOffset)
const {
2083 auto itev =
events.cbegin();
2084 auto itev_end =
events.cend();
2087 while ((itev != itev_end) &&
2088 (
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset)) < seek_time))
2105template <
class T>
typename std::vector<T>::iterator
static findFirstEvent(std::vector<T> &events, T seek_tof) {
2106 return std::find_if_not(events.begin(), events.end(), [seek_tof](
const T &
x) { return x < seek_tof; });
2123 size_t x_size =
X.size();
2132 bool mustFill = (
Y.size() == x_size - 1);
2134 Y.resize(x_size - 1, 0.0);
2137 E.resize(x_size - 1, 0.0);
2141 std::fill(
Y.begin(),
Y.end(), 0.0);
2142 std::fill(E.begin(), E.end(), 0.0);
2152 auto itev_end =
events.cend();
2155 if (itev == itev_end)
2162 double tof = itev->tof();
2163 while (bin < x_size - 1) {
2165 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
2168 Y[bin] += double(itev->m_weight);
2169 E[bin] += double(itev->m_errorSquared);
2178 while ((itev != itev_end) && (bin < x_size - 1)) {
2180 while (bin < x_size - 1) {
2184 if (tof <
X[bin + 1]) {
2187 Y[bin] += double(itev->m_weight);
2188 E[bin] += double(itev->m_errorSquared);
2198 std::transform(E.cbegin(), E.cend(), E.begin(),
static_cast<double (*)(
double)
>(sqrt));
2218 size_t x_size =
X.size();
2227 bool mustFill = (
Y.size() == x_size - 1);
2228 Y.resize(x_size - 1, 0.0);
2229 E.resize(x_size - 1, 0.0);
2232 std::fill(
Y.begin(),
Y.end(), 0.0);
2233 std::fill(E.begin(), E.end(), 0.0);
2239 const auto xmin =
X.front();
2240 const auto xmax =
X.back();
2242 auto findBin =
FindBin(step, xmin);
2244 for (
const T &ev :
events) {
2245 const double tof = ev.tof();
2246 if (tof < xmin || tof >= xmax)
2249 std::optional<size_t> n_bin = findBin(
X, tof,
true);
2252 Y[n_bin.value()] += ev.weight();
2253 E[n_bin.value()] += ev.errorSquared();
2258 std::transform(E.cbegin(), E.cend(), E.begin(),
static_cast<double (*)(
double)
>(sqrt));
2284 throw std::runtime_error(
"Cannot histogram by pulse time on Weighted "
2285 "Events currently");
2288 throw std::runtime_error(
"Cannot histogram by pulse time on Weighted Events NoTime");
2304 const double &tofOffset,
bool skipError)
const {
2317 throw std::runtime_error(
"Cannot histogram by time at sample on Weighted "
2318 "Events currently");
2321 throw std::runtime_error(
"Cannot histogram by time at sample on Weighted Events NoTime");
2374 bool skipError)
const {
2405 size_t x_size =
X.size();
2416 Y.resize(x_size - 1, 0);
2421 if (!this->
events->empty()) {
2424 auto itev_end =
events->cend();
2427 if (itev == itev_end)
2435 double pulsetime =
static_cast<double>(itev->pulseTime().totalNanoseconds());
2436 while (bin < x_size - 1) {
2438 if ((pulsetime >=
X[bin]) && (pulsetime <
X[bin + 1])) {
2448 while ((itev != itev_end) && (bin < x_size - 1)) {
2449 pulsetime =
static_cast<double>(itev->pulseTime().totalNanoseconds());
2450 while (bin < x_size - 1) {
2452 if ((pulsetime >=
X[bin]) && (pulsetime <
X[bin + 1])) {
2478 const double TOF_min,
const double TOF_max)
const {
2480 if (this->
events->empty())
2483 size_t nBins =
Y.size();
2488 double step = (xMax - xMin) /
static_cast<double>(nBins);
2490 for (
const TofEvent &ev : *this->
events) {
2491 double pulsetime =
static_cast<double>(ev.pulseTime().totalNanoseconds());
2492 if (pulsetime < xMin || pulsetime >= xMax)
2494 if (ev.tof() < TOF_min || ev.tof() >= TOF_max)
2497 auto n_bin =
static_cast<size_t>((pulsetime - xMin) / step);
2512 const double &tofOffset)
const {
2514 const size_t x_size =
X.size();
2525 Y.resize(x_size - 1, 0);
2530 if (!this->
events->empty()) {
2533 std::vector<TofEvent>::const_iterator itev_end =
events->end();
2536 if (itev == itev_end)
2542 auto tAtSample =
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset));
2543 while (bin < x_size - 1) {
2545 if ((tAtSample >=
X[bin]) && (tAtSample <
X[bin + 1])) {
2555 while ((itev != itev_end) && (bin < x_size - 1)) {
2556 tAtSample =
static_cast<double>(calculateCorrectedFullTime(*itev, tofFactor, tofOffset));
2557 while (bin < x_size - 1) {
2559 if ((tAtSample >=
X[bin]) && (tAtSample <
X[bin + 1])) {
2578 size_t x_size =
X.size();
2589 Y.resize(x_size - 1, 0);
2595 if (!this->
events->empty()) {
2599 const auto itend = this->
events->end();
2601 for (
auto itx =
X.cbegin(); itev != itend; ++itev) {
2602 const double tof = itev->tof();
2603 itx = std::find_if(itx,
X.cend(), [tof](
const double x) { return tof < x; });
2604 if (itx ==
X.cend()) {
2607 const auto bin =
static_cast<size_t>(std::max(std::distance(
X.cbegin(), itx) - 1, std::ptrdiff_t{0}));
2624 const double offset,
const bool findExact) {
2625 const auto bin =
static_cast<size_t>(tof * divisor - offset);
2626 if (bin >=
X.size())
2627 return std::nullopt;
2653 const double offset,
const bool findExact) {
2654 const auto bin =
static_cast<size_t>(log(tof) * divisor - offset);
2655 if (bin >=
X.size())
2656 return std::nullopt;
2672 auto tof_of_bin =
X.cbegin() + n_bin;
2673 if (tof < *tof_of_bin)
2674 return std::move(n_bin - 1);
2678 if (tof >= *tof_of_bin)
2679 return std::move(n_bin + 1);
2682 return std::move(n_bin);
2698 size_t x_size =
X.size();
2707 bool mustFill = (
Y.size() == x_size - 1);
2709 Y.resize(x_size - 1, 0);
2711 std::fill(
Y.begin(),
Y.end(), 0.0);
2714 if (this->
events->empty())
2717 const auto xmin =
X.front();
2718 const auto xmax =
X.back();
2720 auto findBin =
FindBin(step, xmin);
2722 for (
const TofEvent &ev : *this->
events) {
2723 const double tof = ev.tof();
2724 if (tof < xmin || tof >= xmax)
2727 const std::optional<size_t> n_bin = findBin(
X, tof,
true);
2744 E.resize(
Y.size(), 0);
2747 std::transform(
Y.cbegin(),
Y.cend(), E.begin(),
static_cast<double (*)(
double)
>(sqrt));
2763 double &sum,
double &
error) {
2771 auto lowit =
events.cbegin();
2772 auto highit =
events.cend();
2781 if (lowit->tof() < minX)
2782 lowit = std::lower_bound(
events.cbegin(),
events.cend(), minX);
2784 if ((highit - 1)->tof() > maxX) {
2785 highit = std::upper_bound(lowit,
events.cend(), T(maxX));
2790 for (
auto it = lowit; it != highit; ++it) {
2791 sum += it->weight();
2792 error += it->errorSquared();
2807 double sum(0),
error(0);
2822 double &
error)
const {
2842 throw std::runtime_error(
"EventList: invalid event type value was found.");
2860 transform(
x.cbegin(),
x.cend(),
x.begin(), func);
2893 ev.m_tof = func(ev.m_tof);
2939 for (
auto &event :
events) {
2940 event.m_tof =
event.m_tof * factor + offset;
2968 for (
auto &event :
events) {
2969 event.m_pulsetime += seconds;
2980 auto eventIterEnd{
events.end()};
2981 auto secondsIter{seconds.cbegin()};
2982 for (
auto eventIter =
events.begin(); eventIter < eventIterEnd; ++eventIter, ++secondsIter) {
2983 eventIter->m_pulsetime += *secondsIter;
3005 throw std::runtime_error(
"EventList::addPulsetime() called on an event "
3006 "list with no pulse times. You must call this "
3007 "algorithm BEFORE CompressEvents.");
3021 throw std::runtime_error(
"");
3033 throw std::runtime_error(
"EventList::addPulsetime() called on an event "
3034 "list with no pulse times. You must call this "
3035 "algorithm BEFORE CompressEvents.");
3051 if (tofMin >
events.crbegin()->tof())
3053 if (tofMax <
events.cbegin()->tof())
3057 auto it_first = std::lower_bound(
events.begin(),
events.end(), tofMin);
3058 if ((it_first !=
events.end()) && (it_first->tof() < tofMax)) {
3061 auto it_last = std::upper_bound(it_first,
events.end(), T(tofMax));
3063 if (it_first >= it_last) {
3064 throw std::runtime_error(
"Event filter is all messed up");
3067 size_t tmp = std::size_t(std::distance(it_first, it_last));
3070 events.erase(it_first, it_last);
3086 if (tofMax <= tofMin)
3087 throw std::runtime_error(
"EventList::maskTof: tofMax must be > tofMin");
3101 numOrig = this->events->size();
3102 numDel = this->
maskTofHelper(*this->events, tofMin, tofMax);
3114 if (numDel >= numOrig)
3129 auto itm = std::find(mask.begin(), mask.end(),
false);
3130 auto first =
events.begin() + (itm - mask.begin());
3132 if (itm != mask.end()) {
3133 for (
auto ite = first; ++ite !=
events.end() && ++itm != mask.end();) {
3134 if (*itm !=
false) {
3135 *first++ = std::move(*ite);
3140 const auto n =
static_cast<size_t>(
events.end() - first);
3157 throw std::runtime_error(
"EventList::maskTof: tofMax must be > tofMin");
3168 numOrig = this->events->size();
3181 if (numDel >= numOrig)
3193 for (
auto itev =
events.cbegin(); itev !=
events.cend(); ++itev)
3194 tofs.emplace_back(itev->m_tof);
3223 std::vector<double> tofs;
3236 weights.reserve(
events.size());
3237 std::transform(
events.cbegin(),
events.cend(), std::back_inserter(weights),
3238 [](
const auto &event) { return event.weight(); });
3268 std::vector<double> weights;
3281 weightErrors.clear();
3282 weightErrors.reserve(
events.size());
3283 std::transform(
events.cbegin(),
events.cend(), std::back_inserter(weightErrors),
3284 [](
const auto &event) { return event.error(); });
3314 std::vector<double> weightErrors;
3316 return weightErrors;
3324template <
typename UnaryOperation>
3326 std::vector<DateAndTime> times;
3329 times.reserve(
events->size());
3330 std::transform(
events->cbegin(),
events->cend(), std::back_inserter(times), timesCalc);
3349 auto timeCalc = [](
const auto &event) {
return event.pulseTime(); };
3355 auto timeCalc = [](
const auto &event) {
return event.pulseTOFTime(); };
3364 auto timeCalc = [factor, shift](
const auto &event) {
return event.pulseTOFTimeAtSample(factor, shift); };
3371template <
class T>
double getTofMinimumHelper(
const std::vector<T> &events) {
3372 const auto result = std::min_element(events.cbegin(), events.cend(),
3373 [](
const auto &
left,
const auto &
right) { return left.tof() < right.tof(); });
3374 return result->tof();
3377template <
class T>
double getTofMaximumHelper(
const std::vector<T> &events) {
3378 const auto result = std::max_element(events.cbegin(), events.cend(),
3379 [](
const auto &
left,
const auto &
right) { return left.tof() < right.tof(); });
3380 return result->tof();
3389 double tMin = std::numeric_limits<double>::max();
3399 return this->events->front().tof();
3410 tMin = getTofMinimumHelper(*this->events);
3431 double tMax = std::numeric_limits<double>::lowest();
3441 return this->events->back().tof();
3452 tMax = getTofMaximumHelper(*this->events);
3470template <
class T> DateAndTime getPulseMinimumHelper(
const std::vector<T> &events) {
3471 const auto result = std::min_element(events.cbegin(), events.cend(), [](
const auto &
left,
const auto &
right) {
3472 return left.pulseTime() < right.pulseTime();
3474 return result->pulseTime();
3477template <
class T> DateAndTime getPulseMaximumHelper(
const std::vector<T> &events) {
3478 const auto result = std::max_element(events.cbegin(), events.cend(), [](
const auto &
left,
const auto &
right) {
3479 return left.pulseTime() < right.pulseTime();
3481 return result->pulseTime();
3491 return DateAndTime::maximum();
3497 return this->events->front().pulseTime();
3508 return getPulseMinimumHelper(*this->events);
3515 return DateAndTime::maximum();
3524 return DateAndTime::minimum();
3530 return this->events->back().pulseTime();
3541 return getPulseMaximumHelper(*this->events);
3548 return DateAndTime::minimum();
3552 Mantid::Types::Core::DateAndTime &tMax)
const {
3554 tMax = DateAndTime::minimum();
3555 tMin = DateAndTime::maximum();
3565 tMin = this->events->front().pulseTime();
3566 tMax = this->events->back().pulseTime();
3582 DateAndTime temp = tMax;
3583 for (
size_t i = 0; i <
numEvents; i++) {
3586 temp = this->events->at(i).pulseTime();
3604 DateAndTime tMax = DateAndTime::minimum();
3614 return calculateCorrectedFullTime(this->events->back(), tofFactor, tofOffset);
3616 return calculateCorrectedFullTime(this->
weightedEvents->back(), tofFactor, tofOffset);
3624 DateAndTime temp = tMax;
3625 for (
size_t i = 0; i <
numEvents; i++) {
3628 temp = calculateCorrectedFullTime(this->events->at(i), tofFactor, tofOffset);
3631 temp = calculateCorrectedFullTime(this->
weightedEvents->at(i), tofFactor, tofOffset);
3645 DateAndTime tMin = DateAndTime::maximum();
3655 return calculateCorrectedFullTime(this->events->front(), tofFactor, tofOffset);
3657 return calculateCorrectedFullTime(this->
weightedEvents->front(), tofFactor, tofOffset);
3665 DateAndTime temp = tMin;
3666 for (
size_t i = 0; i <
numEvents; i++) {
3669 temp = calculateCorrectedFullTime(this->events->at(i), tofFactor, tofOffset);
3672 temp = calculateCorrectedFullTime(this->
weightedEvents->at(i), tofFactor, tofOffset);
3694 size_t x_size = tofs.size();
3695 if (
events.size() != x_size)
3698 for (
size_t i = 0; i < x_size; ++i)
3741 auto itev_end =
events.end();
3745 for (
auto itev =
events.begin(); itev != itev_end; itev++) {
3746 itev->m_errorSquared =
static_cast<float>(itev->m_errorSquared * valueSquared);
3747 itev->m_weight *=
static_cast<float>(
value);
3752 for (
auto itev =
events.begin(); itev != itev_end; itev++) {
3753 itev->m_errorSquared =
3754 static_cast<float>(itev->m_errorSquared * valueSquared + errorSquared * itev->m_weight * itev->m_weight);
3755 itev->m_weight *=
static_cast<float>(
value);
3840 if ((
X.size() < 2) || (
Y.size() != E.size()) || (
X.size() != 1 +
Y.size())) {
3841 std::stringstream msg;
3842 msg <<
"EventList::multiply() was given invalid size or "
3843 "inconsistent histogram arrays: X["
3845 <<
"Y[" <<
Y.size() <<
" E[" << E.size() <<
"]";
3846 throw std::invalid_argument(msg.str());
3849 size_t x_size =
X.size();
3853 auto itev_end =
events.end();
3856 if (itev == itev_end)
3865 double valueSquared;
3866 double errorSquared;
3870 double tof = itev->tof();
3871 while (bin < x_size - 1) {
3873 if ((tof >=
X[bin]) && (tof <
X[bin + 1]))
3885 while ((itev != itev_end) && (bin < x_size - 1)) {
3887 while (bin < x_size - 1) {
3889 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
3891 itev->m_errorSquared =
3892 static_cast<float>(itev->m_errorSquared * valueSquared + errorSquared * itev->m_weight * itev->m_weight);
3893 itev->m_weight *=
static_cast<float>(
value);
3897 if (bin >= x_size - 1)
3965 if ((
X.size() < 2) || (
Y.size() != E.size()) || (
X.size() != 1 +
Y.size())) {
3966 std::stringstream msg;
3967 msg <<
"EventList::divide() was given invalid size or "
3968 "inconsistent histogram arrays: X["
3970 <<
"Y[" <<
Y.size() <<
" E[" << E.size() <<
"]";
3971 throw std::invalid_argument(msg.str());
3974 size_t x_size =
X.size();
3978 auto itev_end =
events.end();
3981 if (itev == itev_end)
3990 double valError_over_value_squared;
3994 double tof = itev->tof();
3995 while (bin < x_size - 1) {
3997 if ((tof >=
X[bin]) && (tof <
X[bin + 1]))
4008 value = std::numeric_limits<float>::quiet_NaN();
4009 valError_over_value_squared = 0;
4014 while ((itev !=
events.end()) && (bin < x_size - 1)) {
4016 while (bin < x_size - 1) {
4018 if ((tof >=
X[bin]) && (tof <
X[bin + 1])) {
4020 double newWeight = itev->m_weight /
value;
4021 itev->m_errorSquared =
static_cast<float>(
4022 newWeight * newWeight *
4023 ((itev->m_errorSquared / (itev->m_weight * itev->m_weight)) + valError_over_value_squared));
4024 itev->m_weight =
static_cast<float>(newWeight);
4028 if (bin >= x_size - 1)
4037 value = std::numeric_limits<float>::quiet_NaN();
4038 valError_over_value_squared = 0;
4100 throw std::invalid_argument(
"EventList::divide() called with value of 0.0. Cannot divide by zero.");
4117 throw std::invalid_argument(
"EventList::divide() called with value of 0.0. Cannot divide by zero.");
4123 double invValue = 1.0 /
value;
4125 double invError = (
error /
value) * invValue;
4127 this->
multiply(invValue, invError);
4145 if (
this == &output) {
4146 throw std::invalid_argument(
"In-place filtering is not allowed");
4168 throw std::runtime_error(
"EventList::filterByPulseTime() called on an "
4169 "EventList that no longer has time information.");
4197 if ((timeRoi ==
nullptr) || (timeRoi->
useAll())) {
4198 throw std::invalid_argument(
"TimeROI can not use all time");
4201 if (intervals.empty())
4212 throw std::runtime_error(
"EventList::filterByPulseTime() called on an "
4213 "EventList that no longer has time information.");
4227 std::vector<T> &output) {
4228 std::copy_if(
events.begin(),
events.end(), std::back_inserter(output),
4229 [start, stop](
const T &t) { return (t.m_pulsetime >= start) && (t.m_pulsetime < stop); });
4242 auto itspl = intervals.cbegin();
4243 auto itspl_end = intervals.cend();
4245 auto itev =
events.cbegin();
4246 auto itev_end =
events.cend();
4249 while (itspl != itspl_end) {
4251 DateAndTime start = itspl->start();
4252 DateAndTime stop = itspl->stop();
4254 while ((itev != itev_end) && (itev->m_pulsetime < start))
4258 while ((itev != itev_end) && (itev->m_pulsetime < stop)) {
4260 const T eventCopy(*itev);
4268 if (itspl == itspl_end)
4272 if (itev == itev_end)
4283 if (timeRoi ==
nullptr) {
4284 throw std::runtime_error(
"TimeROI can not be a nullptr\n");
4287 throw std::invalid_argument(
"TimeROI can not be empty\n");
4301 throw std::runtime_error(
"EventList::filterInPlace() called on an "
4302 "EventList that no longer has time information.");
4338 auto itspl = splitter.cbegin();
4339 auto itspl_end = splitter.cend();
4340 DateAndTime start, stop;
4343 auto itev =
events.begin();
4344 auto itev_end =
events.end();
4348 auto itOut =
events.begin();
4351 while (itspl != itspl_end) {
4353 start = itspl->start();
4354 stop = itspl->stop();
4356 while ((itev != itev_end) && (itev->m_pulsetime < start))
4360 bool copyingInPlace = (itOut == itev);
4361 if (copyingInPlace) {
4362 while ((itev != itev_end) && (itev->m_pulsetime < stop))
4368 while ((itev != itev_end) && (itev->m_pulsetime < stop)) {
4378 if (itspl == itspl_end)
4382 if (itev == itev_end)
4388 events.resize(std::size_t(std::distance(
events.begin(), itOut)));
4398 bool removeDetIDs{
true};
4403 auto initPartial = [&](
EventList *partial) {
4404 partial->clear(removeDetIDs);
4405 partial->copyInfoFrom(*
this);
4406 partial->setHistogram(histogramLocal);
4407 partial->switchTo(eventTypeLocal);
4411 std::for_each(partials.cbegin(), partials.cend(),
4412 [&](
const std::pair<int, EventList *> &pair) { initPartial(pair.second); });
4463 for (
auto &itev :
events) {
4465 const double tof = fromUnit->
singleToTOF(itev.m_tof);
4481 if (!fromUnit || !toUnit)
4482 throw std::runtime_error(
"EventList::convertUnitsViaTof(): one of the units is NULL!");
4484 throw std::runtime_error(
"EventList::convertUnitsViaTof(): fromUnit is not initialized!");
4486 throw std::runtime_error(
"EventList::convertUnitsViaTof(): toUnit is not initialized!");
4510 for (
auto &event :
events) {
4512 event.m_tof = factor * std::pow(event.m_tof, power);
4543 if (
histogram.xMode() != HistogramData::Histogram::XMode::BinEdges)
4544 throw std::runtime_error(
"EventList: setting histogram with storage mode "
4545 "other than BinEdges is not possible");
4547 throw std::runtime_error(
"EventList: setting histogram data with non-null "
4548 "Y or E data is not possible");
4550 if (
histogram.yMode() == HistogramData::Histogram::YMode::Uninitialized)
4553 throw std::runtime_error(
"EventList: setting histogram data with different "
4554 "YMode is not possible");
4558 throw std::runtime_error(
"EventList: setting Points as X data is not "
4559 "possible, only BinEdges are supported");
4563 throw std::runtime_error(
"EventList: Cannot set Y or E data, these data are "
4564 "generated automatically based on the events");
std::vector< float > m_tof
sum of all time-of-flight within the bin
const std::vector< double > & rhs
double value
The value of the point.
#define PARALLEL_THREAD_NUMBER
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.
const HistogramData::HistogramX & x() const
virtual const HistogramData::HistogramE & e() const
void setDetectorIDs(const std::set< detid_t > &detIDs)
Set the detector IDs to be the set given.
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.
Kernel::cow_ptr< HistogramData::HistogramX > sharedX() const
virtual const HistogramData::HistogramY & y() 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.
void setSharedX(const Kernel::cow_ptr< HistogramData::HistogramX > &x) &
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 size_t findExactBin(const MantidVec &X, const double tof, const size_t n_bin)
Find the exact bin which a TOF falls in starting from the provided estimated one.
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.
Mantid::Types::Core::DateAndTime getTimeAtSampleMax(const double &tofFactor, const double &tofOffset) const override
Get the maximum time at sample.
std::vector< 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 maskTof(const double tofMin, const double tofMax) override
Mask out events that have a tof between tofMin and tofMax (inclusively).
EventList(const Mantid::API::EventType event_type=Mantid::API::EventType::TOF)
Constructor (empty)
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.
static std::optional< size_t > findLinearBin(const MantidVec &X, const double tof, const double divisor, const double offset, const bool findExact=true)
Find the bin which this TOF value falls in with linear binning, assumes TOF is in range of X.
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
void convertUnitsViaTofHelper(typename std::vector< T > &events, Mantid::Kernel::Unit const *fromUnit, Mantid::Kernel::Unit const *toUnit)
Helper function for the conversion to TOF.
HistogramData::Counts counts() const override
std::vector< double > getWeights() const override
Return the list of event weight values.
void convertUnitsQuickly(const double &factor, const double &power)
Convert the event's TOF (x) value according to a simple output = a * (input^b) relationship.
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
static void filterByTimeROIHelper(std::vector< T > &events, const std::vector< Kernel::TimeInterval > &intervals, EventList *output)
Filter a vector of events into another based on TimeROI.
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...
~EventList() override
Destructor.
std::vector< Types::Event::TofEvent > & getEvents()
Return the list of TofEvents contained.
HistogramData::FrequencyStandardDeviations frequencyStandardDeviations() const override
void setSortOrder(const EventSortType order) const
Manually set the event list sort order value.
static void processWeightedEvents(const std::vector< T > &events, std::vector< WeightedEventNoTime > &out, const std::shared_ptr< std::vector< double > > histogram_bin_edges, struct FindBin findBin)
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.
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 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
void filterInPlace(const Kernel::TimeROI *timeRoi)
Use a SplittingIntervalVec to filter the event list in place.
std::size_t getNumberEvents() const override
Return the number of events in the list.
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.
void convertUnitsViaTof(Mantid::Kernel::Unit const *fromUnit, Mantid::Kernel::Unit const *toUnit)
Converts the X units in each event by going through TOF.
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.
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.
static void createWeightedEvents(std::vector< WeightedEventNoTime > &out, const std::vector< double > &tof, const std::vector< T > &weight, const std::vector< T > &error)
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)
Append an event to the histogram.
static void minusHelper(std::vector< T1 > &events, const std::vector< T2 > &more_events)
SUBTRACT another EventList from this event list.
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 addPulsetime(const double seconds) override
Add an offset to the pulsetime (wall-clock time) of each event in the list.
HistogramData::Histogram getHistogram() const
Returns a copy of the Histogram associated with this spectrum.
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
MantidVec & dataE() override
Deprecated, use mutableE() instead.
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
std::vector< Types::Core::DateAndTime > getPulseTOFTimes() const
Get the Pulse-time + TOF for each event in this EventList.
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)
std::unique_ptr< std::vector< WeightedEvent > > weightedEvents
List of WeightedEvent's.
void initializePartials(std::map< int, EventList * > partials) const
Initialize the detector ID's and event type of the destination event lists when splitting this list.
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.
std::vector< Types::Core::DateAndTime > eventTimesCalculator(const UnaryOperation ×Calc) const
Compute a time (for instance, pulse-time plus TOF) associated to each event in the list.
void switchTo(Mantid::API::EventType newType) override
Switch the EventList to use the given EventType (TOF, WEIGHTED, or WEIGHTED_NOTIME)
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.
void filterInPlaceHelper(Kernel::TimeROI const *timeRoi, typename std::vector< T > &events)
Perform an in-place filtering on a vector of either TofEvent's or WeightedEvent's.
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.
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.
static std::optional< size_t > findLogBin(const MantidVec &X, const double tof, const double divisor, const double offset, const bool findExact=true)
Find the bin which this TOF value falls in with log binning, assumes TOF is in range of X.
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.
MantidVec * makeDataE() const
Calculates and returns a pointer to the E histogrammed data.
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 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
std::unique_ptr< std::vector< WeightedEventNoTime > > weightedEventsNoTime
List of WeightedEvent's.
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.
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...
std::vector< Types::Core::DateAndTime > getPulseTOFTimesAtSample(const double &factor, const double &shift) const
Get the Pulse-time + time-of-flight of the neutron up to the sample, for each event in this EventList...
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.
std::unique_ptr< std::vector< Types::Event::TofEvent > > events
List of TofEvent (no weights).
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:
TimeROI : Object that holds information about when the time measurement was active.
const std::vector< Kernel::TimeInterval > toTimeIntervals() const
This method is to lend itself to helping with transition.
bool useAll() const
TimeROI selects all time to be used.
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)
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< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
int32_t specnum_t
Typedef for a spectrum Number.
FindBin(double step, double xmin)
std::optional< size_t > operator()(const Mantid::MantidVec &X, const double tof, const bool findExact)
std::optional< size_t >(* findBin)(const Mantid::MantidVec &, const double, const double, const double, const bool)
bool operator()(const TofEvent &e1, const TofEvent &e2)
comparePulseTimeTOFDelta(const Types::Core::DateAndTime &start, const double seconds)