##// 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
@@ -9,6 +9,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;
@@ -27,6 +27,65
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");
@@ -156,6 +215,8 PYBIND11_MODULE(pysciqlopcore, m)
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(
@@ -172,13 +233,7 PYBIND11_MODULE(pysciqlopcore, m)
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__",
@@ -202,14 +257,16 PYBIND11_MODULE(pysciqlopcore, m)
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__",
@@ -221,10 +278,28 PYBIND11_MODULE(pysciqlopcore, m)
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&>())
@@ -50,6 +50,11 declare_test(TestVariableController2WithSync TestVariableController2WithSync Var
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
@@ -1,10 +1,15
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
@@ -20,7 +25,7 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])
@@ -35,10 +40,50 class TimeSeriesData(unittest.TestCase):
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.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 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