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; }
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; }
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"); }
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; }
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; }
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); }
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]); } }
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; }
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; }
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; }
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]); } }
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); }
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; }
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; }
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; }
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; }
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; }