Fixed a bug in the pdb-writing code.
[gromacs.git] / src / tools / g_gyrate.c
blobe87b389369266db5e0358aa03c61725f9dc2f581
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.1
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
29 * And Hey:
30 * Gromacs Runs One Microsecond At Cannonball Speeds
32 static char *SRCID_g_gyrate_c = "$Id$";
33 #include <math.h>
34 #include <string.h>
35 #include "statutil.h"
36 #include "sysstuff.h"
37 #include "typedefs.h"
38 #include "smalloc.h"
39 #include "macros.h"
40 #include "vec.h"
41 #include "pbc.h"
42 #include "copyrite.h"
43 #include "futil.h"
44 #include "statutil.h"
45 #include "rdgroup.h"
46 #include "mshift.h"
47 #include "xvgr.h"
48 #include "princ.h"
49 #include "rmpbc.h"
50 #include "txtdump.h"
51 #include "tpxio.h"
53 real calc_gyro(rvec x[],int gnx,atom_id index[],t_atom atom[],real tm,
54 rvec gvec,rvec d,bool bQ,bool bRot)
56 int i,ii,m;
57 real gyro,dx2,m0;
58 matrix trans;
59 rvec comp;
61 if (bRot) {
62 principal_comp(gnx,index,atom,x,trans,d);
63 for(m=0; (m<DIM); m++)
64 d[m]=sqrt(d[m]/tm);
65 #ifdef DEBUG
66 pr_rvecs(stderr,0,"trans",trans,DIM);
67 #endif
68 /* rotate_atoms(gnx,index,x,trans); */
70 clear_rvec(comp);
71 for(i=0; (i<gnx); i++) {
72 ii=index[i];
73 if (bQ)
74 m0=fabs(atom[ii].q);
75 else
76 m0=atom[ii].m;
77 for(m=0; (m<DIM); m++) {
78 dx2=x[ii][m]*x[ii][m];
79 comp[m]+=dx2*m0;
82 gyro=comp[XX]+comp[YY]+comp[ZZ];
84 for(m=0; (m<DIM); m++)
85 gvec[m]=sqrt((gyro-comp[m])/tm);
87 return sqrt(gyro/tm);
90 int main(int argc,char *argv[])
92 static char *desc[] = {
93 "g_gyrate computes the radius of gyration of a group of atoms",
94 "and the radii of gyration about the x, y and z axes,"
95 "as a function of time. The atoms are explicitly mass weighted."
97 static bool bQ=FALSE,bRot=FALSE;
98 t_pargs pa[] = {
99 { "-q", FALSE, etBOOL, {&bQ},
100 "Use absolute value of the charge of an atom as weighting factor instead of mass" },
101 { "-p", FALSE, etBOOL, {&bRot},
102 "Calculate the radii of gyration about the principal axes." }
104 FILE *out;
105 int status;
106 t_topology top;
107 rvec *x,*x_s;
108 rvec xcm,gvec;
109 rvec d; /* eigenvalues of inertia tensor */
110 matrix box;
111 real t,tm,gyro;
112 int natoms;
113 char *grpname,title[256];
114 int i,j,gnx;
115 atom_id *index;
116 char *leg[] = { "Rg", "RgX", "RgY", "RgZ" };
117 #define NLEG asize(leg)
118 t_filenm fnm[] = {
119 { efTRX, "-f", NULL, ffREAD },
120 { efTPS, NULL, NULL, ffREAD },
121 { efXVG, NULL, "gyrate", ffWRITE },
122 { efNDX, NULL, NULL, ffOPTRD }
124 #define NFILE asize(fnm)
126 CopyRight(stderr,argv[0]);
127 parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
128 NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);
129 clear_rvec(d);
131 for(i=1; (i<argc); i++) {
132 if (strcmp(argv[i],"-q") == 0) {
133 bQ=TRUE;
134 fprintf(stderr,"Will print radius normalised by charge\n");
136 else if (strcmp(argv[i],"-r") == 0) {
137 bRot=TRUE;
138 fprintf(stderr,"Will rotate system along principal axes\n");
141 read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&x,NULL,box,TRUE);
142 get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);
144 natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
145 snew(x_s,natoms);
147 j=0;
148 if (bQ)
149 out=xvgropen(ftp2fn(efXVG,NFILE,fnm),
150 "Radius of Charge","Time (ps)","Rg (nm)");
151 else
152 out=xvgropen(ftp2fn(efXVG,NFILE,fnm),
153 "Radius of gyration","Time (ps)","Rg (nm)");
154 if (bRot)
155 fprintf(out,"@ subtitle \"Axes are principal component axes\"\n");
156 xvgr_legend(out,NLEG,leg);
157 do {
158 rm_pbc(&top.idef,natoms,box,x,x_s);
159 tm=sub_xcm(x_s,gnx,index,top.atoms.atom,xcm,bQ);
160 gyro=calc_gyro(x_s,gnx,index,top.atoms.atom,tm,gvec,d,bQ,bRot);
162 if (bRot) {
163 fprintf(out,"%10g %10g %10g %10g %10g\n",
164 t,gyro,d[XX],d[YY],d[ZZ]); }
165 else {
166 fprintf(out,"%10g %10g %10g %10g %10g\n",
167 t,gyro,gvec[XX],gvec[YY],gvec[ZZ]); }
168 j++;
169 } while(read_next_x(status,&t,natoms,x,box));
170 close_trj(status);
172 fclose(out);
174 do_view(ftp2fn(efXVG,NFILE,fnm),"-nxy");
176 thanx(stderr);
178 return 0;