Changed C API Numpy library to directly access molfile structure data
pymolfile/molfile/1
0 → 100644
No preview for this file type
No preview for this file type
File added
/* -*- C -*- (not really, but good for syntax highlighting) */ | ||
/* SWIG interface for libpymolfile of VMD molfile_plugins | ||
Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk> | ||
Published under UIUC LICENSE | ||
swig -c++ -python -outdir . molfile/libpymolfile.i | ||
*/ | ||
%define DOCSTRING | ||
" | ||
:Author: Berk Onat <b.onat@warwick.ac.uk> | ||
:Year: 2017 | ||
:Licence: UIUC LICENSE | ||
" | ||
%enddef | ||
%module(docstring=DOCSTRING) libpymolfile | ||
%{ | ||
/* Python SWIG interface to libpymolfile | ||
Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk> | ||
Published under BSD LICENSE | ||
*/ | ||
#define SWIG_FILE_WITH_INIT | ||
#define __STDC_FORMAT_MACROS | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <ctype.h> | ||
#include <string.h> | ||
#include <inttypes.h> | ||
#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;i<natoms;i++){ | ||
atm = atoms[i]; | ||
MolAtom_name[i] = atm.name; | ||
MolAtom_type[i] = atm.type; | ||
MolAtom_resid[i] = atm.resid; | ||
MolAtom_mass[i] = atm.mass; | ||
MolAtom_atomicnumber[i] = atm.atomicnumber; | ||
} | ||
return 0; | ||
} | ||
%} | ||
*/ | ||
%feature("autodoc", "0") my_read_structure; | ||
%rename (read_structure) my_read_structure; | ||
extern PyObject * my_read_structure(PyObject* molpack); | ||
%feature("autodoc", "0") get_structure; | ||
extern PyObject * get_structure(PyObject* molpack); | ||
/* | ||
%feature("autodoc", "0") my_read_structure; | ||
%rename (read_structure) my_read_structure; | ||
%exception my_read_structure { | ||
$action | ||
if (PyErr_Occurred()) SWIG_fail; | ||
} | ||
%inline %{ | ||
PyObject * my_read_structure(PyObject* molpack) { | ||
int options = 0; | ||
int i; | ||
molfile_plugin_t* plugin; | ||
void* file_handle; | ||
molfile_atom_t* atoms; | ||
int numatoms, status; | ||
char** atom_names; | ||
char** atom_types; | ||
PyObject *npatoms = NULL; */ | ||
/*MolObject* plugin_handle = (MolObject*)PyCapsule_GetPointer(molpack, "plugin");*/ | ||
/* MolObject* plugin_handle = (MolObject*)molpack; | ||
plugin = plugin_handle->plugin; | ||
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;i<numatoms;i++){ | ||
MolAtom_name[i] = atoms[i].name; | ||
MolAtom_type[i] = atoms[i].type; | ||
cresid[i] = (int64_t) atoms[i].resid; | ||
MolAtom_mass[i] = atoms[i].mass; | ||
MolAtom_atomicnumber[i] = atoms[i].atomicnumber; | ||
} */ | ||
/*Py_DECREF( obj );*/ | ||
/*npy_intp dims[3];*/ /* PyArray_AsCArray is for ndim <= 3 */ | ||
/* PyArray_Descr *descr; | ||
npatoms = PyArray_SimpleNewFromData(1, natoms, NPY_USERDEF, atoms); | ||
printf("Test4 numatoms=%d\n", numatoms); | ||
PyObject* npatomname = NULL; | ||
npatomname = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, MolAtom_name[0]); | ||
PyObject* npatomtype = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, MolAtom_type); */ | ||
/*PyObject* npatomresname = PyArray_SimpleNewFromData(1, natoms, NPY_STRING, atoms->resname);*/ | ||
/*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); | ||
< |