##// END OF EJS Templates
Added more features in DateTimeRange to prepare variable synchronization...
jeandet -
r8:69bf3d2aeca6
parent child
Show More
@@ -0,0 +1,47
1 #ifndef SCIQLOP_DATETIMERANGEHELPER_H
2 #define SCIQLOP_DATETIMERANGEHELPER_H
3
4 #include <cmath>
5 #include <QObject>
6
7 #include <QDebug>
8
9 #include <opaque/numeric_typedef.hpp>
10 #include <Common/DateUtils.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/Numeric.h>
13 #include <Data/DateTimeRange.h>
14
15 namespace DateTimeRangeHelper {
16
17
18
19 bool isPureShift(const DateTimeRange& range1, const DateTimeRange& range2)
20 {
21 return SciQLop::numeric::almost_equal<double>(range1.delta(), range2.delta(), 1.)
22 && !SciQLop::numeric::almost_equal(range1.m_TStart, range2.m_TStart, 1.);
23 }
24
25 bool isPureZoom(const DateTimeRange& range1, const DateTimeRange& range2)
26 {
27 return !SciQLop::numeric::almost_equal<double>(range1.delta(),range2.delta(),1.)&&
28 SciQLop::numeric::almost_equal<double>(range1.center(), range2.center(),1.);
29 }
30
31 /**
32 * @brief computeTransformation such as range2 = zoom*range1 + shift
33 * @param range1
34 * @param range2
35 * @return trnaformation applied to range1 to get range2
36 */
37 DateTimeRangeTransformation computeTransformation(const DateTimeRange& range1, const DateTimeRange& range2)
38 {
39 DateTimeRangeTransformation transformation;
40 transformation.zoom = range2.delta()/range1.delta();
41 transformation.shift = range2.center() - (range1*transformation.zoom).center();
42 return transformation;
43 }
44
45 }
46
47 #endif // SCIQLOP_DATETIMERANGEHELPER_H
@@ -56,6 +56,7 FILE (GLOB_RECURSE core_SRCS
56 ./include/Data/VariableRequest.h
56 ./include/Data/VariableRequest.h
57 ./include/Data/VectorSeries.h
57 ./include/Data/VectorSeries.h
58 ./include/Data/DateTimeRange.h
58 ./include/Data/DateTimeRange.h
59 ./include/Data/DateTimeRangeHelper.h
59 ./include/Data/ScalarSeries.h
60 ./include/Data/ScalarSeries.h
60 ./include/Data/DataSeriesMergeHelper.h
61 ./include/Data/DataSeriesMergeHelper.h
61 ./include/Data/DataSeries.h
62 ./include/Data/DataSeries.h
@@ -1,5 +1,5
1 #ifndef SCIQLOP_SQPRANGE_H
1 #ifndef SCIQLOP_DATETIMERANGE_H
2 #define SCIQLOP_SQPRANGE_H
2 #define SCIQLOP_DATETIMERANGE_H
3
3
4 #include <cmath>
4 #include <cmath>
5 #include <QObject>
5 #include <QObject>
@@ -25,6 +25,17 struct Seconds : opaque::numeric_typedef<T, Seconds<T>> ,
25 operator T () const {return this->value;}
25 operator T () const {return this->value;}
26 };
26 };
27
27
28 struct DateTimeRangeTransformation
29 {
30 double zoom;
31 Seconds<double> shift;
32 bool operator==(const DateTimeRangeTransformation& other) const
33 {
34 return SciQLop::numeric::almost_equal(zoom, other.zoom, 1.) &&
35 SciQLop::numeric::almost_equal<double>(shift, other.shift, 1.);
36 }
37 };
38
28 /**
39 /**
29 * @brief The SqpRange struct holds the information of time parameters
40 * @brief The SqpRange struct holds the information of time parameters
30 */
41 */
@@ -48,18 +59,25 struct DateTimeRange {
48 /// End time (UTC)
59 /// End time (UTC)
49 double m_TEnd;
60 double m_TEnd;
50
61
51 Seconds<double> delta()const {return Seconds<double>{this->m_TEnd - this->m_TStart};}
62 Seconds<double> delta()const noexcept{return Seconds<double>{this->m_TEnd - this->m_TStart};}
52
63
53 bool contains(const DateTimeRange &dateTime) const noexcept
64 bool contains(const DateTimeRange &dateTime) const noexcept
54 {
65 {
55 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
66 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
56 }
67 }
57
68
69 Seconds<double> center() const noexcept
70 {
71 return Seconds<double>((m_TStart + m_TEnd) / 2.);
72 }
73
58 bool intersect(const DateTimeRange &dateTime) const noexcept
74 bool intersect(const DateTimeRange &dateTime) const noexcept
59 {
75 {
60 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
76 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
61 }
77 }
62
78
79 inline DateTimeRange transform(const DateTimeRangeTransformation& tr)const noexcept;
80
63 bool operator==(const DateTimeRange &other) const
81 bool operator==(const DateTimeRange &other) const
64 {
82 {
65 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1.) &&
83 return SciQLop::numeric::almost_equal(m_TStart, other.m_TStart, 1.) &&
@@ -68,14 +86,14 struct DateTimeRange {
68
86
69 bool operator!=(const DateTimeRange &other) const { return !(*this == other); }
87 bool operator!=(const DateTimeRange &other) const { return !(*this == other); }
70
88
71 void grow(double factor)
89 void grow(double factor)noexcept
72 {
90 {
73 double grow_v{delta()*(factor - 1.)/2.};
91 double grow_v{delta()*(factor - 1.)/2.};
74 m_TStart -= grow_v;
92 m_TStart -= grow_v;
75 m_TEnd += grow_v;
93 m_TEnd += grow_v;
76 }
94 }
77
95
78 void shrink(double factor)
96 void shrink(double factor)noexcept
79 {
97 {
80 double shrink_v{this->delta()*(1. - factor)/2.};
98 double shrink_v{this->delta()*(1. - factor)/2.};
81 m_TStart += shrink_v;
99 m_TStart += shrink_v;
@@ -158,7 +176,14 inline QDebug operator<<(QDebug d, DateTimeRange obj)
158 return d;
176 return d;
159 }
177 }
160
178
179
180
181 DateTimeRange DateTimeRange::transform(const DateTimeRangeTransformation &tr) const noexcept
182 {
183 return DateTimeRange{*this} * tr.zoom + tr.shift;
184 }
185
161 // Required for using shared_ptr in signals/slots
186 // Required for using shared_ptr in signals/slots
162 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
187 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, DateTimeRange)
163
188
164 #endif // SCIQLOP_SQPRANGE_H
189 #endif // SCIQLOP_DATETIMERANGE_H
@@ -29,6 +29,9 public:
29 void asyncChangeRange(std::shared_ptr<Variable> variable, DateTimeRange r);
29 void asyncChangeRange(std::shared_ptr<Variable> variable, DateTimeRange r);
30 const std::set<std::shared_ptr<Variable> > &variables();
30 const std::set<std::shared_ptr<Variable> > &variables();
31
31
32 void synchronize(std::shared_ptr<Variable> var, std::shared_ptr<Variable> with);
33
34
32 signals:
35 signals:
33 void variableAdded(std::shared_ptr<Variable>);
36 void variableAdded(std::shared_ptr<Variable>);
34 void variableDeleted(std::shared_ptr<Variable>);
37 void variableDeleted(std::shared_ptr<Variable>);
@@ -9,6 +9,19 class VariableController2::VariableController2Private
9 std::set<std::shared_ptr<Variable>> _variables;
9 std::set<std::shared_ptr<Variable>> _variables;
10 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
10 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
11 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
11 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
12
13 bool p_contains(std::shared_ptr<Variable> variable)
14 {
15 return _providers.contains(variable->ID());
16 }
17 bool v_contains(std::shared_ptr<Variable> variable)
18 {
19 return SciQLop::containers::contains(this->_variables, variable);
20 }
21 bool sg_contains(std::shared_ptr<Variable> variable)
22 {
23 return _synchronizationGroups.contains(variable->ID());
24 }
12 public:
25 public:
13 VariableController2Private(QObject* parent=Q_NULLPTR)
26 VariableController2Private(QObject* parent=Q_NULLPTR)
14 {
27 {
@@ -28,15 +41,21 public:
28
41
29 void deleteVariable(std::shared_ptr<Variable> variable)
42 void deleteVariable(std::shared_ptr<Variable> variable)
30 {
43 {
31 if(this->_providers.contains(variable->ID()))
44 /*
32 this->_providers.remove(variable->ID());
45 * Removing twice a var is ok but a var without provider has to be a hard error
33 if(SciQLop::containers::contains(this->_variables, variable))
46 * this means we got the var controller in an inconsistent state
47 */
48 if(v_contains(variable))
34 this->_variables.erase(variable);
49 this->_variables.erase(variable);
50 if(p_contains(variable))
51 this->_providers.remove(variable->ID());
52 else
53 SCIQLOP_ERROR("No provider found for given variable");
35 }
54 }
36
55
37 void changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
56 void changeRange(std::shared_ptr<Variable> variable, DateTimeRange r)
38 {
57 {
39 if(_providers.contains(variable->ID()))
58 if(p_contains(variable))
40 {
59 {
41 auto provider = _providers[variable->ID()];
60 auto provider = _providers[variable->ID()];
42 auto data = provider->getData(DataProviderParameters{{r},variable->metadata()});
61 auto data = provider->getData(DataProviderParameters{{r},variable->metadata()});
@@ -48,6 +67,27 public:
48 }
67 }
49 }
68 }
50
69
70 void synchronize(std::shared_ptr<Variable> var, std::shared_ptr<Variable> with)
71 {
72 if(v_contains(var) && v_contains(with))
73 {
74 if(sg_contains(var) && sg_contains(with))
75 {
76
77 auto dest_group = this->_synchronizationGroups[with->ID()];
78 this->_synchronizationGroups[var->ID()] = dest_group;
79 dest_group->addVariable(var->ID());
80 }
81 else
82 {
83 SCIQLOP_ERROR("At least one of the given variables isn't in a sync group");
84 }
85 }
86 else
87 {
88 SCIQLOP_ERROR("At least one of the given variables is not found");
89 }
90 }
51
91
52 const std::set<std::shared_ptr<Variable>>& variables()
92 const std::set<std::shared_ptr<Variable>>& variables()
53 {
93 {
@@ -84,3 +124,8 const std::set<std::shared_ptr<Variable> > &VariableController2::variables()
84 return impl->variables();
124 return impl->variables();
85 }
125 }
86
126
127 void VariableController2::synchronize(std::shared_ptr<Variable> var, std::shared_ptr<Variable> with)
128 {
129 impl->synchronize(var, with);
130 }
131
@@ -5,9 +5,11
5
5
6
6
7 #include <Data/DateTimeRange.h>
7 #include <Data/DateTimeRange.h>
8 #include <Data/DateTimeRangeHelper.h>
8 #include <Common/Numeric.h>
9 #include <Common/Numeric.h>
9
10
10 Q_DECLARE_METATYPE(Seconds<double>);
11 Q_DECLARE_METATYPE(Seconds<double>);
12 Q_DECLARE_METATYPE(DateTimeRangeTransformation);
11
13
12 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
14 DateTimeRange computeZoom(QDateTime start, QDateTime stop, double zoom)
13 {
15 {
@@ -137,6 +139,7 private slots:
137 QTest::newRow("Bigger range") << range << range * 1.2 << true;
139 QTest::newRow("Bigger range") << range << range * 1.2 << true;
138 QTest::newRow("Shifted range with overlap") << range << range + Seconds<double>{1000.} << true;
140 QTest::newRow("Shifted range with overlap") << range << range + Seconds<double>{1000.} << true;
139 QTest::newRow("Shifted range with overlaping boundary") << range << range2 << 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;
140 QTest::newRow("Shifted range without overlap") << range << range + Seconds<double>{24.*60.*60.*10} << false;
143 QTest::newRow("Shifted range without overlap") << range << range + Seconds<double>{24.*60.*60.*10} << false;
141
144
142 }
145 }
@@ -147,6 +150,41 private slots:
147 QFETCH(bool,contains);
150 QFETCH(bool,contains);
148 QCOMPARE(range.intersect(range2), contains);
151 QCOMPARE(range.intersect(range2), contains);
149 }
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);
184 QCOMPARE(computed_tr, transformation);
185 QCOMPARE(range1.transform(transformation),range2);
186 QCOMPARE(range1.transform(computed_tr),range2);
187 }
150 };
188 };
151 QTEST_MAIN(TestDateTimeRange)
189 QTEST_MAIN(TestDateTimeRange)
152
190
@@ -24,6 +24,15 private slots:
24 }
24 }
25 }
25 }
26
26
27 void testAddingTwiceAVar()
28 {
29 auto v = QUuid::createUuid();
30 VariableSynchronizationGroup2 group{v};
31 QVERIFY(group.contains(v));
32 group.addVariable(v);
33 QVERIFY(group.variables().size()==1);
34 }
35
27 void testRemoveVariables()
36 void testRemoveVariables()
28 {
37 {
29 auto v = QUuid::createUuid();
38 auto v = QUuid::createUuid();
General Comments 0
You need to be logged in to leave comments. Login now