Parallel vs. sequentiual code: I get binary identical result (apart from comment...
[gromacs/qmmm-gamess-us.git] / src / tools / gmx_dyndom.c
blob0390c5c0177cfd4e11028439d150b47d71941950
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
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
32 * And Hey:
33 * Green Red Orange Magenta Azure Cyan Skyblue
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include "3dview.h"
40 #include "statutil.h"
41 #include "smalloc.h"
42 #include "copyrite.h"
43 #include "index.h"
44 #include "confio.h"
45 #include "gmx_fatal.h"
46 #include "vec.h"
47 #include "physics.h"
48 #include "random.h"
49 #include "gmx_ana.h"
52 static void rot_conf(t_atoms *atoms,rvec x[],rvec v[],real trans,real angle,
53 rvec head,rvec tail,matrix box,int isize,atom_id index[],
54 rvec xout[],rvec vout[])
56 rvec arrow,center,xcm;
57 real theta,phi,arrow_len;
58 mat4 Rx,Ry,Rz,Rinvy,Rinvz,Mtot,Tcm,Tinvcm,Tx;
59 mat4 temp1,temp2,temp3,temp4,temp21,temp43;
60 vec4 xv;
61 int i,j,ai;
63 rvec_sub(tail,head,arrow);
64 arrow_len = norm(arrow);
65 if (debug) {
66 fprintf(debug,"Arrow vector: %10.4f %10.4f %10.4f\n",
67 arrow[XX],arrow[YY],arrow[ZZ]);
68 fprintf(debug,"Effective translation %g nm\n",trans);
70 if (arrow_len == 0.0)
71 gmx_fatal(FARGS,"Arrow vector not given");
73 /* Copy all aoms to output */
74 for(i=0; (i<atoms->nr);i ++) {
75 copy_rvec(x[i],xout[i]);
76 copy_rvec(v[i],vout[i]);
79 /* Compute center of mass and move atoms there */
80 clear_rvec(xcm);
81 for(i=0; (i<isize); i++)
82 rvec_inc(xcm,x[index[i]]);
83 for(i=0; (i<DIM); i++)
84 xcm[i] /= isize;
85 if (debug)
86 fprintf(debug,"Center of mass: %10.4f %10.4f %10.4f\n",
87 xcm[XX],xcm[YY],xcm[ZZ]);
88 for(i=0; (i<isize); i++)
89 rvec_sub(x[index[i]],xcm,xout[index[i]]);
91 /* Compute theta and phi that describe the arrow */
92 theta = acos(arrow[ZZ]/arrow_len);
93 phi = atan2(arrow[YY]/arrow_len,arrow[XX]/arrow_len);
94 if (debug)
95 fprintf(debug,"Phi = %.1f, Theta = %.1f\n",RAD2DEG*phi,RAD2DEG*theta);
97 /* Now the total rotation matrix: */
98 /* Rotate a couple of times */
99 rotate(ZZ,-phi,Rz);
100 rotate(YY,M_PI/2-theta,Ry);
101 rotate(XX,angle*DEG2RAD,Rx);
102 Rx[WW][XX] = trans;
103 rotate(YY,theta-M_PI/2,Rinvy);
104 rotate(ZZ,phi,Rinvz);
106 mult_matrix(temp1,Ry,Rz);
107 mult_matrix(temp2,Rinvy,Rx);
108 mult_matrix(temp3,temp2,temp1);
109 mult_matrix(Mtot,Rinvz,temp3);
111 print_m4(debug,"Rz",Rz);
112 print_m4(debug,"Ry",Ry);
113 print_m4(debug,"Rx",Rx);
114 print_m4(debug,"Rinvy",Rinvy);
115 print_m4(debug,"Rinvz",Rinvz);
116 print_m4(debug,"Mtot",Mtot);
118 for(i=0; (i<isize); i++) {
119 ai = index[i];
120 m4_op(Mtot,xout[ai],xv);
121 rvec_add(xv,xcm,xout[ai]);
122 m4_op(Mtot,v[ai],xv);
123 copy_rvec(xv,vout[ai]);
127 int gmx_dyndom(int argc,char *argv[])
129 const char *desc[] = {
130 "g_dyndom reads a pdb file output from DynDom",
131 "http://www.cmp.uea.ac.uk/dyndom/",
132 "It reads the coordinates, and the coordinates of the rotation axis",
133 "furthermore it reads an index file containing the domains.",
134 "Furthermore it takes the first and last atom of the arrow file",
135 "as command line arguments (head and tail) and",
136 "finally it takes the translation vector (given in DynDom info file)",
137 "and the angle of rotation (also as command line arguments). If the angle",
138 "determined by DynDom is given, one should be able to recover the",
139 "second structure used for generating the DynDom output.",
140 "Because of limited numerical accuracy this should be verified by",
141 "computing an all-atom RMSD (using [TT]g_confrms[tt]) rather than by file",
142 "comparison (using diff).[PAR]",
143 "The purpose of this program is to interpolate and extrapolate the",
144 "rotation as found by DynDom. As a result unphysical structures with",
145 "long or short bonds, or overlapping atoms may be produced. Visual",
146 "inspection, and energy minimization may be necessary to",
147 "validate the structure."
149 static real trans0 = 0;
150 static rvec head = { 0,0,0 };
151 static rvec tail = { 0,0,0 };
152 static real angle0 = 0,angle1 = 0, maxangle = 0;
153 static int label = 0,nframes=11;
154 t_pargs pa[] = {
155 { "-firstangle", FALSE, etREAL, {&angle0},
156 "Angle of rotation about rotation vector" },
157 { "-lastangle", FALSE, etREAL, {&angle1},
158 "Angle of rotation about rotation vector" },
159 { "-nframe", FALSE, etINT, {&nframes},
160 "Number of steps on the pathway" },
161 { "-maxangle", FALSE, etREAL, {&maxangle},
162 "DymDom dtermined angle of rotation about rotation vector" },
163 { "-trans", FALSE, etREAL, {&trans0},
164 "Translation (Aangstroem) along rotation vector (see DynDom info file)" },
165 { "-head", FALSE, etRVEC, {head},
166 "First atom of the arrow vector" },
167 { "-tail", FALSE, etRVEC, {tail},
168 "Last atom of the arrow vector" }
170 int i,j,natoms,isize,status;
171 atom_id *index=NULL,*index_all;
172 char title[256],*grpname;
173 t_atoms atoms;
174 real angle,trans;
175 rvec *x,*v,*xout,*vout;
176 matrix box;
177 output_env_t oenv;
179 t_filenm fnm[] = {
180 { efPDB, "-f", "dyndom", ffREAD },
181 { efTRO, "-o", "rotated", ffWRITE },
182 { efNDX, "-n", "domains", ffREAD }
184 #define NFILE asize(fnm)
186 CopyRight(stderr,argv[0]);
188 parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
189 asize(desc),desc,0,NULL,&oenv);
191 get_stx_coordnum (opt2fn("-f",NFILE,fnm),&natoms);
192 init_t_atoms(&atoms,natoms,TRUE);
193 snew(x,natoms);
194 snew(v,natoms);
195 read_stx_conf(opt2fn("-f",NFILE,fnm),title,&atoms,x,v,NULL,box);
196 snew(xout,natoms);
197 snew(vout,natoms);
199 printf("Select group to rotate:\n");
200 rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
201 printf("Going to rotate %s containg %d atoms\n",grpname,isize);
203 snew(index_all,atoms.nr);
204 for(i=0; (i<atoms.nr); i++)
205 index_all[i] = i;
207 status = open_trx(opt2fn("-o",NFILE,fnm),"w");
209 label = 'A';
210 for(i=0; (i<nframes); i++,label++) {
211 angle = angle0 + (i*(angle1-angle0))/(nframes-1);
212 trans = trans0*0.1*angle/maxangle;
213 printf("Frame: %2d (label %c), angle: %8.3f deg., trans: %8.3f nm\n",
214 i,label,angle,trans);
215 rot_conf(&atoms,x,v,trans,angle,head,tail,box,isize,index,xout,vout);
217 if (label > 'Z')
218 label-=26;
219 for(j=0; (j<atoms.nr); j++)
220 atoms.resinfo[atoms.atom[j].resind].chain = label;
222 write_trx(status,atoms.nr,index_all,&atoms,i,angle,box,xout,vout,NULL);
224 close_trx(status);
226 thanx(stderr);
228 return 0;