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
42 #include "gromacs/fileio/confio.h"
47 #include "gmx_fatal.h"
48 #include "gromacs/fileio/trxio.h"
51 static real dointerp(int n, rvec x1[], rvec x2[], rvec xx[],
52 int I, int N, real first, real last)
55 double fac, fac0, fac1;
57 fac = first + (I*(last-first))/(N-1);
60 for (i = 0; (i < n); i++)
62 for (j = 0; (j < DIM); j++)
64 xx[i][j] = fac0*x1[i][j] + fac1*x2[i][j];
71 int gmx_morph(int argc, char *argv[])
73 const char *desc[] = {
74 "[TT]g_morph[tt] does a linear interpolation of conformations in order to",
75 "create intermediates. Of course these are completely unphysical, but",
76 "that you may try to justify yourself. Output is in the form of a ",
77 "generic trajectory. The number of intermediates can be controlled with",
78 "the [TT]-ninterm[tt] flag. The first and last flag correspond to the way of",
79 "interpolating: 0 corresponds to input structure 1 while",
80 "1 corresponds to input structure 2.",
81 "If you specify [TT]-first[tt] < 0 or [TT]-last[tt] > 1 extrapolation will be",
82 "on the path from input structure x[SUB]1[sub] to x[SUB]2[sub]. In general, the coordinates",
83 "of the intermediate x(i) out of N total intermediates correspond to:[PAR]",
84 "x(i) = x[SUB]1[sub] + (first+(i/(N-1))*(last-first))*(x[SUB]2[sub]-x[SUB]1[sub])[PAR]",
85 "Finally the RMSD with respect to both input structures can be computed",
86 "if explicitly selected ([TT]-or[tt] option). In that case, an index file may be",
87 "read to select the group from which the RMS is computed."
90 { efSTX, "-f1", "conf1", ffREAD },
91 { efSTX, "-f2", "conf2", ffREAD },
92 { efTRX, "-o", "interm", ffWRITE },
93 { efXVG, "-or", "rms-interm", ffOPTWR },
94 { efNDX, "-n", "index", ffOPTRD }
96 #define NFILE asize(fnm)
97 static int ninterm = 11;
98 static real first = 0.0;
99 static real last = 1.0;
100 static gmx_bool bFit = TRUE;
102 { "-ninterm", FALSE, etINT, {&ninterm},
103 "Number of intermediates" },
104 { "-first", FALSE, etREAL, {&first},
105 "Corresponds to first generated structure (0 is input x[SUB]1[sub], see above)" },
106 { "-last", FALSE, etREAL, {&last},
107 "Corresponds to last generated structure (1 is input x[SUB]2[sub], see above)" },
108 { "-fit", FALSE, etBOOL, {&bFit},
109 "Do a least squares fit of the second to the first structure before interpolating" }
111 const char *leg[] = { "Ref = 1\\Sst\\N conf", "Ref = 2\\Snd\\N conf" };
113 int i, isize, is_lsq, nat1, nat2;
115 atom_id *index, *index_lsq, *index_all, *dummy;
117 rvec *x1, *x2, *xx, *v;
119 real rms1, rms2, fac, *mass;
120 char title[STRLEN], *grpname;
124 if (!parse_common_args(&argc, argv, PCA_CAN_VIEW,
125 NFILE, fnm, asize(pa), pa, asize(desc), desc,
130 get_stx_coordnum (opt2fn("-f1", NFILE, fnm), &nat1);
131 get_stx_coordnum (opt2fn("-f2", NFILE, fnm), &nat2);
134 gmx_fatal(FARGS, "Number of atoms in first structure is %d, in second %d",
138 init_t_atoms(&atoms, nat1, TRUE);
144 read_stx_conf(opt2fn("-f1", NFILE, fnm), title, &atoms, x1, v, NULL, box);
145 read_stx_conf(opt2fn("-f2", NFILE, fnm), title, &atoms, x2, v, NULL, box);
148 snew(index_all, nat1);
149 for (i = 0; (i < nat1); i++)
156 printf("Select group for LSQ superposition:\n");
157 get_index(&atoms, opt2fn_null("-n", NFILE, fnm), 1, &is_lsq, &index_lsq,
159 reset_x(is_lsq, index_lsq, nat1, index_all, x1, mass);
160 reset_x(is_lsq, index_lsq, nat1, index_all, x2, mass);
161 do_fit(nat1, mass, x1, x2);
164 bRMS = opt2bSet("-or", NFILE, fnm);
167 fp = xvgropen(opt2fn("-or", NFILE, fnm), "RMSD", "Conf", "(nm)", oenv);
168 xvgr_legend(fp, asize(leg), leg, oenv);
169 printf("Select group for RMSD calculation:\n");
170 get_index(&atoms, opt2fn_null("-n", NFILE, fnm), 1, &isize, &index, &grpname);
171 printf("You selected group %s, containing %d atoms\n", grpname, isize);
172 rms1 = rmsdev_ind(isize, index, mass, x1, x2);
173 fprintf(stderr, "RMSD between input conformations is %g nm\n", rms1);
177 for (i = 0; (i < nat1); i++)
181 status = open_trx(ftp2fn(efTRX, NFILE, fnm), "w");
183 for (i = 0; (i < ninterm); i++)
185 fac = dointerp(nat1, x1, x2, xx, i, ninterm, first, last);
186 write_trx(status, nat1, dummy, &atoms, i, fac, box, xx, NULL, NULL);
189 rms1 = rmsdev_ind(isize, index, mass, x1, xx);
190 rms2 = rmsdev_ind(isize, index, mass, x2, xx);
191 fprintf(fp, "%10g %10g %10g\n", fac, rms1, rms2);
200 do_view(oenv, opt2fn("-or", NFILE, fnm), "-nxy");