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_disco_c
= "$Id$";
51 void rand_box(bool bUserBox
,
52 matrix box
,rvec boxsize
,int nres
,bool bCubic
,int *seed
)
60 for(m
=0; (m
<DIM
); m
++)
61 box
[m
][m
] = boxsize
[m
];
64 /* Generate a random box with size between 5*nres and 10*nres in nm */
65 fac
= 0.5*nres
; /* Ca-Ca distance is 0.35 nm */
66 box
[XX
][XX
] = fac
*(1+rando(seed
));
68 box
[YY
][YY
] = box
[ZZ
][ZZ
] = box
[XX
][XX
];
70 box
[YY
][YY
] = fac
*(1+rando(seed
));
71 box
[ZZ
][ZZ
] = fac
*(1+rando(seed
));
73 for(m
=0; (m
<DIM
); m
++)
74 boxsize
[m
] = box
[m
][m
];
78 void rand_coord(rvec x
,int *seed
,rvec box
)
82 for(m
=0; (m
<DIM
); m
++)
83 x
[m
] = box
[m
]*rando(seed
);
86 void rand_coords(int natom
,rvec x
[],rvec xref
[],real weight
[],
87 bool bCenter
,rvec xcenter
[],rvec box
,int *seed
)
91 for(i
=0; (i
<natom
); i
++) {
93 copy_rvec(xref
[i
],x
[i
]);
95 rand_coord(x
[i
],seed
,box
);
97 rvec_inc(x
[i
],xcenter
[i
]);
102 void pr_conv_stat(FILE *fp
,int ntry
,int nconv
,double tnit
)
104 fprintf(fp
,"\n-------------------------\n");
105 fprintf(fp
," Convergence statistics:\n");
106 fprintf(fp
," # tries: %d\n",ntry
);
107 fprintf(fp
," # converged: %d\n",nconv
);
108 fprintf(fp
," # nit/ntry: %d\n",(int)(tnit
/ntry
));
110 fprintf(fp
," # nit/nconv: %d\n",(int)(tnit
/nconv
));
111 fprintf(fp
,"-------------------------\n");
114 static void do_disco(FILE *log
,char *outfn
,char *keepfn
,t_correct
*c
,
115 bool bVerbose
,t_atoms
*atoms
,
116 rvec xref
[],rvec xcenter
[],
117 int nstruct
,int *seed
,
118 bool bFit
,int nfit
,atom_id fit_ind
[],
119 bool bPrintViol
,char *violfn
,rvec boxsize
)
123 int i
,k
,kk
,nconv
,ntry
,status
,kstatus
,natom
,nres
,nit
,nvtest
,nviol
;
134 /* Initiate some local arrays */
138 wrbox
[XX
][XX
] = wrbox
[YY
][YY
] = wrbox
[ZZ
][ZZ
] = nres
;
139 status
= open_trx(outfn
,"w");
141 kstatus
= open_trx(keepfn
,"w");
146 for(k
=0; (k
<natom
); k
++)
149 for(k
=0; (k
<nfit
); k
++)
150 w_rls
[fit_ind
[k
]] = 1;
152 snew(nconvdist
,c
->maxnit
+1);
153 /* Now loop over structures */
155 for(k
=nconv
=ntry
=0; (k
<nstruct
); ntry
++) {
157 fprintf(stderr
,"\rTry: %d, Success: %d",ntry
,nconv
);
159 /* Generate random box*/
160 rand_box(c
->bBox
,box
,boxsize
,nres
,c
->bCubic
,seed
);
162 /* Generate random coords */
163 rand_coords(natom
,x
,xref
,c
->weight
,c
->bCenter
,xcenter
,boxsize
,seed
);
165 /* Now correct the random coords */
166 nviol
= shake_coords(log
,bVerbose
,k
,natom
,xref
,x
,seed
,box
,c
,&nit
);
167 bConverged
= (nviol
== 0);
173 nvtest
= quick_check(bVerbose
? log
: NULL
,natom
,x
,box
,c
);
174 fprintf(stderr
,"Double checking: %d violations\n",nvtest
);
176 if (bConverged
|| keepfn
) {
177 center_in_box(natom
,x
,wrbox
,x
);
179 do_fit(natom
,w_rls
,xref
,x
);
180 write_trx(bConverged
? status
: kstatus
,
181 natom
,wr_ind
,atoms
,k
,(real
) k
,wrbox
,x
,NULL
);
189 /* Print structure coloured by the violations */
191 snew(atoms
->pdbinfo
,natom
);
192 for(kk
=0; (kk
<natom
); kk
++)
193 atoms
->pdbinfo
[kk
].bfac
= (real
) c
->bViol
[kk
];
194 gp
=ffopen(violfn
,"w");
195 write_pdbfile(gp
,"Structure coloured by violation",atoms
,x
,box
,0,-1);
202 gp
= xvgropen("conv_stat.xvg","Iterations per converged structure",
204 for(i
=0; (i
<c
->maxnit
); i
++)
205 fprintf(gp
,"%10d %10d\n",i
,nconvdist
[i
]);
212 pr_conv_stat(log
,ntry
,nconv
,tnit
);
213 pr_conv_stat(stderr
,ntry
,nconv
,tnit
);
216 int main(int argc
,char *argv
[])
218 static char *desc
[] = {
219 "disco reads a topology (tpr) file and runs distance geometry",
220 "calculations based on the distances defined in the",
221 "distance-restraints section of the topology. An appropriate tpr",
222 "file may be generated by the cdist program.[PAR]",
223 "The algorithm is the CONCOORD algorithm of De Groot et al.,",
224 "which in turn is derived from the SHAKE alogrithm.[PAR]",
225 "A parallel version of disco is under development whihc uses a",
226 "master-slave approach. Slaves work asynchronously, and it is no",
227 "problem when nodes are not equally fast, or when a node dies,",
228 "unless it is the master node."
234 t_atoms atoms
,newatoms
;
236 rvec xcm
,*xref
,*xcenter
=NULL
;
238 real t
,lambda
,tot_weight
;
239 int i
,nfit
,step
,natom
;
243 static int nstruct
=10,maxnit
=1000,seed
=1997,nbcheck
=1;
244 static int nstprint
=1,nstranlist
=0,ngrow
=0;
245 static bool bVerbose
=TRUE
,bCubic
=FALSE
,bWeight
=FALSE
,bLower
=FALSE
;
246 static real lowdev
=0.05;
247 static bool bExplicit
=FALSE
,bChiral
=TRUE
,bFit
=FALSE
,bDump
=FALSE
,bPep
=TRUE
;
248 static bool bRanlistFirst
=TRUE
;
249 static rvec boxsize
={ 2, 2, 2 };
251 { "-nf", FALSE
, etINT
, {&nstruct
},
252 "Number of structures to generate" },
253 { "-nit", FALSE
, etINT
, {&maxnit
},
254 "Max number of iterations for a structure to converge" },
255 { "-v", FALSE
, etBOOL
, {&bVerbose
},
257 { "-chiral", FALSE
, etBOOL
, {&bChiral
},
258 "Check chirality during disco-ing" },
259 { "-pep", FALSE
, etBOOL
, {&bPep
},
260 "Flip all cis-peptide bonds automatically to trans" },
261 { "-lower", FALSE
, etBOOL
, {&bLower
},
262 "Use lower bounds only for nonbondeds." },
263 { "-weighted", FALSE
, etBOOL
, {&bWeight
},
264 "Use weighted disco. The STX file must be a pdb file in this case and weights are read from the occupancy field" },
265 { "-dump", FALSE
, etBOOL
, {&bDump
},
266 "Dump the trajectory of the shaking to testX.xtc file where X is the structure number." },
267 { "-cubic", FALSE
, etBOOL
, {&bCubic
},
268 "Generate coordinates in a cubic box, rather than rectangular" },
269 { "-explicit", FALSE
, etBOOL
, {&bExplicit
},
270 "Use explicit updating of positions if the sum of deviations is smaller than lowdev" },
271 { "-fit", FALSE
, etBOOL
, {&bFit
},
272 "Fit output structures to reference structure in tpx file" },
273 { "-nbcheck", FALSE
, etINT
, {&nbcheck
},
274 "Check non-bonded interactions every N steps" },
275 { "-nstprint", FALSE
, etINT
, {&nstprint
},
276 "Print number of violations every N steps" },
277 { "-ranlist", FALSE
, etINT
, {&nstranlist
},
278 "Update list order to avoid bias every n steps" },
279 { "-ranlistfirst", FALSE
, etBOOL
, {&bRanlistFirst
},
280 "Randomize list once before shaking" },
281 { "-lowdev", FALSE
, etREAL
, {&lowdev
},
282 "Low deviation [Sum of distance deviation per atom in nm] beyond which nonbondeds are done every step" },
283 { "-seed", FALSE
, etINT
, {&seed
},
284 "Seed for the random number generator" },
285 { "-box", FALSE
, etRVEC
, {boxsize
},
286 "Boxsize (nm) for generating random coordinates" },
287 { "-grow", FALSE
, etINT
, {&ngrow
},
288 "Number of steps after which Van der Waals lower bounds grow from 0 to the real lower bounds. If this is 0 (default), the Van der Waals lower bounds are in effect from the beginning" }
291 #define NPA asize(pa)
294 { efLOG
, "-g", "disco", ffWRITE
},
295 { efSTX
, "-f", NULL
, ffREAD
},
296 { efDAT
, "-d", "cdist", ffREAD
},
297 { efDAT
, "-do", "distout", ffOPTWR
},
298 { efSTO
, "-c", NULL
, ffREAD
},
299 { efSTO
, "-center", NULL
, ffOPTRD
},
300 { efNDX
, "-n", NULL
, ffOPTRD
},
301 { efTRX
, "-o", "structs", ffWRITE
},
302 { efTRX
, "-keep", "unconverged", ffOPTWR
},
303 { efPDB
, "-viol", "vvv", ffOPTWR
}
305 #define NFILE asize(fnm)
307 cr
= init_par(&argc
,&argv
);
308 bVerbose
= bVerbose
&& MASTER(cr
);
311 CopyRight(stderr
,argv
[0]);
313 parse_common_args(&argc
,argv
,PCA_BE_NICE
,
314 NFILE
,fnm
,NPA
,pa
,asize(desc
),desc
,0,NULL
);
316 /* Copy arguments to correct structure */
317 bCenter
= opt2bSet("-center",NFILE
,fnm
);
318 bBox
= opt2parg_bSet("-box",asize(pa
),pa
),
319 corr
= init_corr(maxnit
,nstprint
,nbcheck
,nstranlist
,ngrow
,bExplicit
,
320 bChiral
,bPep
,bDump
,lowdev
,bLower
,bRanlistFirst
,
321 bCubic
,bBox
,bCenter
);
323 /* Open the log file */
324 open_log(ftp2fn(efLOG
,NFILE
,fnm
),cr
);
327 CopyRight(stdlog
,argv
[0]);
328 please_cite(stdlog
,"Ryckaert77a");
329 please_cite(stdlog
,"DeGroot97a");
333 /* Get number of atoms etc. */
334 get_stx_coordnum(ftp2fn(efSTX
,NFILE
,fnm
),&natom
);
336 init_t_atoms(&atoms
,natom
,bWeight
);
338 read_stx_conf(ftp2fn(efSTX
,NFILE
,fnm
),title
,&atoms
,xref
,NULL
,box
);
340 /* Translate reference and xcenter coords to C.O.M. */
341 sub_xcm(xref
,natom
,NULL
,NULL
,xcm
,FALSE
);
343 snew(corr
->weight
,natom
);
345 for(i
=0; (i
<natom
); i
++) {
346 corr
->weight
[i
] = bWeight
? atoms
.pdbinfo
[i
].occup
: 1;
347 tot_weight
+= corr
->weight
[i
];
350 fprintf(stderr
,"Reading distances from %s\n",opt2fn("-d",NFILE
,fnm
));
351 read_dist(stdlog
,opt2fn("-d",NFILE
,fnm
),natom
,corr
);
353 /* Dump a distance file if necessary */
354 if (opt2bSet("-do",NFILE
,fnm
)) {
355 dp
= fopen(opt2fn("-do",NFILE
,fnm
),"w");
356 pr_distances(dp
,corr
);
360 /* Check distances */
361 check_dist(stdlog
,corr
);
363 /* Read index if necessary */
365 fprintf(stderr
,"Select group for fitting output structures:\n");
366 get_index(&atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),1,
367 &nfit
,&fit_ind
,&grpname
);
374 /* Read centers for generating coordinates (optional) */
377 init_t_atoms(&newatoms
,natom
,TRUE
);
378 read_stx_conf(opt2fn("-center",NFILE
,fnm
),title
,
379 &newatoms
,xcenter
,NULL
,box
);
380 free_t_atoms(&newatoms
);
382 for(i
=0; (i
<natom
); i
++)
383 rvec_dec(xcenter
[i
],xcm
);
387 * define improper dihedrals that are not automatically correct
388 * when all distances are correct
390 define_impropers(stdlog
,&atoms
,corr
);
392 /* define peptide-bonds, so we can correct cis to trans
393 * Adam Kirrander 990121
395 define_peptide_bonds(stdlog
,&atoms
,corr
);
397 /* Print parameters */
398 pr_corr(stdlog
,corr
);
401 /* Now do my thing */
405 disco_master(cr
,stdlog
,opt2fn("-o",NFILE
,fnm
),
406 opt2bSet("-keep",NFILE
,fnm
) ? opt2fn("-keep",NFILE
,fnm
) : NULL
,
407 corr
,bVerbose
,&atoms
,
408 xref
,xcenter
,nstruct
,&seed
,bFit
,nfit
,fit_ind
,
409 opt2bSet("-viol",NFILE
,fnm
),opt2fn("-viol",NFILE
,fnm
),boxsize
);
411 disco_slave(cr
,stdlog
);
415 do_disco(stdlog
,opt2fn("-o",NFILE
,fnm
),
416 opt2bSet("-keep",NFILE
,fnm
) ? opt2fn("-keep",NFILE
,fnm
) : NULL
,
417 corr
,bVerbose
,&atoms
,
418 xref
,xcenter
,nstruct
,&seed
,bFit
,nfit
,fit_ind
,
419 opt2bSet("-viol",NFILE
,fnm
),opt2fn("-viol",NFILE
,fnm
),