diff --git a/pymolfile/__init__.py b/pymolfile/__init__.py index 0e4f244a9fecb0fa27699383764a33f9bd9b22cf..2c2eb8483d30419664826a7c3a7842d633c5bdad 100644 --- a/pymolfile/__init__.py +++ b/pymolfile/__init__.py @@ -1,11 +1,14 @@ from __future__ import absolute_import +import warnings +try: + from .molfile import libpymolfile +except ImportError: + warnings.warn("libpymolfile package not available, pymolfile does not work without its library!") + +from . import plugin_list from . import pymolfile __all__ = [ "pymolfile" ] -MAX_NUM_PLUGINS = 200 -C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS) -MOLFILE_PLUGINS = pymolfile.plugins() - diff --git a/pymolfile/__init__.pyc b/pymolfile/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db20cea1fbf7e49adc459293f5aed9592e6b1e5b Binary files /dev/null and b/pymolfile/__init__.pyc differ diff --git a/pymolfile/__pycache__/__init__.cpython-36.pyc b/pymolfile/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63924f642961ed427b9c7f4fb811158d1fbc4432 Binary files /dev/null and b/pymolfile/__pycache__/__init__.cpython-36.pyc differ diff --git a/pymolfile/__pycache__/plugin_list.cpython-36.pyc b/pymolfile/__pycache__/plugin_list.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5083ef19e1fb1d757a92f41b3057ff13fa8093c2 Binary files /dev/null and b/pymolfile/__pycache__/plugin_list.cpython-36.pyc differ diff --git a/pymolfile/__pycache__/pymolfile.cpython-36.pyc b/pymolfile/__pycache__/pymolfile.cpython-36.pyc index 1e19a06a51bf6003652eb8cfb19bc4b9a0a26c52..54786c87e0e5f0ff6aaaaacaaec9edcfe4107478 100644 Binary files a/pymolfile/__pycache__/pymolfile.cpython-36.pyc and b/pymolfile/__pycache__/pymolfile.cpython-36.pyc differ diff --git a/pymolfile/molfile/__init__.py b/pymolfile/molfile/__init__.py index 2fa350890c2794810c7356d8e44d2271788527c6..7d9a865f6f70451bcb9b0efc731be5bb612b7db6 100644 --- a/pymolfile/molfile/__init__.py +++ b/pymolfile/molfile/__init__.py @@ -1,7 +1,7 @@ -# Stand-alone python bindings for libvmdmolfile +# Stand-alone python bindings for libpymolfile # Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk> -# Published under the BSD LICENSE +# Published under the UIUC OpenSource LICENSE """libpymolfile library. """ diff --git a/pymolfile/molfile/__init__.pyc b/pymolfile/molfile/__init__.pyc index abcb6018cc59e2cabc6876c73bafec8ec6bfa898..c7f427c1eb27c1e30e6a82be67f5fe5f3031bc4d 100644 Binary files a/pymolfile/molfile/__init__.pyc and b/pymolfile/molfile/__init__.pyc differ diff --git a/pymolfile/molfile/__pycache__/__init__.cpython-36.pyc b/pymolfile/molfile/__pycache__/__init__.cpython-36.pyc index 3aaa7daa4aa032356318545e3c703ed00ac0ac6e..f4bafae7c67b6c6045648c7b759850b862012a34 100644 Binary files a/pymolfile/molfile/__pycache__/__init__.cpython-36.pyc and b/pymolfile/molfile/__pycache__/__init__.cpython-36.pyc differ diff --git a/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc b/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc index bc43e9aae4503301f6e3a92af0ca934b25c01e4b..8dd9e9273c607b9be2faa81535ac9f264641d5af 100644 Binary files a/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc and b/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc differ diff --git a/pymolfile/molfile/_libpymolfile.so b/pymolfile/molfile/_libpymolfile.so index fdfdcc550fe4a6a7dba7e86c38a4b9974d2da208..c2d0abc0cc6df354db0bd7aab872dd1cc619cbdb 100755 Binary files a/pymolfile/molfile/_libpymolfile.so and b/pymolfile/molfile/_libpymolfile.so differ diff --git a/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so b/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so index a0b3a8c49d4db6f95fffdd9921c301f5d99e2fdd..e04a1213f814adef895c7fc7f017a6c7929ca7ae 100644 Binary files a/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so and b/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so differ diff --git a/pymolfile/molfile/compile-without-tng.sh b/pymolfile/molfile/compile-without-tng.sh new file mode 100644 index 0000000000000000000000000000000000000000..3f2ddc97294adb3c692ed46004874d49ea7dfb1b --- /dev/null +++ b/pymolfile/molfile/compile-without-tng.sh @@ -0,0 +1,20 @@ +echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" +swig -py3 -Wall -c++ -python libpymolfile.i +echo "'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'" +g++-7 -fPIC -Wall -Wextra -shared -g -Wunused-function -Wunused-parameter \ + -I/labEnv3/lib/python3.6/site-packages/numpy/core/include/ \ + -I./include \ + -I./include/molfile_plugin/include \ + -I./lib/molfile_plugin/lib \ + -I./include/plugin_src/include \ + -I./include/netcdf/include \ + -I./include/expat/include \ + -I./include/tng/include \ + libpymolfile_wrap.cxx pymolfile.c -o _libpymolfile.so -L. \ + -L./lib/molfile_plugin/lib \ + -L./lib/netcdf/lib \ + -L./lib/expat/lib \ + -L./lib/tng/lib \ + lib/molfile_plugin/lib/libmolfile_plugin.a -I/labEnv3/include/python3.6m/ \ + -L/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib \ + -lpython3.6 -lnetcdf diff --git a/pymolfile/molfile/compile27.sh b/pymolfile/molfile/compile27.sh new file mode 100644 index 0000000000000000000000000000000000000000..5863c883f775c4e6a1ec560c4a11a330b2a22bef --- /dev/null +++ b/pymolfile/molfile/compile27.sh @@ -0,0 +1,22 @@ +echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" +#swig -py3 -Wall -c++ -python libpymolfile.i +swig -Wall -c++ -python libpymolfile.i +echo "'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'" +g++-7 -fPIC -Wall -Wextra -Xlinker -export-dynamic -shared -g -Wunused-function -Wunused-parameter \ + -I/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include/ \ + -I./include \ + -I./include/molfile_plugin/include \ + -I./lib/molfile_plugin/lib \ + -I./include/plugin_src/include \ + -I./include/netcdf/include \ + -I./include/expat/include \ + -I./include/tng/include \ + libpymolfile_wrap.cxx pymolfile.c -o _libpymolfile.so -L. \ + -L./lib/molfile_plugin/lib \ + -L./lib/netcdf/lib \ + -L./lib/expat/lib \ + -L./lib/tng/lib \ + lib/molfile_plugin/lib/libmolfile_plugin.a \ + -I/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/include/python2.7/ \ + -L/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib \ + -lpython2.7 -ltng_io -lnetcdf -lexpat diff --git a/pymolfile/molfile/libpymolfile.i b/pymolfile/molfile/libpymolfile.i index 4531072d9c1840d9e5080f4ec2a81303a30575ea..ff8fdad9ef1b08e1308ea58093ad82ca8a8ea1fa 100644 --- a/pymolfile/molfile/libpymolfile.i +++ b/pymolfile/molfile/libpymolfile.i @@ -165,9 +165,10 @@ PyObject * my_close_file_read(PyObject* molpack) { plugin = plugin_handle->plugin; file_handle = plugin_handle->file_handle; numatoms = plugin_handle->natoms; - plugin->close_file_read(file_handle); + Py_INCREF(plugin_handle); + plugin->close_file_read(file_handle); Py_DECREF(plugin_handle); - Py_DECREF(molpack); + /*Py_DECREF(molpack);*/ Py_RETURN_NONE; } %} diff --git a/pymolfile/molfile/libpymolfile_wrap.cxx b/pymolfile/molfile/libpymolfile_wrap.cxx index 533687b00f09f7f7734804817b5a34f0917f375f..41187236a0516f0d7f6db83ce2865f0fc727bb7a 100644 --- a/pymolfile/molfile/libpymolfile_wrap.cxx +++ b/pymolfile/molfile/libpymolfile_wrap.cxx @@ -3445,9 +3445,10 @@ PyObject * my_close_file_read(PyObject* molpack) { plugin = plugin_handle->plugin; file_handle = plugin_handle->file_handle; numatoms = plugin_handle->natoms; - plugin->close_file_read(file_handle); + Py_INCREF(plugin_handle); + plugin->close_file_read(file_handle); Py_DECREF(plugin_handle); - Py_DECREF(molpack); + /*Py_DECREF(molpack);*/ Py_RETURN_NONE; } diff --git a/pymolfile/molfile/pymolfile.h b/pymolfile/molfile/pymolfile.h index 94a0b42d5dcb259684cb942600e482c97e5ed797..14b925546ef5d974e1cb0182bef4dc1e9ff2baeb 100644 --- a/pymolfile/molfile/pymolfile.h +++ b/pymolfile/molfile/pymolfile.h @@ -61,7 +61,7 @@ void del_molfile_plugin_list(PyObject* molcapsule); static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj) { - void *ret = PyCapsule_GetPointer(obj, NULL); + void *ret = PyCapsule_GetPointer(obj, "plugin_handle"); if (ret == NULL) { PyErr_Clear(); } @@ -70,7 +70,7 @@ static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj) static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*destr)(PyObject *)) { - PyObject *ret = PyCapsule_New(ptr, NULL, destr); + PyObject *ret = PyCapsule_New(ptr, "plugin_handle", destr); if (ret == NULL) { PyErr_Clear(); } diff --git a/pymolfile/molfile/vmd_molfile_plugins/Make-arch b/pymolfile/molfile/vmd_molfile_plugins/Make-arch index a79c02dd93f796515fc8a0a319c8346401ab2da0..c97290cebd0c343b6f5b2d7cf46456c0b37bff42 100755 --- a/pymolfile/molfile/vmd_molfile_plugins/Make-arch +++ b/pymolfile/molfile/vmd_molfile_plugins/Make-arch @@ -29,6 +29,8 @@ make-arch-help: @echo " MACOSX" @echo " MACOSXX86" @echo " MACOSXX86_64" + @echo " MACOSXX86_64GCC" + @echo " MACOSXX86_64GCCTNG" @echo " NETBSD" @echo " OPENPOWER" @echo " SOLARIS2" @@ -499,6 +501,27 @@ MACOSXX86_64: "TCLSHLD = c++ -dynamiclib" MACOSXX86_64GCC: + $(MAKE) dynlibs staticlibs bins \ + "ARCH = MACOSXX86_64GCC" \ + "COPTO = -m64 -fPIC -o " \ + "LOPTO = -m64 -fPIC -o " \ + "CC = gcc-7" \ + "CXX = g++-7" \ + "DEF = -D" \ + "CCFLAGS = -m64 -Os -Wall -fPIC -dynamic" \ + "CXXFLAGS = -m64 -Os -Wall -fPIC -dynamic" \ + "TCLLDFLAGS = -ltcl8.5" \ + "NETCDFLDFLAGS = -lnetcdf" \ + "NETCDFLIB = -L/usr/local/Cellar/netcdf/4.4.1.1_6/lib " \ + "NETCDFINC = -I/usr/local/Cellar/netcdf/4.4.1.1_6/include " \ + "AR = ar" \ + "NM = nm -p" \ + "RANLIB = ranlib" \ + "LIBTOOL = libtool -dynamic" \ + "SHLD = g++-7 -shared" \ + "TCLSHLD = g++-7 -dynamiclib" + +MACOSXX86_64GCCTNG: $(MAKE) dynlibs staticlibs bins \ "ARCH = MACOSXX86_64GCC" \ "COPTO = -m64 -fPIC -o " \ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin-s.o b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin-s.o deleted file mode 100644 index 02dcbe695b7e0d5252e37da16906c1f931355049..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin-s.o and /dev/null differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.o b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.o deleted file mode 100644 index 32eab9e2adb7b19e7ee1fbbd099a0c8c636f2b3d..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.o and /dev/null differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.so b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.so deleted file mode 100755 index 30d75a56dde6c660f76000ab2215e61a76cec856..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/hoomdplugin.so and /dev/null differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.a b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.a index 0e53d339f0336cf2c58997d13b20181adfc279ab..f4e208badc74bca6caed07bf4ebf6ba5f906e2ca 100644 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.a and b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.a differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.h b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.h index 8c25b6dac3da210c2d5f0bf89ce255cd828be693..3eec061a70c95d39acb51cd4027d769ddf04f4be 100644 --- a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.h +++ b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/libmolfile_plugin.h @@ -204,12 +204,6 @@ extern int molfile_maeffplugin_fini(void); extern int molfile_netcdfplugin_init(void); extern int molfile_netcdfplugin_register(void *, vmdplugin_register_cb); extern int molfile_netcdfplugin_fini(void); -extern int molfile_hoomdplugin_init(void); -extern int molfile_hoomdplugin_register(void *, vmdplugin_register_cb); -extern int molfile_hoomdplugin_fini(void); -extern int molfile_tngplugin_init(void); -extern int molfile_tngplugin_register(void *, vmdplugin_register_cb); -extern int molfile_tngplugin_fini(void); #define MOLFILE_INIT_ALL \ molfile_abinitplugin_init(); \ @@ -278,8 +272,6 @@ extern int molfile_tngplugin_fini(void); molfile_dtrplugin_init(); \ molfile_maeffplugin_init(); \ molfile_netcdfplugin_init(); \ - molfile_hoomdplugin_init(); \ - molfile_tngplugin_init(); \ #define MOLFILE_REGISTER_ALL(v, cb) \ molfile_abinitplugin_register(v, cb); \ @@ -348,8 +340,6 @@ extern int molfile_tngplugin_fini(void); molfile_dtrplugin_register(v, cb); \ molfile_maeffplugin_register(v, cb); \ molfile_netcdfplugin_register(v, cb); \ - molfile_hoomdplugin_register(v, cb); \ - molfile_tngplugin_register(v, cb); \ #define MOLFILE_FINI_ALL \ molfile_abinitplugin_fini(); \ @@ -418,8 +408,6 @@ extern int molfile_tngplugin_fini(void); molfile_dtrplugin_fini(); \ molfile_maeffplugin_fini(); \ molfile_netcdfplugin_fini(); \ - molfile_hoomdplugin_fini(); \ - molfile_tngplugin_fini(); \ #ifdef __cplusplus } diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin-s.o b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin-s.o deleted file mode 100644 index 726261002f304e578717594280d2f8a5c5746995..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin-s.o and /dev/null differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.o b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.o deleted file mode 100644 index d9db5f9d3e7fd3d5e0c357d4ca1b63d6c73b78ae..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.o and /dev/null differ diff --git a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.so b/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.so deleted file mode 100755 index 5e35447d790c7ccc92a3a7d31cc7d45e4e63f764..0000000000000000000000000000000000000000 Binary files a/pymolfile/molfile/vmd_molfile_plugins/compile/lib_MACOSXX86_64GCC/molfile/tngplugin.so and /dev/null differ diff --git a/pymolfile/plugin_list.py b/pymolfile/plugin_list.py new file mode 100644 index 0000000000000000000000000000000000000000..6665034e5e077518aaa9b7c8add1474c3b393047 --- /dev/null +++ b/pymolfile/plugin_list.py @@ -0,0 +1,63 @@ +import warnings +import sys + +from .molfile import libpymolfile +try: + from .molfile import libpymolfile +except ImportError: + warnings.warn("libpymolfile package not available, pymolfile does not work without its library!") + +MAX_NUM_PLUGINS = 200 +C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS) + +def byte_str_decode(data, dectype=None): + try: + return data.decode(dectype) + except AttributeError: + return data + +def plugins(): + """ Information on the available molfile plugins + + Example tuple: ('psf', 'psf', 1, 1, 1, 0, 1, 1, 1, 0, + 'CHARMM,NAMD,XPLOR PSF', 'mol file reader', + 'Justin Gullingsrud, John Stone', 1, 9, 17, 1) + + The fields in the tuple represent info in ordered as follows: + 1: format extension + 2: format name + 3: read_structure is avaliable if 1 + 4: read_bonds is avaliable if 1 + 5: read_angles is avaliable if 1 + 6: read_next_timestep is avaliable if 1 + 7: write_structure is avaliable if 1 + 8: write_bonds is avaliable if 1 + 9: write_angles is avaliable if 1 + 10: write_timestep is avaliable if 1 + 11: long name of the plugin + 12: type of plugin + 13: authors of the plugin + 14: major version of the plugin + 15: minor version of the plugin + 16: ABI version of the plugin + 17: 1 if is reentrant (returns is_reentrant) + + Returns: A list of tuples that includes the information and + capabilities of each molfile plugin. The information is + extracted from molfile_plugin_t. + """ + global C_MOLFILE_PLUGINS + numlist = libpymolfile.molfile_init() + if sys.version_info > (3,): + basestring = str + plugins_list = [ + [byte_str_decode(item, + dectype="unicode_escape") for item in libpymolfile.molfile_plugin_info( + C_MOLFILE_PLUGINS, i) + ] for i in range(numlist) + ] + libpymolfile.molfile_finish() + return plugins_list + +MOLFILE_PLUGINS = plugins() + diff --git a/pymolfile/plugin_list.pyc b/pymolfile/plugin_list.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2ae09006f8595e1ab959ded1fa70b1e9e6da63d Binary files /dev/null and b/pymolfile/plugin_list.pyc differ diff --git a/pymolfile/pymolfile.py b/pymolfile/pymolfile.py index b96887b61467d291b7a59818c779864098ea0ce0..6a1ce670e90f2ce25a25cace31a6d33719e76b1b 100644 --- a/pymolfile/pymolfile.py +++ b/pymolfile/pymolfile.py @@ -16,41 +16,18 @@ try: except ImportError: warnings.warn("libpymolfile package not available, pymolfile does not work without its library!") +from .plugin_list import plugins, byte_str_decode, MOLFILE_PLUGINS, C_MOLFILE_PLUGINS -def plugins(): - """ Information on the available molfile plugins - - Example tuple: ('psf', 'psf', 1, 1, 1, 0, 1, 1, 1, 0, - 'CHARMM,NAMD,XPLOR PSF', 'mol file reader', - 'Justin Gullingsrud, John Stone', 1, 9, 17, 1) - - The fields in the tuple represent info in ordered as follows: - 1: format extension - 2: format name - 3: read_structure is avaliable if 1 - 4: read_bonds is avaliable if 1 - 5: read_angles is avaliable if 1 - 6: read_next_timestep is avaliable if 1 - 7: write_structure is avaliable if 1 - 8: write_bonds is avaliable if 1 - 9: write_angles is avaliable if 1 - 10: write_timestep is avaliable if 1 - 11: long name of the plugin - 12: type of plugin - 13: authors of the plugin - 14: major version of the plugin - 15: minor version of the plugin - 16: ABI version of the plugin - 17: 1 if is reentrant (returns is_reentrant) - - Returns: A list of tuples that includes the information and - capabilities of each molfile plugin. The information is - extracted from molfile_plugin_t. - """ - numlist = libpymolfile.molfile_init() - plugins_list = [libpymolfile.molfile_plugin_info(C_MOLFILE_PLUGINS, i) for i in range(numlist)] - libpymolfile.molfile_finish() - return plugins_list +def list_plugins(): + global MOLFILE_PLUGINS + return MOLFILE_PLUGINS + +def decode_array(inarray): + return [ + [byte_str_decode(element, + dectype="unicode_escape") for element in item + ] for item in inarray + ] def get_dir_base_extension(file_name): """ Splits directory, file base and file extensions @@ -86,6 +63,9 @@ def get_plugin_with_ext(file_ext): Returns: Plugin no in the list and the list item (the plugin info tuple) """ + global MOLFILE_PLUGINS + global C_MOLFILE_PLUGINS + if not MOLFILE_PLUGINS: MOLFILE_PLUGINS = plugins() @@ -93,14 +73,17 @@ def get_plugin_with_ext(file_ext): plugin_no = -1 for plugin_info in MOLFILE_PLUGINS: plugin_no += 1 - if file_ext == plugin_info[1]: - return (plugin_no, plugin_info) + plugin_ext_info = str(plugin_info[0]).replace('*|', + '').replace('*', '').replace('|', ',').replace(' ', '') + for ext_item in str(plugin_ext_info).split(','): + if str(file_ext) == str(ext_item): + return (plugin_no, plugin_info) return None def plugins_same(plugin_one, plugin_two): - if((plugin_one[1] == plugin_two[1]) and - (plugin_one[2][2] == plugin_two[2][2])): + if((plugin_one[0] == plugin_two[0]) and + (plugin_one[1][1] == plugin_two[1][1])): return True else: return False @@ -111,6 +94,9 @@ def get_plugin_with_name(plugin_name): Returns: Plugin no in the list and the list item (the plugin info tuple) """ + global MOLFILE_PLUGINS + global C_MOLFILE_PLUGINS + if not MOLFILE_PLUGINS: MOLFILE_PLUGINS = plugins() @@ -118,58 +104,113 @@ def get_plugin_with_name(plugin_name): plugin_no = -1 for plugin_info in MOLFILE_PLUGINS: plugin_no += 1 - if plugin_name == plugin_info[2]: + if(str(plugin_name) in str(plugin_info[1]) or + str(plugin_name) in str(plugin_info[10])): return (plugin_no, plugin_info) return None -class Topology( object ): +class Topology(object): - def __init__(self): + def __init__(self, fplugin, fname, ftype, natoms): self.natoms = None self.structure = None self.bonds = None self.angles = None + self._structure = None + self._bonds = None + self._angles = None + self.pluginhandle = None + try: + self.pluginhandle = libpymolfile.open_file_read(fplugin, + fname, ftype, natoms) + self.natoms = self.pluginhandle.natoms + except (IOError, OSError, AttributeError): + pass + + def read_structure(self, prototype): + try: + self._structure = libpymolfile.read_fill_structure(self.pluginhandle, prototype) + return self._structure + except (AttributeError, SystemError): + return None + + def read_bonds(self): + try: + self._bonds = libpymolfile.read_fill_bonds(self.pluginhandle) + return self._bonds + except (AttributeError, SystemError): + return None + + def read_angles(self): + try: + self._angles = libpymolfile.read_fill_angles(self.pluginhandle) + return self._angles + except (AttributeError, SystemError): + return None def __del__( self ): - pass + if self.pluginhandle is not None: + libpymolfile.close_file_read(self.pluginhandle) -class Trajectory( object ): +class Trajectory(object): def __init__(self, file_name, file_format, plugin, natoms): + global MOLFILE_PLUGINS + global C_MOLFILE_PLUGINS self.natoms = None self.atoms = None self.plugin = None + self.handle = None self.fname = None self.ftype = None self.fname = file_name self.ftype = file_format self.plugin = plugin - self.natoms = natoms + self.natoms = 0 - def iread(self, chunk=None): - numlist = libpymolfile.molfile_init() - tplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, - self.plugin[1]) - pluginhandle = libpymolfile.open_file_read(tplugin, - file_name, file_format, natoms) + if natoms is not None: + self.natoms = natoms - step=0 - while True: + numlist = libpymolfile.molfile_init() + self.fplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, + self.plugin[0]) + self.pluginhandle = None + if self.natoms > 0: try: - x = libpymolfile.read_fill_next_timestep( - pluginhandle) + self.pluginhandle = libpymolfile.open_file_read(self.fplugin, + self.fname, self.ftype, self.natoms) + except (IOError, OSError, AttributeError): + pass + + def read_next(self): + return libpymolfile.read_fill_next_timestep(self.pluginhandle) + + def iter_on_traj(self): + try: + empty = False + self.step = 0 + while not empty: + print(f) + x = self.read_next() if x is None: - break - step=step+1 - if x is not None: - self.atoms = x + empty = True + else: + self.step += 1 yield x - except (AttributeError,OSError): - pass + except (IOError, AttributeError, OSError): + return - libpymolfile.close_file_read(pluginhandle) - libpymolfile.molfile_finish() + def iread(self): + iter_obj = iter(self.iter_on_traj()) + try: + while True: + self.atoms = next(iter_obj) + return self.atoms + except StopIteration: + pass + finally: + del iter_obj # def read_frame(self, index_no): # numlist = libpymolfile.molfile_init() @@ -187,40 +228,9 @@ class Trajectory( object ): # file_name, file_format, natoms) # libpymolfile.molfile_finish() - def __del__( self ): - pass - -class Molfile(object): - - def __init__(self, file_name, **kwargs): - self.plugin_list = MOLFILE_PLUGINS - self.c_plugin_list = C_MOLFILE_PLUGINS - self.trajectory = None - self.topology = None - self.fplugin = None - self.tplugin = None - self.smolplugin = None - self.cmolplugin = None - self.kwords = { - "file_format" : None, - "file_plugin" : None, - "topology" : None, - "topology_format" : None, - "topology_plugin" : None, - "natoms" : None - } - - if not C_MOLFILE_PLUGINS: - C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS) - if not MOLFILE_PLUGINS: - MOLFILE_PLUGINS = plugins() - if(MOLFILE_PLUGINS and self.plugin_list is None): - self.plugin_list = MOLFILE_PLUGINS - if(C_MOLFILE_PLUGINS and self.c_plugin_list is None): - self.c_plugin_list = C_MOLFILE_PLUGINS - - def __del__( self ): - pass + def __del__(self): + if self.pluginhandle is not None: + libpymolfile.close_file_read(self.pluginhandle) def read_topology(self, file_name, file_format, plugin): """ Reads structure, bonds, angles, dihedrals, impropers and @@ -241,13 +251,15 @@ def read_topology(self, file_name, file_format, plugin): function returns None """ topo = None + structure = None + bonds = None + angles = None if(file_name is not None and file_format is not None and plugin is not None): natoms=0 - pluginhandle = libpymolfile.open_file_read(plugin, - file_name, file_format, natoms) - natoms = pluginhandle.natoms + topo = Topology(plugin, file_name, file_format, natoms) + topo.natoms = natoms #if 0 && vmdplugin_ABIVERSION > 17 # /* The new PDB file formats allows for much larger structures, */ # /* which can therefore require longer chain ID strings. The */ @@ -266,46 +278,50 @@ def read_topology(self, file_name, file_format, plugin): chain_size = 'S2' else: chain_size = 'S4' - prototype = numpy.array([ - ('C1','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6), - ('C2','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6) - ], - dtype=[ - ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'), - ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size), - ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'), - ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'), - ('radius', 'f4'), ('atomicnumber', 'i4') - ] - ) - structure = libpymolfile.read_fill_structure(pluginhandle, prototype) - try: - bonds = libpymolfile.read_fill_bonds(pluginhandle) - except (AttributeError, SystemError): - pass - - try: - angles = libpymolfile.read_fill_angles(pluginhandle) - except (AttributeError, SystemError): - pass - - if structure: - topo = Topology() - topo.natoms = natoms - topo.structure = structure - if bonds: - topo.bonds = bonds - if angles: - topo.angles = angles - - libpymolfile.close_file_read(pluginhandle) - - if topo: + if('dtr' in file_format or + 'stk' in file_format or + 'atr' in file_format): + prototype = np.array([ + ('','','',0,'','','','',1.0,1.0,1.0,1.0,1.0,6,0), + ('','','',0,'','','','',1.0,1.0,1.0,1.0,1.0,6,0) + ], + dtype=[ + ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'), + ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size), + ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'), + ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'), + ('radius', 'f4'), ('atomicnumber', 'i4'), ('ctnumber', 'i4') + ] + ) + else: + prototype = np.array([ + ('','','',0,'','','','',1.0,1.0,1.0,1.0,1.0,6), + ('','','',0,'','','','',1.0,1.0,1.0,1.0,1.0,6) + ], + dtype=[ + ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'), + ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size), + ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'), + ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'), + ('radius', 'f4'), ('atomicnumber', 'i4') + ] + ) + + if topo.read_structure(prototype) is not None: + topo.structure = decode_array(topo._structure) + if topo.read_bonds() is not None: + topo.bonds = topo._bonds + if topo.read_angles() is not None: + topo.angles = topo._angles + + if(topo.structure is not None or + topo.bonds is not None or + topo.angles is not None): return topo else: return None -class OpenMolfile(Molfile): +class OpenMolfile(object): """ The main class/function to read topology and trajectory files @@ -315,13 +331,40 @@ class OpenMolfile(Molfile): without topology information. (the number of atoms must be known) If both files are supplied, it returns trajectory class with topology information. + If file has both topology and trajectory info, both info will be + available in the class + If none of the above is available, the topology and + trajectory will be None in the return object """ - def __init__(self, file_name, **kwargs): + def __init__(self, *args, **kwargs): + self.initialize_settings() + #super(OpenMolfile, self).__init__(*args, **kwargs) + global MOLFILE_PLUGINS + global C_MOLFILE_PLUGINS + file_name = None + + if args: + for arg in args: + if isinstance(arg, dict): + self.reset_kwords() + for k, v in arg.items(): + if k in self.kwords: + self.kwords[k] = v + elif isinstance(arg, (list, tuple)): + self.kwords["file_name"] = arg[0] + elif isinstance(arg, str): + self.kwords["file_name"] = arg + else: + self.kwords["file_name"] = arg + if kwargs: for k, v in kwargs.items(): if k in self.kwords: self.kwords[k] = v + + if self.kwords["file_name"] is not None: + file_name = self.kwords["file_name"] if file_name: if self.kwords["file_format"] is None: @@ -338,34 +381,35 @@ class OpenMolfile(Molfile): plugin_item = get_plugin_with_ext(self.kwords["file_format"]) if plugin_item: self.fplugin = plugin_item - self.kwords["file_plugin"] = plugin_item[2][2] + self.kwords["file_plugin"] = plugin_item[1][1] else: self.kwords["file_plugin"] = None - + if self.kwords["file_plugin"]: # Check if file_plugin reads structure info # for the given file format. - if self.fplugin[2][3] == 1: + if self.fplugin[1][2] == 1: # Topology may be read with the plugin. # This will override topology information # if a 'topology' is supplied in keywords. if self.kwords["file_format"] is not None: numlist = libpymolfile.molfile_init() self.smolplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, - self.fplugin[1]) - self.topology = read_topology(file_name, + self.fplugin[0]) + self.topology = read_topology(self, + file_name, self.kwords["file_format"], self.smolplugin) - libpymolfile.molfile_finish() + #libpymolfile.molfile_finish() - if self.fplugin[2][3] == 0: + if self.fplugin[1][2] == 0: # Topology can not be read with plugin from # the file. If 'topology' is not set but 'natoms' # is set, only the trajectory will be available. if self.kwords["topology"] is not None: - if isinstance(self.kwords["topology"], Molfile): + if isinstance(self.kwords["topology"], OpenMolfile): self.topology = self.kwords["topology"].topology - elif isinstance(elf.kwords["topology"], Topology): + elif isinstance(self.kwords["topology"], Topology): self.topology = self.kwords["topology"] else: if self.kwords["topology_format"] is None: @@ -383,30 +427,30 @@ class OpenMolfile(Molfile): topo_plugin_item = get_plugin_with_ext(self.kwords["topology_format"]) if topo_plugin_item: self.tplugin = topo_plugin_item - self.kwords["topology_plugin"] = topo_plugin_item[2][2] + self.kwords["topology_plugin"] = topo_plugin_item[1][1] else: self.kwords["topology_plugin"] = None if self.kwords["topology_plugin"]: # Check if topology_plugin reads structure info # for the given file format. - if self.tplugin[2][3] == 1: + if self.tplugin[1][2] == 1: # Topology may be read with the plugin. # This will override the topology information. if self.kwords["topology_format"] is not None: numlist = libpymolfile.molfile_init() self.smolplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, - self.fplugin[1]) + self.fplugin[0]) self.topology = read_topology(file_name, self.kwords["topology_format"], self.smolplugin) - libpymolfile.molfile_finish() + #libpymolfile.molfile_finish() else: - print("Pymolfile can not determine the {0} file format " + - "of the file {1}" % (self.kwords["topology_format"], - topo_file_base + "." + topo_file_ext)) + print("Pymolfile can not find a plugin to open the '" + + self.kwords["topology_format"] + "' file format of the file " + + str(topo_file_base) + "." + str(topo_file_ext)) - if(self.fplugin[2][6] == 1): + if(self.fplugin[1][5] == 1): num_atoms = 0 if self.topology: num_atoms = self.topology.natoms @@ -416,11 +460,55 @@ class OpenMolfile(Molfile): if num_atoms>0: self.trajectory = Trajectory(file_name, self.kwords["file_format"], - self.kwords["file_plugin"], + self.fplugin, num_atoms) else: - print("Pymolfile can not determine the {0} file format " + - "of the file {1}" % (self.kwords["file_format"], - file_base + "." + file_ext)) + print("Pymolfile can not find a plugin to open the '" + self.kwords["file_format"] + + "' file format of the file " + str(file_base) + "." + str(file_ext)) + + def initialize_settings(self): + global MOLFILE_PLUGINS + global C_MOLFILE_PLUGINS + self.plugin_list = MOLFILE_PLUGINS + self.c_plugin_list = C_MOLFILE_PLUGINS + self.trajectory = None + self.topology = None + self.fplugin = None + self.tplugin = None + self.smolplugin = None + self.cmolplugin = None + self.kwords = { + "file_name" : None, + "file_format" : None, + "file_plugin" : None, + "topology" : None, + "topology_format" : None, + "topology_plugin" : None, + "natoms" : None + } + + if not C_MOLFILE_PLUGINS: + C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS) + if not MOLFILE_PLUGINS: + MOLFILE_PLUGINS = plugins() + if(MOLFILE_PLUGINS and self.plugin_list is None): + self.plugin_list = MOLFILE_PLUGINS + if(C_MOLFILE_PLUGINS and self.c_plugin_list is None): + self.c_plugin_list = C_MOLFILE_PLUGINS + def reset_kwords(self): + self.kwords.update({ + "file_name" : None, + "file_format" : None, + "file_plugin" : None, + "topology" : None, + "topology_format" : None, + "topology_plugin" : None, + "natoms" : None + }) + + def __del__(self): + del self.topology + del self.trajectory + libpymolfile.molfile_finish() diff --git a/pymolfile/pymolfile.pyc b/pymolfile/pymolfile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad428713b68f97c74134807f79a3bc1f2769ca3b Binary files /dev/null and b/pymolfile/pymolfile.pyc differ diff --git a/pymolfile/test.py b/pymolfile/test.py deleted file mode 100644 index 35fb3d9cfb303bc5ded90f2ca018938d5d82bc26..0000000000000000000000000000000000000000 --- a/pymolfile/test.py +++ /dev/null @@ -1,20 +0,0 @@ -import numpy -import pymolfile as pym - -sfname="../test/DPDP.pdb" -cfname="../test/DPDP.nc" - -#sfname="../test/ala3.pdb" -#sfname="../test/ala3.psf" -#cfname="../test/ala3.dcd" - -#sfname="../test/md.gro" -#cfname="../test/md.trr" -#cfname="../test/md.xtc" - -#sfname="../test/md_1u19.gro" -#cfname="../test/md_1u19.xtc" - -molfile = pym.OpenMolfile(sfname) -print(molfile) - diff --git a/pymolfile/test_libpymolfile.py b/pymolfile/test_libpymolfile.py index 59d978e27129152aa349c63f7f60354467f772c1..a509ef39b8dd2d91171f1cd1c4389330123337e1 100644 --- a/pymolfile/test_libpymolfile.py +++ b/pymolfile/test_libpymolfile.py @@ -9,22 +9,22 @@ for i in range(numlist): testplugin = pym.molfile_plugin_info(mylist, i) print(i, testplugin) -splugin = pym.get_plugin(mylist, 99) #pdb +#splugin = pym.get_plugin(mylist, 99) #pdb #cplugin = pym.get_plugin(mylist, 83) #trr #cplugin = pym.get_plugin(mylist, 85) #xtc -#splugin = pym.get_plugin(mylist, 105) #psf +splugin = pym.get_plugin(mylist, 105) #psf #splugin = pym.get_plugin(mylist, 81) #gro -#cplugin = pym.get_plugin(mylist, 69) #dcd -cplugin = pym.get_plugin(mylist, 126) #nc +cplugin = pym.get_plugin(mylist, 69) #dcd +#cplugin = pym.get_plugin(mylist, 126) #nc print(splugin) print(cplugin) natoms=0 -sfname="../test/DPDP.pdb" -cfname="../test/DPDP.nc" +#sfname="../test/DPDP.pdb" +#cfname="../test/DPDP.nc" #sfname="../test/ala3.pdb" -#sfname="../test/ala3.psf" -#cfname="../test/ala3.dcd" +sfname="../test/ala3.psf" +cfname="../test/ala3.dcd" #sfname="../test/md.gro" #cfname="../test/md.trr" @@ -33,13 +33,13 @@ cfname="../test/DPDP.nc" #sfname="../test/md_1u19.gro" #cfname="../test/md_1u19.xtc" -sftype="pdb" +#sftype="pdb" #cftype="trr" #cftype="xtc" -#sftype="psf" +sftype="psf" #sftype="gro" -#cftype="dcd" -cftype="nc" +cftype="dcd" +#cftype="nc" print("Structure plugin:") spluginhandle = pym.open_file_read(splugin, sfname, sftype, natoms) diff --git a/test.py b/test.py new file mode 100644 index 0000000000000000000000000000000000000000..18a33d08a980c431750cb27586dba33fd8cc117d --- /dev/null +++ b/test.py @@ -0,0 +1,44 @@ +import numpy +from pymolfile import pymolfile as pym + +#sfname="./test/DPDP.pdb" +#cfname="./test/DPDP.nc" + +#sfname="./test/ala3.pdb" +sfname="./test/ala3.psf" +cfname="./test/ala3.dcd" + +#sfname="./test/md.gro" +#cfname="./test/md.trr" +#cfname="./test/md.xtc" + +#sfname="./test/md_1u19.gro" +#cfname="./test/md_1u19.xtc" + +print("Reading topology") +moltopo = pym.OpenMolfile(sfname) +if moltopo.topology is not None: + if moltopo.topology.structure is not None: + print(moltopo.topology.structure) + if moltopo.topology.bonds is not None: + print(moltopo.topology.bonds) + if moltopo.topology.angles is not None: + print(moltopo.topology.angles) + +if True: + print("Reading trajectory") + moltraj = pym.OpenMolfile(cfname, topology=moltopo) + print(moltraj) + print(moltraj.trajectory) + + if moltraj.trajectory is not None: + step=0 + while True: + positions = moltraj.trajectory.iread() + if positions is not None: + print("STEP:",step) + print(positions) + step += 1 + else: + break +