4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Gromacs Runs One Microsecond At Cannonball Speeds
32 static char *SRCID_cdist_c
= "$Id$";
45 #define NINDEX(ai,aj,natom) (natom*(ai)-((ai)*(ai+1))/2+(aj)-(ai))
46 #define INDEX(ai,aj,natom) ((ai) < (aj))?NINDEX((ai),(aj),natom):NINDEX(aj,ai,natom)
47 #define CHECK(ai,natom) if (((ai)<0) || ((ai)>=natom)) fatal_error(0,"Invalid atom number %d",ai+1)
49 static real
vdwlen(t_atoms
*atoms
,int i
,int j
)
52 char anm
[NAT
] = "HCNOS";
53 /* For time being I give S the same vdw-parameters as O */
54 real dist
[NAT
][NAT
] = {
55 { 2.0, 2.4, 2.4, 2.3, 2.3 },
56 { 2.4, 3.0, 2.9, 2.75, 2.75 },
57 { 2.4, 2.9, 2.7, 2.7, 2.7 },
58 { 2.3, 2.75, 2.7, 2.8, 2.8 },
59 { 2.3, 2.75, 2.7, 2.8, 2.8 }
64 ati
=toupper((*atoms
->atomname
[i
])[0]);
65 atj
=toupper((*atoms
->atomname
[j
])[0]);
67 for(ai
=0; (ai
<NAT
) && (ati
!= anm
[ai
]); ai
++)
69 for(aj
=0; (aj
<NAT
) && (atj
!= anm
[aj
]); aj
++)
71 if ((ai
< NAT
) && (aj
< NAT
))
74 fprintf(stderr
,"No combination for nbs (%c %c) using 2.0 A\n",ati
,atj
);
79 void set_dist(t_dist
*d
,int natoms
,int ai
,int aj
,real lb
,
85 fprintf(stderr
,"set_dist: lb = %f, ub = %f, len = %f, atoms %d,%d\n",
90 index
= INDEX(ai
,aj
,natoms
);
97 void set_ideal(t_dist
*d
,int natoms
,int ai
,int aj
,real len
)
103 index
= INDEX(ai
,aj
,natoms
);
107 bool dist_set(t_dist
*d
,int natoms
,int ai
,int aj
)
111 index
= INDEX(ai
,aj
,natoms
);
113 return (d
[index
].lb
!= 0.0);
116 static t_dist
*new_dist(int natom
)
120 snew(d
,(natom
*(natom
+1))/2);
125 real
d_lb(t_dist
*d
,int natoms
,int ai
,int aj
)
129 index
= INDEX(ai
,aj
,natoms
);
134 real
d_ub(t_dist
*d
,int natoms
,int ai
,int aj
)
138 index
= INDEX(ai
,aj
,natoms
);
143 real
d_len(t_dist
*d
,int natoms
,int ai
,int aj
)
147 index
= INDEX(ai
,aj
,natoms
);
152 static t_dist
*read_dist(FILE *log
,char *fn
,int natom
,real weight
[])
157 int i
,ai
,aj
,www
,ndist
;
161 fprintf(log
,"Going to read %s\n",fn
);
166 while (fgets2(buf
,BLEN
,fp
) != NULL
) {
168 if (sscanf(buf
,"%d%d%lf%lf%lf",&ai
,&aj
,&len
,&lb
,&ub
) != 5)
169 if (sscanf(buf
,"%d%d%lf%lf",&ai
,&aj
,&lb
,&ub
) != 4)
170 fatal_error(0,"Invalid dist format in %s",fn
);
173 if ((weight
[ai
] != 0) || (weight
[aj
] != 0)) {
174 if (!dist_set(d
,natom
,ai
,aj
)) {
176 fprintf(debug
,"\r%d %d %d",ndist
,ai
,aj
);
177 set_dist(d
,natom
,ai
,aj
,lb
,ub
,-1);
188 "Read %d distances from %s (discarded %d due to zero weight)\n",
191 "Read %d distances from %s (discarded %d due to zero weight)\n",
198 static void measure_report(FILE *fp
,int nm
,int natom
,int nover
,int nnotideal
,
199 int nhb_rep
,int nhb
,real cutoff
,real rmsd
)
201 double ndtot
=(natom
*(natom
-1.0))/2.0;
203 fprintf(fp
,"Determined %d distances out of a possible %.0f "
204 "(%.2f %%)\nby measuring from the structure within %f A\n",
205 nm
,ndtot
,(nm
*100.0)/ndtot
,cutoff
);
206 fprintf(fp
,"%d distances from the database were replaced by measured ones\n",
208 fprintf(fp
,"Of these, %d were not within the bounds of the database.\n"
209 "RMS deviation from bound limits for these was %e A.\n",
211 fprintf(fp
,"For %d hydrogen bonds out of %d in the index file the margins "
212 "were reduced\n",nhb_rep
/2,nhb
/3);
216 static void measure_dist(FILE *log
,t_dist
*d
,t_atoms
*atoms
,rvec x
[],
217 real cutoff
,real margin
,real hbmargin
,
218 int nhb
,atom_id hb
[])
220 int i
,j
,natom
,dd
,aa
,ai
,aj
,nm
,nover
,nnotideal
,nhb_rep
;
223 real ideal
,lbfac
,ubfac
,vdw
,lb
,ub
,nmargin
;
234 for(ai
=0; (ai
<natom
); ai
++)
235 for(aj
=ai
+1; (aj
<natom
); aj
++) {
236 rvec_sub(x
[ai
],x
[aj
],dx
);
239 fprintf(stderr
,"Warning distance between atoms %s and %s is zero\n",
240 atomname(atoms
,ai
),atomname(atoms
,aj
));
243 if (!dist_set(d
,natom
,ai
,aj
)) {
244 /* This distance is not determined by the database. */
245 vdw
= 0; /*vdwlen(atoms,ai,aj);*/
246 if ((ideal
< cutoff
) || (cutoff
== 0)) {
247 set_dist(d
,natom
,ai
,aj
,max(vdw
,ideal
*lbfac
),ideal
*ubfac
,ideal
);
252 /* These distances are already set by the database routines.
253 * However, we override the distances with the measured ones
254 * while keeping the original margins.
256 lb
= d_lb(d
,natom
,ai
,aj
);
257 ub
= d_ub(d
,natom
,ai
,aj
);
258 if ((ideal
< lb
) || (ideal
> ub
)) {
260 fprintf(debug
,"Warning: d(%s,%s) = %8.4f. According to E&H"
261 " it should be %8.4f (dev. %.1f%%)\n",
264 ideal
,(lb
+ub
)*0.5,50*fabs(ideal
*2-lb
-ub
));
265 msd
+= (ideal
< lb
) ? sqr(ideal
-lb
) : sqr(ideal
-ub
);
268 nmargin
= (ub
-lb
)/(ub
+lb
);
269 set_dist(d
,natom
,ai
,aj
,ideal
*(1-nmargin
),ideal
*(1+nmargin
),ideal
);
275 /* Now we have set all the distances. We have to verify though
276 * that h bonds are maintained, we therefore reduce their margins.
279 for(i
=0; (i
<nhb
); i
+= 3) {
283 for(j
=0; (j
<2); j
++) {
287 if (dist_set(d
,natom
,dd
,aa
)) {
288 lb
= d_lb(d
,natom
,dd
,aa
);
289 ub
= d_ub(d
,natom
,dd
,aa
);
290 ideal
= d_len(d
,natom
,dd
,aa
);
291 nmargin
= (ub
-lb
)/(ub
+lb
);
292 if (hbmargin
< nmargin
) {
293 set_dist(d
,natom
,dd
,aa
,ideal
*(1-hbmargin
),ideal
*(1+hbmargin
),ideal
);
298 fatal_error(0,"Distance between %s and %s not set, while they do make"
299 " a hbond:\nincrease radius for measuring (now %f A)\n",
300 atomname(atoms
,aa
),atomname(atoms
,dd
),cutoff
);
305 rmsd
= sqrt(msd
/nnotideal
);
308 measure_report(log
,nm
,natom
,nover
,nnotideal
,nhb_rep
,nhb
,cutoff
,rmsd
);
309 measure_report(stderr
,nm
,natom
,nover
,nnotideal
,nhb_rep
,nhb
,cutoff
,rmsd
);
312 static void dump_dist(char *fn
,t_dist
*d
,int natom
,bool bAddR
)
319 fprintf(fp
,"# distance file generated by cdist\n");
321 for(i
=0; (i
<natom
); i
++) {
322 for(j
=i
+1; (j
<natom
); j
++) {
323 if (dist_set(d
,natom
,i
,j
)) {
324 lb
= d_lb(d
,natom
,i
,j
);
325 ub
= d_ub(d
,natom
,i
,j
);
326 len
= d_len(d
,natom
,i
,j
);
328 fprintf(fp
,"%5d%5d%10.5f%10.5f\n",i
+1,j
+1,lb
,ub
);
330 fprintf(fp
,"%5d%5d%10.5f%10.5f%10.5f\n",i
+1,j
+1,len
,lb
,ub
);
331 /* Output for real-precision disco: */
332 /* fprintf(fp,"%5d%5d%15.10f%15.10f%15.10f\n",i+1,j+1,len,lb,ub); */
339 static real
*read_weights(char *fn
,int natom
)
352 /* Check the number of atoms */
353 get_pdb_coordnum(in
,&n
);
355 fatal_error(0,"Number of atoms in pdb file (%d) does not match tpx (%d)",
361 init_t_atoms(&atoms
,natom
,TRUE
);
364 /* Now read it all */
366 read_pdbfile(in
,title
,NULL
,&atoms
,x
,box
,FALSE
);
368 fprintf(stderr
,"%s\n",title
);
370 /* Now copy the weights */
371 for(i
=0; (i
<natom
); i
++)
372 w
[i
] = atoms
.pdbinfo
[i
].occup
;
376 free_t_atoms(&atoms
);
382 void init_rot_matrix(real mat
[3][3],real theta
, real omega
)
384 mat
[0][0] = -(cos(theta
)*cos(omega
));
385 mat
[1][0] = -(cos(theta
)*sin(omega
));
386 mat
[2][0] = sin(theta
);
388 mat
[0][1] = sin(omega
);
389 mat
[1][1] = -(cos(omega
));
392 mat
[0][2] = sin(theta
)*cos(omega
);
393 mat
[1][2] = sin(theta
)*sin(omega
);
394 mat
[2][2] = cos(theta
);
397 void vect_matrix(real vect
[3], real mat
[3][3])
407 for ( i
=0 ; i
<= 2 ; i
++ ) {
408 for ( j
=0 ; j
<=2 ; j
++ ) {
409 tmp
[i
]=tmp
[i
]+mat
[i
][j
]*vect
[j
];
412 for ( i
=0 ; i
<=2 ; i
++ ) {
417 void gauche_(int ai
,int aj
,int ak
,int al
,t_ilist ilist
[],
418 t_iparams iparams
[],real
*lb
,t_atoms
*atoms
,char *file
,int line
)
421 /* Matrix based approach */
423 real matrix1
[3][3],matrix2
[3][3];
424 real vect1
[3],vect2
[3],vect3
[3];
427 real half_pi
= M_PI
*0.5;
429 real thijk
,thjkl
,theta1
,theta2
,omega1
=pi
,omega2
= pi
+pi
/3.0;
431 rij
= lookup_bondlength_(ai
,aj
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
432 rjk
= lookup_bondlength_(aj
,ak
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
433 rkl
= lookup_bondlength_(ak
,al
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
434 thijk
= lookup_angle_(ai
,aj
,ak
,ilist
,iparams
,atoms
,file
,line
);
435 thjkl
= lookup_angle_(aj
,ak
,al
,ilist
,iparams
,atoms
,file
,line
);
439 /*Initialise vectors*/
450 /*Initialize matrices*/
451 init_rot_matrix(matrix1
,theta1
,omega1
);
452 init_rot_matrix(matrix2
,theta2
,omega2
);
454 /* Express vect2 and vect3 in coord. system of vect1 */
455 vect_matrix(vect2
,matrix1
);
456 vect_matrix(vect3
,matrix2
);
457 vect_matrix(vect3
,matrix1
);
460 for ( i
=0 ; i
<=2 ; i
++) {
461 vect3
[i
] = vect1
[i
]+vect2
[i
]+vect3
[i
];
464 /* Calculate distance */
465 *lb
= sqrt(vect3
[0]*vect3
[0]+vect3
[1]*vect3
[1]+vect3
[2]*vect3
[2]);
469 void gauche15_(int ai
,int aj
,int ak
,int al
,int am
,real omega1
,real omega2
,
470 real omega3
,t_ilist ilist
[],t_iparams iparams
[],real
*lb
,
471 t_atoms
*atoms
,char *file
,int line
)
474 /* Matrix based approach */
476 real matrix1
[3][3],matrix2
[3][3],matrix3
[3][3];
477 real vect1
[3],vect2
[3],vect3
[3],vect4
[3];
479 real half_pi
= M_PI
*0.5;
480 real rij
,rjk
,rkl
,rlm
;
481 real thijk
,thjkl
,thklm
,theta1
,theta2
,theta3
;
483 rij
= lookup_bondlength_(ai
,aj
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
484 rjk
= lookup_bondlength_(aj
,ak
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
485 rkl
= lookup_bondlength_(ak
,al
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
486 rlm
= lookup_bondlength_(al
,am
,ilist
,iparams
,TRUE
,atoms
,file
,line
);
487 thijk
= lookup_angle_(ai
,aj
,ak
,ilist
,iparams
,atoms
,file
,line
);
488 thjkl
= lookup_angle_(aj
,ak
,al
,ilist
,iparams
,atoms
,file
,line
);
489 thklm
= lookup_angle_(ak
,al
,am
,ilist
,iparams
,atoms
,file
,line
);
494 /*Initialise vectors*/
508 /*Initialize matrices*/
509 init_rot_matrix(matrix1
,theta1
,omega1
);
510 init_rot_matrix(matrix2
,theta2
,omega2
);
511 init_rot_matrix(matrix3
,theta3
,omega3
);
513 /* Express vect2 and vect3 in coord. system of vect1 */
514 vect_matrix(vect2
,matrix1
);
515 vect_matrix(vect3
,matrix2
);
516 vect_matrix(vect3
,matrix1
);
517 vect_matrix(vect4
,matrix3
);
518 vect_matrix(vect4
,matrix2
);
519 vect_matrix(vect4
,matrix1
);
522 for ( i
=0 ; i
<=2 ; i
++) {
523 vect4
[i
] = vect1
[i
]+vect2
[i
]+vect3
[i
]+vect4
[i
];
526 /* Calculate distance */
527 *lb
= sqrt(vect4
[0]*vect4
[0]+vect4
[1]*vect4
[1]+vect4
[2]*vect4
[2]);
531 static void dump_bonds(t_atoms
*atoms
,t_dist
*d
,
532 t_ilist ilist
[],t_functype functype
[],
533 t_iparams ip
[],real bond_margin
,real angle_margin
,
534 real dih_margin
,real idih_margin
,
535 real weight
[],bool bAddR
)
537 int dodist
[] = { F_BONDS
, F_MORSE
, F_SHAKE
, F_G96BONDS
,
538 F_G96ANGLES
, F_ANGLES
, F_IDIHS
/*,F_RBDIHS, F_PDIHS*/ };
539 int i
,j
,atom1
,atom2
,ai
,aj
,ak
,al
,type
,ftype
,nra
,ndist
,odist
,natoms
;
540 real blen
,rij
,rjk
,c6
,c12
,lb
=-1,ub
,theta
;
546 for(j
=0; (j
<asize(dodist
)); j
++) {
548 nra
= interaction_function
[ftype
].nratoms
;
549 for(i
=0; (i
<ilist
[ftype
].nr
); i
+=nra
+1) {
550 type
= ilist
[ftype
].iatoms
[i
];
551 ai
= ilist
[ftype
].iatoms
[i
+1];
552 aj
= ilist
[ftype
].iatoms
[i
+2];
560 blen
= lookup_bondlength(ai
,aj
,ilist
,ip
,TRUE
,atoms
);
564 ak
= ilist
[ftype
].iatoms
[i
+3];
565 theta
= lookup_angle(ai
,aj
,ak
,ilist
,ip
,atoms
);
566 blen
= angle_length(ai
,aj
,ak
,RAD2DEG
*theta
,ilist
,ip
,atoms
);
571 ak
= ilist
[ftype
].iatoms
[i
+3];
572 al
= ilist
[ftype
].iatoms
[i
+4];
573 pdih_lengths(ai
,aj
,ak
,al
,ilist
,ip
,&blen
,&ub
,atoms
);
577 ak
= ilist
[ftype
].iatoms
[i
+3];
578 al
= ilist
[ftype
].iatoms
[i
+4];
579 blen
= idih_lengths(ai
,aj
,ak
,al
,ilist
,ip
,atoms
);
585 if ((blen
!= 0) && ((weight
[atom1
] != 0.0) || (weight
[atom2
] != 0.0))) {
591 lb
= (1.0-bond_margin
)*blen
;
592 ub
= (1.0+bond_margin
)*blen
;
596 lb
= (1.0-angle_margin
)*blen
;
597 ub
= (1.0+angle_margin
)*blen
;
600 lb
= (1-idih_margin
)*blen
;
601 ub
= (1+idih_margin
)*blen
;
605 lb
= (1.0-dih_margin
)*blen
;
606 ub
= (1.0+dih_margin
)*ub
;
609 if (!dist_set(d
,natoms
,atom1
,atom2
)) {
610 set_dist(d
,natoms
,atom1
,atom2
,lb
,ub
,blen
);
618 fprintf(stderr
,"There are %d new bonded distances + %d old\n",ndist
,odist
);
621 static bool notexcl(t_block
*excl
,int ai
,int aj
)
625 for(i
=excl
->index
[ai
]; (i
<excl
->index
[ai
+1]); i
++) {
626 if (aj
== excl
->a
[i
])
632 static void dump_nonbonds(t_dist
*d
,t_idef
*idef
,t_atoms
*atoms
,
633 real hblen
,real weight
[],
634 real nb_margin
,bool bAddR
,
637 int i
,j
,k
,natoms
,ntype
,tpi
,tpj
,ndist
,odist
;
640 char element
,ati
,atj
;
645 /* Determine which atoms are capable of H bonding or not */
647 for(j
=0; (j
<ntype
); j
++)
648 for(i
=0; (i
<natoms
); i
++) {
649 if (atoms
->atom
[i
].type
== j
) {
650 element
= (*atoms
->atomname
[i
])[0];
651 bDA
[j
] = ((element
== 'N') || (element
== 'O'));
656 /* Make a distance matrix for VDWaals distances */
658 for(i=0; (i<ntype); i++) {
660 for(j=0; (j<ntype); j++) {
661 if (bDA[i] && bDA[j])
664 dmat[i][j] = vdwlen(idef,i,j,hblen);
669 /* Now loop over atom pairs */
672 for(i
=0; (i
<natoms
); i
++) {
673 tpi
= atoms
->atom
[i
].type
;
674 for(j
=i
+1; (j
<natoms
); j
++) {
675 if (((weight
[i
] != 0.0) || (weight
[j
] != 0.0))
676 /*&& (notexcl(&atoms->excl,i,j))*/) {
677 if (!dist_set(d
,natoms
,i
,j
)) {
678 /* We don't care about virtual particles */
679 ati
=(*atoms
->atomname
[i
])[0];
680 atj
=(*atoms
->atomname
[j
])[0];
681 if ( !(ati
== 'V' || atj
== 'V') ) {
683 tpj
= atoms
->atom
[j
].type
;
684 len
= vdwlen(atoms
,i
,j
);
685 lb
= (1-nb_margin
)*len
;
687 set_dist(d
,natoms
,i
,j
,lb
,maxdist
,0.0);
688 /* set_dist(d,natoms,i,j,lb,0.0,lb); */
698 fprintf(stderr
,"There are %d new non-bonded distances + %d old ones\n",
702 static void release_domains(FILE *fp
,char *ndx
,t_dist dist
[],t_atoms
*atoms
,
707 int i
,j
,k
,ii
,jj
,ai
,aj
,natoms
;
711 doms
= init_index(ndx
,&grpname
);
713 fprintf(fp
,"Found %d domains, named:\n",doms
->nr
);
714 for(i
=0; (i
<doms
->nr
); i
++)
715 fprintf(fp
,"%3d %s\n",i
,grpname
[i
]);
717 for(i
=0; (i
<doms
->nr
); i
++) {
718 for(ii
=doms
->index
[i
]; (ii
<doms
->index
[i
+1]); ii
++) {
720 for(j
=i
+1; (j
<doms
->nr
); j
++) {
721 for(jj
=doms
->index
[j
]; (jj
<doms
->index
[j
+1]); jj
++) {
723 if (dist_set(dist
,natoms
,ai
,aj
)) {
724 lb
= vdwlen(atoms
,ai
,aj
);
725 set_dist(dist
,natoms
,ai
,aj
,lb
,maxdist
,0.0);
736 int main(int argc
,char *argv
[])
738 static char *desc
[] = {
739 "cdist read a [BB]tpx[bb] file and dumps an input file for disco.",
740 "Bond lengths etc. are read from the topology. Pairs of atoms that can",
741 "form hydrogen bonds are given a lowest possible distance of",
742 "[BB]hblen[bb] (can be specified by the user). Other nonbonded pairs",
743 "take their minimum distance from the Lennard Jones parameters",
744 "(at the combined sigma).[PAR]",
745 "The program uses proper dihedrals to give a distance too, as minimum",
746 "respectively maximum the [IT]cis[it] and [IT]trans[it] configurations",
747 "are taken. It is therefore beneficial to use the [BB]-alldih[bb] option",
748 "of [TT]pdb2gmx[tt] to generate a topology with all dihedrals in there.",
749 "If the optional pdb file is given, weights are read from the occupancy",
751 "not all atoms are part of the disco run, only those of which one of the",
752 "weights is non-zero.[PAR]",
753 "If the option -engh is on (default) bond lengths and angles etc. are",
754 "read from another database, which is basically the Engh-Huber data",
755 "but refined to be completely self consistent. The database name is",
756 "refi_aa.dat and it resides in the $GMXLIB directory, or in the current",
758 "The program can read a file with distances from NMR distance restraints",
759 "(-d option). Note that these distance are treated slightly different",
760 "in the disco program, and therefore these distance should be NMR",
761 "derived distance restraints only.[PAR]",
762 "Furthermore, the program can read an index file with hydrogen bond",
763 "information as generated by [TT]g_hbond[tt]. This is then used to set",
764 "tighter restraints on the hydrogen bonded atoms than on the other",
765 "non bonded atom pairs, in order to maintain secondary structure.",
766 "This option is useful only in combination with the [TT]-measure[tt]",
767 "option, when a sensible structure is known.[PAR]",
768 "The option [TT]-dom[tt] can be used to release distances bounds between",
769 "different domains to the lower bounds given by Van der Waals contacts.",
770 "This way, different domains can move independently, but without",
771 "overlapping. The index file should contain domains that do not overlap",
775 { efTPS
, "-s", NULL
, ffREAD
},
776 { efLOG
, "-g", "cdist", ffWRITE
},
777 { efPDB
, "-q", NULL
, ffOPTRD
},
778 { efDAT
, "-d", NULL
, ffOPTRD
},
779 { efDAT
, "-o", "cdist", ffWRITE
},
780 { efNDX
, "-n", "hbond", ffOPTRD
},
781 { efNDX
, "-dom","domain",ffOPTRD
}
783 #define NFILE asize(fnm)
791 char *topfn
,title
[256];
796 /* Tolerance used in smoothing functions (real precision)*/
798 /* Hacked 990609 by Adam */
800 /* Command line options */
801 static real tol
=1e-6;
802 static real bond_margin
= 0.01;
803 static real angle_margin
= 0.01;
804 /* static real pep_margin = 0.005; */
805 static real pep_margin
= 0.01;
806 /* static real ring_margin = 0.002; */
807 static real ring_margin
= 0.01;
808 /* static real arg_margin = 0.002; */
809 static real arg_margin
= 0.01;
810 /* Use end_margin for asn and gln */
811 /* static real end_margin = 0.004; */
812 static real end_margin
= 0.01;
813 static real val_margin
= 0.01;
814 static real leu_margin
= 0.01;
815 static real ile_margin
= 0.03;
816 static real dih_margin
= 0.01;
817 static real idih_margin
= 0.01;
818 static real nb_margin
= 0.05;
819 static real hb_margin
= 0.02;
820 static real hblen
= 2.3;
821 static real rcut
= 0.0;
822 static real maxdist
= 0.0;
823 static bool bNB
=TRUE
,bBON
=TRUE
,bAddR
=FALSE
;
824 static bool bVir
=FALSE
,bEnghHuber
=TRUE
;
825 static char *smth_str
[] = { NULL
, "none", "tri", "tetra", NULL
};
827 { "-engh",FALSE
,etBOOL
, {&bEnghHuber
},
828 "Use the Engh&Huber parameters for bond-lengths etc." },
829 { "-tol", FALSE
, etREAL
, {&tol
},
830 "HIDDENTolerance for smoothing" },
831 { "-bm", FALSE
, etREAL
, {&bond_margin
},
832 "Relative margin for bond lengths" },
833 { "-am", FALSE
, etREAL
, {&angle_margin
},
834 "Relative margin for bond angle lengths" },
835 { "-pm", FALSE
, etREAL
, {&pep_margin
},
836 "Relative margin for peptidebond dihedrals" },
837 { "-rr", FALSE
, etREAL
, {&ring_margin
},
838 "Relative margin to keep rings flat (trp,tyr,phe,hisb)" },
839 { "-ar", FALSE
, etREAL
, {&arg_margin
},
840 "Relative margin for arginine" },
841 { "-er", FALSE
, etREAL
, {&end_margin
},
842 "Relative margin for asn and gln" },
843 { "-vm", FALSE
, etREAL
, {&val_margin
},
844 "Relative margin for valine (0 disables)" },
845 { "-lm", FALSE
, etREAL
, {&leu_margin
},
846 "Relative margin for leucine (0 disables)" },
847 { "-il", FALSE
, etREAL
, {&ile_margin
},
848 "Relative margin for isoleucine (0 disables)" },
849 { "-dm", FALSE
, etREAL
, {&dih_margin
},
850 "!inactive! Relative margin for dihedral lengths" },
851 { "-im", FALSE
, etREAL
, {&idih_margin
},
852 "Relative margin for improper dihedral lengths" },
853 { "-nm", FALSE
, etREAL
, {&nb_margin
},
854 "Relative margin for nonbonded lower bounds" },
855 { "-hm", FALSE
, etREAL
, {&hb_margin
},
856 "Relative margin for hydrogen bonded atoms, which must be specified in an index file, as generated by g_hbond" },
857 { "-hb", FALSE
, etREAL
, {&hblen
},
858 "Shortest possible distance for a hydrogen bond (in Angstrom!)" },
859 { "-bon", FALSE
, etBOOL
, {&bBON
},
860 "Make bonded distance constraints" },
861 { "-nb", FALSE
, etBOOL
, {&bNB
},
862 "Make nonbonded distance constraints (lower bound only) " },
863 { "-measure", FALSE
, etREAL
, {&rcut
},
864 "Add (nonbonded) distances by examining all atoms within the distance given (in Angstrom), and using the margin given by the -nm option." },
865 { "-maxdist", FALSE
, etREAL
, {&maxdist
},
866 "Maximum distance between any pair of atoms" },
867 { "-add",FALSE
, etBOOL
, {&bAddR
},
868 "Write restraints in format of additional restraints for disco" },
869 { "-vir",FALSE
, etBOOL
, {&bVir
},
870 "Use virtual particles"},
871 { "-sm", FALSE
, etENUM
, {smth_str
},
872 "Smoothing: none, tri (Using triangle inequality), or tetra (Partial tetrangle inequaliy)" }
875 CopyRight(stderr
,argv
[0]);
876 parse_common_args(&argc
,argv
,0,NFILE
,fnm
,asize(pa
),pa
,
877 asize(desc
),desc
,0,NULL
);
880 fprintf(stderr
,"WARNING: running %s in single precision may produce bad"
881 " distances\n",argv
[0]);
884 fp
=ffopen(ftp2fn(efLOG
,NFILE
,fnm
),"w");
886 if ((!bBON
&& !bNB
) && (rcut
==0.0))
887 fprintf(stderr
,"That was interesting... (nothing done)\n");
890 topfn
= ftp2fn(efTPS
,NFILE
,fnm
);
891 if (!read_tps_conf(topfn
,title
,top
,&x
,NULL
,box
,FALSE
))
892 fatal_error(0,"No topology in %s",topfn
);
893 fprintf(stderr
,"Successfully read %s (%s)\n",topfn
,title
);
895 if (!opt2parg_bSet("-maxdist",asize(pa
),pa
))
896 maxdist
= (top
->atoms
.nres
+3)*3.5; /* Ca-Ca distance + some buffer */
898 if (opt2bSet("-q",NFILE
,fnm
)) {
899 weight
= read_weights(opt2fn("-q",NFILE
,fnm
),top
->atoms
.nr
);
902 snew(weight
,top
->atoms
.nr
);
903 for(i
=0; (i
<top
->atoms
.nr
); i
++)
906 if (opt2bSet("-d",NFILE
,fnm
)) {
907 dist
= read_dist(fp
,opt2fn("-d",NFILE
,fnm
),top
->atoms
.nr
,weight
);
910 dist
= new_dist(top
->atoms
.nr
);
916 simple_bonds_and_angles(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,
917 bond_margin
,angle_margin
);
918 peptide_bonds(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,pep_margin
,
919 top
->idef
.il
,top
->idef
.iparams
,bVir
);
920 arg(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,arg_margin
,
921 top
->idef
.il
,top
->idef
.iparams
,bVir
);
922 asn(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,end_margin
,
923 top
->idef
.il
,top
->idef
.iparams
,bVir
);
924 gln(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,end_margin
,
925 top
->idef
.il
,top
->idef
.iparams
,bVir
);
926 phe(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
927 top
->idef
.il
,top
->idef
.iparams
,bVir
);
928 tyr(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
929 top
->idef
.il
,top
->idef
.iparams
,bVir
);
930 trp(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
931 top
->idef
.il
,top
->idef
.iparams
,bVir
);
932 hisb(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
933 top
->idef
.il
,top
->idef
.iparams
,bVir
);
934 if ( val_margin
!= 0 ) {
935 val(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,val_margin
,
936 top
->idef
.il
,top
->idef
.iparams
);
938 if ( leu_margin
!= 0 ) {
939 leu(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,leu_margin
,
940 top
->idef
.il
,top
->idef
.iparams
);
942 if ( ile_margin
!= 0 ) {
943 ile(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ile_margin
,
944 top
->idef
.il
,top
->idef
.iparams
);
947 fprintf(stderr
,"Done residues...\n");
948 dump_bonds(&top
->atoms
,dist
,
949 top
->idef
.il
,top
->idef
.functype
,top
->idef
.iparams
,
950 bond_margin
,angle_margin
,dih_margin
,
951 idih_margin
,weight
,bAddR
);
953 fprintf(stderr
,"Done bondeds\n");
959 if (ftp2bSet(efNDX
,NFILE
,fnm
)) {
960 rd_index(ftp2fn(efNDX
,NFILE
,fnm
),1,&nhb
,&hb
,&grpname
);
961 fprintf(stderr
,"There are %d hydrogen bonds\n",nhb
/3);
963 measure_dist(fp
,dist
,&top
->atoms
,x
,rcut
,nb_margin
,hb_margin
,nhb
,hb
);
965 if (opt2bSet("-dom",NFILE
,fnm
)) {
966 release_domains(fp
,opt2fn("-dom",NFILE
,fnm
),dist
,&top
->atoms
,maxdist
);
969 dump_nonbonds(dist
,&top
->idef
,&top
->atoms
,hblen
,weight
,
970 nb_margin
,bAddR
,maxdist
);
972 if (strcmp(smth_str
[0],smth_str
[1]) == 0)
973 fprintf(stderr
,"No smoothing\n");
974 else if (strcmp(smth_str
[0],smth_str
[2]) == 0) {
975 fprintf(stderr
,"Triangle smoothing only\n");
976 (void) do_triangle (dist
,&top
->atoms
,tol
);
978 else if (strcmp(smth_str
[0],smth_str
[3]) == 0) {
979 fprintf(stderr
,"Partial tetrangle + triangle smoothing\n");
980 do_smooth(dist
,&top
->atoms
,tol
);
983 fatal_error(0,"Uh-oh, smth_str = %s, %s, line %d",
984 smth_str
[0],__FILE__
,__LINE__
);
986 dump_dist(opt2fn("-o",NFILE
,fnm
),dist
,top
->atoms
.nr
,bAddR
);