Mantid
Loading...
Searching...
No Matches
LogFilter.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 +
11
12namespace Mantid::Kernel {
13
14namespace {
15// local name for a time that has been made with the default constructor
16const DateAndTime UNSET_TIME(DateAndTime::GPS_EPOCH);
17} // namespace
18
27 : m_prop(), m_filter(std::make_unique<TimeSeriesProperty<bool>>("filter")) {
29}
30
36LogFilter::LogFilter(const Property *prop) : m_filter(std::make_unique<TimeSeriesProperty<bool>>("filter")) {
38}
39
45 : m_filter(std::make_unique<TimeSeriesProperty<bool>>("filter")) {
46 m_prop.reset(convertToTimeSeriesOfDouble(timeSeries));
47}
48
56 // do nothing with empty filter
57 if (filter.size() == 0)
58 return;
59 // a single value of one at default GPS epoch is also ignorable
60 if (filter.size() == 1 && filter.firstTime() == UNSET_TIME)
61 return;
62
63 // clear the filter first
64 if (m_prop) {
65 m_prop->clearFilter();
66 }
67
68 // get a local copy of the values for a check further down
69 const auto values = filter.valuesAsVector();
70
71 // If the filter ends in USE
72 bool filterOpenEnded;
73
74 if (std::find(values.cbegin(), values.cend(), true) == values.cend()) {
75 // reset the filter to empty if the new one is all ignore
76 // this assumes that the filter is non-empty because
77 // that is checked for above
78 filterOpenEnded = false;
79 this->setFilter(TimeROI(), filterOpenEnded);
80 } else if (!m_filter || m_filter->size() == 0) {
81 // clean-up and replace current filter
82 filterOpenEnded = filter.lastValue();
83
84 // TimeROI constructor does a ton of cleanup
85 TimeROI mine(&filter);
86
87 // put the results back into the TimeSeriesProperty
88 this->setFilter(mine, filterOpenEnded);
89 } else {
90 // determine if the current version of things are open-ended
91 filterOpenEnded = (m_filter->lastValue() && filter.lastValue());
92
93 // create a local copy of both filters to add extra values to
94 auto filter1 = m_filter.get();
95 auto filter2 = std::unique_ptr<TimeSeriesProperty<bool>>(filter.clone());
96
97 TimeInterval time1 = filter1->nthInterval(filter1->size() - 1);
98 TimeInterval time2 = filter2->nthInterval(filter2->size() - 1);
99
100 if (time1.start() < time2.start()) {
101 filter1->addValue(time2.start(),
102 true); // should be f1->lastValue, but it doesnt
103 // matter for boolean AND
104 } else if (time2.start() < time1.start()) {
105 filter2->addValue(time1.start(), true);
106 }
107
108 // temporary objects to handle the intersection calculation
109 TimeROI mine(filter1);
110 TimeROI theirs(filter2.get());
111 mine.update_intersection(theirs);
112
113 // put the results into the TimeSeriesProperty
114 this->setFilter(mine, filterOpenEnded);
115 }
116
117 // apply the filter to the property
118 if (m_prop) {
119 // create a TimeROI to apply
120 TimeROI timeroi;
121
122 // if the end point is a open, then the last point in the TimeROI needs to be modified to make things work out
123 if (filterOpenEnded) {
124 if (m_filter->size() == 1 && m_filter->lastValue()) {
125 // create a pretend ROI from the start to the year 2100
126 timeroi.addROI(m_filter->lastTime(), DateAndTime("2100-Jan-01 00:00:01"));
127 } else {
128 // default constructor is fine
129 timeroi = TimeROI(m_filter.get());
130 }
131
132 // do a test filtering so the second to last interval can be inspected
133 m_prop->filterWith(timeroi);
134 // determine how far out to adjust the last ROI
135 const auto mysize = m_prop->size();
136 const auto penultimate_interval = m_prop->nthInterval(mysize - 2);
137 const auto ultimate_interval = m_prop->nthInterval(mysize - 1);
138 const auto oldEnd = ultimate_interval.stop();
139 const auto newEnd = ultimate_interval.start() + penultimate_interval.length();
140 // extend or shrink the last ROI depending on which value is bigger
141 if (oldEnd > newEnd)
142 timeroi.addMask(newEnd, ultimate_interval.stop());
143 else if (newEnd > oldEnd)
144 timeroi.addROI(oldEnd, newEnd);
145 // both ends match (lucky guess earlier) so there is nothing to adjust
146 } else {
147 timeroi = TimeROI(m_filter.get());
148 }
149
150 // apply the filter
151 m_prop->filterWith(timeroi);
152 }
153}
154
155//-------------------------------------------------------------------------------------------------
158 if (m_prop)
159 m_prop->clearFilter();
160 m_filter.reset();
161}
162
163//--------------------------------------------------------------------------------------------------
164// Private methods
165//--------------------------------------------------------------------------------------------------
166namespace {
167template <typename SrcType> struct ConvertToTimeSeriesDouble {
168 static FilteredTimeSeriesProperty<double> *apply(const Property *prop) {
169 auto srcTypeSeries = dynamic_cast<const TimeSeriesProperty<SrcType> *>(prop);
170 if (!srcTypeSeries)
171 return nullptr;
172 auto converted = new FilteredTimeSeriesProperty<double>(prop->name());
173 auto pmap = srcTypeSeries->valueAsMap();
174 for (auto it = pmap.begin(); it != pmap.end(); ++it) {
175 converted->addValue(it->first, double(it->second));
176 }
177 return converted;
178 }
179};
180} // namespace
181
190 if (auto doubleSeries = ConvertToTimeSeriesDouble<double>::apply(prop)) {
191 return doubleSeries;
192 } else if (auto doubleSeries = ConvertToTimeSeriesDouble<int>::apply(prop)) {
193 return doubleSeries;
194 } else if (auto doubleSeries = ConvertToTimeSeriesDouble<bool>::apply(prop)) {
195 return doubleSeries;
196 } else {
197 throw std::invalid_argument("LogFilter::convertToTimeSeriesOfDouble - Cannot convert property, \"" + prop->name() +
198 "\", to double series.");
199 }
200}
201
202void LogFilter::setFilter(const TimeROI &roi, const bool filterOpenEnded) {
203 // put the results into the TimeSeriesProperty
204 std::vector<bool> values;
205 std::vector<DateAndTime> times;
206 for (const auto &splitter : roi.toTimeIntervals()) {
207 values.emplace_back(true);
208 values.emplace_back(false);
209 times.emplace_back(splitter.start());
210 times.emplace_back(splitter.stop());
211 }
212 // if both are open ended, remove the ending
213 if (filterOpenEnded) {
214 times.pop_back();
215 values.pop_back();
216 }
217
218 // set as the filter
219 if (!m_filter) {
220 m_filter = std::make_unique<TimeSeriesProperty<bool>>("filter");
221 }
222 m_filter->replaceValues(times, values);
223}
224
225} // namespace Mantid::Kernel
Templated class that defines a filtered time series but still gives access to the original data.
std::unique_ptr< FilteredTimeSeriesProperty< double > > m_prop
Owned pointer to the filtered property.
Definition LogFilter.h:66
void clear()
Clears filters.
const TimeSeriesProperty< bool > * filter() const
Returns a reference to the filter.
Definition LogFilter.h:55
void addFilter(const TimeSeriesProperty< bool > &filter)
Adds a filter using boolean AND.
Definition LogFilter.cpp:55
FilteredTimeSeriesProperty< double > * convertToTimeSeriesOfDouble(const Property *prop)
Converts the given property to a TimeSeriesProperty<double>, throws if invalid.
std::unique_ptr< TimeSeriesProperty< bool > > m_filter
Owned pointer to the filter mask.
Definition LogFilter.h:68
LogFilter()=delete
Disable default constructor.
void setFilter(const TimeROI &roi, const bool filterOpenEnded)
Base class for properties.
Definition Property.h:94
const std::string & name() const
Get the property's name.
Definition Property.cpp:63
Represents a time interval.
Definition DateAndTime.h:25
const Types::Core::DateAndTime & start() const
Beginning of the interval.
Definition DateAndTime.h:34
TimeROI : Object that holds information about when the time measurement was active.
Definition TimeROI.h:18
void addMask(const std::string &startTime, const std::string &stopTime)
Definition TimeROI.cpp:151
const std::vector< Kernel::TimeInterval > toTimeIntervals() const
This method is to lend itself to helping with transition.
Definition TimeROI.cpp:557
void addROI(const std::string &startTime, const std::string &stopTime)
Definition TimeROI.cpp:76
void update_intersection(const TimeROI &other)
Updates the TimeROI values with the intersection with another TimeROI.
Definition TimeROI.cpp:503
A specialised Property class for holding a series of time-value pairs.
TimeSeriesProperty< TYPE > * clone() const override
"Virtual" copy constructor
int size() const override
Returns the number of values at UNIQUE time intervals in the time series.
std::vector< TYPE > valuesAsVector() const
Return the time series's values (unfiltered) as a vector<TYPE>
Types::Core::DateAndTime firstTime() const
Returns the first time regardless of filter.
TYPE lastValue() const
Returns the last value.
Generate a tableworkspace to store the calibration results.
STL namespace.