From 728ad1c9334ece304c0796c904ab650b3c59855c Mon Sep 17 00:00:00 2001 From: Gabriel Studer <gabriel.studer@unibas.ch> Date: Fri, 5 Apr 2024 18:15:53 +0200 Subject: [PATCH] disable numpy support in C++ layer Numpy support in C++ enabled features at two points: Efficient way of setting positions in entity handles or setting meshes in gfx.PrimList. Support for newer numpy versions would've required an effort to implement. As far as I know, no one uses these features (fingers crossed) so let's just dump numpy alltogether to simplify the build system. --- CMakeLists.txt | 15 --- cmake_support/FindNumpy.cmake | 31 ------ modules/base/pymod/__init__.py.in | 2 +- modules/base/pymod/wrap_base.cc | 1 - modules/config/CMakeLists.txt | 6 -- modules/config/config.hh.in | 1 - modules/doc/install.rst | 3 - modules/gfx/pymod/export_primlist.cc | 110 +------------------ modules/gfx/tests/test_gfx.py | 41 ------- modules/mol/base/doc/editors.rst | 33 ------ modules/mol/base/doc/entity.rst | 19 ---- modules/mol/base/pymod/export_editors.cc | 131 ----------------------- modules/mol/base/pymod/export_entity.cc | 71 ------------ modules/mol/base/tests/CMakeLists.txt | 4 - modules/mol/base/tests/test_numpy.py | 75 ------------- scripts/ost-nightly-build.sh | 1 - 16 files changed, 3 insertions(+), 541 deletions(-) delete mode 100644 cmake_support/FindNumpy.cmake delete mode 100644 modules/mol/base/tests/test_numpy.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fd6b1c03..552aae0c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,6 @@ option(OPENGLPREFERENCE_LEGACY "whether to use the OpenGL Legacy GL implementati OFF) option(ENABLE_INFO "whether openstructure should be compiled with support for the info library" ON) -option(USE_NUMPY "whether numpy support is added" - OFF) option(USE_DOUBLE_PRECISION "whether to compile in double precision" OFF) option(ENABLE_SPNAV "whether 3DConnexion devices should be supported" @@ -117,11 +115,6 @@ if (USE_SHADER) else() set(_SHADER OFF) endif() -if (USE_NUMPY) - set(_NUMPY ON) -else() - set(_NUMPY OFF) -endif() if (COMPILE_TMTOOLS) set(_TM_TOOLS ON) else() @@ -228,10 +221,6 @@ find_package(PNG REQUIRED) find_package(FFTW REQUIRED) find_package(TIFF REQUIRED) -if(USE_NUMPY) - find_package(Numpy REQUIRED) -endif() - if(ENABLE_MM) find_package(OpenMM REQUIRED) set(_OPENMM_PLUGINS "${OPEN_MM_PLUGIN_DIR}") @@ -302,9 +291,6 @@ include_directories(${Boost_INCLUDE_DIRS} ${OPEN_MM_INCLUDE_DIRS} ${SQLITE3_INCLUDE_DIRS} ) -if(USE_NUMPY) -include_directories(${PYTHON_NUMPY_INCLUDE_DIR}) -endif() if (UNIX) SET(CMAKE_SKIP_BUILD_RPATH FALSE) @@ -353,7 +339,6 @@ message(STATUS " Graphical interface (-DENABLE_GUI) : ${_UI}\n" " OpenGL support (-DENABLE_GFX) : ${_OPENGL}\n" " Shader support (-DUSE_SHADER) : ${_SHADER}\n" - " Numpy support (-DUSE_NUMPY) : ${_NUMPY}\n" " SpaceNav Device support (-DENABLE_SPNAV) : ${_SPNAV}\n" " OpenMM support (-DENABLE_MM) : ${_OPENMM}\n" " OpenMM plugins (-DOPEN_MM_PLUGIN_DIR) : ${_OPENMM_PLUGINS}\n" diff --git a/cmake_support/FindNumpy.cmake b/cmake_support/FindNumpy.cmake deleted file mode 100644 index 2f67a64ed..000000000 --- a/cmake_support/FindNumpy.cmake +++ /dev/null @@ -1,31 +0,0 @@ -if (PYTHON_NUMPY_INCLUDE_DIR) - # in cache already - set (PYTHON_NUMPY_FIND_QUIETLY TRUE) -endif (PYTHON_NUMPY_INCLUDE_DIR) - -#INCLUDE(FindPython) - -IF(Python_EXECUTABLE) - EXEC_PROGRAM ("${Python_EXECUTABLE}" - ARGS "-c 'import numpy; print(numpy.get_include())'" - OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR - RETURN_VALUE PYTHON_NUMPY_NOT_FOUND) - if (PYTHON_NUMPY_NOT_FOUND) - set(PYTHON_NUMPY_FOUND FALSE) - else (PYTHON_NUMPY_NOT_FOUND) - set (PYTHON_NUMPY_FOUND TRUE) - set (PYTHON_NUMPY_INCLUDE_DIR ${PYTHON_NUMPY_INCLUDE_DIR} CACHE STRING "Numpy include path") - endif (PYTHON_NUMPY_NOT_FOUND) -ENDIF(Python_EXECUTABLE) - -if (PYTHON_NUMPY_FOUND) - if (NOT PYTHON_NUMPY_FIND_QUIETLY) - message (STATUS "Numpy headers found") - endif (NOT PYTHON_NUMPY_FIND_QUIETLY) -else (PYTHON_NUMPY_FOUND) - if (Numpy_FIND_REQUIRED) - message (FATAL_ERROR "Numpy headers missing") - endif (Numpy_FIND_REQUIRED) -endif (PYTHON_NUMPY_FOUND) - -MARK_AS_ADVANCED (PYTHON_NUMPY_INCLUDE_DIR) diff --git a/modules/base/pymod/__init__.py.in b/modules/base/pymod/__init__.py.in index 4237d6b95..45c3e6000 100644 --- a/modules/base/pymod/__init__.py.in +++ b/modules/base/pymod/__init__.py.in @@ -18,7 +18,7 @@ #------------------------------------------------------------------------------ import os -__all__=['CharList','Correl', 'FileLogSink', 'FloatList', 'FloatMatrix', 'FloatMatrix3', 'FloatMatrix4', 'GetCurrentLogSink', 'GetPrefixPath', 'GetSharedDataPath', 'GetVerbosityLevel', 'Histogram', 'IntList', 'LogDebug', 'LogError', 'LogInfo', 'LogScript', 'LogSink', 'LogTrace', 'LogVerbose', 'LogWarning', 'Max', 'Mean', 'Median', 'Min', 'MultiLogSink', 'PopLogSink', 'PopVerbosityLevel', 'PushLogSink', 'PushVerbosityLevel', 'Range', 'SetPrefixPath', 'StdDev', 'StreamLogSink', 'StringList', 'StringLogSink', 'Units', 'VERSION', 'VERSION_MAJOR', 'VERSION_MINOR', 'VERSION_PATCH', 'WITH_NUMPY', 'conop', 'geom', 'io', 'mol', 'seq', 'stutil' @ALL_ADDITIONAL_MODULES@] +__all__=['CharList','Correl', 'FileLogSink', 'FloatList', 'FloatMatrix', 'FloatMatrix3', 'FloatMatrix4', 'GetCurrentLogSink', 'GetPrefixPath', 'GetSharedDataPath', 'GetVerbosityLevel', 'Histogram', 'IntList', 'LogDebug', 'LogError', 'LogInfo', 'LogScript', 'LogSink', 'LogTrace', 'LogVerbose', 'LogWarning', 'Max', 'Mean', 'Median', 'Min', 'MultiLogSink', 'PopLogSink', 'PopVerbosityLevel', 'PushLogSink', 'PushVerbosityLevel', 'Range', 'SetPrefixPath', 'StdDev', 'StreamLogSink', 'StringList', 'StringLogSink', 'Units', 'VERSION', 'VERSION_MAJOR', 'VERSION_MINOR', 'VERSION_PATCH', 'conop', 'geom', 'io', 'mol', 'seq', 'stutil' @ALL_ADDITIONAL_MODULES@] from ._ost_base import * from .stutil import * diff --git a/modules/base/pymod/wrap_base.cc b/modules/base/pymod/wrap_base.cc index 2c4877911..7f2d8b114 100644 --- a/modules/base/pymod/wrap_base.cc +++ b/modules/base/pymod/wrap_base.cc @@ -97,7 +97,6 @@ BOOST_PYTHON_MODULE(_ost_base) scope().attr("VERSION_MAJOR")=OST_VERSION_MAJOR; scope().attr("VERSION_MINOR")=OST_VERSION_MINOR; scope().attr("VERSION_PATCH")=OST_VERSION_PATCH; - scope().attr("WITH_NUMPY")= OST_NUMPY_SUPPORT_ENABLED; export_Logger(); export_Range(); export_Units(); diff --git a/modules/config/CMakeLists.txt b/modules/config/CMakeLists.txt index 60c1c38e2..826de455f 100644 --- a/modules/config/CMakeLists.txt +++ b/modules/config/CMakeLists.txt @@ -15,12 +15,6 @@ if (USE_SHADER) else() set(shader_support 0) endif() - -if (USE_NUMPY) - set(numpy_support 1) -else() - set(numpy_support 0) -endif() if (PROFILE) set(profiling_enabled 1) else() diff --git a/modules/config/config.hh.in b/modules/config/config.hh.in index e69421653..e48f750d4 100644 --- a/modules/config/config.hh.in +++ b/modules/config/config.hh.in @@ -29,7 +29,6 @@ #define OST_DOUBLE_PRECISION @double_prec@ #define OST_STATIC_PROPERTY_WORKAROUND @static_props@ #define OST_FFT_USE_THREADS @fftw_use_threads@ -#define OST_NUMPY_SUPPORT_ENABLED @numpy_support@ #define OST_UBUNTU_LAYOUT @ubuntu_layout@ #define OST_INFO_ENABLED @info_enabled@ diff --git a/modules/doc/install.rst b/modules/doc/install.rst index 2f5470c56..1fc703dd9 100644 --- a/modules/doc/install.rst +++ b/modules/doc/install.rst @@ -178,9 +178,6 @@ can influence it. then available at python level. This option requires a Fortran compiler. By default, this option is switched off. -* `USE_NUMPY` allows OpenStructure to pass back data in NumPy format. By - default, this is switched off. - * `ENABLE_MM` controls whether the molecular mechanics module is enabled. By default, this is switched off. If it is turned on, you should also set the paths to your local OpenMM installation: diff --git a/modules/gfx/pymod/export_primlist.cc b/modules/gfx/pymod/export_primlist.cc index 4538f366e..e0d21eb81 100644 --- a/modules/gfx/pymod/export_primlist.cc +++ b/modules/gfx/pymod/export_primlist.cc @@ -26,122 +26,16 @@ using namespace boost::python; using namespace ost; using namespace ost::gfx; -/* The following #include triggers a deprecation warning upon compilation: - -In file included from /unibas/lcs-software/software/Python/2.7.11-goolf-1.7.20/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1781:0, - from /unibas/lcs-software/software/Python/2.7.11-goolf-1.7.20/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:18, - from /unibas/lcs-software/software/Python/2.7.11-goolf-1.7.20/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:4, - from /home/zohixe92/build/ost-develop/modules/gfx/pymod/export_primlist.cc:30: -/unibas/lcs-software/software/Python/2.7.11-goolf-1.7.20/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp] - #warning "Using deprecated NumPy API, disable it by " \ - ^ - -It looks like just including <numpy/arrayobject.h>, without actually using anything from it, already triggers the -warning. This could be a side effect of other includes in export_primlist.cc though, such as boost. - -The Numpy C API documentation <https://docs.scipy.org/doc/numpy-1.15.1/reference/c-api.deprecations.html> is very -unclear about what is deprecated exactly (the whole API or only direct data access?) The Array API doc -<https://docs.scipy.org/doc/numpy-1.16.0/reference/c-api.array.html> doesn't clearly state what to import instead, -and while some functions are marked as deprecated I couldn't see that we are using any of them. Last, the migration sed -script <https://github.com/numpy/numpy/blob/master/tools/replace_old_macros.sed> didn't trigger any changes. - -The warnings appear to be safe though, behavior has been checked in <https://jira.biozentrum.unibas.ch/browse/SCHWED-3149> -and Numpy guarantees to maintain them until the next major release (2.0). So it is safe to ignore them for now. -They can be silenced with the following #define, however it was decided to keep them for now as functionality *will* -disappear in the future. - -#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION - -In the future it might be desirable to move to the newer API in Boost::Python::NumPy -which uses modern C++ instead of old-style C macros. -<https://www.boost.org/doc/libs/1_64_0/libs/python/doc/html/numpy/reference/ndarray.html> -*/ -#if OST_NUMPY_SUPPORT_ENABLED -#include <numpy/arrayobject.h> -#endif - namespace { + // used numpy support that has been deprecated... void add_mesh(PrimList& p, object ova, object ona, object oca, object oia) { -#if OST_NUMPY_SUPPORT_ENABLED - if(!PyArray_Check(ova.ptr())) { - throw Error("ova is not a numpy array"); - } - PyArrayObject* va=reinterpret_cast<PyArrayObject*>(ova.ptr()); - if(!PyArray_ISCONTIGUOUS(va)) { - throw Error("expected vertex array to be contiguous"); - } - if(PyArray_TYPE(va)!=NPY_FLOAT) { - throw Error("expected vertex array to be of dtype=float32"); - } - size_t v_size=PyArray_SIZE(va); - if(v_size%3!=0) { - throw Error("expected vertex array size to be divisible by 3"); - } - size_t v_count=v_size/3; - float* vp=reinterpret_cast<float*>(PyArray_DATA(va)); - float* np=0; - float* cp=0; - if(!ona.is_none()) { - if(!PyArray_Check(ona.ptr())) { - throw Error("ona is not a numpy array"); - } - PyArrayObject* na=reinterpret_cast<PyArrayObject*>(ona.ptr()); - if(!PyArray_ISCONTIGUOUS(na)) { - throw Error("expected normal array to be contiguous"); - } - if(PyArray_TYPE(na)!=NPY_FLOAT) { - throw Error("expected normal array to be of dtype=float32"); - } - if((size_t)PyArray_SIZE(na)!=v_size) { - throw Error("expected normal array size to match vertex array size"); - } - np=reinterpret_cast<float*>(PyArray_DATA(na)); - } - if(!oca.is_none()) { - if(!PyArray_Check(oca.ptr())) { - throw Error("oca is not a numpy array"); - } - PyArrayObject* ca=reinterpret_cast<PyArrayObject*>(oca.ptr()); - if(!PyArray_ISCONTIGUOUS(ca)) { - throw Error("expected color array to be contiguous"); - } - if(PyArray_TYPE(ca)!=NPY_FLOAT) { - throw Error("expected color array to be of dtype=float32"); - } - if((size_t)PyArray_SIZE(ca)!=v_count*4) { - throw Error("expected color array size to equal vertex-count x 4"); - } - cp=reinterpret_cast<float*>(PyArray_DATA(ca)); - } - if(!PyArray_Check(oia.ptr())) { - throw Error("oia is not a numpy array"); - } - PyArrayObject* ia=reinterpret_cast<PyArrayObject*>(oia.ptr()); - if(!PyArray_ISCONTIGUOUS(ia)) { - throw Error("expected vertex array to be contiguous"); - } - if(PyArray_TYPE(ia)!=NPY_UINT) { - throw Error("expected vertex array to be of dtype=uint32"); - } - size_t i_size=PyArray_SIZE(ia); - unsigned int* ip=reinterpret_cast<unsigned int*>(PyArray_DATA(ia)); - - p.AddMesh(vp,np,cp,v_count,ip,i_size/3); -#else - throw Error("AddMesh requires compiled-in numpy support"); -#endif + throw Error("AddMesh requires compiled-in numpy support and that has been deprecated"); } } void export_primlist() { -#if OST_NUMPY_SUPPORT_ENABLED - // The following define enforces no return value when calling import_array - #define NUMPY_IMPORT_ARRAY_RETVAL - import_array(); // magic handshake for numpy module -#endif - class_<PrimList, bases<GfxObj>, boost::shared_ptr<PrimList>, boost::noncopyable>("PrimList", init<const String& >()) .def("Clear",&PrimList::Clear) .def("_add_line",&PrimList::AddLine) diff --git a/modules/gfx/tests/test_gfx.py b/modules/gfx/tests/test_gfx.py index 2baf689d8..d4635ca18 100644 --- a/modules/gfx/tests/test_gfx.py +++ b/modules/gfx/tests/test_gfx.py @@ -28,15 +28,6 @@ import ost.mol as mol import ost.gfx as gfx import ost.geom as geom -if ost.WITH_NUMPY: - has_numpy=True - try: - import numpy - except ImportError as e: - has_numpy=False -else: - has_numpy=False - def col_delta(c1,c2): return geom.Distance(geom.Vec3(c1[0],c1[1],c1[2]),geom.Vec3(c2[0],c2[1],c2[2])) @@ -120,38 +111,6 @@ class TestGfx(unittest.TestCase): pl.AddCyl(geom.Vec3(0,0,0),geom.Vec3(1,2,3),radius1=0.5,radius2=0.1,color1=gfx.BLUE,color2=gfx.GREEN) pl.AddText("foo",[0,2,3]) pl.AddText("bar",[-2,0,0],color=gfx.WHITE,point_size=8) - if has_numpy: - pl.AddMesh(numpy.zeros((5,3),dtype=numpy.float32), - numpy.zeros((5,3),dtype=numpy.float32), - numpy.zeros((5,4),dtype=numpy.float32), - numpy.zeros((2,3),dtype=numpy.uint32)) - pl.AddMesh(numpy.zeros((7,3),dtype=numpy.float32), - None, - None, - numpy.zeros((4,3),dtype=numpy.uint32)) - - # Passing wrong data type should fail - with self.assertRaises(Exception): - pl.AddMesh(numpy.zeros((5, 3), dtype=numpy.uint32), - numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 4), dtype=numpy.float32), - numpy.zeros((2, 3), dtype=numpy.uint32)) - with self.assertRaises(Exception): - pl.AddMesh(numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 3), dtype=numpy.uint32), - numpy.zeros((5, 4), dtype=numpy.float32), - numpy.zeros((2, 3), dtype=numpy.uint32)) - with self.assertRaises(Exception): - pl.AddMesh(numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 4), dtype=numpy.uint32), - numpy.zeros((2, 3), dtype=numpy.uint32)) - with self.assertRaises(Exception): - pl.AddMesh(numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 3), dtype=numpy.float32), - numpy.zeros((5, 4), dtype=numpy.float32), - numpy.zeros((2, 3), dtype=numpy.float32)) - if __name__== '__main__': from ost import testutils diff --git a/modules/mol/base/doc/editors.rst b/modules/mol/base/doc/editors.rst index 24162f9fa..01214c4b3 100644 --- a/modules/mol/base/doc/editors.rst +++ b/modules/mol/base/doc/editors.rst @@ -439,39 +439,6 @@ Euclidian space. Set the transformed position of atoms. This method will also update the original position of atoms by applying the inverse of the entity transform. - - Setting all positions at once is by far faster than call the function for - each atom, but it is only available if OpenStructure was compiled with an - enabled ``USE_NUMPY`` flag (see :ref:`here <cmake-flags>` for details). The - fastest option to work with all atom positions externally is to extract the - list of :attr:`~ost.mol.EntityHandle.atoms` with - :meth:`ost.mol.EntityHandle.GetPositions` (with *sort_by_index = False*). - Then extract a buffered editor and use the same list of atoms with a - modified numpy array as input to this function. Example: - - .. code-block:: python - - # get atom list and positions - atom_list = ent.atoms - positions = ent.GetPositions(False) - # modify positions but keep ent and atom_list unchanged - # ... - # apply changes to entity all at once - edi = ent.EditXCS(mol.BUFFERED_EDIT) - edi.SetAtomPos(atom_list, positions) - edi.UpdateICS() - - :param atom: A valid atom handle - :type atom: :class:`ost.mol.AtomHandle` - :param atom_list: A valid atom handle list or a list of atom :attr:`indices - <ost.mol.AtomHandle.index>`. - :type atom_list: :class:`ost.mol.AtomHandleList` or :class:`list` of - :class:`int` - :param pos: The new position - :type pos: :class:`~ost.geom.Vec3` - :param pos_list: An array of positions (shape [*len(atom_list)*, 3], - preferably contiguous array in memory (C order)). - :type pos_list: :class:`numpy.array` .. method:: SetAtomOriginalPos(atom, pos) SetAtomOriginalPos(atom_list, pos_list) diff --git a/modules/mol/base/doc/entity.rst b/modules/mol/base/doc/entity.rst index 4238bfbce..6d8f4ea10 100644 --- a/modules/mol/base/doc/entity.rst +++ b/modules/mol/base/doc/entity.rst @@ -131,14 +131,6 @@ Entity Handle :type: Vec3 - .. attribute:: positions - - Equivalent to calling :meth:`GetPositions` with *sort_by_index = True*. This - property is read-only and only available if OpenStructure was compiled with - an enabled ``USE_NUMPY`` flag (see :ref:`here <cmake-flags>` for details). - - :type: :class:`numpy.array` - .. attribute:: valid Validity of handle. @@ -321,17 +313,6 @@ Entity Handle .. method:: GetGeometricCenter() See :attr:`geometric_center` - - .. method:: GetPositions(sort_by_index=True) - - :return: Array of atom positions for this entity. - :rtype: :class:`numpy.array` (shape [:attr:`atom_count`, 3]) - :param sort_by_index: If True, the atoms are sorted by their - :attr:`~AtomHandle.index`. Otherwise, they are sorted - as they appear in the :attr:`atoms` list. - - This method is only available if OpenStructure was compiled with an enabled - ``USE_NUMPY`` flag (see :ref:`here <cmake-flags>` for details). .. method:: FindWithin(pos, radius) diff --git a/modules/mol/base/pymod/export_editors.cc b/modules/mol/base/pymod/export_editors.cc index e20ee4d4e..e2cd89b9b 100644 --- a/modules/mol/base/pymod/export_editors.cc +++ b/modules/mol/base/pymod/export_editors.cc @@ -29,18 +29,6 @@ using namespace boost::python; using namespace ost; using namespace ost::mol; -/* Including NumPy headers produces compiler warnings. The ones about "Using - deprecated NumPy API..." we can not get rid of. The highest NumPy version we - support is 1.6 while the non-deprecated API starts with version 1.7. - Also see the comment in modules/gfx/pymod/export_primlist.cc for further - information. -*/ -#if OST_NUMPY_SUPPORT_ENABLED -#include <numpy/numpyconfig.h> -#define NPY_NO_DEPRECATED_API NPY_1_6_API_VERSION -#include <numpy/arrayobject.h> -#endif - namespace { BondHandle (EditorBase::*connect_a)(const AtomHandle&, @@ -93,74 +81,6 @@ void (ICSEditor::*rotate_torsion_b)(const AtomHandle&, const AtomHandle&, void (EditorBase::*renumber_chain_a)(ChainHandle,const ResNumList&)=&EditorBase::RenumberChain; void (EditorBase::*renumber_chain_b)(const ChainHandle&,int, bool)=&EditorBase::RenumberChain; -#if OST_NUMPY_SUPPORT_ENABLED -template<typename T, bool O> -void set_pos2_nc_t(XCSEditor& e, const AtomHandleList& alist, PyArrayObject* na) -{ - size_t count=0; - for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait,++count) { - if(O) { - e.SetAtomOriginalPos(*ait,geom::Vec3(static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,0))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); - } else { - e.SetAtomTransformedPos(*ait,geom::Vec3(static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,0))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); - } - } -} - -template<bool O> -void set_pos2_t(XCSEditor& e, const AtomHandleList& alist, object pyobj) -{ - size_t acount = alist.size(); - - if(!PyArray_Check(pyobj.ptr())) { - throw Error("expected a numpy array"); - return; - } - PyArrayObject* na=reinterpret_cast<PyArrayObject*>(pyobj.ptr()); - - if(PyArray_NDIM(na)!=2 || PyArray_DIM(na,0)!=int(acount) || PyArray_DIM(na,1)!=3) { - throw Error("expected a numpy array of shape (NAtoms, 3)"); - return; - } - - if(PyArray_ISCONTIGUOUS(na)) { - if(PyArray_TYPE(na)==NPY_FLOAT) { - if(O) { - e.SetAtomOriginalPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); - } else { - e.SetAtomTransformedPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); - } - } else if(PyArray_TYPE(na)==NPY_DOUBLE) { - if(O) { - e.SetAtomOriginalPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); - } else { - e.SetAtomTransformedPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); - } - } else { - throw Error("expected a numpy array of type float or double"); - return; - } - } else { - // non-contiguous -#if 0 - throw Error("expected contiguous numpy array"); -#else - if(PyArray_TYPE(na)==NPY_FLOAT) { - set_pos2_nc_t<float,O>(e,alist,na); - } else if(PyArray_TYPE(na)==NPY_DOUBLE) { - set_pos2_nc_t<double,O>(e,alist,na); - } else { - throw Error("expected a numpy array of type float or double"); - return; - } -#endif - } -} -#endif void set_pos(XCSEditor& e, object o1, object o2, bool trans) { @@ -174,50 +94,7 @@ void set_pos(XCSEditor& e, object o1, object o2, bool trans) } return; } - -#if OST_NUMPY_SUPPORT_ENABLED - - extract<AtomHandleList> eal(o1); - if(eal.check()) { - if(trans) { - set_pos2_t<false>(e,eal(),o2); - } else { - set_pos2_t<true>(e,eal(),o2); - } - return; - } - - std::map<unsigned long,AtomHandle> amap; - impl::EntityImplPtr ei=e.GetEntity().Impl(); - for(impl::ChainImplList::iterator cit=ei->GetChainList().begin(); - cit!=ei->GetChainList().end();++cit) { - for (impl::ResidueImplList::iterator rit = (*cit)->GetResidueList().begin(), - ret = (*cit)->GetResidueList().end(); rit != ret; ++rit) { - - for (impl::AtomImplList::iterator ait = (*rit)->GetAtomList().begin(), - aet = (*rit)->GetAtomList().end(); ait != aet; ++ait) { - - amap[(*ait)->GetIndex()]=*ait; - } - } - } - - AtomHandleList alist; - for(int i=0;i<len(o1);++i) { - int gid = extract<int>(o1[i]); - std::map<unsigned long,AtomHandle>::iterator ait=amap.find(static_cast<unsigned long>(gid)); - alist.push_back(ait==amap.end() ? AtomHandle() : ait->second); - } - - if(trans) { - set_pos2_t<false>(e,alist,o2); - } else { - set_pos2_t<true>(e,alist,o2); - } - -#else throw Error("SetAtom*Pos(...,ndarray) not available, because numpy support not compiled in"); -#endif } void set_o_pos(XCSEditor& e, object o1, object o2) @@ -234,14 +111,6 @@ void set_t_pos(XCSEditor& e, object o1, object o2) void export_Editors() { -#if OST_NUMPY_SUPPORT_ENABLED - // The following define enforces no return value when calling import_array - #undef NUMPY_IMPORT_ARRAY_RETVAL - #define NUMPY_IMPORT_ARRAY_RETVAL - import_array(); -#endif - - class_<EditorBase>("EditorBase", no_init) .def("InsertChain", insert_chain_a) .def("InsertChain", insert_chain_b,(arg("chain_name"),arg("chain"), arg("deep")=false)) diff --git a/modules/mol/base/pymod/export_entity.cc b/modules/mol/base/pymod/export_entity.cc index bd2e97248..b12feb7bc 100644 --- a/modules/mol/base/pymod/export_entity.cc +++ b/modules/mol/base/pymod/export_entity.cc @@ -35,18 +35,6 @@ using namespace ost::mol; #include <ost/export_helper/generic_property_def.hh> -/* Including NumPy headers produces compiler warnings. The ones about "Using - deprecated NumPy API..." we can not get rid of. The highest NumPy version we - support is 1.6 while the non-deprecated API starts with version 1.7. - Also see the comment in modules/gfx/pymod/export_primlist.cc for further - information. -*/ -#if OST_NUMPY_SUPPORT_ENABLED -#include <numpy/numpyconfig.h> -#define NPY_NO_DEPRECATED_API NPY_1_6_API_VERSION -#include <numpy/arrayobject.h> -#endif - namespace { EntityHandle create1() { return CreateEntity(); } @@ -76,53 +64,6 @@ ICSEditor depr_request_ics_editor(EntityHandle e, EditMode m) return e.EditICS(m); } - -#if OST_NUMPY_SUPPORT_ENABLED - -bool less_index(const mol::AtomHandle& a1, const mol::AtomHandle& a2) -{ - return a1.GetIndex()<a2.GetIndex(); -} -PyObject* get_pos2(EntityHandle& entity, bool id_sorted) -{ - npy_intp dims[]={entity.GetAtomCount(),3}; - PyObject* na = PyArray_SimpleNew(2,dims,NPY_FLOAT); - npy_float* nad = reinterpret_cast<npy_float*>(PyArray_DATA(na)); - if(id_sorted) { - AtomHandleList alist = entity.GetAtomList(); - std::sort(alist.begin(),alist.end(),less_index); - for(AtomHandleList::const_iterator it=alist.begin();it!=alist.end();++it,nad+=3) { - geom::Vec3 pos=(*it).GetPos(); - nad[0]=static_cast<npy_float>(pos[0]); - nad[1]=static_cast<npy_float>(pos[1]); - nad[2]=static_cast<npy_float>(pos[2]); - } - } else { - impl::EntityImplPtr ei=entity.Impl(); - for(impl::ChainImplList::iterator cit=ei->GetChainList().begin(); - cit!=ei->GetChainList().end();++cit) { - for (impl::ResidueImplList::iterator rit = (*cit)->GetResidueList().begin(), - ret = (*cit)->GetResidueList().end(); rit != ret; ++rit) { - - for (impl::AtomImplList::iterator ait = (*rit)->GetAtomList().begin(), - aet = (*rit)->GetAtomList().end(); ait != aet; ++ait, nad+=3) { - - geom::Vec3 pos=(*ait)->TransformedPos(); - nad[0]=static_cast<npy_float>(pos[0]); - nad[1]=static_cast<npy_float>(pos[1]); - nad[2]=static_cast<npy_float>(pos[2]); - }}} - } - return na; -} - -PyObject* get_pos1(EntityHandle& entity) -{ - return get_pos2(entity,true); -} - -#endif - geom::Mat4 depr_get_transformation_matrix(const EntityHandle& eh) { return eh.GetTransformationMatrix(); @@ -137,13 +78,6 @@ bool depr_is_transformation_identity(const EntityHandle& eh) void export_Entity() { -#if OST_NUMPY_SUPPORT_ENABLED - // The following define enforces no return value when calling import_array - #undef NUMPY_IMPORT_ARRAY_RETVAL - #define NUMPY_IMPORT_ARRAY_RETVAL - import_array(); -#endif - class_<EntityBase> ent_base("EntityBase", no_init); ent_base .def(self_ns::str(self)) @@ -229,11 +163,6 @@ void export_Entity() .def("GetHashCode", &EntityHandle::GetHashCode) .def(self==self) .def(self!=self) -#if OST_NUMPY_SUPPORT_ENABLED - .def("GetPositions",get_pos1) - .def("GetPositions",get_pos2) - .add_property("positions",get_pos1) -#endif ; def("CreateEntity",create1); diff --git a/modules/mol/base/tests/CMakeLists.txt b/modules/mol/base/tests/CMakeLists.txt index 591eadd86..8a97c347e 100644 --- a/modules/mol/base/tests/CMakeLists.txt +++ b/modules/mol/base/tests/CMakeLists.txt @@ -17,10 +17,6 @@ set(OST_MOL_BASE_UNIT_TESTS test_invalid.py ) -if (USE_NUMPY) - list(APPEND OST_MOL_BASE_UNIT_TESTS test_numpy.py) -endif (USE_NUMPY) - ost_unittest(MODULE mol SOURCES "${OST_MOL_BASE_UNIT_TESTS}") # for valgrind debugging diff --git a/modules/mol/base/tests/test_numpy.py b/modules/mol/base/tests/test_numpy.py deleted file mode 100644 index fb69b9afe..000000000 --- a/modules/mol/base/tests/test_numpy.py +++ /dev/null @@ -1,75 +0,0 @@ -import unittest -if __name__== '__main__': - import sys - sys.path.insert(0,"../../../../stage/lib64/openstructure/") - sys.path.insert(0,"../../../../stage/lib/openstructure/") - -import ost -from ost import geom, mol - -if ost.WITH_NUMPY: - has_numpy=True - try: - import numpy - except ImportError as e: - has_numpy=False -else: - has_numpy=False - -def v2v(v): - return geom.Vec3(float(v[0]),float(v[1]),float(v[2])) - -def dd(v1,v2): - return geom.Distance(v1,v2)<1e-8 - -class TestNumpy(unittest.TestCase): - def setUp(self): - pass - - def test_(self): - if not has_numpy: - return - entity=mol.CreateEntity() - ed=entity.EditXCS() - ch=ed.InsertChain("X") - re=ed.AppendResidue(ch,"ALA") - a0=ed.InsertAtom(re,"A",geom.Vec3(0,0,0)) - self.assertEqual(a0.GetIndex(),0) - a1=ed.InsertAtom(re,"B",geom.Vec3(1,0,0)) - self.assertEqual(a1.GetIndex(),1) - a2=ed.InsertAtom(re,"C",geom.Vec3(2,0,0)) - self.assertEqual(a2.GetIndex(),2) - a3=ed.InsertAtom(re,"D",geom.Vec3(3,0,0)) - self.assertEqual(a3.GetIndex(),3) - - self.assertTrue(dd(a0.pos,geom.Vec3(0,0,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(1,0,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(2,0,0))) - self.assertTrue(dd(a3.pos,geom.Vec3(3,0,0))) - - ed.SetAtomTransformedPos(entity.GetAtomList(), - numpy.array([[0,1,0],[0,2,0],[0,3,0],[0,4,0]], dtype=numpy.float32)) - - self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(0,3,0))) - self.assertTrue(dd(a3.pos,geom.Vec3(0,4,0))) - - na=entity.positions - - self.assertTrue(dd(v2v(na[0]),geom.Vec3(0,1,0))) - self.assertTrue(dd(v2v(na[1]),geom.Vec3(0,2,0))) - self.assertTrue(dd(v2v(na[2]),geom.Vec3(0,3,0))) - self.assertTrue(dd(v2v(na[3]),geom.Vec3(0,4,0))) - - ed.SetAtomTransformedPos([3,99,2], - numpy.array([[0,0,-3],[-1,-1,-1],[0,0,-2]], dtype=numpy.float32)) - - self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) - self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) - self.assertTrue(dd(a2.pos,geom.Vec3(0,0,-2))) - self.assertTrue(dd(a3.pos,geom.Vec3(0,0,-3))) - -if __name__== '__main__': - unittest.main() - diff --git a/scripts/ost-nightly-build.sh b/scripts/ost-nightly-build.sh index 653b9142a..4b6fbab30 100644 --- a/scripts/ost-nightly-build.sh +++ b/scripts/ost-nightly-build.sh @@ -134,7 +134,6 @@ dependencies = [ ('FFTW', '3.3.3', '-dynamic', ('gompi', '1.4.10')), ] -configopts = " -DOPTIMIZE=1 -DCOMPILE_TMTOOLS=1 -DENABLE_GFX=OFF -DENABLE_GUI=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS_RELEASE='-O3 -DNDEBUG -Wno-unused-local-typedefs' -DUSE_NUMPY=1 -DUSE_RPATH=1" configopts += " -DCOMPOUND_LIB=/scicore/home/schwede/GROUP/OpenStructure/ChemLib/1.6/compounds.chemlib" -- GitLab