babel-1.6
|
Makefile,
README.1ST,
addh.c,
addh2.c,
aromatic.c,
assbnd.c,
asstypes.c,
babel.h,
bblmacs.h,
bblmast.h,
bbltyp.h,
block.c,
bndord.c,
bo.c,
buildct.c,
combine.c,
convert.c,
delatms.c,
delh2o.c,
element.lis,
filesrch.c,
fileutil.c,
gastchg.c,
gauss.hdr,
htoend.c,
int2cart.c,
intcart.c,
menus.c,
miniums.c,
molwt.c,
new.lis,
nodummy.c,
orient.c,
precip.c,
printbad.c,
progress.c,
psgvb.hdr,
quanta.lis,
rdalch.c,
rdampout.c,
rdbalst.c,
rdbgf.c,
rdboogie.c,
rdc3d.c,
rdcacao.c,
rdcadpac.c,
rdcharmm.c,
rdcsd.c,
rddock.c,
rddpdb.c,
rdelmnts.c,
rdfdat.c,
rdfeat.c,
rdfract.c,
rdg96.c,
rdgamout.c,
rdgauout.c,
rdgzmat.c,
rdhin.c,
rdinsite.c,
rdint.c,
rdirc.c,
rdisis.c,
rdm3d.c,
rdmacmod.c,
rdmacmol.c,
rdmdl.c,
rdmicro.c,
rdmm2.c,
rdmm2in.c,
rdmm3.c,
rdmolen.c,
rdmopac.c,
rdmopcrt.c,
rdpcmod.c,
rdpdb.c,
rdprep.c,
rdpsgout.c,
rdpsgvin.c,
rdquanta.c,
rdschak.c,
rdshelx.c,
rdsmiles.c,
rdspart.c,
rdspmm.c,
rdspsemi.c,
rdsybmol.c,
rdsybyl.c,
rdtypes.c,
rdunichm.c,
rdwiz.c,
rdxed.c,
rdxyz.c,
renum.c,
report.c,
rings.c,
ringutil.c,
sets.c,
smilesto.c,
spline.c,
strngutl.c,
tokenst.c,
tosmiles.c,
tree.c,
typbybo.c,
types.lis,
umslist.c,
utils.c,
vectors.c,
wralch.c,
wrbalst.c,
wrbgf.c,
wrbmin.c,
wrbox.c,
wrc3d.c,
wrcacao.c,
wrcache.c,
wrcacint.c,
wrchdrw.c,
wrcontmp.c,
wrcsr.c,
wrcssr.c,
wrdock.c,
wrdpdb.c,
wrfeat.c,
wrfh.c,
wrg96.c,
wrgamess.c,
wrgau.c,
wrgaucrt.c,
wrhin.c,
wricon.c,
wrint.c,
wrisis.c,
wrm3d.c,
wrmaccs.c,
wrmacmod.c,
wrmcmol.c,
wrmdl.c,
wrmicro.c,
wrmimic.c,
wrmiv.c,
wrmm2.c,
wrmm3.c,
wrmopac.c,
wrpcmod.c,
wrpdb.c,
wrpsgv.c,
wrpsgvz.c,
wrsmiles.c,
wrspart.c,
wrsybmol.c,
wrsybyl.c,
wrtinker.c,
wrtorlst.c,
wrunichm.c,
wrwiz.c,
wrxed.c,
wrxyz.c
|
|
|
/*****
This file is part of the Babel Program
Copyright (C) 1992-96 W. Patrick Walters and Matthew T. Stahl
All Rights Reserved
All Rights Reserved
All Rights Reserved
All Rights Reserved
For more information please contact :
babel@mercury.aichem.arizona.edu
--------------------------------------------------------------------------------
FILE : bndord.c
AUTHOR(S) : Pat Walters
DATE : 2-10-93
PURPOSE : Assign bond orders based on atom types, clean up conjugated pi systems
******/
#include "bbltyp.h"
static char wstr[256];
static int cycles;
#define SINGLE_DOUBLE_CUTOFF 0.95
#define DOUBLE_TRIPLE_CUTOFF 0.81
void assign_bond_order2(ums_type *mol)
{
int *dots;
int i,j;
bnd_stack stk;
set_type *dbatoms, *dbbonds;
ring_struct rings;
int conn;
for (i = 1; i <= Atoms; i++)
Redo(i) = 0;
dots = (int *)malloc((Atoms + 1) * sizeof(int));
stk.bond = (int *)malloc((Bonds) * sizeof(int));
stk.choice = (int *)malloc((Bonds) * sizeof(int));
dbatoms = init_set_minbits(Atoms);
dbbonds = init_set_minbits(Bonds);
find_SSSR(mol,&rings);
tag_ring_atoms(mol,rings.ring_list,rings.count);
assign_hybrid_radii(mol);
estimate_bond_order2(mol);
for (i = 0; i < rings.count; i++)
{
if (rings.ring_list[i].length == 5)
process_5_ring(mol,&rings,i);
}
dissect_connection_table(mol);
cleanup_rings(&rings);
for (i = 0; i < Bonds; i++)
{
if (Bond_order(i) == 2)
{
if ((Valence(Start(i)) > 1) && (Type(Start(i))[0] == 'O'))
Bond_order(i) = 1;
else
if ((Valence(End(i)) > 1) && (Type(End(i))[0] == 'O'))
Bond_order(i) = 1;
}
}
for (i = 0; i < Bonds; i++)
{
if (Bond_order(i) == 2)
{
if ((Valence(Start(i)) == 1) && (Type(Start(i))[0] == 'N'))
Bond_order(i) = 1;
else
if ((Valence(End(i)) == 1) && (Type(End(i))[0] == 'N'))
Bond_order(i) = 1;
}
}
for (i = 1; i <= Atoms; i++)
dots[i] = 0;
for (i = 0; i < Bonds; i++)
if (Bond_order(i) > 1)
{
if ((Redo(Start(i))) && (check_for_carbonyl(mol,Start(i))) != 3)
dots[Start(i)] = 1;
if ((Redo(End(i))) &&(check_for_carbonyl(mol,End(i))) != 3)
dots[End(i)] = 1;
if ((Valence(Start(i)) == 1) || (Valence(End(i)) == 1))
{
dots[Start(i)] = 0;
dots[End(i)] = 0;
}
}
for (i = 1; i <= Atoms; i++)
{
if (EQ(Type(i),"Npl") && (Valence(i) == 3))
dots[i] = 0;
}
stk.ptr = 0;
cycles = 0;
connect_the_dots(mol,1,0,dots,&stk);
for (i = 1; i <= stk.ptr; i++)
{
if (Bond_order(stk.bond[i]) > 1)
{
biton(dbbonds,stk.bond[i]);
biton(dbatoms,Start(stk.bond[i]));
biton(dbatoms,End(stk.bond[i]));
}
}
for (i = 0; i < Bonds; i++)
{
if (EQ(Type(Start(i)),"O2") || EQ(Type(End(i)),"O2"))
{
biton(dbbonds,i);
biton(dbatoms,Start(i));
biton(dbatoms,End(i));
}
else
if (EQ(Type(Start(i)),"O-") && (Valence(Start(i)) == 1))
{
biton(dbbonds,i);
biton(dbatoms,Start(i));
biton(dbatoms,End(i));
}
else
if (EQ(Type(End(i)),"O-") && (Valence(End(i)) == 1))
{
biton(dbbonds,i);
biton(dbatoms,Start(i));
biton(dbatoms,End(i));
}
}
#ifdef DEBUG
setprint(dbatoms,"dbatoms");
setprint(dbbonds,"dbbonds");
#endif
for (i = 1; i <= Atoms; i++)
dots[i] = 0;
for (i = 0; i < Bonds; i++)
{
if (Bond_order(i) > 1)
{
if (!bit_is_on(dbatoms,Start(i)) && !bit_is_on(dbatoms,End(i)))
{
dots[Start(i)] = 1;
dots[End(i)] = 1;
}
}
}
stk.ptr = 0;
connect_the_dots(mol,1,0,dots,&stk);
for (i = 1; i <= stk.ptr; i++)
{
biton(dbbonds,stk.bond[i]);
}
for (i = 0; i < Bonds; i++)
{
if (!bit_is_on(dbbonds,i))
Bond_order(i) = 1;
}
dissect_connection_table(mol);
for (i = 0; i <= Atoms; i++)
{
Redo(i) = 0;
for (j = 0; j < Valence(i); j++)
Redo(i) += BO(i,j);
if ((Atomic_number(i) == 6 || Atomic_number(i) == 7) && (Redo(i) > 4))
{
for (j = 0; j < Valence(i); j++)
{
conn = -1;
if (BO(i,j) == 2)
{
BO(i,j) = 1;
conn = Connection(i,j);
break;
}
}
if (conn > 0)
{
for (j = 0; j < Valence(conn); j++)
{
if (Connection(conn,j) == i)
BO(conn,j) = 1;
}
}
}
}
build_connection_table(mol);
if (dots)
free(dots);
if (stk.bond)
free(stk.bond);
if (stk.choice)
free(stk.choice);
free_set(dbatoms);
free_set(dbbonds);
}
void set_bo(ums_type *mol)
{
int i;
int sum_code;
for (i = 0; i < Bonds; i++)
{
sum_code = assign_bond_code(Type(Start(i))) +
assign_bond_code(Type(End(i)));
switch(sum_code)
{
case 6 :
Bond_order(i) = 3;
break;
case 4 :
Bond_order(i) = 2;
break;
default :
Bond_order(i) = 1;
}
if (is_carboxyl(mol,i))
Bond_order(i) = 2;
if (Bond_order(i) < 1 || Bond_order(i) > 3)
{
sprintf(wstr,"Bond %d - atoms %d - %d is wierd - Bond order is %d\n",
i,Start(i),End(i),Bond_order(i));
show_warning(wstr);
}
}
}
int connect_the_dots(ums_type *mol, int atm, int start, int *dots, bnd_stack *stk)
{
int i;
int con;
int bond;
int done;
int new_atm, choice_bnd;
if (start == Valence(atm))
return(0);
if (dots[atm])
{
done = FALSE;
for (i = start; (i < Valence(atm) && !done); i++)
{
con = Connection(atm,i);
if (dots[con])
{
stk->ptr++;
bond = get_bond_number(mol,atm,con);
stk->bond[stk->ptr]= bond;
if (atm == Start(bond))
stk->choice[stk->ptr] = i+1;
else
stk->choice[stk->ptr] = -(i+1);
dots[atm] -= 1;
dots[con] -= 1;
done = TRUE;
}
}
if ((!done) && (stk->ptr > 0))
{
bond = stk->bond[stk->ptr];
choice_bnd = stk->choice[stk->ptr];
if (choice_bnd > 0)
new_atm = Start(bond);
else
new_atm = End(bond);
choice_bnd = abs(choice_bnd);
stk->ptr--;
dots[Start(bond)] += 1;
dots[End(bond)] += 1;
connect_the_dots(mol,new_atm,choice_bnd,dots,stk);
}
}
if (cycles > 10000)
return(0);
if (atm == Atoms)
return(1);
else
{
cycles++;
connect_the_dots(mol,atm+1,0,dots,stk);
}
return(TRUE);
}
int get_bond_number(ums_type *mol,int start, int end)
{
int i;
for (i = 0; i < Bonds; i++)
{
if ((Start(i) == start) && (End(i) == end))
return(i);
else
if ((Start(i) == end) && (End(i) == start))
return(i);
}
return(-1);
}
void tag_ring_atoms(ums_type *mol, path *ring_set, int ring_count)
{
int i,j;
for (i = 1; i <= Atoms; i++)
Redo(i) = 0;
for (i = 0; i < ring_count; i++)
{
if (ring_set[i].bogus == FALSE)
{
for (j = 0; j < ring_set[i].length; j++)
{
Redo(ring_set[i].path_atoms[j]) = 1;
}
}
}
}
double get_bond_ratio(ums_type *mol, int a1, int a2)
{
double dist,cov_sum;
dist = distance(Point(a1),Point(a2));
cov_sum = BORadius(a1) + BORadius(a2);
return(dist/cov_sum);
}
void estimate_bond_order2(ums_type *mol)
{
double ratio;
int bo;
int i;
char start_type[5];
char end_type[5];
for (i = 0; i < Bonds; i++)
{
bo = 1;
ratio = get_bond_ratio(mol,Start(i),End(i));
get_output_type(Start(i),"HYB",Type(Start(i)),start_type,all_caps);
get_output_type(End(i),"HYB",Type(End(i)),end_type,all_caps);
if (ratio <= DOUBLE_TRIPLE_CUTOFF)
{
if ((start_type[0] == '1') && (end_type[0] == '1'))
bo = 3;
}
else
if (ratio <= SINGLE_DOUBLE_CUTOFF)
{
get_output_type(Start(i),"HYB",Type(Start(i)),start_type,all_caps);
get_output_type(End(i),"HYB",Type(End(i)),end_type,all_caps);
if ((start_type[0] == '2') && (end_type[0] == '2'))
bo = 2;
}
#ifdef DEBUG
printf("i = %d Start = %d End = %d r1 = %10.3f r2 = %10.3f dist = %10.2f sum = %10.2f ratio = %10.2f bond order = %4d\n",
i,Start(i),End(i),BORadius(Start(i)),BORadius(End(i)),dist,cov_sum,ratio,bo);
#endif
Bond_order(i) = bo;
}
}
void process_5_ring(ums_type *mol, ring_struct *rings, int num)
{
int bond;
int a1,a2,a3,a4,a5;
double t1,t2,t3,t4,t5;
double ratio;
a1 = rings->ring_list[num].path_atoms[0];
a2 = rings->ring_list[num].path_atoms[1];
a3 = rings->ring_list[num].path_atoms[2];
a4 = rings->ring_list[num].path_atoms[3];
a5 = rings->ring_list[num].path_atoms[4];
t1 = torsion(Point(a5),Point(a1),Point(a2),Point(a3));
t2 = torsion(Point(a1),Point(a2),Point(a3),Point(a4));
t3 = torsion(Point(a2),Point(a3),Point(a4),Point(a5));
t4 = torsion(Point(a3),Point(a4),Point(a5),Point(a1));
t5 = torsion(Point(a4),Point(a5),Point(a1),Point(a2));
#if 0
printf("%4d %4d %4d %4d %4d\n",a1,a2,a3,a4,a5);
printf("%10.3f %10.3f %10.3f %10.3f %10.3f\n",t1,t2,t3,t4,t5);
printf("%10.3f %10.3f %10.3f %10.3f %10.3f\n",T1,T2,T3,T4,T5);
#endif
if (fabs(t1) < 7.0)
{
bond = get_bond_number(mol,a1,a2);
Bond_order(bond) = 1;
ratio = get_bond_ratio(mol,a1,a2);
if (ratio < SINGLE_DOUBLE_CUTOFF)
Bond_order(bond) = 2;
}
if (fabs(t2) < 7.0)
{
bond = get_bond_number(mol,a2,a3);
Bond_order(bond) = 1;
ratio = get_bond_ratio(mol,a2,a3);
if (ratio < SINGLE_DOUBLE_CUTOFF)
Bond_order(bond) = 2;
}
if (fabs(t3) < 7.0)
{
bond = get_bond_number(mol,a3,a4);
Bond_order(bond) = 1;
ratio = get_bond_ratio(mol,a3,a4);
if (ratio < SINGLE_DOUBLE_CUTOFF)
Bond_order(bond) = 2;
}
if (fabs(t3) < 7.0)
{
bond = get_bond_number(mol,a4,a5);
Bond_order(bond) = 1;
ratio = get_bond_ratio(mol,a4,a5);
if (ratio < SINGLE_DOUBLE_CUTOFF)
Bond_order(bond) = 2;
}
if (fabs(t3) < 7.0)
{
bond = get_bond_number(mol,a5,a1);
Bond_order(bond) = 1;
ratio = get_bond_ratio(mol,a5,a1);
if (ratio < SINGLE_DOUBLE_CUTOFF)
Bond_order(bond) = 2;
}
}
/*-----------------------------------------------
Testing functions for validating bond order assignments
------------------------------------------------*/
void print_bo(ums_type *mol)
{
int i;
for (i = 0; i < Bonds; i++)
printf("%4d - %4d %4d %4d\n",i,Start(i),End(i),Bond_order(i));
}
void reset_bonds(ums_type *mol, int *temp_bo)
{
int i;
for (i = 0; i < Bonds; i++)
Bond_order(i) = temp_bo[i];
}
void save_bond_orders(ums_type *mol, int *temp_bo)
{
int i;
for (i = 0; i < Bonds; i++)
temp_bo[i] = Bond_order(i);
}
int check_bond_order(ums_type *mol)
{
int mdl_count[4] = {0,0,0,0};
int babel_count[4] = {0,0,0,0};
int i;
for (i = 0; i < Bonds; i++)
{
mdl_count[Bond_order(i)]++;
Bond_order(i) = 1;
}
assign_bond_order2(mol);
for (i = 0; i < Bonds; i++)
{
babel_count[Bond_order(i)]++;
}
for (i = 1; i <= 3; i++)
{
if (mdl_count[i] != babel_count[i])
return(FALSE);
}
return(TRUE);
}
double torsion_angle(coord_type a, coord_type b, coord_type c, coord_type d)
{
vect_type c1,c2,c3,c4;
vect_type v1,v2,v3, p,q;
double xtheta, theta, absth, s;
int done = FALSE;
point_to_vect(a,&c1);
point_to_vect(b,&c2);
point_to_vect(c,&c3);
point_to_vect(d,&c4);
vect_diff(&c1,&c2,&v1);
vect_diff(&c2,&c3,&v2);
vect_diff(&c3,&c4,&v3);
cross_prod(&v2,&v1,&p);
cross_prod(&v3,&v2,&q);
normalize_vect(&p);
normalize_vect(&q);
xtheta = dot(&p,&q);
if (xtheta > 1.0)
xtheta = 1.0;
if (xtheta < -1.0)
xtheta = -1.0;
theta = acos(xtheta);
theta *= 57.29578;
absth = fabs(theta);
if (absth < 0.001)
{
done = TRUE;
theta = 0.0;
}
else if (fabs(absth - 180.0) < 0.001)
{
done = TRUE;
theta = 180.0;
}
if (!done)
{
s = dot(&v1,&q);
if (s < 0.0)
theta = 360.0 - theta;
}
if (theta > 180.0)
theta -= 360.0;
return(theta);
}
/*-------------------------------------
dearomatize - turn a ums with aromatic bonds
into a ums with single and double bonds
Inputs:
mol - a ums
-------------------------------------*/
void dearomatize(ums_type *mol)
{
int *dots;
bnd_stack stk;
int i;
dots = (int *)malloc((Atoms + 1) * sizeof(int));
stk.bond = (int *)malloc((Bonds) * sizeof(int));
stk.choice = (int *)malloc((Bonds) * sizeof(int));
for (i = 1; i <= Atoms; i++)
dots[i] = 0;
for (i = 0; i < Bonds; i++)
{
if (Bond_order(i) == 5)
{
Bond_order(i) = 1;
dots[Start(i)] = 1;
dots[End(i)] = 1;
}
}
/*
for (i = 1; i <= Atoms; i++)
{
if (EQ(Type(i),"Car") || EQ(Type(i),"Nar"))
dots[i] = 1;
else
dots[i] = 0;
}
for (i = 1; i <= Atoms; i++)
printf("%d %s %d\n",i,Type(i),dots[i]);
*/
stk.ptr = 0;
connect_the_dots(mol,1,0,dots,&stk);
for (i = 1; i <= stk.ptr; i++)
{
Bond_order(stk.bond[i]) = 2;
}
dissect_connection_table(mol);
if (dots)
free(dots);
if (stk.bond)
free(stk.bond);
if (stk.choice)
free(stk.choice);
}
int has_aromatic_bonds(ums_type *mol)
{
int i;
for (i = 0; i < Bonds; i++)
{
if (Bond_order(i) == 5)
return(TRUE);
}
return(FALSE);
}
|