コード例 #1
0
ファイル: gmx_anaeig.c プロジェクト: martinhoefling/gromacs
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");
}
コード例 #2
0
ファイル: gmx_nmens.c プロジェクト: drmaruyama/gromacs
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;
}
コード例 #3
0
ファイル: gmx_dyndom.c プロジェクト: yhalcyon/Gromacs
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;
}
コード例 #4
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;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: gmx_nmtraj.cpp プロジェクト: mpharrigan/gromacs
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;
}
コード例 #7
0
ファイル: gmx_mindist.c プロジェクト: exianshine/gromacs
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);
}
コード例 #8
0
ファイル: gmx_filter.c プロジェクト: martinhoefling/gromacs
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;
}
コード例 #9
0
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);
}