in contrib/champ/champ.c [1335:1666]
int ChampModelToPat(CChamp *I,PyObject *model)
{
int nAtom,nBond;
int a;
int ok=true;
int cur_atom=0,last_atom = 0;
ListAtom *at;
int cur_bond=0,last_bond = 0;
ListBond *bd;
int charge=0,order=1;
int result = 0;
int atom1,atom2;
int *atom_index = NULL;
int std_flag;
char *c;
PyObject *atomList = NULL;
PyObject *bondList = NULL;
PyObject *molec = NULL;
PyObject *atom = NULL;
PyObject *bnd = NULL;
PyObject *index = NULL;
PyObject *tmp = NULL;
nAtom=0;
nBond=0;
atomList = PyObject_GetAttrString(model,"atom");
if(atomList)
nAtom = PyList_Size(atomList);
else
ok=err_message("ChampModel2Pat","can't get atom list");
atom_index = mac_malloc_array(int,nAtom);
if(ok) {
for(a=nAtom-1;a>=0;a--) /* reverse order */
{
atom = PyList_GetItem(atomList,a);
if(!atom)
ok=err_message("ChampModel2Pat","can't get atom");
cur_atom = ListElemNewZero(&I->Atom);
at = I->Atom + cur_atom;
at->link = last_atom;
last_atom = cur_atom;
at->chempy_atom = atom;
Py_INCREF(at->chempy_atom);
atom_index[a] = cur_atom; /* for bonds */
if(ok) {
tmp = PyObject_GetAttrString(atom,"name");
if (tmp)
ok = PConvPyObjectToStrMaxClean(tmp,at->name,NAM_SIZE-1);
if(!ok)
err_message("ChampModel2Pat","can't read name");
Py_XDECREF(tmp);
}
if(ok) {
if(PTruthCallStr(atom,"has","flags")) {
tmp = PyObject_GetAttrString(atom,"flags");
if (tmp)
ok = PConvPyObjectToInt(tmp,(int*)&at->tag);
if(!ok)
err_message("ChampModel2Pat","can't read flags");
Py_XDECREF(tmp);
} else {
at->tag = 0;
}
}
if(ok) {
if(PTruthCallStr(atom,"has","index")) { /* note -- chempy models have 1-based index attributes
even though the arrays are zero-based */
tmp = PyObject_GetAttrString(atom,"index");
if (tmp)
ok = PConvPyObjectToInt(tmp,(int*)&at->ext_index);
if(!ok)
err_message("ChampModel2Pat","can't read index");
Py_XDECREF(tmp);
} else {
at->index = 0;
}
}
if(ok) {
if(PTruthCallStr(atom,"has","coord")) {
tmp = PyObject_GetAttrString(atom,"coord");
if (tmp)
ok = PConvPyListToFloatArrayInPlace(tmp,at->coord,3);
if(!ok)
err_message("ChampModel2Pat","can't read coordinates");
Py_XDECREF(tmp);
}
}
if(ok) {
if(PTruthCallStr(atom,"has","formal_charge")) {
tmp = PyObject_GetAttrString(atom,"formal_charge");
if (tmp)
ok = PConvPyObjectToInt(tmp,&charge);
if(!ok)
err_message("ChampModel2Pat","can't read formal_charge");
Py_XDECREF(tmp);
} else {
charge = 0;
}
switch(charge) {
case 0: at->charge = cH_Neutral; break;
case 1: at->charge = cH_Cation; break;
case 2: at->charge = cH_Dication; break;
case -1: at->charge = cH_Anion; break;
case -2: at->charge = cH_Dianion; break;
}
}
if(ok) {
tmp = PyObject_GetAttrString(atom,"resn");
if (tmp)
ok = PConvPyObjectToStrMaxClean(tmp,at->residue,RES_SIZE-1);
if(!ok)
err_message("ChampModel2Pat","can't read resn");
Py_XDECREF(tmp);
}
if(ok) {
tmp = PyObject_GetAttrString(atom,"symbol");
if (tmp)
ok = PConvPyObjectToStrMaxClean(tmp,at->symbol,SYM_SIZE-1);
if(!ok)
err_message("ChampModel2Pat","can't read symbol");
c = at->symbol;
std_flag = false;
switch(*c) {
case 'C':
switch(*(c+1)) {
case 'l':
case 'L':
ChampParseAliphaticAtom(I,c,cur_atom,cH_Cl,2,false);
std_flag = true;
break;
default:
ChampParseAliphaticAtom(I,c,cur_atom,cH_C,1,true);
std_flag = true;
break;
}
break;
case 'H': /* nonstandard */
ChampParseAliphaticAtom(I,c,cur_atom,cH_H,1,false);
std_flag = true;
break;
case 'N':
ChampParseAliphaticAtom(I,c,cur_atom,cH_N,1,true);
std_flag = true;
break;
case 'O':
ChampParseAliphaticAtom(I,c,cur_atom,cH_O,1,true);
std_flag = true;
break;
case 'B':
switch(*(c+1)) {
case 'r':
case 'R':
ChampParseAliphaticAtom(I,c,cur_atom,cH_Br,2,false);
std_flag = true;
break;
default:
ChampParseAliphaticAtom(I,c,cur_atom,cH_B,1,true);
std_flag = true;
break;
}
break;
case 'A':
ChampParseAliphaticAtom(I,c,cur_atom,cH_A,1,true);
std_flag = true;
break;
case 'P':
ChampParseAliphaticAtom(I,c,cur_atom,cH_P,1,true);
std_flag = true;
break;
case 'S':
ChampParseAliphaticAtom(I,c,cur_atom,cH_S,1,true);
std_flag = true;
break;
case 'F':
ChampParseAliphaticAtom(I,c,cur_atom,cH_F,1,false);
std_flag = true;
break;
case 'I':
ChampParseAliphaticAtom(I,c,cur_atom,cH_I,1,false);
std_flag = true;
break;
case 'E':
ChampParseAliphaticAtom(I,c,cur_atom,cH_E,1,false);
std_flag = true;
break;
case 'G':
ChampParseAliphaticAtom(I,c,cur_atom,cH_G,1,false);
std_flag = true;
break;
case 'J':
ChampParseAliphaticAtom(I,c,cur_atom,cH_J,1,false);
std_flag = true;
break;
case 'L':
ChampParseAliphaticAtom(I,c,cur_atom,cH_L,1,false);
std_flag = true;
break;
case 'M':
ChampParseAliphaticAtom(I,c,cur_atom,cH_M,1,false);
std_flag = true;
break;
case 'Q':
ChampParseAliphaticAtom(I,c,cur_atom,cH_Q,1,false);
std_flag = true;
break;
case 'R':
ChampParseAliphaticAtom(I,c,cur_atom,cH_R,1,false);
std_flag = true;
break;
case 'T':
ChampParseAliphaticAtom(I,c,cur_atom,cH_T,1,false);
std_flag = true;
break;
case 'X':
ChampParseAliphaticAtom(I,c,cur_atom,cH_X,1,false);
std_flag = true;
break;
case 'Z':
ChampParseAliphaticAtom(I,c,cur_atom,cH_Z,1,false);
std_flag = true;
break;
}
if(!std_flag) {
ChampParseStringAtom(I,c,cur_atom,strlen(c));
}
Py_XDECREF(tmp);
}
if(!ok)
break;
}
}
bondList = PyObject_GetAttrString(model,"bond");
if(bondList)
nBond = PyList_Size(bondList);
else
ok=err_message("ChampModel2Pat","can't get bond list");
if(ok) {
for(a=nBond-1;a>=0;a--) /* reverse order */
{
bnd = PyList_GetItem(bondList,a);
if(!bnd)
ok=err_message("ChampModel2Pat","can't get bond");
cur_bond = ListElemNewZero(&I->Bond);
bd = I->Bond + cur_bond;
bd->link = last_bond;
last_bond = cur_bond;
bd->chempy_bond = bnd;
Py_INCREF(bd->chempy_bond);
if(ok) {
tmp = PyObject_GetAttrString(bnd,"order");
if (tmp)
ok = PConvPyObjectToInt(tmp,&order);
if(!ok)
err_message("ChampModel2Pat","can't read bond order");
switch(order) {
case 1: bd->order = cH_Single; break;
case 2: bd->order = cH_Double; break;
case 3: bd->order = cH_Triple; break;
case 4: bd->order = cH_Single; bd->class = cH_Aromatic|cH_Pi; break;
}
Py_XDECREF(tmp);
}
index = PyObject_GetAttrString(bnd,"index");
if(!index)
ok=err_message("ChampModel2Pat","can't get bond indices");
else {
if(ok) ok = PConvPyObjectToInt(PyList_GetItem(index,0),&atom1);
if(ok) ok = PConvPyObjectToInt(PyList_GetItem(index,1),&atom2);
if(!ok)
err_message("ChampModel2Pat","can't read bond atoms");
else {
atom1 = atom_index[atom1];
atom2 = atom_index[atom2];
if(order==4) {
I->Atom[atom1].class |= cH_Aromatic|cH_Pi;
I->Atom[atom2].class |= cH_Aromatic|cH_Pi;
}
bd->atom[0]=atom1;
bd->atom[1]=atom2;
bd->pri[0]=0;
bd->pri[1]=0;
ChampAddBondToAtom(I,atom1,cur_bond);
ChampAddBondToAtom(I,atom2,cur_bond);
}
}
Py_XDECREF(index);
}
}
Py_XDECREF(atomList);
Py_XDECREF(bondList);
if(PyObject_HasAttrString(model,"molecule")) {
molec = PyObject_GetAttrString(model,"molecule"); /* returns new reference */
} else {
molec = NULL;
}
mac_free(atom_index);
result = ListElemNewZero(&I->Pat);
if(result)
{
I->ActivePatList = ListElemPushInt(&I->Int,I->ActivePatList,result);
I->Pat[result].atom = cur_atom;
I->Pat[result].bond = cur_bond;
I->Pat[result].chempy_molecule = molec;
ChampPatReindex(I,result);
}
return(result);
}