##// END OF EJS Templates
Some work on SpectrogramTS Python wrapper...
jeandet -
r83:698d7cfa01b0
parent child
Show More
@@ -1,25 +1,35
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 12 using item_t =
13 13 decltype(std::declval<
14 14 TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>>()[0]);
15 15
16 16 using iterator_t = decltype(
17 17 std::declval<TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>>()
18 18 .begin());
19 19
20 20 SpectrogramTimeSerie() {}
21 SpectrogramTimeSerie(SpectrogramTimeSerie::axis_t& t,
22 SpectrogramTimeSerie::axis_t& y,
23 SpectrogramTimeSerie::container_type<
24 SpectrogramTimeSerie::raw_value_type>& values,
25 std::vector<std::size_t>& shape)
26 : TimeSeries::TimeSerie<double, SpectrogramTimeSerie, 2>(t, values, shape)
27 {
28 _axes[1] = y;
29 }
30
21 31 ~SpectrogramTimeSerie() = default;
22 32 using TimeSerie::TimeSerie;
23 33 };
24 34
25 35 #endif // SCIQLOP_SPECTROGRAMTIMESERIE_H
@@ -1,264 +1,295
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 <Network/Downloader.h>
8 8 #include <Time/TimeController.h>
9 9 #include <Variable/Variable2.h>
10 10 #include <Variable/VariableController2.h>
11 11 #include <pybind11/chrono.h>
12 12 #include <pybind11/embed.h>
13 13 #include <pybind11/functional.h>
14 14 #include <pybind11/numpy.h>
15 15 #include <pybind11/operators.h>
16 16 #include <pybind11/pybind11.h>
17 17 #include <pybind11/stl.h>
18 18 #include <pybind11/stl_bind.h>
19 19 #include <sstream>
20 20 #include <string>
21 21
22 22 namespace py = pybind11;
23 23 using namespace std::chrono;
24 24
25 25 template<typename T, typename U, bool row_major = true>
26 26 void copy_vector(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
27 27 U& dest_values)
28 28 {
29 29 auto t_view = t.unchecked<1>();
30 30 auto values_view = values.unchecked<2>();
31 31 for(std::size_t i = 0; i < t.size(); i++)
32 32 {
33 33 dest_t[i] = t_view[i];
34 34 dest_values[i] = {values_view(i, 0), values_view(i, 1), values_view(i, 2)};
35 35 }
36 36 }
37 37
38 38 template<typename T, typename U>
39 39 void copy_scalar(py::array_t<double>& t, py::array_t<double>& values, T& dest_t,
40 40 U& dest_values)
41 41 {
42 42 auto t_view = t.unchecked<1>();
43 43 if(values.ndim() == 1)
44 44 {
45 45 auto values_view = values.unchecked<1>();
46 46 for(std::size_t i = 0; i < t.size(); i++)
47 47 {
48 48 dest_t[i] = t_view[i];
49 49 dest_values[i] = values_view[i];
50 50 }
51 51 }
52 52 else if(values.ndim() == 2 && values.shape(1) == 1)
53 53 {
54 54 auto values_view = values.unchecked<2>();
55 55 for(std::size_t i = 0; i < t.size(); i++)
56 56 {
57 57 dest_t[i] = t_view[i];
58 58 dest_values[i] = values_view(i, 0);
59 59 }
60 60 }
61 61 }
62 template<typename T, typename U>
63 void copy_multicomp(py::array_t<double>& t, py::array_t<double>& values,
64 T& dest_t, U& dest_values)
65 {
66 auto t_view = t.unchecked<1>();
67 auto values_view = values.unchecked<2>();
68 const auto width = values.shape(1);
69 for(std::size_t i = 0; i < t.size(); i++)
70 {
71 dest_t[i] = t_view[i];
72 for(int j = 0; j < width; j++)
73 {
74 dest_values[i * width + j] = values_view(i, j);
75 }
76 }
77 }
62 78
63 79 template<typename T, typename U>
64 void copy_spectro(py::array_t<double>& t, py::array_t<double>& values,
65 T& dest_t, U& dest_values)
80 void copy_spectro(py::array_t<double>& t, py::array_t<double>& y,
81 py::array_t<double>& values, T& dest_t, T& dest_y,
82 U& dest_values)
66 83 {
67 84 auto t_view = t.unchecked<1>();
85 auto y_view = y.unchecked<1>();
68 86 auto values_view = values.unchecked<2>();
69 87 const auto width = values.shape(1);
88 for(std::size_t i = 0; i < y.size(); i++)
89 {
90 dest_y[i] = y_view[i];
91 }
70 92 for(std::size_t i = 0; i < t.size(); i++)
71 93 {
72 94 dest_t[i] = t_view[i];
73 95 for(int j = 0; j < width; j++)
74 96 {
75 97 dest_values[i * width + j] = values_view(i, j);
76 98 }
77 99 }
78 100 }
79 101
80 102 PYBIND11_MODULE(pysciqlopcore, m)
81 103 {
82 104 pybind11::bind_vector<std::vector<double>>(m, "VectorDouble");
83 105
84 106 py::enum_<DataSeriesType>(m, "DataSeriesType")
85 107 .value("SCALAR", DataSeriesType::SCALAR)
86 108 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
87 109 .value("VECTOR", DataSeriesType::VECTOR)
88 110 .value("MULTICOMPONENT", DataSeriesType::MULTICOMPONENT)
89 111 .value("NONE", DataSeriesType::NONE)
90 112 .export_values();
91 113
92 114 py::class_<Response>(m, "Response")
93 115 .def("status_code", &Response::status_code);
94 116
95 117 py::class_<Downloader>(m, "Downloader")
96 118 .def_static("get", Downloader::get)
97 119 .def_static("getAsync", Downloader::getAsync)
98 120 .def_static("downloadFinished", Downloader::downloadFinished);
99 121
100 122 py::class_<IDataProvider, std::shared_ptr<IDataProvider>>(m, "IDataProvider");
101 123
102 124 py::class_<TimeSeries::ITimeSerie, std::shared_ptr<TimeSeries::ITimeSerie>>(
103 125 m, "ITimeSerie")
104 126 .def_property_readonly(
105 127 "size", [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
106 128 .def("__len__",
107 129 [](const TimeSeries::ITimeSerie& ts) { return ts.size(); })
108 130 .def_property_readonly(
109 131 "shape", [](const TimeSeries::ITimeSerie& ts) { return ts.shape(); })
110 132 .def_property_readonly(
111 133 "t",
112 134 [](TimeSeries::ITimeSerie& ts) -> decltype(ts.axis(0))& {
113 135 return ts.axis(0);
114 136 },
137 py::return_value_policy::reference)
138 .def(
139 "axis",
140 [](TimeSeries::ITimeSerie& ts, unsigned int index)
141 -> decltype(ts.axis(0))& { return ts.axis(index); },
115 142 py::return_value_policy::reference);
116 143
117 144 py::class_<ScalarTimeSerie, TimeSeries::ITimeSerie,
118 145 std::shared_ptr<ScalarTimeSerie>>(m, "ScalarTimeSerie")
119 146 .def(py::init<>())
120 147 .def(py::init<std::size_t>())
121 148 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
122 149 assert(t.size() == values.size());
123 150 ScalarTimeSerie::axis_t _t(t.size());
124 151 ScalarTimeSerie::axis_t _values(t.size());
125 152 copy_scalar(t, values, _t, _values);
126 153 return ScalarTimeSerie(_t, _values);
127 154 }))
128 155 .def("__getitem__",
129 156 [](ScalarTimeSerie& ts, std::size_t key) { return ts[key]; })
130 157 .def("__setitem__", [](ScalarTimeSerie& ts, std::size_t key,
131 158 double value) { *(ts.begin() + key) = value; });
132 159
133 160 py::class_<VectorTimeSerie::raw_value_type>(m, "vector")
134 161 .def(py::init<>())
135 162 .def(py::init<double, double, double>())
136 163 .def("__repr__", __repr__<VectorTimeSerie::raw_value_type>)
137 164 .def_readwrite("x", &VectorTimeSerie::raw_value_type::x)
138 165 .def_readwrite("y", &VectorTimeSerie::raw_value_type::y)
139 166 .def_readwrite("z", &VectorTimeSerie::raw_value_type::z);
140 167
141 168 py::class_<VectorTimeSerie, TimeSeries::ITimeSerie,
142 169 std::shared_ptr<VectorTimeSerie>>(m, "VectorTimeSerie")
143 170 .def(py::init<>())
144 171 .def(py::init<std::size_t>())
145 172 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
146 173 assert(t.size() * 3 == values.size());
147 174 VectorTimeSerie::axis_t _t(t.size());
148 175 VectorTimeSerie::container_type<VectorTimeSerie::raw_value_type>
149 176 _values(t.size());
150 177 copy_vector(t, values, _t, _values);
151 178 return VectorTimeSerie(_t, _values);
152 179 }))
153 .def("__getitem__",
154 [](VectorTimeSerie& ts, std::size_t key)
155 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
156 py::return_value_policy::reference)
180 .def(
181 "__getitem__",
182 [](VectorTimeSerie& ts, std::size_t key)
183 -> VectorTimeSerie::raw_value_type& { return ts[key]; },
184 py::return_value_policy::reference)
157 185 .def("__setitem__", [](VectorTimeSerie& ts, std::size_t key,
158 186 VectorTimeSerie::raw_value_type value) {
159 187 *(ts.begin() + key) = value;
160 188 });
161 189
162 190 py::class_<MultiComponentTimeSerie::iterator_t>(m,
163 191 "MultiComponentTimeSerieItem")
164 192 .def("__getitem__", [](MultiComponentTimeSerie::iterator_t& self,
165 193 std::size_t key) { return (*self)[key]; })
166 194 .def("__setitem__",
167 195 [](MultiComponentTimeSerie::iterator_t& self, std::size_t key,
168 196 double value) { (*self)[key] = value; });
169 197
170 198 py::class_<MultiComponentTimeSerie, TimeSeries::ITimeSerie,
171 199 std::shared_ptr<MultiComponentTimeSerie>>(
172 200 m, "MultiComponentTimeSerie")
173 201 .def(py::init<>())
174 202 .def(py::init<const std::vector<std::size_t>>())
175 203 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
176 204 assert((t.size() < values.size()) |
177 205 (t.size() == 0)); // TODO check geometry
178 206 MultiComponentTimeSerie::axis_t _t(t.size());
179 207 MultiComponentTimeSerie::container_type<
180 208 MultiComponentTimeSerie::raw_value_type>
181 209 _values(values.size());
182 copy_spectro(t, values, _t, _values);
210 copy_multicomp(t, values, _t, _values);
183 211 std::vector<std::size_t> shape;
184 212 shape.push_back(values.shape(0));
185 213 shape.push_back(values.shape(1));
186 214 return MultiComponentTimeSerie(_t, _values, shape);
187 215 }))
188 216 .def("__getitem__",
189 217 [](MultiComponentTimeSerie& ts,
190 218 std::size_t key) -> MultiComponentTimeSerie::iterator_t {
191 219 return ts.begin() + key;
192 220 });
193 221
194 222 py::class_<SpectrogramTimeSerie::iterator_t>(m, "SpectrogramTimeSerieItem")
195 223 .def("__getitem__", [](SpectrogramTimeSerie::iterator_t& self,
196 224 std::size_t key) { return (*self)[key]; })
197 225 .def("__setitem__",
198 226 [](SpectrogramTimeSerie::iterator_t& self, std::size_t key,
199 227 double value) { (*self)[key] = value; });
200 228
201 229 py::class_<SpectrogramTimeSerie, TimeSeries::ITimeSerie,
202 230 std::shared_ptr<SpectrogramTimeSerie>>(m, "SpectrogramTimeSerie")
203 231 .def(py::init<>())
204 232 .def(py::init<const std::vector<std::size_t>>())
205 .def(py::init([](py::array_t<double> t, py::array_t<double> values) {
233 .def(py::init([](py::array_t<double> t, py::array_t<double> y,
234 py::array_t<double> values) {
206 235 assert(t.size() < values.size()); // TODO check geometry
236 assert(y.size() == values.shape(1));
207 237 SpectrogramTimeSerie::axis_t _t(t.size());
238 SpectrogramTimeSerie::axis_t _y(y.size());
208 239 SpectrogramTimeSerie::container_type<
209 240 SpectrogramTimeSerie::raw_value_type>
210 241 _values(values.size());
211 copy_spectro(t, values, _t, _values);
242 copy_spectro(t, y, values, _t, _y, _values);
212 243 std::vector<std::size_t> shape;
213 244 shape.push_back(values.shape(0));
214 245 shape.push_back(values.shape(1));
215 return SpectrogramTimeSerie(_t, _values, shape);
246 return SpectrogramTimeSerie(_t, _y, _values, shape);
216 247 }))
217 248 .def("__getitem__",
218 249 [](SpectrogramTimeSerie& ts,
219 250 std::size_t key) -> SpectrogramTimeSerie::iterator_t {
220 251 return ts.begin() + key;
221 252 });
222 253
223 254 py::class_<Variable2, std::shared_ptr<Variable2>>(m, "Variable2")
224 255 .def(py::init<const QString&>())
225 256 .def_property("name", &Variable2::name, &Variable2::setName)
226 257 .def_property_readonly("range", &Variable2::range)
227 258 .def_property_readonly("nbPoints", &Variable2::nbPoints)
228 259 .def_property_readonly(
229 260 "data",
230 261 [](Variable2& var) -> std::shared_ptr<TimeSeries::ITimeSerie> {
231 262 return var.data();
232 263 })
233 264 .def("set_data",
234 265 [](Variable2& var, std::vector<TimeSeries::ITimeSerie*> ts_list,
235 266 const DateTimeRange& range) { var.setData(ts_list, range); })
236 267 .def("__len__", &Variable2::nbPoints)
237 268 .def("__repr__", __repr__<Variable2>);
238 269
239 270 py::class_<DateTimeRange>(m, "SqpRange")
240 271 //.def("fromDateTime", &DateTimeRange::fromDateTime,
241 272 // py::return_value_policy::move)
242 273 .def(py::init([](double start, double stop) {
243 274 return DateTimeRange{start, stop};
244 275 }))
245 276 .def(py::init(
246 277 [](system_clock::time_point start, system_clock::time_point stop) {
247 278 double start_ =
248 279 0.001 *
249 280 duration_cast<milliseconds>(start.time_since_epoch()).count();
250 281 double stop_ =
251 282 0.001 *
252 283 duration_cast<milliseconds>(stop.time_since_epoch()).count();
253 284 return DateTimeRange{start_, stop_};
254 285 }))
255 286 .def_property_readonly("start",
256 287 [](const DateTimeRange& range) {
257 288 return system_clock::from_time_t(range.m_TStart);
258 289 })
259 290 .def_property_readonly("stop",
260 291 [](const DateTimeRange& range) {
261 292 return system_clock::from_time_t(range.m_TEnd);
262 293 })
263 294 .def("__repr__", __repr__<DateTimeRange>);
264 295 }
@@ -1,152 +1,154
1 1 import sys
2 2 import os
3 3 if not hasattr(sys, 'argv') or len(sys.argv)==0:
4 4 sys.argv = ['']
5 5 current_script_path = os.path.dirname(os.path.realpath(__file__))
6 6 sys.path.append(current_script_path)
7 7
8 8 import sciqlopqt
9 9 import pysciqlopcore
10 10
11 11 import numpy as np
12 12 import pandas as pds
13 13 import datetime
14 14 import time
15 15 import unittest
16 16 import ddt
17 17
18 18 def listify(obj):
19 19 if hasattr(obj, "__getitem__"):
20 20 return obj
21 21 return [obj]
22 22
23 23 @ddt.ddt
24 24 class TimeSeriesCtors(unittest.TestCase):
25 25 @ddt.data(
26 26 (pysciqlopcore.ScalarTimeSerie,10),
27 27 (pysciqlopcore.VectorTimeSerie,10),
28 28 (pysciqlopcore.SpectrogramTimeSerie,[10,10]),
29 29 (pysciqlopcore.MultiComponentTimeSerie,[10,10]),
30 30 (pysciqlopcore.ScalarTimeSerie,0),
31 31 (pysciqlopcore.VectorTimeSerie,0),
32 32 (pysciqlopcore.SpectrogramTimeSerie,[0,10]),
33 33 (pysciqlopcore.MultiComponentTimeSerie,[0,10])
34 34 )
35 35 def test_construct(self, case):
36 36 ts = case[0](case[1])
37 37 self.assertEqual(ts.shape,listify(case[1]))
38 38
39 39 class TimeSeriesData(unittest.TestCase):
40 40 def test_set_ScalarTimeSerie_values(self):
41 41 ts = pysciqlopcore.ScalarTimeSerie(10)
42 42 ts.t[0]=111.
43 43 self.assertEqual(ts.t[0],111.)
44 44 ts[0]=123.
45 45 self.assertEqual(ts[0],123.)
46 46
47 47 def test_set_VectorTimeSerie_values(self):
48 48 ts = pysciqlopcore.VectorTimeSerie(10)
49 49 ts.t[0]=111.
50 50 self.assertEqual(ts.t[0],111.)
51 51 ts[0].x=111.
52 52 ts[0].y=222.
53 53 ts[0].z=333.
54 54 self.assertEqual(ts[0].x,111.)
55 55 self.assertEqual(ts[0].y,222.)
56 56 self.assertEqual(ts[0].z,333.)
57 57
58 58 def test_set_SpectrogramTimeSerie_values(self):
59 59 ts = pysciqlopcore.SpectrogramTimeSerie((10,100))
60 60 ts.t[0]=111.
61 61 self.assertEqual(ts.t[0],111.)
62 62 ts[0][11]=123.
63 63 self.assertEqual(ts[0][11],123.)
64 64
65 65 def test_build_ScalarTimeSerie_from_np_arrays(self):
66 66 ts = pysciqlopcore.ScalarTimeSerie(np.arange(10), np.arange(10)*10)
67 67 for i in range(len(ts)):
68 68 self.assertEqual(ts[i],i*10.)
69 69
70 70 def test_build_VectorTimeSerie_from_np_arrays(self):
71 71 v=np.ones((10,3))
72 72 for i in range(3):
73 73 v.transpose()[:][i] = np.arange(10)*10**i
74 74 ts = pysciqlopcore.VectorTimeSerie(np.arange(10), v)
75 75 for i in range(len(ts)):
76 76 self.assertEqual(ts[i].x,i)
77 77 self.assertEqual(ts[i].y,i*10.)
78 78 self.assertEqual(ts[i].z,i*100.)
79 79
80 80
81 81 def test_build_MultiComponentTimeSerie_from_np_arrays(self):
82 82 v=np.ones((10,5))
83 83 for i in range(5):
84 84 v.transpose()[:][i] = np.arange(10)*10**i
85 85 ts = pysciqlopcore.MultiComponentTimeSerie(np.arange(10), v)
86 86 for i in range(len(ts)):
87 87 self.assertEqual(ts[i][0],i)
88 88 self.assertEqual(ts[i][1],i*10.)
89 89 self.assertEqual(ts[i][2],i*100.)
90 90
91 91 def test_build_MultiComponentTimeSerie_from_np_arrays_of_nan(self):
92 92 v=np.empty((2,5))
93 93 v.fill(np.nan)
94 94 ts = pysciqlopcore.MultiComponentTimeSerie(np.arange(2), v)
95 95 for i in range(len(ts)):
96 96 self.assertTrue(np.isnan(ts[i][0]))
97 97 self.assertTrue(np.isnan(ts[i][1]))
98 98 self.assertTrue(np.isnan(ts[i][2]))
99 99 self.assertTrue(np.isnan(ts[i][3]))
100 100
101 101 def test_build_VectorTimeSerie_from_np_arrays_row(self):
102 102 v=np.ones((10,3))
103 103 for i in range(3):
104 104 v.transpose()[:][i] = np.arange(10)*10**i
105 105 ts = pysciqlopcore.VectorTimeSerie(np.arange(10), v)
106 106 for i in range(len(ts)):
107 107 self.assertEqual(ts[i].x,i)
108 108 self.assertEqual(ts[i].y,i*10.)
109 109 self.assertEqual(ts[i].z,i*100.)
110 110
111 111 def test_build_ScalarTimeSerie_from_np_dataframe(self):
112 112 df = pds.DataFrame(data=np.zeros((10,1)),index=np.arange(10))
113 113 df[0] = np.arange(10)
114 114 ts = pysciqlopcore.ScalarTimeSerie(df.index.values, df.values)
115 115 for i in range(len(ts)):
116 116 self.assertEqual(ts[i],i)
117 117
118 118 def test_build_VectorTimeSerie_from_np_dataframe(self):
119 119 df = pds.DataFrame(data=np.zeros((10,3)),index=np.arange(10))
120 120 for i in range(3):
121 121 df[i] = np.arange(10)*10**i
122 122 ts = pysciqlopcore.VectorTimeSerie(df.index.values, df.values)
123 123 for i in range(len(ts)):
124 124 self.assertEqual(ts[i].x,i)
125 125 self.assertEqual(ts[i].y,i*10.)
126 126 self.assertEqual(ts[i].z,i*100.)
127 127
128 128 def test_build_SpectrogramTimeSerie_from_np_arrays(self):
129 v=np.ones((10,4))
130 for i in range(4):
131 v.transpose()[:][i] = np.arange(10)*10**i
132 ts = pysciqlopcore.SpectrogramTimeSerie(np.arange(10), v)
129 v=np.ones((10,30))
130 for i in range(30):
131 v.transpose()[:][i] = np.arange(10)*10**(i/10.)
132 ts = pysciqlopcore.SpectrogramTimeSerie(np.arange(10),np.arange(30), v)
133 133 for i in range(len(ts)):
134 for j in range(4):
135 self.assertEqual(ts[i][j], i*10**j)
134 for j in range(30):
135 self.assertEqual(ts[i][j], i*10**(j/10.))
136 for i in range(30):
137 self.assertEqual(ts.axis(1)[i], i)
136 138
137 139 class VariableData(unittest.TestCase):
138 140 def test_default_state(self):
139 141 v=pysciqlopcore.Variable2("hello")
140 142 self.assertEqual(str(v.name), str("hello"))
141 143 self.assertEqual(type(v.data), type(None))
142 144 self.assertEqual(len(v), 0)
143 145
144 146 def test_set_name(self):
145 147 v=pysciqlopcore.Variable2("hello")
146 148 self.assertEqual(str(v.name), str("hello"))
147 149 v.name="newName"
148 150 self.assertEqual(str(v.name), str("newName"))
149 151
150 152 if __name__ == '__main__':
151 153 unittest.main(exit=False)
152 154
General Comments 0
You need to be logged in to leave comments. Login now