Newer
Older
#ifndef TIMESERIESPROPERTYTEST_H_
#define TIMESERIESPROPERTYTEST_H_
#include <cxxtest/TestSuite.h>
Gigg, Martyn Anthony
committed
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/make_unique.h"
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/TimeSplitter.h"
Gigg, Martyn Anthony
committed
#include <boost/make_shared.hpp>
Gigg, Martyn Anthony
committed
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
using namespace Mantid::Kernel;
class TimeSeriesPropertyTest : public CxxTest::TestSuite {
// Create a small TSP<double>. Callee owns the returned object.
TimeSeriesProperty<double> *createDoubleTSP() {
TimeSeriesProperty<double> *p =
new TimeSeriesProperty<double>("doubleProp");
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:00", 9.99));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:10", 7.55));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:20", 5.55));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:30", 10.55));
return p;
}
// Create a small TSP<int>. Callee owns the returned object.
TimeSeriesProperty<int> *createIntegerTSP(int numberOfValues) {
TimeSeriesProperty<int> *log = new TimeSeriesProperty<int>("intProp");
DateAndTime startTime("2007-11-30T16:17:00");
for (int value = 0; value < numberOfValues; ++value) {
DateAndTime time = startTime + value * 10.0;
TS_ASSERT_THROWS_NOTHING(log->addValue(time, value + 1));
}
return log;
}
iProp = new TimeSeriesProperty<int>("intProp");
dProp = new TimeSeriesProperty<double>("doubleProp");
sProp = new TimeSeriesProperty<std::string>("stringProp");
}
void tearDown() override {
Russell Taylor
committed
delete iProp;
delete dProp;
delete sProp;
}
// Test that all the base class member variables are correctly assigned to
TS_ASSERT(!iProp->name().compare("intProp"));
TS_ASSERT(!iProp->documentation().compare(""));
TS_ASSERT(typeid(std::vector<TimeValueUnit<int>>) == *iProp->type_info());
TS_ASSERT(!iProp->isDefault())
TS_ASSERT(!dProp->name().compare("doubleProp"));
TS_ASSERT(!dProp->documentation().compare(""));
TS_ASSERT(typeid(std::vector<TimeValueUnit<double>>) ==
*dProp->type_info());
TS_ASSERT(!dProp->isDefault())
TS_ASSERT(!sProp->name().compare("stringProp"));
TS_ASSERT(!sProp->documentation().compare(""));
TS_ASSERT(typeid(std::vector<TimeValueUnit<std::string>>) ==
*sProp->type_info());
TS_ASSERT(!sProp->isDefault())
}
void test_SetValue() {
TS_ASSERT_THROWS(iProp->setValue("1"), Exception::NotImplementedError);
TS_ASSERT_THROWS(dProp->setValue("5.5"), Exception::NotImplementedError);
TS_ASSERT_THROWS(sProp->setValue("aValue"), Exception::NotImplementedError);
}
const std::string tester("2007-11-30T16:17:00");
TS_ASSERT_THROWS_NOTHING(iProp->addValue(tester, 1));
TS_ASSERT_THROWS_NOTHING(iProp->addValue("2007-11-30T16:17:10", 1));
TS_ASSERT_EQUALS(iProp->size(), sizepre + 2);
TS_ASSERT_THROWS_NOTHING(dProp->addValue("2007-11-30T16:17:00", 9.99));
TS_ASSERT_THROWS_NOTHING(dProp->addValue("2007-11-30T16:17:10", 5.55));
TS_ASSERT_EQUALS(dProp->size(), sizepre + 2);
TS_ASSERT_THROWS_NOTHING(sProp->addValue("2007-11-30T16:17:00", "test"));
TS_ASSERT_THROWS_NOTHING(sProp->addValue("2007-11-30T16:17:10", "test2"));
TS_ASSERT_EQUALS(sProp->size(), sizepre + 2);
Janik Zikovsky
committed
Janik Zikovsky
committed
TimeSeriesProperty<int> otherProp("otherProp");
TS_ASSERT_THROWS_NOTHING(
otherProp.addValue(static_cast<std::time_t>(123), 1));
TS_ASSERT_THROWS_NOTHING(
otherProp.addValue(boost::posix_time::second_clock::local_time(), 1));
const std::string dString = dProp->value();
TS_ASSERT_EQUALS(dString.substr(0, 27), "2007-Nov-30 16:17:00 9.99\n");
const std::string iString = iProp->value();
TS_ASSERT_EQUALS(iString.substr(0, 24), "2007-Nov-30 16:17:00 1\n");
const std::string sString = sProp->value();
TS_ASSERT_EQUALS(sString.substr(0, 27), "2007-Nov-30 16:17:00 test\n");
// Test the internal toggling of the 'sorted' flag works
auto twoVals = dProp->valuesAsVector();
double newVal = 2.22;
dProp->addValue("2007-11-30T16:17:05", newVal);
// Calling this method sorts the vector by time, so long as the internal
// flag says it isn't sorted
auto threeVals = dProp->valuesAsVector();
TS_ASSERT_EQUALS(threeVals.size(), 3);
TS_ASSERT_EQUALS(twoVals[0], threeVals[0]);
TS_ASSERT_EQUALS(twoVals[1], threeVals[2]);
TS_ASSERT_EQUALS(newVal, threeVals[1]);
}
void test_GetDerivative() {
dProp->addValue("2007-11-30T16:17:10", 10);
dProp->addValue("2007-11-30T16:17:12", 12);
dProp->addValue("2007-11-30T16:17:01", 01);
dProp->addValue("2007-11-30T16:17:05", 05);
auto derProp = dProp->getDerivative();
TS_ASSERT(dynamic_cast<TimeSeriesProperty<double> *>(derProp.get()))
auto derValues = derProp->valuesAsVector();
TS_ASSERT_EQUALS(derValues[0], 1);
TS_ASSERT_EQUALS(derValues[1], 1);
TS_ASSERT_EQUALS(derValues[2], 1);
TSM_ASSERT_THROWS("derivative undefined for string property",
sProp->getDerivative(), std::runtime_error);
iProp->addValue("2007-11-30T16:17:10", 10);
TSM_ASSERT_THROWS(
"derivative undefined for property with less then 2 values",
iProp->getDerivative(), std::runtime_error);
iProp->addValue("2007-11-30T16:17:12", 12);
derProp = iProp->getDerivative();
derValues = derProp->valuesAsVector();
void test_timesAsVector() {
TimeSeriesProperty<double> *p =
new TimeSeriesProperty<double>("doubleProp");
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:20", 5.55));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:00", 9.99));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:10", 5.55));
TS_ASSERT_THROWS_NOTHING(p->addValue("2007-11-30T16:17:30", 5.55));
std::vector<double> timeSec;
timeSec = p->timesAsVectorSeconds();
TS_ASSERT_DELTA(timeSec[0], 0.0, 1e-6);
TS_ASSERT_DELTA(timeSec[1], 10.0, 1e-6);
TS_ASSERT_DELTA(timeSec[2], 20.0, 1e-6);
TS_ASSERT_DELTA(timeSec[3], 30.0, 1e-6);
std::vector<DateAndTime> time;
time = p->timesAsVector();
TS_ASSERT_EQUALS(time[0], DateAndTime("2007-11-30T16:17:00"));
TS_ASSERT_EQUALS(time[1], DateAndTime("2007-11-30T16:17:10"));
TS_ASSERT_EQUALS(time[2], DateAndTime("2007-11-30T16:17:20"));
TS_ASSERT_EQUALS(time[3], DateAndTime("2007-11-30T16:17:30"));
void test_replaceValues() {
size_t num = 1000;
DateAndTime first("2007-11-30T16:17:10");
std::vector<DateAndTime> times;
std::vector<double> values;
std::vector<double> replacementValues;
double offset = 100.0;
for (size_t i = 0; i < num; i++) {
times.push_back(first + double(i));
values.push_back(double(i));
replacementValues.push_back(double(i) + offset);
}
TimeSeriesProperty<double> tsp("test");
tsp.addValues(times, values);
TS_ASSERT_EQUALS(tsp.size(), 1000);
TS_ASSERT_EQUALS(tsp.nthValue(3), 3.0);
// Act
tsp.replaceValues(times, replacementValues);
// Assert
TSM_ASSERT_EQUALS("Should have 1000 entries", tsp.size(), 1000);
TSM_ASSERT_EQUALS("Should be 3 plus the offset of 100", tsp.nthValue(3),
103.0);
void test_addValues() {
size_t num = 1000;
DateAndTime first("2007-11-30T16:17:10");
std::vector<DateAndTime> times;
std::vector<double> values;
for (size_t i = 0; i < num; i++) {
times.push_back(first + double(i));
values.push_back(double(i));
}
TimeSeriesProperty<double> tsp("test");
tsp.addValues(times, values);
TS_ASSERT_EQUALS(tsp.size(), 1000);
TS_ASSERT_EQUALS(tsp.nthValue(3), 3.0);
}
void test_Casting() {
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(iProp),
static_cast<Property *>(0));
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(dProp),
static_cast<Property *>(0));
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(sProp),
static_cast<Property *>(0));
TS_ASSERT_DIFFERS(dynamic_cast<ITimeSeriesProperty *>(iProp),
static_cast<ITimeSeriesProperty *>(0));
}
Janik Zikovsky
committed
Janik Zikovsky
committed
//----------------------------------------------------------------------------
void test_AdditionOperator() {
TimeSeriesProperty<int> *log = new TimeSeriesProperty<int>("MyIntLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:00", 1));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:19:10", 2));
Janik Zikovsky
committed
TimeSeriesProperty<int> *log2 = new TimeSeriesProperty<int>("MyIntLog2");
TS_ASSERT_THROWS_NOTHING(log2->addValue("2007-11-30T16:18:00", 3));
TS_ASSERT_THROWS_NOTHING(log2->addValue("2007-11-30T16:18:10", 4));
TS_ASSERT_THROWS_NOTHING(log2->addValue("2007-11-30T16:18:11", 5));
Janik Zikovsky
committed
TS_ASSERT_EQUALS(log->size(), 2);
Janik Zikovsky
committed
Janik Zikovsky
committed
(*log) += log2;
TS_ASSERT_EQUALS(log->size(), 5);
DateAndTime t0 = log->firstTime();
DateAndTime tf = log->lastTime();
TS_ASSERT_EQUALS(t0, DateAndTime("2007-11-30T16:17:00"));
TS_ASSERT_EQUALS(tf, DateAndTime("2007-11-30T16:19:10"));
}
//----------------------------------------------------------------------------
Janik Zikovsky
committed
/// Ticket 2097: This caused an infinite loop
void test_AdditionOperatorOnYourself() {
TimeSeriesProperty<int> *log = createIntegerTSP(2);
(*log) += log;
// There is now a check and trying to do this does nothing.
TS_ASSERT_EQUALS(log->size(), 2);
void test_ComparisonOperator() {
// Setup two logs and two filters so that logs have different sizes but are
// the same size after applying the filter
TimeSeriesProperty<int> *log1 = new TimeSeriesProperty<int>("count_rate");
log1->addValue("2016-03-17T00:00:00", 1);
log1->addValue("2016-03-17T00:30:00", 2);
log1->addValue("2016-03-17T01:00:00", 3);
log1->addValue("2016-03-17T01:30:00", 4);
log1->addValue("2016-03-17T02:00:00", 5);
TimeSeriesProperty<bool> *filter1 = new TimeSeriesProperty<bool>("filter");
filter1->addValue("2016-Mar-17T00:00:00", 1);
filter1->addValue("2016-Mar-17T01:00:00", 0);
log1->filterWith(filter1);
TimeSeriesProperty<int> *log2 = new TimeSeriesProperty<int>("count_rate");
log2->addValue("2016-03-17T03:00:00", 1);
log2->addValue("2016-03-17T04:00:00", 2);
log2->addValue("2016-03-17T05:00:00", 3);
log2->addValue("2016-03-17T06:00:0", 4);
TimeSeriesProperty<bool> *filter2 = new TimeSeriesProperty<bool>("filter");
filter2->addValue("2016-Mar-17T03:00:00", 1);
filter2->addValue("2016-Mar-17T05:00:00", 0);
log2->filterWith(filter2);
TS_ASSERT(!(*log1 == *log2));
delete log1;
delete log2;
delete filter1;
delete filter2;
}
Janik Zikovsky
committed
//----------------------------------------------------------------------------
void test_filterByTime() {
TimeSeriesProperty<int> *log = createIntegerTSP(6);
TS_ASSERT_EQUALS(log->realSize(), 6);
Janik Zikovsky
committed
DateAndTime start = DateAndTime("2007-11-30T16:17:10");
DateAndTime stop = DateAndTime("2007-11-30T16:17:40");
// Since the filter is < stop, the last one is not counted, so there are 3
// taken out.
log->filterByTime(start, stop);
TS_ASSERT_EQUALS(log->realSize(), 3);
Janik Zikovsky
committed
}
//-------------------------------------------------------------------------------
void test_filterByTimes1() {
TimeSeriesProperty<int> *log = createIntegerTSP(6);
TS_ASSERT_EQUALS(log->realSize(), 6);
Mantid::Kernel::SplittingInterval interval0(
DateAndTime("2007-11-30T16:17:10"), DateAndTime("2007-11-30T16:17:40"),
0);
Mantid::Kernel::TimeSplitterType splitters;
splitters.push_back(interval0);
// Since the filter is < stop, the last one is not counted, so there are 3
// taken out.
log->filterByTimes(splitters);
TS_ASSERT_EQUALS(log->realSize(), 3);
void test_filterByTimesN() {
TimeSeriesProperty<int> *log = createIntegerTSP(10);
TS_ASSERT_EQUALS(log->realSize(), 10);
Mantid::Kernel::SplittingInterval interval0(
DateAndTime("2007-11-30T16:17:10"), DateAndTime("2007-11-30T16:17:40"),
0);
Mantid::Kernel::SplittingInterval interval1(
DateAndTime("2007-11-30T16:18:05"), DateAndTime("2007-11-30T16:18:25"),
0);
Mantid::Kernel::TimeSplitterType splitters;
splitters.push_back(interval0);
splitters.push_back(interval1);
// Since the filter is < stop, the last one is not counted, so there are 3
// taken out.
log->filterByTimes(splitters);
TS_ASSERT_EQUALS(log->realSize(), 6);
Janik Zikovsky
committed
//----------------------------------------------------------------------------
/// Ticket #2591
void test_filterByTime_ifOnlyOneValue_assumes_constant_instead() {
TimeSeriesProperty<int> *log = createIntegerTSP(1);
TS_ASSERT_EQUALS(log->realSize(), 1);
Janik Zikovsky
committed
DateAndTime start = DateAndTime("2007-11-30T16:17:10");
DateAndTime stop = DateAndTime("2007-11-30T16:17:40");
log->filterByTime(start, stop);
TS_ASSERT_EQUALS(log->realSize(), 1);
}
//----------------------------------------------------------------------------
/// Ticket #2591
void test_filterByTime_ifOnlyOneValue_assumes_constant_instead_2() {
TimeSeriesProperty<int> *log = new TimeSeriesProperty<int>("MyIntLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("1990-01-01T00:00:00", 1));
TS_ASSERT_EQUALS(log->realSize(), 1);
DateAndTime start = DateAndTime("2007-11-30T16:17:10");
DateAndTime stop = DateAndTime("2007-11-30T16:17:40");
log->filterByTime(start, stop);
Janik Zikovsky
committed
// Still there!
TS_ASSERT_EQUALS(log->realSize(), 1);
Janik Zikovsky
committed
}
Janik Zikovsky
committed
//----------------------------------------------------------------------------
void test_makeFilterByValue() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MyIntLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:00", 1));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:10", 2));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:20", 3));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:30", 2.0));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:40", 2.01));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:50", 6));
TS_ASSERT_EQUALS(log->realSize(), 6);
Janik Zikovsky
committed
// Test centred log value boundaries
Janik Zikovsky
committed
TimeSplitterType splitter;
log->makeFilterByValue(splitter, 1.8, 2.2, 1.0, true);
Janik Zikovsky
committed
TS_ASSERT_EQUALS(splitter.size(), 2);
Janik Zikovsky
committed
SplittingInterval s;
Janik Zikovsky
committed
DateAndTime t;
Janik Zikovsky
committed
s = splitter[0];
Janik Zikovsky
committed
t = DateAndTime("2007-11-30T16:17:09");
TS_ASSERT_DELTA(s.start(), t, 1e-3);
Janik Zikovsky
committed
t = DateAndTime("2007-11-30T16:17:11");
TS_ASSERT_DELTA(s.stop(), t, 1e-3);
Janik Zikovsky
committed
s = splitter[1];
Janik Zikovsky
committed
t = DateAndTime("2007-11-30T16:17:29");
TS_ASSERT_DELTA(s.start(), t, 1e-3);
Janik Zikovsky
committed
t = DateAndTime("2007-11-30T16:17:41");
TS_ASSERT_DELTA(s.stop(), t, 1e-3);
// Now test with left-aligned log value boundaries
log->makeFilterByValue(splitter, 1.8, 2.2, 1.0);
TS_ASSERT_EQUALS(splitter.size(), 2);
s = splitter[0];
t = DateAndTime("2007-11-30T16:17:10");
TS_ASSERT_DELTA(s.start(), t, 1e-3);
t = DateAndTime("2007-11-30T16:17:20");
TS_ASSERT_DELTA(s.stop(), t, 1e-3);
s = splitter[1];
t = DateAndTime("2007-11-30T16:17:30");
TS_ASSERT_DELTA(s.start(), t, 1e-3);
t = DateAndTime("2007-11-30T16:17:50");
TS_ASSERT_DELTA(s.stop(), t, 1e-3);
// Check throws if min > max
TS_ASSERT_THROWS(log->makeFilterByValue(splitter, 2.0, 1.0, 0.0, true),
std::invalid_argument);
void test_makeFilterByValue_throws_for_string_property() {
TimeSeriesProperty<std::string> log("StringTSP");
TimeSplitterType splitter;
TS_ASSERT_THROWS(log.makeFilterByValue(splitter, 0.0, 0.0, 0.0, true),
Exception::NotImplementedError);
}
void test_expandFilterToRange() {
TimeSeriesProperty<int> log("MyIntLog");
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:00", 1));
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:10", 2));
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:20", 3));
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:30", 4));
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:40", 6));
TS_ASSERT_THROWS_NOTHING(log.addValue("2007-11-30T16:17:50", 2));
// Create a TimeInterval that's wider than this log
TimeInterval interval(DateAndTime("2007-11-30T16:16:00"),
DateAndTime("2007-11-30T16:18:50"));
TimeSplitterType splitter;
// Test good at both ends
log.makeFilterByValue(splitter, 1.0, 2.2, 1.0, false);
log.expandFilterToRange(splitter, 1.0, 2.2, interval);
TS_ASSERT_EQUALS(splitter.size(), 2);
TS_ASSERT_DELTA(splitter[0].start(), DateAndTime("2007-11-30T16:16:00"),
1e-3);
TS_ASSERT_DELTA(splitter[0].stop(), DateAndTime("2007-11-30T16:17:20"),
1e-3);
TS_ASSERT_DELTA(splitter[1].start(), DateAndTime("2007-11-30T16:17:50"),
1e-3);
TS_ASSERT_DELTA(splitter[1].stop(), DateAndTime("2007-11-30T16:18:50"),
1e-3);
// Test bad at both ends
log.makeFilterByValue(splitter, 2.5, 10.0, 0.0, false);
log.expandFilterToRange(splitter, 2.5, 10.0, interval);
TS_ASSERT_EQUALS(splitter.size(), 1);
TS_ASSERT_DELTA(splitter[0].start(), DateAndTime("2007-11-30T16:17:20"),
1e-3);
TS_ASSERT_DELTA(splitter[0].stop(), DateAndTime("2007-11-30T16:17:50"),
1e-3);
// Test good at start, bad at end
log.makeFilterByValue(splitter, -1.0, 1.5, 0.0, false);
log.expandFilterToRange(splitter, -1.0, 1.5, interval);
TS_ASSERT_EQUALS(splitter.size(), 1);
TS_ASSERT_DELTA(splitter[0].start(), DateAndTime("2007-11-30T16:16:00"),
1e-3);
TS_ASSERT_DELTA(splitter[0].stop(), DateAndTime("2007-11-30T16:17:10"),
1e-3);
// Test good at end, bad at start
log.makeFilterByValue(splitter, 1.99, 2.5, 1.0, false);
log.expandFilterToRange(splitter, 1.99, 2.5, interval);
TS_ASSERT_EQUALS(splitter.size(), 2);
TS_ASSERT_DELTA(splitter[0].start(), DateAndTime("2007-11-30T16:17:10"),
1e-3);
TS_ASSERT_DELTA(splitter[0].stop(), DateAndTime("2007-11-30T16:17:20"),
1e-3);
TS_ASSERT_DELTA(splitter[1].start(), DateAndTime("2007-11-30T16:17:50"),
1e-3);
TS_ASSERT_DELTA(splitter[1].stop(), DateAndTime("2007-11-30T16:18:50"),
1e-3);
// Check throws if min > max
TS_ASSERT_THROWS(log.expandFilterToRange(splitter, 2.0, 1.0, interval),
std::invalid_argument);
// Test good at both ends, but interval narrower than log range
TimeInterval narrowinterval(DateAndTime("2007-11-30T16:17:15"),
DateAndTime("2007-11-30T16:17:41"));
log.makeFilterByValue(splitter, 0.0, 10.0, 0.0, false);
log.expandFilterToRange(splitter, 0.0, 10.0, narrowinterval);
TS_ASSERT_EQUALS(splitter.size(), 1);
TS_ASSERT_DELTA(splitter[0].start(), DateAndTime("2007-11-30T16:17:00"),
1e-3);
TS_ASSERT_DELTA(splitter[0].stop(), DateAndTime("2007-11-30T16:17:50"),
1e-3);
}
void test_expandFilterToRange_throws_for_string_property() {
TimeSeriesProperty<std::string> log("StringTSP");
TimeSplitterType splitter;
TS_ASSERT_THROWS(
log.expandFilterToRange(splitter, 0.0, 0.0, TimeInterval()),
Exception::NotImplementedError);
}
void test_averageValueInFilter() {
auto dblLog = createDoubleTSP();
auto intLog = createIntegerTSP(5);
// Test a filter that's fully within the range of both properties
TimeSplitterType filter;
filter.push_back(SplittingInterval(DateAndTime("2007-11-30T16:17:05"),
DateAndTime("2007-11-30T16:17:29")));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 7.308, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 2.167, 0.001);
// Test a filter that starts before the log start time
filter[0] = SplittingInterval(DateAndTime("2007-11-30T16:16:30"),
DateAndTime("2007-11-30T16:17:13"));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 9.820, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 1.070, 0.001);
// How about one that's entirely outside the log range (should just take the
// last value)
filter[0] = SplittingInterval(DateAndTime("2013-01-01T00:00:00"),
DateAndTime("2013-01-01T01:00:00"));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 10.55, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 5.0, 0.001);
// Test a filter with two separate ranges, one of which goes past the end of
// the log
filter[0] = SplittingInterval(DateAndTime("2007-11-30T16:17:05"),
DateAndTime("2007-11-30T16:17:15"));
filter.push_back(SplittingInterval(DateAndTime("2007-11-30T16:17:25"),
DateAndTime("2007-11-30T16:17:45")));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 9.123, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 3.167, 0.001);
// Test a filter with two out of order ranges (the second one coming before
// the first)
// It should work fine.
filter[0] = filter[1];
filter[0] = SplittingInterval(DateAndTime("2007-11-30T16:17:05"),
DateAndTime("2007-11-30T16:17:15"));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 9.123, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 3.167, 0.001);
// What about an overlap between the filters? It's odd, but it's allowed.
filter[0] = SplittingInterval(DateAndTime("2007-11-30T16:17:05"),
DateAndTime("2007-11-30T16:17:15"));
filter[1] = SplittingInterval(DateAndTime("2007-11-30T16:17:10"),
DateAndTime("2007-11-30T16:17:20"));
TS_ASSERT_DELTA(dblLog->averageValueInFilter(filter), 8.16, 0.001);
TS_ASSERT_DELTA(intLog->averageValueInFilter(filter), 1.75, 0.001);
// Check the correct behaviour of empty of single value logs.
TS_ASSERT(std::isnan(dProp->averageValueInFilter(filter)));
iProp->addValue(DateAndTime("2010-11-30T16:17:25"), 99);
TS_ASSERT_EQUALS(iProp->averageValueInFilter(filter), 99.0);
// Clean up
delete dblLog;
delete intLog;
}
auto dblLog = createDoubleTSP();
auto intLog = createIntegerTSP(5);
TS_ASSERT_DELTA(dblLog->timeAverageValue(), 7.6966, .0001);
TS_ASSERT_DELTA(intLog->timeAverageValue(), 2.5, .0001);
// Clean up
delete dblLog;
delete intLog;
}
void test_averageValueInFilter_throws_for_string_property() {
TimeSplitterType splitter;
TS_ASSERT_THROWS(sProp->averageValueInFilter(splitter),
Exception::NotImplementedError);
}
Janik Zikovsky
committed
//----------------------------------------------------------------------------
void test_splitByTime_and_getTotalValue() {
TimeSeriesProperty<int> *log = createIntegerTSP(12);
// Make the outputs
std::vector<Property *> outputs;
for (std::size_t i = 0; i < 5; i++) {
TimeSeriesProperty<int> *newlog = new TimeSeriesProperty<int>("MyIntLog");
outputs.push_back(newlog);
}
Janik Zikovsky
committed
DateAndTime start, stop;
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:17:10");
stop = DateAndTime("2007-11-30T16:17:40");
splitter.push_back(SplittingInterval(start, stop, 0));
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:17:55");
stop = DateAndTime("2007-11-30T16:17:56");
splitter.push_back(SplittingInterval(start, stop, 1));
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:17:56");
stop = DateAndTime("2007-11-30T16:18:01");
splitter.push_back(SplittingInterval(start, stop, 2)); // just one entry
Janik Zikovsky
committed
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:18:09");
stop = DateAndTime("2007-11-30T16:18:21");
splitter.push_back(SplittingInterval(start, stop, 3));
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:18:45");
stop = DateAndTime("2007-11-30T16:22:50");
splitter.push_back(SplittingInterval(start, stop, 4));
log->splitByTime(splitter, outputs, false);
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[0])->realSize(), 3);
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[1])->realSize(), 1);
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[2])->realSize(), 2);
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[3])->realSize(), 3);
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[4])->realSize(), 2);
delete log;
delete outputs[0];
delete outputs[1];
delete outputs[2];
delete outputs[3];
delete outputs[4];
Janik Zikovsky
committed
//----------------------------------------------------------------------------
void test_splitByTime_withOverlap() {
TimeSeriesProperty<int> *log = createIntegerTSP(12);
Janik Zikovsky
committed
// Make the outputs
std::vector<Property *> outputs;
for (std::size_t i = 0; i < 1; i++) {
TimeSeriesProperty<int> *newlog = new TimeSeriesProperty<int>("MyIntLog");
Janik Zikovsky
committed
outputs.push_back(newlog);
}
Janik Zikovsky
committed
DateAndTime start, stop;
Janik Zikovsky
committed
TimeSplitterType splitter;
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:17:10");
stop = DateAndTime("2007-11-30T16:17:40");
splitter.push_back(SplittingInterval(start, stop, 0));
Janik Zikovsky
committed
Janik Zikovsky
committed
start = DateAndTime("2007-11-30T16:17:35");
stop = DateAndTime("2007-11-30T16:17:59");
splitter.push_back(SplittingInterval(start, stop, 0));
Janik Zikovsky
committed
log->splitByTime(splitter, outputs, false);
Janik Zikovsky
committed
TS_ASSERT_EQUALS(
dynamic_cast<TimeSeriesProperty<int> *>(outputs[0])->realSize(), 5);
Janik Zikovsky
committed
delete log;
delete outputs[0];
Janik Zikovsky
committed
}
//----------------------------------------------------------------------------
/**
* otuput 0 has entries: 3
* otuput 1 has entries: 5
* otuput 2 has entries: 2
* otuput 3 has entries: 7
* @brief test_splitByTimeVector
*/
void test_splitByTimeVector() {
// create the splitters
std::vector<DateAndTime> split_time_vec;
split_time_vec.push_back(DateAndTime("2007-11-30T16:17:10"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:17:40"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:17:55"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:17:56"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:18:09"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:18:45"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:22:50"));
std::vector<int> split_target_vec;
split_target_vec.push_back(1);
split_target_vec.push_back(0);
split_target_vec.push_back(2);
split_target_vec.push_back(0);
split_target_vec.push_back(1);
split_target_vec.push_back(3);
TimeSeriesProperty<int> log("test log");
log.addValue(DateAndTime("2007-11-30T16:17:00"), 1);
log.addValue(DateAndTime("2007-11-30T16:17:30"), 2);
log.addValue(DateAndTime("2007-11-30T16:18:00"), 3);
log.addValue(DateAndTime("2007-11-30T16:18:30"), 4);
log.addValue(DateAndTime("2007-11-30T16:19:00"), 5);
log.addValue(DateAndTime("2007-11-30T16:19:30"), 6);
log.addValue(DateAndTime("2007-11-30T16:20:00"), 7);
log.addValue(DateAndTime("2007-11-30T16:20:30"), 8);
log.addValue(DateAndTime("2007-11-30T16:21:00"), 9);
log.addValue(DateAndTime("2007-11-30T16:21:30"), 10);
std::vector<TimeSeriesProperty<int> *> outputs;
for (int itarget = 0; itarget < 4; ++itarget) {
TimeSeriesProperty<int> *tsp = new TimeSeriesProperty<int>("target");
outputs.push_back(tsp);
}
log.splitByTimeVector(split_time_vec, split_target_vec, outputs);
// Exam the split entries
TimeSeriesProperty<int> *out_0 = outputs[0];
// FIXME - Check whether out_0 is correct!
TS_ASSERT_EQUALS(out_0->size(), 3);
TS_ASSERT_EQUALS(out_0->nthValue(0), 2);
TS_ASSERT_EQUALS(out_0->nthValue(1), 3);
TS_ASSERT_EQUALS(out_0->nthValue(2), 4);
TimeSeriesProperty<int> *out_1 = outputs[1];
TS_ASSERT_EQUALS(out_1->size(), 5);
TS_ASSERT_EQUALS(out_1->nthValue(0), 1);
TS_ASSERT_EQUALS(out_1->nthValue(1), 2);
TS_ASSERT_EQUALS(out_1->nthValue(2), 3);
TS_ASSERT_EQUALS(out_1->nthValue(3), 4);
TS_ASSERT_EQUALS(out_1->nthValue(4), 5);
TimeSeriesProperty<int> *out_2 = outputs[2];
TS_ASSERT_EQUALS(out_2->size(), 2);
TS_ASSERT_EQUALS(out_2->nthValue(0), 2);
TS_ASSERT_EQUALS(out_2->nthValue(1), 3);
TimeSeriesProperty<int> *out_3 = outputs[3];
TS_ASSERT_EQUALS(out_3->size(), 7);
// out[3] should have entries: 4, 5, 6, 7, 8, 9, 10
for (int j = 0; j < out_3->size(); ++j) {
TS_ASSERT_EQUALS(out_3->nthValue(j), j + 4);
}
//----------------------------------------------------------------------------
/** last splitter is before first entry
* @brief test_splitByTimeVectorEarlySplitter
*/
void test_splitByTimeVectorEarlySplitter() {
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
// create the splitters
std::vector<DateAndTime> split_time_vec;
split_time_vec.push_back(DateAndTime("2007-11-30T16:00:10"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:00:40"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:07:55"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:07:56"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:08:09"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:08:45"));
split_time_vec.push_back(DateAndTime("2007-11-30T16:12:50"));
std::vector<int> split_target_vec;
split_target_vec.push_back(1);
split_target_vec.push_back(0);
split_target_vec.push_back(2);
split_target_vec.push_back(0);
split_target_vec.push_back(1);
split_target_vec.push_back(3);
TimeSeriesProperty<int> log("test log");
log.addValue(DateAndTime("2007-11-30T16:17:00"), 1);
log.addValue(DateAndTime("2007-11-30T16:17:30"), 2);
log.addValue(DateAndTime("2007-11-30T16:18:00"), 3);
log.addValue(DateAndTime("2007-11-30T16:18:30"), 4);
log.addValue(DateAndTime("2007-11-30T16:19:00"), 5);
log.addValue(DateAndTime("2007-11-30T16:19:30"), 6);
log.addValue(DateAndTime("2007-11-30T16:20:00"), 7);
log.addValue(DateAndTime("2007-11-30T16:20:30"), 8);
log.addValue(DateAndTime("2007-11-30T16:21:00"), 9);
log.addValue(DateAndTime("2007-11-30T16:21:30"), 10);
// Initialze the 4 splitters
std::vector<TimeSeriesProperty<int> *> outputs;
for (int itarget = 0; itarget < 4; ++itarget) {
TimeSeriesProperty<int> *tsp = new TimeSeriesProperty<int>("target");
outputs.push_back(tsp);
}
log.splitByTimeVector(split_time_vec, split_target_vec, outputs);
// check
TimeSeriesProperty<int> *out_i = outputs[i];
TS_ASSERT_EQUALS(out_i->size(), 0);
}
}
//----------------------------------------------------------------------------
/** first splitter is after last entry
* @brief test_splitByTimeVectorLaterSplitter
*/
void test_splitByTimeVectorLaterSplitter() {
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
// create the splitters
std::vector<DateAndTime> split_time_vec;
split_time_vec.push_back(DateAndTime("2007-12-30T16:00:10"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:00:40"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:07:55"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:07:56"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:08:09"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:08:45"));
split_time_vec.push_back(DateAndTime("2007-12-30T16:12:50"));
std::vector<int> split_target_vec;
split_target_vec.push_back(1);
split_target_vec.push_back(0);
split_target_vec.push_back(2);
split_target_vec.push_back(0);
split_target_vec.push_back(1);
split_target_vec.push_back(3);
// create test log
TimeSeriesProperty<int> log("test log");
log.addValue(DateAndTime("2007-11-30T16:17:00"), 1);
log.addValue(DateAndTime("2007-11-30T16:17:30"), 2);
log.addValue(DateAndTime("2007-11-30T16:18:00"), 3);
log.addValue(DateAndTime("2007-11-30T16:18:30"), 4);
log.addValue(DateAndTime("2007-11-30T16:19:00"), 5);
log.addValue(DateAndTime("2007-11-30T16:19:30"), 6);
log.addValue(DateAndTime("2007-11-30T16:20:00"), 7);
log.addValue(DateAndTime("2007-11-30T16:20:30"), 8);
log.addValue(DateAndTime("2007-11-30T16:21:00"), 9);
log.addValue(DateAndTime("2007-11-30T16:21:30"), 10);
// Initialze the 4 splitters
std::vector<TimeSeriesProperty<int> *> outputs;
for (int itarget = 0; itarget < 4; ++itarget) {
TimeSeriesProperty<int> *tsp = new TimeSeriesProperty<int>("target");
outputs.push_back(tsp);
}
log.splitByTimeVector(split_time_vec, split_target_vec, outputs);
// check
TimeSeriesProperty<int> *out_i = outputs[i];
TS_ASSERT_EQUALS(out_i->size(), 0);
}
}
//----------------------------------------------------------------------------
/** high-frequency splitters splits a slow change log
* @brief test_splitByTimeVectorFastLogSplitter
*/
void test_splitByTimeVectorFastLogSplitter() {
// create test log
TimeSeriesProperty<int> log("test log");
log.addValue(DateAndTime("2007-11-30T16:17:00"), 1);
log.addValue(DateAndTime("2007-11-30T16:17:30"), 2);
log.addValue(DateAndTime("2007-11-30T16:18:00"), 3);
log.addValue(DateAndTime("2007-11-30T16:18:30"), 4);
log.addValue(DateAndTime("2007-11-30T16:19:00"), 5);
log.addValue(DateAndTime("2007-11-30T16:19:30"), 6);
log.addValue(DateAndTime("2007-11-30T16:20:00"), 7);
log.addValue(DateAndTime("2007-11-30T16:20:30"), 8);
log.addValue(DateAndTime("2007-11-30T16:21:00"), 9);
log.addValue(DateAndTime("2007-11-30T16:21:30"), 10);
// create a high frequency splitter
DateAndTime split_time("2007-11-30T16:17:00");
std::vector<DateAndTime> vec_split_times;
std::vector<int> vec_split_target;
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
vec_split_times.push_back(split_time);
split_time += dt;
vec_split_target.push_back(j);
}
}
// push back last split-time (split stop)
vec_split_times.push_back(split_time);
// Initialze the 10 splitters
std::vector<TimeSeriesProperty<int> *> outputs;
for (int itarget = 0; itarget < 10; ++itarget) {
TimeSeriesProperty<int> *tsp = new TimeSeriesProperty<int>("target");
outputs.push_back(tsp);
}
size_t num_splits = vec_split_target.size();
for (size_t i = 0; i < num_splits; ++i) {
std::cout << "s[" << i << "] start = " << vec_split_times[i]
<< ", stop = " << vec_split_times[i + 1]
<< ": target = " << vec_split_target[i] << "\n";
log.splitByTimeVector(vec_split_times, vec_split_target, outputs);
// TODO/FIXME/ - continue to debug from here!
TimeSeriesProperty<int> *out0 = outputs[0];
for (int i = 0; i < out0->size(); ++i) {
std::cout << i << "-th: " << out0->nthTime(i) << ", " << out0->nthValue(i)
<< "\n";
for (size_t i = 0; i < 10; ++i) {
TS_ASSERT_EQUALS(outputs[i]->size(), 2);
}
//----------------------------------------------------------------------------
void test_statistics() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MydoubleLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:00", 1));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:10", 2));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:20", 3));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:30", 4));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:40", 5));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:50", 6));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:00", 7));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:10", 8));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:20", 9));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:30", 10));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:40", 11));
TS_ASSERT_EQUALS(log->realSize(), 11);
TimeSeriesPropertyStatistics stats = log->getStatistics();
TS_ASSERT_DELTA(stats.minimum, 1.0, 1e-3);
TS_ASSERT_DELTA(stats.maximum, 11.0, 1e-3);
TS_ASSERT_DELTA(stats.median, 6.0, 1e-3);
TS_ASSERT_DELTA(stats.mean, 6.0, 1e-3);
TS_ASSERT_DELTA(stats.duration, 100.0, 1e-3);
TS_ASSERT_DELTA(stats.standard_deviation, 3.1622, 1e-3);
TS_ASSERT_DELTA(log->timeAverageValue(), 5.5, 1e-3);
}
void test_empty_statistics() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MydoubleLog");
TimeSeriesPropertyStatistics stats = log->getStatistics();