3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
48 #include "gmx_fatal.h"
50 #include "gpp_nextnb.h"
63 #include "gen_vsite.h"
67 /* this must correspond to enum in pdb2top.h */
68 const char *hh
[ehisNR
] = { "HISA", "HISB", "HISH", "HIS1" };
70 static int missing_atoms(t_restp
*rp
, int resind
,
71 t_atoms
*at
, int i0
, int i
, bool bCTer
)
78 for (j
=0; j
<rp
->natom
; j
++) {
79 name
=*(rp
->atomname
[j
]);
80 /* if ((name[0]!='H') && (name[0]!='h') && (!bCTer || (name[0]!='O'))) { */
83 bFound
=(bFound
|| !strcasecmp(*(at
->atomname
[k
]),name
));
86 fprintf(stderr
,"\nWARNING: "
87 "atom %s is missing in residue %s %d in the pdb file\n",
88 name
,*(at
->resinfo
[resind
].name
),at
->resinfo
[resind
].nr
);
89 if (name
[0]=='H' || name
[0]=='h')
90 fprintf(stderr
," You might need to add atom %s to the hydrogen database of residue %s\n"
91 " in the file ff???.hdb (see the manual)\n",
92 name
,*(at
->resinfo
[resind
].name
));
101 bool is_int(double x
)
103 const double tol
= 1e-4;
110 return (fabs(x
-ix
) < tol
);
113 typedef struct { char *desc
,*fn
; } t_fff
;
116 choose_ff(char *forcefield
, int maxlen
)
121 char *c
,buf
[STRLEN
],fn
[32];
124 in
=libopen("FF.dat");
126 sscanf(buf
,"%d",&nff
);
128 for(i
=0; (i
<nff
); i
++) {
131 fff
[i
].fn
=strdup(fn
);
132 /* Search for next non-space character, there starts description */
133 c
=&(buf
[strlen(fn
)+1]);
134 while (isspace(*c
)) c
++;
135 fff
[i
].desc
=strdup(c
);
140 printf("\nSelect the Force Field:\n");
141 for(i
=0; (i
<nff
); i
++)
142 printf("%2d: %s\n",i
,fff
[i
].desc
);
144 pret
= fgets(buf
,STRLEN
,stdin
);
147 sscanf(buf
,"%d",&sel
);
148 } while ( pret
==NULL
|| (sel
< 0) || (sel
>= nff
));
153 strncpy(forcefield
,fff
[sel
].fn
,maxlen
);
155 for(i
=0; (i
<nff
); i
++) {
164 static int name2type(t_atoms
*at
, int **cgnr
, gpp_atomtype_t atype
,
167 int i
,j
,prevresind
,resind
,i0
,prevcg
,cg
,curcg
;
186 aan
= get_aa_names();
188 for(i
=0; (i
<at
->nr
); i
++) {
190 if (at
->atom
[i
].resind
!= resind
) {
191 resind
= at
->atom
[i
].resind
;
192 bProt
= is_protein(aan
,*(at
->resinfo
[resind
].name
));
193 bNterm
=bProt
&& (resind
== 0);
196 missing_atoms(&restp
[prevresind
],prevresind
,at
,i0
,i
,
197 (!bProt
&& is_protein(aan
,restp
[prevresind
].resname
)));
200 if (at
->atom
[i
].m
== 0) {
202 fprintf(debug
,"atom %d%s: curcg=%d, prevcg=%d, cg=%d\n",
203 i
+1,*(at
->atomname
[i
]),curcg
,prevcg
,
204 j
==NOTSET
? NOTSET
: restp
[resind
].cgnr
[j
]);
207 name
=*(at
->atomname
[i
]);
208 j
=search_jtype(&restp
[resind
],name
,bNterm
);
209 at
->atom
[i
].type
= restp
[resind
].atom
[j
].type
;
210 at
->atom
[i
].q
= restp
[resind
].atom
[j
].q
;
211 at
->atom
[i
].m
= get_atomtype_massA(restp
[resind
].atom
[j
].type
,
213 cg
= restp
[resind
].cgnr
[j
];
214 if ( (cg
!= prevcg
) || (resind
!= prevresind
) )
218 fprintf(debug
,"atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
219 i
+1,*(at
->atomname
[i
]),curcg
,qt
,is_int(qt
));
228 at
->atom
[i
].typeB
= at
->atom
[i
].type
;
229 at
->atom
[i
].qB
= at
->atom
[i
].q
;
230 at
->atom
[i
].mB
= at
->atom
[i
].m
;
232 nmissat
+= missing_atoms(&restp
[resind
],resind
,at
,i0
,i
,
233 (!bProt
|| is_protein(aan
,restp
[resind
].resname
)));
239 static void print_top_heavy_H(FILE *out
, real mHmult
)
242 fprintf(out
,"; Using deuterium instead of hydrogen\n\n");
243 else if (mHmult
== 4.0)
244 fprintf(out
,"#define HEAVY_H\n\n");
245 else if (mHmult
!= 1.0)
246 fprintf(stderr
,"WARNING: unsupported proton mass multiplier (%g) "
247 "in pdb2top\n",mHmult
);
250 void print_top_comment(FILE *out
,const char *filename
,const char *title
,bool bITP
)
254 nice_header(out
,filename
);
255 fprintf(out
,";\tThis is your %stopology file\n",bITP
? "include " : "");
256 cool_quote(tmp
,255,NULL
);
257 fprintf(out
,";\t%s\n",title
[0]?title
:tmp
);
261 void print_top_header(FILE *out
,const char *filename
,
262 const char *title
,bool bITP
,const char *ff
,real mHmult
)
264 print_top_comment(out
,filename
,title
,bITP
);
266 print_top_heavy_H(out
, mHmult
);
267 fprintf(out
,"; Include forcefield parameters\n");
268 fprintf(out
,"#include \"%s.itp\"\n\n",ff
);
271 static void print_top_posre(FILE *out
,const char *pr
)
273 fprintf(out
,"; Include Position restraint file\n");
274 fprintf(out
,"#ifdef POSRES\n");
275 fprintf(out
,"#include \"%s\"\n",pr
);
276 fprintf(out
,"#endif\n\n");
279 static void print_top_water(FILE *out
,const char *water
)
281 fprintf(out
,"; Include water topology\n");
282 fprintf(out
,"#include \"%s.itp\"\n",water
);
284 fprintf(out
,"#ifdef POSRES_WATER\n");
285 fprintf(out
,"; Position restraint for each water oxygen\n");
286 fprintf(out
,"[ position_restraints ]\n");
287 fprintf(out
,";%3s %5s %9s %10s %10s\n","i","funct","fcx","fcy","fcz");
288 fprintf(out
,"%4d %4d %10g %10g %10g\n",1,1,1000.0,1000.0,1000.0);
289 fprintf(out
,"#endif\n\n");
290 fprintf(out
,"; Include generic topology for ions\n");
291 fprintf(out
,"#include \"ions.itp\"\n");
295 static void print_top_system(FILE *out
, const char *title
)
297 fprintf(out
,"[ %s ]\n",dir2str(d_system
));
298 fprintf(out
,"; Name\n");
299 fprintf(out
,"%s\n\n",title
[0]?title
:"Protein");
302 void print_top_mols(FILE *out
, const char *title
, const char *water
,
303 int nincl
, char **incls
, int nmol
, t_mols
*mols
)
308 fprintf(out
,"; Include chain topologies\n");
309 for (i
=0; (i
<nincl
); i
++)
310 fprintf(out
,"#include \"%s\"\n",incls
[i
]);
315 print_top_water(out
,water
);
316 print_top_system(out
, title
);
319 fprintf(out
,"[ %s ]\n",dir2str(d_molecules
));
320 fprintf(out
,"; %-15s %5s\n","Compound","#mols");
321 for (i
=0; (i
<nmol
); i
++)
322 fprintf(out
,"%-15s %5d\n",mols
[i
].name
,mols
[i
].nr
);
326 void write_top(FILE *out
, char *pr
,char *molname
,
327 t_atoms
*at
,int bts
[],t_params plist
[],t_excls excls
[],
328 gpp_atomtype_t atype
,int *cgnr
, int nrexcl
)
329 /* NOTE: nrexcl is not the size of *excl! */
331 if (at
&& atype
&& cgnr
) {
332 fprintf(out
,"[ %s ]\n",dir2str(d_moleculetype
));
333 fprintf(out
,"; %-15s %5s\n","Name","nrexcl");
334 fprintf(out
,"%-15s %5d\n\n",molname
?molname
:"Protein",nrexcl
);
336 print_atoms(out
, atype
, at
, cgnr
);
337 print_bondeds(out
,at
->nr
,d_bonds
, F_BONDS
, bts
[ebtsBONDS
], plist
);
338 print_bondeds(out
,at
->nr
,d_constraints
,F_CONSTR
, 0, plist
);
339 print_bondeds(out
,at
->nr
,d_constraints
,F_CONSTRNC
, 0, plist
);
340 print_bondeds(out
,at
->nr
,d_pairs
, F_LJ14
, 0, plist
);
341 print_excl(out
,at
->nr
,excls
);
342 print_bondeds(out
,at
->nr
,d_angles
, F_ANGLES
, bts
[ebtsANGLES
],plist
);
343 print_bondeds(out
,at
->nr
,d_dihedrals
, F_PDIHS
, bts
[ebtsPDIHS
], plist
);
344 print_bondeds(out
,at
->nr
,d_dihedrals
, F_IDIHS
, bts
[ebtsIDIHS
], plist
);
345 print_bondeds(out
,at
->nr
,d_cmap
, F_CMAP
, bts
[ebtsCMAP
], plist
);
346 print_bondeds(out
,at
->nr
,d_polarization
,F_POLARIZATION
, 0, plist
);
347 print_bondeds(out
,at
->nr
,d_thole_polarization
,F_THOLE_POL
,0, plist
);
348 print_bondeds(out
,at
->nr
,d_vsites2
, F_VSITE2
, 0, plist
);
349 print_bondeds(out
,at
->nr
,d_vsites3
, F_VSITE3
, 0, plist
);
350 print_bondeds(out
,at
->nr
,d_vsites3
, F_VSITE3FD
, 0, plist
);
351 print_bondeds(out
,at
->nr
,d_vsites3
, F_VSITE3FAD
,0, plist
);
352 print_bondeds(out
,at
->nr
,d_vsites3
, F_VSITE3OUT
,0, plist
);
353 print_bondeds(out
,at
->nr
,d_vsites4
, F_VSITE4FD
, 0, plist
);
354 print_bondeds(out
,at
->nr
,d_vsites4
, F_VSITE4FDN
, 0, plist
);
357 print_top_posre(out
,pr
);
361 static atom_id
search_res_atom(const char *type
,int resind
,
362 int natom
,t_atom at
[],
363 char ** const *aname
,
364 const char *bondtype
,bool bMissing
)
368 for(i
=0; (i
<natom
); i
++)
369 if (at
[i
].resind
== resind
)
370 return search_atom(type
,i
,natom
,at
,aname
,bondtype
,bMissing
);
375 static void do_ssbonds(t_params
*ps
,int natoms
,t_atom atom
[],char **aname
[],
376 int nssbonds
,t_ssbond
*ssbonds
,bool bMissing
)
381 for(i
=0; (i
<nssbonds
); i
++) {
382 ri
= ssbonds
[i
].res1
;
383 rj
= ssbonds
[i
].res2
;
384 ai
= search_res_atom(ssbonds
[i
].a1
,ri
,natoms
,atom
,aname
,
385 "special bond",bMissing
);
386 aj
= search_res_atom(ssbonds
[i
].a2
,rj
,natoms
,atom
,aname
,
387 "special bond",bMissing
);
388 if ((ai
== NO_ATID
) || (aj
== NO_ATID
))
389 gmx_fatal(FARGS
,"Trying to make impossible special bond (%s-%s)!",
390 ssbonds
[i
].a1
,ssbonds
[i
].a2
);
391 add_param(ps
,ai
,aj
,NULL
,NULL
);
395 static void at2bonds(t_params
*psb
, t_hackblock
*hb
,
396 int natoms
, t_atom atom
[], char **aname
[],
398 real long_bond_dist
, real short_bond_dist
)
402 real dist2
, long_bond_dist2
, short_bond_dist2
;
405 long_bond_dist2
= sqr(long_bond_dist
);
406 short_bond_dist2
= sqr(short_bond_dist
);
413 fprintf(stderr
,"Making bonds...\n");
415 for(resind
=0; (resind
< nres
) && (i
<natoms
); resind
++) {
416 /* add bonds from list of bonded interactions */
417 for(j
=0; j
< hb
[resind
].rb
[ebtsBONDS
].nb
; j
++) {
418 /* Unfortunately we can not issue errors or warnings
419 * for missing atoms in bonds, as the hydrogens and terminal atoms
420 * have not been added yet.
422 ai
=search_atom(hb
[resind
].rb
[ebtsBONDS
].b
[j
].AI
,i
,natoms
,atom
,aname
,
424 aj
=search_atom(hb
[resind
].rb
[ebtsBONDS
].b
[j
].AJ
,i
,natoms
,atom
,aname
,
426 if (ai
!= NO_ATID
&& aj
!= NO_ATID
) {
427 dist2
= distance2(x
[ai
],x
[aj
]);
428 if (dist2
> long_bond_dist2
)
429 fprintf(stderr
,"Warning: Long Bond (%d-%d = %g nm)\n",
430 ai
+1,aj
+1,sqrt(dist2
));
431 else if (dist2
< short_bond_dist2
)
432 fprintf(stderr
,"Warning: Short Bond (%d-%d = %g nm)\n",
433 ai
+1,aj
+1,sqrt(dist2
));
434 add_param(psb
,ai
,aj
,NULL
,hb
[resind
].rb
[ebtsBONDS
].b
[j
].s
);
437 /* add bonds from list of hacks (each added atom gets a bond) */
438 while( (i
<natoms
) && (atom
[i
].resind
== resind
) ) {
439 for(j
=0; j
< hb
[resind
].nhack
; j
++)
440 if ( ( hb
[resind
].hack
[j
].tp
> 0 ||
441 hb
[resind
].hack
[j
].oname
==NULL
) &&
442 strcmp(hb
[resind
].hack
[j
].AI
,*(aname
[i
])) == 0 ) {
443 switch(hb
[resind
].hack
[j
].tp
) {
444 case 9: /* COOH terminus */
445 add_param(psb
,i
,i
+1,NULL
,NULL
); /* C-O */
446 add_param(psb
,i
,i
+2,NULL
,NULL
); /* C-OA */
447 add_param(psb
,i
+2,i
+3,NULL
,NULL
); /* OA-H */
450 for(k
=0; (k
<hb
[resind
].hack
[j
].nr
); k
++)
451 add_param(psb
,i
,i
+k
+1,NULL
,NULL
);
456 /* we're now at the start of the next residue */
460 static int pcompar(const void *a
, const void *b
)
471 return strlen(pb
->s
) - strlen(pa
->s
);
476 static void clean_bonds(t_params
*ps
)
482 /* swap atomnumbers in bond if first larger than second: */
483 for(i
=0; (i
<ps
->nr
); i
++)
484 if ( ps
->param
[i
].AJ
< ps
->param
[i
].AI
) {
486 ps
->param
[i
].AI
= ps
->param
[i
].AJ
;
491 qsort(ps
->param
,ps
->nr
,(size_t)sizeof(ps
->param
[0]),pcompar
);
493 /* remove doubles, keep the first one always. */
495 for(i
=1; (i
<ps
->nr
); i
++) {
496 if ((ps
->param
[i
].AI
!= ps
->param
[j
-1].AI
) ||
497 (ps
->param
[i
].AJ
!= ps
->param
[j
-1].AJ
) ) {
498 cp_param(&(ps
->param
[j
]),&(ps
->param
[i
]));
502 fprintf(stderr
,"Number of bonds was %d, now %d\n",ps
->nr
,j
);
506 fprintf(stderr
,"No bonds\n");
509 void print_sums(t_atoms
*atoms
, bool bSystem
)
522 for(i
=0; (i
<atoms
->nr
); i
++) {
524 qtot
+=atoms
->atom
[i
].q
;
527 fprintf(stderr
,"Total mass%s %.3f a.m.u.\n",where
,m
);
528 fprintf(stderr
,"Total charge%s %.3f e\n",where
,qtot
);
531 static void get_hackblocks_rtp(t_hackblock
**hb
, t_restp
**restp
,
532 int nrtp
, t_restp rtp
[],
533 int nres
, t_resinfo
*resinfo
,
535 t_hackblock
**ntdb
, t_hackblock
**ctdb
,
541 const char *Hnum
="123456";
546 /* first the termini */
547 for(i
=0; i
<nterpairs
; i
++) {
549 copy_t_hackblock(ntdb
[i
], &(*hb
)[rn
[i
]]);
551 merge_t_hackblock(ctdb
[i
], &(*hb
)[rc
[i
]]);
554 /* then the whole rtp */
555 for(i
=0; i
< nres
; i
++) {
556 res
= search_rtp(*resinfo
[i
].name
,nrtp
,rtp
);
557 copy_t_restp(res
, &(*restp
)[i
]);
559 for(j
=0; j
<nterpairs
&& !bN
; j
++)
562 for(j
=0; j
<nterpairs
&& !bC
; j
++)
564 merge_t_bondeds(res
->rb
, (*hb
)[i
].rb
,bN
,bC
);
567 /* now perform t_hack's on t_restp's,
568 i.e. add's and deletes from termini database will be
569 added to/removed from residue topology
570 we'll do this on one big dirty loop, so it won't make easy reading! */
571 for(i
=0; i
< nres
; i
++)
572 for(j
=0; j
< (*hb
)[i
].nhack
; j
++)
573 if ( (*hb
)[i
].hack
[j
].nr
) {
574 /* find atom in restp */
575 for(l
=0; l
< (*restp
)[i
].natom
; l
++)
576 if ( ( (*hb
)[i
].hack
[j
].oname
==NULL
&&
577 strcmp((*hb
)[i
].hack
[j
].AI
, *(*restp
)[i
].atomname
[l
])==0 ) ||
578 ( (*hb
)[i
].hack
[j
].oname
!=NULL
&&
579 strcmp((*hb
)[i
].hack
[j
].oname
,*(*restp
)[i
].atomname
[l
])==0 ) )
581 if (l
== (*restp
)[i
].natom
)
582 gmx_fatal(FARGS
,"atom %s not found in residue %d%s "
583 "while combining tdb and rtp",
584 (*hb
)[i
].hack
[j
].oname
!=NULL
?
585 (*hb
)[i
].hack
[j
].oname
: (*hb
)[i
].hack
[j
].AI
,
586 i
+1,*resinfo
[i
].name
);
587 if ( (*hb
)[i
].hack
[j
].oname
==NULL
) {
590 fprintf(debug
,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
591 (*hb
)[i
].hack
[j
].nname
,
592 *(*restp
)[i
].atomname
[l
], i
+1, (*restp
)[i
].resname
);
593 strcpy(buf
, (*hb
)[i
].hack
[j
].nname
);
594 buf
[strlen(buf
)+1]='\0';
595 if ( (*hb
)[i
].hack
[j
].nr
> 1 )
596 buf
[strlen(buf
)]='-';
598 (*restp
)[i
].natom
+= (*hb
)[i
].hack
[j
].nr
;
599 srenew((*restp
)[i
].atom
, (*restp
)[i
].natom
);
600 srenew((*restp
)[i
].atomname
, (*restp
)[i
].natom
);
601 srenew((*restp
)[i
].cgnr
, (*restp
)[i
].natom
);
603 for(k
=(*restp
)[i
].natom
-1; k
> l
+(*hb
)[i
].hack
[j
].nr
; k
--) {
604 (*restp
)[i
].atom
[k
] =
605 (*restp
)[i
].atom
[k
- (*hb
)[i
].hack
[j
].nr
];
606 (*restp
)[i
].atomname
[k
] =
607 (*restp
)[i
].atomname
[k
- (*hb
)[i
].hack
[j
].nr
];
608 (*restp
)[i
].cgnr
[k
] =
609 (*restp
)[i
].cgnr
[k
- (*hb
)[i
].hack
[j
].nr
];
612 for(k
=0; k
< (*hb
)[i
].hack
[j
].nr
; k
++) {
613 /* set counter in atomname */
614 if ( (*hb
)[i
].hack
[j
].nr
> 1 )
615 buf
[strlen(buf
)-1]=Hnum
[k
];
616 snew( (*restp
)[i
].atomname
[l
+1+k
], 1);
617 (*restp
)[i
].atom
[l
+1+k
] = *(*hb
)[i
].hack
[j
].atom
;
618 *(*restp
)[i
].atomname
[l
+1+k
] = strdup(buf
);
619 if ( (*hb
)[i
].hack
[j
].cgnr
!= NOTSET
)
620 (*restp
)[i
].cgnr
[l
+1+k
] = (*hb
)[i
].hack
[j
].cgnr
;
622 (*restp
)[i
].cgnr
[l
+1+k
] = (*restp
)[i
].cgnr
[l
];
624 } else /* oname != NULL */
625 if ( (*hb
)[i
].hack
[j
].nname
==NULL
) {
628 fprintf(debug
, "deleting atom %s from res %d%s in rtp\n",
629 *(*restp
)[i
].atomname
[l
],
630 i
+1,(*restp
)[i
].resname
);
633 for(k
=l
; k
< (*restp
)[i
].natom
; k
++) {
634 (*restp
)[i
].atom
[k
] = (*restp
)[i
].atom
[k
+1];
635 (*restp
)[i
].atomname
[k
] = (*restp
)[i
].atomname
[k
+1];
636 (*restp
)[i
].cgnr
[k
] = (*restp
)[i
].cgnr
[k
+1];
638 /* give back space */
639 srenew((*restp
)[i
].atom
, (*restp
)[i
].natom
);
640 srenew((*restp
)[i
].atomname
, (*restp
)[i
].natom
);
641 srenew((*restp
)[i
].cgnr
, (*restp
)[i
].natom
);
642 } else { /* nname != NULL */
643 /* we're replacing */
645 fprintf(debug
, "replacing atom %s by %s in res %d%s in rtp\n",
646 *(*restp
)[i
].atomname
[l
], (*hb
)[i
].hack
[j
].nname
,
647 i
+1,(*restp
)[i
].resname
);
648 snew( (*restp
)[i
].atomname
[l
], 1);
649 (*restp
)[i
].atom
[l
] = *(*hb
)[i
].hack
[j
].atom
;
650 *(*restp
)[i
].atomname
[l
] = strdup((*hb
)[i
].hack
[j
].nname
);
651 if ( (*hb
)[i
].hack
[j
].cgnr
!= NOTSET
)
652 (*restp
)[i
].cgnr
[l
] = (*hb
)[i
].hack
[j
].cgnr
;
657 void gen_cmap(t_params
*psb
, t_restp
*restp
, int natoms
, t_atom atom
[], char **aname
[], int nres
)
660 atom_id ai
,aj
,ak
,al
,am
;
668 fprintf(stderr
,"Making cmap torsions...");
670 /* End loop at nres-1, since the very last residue does not have a +N atom, and
671 * therefore we get a valgrind invalid 4 byte read error with atom am */
672 for(residx
=0; residx
<nres
-1; residx
++)
674 /* Add CMAP terms from the list of CMAP interactions */
675 for(j
=0;j
<restp
[residx
].rb
[ebtsCMAP
].nb
; j
++)
677 ai
=search_atom(restp
[residx
].rb
[ebtsCMAP
].b
[j
].a
[0],i
,natoms
,atom
,aname
,
679 aj
=search_atom(restp
[residx
].rb
[ebtsCMAP
].b
[j
].a
[1],i
,natoms
,atom
,aname
,
681 ak
=search_atom(restp
[residx
].rb
[ebtsCMAP
].b
[j
].a
[2],i
,natoms
,atom
,aname
,
683 al
=search_atom(restp
[residx
].rb
[ebtsCMAP
].b
[j
].a
[3],i
,natoms
,atom
,aname
,
685 am
=search_atom(restp
[residx
].rb
[ebtsCMAP
].b
[j
].a
[4],i
,natoms
,atom
,aname
,
688 /* The first and last residues no not have cmap torsions */
689 if(ai
!=NO_ATID
&& aj
!=NO_ATID
&& ak
!=NO_ATID
&& al
!=NO_ATID
&& am
!=NO_ATID
)
691 add_cmap_param(psb
,ai
,aj
,ak
,al
,am
,0,0,restp
[residx
].rb
[ebtsCMAP
].b
[j
].s
);
697 while(atom
[i
].resind
<residx
+1)
704 /* Start the next residue */
708 scrub_charge_groups(int *cgnr
, int natoms
)
712 for(i
=0;i
<natoms
;i
++)
719 void pdb2top(FILE *top_file
, char *posre_fn
, char *molname
,
720 t_atoms
*atoms
, rvec
**x
, gpp_atomtype_t atype
, t_symtab
*tab
,
721 int bts
[], int nrtp
, t_restp rtp
[],
722 int nterpairs
,t_hackblock
**ntdb
, t_hackblock
**ctdb
,
723 int *rn
, int *rc
, bool bMissing
,
724 bool bH14
, bool bAlldih
, bool bRemoveDih
,
725 bool bVsites
, bool bVsiteAromatics
, char *ff
, real mHmult
,
726 int nssbonds
, t_ssbond
*ssbonds
, int nrexcl
,
727 real long_bond_dist
, real short_bond_dist
,
728 bool bDeuterate
, bool bChargeGroups
)
732 t_params plist
[F_NRE
];
741 /* lookup hackblocks and rtp for all residues */
742 get_hackblocks_rtp(&hb
, &restp
, nrtp
, rtp
, atoms
->nres
, atoms
->resinfo
,
743 nterpairs
, ntdb
, ctdb
, rn
, rc
);
744 /* ideally, now we would not need the rtp itself anymore, but do
745 everything using the hb and restp arrays. Unfortunately, that
746 requires some re-thinking of code in gen_vsite.c, which I won't
747 do now :( AF 26-7-99 */
750 print_resall(debug
, bts
, atoms
->nres
, restp
, atype
,bAlldih
,nrexcl
,
752 dump_hb(debug
, atoms
->nres
, hb
);
756 at2bonds(&(plist
[F_BONDS
]), hb
,
757 atoms
->nr
, atoms
->atom
, atoms
->atomname
, atoms
->nres
, *x
,
758 long_bond_dist
, short_bond_dist
);
760 /* specbonds: disulphide bonds & heme-his */
761 do_ssbonds(&(plist
[F_BONDS
]),
762 atoms
->nr
, atoms
->atom
, atoms
->atomname
, nssbonds
, ssbonds
,
765 nmissat
= name2type(atoms
, &cgnr
, atype
, restp
);
768 fprintf(stderr
,"There were %d missing atoms in molecule %s\n",
771 gmx_fatal(FARGS
,"There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
775 /* Cleanup bonds (sort and rm doubles) */
776 clean_bonds(&(plist
[F_BONDS
]));
778 snew(vsite_type
,atoms
->nr
);
779 for(i
=0; i
<atoms
->nr
; i
++)
780 vsite_type
[i
]=NOTSET
;
782 /* determine which atoms will be vsites and add dummy masses
783 also renumber atom numbers in plist[0..F_NRE]! */
784 do_vsites(nrtp
, rtp
, atype
, atoms
, tab
, x
, plist
,
785 &vsite_type
, &cgnr
, mHmult
, bVsiteAromatics
, ff
);
787 /* Make Angles and Dihedrals */
788 fprintf(stderr
,"Generating angles, dihedrals and pairs...\n");
789 snew(excls
,atoms
->nr
);
790 init_nnb(&nnb
,atoms
->nr
,4);
792 print_nnb(&nnb
,"NNB");
793 gen_pad(&nnb
,atoms
,nrexcl
,bH14
,plist
,excls
,hb
,bAlldih
,bRemoveDih
,bMissing
);
797 gen_cmap(&(plist
[F_CMAP
]), restp
, atoms
->nr
, atoms
->atom
, atoms
->atomname
, atoms
->nres
);
798 fprintf(stderr
, "there are %4d cmap torsions\n",plist
[F_CMAP
].nr
);
800 /* set mass of all remaining hydrogen atoms */
802 do_h_mass(&(plist
[F_BONDS
]),vsite_type
,atoms
,mHmult
,bDeuterate
);
805 /* Cleanup bonds (sort and rm doubles) */
806 /* clean_bonds(&(plist[F_BONDS]));*/
809 "There are %4d dihedrals, %4d impropers, %4d angles\n"
810 " %4d pairs, %4d bonds and %4d virtual sites\n",
811 plist
[F_PDIHS
].nr
, plist
[F_IDIHS
].nr
, plist
[F_ANGLES
].nr
,
812 plist
[F_LJ14
].nr
, plist
[F_BONDS
].nr
,
815 plist
[F_VSITE3FD
].nr
+
816 plist
[F_VSITE3FAD
].nr
+
817 plist
[F_VSITE3OUT
].nr
+
818 plist
[F_VSITE4FD
].nr
+
819 plist
[F_VSITE4FDN
].nr
);
821 print_sums(atoms
, FALSE
);
823 if (FALSE
== bChargeGroups
)
825 scrub_charge_groups(cgnr
, atoms
->nr
);
829 fprintf(stderr
,"Writing topology\n");
830 write_top(top_file
, posre_fn
, molname
,
831 atoms
, bts
, plist
, excls
, atype
, cgnr
, nrexcl
);
835 free_t_hackblock(atoms
->nres
, &hb
);
836 free_t_restp(atoms
->nres
, &restp
);
838 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
840 for (i
=0; i
<F_NRE
; i
++)
841 sfree(plist
[i
].param
);
842 for (i
=0; i
<atoms
->nr
; i
++)