4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_hizzie_c
= "$Id$";
41 static int in_strings(char *key
,int nstr
,char **str
)
45 for(j
=0; (j
<nstr
); j
++)
46 if (strcmp(str
[j
],key
) == 0)
52 static bool hbond(rvec x
[],int i
,int j
,real distance
)
54 real tol
= distance
*distance
;
57 rvec_sub(x
[i
],x
[j
],tmp
);
59 return (iprod(tmp
,tmp
) < tol
);
62 static void chk_allhb(t_atoms
*pdba
,rvec x
[],t_block
*hb
,
63 bool donor
[],bool accept
[],real dist
)
68 snew(hb
->index
,natom
+1);
75 for(i
=0; (i
<natom
); i
++) {
77 for(j
=i
+1; (j
<natom
); j
++)
78 if ((accept
[j
]) && (hbond(x
,i
,j
,dist
)))
82 for(j
=i
+1; (j
<natom
); j
++)
83 if ((donor
[j
]) && (hbond(x
,i
,j
,dist
)))
91 static void pr_hbonds(FILE *fp
,t_block
*hb
,t_atoms
*pdba
)
95 fprintf(fp
,"Dumping all hydrogen bonds!\n");
96 for(i
=0; (i
<hb
->nr
); i
++) {
99 for(j
=j0
; (j
<j1
); j
++) {
101 fprintf(fp
,"%5s%4d%5s - %5s%4d%5s\n",
102 *pdba
->resname
[pdba
->atom
[i
].resnr
],
103 pdba
->atom
[i
].resnr
+1,*pdba
->atomname
[i
],
104 *pdba
->resname
[pdba
->atom
[k
].resnr
],
105 pdba
->atom
[k
].resnr
+1,*pdba
->atomname
[k
]);
110 static bool chk_hbonds(int i
,t_atoms
*pdba
, rvec x
[],
111 bool ad
[],bool hbond
[],rvec xh
,
112 real angle
,real dist
)
121 ri
= pdba
->atom
[i
].resnr
;
123 for(j
=0; (j
<natom
); j
++) {
124 /* Check whether the other atom is a donor/acceptor and not i */
125 if ((ad
[j
]) && (j
!= i
)) {
126 /* Check whether the other atom is on the same ring as well */
127 if ((pdba
->atom
[j
].resnr
!= ri
) ||
128 ((strcmp(*pdba
->atomname
[j
],"ND1") != 0) &&
129 (strcmp(*pdba
->atomname
[j
],"NE2") != 0))) {
131 d2
= distance2(x
[i
],x
[j
]);
132 rvec_sub(x
[i
],xh
,nh
);
133 rvec_sub(x
[aj
],xh
,oh
);
134 a
= RAD2DEG
* acos(cos_angle(nh
,oh
));
135 if ((d2
< dist2
) && (a
> angle
)) {
138 "HBOND between %s%d-%s and %s%d-%s is %g nm, %g deg\n",
139 *pdba
->resname
[pdba
->atom
[i
].resnr
],
140 pdba
->atom
[i
].resnr
+1, *pdba
->atomname
[i
],
141 *pdba
->resname
[pdba
->atom
[aj
].resnr
],
142 pdba
->atom
[aj
].resnr
+1,*pdba
->atomname
[aj
],sqrt(d2
),a
);
152 static void calc_ringh(rvec xattach
,rvec xb
,rvec xc
,rvec xh
)
157 /* Add a proton on a ring to atom attach at distance 0.1 nm */
158 rvec_sub(xattach
,xb
,tab
);
159 rvec_sub(xattach
,xc
,tac
);
160 rvec_add(tab
,tac
,xh
);
163 rvec_inc(xh
,xattach
);
166 void set_histp(t_atoms
*pdba
,rvec
*x
,real angle
,real dist
){
167 static char *prot_acc
[] = {
168 "O", "OD1", "OD2", "OE1", "OE2", "OG", "OG1", "OH", "OW"
170 #define NPA asize(prot_acc)
171 static char *prot_don
[] = {
172 "N", "NH1", "NH2", "NE", "ND1", "ND2", "NE2", "NZ", "OG", "OG1", "OH", "NE1", "OW"
174 #define NPD asize(prot_don)
176 bool *donor
,*acceptor
;
177 bool *hbond
,bHaveH
=FALSE
;
181 int i
,j
,nd
,na
,aj
,hisnr
,his0
,type
=-1;
182 int nd1
,ne2
,cg
,cd2
,ce1
;
189 snew(acceptor
,natom
);
194 for(i
=0; (i
<natom
); i
++) {
195 if (in_strings(*pdba
->atomname
[i
],NPA
,prot_acc
) != -1) {
199 if (in_strings(*pdba
->atomname
[i
],NPD
,prot_don
) != -1) {
204 fprintf(stderr
,"There are %d donors and %d acceptors\n",nd
,na
);
205 chk_allhb(pdba
,x
,hb
,donor
,acceptor
,dist
);
207 pr_hbonds(debug
,hb
,pdba
);
208 fprintf(stderr
,"There are %d hydrogen bonds\n",hb
->nra
);
210 /* Now do the HIS stuff */
212 for(i
=0; (i
<natom
); ) {
213 if (strcasecmp(*pdba
->resname
[pdba
->atom
[i
].resnr
],"HIS") != 0)
216 if (pdba
->atom
[i
].resnr
!= hisnr
) {
217 hisnr
=pdba
->atom
[i
].resnr
;
219 /* Find the atoms in the ring */
220 nd1
=ne2
=cg
=cd2
=ce1
=-1;
221 for(j
=i
; (pdba
->atom
[j
].resnr
==hisnr
) && (j
<natom
); j
++) {
222 atomnm
=*pdba
->atomname
[j
];
223 if (strcmp(atomnm
,"CD2") == 0)
225 else if (strcmp(atomnm
,"CG") == 0)
227 else if (strcmp(atomnm
,"CE1") == 0)
229 else if (strcmp(atomnm
,"ND1") == 0)
231 else if (strcmp(atomnm
,"NE2") == 0)
235 if (!((cg
== -1 ) || (cd2
== -1) || (ce1
== -1) ||
236 (nd1
== -1) || (ne2
== -1))) {
237 calc_ringh(x
[nd1
],x
[cg
],x
[ce1
],xh1
);
238 calc_ringh(x
[ne2
],x
[ce1
],x
[cd2
],xh2
);
240 bHDd
= chk_hbonds(nd1
,pdba
,x
,acceptor
,hbond
,xh1
,angle
,dist
);
241 chk_hbonds(nd1
,pdba
,x
,donor
,hbond
,xh1
,angle
,dist
);
242 bHEd
= chk_hbonds(ne2
,pdba
,x
,acceptor
,hbond
,xh2
,angle
,dist
);
243 chk_hbonds(ne2
,pdba
,x
,donor
,hbond
,xh2
,angle
,dist
);
253 fprintf(stderr
,"Will use %s for residue %d\n",hh
[type
],hisnr
+1);
256 fatal_error(0,"Incomplete ring in HIS%d",hisnr
+1);
258 sfree(*pdba
->resname
[hisnr
]);
259 *pdba
->resname
[hisnr
]=strdup(hh
[type
]);