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 * Green Red Orange Magenta Azure Cyan Skyblue
49 #include "gmx_fatal.h"
61 static void norm_princ(t_atoms *atoms, int isize, atom_id *index, int natoms,
67 /* equalize principal components: */
68 /* orient principal axes, get principal components */
69 orient_princ(atoms, isize, index, natoms, x, NULL, princ);
71 /* calc our own principal components */
73 for (m = 0; m < DIM; m++)
75 for (i = 0; i < isize; i++)
76 vec[m] += sqr(x[index[i]][m]);
77 vec[m] = sqrt(vec[m] / isize);
78 /* calculate scaling constants */
79 vec[m] = 1 / (sqrt(3) * vec[m]);
82 /* scale coordinates */
83 for (i = 0; i < natoms; i++)
85 for (m = 0; m < DIM; m++)
92 int gmx_rms(int argc, char *argv[])
97 "g_rms compares two structures by computing the root mean square",
98 "deviation (RMSD), the size-independent 'rho' similarity parameter",
99 "(rho) or the scaled rho (rhosc), ",
100 "see Maiorov & Crippen, PROTEINS [BB]22[bb], 273 (1995).",
101 "This is selected by [TT]-what[tt].[PAR]"
103 "Each structure from a trajectory ([TT]-f[tt]) is compared to a",
104 "reference structure. The reference structure",
105 "is taken from the structure file ([TT]-s[tt]).[PAR]",
107 "With option [TT]-mir[tt] also a comparison with the mirror image of",
108 "the reference structure is calculated.",
109 "This is useful as a reference for 'significant' values, see",
110 "Maiorov & Crippen, PROTEINS [BB]22[bb], 273 (1995).[PAR]",
112 "Option [TT]-prev[tt] produces the comparison with a previous frame",
113 "the specified number of frames ago.[PAR]",
115 "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of",
116 "comparison values of each structure in the trajectory with respect to",
117 "each other structure. This file can be visualized with for instance",
118 "[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].[PAR]",
120 "Option [TT]-fit[tt] controls the least-squares fitting of",
121 "the structures on top of each other: complete fit (rotation and",
122 "translation), translation only, or no fitting at all.[PAR]",
124 "Option [TT]-mw[tt] controls whether mass weighting is done or not.",
125 "If you select the option (default) and ",
126 "supply a valid tpr file masses will be taken from there, ",
127 "otherwise the masses will be deduced from the atommass.dat file in",
128 "the GROMACS library directory. This is fine for proteins but not",
129 "necessarily for other molecules. A default mass of 12.011 amu (Carbon)",
130 "is assigned to unknown atoms. You can check whether this happend by",
131 "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]",
133 "With [TT]-f2[tt], the 'other structures' are taken from a second",
134 "trajectory, this generates a comparison matrix of one trajectory",
135 "versus the other.[PAR]",
137 "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]",
139 "Option [TT]-bm[tt] produces a matrix of average bond angle deviations",
140 "analogously to the [TT]-m[tt] option. Only bonds between atoms in the",
141 "comparison group are considered." };
142 static bool bPBC = TRUE, bFitAll = TRUE, bSplit = FALSE;
143 static bool bDeltaLog = FALSE;
144 static int prev = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0;
145 static real rmsd_user_max = -1, rmsd_user_min = -1, bond_user_max = -1,
146 bond_user_min = -1, delta_maxy = 0.0;
147 /* strings and things for selecting difference method */
150 ewSel, ewRMSD, ewRho, ewRhoSc, ewNR
153 const char *what[ewNR + 1] =
154 { NULL, "rmsd", "rho", "rhosc", NULL };
155 const char *whatname[ewNR] =
156 { NULL, "RMSD", "Rho", "Rho sc" };
157 const char *whatlabel[ewNR] =
158 { NULL, "RMSD (nm)", "Rho", "Rho sc" };
159 const char *whatxvgname[ewNR] =
160 { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" };
161 const char *whatxvglabel[ewNR] =
162 { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" };
163 /* strings and things for fitting methods */
166 efSel, efFit, efReset, efNone, efNR
169 const char *fit[efNR + 1] =
170 { NULL, "rot+trans", "translation", "none", NULL };
171 const char *fitgraphlabel[efNR + 1] =
172 { NULL, "lsq fit", "translational fit", "no fit" };
174 static bool bMassWeighted = TRUE;
177 { "-what", FALSE, etENUM,
178 { what }, "Structural difference measure" },
179 { "-pbc", FALSE, etBOOL,
180 { &bPBC }, "PBC check" },
181 { "-fit", FALSE, etENUM,
182 { fit }, "Fit to reference structure" },
183 { "-prev", FALSE, etINT,
184 { &prev }, "Compare with previous frame" },
185 { "-split", FALSE, etBOOL,
186 { &bSplit }, "Split graph where time is zero" },
187 { "-fitall", FALSE, etBOOL,
188 { &bFitAll }, "HIDDENFit all pairs of structures in matrix" },
189 { "-skip", FALSE, etINT,
190 { &freq }, "Only write every nr-th frame to matrix" },
191 { "-skip2", FALSE, etINT,
192 { &freq2 }, "Only write every nr-th frame to matrix" },
193 { "-max", FALSE, etREAL,
194 { &rmsd_user_max }, "Maximum level in comparison matrix" },
195 { "-min", FALSE, etREAL,
196 { &rmsd_user_min }, "Minimum level in comparison matrix" },
197 { "-bmax", FALSE, etREAL,
198 { &bond_user_max }, "Maximum level in bond angle matrix" },
199 { "-bmin", FALSE, etREAL,
200 { &bond_user_min }, "Minimum level in bond angle matrix" },
201 { "-mw", FALSE, etBOOL,
202 { &bMassWeighted }, "Use mass weighting for superposition" },
203 { "-nlevels", FALSE, etINT,
204 { &nlevels }, "Number of levels in the matrices" },
205 { "-ng", FALSE, etINT,
206 { &nrms }, "Number of groups to compute RMS between" },
207 { "-dlog", FALSE, etBOOL,
209 "HIDDENUse a log x-axis in the delta t matrix" },
210 { "-dmax", FALSE, etREAL,
211 { &delta_maxy }, "HIDDENMaximum level in delta matrix" },
212 { "-aver", FALSE, etINT,
214 "HIDDENAverage over this distance in the RMSD matrix" } };
216 int i, j, k, m, teller, teller2, tel_mat, tel_mat2;
218 int maxframe = NFRAME, maxframe2 = NFRAME;
219 real t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL;
220 bool bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass;
224 t_iatom *iatom = NULL;
227 rvec *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
230 char buf[256], buf2[256];
233 real rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL,
234 **rmsd_mat = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis,
235 *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang;
236 real **rmsdav_mat = NULL, av_tot, weight, weight_tot;
237 real **delta = NULL, delta_max, delta_scalex = 0, delta_scaley = 0,
239 int delta_xsize = 0, del_lev = 100, mx, my, abs_my;
240 bool bA1, bA2, bPrev, bTop, *bInMat = NULL;
241 int ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m =
243 atom_id *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m =
245 char *gn_fit, **gn_rms;
248 gmx_rmpbc_t gpbc=NULL;
252 { efTPS, NULL, NULL, ffREAD },
253 { efTRX, "-f", NULL, ffREAD },
254 { efTRX, "-f2", NULL, ffOPTRD },
255 { efNDX, NULL, NULL, ffOPTRD },
256 { efXVG, NULL, "rmsd", ffWRITE },
257 { efXVG, "-mir", "rmsdmir", ffOPTWR },
258 { efXVG, "-a", "avgrp", ffOPTWR },
259 { efXVG, "-dist", "rmsd-dist", ffOPTWR },
260 { efXPM, "-m", "rmsd", ffOPTWR },
261 { efDAT, "-bin", "rmsd", ffOPTWR },
262 { efXPM, "-bm", "bond", ffOPTWR } };
263 #define NFILE asize(fnm)
265 CopyRight(stderr, argv[0]);
266 parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW
267 | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL,
269 /* parse enumerated options: */
271 if (ewhat == ewRho || ewhat == ewRhoSc)
272 please_cite(stdout, "Maiorov95");
274 bFit = efit == efFit;
275 bReset = efit == efReset;
278 bReset = TRUE; /* for fit, reset *must* be set */
285 /* mark active cmdline options */
286 bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */
287 bFile2 = opt2bSet("-f2", NFILE, fnm);
288 bMat = opt2bSet("-m", NFILE, fnm);
289 bBond = opt2bSet("-bm", NFILE, fnm);
290 bDelta = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from *
291 * your RMSD matrix (hidden option */
292 bNorm = opt2bSet("-a", NFILE, fnm);
293 bFreq2 = opt2parg_bSet("-skip2", asize(pa), pa);
296 fprintf(stderr, "The number of frames to skip is <= 0. "
297 "Writing out all frames.\n\n");
304 else if (bFile2 && freq2 <= 0)
307 "The number of frames to skip in second trajectory is <= 0.\n"
308 " Writing out all frames.\n\n");
317 fprintf(stderr, "WARNING: option -skip also applies to -prev\n");
320 if (bFile2 && !bMat && !bBond)
324 "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n"
325 " will not read from %s\n", opt2fn("-f2", NFILE,
336 "WARNING: second trajectory (-f2) useless when making delta matrix,\n"
337 " will not read from %s\n", opt2fn("-f2",
343 bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp,
345 snew(w_rls,top.atoms.nr);
346 snew(w_rms,top.atoms.nr);
351 "WARNING: Need a run input file for bond angle matrix,\n"
352 " will not calculate bond angle matrix.\n");
358 fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares"
360 get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit,
368 if (bFit && ifit < 3)
369 gmx_fatal(FARGS,"Need >= 3 points to fit!\n" );
372 for(i=0; i<ifit; i++)
375 w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m;
377 w_rls[ind_fit[i]] = 1;
378 bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0);
382 fprintf(stderr,"All masses in the fit group are 0, using masses of 1\n");
383 for(i=0; i<ifit; i++)
385 w_rls[ind_fit[i]] = 1;
397 fprintf(stderr,"Select group%s for %s calculation\n",
398 (nrms>1) ? "s" : "",whatname[ewhat]);
399 get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm),
400 nrms,irms,ind_rms,gn_rms);
404 snew(rlsnorm,irms[0]);
407 for(j=0; j<nrms; j++)
408 snew(rls[j],maxframe);
412 for(j=0; j<nrms; j++)
413 snew(rlsm[j],maxframe);
416 for(j=0; j<nrms; j++)
419 for(i=0; i<irms[j]; i++)
422 w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m;
424 w_rms[ind_rms[j][i]] = 1.0;
425 bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0);
428 fprintf(stderr,"All masses in group %d are 0, using masses of 1\n",j);
429 for(i=0; i<irms[j]; i++)
430 w_rms[ind_rms[j][i]] = 1;
433 /* Prepare reference frame */
435 gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,box);
436 gmx_rmpbc(gpbc,top.atoms.nr,box,xp);
439 reset_x(ifit,ind_fit,top.atoms.nr,NULL,xp,w_rls);
441 /* generate reference structure mirror image: */
442 snew(xm, top.atoms.nr);
443 for(i=0; i<top.atoms.nr; i++) {
444 copy_rvec(xp[i],xm[i]);
445 xm[i][XX] = -xm[i][XX];
449 norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp);
451 /* read first frame */
452 natoms=read_first_x(oenv,&status,opt2fn("-f",NFILE,fnm),&t,&x,box);
453 if (natoms != top.atoms.nr)
455 "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
456 top.atoms.nr,natoms);
457 if (bMat || bBond || bPrev) {
461 /* With -prev we use all atoms for simplicity */
464 /* Check which atoms we need (fit/rms) */
466 for(i=0; i<ifit; i++)
467 bInMat[ind_fit[i]] = TRUE;
469 for(i=0; i<irms[0]; i++)
470 if (!bInMat[ind_rms[0][i]]) {
471 bInMat[ind_rms[0][i]] = TRUE;
475 /* Make an index of needed atoms */
477 snew(rev_ind_m,natoms);
479 for(i=0; i<natoms; i++)
480 if (bPrev || bInMat[i]) {
485 snew(w_rls_m,n_ind_m);
486 snew(ind_rms_m,irms[0]);
487 snew(w_rms_m,n_ind_m);
488 for(i=0; i<ifit; i++)
489 w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]];
490 for(i=0; i<irms[0]; i++) {
491 ind_rms_m[i] = rev_ind_m[ind_rms[0][i]];
492 w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]];
499 for(k=0; k<F_NRE; k++)
500 if (IS_CHEMBOND(k)) {
501 iatom = top.idef.il[k].iatoms;
502 ncons += top.idef.il[k].nr/3;
504 fprintf(stderr,"Found %d bonds in topology\n",ncons);
505 snew(ind_bond1,ncons);
506 snew(ind_bond2,ncons);
508 for(k=0; k<F_NRE; k++)
509 if (IS_CHEMBOND(k)) {
510 iatom = top.idef.il[k].iatoms;
511 ncons = top.idef.il[k].nr/3;
512 for (i=0; i<ncons; i++) {
515 for (j=0; j<irms[0]; j++) {
516 if (iatom[3*i+1] == ind_rms[0][j]) bA1=TRUE;
517 if (iatom[3*i+2] == ind_rms[0][j]) bA2=TRUE;
520 ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]];
521 ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]];
526 fprintf(stderr,"Using %d bonds for bond angle matrix\n",ibond);
528 gmx_fatal(FARGS,"0 bonds found");
531 /* start looping over frames: */
536 gmx_rmpbc(gpbc,natoms,box,x);
539 reset_x(ifit,ind_fit,natoms,NULL,x,w_rls);
541 norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
544 /*do the least squares fit to original structure*/
545 do_fit(natoms,w_rls,xp,x);
547 if (teller % freq == 0) {
548 /* keep frame for matrix calculation */
549 if (bMat || bBond || bPrev) {
550 if (tel_mat >= NFRAME)
551 srenew(mat_x,tel_mat+1);
552 snew(mat_x[tel_mat],n_ind_m);
553 for (i=0;i<n_ind_m;i++)
554 copy_rvec(x[ind_m[i]],mat_x[tel_mat][i]);
559 /*calculate energy of root_least_squares*/
564 for (i=0;i<n_ind_m;i++)
565 copy_rvec(mat_x[j][i],xp[ind_m[i]]);
567 reset_x(ifit,ind_fit,natoms,NULL,xp,w_rls);
569 do_fit(natoms,w_rls,x,xp);
571 for(j=0; (j<nrms); j++)
573 calc_similar_ind(ewhat!=ewRMSD,irms[j],ind_rms[j],w_rms,x,xp);
575 for(j=0; (j<irms[0]); j++)
577 calc_similar_ind(ewhat!=ewRMSD,1,&(ind_rms[0][j]),w_rms,x,xp);
582 /*do the least squares fit to mirror of original structure*/
583 do_fit(natoms,w_rls,xm,x);
585 for(j=0; j<nrms; j++)
587 calc_similar_ind(ewhat!=ewRMSD,irms[j],ind_rms[j],w_rms,x,xm);
589 time[teller]=output_env_conv_time(oenv,t);
592 if (teller >= maxframe) {
594 srenew(time,maxframe);
595 for(j=0; (j<nrms); j++)
596 srenew(rls[j],maxframe);
598 for(j=0; (j<nrms); j++)
599 srenew(rlsm[j],maxframe);
601 } while (read_next_x(oenv,status,&t,natoms,x,box));
605 snew(time2,maxframe2);
607 fprintf(stderr,"\nWill read second trajectory file\n");
609 natoms2=read_first_x(oenv,&status,opt2fn("-f2",NFILE,fnm),&t,&x,box);
610 if ( natoms2 != natoms )
612 "Second trajectory (%d atoms) does not match the first one"
613 " (%d atoms)", natoms2, natoms);
618 gmx_rmpbc(gpbc,natoms,box,x);
621 reset_x(ifit,ind_fit,natoms,NULL,x,w_rls);
623 norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
626 /*do the least squares fit to original structure*/
627 do_fit(natoms,w_rls,xp,x);
629 if (teller2 % freq2 == 0) {
630 /* keep frame for matrix calculation */
632 if (tel_mat2 >= NFRAME)
633 srenew(mat_x2,tel_mat2+1);
634 snew(mat_x2[tel_mat2],n_ind_m);
635 for (i=0;i<n_ind_m;i++)
636 copy_rvec(x[ind_m[i]],mat_x2[tel_mat2][i]);
641 time2[teller2]=output_env_conv_time(oenv,t);
644 if (teller2 >= maxframe2) {
646 srenew(time2,maxframe2);
648 } while (read_next_x(oenv,status,&t,natoms,x,box));
656 gmx_rmpbc_done(gpbc);
659 /* calculate RMS matrix */
660 fprintf(stderr,"\n");
662 fprintf(stderr,"Building %s matrix, %dx%d elements\n",
663 whatname[ewhat],tel_mat,tel_mat2);
664 snew(rmsd_mat,tel_mat);
667 fprintf(stderr,"Building bond angle matrix, %dx%d elements\n",
669 snew(bond_mat,tel_mat);
672 snew(axis2,tel_mat2);
681 for(j=0; j<tel_mat2; j++)
682 axis2[j]=time2[freq2*j];
685 delta_scalex=8.0/log(2.0);
686 delta_xsize=(int)(log(tel_mat/2)*delta_scalex+0.5)+1;
689 delta_xsize=tel_mat/2;
691 delta_scaley=1.0/delta_maxy;
692 snew(delta,delta_xsize);
693 for(j=0; j<delta_xsize; j++)
694 snew(delta[j],del_lev+1);
696 snew(rmsdav_mat,tel_mat);
697 for(j=0; j<tel_mat; j++)
698 snew(rmsdav_mat[j],tel_mat);
703 snew(mat_x2_j,natoms);
704 for(i=0; i<tel_mat; i++) {
705 axis[i]=time[freq*i];
706 fprintf(stderr,"\r element %5d; time %5.2f ",i,axis[i]);
707 if (bMat) snew(rmsd_mat[i],tel_mat2);
708 if (bBond) snew(bond_mat[i],tel_mat2);
709 for(j=0; j<tel_mat2; j++) {
711 for (k=0;k<n_ind_m;k++)
712 copy_rvec(mat_x2[j][k],mat_x2_j[k]);
713 do_fit(n_ind_m,w_rls_m,mat_x[i],mat_x2_j);
717 if (bFile2 || (i<j)) {
719 calc_similar_ind(ewhat!=ewRMSD,irms[0],ind_rms_m,
720 w_rms_m,mat_x[i],mat_x2_j);
721 if (rmsd_mat[i][j] > rmsd_max) rmsd_max=rmsd_mat[i][j];
722 if (rmsd_mat[i][j] < rmsd_min) rmsd_min=rmsd_mat[i][j];
723 rmsd_avg += rmsd_mat[i][j];
725 rmsd_mat[i][j]=rmsd_mat[j][i];
728 if (bFile2 || (i<=j)) {
730 for(m=0;m<ibond;m++) {
731 rvec_sub(mat_x[i][ind_bond1[m]],mat_x[i][ind_bond2[m]],vec1);
732 rvec_sub(mat_x2_j[ind_bond1[m]],mat_x2_j[ind_bond2[m]],vec2);
733 ang += acos(cos_angle(vec1,vec2));
735 bond_mat[i][j]=ang*180.0/(M_PI*ibond);
736 if (bond_mat[i][j] > bond_max) bond_max=bond_mat[i][j];
737 if (bond_mat[i][j] < bond_min) bond_min=bond_mat[i][j];
740 bond_mat[i][j]=bond_mat[j][i];
745 rmsd_avg /= tel_mat*tel_mat2;
747 rmsd_avg /= tel_mat*(tel_mat - 1)/2;
748 if (bMat && (avl > 0)) {
752 for(j=0; j<tel_mat-1; j++) {
753 for(i=j+1; i<tel_mat; i++) {
756 for (my=-avl; my<=avl; my++) {
757 if ((j+my>=0) && (j+my<tel_mat)) {
759 for (mx=-avl; mx<=avl; mx++) {
760 if ((i+mx>=0) && (i+mx<tel_mat)) {
761 weight = (real)(avl+1-max(abs(mx),abs_my));
762 av_tot += weight*rmsd_mat[i+mx][j+my];
768 rmsdav_mat[i][j] = av_tot/weight_tot;
769 rmsdav_mat[j][i] = rmsdav_mat[i][j];
770 if (rmsdav_mat[i][j] > rmsd_max) rmsd_max=rmsdav_mat[i][j];
777 fprintf(stderr,"\n%s: Min %f, Max %f, Avg %f\n",
778 whatname[ewhat],rmsd_min,rmsd_max,rmsd_avg);
779 rlo.r = 1; rlo.g = 1; rlo.b = 1;
780 rhi.r = 0; rhi.g = 0; rhi.b = 0;
781 if (rmsd_user_max != -1) rmsd_max=rmsd_user_max;
782 if (rmsd_user_min != -1) rmsd_min=rmsd_user_min;
783 if ((rmsd_user_max != -1) || (rmsd_user_min != -1))
784 fprintf(stderr,"Min and Max value set to resp. %f and %f\n",
786 sprintf(buf,"%s %s matrix",gn_rms[0],whatname[ewhat]);
787 write_xpm(opt2FILE("-m",NFILE,fnm,"w"),0,buf,whatlabel[ewhat],
788 output_env_get_time_label(oenv),output_env_get_time_label(oenv),tel_mat,tel_mat2,
789 axis,axis2, rmsd_mat,rmsd_min,rmsd_max,rlo,rhi,&nlevels);
790 /* Print the distribution of RMSD values */
791 if (opt2bSet("-dist",NFILE,fnm))
792 low_rmsd_dist(opt2fn("-dist",NFILE,fnm),rmsd_max,tel_mat,rmsd_mat,oenv);
795 snew(delta_tot,delta_xsize);
796 for(j=0; j<tel_mat-1; j++) {
797 for(i=j+1; i<tel_mat; i++) {
799 if (mx < tel_mat/2) {
801 mx=(int)(log(mx)*delta_scalex+0.5);
802 my=(int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5);
803 delta_tot[mx] += 1.0;
804 if ((rmsd_mat[i][j]>=0) && (rmsd_mat[i][j]<=delta_maxy))
805 delta[mx][my] += 1.0;
810 for(i=0; i<delta_xsize; i++) {
811 if (delta_tot[i] > 0.0) {
812 delta_tot[i]=1.0/delta_tot[i];
813 for(j=0; j<=del_lev; j++) {
814 delta[i][j] *= delta_tot[i];
815 if (delta[i][j] > delta_max)
816 delta_max=delta[i][j];
820 fprintf(stderr,"Maximum in delta matrix: %f\n",delta_max);
821 snew(del_xaxis,delta_xsize);
822 snew(del_yaxis,del_lev+1);
823 for (i=0; i<delta_xsize; i++)
824 del_xaxis[i]=axis[i]-axis[0];
825 for (i=0; i<del_lev+1; i++)
826 del_yaxis[i]=delta_maxy*i/del_lev;
827 sprintf(buf,"%s %s vs. delta t",gn_rms[0],whatname[ewhat]);
828 fp = ffopen("delta.xpm","w");
829 write_xpm(fp,0,buf,"density",output_env_get_time_label(oenv),whatlabel[ewhat],
830 delta_xsize,del_lev+1,del_xaxis,del_yaxis,
831 delta,0.0,delta_max,rlo,rhi,&nlevels);
834 if (opt2bSet("-bin",NFILE,fnm)) {
835 /* NB: File must be binary if we use fwrite */
836 fp=ftp2FILE(efDAT,NFILE,fnm,"wb");
837 for(i=0;i<tel_mat;i++)
838 if(fwrite(rmsd_mat[i],sizeof(**rmsd_mat),tel_mat2,fp) != tel_mat2)
840 gmx_fatal(FARGS,"Error writing to output file");
846 fprintf(stderr,"\nMin. angle: %f, Max. angle: %f\n",bond_min,bond_max);
847 if (bond_user_max != -1) bond_max=bond_user_max;
848 if (bond_user_min != -1) bond_min=bond_user_min;
849 if ((bond_user_max != -1) || (bond_user_min != -1))
850 fprintf(stderr,"Bond angle Min and Max set to:\n"
851 "Min. angle: %f, Max. angle: %f\n",bond_min,bond_max);
852 rlo.r = 1; rlo.g = 1; rlo.b = 1;
853 rhi.r = 0; rhi.g = 0; rhi.b = 0;
854 sprintf(buf,"%s av. bond angle deviation",gn_rms[0]);
855 write_xpm(opt2FILE("-bm",NFILE,fnm,"w"),0,buf,"degrees",
856 output_env_get_time_label(oenv),output_env_get_time_label(oenv),tel_mat,tel_mat2,
857 axis,axis2, bond_mat,bond_min,bond_max,rlo,rhi,&nlevels);
861 bAv=opt2bSet("-a",NFILE,fnm);
863 /* Write the RMSD's to file */
865 sprintf(buf,"%s",whatxvgname[ewhat]);
867 sprintf(buf,"%s with frame %g %s ago",whatxvgname[ewhat],
868 time[prev*freq]-time[0], output_env_get_time_label(oenv));
869 fp=xvgropen(opt2fn("-o",NFILE,fnm),buf,output_env_get_xvgr_tlabel(oenv),
870 whatxvglabel[ewhat], oenv);
871 if (output_env_get_print_xvgr_codes(oenv))
872 fprintf(fp,"@ subtitle \"%s%s after %s%s%s\"\n",
873 (nrms==1)?"":"of " , gn_rms[0], fitgraphlabel[efit],
874 bFit ?" to ":"" , bFit?gn_fit:"");
876 xvgr_legend(fp,nrms,(const char**)gn_rms,oenv);
877 for(i=0; (i<teller); i++) {
878 if ( bSplit && i>0 &&
879 abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv))<1e-5 )
883 fprintf(fp,"%12.7f",time[bPrev ? freq*i : i]);
884 for(j=0; (j<nrms); j++) {
885 fprintf(fp," %12.7f",rls[j][i]);
894 /* Write the mirror RMSD's to file */
895 sprintf(buf,"%s with Mirror",whatxvgname[ewhat]);
896 sprintf(buf2,"Mirror %s",whatxvglabel[ewhat]);
897 fp=xvgropen(opt2fn("-mir",NFILE,fnm), buf, output_env_get_xvgr_tlabel(oenv),
900 if (output_env_get_print_xvgr_codes(oenv))
901 fprintf(fp,"@ subtitle \"of %s after lsq fit to mirror of %s\"\n",
905 if (output_env_get_print_xvgr_codes(oenv))
906 fprintf(fp,"@ subtitle \"after lsq fit to mirror %s\"\n",gn_fit);
907 xvgr_legend(fp,nrms,(const char**)gn_rms,oenv);
909 for(i=0; (i<teller); i++) {
910 if ( bSplit && i>0 && abs(time[i])<1e-5 )
912 fprintf(fp,"%12.7f",time[i]);
913 for(j=0; (j<nrms); j++)
914 fprintf(fp," %12.7f",rlsm[j][i]);
921 sprintf(buf,"Average %s",whatxvgname[ewhat]);
922 sprintf(buf2,"Average %s",whatxvglabel[ewhat]);
923 fp = xvgropen(opt2fn("-a",NFILE,fnm), buf, "Residue", buf2,oenv);
924 for(j=0; (j<nrms); j++)
925 fprintf(fp,"%10d %10g\n",j,rlstot/teller);
930 fp = xvgropen("aver.xvg",gn_rms[0],"Residue",whatxvglabel[ewhat],oenv);
931 for(j=0; (j<irms[0]); j++)
932 fprintf(fp,"%10d %10g\n",j,rlsnorm[j]/teller);
935 do_view(oenv,opt2fn_null("-a",NFILE,fnm),"-graphtype bar");
936 do_view(oenv,opt2fn("-o",NFILE,fnm),NULL);
937 do_view(oenv,opt2fn_null("-mir",NFILE,fnm),NULL);
938 do_view(oenv,opt2fn_null("-m",NFILE,fnm),NULL);
939 do_view(oenv,opt2fn_null("-bm",NFILE,fnm),NULL);
940 do_view(oenv,opt2fn_null("-dist",NFILE,fnm),NULL);