##// END OF EJS Templates
Initial Pybind11 binding experiment working....
jeandet -
r1339:98271eda8c6e
parent child
Show More
@@ -0,0 +1,1
1 Subproject commit 2d0507db43cd5a117f7843e053b17dffca114107
@@ -0,0 +1,164
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the SciQLOP Software
3 -- Copyright (C) 2018, 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 <string>
23 #include <sstream>
24 #include <memory>
25
26 #include <pybind11/pybind11.h>
27 #include <pybind11/operators.h>
28 #include <pybind11/embed.h>
29
30 #include <SqpApplication.h>
31 #include <Variable/VariableController.h>
32 #include <Time/TimeController.h>
33 #include <Data/SqpRange.h>
34 #include <Data/DataSeriesType.h>
35 #include <Common/DateUtils.h>
36 #include <Variable/Variable.h>
37 #include <Data/ScalarSeries.h>
38
39 #include <AmdaProvider.h>
40 #include <AmdaResultParser.h>
41
42 #include <QDate>
43 #include <QTime>
44 #include <QUuid>
45 #include <QString>
46 #include <QFile>
47
48 namespace py = pybind11;
49
50 std::ostream &operator <<(std::ostream& os, const Unit& u)
51 {
52 os << "=========================" << std::endl
53 << "Unit:" << std::endl
54 << "Name:" << std::endl << u.m_Name.toStdString() << std::endl
55 << "Is_TimeUnit: " << u.m_TimeUnit << std::endl;
56 return os;
57 }
58
59 std::ostream &operator <<(std::ostream& os, const IDataSeries& ds)
60 {
61 os << "=========================" << std::endl
62 << "DataSerie:" << std::endl
63 << "Number of points:" << ds.nbPoints() << std::endl
64 << "X Axis Unit:" << std::endl << ds.xAxisUnit() << std::endl
65 << "Y Axis Unit:" << std::endl << ds.yAxisUnit()<< std::endl
66 << "Values Axis Unit:" << std::endl << ds.valuesUnit()<< std::endl;
67 return os;
68 }
69
70 template <typename T>
71 std::string __repr__(const T& obj)
72 {
73 std::stringstream sstr;
74 sstr << obj;
75 return sstr.str();
76 }
77
78
79 PYBIND11_MODULE(pytestamda, m){
80 m.doc() = "hello";
81
82 py::enum_<DataSeriesType>(m, "DataSeriesType")
83 .value("SCALAR", DataSeriesType::SCALAR)
84 .value("SPECTROGRAM", DataSeriesType::SPECTROGRAM)
85 .value("UNKNOWN", DataSeriesType::UNKNOWN)
86 .export_values();
87
88 py::class_<Unit>(m, "Unit")
89 .def_readwrite("name", &Unit::m_Name)
90 .def_readwrite("time_unit", &Unit::m_TimeUnit)
91 .def(py::self == py::self)
92 .def(py::self != py::self)
93 .def("__repr__",__repr__<Unit>);
94
95 py::class_<IDataSeries, std::shared_ptr<IDataSeries>>(m, "IDataSeries")
96 .def("nbPoints", &IDataSeries::nbPoints)
97 .def_property_readonly("xAxisUnit", &IDataSeries::xAxisUnit)
98 .def_property_readonly("yAxisUnit", &IDataSeries::yAxisUnit)
99 .def_property_readonly("valuesUnit", &IDataSeries::valuesUnit)
100 .def("__repr__",__repr__<IDataSeries>);
101
102
103
104 py::class_<ScalarSeries, std::shared_ptr<ScalarSeries>, IDataSeries>(m, "ScalarSeries")
105 .def("nbPoints", &ScalarSeries::nbPoints);
106
107 py::class_<QString>(m, "QString")
108 .def(py::init([](const std::string& value){return QString::fromStdString(value);}))
109 .def("__repr__", &QString::toStdString);
110
111 py::class_<VariableController>(m, "VariableController");
112
113 py::class_<AmdaProvider>(m, "AmdaProvider");
114
115 py::class_<AmdaResultParser>(m, "AmdaResultParser")
116 .def_static("readTxt", AmdaResultParser::readTxt)
117 .def("readScalarTxt", [](const QString& path){
118 return std::dynamic_pointer_cast<ScalarSeries>(AmdaResultParser::readTxt(path, DataSeriesType::SCALAR));
119 }, py::return_value_policy::copy);
120
121 py::class_<Variable>(m, "Variable")
122 .def(py::init<const QString&>())
123 .def_property("name", &Variable::name, &Variable::setName)
124 .def_property("range", &Variable::range, &Variable::setRange)
125 .def_property("cacheRange", &Variable::cacheRange, &Variable::setCacheRange);
126
127 py::implicitly_convertible<std::string, QString>();
128
129 py::class_<TimeController>(m,"TimeController");
130
131 py::class_<SqpRange>(m,"SqpRange")
132 .def("fromDateTime", &SqpRange::fromDateTime, py::return_value_policy::move)
133 .def(py::init([](double start, double stop){return SqpRange{start, stop};}))
134 .def("__repr__", [](const SqpRange& range){
135 QString repr = QString("SqpRange:\n Start date: %1\n Stop date: %2")
136 .arg(DateUtils::dateTime(range.m_TStart).toString())
137 .arg(DateUtils::dateTime(range.m_TEnd).toString());
138 return repr.toStdString();
139 });
140
141 py::class_<QUuid>(m,"QUuid");
142
143 py::class_<QDate>(m,"QDate")
144 .def(py::init<int,int,int>());
145
146 py::class_<QTime>(m,"QTime")
147 .def(py::init<int,int,int>());
148
149 }
150
151
152 int pytestamda_test(int argc, char** argv, const char* testScriptPath )
153 {
154 SqpApplication::setOrganizationName("LPP");
155 SqpApplication::setOrganizationDomain("lpp.fr");
156 SqpApplication::setApplicationName("SciQLop");
157 SqpApplication app(argc, argv);
158 py::scoped_interpreter guard{};
159
160 py::globals()["__file__"] = py::str(testScriptPath);
161 py::eval_file(testScriptPath);
162 return 0;
163 }
164
@@ -0,0 +1,33
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the SciQLOP Software
3 -- Copyright (C) 2018, 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 <QString>
23 extern int pytestamda_test(int argc, char** argv, const char* testScriptPath );
24
25 int main(int argc, char** argv)
26 {
27 pytestamda_test(argc, argv, PYTESTAMDA_SCRIPT);
28 return 0;
29 }
30
31
32
33
@@ -0,0 +1,5
1 import pytestamda
2 import os
3 current_script_path = os.path.dirname(os.path.realpath(__file__))
4 path = current_script_path+'/../tests-resources/TestAmdaResultParser/ValidScalar1.txt'
5 c = pytestamda.AmdaResultParser.readScalarTxt(path)
@@ -1,6 +1,9
1 1 [submodule "external/CatalogueAPI"]
2 2 path = external/CatalogueAPI
3 3 url = https://hephaistos.lpp.polytechnique.fr/rhodecode/HG_REPOSITORIES/LPP/INSTRUMENTATION/USERS/JEANDET/CatalogueAPI
4 4 [submodule "external/libcatalogs"]
5 5 path = external/libcatalogs
6 6 url = https://hephaistos.lpp.polytechnique.fr/rhodecode/HG_REPOSITORIES/LPP/SciQLOP_Repos/libcatalogs
7 [submodule "external/pybind11"]
8 path = external/pybind11
9 url = https://github.com/pybind/pybind11
@@ -1,62 +1,69
1 1 cmake_minimum_required(VERSION 3.6)
2 2 project(SciQLOP CXX)
3 3
4 4 include(GNUInstallDirs)
5 5
6 6 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake")
7 7
8 8 OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF)
9 9 OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF)
10 10 OPTION (IWYU "Analyzes the source code with Include What You Use" OFF)
11 11
12 12 set(CMAKE_CXX_STANDARD 14)
13 13
14 14 set(CMAKE_AUTOMOC ON)
15 15 #https://gitlab.kitware.com/cmake/cmake/issues/15227
16 16 #set(CMAKE_AUTOUIC ON)
17 17 if(POLICY CMP0071)
18 18 cmake_policy(SET CMP0071 OLD)
19 19 endif()
20 20 set(CMAKE_AUTORCC ON)
21 21 set(CMAKE_INCLUDE_CURRENT_DIR ON)
22 22
23 23 if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH)
24 24 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
25 25 endif()
26 26 if(NOT DEFINED CMAKE_MACOSX_RPATH)
27 27 set(CMAKE_MACOSX_RPATH TRUE)
28 28 endif()
29 29
30 30 if(NOT CMAKE_BUILD_TYPE)
31 31 set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
32 32 endif()
33 33
34 34 find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED)
35 35
36 36 IF(CPPCHECK)
37 37 set(CMAKE_CXX_CPPCHECK "cppcheck;--enable=warning,style")
38 38 ENDIF(CPPCHECK)
39 39
40 40 IF(CLANG_TIDY)
41 41 set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-style=file;-checks=*")
42 42 ENDIF(CLANG_TIDY)
43 43
44 44 IF(IWYU)
45 45 set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "include-what-you-use")
46 46 ENDIF(IWYU)
47 47
48 48 enable_testing()
49 49
50 50
51 51 find_package(catalogs CONFIG QUIET)
52 52 if (NOT CatalogueAPI_FOUND)
53 53 execute_process(COMMAND git submodule init external/libcatalogs WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
54 54 execute_process(COMMAND git submodule update external/libcatalogs WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
55 55 add_subdirectory(external/libcatalogs)
56 56 endif()
57 57
58 find_package(pybind11 CONFIG QUIET)
59 if (NOT pybind11_FOUND)
60 execute_process(COMMAND git submodule init external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
61 execute_process(COMMAND git submodule update external/pybind11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
62 add_subdirectory(external/pybind11)
63 endif()
64
58 65 add_subdirectory(core)
59 66 add_subdirectory(gui)
60 67 add_subdirectory(app)
61 68 add_subdirectory(plugins)
62 69 add_subdirectory(docs)
@@ -1,40 +1,62
1 1 include_directories(include)
2 2 FILE (GLOB_RECURSE amdaplugin_SRCS
3 3 include/*.h
4 4 src/*.cpp
5 5 resources/*.qrc
6 6 )
7 7
8 8
9 9 set(AMDA_server_type hybrid CACHE STRING "AMDA server type selected at CMake configure time")
10 10
11 11 set(AMDA_SERVER_TYPE "hybrid;amdatest;localhost" CACHE STRING
12 12 "List of possible for AMDA server type")
13 13
14 14 set_property(CACHE AMDA_server_type PROPERTY STRINGS ${AMDA_SERVER_TYPE})
15 add_definitions(-DSCIQLOP_AMDA_SERVER="{AMDA_server_type}")
15 add_definitions(-DSCIQLOP_AMDA_SERVER="${AMDA_server_type}")
16 16
17 17 add_definitions(-DQT_PLUGIN)
18 18 add_definitions(-DSCIQLOP_PLUGIN_JSON_FILE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/amda.json")
19 19 if(NOT BUILD_SHARED_LIBS)
20 20 add_definitions(-DQT_STATICPLUGIN)
21 21 endif()
22 22
23 23 add_library(amdaplugin ${amdaplugin_SRCS})
24 24 SET_TARGET_PROPERTIES(amdaplugin PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
25 25
26 26 target_link_libraries(amdaplugin PUBLIC sciqlopgui)
27 27
28 28 install(TARGETS amdaplugin
29 29 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
30 30 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
31 31 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
32 32
33 33 include(sciqlop_tests)
34 34
35 35 add_definitions(-DAMDA_TESTS_RESOURCES_DIR="${CMAKE_CURRENT_LIST_DIR}/tests-resources")
36 36
37 37 declare_test(TestAmdaParser TestAmdaParser tests/TestAmdaParser.cpp "amdaplugin;Qt5::Test")
38 38 declare_test(TestAmdaResultParser TestAmdaResultParser tests/TestAmdaResultParser.cpp "amdaplugin;Qt5::Test")
39 39 declare_test(TestAmdaAcquisition TestAmdaAcquisition tests/TestAmdaAcquisition.cpp "amdaplugin;Qt5::Test")
40 40 declare_test(TestAmdaFuzzing TestAmdaFuzzing "tests/TestAmdaFuzzing.cpp;tests/FuzzingValidators.cpp;tests/FuzzingUtils.cpp;tests/FuzzingOperations.cpp;tests/FuzzingDefs.cpp" "amdaplugin;Qt5::Test")
41
42 pybind11_add_module(pytestamda tests/PyTestAmdaWrapper.cpp)
43 target_link_libraries(pytestamda PUBLIC amdaplugin)
44
45 #pybind11_add_module(pytestamdalib SHARED tests/PyTestAmdaWrapper.cpp)
46 add_library(pytestamdalib tests/PyTestAmdaWrapper.cpp)
47 target_link_libraries(pytestamdalib PUBLIC pybind11::module)
48 target_link_libraries(pytestamdalib PUBLIC pybind11::embed)
49 target_link_libraries(pytestamdalib PUBLIC amdaplugin)
50
51 declare_test(TestPytestamda TestPytestamda "tests/PyTestAmdaWrapperExe.cpp" "amdaplugin;pytestamdalib")
52 target_compile_definitions(TestPytestamda PRIVATE -DPYTESTAMDA_SCRIPT="${CMAKE_CURRENT_LIST_DIR}/tests/pyamdatests.py")
53
54 find_package(PythonInterp 3 REQUIRED)
55
56 add_test(NAME pyamdatests
57 COMMAND ${PYTHON_EXECUTABLE}
58 ${CMAKE_CURRENT_LIST_DIR}/tests/pyamdatests.py
59 pyamdatests)
60
61 set_tests_properties(pyamdatests PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR})
62
General Comments 0
You need to be logged in to leave comments. Login now