@@ -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 | 1 | #ifndef SCIQLOP_SPECTROGRAMTIMESERIE_H |
|
2 | 2 | #define SCIQLOP_SPECTROGRAMTIMESERIE_H |
|
3 | 3 | |
|
4 | 4 | #include "CoreGlobal.h" |
|
5 | 5 | |
|
6 | 6 | #include <TimeSeries.h> |
|
7 | 7 | |
|
8 | 8 | class SCIQLOP_CORE_EXPORT SpectrogramTimeSerie |
|
9 | 9 | : public TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2> |
|
10 | 10 | { |
|
11 | 11 | public: |
|
12 | using item_t = | |
|
13 | decltype(TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>()[0]); | |
|
12 | 14 | SpectrogramTimeSerie() {} |
|
13 | 15 | ~SpectrogramTimeSerie() = default; |
|
14 | 16 | using TimeSerie::TimeSerie; |
|
15 | 17 | }; |
|
16 | 18 | |
|
17 | 19 | #endif // SCIQLOP_SPECTROGRAMTIMESERIE_H |
@@ -1,272 +1,347 | |||
|
1 | 1 | #include "CoreWrappers.h" |
|
2 | 2 | |
|
3 | 3 | #include "pywrappers_common.h" |
|
4 | 4 | |
|
5 | 5 | #include <Data/DataSeriesType.h> |
|
6 | 6 | #include <Data/IDataProvider.h> |
|
7 | 7 | #include <Data/OptionalAxis.h> |
|
8 | 8 | #include <Data/ScalarSeries.h> |
|
9 | 9 | #include <Data/SpectrogramSeries.h> |
|
10 | 10 | #include <Data/Unit.h> |
|
11 | 11 | #include <Data/VectorSeries.h> |
|
12 | 12 | #include <Network/Downloader.h> |
|
13 | 13 | #include <Time/TimeController.h> |
|
14 | 14 | #include <Variable/Variable2.h> |
|
15 | 15 | #include <Variable/VariableController2.h> |
|
16 | 16 | #include <pybind11/chrono.h> |
|
17 | 17 | #include <pybind11/embed.h> |
|
18 | 18 | #include <pybind11/functional.h> |
|
19 | 19 | #include <pybind11/numpy.h> |
|
20 | 20 | #include <pybind11/operators.h> |
|
21 | 21 | #include <pybind11/pybind11.h> |
|
22 | 22 | #include <pybind11/stl.h> |
|
23 | 23 | #include <pybind11/stl_bind.h> |
|
24 | 24 | #include <sstream> |
|
25 | 25 | #include <string> |
|
26 | 26 | |
|
27 | 27 | namespace py = pybind11; |
|
28 | 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 | 89 | PYBIND11_MODULE(pysciqlopcore, m) |
|
31 | 90 | { |
|
32 | 91 | pybind11::bind_vector<std::vector<double>>(m, "VectorDouble"); |
|
33 | 92 | |
|
34 | 93 | py::enum_<DataSeriesType>(m, "DataSeriesType") |
|
35 | 94 | .value("SCALAR", DataSeriesType::SCALAR) |
|
36 | 95 | .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM) |
|
37 | 96 | .value("VECTOR", DataSeriesType::VECTOR) |
|
38 | 97 | .value("NONE", DataSeriesType::NONE) |
|
39 | 98 | .export_values(); |
|
40 | 99 | |
|
41 | 100 | py::class_<Unit>(m, "Unit") |
|
42 | 101 | .def_readwrite("name", &Unit::m_Name) |
|
43 | 102 | .def_readwrite("time_unit", &Unit::m_TimeUnit) |
|
44 | 103 | .def(py::self == py::self) |
|
45 | 104 | .def(py::self != py::self) |
|
46 | 105 | .def("__repr__", __repr__<Unit>); |
|
47 | 106 | |
|
48 | 107 | py::class_<Response>(m, "Response") |
|
49 | 108 | .def("status_code", &Response::status_code); |
|
50 | 109 | |
|
51 | 110 | py::class_<Downloader>(m, "Downloader") |
|
52 | 111 | .def_static("get", Downloader::get) |
|
53 | 112 | .def_static("getAsync", Downloader::getAsync) |
|
54 | 113 | .def_static("downloadFinished", Downloader::downloadFinished); |
|
55 | 114 | |
|
56 | 115 | py::class_<ArrayDataIteratorValue>(m, "ArrayDataIteratorValue") |
|
57 | 116 | .def_property_readonly("value", &ArrayDataIteratorValue::first); |
|
58 | 117 | |
|
59 | 118 | py::class_<OptionalAxis>(m, "OptionalAxis") |
|
60 | 119 | .def("__len__", &OptionalAxis::size) |
|
61 | 120 | .def_property_readonly("size", &OptionalAxis::size) |
|
62 | 121 | .def("__getitem__", |
|
63 | 122 | [](OptionalAxis& ax, int key) { |
|
64 | 123 | return (*(ax.begin() + key)).first(); |
|
65 | 124 | }, |
|
66 | 125 | py::is_operator()) |
|
67 | 126 | .def("__iter__", |
|
68 | 127 | [](OptionalAxis& ax) { |
|
69 | 128 | return py::make_iterator(ax.begin(), ax.end()); |
|
70 | 129 | }, |
|
71 | 130 | py::keep_alive<0, 1>()); |
|
72 | 131 | |
|
73 | 132 | py::class_<DataSeriesIteratorValue>(m, "DataSeriesIteratorValue") |
|
74 | 133 | .def_property_readonly("x", &DataSeriesIteratorValue::x) |
|
75 | 134 | .def_property_readonly("y", &DataSeriesIteratorValue::y) |
|
76 | 135 | .def("value", |
|
77 | 136 | py::overload_cast<>(&DataSeriesIteratorValue::value, py::const_)) |
|
78 | 137 | .def("value", |
|
79 | 138 | py::overload_cast<int>(&DataSeriesIteratorValue::value, py::const_)) |
|
80 | 139 | .def("values", &DataSeriesIteratorValue::values); |
|
81 | 140 | |
|
82 | 141 | py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries") |
|
83 | 142 | .def("nbPoints", &IDataSeries::nbPoints) |
|
84 | 143 | .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit) |
|
85 | 144 | .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit) |
|
86 | 145 | .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit) |
|
87 | 146 | .def("__getitem__", |
|
88 | 147 | [](IDataSeries& serie, int key) { return *(serie.begin() + key); }, |
|
89 | 148 | py::is_operator()) |
|
90 | 149 | .def("__len__", &IDataSeries::nbPoints) |
|
91 | 150 | .def("__iter__", |
|
92 | 151 | [](IDataSeries& serie) { |
|
93 | 152 | return py::make_iterator(serie.begin(), serie.end()); |
|
94 | 153 | }, |
|
95 | 154 | py::keep_alive<0, 1>()) |
|
96 | 155 | .def("__repr__", __repr__<IDataSeries>); |
|
97 | 156 | |
|
98 | 157 | py::class_<ArrayData<1>, std::shared_ptr<ArrayData<1>>>(m, "ArrayData1d") |
|
99 | 158 | .def("cdata", [](ArrayData<1>& array) { return array.cdata(); }); |
|
100 | 159 | |
|
101 | 160 | py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>( |
|
102 | 161 | m, "ScalarSeries") |
|
103 | 162 | .def("nbPoints", &ScalarSeries::nbPoints); |
|
104 | 163 | |
|
105 | 164 | py::class_<VectorSeries, std::shared_ptr<VectorSeries>, IDataSeries>( |
|
106 | 165 | m, "VectorSeries") |
|
107 | 166 | .def("nbPoints", &VectorSeries::nbPoints); |
|
108 | 167 | |
|
109 | 168 | py::class_<DataSeries<2>, std::shared_ptr<DataSeries<2>>, IDataSeries>( |
|
110 | 169 | m, "DataSeries2d") |
|
111 | 170 | .def_property_readonly( |
|
112 | 171 | "xAxis", py::overload_cast<>(&DataSeries<2>::xAxisData, py::const_)) |
|
113 | 172 | .def_property_readonly( |
|
114 | 173 | "yAxis", py::overload_cast<>(&DataSeries<2>::yAxis, py::const_)); |
|
115 | 174 | |
|
116 | 175 | py::class_<SpectrogramSeries, std::shared_ptr<SpectrogramSeries>, |
|
117 | 176 | DataSeries<2>>(m, "SpectrogramSeries") |
|
118 | 177 | .def("nbPoints", &SpectrogramSeries::nbPoints) |
|
119 | 178 | .def("xRes", &SpectrogramSeries::xResolution); |
|
120 | 179 | |
|
121 | 180 | py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider"); |
|
122 | 181 | |
|
123 | 182 | py::class_<Variable, std::shared_ptr<Variable>>(m, "Variable") |
|
124 | 183 | .def(py::init<const QString&>()) |
|
125 | 184 | .def_property("name", &Variable::name, &Variable::setName) |
|
126 | 185 | .def_property("range", &Variable::range, &Variable::setRange) |
|
127 | 186 | .def_property("cacheRange", &Variable::cacheRange, |
|
128 | 187 | &Variable::setCacheRange) |
|
129 | 188 | .def_property_readonly("nbPoints", &Variable::nbPoints) |
|
130 | 189 | .def_property_readonly("dataSeries", &Variable::dataSeries) |
|
131 | 190 | .def("__len__", |
|
132 | 191 | [](Variable& variable) { |
|
133 | 192 | auto rng = variable.dataSeries()->xAxisRange( |
|
134 | 193 | variable.range().m_TStart, variable.range().m_TEnd); |
|
135 | 194 | return std::distance(rng.first, rng.second); |
|
136 | 195 | }) |
|
137 | 196 | .def("__iter__", |
|
138 | 197 | [](Variable& variable) { |
|
139 | 198 | auto rng = variable.dataSeries()->xAxisRange( |
|
140 | 199 | variable.range().m_TStart, variable.range().m_TEnd); |
|
141 | 200 | return py::make_iterator(rng.first, rng.second); |
|
142 | 201 | }, |
|
143 | 202 | py::keep_alive<0, 1>()) |
|
144 | 203 | .def("__getitem__", |
|
145 | 204 | [](Variable& variable, int key) { |
|
146 | 205 | // insane and slow! |
|
147 | 206 | auto rng = variable.dataSeries()->xAxisRange( |
|
148 | 207 | variable.range().m_TStart, variable.range().m_TEnd); |
|
149 | 208 | if(key < 0) |
|
150 | 209 | return *(rng.second + key); |
|
151 | 210 | else |
|
152 | 211 | return *(rng.first + key); |
|
153 | 212 | }) |
|
154 | 213 | .def("__repr__", __repr__<Variable>); |
|
155 | 214 | |
|
156 | 215 | py::class_<TimeSeries::ITimeSerie>(m, "ITimeSerie") |
|
157 | 216 | .def_property_readonly( |
|
158 | 217 | "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); }) |
|
218 | .def("__len__", | |
|
219 | [](const TimeSeries::ITimeSerie& ts) { return ts.size(); }) | |
|
159 | 220 | .def_property_readonly( |
|
160 | 221 | "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); }) |
|
161 | 222 | .def_property_readonly( |
|
162 | 223 | "t", |
|
163 | 224 | [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& { |
|
164 | 225 | return ts.axis(0); |
|
165 | 226 | }, |
|
166 | 227 | py::return_value_policy::reference); |
|
167 | 228 | |
|
168 | 229 | py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie>(m, "ScalarTimeSerie") |
|
169 | 230 | .def(py::init<>()) |
|
170 | 231 | .def(py::init<std::size_t>()) |
|
171 | 232 | .def(py::init([](py::array_t<double> t, py::array_t<double> values) { |
|
172 | 233 | assert(t.size() == values.size()); |
|
173 | 234 | ScalarTimeSerie::axis_t _t(t.size()); |
|
174 | 235 | ScalarTimeSerie::axis_t _values(t.size()); |
|
175 | auto t_vew = t.unchecked<1>(); | |
|
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 | } | |
|
236 | copy_scalar(t, values, _t, _values); | |
|
182 | 237 | return ScalarTimeSerie(_t, _values); |
|
183 | 238 | })) |
|
184 | 239 | .def("__getitem__", |
|
185 | 240 | [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; }) |
|
186 | 241 | .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key, |
|
187 | 242 | double value) { *(ts.begin() + key) = value; }); |
|
188 | 243 | |
|
189 | 244 | py::class_<VectorTimeSerie::raw_value_type>(m, "vector") |
|
190 | 245 | .def(py::init<>()) |
|
191 | 246 | .def(py::init<double, double, double>()) |
|
192 | 247 | .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>) |
|
193 | 248 | .def_readwrite("x", &VectorTimeSerie::raw_value_type::x) |
|
194 | 249 | .def_readwrite("y", &VectorTimeSerie::raw_value_type::y) |
|
195 | 250 | .def_readwrite("z", &VectorTimeSerie::raw_value_type::z); |
|
196 | 251 | |
|
197 | 252 | py::class_<VectorTimeSerie, TimeSeries::ITimeSerie>(m, "VectorTimeSerie") |
|
198 | 253 | .def(py::init<>()) |
|
199 | 254 | .def(py::init<std::size_t>()) |
|
200 | 255 | .def(py::init([](py::array_t<double> t, py::array_t<double> values) { |
|
201 | 256 | assert(t.size() * 3 == values.size()); |
|
202 | 257 | VectorTimeSerie::axis_t _t(t.size()); |
|
203 | 258 | VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type> |
|
204 | 259 | _values(t.size()); |
|
205 | auto t_vew = t.unchecked<1>(); | |
|
206 | auto values_vew = values.unchecked<2>(); | |
|
207 | for(std::size_t i = 0; i < t.size(); i++) | |
|
260 | if(values.shape()[0] == 3 && values.shape(1) != 3) | |
|
208 | 261 | { |
|
209 | _t[i] = t_vew[i]; | |
|
210 | _values[i] = VectorTimeSerie::raw_value_type{ | |
|
211 | values_vew(0, i), values_vew(1, i), values_vew(2, i)}; | |
|
262 | copy_vector<decltype(_t), decltype(_values), false>(t, values, _t, | |
|
263 | _values); | |
|
212 | 264 | } |
|
265 | else | |
|
266 | { | |
|
267 | copy_vector(t, values, _t, _values); | |
|
268 | } | |
|
269 | ||
|
213 | 270 | return VectorTimeSerie(_t, _values); |
|
214 | 271 | })) |
|
215 | 272 | .def("__getitem__", |
|
216 | 273 | [](VectorTimeSerie& ts, std::size_t key) |
|
217 | 274 | -> VectorTimeSerie::raw_value_type& { return ts[key]; }, |
|
218 | 275 | py::return_value_policy::reference) |
|
219 | 276 | .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key, |
|
220 | 277 | VectorTimeSerie::raw_value_type value) { |
|
221 | 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 | 285 | py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie>( |
|
225 | 286 | m, "SpectrogramTimeSerie") |
|
226 | 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 | 304 | py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2") |
|
230 | 305 | .def(py::init<const QString&>()) |
|
231 | 306 | .def_property("name", &Variable2::name, &Variable2::setName) |
|
232 | 307 | .def_property_readonly("range", &Variable2::range) |
|
233 | 308 | .def_property_readonly("nbPoints", &Variable2::nbPoints) |
|
234 | 309 | .def_property_readonly( |
|
235 | 310 | "data", |
|
236 | 311 | [](const Variable2& var) -> TimeSeries::ITimeSerie* { |
|
237 | 312 | auto data = var.data(); |
|
238 | 313 | if(data) return data->base(); |
|
239 | 314 | return nullptr; |
|
240 | 315 | }) |
|
241 | 316 | .def("set_data", |
|
242 | 317 | [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list, |
|
243 | 318 | const DateTimeRange& range) { var.setData(ts_list, range); }) |
|
244 | 319 | .def("__len__", &Variable2::nbPoints) |
|
245 | 320 | .def("__repr__", __repr__<Variable2>); |
|
246 | 321 | |
|
247 | 322 | py::class_<DateTimeRange>(m, "SqpRange") |
|
248 | 323 | //.def("fromDateTime", &DateTimeRange::fromDateTime, |
|
249 | 324 | // py::return_value_policy::move) |
|
250 | 325 | .def(py::init([](double start, double stop) { |
|
251 | 326 | return DateTimeRange{start, stop}; |
|
252 | 327 | })) |
|
253 | 328 | .def(py::init( |
|
254 | 329 | [](system_clock::time_point start, system_clock::time_point stop) { |
|
255 | 330 | double start_ = |
|
256 | 331 | 0.001 * |
|
257 | 332 | duration_cast<milliseconds>(start.time_since_epoch()).count(); |
|
258 | 333 | double stop_ = |
|
259 | 334 | 0.001 * |
|
260 | 335 | duration_cast<milliseconds>(stop.time_since_epoch()).count(); |
|
261 | 336 | return DateTimeRange{start_, stop_}; |
|
262 | 337 | })) |
|
263 | 338 | .def_property_readonly("start", |
|
264 | 339 | [](const DateTimeRange& range) { |
|
265 | 340 | return system_clock::from_time_t(range.m_TStart); |
|
266 | 341 | }) |
|
267 | 342 | .def_property_readonly("stop", |
|
268 | 343 | [](const DateTimeRange& range) { |
|
269 | 344 | return system_clock::from_time_t(range.m_TEnd); |
|
270 | 345 | }) |
|
271 | 346 | .def("__repr__", __repr__<DateTimeRange>); |
|
272 | 347 | } |
@@ -1,60 +1,65 | |||
|
1 | 1 | add_definitions(-DCORE_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/../tests-resources") |
|
2 | 2 | |
|
3 | 3 | FILE (GLOB_RECURSE TestUtilsSources |
|
4 | 4 | TestUtils/TestProviders.h |
|
5 | 5 | TestUtils/TestProviders.cpp |
|
6 | 6 | ) |
|
7 | 7 | |
|
8 | 8 | add_library(TestUtils ${TestUtilsSources}) |
|
9 | 9 | target_link_libraries(TestUtils sciqlopcore Qt5::Test) |
|
10 | 10 | target_include_directories(TestUtils PUBLIC |
|
11 | 11 | $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/TestUtils |
|
12 | 12 | ) |
|
13 | 13 | |
|
14 | 14 | declare_test(TestStringUtils TestStringUtils Common/TestStringUtils.cpp "sciqlopcore;Qt5::Test") |
|
15 | 15 | |
|
16 | 16 | declare_test(TestContainers TestContainers Common/TestContainers.cpp "sciqlopcore;Qt5::Test") |
|
17 | 17 | declare_test(TestSyncGroup TestSyncGroup Variable/TestSyncGroup.cpp "sciqlopcore;Qt5::Test") |
|
18 | 18 | |
|
19 | 19 | declare_test(TestDateTimeRange TestDateTimeRange Data/TestDateTimeRange.cpp "sciqlopcore;Qt5::Test") |
|
20 | 20 | |
|
21 | 21 | |
|
22 | 22 | declare_test(TestDataSeriesUtils TestDataSeriesUtils Data/TestDataSeriesUtils.cpp "sciqlopcore;Qt5::Test") |
|
23 | 23 | declare_test(TestOptionalAxis TestOptionalAxis Data/TestOptionalAxis.cpp "sciqlopcore;Qt5::Test") |
|
24 | 24 | declare_test(TestSpectrogramSeries TestSpectrogramSeries |
|
25 | 25 | "Data/TestSpectrogramSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp" |
|
26 | 26 | "sciqlopcore;Qt5::Test") |
|
27 | 27 | declare_test(TestOneDimArrayData TestOneDimArrayData Data/TestOneDimArrayData.cpp "sciqlopcore;Qt5::Test") |
|
28 | 28 | declare_test(TestScalarSeries TestScalarSeries |
|
29 | 29 | "Data/TestScalarSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp" |
|
30 | 30 | "sciqlopcore;Qt5::Test") |
|
31 | 31 | declare_test(TestTwoDimArrayData TestTwoDimArrayData Data/TestTwoDimArrayData.cpp "sciqlopcore;Qt5::Test") |
|
32 | 32 | declare_test(TestVectorSeries TestVectorSeries |
|
33 | 33 | "Data/TestVectorSeries.cpp;Data/DataSeriesBuilders.h;Data/DataSeriesBuilders.cpp;Data/DataSeriesTestsUtils.h;Data/DataSeriesTestsUtils.cpp" |
|
34 | 34 | "sciqlopcore;Qt5::Test") |
|
35 | 35 | |
|
36 | 36 | declare_test(TestDataSourceController TestDataSourceController |
|
37 | 37 | "DataSource/TestDataSourceController.cpp;DataSource/DataSourceItemBuilder.cpp" |
|
38 | 38 | "sciqlopcore;Qt5::Test") |
|
39 | 39 | declare_test(TestDataSourceItem TestDataSourceItem |
|
40 | 40 | "DataSource/TestDataSourceItem.cpp;DataSource/DataSourceItemBuilder.cpp" |
|
41 | 41 | "sciqlopcore;Qt5::Test") |
|
42 | 42 | |
|
43 | 43 | declare_test(TestVariable TestVariable Variable/TestVariable.cpp "sciqlopcore;Qt5::Test") |
|
44 | 44 | declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test;Qt5::Concurrent") |
|
45 | 45 | |
|
46 | 46 | |
|
47 | 47 | declare_test(TestVariableController2 TestVariableController2 Variable/TestVariableController2.cpp "sciqlopcore;TestUtils;Qt5::Test") |
|
48 | 48 | declare_test(TestVariableController2Async TestVariableController2Async Variable/TestVariableController2Async.cpp "sciqlopcore;TestUtils;Qt5::Test") |
|
49 | 49 | declare_test(TestVariableController2WithSync TestVariableController2WithSync Variable/TestVariableController2WithSync.cpp "sciqlopcore;TestUtils;Qt5::Test") |
|
50 | 50 | |
|
51 | 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 | 59 | find_package(PythonInterp 3 REQUIRED) |
|
55 | 60 | |
|
56 | 61 | add_test(NAME TestVariables |
|
57 | 62 | COMMAND ${PYTHON_EXECUTABLE} |
|
58 | 63 | ${CMAKE_CURRENT_LIST_DIR}/TestVariables.py |
|
59 | 64 | TestVariables) |
|
60 | 65 | set_tests_properties(TestVariables PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/../) |
@@ -1,44 +1,89 | |||
|
1 | 1 | import sys |
|
2 | 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 | 8 | import sciqlopqt |
|
5 | 9 | import pysciqlopcore |
|
6 | 10 | |
|
7 | 11 | import numpy as np |
|
12 | import pandas as pds | |
|
8 | 13 | import datetime |
|
9 | 14 | import time |
|
10 | 15 | import unittest |
|
11 | 16 | import ddt |
|
12 | 17 | |
|
13 | 18 | def listify(obj): |
|
14 | 19 | if hasattr(obj, "__getitem__"): |
|
15 | 20 | return obj |
|
16 | 21 | return [obj] |
|
17 | 22 | |
|
18 | 23 | @ddt.ddt |
|
19 | 24 | class TimeSeriesCtors(unittest.TestCase): |
|
20 | 25 | @ddt.data( |
|
21 | 26 | (pysciqlopcore.ScalarTimeSerie,10), |
|
22 | 27 | (pysciqlopcore.VectorTimeSerie,10), |
|
23 |
(pysciqlopcore.SpectrogramTimeSerie,[10,10]) |
|
|
28 | (pysciqlopcore.SpectrogramTimeSerie,[10,10]) | |
|
24 | 29 | ) |
|
25 | 30 | def test_construct(self, case): |
|
26 | 31 | ts = case[0](case[1]) |
|
27 | 32 | self.assertEqual(ts.shape,listify(case[1])) |
|
28 | 33 | |
|
29 | 34 | class TimeSeriesData(unittest.TestCase): |
|
30 | 35 | def test_set_ScalarTimeSerie_values(self): |
|
31 | 36 | ts = pysciqlopcore.ScalarTimeSerie(10) |
|
32 | 37 | ts.t[0]=111. |
|
33 | 38 | self.assertEqual(ts.t[0],111.) |
|
34 | 39 | ts[0]=123. |
|
35 | 40 | self.assertEqual(ts[0],123.) |
|
36 | 41 | |
|
37 | 42 | def test_build_ScalarTimeSerie_from_np_arrays(self): |
|
38 |
ts = pysciqlopcore.ScalarTimeSerie(np.arange(10),np. |
|
|
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 | 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 | 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