##// END OF EJS Templates
Wrapper prototype working, with all kind of Serie...
jeandet -
r1479:704e0f1deb02
parent child
Show More
@@ -0,0 +1,94
1 import traceback
2 from SciQLopBindings import PyDataProvider, Product, VectorTimeSerie, ScalarTimeSerie, DataSeriesType
3 import numpy as np
4 import math
5 from spwc.cache import _cache
6 from spwc.common.datetime_range import DateTimeRange
7 from functools import partial
8 from datetime import datetime, timedelta, timezone
9 from spwc.common.variable import SpwcVariable
10
11
12 def make_scalar(x):
13 y = np.cos(x/10.)
14 return SpwcVariable(time=x, data=y)
15
16 def make_vector(x):
17 v=np.ones((len(x),3))
18 for i in range(3):
19 v.transpose()[:][i] = np.cos(x/10. + float(i)) + (100. * np.cos(x/10000. + float(i)))
20 return SpwcVariable(time=x, data=v)
21
22
23 def make_multicomponent(x):
24 v=np.ones((len(x),4))
25 for i in range(4):
26 v.transpose()[:][i] = float(i+1) * np.cos(x/10. + float(i))
27 return SpwcVariable(time=x, data=v)
28
29 def make_spectrogram(x):
30 v=np.ones((len(x),32))
31 for i in range(32):
32 v.transpose()[:][i] = 100.*(2.+ float(i+1) * np.cos(x/1024. + float(i)))
33 return SpwcVariable(time=x, data=v)
34
35
36 def _get_data(p_type, start, stop):
37 if type(start) is datetime:
38 start = start.timestamp()
39 stop = stop.timestamp()
40 x = np.arange(math.ceil(start), math.floor(stop))*1.
41 if p_type == 'scalar':
42 return make_scalar(x)
43 if p_type == 'vector':
44 return make_vector(x)
45 if p_type == 'multicomponent':
46 return make_multicomponent(x)
47 if p_type == 'spectrogram':
48 return make_spectrogram(np.arange(math.ceil(start), math.floor(stop),15.))
49 return None
50
51 class MyProvider(PyDataProvider):
52 def __init__(self):
53 super(MyProvider,self).__init__()
54 self.register_products([Product("/tests/without_cache/scalar",[],{"type":"scalar"}),
55 Product("/tests/without_cache/vector",[],{"type":"vector"}),
56 Product("/tests/without_cache/multicomponent",[],{"type":"multicomponent",'size':'4'}),
57 Product("/tests/without_cache/spectrogram",[],{"type":"spectrogram",'size':'32'}),
58 Product("/tests/with_cache/scalar",[],{"type":"scalar", "cache":"true"}),
59 Product("/tests/with_cache/vector",[],{"type":"vector", "cache":"true"}),
60 Product("/tests/with_cache/multicomponent",[],{"type":"multicomponent",'size':'4', "cache":"true"})
61 ])
62
63 def get_data(self,metadata,start,stop):
64 ts_type = DataSeriesType.SCALAR
65 default_ctor_args = 1
66 use_cache = False
67 p_type = 'scalar'
68 try:
69 for key,value in metadata.items():
70 if key == 'type':
71 p_type = value
72 if value == 'vector':
73 ts_type = DataSeriesType.VECTOR
74 elif value == 'multicomponent':
75 ts_type = DataSeriesType.MULTICOMPONENT
76 elif value == 'spectrogram':
77 ts_type = DataSeriesType.SPECTROGRAM
78 if key == 'cache' and value == 'true':
79 use_cache = True
80 if use_cache:
81 cache_product = f"tests/{p_type}"
82 var = _cache.get_data(cache_product, DateTimeRange(datetime.fromtimestamp(start, tz=timezone.utc), datetime.fromtimestamp(stop, tz=timezone.utc)), partial(_get_data, p_type), fragment_hours=24)
83 else:
84 print("No Cache")
85 var = _get_data(p_type, start, stop)
86 return ((var.time,var.data), ts_type)
87 except Exception as e:
88 print(traceback.format_exc())
89 print("Error in test.py ",str(e))
90 return ((np.array(), np.array()), ts_type)
91
92
93 t=MyProvider()
94
@@ -1,79 +1,80
1 find_package(PythonLibs 3 REQUIRED)
1 find_package(PythonLibs 3 REQUIRED)
2 find_package(PythonInterp 3 REQUIRED)
2 find_package(PythonInterp 3 REQUIRED)
3 find_package(PySide2 REQUIRED)
3 find_package(PySide2 REQUIRED)
4 find_package(Shiboken2 REQUIRED)
4 find_package(Shiboken2 REQUIRED)
5 include(PythonInfo)
5 include(PythonInfo)
6 find_python_site_packages(PYTHON_SITE_PACKAGES)
6 find_python_site_packages(PYTHON_SITE_PACKAGES)
7
7
8 set(BINDINGS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
8 set(BINDINGS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
9 set(BINDINGS_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
9 set(BINDINGS_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
10
10
11 configure_file("${BINDINGS_SRC_DIR}/bindings.xml" "${BINDINGS_BUILD_DIR}/bindings.xml" COPYONLY)
11 configure_file("${BINDINGS_SRC_DIR}/bindings.xml" "${BINDINGS_BUILD_DIR}/bindings.xml" COPYONLY)
12 configure_file("${BINDINGS_SRC_DIR}/main.py" "${BINDINGS_BUILD_DIR}/main.py" COPYONLY)
12 configure_file("${BINDINGS_SRC_DIR}/main.py" "${BINDINGS_BUILD_DIR}/main.py" COPYONLY)
13 configure_file("${BINDINGS_SRC_DIR}/TestPlugin.py" "${BINDINGS_BUILD_DIR}/plugins/TestPlugin.py" COPYONLY)
13
14
14 execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${BINDINGS_SRC_DIR}/src_list.py" cmake "${BINDINGS_BUILD_DIR}" OUTPUT_VARIABLE BINDINGS_SOURCE)
15 execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${BINDINGS_SRC_DIR}/src_list.py" cmake "${BINDINGS_BUILD_DIR}" OUTPUT_VARIABLE BINDINGS_SOURCE)
15
16
16 set_property(SOURCE ${BINDINGS_SOURCE} PROPERTY SKIP_AUTOGEN ON)
17 set_property(SOURCE ${BINDINGS_SOURCE} PROPERTY SKIP_AUTOGEN ON)
17
18
18 list(APPEND BINDINGS_INCLUDE_DIRS
19 list(APPEND BINDINGS_INCLUDE_DIRS
19 ${PYTHON_INCLUDE_DIRS}
20 ${PYTHON_INCLUDE_DIRS}
20 ${Qt5Core_INCLUDE_DIRS}
21 ${Qt5Core_INCLUDE_DIRS}
21 ${Qt5Widgets_INCLUDE_DIRS}
22 ${Qt5Widgets_INCLUDE_DIRS}
22 ${Qt5Gui_INCLUDE_DIRS}
23 ${Qt5Gui_INCLUDE_DIRS}
23 ${CMAKE_CURRENT_SOURCE_DIR}/../../gui/include
24 ${CMAKE_CURRENT_SOURCE_DIR}/../../gui/include
24 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/include
25 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/include
25 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/external/TimeSeries/include
26 ${CMAKE_CURRENT_SOURCE_DIR}/../../core/external/TimeSeries/include
26 )
27 )
27 list(REMOVE_DUPLICATES BINDINGS_INCLUDE_DIRS)
28 list(REMOVE_DUPLICATES BINDINGS_INCLUDE_DIRS)
28 foreach(DIR ${BINDINGS_INCLUDE_DIRS})
29 foreach(DIR ${BINDINGS_INCLUDE_DIRS})
29 list(APPEND BINDINGS_INCLUDE_DIRS_ARGS "-I${DIR}")
30 list(APPEND BINDINGS_INCLUDE_DIRS_ARGS "-I${DIR}")
30 endforeach()
31 endforeach()
31
32
32 set(SHIBOKEN_OPTIONS --generator-set=shiboken
33 set(SHIBOKEN_OPTIONS --generator-set=shiboken
33 --enable-parent-ctor-heuristic
34 --enable-parent-ctor-heuristic
34 --enable-return-value-heuristic
35 --enable-return-value-heuristic
35 --use-isnull-as-nb_nonzero
36 --use-isnull-as-nb_nonzero
36 --avoid-protected-hack
37 --avoid-protected-hack
37 --enable-pyside-extensions
38 --enable-pyside-extensions
38 -std=c++17)
39 -std=c++17)
39 add_custom_command(
40 add_custom_command(
40 OUTPUT ${BINDINGS_SOURCE}
41 OUTPUT ${BINDINGS_SOURCE}
41 COMMAND Shiboken2::shiboken2 ${SHIBOKEN_OPTIONS}
42 COMMAND Shiboken2::shiboken2 ${SHIBOKEN_OPTIONS}
42 ${BINDINGS_INCLUDE_DIRS_ARGS}
43 ${BINDINGS_INCLUDE_DIRS_ARGS}
43 --typesystem-paths=${PYSIDE_TYPESYSTEMS}
44 --typesystem-paths=${PYSIDE_TYPESYSTEMS}
44 --output-directory=${CMAKE_CURRENT_BINARY_DIR}
45 --output-directory=${CMAKE_CURRENT_BINARY_DIR}
45 ${CMAKE_CURRENT_SOURCE_DIR}/bindings.h ${CMAKE_CURRENT_SOURCE_DIR}/bindings.xml
46 ${CMAKE_CURRENT_SOURCE_DIR}/bindings.h ${CMAKE_CURRENT_SOURCE_DIR}/bindings.xml
46
47
47 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bindings.xml"
48 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bindings.xml"
48 IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/bindings.h"
49 IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/bindings.h"
49 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
50 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
50 COMMENT "Generating Python bindings with shiboken2")
51 COMMENT "Generating Python bindings with shiboken2")
51
52
52 include_directories(
53 include_directories(
53 ${PYSIDE_INCLUDE_DIR}/QtCore
54 ${PYSIDE_INCLUDE_DIR}/QtCore
54 ${PYSIDE_INCLUDE_DIR}/QtGui
55 ${PYSIDE_INCLUDE_DIR}/QtGui
55 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
56 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
56
57
57 include_directories(
58 include_directories(
58 ${PYTHON_SITE_PACKAGES}/numpy/core/include/
59 ${PYTHON_SITE_PACKAGES}/numpy/core/include/
59 ${PYTHON_INCLUDE_DIRS}
60 ${PYTHON_INCLUDE_DIRS}
60 ${SHIBOKEN_INCLUDE_DIR}
61 ${SHIBOKEN_INCLUDE_DIR}
61 ${PYSIDE_INCLUDE_DIR}
62 ${PYSIDE_INCLUDE_DIR}
62 ${PYSIDE_INCLUDE_DIR}/QtCore
63 ${PYSIDE_INCLUDE_DIR}/QtCore
63 ${PYSIDE_INCLUDE_DIR}/QtGui
64 ${PYSIDE_INCLUDE_DIR}/QtGui
64 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
65 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
65
66
66 add_library(SciQLopBindings MODULE ${BINDINGS_SOURCE} numpy_wrappers.h PyDataProvider.h)
67 add_library(SciQLopBindings MODULE ${BINDINGS_SOURCE} numpy_wrappers.h PyDataProvider.h)
67 set_target_properties(
68 set_target_properties(
68 SciQLopBindings
69 SciQLopBindings
69 PROPERTIES
70 PROPERTIES
70 PREFIX ""
71 PREFIX ""
71 OUTPUT_NAME "SciQLopBindings"
72 OUTPUT_NAME "SciQLopBindings"
72 )
73 )
73 target_link_libraries(SciQLopBindings sciqlopapp)
74 target_link_libraries(SciQLopBindings sciqlopapp)
74 target_link_libraries(SciQLopBindings Shiboken2::libshiboken)
75 target_link_libraries(SciQLopBindings Shiboken2::libshiboken)
75 target_link_libraries(SciQLopBindings PySide2::pyside2)
76 target_link_libraries(SciQLopBindings PySide2::pyside2)
76
77
77 add_executable(debug_sciqlop_app main.cpp )
78 add_executable(debug_sciqlop_app main.cpp )
78 find_package (Python3 COMPONENTS Development)
79 find_package (Python3 COMPONENTS Development)
79 target_link_libraries(debug_sciqlop_app PRIVATE Python3::Python)
80 target_link_libraries(debug_sciqlop_app PRIVATE Python3::Python)
@@ -1,89 +1,111
1 #pragma once
1 #pragma once
2 #include <Data/DataProviderParameters.h>
2 #include <Data/DataProviderParameters.h>
3 #include <Data/DataSeriesType.h>
3 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
5 #include <DataSource/DataSourceController.h>
5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceItemAction.h>
7 #include <DataSource/DataSourceItemAction.h>
7 #include <QPair>
8 #include <QPair>
8 #include <SqpApplication.h>
9 #include <SqpApplication.h>
9 // must be included last because of Python/Qt definition of slots
10 // must be included last because of Python/Qt definition of slots
10 #include "numpy_wrappers.h"
11 #include "numpy_wrappers.h"
11
12
12 struct Product
13 struct Product
13 {
14 {
14 QString path;
15 QString path;
15 std::vector<std::string> components;
16 std::vector<std::string> components;
16 QMap<QString, QString> metadata;
17 QMap<QString, QString> metadata;
17 Product() = default;
18 Product() = default;
18 explicit Product(const QString& path, const std::vector<std::string>& components,
19 explicit Product(const QString& path, const std::vector<std::string>& components,
19 const QMap<QString, QString>& metadata)
20 const QMap<QString, QString>& metadata)
20 : path { path }, components { components }, metadata { metadata }
21 : path { path }, components { components }, metadata { metadata }
21 {
22 {
22 }
23 }
23 virtual ~Product() = default;
24 ~Product() = default;
24 };
25 };
25
26
26 class PyDataProvider : public IDataProvider
27 class PyDataProvider : public IDataProvider
27 {
28 {
28 public:
29 public:
29 PyDataProvider()
30 PyDataProvider()
30 {
31 {
31 auto& dataSourceController = sqpApp->dataSourceController();
32 auto& dataSourceController = sqpApp->dataSourceController();
32 dataSourceController.registerProvider(this);
33 dataSourceController.registerProvider(this);
33 }
34 }
34
35
35 virtual ~PyDataProvider() {}
36 virtual ~PyDataProvider() {}
36
37
37 virtual QPair<NpArray, NpArray> getData(
38 virtual QPair<QPair<NpArray,NpArray>,DataSeriesType> get_data(const QMap<QString,QString>& key, double start_time, double stop_time)
38 const std::string& key, double start_time, double stop_time)
39 {
39 {
40 (void)key, (void)start_time, (void)stop_time;
40 (void)key, (void)start_time, (void)stop_time;
41 return {};
41 return {};
42 }
42 }
43
43
44 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
44 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
45 {
45 {
46 if (parameters.m_Data.contains("name"))
46 if (parameters.m_Data.contains("name"))
47 {
47 {
48 auto data = getData(parameters.m_Data["name"].toString().toStdString(),
48 QMap<QString,QString> metadata;
49 std::for_each(parameters.m_Data.constKeyValueBegin(), parameters.m_Data.constKeyValueEnd(), [&metadata](const auto& item) {
50 metadata[item.first] = item.second.toString();
51 });
52 auto [data, type] = get_data(metadata,
49 parameters.m_Range.m_TStart, parameters.m_Range.m_TEnd);
53 parameters.m_Range.m_TStart, parameters.m_Range.m_TEnd);
50 // TODO add shape/type switch
54 // TODO add shape/type switch
51 return new ScalarTimeSerie { data.first.to_std_vect(), data.second.to_std_vect() };
55 //if (builder)
56 {
57 auto& [t,y]=data;
58 switch (type)
59 {
60 case DataSeriesType::SCALAR:
61 return new ScalarTimeSerie { std::move(t.data),
62 std::move(y.data) };
63 break;
64 case DataSeriesType::VECTOR:
65 return new VectorTimeSerie { std::move(t.data),
66 y.to_std_vect_vect() };
67 break;
68 case DataSeriesType::MULTICOMPONENT:
69 {
70 auto y_size = y.flat_size();
71 auto t_size = t.flat_size();
72
73 if(t_size && (y_size%t_size)==0)
74 {
75 return new MultiComponentTimeSerie { std::move(t.data),
76 std::move(y.data),{t_size, y_size/t_size} };
77 }
78 break;
79 }
80 case DataSeriesType::SPECTROGRAM:
81 {
82 auto y_size = y.flat_size();
83 auto t_size = t.flat_size();
84
85 if(t_size && (y_size%t_size)==0)
86 {
87 return new SpectrogramTimeSerie { std::move(t.data),
88 std::move(y.data),{t_size, y_size/t_size} };
89 }
90 break;
91 }
92 default:
93 break;
94 }
95 }
52 }
96 }
53 return nullptr;
97 return nullptr;
54 }
98 }
55
99
56
100
57 inline void register_products(const QVector<Product*>& products)
101 inline void register_products(const QVector<Product*>& products)
58 {
102 {
59 auto& dataSourceController = sqpApp->dataSourceController();
103 auto& dataSourceController = sqpApp->dataSourceController();
60 auto id = this->id();
104 auto id = this->id();
61 auto data_source_name = this->name();
105 auto data_source_name = this->name();
62 std::for_each(std::cbegin(products), std::cend(products),
106 std::for_each(std::cbegin(products), std::cend(products),
63 [&id, &dataSourceController](const Product* product) {
107 [&id, &dataSourceController](const Product* product) {
64 dataSourceController.setDataSourceItem(id, product->path, product->metadata);
108 dataSourceController.setDataSourceItem(id, product->path, product->metadata);
65 });
109 });
66 }
110 }
67 };
111 };
68
69
70 struct Providers
71 {
72 Providers() = default;
73 virtual ~Providers() = default;
74 inline void register_provider(PyDataProvider* provider)
75 {
76 auto& dataSourceController = sqpApp->dataSourceController();
77 dataSourceController.setDataProvider(
78 provider->id(), std::unique_ptr<IDataProvider>(provider));
79 }
80 };
81
82
83 inline ScalarTimeSerie test_PyDataProvider(PyDataProvider& prov)
84 {
85 auto v = prov.getData("", 0., 0.);
86 ScalarTimeSerie s;
87 s.set_data(v.first.to_std_vect(), v.second.to_std_vect());
88 return s;
89 }
@@ -1,12 +1,14
1 #ifndef SCIQLOP_BINDINGS_H
1 #ifndef SCIQLOP_BINDINGS_H
2 #define SCIQLOP_BINDINGS_H
2 #define SCIQLOP_BINDINGS_H
3 #define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
3 #define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
4 #include "../include/MainWindow.h"
4 #include "../include/MainWindow.h"
5 #include "PyDataProvider.h"
5 #include "PyDataProvider.h"
6 #include "numpy_wrappers.h"
6 #include "numpy_wrappers.h"
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/ScalarTimeSerie.h>
8 #include <Data/ScalarTimeSerie.h>
9 #include <Data/VectorTimeSerie.h>
10 #include <Data/DataSeriesType.h>
9 #include <SqpApplication.h>
11 #include <SqpApplication.h>
10
12
11
13
12 #endif // SCIQLOP_BINDINGS_H
14 #endif // SCIQLOP_BINDINGS_H
@@ -1,91 +1,103
1 <?xml version="1.0"?>
1 <?xml version="1.0"?>
2 <typesystem package="SciQLopBindings">
2 <typesystem package="SciQLopBindings">
3 <load-typesystem name="typesystem_core.xml" generate="no" />
3 <load-typesystem name="typesystem_core.xml" generate="no" />
4 <load-typesystem name="typesystem_gui.xml" generate="no" />
4 <load-typesystem name="typesystem_gui.xml" generate="no" />
5 <load-typesystem name="typesystem_widgets.xml" generate="no" />
5 <load-typesystem name="typesystem_widgets.xml" generate="no" />
6 <primitive-type name="std::string"/>
6 <primitive-type name="std::string"/>
7 <primitive-type name="std::size_t"/>
7 <primitive-type name="std::size_t"/>
8 <enum-type name="DataSeriesType"/>
8 <container-type name="std::vector" type="vector">
9 <container-type name="std::vector" type="vector">
9 <include file-name="vector" location="global"/>
10 <include file-name="vector" location="global"/>
10 <conversion-rule>
11 <conversion-rule>
11 <native-to-target>
12 <native-to-target>
12 %INTYPE::size_type vectorSize = %in.size();
13 %INTYPE::size_type vectorSize = %in.size();
13 PyObject* %out = PyList_New((int) vectorSize);
14 PyObject* %out = PyList_New((int) vectorSize);
14 for (%INTYPE::size_type idx = 0; idx &lt; vectorSize; ++idx) {
15 for (%INTYPE::size_type idx = 0; idx &lt; vectorSize; ++idx) {
15 %INTYPE_0 cppItem(%in[idx]);
16 %INTYPE_0 cppItem(%in[idx]);
16 PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
17 PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
17 }
18 }
18 return %out;
19 return %out;
19 </native-to-target>
20 </native-to-target>
20 <target-to-native>
21 <target-to-native>
21 <add-conversion type="PySequence">
22 <add-conversion type="PySequence">
22 Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
23 Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
23 int vectorSize = PySequence_Fast_GET_SIZE(seq.object());
24 int vectorSize = PySequence_Fast_GET_SIZE(seq.object());
24 %out.reserve(vectorSize);
25 %out.reserve(vectorSize);
25 for (int idx = 0; idx &lt; vectorSize; ++idx ) {
26 for (int idx = 0; idx &lt; vectorSize; ++idx ) {
26 PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), idx);
27 PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), idx);
27 %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
28 %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
28 %out.push_back(cppItem);
29 %out.push_back(cppItem);
29 }
30 }
30 </add-conversion>
31 </add-conversion>
31 </target-to-native>
32 </target-to-native>
32 </conversion-rule>
33 </conversion-rule>
33 </container-type>
34 </container-type>
34 <object-type name="PyDataProvider" />
35 <primitive-type name="NpArray" target-lang-api-name="PyObject">
36 <include file-name="numpy_wrappers.h" location="local"/>
37 <conversion-rule>
38 <native-to-target>
39 auto result = %in.py_object();
40 return result;
41 </native-to-target>
42 <target-to-native>
43 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
44 %out = %OUTTYPE(%in);
45 </add-conversion>
46 </target-to-native>
47 </conversion-rule>
48 </primitive-type>
49 <object-type name="PyDataProvider"/>
35 <object-type name="Product" />
50 <object-type name="Product" />
36 <object-type name="MainWindow" />
51 <object-type name="MainWindow" />
37 <object-type name="SqpApplication">
52 <object-type name="SqpApplication">
38 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
53 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
39 </object-type>
54 </object-type>
40 <object-type name="Providers">
41 <modify-function signature="register_provider(PyDataProvider*)">
42 <modify-argument index="1">
43 <define-ownership owner="c++" />
44 </modify-argument>
45 </modify-function>
46 </object-type>
47 <function signature="SqpApplication_ctor()" return-type="SqpApplication*"/>
55 <function signature="SqpApplication_ctor()" return-type="SqpApplication*"/>
48 <add-function signature="SqpApplication_ctor(PySequence)" return-type="SqpApplication*">
56 <add-function signature="SqpApplication_ctor(PySequence)" return-type="SqpApplication*">
49 <inject-code class="target">
57 <inject-code class="target">
50 static int argc;
58 static int argc;
51 static char **argv;
59 static char **argv;
52 Shiboken::listToArgcArgv(%1, &amp;argc, &amp;argv, "PySideApp");
60 Shiboken::listToArgcArgv(%1, &amp;argc, &amp;argv, "PySideApp");
53 auto retval = new SqpApplication(argc,argv);
61 auto retval = new SqpApplication(argc,argv);
54 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
62 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
55 </inject-code>
63 </inject-code>
56 </add-function>
64 </add-function>
57 <function signature="init_resources()"/>
65 <function signature="init_resources()"/>
58 <primitive-type name="NpArray" target-lang-api-name="PyObject">
59 <include file-name="numpy_wrappers.h" location="local"/>
60 <conversion-rule>
61 <native-to-target>
62 auto result = %in.py_object();
63 return result;
64 </native-to-target>
65 <target-to-native>
66 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
67 %out = %OUTTYPE(%in);
68 </add-conversion>
69 </target-to-native>
70 </conversion-rule>
71 </primitive-type>
72 <function signature="load_plugins(const SqpApplication&amp;)"/>
66 <function signature="load_plugins(const SqpApplication&amp;)"/>
73 <object-type name="ScalarTimeSerie">
67 <object-type name="ScalarTimeSerie">
74 <add-function signature="ScalarTimeSerie(NpArray&amp;,NpArray&amp;)" return-type="ScalarTimeSerie">
68 <add-function signature="ScalarTimeSerie(NpArray&amp;,NpArray&amp;)" return-type="ScalarTimeSerie">
75 <inject-code class="target">
69 <inject-code class="target">
76 %BEGIN_ALLOW_THREADS
70 %BEGIN_ALLOW_THREADS
77 %0 = new ScalarTimeSerieWrapper();
71 %0 = new ScalarTimeSerieWrapper();
78 %0.set_data(%1.to_std_vect(),%2.to_std_vect());
72 %0.set_data(std::move(%1.data),std::move(%2.data));
73 %END_ALLOW_THREADS
74 </inject-code>
75 </add-function>
76 <add-function signature="size()" return-type="int" access="public" static="no">
77 <inject-code class="target">
78 %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
79 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
80 </inject-code>
81 </add-function>
82 </object-type>
83 <object-type name="VectorTimeSerie">
84 <add-function signature="VectorTimeSerie(NpArray&amp;,NpArray&amp;)" return-type="VectorTimeSerie">
85 <inject-code class="target">
86 %BEGIN_ALLOW_THREADS
87 %0 = new VectorTimeSerieWrapper();
88 %0.set_data(std::move(%1.data),%2.to_std_vect_vect());
79 %END_ALLOW_THREADS
89 %END_ALLOW_THREADS
80 </inject-code>
90 </inject-code>
81 </add-function>
91 </add-function>
82 <add-function signature="size()" return-type="int" access="public" static="no">
92 <add-function signature="size()" return-type="int" access="public" static="no">
83 <inject-code class="target">
93 <inject-code class="target">
84 %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
94 %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
85 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
95 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
86 </inject-code>
96 </inject-code>
87 </add-function>
97 </add-function>
88 </object-type>
98 </object-type>
89 <function signature="test_PyDataProvider(PyDataProvider&amp;)"/>
90 <function signature="test_np_array(NpArray&amp;)"/>
99 <function signature="test_np_array(NpArray&amp;)"/>
91 </typesystem>
100 </typesystem>
101
102
103
@@ -1,103 +1,106
1 # This Python file uses the following encoding: utf-8
1 # This Python file uses the following encoding: utf-8
2 import os
2 import os
3 print(os.getcwd())
3 print(os.getcwd())
4 import sys
4 import sys
5 from PySide2.QtWidgets import QApplication, QMainWindow, QDockWidget
5 from PySide2.QtWidgets import QApplication, QMainWindow, QDockWidget
6 from PySide2.QtCore import QSize, Qt
6 from PySide2.QtCore import QSize, Qt
7 from PySide2 import QtGui
7 from PySide2 import QtGui
8 import os
8 import os
9 sys.path.append(os.getcwd())
9 sys.path.append(os.getcwd())
10 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
10 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
11 from qtconsole.rich_ipython_widget import RichJupyterWidget
11 from qtconsole.rich_ipython_widget import RichJupyterWidget
12 from qtconsole.inprocess import QtInProcessKernelManager
12 from qtconsole.inprocess import QtInProcessKernelManager
13
13
14
14
15 class IPythonWidget(RichJupyterWidget):
15 class IPythonWidget(RichJupyterWidget):
16 """Live IPython console widget.
16 """Live IPython console widget.
17
17
18 .. image:: img/IPythonWidget.png
18 .. image:: img/IPythonWidget.png
19
19
20 :param custom_banner: Custom welcome message to be printed at the top of
20 :param custom_banner: Custom welcome message to be printed at the top of
21 the console.
21 the console.
22 """
22 """
23
23
24 def __init__(self, parent=None, custom_banner=None, *args, **kwargs):
24 def __init__(self, parent=None, custom_banner=None, *args, **kwargs):
25 if parent is not None:
25 if parent is not None:
26 kwargs["parent"] = parent
26 kwargs["parent"] = parent
27 super(IPythonWidget, self).__init__(*args, **kwargs)
27 super(IPythonWidget, self).__init__(*args, **kwargs)
28 if custom_banner is not None:
28 if custom_banner is not None:
29 self.banner = custom_banner
29 self.banner = custom_banner
30 self.setWindowTitle(self.banner)
30 self.setWindowTitle(self.banner)
31 self.kernel_manager = kernel_manager = QtInProcessKernelManager()
31 self.kernel_manager = kernel_manager = QtInProcessKernelManager()
32 kernel_manager.start_kernel()
32 kernel_manager.start_kernel()
33 self.kernel_client = kernel_client = self._kernel_manager.client()
33 self.kernel_client = kernel_client = self._kernel_manager.client()
34 kernel_client.start_channels()
34 kernel_client.start_channels()
35
35
36 def stop():
36 def stop():
37 kernel_client.stop_channels()
37 kernel_client.stop_channels()
38 kernel_manager.shutdown_kernel()
38 kernel_manager.shutdown_kernel()
39 self.exit_requested.connect(stop)
39 self.exit_requested.connect(stop)
40
40
41 def sizeHint(self):
41 def sizeHint(self):
42 """Return a reasonable default size for usage in :class:`PlotWindow`"""
42 """Return a reasonable default size for usage in :class:`PlotWindow`"""
43 return QSize(500, 300)
43 return QSize(500, 300)
44
44
45 def pushVariables(self, variable_dict):
45 def pushVariables(self, variable_dict):
46 """ Given a dictionary containing name / value pairs, push those
46 """ Given a dictionary containing name / value pairs, push those
47 variables to the IPython console widget.
47 variables to the IPython console widget.
48
48
49 :param variable_dict: Dictionary of variables to be pushed to the
49 :param variable_dict: Dictionary of variables to be pushed to the
50 console's interactive namespace (```{variable_name: object, …}```)
50 console's interactive namespace (```{variable_name: object, …}```)
51 """
51 """
52 self.kernel_manager.kernel.shell.push(variable_dict)
52 self.kernel_manager.kernel.shell.push(variable_dict)
53
53
54
54
55 class IPythonDockWidget(QDockWidget):
55 class IPythonDockWidget(QDockWidget):
56 """Dock Widget including a :class:`IPythonWidget` inside
56 """Dock Widget including a :class:`IPythonWidget` inside
57 a vertical layout.
57 a vertical layout.
58
58
59 .. image:: img/IPythonDockWidget.png
59 .. image:: img/IPythonDockWidget.png
60
60
61 :param available_vars: Dictionary of variables to be pushed to the
61 :param available_vars: Dictionary of variables to be pushed to the
62 console's interactive namespace: ``{"variable_name": object, …}``
62 console's interactive namespace: ``{"variable_name": object, …}``
63 :param custom_banner: Custom welcome message to be printed at the top of
63 :param custom_banner: Custom welcome message to be printed at the top of
64 the console
64 the console
65 :param title: Dock widget title
65 :param title: Dock widget title
66 :param parent: Parent :class:`qt.QMainWindow` containing this
66 :param parent: Parent :class:`qt.QMainWindow` containing this
67 :class:`qt.QDockWidget`
67 :class:`qt.QDockWidget`
68 """
68 """
69 def __init__(self, parent=None, available_vars=None, custom_banner=None,
69 def __init__(self, parent=None, available_vars=None, custom_banner=None,
70 title="Console"):
70 title="Console"):
71 super(IPythonDockWidget, self).__init__(title, parent)
71 super(IPythonDockWidget, self).__init__(title, parent)
72
72
73 self.ipyconsole = IPythonWidget(custom_banner=custom_banner)
73 self.ipyconsole = IPythonWidget(custom_banner=custom_banner)
74
74
75 self.layout().setContentsMargins(0, 0, 0, 0)
75 self.layout().setContentsMargins(0, 0, 0, 0)
76 self.setWidget(self.ipyconsole)
76 self.setWidget(self.ipyconsole)
77
77
78 if available_vars is not None:
78 if available_vars is not None:
79 self.ipyconsole.pushVariables(available_vars)
79 self.ipyconsole.pushVariables(available_vars)
80 self.ipyconsole.pushVariables({"blah":self})
80 self.ipyconsole.pushVariables({"blah":self})
81
81
82 def showEvent(self, event):
82 def showEvent(self, event):
83 """Make sure this widget is raised when it is shown
83 """Make sure this widget is raised when it is shown
84 (when it is first created as a tab in PlotWindow or when it is shown
84 (when it is first created as a tab in PlotWindow or when it is shown
85 again after hiding).
85 again after hiding).
86 """
86 """
87 self.raise_()
87 self.raise_()
88
88
89 def print_process_id():
89 def print_process_id():
90 print ('Process ID is:', os.getpid())
90 print ('Process ID is:', os.getpid())
91
91
92
92
93 if __name__ == "__main__":
93 if __name__ == "__main__":
94 init_resources()
94 init_resources()
95 app = SqpApplication_ctor(sys.argv)
95 app = SqpApplication_ctor(sys.argv)
96 QtGui.qApp = app
96 QtGui.qApp = app
97 load_plugins(app)
97 load_plugins(app)
98 main_window = MainWindow()
98 main_window = MainWindow()
99 term = IPythonDockWidget(available_vars={"app":app, "main_window":main_window}, custom_banner="SciQLop IPython Console ")
99 term = IPythonDockWidget(available_vars={"app":app, "main_window":main_window}, custom_banner="SciQLop IPython Console ")
100 main_window.addDockWidget(Qt.BottomDockWidgetArea, term)
100 main_window.addDockWidget(Qt.BottomDockWidgetArea, term)
101 main_window.show()
101 main_window.show()
102 for file in os.listdir('plugins'):
103 if os.path.isfile(f"plugins/{file}"):
104 exec(open(f"plugins/{file}").read())
102 sys.exit(app.exec_())
105 sys.exit(app.exec_())
103
106
@@ -1,179 +1,261
1 #ifndef NUMPY_WRAPPERS_H
1 #ifndef NUMPY_WRAPPERS_H
2 #define NUMPY_WRAPPERS_H
2 #define NUMPY_WRAPPERS_H
3 #include <Data/ScalarTimeSerie.h>
3 #include <Data/ScalarTimeSerie.h>
4 #include <Data/VectorTimeSerie.h>
4 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
5 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
5 #if defined(slots) && (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
6 #if defined(slots) && (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
6 #pragma push_macro("slots")
7 #pragma push_macro("slots")
7 #undef slots
8 #undef slots
8 extern "C"
9 extern "C"
9 {
10 {
10 /*
11 /*
11 * Python 2 uses the "register" keyword, which is deprecated in C++ 11
12 * Python 2 uses the "register" keyword, which is deprecated in C++ 11
12 * and forbidden in C++17.
13 * and forbidden in C++17.
13 */
14 */
14 #if defined(__clang__)
15 #if defined(__clang__)
15 #pragma clang diagnostic push
16 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wdeprecated-register"
17 #pragma clang diagnostic ignored "-Wdeprecated-register"
17 #endif
18 #endif
18
19
19 #include <Python.h>
20 #include <Python.h>
20 #include <numpy/arrayobject.h>
21 #include <numpy/arrayobject.h>
21
22
22 #if defined(__clang__)
23 #if defined(__clang__)
23 #pragma clang diagnostic pop
24 #pragma clang diagnostic pop
24 #endif
25 #endif
25 }
26 }
26 #else
27 #else
27 #include <Python.h>
28 #include <Python.h>
28 #include <numpy/arrayobject.h>
29 #include <numpy/arrayobject.h>
29 #endif
30 #endif
30 #include <assert.h>
31 #include <assert.h>
31
32
32 #include <map>
33 #include <map>
33
34
34 inline int init_numpy()
35 inline int init_numpy()
35 {
36 {
36 import_array(); // PyError if not successful
37 import_array(); // PyError if not successful
37 return 0;
38 return 0;
38 }
39 }
39 const static int numpy_initialized = init_numpy();
40 const static int numpy_initialized = init_numpy();
40 template <typename dest_type = PyObject>
41 template <typename dest_type = PyObject>
41 struct PyObjectWrapper
42 struct PyObjectWrapper
42 {
43 {
43 private:
44 private:
44 PyObject* _py_obj = nullptr;
45 PyObject* _py_obj = nullptr;
45 void inc_refcount()
46 void inc_refcount() { Py_XINCREF(_py_obj); }
46 {
47 Py_XINCREF(_py_obj);
48 }
49 void dec_refcount()
47 void dec_refcount()
50 {
48 {
51 Py_XDECREF(_py_obj);
49 Py_XDECREF(_py_obj);
52 _py_obj = nullptr;
50 _py_obj = nullptr;
53 }
51 }
54
52
55 public:
53 public:
56 PyObjectWrapper() : _py_obj { nullptr } {}
54 PyObjectWrapper() : _py_obj { nullptr } {}
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); }
55 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); }
58 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj } { inc_refcount(); }
56 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj } { inc_refcount(); }
59 explicit PyObjectWrapper(PyObject* obj) : _py_obj { obj }
57 explicit PyObjectWrapper(PyObject* obj) : _py_obj { obj } { inc_refcount(); }
60 {
61 inc_refcount();
62 }
63 ~PyObjectWrapper() { dec_refcount(); }
58 ~PyObjectWrapper() { dec_refcount(); }
64 PyObjectWrapper& operator=(PyObjectWrapper&& other)
59 PyObjectWrapper& operator=(PyObjectWrapper&& other)
65 {
60 {
66 dec_refcount();
61 dec_refcount();
67 this->_py_obj = other._py_obj;
62 this->_py_obj = other._py_obj;
68 inc_refcount();
63 inc_refcount();
69 return *this;
64 return *this;
70 }
65 }
71 PyObjectWrapper& operator=(const PyObjectWrapper& other)
66 PyObjectWrapper& operator=(const PyObjectWrapper& other)
72 {
67 {
73 dec_refcount();
68 dec_refcount();
74 this->_py_obj = other._py_obj;
69 this->_py_obj = other._py_obj;
75 inc_refcount();
70 inc_refcount();
76 return *this;
71 return *this;
77 }
72 }
78
73
79 PyObject* py_object() { return _py_obj; }
74 PyObject* py_object() { return _py_obj; }
80 inline dest_type* get() { return reinterpret_cast<dest_type*>(_py_obj); }
75 inline dest_type* get() { return reinterpret_cast<dest_type*>(_py_obj); }
81 inline bool is_null() { return _py_obj == nullptr; }
76 inline bool is_null() { return _py_obj == nullptr; }
82 };
77 };
83
78
84 struct NpArray
79 struct NpArray_view
85 {
80 {
86 private:
81 private:
87 PyObjectWrapper<PyArrayObject> _py_obj;
82 PyObjectWrapper<PyArrayObject> _py_obj;
88 NpArray(NpArray& other) = delete;
83 NpArray_view(const NpArray_view&& other) = delete;
89 NpArray(const NpArray& other) = delete;
90 NpArray(const NpArray&& other) = delete;
91
84
92 public:
85 public:
93 static bool isNpArray(PyObject* obj)
86 static bool isNpArray(PyObject* obj)
94 {
87 {
95 auto arr = reinterpret_cast<PyArrayObject*>(obj);
88 auto arr = reinterpret_cast<PyArrayObject*>(obj);
96 auto is_c_aray = obj && PyArray_Check(arr) && PyArray_ISCARRAY(arr);
89 auto is_c_aray = obj && PyArray_Check(arr) && PyArray_ISCARRAY(arr);
97 return is_c_aray;
90 return is_c_aray;
98 }
91 }
99 NpArray() : _py_obj { nullptr } {}
92 NpArray_view() : _py_obj { nullptr } {}
100 NpArray(NpArray&& other) : _py_obj { other._py_obj } {}
93 NpArray_view(const NpArray_view& other) : _py_obj { other._py_obj } {}
101 explicit NpArray(PyObject* obj) : _py_obj { obj }
94 NpArray_view(NpArray_view&& other) : _py_obj { other._py_obj } {}
95 explicit NpArray_view(PyObject* obj) : _py_obj { obj }
102 {
96 {
103 assert(isNpArray(obj));
97 assert(isNpArray(obj));
104 assert(PyArray_ISFLOAT(_py_obj.get()));
98 assert(PyArray_ISFLOAT(_py_obj.get()));
105 }
99 }
106
100
107 NpArray& operator=(const NpArray& other)
101 NpArray_view& operator=(const NpArray_view& other)
108 {
102 {
109 this->_py_obj = other._py_obj;
103 this->_py_obj = other._py_obj;
110 return *this;
104 return *this;
111 }
105 }
112
106
113 NpArray& operator=(NpArray&& other)
107 NpArray_view& operator=(NpArray_view&& other)
114 {
108 {
115 this->_py_obj = other._py_obj;
109 this->_py_obj = other._py_obj;
116 return *this;
110 return *this;
117 }
111 }
118
112
119 std::vector<std::size_t> shape()
113 std::vector<std::size_t> shape()
120 {
114 {
121 std::vector<std::size_t> shape;
115 std::vector<std::size_t> shape;
122 if (!_py_obj.is_null())
116 if (!_py_obj.is_null())
123 {
117 {
124 if (int ndim = PyArray_NDIM(_py_obj.get()); ndim > 0)
118 if (int ndim = PyArray_NDIM(_py_obj.get()); ndim > 0)
125 {
119 {
126 if (ndim < 10)
120 if (ndim < 10)
127 {
121 {
128 shape.resize(ndim);
122 shape.resize(ndim);
129 std::copy_n(PyArray_SHAPE(_py_obj.get()), ndim, std::begin(shape));
123 std::copy_n(PyArray_SHAPE(_py_obj.get()), ndim, std::begin(shape));
130 }
124 }
131 }
125 }
132 }
126 }
133 return shape;
127 return shape;
134 }
128 }
135
129
130 std::size_t ndim()
131 {
132 if (!_py_obj.is_null())
133 {
134 return static_cast<std::size_t>(PyArray_NDIM(_py_obj.get()));
135 }
136 return 0;
137 }
138
139 std::size_t size(std::size_t index = 0)
140 {
141 if (!_py_obj.is_null())
142 {
143 if (index < static_cast<std::size_t>(PyArray_NDIM(_py_obj.get())))
144 {
145 return PyArray_SHAPE(_py_obj.get())[index];
146 }
147 }
148 return 0;
149 }
150
136 std::size_t flat_size()
151 std::size_t flat_size()
137 {
152 {
138 auto s = this->shape();
153 auto s = this->shape();
139 return std::accumulate(std::cbegin(s), std::cend(s), 0);
154 return std::accumulate(
155 std::cbegin(s), std::cend(s), 1, [](const auto& a, const auto& b) { return a * b; });
140 }
156 }
141
157
142 double data(std::size_t pos)
158 double data(std::size_t pos)
143 {
159 {
144 if (!_py_obj.is_null())
160 if (!_py_obj.is_null())
145 {
161 {
146 return reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()))[pos];
162 return reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()))[pos];
147 }
163 }
148 return nan("NAN");
164 return nan("NAN");
149 }
165 }
150
166
151 std::vector<double> to_std_vect()
167 std::vector<double> to_std_vect()
152 {
168 {
169 assert(!this->_py_obj.is_null());
153 auto sz = flat_size();
170 auto sz = flat_size();
154 std::vector<double> v(sz);
171 std::vector<double> v(sz);
155 auto d_ptr = reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()));
172 auto d_ptr = reinterpret_cast<double*>(PyArray_DATA(_py_obj.get()));
156 std::copy(d_ptr, d_ptr + sz, std::begin(v));
173 std::copy(d_ptr, d_ptr + sz, std::begin(v));
157 return v;
174 return v;
158 }
175 }
159
176
177 std::vector<VectorTimeSerie::raw_value_type> to_std_vect_vect()
178 {
179 auto sz = size(0);
180 std::vector<VectorTimeSerie::raw_value_type> v(sz);
181 if (sz)
182 {
183 assert(ndim() == 2);
184 assert(size(1) == 3);
185 auto d_ptr
186 = reinterpret_cast<VectorTimeSerie::raw_value_type*>(PyArray_DATA(_py_obj.get()));
187 std::copy(d_ptr, d_ptr + sz, std::begin(v));
188 }
189 return v;
190 }
191
160 PyObject* py_object() { return _py_obj.py_object(); }
192 PyObject* py_object() { return _py_obj.py_object(); }
161 };
193 };
162
194
195 struct NpArray
196 {
197 std::vector<std::size_t> shape;
198 std::vector<double> data;
199 static bool isNpArray(PyObject* obj) { return NpArray_view::isNpArray(obj); }
200 NpArray() = default;
201 explicit NpArray(PyObject* obj)
202 {
203 if (obj)
204 {
205 NpArray_view view { obj };
206 shape = view.shape();
207 data = view.to_std_vect();
208 }
209 }
210
211 inline std::size_t ndim() { return shape.size(); }
212
213 std::size_t size(std::size_t index = 0)
214 {
215 if (index < shape.size())
216 return shape[index];
217 return 0;
218 }
219
220 std::size_t flat_size()
221 {
222 return std::accumulate(std::cbegin(shape), std::cend(shape), 1,
223 [](const auto& a, const auto& b) { return a * b; });
224 }
225
226 // TODO temporary hack should find a way to avoid this copy
227 std::vector<VectorTimeSerie::raw_value_type> to_std_vect_vect()
228 {
229 auto sz = size(0);
230 std::vector<VectorTimeSerie::raw_value_type> v(sz);
231 if (sz)
232 {
233 assert(ndim() == 2);
234 assert(size(1) == 3);
235 auto d_ptr = reinterpret_cast<VectorTimeSerie::raw_value_type*>(data.data());
236 std::copy(d_ptr, d_ptr + sz, std::begin(v));
237 }
238 return v;
239 }
240
241 // TODO maybe ;)
242 PyObject* py_object() { return nullptr; }
243 };
244
163 inline int test_np_array(NpArray& arr)
245 inline int test_np_array(NpArray& arr)
164 {
246 {
165 auto shape = arr.shape();
247 auto shape = arr.shape;
166 std::cout << "len(shape)=" << shape.size() << std::endl;
248 std::cout << "len(shape)=" << shape.size() << std::endl;
167 std::for_each(std::cbegin(shape), std::cend(shape), [](auto sz) {
249 std::for_each(std::cbegin(shape), std::cend(shape), [](auto sz) {
168 static int i = 0;
250 static int i = 0;
169 std::cout << "shape[" << i++ << "]=" << sz << std::endl;
251 std::cout << "shape[" << i++ << "]=" << sz << std::endl;
170 });
252 });
171 auto flatsize = std::accumulate(std::cbegin(shape), std::cend(shape), 0);
253 auto flatsize = std::accumulate(std::cbegin(shape), std::cend(shape), 0);
172 for (auto i = 0; i < flatsize; i++)
254 for (auto i = 0; i < flatsize; i++)
173 {
255 {
174 std::cout << "data[" << i << "]=" << arr.data(i) << std::endl;
256 std::cout << "data[" << i << "]=" << arr.data[i] << std::endl;
175 }
257 }
176 return 1;
258 return 1;
177 }
259 }
178
260
179 #endif //#ifndef NUMPY_WRAPPERS_H
261 #endif //#ifndef NUMPY_WRAPPERS_H
General Comments 0
You need to be logged in to leave comments. Login now