void low_rmsd_dist(const char *fn, real maxrms, int nn, real **mat, const gmx_output_env_t *oenv) { FILE *fp; int i, j, *histo, x; real fac; fac = 100/maxrms; snew(histo, 101); for (i = 0; i < nn; i++) { for (j = i+1; j < nn; j++) { x = static_cast<int>(fac*mat[i][j]+0.5); if (x <= 100) { histo[x]++; } } } fp = xvgropen(fn, "RMS Distribution", "RMS (nm)", "a.u.", oenv); for (i = 0; (i < 101); i++) { fprintf(fp, "%10g %10d\n", i/fac, histo[i]); } xvgrclose(fp); sfree(histo); }
void histogram(const char *distfile, real binwidth, int n, int nset, real **val, const gmx_output_env_t *oenv) { FILE *fp; int i, s; double minval, maxval; int nbin; gmx_int64_t *histo; minval = val[0][0]; maxval = val[0][0]; for (s = 0; s < nset; s++) { for (i = 0; i < n; i++) { if (val[s][i] < minval) { minval = val[s][i]; } else if (val[s][i] > maxval) { maxval = val[s][i]; } } } minval = binwidth*std::floor(minval/binwidth); maxval = binwidth*std::ceil(maxval/binwidth); if (minval != 0) { minval -= binwidth; } maxval += binwidth; nbin = static_cast<int>(((maxval - minval)/binwidth + 0.5) + 1); fprintf(stderr, "Making distributions with %d bins\n", nbin); snew(histo, nbin); fp = xvgropen(distfile, "Distribution", "", "", oenv); for (s = 0; s < nset; s++) { for (i = 0; i < nbin; i++) { histo[i] = 0; } for (i = 0; i < n; i++) { histo[static_cast<int>((val[s][i] - minval)/binwidth + 0.5)]++; } for (i = 0; i < nbin; i++) { fprintf(fp, " %g %g\n", minval+i*binwidth, static_cast<double>(histo[i])/(n*binwidth)); } if (s < nset-1) { fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } } xvgrclose(fp); }
void histogram(const char *distfile, real binwidth, int n, int nset, real **val, const output_env_t oenv) { FILE *fp; int i, s; double min, max; int nbin; gmx_int64_t *histo; min = val[0][0]; max = val[0][0]; for (s = 0; s < nset; s++) { for (i = 0; i < n; i++) { if (val[s][i] < min) { min = val[s][i]; } else if (val[s][i] > max) { max = val[s][i]; } } } min = binwidth*floor(min/binwidth); max = binwidth*ceil(max/binwidth); if (min != 0) { min -= binwidth; } max += binwidth; nbin = (int)((max - min)/binwidth + 0.5) + 1; fprintf(stderr, "Making distributions with %d bins\n", nbin); snew(histo, nbin); fp = xvgropen(distfile, "Distribution", "", "", oenv); for (s = 0; s < nset; s++) { for (i = 0; i < nbin; i++) { histo[i] = 0; } for (i = 0; i < n; i++) { histo[(int)((val[s][i] - min)/binwidth + 0.5)]++; } for (i = 0; i < nbin; i++) { fprintf(fp, " %g %g\n", min+i*binwidth, (double)histo[i]/(n*binwidth)); } if (s < nset-1) { fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } } xvgrclose(fp); }
static void do_ballistic(const char *balFile, int nData, real *t, real **val, int nSet, real balTime, int nBalExp, const output_env_t oenv) { double **ctd = NULL, *td = NULL; t_gemParams *GP = init_gemParams(0, 0, t, nData, 0, 0, 0, balTime, nBalExp); static char *leg[] = {"Ac'(t)"}; FILE *fp; int i, set; if (GP->ballistic/GP->tDelta >= GP->nExpFit*2+1) { snew(ctd, nSet); snew(td, nData); fp = xvgropen(balFile, "Hydrogen Bond Autocorrelation", "Time (ps)", "C'(t)", oenv); xvgr_legend(fp, asize(leg), (const char**)leg, oenv); for (set = 0; set < nSet; set++) { snew(ctd[set], nData); for (i = 0; i < nData; i++) { ctd[set][i] = (double)val[set][i]; if (set == 0) { td[i] = (double)t[i]; } } takeAwayBallistic(ctd[set], td, nData, GP->ballistic, GP->nExpFit, GP->bDt); } for (i = 0; i < nData; i++) { fprintf(fp, " %g", t[i]); for (set = 0; set < nSet; set++) { fprintf(fp, " %g", ctd[set][i]); } fprintf(fp, "\n"); } for (set = 0; set < nSet; set++) { sfree(ctd[set]); } sfree(ctd); sfree(td); xvgrclose(fp); } else { printf("Number of data points is less than the number of parameters to fit\n." "The system is underdetermined, hence no ballistic term can be found.\n\n"); } }
static void ehisto(const char *fh, int n, real **enerT, const output_env_t oenv) { FILE *fp; int i, j, k, nbin, blength; int *bindex; real *T, bmin, bmax, bwidth; int **histo; bmin = 1e8; bmax = -1e8; snew(bindex, n); snew(T, n); nbin = 0; for (j = 1; (j < n); j++) { for (k = 0; (k < nbin); k++) { if (T[k] == enerT[1][j]) { bindex[j] = k; break; } } if (k == nbin) { bindex[j] = nbin; T[nbin] = enerT[1][j]; nbin++; } bmin = std::min(enerT[0][j], bmin); bmax = std::max(enerT[0][j], bmax); } bwidth = 1.0; blength = static_cast<int>((bmax - bmin)/bwidth + 2); snew(histo, nbin); for (i = 0; (i < nbin); i++) { snew(histo[i], blength); } for (j = 0; (j < n); j++) { k = static_cast<int>((enerT[0][j]-bmin)/bwidth); histo[bindex[j]][k]++; } fp = xvgropen(fh, "Energy distribution", "E (kJ/mol)", "", oenv); for (j = 0; (j < blength); j++) { fprintf(fp, "%8.3f", bmin+j*bwidth); for (k = 0; (k < nbin); k++) { fprintf(fp, " %6d", histo[k][j]); } fprintf(fp, "\n"); } xvgrclose(fp); }
void plot_potential(double *potential[], double *charge[], double *field[], const char *afile, const char *bfile, const char *cfile, int nslices, int nr_grps, const char *grpname[], double slWidth, const gmx_output_env_t *oenv) { FILE *pot, /* xvgr file with potential */ *cha, /* xvgr file with charges */ *fie; /* xvgr files with fields */ char buf[256]; /* for xvgr title */ int slice, n; sprintf(buf, "Electrostatic Potential"); pot = xvgropen(afile, buf, "Box (nm)", "Potential (V)", oenv); xvgr_legend(pot, nr_grps, grpname, oenv); sprintf(buf, "Charge Distribution"); cha = xvgropen(bfile, buf, "Box (nm)", "Charge density (q/nm\\S3\\N)", oenv); xvgr_legend(cha, nr_grps, grpname, oenv); sprintf(buf, "Electric Field"); fie = xvgropen(cfile, buf, "Box (nm)", "Field (V/nm)", oenv); xvgr_legend(fie, nr_grps, grpname, oenv); for (slice = cb; slice < (nslices - ce); slice++) { fprintf(pot, "%20.16g ", slice * slWidth); fprintf(cha, "%20.16g ", slice * slWidth); fprintf(fie, "%20.16g ", slice * slWidth); for (n = 0; n < nr_grps; n++) { fprintf(pot, " %20.16g", potential[n][slice]); fprintf(fie, " %20.16g", field[n][slice]/1e9); /* convert to V/nm */ fprintf(cha, " %20.16g", charge[n][slice]); } fprintf(pot, "\n"); fprintf(cha, "\n"); fprintf(fie, "\n"); } xvgrclose(pot); xvgrclose(cha); xvgrclose(fie); }
static void do_geminate(const char *gemFile, int nData, real *t, real **val, int nSet, const real D, const real rcut, const real balTime, const int nFitPoints, const real begFit, const real endFit, const output_env_t oenv) { double **ctd = NULL, **ctdGem = NULL, *td = NULL; t_gemParams *GP = init_gemParams(rcut, D, t, nData, nFitPoints, begFit, endFit, balTime, 1); const char *leg[] = {"Ac\\sgem\\N(t)"}; FILE *fp; int i, set; snew(ctd, nSet); snew(ctdGem, nSet); snew(td, nData); fp = xvgropen(gemFile, "Hydrogen Bond Autocorrelation", "Time (ps)", "C'(t)", oenv); xvgr_legend(fp, asize(leg), leg, oenv); for (set = 0; set < nSet; set++) { snew(ctd[set], nData); snew(ctdGem[set], nData); for (i = 0; i < nData; i++) { ctd[set][i] = (double)val[set][i]; if (set == 0) { td[i] = (double)t[i]; } } fitGemRecomb(ctd[set], td, &(ctd[set]), nData, GP); } for (i = 0; i < nData; i++) { fprintf(fp, " %g", t[i]); for (set = 0; set < nSet; set++) { fprintf(fp, " %g", ctdGem[set][i]); } fprintf(fp, "\n"); } for (set = 0; set < nSet; set++) { sfree(ctd[set]); sfree(ctdGem[set]); } sfree(ctd); sfree(ctdGem); sfree(td); xvgrclose(fp); }
static void calc_spectrum(int n, real c[], real dt, const char *fn, gmx_output_env_t *oenv, gmx_bool bRecip) { FILE *fp; gmx_fft_t fft; int i, status; real *data; real nu, omega, recip_fac; snew(data, n*2); for (i = 0; (i < n); i++) { data[i] = c[i]; } if ((status = gmx_fft_init_1d_real(&fft, n, GMX_FFT_FLAG_NONE)) != 0) { gmx_fatal(FARGS, "Invalid fft return status %d", status); } if ((status = gmx_fft_1d_real(fft, GMX_FFT_REAL_TO_COMPLEX, data, data)) != 0) { gmx_fatal(FARGS, "Invalid fft return status %d", status); } fp = xvgropen(fn, "Vibrational Power Spectrum", bRecip ? "\\f{12}w\\f{4} (cm\\S-1\\N)" : "\\f{12}n\\f{4} (ps\\S-1\\N)", "a.u.", oenv); /* This is difficult. * The length of the ACF is dt (as passed to this routine). * We pass the vacf with N time steps from 0 to dt. * That means that after FFT we have lowest frequency = 1/dt * then 1/(2 dt) etc. (this is the X-axis of the data after FFT). * To convert to 1/cm we need to have to realize that * E = hbar w = h nu = h c/lambda. We want to have reciprokal cm * on the x-axis, that is 1/lambda, so we then have * 1/lambda = nu/c. Since nu has units of 1/ps and c has gromacs units * of nm/ps, we need to multiply by 1e7. * The timestep between saving the trajectory is * 1e7 is to convert nanometer to cm */ recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0; for (i = 0; (i < n); i += 2) { nu = i/(2*dt); omega = nu*recip_fac; /* Computing the square magnitude of a complex number, since this is a power * spectrum. */ fprintf(fp, "%10g %10g\n", omega, gmx::square(data[i])+gmx::square(data[i+1])); } xvgrclose(fp); gmx_fft_destroy(fft); sfree(data); }
static void print_histo(const char *fn, int nhisto, int histo[], real binwidth, const gmx_output_env_t *oenv) { FILE *fp; int i; fp = xvgropen(fn, "Velocity distribution", "V (nm/ps)", "arbitrary units", oenv); for (i = 0; (i < nhisto); i++) { fprintf(fp, "%10.3e %10d\n", i*binwidth, histo[i]); } xvgrclose(fp); }
extern void save_data (structure_factor_t *sft, const char *file, int ngrps, real start_q, real end_q, const output_env_t oenv) { FILE *fp; int i, g = 0; double *tmp, polarization_factor, A; structure_factor *sf = (structure_factor *)sft; fp = xvgropen (file, "Scattering Intensity", "q (1/nm)", "Intensity (a.u.)", oenv); snew (tmp, ngrps); for (g = 0; g < ngrps; g++) { for (i = 0; i < sf->n_angles; i++) { /* * theta is half the angle between incoming and scattered vectors. * * polar. fact. = 0.5*(1+cos^2(2*theta)) = 1 - 0.5 * sin^2(2*theta) * * sin(theta) = q/(2k) := A -> sin^2(theta) = 4*A^2 (1-A^2) -> * -> 0.5*(1+cos^2(2*theta)) = 1 - 2 A^2 (1-A^2) */ A = static_cast<double>(i * sf->ref_k) / (2.0 * sf->momentum); polarization_factor = 1 - 2.0 * sqr (A) * (1 - sqr (A)); sf->F[g][i] *= polarization_factor; } } for (i = 0; i < sf->n_angles; i++) { if (i * sf->ref_k >= start_q && i * sf->ref_k <= end_q) { fprintf (fp, "%10.5f ", i * sf->ref_k); for (g = 0; g < ngrps; g++) { fprintf (fp, " %10.5f ", (sf->F[g][i]) /( sf->total_n_atoms* sf->nSteps)); } fprintf (fp, "\n"); } } xvgrclose (fp); }
void AbstractPlotModule::Impl::closeFile() { if (fp_ != NULL) { if (bPlain_) { gmx_fio_fclose(fp_); } else { xvgrclose(fp_); } fp_ = NULL; } }
void write_xvg(char *fn,char *title,int nx,int ny,real **y,char **leg) { FILE *fp; int i,j; fp=xvgropen(fn,title,"X","Y"); if (leg) xvgr_legend(fp,ny-1,leg); for(i=0; (i<nx); i++) { for(j=0; (j<ny); j++) { fprintf(fp," %12.5e",y[j][i]); } fprintf(fp,"\n"); } xvgrclose(fp); }
static void dump_w(output_env_t oenv, real beta) { FILE *fp; double nu; const char *leg[] = { "wCv", "wS", "wA", "wE" }; fp = xvgropen("w.xvg", "Fig. 1, Berens1983a", "\\f{12}b\\f{4}h\\f{12}n", "w", oenv); xvgr_legend(fp, asize(leg), leg, oenv); for (nu = 1; (nu < 100); nu += 0.05) { fprintf(fp, "%10g %10g %10g %10g %10g\n", beta*PLANCK*nu, wCsolid(nu, beta), wSsolid(nu, beta), wAsolid(nu, beta), wEsolid(nu, beta)); } xvgrclose(fp); }
void print_one(const output_env_t oenv, const char *base, const char *name, const char *title, const char *ylabel, int nf, real time[], real data[]) { FILE *fp; char buf[256], t2[256]; int k; sprintf(buf, "%s%s.xvg", base, name); fprintf(stderr, "\rPrinting %s ", buf); sprintf(t2, "%s %s", title, name); fp = xvgropen(buf, t2, "Time (ps)", ylabel, oenv); for (k = 0; (k < nf); k++) { fprintf(fp, "%10g %10g\n", time[k], data[k]); } xvgrclose(fp); }
static void analyse_em_all(int npdb, t_pdbfile *pdbf[], const char *edocked, const char *efree, const gmx_output_env_t *oenv) { FILE *fp; int i; for (bFreeSort = FALSE; (bFreeSort <= TRUE); bFreeSort++) { qsort(pdbf, npdb, sizeof(pdbf[0]), pdbf_comp); fp = xvgropen(bFreeSort ? efree : edocked, etitles[bFreeSort], "()", "E (kJ/mol)", oenv); for (i = 0; (i < npdb); i++) { fprintf(fp, "%12lf\n", bFreeSort ? pdbf[i]->efree : pdbf[i]->edocked); } xvgrclose(fp); } }
static void corr_print(t_corr *curr, gmx_bool bTen, const char *fn, const char *title, const char *yaxis, real msdtime, real beginfit, real endfit, real *DD, real *SigmaD, char *grpname[], const output_env_t oenv) { FILE *out; int i, j; out = xvgropen(fn, title, output_env_get_xvgr_tlabel(oenv), yaxis, oenv); if (DD) { fprintf(out, "# MSD gathered over %g %s with %d restarts\n", msdtime, output_env_get_time_unit(oenv), curr->nrestart); fprintf(out, "# Diffusion constants fitted from time %g to %g %s\n", beginfit, endfit, output_env_get_time_unit(oenv)); for (i = 0; i < curr->ngrp; i++) { fprintf(out, "# D[%10s] = %.4f (+/- %.4f) (1e-5 cm^2/s)\n", grpname[i], DD[i], SigmaD[i]); } } for (i = 0; i < curr->nframes; i++) { fprintf(out, "%10g", output_env_conv_time(oenv, curr->time[i])); for (j = 0; j < curr->ngrp; j++) { fprintf(out, " %10g", curr->data[j][i]); if (bTen) { fprintf(out, " %10g %10g %10g %10g %10g %10g", curr->datam[j][i][XX][XX], curr->datam[j][i][YY][YY], curr->datam[j][i][ZZ][ZZ], curr->datam[j][i][YY][XX], curr->datam[j][i][ZZ][XX], curr->datam[j][i][ZZ][YY]); } } fprintf(out, "\n"); } xvgrclose(out); }
static void dump_fy(output_env_t oenv, real toler) { FILE *fp; double Delta, f, y, DD; const char *leg[] = { "f", "fy", "y" }; DD = pow(10.0, 0.125); fp = xvgropen("fy.xvg", "Fig. 2, Lin2003a", "Delta", "y or fy", oenv); xvgr_legend(fp, asize(leg), leg, oenv); fprintf(fp, "@ world 1e-05, 0, 1000, 1\n"); fprintf(fp, "@ xaxes scale Logarithmic\n"); for (Delta = 1e-5; (Delta <= 1000); Delta *= DD) { f = calc_fluidicity(Delta, toler); y = calc_y(f, Delta, toler); fprintf(fp, "%10g %10g %10g %10g\n", Delta, f, f*y, y); } xvgrclose(fp); }
static void correlate_aniso(const char *fn, t_atoms *ref, t_atoms *calc, const gmx_output_env_t *oenv) { FILE *fp; int i, j; fp = xvgropen(fn, "Correlation between X-Ray and Computed Uij", "X-Ray", "Computed", oenv); for (i = 0; (i < ref->nr); i++) { if (ref->pdbinfo[i].bAnisotropic) { for (j = U11; (j <= U23); j++) { fprintf(fp, "%10d %10d\n", ref->pdbinfo[i].uij[j], calc->pdbinfo[i].uij[j]); } } } xvgrclose(fp); }
static void plot_coscont(const char *ccfile, int n, int nset, real **val, const gmx_output_env_t *oenv) { FILE *fp; int s; real cc; fp = xvgropen(ccfile, "Cosine content", "set / half periods", "cosine content", oenv); for (s = 0; s < nset; s++) { cc = cosine_content(s+1, n, val[s]); fprintf(fp, " %d %g\n", s+1, cc); fprintf(stdout, "Cosine content of set %d with %.1f periods: %g\n", s+1, 0.5*(s+1), cc); } fprintf(stdout, "\n"); xvgrclose(fp); }
void write_xvg(const char *fn, const char *title, int nx, int ny, real **y, const char **leg, const gmx_output_env_t *oenv) { FILE *fp; int i, j; fp = xvgropen(fn, title, "X", "Y", oenv); if (leg) { xvgr_legend(fp, ny-1, leg, oenv); } for (i = 0; (i < nx); i++) { for (j = 0; (j < ny); j++) { fprintf(fp, " %12.5e", y[j][i]); } fprintf(fp, "\n"); } xvgrclose(fp); }
void h2order_plot(rvec dipole[], real order[], const char *afile, int nslices, real slWidth, const gmx_output_env_t *oenv) { FILE *ord; /* xvgr files with order parameters */ int slice; /* loop index */ char buf[256]; /* for xvgr title */ real factor; /* conversion to Debye from electron*nm */ /* factor = 1e-9*1.60217733e-19/3.336e-30 */ factor = 1.60217733/3.336e-2; fprintf(stderr, "%d slices\n", nslices); sprintf(buf, "Water orientation with respect to normal"); ord = xvgropen(afile, buf, "box (nm)", "mu_x, mu_y, mu_z (D), cosine with normal", oenv); for (slice = 0; slice < nslices; slice++) { fprintf(ord, "%8.3f %8.3f %8.3f %8.3f %e\n", slWidth*slice, factor*dipole[slice][XX], factor*dipole[slice][YY], factor*dipole[slice][ZZ], order[slice]); } xvgrclose(ord); }
int gmx_rmsf(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes the root mean square fluctuation (RMSF, i.e. standard ", "deviation) of atomic positions in the trajectory (supplied with [TT]-f[tt])", "after (optionally) fitting to a reference frame (supplied with [TT]-s[tt]).[PAR]", "With option [TT]-oq[tt] the RMSF values are converted to B-factor", "values, which are written to a [REF].pdb[ref] file with the coordinates, of the", "structure file, or of a [REF].pdb[ref] file when [TT]-q[tt] is specified.", "Option [TT]-ox[tt] writes the B-factors to a file with the average", "coordinates.[PAR]", "With the option [TT]-od[tt] the root mean square deviation with", "respect to the reference structure is calculated.[PAR]", "With the option [TT]-aniso[tt], [THISMODULE] will compute anisotropic", "temperature factors and then it will also output average coordinates", "and a [REF].pdb[ref] file with ANISOU records (corresonding to the [TT]-oq[tt]", "or [TT]-ox[tt] option). Please note that the U values", "are orientation-dependent, so before comparison with experimental data", "you should verify that you fit to the experimental coordinates.[PAR]", "When a [REF].pdb[ref] input file is passed to the program and the [TT]-aniso[tt]", "flag is set", "a correlation plot of the Uij will be created, if any anisotropic", "temperature factors are present in the [REF].pdb[ref] file.[PAR]", "With option [TT]-dir[tt] the average MSF (3x3) matrix is diagonalized.", "This shows the directions in which the atoms fluctuate the most and", "the least." }; static gmx_bool bRes = FALSE, bAniso = FALSE, bFit = TRUE; t_pargs pargs[] = { { "-res", FALSE, etBOOL, {&bRes}, "Calculate averages for each residue" }, { "-aniso", FALSE, etBOOL, {&bAniso}, "Compute anisotropic termperature factors" }, { "-fit", FALSE, etBOOL, {&bFit}, "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." } }; int natom; int i, m, teller = 0; real t, *w_rls; t_topology top; int ePBC; t_atoms *pdbatoms, *refatoms; matrix box, pdbbox; rvec *x, *pdbx, *xref; t_trxstatus *status; const char *label; FILE *fp; /* the graphics file */ const char *devfn, *dirfn; int resind; gmx_bool bReadPDB; int *index; int isize; char *grpnames; real bfac, pdb_bfac, *Uaver; double **U, *xav; int aid; rvec *rmsd_x = nullptr; double *rmsf, invcount, totmass; int d; real count = 0; rvec xcm; gmx_rmpbc_t gpbc = nullptr; gmx_output_env_t *oenv; const char *leg[2] = { "MD", "X-Ray" }; t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffOPTRD }, { efPDB, "-q", nullptr, ffOPTRD }, { efPDB, "-oq", "bfac", ffOPTWR }, { efPDB, "-ox", "xaver", ffOPTWR }, { efXVG, "-o", "rmsf", ffWRITE }, { efXVG, "-od", "rmsdev", ffOPTWR }, { efXVG, "-oc", "correl", ffOPTWR }, { efLOG, "-dir", "rmsf", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs), pargs, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } bReadPDB = ftp2bSet(efPDB, NFILE, fnm); devfn = opt2fn_null("-od", NFILE, fnm); dirfn = opt2fn_null("-dir", NFILE, fnm); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xref, nullptr, box, TRUE); const char *title = *top.name; snew(w_rls, top.atoms.nr); fprintf(stderr, "Select group(s) for root mean square calculation\n"); get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpnames); /* Set the weight */ for (i = 0; i < isize; i++) { w_rls[index[i]] = top.atoms.atom[index[i]].m; } /* Malloc the rmsf arrays */ snew(xav, isize*DIM); snew(U, isize); for (i = 0; i < isize; i++) { snew(U[i], DIM*DIM); } snew(rmsf, isize); if (devfn) { snew(rmsd_x, isize); } if (bReadPDB) { t_topology *top_pdb; snew(top_pdb, 1); /* Read coordinates twice */ read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, nullptr, nullptr, nullptr, pdbbox, FALSE); snew(pdbatoms, 1); *pdbatoms = top_pdb->atoms; read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, nullptr, &pdbx, nullptr, pdbbox, FALSE); /* TODO Should this assert that top_pdb->atoms.nr == top.atoms.nr? * See discussion at https://gerrit.gromacs.org/#/c/6430/1 */ title = *top_pdb->name; snew(refatoms, 1); *refatoms = top_pdb->atoms; sfree(top_pdb); } else { pdbatoms = &top.atoms; refatoms = &top.atoms; pdbx = xref; snew(pdbatoms->pdbinfo, pdbatoms->nr); pdbatoms->havePdbInfo = TRUE; copy_mat(box, pdbbox); } if (bFit) { sub_xcm(xref, isize, index, top.atoms.atom, xcm, FALSE); } natom = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); if (bFit) { gpbc = gmx_rmpbc_init(&top.idef, ePBC, natom); } /* Now read the trj again to compute fluctuations */ teller = 0; do { if (bFit) { /* Remove periodic boundary */ gmx_rmpbc(gpbc, natom, box, x); /* Set center of mass to zero */ sub_xcm(x, isize, index, top.atoms.atom, xcm, FALSE); /* Fit to reference structure */ do_fit(natom, w_rls, xref, x); } /* Calculate Anisotropic U Tensor */ for (i = 0; i < isize; i++) { aid = index[i]; for (d = 0; d < DIM; d++) { xav[i*DIM + d] += x[aid][d]; for (m = 0; m < DIM; m++) { U[i][d*DIM + m] += x[aid][d]*x[aid][m]; } } } if (devfn) { /* Calculate RMS Deviation */ for (i = 0; (i < isize); i++) { aid = index[i]; for (d = 0; (d < DIM); d++) { rmsd_x[i][d] += gmx::square(x[aid][d]-xref[aid][d]); } } } count += 1.0; teller++; } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); if (bFit) { gmx_rmpbc_done(gpbc); } invcount = 1.0/count; snew(Uaver, DIM*DIM); totmass = 0; for (i = 0; i < isize; i++) { for (d = 0; d < DIM; d++) { xav[i*DIM + d] *= invcount; } for (d = 0; d < DIM; d++) { for (m = 0; m < DIM; m++) { U[i][d*DIM + m] = U[i][d*DIM + m]*invcount - xav[i*DIM + d]*xav[i*DIM + m]; Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m]; } } totmass += top.atoms.atom[index[i]].m; } for (d = 0; d < DIM*DIM; d++) { Uaver[d] /= totmass; } if (bRes) { for (d = 0; d < DIM*DIM; d++) { average_residues(nullptr, U, d, isize, index, w_rls, &top.atoms); } } if (bAniso) { for (i = 0; i < isize; i++) { aid = index[i]; pdbatoms->pdbinfo[aid].bAnisotropic = TRUE; pdbatoms->pdbinfo[aid].uij[U11] = static_cast<int>(1e6*U[i][XX*DIM + XX]); pdbatoms->pdbinfo[aid].uij[U22] = static_cast<int>(1e6*U[i][YY*DIM + YY]); pdbatoms->pdbinfo[aid].uij[U33] = static_cast<int>(1e6*U[i][ZZ*DIM + ZZ]); pdbatoms->pdbinfo[aid].uij[U12] = static_cast<int>(1e6*U[i][XX*DIM + YY]); pdbatoms->pdbinfo[aid].uij[U13] = static_cast<int>(1e6*U[i][XX*DIM + ZZ]); pdbatoms->pdbinfo[aid].uij[U23] = static_cast<int>(1e6*U[i][YY*DIM + ZZ]); } } if (bRes) { label = "Residue"; } else { label = "Atom"; } for (i = 0; i < isize; i++) { rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ]; } if (dirfn) { fprintf(stdout, "\n"); print_dir(stdout, Uaver); fp = gmx_ffopen(dirfn, "w"); print_dir(fp, Uaver); gmx_ffclose(fp); } for (i = 0; i < isize; i++) { sfree(U[i]); } sfree(U); /* Write RMSF output */ if (bReadPDB) { bfac = 8.0*M_PI*M_PI/3.0*100; fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "B-Factors", label, "(A\\b\\S\\So\\N\\S2\\N)", oenv); xvgr_legend(fp, 2, leg, oenv); for (i = 0; (i < isize); i++) { if (!bRes || i+1 == isize || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) { resind = top.atoms.atom[index[i]].resind; pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind], *(top.atoms.atomname[index[i]])); fprintf(fp, "%5d %10.5f %10.5f\n", bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, rmsf[i]*bfac, pdb_bfac); } } xvgrclose(fp); } else { fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS fluctuation", label, "(nm)", oenv); for (i = 0; i < isize; i++) { if (!bRes || i+1 == isize || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) { fprintf(fp, "%5d %8.4f\n", bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i])); } } xvgrclose(fp); } for (i = 0; i < isize; i++) { pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i]; } if (devfn) { for (i = 0; i < isize; i++) { rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count; } if (bRes) { average_residues(rmsf, nullptr, 0, isize, index, w_rls, &top.atoms); } /* Write RMSD output */ fp = xvgropen(devfn, "RMS Deviation", label, "(nm)", oenv); for (i = 0; i < isize; i++) { if (!bRes || i+1 == isize || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) { fprintf(fp, "%5d %8.4f\n", bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i])); } } xvgrclose(fp); } if (opt2bSet("-oq", NFILE, fnm)) { /* Write a .pdb file with B-factors and optionally anisou records */ for (i = 0; i < isize; i++) { rvec_inc(pdbx[index[i]], xcm); } write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, ePBC, pdbbox, isize, index); } if (opt2bSet("-ox", NFILE, fnm)) { rvec *bFactorX; snew(bFactorX, top.atoms.nr); for (i = 0; i < isize; i++) { for (d = 0; d < DIM; d++) { bFactorX[index[i]][d] = xcm[d] + xav[i*DIM + d]; } } /* Write a .pdb file with B-factors and optionally anisou records */ write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr, ePBC, pdbbox, isize, index); sfree(bFactorX); } if (bAniso) { correlate_aniso(opt2fn("-oc", NFILE, fnm), refatoms, pdbatoms, oenv); do_view(oenv, opt2fn("-oc", NFILE, fnm), "-nxy"); } do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); if (devfn) { do_view(oenv, opt2fn("-od", NFILE, fnm), "-nxy"); } return 0; }
static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, real rho, real wt, const char *fn_trans, const char *fn_tca, const char *fn_tc, const char *fn_tcf, const char *fn_cub, const char *fn_vk, const gmx_output_env_t *oenv) { FILE *fp, *fp_vk, *fp_cub = NULL; int nk, ntc; real **tcaf, **tcafc = NULL, eta, *sig; int i, j, k, kc; int ncorr; double fitparms[3]; nk = kset_c[nkc]; ntc = nk*NPK; if (fn_trans) { fp = xvgropen(fn_trans, "Transverse Current", "Time (ps)", "TC (nm/ps)", oenv); for (i = 0; i < nframes; i++) { fprintf(fp, "%g", i*dt); for (j = 0; j < ntc; j++) { fprintf(fp, " %g", tc[j][i]); } fprintf(fp, "\n"); } xvgrclose(fp); do_view(oenv, fn_trans, "-nxy"); } ncorr = (nframes+1)/2; if (ncorr > static_cast<int>(5*wt/dt+0.5)) { ncorr = static_cast<int>(5*wt/dt+0.5)+1; } snew(tcaf, nk); for (k = 0; k < nk; k++) { snew(tcaf[k], ncorr); } if (fn_cub) { snew(tcafc, nkc); for (k = 0; k < nkc; k++) { snew(tcafc[k], ncorr); } } snew(sig, ncorr); for (i = 0; i < ncorr; i++) { sig[i] = std::exp(0.5*i*dt/wt); } low_do_autocorr(fn_tca, oenv, "Transverse Current Autocorrelation Functions", nframes, ntc, ncorr, tc, dt, eacNormal, 1, FALSE, FALSE, FALSE, 0, 0, 0); do_view(oenv, fn_tca, "-nxy"); fp = xvgropen(fn_tc, "Transverse Current Autocorrelation Functions", "Time (ps)", "TCAF", oenv); for (i = 0; i < ncorr; i++) { kc = 0; fprintf(fp, "%g", i*dt); for (k = 0; k < nk; k++) { for (j = 0; j < NPK; j++) { tcaf[k][i] += tc[NPK*k+j][i]; } if (fn_cub) { for (j = 0; j < NPK; j++) { tcafc[kc][i] += tc[NPK*k+j][i]; } } if (i == 0) { fprintf(fp, " %g", 1.0); } else { tcaf[k][i] /= tcaf[k][0]; fprintf(fp, " %g", tcaf[k][i]); } if (k+1 == kset_c[kc+1]) { kc++; } } fprintf(fp, "\n"); } xvgrclose(fp); do_view(oenv, fn_tc, "-nxy"); if (fn_cub) { fp_cub = xvgropen(fn_cub, "TCAFs and fits", "Time (ps)", "TCAF", oenv); for (kc = 0; kc < nkc; kc++) { fprintf(fp_cub, "%g %g\n", 0.0, 1.0); for (i = 1; i < ncorr; i++) { tcafc[kc][i] /= tcafc[kc][0]; fprintf(fp_cub, "%g %g\n", i*dt, tcafc[kc][i]); } fprintf(fp_cub, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); tcafc[kc][0] = 1.0; } } fp_vk = xvgropen(fn_vk, "Fits", "k (nm\\S-1\\N)", "\\8h\\4 (10\\S-3\\N kg m\\S-1\\N s\\S-1\\N)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp_vk, "@ s0 symbol 2\n"); fprintf(fp_vk, "@ s0 symbol color 1\n"); fprintf(fp_vk, "@ s0 linestyle 0\n"); if (fn_cub) { fprintf(fp_vk, "@ s1 symbol 3\n"); fprintf(fp_vk, "@ s1 symbol color 2\n"); } } fp = xvgropen(fn_tcf, "TCAF Fits", "Time (ps)", "", oenv); for (k = 0; k < nk; k++) { tcaf[k][0] = 1.0; fitparms[0] = 1; fitparms[1] = 1; do_lmfit(ncorr, tcaf[k], sig, dt, 0, 0, ncorr*dt, oenv, bDebugMode(), effnVAC, fitparms, 0, NULL); eta = 1000*fitparms[1]*rho/ (4*fitparms[0]*PICO*norm2(kfac[k])/(NANO*NANO)); fprintf(stdout, "k %6.3f tau %6.3f eta %8.5f 10^-3 kg/(m s)\n", norm(kfac[k]), fitparms[0], eta); fprintf(fp_vk, "%6.3f %g\n", norm(kfac[k]), eta); for (i = 0; i < ncorr; i++) { fprintf(fp, "%g %g\n", i*dt, fit_function(effnVAC, fitparms, i*dt)); } fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } xvgrclose(fp); do_view(oenv, fn_tcf, "-nxy"); if (fn_cub) { fprintf(stdout, "Averaged over k-vectors:\n"); fprintf(fp_vk, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); for (k = 0; k < nkc; k++) { tcafc[k][0] = 1.0; fitparms[0] = 1; fitparms[1] = 1; do_lmfit(ncorr, tcafc[k], sig, dt, 0, 0, ncorr*dt, oenv, bDebugMode(), effnVAC, fitparms, 0, NULL); eta = 1000*fitparms[1]*rho/ (4*fitparms[0]*PICO*norm2(kfac[kset_c[k]])/(NANO*NANO)); fprintf(stdout, "k %6.3f tau %6.3f Omega %6.3f eta %8.5f 10^-3 kg/(m s)\n", norm(kfac[kset_c[k]]), fitparms[0], fitparms[1], eta); fprintf(fp_vk, "%6.3f %g\n", norm(kfac[kset_c[k]]), eta); for (i = 0; i < ncorr; i++) { fprintf(fp_cub, "%g %g\n", i*dt, fit_function(effnVAC, fitparms, i*dt)); } fprintf(fp_cub, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } fprintf(fp_vk, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); xvgrclose(fp_cub); do_view(oenv, fn_cub, "-nxy"); } xvgrclose(fp_vk); do_view(oenv, fn_vk, "-nxy"); }
int gmx_polystat(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] plots static properties of polymers as a function of time", "and prints the average.[PAR]", "By default it determines the average end-to-end distance and radii", "of gyration of polymers. It asks for an index group and split this", "into molecules. The end-to-end distance is then determined using", "the first and the last atom in the index group for each molecules.", "For the radius of gyration the total and the three principal components", "for the average gyration tensor are written.", "With option [TT]-v[tt] the eigenvectors are written.", "With option [TT]-pc[tt] also the average eigenvalues of the individual", "gyration tensors are written.", "With option [TT]-i[tt] the mean square internal distances are", "written.[PAR]", "With option [TT]-p[tt] the persistence length is determined.", "The chosen index group should consist of atoms that are", "consecutively bonded in the polymer mainchains.", "The persistence length is then determined from the cosine of", "the angles between bonds with an index difference that is even,", "the odd pairs are not used, because straight polymer backbones", "are usually all trans and therefore only every second bond aligns.", "The persistence length is defined as number of bonds where", "the average cos reaches a value of 1/e. This point is determined", "by a linear interpolation of [LOG]<cos>[log]." }; static gmx_bool bMW = TRUE, bPC = FALSE; t_pargs pa[] = { { "-mw", FALSE, etBOOL, {&bMW}, "Use the mass weighting for radii of gyration" }, { "-pc", FALSE, etBOOL, {&bPC}, "Plot average eigenvalues" } }; t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-o", "polystat", ffWRITE }, { efXVG, "-v", "polyvec", ffOPTWR }, { efXVG, "-p", "persist", ffOPTWR }, { efXVG, "-i", "intdist", ffOPTWR } }; #define NFILE asize(fnm) t_topology *top; gmx_output_env_t *oenv; int ePBC; int isize, *index, nmol, *molind, mol, nat_min = 0, nat_max = 0; char *grpname; t_trxstatus *status; real t; rvec *x, *bond = nullptr; matrix box; int natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = {0}; dvec cm, sum_eig = {0, 0, 0}; double **gyr, **gyr_all, eig[DIM], **eigv; double sum_eed2, sum_eed2_tot, sum_gyro, sum_gyro_tot, sum_pers_tot; int *ninp = nullptr; double *sum_inp = nullptr, pers; double *intd, ymax, ymin; double mmol, m; char title[STRLEN]; FILE *out, *outv, *outp, *outi; const char *leg[8] = { "end to end", "<R\\sg\\N>", "<R\\sg\\N> eig1", "<R\\sg\\N> eig2", "<R\\sg\\N> eig3", "<R\\sg\\N eig1>", "<R\\sg\\N eig2>", "<R\\sg\\N eig3>" }; char **legp, buf[STRLEN]; gmx_rmpbc_t gpbc = nullptr; if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } snew(top, 1); ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms, nullptr, nullptr, top); fprintf(stderr, "Select a group of polymer mainchain atoms:\n"); get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); snew(molind, top->mols.nr+1); nmol = 0; mol = -1; for (i = 0; i < isize; i++) { if (i == 0 || index[i] >= top->mols.index[mol+1]) { molind[nmol++] = i; do { mol++; } while (index[i] >= top->mols.index[mol+1]); } } molind[nmol] = i; nat_min = top->atoms.nr; nat_max = 0; for (mol = 0; mol < nmol; mol++) { nat_min = std::min(nat_min, molind[mol+1]-molind[mol]); nat_max = std::max(nat_max, molind[mol+1]-molind[mol]); } fprintf(stderr, "Group %s consists of %d molecules\n", grpname, nmol); fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n", nat_min, nat_max); sprintf(title, "Size of %d polymers", nmol); out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); xvgr_legend(out, bPC ? 8 : 5, leg, oenv); if (opt2bSet("-v", NFILE, fnm)) { outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components", output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); snew(legp, DIM*DIM); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { sprintf(buf, "eig%d %c", d+1, 'x'+d2); legp[d*DIM+d2] = gmx_strdup(buf); } } xvgr_legend(outv, DIM*DIM, (const char**)legp, oenv); } else { outv = nullptr; } if (opt2bSet("-p", NFILE, fnm)) { outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length", output_env_get_xvgr_tlabel(oenv), "bonds", oenv); snew(bond, nat_max-1); snew(sum_inp, nat_min/2); snew(ninp, nat_min/2); } else { outp = nullptr; } if (opt2bSet("-i", NFILE, fnm)) { outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances", "n", "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv); i = index[molind[1]-1] - index[molind[0]]; /* Length of polymer -1 */ snew(intd, i); } else { intd = nullptr; outi = nullptr; } natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); snew(gyr, DIM); snew(gyr_all, DIM); snew(eigv, DIM); for (d = 0; d < DIM; d++) { snew(gyr[d], DIM); snew(gyr_all[d], DIM); snew(eigv[d], DIM); } frame = 0; sum_eed2_tot = 0; sum_gyro_tot = 0; sum_pers_tot = 0; gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); do { gmx_rmpbc(gpbc, natoms, box, x); sum_eed2 = 0; for (d = 0; d < DIM; d++) { clear_dvec(gyr_all[d]); } if (bPC) { clear_dvec(sum_eig); } if (outp) { for (i = 0; i < nat_min/2; i++) { sum_inp[i] = 0; ninp[i] = 0; } } for (mol = 0; mol < nmol; mol++) { ind0 = molind[mol]; ind1 = molind[mol+1]; /* Determine end to end distance */ sum_eed2 += distance2(x[index[ind0]], x[index[ind1-1]]); /* Determine internal distances */ if (outi) { calc_int_dist(intd, x, index[ind0], index[ind1-1]); } /* Determine the radius of gyration */ clear_dvec(cm); for (d = 0; d < DIM; d++) { clear_dvec(gyr[d]); } mmol = 0; for (i = ind0; i < ind1; i++) { a = index[i]; if (bMW) { m = top->atoms.atom[a].m; } else { m = 1; } mmol += m; for (d = 0; d < DIM; d++) { cm[d] += m*x[a][d]; for (d2 = 0; d2 < DIM; d2++) { gyr[d][d2] += m*x[a][d]*x[a][d2]; } } } dsvmul(1/mmol, cm, cm); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { gyr[d][d2] = gyr[d][d2]/mmol - cm[d]*cm[d2]; gyr_all[d][d2] += gyr[d][d2]; } } if (bPC) { gyro_eigen(gyr, eig, eigv, ord); for (d = 0; d < DIM; d++) { sum_eig[d] += eig[ord[d]]; } } if (outp) { for (i = ind0; i < ind1-1; i++) { rvec_sub(x[index[i+1]], x[index[i]], bond[i-ind0]); unitv(bond[i-ind0], bond[i-ind0]); } for (i = ind0; i < ind1-1; i++) { for (j = 0; (i+j < ind1-1 && j < nat_min/2); j += 2) { sum_inp[j] += iprod(bond[i-ind0], bond[i-ind0+j]); ninp[j]++; } } } } sum_eed2 /= nmol; sum_gyro = 0; for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { gyr_all[d][d2] /= nmol; } sum_gyro += gyr_all[d][d]; } gyro_eigen(gyr_all, eig, eigv, ord); fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f", t*output_env_get_time_factor(oenv), std::sqrt(sum_eed2), sqrt(sum_gyro), std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), std::sqrt(eig[ord[2]])); if (bPC) { for (d = 0; d < DIM; d++) { fprintf(out, " %8.4f", std::sqrt(sum_eig[d]/nmol)); } } fprintf(out, "\n"); if (outv) { fprintf(outv, "%10.3f", t*output_env_get_time_factor(oenv)); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { fprintf(outv, " %6.3f", eigv[ord[d]][d2]); } } fprintf(outv, "\n"); } sum_eed2_tot += sum_eed2; sum_gyro_tot += sum_gyro; if (outp) { i = -1; for (j = 0; j < nat_min/2; j += 2) { sum_inp[j] /= ninp[j]; if (i == -1 && sum_inp[j] <= std::exp(-1.0)) { i = j; } } if (i == -1) { pers = j; } else { /* Do linear interpolation on a log scale */ pers = i - 2.0 + 2.0*(std::log(sum_inp[i-2]) + 1.0)/(std::log(sum_inp[i-2]) - std::log(sum_inp[i])); } fprintf(outp, "%10.3f %8.4f\n", t*output_env_get_time_factor(oenv), pers); sum_pers_tot += pers; } frame++; } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); close_trx(status); xvgrclose(out); if (outv) { xvgrclose(outv); } if (outp) { xvgrclose(outp); } sum_eed2_tot /= frame; sum_gyro_tot /= frame; sum_pers_tot /= frame; fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n", std::sqrt(sum_eed2_tot)); fprintf(stdout, "\nAverage radius of gyration: %.3f (nm)\n", std::sqrt(sum_gyro_tot)); if (opt2bSet("-p", NFILE, fnm)) { fprintf(stdout, "\nAverage persistence length: %.2f bonds\n", sum_pers_tot); } /* Handle printing of internal distances. */ if (outi) { if (output_env_get_print_xvgr_codes(oenv)) { fprintf(outi, "@ xaxes scale Logarithmic\n"); } ymax = -1; ymin = 1e300; j = index[molind[1]-1] - index[molind[0]]; /* Polymer length -1. */ for (i = 0; i < j; i++) { intd[i] /= (i + 1) * frame * nmol; if (intd[i] > ymax) { ymax = intd[i]; } if (intd[i] < ymin) { ymin = intd[i]; } } xvgr_world(outi, 1, ymin, j, ymax, oenv); for (i = 0; i < j; i++) { fprintf(outi, "%d %8.4f\n", i+1, intd[i]); } xvgrclose(outi); } do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); if (opt2bSet("-v", NFILE, fnm)) { do_view(oenv, opt2fn("-v", NFILE, fnm), "-nxy"); } if (opt2bSet("-p", NFILE, fnm)) { do_view(oenv, opt2fn("-p", NFILE, fnm), "-nxy"); } return 0; }
int gmx_dyecoupl(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] extracts dye dynamics from trajectory files.", "Currently, R and kappa^2 between dyes is extracted for (F)RET", "simulations with assumed dipolar coupling as in the Foerster equation.", "It further allows the calculation of R(t) and kappa^2(t), R and", "kappa^2 histograms and averages, as well as the instantaneous FRET", "efficiency E(t) for a specified Foerster radius R_0 (switch [TT]-R0[tt]).", "The input dyes have to be whole (see res and mol pbc options", "in [TT]trjconv[tt]).", "The dye transition dipole moment has to be defined by at least", "a single atom pair, however multiple atom pairs can be provided ", "in the index file. The distance R is calculated on the basis of", "the COMs of the given atom pairs.", "The [TT]-pbcdist[tt] option calculates distances to the nearest periodic", "image instead to the distance in the box. This works however only," "for periodic boundaries in all 3 dimensions.", "The [TT]-norm[tt] option (area-) normalizes the histograms." }; static gmx_bool bPBCdist = FALSE, bNormHist = FALSE; int histbins = 50; gmx_output_env_t *oenv; real R0 = -1; t_pargs pa[] = { { "-pbcdist", FALSE, etBOOL, { &bPBCdist }, "Distance R based on PBC" }, { "-norm", FALSE, etBOOL, { &bNormHist }, "Normalize histograms" }, { "-bins", FALSE, etINT, {&histbins}, "# of histogram bins" }, { "-R0", FALSE, etREAL, {&R0}, "Foerster radius including kappa^2=2/3 in nm" } }; #define NPA asize(pa) t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efXVG, "-ot", "rkappa", ffOPTWR }, { efXVG, "-oe", "insteff", ffOPTWR }, { efDAT, "-o", "rkappa", ffOPTWR }, { efXVG, "-rhist", "rhist", ffOPTWR }, { efXVG, "-khist", "khist", ffOPTWR } }; #define NFILE asize(fnm) const char *in_trajfile, *out_xvgrkfile = NULL, *out_xvginstefffile = NULL, *out_xvgrhistfile = NULL, *out_xvgkhistfile = NULL, *out_datfile = NULL; gmx_bool bHaveFirstFrame, bHaveNextFrame, indexOK = TRUE; int ndon, nacc; atom_id *donindex, *accindex; char *grpnm; t_trxstatus *status; t_trxframe fr; int flags; int allocblock = 1000; real histexpand = 1e-6; rvec donvec, accvec, donpos, accpos, dist, distnorm; int natoms; /*we rely on PBC autodetection (...currently)*/ int ePBC = -1; real *rvalues = NULL, *kappa2values = NULL, *rhist = NULL, *khist = NULL; t_pbc *pbc = NULL; int i, bin; FILE *rkfp = NULL, *rhfp = NULL, *khfp = NULL, *datfp = NULL, *iefp = NULL; gmx_bool bRKout, bRhistout, bKhistout, bDatout, bInstEffout, grident; const char *rkleg[2] = { "R", "\\f{Symbol}k\\f{}\\S2\\N" }; const char *rhleg[1] = { "p(R)" }; const char *khleg[1] = { "p(\\f{Symbol}k\\f{}\\S2\\N)" }; const char *ieleg[1] = { "E\\sRET\\N(t)" }; real R, kappa2, insteff, Rs = 0., kappa2s = 0., insteffs = 0., rmax, rmin, kmin = 0., kmax = 4., rrange, krange, rincr, kincr, Rfrac; int rkcount = 0, rblocksallocated = 0, kblocksallocated = 0; if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT, NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } /* Check command line options for filenames and set bool flags when switch used*/ in_trajfile = opt2fn("-f", NFILE, fnm); out_xvgrkfile = opt2fn("-ot", NFILE, fnm); out_xvgrhistfile = opt2fn("-rhist", NFILE, fnm); out_xvgkhistfile = opt2fn("-khist", NFILE, fnm); out_xvginstefffile = opt2fn("-oe", NFILE, fnm); out_datfile = opt2fn("-o", NFILE, fnm); bRKout = opt2bSet("-ot", NFILE, fnm); bRhistout = opt2bSet("-rhist", NFILE, fnm); bKhistout = opt2bSet("-khist", NFILE, fnm); bDatout = opt2bSet("-o", NFILE, fnm); bInstEffout = opt2bSet("-oe", NFILE, fnm); /* PBC warning. */ if (bPBCdist) { printf("Calculating distances to periodic image.\n"); printf("Be careful! This produces only valid results for PBC in all three dimensions\n"); } if (bInstEffout && R0 <= 0.) { gmx_fatal(FARGS, "You have to specify R0 and R0 has to be larger than 0 nm.\n\n"); } printf("Select group with donor atom pairs defining the transition moment\n"); get_index(NULL, ftp2fn_null(efNDX, NFILE, fnm), 1, &ndon, &donindex, &grpnm); printf("Select group with acceptor atom pairs defining the transition moment\n"); get_index(NULL, ftp2fn_null(efNDX, NFILE, fnm), 1, &nacc, &accindex, &grpnm); /*check if groups are identical*/ grident = TRUE; if (ndon == nacc) { for (i = 0; i < nacc; i++) { if (accindex[i] != donindex[i]) { grident = FALSE; break; } } } if (grident) { gmx_fatal(FARGS, "Donor and acceptor group are identical. This makes no sense."); } printf("Reading first frame\n"); /* open trx file for reading */ flags = 0; flags = flags | TRX_READ_X; bHaveFirstFrame = read_first_frame(oenv, &status, in_trajfile, &fr, flags); if (bHaveFirstFrame) { printf("First frame is OK\n"); natoms = fr.natoms; if ((ndon % 2 != 0) || (nacc % 2 != 0)) { indexOK = FALSE; } else { for (i = 0; i < ndon; i++) { if (donindex[i] >= natoms) { indexOK = FALSE; } } for (i = 0; i < nacc; i++) { if (accindex[i] >= natoms) { indexOK = FALSE; } } } if (indexOK) { if (bDatout) { datfp = gmx_ffopen(out_datfile, "w"); } if (bRKout) { rkfp = xvgropen(out_xvgrkfile, "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory", "Time (ps)", "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N", oenv); xvgr_legend(rkfp, 2, rkleg, oenv); } if (bInstEffout) { iefp = xvgropen(out_xvginstefffile, "Instantaneous RET Efficiency", "Time (ps)", "RET Efficiency", oenv); xvgr_legend(iefp, 1, ieleg, oenv); } if (bRhistout) { snew(rvalues, allocblock); rblocksallocated += 1; snew(rhist, histbins); } if (bKhistout) { snew(kappa2values, allocblock); kblocksallocated += 1; snew(khist, histbins); } do { clear_rvec(donvec); clear_rvec(accvec); clear_rvec(donpos); clear_rvec(accpos); for (i = 0; i < ndon / 2; i++) { rvec_sub(donvec, fr.x[donindex[2 * i]], donvec); rvec_add(donvec, fr.x[donindex[2 * i + 1]], donvec); rvec_add(donpos, fr.x[donindex[2 * i]], donpos); rvec_add(donpos, fr.x[donindex[2 * i + 1]], donpos); } for (i = 0; i < nacc / 2; i++) { rvec_sub(accvec, fr.x[accindex[2 * i]], accvec); rvec_add(accvec, fr.x[accindex[2 * i + 1]], accvec); rvec_add(accpos, fr.x[accindex[2 * i]], accpos); rvec_add(accpos, fr.x[accindex[2 * i + 1]], accpos); } unitv(donvec, donvec); unitv(accvec, accvec); svmul(1.0 / ndon, donpos, donpos); svmul(1.0 / nacc, accpos, accpos); if (bPBCdist) { set_pbc(pbc, ePBC, fr.box); pbc_dx(pbc, donpos, accpos, dist); } else { rvec_sub(donpos, accpos, dist); } unitv(dist, distnorm); R = norm(dist); kappa2 = iprod(donvec, accvec)- 3.* (iprod(donvec, distnorm) * iprod(distnorm, accvec)); kappa2 *= kappa2; if (R0 > 0) { Rfrac = R/R0; insteff = 1/(1+(Rfrac*Rfrac*Rfrac*Rfrac*Rfrac*Rfrac)*2/3/kappa2); insteffs += insteff; if (bInstEffout) { fprintf(iefp, "%12.7f %12.7f\n", fr.time, insteff); } } Rs += R; kappa2s += kappa2; rkcount++; if (bRKout) { fprintf(rkfp, "%12.7f %12.7f %12.7f\n", fr.time, R, kappa2); } if (bDatout) { fprintf(datfp, "%12.7f %12.7f %12.7f\n", fr.time, R, kappa2); } if (bRhistout) { rvalues[rkcount-1] = R; if (rkcount % allocblock == 0) { srenew(rvalues, allocblock*(rblocksallocated+1)); rblocksallocated += 1; } } if (bKhistout) { kappa2values[rkcount-1] = kappa2; if (rkcount % allocblock == 0) { srenew(kappa2values, allocblock*(kblocksallocated+1)); kblocksallocated += 1; } } bHaveNextFrame = read_next_frame(oenv, status, &fr); } while (bHaveNextFrame); if (bRKout) { xvgrclose(rkfp); } if (bDatout) { gmx_ffclose(datfp); } if (bInstEffout) { xvgrclose(iefp); } if (bRhistout) { printf("Writing R-Histogram\n"); rmin = rvalues[0]; rmax = rvalues[0]; for (i = 1; i < rkcount; i++) { if (rvalues[i] < rmin) { rmin = rvalues[i]; } else if (rvalues[i] > rmax) { rmax = rvalues[i]; } } rmin -= histexpand; rmax += histexpand; rrange = rmax - rmin; rincr = rrange / histbins; for (i = 1; i < rkcount; i++) { bin = static_cast<int>((rvalues[i] - rmin) / rincr); rhist[bin] += 1; } if (bNormHist) { for (i = 0; i < histbins; i++) { rhist[i] /= rkcount * rrange/histbins; } rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)", "Normalized Probability", oenv); } else { rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)", "Probability", oenv); } xvgr_legend(rhfp, 1, rhleg, oenv); for (i = 0; i < histbins; i++) { fprintf(rhfp, "%12.7f %12.7f\n", (i + 0.5) * rincr + rmin, rhist[i]); } xvgrclose(rhfp); } if (bKhistout) { printf("Writing kappa^2-Histogram\n"); krange = kmax - kmin; kincr = krange / histbins; for (i = 1; i < rkcount; i++) { bin = static_cast<int>((kappa2values[i] - kmin) / kincr); khist[bin] += 1; } if (bNormHist) { for (i = 0; i < histbins; i++) { khist[i] /= rkcount * krange/histbins; } khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution", "\\f{Symbol}k\\f{}\\S2\\N", "Normalized Probability", oenv); } else { khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution", "\\f{Symbol}k\\f{}\\S2\\N", "Probability", oenv); } xvgr_legend(khfp, 1, khleg, oenv); for (i = 0; i < histbins; i++) { fprintf(khfp, "%12.7f %12.7f\n", (i + 0.5) * kincr + kmin, khist[i]); } xvgrclose(khfp); } printf("\nAverages:\n"); printf("R_avg = %8.4f nm\nKappa^2 = %8.4f\n", Rs / rkcount, kappa2s / rkcount); if (R0 > 0) { printf("E_RETavg = %8.4f\n", insteffs / rkcount); } please_cite(stdout, "Hoefling2011"); } else { gmx_fatal(FARGS, "Index file invalid, check your index file for correct pairs.\n"); } } else { gmx_fatal(FARGS, "Could not read first frame of the trajectory.\n"); } return 0; }
int gmx_dos(int argc, char *argv[]) { const char *desc[] = { "[TT]g_dos[tt] computes the Density of States from a simulations.", "In order for this to be meaningful the velocities must be saved", "in the trajecotry with sufficiently high frequency such as to cover", "all vibrations. For flexible systems that would be around a few fs", "between saving. Properties based on the DoS are printed on the", "standard output." }; const char *bugs[] = { "This program needs a lot of memory: total usage equals the number of atoms times 3 times number of frames times 4 (or 8 when run in double precision)." }; FILE *fp, *fplog; t_topology top; int ePBC = -1; t_trxframe fr; matrix box; int gnx; char title[256]; real t0, t1, m; t_trxstatus *status; int nV, nframes, n_alloc, i, j, k, l, fftcode, Nmol, Natom; double rho, dt, V2sum, Vsum, V, tmass, dostot, dos2, dosabs; real **c1, **dos, mi, beta, bfac, *nu, *tt, stddev, c1j; output_env_t oenv; gmx_fft_t fft; double cP, S, A, E, DiffCoeff, Delta, f, y, z, sigHS, Shs, Sig, DoS0, recip_fac; double wCdiff, wSdiff, wAdiff, wEdiff; static gmx_bool bVerbose = TRUE, bAbsolute = FALSE, bNormalize = FALSE; static gmx_bool bRecip = FALSE, bDump = FALSE; static real Temp = 298.15, toler = 1e-6; t_pargs pa[] = { { "-v", FALSE, etBOOL, {&bVerbose}, "Be loud and noisy." }, { "-recip", FALSE, etBOOL, {&bRecip}, "Use cm^-1 on X-axis instead of 1/ps for DoS plots." }, { "-abs", FALSE, etBOOL, {&bAbsolute}, "Use the absolute value of the Fourier transform of the VACF as the Density of States. Default is to use the real component only" }, { "-normdos", FALSE, etBOOL, {&bNormalize}, "Normalize the DoS such that it adds up to 3N. This is a hack that should not be necessary." }, { "-T", FALSE, etREAL, {&Temp}, "Temperature in the simulation" }, { "-toler", FALSE, etREAL, {&toler}, "[HIDDEN]Tolerance when computing the fluidicity using bisection algorithm" }, { "-dump", FALSE, etBOOL, {&bDump}, "[HIDDEN]Dump the y/fy plot corresponding to Fig. 2 inLin2003a and the and the weighting functions corresponding to Fig. 1 in Berens1983a." } }; t_filenm fnm[] = { { efTRN, "-f", NULL, ffREAD }, { efTPX, "-s", NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, "-vacf", "vacf", ffWRITE }, { efXVG, "-mvacf", "mvacf", ffWRITE }, { efXVG, "-dos", "dos", ffWRITE }, { efLOG, "-g", "dos", ffWRITE }, }; #define NFILE asize(fnm) int npargs; t_pargs *ppa; const char *DoSlegend[] = { "DoS(v)", "DoS(v)[Solid]", "DoS(v)[Diff]" }; 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); beta = 1/(Temp*BOLTZ); if (bDump) { printf("Dumping reference figures. Thanks for your patience.\n"); dump_fy(oenv, toler); dump_w(oenv, beta); exit(0); } fplog = gmx_fio_fopen(ftp2fn(efLOG, NFILE, fnm), "w"); fprintf(fplog, "Doing density of states analysis based on trajectory.\n"); please_cite(fplog, "Pascal2011a"); please_cite(fplog, "Caleman2011b"); read_tps_conf(ftp2fn(efTPX, NFILE, fnm), title, &top, &ePBC, NULL, NULL, box, TRUE); V = det(box); tmass = 0; for (i = 0; (i < top.atoms.nr); i++) { tmass += top.atoms.atom[i].m; } Natom = top.atoms.nr; Nmol = top.mols.nr; gnx = Natom*DIM; /* Correlation stuff */ snew(c1, gnx); for (i = 0; (i < gnx); i++) { c1[i] = NULL; } read_first_frame(oenv, &status, ftp2fn(efTRN, NFILE, fnm), &fr, TRX_NEED_V); t0 = fr.time; n_alloc = 0; nframes = 0; Vsum = V2sum = 0; nV = 0; do { if (fr.bBox) { V = det(fr.box); V2sum += V*V; Vsum += V; nV++; } if (nframes >= n_alloc) { n_alloc += 100; for (i = 0; i < gnx; i++) { srenew(c1[i], n_alloc); } } for (i = 0; i < gnx; i += DIM) { c1[i+XX][nframes] = fr.v[i/DIM][XX]; c1[i+YY][nframes] = fr.v[i/DIM][YY]; c1[i+ZZ][nframes] = fr.v[i/DIM][ZZ]; } t1 = fr.time; nframes++; } while (read_next_frame(oenv, status, &fr)); close_trj(status); dt = (t1-t0)/(nframes-1); if (nV > 0) { V = Vsum/nV; } if (bVerbose) { printf("Going to do %d fourier transforms of length %d. Hang on.\n", gnx, nframes); } low_do_autocorr(NULL, oenv, NULL, nframes, gnx, nframes, c1, dt, eacNormal, 0, FALSE, FALSE, FALSE, -1, -1, 0, 0); snew(dos, DOS_NR); for (j = 0; (j < DOS_NR); j++) { snew(dos[j], nframes+4); } if (bVerbose) { printf("Going to merge the ACFs into the mass-weighted and plain ACF\n"); } for (i = 0; (i < gnx); i += DIM) { mi = top.atoms.atom[i/DIM].m; for (j = 0; (j < nframes/2); j++) { c1j = (c1[i+XX][j] + c1[i+YY][j] + c1[i+ZZ][j]); dos[VACF][j] += c1j/Natom; dos[MVACF][j] += mi*c1j; } } fp = xvgropen(opt2fn("-vacf", NFILE, fnm), "Velocity ACF", "Time (ps)", "C(t)", oenv); snew(tt, nframes/2); for (j = 0; (j < nframes/2); j++) { tt[j] = j*dt; fprintf(fp, "%10g %10g\n", tt[j], dos[VACF][j]); } xvgrclose(fp); fp = xvgropen(opt2fn("-mvacf", NFILE, fnm), "Mass-weighted velocity ACF", "Time (ps)", "C(t)", oenv); for (j = 0; (j < nframes/2); j++) { fprintf(fp, "%10g %10g\n", tt[j], dos[MVACF][j]); } xvgrclose(fp); if ((fftcode = gmx_fft_init_1d_real(&fft, nframes/2, GMX_FFT_FLAG_NONE)) != 0) { gmx_fatal(FARGS, "gmx_fft_init_1d_real returned %d", fftcode); } if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_REAL_TO_COMPLEX, (void *)dos[MVACF], (void *)dos[DOS])) != 0) { gmx_fatal(FARGS, "gmx_fft_1d_real returned %d", fftcode); } /* First compute the DoS */ /* Magic factor of 8 included now. */ bfac = 8*dt*beta/2; dos2 = 0; snew(nu, nframes/4); for (j = 0; (j < nframes/4); j++) { nu[j] = 2*j/(t1-t0); dos2 += sqr(dos[DOS][2*j]) + sqr(dos[DOS][2*j+1]); if (bAbsolute) { dos[DOS][j] = bfac*sqrt(sqr(dos[DOS][2*j]) + sqr(dos[DOS][2*j+1])); } else { dos[DOS][j] = bfac*dos[DOS][2*j]; } } /* Normalize it */ dostot = evaluate_integral(nframes/4, nu, dos[DOS], NULL, nframes/4, &stddev); if (bNormalize) { for (j = 0; (j < nframes/4); j++) { dos[DOS][j] *= 3*Natom/dostot; } } /* Now analyze it */ DoS0 = dos[DOS][0]; /* Note this eqn. is incorrect in Pascal2011a! */ Delta = ((2*DoS0/(9*Natom))*sqrt(M_PI*BOLTZ*Temp*Natom/tmass)* pow((Natom/V), 1.0/3.0)*pow(6/M_PI, 2.0/3.0)); f = calc_fluidicity(Delta, toler); y = calc_y(f, Delta, toler); z = calc_compress(y); Sig = BOLTZ*(5.0/2.0+log(2*M_PI*BOLTZ*Temp/(sqr(PLANCK))*V/(f*Natom))); Shs = Sig+calc_Shs(f, y); rho = (tmass*AMU)/(V*NANO*NANO*NANO); sigHS = pow(6*y*V/(M_PI*Natom), 1.0/3.0); fprintf(fplog, "System = \"%s\"\n", title); fprintf(fplog, "Nmol = %d\n", Nmol); fprintf(fplog, "Natom = %d\n", Natom); fprintf(fplog, "dt = %g ps\n", dt); fprintf(fplog, "tmass = %g amu\n", tmass); fprintf(fplog, "V = %g nm^3\n", V); fprintf(fplog, "rho = %g g/l\n", rho); fprintf(fplog, "T = %g K\n", Temp); fprintf(fplog, "beta = %g mol/kJ\n", beta); fprintf(fplog, "\nDoS parameters\n"); fprintf(fplog, "Delta = %g\n", Delta); fprintf(fplog, "fluidicity = %g\n", f); fprintf(fplog, "hard sphere packing fraction = %g\n", y); fprintf(fplog, "hard sphere compressibility = %g\n", z); fprintf(fplog, "ideal gas entropy = %g\n", Sig); fprintf(fplog, "hard sphere entropy = %g\n", Shs); fprintf(fplog, "sigma_HS = %g nm\n", sigHS); fprintf(fplog, "DoS0 = %g\n", DoS0); fprintf(fplog, "Dos2 = %g\n", dos2); fprintf(fplog, "DoSTot = %g\n", dostot); /* Now compute solid (2) and diffusive (3) components */ fp = xvgropen(opt2fn("-dos", NFILE, fnm), "Density of states", bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)", "\\f{4}S(\\f{12}n\\f{4})", oenv); xvgr_legend(fp, asize(DoSlegend), DoSlegend, oenv); recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0; for (j = 0; (j < nframes/4); j++) { dos[DOS_DIFF][j] = DoS0/(1+sqr(DoS0*M_PI*nu[j]/(6*f*Natom))); dos[DOS_SOLID][j] = dos[DOS][j]-dos[DOS_DIFF][j]; fprintf(fp, "%10g %10g %10g %10g\n", recip_fac*nu[j], dos[DOS][j]/recip_fac, dos[DOS_SOLID][j]/recip_fac, dos[DOS_DIFF][j]/recip_fac); } xvgrclose(fp); /* Finally analyze the results! */ wCdiff = 0.5; wSdiff = Shs/(3*BOLTZ); /* Is this correct? */ wEdiff = 0.5; wAdiff = wEdiff-wSdiff; for (j = 0; (j < nframes/4); j++) { dos[DOS_CP][j] = (dos[DOS_DIFF][j]*wCdiff + dos[DOS_SOLID][j]*wCsolid(nu[j], beta)); dos[DOS_S][j] = (dos[DOS_DIFF][j]*wSdiff + dos[DOS_SOLID][j]*wSsolid(nu[j], beta)); dos[DOS_A][j] = (dos[DOS_DIFF][j]*wAdiff + dos[DOS_SOLID][j]*wAsolid(nu[j], beta)); dos[DOS_E][j] = (dos[DOS_DIFF][j]*wEdiff + dos[DOS_SOLID][j]*wEsolid(nu[j], beta)); } DiffCoeff = evaluate_integral(nframes/2, tt, dos[VACF], NULL, nframes/2, &stddev); DiffCoeff = 1000*DiffCoeff/3.0; fprintf(fplog, "Diffusion coefficient from VACF %g 10^-5 cm^2/s\n", DiffCoeff); fprintf(fplog, "Diffusion coefficient from DoS %g 10^-5 cm^2/s\n", 1000*DoS0/(12*tmass*beta)); cP = BOLTZ * evaluate_integral(nframes/4, nu, dos[DOS_CP], NULL, nframes/4, &stddev); fprintf(fplog, "Heat capacity %g J/mol K\n", 1000*cP/Nmol); /* S = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_S],NULL, nframes/4,&stddev); fprintf(fplog,"Entropy %g J/mol K\n",1000*S/Nmol); A = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_A],NULL, nframes/4,&stddev); fprintf(fplog,"Helmholtz energy %g kJ/mol\n",A/Nmol); E = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_E],NULL, nframes/4,&stddev); fprintf(fplog,"Internal energy %g kJ/mol\n",E/Nmol); */ fprintf(fplog, "\nArrivederci!\n"); gmx_fio_fclose(fplog); do_view(oenv, ftp2fn(efXVG, NFILE, fnm), "-nxy"); thanx(stderr); return 0; }
real do_lmfit(int ndata, real c1[], real sig[], real dt, real *x0, real begintimefit, real endtimefit, const gmx_output_env_t *oenv, gmx_bool bVerbose, int eFitFn, double fitparms[], int fix, const char *fn_fitted) { FILE *fp; int i, j, nfitpnts; double integral, ttt; double *x, *y, *dy; if (0 != fix) { fprintf(stderr, "Using fixed parameters in curve fitting is temporarily not working.\n"); } if (debug) { fprintf(debug, "There are %d points to fit %d vars!\n", ndata, effnNparams(eFitFn)); fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, endtimefit, dt); } snew(x, ndata); snew(y, ndata); snew(dy, ndata); j = 0; for (i = 0; i < ndata; i++) { ttt = x0 ? x0[i] : dt*i; if (ttt >= begintimefit && ttt <= endtimefit) { x[j] = ttt; y[j] = c1[i]; if (NULL == sig) { // No weighting if all values are divided by 1. dy[j] = 1; } else { dy[j] = std::max(1.0e-7, (double)sig[i]); } if (debug) { fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy=%g, ttt=%g\n", j, i, x[j], y[j], dy[j], ttt); } j++; } } nfitpnts = j; integral = 0; if (nfitpnts < effnNparams(eFitFn)) { fprintf(stderr, "Not enough (%d) data points for fitting, dt = %g!\n", nfitpnts, dt); } else { gmx_bool bSuccess; if (bVerbose) { print_chi2_params(stdout, eFitFn, fitparms, "initial", nfitpnts, x, y); } initiate_fit_params(eFitFn, fitparms); bSuccess = lmfit_exp(nfitpnts, x, y, dy, fitparms, bVerbose, eFitFn, fix); extract_fit_params(eFitFn, fitparms); if (!bSuccess) { fprintf(stderr, "Fit failed!\n"); } else { if (bVerbose) { print_chi2_params(stdout, eFitFn, fitparms, "final", nfitpnts, x, y); } switch (eFitFn) { case effnEXP1: integral = fitparms[0]*myexp(begintimefit, 1, fitparms[0]); break; case effnEXP2: integral = fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]); break; case effnEXPEXP: integral = (fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]) + fitparms[2]*myexp(begintimefit, 1-fitparms[1], fitparms[2])); break; case effnEXP5: case effnEXP7: case effnEXP9: integral = 0; for (i = 0; (i < (effnNparams(eFitFn)-1)/2); i++) { integral += fitparms[2*i]*myexp(begintimefit, fitparms[2*i+1], fitparms[2*i]); } break; default: /* Do numerical integration */ integral = 0; for (i = 0; (i < nfitpnts-1); i++) { double y0 = lmcurves[eFitFn](x[i], fitparms); double y1 = lmcurves[eFitFn](x[i+1], fitparms); integral += (x[i+1]-x[i])*(y1+y0)*0.5; } break; } if (bVerbose) { printf("FIT: Integral of fitted function: %g\n", integral); if ((effnEXP5 == eFitFn) || (effnEXP7 == eFitFn) || (effnEXP9 == eFitFn)) { printf("FIT: Note that the constant term is not taken into account when computing integral.\n"); } } /* Generate debug output */ if (NULL != fn_fitted) { fp = xvgropen(fn_fitted, "Data + Fit", "Time (ps)", "Data (t)", oenv); for (i = 0; (i < effnNparams(eFitFn)); i++) { fprintf(fp, "# fitparms[%d] = %g\n", i, fitparms[i]); } for (j = 0; (j < nfitpnts); j++) { real ttt = x0 ? x0[j] : dt*j; fprintf(fp, "%10.5e %10.5e %10.5e\n", x[j], y[j], (lmcurves[eFitFn])(ttt, fitparms)); } xvgrclose(fp); } } } sfree(x); sfree(y); sfree(dy); return integral; }
real do_lmfit(int ndata, real c1[], real sig[], real dt, real x0[], real begintimefit, real endtimefit, const output_env_t oenv, gmx_bool bVerbose, int eFitFn, real fitparms[], int fix) { FILE *fp; char buf[32]; int i, j, nparm, nfitpnts; real integral, ttt; real *parm, *dparm; real *x, *y, *dy; real ftol = 1e-4; nparm = nfp_ffn[eFitFn]; if (debug) { fprintf(debug, "There are %d points to fit %d vars!\n", ndata, nparm); fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, endtimefit, dt); } snew(x, ndata); snew(y, ndata); snew(dy, ndata); j = 0; for (i = 0; i < ndata; i++) { ttt = x0 ? x0[i] : dt*i; if (ttt >= begintimefit && ttt <= endtimefit) { x[j] = ttt; y[j] = c1[i]; /* mrqmin does not like sig to be zero */ if (sig[i] < 1.0e-7) { dy[j] = 1.0e-7; } else { dy[j] = sig[i]; } if (debug) { fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy= %g\n", j, i, x[j], y[j], dy[j]); } j++; } } nfitpnts = j; integral = 0; if (nfitpnts < nparm) { fprintf(stderr, "Not enough data points for fitting!\n"); } else { snew(parm, nparm); snew(dparm, nparm); if (fitparms) { for (i = 0; (i < nparm); i++) { parm[i] = fitparms[i]; } } if (!lmfit_exp(nfitpnts, x, y, dy, ftol, parm, dparm, bVerbose, eFitFn, fix)) { fprintf(stderr, "Fit failed!\n"); } else if (nparm <= 3) { /* Compute the integral from begintimefit */ if (nparm == 3) { integral = (parm[0]*myexp(begintimefit, parm[1], parm[0]) + parm[2]*myexp(begintimefit, 1-parm[1], parm[2])); } else if (nparm == 2) { integral = parm[0]*myexp(begintimefit, parm[1], parm[0]); } else if (nparm == 1) { integral = parm[0]*myexp(begintimefit, 1, parm[0]); } else { gmx_fatal(FARGS, "nparm = %d in file %s, line %d", nparm, __FILE__, __LINE__); } /* Generate THE output */ if (bVerbose) { fprintf(stderr, "FIT: # points used in fit is: %d\n", nfitpnts); fprintf(stderr, "FIT: %21s%21s%21s\n", "parm0 ", "parm1 (ps) ", "parm2 (ps) "); fprintf(stderr, "FIT: ------------------------------------------------------------\n"); fprintf(stderr, "FIT: %8.3g +/- %8.3g%9.4g +/- %8.3g%8.3g +/- %8.3g\n", parm[0], dparm[0], parm[1], dparm[1], parm[2], dparm[2]); fprintf(stderr, "FIT: Integral (calc with fitted function) from %g ps to inf. is: %g\n", begintimefit, integral); sprintf(buf, "test%d.xvg", nfitpnts); fp = xvgropen(buf, "C(t) + Fit to C(t)", "Time (ps)", "C(t)", oenv); fprintf(fp, "# parm0 = %g, parm1 = %g, parm2 = %g\n", parm[0], parm[1], parm[2]); for (j = 0; (j < nfitpnts); j++) { ttt = x0 ? x0[j] : dt*j; fprintf(fp, "%10.5e %10.5e %10.5e\n", ttt, c1[j], fit_function(eFitFn, parm, ttt)); } xvgrclose(fp); } } if (fitparms) { for (i = 0; (i < nparm); i++) { fitparms[i] = parm[i]; } } sfree(parm); sfree(dparm); } sfree(x); sfree(y); sfree(dy); return integral; }
int gmx_sans(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes SANS spectra using Debye formula.", "It currently uses topology file (since it need to assigne element for each atom).", "[PAR]", "Parameters:[PAR]" "[TT]-pr[tt] Computes normalized g(r) function averaged over trajectory[PAR]", "[TT]-prframe[tt] Computes normalized g(r) function for each frame[PAR]", "[TT]-sq[tt] Computes SANS intensity curve averaged over trajectory[PAR]", "[TT]-sqframe[tt] Computes SANS intensity curve for each frame[PAR]", "[TT]-startq[tt] Starting q value in nm[PAR]", "[TT]-endq[tt] Ending q value in nm[PAR]", "[TT]-qstep[tt] Stepping in q space[PAR]", "Note: When using Debye direct method computational cost increases as", "1/2 * N * (N - 1) where N is atom number in group of interest.", "[PAR]", "WARNING: If sq or pr specified this tool can produce large number of files! Up to two times larger than number of frames!" }; static gmx_bool bPBC = TRUE; static gmx_bool bNORM = FALSE; static real binwidth = 0.2, grid = 0.05; /* bins shouldnt be smaller then smallest bond (~0.1nm) length */ static real start_q = 0.0, end_q = 2.0, q_step = 0.01; static real mcover = -1; static unsigned int seed = 0; static int nthreads = -1; static const char *emode[] = { NULL, "direct", "mc", NULL }; static const char *emethod[] = { NULL, "debye", "fft", NULL }; gmx_neutron_atomic_structurefactors_t *gnsf; gmx_sans_t *gsans; #define NPA asize(pa) t_pargs pa[] = { { "-bin", FALSE, etREAL, {&binwidth}, "[HIDDEN]Binwidth (nm)" }, { "-mode", FALSE, etENUM, {emode}, "Mode for sans spectra calculation" }, { "-mcover", FALSE, etREAL, {&mcover}, "Monte-Carlo coverage should be -1(default) or (0,1]"}, { "-method", FALSE, etENUM, {emethod}, "[HIDDEN]Method for sans spectra calculation" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions for computing distances" }, { "-grid", FALSE, etREAL, {&grid}, "[HIDDEN]Grid spacing (in nm) for FFTs" }, {"-startq", FALSE, etREAL, {&start_q}, "Starting q (1/nm) "}, {"-endq", FALSE, etREAL, {&end_q}, "Ending q (1/nm)"}, { "-qstep", FALSE, etREAL, {&q_step}, "Stepping in q (1/nm)"}, { "-seed", FALSE, etINT, {&seed}, "Random seed for Monte-Carlo"}, #ifdef GMX_OPENMP { "-nt", FALSE, etINT, {&nthreads}, "Number of threads to start"}, #endif }; FILE *fp; const char *fnTPX, *fnNDX, *fnTRX, *fnDAT = NULL; t_trxstatus *status; t_topology *top = NULL; t_atom *atom = NULL; gmx_rmpbc_t gpbc = NULL; gmx_bool bTPX; gmx_bool bFFT = FALSE, bDEBYE = FALSE; gmx_bool bMC = FALSE; int ePBC = -1; matrix box; char title[STRLEN]; rvec *x; int natoms; real t; char **grpname = NULL; atom_id *index = NULL; int isize; int i, j; char *hdr = NULL; char *suffix = NULL; t_filenm *fnmdup = NULL; gmx_radial_distribution_histogram_t *prframecurrent = NULL, *pr = NULL; gmx_static_structurefactor_t *sqframecurrent = NULL, *sq = NULL; output_env_t oenv; #define NFILE asize(fnm) t_filenm fnm[] = { { efTPX, "-s", NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-d", "nsfactor", ffOPTRD }, { efXVG, "-pr", "pr", ffWRITE }, { efXVG, "-sq", "sq", ffWRITE }, { efXVG, "-prframe", "prframe", ffOPTWR }, { efXVG, "-sqframe", "sqframe", ffOPTWR } }; nthreads = gmx_omp_get_max_threads(); if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } /* check that binwidth not smaller than smallers distance */ check_binwidth(binwidth); check_mcover(mcover); /* setting number of omp threads globaly */ gmx_omp_set_num_threads(nthreads); /* Now try to parse opts for modes */ switch (emethod[0][0]) { case 'd': bDEBYE = TRUE; switch (emode[0][0]) { case 'd': bMC = FALSE; break; case 'm': bMC = TRUE; break; default: break; } break; case 'f': bFFT = TRUE; break; default: break; } if (bDEBYE) { if (bMC) { fprintf(stderr, "Using Monte Carlo Debye method to calculate spectrum\n"); } else { fprintf(stderr, "Using direct Debye method to calculate spectrum\n"); } } else if (bFFT) { gmx_fatal(FARGS, "FFT method not implemented!"); } else { gmx_fatal(FARGS, "Unknown combination for mode and method!"); } /* Try to read files */ fnDAT = ftp2fn(efDAT, NFILE, fnm); fnTPX = ftp2fn(efTPX, NFILE, fnm); fnTRX = ftp2fn(efTRX, NFILE, fnm); gnsf = gmx_neutronstructurefactors_init(fnDAT); fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n", gnsf->nratoms, fnDAT); snew(top, 1); snew(grpname, 1); snew(index, 1); bTPX = read_tps_conf(fnTPX, title, top, &ePBC, &x, NULL, box, TRUE); printf("\nPlease select group for SANS spectra calculation:\n"); get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, grpname); gsans = gmx_sans_init(top, gnsf); /* Prepare reference frame */ if (bPBC) { gpbc = gmx_rmpbc_init(&top->idef, ePBC, top->atoms.nr); gmx_rmpbc(gpbc, top->atoms.nr, box, x); } natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box); if (natoms != top->atoms.nr) { fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", natoms, top->atoms.nr); } do { if (bPBC) { gmx_rmpbc(gpbc, top->atoms.nr, box, x); } /* allocate memory for pr */ if (pr == NULL) { /* in case its first frame to read */ snew(pr, 1); } /* realy calc p(r) */ prframecurrent = calc_radial_distribution_histogram(gsans, x, box, index, isize, binwidth, bMC, bNORM, mcover, seed); /* copy prframecurrent -> pr and summ up pr->gr[i] */ /* allocate and/or resize memory for pr->gr[i] and pr->r[i] */ if (pr->gr == NULL) { /* check if we use pr->gr first time */ snew(pr->gr, prframecurrent->grn); snew(pr->r, prframecurrent->grn); } else { /* resize pr->gr and pr->r if needed to preven overruns */ if (prframecurrent->grn > pr->grn) { srenew(pr->gr, prframecurrent->grn); srenew(pr->r, prframecurrent->grn); } } pr->grn = prframecurrent->grn; pr->binwidth = prframecurrent->binwidth; /* summ up gr and fill r */ for (i = 0; i < prframecurrent->grn; i++) { pr->gr[i] += prframecurrent->gr[i]; pr->r[i] = prframecurrent->r[i]; } /* normalize histo */ normalize_probability(prframecurrent->grn, prframecurrent->gr); /* convert p(r) to sq */ sqframecurrent = convert_histogram_to_intensity_curve(prframecurrent, start_q, end_q, q_step); /* print frame data if needed */ if (opt2fn_null("-prframe", NFILE, fnm)) { snew(hdr, 25); snew(suffix, GMX_PATH_MAX); /* prepare header */ sprintf(hdr, "g(r), t = %f", t); /* prepare output filename */ fnmdup = dup_tfn(NFILE, fnm); sprintf(suffix, "-t%.2f", t); add_suffix_to_output_names(fnmdup, NFILE, suffix); fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup), hdr, "Distance (nm)", "Probability", oenv); for (i = 0; i < prframecurrent->grn; i++) { fprintf(fp, "%10.6f%10.6f\n", prframecurrent->r[i], prframecurrent->gr[i]); } done_filenms(NFILE, fnmdup); fclose(fp); sfree(hdr); sfree(suffix); sfree(fnmdup); } if (opt2fn_null("-sqframe", NFILE, fnm)) { snew(hdr, 25); snew(suffix, GMX_PATH_MAX); /* prepare header */ sprintf(hdr, "I(q), t = %f", t); /* prepare output filename */ fnmdup = dup_tfn(NFILE, fnm); sprintf(suffix, "-t%.2f", t); add_suffix_to_output_names(fnmdup, NFILE, suffix); fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup), hdr, "q (nm^-1)", "s(q)/s(0)", oenv); for (i = 0; i < sqframecurrent->qn; i++) { fprintf(fp, "%10.6f%10.6f\n", sqframecurrent->q[i], sqframecurrent->s[i]); } done_filenms(NFILE, fnmdup); fclose(fp); sfree(hdr); sfree(suffix); sfree(fnmdup); } /* free pr structure */ sfree(prframecurrent->gr); sfree(prframecurrent->r); sfree(prframecurrent); /* free sq structure */ sfree(sqframecurrent->q); sfree(sqframecurrent->s); sfree(sqframecurrent); } while (read_next_x(oenv, status, &t, x, box)); close_trj(status); /* normalize histo */ normalize_probability(pr->grn, pr->gr); sq = convert_histogram_to_intensity_curve(pr, start_q, end_q, q_step); /* prepare pr.xvg */ fp = xvgropen(opt2fn_null("-pr", NFILE, fnm), "G(r)", "Distance (nm)", "Probability", oenv); for (i = 0; i < pr->grn; i++) { fprintf(fp, "%10.6f%10.6f\n", pr->r[i], pr->gr[i]); } xvgrclose(fp); /* prepare sq.xvg */ fp = xvgropen(opt2fn_null("-sq", NFILE, fnm), "I(q)", "q (nm^-1)", "s(q)/s(0)", oenv); for (i = 0; i < sq->qn; i++) { fprintf(fp, "%10.6f%10.6f\n", sq->q[i], sq->s[i]); } xvgrclose(fp); /* * Clean up memory */ sfree(pr->gr); sfree(pr->r); sfree(pr); sfree(sq->q); sfree(sq->s); sfree(sq); please_cite(stdout, "Garmay2012"); return 0; }
int gmx_mdmat(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] makes distance matrices consisting of the smallest distance", "between residue pairs. With [TT]-frames[tt], these distance matrices can be", "stored in order to see differences in tertiary structure as a", "function of time. If you choose your options unwisely, this may generate", "a large output file. By default, only an averaged matrix over the whole", "trajectory is output.", "Also a count of the number of different atomic contacts between", "residues over the whole trajectory can be made.", "The output can be processed with [gmx-xpm2ps] to make a PostScript (tm) plot." }; static real truncate = 1.5; static gmx_bool bAtom = FALSE; static int nlevels = 40; t_pargs pa[] = { { "-t", FALSE, etREAL, {&truncate}, "trunc distance" }, { "-nlevels", FALSE, etINT, {&nlevels}, "Discretize distance in this number of levels" } }; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efXPM, "-mean", "dm", ffWRITE }, { efXPM, "-frames", "dmf", ffOPTWR }, { efXVG, "-no", "num", ffOPTWR }, }; #define NFILE asize(fnm) FILE *out = NULL, *fp; t_topology top; int ePBC; t_atoms useatoms; int isize; atom_id *index; char *grpname; int *rndx, *natm, prevres, newres; int i, j, nres, natoms, nframes, it, trxnat; t_trxstatus *status; int nr0; gmx_bool bCalcN, bFrames; real t, ratio; char title[256], label[234]; t_rgb rlo, rhi; rvec *x; real **mdmat, *resnr, **totmdmat; int **nmat, **totnmat; real *mean_n; int *tot_n; matrix box = {{0}}; output_env_t oenv; gmx_rmpbc_t gpbc = NULL; if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } fprintf(stderr, "Will truncate at %f nm\n", truncate); bCalcN = opt2bSet("-no", NFILE, fnm); bFrames = opt2bSet("-frames", NFILE, fnm); if (bCalcN) { fprintf(stderr, "Will calculate number of different contacts\n"); } read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &x, NULL, box, FALSE); fprintf(stderr, "Select group for analysis\n"); get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); natoms = isize; snew(useatoms.atom, natoms); snew(useatoms.atomname, natoms); useatoms.nres = 0; snew(useatoms.resinfo, natoms); prevres = top.atoms.atom[index[0]].resind; newres = 0; for (i = 0; (i < isize); i++) { int ii = index[i]; useatoms.atomname[i] = top.atoms.atomname[ii]; if (top.atoms.atom[ii].resind != prevres) { prevres = top.atoms.atom[ii].resind; newres++; useatoms.resinfo[i] = top.atoms.resinfo[prevres]; if (debug) { fprintf(debug, "New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n", *(top.atoms.resinfo[top.atoms.atom[ii].resind].name), *(top.atoms.atomname[ii]), ii, i, newres); } } useatoms.atom[i].resind = newres; } useatoms.nres = newres+1; useatoms.nr = isize; rndx = res_ndx(&(useatoms)); natm = res_natm(&(useatoms)); nres = useatoms.nres; fprintf(stderr, "There are %d residues with %d atoms\n", nres, natoms); snew(resnr, nres); snew(mdmat, nres); snew(nmat, nres); snew(totnmat, nres); snew(mean_n, nres); snew(tot_n, nres); for (i = 0; (i < nres); i++) { snew(mdmat[i], nres); snew(nmat[i], natoms); snew(totnmat[i], natoms); resnr[i] = i+1; } snew(totmdmat, nres); for (i = 0; (i < nres); i++) { snew(totmdmat[i], nres); } trxnat = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); nframes = 0; rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0; rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0; gpbc = gmx_rmpbc_init(&top.idef, ePBC, trxnat); if (bFrames) { out = opt2FILE("-frames", NFILE, fnm, "w"); } do { gmx_rmpbc(gpbc, trxnat, box, x); nframes++; calc_mat(nres, natoms, rndx, x, index, truncate, mdmat, nmat, ePBC, box); for (i = 0; (i < nres); i++) { for (j = 0; (j < natoms); j++) { if (nmat[i][j]) { totnmat[i][j]++; } } } for (i = 0; (i < nres); i++) { for (j = 0; (j < nres); j++) { totmdmat[i][j] += mdmat[i][j]; } } if (bFrames) { sprintf(label, "t=%.0f ps", t); write_xpm(out, 0, label, "Distance (nm)", "Residue Index", "Residue Index", nres, nres, resnr, resnr, mdmat, 0, truncate, rlo, rhi, &nlevels); } } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); close_trj(status); gmx_rmpbc_done(gpbc); if (bFrames) { gmx_ffclose(out); } fprintf(stderr, "Processed %d frames\n", nframes); for (i = 0; (i < nres); i++) { for (j = 0; (j < nres); j++) { totmdmat[i][j] /= nframes; } } write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean smallest distance", "Distance (nm)", "Residue Index", "Residue Index", nres, nres, resnr, resnr, totmdmat, 0, truncate, rlo, rhi, &nlevels); if (bCalcN) { char **legend; snew(legend, 5); for (i = 0; i < 5; i++) { snew(legend[i], STRLEN); } tot_nmat(nres, natoms, nframes, totnmat, tot_n, mean_n); fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Increase in number of contacts", "Residue", "Ratio", oenv); sprintf(legend[0], "Total/mean"); sprintf(legend[1], "Total"); sprintf(legend[2], "Mean"); sprintf(legend[3], "# atoms"); sprintf(legend[4], "Mean/# atoms"); xvgr_legend(fp, 5, (const char**)legend, oenv); for (i = 0; (i < nres); i++) { if (mean_n[i] == 0) { ratio = 1; } else { ratio = tot_n[i]/mean_n[i]; } fprintf(fp, "%3d %8.3f %3d %8.3f %3d %8.3f\n", i+1, ratio, tot_n[i], mean_n[i], natm[i], mean_n[i]/natm[i]); } xvgrclose(fp); } return 0; }