##// END OF EJS Templates
New TimeSeries classes mostly usable from Python...
jeandet -
r65:00b9e6e4b7f5
parent child
Show More
@@ -0,0 +1,41
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the SciQLOP Software
3 -- Copyright (C) 2019, Plasma Physics Laboratory - CNRS
4 --
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
9 --
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
14 --
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
22 #include <iostream>
23 #include <pybind11/embed.h>
24 #include <pybind11/pybind11.h>
25 #include <string>
26
27 namespace py = pybind11;
28
29 int main(int argc, char** argv)
30 {
31 py::scoped_interpreter guard{};
32 py::globals()["__file__"] = py::str(PYTEST_SCRIPT);
33 try
34 {
35 py::eval_file(PYTEST_SCRIPT);
36 } catch(py::error_already_set const& pythonErr)
37 {
38 std::cout << pythonErr.what();
39 }
40 return 0;
41 }
@@ -1,1 +1,1
1 Subproject commit b8442947c778c24a35d33c5f8eed8548cbf9fead
1 Subproject commit 2146d47985f44d6914b224c3b99ebf9e16e87b3f
@@ -1,1 +1,1
1 Subproject commit f7bc18f528bb35cd06c93d0a58c17e6eea3fa68c
1 Subproject commit 25abf7efba0b2990f5a6dfb0a31bc65c0f2f4d17
@@ -1,17 +1,19
1 #ifndef SCIQLOP_SPECTROGRAMTIMESERIE_H
1 #ifndef SCIQLOP_SPECTROGRAMTIMESERIE_H
2 #define SCIQLOP_SPECTROGRAMTIMESERIE_H
2 #define SCIQLOP_SPECTROGRAMTIMESERIE_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <TimeSeries.h>
6 #include <TimeSeries.h>
7
7
8 class SCIQLOP_CORE_EXPORT SpectrogramTimeSerie
8 class SCIQLOP_CORE_EXPORT SpectrogramTimeSerie
9 : public TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>
9 : public TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>
10 {
10 {
11 public:
11 public:
12 using item_t =
13 decltype(TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>()[0]);
12 SpectrogramTimeSerie() {}
14 SpectrogramTimeSerie() {}
13 ~SpectrogramTimeSerie() = default;
15 ~SpectrogramTimeSerie() = default;
14 using TimeSerie::TimeSerie;
16 using TimeSerie::TimeSerie;
15 };
17 };
16
18
17 #endif // SCIQLOP_SPECTROGRAMTIMESERIE_H
19 #endif // SCIQLOP_SPECTROGRAMTIMESERIE_H
@@ -1,272 +1,347
1 #include "CoreWrappers.h"
1 #include "CoreWrappers.h"
2
2
3 #include "pywrappers_common.h"
3 #include "pywrappers_common.h"
4
4
5 #include <Data/DataSeriesType.h>
5 #include <Data/DataSeriesType.h>
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7 #include <Data/OptionalAxis.h>
7 #include <Data/OptionalAxis.h>
8 #include <Data/ScalarSeries.h>
8 #include <Data/ScalarSeries.h>
9 #include <Data/SpectrogramSeries.h>
9 #include <Data/SpectrogramSeries.h>
10 #include <Data/Unit.h>
10 #include <Data/Unit.h>
11 #include <Data/VectorSeries.h>
11 #include <Data/VectorSeries.h>
12 #include <Network/Downloader.h>
12 #include <Network/Downloader.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14 #include <Variable/Variable2.h>
14 #include <Variable/Variable2.h>
15 #include <Variable/VariableController2.h>
15 #include <Variable/VariableController2.h>
16 #include <pybind11/chrono.h>
16 #include <pybind11/chrono.h>
17 #include <pybind11/embed.h>
17 #include <pybind11/embed.h>
18 #include <pybind11/functional.h>
18 #include <pybind11/functional.h>
19 #include <pybind11/numpy.h>
19 #include <pybind11/numpy.h>
20 #include <pybind11/operators.h>
20 #include <pybind11/operators.h>
21 #include <pybind11/pybind11.h>
21 #include <pybind11/pybind11.h>
22 #include <pybind11/stl.h>
22 #include <pybind11/stl.h>
23 #include <pybind11/stl_bind.h>
23 #include <pybind11/stl_bind.h>
24 #include <sstream>
24 #include <sstream>
25 #include <string>
25 #include <string>
26
26
27 namespace py = pybind11;
27 namespace py = pybind11;
28 using namespace std::chrono;
28 using namespace std::chrono;
29
29
30 template<typename T, typename U, bool row_major = true>
31 void copy_vector(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
32 U& dest_values)
33 {
34 auto t_view = t.unchecked<1>();
35 auto values_view = values.unchecked<2>();
36 if constexpr(row_major)
37 {
38 for(std::size_t i = 0; i < t.size(); i++)
39 {
40 dest_t[i] = t_view[i];
41 dest_values[i] = {values_view(i, 0), values_view(i, 1),
42 values_view(i, 2)};
43 }
44 }
45 else
46 {
47 for(std::size_t i = 0; i < t.size(); i++)
48 {
49 dest_t[i] = t_view[i];
50 dest_values[i] = {values_view(0, i), values_view(1, i),
51 values_view(2, i)};
52 }
53 }
54 }
55
56 template<typename T, typename U>
57 void copy_scalar(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
58 U& dest_values)
59 {
60 auto t_view = t.unchecked<1>();
61 auto values_view = values.unchecked<1>();
62 for(std::size_t i = 0; i < t.size(); i++)
63 {
64 dest_t[i] = t_view[i];
65 dest_values[i] = values_view[i];
66 }
67 }
68
69 template<typename T, typename U>
70 void copy_spectro(py::array_t<double>& t, py::array_t<double>& values,
71 T& dest_t, U& dest_values)
72 {
73 auto t_view = t.unchecked<1>();
74 auto values_view = values.unchecked<2>();
75 const auto width = values.shape(0);
76 std::cout << "WIDTH" << width << std::endl;
77 for(std::size_t i = 0; i < t.size(); i++)
78 {
79 dest_t[i] = t_view[i];
80 for(int j = 0; j < width; j++)
81 {
82 dest_values[i * width + j] = values_view(j, i);
83 std::cout << "dest_values[" << i * width + j << "] = values_view(" << j
84 << ", " << i << ") = " << values_view(j, i) << std::endl;
85 }
86 }
87 }
88
30 PYBIND11_MODULE(pysciqlopcore, m)
89 PYBIND11_MODULE(pysciqlopcore, m)
31 {
90 {
32 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
91 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
33
92
34 py::enum_<DataSeriesType>(m, "DataSeriesType")
93 py::enum_<DataSeriesType>(m, "DataSeriesType")
35 .value("SCALAR", DataSeriesType::SCALAR)
94 .value("SCALAR", DataSeriesType::SCALAR)
36 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
95 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
37 .value("VECTOR", DataSeriesType::VECTOR)
96 .value("VECTOR", DataSeriesType::VECTOR)
38 .value("NONE", DataSeriesType::NONE)
97 .value("NONE", DataSeriesType::NONE)
39 .export_values();
98 .export_values();
40
99
41 py::class_<Unit>(m, "Unit")
100 py::class_<Unit>(m, "Unit")
42 .def_readwrite("name", &Unit::m_Name)
101 .def_readwrite("name", &Unit::m_Name)
43 .def_readwrite("time_unit", &Unit::m_TimeUnit)
102 .def_readwrite("time_unit", &Unit::m_TimeUnit)
44 .def(py::self == py::self)
103 .def(py::self == py::self)
45 .def(py::self != py::self)
104 .def(py::self != py::self)
46 .def("__repr__", __repr__<Unit>);
105 .def("__repr__", __repr__<Unit>);
47
106
48 py::class_<Response>(m, "Response")
107 py::class_<Response>(m, "Response")
49 .def("status_code", &Response::status_code);
108 .def("status_code", &Response::status_code);
50
109
51 py::class_<Downloader>(m, "Downloader")
110 py::class_<Downloader>(m, "Downloader")
52 .def_static("get", Downloader::get)
111 .def_static("get", Downloader::get)
53 .def_static("getAsync", Downloader::getAsync)
112 .def_static("getAsync", Downloader::getAsync)
54 .def_static("downloadFinished", Downloader::downloadFinished);
113 .def_static("downloadFinished", Downloader::downloadFinished);
55
114
56 py::class_<ArrayDataIteratorValue>(m, "ArrayDataIteratorValue")
115 py::class_<ArrayDataIteratorValue>(m, "ArrayDataIteratorValue")
57 .def_property_readonly("value", &ArrayDataIteratorValue::first);
116 .def_property_readonly("value", &ArrayDataIteratorValue::first);
58
117
59 py::class_<OptionalAxis>(m, "OptionalAxis")
118 py::class_<OptionalAxis>(m, "OptionalAxis")
60 .def("__len__", &OptionalAxis::size)
119 .def("__len__", &OptionalAxis::size)
61 .def_property_readonly("size", &OptionalAxis::size)
120 .def_property_readonly("size", &OptionalAxis::size)
62 .def("__getitem__",
121 .def("__getitem__",
63 [](OptionalAxis& ax, int key) {
122 [](OptionalAxis& ax, int key) {
64 return (*(ax.begin() + key)).first();
123 return (*(ax.begin() + key)).first();
65 },
124 },
66 py::is_operator())
125 py::is_operator())
67 .def("__iter__",
126 .def("__iter__",
68 [](OptionalAxis& ax) {
127 [](OptionalAxis& ax) {
69 return py::make_iterator(ax.begin(), ax.end());
128 return py::make_iterator(ax.begin(), ax.end());
70 },
129 },
71 py::keep_alive<0, 1>());
130 py::keep_alive<0, 1>());
72
131
73 py::class_<DataSeriesIteratorValue>(m, "DataSeriesIteratorValue")
132 py::class_<DataSeriesIteratorValue>(m, "DataSeriesIteratorValue")
74 .def_property_readonly("x", &DataSeriesIteratorValue::x)
133 .def_property_readonly("x", &DataSeriesIteratorValue::x)
75 .def_property_readonly("y", &DataSeriesIteratorValue::y)
134 .def_property_readonly("y", &DataSeriesIteratorValue::y)
76 .def("value",
135 .def("value",
77 py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_))
136 py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_))
78 .def("value",
137 .def("value",
79 py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_))
138 py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_))
80 .def("values", &DataSeriesIteratorValue::values);
139 .def("values", &DataSeriesIteratorValue::values);
81
140
82 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
141 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
83 .def("nbPoints", &IDataSeries::nbPoints)
142 .def("nbPoints", &IDataSeries::nbPoints)
84 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
143 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
85 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
144 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
86 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
145 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
87 .def("__getitem__",
146 .def("__getitem__",
88 [](IDataSeries& serie, int key) { return *(serie.begin() + key); },
147 [](IDataSeries& serie, int key) { return *(serie.begin() + key); },
89 py::is_operator())
148 py::is_operator())
90 .def("__len__", &IDataSeries::nbPoints)
149 .def("__len__", &IDataSeries::nbPoints)
91 .def("__iter__",
150 .def("__iter__",
92 [](IDataSeries& serie) {
151 [](IDataSeries& serie) {
93 return py::make_iterator(serie.begin(), serie.end());
152 return py::make_iterator(serie.begin(), serie.end());
94 },
153 },
95 py::keep_alive<0, 1>())
154 py::keep_alive<0, 1>())
96 .def("__repr__", __repr__<IDataSeries>);
155 .def("__repr__", __repr__<IDataSeries>);
97
156
98 py::class_<ArrayData<1>, std::shared_ptr<ArrayData<1>>>(m, "ArrayData1d")
157 py::class_<ArrayData<1>, std::shared_ptr<ArrayData<1>>>(m, "ArrayData1d")
99 .def("cdata", [](ArrayData<1>& array) { return array.cdata(); });
158 .def("cdata", [](ArrayData<1>& array) { return array.cdata(); });
100
159
101 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(
160 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(
102 m, "ScalarSeries")
161 m, "ScalarSeries")
103 .def("nbPoints", &ScalarSeries::nbPoints);
162 .def("nbPoints", &ScalarSeries::nbPoints);
104
163
105 py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>(
164 py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>(
106 m, "VectorSeries")
165 m, "VectorSeries")
107 .def("nbPoints", &VectorSeries::nbPoints);
166 .def("nbPoints", &VectorSeries::nbPoints);
108
167
109 py::class_<DataSeries<2>, std::shared_ptr<DataSeries<2>>, IDataSeries>(
168 py::class_<DataSeries<2>, std::shared_ptr<DataSeries<2>>, IDataSeries>(
110 m, "DataSeries2d")
169 m, "DataSeries2d")
111 .def_property_readonly(
170 .def_property_readonly(
112 "xAxis", py::overload_cast<>(&DataSeries<2>::xAxisData, py::const_))
171 "xAxis", py::overload_cast<>(&DataSeries<2>::xAxisData, py::const_))
113 .def_property_readonly(
172 .def_property_readonly(
114 "yAxis", py::overload_cast<>(&DataSeries<2>::yAxis, py::const_));
173 "yAxis", py::overload_cast<>(&DataSeries<2>::yAxis, py::const_));
115
174
116 py::class_<SpectrogramSeries, std::shared_ptr<SpectrogramSeries>,
175 py::class_<SpectrogramSeries, std::shared_ptr<SpectrogramSeries>,
117 DataSeries<2>>(m, "SpectrogramSeries")
176 DataSeries<2>>(m, "SpectrogramSeries")
118 .def("nbPoints", &SpectrogramSeries::nbPoints)
177 .def("nbPoints", &SpectrogramSeries::nbPoints)
119 .def("xRes", &SpectrogramSeries::xResolution);
178 .def("xRes", &SpectrogramSeries::xResolution);
120
179
121 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
180 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
122
181
123 py::class_<Variable, std::shared_ptr<Variable>>(m, "Variable")
182 py::class_<Variable, std::shared_ptr<Variable>>(m, "Variable")
124 .def(py::init<const QString&>())
183 .def(py::init<const QString&>())
125 .def_property("name", &Variable::name, &Variable::setName)
184 .def_property("name", &Variable::name, &Variable::setName)
126 .def_property("range", &Variable::range, &Variable::setRange)
185 .def_property("range", &Variable::range, &Variable::setRange)
127 .def_property("cacheRange", &Variable::cacheRange,
186 .def_property("cacheRange", &Variable::cacheRange,
128 &Variable::setCacheRange)
187 &Variable::setCacheRange)
129 .def_property_readonly("nbPoints", &Variable::nbPoints)
188 .def_property_readonly("nbPoints", &Variable::nbPoints)
130 .def_property_readonly("dataSeries", &Variable::dataSeries)
189 .def_property_readonly("dataSeries", &Variable::dataSeries)
131 .def("__len__",
190 .def("__len__",
132 [](Variable& variable) {
191 [](Variable& variable) {
133 auto rng = variable.dataSeries()->xAxisRange(
192 auto rng = variable.dataSeries()->xAxisRange(
134 variable.range().m_TStart, variable.range().m_TEnd);
193 variable.range().m_TStart, variable.range().m_TEnd);
135 return std::distance(rng.first, rng.second);
194 return std::distance(rng.first, rng.second);
136 })
195 })
137 .def("__iter__",
196 .def("__iter__",
138 [](Variable& variable) {
197 [](Variable& variable) {
139 auto rng = variable.dataSeries()->xAxisRange(
198 auto rng = variable.dataSeries()->xAxisRange(
140 variable.range().m_TStart, variable.range().m_TEnd);
199 variable.range().m_TStart, variable.range().m_TEnd);
141 return py::make_iterator(rng.first, rng.second);
200 return py::make_iterator(rng.first, rng.second);
142 },
201 },
143 py::keep_alive<0, 1>())
202 py::keep_alive<0, 1>())
144 .def("__getitem__",
203 .def("__getitem__",
145 [](Variable& variable, int key) {
204 [](Variable& variable, int key) {
146 // insane and slow!
205 // insane and slow!
147 auto rng = variable.dataSeries()->xAxisRange(
206 auto rng = variable.dataSeries()->xAxisRange(
148 variable.range().m_TStart, variable.range().m_TEnd);
207 variable.range().m_TStart, variable.range().m_TEnd);
149 if(key < 0)
208 if(key < 0)
150 return *(rng.second + key);
209 return *(rng.second + key);
151 else
210 else
152 return *(rng.first + key);
211 return *(rng.first + key);
153 })
212 })
154 .def("__repr__", __repr__<Variable>);
213 .def("__repr__", __repr__<Variable>);
155
214
156 py::class_<TimeSeries::ITimeSerie>(m, "ITimeSerie")
215 py::class_<TimeSeries::ITimeSerie>(m, "ITimeSerie")
157 .def_property_readonly(
216 .def_property_readonly(
158 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
217 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
218 .def("__len__",
219 [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
159 .def_property_readonly(
220 .def_property_readonly(
160 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
221 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
161 .def_property_readonly(
222 .def_property_readonly(
162 "t",
223 "t",
163 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
224 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
164 return ts.axis(0);
225 return ts.axis(0);
165 },
226 },
166 py::return_value_policy::reference);
227 py::return_value_policy::reference);
167
228
168 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
229 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie")
169 .def(py::init<>())
230 .def(py::init<>())
170 .def(py::init<std::size_t>())
231 .def(py::init<std::size_t>())
171 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
232 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
172 assert(t.size() == values.size());
233 assert(t.size() == values.size());
173 ScalarTimeSerie::axis_t _t(t.size());
234 ScalarTimeSerie::axis_t _t(t.size());
174 ScalarTimeSerie::axis_t _values(t.size());
235 ScalarTimeSerie::axis_t _values(t.size());
175 auto t_vew = t.unchecked<1>();
236 copy_scalar(t, values, _t, _values);
176 auto values_vew = values.unchecked<1>();
177 for(std::size_t 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);
237 return ScalarTimeSerie(_t, _values);
183 }))
238 }))
184 .def("__getitem__",
239 .def("__getitem__",
185 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
240 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
186 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
241 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
187 double value) { *(ts.begin() + key) = value; });
242 double value) { *(ts.begin() + key) = value; });
188
243
189 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
244 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
190 .def(py::init<>())
245 .def(py::init<>())
191 .def(py::init<double, double, double>())
246 .def(py::init<double, double, double>())
192 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
247 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
193 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
248 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
194 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
249 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
195 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
250 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
196
251
197 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie")
252 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie")
198 .def(py::init<>())
253 .def(py::init<>())
199 .def(py::init<std::size_t>())
254 .def(py::init<std::size_t>())
200 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
255 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
201 assert(t.size() * 3 == values.size());
256 assert(t.size() * 3 == values.size());
202 VectorTimeSerie::axis_t _t(t.size());
257 VectorTimeSerie::axis_t _t(t.size());
203 VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type>
258 VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type>
204 _values(t.size());
259 _values(t.size());
205 auto t_vew = t.unchecked<1>();
260 if(values.shape()[0] == 3 && values.shape(1) != 3)
206 auto values_vew = values.unchecked<2>();
207 for(std::size_t i = 0; i < t.size(); i++)
208 {
261 {
209 _t[i] = t_vew[i];
262 copy_vector<decltype(_t), decltype(_values), false>(t, values, _t,
210 _values[i] = VectorTimeSerie::raw_value_type{
263 _values);
211 values_vew(0, i), values_vew(1, i), values_vew(2, i)};
212 }
264 }
265 else
266 {
267 copy_vector(t, values, _t, _values);
268 }
269
213 return VectorTimeSerie(_t, _values);
270 return VectorTimeSerie(_t, _values);
214 }))
271 }))
215 .def("__getitem__",
272 .def("__getitem__",
216 [](VectorTimeSerie& ts, std::size_t key)
273 [](VectorTimeSerie& ts, std::size_t key)
217 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
274 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
218 py::return_value_policy::reference)
275 py::return_value_policy::reference)
219 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
276 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
220 VectorTimeSerie::raw_value_type value) {
277 VectorTimeSerie::raw_value_type value) {
221 *(ts.begin() + key) = value;
278 *(ts.begin() + key) = value;
222 });
279 });
223
280
281 py::class_<SpectrogramTimeSerie::item_t>(m, "SpectrogramTimeSerieItem")
282 .def("__getitem__", [](SpectrogramTimeSerie::item_t& self,
283 std::size_t key) { return self[key]; });
284
224 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>(
285 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>(
225 m, "SpectrogramTimeSerie")
286 m, "SpectrogramTimeSerie")
226 .def(py::init<>())
287 .def(py::init<>())
227 .def(py::init<const std::vector<std::size_t>>());
288 .def(py::init<const std::vector<std::size_t>>())
289 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
290 assert(t.size() < values.size()); // TODO check geometry
291 SpectrogramTimeSerie::axis_t _t(t.size());
292 SpectrogramTimeSerie::container_type<
293 SpectrogramTimeSerie::raw_value_type>
294 _values(values.size());
295 copy_spectro(t, values, _t, _values);
296 std::vector<std::size_t> shape;
297 shape.push_back(values.shape(1));
298 shape.push_back(values.shape(0));
299 return SpectrogramTimeSerie(_t, _values, shape);
300 }))
301 .def("__getitem__",
302 [](SpectrogramTimeSerie& ts, std::size_t key) { return ts[key]; });
228
303
229 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
304 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
230 .def(py::init<const QString&>())
305 .def(py::init<const QString&>())
231 .def_property("name", &Variable2::name, &Variable2::setName)
306 .def_property("name", &Variable2::name, &Variable2::setName)
232 .def_property_readonly("range", &Variable2::range)
307 .def_property_readonly("range", &Variable2::range)
233 .def_property_readonly("nbPoints", &Variable2::nbPoints)
308 .def_property_readonly("nbPoints", &Variable2::nbPoints)
234 .def_property_readonly(
309 .def_property_readonly(
235 "data",
310 "data",
236 [](const Variable2& var) -> TimeSeries::ITimeSerie* {
311 [](const Variable2& var) -> TimeSeries::ITimeSerie* {
237 auto data = var.data();
312 auto data = var.data();
238 if(data) return data->base();
313 if(data) return data->base();
239 return nullptr;
314 return nullptr;
240 })
315 })
241 .def("set_data",
316 .def("set_data",
242 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
317 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
243 const DateTimeRange& range) { var.setData(ts_list, range); })
318 const DateTimeRange& range) { var.setData(ts_list, range); })
244 .def("__len__", &Variable2::nbPoints)
319 .def("__len__", &Variable2::nbPoints)
245 .def("__repr__", __repr__<Variable2>);
320 .def("__repr__", __repr__<Variable2>);
246
321
247 py::class_<DateTimeRange>(m, "SqpRange")
322 py::class_<DateTimeRange>(m, "SqpRange")
248 //.def("fromDateTime", &DateTimeRange::fromDateTime,
323 //.def("fromDateTime", &DateTimeRange::fromDateTime,
249 // py::return_value_policy::move)
324 // py::return_value_policy::move)
250 .def(py::init([](double start, double stop) {
325 .def(py::init([](double start, double stop) {
251 return DateTimeRange{start, stop};
326 return DateTimeRange{start, stop};
252 }))
327 }))
253 .def(py::init(
328 .def(py::init(
254 [](system_clock::time_point start, system_clock::time_point stop) {
329 [](system_clock::time_point start, system_clock::time_point stop) {
255 double start_ =
330 double start_ =
256 0.001 *
331 0.001 *
257 duration_cast<milliseconds>(start.time_since_epoch()).count();
332 duration_cast<milliseconds>(start.time_since_epoch()).count();
258 double stop_ =
333 double stop_ =
259 0.001 *
334 0.001 *
260 duration_cast<milliseconds>(stop.time_since_epoch()).count();
335 duration_cast<milliseconds>(stop.time_since_epoch()).count();
261 return DateTimeRange{start_, stop_};
336 return DateTimeRange{start_, stop_};
262 }))
337 }))
263 .def_property_readonly("start",
338 .def_property_readonly("start",
264 [](const DateTimeRange& range) {
339 [](const DateTimeRange& range) {
265 return system_clock::from_time_t(range.m_TStart);
340 return system_clock::from_time_t(range.m_TStart);
266 })
341 })
267 .def_property_readonly("stop",
342 .def_property_readonly("stop",
268 [](const DateTimeRange& range) {
343 [](const DateTimeRange& range) {
269 return system_clock::from_time_t(range.m_TEnd);
344 return system_clock::from_time_t(range.m_TEnd);
270 })
345 })
271 .def("__repr__", __repr__<DateTimeRange>);
346 .def("__repr__", __repr__<DateTimeRange>);
272 }
347 }
@@ -1,60 +1,65
1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
1 add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources")
2
2
3 FILE (GLOB_RECURSE TestUtilsSources
3 FILE (GLOB_RECURSE TestUtilsSources
4 TestUtils/TestProviders.h
4 TestUtils/TestProviders.h
5 TestUtils/TestProviders.cpp
5 TestUtils/TestProviders.cpp
6 )
6 )
7
7
8 add_library(TestUtils ${TestUtilsSources})
8 add_library(TestUtils ${TestUtilsSources})
9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
9 target_link_libraries(TestUtils sciqlopcore Qt5::Test)
10 target_include_directories(TestUtils PUBLIC
10 target_include_directories(TestUtils PUBLIC
11 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/TestUtils
11 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/TestUtils
12 )
12 )
13
13
14 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
14 declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test")
15
15
16 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
16 declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test")
17 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
17 declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test")
18
18
19 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
19 declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test")
20
20
21
21
22 declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test")
22 declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test")
23 declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test")
23 declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test")
24 declare_test(TestSpectrogramSeries TestSpectrogramSeries
24 declare_test(TestSpectrogramSeries TestSpectrogramSeries
25 "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
25 "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
26 "sciqlopcore;Qt5::Test")
26 "sciqlopcore;Qt5::Test")
27 declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test")
27 declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test")
28 declare_test(TestScalarSeries TestScalarSeries
28 declare_test(TestScalarSeries TestScalarSeries
29 "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
29 "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
30 "sciqlopcore;Qt5::Test")
30 "sciqlopcore;Qt5::Test")
31 declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test")
31 declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test")
32 declare_test(TestVectorSeries TestVectorSeries
32 declare_test(TestVectorSeries TestVectorSeries
33 "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
33 "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp"
34 "sciqlopcore;Qt5::Test")
34 "sciqlopcore;Qt5::Test")
35
35
36 declare_test(TestDataSourceController TestDataSourceController
36 declare_test(TestDataSourceController TestDataSourceController
37 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
37 "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp"
38 "sciqlopcore;Qt5::Test")
38 "sciqlopcore;Qt5::Test")
39 declare_test(TestDataSourceItem TestDataSourceItem
39 declare_test(TestDataSourceItem TestDataSourceItem
40 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
40 "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp"
41 "sciqlopcore;Qt5::Test")
41 "sciqlopcore;Qt5::Test")
42
42
43 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
43 declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test")
44 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test;Qt5::Concurrent")
44 declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test;Qt5::Concurrent")
45
45
46
46
47 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
47 declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test")
48 declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test")
48 declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test")
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
52
53 add_executable(TestVariablesEmbed TestUtils/PyTestWrapperExe.cpp)
54 target_link_libraries(TestVariablesEmbed PRIVATE pybind11::embed)
55 add_test(NAME TestTestVariablesEmbed COMMAND TestVariablesEmbed)
56 target_compile_definitions(TestVariablesEmbed PRIVATE -DPYTEST_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/TestVariables.py")
57 set_tests_properties(TestTestVariablesEmbed PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
53
58
54 find_package(PythonInterp 3 REQUIRED)
59 find_package(PythonInterp 3 REQUIRED)
55
60
56 add_test(NAME TestVariables
61 add_test(NAME TestVariables
57 COMMAND ${PYTHON_EXECUTABLE}
62 COMMAND ${PYTHON_EXECUTABLE}
58 ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py
63 ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py
59 TestVariables)
64 TestVariables)
60 set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
65 set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../)
@@ -1,44 +1,89
1 import sys
1 import sys
2 import os
2 import os
3 if not hasattr(sys, 'argv') or len(sys.argv)==0:
4 sys.argv = ['']
5 current_script_path = os.path.dirname(os.path.realpath(__file__))
6 sys.path.append(current_script_path)
3
7
4 import sciqlopqt
8 import sciqlopqt
5 import pysciqlopcore
9 import pysciqlopcore
6
10
7 import numpy as np
11 import numpy as np
12 import pandas as pds
8 import datetime
13 import datetime
9 import time
14 import time
10 import unittest
15 import unittest
11 import ddt
16 import ddt
12
17
13 def listify(obj):
18 def listify(obj):
14 if hasattr(obj, "__getitem__"):
19 if hasattr(obj, "__getitem__"):
15 return obj
20 return obj
16 return [obj]
21 return [obj]
17
22
18 @ddt.ddt
23 @ddt.ddt
19 class TimeSeriesCtors(unittest.TestCase):
24 class TimeSeriesCtors(unittest.TestCase):
20 @ddt.data(
25 @ddt.data(
21 (pysciqlopcore.ScalarTimeSerie,10),
26 (pysciqlopcore.ScalarTimeSerie,10),
22 (pysciqlopcore.VectorTimeSerie,10),
27 (pysciqlopcore.VectorTimeSerie,10),
23 (pysciqlopcore.SpectrogramTimeSerie,[10,10]),
28 (pysciqlopcore.SpectrogramTimeSerie,[10,10])
24 )
29 )
25 def test_construct(self, case):
30 def test_construct(self, case):
26 ts = case[0](case[1])
31 ts = case[0](case[1])
27 self.assertEqual(ts.shape,listify(case[1]))
32 self.assertEqual(ts.shape,listify(case[1]))
28
33
29 class TimeSeriesData(unittest.TestCase):
34 class TimeSeriesData(unittest.TestCase):
30 def test_set_ScalarTimeSerie_values(self):
35 def test_set_ScalarTimeSerie_values(self):
31 ts = pysciqlopcore.ScalarTimeSerie(10)
36 ts = pysciqlopcore.ScalarTimeSerie(10)
32 ts.t[0]=111.
37 ts.t[0]=111.
33 self.assertEqual(ts.t[0],111.)
38 self.assertEqual(ts.t[0],111.)
34 ts[0]=123.
39 ts[0]=123.
35 self.assertEqual(ts[0],123.)
40 self.assertEqual(ts[0],123.)
36
41
37 def test_build_ScalarTimeSerie_from_np_arrays(self):
42 def test_build_ScalarTimeSerie_from_np_arrays(self):
38 ts = pysciqlopcore.ScalarTimeSerie(np.arange(10),np.zeros(10))
43 ts = pysciqlopcore.ScalarTimeSerie(np.arange(10), np.arange(10)*10)
44 for i in range(len(ts)):
45 self.assertEqual(ts[i],i*10.)
39
46
40 def test_build_VectorTimeSerie_from_np_arrays(self):
47 def test_build_VectorTimeSerie_from_np_arrays(self):
41 ts = pysciqlopcore.VectorTimeSerie(np.arange(10),np.zeros((3,10)))
48 v=np.ones((3,10))
49 for i in range(3):
50 v[:][i] = np.arange(10)*10**i
51 ts = pysciqlopcore.VectorTimeSerie(np.arange(10), v)
52 for i in range(len(ts)):
53 self.assertEqual(ts[i].x,i)
54 self.assertEqual(ts[i].y,i*10.)
55 self.assertEqual(ts[i].z,i*100.)
56
57 def test_build_VectorTimeSerie_from_np_arrays_row(self):
58 v=np.ones((10,3))
59 for i in range(3):
60 v.transpose()[:][i] = np.arange(10)*10**i
61 ts = pysciqlopcore.VectorTimeSerie(np.arange(10), v)
62 for i in range(len(ts)):
63 self.assertEqual(ts[i].x,i)
64 self.assertEqual(ts[i].y,i*10.)
65 self.assertEqual(ts[i].z,i*100.)
66
67 def test_build_VectorTimeSerie_from_np_dataframe(self):
68 df = pds.DataFrame(data=np.zeros((10,3)),index=np.arange(10))
69 for i in range(3):
70 df[i] = np.arange(10)*10**i
71 ts = pysciqlopcore.VectorTimeSerie(df.index.values, df.values)
72 for i in range(len(ts)):
73 self.assertEqual(ts[i].x,i)
74 self.assertEqual(ts[i].y,i*10.)
75 self.assertEqual(ts[i].z,i*100.)
76
77 def test_build_SpectrogramTimeSerie_from_np_arrays(self):
78 v=np.ones((4,10))
79 for i in range(4):
80 v[:][i] = np.arange(10)*10**i
81 ts = pysciqlopcore.SpectrogramTimeSerie(np.arange(10), v)
82 for i in range(len(ts)):
83 for j in range(4):
84 print(f"ts[{i}][{j}] = " + str(ts[i][j]))
85
42
86
43 if __name__ == '__main__':
87 if __name__ == '__main__':
44 unittest.main()
88 unittest.main(exit=False)
89
General Comments 0
You need to be logged in to leave comments. Login now