Mantid
Loading...
Searching...
No Matches
SplittingInterval.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9
10namespace Mantid {
11
12using namespace Types::Core;
13namespace Kernel {
14
17
19SplittingInterval::SplittingInterval(const Types::Core::DateAndTime &start, const Types::Core::DateAndTime &stop,
20 const int index)
21 : TimeInterval(start, stop), m_index(index) {}
22
24int SplittingInterval::index() const { return m_index; }
25
29SplittingInterval SplittingInterval::operator&(const SplittingInterval &b) const {
30 const auto &begin = std::max(this->start(), b.start());
31 const auto &end = std::min(this->stop(), b.stop());
32
33 return SplittingInterval(begin, end, this->index());
34}
36
39 if (!this->overlaps(&b))
40 throw std::invalid_argument("SplittingInterval: cannot apply the OR (|) "
41 "operator to non-overlapping "
42 "SplittingInterval's.");
43
44 const auto &begin = std::min(this->start(), b.start());
45 const auto &end = std::max(this->stop(), b.stop());
46
47 return SplittingInterval(begin, end, this->index());
48}
49
51 if (TimeInterval::operator==(ti)) {
52 return index() == ti.index();
53 } else {
54 return false;
55 }
56}
57
59 std::stringstream ss;
60 ss << this->begin_str() << " to " << this->end_str();
61 ss << " index: " << index();
62 ss << std::endl;
63 return ss.str();
64}
65//------------------------------------------------------------------------------------------------
70 int max = -1;
71 SplittingIntervalVec::const_iterator it;
72 for (it = a.begin(); it != a.end(); ++it)
73 if (it->index() > max)
74 max = it->index();
75 return (max <= 0);
76}
77
78//------------------------------------------------------------------------------------------------
89 bool a_filter, b_filter;
90 a_filter = isFilter(a);
91 b_filter = isFilter(b);
92
93 if (a_filter && b_filter) {
94 return a & b;
95 } else if (a_filter && !b_filter) {
96 return b & a;
97 } else if (!a_filter && b_filter) {
98 return a & b;
99 } else // (!a_filter && !b_filter)
100 {
101 // Both are splitters.
102 throw std::invalid_argument("Cannot combine two splitters together, as the "
103 "output is undefined. Try splitting each "
104 "output workspace by b after the a split has "
105 "been done.");
106 }
107}
108
109//------------------------------------------------------------------------------------------------
122 // If either is empty, then no entries in the filter (aka everything is
123 // removed)
124 if ((a.empty()) || (b.empty()))
125 return out;
126
127 SplittingIntervalVec::const_iterator ait;
128 SplittingIntervalVec::const_iterator bit;
129
130 // For now, a simple double iteration. Can be made smarter if a and b are
131 // sorted.
132 for (ait = a.begin(); ait != a.end(); ++ait) {
133 for (bit = b.begin(); bit != b.end(); ++bit) {
134 if (ait->overlaps(&(*bit))) {
135 // The & operator for SplittingInterval keeps the index of the
136 // left-hand-side (ait in this case)
137 // meaning that a has to be the splitter because the b index is
138 // ignored.
139 out.emplace_back(*ait & *bit);
140 }
141 }
142 }
143 return out;
144}
145
146//------------------------------------------------------------------------------------------------
153 out.reserve(a.size());
154
155 // Now we have to merge duplicate/overlapping intervals together
156 auto it = a.cbegin();
157 while (it != a.cend()) {
158 // All following intervals will start at or after this one
159 const DateAndTime &start = it->start();
160 DateAndTime stop = it->stop();
161
162 // Keep looking for the next interval where there is a gap (start > old
163 // stop);
164 while ((it != a.cend()) && (it->start() <= stop)) {
165 // Extend the stop point (the start cannot be extended since the list is
166 // sorted)
167 if (it->stop() > stop)
168 stop = it->stop();
169 ++it;
170 }
171 // We've reached a gap point. Output this merged interval and move on.
172 out.emplace_back(start, stop, 0);
173 }
174
175 return out;
176}
177
178//------------------------------------------------------------------------------------------------
188 // Concatenate the two lists
190 auto isValid = [](const SplittingInterval &value) { return value.isValid(); };
191 std::copy_if(a.begin(), a.end(), std::back_insert_iterator(temp), isValid);
192 std::copy_if(b.begin(), b.end(), std::back_insert_iterator(temp), isValid);
193
194 // Sort by start time rather than the default
195 auto compareStart = [](const SplittingInterval &left, const SplittingInterval &right) {
196 return left.start() < right.start();
197 };
198 std::sort(temp.begin(), temp.end(), compareStart);
199
201
202 return out;
203}
204
205//------------------------------------------------------------------------------------------------
213 SplittingIntervalVec out, temp;
214 // First, you must remove any overlapping intervals, otherwise the output is
215 // stupid.
216 temp = removeFilterOverlap(a);
217
218 // No entries: then make a "filter" that keeps everything
219 if ((temp.empty())) {
220 out.emplace_back(DateAndTime::minimum(), DateAndTime::maximum(), 0);
221 return out;
222 }
223
224 SplittingIntervalVec::const_iterator ait;
225 ait = temp.begin();
226 if (ait != temp.end()) {
227 // First entry; start at -infinite time
228 out.emplace_back(DateAndTime::minimum(), ait->start(), 0);
229 // Now start at the second entry
230 while (ait != temp.end()) {
231 DateAndTime start, stop;
232 start = ait->stop();
233 ++ait;
234 if (ait == temp.end()) { // Reached the end - go to inf
235 stop = DateAndTime::maximum();
236 } else { // Stop at the start of the next entry
237 stop = ait->start();
238 }
239 out.emplace_back(start, stop, 0);
240 }
241 }
242 return out;
243}
244
245//------------------------------------------------------------------------------------------------
250std::map<int, Kernel::TimeROI> timeROIsFromSplitters(const SplittingIntervalVec &splitters) {
251 std::map<int, Kernel::TimeROI> roisMap;
252 for (auto const &splitter : splitters) {
253 // some input SplittingInterval can have same `begin` and `end` time, which is disallowed for a TimeROI object
254 if (splitter.start() >= splitter.stop())
255 continue;
256 int destinationIndex = splitter.index(); // if existing, nonsense index -1 will also have its TimeROI
257 if (roisMap.find(destinationIndex) == roisMap.end()) // first time we encounter destinationIndex
258 roisMap.insert({destinationIndex, TimeROI(splitter.start(), splitter.stop())});
259 else
260 roisMap[destinationIndex].addROI(splitter.start(), splitter.stop());
261 }
262 return roisMap;
263}
264
265} // namespace Kernel
266} // namespace Mantid
double value
The value of the point.
Definition FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
double left
double right
Class holding a start/end time and a destination for splitting event lists and logs.
int index() const
Return the index (destination of this split time block)
int m_index
Index of the destination.
bool operator==(const SplittingInterval &ti) const
SplittingInterval operator|(const SplittingInterval &b) const
Or operator. Return the largest time interval.
Represents a time interval.
Definition DateAndTime.h:25
const Types::Core::DateAndTime & start() const
Beginning of the interval.
Definition DateAndTime.h:34
bool overlaps(const TimeInterval *other) const
Return true if the SplittingInterval overlaps with this one.
const Types::Core::DateAndTime & stop() const
End of the interval.
Definition DateAndTime.h:36
std::string end_str() const
String representation of the end time.
std::string begin_str() const
String representation of the begin time.
TimeROI : Object that holds information about when the time measurement was active.
Definition TimeROI.h:18
MANTID_KERNEL_DLL SplittingIntervalVec operator~(const SplittingIntervalVec &a)
NOT operator for SplittingIntervalVec Only works on Filters.
bool isFilter(const SplittingIntervalVec &a)
Return true if the SplittingIntervalVec provided is a filter, meaning that it only has an output inde...
MANTID_KERNEL_DLL std::map< int, TimeROI > timeROIsFromSplitters(const SplittingIntervalVec &splitters)
For every workspace index, create a TimeROI out of its associated splitting intervals.
MANTID_KERNEL_DLL SplittingIntervalVec operator|(const SplittingIntervalVec &a, const SplittingIntervalVec &b)
OR operator for SplittingIntervalVec Only works on Filters, not splitters.
std::vector< SplittingInterval > SplittingIntervalVec
A typedef for splitting events according their pulse time.
Definition LogManager.h:28
MANTID_KERNEL_DLL SplittingIntervalVec operator&(const SplittingIntervalVec &a, const SplittingIntervalVec &b)
AND operator for SplittingIntervalVec Works on Filters - combines them to only keep times where both ...
SplittingIntervalVec removeFilterOverlap(const SplittingIntervalVec &a)
Remove any overlap in a filter (will not work properly on a splitter)
MANTID_KERNEL_DLL SplittingIntervalVec operator+(const SplittingIntervalVec &a, const SplittingIntervalVec &b)
Plus operator for SplittingIntervalVec.
Helper class which provides the Collimation Length for SANS instruments.