@@ -1,1 +1,1 | |||
|
1 | Subproject commit 772f73227be2003fda7309a27d11cd0e248663ad | |
|
1 | Subproject commit 3e1b5ebf191a92c416fb1f51ab071875008f0ff4 |
@@ -1,6 +1,9 | |||
|
1 | 1 | #ifndef SCIQLOP_DATASERIESTYPE_H |
|
2 | 2 | #define SCIQLOP_DATASERIESTYPE_H |
|
3 | 3 | |
|
4 | #include <Data/ScalarTimeSerie.h> | |
|
5 | #include <Data/SpectrogramTimeSerie.h> | |
|
6 | #include <Data/VectorTimeSerie.h> | |
|
4 | 7 | #include <QString> |
|
5 | 8 | |
|
6 | 9 | enum class DataSeriesType |
@@ -30,6 +33,15 struct DataSeriesTypeUtils | |||
|
30 | 33 | return DataSeriesType::NONE; |
|
31 | 34 | } |
|
32 | 35 | } |
|
36 | static DataSeriesType type(TimeSeries::ITimeSerie* ts) | |
|
37 | { | |
|
38 | if(!ts) return DataSeriesType::NONE; | |
|
39 | if(dynamic_cast<ScalarTimeSerie*>(ts)) return DataSeriesType::SCALAR; | |
|
40 | if(dynamic_cast<VectorTimeSerie*>(ts)) return DataSeriesType::VECTOR; | |
|
41 | if(dynamic_cast<SpectrogramTimeSerie*>(ts)) | |
|
42 | return DataSeriesType::SPECTROGRAM; | |
|
43 | return DataSeriesType::NONE; | |
|
44 | } | |
|
33 | 45 | }; |
|
34 | 46 | |
|
35 | 47 | #endif // SCIQLOP_DATASERIESTYPE_H |
@@ -49,6 +49,9 struct DateTimeRange | |||
|
49 | 49 | { |
|
50 | 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(const std::pair<double, double>& range) | |
|
53 | : m_TStart(range.first), m_TEnd(range.second) | |
|
54 | {} | |
|
52 | 55 | /// Creates SqpRange from dates and times |
|
53 | 56 | static DateTimeRange fromDateTime(const QDate& startDate, |
|
54 | 57 | const QTime& startTime, |
@@ -19,11 +19,6 | |||
|
19 | 19 | #include <TimeSeries.h> |
|
20 | 20 | #include <optional> |
|
21 | 21 | |
|
22 | using AnyTimeSerie = | |
|
23 | variant_w_base<TimeSeries::ITimeSerie, | |
|
24 | std::variant<std::monostate, ScalarTimeSerie, | |
|
25 | VectorTimeSerie, SpectrogramTimeSerie>>; | |
|
26 | ||
|
27 | 22 | class SCIQLOP_CORE_EXPORT Variable2 : public QObject |
|
28 | 23 | { |
|
29 | 24 | Q_OBJECT |
@@ -45,7 +40,7 public: | |||
|
45 | 40 | std::size_t nbPoints(); |
|
46 | 41 | |
|
47 | 42 | /// @return the data of the variable, nullptr if there is no data |
|
48 | AnyTimeSerie* data(); | |
|
43 | std::shared_ptr<TimeSeries::ITimeSerie> data(); | |
|
49 | 44 | |
|
50 | 45 | /// @return the type of data that the variable holds |
|
51 | 46 | DataSeriesType type(); |
@@ -71,7 +71,7 public: | |||
|
71 | 71 | _variable->setData(data, _range, true); |
|
72 | 72 | else |
|
73 | 73 | { |
|
74 |
data.push_back(_variable->data() |
|
|
74 | data.push_back(_variable->data().get()); | |
|
75 | 75 | _variable->setData(data, _range, true); |
|
76 | 76 | } |
|
77 | 77 | emit transactionComplete(); |
@@ -43,6 +43,18 static DataSeriesType findDataSeriesType(const QVariantHash& metadata) | |||
|
43 | 43 | return dataSeriesType; |
|
44 | 44 | } |
|
45 | 45 | |
|
46 | std::shared_ptr<TimeSeries::ITimeSerie> | |
|
47 | clone_ts(const std::shared_ptr<TimeSeries::ITimeSerie>& ts) | |
|
48 | { | |
|
49 | if(auto scal_ts = std::dynamic_pointer_cast<ScalarTimeSerie>(ts)) | |
|
50 | return std::make_shared<ScalarTimeSerie>(*scal_ts); | |
|
51 | if(auto scal_ts = std::dynamic_pointer_cast<VectorTimeSerie>(ts)) | |
|
52 | return std::make_shared<VectorTimeSerie>(*scal_ts); | |
|
53 | if(auto scal_ts = std::dynamic_pointer_cast<SpectrogramTimeSerie>(ts)) | |
|
54 | return std::make_shared<SpectrogramTimeSerie>(*scal_ts); | |
|
55 | return nullptr; | |
|
56 | } | |
|
57 | ||
|
46 | 58 | struct Variable2::VariablePrivate |
|
47 | 59 | { |
|
48 | 60 | VariablePrivate(const QString& name, const QVariantHash& metadata) |
@@ -52,51 +64,52 struct Variable2::VariablePrivate | |||
|
52 | 64 | switch(findDataSeriesType(metadata)) |
|
53 | 65 | { |
|
54 | 66 | case DataSeriesType::SCALAR: |
|
55 |
m_TimeSerie = std::make_ |
|
|
67 | m_TimeSerie = std::make_shared<ScalarTimeSerie>(ScalarTimeSerie{}); | |
|
56 | 68 | break; |
|
57 | 69 | case DataSeriesType::VECTOR: |
|
58 |
m_TimeSerie = std::make_ |
|
|
70 | m_TimeSerie = std::make_shared<VectorTimeSerie>(VectorTimeSerie{}); | |
|
59 | 71 | break; |
|
60 | 72 | case DataSeriesType::SPECTROGRAM: |
|
61 | m_TimeSerie = std::make_unique<AnyTimeSerie>(SpectrogramTimeSerie{}); | |
|
73 | m_TimeSerie = | |
|
74 | std::make_shared<SpectrogramTimeSerie>(SpectrogramTimeSerie{}); | |
|
62 | 75 | break; |
|
63 | 76 | default: break; |
|
64 | 77 | } |
|
65 | 78 | } |
|
66 | 79 | |
|
67 |
VariablePrivate(const VariablePrivate& other) |
|
|
80 | VariablePrivate(const VariablePrivate& other) | |
|
81 | : m_Name{other.m_Name}, m_Range{other.m_Range}, | |
|
82 | m_Metadata{other.m_Metadata}, m_RealRange{other.m_RealRange} | |
|
83 | { | |
|
84 | m_TimeSerie = clone_ts(other.m_TimeSerie); | |
|
85 | } | |
|
86 | ||
|
68 | 87 | std::size_t nbPoints() |
|
69 | 88 | { |
|
70 |
if(m_TimeSerie) return m_TimeSerie-> |
|
|
89 | if(m_TimeSerie) return m_TimeSerie->size(); | |
|
71 | 90 | return 0; |
|
72 | 91 | } |
|
73 | 92 | DataSeriesType type() const |
|
74 | 93 | { |
|
75 |
|
|
|
76 | return DataSeriesType::NONE; | |
|
94 | return DataSeriesTypeUtils::type(m_TimeSerie.get()); | |
|
77 | 95 | } |
|
78 | 96 | |
|
79 | 97 | PROPERTY_(m_Name, name, setName, QString) |
|
80 | 98 | PROPERTY_(m_Range, range, setRange, DateTimeRange) |
|
81 | 99 | PROPERTY_(m_Metadata, metadata, setMetadata, QVariantHash) |
|
82 | 100 | PROPERTY_(m_RealRange, realRange, setRealRange, std::optional<DateTimeRange>) |
|
83 |
|
|
|
84 |
void setDataSeries(std:: |
|
|
101 | std::shared_ptr<TimeSeries::ITimeSerie> dataSeries() { return m_TimeSerie; } | |
|
102 | void setDataSeries(std::shared_ptr<TimeSeries::ITimeSerie>&& timeSerie) | |
|
85 | 103 | { |
|
86 | 104 | QWriteLocker lock{&m_Lock}; |
|
87 |
m_TimeSerie = |
|
|
88 | if(m_TimeSerie->index() != 0) | |
|
89 | { | |
|
90 | setRealRange(DateTimeRange( | |
|
91 | m_TimeSerie->base()->t(0), | |
|
92 | m_TimeSerie->base()->t(m_TimeSerie->base()->size() - 1))); | |
|
93 | } | |
|
105 | m_TimeSerie = timeSerie; | |
|
106 | if(m_TimeSerie) { setRealRange(DateTimeRange(m_TimeSerie->axis_range(0))); } | |
|
94 | 107 | else |
|
95 | 108 | { |
|
96 | 109 | setRealRange(std::nullopt); |
|
97 | 110 | } |
|
98 | 111 | } |
|
99 |
std:: |
|
|
112 | std::shared_ptr<TimeSeries::ITimeSerie> m_TimeSerie; | |
|
100 | 113 | QReadWriteLock m_Lock{QReadWriteLock::Recursive}; |
|
101 | 114 | }; |
|
102 | 115 | |
@@ -133,7 +146,10 std::optional<DateTimeRange> Variable2::realRange() | |||
|
133 | 146 | |
|
134 | 147 | std::size_t Variable2::nbPoints() { return impl->nbPoints(); } |
|
135 | 148 | |
|
136 | AnyTimeSerie* Variable2::data() { return impl->dataSeries(); } | |
|
149 | std::shared_ptr<TimeSeries::ITimeSerie> Variable2::data() | |
|
150 | { | |
|
151 | return impl->dataSeries(); | |
|
152 | } | |
|
137 | 153 | |
|
138 | 154 | DataSeriesType Variable2::type() |
|
139 | 155 | { |
@@ -143,81 +159,47 DataSeriesType Variable2::type() | |||
|
143 | 159 | |
|
144 | 160 | QVariantHash Variable2::metadata() const noexcept { return QVariantHash{}; } |
|
145 | 161 | |
|
146 | // template<typename T> | |
|
147 | // std::unique_ptr<AnyTimeSerie> _merge(std::vector<AnyTimeSerie*> source) | |
|
148 | //{ | |
|
149 | // std::unique_ptr<AnyTimeSerie> dest = std::make_unique<AnyTimeSerie>(); | |
|
150 | // std::sort(std::begin(source), std::end(source), | |
|
151 | // [](AnyTimeSerie* a, AnyTimeSerie* b) { | |
|
152 | // return a->get<T>().front().t() < b->get<T>().front().t(); | |
|
153 | // }); | |
|
154 | // *dest = std::move(*source.front()); | |
|
155 | // std::for_each( | |
|
156 | // std::begin(source) + 1, std::end(source), [&dest](AnyTimeSerie* serie) { | |
|
157 | // std::copy(std::begin(serie->get<T>()), std::end(serie->get<T>()), | |
|
158 | // std::back_inserter(dest->get<T>())); | |
|
159 | // }); | |
|
160 | // return dest; | |
|
161 | //} | |
|
162 | ||
|
163 | 162 | template<typename T> |
|
164 |
std:: |
|
|
165 | _merge(std::vector<TimeSeries::ITimeSerie*> source) | |
|
163 | std::shared_ptr<TimeSeries::ITimeSerie> | |
|
164 | _merge(std::vector<TimeSeries::ITimeSerie*> source, const DateTimeRange& range) | |
|
166 | 165 | { |
|
167 | std::unique_ptr<AnyTimeSerie> dest = std::make_unique<AnyTimeSerie>(); | |
|
168 | 166 | std::sort(std::begin(source), std::end(source), |
|
169 | 167 | [](TimeSeries::ITimeSerie* a, TimeSeries::ITimeSerie* b) { |
|
170 | 168 | if(a->size() && b->size()) return a->t(0) < b->t(0); |
|
171 | 169 | return false; |
|
172 | 170 | }); |
|
173 | *dest = std::move(*static_cast<T*>(source.front())); | |
|
174 | std::for_each(std::begin(source) + 1, std::end(source), | |
|
175 | [&dest](TimeSeries::ITimeSerie* serie) { | |
|
176 | // TODO -> remove overlap ! | |
|
177 |
|
|
|
178 | std::end(*static_cast<T*>(serie)), | |
|
179 | std::back_inserter(dest->get<T>())); | |
|
180 | }); | |
|
171 | std::shared_ptr<TimeSeries::ITimeSerie> dest = std::make_shared<T>(); | |
|
172 | std::for_each( | |
|
173 | std::begin(source), std::end(source), | |
|
174 | [&dest, &range](TimeSeries::ITimeSerie* serie) { | |
|
175 | auto& ts = *static_cast<T*>(serie); | |
|
176 | auto last_t = range.m_TStart; | |
|
177 | if(dest->size()) last_t = dest->axis(0).back(); | |
|
178 | ||
|
179 | std::copy(std::upper_bound( | |
|
180 | std::begin(ts), std::end(ts), last_t, | |
|
181 | [](const auto& a, const auto& b) { return a < b.t(); }), | |
|
182 | std::lower_bound( | |
|
183 | std::begin(ts), std::end(ts), range.m_TEnd, | |
|
184 | [](const auto& a, const auto& b) { return a.t() < b; }), | |
|
185 | std::back_inserter(*std::dynamic_pointer_cast<T>(dest))); | |
|
186 | }); | |
|
181 | 187 | return dest; |
|
182 | 188 | } |
|
183 | 189 | |
|
184 | // std::unique_ptr<AnyTimeSerie> | |
|
185 |
|
|
|
186 | //{ | |
|
187 | // switch(DataSeriesType(dataSeries.front()->index())) | |
|
188 | // { | |
|
189 | // case DataSeriesType::NONE: break; | |
|
190 | // case DataSeriesType::SCALAR: return _merge<ScalarTimeSerie>(dataSeries); | |
|
191 | // case DataSeriesType::VECTOR: return _merge<VectorTimeSerie>(dataSeries); | |
|
192 | // case DataSeriesType::SPECTROGRAM: | |
|
193 | // return _merge<SpectrogramTimeSerie>(dataSeries); | |
|
194 | // } | |
|
195 | // return std::unique_ptr<AnyTimeSerie>{}; | |
|
196 | //} | |
|
197 | ||
|
198 | std::unique_ptr<AnyTimeSerie> | |
|
199 | merge(const std::vector<TimeSeries::ITimeSerie*>& dataSeries) | |
|
190 | std::shared_ptr<TimeSeries::ITimeSerie> | |
|
191 | merge(const std::vector<TimeSeries::ITimeSerie*>& dataSeries, | |
|
192 | const DateTimeRange& range) | |
|
200 | 193 | { |
|
201 | 194 | if(dynamic_cast<ScalarTimeSerie*>(dataSeries.front())) |
|
202 | return _merge<ScalarTimeSerie>(dataSeries); | |
|
195 | return _merge<ScalarTimeSerie>(dataSeries, range); | |
|
203 | 196 | if(dynamic_cast<VectorTimeSerie*>(dataSeries.front())) |
|
204 | return _merge<VectorTimeSerie>(dataSeries); | |
|
197 | return _merge<VectorTimeSerie>(dataSeries, range); | |
|
205 | 198 | if(dynamic_cast<SpectrogramTimeSerie*>(dataSeries.front())) |
|
206 | return _merge<SpectrogramTimeSerie>(dataSeries); | |
|
207 |
return std:: |
|
|
199 | return _merge<SpectrogramTimeSerie>(dataSeries, range); | |
|
200 | return std::shared_ptr<TimeSeries::ITimeSerie>{}; | |
|
208 | 201 | } |
|
209 | 202 | |
|
210 | // void Variable2::setData(const std::vector<AnyTimeSerie*>& dataSeries, | |
|
211 | // const DateTimeRange& range, bool notify) | |
|
212 | //{ | |
|
213 | // if(dataSeries.size()) | |
|
214 | // { | |
|
215 | // impl->setDataSeries(merge(dataSeries)); | |
|
216 | // impl->setRange(range); | |
|
217 | // if(notify) emit this->updated(this->ID()); | |
|
218 | // } | |
|
219 | //} | |
|
220 | ||
|
221 | 203 | void Variable2::setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries, |
|
222 | 204 | const DateTimeRange& range, bool notify) |
|
223 | 205 | { |
@@ -225,7 +207,7 void Variable2::setData(const std::vector<TimeSeries::ITimeSerie*>& dataSeries, | |||
|
225 | 207 | { |
|
226 | 208 | { |
|
227 | 209 | QWriteLocker lock{&m_lock}; |
|
228 | impl->setDataSeries(merge(dataSeries)); | |
|
210 | impl->setDataSeries(merge(dataSeries, range)); | |
|
229 | 211 | impl->setRange(range); |
|
230 | 212 | } |
|
231 | 213 | if(notify) emit this->updated(this->ID()); |
@@ -264,7 +264,7 class VariableController2::VariableController2Private | |||
|
264 | 264 | data.push_back( |
|
265 | 265 | provider->getData(DataProviderParameters{{range}, var->metadata()})); |
|
266 | 266 | } |
|
267 |
data.push_back(var->data() |
|
|
267 | data.push_back(var->data().get()); // might be smarter | |
|
268 | 268 | var->setData(data, r, true); |
|
269 | 269 | } |
|
270 | 270 |
@@ -209,7 +209,8 PYBIND11_MODULE(pysciqlopcore, m) | |||
|
209 | 209 | }) |
|
210 | 210 | .def("__repr__", __repr__<Variable>); |
|
211 | 211 | |
|
212 |
py::class_<TimeSeries::ITimeSerie>( |
|
|
212 | py::class_<TimeSeries::ITimeSerie, std::shared_ptr<TimeSeries::ITimeSerie>>( | |
|
213 | m, "ITimeSerie") | |
|
213 | 214 | .def_property_readonly( |
|
214 | 215 | "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); }) |
|
215 | 216 | .def("__len__", |
@@ -309,12 +310,11 PYBIND11_MODULE(pysciqlopcore, m) | |||
|
309 | 310 | .def_property("name", &Variable2::name, &Variable2::setName) |
|
310 | 311 | .def_property_readonly("range", &Variable2::range) |
|
311 | 312 | .def_property_readonly("nbPoints", &Variable2::nbPoints) |
|
312 |
.def_property_readonly( |
|
|
313 | [](Variable2& var) -> TimeSeries::ITimeSerie* { | |
|
314 | auto data = var.data(); | |
|
315 | if(data) return data->base(); | |
|
316 | return nullptr; | |
|
317 | }) | |
|
313 | .def_property_readonly( | |
|
314 | "data", | |
|
315 | [](Variable2& var) -> std::shared_ptr<TimeSeries::ITimeSerie> { | |
|
316 | return var.data(); | |
|
317 | }) | |
|
318 | 318 | .def("set_data", |
|
319 | 319 | [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list, |
|
320 | 320 | const DateTimeRange& range) { var.setData(ts_list, range); }) |
@@ -37,8 +37,7 public: | |||
|
37 | 37 | auto serie = new ScalarTimeSerie(size); |
|
38 | 38 | std::generate(std::begin(*serie), std::end(*serie), |
|
39 | 39 | [i = ceil(parameters.m_Range.m_TStart)]() mutable { |
|
40 | return std::pair<double, double>{i, i * slope}; | |
|
41 | i++; | |
|
40 | return std::pair<double, double>{i, i++ * slope}; | |
|
42 | 41 | }); |
|
43 | 42 | return serie; |
|
44 | 43 | } |
@@ -63,8 +62,9 template<int slope = 1> struct RangeType | |||
|
63 | 62 | template<class T> |
|
64 | 63 | void check_variable_state(std::shared_ptr<Variable2> v, DateTimeRange r) |
|
65 | 64 | { |
|
66 | QVERIFY(v->data()->base()->t(0) >= r.m_TStart); | |
|
67 | QVERIFY(v->data()->base()->t(v->data()->base()->size() - 1) <= r.m_TEnd); | |
|
65 | auto range = v->data()->axis_range(0); | |
|
66 | QVERIFY(range.first >= r.m_TStart); | |
|
67 | QVERIFY(range.second <= r.m_TEnd); | |
|
68 | 68 | T::check_properties(v, r); |
|
69 | 69 | } |
|
70 | 70 |
General Comments 0
You need to be logged in to leave comments.
Login now