int gmx_vanhove(int argc, char *argv[])
{
    const char *desc[] = {
        "[THISMODULE] computes the Van Hove correlation function.",
        "The Van Hove G(r,t) is the probability that a particle that is at r[SUB]0[sub]",
        "at time zero can be found at position r[SUB]0[sub]+r at time t.",
        "[THISMODULE] determines G not for a vector r, but for the length of r.",
        "Thus it gives the probability that a particle moves a distance of r",
        "in time t.",
        "Jumps across the periodic boundaries are removed.",
        "Corrections are made for scaling due to isotropic",
        "or anisotropic pressure coupling.",
        "[PAR]",
        "With option [TT]-om[tt] the whole matrix can be written as a function",
        "of t and r or as a function of [SQRT]t[sqrt] and r (option [TT]-sqrt[tt]).",
        "[PAR]",
        "With option [TT]-or[tt] the Van Hove function is plotted for one",
        "or more values of t. Option [TT]-nr[tt] sets the number of times,",
        "option [TT]-fr[tt] the number spacing between the times.",
        "The binwidth is set with option [TT]-rbin[tt]. The number of bins",
        "is determined automatically.",
        "[PAR]",
        "With option [TT]-ot[tt] the integral up to a certain distance",
        "(option [TT]-rt[tt]) is plotted as a function of time.",
        "[PAR]",
        "For all frames that are read the coordinates of the selected particles",
        "are stored in memory. Therefore the program may use a lot of memory.",
        "For options [TT]-om[tt] and [TT]-ot[tt] the program may be slow.",
        "This is because the calculation scales as the number of frames times",
        "[TT]-fm[tt] or [TT]-ft[tt].",
        "Note that with the [TT]-dt[tt] option the memory usage and calculation",
        "time can be reduced."
    };
    static int  fmmax = 0, ftmax = 0, nlev = 81, nr = 1, fshift = 0;
    static real sbin  = 0, rmax = 2, rbin = 0.01, mmax = 0, rint = 0;
    t_pargs     pa[]  = {
        { "-sqrt",    FALSE, etREAL, {&sbin},
          "Use [SQRT]t[sqrt] on the matrix axis which binspacing # in [SQRT]ps[sqrt]" },
        { "-fm",      FALSE, etINT, {&fmmax},
          "Number of frames in the matrix, 0 is plot all" },
        { "-rmax",    FALSE, etREAL, {&rmax},
          "Maximum r in the matrix (nm)" },
        { "-rbin",    FALSE, etREAL, {&rbin},
          "Binwidth in the matrix and for [TT]-or[tt] (nm)" },
        { "-mmax",    FALSE, etREAL, {&mmax},
          "Maximum density in the matrix, 0 is calculate (1/nm)" },
        { "-nlevels", FALSE, etINT,  {&nlev},
          "Number of levels in the matrix" },
        { "-nr",      FALSE, etINT, {&nr},
          "Number of curves for the [TT]-or[tt] output" },
        { "-fr",      FALSE, etINT, {&fshift},
          "Frame spacing for the [TT]-or[tt] output" },
        { "-rt",      FALSE, etREAL, {&rint},
          "Integration limit for the [TT]-ot[tt] output (nm)" },
        { "-ft",      FALSE, etINT, {&ftmax},
          "Number of frames in the [TT]-ot[tt] output, 0 is plot all" }
    };
#define NPA asize(pa)

    t_filenm fnm[] = {
        { efTRX, NULL, NULL,  ffREAD },
        { efTPS, NULL, NULL,  ffREAD },
        { efNDX, NULL, NULL,  ffOPTRD },
        { efXPM, "-om", "vanhove", ffOPTWR },
        { efXVG, "-or", "vanhove_r", ffOPTWR },
        { efXVG, "-ot", "vanhove_t", ffOPTWR }
    };
#define NFILE asize(fnm)

    output_env_t oenv;
    const char  *matfile, *otfile, *orfile;
    char         title[256];
    t_topology   top;
    int          ePBC;
    matrix       boxtop, box, *sbox, avbox, corr;
    rvec        *xtop, *x, **sx;
    int          isize, nalloc, nallocn, natom;
    t_trxstatus *status;
    atom_id     *index;
    char        *grpname;
    int          nfr, f, ff, i, m, mat_nx = 0, nbin = 0, bin, mbin, fbin;
    real        *time, t, invbin = 0, rmax2 = 0, rint2 = 0, d2;
    real         invsbin = 0, matmax, normfac, dt, *tickx, *ticky;
    char         buf[STRLEN], **legend;
    real       **mat = NULL;
    int         *pt  = NULL, **pr = NULL, *mcount = NULL, *tcount = NULL, *rcount = NULL;
    FILE        *fp;
    t_rgb        rlo = {1, 1, 1}, rhi = {0, 0, 0};

    if (!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))
    {
        return 0;
    }

    matfile = opt2fn_null("-om", NFILE, fnm);
    if (opt2parg_bSet("-fr", NPA, pa))
    {
        orfile  = opt2fn("-or", NFILE, fnm);
    }
    else
    {
        orfile  = opt2fn_null("-or", NFILE, fnm);
    }
    if (opt2parg_bSet("-rt", NPA, pa))
    {
        otfile  = opt2fn("-ot", NFILE, fnm);
    }
    else
    {
        otfile  = opt2fn_null("-ot", NFILE, fnm);
    }

    if (!matfile && !otfile && !orfile)
    {
        fprintf(stderr,
                "For output set one (or more) of the output file options\n");
        exit(0);
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, boxtop,
                  FALSE);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    nalloc = 0;
    time   = NULL;
    sbox   = NULL;
    sx     = NULL;
    clear_mat(avbox);

    natom = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    nfr   = 0;
    do
    {
        if (nfr >= nalloc)
        {
            nalloc += 100;
            srenew(time, nalloc);
            srenew(sbox, nalloc);
            srenew(sx, nalloc);
        }

        time[nfr] = t;
        copy_mat(box, sbox[nfr]);
        /* This assumes that the off-diagonal box elements
         * are not affected by jumps across the periodic boundaries.
         */
        m_add(avbox, box, avbox);
        snew(sx[nfr], isize);
        for (i = 0; i < isize; i++)
        {
            copy_rvec(x[index[i]], sx[nfr][i]);
        }

        nfr++;
    }
    while (read_next_x(oenv, status, &t, x, box));

    /* clean up */
    sfree(x);
    close_trj(status);

    fprintf(stderr, "Read %d frames\n", nfr);

    dt = (time[nfr-1] - time[0])/(nfr - 1);
    /* Some ugly rounding to get nice nice times in the output */
    dt = (int)(10000.0*dt + 0.5)/10000.0;

    invbin = 1.0/rbin;

    if (matfile)
    {
        if (fmmax <= 0 || fmmax >= nfr)
        {
            fmmax = nfr - 1;
        }
        snew(mcount, fmmax);
        nbin = (int)(rmax*invbin + 0.5);
        if (sbin == 0)
        {
            mat_nx = fmmax + 1;
        }
        else
        {
            invsbin = 1.0/sbin;
            mat_nx  = sqrt(fmmax*dt)*invsbin + 1;
        }
        snew(mat, mat_nx);
        for (f = 0; f < mat_nx; f++)
        {
            snew(mat[f], nbin);
        }
        rmax2 = sqr(nbin*rbin);
        /* Initialize time zero */
        mat[0][0]  = nfr*isize;
        mcount[0] += nfr;
    }
    else
    {
        fmmax = 0;
    }

    if (orfile)
    {
        snew(pr, nr);
        nalloc = 0;
        snew(rcount, nr);
    }

    if (otfile)
    {
        if (ftmax <= 0)
        {
            ftmax = nfr - 1;
        }
        snew(tcount, ftmax);
        snew(pt, nfr);
        rint2 = rint*rint;
        /* Initialize time zero */
        pt[0]      = nfr*isize;
        tcount[0] += nfr;
    }
    else
    {
        ftmax = 0;
    }

    msmul(avbox, 1.0/nfr, avbox);
    for (f = 0; f < nfr; f++)
    {
        if (f % 100 == 0)
        {
            fprintf(stderr, "\rProcessing frame %d", f);
        }
        /* Scale all the configuration to the average box */
        m_inv_ur0(sbox[f], corr);
        mmul_ur0(avbox, corr, corr);
        for (i = 0; i < isize; i++)
        {
            mvmul_ur0(corr, sx[f][i], sx[f][i]);
            if (f > 0)
            {
                /* Correct for periodic jumps */
                for (m = DIM-1; m >= 0; m--)
                {
                    while (sx[f][i][m] - sx[f-1][i][m] > 0.5*avbox[m][m])
                    {
                        rvec_dec(sx[f][i], avbox[m]);
                    }
                    while (sx[f][i][m] - sx[f-1][i][m] <= -0.5*avbox[m][m])
                    {
                        rvec_inc(sx[f][i], avbox[m]);
                    }
                }
            }
        }
        for (ff = 0; ff < f; ff++)
        {
            fbin = f - ff;
            if (fbin <= fmmax || fbin <= ftmax)
            {
                if (sbin == 0)
                {
                    mbin = fbin;
                }
                else
                {
                    mbin = (int)(sqrt(fbin*dt)*invsbin + 0.5);
                }
                for (i = 0; i < isize; i++)
                {
                    d2 = distance2(sx[f][i], sx[ff][i]);
                    if (mbin < mat_nx && d2 < rmax2)
                    {
                        bin = (int)(sqrt(d2)*invbin + 0.5);
                        if (bin < nbin)
                        {
                            mat[mbin][bin] += 1;
                        }
                    }
                    if (fbin <= ftmax && d2 <= rint2)
                    {
                        pt[fbin]++;
                    }
                }
                if (matfile)
                {
                    mcount[mbin]++;
                }
                if (otfile)
                {
                    tcount[fbin]++;
                }
            }
        }
        if (orfile)
        {
            for (fbin = 0; fbin < nr; fbin++)
            {
                ff = f - (fbin + 1)*fshift;
                if (ff >= 0)
                {
                    for (i = 0; i < isize; i++)
                    {
                        d2  = distance2(sx[f][i], sx[ff][i]);
                        bin = (int)(sqrt(d2)*invbin + 0.5);
                        if (bin >= nalloc)
                        {
                            nallocn = 10*(bin/10) + 11;
                            for (m = 0; m < nr; m++)
                            {
                                srenew(pr[m], nallocn);
                                for (i = nalloc; i < nallocn; i++)
                                {
                                    pr[m][i] = 0;
                                }
                            }
                            nalloc = nallocn;
                        }
                        pr[fbin][bin]++;
                    }
                    rcount[fbin]++;
                }
            }
        }
    }
    fprintf(stderr, "\n");

    if (matfile)
    {
        matmax = 0;
        for (f = 0; f < mat_nx; f++)
        {
            normfac = 1.0/(mcount[f]*isize*rbin);
            for (i = 0; i < nbin; i++)
            {
                mat[f][i] *= normfac;
                if (mat[f][i] > matmax && (f != 0 || i != 0))
                {
                    matmax = mat[f][i];
                }
            }
        }
        fprintf(stdout, "Value at (0,0): %.3f, maximum of the rest %.3f\n",
                mat[0][0], matmax);
        if (mmax > 0)
        {
            matmax = mmax;
        }
        snew(tickx, mat_nx);
        for (f = 0; f < mat_nx; f++)
        {
            if (sbin == 0)
            {
                tickx[f] = f*dt;
            }
            else
            {
                tickx[f] = f*sbin;
            }
        }
        snew(ticky, nbin+1);
        for (i = 0; i <= nbin; i++)
        {
            ticky[i] = i*rbin;
        }
        fp = gmx_ffopen(matfile, "w");
        write_xpm(fp, MAT_SPATIAL_Y, "Van Hove function", "G (1/nm)",
                  sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)", "r (nm)",
                  mat_nx, nbin, tickx, ticky, mat, 0, matmax, rlo, rhi, &nlev);
        gmx_ffclose(fp);
    }

    if (orfile)
    {
        fp = xvgropen(orfile, "Van Hove function", "r (nm)", "G (nm\\S-1\\N)", oenv);
        if (output_env_get_print_xvgr_codes(oenv))
        {
            fprintf(fp, "@ subtitle \"for particles in group %s\"\n", grpname);
        }
        snew(legend, nr);
        for (fbin = 0; fbin < nr; fbin++)
        {
            sprintf(buf, "%g ps", (fbin + 1)*fshift*dt);
            legend[fbin] = strdup(buf);
        }
        xvgr_legend(fp, nr, (const char**)legend, oenv);
        for (i = 0; i < nalloc; i++)
        {
            fprintf(fp, "%g", i*rbin);
            for (fbin = 0; fbin < nr; fbin++)
            {
                fprintf(fp, " %g",
                        (real)pr[fbin][i]/(rcount[fbin]*isize*rbin*(i == 0 ? 0.5 : 1)));
            }
            fprintf(fp, "\n");
        }
        gmx_ffclose(fp);
    }

    if (otfile)
    {
        sprintf(buf, "Probability of moving less than %g nm", rint);
        fp = xvgropen(otfile, buf, "t (ps)", "", oenv);
        if (output_env_get_print_xvgr_codes(oenv))
        {
            fprintf(fp, "@ subtitle \"for particles in group %s\"\n", grpname);
        }
        for (f = 0; f <= ftmax; f++)
        {
            fprintf(fp, "%g %g\n", f*dt, (real)pt[f]/(tcount[f]*isize));
        }
        gmx_ffclose(fp);
    }

    do_view(oenv, matfile, NULL);
    do_view(oenv, orfile, NULL);
    do_view(oenv, otfile, NULL);

    return 0;
}
示例#2
0
int gmx_lie(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes a free energy estimate based on an energy analysis",
        "from nonbonded energies. One needs an energy file with the following components:",
        "Coul-(A-B) LJ-SR (A-B) etc.[PAR]",
        "To utilize [TT]g_lie[tt] correctly, two simulations are required: one with the",
        "molecule of interest bound to its receptor and one with the molecule in water.",
        "Both need to utilize [TT]energygrps[tt] such that Coul-SR(A-B), LJ-SR(A-B), etc. terms",
        "are written to the [REF].edr[ref] file. Values from the molecule-in-water simulation",
        "are necessary for supplying suitable values for -Elj and -Eqq."
    };
    static real        lie_lj = 0, lie_qq = 0, fac_lj = 0.181, fac_qq = 0.5;
    static const char *ligand = "none";
    t_pargs            pa[]   = {
        { "-Elj",  FALSE, etREAL, {&lie_lj},
          "Lennard-Jones interaction between ligand and solvent" },
        { "-Eqq",  FALSE, etREAL, {&lie_qq},
          "Coulomb interaction between ligand and solvent" },
        { "-Clj",  FALSE, etREAL, {&fac_lj},
          "Factor in the LIE equation for Lennard-Jones component of energy" },
        { "-Cqq",  FALSE, etREAL, {&fac_qq},
          "Factor in the LIE equation for Coulomb component of energy" },
        { "-ligand",  FALSE, etSTR, {&ligand},
          "Name of the ligand in the energy file" }
    };
#define NPA asize(pa)

    FILE             *out;
    int               nre, nframes = 0, ct = 0;
    ener_file_t       fp;
    t_liedata        *ld;
    gmx_enxnm_t      *enm = NULL;
    t_enxframe       *fr;
    real              lie;
    double            lieaver = 0, lieav2 = 0;
    gmx_output_env_t *oenv;

    t_filenm          fnm[] = {
        { efEDR, "-f",    "ener",     ffREAD   },
        { efXVG, "-o",    "lie",      ffWRITE  }
    };
#define NFILE asize(fnm)

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

    fp = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
    do_enxnms(fp, &nre, &enm);

    ld = analyze_names(nre, enm, ligand);
    snew(fr, 1);

    out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "LIE free energy estimate",
                   "Time (ps)", "DGbind (kJ/mol)", oenv);
    while (do_enx(fp, fr))
    {
        ct = check_times(fr->t);
        if (ct == 0)
        {
            lie      = calc_lie(ld, fr->ener, lie_lj, lie_qq, fac_lj, fac_qq);
            lieaver += lie;
            lieav2  += lie*lie;
            nframes++;
            fprintf(out, "%10g  %10g\n", fr->t, lie);
        }
    }
    close_enx(fp);
    xvgrclose(out);
    fprintf(stderr, "\n");

    if (nframes > 0)
    {
        printf("DGbind = %.3f (%.3f)\n", lieaver/nframes,
               std::sqrt(lieav2/nframes-sqr(lieaver/nframes)));
    }

    do_view(oenv, ftp2fn(efXVG, NFILE, fnm), "-nxy");

    return 0;
}
示例#3
0
int gmx_principal(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] calculates the three principal axes of inertia for a group",
        "of atoms. NOTE: Old versions of GROMACS wrote the output data in a",
        "strange transposed way. As of GROMACS 5.0, the output file paxis1.dat",
        "contains the x/y/z components of the first (major) principal axis for",
        "each frame, and similarly for the middle and minor axes in paxis2.dat",
        "and paxis3.dat."
    };
    static gmx_bool foo = FALSE;

    t_pargs         pa[] = {
        { "-foo",      FALSE, etBOOL, {&foo}, "Dummy option to avoid empty array" }
    };
    t_trxstatus    *status;
    t_topology      top;
    int             ePBC;
    real            t;
    rvec      *     x;

    int             natoms;
    char           *grpname;
    int             i, gnx;
    atom_id        *index;
    rvec            moi;
    FILE      *     axis1;
    FILE      *     axis2;
    FILE      *     axis3;
    FILE      *     fmoi;
    matrix          axes, box;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc = NULL;
    char **         legend;

    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efXVG, "-a1",  "paxis1",   ffWRITE },
        { efXVG, "-a2",  "paxis2",   ffWRITE },
        { efXVG, "-a3",  "paxis3",   ffWRITE },
        { efXVG, "-om",  "moi",      ffWRITE }
    };
#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;
    }

    snew(legend, DIM);
    for (i = 0; i < DIM; i++)
    {
        snew(legend[i], STRLEN);
        sprintf(legend[i], "%c component", 'X'+i);
    }

    axis1 = xvgropen(opt2fn("-a1", NFILE, fnm), "Principal axis 1 (major axis)",
                     output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
    xvgr_legend(axis1, DIM, (const char **)legend, oenv);

    axis2 = xvgropen(opt2fn("-a2", NFILE, fnm), "Principal axis 2 (middle axis)",
                     output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
    xvgr_legend(axis2, DIM, (const char **)legend, oenv);

    axis3 = xvgropen(opt2fn("-a3", NFILE, fnm), "Principal axis 3 (minor axis)",
                     output_env_get_xvgr_tlabel(oenv), "Component (nm)", oenv);
    xvgr_legend(axis3, DIM, (const char **)legend, oenv);

    sprintf(legend[XX], "Axis 1 (major)");
    sprintf(legend[YY], "Axis 2 (middle)");
    sprintf(legend[ZZ], "Axis 3 (minor)");

    fmoi  = xvgropen(opt2fn("-om", NFILE, fnm), "Moments of inertia around inertial axes",
                     output_env_get_xvgr_tlabel(oenv), "I (au nm\\S2\\N)", oenv);
    xvgr_legend(fmoi, DIM, (const char **)legend, oenv);

    for (i = 0; i < DIM; i++)
    {
        sfree(legend[i]);
    }
    sfree(legend);

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

    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);

    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);

        calc_principal_axes(&top, x, index, gnx, axes, moi);

        fprintf(axis1, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][XX], axes[XX][YY], axes[XX][ZZ]);
        fprintf(axis2, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[YY][XX], axes[YY][YY], axes[YY][ZZ]);
        fprintf(axis3, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY], axes[ZZ][ZZ]);
        fprintf(fmoi,  "%15.10f     %15.10f  %15.10f  %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]);
    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);

    close_trj(status);

    xvgrclose(axis1);
    xvgrclose(axis2);
    xvgrclose(axis3);
    xvgrclose(fmoi);

    return 0;
}
示例#4
0
int gmx_eneconv(int argc, char *argv[])
{
    const char     *desc[] = {
        "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[BR]",
        "Concatenates several energy files in sorted order.",
        "In the 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 the command [TT]gmx eneconv -f *.edr -o fixed.edr[tt] should do",
        "the trick. [PAR]",
        "With [IT]one file[it] specified for [TT]-f[tt]:[BR]",
        "Reads one energy file and writes another, applying the [TT]-dt[tt],",
        "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
        "converting to a different format if necessary (indicated by file",
        "extentions).[PAR]",
        "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
        "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
    };
    const char     *bugs[] = {
        "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way."
    };
    ener_file_t     in  = NULL, out = NULL;
    gmx_enxnm_t    *enm = NULL;
#if 0
    ener_file_t     in, out = NULL;
    gmx_enxnm_t    *enm = NULL;
#endif
    t_enxframe     *fr, *fro;
    gmx_large_int_t ee_sum_step = 0, ee_sum_nsteps, ee_sum_nsum;
    t_energy       *ee_sum;
    gmx_large_int_t lastfilestep, laststep, startstep, startstep_file = 0;
    int             noutfr;
    int             nre, nremax, this_nre, nfile, f, i, j, kkk, nset, *set = NULL;
    double          last_t;
    char          **fnms;
    real           *readtime, *settime, timestep, t1, tadjust;
    char            inputstring[STRLEN], *chptr, buf[22], buf2[22], buf3[22];
    gmx_bool        ok;
    int            *cont_type;
    gmx_bool        bNewFile, bFirst, bNewOutput;
    output_env_t    oenv;
    gmx_bool        warned_about_dh = FALSE;
    t_enxblock     *blocks          = NULL;
    int             nblocks         = 0;
    int             nblocks_alloc   = 0;

    t_filenm        fnm[] = {
        { efEDR, "-f", NULL,    ffRDMULT },
        { efEDR, "-o", "fixed", ffWRITE  },
    };

#define NFILE asize(fnm)
    gmx_bool         bWrite;
    static real      delta_t   = 0.0, toffset = 0, scalefac = 1;
    static gmx_bool  bSetTime  = FALSE;
    static gmx_bool  bSort     = TRUE, bError = TRUE;
    static real      begin     = -1;
    static real      end       = -1;
    gmx_bool         remove_dh = FALSE;

    t_pargs          pa[] = {
        { "-b",        FALSE, etREAL, {&begin},
          "First time to use"},
        { "-e",        FALSE, etREAL, {&end},
          "Last time to use"},
        { "-dt",       FALSE, etREAL, {&delta_t},
          "Only write out frame when t MOD dt = offset" },
        { "-offset",   FALSE, etREAL, {&toffset},
          "Time offset for [TT]-dt[tt] option" },
        { "-settime",  FALSE, etBOOL, {&bSetTime},
          "Change starting time interactively" },
        { "-sort",     FALSE, etBOOL, {&bSort},
          "Sort energy files (not frames)"},
        { "-rmdh",     FALSE, etBOOL, {&remove_dh},
          "Remove free energy block data" },
        { "-scalefac", FALSE, etREAL, {&scalefac},
          "Multiply energy component by this factor" },
        { "-error",    FALSE, etBOOL, {&bError},
          "Stop on errors in the file" }
    };

    if (!parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, asize(pa),
                           pa, asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }
    tadjust  = 0;
    nremax   = 0;
    nset     = 0;
    timestep = 0.0;
    snew(fnms, argc);
    nfile        = 0;
    lastfilestep = 0;
    laststep     = startstep = 0;

    nfile = opt2fns(&fnms, "-f", NFILE, fnm);

    if (!nfile)
    {
        gmx_fatal(FARGS, "No input files!");
    }

    snew(settime, nfile+1);
    snew(readtime, nfile+1);
    snew(cont_type, nfile+1);

    nre = scan_ene_files(fnms, nfile, readtime, &timestep, &nremax);
    edit_files(fnms, nfile, readtime, settime, cont_type, bSetTime, bSort);

    ee_sum_nsteps = 0;
    ee_sum_nsum   = 0;
    snew(ee_sum, nremax);

    snew(fr, 1);
    snew(fro, 1);
    fro->t   = -1e20;
    fro->nre = nre;
    snew(fro->ener, nremax);

    noutfr = 0;
    bFirst = TRUE;

    last_t = fro->t;
    for (f = 0; f < nfile; f++)
    {
        bNewFile   = TRUE;
        bNewOutput = TRUE;
        in         = open_enx(fnms[f], "r");
        enm        = NULL;
        do_enxnms(in, &this_nre, &enm);
        if (f == 0)
        {
            if (scalefac != 1)
            {
                set = select_it(nre, enm, &nset);
            }

            /* write names to the output file */
            out = open_enx(opt2fn("-o", NFILE, fnm), "w");
            do_enxnms(out, &nre, &enm);
        }

        /* start reading from the next file */
        while ((fro->t <= (settime[f+1] + GMX_REAL_EPS)) &&
               do_enx(in, fr))
        {
            if (bNewFile)
            {
                startstep_file = fr->step;
                tadjust        = settime[f] - fr->t;
                if (cont_type[f+1] == TIME_LAST)
                {
                    settime[f+1]   = readtime[f+1]-readtime[f]+settime[f];
                    cont_type[f+1] = TIME_EXPLICIT;
                }
                bNewFile = FALSE;
            }

            if (tadjust + fr->t <= last_t)
            {
                /* Skip this frame, since we already have it / past it */
                if (debug)
                {
                    fprintf(debug, "fr->step %s, fr->t %.4f\n",
                            gmx_step_str(fr->step, buf), fr->t);
                    fprintf(debug, "tadjust %12.6e + fr->t %12.6e <= t %12.6e\n",
                            tadjust, fr->t, last_t);
                }
                continue;
            }

            fro->step = lastfilestep + fr->step - startstep_file;
            fro->t    = tadjust  + fr->t;

            bWrite = ((begin < 0 || (begin >= 0 && (fro->t >= begin-GMX_REAL_EPS))) &&
                      (end  < 0 || (end  >= 0 && (fro->t <= end  +GMX_REAL_EPS))) &&
                      (fro->t <= settime[f+1]+0.5*timestep));

            if (debug)
            {
                fprintf(debug,
                        "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %d\n",
                        gmx_step_str(fr->step, buf), fr->t,
                        gmx_step_str(fro->step, buf2), fro->t, bWrite);
            }

            if (bError)
            {
                if ((end > 0) && (fro->t > end+GMX_REAL_EPS))
                {
                    f = nfile;
                    break;
                }
            }

            if (fro->t >= begin-GMX_REAL_EPS)
            {
                if (bFirst)
                {
                    bFirst    = FALSE;
                    startstep = fr->step;
                }
                if (bWrite)
                {
                    update_ee_sum(nre, &ee_sum_step, &ee_sum_nsteps, &ee_sum_nsum, ee_sum,
                                  fr, fro->step);
                }
            }

            /* determine if we should write it */
            if (bWrite && (delta_t == 0 || bRmod(fro->t, toffset, delta_t)))
            {
                laststep = fro->step;
                last_t   = fro->t;
                if (bNewOutput)
                {
                    bNewOutput = FALSE;
                    fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n",
                            fro->t, gmx_step_str(fro->step, buf));
                }

                /* Copy the energies */
                for (i = 0; i < nre; i++)
                {
                    fro->ener[i].e = fr->ener[i].e;
                }

                fro->nsteps = ee_sum_nsteps;
                fro->dt     = fr->dt;

                if (ee_sum_nsum <= 1)
                {
                    fro->nsum = 0;
                }
                else
                {
                    fro->nsum = gmx_large_int_to_int(ee_sum_nsum,
                                                     "energy average summation");
                    /* Copy the energy sums */
                    for (i = 0; i < nre; i++)
                    {
                        fro->ener[i].esum = ee_sum[i].esum;
                        fro->ener[i].eav  = ee_sum[i].eav;
                    }
                }
                /* We wrote the energies, so reset the counts */
                ee_sum_nsteps = 0;
                ee_sum_nsum   = 0;

                if (scalefac != 1)
                {
                    for (kkk = 0; kkk < nset; kkk++)
                    {
                        fro->ener[set[kkk]].e    *= scalefac;
                        if (fro->nsum > 0)
                        {
                            fro->ener[set[kkk]].eav  *= scalefac*scalefac;
                            fro->ener[set[kkk]].esum *= scalefac;
                        }
                    }
                }
                /* Copy restraint stuff */
                /*fro->ndisre       = fr->ndisre;
                   fro->disre_rm3tav = fr->disre_rm3tav;
                   fro->disre_rt     = fr->disre_rt;*/
                fro->nblock       = fr->nblock;
                /*fro->nr           = fr->nr;*/
                fro->block        = fr->block;

                /* check if we have blocks with delta_h data and are throwing
                   away data */
                if (fro->nblock > 0)
                {
                    if (remove_dh)
                    {
                        int i;
                        if (!blocks || nblocks_alloc < fr->nblock)
                        {
                            /* we pre-allocate the blocks */
                            nblocks_alloc = fr->nblock;
                            snew(blocks, nblocks_alloc);
                        }
                        nblocks = 0; /* number of blocks so far */

                        for (i = 0; i < fr->nblock; i++)
                        {
                            if ( (fr->block[i].id != enxDHCOLL) &&
                                 (fr->block[i].id != enxDH) &&
                                 (fr->block[i].id != enxDHHIST) )
                            {
                                /* copy everything verbatim */
                                blocks[nblocks] = fr->block[i];
                                nblocks++;
                            }
                        }
                        /* now set the block pointer to the new blocks */
                        fro->nblock = nblocks;
                        fro->block  = blocks;
                    }
                    else if (delta_t > 0)
                    {
                        if (!warned_about_dh)
                        {
                            for (i = 0; i < fr->nblock; i++)
                            {
                                if (fr->block[i].id == enxDH ||
                                    fr->block[i].id == enxDHHIST)
                                {
                                    int size;
                                    if (fr->block[i].id == enxDH)
                                    {
                                        size = fr->block[i].sub[2].nr;
                                    }
                                    else
                                    {
                                        size = fr->nsteps;
                                    }
                                    if (size > 0)
                                    {
                                        printf("\nWARNING: %s contains delta H blocks or histograms for which\n"
                                               "         some data is thrown away on a block-by-block basis, where each block\n"
                                               "         contains up to %d samples.\n"
                                               "         This is almost certainly not what you want.\n"
                                               "         Use the -rmdh option to throw all delta H samples away.\n"
                                               "         Use g_energy -odh option to extract these samples.\n",
                                               fnms[f], size);
                                        warned_about_dh = TRUE;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                do_enx(out, fro);
                if (noutfr % 1000 == 0)
                {
                    fprintf(stderr, "Writing frame time %g    ", fro->t);
                }
                noutfr++;
            }
        }
        if (f == nfile)
        {
            f--;
        }
        printf("\nLast step written from %s: t %g, step %s\n",
               fnms[f], last_t, gmx_step_str(laststep, buf));
        lastfilestep = laststep;

        /* set the next time from the last in previous file */
        if (cont_type[f+1] == TIME_CONTINUE)
        {
            settime[f+1] = fro->t;
            /* in this case we have already written the last frame of
             * previous file, so update begin to avoid doubling it
             * with the start of the next file
             */
            begin = fro->t+0.5*timestep;
            /* cont_type[f+1]==TIME_EXPLICIT; */
        }

        if ((fro->t < end) && (f < nfile-1) &&
            (fro->t < settime[f+1]-1.5*timestep))
        {
            fprintf(stderr,
                    "\nWARNING: There might be a gap around t=%g\n", fro->t);
        }

        /* move energies to lastee */
        close_enx(in);
        free_enxnms(this_nre, enm);

        fprintf(stderr, "\n");
    }
    if (noutfr == 0)
    {
        fprintf(stderr, "No frames written.\n");
    }
    else
    {
        fprintf(stderr, "Last frame written was at step %s, time %f\n",
                gmx_step_str(fro->step, buf), fro->t);
        fprintf(stderr, "Wrote %d frames\n", noutfr);
    }

    return 0;
}
int gmx_chi(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_chi[tt] computes [GRK]phi[grk], [GRK]psi[grk], [GRK]omega[grk], and [GRK]chi[grk] dihedrals for all your ",
    "amino acid backbone and sidechains.",
    "It can compute dihedral angle as a function of time, and as",
    "histogram distributions.",
    "The distributions [TT](histo-(dihedral)(RESIDUE).xvg[tt]) are cumulative over all residues of each type.[PAR]", 
    "If option [TT]-corr[tt] is given, the program will",
    "calculate dihedral autocorrelation functions. The function used",
    "is C(t) = < cos([GRK]chi[grk]([GRK]tau[grk])) cos([GRK]chi[grk]([GRK]tau[grk]+t)) >. The use of cosines",
    "rather than angles themselves, resolves the problem of periodicity.",
    "(Van der Spoel & Berendsen (1997), Biophys. J. 72, 2032-2041).",
    "Separate files for each dihedral of each residue", 
    "[TT](corr(dihedral)(RESIDUE)(nresnr).xvg[tt]) are output, as well as a", 
    "file containing the information for all residues (argument of [TT]-corr[tt]).[PAR]", 
    "With option [TT]-all[tt], the angles themselves as a function of time for", 
    "each residue are printed to separate files [TT](dihedral)(RESIDUE)(nresnr).xvg[tt].", 
    "These can be in radians or degrees.[PAR]", 
    "A log file (argument [TT]-g[tt]) is also written. This contains [BR]",
    "(a) information about the number of residues of each type.[BR]", 
    "(b) The NMR ^3J coupling constants from the Karplus equation.[BR]", 
    "(c) a table for each residue of the number of transitions between ", 
    "rotamers per nanosecond,  and the order parameter S^2 of each dihedral.[BR]",
    "(d) a table for each residue of the rotamer occupancy.[PAR]", 
    "All rotamers are taken as 3-fold, except for [GRK]omega[grk] and [GRK]chi[grk] dihedrals",
    "to planar groups (i.e. [GRK]chi[grk]2 of aromatics, Asp and Asn; [GRK]chi[grk]3 of Glu", 
    "and Gln; and [GRK]chi[grk]4 of Arg), which are 2-fold. \"rotamer 0\" means ", 
    "that the dihedral was not in the core region of each rotamer. ", 
    "The width of the core region can be set with [TT]-core_rotamer[tt][PAR]", 

    "The S^2 order parameters are also output to an [TT].xvg[tt] file", 
    "(argument [TT]-o[tt] ) and optionally as a [TT].pdb[tt] file with", 
    "the S^2 values as B-factor (argument [TT]-p[tt]). ", 
    "The total number of rotamer transitions per timestep", 
    "(argument [TT]-ot[tt]), the number of transitions per rotamer", 
    "(argument [TT]-rt[tt]), and the ^3J couplings (argument [TT]-jc[tt]), ", 
    "can also be written to [TT].xvg[tt] files.[PAR]", 

    "If [TT]-chi_prod[tt] is set (and [TT]-maxchi[tt] > 0), cumulative rotamers, e.g.", 
    "1+9([GRK]chi[grk]1-1)+3([GRK]chi[grk]2-1)+([GRK]chi[grk]3-1) (if the residue has three 3-fold ", 
    "dihedrals and [TT]-maxchi[tt] >= 3)", 
    "are calculated. As before, if any dihedral is not in the core region,", 
    "the rotamer is taken to be 0. The occupancies of these cumulative ",
    "rotamers (starting with rotamer 0) are written to the file", 
    "that is the argument of [TT]-cp[tt], and if the [TT]-all[tt] flag", 
    "is given, the rotamers as functions of time", 
    "are written to [TT]chiproduct(RESIDUE)(nresnr).xvg[tt] ", 
    "and their occupancies to [TT]histo-chiproduct(RESIDUE)(nresnr).xvg[tt].[PAR]", 

    "The option [TT]-r[tt] generates a contour plot of the average [GRK]omega[grk] angle",
    "as a function of the [GRK]phi[grk] and [GRK]psi[grk] angles, that is, in a Ramachandran plot",
    "the average [GRK]omega[grk] angle is plotted using color coding.", 

  };
  
  const char *bugs[] = {
    "Produces MANY output files (up to about 4 times the number of residues in the protein, twice that if autocorrelation functions are calculated). Typically several hundred files are output.",
    "[GRK]phi[grk] and [GRK]psi[grk] dihedrals are calculated in a non-standard way, using H-N-CA-C for [GRK]phi[grk] instead of C(-)-N-CA-C, and N-CA-C-O for [GRK]psi[grk] instead of N-CA-C-N(+). This causes (usually small) discrepancies with the output of other tools like [TT]g_rama[tt].", 
    "[TT]-r0[tt] option does not work properly", 
    "Rotamers with multiplicity 2 are printed in [TT]chi.log[tt] as if they had multiplicity 3, with the 3rd (g(+)) always having probability 0" 
  };

  /* defaults */ 
  static int  r0=1,ndeg=1,maxchi=2;
  static gmx_bool bAll=FALSE;
  static gmx_bool bPhi=FALSE,bPsi=FALSE,bOmega=FALSE;
  static real bfac_init=-1.0,bfac_max=0;
  static const char *maxchistr[] = { NULL, "0", "1", "2", "3",  "4", "5", "6", NULL };
  static gmx_bool bRama=FALSE,bShift=FALSE,bViol=FALSE,bRamOmega=FALSE;
  static gmx_bool bNormHisto=TRUE,bChiProduct=FALSE,bHChi=FALSE,bRAD=FALSE,bPBC=TRUE;
  static real core_frac=0.5 ;  
  t_pargs pa[] = {
    { "-r0",  FALSE, etINT, {&r0},
      "starting residue" },
    { "-phi",  FALSE, etBOOL, {&bPhi},
      "Output for [GRK]phi[grk] dihedral angles" },
    { "-psi",  FALSE, etBOOL, {&bPsi},
      "Output for [GRK]psi[grk] dihedral angles" },
    { "-omega",FALSE, etBOOL, {&bOmega},  
      "Output for [GRK]omega[grk] dihedrals (peptide bonds)" },
    { "-rama", FALSE, etBOOL, {&bRama},
      "Generate [GRK]phi[grk]/[GRK]psi[grk] and [GRK]chi[grk]1/[GRK]chi[grk]2 Ramachandran plots" },
    { "-viol", FALSE, etBOOL, {&bViol},
      "Write a file that gives 0 or 1 for violated Ramachandran angles" },
    { "-periodic", FALSE, etBOOL, {&bPBC},
      "Print dihedral angles modulo 360 degrees" },
    { "-all",  FALSE, etBOOL, {&bAll},
      "Output separate files for every dihedral." },
    { "-rad",  FALSE, etBOOL, {&bRAD},
      "in angle vs time files, use radians rather than degrees."}, 
    { "-shift", FALSE, etBOOL, {&bShift},
	"Compute chemical shifts from [GRK]phi[grk]/[GRK]psi[grk] angles" },
    { "-binwidth", FALSE, etINT, {&ndeg},
      "bin width for histograms (degrees)" },
    { "-core_rotamer", FALSE, etREAL, {&core_frac},
      "only the central [TT]-core_rotamer[tt]*(360/multiplicity) belongs to each rotamer (the rest is assigned to rotamer 0)" },
    { "-maxchi", FALSE, etENUM, {maxchistr},
      "calculate first ndih [GRK]chi[grk] dihedrals" },
    { "-normhisto", FALSE, etBOOL, {&bNormHisto},
      "Normalize histograms" },
    { "-ramomega",FALSE,etBOOL, {&bRamOmega},
      "compute average omega as a function of phi/psi and plot it in an [TT].xpm[tt] plot" },
    { "-bfact", FALSE, etREAL, {&bfac_init},
      "B-factor value for [TT].pdb[tt] file for atoms with no calculated dihedral order parameter"},
    { "-chi_prod",FALSE,etBOOL, {&bChiProduct},
      "compute a single cumulative rotamer for each residue"},
    { "-HChi",FALSE,etBOOL, {&bHChi},
      "Include dihedrals to sidechain hydrogens"}, 
    { "-bmax",  FALSE, etREAL, {&bfac_max},
      "Maximum B-factor on any of the atoms that make up a dihedral, for the dihedral angle to be considere in the statistics. Applies to database work where a number of X-Ray structures is analyzed. [TT]-bmax[tt] <= 0 means no limit." }
  };

  FILE       *log;
  int        natoms,nlist,idum,nbin;
  t_atoms    atoms;
  rvec       *x;
  int        ePBC;
  matrix     box;
  char       title[256],grpname[256]; 
  t_dlist    *dlist;
  gmx_bool       bChi,bCorr,bSSHisto;
  gmx_bool       bDo_rt, bDo_oh, bDo_ot, bDo_jc ; 
  real       dt=0, traj_t_ns;
  output_env_t oenv;
  gmx_residuetype_t rt;
  
  atom_id    isize,*index;
  int        ndih,nactdih,nf;
  real       **dih,*trans_frac,*aver_angle,*time;
  int        i,j,**chi_lookup,*xity; 
  
  t_filenm  fnm[] = {
    { efSTX, "-s",  NULL,     ffREAD  },
    { efTRX, "-f",  NULL,     ffREAD  },
    { efXVG, "-o",  "order",  ffWRITE },
    { efPDB, "-p",  "order",  ffOPTWR },
    { efDAT, "-ss", "ssdump", ffOPTRD },
    { efXVG, "-jc", "Jcoupling", ffWRITE },
    { efXVG, "-corr",  "dihcorr",ffOPTWR },
    { efLOG, "-g",  "chi",    ffWRITE },
    /* add two more arguments copying from g_angle */ 
    { efXVG, "-ot", "dihtrans", ffOPTWR }, 
    { efXVG, "-oh", "trhisto",  ffOPTWR },
    { efXVG, "-rt", "restrans",  ffOPTWR }, 
    { efXVG, "-cp", "chiprodhisto",  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_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,npargs,ppa,asize(desc),desc,asize(bugs),bugs,
                    &oenv);

  /* Handle result from enumerated type */
  sscanf(maxchistr[0],"%d",&maxchi);
  bChi = (maxchi > 0);
  
  log=ffopen(ftp2fn(efLOG,NFILE,fnm),"w");

  if (bRamOmega) {
    bOmega = TRUE;
    bPhi   = TRUE;
    bPsi   = TRUE;
  }
    
  /* set some options */ 
  bDo_rt=(opt2bSet("-rt",NFILE,fnm));
  bDo_oh=(opt2bSet("-oh",NFILE,fnm));
  bDo_ot=(opt2bSet("-ot",NFILE,fnm));
  bDo_jc=(opt2bSet("-jc",NFILE,fnm));
  bCorr=(opt2bSet("-corr",NFILE,fnm));
  if (bCorr) 
    fprintf(stderr,"Will calculate autocorrelation\n");
  
  if (core_frac > 1.0 ) {
    fprintf(stderr, "core_rotamer fraction > 1.0 ; will use 1.0\n"); 
    core_frac=1.0 ; 
  }
  if (core_frac < 0.0 ) {
    fprintf(stderr, "core_rotamer fraction < 0.0 ; will use 0.0\n"); 
    core_frac=0.0 ; 
  }

  if (maxchi > MAXCHI) {
    fprintf(stderr, 
	    "Will only calculate first %d Chi dihedrals in stead of %d.\n",
	    MAXCHI, maxchi);
    maxchi=MAXCHI;
  }
  bSSHisto = ftp2bSet(efDAT,NFILE,fnm);
  nbin = 360/ndeg ; 

  /* Find the chi angles using atoms struct and a list of amino acids */
  get_stx_coordnum(ftp2fn(efSTX,NFILE,fnm),&natoms);
  init_t_atoms(&atoms,natoms,TRUE);
  snew(x,natoms);
  read_stx_conf(ftp2fn(efSTX,NFILE,fnm),title,&atoms,x,NULL,&ePBC,box);
  fprintf(log,"Title: %s\n",title);
  
  gmx_residuetype_init(&rt);
  dlist=mk_dlist(log,&atoms,&nlist,bPhi,bPsi,bChi,bHChi,maxchi,r0,rt);
  fprintf(stderr,"%d residues with dihedrals found\n", nlist);
  
  if (nlist == 0) 
    gmx_fatal(FARGS,"No dihedrals in your structure!\n");
  
  /* Make a linear index for reading all. */
  index=make_chi_ind(nlist,dlist,&ndih);
  isize=4*ndih;
  fprintf(stderr,"%d dihedrals found\n", ndih);

  snew(dih,ndih);

  /* COMPUTE ALL DIHEDRALS! */
  read_ang_dih(ftp2fn(efTRX,NFILE,fnm),FALSE,TRUE,FALSE,bPBC,1,&idum,
	       &nf,&time,isize,index,&trans_frac,&aver_angle,dih,oenv);
  
  dt=(time[nf-1]-time[0])/(nf-1); /* might want this for corr or n. transit*/ 
  if (bCorr) 
  {
	  if (nf < 2)
	  {
		  gmx_fatal(FARGS,"Need at least 2 frames for correlation");
	  }
  }

  /* put angles in -M_PI to M_PI ! and correct phase factor for phi and psi 
  * pass nactdih instead of ndih to low_ana_dih_trans and get_chi_product_traj
  * to prevent accessing off end of arrays when maxchi < 5 or 6. */ 
  nactdih = reset_em_all(nlist,dlist,nf,dih,maxchi);
  
  if (bAll)
    dump_em_all(nlist,dlist,nf,time,dih,maxchi,bPhi,bPsi,bChi,bOmega,bRAD,oenv);
  
  /* Histogramming & J coupling constants & calc of S2 order params */
  histogramming(log,nbin,rt,nf,maxchi,dih,nlist,dlist,index,
		bPhi,bPsi,bOmega,bChi,
		bNormHisto,bSSHisto,ftp2fn(efDAT,NFILE,fnm),bfac_max,&atoms,
		bDo_jc,opt2fn("-jc",NFILE,fnm),oenv);

  /* transitions 
   *
   * added multiplicity */ 

  snew(xity,ndih) ;
  mk_multiplicity_lookup(xity, maxchi, dih, nlist, dlist,ndih); 
 
  strcpy(grpname, "All residues, "); 
  if(bPhi) 
    strcat(grpname, "Phi "); 
  if(bPsi) 
    strcat(grpname, "Psi "); 
  if(bOmega) 
    strcat(grpname, "Omega "); 
  if(bChi){ 
    strcat(grpname, "Chi 1-") ; 
    sprintf(grpname + strlen(grpname), "%i", maxchi); 
  }


  low_ana_dih_trans(bDo_ot, opt2fn("-ot",NFILE,fnm),
		    bDo_oh, opt2fn("-oh",NFILE,fnm),maxchi, 
		    dih, nlist, dlist, nf, nactdih, grpname, xity, 
		    *time,  dt, FALSE, core_frac,oenv) ; 

  /* Order parameters */  
  order_params(log,opt2fn("-o",NFILE,fnm),maxchi,nlist,dlist,
	       ftp2fn_null(efPDB,NFILE,fnm),bfac_init,
	       &atoms,x,ePBC,box,bPhi,bPsi,bChi,oenv);
  
  /* Print ramachandran maps! */
  if (bRama)
    do_rama(nf,nlist,dlist,dih,bViol,bRamOmega,oenv);
  
  if (bShift)
    do_pp2shifts(log,nf,nlist,dlist,dih);

  /* rprint S^2, transitions, and rotamer occupancies to log */ 
  traj_t_ns = 0.001 * (time[nf-1]-time[0]) ; 
  pr_dlist(log,nlist,dlist,traj_t_ns,edPrintST,bPhi,bPsi,bChi,bOmega,maxchi);
  pr_dlist(log,nlist,dlist,traj_t_ns,edPrintRO,bPhi,bPsi,bChi,bOmega,maxchi);  
  ffclose(log);
  /* transitions to xvg */
  if (bDo_rt)
    print_transitions(opt2fn("-rt",NFILE,fnm),maxchi,nlist,dlist,
		      &atoms,x,box,bPhi,bPsi,bChi,traj_t_ns,oenv); 
  
  /* chi_product trajectories (ie one "rotamer number" for each residue) */
  if (bChiProduct && bChi ) {
    snew(chi_lookup,nlist) ;
    for (i=0;i<nlist;i++)
      snew(chi_lookup[i], maxchi) ; 
    mk_chi_lookup(chi_lookup, maxchi, dih, nlist, dlist); 
    
    get_chi_product_traj(dih,nf,nactdih,nlist,
			 maxchi,dlist,time,chi_lookup,xity,
			 FALSE,bNormHisto, core_frac,bAll,
			 opt2fn("-cp",NFILE,fnm),oenv); 

    for (i=0;i<nlist;i++)
      sfree(chi_lookup[i]); 
  }

  /* Correlation comes last because it f***s up the angles */
  if (bCorr)
    do_dihcorr(opt2fn("-corr",NFILE,fnm),nf,ndih,dih,dt,nlist,dlist,time,
	       maxchi,bPhi,bPsi,bChi,bOmega,oenv);
  
  
  do_view(oenv,opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(oenv,opt2fn("-jc",NFILE,fnm),"-nxy");
  if (bCorr)
    do_view(oenv,opt2fn("-corr",NFILE,fnm),"-nxy");
    
  gmx_residuetype_destroy(rt);

  thanx(stderr);
    
  return 0;
}
示例#6
0
int gmx_genconf(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] multiplies a given coordinate file by simply stacking them",
        "on top of each other, like a small child playing with wooden blocks.",
        "The program makes a grid of [IT]user-defined[it]",
        "proportions ([TT]-nbox[tt]), ",
        "and interspaces the grid point with an extra space [TT]-dist[tt].[PAR]",
        "When option [TT]-rot[tt] is used the program does not check for overlap",
        "between molecules on grid points. It is recommended to make the box in",
        "the input file at least as big as the coordinates + ",
        "van der Waals radius.[PAR]",
        "If the optional trajectory file is given, conformations are not",
        "generated, but read from this file and translated appropriately to",
        "build the grid."

    };
    const char       *bugs[] = {
        "The program should allow for random displacement of lattice points."
    };

    int               vol;
    t_atoms          *atoms;      /* list with all atoms */
    rvec             *x, *xx, *v; /* coordinates? */
    real              t;
    vec4             *xrot, *vrot;
    int               ePBC;
    matrix            box, boxx; /* box length matrix */
    rvec              shift;
    int               natoms;    /* number of atoms in one molecule  */
    int               nres;      /* number of molecules? */
    int               i, j, k, l, m, ndx, nrdx, nx, ny, nz;
    t_trxstatus      *status;
    gmx_bool          bTRX;
    gmx_output_env_t *oenv;
    gmx_rng_t         rng;

    t_filenm          fnm[] = {
        { efSTX, "-f", "conf", ffREAD  },
        { efSTO, "-o", "out",  ffWRITE },
        { efTRX, "-trj", NULL,  ffOPTRD }
    };
#define NFILE asize(fnm)
    static rvec       nrbox    = {1, 1, 1};
    static int        seed     = 0;               /* seed for random number generator */
    static gmx_bool   bRandom  = FALSE;           /* False: no random rotations */
    static gmx_bool   bRenum   = TRUE;            /* renumber residues */
    static rvec       dist     = {0, 0, 0};       /* space added between molecules ? */
    static rvec       max_rot  = {180, 180, 180}; /* maximum rotation */
    t_pargs           pa[]     = {
        { "-nbox",   FALSE, etRVEC, {nrbox},   "Number of boxes" },
        { "-dist",   FALSE, etRVEC, {dist},    "Distance between boxes" },
        { "-seed",   FALSE, etINT,  {&seed},
          "Random generator seed, if 0 generated from the time" },
        { "-rot",    FALSE, etBOOL, {&bRandom}, "Randomly rotate conformations" },
        { "-maxrot", FALSE, etRVEC, {max_rot}, "Maximum random rotation" },
        { "-renumber", FALSE, etBOOL, {&bRenum},  "Renumber residues" }
    };

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

    if (seed == 0)
    {
        rng = gmx_rng_init(gmx_rng_make_seed());
    }
    else
    {
        rng = gmx_rng_init(seed);
    }

    bTRX = ftp2bSet(efTRX, NFILE, fnm);
    nx   = (int)(nrbox[XX]+0.5);
    ny   = (int)(nrbox[YY]+0.5);
    nz   = (int)(nrbox[ZZ]+0.5);

    if ((nx <= 0) || (ny <= 0) || (nz <= 0))
    {
        gmx_fatal(FARGS, "Number of boxes (-nbox) should be larger than zero");
    }

    vol = nx*ny*nz; /* calculate volume in grid points (= nr. molecules) */

    t_topology *top;
    snew(top, 1);
    atoms = &top->atoms;
    read_tps_conf(opt2fn("-f", NFILE, fnm), top, &ePBC, &x, &v, box, FALSE);
    natoms = atoms->nr;
    nres   = atoms->nres;          /* nr of residues in one element? */
    /* make space for all the atoms */
    add_t_atoms(atoms, natoms*(vol-1), nres*(vol-1));
    srenew(x, natoms*vol);         /* get space for coordinates of all atoms */
    srenew(v, natoms*vol);         /* velocities. not really needed? */
    snew(xrot, natoms);            /* get space for rotation matrix? */
    snew(vrot, natoms);

    if (bTRX)
    {
        if (!read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &xx, boxx))
        {
            gmx_fatal(FARGS, "No atoms in trajectory %s", ftp2fn(efTRX, NFILE, fnm));
        }
    }
    else
    {
        snew(xx, natoms);
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(x[i], xx[i]);
        }
    }


    for (k = 0; (k < nz); k++)     /* loop over all gridpositions    */
    {
        shift[ZZ] = k*(dist[ZZ]+box[ZZ][ZZ]);

        for (j = 0; (j < ny); j++)
        {
            shift[YY] = j*(dist[YY]+box[YY][YY])+k*box[ZZ][YY];

            for (i = 0; (i < nx); i++)
            {
                shift[XX] = i*(dist[XX]+box[XX][XX])+j*box[YY][XX]+k*box[ZZ][XX];

                ndx  = (i*ny*nz+j*nz+k)*natoms;
                nrdx = (i*ny*nz+j*nz+k)*nres;

                /* Random rotation on input coords */
                if (bRandom)
                {
                    rand_rot(natoms, xx, v, xrot, vrot, rng, max_rot);
                }

                for (l = 0; (l < natoms); l++)
                {
                    for (m = 0; (m < DIM); m++)
                    {
                        if (bRandom)
                        {
                            x[ndx+l][m] = xrot[l][m];
                            v[ndx+l][m] = vrot[l][m];
                        }
                        else
                        {
                            x[ndx+l][m] = xx[l][m];
                            v[ndx+l][m] = v[l][m];
                        }
                    }
                    if (ePBC == epbcSCREW && i % 2 == 1)
                    {
                        /* Rotate around x axis */
                        for (m = YY; m <= ZZ; m++)
                        {
                            x[ndx+l][m] = box[YY][m] + box[ZZ][m] - x[ndx+l][m];
                            v[ndx+l][m] = -v[ndx+l][m];
                        }
                    }
                    for (m = 0; (m < DIM); m++)
                    {
                        x[ndx+l][m] += shift[m];
                    }
                    atoms->atom[ndx+l].resind = nrdx + atoms->atom[l].resind;
                    atoms->atomname[ndx+l]    = atoms->atomname[l];
                }

                for (l = 0; (l < nres); l++)
                {
                    atoms->resinfo[nrdx+l] = atoms->resinfo[l];
                    if (bRenum)
                    {
                        atoms->resinfo[nrdx+l].nr += nrdx;
                    }
                }
                if (bTRX)
                {
                    if (!read_next_x(oenv, status, &t, xx, boxx) &&
                        ((i+1)*(j+1)*(k+1) < vol))
                    {
                        gmx_fatal(FARGS, "Not enough frames in trajectory");
                    }
                }
            }
        }
    }
    if (bTRX)
    {
        close_trj(status);
    }

    /* make box bigger */
    for (m = 0; (m < DIM); m++)
    {
        box[m][m] += dist[m];
    }
    svmul(nx, box[XX], box[XX]);
    svmul(ny, box[YY], box[YY]);
    svmul(nz, box[ZZ], box[ZZ]);
    if (ePBC == epbcSCREW && nx % 2 == 0)
    {
        /* With an even number of boxes in x we can forgot about the screw */
        ePBC = epbcXYZ;
    }

    /*depending on how you look at it, this is either a nasty hack or the way it should work*/
    if (bRenum)
    {
        for (i = 0; i < atoms->nres; i++)
        {
            atoms->resinfo[i].nr = i+1;
        }
    }

    gmx_rng_destroy(rng);

    write_sto_conf(opt2fn("-o", NFILE, fnm), *top->name, atoms, x, v, ePBC, box);

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

    t_pargs
        pa[] =
    {
        { "-b", FALSE, etTIME,
          { &begin }, "First time to use (%t)" },
        { "-e", FALSE, etTIME,
          { &end }, "Last time to use (%t)" },
        { "-dt", FALSE, etTIME,
          { &dt }, "Only write frame when t MOD dt = first time (%t)" },
        { "-settime", FALSE, etBOOL,
          { &bSetTime }, "Change starting time interactively" },
        { "-sort", FALSE, etBOOL,
          { &bSort }, "Sort trajectory files (not frames)" },
        { "-keeplast", FALSE, etBOOL,
          { &bKeepLast }, "Keep overlapping frames at end of trajectory" },
        { "-overwrite", FALSE, etBOOL,
          { &bOverwrite }, "Overwrite overlapping frames during appending" },
        { "-cat", FALSE, etBOOL,
          { &bCat }, "Do not discard double time frames" }
    };
#define npargs asize(pa)
    int               ftpin, i, frame, frame_out;
    t_trxstatus      *status, *trxout = nullptr;
    real              t_corr;
    t_trxframe        fr, frout;
    int               n_append;
    gmx_bool          bNewFile, bIndex, bWrite;
    int              *cont_type;
    real             *readtime, *timest, *settime;
    real              first_time  = 0, lasttime = 0, last_ok_t = -1, timestep;
    gmx_bool          lastTimeSet = FALSE;
    real              last_frame_time, searchtime;
    int               isize = 0, j;
    int              *index = nullptr, imax;
    char             *grpname;
    real            **val = nullptr, *t = nullptr, dt_remd;
    int               n, nset, ftpout = -1, prevEndStep = 0, filetype;
    gmx_off_t         fpos;
    gmx_output_env_t *oenv;
    t_filenm          fnm[] =
    {
        { efTRX, "-f", nullptr, ffRDMULT },
        { efTRO, "-o", nullptr, 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, nullptr, &oenv))
    {
        return 0;
    }
    fprintf(stdout, "Note that major changes are planned in future for "
            "trjcat, to improve usability and utility.");

    auto timeUnit = output_env_get_time_unit(oenv);

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

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

    gmx::ArrayRef<const std::string> inFiles = opt2fns("-f", NFILE, fnm);
    if (inFiles.empty())
    {
        gmx_fatal(FARGS, "No input files!" );
    }

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

    ftpin = fn2ftp(inFiles[0].c_str());

    if (ftpin != efTRR && ftpin != efXTC && ftpin != efTNG)
    {
        gmx_fatal(FARGS, "gmx trjcat can only handle binary trajectory formats (trr, xtc, tng)");
    }

    for (const std::string &inFile : inFiles)
    {
        if (ftpin != fn2ftp(inFile.c_str()))
        {
            gmx_fatal(FARGS, "All input files must be of the same (trr, xtc or tng) format");
        }
    }

    gmx::ArrayRef<const std::string> outFiles = opt2fns("-o", NFILE, fnm);
    if (outFiles.empty())
    {
        gmx_fatal(FARGS, "No output files!");
    }
    if ((outFiles.size() > 1) && !bDeMux)
    {
        gmx_fatal(FARGS, "Don't know what to do with more than 1 output file if  not demultiplexing");
    }
    else if (bDeMux && ssize(outFiles) != nset && outFiles.size() != 1)
    {
        gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %td", nset, outFiles.ssize());
    }
    if (bDeMux)
    {
        auto outFilesDemux = gmx::copyOf(outFiles);
        if (gmx::ssize(outFilesDemux) != nset)
        {
            std::string name = outFilesDemux[0];
            outFilesDemux.resize(nset);
            for (i = 0; (i < nset); i++)
            {
                outFilesDemux[0] = gmx::formatString("%d_%s", i, name.c_str());
            }
        }
        do_demux(inFiles, outFilesDemux, n, val, t, dt_remd, isize, index, dt, oenv);
    }
    else
    {
        snew(readtime, inFiles.size() + 1);
        snew(timest, inFiles.size() + 1);
        scan_trj_files(inFiles, readtime, timest, imax, oenv);

        snew(settime, inFiles.size() + 1);
        snew(cont_type, inFiles.size() + 1);
        auto inFilesEdited = gmx::copyOf(inFiles);
        edit_files(inFilesEdited, 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.
         */
        const char *out_file = outFiles[0].c_str();
        ftpout   = fn2ftp(out_file);
        n_append = -1;
        for (size_t i = 0; i < inFilesEdited.size() && n_append == -1; i++)
        {
            if (std::strcmp(inFilesEdited[i].c_str(), 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)",
                      inFilesEdited[0].c_str(), 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)
                {
                    trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr,
                                                              inFilesEdited[0].c_str(), isize, nullptr, gmx::arrayRefFromArray(index, isize), grpname);
                }
                else
                {
                    trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr,
                                                              inFilesEdited[0].c_str(), -1, nullptr, {}, nullptr);
                }
            }
            else
            {
                trxout = open_trx(out_file, "w");
            }
            std::memset(&frout, 0, sizeof(frout));
        }
        else
        {
            t_fileio *stfio;

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

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

                filetype = gmx_fio_getftp(stfio);
                /* Fails if last frame is incomplete
                 * We can't do anything about it without overwriting
                 * */
                if (filetype == efXTC || filetype == efTNG)
                {
                    lasttime = trx_get_time_of_final_frame(status);
                    fr.time  = lasttime;
                }
                else
                {
                    while (read_next_frame(oenv, status, &fr))
                    {
                        ;
                    }
                    lasttime = fr.time;
                }
                lastTimeSet     = TRUE;
                bKeepLastAppend = TRUE;
                close_trx(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 (inFilesEdited.size() > 1 && settime[1] < last_frame_time+timest[0]*0.5)
                {
                    /* Jump to one time-frame before the start of next
                     *  trajectory file */
                    searchtime = settime[1]-timest[0]*1.25;
                }
                else
                {
                    searchtime = last_frame_time;
                }
                if (xtc_seek_time(stfio, searchtime, fr.natoms, TRUE))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
                read_next_frame(oenv, status, &fr);
                if (std::abs(searchtime - fr.time) > timest[0]*0.5)
                {
                    gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.",
                              searchtime, fr.time);
                }
                lasttime    = fr.time;
                lastTimeSet = TRUE;
                fpos        = gmx_fio_ftell(stfio);
                close_trx(status);
                trxout = open_trx(out_file, "r+");
                if (gmx_fio_seek(trx_get_fileio(trxout), fpos))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
            }
            if (lastTimeSet)
            {
                printf("\n Will append after %f \n", lasttime);
            }
            frout = fr;
        }
        /* Lets stitch up some files */
        timestep = timest[0];
        for (size_t i = n_append + 1; i < inFilesEdited.size(); 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 < inFilesEdited.size() &&
                        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),
                                timeUnit.c_str());
                    }
                }
            }

            /* 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, inFilesEdited[i].c_str(), &fr, FLAGS);
            if (!fr.bTime)
            {
                fr.time = 0;
                fprintf(stderr, "\nWARNING: Couldn't find a time in the frame.\n");
            }

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

            bNewFile = TRUE;

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

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

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

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

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

            close_trx(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), timeUnit.c_str());
    }

    return 0;
}
示例#8
0
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, *fnTRX, *fnDAT = NULL;
    t_trxstatus                          *status;
    t_topology                           *top  = NULL;
    gmx_rmpbc_t                           gpbc = NULL;
    gmx_bool                              bFFT = FALSE, bDEBYE = FALSE;
    gmx_bool                              bMC  = FALSE;
    int                                   ePBC = -1;
    matrix                                box;
    rvec                                 *x;
    int                                   natoms;
    real                                  t;
    char                                **grpname = NULL;
    int                                  *index   = NULL;
    int                                   isize;
    int                                   i;
    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;
    gmx_output_env_t                     *oenv;

#define NFILE asize(fnm)

    t_filenm   fnm[] = {
        { efTPR,  "-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,
                           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 */
    GMX_RELEASE_ASSERT(emethod[0] != NULL, "Options inconsistency; emethod[0] is NULL");
    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(efTPR, 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);

    read_tps_conf(fnTPX, 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);
            xvgrclose(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);
            xvgrclose(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;
}
示例#9
0
void
gmx_nonbonded_set_kernel_pointers(FILE *log, t_nblist *nl)
{
    const char *     elec;
    const char *     elec_mod;
    const char *     vdw;
    const char *     vdw_mod;
    const char *     geom;
    const char *     other;
    const char *     vf;

    struct
    {
        const char *  arch;
        int           simd_padding_width;
    }
    arch_and_padding[] =
    {
        /* Single precision */
#if (defined GMX_SIMD_X86_AVX_256_OR_HIGHER) && !(defined GMX_DOUBLE)
        { "avx_256_single", 8 },
#endif
#if (defined GMX_SIMD_X86_AVX_128_FMA) && !(defined GMX_DOUBLE)
        { "avx_128_fma_single", 4 },
#endif
#if (defined GMX_SIMD_X86_SSE4_1) && !(defined GMX_DOUBLE)
        { "sse4_1_single", 4 },
#endif
#if (defined GMX_SIMD_X86_SSE2) && !(defined GMX_DOUBLE)
        { "sse2_single", 4 },
#endif
        /* Double precision */
#if (defined GMX_SIMD_X86_AVX_256_OR_HIGHER && defined GMX_DOUBLE)
        { "avx_256_double", 4 },
#endif
#if (defined GMX_SIMD_X86_AVX_128_FMA && defined GMX_DOUBLE)
        /* Sic. Double precision 2-way SIMD does not require neighbor list padding,
         * since the kernels execute a loop unrolled a factor 2, followed by
         * a possible single odd-element epilogue.
         */
        { "avx_128_fma_double", 1 },
#endif
#if (defined GMX_SIMD_X86_SSE2 && defined GMX_DOUBLE)
        /* No padding - see comment above */
        { "sse2_double", 1 },
#endif
#if (defined GMX_SIMD_X86_SSE4_1 && defined GMX_DOUBLE)
        /* No padding - see comment above */
        { "sse4_1_double", 1 },
#endif
#if (defined GMX_SIMD_SPARC64_HPC_ACE && defined GMX_DOUBLE)
        /* No padding - see comment above */
        { "sparc64_hpc_ace_double", 1 },
#endif
        { "c", 1 },
    };
    int              narch = asize(arch_and_padding);
    int              i;

    if (nonbonded_setup_done == FALSE)
    {
        /* We typically call this setup routine before starting timers,
         * but if that has not been done for whatever reason we do it now.
         */
        gmx_nonbonded_setup(NULL, FALSE);
    }

    /* Not used yet */
    other = "";

    nl->kernelptr_vf = NULL;
    nl->kernelptr_v  = NULL;
    nl->kernelptr_f  = NULL;

    elec     = gmx_nbkernel_elec_names[nl->ielec];
    elec_mod = eintmod_names[nl->ielecmod];
    vdw      = gmx_nbkernel_vdw_names[nl->ivdw];
    vdw_mod  = eintmod_names[nl->ivdwmod];
    geom     = gmx_nblist_geometry_names[nl->igeometry];

    if (nl->type == GMX_NBLIST_INTERACTION_ADRESS)
    {
        nl->kernelptr_vf       = (void *) gmx_nb_generic_adress_kernel;
        nl->kernelptr_f        = (void *) gmx_nb_generic_adress_kernel;
        nl->simd_padding_width = 1;
        return;
    }

    if (nl->type == GMX_NBLIST_INTERACTION_FREE_ENERGY)
    {
        nl->kernelptr_vf       = (void *) gmx_nb_free_energy_kernel;
        nl->kernelptr_f        = (void *) gmx_nb_free_energy_kernel;
        nl->simd_padding_width = 1;
    }
    else if (!gmx_strcasecmp_min(geom, "CG-CG"))
    {
        nl->kernelptr_vf       = (void *) gmx_nb_generic_cg_kernel;
        nl->kernelptr_f        = (void *) gmx_nb_generic_cg_kernel;
        nl->simd_padding_width = 1;
    }
    else
    {
        /* Try to find a specific kernel first */

        for (i = 0; i < narch && nl->kernelptr_vf == NULL; i++)
        {
            nl->kernelptr_vf       = (void *) nb_kernel_list_findkernel(log, arch_and_padding[i].arch, elec, elec_mod, vdw, vdw_mod, geom, other, "PotentialAndForce");
            nl->simd_padding_width = arch_and_padding[i].simd_padding_width;
        }
        for (i = 0; i < narch && nl->kernelptr_f == NULL; i++)
        {
            nl->kernelptr_f        = (void *) nb_kernel_list_findkernel(log, arch_and_padding[i].arch, elec, elec_mod, vdw, vdw_mod, geom, other, "Force");
            nl->simd_padding_width = arch_and_padding[i].simd_padding_width;

            /* If there is not force-only optimized kernel, is there a potential & force one? */
            if (nl->kernelptr_f == NULL)
            {
                nl->kernelptr_f        = (void *) nb_kernel_list_findkernel(NULL, arch_and_padding[i].arch, elec, elec_mod, vdw, vdw_mod, geom, other, "PotentialAndForce");
                nl->simd_padding_width = arch_and_padding[i].simd_padding_width;
            }
        }

        /* Give up. If this was a water kernel, leave the pointer as NULL, which
         * will disable water optimization in NS. If it is a particle kernel, set
         * the pointer to the generic NB kernel.
         */
        if (nl->kernelptr_vf == NULL && !gmx_strcasecmp_min(geom, "Particle-Particle"))
        {
            nl->kernelptr_vf       = (void *) gmx_nb_generic_kernel;
            nl->kernelptr_f        = (void *) gmx_nb_generic_kernel;
            nl->simd_padding_width = 1;
            if (debug)
            {
                fprintf(debug,
                        "WARNING - Slow generic NB kernel used for neighborlist with\n"
                        "    Elec: '%s', Modifier: '%s'\n"
                        "    Vdw:  '%s', Modifier: '%s'\n"
                        "    Geom: '%s', Other: '%s'\n\n",
                        elec, elec_mod, vdw, vdw_mod, geom, other);
            }
        }
    }

    return;
}
int gmx_rotmat(int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_rotmat[tt] plots the rotation matrix required for least squares fitting",
        "a conformation onto the reference conformation provided with",
        "[TT]-s[tt]. Translation is removed before fitting.",
        "The output are the three vectors that give the new directions",
        "of the x, y and z directions of the reference conformation,",
        "for example: (zx,zy,zz) is the orientation of the reference",
        "z-axis in the trajectory frame.",
        "[PAR]",
        "This tool is useful for, for instance,",
        "determining the orientation of a molecule",
        "at an interface, possibly on a trajectory produced with",
        "[TT]trjconv -fit rotxy+transxy[tt] to remove the rotation",
        "in the [IT]x-y[it] plane.",
        "[PAR]",
        "Option [TT]-ref[tt] determines a reference structure for fitting,",
        "instead of using the structure from [TT]-s[tt]. The structure with",
        "the lowest sum of RMSD's to all other structures is used.",
        "Since the computational cost of this procedure grows with",
        "the square of the number of frames, the [TT]-skip[tt] option",
        "can be useful. A full fit or only a fit in the [IT]x-y[it] plane can",
        "be performed.",
        "[PAR]",
        "Option [TT]-fitxy[tt] fits in the [IT]x-y[it] plane before determining",
        "the rotation matrix."
    };
    const char *reffit[] = 
        { NULL, "none", "xyz", "xy", NULL }; 
    static int  skip=1;
    static gmx_bool bFitXY=FALSE,bMW=TRUE;
    t_pargs pa[] = {
        { "-ref", FALSE, etENUM, {reffit},
          "Determine the optimal reference structure" },
        { "-skip", FALSE, etINT, {&skip},
          "Use every nr-th frame for [TT]-ref[tt]" },
        { "-fitxy", FALSE, etBOOL, {&bFitXY},
          "Fit the x/y rotation before determining the rotation" },
        { "-mw", FALSE, etBOOL, {&bMW},
          "Use mass weighted fitting" }
    };
    FILE       *out;
    t_trxstatus *status;
    t_topology top;
    int        ePBC;
    rvec       *x_ref,*x;
    matrix     box,R;
    real       t;
    int        natoms,i;
    char       *grpname,title[256];
    int        gnx;
    gmx_rmpbc_t  gpbc=NULL;
    atom_id    *index;
    output_env_t oenv;
    real       *w_rls;
    const char *leg[]  = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" }; 
#define NLEG asize(leg) 
    t_filenm fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD }, 
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efXVG, NULL,   "rotmat",   ffWRITE }
    }; 
#define NFILE asize(fnm) 
    
    CopyRight(stderr,argv[0]);
    
    parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
                      NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 
    
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x_ref,NULL,box,bMW);

    gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,box);
    
    gmx_rmpbc(gpbc,top.atoms.nr,box,x_ref);
    
    get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);

    if (reffit[0][0] != 'n')
    {
        get_refx(oenv,ftp2fn(efTRX,NFILE,fnm),reffit[0][2]=='z' ? 3 : 2,skip,
                 gnx,index,bMW,&top,ePBC,x_ref);
    }

    natoms = read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); 

    snew(w_rls,natoms);
    for(i=0; i<gnx; i++)
    {
        if (index[i] >= natoms)
        {
            gmx_fatal(FARGS,"Atom index (%d) is larger than the number of atoms in the trajecory (%d)",index[i]+1,natoms);
        }
        w_rls[index[i]] = (bMW ? top.atoms.atom[index[i]].m : 1.0);
    }

    if (reffit[0][0] == 'n')
    {
        reset_x(gnx,index,natoms,NULL,x_ref,w_rls);
    }
    
    out = xvgropen(ftp2fn(efXVG,NFILE,fnm), 
                   "Fit matrix","Time (ps)","",oenv); 
    xvgr_legend(out,NLEG,leg,oenv);
    
    do
    {
        gmx_rmpbc(gpbc,natoms,box,x);

        reset_x(gnx,index,natoms,NULL,x,w_rls);

        if (bFitXY)
        {
            do_fit_ndim(2,natoms,w_rls,x_ref,x);
        }

        calc_fit_R(DIM,natoms,w_rls,x_ref,x,R);
          
        fprintf(out,
                "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n",
                t,
                R[XX][XX],R[XX][YY],R[XX][ZZ],
                R[YY][XX],R[YY][YY],R[YY][ZZ],
                R[ZZ][XX],R[ZZ][YY],R[ZZ][ZZ]);
    }
    while(read_next_x(oenv,status,&t,natoms,x,box));

    gmx_rmpbc_done(gpbc);

    close_trj(status);
    
    ffclose(out);
    
    do_view(oenv,ftp2fn(efXVG,NFILE,fnm),"-nxy");
    
    thanx(stderr);
    
    return 0;
}
示例#11
0
int gmx_order(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes the order parameter per atom for carbon tails. For atom i the",
        "vector i-1, i+1 is used together with an axis. ",
        "The index file should contain only the groups to be used for calculations,",
        "with each group of equivalent carbons along the relevant acyl chain in its own",
        "group. There should not be any generic groups (like System, Protein) in the index",
        "file to avoid confusing the program (this is not relevant to tetrahedral order",
        "parameters however, which only work for water anyway).[PAR]",
        "[THISMODULE] can also give all",
        "diagonal elements of the order tensor and even calculate the deuterium",
        "order parameter Scd (default). If the option [TT]-szonly[tt] is given, only one",
        "order tensor component (specified by the [TT]-d[tt] option) is given and the",
        "order parameter per slice is calculated as well. If [TT]-szonly[tt] is not",
        "selected, all diagonal elements and the deuterium order parameter is",
        "given.[PAR]"
        "The tetrahedrality order parameters can be determined",
        "around an 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]",
        ""
    };

    static int         nslices       = 1;     /* nr of slices defined       */
    static gmx_bool    bSzonly       = FALSE; /* True if only Sz is wanted  */
    static gmx_bool    bUnsat        = FALSE; /* True if carbons are unsat. */
    static const char *normal_axis[] = { NULL, "z", "x", "y", NULL };
    static gmx_bool    permolecule   = FALSE; /*compute on a per-molecule basis */
    static gmx_bool    radial        = FALSE; /*compute a radial membrane normal */
    static gmx_bool    distcalc      = FALSE; /*calculate distance from a reference group */
    t_pargs            pa[]          = {
        { "-d",      FALSE, etENUM, {normal_axis},
          "Direction of the normal on the membrane" },
        { "-sl",     FALSE, etINT, {&nslices},
          "Calculate order parameter as function of box length, dividing the box"
          " into this number of slices." },
        { "-szonly", FALSE, etBOOL, {&bSzonly},
          "Only give Sz element of order tensor. (axis can be specified with [TT]-d[tt])" },
        { "-unsat",  FALSE, etBOOL, {&bUnsat},
          "Calculate order parameters for unsaturated carbons. Note that this can"
          "not be mixed with normal order parameters." },
        { "-permolecule", FALSE, etBOOL, {&permolecule},
          "Compute per-molecule Scd order parameters" },
        { "-radial", FALSE, etBOOL, {&radial},
          "Compute a radial membrane normal" },
        { "-calcdist", FALSE, etBOOL, {&distcalc},
          "Compute distance from a reference" },
    };

    rvec              *order;                         /* order par. for each atom   */
    real             **slOrder;                       /* same, per slice            */
    real               slWidth = 0.0;                 /* width of a slice           */
    char             **grpname;                       /* groupnames                 */
    int                ngrps,                         /* nr. of groups              */
                       i,
                       axis = 0;                      /* normal axis                */
    t_topology   *top;                                /* topology         */
    int           ePBC;
    atom_id      *index,                              /* indices for a              */
    *a;                                               /* atom numbers in each group */
    t_blocka     *block;                              /* data from index file       */
    t_filenm      fnm[] = {                           /* files for g_order    */
        { efTRX, "-f", NULL,  ffREAD },               /* trajectory file              */
        { efNDX, "-n", NULL,  ffREAD },               /* index file           */
        { efNDX, "-nr", NULL,  ffREAD },              /* index for radial axis calculation	  */
        { efTPX, NULL, NULL,  ffREAD },               /* topology file                */
        { efXVG, "-o", "order", ffWRITE },            /* xvgr output file     */
        { efXVG, "-od", "deuter", ffWRITE },          /* xvgr output file           */
        { efPDB, "-ob", NULL, ffWRITE },              /* write Scd as B factors to PDB if permolecule           */
        { efXVG, "-os", "sliced", ffWRITE },          /* xvgr output file           */
        { efXVG, "-Sg", "sg-ang", ffOPTWR },          /* xvgr output file           */
        { efXVG, "-Sk", "sk-dist", ffOPTWR },         /* xvgr output file           */
        { efXVG, "-Sgsl", "sg-ang-slice", ffOPTWR },  /* xvgr output file           */
        { efXVG, "-Sksl", "sk-dist-slice", ffOPTWR }, /* xvgr output file           */
    };
    gmx_bool      bSliced = FALSE;                    /* True if box is sliced      */
#define NFILE asize(fnm)
    real        **distvals = NULL;
    const char   *sgfnm, *skfnm, *ndxfnm, *tpsfnm, *trxfnm;
    output_env_t  oenv;

    if (!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))
    {
        return 0;
    }
    if (nslices < 1)
    {
        gmx_fatal(FARGS, "Can not have nslices < 1");
    }
    sgfnm  = opt2fn_null("-Sg", NFILE, fnm);
    skfnm  = opt2fn_null("-Sk", NFILE, fnm);
    ndxfnm = opt2fn_null("-n", 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 (skfnm || sgfnm)
    {
        /* If either of theoptions is set we compute both */
        sgfnm = opt2fn("-Sg", NFILE, fnm);
        skfnm = opt2fn("-Sk", NFILE, fnm);
        calc_tetra_order_parm(ndxfnm, tpsfnm, trxfnm, sgfnm, skfnm, nslices, axis,
                              opt2fn("-Sgsl", NFILE, fnm), opt2fn("-Sksl", NFILE, fnm),
                              oenv);
        /* view xvgr files */
        do_view(oenv, opt2fn("-Sg", NFILE, fnm), NULL);
        do_view(oenv, opt2fn("-Sk", NFILE, fnm), NULL);
        if (nslices > 1)
        {
            do_view(oenv, opt2fn("-Sgsl", NFILE, fnm), NULL);
            do_view(oenv, opt2fn("-Sksl", NFILE, fnm), NULL);
        }
    }
    else
    {
        /* tail order parameter */

        if (nslices > 1)
        {
            bSliced = TRUE;
            fprintf(stderr, "Dividing box in %d slices.\n\n", nslices);
        }

        if (bSzonly)
        {
            fprintf(stderr, "Only calculating Sz\n");
        }
        if (bUnsat)
        {
            fprintf(stderr, "Taking carbons as unsaturated!\n");
        }

        top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC); /* read topology file */

        block = init_index(ftp2fn(efNDX, NFILE, fnm), &grpname);
        index = block->index;                   /* get indices from t_block block */
        a     = block->a;                       /* see block.h                    */
        ngrps = block->nr;

        if (permolecule)
        {
            nslices = index[1] - index[0]; /*I think this assumes contiguous lipids in topology*/
            fprintf(stderr, "Calculating Scd order parameters for each of %d molecules\n", nslices);
        }

        if (radial)
        {
            fprintf(stderr, "Calculating radial distances\n");
            if (!permolecule)
            {
                gmx_fatal(FARGS, "Cannot yet output radial distances without permolecule\n");
            }
        }

        /* show atomtypes, to check if index file is correct */
        print_types(index, a, ngrps, grpname, top);

        calc_order(ftp2fn(efTRX, NFILE, fnm), index, a, &order,
                   &slOrder, &slWidth, nslices, bSliced, bUnsat,
                   top, ePBC, ngrps, axis, permolecule, radial, distcalc, opt2fn_null("-nr", NFILE, fnm), &distvals, oenv);

        if (radial)
        {
            ngrps--; /*don't print the last group--was used for
                               center-of-mass determination*/

        }
        order_plot(order, slOrder, opt2fn("-o", NFILE, fnm), opt2fn("-os", NFILE, fnm),
                   opt2fn("-od", NFILE, fnm), ngrps, nslices, slWidth, bSzonly, permolecule, distvals, oenv);

        if (opt2bSet("-ob", NFILE, fnm))
        {
            if (!permolecule)
            {
                fprintf(stderr,
                        "Won't write B-factors with averaged order parameters; use -permolecule\n");
            }
            else
            {
                write_bfactors(fnm, NFILE, index, a, nslices, ngrps, slOrder, top, distvals, oenv);
            }
        }


        do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);  /* view xvgr file */
        do_view(oenv, opt2fn("-os", NFILE, fnm), NULL); /* view xvgr file */
        do_view(oenv, opt2fn("-od", NFILE, fnm), NULL); /* view xvgr file */
    }

    if (distvals != NULL)
    {
        for (i = 0; i < nslices; ++i)
        {
            sfree(distvals[i]);
        }
        sfree(distvals);
    }

    return 0;
}
示例#12
0
int gmx_confrms(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the root mean square deviation (RMSD) of two",
        "structures after least-squares fitting the second structure on the first one.",
        "The two structures do NOT need to have the same number of atoms,",
        "only the two index groups used for the fit need to be identical.",
        "With [TT]-name[tt] only matching atom names from the selected groups",
        "will be used for the fit and RMSD calculation. This can be useful ",
        "when comparing mutants of a protein.",
        "[PAR]",
        "The superimposed structures are written to file. In a [TT].pdb[tt] file",
        "the two structures will be written as separate models",
        "(use [TT]rasmol -nmrpdb[tt]). Also in a [TT].pdb[tt] file, B-factors",
        "calculated from the atomic MSD values can be written with [TT]-bfac[tt].",
    };
    static gmx_bool bOne  = FALSE, bRmpbc = FALSE, bMW = TRUE, bName = FALSE,
                    bBfac = FALSE, bFit = TRUE, bLabel = FALSE;

    t_pargs  pa[] = {
        { "-one", FALSE, etBOOL, {&bOne},   "Only write the fitted structure to file" },
        { "-mw",  FALSE, etBOOL, {&bMW},    "Mass-weighted fitting and RMSD" },
        { "-pbc", FALSE, etBOOL, {&bRmpbc}, "Try to make molecules whole again" },
        { "-fit", FALSE, etBOOL, {&bFit},
          "Do least squares superposition of the target structure to the reference" },
        { "-name", FALSE, etBOOL, {&bName},
          "Only compare matching atom names" },
        { "-label", FALSE, etBOOL, {&bLabel},
          "Added chain labels A for first and B for second structure"},
        { "-bfac", FALSE, etBOOL, {&bBfac},
          "Output B-factors from atomic MSD values" }
    };
    t_filenm fnm[] = {
        { efTPS, "-f1",  "conf1.gro", ffREAD  },
        { efSTX, "-f2",  "conf2",     ffREAD  },
        { efSTO, "-o",   "fit.pdb",   ffWRITE },
        { efNDX, "-n1",  "fit1",      ffOPTRD },
        { efNDX, "-n2",  "fit2",      ffOPTRD },
        { efNDX, "-no",  "match",     ffOPTWR }
    };
#define NFILE asize(fnm)

    /* the two structure files */
    const char  *conf1file, *conf2file, *matchndxfile, *outfile;
    FILE        *fp;
    char         title1[STRLEN], title2[STRLEN], *name1, *name2;
    t_topology  *top1, *top2;
    int          ePBC1, ePBC2;
    t_atoms     *atoms1, *atoms2;
    int          warn = 0;
    atom_id      at;
    real        *w_rls, mass, totmass;
    rvec        *x1, *v1, *x2, *v2, *fit_x;
    matrix       box1, box2;

    output_env_t oenv;

    /* counters */
    int     i, j, m;

    /* center of mass calculation */
    real    tmas1, tmas2;
    rvec    xcm1, xcm2;

    /* variables for fit */
    char    *groupnames1, *groupnames2;
    int      isize1, isize2;
    atom_id *index1, *index2;
    real     rms, msd, minmsd, maxmsd;
    real    *msds;


    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }
    matchndxfile = opt2fn_null("-no", NFILE, fnm);
    conf1file    = ftp2fn(efTPS, NFILE, fnm);
    conf2file    = ftp2fn(efSTX, NFILE, fnm);

    /* reading reference structure from first structure file */
    fprintf(stderr, "\nReading first structure file\n");
    snew(top1, 1);
    read_tps_conf(conf1file, title1, top1, &ePBC1, &x1, &v1, box1, TRUE);
    atoms1 = &(top1->atoms);
    fprintf(stderr, "%s\nContaining %d atoms in %d residues\n",
            title1, atoms1->nr, atoms1->nres);

    if (bRmpbc)
    {
        rm_gropbc(atoms1, x1, box1);
    }

    fprintf(stderr, "Select group from first structure\n");
    get_index(atoms1, opt2fn_null("-n1", NFILE, fnm),
              1, &isize1, &index1, &groupnames1);
    printf("\n");

    if (bFit && (isize1 < 3))
    {
        gmx_fatal(FARGS, "Need >= 3 points to fit!\n");
    }

    /* reading second structure file */
    fprintf(stderr, "\nReading second structure file\n");
    snew(top2, 1);
    read_tps_conf(conf2file, title2, top2, &ePBC2, &x2, &v2, box2, TRUE);
    atoms2 = &(top2->atoms);
    fprintf(stderr, "%s\nContaining %d atoms in %d residues\n",
            title2, atoms2->nr, atoms2->nres);

    if (bRmpbc)
    {
        rm_gropbc(atoms2, x2, box2);
    }

    fprintf(stderr, "Select group from second structure\n");
    get_index(atoms2, opt2fn_null("-n2", NFILE, fnm),
              1, &isize2, &index2, &groupnames2);

    if (bName)
    {
        find_matching_names(&isize1, index1, atoms1, &isize2, index2, atoms2);
        if (matchndxfile)
        {
            fp = gmx_ffopen(matchndxfile, "w");
            fprintf(fp, "; Matching atoms between %s from %s and %s from %s\n",
                    groupnames1, conf1file, groupnames2, conf2file);
            fprintf(fp, "[ Match_%s_%s ]\n", conf1file, groupnames1);
            for (i = 0; i < isize1; i++)
            {
                fprintf(fp, "%4d%s", index1[i]+1, (i%15 == 14 || i == isize1-1) ? "\n" : " ");
            }
            fprintf(fp, "[ Match_%s_%s ]\n", conf2file, groupnames2);
            for (i = 0; i < isize2; i++)
            {
                fprintf(fp, "%4d%s", index2[i]+1, (i%15 == 14 || i == isize2-1) ? "\n" : " ");
            }
        }
    }

    /* check isizes, must be equal */
    if (isize2 != isize1)
    {
        gmx_fatal(FARGS, "You selected groups with differen number of atoms.\n");
    }

    for (i = 0; i < isize1; i++)
    {
        name1 = *atoms1->atomname[index1[i]];
        name2 = *atoms2->atomname[index2[i]];
        if (strcmp(name1, name2))
        {
            if (warn < 20)
            {
                fprintf(stderr,
                        "Warning: atomnames at index %d don't match: %d %s, %d %s\n",
                        i+1, index1[i]+1, name1, index2[i]+1, name2);
            }
            warn++;
        }
        if (!bMW)
        {
            atoms1->atom[index1[i]].m = 1;
            atoms2->atom[index2[i]].m = 1;
        }
    }
    if (warn)
    {
        fprintf(stderr, "%d atomname%s did not match\n", warn, (warn == 1) ? "" : "s");
    }

    if (bFit)
    {
        /* calculate and remove center of mass of structures */
        calc_rm_cm(isize1, index1, atoms1, x1, xcm1);
        calc_rm_cm(isize2, index2, atoms2, x2, xcm2);

        snew(w_rls, atoms2->nr);
        snew(fit_x, atoms2->nr);
        for (at = 0; (at < isize1); at++)
        {
            w_rls[index2[at]] = atoms1->atom[index1[at]].m;
            copy_rvec(x1[index1[at]], fit_x[index2[at]]);
        }

        /* do the least squares fit to the reference structure */
        do_fit(atoms2->nr, w_rls, fit_x, x2);

        sfree(fit_x);
        sfree(w_rls);
        w_rls = NULL;
    }
    else
    {
        clear_rvec(xcm1);
        clear_rvec(xcm2);
        w_rls = NULL;
    }

    /* calculate the rms deviation */
    rms     = 0;
    totmass = 0;
    maxmsd  = -1e18;
    minmsd  =  1e18;
    snew(msds, isize1);
    for (at = 0; at < isize1; at++)
    {
        mass = atoms1->atom[index1[at]].m;
        for (m = 0; m < DIM; m++)
        {
            msd       = sqr(x1[index1[at]][m] - x2[index2[at]][m]);
            rms      += msd*mass;
            msds[at] += msd;
        }
        maxmsd   = max(maxmsd, msds[at]);
        minmsd   = min(minmsd, msds[at]);
        totmass += mass;
    }
    rms = sqrt(rms/totmass);

    printf("Root mean square deviation after lsq fit = %g nm\n", rms);
    if (bBfac)
    {
        printf("Atomic MSD's range from %g to %g nm^2\n", minmsd, maxmsd);
    }

    if (bFit)
    {
        /* reset coordinates of reference and fitted structure */
        for (i = 0; i < atoms1->nr; i++)
        {
            for (m = 0; m < DIM; m++)
            {
                x1[i][m] += xcm1[m];
            }
        }
        for (i = 0; i < atoms2->nr; i++)
        {
            for (m = 0; m < DIM; m++)
            {
                x2[i][m] += xcm1[m];
            }
        }
    }

    outfile = ftp2fn(efSTO, NFILE, fnm);
    switch (fn2ftp(outfile))
    {
        case efPDB:
        case efBRK:
        case efENT:
            if (bBfac || bLabel)
            {
                srenew(atoms1->pdbinfo, atoms1->nr);
                srenew(atoms1->atom, atoms1->nr); /* Why renew atom? */

                /* Avoid segfaults when writing the pdb-file */
                for (i = 0; i < atoms1->nr; i++)
                {
                    atoms1->pdbinfo[i].type         = eptAtom;
                    atoms1->pdbinfo[i].occup        = 1.00;
                    atoms1->pdbinfo[i].bAnisotropic = FALSE;
                    if (bBfac)
                    {
                        atoms1->pdbinfo[i].bfac = 0;
                    }
                    if (bLabel)
                    {
                        atoms1->resinfo[atoms1->atom[i].resind].chainid = 'A';
                    }
                }

                for (i = 0; i < isize1; i++)
                {
                    /* atoms1->pdbinfo[index1[i]].type = eptAtom; */
/*  atoms1->pdbinfo[index1[i]].bAnisotropic = FALSE; */
                    if (bBfac)
                    {
                        atoms1->pdbinfo[index1[i]].bfac = (800*M_PI*M_PI/3.0)*msds[i];
                    }
/*  if (bLabel) */
/*    atoms1->resinfo[atoms1->atom[index1[i]].resind].chain = 'A'; */
                }
                srenew(atoms2->pdbinfo, atoms2->nr);
                srenew(atoms2->atom, atoms2->nr); /* Why renew atom? */

                for (i = 0; i < atoms2->nr; i++)
                {
                    atoms2->pdbinfo[i].type         = eptAtom;
                    atoms2->pdbinfo[i].occup        = 1.00;
                    atoms2->pdbinfo[i].bAnisotropic = FALSE;
                    if (bBfac)
                    {
                        atoms2->pdbinfo[i].bfac = 0;
                    }
                    if (bLabel)
                    {
                        atoms2->resinfo[atoms1->atom[i].resind].chainid = 'B';
                    }
                }

                for (i = 0; i < isize2; i++)
                {
                    /* atoms2->pdbinfo[index2[i]].type = eptAtom; */
/*  atoms2->pdbinfo[index2[i]].bAnisotropic = FALSE; */
                    if (bBfac)
                    {
                        atoms2->pdbinfo[index2[i]].bfac = (800*M_PI*M_PI/3.0)*msds[i];
                    }
/*  if (bLabel) */
/*    atoms2->resinfo[atoms2->atom[index2[i]].resind].chain = 'B'; */
                }
            }
            fp = gmx_ffopen(outfile, "w");
            if (!bOne)
            {
                write_pdbfile(fp, title1, atoms1, x1, ePBC1, box1, ' ', 1, NULL, TRUE);
            }
            write_pdbfile(fp, title2, atoms2, x2, ePBC2, box2, ' ', bOne ? -1 : 2, NULL, TRUE);
            gmx_ffclose(fp);
            break;
        case efGRO:
            if (bBfac)
            {
                fprintf(stderr, "WARNING: cannot write B-factor values to gro file\n");
            }
            fp = gmx_ffopen(outfile, "w");
            if (!bOne)
            {
                write_hconf_p(fp, title1, atoms1, 3, x1, v1, box1);
            }
            write_hconf_p(fp, title2, atoms2, 3, x2, v2, box2);
            gmx_ffclose(fp);
            break;
        default:
            if (bBfac)
            {
                fprintf(stderr, "WARNING: cannot write B-factor values to %s file\n",
                        ftp2ext(fn2ftp(outfile)));
            }
            if (!bOne)
            {
                fprintf(stderr,
                        "WARNING: cannot write the reference structure to %s file\n",
                        ftp2ext(fn2ftp(outfile)));
            }
            write_sto_conf(outfile, title2, atoms2, x2, v2, ePBC2, box2);
            break;
    }

    view_all(oenv, NFILE, fnm);

    return 0;
}
示例#13
0
int gmx_make_ndx(int argc, char *argv[])
{
    const char     *desc[] = {
        "Index groups are necessary for almost every GROMACS program.",
        "All these programs can generate default index groups. You ONLY",
        "have to use [THISMODULE] when you need SPECIAL index groups.",
        "There is a default index group for the whole system, 9 default",
        "index groups for proteins, and a default index group",
        "is generated for every other residue name.",
        "",
        "When no index file is supplied, also [THISMODULE] will generate the",
        "default groups.",
        "With the index editor you can select on atom, residue and chain names",
        "and numbers.",
        "When a run input file is supplied you can also select on atom type.",
        "You can use boolean operations, you can split groups",
        "into chains, residues or atoms. You can delete and rename groups.",
        "Type 'h' in the editor for more details.",
        "",
        "The atom numbering in the editor and the index file starts at 1.",
        "",
        "The [TT]-twin[tt] switch duplicates all index groups with an offset of",
        "[TT]-natoms[tt], which is useful for Computational Electrophysiology",
        "double-layer membrane setups.",
        "",
        "See also [gmx-select] [TT]-on[tt], which provides an alternative way",
        "for constructing index groups.  It covers nearly all of [THISMODULE]",
        "functionality, and in many cases much more."
    };

    static int      natoms     = 0;
    static gmx_bool bVerbose   = FALSE;
    static gmx_bool bDuplicate = FALSE;
    t_pargs         pa[]       = {
        { "-natoms",  FALSE, etINT, {&natoms},
          "set number of atoms (default: read from coordinate or index file)" },
        { "-twin",     FALSE, etBOOL, {&bDuplicate},
          "Duplicate all index groups with an offset of -natoms" },
        { "-verbose", FALSE, etBOOL, {&bVerbose},
          "HIDDENVerbose output" }
    };
#define NPA asize(pa)

    gmx_output_env_t *oenv;
    int               nndxin;
    const char       *stxfile;
    char            **ndxinfiles;
    const char       *ndxoutfile;
    gmx_bool          bNatoms;
    int               i, j;
    t_atoms          *atoms;
    rvec             *x, *v;
    int               ePBC;
    matrix            box;
    t_blocka         *block, *block2;
    char            **gnames, **gnames2;
    t_filenm          fnm[] = {
        { efSTX, "-f", nullptr,     ffOPTRD  },
        { efNDX, "-n", nullptr,     ffOPTRDMULT },
        { efNDX, "-o", nullptr,     ffWRITE }
    };
#define NFILE asize(fnm)

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

    stxfile = ftp2fn_null(efSTX, NFILE, fnm);
    if (opt2bSet("-n", NFILE, fnm))
    {
        nndxin = opt2fns(&ndxinfiles, "-n", NFILE, fnm);
    }
    else
    {
        nndxin = 0;
    }
    ndxoutfile = opt2fn("-o", NFILE, fnm);
    bNatoms    = opt2parg_bSet("-natoms", NPA, pa);

    if (!stxfile && !nndxin)
    {
        gmx_fatal(FARGS, "No input files (structure or index)");
    }

    if (stxfile)
    {
        t_topology *top;
        snew(top, 1);
        fprintf(stderr, "\nReading structure file\n");
        read_tps_conf(stxfile, top, &ePBC, &x, &v, box, FALSE);
        atoms = &top->atoms;
        if (atoms->pdbinfo == nullptr)
        {
            snew(atoms->pdbinfo, atoms->nr);
        }
        natoms  = atoms->nr;
        bNatoms = TRUE;
    }
    else
    {
        atoms = nullptr;
        x     = nullptr;
    }

    /* read input file(s) */
    block  = new_blocka();
    gnames = nullptr;
    printf("Going to read %d old index file(s)\n", nndxin);
    if (nndxin)
    {
        for (i = 0; i < nndxin; i++)
        {
            block2 = init_index(ndxinfiles[i], &gnames2);
            srenew(gnames, block->nr+block2->nr);
            for (j = 0; j < block2->nr; j++)
            {
                gnames[block->nr+j] = gnames2[j];
            }
            sfree(gnames2);
            merge_blocks(block, block2);
            sfree(block2->a);
            sfree(block2->index);
/*       done_block(block2); */
            sfree(block2);
        }
    }
    else
    {
        snew(gnames, 1);
        analyse(atoms, block, &gnames, FALSE, TRUE);
    }

    if (!bNatoms)
    {
        natoms = block2natoms(block);
        printf("Counted atom numbers up to %d in index file\n", natoms);
    }

    edit_index(natoms, atoms, x, block, &gnames, bVerbose);

    write_index(ndxoutfile, block, gnames, bDuplicate, natoms);

    return 0;
}
示例#14
0
int gmx_rotacf(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_rotacf[tt] calculates the rotational correlation function",
        "for molecules. Atom triplets (i,j,k) must be given in the index",
        "file, defining two vectors ij and jk. The rotational ACF",
        "is calculated as the autocorrelation function of the vector",
        "n = ij x jk, i.e. the cross product of the two vectors.",
        "Since three atoms span a plane, the order of the three atoms",
        "does not matter. Optionally, by invoking the [TT]-d[tt] switch, you can",
        "calculate the rotational correlation function for linear molecules",
        "by specifying atom pairs (i,j) in the index file.",
        "[PAR]",
        "EXAMPLES[PAR]",
        "[TT]g_rotacf -P 1 -nparm 2 -fft -n index -o rotacf-x-P1",
        "-fa expfit-x-P1 -beginfit 2.5 -endfit 20.0[tt][PAR]",
        "This will calculate the rotational correlation function using a first",
        "order Legendre polynomial of the angle of a vector defined by the index",
        "file. The correlation function will be fitted from 2.5 ps until 20.0 ps",
        "to a two-parameter exponential."
    };
    static gmx_bool bVec    = FALSE, bAver = TRUE;

    t_pargs         pa[] = {
        { "-d",   FALSE, etBOOL, {&bVec},
          "Use index doublets (vectors) for correlation function instead of triplets (planes)" },
        { "-aver", FALSE, etBOOL, {&bAver},
          "Average over molecules" }
    };

    t_trxstatus    *status;
    int             isize;
    atom_id        *index;
    char           *grpname;
    rvec           *x, *x_s;
    matrix          box;
    real          **c1;
    rvec            xij, xjk, n;
    int             i, m, teller, n_alloc, natoms, nvec, ai, aj, ak;
    unsigned long   mode;
    real            t, t0, t1, dt;
    gmx_rmpbc_t     gpbc = NULL;
    t_topology     *top;
    int             ePBC;
    t_filenm        fnm[] = {
        { efTRX, "-f", NULL,  ffREAD  },
        { efTPX, NULL, NULL,  ffREAD },
        { efNDX, NULL, NULL,  ffREAD  },
        { efXVG, "-o", "rotacf",  ffWRITE }
    };
#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, 0, NULL, &oenv);

    rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    if (bVec)
    {
        nvec = isize/2;
    }
    else
    {
        nvec = isize/3;
    }

    if (((isize % 3) != 0) && !bVec)
    {
        gmx_fatal(FARGS, "number of index elements not multiple of 3, "
                  "these can not be atom triplets\n");
    }
    if (((isize % 2) != 0) && bVec)
    {
        gmx_fatal(FARGS, "number of index elements not multiple of 2, "
                  "these can not be atom doublets\n");
    }

    top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC);

    snew(c1, nvec);
    for (i = 0; (i < nvec); i++)
    {
        c1[i] = NULL;
    }
    n_alloc = 0;

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    snew(x_s, natoms);

    gpbc = gmx_rmpbc_init(&(top->idef), ePBC, natoms, box);

    /* Start the loop over frames */
    t1      = t0 = t;
    teller  = 0;
    do
    {
        if (teller >= n_alloc)
        {
            n_alloc += 100;
            for (i = 0; (i < nvec); i++)
            {
                srenew(c1[i], DIM*n_alloc);
            }
        }
        t1 = t;

        /* Remove periodicity */
        gmx_rmpbc_copy(gpbc, natoms, box, x, x_s);

        /* Compute crossproducts for all vectors, if triplets.
         * else, just get the vectors in case of doublets.
         */
        if (bVec == FALSE)
        {
            for (i = 0; (i < nvec); i++)
            {
                ai = index[3*i];
                aj = index[3*i+1];
                ak = index[3*i+2];
                rvec_sub(x_s[ai], x_s[aj], xij);
                rvec_sub(x_s[aj], x_s[ak], xjk);
                cprod(xij, xjk, n);
                for (m = 0; (m < DIM); m++)
                {
                    c1[i][DIM*teller+m] = n[m];
                }
            }
        }
        else
        {
            for (i = 0; (i < nvec); i++)
            {
                ai = index[2*i];
                aj = index[2*i+1];
                rvec_sub(x_s[ai], x_s[aj], n);
                for (m = 0; (m < DIM); m++)
                {
                    c1[i][DIM*teller+m] = n[m];
                }
            }
        }
        /* Increment loop counter */
        teller++;
    }
    while (read_next_x(oenv, status, &t, natoms, x, box));
    close_trj(status);
    fprintf(stderr, "\nDone with trajectory\n");

    gmx_rmpbc_done(gpbc);


    /* Autocorrelation function */
    if (teller < 2)
    {
        fprintf(stderr, "Not enough frames for correlation function\n");
    }
    else
    {
        dt = (t1 - t0)/(teller-1);

        mode = eacVector;

        do_autocorr(ftp2fn(efXVG, NFILE, fnm), oenv, "Rotational Correlation Function",
                    teller, nvec, c1, dt, mode, bAver);
    }

    do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL);

    thanx(stderr);

    return 0;
}
int gmx_kinetics(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_kinetics[tt] reads two [TT].xvg[tt] files, each one containing data for N replicas.",
    "The first file contains the temperature of each replica at each timestep,",
    "and the second contains real values that can be interpreted as",
    "an indicator for folding. If the value in the file is larger than",
    "the cutoff it is taken to be unfolded and the other way around.[PAR]",
    "From these data an estimate of the forward and backward rate constants",
    "for folding is made at a reference temperature. In addition,",
    "a theoretical melting curve and free energy as a function of temperature",
    "are printed in an [TT].xvg[tt] file.[PAR]",
    "The user can give a max value to be regarded as intermediate",
    "([TT]-ucut[tt]), which, when given will trigger the use of an intermediate state",
    "in the algorithm to be defined as those structures that have",
    "cutoff < DATA < ucut. Structures with DATA values larger than ucut will",
    "not be regarded as potential folders. In this case 8 parameters are optimized.[PAR]",
    "The average fraction foled is printed in an [TT].xvg[tt] file together with the fit to it.", 
    "If an intermediate is used a further file will show the build of the intermediate and the fit to that process.[PAR]",
    "The program can also be used with continuous variables (by setting",
    "[TT]-nodiscrete[tt]). In this case kinetics of other processes can be",
    "studied. This is very much a work in progress and hence the manual",
    "(this information) is lagging behind somewhat.[PAR]",
    "In order to compile this program you need access to the GNU",
    "scientific library."
  };
  static int  nreplica  = 1;
  static real tref      = 298.15;
  static real cutoff    = 0.2;
  static real ucut      = 0.0;
  static real Euf       = 10;
  static real Efu       = 30;
  static real Ei        = 10;
  static gmx_bool bHaveT    = TRUE;
  static real t0        = -1;
  static real t1        = -1;
  static real tb        = 0;
  static real te        = 0;
  static real tol       = 1e-3;
  static int  maxiter   = 100;
  static int  skip      = 0;
  static int  nmult     = 1;
  static gmx_bool bBack     = TRUE;
  static gmx_bool bSplit    = TRUE;
  static gmx_bool bSum      = TRUE;
  static gmx_bool bDiscrete = TRUE;
  t_pargs pa[] = {
    { "-time",    FALSE, etBOOL, {&bHaveT},
      "Expect a time in the input" },
    { "-b",       FALSE, etREAL, {&tb},
      "First time to read from set" },
    { "-e",       FALSE, etREAL, {&te},
      "Last time to read from set" },
    { "-bfit",    FALSE, etREAL, {&t0},
      "Time to start the fit from" },
    { "-efit",    FALSE, etREAL, {&t1},
      "Time to end the fit" },
    { "-T",       FALSE, etREAL, {&tref},
      "Reference temperature for computing rate constants" },
    { "-n",       FALSE, etINT, {&nreplica},
      "Read data for # replicas. Only necessary when files are written in xmgrace format using @type and & as delimiters." },
    { "-cut",     FALSE, etREAL, {&cutoff},
      "Cut-off (max) value for regarding a structure as folded" },
    { "-ucut",    FALSE, etREAL, {&ucut},
      "Cut-off (max) value for regarding a structure as intermediate (if not folded)" },
    { "-euf",     FALSE, etREAL, {&Euf},
      "Initial guess for energy of activation for folding (kJ/mol)" },
    { "-efu",     FALSE, etREAL, {&Efu},
      "Initial guess for energy of activation for unfolding (kJ/mol)" },
    { "-ei",      FALSE, etREAL, {&Ei},
      "Initial guess for energy of activation for intermediates (kJ/mol)" },
    { "-maxiter", FALSE, etINT, {&maxiter},
      "Max number of iterations" },
    { "-back",    FALSE, etBOOL, {&bBack},
      "Take the back reaction into account" },
    { "-tol",     FALSE, etREAL,{&tol},
      "Absolute tolerance for convergence of the Nelder and Mead simplex algorithm" },
    { "-skip",    FALSE, etINT, {&skip},
      "Skip points in the output [TT].xvg[tt] file" },
    { "-split",   FALSE, etBOOL,{&bSplit},
      "Estimate error by splitting the number of replicas in two and refitting" },
    { "-sum",     FALSE, etBOOL,{&bSum},
      "Average folding before computing [GRK]chi[grk]^2" },
    { "-discrete", FALSE, etBOOL, {&bDiscrete},
      "Use a discrete folding criterion (F <-> U) or a continuous one" },
    { "-mult",    FALSE, etINT, {&nmult},
      "Factor to multiply the data with before discretization" }
  };
#define NPA asize(pa)

  FILE        *fp;
  real        dt_t,dt_d,dt_d2;
  int         nset_t,nset_d,nset_d2,n_t,n_d,n_d2,i;
  const char  *tfile,*dfile,*dfile2;
  t_remd_data remd; 
  output_env_t oenv; 
  
  t_filenm fnm[] = { 
    { efXVG, "-f",    "temp",    ffREAD   },
    { efXVG, "-d",    "data",    ffREAD   },
    { efXVG, "-d2",   "data2",   ffOPTRD  },
    { efXVG, "-o",    "ft_all",  ffWRITE  },
    { efXVG, "-o2",   "it_all",  ffOPTWR  },
    { efXVG, "-o3",   "ft_repl", ffOPTWR  },
    { efXVG, "-ee",   "err_est", ffOPTWR  },
    { efLOG, "-g",    "remd",    ffWRITE  },
    { efXVG, "-m",    "melt",    ffWRITE  }
  }; 
#define NFILE asize(fnm) 

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

  please_cite(stdout,"Spoel2006d");
  if (cutoff < 0)
    gmx_fatal(FARGS,"cutoff should be >= 0 (rather than %f)",cutoff);

  tfile   = opt2fn("-f",NFILE,fnm);
  dfile   = opt2fn("-d",NFILE,fnm);
  dfile2  = opt2fn_null("-d2",NFILE,fnm);
  
  fp = ffopen(opt2fn("-g",NFILE,fnm),"w");
  
  remd.temp = read_xvg_time(tfile,bHaveT,
			    opt2parg_bSet("-b",NPA,pa),tb,
			    opt2parg_bSet("-e",NPA,pa),te,
			    nreplica,&nset_t,&n_t,&dt_t,&remd.time);
  printf("Read %d sets of %d points in %s, dt = %g\n\n",nset_t,n_t,tfile,dt_t);
  sfree(remd.time);
  
  remd.data = read_xvg_time(dfile,bHaveT,
			    opt2parg_bSet("-b",NPA,pa),tb,
			    opt2parg_bSet("-e",NPA,pa),te,
			    nreplica,&nset_d,&n_d,&dt_d,&remd.time);
  printf("Read %d sets of %d points in %s, dt = %g\n\n",nset_d,n_d,dfile,dt_d);

  if ((nset_t != nset_d) || (n_t != n_d) || (dt_t != dt_d))
    gmx_fatal(FARGS,"Files %s and %s are inconsistent. Check log file",
	      tfile,dfile);

  if (dfile2) {
    remd.data2 = read_xvg_time(dfile2,bHaveT,
			       opt2parg_bSet("-b",NPA,pa),tb,
			       opt2parg_bSet("-e",NPA,pa),te,
			       nreplica,&nset_d2,&n_d2,&dt_d2,&remd.time);
    printf("Read %d sets of %d points in %s, dt = %g\n\n",
	   nset_d2,n_d2,dfile2,dt_d2);
    if ((nset_d2 != nset_d) || (n_d != n_d2) || (dt_d != dt_d2))
      gmx_fatal(FARGS,"Files %s and %s are inconsistent. Check log file",
		dfile,dfile2);
  }
  else {
    remd.data2 = NULL;
  }
  
  remd.nreplica  = nset_d;
  remd.nframe    = n_d;
  remd.dt        = 1;
  preprocess_remd(fp,&remd,cutoff,tref,ucut,bBack,Euf,Efu,Ei,t0,t1,
		  bSum,bDiscrete,nmult);
  
  optimize_remd_parameters(fp,&remd,maxiter,tol);
  
  dump_remd_parameters(fp,&remd,opt2fn("-o",NFILE,fnm),
		       opt2fn_null("-o2",NFILE,fnm),
		       opt2fn_null("-o3",NFILE,fnm),
		       opt2fn_null("-ee",NFILE,fnm),
		       opt2fn("-m",NFILE,fnm),skip,tref,oenv);

  if (bSplit) {
    printf("Splitting set of replicas in two halves\n");
    for(i=0; (i<remd.nreplica); i++) 
      remd.bMask[i] = FALSE;
    remd.nmask = 0;
    for(i=0; (i<remd.nreplica); i+=2) {
      remd.bMask[i] = TRUE;
      remd.nmask++;
    }
    sum_ft(&remd);
    optimize_remd_parameters(fp,&remd,maxiter,tol);
    dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
    
    for(i=0; (i<remd.nreplica); i++) 
      remd.bMask[i] = !remd.bMask[i];
    remd.nmask = remd.nreplica - remd.nmask;
    
    sum_ft(&remd);
    optimize_remd_parameters(fp,&remd,maxiter,tol);
    dump_remd_parameters(fp,&remd,"test2.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
    
    for(i=0; (i<remd.nreplica); i++) 
      remd.bMask[i] = FALSE;
    remd.nmask = 0;
    for(i=0; (i<remd.nreplica/2); i++) {
      remd.bMask[i] = TRUE;
      remd.nmask++;
    }
    sum_ft(&remd);
    optimize_remd_parameters(fp,&remd,maxiter,tol);
    dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
    
    for(i=0; (i<remd.nreplica); i++) 
      remd.bMask[i] = FALSE;
    remd.nmask = 0;
    for(i=remd.nreplica/2; (i<remd.nreplica); i++) {
      remd.bMask[i] = TRUE;
      remd.nmask++;
    }
    sum_ft(&remd);
    optimize_remd_parameters(fp,&remd,maxiter,tol);
    dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
  }
  ffclose(fp);
  
  view_all(oenv, NFILE, fnm);
  
  thanx(stderr);
  
  return 0;
}
示例#16
0
int gmx_wheel(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_wheel[tt] 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;

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

    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, r0, rot0, title);
    }

    thanx(stderr);

    return 0;
}
示例#17
0
int gmx_rdf(int argc,char *argv[])
{
  static char *desc[] = {
    "The structure of liquids can be studied by either neutron or X-ray",
    "scattering. The most common way to describe liquid structure is by a",
    "radial distribution function. However, this is not easy to obtain from",
    "a scattering experiment.[PAR]",
    "g_rdf calculates radial distribution functions in different ways.",
    "The normal method is around a (set of) particle(s), the other method",
    "is around the center of mass of a set of particles.",
    "With both methods rdf's can also be calculated around axes parallel",
    "to the z-axis with option [TT]-xy[tt].[PAR]",
    "The option [TT]-rdf[tt] sets the type of rdf to be computed.",
    "Default is for atoms or particles, but one can also select center",
    "of mass or geometry of molecules or residues. In all cases only",
    "the atoms in the index groups are taken into account.",
    "For molecules and/or the center of mass option a run input file",
    "is required.",
    "Other weighting than COM or COG can currently only be achieved",
    "by providing a run input file with different masses.",
    "Option [TT]-com[tt] also works in conjunction with [TT]-rdf[tt].[PAR]"
    "If a run input file is supplied ([TT]-s[tt]) and [TT]-rdf[tt] is set",
    "to [TT]atom[tt], exclusions defined",
    "in that file are taken into account when calculating the rdf.",
    "The option [TT]-cut[tt] is meant as an alternative way to avoid",
    "intramolecular peaks in the rdf plot.",
    "It is however better to supply a run input file with a higher number of",
    "exclusions. For eg. benzene a topology with nrexcl set to 5",
    "would eliminate all intramolecular contributions to the rdf.",
    "Note that all atoms in the selected groups are used, also the ones",
    "that don't have Lennard-Jones interactions.[PAR]",
    "Option [TT]-cn[tt] produces the cumulative number rdf,",
    "i.e. the average number of particles within a distance r.[PAR]",
    "To bridge the gap between theory and experiment structure factors can",
    "be computed (option [TT]-sq[tt]). The algorithm uses FFT, the grid"
    "spacing of which is determined by option [TT]-grid[tt]."
  };
  static bool bCM=FALSE,bXY=FALSE,bPBC=TRUE,bNormalize=TRUE;
  static real cutoff=0,binwidth=0.002,grid=0.05,fade=0.0,lambda=0.1,distance=10;
  static int  npixel=256,nlevel=20,ngroups=1;
  static real start_q=0.0, end_q=60.0, energy=12.0;

  static char *rdft[]={ NULL, "atom", "mol_com", "mol_cog", "res_com", "res_cog", NULL };

  t_pargs pa[] = {
    { "-bin",      FALSE, etREAL, {&binwidth},
      "Binwidth (nm)" },
    { "-com",      FALSE, etBOOL, {&bCM},
      "RDF with respect to the center of mass of first group" },
    { "-rdf",   FALSE, etENUM, {rdft}, 
      "RDF type" },
    { "-pbc",      FALSE, etBOOL, {&bPBC},
      "Use periodic boundary conditions for computing distances. Without PBC the maximum range will be three times the larges box edge." },
    { "-norm",     FALSE, etBOOL, {&bNormalize},
      "Normalize for volume and density" },
    { "-xy",       FALSE, etBOOL, {&bXY},
      "Use only the x and y components of the distance" },
    { "-cut",      FALSE, etREAL, {&cutoff},
      "Shortest distance (nm) to be considered"},
    { "-ng",       FALSE, etINT, {&ngroups},
      "Number of secondary groups to compute RDFs around a central group" },
    { "-fade",     FALSE, etREAL, {&fade},
      "From this distance onwards the RDF is tranformed by g'(r) = 1 + [g(r)-1] exp(-(r/fade-1)^2 to make it go to 1 smoothly. If fade is 0.0 nothing is done." },
    { "-grid",     FALSE, etREAL, {&grid},
      "[HIDDEN]Grid spacing (in nm) for FFTs when computing structure factors" },
    { "-npixel",   FALSE, etINT,  {&npixel},
      "[HIDDEN]# pixels per edge of the square detector plate" },
    { "-nlevel",   FALSE, etINT,  {&nlevel},
      "Number of different colors in the diffraction image" },
    { "-distance", FALSE, etREAL, {&distance},
      "[HIDDEN]Distance (in cm) from the sample to the detector" },
    { "-wave",     FALSE, etREAL, {&lambda},
      "[HIDDEN]Wavelength for X-rays/Neutrons for scattering. 0.1 nm corresponds to roughly 12 keV" },
    
    {"-startq", FALSE, etREAL, {&start_q},
     "Starting q (1/nm) "},
    {"-endq", FALSE, etREAL, {&end_q},
     "Ending q (1/nm)"},
    {"-energy", FALSE, etREAL, {&energy},
     "Energy of the incoming X-ray (keV) "}
  };
#define NPA asize(pa)
  char       *fnTPS,*fnNDX;
  bool       bSQ,bRDF;
  
  t_filenm   fnm[] = {
    { efTRX, "-f",  NULL,     ffREAD },
    { efTPS, NULL,  NULL,     ffOPTRD },
    { efNDX, NULL,  NULL,     ffOPTRD },
    { efXVG, "-o",  "rdf",    ffOPTWR },
    { efXVG, "-sq", "sq",     ffOPTWR },
    { efXVG, "-cn", "rdf_cn", ffOPTWR },
    { efXVG, "-hq", "hq",     ffOPTWR },
/*    { efXPM, "-image", "sq",  ffOPTWR }*/
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL);

  bSQ   = opt2bSet("-sq",NFILE,fnm);
  bRDF  = opt2bSet("-o",NFILE,fnm) || !bSQ;
  if (bSQ || bCM || rdft[0][0]=='m' || rdft[0][6]=='m') {
    fnTPS = ftp2fn(efTPS,NFILE,fnm);
  } else {
    fnTPS = ftp2fn_null(efTPS,NFILE,fnm);
  }
  fnNDX = ftp2fn_null(efNDX,NFILE,fnm);

  if (!bSQ && (!fnTPS && !fnNDX))
    gmx_fatal(FARGS,"Neither index file nor topology file specified\n"
	      "Nothing to do!");
 
  if  (bSQ) 
   do_scattering_intensity(fnTPS,fnNDX,opt2fn("-sq",NFILE,fnm),ftp2fn(efTRX,NFILE,fnm),
		           start_q, end_q, energy, ngroups  );

  if (bRDF) 
    do_rdf(fnNDX,fnTPS,ftp2fn(efTRX,NFILE,fnm),
	   opt2fn("-o",NFILE,fnm),opt2fn_null("-cn",NFILE,fnm),
	   opt2fn_null("-hq",NFILE,fnm),
	   bCM,rdft,bXY,bPBC,bNormalize,cutoff,binwidth,fade,ngroups);

  thanx(stderr);
  
  return 0;
}
示例#18
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 [TT].xpm[tt] file.",
        "The total number of clusters is written to an [TT].xvg[tt] 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 [TT].xvg[tt] 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 };

    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 [TT].tpr[tt] 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 [TT].xpm[tt] 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;
    gmx_bool        bSQ, bRDF;
    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 | PCA_BE_NICE,
                           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;
}
示例#19
0
int gmx_genion(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] randomly replaces solvent molecules with monoatomic ions.",
        "The group of solvent molecules should be continuous and all molecules",
        "should have the same number of atoms.",
        "The user should add the ion molecules to the topology file or use",
        "the [TT]-p[tt] option to automatically modify the topology.[PAR]",
        "The ion molecule type, residue and atom names in all force fields",
        "are the capitalized element names without sign. This molecule name",
        "should be given with [TT]-pname[tt] or [TT]-nname[tt], and the",
        "[TT][molecules][tt] section of your topology updated accordingly,",
        "either by hand or with [TT]-p[tt]. Do not use an atom name instead!",
        "[PAR]Ions which can have multiple charge states get the multiplicity",
        "added, without sign, for the uncommon states only.[PAR]",
        "For larger ions, e.g. sulfate we recommended using [gmx-insert-molecules]."
    };
    const char        *bugs[] = {
        "If you specify a salt concentration existing ions are not taken into "
        "account. In effect you therefore specify the amount of salt to be added.",
    };
    static int         p_num    = 0, n_num = 0, p_q = 1, n_q = -1;
    static const char *p_name   = "NA", *n_name = "CL";
    static real        rmin     = 0.6, conc = 0;
    static int         seed     = 1993;
    static gmx_bool    bNeutral = FALSE;
    static t_pargs     pa[]     = {
        { "-np",    FALSE, etINT,  {&p_num}, "Number of positive ions"       },
        { "-pname", FALSE, etSTR,  {&p_name}, "Name of the positive ion"      },
        { "-pq",    FALSE, etINT,  {&p_q},   "Charge of the positive ion"    },
        { "-nn",    FALSE, etINT,  {&n_num}, "Number of negative ions"       },
        { "-nname", FALSE, etSTR,  {&n_name}, "Name of the negative ion"      },
        { "-nq",    FALSE, etINT,  {&n_q},   "Charge of the negative ion"    },
        { "-rmin",  FALSE, etREAL, {&rmin},  "Minimum distance between ions" },
        { "-seed",  FALSE, etINT,  {&seed},  "Seed for random number generator" },
        {   "-conc",  FALSE, etREAL, {&conc},
            "Specify salt concentration (mol/liter). This will add sufficient ions to reach up to the specified concentration as computed from the volume of the cell in the input [REF].tpr[ref] file. Overrides the [TT]-np[tt] and [TT]-nn[tt] options."
        },
        { "-neutral", FALSE, etBOOL, {&bNeutral}, "This option will add enough ions to neutralize the system. These ions are added on top of those specified with [TT]-np[tt]/[TT]-nn[tt] or [TT]-conc[tt]. "}
    };
    t_topology         top;
    rvec              *x, *v;
    real               vol, qtot;
    matrix             box;
    t_atoms            atoms;
    t_pbc              pbc;
    int               *repl, ePBC;
    atom_id           *index;
    char              *grpname, title[STRLEN];
    gmx_bool          *bSet;
    int                i, nw, nwa, nsa, nsalt, iqtot;
    output_env_t       oenv;
    gmx_rng_t          rng;
    t_filenm           fnm[] = {
        { efTPR, NULL,  NULL,      ffREAD  },
        { efNDX, NULL,  NULL,      ffOPTRD },
        { efSTO, "-o",  NULL,      ffWRITE },
        { efTOP, "-p",  "topol",   ffOPTRW }
    };
#define NFILE asize(fnm)

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

    /* Check input for something sensible */
    if ((p_num < 0) || (n_num < 0))
    {
        gmx_fatal(FARGS, "Negative number of ions to add?");
    }

    if (conc > 0 && (p_num > 0 || n_num > 0))
    {
        fprintf(stderr, "WARNING: -conc specified, overriding -nn and -np.\n");
    }

    /* Read atom positions and charges */
    read_tps_conf(ftp2fn(efTPR, NFILE, fnm), title, &top, &ePBC, &x, &v, box, FALSE);
    atoms = top.atoms;

    /* Compute total charge */
    qtot = 0;
    for (i = 0; (i < atoms.nr); i++)
    {
        qtot += atoms.atom[i].q;
    }
    iqtot = gmx_nint(qtot);


    if (conc > 0)
    {
        /* Compute number of ions to be added */
        vol   = det(box);
        nsalt = gmx_nint(conc*vol*AVOGADRO/1e24);
        p_num = abs(nsalt*n_q);
        n_num = abs(nsalt*p_q);
    }
    if (bNeutral)
    {
        int qdelta = p_num*p_q + n_num*n_q + iqtot;

        /* Check if the system is neutralizable
         * is (qdelta == p_q*p_num + n_q*n_num) solvable for p_num and n_num? */
        int gcd = gmx_greatest_common_divisor(n_q, p_q);
        if ((qdelta % gcd) != 0)
        {
            gmx_fatal(FARGS, "Can't neutralize this system using -nq %d and"
                      " -pq %d.\n", n_q, p_q);
        }

        while (qdelta != 0)
        {
            while (qdelta < 0)
            {
                p_num++;
                qdelta += p_q;
            }
            while (qdelta > 0)
            {
                n_num++;
                qdelta += n_q;
            }
        }
    }

    if ((p_num == 0) && (n_num == 0))
    {
        fprintf(stderr, "No ions to add, will just copy input configuration.\n");
    }
    else
    {
        printf("Will try to add %d %s ions and %d %s ions.\n",
               p_num, p_name, n_num, n_name);
        printf("Select a continuous group of solvent molecules\n");
        get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nwa, &index, &grpname);
        for (i = 1; i < nwa; i++)
        {
            if (index[i] != index[i-1]+1)
            {
                gmx_fatal(FARGS, "The solvent group %s is not continuous: "
                          "index[%d]=%d, index[%d]=%d",
                          grpname, i, index[i-1]+1, i+1, index[i]+1);
            }
        }
        nsa = 1;
        while ((nsa < nwa) &&
                (atoms.atom[index[nsa]].resind ==
                 atoms.atom[index[nsa-1]].resind))
        {
            nsa++;
        }
        if (nwa % nsa)
        {
            gmx_fatal(FARGS, "Your solvent group size (%d) is not a multiple of %d",
                      nwa, nsa);
        }
        nw = nwa/nsa;
        fprintf(stderr, "Number of (%d-atomic) solvent molecules: %d\n", nsa, nw);
        if (p_num+n_num > nw)
        {
            gmx_fatal(FARGS, "Not enough solvent for adding ions");
        }

        if (opt2bSet("-p", NFILE, fnm))
        {
            update_topol(opt2fn("-p", NFILE, fnm), p_num, n_num, p_name, n_name, grpname);
        }

        snew(bSet, nw);
        snew(repl, nw);

        snew(v, atoms.nr);
        snew(atoms.pdbinfo, atoms.nr);

        set_pbc(&pbc, ePBC, box);

        if (seed == 0)
        {
            rng = gmx_rng_init(gmx_rng_make_seed());
        }
        else
        {
            rng = gmx_rng_init(seed);
        }
        /* Now loop over the ions that have to be placed */
        while (p_num-- > 0)
        {
            insert_ion(nsa, &nw, bSet, repl, index, x, &pbc,
                       1, p_q, p_name, &atoms, rmin, rng);
        }
        while (n_num-- > 0)
        {
            insert_ion(nsa, &nw, bSet, repl, index, x, &pbc,
                       -1, n_q, n_name, &atoms, rmin, rng);
        }
        gmx_rng_destroy(rng);
        fprintf(stderr, "\n");

        if (nw)
        {
            sort_ions(nsa, nw, repl, index, &atoms, x, p_name, n_name);
        }

        sfree(atoms.pdbinfo);
        atoms.pdbinfo = NULL;
    }
    write_sto_conf(ftp2fn(efSTO, NFILE, fnm), *top.name, &atoms, x, NULL, ePBC, box);

    return 0;
}
示例#20
0
t_mdebin *init_mdebin(ener_file_t fp_ene,
                      const gmx_mtop_t *mtop,
                      const t_inputrec *ir,
                      FILE *fp_dhdl)
{
    const char *ener_nm[F_NRE];
    static const char *vir_nm[] = {
        "Vir-XX", "Vir-XY", "Vir-XZ",
        "Vir-YX", "Vir-YY", "Vir-YZ",
        "Vir-ZX", "Vir-ZY", "Vir-ZZ"
    };
    static const char *sv_nm[] = {
        "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ",
        "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ",
        "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ"
    };
    static const char *fv_nm[] = {
        "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ",
        "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ",
        "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ"
    };
    static const char *pres_nm[] = {
        "Pres-XX","Pres-XY","Pres-XZ",
        "Pres-YX","Pres-YY","Pres-YZ",
        "Pres-ZX","Pres-ZY","Pres-ZZ"
    };
    static const char *surft_nm[] = {
        "#Surf*SurfTen"
    };
    static const char *mu_nm[] = {
        "Mu-X", "Mu-Y", "Mu-Z"
    };
    static const char *vcos_nm[] = {
        "2CosZ*Vel-X"
    };
    static const char *visc_nm[] = {
        "1/Viscosity"
    };
    static const char *baro_nm[] = {
        "Barostat"
    };

    char     **grpnms;
    const gmx_groups_t *groups;
    char     **gnm;
    char     buf[256];
    const char     *bufi;
    t_mdebin *md;
    int      i,j,ni,nj,n,nh,k,kk,ncon,nset;
    gmx_bool     bBHAM,bNoseHoover,b14;

    snew(md,1);

    if (EI_DYNAMICS(ir->eI))
    {
        md->delta_t = ir->delta_t;
    }
    else
    {
        md->delta_t = 0;
    }

    groups = &mtop->groups;

    bBHAM = (mtop->ffparams.functype[0] == F_BHAM);
    b14   = (gmx_mtop_ftype_count(mtop,F_LJ14) > 0 ||
             gmx_mtop_ftype_count(mtop,F_LJC14_Q) > 0);

    ncon = gmx_mtop_ftype_count(mtop,F_CONSTR);
    nset = gmx_mtop_ftype_count(mtop,F_SETTLE);
    md->bConstr    = (ncon > 0 || nset > 0);
    md->bConstrVir = FALSE;
    if (md->bConstr) {
        if (ncon > 0 && ir->eConstrAlg == econtLINCS) {
            if (ir->eI == eiSD2)
                md->nCrmsd = 2;
            else
                md->nCrmsd = 1;
        }
        md->bConstrVir = (getenv("GMX_CONSTRAINTVIR") != NULL);
    } else {
        md->nCrmsd = 0;
    }

    /* Energy monitoring */
    for(i=0;i<egNR;i++)
    {
        md->bEInd[i]=FALSE;
    }

#ifndef GMX_OPENMM
    for(i=0; i<F_NRE; i++)
    {
        md->bEner[i] = FALSE;
        if (i == F_LJ)
            md->bEner[i] = !bBHAM;
        else if (i == F_BHAM)
            md->bEner[i] = bBHAM;
        else if (i == F_EQM)
            md->bEner[i] = ir->bQMMM;
        else if (i == F_COUL_LR)
            md->bEner[i] = (ir->rcoulomb > ir->rlist);
        else if (i == F_LJ_LR)
            md->bEner[i] = (!bBHAM && ir->rvdw > ir->rlist);
        else if (i == F_BHAM_LR)
            md->bEner[i] = (bBHAM && ir->rvdw > ir->rlist);
        else if (i == F_RF_EXCL)
            md->bEner[i] = (EEL_RF(ir->coulombtype) && ir->coulombtype != eelRF_NEC);
        else if (i == F_COUL_RECIP)
            md->bEner[i] = EEL_FULL(ir->coulombtype);
        else if (i == F_LJ14)
            md->bEner[i] = b14;
        else if (i == F_COUL14)
            md->bEner[i] = b14;
        else if (i == F_LJC14_Q || i == F_LJC_PAIRS_NB)
            md->bEner[i] = FALSE;
        else if ((i == F_DVDL) || (i == F_DKDL))
            md->bEner[i] = (ir->efep != efepNO);
        else if (i == F_DHDL_CON)
            md->bEner[i] = (ir->efep != efepNO && md->bConstr);
        else if ((interaction_function[i].flags & IF_VSITE) ||
                 (i == F_CONSTR) || (i == F_CONSTRNC) || (i == F_SETTLE))
            md->bEner[i] = FALSE;
        else if ((i == F_COUL_SR) || (i == F_EPOT) || (i == F_PRES)  || (i==F_EQM))
            md->bEner[i] = TRUE;
        else if ((i == F_GBPOL) && ir->implicit_solvent==eisGBSA)
            md->bEner[i] = TRUE;
        else if ((i == F_NPSOLVATION) && ir->implicit_solvent==eisGBSA && (ir->sa_algorithm != esaNO))
            md->bEner[i] = TRUE;
        else if ((i == F_GB12) || (i == F_GB13) || (i == F_GB14))
            md->bEner[i] = FALSE;
        else if ((i == F_ETOT) || (i == F_EKIN) || (i == F_TEMP))
            md->bEner[i] = EI_DYNAMICS(ir->eI);
        else if (i==F_VTEMP) 
            md->bEner[i] =  (EI_DYNAMICS(ir->eI) && getenv("GMX_VIRIAL_TEMPERATURE"));
        else if (i == F_DISPCORR || i == F_PDISPCORR)
            md->bEner[i] = (ir->eDispCorr != edispcNO);
        else if (i == F_DISRESVIOL)
            md->bEner[i] = (gmx_mtop_ftype_count(mtop,F_DISRES) > 0);
        else if (i == F_ORIRESDEV)
            md->bEner[i] = (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0);
        else if (i == F_CONNBONDS)
            md->bEner[i] = FALSE;
        else if (i == F_COM_PULL)
            md->bEner[i] = (ir->ePull == epullUMBRELLA || ir->ePull == epullCONST_F);
        else if (i == F_ECONSERVED)
            md->bEner[i] = ((ir->etc == etcNOSEHOOVER || ir->etc == etcVRESCALE) &&
                            (ir->epc == epcNO || ir->epc==epcMTTK));
        else
            md->bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0);
    }
#else
    /* OpenMM always produces only the following 4 energy terms */
    md->bEner[F_EPOT] = TRUE;
    md->bEner[F_EKIN] = TRUE;
    md->bEner[F_ETOT] = TRUE;
    md->bEner[F_TEMP] = TRUE;
#endif

    md->f_nre=0;
    for(i=0; i<F_NRE; i++)
    {
        if (md->bEner[i])
        {
            /* FIXME: The constness should not be cast away */
            /*ener_nm[f_nre]=(char *)interaction_function[i].longname;*/
            ener_nm[md->f_nre]=interaction_function[i].longname;
            md->f_nre++;
        }
    }

    md->epc = ir->epc;
    for (i=0;i<DIM;i++) 
    {
        for (j=0;j<DIM;j++) 
        {
            md->ref_p[i][j] = ir->ref_p[i][j];
        }
    }
    md->bTricl = TRICLINIC(ir->compress) || TRICLINIC(ir->deform);
    md->bDynBox = DYNAMIC_BOX(*ir);
    md->etc = ir->etc;
    md->bNHC_trotter = IR_NVT_TROTTER(ir);
    md->bMTTK = IR_NPT_TROTTER(ir);

    md->ebin  = mk_ebin();
    /* Pass NULL for unit to let get_ebin_space determine the units
     * for interaction_function[i].longname
     */
    md->ie    = get_ebin_space(md->ebin,md->f_nre,ener_nm,NULL);
    if (md->nCrmsd)
    {
        /* This should be called directly after the call for md->ie,
         * such that md->iconrmsd follows directly in the list.
         */
        md->iconrmsd = get_ebin_space(md->ebin,md->nCrmsd,conrmsd_nm,"");
    }
    if (md->bDynBox)
    {
        md->ib    = get_ebin_space(md->ebin, 
                                   md->bTricl ? NTRICLBOXS : NBOXS, 
                                   md->bTricl ? tricl_boxs_nm : boxs_nm,
                                   unit_length);
        md->ivol  = get_ebin_space(md->ebin, 1, vol_nm,  unit_volume);
        md->idens = get_ebin_space(md->ebin, 1, dens_nm, unit_density_SI);
        md->ipv   = get_ebin_space(md->ebin, 1, pv_nm,   unit_energy);
        md->ienthalpy = get_ebin_space(md->ebin, 1, enthalpy_nm,   unit_energy);
    }
    if (md->bConstrVir)
    {
        md->isvir = get_ebin_space(md->ebin,asize(sv_nm),sv_nm,unit_energy);
        md->ifvir = get_ebin_space(md->ebin,asize(fv_nm),fv_nm,unit_energy);
    }
    md->ivir   = get_ebin_space(md->ebin,asize(vir_nm),vir_nm,unit_energy);
    md->ipres  = get_ebin_space(md->ebin,asize(pres_nm),pres_nm,unit_pres_bar);
    md->isurft = get_ebin_space(md->ebin,asize(surft_nm),surft_nm,
                                unit_surft_bar);
    if (md->epc == epcPARRINELLORAHMAN || md->epc == epcMTTK)
    {
        md->ipc = get_ebin_space(md->ebin,md->bTricl ? 6 : 3,
                                 boxvel_nm,unit_vel);
    }
    md->imu    = get_ebin_space(md->ebin,asize(mu_nm),mu_nm,unit_dipole_D);
    if (ir->cos_accel != 0)
    {
        md->ivcos = get_ebin_space(md->ebin,asize(vcos_nm),vcos_nm,unit_vel);
        md->ivisc = get_ebin_space(md->ebin,asize(visc_nm),visc_nm,
                                   unit_invvisc_SI);
    }

    /* Energy monitoring */
    for(i=0;i<egNR;i++)
    {
        md->bEInd[i] = FALSE;
    }
    md->bEInd[egCOULSR] = TRUE;
    md->bEInd[egLJSR  ] = TRUE;

    if (ir->rcoulomb > ir->rlist)
    {
        md->bEInd[egCOULLR] = TRUE;
    }
    if (!bBHAM)
    {
        if (ir->rvdw > ir->rlist)
        {
            md->bEInd[egLJLR]   = TRUE;
        }
    }
    else
    {
        md->bEInd[egLJSR]   = FALSE;
        md->bEInd[egBHAMSR] = TRUE;
        if (ir->rvdw > ir->rlist)
        {
            md->bEInd[egBHAMLR]   = TRUE;
        }
    }
    if (b14)
    {
        md->bEInd[egLJ14] = TRUE;
        md->bEInd[egCOUL14] = TRUE;
    }
    md->nEc=0;
    for(i=0; (i<egNR); i++)
    {
        if (md->bEInd[i])
        {
            md->nEc++;
        }
    }

    n=groups->grps[egcENER].nr;
    md->nEg=n;
    md->nE=(n*(n+1))/2;
    snew(md->igrp,md->nE);
    if (md->nE > 1)
    {
        n=0;
        snew(gnm,md->nEc);
        for(k=0; (k<md->nEc); k++)
        {
            snew(gnm[k],STRLEN);
        }
        for(i=0; (i<groups->grps[egcENER].nr); i++)
        {
            ni=groups->grps[egcENER].nm_ind[i];
            for(j=i; (j<groups->grps[egcENER].nr); j++)
            {
                nj=groups->grps[egcENER].nm_ind[j];
                for(k=kk=0; (k<egNR); k++)
                {
                    if (md->bEInd[k])
                    {
                        sprintf(gnm[kk],"%s:%s-%s",egrp_nm[k],
                                *(groups->grpname[ni]),*(groups->grpname[nj]));
                        kk++;
                    }
                }
                md->igrp[n]=get_ebin_space(md->ebin,md->nEc,
                                           (const char **)gnm,unit_energy);
                n++;
            }
        }
        for(k=0; (k<md->nEc); k++)
        {
            sfree(gnm[k]);
        }
        sfree(gnm);

        if (n != md->nE)
        {
            gmx_incons("Number of energy terms wrong");
        }
    }

    md->nTC=groups->grps[egcTC].nr;
    md->nNHC = ir->opts.nhchainlength; /* shorthand for number of NH chains */ 
    if (md->bMTTK)
    {
        md->nTCP = 1;  /* assume only one possible coupling system for barostat 
                          for now */
    } 
    else 
    {
        md->nTCP = 0;
    }

    if (md->etc == etcNOSEHOOVER) {
        if (md->bNHC_trotter) { 
            md->mde_n = 2*md->nNHC*md->nTC;
        }
        else 
        {
            md->mde_n = 2*md->nTC;
        }
        if (md->epc == epcMTTK)
        {
            md->mdeb_n = 2*md->nNHC*md->nTCP;
        }
    } else { 
        md->mde_n = md->nTC;
        md->mdeb_n = 0;
    }

    snew(md->tmp_r,md->mde_n);
    snew(md->tmp_v,md->mde_n);
    snew(md->grpnms,md->mde_n);
    grpnms = md->grpnms;

    for(i=0; (i<md->nTC); i++)
    {
        ni=groups->grps[egcTC].nm_ind[i];
        sprintf(buf,"T-%s",*(groups->grpname[ni]));
        grpnms[i]=strdup(buf);
    }
    md->itemp=get_ebin_space(md->ebin,md->nTC,(const char **)grpnms,
                             unit_temp_K);

    bNoseHoover = (getenv("GMX_NOSEHOOVER_CHAINS") != NULL); /* whether to print Nose-Hoover chains */

    if (md->etc == etcNOSEHOOVER)
    {
        if (bNoseHoover) 
        {
            if (md->bNHC_trotter) 
            {
                for(i=0; (i<md->nTC); i++) 
                {
                    ni=groups->grps[egcTC].nm_ind[i];
                    bufi = *(groups->grpname[ni]);
                    for(j=0; (j<md->nNHC); j++) 
                    {
                        sprintf(buf,"Xi-%d-%s",j,bufi);
                        grpnms[2*(i*md->nNHC+j)]=strdup(buf);
                        sprintf(buf,"vXi-%d-%s",j,bufi);
                        grpnms[2*(i*md->nNHC+j)+1]=strdup(buf);
                    }
                }
                md->itc=get_ebin_space(md->ebin,md->mde_n,
                                       (const char **)grpnms,unit_invtime);
                if (md->bMTTK) 
                {
                    for(i=0; (i<md->nTCP); i++) 
                    {
                        bufi = baro_nm[0];  /* All barostat DOF's together for now. */
                        for(j=0; (j<md->nNHC); j++) 
                        {
                            sprintf(buf,"Xi-%d-%s",j,bufi);
                            grpnms[2*(i*md->nNHC+j)]=strdup(buf);
                            sprintf(buf,"vXi-%d-%s",j,bufi);
                            grpnms[2*(i*md->nNHC+j)+1]=strdup(buf);
                        }
                    }
                    md->itcb=get_ebin_space(md->ebin,md->mdeb_n,
                                            (const char **)grpnms,unit_invtime);
                }
            } 
            else
            {
                for(i=0; (i<md->nTC); i++) 
                {
                    ni=groups->grps[egcTC].nm_ind[i];
                    bufi = *(groups->grpname[ni]);
                    sprintf(buf,"Xi-%s",bufi);
                    grpnms[2*i]=strdup(buf);
                    sprintf(buf,"vXi-%s",bufi);
                    grpnms[2*i+1]=strdup(buf);
                }
                md->itc=get_ebin_space(md->ebin,md->mde_n,
                                       (const char **)grpnms,unit_invtime);
            }
        }
    }
    else if (md->etc == etcBERENDSEN || md->etc == etcYES || 
             md->etc == etcVRESCALE)
    {
        for(i=0; (i<md->nTC); i++)
        {
            ni=groups->grps[egcTC].nm_ind[i];
            sprintf(buf,"Lamb-%s",*(groups->grpname[ni]));
            grpnms[i]=strdup(buf);
        }
        md->itc=get_ebin_space(md->ebin,md->mde_n,(const char **)grpnms,"");
    }

    sfree(grpnms);


    md->nU=groups->grps[egcACC].nr;
    if (md->nU > 1)
    {
        snew(grpnms,3*md->nU);
        for(i=0; (i<md->nU); i++)
        {
            ni=groups->grps[egcACC].nm_ind[i];
            sprintf(buf,"Ux-%s",*(groups->grpname[ni]));
            grpnms[3*i+XX]=strdup(buf);
            sprintf(buf,"Uy-%s",*(groups->grpname[ni]));
            grpnms[3*i+YY]=strdup(buf);
            sprintf(buf,"Uz-%s",*(groups->grpname[ni]));
            grpnms[3*i+ZZ]=strdup(buf);
        }
        md->iu=get_ebin_space(md->ebin,3*md->nU,(const char **)grpnms,unit_vel);
        sfree(grpnms);
    }

    if ( fp_ene )
    {
        do_enxnms(fp_ene,&md->ebin->nener,&md->ebin->enm);
    }

    md->print_grpnms=NULL;

    /* check whether we're going to write dh histograms */
    md->dhc=NULL; 
    if (ir->separate_dhdl_file == sepdhdlfileNO )
    {
        int i;
        snew(md->dhc, 1);

        mde_delta_h_coll_init(md->dhc, ir);
        md->fp_dhdl = NULL;
    }
    else
    {
        md->fp_dhdl = fp_dhdl;
    }
    md->dhdl_derivatives = (ir->dhdl_derivatives==dhdlderivativesYES);
    return md;
}
示例#21
0
    "returned in ascending order. This can be changed by appending",
    "[TT]permute P1 P2 ... PN[tt] to an expression.",
    "The [TT]Pi[tt] should form a permutation of the numbers 1 to N.",
    "This keyword permutes each N-position block in the selection such that",
    "the i'th position in the block becomes Pi'th.",
    "Note that it is the positions that are permuted, not individual atoms.",
    "A fatal error occurs if the size of the selection is not a multiple of n.",
    "It is only possible to permute the whole selection expression, not any",
    "subexpressions, i.e., the [TT]permute[tt] keyword should appear last in",
    "a selection.",
};

/** \internal Selection method data for the \p permute modifier. */
gmx_ana_selmethod_t sm_permute = {
    "permute", POS_VALUE, SMETH_MODIFIER,
    asize(smparams_permute), smparams_permute,
    &init_data_permute,
    NULL,
    &init_permute,
    &init_output_permute,
    &free_data_permute,
    NULL,
    NULL,
    &evaluate_permute,
    {"permute P1 ... PN", asize(help_permute), help_permute},
};

/*!
 * \param[in]     npar  Not used (should be 2).
 * \param[in,out] param Method parameters (should point to a copy of
 *   \ref smparams_permute).
示例#22
0
int gmx_spol(int argc,char *argv[])
{
  t_topology *top;
  t_inputrec *ir;
  t_atom     *atom;
  char     title[STRLEN];
  t_trxstatus *status;
  int      nrefat,natoms,nf,ntot;
  real     t;
  rvec     *xtop,*x,xref,trial,dx={0},dip,dir;
  matrix   box;
  
  FILE    *fp;
  int     *isize,nrefgrp;
  atom_id **index,*molindex;
  char    **grpname;
  real    rmin2,rmax2,rcut,rcut2,rdx2=0,rtry2,qav,q,dip2,invbw;
  int     nbin,i,m,mol,a0,a1,a,d;
  double  sdip,sdip2,sinp,sdinp,nmol;
  int     *hist;
  t_pbc   pbc;
  gmx_rmpbc_t  gpbc=NULL;

  
  const char *desc[] = {
    "[TT]g_spol[tt] analyzes dipoles around a solute; it is especially useful",
    "for polarizable water. A group of reference atoms, or a center",
    "of mass reference (option [TT]-com[tt]) and a group of solvent",
    "atoms is required. The program splits the group of solvent atoms",
    "into molecules. For each solvent molecule the distance to the",
    "closest atom in reference group or to the COM is determined.",
    "A cumulative distribution of these distances is plotted.",
    "For each distance between [TT]-rmin[tt] and [TT]-rmax[tt]",
    "the inner product of the distance vector",
    "and the dipole of the solvent molecule is determined.",
    "For solvent molecules with net charge (ions), the net charge of the ion",
    "is subtracted evenly from all atoms in the selection of each ion.",
    "The average of these dipole components is printed.",
    "The same is done for the polarization, where the average dipole is",
    "subtracted from the instantaneous dipole. The magnitude of the average",
    "dipole is set with the option [TT]-dip[tt], the direction is defined",
    "by the vector from the first atom in the selected solvent group",
    "to the midpoint between the second and the third atom."
  };
 
  output_env_t oenv;
  static gmx_bool bCom = FALSE,bPBC = FALSE;
  static int  srefat=1;
  static real rmin=0.0,rmax=0.32,refdip=0,bw=0.01;
  t_pargs pa[] = {
    { "-com",  FALSE, etBOOL,  {&bCom},
      "Use the center of mass as the reference postion" },
    { "-refat",  FALSE, etINT, {&srefat},
      "The reference atom of the solvent molecule" },
    { "-rmin",  FALSE, etREAL, {&rmin}, "Maximum distance (nm)" },
    { "-rmax",  FALSE, etREAL, {&rmax}, "Maximum distance (nm)" },
    { "-dip",   FALSE, etREAL, {&refdip}, "The average dipole (D)" },
    { "-bw",    FALSE, etREAL, {&bw}, "The bin width" }
  };
  
  t_filenm fnm[] = {
    { efTRX, NULL,  NULL,  ffREAD },
    { efTPX, NULL,  NULL,  ffREAD },
    { efNDX, NULL,  NULL,  ffOPTRD },
    { efXVG, NULL,  "scdist.xvg",  ffWRITE }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
  
  snew(top,1);
  snew(ir,1);
  read_tpx_top(ftp2fn(efTPX,NFILE,fnm),
	       ir,box,&natoms,NULL,NULL,NULL,top);
  
  /* get index groups */
  printf("Select a group of reference particles and a solvent group:\n"); 
  snew(grpname,2);
  snew(index,2);
  snew(isize,2);
  get_index(&top->atoms,ftp2fn_null(efNDX,NFILE,fnm),2,isize,index,grpname);

  if (bCom) {
    nrefgrp = 1;
    nrefat  = isize[0];
  } else {
    nrefgrp = isize[0];
    nrefat  = 1;
  }

  spol_atom2molindex(&(isize[1]),index[1],&(top->mols));
  srefat--;

  /* initialize reading trajectory:                         */
  natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);

  rcut  = 0.99*sqrt(max_cutoff2(ir->ePBC,box));
  if (rcut == 0)
    rcut = 10*rmax;
  rcut2 = sqr(rcut);
  invbw = 1/bw;
  nbin = (int)(rcut*invbw)+2;
  snew(hist,nbin);

  rmin2 = sqr(rmin);
  rmax2 = sqr(rmax);

  nf = 0;
  ntot = 0;
  sdip  = 0;
  sdip2 = 0;
  sinp  = 0;
  sdinp = 0;

  molindex = top->mols.index;
  atom     = top->atoms.atom;
  
  gpbc = gmx_rmpbc_init(&top->idef,ir->ePBC,natoms,box);

  /* start analysis of trajectory */
  do {
    /* make molecules whole again */
    gmx_rmpbc(gpbc,natoms,box,x);

    set_pbc(&pbc,ir->ePBC,box);
    if (bCom)
      calc_com_pbc(nrefat,top,x,&pbc,index[0],xref,ir->ePBC,box);

    for(m=0; m<isize[1]; m++) {
      mol = index[1][m];
      a0 = molindex[mol];
      a1 = molindex[mol+1];
      for(i=0; i<nrefgrp; i++) {
	pbc_dx(&pbc,x[a0+srefat],bCom ? xref : x[index[0][i]],trial);
	rtry2 = norm2(trial);
	if (i==0 || rtry2 < rdx2) {
	  copy_rvec(trial,dx);
	  rdx2 = rtry2;
	}
      }
      if (rdx2 < rcut2)
	hist[(int)(sqrt(rdx2)*invbw)+1]++;
      if (rdx2 >= rmin2 && rdx2 < rmax2) {
	unitv(dx,dx);
	clear_rvec(dip);
	qav = 0;
	for(a=a0; a<a1; a++) {
	  qav += atom[a].q;
	}
	qav /= (a1 - a0);
	for(a=a0; a<a1; a++) {
	  q = atom[a].q - qav;
	  for(d=0; d<DIM; d++)
	    dip[d] += q*x[a][d];
	}
	for(d=0; d<DIM; d++)
	  dir[d] = -x[a0][d];
	for(a=a0+1; a<a0+3; a++) {
	  for(d=0; d<DIM; d++)
	    dir[d] += 0.5*x[a][d];
	}
	unitv(dir,dir);

	svmul(ENM2DEBYE,dip,dip);
	dip2 = norm2(dip);
	sdip  += sqrt(dip2);
	sdip2 += dip2;
	for(d=0; d<DIM; d++) {
	  sinp  += dx[d]*dip[d];
	  sdinp += dx[d]*(dip[d] - refdip*dir[d]);
	}

	ntot++;
      }
    }
    nf++;

  }  while (read_next_x(oenv,status,&t,natoms,x,box));
  
  gmx_rmpbc_done(gpbc);

  /* clean up */
  sfree(x);
  close_trj(status);
  
  fprintf(stderr,"Average number of molecules within %g nm is %.1f\n",
	  rmax,(real)ntot/(real)nf);
  if (ntot > 0) {
    sdip  /= ntot;
    sdip2 /= ntot;
    sinp  /= ntot;
    sdinp /= ntot;
    fprintf(stderr,"Average dipole:                               %f (D), std.dev. %f\n",
	    sdip,sqrt(sdip2-sqr(sdip)));
    fprintf(stderr,"Average radial component of the dipole:       %f (D)\n",
	    sinp);
    fprintf(stderr,"Average radial component of the polarization: %f (D)\n",
	    sdinp);
  }

  fp = xvgropen(opt2fn("-o",NFILE,fnm),
		"Cumulative solvent distribution","r (nm)","molecules",oenv);
  nmol = 0;
  for(i=0; i<=nbin; i++) {
    nmol += hist[i];
    fprintf(fp,"%g %g\n",i*bw,nmol/nf);
  }
  ffclose(fp);

  do_view(oenv,opt2fn("-o",NFILE,fnm),NULL);

  thanx(stderr);
  
  return 0;
}
示例#23
0
int gmx_pme_error(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] estimates the error of the electrostatic forces",
        "if using the sPME algorithm. The flag [TT]-tune[tt] will determine",
        "the splitting parameter such that the error is equally",
        "distributed over the real and reciprocal space part.",
        "The part of the error that stems from self interaction of the particles "
        "is computationally demanding. However, a good a approximation is to",
        "just use a fraction of the particles for this term which can be",
        "indicated by the flag [TT]-self[tt].[PAR]",
    };

    real            fs        = 0.0; /* 0 indicates: not set by the user */
    real            user_beta = -1.0;
    real            fracself  = 1.0;
    t_inputinfo     info;
    t_state         state;     /* The state from the tpr input file */
    gmx_mtop_t      mtop;      /* The topology from the tpr input file */
    t_inputrec     *ir = NULL; /* The inputrec from the tpr file */
    FILE           *fp = NULL;
    t_commrec      *cr;
    unsigned long   PCA_Flags;
    gmx_bool        bTUNE    = FALSE;
    gmx_bool        bVerbose = FALSE;
    int             seed     = 0;


    static t_filenm fnm[] = {
        { efTPX, "-s",     NULL,    ffREAD },
        { efOUT, "-o",    "error",  ffWRITE },
        { efTPX, "-so",   "tuned",  ffOPTWR }
    };

    output_env_t    oenv = NULL;

    t_pargs         pa[] = {
        { "-beta",     FALSE, etREAL, {&user_beta},
          "If positive, overwrite ewald_beta from [TT].tpr[tt] file with this value" },
        { "-tune",     FALSE, etBOOL, {&bTUNE},
          "Tune the splitting parameter such that the error is equally distributed between real and reciprocal space" },
        { "-self",     FALSE, etREAL, {&fracself},
          "If between 0.0 and 1.0, determine self interaction error from just this fraction of the charged particles" },
        { "-seed",     FALSE, etINT,  {&seed},
          "Random number seed used for Monte Carlo algorithm when [TT]-self[tt] is set to a value between 0.0 and 1.0" },
        { "-v",        FALSE, etBOOL, {&bVerbose},
          "Be loud and noisy" }
    };


#define NFILE asize(fnm)

    cr = init_commrec();
#ifdef GMX_LIB_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif

    PCA_Flags  = PCA_NOEXIT_ON_ARGS;
    PCA_Flags |= (MASTER(cr) ? 0 : PCA_QUIET);

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

    if (!bTUNE)
    {
        bTUNE = opt2bSet("-so", NFILE, fnm);
    }

    info.n_entries = 1;

    /* Allocate memory for the inputinfo struct: */
    create_info(&info);
    info.fourier_sp[0] = fs;

    /* Read in the tpr file and open logfile for reading */
    if (MASTER(cr))
    {
        snew(ir, 1);
        read_tpr_file(opt2fn("-s", NFILE, fnm), &info, &state, &mtop, ir, user_beta, fracself);

        fp = fopen(opt2fn("-o", NFILE, fnm), "w");
    }

    /* Check consistency if the user provided fourierspacing */
    if (fs > 0 && MASTER(cr))
    {
        /* Recalculate the grid dimensions using fourierspacing from user input */
        info.nkx[0] = 0;
        info.nky[0] = 0;
        info.nkz[0] = 0;
        calc_grid(stdout, state.box, info.fourier_sp[0], &(info.nkx[0]), &(info.nky[0]), &(info.nkz[0]));
        if ( (ir->nkx != info.nkx[0]) || (ir->nky != info.nky[0]) || (ir->nkz != info.nkz[0]) )
        {
            gmx_fatal(FARGS, "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = %d x %d x %d",
                      fs, ir->nkx, ir->nky, ir->nkz, info.nkx[0], info.nky[0], info.nkz[0]);
        }
    }

    /* Estimate (S)PME force error */

    /* Determine the volume of the simulation box */
    if (MASTER(cr))
    {
        info.volume = det(state.box);
        calc_recipbox(state.box, info.recipbox);
        info.natoms = mtop.natoms;
        info.bTUNE  = bTUNE;
    }

    if (PAR(cr))
    {
        bcast_info(&info, cr);
    }

    /* Get an error estimate of the input tpr file and do some tuning if requested */
    estimate_PME_error(&info, &state, &mtop, fp, bVerbose, seed, cr);

    if (MASTER(cr))
    {
        /* Write out optimized tpr file if requested */
        if (opt2bSet("-so", NFILE, fnm) || bTUNE)
        {
            ir->ewald_rtol = info.ewald_rtol[0];
            write_tpx_state(opt2fn("-so", NFILE, fnm), ir, &state, &mtop);
        }
        please_cite(fp, "Wang2010");
        fclose(fp);
    }

    return 0;
}
示例#24
0
int gmx_g_angle(int argc, char *argv[])
{
    static const char *desc[] = {
        "[THISMODULE] computes the angle distribution for a number of angles",
        "or dihedrals.[PAR]",
        "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 and the rest are the individual angles.[PAR]",
        "With the [TT]-of[tt] option, [THISMODULE] also calculates the fraction of trans",
        "dihedrals (only for dihedrals) as function of time, but this is",
        "probably only fun for a select few.[PAR]",
        "With option [TT]-oc[tt], a dihedral correlation function is calculated.[PAR]",
        "It should be noted that the index file must contain",
        "atom triplets 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 principal components analysis using [gmx-covar].[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               dt;
    int                isize;
    atom_id           *index;
    char              *grpname;
    real               maxang, S2, norm_fac, maxstat;
    unsigned long      mode;
    int                nframes, maxangstat, mult, *angstat;
    int                i, j, nangles, first, last;
    gmx_bool           bAver, bRb, bPeriodic,
                       bFrac,          /* calculate fraction too?  */
                       bTrans,         /* worry about transtions too? */
                       bCorr;          /* correlation function ? */
    real         aver, aver2, aversig; /* fraction trans dihedrals */
    double       tfrac = 0;
    char         title[256];
    real       **dih = NULL;      /* mega array with all dih. angles at all times*/
    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);
    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs,
                           &oenv))
    {
        return 0;
    }

    mult   = 4;
    maxang = 360.0;
    bRb    = FALSE;

    GMX_RELEASE_ASSERT(opt[0] != NULL, "Internal option inconsistency; opt[0]==NULL after processing");

    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 trr dump");
        }
        else
        {
            please_cite(stdout, "Mu2005a");
        }
    }

    /* Calculate bin size */
    maxangstat = static_cast<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", std::atan2(std::sin(dd), std::cos(dd))*RAD2DEG);
                    }
                    else
                    {
                        fprintf(out, "  %8.3f", dih[j][i]*RAD2DEG);
                    }
                }
            }
            fprintf(out, "\n");
        }
        xvgrclose(out);
    }
    if (opt2bSet("-or", NFILE, fnm))
    {
        dump_dih_trr(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];
        }
        xvgrclose(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   /= nframes;
    aver2  /= nframes;
    aversig = std::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 = std::max(maxstat, angstat[i]*norm_fac);
        }
        if (output_env_get_print_xvgr_codes(oenv))
        {
            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);
    }

    xvgrclose(out);

    do_view(oenv, opt2fn("-od", NFILE, fnm), "-nxy");
    if (bAver)
    {
        do_view(oenv, opt2fn("-ov", NFILE, fnm), "-nxy");
    }

    return 0;
}
示例#25
0
int gmx_dump(int argc, char *argv[])
{
    const char *desc[] = {
        "[THISMODULE] reads a run input file ([REF].tpr[ref]),",
        "a trajectory ([REF].trr[ref]/[REF].xtc[ref]/[TT]/tng[tt]), an energy",
        "file ([REF].edr[ref]) or a checkpoint file ([REF].cpt[ref])",
        "and prints that to standard output in a readable format.",
        "This program is essential for checking your run input file in case of",
        "problems.[PAR]",
        "The program can also preprocess a topology to help finding problems.",
        "Note that currently setting [TT]GMXLIB[tt] is the only way to customize",
        "directories used for searching include files.",
    };
    const char *bugs[] = {
        "Position restraint output from -sys -s is broken"
    };
    t_filenm    fnm[] = {
        { efTPR, "-s", NULL, ffOPTRD },
        { efTRX, "-f", NULL, ffOPTRD },
        { efEDR, "-e", NULL, ffOPTRD },
        { efCPT, NULL, NULL, ffOPTRD },
        { efTOP, "-p", NULL, ffOPTRD },
        { efMTX, "-mtx", "hessian", ffOPTRD },
        { efMDP, "-om", NULL, ffOPTWR }
    };
#define NFILE asize(fnm)

    output_env_t    oenv;
    /* Command line options */
    static gmx_bool bShowNumbers = TRUE;
    static gmx_bool bSysTop      = FALSE;
    t_pargs         pa[]         = {
        { "-nr", FALSE, etBOOL, {&bShowNumbers}, "Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)" },
        { "-sys", FALSE, etBOOL, {&bSysTop}, "List the atoms and bonded interactions for the whole system instead of for each molecule type" }
    };

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


    if (ftp2bSet(efTPR, NFILE, fnm))
    {
        list_tpx(ftp2fn(efTPR, NFILE, fnm), bShowNumbers,
                 ftp2fn_null(efMDP, NFILE, fnm), bSysTop);
    }
    else if (ftp2bSet(efTRX, NFILE, fnm))
    {
        list_trx(ftp2fn(efTRX, NFILE, fnm));
    }
    else if (ftp2bSet(efEDR, NFILE, fnm))
    {
        list_ene(ftp2fn(efEDR, NFILE, fnm));
    }
    else if (ftp2bSet(efCPT, NFILE, fnm))
    {
        list_checkpoint(ftp2fn(efCPT, NFILE, fnm), stdout);
    }
    else if (ftp2bSet(efTOP, NFILE, fnm))
    {
        list_top(ftp2fn(efTOP, NFILE, fnm));
    }
    else if (ftp2bSet(efMTX, NFILE, fnm))
    {
        list_mtx(ftp2fn(efMTX, NFILE, fnm));
    }

    return 0;
}
示例#26
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "[TT]g_anavel[tt] computes temperature profiles in a sample. The sample",
    "can be analysed radial, i.e. the temperature as a function of",
    "distance from the center, cylindrical, i.e. as a function of distance",
    "from the vector (0,0,1) through the center of the box, or otherwise",
    "(will be specified later)"
  };
  t_filenm fnm[] = {
    { efTRN,  "-f",  NULL, ffREAD },
    { efTPX,  "-s",  NULL, ffREAD },
    { efXPM,  "-o", "xcm", ffWRITE }
  };
#define NFILE asize(fnm)

  static int  mode = 0,   nlevels = 10;
  static real tmax = 300, xmax    = -1;
  t_pargs pa[] = {
    { "-mode",    FALSE, etINT,  {&mode},    "mode" },
    { "-nlevels", FALSE, etINT,  {&nlevels}, "number of levels" },
    { "-tmax",    FALSE, etREAL, {&tmax},    "max temperature in output" },
    { "-xmax",    FALSE, etREAL, {&xmax},    "max distance from center" }
  };
  
  FILE       *fp;
  int        *npts,nmax;
  int        status;
  int        i,j,idum,step,nframe=0,index;
  real       temp,rdum,hboxx,hboxy,scale,xnorm=0;
  real       **profile=NULL;
  real       *t_x=NULL,*t_y,hi=0;
  t_topology *top;
  int        d,m,n;
  matrix     box;
  atom_id    *sysindex;
  gmx_bool       bHaveV,bReadV;
  t_rgb      rgblo = { 0, 0, 1 },rgbhi = { 1, 0, 0 };
  int        flags = TRX_READ_X | TRX_READ_V;
  t_trxframe fr;

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

  top    = read_top(ftp2fn(efTPX,NFILE,fnm));

  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags);
	
  if (xmax > 0) {
    scale  = 5;
    nmax   = xmax*scale;
  }
  else {
    scale  = 5;
    nmax   = (0.5*sqrt(sqr(box[XX][XX])+sqr(box[YY][YY])))*scale; 
  }
  snew(npts,nmax+1);
  snew(t_y,nmax+1);
  for(i=0; (i<=nmax); i++) {
    npts[i] = 0;
    t_y[i]  = i/scale;
  }
  do {
    srenew(profile,++nframe);
    snew(profile[nframe-1],nmax+1);
    srenew(t_x,nframe);
    t_x[nframe-1] = fr.time*1000;
    hboxx = box[XX][XX]/2;
    hboxy = box[YY][YY]/2;
    for(i=0; (i<fr.natoms); i++) {
      /* determine position dependent on mode */
      switch (mode) {
      case 0:
	xnorm = sqrt(sqr(fr.x[i][XX]-hboxx) + sqr(fr.x[i][YY]-hboxy));
	break;
      default:
	gmx_fatal(FARGS,"Unknown mode %d",mode);
      }
      index = xnorm*scale;
      if (index <= nmax) {
	temp = top->atoms.atom[i].m*iprod(fr.v[i],fr.v[i])/(2*BOLTZ);
	if (temp > hi)
	  hi = temp;
	npts[index]++;
	profile[nframe-1][index] += temp;
      }
    }
    for(i=0; (i<=nmax); i++) {
      if (npts[i] != 0) 
	profile[nframe-1][i] /= npts[i];
      npts[i] = 0;
    }
  } while (read_next_frame(status,&fr));
  close_trx(status);

  fp = ftp2FILE(efXPM,NFILE,fnm,"w");
  write_xpm(fp,0,"Temp. profile","T (a.u.)",
	    "t (fs)","R (nm)",
	    nframe,nmax+1,t_x,t_y,profile,0,tmax,
	    rgblo,rgbhi,&nlevels);
  
  gmx_thanx(stderr);
  
  return 0;
}
示例#27
0
文件: mdrun.c 项目: nrego/gist
int main(int argc,char *argv[])
{
  const char *desc[] = {
 #ifdef GMX_OPENMM
    "This is an experimental release of GROMACS for accelerated",
	"Molecular Dynamics simulations on GPU processors. Support is provided",
	"by the OpenMM library (https://simtk.org/home/openmm).[PAR]",
	"*Warning*[BR]",
	"This release is targeted at developers and advanced users and",
	"care should be taken before production use. The following should be",
	"noted before using the program:[PAR]",
	" * The current release runs only on modern nVidia GPU hardware with CUDA support.",
	"Make sure that the necessary CUDA drivers and libraries for your operating system",
	"are already installed. The CUDA SDK also should be installed in order to compile",
	"the program from source (http://www.nvidia.com/object/cuda_home.html).[PAR]",
	" * Multiple GPU cards are not supported.[PAR]",
	" * Only a small subset of the GROMACS features and options are supported on the GPUs.",
	"See below for a detailed list.[PAR]",
	" * Consumer level GPU cards are known to often have problems with faulty memory.",
	"It is recommended that a full memory check of the cards is done at least once",
	"(for example, using the memtest=full option).",
	"A partial memory check (for example, memtest=15) before and",
	"after the simulation run would help spot",
	"problems resulting from processor overheating.[PAR]",
	" * The maximum size of the simulated systems depends on the available",
	"GPU memory,for example, a GTX280 with 1GB memory has been tested with systems",
	"of up to about 100,000 atoms.[PAR]",
	" * In order to take a full advantage of the GPU platform features, many algorithms",
	"have been implemented in a very different way than they are on the CPUs.",
	"Therefore numercal correspondence between properties of the state of",
	"simulated systems should not be expected. Moreover, the values will likely vary",
	"when simulations are done on different GPU hardware.[PAR]",
	" * Frequent retrieval of system state information such as",
	"trajectory coordinates and energies can greatly influence the performance",
	"of the program due to slow CPU<->GPU memory transfer speed.[PAR]",
	" * MD algorithms are complex, and although the Gromacs code is highly tuned for them,",
	"they often do not translate very well onto the streaming architetures.",
	"Realistic expectations about the achievable speed-up from test with GTX280:",
	"For small protein systems in implicit solvent using all-vs-all kernels the acceleration",
	"can be as high as 20 times, but in most other setups involving cutoffs and PME the",
	"acceleration is usually only ~4 times relative to a 3GHz CPU.[PAR]",
	"Supported features:[PAR]",
	" * Integrators: md/md-vv/md-vv-avek, sd/sd1 and bd.\n",
	" * Long-range interactions (option coulombtype): Reaction-Field, Ewald, PME, and cut-off (for Implicit Solvent only)\n",
	" * Temperature control: Supported only with the md/md-vv/md-vv-avek, sd/sd1 and bd integrators.\n",
	" * Pressure control: Supported.\n",
	" * Implicit solvent: Supported.\n",
	"A detailed description can be found on the GROMACS website:\n",
	"http://www.gromacs.org/gpu[PAR]",
/* From the original mdrun documentaion */
    "The mdrun program reads the run input file ([TT]-s[tt])",
    "and distributes the topology over nodes if needed.",
    "mdrun produces at least four output files.",
    "A single log file ([TT]-g[tt]) is written, unless the option",
    "[TT]-seppot[tt] is used, in which case each node writes a log file.",
    "The trajectory file ([TT]-o[tt]), contains coordinates, velocities and",
    "optionally forces.",
    "The structure file ([TT]-c[tt]) contains the coordinates and",
    "velocities of the last step.",
    "The energy file ([TT]-e[tt]) contains energies, the temperature,",
    "pressure, etc, a lot of these things are also printed in the log file.",
    "Optionally coordinates can be written to a compressed trajectory file",
    "([TT]-x[tt]).[PAR]",
/* openmm specific information */
	"Usage with OpenMM:[BR]",
	"$ mdrun -device \"OpenMM:platform=Cuda,memtest=15,deviceid=0,force-device=no\"[PAR]",
	"Options:[PAR]",
	"      [TT]platform[tt] = Cuda\t\t:\tThe only available value. OpenCL support will be available in future.\n",
	"      [TT]memtest[tt] = 15\t\t:\tRun a partial, random GPU memory test for the given amount of seconds. A full test",
	"(recommended!) can be run with \"memtest=full\". Memory testing can be disabled with \"memtest=off\".\n",
	"      [TT]deviceid[tt] = 0\t\t:\tSpecify the target device when multiple cards are present.",
	"Only one card can be used at any given time though.\n",
	"      [TT]force-device[tt] = no\t\t:\tIf set to \"yes\" mdrun  will be forced to execute on",
	"hardware that is not officially supported. GPU acceleration can also be achieved on older",
	"but Cuda capable cards, although the simulation might be too slow, and the memory limits too strict.",
#else
    "The mdrun program is the main computational chemistry engine",
    "within GROMACS. Obviously, it performs Molecular Dynamics simulations,",
    "but it can also perform Stochastic Dynamics, Energy Minimization,",
    "test particle insertion or (re)calculation of energies.",
    "Normal mode analysis is another option. In this case mdrun",
    "builds a Hessian matrix from single conformation.",
    "For usual Normal Modes-like calculations, make sure that",
    "the structure provided is properly energy-minimized.",
    "The generated matrix can be diagonalized by g_nmeig.[PAR]",
    "The mdrun program reads the run input file ([TT]-s[tt])",
    "and distributes the topology over nodes if needed.",
    "mdrun produces at least four output files.",
    "A single log file ([TT]-g[tt]) is written, unless the option",
    "[TT]-seppot[tt] is used, in which case each node writes a log file.",
    "The trajectory file ([TT]-o[tt]), contains coordinates, velocities and",
    "optionally forces.",
    "The structure file ([TT]-c[tt]) contains the coordinates and",
    "velocities of the last step.",
    "The energy file ([TT]-e[tt]) contains energies, the temperature,",
    "pressure, etc, a lot of these things are also printed in the log file.",
    "Optionally coordinates can be written to a compressed trajectory file",
    "([TT]-x[tt]).[PAR]",
    "The option [TT]-dhdl[tt] is only used when free energy calculation is",
    "turned on.[PAR]",
    "When mdrun is started using MPI with more than 1 node, parallelization",
    "is used. By default domain decomposition is used, unless the [TT]-pd[tt]",
    "option is set, which selects particle decomposition.[PAR]",
    "With domain decomposition, the spatial decomposition can be set",
    "with option [TT]-dd[tt]. By default mdrun selects a good decomposition.",
    "The user only needs to change this when the system is very inhomogeneous.",
    "Dynamic load balancing is set with the option [TT]-dlb[tt],",
    "which can give a significant performance improvement,",
    "especially for inhomogeneous systems. The only disadvantage of",
    "dynamic load balancing is that runs are no longer binary reproducible,",
    "but in most cases this is not important.",
    "By default the dynamic load balancing is automatically turned on",
    "when the measured performance loss due to load imbalance is 5% or more.",
    "At low parallelization these are the only important options",
    "for domain decomposition.",
    "At high parallelization the options in the next two sections",
    "could be important for increasing the performace.",
    "[PAR]",
    "When PME is used with domain decomposition, separate nodes can",
    "be assigned to do only the PME mesh calculation;",
    "this is computationally more efficient starting at about 12 nodes.",
    "The number of PME nodes is set with option [TT]-npme[tt],",
    "this can not be more than half of the nodes.",
    "By default mdrun makes a guess for the number of PME",
    "nodes when the number of nodes is larger than 11 or performance wise",
    "not compatible with the PME grid x dimension.",
    "But the user should optimize npme. Performance statistics on this issue",
    "are written at the end of the log file.",
    "For good load balancing at high parallelization, the PME grid x and y",
    "dimensions should be divisible by the number of PME nodes",
    "(the simulation will run correctly also when this is not the case).",
    "[PAR]",
    "This section lists all options that affect the domain decomposition.",
    "[BR]",
    "Option [TT]-rdd[tt] can be used to set the required maximum distance",
    "for inter charge-group bonded interactions.",
    "Communication for two-body bonded interactions below the non-bonded",
    "cut-off distance always comes for free with the non-bonded communication.",
    "Atoms beyond the non-bonded cut-off are only communicated when they have",
    "missing bonded interactions; this means that the extra cost is minor",
    "and nearly indepedent of the value of [TT]-rdd[tt].",
    "With dynamic load balancing option [TT]-rdd[tt] also sets",
    "the lower limit for the domain decomposition cell sizes.",
    "By default [TT]-rdd[tt] is determined by mdrun based on",
    "the initial coordinates. The chosen value will be a balance",
    "between interaction range and communication cost.",
    "[BR]",
    "When inter charge-group bonded interactions are beyond",
    "the bonded cut-off distance, mdrun terminates with an error message.",
    "For pair interactions and tabulated bonds",
    "that do not generate exclusions, this check can be turned off",
    "with the option [TT]-noddcheck[tt].",
    "[BR]",
    "When constraints are present, option [TT]-rcon[tt] influences",
    "the cell size limit as well.",
    "Atoms connected by NC constraints, where NC is the LINCS order plus 1,",
    "should not be beyond the smallest cell size. A error message is",
    "generated when this happens and the user should change the decomposition",
    "or decrease the LINCS order and increase the number of LINCS iterations.",
    "By default mdrun estimates the minimum cell size required for P-LINCS",
    "in a conservative fashion. For high parallelization it can be useful",
    "to set the distance required for P-LINCS with the option [TT]-rcon[tt].",
    "[BR]",
    "The [TT]-dds[tt] option sets the minimum allowed x, y and/or z scaling",
    "of the cells with dynamic load balancing. mdrun will ensure that",
    "the cells can scale down by at least this factor. This option is used",
    "for the automated spatial decomposition (when not using [TT]-dd[tt])",
    "as well as for determining the number of grid pulses, which in turn",
    "sets the minimum allowed cell size. Under certain circumstances",
    "the value of [TT]-dds[tt] might need to be adjusted to account for",
    "high or low spatial inhomogeneity of the system.",
    "[PAR]",
    "The option [TT]-gcom[tt] can be used to only do global communication",
    "every n steps.",
    "This can improve performance for highly parallel simulations",
    "where this global communication step becomes the bottleneck.",
    "For a global thermostat and/or barostat the temperature",
    "and/or pressure will also only be updated every -gcom steps.",
    "By default it is set to the minimum of nstcalcenergy and nstlist.[PAR]",
    "With [TT]-rerun[tt] an input trajectory can be given for which ",
    "forces and energies will be (re)calculated. Neighbor searching will be",
    "performed for every frame, unless [TT]nstlist[tt] is zero",
    "(see the [TT].mdp[tt] file).[PAR]",
    "ED (essential dynamics) sampling is switched on by using the [TT]-ei[tt]",
    "flag followed by an [TT].edi[tt] file.",
    "The [TT].edi[tt] file can be produced using options in the essdyn",
    "menu of the WHAT IF program. mdrun produces a [TT].edo[tt] file that",
    "contains projections of positions, velocities and forces onto selected",
    "eigenvectors.[PAR]",
    "When user-defined potential functions have been selected in the",
    "[TT].mdp[tt] file the [TT]-table[tt] option is used to pass mdrun",
    "a formatted table with potential functions. The file is read from",
    "either the current directory or from the GMXLIB directory.",
    "A number of pre-formatted tables are presented in the GMXLIB dir,",
    "for 6-8, 6-9, 6-10, 6-11, 6-12 Lennard Jones potentials with",
    "normal Coulomb.",
    "When pair interactions are present a separate table for pair interaction",
    "functions is read using the [TT]-tablep[tt] option.[PAR]",
    "When tabulated bonded functions are present in the topology,",
    "interaction functions are read using the [TT]-tableb[tt] option.",
    "For each different tabulated interaction type the table file name is",
    "modified in a different way: before the file extension an underscore is",
    "appended, then a b for bonds, an a for angles or a d for dihedrals",
    "and finally the table number of the interaction type.[PAR]",
    "The options [TT]-px[tt] and [TT]-pf[tt] are used for writing pull COM",
    "coordinates and forces when pulling is selected",
    "in the [TT].mdp[tt] file.[PAR]",
    "With [TT]-multi[tt] multiple systems are simulated in parallel.",
    "As many input files are required as the number of systems.",
    "The system number is appended to the run input and each output filename,",
    "for instance topol.tpr becomes topol0.tpr, topol1.tpr etc.",
    "The number of nodes per system is the total number of nodes",
    "divided by the number of systems.",
    "One use of this option is for NMR refinement: when distance",
    "or orientation restraints are present these can be ensemble averaged",
    "over all the systems.[PAR]",
    "With [TT]-replex[tt] replica exchange is attempted every given number",
    "of steps. The number of replicas is set with the [TT]-multi[tt] option,",
    "see above.",
    "All run input files should use a different coupling temperature,",
    "the order of the files is not important. The random seed is set with",
    "[TT]-reseed[tt]. The velocities are scaled and neighbor searching",
    "is performed after every exchange.[PAR]",
    "Finally some experimental algorithms can be tested when the",
    "appropriate options have been given. Currently under",
    "investigation are: polarizability, and X-Ray bombardments.",
    "[PAR]",
    "The option [TT]-pforce[tt] is useful when you suspect a simulation",
    "crashes due to too large forces. With this option coordinates and",
    "forces of atoms with a force larger than a certain value will",
    "be printed to stderr.",
    "[PAR]",
    "Checkpoints containing the complete state of the system are written",
    "at regular intervals (option [TT]-cpt[tt]) to the file [TT]-cpo[tt],",
    "unless option [TT]-cpt[tt] is set to -1.",
    "The previous checkpoint is backed up to [TT]state_prev.cpt[tt] to",
    "make sure that a recent state of the system is always available,",
    "even when the simulation is terminated while writing a checkpoint.",
    "With [TT]-cpnum[tt] all checkpoint files are kept and appended",
    "with the step number.",
    "A simulation can be continued by reading the full state from file",
    "with option [TT]-cpi[tt]. This option is intelligent in the way that",
    "if no checkpoint file is found, Gromacs just assumes a normal run and",
    "starts from the first step of the tpr file. By default the output",
    "will be appending to the existing output files. The checkpoint file",
    "contains checksums of all output files, such that you will never",
    "loose data when some output files are modified, corrupt or removed.",
    "There are three scenarios with [TT]-cpi[tt]:[BR]",
    "* no files with matching names are present: new output files are written[BR]",
    "* all files are present with names and checksums matching those stored",
    "in the checkpoint file: files are appended[BR]",
    "* otherwise no files are modified and a fatal error is generated[BR]",
    "With [TT]-noappend[tt] new output files are opened and the simulation",
    "part number is added to all output file names.",
    "Note that in all cases the checkpoint file itself is not renamed",
    "and will be overwritten, unless its name does not match",
    "the [TT]-cpo[tt] option.",
    "[PAR]",
    "With checkpointing the output is appended to previously written",
    "output files, unless [TT]-noappend[tt] is used or none of the previous",
    "output files are present (except for the checkpoint file).",
    "The integrity of the files to be appended is verified using checksums",
    "which are stored in the checkpoint file. This ensures that output can",
    "not be mixed up or corrupted due to file appending. When only some",
    "of the previous output files are present, a fatal error is generated",
    "and no old output files are modified and no new output files are opened.",
    "The result with appending will be the same as from a single run.",
    "The contents will be binary identical, unless you use a different number",
    "of nodes or dynamic load balancing or the FFT library uses optimizations",
    "through timing.",
    "[PAR]",
    "With option [TT]-maxh[tt] a simulation is terminated and a checkpoint",
    "file is written at the first neighbor search step where the run time",
    "exceeds [TT]-maxh[tt]*0.99 hours.",
    "[PAR]",
    "When mdrun receives a TERM signal, it will set nsteps to the current",
    "step plus one. When mdrun receives an INT signal (e.g. when ctrl+C is",
    "pressed), it will stop after the next neighbor search step ",
    "(with nstlist=0 at the next step).",
    "In both cases all the usual output will be written to file.",
    "When running with MPI, a signal to one of the mdrun processes",
    "is sufficient, this signal should not be sent to mpirun or",
    "the mdrun process that is the parent of the others.",
    "[PAR]",
    "When mdrun is started with MPI, it does not run niced by default."
#endif
  };
  t_commrec    *cr;
  t_filenm fnm[] = {
    { efTPX, NULL,      NULL,       ffREAD },
    { efTRN, "-o",      NULL,       ffWRITE },
    { efXTC, "-x",      NULL,       ffOPTWR },
    { efCPT, "-cpi",    NULL,       ffOPTRD },
    { efCPT, "-cpo",    NULL,       ffOPTWR },
    { efSTO, "-c",      "confout",  ffWRITE },
    { efEDR, "-e",      "ener",     ffWRITE },
    { efLOG, "-g",      "md",       ffWRITE },
    { efXVG, "-dhdl",   "dhdl",     ffOPTWR },
    { efXVG, "-field",  "field",    ffOPTWR },
    { efXVG, "-table",  "table",    ffOPTRD },
    { efXVG, "-tablep", "tablep",   ffOPTRD },
    { efXVG, "-tableb", "table",    ffOPTRD },
    { efTRX, "-rerun",  "rerun",    ffOPTRD },
    { efXVG, "-tpi",    "tpi",      ffOPTWR },
    { efXVG, "-tpid",   "tpidist",  ffOPTWR },
    { efEDI, "-ei",     "sam",      ffOPTRD },
    { efEDO, "-eo",     "sam",      ffOPTWR },
    { efGCT, "-j",      "wham",     ffOPTRD },
    { efGCT, "-jo",     "bam",      ffOPTWR },
    { efXVG, "-ffout",  "gct",      ffOPTWR },
    { efXVG, "-devout", "deviatie", ffOPTWR },
    { efXVG, "-runav",  "runaver",  ffOPTWR },
    { efXVG, "-px",     "pullx",    ffOPTWR },
    { efXVG, "-pf",     "pullf",    ffOPTWR },
    { efMTX, "-mtx",    "nm",       ffOPTWR },
    { efNDX, "-dn",     "dipole",   ffOPTWR }
  };
#define NFILE asize(fnm)

  /* Command line options ! */
  gmx_bool bCart        = FALSE;
  gmx_bool bPPPME       = FALSE;
  gmx_bool bPartDec     = FALSE;
  gmx_bool bDDBondCheck = TRUE;
  gmx_bool bDDBondComm  = TRUE;
  gmx_bool bVerbose     = FALSE;
  gmx_bool bCompact     = TRUE;
  gmx_bool bSepPot      = FALSE;
  gmx_bool bRerunVSite  = FALSE;
  gmx_bool bIonize      = FALSE;
  gmx_bool bConfout     = TRUE;
  gmx_bool bReproducible = FALSE;

  //nrego - new GIST variables
 gmx_bool bGist = FALSE;
  //nrego - end mod

  int  npme=-1;
  int  nmultisim=0;
  int  nstglobalcomm=-1;
  int  repl_ex_nst=0;
  int  repl_ex_seed=-1;
  int  nstepout=100;
  int  nthreads=0; /* set to determine # of threads automatically */
  int  resetstep=-1;
  
  rvec realddxyz={0,0,0};
  const char *ddno_opt[ddnoNR+1] =
    { NULL, "interleave", "pp_pme", "cartesian", NULL };
    const char *dddlb_opt[] =
    { NULL, "auto", "no", "yes", NULL };
  real rdd=0.0,rconstr=0.0,dlb_scale=0.8,pforce=-1;
  char *ddcsx=NULL,*ddcsy=NULL,*ddcsz=NULL;
  real cpt_period=15.0,max_hours=-1;
  gmx_bool bAppendFiles=TRUE;
  gmx_bool bKeepAndNumCPT=FALSE;
  gmx_bool bResetCountersHalfWay=FALSE;
  output_env_t oenv=NULL;
  const char *deviceOptions = "";

  t_pargs pa[] = {

    { "-pd",      FALSE, etBOOL,{&bPartDec},
      "Use particle decompostion" },
    { "-dd",      FALSE, etRVEC,{&realddxyz},
      "Domain decomposition grid, 0 is optimize" },
#ifdef GMX_THREADS
    { "-nt",      FALSE, etINT, {&nthreads},
      "Number of threads to start (0 is guess)" },
#endif
    { "-npme",    FALSE, etINT, {&npme},
      "Number of separate nodes to be used for PME, -1 is guess" },
    { "-ddorder", FALSE, etENUM, {ddno_opt},
      "DD node order" },
    { "-ddcheck", FALSE, etBOOL, {&bDDBondCheck},
      "Check for all bonded interactions with DD" },
    { "-ddbondcomm", FALSE, etBOOL, {&bDDBondComm},
      "HIDDENUse special bonded atom communication when -rdd > cut-off" },
    { "-rdd",     FALSE, etREAL, {&rdd},
      "The maximum distance for bonded interactions with DD (nm), 0 is determine from initial coordinates" },
    { "-rcon",    FALSE, etREAL, {&rconstr},
      "Maximum distance for P-LINCS (nm), 0 is estimate" },
    { "-dlb",     FALSE, etENUM, {dddlb_opt},
      "Dynamic load balancing (with DD)" },
    { "-dds",     FALSE, etREAL, {&dlb_scale},
      "Minimum allowed dlb scaling of the DD cell size" },
    { "-ddcsx",   FALSE, etSTR, {&ddcsx},
      "HIDDENThe DD cell sizes in x" },
    { "-ddcsy",   FALSE, etSTR, {&ddcsy},
      "HIDDENThe DD cell sizes in y" },
    { "-ddcsz",   FALSE, etSTR, {&ddcsz},
      "HIDDENThe DD cell sizes in z" },
    { "-gcom",    FALSE, etINT,{&nstglobalcomm},
      "Global communication frequency" },
    { "-v",       FALSE, etBOOL,{&bVerbose},  
      "Be loud and noisy" },
    { "-compact", FALSE, etBOOL,{&bCompact},  
      "Write a compact log file" },
    { "-seppot",  FALSE, etBOOL, {&bSepPot},
      "Write separate V and dVdl terms for each interaction type and node to the log file(s)" },
    { "-pforce",  FALSE, etREAL, {&pforce},
      "Print all forces larger than this (kJ/mol nm)" },
    { "-reprod",  FALSE, etBOOL,{&bReproducible},  
      "Try to avoid optimizations that affect binary reproducibility" },
    { "-cpt",     FALSE, etREAL, {&cpt_period},
      "Checkpoint interval (minutes)" },
    { "-cpnum",   FALSE, etBOOL, {&bKeepAndNumCPT},
      "Keep and number checkpoint files" },
    { "-append",  FALSE, etBOOL, {&bAppendFiles},
      "Append to previous output files when continuing from checkpoint instead of adding the simulation part number to all file names" },
    { "-maxh",   FALSE, etREAL, {&max_hours},
      "Terminate after 0.99 times this time (hours)" },
    { "-multi",   FALSE, etINT,{&nmultisim}, 
      "Do multiple simulations in parallel" },
    { "-replex",  FALSE, etINT, {&repl_ex_nst}, 
      "Attempt replica exchange every # steps" },
    { "-reseed",  FALSE, etINT, {&repl_ex_seed}, 
      "Seed for replica exchange, -1 is generate a seed" },
    { "-rerunvsite", FALSE, etBOOL, {&bRerunVSite},
      "HIDDENRecalculate virtual site coordinates with -rerun" },
    { "-ionize",  FALSE, etBOOL,{&bIonize},
      "Do a simulation including the effect of an X-Ray bombardment on your system" },
    { "-confout", FALSE, etBOOL, {&bConfout},
      "HIDDENWrite the last configuration with -c and force checkpointing at the last step" },
    { "-stepout", FALSE, etINT, {&nstepout},
      "HIDDENFrequency of writing the remaining runtime" },
    { "-resetstep", FALSE, etINT, {&resetstep},
      "HIDDENReset cycle counters after these many time steps" },
    { "-resethway", FALSE, etBOOL, {&bResetCountersHalfWay},
      "HIDDENReset the cycle counters after half the number of steps or halfway -maxh" },
// Nrego - new command line options for running GIST
    { "-gist", FALSE, etBOOL, { &bGist }, 
      "Do GIST - option only matters if '-rerun' used" },
// end nrego mod
#ifdef GMX_OPENMM
    ,
    { "-device",  FALSE, etSTR, {&deviceOptions},
      "Device option string" }
#endif
  };
  gmx_edsam_t  ed;
  unsigned long Flags, PCA_Flags;
  ivec     ddxyz;
  int      dd_node_order;
  gmx_bool     bAddPart;
  FILE     *fplog,*fptest;
  int      sim_part,sim_part_fn;
  const char *part_suffix=".part";
  char     suffix[STRLEN];
  int      rc;



  cr = init_par(&argc,&argv);

  if (MASTER(cr))
    CopyRight(stderr, argv[0]);

  PCA_Flags = (PCA_KEEP_ARGS | PCA_NOEXIT_ON_ARGS | PCA_CAN_SET_DEFFNM
	       | (MASTER(cr) ? 0 : PCA_QUIET));
  

  /* Comment this in to do fexist calls only on master
   * works not with rerun or tables at the moment
   * also comment out the version of init_forcerec in md.c 
   * with NULL instead of opt2fn
   */
  /*
     if (!MASTER(cr))
     {
     PCA_Flags |= PCA_NOT_READ_NODE;
     }
     */

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

  /* we set these early because they might be used in init_multisystem() 
     Note that there is the potential for npme>nnodes until the number of
     threads is set later on, if there's thread parallelization. That shouldn't
     lead to problems. */ 
  dd_node_order = nenum(ddno_opt);
  cr->npmenodes = npme;

#ifndef GMX_THREADS
  nthreads=1;
#endif


  if (repl_ex_nst != 0 && nmultisim < 2)
      gmx_fatal(FARGS,"Need at least two replicas for replica exchange (option -multi)");

  if (nmultisim > 1) {
#ifndef GMX_THREADS
    init_multisystem(cr,nmultisim,NFILE,fnm,TRUE);
#else
    gmx_fatal(FARGS,"mdrun -multi is not supported with the thread library.Please compile GROMACS with MPI support");
#endif
  }

  bAddPart = !bAppendFiles;

  /* Check if there is ANY checkpoint file available */	
  sim_part    = 1;
  sim_part_fn = sim_part;
  if (opt2bSet("-cpi",NFILE,fnm))
  {
      if (bSepPot && bAppendFiles)
      {
          gmx_fatal(FARGS,"Output file appending is not supported with -seppot");
      }

      bAppendFiles =
                read_checkpoint_simulation_part(opt2fn_master("-cpi", NFILE,
                                                              fnm,cr),
                                                &sim_part_fn,NULL,cr,
                                                bAppendFiles,NFILE,fnm,
                                                part_suffix,&bAddPart);
      if (sim_part_fn==0 && MASTER(cr))
      {
          fprintf(stdout,"No previous checkpoint file present, assuming this is a new run.\n");
      }
      else
      {
          sim_part = sim_part_fn + 1;
      }
  } 
  else
  {
      bAppendFiles = FALSE;
  }

  if (!bAppendFiles)
  {
      sim_part_fn = sim_part;
  }

  if (bAddPart)
  {
      /* Rename all output files (except checkpoint files) */
      /* create new part name first (zero-filled) */
      sprintf(suffix,"%s%04d",part_suffix,sim_part_fn);

      add_suffix_to_output_names(fnm,NFILE,suffix);
      if (MASTER(cr))
      {
          fprintf(stdout,"Checkpoint file is from part %d, new output files will be suffixed '%s'.\n",sim_part-1,suffix);
      }
  }

  Flags = opt2bSet("-rerun",NFILE,fnm) ? MD_RERUN : 0;
  Flags = Flags | (bSepPot       ? MD_SEPPOT       : 0);
  Flags = Flags | (bIonize       ? MD_IONIZE       : 0);
  Flags = Flags | (bPartDec      ? MD_PARTDEC      : 0);
  Flags = Flags | (bDDBondCheck  ? MD_DDBONDCHECK  : 0);
  Flags = Flags | (bDDBondComm   ? MD_DDBONDCOMM   : 0);
  Flags = Flags | (bConfout      ? MD_CONFOUT      : 0);
  Flags = Flags | (bRerunVSite   ? MD_RERUN_VSITE  : 0);
  Flags = Flags | (bReproducible ? MD_REPRODUCIBLE : 0);
  Flags = Flags | (bAppendFiles  ? MD_APPENDFILES  : 0); 
  Flags = Flags | (bKeepAndNumCPT ? MD_KEEPANDNUMCPT : 0); 
  Flags = Flags | (sim_part>1    ? MD_STARTFROMCPT : 0); 
  Flags = Flags | (bResetCountersHalfWay ? MD_RESETCOUNTERSHALFWAY : 0);


  /* We postpone opening the log file if we are appending, so we can 
     first truncate the old log file and append to the correct position 
     there instead.  */
  if ((MASTER(cr) || bSepPot) && !bAppendFiles) 
  {
      gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,!bSepPot,Flags,&fplog);
      CopyRight(fplog,argv[0]);
      please_cite(fplog,"Hess2008b");
      please_cite(fplog,"Spoel2005a");
      please_cite(fplog,"Lindahl2001a");
      please_cite(fplog,"Berendsen95a");
  }
  else if (!MASTER(cr) && bSepPot)
  {
      gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,!bSepPot,Flags,&fplog);
  }
  else
  {
      fplog = NULL;
  }

  ddxyz[XX] = (int)(realddxyz[XX] + 0.5);
  ddxyz[YY] = (int)(realddxyz[YY] + 0.5);
  ddxyz[ZZ] = (int)(realddxyz[ZZ] + 0.5);


  rc = mdrunner(nthreads, fplog,cr,NFILE,fnm,oenv,bVerbose,bCompact,
                nstglobalcomm, ddxyz,dd_node_order,rdd,rconstr,
                dddlb_opt[0],dlb_scale,ddcsx,ddcsy,ddcsz,
                nstepout,resetstep,nmultisim,repl_ex_nst,repl_ex_seed,
                pforce, cpt_period,max_hours,deviceOptions,Flags
                //Nrego mod
                ,bGist
                //end nrego mod
                );

  if (gmx_parallel_env_initialized())
      gmx_finalize();

  if (MULTIMASTER(cr)) {
      thanx(stderr);
  }

  /* Log file has to be closed in mdrunner if we are appending to it 
     (fplog not set here) */
  if (MASTER(cr) && !bAppendFiles) 
  {
      gmx_log_close(fplog);
  }

  return rc;
}
static void dump_remd_parameters(FILE *gp,t_remd_data *d,const char *fn,
				 const char *fn2,const char *rfn,
				 const char *efn,const char *mfn,int skip,real tref,
				 output_env_t oenv)
{
  FILE *fp,*hp;
  int  i,j,np=d->nparams;
  real rhs,tauf,taub,fff,DG;
  real *params;
  const char *leg[] = { "Measured", "Fit", "Difference" };
  const char *mleg[] = { "Folded fraction","DG (kJ/mole)"};
  char **rleg;
  real fac[] = { 0.97, 0.98, 0.99, 1.0, 1.01, 1.02, 1.03 };
#define NFAC asize(fac)
  real d2[NFAC];
  double norm;
    
  integrate_dfdt(d);
  print_tau(gp,d,tref);
  norm = (d->bDiscrete ? 1.0/d->nmask : 1.0);
  
  if (fn) {
    fp = xvgropen(fn,"Optimized fit to data","Time (ps)","Fraction Folded",oenv);
    xvgr_legend(fp,asize(leg),leg,oenv);
    for(i=0; (i<d->nframe); i++) {
      if ((skip <= 0) || ((i % skip) == 0)) {
	fprintf(fp,"%12.5e  %12.5e  %12.5e  %12.5e\n",d->time[i],
		d->sumft[i]*norm,d->sumfct[i]*norm,
		(d->sumft[i]-d->sumfct[i])*norm);
      }
    }
    ffclose(fp);
  }
  if (!d->bSum && rfn) {
    snew(rleg,d->nreplica*2);
    for(i=0; (i<d->nreplica); i++) {
      snew(rleg[2*i],32);
      snew(rleg[2*i+1],32);
      sprintf(rleg[2*i],"\\f{4}F(t) %d",i);
      sprintf(rleg[2*i+1],"\\f{12}F \\f{4}(t) %d",i);
    }
    fp = xvgropen(rfn,"Optimized fit to data","Time (ps)","Fraction Folded",oenv);
    xvgr_legend(fp,d->nreplica*2,(const char**)rleg,oenv);
    for(j=0; (j<d->nframe); j++) {
      if ((skip <= 0) || ((j % skip) == 0)) {
	fprintf(fp,"%12.5e",d->time[j]);
	for(i=0; (i<d->nreplica); i++) 
	  fprintf(fp,"  %5f  %9.2e",is_folded(d,i,j),d->fcalt[i][j]);
	fprintf(fp,"\n");
      }
    }
    ffclose(fp);
  }

  if (fn2 && (d->nstate > 2)) {
    fp = xvgropen(fn2,"Optimized fit to data","Time (ps)",
		  "Fraction Intermediate",oenv);
    xvgr_legend(fp,asize(leg),leg,oenv);
    for(i=0; (i<d->nframe); i++) {
      if ((skip <= 0) || ((i % skip) == 0))
	fprintf(fp,"%12.5e  %12.5e  %12.5e  %12.5e\n",d->time[i],
		d->sumit[i]*norm,d->sumict[i]*norm,
		(d->sumit[i]-d->sumict[i])*norm);
    }
    ffclose(fp);
  }
  if (mfn) {
    if (bBack(d)) {
      fp = xvgropen(mfn,"Melting curve","T (K)","",oenv);
      xvgr_legend(fp,asize(mleg),mleg,oenv);
      for(i=260; (i<=420); i++) {
	tauf = tau(d->params[epAuf],d->params[epEuf],1.0*i);
	taub = tau(d->params[epAfu],d->params[epEfu],1.0*i);
	fff  = taub/(tauf+taub);
	DG   = BOLTZ*i*log(fff/(1-fff));
	fprintf(fp,"%5d  %8.3f  %8.3f\n",i,fff,DG);
      }
      ffclose(fp);
    }
  }
  
  if (efn) {
    snew(params,d->nparams);
    for(i=0; (i<d->nparams); i++)
      params[i] = d->params[i];
    
    hp = xvgropen(efn,"Chi2 as a function of relative parameter",
		  "Fraction","Chi2",oenv);
    for(j=0; (j<d->nparams); j++) {
      /* Reset all parameters to optimized values */
      fprintf(hp,"@type xy\n");
      for(i=0; (i<d->nparams); i++) 
	d->params[i] = params[i];
      /* Now modify one of them */
      for(i=0; (i<NFAC); i++) {
	d->params[j] = fac[i]*params[j];
	d2[i] = calc_d2(d);
	fprintf(gp,"%s = %12g  d2 = %12g\n",epnm(np,j),d->params[j],d2[i]);
	fprintf(hp,"%12g  %12g\n",fac[i],d2[i]);
      }
      fprintf(hp,"&\n");
    }
    ffclose(hp);
    for(i=0; (i<d->nparams); i++) 
      d->params[i] = params[i];
    sfree(params);
  }
  if (!d->bSum) {
    for(i=0; (i<d->nreplica); i++)
      fprintf(gp,"Chi2[%3d] = %8.2e\n",i,d->d2_replica[i]);
  }
}
示例#29
0
文件: g_x2top.c 项目: hasagar/gromacs
int cmain(int argc, char *argv[])
{
    const char        *desc[] = {
        "[TT]g_x2top[tt] generates a primitive topology from a coordinate file.",
        "The program assumes all hydrogens are present when defining",
        "the hybridization from the atom name and the number of bonds.",
        "The program can also make an [TT].rtp[tt] entry, which you can then add",
        "to the [TT].rtp[tt] database.[PAR]",
        "When [TT]-param[tt] is set, equilibrium distances and angles",
        "and force constants will be printed in the topology for all",
        "interactions. The equilibrium distances and angles are taken",
        "from the input coordinates, the force constant are set with",
        "command line options.",
        "The force fields somewhat supported currently are:[PAR]",
        "G53a5  GROMOS96 53a5 Forcefield (official distribution)[PAR]",
        "oplsaa OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)[PAR]",
        "The corresponding data files can be found in the library directory",
        "with name [TT]atomname2type.n2t[tt]. Check Chapter 5 of the manual for more",
        "information about file formats. By default, the force field selection",
        "is interactive, but you can use the [TT]-ff[tt] option to specify",
        "one of the short names above on the command line instead. In that",
        "case [TT]g_x2top[tt] just looks for the corresponding file.[PAR]",
    };
    const char        *bugs[] = {
        "The atom type selection is primitive. Virtually no chemical knowledge is used",
        "Periodic boundary conditions screw up the bonding",
        "No improper dihedrals are generated",
        "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew."
    };
    FILE              *fp;
    t_params           plist[F_NRE];
    t_excls           *excls;
    t_atoms           *atoms; /* list with all atoms */
    gpp_atomtype_t     atype;
    t_nextnb           nnb;
    t_nm2type         *nm2t;
    t_mols             mymol;
    gmx_atomprop_t     aps;
    int                nnm;
    char               title[STRLEN], forcefield[32], ffdir[STRLEN];
    rvec              *x; /* coordinates? */
    int               *nbonds, *cgnr;
    int                bts[] = { 1, 1, 1, 2 };
    matrix             box;    /* box length matrix */
    int                natoms; /* number of atoms in one molecule  */
    int                nres;   /* number of molecules? */
    int                i, j, k, l, m, ndih;
    int                epbc;
    gmx_bool           bRTP, bTOP, bOPLS;
    t_symtab           symtab;
    real               cutoff, qtot, mtot;
    char               n2t[STRLEN];
    output_env_t       oenv;

    t_filenm           fnm[] = {
        { efSTX, "-f", "conf", ffREAD  },
        { efTOP, "-o", "out",  ffOPTWR },
        { efRTP, "-r", "out",  ffOPTWR }
    };
#define NFILE asize(fnm)
    static real        scale = 1.1, kb = 4e5, kt = 400, kp = 5;
    static t_restp     rtp_header_settings;
    static gmx_bool    bRemoveDihedralIfWithImproper = FALSE;
    static gmx_bool    bGenerateHH14Interactions     = TRUE;
    static gmx_bool    bKeepAllGeneratedDihedrals    = FALSE;
    static int         nrexcl                        = 3;
    static gmx_bool    bParam                        = TRUE, bRound = TRUE;
    static gmx_bool    bPairs                        = TRUE, bPBC = TRUE;
    static gmx_bool    bUsePDBcharge                 = FALSE, bVerbose = FALSE;
    static const char *molnm                         = "ICE";
    static const char *ff                            = "oplsaa";
    t_pargs            pa[]                          = {
        { "-ff",     FALSE, etSTR, {&ff},
          "Force field for your simulation. Type \"select\" for interactive selection." },
        { "-v",      FALSE, etBOOL, {&bVerbose},
          "Generate verbose output in the top file." },
        { "-nexcl", FALSE, etINT,  {&nrexcl},
          "Number of exclusions" },
        { "-H14",    FALSE, etBOOL, {&bGenerateHH14Interactions},
          "Use 3rd neighbour interactions for hydrogen atoms" },
        { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals},
          "Generate all proper dihedrals" },
        { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper},
          "Remove dihedrals on the same bond as an improper" },
        { "-pairs",  FALSE, etBOOL, {&bPairs},
          "Output 1-4 interactions (pairs) in topology file" },
        { "-name",   FALSE, etSTR,  {&molnm},
          "Name of your molecule" },
        { "-pbc",    FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions." },
        { "-pdbq",  FALSE, etBOOL, {&bUsePDBcharge},
          "Use the B-factor supplied in a [TT].pdb[tt] file for the atomic charges" },
        { "-param", FALSE, etBOOL, {&bParam},
          "Print parameters in the output" },
        { "-round",  FALSE, etBOOL, {&bRound},
          "Round off measured values" },
        { "-kb",    FALSE, etREAL, {&kb},
          "Bonded force constant (kJ/mol/nm^2)" },
        { "-kt",    FALSE, etREAL, {&kt},
          "Angle force constant (kJ/mol/rad^2)" },
        { "-kp",    FALSE, etREAL, {&kp},
          "Dihedral angle force constant (kJ/mol/rad^2)" }
    };

    CopyRight(stderr, argv[0]);

    parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                      asize(desc), desc, asize(bugs), bugs, &oenv);
    bRTP = opt2bSet("-r", NFILE, fnm);
    bTOP = opt2bSet("-o", NFILE, fnm);
    /* C89 requirements mean that these struct members cannot be used in
     * the declaration of pa. So some temporary variables are needed. */
    rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper;
    rtp_header_settings.bGenerateHH14Interactions     = bGenerateHH14Interactions;
    rtp_header_settings.bKeepAllGeneratedDihedrals    = bKeepAllGeneratedDihedrals;
    rtp_header_settings.nrexcl = nrexcl;

    if (!bRTP && !bTOP)
    {
        gmx_fatal(FARGS, "Specify at least one output file");
    }

    aps = gmx_atomprop_init();

    /* Force field selection, interactive or direct */
    choose_ff(strcmp(ff, "select") == 0 ? NULL : ff,
              forcefield, sizeof(forcefield),
              ffdir, sizeof(ffdir));

    bOPLS = (strcmp(forcefield, "oplsaa") == 0);


    mymol.name = strdup(molnm);
    mymol.nr   = 1;

    /* Init parameter lists */
    init_plist(plist);

    /* Read coordinates */
    get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms);
    snew(atoms, 1);

    /* make space for all the atoms */
    init_t_atoms(atoms, natoms, TRUE);
    snew(x, natoms);

    read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, NULL, &epbc, box);

    sprintf(n2t, "%s", ffdir);
    nm2t = rd_nm2type(n2t, &nnm);
    if (nnm == 0)
    {
        gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)",
                  n2t);
    }
    else
    {
        printf("There are %d name to type translations in file %s\n", nnm, n2t);
    }
    if (debug)
    {
        dump_nm2type(debug, nnm, nm2t);
    }
    printf("Generating bonds from distances...\n");
    snew(nbonds, atoms->nr);
    mk_bonds(nnm, nm2t, atoms, x, &(plist[F_BONDS]), nbonds, forcefield,
             bPBC, box, aps);

    open_symtab(&symtab);
    atype = set_atom_type(&symtab, atoms, &(plist[F_BONDS]), nbonds, nnm, nm2t);

    /* Make Angles and Dihedrals */
    snew(excls, atoms->nr);
    printf("Generating angles and dihedrals from bonds...\n");
    init_nnb(&nnb, atoms->nr, 4);
    gen_nnb(&nnb, plist);
    print_nnb(&nnb, "NNB");
    gen_pad(&nnb, atoms, &rtp_header_settings, plist, excls, NULL, TRUE);
    done_nnb(&nnb);

    if (!bPairs)
    {
        plist[F_LJ14].nr = 0;
    }
    fprintf(stderr,
            "There are %4d %s dihedrals, %4d impropers, %4d angles\n"
            "          %4d pairs,     %4d bonds and  %4d atoms\n",
            plist[F_PDIHS].nr,
            bOPLS ? "Ryckaert-Bellemans" : "proper",
            plist[F_IDIHS].nr, plist[F_ANGLES].nr,
            plist[F_LJ14].nr, plist[F_BONDS].nr, atoms->nr);

    calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box);

    set_force_const(plist, kb, kt, kp, bRound, bParam);

    cgnr = set_cgnr(atoms, bUsePDBcharge, &qtot, &mtot);
    printf("Total charge is %g, total mass is %g\n", qtot, mtot);
    if (bOPLS)
    {
        bts[2] = 3;
        bts[3] = 1;
    }

    if (bTOP)
    {
        fp = ftp2FILE(efTOP, NFILE, fnm, "w");
        print_top_header(fp, ftp2fn(efTOP, NFILE, fnm),
                         "Generated by x2top", TRUE, ffdir, 1.0);

        write_top(fp, NULL, mymol.name, atoms, FALSE, bts, plist, excls, atype,
                  cgnr, rtp_header_settings.nrexcl);
        print_top_mols(fp, mymol.name, ffdir, NULL, 0, NULL, 1, &mymol);

        ffclose(fp);
    }
    if (bRTP)
    {
        print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top",
                  atoms, plist, atype, cgnr, asize(bts), bts);
    }

    if (debug)
    {
        dump_hybridization(debug, atoms, nbonds);
    }
    close_symtab(&symtab);
    free(mymol.name);

    printf("\nWARNING: topologies generated by %s can not be trusted at face value.\n", Program());
    printf("         Please verify atomtypes and charges by comparison to other\n");
    printf("         topologies.\n");

    thanx(stderr);

    return 0;
}
示例#30
0
int main(int argc,char *argv[])
{
  FILE *fp;
  const char *desc[] = {
    "testac tests the functioning of the GROMACS acf routines"
  };
  static int nframes = 1024;
  static int datatp  = 0;
  static real a=0.02*M_PI;
  output_env_t oenv;
  t_pargs pa[] = {
    { "-np", FALSE, etINT, &nframes,
      "Number of data points" },
    { "-dtp",FALSE, etINT, &datatp,
      "Which data: 0=all 0.0, 1=all 1.0, 2=cos(a t), 3=random, 4=cos(a t)+random, 5=sin(a t)/(a t)" }
  };
  static char *str[] = {
    "all 0.0", 
    "all 1.0",
    "cos(a t)",
    "random", 
    "cos(a t)+random",
    "sin(a t)/(a t)"
  };
  t_filenm fnm[] = {
    { efXVG, "-d", "acf-data", ffWRITE },
    { efXVG, "-c", "acf-corr", ffWRITE },
    { efXVG, "-comb", "acf-comb.xvg", ffWRITE }
  };
#define NFILE asize(fnm)
  int     npargs,i,nlag;
  int     seed=1993;
  real    *data,*data2,x;
  t_pargs *ppa;
  
  CopyRight(stderr,argv[0]);
  npargs = asize(pa);
  ppa    = add_acf_pargs(&npargs,pa);
  parse_common_args_r(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
		      NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv);
  snew(data,nframes);
  snew(data2,nframes);
  
  fp = xvgropen(opt2fn("-d",NFILE,fnm),"testac","x","y",oenv);
  for(i=0; (i<nframes); i++) {
    x = a*i;
    switch (datatp) {
    case 1:
      data[i] = 1;
      break;
    case 2:
      data[i] = cos(x);
      break;
    case 3:
      data[i] = 2*rando(&seed)-1.0;
      break;
    case 4:
      data[i] = cos(x)+2*rando(&seed)-1.0;
      break;
    case 5:
      if (i==0)
        data[i] = 1;
      else
        data[i] = sin(x)/(x);
      break;
    default:
      /* Data remains 0.0 */
      break;
    }
    fprintf(fp,"%10g  %10g\n",x,data[i]);
    data2[i] = data[i];
  }
  ffclose(fp);
  
  do_autocorr(opt2fn("-c",NFILE,fnm),oenv,str[datatp],
	      nframes,1,&data,a,eacNormal,FALSE);
	      
  nlag = get_acfnout();
  fp = xvgropen(opt2fn("-comb",NFILE,fnm),"testac","x","y",oenv);
  for(i=0; (i<nlag); i++) {
    fprintf(fp,"%10g  %10g  %10g\n",a*i,data2[i],data[i]);
  }
  ffclose(fp);

  do_view(opt2fn("-c",NFILE,fnm),"-nxy");
    
  thanx(stderr);

  return 0;
}