/* -*- C -*- (not really, but good for syntax highlighting) */ /* SWIG interface for libpymolfile of VMD molfile_plugins Copyright (c) 2017 Berk Onat Published under UIUC LICENSE swig -c++ -python -outdir . molfile/libpymolfile.i */ %define DOCSTRING " :Author: Berk Onat :Year: 2017 :Licence: UIUC LICENSE " %enddef %module(docstring=DOCSTRING) libpymolfile %{ /* Python SWIG interface to libpymolfile Copyright (c) 2017 Berk Onat Published under BSD LICENSE */ #define SWIG_FILE_WITH_INIT #define __STDC_FORMAT_MACROS #include #include #include #include #include #include "molfile_plugin.h" #include "libmolfile_plugin.h" #include "vmdplugin.h" #include "pymolfile.h" %} %include "numpy.i" %init %{ Py_Initialize(); import_array(); %} /* Wrapping only high-level plugin functions to register VMD plugins and to retrive the data through molfile_plugin interface. Only modifing call signatures. This will help one to access functions without dealing with pointers from python. */ /* plugin status codes for error handling */ enum { pluginOK, pluginNOINIT, pluginCLOSE, pluginNOMEM, pluginENDOFFILE, pluginFILENOTFOUND, pluginFORMATERROR }; /* Definition of molfile_atoms_t from molfile_plugin.h */ %inline %{ /* struct MolAtoms { char name[16]; char type[16]; char resname[8]; int resid; char segid[8]; char chain[2]; char altloc[2]; char insertion[2]; float occupancy; float bfactor; float mass; float charge; float radius; float atomicnumber; float ctnumber; }; void del_plugin_structure(PyObject* pymolfile_atoms){ delete (MolAtoms*)PyCapsule_GetPointer(pymolfile_atoms, "plugin_structure"); } static PyObject* alloc_plugin_structure(PyObject *self, PyObject *args) { return PyCapsule_New((void*)new MolAtoms(), "plugin_structure", del_plugin_structure); } */ void del_plugin(PyObject* pymolfile_plugin){ delete (MolObject*)PyCapsule_GetPointer(pymolfile_plugin, "plugin"); } void del_atoms(PyObject* pymolfile_atoms){ delete (PyObject*)PyCapsule_GetPointer(pymolfile_atoms, "atoms"); } void del_atomname(PyObject* pymolfile_atoms){ delete (PyObject*)PyCapsule_GetPointer(pymolfile_atoms, "atomname"); } static PyObject* alloc_plugin(PyObject *self, PyObject *args) { return PyCapsule_New((void*)new MolObject(), "plugin_handle", del_plugin); } %} /* pymolfile.c initialize and finalize molfile plugins */ %feature("autodoc", "0") molfile_plugin_list; extern molfile_plugin_t** molfile_plugin_list(int maxsize); %feature("autodoc", "0") molfile_init; extern int molfile_init(void); %feature("autodoc", "0") molfile_finish; extern int molfile_finish(void); %feature("autodoc", "0") get_plugin; extern molfile_plugin_t* get_plugin(molfile_plugin_t** plugin_list, int plugin_no); %feature("autodoc", "0") molfile_plugin_info; %exception molfile_plugin_info { $action if (PyErr_Occurred()) SWIG_fail; } %inline %{ 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; } %} %feature("autodoc", "0") my_open_file_read; %rename (open_file_read) my_open_file_read; %exception my_open_file_read { $action if (PyErr_Occurred()) SWIG_fail; } %inline %{ PyObject * my_open_file_read(molfile_plugin_t* plugin, char* fname, char* ftype, int natoms) { if (PyType_Ready(&MolObjectType) < 0) return NULL; PyTypeObject *type = &MolObjectType; /*plugin_handle = PyCapsule_New((void*)new MolObject(), "plugin", del_plugin); */ /*MolObject* plugin_c = new MolObject;*/ MolObject *plugin_c; plugin_c = (MolObject *)type->tp_alloc(type, 0); /*PyObject * plugin_c = MolObject_new(&MolObjectType, args, kwds);*/ plugin_c->plugin = plugin; plugin_c->file_handle = plugin->open_file_read(fname, ftype, &natoms); plugin_c->natoms = natoms; /* PyCapsule_SetPointer(plugin_handle, &plugin_c); */ /* PyObject* plugin_handle = PyCapsule_New((void*)plugin_c, "plugin", del_plugin); */ PyObject* plugin_handle = (PyObject *)plugin_c; /*if(!plugin_handle) printf("Not assigned\n");*/ /*PyObject *tuple = PyTuple_New(2); PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)natoms)); PyTuple_SET_ITEM(tuple, 1, plugin_handle);*/ return plugin_handle; } %} /* %typemap( argout ) ( char **MolfileAtomT_CharArray ) { // The result variable is the return value from // c_ephcom_read_constants, the number of actual values that are // defined for cnames/values. npy_intp dims[] = { result }; PyArray_Dims newshape_location; PyArray_Dims * newshape = &newshape_location; PyObject * status_check; newshape->len = 1; newshape->ptr = dims; // resize array$argnum to actual size needed. // Follow directions at http://www.mail-archive.com/numpy-discussion@scipy.org/msg13013.html status_check = PyArray_Resize( (PyArrayObject *) array$argnum, newshape, 0, NPY_CORDER ); if ( !status_check ) SWIG_fail; Py_DECREF( status_check ); $result = SWIG_Python_AppendOutput( $result, array$argnum ); } %typemap( freearg ) ( char **MolfileAtomT_CharArray ) { free( $1 ); } */ /* #define DIM 3 typedef int imatrix[DIM][DIM]; typedef int ivec[DIM]; typedef float fmatrix[DIM][DIM]; typedef float fvec[DIM]; */ /* Reading from xdr files */ /* %apply (float INPLACE_ARRAY2[ANY][ANY]) {(matrix box)} %apply (int DIM1, int DIM2, float* INPLACE_ARRAY2) {(int natoms, int _DIM, float *x), (int vnatoms, int v_DIM, float *v), (int fnatoms, int f_DIM, float *f)} */ /* %apply (int INPLACE_IARRAY2[ANY][ANY]) {(imatrix intdata)} %apply (float INPLACE_FARRAY2[ANY][ANY]) {(fmatrix floatdata)} %apply (int DIM1, int* INPLACE_IARRAY2) {(int rnatoms, int* MolAtom_resid)} %apply (int DIM1, float* INPLACE_FARRAY2) {(int mnatoms, float* MolAtom_mass), (int anatoms, float* MolAtom_atomicnumber)} */ /* %inline %{ int structure_read(molfile_plugin_t* plugin, void* fhandle, int *options, int* natoms, char** MolAtom_name, int* natoms, char** MolAtom_type, int* natoms, char** MolAtom_resname, int* natoms, int** MolAtom_resid, int* natoms, char** MolAtom_segid, int* natoms, char** MolAtom_chain, int* natoms, char** MolAtom_altloc, int* natoms, char** MolAtom_insertion, int* natoms, float** MolAtom_occupancy, int* natoms, float** MolAtom_bfactor, int* natoms, float** MolAtom_mass, int* natoms, float** MolAtom_charge, int* natoms, float** MolAtom_radius, int* natoms, float** MolAtom_atomicnumber, int* natoms, float** MolAtom_ctnumber) { molfile_atom_t* atoms; atoms = (molfile_atom_t *)calloc(natoms,sizeof(molfile_atom_t)); plugin->read_structure(fhandle, options, atoms); MolAtom_name = (char **)malloc(natoms,sizeof(char*)); MolAtom_type = (char **)malloc(natoms,sizeof(char*)); MolAtom_resname = (char **)malloc(natoms,sizeof(char*)); MolAtom_resid = (int **)malloc(natoms,sizeof(int*)); %} */ /* %inline %{ int structure_read(molfile_plugin_t* plugin, void* fhandle, int *options, int natoms, char** MolAtom_name, int tnatoms, char** MolAtom_type, int rnatoms, int* MolAtom_resid, int mnatoms, float* MolAtom_mass, int anatoms, float* MolAtom_atomicnumber) { int i; molfile_atom_t* atoms; molfile_atom_t atm; atoms = (molfile_atom_t *)calloc(natoms,sizeof(molfile_atom_t)); plugin->read_structure(fhandle, options, atoms); if(atoms == NULL) { free(atoms); return 1; } if(atoms->type == NULL || atoms->name == NULL){ free(atoms); return 1; } MolAtom_name = (char **)malloc(natoms,sizeof(char*)); MolAtom_type = (char **)malloc(natoms,sizeof(char*)); MolAtom_resid = (int *)malloc(natoms,sizeof(int)); MolAtom_mass = (float *)malloc(natoms,sizeof(float)); MolAtom_atomicnumber = (float *)malloc(natoms,sizeof(float)); for (i=0;iplugin; file_handle = plugin_handle->file_handle; numatoms = plugin_handle->natoms; atoms = (molfile_atom_t *)calloc(numatoms,sizeof(molfile_atom_t)); printf("Test1\n"); status = plugin->read_structure(file_handle, &options, atoms); printf("Test2 %d\n",status); if (status!=0){ PyErr_Format(PyExc_IOError, "Error copying molfile_atom_t into Python."); return NULL; } printf("Test3\n"); npy_intp natoms[1] = { numatoms }; PyArrayObject* oresid; int64_t* cresid; int typenum; int nd = 1; npy_intp dims[1] = { numatoms }; */ /*dims[0] = numatoms;*/ /* oresid = (PyArrayObject*) PyArray_SimpleNew(nd, dims, NPY_INT64); npy_intp* n = PyArray_DIMS(oresid); printf("dimensions %ld\n", n[0]); cresid = (int64_t*) PyArray_DATA(oresid); PyObject* npatomresid = NULL; char** MolAtom_name = (char **)malloc(numatoms*sizeof(char*)); char** MolAtom_type = (char **)malloc(numatoms*sizeof(char*)); int64_t* MolAtom_resid = NULL; */ /*int64_t* MolAtom_resid = (int64_t *)malloc(numatoms*sizeof(int64_t));*/ /* float* MolAtom_mass = (float *)malloc(numatoms*sizeof(float)); float* MolAtom_atomicnumber = (float *)malloc(numatoms*sizeof(float)); for (i=0;iresname);*/ /*PyObject* npatomsegid = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, atoms->segid);*/ /*PyObject* npatomchain = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, atoms->chain);*/ /*PyObject* npatomaltloc = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, atoms->altloc);*/ /*PyObject* npatominsert = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, atoms->insertion);*/ /*PyObject* npatomoccup = PyArray_SimpleNewFromData(1, natoms, NPY_FLOAT64, &atoms->occupancy);*/ /*PyObject* npatombfact = PyArray_SimpleNewFromData(1, natoms, NPY_FLOAT64, &atoms->bfactor);*/ /* PyObject* npatommass = PyArray_SimpleNewFromData(1, natoms, NPY_FLOAT64, MolAtom_mass); */ /*PyObject* npatomcharge = PyArray_SimpleNewFromData(1, natoms, NPY_FLOAT64, &atoms->charge);*/ /*PyObject* npatomradius = PyArray_SimpleNewFromData(1, natoms, NPY_FLOAT64, &atoms->radius);*/ /* PyObject* npatomicnumber = PyArray_SimpleNewFromData(1, natoms, NPY_INT64, MolAtom_atomicnumber); */ /*if (npatomname==NULL || npatomtype==NULL || npatomresname==NULL || npatomresid==NULL || npatomsegid==NULL || npatomchain==NULL ) { free(atoms); Py_XDECREF(npatomname); Py_XDECREF(npatomtype); Py_XDECREF(npatomresname); Py_XDECREF(npatomresid); Py_XDECREF(npatomsegid); Py_XDECREF(npatomchain); Py_XDECREF(npatomaltloc); Py_XDECREF(npatominsert); Py_XDECREF(npatomoccup); Py_XDECREF(npatombfact); Py_XDECREF(npatommass); Py_XDECREF(npatomcharge); Py_XDECREF(npatomradius); Py_XDECREF(npatomicnumber); PyErr_Format(PyExc_IOError, "Error copying molfile_atom_t into Python."); return 0; } PyArray_BASE(npatomname) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomtype) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomresname) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomresid) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomsegid) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomchain) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomaltloc) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatominsert) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomoccup) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatombfact) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatommass) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomcharge) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomradius) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatomicnumber) = PyCObject_FromVoidPtr(*atoms, free); PyArray_BASE(npatoms) = PyCObject_FromVoidPtr(atoms, free); PyArray_BASE((PyArrayObject *)npatoms) = PyCapsule_New(atoms, "atoms", del_atoms);*/ /*PyArray_BASE((PyArrayObject *)npatoms); */ /* printf("Test4-2\n"); */ /*PyObject* Py_MolAtom_name = PyCapsule_New((void*)MolAtom_name, "atomname", del_atomname);*/ /*PyObject* Py_MolAtom_name; Py_INCREF(Py_MolAtom_name);*/ /* printf("Test4-3\n"); */ /*PyArray_SetBaseObject((PyArrayObject *)npatomname, Py_MolAtom_name);*/ /*PyArray_SetBaseObject((PyArrayObject *)npatomtype, MolAtom_type); PyArray_SetBaseObject((PyArrayObject *)npatomresid, MolAtom_resid); PyArray_SetBaseObject((PyArrayObject *)npatommass, MolAtom_mass); PyArray_SetBaseObject((PyArrayObject *)npatomicnumber, MolAtom_atomicnumber); */ /* printf("Test5\n"); PyObject *tuple = PyTuple_New(2); PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)natoms)); printf("Test6\n"); PyTuple_SET_ITEM(tuple, 1, npatomname); */ /*PyTuple_SET_ITEM(tuple, 2, npatomtype); PyTuple_SET_ITEM(tuple, 3, npatomresid); PyTuple_SET_ITEM(tuple, 4, npatommass); PyTuple_SET_ITEM(tuple, 5, npatomicnumber); PyObject* vars = PyDict_New(); printf("Test7\n"); PyDict_SetItemString( vars, "name", npatomname ); */ /* printf("Test8\n"); */ /*PyDict_SetItemString( vars, "resid", npatomresid ); */ /*return Py_BuildValue("O", oresid); */ /*return PyArray_FromArray(oresid, PyArray_DESCR(oresid), 0);*/ /* return 0; } %} */ /* python wrappers for functions and structure data in molfile_plugin.h */ /* molfile_atom_t char name[16]; required atom name string char type[16]; required atom type string char resname[8]; required residue name string int resid; required integer residue ID char segid[8]; required segment name string, or "" char chain[2]; required chain name, or "" char altloc[2]; optional PDB alternate location code char insertion[2]; optional PDB insertion code float occupancy; optional occupancy value float bfactor; optional B-factor value float mass; optional mass value float charge; optional charge value float radius; optional radius value int atomicnumber; optional element atomic number int ctnumber; mae ct block, 0-based, including meta */ /* molfile_plugin_t */ /* %feature("autodoc", "0") molfile_open_file_read; %rename (open_file_read) molfile_open_file_read; %exception molfile_open_file_read { $action if (PyErr_Occurred()) SWIG_fail; } %inline %{ PyObject * molfile_open_file_read(molfile_plugin_t* plugin, char *fname, int natoms) { int *plugno = &plugin_no; return plugin; } %} */ /* void *(* open_file_read)(const char *filepath, const char *filetype, int *natoms); void (* close_file_read)(void *); int (*read_structure)(void *, int *optflags, molfile_atom_t *atoms); int (*read_bonds)(void *, int *nbonds, int **from, int **to, float **bondorder, int **bondtype, int *nbondtypes, char ***bondtypename); int (* read_next_timestep)(void *, int natoms, molfile_timestep_t *); void *(* open_file_write)(const char *filepath, const char *filetype, int natoms); int (* write_structure)(void *, int optflags, const molfile_atom_t *atoms); int (* write_timestep)(void *, const molfile_timestep_t *); void (* close_file_write)(void *); int (* read_molecule_metadata)(void *, molfile_metadata_t **metadata); int (* write_bonds)(void *, int nbonds, int *from, int *to, float *bondorder, int *bondtype, int nbondtypes, char **bondtypename); int (* read_angles)(void *handle, int *numangles, int **angles, int **angletypes, int *numangletypes, char ***angletypenames, int *numdihedrals, int **dihedrals, int **dihedraltypes, int *numdihedraltypes, char ***dihedraltypenames, int *numimpropers, int **impropers, int **impropertypes, int *numimpropertypes, char ***impropertypenames, int *numcterms, int **cterms, int *ctermcols, int *ctermrows); int (* write_angles)(void *handle, int numangles, const int *angles, const int *angletypes, int numangletypes, const char **angletypenames, int numdihedrals, const int *dihedrals, const int *dihedraltypes, int numdihedraltypes, const char **dihedraltypenames, int numimpropers, const int *impropers, const int *impropertypes, int numimpropertypes, const char **impropertypenames, int numcterms, const int *cterms, int ctermcols, int ctermrows); int (* read_timestep)(void *, int natoms, molfile_timestep_t *, molfile_qm_metadata_t *, molfile_qm_timestep_t *); int (* read_timestep_metadata)(void *, molfile_timestep_metadata_t *); int (* read_timestep2)(void *, molfile_ssize_t index, molfile_timestep_t *); molfile_ssize_t (* read_times)( void *, molfile_ssize_t start, molfile_ssize_t count, double * times ); int (* cons_fputs)(const int, const char*); */ /* molfile_timestep_t float *coords; coordinates of all atoms, arranged xyzxyzxyz float *velocities; space for velocities of all atoms; same layout float A, B, C, alpha, beta, gamma; double physical_time; physical time point associated with this frame double total_energy; double potential_energy; double kinetic_energy; double extended_energy; double force_energy; double total_pressure; */ /* molfile_timestep_metadata_t unsigned int count; total # timesteps; -1 if unknown unsigned int avg_bytes_per_timestep; bytes per timestep int has_velocities; if timesteps have velocities */