/*
- *
+ *
* This source code is part of
- *
+ *
* G R O M A C S
- *
+ *
* GROningen MAchine for Chemical Simulations
- *
+ *
* VERSION 3.2.0
* Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* If you want to redistribute modifications, please consider that
* scientific software is very special. Version control is crucial -
* bugs must be traceable. We will be happy to consider code for
* inclusion in the official distribution, but derived work must not
* be called official GROMACS. Details are found in the README & COPYING
* files - if they are missing, get the official version at www.gromacs.org.
- *
+ *
* To help us fund GROMACS development, we humbly ask that you cite
* the papers on the package - you can find them in the top README file.
- *
+ *
* For more info, check our website at http://www.gromacs.org
- *
+ *
* And Hey:
* Green Red Orange Magenta Azure Cyan Skyblue
*/
#include "gromacs/linearalgebra/eigensolver.h"
-static real find_pdb_bfac(t_atoms *atoms,t_resinfo *ri,char *atomnm)
+static real find_pdb_bfac(t_atoms *atoms, t_resinfo *ri, char *atomnm)
{
- char rresnm[8];
- int i;
-
- strcpy(rresnm,*ri->name);
- rresnm[3]='\0';
- for(i=0; (i<atoms->nr); i++) {
- if ((ri->nr == atoms->resinfo[atoms->atom[i].resind].nr) &&
- (ri->ic == atoms->resinfo[atoms->atom[i].resind].ic) &&
- (strcmp(*atoms->resinfo[atoms->atom[i].resind].name,rresnm) == 0) &&
- (strstr(*atoms->atomname[i],atomnm) != NULL))
- break;
- }
- if (i == atoms->nr) {
- fprintf(stderr,"\rCan not find %s%d-%s in pdbfile\n",
- rresnm,ri->nr,atomnm);
- return 0.0;
- }
-
- return atoms->pdbinfo[i].bfac;
+ char rresnm[8];
+ int i;
+
+ strcpy(rresnm, *ri->name);
+ rresnm[3] = '\0';
+ for (i = 0; (i < atoms->nr); i++)
+ {
+ if ((ri->nr == atoms->resinfo[atoms->atom[i].resind].nr) &&
+ (ri->ic == atoms->resinfo[atoms->atom[i].resind].ic) &&
+ (strcmp(*atoms->resinfo[atoms->atom[i].resind].name, rresnm) == 0) &&
+ (strstr(*atoms->atomname[i], atomnm) != NULL))
+ {
+ break;
+ }
+ }
+ if (i == atoms->nr)
+ {
+ fprintf(stderr, "\rCan not find %s%d-%s in pdbfile\n",
+ rresnm, ri->nr, atomnm);
+ return 0.0;
+ }
+
+ return atoms->pdbinfo[i].bfac;
}
-void correlate_aniso(const char *fn,t_atoms *ref,t_atoms *calc,
+void correlate_aniso(const char *fn, t_atoms *ref, t_atoms *calc,
const output_env_t oenv)
{
- FILE *fp;
- int i,j;
-
- fp = xvgropen(fn,"Correlation between X-Ray and Computed Uij","X-Ray",
- "Computed",oenv);
- for(i=0; (i<ref->nr); i++) {
- if (ref->pdbinfo[i].bAnisotropic) {
- for(j=U11; (j<=U23); j++)
- fprintf(fp,"%10d %10d\n",ref->pdbinfo[i].uij[j],calc->pdbinfo[i].uij[j]);
- }
- }
- ffclose(fp);
+ FILE *fp;
+ int i, j;
+
+ fp = xvgropen(fn, "Correlation between X-Ray and Computed Uij", "X-Ray",
+ "Computed", oenv);
+ for (i = 0; (i < ref->nr); i++)
+ {
+ if (ref->pdbinfo[i].bAnisotropic)
+ {
+ for (j = U11; (j <= U23); j++)
+ {
+ fprintf(fp, "%10d %10d\n", ref->pdbinfo[i].uij[j], calc->pdbinfo[i].uij[j]);
+ }
+ }
+ }
+ ffclose(fp);
}
-static void average_residues(double f[],double **U,int uind,
- int isize,atom_id index[],real w_rls[],
- t_atoms *atoms)
+static void average_residues(double f[], double **U, int uind,
+ int isize, atom_id index[], real w_rls[],
+ t_atoms *atoms)
{
- int i,j,start;
- double av,m;
-
- start = 0;
- av = 0;
- m = 0;
- for(i=0; i<isize; i++) {
- av += w_rls[index[i]]*(f != NULL ? f[i] : U[i][uind]);
- m += w_rls[index[i]];
- if (i+1==isize ||
- atoms->atom[index[i]].resind!=atoms->atom[index[i+1]].resind) {
- av /= m;
- if (f != NULL) {
- for(j=start; j<=i; j++)
- f[i] = av;
- } else {
- for(j=start; j<=i; j++)
- U[j][uind] = av;
- }
- start = i+1;
- av = 0;
- m = 0;
- }
- }
+ int i, j, start;
+ double av, m;
+
+ start = 0;
+ av = 0;
+ m = 0;
+ for (i = 0; i < isize; i++)
+ {
+ av += w_rls[index[i]]*(f != NULL ? f[i] : U[i][uind]);
+ m += w_rls[index[i]];
+ if (i+1 == isize ||
+ atoms->atom[index[i]].resind != atoms->atom[index[i+1]].resind)
+ {
+ av /= m;
+ if (f != NULL)
+ {
+ for (j = start; j <= i; j++)
+ {
+ f[i] = av;
+ }
+ }
+ else
+ {
+ for (j = start; j <= i; j++)
+ {
+ U[j][uind] = av;
+ }
+ }
+ start = i+1;
+ av = 0;
+ m = 0;
+ }
+ }
}
-void print_dir(FILE *fp,real *Uaver)
+void print_dir(FILE *fp, real *Uaver)
{
real eigvec[DIM*DIM];
- real tmp[DIM*DIM];
+ real tmp[DIM*DIM];
rvec eigval;
- int d,m;
+ int d, m;
- fprintf(fp,"MSF X Y Z\n");
- for(d=0; d<DIM; d++)
+ fprintf(fp, "MSF X Y Z\n");
+ for (d = 0; d < DIM; d++)
{
- fprintf(fp," %c ",'X'+d-XX);
- for(m=0; m<DIM; m++)
- fprintf(fp," %9.2e",Uaver[3*m+d]);
- fprintf(fp,"%s\n",m==DIM ? " (nm^2)" : "");
+ fprintf(fp, " %c ", 'X'+d-XX);
+ for (m = 0; m < DIM; m++)
+ {
+ fprintf(fp, " %9.2e", Uaver[3*m+d]);
+ }
+ fprintf(fp, "%s\n", m == DIM ? " (nm^2)" : "");
}
-
- for(m=0; m<DIM*DIM; m++)
+
+ for (m = 0; m < DIM*DIM; m++)
+ {
tmp[m] = Uaver[m];
+ }
-
- eigensolver(tmp,DIM,0,DIM,eigval,eigvec);
-
- fprintf(fp,"\n Eigenvectors\n\n");
- fprintf(fp,"Eigv %-8.2e %-8.2e %-8.2e (nm^2)\n\n",
- eigval[2],eigval[1],eigval[0]);
- for(d=0; d<DIM; d++)
+
+ eigensolver(tmp, DIM, 0, DIM, eigval, eigvec);
+
+ fprintf(fp, "\n Eigenvectors\n\n");
+ fprintf(fp, "Eigv %-8.2e %-8.2e %-8.2e (nm^2)\n\n",
+ eigval[2], eigval[1], eigval[0]);
+ for (d = 0; d < DIM; d++)
{
- fprintf(fp," %c ",'X'+d-XX);
- for(m=DIM-1; m>=0; m--)
- fprintf(fp,"%7.4f ",eigvec[3*m+d]);
- fprintf(fp,"\n");
+ fprintf(fp, " %c ", 'X'+d-XX);
+ for (m = DIM-1; m >= 0; m--)
+ {
+ fprintf(fp, "%7.4f ", eigvec[3*m+d]);
+ }
+ fprintf(fp, "\n");
}
}
-int gmx_rmsf(int argc,char *argv[])
+int gmx_rmsf(int argc, char *argv[])
{
- const char *desc[] = {
- "[TT]g_rmsf[tt] computes the root mean square fluctuation (RMSF, i.e. standard ",
- "deviation) of atomic positions in the trajectory (supplied with [TT]-f[tt])",
- "after (optionally) fitting to a reference frame (supplied with [TT]-s[tt]).[PAR]",
- "With option [TT]-oq[tt] the RMSF values are converted to B-factor",
- "values, which are written to a [TT].pdb[tt] file with the coordinates, of the",
- "structure file, or of a [TT].pdb[tt] file when [TT]-q[tt] is specified.",
- "Option [TT]-ox[tt] writes the B-factors to a file with the average",
- "coordinates.[PAR]",
- "With the option [TT]-od[tt] the root mean square deviation with",
- "respect to the reference structure is calculated.[PAR]",
- "With the option [TT]-aniso[tt], [TT]g_rmsf[tt] will compute anisotropic",
- "temperature factors and then it will also output average coordinates",
- "and a [TT].pdb[tt] file with ANISOU records (corresonding to the [TT]-oq[tt]",
- "or [TT]-ox[tt] option). Please note that the U values",
- "are orientation-dependent, so before comparison with experimental data",
- "you should verify that you fit to the experimental coordinates.[PAR]",
- "When a [TT].pdb[tt] input file is passed to the program and the [TT]-aniso[tt]",
- "flag is set",
- "a correlation plot of the Uij will be created, if any anisotropic",
- "temperature factors are present in the [TT].pdb[tt] file.[PAR]",
- "With option [TT]-dir[tt] the average MSF (3x3) matrix is diagonalized.",
- "This shows the directions in which the atoms fluctuate the most and",
- "the least."
- };
- static gmx_bool bRes=FALSE,bAniso=FALSE,bdevX=FALSE,bFit=TRUE;
- t_pargs pargs[] = {
- { "-res", FALSE, etBOOL, {&bRes},
- "Calculate averages for each residue" },
- { "-aniso",FALSE, etBOOL, {&bAniso},
- "Compute anisotropic termperature factors" },
- { "-fit", FALSE, etBOOL, {&bFit},
- "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." }
- };
- int natom;
- int step,nre,natoms,i,g,m,teller=0;
- real t,lambda,*w_rls,*w_rms;
-
- t_tpxheader header;
- t_inputrec ir;
- t_topology top;
- int ePBC;
- t_atoms *pdbatoms,*refatoms;
- gmx_bool bCont;
-
- matrix box,pdbbox;
- rvec *x,*pdbx,*xref;
- t_trxstatus *status;
- int npdbatoms,res0;
- char buf[256];
- const char *label;
- char title[STRLEN];
-
- FILE *fp; /* the graphics file */
- const char *devfn,*dirfn;
- int resind;
-
- gmx_bool bReadPDB;
- atom_id *index;
- int isize;
- char *grpnames;
-
- real bfac,pdb_bfac,*Uaver;
- double **U,*xav;
- atom_id aid;
- rvec *rmsd_x=NULL;
- double *rmsf,invcount,totmass;
- int d;
- real count=0;
- rvec xcm;
- gmx_rmpbc_t gpbc=NULL;
-
- output_env_t oenv;
-
- const char *leg[2] = { "MD", "X-Ray" };
-
- t_filenm fnm[] = {
- { efTRX, "-f", NULL, ffREAD },
- { efTPS, NULL, NULL, ffREAD },
- { efNDX, NULL, NULL, ffOPTRD },
- { efPDB, "-q", NULL, ffOPTRD },
- { efPDB, "-oq", "bfac", ffOPTWR },
- { efPDB, "-ox", "xaver", ffOPTWR },
- { efXVG, "-o", "rmsf", ffWRITE },
- { efXVG, "-od", "rmsdev", ffOPTWR },
- { efXVG, "-oc", "correl", ffOPTWR },
- { efLOG, "-dir", "rmsf", ffOPTWR }
- };
+ const char *desc[] = {
+ "[TT]g_rmsf[tt] computes the root mean square fluctuation (RMSF, i.e. standard ",
+ "deviation) of atomic positions in the trajectory (supplied with [TT]-f[tt])",
+ "after (optionally) fitting to a reference frame (supplied with [TT]-s[tt]).[PAR]",
+ "With option [TT]-oq[tt] the RMSF values are converted to B-factor",
+ "values, which are written to a [TT].pdb[tt] file with the coordinates, of the",
+ "structure file, or of a [TT].pdb[tt] file when [TT]-q[tt] is specified.",
+ "Option [TT]-ox[tt] writes the B-factors to a file with the average",
+ "coordinates.[PAR]",
+ "With the option [TT]-od[tt] the root mean square deviation with",
+ "respect to the reference structure is calculated.[PAR]",
+ "With the option [TT]-aniso[tt], [TT]g_rmsf[tt] will compute anisotropic",
+ "temperature factors and then it will also output average coordinates",
+ "and a [TT].pdb[tt] file with ANISOU records (corresonding to the [TT]-oq[tt]",
+ "or [TT]-ox[tt] option). Please note that the U values",
+ "are orientation-dependent, so before comparison with experimental data",
+ "you should verify that you fit to the experimental coordinates.[PAR]",
+ "When a [TT].pdb[tt] input file is passed to the program and the [TT]-aniso[tt]",
+ "flag is set",
+ "a correlation plot of the Uij will be created, if any anisotropic",
+ "temperature factors are present in the [TT].pdb[tt] file.[PAR]",
+ "With option [TT]-dir[tt] the average MSF (3x3) matrix is diagonalized.",
+ "This shows the directions in which the atoms fluctuate the most and",
+ "the least."
+ };
+ static gmx_bool bRes = FALSE, bAniso = FALSE, bdevX = FALSE, bFit = TRUE;
+ t_pargs pargs[] = {
+ { "-res", FALSE, etBOOL, {&bRes},
+ "Calculate averages for each residue" },
+ { "-aniso", FALSE, etBOOL, {&bAniso},
+ "Compute anisotropic termperature factors" },
+ { "-fit", FALSE, etBOOL, {&bFit},
+ "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." }
+ };
+ int natom;
+ int step, nre, natoms, i, g, m, teller = 0;
+ real t, lambda, *w_rls, *w_rms;
+
+ t_tpxheader header;
+ t_inputrec ir;
+ t_topology top;
+ int ePBC;
+ t_atoms *pdbatoms, *refatoms;
+ gmx_bool bCont;
+
+ matrix box, pdbbox;
+ rvec *x, *pdbx, *xref;
+ t_trxstatus *status;
+ int npdbatoms, res0;
+ char buf[256];
+ const char *label;
+ char title[STRLEN];
+
+ FILE *fp; /* the graphics file */
+ const char *devfn, *dirfn;
+ int resind;
+
+ gmx_bool bReadPDB;
+ atom_id *index;
+ int isize;
+ char *grpnames;
+
+ real bfac, pdb_bfac, *Uaver;
+ double **U, *xav;
+ atom_id aid;
+ rvec *rmsd_x = NULL;
+ double *rmsf, invcount, totmass;
+ int d;
+ real count = 0;
+ rvec xcm;
+ gmx_rmpbc_t gpbc = NULL;
+
+ output_env_t oenv;
+
+ const char *leg[2] = { "MD", "X-Ray" };
+
+ t_filenm fnm[] = {
+ { efTRX, "-f", NULL, ffREAD },
+ { efTPS, NULL, NULL, ffREAD },
+ { efNDX, NULL, NULL, ffOPTRD },
+ { efPDB, "-q", NULL, ffOPTRD },
+ { efPDB, "-oq", "bfac", ffOPTWR },
+ { efPDB, "-ox", "xaver", ffOPTWR },
+ { efXVG, "-o", "rmsf", ffWRITE },
+ { efXVG, "-od", "rmsdev", ffOPTWR },
+ { efXVG, "-oc", "correl", ffOPTWR },
+ { efLOG, "-dir", "rmsf", ffOPTWR }
+ };
#define NFILE asize(fnm)
-
- parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE ,
- NFILE,fnm,asize(pargs),pargs,asize(desc),desc,0,NULL,
- &oenv);
-
- bReadPDB = ftp2bSet(efPDB,NFILE,fnm);
- devfn = opt2fn_null("-od",NFILE,fnm);
- dirfn = opt2fn_null("-dir",NFILE,fnm);
-
- read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xref,NULL,box,TRUE);
- snew(w_rls,top.atoms.nr);
-
- fprintf(stderr,"Select group(s) for root mean square calculation\n");
- get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpnames);
-
- /* Set the weight */
- for(i=0; i<isize; i++)
- w_rls[index[i]]=top.atoms.atom[index[i]].m;
-
- /* Malloc the rmsf arrays */
- snew(xav,isize*DIM);
- snew(U,isize);
- for(i=0; i<isize; i++)
- snew(U[i],DIM*DIM);
- snew(rmsf,isize);
- if (devfn)
- snew(rmsd_x, isize);
-
- if (bReadPDB) {
- get_stx_coordnum(opt2fn("-q",NFILE,fnm),&npdbatoms);
- snew(pdbatoms,1);
- snew(refatoms,1);
- init_t_atoms(pdbatoms,npdbatoms,TRUE);
- init_t_atoms(refatoms,npdbatoms,TRUE);
- snew(pdbx,npdbatoms);
- /* Read coordinates twice */
- read_stx_conf(opt2fn("-q",NFILE,fnm),title,pdbatoms,pdbx,NULL,NULL,pdbbox);
- read_stx_conf(opt2fn("-q",NFILE,fnm),title,refatoms,pdbx,NULL,NULL,pdbbox);
- } else {
- pdbatoms = &top.atoms;
- refatoms = &top.atoms;
- pdbx = xref;
- npdbatoms = pdbatoms->nr;
- snew(pdbatoms->pdbinfo,npdbatoms);
- copy_mat(box,pdbbox);
- }
-
- if (bFit) {
- sub_xcm(xref,isize,index,top.atoms.atom,xcm,FALSE);
- }
-
- natom = read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
-
- if (bFit) {
- gpbc = gmx_rmpbc_init(&top.idef,ePBC,natom,box);
- }
-
- /* Now read the trj again to compute fluctuations */
- teller = 0;
- do {
- if (bFit) {
- /* Remove periodic boundary */
- gmx_rmpbc(gpbc,natom,box,x);
-
- /* Set center of mass to zero */
- sub_xcm(x,isize,index,top.atoms.atom,xcm,FALSE);
-
- /* Fit to reference structure */
- do_fit(natom,w_rls,xref,x);
- }
-
- /* Calculate Anisotropic U Tensor */
- for(i=0; i<isize; i++) {
- aid = index[i];
- for(d=0; d<DIM; d++) {
- xav[i*DIM + d] += x[aid][d];
- for(m=0; m<DIM; m++)
- U[i][d*DIM + m] += x[aid][d]*x[aid][m];
- }
- }
-
- if (devfn) {
- /* Calculate RMS Deviation */
- for(i=0;(i<isize);i++) {
- aid = index[i];
- for(d=0;(d<DIM);d++) {
- rmsd_x[i][d] += sqr(x[aid][d]-xref[aid][d]);
- }
- }
- }
- count += 1.0;
- teller++;
- } while(read_next_x(oenv,status,&t,natom,x,box));
- close_trj(status);
-
- if (bFit)
- gmx_rmpbc_done(gpbc);
-
-
- invcount = 1.0/count;
- snew(Uaver,DIM*DIM);
- totmass = 0;
- for(i=0; i<isize; i++) {
- for(d=0; d<DIM; d++)
- xav[i*DIM + d] *= invcount;
- for(d=0; d<DIM; d++)
- for(m=0; m<DIM; m++) {
- U[i][d*DIM + m] = U[i][d*DIM + m]*invcount
- - xav[i*DIM + d]*xav[i*DIM + m];
- Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m];
- }
- totmass += top.atoms.atom[index[i]].m;
- }
- for(d=0; d<DIM*DIM; d++)
- Uaver[d] /= totmass;
-
- if (bRes) {
- for(d=0; d<DIM*DIM; d++) {
- average_residues(NULL,U,d,isize,index,w_rls,&top.atoms);
- }
- }
-
- if (bAniso) {
- for(i=0; i<isize; i++) {
- aid = index[i];
- pdbatoms->pdbinfo[aid].bAnisotropic = TRUE;
- pdbatoms->pdbinfo[aid].uij[U11] = 1e6*U[i][XX*DIM + XX];
- pdbatoms->pdbinfo[aid].uij[U22] = 1e6*U[i][YY*DIM + YY];
- pdbatoms->pdbinfo[aid].uij[U33] = 1e6*U[i][ZZ*DIM + ZZ];
- pdbatoms->pdbinfo[aid].uij[U12] = 1e6*U[i][XX*DIM + YY];
- pdbatoms->pdbinfo[aid].uij[U13] = 1e6*U[i][XX*DIM + ZZ];
- pdbatoms->pdbinfo[aid].uij[U23] = 1e6*U[i][YY*DIM + ZZ];
- }
- }
- if (bRes) {
- label = "Residue";
- } else
- label = "Atom";
-
- for(i=0; i<isize; i++)
- rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ];
-
- if (dirfn) {
- fprintf(stdout,"\n");
- print_dir(stdout,Uaver);
- fp = ffopen(dirfn,"w");
- print_dir(fp,Uaver);
- ffclose(fp);
- }
-
- for(i=0; i<isize; i++)
- sfree(U[i]);
- sfree(U);
-
- /* Write RMSF output */
- if (bReadPDB) {
- bfac = 8.0*M_PI*M_PI/3.0*100;
- fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"B-Factors",
- label,"(A\\b\\S\\So\\N\\S2\\N)",oenv);
- xvgr_legend(fp,2,leg,oenv);
- for(i=0;(i<isize);i++) {
- if (!bRes || i+1==isize ||
- top.atoms.atom[index[i]].resind!=top.atoms.atom[index[i+1]].resind) {
- resind = top.atoms.atom[index[i]].resind;
- pdb_bfac = find_pdb_bfac(pdbatoms,&top.atoms.resinfo[resind],
- *(top.atoms.atomname[index[i]]));
-
- fprintf(fp,"%5d %10.5f %10.5f\n",
- bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1,rmsf[i]*bfac,
- pdb_bfac);
- }
+
+ parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
+ NFILE, fnm, asize(pargs), pargs, asize(desc), desc, 0, NULL,
+ &oenv);
+
+ bReadPDB = ftp2bSet(efPDB, NFILE, fnm);
+ devfn = opt2fn_null("-od", NFILE, fnm);
+ dirfn = opt2fn_null("-dir", NFILE, fnm);
+
+ read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xref, NULL, box, TRUE);
+ snew(w_rls, top.atoms.nr);
+
+ fprintf(stderr, "Select group(s) for root mean square calculation\n");
+ get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpnames);
+
+ /* Set the weight */
+ for (i = 0; i < isize; i++)
+ {
+ w_rls[index[i]] = top.atoms.atom[index[i]].m;
}
- ffclose(fp);
- } else {
- fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"RMS fluctuation",label,"(nm)",oenv);
- for(i=0; i<isize; i++)
- if (!bRes || i+1==isize ||
- top.atoms.atom[index[i]].resind!=top.atoms.atom[index[i+1]].resind)
- fprintf(fp,"%5d %8.4f\n",
- bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1,sqrt(rmsf[i]));
- ffclose(fp);
- }
-
- for(i=0; i<isize; i++)
- pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i];
-
- if (devfn) {
- for(i=0; i<isize; i++)
- rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count;
+
+ /* Malloc the rmsf arrays */
+ snew(xav, isize*DIM);
+ snew(U, isize);
+ for (i = 0; i < isize; i++)
+ {
+ snew(U[i], DIM*DIM);
+ }
+ snew(rmsf, isize);
+ if (devfn)
+ {
+ snew(rmsd_x, isize);
+ }
+
+ if (bReadPDB)
+ {
+ get_stx_coordnum(opt2fn("-q", NFILE, fnm), &npdbatoms);
+ snew(pdbatoms, 1);
+ snew(refatoms, 1);
+ init_t_atoms(pdbatoms, npdbatoms, TRUE);
+ init_t_atoms(refatoms, npdbatoms, TRUE);
+ snew(pdbx, npdbatoms);
+ /* Read coordinates twice */
+ read_stx_conf(opt2fn("-q", NFILE, fnm), title, pdbatoms, pdbx, NULL, NULL, pdbbox);
+ read_stx_conf(opt2fn("-q", NFILE, fnm), title, refatoms, pdbx, NULL, NULL, pdbbox);
+ }
+ else
+ {
+ pdbatoms = &top.atoms;
+ refatoms = &top.atoms;
+ pdbx = xref;
+ npdbatoms = pdbatoms->nr;
+ snew(pdbatoms->pdbinfo, npdbatoms);
+ copy_mat(box, pdbbox);
+ }
+
+ if (bFit)
+ {
+ sub_xcm(xref, isize, index, top.atoms.atom, xcm, FALSE);
+ }
+
+ natom = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
+
+ if (bFit)
+ {
+ gpbc = gmx_rmpbc_init(&top.idef, ePBC, natom, box);
+ }
+
+ /* Now read the trj again to compute fluctuations */
+ teller = 0;
+ do
+ {
+ if (bFit)
+ {
+ /* Remove periodic boundary */
+ gmx_rmpbc(gpbc, natom, box, x);
+
+ /* Set center of mass to zero */
+ sub_xcm(x, isize, index, top.atoms.atom, xcm, FALSE);
+
+ /* Fit to reference structure */
+ do_fit(natom, w_rls, xref, x);
+ }
+
+ /* Calculate Anisotropic U Tensor */
+ for (i = 0; i < isize; i++)
+ {
+ aid = index[i];
+ for (d = 0; d < DIM; d++)
+ {
+ xav[i*DIM + d] += x[aid][d];
+ for (m = 0; m < DIM; m++)
+ {
+ U[i][d*DIM + m] += x[aid][d]*x[aid][m];
+ }
+ }
+ }
+
+ if (devfn)
+ {
+ /* Calculate RMS Deviation */
+ for (i = 0; (i < isize); i++)
+ {
+ aid = index[i];
+ for (d = 0; (d < DIM); d++)
+ {
+ rmsd_x[i][d] += sqr(x[aid][d]-xref[aid][d]);
+ }
+ }
+ }
+ count += 1.0;
+ teller++;
+ }
+ while (read_next_x(oenv, status, &t, natom, x, box));
+ close_trj(status);
+
+ if (bFit)
+ {
+ gmx_rmpbc_done(gpbc);
+ }
+
+
+ invcount = 1.0/count;
+ snew(Uaver, DIM*DIM);
+ totmass = 0;
+ for (i = 0; i < isize; i++)
+ {
+ for (d = 0; d < DIM; d++)
+ {
+ xav[i*DIM + d] *= invcount;
+ }
+ for (d = 0; d < DIM; d++)
+ {
+ for (m = 0; m < DIM; m++)
+ {
+ U[i][d*DIM + m] = U[i][d*DIM + m]*invcount
+ - xav[i*DIM + d]*xav[i*DIM + m];
+ Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m];
+ }
+ }
+ totmass += top.atoms.atom[index[i]].m;
+ }
+ for (d = 0; d < DIM*DIM; d++)
+ {
+ Uaver[d] /= totmass;
+ }
+
if (bRes)
- average_residues(rmsf,NULL,0,isize,index,w_rls,&top.atoms);
- /* Write RMSD output */
- fp = xvgropen(devfn,"RMS Deviation",label,"(nm)",oenv);
- for(i=0; i<isize; i++)
- if (!bRes || i+1==isize ||
- top.atoms.atom[index[i]].resind!=top.atoms.atom[index[i+1]].resind)
- fprintf(fp,"%5d %8.4f\n",
- bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1,sqrt(rmsf[i]));
- ffclose(fp);
- }
-
- if (opt2bSet("-oq",NFILE,fnm)) {
- /* Write a .pdb file with B-factors and optionally anisou records */
- for(i=0; i<isize; i++)
- rvec_inc(xref[index[i]],xcm);
- write_sto_conf_indexed(opt2fn("-oq",NFILE,fnm),title,pdbatoms,pdbx,
- NULL,ePBC,pdbbox,isize,index);
- }
- if (opt2bSet("-ox",NFILE,fnm)) {
- /* Misuse xref as a temporary array */
- for(i=0; i<isize; i++)
- for(d=0; d<DIM; d++)
- xref[index[i]][d] = xcm[d] + xav[i*DIM + d];
- /* Write a .pdb file with B-factors and optionally anisou records */
- write_sto_conf_indexed(opt2fn("-ox",NFILE,fnm),title,pdbatoms,xref,NULL,
- ePBC,pdbbox,isize,index);
- }
- if (bAniso) {
- correlate_aniso(opt2fn("-oc",NFILE,fnm),refatoms,pdbatoms,oenv);
- do_view(oenv,opt2fn("-oc",NFILE,fnm),"-nxy");
- }
- do_view(oenv,opt2fn("-o",NFILE,fnm),"-nxy");
- if (devfn)
- do_view(oenv,opt2fn("-od",NFILE,fnm),"-nxy");
-
- thanx(stderr);
-
- return 0;
+ {
+ for (d = 0; d < DIM*DIM; d++)
+ {
+ average_residues(NULL, U, d, isize, index, w_rls, &top.atoms);
+ }
+ }
+
+ if (bAniso)
+ {
+ for (i = 0; i < isize; i++)
+ {
+ aid = index[i];
+ pdbatoms->pdbinfo[aid].bAnisotropic = TRUE;
+ pdbatoms->pdbinfo[aid].uij[U11] = 1e6*U[i][XX*DIM + XX];
+ pdbatoms->pdbinfo[aid].uij[U22] = 1e6*U[i][YY*DIM + YY];
+ pdbatoms->pdbinfo[aid].uij[U33] = 1e6*U[i][ZZ*DIM + ZZ];
+ pdbatoms->pdbinfo[aid].uij[U12] = 1e6*U[i][XX*DIM + YY];
+ pdbatoms->pdbinfo[aid].uij[U13] = 1e6*U[i][XX*DIM + ZZ];
+ pdbatoms->pdbinfo[aid].uij[U23] = 1e6*U[i][YY*DIM + ZZ];
+ }
+ }
+ if (bRes)
+ {
+ label = "Residue";
+ }
+ else
+ {
+ label = "Atom";
+ }
+
+ for (i = 0; i < isize; i++)
+ {
+ rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ];
+ }
+
+ if (dirfn)
+ {
+ fprintf(stdout, "\n");
+ print_dir(stdout, Uaver);
+ fp = ffopen(dirfn, "w");
+ print_dir(fp, Uaver);
+ ffclose(fp);
+ }
+
+ for (i = 0; i < isize; i++)
+ {
+ sfree(U[i]);
+ }
+ sfree(U);
+
+ /* Write RMSF output */
+ if (bReadPDB)
+ {
+ bfac = 8.0*M_PI*M_PI/3.0*100;
+ fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "B-Factors",
+ label, "(A\\b\\S\\So\\N\\S2\\N)", oenv);
+ xvgr_legend(fp, 2, leg, oenv);
+ for (i = 0; (i < isize); i++)
+ {
+ if (!bRes || i+1 == isize ||
+ top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
+ {
+ resind = top.atoms.atom[index[i]].resind;
+ pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind],
+ *(top.atoms.atomname[index[i]]));
+
+ fprintf(fp, "%5d %10.5f %10.5f\n",
+ bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, rmsf[i]*bfac,
+ pdb_bfac);
+ }
+ }
+ ffclose(fp);
+ }
+ else
+ {
+ fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS fluctuation", label, "(nm)", oenv);
+ for (i = 0; i < isize; i++)
+ {
+ if (!bRes || i+1 == isize ||
+ top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
+ {
+ fprintf(fp, "%5d %8.4f\n",
+ bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, sqrt(rmsf[i]));
+ }
+ }
+ ffclose(fp);
+ }
+
+ for (i = 0; i < isize; i++)
+ {
+ pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i];
+ }
+
+ if (devfn)
+ {
+ for (i = 0; i < isize; i++)
+ {
+ rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count;
+ }
+ if (bRes)
+ {
+ average_residues(rmsf, NULL, 0, isize, index, w_rls, &top.atoms);
+ }
+ /* Write RMSD output */
+ fp = xvgropen(devfn, "RMS Deviation", label, "(nm)", oenv);
+ for (i = 0; i < isize; i++)
+ {
+ if (!bRes || i+1 == isize ||
+ top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
+ {
+ fprintf(fp, "%5d %8.4f\n",
+ bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, sqrt(rmsf[i]));
+ }
+ }
+ ffclose(fp);
+ }
+
+ if (opt2bSet("-oq", NFILE, fnm))
+ {
+ /* Write a .pdb file with B-factors and optionally anisou records */
+ for (i = 0; i < isize; i++)
+ {
+ rvec_inc(xref[index[i]], xcm);
+ }
+ write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx,
+ NULL, ePBC, pdbbox, isize, index);
+ }
+ if (opt2bSet("-ox", NFILE, fnm))
+ {
+ /* Misuse xref as a temporary array */
+ for (i = 0; i < isize; i++)
+ {
+ for (d = 0; d < DIM; d++)
+ {
+ xref[index[i]][d] = xcm[d] + xav[i*DIM + d];
+ }
+ }
+ /* Write a .pdb file with B-factors and optionally anisou records */
+ write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, xref, NULL,
+ ePBC, pdbbox, isize, index);
+ }
+ if (bAniso)
+ {
+ correlate_aniso(opt2fn("-oc", NFILE, fnm), refatoms, pdbatoms, oenv);
+ do_view(oenv, opt2fn("-oc", NFILE, fnm), "-nxy");
+ }
+ do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
+ if (devfn)
+ {
+ do_view(oenv, opt2fn("-od", NFILE, fnm), "-nxy");
+ }
+
+ thanx(stderr);
+
+ return 0;
}