changed reading hint
[gromacs/adressmacs.git] / src / kernel / specbond.c
blob003d3f7e65b44257d4d9e0cb205b73f2e64856aa
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 2.0
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
16 * Please refer to:
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
23 * or e-mail to:
24 * gromacs@chem.rug.nl
26 * And Hey:
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_specbond_c = "$Id$";
31 #include <ctype.h>
32 #include <math.h>
33 #include "typedefs.h"
34 #include "pdbio.h"
35 #include "strdb.h"
36 #include "string2.h"
37 #include "smalloc.h"
38 #include "specbond.h"
39 #include "pdb2top.h"
40 #include "vec.h"
42 bool yesno(void)
44 char c;
46 do {
47 c=toupper(fgetc(stdin));
48 } while ((c != 'Y') && (c != 'N'));
50 return (c == 'Y');
53 typedef struct {
54 char *res1, *res2;
55 char *atom1,*atom2;
56 char *nres1,*nres2;
57 int nbond1,nbond2;
58 real length;
59 } t_specbond;
61 static t_specbond *get_specbonds(int *nspecbond)
63 static char *sbfile="specbond.dat";
65 t_specbond *sb=NULL;
66 char r1buf[32],r2buf[32],a1buf[32],a2buf[32],nr1buf[32],nr2buf[32];
67 double length;
68 int nb1,nb2;
69 char **lines;
70 int nlines,i,n;
72 nlines = get_lines(sbfile,&lines);
73 if (nlines > 0)
74 snew(sb,nlines);
76 n = 0;
77 for(i=0; (i<nlines); i++) {
78 if (sscanf(lines[i],"%s%s%d%s%s%d%lf%s%s",
79 r1buf,a1buf,&nb1,r2buf,a2buf,&nb2,&length,nr1buf,nr2buf) != 9)
80 fprintf(stderr,"Invalid line '%s' in %s\n",lines[i],sbfile);
81 else {
82 sb[n].res1 = strdup(r1buf);
83 sb[n].res2 = strdup(r2buf);
84 sb[n].nres1 = strdup(nr1buf);
85 sb[n].nres2 = strdup(nr2buf);
86 sb[n].atom1 = strdup(a1buf);
87 sb[n].atom2 = strdup(a2buf);
88 sb[n].nbond1 = nb1;
89 sb[n].nbond2 = nb2;
90 sb[n].length = length;
91 n++;
93 sfree(lines[i]);
95 if (nlines > 0)
96 sfree(lines);
97 fprintf(stderr,"%d out of %d lines of %s converted succesfully\n",
98 n,nlines,sbfile);
100 *nspecbond = n;
102 return sb;
105 static void done_specbonds(int nsb,t_specbond sb[])
107 int i;
109 for(i=0; (i<nsb); i++) {
110 sfree(sb[i].res1);
111 sfree(sb[i].res2);
112 sfree(sb[i].atom1);
113 sfree(sb[i].atom2);
114 sfree(sb[i].nres1);
115 sfree(sb[i].nres2);
119 static bool is_special(int nsb,t_specbond sb[],char *res,char *atom)
121 int i;
123 for(i=0; (i<nsb); i++) {
124 if (((strcasecmp(sb[i].res1,res) == 0) &&
125 (strcasecmp(sb[i].atom1,atom) == 0)) ||
126 ((strcasecmp(sb[i].res2,res) == 0) &&
127 (strcasecmp(sb[i].atom2,atom) == 0)))
128 return TRUE;
130 return FALSE;
133 static bool is_bond(int nsb,t_specbond sb[],t_atoms *pdba,int a1,int a2,
134 real d,int *nb,bool *bSwap)
136 int i;
137 char *at1,*at2,*res1,*res2;
139 at1=*pdba->atomname[a1];
140 at2=*pdba->atomname[a2];
141 res1=*pdba->resname[pdba->atom[a1].resnr];
142 res2=*pdba->resname[pdba->atom[a2].resnr];
144 for(i=0; (i<nsb); i++) {
145 *nb = i;
146 if (((strcasecmp(sb[i].res1,res1) == 0) &&
147 (strcasecmp(sb[i].atom1,at1) == 0) &&
148 (strcasecmp(sb[i].res2,res2) == 0) &&
149 (strcasecmp(sb[i].atom2,at2) == 0))) {
150 *bSwap = FALSE;
151 if ((0.9*sb[i].length < d) && (1.1*sb[i].length > d))
152 return TRUE;
154 if (((strcasecmp(sb[i].res1,res2) == 0) &&
155 (strcasecmp(sb[i].atom1,at2) == 0) &&
156 (strcasecmp(sb[i].res2,res1) == 0) &&
157 (strcasecmp(sb[i].atom2,at1) == 0))) {
158 *bSwap = TRUE;
159 if ((0.9*sb[i].length < d) && (1.1*sb[i].length > d))
160 return TRUE;
163 return FALSE;
166 static void rename_1res(t_atoms *pdba,int resnr,char *nres)
168 sfree(*pdba->resname[resnr]);
169 *pdba->resname[resnr]=strdup(nres);
172 int mk_specbonds(t_atoms *pdba,rvec x[],bool bInteractive,
173 t_ssbond **specbonds)
175 t_specbond *sb=NULL;
176 t_ssbond *bonds=NULL;
177 int nsb,natoms;
178 int nspec,nbonds;
179 int *specp,*sgp;
180 bool bDoit,bSwap;
181 int i,j,b,e,e2;
182 int ai,aj,index_sb;
183 real **d;
184 char buf[10];
186 natoms=pdba->nr;
187 /* Initiate variables that will be exported */
188 nbonds = 0;
189 sb=get_specbonds(&nsb);
191 if (nsb > 0) {
192 snew(specp,natoms);
193 snew(sgp,natoms);
195 nspec = 0;
196 for(i=0;(i<natoms);i++) {
197 if (is_special(nsb,sb,*pdba->resname[pdba->atom[i].resnr],
198 *pdba->atomname[i])) {
199 specp[nspec] = pdba->atom[i].resnr;
200 sgp[nspec] = i;
201 nspec++;
204 srenew(specp,nspec);
205 srenew(sgp,nspec);
207 /* distance matrix d[nspec][nspec] */
208 snew(d,nspec);
209 for(i=0; (i<nspec); i++)
210 snew(d[i],nspec);
212 for(i=0; (i<nspec); i++) {
213 ai=sgp[i];
214 for(j=0; (j<nspec); j++) {
215 aj=sgp[j];
216 d[i][j]=sqrt(distance2(x[ai],x[aj]));
219 if (nspec > 1) {
220 #define MAXCOL 8
221 fprintf(stderr,"Special Atom Distance matrix:\n");
222 for(b=0; (b<nspec); b+=MAXCOL) {
223 fprintf(stderr,"%8s","");
224 e=min(b+MAXCOL, nspec-1);
225 for(i=b; (i<e); i++) {
226 sprintf(buf,"%s%d",*pdba->resname[pdba->atom[sgp[i]].resnr],
227 specp[i]+1);
228 fprintf(stderr,"%8s",buf);
230 fprintf(stderr,"\n");
231 e=min(b+MAXCOL, nspec);
232 for(i=b+1; (i<nspec); i++) {
233 sprintf(buf,"%s%d",*pdba->resname[pdba->atom[sgp[i]].resnr],
234 specp[i]+1);
235 fprintf(stderr,"%8s",buf);
236 e2=min(i,e);
237 for(j=b; (j<e2); j++)
238 fprintf(stderr," %7.3f",d[i][j]);
239 fprintf(stderr,"\n");
243 i=j=0;
245 snew(bonds,nspec/2);
247 for(i=0; (i<nspec); i++) {
248 ai = sgp[i];
249 for(j=i+1; (j<nspec); j++) {
250 aj = sgp[j];
251 if (is_bond(nsb,sb,pdba,ai,aj,d[i][j],
252 &index_sb,&bSwap)) {
253 if (bInteractive) {
254 fprintf(stderr,"Link Res%4d and Res%4d (y/n) ?",specp[i]+1,specp[j]+1);
255 bDoit=yesno();
257 else {
258 fprintf(stderr,"Linking Res%4d and Res%4d...\n",specp[i]+1,specp[j]+1);
259 bDoit=TRUE;
261 if (bDoit) {
262 /* Store the residue numbers in the bonds array */
263 bonds[nbonds].res1 = specp[i];
264 bonds[nbonds].res2 = specp[j];
265 bonds[nbonds].a1 = strdup(*pdba->atomname[ai]);
266 bonds[nbonds].a2 = strdup(*pdba->atomname[aj]);
267 if (bSwap) {
268 rename_1res(pdba,specp[i],sb[index_sb].nres2);
269 rename_1res(pdba,specp[j],sb[index_sb].nres1);
271 else {
272 rename_1res(pdba,specp[i],sb[index_sb].nres1);
273 rename_1res(pdba,specp[j],sb[index_sb].nres2);
275 nbonds++;
281 for(i=0; (i<nspec); i++)
282 sfree(d[i]);
283 sfree(d);
284 sfree(sgp);
285 sfree(specp);
287 done_specbonds(nsb,sb);
288 sfree(sb);
291 *specbonds=bonds;
293 return nbonds;