diff --git a/pymolfile/] b/pymolfile/] deleted file mode 100644 index 3667a47ab4607d1e5a9a3d67121514c96b30af25..0000000000000000000000000000000000000000 --- a/pymolfile/] +++ /dev/null @@ -1,254 +0,0 @@ - -from __future__ import absolute_import -from __future__ import print_function - -import os -import re -import sys -import numpy as np -import warnings - -if sys.version_info > (3,): - long = int - -try: - from .molfile import libpymolfile -except ImportError: - warnings.warn("libpymolfile package not available, pymolfile does not work without its library!") - - -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. - """ - max_num_plugins = 200 - c_list = libpymolfile.molfile_plugin_list(max_num_plugins) - numlist = libpymolfile.molfile_init() - plugins_list = [libpymolfile.molfile_plugin_info(c_list, i) for i in range(numlist)] - libpymolfile.molfile_finish() - return plugins_list - -def open(file_name_with_path, topology=None, - file_format=None, topology_format=None, - plugin=None, topology_plugin=None): - """ The main function to read topology and - trajectory files - - Returns: Depends on the file format and arguments: - If structure file is supplied, it returns topology class. - If only trajectory file is supplied, it returns trajectory class - without topology information. (the number of atoms must be known) - If both files are supplied, it returns trajectory class with - topology information. - """ - pass - -def get_dir_base_extension(file_name): - """ Splits directory, file base and file extensions - - Returns: directory without leading '/', - file base name, and file extension without '.' - """ - file_base, file_extension_with_dot = os.path.splitext(os.path.basename(file_name)) - file_extension = file_extension_with_dot.split(".")[-1] - file_dir = os.path.dirname(file_name) - return file_dir, file_base, file_extension - -def get_extension(file_name): - """ Gets file extension of a file - - Returns: file extension without '.' - """ - file_extension_with_dot = os.path.splitext(os.path.basename(file_name))[1] - return file_extension_with_dot.split(".")[-1] - -def get_plugin_with_ext(file_ext): - """ Search molfile plugins list and returns the plugin info - for the first matched extension. - - Returns: Plugin no in the list and the list item (the plugin info tuple) - """ - if not MOLFILE_PLUGINS: - MOLFILE_PLUGINS = plugins() - - if MOLFILE_PLUGINS: - plugin_no = -1 - for plugin_info in MOLFILE_PLUGINS: - plugin_no += 1 - if file_ext == plugin_info[1]: - return (plugin_no, plugin_info) - - return None - -def get_plugin_with_name(plugin_name): - """ Search molfile plugins list and returns the plugin info - for the first matching name in plugin name field. - - Returns: Plugin no in the list and the list item (the plugin info tuple) - """ - if not MOLFILE_PLUGINS: - MOLFILE_PLUGINS = plugins() - - if MOLFILE_PLUGINS: - plugin_no = -1 - for plugin_info in MOLFILE_PLUGINS: - plugin_no += 1 - if plugin_name == plugin_info[2]: - return (plugin_no, plugin_info) - - return None - - -class OpenMolfile(object): - - self.plugin_list = MOLFILE_PLUGINS - self.trajectory = None - self.topology = None - self.smolobject = None - self.cmolobject = None - self.kwords = { - "file_format" : None, - "file_plugin" : None, - "topology" : None, - "topology_format" : None, - "topology_plugin" : None, - "natoms" : None - } - - def __init__(self, file_name, **kwargs): - if kwargs: - for k, v in kwargs.items(): - if k in self.kwords: - self.kwords[k] = v - - if file_name: - if self.kwords["file_format"] is None: - file_dir, file_base, file_ext = get_dir_base_extension(file_name) - if file_ext: - self.kwords["file_format"] = file_ext - else: - self.kwords["file_format"] = file_base - - if self.kwords["file_plugin"] is None: - self.kwords["file_plugin"] = "auto" - - if "auto" in self.kwords["file_plugin"]: - plugin_item = get_plugin_with_ext(self.kwords["file_format"]) - self.kwords["file_plugin"] = - - if self.kwords["file_plugin"]: - if not MOLFILE_PLUGINS: - MOLFILE_PLUGINS = plugins() - - - - - c_list = libpymolfile.molfile_plugin_list(max_num_plugins) - numlist = libpymolfile.molfile_init() - self.cmolobject = libpymolfile.get_plugin(MOLFILE_PLUGINS, 83) #trr - - - - else: - return None - - - - - - - - - - - -def get_listof_parts( filename, filepath, fileformats ): - pattern = re.escape( filename[1:-4] ) + "\.part[0-9]{4,4}\.(xtc|trr)$" - parts = [] - for f in os.listdir( directory ): - m = re.match( pattern, f ) - if m and os.path.isfile( os.path.join( directory, f ) ): - parts.append( os.path.join( directory, f ) ) - return sorted( parts ) - - -def get_trajectory( file_name ): - ext = os.path.splitext( file_name )[1].lower() - types = { - ".xtc": XtcTrajectory, - ".trr": TrrTrajectory, - ".netcdf": NetcdfTrajectory, - ".nc": NetcdfTrajectory, - ".dcd": DcdTrajectory, - } - if ext in types: - return types[ ext ]( file_name ) - else: - raise Exception( "extension '%s' not supported" % ext ) - -class Topology( object ): - - self.structure = None - self.bonds = None - self.angles = None - - def __init__( self, file_name ): - pass - - - -class Trajectory( object ): - def __init__( self, file_name ): - pass - - def update( self, force=False ): - pass - - def _get_frame( self, index ): - pass - - def get_frame( self, index, atom_indices=None ): - box, coords, time = self._get_frame( int( index ) ) - if atom_indices: - coords = np.concatenate([ - ]) - return { - "coords": coords - "velocities": coords - } - - def get_frame_string( self, index, atom_indices=None ): - frame = self.get_frame( index, atom_indices=atom_indices ) - return ( - ) - - def __del__( self ): - pass - - diff --git a/pymolfile/__init__.py b/pymolfile/__init__.py index 62fae02b838f8df5482f3f643ceacdf3ddc3a1ee..0e4f244a9fecb0fa27699383764a33f9bd9b22cf 100644 --- a/pymolfile/__init__.py +++ b/pymolfile/__init__.py @@ -5,5 +5,7 @@ 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/__pycache__/pymolfile.cpython-36.pyc b/pymolfile/__pycache__/pymolfile.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e19a06a51bf6003652eb8cfb19bc4b9a0a26c52 Binary files /dev/null and b/pymolfile/__pycache__/pymolfile.cpython-36.pyc differ diff --git a/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc b/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc index 09623bd45a3e5dc77246c0a88f466113249b2ab2..bc43e9aae4503301f6e3a92af0ca934b25c01e4b 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 e72261324ff900aeaa9dbe33df442ea998472857..fdfdcc550fe4a6a7dba7e86c38a4b9974d2da208 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 c62a68708ff5b2653918f126239f92fabd92fefb..a0b3a8c49d4db6f95fffdd9921c301f5d99e2fdd 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.sh b/pymolfile/molfile/compile.sh index 100753d1b510ba934722e4328b09af79d11eb990..b04a1dd781331d66c0b4a562a414fcfecdd11ea2 100644 --- a/pymolfile/molfile/compile.sh +++ b/pymolfile/molfile/compile.sh @@ -1,4 +1,6 @@ +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 \ diff --git a/pymolfile/molfile/libpymolfile.i b/pymolfile/molfile/libpymolfile.i index 263d94239065b3e5ea31358fbbff2d9961ec0d35..4531072d9c1840d9e5080f4ec2a81303a30575ea 100644 --- a/pymolfile/molfile/libpymolfile.i +++ b/pymolfile/molfile/libpymolfile.i @@ -30,9 +30,6 @@ #include <ctype.h> #include <string.h> #include <inttypes.h> -#include "molfile_plugin.h" -#include "libmolfile_plugin.h" -#include "vmdplugin.h" #include "pymolfile.h" %} @@ -57,7 +54,7 @@ import_array(); initialize and finalize molfile plugins */ %feature("autodoc", "0") molfile_plugin_list; -extern molfile_plugin_t** molfile_plugin_list(int maxsize); +extern PyObject* molfile_plugin_list(int maxsize); %feature("autodoc", "0") molfile_init; extern int molfile_init(void); @@ -66,16 +63,20 @@ extern int molfile_init(void); extern int molfile_finish(void); %feature("autodoc", "0") get_plugin; -extern molfile_plugin_t* get_plugin(molfile_plugin_t** plugin_list, int plugin_no); +extern PyObject* get_plugin(PyObject* molcapsule, int plug_no); + %feature("autodoc", "0") molfile_plugin_info; +extern PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no); +/* %exception molfile_plugin_info { $action if (PyErr_Occurred()) SWIG_fail; } %inline %{ -PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) { +PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no) { molfile_plugin_t *plugin; + molfile_plugin_t** plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule); int *plugno = &plugin_no; int has_readstructure = 0; int has_readbonds = 0; @@ -87,12 +88,12 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) { int has_writetimestep = 0; int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**); if (plugno==NULL || plugin_no<0){ - PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", pluginNOINIT, plugin_list_size, plugin_no); + PyErr_Format(PyExc_IOError, "Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", plugin_list_size, plugin_no); return 0; } plugin = plugin_list[plugin_no]; if(plugin==NULL || !plugin->open_file_read){ - PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin '%d' is not initialized.", pluginNOINIT, plugin_no); + PyErr_Format(PyExc_IOError, "Error: molfile plugin '%d' is not initialized.", plugin_no); return 0; } if (plugin->read_structure) has_readstructure = 1; @@ -124,6 +125,7 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) { return tuple; } %} +*/ %feature("autodoc", "0") my_open_file_read; @@ -133,11 +135,12 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) { if (PyErr_Occurred()) SWIG_fail; } %inline %{ -PyObject * my_open_file_read(molfile_plugin_t* plugin, char* fname, char* ftype, int natoms) { +PyObject * my_open_file_read(PyObject* molcapsule, char* fname, char* ftype, int natoms) { if (PyType_Ready(&MolObjectType) < 0) return NULL; PyTypeObject *type = &MolObjectType; MolObject *plugin_c; + molfile_plugin_t* plugin = (molfile_plugin_t*) PyMolfileCapsule_AsVoidPtr(molcapsule); plugin_c = (MolObject *)type->tp_alloc(type, 0); plugin_c->plugin = plugin; plugin_c->file_handle = plugin->open_file_read(fname, ftype, &natoms); @@ -159,7 +162,7 @@ PyObject * my_close_file_read(PyObject* molpack) { void* file_handle; int numatoms; MolObject* plugin_handle = (MolObject*) molpack; - plugin = plugin_handle->plugin; + plugin = plugin_handle->plugin; file_handle = plugin_handle->file_handle; numatoms = plugin_handle->natoms; plugin->close_file_read(file_handle); diff --git a/pymolfile/molfile/libpymolfile.py b/pymolfile/molfile/libpymolfile.py index cb5776343d31d4f4d488fc87d9d25dc3ea21901d..a57642aa6cb2eb903f6ce95a5d4ac44f7d63d090 100644 --- a/pymolfile/molfile/libpymolfile.py +++ b/pymolfile/molfile/libpymolfile.py @@ -107,8 +107,8 @@ except __builtin__.Exception: _newclass = 0 -def molfile_plugin_list(maxsize: 'int') -> "molfile_plugin_t **": - """molfile_plugin_list(maxsize) -> molfile_plugin_t **""" +def molfile_plugin_list(maxsize: 'int') -> "PyObject *": + """molfile_plugin_list(maxsize) -> PyObject *""" return _libpymolfile.molfile_plugin_list(maxsize) def molfile_init() -> "int": @@ -119,17 +119,17 @@ def molfile_finish() -> "int": """molfile_finish() -> int""" return _libpymolfile.molfile_finish() -def get_plugin(plugin_list: 'molfile_plugin_t **', plugin_no: 'int') -> "molfile_plugin_t *": - """get_plugin(plugin_list, plugin_no) -> molfile_plugin_t *""" - return _libpymolfile.get_plugin(plugin_list, plugin_no) +def get_plugin(molcapsule: 'PyObject *', plug_no: 'int') -> "PyObject *": + """get_plugin(molcapsule, plug_no) -> PyObject *""" + return _libpymolfile.get_plugin(molcapsule, plug_no) -def molfile_plugin_info(plugin_list: 'molfile_plugin_t **', plugin_no: 'int') -> "PyObject *": - """molfile_plugin_info(plugin_list, plugin_no) -> PyObject *""" - return _libpymolfile.molfile_plugin_info(plugin_list, plugin_no) +def molfile_plugin_info(molcapsule: 'PyObject *', plugin_no: 'int') -> "PyObject *": + """molfile_plugin_info(molcapsule, plugin_no) -> PyObject *""" + return _libpymolfile.molfile_plugin_info(molcapsule, plugin_no) -def open_file_read(plugin: 'molfile_plugin_t *', fname: 'char *', ftype: 'char *', natoms: 'int') -> "PyObject *": - """open_file_read(plugin, fname, ftype, natoms) -> PyObject *""" - return _libpymolfile.open_file_read(plugin, fname, ftype, natoms) +def open_file_read(molcapsule: 'PyObject *', fname: 'char *', ftype: 'char *', natoms: 'int') -> "PyObject *": + """open_file_read(molcapsule, fname, ftype, natoms) -> PyObject *""" + return _libpymolfile.open_file_read(molcapsule, fname, ftype, natoms) def close_file_read(molpack: 'PyObject *') -> "PyObject *": """close_file_read(molpack) -> PyObject *""" diff --git a/pymolfile/molfile/libpymolfile_wrap.cxx b/pymolfile/molfile/libpymolfile_wrap.cxx index e6fbc91446d74b4a71d28b0aaff7f349ea61e78c..533687b00f09f7f7734804817b5a34f0917f375f 100644 --- a/pymolfile/molfile/libpymolfile_wrap.cxx +++ b/pymolfile/molfile/libpymolfile_wrap.cxx @@ -3004,10 +3004,8 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { /* -------- TYPES TABLE (BEGIN) -------- */ #define SWIGTYPE_p_char swig_types[0] -#define SWIGTYPE_p_molfile_plugin_t swig_types[1] -#define SWIGTYPE_p_p_molfile_plugin_t swig_types[2] -static swig_type_info *swig_types[4]; -static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0}; +static swig_type_info *swig_types[2]; +static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -3123,9 +3121,6 @@ namespace swig { #include <ctype.h> #include <string.h> #include <inttypes.h> -#include "molfile_plugin.h" -#include "libmolfile_plugin.h" -#include "vmdplugin.h" #include "pymolfile.h" @@ -3298,62 +3293,12 @@ SWIGINTERNINLINE PyObject* } -PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) { - molfile_plugin_t *plugin; - int *plugno = &plugin_no; - int has_readstructure = 0; - int has_readbonds = 0; - int has_readangles = 0; - int has_writestructure = 0; - int has_writebonds = 0; - int has_writeangles = 0; - int has_readnexttimestep = 0; - int has_writetimestep = 0; - int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**); - if (plugno==NULL || plugin_no<0){ - PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", pluginNOINIT, plugin_list_size, plugin_no); - return 0; - } - plugin = plugin_list[plugin_no]; - if(plugin==NULL || !plugin->open_file_read){ - PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin '%d' is not initialized.", pluginNOINIT, plugin_no); - return 0; - } - if (plugin->read_structure) has_readstructure = 1; - if (plugin->read_bonds) has_readbonds = 1; - if (plugin->read_angles) has_readangles = 1; - if (plugin->read_next_timestep) has_readnexttimestep = 1; - if (plugin->write_structure) has_writestructure = 1; - if (plugin->write_bonds) has_writebonds = 1; - if (plugin->write_angles) has_writeangles = 1; - if (plugin->write_timestep) has_writetimestep = 1; - PyObject *tuple = PyTuple_New(17); - PyTuple_SET_ITEM(tuple, 0, PyString_FromString(plugin->filename_extension)); - PyTuple_SET_ITEM(tuple, 1, PyString_FromString(plugin->name)); - PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((long)has_readstructure)); - PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong((long)has_readbonds)); - PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong((long)has_readangles)); - PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong((long)has_readnexttimestep)); - PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong((long)has_writestructure)); - PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong((long)has_writebonds)); - PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong((long)has_writeangles)); - PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong((long)has_writetimestep)); - PyTuple_SET_ITEM(tuple, 10, PyString_FromString(plugin->prettyname)); - PyTuple_SET_ITEM(tuple, 11, PyString_FromString(plugin->type)); - PyTuple_SET_ITEM(tuple, 12, PyString_FromString(plugin->author)); - PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong((long)plugin->majorv)); - PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong((long)plugin->minorv)); - PyTuple_SET_ITEM(tuple, 15, PyInt_FromLong((long)plugin->abiversion)); - PyTuple_SET_ITEM(tuple, 16, PyInt_FromLong((long)plugin->is_reentrant)); - return tuple; - } - - -PyObject * my_open_file_read(molfile_plugin_t* plugin, char* fname, char* ftype, int natoms) { +PyObject * my_open_file_read(PyObject* molcapsule, char* fname, char* ftype, int natoms) { if (PyType_Ready(&MolObjectType) < 0) return NULL; PyTypeObject *type = &MolObjectType; MolObject *plugin_c; + molfile_plugin_t* plugin = (molfile_plugin_t*) PyMolfileCapsule_AsVoidPtr(molcapsule); plugin_c = (MolObject *)type->tp_alloc(type, 0); plugin_c->plugin = plugin; plugin_c->file_handle = plugin->open_file_read(fname, ftype, &natoms); @@ -3497,7 +3442,7 @@ PyObject * my_close_file_read(PyObject* molpack) { void* file_handle; int numatoms; MolObject* plugin_handle = (MolObject*) molpack; - plugin = plugin_handle->plugin; + plugin = plugin_handle->plugin; file_handle = plugin_handle->file_handle; numatoms = plugin_handle->natoms; plugin->close_file_read(file_handle); @@ -3515,7 +3460,7 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_list(PyObject *SWIGUNUSEDPARM(self), P int val1 ; int ecode1 = 0 ; PyObject * obj0 = 0 ; - molfile_plugin_t **result = 0 ; + PyObject *result = 0 ; if (!PyArg_ParseTuple(args,(char *)"O:molfile_plugin_list",&obj0)) SWIG_fail; ecode1 = SWIG_AsVal_int(obj0, &val1); @@ -3523,8 +3468,8 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_list(PyObject *SWIGUNUSEDPARM(self), P SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "molfile_plugin_list" "', argument " "1"" of type '" "int""'"); } arg1 = static_cast< int >(val1); - result = (molfile_plugin_t **)molfile_plugin_list(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_molfile_plugin_t, 0 | 0 ); + result = (PyObject *)molfile_plugin_list(arg1); + resultobj = result; return resultobj; fail: return NULL; @@ -3559,29 +3504,23 @@ fail: SWIGINTERN PyObject *_wrap_get_plugin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; - molfile_plugin_t **arg1 = (molfile_plugin_t **) 0 ; + PyObject *arg1 = (PyObject *) 0 ; int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; int val2 ; int ecode2 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; - molfile_plugin_t *result = 0 ; + PyObject *result = 0 ; if (!PyArg_ParseTuple(args,(char *)"OO:get_plugin",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_molfile_plugin_t, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_plugin" "', argument " "1"" of type '" "molfile_plugin_t **""'"); - } - arg1 = reinterpret_cast< molfile_plugin_t ** >(argp1); + arg1 = obj0; ecode2 = SWIG_AsVal_int(obj1, &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "get_plugin" "', argument " "2"" of type '" "int""'"); } arg2 = static_cast< int >(val2); - result = (molfile_plugin_t *)get_plugin(arg1,arg2); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_molfile_plugin_t, 0 | 0 ); + result = (PyObject *)get_plugin(arg1,arg2); + resultobj = result; return resultobj; fail: return NULL; @@ -3590,10 +3529,8 @@ fail: SWIGINTERN PyObject *_wrap_molfile_plugin_info(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; - molfile_plugin_t **arg1 = (molfile_plugin_t **) 0 ; + PyObject *arg1 = (PyObject *) 0 ; int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; int val2 ; int ecode2 = 0 ; PyObject * obj0 = 0 ; @@ -3601,20 +3538,13 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_info(PyObject *SWIGUNUSEDPARM(self), P PyObject *result = 0 ; if (!PyArg_ParseTuple(args,(char *)"OO:molfile_plugin_info",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_molfile_plugin_t, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "molfile_plugin_info" "', argument " "1"" of type '" "molfile_plugin_t **""'"); - } - arg1 = reinterpret_cast< molfile_plugin_t ** >(argp1); + arg1 = obj0; ecode2 = SWIG_AsVal_int(obj1, &val2); if (!SWIG_IsOK(ecode2)) { SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "molfile_plugin_info" "', argument " "2"" of type '" "int""'"); } arg2 = static_cast< int >(val2); - { - result = (PyObject *)molfile_plugin_info(arg1,arg2); - if (PyErr_Occurred()) SWIG_fail; - } + result = (PyObject *)molfile_plugin_info(arg1,arg2); resultobj = result; return resultobj; fail: @@ -3624,12 +3554,10 @@ fail: SWIGINTERN PyObject *_wrap_open_file_read(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; - molfile_plugin_t *arg1 = (molfile_plugin_t *) 0 ; + PyObject *arg1 = (PyObject *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; int arg4 ; - void *argp1 = 0 ; - int res1 = 0 ; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3645,11 +3573,7 @@ SWIGINTERN PyObject *_wrap_open_file_read(PyObject *SWIGUNUSEDPARM(self), PyObje PyObject *result = 0 ; if (!PyArg_ParseTuple(args,(char *)"OOOO:open_file_read",&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_molfile_plugin_t, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "open_file_read" "', argument " "1"" of type '" "molfile_plugin_t *""'"); - } - arg1 = reinterpret_cast< molfile_plugin_t * >(argp1); + arg1 = obj0; res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_file_read" "', argument " "2"" of type '" "char *""'"); @@ -3806,12 +3730,12 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL}, - { (char *)"molfile_plugin_list", _wrap_molfile_plugin_list, METH_VARARGS, (char *)"molfile_plugin_list(maxsize) -> molfile_plugin_t **"}, + { (char *)"molfile_plugin_list", _wrap_molfile_plugin_list, METH_VARARGS, (char *)"molfile_plugin_list(maxsize) -> PyObject *"}, { (char *)"molfile_init", _wrap_molfile_init, METH_VARARGS, (char *)"molfile_init() -> int"}, { (char *)"molfile_finish", _wrap_molfile_finish, METH_VARARGS, (char *)"molfile_finish() -> int"}, - { (char *)"get_plugin", _wrap_get_plugin, METH_VARARGS, (char *)"get_plugin(plugin_list, plugin_no) -> molfile_plugin_t *"}, - { (char *)"molfile_plugin_info", _wrap_molfile_plugin_info, METH_VARARGS, (char *)"molfile_plugin_info(plugin_list, plugin_no) -> PyObject *"}, - { (char *)"open_file_read", _wrap_open_file_read, METH_VARARGS, (char *)"open_file_read(plugin, fname, ftype, natoms) -> PyObject *"}, + { (char *)"get_plugin", _wrap_get_plugin, METH_VARARGS, (char *)"get_plugin(molcapsule, plug_no) -> PyObject *"}, + { (char *)"molfile_plugin_info", _wrap_molfile_plugin_info, METH_VARARGS, (char *)"molfile_plugin_info(molcapsule, plugin_no) -> PyObject *"}, + { (char *)"open_file_read", _wrap_open_file_read, METH_VARARGS, (char *)"open_file_read(molcapsule, fname, ftype, natoms) -> PyObject *"}, { (char *)"close_file_read", _wrap_close_file_read, METH_VARARGS, (char *)"close_file_read(molpack) -> PyObject *"}, { (char *)"read_fill_structure", _wrap_read_fill_structure, METH_VARARGS, (char *)"read_fill_structure(molpack, prototype) -> PyObject *"}, { (char *)"read_fill_bonds", _wrap_read_fill_bonds, METH_VARARGS, (char *)"read_fill_bonds(molpack) -> PyObject *"}, @@ -3826,23 +3750,15 @@ static PyMethodDef SwigMethods[] = { /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_molfile_plugin_t = {"_p_molfile_plugin_t", "molfile_plugin_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_molfile_plugin_t = {"_p_p_molfile_plugin_t", "molfile_plugin_t **", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_char, - &_swigt__p_molfile_plugin_t, - &_swigt__p_p_molfile_plugin_t, }; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_molfile_plugin_t[] = { {&_swigt__p_molfile_plugin_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_molfile_plugin_t[] = { {&_swigt__p_p_molfile_plugin_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { _swigc__p_char, - _swigc__p_molfile_plugin_t, - _swigc__p_p_molfile_plugin_t, }; diff --git a/pymolfile/molfile/pymolfile.c b/pymolfile/molfile/pymolfile.c index f334813e74554d4d367eee2e4b249ba1fb9fd94b..fa2f689ce0c327c9cede5e774b51ebbf6d76e27e 100644 --- a/pymolfile/molfile/pymolfile.c +++ b/pymolfile/molfile/pymolfile.c @@ -1,16 +1,14 @@ /* Hey emacs this is -*- C -*- and this is my editor vim. * - * molfile.c : C and Fortran interfaces for molfile_plugins + * pymolfile.c : C and Python interfaces for molfile_plugins * Copyright (c) Berk Onat <b.onat@warwick.ac.uk> 2017 * - * This program is under BSD LICENSE + * This program is under UIUC Open Source License please see LICENSE file */ /* * The code is written following the plugin test - * context of f77_molfile.c by Axel Kohlmeyer and - * in molfile_plugin/src/f77 and catdcd.c by - * Justin Gullingsrud of VMD plugins. + * context of main.c in molfile_plugin/src/ */ /* Get HAVE_CONFIG_H */ @@ -36,39 +34,44 @@ int numplugins=0; molfile_plugin_t** plugin_list; -/* * * * * * * * * * * * * * * * * * * * * * * - * Helper functions to set and store plugins * - * * * * * * * * * * * * * * * * * * * * * * */ - #if PY_VERSION_HEX >= 0x03000000 -#define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsLong PyLong_AsLong -#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type) #define PyString_FromString PyBytes_FromString -#define PyUString_Check PyUnicode_Check -#define PyUString_GET_SIZE PyUnicode_GET_SIZE -#define PyUString_FromFormat PyUnicode_FromFormat #define PyInt_FromLong PyLong_FromLong -#define PyString_Type PyBytes_Type -#define PyInt_Type PyLong_Type +void del_molfile_plugin_list(PyObject* molcapsule) +{ + plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule); + free(plugin_list); + Py_XDECREF(molcapsule); +} #else -#define PyBytes_FromString PyString_FromString +void* del_molfile_plugin_list(void* molcapsule) +{ + plugin_list = PyMolfileCapsule_AsVoidPtr((PyObject*)molcapsule); + free(plugin_list); + Py_XDECREF(molcapsule); +} #endif +/* * * * * * * * * * * * * * * * * * * * * * * + * Helper functions to set and store plugins * + * * * * * * * * * * * * * * * * * * * * * * */ -#define NPY_NEXT_ALIGNED_OFFSET(offset, alignment) \ - (((offset) + (alignment) - 1) & (-(alignment))) - -molfile_plugin_t* get_plugin(molfile_plugin_t** plug_list, int plug_no) +PyObject* get_plugin(PyObject* molcapsule, int plug_no) { molfile_plugin_t* plugin; + molfile_plugin_t** plug_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule); if(plug_no < 0){ plugin = NULL; } else { - plugin = plug_list[plug_no]; + if(plug_list != NULL){ + plugin = plug_list[plug_no]; + } else { + plugin = NULL; + } } - return plugin; + return PyMolfileCapsule_FromVoidPtr((void *)plugin, NULL); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -99,13 +102,13 @@ static int molfile_register(void*, vmdplugin_t *plugin) { return VMDPLUGIN_SUCCESS; } -molfile_plugin_t** molfile_plugin_list(int maxsize) +PyObject* molfile_plugin_list(int maxsize) { if(maxsize < MAXPLUGINS){ maxsize = MAXPLUGINS; } plugin_list = (molfile_plugin_t**) malloc(sizeof(molfile_plugin_t*)*maxsize); - return plugin_list; + return PyMolfileCapsule_FromVoidPtr((void *)plugin_list, del_molfile_plugin_list); } /* register all available plugins and clear handles. */ @@ -132,6 +135,57 @@ int molfile_finish(void) /* Functions in molfile_plugin_t */ +PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no) { + molfile_plugin_t *plugin; + molfile_plugin_t** plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule); + int *plugno = &plugin_no; + int has_readstructure = 0; + int has_readbonds = 0; + int has_readangles = 0; + int has_writestructure = 0; + int has_writebonds = 0; + int has_writeangles = 0; + int has_readnexttimestep = 0; + int has_writetimestep = 0; + int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**); + if (plugno==NULL || plugin_no<0){ + PyErr_Format(PyExc_IOError, "Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", plugin_list_size, plugin_no); + return 0; + } + plugin = plugin_list[plugin_no]; + if(plugin==NULL || !plugin->open_file_read){ + PyErr_Format(PyExc_IOError, "Error: molfile plugin '%d' is not initialized.", plugin_no); + return 0; + } + if (plugin->read_structure) has_readstructure = 1; + if (plugin->read_bonds) has_readbonds = 1; + if (plugin->read_angles) has_readangles = 1; + if (plugin->read_next_timestep) has_readnexttimestep = 1; + if (plugin->write_structure) has_writestructure = 1; + if (plugin->write_bonds) has_writebonds = 1; + if (plugin->write_angles) has_writeangles = 1; + if (plugin->write_timestep) has_writetimestep = 1; + PyObject *tuple = PyTuple_New(17); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString(plugin->filename_extension)); + PyTuple_SET_ITEM(tuple, 1, PyString_FromString(plugin->name)); + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((long)has_readstructure)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong((long)has_readbonds)); + PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong((long)has_readangles)); + PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong((long)has_readnexttimestep)); + PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong((long)has_writestructure)); + PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong((long)has_writebonds)); + PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong((long)has_writeangles)); + PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong((long)has_writetimestep)); + PyTuple_SET_ITEM(tuple, 10, PyString_FromString(plugin->prettyname)); + PyTuple_SET_ITEM(tuple, 11, PyString_FromString(plugin->type)); + PyTuple_SET_ITEM(tuple, 12, PyString_FromString(plugin->author)); + PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong((long)plugin->majorv)); + PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong((long)plugin->minorv)); + PyTuple_SET_ITEM(tuple, 15, PyInt_FromLong((long)plugin->abiversion)); + PyTuple_SET_ITEM(tuple, 16, PyInt_FromLong((long)plugin->is_reentrant)); + return tuple; +} + PyObject* read_fill_structure(PyObject* molpack, PyObject* prototype) { // Py_Initialize(); @@ -146,14 +200,14 @@ PyObject* read_fill_structure(PyObject* molpack, PyObject* prototype) // Access plugin_handle values MolObject* plugin_handle = (MolObject*) molpack; if (plugin_handle->plugin) { - plugin = plugin_handle->plugin; - } else { + plugin = plugin_handle->plugin; + } else { PyErr_Format(PyExc_IOError, "molfile plugin is not active."); return NULL; } if (plugin_handle->file_handle) { file_handle = plugin_handle->file_handle; - } else { + } else { PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle."); return NULL; } @@ -206,8 +260,18 @@ PyObject* read_fill_bonds(PyObject* molpack) PyObject *ret = NULL; // Access plugin_handle values MolObject* plugin_handle = (MolObject*) molpack; - plugin = plugin_handle->plugin; - file_handle = plugin_handle->file_handle; + if (plugin_handle->plugin) { + plugin = plugin_handle->plugin; + } else { + PyErr_Format(PyExc_IOError, "molfile plugin is not active."); + return NULL; + } + if (plugin_handle->file_handle) { + file_handle = plugin_handle->file_handle; + } else { + PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle."); + return NULL; + } numatoms = plugin_handle->natoms; if (plugin->read_bonds) { int nbonds, *from, *to, *bondtype, nbondtypes; @@ -290,8 +354,18 @@ PyObject* read_fill_angles(PyObject* molpack) PyObject *ret = NULL; // Access plugin_handle values MolObject* plugin_handle = (MolObject*) molpack; - plugin = plugin_handle->plugin; - file_handle = plugin_handle->file_handle; + if (plugin_handle->plugin) { + plugin = plugin_handle->plugin; + } else { + PyErr_Format(PyExc_IOError, "molfile plugin is not active."); + return NULL; + } + if (plugin_handle->file_handle) { + file_handle = plugin_handle->file_handle; + } else { + PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle."); + return NULL; + } numatoms = plugin_handle->natoms; // Check if there is read_angles support in this plugin if (plugin->read_angles) { @@ -476,16 +550,16 @@ PyObject* read_fill_next_timestep(PyObject* molpack) // Access plugin_handle values MolObject* plugin_handle = (MolObject*) molpack; if (plugin_handle->plugin) { - plugin = plugin_handle->plugin; - } else { + plugin = plugin_handle->plugin; + } else { PyErr_Format(PyExc_IOError, "molfile plugin is not active."); - return NULL; + return NULL; } if (plugin_handle->file_handle) { file_handle = plugin_handle->file_handle; - } else { + } else { PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle."); - return NULL; + return NULL; } if (plugin_handle->natoms) { numatoms = plugin_handle->natoms; @@ -597,14 +671,14 @@ PyObject* is_plugin_same(PyObject* molpack_a, PyObject* molpack_b) MolObject* plugin_handle_a = (MolObject*) molpack_a; MolObject* plugin_handle_b = (MolObject*) molpack_b; if (plugin_handle_a->plugin) { - plugin_a = plugin_handle_a->plugin; - } else { + plugin_a = plugin_handle_a->plugin; + } else { PyErr_Format(PyExc_IOError, "Arg 1 of the molfile plugin is not active."); - return NULL; + return NULL; } if (plugin_handle_b->plugin) { - plugin_b = plugin_handle_b->plugin; - } else { + plugin_b = plugin_handle_b->plugin; + } else { PyErr_Format(PyExc_IOError, "Arg 2 of the molfile plugin is not active."); return NULL; } @@ -619,18 +693,18 @@ PyObject* is_filehandle_same(PyObject* molpack_a, PyObject* molpack_b) { MolObject* plugin_handle_a = (MolObject*) molpack_a; MolObject* plugin_handle_b = (MolObject*) molpack_b; - void* file_handle_a; - void* file_handle_b; + void* file_handle_a; + void* file_handle_b; if (plugin_handle_a->file_handle) { - file_handle_a = plugin_handle_a->file_handle; - } else { + file_handle_a = plugin_handle_a->file_handle; + } else { PyErr_Format(PyExc_IOError, "no file handle in arg 1 of molfile plugin."); return NULL; } if (plugin_handle_b->file_handle) { - file_handle_b = plugin_handle_b->file_handle; - } else { - PyErr_Format(PyExc_IOError, "no file handle in arg 1 of molfile plugin."); + file_handle_b = plugin_handle_b->file_handle; + } else { + PyErr_Format(PyExc_IOError, "no file handle in arg 2 of molfile plugin."); return NULL; } if(file_handle_a == file_handle_b){ diff --git a/pymolfile/molfile/pymolfile.h b/pymolfile/molfile/pymolfile.h index 98dbf324bdd1fbc5f74048b68cac8007561eedc7..94a0b42d5dcb259684cb942600e482c97e5ed797 100644 --- a/pymolfile/molfile/pymolfile.h +++ b/pymolfile/molfile/pymolfile.h @@ -31,9 +31,6 @@ extern "C" #include <numpy/arrayobject.h> -//enum { pluginOK, pluginNOINIT, pluginCLOSE, pluginNOMEM, -// pluginENDOFFILE, pluginFILENOTFOUND, pluginFORMATERROR }; - #ifndef MAXPLUGINS #define MAXPLUGINS 200 #endif @@ -46,6 +43,55 @@ struct MolObject { MolObject(void) {} }; +static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj); +static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*data)(PyObject *)); +void del_molfile_plugin_list(PyObject* molcapsule); + +#if PY_VERSION_HEX >= 0x03000000 +#define PyInt_AsSsize_t PyLong_AsSsize_t +//#define PyInt_AsLong PyLong_AsLong +#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type) +//#define PyString_FromString PyBytes_FromString +#define PyUString_Check PyUnicode_Check +#define PyUString_GET_SIZE PyUnicode_GET_SIZE +#define PyUString_FromFormat PyUnicode_FromFormat +//#define PyInt_FromLong PyLong_FromLong +#define PyString_Type PyBytes_Type +#define PyInt_Type PyLong_Type + +static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj) +{ + void *ret = PyCapsule_GetPointer(obj, NULL); + if (ret == NULL) { + PyErr_Clear(); + } + return ret; +} + +static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*destr)(PyObject *)) +{ + PyObject *ret = PyCapsule_New(ptr, NULL, destr); + if (ret == NULL) { + PyErr_Clear(); + } + return ret; +} + +#else +#define PyBytes_FromString PyString_FromString + +static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj) +{ + return PyCObject_AsVoidPtr(obj); +} + +static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*destr)(void *)) +{ + return PyCObject_FromVoidPtr(ptr, destr); +} + +#endif + static void MolObject_dealloc(MolObject* self) { Py_XDECREF(self->plugin); @@ -184,16 +230,15 @@ static PyTypeObject MolObjectType = { MolObject_new, /* tp_new */ }; +PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no); PyObject * read_fill_structure(PyObject* molpack, PyObject* prototype); PyObject * read_fill_bonds(PyObject* molpack); PyObject * read_fill_angles(PyObject* molpack); PyObject * read_fill_next_timestep(PyObject* molpack); PyObject * is_plugin_same(PyObject* molpack_a, PyObject* molpack_b); PyObject * is_filehandle_same(PyObject* molpack_a, PyObject* molpack_b); - -molfile_plugin_t* get_plugin(molfile_plugin_t** plug_list, int plug_no); - -molfile_plugin_t** molfile_plugin_list(int maxsize); +PyObject * get_plugin(PyObject* molcapsule, int plug_no); +PyObject * molfile_plugin_list(int maxsize); int molfile_init(void); diff --git a/pymolfile/pymolfile.py b/pymolfile/pymolfile.py index 8902abaa5629d35f9bad7c4d2cb5f5d65a955243..b96887b61467d291b7a59818c779864098ea0ce0 100644 --- a/pymolfile/pymolfile.py +++ b/pymolfile/pymolfile.py @@ -47,28 +47,11 @@ def plugins(): capabilities of each molfile plugin. The information is extracted from molfile_plugin_t. """ - max_num_plugins = 200 - c_list = libpymolfile.molfile_plugin_list(max_num_plugins) numlist = libpymolfile.molfile_init() - plugins_list = [libpymolfile.molfile_plugin_info(c_list, i) for i in range(numlist)] + plugins_list = [libpymolfile.molfile_plugin_info(C_MOLFILE_PLUGINS, i) for i in range(numlist)] libpymolfile.molfile_finish() return plugins_list -def open(file_name_with_path, topology=None, - file_format=None, topology_format=None, - plugin=None, topology_plugin=None): - """ The main function to read topology and - trajectory files - - Returns: Depends on the file format and arguments: - If structure file is supplied, it returns topology class. - If only trajectory file is supplied, it returns trajectory class - without topology information. (the number of atoms must be known) - If both files are supplied, it returns trajectory class with - topology information. - """ - pass - def get_dir_base_extension(file_name): """ Splits directory, file base and file extensions @@ -115,6 +98,13 @@ def get_plugin_with_ext(file_ext): 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])): + return True + else: + return False + def get_plugin_with_name(plugin_name): """ Search molfile plugins list and returns the plugin info for the first matching name in plugin name field. @@ -135,54 +125,197 @@ def get_plugin_with_name(plugin_name): class Topology( object ): - self.structure = None - self.bonds = None - self.angles = None - def __init__(self): + self.natoms = None + self.structure = None + self.bonds = None + self.angles = None + + def __del__( self ): pass class Trajectory( object ): - self.atoms = None + def __init__(self, file_name, file_format, plugin, natoms): + self.natoms = None + self.atoms = None + self.plugin = None + self.fname = None + self.ftype = None + self.fname = file_name + self.ftype = file_format + self.plugin = plugin + self.natoms = natoms - def __init__(self): - pass - - def get_frame(self, index): - 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) + + step=0 + while True: + try: + x = libpymolfile.read_fill_next_timestep( + pluginhandle) + if x is None: + break + step=step+1 + if x is not None: + self.atoms = x + yield x + except (AttributeError,OSError): + pass + + libpymolfile.close_file_read(pluginhandle) + libpymolfile.molfile_finish() + +# def read_frame(self, index_no): +# 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) +# libpymolfile.molfile_finish() + +# def read(self, index_list, 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) +# libpymolfile.molfile_finish() - def read(self, index, chunk=None): - - def __del__(self): + def __del__( self ): pass class Molfile(object): - self.plugin_list = MOLFILE_PLUGINS - self.trajectory = None - self.topology = None - self.fplugin = None - self.tplugin = None - self.fmolobject = None - self.tmolobject = None - self.kwords = { - "file_format" : None, - "file_plugin" : None, - "topology" : None, - "topology_format" : None, - "topology_plugin" : None, - "natoms" : None - } - def __init__(self, file_name, **kwargs): - pass + 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 read_topology(self, file_name, file_format, plugin): + """ Reads structure, bonds, angles, dihedrals, impropers and + additional informations through molfile_plugin if the + data is available + + The topology data in pymolfile is a list of tuples that include + the following fields: + (name, type, resname, resid, segid, chain, altloc, insertion, + occupancy, bfactor, mass, charge, radius, atomicnumber) + + The data types are as follows in the tuple: + s = string, i = integer, f = float + (s, s, s, i, s, s, s, s, f, f, f, f, f, i) + + Returns: Topology class if at least one of the topology + data is available. If non of the data is accessible, + function returns None + """ + topo = 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 + #if 0 && vmdplugin_ABIVERSION > 17 + # /* The new PDB file formats allows for much larger structures, */ + # /* which can therefore require longer chain ID strings. The */ + # /* new PDBx/mmCIF file formats do not have length limits on */ + # /* fields, so PDB chains could be arbitrarily long strings */ + # /* in such files. At present, we know we need at least 3-char */ + # /* chains for existing PDBx/mmCIF files. */ + # char chain[4]; /**< required chain name, or "" */ + #else + # char chain[2]; /**< required chain name, or "" */ + #endif + # + # Change 'chain', 'S4' to S2 for PDB + # + if 'pdb' in file_format: + 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: + return topo + else: + return None + class OpenMolfile(Molfile): + """ The main class/function to read topology and + trajectory files + + Returns: Depends on the file format and arguments: + If structure file is supplied, it returns topology class. + If only trajectory file is supplied, it returns trajectory class + without topology information. (the number of atoms must be known) + If both files are supplied, it returns trajectory class with + topology information. + """ def __init__(self, file_name, **kwargs): if kwargs: @@ -206,6 +339,8 @@ class OpenMolfile(Molfile): if plugin_item: self.fplugin = plugin_item self.kwords["file_plugin"] = plugin_item[2][2] + else: + self.kwords["file_plugin"] = None if self.kwords["file_plugin"]: # Check if file_plugin reads structure info @@ -214,34 +349,78 @@ class OpenMolfile(Molfile): # Topology may be read with the plugin. # This will override topology information # if a 'topology' is supplied in keywords. - else: + 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.kwords["file_format"], + self.smolplugin) + libpymolfile.molfile_finish() + + if self.fplugin[2][3] == 0: # Topology can not be read with plugin from # the file. If 'topology' is not set but 'natoms' - # is only the trajectory will be available. - - - - - - - - c_list = libpymolfile.molfile_plugin_list(max_num_plugins) - numlist = libpymolfile.molfile_init() - self.cmolobject = libpymolfile.get_plugin(MOLFILE_PLUGINS, 83) #trr - - - - return self - else: - return None - - - - - - - - - + # is set, only the trajectory will be available. + if self.kwords["topology"] is not None: + if isinstance(self.kwords["topology"], Molfile): + self.topology = self.kwords["topology"].topology + elif isinstance(elf.kwords["topology"], Topology): + self.topology = self.kwords["topology"] + else: + if self.kwords["topology_format"] is None: + topo_file_dir, topo_file_base, topo_file_ext = get_dir_base_extension( + self.kwords["topology"]) + if topo_file_ext: + self.kwords["topology_format"] = topo_file_ext + else: + self.kwords["topology_format"] = topo_file_base + + if self.kwords["topology_plugin"] is None: + self.kwords["topology_plugin"] = "auto" + + if "auto" in self.kwords["topology_plugin"]: + 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] + 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: + # 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.topology = read_topology(file_name, + self.kwords["topology_format"], + self.smolplugin) + 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)) + + if(self.fplugin[2][6] == 1): + num_atoms = 0 + if self.topology: + num_atoms = self.topology.natoms + elif natoms is not None: + num_atoms = natoms + # Trajectory can be read if num_atoms is set + if num_atoms>0: + self.trajectory = Trajectory(file_name, + self.kwords["file_format"], + self.kwords["file_plugin"], + num_atoms) + else: + print("Pymolfile can not determine the {0} file format " + + "of the file {1}" % (self.kwords["file_format"], + file_base + "." + file_ext)) diff --git a/pymolfile/test.py b/pymolfile/test.py index c081c3845eb113a85432766127def8062bf51bc6..35fb3d9cfb303bc5ded90f2ca018938d5d82bc26 100644 --- a/pymolfile/test.py +++ b/pymolfile/test.py @@ -1,131 +1,20 @@ import numpy -import molfile.libpymolfile as pym +import pymolfile as pym -mylist = pym.molfile_plugin_list(200) -numlist = pym.molfile_init() -print(numlist) -for i in range(numlist): - testplugin = pym.molfile_plugin_info(mylist, i) - print(i, testplugin) - -#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, 81) #gro -#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/md.gro" -cfname="../test/md.trr" +#sfname="../test/md.gro" +#cfname="../test/md.trr" #cfname="../test/md.xtc" #sfname="../test/md_1u19.gro" #cfname="../test/md_1u19.xtc" -#sftype="pdb" -cftype="trr" -#cftype="xtc" -#sftype="psf" -sftype="gro" -#cftype="dcd" -#cftype="nc" - -print("Structure plugin:") -spluginhandle = pym.open_file_read(splugin, sfname, sftype, natoms) -print("Coordinate plugin:") -cpluginhandle = pym.open_file_read(cplugin, cfname, cftype, natoms) -print(cpluginhandle) -print(cpluginhandle.natoms) -print(spluginhandle) -print(spluginhandle.natoms) -if cpluginhandle.natoms != spluginhandle.natoms: - print("Number of atoms do not match in structure and coordinate files.") - - -if pym.is_plugin_same(spluginhandle, cpluginhandle): - pym.close_file_read(cpluginhandle) - cpluginhandle = spluginhandle - -#if 0 && vmdplugin_ABIVERSION > 17 -# /* The new PDB file formats allows for much larger structures, */ -# /* which can therefore require longer chain ID strings. The */ -# /* new PDBx/mmCIF file formats do not have length limits on */ -# /* fields, so PDB chains could be arbitrarily long strings */ -# /* in such files. At present, we know we need at least 3-char */ -# /* chains for existing PDBx/mmCIF files. */ -# char chain[4]; /**< required chain name, or "" */ -#else -# char chain[2]; /**< required chain name, or "" */ -#endif -# Change 'chain', 'S4' to S2 for PDB -if 'pdb' in [sftype, cftype]: - print("file chain is set to S2") - chain_size = 'S2' -else: - chain_size = 'S4' -x = 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') - ] - ) -y = pym.read_fill_structure(spluginhandle, x) -print(y) -if y is not None: - print(len(y)) - -try: - z = pym.read_fill_bonds(spluginhandle) - print(z) - if z is not None: - print(len(z)) -except (AttributeError, SystemError): - pass - -try: - a = pym.read_fill_angles(spluginhandle) - print(a) - if a is not None: - print(len(a)) -except (AttributeError, SystemError): - pass - -if pym.is_plugin_same(spluginhandle, cpluginhandle): - pass -else: - pym.close_file_read(spluginhandle) - -#step=0 -#while True: -# try: -# c = pym.read_fill_next_timestep(cpluginhandle) -# if c is None: -# break -# step=step+1 -# print("Step:",step) -# print(c) -# if c["coords"] is not None: -# print(len(c["coords"])) -# except (AttributeError,OSError): -# pass - -pym.close_file_read(cpluginhandle) -pym.molfile_finish() - +molfile = pym.OpenMolfile(sfname) +print(molfile) diff --git a/pymolfile/test_libpymolfile.py b/pymolfile/test_libpymolfile.py new file mode 100644 index 0000000000000000000000000000000000000000..59d978e27129152aa349c63f7f60354467f772c1 --- /dev/null +++ b/pymolfile/test_libpymolfile.py @@ -0,0 +1,133 @@ +import numpy +import molfile.libpymolfile as pym + +mylist = pym.molfile_plugin_list(200) +print(mylist) +numlist = pym.molfile_init() +print(numlist) +for i in range(numlist): + testplugin = pym.molfile_plugin_info(mylist, i) + print(i, testplugin) + +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, 81) #gro +#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/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" + +sftype="pdb" +#cftype="trr" +#cftype="xtc" +#sftype="psf" +#sftype="gro" +#cftype="dcd" +cftype="nc" + +print("Structure plugin:") +spluginhandle = pym.open_file_read(splugin, sfname, sftype, natoms) +print("Coordinate plugin:") +cpluginhandle = pym.open_file_read(cplugin, cfname, cftype, natoms) +print(cpluginhandle) +print(cpluginhandle.natoms) +print(spluginhandle) +print(spluginhandle.natoms) +if cpluginhandle.natoms != spluginhandle.natoms: + print("Number of atoms do not match in structure and coordinate files.") + + +if pym.is_plugin_same(spluginhandle, cpluginhandle): + pym.close_file_read(cpluginhandle) + cpluginhandle = spluginhandle + +#if 0 && vmdplugin_ABIVERSION > 17 +# /* The new PDB file formats allows for much larger structures, */ +# /* which can therefore require longer chain ID strings. The */ +# /* new PDBx/mmCIF file formats do not have length limits on */ +# /* fields, so PDB chains could be arbitrarily long strings */ +# /* in such files. At present, we know we need at least 3-char */ +# /* chains for existing PDBx/mmCIF files. */ +# char chain[4]; /**< required chain name, or "" */ +#else +# char chain[2]; /**< required chain name, or "" */ +#endif +# Change 'chain', 'S4' to S2 for PDB +if 'pdb' in [sftype, cftype]: + print("file chain is set to S2") + chain_size = 'S2' +else: + chain_size = 'S4' +x = 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') + ] + ) +y = pym.read_fill_structure(spluginhandle, x) +if y is not None: + print(y) + print(len(y)) + +try: + z = pym.read_fill_bonds(spluginhandle) + if z is not None: + print(z) + print(len(z)) +except (AttributeError, SystemError): + pass + +try: + a = pym.read_fill_angles(spluginhandle) + if a is not None: + print(a) + print(len(a)) +except (AttributeError, SystemError): + pass + +if pym.is_plugin_same(spluginhandle, cpluginhandle): + pass +else: + pym.close_file_read(spluginhandle) + +step=0 +while True: +#while False: + try: + c = pym.read_fill_next_timestep(cpluginhandle) + if c is None: + break + step=step+1 + print("Step:",step) + print(c) + if c["coords"] is not None: + print(len(c["coords"])) + except (AttributeError,OSError): + pass + +pym.close_file_read(cpluginhandle) +pym.molfile_finish() + +