Newer
Older
#ifndef MANTID_KERNEL_TIMESERIESPROPERTY_H_
#define MANTID_KERNEL_TIMESERIESPROPERTY_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/DateAndTime.h"
#include "MantidKernel/DllConfig.h"
#include "MantidKernel/ITimeSeriesProperty.h"
#include "MantidKernel/Property.h"
#include "MantidKernel/Statistics.h"
namespace Mantid {
namespace Kernel {
class DataItem;
class SplittingInterval;
enum TimeSeriesSortStatus { TSUNKNOWN, TSUNSORTED, TSSORTED };
//=========================================================================
/** Struct holding some useful statistics for a TimeSeriesProperty
*
*/
struct TimeSeriesPropertyStatistics {
/// Minimum value
double minimum;
/// Maximum value
double maximum;
/// Mean value
double mean;
/// Median value
double median;
/// standard_deviation of the values
double standard_deviation;
/// Duration in seconds
double duration;
};
//================================================================================================
/**
* Class to hold unit value (DateAndTime, T)
*/
template <class TYPE> class TimeValueUnit {
private:
Types::Core::DateAndTime mtime;
TimeValueUnit(const Types::Core::DateAndTime &time, TYPE value) {
mtime = time;
mvalue = value;
}
~TimeValueUnit() = default;
bool operator>(const TimeValueUnit &rhs) { return (mtime > rhs.mtime); }
friend bool operator>(const TimeValueUnit &lhs, const TimeValueUnit &rhs) {
return (lhs.mtime > rhs.mtime);
}
bool operator==(const TimeValueUnit &rhs) { return (mtime == rhs.mtime); }
friend bool operator==(const TimeValueUnit &lhs, const TimeValueUnit &rhs) {
return (lhs.mtime == rhs.mtime);
}
bool operator<(const TimeValueUnit &rhs) { return (mtime < rhs.mtime); }
friend bool operator<(const TimeValueUnit &lhs, const TimeValueUnit &rhs) {
return (lhs.mtime < rhs.mtime);
}
Types::Core::DateAndTime time() const { return mtime; }
void setTime(Types::Core::DateAndTime newtime) { mtime = newtime; }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
TYPE value() const { return mvalue; }
static bool valueCmp(const TimeValueUnit &lhs, const TimeValueUnit &rhs) {
return (lhs.mvalue < rhs.mvalue);
}
};
//========================================================================================================
/**
A specialised Property class for holding a series of time-value pairs.
Copyright © 2007-2010 ISIS Rutherford Appleton Laboratory, NScD Oak
Ridge National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
template <typename TYPE>
class DLLExport TimeSeriesProperty : public Property,
public ITimeSeriesProperty {
public:
/// Constructor
explicit TimeSeriesProperty(const std::string &name);
/// Virtual destructor
~TimeSeriesProperty() override;
TimeSeriesProperty<TYPE> *clone() const override;
//
/// Return time series property, containing time derivative of current
/// property
std::unique_ptr<TimeSeriesProperty<double>> getDerivative() const;
void saveProperty(::NeXus::File *file) override;
/// "Virtual" copy constructor with a time shift in seconds
Property *cloneWithTimeShift(const double timeShift) const override;
/// Return the memory used by the property, in bytes
size_t getMemorySize() const override;
/// Merge the given property with this one
TimeSeriesProperty<TYPE> &merge(Property *rhs) override;
//--------------------------------------------------------------------------------------
/// Add the value of another property
TimeSeriesProperty &operator+=(Property const *right) override;
/// Deep comparison
virtual bool operator==(const TimeSeriesProperty<TYPE> &right) const;
/// Deep comparison (not equal).
virtual bool operator!=(const TimeSeriesProperty<TYPE> &right) const;
/// Deep comparison
virtual bool operator==(const Property &right) const;
/// Deep comparison (not equal).
virtual bool operator!=(const Property &right) const;
/// Set name of property
void setName(const std::string name);
/// Filter out a run by time.
void filterByTime(const Types::Core::DateAndTime &start,
const Types::Core::DateAndTime &stop) override;
/// Filter by a range of times
void filterByTimes(const std::vector<SplittingInterval> &splittervec);
/// Split out a time series property by time intervals.
void splitByTime(std::vector<SplittingInterval> &splitter,
std::vector<Property *> outputs,
bool isPeriodic) const override;
/// New split method
splitByTimeVector(std::vector<Types::Core::DateAndTime> &splitter_time_vec,
std::vector<int> &target_vec,
std::vector<TimeSeriesProperty *> outputs);
/// Fill a TimeSplitterType that will filter the events by matching
void makeFilterByValue(std::vector<SplittingInterval> &split, double min,
double max, double TimeTolerance = 0.0,
bool centre = false) const override;
/// Make sure an existing filter covers the full time range given
void expandFilterToRange(std::vector<SplittingInterval> &split, double min,
double max,
const TimeInterval &range) const override;
/// Calculate the time-weighted average of a property in a filtered range
double averageValueInFilter(
const std::vector<SplittingInterval> &filter) const override;
/// @copydoc Mantid::Kernel::ITimeSeriesProperty::averageAndStdDevInFilter()
std::pair<double, double> averageAndStdDevInFilter(
const std::vector<SplittingInterval> &filter) const override;
/// Calculate the time-weighted average of a property
double timeAverageValue() const override;
/// @copydoc Mantid::Kernel::ITimeSeriesProperty::timeAverageValueAndStdDev()
std::pair<double, double> timeAverageValueAndStdDev() const override;
/// generate constant time-step histogram from the property values
void histogramData(const Types::Core::DateAndTime &tMin,
const Types::Core::DateAndTime &tMax,
std::vector<double> &counts) const;
/// Return the time series as a correct C++ map<DateAndTime, TYPE>. All
/// values
std::map<Types::Core::DateAndTime, TYPE> valueAsCorrectMap() const;
/// Return the time series's values (unfiltered) as a vector<TYPE>
std::vector<TYPE> valuesAsVector() const;
/// Return the time series as a correct C++ multimap<DateAndTime, TYPE>. All
/// values
std::multimap<Types::Core::DateAndTime, TYPE> valueAsMultiMap() const;
/// Get filtered values as a vector
std::vector<TYPE> filteredValuesAsVector() const;
/// Return the time series's times as a vector<DateAndTime>
std::vector<Types::Core::DateAndTime> timesAsVector() const override;
/// Return the series as list of times, where the time is the number of
/// seconds since the start.
std::vector<double> timesAsVectorSeconds() const;
/// Add a value to the map using a DateAndTime object
void addValue(const Types::Core::DateAndTime &time, const TYPE value);
/// Add a value to the map using a string time
void addValue(const std::string &time, const TYPE value);
/// Add a value to the map using a time_t
void addValue(const std::time_t &time, const TYPE value);
/// Adds vectors of values to the map. Should be much faster than repeated
/// calls to addValue.
void addValues(const std::vector<Types::Core::DateAndTime> ×,
const std::vector<TYPE> &values);
/// Replaces the time series with new values time series values
void replaceValues(const std::vector<Types::Core::DateAndTime> ×,
Types::Core::DateAndTime lastTime() const;
/// Returns the first value regardless of filter
TYPE firstValue() const;
/// Returns the first time regardless of filter
Types::Core::DateAndTime firstTime() const;
/// Returns the last value
TYPE lastValue() const;
/// Returns the minimum value found in the series
TYPE minValue() const;
/// Returns the maximum value found in the series
TYPE maxValue() const;
/// Returns the number of values at UNIQUE time intervals in the time series
int size() const override;
/// Returns the real size of the time series property map:
int realSize() const override;
// ==== The following functions are specific to the odd mechanism of
// FilterByLogValue =========
/// Get the time series property as a string of 'time value'
std::string value() const override;
/// New method to return time series value pairs as std::vector<std::string>
std::vector<std::string> time_tValue() const;
/// Return the time series as a C++ map<DateAndTime, TYPE>
std::map<Types::Core::DateAndTime, TYPE> valueAsMap() const;
// ============================================================================================
/// Set a property from a string
std::string setValue(const std::string &) override;
/// Set a property from a DataItem
std::string setDataItem(const boost::shared_ptr<DataItem>) override;
/// Deletes the series of values in the property
void clear() override;
/// Deletes all but the 'last entry' in the property
void clearOutdated() override;
/// Clears and creates a TimeSeriesProperty from these parameters
void create(const Types::Core::DateAndTime &start_time,
const std::vector<double> &time_sec,
const std::vector<TYPE> &new_values);
/// Clears and creates a TimeSeriesProperty from these parameters
void create(const std::vector<Types::Core::DateAndTime> &new_times,
const std::vector<TYPE> &new_values);
/// Returns the value at a particular time
TYPE getSingleValue(const Types::Core::DateAndTime &t) const;
/// Returns the value at a particular time
TYPE getSingleValue(const Types::Core::DateAndTime &t, int &index) const;
/// Returns n-th valid time interval, in a very inefficient way.
TimeInterval nthInterval(int n) const;
/// Returns n-th value of n-th interval in an incredibly inefficient way.
TYPE nthValue(int n) const;
/// Returns n-th time. NOTE: Complexity is order(n)! regardless of filter
Types::Core::DateAndTime nthTime(int n) const;
/// Divide the property into allowed and disallowed time intervals according
/// to \a filter.
void filterWith(const TimeSeriesProperty<bool> *filter);
/// Restores the property to the unsorted state
void clearFilter();
/// Updates size()
void countSize() const;
/// Check if str has the right time format
static bool isTimeString(const std::string &str);
/// This doesn't check anything -we assume these are always valid
std::string isValid() const override;
std::string getDefault() const override;
/// Returns if the value is at the default
bool isDefault() const override;
/// Return a TimeSeriesPropertyStatistics object
TimeSeriesPropertyStatistics getStatistics() const;
/// Detects whether there are duplicated entries (of time) in property &
/// eliminates them
void eliminateDuplicates();
/// Stringize the property
std::string toString() const;
/**Reserve memory for efficient adding values to existing property
* makes sense only when you have reasonably precise estimate of the
* total size you'll need easily available in advance. */
void reserve(size_t size) { m_values.reserve(size); };
/// If filtering by log, get the time intervals for splitting
std::vector<Mantid::Kernel::SplittingInterval> getSplittingIntervals() const;
//----------------------------------------------------------------------------------------------
/// Saves the time vector has time + start attribute
void saveTimeVector(::NeXus::File *file);
/// Sort the property into increasing times, if not already sorted
void sortIfNecessary() const;
/// Find the index of the entry of time t in the mP vector (sorted)
int findIndex(Types::Core::DateAndTime t) const;
/// Find the upper_bound of time t in container.
int upperBound(Types::Core::DateAndTime t, int istart, int iend) const;
/// Apply a filter
void applyFilter() const;
/// A new algorithm to find Nth index. It is simple and leave a lot work to
/// the callers
size_t findNthIndexFromQuickRef(int n) const;
/// Set a value from another property
std::string setValueFromProperty(const Property &right) override;
/// Find if time lies in a filtered region
bool isTimeFiltered(const Types::Core::DateAndTime &time) const;
/// Holds the time series data
mutable std::vector<TimeValueUnit<TYPE>> m_values;
/// The number of values (or time intervals) in the time series. It can be
/// different from m_propertySeries.size()
mutable int m_size;
/// Flag to state whether mP is sorted or not
mutable TimeSeriesSortStatus m_propSortedFlag;
/// The filter
mutable std::vector<std::pair<Types::Core::DateAndTime, bool>> m_filter;
/// Quick reference regions for filter
mutable std::vector<std::pair<size_t, size_t>> m_filterQuickRef;
/// True if a filter has been applied
mutable bool m_filterApplied;
};
/// Function filtering double TimeSeriesProperties according to the requested
/// statistics.
double DLLExport
filterByStatistic(TimeSeriesProperty<double> const *const propertyToFilter,
Lamar Moore
committed
Kernel::Math::StatisticType statisticType);
} // namespace Mantid
#endif /*MANTID_KERNEL_TIMESERIESPROPERTY_H_*/