##// END OF EJS Templates
More work on new Variable python bindings...
jeandet -
r63:98081fcec6d5
parent child
Show More
@@ -0,0 +1,17
1 #ifndef SCIQLOP_SPECTROGRAMTIMESERIE_H
2 #define SCIQLOP_SPECTROGRAMTIMESERIE_H
3
4 #include "CoreGlobal.h"
5
6 #include <TimeSeries.h>
7
8 class SCIQLOP_CORE_EXPORT SpectrogramTimeSerie
9 : public TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>
10 {
11 public:
12 SpectrogramTimeSerie() {}
13 ~SpectrogramTimeSerie() = default;
14 using TimeSerie::TimeSerie;
15 };
16
17 #endif // SCIQLOP_SPECTROGRAMTIMESERIE_H
@@ -0,0 +1,41
1 import sys
2 import os
3
4 import sciqlopqt
5 import pysciqlopcore
6
7 import numpy as np
8 import datetime
9 import time
10 import unittest
11 import ddt
12
13 def listify(obj):
14 if hasattr(obj, "__getitem__"):
15 return obj
16 return [obj]
17
18 @ddt.ddt
19 class TimeSeriesCtors(unittest.TestCase):
20 @ddt.data(
21 (pysciqlopcore.ScalarTimeSerie,10),
22 (pysciqlopcore.VectorTimeSerie,10),
23 (pysciqlopcore.SpectrogramTimeSerie,[10,10]),
24 )
25 def test_construct(self, case):
26 ts = case[0](case[1])
27 self.assertEqual(ts.shape,listify(case[1]))
28
29 class TimeSeriesData(unittest.TestCase):
30 def test_set_ScalarTimeSerie_values(self):
31 ts = pysciqlopcore.ScalarTimeSerie(10)
32 ts.t[0]=111.
33 self.assertEqual(ts.t[0],111.)
34 ts[0]=123.
35 self.assertEqual(ts[0],123.)
36
37 def test_build_ScalarTimeSerie_from_np_arrays(self):
38 ts = pysciqlopcore.ScalarTimeSerie(np.arange(10),np.zeros(10))
39
40 if __name__ == '__main__':
41 unittest.main()
@@ -95,6 +95,7 FILE (GLOB_RECURSE core_SRCS
95 ./include/Data/DataSeriesIterator.h
95 ./include/Data/DataSeriesIterator.h
96 ./include/Data/DataSeriesUtils.h
96 ./include/Data/DataSeriesUtils.h
97 ./include/Data/SpectrogramSeries.h
97 ./include/Data/SpectrogramSeries.h
98 ./include/Data/SpectrogramTimeSerie.h
98 ./include/Data/Unit.h
99 ./include/Data/Unit.h
99 ./include/Data/DataProviderParameters.h
100 ./include/Data/DataProviderParameters.h
100 ./include/Data/OptionalAxis.h
101 ./include/Data/OptionalAxis.h
@@ -1,1 +1,1
1 Subproject commit ce006cf8df2b0bb3d433f901b6e80ce69119a430
1 Subproject commit b8442947c778c24a35d33c5f8eed8548cbf9fead
@@ -1,221 +1,219
1 #ifndef SCIQLOP_DATETIMERANGE_H
1 #ifndef SCIQLOP_DATETIMERANGE_H
2 #define SCIQLOP_DATETIMERANGE_H
2 #define SCIQLOP_DATETIMERANGE_H
3
3
4 #include <cmath>
5 #include <QObject>
6
7 #include <QDebug>
8
9 #include <opaque/numeric_typedef.hpp>
10 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
11 #include <Common/MetaTypes.h>
5 #include <Common/MetaTypes.h>
12 #include <Common/Numeric.h>
6 #include <Common/Numeric.h>
7 #include <QDebug>
8 #include <QObject>
9 #include <cmath>
10 #include <opaque/numeric_typedef.hpp>
13
11
14
12 template<typename T>
15 template <typename T>
13 struct Seconds
16 struct Seconds : opaque::numeric_typedef<T, Seconds<T>> ,
14 : opaque::numeric_typedef<T, Seconds<T>>,
17 opaque::binop::multipliable <Seconds<T>, true , Seconds<T>, T, T>,
15 opaque::binop::multipliable<Seconds<T>, true, Seconds<T>, T, T>,
18 opaque::binop::dividable <Seconds<T>, true , Seconds<T>, T, T>,
16 opaque::binop::dividable<Seconds<T>, true, Seconds<T>, T, T>,
19 opaque::binop::addable <Seconds<T>, true , Seconds<T>, T, T>,
17 opaque::binop::addable<Seconds<T>, true, Seconds<T>, T, T>,
20 opaque::binop::subtractable <Seconds<T>, true , Seconds<T>, T, T>
18 opaque::binop::subtractable<Seconds<T>, true, Seconds<T>, T, T>
21
19
22 {
20 {
23 using base = opaque::numeric_typedef<T, Seconds<T>>;
21 using base = opaque::numeric_typedef<T, Seconds<T>>;
24 using base::base;
22 using base::base;
25 operator T () const {return this->value;}
23 operator T() const { return this->value; }
26 };
24 };
27
25
28 struct InvalidDateTimeRangeTransformation{};
26 struct InvalidDateTimeRangeTransformation
27 {};
29
28
30 struct DateTimeRangeTransformation
29 struct DateTimeRangeTransformation
31 {
30 {
32 double zoom;
31 double zoom;
33 Seconds<double> shift;
32 Seconds<double> shift;
34 bool operator==(const DateTimeRangeTransformation& other) const
33 bool operator==(const DateTimeRangeTransformation& other) const
35 {
34 {
36 return SciQLop::numeric::almost_equal(zoom, other.zoom, 1) &&
35 return SciQLop::numeric::almost_equal(zoom, other.zoom, 1) &&
37 SciQLop::numeric::almost_equal<double>(shift, other.shift, 1);
36 SciQLop::numeric::almost_equal<double>(shift, other.shift, 1);
38 }
37 }
39 DateTimeRangeTransformation merge(const DateTimeRangeTransformation& other) const
38 DateTimeRangeTransformation
40 {
39 merge(const DateTimeRangeTransformation& other) const
41 return DateTimeRangeTransformation{zoom*other.zoom,shift+other.shift};
40 {
42 }
41 return DateTimeRangeTransformation{zoom * other.zoom, shift + other.shift};
42 }
43 };
43 };
44
44
45 /**
45 /**
46 * @brief The SqpRange struct holds the information of time parameters
46 * @brief The SqpRange struct holds the information of time parameters
47 */
47 */
48 struct DateTimeRange {
48 struct DateTimeRange
49 DateTimeRange()
49 {
50 :m_TStart(std::nan("")), m_TEnd(std::nan(""))
50 DateTimeRange() : m_TStart(std::nan("")), m_TEnd(std::nan("")) {}
51 {}
51 DateTimeRange(double TStart, double TEnd) : m_TStart(TStart), m_TEnd(TEnd) {}
52 DateTimeRange(double TStart, double TEnd)
52 /// Creates SqpRange from dates and times
53 :m_TStart(TStart), m_TEnd(TEnd)
53 static DateTimeRange fromDateTime(const QDate& startDate,
54 {}
54 const QTime& startTime,
55 /// Creates SqpRange from dates and times
55 const QDate& endDate, const QTime& endTime)
56 static DateTimeRange fromDateTime(const QDate &startDate, const QTime &startTime,
56 {
57 const QDate &endDate, const QTime &endTime)
57 return {
58 {
58 DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
59 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
59 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
60 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
60 }
61 }
61
62
62 static DateTimeRange fromDateTime(const QDateTime& start,
63 static DateTimeRange fromDateTime(const QDateTime &start, const QDateTime &end)
63 const QDateTime& end)
64 {
64 {
65 return {DateUtils::secondsSinceEpoch(start),
65 return {DateUtils::secondsSinceEpoch(start),
66 DateUtils::secondsSinceEpoch(end)};
66 DateUtils::secondsSinceEpoch(end)};
67 }
67 }
68
68
69 /// Start time (UTC)
69 /// Start time (UTC)
70 double m_TStart;
70 double m_TStart;
71 /// End time (UTC)
71 /// End time (UTC)
72 double m_TEnd;
72 double m_TEnd;
73
73
74 Seconds<double> delta()const noexcept{return Seconds<double>{this->m_TEnd - this->m_TStart};}
74 Seconds<double> delta() const noexcept
75
75 {
76 bool contains(const DateTimeRange &dateTime) const noexcept
76 return Seconds<double>{this->m_TEnd - this->m_TStart};
77 {
77 }
78 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
78
79 }
79 bool contains(const DateTimeRange& dateTime) const noexcept
80
80 {
81 Seconds<double> center() const noexcept
81 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
82 {
82 }
83 return Seconds<double>((m_TStart + m_TEnd) / 2.);
83
84 }
84 Seconds<double> center() const noexcept
85
85 {
86 bool intersect(const DateTimeRange &dateTime) const noexcept
86 return Seconds<double>((m_TStart + m_TEnd) / 2.);
87 {
87 }
88 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
88
89 }
89 bool intersect(const DateTimeRange& dateTime) const noexcept
90
90 {
91 inline DateTimeRange transform(const DateTimeRangeTransformation& tr)const noexcept;
91 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
92
92 }
93 bool operator==(const DateTimeRange &other) const
93
94 {
94 inline DateTimeRange transform(const DateTimeRangeTransformation& tr) const
95 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1) &&
95 noexcept;
96 SciQLop::numeric::almost_equal(m_TEnd, other.m_TEnd, 1);
96
97 }
97 bool operator==(const DateTimeRange& other) const
98
98 {
99 bool operator!=(const DateTimeRange &other) const { return !(*this == other); }
99 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1) &&
100
100 SciQLop::numeric::almost_equal(m_TEnd, other.m_TEnd, 1);
101 void grow(double factor)noexcept
101 }
102 {
102
103 double grow_v{delta()*(factor - 1.)/2.};
103 bool operator!=(const DateTimeRange& other) const
104 m_TStart -= grow_v;
104 {
105 m_TEnd += grow_v;
105 return !(*this == other);
106 }
106 }
107
107
108 void shrink(double factor)noexcept
108 void grow(double factor) noexcept
109 {
109 {
110 double shrink_v{this->delta()*(1. - factor)/2.};
110 double grow_v{delta() * (factor - 1.) / 2.};
111 m_TStart += shrink_v;
111 m_TStart -= grow_v;
112 m_TEnd -= shrink_v;
112 m_TEnd += grow_v;
113 }
113 }
114
114
115 DateTimeRange& operator*=(double k)
115 void shrink(double factor) noexcept
116 {
116 {
117 this->grow(k);
117 double shrink_v{this->delta() * (1. - factor) / 2.};
118 return *this;
118 m_TStart += shrink_v;
119 }
119 m_TEnd -= shrink_v;
120
120 }
121 DateTimeRange& operator/=(double k)
121
122 {
122 DateTimeRange& operator*=(double k)
123 this->shrink(k);
123 {
124 return *this;
124 this->grow(k);
125 }
125 return *this;
126
126 }
127 // compute set difference
127
128 std::vector<DateTimeRange> operator-(const DateTimeRange& other)const
128 DateTimeRange& operator/=(double k)
129 {
130 this->shrink(k);
131 return *this;
132 }
133
134 // compute set difference
135 std::vector<DateTimeRange> operator-(const DateTimeRange& other) const
136 {
137 std::vector<DateTimeRange> result;
138 if(std::isnan(other.m_TStart) || std::isnan(other.m_TEnd) ||
139 !this->intersect(other))
140 { result.emplace_back(m_TStart, m_TEnd); }
141 else
129 {
142 {
130 std::vector<DateTimeRange> result;
143 if(this->m_TStart < other.m_TStart)
131 if(std::isnan(other.m_TStart)||std::isnan(other.m_TEnd)||!this->intersect(other))
144 { result.emplace_back(this->m_TStart, other.m_TStart); }
132 {
145 if(this->m_TEnd > other.m_TEnd)
133 result.emplace_back(m_TStart, m_TEnd);
146 { result.emplace_back(other.m_TEnd, this->m_TEnd); }
134 }
135 else
136 {
137 if(this->m_TStart<other.m_TStart)
138 {
139 result.emplace_back(this->m_TStart, other.m_TStart);
140 }
141 if(this->m_TEnd>other.m_TEnd)
142 {
143 result.emplace_back(other.m_TEnd, this->m_TEnd);
144 }
145 }
146 return result;
147 }
147 }
148
148 return result;
149 }
149 };
150 };
150
151
151 template <class T>
152 template<class T> DateTimeRange& operator+=(DateTimeRange& r, Seconds<T> offset)
152 DateTimeRange& operator+=(DateTimeRange&r, Seconds<T> offset)
153 {
153 {
154 shift(r,offset);
154 shift(r, offset);
155 return r;
155 return r;
156 }
156 }
157
157
158 template <class T>
158 template<class T> DateTimeRange& operator-=(DateTimeRange& r, Seconds<T> offset)
159 DateTimeRange& operator-=(DateTimeRange&r, Seconds<T> offset)
160 {
159 {
161 shift(r,-offset);
160 shift(r, -offset);
162 return r;
161 return r;
163 }
162 }
164
163
165 template <class T>
164 template<class T> void shift(DateTimeRange& r, Seconds<T> offset)
166 void shift(DateTimeRange& r, Seconds<T> offset)
167 {
165 {
168 r.m_TEnd+=static_cast<double>(offset);
166 r.m_TEnd += static_cast<double>(offset);
169 r.m_TStart+=static_cast<double>(offset);
167 r.m_TStart += static_cast<double>(offset);
170 }
168 }
171
169
172 inline DateTimeRange operator*(const DateTimeRange& r, double k)
170 inline DateTimeRange operator*(const DateTimeRange& r, double k)
173 {
171 {
174 DateTimeRange result{r};
172 DateTimeRange result{r};
175 result.grow(k);
173 result.grow(k);
176 return result;
174 return result;
177 }
175 }
178
176
179 inline DateTimeRange operator/(const DateTimeRange& r, double k)
177 inline DateTimeRange operator/(const DateTimeRange& r, double k)
180 {
178 {
181 DateTimeRange result{r};
179 DateTimeRange result{r};
182 result.shrink(k);
180 result.shrink(k);
183 return result;
181 return result;
184 }
182 }
185
183
186 template<class T>
184 template<class T>
187 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
185 DateTimeRange operator+(const DateTimeRange& r, Seconds<T> offset)
188 {
186 {
189 DateTimeRange result{r};
187 DateTimeRange result{r};
190 shift(result,offset);
188 shift(result, offset);
191 return result;
189 return result;
192 }
190 }
193
191
194 template<class T>
192 template<class T>
195 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
193 DateTimeRange operator-(const DateTimeRange& r, Seconds<T> offset)
196 {
194 {
197 DateTimeRange result{r};
195 DateTimeRange result{r};
198 shift(result,-offset);
196 shift(result, -offset);
199 return result;
197 return result;
200 }
198 }
201
199
202 const auto INVALID_RANGE
200 const auto INVALID_RANGE =
203 = DateTimeRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
201 DateTimeRange{std::numeric_limits<double>::quiet_NaN(),
202 std::numeric_limits<double>::quiet_NaN()};
204
203
205 inline QDebug operator<<(QDebug d, DateTimeRange obj)
204 inline QDebug operator<<(QDebug d, DateTimeRange obj)
206 {
205 {
207 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
206 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
208 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
207 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
209
208
210 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
209 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
211 return d;
210 return d;
212 }
211 }
213
212
214
213 DateTimeRange
215
214 DateTimeRange::transform(const DateTimeRangeTransformation& tr) const noexcept
216 DateTimeRange DateTimeRange::transform(const DateTimeRangeTransformation &tr) const noexcept
217 {
215 {
218 return DateTimeRange{*this} * tr.zoom + tr.shift;
216 return DateTimeRange{*this} * tr.zoom + tr.shift;
219 }
217 }
220
218
221 // Required for using shared_ptr in signals/slots
219 // Required for using shared_ptr in signals/slots
@@ -10,6 +10,7
10 #include <Data/DataSeriesType.h>
10 #include <Data/DataSeriesType.h>
11 #include <Data/DateTimeRange.h>
11 #include <Data/DateTimeRange.h>
12 #include <Data/ScalarTimeSerie.h>
12 #include <Data/ScalarTimeSerie.h>
13 #include <Data/SpectrogramTimeSerie.h>
13 #include <Data/VectorTimeSerie.h>
14 #include <Data/VectorTimeSerie.h>
14 #include <QDataStream>
15 #include <QDataStream>
15 #include <QObject>
16 #include <QObject>
@@ -18,9 +19,10
18 #include <TimeSeries.h>
19 #include <TimeSeries.h>
19 #include <optional>
20 #include <optional>
20
21
21 using AnyTimeSerie = variant_w_base<
22 using AnyTimeSerie =
22 TimeSeries::ITimeSerie,
23 variant_w_base<TimeSeries::ITimeSerie,
23 std::variant<std::monostate, ScalarTimeSerie, VectorTimeSerie>>;
24 std::variant<std::monostate, ScalarTimeSerie,
25 VectorTimeSerie, SpectrogramTimeSerie>>;
24
26
25 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
27 class SCIQLOP_CORE_EXPORT Variable2 : public QObject
26 {
28 {
@@ -52,6 +54,9 public:
52 void setData(const std::vector<AnyTimeSerie*>& dataSeries,
54 void setData(const std::vector<AnyTimeSerie*>& dataSeries,
53 const DateTimeRange& range, bool notify = true);
55 const DateTimeRange& range, bool notify = true);
54
56
57 void setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
58 const DateTimeRange& range, bool notify = true);
59
55 static QByteArray
60 static QByteArray
56 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
61 mimeData(const std::vector<std::shared_ptr<Variable2>>& variables)
57 {
62 {
@@ -42,7 +42,7 struct Variable2::VariablePrivate
42 PROPERTY_(m_Name, name, setName, QString)
42 PROPERTY_(m_Name, name, setName, QString)
43 PROPERTY_(m_Range, range, setRange, DateTimeRange)
43 PROPERTY_(m_Range, range, setRange, DateTimeRange)
44 PROPERTY_(m_Metadata, metadata, setMetadata, QVariantHash)
44 PROPERTY_(m_Metadata, metadata, setMetadata, QVariantHash)
45 AnyTimeSerie& dataSeries() { return *m_TimeSerie.get(); }
45 AnyTimeSerie* dataSeries() { return m_TimeSerie.get(); }
46 void setDataSeries(std::unique_ptr<AnyTimeSerie>&& timeSerie)
46 void setDataSeries(std::unique_ptr<AnyTimeSerie>&& timeSerie)
47 {
47 {
48 QWriteLocker lock{&m_Lock};
48 QWriteLocker lock{&m_Lock};
@@ -73,45 +73,87 DateTimeRange Variable2::range() const noexcept { return impl->range(); }
73
73
74 std::size_t Variable2::nbPoints() const noexcept { return impl->nbPoints(); }
74 std::size_t Variable2::nbPoints() const noexcept { return impl->nbPoints(); }
75
75
76 AnyTimeSerie* Variable2::data() const noexcept {}
76 AnyTimeSerie* Variable2::data() const noexcept { return impl->dataSeries(); }
77
77
78 DataSeriesType Variable2::type() const noexcept { return impl->type(); }
78 DataSeriesType Variable2::type() const noexcept { return impl->type(); }
79
79
80 QVariantHash Variable2::metadata() const noexcept {}
80 QVariantHash Variable2::metadata() const noexcept {}
81
81
82 // template<typename T>
83 // std::unique_ptr<AnyTimeSerie> _merge(std::vector<AnyTimeSerie*> source)
84 //{
85 // std::unique_ptr<AnyTimeSerie> dest = std::make_unique<AnyTimeSerie>();
86 // std::sort(std::begin(source), std::end(source),
87 // [](AnyTimeSerie* a, AnyTimeSerie* b) {
88 // return a->get<T>().front().t() < b->get<T>().front().t();
89 // });
90 // *dest = std::move(*source.front());
91 // std::for_each(
92 // std::begin(source) + 1, std::end(source), [&dest](AnyTimeSerie* serie) {
93 // std::copy(std::begin(serie->get<T>()), std::end(serie->get<T>()),
94 // std::back_inserter(dest->get<T>()));
95 // });
96 // return dest;
97 //}
98
82 template<typename T>
99 template<typename T>
83 void _merge(const std::vector<AnyTimeSerie*>& source, AnyTimeSerie* dest)
100 std::unique_ptr<AnyTimeSerie>
101 _merge(std::vector<TimeSeries::ITimeSerie*> source)
84 {
102 {
85 // std::for_each(
103 std::unique_ptr<AnyTimeSerie> dest = std::make_unique<AnyTimeSerie>();
86 // std::cbegin(source) + 1, std::cend(source), [dest](AnyTimeSerie*
104 std::sort(std::begin(source), std::end(source),
87 // serie) {
105 [](TimeSeries::ITimeSerie* a, TimeSeries::ITimeSerie* b) {
88 // std::copy(std::begin(serie->get<T>()), std::end(serie->get<T>()),
106 if(a->size() && b->size()) return a->t(0) < b->t(0);
89 // std::back_inserter(dest->get<T>()));
107 return false;
90 // });
108 });
109 *dest = std::move(*static_cast<T*>(source.front()));
110 std::for_each(std::begin(source) + 1, std::end(source),
111 [&dest](TimeSeries::ITimeSerie* serie) {
112 std::copy(std::begin(*static_cast<T*>(serie)),
113 std::end(*static_cast<T*>(serie)),
114 std::back_inserter(dest->get<T>()));
115 });
116 return dest;
91 }
117 }
92
118
119 // std::unique_ptr<AnyTimeSerie>
120 // merge(const std::vector<AnyTimeSerie*>& dataSeries)
121 //{
122 // switch(DataSeriesType(dataSeries.front()->index()))
123 // {
124 // case DataSeriesType::NONE: break;
125 // case DataSeriesType::SCALAR: return _merge<ScalarTimeSerie>(dataSeries);
126 // case DataSeriesType::VECTOR: return _merge<VectorTimeSerie>(dataSeries);
127 // case DataSeriesType::SPECTROGRAM:
128 // return _merge<SpectrogramTimeSerie>(dataSeries);
129 // }
130 // return std::unique_ptr<AnyTimeSerie>{};
131 //}
132
93 std::unique_ptr<AnyTimeSerie>
133 std::unique_ptr<AnyTimeSerie>
94 merge(const std::vector<AnyTimeSerie*>& dataSeries)
134 merge(const std::vector<TimeSeries::ITimeSerie*>& dataSeries)
95 {
135 {
96 std::unique_ptr<AnyTimeSerie> ts;
136 if(dynamic_cast<ScalarTimeSerie*>(dataSeries.front()))
97 *ts = *dataSeries.front();
137 return _merge<ScalarTimeSerie>(dataSeries);
98 switch(DataSeriesType(ts->index()))
138 if(dynamic_cast<VectorTimeSerie*>(dataSeries.front()))
99 {
139 return _merge<VectorTimeSerie>(dataSeries);
100 case DataSeriesType::NONE: break;
140 if(dynamic_cast<SpectrogramTimeSerie*>(dataSeries.front()))
101 case DataSeriesType::SCALAR:
141 return _merge<SpectrogramTimeSerie>(dataSeries);
102 _merge<ScalarTimeSerie>(dataSeries, ts.get());
142 return std::unique_ptr<AnyTimeSerie>{};
103 break;
104 case DataSeriesType::VECTOR:
105 _merge<VectorTimeSerie>(dataSeries, ts.get());
106 break;
107 case DataSeriesType::SPECTROGRAM:
108 // merge<Spe>(dataSeries, ts.get());
109 break;
110 }
111 return ts;
112 }
143 }
113
144
114 void Variable2::setData(const std::vector<AnyTimeSerie*>& dataSeries,
145 // void Variable2::setData(const std::vector<AnyTimeSerie*>& dataSeries,
146 // const DateTimeRange& range, bool notify)
147 //{
148 // if(dataSeries.size())
149 // {
150 // impl->setDataSeries(merge(dataSeries));
151 // impl->setRange(range);
152 // if(notify) emit this->updated(this->ID());
153 // }
154 //}
155
156 void Variable2::setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries,
115 const DateTimeRange& range, bool notify)
157 const DateTimeRange& range, bool notify)
116 {
158 {
117 if(dataSeries.size())
159 if(dataSeries.size())
@@ -157,6 +157,8 PYBIND11_MODULE(pysciqlopcore, m)
157 .def_property_readonly(
157 .def_property_readonly(
158 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
158 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
159 .def_property_readonly(
159 .def_property_readonly(
160 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
161 .def_property_readonly(
160 "t",
162 "t",
161 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
163 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
162 return ts.axis(0);
164 return ts.axis(0);
@@ -166,6 +168,19 PYBIND11_MODULE(pysciqlopcore, m)
166 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
168 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
167 .def(py::init<>())
169 .def(py::init<>())
168 .def(py::init<std::size_t>())
170 .def(py::init<std::size_t>())
171 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
172 assert(t.size() == values.size());
173 ScalarTimeSerie::axis_t _t(t.size());
174 ScalarTimeSerie::axis_t _values(t.size());
175 auto t_vew = t.unchecked<1>();
176 auto values_vew = values.unchecked<1>();
177 for(int i = 0; i < t.size(); i++)
178 {
179 _t[i] = t_vew[i];
180 _values[i] = values_vew[i];
181 }
182 return ScalarTimeSerie(_t, _values);
183 }))
169 .def("__getitem__",
184 .def("__getitem__",
170 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
185 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
171 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
186 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
@@ -191,14 +206,26 PYBIND11_MODULE(pysciqlopcore, m)
191 *(ts.begin() + key) = value;
206 *(ts.begin() + key) = value;
192 });
207 });
193
208
209 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>(
210 m, "SpectrogramTimeSerie")
211 .def(py::init<>())
212 .def(py::init<const std::vector<std::size_t>>());
213
194 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
214 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
195 .def(py::init<const QString&>())
215 .def(py::init<const QString&>())
196 .def_property("name", &Variable2::name, &Variable2::setName)
216 .def_property("name", &Variable2::name, &Variable2::setName)
197 .def_property_readonly("range", &Variable2::range)
217 .def_property_readonly("range", &Variable2::range)
198 .def_property_readonly("nbPoints", &Variable2::nbPoints)
218 .def_property_readonly("nbPoints", &Variable2::nbPoints)
199 .def_property_readonly(
219 .def_property_readonly(
200 "dataSeries", [](const Variable2& var) { return var.data()->base(); })
220 "data",
201 .def("set_data", &Variable2::setData)
221 [](const Variable2& var) -> TimeSeries::ITimeSerie* {
222 auto data = var.data();
223 if(data) return data->base();
224 return nullptr;
225 })
226 .def("set_data",
227 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
228 const DateTimeRange& range) { var.setData(ts_list, range); })
202 .def("__len__", &Variable2::nbPoints)
229 .def("__len__", &Variable2::nbPoints)
203 .def("__repr__", __repr__<Variable2>);
230 .def("__repr__", __repr__<Variable2>);
204
231
@@ -49,3 +49,12 declare_test(TestVariableController2Async TestVariableController2Async Variable/
49 declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test")
49 declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test")
50
50
51 declare_test(TestCatalogueController TestCatalogueController CatalogueController/TestCatalogueController.cpp "sciqlopcore;TestUtils;Qt5::Test")
51 declare_test(TestCatalogueController TestCatalogueController CatalogueController/TestCatalogueController.cpp "sciqlopcore;TestUtils;Qt5::Test")
52
53
54 find_package(PythonInterp 3 REQUIRED)
55
56 add_test(NAME TestVariables
57 COMMAND ${PYTHON_EXECUTABLE}
58 ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py
59 TestVariables)
60 set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
@@ -1,223 +1,248
1 #include <Common/Numeric.h>
2 #include <Data/DateTimeRange.h>
3 #include <Data/DateTimeRangeHelper.h>
1 #include <QObject>
4 #include <QObject>
2 #include <QtTest>
3 #include <QUuid>
5 #include <QUuid>
6 #include <QtTest>
4 #include <limits>
7 #include <limits>
5
8
6
7 #include <Data/DateTimeRange.h>
8 #include <Data/DateTimeRangeHelper.h>
9 #include <Common/Numeric.h>
10
11 Q_DECLARE_METATYPE(Seconds<double>);
9 Q_DECLARE_METATYPE(Seconds<double>);
12 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
10 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
13
11
14 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
12 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
15 {
13 {
16 double start_epoch = start.toMSecsSinceEpoch();
14 double start_epoch = start.toMSecsSinceEpoch();
17 double stop_epoch = stop.toMSecsSinceEpoch();
15 double stop_epoch = stop.toMSecsSinceEpoch();
18 auto delta = stop_epoch - start_epoch;
16 auto delta = stop_epoch - start_epoch;
19 auto dt_ms = (zoom-1.)*(double(delta))/2.;
17 auto dt_ms = (zoom - 1.) * (double(delta)) / 2.;
20 return DateTimeRange{(start_epoch - dt_ms)/1000., (stop_epoch + dt_ms)/1000.};
18 return DateTimeRange{(start_epoch - dt_ms) / 1000.,
19 (stop_epoch + dt_ms) / 1000.};
21 }
20 }
22
21
23 class TestDateTimeRange: public QObject {
22 class TestDateTimeRange : public QObject
24 Q_OBJECT
23 {
24 Q_OBJECT
25
25
26 private slots:
26 private slots:
27 void testRangeDelta_data()
27 void testRangeDelta_data()
28 {
28 {
29 QTest::addColumn<QDateTime>("tstart");
29 QTest::addColumn<QDateTime>("tstart");
30 QTest::addColumn<QDateTime>("tend");
30 QTest::addColumn<QDateTime>("tend");
31 QTest::addColumn<double>("expected");
31 QTest::addColumn<double>("expected");
32 auto now = QDateTime::currentDateTime();
32 auto now = QDateTime::currentDateTime();
33 auto yesterday = QDateTime::currentDateTime().addDays(-1);
33 auto yesterday = QDateTime::currentDateTime().addDays(-1);
34 QTest::newRow("No delta") << now << now << 0.;
34 QTest::newRow("No delta") << now << now << 0.;
35 QTest::newRow("One day delta") << yesterday << now << 60.*60.*24.;
35 QTest::newRow("One day delta") << yesterday << now << 60. * 60. * 24.;
36 QTest::newRow("Minus one day delta") << now << yesterday << -60.*60.*24.;
36 QTest::newRow("Minus one day delta")
37 }
37 << now << yesterday << -60. * 60. * 24.;
38
38 }
39 void testRangeDelta()
39
40 void testRangeDelta()
41 {
42 QFETCH(QDateTime, tstart);
43 QFETCH(QDateTime, tend);
44 QFETCH(double, expected);
45 auto range = DateTimeRange::fromDateTime(tstart, tend);
46 double delta = range.delta();
47 // Since it is built from QDateTime don't expect better resolution
48 QVERIFY((delta - expected) <= 0.002);
49 }
50
51 void testRangeShift_data()
52 {
53 QTest::addColumn<DateTimeRange>("initial");
54 QTest::addColumn<Seconds<double>>("shift");
55 QTest::addColumn<DateTimeRange>("expected");
56 auto now = QDateTime::currentDateTime();
57 auto yestd = QDateTime::currentDateTime().addDays(-1);
58 auto range = DateTimeRange::fromDateTime(yestd, now);
59 QTest::newRow("No shift") << range << Seconds<double>{0.} << range;
60
61 QTest::newRow("One milisecond left")
62 << range << Seconds<double>{-.001}
63 << DateTimeRange::fromDateTime(yestd.addMSecs(-1.), now.addMSecs(-1.));
64 QTest::newRow("One milisecond right")
65 << range << Seconds<double>{.001}
66 << DateTimeRange::fromDateTime(yestd.addMSecs(1.), now.addMSecs(1.));
67 QTest::newRow("One second left")
68 << range << Seconds<double>{-1.}
69 << DateTimeRange::fromDateTime(yestd.addSecs(-1.), now.addSecs(-1.));
70 QTest::newRow("One second right")
71 << range << Seconds<double>{1.}
72 << DateTimeRange::fromDateTime(yestd.addSecs(1.), now.addSecs(1.));
73 QTest::newRow("One year left")
74 << range << Seconds<double>{-365. * 24. * 60. * 60.}
75 << DateTimeRange::fromDateTime(yestd.addSecs(-365 * 24 * 60 * 60),
76 now.addSecs(-365 * 24 * 60 * 60));
77 QTest::newRow("One year right")
78 << range << Seconds<double>{365. * 24. * 60. * 60.}
79 << DateTimeRange::fromDateTime(yestd.addSecs(365 * 24 * 60 * 60),
80 now.addSecs(365 * 24 * 60 * 60));
81 }
82
83 void testRangeShift()
84 {
85 QFETCH(DateTimeRange, initial);
86 QFETCH(Seconds<double>, shift);
87 QFETCH(DateTimeRange, expected);
88 QCOMPARE(initial + shift, expected);
89 }
90
91 void testRangeZoom_data()
92 {
93 QTest::addColumn<DateTimeRange>("initial");
94 QTest::addColumn<double>("zoom");
95 QTest::addColumn<DateTimeRange>("expected");
96 auto now = QDateTime::currentDateTime();
97 auto yestd = QDateTime::currentDateTime().addDays(-1);
98 auto range = DateTimeRange::fromDateTime(yestd, now);
99 QTest::newRow("No zoom") << range << 1. << range;
100
101 QTest::newRow("Zoom IN 0.001")
102 << range << 1.001 << computeZoom(yestd, now, 1.001);
103 QTest::newRow("Zoom OUT 0.001")
104 << range << 0.999 << computeZoom(yestd, now, 0.999);
105 }
106 void testRangeZoom()
107 {
108 QFETCH(DateTimeRange, initial);
109 QFETCH(double, zoom);
110 QFETCH(DateTimeRange, expected);
111 QCOMPARE(initial * zoom, expected);
112 }
113
114 void testRangeContains_data()
115 {
116 QTest::addColumn<DateTimeRange>("range");
117 QTest::addColumn<DateTimeRange>("range2");
118 QTest::addColumn<bool>("contains");
119 auto now = QDateTime::currentDateTime();
120 auto yestd = QDateTime::currentDateTime().addDays(-1);
121 auto range = DateTimeRange::fromDateTime(yestd, now);
122 QTest::newRow("Same range") << range << range << true;
123 QTest::newRow("Smaller range") << range << range * 0.8 << true;
124 QTest::newRow("Bigger range") << range << range * 1.2 << false;
125 QTest::newRow("Shifted range with overlap")
126 << range << range + Seconds<double>{1000.} << false;
127 QTest::newRow("Shifted range without overlap")
128 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
129 }
130
131 void testRangeContains()
132 {
133 QFETCH(DateTimeRange, range);
134 QFETCH(DateTimeRange, range2);
135 QFETCH(bool, contains);
136 QCOMPARE(range.contains(range2), contains);
137 }
138
139 void testRangeIntersect_data()
140 {
141 QTest::addColumn<DateTimeRange>("range");
142 QTest::addColumn<DateTimeRange>("range2");
143 QTest::addColumn<bool>("contains");
144 auto now = QDateTime::currentDateTime();
145 auto yestd = QDateTime::currentDateTime().addDays(-1);
146 auto tomorrow = QDateTime::currentDateTime().addDays(1);
147 auto range = DateTimeRange::fromDateTime(yestd, now);
148 auto range2 = DateTimeRange::fromDateTime(now, tomorrow);
149 QTest::newRow("Same range") << range << range << true;
150 QTest::newRow("Smaller range") << range << range * 0.8 << true;
151 QTest::newRow("Bigger range") << range << range * 1.2 << true;
152 QTest::newRow("Shifted range with overlap")
153 << range << range + Seconds<double>{1000.} << true;
154 QTest::newRow("Shifted range with overlaping boundary")
155 << range << range2 << true;
156 QTest::newRow("Shifted range .1 seonds outside")
157 << range << range2 + Seconds<double>{.1} << false;
158 QTest::newRow("Shifted range without overlap")
159 << range << range + Seconds<double>{24. * 60. * 60. * 10} << false;
160 }
161
162 void testRangeIntersect()
163 {
164 QFETCH(DateTimeRange, range);
165 QFETCH(DateTimeRange, range2);
166 QFETCH(bool, contains);
167 QCOMPARE(range.intersect(range2), contains);
168 }
169
170 void testRangeTransformations_data()
171 {
172 QTest::addColumn<DateTimeRange>("range1");
173 QTest::addColumn<DateTimeRange>("range2");
174 QTest::addColumn<DateTimeRangeTransformation>("transformation");
175 auto now = QDateTime::currentDateTime();
176 auto yestd = QDateTime::currentDateTime().addDays(-1);
177 auto range = DateTimeRange::fromDateTime(yestd, now);
178
179 QTest::newRow("Same range")
180 << range << range
181 << DateTimeRangeTransformation{1., Seconds<double>{0.}};
182
183 QTest::newRow("Transformatio 1.1x + 10s")
184 << range << range * 1.1 + Seconds<double>{10.}
185 << DateTimeRangeTransformation{1.1, Seconds<double>{10.}};
186
187 QTest::newRow("Transformatio 1.x + 10s")
188 << range << range * 1. + Seconds<double>{10.}
189 << DateTimeRangeTransformation{1., Seconds<double>{10.}};
190
191 QTest::newRow("Transformatio 1.1x + 0s")
192 << range << range * 1.1 + Seconds<double>{0.}
193 << DateTimeRangeTransformation{1.1, Seconds<double>{0.}};
194
195 QTest::newRow("Transformatio 0.9x - 10s")
196 << range << range * 0.9 + Seconds<double>{-10.}
197 << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}};
198 }
199 void testRangeTransformations()
200 {
201 QFETCH(DateTimeRange, range1);
202 QFETCH(DateTimeRange, range2);
203 QFETCH(DateTimeRangeTransformation, transformation);
204 auto computed_tr =
205 DateTimeRangeHelper::computeTransformation(range1, range2).value();
206 QCOMPARE(computed_tr, transformation);
207 QCOMPARE(range1.transform(transformation), range2);
208 QCOMPARE(range1.transform(computed_tr), range2);
209 }
210
211 void testRangeDiff_data()
212 {
213 QTest::addColumn<DateTimeRange>("source");
214 QTest::addColumn<DateTimeRange>("destination");
215 QTest::addColumn<int>("count");
216 auto now = QDateTime::currentDateTime();
217 auto yestd = QDateTime::currentDateTime().addDays(-1);
218 auto range = DateTimeRange::fromDateTime(yestd, now);
219 QTest::newRow("Same range") << range << range << 0;
220 QTest::newRow("No missing data (zoom in)") << range << range * 0.9 << 0;
221 QTest::newRow("Missing data on both sides (zoom out)")
222 << range << range * 2. << 2;
223 QTest::newRow("Missing data on left side (pan left)")
224 << range << range - Seconds<double>{1000.} << 1;
225 QTest::newRow("Missing data on right side (pan right)")
226 << range << range + Seconds<double>{1000.} << 1;
227 QTest::newRow("Missing data on right side no intersect (big pan right)")
228 << range << range + Seconds<double>{24. * 60. * 60. * 2} << 1;
229 QTest::newRow("Missing data on left side no intersect (big pan left)")
230 << range << range - Seconds<double>{24. * 60. * 60. * 2} << 1;
231 }
232
233 void testRangeDiff()
234 {
235 QFETCH(DateTimeRange, source);
236 QFETCH(DateTimeRange, destination);
237 QFETCH(int, count);
238 auto diff = destination - source;
239 QCOMPARE(diff.size(), count);
240 for(const auto& range : diff)
40 {
241 {
41 QFETCH(QDateTime,tstart);
242 QVERIFY(range.delta().value > 0.);
42 QFETCH(QDateTime,tend);
43 QFETCH(double,expected);
44 auto range = DateTimeRange::fromDateTime(tstart, tend);
45 double delta = range.delta();
46 // Since it is built from QDateTime don't expect better resolution
47 QVERIFY((delta-expected) <= 0.002);
48 }
49
50 void testRangeShift_data()
51 {
52 QTest::addColumn<DateTimeRange>("initial");
53 QTest::addColumn<Seconds<double>>("shift");
54 QTest::addColumn<DateTimeRange>("expected");
55 auto now = QDateTime::currentDateTime();
56 auto yestd = QDateTime::currentDateTime().addDays(-1);
57 auto range = DateTimeRange::fromDateTime(yestd, now);
58 QTest::newRow("No shift") << range << Seconds<double>{0.} << range;
59
60 QTest::newRow("One milisecond left") << range << Seconds<double>{-.001} <<
61 DateTimeRange::fromDateTime(yestd.addMSecs(-1.), now.addMSecs(-1.));
62 QTest::newRow("One milisecond right") << range << Seconds<double>{.001} <<
63 DateTimeRange::fromDateTime(yestd.addMSecs(1.), now.addMSecs(1.));
64 QTest::newRow("One second left") << range << Seconds<double>{-1.} <<
65 DateTimeRange::fromDateTime(yestd.addSecs(-1.), now.addSecs(-1.));
66 QTest::newRow("One second right") << range << Seconds<double>{1.} <<
67 DateTimeRange::fromDateTime(yestd.addSecs(1.), now.addSecs(1.));
68 QTest::newRow("One year left") << range << Seconds<double>{-365.*24.*60.*60.} <<
69 DateTimeRange::fromDateTime(yestd.addYears(-1.), now.addYears(-1.));
70 QTest::newRow("One year right") << range << Seconds<double>{365.*24.*60.*60.} <<
71 DateTimeRange::fromDateTime(yestd.addYears(1.), now.addYears(1.));
72 }
73 void testRangeShift()
74 {
75 QFETCH(DateTimeRange,initial);
76 QFETCH(Seconds<double>,shift);
77 QFETCH(DateTimeRange,expected);
78 QCOMPARE(initial+shift, expected);
79 }
80
81 void testRangeZoom_data()
82 {
83 QTest::addColumn<DateTimeRange>("initial");
84 QTest::addColumn<double>("zoom");
85 QTest::addColumn<DateTimeRange>("expected");
86 auto now = QDateTime::currentDateTime();
87 auto yestd = QDateTime::currentDateTime().addDays(-1);
88 auto range = DateTimeRange::fromDateTime(yestd, now);
89 QTest::newRow("No zoom") << range << 1. << range;
90
91 QTest::newRow("Zoom IN 0.001") << range << 1.001 <<
92 computeZoom(yestd, now, 1.001);
93 QTest::newRow("Zoom OUT 0.001") << range << 0.999 <<
94 computeZoom(yestd, now, 0.999);
95 }
96 void testRangeZoom()
97 {
98 QFETCH(DateTimeRange,initial);
99 QFETCH(double,zoom);
100 QFETCH(DateTimeRange,expected);
101 QCOMPARE(initial*zoom, expected);
102 }
103
104 void testRangeContains_data()
105 {
106 QTest::addColumn<DateTimeRange>("range");
107 QTest::addColumn<DateTimeRange>("range2");
108 QTest::addColumn<bool>("contains");
109 auto now = QDateTime::currentDateTime();
110 auto yestd = QDateTime::currentDateTime().addDays(-1);
111 auto range = DateTimeRange::fromDateTime(yestd, now);
112 QTest::newRow("Same range") << range << range << true;
113 QTest::newRow("Smaller range") << range << range * 0.8 << true;
114 QTest::newRow("Bigger range") << range << range * 1.2 << false;
115 QTest::newRow("Shifted range with overlap") << range << range + Seconds<double>{1000.} << false;
116 QTest::newRow("Shifted range without overlap") << range << range + Seconds<double>{24.*60.*60.*10} << false;
117 }
118
119 void testRangeContains()
120 {
121 QFETCH(DateTimeRange,range);
122 QFETCH(DateTimeRange,range2);
123 QFETCH(bool,contains);
124 QCOMPARE(range.contains(range2), contains);
125 }
126
127 void testRangeIntersect_data()
128 {
129 QTest::addColumn<DateTimeRange>("range");
130 QTest::addColumn<DateTimeRange>("range2");
131 QTest::addColumn<bool>("contains");
132 auto now = QDateTime::currentDateTime();
133 auto yestd = QDateTime::currentDateTime().addDays(-1);
134 auto tomorrow = QDateTime::currentDateTime().addDays(1);
135 auto range = DateTimeRange::fromDateTime(yestd, now);
136 auto range2 = DateTimeRange::fromDateTime(now, tomorrow);
137 QTest::newRow("Same range") << range << range << true;
138 QTest::newRow("Smaller range") << range << range * 0.8 << true;
139 QTest::newRow("Bigger range") << range << range * 1.2 << true;
140 QTest::newRow("Shifted range with overlap") << range << range + Seconds<double>{1000.} << true;
141 QTest::newRow("Shifted range with overlaping boundary") << range << range2 << true;
142 QTest::newRow("Shifted range .1 seonds outside") << range << range2 + Seconds<double>{.1} << false;
143 QTest::newRow("Shifted range without overlap") << range << range + Seconds<double>{24.*60.*60.*10} << false;
144 }
145
146 void testRangeIntersect()
147 {
148 QFETCH(DateTimeRange,range);
149 QFETCH(DateTimeRange,range2);
150 QFETCH(bool,contains);
151 QCOMPARE(range.intersect(range2), contains);
152 }
153
154 void testRangeTransformations_data()
155 {
156 QTest::addColumn<DateTimeRange>("range1");
157 QTest::addColumn<DateTimeRange>("range2");
158 QTest::addColumn<DateTimeRangeTransformation>("transformation");
159 auto now = QDateTime::currentDateTime();
160 auto yestd = QDateTime::currentDateTime().addDays(-1);
161 auto range = DateTimeRange::fromDateTime(yestd, now);
162
163 QTest::newRow("Same range") << range << range << DateTimeRangeTransformation{1.,Seconds<double>{0.}};
164
165 QTest::newRow("Transformatio 1.1x + 10s") << range << range*1.1 + Seconds<double>{10.}
166 << DateTimeRangeTransformation{1.1, Seconds<double>{10.}};
167
168 QTest::newRow("Transformatio 1.x + 10s") << range << range*1. + Seconds<double>{10.}
169 << DateTimeRangeTransformation{1., Seconds<double>{10.}};
170
171 QTest::newRow("Transformatio 1.1x + 0s") << range << range*1.1 + Seconds<double>{0.}
172 << DateTimeRangeTransformation{1.1,Seconds<double>{0.}};
173
174 QTest::newRow("Transformatio 0.9x - 10s") << range << range*0.9 + Seconds<double>{-10.}
175 << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}};
176
177 }
178 void testRangeTransformations()
179 {
180 QFETCH(DateTimeRange,range1);
181 QFETCH(DateTimeRange,range2);
182 QFETCH(DateTimeRangeTransformation, transformation);
183 auto computed_tr = DateTimeRangeHelper::computeTransformation(range1,range2).value();
184 QCOMPARE(computed_tr, transformation);
185 QCOMPARE(range1.transform(transformation),range2);
186 QCOMPARE(range1.transform(computed_tr),range2);
187 }
188
189 void testRangeDiff_data()
190 {
191 QTest::addColumn<DateTimeRange>("source");
192 QTest::addColumn<DateTimeRange>("destination");
193 QTest::addColumn<int>("count");
194 auto now = QDateTime::currentDateTime();
195 auto yestd = QDateTime::currentDateTime().addDays(-1);
196 auto range = DateTimeRange::fromDateTime(yestd, now);
197 QTest::newRow("Same range") << range << range << 0;
198 QTest::newRow("No missing data (zoom in)") << range << range*0.9 << 0;
199 QTest::newRow("Missing data on both sides (zoom out)") << range << range*2. << 2;
200 QTest::newRow("Missing data on left side (pan left)") << range << range-Seconds<double>{1000.} << 1;
201 QTest::newRow("Missing data on right side (pan right)") << range << range+Seconds<double>{1000.} << 1;
202 QTest::newRow("Missing data on right side no intersect (big pan right)") << range << range+Seconds<double>{24.*60.*60.*2} << 1;
203 QTest::newRow("Missing data on left side no intersect (big pan left)") << range << range-Seconds<double>{24.*60.*60.*2} << 1;
204
205 }
206
207 void testRangeDiff()
208 {
209 QFETCH(DateTimeRange,source);
210 QFETCH(DateTimeRange,destination);
211 QFETCH(int, count);
212 auto diff = destination-source;
213 QCOMPARE(diff.size(),count);
214 for(const auto& range:diff)
215 {
216 QVERIFY(range.delta().value>0.);
217 }
218 }
243 }
244 }
219 };
245 };
220 QTEST_MAIN(TestDateTimeRange)
246 QTEST_MAIN(TestDateTimeRange)
221
247
222
223 #include "TestDateTimeRange.moc"
248 #include "TestDateTimeRange.moc"
General Comments 0
You need to be logged in to leave comments. Login now