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_cdist_c
= "$Id$";
42 #define NINDEX(ai,aj,natom) (natom*(ai)-((ai)*(ai+1))/2+(aj)-(ai))
43 #define INDEX(ai,aj,natom) ((ai) < (aj))?NINDEX((ai),(aj),natom):NINDEX(aj,ai,natom)
44 #define CHECK(ai,natom) if (((ai)<0) || ((ai)>=natom)) fatal_error(0,"Invalid atom number %d",ai+1)
46 static real
vdwlen(t_atoms
*atoms
,int i
,int j
)
49 char anm
[NAT
] = "HCNOS";
50 /* For time being I give S the same vdw-parameters as O */
51 real dist
[NAT
][NAT
] = {
52 { 2.0, 2.4, 2.4, 2.3, 2.3 },
53 { 2.4, 3.0, 2.9, 2.75, 2.75 },
54 { 2.4, 2.9, 2.7, 2.7, 2.7 },
55 { 2.3, 2.75, 2.7, 2.8, 2.8 },
56 { 2.3, 2.75, 2.7, 2.8, 2.8 }
61 ati
=toupper((*atoms
->atomname
[i
])[0]);
62 atj
=toupper((*atoms
->atomname
[j
])[0]);
64 for(ai
=0; (ai
<NAT
) && (ati
!= anm
[ai
]); ai
++)
66 for(aj
=0; (aj
<NAT
) && (atj
!= anm
[aj
]); aj
++)
68 if ((ai
< NAT
) && (aj
< NAT
))
71 fprintf(stderr
,"No combination for nbs (%c %c) using 2.0 A\n",ati
,atj
);
76 void set_dist(t_dist
*d
,int natoms
,int ai
,int aj
,real lb
,
82 fprintf(stderr
,"set_dist: lb = %f, ub = %f, len = %f, atoms %d,%d\n",
87 index
= INDEX(ai
,aj
,natoms
);
94 void set_ideal(t_dist
*d
,int natoms
,int ai
,int aj
,real len
)
100 index
= INDEX(ai
,aj
,natoms
);
104 bool dist_set(t_dist
*d
,int natoms
,int ai
,int aj
)
108 index
= INDEX(ai
,aj
,natoms
);
110 return (d
[index
].lb
!= 0.0);
113 static t_dist
*new_dist(int natom
)
117 snew(d
,(natom
*(natom
+1))/2);
122 real
d_lb(t_dist
*d
,int natoms
,int ai
,int aj
)
126 index
= INDEX(ai
,aj
,natoms
);
131 real
d_ub(t_dist
*d
,int natoms
,int ai
,int aj
)
135 index
= INDEX(ai
,aj
,natoms
);
140 real
d_len(t_dist
*d
,int natoms
,int ai
,int aj
)
144 index
= INDEX(ai
,aj
,natoms
);
149 static t_dist
*read_dist(FILE *log
,char *fn
,int natom
,real weight
[])
154 int i
,ai
,aj
,www
,ndist
;
158 fprintf(log
,"Going to read %s\n",fn
);
163 while (fgets2(buf
,BLEN
,fp
) != NULL
) {
165 if (sscanf(buf
,"%d%d%lf%lf%lf",&ai
,&aj
,&len
,&lb
,&ub
) != 5)
166 if (sscanf(buf
,"%d%d%lf%lf",&ai
,&aj
,&lb
,&ub
) != 4)
167 fatal_error(0,"Invalid dist format in %s",fn
);
170 if ((weight
[ai
] != 0) || (weight
[aj
] != 0)) {
171 if (!dist_set(d
,natom
,ai
,aj
)) {
173 fprintf(debug
,"\r%d %d %d",ndist
,ai
,aj
);
174 set_dist(d
,natom
,ai
,aj
,lb
,ub
,-1);
185 "Read %d distances from %s (discarded %d due to zero weight)\n",
191 static void measure_report(FILE *fp
,int nm
,int natom
,int nover
,int nnotideal
,
192 int nhb_rep
,int nhb
,real cutoff
,real rmsd
)
194 double ndtot
=(natom
*(natom
-1.0))/2.0;
196 fprintf(fp
,"Determined %d distances out of a possible %.0f "
197 "(%.2f %%)\nby measuring from the structure within %f A\n",
198 nm
,ndtot
,(nm
*100.0)/ndtot
,cutoff
);
199 fprintf(fp
,"%d distances from the database were replaced by measured ones\n",
201 fprintf(fp
,"Of these, %d were not within the bounds of the database.\n"
202 "RMS deviation from bound limits for these was %e A.\n",
204 fprintf(fp
,"For %d hydrogen bonds out of %d in the index file the margins "
205 "were reduced\n",nhb_rep
/2,nhb
/3);
208 static void measure_dist(FILE *log
,t_dist
*d
,t_atoms
*atoms
,rvec x
[],
209 real cutoff
,real margin
,real hbmargin
,
210 int nhb
,atom_id hb
[])
212 int i
,j
,natom
,dd
,aa
,ai
,aj
,nm
,nover
,nnotideal
,nhb_rep
;
215 real ideal
,lbfac
,ubfac
,vdw
,lb
,ub
,nmargin
;
226 for(ai
=0; (ai
<natom
); ai
++)
227 for(aj
=ai
+1; (aj
<natom
); aj
++) {
228 rvec_sub(x
[ai
],x
[aj
],dx
);
231 fprintf(stderr
,"Warning distance between atoms %s and %s is zero\n",
232 atomname(atoms
,ai
),atomname(atoms
,aj
));
235 if (!dist_set(d
,natom
,ai
,aj
)) {
236 /* This distance is not determined by the database. */
237 vdw
= 0; /*vdwlen(atoms,ai,aj);*/
238 if ((ideal
< cutoff
) || (cutoff
== 0)) {
239 set_dist(d
,natom
,ai
,aj
,max(vdw
,ideal
*lbfac
),ideal
*ubfac
,ideal
);
244 /* These distances are already set by the database routines.
245 * However, we override the distances with the measured ones
246 * while keeping the original margins.
248 lb
= d_lb(d
,natom
,ai
,aj
);
249 ub
= d_ub(d
,natom
,ai
,aj
);
250 if ((ideal
< lb
) || (ideal
> ub
)) {
252 fprintf(debug
,"Warning: d(%s,%s) = %8.4f. According to E&H"
253 " it should be %8.4f (dev. %.1f%%)\n",
256 ideal
,(lb
+ub
)*0.5,50*fabs(ideal
*2-lb
-ub
));
257 msd
+= (ideal
< lb
) ? sqr(ideal
-lb
) : sqr(ideal
-ub
);
260 nmargin
= (ub
-lb
)/(ub
+lb
);
261 set_dist(d
,natom
,ai
,aj
,ideal
*(1-nmargin
),ideal
*(1+nmargin
),ideal
);
267 /* Now we have set all the distances. We have to verify though
268 * that h bonds are maintained, we therefore reduce their margins.
271 for(i
=0; (i
<nhb
); i
+= 3) {
275 for(j
=0; (j
<2); j
++) {
279 if (dist_set(d
,natom
,dd
,aa
)) {
280 lb
= d_lb(d
,natom
,dd
,aa
);
281 ub
= d_ub(d
,natom
,dd
,aa
);
282 ideal
= d_len(d
,natom
,dd
,aa
);
283 nmargin
= (ub
-lb
)/(ub
+lb
);
284 if (hbmargin
< nmargin
) {
285 set_dist(d
,natom
,dd
,aa
,ideal
*(1-hbmargin
),ideal
*(1+hbmargin
),ideal
);
290 fatal_error(0,"Distance between %s and %s not set, while they do make"
291 " a hbond:\nincrease radius for measuring (now %f A)\n",
292 atomname(atoms
,aa
),atomname(atoms
,dd
),cutoff
);
297 rmsd
= sqrt(msd
/nnotideal
);
300 measure_report(log
,nm
,natom
,nover
,nnotideal
,nhb_rep
,nhb
,cutoff
,rmsd
);
301 measure_report(stderr
,nm
,natom
,nover
,nnotideal
,nhb_rep
,nhb
,cutoff
,rmsd
);
304 static void dump_dist(char *fn
,t_dist
*d
,int natom
,bool bAddR
)
311 fprintf(fp
,"# distance file generated by cdist\n");
313 for(i
=0; (i
<natom
); i
++) {
314 for(j
=i
+1; (j
<natom
); j
++) {
315 if (dist_set(d
,natom
,i
,j
)) {
316 lb
= d_lb(d
,natom
,i
,j
);
317 ub
= d_ub(d
,natom
,i
,j
);
318 len
= d_len(d
,natom
,i
,j
);
320 fprintf(fp
,"%5d%5d%10.5f%10.5f\n",i
+1,j
+1,lb
,ub
);
322 fprintf(fp
,"%5d%5d%10.5f%10.5f%10.5f\n",i
+1,j
+1,len
,lb
,ub
);
323 /* Output for real-precision disco: */
324 /* fprintf(fp,"%5d%5d%15.10f%15.10f%15.10f\n",i+1,j+1,len,lb,ub); */
331 static real
*read_weights(char *fn
,int natom
)
344 /* Check the number of atoms */
345 get_pdb_coordnum(in
,&n
);
347 fatal_error(0,"Number of atoms in pdb file (%d) does not match tpx (%d)",
353 init_t_atoms(&atoms
,natom
,TRUE
);
356 /* Now read it all */
358 read_pdbfile(in
,title
,&atoms
,x
,box
,FALSE
);
360 fprintf(stderr
,"%s\n",title
);
362 /* Now copy the weights */
363 for(i
=0; (i
<natom
); i
++)
364 w
[i
] = atoms
.pdbinfo
[i
].occup
;
368 free_t_atoms(&atoms
);
377 void init_rot_matrix(real matrix
[3][3],real theta
, real omega
)
379 matrix
[0][0] = -(cos(theta
)*cos(omega
));
380 matrix
[1][0] = -(cos(theta
)*sin(omega
));
381 matrix
[2][0] = sin(theta
);
383 matrix
[0][1] = sin(omega
);
384 matrix
[1][1] = -(cos(omega
));
387 matrix
[0][2] = sin(theta
)*cos(omega
);
388 matrix
[1][2] = sin(theta
)*sin(omega
);
389 matrix
[2][2] = cos(theta
);
392 void vect_matrix(real vect
[3], real matrix
[3][3])
402 for ( i
=0 ; i
<= 2 ; i
++ ) {
403 for ( j
=0 ; j
<=2 ; j
++ ) {
404 tmp
[i
]=tmp
[i
]+matrix
[i
][j
]*vect
[j
];
407 for ( i
=0 ; i
<=2 ; i
++ ) {
412 void gauche(int ai
,int aj
,int ak
,int al
,t_ilist ilist
[],
413 t_iparams iparams
[],real
*lb
,t_atoms
*atoms
)
416 /* Matrix based approach */
418 real matrix1
[3][3],matrix2
[3][3];
419 real vect1
[3],vect2
[3],vect3
[3];
422 real half_pi
= M_PI
*0.5;
424 real thijk
,thjkl
,theta1
,theta2
,omega1
=pi
,omega2
= pi
+pi
/3.0;
426 rij
= lookup_bondlength(ai
,aj
,ilist
,iparams
,TRUE
,atoms
);
427 rjk
= lookup_bondlength(aj
,ak
,ilist
,iparams
,TRUE
,atoms
);
428 rkl
= lookup_bondlength(ak
,al
,ilist
,iparams
,TRUE
,atoms
);
429 thijk
= lookup_angle(ai
,aj
,ak
,ilist
,iparams
,atoms
);
430 thjkl
= lookup_angle(aj
,ak
,al
,ilist
,iparams
,atoms
);
434 /*Initialise vectors*/
445 /*Initialize matrices*/
446 init_rot_matrix(matrix1
,theta1
,omega1
);
447 init_rot_matrix(matrix2
,theta2
,omega2
);
449 /* Express vect2 and vect3 in coord. system of vect1 */
450 vect_matrix(vect2
,matrix1
);
451 vect_matrix(vect3
,matrix2
);
452 vect_matrix(vect3
,matrix1
);
455 for ( i
=0 ; i
<=2 ; i
++) {
456 vect3
[i
] = vect1
[i
]+vect2
[i
]+vect3
[i
];
459 /* Calculate distance */
460 *lb
= sqrt(vect3
[0]*vect3
[0]+vect3
[1]*vect3
[1]+vect3
[2]*vect3
[2]);
464 void gauche15(int ai
,int aj
,int ak
,int al
,int am
,real omega1
,real omega2
,
465 real omega3
,t_ilist ilist
[],t_iparams iparams
[],real
*lb
,
469 /* Matrix based approach */
471 real matrix1
[3][3],matrix2
[3][3],matrix3
[3][3];
472 real vect1
[3],vect2
[3],vect3
[3],vect4
[3];
474 real half_pi
= M_PI
*0.5;
475 real rij
,rjk
,rkl
,rlm
;
476 real thijk
,thjkl
,thklm
,theta1
,theta2
,theta3
;
478 rij
= lookup_bondlength(ai
,aj
,ilist
,iparams
,TRUE
,atoms
);
479 rjk
= lookup_bondlength(aj
,ak
,ilist
,iparams
,TRUE
,atoms
);
480 rkl
= lookup_bondlength(ak
,al
,ilist
,iparams
,TRUE
,atoms
);
481 rlm
= lookup_bondlength(al
,am
,ilist
,iparams
,TRUE
,atoms
);
482 thijk
= lookup_angle(ai
,aj
,ak
,ilist
,iparams
,atoms
);
483 thjkl
= lookup_angle(aj
,ak
,al
,ilist
,iparams
,atoms
);
484 thklm
= lookup_angle(ak
,al
,am
,ilist
,iparams
,atoms
);
489 /*Initialise vectors*/
503 /*Initialize matrices*/
504 init_rot_matrix(matrix1
,theta1
,omega1
);
505 init_rot_matrix(matrix2
,theta2
,omega2
);
506 init_rot_matrix(matrix3
,theta3
,omega3
);
508 /* Express vect2 and vect3 in coord. system of vect1 */
509 vect_matrix(vect2
,matrix1
);
510 vect_matrix(vect3
,matrix2
);
511 vect_matrix(vect3
,matrix1
);
512 vect_matrix(vect4
,matrix3
);
513 vect_matrix(vect4
,matrix2
);
514 vect_matrix(vect4
,matrix1
);
517 for ( i
=0 ; i
<=2 ; i
++) {
518 vect4
[i
] = vect1
[i
]+vect2
[i
]+vect3
[i
]+vect4
[i
];
521 /* Calculate distance */
522 *lb
= sqrt(vect4
[0]*vect4
[0]+vect4
[1]*vect4
[1]+vect4
[2]*vect4
[2]);
526 static void dump_bonds(t_atoms
*atoms
,t_dist
*d
,
527 t_ilist ilist
[],t_functype functype
[],
528 t_iparams ip
[],real bond_margin
,real angle_margin
,
529 real dih_margin
,real idih_margin
,
530 real weight
[],bool bAddR
)
532 int dodist
[] = { F_BONDS
, F_MORSE
, F_SHAKE
, F_G96BONDS
,
533 F_G96ANGLES
, F_ANGLES
, F_IDIHS
/*,F_RBDIHS, F_PDIHS*/ };
534 int i
,j
,atom1
,atom2
,ai
,aj
,ak
,al
,type
,ftype
,nra
,ndist
,odist
,natoms
;
535 real blen
,rij
,rjk
,c6
,c12
,lb
=-1,ub
,theta
;
541 for(j
=0; (j
<asize(dodist
)); j
++) {
543 nra
= interaction_function
[ftype
].nratoms
;
544 for(i
=0; (i
<ilist
[ftype
].nr
); i
+=nra
+1) {
545 type
= ilist
[ftype
].iatoms
[i
];
546 ai
= ilist
[ftype
].iatoms
[i
+1];
547 aj
= ilist
[ftype
].iatoms
[i
+2];
555 blen
= lookup_bondlength(ai
,aj
,ilist
,ip
,TRUE
,atoms
);
559 ak
= ilist
[ftype
].iatoms
[i
+3];
560 theta
= lookup_angle(ai
,aj
,ak
,ilist
,ip
,atoms
);
561 blen
= angle_length(ai
,aj
,ak
,RAD2DEG
*theta
,ilist
,ip
,atoms
);
566 ak
= ilist
[ftype
].iatoms
[i
+3];
567 al
= ilist
[ftype
].iatoms
[i
+4];
568 pdih_lengths(ai
,aj
,ak
,al
,ilist
,ip
,&blen
,&ub
,atoms
);
572 ak
= ilist
[ftype
].iatoms
[i
+3];
573 al
= ilist
[ftype
].iatoms
[i
+4];
574 blen
= idih_lengths(ai
,aj
,ak
,al
,ilist
,ip
,atoms
);
580 if ((blen
!= 0) && ((weight
[atom1
] != 0.0) || (weight
[atom2
] != 0.0))) {
586 lb
= (1.0-bond_margin
)*blen
;
587 ub
= (1.0+bond_margin
)*blen
;
591 lb
= (1.0-angle_margin
)*blen
;
592 ub
= (1.0+angle_margin
)*blen
;
595 lb
= (1-idih_margin
)*blen
;
596 ub
= (1+idih_margin
)*blen
;
600 lb
= (1.0-dih_margin
)*blen
;
601 ub
= (1.0+dih_margin
)*ub
;
604 if (!dist_set(d
,natoms
,atom1
,atom2
)) {
605 set_dist(d
,natoms
,atom1
,atom2
,lb
,ub
,blen
);
613 fprintf(stderr
,"There are %d new bonded distances + %d old\n",ndist
,odist
);
616 static bool notexcl(t_block
*excl
,int ai
,int aj
)
620 for(i
=excl
->index
[ai
]; (i
<excl
->index
[ai
+1]); i
++) {
621 if (aj
== excl
->a
[i
])
627 static void dump_nonbonds(t_dist
*d
,t_idef
*idef
,t_atoms
*atoms
,
628 real hblen
,real weight
[],
629 real nb_margin
,bool bAddR
)
631 int i
,j
,k
,natoms
,ntype
,tpi
,tpj
,ndist
,odist
;
632 real
**dmat
,len
,lb
,maxdist
;
634 char element
,ati
,atj
;
638 maxdist
= (atoms
->nres
+3)*3.5; /* Ca-Ca distance + some buffer */
640 /* Determine which atoms are capable of H bonding or not */
642 for(j
=0; (j
<ntype
); j
++)
643 for(i
=0; (i
<natoms
); i
++) {
644 if (atoms
->atom
[i
].type
== j
) {
645 element
= (*atoms
->atomname
[i
])[0];
646 bDA
[j
] = ((element
== 'N') || (element
== 'O'));
651 /* Make a distance matrix for VDWaals distances */
653 for(i=0; (i<ntype); i++) {
655 for(j=0; (j<ntype); j++) {
656 if (bDA[i] && bDA[j])
659 dmat[i][j] = vdwlen(idef,i,j,hblen);
664 /* Now loop over atom pairs */
667 for(i
=0; (i
<natoms
); i
++) {
668 tpi
= atoms
->atom
[i
].type
;
669 for(j
=i
+1; (j
<natoms
); j
++) {
670 if (((weight
[i
] != 0.0) || (weight
[j
] != 0.0))
671 /*&& (notexcl(&atoms->excl,i,j))*/) {
672 if (!dist_set(d
,natoms
,i
,j
)) {
673 /* We don't care about virtual particles */
674 ati
=(*atoms
->atomname
[i
])[0];
675 atj
=(*atoms
->atomname
[j
])[0];
676 if ( !(ati
== 'V' || atj
== 'V') ) {
678 tpj
= atoms
->atom
[j
].type
;
679 len
= vdwlen(atoms
,i
,j
);
680 lb
= (1-nb_margin
)*len
;
682 set_dist(d
,natoms
,i
,j
,lb
,maxdist
,0.0);
683 /* set_dist(d,natoms,i,j,lb,0.0,lb); */
693 fprintf(stderr
,"There are %d new non-bonded distances + %d old ones\n",
698 int main(int argc
,char *argv
[])
700 static char *desc
[] = {
701 "cdist read a [BB]tpx[bb] file and dumps an input file for disco.",
702 "Bond lengths etc. are read from the topology. Pairs of atoms that can",
703 "form hydrogen bonds are given a lowest possible distance of",
704 "[BB]hblen[bb] (can be specified by the user). Other nonbonded pairs",
705 "take their minimum distance from the Lennard Jones parameters",
706 "(at the combined sigma).[PAR]",
707 "The program uses proper dihedrals to give a distance too, as minimum",
708 "respectively maximum the [IT]cis[it] and [IT]trans[it] configurations",
709 "are taken. It is therefore beneficial to use the [BB]-alldih[bb] option",
710 "of [TT]pdb2gmx[tt] to generate a topology with all dihedrals in there.",
711 "If the optional pdb file is given, weights are read from the occupancy",
713 "not all atoms are part of the disco run, only those of which one of the",
714 "weights is non-zero.[PAR]",
715 "If the option -engh is on (default) bond lengths and angles etc. are",
716 "read from another database, which is basically the Engh-Huber data",
717 "but refined to be completely self consistent. The database name is",
718 "refi_aa.dat and it resides in the $GMXLIB directory, or in the current",
720 "The program can read a file with distances from NMR distance restraints",
721 "(-d option). Note that these distance are treated slightly different",
722 "in the disco program, and therefore these distance should be NMR",
723 "derived distance restraints only.[PAR]",
724 "Furthermore, the program can read an index file with hydrogen bond",
725 "information as generated by [TT]g_hbond[tt]. This is then used to set",
726 "tighter restraints on the hydrogen bonded atoms than on the other",
727 "non bonded atom pairs, in order to maintain secondary structure.",
728 "This option is useful only in combination with the [TT]-measure[tt]",
729 "option, when a sensible structure is known."
732 { efTPS
, "-s", NULL
, ffREAD
},
733 { efLOG
, "-g", "cdist", ffWRITE
},
734 { efPDB
, "-q", NULL
, ffOPTRD
},
735 { efDAT
, "-d", NULL
, ffOPTRD
},
736 { efDAT
, "-o", "cdist", ffWRITE
},
737 { efNDX
, "-n", "hbond", ffOPTRD
}
739 #define NFILE asize(fnm)
747 char *topfn
,title
[256];
752 /* Tolerance used in smoothing functions (real precision)*/
754 /* Hacked 990609 by Adam */
756 /* Command line options */
757 static real tol
=1e-6;
758 static real bond_margin
= 0.01;
759 static real angle_margin
= 0.01;
760 /* static real pep_margin = 0.005; */
761 static real pep_margin
= 0.01;
762 /* static real ring_margin = 0.002; */
763 static real ring_margin
= 0.01;
764 /* static real arg_margin = 0.002; */
765 static real arg_margin
= 0.01;
766 /* Use end_margin for asn and gln */
767 /* static real end_margin = 0.004; */
768 static real end_margin
= 0.01;
769 static real val_margin
= 0.01;
770 static real leu_margin
= 0.01;
771 static real ile_margin
= 0.03;
772 static real dih_margin
= 0.01;
773 static real idih_margin
= 0.01;
774 static real nb_margin
= 0.05;
775 static real hb_margin
= 0.02;
776 static real hblen
= 2.3;
777 static real rcut
= 0.0;
778 static bool bNB
=TRUE
,bBON
=TRUE
,bAddR
=FALSE
;
779 static bool bVir
=FALSE
,bEnghHuber
=TRUE
;
780 static char *smth_str
[] = { NULL
, "none", "tri", "tetra", NULL
};
782 { "-engh",FALSE
,etBOOL
, &bEnghHuber
,
783 "Use the Engh&Huber parameters for bond-lengths etc." },
784 { "-tol", FALSE
, etREAL
, &tol
,
785 "HIDDENTolerance for smoothing" },
786 { "-bm", FALSE
, etREAL
, &bond_margin
,
787 "Relative margin for bond lengths" },
788 { "-am", FALSE
, etREAL
, &angle_margin
,
789 "Relative margin for bond angle lengths" },
790 { "-pm", FALSE
, etREAL
, &pep_margin
,
791 "Relative margin for peptidebond dihedrals" },
792 { "-rr", FALSE
, etREAL
, &ring_margin
,
793 "Relative margin to keep rings flat (trp,tyr,phe,hisb)" },
794 { "-ar", FALSE
, etREAL
, &arg_margin
,
795 "Relative margin for arginine" },
796 { "-er", FALSE
, etREAL
, &end_margin
,
797 "Relative margin for asn and gln" },
798 { "-vm", FALSE
, etREAL
, &val_margin
,
799 "Relative margin for valine (0 disables)" },
800 { "-lm", FALSE
, etREAL
, &leu_margin
,
801 "Relative margin for leucine (0 disables)" },
802 { "-il", FALSE
, etREAL
, &ile_margin
,
803 "Relative margin for isoleucine (0 disables)" },
804 { "-dm", FALSE
, etREAL
, &dih_margin
,
805 "!inactive! Relative margin for dihedral lengths" },
806 { "-im", FALSE
, etREAL
, &idih_margin
,
807 "Relative margin for improper dihedral lengths" },
808 { "-nm", FALSE
, etREAL
, &nb_margin
,
809 "Relative margin for nonbonded lower bounds" },
810 { "-hm", FALSE
, etREAL
, &hb_margin
,
811 "Relative margin for hydrogen bonded atoms, which must be specified in an index file, as generated by g_hbond" },
812 { "-hb", FALSE
, etREAL
, &hblen
,
813 "Shortest possible distance for a hydrogen bond (in Angstrom!)" },
814 { "-bon", FALSE
, etBOOL
, &bBON
,
815 "Make bonded distance constraints" },
816 { "-nb", FALSE
, etBOOL
, &bNB
,
817 "Make nonbonded distance constraints (lower bound only) " },
818 { "-measure", FALSE
, etREAL
, &rcut
,
819 "Add (nonbonded) distances by examining all atoms within the distance given (in Angstrom), and using the margin given by the -nm option." },
820 { "-add",FALSE
, etBOOL
, &bAddR
,
821 "Write restraints in format of additional restraints for disco" },
822 { "-vir",FALSE
, etBOOL
, &bVir
,
823 "Use virtual particles"},
824 { "-sm", FALSE
, etENUM
, smth_str
,
825 "Smoothing: none, tri (Using triangle inequality), or tetra (Partial tetrangle inequaliy)" }
828 CopyRight(stdout
,argv
[0]);
829 parse_common_args(&argc
,argv
,0,FALSE
,NFILE
,fnm
,asize(pa
),pa
,
830 asize(desc
),desc
,0,NULL
);
833 fprintf(stderr
,"WARNING: running %s in single precision may produce bad"
834 " distances\n",argv
[0]);
837 fp
=ffopen(ftp2fn(efLOG
,NFILE
,fnm
),"w");
839 if ((!bBON
&& !bNB
) && (rcut
==0.0))
840 fprintf(stderr
,"That was interesting... (nothing done)\n");
843 topfn
= ftp2fn(efTPS
,NFILE
,fnm
);
844 if (!read_tps_conf(topfn
,title
,top
,&x
,NULL
,box
,FALSE
))
845 fatal_error(0,"No topology in %s",topfn
);
846 fprintf(stderr
,"Successfully read %s (%s)\n",topfn
,title
);
848 if (opt2bSet("-q",NFILE
,fnm
)) {
849 weight
= read_weights(opt2fn("-q",NFILE
,fnm
),top
->atoms
.nr
);
852 snew(weight
,top
->atoms
.nr
);
853 for(i
=0; (i
<top
->atoms
.nr
); i
++)
856 if (opt2bSet("-d",NFILE
,fnm
)) {
857 dist
= read_dist(fp
,opt2fn("-d",NFILE
,fnm
),top
->atoms
.nr
,weight
);
860 dist
= new_dist(top
->atoms
.nr
);
866 peptide_bonds(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,pep_margin
,
867 top
->idef
.il
,top
->idef
.iparams
,bVir
);
868 arg(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,arg_margin
,
869 top
->idef
.il
,top
->idef
.iparams
,bVir
);
870 asn(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,end_margin
,
871 top
->idef
.il
,top
->idef
.iparams
,bVir
);
872 gln(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,end_margin
,
873 top
->idef
.il
,top
->idef
.iparams
,bVir
);
874 phe(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
875 top
->idef
.il
,top
->idef
.iparams
,bVir
);
876 tyr(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
877 top
->idef
.il
,top
->idef
.iparams
,bVir
);
878 trp(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
879 top
->idef
.il
,top
->idef
.iparams
,bVir
);
880 hisb(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ring_margin
,
881 top
->idef
.il
,top
->idef
.iparams
,bVir
);
882 if ( val_margin
!= 0 ) {
883 val(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,val_margin
,
884 top
->idef
.il
,top
->idef
.iparams
);
886 if ( leu_margin
!= 0 ) {
887 leu(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,leu_margin
,
888 top
->idef
.il
,top
->idef
.iparams
);
890 if ( ile_margin
!= 0 ) {
891 ile(fp
,dist
,&top
->idef
,&top
->atoms
,weight
,ile_margin
,
892 top
->idef
.il
,top
->idef
.iparams
);
894 fprintf(stderr
,"Done residues...\n");
895 dump_bonds(&top
->atoms
,dist
,
896 top
->idef
.il
,top
->idef
.functype
,top
->idef
.iparams
,
897 bond_margin
,angle_margin
,dih_margin
,
898 idih_margin
,weight
,bAddR
);
900 fprintf(stderr
,"Done bondeds\n");
906 if (ftp2bSet(efNDX
,NFILE
,fnm
)) {
907 rd_index(ftp2fn(efNDX
,NFILE
,fnm
),1,&nhb
,&hb
,&grpname
);
908 fprintf(stderr
,"There are %d hydrogen bonds\n",nhb
/3);
910 measure_dist(fp
,dist
,&top
->atoms
,x
,rcut
,nb_margin
,hb_margin
,nhb
,hb
);
913 dump_nonbonds(dist
,&top
->idef
,&top
->atoms
,hblen
,weight
,
916 if (strcmp(smth_str
[0],smth_str
[1]) == 0)
917 fprintf(stderr
,"No smoothing\n");
918 else if (strcmp(smth_str
[0],smth_str
[2]) == 0) {
919 fprintf(stderr
,"Triangle smoothing only\n");
920 do_triangle (dist
,&top
->atoms
,tol
);
922 else if (strcmp(smth_str
[0],smth_str
[3]) == 0) {
923 fprintf(stderr
,"Partial tetrangle + triangle smoothing\n");
924 do_smooth(dist
,&top
->atoms
,tol
);
927 fatal_error(0,"Uh-oh, smth_str = %s, %s, line %d",
928 smth_str
[0],__FILE__
,__LINE__
);
930 dump_dist(opt2fn("-o",NFILE
,fnm
),dist
,top
->atoms
.nr
,bAddR
);