示例#1
0
int gmx_nmens(int argc, char *argv[])
{
    const char *desc[] = {
        "[THISMODULE] generates an ensemble around an average structure",
        "in a subspace that is defined by a set of normal modes (eigenvectors).",
        "The eigenvectors are assumed to be mass-weighted.",
        "The position along each eigenvector is randomly taken from a Gaussian",
        "distribution with variance kT/eigenvalue.[PAR]",
        "By default the starting eigenvector is set to 7, since the first six",
        "normal modes are the translational and rotational degrees of freedom."
    };
    static int  nstruct = 100, first = 7, last = -1, seed = -1;
    static real temp    = 300.0;
    t_pargs     pa[]    = {
        { "-temp",  FALSE, etREAL, {&temp},
          "Temperature in Kelvin" },
        { "-seed", FALSE, etINT, {&seed},
          "Random seed, -1 generates a seed from time and pid" },
        { "-num", FALSE, etINT, {&nstruct},
          "Number of structures to generate" },
        { "-first", FALSE, etINT, {&first},
          "First eigenvector to use (-1 is select)" },
        { "-last",  FALSE, etINT, {&last},
          "Last eigenvector to use (-1 is till the last)" }
    };
#define NPA asize(pa)

    t_trxstatus        *out;
    int                 status, trjout;
    t_topology          top;
    int                 ePBC;
    t_atoms            *atoms;
    rvec               *xtop, *xref, *xav, *xout1, *xout2;
    gmx_bool            bDMR, bDMA, bFit;
    int                 nvec, *eignr = NULL;
    rvec              **eigvec = NULL;
    matrix              box;
    real               *eigval, totmass, *invsqrtm, t, disp;
    int                 natoms, neigval;
    char               *grpname, title[STRLEN];
    const char         *indexfile;
    int                 i, j, d, s, v;
    int                 nout, *iout, noutvec, *outvec;
    atom_id            *index;
    real                rfac, invfr, rhalf, jr;
    int          *      eigvalnr;
    output_env_t        oenv;
    gmx_rng_t           rng;
    unsigned long       jran;
    const unsigned long im = 0xffff;
    const unsigned long ia = 1093;
    const unsigned long ic = 18257;


    t_filenm fnm[] = {
        { efTRN, "-v",    "eigenvec",    ffREAD  },
        { efXVG, "-e",    "eigenval",    ffREAD  },
        { efTPS, NULL,    NULL,          ffREAD },
        { efNDX, NULL,    NULL,          ffOPTRD },
        { efTRO, "-o",    "ensemble",    ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_BE_NICE,
                           NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    indexfile = ftp2fn_null(efNDX, NFILE, fnm);

    read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit,
                      &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, box, bDMA);
    atoms = &top.atoms;

    printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n", natoms);
    get_index(atoms, indexfile, 1, &i, &index, &grpname);
    if (i != natoms)
    {
        gmx_fatal(FARGS, "you selected a group with %d elements instead of %d",
                  i, natoms);
    }
    printf("\n");

    snew(invsqrtm, natoms);
    if (bDMA)
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = gmx_invsqrt(atoms->atom[index[i]].m);
        }
    }
    else
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = 1.0;
        }
    }

    if (last == -1)
    {
        last = natoms*DIM;
    }
    if (first > -1)
    {
        /* make an index from first to last */
        nout = last-first+1;
        snew(iout, nout);
        for (i = 0; i < nout; i++)
        {
            iout[i] = first-1+i;
        }
    }
    else
    {
        printf("Select eigenvectors for output, end your selection with 0\n");
        nout = -1;
        iout = NULL;
        do
        {
            nout++;
            srenew(iout, nout+1);
            if (1 != scanf("%d", &iout[nout]))
            {
                gmx_fatal(FARGS, "Error reading user input");
            }
            iout[nout]--;
        }
        while (iout[nout] >= 0);
        printf("\n");
    }

    /* make an index of the eigenvectors which are present */
    snew(outvec, nout);
    noutvec = 0;
    for (i = 0; i < nout; i++)
    {
        j = 0;
        while ((j < nvec) && (eignr[j] != iout[i]))
        {
            j++;
        }
        if ((j < nvec) && (eignr[j] == iout[i]))
        {
            outvec[noutvec] = j;
            iout[noutvec]   = iout[i];
            noutvec++;
        }
    }

    fprintf(stderr, "%d eigenvectors selected for output\n", noutvec);

    if (seed == -1)
    {
        seed = (int)gmx_rng_make_seed();
        rng  = gmx_rng_init(seed);
    }
    else
    {
        rng = gmx_rng_init(seed);
    }
    fprintf(stderr, "Using seed %d and a temperature of %g K\n", seed, temp);

    snew(xout1, natoms);
    snew(xout2, atoms->nr);
    out  = open_trx(ftp2fn(efTRO, NFILE, fnm), "w");
    jran = (unsigned long)((real)im*gmx_rng_uniform_real(rng));
    gmx_rng_destroy(rng);
    for (s = 0; s < nstruct; s++)
    {
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(xav[i], xout1[i]);
        }
        for (j = 0; j < noutvec; j++)
        {
            v = outvec[j];
            /* (r-0.5) n times:  var_n = n * var_1 = n/12
               n=4:  var_n = 1/3, so multiply with 3 */

            rfac  = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]);
            rhalf = 2.0*rfac;
            rfac  = rfac/(real)im;

            jran = (jran*ia+ic) & im;
            jr   = (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            disp = rfac * jr - rhalf;

            for (i = 0; i < natoms; i++)
            {
                for (d = 0; d < DIM; d++)
                {
                    xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i];
                }
            }
        }
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(xout1[i], xout2[index[i]]);
        }
        t = s+1;
        write_trx(out, natoms, index, atoms, 0, t, box, xout2, NULL, NULL);
        fprintf(stderr, "\rGenerated %d structures", s+1);
    }
    fprintf(stderr, "\n");
    close_trx(out);

    return 0;
}
示例#2
0
int gmx_bundle(int argc,char *argv[])
{
  const char *desc[] = {
    "g_bundle analyzes bundles of axes. The axes can be for instance",
    "helix axes. The program reads two index groups and divides both",
    "of them in [TT]-na[tt] parts. The centers of mass of these parts",
    "define the tops and bottoms of the axes.",
    "Several quantities are written to file:",
    "the axis length, the distance and the z-shift of the axis mid-points",
    "with respect to the average center of all axes, the total tilt,",
    "the radial tilt and the lateral tilt with respect to the average axis.",
    "[PAR]",
    "With options [TT]-ok[tt], [TT]-okr[tt] and [TT]-okl[tt] the total,",
    "radial and lateral kinks of the axes are plotted. An extra index",
    "group of kink atoms is required, which is also divided into [TT]-na[tt]",
    "parts. The kink angle is defined as the angle between the kink-top and",
    "the bottom-kink vectors.",
    "[PAR]",
    "With option [TT]-oa[tt] the top, mid (or kink when [TT]-ok[tt] is set)",
    "and bottom points of each axis",
    "are written to a pdb file each frame. The residue numbers correspond",
    "to the axis numbers. When viewing this file with [TT]rasmol[tt], use the",
    "command line option [TT]-nmrpdb[tt], and type [TT]set axis true[tt] to",
    "display the reference axis."
  };
  static int  n=0;
  static gmx_bool bZ=FALSE;
  t_pargs pa[] = {
    { "-na", FALSE, etINT, {&n},
	"Number of axes" },
    { "-z", FALSE, etBOOL, {&bZ},
	"Use the Z-axis as reference iso the average axis" }
  };
  FILE       *out,*flen,*fdist,*fz,*ftilt,*ftiltr,*ftiltl;
  FILE       *fkink=NULL,*fkinkr=NULL,*fkinkl=NULL;
  t_trxstatus *status;
  t_trxstatus *fpdb;
  t_topology top;
  int        ePBC;
  rvec       *xtop;
  matrix     box;
  t_trxframe fr;
  t_atoms    outatoms;
  real       t,comp;
  int        natoms;
  char       *grpname[MAX_ENDS],title[256];
  /* FIXME: The constness should not be cast away */
  char       *anm=(char *)"CA",*rnm=(char *)"GLY";
  int        i,j,gnx[MAX_ENDS];
  atom_id    *index[MAX_ENDS];
  t_bundle   bun;
  gmx_bool       bKink;
  rvec       va,vb,vc,vr,vl;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;
  
#define NLEG asize(leg) 
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD }, 
    { efTPS, NULL, NULL, ffREAD }, 
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ol", "bun_len", ffWRITE },
    { efXVG, "-od", "bun_dist", ffWRITE },
    { efXVG, "-oz", "bun_z", ffWRITE },
    { efXVG, "-ot", "bun_tilt", ffWRITE },
    { efXVG, "-otr", "bun_tiltr", ffWRITE },
    { efXVG, "-otl", "bun_tiltl", ffWRITE },
    { efXVG, "-ok", "bun_kink", ffOPTWR },
    { efXVG, "-okr", "bun_kinkr", ffOPTWR },
    { efXVG, "-okl", "bun_kinkl", ffOPTWR },
    { efPDB, "-oa", "axes", ffOPTWR }
  }; 
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,TRUE);

  bKink = opt2bSet("-ok",NFILE,fnm) || opt2bSet("-okr",NFILE,fnm) 
    || opt2bSet("-okl",NFILE,fnm);
  if (bKink)
    bun.nend = 3;
  else
    bun.nend = 2;
  
  fprintf(stderr,"Select a group of top and a group of bottom ");
  if (bKink)
    fprintf(stderr,"and a group of kink ");
  fprintf(stderr,"atoms\n");
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),bun.nend,
	    gnx,index,grpname);

  if (n<=0 || gnx[0] % n || gnx[1] % n || (bKink && gnx[2] % n))
    gmx_fatal(FARGS,
		"The size of one of your index groups is not a multiple of n");
  bun.n = n;
  snew(bun.end[0],n);
  snew(bun.end[1],n);
  if (bKink)
    snew(bun.end[2],n);
  snew(bun.mid,n);
  snew(bun.dir,n);
  snew(bun.len,n);

  flen   = xvgropen(opt2fn("-ol",NFILE,fnm),"Axis lengths",
		    output_env_get_xvgr_tlabel(oenv),"(nm)",oenv);
  fdist  = xvgropen(opt2fn("-od",NFILE,fnm),"Distance of axis centers",
		    output_env_get_xvgr_tlabel(oenv),"(nm)",oenv);
  fz     = xvgropen(opt2fn("-oz",NFILE,fnm),"Z-shift of axis centers",
		    output_env_get_xvgr_tlabel(oenv),"(nm)",oenv);
  ftilt  = xvgropen(opt2fn("-ot",NFILE,fnm),"Axis tilts",
		    output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
  ftiltr = xvgropen(opt2fn("-otr",NFILE,fnm),"Radial axis tilts",
		    output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
  ftiltl = xvgropen(opt2fn("-otl",NFILE,fnm),"Lateral axis tilts",
		    output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
  
  if (bKink) {
    fkink  = xvgropen(opt2fn("-ok",NFILE,fnm),"Kink angles",
		      output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
    fkinkr = xvgropen(opt2fn("-okr",NFILE,fnm),"Radial kink angles",
		      output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
    if (output_env_get_print_xvgr_codes(oenv))
      fprintf(fkinkr,"@ subtitle \"+ = ) (   - = ( )\"\n");
    fkinkl = xvgropen(opt2fn("-okl",NFILE,fnm),"Lateral kink angles",
		      output_env_get_xvgr_tlabel(oenv),"(degrees)",oenv);
  }

  if (opt2bSet("-oa",NFILE,fnm)) {
    init_t_atoms(&outatoms,3*n,FALSE);
    outatoms.nr = 3*n;
    for(i=0; i<3*n; i++) {
      outatoms.atomname[i] = &anm;
      outatoms.atom[i].resind = i/3;
      outatoms.resinfo[i/3].name = &rnm;
      outatoms.resinfo[i/3].nr   = i/3 + 1;
      outatoms.resinfo[i/3].ic   = ' ';
    }
    fpdb = open_trx(opt2fn("-oa",NFILE,fnm),"w");
  } else
    fpdb = NULL;
  
  read_first_frame(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_NEED_X); 
  gpbc = gmx_rmpbc_init(&top.idef,ePBC,fr.natoms,fr.box);

  do {
    gmx_rmpbc_trxfr(gpbc,&fr);
    calc_axes(fr.x,top.atoms.atom,gnx,index,!bZ,&bun);
    t = output_env_conv_time(oenv,fr.time);
    fprintf(flen," %10g",t);
    fprintf(fdist," %10g",t);
    fprintf(fz," %10g",t);
    fprintf(ftilt," %10g",t);
    fprintf(ftiltr," %10g",t);
    fprintf(ftiltl," %10g",t);
    if (bKink) {
      fprintf(fkink," %10g",t);
      fprintf(fkinkr," %10g",t);
      fprintf(fkinkl," %10g",t);
    }

    for(i=0; i<bun.n; i++) {
      fprintf(flen," %6g",bun.len[i]);
      fprintf(fdist," %6g",norm(bun.mid[i]));
      fprintf(fz," %6g",bun.mid[i][ZZ]);
      fprintf(ftilt," %6g",RAD2DEG*acos(bun.dir[i][ZZ]));
      comp = bun.mid[i][XX]*bun.dir[i][XX]+bun.mid[i][YY]*bun.dir[i][YY];
      fprintf(ftiltr," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      comp = bun.mid[i][YY]*bun.dir[i][XX]-bun.mid[i][XX]*bun.dir[i][YY];
      fprintf(ftiltl," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      if (bKink) {
	rvec_sub(bun.end[0][i],bun.end[2][i],va);
	rvec_sub(bun.end[2][i],bun.end[1][i],vb);
	unitv_no_table(va,va);
	unitv_no_table(vb,vb);
	fprintf(fkink," %6g",RAD2DEG*acos(iprod(va,vb)));
	cprod(va,vb,vc);
	copy_rvec(bun.mid[i],vr);
	vr[ZZ] = 0;
	unitv_no_table(vr,vr);
	fprintf(fkinkr," %6g",RAD2DEG*asin(iprod(vc,vr)));
	vl[XX] = vr[YY];
	vl[YY] = -vr[XX];
	vl[ZZ] = 0;
	fprintf(fkinkl," %6g",RAD2DEG*asin(iprod(vc,vl)));
      }
    }
    fprintf(flen,"\n");
    fprintf(fdist,"\n");
    fprintf(fz,"\n");
    fprintf(ftilt,"\n");
    fprintf(ftiltr,"\n");
    fprintf(ftiltl,"\n");
    if (bKink) {
      fprintf(fkink,"\n");
      fprintf(fkinkr,"\n");
      fprintf(fkinkl,"\n");
    }
    if (fpdb )
      dump_axes(fpdb,&fr,&outatoms,&bun);
  } while(read_next_frame(oenv,status,&fr));
  gmx_rmpbc_done(gpbc);

  close_trx(status);
  
  if (fpdb )
    close_trx(fpdb);
  ffclose(flen);
  ffclose(fdist);
  ffclose(fz);
  ffclose(ftilt);
  ffclose(ftiltr);
  ffclose(ftiltl);
  if (bKink) {
    ffclose(fkink);
    ffclose(fkinkr);
    ffclose(fkinkl);
  }
  
  thanx(stderr);
  
  return 0;
}
示例#3
0
static void project(const char *trajfile,t_topology *top,int ePBC,matrix topbox,
                    const char *projfile,const char *twodplotfile,
                    const char *threedplotfile, const char *filterfile,int skip,
                    const char *extremefile,gmx_bool bExtrAll,real extreme,
                    int nextr, t_atoms *atoms,int natoms,atom_id *index,
                    gmx_bool bFit,rvec *xref,int nfit,atom_id *ifit,real *w_rls,
                    real *sqrtm,rvec *xav,
                    int *eignr,rvec **eigvec,
                    int noutvec,int *outvec, gmx_bool bSplit,
                    const output_env_t oenv)
{
  FILE    *xvgrout=NULL;
  int     nat,i,j,d,v,vec,nfr,nframes=0,snew_size,frame;
  t_trxstatus *out=NULL;
  t_trxstatus *status;
  int     noutvec_extr,imin,imax;
  real    *pmin,*pmax;
  atom_id *all_at;
  matrix  box;
  rvec    *xread,*x;
  real    t,inp,**inprod=NULL,min=0,max=0;
  char    str[STRLEN],str2[STRLEN],**ylabel,*c;
  real    fact;
  gmx_rmpbc_t  gpbc=NULL;

  snew(x,natoms);
  
  if (bExtrAll)
    noutvec_extr=noutvec;
  else
    noutvec_extr=1;
  

  if (trajfile) {
    snew(inprod,noutvec+1);
    
    if (filterfile) {
      fprintf(stderr,"Writing a filtered trajectory to %s using eigenvectors\n",
	      filterfile);
      for(i=0; i<noutvec; i++)
	fprintf(stderr,"%d ",outvec[i]+1);
      fprintf(stderr,"\n");
      out=open_trx(filterfile,"w");
    }
    snew_size=0;
    nfr=0;
    nframes=0;
    nat=read_first_x(oenv,&status,trajfile,&t,&xread,box);
    if (nat>atoms->nr)
      gmx_fatal(FARGS,"the number of atoms in your trajectory (%d) is larger than the number of atoms in your structure file (%d)",nat,atoms->nr); 
    snew(all_at,nat);
    
    if (top)
      gpbc = gmx_rmpbc_init(&top->idef,ePBC,nat,box);

    for(i=0; i<nat; i++)
      all_at[i]=i;
    do {
      if (nfr % skip == 0) {
	if (top)
	  gmx_rmpbc(gpbc,nat,box,xread);
	if (nframes>=snew_size) {
	  snew_size+=100;
	  for(i=0; i<noutvec+1; i++)
	    srenew(inprod[i],snew_size);
	}
	inprod[noutvec][nframes]=t;
	/* calculate x: a fitted struture of the selected atoms */
	if (bFit) {
	  reset_x(nfit,ifit,nat,NULL,xread,w_rls);
	  do_fit(nat,w_rls,xref,xread);
	}
	for (i=0; i<natoms; i++)
	  copy_rvec(xread[index[i]],x[i]);

	for(v=0; v<noutvec; v++) {
	  vec=outvec[v];
	  /* calculate (mass-weighted) projection */
	  inp=0;
	  for (i=0; i<natoms; i++) {
	    inp+=(eigvec[vec][i][0]*(x[i][0]-xav[i][0])+
	    eigvec[vec][i][1]*(x[i][1]-xav[i][1])+
	    eigvec[vec][i][2]*(x[i][2]-xav[i][2]))*sqrtm[i];
	  }
	  inprod[v][nframes]=inp;
	}
	if (filterfile) {
	  for(i=0; i<natoms; i++)
	    for(d=0; d<DIM; d++) {
	      /* misuse xread for output */
	      xread[index[i]][d] = xav[i][d];
	      for(v=0; v<noutvec; v++)
		xread[index[i]][d] +=
		  inprod[v][nframes]*eigvec[outvec[v]][i][d]/sqrtm[i];
	    }
	  write_trx(out,natoms,index,atoms,0,t,box,xread,NULL,NULL);
	}
	nframes++;
      }
      nfr++;
    } while (read_next_x(oenv,status,&t,nat,xread,box));
    close_trx(status);
     sfree(x);
     if (filterfile)
       close_trx(out);
  }
  else
    snew(xread,atoms->nr);
  
  if (top)
    gmx_rmpbc_done(gpbc);


  if (projfile) {
    snew(ylabel,noutvec);
    for(v=0; v<noutvec; v++) {
      sprintf(str,"vec %d",eignr[outvec[v]]+1);
      ylabel[v]=strdup(str);
    }
    sprintf(str,"projection on eigenvectors (%s)",proj_unit);
    write_xvgr_graphs(projfile, noutvec, 1, str, NULL, output_env_get_xvgr_tlabel(oenv),
		      (const char **)ylabel,
		      nframes, inprod[noutvec], inprod, NULL,
		      output_env_get_time_factor(oenv), FALSE, bSplit,oenv);
  }
  
  if (twodplotfile) {
    sprintf(str,"projection on eigenvector %d (%s)",
	    eignr[outvec[0]]+1,proj_unit);
    sprintf(str2,"projection on eigenvector %d (%s)",
	    eignr[outvec[noutvec-1]]+1,proj_unit); 
    xvgrout=xvgropen(twodplotfile,"2D projection of trajectory",str,str2,
                     oenv);
    for(i=0; i<nframes; i++) {
      if ( bSplit && i>0 && abs(inprod[noutvec][i])<1e-5 ) 
	fprintf(xvgrout,"&\n");
      fprintf(xvgrout,"%10.5f %10.5f\n",inprod[0][i],inprod[noutvec-1][i]);
    }
    ffclose(xvgrout);
  }
  
  if (threedplotfile) {
    t_atoms atoms;
    rvec    *x;
    real    *b=NULL;
    matrix  box;
    char    *resnm,*atnm, pdbform[STRLEN];
    gmx_bool    bPDB, b4D;
    FILE    *out;
    
    if (noutvec < 3)
      gmx_fatal(FARGS,"You have selected less than 3 eigenvectors");  
      
    /* initialize */
    bPDB = fn2ftp(threedplotfile)==efPDB;
    clear_mat(box);
    box[XX][XX] = box[YY][YY] = box[ZZ][ZZ] = 1;
    
    b4D = bPDB && (noutvec >= 4);
    if (b4D) {
      fprintf(stderr, "You have selected four or more eigenvectors:\n"
	      "fourth eigenvector will be plotted "
	      "in bfactor field of pdb file\n");
      sprintf(str,"4D proj. of traj. on eigenv. %d, %d, %d and %d",
	      eignr[outvec[0]]+1,eignr[outvec[1]]+1,
	      eignr[outvec[2]]+1,eignr[outvec[3]]+1);
    } else {
    sprintf(str,"3D proj. of traj. on eigenv. %d, %d and %d",
	    eignr[outvec[0]]+1,eignr[outvec[1]]+1,eignr[outvec[2]]+1);
    }
    init_t_atoms(&atoms,nframes,FALSE);
    snew(x,nframes);
    snew(b,nframes);
    atnm=strdup("C");
    resnm=strdup("PRJ");

    if(nframes>10000)
      fact=10000.0/nframes;
    else
      fact=1.0;

    for(i=0; i<nframes; i++) {
      atoms.atomname[i] = &atnm;
      atoms.atom[i].resind = i;
      atoms.resinfo[i].name = &resnm;
      atoms.resinfo[i].nr   = ceil(i*fact);
      atoms.resinfo[i].ic   = ' ';
      x[i][XX]=inprod[0][i];
      x[i][YY]=inprod[1][i];
      x[i][ZZ]=inprod[2][i];
      if (b4D)
	b[i]  =inprod[3][i];
    }
    if ( ( b4D || bSplit ) && bPDB ) {
      strcpy(pdbform,get_pdbformat());
      strcat(pdbform,"%8.4f%8.4f\n");
      
      out=ffopen(threedplotfile,"w");
      fprintf(out,"HEADER    %s\n",str);
      if ( b4D )
	fprintf(out,"REMARK    %s\n","fourth dimension plotted as B-factor");
      j=0;
      for(i=0; i<atoms.nr; i++) {
	if ( j>0 && bSplit && abs(inprod[noutvec][i])<1e-5 ) {
	  fprintf(out,"TER\n");
	  j=0;
	}
	fprintf(out,pdbform,"ATOM",i+1,"C","PRJ",' ',j+1,
		PR_VEC(10*x[i]), 1.0, 10*b[i]);
	if (j>0)
	  fprintf(out,"CONECT%5d%5d\n", i, i+1);
	j++;
      }
      fprintf(out,"TER\n");
      ffclose(out);
    } else
      write_sto_conf(threedplotfile,str,&atoms,x,NULL,ePBC,box); 
    free_t_atoms(&atoms,FALSE);
  }
  
  if (extremefile) {
    snew(pmin,noutvec_extr);
    snew(pmax,noutvec_extr);
    if (extreme==0) {
      fprintf(stderr,"%11s %17s %17s\n","eigenvector","Minimum","Maximum");
      fprintf(stderr,
	      "%11s %10s %10s %10s %10s\n","","value","frame","value","frame");
      imin = 0;
      imax = 0;
      for(v=0; v<noutvec_extr; v++) {
	for(i=0; i<nframes; i++) {
	  if (inprod[v][i]<inprod[v][imin])
	    imin = i;
	  if (inprod[v][i]>inprod[v][imax])
	    imax = i;
	}
	pmin[v] = inprod[v][imin];
	pmax[v] = inprod[v][imax];
	fprintf(stderr,"%7d     %10.6f %10d %10.6f %10d\n",
		eignr[outvec[v]]+1,
		pmin[v],imin,pmax[v],imax); 
      }
    }
    else {
      pmin[0] = -extreme;
      pmax[0] =  extreme;
    }
    /* build format string for filename: */
    strcpy(str,extremefile);/* copy filename */
    c=strrchr(str,'.'); /* find where extention begins */
    strcpy(str2,c); /* get extention */
    sprintf(c,"%%d%s",str2); /* append '%s' and extention to filename */
    for(v=0; v<noutvec_extr; v++) {
      /* make filename using format string */
      if (noutvec_extr==1)
	strcpy(str2,extremefile);
      else
	sprintf(str2,str,eignr[outvec[v]]+1);
      fprintf(stderr,"Writing %d frames along eigenvector %d to %s\n",
	      nextr,outvec[v]+1,str2);
      out=open_trx(str2,"w");
      for(frame=0; frame<nextr; frame++) {
	if ((extreme==0) && (nextr<=3))
	  for(i=0; i<natoms; i++) {
	    atoms->resinfo[atoms->atom[index[i]].resind].chainid = 'A' + frame;
	  }
	for(i=0; i<natoms; i++)
	  for(d=0; d<DIM; d++) 
	    xread[index[i]][d] = 
	      (xav[i][d] + (pmin[v]*(nextr-frame-1)+pmax[v]*frame)/(nextr-1)
	      *eigvec[outvec[v]][i][d]/sqrtm[i]);
	write_trx(out,natoms,index,atoms,0,frame,topbox,xread,NULL,NULL);
      }
      close_trx(out);
    }
    sfree(pmin);
    sfree(pmax);
  }
  fprintf(stderr,"\n");
}
示例#4
0
int gmx_dyndom(int argc, char *argv[])
{
    const char  *desc[] = {
        "[TT]g_dyndom[tt] reads a [TT].pdb[tt] file output from DynDom",
        "(http://www.cmp.uea.ac.uk/dyndom/).",
        "It reads the coordinates, the coordinates of the rotation axis,",
        "and an index file containing the domains.",
        "Furthermore, it takes the first and last atom of the arrow file",
        "as command line arguments (head and tail) and",
        "finally it takes the translation vector (given in DynDom info file)",
        "and the angle of rotation (also as command line arguments). If the angle",
        "determined by DynDom is given, one should be able to recover the",
        "second structure used for generating the DynDom output.",
        "Because of limited numerical accuracy this should be verified by",
        "computing an all-atom RMSD (using [TT]g_confrms[tt]) rather than by file",
        "comparison (using diff).[PAR]",
        "The purpose of this program is to interpolate and extrapolate the",
        "rotation as found by DynDom. As a result unphysical structures with",
        "long or short bonds, or overlapping atoms may be produced. Visual",
        "inspection, and energy minimization may be necessary to",
        "validate the structure."
    };
    static real  trans0 = 0;
    static rvec  head   = { 0, 0, 0 };
    static rvec  tail   = { 0, 0, 0 };
    static real  angle0 = 0, angle1 = 0, maxangle = 0;
    static int   label  = 0, nframes = 11;
    t_pargs      pa[]   = {
        { "-firstangle",    FALSE, etREAL, {&angle0},
          "Angle of rotation about rotation vector" },
        { "-lastangle",    FALSE, etREAL, {&angle1},
          "Angle of rotation about rotation vector" },
        { "-nframe",   FALSE, etINT,  {&nframes},
          "Number of steps on the pathway" },
        { "-maxangle", FALSE, etREAL, {&maxangle},
          "DymDom dtermined angle of rotation about rotation vector" },
        { "-trans",    FALSE, etREAL, {&trans0},
          "Translation (Angstrom) along rotation vector (see DynDom info file)" },
        { "-head",     FALSE, etRVEC, {head},
          "First atom of the arrow vector" },
        { "-tail",     FALSE, etRVEC, {tail},
          "Last atom of the arrow vector" }
    };
    int          i, j, natoms, isize;
    t_trxstatus *status;
    atom_id     *index = NULL, *index_all;
    char         title[256], *grpname;
    t_atoms      atoms;
    real         angle, trans;
    rvec        *x, *v, *xout, *vout;
    matrix       box;
    output_env_t oenv;

    t_filenm     fnm[] = {
        { efPDB, "-f", "dyndom",  ffREAD },
        { efTRO, "-o", "rotated", ffWRITE },
        { efNDX, "-n", "domains", ffREAD }
    };
#define NFILE asize(fnm)

    CopyRight(stderr, argv[0]);

    parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                      asize(desc), desc, 0, NULL, &oenv);

    get_stx_coordnum (opt2fn("-f", NFILE, fnm), &natoms);
    init_t_atoms(&atoms, natoms, TRUE);
    snew(x, natoms);
    snew(v, natoms);
    read_stx_conf(opt2fn("-f", NFILE, fnm), title, &atoms, x, v, NULL, box);
    snew(xout, natoms);
    snew(vout, natoms);

    printf("Select group to rotate:\n");
    rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
    printf("Going to rotate %s containg %d atoms\n", grpname, isize);

    snew(index_all, atoms.nr);
    for (i = 0; (i < atoms.nr); i++)
    {
        index_all[i] = i;
    }

    status = open_trx(opt2fn("-o", NFILE, fnm), "w");

    label = 'A';
    for (i = 0; (i < nframes); i++, label++)
    {
        angle = angle0 + (i*(angle1-angle0))/(nframes-1);
        trans = trans0*0.1*angle/maxangle;
        printf("Frame: %2d (label %c), angle: %8.3f deg., trans: %8.3f nm\n",
               i, label, angle, trans);
        rot_conf(&atoms, x, v, trans, angle, head, tail, box, isize, index, xout, vout);

        if (label > 'Z')
        {
            label -= 26;
        }
        for (j = 0; (j < atoms.nr); j++)
        {
            atoms.resinfo[atoms.atom[j].resind].chainid = label;
        }

        write_trx(status, atoms.nr, index_all, &atoms, i, angle, box, xout, vout, NULL);
    }
    close_trx(status);

    thanx(stderr);

    return 0;
}
示例#5
0
int gmx_trjorder(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] orders molecules according to the smallest distance",
        "to atoms in a reference group",
        "or on z-coordinate (with option [TT]-z[tt]).",
        "With distance ordering, it will ask for a group of reference",
        "atoms and a group of molecules. For each frame of the trajectory",
        "the selected molecules will be reordered according to the shortest",
        "distance between atom number [TT]-da[tt] in the molecule and all the",
        "atoms in the reference group. The center of mass of the molecules can",
        "be used instead of a reference atom by setting [TT]-da[tt] to 0.",
        "All atoms in the trajectory are written",
        "to the output trajectory.[PAR]",
        "[THISMODULE] can be useful for e.g. analyzing the n waters closest to a",
        "protein.",
        "In that case the reference group would be the protein and the group",
        "of molecules would consist of all the water atoms. When an index group",
        "of the first n waters is made, the ordered trajectory can be used",
        "with any GROMACS program to analyze the n closest waters.",
        "[PAR]",
        "If the output file is a [REF].pdb[ref] file, the distance to the reference target",
        "will be stored in the B-factor field in order to color with e.g. Rasmol.",
        "[PAR]",
        "With option [TT]-nshell[tt] the number of molecules within a shell",
        "of radius [TT]-r[tt] around the reference group are printed."
    };
    static int      na   = 3, ref_a = 1;
    static real     rcut = 0;
    static gmx_bool bCOM = FALSE, bZ = FALSE;
    t_pargs         pa[] = {
        { "-na", FALSE, etINT,  {&na},
          "Number of atoms in a molecule" },
        { "-da", FALSE, etINT,  {&ref_a},
          "Atom used for the distance calculation, 0 is COM" },
        { "-com", FALSE, etBOOL, {&bCOM},
          "Use the distance to the center of mass of the reference group" },
        { "-r",  FALSE, etREAL, {&rcut},
          "Cutoff used for the distance calculation when computing the number of molecules in a shell around e.g. a protein" },
        { "-z", FALSE, etBOOL, {&bZ},
          "Order molecules on z-coordinate" }
    };
    FILE           *fp;
    t_trxstatus    *out;
    t_trxstatus    *status;
    gmx_bool        bNShell, bPDBout;
    t_topology      top;
    int             ePBC;
    rvec           *x, *xsol, xcom, dx;
    matrix          box;
    t_pbc           pbc;
    gmx_rmpbc_t     gpbc;
    real            t, totmass, mass, rcut2 = 0, n2;
    int             natoms, nwat, ncut;
    char          **grpname;
    int             i, j, d, *isize, isize_ref = 0, isize_sol;
    atom_id         sa, sr, *swi, **index, *ind_ref = NULL, *ind_sol;
    output_env_t    oenv;
    t_filenm        fnm[] = {
        { efTRX, "-f", NULL, ffREAD  },
        { efTPS, NULL, NULL, ffREAD  },
        { efNDX, NULL, NULL, ffOPTRD },
        { efTRO, "-o", "ordered", ffOPTWR },
        { efXVG, "-nshell", "nshell", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, TRUE);
    sfree(x);

    /* get index groups */
    printf("Select %sa group of molecules to be ordered:\n",
           bZ ? "" : "a group of reference atoms and ");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bZ ? 1 : 2,
              isize, index, grpname);

    if (!bZ)
    {
        isize_ref = isize[0];
        isize_sol = isize[1];
        ind_ref   = index[0];
        ind_sol   = index[1];
    }
    else
    {
        isize_sol = isize[0];
        ind_sol   = index[0];
    }

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    if (natoms > top.atoms.nr)
    {
        gmx_fatal(FARGS, "Number of atoms in the run input file is larger than in the trjactory");
    }
    for (i = 0; (i < 2); i++)
    {
        for (j = 0; (j < isize[i]); j++)
        {
            if (index[i][j] > natoms)
            {
                gmx_fatal(FARGS, "An atom number in group %s is larger than the number of atoms in the trajectory");
            }
        }
    }

    if ((isize_sol % na) != 0)
    {
        gmx_fatal(FARGS, "Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
                  isize[1], na);
    }

    nwat = isize_sol/na;
    if (ref_a > na)
    {
        gmx_fatal(FARGS, "The reference atom can not be larger than the number of atoms in a molecule");
    }
    ref_a--;
    snew(xsol, nwat);
    snew(order, nwat);
    snew(swi, natoms);
    for (i = 0; (i < natoms); i++)
    {
        swi[i] = i;
    }

    out     = NULL;
    fp      = NULL;
    bNShell = ((opt2bSet("-nshell", NFILE, fnm)) ||
               (opt2parg_bSet("-r", asize(pa), pa)));
    bPDBout = FALSE;
    if (bNShell)
    {
        rcut2   = rcut*rcut;
        fp      = xvgropen(opt2fn("-nshell", NFILE, fnm), "Number of molecules",
                           "Time (ps)", "N", oenv);
        printf("Will compute the number of molecules within a radius of %g\n",
               rcut);
    }
    if (!bNShell || opt2bSet("-o", NFILE, fnm))
    {
        bPDBout = (fn2ftp(opt2fn("-o", NFILE, fnm)) == efPDB);
        if (bPDBout && !top.atoms.pdbinfo)
        {
            fprintf(stderr, "Creating pdbfino records\n");
            snew(top.atoms.pdbinfo, top.atoms.nr);
        }
        out = open_trx(opt2fn("-o", NFILE, fnm), "w");
    }
    gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);
        set_pbc(&pbc, ePBC, box);

        if (ref_a == -1)
        {
            /* Calculate the COM of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                totmass = 0;
                clear_rvec(xsol[i]);
                for (j = 0; j < na; j++)
                {
                    sa       = ind_sol[i*na+j];
                    mass     = top.atoms.atom[sa].m;
                    totmass += mass;
                    for (d = 0; d < DIM; d++)
                    {
                        xsol[i][d] += mass*x[sa][d];
                    }
                }
                svmul(1.0/totmass, xsol[i], xsol[i]);
            }
        }
        else
        {
            /* Copy the reference atom of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                copy_rvec(x[ind_sol[i*na+ref_a]], xsol[i]);
            }
        }

        if (bZ)
        {
            for (i = 0; (i < nwat); i++)
            {
                sa           = ind_sol[na*i];
                order[i].i   = sa;
                order[i].d2  = xsol[i][ZZ];
            }
        }
        else if (bCOM)
        {
            totmass = 0;
            clear_rvec(xcom);
            for (i = 0; i < isize_ref; i++)
            {
                mass     = top.atoms.atom[ind_ref[i]].m;
                totmass += mass;
                for (j = 0; j < DIM; j++)
                {
                    xcom[j] += mass*x[ind_ref[i]][j];
                }
            }
            svmul(1/totmass, xcom, xcom);
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, xcom, xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
        }
        else
        {
            /* Set distance to first atom */
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, x[ind_ref[0]], xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
            for (j = 1; (j < isize_ref); j++)
            {
                sr = ind_ref[j];
                for (i = 0; (i < nwat); i++)
                {
                    pbc_dx(&pbc, x[sr], xsol[i], dx);
                    n2 = norm2(dx);
                    if (n2 < order[i].d2)
                    {
                        order[i].d2  = n2;
                    }
                }
            }
        }

        if (bNShell)
        {
            ncut = 0;
            for (i = 0; (i < nwat); i++)
            {
                if (order[i].d2 <= rcut2)
                {
                    ncut++;
                }
            }
            fprintf(fp, "%10.3f  %8d\n", t, ncut);
        }
        if (out)
        {
            qsort(order, nwat, sizeof(*order), ocomp);
            for (i = 0; (i < nwat); i++)
            {
                for (j = 0; (j < na); j++)
                {
                    swi[ind_sol[na*i]+j] = order[i].i+j;
                }
            }

            /* Store the distance as the B-factor */
            if (bPDBout)
            {
                for (i = 0; (i < nwat); i++)
                {
                    for (j = 0; (j < na); j++)
                    {
                        top.atoms.pdbinfo[order[i].i+j].bfac = std::sqrt(order[i].d2);
                    }
                }
            }
            write_trx(out, natoms, swi, &top.atoms, 0, t, box, x, NULL, NULL);
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);
    if (out)
    {
        close_trx(out);
    }
    if (fp)
    {
        xvgrclose(fp);
    }
    gmx_rmpbc_done(gpbc);

    return 0;
}
示例#6
0
static void do_demux(int nset,char *fnms[],char *fnms_out[],
		     int nval,real **value,real *time,real dt_remd,
		     int isize,atom_id index[],real dt)
{
  int        i,j,k,natoms,nnn;
  int        *fp_in,*fp_out;
  bool       bCont,*bSet;
  real       t,first_time=0;
  t_trxframe *trx;
  
  snew(fp_in,nset);
  snew(trx,nset);
  snew(bSet,nset);
  natoms = -1;
  t = -1;
  for(i=0; (i<nset); i++) {
    nnn = read_first_frame(&(fp_in[i]),fnms[i],&(trx[i]),TRX_NEED_X);
    if (natoms == -1) {
      natoms = nnn;
      first_time = trx[i].time;
    }
    else if (natoms != nnn) 
      gmx_fatal(FARGS,"Trajectory file %s has %d atoms while previous trajs had %d atoms",fnms[i],nnn,natoms);
    if (t == -1)
      t = trx[i].time;
    else if (t != trx[i].time) 
      gmx_fatal(FARGS,"Trajectory file %s has time %f while previous trajs had time %f",fnms[i],trx[i].time,t);
  }
   
  snew(fp_out,nset);
  for(i=0; (i<nset); i++)
    fp_out[i] = open_trx(fnms_out[i],"w");
  k = 0;
  if (gmx_nint(time[k] - t) != 0) 
    gmx_fatal(FARGS,"First time in demuxing table does not match trajectories");
    
  do {
    while ((k+1 < nval) && ((trx[0].time - time[k+1]) > dt_remd*0.1))
      k++;
    if (debug)
      fprintf(debug,"trx[0].time = %g, time[k] = %g\n",trx[0].time,time[k]);
    for(i=0; (i<nset); i++) 
      bSet[i] = FALSE;
    for(i=0; (i<nset); i++) {
      j = gmx_nint(value[i][k]);
      range_check(j,0,nset);
      if (bSet[j])
	gmx_fatal(FARGS,"Demuxing the same replica %d twice at time %f",
		  j,trx[0].time);
      bSet[j] = TRUE;
      
      if (dt==0 || bRmod(trx[i].time,first_time,dt)) {
	if (index)
	  write_trxframe_indexed(fp_out[j],&trx[i],isize,index);
	else
	  write_trxframe(fp_out[j],&trx[i]);
      }
    }
    
    bCont = (k < nval);
    for(i=0; (i<nset); i++) 
      bCont = bCont && read_next_frame(fp_in[i],&trx[i]);
  } while (bCont);
  
  for(i=0; (i<nset); i++) {
    close_trx(fp_in[i]);
    close_trx(fp_out[i]);
  }
}
static void analyze_clusters(int nf, t_clusters *clust, real **rmsd,
			     int natom, t_atoms *atoms, rvec *xtps, 
			     real *mass, rvec **xx, real *time,
			     int ifsize, atom_id *fitidx,
			     int iosize, atom_id *outidx,
			     char *trxfn, char *sizefn, char *transfn, 
			     char *ntransfn, char *clustidfn, bool bAverage, 
			     int write_ncl, int write_nst, real rmsmin,bool bFit,
			     FILE *log,t_rgb rlo,t_rgb rhi)
{
  FILE *fp=NULL;
  char buf[STRLEN],buf1[40],buf2[40],buf3[40],*trxsfn;
  int  trxout=0,trxsout=0;
  int  i,i1,cl,nstr,*structure,first=0,midstr;
  bool *bWrite=NULL;
  real r,clrmsd,midrmsd;
  rvec *xav=NULL;
  matrix zerobox;
  
  clear_mat(zerobox);
  
  ffprintf1(stderr,log,buf,"\nFound %d clusters\n\n",clust->ncl);
  trxsfn=NULL;
  if (trxfn) {
    /* do we write all structures? */
    if (write_ncl) {
      trxsfn = parse_filename(trxfn, max(write_ncl,clust->ncl));
      snew(bWrite,nf);
    }
    ffprintf2(stderr,log,buf,"Writing %s structure for each cluster to %s\n",
	      bAverage ? "average" : "middle", trxfn);
    if (write_ncl) {
      /* find out what we want to tell the user:
	 Writing [all structures|structures with rmsd > %g] for 
	 {all|first %d} clusters {with more than %d structures} to %s     */
      if (rmsmin>0.0)
	sprintf(buf1,"structures with rmsd > %g",rmsmin);
      else
	sprintf(buf1,"all structures");
      buf2[0]=buf3[0]='\0';
      if (write_ncl>=clust->ncl) {
	if (write_nst==0)
	  sprintf(buf2,"all ");
      } else
	sprintf(buf2,"the first %d ",write_ncl);
      if (write_nst)
	sprintf(buf3," with more than %d structures",write_nst);
      sprintf(buf,"Writing %s for %sclusters%s to %s\n",buf1,buf2,buf3,trxsfn);
      ffprintf(stderr,log,buf);
    }
  
    /* Prepare a reference structure for the orientation of the clusters  */
    if (bFit)
    reset_x(ifsize,fitidx,natom,NULL,xtps,mass);
    trxout = open_trx(trxfn,"w");
    /* Calculate the average structure in each cluster,               *
     * all structures are fitted to the first struture of the cluster */
    snew(xav,natom);
  }
  
  if (transfn || ntransfn) 
    ana_trans(clust, nf, transfn, ntransfn, log,rlo,rhi);
  
  if (clustidfn) {
    fp=xvgropen(clustidfn,"Clusters",xvgr_tlabel(),"Cluster #");
    fprintf(fp,"@    s0 symbol 2\n");
    fprintf(fp,"@    s0 symbol size 0.2\n");
    fprintf(fp,"@    s0 linestyle 0\n");
    for(i=0; i<nf; i++)
      fprintf(fp,"%8g %8d\n",time[i],clust->cl[i]);
    ffclose(fp);
  }
  if (sizefn) {
    fp=xvgropen(sizefn,"Cluster Sizes","Cluster #","# Structures");
    fprintf(fp,"@g%d type %s\n",0,"bar");
  }
  snew(structure,nf);
  fprintf(log,"\n%3s | %3s %4s | %6s %4s | cluster members\n",
	  "cl.","#st","rmsd","middle","rmsd");
  for(cl=1; cl<=clust->ncl; cl++) {
    /* prepare structures (fit, middle, average) */
    if (xav)
      for(i=0; i<natom;i++)
	clear_rvec(xav[i]);
    nstr=0;
    for(i1=0; i1<nf; i1++)
      if (clust->cl[i1] == cl) {
	structure[nstr] = i1;
	nstr++;
	if (trxfn && (bAverage || write_ncl) ) {
	  if (bFit)
	  reset_x(ifsize,fitidx,natom,NULL,xx[i1],mass);
	  if (nstr == 1)
	    first = i1;
	  else if (bFit)
	    do_fit(natom,mass,xx[first],xx[i1]);
	  if (xav)
	    for(i=0; i<natom; i++)
	      rvec_inc(xav[i],xx[i1][i]);
	}
      }
    if (sizefn)
      fprintf(fp,"%8d %8d\n",cl,nstr);
    clrmsd = 0;
    midstr = 0;
    midrmsd = 10000;
    for(i1=0; i1<nstr; i1++) {
      r = 0;
      if (nstr > 1) {
	for(i=0; i<nstr; i++)
	  if (i < i1)
	    r += rmsd[structure[i]][structure[i1]];
	  else
	    r += rmsd[structure[i1]][structure[i]];
	r /= (nstr - 1);
      }
      if ( r < midrmsd ) {
	midstr = structure[i1];
	midrmsd = r;
      }
      clrmsd += r;
    }
    clrmsd /= nstr;
    
    /* dump cluster info to logfile */
    if (nstr > 1) {
      sprintf(buf1,"%5.3f",clrmsd);
      if (buf1[0] == '0')
	buf1[0] = ' ';
      sprintf(buf2,"%5.3f",midrmsd);
      if (buf2[0] == '0')
	buf2[0] = ' ';
    } else {
      sprintf(buf1,"%5s","");
      sprintf(buf2,"%5s","");
    }
    fprintf(log,"%3d | %3d%s | %6g%s |",cl,nstr,buf1,time[midstr],buf2);
    for(i=0; i<nstr; i++) {
      if ((i % 7 == 0) && i)
	sprintf(buf,"\n%3s | %3s %4s | %6s %4s |","","","","","");
      else
	buf[0] = '\0';
      i1 = structure[i];
      fprintf(log,"%s %6g",buf,time[i1]);
    }
    fprintf(log,"\n");
    
    /* write structures to trajectory file(s) */
    if (trxfn) {
      if (write_ncl)
	for(i=0; i<nstr; i++)
	  bWrite[i]=FALSE;
      if ( cl < write_ncl+1 && nstr > write_nst ) {
	/* Dump all structures for this cluster */
	/* generate numbered filename (there is a %d in trxfn!) */
	sprintf(buf,trxsfn,cl);
	trxsout = open_trx(buf,"w");
	for(i=0; i<nstr; i++) {
	  bWrite[i] = TRUE;
	  if (rmsmin>0.0)
	    for(i1=0; i1<i && bWrite[i]; i1++)
	      if (bWrite[i1])
		bWrite[i] = rmsd[structure[i1]][structure[i]] > rmsmin;
	  if (bWrite[i])
	    write_trx(trxsout,iosize,outidx,atoms,i,time[structure[i]],zerobox,
		      xx[structure[i]],NULL);
	}
	close_trx(trxsout);
      } 
      /* Dump the average structure for this cluster */
      if (bAverage) {
	for(i=0; i<natom; i++)
	  svmul(1.0/nstr,xav[i],xav[i]);
      } else {
	for(i=0; i<natom; i++)
	  copy_rvec(xx[midstr][i],xav[i]);
	if (bFit)
	reset_x(ifsize,fitidx,natom,NULL,xav,mass);
      }
      if (bFit)
	do_fit(natom,mass,xtps,xav);
      r = cl;
      write_trx(trxout,iosize,outidx,atoms,cl,time[midstr],zerobox,xav,NULL);
    }
  }
  /* clean up */
  if (trxfn) {
    close_trx(trxout);
    sfree(xav);
    if (write_ncl)
      sfree(bWrite);
  }
  sfree(structure);
  if (trxsfn)
    sfree(trxsfn);
}
示例#8
0
static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
                     real **value, real *time, real dt_remd, int isize,
                     int index[], real dt, const gmx_output_env_t *oenv)
{
    int           i, j, k, natoms, nnn;
    t_trxstatus **fp_in, **fp_out;
    gmx_bool      bCont, *bSet;
    real          t, first_time = 0;
    t_trxframe   *trx;

    snew(fp_in, nset);
    snew(trx, nset);
    snew(bSet, nset);
    natoms = -1;
    t      = -1;
    for (i = 0; (i < nset); i++)
    {
        nnn = read_first_frame(oenv, &(fp_in[i]), fnms[i], &(trx[i]),
                               TRX_NEED_X);
        if (natoms == -1)
        {
            natoms     = nnn;
            first_time = trx[i].time;
        }
        else if (natoms != nnn)
        {
            gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", fnms[i], nnn, natoms);
        }
        if (t == -1)
        {
            t = trx[i].time;
        }
        else if (t != trx[i].time)
        {
            gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", fnms[i], trx[i].time, t);
        }
    }

    snew(fp_out, nset);
    for (i = 0; (i < nset); i++)
    {
        fp_out[i] = open_trx(fnms_out[i], "w");
    }
    k = 0;
    if (std::round(time[k] - t) != 0)
    {
        gmx_fatal(FARGS, "First time in demuxing table does not match trajectories");
    }
    do
    {
        while ((k+1 < nval) && ((trx[0].time - time[k+1]) > dt_remd*0.1))
        {
            k++;
        }
        if (debug)
        {
            fprintf(debug, "trx[0].time = %g, time[k] = %g\n", trx[0].time, time[k]);
        }
        for (i = 0; (i < nset); i++)
        {
            bSet[i] = FALSE;
        }
        for (i = 0; (i < nset); i++)
        {
            j = std::round(value[i][k]);
            range_check(j, 0, nset);
            if (bSet[j])
            {
                gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f",
                          j, trx[0].time);
            }
            bSet[j] = TRUE;

            if (dt == 0 || bRmod(trx[i].time, first_time, dt))
            {
                if (index)
                {
                    write_trxframe_indexed(fp_out[j], &trx[i], isize, index, NULL);
                }
                else
                {
                    write_trxframe(fp_out[j], &trx[i], NULL);
                }
            }
        }

        bCont = (k < nval);
        for (i = 0; (i < nset); i++)
        {
            bCont = bCont && read_next_frame(oenv, fp_in[i], &trx[i]);
        }
    }
    while (bCont);

    for (i = 0; (i < nset); i++)
    {
        close_trx(fp_in[i]);
        close_trx(fp_out[i]);
    }
}
示例#9
0
int gmx_trjcat(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] concatenates several input trajectory files in sorted order. ",
        "In case of double time frames the one in the later file is used. ",
        "By specifying [TT]-settime[tt] you will be asked for the start time ",
        "of each file. The input files are taken from the command line, ",
        "such that a command like [TT]gmx trjcat -f *.trr -o fixed.trr[tt] should do ",
        "the trick. Using [TT]-cat[tt], you can simply paste several files ",
        "together without removal of frames with identical time stamps.[PAR]",
        "One important option is inferred when the output file is amongst the",
        "input files. In that case that particular file will be appended to",
        "which implies you do not need to store double the amount of data.",
        "Obviously the file to append to has to be the one with lowest starting",
        "time since one can only append at the end of a file.[PAR]",
        "If the [TT]-demux[tt] option is given, the N trajectories that are",
        "read, are written in another order as specified in the [REF].xvg[ref] file.",
        "The [REF].xvg[ref] file should contain something like::",
        "",
        "    0  0  1  2  3  4  5",
        "    2  1  0  2  3  5  4",
        "",
        "The first number is the time, and subsequent numbers point to",
        "trajectory indices.",
        "The frames corresponding to the numbers present at the first line",
        "are collected into the output trajectory. If the number of frames in",
        "the trajectory does not match that in the [REF].xvg[ref] file then the program",
        "tries to be smart. Beware."
    };
    static gmx_bool bCat            = FALSE;
    static gmx_bool bSort           = TRUE;
    static gmx_bool bKeepLast       = FALSE;
    static gmx_bool bKeepLastAppend = FALSE;
    static gmx_bool bOverwrite      = FALSE;
    static gmx_bool bSetTime        = FALSE;
    static gmx_bool bDeMux;
    static real     begin = -1;
    static real     end   = -1;
    static real     dt    = 0;

    t_pargs
        pa[] =
    {
        { "-b", FALSE, etTIME,
          { &begin }, "First time to use (%t)" },
        { "-e", FALSE, etTIME,
          { &end }, "Last time to use (%t)" },
        { "-dt", FALSE, etTIME,
          { &dt }, "Only write frame when t MOD dt = first time (%t)" },
        { "-settime", FALSE, etBOOL,
          { &bSetTime }, "Change starting time interactively" },
        { "-sort", FALSE, etBOOL,
          { &bSort }, "Sort trajectory files (not frames)" },
        { "-keeplast", FALSE, etBOOL,
          { &bKeepLast }, "Keep overlapping frames at end of trajectory" },
        { "-overwrite", FALSE, etBOOL,
          { &bOverwrite }, "Overwrite overlapping frames during appending" },
        { "-cat", FALSE, etBOOL,
          { &bCat }, "Do not discard double time frames" }
    };
#define npargs asize(pa)
    int               ftpin, i, frame, frame_out;
    t_trxstatus      *status, *trxout = NULL;
    real              t_corr;
    t_trxframe        fr, frout;
    char            **fnms, **fnms_out, *out_file;
    int               n_append;
    gmx_bool          bNewFile, bIndex, bWrite;
    int               nfile_in, nfile_out, *cont_type;
    real             *readtime, *timest, *settime;
    real              first_time  = 0, lasttime, last_ok_t = -1, timestep;
    gmx_bool          lastTimeSet = FALSE;
    real              last_frame_time, searchtime;
    int               isize = 0, j;
    int              *index = NULL, imax;
    char             *grpname;
    real            **val = NULL, *t = NULL, dt_remd;
    int               n, nset, ftpout = -1, prevEndStep = 0, filetype;
    gmx_off_t         fpos;
    gmx_output_env_t *oenv;
    t_filenm          fnm[] =
    {
        { efTRX, "-f", NULL, ffRDMULT },
        { efTRO, "-o", NULL, ffWRMULT },
        { efNDX, "-n", "index", ffOPTRD },
        { efXVG, "-demux", "remd", ffOPTRD }
    };

#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_TIME_UNIT, NFILE, fnm,
                           asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    bIndex = ftp2bSet(efNDX, NFILE, fnm);
    bDeMux = ftp2bSet(efXVG, NFILE, fnm);
    bSort  = bSort && !bDeMux;

    imax = -1;
    if (bIndex)
    {
        printf("Select group for output\n");
        rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
        /* scan index */
        imax = index[0];
        for (i = 1; i < isize; i++)
        {
            imax = std::max(imax, index[i]);
        }
    }
    if (bDeMux)
    {
        nset    = 0;
        dt_remd = 0;
        val     = read_xvg_time(opt2fn("-demux", NFILE, fnm), TRUE,
                                opt2parg_bSet("-b", npargs, pa), begin,
                                opt2parg_bSet("-e", npargs, pa), end, 1, &nset, &n,
                                &dt_remd, &t);
        printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt_remd);
        if (debug)
        {
            fprintf(debug, "Dump of replica_index.xvg\n");
            for (i = 0; (i < n); i++)
            {
                fprintf(debug, "%10g", t[i]);
                for (j = 0; (j < nset); j++)
                {
                    fprintf(debug, "  %3d", static_cast<int>(std::round(val[j][i])));
                }
                fprintf(debug, "\n");
            }
        }
    }

    nfile_in = opt2fns(&fnms, "-f", NFILE, fnm);
    if (!nfile_in)
    {
        gmx_fatal(FARGS, "No input files!" );
    }

    if (bDeMux && (nfile_in != nset))
    {
        gmx_fatal(FARGS, "You have specified %d files and %d entries in the demux table", nfile_in, nset);
    }

    ftpin = fn2ftp(fnms[0]);

    for (i = 1; i < nfile_in; i++)
    {
        if (ftpin != fn2ftp(fnms[i]))
        {
            gmx_fatal(FARGS, "All input files must be of the same format");
        }
    }

    nfile_out = opt2fns(&fnms_out, "-o", NFILE, fnm);
    if (!nfile_out)
    {
        gmx_fatal(FARGS, "No output files!");
    }
    if ((nfile_out > 1) && !bDeMux)
    {
        gmx_fatal(FARGS, "Don't know what to do with more than 1 output file if  not demultiplexing");
    }
    else if (bDeMux && (nfile_out != nset) && (nfile_out != 1))
    {
        gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %d", nset, nfile_out);
    }
    if (bDeMux)
    {
        if (nfile_out != nset)
        {
            char *buf = gmx_strdup(fnms_out[0]);
            snew(fnms_out, nset);
            for (i = 0; (i < nset); i++)
            {
                snew(fnms_out[i], std::strlen(buf)+32);
                sprintf(fnms_out[i], "%d_%s", i, buf);
            }
            sfree(buf);
        }
        do_demux(nfile_in, fnms, fnms_out, n, val, t, dt_remd, isize, index, dt, oenv);
    }
    else
    {
        snew(readtime, nfile_in+1);
        snew(timest, nfile_in+1);
        scan_trj_files(fnms, nfile_in, readtime, timest, imax, oenv);

        snew(settime, nfile_in+1);
        snew(cont_type, nfile_in+1);
        edit_files(fnms, nfile_in, readtime, timest, settime, cont_type, bSetTime, bSort,
                   oenv);

        /* Check whether the output file is amongst the input files
         * This has to be done after sorting etc.
         */
        out_file = fnms_out[0];
        ftpout   = fn2ftp(out_file);
        n_append = -1;
        for (i = 0; ((i < nfile_in) && (n_append == -1)); i++)
        {
            if (std::strcmp(fnms[i], out_file) == 0)
            {
                n_append = i;
            }
        }
        if (n_append == 0)
        {
            fprintf(stderr, "Will append to %s rather than creating a new file\n",
                    out_file);
        }
        else if (n_append != -1)
        {
            gmx_fatal(FARGS, "Can only append to the first file which is %s (not %s)",
                      fnms[0], out_file);
        }

        /* Not checking input format, could be dangerous :-) */
        /* Not checking output format, equally dangerous :-) */

        frame     = -1;
        frame_out = -1;
        /* the default is not to change the time at all,
         * but this is overridden by the edit_files routine
         */
        t_corr = 0;

        if (n_append == -1)
        {
            if (ftpout == efTNG)
            {
                if (ftpout != ftpin)
                {
                    gmx_fatal(FARGS, "When writing TNG the input file format must also be TNG");
                }
                if (bIndex)
                {
                    trjtools_gmx_prepare_tng_writing(out_file, 'w', NULL, &trxout,
                                                     fnms[0], isize, NULL, index, grpname);
                }
                else
                {
                    trjtools_gmx_prepare_tng_writing(out_file, 'w', NULL, &trxout,
                                                     fnms[0], -1, NULL, NULL, NULL);
                }
            }
            else
            {
                trxout = open_trx(out_file, "w");
            }
            std::memset(&frout, 0, sizeof(frout));
        }
        else
        {
            t_fileio *stfio;

            if (!read_first_frame(oenv, &status, out_file, &fr, FLAGS))
            {
                gmx_fatal(FARGS, "Reading first frame from %s", out_file);
            }

            stfio = trx_get_fileio(status);
            if (!bKeepLast && !bOverwrite)
            {
                fprintf(stderr, "\n\nWARNING: Appending without -overwrite implies -keeplast "
                        "between the first two files. \n"
                        "If the trajectories have an overlap and have not been written binary \n"
                        "reproducible this will produce an incorrect trajectory!\n\n");

                filetype = gmx_fio_getftp(stfio);
                /* Fails if last frame is incomplete
                 * We can't do anything about it without overwriting
                 * */
                if (filetype == efXTC || filetype == efTNG)
                {
                    lasttime = trx_get_time_of_final_frame(status);
                    fr.time  = lasttime;
                }
                else
                {
                    while (read_next_frame(oenv, status, &fr))
                    {
                        ;
                    }
                    lasttime = fr.time;
                }
                lastTimeSet     = TRUE;
                bKeepLastAppend = TRUE;
                close_trj(status);
                trxout = open_trx(out_file, "a");
            }
            else if (bOverwrite)
            {
                if (gmx_fio_getftp(stfio) != efXTC)
                {
                    gmx_fatal(FARGS, "Overwrite only supported for XTC." );
                }
                last_frame_time = trx_get_time_of_final_frame(status);

                /* xtc_seek_time broken for trajectories containing only 1 or 2 frames
                 *     or when seek time = 0 */
                if (nfile_in > 1 && settime[1] < last_frame_time+timest[0]*0.5)
                {
                    /* Jump to one time-frame before the start of next
                     *  trajectory file */
                    searchtime = settime[1]-timest[0]*1.25;
                }
                else
                {
                    searchtime = last_frame_time;
                }
                if (xtc_seek_time(stfio, searchtime, fr.natoms, TRUE))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
                read_next_frame(oenv, status, &fr);
                if (std::abs(searchtime - fr.time) > timest[0]*0.5)
                {
                    gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.",
                              searchtime, fr.time);
                }
                lasttime    = fr.time;
                lastTimeSet = TRUE;
                fpos        = gmx_fio_ftell(stfio);
                close_trj(status);
                trxout = open_trx(out_file, "r+");
                if (gmx_fio_seek(trx_get_fileio(trxout), fpos))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
            }
            if (lastTimeSet)
            {
                printf("\n Will append after %f \n", lasttime);
            }
            frout = fr;
        }
        /* Lets stitch up some files */
        timestep = timest[0];
        for (i = n_append+1; (i < nfile_in); i++)
        {
            /* Open next file */

            /* set the next time from the last frame in previous file */
            if (i > 0)
            {
                /* When writing TNG the step determine which frame to write. Use an
                 * offset to be able to increase steps properly when changing files. */
                if (ftpout == efTNG)
                {
                    prevEndStep = frout.step;
                }

                if (frame_out >= 0)
                {
                    if (cont_type[i] == TIME_CONTINUE)
                    {
                        begin        = frout.time;
                        begin       += 0.5*timestep;
                        settime[i]   = frout.time;
                        cont_type[i] = TIME_EXPLICIT;
                    }
                    else if (cont_type[i] == TIME_LAST)
                    {
                        begin  = frout.time;
                        begin += 0.5*timestep;
                    }
                    /* Or, if the time in the next part should be changed by the
                     * same amount, start at half a timestep from the last time
                     * so we dont repeat frames.
                     */
                    /* I don't understand the comment above, but for all the cases
                     * I tried the code seems to work properly. B. Hess 2008-4-2.
                     */
                }
                /* Or, if time is set explicitly, we check for overlap/gap */
                if (cont_type[i] == TIME_EXPLICIT)
                {
                    if ( ( i < nfile_in ) &&
                         ( frout.time < settime[i]-1.5*timestep ) )
                    {
                        fprintf(stderr, "WARNING: Frames around t=%f %s have a different "
                                "spacing than the rest,\n"
                                "might be a gap or overlap that couldn't be corrected "
                                "automatically.\n", output_env_conv_time(oenv, frout.time),
                                output_env_get_time_unit(oenv));
                    }
                }
            }

            /* if we don't have a timestep in the current file, use the old one */
            if (timest[i] != 0)
            {
                timestep = timest[i];
            }
            read_first_frame(oenv, &status, fnms[i], &fr, FLAGS);
            if (!fr.bTime)
            {
                fr.time = 0;
                fprintf(stderr, "\nWARNING: Couldn't find a time in the frame.\n");
            }

            if (cont_type[i] == TIME_EXPLICIT)
            {
                t_corr = settime[i]-fr.time;
            }
            /* t_corr is the amount we want to change the time.
             * If the user has chosen not to change the time for
             * this part of the trajectory t_corr remains at
             * the value it had in the last part, changing this
             * by the same amount.
             * If no value was given for the first trajectory part
             * we let the time start at zero, see the edit_files routine.
             */

            bNewFile = TRUE;

            if (!lastTimeSet)
            {
                lasttime    = 0;
                lastTimeSet = true;
            }
            printf("\n");
            printf("lasttime %g\n", lasttime);

            do
            {
                /* copy the input frame to the output frame */
                frout = fr;
                /* set the new time by adding the correct calculated above */
                frout.time += t_corr;
                if (ftpout == efTNG)
                {
                    frout.step += prevEndStep;
                }
                /* quit if we have reached the end of what should be written */
                if ((end > 0) && (frout.time > end+GMX_REAL_EPS))
                {
                    i = nfile_in;
                    break;
                }

                /* determine if we should write this frame (dt is handled elsewhere) */
                if (bCat) /* write all frames of all files */
                {
                    bWrite = TRUE;
                }
                else if (bKeepLast || (bKeepLastAppend && i == 1))
                /* write till last frame of this traj
                   and skip first frame(s) of next traj */
                {
                    bWrite = ( frout.time > lasttime+0.5*timestep );
                }
                else /* write till first frame of next traj */
                {
                    bWrite = ( frout.time < settime[i+1]-0.5*timestep );
                }

                if (bWrite && (frout.time >= begin) )
                {
                    frame++;
                    if (frame_out == -1)
                    {
                        first_time = frout.time;
                    }
                    lasttime    = frout.time;
                    lastTimeSet = TRUE;
                    if (dt == 0 || bRmod(frout.time, first_time, dt))
                    {
                        frame_out++;
                        last_ok_t = frout.time;
                        if (bNewFile)
                        {
                            fprintf(stderr, "\nContinue writing frames from %s t=%g %s, "
                                    "frame=%d      \n",
                                    fnms[i], output_env_conv_time(oenv, frout.time), output_env_get_time_unit(oenv),
                                    frame);
                            bNewFile = FALSE;
                        }

                        if (bIndex)
                        {
                            write_trxframe_indexed(trxout, &frout, isize, index,
                                                   NULL);
                        }
                        else
                        {
                            write_trxframe(trxout, &frout, NULL);
                        }
                        if ( ((frame % 10) == 0) || (frame < 10) )
                        {
                            fprintf(stderr, " ->  frame %6d time %8.3f %s     \r",
                                    frame_out, output_env_conv_time(oenv, frout.time), output_env_get_time_unit(oenv));
                            fflush(stderr);
                        }
                    }
                }
            }
            while (read_next_frame(oenv, status, &fr));

            close_trj(status);
        }
        if (trxout)
        {
            close_trx(trxout);
        }
        fprintf(stderr, "\nLast frame written was %d, time %f %s\n",
                frame, output_env_conv_time(oenv, last_ok_t), output_env_get_time_unit(oenv));
    }

    return 0;
}
示例#10
0
int gmx_insert_dummy_atom(int argc, char *argv[])
{
    const char      *desc[] = {
        "\tAdd a dummy atom between atoms -a1 and -a2",
    };

    gmx_bool        bVerbose = FALSE;
    int             a1=-1,a2=-1;
	int 			insert_at=-1;
    const char      *tpr_file, *traj_file, *out_file;
    t_pargs         pa[] = {
        { "-a1", TRUE, etINT,
            {&a1}, "Starting atom for bond vector--ie: CD in CNC"},
        { "-a2", TRUE, etINT,
            {&a2}, "Ending atom for bond vector--ie: NE in CNC"},
        { "-insert_at", TRUE, etINT,
            {&insert_at}, "Desired index for dummy atom. Default = 0"},
        { "-v", FALSE, etBOOL,
            {&bVerbose}, "Be slightly more verbose"}
    };
    t_filenm        fnm[] = {
        {efTPS, NULL, NULL, ffREAD},
        {efTRX, NULL, NULL, ffREAD},
        {efTRO, "-o","tilt",ffWRITE},
    };
#define NFILE asize(fnm)
#define NPA asize(pa)
    output_env_t    oenv;
    int             ngrps, nrefgrps;
    t_topology      top;
    t_atoms         *atoms=NULL;
    t_trxframe      fr,frout;
    t_trxstatus     *status;
    rvec            *xtop;
    matrix          box;
    int             ePBC;
    int             flags=TRX_READ_X;
    char            buffer[1024];
    int             ftp;
    FILE            *out_gro = NULL;
    t_trxstatus     *trxout = NULL;

    CopyRight(stderr,argv[0]);
    parse_common_args(&argc, argv, 
                      PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | 
                      PCA_TIME_UNIT | PCA_BE_NICE | PCA_CAN_TIME,
                      NFILE, fnm, NPA, pa, asize(desc), desc,
                      0, NULL, &oenv);

    /* Get inputs */
    tpr_file    = ftp2fn(efTPS, NFILE, fnm);
    traj_file   = opt2fn( "-f", NFILE, fnm);
    out_file    = opt2fn("-o", NFILE, fnm);
    ftp = fn2ftp(out_file);
    
    std::cout << "\n\n" << out_file << " " << ftp << std::endl;
    
    /* Open inputs */
    read_tps_conf(tpr_file, buffer, &top, &ePBC,
                  &xtop, NULL, box, TRUE);
    sfree(xtop);
    atoms = &top.atoms;
    gmx_conect gc = NULL;
    gc = gmx_conect_generate(&top);
    
    /* Make sure -a1 and -a2 are included and increment by -1 to match internal numbering */
    if ( a1<1 || a2<1 || a1==a2 || a1>top.atoms.nr || a2>top.atoms.nr ) {
        gmx_fatal(FARGS, "\nAtom numbers -a1 and -a2 defining the bond vector must be specified and different\n");
    }
    a1--; a2--;

    /* Read first frame */
    gmx_bool bHaveFirstFrame = read_first_frame(oenv, &status, traj_file, &fr, flags);
    if (bHaveFirstFrame) {
        set_trxframe_ePBC(&fr,ePBC);
    }
    
    if (ftp == efGRO) {
        out_gro = ffopen(out_file,"w");
    }
    else if (ftp == efXTC) {
        trxout = open_trx(out_file,"w");
    }
    
    /* read file and loop through frames */
    int frameN = 0;
    do {
        if (ftp == efGRO) {
            fprintf(out_gro,"Dummy atom inserted into %s, FRAME %i\n",traj_file,frameN);
            fprintf(out_gro,"%i\n",top.atoms.nr+1);
            float CD[3] = { fr.x[a1][0], fr.x[a1][1], fr.x[a1][2] };
            float NE[3] = { fr.x[a2][0], fr.x[a2][1], fr.x[a2][2] };
            float MP[3] ;
            for (int i=0;i<3;i++) {
                MP[i] = (CD[i]+NE[i])*0.5;
            }
            // GRO format:
            // RESID, RESNAME, ATOM, INDEX, X, Y, Z, vX, vY, vZ
            //"%5d%-5s%5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f"
            int index = 1;
			if (insert_at <= 0) {
            	fprintf(out_gro,"%5d%-5s%5s%5d%8.4f%8.4f%8.4f%8.4f%8.4f%8.4f\n",
                    0,"TCHG","TCHG",0,MP[0],MP[1],MP[2],0.0f,0.0f,0.0f);
					index++;
			}

            /* Loop over atoms */
			int i;
			int resid_offset = 0;
            for (i=0;i<top.atoms.nr;i++){
				if (insert_at == index) {
            		fprintf(out_gro,"%5d%-5s%5s%5d%8.4f%8.4f%8.4f%8.4f%8.4f%8.4f\n",
                    	top.atoms.atom[i-1].resind+2,"TCHG","TCHG",index,MP[0],MP[1],MP[2],0.0f,0.0f,0.0f);
					index++;
					resid_offset++;
				}
                // Ignoring velocities since I'm using this with mdrun -rerun for
                // force calculations only, which don't care about velocities
                fprintf(out_gro,"%5d%-5s%5s%5d%8.4f%8.4f%8.4f%8.4f%8.4f%8.4f\n",
                        top.atoms.atom[i].resind+1 + resid_offset,
                        *top.atoms.resinfo[top.atoms.atom[i].resind].name,
                        *top.atoms.atomname[i],
                        index,
                        fr.x[i][0], fr.x[i][1], fr.x[i][2],
                        0.0f,0.0f,0.0f);
                index++;
                if (index > 99999) {
                    index = 0;
                }
            }
            /* Get box information */
            write_hconf_box(out_gro,1,box);
        }
        else if (ftp == efXTC) {
            float CD[3] = { fr.x[a1][0], fr.x[a1][1], fr.x[a1][2] };
            float NE[3] = { fr.x[a2][0], fr.x[a2][1], fr.x[a2][2] };
            rvec MP ;
            for (int i=0;i<3;i++) {
                MP[i] = (CD[i]+NE[i])*0.5;
            }
            rvec * newX = new rvec [top.atoms.nr+1];
			int i = 0;
			int offset = 0;
			if (insert_at <= 0) {
            	for (int j=0;j<3;j++) {
                	newX[i][j] = MP[j];
            	}
				offset++;
			}
            for (i=0; i<top.atoms.nr; i++) {
				if (insert_at == i) {
            		for (int j=0;j<3;j++) {
                		newX[i][j] = MP[j];
					}
					offset++;
				}
                for (int j=0;j<3;j++) {
                    newX[i+offset][j] = fr.x[i][j];
                }
            }
            frout = fr;
            frout.x = newX;
            frout.natoms++;
            write_trxframe(trxout,&frout,gc);
            delete[] newX;
        }
        frameN++;
    } while(read_next_frame(oenv, status, &fr));
    
    if (trxout) {
        close_trx(trxout);
    }
    if (out_gro) {
        ffclose(out_gro);
    }
    
    return 0;
}
示例#11
0
int gmx_nmtraj(int argc, char *argv[])
{
    const char *desc[] =
    {
        "[THISMODULE] generates an virtual trajectory from an eigenvector, ",
        "corresponding to a harmonic Cartesian oscillation around the average ",
        "structure. The eigenvectors should normally be mass-weighted, but you can ",
        "use non-weighted eigenvectors to generate orthogonal motions. ",
        "The output frames are written as a trajectory file covering an entire period, and ",
        "the first frame is the average structure. If you write the trajectory in (or convert to) ",
        "PDB format you can view it directly in PyMol and also render a photorealistic movie. ",
        "Motion amplitudes are calculated from the eigenvalues and a preset temperature, ",
        "assuming equipartition of the energy over all modes. To make the motion clearly visible ",
        "in PyMol you might want to amplify it by setting an unrealistically high temperature. ",
        "However, be aware that both the linear Cartesian displacements and mass weighting will ",
        "lead to serious structure deformation for high amplitudes - this is is simply a limitation ",
        "of the Cartesian normal mode model. By default the selected eigenvector is set to 7, since ",
        "the first six normal modes are the translational and rotational degrees of freedom."
    };

    static real        refamplitude = 0.25;
    static int         nframes      = 30;
    static real        temp         = 300.0;
    static const char *eignrvec     = "7";
    static const char *phasevec     = "0.0";

    t_pargs            pa[] =
    {
        { "-eignr",     FALSE, etSTR,  {&eignrvec}, "String of eigenvectors to use (first is 1)" },
        { "-phases",    FALSE, etSTR,  {&phasevec}, "String of phases (default is 0.0)" },
        { "-temp",      FALSE, etREAL, {&temp},      "Temperature (K)" },
        { "-amplitude", FALSE, etREAL, {&refamplitude}, "Amplitude for modes with eigenvalue<=0" },
        { "-nframes",   FALSE, etINT,  {&nframes},   "Number of frames to generate" }
    };

#define NPA asize(pa)

    t_trxstatus      *out;
    t_topology        top;
    int               ePBC;
    t_atoms          *atoms;
    rvec             *xtop, *xref, *xav, *xout;
    int               nvec, *eignr = NULL;
    rvec            **eigvec = NULL;
    matrix            box;
    int               natoms;
    int               i, j, k, kmode, d;
    gmx_bool          bDMR, bDMA, bFit;

    real        *     eigval;
    int        *      dummy;
    real        *     invsqrtm;
    real              fraction;
    int              *out_eigidx;
    rvec        *     this_eigvec;
    real              omega, Ekin, m, vel;
    int               nmodes, nphases;
    int              *imodes;
    real             *amplitude;
    real             *phases;
    const char       *p;
    char             *pe;
    output_env_t      oenv;

    t_filenm          fnm[] =
    {
        { efTPS, NULL,    NULL,          ffREAD },
        { efTRN, "-v",    "eigenvec",    ffREAD  },
        { efTRO, "-o",    "nmtraj",      ffWRITE }
    };

#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, 0,
                           NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit,
                      &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, NULL, box, bDMA);

    /* Find vectors and phases */

    /* first find number of args in string */
    nmodes = gmx::countWords(eignrvec);

    snew(imodes, nmodes);
    p = eignrvec;
    for (i = 0; i < nmodes; i++)
    {
        /* C indices start on 0 */
        imodes[i] = std::strtol(p, &pe, 10)-1;
        p         = pe;
    }

    /* Now read phases */
    nphases = gmx::countWords(phasevec);

    if (nphases > nmodes)
    {
        gmx_fatal(FARGS, "More phases than eigenvector indices specified.\n");
    }

    snew(phases, nmodes);
    p = phasevec;

    for (i = 0; i < nphases; i++)
    {
        phases[i] = strtod(p, &pe);
        p         = pe;
    }

    if (nmodes > nphases)
    {
        printf("Warning: Setting phase of last %d modes to zero...\n", nmodes-nphases);
    }

    for (i = nphases; i < nmodes; i++)
    {
        phases[i] = 0;
    }

    atoms = &top.atoms;

    if (atoms->nr != natoms)
    {
        gmx_fatal(FARGS, "Different number of atoms in topology and eigenvectors.\n");
    }

    snew(dummy, natoms);
    for (i = 0; i < natoms; i++)
    {
        dummy[i] = i;
    }

    /* Find the eigenvalue/vector to match our select one */
    snew(out_eigidx, nmodes);
    for (i = 0; i < nmodes; i++)
    {
        out_eigidx[i] = -1;
    }

    for (i = 0; i < nvec; i++)
    {
        for (j = 0; j < nmodes; j++)
        {
            if (imodes[j] == eignr[i])
            {
                out_eigidx[j] = i;
            }
        }
    }
    for (i = 0; i < nmodes; i++)
    {
        if (out_eigidx[i] == -1)
        {
            gmx_fatal(FARGS, "Could not find mode %d in eigenvector file.\n", imodes[i]);
        }
    }


    snew(invsqrtm, natoms);

    if (bDMA)
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = gmx_invsqrt(atoms->atom[i].m);
        }
    }
    else
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = 1.0;
        }
    }

    snew(xout, natoms);
    snew(amplitude, nmodes);

    printf("mode phases: %g %g\n", phases[0], phases[1]);

    for (i = 0; i < nmodes; i++)
    {
        kmode       = out_eigidx[i];
        this_eigvec = eigvec[kmode];

        if ( (kmode >= 6) && (eigval[kmode] > 0))
        {
            /* Derive amplitude from temperature and eigenvalue if we can */

            /* Convert eigenvalue to angular frequency, in units s^(-1) */
            omega = std::sqrt(eigval[kmode]*1.0E21/(AVOGADRO*AMU));
            /* Harmonic motion will be x=x0 + A*sin(omega*t)*eigenvec.
             * The velocity is thus:
             *
             * v = A*omega*cos(omega*t)*eigenvec.
             *
             * And the average kinetic energy the integral of mass*v*v/2 over a
             * period:
             *
             * (1/4)*mass*A*omega*eigenvec
             *
             * For t =2*pi*n, all energy will be kinetic, and v=A*omega*eigenvec.
             * The kinetic energy will be sum(0.5*mass*v*v) if we temporarily set A to 1,
             * and the average over a period half of this.
             */

            Ekin = 0;
            for (k = 0; k < natoms; k++)
            {
                m = atoms->atom[k].m;
                for (d = 0; d < DIM; d++)
                {
                    vel   = omega*this_eigvec[k][d];
                    Ekin += 0.5*0.5*m*vel*vel;
                }
            }

            /* Convert Ekin from amu*(nm/s)^2 to J, i.e., kg*(m/s)^2
             * This will also be proportional to A^2
             */
            Ekin *= AMU*1E-18;

            /* Set the amplitude so the energy is kT/2 */
            amplitude[i] = std::sqrt(0.5*BOLTZMANN*temp/Ekin);
        }
        else
        {
            amplitude[i] = refamplitude;
        }
    }

    out = open_trx(ftp2fn(efTRO, NFILE, fnm), "w");

    /* Write a sine oscillation around the average structure,
     * modulated by the eigenvector with selected amplitude.
     */

    for (i = 0; i < nframes; i++)
    {
        fraction = static_cast<real>(i)/nframes;
        for (j = 0; j < natoms; j++)
        {
            copy_rvec(xav[j], xout[j]);
        }

        for (k = 0; k < nmodes; k++)
        {
            kmode       = out_eigidx[k];
            this_eigvec = eigvec[kmode];

            for (j = 0; j < natoms; j++)
            {
                for (d = 0; d < DIM; d++)
                {
                    xout[j][d] += amplitude[k]*std::sin(2*M_PI*(fraction+phases[k]/360.0))*this_eigvec[j][d];
                }
            }
        }
        write_trx(out, natoms, dummy, atoms, i, static_cast<real>(i)/nframes, box, xout, NULL, NULL);
    }

    fprintf(stderr, "\n");
    close_trx(out);

    return 0;
}
示例#12
0
static void do_demux(gmx::ArrayRef<const std::string> inFiles,
                     gmx::ArrayRef<const std::string> outFiles, int nval,
                     real **value, real *time, real dt_remd, int isize,
                     int index[], real dt, const gmx_output_env_t *oenv)
{
    int           k, natoms;
    t_trxstatus **fp_in, **fp_out;
    gmx_bool      bCont, *bSet;
    real          t, first_time = 0;
    t_trxframe   *trx;

    snew(fp_in, inFiles.size());
    snew(trx, inFiles.size());
    snew(bSet, inFiles.size());
    natoms = -1;
    t      = -1;
    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        read_first_frame(oenv, &(fp_in[i]), inFiles[i].c_str(), &(trx[i]),
                         TRX_NEED_X);
        if (natoms == -1)
        {
            natoms     = trx[i].natoms;
            first_time = trx[i].time;
        }
        else if (natoms != trx[i].natoms)
        {
            gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", inFiles[i].c_str(), trx[i].natoms, natoms);
        }
        if (t == -1)
        {
            t = trx[i].time;
        }
        else if (t != trx[i].time)
        {
            gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", inFiles[i].c_str(), trx[i].time, t);
        }
    }

    snew(fp_out, inFiles.size());
    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        fp_out[i] = open_trx(outFiles[i].c_str(), "w");
    }
    k = 0;
    if (std::round(time[k] - t) != 0)
    {
        gmx_fatal(FARGS, "First time in demuxing table does not match trajectories");
    }
    do
    {
        while ((k+1 < nval) && ((trx[0].time - time[k+1]) > dt_remd*0.1))
        {
            k++;
        }
        if (debug)
        {
            fprintf(debug, "trx[0].time = %g, time[k] = %g\n", trx[0].time, time[k]);
        }
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            bSet[i] = FALSE;
        }
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            int j = gmx::roundToInt(value[i][k]);
            range_check(j, 0, inFiles.size());
            if (bSet[j])
            {
                gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f",
                          j, trx[0].time);
            }
            bSet[j] = TRUE;

            if (dt == 0 || bRmod(trx[i].time, first_time, dt))
            {
                if (index)
                {
                    write_trxframe_indexed(fp_out[j], &trx[i], isize, index, nullptr);
                }
                else
                {
                    write_trxframe(fp_out[j], &trx[i], nullptr);
                }
            }
        }

        bCont = (k < nval);
        for (gmx::index i = 0; i < inFiles.ssize(); i++)
        {
            bCont = bCont && read_next_frame(oenv, fp_in[i], &trx[i]);
        }
    }
    while (bCont);

    for (gmx::index i = 0; i < inFiles.ssize(); i++)
    {
        close_trx(fp_in[i]);
        close_trx(fp_out[i]);
    }
}
示例#13
0
void dist_plot(const char *fn, const char *afile, const char *dfile,
               const char *nfile, const char *rfile, const char *xfile,
               real rcut, gmx_bool bMat, t_atoms *atoms,
               int ng, atom_id *index[], int gnx[], char *grpn[], gmx_bool bSplit,
               gmx_bool bMin, int nres, atom_id *residue, gmx_bool bPBC, int ePBC,
               gmx_bool bGroup, gmx_bool bEachResEachTime, gmx_bool bPrintResName,
               const output_env_t oenv)
{
    FILE            *atm, *dist, *num;
    t_trxstatus     *trxout;
    char             buf[256];
    char           **leg;
    real             t, dmin, dmax, **mindres = NULL, **maxdres = NULL;
    int              nmin, nmax;
    t_trxstatus     *status;
    int              i = -1, j, k, natoms;
    int              min1, min2, max1, max2, min1r, min2r, max1r, max2r;
    atom_id          oindex[2];
    rvec            *x0;
    matrix           box;
    t_trxframe       frout;
    gmx_bool         bFirst;
    FILE            *respertime = NULL;

    if ((natoms = read_first_x(oenv, &status, fn, &t, &x0, box)) == 0)
    {
        gmx_fatal(FARGS, "Could not read coordinates from statusfile\n");
    }

    sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
    dist = xvgropen(dfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv);
    sprintf(buf, "Number of Contacts %s %g nm", bMin ? "<" : ">", rcut);
    num    = nfile ? xvgropen(nfile, buf, output_env_get_time_label(oenv), "Number", oenv) : NULL;
    atm    = afile ? ffopen(afile, "w") : NULL;
    trxout = xfile ? open_trx(xfile, "w") : NULL;

    if (bMat)
    {
        if (ng == 1)
        {
            snew(leg, 1);
            sprintf(buf, "Internal in %s", grpn[0]);
            leg[0] = strdup(buf);
            xvgr_legend(dist, 0, (const char**)leg, oenv);
            if (num)
            {
                xvgr_legend(num, 0, (const char**)leg, oenv);
            }
        }
        else
        {
            snew(leg, (ng*(ng-1))/2);
            for (i = j = 0; (i < ng-1); i++)
            {
                for (k = i+1; (k < ng); k++, j++)
                {
                    sprintf(buf, "%s-%s", grpn[i], grpn[k]);
                    leg[j] = strdup(buf);
                }
            }
            xvgr_legend(dist, j, (const char**)leg, oenv);
            if (num)
            {
                xvgr_legend(num, j, (const char**)leg, oenv);
            }
        }
    }
    else
    {
        snew(leg, ng-1);
        for (i = 0; (i < ng-1); i++)
        {
            sprintf(buf, "%s-%s", grpn[0], grpn[i+1]);
            leg[i] = strdup(buf);
        }
        xvgr_legend(dist, ng-1, (const char**)leg, oenv);
        if (num)
        {
            xvgr_legend(num, ng-1, (const char**)leg, oenv);
        }
    }

    if (bEachResEachTime)
    {
        sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
        respertime = xvgropen(rfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv);
        xvgr_legend(respertime, ng-1, (const char**)leg, oenv);
        if (bPrintResName)
        {
            fprintf(respertime, "# ");
        }
        for (j = 0; j < nres; j++)
        {
            fprintf(respertime, "%s%d ", *(atoms->resinfo[atoms->atom[index[0][residue[j]]].resind].name), atoms->atom[index[0][residue[j]]].resind);
        }
        fprintf(respertime, "\n");

    }

    j = 0;
    if (nres)
    {
        snew(mindres, ng-1);
        snew(maxdres, ng-1);
        for (i = 1; i < ng; i++)
        {
            snew(mindres[i-1], nres);
            snew(maxdres[i-1], nres);
            for (j = 0; j < nres; j++)
            {
                mindres[i-1][j] = 1e6;
            }
            /* maxdres[*][*] is already 0 */
        }
    }
    bFirst = TRUE;
    do
    {
        if (bSplit && !bFirst && abs(t/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(dist, "&\n");
            if (num)
            {
                fprintf(num, "&\n");
            }
            if (atm)
            {
                fprintf(atm, "&\n");
            }
        }
        fprintf(dist, "%12e", output_env_conv_time(oenv, t));
        if (num)
        {
            fprintf(num, "%12e", output_env_conv_time(oenv, t));
        }

        if (bMat)
        {
            if (ng == 1)
            {
                calc_dist(rcut, bPBC, ePBC, box, x0, gnx[0], gnx[0], index[0], index[0], bGroup,
                          &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                fprintf(dist, "  %12e", bMin ? dmin : dmax);
                if (num)
                {
                    fprintf(num, "  %8d", bMin ? nmin : nmax);
                }
            }
            else
            {
                for (i = 0; (i < ng-1); i++)
                {
                    for (k = i+1; (k < ng); k++)
                    {
                        calc_dist(rcut, bPBC, ePBC, box, x0, gnx[i], gnx[k], index[i], index[k],
                                  bGroup, &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                        fprintf(dist, "  %12e", bMin ? dmin : dmax);
                        if (num)
                        {
                            fprintf(num, "  %8d", bMin ? nmin : nmax);
                        }
                    }
                }
            }
        }
        else
        {
            for (i = 1; (i < ng); i++)
            {
                calc_dist(rcut, bPBC, ePBC, box, x0, gnx[0], gnx[i], index[0], index[i], bGroup,
                          &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2);
                fprintf(dist, "  %12e", bMin ? dmin : dmax);
                if (num)
                {
                    fprintf(num, "  %8d", bMin ? nmin : nmax);
                }
                if (nres)
                {
                    for (j = 0; j < nres; j++)
                    {
                        calc_dist(rcut, bPBC, ePBC, box, x0, residue[j+1]-residue[j], gnx[i],
                                  &(index[0][residue[j]]), index[i], bGroup,
                                  &dmin, &dmax, &nmin, &nmax, &min1r, &min2r, &max1r, &max2r);
                        mindres[i-1][j] = min(mindres[i-1][j], dmin);
                        maxdres[i-1][j] = max(maxdres[i-1][j], dmax);
                    }
                }
            }
        }
        fprintf(dist, "\n");
        if (num)
        {
            fprintf(num, "\n");
        }
        if ( (bMin ? min1 : max1) != -1)
        {
            if (atm)
            {
                fprintf(atm, "%12e  %12d  %12d\n",
                        output_env_conv_time(oenv, t), 1+(bMin ? min1 : max1),
                        1+(bMin ? min2 : max2));
            }
        }

        if (trxout)
        {
            oindex[0] = bMin ? min1 : max1;
            oindex[1] = bMin ? min2 : max2;
            write_trx(trxout, 2, oindex, atoms, i, t, box, x0, NULL, NULL);
        }
        bFirst = FALSE;
        /*dmin should be minimum distance for residue and group*/
        if (bEachResEachTime)
        {
            fprintf(respertime, "%12e", t);
            for (i = 1; i < ng; i++)
            {
                for (j = 0; j < nres; j++)
                {
                    fprintf(respertime, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]);
                    /*reset distances for next time point*/
                    mindres[i-1][j] = 1e6;
                    maxdres[i-1][j] = 0;
                }
            }
            fprintf(respertime, "\n");
        }
    }
    while (read_next_x(oenv, status, &t, x0, box));

    close_trj(status);
    ffclose(dist);
    if (num)
    {
        ffclose(num);
    }
    if (atm)
    {
        ffclose(atm);
    }
    if (trxout)
    {
        close_trx(trxout);
    }

    if (nres && !bEachResEachTime)
    {
        FILE *res;

        sprintf(buf, "%simum Distance", bMin ? "Min" : "Max");
        res = xvgropen(rfile, buf, "Residue (#)", "Distance (nm)", oenv);
        xvgr_legend(res, ng-1, (const char**)leg, oenv);
        for (j = 0; j < nres; j++)
        {
            fprintf(res, "%4d", j+1);
            for (i = 1; i < ng; i++)
            {
                fprintf(res, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]);
            }
            fprintf(res, "\n");
        }
    }

    sfree(x0);
}
示例#14
0
int gmx_filter(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_filter[tt] performs frequency filtering on a trajectory.",
    "The filter shape is cos([GRK]pi[grk] t/A) + 1 from -A to +A, where A is given",
    "by the option [TT]-nf[tt] times the time step in the input trajectory.",
    "This filter reduces fluctuations with period A by 85%, with period",
    "2*A by 50% and with period 3*A by 17% for low-pass filtering.",
    "Both a low-pass and high-pass filtered trajectory can be written.[PAR]",

    "Option [TT]-ol[tt] writes a low-pass filtered trajectory.",
    "A frame is written every [TT]-nf[tt] input frames.",
    "This ratio of filter length and output interval ensures a good",
    "suppression of aliasing of high-frequency motion, which is useful for",
    "making smooth movies. Also averages of properties which are linear",
    "in the coordinates are preserved, since all input frames are weighted",
    "equally in the output.",
    "When all frames are needed, use the [TT]-all[tt] option.[PAR]",

    "Option [TT]-oh[tt] writes a high-pass filtered trajectory.",
    "The high-pass filtered coordinates are added to the coordinates",
    "from the structure file. When using high-pass filtering use [TT]-fit[tt]",
    "or make sure you use a trajectory that has been fitted on",
    "the coordinates in the structure file."
  };
  
  static int nf=10;
  static gmx_bool bNoJump = TRUE,bFit = FALSE,bLowAll = FALSE;
  t_pargs pa[] = {
    { "-nf", FALSE, etINT, {&nf},
      "Sets the filter length as well as the output interval for low-pass filtering" },
    { "-all", FALSE, etBOOL, {&bLowAll},
      "Write all low-pass filtered frames" },
    { "-nojump", FALSE, etBOOL, {&bNoJump},
      "Remove jumps of atoms across the box" },
    { "-fit", FALSE, etBOOL, {&bFit},
      "Fit all frames to a reference structure" }
  };
  const char *topfile,*lowfile,*highfile;
  gmx_bool       bTop=FALSE;
  t_topology top;
  int        ePBC=-1;
  rvec       *xtop;
  matrix     topbox,*box,boxf;
  char       title[256],*grpname;
  int        isize;
  atom_id    *index;
  real       *w_rls=NULL;
  t_trxstatus *in;
  t_trxstatus *outl,*outh;
  int        nffr,i,fr,nat,j,d,m;
  atom_id    *ind;
  real       flen,*filt,sum,*t;
  rvec       xcmtop,xcm,**x,*ptr,*xf,*xn,*xp,hbox;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;

#define NLEG asize(leg)
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD  }, 
    { efTPS, NULL, NULL, ffOPTRD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efTRO, "-ol", "lowpass",  ffOPTWR }, 
    { efTRO, "-oh", "highpass", ffOPTWR } 
  }; 
#define NFILE asize(fnm) 

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 

  highfile = opt2fn_null("-oh",NFILE,fnm);
  if (highfile) {
    topfile = ftp2fn(efTPS,NFILE,fnm);
    lowfile = opt2fn_null("-ol",NFILE,fnm);
  } else {
    topfile = ftp2fn_null(efTPS,NFILE,fnm);
    lowfile = opt2fn("-ol",NFILE,fnm);
  }
  if (topfile) {
    bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,
			 &xtop,NULL,topbox,TRUE);
    if (bTop) {
      gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,topbox);
      gmx_rmpbc(gpbc,top.atoms.nr,topbox,xtop);
    }
  }

  clear_rvec(xcmtop);
  if (bFit) {
    fprintf(stderr,"Select group for least squares fit\n");
    get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
    /* Set the weight */
    snew(w_rls,top.atoms.nr);
    for(i=0; i<isize; i++) 
      w_rls[index[i]] = top.atoms.atom[index[i]].m;
    calc_xcm(xtop,isize,index,top.atoms.atom,xcmtop,FALSE);
    for(j=0; j<top.atoms.nr; j++)
      rvec_dec(xtop[j],xcmtop);
  }

  /* The actual filter length flen can actually be any real number */
  flen = 2*nf;
  /* nffr is the number of frames that we filter over */
  nffr = 2*nf - 1;
  snew(filt,nffr);
  sum = 0;
  for(i=0; i<nffr; i++) {
    filt[i] = cos(2*M_PI*(i - nf + 1)/(real)flen) + 1;
    sum += filt[i];
  }
  fprintf(stdout,"filter weights:");
  for(i=0; i<nffr; i++) {
    filt[i] /= sum;
    fprintf(stdout," %5.3f",filt[i]);
  }
  fprintf(stdout,"\n");
  
  snew(t,nffr);
  snew(x,nffr);
  snew(box,nffr);

  nat = read_first_x(oenv,&in,opt2fn("-f",NFILE,fnm),
		     &(t[nffr - 1]),&(x[nffr - 1]),box[nffr - 1]);
  snew(ind,nat);
  for(i=0; i<nat; i++)
    ind[i] = i;
  /* x[nffr - 1] was already allocated by read_first_x */
  for(i=0; i<nffr-1; i++)
    snew(x[i],nat);
  snew(xf,nat);
  if (lowfile)
    outl = open_trx(lowfile,"w");
  else
    outl = 0;
  if (highfile)
    outh = open_trx(highfile,"w");
  else
    outh = 0;

  fr = 0;
  do {
    xn = x[nffr - 1];
    if (bNoJump && fr > 0) {
      xp = x[nffr - 2];
      for(j=0; j<nat; j++)
	for(d=0; d<DIM; d++)
	  hbox[d] = 0.5*box[nffr - 1][d][d];
      for(i=0; i<nat; i++)
	for(m=DIM-1; m>=0; m--)
	  if (hbox[m] > 0) {
	    while (xn[i][m] - xp[i][m] <= -hbox[m])
	      for(d=0; d<=m; d++)
		xn[i][d] += box[nffr - 1][m][d];
	    while (xn[i][m] - xp[i][m] > hbox[m])
	      for(d=0; d<=m; d++)
		xn[i][d] -= box[nffr - 1][m][d];
	  }
    }
    if (bTop) {
      gmx_rmpbc(gpbc,nat,box[nffr - 1],xn);
    }
    if (bFit) {
      calc_xcm(xn,isize,index,top.atoms.atom,xcm,FALSE);
      for(j=0; j<nat; j++)
	rvec_dec(xn[j],xcm);
      do_fit(nat,w_rls,xtop,xn);
      for(j=0; j<nat; j++)
	rvec_inc(xn[j],xcmtop);
    }
    if (fr >= nffr && (outh || bLowAll || fr % nf == nf - 1)) {
      /* Lowpass filtering */
      for(j=0; j<nat; j++)
	clear_rvec(xf[j]);
      clear_mat(boxf);
      for(i=0; i<nffr; i++) {
	for(j=0; j<nat; j++)
	  for(d=0; d<DIM; d++)
	    xf[j][d] += filt[i]*x[i][j][d];
	for(j=0; j<DIM; j++)
	  for(d=0; d<DIM; d++)
	    boxf[j][d] += filt[i]*box[i][j][d];
      }
      if (outl && (bLowAll || fr % nf == nf - 1))
	write_trx(outl,nat,ind,topfile ? &(top.atoms) : NULL,
		  0,t[nf - 1],bFit ? topbox : boxf,xf,NULL,NULL);
      if (outh) {
	/* Highpass filtering */
	for(j=0; j<nat; j++)
	  for(d=0; d<DIM; d++)
	    xf[j][d] = xtop[j][d] + x[nf - 1][j][d] - xf[j][d];
	if (bFit)
	  for(j=0; j<nat; j++)
	    rvec_inc(xf[j],xcmtop);
	for(j=0; j<DIM; j++)
	  for(d=0; d<DIM; d++)
	    boxf[j][d] = topbox[j][d] + box[nf - 1][j][d] - boxf[j][d];
	write_trx(outh,nat,ind,topfile ? &(top.atoms) : NULL,
		  0,t[nf - 1],bFit ? topbox : boxf,xf,NULL,NULL);
      }
    }
    /* Cycle all the pointer and the box by one */
    ptr = x[0];
    for(i=0; i<nffr-1; i++) {
      t[i] = t[i+1];
      x[i] = x[i+1];
      copy_mat(box[i+1],box[i]);
    }
    x[nffr - 1] = ptr;
    fr++;
  } while (read_next_x(oenv,in,&(t[nffr - 1]),nat,x[nffr - 1],box[nffr - 1]));
  
  if (bTop)
    gmx_rmpbc_done(gpbc);

  if (outh)
    close_trx(outh);
  if (outl)
    close_trx(outl);
  close_trx(in);
  
  return 0;
}
int main (int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_protonate[tt] reads (a) conformation(s) and adds all missing",
        "hydrogens as defined in [TT]gmx2.ff/aminoacids.hdb[tt]. If only [TT]-s[tt] is",
        "specified, this conformation will be protonated, if also [TT]-f[tt]",
        "is specified, the conformation(s) will be read from this file, ",
        "which can be either a single conformation or a trajectory.",
        "[PAR]",
        "If a [TT].pdb[tt] file is supplied, residue names might not correspond to",
        "to the GROMACS naming conventions, in which case these residues will",
        "probably not be properly protonated.",
        "[PAR]",
        "If an index file is specified, please note that the atom numbers",
        "should correspond to the [BB]protonated[bb] state."
    };

    char        title[STRLEN+1];
    const char  *infile;
    char        *grpnm;
    t_topology  top;
    int         ePBC;
    t_atoms     *atoms,*iatoms;
    t_protonate protdata;
    atom_id     *index;
    t_trxstatus *status;
    t_trxstatus *out;
    t_trxframe  fr,frout;
    rvec        *x,*ix;
    int         nidx,natoms,natoms_out;
    matrix      box;
    int         i,frame,resind;
    gmx_bool        bReadMultiple;
    output_env_t oenv;

    const char *bugs[] = {
        "For the moment, only .pdb files are accepted to the -s flag"
    };

    t_filenm fnm[] = {
        { efTPS, NULL, NULL,         ffREAD  },
        { efTRX, "-f", NULL,         ffOPTRD },
        { efNDX, NULL, NULL,         ffOPTRD },
        { efTRO, "-o", "protonated", ffWRITE }
    };
#define NFILE asize(fnm)

    CopyRight(stderr,argv[0]);
    parse_common_args(&argc,argv,PCA_CAN_TIME,
                      NFILE,fnm,0,NULL,asize(desc),desc,asize(bugs),bugs,&oenv);

    infile=opt2fn("-s",NFILE,fnm);
    read_tps_conf(infile,title,&top,&ePBC,&x,NULL,box,FALSE);
    atoms=&(top.atoms);
    printf("Select group to process:\n");
    get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&nidx,&index,&grpnm);
    bReadMultiple = opt2bSet("-f",NFILE,fnm);
    if (bReadMultiple) {
        infile = opt2fn("-f",NFILE,fnm);
        if ( !read_first_frame(oenv,&status, infile, &fr, TRX_NEED_X ) ) {
            gmx_fatal(FARGS,"cannot read coordinate file %s",infile);
        }
        natoms = fr.natoms;
    } else {
        clear_trxframe(&fr,TRUE);
        fr.natoms = atoms->nr;
        fr.bTitle = TRUE;
        fr.title  = title;
        fr.bX     = TRUE;
        fr.x      = x;
        fr.bBox   = TRUE;
        copy_mat(box, fr.box);
        natoms = fr.natoms;
    }

    /* check input */
    if ( natoms == 0 ) {
        gmx_fatal(FARGS,"no atoms in coordinate file %s",infile);
    }

    if ( natoms > atoms->nr ) {
        gmx_fatal(FARGS,"topology with %d atoms does not match "
                  "coordinates with %d atoms",atoms->nr,natoms);
    }

    for(i=0; i<nidx; i++) {
        if (index[i] > natoms) {
            gmx_fatal(FARGS,"An atom number in group %s is larger than the number of "
                      "atoms (%d) in the coordinate file %s",grpnm,natoms,infile);
        }
    }

    /* get indexed copy of atoms */
    snew(iatoms,1);
    init_t_atoms(iatoms,nidx,FALSE);
    snew(iatoms->atom, iatoms->nr);
    resind = 0;
    for(i=0; i<nidx; i++) {
        iatoms->atom[i] = atoms->atom[index[i]];
        iatoms->atomname[i] = atoms->atomname[index[i]];
        if ( i>0 && (atoms->atom[index[i]].resind!=atoms->atom[index[i-1]].resind) ) {
            resind++;
        }
        iatoms->atom[i].resind = resind;
        iatoms->resinfo[resind] = atoms->resinfo[atoms->atom[index[i]].resind];
        /* allocate some space for the rtp name and copy from name */
        snew(iatoms->resinfo[resind].rtp,1);
        *iatoms->resinfo[resind].rtp = gmx_strdup(*atoms->resinfo[resind].name);

        iatoms->nres = max(iatoms->nres, iatoms->atom[i].resind+1);
    }

    init_t_protonate(&protdata);

    out = open_trx(opt2fn("-o",NFILE,fnm),"w");
    snew(ix, nidx);
    frame=0;
    do {
        if (debug) {
            fprintf(debug,"FRAME %d (%d %g)\n",frame,fr.step,fr.time);
        }
        /* get indexed copy of x */
        for(i=0; i<nidx; i++) {
            copy_rvec(fr.x[index[i]], ix[i]);
        }
        /* protonate */
        natoms_out = protonate(&iatoms, &ix, &protdata);

        /* setup output frame */
        frout = fr;
        frout.natoms = natoms_out;
        frout.bAtoms = TRUE;
        frout.atoms  = iatoms;
        frout.bV     = FALSE;
        frout.bF     = FALSE;
        frout.x      = ix;

        /* write output */
        write_trxframe(out,&frout,NULL);
        frame++;
    } while ( bReadMultiple && read_next_frame(oenv,status, &fr) );

    sfree(ix);
    sfree(iatoms);

    thanx(stderr);

    return 0;
}
int gmx_morph(int argc, char *argv[])
{
    const char      *desc[] = {
        "[THISMODULE] does a linear interpolation of conformations in order to",
        "create intermediates. Of course these are completely unphysical, but",
        "that you may try to justify yourself. Output is in the form of a ",
        "generic trajectory. The number of intermediates can be controlled with",
        "the [TT]-ninterm[tt] flag. The first and last flag correspond to the way of",
        "interpolating: 0 corresponds to input structure 1 while",
        "1 corresponds to input structure 2.",
        "If you specify [TT]-first[tt] < 0 or [TT]-last[tt] > 1 extrapolation will be",
        "on the path from input structure x[SUB]1[sub] to x[SUB]2[sub]. In general, the coordinates",
        "of the intermediate x(i) out of N total intermediates correspond to:[PAR]",
        "x(i) = x[SUB]1[sub] + (first+(i/(N-1))*(last-first))*(x[SUB]2[sub]-x[SUB]1[sub])[PAR]",
        "Finally the RMSD with respect to both input structures can be computed",
        "if explicitly selected ([TT]-or[tt] option). In that case, an index file may be",
        "read to select the group from which the RMS is computed."
    };
    t_filenm         fnm[] = {
        { efSTX, "-f1", "conf1",  ffREAD },
        { efSTX, "-f2", "conf2",  ffREAD },
        { efTRX, "-o",  "interm", ffWRITE },
        { efXVG, "-or", "rms-interm", ffOPTWR },
        { efNDX, "-n",  "index",  ffOPTRD }
    };
#define NFILE asize(fnm)
    static  int      ninterm = 11;
    static  real     first   = 0.0;
    static  real     last    = 1.0;
    static  gmx_bool bFit    = TRUE;
    t_pargs          pa []   = {
        { "-ninterm", FALSE, etINT,  {&ninterm},
          "Number of intermediates" },
        { "-first",   FALSE, etREAL, {&first},
          "Corresponds to first generated structure (0 is input x[SUB]1[sub], see above)" },
        { "-last",    FALSE, etREAL, {&last},
          "Corresponds to last generated structure (1 is input x[SUB]2[sub], see above)" },
        { "-fit",     FALSE, etBOOL, {&bFit},
          "Do a least squares fit of the second to the first structure before interpolating" }
    };
    const char      *leg[] = { "Ref = 1\\Sst\\N conf", "Ref = 2\\Snd\\N conf" };
    FILE            *fp    = NULL;
    int              i, isize, is_lsq, nat1, nat2;
    t_trxstatus     *status;
    atom_id         *index, *index_lsq, *index_all, *dummy;
    t_atoms          atoms;
    rvec            *x1, *x2, *xx, *v;
    matrix           box;
    real             rms1, rms2, fac, *mass;
    char             title[STRLEN], *grpname;
    gmx_bool         bRMS;
    output_env_t     oenv;

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc,
                           0, NULL, &oenv))
    {
        return 0;
    }
    get_stx_coordnum (opt2fn("-f1", NFILE, fnm), &nat1);
    get_stx_coordnum (opt2fn("-f2", NFILE, fnm), &nat2);
    if (nat1 != nat2)
    {
        gmx_fatal(FARGS, "Number of atoms in first structure is %d, in second %d",
                  nat1, nat2);
    }

    init_t_atoms(&atoms, nat1, TRUE);
    snew(x1, nat1);
    snew(x2, nat1);
    snew(xx, nat1);
    snew(v, nat1);

    read_stx_conf(opt2fn("-f1", NFILE, fnm), title, &atoms, x1, v, NULL, box);
    read_stx_conf(opt2fn("-f2", NFILE, fnm), title, &atoms, x2, v, NULL, box);

    snew(mass, nat1);
    snew(index_all, nat1);
    for (i = 0; (i < nat1); i++)
    {
        mass[i]      = 1;
        index_all[i] = i;
    }
    if (bFit)
    {
        printf("Select group for LSQ superposition:\n");
        get_index(&atoms, opt2fn_null("-n", NFILE, fnm), 1, &is_lsq, &index_lsq,
                  &grpname);
        reset_x(is_lsq, index_lsq, nat1, index_all, x1, mass);
        reset_x(is_lsq, index_lsq, nat1, index_all, x2, mass);
        do_fit(nat1, mass, x1, x2);
    }

    bRMS = opt2bSet("-or", NFILE, fnm);
    if (bRMS)
    {
        fp = xvgropen(opt2fn("-or", NFILE, fnm), "RMSD", "Conf", "(nm)", oenv);
        xvgr_legend(fp, asize(leg), leg, oenv);
        printf("Select group for RMSD calculation:\n");
        get_index(&atoms, opt2fn_null("-n", NFILE, fnm), 1, &isize, &index, &grpname);
        printf("You selected group %s, containing %d atoms\n", grpname, isize);
        rms1 = rmsdev_ind(isize, index, mass, x1, x2);
        fprintf(stderr, "RMSD between input conformations is %g nm\n", rms1);
    }

    snew(dummy, nat1);
    for (i = 0; (i < nat1); i++)
    {
        dummy[i] = i;
    }
    status = open_trx(ftp2fn(efTRX, NFILE, fnm), "w");

    for (i = 0; (i < ninterm); i++)
    {
        fac = dointerp(nat1, x1, x2, xx, i, ninterm, first, last);
        write_trx(status, nat1, dummy, &atoms, i, fac, box, xx, NULL, NULL);
        if (bRMS)
        {
            rms1 = rmsdev_ind(isize, index, mass, x1, xx);
            rms2 = rmsdev_ind(isize, index, mass, x2, xx);
            fprintf(fp, "%10g  %10g  %10g\n", fac, rms1, rms2);
        }
    }

    close_trx(status);

    if (bRMS)
    {
        gmx_ffclose(fp);
        do_view(oenv, opt2fn("-or", NFILE, fnm), "-nxy");
    }

    return 0;
}
示例#17
0
int main(int argc,char *argv[])
{
    const char *desc[] = {
	"[TT]do_multiprot[tt] ", 
	"reads a trajectory file and aligns it to a reference structure  ",
	"each time frame",
	"calling the multiprot program. This allows you to use a reference",
	"structure whose sequence is different than that of the protein in the ",
	"trajectory, since the alignment is based on the geometry, not sequence.",
	"The output of [TT]do_multiprot[tt] includes the rmsd and the number of residues",
	"on which it was calculated.",
	"[PAR]",
	"An aligned trajectory file is generated with the [TT]-ox[tt] option.[PAR]",
	"With the [TT]-cr[tt] option, the number of hits in the alignment is given",
	"per residue. This number can be between 0 and the number of frames, and",
	"indicates the structural conservation of this residue.[PAR]",
	"If you do not have the [TT]multiprot[tt] program, get it. [TT]do_multiprot[tt] assumes", 
	"that the [TT]multiprot[tt] executable is [TT]/usr/local/bin/multiprot[tt]. If this is ",
	"not the case, then you should set an environment variable [BB]MULTIPROT[bb]", 
	"pointing to the [TT]multiprot[tt] executable, e.g.: [PAR]",
	"[TT]setenv MULTIPROT /usr/MultiProtInstall/multiprot.Linux[tt][PAR]",
	"Note that at the current implementation only binary alignment (your",
	"molecule to a reference) is supported. In addition, note that the ",
	"by default [TT]multiprot[tt] aligns the two proteins on their C-alpha carbons.",
	"and that this depends on the [TT]multiprot[tt] parameters which are not dealt ",
	"with here. Thus, the C-alpha carbons is expected to give the same "
	"results as choosing the whole protein and will be slightly faster.[PAR]",
	"For information about [TT]multiprot[tt], see:",
	"http://bioinfo3d.cs.tau.ac.il/MultiProt/.[PAR]"
    };
    static bool bVerbose;
    t_pargs pa[] = {
	{ "-v",  FALSE, etBOOL, {&bVerbose},
	  "HIDDENGenerate miles of useless information" }
    };
  
    const char *bugs[] = { 
	"The program is very slow, since multiprot is run externally"
    };
  
    t_trxstatus *status;
    t_trxstatus *trxout=NULL;
    FILE        *tapein,*fo,*frc,*tmpf,*out=NULL,*fres=NULL;
    const char  *fnRef;
    const char  *fn="2_sol.res";
    t_topology  top;
    int         ePBC;
    t_atoms     *atoms,ratoms,useatoms;
    t_trxframe  fr;
    t_pdbinfo   p;
    int         nres,nres2,nr0;
    real        t;
    int         i,j,natoms,nratoms,nframe=0,model_nr=-1;
    int         cur_res,prev_res;
    int         nout;
    t_countres  *countres=NULL;
    matrix      box,rbox;
    int         gnx;
    char        *grpnm,*ss_str; 
    atom_id     *index;
    rvec        *xp,*x,*xr;
    char        pdbfile[32],refpdb[256],title[256],rtitle[256],filemode[5];
    char        out_title[256];
    char        multiprot[256],*mptr;
    int         ftp;
    int         outftp=-1;
    real        rmsd;
    bool        bTrjout,bCountres;
    const char  *TrjoutFile=NULL;
    output_env_t oenv;
    static rvec translation={0,0,0},rotangles={0,0,0};
    gmx_rmpbc_t gpbc=NULL;
    
    t_filenm   fnm[] = {
	{ efTRX, "-f",   NULL,      ffREAD },
	{ efTPS, NULL,   NULL,      ffREAD },
	{ efNDX, NULL,   NULL,      ffOPTRD },
	{ efSTX, "-r",   NULL     , ffREAD },
	{ efXVG, "-o",  "rmss",     ffWRITE },
	{ efXVG, "-rc", "rescount", ffWRITE},
	{ efXVG, "-cr", "countres", ffOPTWR},
	{ efTRX, "-ox", "aligned",  ffOPTWR }
    };
#define NFILE asize(fnm)
    
    CopyRight(stderr,argv[0]);
    parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT,
		      NFILE,fnm, asize(pa),pa, asize(desc),desc,
		      asize(bugs),bugs,&oenv
	);
    fnRef=opt2fn("-r",NFILE,fnm);
    bTrjout = opt2bSet("-ox",NFILE,fnm);
    bCountres=  opt2bSet("-cr",NFILE,fnm);
    
    if (bTrjout) {
	TrjoutFile = opt2fn_null("-ox",NFILE,fnm);
    }
    
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xp,NULL,box,FALSE);
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,box);
    atoms=&(top.atoms);

    ftp=fn2ftp(fnRef);
 
    get_stx_coordnum(fnRef,&nratoms);
    init_t_atoms(&ratoms,nratoms,TRUE);  
    snew(xr,nratoms);
    read_stx_conf(fnRef,rtitle,&ratoms,xr,NULL,&ePBC,rbox);
    
    if (bVerbose) {
	fprintf(stderr,"Read %d atoms\n",atoms->nr); 
	fprintf(stderr,"Read %d reference atoms\n",ratoms.nr); 
    }
    if (bCountres) {
	snew(countres,ratoms.nres);
	j=0;
	cur_res=0;
	for (i=0;i<ratoms.nr;i++) {
	    prev_res=cur_res;
	    cur_res=ratoms.atom[i].resind;
	    if (cur_res != prev_res) {
		countres[j].resnr=cur_res;
		countres[j].count=0;
		j++;
	    }
	}
    }
    get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpnm);
    nres=0;
    nr0=-1;
    for(i=0; (i<gnx); i++) {
	if (atoms->atom[index[i]].resind != nr0) {
	    nr0=atoms->atom[index[i]].resind;
	    nres++;
	}
    }
    fprintf(stderr,"There are %d residues in your selected group\n",nres);
    
    strcpy(pdbfile,"ddXXXXXX");
    gmx_tmpnam(pdbfile);
    if ((tmpf = fopen(pdbfile,"w")) == NULL) {
	sprintf(pdbfile,"%ctmp%cfilterXXXXXX",DIR_SEPARATOR,DIR_SEPARATOR);
	gmx_tmpnam(pdbfile);
	if ((tmpf = fopen(pdbfile,"w")) == NULL) {
	    gmx_fatal(FARGS,"Can not open tmp file %s",pdbfile);
	}
    }
    else {
	gmx_ffclose(tmpf);
    }

    if (ftp != efPDB) {
	strcpy(refpdb,"ddXXXXXX");
	gmx_tmpnam(refpdb);
	strcat(refpdb,".pdb");
	write_sto_conf(refpdb,rtitle,&ratoms,xr,NULL,ePBC,rbox);
    }
    else {
	strcpy(refpdb,fnRef);
    }

    if ((mptr=getenv("MULTIPROT")) == NULL) {
	mptr="/usr/local/bin/multiprot";
    }
    if (!gmx_fexist(mptr)) {
	gmx_fatal(FARGS,"MULTIPROT executable (%s) does not exist (use setenv MULTIPROT)",
		  mptr);
    }
    sprintf (multiprot,"%s %s %s > /dev/null %s",
	     mptr, refpdb, pdbfile, "2> /dev/null");
    
    if (bVerbose)
	fprintf(stderr,"multiprot cmd='%s'\n",multiprot);
    
    if (!read_first_frame(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_READ_X)) 
      	gmx_fatal(FARGS,"Could not read a frame from %s",ftp2fn(efTRX,NFILE,fnm));
    natoms = fr.natoms;

    if (bTrjout) {
	nout=natoms;
	/* open file now */
	outftp=fn2ftp(TrjoutFile);
	if (bVerbose)
	    fprintf(stderr,"Will write %s: %s\n",ftp2ext(ftp),ftp2desc(outftp));
	strcpy(filemode,"w");
	switch (outftp) {
	    case efXTC:
	    case efG87:
	    case efTRR:
	    case efTRJ:
		out=NULL;
		trxout = open_trx(TrjoutFile,filemode);
		break;
	    case efGRO:
	    case efG96:
	    case efPDB:
		/* Make atoms struct for output in GRO or PDB files */
		/* get memory for stuff to go in pdb file */
		init_t_atoms(&useatoms,nout,FALSE);
		sfree(useatoms.resinfo);
		useatoms.resinfo=atoms->resinfo;
		for(i=0;(i<nout);i++) {
		    useatoms.atomname[i]=atoms->atomname[i];
		    useatoms.atom[i]=atoms->atom[i];
		    useatoms.nres=max(useatoms.nres,useatoms.atom[i].resind+1);
		}
		useatoms.nr=nout;
		out=gmx_ffopen(TrjoutFile,filemode);
		break;
	}
    }
    
    if (natoms > atoms->nr) {
	gmx_fatal(FARGS,"\nTrajectory does not match topology!");
    }
    if (gnx > natoms) {
	gmx_fatal(FARGS,"\nTrajectory does not match selected group!");
    }

    fo = xvgropen(opt2fn("-o",NFILE,fnm),"RMSD","Time (ps)","RMSD (nm)",oenv);
    frc = xvgropen(opt2fn("-rc",NFILE,fnm),"Number of Residues in the alignment","Time (ps)","Residues",oenv);
    
    do {
	t = output_env_conv_time(oenv,fr.time);
	gmx_rmpbc(gpbc,natoms,fr.box,fr.x);
	tapein=gmx_ffopen(pdbfile,"w");
	write_pdbfile_indexed(tapein,NULL,atoms,fr.x,ePBC,fr.box,' ',-1,gnx,index,NULL,TRUE); 
	gmx_ffclose(tapein);
	system(multiprot);
	remove(pdbfile);
	process_multiprot_output(fn, &rmsd, &nres2,rotangles,translation,bCountres,countres);
	fprintf(fo,"%12.7f",t);
	fprintf(fo," %12.7f\n",rmsd);
	fprintf(frc,"%12.7f",t);
	fprintf(frc,"%12d\n",nres2);
	if (bTrjout) {
	    rotate_conf(natoms,fr.x,NULL,rotangles[XX],rotangles[YY],rotangles[ZZ]);
	    for(i=0; i<natoms; i++) {
		rvec_inc(fr.x[i],translation);
	    }
	    switch(outftp) {
		case efTRJ:
		case efTRR:
		case efG87:
		case efXTC:
		    write_trxframe(trxout,&fr,NULL);
		    break;
		case efGRO:
		case efG96:
		case efPDB:
		    sprintf(out_title,"Generated by do_multiprot : %s t= %g %s",
			    title,output_env_conv_time(oenv,fr.time),output_env_get_time_unit(oenv));
		    switch(outftp) {
			case efGRO: 
			    write_hconf_p(out,out_title,&useatoms,prec2ndec(fr.prec),
					  fr.x,NULL,fr.box);
			    break;
			case efPDB:
			    fprintf(out,"REMARK    GENERATED BY DO_MULTIPROT\n");
			    sprintf(out_title,"%s t= %g %s",title,output_env_conv_time(oenv,fr.time),output_env_get_time_unit(oenv));
			    /* if reading from pdb, we want to keep the original 
			       model numbering else we write the output frame
			       number plus one, because model 0 is not allowed in pdb */
			    if (ftp==efPDB && fr.step > model_nr) {
				model_nr = fr.step;
			    }
			    else {
				model_nr++;
			    }
			    write_pdbfile(out,out_title,&useatoms,fr.x,ePBC,fr.box,' ',model_nr,NULL,TRUE);
			    break;
			case efG96:
			    fr.title = out_title;
			    fr.bTitle = (nframe == 0);
			    fr.bAtoms = FALSE;
			    fr.bStep = TRUE;
			    fr.bTime = TRUE;
			    write_g96_conf(out,&fr,-1,NULL);
		    }
		    break;
	    }
	}
	nframe++;
    } while(read_next_frame(oenv,status,&fr));
    if (bCountres) {
	fres=  xvgropen(opt2fn("-cr",NFILE,fnm),"Number of frames in which the residues are aligned to","Residue","Number",oenv);
	for (i=0;i<ratoms.nres;i++) {
	    fprintf(fres,"%10d  %12d\n",countres[i].resnr,countres[i].count);
	}
	gmx_ffclose(fres);
    }
    gmx_ffclose(fo);
    gmx_ffclose(frc);
    fprintf(stderr,"\n");
    close_trj(status);
    if (trxout != NULL) {
	close_trx(trxout);
    }
    else if (out != NULL) {
	gmx_ffclose(out);
    }
    view_all(oenv,NFILE, fnm);
    sfree(xr);
    if (bCountres) {
	sfree(countres);
    }
    free_t_atoms(&ratoms,TRUE);
    if (bTrjout) {
	if (outftp==efPDB || outftp==efGRO || outftp==efG96) {
	    free_t_atoms(&useatoms,TRUE);
	}
    }
    gmx_thanx(stderr);
    return 0;
}
示例#18
0
int gmx_traj(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] plots coordinates, velocities, forces and/or the box.",
        "With [TT]-com[tt] the coordinates, velocities and forces are",
        "calculated for the center of mass of each group.",
        "When [TT]-mol[tt] is set, the numbers in the index file are",
        "interpreted as molecule numbers and the same procedure as with",
        "[TT]-com[tt] is used for each molecule.[PAR]",
        "Option [TT]-ot[tt] plots the temperature of each group,",
        "provided velocities are present in the trajectory file.",
        "No corrections are made for constrained degrees of freedom!",
        "This implies [TT]-com[tt].[PAR]",
        "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and",
        "rotational kinetic energy of each group,",
        "provided velocities are present in the trajectory file.",
        "This implies [TT]-com[tt].[PAR]",
        "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities",
        "and average forces as temperature factors to a [REF].pdb[ref] file with",
        "the average coordinates or the coordinates at [TT]-ctime[tt].",
        "The temperature factors are scaled such that the maximum is 10.",
        "The scaling can be changed with the option [TT]-scale[tt].",
        "To get the velocities or forces of one",
        "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of",
        "desired frame. When averaging over frames you might need to use",
        "the [TT]-nojump[tt] option to obtain the correct average coordinates.",
        "If you select either of these option the average force and velocity",
        "for each atom are written to an [REF].xvg[ref] file as well",
        "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]",
        "Option [TT]-vd[tt] computes a velocity distribution, i.e. the",
        "norm of the vector is plotted. In addition in the same graph",
        "the kinetic energy distribution is given."
    };
    static gmx_bool   bMol    = FALSE, bCom = FALSE, bPBC = TRUE, bNoJump = FALSE;
    static gmx_bool   bX      = TRUE, bY = TRUE, bZ = TRUE, bNorm = FALSE, bFP = FALSE;
    static int        ngroups = 1;
    static real       ctime   = -1, scale = 0, binwidth = 1;
    t_pargs           pa[]    = {
        { "-com", FALSE, etBOOL, {&bCom},
          "Plot data for the com of each group" },
        { "-pbc", FALSE, etBOOL, {&bPBC},
          "Make molecules whole for COM" },
        { "-mol", FALSE, etBOOL, {&bMol},
          "Index contains molecule numbers iso atom numbers" },
        { "-nojump", FALSE, etBOOL, {&bNoJump},
          "Remove jumps of atoms across the box" },
        { "-x", FALSE, etBOOL, {&bX},
          "Plot X-component" },
        { "-y", FALSE, etBOOL, {&bY},
          "Plot Y-component" },
        { "-z", FALSE, etBOOL, {&bZ},
          "Plot Z-component" },
        { "-ng",       FALSE, etINT, {&ngroups},
          "Number of groups to consider" },
        { "-len", FALSE, etBOOL, {&bNorm},
          "Plot vector length" },
        { "-fp", FALSE, etBOOL, {&bFP},
          "Full precision output" },
        { "-bin", FALSE, etREAL, {&binwidth},
          "Binwidth for velocity histogram (nm/ps)" },
        { "-ctime", FALSE, etREAL, {&ctime},
          "Use frame at this time for x in [TT]-cv[tt] and [TT]-cf[tt] instead of the average x" },
        { "-scale", FALSE, etREAL, {&scale},
          "Scale factor for [REF].pdb[ref] output, 0 is autoscale" }
    };
    FILE             *outx   = NULL, *outv = NULL, *outf = NULL, *outb = NULL, *outt = NULL;
    FILE             *outekt = NULL, *outekr = NULL;
    t_topology        top;
    int               ePBC;
    real             *mass, time;
    const char       *indexfn;
    t_trxframe        fr, frout;
    int               flags, nvhisto = 0, *vhisto = NULL;
    rvec             *xtop, *xp = NULL;
    rvec             *sumx = NULL, *sumv = NULL, *sumf = NULL;
    matrix            topbox;
    t_trxstatus      *status;
    t_trxstatus      *status_out = NULL;
    gmx_rmpbc_t       gpbc       = NULL;
    int               i, j;
    int               nr_xfr, nr_vfr, nr_ffr;
    char            **grpname;
    int              *isize0, *isize;
    int             **index0, **index;
    int              *atndx;
    t_block          *mols;
    gmx_bool          bTop, bOX, bOXT, bOV, bOF, bOB, bOT, bEKT, bEKR, bCV, bCF;
    gmx_bool          bDim[4], bDum[4], bVD;
    char              sffmt[STRLEN], sffmt6[STRLEN];
    const char       *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" };
    gmx_output_env_t *oenv;

    t_filenm          fnm[] = {
        { efTRX, "-f", NULL, ffREAD },
        { efTPS, NULL, NULL, ffREAD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efXVG, "-ox",  "coord",     ffOPTWR },
        { efTRX, "-oxt", "coord",     ffOPTWR },
        { efXVG, "-ov",  "veloc",     ffOPTWR },
        { efXVG, "-of",  "force",     ffOPTWR },
        { efXVG, "-ob",  "box",       ffOPTWR },
        { efXVG, "-ot",  "temp",      ffOPTWR },
        { efXVG, "-ekt", "ektrans",   ffOPTWR },
        { efXVG, "-ekr", "ekrot",     ffOPTWR },
        { efXVG, "-vd",  "veldist",   ffOPTWR },
        { efPDB, "-cv",  "veloc",     ffOPTWR },
        { efPDB, "-cf",  "force",     ffOPTWR },
        { efXVG, "-av",  "all_veloc", ffOPTWR },
        { efXVG, "-af",  "all_force", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv,
                           PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    if (bMol)
    {
        fprintf(stderr, "Interpreting indexfile entries as molecules.\n"
                "Using center of mass.\n");
    }

    bOX  = opt2bSet("-ox", NFILE, fnm);
    bOXT = opt2bSet("-oxt", NFILE, fnm);
    bOV  = opt2bSet("-ov", NFILE, fnm);
    bOF  = opt2bSet("-of", NFILE, fnm);
    bOB  = opt2bSet("-ob", NFILE, fnm);
    bOT  = opt2bSet("-ot", NFILE, fnm);
    bEKT = opt2bSet("-ekt", NFILE, fnm);
    bEKR = opt2bSet("-ekr", NFILE, fnm);
    bCV  = opt2bSet("-cv", NFILE, fnm) || opt2bSet("-av", NFILE, fnm);
    bCF  = opt2bSet("-cf", NFILE, fnm) || opt2bSet("-af", NFILE, fnm);
    bVD  = opt2bSet("-vd", NFILE, fnm) || opt2parg_bSet("-bin", asize(pa), pa);
    if (bMol || bOT || bEKT || bEKR)
    {
        bCom = TRUE;
    }

    bDim[XX]  = bX;
    bDim[YY]  = bY;
    bDim[ZZ]  = bZ;
    bDim[DIM] = bNorm;

    if (bFP)
    {
        sprintf(sffmt, "\t%s", gmx_real_fullprecision_pfmt);
    }
    else
    {
        sprintf(sffmt, "\t%%g");
    }
    sprintf(sffmt6, "%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt);

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC,
                         &xtop, NULL, topbox,
                         bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR));
    sfree(xtop);
    if ((bMol || bCV || bCF) && !bTop)
    {
        gmx_fatal(FARGS, "Need a run input file for option -mol, -cv or -cf");
    }

    if (bMol)
    {
        indexfn = ftp2fn(efNDX, NFILE, fnm);
    }
    else
    {
        indexfn = ftp2fn_null(efNDX, NFILE, fnm);
    }

    if (!(bCom && !bMol))
    {
        ngroups = 1;
    }
    snew(grpname, ngroups);
    snew(isize0, ngroups);
    snew(index0, ngroups);
    get_index(&(top.atoms), indexfn, ngroups, isize0, index0, grpname);

    if (bMol)
    {
        mols    = &(top.mols);
        atndx   = mols->index;
        ngroups = isize0[0];
        snew(isize, ngroups);
        snew(index, ngroups);
        for (i = 0; i < ngroups; i++)
        {
            if (index0[0][i] < 0 || index0[0][i] >= mols->nr)
            {
                gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)",
                          index0[0][i]+1, 1, mols->nr);
            }
            isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]];
            snew(index[i], isize[i]);
            for (j = 0; j < isize[i]; j++)
            {
                index[i][j] = atndx[index0[0][i]] + j;
            }
        }
    }
    else
    {
        isize = isize0;
        index = index0;
    }
    if (bCom)
    {
        snew(mass, top.atoms.nr);
        for (i = 0; i < top.atoms.nr; i++)
        {
            mass[i] = top.atoms.atom[i].m;
        }
    }
    else
    {
        mass = NULL;
    }

    flags = 0;
    if (bOX)
    {
        flags = flags | TRX_READ_X;
        outx  = xvgropen(opt2fn("-ox", NFILE, fnm),
                         bCom ? "Center of mass" : "Coordinate",
                         output_env_get_xvgr_tlabel(oenv), "Coordinate (nm)", oenv);
        make_legend(outx, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
    }
    if (bOXT)
    {
        flags      = flags | TRX_READ_X;
        status_out = open_trx(opt2fn("-oxt", NFILE, fnm), "w");
    }
    if (bOV)
    {
        flags = flags | TRX_READ_V;
        outv  = xvgropen(opt2fn("-ov", NFILE, fnm),
                         bCom ? "Center of mass velocity" : "Velocity",
                         output_env_get_xvgr_tlabel(oenv), "Velocity (nm/ps)", oenv);
        make_legend(outv, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
    }
    if (bOF)
    {
        flags = flags | TRX_READ_F;
        outf  = xvgropen(opt2fn("-of", NFILE, fnm), "Force",
                         output_env_get_xvgr_tlabel(oenv), "Force (kJ mol\\S-1\\N nm\\S-1\\N)",
                         oenv);
        make_legend(outf, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv);
    }
    if (bOB)
    {
        outb = xvgropen(opt2fn("-ob", NFILE, fnm), "Box vector elements",
                        output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);

        xvgr_legend(outb, 6, box_leg, oenv);
    }
    if (bOT)
    {
        bDum[XX]  = FALSE;
        bDum[YY]  = FALSE;
        bDum[ZZ]  = FALSE;
        bDum[DIM] = TRUE;
        flags     = flags | TRX_READ_V;
        outt      = xvgropen(opt2fn("-ot", NFILE, fnm), "Temperature",
                             output_env_get_xvgr_tlabel(oenv), "(K)", oenv);
        make_legend(outt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv);
    }
    if (bEKT)
    {
        bDum[XX]  = FALSE;
        bDum[YY]  = FALSE;
        bDum[ZZ]  = FALSE;
        bDum[DIM] = TRUE;
        flags     = flags | TRX_READ_V;
        outekt    = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation",
                             output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv);
        make_legend(outekt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv);
    }
    if (bEKR)
    {
        bDum[XX]  = FALSE;
        bDum[YY]  = FALSE;
        bDum[ZZ]  = FALSE;
        bDum[DIM] = TRUE;
        flags     = flags | TRX_READ_X | TRX_READ_V;
        outekr    = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation",
                             output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv);
        make_legend(outekr, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv);
    }
    if (bVD)
    {
        flags = flags | TRX_READ_V;
    }
    if (bCV)
    {
        flags = flags | TRX_READ_X | TRX_READ_V;
    }
    if (bCF)
    {
        flags = flags | TRX_READ_X | TRX_READ_F;
    }
    if ((flags == 0) && !bOB)
    {
        fprintf(stderr, "Please select one or more output file options\n");
        exit(0);
    }

    read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);


    if ((bOV || bOF) && fn2ftp(ftp2fn(efTRX, NFILE, fnm)) == efXTC)
    {
        gmx_fatal(FARGS, "Cannot extract velocities or forces since your input XTC file does not contain them.");
    }

    if (bCV || bCF)
    {
        snew(sumx, fr.natoms);
    }
    if (bCV)
    {
        snew(sumv, fr.natoms);
    }
    if (bCF)
    {
        snew(sumf, fr.natoms);
    }
    nr_xfr = 0;
    nr_vfr = 0;
    nr_ffr = 0;

    if (bCom && bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, fr.natoms);
    }

    do
    {
        time = output_env_conv_time(oenv, fr.time);

        if (fr.bX && bNoJump && fr.bBox)
        {
            if (xp)
            {
                remove_jump(fr.box, fr.natoms, xp, fr.x);
            }
            else
            {
                snew(xp, fr.natoms);
            }
            for (i = 0; i < fr.natoms; i++)
            {
                copy_rvec(fr.x[i], xp[i]);
            }
        }

        if (fr.bX && bCom && bPBC)
        {
            gmx_rmpbc_trxfr(gpbc, &fr);
        }

        if (bVD && fr.bV)
        {
            update_histo(isize[0], index[0], fr.v, &nvhisto, &vhisto, binwidth);
        }

        if (bOX && fr.bX)
        {
            print_data(outx, time, fr.x, mass, bCom, ngroups, isize, index, bDim, sffmt);
        }
        if (bOXT && fr.bX)
        {
            frout = fr;
            if (!frout.bAtoms)
            {
                frout.atoms  = &top.atoms;
                frout.bAtoms = TRUE;
            }
            write_trx_x(status_out, &frout, mass, bCom, ngroups, isize, index);
        }
        if (bOV && fr.bV)
        {
            print_data(outv, time, fr.v, mass, bCom, ngroups, isize, index, bDim, sffmt);
        }
        if (bOF && fr.bF)
        {
            print_data(outf, time, fr.f, NULL, bCom, ngroups, isize, index, bDim, sffmt);
        }
        if (bOB && fr.bBox)
        {
            fprintf(outb, "\t%g", fr.time);
            fprintf(outb, sffmt6,
                    fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ],
                    fr.box[YY][XX], fr.box[ZZ][XX], fr.box[ZZ][YY]);
            fprintf(outb, "\n");
        }
        if (bOT && fr.bV)
        {
            fprintf(outt, " %g", time);
            for (i = 0; i < ngroups; i++)
            {
                fprintf(outt, sffmt, temp(fr.v, mass, isize[i], index[i]));
            }
            fprintf(outt, "\n");
        }
        if (bEKT && fr.bV)
        {
            fprintf(outekt, " %g", time);
            for (i = 0; i < ngroups; i++)
            {
                fprintf(outekt, sffmt, ektrans(fr.v, mass, isize[i], index[i]));
            }
            fprintf(outekt, "\n");
        }
        if (bEKR && fr.bX && fr.bV)
        {
            fprintf(outekr, " %g", time);
            for (i = 0; i < ngroups; i++)
            {
                fprintf(outekr, sffmt, ekrot(fr.x, fr.v, mass, isize[i], index[i]));
            }
            fprintf(outekr, "\n");
        }
        if ((bCV || bCF) && fr.bX &&
            (ctime < 0 || (fr.time >= ctime*0.999999 &&
                           fr.time <= ctime*1.000001)))
        {
            for (i = 0; i < fr.natoms; i++)
            {
                rvec_inc(sumx[i], fr.x[i]);
            }
            nr_xfr++;
        }
        if (bCV && fr.bV)
        {
            for (i = 0; i < fr.natoms; i++)
            {
                rvec_inc(sumv[i], fr.v[i]);
            }
            nr_vfr++;
        }
        if (bCF && fr.bF)
        {
            for (i = 0; i < fr.natoms; i++)
            {
                rvec_inc(sumf[i], fr.f[i]);
            }
            nr_ffr++;
        }

    }
    while (read_next_frame(oenv, status, &fr));

    if (gpbc != NULL)
    {
        gmx_rmpbc_done(gpbc);
    }

    /* clean up a bit */
    close_trj(status);

    if (bOX)
    {
        xvgrclose(outx);
    }
    if (bOXT)
    {
        close_trx(status_out);
    }
    if (bOV)
    {
        xvgrclose(outv);
    }
    if (bOF)
    {
        xvgrclose(outf);
    }
    if (bOB)
    {
        xvgrclose(outb);
    }
    if (bOT)
    {
        xvgrclose(outt);
    }
    if (bEKT)
    {
        xvgrclose(outekt);
    }
    if (bEKR)
    {
        xvgrclose(outekr);
    }

    if (bVD)
    {
        print_histo(opt2fn("-vd", NFILE, fnm), nvhisto, vhisto, binwidth, oenv);
    }

    if (bCV || bCF)
    {
        if (nr_xfr > 1)
        {
            if (ePBC != epbcNONE && !bNoJump)
            {
                fprintf(stderr, "\nWARNING: More than one frame was used for option -cv or -cf\n"
                        "If atoms jump across the box you should use the -nojump or -ctime option\n\n");
            }
            for (i = 0; i < isize[0]; i++)
            {
                svmul(1.0/nr_xfr, sumx[index[0][i]], sumx[index[0][i]]);
            }
        }
        else if (nr_xfr == 0)
        {
            fprintf(stderr, "\nWARNING: No coordinate frames found for option -cv or -cf\n\n");
        }
    }
    if (bCV)
    {
        write_pdb_bfac(opt2fn("-cv", NFILE, fnm),
                       opt2fn("-av", NFILE, fnm), "average velocity", &(top.atoms),
                       ePBC, topbox, isize[0], index[0], nr_xfr, sumx,
                       nr_vfr, sumv, bDim, scale, oenv);
    }
    if (bCF)
    {
        write_pdb_bfac(opt2fn("-cf", NFILE, fnm),
                       opt2fn("-af", NFILE, fnm), "average force", &(top.atoms),
                       ePBC, topbox, isize[0], index[0], nr_xfr, sumx,
                       nr_ffr, sumf, bDim, scale, oenv);
    }

    /* view it */
    view_all(oenv, NFILE, fnm);

    return 0;
}
示例#19
0
int gmx_trjcat(int argc,char *argv[])
{
  static char *desc[] = {
      "trjcat concatenates several input trajectory files in sorted order. ",
      "In case of double time frames the one in the later file is used. ",
      "By specifying [TT]-settime[tt] you will be asked for the start time ",
      "of each file. The input files are taken from the command line, ",
      "such that a command like [TT]trjcat -o fixed.trr *.trr[tt] should do ",
      "the trick. Using [TT]-cat[tt] you can simply paste several files ",
      "together without removal of frames with identical time stamps.[PAR]",
      "One important option is inferred when the output file is amongst the",
      "input files. In that case that particular file will be appended to",
      "which implies you do not need to store double the amount of data.",
      "Obviously the file to append to has to be the one with lowest starting",
      "time since one can only append at the end of a file.[PAR]",
      "If the [TT]-demux[tt] option is given, the N trajectories that are",
      "read, are written in another order as specified in the xvg file."
      "The xvg file should contain something like:[PAR]",
      "0  0  1  2  3  4  5[BR]",
      "2  1  0  2  3  5  4[BR]",
      "Where the first number is the time, and subsequent numbers point to",
      "trajectory indices.",
      "The frames corresponding to the numbers present at the first line",
      "are collected into the output trajectory. If the number of frames in",
      "the trajectory does not match that in the xvg file then the program",
      "tries to be smart. Beware."
  };
  static bool  bVels=TRUE;
  static int   prec=3;
  static bool  bCat=FALSE;
  static bool  bSort=TRUE;
  static bool  bKeepLast=FALSE;
  static bool  bSetTime=FALSE;
  static bool  bDeMux;
  static real  begin=-1;
  static real  end=-1;
  static real  dt=0;

  t_pargs pa[] = {
    { "-b",       FALSE, etTIME, {&begin},
      "First time to use (%t)"},
    { "-e",       FALSE, etTIME, {&end},
      "Last time to use (%t)"},
    { "-dt",      FALSE, etTIME, {&dt},
      "Only write frame when t MOD dt = first time (%t)" },
    { "-prec",    FALSE, etINT,  {&prec},
      "Precision for .xtc and .gro writing in number of decimal places" },
    { "-vel",     FALSE, etBOOL, {&bVels},
      "Read and write velocities if possible" },
    { "-settime", FALSE, etBOOL, {&bSetTime}, 
      "Change starting time interactively" },
    { "-sort",    FALSE, etBOOL, {&bSort},
      "Sort trajectory files (not frames)" },
    { "-keeplast",FALSE, etBOOL, {&bKeepLast},
      "keep overlapping frames at end of trajectory" },
    { "-cat",     FALSE, etBOOL, {&bCat},
      "do not discard double time frames" }
  };
#define npargs asize(pa)
  int         status,ftpin,i,frame,frame_out,step=0,trjout=0;
  rvec        *x,*v;
  real        xtcpr,t_corr;
  t_trxframe  fr,frout;
  char        **fnms,**fnms_out,*in_file,*out_file;
  int         n_append;
  int         trxout=-1;
  bool        bNewFile,bIndex,bWrite;
  int         earliersteps,nfile_in,nfile_out,*cont_type,last_ok_step;
  real        *readtime,*timest,*settime;
  real        first_time=0,lasttime=NOTSET,last_ok_t=-1,timestep;
  int         isize,j;
  atom_id     *index=NULL,imax;
  char        *grpname;
  real        **val=NULL,*t=NULL,dt_remd;
  int         n,nset;
  t_filenm fnm[] = {
      { efTRX, "-f",     NULL,      ffRDMULT },
      { efTRO, "-o",     NULL,      ffWRMULT },
      { efNDX, "-n",     "index",   ffOPTRD  },
      { efXVG, "-demux", "remd",    ffOPTRD  }
  };
  
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_BE_NICE|PCA_TIME_UNIT,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,
		    0,NULL);

  bIndex = ftp2bSet(efNDX,NFILE,fnm);
  bDeMux = ftp2bSet(efXVG,NFILE,fnm);
  bSort  = bSort && !bDeMux;
  
  imax=NO_ATID;
  if (bIndex) {
    printf("Select group for output\n");
    rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
    /* scan index */
    imax=index[0];
    for(i=1; i<isize; i++)
      imax = max(imax, index[i]);
  }
  if (bDeMux) {
    nset    = 0;
    dt_remd = 0;
    val=read_xvg_time(opt2fn("-demux",NFILE,fnm),TRUE,
		      opt2parg_bSet("-b",npargs,pa),begin,
		      opt2parg_bSet("-e",npargs,pa),end,
		      1,&nset,&n,&dt_remd,&t);
    printf("Read %d sets of %d points, dt = %g\n\n",nset,n,dt_remd);
    if (debug) {
      fprintf(debug,"Dump of replica_index.xvg\n");
      for(i=0; (i<n); i++) {
	fprintf(debug,"%10g",t[i]);
	for(j=0; (j<nset); j++) {
	  fprintf(debug,"  %3d",gmx_nint(val[j][i]));
	}
	fprintf(debug,"\n");
      }
    }
  }
  /* prec is in nr of decimal places, xtcprec is a multiplication factor: */
  xtcpr=1;
  for (i=0; i<prec; i++)
    xtcpr*=10;
  
  nfile_in = opt2fns(&fnms,"-f",NFILE,fnm);
  if (!nfile_in)
    gmx_fatal(FARGS,"No input files!");
    
  if (bDeMux && (nfile_in != nset)) 
    gmx_fatal(FARGS,"You have specified %d files and %d entries in the demux table",nfile_in,nset);
    
  nfile_out = opt2fns(&fnms_out,"-o",NFILE,fnm);
  if (!nfile_out)
    gmx_fatal(FARGS,"No output files!");
  if ((nfile_out > 1) && !bDeMux) 
    gmx_fatal(FARGS,"Don't know what to do with more than 1 output file if  not demultiplexing");
  else if (bDeMux && (nfile_out != nset) && (nfile_out != 1))
    gmx_fatal(FARGS,"Number of output files should be 1 or %d (#input files), not %d",nset,nfile_out);

  if (bDeMux) {
    if (nfile_out != nset) {
      char *buf = strdup(fnms_out[0]);
      snew(fnms_out,nset);
      for(i=0; (i<nset); i++) {
	snew(fnms_out[i],strlen(buf)+32);
	sprintf(fnms_out[i],"%d_%s",i,buf);
      }
    }
    do_demux(nfile_in,fnms,fnms_out,n,val,t,dt_remd,isize,index,dt);
  }
  else {
    snew(readtime,nfile_in+1);
    snew(timest,nfile_in+1);
    scan_trj_files(fnms,nfile_in,readtime,timest,imax);
    
    snew(settime,nfile_in+1);
    snew(cont_type,nfile_in+1);
    edit_files(fnms,nfile_in,readtime,timest,settime,cont_type,bSetTime,bSort);
  
    /* Check whether the output file is amongst the input files 
     * This has to be done after sorting etc.
     */
    out_file = fnms_out[0];
    n_append = -1;
    for(i=0; ((i<nfile_in) && (n_append==-1)); i++) {
      if (strcmp(fnms[i],out_file) == 0) {
	n_append = i;
      }
    }
    if (n_append == 0)
      fprintf(stderr,"Will append to %s rather than creating a new file\n",
	      out_file);
    else if (n_append != -1)
      gmx_fatal(FARGS,"Can only append to the first file which is %s (not %s)",
		fnms[0],out_file);
    
    earliersteps=0;    
    
    /* Not checking input format, could be dangerous :-) */
    /* Not checking output format, equally dangerous :-) */
    
    frame=-1;
    frame_out=-1;
    /* the default is not to change the time at all,
     * but this is overridden by the edit_files routine
     */
    t_corr=0;
    
    if (n_append == -1) {
      trxout = open_trx(out_file,"w");
      memset(&frout,0,sizeof(frout));
    }
    else {
      /* Read file to find what is the last frame in it */
      if (!read_first_frame(&status,out_file,&fr,FLAGS))
	gmx_fatal(FARGS,"Reading first frame from %s",out_file);
      while (read_next_frame(status,&fr))
	;
      close_trj(status);
      lasttime = fr.time;
      bKeepLast = TRUE;
      trxout = open_trx(out_file,"a");
      frout = fr;
    }
    /* Lets stitch up some files */
    timestep = timest[0];
    for(i=n_append+1; (i<nfile_in); i++) {
      /* Open next file */
      
      /* set the next time from the last frame in previous file */
      if (i > 0) {
	if (frame_out >= 0) {
	  if(cont_type[i]==TIME_CONTINUE) {
	    begin =frout.time;
	    begin += 0.5*timestep;
	    settime[i]=frout.time;
	    cont_type[i]=TIME_EXPLICIT;	  
	  }
	  else if(cont_type[i]==TIME_LAST) {
	    begin=frout.time;
	    begin += 0.5*timestep;
	  }
	  /* Or, if the time in the next part should be changed by the
	   * same amount, start at half a timestep from the last time
	   * so we dont repeat frames.
	   */
	  /* I don't understand the comment above, but for all the cases
	   * I tried the code seems to work properly. B. Hess 2008-4-2.
	   */
	}
	/* Or, if time is set explicitly, we check for overlap/gap */
	if(cont_type[i]==TIME_EXPLICIT) 
	  if( ( i < nfile_in ) &&
	      ( frout.time < settime[i]-1.5*timestep ) ) 
	    fprintf(stderr, "WARNING: Frames around t=%f %s have a different "
		    "spacing than the rest,\n"
		    "might be a gap or overlap that couldn't be corrected "
		    "automatically.\n",convert_time(frout.time),time_unit());
      }
      
      /* if we don't have a timestep in the current file, use the old one */
      if ( timest[i] != 0 )
	timestep = timest[i];
      
      read_first_frame(&status,fnms[i],&fr,FLAGS);
      if(!fr.bTime) {
	fr.time=0;
	fprintf(stderr,"\nWARNING: Couldn't find a time in the frame.\n");
      }
      
      if(cont_type[i]==TIME_EXPLICIT)
	t_corr=settime[i]-fr.time;
      /* t_corr is the amount we want to change the time.
       * If the user has chosen not to change the time for
       * this part of the trajectory t_corr remains at 
       * the value it had in the last part, changing this
       * by the same amount.
       * If no value was given for the first trajectory part
       * we let the time start at zero, see the edit_files routine.
       */
	
      bNewFile=TRUE;
      
      printf("\n");
      if (lasttime != NOTSET)
	printf("lasttime %g\n", lasttime);
      
      do {
	/* copy the input frame to the output frame */
	frout=fr;
	/* set the new time by adding the correct calculated above */
	frout.time += t_corr; 
	/* quit if we have reached the end of what should be written */
	if((end > 0) && (frout.time > end+GMX_REAL_EPS)) {
	  i=nfile_in;
	  break;
	}
	
	/* determine if we should write this frame (dt is handled elsewhere) */
	if (bCat) /* write all frames of all files */ 
	  bWrite = TRUE;
	else if ( bKeepLast ) /* write till last frame of this traj
				 and skip first frame(s) of next traj */
	  bWrite = ( frout.time > lasttime+0.5*timestep );
	else /* write till first frame of next traj */
	  bWrite = ( frout.time < settime[i+1]-0.5*timestep );
	
	if( bWrite && (frout.time >= begin) ) {
	  frame++;
	  if (frame_out == -1)
	    first_time = frout.time;
	  lasttime = frout.time;
	  if (dt==0 || bRmod(frout.time,first_time,dt)) {
	    frame_out++;
	    last_ok_t=frout.time;
	    if(bNewFile) {
	      fprintf(stderr,"\nContinue writing frames from %s t=%g %s, "
		      "frame=%d      \n",
		      fnms[i],convert_time(frout.time),time_unit(),frame);
	      bNewFile=FALSE;
	    }
	    
	    if (bIndex)
	      write_trxframe_indexed(trxout,&frout,isize,index);
	    else
	      write_trxframe(trxout,&frout);
	    if ( ((frame % 10) == 0) || (frame < 10) )
	      fprintf(stderr," ->  frame %6d time %8.3f %s     \r",
		      frame_out,convert_time(frout.time),time_unit());
	  }
	}
      } while( read_next_frame(status,&fr));
      
      close_trj(status);
      
      earliersteps+=step;	  
    }  
    if (trxout >= 0)
      close_trx(trxout);
     
    fprintf(stderr,"\nLast frame written was %d, time %f %s\n",
	    frame,convert_time(last_ok_t),time_unit()); 
  }
  thanx(stderr);
  
  return 0;
}
示例#20
0
int gmx_traj(int argc,char *argv[])
{
  static char *desc[] = {
    "g_traj plots coordinates, velocities, forces and/or the box.",
    "With [TT]-com[tt] the coordinates, velocities and forces are",
    "calculated for the center of mass of each group.",
    "When [TT]-mol[tt] is set, the numbers in the index file are",
    "interpreted as molecule numbers and the same procedure as with",
    "[TT]-com[tt] is used for each molecule.[PAR]",
    "Option [TT]-ot[tt] plots the temperature of each group,",
    "provided velocities are present in the trajectory file.",
    "No corrections are made for constrained degrees of freedom!",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and",
    "rotational kinetic energy of each group,", 
    "provided velocities are present in the trajectory file.",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities",
    "and average forces as temperature factors to a pdb file with",
    "the average coordinates. The temperature factors are scaled such",
    "that the maximum is 10. The scaling can be changed with the option",
    "[TT]-scale[tt]. To get the velocities or forces of one",
    "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of",
    "desired frame. When averaging over frames you might need to use",
    "the [TT]-nojump[tt] option to obtain the correct average coordinates.",
    "If you select either of these option the average force and velocity",
    "for each atom are written to an xvg file as well",
    "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]",
    "Option [TT]-vd[tt] computes a velocity distribution, i.e. the",
    "norm of the vector is plotted. In addition in the same graph",
    "the kinetic energy distribution is given."
  };
  static bool bMol=FALSE,bCom=FALSE,bNoJump=FALSE;
  static bool bX=TRUE,bY=TRUE,bZ=TRUE,bNorm=FALSE;
  static int  ngroups=1;
  static real scale=0,binwidth=1;
  t_pargs pa[] = {
    { "-com", FALSE, etBOOL, {&bCom},
      "Plot data for the com of each group" },
    { "-mol", FALSE, etBOOL, {&bMol},
      "Index contains molecule numbers iso atom numbers" },
    { "-nojump", FALSE, etBOOL, {&bNoJump},
      "Remove jumps of atoms across the box" },
    { "-x", FALSE, etBOOL, {&bX},
      "Plot X-component" },
    { "-y", FALSE, etBOOL, {&bY},
      "Plot Y-component" },
    { "-z", FALSE, etBOOL, {&bZ},
      "Plot Z-component" },
    { "-ng",       FALSE, etINT, {&ngroups},
      "Number of groups to consider" },
    { "-len", FALSE, etBOOL, {&bNorm},
      "Plot vector length" },
    { "-bin", FALSE, etREAL, {&binwidth},
      "Binwidth for velocity histogram (nm/ps)" },
    { "-scale", FALSE, etREAL, {&scale},
      "Scale factor for pdb output, 0 is autoscale" }
    
  };
  FILE       *outx=NULL,*outv=NULL,*outf=NULL,*outb=NULL,*outt=NULL;
  FILE       *outekt=NULL,*outekr=NULL;
  t_topology top;
  int        ePBC;
  real       *mass,time;
  char       title[STRLEN],*indexfn;
  t_trxframe fr,frout;
  int        flags,nvhisto=0,*vhisto=NULL;
  rvec       *xtop,*xp=NULL;
  rvec       *sumxv=NULL,*sumv=NULL,*sumxf=NULL,*sumf=NULL;
  matrix     topbox;
  int        status,status_out=-1;
  int        i,j,n;
  int        nr_xfr,nr_vfr,nr_ffr;
  char       **grpname;
  int        *isize0,*isize;
  atom_id    **index0,**index;
  atom_id    *atndx;
  t_block    *mols;
  bool       bTop,bOX,bOXT,bOV,bOF,bOB,bOT,bEKT,bEKR,bCV,bCF;
  bool       bDim[4],bDum[4],bVD;
  char       *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" };

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPS, NULL, NULL, ffREAD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ox", "coord.xvg", ffOPTWR },
    { efTRX, "-oxt","coord.xtc", ffOPTWR },
    { efXVG, "-ov", "veloc.xvg", ffOPTWR },
    { efXVG, "-of", "force.xvg", ffOPTWR },
    { efXVG, "-ob", "box.xvg",   ffOPTWR },
    { efXVG, "-ot", "temp.xvg",  ffOPTWR },
    { efXVG, "-ekt","ektrans.xvg", ffOPTWR },
    { efXVG, "-ekr","ekrot.xvg", ffOPTWR },
    { efXVG, "-vd", "veldist.xvg", ffOPTWR },
    { efPDB, "-cv", "veloc.pdb", ffOPTWR },
    { efPDB, "-cf", "force.pdb", ffOPTWR },
    { efXVG, "-av", "all_veloc.xvg", ffOPTWR },
    { efXVG, "-af", "all_force.xvg", ffOPTWR }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,
		    PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);

  if (bMol)
    fprintf(stderr,"Interpreting indexfile entries as molecules.\n"
	    "Using center of mass.\n");
  
  bOX  = opt2bSet("-ox",NFILE,fnm);
  bOXT = opt2bSet("-oxt",NFILE,fnm);
  bOV  = opt2bSet("-ov",NFILE,fnm);
  bOF  = opt2bSet("-of",NFILE,fnm);
  bOB  = opt2bSet("-ob",NFILE,fnm);
  bOT  = opt2bSet("-ot",NFILE,fnm);
  bEKT = opt2bSet("-ekt",NFILE,fnm);
  bEKR = opt2bSet("-ekr",NFILE,fnm);
  bCV  = opt2bSet("-cv",NFILE,fnm) || opt2bSet("-av",NFILE,fnm);
  bCF  = opt2bSet("-cf",NFILE,fnm) || opt2bSet("-af",NFILE,fnm);
  bVD  = opt2bSet("-vd",NFILE,fnm) || opt2parg_bSet("-bin",asize(pa),pa);
  if (bMol || bOT || bEKT || bEKR)
    bCom = TRUE;

  bDim[XX] = bX;
  bDim[YY] = bY;
  bDim[ZZ] = bZ;
  bDim[DIM] = bNorm;

  bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,
		       bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR));
  sfree(xtop);
  if ((bMol || bCV || bCF) && !bTop)
    gmx_fatal(FARGS,"Need a run input file for option -mol, -cv or -cf");

  if (bMol)
    indexfn = ftp2fn(efNDX,NFILE,fnm);
  else
    indexfn = ftp2fn_null(efNDX,NFILE,fnm);

  if (!(bCom && !bMol))
    ngroups = 1;
  snew(grpname,ngroups);
  snew(isize0,ngroups);
  snew(index0,ngroups);
  get_index(&(top.atoms),indexfn,ngroups,isize0,index0,grpname);
  
  if (bMol) {
    mols=&(top.mols);
    atndx = mols->index;
    ngroups = isize0[0];
    snew(isize,ngroups);
    snew(index,ngroups);
    for (i=0; i<ngroups; i++) {
      if (index0[0][i] < 0 || index0[0][i] >= mols->nr)
	gmx_fatal(FARGS,"Molecule index (%d) is out of range (%d-%d)",
		  index0[0][i]+1,1,mols->nr);
      isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]];
      snew(index[i],isize[i]);
      for(j=0; j<isize[i]; j++)
	index[i][j] = atndx[index0[0][i]] + j;
    }
  } else {
    isize = isize0;
    index = index0;
  }
  if (bCom) {
    snew(mass,top.atoms.nr);
    for(i=0; i<top.atoms.nr; i++)
      mass[i] = top.atoms.atom[i].m;
  } else
    mass = NULL;

  flags = 0;
  if (bOX) {
    flags = flags | TRX_READ_X;
    outx = xvgropen(opt2fn("-ox",NFILE,fnm),
		    bCom ? "Center of mass" : "Coordinate",
		    xvgr_tlabel(),"Coordinate (nm)");
    make_legend(outx,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOXT) {
    flags = flags | TRX_READ_X;
    status_out = open_trx(opt2fn("-oxt",NFILE,fnm),"w");
  }
  if (bOV) {
    flags = flags | TRX_READ_V;
    outv = xvgropen(opt2fn("-ov",NFILE,fnm),
		    bCom ? "Center of mass velocity" : "Velocity",
		    xvgr_tlabel(),"Velocity (nm/ps)");
   make_legend(outv,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); 
  }
  if (bOF) {
    flags = flags | TRX_READ_F;
    outf = xvgropen(opt2fn("-of",NFILE,fnm),"Force",
		    xvgr_tlabel(),"Force (kJ mol\\S-1\\N nm\\S-1\\N)");
    make_legend(outf,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOB) {
    outb = xvgropen(opt2fn("-ob",NFILE,fnm),"Box vector elements",
		    xvgr_tlabel(),"(nm)");
   
    xvgr_legend(outb,6,box_leg);
  }
  if (bOT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outt = xvgropen(opt2fn("-ot",NFILE,fnm),"Temperature",xvgr_tlabel(),"(K)");
    make_legend(outt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outekt = xvgropen(opt2fn("-ekt",NFILE,fnm),"Center of mass translation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKR) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_X | TRX_READ_V;
    outekr = xvgropen(opt2fn("-ekr",NFILE,fnm),"Center of mass rotation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekr,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bVD)
    flags = flags | TRX_READ_V;
  if (bCV)
    flags = flags | TRX_READ_X | TRX_READ_V;
  if (bCF)
    flags = flags | TRX_READ_X | TRX_READ_F;
  if ((flags == 0) && !bOB) {
    fprintf(stderr,"Please select one or more output file options\n");
    exit(0);
  }

  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags);

  if (bCV) {
    snew(sumxv,fr.natoms);
    snew(sumv,fr.natoms);
  }
  if (bCF) {
    snew(sumxf,fr.natoms);
    snew(sumf,fr.natoms);
  }
  nr_xfr = 0;
  nr_vfr = 0;
  nr_ffr = 0;
  
  do {
    time = convert_time(fr.time);

    if (fr.bX && bNoJump && fr.bBox) {
      if (xp)
	remove_jump(fr.box,fr.natoms,xp,fr.x);
      else 
	snew(xp,fr.natoms);
      for(i=0; i<fr.natoms; i++)
	copy_rvec(fr.x[i],xp[i]);
    }
    
    if (fr.bX && bCom)
      rm_pbc(&(top.idef),ePBC,fr.natoms,fr.box,fr.x,fr.x);

    if (bVD && fr.bV) 
      update_histo(isize[0],index[0],fr.v,&nvhisto,&vhisto,binwidth);
      
    if (bOX && fr.bX)
      print_data(outx,time,fr.x,mass,bCom,ngroups,isize,index,bDim);
    if (bOXT && fr.bX) {
      frout = fr;
      if (!frout.bAtoms) {
	frout.atoms  = &top.atoms;
	frout.bAtoms = TRUE;
      }
      write_trx_x(status_out,&frout,mass,bCom,ngroups,isize,index);
    }
    if (bOV && fr.bV)
      print_data(outv,time,fr.v,mass,bCom,ngroups,isize,index,bDim);
    if (bOF && fr.bF)
      print_data(outf,time,fr.f,NULL,bCom,ngroups,isize,index,bDim);
    if (bOB && fr.bBox)
      fprintf(outb,"\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",fr.time,
	      fr.box[XX][XX],fr.box[YY][YY],fr.box[ZZ][ZZ],
	      fr.box[YY][XX],fr.box[ZZ][XX],fr.box[ZZ][YY]);
    if (bOT && fr.bV) {
      fprintf(outt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outt,"\t%g",temp(fr.v,mass,isize[i],index[i]));
      fprintf(outt,"\n");
    }
    if (bEKT && fr.bV) {
      fprintf(outekt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekt,"\t%g",ektrans(fr.v,mass,isize[i],index[i]));
      fprintf(outekt,"\n");
    }
    if (bEKR && fr.bX && fr.bV) {
      fprintf(outekr," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekr,"\t%g",ekrot(fr.x,fr.v,mass,isize[i],index[i]));
      fprintf(outekr,"\n");
    }
    if (bCV) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxv[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bV) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumv[i],fr.v[i]);
	nr_vfr++;
      }
    }
    if (bCF) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxf[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bF) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumf[i],fr.f[i]);
	nr_ffr++;
      }
    }
    
  } while(read_next_frame(status,&fr));
  

  /* clean up a bit */
  close_trj(status);
  
  if (bOX) fclose(outx);
  if (bOXT) close_trx(status_out);
  if (bOV) fclose(outv);
  if (bOF) fclose(outf);
  if (bOB) fclose(outb);
  if (bOT) fclose(outt);
  if (bEKT) fclose(outekt);
  if (bEKR) fclose(outekr);

  if (bVD)
    print_histo(opt2fn("-vd",NFILE,fnm),nvhisto,vhisto,binwidth);
    
  if ((bCV || bCF) && (nr_vfr>1 || nr_ffr>1) && !bNoJump)
    fprintf(stderr,"WARNING: More than one frame was used for option -cv or -cf\n"
	    "If atoms jump across the box you should use the -nojump option\n");

  if (bCV)
    write_pdb_bfac(opt2fn("-cv",NFILE,fnm),
		   opt2fn("-av",NFILE,fnm),"average velocity",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxv,
		   nr_vfr,sumv,bDim,scale);
  if (bCF)
    write_pdb_bfac(opt2fn("-cf",NFILE,fnm),
		   opt2fn("-af",NFILE,fnm),"average force",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxf,
		   nr_ffr,sumf,bDim,scale);

  /* view it */
  view_all(NFILE, fnm);
  
  thanx(stderr);
  
  return 0;
}