static bool step_man(t_manager *man, int *nat)
{
    static int      ncount = 0;
    static bool     bWarn  = false;
    bool            bEof;
    const char     *warn;

    if (!man->natom)
    {
        fprintf(stderr, "Not initiated yet!");
        exit(1);
    }
    bEof = read_next_x(man->oenv, man->status, &man->time, man->x, man->box);
    *nat = man->natom;
    if (ncount == man->nSkip)
    {
        switch (man->molw->boxtype)
        {
            case esbTri:
                put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, man->natom, man->x);
                break;
            case esbTrunc:
                warn = put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
                                                     man->natom, man->x);
                if (warn && !bWarn)
                {
                    fprintf(stderr, "\n%s\n", warn);
                    bWarn = true;
                }
                break;
            case esbRect:
            case esbNone:
            default:
                break;
        }
        if (man->bPbc)
        {
            gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
            reset_mols(&(man->top.mols), man->box, man->x);
        }
        ncount = 0;
    }
    else
    {
        if (man->nSkip > 0)
        {
            ncount++;
            return step_man(man, nat);
        }
    }

    return bEof;
}
Exemplo n.º 2
0
static bool step_man(t_manager *man, int *nat)
{
    static int      ncount = 0;
    bool            bEof;

    if (!man->natom)
    {
        std::fprintf(stderr, "Not initiated yet!");
        std::exit(1);
    }
    bEof = read_next_x(man->oenv, man->status, &man->time, man->x, man->box);
    *nat = man->natom;
    if (ncount == man->nSkip)
    {
        auto atomsArrayRef = gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(man->x), man->natom);
        switch (man->molw->boxtype)
        {
            case esbTri:
                put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, atomsArrayRef);
                break;
            case esbTrunc:
                put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
                                              atomsArrayRef);
                break;
            case esbRect:
            case esbNone:
            default:
                break;
        }
        if (man->bPbc)
        {
            gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
            reset_mols(&(man->top.mols), man->box, man->x);
        }
        ncount = 0;
    }
    else
    {
        if (man->nSkip > 0)
        {
            ncount++;
            return step_man(man, nat);
        }
    }

    return bEof;
}
Exemplo n.º 3
0
static void calc_dihs(t_xrama *xr)
{
    int          i, t1, t2, t3;
    rvec         r_ij, r_kj, r_kl, m, n;
    t_dih       *dd;
    gmx_rmpbc_t  gpbc = nullptr;

    gpbc = gmx_rmpbc_init(xr->idef, xr->ePBC, xr->natoms);
    gmx_rmpbc(gpbc, xr->natoms, xr->box, xr->x);
    gmx_rmpbc_done(gpbc);

    for (i = 0; (i < xr->ndih); i++)
    {
        dd      = &(xr->dih[i]);
        dd->ang = dih_angle(xr->x[dd->ai[0]], xr->x[dd->ai[1]],
                            xr->x[dd->ai[2]], xr->x[dd->ai[3]],
                            nullptr,
                            r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3);
    }
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
int gmx_polystat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] plots static properties of polymers as a function of time",
        "and prints the average.[PAR]",
        "By default it determines the average end-to-end distance and radii",
        "of gyration of polymers. It asks for an index group and split this",
        "into molecules. The end-to-end distance is then determined using",
        "the first and the last atom in the index group for each molecules.",
        "For the radius of gyration the total and the three principal components",
        "for the average gyration tensor are written.",
        "With option [TT]-v[tt] the eigenvectors are written.",
        "With option [TT]-pc[tt] also the average eigenvalues of the individual",
        "gyration tensors are written.",
        "With option [TT]-i[tt] the mean square internal distances are",
        "written.[PAR]",
        "With option [TT]-p[tt] the persistence length is determined.",
        "The chosen index group should consist of atoms that are",
        "consecutively bonded in the polymer mainchains.",
        "The persistence length is then determined from the cosine of",
        "the angles between bonds with an index difference that is even,",
        "the odd pairs are not used, because straight polymer backbones",
        "are usually all trans and therefore only every second bond aligns.",
        "The persistence length is defined as number of bonds where",
        "the average cos reaches a value of 1/e. This point is determined",
        "by a linear interpolation of [LOG]<cos>[log]."
    };
    static gmx_bool bMW  = TRUE, bPC = FALSE;
    t_pargs         pa[] = {
        { "-mw", FALSE, etBOOL, {&bMW},
          "Use the mass weighting for radii of gyration" },
        { "-pc", FALSE, etBOOL, {&bPC},
          "Plot average eigenvalues" }
    };

    t_filenm        fnm[] = {
        { efTPR, nullptr, nullptr,  ffREAD  },
        { efTRX, "-f", nullptr,  ffREAD  },
        { efNDX, nullptr, nullptr,  ffOPTRD },
        { efXVG, "-o", "polystat",  ffWRITE },
        { efXVG, "-v", "polyvec", ffOPTWR },
        { efXVG, "-p", "persist",  ffOPTWR },
        { efXVG, "-i", "intdist", ffOPTWR }
    };
#define NFILE asize(fnm)

    t_topology       *top;
    gmx_output_env_t *oenv;
    int               ePBC;
    int               isize, *index, nmol, *molind, mol, nat_min = 0, nat_max = 0;
    char             *grpname;
    t_trxstatus      *status;
    real              t;
    rvec             *x, *bond = nullptr;
    matrix            box;
    int               natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = {0};
    dvec              cm, sum_eig = {0, 0, 0};
    double          **gyr, **gyr_all, eig[DIM], **eigv;
    double            sum_eed2, sum_eed2_tot, sum_gyro, sum_gyro_tot, sum_pers_tot;
    int              *ninp    = nullptr;
    double           *sum_inp = nullptr, pers;
    double           *intd, ymax, ymin;
    double            mmol, m;
    char              title[STRLEN];
    FILE             *out, *outv, *outp, *outi;
    const char       *leg[8] = {
        "end to end", "<R\\sg\\N>",
        "<R\\sg\\N> eig1", "<R\\sg\\N> eig2", "<R\\sg\\N> eig3",
        "<R\\sg\\N eig1>", "<R\\sg\\N eig2>", "<R\\sg\\N eig3>"
    };
    char            **legp, buf[STRLEN];
    gmx_rmpbc_t       gpbc = nullptr;

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

    snew(top, 1);
    ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm),
                        nullptr, box, &natoms, nullptr, nullptr, top);

    fprintf(stderr, "Select a group of polymer mainchain atoms:\n");
    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm),
              1, &isize, &index, &grpname);

    snew(molind, top->mols.nr+1);
    nmol = 0;
    mol  = -1;
    for (i = 0; i < isize; i++)
    {
        if (i == 0 || index[i] >= top->mols.index[mol+1])
        {
            molind[nmol++] = i;
            do
            {
                mol++;
            }
            while (index[i] >= top->mols.index[mol+1]);
        }
    }
    molind[nmol] = i;
    nat_min      = top->atoms.nr;
    nat_max      = 0;
    for (mol = 0; mol < nmol; mol++)
    {
        nat_min = std::min(nat_min, molind[mol+1]-molind[mol]);
        nat_max = std::max(nat_max, molind[mol+1]-molind[mol]);
    }
    fprintf(stderr, "Group %s consists of %d molecules\n", grpname, nmol);
    fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n",
            nat_min, nat_max);

    sprintf(title, "Size of %d polymers", nmol);
    out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)",
                   oenv);
    xvgr_legend(out, bPC ? 8 : 5, leg, oenv);

    if (opt2bSet("-v", NFILE, fnm))
    {
        outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components",
                        output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
        snew(legp, DIM*DIM);
        for (d = 0; d < DIM; d++)
        {
            for (d2 = 0; d2 < DIM; d2++)
            {
                sprintf(buf, "eig%d %c", d+1, 'x'+d2);
                legp[d*DIM+d2] = gmx_strdup(buf);
            }
        }
        xvgr_legend(outv, DIM*DIM, (const char**)legp, oenv);
    }
    else
    {
        outv = nullptr;
    }

    if (opt2bSet("-p", NFILE, fnm))
    {
        outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length",
                        output_env_get_xvgr_tlabel(oenv), "bonds", oenv);
        snew(bond, nat_max-1);
        snew(sum_inp, nat_min/2);
        snew(ninp, nat_min/2);
    }
    else
    {
        outp = nullptr;
    }

    if (opt2bSet("-i", NFILE, fnm))
    {
        outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances",
                        "n", "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv);
        i = index[molind[1]-1] - index[molind[0]]; /* Length of polymer -1 */
        snew(intd, i);
    }
    else
    {
        intd = nullptr;
        outi = nullptr;
    }

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

    snew(gyr, DIM);
    snew(gyr_all, DIM);
    snew(eigv, DIM);
    for (d = 0; d < DIM; d++)
    {
        snew(gyr[d], DIM);
        snew(gyr_all[d], DIM);
        snew(eigv[d], DIM);
    }

    frame        = 0;
    sum_eed2_tot = 0;
    sum_gyro_tot = 0;
    sum_pers_tot = 0;

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

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

        sum_eed2 = 0;
        for (d = 0; d < DIM; d++)
        {
            clear_dvec(gyr_all[d]);
        }

        if (bPC)
        {
            clear_dvec(sum_eig);
        }

        if (outp)
        {
            for (i = 0; i < nat_min/2; i++)
            {
                sum_inp[i] = 0;
                ninp[i]    = 0;
            }
        }

        for (mol = 0; mol < nmol; mol++)
        {
            ind0 = molind[mol];
            ind1 = molind[mol+1];

            /* Determine end to end distance */
            sum_eed2 += distance2(x[index[ind0]], x[index[ind1-1]]);

            /* Determine internal distances */
            if (outi)
            {
                calc_int_dist(intd, x, index[ind0], index[ind1-1]);
            }

            /* Determine the radius of gyration */
            clear_dvec(cm);
            for (d = 0; d < DIM; d++)
            {
                clear_dvec(gyr[d]);
            }
            mmol = 0;

            for (i = ind0; i < ind1; i++)
            {
                a = index[i];
                if (bMW)
                {
                    m = top->atoms.atom[a].m;
                }
                else
                {
                    m = 1;
                }
                mmol += m;
                for (d = 0; d < DIM; d++)
                {
                    cm[d] += m*x[a][d];
                    for (d2 = 0; d2 < DIM; d2++)
                    {
                        gyr[d][d2] += m*x[a][d]*x[a][d2];
                    }
                }
            }
            dsvmul(1/mmol, cm, cm);
            for (d = 0; d < DIM; d++)
            {
                for (d2 = 0; d2 < DIM; d2++)
                {
                    gyr[d][d2]      = gyr[d][d2]/mmol - cm[d]*cm[d2];
                    gyr_all[d][d2] += gyr[d][d2];
                }
            }
            if (bPC)
            {
                gyro_eigen(gyr, eig, eigv, ord);
                for (d = 0; d < DIM; d++)
                {
                    sum_eig[d] += eig[ord[d]];
                }
            }
            if (outp)
            {
                for (i = ind0; i < ind1-1; i++)
                {
                    rvec_sub(x[index[i+1]], x[index[i]], bond[i-ind0]);
                    unitv(bond[i-ind0], bond[i-ind0]);
                }
                for (i = ind0; i < ind1-1; i++)
                {
                    for (j = 0; (i+j < ind1-1 && j < nat_min/2); j += 2)
                    {
                        sum_inp[j] += iprod(bond[i-ind0], bond[i-ind0+j]);
                        ninp[j]++;
                    }
                }
            }
        }
        sum_eed2 /= nmol;

        sum_gyro = 0;
        for (d = 0; d < DIM; d++)
        {
            for (d2 = 0; d2 < DIM; d2++)
            {
                gyr_all[d][d2] /= nmol;
            }
            sum_gyro += gyr_all[d][d];
        }

        gyro_eigen(gyr_all, eig, eigv, ord);

        fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f",
                t*output_env_get_time_factor(oenv),
                std::sqrt(sum_eed2), sqrt(sum_gyro),
                std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), std::sqrt(eig[ord[2]]));
        if (bPC)
        {
            for (d = 0; d < DIM; d++)
            {
                fprintf(out, " %8.4f", std::sqrt(sum_eig[d]/nmol));
            }
        }
        fprintf(out, "\n");

        if (outv)
        {
            fprintf(outv, "%10.3f", t*output_env_get_time_factor(oenv));
            for (d = 0; d < DIM; d++)
            {
                for (d2 = 0; d2 < DIM; d2++)
                {
                    fprintf(outv, " %6.3f", eigv[ord[d]][d2]);
                }
            }
            fprintf(outv, "\n");
        }

        sum_eed2_tot += sum_eed2;
        sum_gyro_tot += sum_gyro;

        if (outp)
        {
            i = -1;
            for (j = 0; j < nat_min/2; j += 2)
            {
                sum_inp[j] /= ninp[j];
                if (i == -1 && sum_inp[j] <= std::exp(-1.0))
                {
                    i = j;
                }
            }
            if (i == -1)
            {
                pers = j;
            }
            else
            {
                /* Do linear interpolation on a log scale */
                pers = i - 2.0
                    + 2.0*(std::log(sum_inp[i-2]) + 1.0)/(std::log(sum_inp[i-2]) - std::log(sum_inp[i]));
            }
            fprintf(outp, "%10.3f %8.4f\n", t*output_env_get_time_factor(oenv), pers);
            sum_pers_tot += pers;
        }

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

    gmx_rmpbc_done(gpbc);

    close_trx(status);

    xvgrclose(out);
    if (outv)
    {
        xvgrclose(outv);
    }
    if (outp)
    {
        xvgrclose(outp);
    }

    sum_eed2_tot /= frame;
    sum_gyro_tot /= frame;
    sum_pers_tot /= frame;
    fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n",
            std::sqrt(sum_eed2_tot));
    fprintf(stdout, "\nAverage radius of gyration:  %.3f (nm)\n",
            std::sqrt(sum_gyro_tot));
    if (opt2bSet("-p", NFILE, fnm))
    {
        fprintf(stdout, "\nAverage persistence length:  %.2f bonds\n",
                sum_pers_tot);
    }

    /* Handle printing of internal distances. */
    if (outi)
    {
        if (output_env_get_print_xvgr_codes(oenv))
        {
            fprintf(outi, "@    xaxes scale Logarithmic\n");
        }
        ymax = -1;
        ymin = 1e300;
        j    = index[molind[1]-1] - index[molind[0]]; /* Polymer length -1. */
        for (i = 0; i < j; i++)
        {
            intd[i] /= (i + 1) * frame * nmol;
            if (intd[i] > ymax)
            {
                ymax = intd[i];
            }
            if (intd[i] < ymin)
            {
                ymin = intd[i];
            }
        }
        xvgr_world(outi, 1, ymin, j, ymax, oenv);
        for (i = 0; i < j; i++)
        {
            fprintf(outi, "%d  %8.4f\n", i+1, intd[i]);
        }
        xvgrclose(outi);
    }

    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
    if (opt2bSet("-v", NFILE, fnm))
    {
        do_view(oenv, opt2fn("-v", NFILE, fnm), "-nxy");
    }
    if (opt2bSet("-p", NFILE, fnm))
    {
        do_view(oenv, opt2fn("-p", NFILE, fnm), "-nxy");
    }

    return 0;
}
Exemplo n.º 6
0
int main(int argc,char *argv[])
{
    const char *desc[] = {
	"[TT]do_multiprot[tt] ", 
	"reads a trajectory file and aligns it to a reference structure  ",
	"each time frame",
	"calling the multiprot program. This allows you to use a reference",
	"structure whose sequence is different than that of the protein in the ",
	"trajectory, since the alignment is based on the geometry, not sequence.",
	"The output of [TT]do_multiprot[tt] includes the rmsd and the number of residues",
	"on which it was calculated.",
	"[PAR]",
	"An aligned trajectory file is generated with the [TT]-ox[tt] option.[PAR]",
	"With the [TT]-cr[tt] option, the number of hits in the alignment is given",
	"per residue. This number can be between 0 and the number of frames, and",
	"indicates the structural conservation of this residue.[PAR]",
	"If you do not have the [TT]multiprot[tt] program, get it. [TT]do_multiprot[tt] assumes", 
	"that the [TT]multiprot[tt] executable is [TT]/usr/local/bin/multiprot[tt]. If this is ",
	"not the case, then you should set an environment variable [BB]MULTIPROT[bb]", 
	"pointing to the [TT]multiprot[tt] executable, e.g.: [PAR]",
	"[TT]setenv MULTIPROT /usr/MultiProtInstall/multiprot.Linux[tt][PAR]",
	"Note that at the current implementation only binary alignment (your",
	"molecule to a reference) is supported. In addition, note that the ",
	"by default [TT]multiprot[tt] aligns the two proteins on their C-alpha carbons.",
	"and that this depends on the [TT]multiprot[tt] parameters which are not dealt ",
	"with here. Thus, the C-alpha carbons is expected to give the same "
	"results as choosing the whole protein and will be slightly faster.[PAR]",
	"For information about [TT]multiprot[tt], see:",
	"http://bioinfo3d.cs.tau.ac.il/MultiProt/.[PAR]"
    };
    static bool bVerbose;
    t_pargs pa[] = {
	{ "-v",  FALSE, etBOOL, {&bVerbose},
	  "HIDDENGenerate miles of useless information" }
    };
  
    const char *bugs[] = { 
	"The program is very slow, since multiprot is run externally"
    };
  
    t_trxstatus *status;
    t_trxstatus *trxout=NULL;
    FILE        *tapein,*fo,*frc,*tmpf,*out=NULL,*fres=NULL;
    const char  *fnRef;
    const char  *fn="2_sol.res";
    t_topology  top;
    int         ePBC;
    t_atoms     *atoms,ratoms,useatoms;
    t_trxframe  fr;
    t_pdbinfo   p;
    int         nres,nres2,nr0;
    real        t;
    int         i,j,natoms,nratoms,nframe=0,model_nr=-1;
    int         cur_res,prev_res;
    int         nout;
    t_countres  *countres=NULL;
    matrix      box,rbox;
    int         gnx;
    char        *grpnm,*ss_str; 
    atom_id     *index;
    rvec        *xp,*x,*xr;
    char        pdbfile[32],refpdb[256],title[256],rtitle[256],filemode[5];
    char        out_title[256];
    char        multiprot[256],*mptr;
    int         ftp;
    int         outftp=-1;
    real        rmsd;
    bool        bTrjout,bCountres;
    const char  *TrjoutFile=NULL;
    output_env_t oenv;
    static rvec translation={0,0,0},rotangles={0,0,0};
    gmx_rmpbc_t gpbc=NULL;
    
    t_filenm   fnm[] = {
	{ efTRX, "-f",   NULL,      ffREAD },
	{ efTPS, NULL,   NULL,      ffREAD },
	{ efNDX, NULL,   NULL,      ffOPTRD },
	{ efSTX, "-r",   NULL     , ffREAD },
	{ efXVG, "-o",  "rmss",     ffWRITE },
	{ efXVG, "-rc", "rescount", ffWRITE},
	{ efXVG, "-cr", "countres", ffOPTWR},
	{ efTRX, "-ox", "aligned",  ffOPTWR }
    };
#define NFILE asize(fnm)
    
    CopyRight(stderr,argv[0]);
    parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT,
		      NFILE,fnm, asize(pa),pa, asize(desc),desc,
		      asize(bugs),bugs,&oenv
	);
    fnRef=opt2fn("-r",NFILE,fnm);
    bTrjout = opt2bSet("-ox",NFILE,fnm);
    bCountres=  opt2bSet("-cr",NFILE,fnm);
    
    if (bTrjout) {
	TrjoutFile = opt2fn_null("-ox",NFILE,fnm);
    }
    
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xp,NULL,box,FALSE);
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,box);
    atoms=&(top.atoms);

    ftp=fn2ftp(fnRef);
 
    get_stx_coordnum(fnRef,&nratoms);
    init_t_atoms(&ratoms,nratoms,TRUE);  
    snew(xr,nratoms);
    read_stx_conf(fnRef,rtitle,&ratoms,xr,NULL,&ePBC,rbox);
    
    if (bVerbose) {
	fprintf(stderr,"Read %d atoms\n",atoms->nr); 
	fprintf(stderr,"Read %d reference atoms\n",ratoms.nr); 
    }
    if (bCountres) {
	snew(countres,ratoms.nres);
	j=0;
	cur_res=0;
	for (i=0;i<ratoms.nr;i++) {
	    prev_res=cur_res;
	    cur_res=ratoms.atom[i].resind;
	    if (cur_res != prev_res) {
		countres[j].resnr=cur_res;
		countres[j].count=0;
		j++;
	    }
	}
    }
    get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpnm);
    nres=0;
    nr0=-1;
    for(i=0; (i<gnx); i++) {
	if (atoms->atom[index[i]].resind != nr0) {
	    nr0=atoms->atom[index[i]].resind;
	    nres++;
	}
    }
    fprintf(stderr,"There are %d residues in your selected group\n",nres);
    
    strcpy(pdbfile,"ddXXXXXX");
    gmx_tmpnam(pdbfile);
    if ((tmpf = fopen(pdbfile,"w")) == NULL) {
	sprintf(pdbfile,"%ctmp%cfilterXXXXXX",DIR_SEPARATOR,DIR_SEPARATOR);
	gmx_tmpnam(pdbfile);
	if ((tmpf = fopen(pdbfile,"w")) == NULL) {
	    gmx_fatal(FARGS,"Can not open tmp file %s",pdbfile);
	}
    }
    else {
	gmx_ffclose(tmpf);
    }

    if (ftp != efPDB) {
	strcpy(refpdb,"ddXXXXXX");
	gmx_tmpnam(refpdb);
	strcat(refpdb,".pdb");
	write_sto_conf(refpdb,rtitle,&ratoms,xr,NULL,ePBC,rbox);
    }
    else {
	strcpy(refpdb,fnRef);
    }

    if ((mptr=getenv("MULTIPROT")) == NULL) {
	mptr="/usr/local/bin/multiprot";
    }
    if (!gmx_fexist(mptr)) {
	gmx_fatal(FARGS,"MULTIPROT executable (%s) does not exist (use setenv MULTIPROT)",
		  mptr);
    }
    sprintf (multiprot,"%s %s %s > /dev/null %s",
	     mptr, refpdb, pdbfile, "2> /dev/null");
    
    if (bVerbose)
	fprintf(stderr,"multiprot cmd='%s'\n",multiprot);
    
    if (!read_first_frame(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_READ_X)) 
      	gmx_fatal(FARGS,"Could not read a frame from %s",ftp2fn(efTRX,NFILE,fnm));
    natoms = fr.natoms;

    if (bTrjout) {
	nout=natoms;
	/* open file now */
	outftp=fn2ftp(TrjoutFile);
	if (bVerbose)
	    fprintf(stderr,"Will write %s: %s\n",ftp2ext(ftp),ftp2desc(outftp));
	strcpy(filemode,"w");
	switch (outftp) {
	    case efXTC:
	    case efG87:
	    case efTRR:
	    case efTRJ:
		out=NULL;
		trxout = open_trx(TrjoutFile,filemode);
		break;
	    case efGRO:
	    case efG96:
	    case efPDB:
		/* Make atoms struct for output in GRO or PDB files */
		/* get memory for stuff to go in pdb file */
		init_t_atoms(&useatoms,nout,FALSE);
		sfree(useatoms.resinfo);
		useatoms.resinfo=atoms->resinfo;
		for(i=0;(i<nout);i++) {
		    useatoms.atomname[i]=atoms->atomname[i];
		    useatoms.atom[i]=atoms->atom[i];
		    useatoms.nres=max(useatoms.nres,useatoms.atom[i].resind+1);
		}
		useatoms.nr=nout;
		out=gmx_ffopen(TrjoutFile,filemode);
		break;
	}
    }
    
    if (natoms > atoms->nr) {
	gmx_fatal(FARGS,"\nTrajectory does not match topology!");
    }
    if (gnx > natoms) {
	gmx_fatal(FARGS,"\nTrajectory does not match selected group!");
    }

    fo = xvgropen(opt2fn("-o",NFILE,fnm),"RMSD","Time (ps)","RMSD (nm)",oenv);
    frc = xvgropen(opt2fn("-rc",NFILE,fnm),"Number of Residues in the alignment","Time (ps)","Residues",oenv);
    
    do {
	t = output_env_conv_time(oenv,fr.time);
	gmx_rmpbc(gpbc,natoms,fr.box,fr.x);
	tapein=gmx_ffopen(pdbfile,"w");
	write_pdbfile_indexed(tapein,NULL,atoms,fr.x,ePBC,fr.box,' ',-1,gnx,index,NULL,TRUE); 
	gmx_ffclose(tapein);
	system(multiprot);
	remove(pdbfile);
	process_multiprot_output(fn, &rmsd, &nres2,rotangles,translation,bCountres,countres);
	fprintf(fo,"%12.7f",t);
	fprintf(fo," %12.7f\n",rmsd);
	fprintf(frc,"%12.7f",t);
	fprintf(frc,"%12d\n",nres2);
	if (bTrjout) {
	    rotate_conf(natoms,fr.x,NULL,rotangles[XX],rotangles[YY],rotangles[ZZ]);
	    for(i=0; i<natoms; i++) {
		rvec_inc(fr.x[i],translation);
	    }
	    switch(outftp) {
		case efTRJ:
		case efTRR:
		case efG87:
		case efXTC:
		    write_trxframe(trxout,&fr,NULL);
		    break;
		case efGRO:
		case efG96:
		case efPDB:
		    sprintf(out_title,"Generated by do_multiprot : %s t= %g %s",
			    title,output_env_conv_time(oenv,fr.time),output_env_get_time_unit(oenv));
		    switch(outftp) {
			case efGRO: 
			    write_hconf_p(out,out_title,&useatoms,prec2ndec(fr.prec),
					  fr.x,NULL,fr.box);
			    break;
			case efPDB:
			    fprintf(out,"REMARK    GENERATED BY DO_MULTIPROT\n");
			    sprintf(out_title,"%s t= %g %s",title,output_env_conv_time(oenv,fr.time),output_env_get_time_unit(oenv));
			    /* if reading from pdb, we want to keep the original 
			       model numbering else we write the output frame
			       number plus one, because model 0 is not allowed in pdb */
			    if (ftp==efPDB && fr.step > model_nr) {
				model_nr = fr.step;
			    }
			    else {
				model_nr++;
			    }
			    write_pdbfile(out,out_title,&useatoms,fr.x,ePBC,fr.box,' ',model_nr,NULL,TRUE);
			    break;
			case efG96:
			    fr.title = out_title;
			    fr.bTitle = (nframe == 0);
			    fr.bAtoms = FALSE;
			    fr.bStep = TRUE;
			    fr.bTime = TRUE;
			    write_g96_conf(out,&fr,-1,NULL);
		    }
		    break;
	    }
	}
	nframe++;
    } while(read_next_frame(oenv,status,&fr));
    if (bCountres) {
	fres=  xvgropen(opt2fn("-cr",NFILE,fnm),"Number of frames in which the residues are aligned to","Residue","Number",oenv);
	for (i=0;i<ratoms.nres;i++) {
	    fprintf(fres,"%10d  %12d\n",countres[i].resnr,countres[i].count);
	}
	gmx_ffclose(fres);
    }
    gmx_ffclose(fo);
    gmx_ffclose(frc);
    fprintf(stderr,"\n");
    close_trj(status);
    if (trxout != NULL) {
	close_trx(trxout);
    }
    else if (out != NULL) {
	gmx_ffclose(out);
    }
    view_all(oenv,NFILE, fnm);
    sfree(xr);
    if (bCountres) {
	sfree(countres);
    }
    free_t_atoms(&ratoms,TRUE);
    if (bTrjout) {
	if (outftp==efPDB || outftp==efGRO || outftp==efG96) {
	    free_t_atoms(&useatoms,TRUE);
	}
    }
    gmx_thanx(stderr);
    return 0;
}
Exemplo n.º 7
0
int gmx_anaeig(int argc,char *argv[])
{
  static const char *desc[] = {
    "[TT]g_anaeig[tt] analyzes eigenvectors. The eigenvectors can be of a",
    "covariance matrix ([TT]g_covar[tt]) or of a Normal Modes analysis",
    "([TT]g_nmeig[tt]).[PAR]",
    
    "When a trajectory is projected on eigenvectors, all structures are",
    "fitted to the structure in the eigenvector file, if present, otherwise",
    "to the structure in the structure file. When no run input file is",
    "supplied, periodicity will not be taken into account. Most analyses",
    "are performed on eigenvectors [TT]-first[tt] to [TT]-last[tt], but when",
    "[TT]-first[tt] is set to -1 you will be prompted for a selection.[PAR]",
    
    "[TT]-comp[tt]: plot the vector components per atom of eigenvectors",
    "[TT]-first[tt] to [TT]-last[tt].[PAR]",
    
    "[TT]-rmsf[tt]: plot the RMS fluctuation per atom of eigenvectors",
    "[TT]-first[tt] to [TT]-last[tt] (requires [TT]-eig[tt]).[PAR]",

    "[TT]-proj[tt]: calculate projections of a trajectory on eigenvectors",
    "[TT]-first[tt] to [TT]-last[tt].",
    "The projections of a trajectory on the eigenvectors of its",
    "covariance matrix are called principal components (pc's).",
    "It is often useful to check the cosine content of the pc's,",
    "since the pc's of random diffusion are cosines with the number",
    "of periods equal to half the pc index.",
    "The cosine content of the pc's can be calculated with the program",
    "[TT]g_analyze[tt].[PAR]",
    
    "[TT]-2d[tt]: calculate a 2d projection of a trajectory on eigenvectors",
    "[TT]-first[tt] and [TT]-last[tt].[PAR]",
    
    "[TT]-3d[tt]: calculate a 3d projection of a trajectory on the first",
    "three selected eigenvectors.[PAR]",
    
    "[TT]-filt[tt]: filter the trajectory to show only the motion along",
    "eigenvectors [TT]-first[tt] to [TT]-last[tt].[PAR]",
    
    "[TT]-extr[tt]: calculate the two extreme projections along a trajectory",
    "on the average structure and interpolate [TT]-nframes[tt] frames",
    "between them, or set your own extremes with [TT]-max[tt]. The",
    "eigenvector [TT]-first[tt] will be written unless [TT]-first[tt] and",
    "[TT]-last[tt] have been set explicitly, in which case all eigenvectors",
    "will be written to separate files. Chain identifiers will be added",
    "when writing a [TT].pdb[tt] file with two or three structures (you",
    "can use [TT]rasmol -nmrpdb[tt] to view such a [TT].pdb[tt] file).[PAR]",
    
    "  Overlap calculations between covariance analysis:[BR]",
    "  [BB]Note:[bb] the analysis should use the same fitting structure[PAR]",
    
    "[TT]-over[tt]: calculate the subspace overlap of the eigenvectors in",
    "file [TT]-v2[tt] with eigenvectors [TT]-first[tt] to [TT]-last[tt]",
    "in file [TT]-v[tt].[PAR]",
    
    "[TT]-inpr[tt]: calculate a matrix of inner-products between",
    "eigenvectors in files [TT]-v[tt] and [TT]-v2[tt]. All eigenvectors",
    "of both files will be used unless [TT]-first[tt] and [TT]-last[tt]",
    "have been set explicitly.[PAR]",
    
    "When [TT]-v[tt], [TT]-eig[tt], [TT]-v2[tt] and [TT]-eig2[tt] are given,",
    "a single number for the overlap between the covariance matrices is",
    "generated. The formulas are:[BR]",
    "        difference = sqrt(tr((sqrt(M1) - sqrt(M2))^2))[BR]",
    "normalized overlap = 1 - difference/sqrt(tr(M1) + tr(M2))[BR]",
    "     shape overlap = 1 - sqrt(tr((sqrt(M1/tr(M1)) - sqrt(M2/tr(M2)))^2))[BR]",
    "where M1 and M2 are the two covariance matrices and tr is the trace",
    "of a matrix. The numbers are proportional to the overlap of the square",
    "root of the fluctuations. The normalized overlap is the most useful",
    "number, it is 1 for identical matrices and 0 when the sampled",
    "subspaces are orthogonal.[PAR]",
    "When the [TT]-entropy[tt] flag is given an entropy estimate will be",
    "computed based on the Quasiharmonic approach and based on",
    "Schlitter's formula."
  };
  static int  first=1,last=-1,skip=1,nextr=2,nskip=6;
  static real max=0.0,temp=298.15;
  static gmx_bool bSplit=FALSE,bEntropy=FALSE;
  t_pargs pa[] = {
    { "-first", FALSE, etINT, {&first},     
      "First eigenvector for analysis (-1 is select)" },
    { "-last",  FALSE, etINT, {&last}, 
      "Last eigenvector for analysis (-1 is till the last)" },
    { "-skip",  FALSE, etINT, {&skip},
      "Only analyse every nr-th frame" },
    { "-max",  FALSE, etREAL, {&max}, 
      "Maximum for projection of the eigenvector on the average structure, "
      "max=0 gives the extremes" },
    { "-nframes",  FALSE, etINT, {&nextr}, 
      "Number of frames for the extremes output" },
    { "-split",   FALSE, etBOOL, {&bSplit},
      "Split eigenvector projections where time is zero" },
    { "-entropy", FALSE, etBOOL, {&bEntropy},
      "Compute entropy according to the Quasiharmonic formula or Schlitter's method." },
    { "-temp",    FALSE, etREAL, {&temp},
      "Temperature for entropy calculations" },
    { "-nevskip", FALSE, etINT, {&nskip},
      "Number of eigenvalues to skip when computing the entropy due to the quasi harmonic approximation. When you do a rotational and/or translational fit prior to the covariance analysis, you get 3 or 6 eigenvalues that are very close to zero, and which should not be taken into account when computing the entropy." }
  };
#define NPA asize(pa)
  
  FILE       *out;
  int        status,trjout;
  t_topology top;
  int        ePBC=-1;
  t_atoms    *atoms=NULL;
  rvec       *xtop,*xref1,*xref2,*xrefp=NULL;
  gmx_bool       bDMR1,bDMA1,bDMR2,bDMA2;
  int        nvec1,nvec2,*eignr1=NULL,*eignr2=NULL;
  rvec       *x,*xread,*xav1,*xav2,**eigvec1=NULL,**eigvec2=NULL;
  matrix     topbox;
  real       xid,totmass,*sqrtm,*w_rls,t,lambda;
  int        natoms,step;
  char       *grpname;
  const char *indexfile;
  char       title[STRLEN];
  int        i,j,d;
  int        nout,*iout,noutvec,*outvec,nfit;
  atom_id    *index,*ifit;
  const char *VecFile,*Vec2File,*topfile;
  const char *EigFile,*Eig2File;
  const char *CompFile,*RmsfFile,*ProjOnVecFile;
  const char *TwoDPlotFile,*ThreeDPlotFile;
  const char *FilterFile,*ExtremeFile;
  const char *OverlapFile,*InpMatFile;
  gmx_bool       bFit1,bFit2,bM,bIndex,bTPS,bTop,bVec2,bProj;
  gmx_bool       bFirstToLast,bFirstLastSet,bTraj,bCompare,bPDB3D;
  real       *eigval1=NULL,*eigval2=NULL;
  int        neig1,neig2;
  double     **xvgdata;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc;

  t_filenm fnm[] = { 
    { efTRN, "-v",    "eigenvec",    ffREAD  },
    { efTRN, "-v2",   "eigenvec2",   ffOPTRD },
    { efTRX, "-f",    NULL,          ffOPTRD }, 
    { efTPS, NULL,    NULL,          ffOPTRD },
    { efNDX, NULL,    NULL,          ffOPTRD },
    { efXVG, "-eig", "eigenval",     ffOPTRD },
    { efXVG, "-eig2", "eigenval2",   ffOPTRD },
    { efXVG, "-comp", "eigcomp",     ffOPTWR },
    { efXVG, "-rmsf", "eigrmsf",     ffOPTWR },
    { efXVG, "-proj", "proj",        ffOPTWR },
    { efXVG, "-2d",   "2dproj",      ffOPTWR },
    { efSTO, "-3d",   "3dproj.pdb",  ffOPTWR },
    { efTRX, "-filt", "filtered",    ffOPTWR },
    { efTRX, "-extr", "extreme.pdb", ffOPTWR },
    { efXVG, "-over", "overlap",     ffOPTWR },
    { efXPM, "-inpr", "inprod",      ffOPTWR }
  }; 
#define NFILE asize(fnm) 

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

  indexfile=ftp2fn_null(efNDX,NFILE,fnm);

  VecFile         = opt2fn("-v",NFILE,fnm);
  Vec2File        = opt2fn_null("-v2",NFILE,fnm);
  topfile         = ftp2fn(efTPS,NFILE,fnm); 
  EigFile         = opt2fn_null("-eig",NFILE,fnm);
  Eig2File        = opt2fn_null("-eig2",NFILE,fnm);
  CompFile        = opt2fn_null("-comp",NFILE,fnm);
  RmsfFile        = opt2fn_null("-rmsf",NFILE,fnm);
  ProjOnVecFile   = opt2fn_null("-proj",NFILE,fnm);
  TwoDPlotFile    = opt2fn_null("-2d",NFILE,fnm);
  ThreeDPlotFile  = opt2fn_null("-3d",NFILE,fnm);
  FilterFile      = opt2fn_null("-filt",NFILE,fnm);
  ExtremeFile     = opt2fn_null("-extr",NFILE,fnm);
  OverlapFile     = opt2fn_null("-over",NFILE,fnm);
  InpMatFile      = ftp2fn_null(efXPM,NFILE,fnm);
  
  bTop   = fn2bTPX(topfile);
  bProj  = ProjOnVecFile || TwoDPlotFile || ThreeDPlotFile 
    || FilterFile || ExtremeFile;
  bFirstLastSet  = 
    opt2parg_bSet("-first",NPA,pa) && opt2parg_bSet("-last",NPA,pa);
  bFirstToLast = CompFile || RmsfFile || ProjOnVecFile || FilterFile ||
    OverlapFile || ((ExtremeFile || InpMatFile) && bFirstLastSet);
  bVec2  = Vec2File || OverlapFile || InpMatFile;
  bM     = RmsfFile || bProj;
  bTraj  = ProjOnVecFile || FilterFile || (ExtremeFile && (max==0))
    || TwoDPlotFile || ThreeDPlotFile;
  bIndex = bM || bProj;
  bTPS   = ftp2bSet(efTPS,NFILE,fnm) || bM || bTraj ||
    FilterFile  || (bIndex && indexfile);
  bCompare = Vec2File || Eig2File;
  bPDB3D = fn2ftp(ThreeDPlotFile)==efPDB;
  
  read_eigenvectors(VecFile,&natoms,&bFit1,
		    &xref1,&bDMR1,&xav1,&bDMA1,
		    &nvec1,&eignr1,&eigvec1,&eigval1);
  neig1 = DIM*natoms;
  
  /* Overwrite eigenvalues from separate files if the user provides them */
  if (EigFile != NULL) {
    int neig_tmp = read_xvg(EigFile,&xvgdata,&i);
    if (neig_tmp != neig1)
      fprintf(stderr,"Warning: number of eigenvalues in xvg file (%d) does not mtch trr file (%d)\n",neig1,natoms);
    neig1 = neig_tmp;
    srenew(eigval1,neig1);
    for(j=0;j<neig1;j++) {
      real tmp = eigval1[j];
      eigval1[j]=xvgdata[1][j];
      if (debug && (eigval1[j] != tmp))
	fprintf(debug,"Replacing eigenvalue %d. From trr: %10g, from xvg: %10g\n",
		j,tmp,eigval1[j]);
    }
    for(j=0;j<i;j++)
      sfree(xvgdata[j]);
    sfree(xvgdata);
    fprintf(stderr,"Read %d eigenvalues from %s\n",neig1,EigFile);
  }
    
  if (bEntropy) {
    if (bDMA1) {
      gmx_fatal(FARGS,"Can not calculate entropies from mass-weighted eigenvalues, redo the analysis without mass-weighting");
    }
    calc_entropy_qh(stdout,neig1,eigval1,temp,nskip);
    calc_entropy_schlitter(stdout,neig1,nskip,eigval1,temp);
  }
  
  if (bVec2) {
    if (!Vec2File)
      gmx_fatal(FARGS,"Need a second eigenvector file to do this analysis.");
    read_eigenvectors(Vec2File,&neig2,&bFit2,
		      &xref2,&bDMR2,&xav2,&bDMA2,&nvec2,&eignr2,&eigvec2,&eigval2);
    
    neig2 = DIM*neig2;
    if (neig2 != neig1)
      gmx_fatal(FARGS,"Dimensions in the eigenvector files don't match");
  }
  
  if(Eig2File != NULL) {
    neig2 = read_xvg(Eig2File,&xvgdata,&i);
    srenew(eigval2,neig2);
    for(j=0;j<neig2;j++)
      eigval2[j]=xvgdata[1][j];
    for(j=0;j<i;j++)
      sfree(xvgdata[j]);
    sfree(xvgdata);
    fprintf(stderr,"Read %d eigenvalues from %s\n",neig2,Eig2File);      
  }
  
  
  if ((!bFit1 || xref1) && !bDMR1 && !bDMA1) 
    bM=FALSE;
  if ((xref1==NULL) && (bM || bTraj))
    bTPS=TRUE;
  
  xtop=NULL;
  nfit=0;
  ifit=NULL;
  w_rls=NULL;

  if (!bTPS) {
    bTop=FALSE;
  } else {
    bTop=read_tps_conf(ftp2fn(efTPS,NFILE,fnm),
		       title,&top,&ePBC,&xtop,NULL,topbox,bM);
    atoms=&top.atoms;
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,atoms->nr,topbox);
    gmx_rmpbc(gpbc,atoms->nr,topbox,xtop);
    /* Fitting is only required for the projection */ 
    if (bProj && bFit1) {
      if (xref1 == NULL) {
	  printf("\nNote: the structure in %s should be the same\n"
		 "      as the one used for the fit in g_covar\n",topfile);
      }
      printf("\nSelect the index group that was used for the least squares fit in g_covar\n");
      get_index(atoms,indexfile,1,&nfit,&ifit,&grpname);

      snew(w_rls,atoms->nr);
      for(i=0; (i<nfit); i++) {
	if (bDMR1) {
	  w_rls[ifit[i]] = atoms->atom[ifit[i]].m;
	} else {
	  w_rls[ifit[i]] = 1.0;
	}
      }

      snew(xrefp,atoms->nr);
      if (xref1 != NULL) {
	for(i=0; (i<nfit); i++) {
	  copy_rvec(xref1[i],xrefp[ifit[i]]);
	}
      } else {
	/* The top coordinates are the fitting reference */
	for(i=0; (i<nfit); i++) {
	  copy_rvec(xtop[ifit[i]],xrefp[ifit[i]]);
	}
	reset_x(nfit,ifit,atoms->nr,NULL,xrefp,w_rls);
      }
    }
    gmx_rmpbc_done(gpbc);
  }

  if (bIndex) {
    printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n",natoms);
    get_index(atoms,indexfile,1,&i,&index,&grpname);
    if (i!=natoms)
      gmx_fatal(FARGS,"you selected a group with %d elements instead of %d",i,natoms);
      printf("\n");
  }
  
  snew(sqrtm,natoms);
  if (bM && bDMA1) {
    proj_unit="u\\S1/2\\Nnm";
    for(i=0; (i<natoms); i++)
      sqrtm[i]=sqrt(atoms->atom[index[i]].m);
  }
  else {
    proj_unit="nm";
    for(i=0; (i<natoms); i++)
      sqrtm[i]=1.0;
  }
  
  if (bVec2) {
    t=0;
    totmass=0;
    for(i=0; (i<natoms); i++)
      for(d=0;(d<DIM);d++) {
	t+=sqr((xav1[i][d]-xav2[i][d])*sqrtm[i]);
	totmass+=sqr(sqrtm[i]);
      }
    fprintf(stdout,"RMSD (without fit) between the two average structures:"
	    " %.3f (nm)\n\n",sqrt(t/totmass));
  }
  
  if (last==-1)
    last=natoms*DIM;
  if (first>-1) {
    if (bFirstToLast) {
      /* make an index from first to last */
      nout=last-first+1;
      snew(iout,nout);
      for(i=0; i<nout; i++)
	iout[i]=first-1+i;
    } 
    else if (ThreeDPlotFile) {
      /* make an index of first+(0,1,2) and last */
      nout = bPDB3D ? 4 : 3;
      nout = min(last-first+1, nout);
      snew(iout,nout);
      iout[0]=first-1;
      iout[1]=first;
      if (nout>3)
	iout[2]=first+1;
      iout[nout-1]=last-1;
    }
    else {
      /* make an index of first and last */
      nout=2;
      snew(iout,nout);
      iout[0]=first-1;
      iout[1]=last-1;
    }
  }
  else {
    printf("Select eigenvectors for output, end your selection with 0\n");
    nout=-1;
    iout=NULL;
    
    do {
      nout++;
      srenew(iout,nout+1);
      if(1 != scanf("%d",&iout[nout]))
      {
	  gmx_fatal(FARGS,"Error reading user input");
      }
      iout[nout]--;
    }
    while (iout[nout]>=0);
    
    printf("\n");
  }
  /* make an index of the eigenvectors which are present */
  snew(outvec,nout);
  noutvec=0;
  for(i=0; i<nout; i++) 
    {
      j=0;
      while ((j<nvec1) && (eignr1[j]!=iout[i]))
	j++;
      if ((j<nvec1) && (eignr1[j]==iout[i])) 
	{
	  outvec[noutvec]=j;
	  noutvec++;
	}
    }
  fprintf(stderr,"%d eigenvectors selected for output",noutvec);
  if (noutvec <= 100) 
    {
      fprintf(stderr,":");
      for(j=0; j<noutvec; j++)
	fprintf(stderr," %d",eignr1[outvec[j]]+1);
    }
  fprintf(stderr,"\n");
    
  if (CompFile)
    components(CompFile,natoms,eignr1,eigvec1,noutvec,outvec,oenv);
  
  if (RmsfFile)
    rmsf(RmsfFile,natoms,sqrtm,eignr1,eigvec1,noutvec,outvec,eigval1,
         neig1,oenv);
    
  if (bProj)
    project(bTraj ? opt2fn("-f",NFILE,fnm) : NULL,
	    bTop ? &top : NULL,ePBC,topbox,
	    ProjOnVecFile,TwoDPlotFile,ThreeDPlotFile,FilterFile,skip,
	    ExtremeFile,bFirstLastSet,max,nextr,atoms,natoms,index,
	    bFit1,xrefp,nfit,ifit,w_rls,
	    sqrtm,xav1,eignr1,eigvec1,noutvec,outvec,bSplit,
            oenv);
    
  if (OverlapFile)
    overlap(OverlapFile,natoms,
	    eigvec1,nvec2,eignr2,eigvec2,noutvec,outvec,oenv);
    
  if (InpMatFile)
    inprod_matrix(InpMatFile,natoms,
		  nvec1,eignr1,eigvec1,nvec2,eignr2,eigvec2,
		  bFirstLastSet,noutvec,outvec);
    
  if (bCompare)
    compare(natoms,nvec1,eigvec1,nvec2,eigvec2,eigval1,neig1,eigval2,neig2);
  
  
  if (!CompFile && !bProj && !OverlapFile && !InpMatFile && 
          !bCompare && !bEntropy)
  {
    fprintf(stderr,"\nIf you want some output,"
	    " set one (or two or ...) of the output file options\n");
  }
  
  
  view_all(oenv,NFILE, fnm);
  
  thanx(stdout);
  
  return 0;
}
Exemplo n.º 8
0
int gmx_dist(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_dist[tt] can calculate the distance between the centers of mass of two",
    "groups of atoms as a function of time. The total distance and its",
    "[IT]x[it]-, [IT]y[it]-, and [IT]z[it]-components are plotted.[PAR]",
    "Or when [TT]-dist[tt] is set, print all the atoms in group 2 that are",
    "closer than a certain distance to the center of mass of group 1.[PAR]",
    "With options [TT]-lt[tt] and [TT]-dist[tt] the number of contacts",
    "of all atoms in group 2 that are closer than a certain distance",
    "to the center of mass of group 1 are plotted as a function of the time",
    "that the contact was continuously present.[PAR]",
    "Other programs that calculate distances are [TT]g_mindist[tt]",
    "and [TT]g_bond[tt]."
  };
  
  t_topology *top=NULL;
  int  ePBC;
  real t,t0,cut2,dist2;
  rvec *x=NULL,*v=NULL,dx;
  matrix box;
  t_trxstatus *status;
  int natoms;

  int g,d,i,j,res,teller=0;
  atom_id aid;

  int     ngrps;     /* the number of index groups */
  atom_id **index,max;   /* the index for the atom numbers */
  int     *isize;    /* the size of each group */
  char    **grpname; /* the name of each group */
  rvec    *com;
  real    *mass;
  FILE    *fp=NULL,*fplt=NULL;
  gmx_bool    bCutoff,bPrintDist,bLifeTime;
  t_pbc   *pbc;
  int     *contact_time=NULL,*ccount=NULL,ccount_nalloc=0,sum;
  char    buf[STRLEN];
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;
  
  const char *leg[4] = { "|d|","d\\sx\\N","d\\sy\\N","d\\sz\\N" };

  static real cut=0;
  
  static t_pargs pa[] = {
    { "-dist",      FALSE, etREAL, {&cut},
      "Print all atoms in group 2 closer than dist to the center of mass of group 1" }
  };
#define NPA asize(pa)

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPX, NULL, NULL, ffREAD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, NULL, "dist", ffOPTWR },
    { efXVG, "-lt", "lifetime", ffOPTWR },
  };
#define NFILE asize(fnm)


  CopyRight(stderr,argv[0]);

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL,&oenv);
  
  bCutoff = opt2parg_bSet("-dist",NPA,pa);
  cut2 = cut*cut;
  bLifeTime = opt2bSet("-lt",NFILE,fnm);
  bPrintDist = (bCutoff && !bLifeTime);
  
  top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC);
  
  /* read index files */
  ngrps = 2;
  snew(com,ngrps);
  snew(grpname,ngrps);
  snew(index,ngrps);
  snew(isize,ngrps);
  get_index(&top->atoms,ftp2fn(efNDX,NFILE,fnm),ngrps,isize,index,grpname);
  
  /* calculate mass */
  max=0;
  snew(mass,ngrps);
  for(g=0;(g<ngrps);g++) {
    mass[g]=0;
    for(i=0;(i<isize[g]);i++) {
      if (index[g][i]>max)
	max=index[g][i];
      if (index[g][i] >= top->atoms.nr)
	gmx_fatal(FARGS,"Atom number %d, item %d of group %d, is larger than number of atoms in the topolgy (%d)\n",index[g][i]+1,i+1,g+1,top->atoms.nr+1);
      mass[g]+=top->atoms.atom[index[g][i]].m;
    }
  }

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

  if (max>=natoms)
    gmx_fatal(FARGS,"Atom number %d in an index group is larger than number of atoms in the trajectory (%d)\n",(int)max+1,natoms);

  if (!bCutoff) {
    /* open output file */
    fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),
		  "Distance","Time (ps)","Distance (nm)",oenv);
    xvgr_legend(fp,4,leg,oenv);
  } else {
    ngrps = 1;
    if (bLifeTime)
      snew(contact_time,isize[1]);
  }
  if (ePBC != epbcNONE)
    snew(pbc,1);
  else
    pbc = NULL;
    
  gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box);
  do {
    /* initialisation for correct distance calculations */
    if (pbc) {
      set_pbc(pbc,ePBC,box);
      /* make molecules whole again */
      gmx_rmpbc(gpbc,natoms,box,x);
    }
    /* calculate center of masses */
    for(g=0;(g<ngrps);g++) {
      if (isize[g] == 1) {
	copy_rvec(x[index[g][0]],com[g]);
      } else {
	for(d=0;(d<DIM);d++) {
	  com[g][d]=0;
	  for(i=0;(i<isize[g]);i++) {
	    com[g][d] += x[index[g][i]][d] * top->atoms.atom[index[g][i]].m;
	  }
	  com[g][d] /= mass[g];
	}
      }
    }
    
    if (!bCutoff) {
      /* write to output */
      fprintf(fp,"%12.7f ",t);
      for(g=0;(g<ngrps/2);g++) {
	if (pbc)
	  pbc_dx(pbc,com[2*g],com[2*g+1],dx);
	else
	  rvec_sub(com[2*g],com[2*g+1],dx);
	
	fprintf(fp,"%12.7f %12.7f %12.7f %12.7f",
		norm(dx),dx[XX],dx[YY],dx[ZZ]);
      }
      fprintf(fp,"\n");
    } else {
      for(i=0;(i<isize[1]);i++) { 
	j=index[1][i];
	if (pbc)
	  pbc_dx(pbc,x[j],com[0],dx);
	else
	  rvec_sub(x[j],com[0],dx);
	
	dist2 = norm2(dx);
	if (dist2<cut2) {
	  if (bPrintDist) {
	    res=top->atoms.atom[j].resind;
	    fprintf(stdout,"\rt: %g  %d %s %d %s  %g (nm)\n",
		    t,top->atoms.resinfo[res].nr,*top->atoms.resinfo[res].name,
		    j+1,*top->atoms.atomname[j],sqrt(dist2));
	  }
	  if (bLifeTime)
	    contact_time[i]++;
	} else {
	  if (bLifeTime) {
	    if (contact_time[i]) {
	      add_contact_time(&ccount,&ccount_nalloc,contact_time[i]-1);
	      contact_time[i] = 0;
	    }
	  }
	}
      }
    }
    
    teller++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));
  gmx_rmpbc_done(gpbc);

  if (!bCutoff)
    ffclose(fp);

  close_trj(status);
  
  if (bCutoff && bLifeTime) {
    /* Add the contacts still present in the last frame */
    for(i=0; i<isize[1]; i++)
      if (contact_time[i])
	add_contact_time(&ccount,&ccount_nalloc,contact_time[i]-1);

    sprintf(buf,"%s - %s within %g nm",
	    grpname[0],grpname[1],cut);
    fp = xvgropen(opt2fn("-lt",NFILE,fnm),
		  buf,"Time (ps)","Number of contacts",oenv);
    for(i=0; i<min(ccount_nalloc,teller-1); i++) {
      /* Account for all subintervals of longer intervals */
      sum = 0;
      for(j=i; j<ccount_nalloc; j++)
	sum += (j-i+1)*ccount[j];

      fprintf(fp,"%10.3f %10.3f\n",i*(t-t0)/(teller-1),sum/(double)(teller-i));
    }
    ffclose(fp);
  }
  
  thanx(stderr);
  return 0;
}
Exemplo n.º 9
0
int gmx_rms(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] compares two structures by computing the root mean square",
        "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter",
        "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ",
        "see Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).",
        "This is selected by [TT]-what[tt].[PAR]"

        "Each structure from a trajectory ([TT]-f[tt]) is compared to a",
        "reference structure. The reference structure",
        "is taken from the structure file ([TT]-s[tt]).[PAR]",

        "With option [TT]-mir[tt] also a comparison with the mirror image of",
        "the reference structure is calculated.",
        "This is useful as a reference for 'significant' values, see",
        "Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).[PAR]",

        "Option [TT]-prev[tt] produces the comparison with a previous frame",
        "the specified number of frames ago.[PAR]",

        "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of",
        "comparison values of each structure in the trajectory with respect to",
        "each other structure. This file can be visualized with for instance",
        "[TT]xv[tt] and can be converted to postscript with [gmx-xpm2ps].[PAR]",

        "Option [TT]-fit[tt] controls the least-squares fitting of",
        "the structures on top of each other: complete fit (rotation and",
        "translation), translation only, or no fitting at all.[PAR]",

        "Option [TT]-mw[tt] controls whether mass weighting is done or not.",
        "If you select the option (default) and ",
        "supply a valid [TT].tpr[tt] file masses will be taken from there, ",
        "otherwise the masses will be deduced from the [TT]atommass.dat[tt] file in",
        "[TT]GMXLIB[tt]. This is fine for proteins, but not",
        "necessarily for other molecules. A default mass of 12.011 amu (carbon)",
        "is assigned to unknown atoms. You can check whether this happend by",
        "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]",

        "With [TT]-f2[tt], the 'other structures' are taken from a second",
        "trajectory, this generates a comparison matrix of one trajectory",
        "versus the other.[PAR]",

        "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]",

        "Option [TT]-bm[tt] produces a matrix of average bond angle deviations",
        "analogously to the [TT]-m[tt] option. Only bonds between atoms in the",
        "comparison group are considered."
    };
    static gmx_bool bPBC              = TRUE, bFitAll = TRUE, bSplit = FALSE;
    static gmx_bool bDeltaLog         = FALSE;
    static int      prev              = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0;
    static real     rmsd_user_max     = -1, rmsd_user_min = -1, bond_user_max = -1,
                    bond_user_min     = -1, delta_maxy = 0.0;
    /* strings and things for selecting difference method */
    enum
    {
        ewSel, ewRMSD, ewRho, ewRhoSc, ewNR
    };
    int         ewhat;
    const char *what[ewNR + 1] =
    { NULL, "rmsd", "rho", "rhosc", NULL };
    const char *whatname[ewNR] =
    { NULL, "RMSD", "Rho", "Rho sc" };
    const char *whatlabel[ewNR] =
    { NULL, "RMSD (nm)", "Rho", "Rho sc" };
    const char *whatxvgname[ewNR] =
    { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    const char *whatxvglabel[ewNR] =
    { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    /* strings and things for fitting methods */
    enum
    {
        efSel, efFit, efReset, efNone, efNR
    };
    int             efit;
    const char     *fit[efNR + 1] =
    { NULL, "rot+trans", "translation", "none", NULL };
    const char     *fitgraphlabel[efNR + 1] =
    { NULL, "lsq fit", "translational fit", "no fit" };
    static int      nrms          = 1;
    static gmx_bool bMassWeighted = TRUE;
    t_pargs         pa[]          =
    {
        { "-what", FALSE, etENUM,
          { what }, "Structural difference measure" },
        { "-pbc", FALSE, etBOOL,
          { &bPBC }, "PBC check" },
        { "-fit", FALSE, etENUM,
          { fit }, "Fit to reference structure" },
        { "-prev", FALSE, etINT,
          { &prev }, "Compare with previous frame" },
        { "-split", FALSE, etBOOL,
          { &bSplit }, "Split graph where time is zero" },
        { "-fitall", FALSE, etBOOL,
          { &bFitAll }, "HIDDENFit all pairs of structures in matrix" },
        { "-skip", FALSE, etINT,
          { &freq }, "Only write every nr-th frame to matrix" },
        { "-skip2", FALSE, etINT,
          { &freq2 }, "Only write every nr-th frame to matrix" },
        { "-max", FALSE, etREAL,
          { &rmsd_user_max }, "Maximum level in comparison matrix" },
        { "-min", FALSE, etREAL,
          { &rmsd_user_min }, "Minimum level in comparison matrix" },
        { "-bmax", FALSE, etREAL,
          { &bond_user_max }, "Maximum level in bond angle matrix" },
        { "-bmin", FALSE, etREAL,
          { &bond_user_min }, "Minimum level in bond angle matrix" },
        { "-mw", FALSE, etBOOL,
          { &bMassWeighted }, "Use mass weighting for superposition" },
        { "-nlevels", FALSE, etINT,
          { &nlevels }, "Number of levels in the matrices" },
        { "-ng", FALSE, etINT,
          { &nrms }, "Number of groups to compute RMS between" },
        { "-dlog", FALSE, etBOOL,
          { &bDeltaLog },
          "HIDDENUse a log x-axis in the delta t matrix" },
        { "-dmax", FALSE, etREAL,
          { &delta_maxy }, "HIDDENMaximum level in delta matrix" },
        { "-aver", FALSE, etINT,
          { &avl },
          "HIDDENAverage over this distance in the RMSD matrix" }
    };
    int             natoms_trx, natoms_trx2, natoms;
    int             i, j, k, m, teller, teller2, tel_mat, tel_mat2;
#define NFRAME 5000
    int             maxframe = NFRAME, maxframe2 = NFRAME;
    real            t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL;
    gmx_bool        bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass;
    gmx_bool        bFit, bReset;
    t_topology      top;
    int             ePBC;
    t_iatom        *iatom = NULL;

    matrix          box;
    rvec           *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
                    vec2;
    t_trxstatus    *status;
    char            buf[256], buf2[256];
    int             ncons = 0;
    FILE           *fp;
    real            rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL,
    **rmsd_mat             = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis,
    *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang;
    real       **rmsdav_mat = NULL, av_tot, weight, weight_tot;
    real       **delta      = NULL, delta_max, delta_scalex = 0, delta_scaley = 0,
    *delta_tot;
    int          delta_xsize = 0, del_lev = 100, mx, my, abs_my;
    gmx_bool     bA1, bA2, bPrev, bTop, *bInMat = NULL;
    int          ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m =
        0;
    atom_id     *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m =
        NULL;
    char        *gn_fit, **gn_rms;
    t_rgb        rlo, rhi;
    output_env_t oenv;
    gmx_rmpbc_t  gpbc = NULL;

    t_filenm     fnm[] =
    {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efTRX, "-f2", NULL, ffOPTRD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efXVG, NULL, "rmsd", ffWRITE },
        { efXVG, "-mir", "rmsdmir", ffOPTWR },
        { efXVG, "-a", "avgrp", ffOPTWR },
        { efXVG, "-dist", "rmsd-dist", ffOPTWR },
        { efXPM, "-m", "rmsd", ffOPTWR },
        { efDAT, "-bin", "rmsd", ffOPTWR },
        { efXPM, "-bm", "bond", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW
                           | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL,
                           &oenv))
    {
        return 0;
    }
    /* parse enumerated options: */
    ewhat = nenum(what);
    if (ewhat == ewRho || ewhat == ewRhoSc)
    {
        please_cite(stdout, "Maiorov95");
    }
    efit   = nenum(fit);
    bFit   = efit == efFit;
    bReset = efit == efReset;
    if (bFit)
    {
        bReset = TRUE; /* for fit, reset *must* be set */
    }
    else
    {
        bFitAll = FALSE;
    }

    /* mark active cmdline options */
    bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */
    bFile2  = opt2bSet("-f2", NFILE, fnm);
    bMat    = opt2bSet("-m", NFILE, fnm);
    bBond   = opt2bSet("-bm", NFILE, fnm);
    bDelta  = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from *
                                 *	your RMSD matrix (hidden option       */
    bNorm   = opt2bSet("-a", NFILE, fnm);
    bFreq2  = opt2parg_bSet("-skip2", asize(pa), pa);
    if (freq <= 0)
    {
        fprintf(stderr, "The number of frames to skip is <= 0. "
                "Writing out all frames.\n\n");
        freq = 1;
    }
    if (!bFreq2)
    {
        freq2 = freq;
    }
    else if (bFile2 && freq2 <= 0)
    {
        fprintf(stderr,
                "The number of frames to skip in second trajectory is <= 0.\n"
                "  Writing out all frames.\n\n");
        freq2 = 1;
    }

    bPrev = (prev > 0);
    if (bPrev)
    {
        prev = abs(prev);
        if (freq != 1)
        {
            fprintf(stderr, "WARNING: option -skip also applies to -prev\n");
        }
    }

    if (bFile2 && !bMat && !bBond)
    {
        fprintf(
                stderr,
                "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n"
                "         will not read from %s\n", opt2fn("-f2", NFILE,
                                                           fnm));
        bFile2 = FALSE;
    }

    if (bDelta)
    {
        bMat = TRUE;
        if (bFile2)
        {
            fprintf(stderr,
                    "WARNING: second trajectory (-f2) useless when making delta matrix,\n"
                    "         will not read from %s\n", opt2fn("-f2",
                                                               NFILE, fnm));
            bFile2 = FALSE;
        }
    }

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp,
                         NULL, box, TRUE);
    snew(w_rls, top.atoms.nr);
    snew(w_rms, top.atoms.nr);

    if (!bTop && bBond)
    {
        fprintf(stderr,
                "WARNING: Need a run input file for bond angle matrix,\n"
                "         will not calculate bond angle matrix.\n");
        bBond = FALSE;
    }

    if (bReset)
    {
        fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares"
                : "translational");
        get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit,
                  &ind_fit, &gn_fit);
    }
    else
    {
        ifit = 0;
    }

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

        bMass = FALSE;
        for (i = 0; i < ifit; i++)
        {
            if (bMassWeighted)
            {
                w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m;
            }
            else
            {
                w_rls[ind_fit[i]] = 1;
            }
            bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in the fit group are 0, using masses of 1\n");
            for (i = 0; i < ifit; i++)
            {
                w_rls[ind_fit[i]] = 1;
            }
        }
    }

    if (bMat || bBond)
    {
        nrms = 1;
    }

    snew(gn_rms, nrms);
    snew(ind_rms, nrms);
    snew(irms, nrms);

    fprintf(stderr, "Select group%s for %s calculation\n",
            (nrms > 1) ? "s" : "", whatname[ewhat]);
    get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm),
              nrms, irms, ind_rms, gn_rms);

    if (bNorm)
    {
        snew(rlsnorm, irms[0]);
    }
    snew(rls, nrms);
    for (j = 0; j < nrms; j++)
    {
        snew(rls[j], maxframe);
    }
    if (bMirror)
    {
        snew(rlsm, nrms);
        for (j = 0; j < nrms; j++)
        {
            snew(rlsm[j], maxframe);
        }
    }
    snew(time, maxframe);
    for (j = 0; j < nrms; j++)
    {
        bMass = FALSE;
        for (i = 0; i < irms[j]; i++)
        {
            if (bMassWeighted)
            {
                w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m;
            }
            else
            {
                w_rms[ind_rms[j][i]] = 1.0;
            }
            bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in group %d are 0, using masses of 1\n", j);
            for (i = 0; i < irms[j]; i++)
            {
                w_rms[ind_rms[j][i]] = 1;
            }
        }
    }
    /* Prepare reference frame */
    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr);
        gmx_rmpbc(gpbc, top.atoms.nr, box, xp);
    }
    if (bReset)
    {
        reset_x(ifit, ind_fit, top.atoms.nr, NULL, xp, w_rls);
    }
    if (bMirror)
    {
        /* generate reference structure mirror image: */
        snew(xm, top.atoms.nr);
        for (i = 0; i < top.atoms.nr; i++)
        {
            copy_rvec(xp[i], xm[i]);
            xm[i][XX] = -xm[i][XX];
        }
    }
    if (ewhat == ewRhoSc)
    {
        norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp);
    }

    /* read first frame */
    natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box);
    if (natoms_trx != top.atoms.nr)
    {
        fprintf(stderr,
                "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
                top.atoms.nr, natoms_trx);
    }
    natoms = min(top.atoms.nr, natoms_trx);
    if (bMat || bBond || bPrev)
    {
        snew(mat_x, NFRAME);

        if (bPrev)
        {
            /* With -prev we use all atoms for simplicity */
            n_ind_m = natoms;
        }
        else
        {
            /* Check which atoms we need (fit/rms) */
            snew(bInMat, natoms);
            for (i = 0; i < ifit; i++)
            {
                bInMat[ind_fit[i]] = TRUE;
            }
            n_ind_m = ifit;
            for (i = 0; i < irms[0]; i++)
            {
                if (!bInMat[ind_rms[0][i]])
                {
                    bInMat[ind_rms[0][i]] = TRUE;
                    n_ind_m++;
                }
            }
        }
        /* Make an index of needed atoms */
        snew(ind_m, n_ind_m);
        snew(rev_ind_m, natoms);
        j = 0;
        for (i = 0; i < natoms; i++)
        {
            if (bPrev || bInMat[i])
            {
                ind_m[j]     = i;
                rev_ind_m[i] = j;
                j++;
            }
        }
        snew(w_rls_m, n_ind_m);
        snew(ind_rms_m, irms[0]);
        snew(w_rms_m, n_ind_m);
        for (i = 0; i < ifit; i++)
        {
            w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]];
        }
        for (i = 0; i < irms[0]; i++)
        {
            ind_rms_m[i]          = rev_ind_m[ind_rms[0][i]];
            w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]];
        }
        sfree(bInMat);
    }

    if (bBond)
    {
        ncons = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom  = top.idef.il[k].iatoms;
                ncons += top.idef.il[k].nr/3;
            }
        }
        fprintf(stderr, "Found %d bonds in topology\n", ncons);
        snew(ind_bond1, ncons);
        snew(ind_bond2, ncons);
        ibond = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom = top.idef.il[k].iatoms;
                ncons = top.idef.il[k].nr/3;
                for (i = 0; i < ncons; i++)
                {
                    bA1 = FALSE;
                    bA2 = FALSE;
                    for (j = 0; j < irms[0]; j++)
                    {
                        if (iatom[3*i+1] == ind_rms[0][j])
                        {
                            bA1 = TRUE;
                        }
                        if (iatom[3*i+2] == ind_rms[0][j])
                        {
                            bA2 = TRUE;
                        }
                    }
                    if (bA1 && bA2)
                    {
                        ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]];
                        ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]];
                        ibond++;
                    }
                }
            }
        }
        fprintf(stderr, "Using %d bonds for bond angle matrix\n", ibond);
        if (ibond == 0)
        {
            gmx_fatal(FARGS, "0 bonds found");
        }
    }

    /* start looping over frames: */
    tel_mat = 0;
    teller  = 0;
    do
    {
        if (bPBC)
        {
            gmx_rmpbc(gpbc, natoms, box, x);
        }

        if (bReset)
        {
            reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
        }
        if (ewhat == ewRhoSc)
        {
            norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
        }

        if (bFit)
        {
            /*do the least squares fit to original structure*/
            do_fit(natoms, w_rls, xp, x);
        }

        if (teller % freq == 0)
        {
            /* keep frame for matrix calculation */
            if (bMat || bBond || bPrev)
            {
                if (tel_mat >= NFRAME)
                {
                    srenew(mat_x, tel_mat+1);
                }
                snew(mat_x[tel_mat], n_ind_m);
                for (i = 0; i < n_ind_m; i++)
                {
                    copy_rvec(x[ind_m[i]], mat_x[tel_mat][i]);
                }
            }
            tel_mat++;
        }

        /*calculate energy of root_least_squares*/
        if (bPrev)
        {
            j = tel_mat-prev-1;
            if (j < 0)
            {
                j = 0;
            }
            for (i = 0; i < n_ind_m; i++)
            {
                copy_rvec(mat_x[j][i], xp[ind_m[i]]);
            }
            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, xp, w_rls);
            }
            if (bFit)
            {
                do_fit(natoms, w_rls, x, xp);
            }
        }
        for (j = 0; (j < nrms); j++)
        {
            rls[j][teller] =
                calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp);
        }
        if (bNorm)
        {
            for (j = 0; (j < irms[0]); j++)
            {
                rlsnorm[j] +=
                    calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp);
            }
        }

        if (bMirror)
        {
            if (bFit)
            {
                /*do the least squares fit to mirror of original structure*/
                do_fit(natoms, w_rls, xm, x);
            }

            for (j = 0; j < nrms; j++)
            {
                rlsm[j][teller] =
                    calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm);
            }
        }
        time[teller] = output_env_conv_time(oenv, t);

        teller++;
        if (teller >= maxframe)
        {
            maxframe += NFRAME;
            srenew(time, maxframe);
            for (j = 0; (j < nrms); j++)
            {
                srenew(rls[j], maxframe);
            }
            if (bMirror)
            {
                for (j = 0; (j < nrms); j++)
                {
                    srenew(rlsm[j], maxframe);
                }
            }
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);

    if (bFile2)
    {
        snew(time2, maxframe2);

        fprintf(stderr, "\nWill read second trajectory file\n");
        snew(mat_x2, NFRAME);
        natoms_trx2 =
            read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box);
        if (natoms_trx2 != natoms_trx)
        {
            gmx_fatal(FARGS,
                      "Second trajectory (%d atoms) does not match the first one"
                      " (%d atoms)", natoms_trx2, natoms_trx);
        }
        tel_mat2 = 0;
        teller2  = 0;
        do
        {
            if (bPBC)
            {
                gmx_rmpbc(gpbc, natoms, box, x);
            }

            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
            }
            if (ewhat == ewRhoSc)
            {
                norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
            }

            if (bFit)
            {
                /*do the least squares fit to original structure*/
                do_fit(natoms, w_rls, xp, x);
            }

            if (teller2 % freq2 == 0)
            {
                /* keep frame for matrix calculation */
                if (bMat)
                {
                    if (tel_mat2 >= NFRAME)
                    {
                        srenew(mat_x2, tel_mat2+1);
                    }
                    snew(mat_x2[tel_mat2], n_ind_m);
                    for (i = 0; i < n_ind_m; i++)
                    {
                        copy_rvec(x[ind_m[i]], mat_x2[tel_mat2][i]);
                    }
                }
                tel_mat2++;
            }

            time2[teller2] = output_env_conv_time(oenv, t);

            teller2++;
            if (teller2 >= maxframe2)
            {
                maxframe2 += NFRAME;
                srenew(time2, maxframe2);
            }
        }
        while (read_next_x(oenv, status, &t, x, box));
        close_trj(status);
    }
    else
    {
        mat_x2   = mat_x;
        time2    = time;
        tel_mat2 = tel_mat;
        freq2    = freq;
    }
    gmx_rmpbc_done(gpbc);

    if (bMat || bBond)
    {
        /* calculate RMS matrix */
        fprintf(stderr, "\n");
        if (bMat)
        {
            fprintf(stderr, "Building %s matrix, %dx%d elements\n",
                    whatname[ewhat], tel_mat, tel_mat2);
            snew(rmsd_mat, tel_mat);
        }
        if (bBond)
        {
            fprintf(stderr, "Building bond angle matrix, %dx%d elements\n",
                    tel_mat, tel_mat2);
            snew(bond_mat, tel_mat);
        }
        snew(axis, tel_mat);
        snew(axis2, tel_mat2);
        rmsd_max = 0;
        if (bFile2)
        {
            rmsd_min = 1e10;
        }
        else
        {
            rmsd_min = 0;
        }
        rmsd_avg = 0;
        bond_max = 0;
        bond_min = 1e10;
        for (j = 0; j < tel_mat2; j++)
        {
            axis2[j] = time2[freq2*j];
        }
        if (bDelta)
        {
            if (bDeltaLog)
            {
                delta_scalex = 8.0/log(2.0);
                delta_xsize  = (int)(log(tel_mat/2)*delta_scalex+0.5)+1;
            }
            else
            {
                delta_xsize = tel_mat/2;
            }
            delta_scaley = 1.0/delta_maxy;
            snew(delta, delta_xsize);
            for (j = 0; j < delta_xsize; j++)
            {
                snew(delta[j], del_lev+1);
            }
            if (avl > 0)
            {
                snew(rmsdav_mat, tel_mat);
                for (j = 0; j < tel_mat; j++)
                {
                    snew(rmsdav_mat[j], tel_mat);
                }
            }
        }

        if (bFitAll)
        {
            snew(mat_x2_j, natoms);
        }
        for (i = 0; i < tel_mat; i++)
        {
            axis[i] = time[freq*i];
            fprintf(stderr, "\r element %5d; time %5.2f  ", i, axis[i]);
            if (bMat)
            {
                snew(rmsd_mat[i], tel_mat2);
            }
            if (bBond)
            {
                snew(bond_mat[i], tel_mat2);
            }
            for (j = 0; j < tel_mat2; j++)
            {
                if (bFitAll)
                {
                    for (k = 0; k < n_ind_m; k++)
                    {
                        copy_rvec(mat_x2[j][k], mat_x2_j[k]);
                    }
                    do_fit(n_ind_m, w_rls_m, mat_x[i], mat_x2_j);
                }
                else
                {
                    mat_x2_j = mat_x2[j];
                }
                if (bMat)
                {
                    if (bFile2 || (i < j))
                    {
                        rmsd_mat[i][j] =
                            calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m,
                                             w_rms_m, mat_x[i], mat_x2_j);
                        if (rmsd_mat[i][j] > rmsd_max)
                        {
                            rmsd_max = rmsd_mat[i][j];
                        }
                        if (rmsd_mat[i][j] < rmsd_min)
                        {
                            rmsd_min = rmsd_mat[i][j];
                        }
                        rmsd_avg += rmsd_mat[i][j];
                    }
                    else
                    {
                        rmsd_mat[i][j] = rmsd_mat[j][i];
                    }
                }
                if (bBond)
                {
                    if (bFile2 || (i <= j))
                    {
                        ang = 0.0;
                        for (m = 0; m < ibond; m++)
                        {
                            rvec_sub(mat_x[i][ind_bond1[m]], mat_x[i][ind_bond2[m]], vec1);
                            rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2);
                            ang += acos(cos_angle(vec1, vec2));
                        }
                        bond_mat[i][j] = ang*180.0/(M_PI*ibond);
                        if (bond_mat[i][j] > bond_max)
                        {
                            bond_max = bond_mat[i][j];
                        }
                        if (bond_mat[i][j] < bond_min)
                        {
                            bond_min = bond_mat[i][j];
                        }
                    }
                    else
                    {
                        bond_mat[i][j] = bond_mat[j][i];
                    }
                }
            }
        }
        if (bFile2)
        {
            rmsd_avg /= tel_mat*tel_mat2;
        }
        else
        {
            rmsd_avg /= tel_mat*(tel_mat - 1)/2;
        }
        if (bMat && (avl > 0))
        {
            rmsd_max = 0.0;
            rmsd_min = 0.0;
            rmsd_avg = 0.0;
            for (j = 0; j < tel_mat-1; j++)
            {
                for (i = j+1; i < tel_mat; i++)
                {
                    av_tot     = 0;
                    weight_tot = 0;
                    for (my = -avl; my <= avl; my++)
                    {
                        if ((j+my >= 0) && (j+my < tel_mat))
                        {
                            abs_my = abs(my);
                            for (mx = -avl; mx <= avl; mx++)
                            {
                                if ((i+mx >= 0) && (i+mx < tel_mat))
                                {
                                    weight      = (real)(avl+1-max(abs(mx), abs_my));
                                    av_tot     += weight*rmsd_mat[i+mx][j+my];
                                    weight_tot += weight;
                                }
                            }
                        }
                    }
                    rmsdav_mat[i][j] = av_tot/weight_tot;
                    rmsdav_mat[j][i] = rmsdav_mat[i][j];
                    if (rmsdav_mat[i][j] > rmsd_max)
                    {
                        rmsd_max = rmsdav_mat[i][j];
                    }
                }
            }
            rmsd_mat = rmsdav_mat;
        }

        if (bMat)
        {
            fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n",
                    whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg);
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            if (rmsd_user_max != -1)
            {
                rmsd_max = rmsd_user_max;
            }
            if (rmsd_user_min != -1)
            {
                rmsd_min = rmsd_user_min;
            }
            if ((rmsd_user_max !=  -1) || (rmsd_user_min != -1))
            {
                fprintf(stderr, "Min and Max value set to resp. %f and %f\n",
                        rmsd_min, rmsd_max);
            }
            sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]);
            write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat],
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels);
            /* Print the distribution of RMSD values */
            if (opt2bSet("-dist", NFILE, fnm))
            {
                low_rmsd_dist(opt2fn("-dist", NFILE, fnm), rmsd_max, tel_mat, rmsd_mat, oenv);
            }

            if (bDelta)
            {
                snew(delta_tot, delta_xsize);
                for (j = 0; j < tel_mat-1; j++)
                {
                    for (i = j+1; i < tel_mat; i++)
                    {
                        mx = i-j;
                        if (mx < tel_mat/2)
                        {
                            if (bDeltaLog)
                            {
                                mx = (int)(log(mx)*delta_scalex+0.5);
                            }
                            my             = (int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5);
                            delta_tot[mx] += 1.0;
                            if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy))
                            {
                                delta[mx][my] += 1.0;
                            }
                        }
                    }
                }
                delta_max = 0;
                for (i = 0; i < delta_xsize; i++)
                {
                    if (delta_tot[i] > 0.0)
                    {
                        delta_tot[i] = 1.0/delta_tot[i];
                        for (j = 0; j <= del_lev; j++)
                        {
                            delta[i][j] *= delta_tot[i];
                            if (delta[i][j] > delta_max)
                            {
                                delta_max = delta[i][j];
                            }
                        }
                    }
                }
                fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max);
                snew(del_xaxis, delta_xsize);
                snew(del_yaxis, del_lev+1);
                for (i = 0; i < delta_xsize; i++)
                {
                    del_xaxis[i] = axis[i]-axis[0];
                }
                for (i = 0; i < del_lev+1; i++)
                {
                    del_yaxis[i] = delta_maxy*i/del_lev;
                }
                sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]);
                fp = gmx_ffopen("delta.xpm", "w");
                write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat],
                          delta_xsize, del_lev+1, del_xaxis, del_yaxis,
                          delta, 0.0, delta_max, rlo, rhi, &nlevels);
                gmx_ffclose(fp);
            }
            if (opt2bSet("-bin", NFILE, fnm))
            {
                /* NB: File must be binary if we use fwrite */
                fp = ftp2FILE(efDAT, NFILE, fnm, "wb");
                for (i = 0; i < tel_mat; i++)
                {
                    if (fwrite(rmsd_mat[i], sizeof(**rmsd_mat), tel_mat2, fp) != tel_mat2)
                    {
                        gmx_fatal(FARGS, "Error writing to output file");
                    }
                }
                gmx_ffclose(fp);
            }
        }
        if (bBond)
        {
            fprintf(stderr, "\nMin. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            if (bond_user_max != -1)
            {
                bond_max = bond_user_max;
            }
            if (bond_user_min != -1)
            {
                bond_min = bond_user_min;
            }
            if ((bond_user_max !=  -1) || (bond_user_min != -1))
            {
                fprintf(stderr, "Bond angle Min and Max set to:\n"
                        "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            }
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            sprintf(buf, "%s av. bond angle deviation", gn_rms[0]);
            write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees",
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels);
        }
    }

    bAv = opt2bSet("-a", NFILE, fnm);

    /* Write the RMSD's to file */
    if (!bPrev)
    {
        sprintf(buf, "%s", whatxvgname[ewhat]);
    }
    else
    {
        sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat],
                time[prev*freq]-time[0], output_env_get_time_label(oenv));
    }
    fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                  whatxvglabel[ewhat], oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n",
                (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit],
                bFit     ? " to " : "", bFit ? gn_fit : "");
    }
    if (nrms != 1)
    {
        xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
    }
    for (i = 0; (i < teller); i++)
    {
        if (bSplit && i > 0 &&
            abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(fp, "&\n");
        }
        fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, " %12.7f", rls[j][i]);
            if (bAv)
            {
                rlstot += rls[j][i];
            }
        }
        fprintf(fp, "\n");
    }
    gmx_ffclose(fp);

    if (bMirror)
    {
        /* Write the mirror RMSD's to file */
        sprintf(buf, "%s with Mirror", whatxvgname[ewhat]);
        sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                      buf2, oenv);
        if (nrms == 1)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n",
                        gn_rms[0], gn_fit);
            }
        }
        else
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"after lsq fit to mirror %s\"\n", gn_fit);
            }
            xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
        }
        for (i = 0; (i < teller); i++)
        {
            if (bSplit && i > 0 && abs(time[i]) < 1e-5)
            {
                fprintf(fp, "&\n");
            }
            fprintf(fp, "%12.7f", time[i]);
            for (j = 0; (j < nrms); j++)
            {
                fprintf(fp, " %12.7f", rlsm[j][i]);
            }
            fprintf(fp, "\n");
        }
        gmx_ffclose(fp);
    }

    if (bAv)
    {
        sprintf(buf, "Average %s", whatxvgname[ewhat]);
        sprintf(buf2, "Average %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlstot/teller);
        }
        gmx_ffclose(fp);
    }

    if (bNorm)
    {
        fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv);
        for (j = 0; (j < irms[0]); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlsnorm[j]/teller);
        }
        gmx_ffclose(fp);
    }
    do_view(oenv, opt2fn_null("-a", NFILE, fnm), "-graphtype bar");
    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-mir", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-m", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-bm", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-dist", NFILE, fnm), NULL);

    return 0;
}
Exemplo n.º 10
0
int gmx_disre(int argc,char *argv[])
{
  const char *desc[] = {
    "g_disre computes violations of distance restraints.",
    "If necessary all protons can be added to a protein molecule ",
    "using the protonate program.[PAR]",
    "The program always",
    "computes the instantaneous violations rather than time-averaged,",
    "because this analysis is done from a trajectory file afterwards",
    "it does not make sense to use time averaging. However,",
    "the time averaged values per restraint are given in the log file.[PAR]",
    "An index file may be used to select specific restraints for",
    "printing.[PAR]",
    "When the optional[TT]-q[tt] flag is given a pdb file coloured by the",
    "amount of average violations.[PAR]",
    "When the [TT]-c[tt] option is given, an index file will be read",
    "containing the frames in your trajectory corresponding to the clusters",
    "(defined in another manner) that you want to analyze. For these clusters",
    "the program will compute average violations using the third power",
    "averaging algorithm and print them in the log file."
  };
  static int  ntop      = 0;
  static int  nlevels   = 20;
  static real max_dr    = 0;
  static gmx_bool bThird    = TRUE;
  t_pargs pa[] = {
    { "-ntop", FALSE, etINT,  {&ntop},
      "Number of large violations that are stored in the log file every step" },
    { "-maxdr", FALSE, etREAL, {&max_dr},
      "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." },
    { "-nlevels", FALSE, etINT, {&nlevels},
      "Number of levels in the matrix output" },
    { "-third", FALSE, etBOOL, {&bThird},
      "Use inverse third power averaging or linear for matrix output" }
  };
  
  FILE        *out=NULL,*aver=NULL,*numv=NULL,*maxxv=NULL,*xvg=NULL;
  t_tpxheader header;
  t_inputrec  ir;
  gmx_mtop_t  mtop;
  rvec        *xtop;
  gmx_localtop_t *top;
  t_atoms     *atoms=NULL;
  t_forcerec  *fr;
  t_fcdata    fcd;
  t_nrnb      nrnb;
  t_commrec   *cr;
  t_graph     *g;
  int         ntopatoms,natoms,i,j,kkk;
  t_trxstatus *status;
  real        t;
  rvec        *x,*f,*xav=NULL;
  matrix      box;
  gmx_bool        bPDB;
  int         isize;
  atom_id     *index=NULL,*ind_fit=NULL;
  char        *grpname;
  t_cluster_ndx *clust=NULL;
  t_dr_result dr,*dr_clust=NULL;
  char        **leg;
  real        *vvindex=NULL,*w_rls=NULL;
  t_mdatoms   *mdatoms;
  t_pbc       pbc,*pbc_null;
  int         my_clust;
  FILE        *fplog;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;
  
  t_filenm fnm[] = {
    { efTPX, NULL, NULL, ffREAD },
    { efTRX, "-f", NULL, ffREAD },
    { efXVG, "-ds", "drsum",  ffWRITE },
    { efXVG, "-da", "draver", ffWRITE },
    { efXVG, "-dn", "drnum",  ffWRITE },
    { efXVG, "-dm", "drmax",  ffWRITE },
    { efXVG, "-dr", "restr",  ffWRITE },
    { efLOG, "-l",  "disres", ffWRITE },
    { efNDX, NULL,  "viol",   ffOPTRD },
    { efPDB, "-q",  "viol",   ffOPTWR },
    { efNDX, "-c",  "clust",  ffOPTRD },
    { efXPM, "-x",  "matrix", ffOPTWR }
  };
#define NFILE asize(fnm)

  cr  = init_par(&argc,&argv);
  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);

  gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,FALSE,0,&fplog);
  
  if (ntop)
    init5(ntop);
  
  read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&header,FALSE,NULL,NULL);
  snew(xtop,header.natoms);
  read_tpx(ftp2fn(efTPX,NFILE,fnm),&ir,box,&ntopatoms,xtop,NULL,NULL,&mtop);
  bPDB = opt2bSet("-q",NFILE,fnm);
  if (bPDB) {
    snew(xav,ntopatoms);
    snew(ind_fit,ntopatoms);
    snew(w_rls,ntopatoms);
    for(kkk=0; (kkk<ntopatoms); kkk++) {
      w_rls[kkk] = 1;
      ind_fit[kkk] = kkk;
    }
    
    snew(atoms,1);
    *atoms = gmx_mtop_global_atoms(&mtop);
    
    if (atoms->pdbinfo == NULL) {
      snew(atoms->pdbinfo,atoms->nr);
    }
  } 

  top = gmx_mtop_generate_local_top(&mtop,&ir);

  g = NULL;
  pbc_null = NULL;
  if (ir.ePBC != epbcNONE) {
    if (ir.bPeriodicMols)
      pbc_null = &pbc;
    else
      g = mk_graph(fplog,&top->idef,0,mtop.natoms,FALSE,FALSE);
  }
  
  if (ftp2bSet(efNDX,NFILE,fnm)) {
    rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
    xvg=xvgropen(opt2fn("-dr",NFILE,fnm),"Inidividual Restraints","Time (ps)",
		 "nm",oenv);
    snew(vvindex,isize);
    snew(leg,isize);
    for(i=0; (i<isize); i++) {
      index[i]++;
      snew(leg[i],12);
      sprintf(leg[i],"index %d",index[i]);
    }
    xvgr_legend(xvg,isize,(const char**)leg,oenv);
  }
  else 
    isize=0;

  ir.dr_tau=0.0;
  init_disres(fplog,&mtop,&ir,NULL,FALSE,&fcd,NULL);

  natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  snew(f,5*natoms);
  
  init_dr_res(&dr,fcd.disres.nres);
  if (opt2bSet("-c",NFILE,fnm)) {
    clust = cluster_index(fplog,opt2fn("-c",NFILE,fnm));
    snew(dr_clust,clust->clust->nr+1);
    for(i=0; (i<=clust->clust->nr); i++)
      init_dr_res(&dr_clust[i],fcd.disres.nres);
  }
  else {	
    out =xvgropen(opt2fn("-ds",NFILE,fnm),
		  "Sum of Violations","Time (ps)","nm",oenv);
    aver=xvgropen(opt2fn("-da",NFILE,fnm),
		  "Average Violation","Time (ps)","nm",oenv);
    numv=xvgropen(opt2fn("-dn",NFILE,fnm),
		  "# Violations","Time (ps)","#",oenv);
    maxxv=xvgropen(opt2fn("-dm",NFILE,fnm),
		   "Largest Violation","Time (ps)","nm",oenv);
  }

  mdatoms = init_mdatoms(fplog,&mtop,ir.efep!=efepNO);
  atoms2md(&mtop,&ir,0,NULL,0,mtop.natoms,mdatoms);
  update_mdatoms(mdatoms,ir.init_lambda);
  fr      = mk_forcerec();
  fprintf(fplog,"Made forcerec\n");
  init_forcerec(fplog,oenv,fr,NULL,&ir,&mtop,cr,box,FALSE,NULL,NULL,NULL,
                FALSE,-1);
  init_nrnb(&nrnb);
  if (ir.ePBC != epbcNONE)
    gpbc = gmx_rmpbc_init(&top->idef,ir.ePBC,natoms,box);
  
  j=0;
  do {
    if (ir.ePBC != epbcNONE) {
      if (ir.bPeriodicMols)
	set_pbc(&pbc,ir.ePBC,box);
      else
	gmx_rmpbc(gpbc,natoms,box,x);
    }
    
    if (clust) {
      if (j > clust->maxframe)
	gmx_fatal(FARGS,"There are more frames in the trajectory than in the cluster index file. t = %8f\n",t);
      my_clust = clust->inv_clust[j];
      range_check(my_clust,0,clust->clust->nr);
      check_viol(fplog,cr,&(top->idef.il[F_DISRES]),
		 top->idef.iparams,top->idef.functype,
		 x,f,fr,pbc_null,g,dr_clust,my_clust,isize,index,vvindex,&fcd);
    }
    else
      check_viol(fplog,cr,&(top->idef.il[F_DISRES]),
		 top->idef.iparams,top->idef.functype,
		 x,f,fr,pbc_null,g,&dr,0,isize,index,vvindex,&fcd);
    if (bPDB) {
      reset_x(atoms->nr,ind_fit,atoms->nr,NULL,x,w_rls);
      do_fit(atoms->nr,w_rls,x,x);
      if (j == 0) {
	/* Store the first frame of the trajectory as 'characteristic'
	 * for colouring with violations.
	 */
	for(kkk=0; (kkk<atoms->nr); kkk++)
	  copy_rvec(x[kkk],xav[kkk]);
      }
    }
    if (!clust) {
      if (isize > 0) {
	fprintf(xvg,"%10g",t);
	for(i=0; (i<isize); i++)
	  fprintf(xvg,"  %10g",vvindex[i]);
	fprintf(xvg,"\n");
      }    
      fprintf(out,  "%10g  %10g\n",t,dr.sumv);
      fprintf(aver, "%10g  %10g\n",t,dr.averv);
      fprintf(maxxv,"%10g  %10g\n",t,dr.maxv);
      fprintf(numv, "%10g  %10d\n",t,dr.nv);
    }
    j++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));
  close_trj(status);
  if (ir.ePBC != epbcNONE)
    gmx_rmpbc_done(gpbc);

  if (clust) {
    dump_clust_stats(fplog,fcd.disres.nres,&(top->idef.il[F_DISRES]),
		     top->idef.iparams,clust->clust,dr_clust,
		     clust->grpname,isize,index);
  }
  else {
    dump_stats(fplog,j,fcd.disres.nres,&(top->idef.il[F_DISRES]),
	       top->idef.iparams,&dr,isize,index,
	       bPDB ? atoms : NULL);
    if (bPDB) {
      write_sto_conf(opt2fn("-q",NFILE,fnm),
		     "Coloured by average violation in Angstrom",
		     atoms,xav,NULL,ir.ePBC,box);
    }
    dump_disre_matrix(opt2fn_null("-x",NFILE,fnm),&dr,fcd.disres.nres,
		      j,&top->idef,&mtop,max_dr,nlevels,bThird);
    ffclose(out);
    ffclose(aver);
    ffclose(numv);
    ffclose(maxxv);
    if (isize > 0) {
      ffclose(xvg);
      do_view(oenv,opt2fn("-dr",NFILE,fnm),"-nxy");
    }
    do_view(oenv,opt2fn("-dn",NFILE,fnm),"-nxy");
    do_view(oenv,opt2fn("-da",NFILE,fnm),"-nxy");
    do_view(oenv,opt2fn("-ds",NFILE,fnm),"-nxy");
    do_view(oenv,opt2fn("-dm",NFILE,fnm),"-nxy");
  }
  thanx(stderr);

  if (gmx_parallel_env_initialized())
    gmx_finalize();

  gmx_log_close(fplog);
  
  return 0;
}
Exemplo n.º 11
0
void sgangle_plot_single(const char *fn,const char *afile,const char *dfile, 
			 const char *d1file, const char *d2file,
			 atom_id index1[], int gnx1, char *grpn1,
			 atom_id index2[], int gnx2, char *grpn2,
			 t_topology *top,int ePBC, const output_env_t oenv)
{
  FILE         
    *sg_angle,           /* xvgr file with angles */
    *sg_distance = NULL, /* xvgr file with distances */
    *sg_distance1 = NULL,/* xvgr file with distance between plane and atom */
    *sg_distance2 = NULL;/* xvgr file with distance between plane and atom2 */
  real         
    t,                   /* time */
    angle,               /* cosine of angle between two groups */
    distance,            /* distance between two groups. */
    distance1,           /* distance between plane and one of two atoms */
    distance2;           /* same for second of two atoms */
  t_trxstatus *status;
  int        natoms,teller=0;
  int        i;
  rvec       *x0;   /* coordinates, and coordinates corrected for pb */
  rvec       *xzero;
  matrix     box;        
  char       buf[256];   /* for xvgr title */
  gmx_rmpbc_t  gpbc=NULL;
  

  if ((natoms = read_first_x(oenv,&status,fn,&t,&x0,box)) == 0)
    gmx_fatal(FARGS,"Could not read coordinates from statusfile\n");
  
  sprintf(buf,"Angle between %s and %s",grpn1,grpn2);
  sg_angle = xvgropen(afile,buf,"Time (ps)","Cos(angle) ",oenv);
  
  if (dfile) {
    sprintf(buf,"Distance between %s and %s",grpn1,grpn2);
    sg_distance = xvgropen(dfile,buf,"Time (ps)","Distance (nm)",oenv);
  }
  
  if (d1file) {
    sprintf(buf,"Distance between plane and first atom of vector");
    sg_distance1 = xvgropen(d1file,buf,"Time (ps)","Distance (nm)",oenv);
  }
  
  if (d2file) {
    sprintf(buf,"Distance between plane and second atom of vector");
    sg_distance2 = xvgropen(d2file,buf,"Time (ps","Distance (nm)",oenv);
  }
  
  snew(xzero,natoms);
  gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box);

  do {
    teller++;
    
    gmx_rmpbc(gpbc,natoms,box,x0);
    if (teller==1) {
      for(i=0;i<natoms;i++)
	copy_rvec(x0[i],xzero[i]);
    }
    
    
    calc_angle_single(ePBC,box,
		      xzero,x0,index1,index2,gnx1,gnx2,&angle,
		      &distance,&distance1,&distance2);
    
    fprintf(sg_angle,"%12g  %12g  %12g\n",t,angle,acos(angle)*180.0/M_PI);
    if (dfile)
      fprintf(sg_distance,"%12g  %12g\n",t,distance);
    if (d1file)
      fprintf(sg_distance1,"%12g  %12g\n",t,distance1);
    if (d2file)
      fprintf(sg_distance2,"%12g  %12g\n",t,distance1);
    
  } while (read_next_x(oenv,status,&t,natoms,x0,box));
  gmx_rmpbc_done(gpbc);
  
  fprintf(stderr,"\n");
  close_trj(status);
  ffclose(sg_angle);
  if (dfile)
    ffclose(sg_distance);
  if (d1file)
    ffclose(sg_distance1);
  if (d2file)
    ffclose(sg_distance2);
  
  sfree(x0);
}
Exemplo n.º 12
0
int gmx_spol(int argc, char *argv[])
{
    t_topology  *top;
    t_inputrec  *ir;
    t_atom      *atom;
    t_trxstatus *status;
    int          nrefat, natoms, nf, ntot;
    real         t;
    rvec        *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[] = {
        "[THISMODULE] 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;
    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 },
        { efTPR, NULL,  NULL,  ffREAD },
        { efNDX, NULL,  NULL,  ffOPTRD },
        { efXVG, NULL,  "scdist",  ffWRITE }
    };
#define NFILE asize(fnm)

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

    snew(top, 1);
    snew(ir, 1);
    read_tpx_top(ftp2fn(efTPR, 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*std::sqrt(max_cutoff2(ir->ePBC, box));
    if (rcut == 0)
    {
        rcut = 10*rmax;
    }
    rcut2 = sqr(rcut);
    invbw = 1/bw;
    nbin  = static_cast<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);

    /* 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);
        }

        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[static_cast<int>(std::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  += std::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, 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, static_cast<real>(ntot)/nf);
    if (ntot > 0)
    {
        sdip  /= ntot;
        sdip2 /= ntot;
        sinp  /= ntot;
        sdinp /= ntot;
        fprintf(stderr, "Average dipole:                               %f (D), std.dev. %f\n",
                sdip, std::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);
    }
    xvgrclose(fp);

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

    return 0;
}
Exemplo n.º 13
0
int gmx_principal(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_principal[tt] calculates the three principal axes of inertia for a group",
        "of atoms.",
    };
    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, title[256];
    int             i, j, m, gnx, nam, mol;
    atom_id        *index;
    rvec            a1, a2, a3, moi;
    FILE      *     axis1;
    FILE      *     axis2;
    FILE      *     axis3;
    FILE      *     fmoi;
    matrix          axes, box;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc = NULL;


    t_filenm fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-a1",  "axis1",    ffWRITE },
        { efDAT, "-a2",  "axis2",    ffWRITE },
        { efDAT, "-a3",  "axis3",    ffWRITE },
        { efDAT, "-om",  "moi",      ffWRITE }
    };
#define NFILE asize(fnm)

    parse_common_args(&argc, argv,
                      PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW | PCA_BE_NICE,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv);

    axis1 = ffopen(opt2fn("-a1", NFILE, fnm), "w");
    axis2 = ffopen(opt2fn("-a2", NFILE, fnm), "w");
    axis3 = ffopen(opt2fn("-a3", NFILE, fnm), "w");
    fmoi  = ffopen(opt2fn("-om", NFILE, fnm), "w");

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &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[YY][XX], axes[ZZ][XX]);
        fprintf(axis2, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][YY], axes[YY][YY], axes[ZZ][YY]);
        fprintf(axis3, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][ZZ], axes[YY][ZZ], 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);
    ffclose(axis1);
    ffclose(axis2);
    ffclose(axis3);
    ffclose(fmoi);

    return 0;
}
Exemplo n.º 14
0
/* this is the main loop for the correlation type functions
 * fx and nx are file pointers to things like read_first_x and
 * read_next_x
 */
int corr_loop(t_corr *curr, const char *fn, t_topology *top, int ePBC,
              gmx_bool bMol, int gnx[], atom_id *index[],
              t_calc_func *calc1, gmx_bool bTen, int *gnx_com, atom_id *index_com[],
              real dt, real t_pdb, rvec **x_pdb, matrix box_pdb,
              const output_env_t oenv)
{
    rvec            *x[2];  /* the coordinates to read */
    rvec            *xa[2]; /* the coordinates to calculate displacements for */
    rvec             com = {0};
    real             t, t_prev = 0;
    int              natoms, i, j, cur = 0, maxframes = 0;
    t_trxstatus     *status;
#define        prev (1-cur)
    matrix           box;
    gmx_bool         bFirst;
    gmx_rmpbc_t      gpbc = NULL;

    natoms = read_first_x(oenv, &status, fn, &curr->t0, &(x[cur]), box);
#ifdef DEBUG
    fprintf(stderr, "Read %d atoms for first frame\n", natoms);
#endif
    if ((gnx_com != NULL) && natoms < top->atoms.nr)
    {
        fprintf(stderr, "WARNING: The trajectory only contains part of the system (%d of %d atoms) and therefore the COM motion of only this part of the system will be removed\n", natoms, top->atoms.nr);
    }

    snew(x[prev], natoms);

    if (bMol)
    {
        curr->ncoords = curr->nmol;
        snew(xa[0], curr->ncoords);
        snew(xa[1], curr->ncoords);
    }
    else
    {
        curr->ncoords = natoms;
        xa[0]         = x[0];
        xa[1]         = x[1];
    }

    bFirst = TRUE;
    t      = curr->t0;
    if (x_pdb)
    {
        *x_pdb = NULL;
    }

    if (bMol)
    {
        gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms);
    }

    /* the loop over all frames */
    do
    {
        if (x_pdb && ((bFirst && t_pdb < t) ||
                      (!bFirst &&
                       t_pdb > t - 0.5*(t - t_prev) &&
                       t_pdb < t + 0.5*(t - t_prev))))
        {
            if (*x_pdb == NULL)
            {
                snew(*x_pdb, natoms);
            }
            for (i = 0; i < natoms; i++)
            {
                copy_rvec(x[cur][i], (*x_pdb)[i]);
            }
            copy_mat(box, box_pdb);
        }


        /* check whether we've reached a restart point */
        if (bRmod(t, curr->t0, dt))
        {
            curr->nrestart++;

            srenew(curr->x0, curr->nrestart);
            snew(curr->x0[curr->nrestart-1], curr->ncoords);
            srenew(curr->com, curr->nrestart);
            srenew(curr->n_offs, curr->nrestart);
            srenew(curr->lsq, curr->nrestart);
            snew(curr->lsq[curr->nrestart-1], curr->nmol);
            for (i = 0; i < curr->nmol; i++)
            {
                curr->lsq[curr->nrestart-1][i]  = gmx_stats_init();
            }

            if (debug)
            {
                fprintf(debug, "Extended data structures because of new restart %d\n",
                        curr->nrestart);
            }
        }
        /* create or extend the frame-based arrays */
        if (curr->nframes >= maxframes-1)
        {
            if (maxframes == 0)
            {
                for (i = 0; (i < curr->ngrp); i++)
                {
                    curr->ndata[i] = NULL;
                    curr->data[i]  = NULL;
                    if (bTen)
                    {
                        curr->datam[i] = NULL;
                    }
                }
                curr->time = NULL;
            }
            maxframes += 10;
            for (i = 0; (i < curr->ngrp); i++)
            {
                srenew(curr->ndata[i], maxframes);
                srenew(curr->data[i], maxframes);
                if (bTen)
                {
                    srenew(curr->datam[i], maxframes);
                }
                for (j = maxframes-10; j < maxframes; j++)
                {
                    curr->ndata[i][j] = 0;
                    curr->data[i][j]  = 0;
                    if (bTen)
                    {
                        clear_mat(curr->datam[i][j]);
                    }
                }
            }
            srenew(curr->time, maxframes);
        }

        /* set the time */
        curr->time[curr->nframes] = t - curr->t0;

        /* for the first frame, the previous frame is a copy of the first frame */
        if (bFirst)
        {
            std::memcpy(xa[prev], xa[cur], curr->ncoords*sizeof(xa[prev][0]));
            bFirst = FALSE;
        }

        /* make the molecules whole */
        if (bMol)
        {
            gmx_rmpbc(gpbc, natoms, box, x[cur]);
        }

        /* calculate the molecules' centers of masses and put them into xa */
        if (bMol)
        {
            calc_mol_com(gnx[0], index[0], &top->mols, &top->atoms, x[cur], xa[cur]);
        }

        /* first remove the periodic boundary condition crossings */
        for (i = 0; i < curr->ngrp; i++)
        {
            prep_data(bMol, gnx[i], index[i], xa[cur], xa[prev], box);
        }

        /* calculate the center of mass */
        if (gnx_com)
        {
            prep_data(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box);
            calc_com(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box,
                     &top->atoms, com);
        }

        /* loop over all groups in index file */
        for (i = 0; (i < curr->ngrp); i++)
        {
            /* calculate something useful, like mean square displacements */
            calc_corr(curr, i, gnx[i], index[i], xa[cur], (gnx_com != NULL), com,
                      calc1, bTen);
        }
        cur    = prev;
        t_prev = t;

        curr->nframes++;
    }
    while (read_next_x(oenv, status, &t, x[cur], box));
    fprintf(stderr, "\nUsed %d restart points spaced %g %s over %g %s\n\n",
            curr->nrestart,
            output_env_conv_time(oenv, dt), output_env_get_time_unit(oenv),
            output_env_conv_time(oenv, curr->time[curr->nframes-1]),
            output_env_get_time_unit(oenv) );

    if (bMol)
    {
        gmx_rmpbc_done(gpbc);
    }

    close_trj(status);

    return natoms;
}
Exemplo n.º 15
0
int gmx_helix(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes all kinds of helix properties. First, the peptide",
        "is checked to find the longest helical part, as determined by",
        "hydrogen bonds and [GRK]phi[grk]/[GRK]psi[grk] angles.",
        "That bit is fitted",
        "to an ideal helix around the [IT]z[it]-axis and centered around the origin.",
        "Then the following properties are computed:[PAR]",
        "[BB]1.[bb] Helix radius (file [TT]radius.xvg[tt]). This is merely the",
        "RMS deviation in two dimensions for all C[GRK]alpha[grk] atoms.",
        "it is calculated as [SQRT]([SUM][sum][SUB]i[sub] (x^2(i)+y^2(i)))/N[sqrt] where N is the number",
        "of backbone atoms. For an ideal helix the radius is 0.23 nm[BR]",
        "[BB]2.[bb] Twist (file [TT]twist.xvg[tt]). The average helical angle per",
        "residue is calculated. For an [GRK]alpha[grk]-helix it is 100 degrees,",
        "for 3-10 helices it will be smaller, and ",
        "for 5-helices it will be larger.[BR]",
        "[BB]3.[bb] Rise per residue (file [TT]rise.xvg[tt]). The helical rise per",
        "residue is plotted as the difference in [IT]z[it]-coordinate between C[GRK]alpha[grk]",
        "atoms. For an ideal helix, this is 0.15 nm[BR]",
        "[BB]4.[bb] Total helix length (file [TT]len-ahx.xvg[tt]). The total length",
        "of the",
        "helix in nm. This is simply the average rise (see above) times the",
        "number of helical residues (see below).[BR]",
        "[BB]5.[bb] Helix dipole, backbone only (file [TT]dip-ahx.xvg[tt]).[BR]",
        "[BB]6.[bb] RMS deviation from ideal helix, calculated for the C[GRK]alpha[grk]",
        "atoms only (file [TT]rms-ahx.xvg[tt]).[BR]",
        "[BB]7.[bb] Average C[GRK]alpha[grk] - C[GRK]alpha[grk] dihedral angle (file [TT]phi-ahx.xvg[tt]).[BR]",
        "[BB]8.[bb] Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).[BR]",
        "[BB]9.[bb] Ellipticity at 222 nm according to Hirst and Brooks.",
        "[PAR]"
    };
    static gmx_bool    bCheck = FALSE, bFit = TRUE, bDBG = FALSE, bEV = FALSE;
    static int         rStart = 0, rEnd = 0, r0 = 1;
    t_pargs            pa []  = {
        { "-r0", FALSE, etINT, {&r0},
          "The first residue number in the sequence" },
        { "-q",  FALSE, etBOOL, {&bCheck},
          "Check at every step which part of the sequence is helical" },
        { "-F",  FALSE, etBOOL, {&bFit},
          "Toggle fit to a perfect helix" },
        { "-db", FALSE, etBOOL, {&bDBG},
          "Print debug info" },
        { "-ev", FALSE, etBOOL, {&bEV},
          "Write a new 'trajectory' file for ED" },
        { "-ahxstart", FALSE, etINT, {&rStart},
          "First residue in helix" },
        { "-ahxend", FALSE, etINT, {&rEnd},
          "Last residue in helix" }
    };

    typedef struct {
        FILE       *fp, *fp2;
        gmx_bool    bfp2;
        const char *filenm;
        const char *title;
        const char *xaxis;
        const char *yaxis;
        real        val;
    } t_xvgrfile;

    t_xvgrfile     xf[efhNR] = {
        { NULL, NULL, TRUE,  "radius",  "Helix radius",               NULL, "r (nm)", 0.0 },
        { NULL, NULL, TRUE,  "twist",   "Twist per residue",          NULL, "Angle (deg)", 0.0 },
        { NULL, NULL, TRUE,  "rise",    "Rise per residue",           NULL, "Rise (nm)", 0.0 },
        { NULL, NULL, FALSE, "len-ahx", "Length of the Helix",        NULL, "Length (nm)", 0.0 },
        { NULL, NULL, FALSE, "dip-ahx", "Helix Backbone Dipole",      NULL, "rq (nm e)", 0.0 },
        { NULL, NULL, TRUE,  "rms-ahx", "RMS Deviation from Ideal Helix", NULL, "RMS (nm)", 0.0 },
        { NULL, NULL, FALSE, "rmsa-ahx", "Average RMSD per Residue",   "Residue", "RMS (nm)", 0.0 },
        { NULL, NULL, FALSE,  "cd222",   "Ellipticity at 222 nm", NULL, "nm", 0.0 },
        { NULL, NULL, TRUE,  "pprms",   "RMS Distance from \\8a\\4-helix", NULL, "deg", 0.0 },
        { NULL, NULL, TRUE,  "caphi",   "Average Ca-Ca Dihedral",     NULL, "\\8F\\4(deg)", 0.0 },
        { NULL, NULL, TRUE,  "phi",     "Average \\8F\\4 angles", NULL, "deg", 0.0 },
        { NULL, NULL, TRUE,  "psi",     "Average \\8Y\\4 angles", NULL, "deg", 0.0 },
        { NULL, NULL, TRUE,  "hb3",     "Average n-n+3 hbond length", NULL, "nm", 0.0 },
        { NULL, NULL, TRUE,  "hb4",     "Average n-n+4 hbond length", NULL, "nm", 0.0 },
        { NULL, NULL, TRUE,  "hb5",     "Average n-n+5 hbond length", NULL, "nm", 0.0 },
        { NULL, NULL, FALSE,  "JCaHa",   "J-Coupling Values",        "Residue", "Hz", 0.0 },
        { NULL, NULL, FALSE,  "helicity", "Helicity per Residue",     "Residue", "% of time", 0.0 }
    };

    output_env_t   oenv;
    char           buf[54];
    t_trxstatus   *status;
    int            natoms, nre, nres;
    t_bb          *bb;
    int            i, j, m, nall, nbb, nca, teller, nSel = 0;
    atom_id       *bbindex, *caindex, *allindex;
    t_topology    *top;
    int            ePBC;
    rvec          *x, *xref;
    real           t;
    real           rms;
    matrix         box;
    gmx_rmpbc_t    gpbc = NULL;
    gmx_bool       bRange;
    t_filenm       fnm[] = {
        { efTPX, NULL,  NULL,   ffREAD  },
        { efNDX, NULL,  NULL,   ffREAD  },
        { efTRX, "-f",  NULL,   ffREAD  },
        { efSTO, "-cz", "zconf", ffWRITE },
    };
#define NFILE asize(fnm)

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

    bRange = (opt2parg_bSet("-ahxstart", asize(pa), pa) &&
              opt2parg_bSet("-ahxend", asize(pa), pa));

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

    natoms = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box);

    if (natoms != top->atoms.nr)
    {
        gmx_fatal(FARGS, "Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)",
                  top->atoms.nr, natoms);
    }

    bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex,
                 top->atoms.atomname, top->atoms.atom, top->atoms.resinfo);
    snew(bbindex, natoms);
    snew(caindex, nres);

    fprintf(stderr, "nall=%d\n", nall);

    /* Open output files, default x-axis is time */
    for (i = 0; (i < efhNR); i++)
    {
        sprintf(buf, "%s.xvg", xf[i].filenm);
        remove(buf);
        xf[i].fp = xvgropen(buf, xf[i].title,
                            xf[i].xaxis ? xf[i].xaxis : "Time (ps)",
                            xf[i].yaxis, oenv);
        if (xf[i].bfp2)
        {
            sprintf(buf, "%s.out", xf[i].filenm);
            remove(buf);
            xf[i].fp2 = gmx_ffopen(buf, "w");
        }
    }

    /* Read reference frame from tpx file to compute helix length */
    snew(xref, top->atoms.nr);
    read_tpx(ftp2fn(efTPX, NFILE, fnm),
             NULL, NULL, &natoms, xref, NULL, NULL, NULL);
    calc_hxprops(nres, bb, xref);
    do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, bRange, rStart, rEnd);
    sfree(xref);
    if (bDBG)
    {
        fprintf(stderr, "nca=%d, nbb=%d\n", nca, nbb);
        pr_bb(stdout, nres, bb);
    }

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

    teller = 0;
    do
    {
        if ((teller++ % 10) == 0)
        {
            fprintf(stderr, "\rt=%.2f", t);
        }
        gmx_rmpbc(gpbc, natoms, box, x);


        calc_hxprops(nres, bb, x);
        if (bCheck)
        {
            do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, FALSE, 0, 0);
        }

        if (nca >= 5)
        {
            rms = fit_ahx(nres, bb, natoms, nall, allindex, x, nca, caindex, bFit);

            if (teller == 1)
            {
                write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis",
                               &(top->atoms), x, NULL, ePBC, box);
            }

            xf[efhRAD].val   = radius(xf[efhRAD].fp2, nca, caindex, x);
            xf[efhTWIST].val = twist(nca, caindex, x);
            xf[efhRISE].val  = rise(nca, caindex, x);
            xf[efhLEN].val   = ahx_len(nca, caindex, x);
            xf[efhCD222].val = ellipticity(nres, bb);
            xf[efhDIP].val   = dip(nbb, bbindex, x, top->atoms.atom);
            xf[efhRMS].val   = rms;
            xf[efhCPHI].val  = ca_phi(nca, caindex, x);
            xf[efhPPRMS].val = pprms(xf[efhPPRMS].fp2, nres, bb);

            for (j = 0; (j <= efhCPHI); j++)
            {
                fprintf(xf[j].fp,   "%10g  %10g\n", t, xf[j].val);
            }

            av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2,
                      t, nres, bb);
            av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2,
                     xf[efhHB4].fp, xf[efhHB4].fp2,
                     xf[efhHB5].fp, xf[efhHB5].fp2,
                     t, nres, bb);
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");

    gmx_rmpbc_done(gpbc);

    close_trj(status);

    for (i = 0; (i < nres); i++)
    {
        if (bb[i].nrms > 0)
        {
            fprintf(xf[efhRMSA].fp, "%10d  %10g\n", r0+i, bb[i].rmsa/bb[i].nrms);
        }
        fprintf(xf[efhAHX].fp, "%10d  %10g\n", r0+i, (bb[i].nhx*100.0)/(real )teller);
        fprintf(xf[efhJCA].fp, "%10d  %10g\n",
                r0+i, 140.3+(bb[i].jcaha/(double)teller));
    }

    for (i = 0; (i < efhNR); i++)
    {
        gmx_ffclose(xf[i].fp);
        if (xf[i].bfp2)
        {
            gmx_ffclose(xf[i].fp2);
        }
        do_view(oenv, xf[i].filenm, "-nxy");
    }

    return 0;
}
Exemplo n.º 16
0
int gmx_do_dssp(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] ",
        "reads a trajectory file and computes the secondary structure for",
        "each time frame ",
        "calling the dssp program. If you do not have the dssp program,",
        "get it from http://swift.cmbi.ru.nl/gv/dssp. [THISMODULE] assumes ",
        "that the dssp executable is located in ",
        "[TT]/usr/local/bin/dssp[tt]. If this is not the case, then you should",
        "set an environment variable [TT]DSSP[tt] pointing to the dssp",
        "executable, e.g.: [PAR]",
        "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]",
        "Since version 2.0.0, dssp is invoked with a syntax that differs",
        "from earlier versions. If you have an older version of dssp,",
        "use the [TT]-ver[tt] option to direct do_dssp to use the older syntax.",
        "By default, do_dssp uses the syntax introduced with version 2.0.0.",
        "Even newer versions (which at the time of writing are not yet released)",
        "are assumed to have the same syntax as 2.0.0.[PAR]",
        "The structure assignment for each residue and time is written to an",
        "[TT].xpm[tt] matrix file. This file can be visualized with for instance",
        "[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].",
        "Individual chains are separated by light grey lines in the [TT].xpm[tt] and",
        "postscript files.",
        "The number of residues with each secondary structure type and the",
        "total secondary structure ([TT]-sss[tt]) count as a function of",
        "time are also written to file ([TT]-sc[tt]).[PAR]",
        "Solvent accessible surface (SAS) per residue can be calculated, both in",
        "absolute values (A^2) and in fractions of the maximal accessible",
        "surface of a residue. The maximal accessible surface is defined as",
        "the accessible surface of a residue in a chain of glycines.",
        "[BB]Note[bb] that the program [gmx-sas] can also compute SAS",
        "and that is more efficient.[PAR]",
        "Finally, this program can dump the secondary structure in a special file",
        "[TT]ssdump.dat[tt] for usage in the program [gmx-chi]. Together",
        "these two programs can be used to analyze dihedral properties as a",
        "function of secondary structure type."
    };
    static gmx_bool    bVerbose;
    static const char *ss_string   = "HEBT";
    static int         dsspVersion = 2;
    t_pargs            pa[]        = {
        { "-v",  FALSE, etBOOL, {&bVerbose},
          "HIDDENGenerate miles of useless information" },
        { "-sss", FALSE, etSTR, {&ss_string},
          "Secondary structures for structure count"},
        { "-ver", FALSE, etINT, {&dsspVersion},
          "DSSP major version. Syntax changed with version 2"}
    };

    t_trxstatus       *status;
    FILE              *tapein;
    FILE              *ss, *acc, *fTArea, *tmpf;
    const char        *fnSCount, *fnArea, *fnTArea, *fnAArea;
    const char        *leg[] = { "Phobic", "Phylic" };
    t_topology         top;
    int                ePBC;
    t_atoms           *atoms;
    t_matrix           mat;
    int                nres, nr0, naccr, nres_plus_separators;
    gmx_bool          *bPhbres, bDoAccSurf;
    real               t;
    int                i, j, natoms, nframe = 0;
    matrix             box = {{0}};
    int                gnx;
    char              *grpnm, *ss_str;
    atom_id           *index;
    rvec              *xp, *x;
    int               *average_area;
    real             **accr, *accr_ptr = NULL, *av_area, *norm_av_area;
    char               pdbfile[32], tmpfile[32], title[256];
    char               dssp[256];
    const char        *dptr;
    output_env_t       oenv;
    gmx_rmpbc_t        gpbc = NULL;

    t_filenm           fnm[] = {
        { efTRX, "-f",   NULL,      ffREAD },
        { efTPS, NULL,   NULL,      ffREAD },
        { efNDX, NULL,   NULL,      ffOPTRD },
        { efDAT, "-ssdump", "ssdump", ffOPTWR },
        { efMAP, "-map", "ss",      ffLIBRD },
        { efXPM, "-o",   "ss",      ffWRITE },
        { efXVG, "-sc",  "scount",  ffWRITE },
        { efXPM, "-a",   "area",    ffOPTWR },
        { efXVG, "-ta",  "totarea", ffOPTWR },
        { efXVG, "-aa",  "averarea", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv,
                           PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }
    fnSCount   = opt2fn("-sc", NFILE, fnm);
    fnArea     = opt2fn_null("-a", NFILE, fnm);
    fnTArea    = opt2fn_null("-ta", NFILE, fnm);
    fnAArea    = opt2fn_null("-aa", NFILE, fnm);
    bDoAccSurf = (fnArea || fnTArea || fnAArea);

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xp, NULL, box, FALSE);
    atoms = &(top.atoms);
    check_oo(atoms);
    bPhbres = bPhobics(atoms);

    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpnm);
    nres = 0;
    nr0  = -1;
    for (i = 0; (i < gnx); i++)
    {
        if (atoms->atom[index[i]].resind != nr0)
        {
            nr0 = atoms->atom[index[i]].resind;
            nres++;
        }
    }
    fprintf(stderr, "There are %d residues in your selected group\n", nres);

    strcpy(pdbfile, "ddXXXXXX");
    gmx_tmpnam(pdbfile);
    if ((tmpf = fopen(pdbfile, "w")) == NULL)
    {
        sprintf(pdbfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
        gmx_tmpnam(pdbfile);
        if ((tmpf = fopen(pdbfile, "w")) == NULL)
        {
            gmx_fatal(FARGS, "Can not open tmp file %s", pdbfile);
        }
    }
    else
    {
        fclose(tmpf);
    }

    strcpy(tmpfile, "ddXXXXXX");
    gmx_tmpnam(tmpfile);
    if ((tmpf = fopen(tmpfile, "w")) == NULL)
    {
        sprintf(tmpfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
        gmx_tmpnam(tmpfile);
        if ((tmpf = fopen(tmpfile, "w")) == NULL)
        {
            gmx_fatal(FARGS, "Can not open tmp file %s", tmpfile);
        }
    }
    else
    {
        fclose(tmpf);
    }

    if ((dptr = getenv("DSSP")) == NULL)
    {
        dptr = "/usr/local/bin/dssp";
    }
    if (!gmx_fexist(dptr))
    {
        gmx_fatal(FARGS, "DSSP executable (%s) does not exist (use setenv DSSP)",
                  dptr);
    }
    if (dsspVersion >= 2)
    {
        if (dsspVersion > 2)
        {
            printf("\nWARNING: You use DSSP version %d, which is not explicitly\nsupported by do_dssp. Assuming version 2 syntax.\n\n", dsspVersion);
        }

        sprintf(dssp, "%s -i %s -o %s > /dev/null %s",
                dptr, pdbfile, tmpfile, bVerbose ? "" : "2> /dev/null");
    }
    else
    {
        sprintf(dssp, "%s %s %s %s > /dev/null %s",
                dptr, bDoAccSurf ? "" : "-na", pdbfile, tmpfile, bVerbose ? "" : "2> /dev/null");

    }
    fprintf(stderr, "dssp cmd='%s'\n", dssp);

    if (fnTArea)
    {
        fTArea = xvgropen(fnTArea, "Solvent Accessible Surface Area",
                          output_env_get_xvgr_tlabel(oenv), "Area (nm\\S2\\N)", oenv);
        xvgr_legend(fTArea, 2, leg, oenv);
    }
    else
    {
        fTArea = NULL;
    }

    mat.map  = NULL;
    mat.nmap = readcmap(opt2fn("-map", NFILE, fnm), &(mat.map));

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    if (natoms > atoms->nr)
    {
        gmx_fatal(FARGS, "\nTrajectory does not match topology!");
    }
    if (gnx > natoms)
    {
        gmx_fatal(FARGS, "\nTrajectory does not match selected group!");
    }

    snew(average_area, atoms->nres);
    snew(av_area, atoms->nres);
    snew(norm_av_area, atoms->nres);
    accr  = NULL;
    naccr = 0;

    gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    do
    {
        t = output_env_conv_time(oenv, t);
        if (bDoAccSurf && nframe >= naccr)
        {
            naccr += 10;
            srenew(accr, naccr);
            for (i = naccr-10; i < naccr; i++)
            {
                snew(accr[i], 2*atoms->nres-1);
            }
        }
        gmx_rmpbc(gpbc, natoms, box, x);
        tapein = gmx_ffopen(pdbfile, "w");
        write_pdbfile_indexed(tapein, NULL, atoms, x, ePBC, box, ' ', -1, gnx, index, NULL, TRUE);
        gmx_ffclose(tapein);

        if (0 != system(dssp))
        {
            gmx_fatal(FARGS, "Failed to execute command: %s\n",
                      "Try specifying your dssp version with the -ver option.", dssp);
        }

        /* strip_dssp returns the number of lines found in the dssp file, i.e.
         * the number of residues plus the separator lines */

        if (bDoAccSurf)
        {
            accr_ptr = accr[nframe];
        }

        nres_plus_separators = strip_dssp(tmpfile, nres, bPhbres, t,
                                          accr_ptr, fTArea, &mat, average_area, oenv);
        remove(tmpfile);
        remove(pdbfile);
        nframe++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");
    close_trj(status);
    if (fTArea)
    {
        xvgrclose(fTArea);
    }
    gmx_rmpbc_done(gpbc);

    prune_ss_legend(&mat);

    ss        = opt2FILE("-o", NFILE, fnm, "w");
    mat.flags = 0;
    write_xpm_m(ss, mat);
    gmx_ffclose(ss);

    if (opt2bSet("-ssdump", NFILE, fnm))
    {
        ss = opt2FILE("-ssdump", NFILE, fnm, "w");
        snew(ss_str, nres+1);
        fprintf(ss, "%d\n", nres);
        for (j = 0; j < mat.nx; j++)
        {
            for (i = 0; (i < mat.ny); i++)
            {
                ss_str[i] = mat.map[mat.matrix[j][i]].code.c1;
            }
            ss_str[i] = '\0';
            fprintf(ss, "%s\n", ss_str);
        }
        gmx_ffclose(ss);
        sfree(ss_str);
    }
    analyse_ss(fnSCount, &mat, ss_string, oenv);

    if (bDoAccSurf)
    {
        write_sas_mat(fnArea, accr, nframe, nres_plus_separators, &mat);

        for (i = 0; i < atoms->nres; i++)
        {
            av_area[i] = (average_area[i] / (real)nframe);
        }

        norm_acc(atoms, nres, av_area, norm_av_area);

        if (fnAArea)
        {
            acc = xvgropen(fnAArea, "Average Accessible Area",
                           "Residue", "A\\S2", oenv);
            for (i = 0; (i < nres); i++)
            {
                fprintf(acc, "%5d  %10g %10g\n", i+1, av_area[i], norm_av_area[i]);
            }
            xvgrclose(acc);
        }
    }

    view_all(oenv, NFILE, fnm);

    return 0;
}
Exemplo n.º 17
0
static void find_nearest_neighbours(int ePBC,
                                    int natoms, matrix box,
                                    rvec x[], int maxidx, atom_id index[],
                                    real *sgmean, real *skmean,
                                    int nslice, int slice_dim,
                                    real sgslice[], real skslice[],
                                    gmx_rmpbc_t gpbc)
{
    int      ix, jx, nsgbin, *sgbin;
    int      i, ibin, j, k, l, n, *nn[4];
    rvec     dx, rj, rk, urk, urj;
    real     cost, cost2, *sgmol, *skmol, rmean, rmean2, r2, box2, *r_nn[4];
    t_pbc    pbc;
    int      sl_index;
    int     *sl_count;
    real     onethird = 1.0/3.0;
    /*  dmat = init_mat(maxidx, FALSE); */
    box2 = box[XX][XX] * box[XX][XX];
    snew(sl_count, nslice);
    for (i = 0; (i < 4); i++)
    {
        snew(r_nn[i], natoms);
        snew(nn[i], natoms);

        for (j = 0; (j < natoms); j++)
        {
            r_nn[i][j] = box2;
        }
    }

    snew(sgmol, maxidx);
    snew(skmol, maxidx);

    /* Must init pbc every step because of pressure coupling */
    set_pbc(&pbc, ePBC, box);

    gmx_rmpbc(gpbc, natoms, box, x);

    nsgbin = 2001; // Calculated as (1 + 1/0.0005)
    snew(sgbin, nsgbin);

    *sgmean = 0.0;
    *skmean = 0.0;
    l       = 0;
    for (i = 0; (i < maxidx); i++) /* loop over index file */
    {
        ix = index[i];
        for (j = 0; (j < maxidx); j++)
        {
            if (i == j)
            {
                continue;
            }

            jx = index[j];

            pbc_dx(&pbc, x[ix], x[jx], dx);
            r2 = iprod(dx, dx);

            /* set_mat_entry(dmat,i,j,r2); */

            /* determine the nearest neighbours */
            if (r2 < r_nn[0][i])
            {
                r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i];
                r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i];
                r_nn[1][i] = r_nn[0][i]; nn[1][i] = nn[0][i];
                r_nn[0][i] = r2;         nn[0][i] = j;
            }
            else if (r2 < r_nn[1][i])
            {
                r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i];
                r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i];
                r_nn[1][i] = r2;         nn[1][i] = j;
            }
            else if (r2 < r_nn[2][i])
            {
                r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i];
                r_nn[2][i] = r2;         nn[2][i] = j;
            }
            else if (r2 < r_nn[3][i])
            {
                r_nn[3][i] = r2;         nn[3][i] = j;
            }
        }


        /* calculate mean distance between nearest neighbours */
        rmean = 0;
        for (j = 0; (j < 4); j++)
        {
            r_nn[j][i] = std::sqrt(r_nn[j][i]);
            rmean     += r_nn[j][i];
        }
        rmean /= 4;

        n        = 0;
        sgmol[i] = 0.0;
        skmol[i] = 0.0;

        /* Chau1998a eqn 3 */
        /* angular part tetrahedrality order parameter per atom */
        for (j = 0; (j < 3); j++)
        {
            for (k = j+1; (k < 4); k++)
            {
                pbc_dx(&pbc, x[ix], x[index[nn[k][i]]], rk);
                pbc_dx(&pbc, x[ix], x[index[nn[j][i]]], rj);

                unitv(rk, urk);
                unitv(rj, urj);

                cost  = iprod(urk, urj) + onethird;
                cost2 = cost * cost;

                /* sgmol[i] += 3*cost2/32;  */
                sgmol[i] += cost2;

                /* determine distribution */
                ibin = static_cast<int>(nsgbin * cost2);
                if (ibin < nsgbin)
                {
                    sgbin[ibin]++;
                }
                /* printf("%d %d %f %d %d\n", j, k, cost * cost, ibin, sgbin[ibin]);*/
                l++;
                n++;
            }
        }

        /* normalize sgmol between 0.0 and 1.0 */
        sgmol[i] = 3*sgmol[i]/32;
        *sgmean += sgmol[i];

        /* distance part tetrahedrality order parameter per atom */
        rmean2 = 4 * 3 * rmean * rmean;
        for (j = 0; (j < 4); j++)
        {
            skmol[i] += (rmean - r_nn[j][i]) * (rmean - r_nn[j][i]) / rmean2;
            /*      printf("%d %f (%f %f %f %f) \n",
                i, skmol[i], rmean, rmean2, r_nn[j][i], (rmean - r_nn[j][i]) );
             */
        }

        *skmean += skmol[i];

        /* Compute sliced stuff */
        sl_index           = static_cast<int>(std::round((1+x[i][slice_dim]/box[slice_dim][slice_dim])*nslice)) % nslice;
        sgslice[sl_index] += sgmol[i];
        skslice[sl_index] += skmol[i];
        sl_count[sl_index]++;
    } /* loop over entries in index file */

    *sgmean /= maxidx;
    *skmean /= maxidx;

    for (i = 0; (i < nslice); i++)
    {
        if (sl_count[i] > 0)
        {
            sgslice[i] /= sl_count[i];
            skslice[i] /= sl_count[i];
        }
    }
    sfree(sl_count);
    sfree(sgbin);
    sfree(sgmol);
    sfree(skmol);
    for (i = 0; (i < 4); i++)
    {
        sfree(r_nn[i]);
        sfree(nn[i]);
    }
}
Exemplo n.º 18
0
void sas_plot(int nfile,t_filenm fnm[],real solsize,int ndots,
	      real qcut,gmx_bool bSave,real minarea,gmx_bool bPBC,
	      real dgs_default,gmx_bool bFindex, const output_env_t oenv)
{
  FILE         *fp,*fp2,*fp3=NULL,*vp;
  const char   *flegend[] = { "Hydrophobic", "Hydrophilic", 
			      "Total", "D Gsolv" };
  const char   *vlegend[] = { "Volume (nm\\S3\\N)", "Density (g/l)" };
  const char   *or_and_oa_legend[] = { "Average (nm\\S2\\N)", "Standard deviation (nm\\S2\\N)" };
  const char   *vfile;
  real         t;
  gmx_atomprop_t aps=NULL;
  gmx_rmpbc_t  gpbc=NULL;
  t_trxstatus  *status;
  int          ndefault;
  int          i,j,ii,nfr,natoms,flag,nsurfacedots,res;
  rvec         *xtop,*x;
  matrix       topbox,box;
  t_topology   top;
  char         title[STRLEN];
  int          ePBC;
  gmx_bool         bTop;
  t_atoms      *atoms;
  gmx_bool         *bOut,*bPhobic;
  gmx_bool         bConnelly;
  gmx_bool         bResAt,bITP,bDGsol;
  real         *radius,*dgs_factor=NULL,*area=NULL,*surfacedots=NULL;
  real         at_area,*atom_area=NULL,*atom_area2=NULL;
  real         *res_a=NULL,*res_area=NULL,*res_area2=NULL;
  real         totarea,totvolume,totmass=0,density,harea,tarea,fluc2;
  atom_id      **index,*findex;
  int          *nx,nphobic,npcheck,retval;
  char         **grpname,*fgrpname;
  real         dgsolv;

  bITP   = opt2bSet("-i",nfile,fnm);
  bResAt = opt2bSet("-or",nfile,fnm) || opt2bSet("-oa",nfile,fnm) || bITP;

  bTop = read_tps_conf(ftp2fn(efTPS,nfile,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,FALSE);
  atoms = &(top.atoms);
  
  if (!bTop) {
    fprintf(stderr,"No tpr file, will not compute Delta G of solvation\n");
    bDGsol = FALSE;
  } else {
    bDGsol = strcmp(*(atoms->atomtype[0]),"?") != 0;
    if (!bDGsol) {
      fprintf(stderr,"Warning: your tpr file is too old, will not compute "
	      "Delta G of solvation\n");
    } else {
      printf("In case you use free energy of solvation predictions:\n");
      please_cite(stdout,"Eisenberg86a");
    }
  }

  aps = gmx_atomprop_init();
  
  if ((natoms=read_first_x(oenv,&status,ftp2fn(efTRX,nfile,fnm),
			   &t,&x,box))==0)
    gmx_fatal(FARGS,"Could not read coordinates from statusfile\n");

  if ((ePBC != epbcXYZ) || (TRICLINIC(box))) {
    fprintf(stderr,"\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n"
	    "Analysis based on vacuum simulations (with the possibility of evaporation)\n" 
	    "will certainly crash the analysis.\n\n");
  }
  snew(nx,2);
  snew(index,2);
  snew(grpname,2);
  fprintf(stderr,"Select a group for calculation of surface and a group for output:\n");
  get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),2,nx,index,grpname);

  if (bFindex) {
    fprintf(stderr,"Select a group of hydrophobic atoms:\n");
    get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),1,&nphobic,&findex,&fgrpname);
  }
  snew(bOut,natoms);
  for(i=0; i<nx[1]; i++)
    bOut[index[1][i]] = TRUE;

  /* Now compute atomic readii including solvent probe size */
  snew(radius,natoms);
  snew(bPhobic,nx[0]);
  if (bResAt) {
    snew(atom_area,nx[0]);
    snew(atom_area2,nx[0]);
    snew(res_a,atoms->nres);
    snew(res_area,atoms->nres);
    snew(res_area2,atoms->nres);
  }
  if (bDGsol)
    snew(dgs_factor,nx[0]);

  /* Get a Van der Waals radius for each atom */
  ndefault = 0;
  for(i=0; (i<natoms); i++) {
    if (!gmx_atomprop_query(aps,epropVDW,
			    *(atoms->resinfo[atoms->atom[i].resind].name),
			    *(atoms->atomname[i]),&radius[i]))
      ndefault++;
    /* radius[i] = calc_radius(*(top->atoms.atomname[i])); */
    radius[i] += solsize;
  }
  if (ndefault > 0)
    fprintf(stderr,"WARNING: could not find a Van der Waals radius for %d atoms\n",ndefault);
  /* Determine which atom is counted as hydrophobic */
  if (bFindex) {
    npcheck = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      for(j=0; (j<nphobic); j++) {
	if (findex[j] == ii) {
	  bPhobic[i] = TRUE;
	  if (bOut[ii])
	    npcheck++;
	}
      }
    }
    if (npcheck != nphobic)
      gmx_fatal(FARGS,"Consistency check failed: not all %d atoms in the hydrophobic index\n"
		  "found in the normal index selection (%d atoms)",nphobic,npcheck);
  }
  else
    nphobic = 0;
    
  for(i=0; (i<nx[0]); i++) {
    ii = index[0][i];
    if (!bFindex) {
      bPhobic[i] = fabs(atoms->atom[ii].q) <= qcut;
      if (bPhobic[i] && bOut[ii])
	nphobic++;
    }
    if (bDGsol)
      if (!gmx_atomprop_query(aps,epropDGsol,
			      *(atoms->resinfo[atoms->atom[ii].resind].name),
			      *(atoms->atomtype[ii]),&(dgs_factor[i])))
	dgs_factor[i] = dgs_default;
    if (debug)
      fprintf(debug,"Atom %5d %5s-%5s: q= %6.3f, r= %6.3f, dgsol= %6.3f, hydrophobic= %s\n",
	      ii+1,*(atoms->resinfo[atoms->atom[ii].resind].name),
	      *(atoms->atomname[ii]),
	      atoms->atom[ii].q,radius[ii]-solsize,dgs_factor[i],
	      BOOL(bPhobic[i]));
  }
  fprintf(stderr,"%d out of %d atoms were classified as hydrophobic\n",
	  nphobic,nx[1]);
  
  fp=xvgropen(opt2fn("-o",nfile,fnm),"Solvent Accessible Surface","Time (ps)",
	      "Area (nm\\S2\\N)",oenv);
  xvgr_legend(fp,asize(flegend) - (bDGsol ? 0 : 1),flegend,oenv);
  vfile = opt2fn_null("-tv",nfile,fnm);
  if (vfile) {
    if (!bTop) {
      gmx_fatal(FARGS,"Need a tpr file for option -tv");
    }
    vp=xvgropen(vfile,"Volume and Density","Time (ps)","",oenv);
    xvgr_legend(vp,asize(vlegend),vlegend,oenv);
    totmass  = 0;
    ndefault = 0;
    for(i=0; (i<nx[0]); i++) {
      real mm;
      ii = index[0][i];
      /*
      if (!query_atomprop(atomprop,epropMass,
			  *(top->atoms.resname[top->atoms.atom[ii].resnr]),
			  *(top->atoms.atomname[ii]),&mm))
	ndefault++;
      totmass += mm;
      */
      totmass += atoms->atom[ii].m;
    }
    if (ndefault)
      fprintf(stderr,"WARNING: Using %d default masses for density calculation, which most likely are inaccurate\n",ndefault);
  }
  else
    vp = NULL;
    
  gmx_atomprop_destroy(aps);

  if (bPBC)
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,natoms,box);
  
  nfr=0;
  do {
    if (bPBC)
      gmx_rmpbc(gpbc,natoms,box,x);
    
    bConnelly = (nfr==0 && opt2bSet("-q",nfile,fnm));
    if (bConnelly) {
      if (!bTop)
	gmx_fatal(FARGS,"Need a tpr file for Connelly plot");
      flag = FLAG_ATOM_AREA | FLAG_DOTS;
    } else {
      flag = FLAG_ATOM_AREA;
    }
    if (vp) {
      flag = flag | FLAG_VOLUME;
    }
      
    if (debug)
      write_sto_conf("check.pdb","pbc check",atoms,x,NULL,ePBC,box);

    retval = nsc_dclm_pbc(x,radius,nx[0],ndots,flag,&totarea,
			  &area,&totvolume,&surfacedots,&nsurfacedots,
			  index[0],ePBC,bPBC ? box : NULL);
    if (retval)
      gmx_fatal(FARGS,"Something wrong in nsc_dclm_pbc");
    
    if (bConnelly)
      connelly_plot(ftp2fn(efPDB,nfile,fnm),
		    nsurfacedots,surfacedots,x,atoms,
		    &(top.symtab),ePBC,box,bSave);
    harea  = 0; 
    tarea  = 0;
    dgsolv = 0;
    if (bResAt)
      for(i=0; i<atoms->nres; i++)
	res_a[i] = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      if (bOut[ii]) {
	at_area = area[i];
	if (bResAt) {
	  atom_area[i] += at_area;
	  atom_area2[i] += sqr(at_area);
	  res_a[atoms->atom[ii].resind] += at_area;
	}
	tarea += at_area;
	if (bDGsol)
	  dgsolv += at_area*dgs_factor[i];
	if (bPhobic[i])
	  harea += at_area;
      }
    }
    if (bResAt)
      for(i=0; i<atoms->nres; i++) {
	res_area[i] += res_a[i];
	res_area2[i] += sqr(res_a[i]);
      }
    fprintf(fp,"%10g  %10g  %10g  %10g",t,harea,tarea-harea,tarea);
    if (bDGsol)
      fprintf(fp,"  %10g\n",dgsolv);
    else
      fprintf(fp,"\n");
    
    /* Print volume */
    if (vp) {
      density = totmass*AMU/(totvolume*NANO*NANO*NANO);
      fprintf(vp,"%12.5e  %12.5e  %12.5e\n",t,totvolume,density);
    }
    if (area) {
      sfree(area);
      area = NULL;
    }
    if (surfacedots) {
      sfree(surfacedots);
      surfacedots = NULL;
    }
    nfr++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));

  if (bPBC)  
    gmx_rmpbc_done(gpbc);

  fprintf(stderr,"\n");
  close_trj(status);
  ffclose(fp);
  if (vp)
    ffclose(vp);
    
  /* if necessary, print areas per atom to file too: */
  if (bResAt) {
    for(i=0; i<atoms->nres; i++) {
      res_area[i] /= nfr;
      res_area2[i] /= nfr;
    }
    for(i=0; i<nx[0]; i++) {
      atom_area[i] /= nfr;
      atom_area2[i] /= nfr;
    }
    fprintf(stderr,"Printing out areas per atom\n");
    fp  = xvgropen(opt2fn("-or",nfile,fnm),"Area per residue over the trajectory","Residue",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    fp2 = xvgropen(opt2fn("-oa",nfile,fnm),"Area per atom over the trajectory","Atom #",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp2, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    if (bITP) {
      fp3 = ftp2FILE(efITP,nfile,fnm,"w");
      fprintf(fp3,"[ position_restraints ]\n"
	      "#define FCX 1000\n"
	      "#define FCY 1000\n"
	      "#define FCZ 1000\n"
	      "; Atom  Type  fx   fy   fz\n");
    }
    for(i=0; i<nx[0]; i++) {
      ii = index[0][i];
      res = atoms->atom[ii].resind;
      if (i==nx[0]-1 || res!=atoms->atom[index[0][i+1]].resind) {
	fluc2 = res_area2[res]-sqr(res_area[res]);
	if (fluc2 < 0)
	  fluc2 = 0;
	fprintf(fp,"%10d  %10g %10g\n",
		atoms->resinfo[res].nr,res_area[res],sqrt(fluc2));
      }
      fluc2 = atom_area2[i]-sqr(atom_area[i]);
      if (fluc2 < 0)
	fluc2 = 0;
      fprintf(fp2,"%d %g %g\n",index[0][i]+1,atom_area[i],sqrt(fluc2));
      if (bITP && (atom_area[i] > minarea))
	fprintf(fp3,"%5d   1     FCX  FCX  FCZ\n",ii+1);
    }
    if (bITP)
      ffclose(fp3);
    ffclose(fp);
  }

    /* Be a good citizen, keep our memory free! */
    sfree(x);
    sfree(nx);
    for(i=0;i<2;i++)
    {
        sfree(index[i]);
        sfree(grpname[i]);
    }
    sfree(bOut);
    sfree(radius);
    sfree(bPhobic);
    
    if(bResAt)
    {
        sfree(atom_area);
        sfree(atom_area2);
        sfree(res_a);
        sfree(res_area);
        sfree(res_area2);
    }
    if(bDGsol)
    {
        sfree(dgs_factor);
    }
}
Exemplo n.º 19
0
int gmx_trjorder(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] orders molecules according to the smallest distance",
        "to atoms in a reference group",
        "or on z-coordinate (with option [TT]-z[tt]).",
        "With distance ordering, it will ask for a group of reference",
        "atoms and a group of molecules. For each frame of the trajectory",
        "the selected molecules will be reordered according to the shortest",
        "distance between atom number [TT]-da[tt] in the molecule and all the",
        "atoms in the reference group. The center of mass of the molecules can",
        "be used instead of a reference atom by setting [TT]-da[tt] to 0.",
        "All atoms in the trajectory are written",
        "to the output trajectory.[PAR]",
        "[THISMODULE] can be useful for e.g. analyzing the n waters closest to a",
        "protein.",
        "In that case the reference group would be the protein and the group",
        "of molecules would consist of all the water atoms. When an index group",
        "of the first n waters is made, the ordered trajectory can be used",
        "with any GROMACS program to analyze the n closest waters.",
        "[PAR]",
        "If the output file is a [REF].pdb[ref] file, the distance to the reference target",
        "will be stored in the B-factor field in order to color with e.g. Rasmol.",
        "[PAR]",
        "With option [TT]-nshell[tt] the number of molecules within a shell",
        "of radius [TT]-r[tt] around the reference group are printed."
    };
    static int      na   = 3, ref_a = 1;
    static real     rcut = 0;
    static gmx_bool bCOM = FALSE, bZ = FALSE;
    t_pargs         pa[] = {
        { "-na", FALSE, etINT,  {&na},
          "Number of atoms in a molecule" },
        { "-da", FALSE, etINT,  {&ref_a},
          "Atom used for the distance calculation, 0 is COM" },
        { "-com", FALSE, etBOOL, {&bCOM},
          "Use the distance to the center of mass of the reference group" },
        { "-r",  FALSE, etREAL, {&rcut},
          "Cutoff used for the distance calculation when computing the number of molecules in a shell around e.g. a protein" },
        { "-z", FALSE, etBOOL, {&bZ},
          "Order molecules on z-coordinate" }
    };
    FILE           *fp;
    t_trxstatus    *out;
    t_trxstatus    *status;
    gmx_bool        bNShell, bPDBout;
    t_topology      top;
    int             ePBC;
    rvec           *x, *xsol, xcom, dx;
    matrix          box;
    t_pbc           pbc;
    gmx_rmpbc_t     gpbc;
    real            t, totmass, mass, rcut2 = 0, n2;
    int             natoms, nwat, ncut;
    char          **grpname;
    int             i, j, d, *isize, isize_ref = 0, isize_sol;
    atom_id         sa, sr, *swi, **index, *ind_ref = NULL, *ind_sol;
    output_env_t    oenv;
    t_filenm        fnm[] = {
        { efTRX, "-f", NULL, ffREAD  },
        { efTPS, NULL, NULL, ffREAD  },
        { efNDX, NULL, NULL, ffOPTRD },
        { efTRO, "-o", "ordered", ffOPTWR },
        { efXVG, "-nshell", "nshell", ffOPTWR }
    };
#define NFILE asize(fnm)

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

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

    /* get index groups */
    printf("Select %sa group of molecules to be ordered:\n",
           bZ ? "" : "a group of reference atoms and ");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bZ ? 1 : 2,
              isize, index, grpname);

    if (!bZ)
    {
        isize_ref = isize[0];
        isize_sol = isize[1];
        ind_ref   = index[0];
        ind_sol   = index[1];
    }
    else
    {
        isize_sol = isize[0];
        ind_sol   = index[0];
    }

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    if (natoms > top.atoms.nr)
    {
        gmx_fatal(FARGS, "Number of atoms in the run input file is larger than in the trjactory");
    }
    for (i = 0; (i < 2); i++)
    {
        for (j = 0; (j < isize[i]); j++)
        {
            if (index[i][j] > natoms)
            {
                gmx_fatal(FARGS, "An atom number in group %s is larger than the number of atoms in the trajectory");
            }
        }
    }

    if ((isize_sol % na) != 0)
    {
        gmx_fatal(FARGS, "Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
                  isize[1], na);
    }

    nwat = isize_sol/na;
    if (ref_a > na)
    {
        gmx_fatal(FARGS, "The reference atom can not be larger than the number of atoms in a molecule");
    }
    ref_a--;
    snew(xsol, nwat);
    snew(order, nwat);
    snew(swi, natoms);
    for (i = 0; (i < natoms); i++)
    {
        swi[i] = i;
    }

    out     = NULL;
    fp      = NULL;
    bNShell = ((opt2bSet("-nshell", NFILE, fnm)) ||
               (opt2parg_bSet("-r", asize(pa), pa)));
    bPDBout = FALSE;
    if (bNShell)
    {
        rcut2   = rcut*rcut;
        fp      = xvgropen(opt2fn("-nshell", NFILE, fnm), "Number of molecules",
                           "Time (ps)", "N", oenv);
        printf("Will compute the number of molecules within a radius of %g\n",
               rcut);
    }
    if (!bNShell || opt2bSet("-o", NFILE, fnm))
    {
        bPDBout = (fn2ftp(opt2fn("-o", NFILE, fnm)) == efPDB);
        if (bPDBout && !top.atoms.pdbinfo)
        {
            fprintf(stderr, "Creating pdbfino records\n");
            snew(top.atoms.pdbinfo, top.atoms.nr);
        }
        out = open_trx(opt2fn("-o", NFILE, fnm), "w");
    }
    gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);
        set_pbc(&pbc, ePBC, box);

        if (ref_a == -1)
        {
            /* Calculate the COM of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                totmass = 0;
                clear_rvec(xsol[i]);
                for (j = 0; j < na; j++)
                {
                    sa       = ind_sol[i*na+j];
                    mass     = top.atoms.atom[sa].m;
                    totmass += mass;
                    for (d = 0; d < DIM; d++)
                    {
                        xsol[i][d] += mass*x[sa][d];
                    }
                }
                svmul(1.0/totmass, xsol[i], xsol[i]);
            }
        }
        else
        {
            /* Copy the reference atom of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                copy_rvec(x[ind_sol[i*na+ref_a]], xsol[i]);
            }
        }

        if (bZ)
        {
            for (i = 0; (i < nwat); i++)
            {
                sa           = ind_sol[na*i];
                order[i].i   = sa;
                order[i].d2  = xsol[i][ZZ];
            }
        }
        else if (bCOM)
        {
            totmass = 0;
            clear_rvec(xcom);
            for (i = 0; i < isize_ref; i++)
            {
                mass     = top.atoms.atom[ind_ref[i]].m;
                totmass += mass;
                for (j = 0; j < DIM; j++)
                {
                    xcom[j] += mass*x[ind_ref[i]][j];
                }
            }
            svmul(1/totmass, xcom, xcom);
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, xcom, xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
        }
        else
        {
            /* Set distance to first atom */
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, x[ind_ref[0]], xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
            for (j = 1; (j < isize_ref); j++)
            {
                sr = ind_ref[j];
                for (i = 0; (i < nwat); i++)
                {
                    pbc_dx(&pbc, x[sr], xsol[i], dx);
                    n2 = norm2(dx);
                    if (n2 < order[i].d2)
                    {
                        order[i].d2  = n2;
                    }
                }
            }
        }

        if (bNShell)
        {
            ncut = 0;
            for (i = 0; (i < nwat); i++)
            {
                if (order[i].d2 <= rcut2)
                {
                    ncut++;
                }
            }
            fprintf(fp, "%10.3f  %8d\n", t, ncut);
        }
        if (out)
        {
            qsort(order, nwat, sizeof(*order), ocomp);
            for (i = 0; (i < nwat); i++)
            {
                for (j = 0; (j < na); j++)
                {
                    swi[ind_sol[na*i]+j] = order[i].i+j;
                }
            }

            /* Store the distance as the B-factor */
            if (bPDBout)
            {
                for (i = 0; (i < nwat); i++)
                {
                    for (j = 0; (j < na); j++)
                    {
                        top.atoms.pdbinfo[order[i].i+j].bfac = std::sqrt(order[i].d2);
                    }
                }
            }
            write_trx(out, natoms, swi, &top.atoms, 0, t, box, x, NULL, NULL);
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);
    if (out)
    {
        close_trx(out);
    }
    if (fp)
    {
        xvgrclose(fp);
    }
    gmx_rmpbc_done(gpbc);

    return 0;
}
Exemplo n.º 20
0
int gmx_helixorient(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] calculates the coordinates and direction of the average",
        "axis inside an alpha helix, and the direction/vectors of both the",
        "C[GRK]alpha[grk] and (optionally) a sidechain atom relative to the axis.[PAR]",
        "As input, you need to specify an index group with C[GRK]alpha[grk] atoms",
        "corresponding to an [GRK]alpha[grk]-helix of continuous residues. Sidechain",
        "directions require a second index group of the same size, containing",
        "the heavy atom in each residue that should represent the sidechain.[PAR]",
        "[BB]Note[bb] that this program does not do any fitting of structures.[PAR]",
        "We need four C[GRK]alpha[grk] coordinates to define the local direction of the helix",
        "axis.[PAR]",
        "The tilt/rotation is calculated from Euler rotations, where we define",
        "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as [IT]y[it], and the",
        "[IT]z[it]-axis from their cross product. We use the Euler Y-Z-X rotation, meaning",
        "we first tilt the helix axis (1) around and (2) orthogonal to the residues",
        "vector, and finally apply the (3) rotation around it. For debugging or other",
        "purposes, we also write out the actual Euler rotation angles as [TT]theta[1-3].xvg[tt]"
    };

    t_topology       *top = NULL;
    real              t;
    rvec             *x = NULL;
    matrix            box;
    t_trxstatus      *status;
    int               natoms;
    real              theta1, theta2, theta3;

    int               i, j, teller = 0;
    int               iCA, iSC;
    int              *ind_CA;
    int              *ind_SC;
    char             *gn_CA;
    char             *gn_SC;
    rvec              v1, v2;
    rvec             *x_CA, *x_SC;
    rvec             *r12;
    rvec             *r23;
    rvec             *r34;
    rvec             *diff13;
    rvec             *diff24;
    rvec             *helixaxis;
    rvec             *residuehelixaxis;
    rvec             *residueorigin;
    rvec             *residuevector;
    rvec             *sidechainvector;

    rvec             *residuehelixaxis_t0;
    rvec             *residuevector_t0;
    rvec             *axis3_t0;
    rvec             *residuehelixaxis_tlast;
    rvec             *residuevector_tlast;
    rvec             *axis3_tlast;
    rvec              refaxes[3], newaxes[3];
    rvec              unitaxes[3];
    rvec              rot_refaxes[3], rot_newaxes[3];

    real              tilt, rotation;
    rvec             *axis3;
    real             *twist, *residuetwist;
    real             *radius, *residueradius;
    real             *rise, *residuerise;
    real             *residuebending;

    real              tmp;
    real              weight[3];
    t_pbc             pbc;
    matrix            A;

    FILE             *fpaxis, *fpcenter, *fptilt, *fprotation;
    FILE             *fpradius, *fprise, *fptwist;
    FILE             *fptheta1, *fptheta2, *fptheta3;
    FILE             *fpbending;
    int               ePBC;

    gmx_output_env_t *oenv;
    gmx_rmpbc_t       gpbc = NULL;

    static  gmx_bool  bSC          = FALSE;
    static gmx_bool   bIncremental = FALSE;

    static t_pargs    pa[] = {
        { "-sidechain",      FALSE, etBOOL, {&bSC},
          "Calculate sidechain directions relative to helix axis too." },
        { "-incremental",        FALSE, etBOOL, {&bIncremental},
          "Calculate incremental rather than total rotation/tilt." },
    };
#define NPA asize(pa)

    t_filenm fnm[] = {
        { efTPR, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efDAT, "-oaxis",    "helixaxis", ffWRITE },
        { efDAT, "-ocenter",  "center", ffWRITE },
        { efXVG, "-orise",    "rise", ffWRITE },
        { efXVG, "-oradius",  "radius", ffWRITE },
        { efXVG, "-otwist",   "twist", ffWRITE },
        { efXVG, "-obending", "bending", ffWRITE },
        { efXVG, "-otilt",    "tilt", ffWRITE },
        { efXVG, "-orot",     "rotation", ffWRITE }
    };
#define NFILE asize(fnm)

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

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

    for (i = 0; i < 3; i++)
    {
        weight[i] = 1.0;
    }

    /* read index files */
    printf("Select a group of Calpha atoms corresponding to a single continuous helix:\n");
    get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iCA, &ind_CA, &gn_CA);
    snew(x_CA, iCA);
    snew(x_SC, iCA); /* sic! */

    snew(r12, iCA-3);
    snew(r23, iCA-3);
    snew(r34, iCA-3);
    snew(diff13, iCA-3);
    snew(diff24, iCA-3);
    snew(helixaxis, iCA-3);
    snew(twist, iCA);
    snew(residuetwist, iCA);
    snew(radius, iCA);
    snew(residueradius, iCA);
    snew(rise, iCA);
    snew(residuerise, iCA);
    snew(residueorigin, iCA);
    snew(residuehelixaxis, iCA);
    snew(residuevector, iCA);
    snew(sidechainvector, iCA);
    snew(residuebending, iCA);
    snew(residuehelixaxis_t0, iCA);
    snew(residuevector_t0, iCA);
    snew(axis3_t0, iCA);
    snew(residuehelixaxis_tlast, iCA);
    snew(residuevector_tlast, iCA);
    snew(axis3_tlast, iCA);
    snew(axis3, iCA);

    if (bSC)
    {
        printf("Select a group of atoms defining the sidechain direction (1/residue):\n");
        get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iSC, &ind_SC, &gn_SC);
        if (iSC != iCA)
        {
            gmx_fatal(FARGS, "Number of sidechain atoms (%d) != number of CA atoms (%d)", iSC, iCA);
        }

    }

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

    fpaxis    = gmx_ffopen(opt2fn("-oaxis", NFILE, fnm), "w");
    fpcenter  = gmx_ffopen(opt2fn("-ocenter", NFILE, fnm), "w");
    fprise    = gmx_ffopen(opt2fn("-orise", NFILE, fnm), "w");
    fpradius  = gmx_ffopen(opt2fn("-oradius", NFILE, fnm), "w");
    fptwist   = gmx_ffopen(opt2fn("-otwist", NFILE, fnm), "w");
    fpbending = gmx_ffopen(opt2fn("-obending", NFILE, fnm), "w");

    fptheta1 = gmx_ffopen("theta1.xvg", "w");
    fptheta2 = gmx_ffopen("theta2.xvg", "w");
    fptheta3 = gmx_ffopen("theta3.xvg", "w");

    if (bIncremental)
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Incremental local helix tilt", "Time(ps)", "Tilt (degrees)",
                          oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Incremental local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }
    else
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Cumulative local helix tilt", "Time(ps)", "Tilt (degrees)", oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Cumulative local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }

    clear_rvecs(3, unitaxes);
    unitaxes[0][0] = 1;
    unitaxes[1][1] = 1;
    unitaxes[2][2] = 1;

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

    do
    {
        /* initialisation for correct distance calculations */
        set_pbc(&pbc, ePBC, box);
        /* make molecules whole again */
        gmx_rmpbc(gpbc, natoms, box, x);

        /* copy coords to our smaller arrays */
        for (i = 0; i < iCA; i++)
        {
            copy_rvec(x[ind_CA[i]], x_CA[i]);
            if (bSC)
            {
                copy_rvec(x[ind_SC[i]], x_SC[i]);
            }
        }

        for (i = 0; i < iCA-3; i++)
        {
            rvec_sub(x_CA[i+1], x_CA[i], r12[i]);
            rvec_sub(x_CA[i+2], x_CA[i+1], r23[i]);
            rvec_sub(x_CA[i+3], x_CA[i+2], r34[i]);
            rvec_sub(r12[i], r23[i], diff13[i]);
            rvec_sub(r23[i], r34[i], diff24[i]);
            /* calculate helix axis */
            cprod(diff13[i], diff24[i], helixaxis[i]);
            svmul(1.0/norm(helixaxis[i]), helixaxis[i], helixaxis[i]);

            tmp       = cos_angle(diff13[i], diff24[i]);
            twist[i]  = 180.0/M_PI * std::acos( tmp );
            radius[i] = std::sqrt( norm(diff13[i])*norm(diff24[i]) ) / (2.0* (1.0-tmp) );
            rise[i]   = std::abs(iprod(r23[i], helixaxis[i]));

            svmul(radius[i]/norm(diff13[i]), diff13[i], v1);
            svmul(radius[i]/norm(diff24[i]), diff24[i], v2);

            rvec_sub(x_CA[i+1], v1, residueorigin[i+1]);
            rvec_sub(x_CA[i+2], v2, residueorigin[i+2]);
        }
        residueradius[0] = residuetwist[0] = residuerise[0] = 0;

        residueradius[1] = radius[0];
        residuetwist[1]  = twist[0];
        residuerise[1]   = rise[0];

        residuebending[0] = residuebending[1] = 0;
        for (i = 2; i < iCA-2; i++)
        {
            residueradius[i]  = 0.5*(radius[i-2]+radius[i-1]);
            residuetwist[i]   = 0.5*(twist[i-2]+twist[i-1]);
            residuerise[i]    = 0.5*(rise[i-2]+rise[i-1]);
            residuebending[i] = 180.0/M_PI*std::acos( cos_angle(helixaxis[i-2], helixaxis[i-1]) );
        }
        residueradius[iCA-2]  = radius[iCA-4];
        residuetwist[iCA-2]   = twist[iCA-4];
        residuerise[iCA-2]    = rise[iCA-4];
        residueradius[iCA-1]  = residuetwist[iCA-1] = residuerise[iCA-1] = 0;
        residuebending[iCA-2] = residuebending[iCA-1] = 0;

        clear_rvec(residueorigin[0]);
        clear_rvec(residueorigin[iCA-1]);

        /* average helix axes to define them on the residues.
         * Just extrapolate second first/list atom.
         */
        copy_rvec(helixaxis[0], residuehelixaxis[0]);
        copy_rvec(helixaxis[0], residuehelixaxis[1]);

        for (i = 2; i < iCA-2; i++)
        {
            rvec_add(helixaxis[i-2], helixaxis[i-1], residuehelixaxis[i]);
            svmul(0.5, residuehelixaxis[i], residuehelixaxis[i]);
        }
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-2]);
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-1]);

        /* Normalize the axis */
        for (i = 0; i < iCA; i++)
        {
            svmul(1.0/norm(residuehelixaxis[i]), residuehelixaxis[i], residuehelixaxis[i]);
        }

        /* calculate vector from origin to residue CA */
        fprintf(fpaxis, "%15.12g  ", t);
        fprintf(fpcenter, "%15.12g  ", t);
        fprintf(fprise, "%15.12g  ", t);
        fprintf(fpradius, "%15.12g  ", t);
        fprintf(fptwist, "%15.12g  ", t);
        fprintf(fpbending, "%15.12g  ", t);

        for (i = 0; i < iCA; i++)
        {
            if (i == 0 || i == iCA-1)
            {
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fprise, "%15.12g  ", 0.0);
                fprintf(fpradius, "%15.12g  ", 0.0);
                fprintf(fptwist, "%15.12g  ", 0.0);
                fprintf(fpbending, "%15.12g  ", 0.0);
            }
            else
            {
                rvec_sub( bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]);
                svmul(1.0/norm(residuevector[i]), residuevector[i], residuevector[i]);
                cprod(residuehelixaxis[i], residuevector[i], axis3[i]);
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2]);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", residueorigin[i][0], residueorigin[i][1], residueorigin[i][2]);

                fprintf(fprise, "%15.12g  ", residuerise[i]);
                fprintf(fpradius, "%15.12g  ", residueradius[i]);
                fprintf(fptwist, "%15.12g  ", residuetwist[i]);
                fprintf(fpbending, "%15.12g  ", residuebending[i]);
            }
        }
        fprintf(fprise, "\n");
        fprintf(fpradius, "\n");
        fprintf(fpaxis, "\n");
        fprintf(fpcenter, "\n");
        fprintf(fptwist, "\n");
        fprintf(fpbending, "\n");

        if (teller == 0)
        {
            for (i = 0; i < iCA; i++)
            {
                copy_rvec(residuehelixaxis[i], residuehelixaxis_t0[i]);
                copy_rvec(residuevector[i], residuevector_t0[i]);
                copy_rvec(axis3[i], axis3_t0[i]);
            }
        }
        else
        {
            fprintf(fptilt, "%15.12g       ", t);
            fprintf(fprotation, "%15.12g       ", t);
            fprintf(fptheta1, "%15.12g      ", t);
            fprintf(fptheta2, "%15.12g      ", t);
            fprintf(fptheta3, "%15.12g      ", t);

            for (i = 0; i < iCA; i++)
            {
                if (i == 0 || i == iCA-1)
                {
                    tilt = rotation = 0;
                }
                else
                {
                    if (!bIncremental)
                    {
                        /* Total rotation & tilt */
                        copy_rvec(residuehelixaxis_t0[i], refaxes[0]);
                        copy_rvec(residuevector_t0[i], refaxes[1]);
                        copy_rvec(axis3_t0[i], refaxes[2]);
                    }
                    else
                    {
                        /* Rotation/tilt since last step */
                        copy_rvec(residuehelixaxis_tlast[i], refaxes[0]);
                        copy_rvec(residuevector_tlast[i], refaxes[1]);
                        copy_rvec(axis3_tlast[i], refaxes[2]);
                    }
                    copy_rvec(residuehelixaxis[i], newaxes[0]);
                    copy_rvec(residuevector[i], newaxes[1]);
                    copy_rvec(axis3[i], newaxes[2]);

                    /* rotate reference frame onto unit axes */
                    calc_fit_R(3, 3, weight, unitaxes, refaxes, A);
                    for (j = 0; j < 3; j++)
                    {
                        mvmul(A, refaxes[j], rot_refaxes[j]);
                        mvmul(A, newaxes[j], rot_newaxes[j]);
                    }

                    /* Determine local rotation matrix A */
                    calc_fit_R(3, 3, weight, rot_newaxes, rot_refaxes, A);
                    /* Calculate euler angles, from rotation order y-z-x, where
                     * x is helixaxis, y residuevector, and z axis3.
                     *
                     * A contains rotation column vectors.
                     */

                    theta1 = 180.0/M_PI*std::atan2(A[0][2], A[0][0]);
                    theta2 = 180.0/M_PI*std::asin(-A[0][1]);
                    theta3 = 180.0/M_PI*std::atan2(A[2][1], A[1][1]);

                    tilt     = std::sqrt(theta1*theta1+theta2*theta2);
                    rotation = theta3;
                    fprintf(fptheta1, "%15.12g  ", theta1);
                    fprintf(fptheta2, "%15.12g  ", theta2);
                    fprintf(fptheta3, "%15.12g  ", theta3);

                }
                fprintf(fptilt, "%15.12g  ", tilt);
                fprintf(fprotation, "%15.12g  ", rotation);
            }
            fprintf(fptilt, "\n");
            fprintf(fprotation, "\n");
            fprintf(fptheta1, "\n");
            fprintf(fptheta2, "\n");
            fprintf(fptheta3, "\n");
        }

        for (i = 0; i < iCA; i++)
        {
            copy_rvec(residuehelixaxis[i], residuehelixaxis_tlast[i]);
            copy_rvec(residuevector[i], residuevector_tlast[i]);
            copy_rvec(axis3[i], axis3_tlast[i]);
        }

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

    gmx_rmpbc_done(gpbc);

    gmx_ffclose(fpaxis);
    gmx_ffclose(fpcenter);
    xvgrclose(fptilt);
    xvgrclose(fprotation);
    gmx_ffclose(fprise);
    gmx_ffclose(fpradius);
    gmx_ffclose(fptwist);
    gmx_ffclose(fpbending);
    gmx_ffclose(fptheta1);
    gmx_ffclose(fptheta2);
    gmx_ffclose(fptheta3);

    close_trj(status);

    return 0;
}
Exemplo n.º 21
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, *fnNDX, *fnTRX, *fnDAT = NULL;
    t_trxstatus                          *status;
    t_topology                           *top  = NULL;
    t_atom                               *atom = NULL;
    gmx_rmpbc_t                           gpbc = NULL;
    gmx_bool                              bTPX;
    gmx_bool                              bFFT = FALSE, bDEBYE = FALSE;
    gmx_bool                              bMC  = FALSE;
    int                                   ePBC = -1;
    matrix                                box;
    char                                  title[STRLEN];
    rvec                                 *x;
    int                                   natoms;
    real                                  t;
    char                                **grpname = NULL;
    atom_id                              *index   = NULL;
    int                                   isize;
    int                                   i, j;
    char                                 *hdr            = NULL;
    char                                 *suffix         = NULL;
    t_filenm                             *fnmdup         = NULL;
    gmx_radial_distribution_histogram_t  *prframecurrent = NULL, *pr = NULL;
    gmx_static_structurefactor_t         *sqframecurrent = NULL, *sq = NULL;
    output_env_t                          oenv;

#define NFILE asize(fnm)

    t_filenm   fnm[] = {
        { efTPX,  "-s",       NULL,       ffREAD },
        { efTRX,  "-f",       NULL,       ffREAD },
        { efNDX,  NULL,       NULL,       ffOPTRD },
        { efDAT,  "-d",       "nsfactor", ffOPTRD },
        { efXVG,  "-pr",      "pr",       ffWRITE },
        { efXVG,  "-sq",       "sq",      ffWRITE },
        { efXVG,  "-prframe", "prframe",  ffOPTWR },
        { efXVG,  "-sqframe", "sqframe",  ffOPTWR }
    };

    nthreads = gmx_omp_get_max_threads();

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

    /* check that binwidth not smaller than smallers distance */
    check_binwidth(binwidth);
    check_mcover(mcover);

    /* setting number of omp threads globaly */
    gmx_omp_set_num_threads(nthreads);

    /* Now try to parse opts for modes */
    switch (emethod[0][0])
    {
        case 'd':
            bDEBYE = TRUE;
            switch (emode[0][0])
            {
                case 'd':
                    bMC = FALSE;
                    break;
                case 'm':
                    bMC = TRUE;
                    break;
                default:
                    break;
            }
            break;
        case 'f':
            bFFT = TRUE;
            break;
        default:
            break;
    }

    if (bDEBYE)
    {
        if (bMC)
        {
            fprintf(stderr, "Using Monte Carlo Debye method to calculate spectrum\n");
        }
        else
        {
            fprintf(stderr, "Using direct Debye method to calculate spectrum\n");
        }
    }
    else if (bFFT)
    {
        gmx_fatal(FARGS, "FFT method not implemented!");
    }
    else
    {
        gmx_fatal(FARGS, "Unknown combination for mode and method!");
    }

    /* Try to read files */
    fnDAT = ftp2fn(efDAT, NFILE, fnm);
    fnTPX = ftp2fn(efTPX, NFILE, fnm);
    fnTRX = ftp2fn(efTRX, NFILE, fnm);

    gnsf = gmx_neutronstructurefactors_init(fnDAT);
    fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n", gnsf->nratoms, fnDAT);

    snew(top, 1);
    snew(grpname, 1);
    snew(index, 1);

    bTPX = read_tps_conf(fnTPX, title, top, &ePBC, &x, NULL, box, TRUE);

    printf("\nPlease select group for SANS spectra calculation:\n");
    get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, grpname);

    gsans = gmx_sans_init(top, gnsf);

    /* Prepare reference frame */
    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top->idef, ePBC, top->atoms.nr);
        gmx_rmpbc(gpbc, top->atoms.nr, box, x);
    }

    natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box);
    if (natoms != top->atoms.nr)
    {
        fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", natoms, top->atoms.nr);
    }

    do
    {
        if (bPBC)
        {
            gmx_rmpbc(gpbc, top->atoms.nr, box, x);
        }
        /* allocate memory for pr */
        if (pr == NULL)
        {
            /* in case its first frame to read */
            snew(pr, 1);
        }
        /*  realy calc p(r) */
        prframecurrent = calc_radial_distribution_histogram(gsans, x, box, index, isize, binwidth, bMC, bNORM, mcover, seed);
        /* copy prframecurrent -> pr and summ up pr->gr[i] */
        /* allocate and/or resize memory for pr->gr[i] and pr->r[i] */
        if (pr->gr == NULL)
        {
            /* check if we use pr->gr first time */
            snew(pr->gr, prframecurrent->grn);
            snew(pr->r, prframecurrent->grn);
        }
        else
        {
            /* resize pr->gr and pr->r if needed to preven overruns */
            if (prframecurrent->grn > pr->grn)
            {
                srenew(pr->gr, prframecurrent->grn);
                srenew(pr->r, prframecurrent->grn);
            }
        }
        pr->grn      = prframecurrent->grn;
        pr->binwidth = prframecurrent->binwidth;
        /* summ up gr and fill r */
        for (i = 0; i < prframecurrent->grn; i++)
        {
            pr->gr[i] += prframecurrent->gr[i];
            pr->r[i]   = prframecurrent->r[i];
        }
        /* normalize histo */
        normalize_probability(prframecurrent->grn, prframecurrent->gr);
        /* convert p(r) to sq */
        sqframecurrent = convert_histogram_to_intensity_curve(prframecurrent, start_q, end_q, q_step);
        /* print frame data if needed */
        if (opt2fn_null("-prframe", NFILE, fnm))
        {
            snew(hdr, 25);
            snew(suffix, GMX_PATH_MAX);
            /* prepare header */
            sprintf(hdr, "g(r), t = %f", t);
            /* prepare output filename */
            fnmdup = dup_tfn(NFILE, fnm);
            sprintf(suffix, "-t%.2f", t);
            add_suffix_to_output_names(fnmdup, NFILE, suffix);
            fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup), hdr, "Distance (nm)", "Probability", oenv);
            for (i = 0; i < prframecurrent->grn; i++)
            {
                fprintf(fp, "%10.6f%10.6f\n", prframecurrent->r[i], prframecurrent->gr[i]);
            }
            done_filenms(NFILE, fnmdup);
            fclose(fp);
            sfree(hdr);
            sfree(suffix);
            sfree(fnmdup);
        }
        if (opt2fn_null("-sqframe", NFILE, fnm))
        {
            snew(hdr, 25);
            snew(suffix, GMX_PATH_MAX);
            /* prepare header */
            sprintf(hdr, "I(q), t = %f", t);
            /* prepare output filename */
            fnmdup = dup_tfn(NFILE, fnm);
            sprintf(suffix, "-t%.2f", t);
            add_suffix_to_output_names(fnmdup, NFILE, suffix);
            fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup), hdr, "q (nm^-1)", "s(q)/s(0)", oenv);
            for (i = 0; i < sqframecurrent->qn; i++)
            {
                fprintf(fp, "%10.6f%10.6f\n", sqframecurrent->q[i], sqframecurrent->s[i]);
            }
            done_filenms(NFILE, fnmdup);
            fclose(fp);
            sfree(hdr);
            sfree(suffix);
            sfree(fnmdup);
        }
        /* free pr structure */
        sfree(prframecurrent->gr);
        sfree(prframecurrent->r);
        sfree(prframecurrent);
        /* free sq structure */
        sfree(sqframecurrent->q);
        sfree(sqframecurrent->s);
        sfree(sqframecurrent);
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);

    /* normalize histo */
    normalize_probability(pr->grn, pr->gr);
    sq = convert_histogram_to_intensity_curve(pr, start_q, end_q, q_step);
    /* prepare pr.xvg */
    fp = xvgropen(opt2fn_null("-pr", NFILE, fnm), "G(r)", "Distance (nm)", "Probability", oenv);
    for (i = 0; i < pr->grn; i++)
    {
        fprintf(fp, "%10.6f%10.6f\n", pr->r[i], pr->gr[i]);
    }
    xvgrclose(fp);

    /* prepare sq.xvg */
    fp = xvgropen(opt2fn_null("-sq", NFILE, fnm), "I(q)", "q (nm^-1)", "s(q)/s(0)", oenv);
    for (i = 0; i < sq->qn; i++)
    {
        fprintf(fp, "%10.6f%10.6f\n", sq->q[i], sq->s[i]);
    }
    xvgrclose(fp);
    /*
     * Clean up memory
     */
    sfree(pr->gr);
    sfree(pr->r);
    sfree(pr);
    sfree(sq->q);
    sfree(sq->s);
    sfree(sq);

    please_cite(stdout, "Garmay2012");

    return 0;
}
Exemplo n.º 22
0
void calc_h2order(const char *fn, atom_id index[], int ngx, rvec **slDipole,
		  real **slOrder, real *slWidth, int *nslices, 
		  t_topology *top, int ePBC,
		  int axis, gmx_bool bMicel, atom_id micel[], int nmic,
                  const output_env_t oenv)
{
  rvec *x0,              /* coordinates with pbc */
       dipole,           /* dipole moment due to one molecules */
       normal,
       com;              /* center of mass of micel, with bMicel */
  rvec *dip;             /* sum of dipoles, unnormalized */
  matrix box;            /* box (3x3) */
  t_trxstatus *status;
  real  t,               /* time from trajectory */
       *sum,             /* sum of all cosines of dipoles, per slice */
       *frame;           /* order over one frame */
  int natoms,            /* nr. atoms in trj */
      i,j,teller = 0,
      slice=0,           /* current slice number */
      *count;            /* nr. of atoms in one slice */
  gmx_rmpbc_t  gpbc=NULL;
  
  if ((natoms = read_first_x(oenv,&status,fn,&t,&x0,box)) == 0)
    gmx_fatal(FARGS,"Could not read coordinates from statusfile\n");

  if (! *nslices)
    *nslices = (int)(box[axis][axis] * 10); /* default value */


  switch(axis)
  {
  case 0:
    normal[0] = 1; normal[1] = 0; normal[2] = 0;
    break;
  case 1:
    normal[0] = 0; normal[1] = 1; normal[2] = 0;
    break;
  case 2:
    normal[0] = 0; normal[1] = 0; normal[2] = 1;
    break;
  default:
      gmx_fatal(FARGS,"No valid value for -axis-. Exiting.\n");
      /* make compiler happy */
      normal[0] = 1; normal[1] = 0; normal[2] = 0;
  }

  clear_rvec(dipole);
  snew(count, *nslices);
  snew(sum, *nslices);
  snew(dip, *nslices);
  snew(frame, *nslices);

  *slWidth = box[axis][axis]/(*nslices);
  fprintf(stderr,"Box divided in %d slices. Initial width of slice: %f\n",
	  *nslices, *slWidth);

  teller = 0; 

  gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box);
  /*********** Start processing trajectory ***********/
  do 
  {
    *slWidth = box[axis][axis]/(*nslices);
    teller++;
    
    gmx_rmpbc(gpbc,natoms,box,x0);

    if (bMicel)
      calc_xcm(x0, nmic, micel, top->atoms.atom, com, FALSE);
    
    for (i = 0; i < ngx/3; i++)
    {
      /* put all waters in box */
      for (j = 0; j < DIM; j++)
      {
	if (x0[index[3*i]][j] < 0)
	{
	  x0[index[3*i]][j] += box[j][j];
	  x0[index[3*i+1]][j] += box[j][j];
	  x0[index[3*i+2]][j] += box[j][j];
	}
	if (x0[index[3*i]][j] > box[j][j])
	{
	  x0[index[3*i]][j] -= box[j][j];
	  x0[index[3*i+1]][j] -= box[j][j];
	  x0[index[3*i+2]][j] -= box[j][j];
	}
      }
   
      for (j = 0; j < DIM; j++)
 	dipole[j] = 
	  x0[index[3*i]][j] * top->atoms.atom[index[3*i]].q +
	  x0[index[3*i+1]][j] * top->atoms.atom[index[3*i+1]].q +
	  x0[index[3*i+2]][j] * top->atoms.atom[index[3*i+2]].q;

      /* now we have a dipole vector. Might as well safe it. Then the 
	 rest depends on whether we're dealing with
	 a flat or a spherical interface.
       */
      
      if (bMicel)
      { /* this is for spherical interfaces */
	rvec_sub(com, x0[index[3*i]], normal); /* vector from Oxygen to COM */
	slice = norm(normal)/(*slWidth);         /* spherical slice           */

	sum[slice] += iprod(dipole, normal) / (norm(dipole) * norm(normal));
	frame[slice] += iprod(dipole, normal) / (norm(dipole) * norm(normal));
	count[slice]++;

      } else { 
	/* this is for flat interfaces      */

	/* determine which slice atom is in */
	slice = (x0[index[3*i]][axis] / (*slWidth)); 
	if (slice < 0 || slice >= *nslices)
	{
	  fprintf(stderr,"Coordinate: %f ",x0[index[3*i]][axis]);
	  fprintf(stderr,"HELP PANIC! slice = %d, OUT OF RANGE!\n",slice);
	}
	else
	{
	  rvec_add(dipole, dip[slice], dip[slice]);
	  /* Add dipole to total. mag[slice] is total dipole in axis direction */
	  sum[slice] += iprod(dipole,normal)/norm(dipole);
	  frame[slice] += iprod(dipole,normal)/norm(dipole);
	  /* increase count for that slice */
	  count[slice]++;
	}
      }
    }

  } while (read_next_x(oenv,status,&t,natoms,x0,box));
  /*********** done with status file **********/
 
  fprintf(stderr,"\nRead trajectory. Printing parameters to file\n");
  gmx_rmpbc_done(gpbc);

  for (i = 0; i < *nslices; i++)  /* average over frames */
  {
    fprintf(stderr,"%d waters in slice %d\n",count[i],i);
    if (count[i] > 0)   /* divide by number of molecules in each slice */
      {
	sum[i] = sum[i] / count[i]; 
	dip[i][XX] = dip[i][XX] / count[i];
	dip[i][YY] = dip[i][YY] / count[i];
	dip[i][ZZ] = dip[i][ZZ] / count[i];
      }
    else 
      fprintf(stderr,"No water in slice %d\n",i);
  }

  *slOrder = sum;  /* copy a pointer, I hope */
  *slDipole = dip; 
  sfree(x0);  /* free memory used by coordinate arrays */
}
Exemplo n.º 23
0
static void project(const char *trajfile,t_topology *top,int ePBC,matrix topbox,
                    const char *projfile,const char *twodplotfile,
                    const char *threedplotfile, const char *filterfile,int skip,
                    const char *extremefile,gmx_bool bExtrAll,real extreme,
                    int nextr, t_atoms *atoms,int natoms,atom_id *index,
                    gmx_bool bFit,rvec *xref,int nfit,atom_id *ifit,real *w_rls,
                    real *sqrtm,rvec *xav,
                    int *eignr,rvec **eigvec,
                    int noutvec,int *outvec, gmx_bool bSplit,
                    const output_env_t oenv)
{
  FILE    *xvgrout=NULL;
  int     nat,i,j,d,v,vec,nfr,nframes=0,snew_size,frame;
  t_trxstatus *out=NULL;
  t_trxstatus *status;
  int     noutvec_extr,imin,imax;
  real    *pmin,*pmax;
  atom_id *all_at;
  matrix  box;
  rvec    *xread,*x;
  real    t,inp,**inprod=NULL,min=0,max=0;
  char    str[STRLEN],str2[STRLEN],**ylabel,*c;
  real    fact;
  gmx_rmpbc_t  gpbc=NULL;

  snew(x,natoms);
  
  if (bExtrAll)
    noutvec_extr=noutvec;
  else
    noutvec_extr=1;
  

  if (trajfile) {
    snew(inprod,noutvec+1);
    
    if (filterfile) {
      fprintf(stderr,"Writing a filtered trajectory to %s using eigenvectors\n",
	      filterfile);
      for(i=0; i<noutvec; i++)
	fprintf(stderr,"%d ",outvec[i]+1);
      fprintf(stderr,"\n");
      out=open_trx(filterfile,"w");
    }
    snew_size=0;
    nfr=0;
    nframes=0;
    nat=read_first_x(oenv,&status,trajfile,&t,&xread,box);
    if (nat>atoms->nr)
      gmx_fatal(FARGS,"the number of atoms in your trajectory (%d) is larger than the number of atoms in your structure file (%d)",nat,atoms->nr); 
    snew(all_at,nat);
    
    if (top)
      gpbc = gmx_rmpbc_init(&top->idef,ePBC,nat,box);

    for(i=0; i<nat; i++)
      all_at[i]=i;
    do {
      if (nfr % skip == 0) {
	if (top)
	  gmx_rmpbc(gpbc,nat,box,xread);
	if (nframes>=snew_size) {
	  snew_size+=100;
	  for(i=0; i<noutvec+1; i++)
	    srenew(inprod[i],snew_size);
	}
	inprod[noutvec][nframes]=t;
	/* calculate x: a fitted struture of the selected atoms */
	if (bFit) {
	  reset_x(nfit,ifit,nat,NULL,xread,w_rls);
	  do_fit(nat,w_rls,xref,xread);
	}
	for (i=0; i<natoms; i++)
	  copy_rvec(xread[index[i]],x[i]);

	for(v=0; v<noutvec; v++) {
	  vec=outvec[v];
	  /* calculate (mass-weighted) projection */
	  inp=0;
	  for (i=0; i<natoms; i++) {
	    inp+=(eigvec[vec][i][0]*(x[i][0]-xav[i][0])+
	    eigvec[vec][i][1]*(x[i][1]-xav[i][1])+
	    eigvec[vec][i][2]*(x[i][2]-xav[i][2]))*sqrtm[i];
	  }
	  inprod[v][nframes]=inp;
	}
	if (filterfile) {
	  for(i=0; i<natoms; i++)
	    for(d=0; d<DIM; d++) {
	      /* misuse xread for output */
	      xread[index[i]][d] = xav[i][d];
	      for(v=0; v<noutvec; v++)
		xread[index[i]][d] +=
		  inprod[v][nframes]*eigvec[outvec[v]][i][d]/sqrtm[i];
	    }
	  write_trx(out,natoms,index,atoms,0,t,box,xread,NULL,NULL);
	}
	nframes++;
      }
      nfr++;
    } while (read_next_x(oenv,status,&t,nat,xread,box));
    close_trx(status);
     sfree(x);
     if (filterfile)
       close_trx(out);
  }
  else
    snew(xread,atoms->nr);
  
  if (top)
    gmx_rmpbc_done(gpbc);


  if (projfile) {
    snew(ylabel,noutvec);
    for(v=0; v<noutvec; v++) {
      sprintf(str,"vec %d",eignr[outvec[v]]+1);
      ylabel[v]=strdup(str);
    }
    sprintf(str,"projection on eigenvectors (%s)",proj_unit);
    write_xvgr_graphs(projfile, noutvec, 1, str, NULL, output_env_get_xvgr_tlabel(oenv),
		      (const char **)ylabel,
		      nframes, inprod[noutvec], inprod, NULL,
		      output_env_get_time_factor(oenv), FALSE, bSplit,oenv);
  }
  
  if (twodplotfile) {
    sprintf(str,"projection on eigenvector %d (%s)",
	    eignr[outvec[0]]+1,proj_unit);
    sprintf(str2,"projection on eigenvector %d (%s)",
	    eignr[outvec[noutvec-1]]+1,proj_unit); 
    xvgrout=xvgropen(twodplotfile,"2D projection of trajectory",str,str2,
                     oenv);
    for(i=0; i<nframes; i++) {
      if ( bSplit && i>0 && abs(inprod[noutvec][i])<1e-5 ) 
	fprintf(xvgrout,"&\n");
      fprintf(xvgrout,"%10.5f %10.5f\n",inprod[0][i],inprod[noutvec-1][i]);
    }
    ffclose(xvgrout);
  }
  
  if (threedplotfile) {
    t_atoms atoms;
    rvec    *x;
    real    *b=NULL;
    matrix  box;
    char    *resnm,*atnm, pdbform[STRLEN];
    gmx_bool    bPDB, b4D;
    FILE    *out;
    
    if (noutvec < 3)
      gmx_fatal(FARGS,"You have selected less than 3 eigenvectors");  
      
    /* initialize */
    bPDB = fn2ftp(threedplotfile)==efPDB;
    clear_mat(box);
    box[XX][XX] = box[YY][YY] = box[ZZ][ZZ] = 1;
    
    b4D = bPDB && (noutvec >= 4);
    if (b4D) {
      fprintf(stderr, "You have selected four or more eigenvectors:\n"
	      "fourth eigenvector will be plotted "
	      "in bfactor field of pdb file\n");
      sprintf(str,"4D proj. of traj. on eigenv. %d, %d, %d and %d",
	      eignr[outvec[0]]+1,eignr[outvec[1]]+1,
	      eignr[outvec[2]]+1,eignr[outvec[3]]+1);
    } else {
    sprintf(str,"3D proj. of traj. on eigenv. %d, %d and %d",
	    eignr[outvec[0]]+1,eignr[outvec[1]]+1,eignr[outvec[2]]+1);
    }
    init_t_atoms(&atoms,nframes,FALSE);
    snew(x,nframes);
    snew(b,nframes);
    atnm=strdup("C");
    resnm=strdup("PRJ");

    if(nframes>10000)
      fact=10000.0/nframes;
    else
      fact=1.0;

    for(i=0; i<nframes; i++) {
      atoms.atomname[i] = &atnm;
      atoms.atom[i].resind = i;
      atoms.resinfo[i].name = &resnm;
      atoms.resinfo[i].nr   = ceil(i*fact);
      atoms.resinfo[i].ic   = ' ';
      x[i][XX]=inprod[0][i];
      x[i][YY]=inprod[1][i];
      x[i][ZZ]=inprod[2][i];
      if (b4D)
	b[i]  =inprod[3][i];
    }
    if ( ( b4D || bSplit ) && bPDB ) {
      strcpy(pdbform,get_pdbformat());
      strcat(pdbform,"%8.4f%8.4f\n");
      
      out=ffopen(threedplotfile,"w");
      fprintf(out,"HEADER    %s\n",str);
      if ( b4D )
	fprintf(out,"REMARK    %s\n","fourth dimension plotted as B-factor");
      j=0;
      for(i=0; i<atoms.nr; i++) {
	if ( j>0 && bSplit && abs(inprod[noutvec][i])<1e-5 ) {
	  fprintf(out,"TER\n");
	  j=0;
	}
	fprintf(out,pdbform,"ATOM",i+1,"C","PRJ",' ',j+1,
		PR_VEC(10*x[i]), 1.0, 10*b[i]);
	if (j>0)
	  fprintf(out,"CONECT%5d%5d\n", i, i+1);
	j++;
      }
      fprintf(out,"TER\n");
      ffclose(out);
    } else
      write_sto_conf(threedplotfile,str,&atoms,x,NULL,ePBC,box); 
    free_t_atoms(&atoms,FALSE);
  }
  
  if (extremefile) {
    snew(pmin,noutvec_extr);
    snew(pmax,noutvec_extr);
    if (extreme==0) {
      fprintf(stderr,"%11s %17s %17s\n","eigenvector","Minimum","Maximum");
      fprintf(stderr,
	      "%11s %10s %10s %10s %10s\n","","value","frame","value","frame");
      imin = 0;
      imax = 0;
      for(v=0; v<noutvec_extr; v++) {
	for(i=0; i<nframes; i++) {
	  if (inprod[v][i]<inprod[v][imin])
	    imin = i;
	  if (inprod[v][i]>inprod[v][imax])
	    imax = i;
	}
	pmin[v] = inprod[v][imin];
	pmax[v] = inprod[v][imax];
	fprintf(stderr,"%7d     %10.6f %10d %10.6f %10d\n",
		eignr[outvec[v]]+1,
		pmin[v],imin,pmax[v],imax); 
      }
    }
    else {
      pmin[0] = -extreme;
      pmax[0] =  extreme;
    }
    /* build format string for filename: */
    strcpy(str,extremefile);/* copy filename */
    c=strrchr(str,'.'); /* find where extention begins */
    strcpy(str2,c); /* get extention */
    sprintf(c,"%%d%s",str2); /* append '%s' and extention to filename */
    for(v=0; v<noutvec_extr; v++) {
      /* make filename using format string */
      if (noutvec_extr==1)
	strcpy(str2,extremefile);
      else
	sprintf(str2,str,eignr[outvec[v]]+1);
      fprintf(stderr,"Writing %d frames along eigenvector %d to %s\n",
	      nextr,outvec[v]+1,str2);
      out=open_trx(str2,"w");
      for(frame=0; frame<nextr; frame++) {
	if ((extreme==0) && (nextr<=3))
	  for(i=0; i<natoms; i++) {
	    atoms->resinfo[atoms->atom[index[i]].resind].chainid = 'A' + frame;
	  }
	for(i=0; i<natoms; i++)
	  for(d=0; d<DIM; d++) 
	    xread[index[i]][d] = 
	      (xav[i][d] + (pmin[v]*(nextr-frame-1)+pmax[v]*frame)/(nextr-1)
	      *eigvec[outvec[v]][i][d]/sqrtm[i]);
	write_trx(out,natoms,index,atoms,0,frame,topbox,xread,NULL,NULL);
      }
      close_trx(out);
    }
    sfree(pmin);
    sfree(pmax);
  }
  fprintf(stderr,"\n");
}
Exemplo n.º 24
0
void calc_potential(const char *fn, int **index, int gnx[],
                    double ***slPotential, double ***slCharge,
                    double ***slField, int *nslices,
                    const t_topology *top, int ePBC,
                    int axis, int nr_grps, double *slWidth,
                    double fudge_z, gmx_bool bSpherical, gmx_bool bCorrect,
                    const gmx_output_env_t *oenv)
{
    rvec        *x0;     /* coordinates without pbc */
    matrix       box;    /* box (3x3) */
    int          natoms; /* nr. atoms in trj */
    t_trxstatus *status;
    int          i, n,   /* loop indices */
                 teller    = 0,
                 ax1       = 0, ax2 = 0,
                 nr_frames = 0, /* number of frames */
                 slice;         /* current slice */
    double       slVolume;      /* volume of slice for spherical averaging */
    double       qsum, nn;
    real         t;
    double       z;
    rvec         xcm;
    gmx_rmpbc_t  gpbc = NULL;

    switch (axis)
    {
        case 0:
            ax1 = 1; ax2 = 2;
            break;
        case 1:
            ax1 = 0; ax2 = 2;
            break;
        case 2:
            ax1 = 0; ax2 = 1;
            break;
        default:
            gmx_fatal(FARGS, "Invalid axes. Terminating\n");
    }

    if ((natoms = read_first_x(oenv, &status, fn, &t, &x0, box)) == 0)
    {
        gmx_fatal(FARGS, "Could not read coordinates from statusfile\n");
    }

    if (!*nslices)
    {
        *nslices = static_cast<int>(box[axis][axis] * 10.0); /* default value */

    }
    fprintf(stderr, "\nDividing the box in %d slices\n", *nslices);

    snew(*slField, nr_grps);
    snew(*slCharge, nr_grps);
    snew(*slPotential, nr_grps);

    for (i = 0; i < nr_grps; i++)
    {
        snew((*slField)[i], *nslices);
        snew((*slCharge)[i], *nslices);
        snew((*slPotential)[i], *nslices);
    }


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

    /*********** Start processing trajectory ***********/
    do
    {
        *slWidth = box[axis][axis]/(*nslices);
        teller++;
        gmx_rmpbc(gpbc, natoms, box, x0);

        /* calculate position of center of mass based on group 1 */
        calc_xcm(x0, gnx[0], index[0], top->atoms.atom, xcm, FALSE);
        svmul(-1, xcm, xcm);

        for (n = 0; n < nr_grps; n++)
        {
            /* Check whether we actually have all positions of the requested index
             * group in the trajectory file */
            if (gnx[n] > natoms)
            {
                gmx_fatal(FARGS, "You selected a group with %d atoms, but only %d atoms\n"
                          "were found in the trajectory.\n", gnx[n], natoms);
            }
            for (i = 0; i < gnx[n]; i++) /* loop over all atoms in index file */
            {
                if (bSpherical)
                {
                    rvec_add(x0[index[n][i]], xcm, x0[index[n][i]]);
                    /* only distance from origin counts, not sign */
                    slice = static_cast<int>(norm(x0[index[n][i]])/(*slWidth));

                    /* this is a nice check for spherical groups but not for
                       all water in a cubic box since a lot will fall outside
                       the sphere
                       if (slice > (*nslices))
                       {
                       fprintf(stderr,"Warning: slice = %d\n",slice);
                       }
                     */
                    (*slCharge)[n][slice] += top->atoms.atom[index[n][i]].q;
                }
                else
                {
                    z = x0[index[n][i]][axis];
                    z = z + fudge_z;
                    if (z < 0)
                    {
                        z += box[axis][axis];
                    }
                    if (z > box[axis][axis])
                    {
                        z -= box[axis][axis];
                    }
                    /* determine which slice atom is in */
                    slice                  = static_cast<int>((z / (*slWidth)));
                    (*slCharge)[n][slice] += top->atoms.atom[index[n][i]].q;
                }
            }
        }
        nr_frames++;
    }
    while (read_next_x(oenv, status, &t, x0, box));

    gmx_rmpbc_done(gpbc);

    /*********** done with status file **********/
    close_trj(status);

    /* slCharge now contains the total charge per slice, summed over all
       frames. Now divide by nr_frames and integrate twice
     */


    if (bSpherical)
    {
        fprintf(stderr, "\n\nRead %d frames from trajectory. Calculating potential"
                "in spherical coordinates\n", nr_frames);
    }
    else
    {
        fprintf(stderr, "\n\nRead %d frames from trajectory. Calculating potential\n",
                nr_frames);
    }

    for (n = 0; n < nr_grps; n++)
    {
        for (i = 0; i < *nslices; i++)
        {
            if (bSpherical)
            {
                /* charge per volume is now the summed charge, divided by the nr
                   of frames and by the volume of the slice it's in, 4pi r^2 dr
                 */
                slVolume = 4*M_PI * gmx::square(i) * gmx::square(*slWidth) * *slWidth;
                if (slVolume == 0)
                {
                    (*slCharge)[n][i] = 0;
                }
                else
                {
                    (*slCharge)[n][i] = (*slCharge)[n][i] / (nr_frames * slVolume);
                }
            }
            else
            {
                /* get charge per volume */
                (*slCharge)[n][i] = (*slCharge)[n][i] * (*nslices) /
                    (nr_frames * box[axis][axis] * box[ax1][ax1] * box[ax2][ax2]);
            }
        }
        /* Now we have charge densities */
    }

    if (bCorrect && !bSpherical)
    {
        for (n = 0; n < nr_grps; n++)
        {
            nn   = 0;
            qsum = 0;
            for (i = 0; i < *nslices; i++)
            {
                if (std::abs((*slCharge)[n][i]) >= GMX_DOUBLE_MIN)
                {
                    nn++;
                    qsum += (*slCharge)[n][i];
                }
            }
            qsum /= nn;
            for (i = 0; i < *nslices; i++)
            {
                if (std::abs((*slCharge)[n][i]) >= GMX_DOUBLE_MIN)
                {
                    (*slCharge)[n][i] -= qsum;
                }
            }
        }
    }

    for (n = 0; n < nr_grps; n++)
    {
        /* integrate twice to get field and potential */
        p_integrate((*slField)[n], (*slCharge)[n], *nslices, *slWidth);
    }


    if (bCorrect && !bSpherical)
    {
        for (n = 0; n < nr_grps; n++)
        {
            nn   = 0;
            qsum = 0;
            for (i = 0; i < *nslices; i++)
            {
                if (std::abs((*slCharge)[n][i]) >= GMX_DOUBLE_MIN)
                {
                    nn++;
                    qsum += (*slField)[n][i];
                }
            }
            qsum /= nn;
            for (i = 0; i < *nslices; i++)
            {
                if (std::abs((*slCharge)[n][i]) >= GMX_DOUBLE_MIN)
                {
                    (*slField)[n][i] -= qsum;
                }
            }
        }
    }

    for (n = 0; n < nr_grps; n++)
    {
        p_integrate((*slPotential)[n], (*slField)[n], *nslices, *slWidth);
    }

    /* Now correct for eps0 and in spherical case for r*/
    for (n = 0; n < nr_grps; n++)
    {
        for (i = 0; i < *nslices; i++)
        {
            if (bSpherical)
            {
                (*slPotential)[n][i] = ELC * (*slPotential)[n][i] * -1.0E9 /
                    (EPS0 * i * (*slWidth));
                (*slField)[n][i] = ELC * (*slField)[n][i] * 1E18 /
                    (EPS0 * i * (*slWidth));
            }
            else
            {
                (*slPotential)[n][i] = ELC * (*slPotential)[n][i] * -1.0E9 / EPS0;
                (*slField)[n][i]     = ELC * (*slField)[n][i] * 1E18 / EPS0;
            }
        }
    }

    sfree(x0); /* free memory used by coordinate array */
}
Exemplo n.º 25
0
int gmx_covar(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_covar[tt] calculates and diagonalizes the (mass-weighted)",
    "covariance matrix.",
    "All structures are fitted to the structure in the structure file.",
    "When this is not a run input file periodicity will not be taken into",
    "account. When the fit and analysis groups are identical and the analysis",
    "is non mass-weighted, the fit will also be non mass-weighted.",
    "[PAR]",
    "The eigenvectors are written to a trajectory file ([TT]-v[tt]).",
    "When the same atoms are used for the fit and the covariance analysis,",
    "the reference structure for the fit is written first with t=-1.",
    "The average (or reference when [TT]-ref[tt] is used) structure is",
    "written with t=0, the eigenvectors",
    "are written as frames with the eigenvector number as timestamp.",
    "[PAR]",
    "The eigenvectors can be analyzed with [TT]g_anaeig[tt].",
    "[PAR]",
    "Option [TT]-ascii[tt] writes the whole covariance matrix to",
    "an ASCII file. The order of the elements is: x1x1, x1y1, x1z1, x1x2, ...",
    "[PAR]",
    "Option [TT]-xpm[tt] writes the whole covariance matrix to an [TT].xpm[tt] file.",
    "[PAR]",
    "Option [TT]-xpma[tt] writes the atomic covariance matrix to an [TT].xpm[tt] file,",
    "i.e. for each atom pair the sum of the xx, yy and zz covariances is",
    "written.",
    "[PAR]",
    "Note that the diagonalization of a matrix requires memory and time",
    "that will increase at least as fast as than the square of the number",
    "of atoms involved. It is easy to run out of memory, in which",
    "case this tool will probably exit with a 'Segmentation fault'. You",
    "should consider carefully whether a reduced set of atoms will meet",
    "your needs for lower costs."
  };
  static gmx_bool bFit=TRUE,bRef=FALSE,bM=FALSE,bPBC=TRUE;
  static int  end=-1;
  t_pargs pa[] = {
    { "-fit",  FALSE, etBOOL, {&bFit},
      "Fit to a reference structure"},
    { "-ref",  FALSE, etBOOL, {&bRef},
      "Use the deviation from the conformation in the structure file instead of from the average" },
    { "-mwa",  FALSE, etBOOL, {&bM},
      "Mass-weighted covariance analysis"},
    { "-last",  FALSE, etINT, {&end}, 
      "Last eigenvector to write away (-1 is till the last)" },
    { "-pbc",  FALSE,  etBOOL, {&bPBC},
      "Apply corrections for periodic boundary conditions" }
  };
  FILE       *out;
  t_trxstatus *status;
  t_trxstatus *trjout;
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;  
  rvec       *x,*xread,*xref,*xav,*xproj;
  matrix     box,zerobox;
  real       *sqrtm,*mat,*eigval,sum,trace,inv_nframes;
  real       t,tstart,tend,**mat2;
  real       xj,*w_rls=NULL;
  real       min,max,*axis;
  int        ntopatoms,step;
  int        natoms,nat,count,nframes0,nframes,nlevels;
  gmx_large_int_t ndim,i,j,k,l;
  int        WriteXref;
  const char *fitfile,*trxfile,*ndxfile;
  const char *eigvalfile,*eigvecfile,*averfile,*logfile;
  const char *asciifile,*xpmfile,*xpmafile;
  char       str[STRLEN],*fitname,*ananame,*pcwd;
  int        d,dj,nfit;
  atom_id    *index,*ifit;
  gmx_bool       bDiffMass1,bDiffMass2;
  time_t     now;
  char       timebuf[STRLEN];
  t_rgb      rlo,rmi,rhi;
  real       *tmp;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;

  t_filenm fnm[] = { 
    { efTRX, "-f",  NULL, ffREAD }, 
    { efTPS, NULL,  NULL, ffREAD },
    { efNDX, NULL,  NULL, ffOPTRD },
    { efXVG, NULL,  "eigenval", ffWRITE },
    { efTRN, "-v",  "eigenvec", ffWRITE },
    { efSTO, "-av", "average.pdb", ffWRITE },
    { efLOG, NULL,  "covar", ffWRITE },
    { efDAT, "-ascii","covar", ffOPTWR },
    { efXPM, "-xpm","covar", ffOPTWR },
    { efXPM, "-xpma","covara", ffOPTWR }
  }; 
#define NFILE asize(fnm) 

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

  clear_mat(zerobox);

  fitfile    = ftp2fn(efTPS,NFILE,fnm);
  trxfile    = ftp2fn(efTRX,NFILE,fnm);
  ndxfile    = ftp2fn_null(efNDX,NFILE,fnm);
  eigvalfile = ftp2fn(efXVG,NFILE,fnm);
  eigvecfile = ftp2fn(efTRN,NFILE,fnm);
  averfile   = ftp2fn(efSTO,NFILE,fnm);
  logfile    = ftp2fn(efLOG,NFILE,fnm);
  asciifile  = opt2fn_null("-ascii",NFILE,fnm);
  xpmfile    = opt2fn_null("-xpm",NFILE,fnm);
  xpmafile   = opt2fn_null("-xpma",NFILE,fnm);

  read_tps_conf(fitfile,str,&top,&ePBC,&xref,NULL,box,TRUE);
  atoms=&top.atoms;

  if (bFit) {
    printf("\nChoose a group for the least squares fit\n"); 
    get_index(atoms,ndxfile,1,&nfit,&ifit,&fitname);
    if (nfit < 3) 
      gmx_fatal(FARGS,"Need >= 3 points to fit!\n");
  } else
    nfit=0;
  printf("\nChoose a group for the covariance analysis\n"); 
  get_index(atoms,ndxfile,1,&natoms,&index,&ananame);

  bDiffMass1=FALSE;
  if (bFit) {
    snew(w_rls,atoms->nr);
    for(i=0; (i<nfit); i++) {
      w_rls[ifit[i]]=atoms->atom[ifit[i]].m;
      if (i)
        bDiffMass1 = bDiffMass1 || (w_rls[ifit[i]]!=w_rls[ifit[i-1]]);
    }
  }
  bDiffMass2=FALSE;
  snew(sqrtm,natoms);
  for(i=0; (i<natoms); i++)
    if (bM) {
      sqrtm[i]=sqrt(atoms->atom[index[i]].m);
      if (i)
	bDiffMass2 = bDiffMass2 || (sqrtm[i]!=sqrtm[i-1]);
    }
    else
      sqrtm[i]=1.0;
  
  if (bFit && bDiffMass1 && !bDiffMass2) {
    bDiffMass1 = natoms != nfit;
    i=0;
    for (i=0; (i<natoms) && !bDiffMass1; i++)
      bDiffMass1 = index[i] != ifit[i];
    if (!bDiffMass1) {
      fprintf(stderr,"\n"
	      "Note: the fit and analysis group are identical,\n"
	      "      while the fit is mass weighted and the analysis is not.\n"
	      "      Making the fit non mass weighted.\n\n");
      for(i=0; (i<nfit); i++)
	w_rls[ifit[i]]=1.0;
    }
  }
  
  /* Prepare reference frame */
  if (bPBC) {
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,atoms->nr,box);
    gmx_rmpbc(gpbc,atoms->nr,box,xref);
  }
  if (bFit)
    reset_x(nfit,ifit,atoms->nr,NULL,xref,w_rls);

  snew(x,natoms);
  snew(xav,natoms);
  ndim=natoms*DIM;
  if (sqrt(GMX_LARGE_INT_MAX)<ndim) {
    gmx_fatal(FARGS,"Number of degrees of freedoms to large for matrix.\n");
  }
  snew(mat,ndim*ndim);

  fprintf(stderr,"Calculating the average structure ...\n");
  nframes0 = 0;
  nat=read_first_x(oenv,&status,trxfile,&t,&xread,box);
  if (nat != atoms->nr)
    fprintf(stderr,"\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n",natoms,nat);
  do {
    nframes0++;
    /* calculate x: a fitted struture of the selected atoms */
    if (bPBC)
      gmx_rmpbc(gpbc,nat,box,xread);
    if (bFit) {
      reset_x(nfit,ifit,nat,NULL,xread,w_rls);
      do_fit(nat,w_rls,xref,xread);
    }
    for (i=0; i<natoms; i++)
      rvec_inc(xav[i],xread[index[i]]);
  } while (read_next_x(oenv,status,&t,nat,xread,box));
  close_trj(status);
  
  inv_nframes = 1.0/nframes0;
  for(i=0; i<natoms; i++)
    for(d=0; d<DIM; d++) {
      xav[i][d] *= inv_nframes;
      xread[index[i]][d] = xav[i][d];
    }
  write_sto_conf_indexed(opt2fn("-av",NFILE,fnm),"Average structure",
			 atoms,xread,NULL,epbcNONE,zerobox,natoms,index);
  sfree(xread);

  fprintf(stderr,"Constructing covariance matrix (%dx%d) ...\n",(int)ndim,(int)ndim);
  nframes=0;
  nat=read_first_x(oenv,&status,trxfile,&t,&xread,box);
  tstart = t;
  do {
    nframes++;
    tend = t;
    /* calculate x: a (fitted) structure of the selected atoms */
    if (bPBC)
      gmx_rmpbc(gpbc,nat,box,xread);
    if (bFit) {
      reset_x(nfit,ifit,nat,NULL,xread,w_rls);
      do_fit(nat,w_rls,xref,xread);
    }
    if (bRef)
      for (i=0; i<natoms; i++)
	rvec_sub(xread[index[i]],xref[index[i]],x[i]);
    else
      for (i=0; i<natoms; i++)
	rvec_sub(xread[index[i]],xav[i],x[i]);
    
    for (j=0; j<natoms; j++) {
      for (dj=0; dj<DIM; dj++) {
	k=ndim*(DIM*j+dj);
	xj=x[j][dj];
	for (i=j; i<natoms; i++) {
	  l=k+DIM*i;
	  for(d=0; d<DIM; d++)
	    mat[l+d] += x[i][d]*xj;
	}
      }
    }
  } while (read_next_x(oenv,status,&t,nat,xread,box) && 
	   (bRef || nframes < nframes0));
  close_trj(status);
  gmx_rmpbc_done(gpbc);

  fprintf(stderr,"Read %d frames\n",nframes);
  
  if (bRef) {
    /* copy the reference structure to the ouput array x */
    snew(xproj,natoms);
    for (i=0; i<natoms; i++)
      copy_rvec(xref[index[i]],xproj[i]);
  } else {
    xproj = xav;
  }

  /* correct the covariance matrix for the mass */
  inv_nframes = 1.0/nframes;
  for (j=0; j<natoms; j++) 
    for (dj=0; dj<DIM; dj++) 
      for (i=j; i<natoms; i++) { 
	k = ndim*(DIM*j+dj)+DIM*i;
	for (d=0; d<DIM; d++)
	  mat[k+d] = mat[k+d]*inv_nframes*sqrtm[i]*sqrtm[j];
      }

  /* symmetrize the matrix */
  for (j=0; j<ndim; j++) 
    for (i=j; i<ndim; i++)
      mat[ndim*i+j]=mat[ndim*j+i];
  
  trace=0;
  for(i=0; i<ndim; i++)
    trace+=mat[i*ndim+i];
  fprintf(stderr,"\nTrace of the covariance matrix: %g (%snm^2)\n",
	  trace,bM ? "u " : "");
  
  if (asciifile) {
    out = ffopen(asciifile,"w");
    for (j=0; j<ndim; j++) {
      for (i=0; i<ndim; i+=3)
	fprintf(out,"%g %g %g\n",
		mat[ndim*j+i],mat[ndim*j+i+1],mat[ndim*j+i+2]);
    }
    ffclose(out);
  }
  
  if (xpmfile) {
    min = 0;
    max = 0;
    snew(mat2,ndim);
    for (j=0; j<ndim; j++) {
      mat2[j] = &(mat[ndim*j]);
      for (i=0; i<=j; i++) {
	if (mat2[j][i] < min)
	  min = mat2[j][i];
	if (mat2[j][j] > max)
	  max = mat2[j][i];
      }
    }
    snew(axis,ndim);
    for(i=0; i<ndim; i++)
      axis[i] = i+1;
    rlo.r = 0; rlo.g = 0; rlo.b = 1;
    rmi.r = 1; rmi.g = 1; rmi.b = 1;
    rhi.r = 1; rhi.g = 0; rhi.b = 0;
    out = ffopen(xpmfile,"w");
    nlevels = 80;
    write_xpm3(out,0,"Covariance",bM ? "u nm^2" : "nm^2",
	       "dim","dim",ndim,ndim,axis,axis,
	       mat2,min,0.0,max,rlo,rmi,rhi,&nlevels);
    ffclose(out);
    sfree(axis);
    sfree(mat2);
  }

  if (xpmafile) {
    min = 0;
    max = 0;
    snew(mat2,ndim/DIM);
    for (i=0; i<ndim/DIM; i++)
      snew(mat2[i],ndim/DIM);
    for (j=0; j<ndim/DIM; j++) {
      for (i=0; i<=j; i++) {
	mat2[j][i] = 0;
	for(d=0; d<DIM; d++)
	  mat2[j][i] += mat[ndim*(DIM*j+d)+DIM*i+d];
	if (mat2[j][i] < min)
	  min = mat2[j][i];
	if (mat2[j][j] > max)
	  max = mat2[j][i];
	mat2[i][j] = mat2[j][i];
      }
    }
    snew(axis,ndim/DIM);
    for(i=0; i<ndim/DIM; i++)
      axis[i] = i+1;
    rlo.r = 0; rlo.g = 0; rlo.b = 1;
    rmi.r = 1; rmi.g = 1; rmi.b = 1;
    rhi.r = 1; rhi.g = 0; rhi.b = 0;
    out = ffopen(xpmafile,"w");
    nlevels = 80;
    write_xpm3(out,0,"Covariance",bM ? "u nm^2" : "nm^2",
	       "atom","atom",ndim/DIM,ndim/DIM,axis,axis,
	       mat2,min,0.0,max,rlo,rmi,rhi,&nlevels);
    ffclose(out);
    sfree(axis);
    for (i=0; i<ndim/DIM; i++)
      sfree(mat2[i]);
    sfree(mat2);
  }


  /* call diagonalization routine */
  
  fprintf(stderr,"\nDiagonalizing ...\n");
  fflush(stderr);

  snew(eigval,ndim);
  snew(tmp,ndim*ndim);
  memcpy(tmp,mat,ndim*ndim*sizeof(real));
  eigensolver(tmp,ndim,0,ndim,eigval,mat);
  sfree(tmp);
  
  /* now write the output */

  sum=0;
  for(i=0; i<ndim; i++)
    sum+=eigval[i];
  fprintf(stderr,"\nSum of the eigenvalues: %g (%snm^2)\n",
	  sum,bM ? "u " : "");
  if (fabs(trace-sum)>0.01*trace)
    fprintf(stderr,"\nWARNING: eigenvalue sum deviates from the trace of the covariance matrix\n");
  
  fprintf(stderr,"\nWriting eigenvalues to %s\n",eigvalfile);

  sprintf(str,"(%snm\\S2\\N)",bM ? "u " : "");
  out=xvgropen(eigvalfile, 
	       "Eigenvalues of the covariance matrix",
	       "Eigenvector index",str,oenv);  
  for (i=0; (i<ndim); i++)
    fprintf (out,"%10d %g\n",(int)i+1,eigval[ndim-1-i]);
  ffclose(out);  

  if (end==-1) {
    if (nframes-1 < ndim)
      end=nframes-1;
    else
      end=ndim;
  }
  if (bFit) {
    /* misuse lambda: 0/1 mass weighted analysis no/yes */
    if (nfit==natoms) {
      WriteXref = eWXR_YES;
      for(i=0; i<nfit; i++)
	copy_rvec(xref[ifit[i]],x[i]);
    } else
      WriteXref = eWXR_NO;
  } else {
    /* misuse lambda: -1 for no fit */
    WriteXref = eWXR_NOFIT;
  }

  write_eigenvectors(eigvecfile,natoms,mat,TRUE,1,end,
		     WriteXref,x,bDiffMass1,xproj,bM,eigval);

  out = ffopen(logfile,"w");

  time(&now);
  gmx_ctime_r(&now,timebuf,STRLEN);
  fprintf(out,"Covariance analysis log, written %s\n",timebuf);
    
  fprintf(out,"Program: %s\n",argv[0]);
#if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
  pcwd=_getcwd(str,STRLEN);
#else
  pcwd=getcwd(str,STRLEN);
#endif
  if(NULL==pcwd)
  {
      gmx_fatal(FARGS,"Current working directory is undefined");
  }

  fprintf(out,"Working directory: %s\n\n",str);

  fprintf(out,"Read %d frames from %s (time %g to %g %s)\n",nframes,trxfile,
	  output_env_conv_time(oenv,tstart),output_env_conv_time(oenv,tend),output_env_get_time_unit(oenv));
  if (bFit)
    fprintf(out,"Read reference structure for fit from %s\n",fitfile);
  if (ndxfile)
    fprintf(out,"Read index groups from %s\n",ndxfile);
  fprintf(out,"\n");

  fprintf(out,"Analysis group is '%s' (%d atoms)\n",ananame,natoms);
  if (bFit)
    fprintf(out,"Fit group is '%s' (%d atoms)\n",fitname,nfit);
  else
    fprintf(out,"No fit was used\n");
  fprintf(out,"Analysis is %smass weighted\n", bDiffMass2 ? "":"non-");
  if (bFit)
    fprintf(out,"Fit is %smass weighted\n", bDiffMass1 ? "":"non-");
  fprintf(out,"Diagonalized the %dx%d covariance matrix\n",(int)ndim,(int)ndim);
  fprintf(out,"Trace of the covariance matrix before diagonalizing: %g\n",
	  trace);
  fprintf(out,"Trace of the covariance matrix after diagonalizing: %g\n\n",
	  sum);

  fprintf(out,"Wrote %d eigenvalues to %s\n",(int)ndim,eigvalfile);
  if (WriteXref == eWXR_YES)
    fprintf(out,"Wrote reference structure to %s\n",eigvecfile);
  fprintf(out,"Wrote average structure to %s and %s\n",averfile,eigvecfile);
  fprintf(out,"Wrote eigenvectors %d to %d to %s\n",1,end,eigvecfile);

  ffclose(out);

  fprintf(stderr,"Wrote the log to %s\n",logfile);

  thanx(stderr);
  
  return 0;
}
Exemplo n.º 26
0
int gmx_rotmat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] 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]gmx 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)

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

    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);

    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, x, box));

    gmx_rmpbc_done(gpbc);

    close_trj(status);

    gmx_ffclose(out);

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

    return 0;
}
Exemplo n.º 27
0
int gmx_mdmat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_mdmat[tt] makes distance matrices consisting of the smallest distance",
        "between residue pairs. With [TT]-frames[tt], these distance matrices can be",
        "stored in order to see differences in tertiary structure as a",
        "function of time. If you choose your options unwisely, this may generate",
        "a large output file. By default, only an averaged matrix over the whole",
        "trajectory is output.",
        "Also a count of the number of different atomic contacts between",
        "residues over the whole trajectory can be made.",
        "The output can be processed with [TT]xpm2ps[tt] to make a PostScript (tm) plot."
    };
    static real     truncate = 1.5;
    static gmx_bool bAtom    = FALSE;
    static int      nlevels  = 40;
    t_pargs         pa[]     = {
        { "-t",   FALSE, etREAL, {&truncate},
          "trunc distance" },
        { "-nlevels",   FALSE, etINT,  {&nlevels},
          "Discretize distance in this number of levels" }
    };
    t_filenm        fnm[] = {
        { efTRX, "-f",  NULL, ffREAD },
        { efTPS, NULL,  NULL, ffREAD },
        { efNDX, NULL,  NULL, ffOPTRD },
        { efXPM, "-mean", "dm", ffWRITE },
        { efXPM, "-frames", "dmf", ffOPTWR },
        { efXVG, "-no", "num", ffOPTWR },
    };
#define NFILE asize(fnm)

    FILE          *out = NULL, *fp;
    t_topology     top;
    int            ePBC;
    t_atoms        useatoms;
    int            isize;
    atom_id       *index;
    char          *grpname;
    int           *rndx, *natm, prevres, newres;

    int            i, j, nres, natoms, nframes, it, trxnat;
    t_trxstatus   *status;
    int            nr0;
    gmx_bool       bCalcN, bFrames;
    real           t, ratio;
    char           title[256], label[234];
    t_rgb          rlo, rhi;
    rvec          *x;
    real         **mdmat, *resnr, **totmdmat;
    int          **nmat, **totnmat;
    real          *mean_n;
    int           *tot_n;
    matrix         box;
    output_env_t   oenv;
    gmx_rmpbc_t    gpbc = NULL;

    CopyRight(stderr, argv[0]);

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

    fprintf(stderr, "Will truncate at %f nm\n", truncate);
    bCalcN  = opt2bSet("-no", NFILE, fnm);
    bFrames = opt2bSet("-frames", NFILE, fnm);
    if (bCalcN)
    {
        fprintf(stderr, "Will calculate number of different contacts\n");
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &x, NULL, box, FALSE);

    fprintf(stderr, "Select group for analysis\n");
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    natoms = isize;
    snew(useatoms.atom, natoms);
    snew(useatoms.atomname, natoms);

    useatoms.nres = 0;
    snew(useatoms.resinfo, natoms);

    prevres = top.atoms.atom[index[0]].resind;
    newres  = 0;
    for (i = 0; (i < isize); i++)
    {
        int ii = index[i];
        useatoms.atomname[i] = top.atoms.atomname[ii];
        if (top.atoms.atom[ii].resind != prevres)
        {
            prevres = top.atoms.atom[ii].resind;
            newres++;
            useatoms.resinfo[i] = top.atoms.resinfo[prevres];
            if (debug)
            {
                fprintf(debug, "New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n",
                        *(top.atoms.resinfo[top.atoms.atom[ii].resind].name),
                        *(top.atoms.atomname[ii]),
                        ii, i, newres);
            }
        }
        useatoms.atom[i].resind = newres;
    }
    useatoms.nres = newres+1;
    useatoms.nr   = isize;

    rndx = res_ndx(&(useatoms));
    natm = res_natm(&(useatoms));
    nres = useatoms.nres;
    fprintf(stderr, "There are %d residues with %d atoms\n", nres, natoms);

    snew(resnr, nres);
    snew(mdmat, nres);
    snew(nmat, nres);
    snew(totnmat, nres);
    snew(mean_n, nres);
    snew(tot_n, nres);
    for (i = 0; (i < nres); i++)
    {
        snew(mdmat[i], nres);
        snew(nmat[i], natoms);
        snew(totnmat[i], natoms);
        resnr[i] = i+1;
    }
    snew(totmdmat, nres);
    for (i = 0; (i < nres); i++)
    {
        snew(totmdmat[i], nres);
    }

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

    nframes = 0;

    rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0;
    rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0;

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

    if (bFrames)
    {
        out = opt2FILE("-frames", NFILE, fnm, "w");
    }
    do
    {
        gmx_rmpbc(gpbc, trxnat, box, x);
        nframes++;
        calc_mat(nres, natoms, rndx, x, index, truncate, mdmat, nmat, ePBC, box);
        for (i = 0; (i < nres); i++)
        {
            for (j = 0; (j < natoms); j++)
            {
                if (nmat[i][j])
                {
                    totnmat[i][j]++;
                }
            }
        }
        for (i = 0; (i < nres); i++)
        {
            for (j = 0; (j < nres); j++)
            {
                totmdmat[i][j] += mdmat[i][j];
            }
        }
        if (bFrames)
        {
            sprintf(label, "t=%.0f ps", t);
            write_xpm(out, 0, label, "Distance (nm)", "Residue Index", "Residue Index",
                      nres, nres, resnr, resnr, mdmat, 0, truncate, rlo, rhi, &nlevels);
        }
    }
    while (read_next_x(oenv, status, &t, trxnat, x, box));
    fprintf(stderr, "\n");
    close_trj(status);
    gmx_rmpbc_done(gpbc);
    if (bFrames)
    {
        ffclose(out);
    }

    fprintf(stderr, "Processed %d frames\n", nframes);

    for (i = 0; (i < nres); i++)
    {
        for (j = 0; (j < nres); j++)
        {
            totmdmat[i][j] /= nframes;
        }
    }
    write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean smallest distance",
              "Distance (nm)", "Residue Index", "Residue Index",
              nres, nres, resnr, resnr, totmdmat, 0, truncate, rlo, rhi, &nlevels);

    if (bCalcN)
    {
        tot_nmat(nres, natoms, nframes, totnmat, tot_n, mean_n);
        fp = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                      "Increase in number of contacts", "Residue", "Ratio", oenv);
        fprintf(fp, "@ legend on\n");
        fprintf(fp, "@ legend box on\n");
        fprintf(fp, "@ legend loctype view\n");
        fprintf(fp, "@ legend 0.75, 0.8\n");
        fprintf(fp, "@ legend string 0 \"Total/mean\"\n");
        fprintf(fp, "@ legend string 1 \"Total\"\n");
        fprintf(fp, "@ legend string 2 \"Mean\"\n");
        fprintf(fp, "@ legend string 3 \"# atoms\"\n");
        fprintf(fp, "@ legend string 4 \"Mean/# atoms\"\n");
        fprintf(fp, "#%3s %8s  %3s  %8s  %3s  %8s\n",
                "res", "ratio", "tot", "mean", "natm", "mean/atm");
        for (i = 0; (i < nres); i++)
        {
            if (mean_n[i] == 0)
            {
                ratio = 1;
            }
            else
            {
                ratio = tot_n[i]/mean_n[i];
            }
            fprintf(fp, "%3d  %8.3f  %3d  %8.3f  %3d  %8.3f\n",
                    i+1, ratio, tot_n[i], mean_n[i], natm[i], mean_n[i]/natm[i]);
        }
        ffclose(fp);
    }

    thanx(stderr);

    return 0;
}
Exemplo n.º 28
0
static void get_refx(output_env_t oenv, const char *trxfn, int nfitdim, int skip,
                     int gnx, int *index,
                     gmx_bool bMW, t_topology *top, int ePBC, rvec *x_ref)
{
    int          natoms, nfr_all, nfr, i, j, a, r, c, min_fr;
    t_trxstatus *status;
    real        *ti, min_t;
    double       tot_mass, msd, *srmsd, min_srmsd, srmsd_tot;
    rvec        *x, **xi;
    real         xf;
    matrix       box, R;
    real        *w_rls;
    gmx_rmpbc_t  gpbc = NULL;


    nfr_all = 0;
    nfr     = 0;
    snew(ti, 100);
    snew(xi, 100);
    natoms = read_first_x(oenv, &status, trxfn, &ti[nfr], &x, box);

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

    do
    {
        if (nfr_all % skip == 0)
        {
            gmx_rmpbc(gpbc, natoms, box, x);
            snew(xi[nfr], gnx);
            for (i = 0; i < gnx; i++)
            {
                copy_rvec(x[index[i]], xi[nfr][i]);
            }
            reset_x(gnx, NULL, gnx, NULL, xi[nfr], w_rls);
            nfr++;
            if (nfr % 100 == 0)
            {
                srenew(ti, nfr+100);
                srenew(xi, nfr+100);
            }
        }
        nfr_all++;
    }
    while (read_next_x(oenv, status, &ti[nfr], x, box));
    close_trj(status);
    sfree(x);

    gmx_rmpbc_done(gpbc);

    snew(srmsd, nfr);
    for (i = 0; i < nfr; i++)
    {
        printf("\rProcessing frame %d of %d", i, nfr);
        for (j = i+1; j < nfr; j++)
        {
            calc_fit_R(nfitdim, gnx, w_rls, xi[i], xi[j], R);

            msd = 0;
            for (a = 0; a < gnx; a++)
            {
                for (r = 0; r < DIM; r++)
                {
                    xf = 0;
                    for (c = 0; c < DIM; c++)
                    {
                        xf += R[r][c]*xi[j][a][c];
                    }
                    msd += w_rls[a]*sqr(xi[i][a][r] - xf);
                }
            }
            msd      /= tot_mass;
            srmsd[i] += sqrt(msd);
            srmsd[j] += sqrt(msd);
        }
        sfree(xi[i]);
    }
    printf("\n");
    sfree(w_rls);

    min_srmsd = GMX_REAL_MAX;
    min_fr    = -1;
    min_t     = -1;
    srmsd_tot = 0;
    for (i = 0; i < nfr; i++)
    {
        srmsd[i] /= (nfr - 1);
        if (srmsd[i] < min_srmsd)
        {
            min_srmsd = srmsd[i];
            min_fr    = i;
            min_t     = ti[i];
        }
        srmsd_tot += srmsd[i];
    }
    sfree(srmsd);

    printf("Average RMSD between all structures: %.3f\n", srmsd_tot/nfr);
    printf("Structure with lowest RMSD to all others: time %g, av. RMSD %.3f\n",
           min_t, min_srmsd);

    for (a = 0; a < gnx; a++)
    {
        copy_rvec(xi[min_fr][a], x_ref[index[a]]);
    }

    sfree(xi);
}
Exemplo n.º 29
0
int gmx_rmsf(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] computes the root mean square fluctuation (RMSF, i.e. standard ",
        "deviation) of atomic positions in the trajectory (supplied with [TT]-f[tt])",
        "after (optionally) fitting to a reference frame (supplied with [TT]-s[tt]).[PAR]",
        "With option [TT]-oq[tt] the RMSF values are converted to B-factor",
        "values, which are written to a [REF].pdb[ref] file with the coordinates, of the",
        "structure file, or of a [REF].pdb[ref] file when [TT]-q[tt] is specified.",
        "Option [TT]-ox[tt] writes the B-factors to a file with the average",
        "coordinates.[PAR]",
        "With the option [TT]-od[tt] the root mean square deviation with",
        "respect to the reference structure is calculated.[PAR]",
        "With the option [TT]-aniso[tt], [THISMODULE] will compute anisotropic",
        "temperature factors and then it will also output average coordinates",
        "and a [REF].pdb[ref] file with ANISOU records (corresonding to the [TT]-oq[tt]",
        "or [TT]-ox[tt] option). Please note that the U values",
        "are orientation-dependent, so before comparison with experimental data",
        "you should verify that you fit to the experimental coordinates.[PAR]",
        "When a [REF].pdb[ref] input file is passed to the program and the [TT]-aniso[tt]",
        "flag is set",
        "a correlation plot of the Uij will be created, if any anisotropic",
        "temperature factors are present in the [REF].pdb[ref] file.[PAR]",
        "With option [TT]-dir[tt] the average MSF (3x3) matrix is diagonalized.",
        "This shows the directions in which the atoms fluctuate the most and",
        "the least."
    };
    static gmx_bool   bRes    = FALSE, bAniso = FALSE, bFit = TRUE;
    t_pargs           pargs[] = {
        { "-res", FALSE, etBOOL, {&bRes},
          "Calculate averages for each residue" },
        { "-aniso", FALSE, etBOOL, {&bAniso},
          "Compute anisotropic termperature factors" },
        { "-fit", FALSE, etBOOL, {&bFit},
          "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." }
    };
    int               natom;
    int               i, m, teller = 0;
    real              t, *w_rls;

    t_topology        top;
    int               ePBC;
    t_atoms          *pdbatoms, *refatoms;

    matrix            box, pdbbox;
    rvec             *x, *pdbx, *xref;
    t_trxstatus      *status;
    const char       *label;

    FILE             *fp;         /* the graphics file */
    const char       *devfn, *dirfn;
    int               resind;

    gmx_bool          bReadPDB;
    int              *index;
    int               isize;
    char             *grpnames;

    real              bfac, pdb_bfac, *Uaver;
    double          **U, *xav;
    int               aid;
    rvec             *rmsd_x = nullptr;
    double           *rmsf, invcount, totmass;
    int               d;
    real              count = 0;
    rvec              xcm;
    gmx_rmpbc_t       gpbc = nullptr;

    gmx_output_env_t *oenv;

    const char       *leg[2] = { "MD", "X-Ray" };

    t_filenm          fnm[] = {
        { efTRX, "-f",  nullptr,     ffREAD  },
        { efTPS, nullptr,  nullptr,     ffREAD  },
        { efNDX, nullptr,  nullptr,     ffOPTRD },
        { efPDB, "-q",  nullptr,     ffOPTRD },
        { efPDB, "-oq", "bfac",   ffOPTWR },
        { efPDB, "-ox", "xaver",  ffOPTWR },
        { efXVG, "-o",  "rmsf",   ffWRITE },
        { efXVG, "-od", "rmsdev", ffOPTWR },
        { efXVG, "-oc", "correl", ffOPTWR },
        { efLOG, "-dir", "rmsf",  ffOPTWR }
    };
#define NFILE asize(fnm)

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

    bReadPDB = ftp2bSet(efPDB, NFILE, fnm);
    devfn    = opt2fn_null("-od", NFILE, fnm);
    dirfn    = opt2fn_null("-dir", NFILE, fnm);

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xref, nullptr, box, TRUE);
    const char *title = *top.name;
    snew(w_rls, top.atoms.nr);

    fprintf(stderr, "Select group(s) for root mean square calculation\n");
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpnames);

    /* Set the weight */
    for (i = 0; i < isize; i++)
    {
        w_rls[index[i]] = top.atoms.atom[index[i]].m;
    }

    /* Malloc the rmsf arrays */
    snew(xav, isize*DIM);
    snew(U, isize);
    for (i = 0; i < isize; i++)
    {
        snew(U[i], DIM*DIM);
    }
    snew(rmsf, isize);
    if (devfn)
    {
        snew(rmsd_x, isize);
    }

    if (bReadPDB)
    {
        t_topology *top_pdb;
        snew(top_pdb, 1);
        /* Read coordinates twice */
        read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, nullptr, nullptr, nullptr, pdbbox, FALSE);
        snew(pdbatoms, 1);
        *pdbatoms = top_pdb->atoms;
        read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, nullptr, &pdbx, nullptr, pdbbox, FALSE);
        /* TODO Should this assert that top_pdb->atoms.nr == top.atoms.nr?
         * See discussion at https://gerrit.gromacs.org/#/c/6430/1 */
        title = *top_pdb->name;
        snew(refatoms, 1);
        *refatoms = top_pdb->atoms;
        sfree(top_pdb);
    }
    else
    {
        pdbatoms  = &top.atoms;
        refatoms  = &top.atoms;
        pdbx      = xref;
        snew(pdbatoms->pdbinfo, pdbatoms->nr);
        pdbatoms->havePdbInfo = TRUE;
        copy_mat(box, pdbbox);
    }

    if (bFit)
    {
        sub_xcm(xref, isize, index, top.atoms.atom, xcm, FALSE);
    }

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

    if (bFit)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natom);
    }

    /* Now read the trj again to compute fluctuations */
    teller = 0;
    do
    {
        if (bFit)
        {
            /* Remove periodic boundary */
            gmx_rmpbc(gpbc, natom, box, x);

            /* Set center of mass to zero */
            sub_xcm(x, isize, index, top.atoms.atom, xcm, FALSE);

            /* Fit to reference structure */
            do_fit(natom, w_rls, xref, x);
        }

        /* Calculate Anisotropic U Tensor */
        for (i = 0; i < isize; i++)
        {
            aid = index[i];
            for (d = 0; d < DIM; d++)
            {
                xav[i*DIM + d] += x[aid][d];
                for (m = 0; m < DIM; m++)
                {
                    U[i][d*DIM + m] += x[aid][d]*x[aid][m];
                }
            }
        }

        if (devfn)
        {
            /* Calculate RMS Deviation */
            for (i = 0; (i < isize); i++)
            {
                aid = index[i];
                for (d = 0; (d < DIM); d++)
                {
                    rmsd_x[i][d] += gmx::square(x[aid][d]-xref[aid][d]);
                }
            }
        }
        count += 1.0;
        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trx(status);

    if (bFit)
    {
        gmx_rmpbc_done(gpbc);
    }


    invcount = 1.0/count;
    snew(Uaver, DIM*DIM);
    totmass = 0;
    for (i = 0; i < isize; i++)
    {
        for (d = 0; d < DIM; d++)
        {
            xav[i*DIM + d] *= invcount;
        }
        for (d = 0; d < DIM; d++)
        {
            for (m = 0; m < DIM; m++)
            {
                U[i][d*DIM + m] = U[i][d*DIM + m]*invcount
                    - xav[i*DIM + d]*xav[i*DIM + m];
                Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m];
            }
        }
        totmass += top.atoms.atom[index[i]].m;
    }
    for (d = 0; d < DIM*DIM; d++)
    {
        Uaver[d] /= totmass;
    }

    if (bRes)
    {
        for (d = 0; d < DIM*DIM; d++)
        {
            average_residues(nullptr, U, d, isize, index, w_rls, &top.atoms);
        }
    }

    if (bAniso)
    {
        for (i = 0; i < isize; i++)
        {
            aid = index[i];
            pdbatoms->pdbinfo[aid].bAnisotropic = TRUE;
            pdbatoms->pdbinfo[aid].uij[U11]     = static_cast<int>(1e6*U[i][XX*DIM + XX]);
            pdbatoms->pdbinfo[aid].uij[U22]     = static_cast<int>(1e6*U[i][YY*DIM + YY]);
            pdbatoms->pdbinfo[aid].uij[U33]     = static_cast<int>(1e6*U[i][ZZ*DIM + ZZ]);
            pdbatoms->pdbinfo[aid].uij[U12]     = static_cast<int>(1e6*U[i][XX*DIM + YY]);
            pdbatoms->pdbinfo[aid].uij[U13]     = static_cast<int>(1e6*U[i][XX*DIM + ZZ]);
            pdbatoms->pdbinfo[aid].uij[U23]     = static_cast<int>(1e6*U[i][YY*DIM + ZZ]);
        }
    }
    if (bRes)
    {
        label = "Residue";
    }
    else
    {
        label = "Atom";
    }

    for (i = 0; i < isize; i++)
    {
        rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ];
    }

    if (dirfn)
    {
        fprintf(stdout, "\n");
        print_dir(stdout, Uaver);
        fp = gmx_ffopen(dirfn, "w");
        print_dir(fp, Uaver);
        gmx_ffclose(fp);
    }

    for (i = 0; i < isize; i++)
    {
        sfree(U[i]);
    }
    sfree(U);

    /* Write RMSF output */
    if (bReadPDB)
    {
        bfac = 8.0*M_PI*M_PI/3.0*100;
        fp   = xvgropen(ftp2fn(efXVG, NFILE, fnm), "B-Factors",
                        label, "(A\\b\\S\\So\\N\\S2\\N)", oenv);
        xvgr_legend(fp, 2, leg, oenv);
        for (i = 0; (i < isize); i++)
        {
            if (!bRes || i+1 == isize ||
                top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
            {
                resind    = top.atoms.atom[index[i]].resind;
                pdb_bfac  = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind],
                                          *(top.atoms.atomname[index[i]]));

                fprintf(fp, "%5d  %10.5f  %10.5f\n",
                        bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, rmsf[i]*bfac,
                        pdb_bfac);
            }
        }
        xvgrclose(fp);
    }
    else
    {
        fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS fluctuation", label, "(nm)", oenv);
        for (i = 0; i < isize; i++)
        {
            if (!bRes || i+1 == isize ||
                top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
            {
                fprintf(fp, "%5d %8.4f\n",
                        bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i]));
            }
        }
        xvgrclose(fp);
    }

    for (i = 0; i < isize; i++)
    {
        pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i];
    }

    if (devfn)
    {
        for (i = 0; i < isize; i++)
        {
            rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count;
        }
        if (bRes)
        {
            average_residues(rmsf, nullptr, 0, isize, index, w_rls, &top.atoms);
        }
        /* Write RMSD output */
        fp = xvgropen(devfn, "RMS Deviation", label, "(nm)", oenv);
        for (i = 0; i < isize; i++)
        {
            if (!bRes || i+1 == isize ||
                top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind)
            {
                fprintf(fp, "%5d %8.4f\n",
                        bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i]));
            }
        }
        xvgrclose(fp);
    }

    if (opt2bSet("-oq", NFILE, fnm))
    {
        /* Write a .pdb file with B-factors and optionally anisou records */
        for (i = 0; i < isize; i++)
        {
            rvec_inc(pdbx[index[i]], xcm);
        }
        write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx,
                               nullptr, ePBC, pdbbox, isize, index);
    }
    if (opt2bSet("-ox", NFILE, fnm))
    {
        rvec *bFactorX;
        snew(bFactorX, top.atoms.nr);
        for (i = 0; i < isize; i++)
        {
            for (d = 0; d < DIM; d++)
            {
                bFactorX[index[i]][d] = xcm[d] + xav[i*DIM + d];
            }
        }
        /* Write a .pdb file with B-factors and optionally anisou records */
        write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr,
                               ePBC, pdbbox, isize, index);
        sfree(bFactorX);
    }
    if (bAniso)
    {
        correlate_aniso(opt2fn("-oc", NFILE, fnm), refatoms, pdbatoms, oenv);
        do_view(oenv, opt2fn("-oc", NFILE, fnm), "-nxy");
    }
    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
    if (devfn)
    {
        do_view(oenv, opt2fn("-od", NFILE, fnm), "-nxy");
    }

    return 0;
}
Exemplo n.º 30
0
static void density_in_time (const char *fn, atom_id **index, int gnx[], real bw, real bwz, int nsttblock, real *****Densdevel, int *xslices, int *yslices, int *zslices, int *tblock, t_topology *top, int ePBC, int axis, gmx_bool bCenter, gmx_bool bps1d, const gmx_output_env_t *oenv)

{
/*
 * *****Densdevel pointer to array of density values in slices and frame-blocks Densdevel[*nsttblock][*xslices][*yslices][*zslices]
 * Densslice[x][y][z]
 * nsttblock - nr of frames in each time-block
 * bw  widths of normal slices
 *
 * axis	 - axis direction (normal to slices)
 * nndx - number ot atoms in **index
 * grpn	 - group number in index
 */
    t_trxstatus *status;
    gmx_rmpbc_t  gpbc = NULL;
    matrix       box;                    /* Box - 3x3 -each step*/
    rvec        *x0;                     /* List of Coord without PBC*/
    int          i, j,                   /* loop indices, checks etc*/
                 ax1     = 0, ax2 = 0,   /* tangent directions */
                 framenr = 0,            /* frame number in trajectory*/
                 slicex, slicey, slicez; /*slice # of x y z position */
    real ***Densslice = NULL;            /* Density-slice in one frame*/
    real    dscale;                      /*physical scaling factor*/
    real    t, x, y, z;                  /* time and coordinates*/
    rvec    bbww;

    *tblock = 0; /* blocknr in block average - initialise to 0*/
    /* Axis: X=0, Y=1,Z=2 */
    switch (axis)
    {
        case 0:
            ax1 = YY; ax2 = ZZ; /*Surface: YZ*/
            break;
        case 1:
            ax1 = ZZ; ax2 = XX; /* Surface : XZ*/
            break;
        case 2:
            ax1 = XX; ax2 = YY; /* Surface XY*/
            break;
        default:
            gmx_fatal(FARGS, "Invalid axes. Terminating\n");
    }

    if (read_first_x(oenv, &status, fn, &t, &x0, box) == 0)
    {
        gmx_fatal(FARGS, "Could not read coordinates from file"); /* Open trajectory for read*/


    }
    *zslices = 1+static_cast<int>(std::floor(box[axis][axis]/bwz));
    *yslices = 1+static_cast<int>(std::floor(box[ax2][ax2]/bw));
    *xslices = 1+static_cast<int>(std::floor(box[ax1][ax1]/bw));
    if (bps1d)
    {
        if (*xslices < *yslices)
        {
            *xslices = 1;
        }
        else
        {
            *yslices = 1;
        }
    }
    fprintf(stderr,
            "\nDividing the box in %5d x %5d x %5d slices with binw %f along axis %d\n", *xslices, *yslices, *zslices, bw, axis );


    /****Start trajectory processing***/

    /*Initialize Densdevel and PBC-remove*/
    gpbc = gmx_rmpbc_init(&top->idef, ePBC, top->atoms.nr);

    *Densdevel = NULL;

    do
    {
        bbww[XX] = box[ax1][ax1]/ *xslices;
        bbww[YY] = box[ax2][ax2]/ *yslices;
        bbww[ZZ] = box[axis][axis]/ *zslices;
        gmx_rmpbc(gpbc, top->atoms.nr, box, x0);
        /*Reset Densslice every nsttblock steps*/
        /* The first conditional is for clang to understand that this branch is
         * always taken the first time. */
        if (Densslice == NULL || framenr % nsttblock == 0)
        {
            snew(Densslice, *xslices);
            for (i = 0; i < *xslices; i++)
            {
                snew(Densslice[i], *yslices);
                for (j = 0; j < *yslices; j++)
                {
                    snew(Densslice[i][j], *zslices);
                }
            }

            /* Allocate Memory to  extra frame in Densdevel -  rather stupid approach:
             * A single frame each time, although only every nsttblock steps.
             */
            srenew(*Densdevel, *tblock+1);
            (*Densdevel)[*tblock] = Densslice;
        }

        dscale = (*xslices)*(*yslices)*(*zslices)*AMU/ (box[ax1][ax1]*box[ax2][ax2]*box[axis][axis]*nsttblock*(NANO*NANO*NANO));

        if (bCenter)
        {
            center_coords(&top->atoms, box, x0, axis);
        }


        for (j = 0; j < gnx[0]; j++)
        {   /*Loop over all atoms in selected index*/
            x = x0[index[0][j]][ax1];
            y = x0[index[0][j]][ax2];
            z = x0[index[0][j]][axis];
            while (x < 0)
            {
                x += box[ax1][ax1];
            }
            while (x > box[ax1][ax1])
            {
                x -= box[ax1][ax1];
            }

            while (y < 0)
            {
                y += box[ax2][ax2];
            }
            while (y > box[ax2][ax2])
            {
                y -= box[ax2][ax2];
            }

            while (z < 0)
            {
                z += box[axis][axis];
            }
            while (z > box[axis][axis])
            {
                z -= box[axis][axis];
            }

            slicex = static_cast<int>(x/bbww[XX]) % *xslices;
            slicey = static_cast<int>(y/bbww[YY]) % *yslices;
            slicez = static_cast<int>(z/bbww[ZZ]) % *zslices;
            Densslice[slicex][slicey][slicez] += (top->atoms.atom[index[0][j]].m*dscale);
        }

        framenr++;

        if (framenr % nsttblock == 0)
        {
            /*Implicit incrementation of Densdevel via renewal of Densslice*/
            /*only every nsttblock steps*/
            (*tblock)++;
        }

    }
    while (read_next_x(oenv, status, &t, x0, box));


    /*Free memory we no longer need and exit.*/
    gmx_rmpbc_done(gpbc);
    close_trj(status);

    if (0)
    {
        FILE *fp;
        fp = fopen("koko.xvg", "w");
        for (j = 0; (j < *zslices); j++)
        {
            fprintf(fp, "%5d", j);
            for (i = 0; (i < *tblock); i++)
            {
                fprintf(fp, "  %10g", (*Densdevel)[i][9][1][j]);
            }
            fprintf(fp, "\n");
        }
        fclose(fp);
    }

}