int gmx_sdf(int argc,char *argv[]) { const char *desc[] = { "[TT]g_sdf[tt] calculates the spatial distribution function (SDF) of a set of atoms", "within a coordinate system defined by three atoms. There is single body, ", "two body and three body SDF implemented (select with option [TT]-mode[tt]). ", "In the single body case the local coordinate system is defined by using", "a triple of atoms from one single molecule, for the two and three body case", "the configurations are dynamically searched complexes of two or three", "molecules (or residues) meeting certain distance consitions (see below).[PAR]", "The program needs a trajectory, a GROMACS run input file and an index ", "file to work. ", "You have to setup 4 groups in the index file before using g_sdf: [PAR]", "The first three groups are used to define the SDF coordinate system.", "The program will dynamically generate the atom triples according to ", "the selected [TT]-mode[tt]: ", "In [TT]-mode[tt] 1 the triples will be just the 1st, 2nd, 3rd, ... atoms from ", "groups 1, 2 and 3. Hence the nth entries in groups 1, 2 and 3 must be from the", "same residue. In [TT]-mode[tt] 2 the triples will be 1st, 2nd, 3rd, ... atoms from", "groups 1 and 2 (with the nth entries in groups 1 and 2 having the same res-id).", "For each pair from groups 1 and 2 group 3 is searched for an atom meeting the", "distance conditions set with [TT]-triangle[tt] and [TT]-dtri[tt] relative to atoms 1 and 2. In", "[TT]-mode[tt] 3 for each atom in group 1 group 2 is searched for an atom meeting the", "distance condition and if a pair is found group 3 is searched for an atom", "meeting the further conditions. The triple will only be used if all three atoms", "have different res-id's.[PAR]", "The local coordinate system is always defined using the following scheme:", "Atom 1 will be used as the point of origin for the SDF. ", "Atom 1 and 2 will define the principle axis (Z) of the coordinate system.", "The other two axis will be defined inplane (Y) and normal (X) to the plane through", "Atoms 1, 2 and 3. ", "The fourth group", "contains the atoms for which the SDF will be evaluated.[PAR]", "For [TT]-mode[tt] 2 and 3 you have to define the distance conditions for the ", "2 resp. 3 molecule complexes to be searched for using [TT]-triangle[tt] and [TT]-dtri[tt].[PAR]", "The SDF will be sampled in cartesian coordinates.", "Use [TT]-grid x y z[tt] to define the size of the SDF grid around the ", "reference molecule. ", "The Volume of the SDF grid will be V=x*y*z (nm^3). ", "Use [TT]-bin[tt] to set the binwidth for grid.[PAR]", "The output will be a binary 3D-grid file ([TT]gom_plt.dat[tt]) in the [TT].plt[tt] format that can be be", "read directly by gOpenMol. ", "The option [TT]-r[tt] will generate a [TT].gro[tt] file with the reference molecule(s) transferred to", "the SDF coordinate system. Load this file into gOpenMol and display the", "SDF as a contour plot (see http://www.csc.fi/gopenmol/index.phtml for ", "further documentation). [PAR]", "For further information about SDF's have a look at: A. Vishnyakov, JPC A, 105,", "2001, 1702 and the references cited within." }; output_env_t oenv; static gmx_bool bRef=FALSE; static int mode=1; static rvec triangle={0.0,0.0,0.0}; static rvec dtri={0.03,0.03,0.03}; static rvec cutoff={1,1,1}; static real binwidth=0.05; t_pargs pa[] = { { "-mode", FALSE, etINT, {&mode}, "SDF in [1,2,3] particle mode"}, { "-triangle", FALSE, etRVEC, {&triangle}, "r(1,3), r(2,3), r(1,2)"}, { "-dtri", FALSE, etRVEC, {&dtri}, "dr(1,3), dr(2,3), dr(1,2)"}, { "-bin", FALSE, etREAL, {&binwidth}, "Binwidth for the 3D-grid (nm)" }, { "-grid", FALSE, etRVEC, {&cutoff}, "Size of the 3D-grid (nm,nm,nm)"} }; #define NPA asize(pa) const char *fnTPS,*fnNDX,*fnREF; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efTPS, NULL, NULL, ffOPTRD }, { efDAT, "-o", "gom_plt", ffWRITE }, { efSTO, "-r", "refmol", ffOPTWR }, }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL,&oenv); fnTPS = ftp2fn_null(efTPS,NFILE,fnm); fnNDX = ftp2fn_null(efNDX,NFILE,fnm); fnREF = opt2fn_null("-r",NFILE,fnm); bRef = opt2bSet("-r",NFILE,fnm); if (!fnNDX) gmx_fatal(FARGS,"No index file specified\n" " Nothing to do!"); if (!fnTPS) gmx_fatal(FARGS,"No topology file specified\n" " Nothing to do!"); if ( bRef && (fn2ftp(fnREF) != efGRO)) { fprintf(stderr,"\nOnly GROMACS format is supported for reference structures.\n"); fprintf(stderr,"Option -r will be ignored!\n"); bRef = FALSE; } if ((mode < 1) || (mode > 3)) gmx_fatal(FARGS,"Wrong -mode selection. Chose 1-, 2- oder 3-particle mode.\n"); do_sdf(fnNDX,fnTPS,ftp2fn(efTRX,NFILE,fnm),opt2fn("-o",NFILE,fnm), fnREF,bRef,cutoff,binwidth,mode,triangle,dtri,oenv); gmx_thanx(stderr); return 0; }
int gmx_clustsize(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes the size distributions of molecular/atomic clusters in", "the gas phase. The output is given in the form of an [REF].xpm[ref] file.", "The total number of clusters is written to an [REF].xvg[ref] file.[PAR]", "When the [TT]-mol[tt] option is given clusters will be made out of", "molecules rather than atoms, which allows clustering of large molecules.", "In this case an index file would still contain atom numbers", "or your calculation will die with a SEGV.[PAR]", "When velocities are present in your trajectory, the temperature of", "the largest cluster will be printed in a separate [REF].xvg[ref] file assuming", "that the particles are free to move. If you are using constraints,", "please correct the temperature. For instance water simulated with SHAKE", "or SETTLE will yield a temperature that is 1.5 times too low. You can", "compensate for this with the [TT]-ndf[tt] option. Remember to take the removal", "of center of mass motion into account.[PAR]", "The [TT]-mc[tt] option will produce an index file containing the", "atom numbers of the largest cluster." }; static real cutoff = 0.35; static int nskip = 0; static int nlevels = 20; static int ndf = -1; static gmx_bool bMol = FALSE; static gmx_bool bPBC = TRUE; static rvec rlo = { 1.0, 1.0, 0.0 }; static rvec rhi = { 0.0, 0.0, 1.0 }; gmx_output_env_t *oenv; t_pargs pa[] = { { "-cut", FALSE, etREAL, {&cutoff}, "Largest distance (nm) to be considered in a cluster" }, { "-mol", FALSE, etBOOL, {&bMol}, "Cluster molecules rather than atoms (needs [REF].tpr[ref] file)" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions" }, { "-nskip", FALSE, etINT, {&nskip}, "Number of frames to skip between writing" }, { "-nlevels", FALSE, etINT, {&nlevels}, "Number of levels of grey in [REF].xpm[ref] output" }, { "-ndf", FALSE, etINT, {&ndf}, "Number of degrees of freedom of the entire system for temperature calculation. If not set, the number of atoms times three is used." }, { "-rgblo", FALSE, etRVEC, {rlo}, "RGB values for the color of the lowest occupied cluster size" }, { "-rgbhi", FALSE, etRVEC, {rhi}, "RGB values for the color of the highest occupied cluster size" } }; #define NPA asize(pa) const char *fnNDX, *fnTPR; t_rgb rgblo, rgbhi; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPR, NULL, NULL, ffOPTRD }, { efNDX, NULL, NULL, ffOPTRD }, { efXPM, "-o", "csize", ffWRITE }, { efXPM, "-ow", "csizew", ffWRITE }, { efXVG, "-nc", "nclust", ffWRITE }, { efXVG, "-mc", "maxclust", ffWRITE }, { efXVG, "-ac", "avclust", ffWRITE }, { efXVG, "-hc", "histo-clust", ffWRITE }, { efXVG, "-temp", "temp", ffOPTWR }, { efNDX, "-mcn", "maxclust", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } fnNDX = ftp2fn_null(efNDX, NFILE, fnm); rgblo.r = rlo[XX], rgblo.g = rlo[YY], rgblo.b = rlo[ZZ]; rgbhi.r = rhi[XX], rgbhi.g = rhi[YY], rgbhi.b = rhi[ZZ]; fnTPR = ftp2fn_null(efTPR, NFILE, fnm); if (bMol && !fnTPR) { gmx_fatal(FARGS, "You need a tpr file for the -mol option"); } clust_size(fnNDX, ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm), opt2fn("-ow", NFILE, fnm), opt2fn("-nc", NFILE, fnm), opt2fn("-ac", NFILE, fnm), opt2fn("-mc", NFILE, fnm), opt2fn("-hc", NFILE, fnm), opt2fn("-temp", NFILE, fnm), opt2fn("-mcn", NFILE, fnm), bMol, bPBC, fnTPR, cutoff, nskip, nlevels, rgblo, rgbhi, ndf, oenv); return 0; }
int main(int argc,char *argv[]) { static char *desc[] = { "[TT]mkice[tt] generates an ice crystal in the Ih crystal form which is the", "most stable form. The rectangular unitcell contains eight molecules", "and all oxygens are tetrahedrally coordinated.[PAR]", "If an input file is given it is interpreted as a series of oxygen", "coordinates the distance between which can be scaled by the odist flag.", "The program then adds hydrogens to the oxygens in random orientation", "but with proper OH distances and HOH angle. This feature allows to", "build water clusters based on oxygen coordinates only." }; static int nx=1,ny=1,nz=1; static gmx_bool bYaw=FALSE,bLJ=TRUE,bFull=TRUE,bSeries=FALSE; static gmx_bool bOrdered=TRUE,bDiamond=FALSE,bPBC=TRUE; static real rcut=0.3,odist=0.274,hdist=0.09572; t_pargs pa[] = { { "-nx", FALSE, etINT, {&nx}, "nx" }, { "-ny", FALSE, etINT, {&ny}, "ny" }, { "-nz", FALSE, etINT, {&nz}, "nz" }, { "-yaw", FALSE, etBOOL, {&bYaw}, "Generate virtual sites and shell positions" }, { "-lj", FALSE, etBOOL, {&bLJ}, "Use LJ as well as coulomb for virial calculation" }, { "-rcut", FALSE,etREAL, {&rcut},"Cut-off for virial calculations" }, { "-full", FALSE,etBOOL, {&bFull},"Full virial output" }, { "-odist", FALSE, etREAL, {&odist}, "Distance (nm) between oxygens" }, { "-hdist", FALSE, etREAL, {&hdist}, "Bondlength (nm) for OH bond" }, { "-diamond",FALSE,etBOOL, {&bDiamond}, "Make a diamond instead" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Make a periodic diamond" }, { "-order", FALSE,etBOOL, {&bOrdered}, "Make a proton-ordered ice lattice" }, { "-series",FALSE, etBOOL, {&bSeries}, "Do a series of virial calculations with different cut-off (from 0.3 up till the specified one)" } }; t_filenm fnm[] = { { efSTO, "-p", "ice", ffWRITE }, { efSTO, "-c", NULL, ffOPTRD }, { efDAT, "-f", NULL, ffOPTRD }, { efTRN, "-o", "ice", ffOPTWR } }; #define NFILE asize(fnm) FILE *fp; char *fn,quote[256]; int i,j,k,n,nmax,m,natom,natmol; t_atoms *pdba; t_atoms atoms; t_symtab symtab; rvec box,tmp,*xx; matrix boxje; CopyRight(stdout,argv[0]); parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,asize(desc), desc,0,NULL); if (debug) { fprintf(debug,"nx = %3d, ny = %3d, nz = %3d\n",nx,ny,nz); fprintf(debug,"YAW = %3s, LJ = %3s, rcut = %g\n",yesno_names[bYaw], yesno_names[bLJ],rcut); } if (bYaw) natmol = 5; else if (bDiamond) natmol = 1; else natmol = 3; if (opt2bSet("-f",NFILE,fnm)) { natom = read_rel_coords(opt2fn("-f",NFILE,fnm),&xx,natmol); nmax = natom; } else { natom = natmol*8; nmax = natom*nx*ny*nz; snew(xx,nmax); } snew(pdba,1); init_t_atoms(pdba,nmax,TRUE); pdba->nr = nmax; open_symtab(&symtab); for(n=0; (n<nmax); n++) { pdba->pdbinfo[n].type = epdbATOM; pdba->pdbinfo[n].atomnr = 1+n; pdba->atom[n].resnr = 1+(n/natmol); pdba->atomname[n] = put_symtab(&symtab, bDiamond ? diamname[(n % natmol)] : watname[(n % natmol)]); if (bDiamond) pdba->resname[n] = put_symtab(&symtab,"DIA"); else pdba->resname[n] = put_symtab(&symtab,"SOL"); sprintf(pdba->pdbinfo[n].pdbresnr,"%d",n); pdba->atom[n].chain = ' '; } /* Generate the unit cell */ if (bDiamond) unitcell_d(xx,box,odist); else if (opt2bSet("-f",NFILE,fnm)) { random_h_coords(natmol,natom/natmol,xx,box,bYaw,odist,hdist); } else unitcell(xx,box,bYaw,odist,hdist); if (debug) { clear_mat(boxje); boxje[XX][XX] = box[XX]; boxje[YY][YY] = box[YY]; boxje[ZZ][ZZ] = box[ZZ]; } n=0; for(i=0; (i<nx); i++) { tmp[XX] = i*box[XX]; for(j=0; (j<ny); j++) { tmp[YY] = j*box[YY]; for(k=0; (k<nz); k++) { tmp[ZZ] = k*box[ZZ]; for(m=0; (m<natom); m++,n++) { if ((!bOrdered && ((m % natmol) == 0)) || bOrdered) rvec_add(xx[n % natom],tmp,xx[n]); else ; } } } } clear_mat(boxje); boxje[XX][XX] = box[XX]*nx; boxje[YY][YY] = box[YY]*ny; boxje[ZZ][ZZ] = box[ZZ]*nz; printf("Crystal: %10.5f %10.5f %10.5f\n", nx*box[XX],ny*box[YY],nz*box[ZZ]); if (debug && !bDiamond) { if (bSeries) for(i=3; (i<=10*rcut); i++) { fprintf(debug,"This is with rcut = %g\n",i*0.1); virial(debug,bFull,nmax/natmol,xx,boxje, 0.1*i,bYaw,bYaw ? qyaw : qspc,bLJ); } else virial(debug,bFull,nmax/natmol,xx,boxje, rcut,bYaw,bYaw ? qyaw : qspc,bLJ); } if (bDiamond) mk_diamond(pdba,xx,odist,&symtab,bPBC,boxje); fn = ftp2fn(efSTO,NFILE,fnm); if (fn2ftp(fn) == efPDB) { fp = gmx_ffopen(fn,"w"); if (bDiamond) fprintf(fp,"HEADER This is a *diamond*\n"); else fprintf(fp,"HEADER A beautiful Ice Ih crystal\n"); fprintf(fp,"REMARK Generated by mkice with the following options:\n" "REMARK nx = %d, ny = %d, nz = %d, odist = %g, hdist = %g\n", nx,ny,nz,odist,hdist); bromacs(quote,255); write_pdbfile(fp,quote,pdba,xx,boxje,' ',-1); gmx_ffclose(fp); } else { bromacs(quote,255); write_sto_conf(fn,quote,pdba,xx,NULL,boxje); } if (ftp2bSet(efTRN,NFILE,fnm)) write_trn(ftp2fn(efTRN,NFILE,fnm),0,0,0,boxje,nmax,xx,NULL,NULL); return 0; }
int gmx_rmsdist(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes the root mean square deviation of atom distances,", "which has the advantage that no fit is needed like in standard RMS", "deviation as computed by [gmx-rms].", "The reference structure is taken from the structure file.", "The RMSD at time t is calculated as the RMS", "of the differences in distance between atom-pairs in the reference", "structure and the structure at time t.[PAR]", "[THISMODULE] can also produce matrices of the rms distances, rms distances", "scaled with the mean distance and the mean distances and matrices with", "NMR averaged distances (1/r^3 and 1/r^6 averaging). Finally, lists", "of atom pairs with 1/r^3 and 1/r^6 averaged distance below the", "maximum distance ([TT]-max[tt], which will default to 0.6 in this case)", "can be generated, by default averaging over equivalent hydrogens", "(all triplets of hydrogens named \\*[123]). Additionally a list of", "equivalent atoms can be supplied ([TT]-equiv[tt]), each line containing", "a set of equivalent atoms specified as residue number and name and", "atom name; e.g.:[PAR]", "[TT]HB* 3 SER HB1 3 SER HB2[tt][PAR]", "Residue and atom names must exactly match those in the structure", "file, including case. Specifying non-sequential atoms is undefined." }; int i, teller; real t; t_topology top; int ePBC; t_atoms *atoms; matrix box; rvec *x; FILE *fp; t_trxstatus *status; int isize, gnr = 0; int *index, *noe_index; char *grpname; real **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr; real **dtot1_3 = NULL, **dtot1_6 = NULL; real rmsnow, meanmax, rmsmax, rmscmax; real max1_3, max1_6; t_noe_gr *noe_gr = NULL; t_noe **noe = NULL; t_rgb rlo, rhi; gmx_bool bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR; static int nlevels = 40; static real scalemax = -1.0; static gmx_bool bSumH = TRUE; static gmx_bool bPBC = TRUE; gmx_output_env_t *oenv; t_pargs pa[] = { { "-nlevels", FALSE, etINT, {&nlevels}, "Discretize RMS in this number of levels" }, { "-max", FALSE, etREAL, {&scalemax}, "Maximum level in matrices" }, { "-sumh", FALSE, etBOOL, {&bSumH}, "Average distance over equivalent hydrogens" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions when computing distances" } }; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-equiv", "equiv", ffOPTRD }, { efXVG, NULL, "distrmsd", ffWRITE }, { efXPM, "-rms", "rmsdist", ffOPTWR }, { efXPM, "-scl", "rmsscale", ffOPTWR }, { efXPM, "-mean", "rmsmean", ffOPTWR }, { efXPM, "-nmr3", "nmr3", ffOPTWR }, { efXPM, "-nmr6", "nmr6", ffOPTWR }, { efDAT, "-noe", "noe", ffOPTWR }, }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bRMS = opt2bSet("-rms", NFILE, fnm); bScale = opt2bSet("-scl", NFILE, fnm); bMean = opt2bSet("-mean", NFILE, fnm); bNOE = opt2bSet("-noe", NFILE, fnm); bNMR3 = opt2bSet("-nmr3", NFILE, fnm); bNMR6 = opt2bSet("-nmr6", NFILE, fnm); bNMR = bNMR3 || bNMR6 || bNOE; max1_3 = 0; max1_6 = 0; /* check input */ if (bNOE && scalemax < 0) { scalemax = 0.6; fprintf(stderr, "WARNING: using -noe without -max " "makes no sense, setting -max to %g\n\n", scalemax); } /* get topology and index */ read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, FALSE); if (!bPBC) { ePBC = epbcNONE; } atoms = &(top.atoms); get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); /* initialize arrays */ snew(d, isize); snew(dtot, isize); snew(dtot2, isize); if (bNMR) { snew(dtot1_3, isize); snew(dtot1_6, isize); } snew(mean, isize); snew(rms, isize); snew(rmsc, isize); snew(d_r, isize); snew(resnr, isize); for (i = 0; (i < isize); i++) { snew(d[i], isize); snew(dtot[i], isize); snew(dtot2[i], isize); if (bNMR) { snew(dtot1_3[i], isize); snew(dtot1_6[i], isize); } snew(mean[i], isize); snew(rms[i], isize); snew(rmsc[i], isize); snew(d_r[i], isize); resnr[i] = i+1; } /*set box type*/ calc_dist(isize, index, x, ePBC, box, d_r); sfree(x); /*open output files*/ fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname); } /*do a first step*/ read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); teller = 0; do { calc_dist_tot(isize, index, x, ePBC, box, d, dtot, dtot2, bNMR, dtot1_3, dtot1_6); rmsnow = rms_diff(isize, d, d_r); fprintf(fp, "%g %g\n", t, rmsnow); teller++; } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); xvgrclose(fp); close_trj(status); calc_rms(isize, teller, dtot, dtot2, rms, &rmsmax, rmsc, &rmscmax, mean, &meanmax); fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax); if (bNMR) { calc_nmr(isize, teller, dtot1_3, dtot1_6, &max1_3, &max1_6); } if (scalemax > -1.0) { rmsmax = scalemax; rmscmax = scalemax; meanmax = scalemax; max1_3 = scalemax; max1_6 = scalemax; } if (bNOE) { /* make list of noe atom groups */ snew(noe_index, isize+1); snew(noe_gr, isize); gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm), atoms, isize, index, bSumH, noe_index, noe_gr); fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n", gnr, isize); /* make half matrix of of noe-group distances from atom distances */ snew(noe, gnr); for (i = 0; i < gnr; i++) { snew(noe[i], gnr); } calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe); } rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0; rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0; if (bRMS) { write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0, "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels); } if (bScale) { write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0, "Relative RMS", "RMS", "Atom Index", "Atom Index", isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels); } if (bMean) { write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels); } if (bNMR3) { write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels); } if (bNMR6) { write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels); } if (bNOE) { write_noe(opt2FILE("-noe", NFILE, fnm, "w"), gnr, noe, noe_gr, scalemax); } do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL); return 0; }
int gmx_densorder(int argc, char *argv[]) { static const char *desc[] = { "[THISMODULE] reduces a two-phase density distribution", "along an axis, computed over a MD trajectory,", "to 2D surfaces fluctuating in time, by a fit to", "a functional profile for interfacial densities.", "A time-averaged spatial representation of the", "interfaces can be output with the option [TT]-tavg[tt]." }; /* Extra arguments - but note how you always get the begin/end * options when running the program, without mentioning them here! */ output_env_t oenv; t_topology *top; char **grpname; int ePBC, *ngx; static real binw = 0.2; static real binwz = 0.05; static real dens1 = 0.00; static real dens2 = 1000.00; static int ftorder = 0; static int nsttblock = 100; static int axis = 2; static const char *axtitle = "Z"; atom_id **index; /* Index list for single group*/ int xslices, yslices, zslices, tblock; static gmx_bool bGraph = FALSE; static gmx_bool bCenter = FALSE; static gmx_bool bFourier = FALSE; static gmx_bool bRawOut = FALSE; static gmx_bool bOut = FALSE; static gmx_bool b1d = FALSE; static int nlevels = 100; /*Densitymap - Densmap[t][x][y][z]*/ real ****Densmap = NULL; /* Surfaces surf[t][surf_x,surf_y]*/ t_interf ***surf1, ***surf2; static const char *meth[] = {NULL, "bisect", "functional", NULL}; int eMeth; char **graphfiles, **rawfiles, **spectra; /* Filenames for xpm-surface maps, rawdata and powerspectra */ int nfxpm = -1, nfraw, nfspect; /* # files for interface maps and spectra = # interfaces */ t_pargs pa[] = { { "-1d", FALSE, etBOOL, {&b1d}, "Pseudo-1d interface geometry"}, { "-bw", FALSE, etREAL, {&binw}, "Binwidth of density distribution tangential to interface"}, { "-bwn", FALSE, etREAL, {&binwz}, "Binwidth of density distribution normal to interface"}, { "-order", FALSE, etINT, {&ftorder}, "Order of Gaussian filter, order 0 equates to NO filtering"}, {"-axis", FALSE, etSTR, {&axtitle}, "Axis Direction - X, Y or Z"}, {"-method", FALSE, etENUM, {meth}, "Interface location method"}, {"-d1", FALSE, etREAL, {&dens1}, "Bulk density phase 1 (at small z)"}, {"-d2", FALSE, etREAL, {&dens2}, "Bulk density phase 2 (at large z)"}, { "-tblock", FALSE, etINT, {&nsttblock}, "Number of frames in one time-block average"}, { "-nlevel", FALSE, etINT, {&nlevels}, "Number of Height levels in 2D - XPixMaps"} }; t_filenm fnm[] = { { efTPX, "-s", NULL, ffREAD }, /* this is for the topology */ { efTRX, "-f", NULL, ffREAD }, /* and this for the trajectory */ { efNDX, "-n", NULL, ffREAD}, /* this is to select groups */ { efDAT, "-o", "Density4D", ffOPTWR}, /* This is for outputting the entire 4D densityfield in binary format */ { efOUT, "-or", NULL, ffOPTWRMULT}, /* This is for writing out the entire information in the t_interf arrays */ { efXPM, "-og", "interface", ffOPTWRMULT}, /* This is for writing out the interface meshes - one xpm-file per tblock*/ { efOUT, "-Spect", "intfspect", ffOPTWRMULT}, /* This is for the trajectory averaged Fourier-spectra*/ }; #define NFILE asize(fnm) /* This is the routine responsible for adding default options, * calling the X/motif interface, etc. */ if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } eMeth = nenum(meth); bFourier = opt2bSet("-Spect", NFILE, fnm); bRawOut = opt2bSet("-or", NFILE, fnm); bGraph = opt2bSet("-og", NFILE, fnm); bOut = opt2bSet("-o", NFILE, fnm); top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC); snew(grpname, 1); snew(index, 1); snew(ngx, 1); /* Calculate axis */ axis = toupper(axtitle[0]) - 'X'; get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, ngx, index, grpname); density_in_time(ftp2fn(efTRX, NFILE, fnm), index, ngx, binw, binwz, nsttblock, &Densmap, &xslices, &yslices, &zslices, &tblock, top, ePBC, axis, bCenter, b1d, oenv); if (ftorder > 0) { filterdensmap(Densmap, xslices, yslices, zslices, tblock, 2*ftorder+1); } if (bOut) { outputfield(opt2fn("-o", NFILE, fnm), Densmap, xslices, yslices, zslices, tblock); } interfaces_txy(Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1, &surf2, oenv); if (bGraph) { /*Output surface-xpms*/ nfxpm = opt2fns(&graphfiles, "-og", NFILE, fnm); if (nfxpm != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm); } writesurftoxpms(surf1, surf2, tblock, xslices, yslices, zslices, binw, binwz, graphfiles, zslices); } /*Output raw-data*/ if (bRawOut) { nfraw = opt2fns(&rawfiles, "-or", NFILE, fnm); if (nfraw != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm); } writeraw(surf1, surf2, tblock, xslices, yslices, rawfiles); } if (bFourier) { nfspect = opt2fns(&spectra, "-Spect", NFILE, fnm); if (nfspect != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %d", nfspect); } powerspectavg_intf(surf1, surf2, tblock, xslices, yslices, spectra); } sfree(Densmap); if (bGraph || bFourier || bRawOut) { sfree(surf1); sfree(surf2); } return 0; }
int gmx_helix(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes all kinds of helix properties. First, the peptide", "is checked to find the longest helical part, as determined by", "hydrogen bonds and [GRK]phi[grk]/[GRK]psi[grk] angles.", "That bit is fitted", "to an ideal helix around the [IT]z[it]-axis and centered around the origin.", "Then the following properties are computed:[PAR]", "[BB]1.[bb] Helix radius (file [TT]radius.xvg[tt]). This is merely the", "RMS deviation in two dimensions for all C[GRK]alpha[grk] atoms.", "it is calculated as [SQRT]([SUM][sum][SUB]i[sub] (x^2(i)+y^2(i)))/N[sqrt] where N is the number", "of backbone atoms. For an ideal helix the radius is 0.23 nm[BR]", "[BB]2.[bb] Twist (file [TT]twist.xvg[tt]). The average helical angle per", "residue is calculated. For an [GRK]alpha[grk]-helix it is 100 degrees,", "for 3-10 helices it will be smaller, and ", "for 5-helices it will be larger.[BR]", "[BB]3.[bb] Rise per residue (file [TT]rise.xvg[tt]). The helical rise per", "residue is plotted as the difference in [IT]z[it]-coordinate between C[GRK]alpha[grk]", "atoms. For an ideal helix, this is 0.15 nm[BR]", "[BB]4.[bb] Total helix length (file [TT]len-ahx.xvg[tt]). The total length", "of the", "helix in nm. This is simply the average rise (see above) times the", "number of helical residues (see below).[BR]", "[BB]5.[bb] Helix dipole, backbone only (file [TT]dip-ahx.xvg[tt]).[BR]", "[BB]6.[bb] RMS deviation from ideal helix, calculated for the C[GRK]alpha[grk]", "atoms only (file [TT]rms-ahx.xvg[tt]).[BR]", "[BB]7.[bb] Average C[GRK]alpha[grk] - C[GRK]alpha[grk] dihedral angle (file [TT]phi-ahx.xvg[tt]).[BR]", "[BB]8.[bb] Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).[BR]", "[BB]9.[bb] Ellipticity at 222 nm according to Hirst and Brooks.", "[PAR]" }; static gmx_bool bCheck = FALSE, bFit = TRUE, bDBG = FALSE, bEV = FALSE; static int rStart = 0, rEnd = 0, r0 = 1; t_pargs pa [] = { { "-r0", FALSE, etINT, {&r0}, "The first residue number in the sequence" }, { "-q", FALSE, etBOOL, {&bCheck}, "Check at every step which part of the sequence is helical" }, { "-F", FALSE, etBOOL, {&bFit}, "Toggle fit to a perfect helix" }, { "-db", FALSE, etBOOL, {&bDBG}, "Print debug info" }, { "-ev", FALSE, etBOOL, {&bEV}, "Write a new 'trajectory' file for ED" }, { "-ahxstart", FALSE, etINT, {&rStart}, "First residue in helix" }, { "-ahxend", FALSE, etINT, {&rEnd}, "Last residue in helix" } }; typedef struct { FILE *fp, *fp2; gmx_bool bfp2; const char *filenm; const char *title; const char *xaxis; const char *yaxis; real val; } t_xvgrfile; t_xvgrfile xf[efhNR] = { { NULL, NULL, TRUE, "radius", "Helix radius", NULL, "r (nm)", 0.0 }, { NULL, NULL, TRUE, "twist", "Twist per residue", NULL, "Angle (deg)", 0.0 }, { NULL, NULL, TRUE, "rise", "Rise per residue", NULL, "Rise (nm)", 0.0 }, { NULL, NULL, FALSE, "len-ahx", "Length of the Helix", NULL, "Length (nm)", 0.0 }, { NULL, NULL, FALSE, "dip-ahx", "Helix Backbone Dipole", NULL, "rq (nm e)", 0.0 }, { NULL, NULL, TRUE, "rms-ahx", "RMS Deviation from Ideal Helix", NULL, "RMS (nm)", 0.0 }, { NULL, NULL, FALSE, "rmsa-ahx", "Average RMSD per Residue", "Residue", "RMS (nm)", 0.0 }, { NULL, NULL, FALSE, "cd222", "Ellipticity at 222 nm", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "pprms", "RMS Distance from \\8a\\4-helix", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "caphi", "Average Ca-Ca Dihedral", NULL, "\\8F\\4(deg)", 0.0 }, { NULL, NULL, TRUE, "phi", "Average \\8F\\4 angles", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "psi", "Average \\8Y\\4 angles", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "hb3", "Average n-n+3 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "hb4", "Average n-n+4 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "hb5", "Average n-n+5 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, FALSE, "JCaHa", "J-Coupling Values", "Residue", "Hz", 0.0 }, { NULL, NULL, FALSE, "helicity", "Helicity per Residue", "Residue", "% of time", 0.0 } }; output_env_t oenv; char buf[54]; t_trxstatus *status; int natoms, nre, nres; t_bb *bb; int i, j, m, nall, nbb, nca, teller, nSel = 0; atom_id *bbindex, *caindex, *allindex; t_topology *top; int ePBC; rvec *x, *xref; real t; real rms; matrix box; gmx_rmpbc_t gpbc = NULL; gmx_bool bRange; t_filenm fnm[] = { { efTPR, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efSTO, "-cz", "zconf", ffWRITE }, }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bRange = (opt2parg_bSet("-ahxstart", asize(pa), pa) && opt2parg_bSet("-ahxend", asize(pa), pa)); top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC); natoms = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box); if (natoms != top->atoms.nr) { gmx_fatal(FARGS, "Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)", top->atoms.nr, natoms); } bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex, top->atoms.atomname, top->atoms.atom, top->atoms.resinfo); snew(bbindex, natoms); snew(caindex, nres); fprintf(stderr, "nall=%d\n", nall); /* Open output files, default x-axis is time */ for (i = 0; (i < efhNR); i++) { sprintf(buf, "%s.xvg", xf[i].filenm); remove(buf); xf[i].fp = xvgropen(buf, xf[i].title, xf[i].xaxis ? xf[i].xaxis : "Time (ps)", xf[i].yaxis, oenv); if (xf[i].bfp2) { sprintf(buf, "%s.out", xf[i].filenm); remove(buf); xf[i].fp2 = gmx_ffopen(buf, "w"); } } /* Read reference frame from tpx file to compute helix length */ snew(xref, top->atoms.nr); read_tpx(ftp2fn(efTPR, NFILE, fnm), NULL, NULL, &natoms, xref, NULL, NULL, NULL); calc_hxprops(nres, bb, xref); do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, bRange, rStart, rEnd); sfree(xref); if (bDBG) { fprintf(stderr, "nca=%d, nbb=%d\n", nca, nbb); pr_bb(stdout, nres, bb); } gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); teller = 0; do { if ((teller++ % 10) == 0) { fprintf(stderr, "\rt=%.2f", t); } gmx_rmpbc(gpbc, natoms, box, x); calc_hxprops(nres, bb, x); if (bCheck) { do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, FALSE, 0, 0); } if (nca >= 5) { rms = fit_ahx(nres, bb, natoms, nall, allindex, x, nca, caindex, bFit); if (teller == 1) { write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", &(top->atoms), x, NULL, ePBC, box); } xf[efhRAD].val = radius(xf[efhRAD].fp2, nca, caindex, x); xf[efhTWIST].val = twist(nca, caindex, x); xf[efhRISE].val = rise(nca, caindex, x); xf[efhLEN].val = ahx_len(nca, caindex, x); xf[efhCD222].val = ellipticity(nres, bb); xf[efhDIP].val = dip(nbb, bbindex, x, top->atoms.atom); xf[efhRMS].val = rms; xf[efhCPHI].val = ca_phi(nca, caindex, x); xf[efhPPRMS].val = pprms(xf[efhPPRMS].fp2, nres, bb); for (j = 0; (j <= efhCPHI); j++) { fprintf(xf[j].fp, "%10g %10g\n", t, xf[j].val); } av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2, t, nres, bb); av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2, xf[efhHB4].fp, xf[efhHB4].fp2, xf[efhHB5].fp, xf[efhHB5].fp2, t, nres, bb); } } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); gmx_rmpbc_done(gpbc); close_trj(status); for (i = 0; (i < nres); i++) { if (bb[i].nrms > 0) { fprintf(xf[efhRMSA].fp, "%10d %10g\n", r0+i, bb[i].rmsa/bb[i].nrms); } fprintf(xf[efhAHX].fp, "%10d %10g\n", r0+i, (bb[i].nhx*100.0)/(real )teller); fprintf(xf[efhJCA].fp, "%10d %10g\n", r0+i, 140.3+(bb[i].jcaha/(double)teller)); } for (i = 0; (i < efhNR); i++) { gmx_ffclose(xf[i].fp); if (xf[i].bfp2) { gmx_ffclose(xf[i].fp2); } do_view(oenv, xf[i].filenm, "-nxy"); } return 0; }
int gmx_current(int argc, char *argv[]) { static int nshift = 1000; static real temp = 300.0; static real trust = 0.25; static real eps_rf = 0.0; static gmx_bool bNoJump = TRUE; static real bfit = 100.0; static real bvit = 0.5; static real efit = 400.0; static real evit = 5.0; t_pargs pa[] = { { "-sh", FALSE, etINT, {&nshift}, "Shift of the frames for averaging the correlation functions and the mean-square displacement."}, { "-nojump", FALSE, etBOOL, {&bNoJump}, "Removes jumps of atoms across the box."}, { "-eps", FALSE, etREAL, {&eps_rf}, "Dielectric constant of the surrounding medium. The value zero corresponds to infinity (tin-foil boundary conditions)."}, { "-bfit", FALSE, etREAL, {&bfit}, "Begin of the fit of the straight line to the MSD of the translational fraction of the dipole moment."}, { "-efit", FALSE, etREAL, {&efit}, "End of the fit of the straight line to the MSD of the translational fraction of the dipole moment."}, { "-bvit", FALSE, etREAL, {&bvit}, "Begin of the fit of the current autocorrelation function to a*t^b."}, { "-evit", FALSE, etREAL, {&evit}, "End of the fit of the current autocorrelation function to a*t^b."}, { "-tr", FALSE, etREAL, {&trust}, "Fraction of the trajectory taken into account for the integral."}, { "-temp", FALSE, etREAL, {&temp}, "Temperature for calculating epsilon."} }; output_env_t oenv; t_topology top; char title[STRLEN]; char **grpname = NULL; const char *indexfn; t_trxframe fr; real *mass2 = NULL; rvec *xtop, *vtop; matrix box; atom_id *index0; int *indexm = NULL; int isize; t_trxstatus *status; int flags = 0; gmx_bool bTop; gmx_bool bNEU; gmx_bool bACF; gmx_bool bINT; int ePBC = -1; int natoms; int nmols; int i, j, k = 0, l; int step; real t; real lambda; real *qmol; FILE *outf = NULL; FILE *outi = NULL; FILE *tfile = NULL; FILE *mcor = NULL; FILE *fmj = NULL; FILE *fmd = NULL; FILE *fmjdsp = NULL; FILE *fcur = NULL; t_filenm fnm[] = { { efTPS, NULL, NULL, ffREAD }, /* this is for the topology */ { efNDX, NULL, NULL, ffOPTRD }, { efTRX, "-f", NULL, ffREAD }, /* and this for the trajectory */ { efXVG, "-o", "current", ffWRITE }, { efXVG, "-caf", "caf", ffOPTWR }, { efXVG, "-dsp", "dsp", ffWRITE }, { efXVG, "-md", "md", ffWRITE }, { efXVG, "-mj", "mj", ffWRITE }, { efXVG, "-mc", "mc", ffOPTWR } }; #define NFILE asize(fnm) const char *desc[] = { "[THISMODULE] is a tool for calculating the current autocorrelation function, the correlation", "of the rotational and translational dipole moment of the system, and the resulting static", "dielectric constant. To obtain a reasonable result, the index group has to be neutral.", "Furthermore, the routine is capable of extracting the static conductivity from the current ", "autocorrelation function, if velocities are given. Additionally, an Einstein-Helfand fit ", "can be used to obtain the static conductivity." "[PAR]", "The flag [TT]-caf[tt] is for the output of the current autocorrelation function and [TT]-mc[tt] writes the", "correlation of the rotational and translational part of the dipole moment in the corresponding", "file. However, this option is only available for trajectories containing velocities.", "Options [TT]-sh[tt] and [TT]-tr[tt] are responsible for the averaging and integration of the", "autocorrelation functions. Since averaging proceeds by shifting the starting point", "through the trajectory, the shift can be modified with [TT]-sh[tt] to enable the choice of uncorrelated", "starting points. Towards the end, statistical inaccuracy grows and integrating the", "correlation function only yields reliable values until a certain point, depending on", "the number of frames. The option [TT]-tr[tt] controls the region of the integral taken into account", "for calculating the static dielectric constant.", "[PAR]", "Option [TT]-temp[tt] sets the temperature required for the computation of the static dielectric constant.", "[PAR]", "Option [TT]-eps[tt] controls the dielectric constant of the surrounding medium for simulations using", "a Reaction Field or dipole corrections of the Ewald summation ([TT]-eps[tt]=0 corresponds to", "tin-foil boundary conditions).", "[PAR]", "[TT]-[no]nojump[tt] unfolds the coordinates to allow free diffusion. This is required to get a continuous", "translational dipole moment, required for the Einstein-Helfand fit. The results from the fit allow", "the determination of the dielectric constant for system of charged molecules. However, it is also possible to extract", "the dielectric constant from the fluctuations of the total dipole moment in folded coordinates. But this", "option has to be used with care, since only very short time spans fulfill the approximation that the density", "of the molecules is approximately constant and the averages are already converged. To be on the safe side,", "the dielectric constant should be calculated with the help of the Einstein-Helfand method for", "the translational part of the dielectric constant." }; /* At first the arguments will be parsed and the system information processed */ if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bACF = opt2bSet("-caf", NFILE, fnm); bINT = opt2bSet("-mc", NFILE, fnm); bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, &vtop, box, TRUE); sfree(xtop); sfree(vtop); indexfn = ftp2fn_null(efNDX, NFILE, fnm); snew(grpname, 1); get_index(&(top.atoms), indexfn, 1, &isize, &index0, grpname); flags = flags | TRX_READ_X | TRX_READ_V; read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags); snew(mass2, top.atoms.nr); snew(qmol, top.atoms.nr); bNEU = precalc(top, mass2, qmol); snew(indexm, isize); for (i = 0; i < isize; i++) { indexm[i] = index0[i]; } nmols = isize; index_atom2mol(&nmols, indexm, &top.mols); if (fr.bV) { if (bACF) { outf = xvgropen(opt2fn("-caf", NFILE, fnm), "Current autocorrelation function", output_env_get_xvgr_tlabel(oenv), "ACF (e nm/ps)\\S2", oenv); fprintf(outf, "# time\t acf\t average \t std.dev\n"); } fcur = xvgropen(opt2fn("-o", NFILE, fnm), "Current", output_env_get_xvgr_tlabel(oenv), "J(t) (e nm/ps)", oenv); fprintf(fcur, "# time\t Jx\t Jy \t J_z \n"); if (bINT) { mcor = xvgropen(opt2fn("-mc", NFILE, fnm), "M\\sD\\N - current autocorrelation function", output_env_get_xvgr_tlabel(oenv), "< M\\sD\\N (0)\\c7\\CJ(t) > (e nm/ps)\\S2", oenv); fprintf(mcor, "# time\t M_D(0) J(t) acf \t Integral acf\n"); } } fmj = xvgropen(opt2fn("-mj", NFILE, fnm), "Averaged translational part of M", output_env_get_xvgr_tlabel(oenv), "< M\\sJ\\N > (enm)", oenv); fprintf(fmj, "# time\t x\t y \t z \t average of M_J^2 \t std.dev\n"); fmd = xvgropen(opt2fn("-md", NFILE, fnm), "Averaged rotational part of M", output_env_get_xvgr_tlabel(oenv), "< M\\sD\\N > (enm)", oenv); fprintf(fmd, "# time\t x\t y \t z \t average of M_D^2 \t std.dev\n"); fmjdsp = xvgropen(opt2fn("-dsp", NFILE, fnm), "MSD of the squared translational dipole moment M", output_env_get_xvgr_tlabel(oenv), "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N", oenv); /* System information is read and prepared, dielectric() processes the frames * and calculates the requested quantities */ dielectric(fmj, fmd, outf, fcur, mcor, fmjdsp, bNoJump, bACF, bINT, ePBC, top, fr, temp, trust, bfit, efit, bvit, evit, status, isize, nmols, nshift, index0, indexm, mass2, qmol, eps_rf, oenv); gmx_ffclose(fmj); gmx_ffclose(fmd); gmx_ffclose(fmjdsp); if (bACF) { gmx_ffclose(outf); } if (bINT) { gmx_ffclose(mcor); } return 0; }
int gmx_sigeps(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] is a simple utility that converts C6/C12 or C6/Cn combinations", "to [GRK]sigma[grk] and [GRK]epsilon[grk], or vice versa. It can also plot the potential", "in file. In addition, it makes an approximation of a Buckingham potential", "to a Lennard-Jones potential." }; static real c6 = 1.0e-3, cn = 1.0e-6, qi = 0, qj = 0, sig = 0.3, eps = 1, sigfac = 0.7; static real Abh = 1e5, Bbh = 32, Cbh = 1e-3; static int npow = 12; t_pargs pa[] = { { "-c6", FALSE, etREAL, {&c6}, "C6" }, { "-cn", FALSE, etREAL, {&cn}, "Constant for repulsion" }, { "-pow", FALSE, etINT, {&npow}, "Power of the repulsion term" }, { "-sig", FALSE, etREAL, {&sig}, "[GRK]sigma[grk]" }, { "-eps", FALSE, etREAL, {&eps}, "[GRK]epsilon[grk]" }, { "-A", FALSE, etREAL, {&Abh}, "Buckingham A" }, { "-B", FALSE, etREAL, {&Bbh}, "Buckingham B" }, { "-C", FALSE, etREAL, {&Cbh}, "Buckingham C" }, { "-qi", FALSE, etREAL, {&qi}, "qi" }, { "-qj", FALSE, etREAL, {&qj}, "qj" }, { "-sigfac", FALSE, etREAL, {&sigfac}, "Factor in front of [GRK]sigma[grk] for starting the plot" } }; t_filenm fnm[] = { { efXVG, "-o", "potje", ffWRITE } }; output_env_t oenv; #define NFILE asize(fnm) const char *legend[] = { "Lennard-Jones", "Buckingham" }; FILE *fp; int i; gmx_bool bBham; real qq, x, oldx, minimum, mval, dp[2], pp[2]; int cur = 0; #define next (1-cur) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bBham = (opt2parg_bSet("-A", asize(pa), pa) || opt2parg_bSet("-B", asize(pa), pa) || opt2parg_bSet("-C", asize(pa), pa)); if (bBham) { c6 = Cbh; sig = pow((6.0/npow)*pow(npow/Bbh, npow-6.0), 1.0/(npow-6.0)); eps = c6/(4*pow(sig, 6.0)); cn = 4*eps*pow(sig, npow); } else { if (opt2parg_bSet("-sig", asize(pa), pa) || opt2parg_bSet("-eps", asize(pa), pa)) { c6 = 4*eps*pow(sig, 6); cn = 4*eps*pow(sig, npow); } else if (opt2parg_bSet("-c6", asize(pa), pa) || opt2parg_bSet("-cn", asize(pa), pa) || opt2parg_bSet("-pow", asize(pa), pa)) { sig = pow(cn/c6, 1.0/(npow-6.0)); eps = 0.25*c6*pow(sig, -6.0); } else { sig = eps = 0; } printf("c6 = %12.5e, c%d = %12.5e\n", c6, npow, cn); printf("sigma = %12.5f, epsilon = %12.5f\n", sig, eps); minimum = pow(npow/6.0*pow(sig, npow-6.0), 1.0/(npow-6)); printf("Van der Waals minimum at %g, V = %g\n\n", minimum, pot(minimum, 0, c6, cn, npow)); printf("Fit of Lennard Jones (%d-6) to Buckingham:\n", npow); Bbh = npow/minimum; Cbh = c6; Abh = 4*eps*pow(sig/minimum, npow)*exp(npow); printf("A = %g, B = %g, C = %g\n", Abh, Bbh, Cbh); } qq = qi*qj; fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Potential", "r (nm)", "E (kJ/mol)", oenv); xvgr_legend(fp, asize(legend), legend, oenv); if (sig == 0) { sig = 0.25; } minimum = -1; mval = 0; oldx = 0; for (i = 0; (i < 100); i++) { x = sigfac*sig+sig*i*0.02; dp[next] = dpot(x, qq, c6, cn, npow); fprintf(fp, "%10g %10g %10g\n", x, pot(x, qq, c6, cn, npow), bhpot(x, Abh, Bbh, Cbh)); if (qq != 0) { if ((i > 0) && (dp[cur]*dp[next] < 0)) { minimum = oldx + dp[cur]*(x-oldx)/(dp[cur]-dp[next]); mval = pot(minimum, qq, c6, cn, npow); printf("Van der Waals + Coulomb minimum at r = %g (nm). Value = %g (kJ/mol)\n", minimum, mval); } } cur = next; oldx = x; } xvgrclose(fp); do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL); return 0; }
gmx_bool update_forcefield(FILE *fplog, int nfile, const t_filenm fnm[], t_forcerec *fr, int natoms, rvec x[], matrix box) { static int ntry, ntried; int i, j; gmx_bool bDone; /* First time around we have to read the parameters */ if (nparm == 0) { range = read_range(ftp2fn(efDAT, nfile, fnm), &nparm); if (nparm == 0) { gmx_fatal(FARGS, "No correct parameter info in %s", ftp2fn(efDAT, nfile, fnm)); } snew(param_val, nparm); if (opt2bSet("-ga", nfile, fnm)) { /* Genetic algorithm time */ ga = init_ga(fplog, opt2fn("-ga", nfile, fnm), nparm, range); } else { /* Determine the grid size */ ntry = 1; for (i = 0; (i < nparm); i++) { ntry *= range[i].np; } ntried = 0; fprintf(fplog, "Going to try %d different combinations of %d parameters\n", ntry, nparm); } } if (ga) { update_ga(fplog, range, ga); } else { /* Increment the counter * Non-trivial, since this is nparm nested loops in principle */ for (i = 0; (i < nparm); i++) { if (param_val[i] < (range[i].np-1)) { param_val[i]++; for (j = 0; (j < i); j++) { param_val[j] = 0; } ntried++; break; } } if (i == nparm) { fprintf(fplog, "Finished with %d out of %d iterations\n", ntried+1, ntry); return TRUE; } } /* Now do the real updating */ update_ff(fr, nparm, range, param_val); /* Update box and coordinates if necessary */ scale_box(natoms, x, box); return FALSE; }
int gmx_helixorient(int argc,char *argv[]) { const char *desc[] = { "[TT]g_helixorient[tt] calculates the coordinates and direction of the average", "axis inside an alpha helix, and the direction/vectors of both the", "C[GRK]alpha[grk] and (optionally) a sidechain atom relative to the axis.[PAR]", "As input, you need to specify an index group with C[GRK]alpha[grk] atoms", "corresponding to an [GRK]alpha[grk]-helix of continuous residues. Sidechain", "directions require a second index group of the same size, containing", "the heavy atom in each residue that should represent the sidechain.[PAR]", "[BB]Note[bb] that this program does not do any fitting of structures.[PAR]", "We need four C[GRK]alpha[grk] coordinates to define the local direction of the helix", "axis.[PAR]", "The tilt/rotation is calculated from Euler rotations, where we define", "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as [IT]y[it], and the", "[IT]z[it]-axis from their cross product. We use the Euler Y-Z-X rotation, meaning", "we first tilt the helix axis (1) around and (2) orthogonal to the residues", "vector, and finally apply the (3) rotation around it. For debugging or other", "purposes, we also write out the actual Euler rotation angles as [TT]theta[1-3].xvg[tt]" }; t_topology *top=NULL; real t; rvec *x=NULL,dx; matrix box; t_trxstatus *status; int natoms; real theta1,theta2,theta3; int d,i,j,teller=0; int iCA,iSC; atom_id *ind_CA; atom_id *ind_SC; char *gn_CA; char *gn_SC; rvec averageaxis; rvec v1,v2,p1,p2,vtmp,vproj; rvec *x_CA,*x_SC; rvec *r12; rvec *r23; rvec *r34; rvec *diff13; rvec *diff24; rvec *helixaxis; rvec *residuehelixaxis; rvec *residueorigin; rvec *residuevector; rvec *sidechainvector; rvec axes_t0[3]; rvec axes[3]; rvec *residuehelixaxis_t0; rvec *residuevector_t0; rvec *axis3_t0; rvec *residuehelixaxis_tlast; rvec *residuevector_tlast; rvec *axis3_tlast; rvec refaxes[3],newaxes[3]; rvec unitaxes[3]; rvec rot_refaxes[3],rot_newaxes[3]; real tilt,rotation; rvec *axis3; real *twist,*residuetwist; real *radius,*residueradius; real *rise,*residuerise; real *residuebending; real tmp,rotangle; real weight[3]; t_pbc pbc; matrix A; FILE *fpaxis,*fpcenter,*fptilt,*fprotation; FILE *fpradius,*fprise,*fptwist; FILE *fptheta1,*fptheta2,*fptheta3; FILE *fpbending; int ePBC; output_env_t oenv; gmx_rmpbc_t gpbc=NULL; static gmx_bool bSC=FALSE; static gmx_bool bIncremental = FALSE; static t_pargs pa[] = { { "-sidechain", FALSE, etBOOL, {&bSC}, "Calculate sidechain directions relative to helix axis too." }, { "-incremental", FALSE, etBOOL, {&bIncremental}, "Calculate incremental rather than total rotation/tilt." }, }; #define NPA asize(pa) t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-oaxis", "helixaxis", ffWRITE }, { efDAT, "-ocenter", "center", ffWRITE }, { efXVG, "-orise", "rise",ffWRITE }, { efXVG, "-oradius", "radius",ffWRITE }, { efXVG, "-otwist", "twist",ffWRITE }, { efXVG, "-obending", "bending",ffWRITE }, { efXVG, "-otilt", "tilt", ffWRITE }, { efXVG, "-orot", "rotation",ffWRITE } }; #define NFILE asize(fnm) parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL,&oenv); top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC); for(i=0;i<3;i++) weight[i]=1.0; /* read index files */ printf("Select a group of Calpha atoms corresponding to a single continuous helix:\n"); get_index(&(top->atoms),ftp2fn_null(efNDX,NFILE,fnm),1,&iCA,&ind_CA,&gn_CA); snew(x_CA,iCA); snew(x_SC,iCA); /* sic! */ snew(r12,iCA-3); snew(r23,iCA-3); snew(r34,iCA-3); snew(diff13,iCA-3); snew(diff24,iCA-3); snew(helixaxis,iCA-3); snew(twist,iCA); snew(residuetwist,iCA); snew(radius,iCA); snew(residueradius,iCA); snew(rise,iCA); snew(residuerise,iCA); snew(residueorigin,iCA); snew(residuehelixaxis,iCA); snew(residuevector,iCA); snew(sidechainvector,iCA); snew(residuebending,iCA); snew(residuehelixaxis_t0,iCA); snew(residuevector_t0,iCA); snew(axis3_t0,iCA); snew(residuehelixaxis_tlast,iCA); snew(residuevector_tlast,iCA); snew(axis3_tlast,iCA); snew(axis3,iCA); if(bSC) { printf("Select a group of atoms defining the sidechain direction (1/residue):\n"); get_index(&(top->atoms),ftp2fn_null(efNDX,NFILE,fnm),1,&iSC,&ind_SC,&gn_SC); if(iSC!=iCA) gmx_fatal(FARGS,"Number of sidechain atoms (%d) != number of CA atoms (%d)",iSC,iCA); } natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); fpaxis=ffopen(opt2fn("-oaxis",NFILE,fnm),"w"); fpcenter=ffopen(opt2fn("-ocenter",NFILE,fnm),"w"); fprise=ffopen(opt2fn("-orise",NFILE,fnm),"w"); fpradius=ffopen(opt2fn("-oradius",NFILE,fnm),"w"); fptwist=ffopen(opt2fn("-otwist",NFILE,fnm),"w"); fpbending=ffopen(opt2fn("-obending",NFILE,fnm),"w"); fptheta1=ffopen("theta1.xvg","w"); fptheta2=ffopen("theta2.xvg","w"); fptheta3=ffopen("theta3.xvg","w"); if(bIncremental) { fptilt=xvgropen(opt2fn("-otilt",NFILE,fnm), "Incremental local helix tilt","Time(ps)","Tilt (degrees)", oenv); fprotation=xvgropen(opt2fn("-orot",NFILE,fnm), "Incremental local helix rotation","Time(ps)", "Rotation (degrees)",oenv); } else { fptilt=xvgropen(opt2fn("-otilt",NFILE,fnm), "Cumulative local helix tilt","Time(ps)","Tilt (degrees)",oenv); fprotation=xvgropen(opt2fn("-orot",NFILE,fnm), "Cumulative local helix rotation","Time(ps)", "Rotation (degrees)",oenv); } clear_rvecs(3,unitaxes); unitaxes[0][0]=1; unitaxes[1][1]=1; unitaxes[2][2]=1; gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box); do { /* initialisation for correct distance calculations */ set_pbc(&pbc,ePBC,box); /* make molecules whole again */ gmx_rmpbc(gpbc,natoms,box,x); /* copy coords to our smaller arrays */ for(i=0;i<iCA;i++) { copy_rvec(x[ind_CA[i]],x_CA[i]); if(bSC) { copy_rvec(x[ind_SC[i]],x_SC[i]); } } for(i=0;i<iCA-3;i++) { rvec_sub(x_CA[i+1],x_CA[i],r12[i]); rvec_sub(x_CA[i+2],x_CA[i+1],r23[i]); rvec_sub(x_CA[i+3],x_CA[i+2],r34[i]); rvec_sub(r12[i],r23[i],diff13[i]); rvec_sub(r23[i],r34[i],diff24[i]); /* calculate helix axis */ cprod(diff13[i],diff24[i],helixaxis[i]); svmul(1.0/norm(helixaxis[i]),helixaxis[i],helixaxis[i]); tmp = cos_angle(diff13[i],diff24[i]); twist[i] = 180.0/M_PI * acos( tmp ); radius[i] = sqrt( norm(diff13[i])*norm(diff24[i]) ) / (2.0* (1.0-tmp) ); rise[i]=fabs(iprod(r23[i],helixaxis[i])); svmul(radius[i]/norm(diff13[i]),diff13[i],v1); svmul(radius[i]/norm(diff24[i]),diff24[i],v2); rvec_sub(x_CA[i+1],v1,residueorigin[i+1]); rvec_sub(x_CA[i+2],v2,residueorigin[i+2]); } residueradius[0]=residuetwist[0]=residuerise[0]=0; residueradius[1]=radius[0]; residuetwist[1]=twist[0]; residuerise[1]=rise[0]; residuebending[0]=residuebending[1]=0; for(i=2;i<iCA-2;i++) { residueradius[i]=0.5*(radius[i-2]+radius[i-1]); residuetwist[i]=0.5*(twist[i-2]+twist[i-1]); residuerise[i]=0.5*(rise[i-2]+rise[i-1]); residuebending[i] = 180.0/M_PI*acos( cos_angle(helixaxis[i-2],helixaxis[i-1]) ); } residueradius[iCA-2]=radius[iCA-4]; residuetwist[iCA-2]=twist[iCA-4]; residuerise[iCA-2]=rise[iCA-4]; residueradius[iCA-1]=residuetwist[iCA-1]=residuerise[iCA-1]=0; residuebending[iCA-2]=residuebending[iCA-1]=0; clear_rvec(residueorigin[0]); clear_rvec(residueorigin[iCA-1]); /* average helix axes to define them on the residues. * Just extrapolate second first/list atom. */ copy_rvec(helixaxis[0],residuehelixaxis[0]); copy_rvec(helixaxis[0],residuehelixaxis[1]); for(i=2;i<iCA-2;i++) { rvec_add(helixaxis[i-2],helixaxis[i-1],residuehelixaxis[i]); svmul(0.5,residuehelixaxis[i],residuehelixaxis[i]); } copy_rvec(helixaxis[iCA-4],residuehelixaxis[iCA-2]); copy_rvec(helixaxis[iCA-4],residuehelixaxis[iCA-1]); /* Normalize the axis */ for(i=0;i<iCA;i++) { svmul(1.0/norm(residuehelixaxis[i]),residuehelixaxis[i],residuehelixaxis[i]); } /* calculate vector from origin to residue CA */ fprintf(fpaxis,"%15.12g ",t); fprintf(fpcenter,"%15.12g ",t); fprintf(fprise,"%15.12g ",t); fprintf(fpradius,"%15.12g ",t); fprintf(fptwist,"%15.12g ",t); fprintf(fpbending,"%15.12g ",t); for(i=0;i<iCA;i++) { if(i==0 || i==iCA-1) { fprintf(fpaxis,"%15.12g %15.12g %15.12g ",0.0,0.0,0.0); fprintf(fpcenter,"%15.12g %15.12g %15.12g ",0.0,0.0,0.0); fprintf(fprise,"%15.12g ",0.0); fprintf(fpradius,"%15.12g ",0.0); fprintf(fptwist,"%15.12g ",0.0); fprintf(fpbending,"%15.12g ",0.0); } else { rvec_sub( bSC ? x_SC[i] : x_CA[i] ,residueorigin[i], residuevector[i]); svmul(1.0/norm(residuevector[i]),residuevector[i],residuevector[i]); cprod(residuehelixaxis[i],residuevector[i],axis3[i]); fprintf(fpaxis,"%15.12g %15.12g %15.12g ",residuehelixaxis[i][0],residuehelixaxis[i][1],residuehelixaxis[i][2]); fprintf(fpcenter,"%15.12g %15.12g %15.12g ",residueorigin[i][0],residueorigin[i][1],residueorigin[i][2]); fprintf(fprise,"%15.12g ",residuerise[i]); fprintf(fpradius,"%15.12g ",residueradius[i]); fprintf(fptwist,"%15.12g ",residuetwist[i]); fprintf(fpbending,"%15.12g ",residuebending[i]); /* angle with local vector? */ /* printf("res[%2d]: axis: %g %g %g origin: %g %g %g vector: %g %g %g angle: %g\n",i, residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2], residueorigin[i][0], residueorigin[i][1], residueorigin[i][2], residuevector[i][0], residuevector[i][1], residuevector[i][2], 180.0/M_PI*acos( cos_angle(residuevector[i],residuehelixaxis[i]) )); */ /* fprintf(fp,"%15.12g %15.12g %15.12g %15.12g %15.12g %15.12g\n", residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2], residuevector[i][0], residuevector[i][1], residuevector[i][2]); */ } } fprintf(fprise,"\n"); fprintf(fpradius,"\n"); fprintf(fpaxis,"\n"); fprintf(fpcenter,"\n"); fprintf(fptwist,"\n"); fprintf(fpbending,"\n"); if(teller==0) { for(i=0;i<iCA;i++) { copy_rvec(residuehelixaxis[i],residuehelixaxis_t0[i]); copy_rvec(residuevector[i],residuevector_t0[i]); copy_rvec(axis3[i],axis3_t0[i]); } } else { fprintf(fptilt,"%15.12g ",t); fprintf(fprotation,"%15.12g ",t); fprintf(fptheta1,"%15.12g ",t); fprintf(fptheta2,"%15.12g ",t); fprintf(fptheta3,"%15.12g ",t); for(i=0;i<iCA;i++) { if(i==0 || i==iCA-1) { tilt=rotation=0; } else { if(!bIncremental) { /* Total rotation & tilt */ copy_rvec(residuehelixaxis_t0[i],refaxes[0]); copy_rvec(residuevector_t0[i],refaxes[1]); copy_rvec(axis3_t0[i],refaxes[2]); } else { /* Rotation/tilt since last step */ copy_rvec(residuehelixaxis_tlast[i],refaxes[0]); copy_rvec(residuevector_tlast[i],refaxes[1]); copy_rvec(axis3_tlast[i],refaxes[2]); } copy_rvec(residuehelixaxis[i],newaxes[0]); copy_rvec(residuevector[i],newaxes[1]); copy_rvec(axis3[i],newaxes[2]); /* printf("frame %d, i=%d:\n old: %g %g %g , %g %g %g , %g %g %g\n new: %g %g %g , %g %g %g , %g %g %g\n", teller,i, refaxes[0][0],refaxes[0][1],refaxes[0][2], refaxes[1][0],refaxes[1][1],refaxes[1][2], refaxes[2][0],refaxes[2][1],refaxes[2][2], newaxes[0][0],newaxes[0][1],newaxes[0][2], newaxes[1][0],newaxes[1][1],newaxes[1][2], newaxes[2][0],newaxes[2][1],newaxes[2][2]); */ /* rotate reference frame onto unit axes */ calc_fit_R(3,3,weight,unitaxes,refaxes,A); for(j=0;j<3;j++) { mvmul(A,refaxes[j],rot_refaxes[j]); mvmul(A,newaxes[j],rot_newaxes[j]); } /* Determine local rotation matrix A */ calc_fit_R(3,3,weight,rot_newaxes,rot_refaxes,A); /* Calculate euler angles, from rotation order y-z-x, where * x is helixaxis, y residuevector, and z axis3. * * A contains rotation column vectors. */ /* printf("frame %d, i=%d, A: %g %g %g , %g %g %g , %g %g %g\n", teller,i,A[0][0],A[0][1],A[0][2],A[1][0],A[1][1],A[1][2],A[2][0],A[2][1],A[2][2]); */ theta1 = 180.0/M_PI*atan2(A[0][2],A[0][0]); theta2 = 180.0/M_PI*asin(-A[0][1]); theta3 = 180.0/M_PI*atan2(A[2][1],A[1][1]); tilt = sqrt(theta1*theta1+theta2*theta2); rotation = theta3; fprintf(fptheta1,"%15.12g ",theta1); fprintf(fptheta2,"%15.12g ",theta2); fprintf(fptheta3,"%15.12g ",theta3); } fprintf(fptilt,"%15.12g ",tilt); fprintf(fprotation,"%15.12g ",rotation); } fprintf(fptilt,"\n"); fprintf(fprotation,"\n"); fprintf(fptheta1,"\n"); fprintf(fptheta2,"\n"); fprintf(fptheta3,"\n"); } for(i=0;i<iCA;i++) { copy_rvec(residuehelixaxis[i],residuehelixaxis_tlast[i]); copy_rvec(residuevector[i],residuevector_tlast[i]); copy_rvec(axis3[i],axis3_tlast[i]); } teller++; } while (read_next_x(oenv,status,&t,natoms,x,box)); gmx_rmpbc_done(gpbc); ffclose(fpaxis); ffclose(fpcenter); ffclose(fptilt); ffclose(fprotation); ffclose(fprise); ffclose(fpradius); ffclose(fptwist); ffclose(fpbending); ffclose(fptheta1); ffclose(fptheta2); ffclose(fptheta3); close_trj(status); thanx(stderr); return 0; }
int gmx_spatial(int argc,char *argv[]) { const char *desc[] = { "[TT]g_spatial[tt] calculates the spatial distribution function and ", "outputs it in a form that can be read by VMD as Gaussian98 cube format. ", "This was developed from template.c (GROMACS-3.3). ", "For a system of 32,000 atoms and a 50 ns trajectory, the SDF can be generated ", "in about 30 minutes, with most of the time dedicated to the two runs through ", "[TT]trjconv[tt] that are required to center everything properly. ", "This also takes a whole bunch of space (3 copies of the [TT].xtc[tt] file). ", "Still, the pictures are pretty and very informative when the fitted selection is properly made. ", "3-4 atoms in a widely mobile group (like a free amino acid in solution) works ", "well, or select the protein backbone in a stable folded structure to get the SDF ", "of solvent and look at the time-averaged solvation shell. ", "It is also possible using this program to generate the SDF based on some arbitrary ", "Cartesian coordinate. To do that, simply omit the preliminary [TT]trjconv[tt] steps. \n", "USAGE: \n", "1. Use [TT]make_ndx[tt] to create a group containing the atoms around which you want the SDF \n", "2. [TT]trjconv -s a.tpr -f a.xtc -o b.xtc -center tric -ur compact -pbc none[tt] \n", "3. [TT]trjconv -s a.tpr -f b.xtc -o c.xtc -fit rot+trans[tt] \n", "4. run [TT]g_spatial[tt] on the [TT].xtc[tt] output of step #3. \n", "5. Load [TT]grid.cube[tt] into VMD and view as an isosurface. \n", "[BB]Note[bb] that systems such as micelles will require [TT]trjconv -pbc cluster[tt] between steps 1 and 2\n", "WARNINGS:[BR]", "The SDF will be generated for a cube that contains all bins that have some non-zero occupancy. ", "However, the preparatory [TT]-fit rot+trans[tt] option to [TT]trjconv[tt] implies that your system will be rotating ", "and translating in space (in order that the selected group does not). Therefore the values that are ", "returned will only be valid for some region around your central group/coordinate that has full overlap ", "with system volume throughout the entire translated/rotated system over the course of the trajectory. ", "It is up to the user to ensure that this is the case. \n", "BUGS:[BR]", "When the allocated memory is not large enough, a segmentation fault may occur. This is usually detected ", "and the program is halted prior to the fault while displaying a warning message suggesting the use of the [TT]-nab[tt] (Number of Additional Bins)", "option. However, the program does not detect all such events. If you encounter a segmentation fault, run it again ", "with an increased [TT]-nab[tt] value. \n", "RISKY OPTIONS:[BR]", "To reduce the amount of space and time required, you can output only the coords ", "that are going to be used in the first and subsequent run through [TT]trjconv[tt]. ", "However, be sure to set the [TT]-nab[tt] option to a sufficiently high value since ", "memory is allocated for cube bins based on the initial coordinates and the [TT]-nab[tt] ", "option value. \n" }; static gmx_bool bPBC=FALSE; static gmx_bool bSHIFT=FALSE; static int iIGNOREOUTER=-1; /*Positive values may help if the surface is spikey */ static gmx_bool bCUTDOWN=TRUE; static real rBINWIDTH=0.05; /* nm */ static gmx_bool bCALCDIV=TRUE; static int iNAB=4; t_pargs pa[] = { { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions for computing distances" }, { "-div", FALSE, etBOOL, {&bCALCDIV}, "Calculate and apply the divisor for bin occupancies based on atoms/minimal cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to get accurate counts per frame" }, { "-ign", FALSE, etINT, {&iIGNOREOUTER}, "Do not display this number of outer cubes (positive values may reduce boundary speckles; -1 ensures outer surface is visible)" }, /* { "-cut", bCUTDOWN, etBOOL, {&bCUTDOWN},*/ /* "Display a total cube that is of minimal size" }, */ { "-bin", FALSE, etREAL, {&rBINWIDTH}, "Width of the bins (nm)" }, { "-nab", FALSE, etINT, {&iNAB}, "Number of additional bins to ensure proper memory allocation" } }; double MINBIN[3]; double MAXBIN[3]; t_topology top; int ePBC; char title[STRLEN]; t_trxframe fr; rvec *xtop,*shx[26]; matrix box,box_pbc; t_trxstatus *status; int flags = TRX_READ_X; t_pbc pbc; t_atoms *atoms; int natoms; char *grpnm,*grpnmp; atom_id *index,*indexp; int i,nidx,nidxp; int v; int j,k; long ***bin=(long ***)NULL; long nbin[3]; FILE *flp; long x,y,z,minx,miny,minz,maxx,maxy,maxz; long numfr, numcu; long tot,max,min; double norm; output_env_t oenv; gmx_rmpbc_t gpbc=NULL; t_filenm fnm[] = { { efTPS, NULL, NULL, ffREAD }, /* this is for the topology */ { efTRX, "-f", NULL, ffREAD }, /* and this for the trajectory */ { efNDX, NULL, NULL, ffOPTRD } }; #define NFILE asize(fnm) /* This is the routine responsible for adding default options, * calling the X/motif interface, etc. */ parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW, 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); sfree(xtop); atoms=&(top.atoms); printf("Select group to generate SDF:\n"); get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&nidx,&index,&grpnm); printf("Select group to output coords (e.g. solute):\n"); get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&nidxp,&indexp,&grpnmp); /* The first time we read data is a little special */ natoms=read_first_frame(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags); /* Memory Allocation */ MINBIN[XX]=MAXBIN[XX]=fr.x[0][XX]; MINBIN[YY]=MAXBIN[YY]=fr.x[0][YY]; MINBIN[ZZ]=MAXBIN[ZZ]=fr.x[0][ZZ]; for(i=1; i<top.atoms.nr; ++i) { if(fr.x[i][XX]<MINBIN[XX])MINBIN[XX]=fr.x[i][XX]; if(fr.x[i][XX]>MAXBIN[XX])MAXBIN[XX]=fr.x[i][XX]; if(fr.x[i][YY]<MINBIN[YY])MINBIN[YY]=fr.x[i][YY]; if(fr.x[i][YY]>MAXBIN[YY])MAXBIN[YY]=fr.x[i][YY]; if(fr.x[i][ZZ]<MINBIN[ZZ])MINBIN[ZZ]=fr.x[i][ZZ]; if(fr.x[i][ZZ]>MAXBIN[ZZ])MAXBIN[ZZ]=fr.x[i][ZZ]; } for (i=ZZ; i>=XX; --i){ MAXBIN[i]=(ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)+(double)iNAB)*rBINWIDTH+MINBIN[i]; MINBIN[i]-=(double)iNAB*rBINWIDTH; nbin[i]=(long)ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH); } bin=(long ***)malloc(nbin[XX]*sizeof(long **)); if(!bin)mequit(); for(i=0; i<nbin[XX]; ++i){ bin[i]=(long **)malloc(nbin[YY]*sizeof(long *)); if(!bin[i])mequit(); for(j=0; j<nbin[YY]; ++j){ bin[i][j]=(long *)calloc(nbin[ZZ],sizeof(long)); if(!bin[i][j])mequit(); } } copy_mat(box,box_pbc); numfr=0; minx=miny=minz=999; maxx=maxy=maxz=0; if (bPBC) gpbc = gmx_rmpbc_init(&top.idef,ePBC,natoms,box); /* This is the main loop over frames */ do { /* Must init pbc every step because of pressure coupling */ copy_mat(box,box_pbc); if (bPBC) { gmx_rmpbc_trxfr(gpbc,&fr); set_pbc(&pbc,ePBC,box_pbc); } for(i=0; i<nidx; i++) { if(fr.x[index[i]][XX]<MINBIN[XX]||fr.x[index[i]][XX]>MAXBIN[XX]|| fr.x[index[i]][YY]<MINBIN[YY]||fr.x[index[i]][YY]>MAXBIN[YY]|| fr.x[index[i]][ZZ]<MINBIN[ZZ]||fr.x[index[i]][ZZ]>MAXBIN[ZZ]) { printf("There was an item outside of the allocated memory. Increase the value given with the -nab option.\n"); printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n",MINBIN[XX],MINBIN[YY],MINBIN[ZZ],MAXBIN[XX],MAXBIN[YY],MAXBIN[ZZ]); printf("Memory was required for [%f,%f,%f]\n",fr.x[index[i]][XX],fr.x[index[i]][YY],fr.x[index[i]][ZZ]); exit(1); } x=(long)ceil((fr.x[index[i]][XX]-MINBIN[XX])/rBINWIDTH); y=(long)ceil((fr.x[index[i]][YY]-MINBIN[YY])/rBINWIDTH); z=(long)ceil((fr.x[index[i]][ZZ]-MINBIN[ZZ])/rBINWIDTH); ++bin[x][y][z]; if(x<minx)minx=x; if(x>maxx)maxx=x; if(y<miny)miny=y; if(y>maxy)maxy=y; if(z<minz)minz=z; if(z>maxz)maxz=z; } numfr++; /* printf("%f\t%f\t%f\n",box[XX][XX],box[YY][YY],box[ZZ][ZZ]); */ } while(read_next_frame(oenv,status,&fr)); if (bPBC) gmx_rmpbc_done(gpbc); if(!bCUTDOWN){ minx=miny=minz=0; maxx=nbin[XX]; maxy=nbin[YY]; maxz=nbin[ZZ]; } /* OUTPUT */ flp=ffopen("grid.cube","w"); fprintf(flp,"Spatial Distribution Function\n"); fprintf(flp,"test\n"); fprintf(flp,"%5d%12.6f%12.6f%12.6f\n",nidxp,(MINBIN[XX]+(minx+iIGNOREOUTER)*rBINWIDTH)*10./bohr,(MINBIN[YY]+(miny+iIGNOREOUTER)*rBINWIDTH)*10./bohr,(MINBIN[ZZ]+(minz+iIGNOREOUTER)*rBINWIDTH)*10./bohr); fprintf(flp,"%5ld%12.6f%12.6f%12.6f\n",maxx-minx+1-(2*iIGNOREOUTER),rBINWIDTH*10./bohr,0.,0.); fprintf(flp,"%5ld%12.6f%12.6f%12.6f\n",maxy-miny+1-(2*iIGNOREOUTER),0.,rBINWIDTH*10./bohr,0.); fprintf(flp,"%5ld%12.6f%12.6f%12.6f\n",maxz-minz+1-(2*iIGNOREOUTER),0.,0.,rBINWIDTH*10./bohr); for(i=0; i<nidxp; i++){ v=2; if(*(top.atoms.atomname[indexp[i]][0])=='C')v=6; if(*(top.atoms.atomname[indexp[i]][0])=='N')v=7; if(*(top.atoms.atomname[indexp[i]][0])=='O')v=8; if(*(top.atoms.atomname[indexp[i]][0])=='H')v=1; if(*(top.atoms.atomname[indexp[i]][0])=='S')v=16; fprintf(flp,"%5d%12.6f%12.6f%12.6f%12.6f\n",v,0.,(double)fr.x[indexp[i]][XX]*10./bohr,(double)fr.x[indexp[i]][YY]*10./bohr,(double)fr.x[indexp[i]][ZZ]*10./bohr); } tot=0; for(k=0;k<nbin[XX];k++) { if(!(k<minx||k>maxx))continue; for(j=0;j<nbin[YY];j++) { if(!(j<miny||j>maxy))continue; for(i=0;i<nbin[ZZ];i++) { if(!(i<minz||i>maxz))continue; if(bin[k][j][i]!=0){ printf("A bin was not empty when it should have been empty. Programming error.\n"); printf("bin[%d][%d][%d] was = %ld\n",k,j,i,bin[k][j][i]); exit(1); } } } } min=999; max=0; for(k=0;k<nbin[XX];k++) { if(k<minx+iIGNOREOUTER||k>maxx-iIGNOREOUTER)continue; for(j=0;j<nbin[YY];j++) { if(j<miny+iIGNOREOUTER||j>maxy-iIGNOREOUTER)continue; for(i=0;i<nbin[ZZ];i++) { if(i<minz+iIGNOREOUTER||i>maxz-iIGNOREOUTER)continue; tot+=bin[k][j][i]; if(bin[k][j][i]>max)max=bin[k][j][i]; if(bin[k][j][i]<min)min=bin[k][j][i]; } } } numcu=(maxx-minx+1-(2*iIGNOREOUTER))*(maxy-miny+1-(2*iIGNOREOUTER))*(maxz-minz+1-(2*iIGNOREOUTER)); if(bCALCDIV){ norm=((double)numcu*(double)numfr) / (double)tot; }else{ norm=1.0; } for(k=0;k<nbin[XX];k++) { if(k<minx+iIGNOREOUTER||k>maxx-iIGNOREOUTER)continue; for(j=0;j<nbin[YY];j++) { if(j<miny+iIGNOREOUTER||j>maxy-iIGNOREOUTER)continue; for(i=0;i<nbin[ZZ];i++) { if(i<minz+iIGNOREOUTER||i>maxz-iIGNOREOUTER)continue; fprintf(flp,"%12.6f ",norm*(double)bin[k][j][i]/(double)numfr); } fprintf(flp,"\n"); } fprintf(flp,"\n"); } ffclose(flp); /* printf("x=%d to %d\n",minx,maxx); */ /* printf("y=%d to %d\n",miny,maxy); */ /* printf("z=%d to %d\n",minz,maxz); */ if(bCALCDIV){ printf("Counts per frame in all %ld cubes divided by %le\n",numcu,1.0/norm); printf("Normalized data: average %le, min %le, max %le\n",1.0,norm*(double)min/(double)numfr,norm*(double)max/(double)numfr); }else{ printf("grid.cube contains counts per frame in all %ld cubes\n",numcu); printf("Raw data: average %le, min %le, max %le\n",1.0/norm,(double)min/(double)numfr,(double)max/(double)numfr); } thanx(stderr); return 0; }
int main(int argc,char *argv[]) { int mmm[] = { 8, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 100 }; int nnn[] = { 24, 32, 48, 60, 72, 84, 96 }; #define NNN asize(nnn) FILE *fp,*fplog; int *niter; int i,j,n,nit,ntot,n3,rsize; double t,nflop,start; double *rt,*ct; t_fftgrid *g; t_commrec *cr; static gmx_bool bReproducible = FALSE; static int nnode = 1; static int nitfac = 1; t_pargs pa[] = { { "-reproducible", FALSE, etBOOL, {&bReproducible}, "Request binary reproducible results" }, { "-np", FALSE, etINT, {&nnode}, "Number of NODEs" }, { "-itfac", FALSE, etINT, {&nitfac}, "Multiply number of iterations by this" } }; static t_filenm fnm[] = { { efLOG, "-g", "fft", ffWRITE }, { efXVG, "-o", "fft", ffWRITE } }; #define NFILE asize(fnm) cr = init_par(&argc,&argv); if (MASTER(cr)) CopyRight(stdout,argv[0]); parse_common_args(&argc,argv, PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET), NFILE,fnm,asize(pa),pa,0,NULL,0,NULL); gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,1,0,&fplog); snew(niter,NNN); snew(ct,NNN); snew(rt,NNN); rsize = sizeof(real); for(i=0; (i<NNN); i++) { n = nnn[i]; if (n < 16) niter[i] = 50; else if (n < 26) niter[i] = 20; else if (n < 51) niter[i] = 10; else niter[i] = 5; niter[i] *= nitfac; nit = niter[i]; if (MASTER(cr)) fprintf(stderr,"\r3D FFT (%s precision) %3d^3, niter %3d ", (rsize == 8) ? "Double" : "Single",n,nit); g = mk_fftgrid(n,n,n,NULL,NULL,cr,bReproducible); if (PAR(cr)) start = time(NULL); else start_time(); for(j=0; (j<nit); j++) { gmxfft3D(g,GMX_FFT_REAL_TO_COMPLEX,cr); gmxfft3D(g,GMX_FFT_COMPLEX_TO_REAL,cr); } if (PAR(cr)) rt[i] = time(NULL)-start; else { update_time(); rt[i] = node_time(); } done_fftgrid(g); sfree(g); } if (MASTER(cr)) { fprintf(stderr,"\n"); fp=xvgropen(ftp2fn(efXVG,NFILE,fnm), "FFT timings","n^3","t (s)"); for(i=0; (i<NNN); i++) { n3 = 2*niter[i]*nnn[i]*nnn[i]*nnn[i]; fprintf(fp,"%10d %10g\n",nnn[i],rt[i]/(2*niter[i])); } gmx_fio_fclose(fp); } return 0; }
int main(int argc,char *argv[]) { static char *desc[] = { "[TT]do_shift[tt] reads a trajectory file and computes the chemical", "shift for each time frame (or every [BB]dt[bb] ps) by", "calling the 'total' program. If you do not have the total program,", "get it. do_shift assumes that the total executable is in", "[TT]/home/mdgroup/total/total[tt]. If that is not the case, then you should", "set an environment variable [BB]TOTAL[bb] as in: [PAR]", "[TT]setenv TOTAL /usr/local/bin/total[tt][PAR]", "where the right hand side should point to the total executable.[PAR]", "Output is printed in files [TT]shift.out[tt] where t is the time of the frame.[PAR]", "The program also needs an input file called [BB]random.dat[bb] which", "contains the random coil chemical shifts of all protons." }; static real dt=0.0; t_pargs pa[] = { { "-dt", FALSE, etREAL, { &dt }, "Time interval between frames." } }; static char *bugs[] = { "The program is very slow" }; static char *OXYGEN="O"; FILE *out,*tot,*fp; t_topology *top; t_atoms *atoms; int status,nres; real t,nt; int i,natoms,nframe=0; matrix box; int gnx; char *grpnm,*randf; atom_id *index; rvec *x,*x_s; char pdbfile[32],tmpfile[32]; char total[256],*dptr; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPX, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efOUT, "-o", "shift", ffWRITE }, { efDAT, "-d", "random", ffREAD } }; char *leg[] = { "shift","ring","anisCO","anisCN","sigmaE","sum" }; #define NFILE asize(fnm) CopyRight(stdout,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE ,NFILE,fnm, asize(pa),pa,asize(desc),desc,asize(bugs),bugs); top=read_top(ftp2fn(efTPX,NFILE,fnm)); atoms=&(top->atoms); nres=atoms->nres; for(i=0; (i<atoms->nr); i++) if ((strcmp(*atoms->atomname[i],"O1") == 0) || (strcmp(*atoms->atomname[i],"O2") == 0) || (strcmp(*atoms->atomname[i],"OXT") == 0) || (strcmp(*atoms->atomname[i],"OT") == 0)) atoms->atomname[i]=&OXYGEN; rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpnm); snew(x_s,atoms->nr); strcpy(pdbfile,"dsXXXXXX"); gmx_tmpnam(pdbfile); strcpy(tmpfile,"dsXXXXXX"); gmx_tmpnam(tmpfile); fprintf(stderr,"pdbfile = %s\ntmpfile = %s\n",pdbfile,tmpfile); if ((dptr=getenv("TOTAL")) == NULL) dptr="/home/mdgroup/total/total"; sprintf(total,"%s > /dev/null",dptr); fprintf(stderr,"total cmd='%s'\n",total); randf=ftp2fn(efDAT,NFILE,fnm); natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); if (natoms != atoms->nr) gmx_fatal(FARGS,"Trajectory does not match topology!"); out=ftp2FILE(efOUT,NFILE,fnm,"w"); xvgr_legend(out,asize(leg),leg); nt=t; do { if (t >= nt) { rm_pbc(&(top->idef),top->atoms.nr,box,x,x_s); fp=gmx_ffopen(pdbfile,"w"); write_pdbfile_indexed(fp,"Generated by do_shift", atoms,x_s,box,0,-1,gnx,index); gmx_ffclose(fp); if ((tot=popen(total,"w")) == NULL) perror("opening pipe to total"); fprintf(tot,"%s\n",pdbfile); fprintf(tot,"%s\n",tmpfile); fprintf(tot,"3\n"); fprintf(tot,"N\n"); fprintf(tot,"%s\n",randf); fprintf(tot,"N\n"); fprintf(tot,"N\n"); if (pclose(tot) != 0) perror("closing pipe to total"); cat(out,tmpfile,t); remove(pdbfile); remove(tmpfile); nt+=dt; nframe++; } } while(read_next_x(status,&t,natoms,x,box)); close_trj(status); gmx_ffclose(out); 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; 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) { t_trxframe frout = fr; if (!frout.bAtoms) { frout.atoms = &top.atoms; frout.bAtoms = TRUE; } frout.bV = FALSE; frout.bF = FALSE; 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_nmens(int argc, char *argv[]) { const char *desc[] = { "[TT]g_nmens[tt] 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; 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) parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv); 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 = make_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*rando(&seed)); 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_cluster(int argc,char *argv[]) { static char *desc[] = { "g_cluster can cluster structures with several different methods.", "Distances between structures can be determined from a trajectory", "or read from an XPM matrix file with the [TT]-dm[tt] option.", "RMS deviation after fitting or RMS deviation of atom-pair distances", "can be used to define the distance between structures.[PAR]", "single linkage: add a structure to a cluster when its distance to any", "element of the cluster is less than [TT]cutoff[tt].[PAR]", "Jarvis Patrick: add a structure to a cluster when this structure", "and a structure in the cluster have each other as neighbors and", "they have a least [TT]P[tt] neighbors in common. The neighbors", "of a structure are the M closest structures or all structures within", "[TT]cutoff[tt].[PAR]", "Monte Carlo: reorder the RMSD matrix using Monte Carlo.[PAR]", "diagonalization: diagonalize the RMSD matrix.[PAR]" "gromos: use algorithm as described in Daura [IT]et al.[it]", "([IT]Angew. Chem. Int. Ed.[it] [BB]1999[bb], [IT]38[it], pp 236-240).", "Count number of neighbors using cut-off, take structure with", "largest number of neighbors with all its neighbors as cluster", "and eleminate it from the pool of clusters. Repeat for remaining", "structures in pool.[PAR]", "When the clustering algorithm assigns each structure to exactly one", "cluster (single linkage, Jarvis Patrick and gromos) and a trajectory", "file is supplied, the structure with", "the smallest average distance to the others or the average structure", "or all structures for each cluster will be written to a trajectory", "file. When writing all structures, separate numbered files are made", "for each cluster.[PAR]" "Two output files are always written:[BR]", "[TT]-o[tt] writes the RMSD values in the upper left half of the matrix", "and a graphical depiction of the clusters in the lower right half", "When [TT]-minstruct[tt] = 1 the graphical depiction is black", "when two structures are in the same cluster.", "When [TT]-minstruct[tt] > 1 different colors will be used for each", "cluster.[BR]", "[TT]-g[tt] writes information on the options used and a detailed list", "of all clusters and their members.[PAR]", "Additionally, a number of optional output files can be written:[BR]", "[TT]-dist[tt] writes the RMSD distribution.[BR]", "[TT]-ev[tt] writes the eigenvectors of the RMSD matrix", "diagonalization.[BR]", "[TT]-sz[tt] writes the cluster sizes.[BR]", "[TT]-tr[tt] writes a matrix of the number transitions between", "cluster pairs.[BR]", "[TT]-ntr[tt] writes the total number of transitions to or from", "each cluster.[BR]", "[TT]-clid[tt] writes the cluster number as a function of time.[BR]", "[TT]-cl[tt] writes average (with option [TT]-av[tt]) or central", "structure of each cluster or writes numbered files with cluster members", "for a selected set of clusters (with option [TT]-wcl[tt], depends on", "[TT]-nst[tt] and [TT]-rmsmin[tt]).[BR]", }; FILE *fp,*log; int i,i1,i2,j,nf,nrms; matrix box; rvec *xtps,*usextps,*x1,**xx=NULL; char *fn,*trx_out_fn; t_clusters clust; t_mat *rms; real *eigval; t_topology top; int ePBC; t_atoms useatoms; t_matrix *readmat; real *tmp; int isize=0,ifsize=0,iosize=0; atom_id *index=NULL, *fitidx, *outidx; char *grpname; real rmsd,**d1,**d2,*time,time_invfac,*mass=NULL; char buf[STRLEN],buf1[80],title[STRLEN]; bool bAnalyze,bUseRmsdCut,bJP_RMSD=FALSE,bReadMat,bReadTraj; int method,ncluster=0; static char *methodname[] = { NULL, "linkage", "jarvis-patrick","monte-carlo", "diagonalization", "gromos", NULL }; enum { m_null, m_linkage, m_jarvis_patrick, m_monte_carlo, m_diagonalize, m_gromos, m_nr }; /* Set colors for plotting: white = zero RMS, black = maximum */ static t_rgb rlo_top = { 1.0, 1.0, 1.0 }; static t_rgb rhi_top = { 0.0, 0.0, 0.0 }; static t_rgb rlo_bot = { 1.0, 1.0, 1.0 }; static t_rgb rhi_bot = { 0.0, 0.0, 1.0 }; static int nlevels=40,skip=1; static real scalemax=-1.0,rmsdcut=0.1,rmsmin=0.0; static bool bRMSdist=FALSE,bBinary=FALSE,bAverage=FALSE,bFit=TRUE; static int niter=10000,seed=1993,write_ncl=0,write_nst=1,minstruct=1; static real kT=1e-3; static int M=10,P=3; t_pargs pa[] = { { "-dista", FALSE, etBOOL, {&bRMSdist}, "Use RMSD of distances instead of RMS deviation" }, { "-nlevels",FALSE,etINT, {&nlevels}, "Discretize RMSD matrix in # levels" }, { "-cutoff",FALSE, etREAL, {&rmsdcut}, "RMSD cut-off (nm) for two structures to be neighbor" }, { "-fit", FALSE, etBOOL, {&bFit}, "Use least squares fitting before RMSD calculation" }, { "-max", FALSE, etREAL, {&scalemax}, "Maximum level in RMSD matrix" }, { "-skip", FALSE, etINT, {&skip}, "Only analyze every nr-th frame" }, { "-av", FALSE, etBOOL, {&bAverage}, "Write average iso middle structure for each cluster" }, { "-wcl", FALSE, etINT, {&write_ncl}, "Write all structures for first # clusters to numbered files" }, { "-nst", FALSE, etINT, {&write_nst}, "Only write all structures if more than # per cluster" }, { "-rmsmin",FALSE, etREAL, {&rmsmin}, "minimum rms difference with rest of cluster for writing structures" }, { "-method",FALSE, etENUM, {methodname}, "Method for cluster determination" }, { "-minstruct", FALSE, etINT, {&minstruct}, "Minimum number of structures in cluster for coloring in the xpm file" }, { "-binary",FALSE, etBOOL, {&bBinary}, "Treat the RMSD matrix as consisting of 0 and 1, where the cut-off " "is given by -cutoff" }, { "-M", FALSE, etINT, {&M}, "Number of nearest neighbors considered for Jarvis-Patrick algorithm, " "0 is use cutoff" }, { "-P", FALSE, etINT, {&P}, "Number of identical nearest neighbors required to form a cluster" }, { "-seed", FALSE, etINT, {&seed}, "Random number seed for Monte Carlo clustering algorithm" }, { "-niter", FALSE, etINT, {&niter}, "Number of iterations for MC" }, { "-kT", FALSE, etREAL, {&kT}, "Boltzmann weighting factor for Monte Carlo optimization " "(zero turns off uphill steps)" } }; t_filenm fnm[] = { { efTRX, "-f", NULL, ffOPTRD }, { efTPS, "-s", NULL, ffOPTRD }, { efNDX, NULL, NULL, ffOPTRD }, { efXPM, "-dm", "rmsd", ffOPTRD }, { efXPM, "-o", "rmsd-clust", ffWRITE }, { efLOG, "-g", "cluster", ffWRITE }, { efXVG, "-dist", "rmsd-dist", ffOPTWR }, { efXVG, "-ev", "rmsd-eig", ffOPTWR }, { efXVG, "-sz", "clust-size", ffOPTWR}, { efXPM, "-tr", "clust-trans",ffOPTWR}, { efXVG, "-ntr", "clust-trans",ffOPTWR}, { efXVG, "-clid", "clust-id.xvg",ffOPTWR}, { efTRX, "-cl", "clusters.pdb", ffOPTWR } }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); /* parse options */ bReadMat = opt2bSet("-dm",NFILE,fnm); bReadTraj = opt2bSet("-f",NFILE,fnm) || !bReadMat; if ( opt2parg_bSet("-av",asize(pa),pa) || opt2parg_bSet("-wcl",asize(pa),pa) || opt2parg_bSet("-nst",asize(pa),pa) || opt2parg_bSet("-rmsmin",asize(pa),pa) || opt2bSet("-cl",NFILE,fnm) ) trx_out_fn = opt2fn("-cl",NFILE,fnm); else trx_out_fn = NULL; if (bReadMat && time_factor()!=1) { fprintf(stderr, "\nWarning: assuming the time unit in %s is %s\n", opt2fn("-dm",NFILE,fnm),time_unit()); } if (trx_out_fn && !bReadTraj) fprintf(stderr,"\nWarning: " "cannot write cluster structures without reading trajectory\n" " ignoring option -cl %s\n", trx_out_fn); method=1; while ( method < m_nr && strcasecmp(methodname[0], methodname[method])!=0 ) method++; if (method == m_nr) gmx_fatal(FARGS,"Invalid method"); bAnalyze = (method == m_linkage || method == m_jarvis_patrick || method == m_gromos ); /* Open log file */ log = ftp2FILE(efLOG,NFILE,fnm,"w"); fprintf(stderr,"Using %s method for clustering\n",methodname[0]); fprintf(log,"Using %s method for clustering\n",methodname[0]); /* check input and write parameters to log file */ bUseRmsdCut = FALSE; if (method == m_jarvis_patrick) { bJP_RMSD = (M == 0) || opt2parg_bSet("-cutoff",asize(pa),pa); if ((M<0) || (M == 1)) gmx_fatal(FARGS,"M (%d) must be 0 or larger than 1",M); if (M < 2) { sprintf(buf1,"Will use P=%d and RMSD cutoff (%g)",P,rmsdcut); bUseRmsdCut = TRUE; } else { if (P >= M) gmx_fatal(FARGS,"Number of neighbors required (P) must be less than M"); if (bJP_RMSD) { sprintf(buf1,"Will use P=%d, M=%d and RMSD cutoff (%g)",P,M,rmsdcut); bUseRmsdCut = TRUE; } else sprintf(buf1,"Will use P=%d, M=%d",P,M); } ffprintf1(stderr,log,buf,"%s for determining the neighbors\n\n",buf1); } else /* method != m_jarvis */ bUseRmsdCut = ( bBinary || method == m_linkage || method == m_gromos ); if (bUseRmsdCut && method != m_jarvis_patrick) fprintf(log,"Using RMSD cutoff %g nm\n",rmsdcut); if ( method==m_monte_carlo ) fprintf(log,"Using %d iterations\n",niter); if (skip < 1) gmx_fatal(FARGS,"skip (%d) should be >= 1",skip); /* get input */ if (bReadTraj) { /* don't read mass-database as masses (and top) are not used */ read_tps_conf(ftp2fn(efTPS,NFILE,fnm),buf,&top,&ePBC,&xtps,NULL,box, bAnalyze); fprintf(stderr,"\nSelect group for least squares fit%s:\n", bReadMat?"":" and RMSD calculation"); get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm), 1,&ifsize,&fitidx,&grpname); if (trx_out_fn) { fprintf(stderr,"\nSelect group for output:\n"); get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm), 1,&iosize,&outidx,&grpname); /* merge and convert both index groups: */ /* first copy outidx to index. let outidx refer to elements in index */ snew(index,iosize); isize = iosize; for(i=0; i<iosize; i++) { index[i]=outidx[i]; outidx[i]=i; } /* now lookup elements from fitidx in index, add them if necessary and also let fitidx refer to elements in index */ for(i=0; i<ifsize; i++) { j=0; while (j<isize && index[j]!=fitidx[i]) j++; if (j>=isize) { /* slow this way, but doesn't matter much */ isize++; srenew(index,isize); } index[j]=fitidx[i]; fitidx[i]=j; } } else { /* !trx_out_fn */ isize = ifsize; snew(index, isize); for(i=0; i<ifsize; i++) { index[i]=fitidx[i]; fitidx[i]=i; } } } /* Initiate arrays */ snew(d1,isize); snew(d2,isize); for(i=0; (i<isize); i++) { snew(d1[i],isize); snew(d2[i],isize); } if (bReadTraj) { /* Loop over first coordinate file */ fn = opt2fn("-f",NFILE,fnm); xx = read_whole_trj(fn,isize,index,skip,&nf,&time); convert_times(nf, time); if (!bRMSdist || bAnalyze) { /* Center all frames on zero */ snew(mass,isize); for(i=0; i<ifsize; i++) mass[fitidx[i]] = top.atoms.atom[index[fitidx[i]]].m; if (bFit) for(i=0; i<nf; i++) reset_x(ifsize,fitidx,isize,NULL,xx[i],mass); } } if (bReadMat) { fprintf(stderr,"Reading rms distance matrix "); read_xpm_matrix(opt2fn("-dm",NFILE,fnm),&readmat); fprintf(stderr,"\n"); if (readmat[0].nx != readmat[0].ny) gmx_fatal(FARGS,"Matrix (%dx%d) is not square", readmat[0].nx,readmat[0].ny); if (bReadTraj && bAnalyze && (readmat[0].nx != nf)) gmx_fatal(FARGS,"Matrix size (%dx%d) does not match the number of " "frames (%d)",readmat[0].nx,readmat[0].ny,nf); nf = readmat[0].nx; sfree(time); time = readmat[0].axis_x; time_invfac = time_invfactor(); for(i=0; i<nf; i++) time[i] *= time_invfac; rms = init_mat(readmat[0].nx,method == m_diagonalize); convert_mat(&(readmat[0]),rms); nlevels = readmat[0].nmap; } else { /* !bReadMat */ rms = init_mat(nf,method == m_diagonalize); nrms = (nf*(nf-1))/2; if (!bRMSdist) { fprintf(stderr,"Computing %dx%d RMS deviation matrix\n",nf,nf); snew(x1,isize); for(i1=0; (i1<nf); i1++) { for(i2=i1+1; (i2<nf); i2++) { for(i=0; i<isize; i++) copy_rvec(xx[i1][i],x1[i]); if (bFit) do_fit(isize,mass,xx[i2],x1); rmsd = rmsdev(isize,mass,xx[i2],x1); set_mat_entry(rms,i1,i2,rmsd); } nrms -= (nf-i1-1); fprintf(stderr,"\r# RMSD calculations left: %d ",nrms); } } else { /* bRMSdist */ fprintf(stderr,"Computing %dx%d RMS distance deviation matrix\n",nf,nf); for(i1=0; (i1<nf); i1++) { calc_dist(isize,xx[i1],d1); for(i2=i1+1; (i2<nf); i2++) { calc_dist(isize,xx[i2],d2); set_mat_entry(rms,i1,i2,rms_dist(isize,d1,d2)); } nrms -= (nf-i1-1); fprintf(stderr,"\r# RMSD calculations left: %d ",nrms); } } fprintf(stderr,"\n\n"); } ffprintf2(stderr,log,buf,"The RMSD ranges from %g to %g nm\n", rms->minrms,rms->maxrms); ffprintf1(stderr,log,buf,"Average RMSD is %g\n",2*rms->sumrms/(nf*(nf-1))); ffprintf1(stderr,log,buf,"Number of structures for matrix %d\n",nf); ffprintf1(stderr,log,buf,"Energy of the matrix is %g nm\n",mat_energy(rms)); if (bUseRmsdCut && (rmsdcut < rms->minrms || rmsdcut > rms->maxrms) ) fprintf(stderr,"WARNING: rmsd cutoff %g is outside range of rmsd values " "%g to %g\n",rmsdcut,rms->minrms,rms->maxrms); if (bAnalyze && (rmsmin < rms->minrms) ) fprintf(stderr,"WARNING: rmsd minimum %g is below lowest rmsd value %g\n", rmsmin,rms->minrms); if (bAnalyze && (rmsmin > rmsdcut) ) fprintf(stderr,"WARNING: rmsd minimum %g is above rmsd cutoff %g\n", rmsmin,rmsdcut); /* Plot the rmsd distribution */ rmsd_distribution(opt2fn("-dist",NFILE,fnm),rms); if (bBinary) { for(i1=0; (i1 < nf); i1++) for(i2=0; (i2 < nf); i2++) if (rms->mat[i1][i2] < rmsdcut) rms->mat[i1][i2] = 0; else rms->mat[i1][i2] = 1; } snew(clust.cl,nf); switch (method) { case m_linkage: /* Now sort the matrix and write it out again */ gather(rms,rmsdcut,&clust); break; case m_diagonalize: /* Do a diagonalization */ snew(eigval,nf); snew(tmp,nf*nf); memcpy(tmp,rms->mat[0],nf*nf*sizeof(real)); eigensolver(tmp,nf,0,nf,eigval,rms->mat[0]); sfree(tmp); fp = xvgropen(opt2fn("-ev",NFILE,fnm),"RMSD matrix Eigenvalues", "Eigenvector index","Eigenvalues (nm\\S2\\N)"); for(i=0; (i<nf); i++) fprintf(fp,"%10d %10g\n",i,eigval[i]); ffclose(fp); break; case m_monte_carlo: mc_optimize(log,rms,niter,&seed,kT); swap_mat(rms); reset_index(rms); break; case m_jarvis_patrick: jarvis_patrick(rms->nn,rms->mat,M,P,bJP_RMSD ? rmsdcut : -1,&clust); break; case m_gromos: gromos(rms->nn,rms->mat,rmsdcut,&clust); break; default: gmx_fatal(FARGS,"DEATH HORROR unknown method \"%s\"",methodname[0]); } if (method == m_monte_carlo || method == m_diagonalize) fprintf(stderr,"Energy of the matrix after clustering is %g nm\n", mat_energy(rms)); if (bAnalyze) { if (minstruct > 1) { ncluster = plot_clusters(nf,rms->mat,&clust,nlevels,minstruct); } else { mark_clusters(nf,rms->mat,rms->maxrms,&clust); } init_t_atoms(&useatoms,isize,FALSE); snew(usextps, isize); useatoms.resname=top.atoms.resname; for(i=0; i<isize; i++) { useatoms.atomname[i]=top.atoms.atomname[index[i]]; useatoms.atom[i].resnr=top.atoms.atom[index[i]].resnr; useatoms.nres=max(useatoms.nres,useatoms.atom[i].resnr+1); copy_rvec(xtps[index[i]],usextps[i]); } useatoms.nr=isize; analyze_clusters(nf,&clust,rms->mat,isize,&useatoms,usextps,mass,xx,time, ifsize,fitidx,iosize,outidx, bReadTraj?trx_out_fn:NULL, opt2fn_null("-sz",NFILE,fnm), opt2fn_null("-tr",NFILE,fnm), opt2fn_null("-ntr",NFILE,fnm), opt2fn_null("-clid",NFILE,fnm), bAverage, write_ncl, write_nst, rmsmin, bFit, log, rlo_bot,rhi_bot); } ffclose(log); if (bBinary && !bAnalyze) /* Make the clustering visible */ for(i2=0; (i2 < nf); i2++) for(i1=i2+1; (i1 < nf); i1++) if (rms->mat[i1][i2]) rms->mat[i1][i2] = rms->maxrms; fp = opt2FILE("-o",NFILE,fnm,"w"); fprintf(stderr,"Writing rms distance/clustering matrix "); if (bReadMat) { write_xpm(fp,0,readmat[0].title,readmat[0].legend,readmat[0].label_x, readmat[0].label_y,nf,nf,readmat[0].axis_x,readmat[0].axis_y, rms->mat,0.0,rms->maxrms,rlo_top,rhi_top,&nlevels); } else { sprintf(buf,"Time (%s)",time_unit()); sprintf(title,"RMS%sDeviation / Cluster Index", bRMSdist ? " Distance " : " "); if (minstruct > 1) { write_xpm_split(fp,0,title,"RMSD (nm)",buf,buf, nf,nf,time,time,rms->mat,0.0,rms->maxrms,&nlevels, rlo_top,rhi_top,0.0,(real) ncluster, &ncluster,TRUE,rlo_bot,rhi_bot); } else { write_xpm(fp,0,title,"RMSD (nm)",buf,buf, nf,nf,time,time,rms->mat,0.0,rms->maxrms, rlo_top,rhi_top,&nlevels); } } fprintf(stderr,"\n"); ffclose(fp); /* now show what we've done */ do_view(opt2fn("-o",NFILE,fnm),"-nxy"); do_view(opt2fn_null("-sz",NFILE,fnm),"-nxy"); if (method == m_diagonalize) do_view(opt2fn_null("-ev",NFILE,fnm),"-nxy"); do_view(opt2fn("-dist",NFILE,fnm),"-nxy"); if (bAnalyze) { do_view(opt2fn_null("-tr",NFILE,fnm),"-nxy"); do_view(opt2fn_null("-ntr",NFILE,fnm),"-nxy"); do_view(opt2fn_null("-clid",NFILE,fnm),"-nxy"); } /* Thank the user for her patience */ thanx(stderr); return 0; }
int gmx_relax(int argc,char *argv[]) { const char *desc[] = { "g_noe calculates a NOE spectrum" }; int status; t_topology *top; int i,j,k,natoms,nprot,*prot_ind; int ifit; char *gn_fit; atom_id *ind_fit,*all_at; real *w_rls; rvec *xp; t_pair *pair; matrix box; int step,nre; real t,lambda; real *shifts=NULL; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPX, "-s", NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efDAT, "-d", "shifts", ffREAD }, { efOUT, "-o","spec", ffWRITE }, { efXVG, "-corr", "rij-corr", ffWRITE }, { efXVG, "-noe", "noesy", ffWRITE } }; #define NFILE asize(fnm) static real taum = 0.0, maxdist = 0.6; static int nlevels = 15; static int nrestart = 1; static int maxframes = 100; static bool bFFT = TRUE,bFit = TRUE, bVerbose = TRUE; t_pargs pa[] = { { "-taum", FALSE, etREAL, &taum, "Rotational correlation time for your molecule. It is obligatory to pass this option" }, { "-maxdist", FALSE, etREAL, &maxdist, "Maximum distance to be plotted" }, { "-nlevels", FALSE, etINT, &nlevels, "Number of levels for plotting" }, { "-nframes", FALSE, etINT, &maxframes, "Number of frames in your trajectory. Will stop analysis after this" }, { "-fft", FALSE, etBOOL, &bFFT, "Use FFT for correlation function" }, { "-nrestart", FALSE, etINT, &nrestart, "Number of frames between starting point for computation of ACF without FFT" }, { "-fit", FALSE, etBOOL, &bFit, "Do an optimal superposition on reference structure in tpx file" }, { "-v", FALSE, etBOOL, &bVerbose, "Tell you what I am about to do" } }; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (taum <= 0) gmx_fatal(FARGS,"Please give me a sensible taum!\n"); if (nlevels > 50) { nlevels = 50; fprintf(stderr,"Warning: too many levels, setting to %d\n",nlevels); } top = read_top(ftp2fn(efTPX,NFILE,fnm)); natoms = top->atoms.nr; snew(xp,natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,NULL,box, &natoms,xp,NULL,NULL,NULL); /* Determine the number of protons, and their index numbers * by checking the mass */ nprot = 0; snew(prot_ind,natoms); for(i=0; (i<natoms); i++) if (top->atoms.atom[i].m < 2) { prot_ind[nprot++] = i; } fprintf(stderr,"There %d protons in your topology\n",nprot); snew(pair,(nprot*(nprot-1)/2)); for(i=k=0; (i<nprot); i++) { for(j=i+1; (j<nprot); j++,k++) { pair[k].ai = prot_ind[i]; pair[k].aj = prot_ind[j]; } } sfree(prot_ind); fprintf(stderr,"Select group for root least squares fit\n"); rd_index(ftp2fn(efNDX,NFILE,fnm),1,&ifit,&ind_fit,&gn_fit); if (ifit < 3) gmx_fatal(FARGS,"Need >= 3 points to fit!\n"); /* Make an array with weights for fitting */ snew(w_rls,natoms); for(i=0; (i<ifit); i++) w_rls[ind_fit[i]]=top->atoms.atom[ind_fit[i]].m; /* Prepare reference frame */ snew(all_at,natoms); for(j=0; (j<natoms); j++) all_at[j]=j; rm_pbc(&(top->idef),natoms,box,xp,xp); reset_x(ifit,ind_fit,natoms,all_at,xp,w_rls); sfree(all_at); spectrum(bVerbose, ftp2fn(efTRX,NFILE,fnm),ftp2fn(efDAT,NFILE,fnm), ftp2bSet(efDAT,NFILE,fnm),opt2fn("-corr",NFILE,fnm), opt2fn("-noe",NFILE,fnm), maxframes,bFFT,bFit,nrestart, k,pair,natoms,shifts, taum,maxdist,w_rls,xp,&(top->idef)); thanx(stderr); return 0; }
int gmx_wheel(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] plots a helical wheel representation of your sequence.", "The input sequence is in the [TT].dat[tt] file where the first line contains", "the number of residues and each consecutive line contains a residue " "name." }; output_env_t oenv; static real rot0 = 0; static gmx_bool bNum = TRUE; static char *title = NULL; static int r0 = 1; t_pargs pa [] = { { "-r0", FALSE, etINT, {&r0}, "The first residue number in the sequence" }, { "-rot0", FALSE, etREAL, {&rot0}, "Rotate around an angle initially (90 degrees makes sense)" }, { "-T", FALSE, etSTR, {&title}, "Plot a title in the center of the wheel (must be shorter than 10 characters, or it will overwrite the wheel)" }, { "-nn", FALSE, etBOOL, {&bNum}, "Toggle numbers" } }; t_filenm fnm[] = { { efDAT, "-f", NULL, ffREAD }, { efEPS, "-o", NULL, ffWRITE } }; #define NFILE asize(fnm) int i, nres; char **resnm; if (!parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } for (i = 1; (i < argc); i++) { if (strcmp(argv[i], "-r0") == 0) { r0 = strtol(argv[++i], NULL, 10); fprintf(stderr, "First residue is %d\n", r0); } else if (strcmp(argv[i], "-rot0") == 0) { rot0 = strtod(argv[++i], NULL); fprintf(stderr, "Initial rotation is %g\n", rot0); } else if (strcmp(argv[i], "-T") == 0) { title = strdup(argv[++i]); fprintf(stderr, "Title will be '%s'\n", title); } else if (strcmp(argv[i], "-nn") == 0) { bNum = FALSE; fprintf(stderr, "No residue numbers\n"); } else { gmx_fatal(FARGS, "Incorrect usage of option %s", argv[i]); } } nres = get_lines(ftp2fn(efDAT, NFILE, fnm), &resnm); if (bNum) { wheel(ftp2fn(efEPS, NFILE, fnm), nres, resnm, r0, rot0, title); } else { wheel2(ftp2fn(efEPS, NFILE, fnm), nres, resnm, rot0, title); } return 0; }
int gmx_g_angle(int argc,char *argv[]) { static const char *desc[] = { "[TT]g_angle[tt] computes the angle distribution for a number of angles", "or dihedrals. This way you can check whether your simulation", "is correct. With option [TT]-ov[tt] you can plot the average angle of", "a group of angles as a function of time. With the [TT]-all[tt] option", "the first graph is the average, the rest are the individual angles.[PAR]", "With the [TT]-of[tt] option, [TT]g_angle[tt] also calculates the fraction of trans", "dihedrals (only for dihedrals) as function of time, but this is", "probably only fun for a selected few.[PAR]", "With option [TT]-oc[tt] a dihedral correlation function is calculated.[PAR]", "It should be noted that the index file should contain", "atom-triples for angles or atom-quadruplets for dihedrals.", "If this is not the case, the program will crash.[PAR]", "With option [TT]-or[tt] a trajectory file is dumped containing cos and", "sin of selected dihedral angles which subsequently can be used as", "input for a PCA analysis using [TT]g_covar[tt].[PAR]", "Option [TT]-ot[tt] plots when transitions occur between", "dihedral rotamers of multiplicity 3 and [TT]-oh[tt]", "records a histogram of the times between such transitions,", "assuming the input trajectory frames are equally spaced in time." }; static const char *opt[] = { NULL, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL }; static gmx_bool bALL=FALSE,bChandler=FALSE,bAverCorr=FALSE,bPBC=TRUE; static real binwidth=1; t_pargs pa[] = { { "-type", FALSE, etENUM, {opt}, "Type of angle to analyse" }, { "-all", FALSE, etBOOL, {&bALL}, "Plot all angles separately in the averages file, in the order of appearance in the index file." }, { "-binwidth", FALSE, etREAL, {&binwidth}, "binwidth (degrees) for calculating the distribution" }, { "-periodic", FALSE, etBOOL, {&bPBC}, "Print dihedral angles modulo 360 degrees" }, { "-chandler", FALSE, etBOOL, {&bChandler}, "Use Chandler correlation function (N[trans] = 1, N[gauche] = 0) rather than cosine correlation function. Trans is defined as phi < -60 or phi > 60." }, { "-avercorr", FALSE, etBOOL, {&bAverCorr}, "Average the correlation functions for the individual angles/dihedrals" } }; static const char *bugs[] = { "Counting transitions only works for dihedrals with multiplicity 3" }; FILE *out; real tmp,dt; int status,isize; atom_id *index; char *grpname; real maxang,Jc,S2,norm_fac,maxstat; unsigned long mode; int nframes,maxangstat,mult,*angstat; int i,j,total,nangles,natoms,nat2,first,last,angind; gmx_bool bAver,bRb,bPeriodic, bFrac, /* calculate fraction too? */ bTrans, /* worry about transtions too? */ bCorr; /* correlation function ? */ real t,aa,aver,aver2,aversig,fraction; /* fraction trans dihedrals */ double tfrac=0; char title[256]; real **dih=NULL; /* mega array with all dih. angles at all times*/ char buf[80]; real *time,*trans_frac,*aver_angle; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efNDX, NULL, "angle", ffREAD }, { efXVG, "-od", "angdist", ffWRITE }, { efXVG, "-ov", "angaver", ffOPTWR }, { efXVG, "-of", "dihfrac", ffOPTWR }, { efXVG, "-ot", "dihtrans", ffOPTWR }, { efXVG, "-oh", "trhisto", ffOPTWR }, { efXVG, "-oc", "dihcorr", ffOPTWR }, { efTRR, "-or", NULL, ffOPTWR } }; #define NFILE asize(fnm) int npargs; t_pargs *ppa; output_env_t oenv; npargs = asize(pa); ppa = add_acf_pargs(&npargs,pa); parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,npargs,ppa,asize(desc),desc,asize(bugs),bugs, &oenv); mult = 4; maxang = 360.0; bRb = FALSE; switch(opt[0][0]) { case 'a': mult = 3; maxang = 180.0; break; case 'd': break; case 'i': break; case 'r': bRb = TRUE; break; } if (opt2bSet("-or",NFILE,fnm)) { if (mult != 4) gmx_fatal(FARGS,"Can not combine angles with trn dump"); else please_cite(stdout,"Mu2005a"); } /* Calculate bin size */ maxangstat=(int)(maxang/binwidth+0.5); binwidth=maxang/maxangstat; rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname); nangles=isize/mult; if ((isize % mult) != 0) gmx_fatal(FARGS,"number of index elements not multiple of %d, " "these can not be %s\n", mult,(mult==3) ? "angle triplets" : "dihedral quadruplets"); /* Check whether specific analysis has to be performed */ bCorr=opt2bSet("-oc",NFILE,fnm); bAver=opt2bSet("-ov",NFILE,fnm); bTrans=opt2bSet("-ot",NFILE,fnm); bFrac=opt2bSet("-of",NFILE,fnm); if (bTrans && opt[0][0] != 'd') { fprintf(stderr, "Option -ot should only accompany -type dihedral. Disabling -ot.\n"); bTrans = FALSE; } if (bChandler && !bCorr) bCorr=TRUE; if (bFrac && !bRb) { fprintf(stderr,"Warning:" " calculating fractions as defined in this program\n" "makes sense for Ryckaert Bellemans dihs. only. Ignoring -of\n\n"); bFrac = FALSE; } if ( (bTrans || bFrac || bCorr) && mult==3) gmx_fatal(FARGS,"Can only do transition, fraction or correlation\n" "on dihedrals. Select -d\n"); /* * We need to know the nr of frames so we can allocate memory for an array * with all dihedral angles at all timesteps. Works for me. */ if (bTrans || bCorr || bALL || opt2bSet("-or",NFILE,fnm)) snew(dih,nangles); snew(angstat,maxangstat); read_ang_dih(ftp2fn(efTRX,NFILE,fnm),(mult == 3), bALL || bCorr || bTrans || opt2bSet("-or",NFILE,fnm), bRb,bPBC,maxangstat,angstat, &nframes,&time,isize,index,&trans_frac,&aver_angle,dih, oenv); dt=(time[nframes-1]-time[0])/(nframes-1); if (bAver) { sprintf(title,"Average Angle: %s",grpname); out=xvgropen(opt2fn("-ov",NFILE,fnm), title,"Time (ps)","Angle (degrees)",oenv); for(i=0; (i<nframes); i++) { fprintf(out,"%10.5f %8.3f",time[i],aver_angle[i]*RAD2DEG); if (bALL) { for(j=0; (j<nangles); j++) if (bPBC) { real dd = dih[j][i]; fprintf(out," %8.3f",atan2(sin(dd),cos(dd))*RAD2DEG); } else fprintf(out," %8.3f",dih[j][i]*RAD2DEG); } fprintf(out,"\n"); } ffclose(out); } if (opt2bSet("-or",NFILE,fnm)) dump_dih_trn(nframes,nangles,dih,opt2fn("-or",NFILE,fnm),time); if (bFrac) { sprintf(title,"Trans fraction: %s",grpname); out=xvgropen(opt2fn("-of",NFILE,fnm), title,"Time (ps)","Fraction",oenv); tfrac = 0.0; for(i=0; (i<nframes); i++) { fprintf(out,"%10.5f %10.3f\n",time[i],trans_frac[i]); tfrac += trans_frac[i]; } ffclose(out); tfrac/=nframes; fprintf(stderr,"Average trans fraction: %g\n",tfrac); } sfree(trans_frac); if (bTrans) ana_dih_trans(opt2fn("-ot",NFILE,fnm),opt2fn("-oh",NFILE,fnm), dih,nframes,nangles,grpname,time,bRb,oenv); if (bCorr) { /* Autocorrelation function */ if (nframes < 2) fprintf(stderr,"Not enough frames for correlation function\n"); else { if (bChandler) { real dval,sixty=DEG2RAD*60; gmx_bool bTest; for(i=0; (i<nangles); i++) for(j=0; (j<nframes); j++) { dval = dih[i][j]; if (bRb) bTest=(dval > -sixty) && (dval < sixty); else bTest=(dval < -sixty) || (dval > sixty); if (bTest) dih[i][j] = dval-tfrac; else dih[i][j] = -tfrac; } } if (bChandler) mode = eacNormal; else mode = eacCos; do_autocorr(opt2fn("-oc",NFILE,fnm), oenv, "Dihedral Autocorrelation Function", nframes,nangles,dih,dt,mode,bAverCorr); } } /* Determine the non-zero part of the distribution */ for(first=0; (first < maxangstat-1) && (angstat[first+1] == 0); first++) ; for(last=maxangstat-1; (last > 0) && (angstat[last-1] == 0) ; last--) ; aver=aver2=0; for(i=0; (i<nframes); i++) { aver += RAD2DEG*aver_angle[i]; aver2 += sqr(RAD2DEG*aver_angle[i]); } aver /= (real) nframes; aver2 /= (real) nframes; aversig = sqrt(aver2-sqr(aver)); printf("Found points in the range from %d to %d (max %d)\n", first,last,maxangstat); printf(" < angle > = %g\n",aver); printf("< angle^2 > = %g\n",aver2); printf("Std. Dev. = %g\n",aversig); if (mult == 3) sprintf(title,"Angle Distribution: %s",grpname); else { sprintf(title,"Dihedral Distribution: %s",grpname); calc_distribution_props(maxangstat,angstat,-180.0,0,NULL,&S2); fprintf(stderr,"Order parameter S^2 = %g\n",S2); } bPeriodic=(mult==4) && (first==0) && (last==maxangstat-1); out=xvgropen(opt2fn("-od",NFILE,fnm),title,"Degrees","",oenv); if (output_env_get_print_xvgr_codes(oenv)) fprintf(out,"@ subtitle \"average angle: %g\\So\\N\"\n",aver); norm_fac=1.0/(nangles*nframes*binwidth); if (bPeriodic) { maxstat=0; for(i=first; (i<=last); i++) maxstat=max(maxstat,angstat[i]*norm_fac); fprintf(out,"@with g0\n"); fprintf(out,"@ world xmin -180\n"); fprintf(out,"@ world xmax 180\n"); fprintf(out,"@ world ymin 0\n"); fprintf(out,"@ world ymax %g\n",maxstat*1.05); fprintf(out,"@ xaxis tick major 60\n"); fprintf(out,"@ xaxis tick minor 30\n"); fprintf(out,"@ yaxis tick major 0.005\n"); fprintf(out,"@ yaxis tick minor 0.0025\n"); } for(i=first; (i<=last); i++) fprintf(out,"%10g %10f\n",i*binwidth+180.0-maxang,angstat[i]*norm_fac); if ( bPeriodic ) /* print first bin again as last one */ fprintf(out,"%10g %10f\n",180.0,angstat[0]*norm_fac); ffclose(out); do_view(oenv,opt2fn("-od",NFILE,fnm),"-nxy"); if (bAver) do_view(oenv,opt2fn("-ov",NFILE,fnm),"-nxy"); thanx(stderr); return 0; }
int main(int argc,char *argv[]) { static const char *desc[] = { "mk_angndx makes an index file for calculation of", "angle distributions etc. It uses a run input file ([TT].tpx[tt]) for the", "definitions of the angles, dihedrals etc." }; static const char *opt[] = { NULL, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL }; static gmx_bool bH=TRUE; static real hq=-1; t_pargs pa[] = { { "-type", FALSE, etENUM, {opt}, "Type of angle" }, { "-hyd", FALSE, etBOOL, {&bH}, "Include angles with atoms with mass < 1.5" }, { "-hq", FALSE, etREAL, {&hq}, "Ignore angles with atoms with mass < 1.5 and |q| < hq" } }; output_env_t oenv; FILE *out; t_topology *top; int i,j,ntype; int nft=0,*ft,mult=0; int **index; int *ft_ind; int *nr; char **grpnames; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efNDX, NULL, "angle", ffWRITE } }; #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); ft = select_ftype(opt[0],&nft,&mult); top = read_top(ftp2fn(efTPX,NFILE,fnm),NULL); ntype = calc_ntype(nft,ft,&(top->idef)); snew(grpnames,ntype); snew(ft_ind,top->idef.ntypes); fill_ft_ind(nft,ft,&top->idef,ft_ind,grpnames); snew(nr,ntype); snew(index,ntype); fill_ang(nft,ft,mult,nr,index,ft_ind,top,!bH,hq); out=ftp2FILE(efNDX,NFILE,fnm,"w"); for(i=0; (i<ntype); i++) { if (nr[i] > 0) { fprintf(out,"[ %s ]\n",grpnames[i]); for(j=0; (j<nr[i]*mult); j++) { fprintf(out," %5d",index[i][j]+1); if ((j % 12) == 11) fprintf(out,"\n"); } fprintf(out,"\n"); } } ffclose(out); thanx(stderr); return 0; }
int gmx_hydorder(int argc, char *argv[]) { static const char *desc[] = { "g_hydorder computes the tetrahedrality order parameters around a ", "given atom. Both angle an distance order parameters are calculated. See", "P.-L. Chau and A.J. Hardwick, Mol. Phys., 93, (1998), 511-518.", "for more details.[BR]" "This application calculates the orderparameter in a 3d-mesh in the box, and", "with 2 phases in the box gives the user the option to define a 2D interface in time", "separating the faces by specifying parameters -sgang1 and -sgang2 (It is important", "to select these judiciously)" }; int axis = 0; static int nsttblock = 1; static int nlevels = 100; static real binwidth = 1.0; /* binwidth in mesh */ static real sg1 = 1; static real sg2 = 1; /* order parameters for bulk phases */ static gmx_bool bFourier = FALSE; static gmx_bool bRawOut = FALSE; int frames, xslices, yslices; /* Dimensions of interface arrays*/ real ***intfpos; /* Interface arrays (intfnr,t,xy) -potentially large */ static char *normal_axis[] = { NULL, "z", "x", "y", NULL }; t_pargs pa[] = { { "-d", FALSE, etENUM, {normal_axis}, "Direction of the normal on the membrane" }, { "-bw", FALSE, etREAL, {&binwidth}, "Binwidth of box mesh" }, { "-sgang1", FALSE, etREAL, {&sg1}, "tetrahedral angle parameter in Phase 1 (bulk)" }, { "-sgang2", FALSE, etREAL, {&sg2}, "tetrahedral angle parameter in Phase 2 (bulk)" }, { "-tblock", FALSE, etINT, {&nsttblock}, "Number of frames in one time-block average"}, { "-nlevel", FALSE, etINT, {&nlevels}, "Number of Height levels in 2D - XPixMaps"} }; t_filenm fnm[] = { /* files for g_order */ { efTRX, "-f", NULL, ffREAD }, /* trajectory file */ { efNDX, "-n", NULL, ffREAD }, /* index file */ { efTPX, "-s", NULL, ffREAD }, /* topology file */ { efXPM, "-o", "intf", ffWRMULT}, /* XPM- surface maps */ { efOUT, "-or", "raw", ffOPTWRMULT }, /* xvgr output file */ { efOUT, "-Spect", "intfspect", ffOPTWRMULT}, /* Fourier spectrum interfaces */ }; #define NFILE asize(fnm) /*Filenames*/ const char *ndxfnm, *tpsfnm, *trxfnm; char **spectra, **intfn, **raw; int nfspect, nfxpm, nfraw; output_env_t oenv; parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv); bFourier = opt2bSet("-Spect", NFILE, fnm); bRawOut = opt2bSet("-or", NFILE, fnm); if (binwidth < 0.0) { gmx_fatal(FARGS, "Can not have binwidth < 0"); } ndxfnm = ftp2fn(efNDX, NFILE, fnm); tpsfnm = ftp2fn(efTPX, NFILE, fnm); trxfnm = ftp2fn(efTRX, NFILE, fnm); /* Calculate axis */ if (strcmp(normal_axis[0], "x") == 0) { axis = XX; } else if (strcmp(normal_axis[0], "y") == 0) { axis = YY; } else if (strcmp(normal_axis[0], "z") == 0) { axis = ZZ; } else { gmx_fatal(FARGS, "Invalid axis, use x, y or z"); } switch (axis) { case 0: fprintf(stderr, "Taking x axis as normal to the membrane\n"); break; case 1: fprintf(stderr, "Taking y axis as normal to the membrane\n"); break; case 2: fprintf(stderr, "Taking z axis as normal to the membrane\n"); break; } /* tetraheder order parameter */ /* If either of the options is set we compute both */ nfxpm = opt2fns(&intfn, "-o", NFILE, fnm); if (nfxpm != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm); } calc_tetra_order_interface(ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices, &yslices, sg1, sg2, &intfpos, oenv); writesurftoxpms(intfpos, frames, xslices, yslices, binwidth, intfn, nlevels); if (bFourier) { nfspect = opt2fns(&spectra, "-Spect", NFILE, fnm); if (nfspect != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfspect); } powerspectavg(intfpos, frames, xslices, yslices, spectra); } if (bRawOut) { nfraw = opt2fns(&raw, "-or", NFILE, fnm); if (nfraw != 2) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfraw); } writeraw(intfpos, frames, xslices, yslices, raw); } thanx(stderr); return 0; }
static void init_gmx(t_x11 *x11, char *program, int nfile, t_filenm fnm[], gmx_output_env_t *oenv) { Pixmap pm; t_gmx *gmx; XSizeHints hints; int w0, h0; int natom, natom_trx; t_topology top; int ePBC; matrix box; t_trxframe fr; t_trxstatus *status; snew(gmx, 1); snew(gmx->wd, 1); ePBC = read_tpx_top(ftp2fn(efTPR, nfile, fnm), NULL, box, &natom, NULL, NULL, &top); read_first_frame(oenv, &status, ftp2fn(efTRX, nfile, fnm), &fr, TRX_DONT_SKIP); close_trx(status); natom_trx = fr.natoms; /* Creates a simple window */ w0 = DisplayWidth(x11->disp, x11->screen)-132; h0 = DisplayHeight(x11->disp, x11->screen)-140; InitWin(gmx->wd, 0, 0, w0, h0, 3, gmx::bromacs().c_str()); gmx->wd->self = XCreateSimpleWindow(x11->disp, x11->root, gmx->wd->x, gmx->wd->y, gmx->wd->width, gmx->wd->height, gmx->wd->bwidth, WHITE, BLACK); pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char *)gromacs_bits, gromacs_width, gromacs_height, WHITE, BLACK, 1); hints.flags = PMinSize; hints.min_width = 2*EWIDTH+40; hints.min_height = EHEIGHT+LDHEIGHT+LEGHEIGHT+40; XSetStandardProperties(x11->disp, gmx->wd->self, gmx->wd->text, program, pm, NULL, 0, &hints); x11->RegisterCallback(x11, gmx->wd->self, x11->root, MainCallBack, gmx); x11->SetInputMask(x11, gmx->wd->self, ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | ExposureMask | StructureNotifyMask); /* The order of creating windows is important here! */ /* Manager */ gmx->man = init_man(x11, gmx->wd->self, 0, 0, 1, 1, WHITE, BLACK, ePBC, box, oenv); gmx->logo = init_logo(x11, gmx->wd->self, false); /* Now put all windows in the proper place */ move_gmx(x11, gmx, w0, h0, false); XMapWindow(x11->disp, gmx->wd->self); map_man(x11, gmx->man); /* Pull Down menu */ gmx->pd = init_pd(x11, gmx->wd->self, gmx->wd->width, x11->fg, x11->bg, MSIZE, gmx_pd_size, gmx_pd, MenuTitle); /* Dialogs & Filters */ gmx->filter = init_filter(&(top.atoms), ftp2fn_null(efNDX, nfile, fnm), natom_trx); init_dlgs(x11, gmx); /* Now do file operations */ set_file(x11, gmx->man, ftp2fn(efTRX, nfile, fnm), ftp2fn(efTPR, nfile, fnm)); ShowDlg(gmx->dlgs[edFilter]); }
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; rvec *x1, *x2, *xx; matrix box; real rms1, rms2, fac, *mass; char *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; } t_topology *top; snew(top, 1); read_tps_conf(opt2fn("-f1", NFILE, fnm), top, NULL, &x1, NULL, box, FALSE); nat1 = top->atoms.nr; read_tps_conf(opt2fn("-f2", NFILE, fnm), top, NULL, &x2, NULL, box, FALSE); nat2 = top->atoms.nr; if (nat1 != nat2) { gmx_fatal(FARGS, "Number of atoms in first structure is %d, in second %d", nat1, nat2); } snew(xx, nat1); t_atoms &atoms = top->atoms; 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) { xvgrclose(fp); do_view(oenv, opt2fn("-or", NFILE, fnm), "-nxy"); } return 0; }
int gmx_gyrate(int argc,char *argv[]) { const char *desc[] = { "g_gyrate computes the radius of gyration of a group of atoms", "and the radii of gyration about the x, y and z axes,", "as a function of time. The atoms are explicitly mass weighted.[PAR]", "With the [TT]-nmol[tt] option the radius of gyration will be calculated", "for multiple molecules by splitting the analysis group in equally", "sized parts.[PAR]", "With the option [TT]-nz[tt] 2D radii of gyration in the x-y plane", "of slices along the z-axis are calculated." }; static int nmol=1,nz=0; static bool bQ=FALSE,bRot=FALSE,bMOI=FALSE; t_pargs pa[] = { { "-nmol", FALSE, etINT, {&nmol}, "The number of molecules to analyze" }, { "-q", FALSE, etBOOL, {&bQ}, "Use absolute value of the charge of an atom as weighting factor instead of mass" }, { "-p", FALSE, etBOOL, {&bRot}, "Calculate the radii of gyration about the principal axes." }, { "-moi", FALSE, etBOOL, {&bMOI}, "Calculate the moments of inertia (defined by the principal axes)." }, { "-nz", FALSE, etINT, {&nz}, "Calculate the 2D radii of gyration of # slices along the z-axis" }, }; FILE *out; int status; t_topology top; int ePBC; rvec *x,*x_s; rvec xcm,gvec,gvec1; matrix box,trans; bool bACF; real **moi_trans=NULL; int max_moi=0,delta_moi=100; rvec d,d1; /* eigenvalues of inertia tensor */ real t,t0,tm,gyro; int natoms; char *grpname,title[256]; int i,j,m,gnx,nam,mol; atom_id *index; char *leg[] = { "Rg", "RgX", "RgY", "RgZ" }; char *legI[] = { "Itot", "I1", "I2", "I3" }; #define NLEG asize(leg) t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, NULL, "gyrate", ffWRITE }, { efXVG, "-acf", "moi-acf", ffOPTWR }, }; #define NFILE asize(fnm) int npargs; t_pargs *ppa; CopyRight(stderr,argv[0]); npargs = asize(pa); ppa = add_acf_pargs(&npargs,pa); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL); bACF = opt2bSet("-acf",NFILE,fnm); if (bACF && nmol!=1) gmx_fatal(FARGS,"Can only do acf with nmol=1"); bRot = bRot || bMOI || bACF; /* if (nz > 0) bMOI = TRUE; */ if (bRot) { printf("Will rotate system along principal axes\n"); snew(moi_trans,DIM); } if (bMOI) { printf("Will print moments of inertia\n"); bQ = FALSE; } if (bQ) printf("Will print radius normalised by charge\n"); read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,TRUE); get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpname); if (nmol > gnx || gnx % nmol != 0) { gmx_fatal(FARGS,"The number of atoms in the group (%d) is not a multiple of nmol (%d)",gnx,nmol); } nam = gnx/nmol; natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); snew(x_s,natoms); j = 0; t0 = t; if (bQ) out=xvgropen(ftp2fn(efXVG,NFILE,fnm), "Radius of Charge","Time (ps)","Rg (nm)"); else if (bMOI) out=xvgropen(ftp2fn(efXVG,NFILE,fnm), "Moments of inertia","Time (ps)","I (a.m.u. nm\\S2\\N)"); else out=xvgropen(ftp2fn(efXVG,NFILE,fnm), "Radius of gyration","Time (ps)","Rg (nm)"); if (bMOI) xvgr_legend(out,NLEG,legI); else { if (bRot) if (bPrintXvgrCodes()) fprintf(out,"@ subtitle \"Axes are principal component axes\"\n"); xvgr_legend(out,NLEG,leg); } do { if (nz == 0) rm_pbc(&top.idef,ePBC,natoms,box,x,x_s); gyro = 0; clear_rvec(gvec); clear_rvec(d); for(mol=0; mol<nmol; mol++) { tm = sub_xcm(nz==0?x_s:x,nam,index+mol*nam,top.atoms.atom,xcm,bQ); if (nz == 0) gyro += calc_gyro(x_s,nam,index+mol*nam,top.atoms.atom, tm,gvec1,d1,bQ,bRot,bMOI,trans); else calc_gyro_z(x,box,nam,index+mol*nam,top.atoms.atom,nz,t,out); rvec_inc(gvec,gvec1); rvec_inc(d,d1); } if (nmol > 0) { gyro /= nmol; svmul(1.0/nmol,gvec,gvec); svmul(1.0/nmol,d,d); } if (nz == 0) { if (bRot) { if (j >= max_moi) { max_moi += delta_moi; for(m=0; (m<DIM); m++) srenew(moi_trans[m],max_moi*DIM); } for(m=0; (m<DIM); m++) copy_rvec(trans[m],moi_trans[m]+DIM*j); fprintf(out,"%10g %10g %10g %10g %10g\n", t,gyro,d[XX],d[YY],d[ZZ]); } else { fprintf(out,"%10g %10g %10g %10g %10g\n", t,gyro,gvec[XX],gvec[YY],gvec[ZZ]); } } j++; } while(read_next_x(status,&t,natoms,x,box)); close_trj(status); fclose(out); if (bACF) { int mode = eacVector; do_autocorr(opt2fn("-acf",NFILE,fnm), "Moment of inertia vector ACF", j,3,moi_trans,(t-t0)/j,mode,FALSE); do_view(opt2fn("-acf",NFILE,fnm),"-nxy"); } do_view(ftp2fn(efXVG,NFILE,fnm),"-nxy"); thanx(stderr); return 0; }
int gmx_gmx2xyz(int argc, char *argv[]) { const char *desc[] = { "\tThis convert from gromacs to Tinker .xyx.", "\n" }; t_topology top; t_atoms *atoms = NULL, useatoms; int ePBC; char title[STRLEN]; t_trxframe fr; rvec *xtop; matrix box; t_trxstatus *status; int flags = TRX_READ_X; int i_index; atom_id *ind_index; char *gn_index; const char *parm_name; output_env_t oenv; const char *tpr_file, *top_file, *in_file, *index_file, *out_file = NULL; char tpr_title[256], xyz[256]; t_bonded *bonds; t_pargs pa [] = { }; t_filenm fnm[] = { { efTPS, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efTOP, NULL, NULL, ffREAD }, { efRND, "-a", "amoeba.prm", ffREAD }, { efXYZ, "-o", NULL, ffWRITE }, { efNDX, NULL, NULL, ffREAD } }; #define NFILE asize(fnm) #define NPA asize(pa) CopyRight(stderr,argv[0]); parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT | PCA_BE_NICE, NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv); tpr_file = ftp2fn(efTPS, NFILE, fnm); top_file = ftp2fn(efTOP, NFILE, fnm); init_top(&top); in_file = opt2fn("-f", NFILE, fnm); parm_name = opt2fn("-a", NFILE, fnm); out_file = opt2fn("-o", NFILE,fnm); read_tps_conf(tpr_file, tpr_title, &top, &ePBC, &xtop, NULL, box, TRUE); atoms = &top.atoms; printf("Select group for to save atom coordinates:\n"); index_file = ftp2fn(efNDX, NFILE, fnm); get_index(atoms, index_file, 1, &i_index, &ind_index, &gn_index); snew(bonds,top.atoms.nr+1); bonds=read_topol(bonds,top_file); for (int i=0;i<top.atoms.nr;i++){ if (strncmp(*top.atoms.atomname[i],"OW",2) == 0) { bonds[i+1].nb = 2; bonds[i+1].bond[0] = i+1; bonds[i+1].bond[1] = i+2; } else if (strncmp(*top.atoms.atomname[i],"HW1",3) ==0) { bonds[i+1].nb = 1; bonds[i+1].bond[0] = i-1; } else if (strncmp(*top.atoms.atomname[i],"HW2",3) ==0) { bonds[i+1].nb = 1; bonds[i+1].bond[0] = i-2; } } /* for (int i=i_index-10;i<=i_index+17;i++) { printf("\n%i <%i>",i,bonds[i+1].nb); for (int j=0;j<bonds[i+1].nb;j++) { printf(" %i",bonds[i+1].bond[j]); } } */ int nparams = 967; /* I know this from playing around. There's gotta be a smarter way? */ amoeba_parm * atoms_types = (amoeba_parm*)malloc(sizeof(amoeba_parm)*nparams); atoms_types = read_amoeba_parameters( parm_name ); int * parmid = (int*)malloc(sizeof(int)*top.atoms.nr); parm_order(parmid, top, atoms_types, nparams,i_index,ind_index); read_first_frame(oenv, &status, in_file, &fr, flags); int resid; // strncpy(xyz_file,out_file,strlen(out_file)-4); int framen=0; char *xyz_file = out_file; xyz_file[strlen(xyz_file)-4] = 0; do { memset(xyz,0,sizeof(xyz)); memcpy(xyz,xyz_file,strlen(xyz_file));//-1); sprintf(xyz,"%s%i.xyz",xyz,framen); FILE * xyzout = ffopen(xyz,"w"); if (xyzout==NULL) { gmx_fatal(FARGS,"Failed to open output file, '%s'\n",xyz ); } fprintf(xyzout,"%7i %s",i_index,xyz); for (int n=0;n<i_index;n++) { char name[10]; int i = ind_index[n]; resid = top.atoms.atom[i].resind; strcpy(name,*top.atoms.atomname[i]); strcat(name,"."); strcat(name,*top.atoms.resinfo[resid].name); fprintf(xyzout,"\n%7i %9s %13.4f %13.4f %13.4f ",i+1,name,fr.x[i][XX]*10,fr.x[i][YY]*10,fr.x[i][ZZ]*10); fprintf(xyzout,"%7i ",parmid[i]); for (int j = 0; j < bonds[i+1].nb ; j++ ) { fprintf(xyzout,"%7i ",bonds[i+1].bond[j]); } } fclose(xyzout); framen++; } while(read_next_frame(oenv, status, &fr)); printf("\n"); thanx(stderr); return 0; }
int main(int argc, char *argv[]) { static char *desc[] = { "[TT]hrefify[tt] adds href's for all the words in the input file which are not", "already hyperlinked and which appear in the file specified with the", "option [TT]-l[tt].[PAR]", "If the href's should call a script, text can be added", "with the [TT]-t[tt] option." }; int n; char **text,**str,line[1024],*ptr,*ref, start[STRLEN],word[STRLEN],end[STRLEN]; int n_text,n_str,i_str; gmx_bool bInHREF,bIn; FILE *fp; char title[STRLEN]; int i,l,n_repl; t_filenm fnm[] = { { efDAT, "-l", "links", ffLIBRD }, }; #define NFILE asize(fnm) static char *in=NULL,*out=NULL,*excl=NULL,*link_text=NULL; static gmx_bool peratom=FALSE; t_pargs pa[] = { { "-f", FALSE, etSTR, { &in } , "HTML input" }, { "-o", FALSE, etSTR, { &out } , "HTML output" }, { "-e", FALSE, etSTR, { &excl } , "Exclude a string from HREF's, " "when this option is not set, the filename without path and extension " "will be excluded from HREF's"}, { "-t", FALSE, etSTR, { &link_text } , "Insert a string in front of the " "href file name, useful for scripts" } }; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa, asize(desc),desc,0,NULL); if (!in || !out) gmx_fatal(FARGS,"Input or output filename is not set"); n_text = get_file(in, &text); fprintf(stderr,"Read %d lines from %s\n",n_text,in); n_str=get_file(ftp2fn(efDAT,NFILE,fnm),&str); fprintf(stderr,"Read %d strings %s\n",n_str,ftp2fn(efDAT,NFILE,fnm)); if (!excl) { for (i=strlen(in)-1; i>0 && in[i-1]!='/'; i--); excl=strdup(in+i); for(i=strlen(excl)-1; i>0 && (excl[i]!='.'); i--); if (excl[i]=='.') excl[i]='\0'; } fprintf(stderr,"Excluding '%s' from references\n",excl); for(l=0; l<n_str && strcasecmp(str[l],excl); l++); if (l<n_str) { for(i=l+1; i<n_str; i++) str[i-1]=str[i]; n_str--; } if (!link_text) link_text=strdup("\0"); else fprintf(stderr,"Adding '%s' to href's\n",link_text); fp=gmx_ffopen(out,"w"); n_repl=0; i_str=-1; bInHREF=FALSE; for(l=0; l<n_text; l++) { strcpy(line,text[l]); do { bIn=bInHREF; ptr=strstr_href(line,&bIn,&i_str,n_str,str); if (ptr) { ref=ptr; if ((ref!=line) && (ref[-1]=='.')) { ref--; while((ref>line) && isword(ref[-1])) ref--; } strcpy(start,line); start[ref-line]='\0'; strcpy(word,ref); word[ptr-ref+strlen(str[i_str])]='\0'; strcpy(end,ptr+strlen(str[i_str])); sprintf(line,"%s<a href=\"%s%s.html\">%s</a>%s", start,link_text,str[i_str],word,end); fprintf(stderr,"line %d: %s\n",l+1,str[i_str]); n_repl++; } } while (ptr); bInHREF=bIn; fprintf(fp,"%s\n",line); } gmx_ffclose(fp); fprintf(stderr,"Added %d HTML references\n",n_repl); return 0; }
int gmx_disre(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes violations of distance restraints.", "The program always", "computes the instantaneous violations rather than time-averaged,", "because this analysis is done from a trajectory file afterwards", "it does not make sense to use time averaging. However,", "the time averaged values per restraint are given in the log file.[PAR]", "An index file may be used to select specific restraints for", "printing.[PAR]", "When the optional [TT]-q[tt] flag is given a [REF].pdb[ref] file coloured by the", "amount of average violations.[PAR]", "When the [TT]-c[tt] option is given, an index file will be read", "containing the frames in your trajectory corresponding to the clusters", "(defined in another manner) that you want to analyze. For these clusters", "the program will compute average violations using the third power", "averaging algorithm and print them in the log file." }; static int ntop = 0; static int nlevels = 20; static real max_dr = 0; static gmx_bool bThird = TRUE; t_pargs pa[] = { { "-ntop", FALSE, etINT, {&ntop}, "Number of large violations that are stored in the log file every step" }, { "-maxdr", FALSE, etREAL, {&max_dr}, "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." }, { "-nlevels", FALSE, etINT, {&nlevels}, "Number of levels in the matrix output" }, { "-third", FALSE, etBOOL, {&bThird}, "Use inverse third power averaging or linear for matrix output" } }; FILE *out = NULL, *aver = NULL, *numv = NULL, *maxxv = NULL, *xvg = NULL; t_tpxheader header; t_inputrec ir; gmx_mtop_t mtop; rvec *xtop; gmx_localtop_t *top; t_atoms *atoms = NULL; t_fcdata fcd; t_nrnb nrnb; t_graph *g; int ntopatoms, natoms, i, j, kkk; t_trxstatus *status; real t; rvec *x, *f, *xav = NULL; matrix box; gmx_bool bPDB; int isize; atom_id *index = NULL, *ind_fit = NULL; char *grpname; t_cluster_ndx *clust = NULL; t_dr_result dr, *dr_clust = NULL; char **leg; real *vvindex = NULL, *w_rls = NULL; t_mdatoms *mdatoms; t_pbc pbc, *pbc_null; int my_clust; FILE *fplog; output_env_t oenv; gmx_rmpbc_t gpbc = NULL; t_filenm fnm[] = { { efTPR, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efXVG, "-ds", "drsum", ffWRITE }, { efXVG, "-da", "draver", ffWRITE }, { efXVG, "-dn", "drnum", ffWRITE }, { efXVG, "-dm", "drmax", ffWRITE }, { efXVG, "-dr", "restr", ffWRITE }, { efLOG, "-l", "disres", ffWRITE }, { efNDX, NULL, "viol", ffOPTRD }, { efPDB, "-q", "viol", ffOPTWR }, { efNDX, "-c", "clust", ffOPTRD }, { efXPM, "-x", "matrix", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } fplog = ftp2FILE(efLOG, NFILE, fnm, "w"); if (ntop) { init5(ntop); } read_tpxheader(ftp2fn(efTPR, NFILE, fnm), &header, FALSE, NULL, NULL); snew(xtop, header.natoms); read_tpx(ftp2fn(efTPR, NFILE, fnm), &ir, box, &ntopatoms, xtop, NULL, &mtop); bPDB = opt2bSet("-q", NFILE, fnm); if (bPDB) { snew(xav, ntopatoms); snew(ind_fit, ntopatoms); snew(w_rls, ntopatoms); for (kkk = 0; (kkk < ntopatoms); kkk++) { w_rls[kkk] = 1; ind_fit[kkk] = kkk; } snew(atoms, 1); *atoms = gmx_mtop_global_atoms(&mtop); if (atoms->pdbinfo == NULL) { snew(atoms->pdbinfo, atoms->nr); } } top = gmx_mtop_generate_local_top(&mtop, &ir); g = NULL; pbc_null = NULL; if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) { pbc_null = &pbc; } else { g = mk_graph(fplog, &top->idef, 0, mtop.natoms, FALSE, FALSE); } } if (ftp2bSet(efNDX, NFILE, fnm)) { /* TODO: Nothing is written to this file if -c is provided, but it is * still opened... */ rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); xvg = xvgropen(opt2fn("-dr", NFILE, fnm), "Individual Restraints", "Time (ps)", "nm", oenv); snew(vvindex, isize); snew(leg, isize); for (i = 0; (i < isize); i++) { index[i]++; snew(leg[i], 12); sprintf(leg[i], "index %d", index[i]); } xvgr_legend(xvg, isize, (const char**)leg, oenv); } else { isize = 0; } ir.dr_tau = 0.0; init_disres(fplog, &mtop, &ir, NULL, &fcd, NULL, FALSE); natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); snew(f, 5*natoms); init_dr_res(&dr, fcd.disres.nres); if (opt2bSet("-c", NFILE, fnm)) { clust = cluster_index(fplog, opt2fn("-c", NFILE, fnm)); snew(dr_clust, clust->clust->nr+1); for (i = 0; (i <= clust->clust->nr); i++) { init_dr_res(&dr_clust[i], fcd.disres.nres); } } else { out = xvgropen(opt2fn("-ds", NFILE, fnm), "Sum of Violations", "Time (ps)", "nm", oenv); aver = xvgropen(opt2fn("-da", NFILE, fnm), "Average Violation", "Time (ps)", "nm", oenv); numv = xvgropen(opt2fn("-dn", NFILE, fnm), "# Violations", "Time (ps)", "#", oenv); maxxv = xvgropen(opt2fn("-dm", NFILE, fnm), "Largest Violation", "Time (ps)", "nm", oenv); } mdatoms = init_mdatoms(fplog, &mtop, ir.efep != efepNO); atoms2md(&mtop, &ir, 0, NULL, mtop.natoms, mdatoms); update_mdatoms(mdatoms, ir.fepvals->init_lambda); init_nrnb(&nrnb); if (ir.ePBC != epbcNONE) { gpbc = gmx_rmpbc_init(&top->idef, ir.ePBC, natoms); } j = 0; do { if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) { set_pbc(&pbc, ir.ePBC, box); } else { gmx_rmpbc(gpbc, natoms, box, x); } } if (clust) { if (j > clust->maxframe) { gmx_fatal(FARGS, "There are more frames in the trajectory than in the cluster index file. t = %8f\n", t); } my_clust = clust->inv_clust[j]; range_check(my_clust, 0, clust->clust->nr); check_viol(fplog, &(top->idef.il[F_DISRES]), top->idef.iparams, x, f, pbc_null, g, dr_clust, my_clust, isize, index, vvindex, &fcd); } else { check_viol(fplog, &(top->idef.il[F_DISRES]), top->idef.iparams, x, f, pbc_null, g, &dr, 0, isize, index, vvindex, &fcd); } if (bPDB) { reset_x(atoms->nr, ind_fit, atoms->nr, NULL, x, w_rls); do_fit(atoms->nr, w_rls, x, x); if (j == 0) { /* Store the first frame of the trajectory as 'characteristic' * for colouring with violations. */ for (kkk = 0; (kkk < atoms->nr); kkk++) { copy_rvec(x[kkk], xav[kkk]); } } } if (!clust) { if (isize > 0) { fprintf(xvg, "%10g", t); for (i = 0; (i < isize); i++) { fprintf(xvg, " %10g", vvindex[i]); } fprintf(xvg, "\n"); } fprintf(out, "%10g %10g\n", t, dr.sumv); fprintf(aver, "%10g %10g\n", t, dr.averv); fprintf(maxxv, "%10g %10g\n", t, dr.maxv); fprintf(numv, "%10g %10d\n", t, dr.nv); } j++; } while (read_next_x(oenv, status, &t, x, box)); close_trj(status); if (ir.ePBC != epbcNONE) { gmx_rmpbc_done(gpbc); } if (clust) { dump_clust_stats(fplog, fcd.disres.nres, &(top->idef.il[F_DISRES]), top->idef.iparams, clust->clust, dr_clust, clust->grpname, isize, index); } else { dump_stats(fplog, j, fcd.disres.nres, &(top->idef.il[F_DISRES]), top->idef.iparams, &dr, isize, index, bPDB ? atoms : NULL); if (bPDB) { write_sto_conf(opt2fn("-q", NFILE, fnm), "Coloured by average violation in Angstrom", atoms, xav, NULL, ir.ePBC, box); } dump_disre_matrix(opt2fn_null("-x", NFILE, fnm), &dr, fcd.disres.nres, j, &top->idef, &mtop, max_dr, nlevels, bThird); xvgrclose(out); xvgrclose(aver); xvgrclose(numv); xvgrclose(maxxv); do_view(oenv, opt2fn("-dn", NFILE, fnm), "-nxy"); do_view(oenv, opt2fn("-da", NFILE, fnm), "-nxy"); do_view(oenv, opt2fn("-ds", NFILE, fnm), "-nxy"); do_view(oenv, opt2fn("-dm", NFILE, fnm), "-nxy"); } if (isize > 0) { xvgrclose(xvg); if (!clust) { do_view(oenv, opt2fn("-dr", NFILE, fnm), "-nxy"); } } gmx_log_close(fplog); return 0; }
int gmx_enemat(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] extracts an energy matrix from the energy file ([TT]-f[tt]).", "With [TT]-groups[tt] a file must be supplied with on each", "line a group of atoms to be used. For these groups matrix of", "interaction energies will be extracted from the energy file", "by looking for energy groups with names corresponding to pairs", "of groups of atoms, e.g. if your [TT]-groups[tt] file contains::", "", " 2", " Protein", " SOL", "", "then energy groups with names like 'Coul-SR:Protein-SOL' and ", "'LJ:Protein-SOL' are expected in the energy file (although", "[THISMODULE] is most useful if many groups are analyzed", "simultaneously). Matrices for different energy types are written", "out separately, as controlled by the", "[TT]-[no]coul[tt], [TT]-[no]coulr[tt], [TT]-[no]coul14[tt], ", "[TT]-[no]lj[tt], [TT]-[no]lj14[tt], ", "[TT]-[no]bham[tt] and [TT]-[no]free[tt] options.", "Finally, the total interaction energy energy per group can be ", "calculated ([TT]-etot[tt]).[PAR]", "An approximation of the free energy can be calculated using:", "[MATH]E[SUB]free[sub] = E[SUB]0[sub] + kT [LOG][CHEVRON][EXP](E-E[SUB]0[sub])/kT[exp][chevron][log][math], where '[MATH][CHEVRON][chevron][math]'", "stands for time-average. A file with reference free energies", "can be supplied to calculate the free energy difference", "with some reference state. Group names (e.g. residue names)", "in the reference file should correspond to the group names", "as used in the [TT]-groups[tt] file, but a appended number", "(e.g. residue number) in the [TT]-groups[tt] will be ignored", "in the comparison." }; static gmx_bool bSum = FALSE; static gmx_bool bMeanEmtx = TRUE; static int skip = 0, nlevels = 20; static real cutmax = 1e20, cutmin = -1e20, reftemp = 300.0; static gmx_bool bCoulSR = TRUE, bCoulLR = FALSE, bCoul14 = FALSE; static gmx_bool bLJSR = TRUE, bLJLR = FALSE, bLJ14 = FALSE, bBhamSR = FALSE, bBhamLR = FALSE, bFree = TRUE; t_pargs pa[] = { { "-sum", FALSE, etBOOL, {&bSum}, "Sum the energy terms selected rather than display them all" }, { "-skip", FALSE, etINT, {&skip}, "Skip number of frames between data points" }, { "-mean", FALSE, etBOOL, {&bMeanEmtx}, "with [TT]-groups[tt] extracts matrix of mean energies instead of " "matrix for each timestep" }, { "-nlevels", FALSE, etINT, {&nlevels}, "number of levels for matrix colors"}, { "-max", FALSE, etREAL, {&cutmax}, "max value for energies"}, { "-min", FALSE, etREAL, {&cutmin}, "min value for energies"}, { "-coulsr", FALSE, etBOOL, {&bCoulSR}, "extract Coulomb SR energies"}, { "-coullr", FALSE, etBOOL, {&bCoulLR}, "extract Coulomb LR energies"}, { "-coul14", FALSE, etBOOL, {&bCoul14}, "extract Coulomb 1-4 energies"}, { "-ljsr", FALSE, etBOOL, {&bLJSR}, "extract Lennard-Jones SR energies"}, { "-ljlr", FALSE, etBOOL, {&bLJLR}, "extract Lennard-Jones LR energies"}, { "-lj14", FALSE, etBOOL, {&bLJ14}, "extract Lennard-Jones 1-4 energies"}, { "-bhamsr", FALSE, etBOOL, {&bBhamSR}, "extract Buckingham SR energies"}, { "-bhamlr", FALSE, etBOOL, {&bBhamLR}, "extract Buckingham LR energies"}, { "-free", FALSE, etBOOL, {&bFree}, "calculate free energy"}, { "-temp", FALSE, etREAL, {&reftemp}, "reference temperature for free energy calculation"} }; /* We will define egSP more energy-groups: egTotal (total energy) */ #define egTotal egNR #define egSP 1 gmx_bool egrp_use[egNR+egSP]; ener_file_t in; FILE *out; int timecheck = 0; gmx_enxnm_t *enm = NULL; t_enxframe *fr; int teller = 0; real sum; gmx_bool bCont, bRef; gmx_bool bCutmax, bCutmin; real **eneset, *time = NULL; int *set, i, j, k, prevk, m = 0, n, nre, nset, nenergy; char **groups = NULL; char groupname[255], fn[255]; int ngroups; t_rgb rlo, rhi, rmid; real emax, emid, emin; real ***emat, **etot, *groupnr; double beta, expE, **e, *eaver, *efree = NULL, edum; char label[234]; char **ereflines, **erefres = NULL; real *eref = NULL, *edif = NULL; int neref = 0; output_env_t oenv; t_filenm fnm[] = { { efEDR, "-f", NULL, ffOPTRD }, { efDAT, "-groups", "groups", ffREAD }, { efDAT, "-eref", "eref", ffOPTRD }, { efXPM, "-emat", "emat", ffWRITE }, { efXVG, "-etot", "energy", ffWRITE } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } for (i = 0; (i < egNR+egSP); i++) { egrp_use[i] = FALSE; } egrp_use[egCOULSR] = bCoulSR; egrp_use[egLJSR] = bLJSR; egrp_use[egBHAMSR] = bBhamSR; egrp_use[egCOULLR] = bCoulLR; egrp_use[egLJLR] = bLJLR; egrp_use[egBHAMLR] = bBhamLR; egrp_use[egCOUL14] = bCoul14; egrp_use[egLJ14] = bLJ14; egrp_use[egTotal] = TRUE; bRef = opt2bSet("-eref", NFILE, fnm); in = open_enx(ftp2fn(efEDR, NFILE, fnm), "r"); do_enxnms(in, &nre, &enm); if (nre == 0) { gmx_fatal(FARGS, "No energies!\n"); } bCutmax = opt2parg_bSet("-max", asize(pa), pa); bCutmin = opt2parg_bSet("-min", asize(pa), pa); nenergy = 0; /* Read groupnames from input file and construct selection of energy groups from it*/ fprintf(stderr, "Will read groupnames from inputfile\n"); ngroups = get_lines(opt2fn("-groups", NFILE, fnm), &groups); fprintf(stderr, "Read %d groups\n", ngroups); snew(set, static_cast<size_t>(sqr(ngroups)*egNR/2)); n = 0; prevk = 0; for (i = 0; (i < ngroups); i++) { fprintf(stderr, "\rgroup %d", i); for (j = i; (j < ngroups); j++) { for (m = 0; (m < egNR); m++) { if (egrp_use[m]) { sprintf(groupname, "%s:%s-%s", egrp_nm[m], groups[i], groups[j]); #ifdef DEBUG fprintf(stderr, "\r%-15s %5d", groupname, n); #endif for (k = prevk; (k < prevk+nre); k++) { if (std::strcmp(enm[k%nre].name, groupname) == 0) { set[n++] = k; break; } } if (k == prevk+nre) { fprintf(stderr, "WARNING! could not find group %s (%d,%d)" "in energy file\n", groupname, i, j); } else { prevk = k; } } } } } fprintf(stderr, "\n"); nset = n; snew(eneset, nset+1); fprintf(stderr, "Will select half-matrix of energies with %d elements\n", n); /* Start reading energy frames */ snew(fr, 1); do { do { bCont = do_enx(in, fr); if (bCont) { timecheck = check_times(fr->t); } } while (bCont && (timecheck < 0)); if (timecheck == 0) { #define DONTSKIP(cnt) (skip) ? ((cnt % skip) == 0) : TRUE if (bCont) { fprintf(stderr, "\rRead frame: %d, Time: %.3f", teller, fr->t); if ((nenergy % 1000) == 0) { srenew(time, nenergy+1000); for (i = 0; (i <= nset); i++) { srenew(eneset[i], nenergy+1000); } } time[nenergy] = fr->t; sum = 0; for (i = 0; (i < nset); i++) { eneset[i][nenergy] = fr->ener[set[i]].e; sum += fr->ener[set[i]].e; } if (bSum) { eneset[nset][nenergy] = sum; } nenergy++; } teller++; } } while (bCont && (timecheck == 0)); fprintf(stderr, "\n"); fprintf(stderr, "Will build energy half-matrix of %d groups, %d elements, " "over %d frames\n", ngroups, nset, nenergy); snew(emat, egNR+egSP); for (j = 0; (j < egNR+egSP); j++) { if (egrp_use[m]) { snew(emat[j], ngroups); for (i = 0; (i < ngroups); i++) { snew(emat[j][i], ngroups); } } } snew(groupnr, ngroups); for (i = 0; (i < ngroups); i++) { groupnr[i] = i+1; } rlo.r = 1.0, rlo.g = 0.0, rlo.b = 0.0; rmid.r = 1.0, rmid.g = 1.0, rmid.b = 1.0; rhi.r = 0.0, rhi.g = 0.0, rhi.b = 1.0; if (bMeanEmtx) { snew(e, ngroups); for (i = 0; (i < ngroups); i++) { snew(e[i], nenergy); } n = 0; for (i = 0; (i < ngroups); i++) { for (j = i; (j < ngroups); j++) { for (m = 0; (m < egNR); m++) { if (egrp_use[m]) { for (k = 0; (k < nenergy); k++) { emat[m][i][j] += eneset[n][k]; e[i][k] += eneset[n][k]; /* *0.5; */ e[j][k] += eneset[n][k]; /* *0.5; */ } n++; emat[egTotal][i][j] += emat[m][i][j]; emat[m][i][j] /= nenergy; emat[m][j][i] = emat[m][i][j]; } } emat[egTotal][i][j] /= nenergy; emat[egTotal][j][i] = emat[egTotal][i][j]; } } if (bFree) { if (bRef) { fprintf(stderr, "Will read reference energies from inputfile\n"); neref = get_lines(opt2fn("-eref", NFILE, fnm), &ereflines); fprintf(stderr, "Read %d reference energies\n", neref); snew(eref, neref); snew(erefres, neref); for (i = 0; (i < neref); i++) { snew(erefres[i], 5); sscanf(ereflines[i], "%s %lf", erefres[i], &edum); eref[i] = edum; } } snew(eaver, ngroups); for (i = 0; (i < ngroups); i++) { for (k = 0; (k < nenergy); k++) { eaver[i] += e[i][k]; } eaver[i] /= nenergy; } beta = 1.0/(BOLTZ*reftemp); snew(efree, ngroups); snew(edif, ngroups); for (i = 0; (i < ngroups); i++) { expE = 0; for (k = 0; (k < nenergy); k++) { expE += std::exp(beta*(e[i][k]-eaver[i])); } efree[i] = std::log(expE/nenergy)/beta + eaver[i]; if (bRef) { n = search_str2(neref, erefres, groups[i]); if (n != -1) { edif[i] = efree[i]-eref[n]; } else { edif[i] = efree[i]; fprintf(stderr, "WARNING: group %s not found " "in reference energies.\n", groups[i]); } } else { edif[i] = 0; } } } emid = 0.0; /*(emin+emax)*0.5;*/ egrp_nm[egTotal] = "total"; for (m = 0; (m < egNR+egSP); m++) { if (egrp_use[m]) { emin = 1e10; emax = -1e10; for (i = 0; (i < ngroups); i++) { for (j = i; (j < ngroups); j++) { if (emat[m][i][j] > emax) { emax = emat[m][i][j]; } else if (emat[m][i][j] < emin) { emin = emat[m][i][j]; } } } if (emax == emin) { fprintf(stderr, "Matrix of %s energy is uniform at %f " "(will not produce output).\n", egrp_nm[m], emax); } else { fprintf(stderr, "Matrix of %s energy ranges from %f to %f\n", egrp_nm[m], emin, emax); if ((bCutmax) || (emax > cutmax)) { emax = cutmax; } if ((bCutmin) || (emin < cutmin)) { emin = cutmin; } if ((emax == cutmax) || (emin == cutmin)) { fprintf(stderr, "Energy range adjusted: %f to %f\n", emin, emax); } sprintf(fn, "%s%s", egrp_nm[m], ftp2fn(efXPM, NFILE, fnm)); sprintf(label, "%s Interaction Energies", egrp_nm[m]); out = gmx_ffopen(fn, "w"); if (emin >= emid) { write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index", "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emid, emax, rmid, rhi, &nlevels); } else if (emax <= emid) { write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index", "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emin, emid, rlo, rmid, &nlevels); } else { write_xpm3(out, 0, label, "Energy (kJ/mol)", "Residue Index", "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emin, emid, emax, rlo, rmid, rhi, &nlevels); } gmx_ffclose(out); } } } snew(etot, egNR+egSP); for (m = 0; (m < egNR+egSP); m++) { snew(etot[m], ngroups); for (i = 0; (i < ngroups); i++) { for (j = 0; (j < ngroups); j++) { etot[m][i] += emat[m][i][j]; } } } out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Mean Energy", "Residue", "kJ/mol", oenv); xvgr_legend(out, 0, NULL, oenv); j = 0; if (output_env_get_print_xvgr_codes(oenv)) { char str1[STRLEN], str2[STRLEN]; if (output_env_get_xvg_format(oenv) == exvgXMGR) { sprintf(str1, "@ legend string "); sprintf(str2, " "); } else { sprintf(str1, "@ s"); sprintf(str2, " legend "); } for (m = 0; (m < egNR+egSP); m++) { if (egrp_use[m]) { fprintf(out, "%s%d%s \"%s\"\n", str1, j++, str2, egrp_nm[m]); } } if (bFree) { fprintf(out, "%s%d%s \"%s\"\n", str1, j++, str2, "Free"); } if (bFree) { fprintf(out, "%s%d%s \"%s\"\n", str1, j++, str2, "Diff"); } fprintf(out, "@TYPE xy\n"); fprintf(out, "#%3s", "grp"); for (m = 0; (m < egNR+egSP); m++) { if (egrp_use[m]) { fprintf(out, " %9s", egrp_nm[m]); } } if (bFree) { fprintf(out, " %9s", "Free"); } if (bFree) { fprintf(out, " %9s", "Diff"); } fprintf(out, "\n"); } for (i = 0; (i < ngroups); i++) { fprintf(out, "%3.0f", groupnr[i]); for (m = 0; (m < egNR+egSP); m++) { if (egrp_use[m]) { fprintf(out, " %9.5g", etot[m][i]); } } if (bFree) { fprintf(out, " %9.5g", efree[i]); } if (bRef) { fprintf(out, " %9.5g", edif[i]); } fprintf(out, "\n"); } xvgrclose(out); } else { fprintf(stderr, "While typing at your keyboard, suddenly...\n" "...nothing happens.\nWARNING: Not Implemented Yet\n"); /* out=ftp2FILE(efMAT,NFILE,fnm,"w"); n=0; emin=emax=0.0; for (k=0; (k<nenergy); k++) { for (i=0; (i<ngroups); i++) for (j=i+1; (j<ngroups); j++) emat[i][j]=eneset[n][k]; sprintf(label,"t=%.0f ps",time[k]); write_matrix(out,ngroups,1,ngroups,groupnr,emat,label,emin,emax,nlevels); n++; } gmx_ffclose(out); */ } close_enx(in); return 0; }
int gmx_sorient(int argc, char *argv[]) { t_topology top; int ePBC = -1; t_trxstatus *status; int natoms; real t; rvec *xtop, *x; matrix box; FILE *fp; int i, p, sa0, sa1, sa2, n, ntot, nf, m, *hist1, *hist2, *histn, nbin1, nbin2, nrbin; real *histi1, *histi2, invbw, invrbw; double sum1, sum2; int *isize, nrefgrp, nrefat; atom_id **index; char **grpname; real inp, outp, nav, normfac, rmin2, rmax2, rcut, rcut2, r2, r; real c1, c2; char str[STRLEN]; gmx_bool bTPS; rvec xref, dx, dxh1, dxh2, outer; gmx_rmpbc_t gpbc = NULL; t_pbc pbc; const char *legr[] = { "<cos(\\8q\\4\\s1\\N)>", "<3cos\\S2\\N(\\8q\\4\\s2\\N)-1>" }; const char *legc[] = { "cos(\\8q\\4\\s1\\N)", "3cos\\S2\\N(\\8q\\4\\s2\\N)-1" }; const char *desc[] = { "[THISMODULE] analyzes solvent orientation around solutes.", "It calculates two angles between the vector from one or more", "reference positions to the first atom of each solvent molecule:", "", " * [GRK]theta[grk][SUB]1[sub]: the angle with the vector from the first atom of the solvent", " molecule to the midpoint between atoms 2 and 3.", " * [GRK]theta[grk][SUB]2[sub]: the angle with the normal of the solvent plane, defined by the", " same three atoms, or, when the option [TT]-v23[tt] is set, ", " the angle with the vector between atoms 2 and 3.", "", "The reference can be a set of atoms or", "the center of mass of a set of atoms. The group of solvent atoms should", "consist of 3 atoms per solvent molecule.", "Only solvent molecules between [TT]-rmin[tt] and [TT]-rmax[tt] are", "considered for [TT]-o[tt] and [TT]-no[tt] each frame.[PAR]", "[TT]-o[tt]: distribtion of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] for rmin<=r<=rmax.[PAR]", "[TT]-no[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]2[sub][cos][math] for rmin<=r<=rmax.[PAR]", "[TT]-ro[tt]: [MATH][CHEVRON][COS][GRK]theta[grk][SUB]1[sub][cos][chevron][math] and [MATH][CHEVRON]3[COS]^2[GRK]theta[grk][SUB]2[sub][cos]-1[chevron][math] as a function of the", "distance.[PAR]", "[TT]-co[tt]: the sum over all solvent molecules within distance r", "of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] and [MATH]3[COS]^2([GRK]theta[grk][SUB]2[sub])-1[cos][math] as a function of r.[PAR]", "[TT]-rc[tt]: the distribution of the solvent molecules as a function of r" }; gmx_output_env_t *oenv; static gmx_bool bCom = FALSE, bVec23 = FALSE, bPBC = FALSE; static real rmin = 0.0, rmax = 0.5, binwidth = 0.02, rbinw = 0.02; t_pargs pa[] = { { "-com", FALSE, etBOOL, {&bCom}, "Use the center of mass as the reference postion" }, { "-v23", FALSE, etBOOL, {&bVec23}, "Use the vector between atoms 2 and 3" }, { "-rmin", FALSE, etREAL, {&rmin}, "Minimum distance (nm)" }, { "-rmax", FALSE, etREAL, {&rmax}, "Maximum distance (nm)" }, { "-cbin", FALSE, etREAL, {&binwidth}, "Binwidth for the cosine" }, { "-rbin", FALSE, etREAL, {&rbinw}, "Binwidth for r (nm)" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Check PBC for the center of mass calculation. Only necessary when your reference group consists of several molecules." } }; t_filenm fnm[] = { { efTRX, NULL, NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, NULL, "sori", ffWRITE }, { efXVG, "-no", "snor", ffWRITE }, { efXVG, "-ro", "sord", ffWRITE }, { efXVG, "-co", "scum", ffWRITE }, { efXVG, "-rc", "scount", ffWRITE } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bTPS = (opt2bSet("-s", NFILE, fnm) || !opt2bSet("-n", NFILE, fnm) || bCom); if (bTPS) { read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, NULL, box, bCom); } /* get index groups */ printf("Select a group of reference particles and a solvent group:\n"); snew(grpname, 2); snew(index, 2); snew(isize, 2); if (bTPS) { get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpname); } else { get_index(NULL, ftp2fn(efNDX, NFILE, fnm), 2, isize, index, grpname); } if (bCom) { nrefgrp = 1; nrefat = isize[0]; } else { nrefgrp = isize[0]; nrefat = 1; } if (isize[1] % 3) { gmx_fatal(FARGS, "The number of solvent atoms (%d) is not a multiple of 3", isize[1]); } /* initialize reading trajectory: */ natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); rmin2 = sqr(rmin); rmax2 = sqr(rmax); rcut = 0.99*std::sqrt(max_cutoff2(guess_ePBC(box), box)); if (rcut == 0) { rcut = 10*rmax; } rcut2 = sqr(rcut); invbw = 1/binwidth; nbin1 = 1+static_cast<int>(2*invbw + 0.5); nbin2 = 1+static_cast<int>(invbw + 0.5); invrbw = 1/rbinw; snew(hist1, nbin1); snew(hist2, nbin2); nrbin = 1+static_cast<int>(rcut/rbinw); if (nrbin == 0) { nrbin = 1; } snew(histi1, nrbin); snew(histi2, nrbin); snew(histn, nrbin); ntot = 0; nf = 0; sum1 = 0; sum2 = 0; if (bTPS) { /* make molecules whole again */ gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms); } /* start analysis of trajectory */ do { if (bTPS) { /* make molecules whole again */ gmx_rmpbc(gpbc, natoms, box, x); } set_pbc(&pbc, ePBC, box); n = 0; inp = 0; for (p = 0; (p < nrefgrp); p++) { if (bCom) { calc_com_pbc(nrefat, &top, x, &pbc, index[0], xref, bPBC); } else { copy_rvec(x[index[0][p]], xref); } for (m = 0; m < isize[1]; m += 3) { sa0 = index[1][m]; sa1 = index[1][m+1]; sa2 = index[1][m+2]; range_check(sa0, 0, natoms); range_check(sa1, 0, natoms); range_check(sa2, 0, natoms); pbc_dx(&pbc, x[sa0], xref, dx); r2 = norm2(dx); if (r2 < rcut2) { r = std::sqrt(r2); if (!bVec23) { /* Determine the normal to the plain */ rvec_sub(x[sa1], x[sa0], dxh1); rvec_sub(x[sa2], x[sa0], dxh2); rvec_inc(dxh1, dxh2); svmul(1/r, dx, dx); unitv(dxh1, dxh1); inp = iprod(dx, dxh1); cprod(dxh1, dxh2, outer); unitv(outer, outer); outp = iprod(dx, outer); } else { /* Use the vector between the 2nd and 3rd atom */ rvec_sub(x[sa2], x[sa1], dxh2); unitv(dxh2, dxh2); outp = iprod(dx, dxh2)/r; } { int ii = static_cast<int>(invrbw*r); range_check(ii, 0, nrbin); histi1[ii] += inp; histi2[ii] += 3*sqr(outp) - 1; histn[ii]++; } if ((r2 >= rmin2) && (r2 < rmax2)) { int ii1 = static_cast<int>(invbw*(inp + 1)); int ii2 = static_cast<int>(invbw*std::abs(outp)); range_check(ii1, 0, nbin1); range_check(ii2, 0, nbin2); hist1[ii1]++; hist2[ii2]++; sum1 += inp; sum2 += outp; n++; } } } } ntot += n; nf++; } while (read_next_x(oenv, status, &t, x, box)); /* clean up */ sfree(x); close_trj(status); gmx_rmpbc_done(gpbc); /* Add the bin for the exact maximum to the previous bin */ hist1[nbin1-1] += hist1[nbin1]; hist2[nbin2-1] += hist2[nbin2]; nav = static_cast<real>(ntot)/(nrefgrp*nf); normfac = invbw/ntot; fprintf(stderr, "Average nr of molecules between %g and %g nm: %.1f\n", rmin, rmax, nav); if (ntot > 0) { sum1 /= ntot; sum2 /= ntot; fprintf(stderr, "Average cos(theta1) between %g and %g nm: %6.3f\n", rmin, rmax, sum1); fprintf(stderr, "Average 3cos2(theta2)-1 between %g and %g nm: %6.3f\n", rmin, rmax, sum2); } sprintf(str, "Solvent orientation between %g and %g nm", rmin, rmax); fp = xvgropen(opt2fn("-o", NFILE, fnm), str, "cos(\\8q\\4\\s1\\N)", "", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"average shell size %.1f molecules\"\n", nav); } for (i = 0; i < nbin1; i++) { fprintf(fp, "%g %g\n", (i+0.5)*binwidth-1, 2*normfac*hist1[i]); } xvgrclose(fp); sprintf(str, "Solvent normal orientation between %g and %g nm", rmin, rmax); fp = xvgropen(opt2fn("-no", NFILE, fnm), str, "cos(\\8q\\4\\s2\\N)", "", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"average shell size %.1f molecules\"\n", nav); } for (i = 0; i < nbin2; i++) { fprintf(fp, "%g %g\n", (i+0.5)*binwidth, normfac*hist2[i]); } xvgrclose(fp); sprintf(str, "Solvent orientation"); fp = xvgropen(opt2fn("-ro", NFILE, fnm), str, "r (nm)", "", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"as a function of distance\"\n"); } xvgr_legend(fp, 2, legr, oenv); for (i = 0; i < nrbin; i++) { fprintf(fp, "%g %g %g\n", (i+0.5)*rbinw, histn[i] ? histi1[i]/histn[i] : 0, histn[i] ? histi2[i]/histn[i] : 0); } xvgrclose(fp); sprintf(str, "Cumulative solvent orientation"); fp = xvgropen(opt2fn("-co", NFILE, fnm), str, "r (nm)", "", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"as a function of distance\"\n"); } xvgr_legend(fp, 2, legc, oenv); normfac = 1.0/(nrefgrp*nf); c1 = 0; c2 = 0; fprintf(fp, "%g %g %g\n", 0.0, c1, c2); for (i = 0; i < nrbin; i++) { c1 += histi1[i]*normfac; c2 += histi2[i]*normfac; fprintf(fp, "%g %g %g\n", (i+1)*rbinw, c1, c2); } xvgrclose(fp); sprintf(str, "Solvent distribution"); fp = xvgropen(opt2fn("-rc", NFILE, fnm), str, "r (nm)", "molecules/nm", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"as a function of distance\"\n"); } normfac = 1.0/(rbinw*nf); for (i = 0; i < nrbin; i++) { fprintf(fp, "%g %g\n", (i+0.5)*rbinw, histn[i]*normfac); } xvgrclose(fp); do_view(oenv, opt2fn("-o", NFILE, fnm), NULL); do_view(oenv, opt2fn("-no", NFILE, fnm), NULL); do_view(oenv, opt2fn("-ro", NFILE, fnm), "-nxy"); do_view(oenv, opt2fn("-co", NFILE, fnm), "-nxy"); return 0; }
int gmx_trjcat(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] concatenates several input trajectory files in sorted order. ", "In case of double time frames the one in the later file is used. ", "By specifying [TT]-settime[tt] you will be asked for the start time ", "of each file. The input files are taken from the command line, ", "such that a command like [TT]gmx trjcat -f *.trr -o fixed.trr[tt] should do ", "the trick. Using [TT]-cat[tt], you can simply paste several files ", "together without removal of frames with identical time stamps.[PAR]", "One important option is inferred when the output file is amongst the", "input files. In that case that particular file will be appended to", "which implies you do not need to store double the amount of data.", "Obviously the file to append to has to be the one with lowest starting", "time since one can only append at the end of a file.[PAR]", "If the [TT]-demux[tt] option is given, the N trajectories that are", "read, are written in another order as specified in the [REF].xvg[ref] file.", "The [REF].xvg[ref] file should contain something like::", "", " 0 0 1 2 3 4 5", " 2 1 0 2 3 5 4", "", "The first number is the time, and subsequent numbers point to", "trajectory indices.", "The frames corresponding to the numbers present at the first line", "are collected into the output trajectory. If the number of frames in", "the trajectory does not match that in the [REF].xvg[ref] file then the program", "tries to be smart. Beware." }; static gmx_bool bVels = TRUE; 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)" }, { "-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" }, { "-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 = NOTSET, last_ok_t = -1, timestep; real last_frame_time, searchtime; int isize = 0, j; atom_id *index = NULL, imax; char *grpname; real **val = NULL, *t = NULL, dt_remd; int n, nset, ftpout = -1, prevEndStep = 0, filetype; gmx_off_t fpos; 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 = 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 = 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", gmx_nint(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; } 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; 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."); } } 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; 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; 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; 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)); } } } } 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; }