1063 lines
25 KiB
C
1063 lines
25 KiB
C
/*
|
|
A* -------------------------------------------------------------------
|
|
B* This file contains source code for the PyMOL computer program
|
|
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
|
|
D* -------------------------------------------------------------------
|
|
E* It is unlawful to modify or remove this copyright notice.
|
|
F* -------------------------------------------------------------------
|
|
G* Please see the accompanying LICENSE file for further information.
|
|
H* -------------------------------------------------------------------
|
|
I* Additional authors of this source file include:
|
|
-*
|
|
-*
|
|
-*
|
|
Z* -------------------------------------------------------------------
|
|
*/
|
|
#include"os_python.h"
|
|
|
|
#include"os_std.h"
|
|
#include"os_memory.h"
|
|
|
|
#include"const.h"
|
|
#include"champ.h"
|
|
#include"list.h"
|
|
#include"vla.h"
|
|
|
|
/*static PyObject *RetNone()
|
|
{
|
|
return(Py_BuildValue("(iO)",0,Py_None));
|
|
}
|
|
*/
|
|
|
|
static PyObject *RetStatus(int ok)
|
|
{
|
|
return(Py_BuildValue("(iO)",!ok,Py_None));
|
|
}
|
|
|
|
static PyObject *RetObj(int ok,PyObject *result)
|
|
{
|
|
PyObject *ret;
|
|
if(result==Py_None) {
|
|
Py_INCREF(result);
|
|
} else if(result==NULL) {
|
|
result=Py_None;
|
|
Py_INCREF(result);
|
|
}
|
|
ret = Py_BuildValue("(iO)",!ok,result);
|
|
Py_DECREF(result);
|
|
return(ret);
|
|
}
|
|
|
|
static PyObject *RetInt(int ok,int result) /* status/integer return */
|
|
{
|
|
return(Py_BuildValue("(ii)",!ok,result));
|
|
}
|
|
|
|
typedef void(*CObjectDestruct)(void*) ;
|
|
|
|
static void ChampCapsuleFree(PyObject * capsule) {
|
|
ChampFree(PyCapsule_GetPointer(capsule, NULL));
|
|
}
|
|
|
|
static PyObject *_new(PyObject *self, PyObject *args)
|
|
{
|
|
void * I = ChampNew();
|
|
return PyCapsule_New(I, NULL, ChampCapsuleFree);
|
|
}
|
|
|
|
static PyObject *_memory_dump(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"O",&O);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampMemoryDump(I);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
static PyObject *insert_pattern_string(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
char *str1;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Os",&O,&str1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
result = ChampSmiToPat(I,str1);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_free(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampPatFree(I,int1);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_orient_bonds(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampOrientBonds(I,int1);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
static PyObject *pattern_detect_chirality(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampDetectChirality(I,int1);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_generalize(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampGeneralize(I,int1);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
static PyObject *pattern_get_cycle(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b;
|
|
int n_atom,n_bond;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
at = I->Atom + pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
PyList_SetItem(l1,a,PyInt_FromLong(at->cycle));
|
|
at = I->Atom + at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bd = I->Bond + pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
PyList_SetItem(l2,b,PyInt_FromLong(bd->cycle));
|
|
bd = I->Bond + bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_get_class(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b;
|
|
int n_atom,n_bond;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
at = I->Atom + pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
PyList_SetItem(l1,a,PyInt_FromLong(at->class));
|
|
at = I->Atom + at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bd = I->Bond + pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
PyList_SetItem(l2,b,PyInt_FromLong(bd->class));
|
|
bd = I->Bond + bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_codes(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai,bi;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b;
|
|
int n_atom,n_bond;
|
|
char code[255],atom[10];
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
|
|
if(at->class&cH_Aliphatic)
|
|
code[0]='A';
|
|
else if(at->class&cH_Aromatic)
|
|
code[0]='R';
|
|
else
|
|
code[0]='P';
|
|
if(at->cycle&(cH_Ring3|cH_Ring4|cH_Ring5|cH_Ring6|cH_Ring7))
|
|
code[1]='C';
|
|
else
|
|
code[1]='X';
|
|
code[2]=0;
|
|
ChampAtomToString(I,ai,atom);
|
|
if(atom[0]>96)
|
|
atom[0]-=32;
|
|
strcat(code,atom);
|
|
PyList_SetItem(l1,a,PyString_FromString(code));
|
|
ai = at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bi = pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
bd = I->Bond + bi;
|
|
if(bd->class&cH_Aliphatic)
|
|
code[0]='A';
|
|
else if(bd->class&cH_Aromatic)
|
|
code[0]='R';
|
|
else
|
|
code[0]='P';
|
|
if(bd->cycle&(cH_Ring3|cH_Ring4|cH_Ring5|cH_Ring6|cH_Ring7))
|
|
code[1]='C';
|
|
else
|
|
code[1]='X';
|
|
|
|
switch(bd->order) {
|
|
case cH_Single: code[2]='-'; break;
|
|
case cH_Double: code[2]='='; break;
|
|
case cH_Triple: code[2]='#'; break;
|
|
}
|
|
code[3]=0;
|
|
|
|
PyList_SetItem(l2,b,PyString_FromString(code));
|
|
bi = bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_get_tags(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai,bi;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2,*l3;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b,c;
|
|
int n_atom,n_bond;
|
|
int bit_mask;
|
|
int bit_no;
|
|
int n_bits;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
|
|
n_bits = 0;
|
|
bit_mask = at->tag;
|
|
while(bit_mask) { /* count bits */
|
|
if(bit_mask&0x1)
|
|
n_bits++;
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
l3 = PyList_New(n_bits);
|
|
bit_no = 0;
|
|
bit_mask = at->tag;
|
|
c=0;
|
|
for(bit_no=0;bit_no<32;bit_no++) {
|
|
if(bit_mask&0x1) {
|
|
PyList_SetItem(l3,c,PyInt_FromLong(bit_no));
|
|
c++;
|
|
}
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
PyList_SetItem(l1,a,l3);
|
|
|
|
ai = at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bi = pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
bd = I->Bond + bi;
|
|
n_bits = 0;
|
|
bit_mask = bd->tag;
|
|
while(bit_mask) { /* count bits */
|
|
if(bit_mask&0x1)
|
|
n_bits++;
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
l3 = PyList_New(n_bits);
|
|
bit_no = 0;
|
|
bit_mask = bd->tag;
|
|
c=0;
|
|
for(bit_no=0;bit_no<32;bit_no++) {
|
|
if(bit_mask&0x1) {
|
|
PyList_SetItem(l3,c,PyInt_FromLong(bit_no));
|
|
c++;
|
|
}
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
PyList_SetItem(l2,b,l3);
|
|
bi = bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_ext_indices_with_tags(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai,bi;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2,*l3,*l4;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b,c;
|
|
int n_atom,n_bond;
|
|
int bit_mask;
|
|
int bit_no;
|
|
int n_bits;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
|
|
n_bits = 0;
|
|
bit_mask = at->tag;
|
|
while(bit_mask) { /* count bits */
|
|
if(bit_mask&0x1)
|
|
n_bits++;
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
l4 = PyList_New(2);
|
|
l3 = PyList_New(n_bits);
|
|
bit_no = 0;
|
|
bit_mask = at->tag;
|
|
c=0;
|
|
for(bit_no=0;bit_no<32;bit_no++) {
|
|
if(bit_mask&0x1) {
|
|
PyList_SetItem(l3,c,PyInt_FromLong(bit_no));
|
|
c++;
|
|
}
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
PyList_SetItem(l1,a,l4);
|
|
PyList_SetItem(l4,0,PyInt_FromLong(at->ext_index));
|
|
PyList_SetItem(l4,1,l3);
|
|
ai = at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bi = pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
bd = I->Bond + bi;
|
|
n_bits = 0;
|
|
bit_mask = bd->tag;
|
|
while(bit_mask) { /* count bits */
|
|
if(bit_mask&0x1)
|
|
n_bits++;
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
l4 = PyList_New(2);
|
|
l3 = PyList_New(n_bits);
|
|
bit_no = 0;
|
|
bit_mask = bd->tag;
|
|
c=0;
|
|
for(bit_no=0;bit_no<32;bit_no++) {
|
|
if(bit_mask&0x1) {
|
|
PyList_SetItem(l3,c,PyInt_FromLong(bit_no));
|
|
c++;
|
|
}
|
|
bit_mask=((bit_mask>>1)&0x7FFFFFFF);
|
|
}
|
|
PyList_SetItem(l2,b,l4);
|
|
PyList_SetItem(l4,0,PyInt_FromLong(bd->ext_index));
|
|
PyList_SetItem(l4,1,l3);
|
|
|
|
bi = bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_tag_masks(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai,bi;
|
|
PyObject *result = NULL;
|
|
PyObject *O,*l1,*l2;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
int a,b;
|
|
int n_atom,n_bond;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
l1 = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
|
|
PyList_SetItem(l1,a,PyInt_FromLong(at->tag));
|
|
|
|
ai = at->link;
|
|
}
|
|
|
|
n_bond = ListLen(I->Bond,pat->bond);
|
|
l2 = PyList_New(n_bond);
|
|
bi = pat->bond;
|
|
for(b=0;b<n_bond;b++) {
|
|
bd = I->Bond + bi;
|
|
PyList_SetItem(l2,b,PyInt_FromLong(bd->tag));
|
|
bi = bd->link;
|
|
}
|
|
|
|
result = PyList_New(2);
|
|
PyList_SetItem(result,0,l1);
|
|
PyList_SetItem(result,1,l2);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *pattern_clear_tags(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai,bi;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
ListBond *bd;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
ai = pat->atom;
|
|
while(ai) {
|
|
at = I->Atom + ai;
|
|
at->tag = 0;
|
|
ai = at->link;
|
|
}
|
|
|
|
bi = pat->bond;
|
|
while(bi) {
|
|
bd = I->Bond + bi;
|
|
bd->tag = 0;
|
|
bi = bd->link;
|
|
}
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
|
|
|
|
|
|
static PyObject *list_new(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"O",&O);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
result = ListElemNewZero(&I->Int);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
static PyObject *list_free(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int list_index,list_handle,purge;
|
|
int i;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&list_handle,&purge);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
i = list_index;
|
|
while(i) {
|
|
if(purge) ChampPatFree(I,I->Int[i].value);
|
|
i = I->Int[i].link;
|
|
}
|
|
ListElemFreeChain(I->Int,list_index);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
static PyObject *list_get_pattern_indices(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *result = NULL;
|
|
PyObject *O;
|
|
int list_index,list_handle;
|
|
CChamp *I;
|
|
int i,c;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&list_handle);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
i = list_index;
|
|
c = 0;
|
|
while(i) {
|
|
i = I->Int[i].link;
|
|
c++;
|
|
}
|
|
result = PyList_New(c);
|
|
i = list_index;
|
|
c = 0;
|
|
while(i) {
|
|
PyList_SetItem(result,c,PyInt_FromLong(I->Int[i].value));
|
|
i = I->Int[i].link;
|
|
c++;
|
|
}
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_string(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *result = NULL;
|
|
PyObject *O;
|
|
int pat_index;
|
|
int mode;
|
|
CChamp *I;
|
|
char *smi;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&pat_index,&mode);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
smi = ChampPatToSmiVLA(I,pat_index,NULL,mode);
|
|
result = PyString_FromString(smi);
|
|
vla_free(smi);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_dump(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *result = NULL;
|
|
PyObject *O;
|
|
int pat_index;
|
|
CChamp *I;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&pat_index);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
ChampPatDump(I,pat_index);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_atom_symbols(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai;
|
|
PyObject *result = NULL;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
int a;
|
|
int n_atom;
|
|
char atom[255];
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
result = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
ChampAtomToString(I,ai,atom);
|
|
PyList_SetItem(result,a,PyString_FromString(atom));
|
|
ai = at->link;
|
|
}
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *pattern_get_atom_names(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int int1,ai;
|
|
PyObject *result = NULL;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ListPat *pat;
|
|
ListAtom *at;
|
|
int a;
|
|
int n_atom;
|
|
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&int1);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
pat = I->Pat+int1;
|
|
n_atom = ListLen(I->Atom,pat->atom);
|
|
ai = pat->atom;
|
|
result = PyList_New(n_atom);
|
|
for(a=0;a<n_atom;a++) {
|
|
at = I->Atom + ai;
|
|
PyList_SetItem(result,a,PyString_FromString(at->name));
|
|
ai = at->link;
|
|
}
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *list_get_pattern_strings(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *result = NULL,*str;
|
|
PyObject *O;
|
|
int list_index,list_handle;
|
|
CChamp *I;
|
|
int i,c;
|
|
char *smi = NULL;
|
|
ok = PyArg_ParseTuple(args,"Oi",&O,&list_handle);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
i = list_index;
|
|
c = 0;
|
|
while(i) {
|
|
i = I->Int[i].link;
|
|
c++;
|
|
}
|
|
result = PyList_New(c);
|
|
i = list_index;
|
|
c = 0;
|
|
while(i) {
|
|
smi = ChampPatToSmiVLA(I,I->Int[i].value,smi,0);
|
|
str = PyString_FromString(smi);
|
|
PyList_SetItem(result,c,str);
|
|
i = I->Int[i].link;
|
|
c++;
|
|
}
|
|
vla_free(smi);
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *list_prepend_pattern_strings(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int list_handle,pat_index;
|
|
int a,l;
|
|
PyObject *O,*smi_list;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"OiO",&O,&list_handle,&smi_list);
|
|
ok = PyCObject_Check(O);
|
|
ok = PyList_Check(smi_list);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
l = PyList_Size(smi_list);
|
|
for(a=l-1;a>=0;a--) {
|
|
pat_index = ChampSmiToPat(I,PyString_AsString(PyList_GetItem(smi_list,a)));
|
|
if(!pat_index) {
|
|
ok=false;
|
|
break;
|
|
}
|
|
I->Int[list_handle].link = ListElemPushInt(&I->Int,I->Int[list_handle].link,pat_index);
|
|
}
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
|
|
static PyObject *list_prepend_pattern_index(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int list_handle,pat_index;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&list_handle,&pat_index);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
if(pat_index)
|
|
I->Int[list_handle].link = ListElemPushInt(&I->Int,I->Int[list_handle].link,pat_index);
|
|
}
|
|
return(RetStatus(ok));
|
|
}
|
|
|
|
|
|
static PyObject *match_1v1_b(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
int pat1,pat2;
|
|
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&pat1,&pat2);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
result = ChampMatch_1V1_B(I,pat1,pat2);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
static PyObject *match_1v1_n(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
int pat1,pat2;
|
|
int limit;
|
|
int tag;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oiiii",&O,&pat1,&pat2,&limit,&tag);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
result = ChampMatch_1V1_N(I,pat1,pat2,limit,tag);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *match_1v1_map(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
PyObject *result = NULL;
|
|
PyObject *set,*pairs,*tmpl,*targ;
|
|
int pat1,pat2;
|
|
int limit;
|
|
int mat_start;
|
|
int mat_cnt,pair_cnt;
|
|
int a,b,i,j;
|
|
int tag;
|
|
ListMatch *mat;
|
|
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oiiii",&O,&pat1,&pat2,&limit,&tag);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
mat_start = ChampMatch_1V1_Map(I,pat1,pat2,limit,tag);
|
|
|
|
ChampPatReindex(I,pat1);
|
|
ChampPatReindex(I,pat2);
|
|
|
|
mat_cnt = 0;
|
|
i = mat_start;
|
|
while(i) {
|
|
mat_cnt++;
|
|
i = I->Match[i].link;
|
|
}
|
|
result = PyList_New(mat_cnt);
|
|
i = mat_start;
|
|
for(a=0;a<mat_cnt;a++) {
|
|
mat = I->Match + i;
|
|
set = PyList_New(2); /* atom matches, bond matches */
|
|
|
|
pairs = PyList_New(2); /* paired atoms */
|
|
pair_cnt = 0;
|
|
j = mat->atom;
|
|
while(j) {
|
|
pair_cnt++;
|
|
j = I->Int2[j].link;
|
|
}
|
|
tmpl = PyList_New(pair_cnt);
|
|
targ = PyList_New(pair_cnt);
|
|
j = mat->atom;
|
|
for(b=0;b<pair_cnt;b++) {
|
|
/*
|
|
printf("%2d %2d %4d %4d\n",I->Int2[j].value[0],I->Int2[j].value[1],
|
|
I->Atom[I->Int2[j].value[0]].index,
|
|
I->Atom[I->Int2[j].value[1]].index);*/
|
|
PyList_SetItem(tmpl,b,PyInt_FromLong(I->Atom[I->Int2[j].value[0]].index));
|
|
PyList_SetItem(targ,b,PyInt_FromLong(I->Atom[I->Int2[j].value[1]].index));
|
|
j = I->Int2[j].link;
|
|
}
|
|
PyList_SetItem(pairs,0,tmpl);
|
|
PyList_SetItem(pairs,1,targ);
|
|
PyList_SetItem(set,0,pairs);
|
|
|
|
pairs = PyList_New(2); /* paired bonds */
|
|
pair_cnt = 0;
|
|
j = mat->bond;
|
|
while(j) {
|
|
pair_cnt++;
|
|
j = I->Int2[j].link;
|
|
}
|
|
tmpl = PyList_New(pair_cnt);
|
|
targ = PyList_New(pair_cnt);
|
|
j = mat->bond;
|
|
for(b=0;b<pair_cnt;b++) {
|
|
PyList_SetItem(tmpl,b,PyInt_FromLong(I->Bond[I->Int2[j].value[0]].index));
|
|
PyList_SetItem(targ,b,PyInt_FromLong(I->Bond[I->Int2[j].value[1]].index));
|
|
j = I->Int2[j].link;
|
|
}
|
|
PyList_SetItem(pairs,0,tmpl);
|
|
PyList_SetItem(pairs,1,targ);
|
|
PyList_SetItem(set,1,pairs);
|
|
|
|
PyList_SetItem(result,a,set);
|
|
i = I->Match[i].link;
|
|
}
|
|
}
|
|
return(RetObj(ok,result));
|
|
}
|
|
|
|
static PyObject *match_1vN_n(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
int list_handle,list_index;
|
|
int pattern;
|
|
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&pattern,&list_handle);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
result = ChampMatch_1VN_N(I,pattern,list_index);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
static PyObject *exact_1vN_n(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
int list_handle,list_index;
|
|
int pattern;
|
|
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oii",&O,&pattern,&list_handle);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
result = ChampExact_1VN_N(I,pattern,list_index);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
|
|
static PyObject *match_Nv1_n(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
int list_handle,list_index;
|
|
int pattern;
|
|
int limit,tag;
|
|
PyObject *O;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"Oiiii",&O,&list_handle,&pattern,&limit,&tag);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
list_index = I->Int[list_handle].link;
|
|
result = ChampMatch_NV1_N(I,list_index,pattern,limit,tag);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
static PyObject *insert_model(PyObject *self, PyObject *args)
|
|
{
|
|
int ok=true;
|
|
int result = 0;
|
|
|
|
PyObject *O,*M;
|
|
CChamp *I;
|
|
ok = PyArg_ParseTuple(args,"OO",&O,&M);
|
|
ok = PyCObject_Check(O);
|
|
if(ok) {
|
|
I = PyCObject_AsVoidPtr(O);
|
|
result = ChampModelToPat(I,M);
|
|
}
|
|
return(RetInt(ok,result));
|
|
}
|
|
|
|
static PyMethodDef champ_methods[] = {
|
|
{"new", _new, METH_VARARGS },
|
|
{"memory_dump", _memory_dump, METH_VARARGS },
|
|
{"insert_pattern_string", insert_pattern_string, METH_VARARGS },
|
|
{"insert_model", insert_model, METH_VARARGS },
|
|
{"pattern_free", pattern_free, METH_VARARGS },
|
|
{"pattern_clear_tags", pattern_clear_tags, METH_VARARGS },
|
|
{"pattern_get_cycle", pattern_get_cycle, METH_VARARGS },
|
|
{"pattern_get_class", pattern_get_class, METH_VARARGS },
|
|
{"pattern_get_codes", pattern_get_codes, METH_VARARGS },
|
|
{"pattern_get_string", pattern_get_string, METH_VARARGS },
|
|
{"pattern_get_tags", pattern_get_tags, METH_VARARGS },
|
|
{"pattern_get_tag_masks", pattern_get_tag_masks, METH_VARARGS },
|
|
{"pattern_get_atom_symbols", pattern_get_atom_symbols, METH_VARARGS },
|
|
{"pattern_get_atom_names", pattern_get_atom_names, METH_VARARGS },
|
|
{"pattern_get_ext_indices_with_tags", pattern_get_ext_indices_with_tags, METH_VARARGS },
|
|
{"pattern_dump", pattern_dump, METH_VARARGS },
|
|
{"pattern_orient_bonds", pattern_orient_bonds, METH_VARARGS },
|
|
{"pattern_detect_chirality", pattern_detect_chirality, METH_VARARGS },
|
|
{"pattern_generalize", pattern_generalize, METH_VARARGS },
|
|
{"list_prepend_pattern_strings", list_prepend_pattern_strings, METH_VARARGS },
|
|
{"list_prepend_pattern_index", list_prepend_pattern_index, METH_VARARGS },
|
|
{"list_get_pattern_indices", list_get_pattern_indices, METH_VARARGS },
|
|
{"list_get_pattern_strings", list_get_pattern_strings, METH_VARARGS },
|
|
{"list_free", list_free, METH_VARARGS },
|
|
{"list_new", list_new, METH_VARARGS },
|
|
{"match_1v1_b", match_1v1_b, METH_VARARGS },
|
|
{"match_1v1_map", match_1v1_map, METH_VARARGS},
|
|
{"match_1v1_n", match_1v1_n, METH_VARARGS},
|
|
{"match_1vN_n", match_1vN_n, METH_VARARGS },
|
|
{"match_Nv1_n", match_Nv1_n, METH_VARARGS },
|
|
/* {"map_1v1_to_indexed_strings", map_1v1_to_indexed_strings, METH_VARARGS },*/
|
|
{"exact_1vN_n", exact_1vN_n, METH_VARARGS },
|
|
|
|
{NULL, NULL} /* sentinel */
|
|
};
|
|
|
|
PyMODINIT_FUNC PyInit__champ(void)
|
|
{
|
|
static struct PyModuleDef moduledef = {
|
|
PyModuleDef_HEAD_INIT,
|
|
"_champ", NULL, -1, champ_methods };
|
|
return PyModule_Create(&moduledef);
|
|
}
|