int gmx_densmap(int argc, char *argv[])
{
    const char        *desc[] = {
        "[TT]g_densmap[tt] computes 2D number-density maps.",
        "It can make planar and axial-radial density maps.",
        "The output [TT].xpm[tt] file can be visualized with for instance xv",
        "and can be converted to postscript with [TT]xpm2ps[tt].",
        "Optionally, output can be in text form to a [TT].dat[tt] file with [TT]-od[tt], instead of the usual [TT].xpm[tt] file with [TT]-o[tt].",
        "[PAR]",
        "The default analysis is a 2-D number-density map for a selected",
        "group of atoms in the x-y plane.",
        "The averaging direction can be changed with the option [TT]-aver[tt].",
        "When [TT]-xmin[tt] and/or [TT]-xmax[tt] are set only atoms that are",
        "within the limit(s) in the averaging direction are taken into account.",
        "The grid spacing is set with the option [TT]-bin[tt].",
        "When [TT]-n1[tt] or [TT]-n2[tt] is non-zero, the grid",
        "size is set by this option.",
        "Box size fluctuations are properly taken into account.",
        "[PAR]",
        "When options [TT]-amax[tt] and [TT]-rmax[tt] are set, an axial-radial",
        "number-density map is made. Three groups should be supplied, the centers",
        "of mass of the first two groups define the axis, the third defines the",
        "analysis group. The axial direction goes from -amax to +amax, where",
        "the center is defined as the midpoint between the centers of mass and",
        "the positive direction goes from the first to the second center of mass.",
        "The radial direction goes from 0 to rmax or from -rmax to +rmax",
        "when the [TT]-mirror[tt] option has been set.",
        "[PAR]",
        "The normalization of the output is set with the [TT]-unit[tt] option.",
        "The default produces a true number density. Unit [TT]nm-2[tt] leaves out",
        "the normalization for the averaging or the angular direction.",
        "Option [TT]count[tt] produces the count for each grid cell.",
        "When you do not want the scale in the output to go",
        "from zero to the maximum density, you can set the maximum",
        "with the option [TT]-dmax[tt]."
    };
    static int         n1      = 0, n2 = 0;
    static real        xmin    = -1, xmax = -1, bin = 0.02, dmin = 0, dmax = 0, amax = 0, rmax = 0;
    static gmx_bool    bMirror = FALSE, bSums = FALSE;
    static const char *eaver[] = { NULL, "z", "y", "x", NULL };
    static const char *eunit[] = { NULL, "nm-3", "nm-2", "count", NULL };

    t_pargs            pa[] = {
        {   "-bin", FALSE, etREAL, {&bin},
            "Grid size (nm)"
        },
        {   "-aver", FALSE, etENUM, {eaver},
            "The direction to average over"
        },
        {   "-xmin", FALSE, etREAL, {&xmin},
            "Minimum coordinate for averaging"
        },
        {   "-xmax", FALSE, etREAL, {&xmax},
            "Maximum coordinate for averaging"
        },
        {   "-n1", FALSE, etINT, {&n1},
            "Number of grid cells in the first direction"
        },
        {   "-n2", FALSE, etINT, {&n2},
            "Number of grid cells in the second direction"
        },
        {   "-amax", FALSE, etREAL, {&amax},
            "Maximum axial distance from the center"
        },
        {   "-rmax", FALSE, etREAL, {&rmax},
            "Maximum radial distance"
        },
        {   "-mirror", FALSE, etBOOL, {&bMirror},
            "Add the mirror image below the axial axis"
        },
        {   "-sums", FALSE, etBOOL, {&bSums},
            "Print density sums (1D map) to stdout"
        },
        {   "-unit", FALSE, etENUM, {eunit},
            "Unit for the output"
        },
        {   "-dmin", FALSE, etREAL, {&dmin},
            "Minimum density in output"
        },
        {   "-dmax", FALSE, etREAL, {&dmax},
            "Maximum density in output (0 means calculate it)"
        },
    };
    gmx_bool           bXmin, bXmax, bRadial;
    FILE              *fp;
    t_trxstatus       *status;
    t_topology         top;
    int                ePBC = -1;
    rvec              *x, xcom[2], direction, center, dx;
    matrix             box;
    real               t, m, mtot;
    t_pbc              pbc;
    int                cav = 0, c1 = 0, c2 = 0, natoms;
    char             **grpname, title[256], buf[STRLEN];
    const char        *unit;
    int                i, j, k, l, ngrps, anagrp, *gnx = NULL, nindex, nradial = 0, nfr, nmpower;
    atom_id          **ind = NULL, *index;
    real             **grid, maxgrid, m1, m2, box1, box2, *tickx, *tickz, invcellvol;
    real               invspa = 0, invspz = 0, axial, r, vol_old, vol, rowsum;
    int                nlev   = 51;
    t_rgb              rlo    = {1, 1, 1}, rhi = {0, 0, 0};
    output_env_t       oenv;
    const char        *label[] = { "x (nm)", "y (nm)", "z (nm)" };
    t_filenm           fnm[]   = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffOPTRD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-od",  "densmap",   ffOPTWR },
        { efXPM, "-o",   "densmap",   ffWRITE }
    };
#define NFILE asize(fnm)
    int                npargs;

    npargs = asize(pa);

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

    bXmin   = opt2parg_bSet("-xmin", npargs, pa);
    bXmax   = opt2parg_bSet("-xmax", npargs, pa);
    bRadial = (amax > 0 || rmax > 0);
    if (bRadial)
    {
        if (amax <= 0 || rmax <= 0)
        {
            gmx_fatal(FARGS, "Both amax and rmax should be larger than zero");
        }
    }

    if (strcmp(eunit[0], "nm-3") == 0)
    {
        nmpower = -3;
        unit    = "(nm^-3)";
    }
    else if (strcmp(eunit[0], "nm-2") == 0)
    {
        nmpower = -2;
        unit    = "(nm^-2)";
    }
    else
    {
        nmpower = 0;
        unit    = "count";
    }

    if (ftp2bSet(efTPS, NFILE, fnm) || !ftp2bSet(efNDX, NFILE, fnm))
    {
        read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &x, NULL, box,
                      bRadial);
    }
    if (!bRadial)
    {
        ngrps = 1;
        fprintf(stderr, "\nSelect an analysis group\n");
    }
    else
    {
        ngrps = 3;
        fprintf(stderr,
                "\nSelect two groups to define the axis and an analysis group\n");
    }
    snew(gnx, ngrps);
    snew(grpname, ngrps);
    snew(ind, ngrps);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), ngrps, gnx, ind, grpname);
    anagrp = ngrps - 1;
    nindex = gnx[anagrp];
    index  = ind[anagrp];
    if (bRadial)
    {
        if ((gnx[0] > 1 || gnx[1] > 1) && !ftp2bSet(efTPS, NFILE, fnm))
        {
            gmx_fatal(FARGS, "No run input file was supplied (option -s), this is required for the center of mass calculation");
        }
    }

    switch (eaver[0][0])
    {
    case 'x':
        cav = XX;
        c1 = YY;
        c2 = ZZ;
        break;
    case 'y':
        cav = YY;
        c1 = XX;
        c2 = ZZ;
        break;
    case 'z':
        cav = ZZ;
        c1 = XX;
        c2 = YY;
        break;
    }

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

    if (!bRadial)
    {
        if (n1 == 0)
        {
            n1 = (int)(box[c1][c1]/bin + 0.5);
        }
        if (n2 == 0)
        {
            n2 = (int)(box[c2][c2]/bin + 0.5);
        }
    }
    else
    {
        n1      = (int)(2*amax/bin + 0.5);
        nradial = (int)(rmax/bin + 0.5);
        invspa  = n1/(2*amax);
        invspz  = nradial/rmax;
        if (bMirror)
        {
            n2 = 2*nradial;
        }
        else
        {
            n2 = nradial;
        }
    }

    snew(grid, n1);
    for (i = 0; i < n1; i++)
    {
        snew(grid[i], n2);
    }

    box1 = 0;
    box2 = 0;
    nfr  = 0;
    do
    {
        if (!bRadial)
        {
            box1      += box[c1][c1];
            box2      += box[c2][c2];
            invcellvol = n1*n2;
            if (nmpower == -3)
            {
                invcellvol /= det(box);
            }
            else if (nmpower == -2)
            {
                invcellvol /= box[c1][c1]*box[c2][c2];
            }
            for (i = 0; i < nindex; i++)
            {
                j = index[i];
                if ((!bXmin || x[j][cav] >= xmin) &&
                        (!bXmax || x[j][cav] <= xmax))
                {
                    m1 = x[j][c1]/box[c1][c1];
                    if (m1 >= 1)
                    {
                        m1 -= 1;
                    }
                    if (m1 < 0)
                    {
                        m1 += 1;
                    }
                    m2 = x[j][c2]/box[c2][c2];
                    if (m2 >= 1)
                    {
                        m2 -= 1;
                    }
                    if (m2 < 0)
                    {
                        m2 += 1;
                    }
                    grid[(int)(m1*n1)][(int)(m2*n2)] += invcellvol;
                }
            }
        }
        else
        {
            set_pbc(&pbc, ePBC, box);
            for (i = 0; i < 2; i++)
            {
                if (gnx[i] == 1)
                {
                    /* One atom, just copy the coordinates */
                    copy_rvec(x[ind[i][0]], xcom[i]);
                }
                else
                {
                    /* Calculate the center of mass */
                    clear_rvec(xcom[i]);
                    mtot = 0;
                    for (j = 0; j < gnx[i]; j++)
                    {
                        k = ind[i][j];
                        m = top.atoms.atom[k].m;
                        for (l = 0; l < DIM; l++)
                        {
                            xcom[i][l] += m*x[k][l];
                        }
                        mtot += m;
                    }
                    svmul(1/mtot, xcom[i], xcom[i]);
                }
            }
            pbc_dx(&pbc, xcom[1], xcom[0], direction);
            for (i = 0; i < DIM; i++)
            {
                center[i] = xcom[0][i] + 0.5*direction[i];
            }
            unitv(direction, direction);
            for (i = 0; i < nindex; i++)
            {
                j = index[i];
                pbc_dx(&pbc, x[j], center, dx);
                axial = iprod(dx, direction);
                r     = sqrt(norm2(dx) - axial*axial);
                if (axial >= -amax && axial < amax && r < rmax)
                {
                    if (bMirror)
                    {
                        r += rmax;
                    }
                    grid[(int)((axial + amax)*invspa)][(int)(r*invspz)] += 1;
                }
            }
        }
        nfr++;
    }
    while (read_next_x(oenv, status, &t, natoms, x, box));
    close_trj(status);

    /* normalize gridpoints */
    maxgrid = 0;
    if (!bRadial)
    {
        for (i = 0; i < n1; i++)
        {
            for (j = 0; j < n2; j++)
            {
                grid[i][j] /= nfr;
                if (grid[i][j] > maxgrid)
                {
                    maxgrid = grid[i][j];
                }
            }
        }
    }
    else
    {
        for (i = 0; i < n1; i++)
        {
            vol_old = 0;
            for (j = 0; j < nradial; j++)
            {
                switch (nmpower)
                {
                case -3:
                    vol = M_PI*(j+1)*(j+1)/(invspz*invspz*invspa);
                    break;
                case -2:
                    vol =            (j+1)/(invspz*invspa);
                    break;
                default:
                    vol =             j+1;
                    break;
                }
                if (bMirror)
                {
                    k = j + nradial;
                }
                else
                {
                    k = j;
                }
                grid[i][k] /= nfr*(vol - vol_old);
                if (bMirror)
                {
                    grid[i][nradial-1-j] = grid[i][k];
                }
                vol_old = vol;
                if (grid[i][k] > maxgrid)
                {
                    maxgrid = grid[i][k];
                }
            }
        }
    }
    fprintf(stdout, "\n  The maximum density is %f %s\n", maxgrid, unit);
    if (dmax > 0)
    {
        maxgrid = dmax;
    }

    snew(tickx, n1+1);
    snew(tickz, n2+1);
    if (!bRadial)
    {
        /* normalize box-axes */
        box1 /= nfr;
        box2 /= nfr;
        for (i = 0; i <= n1; i++)
        {
            tickx[i] = i*box1/n1;
        }
        for (i = 0; i <= n2; i++)
        {
            tickz[i] = i*box2/n2;
        }
    }
    else
    {
        for (i = 0; i <= n1; i++)
        {
            tickx[i] = i/invspa - amax;
        }
        if (bMirror)
        {
            for (i = 0; i <= n2; i++)
            {
                tickz[i] = i/invspz - rmax;
            }
        }
        else
        {
            for (i = 0; i <= n2; i++)
            {
                tickz[i] = i/invspz;
            }
        }
    }

    if (bSums)
    {
        for (i = 0; i < n1; ++i)
        {
            fprintf(stdout, "Density sums:\n");
            rowsum = 0;
            for (j = 0; j < n2; ++j)
            {
                rowsum += grid[i][j];
            }
            fprintf(stdout, "%g\t", rowsum);
        }
        fprintf(stdout, "\n");
    }

    sprintf(buf, "%s number density", grpname[anagrp]);
    if (!bRadial && (bXmin || bXmax))
    {
        if (!bXmax)
        {
            sprintf(buf+strlen(buf), ", %c > %g nm", eaver[0][0], xmin);
        }
        else if (!bXmin)
        {
            sprintf(buf+strlen(buf), ", %c < %g nm", eaver[0][0], xmax);
        }
        else
        {
            sprintf(buf+strlen(buf), ", %c: %g - %g nm", eaver[0][0], xmin, xmax);
        }
    }
    if (ftp2bSet(efDAT, NFILE, fnm))
    {
        fp = ffopen(ftp2fn(efDAT, NFILE, fnm), "w");
        /*optional text form output:  first row is tickz; first col is tickx */
        fprintf(fp, "0\t");
        for (j = 0; j < n2; ++j)
        {
            fprintf(fp, "%g\t", tickz[j]);
        }
        fprintf(fp, "\n");

        for (i = 0; i < n1; ++i)
        {
            fprintf(fp, "%g\t", tickx[i]);
            for (j = 0; j < n2; ++j)
            {
                fprintf(fp, "%g\t", grid[i][j]);
            }
            fprintf(fp, "\n");
        }
        ffclose(fp);
    }
    else
    {
        fp = ffopen(ftp2fn(efXPM, NFILE, fnm), "w");
        write_xpm(fp, MAT_SPATIAL_X | MAT_SPATIAL_Y, buf, unit,
                  bRadial ? "axial (nm)" : label[c1], bRadial ? "r (nm)" : label[c2],
                  n1, n2, tickx, tickz, grid, dmin, maxgrid, rlo, rhi, &nlev);
        ffclose(fp);
    }

    thanx(stderr);

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

    return 0;
}
Exemple #2
0
int gmx_genpr(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] produces an #include file for a topology containing",
        "a list of atom numbers and three force constants for the",
        "[IT]x[it]-, [IT]y[it]-, and [IT]z[it]-direction based on",
        "the contents of the [TT]-f[tt] file. A single isotropic force constant may",
        "be given on the command line instead of three components.[PAR]",
        "WARNING: Position restraints are interactions within molecules, therefore",
        "they must be included within the correct [TT][ moleculetype ][tt]",
        "block in the topology. The atom indices within the",
        "[TT][ position_restraints ][tt] block must be within the range of the",
        "atom indices for that molecule type. Since the atom numbers in every",
        "moleculetype in the topology start at 1 and the numbers in the input file",
        "for [THISMODULE] number consecutively from 1, [THISMODULE] will only",
        "produce a useful file for the first molecule. You may wish to",
        "edit the resulting index file to remove the lines for later atoms,",
        "or construct a suitable index group to provide",
        "as input to [THISMODULE].[PAR]",
        "The [TT]-of[tt] option produces an index file that can be used for",
        "freezing atoms. In this case, the input file must be a [TT].pdb[tt] file.[PAR]",
        "With the [TT]-disre[tt] option, half a matrix of distance restraints",
        "is generated instead of position restraints. With this matrix, that",
        "one typically would apply to C[GRK]alpha[grk] atoms in a protein, one can",
        "maintain the overall conformation of a protein without tieing it to",
        "a specific position (as with position restraints)."
    };
    static rvec        fc           = {1000.0, 1000.0, 1000.0};
    static real        freeze_level = 0.0;
    static real        disre_dist   = 0.1;
    static real        disre_frac   = 0.0;
    static real        disre_up2    = 1.0;
    static gmx_bool    bDisre       = FALSE;
    static gmx_bool    bConstr      = FALSE;
    static real        cutoff       = -1.0;

    t_pargs            pa[] = {
        { "-fc", FALSE, etRVEC, {fc},
          "Force constants (kJ/mol nm^2)" },
        { "-freeze", FALSE, etREAL, {&freeze_level},
          "If the [TT]-of[tt] option or this one is given an index file will be written containing atom numbers of all atoms that have a B-factor less than the level given here" },
        { "-disre", FALSE, etBOOL, {&bDisre},
          "Generate a distance restraint matrix for all the atoms in index" },
        { "-disre_dist", FALSE, etREAL, {&disre_dist},
          "Distance range around the actual distance for generating distance restraints" },
        { "-disre_frac", FALSE, etREAL, {&disre_frac},
          "Fraction of distance to be used as interval rather than a fixed distance. If the fraction of the distance that you specify here is less than the distance given in the previous option, that one is used instead." },
        { "-disre_up2", FALSE, etREAL, {&disre_up2},
          "Distance between upper bound for distance restraints, and the distance at which the force becomes constant (see manual)" },
        { "-cutoff", FALSE, etREAL, {&cutoff},
          "Only generate distance restraints for atoms pairs within cutoff (nm)" },
        { "-constr", FALSE, etBOOL, {&bConstr},
          "Generate a constraint matrix rather than distance restraints. Constraints of type 2 will be generated that do generate exclusions." }
    };
#define npargs asize(pa)

    output_env_t     oenv;
    t_atoms         *atoms = NULL;
    int              i, j, k;
    FILE            *out;
    int              igrp;
    real             d, dd, lo, hi;
    atom_id         *ind_grp;
    const char      *xfn, *nfn;
    char            *gn_grp;
    char             title[STRLEN];
    matrix           box;
    gmx_bool         bFreeze;
    rvec             dx, *x = NULL, *v = NULL;

    t_filenm         fnm[] = {
        { efSTX, "-f",  NULL,    ffREAD },
        { efNDX, "-n",  NULL,    ffOPTRD },
        { efITP, "-o",  "posre", ffWRITE },
        { efNDX, "-of", "freeze",    ffOPTWR }
    };
#define NFILE asize(fnm)

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

    bFreeze = opt2bSet("-of", NFILE, fnm) || opt2parg_bSet("-freeze", asize(pa), pa);
    bDisre  = bDisre || opt2parg_bSet("-disre_dist", npargs, pa);
    xfn     = opt2fn_null("-f", NFILE, fnm);
    nfn     = opt2fn_null("-n", NFILE, fnm);

    if (( nfn == NULL ) && ( xfn == NULL))
    {
        gmx_fatal(FARGS, "no index file and no structure file supplied");
    }

    if ((disre_frac < 0) || (disre_frac >= 1))
    {
        gmx_fatal(FARGS, "disre_frac should be between 0 and 1");
    }
    if (disre_dist < 0)
    {
        gmx_fatal(FARGS, "disre_dist should be >= 0");
    }

    if (xfn != NULL)
    {
        snew(atoms, 1);
        get_stx_coordnum(xfn, &(atoms->nr));
        init_t_atoms(atoms, atoms->nr, TRUE);
        snew(x, atoms->nr);
        snew(v, atoms->nr);
        fprintf(stderr, "\nReading structure file\n");
        read_stx_conf(xfn, title, atoms, x, v, NULL, box);
    }

    if (bFreeze)
    {
        if (!atoms || !atoms->pdbinfo)
        {
            gmx_fatal(FARGS, "No B-factors in input file %s, use a pdb file next time.",
                      xfn);
        }

        out = opt2FILE("-of", NFILE, fnm, "w");
        fprintf(out, "[ freeze ]\n");
        for (i = 0; (i < atoms->nr); i++)
        {
            if (atoms->pdbinfo[i].bfac <= freeze_level)
            {
                fprintf(out, "%d\n", i+1);
            }
        }
        gmx_ffclose(out);
    }
    else if ((bDisre || bConstr) && x)
    {
        printf("Select group to generate %s matrix from\n",
               bConstr ? "constraint" : "distance restraint");
        get_index(atoms, nfn, 1, &igrp, &ind_grp, &gn_grp);

        out = ftp2FILE(efITP, NFILE, fnm, "w");
        if (bConstr)
        {
            fprintf(out, "; constraints for %s of %s\n\n", gn_grp, title);
            fprintf(out, "[ constraints ]\n");
            fprintf(out, ";%4s %5s %1s %10s\n", "i", "j", "tp", "dist");
        }
        else
        {
            fprintf(out, "; distance restraints for %s of %s\n\n", gn_grp, title);
            fprintf(out, "[ distance_restraints ]\n");
            fprintf(out, ";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n", "i", "j", "?",
                    "label", "funct", "lo", "up1", "up2", "weight");
        }
        for (i = k = 0; i < igrp; i++)
        {
            for (j = i+1; j < igrp; j++, k++)
            {
                rvec_sub(x[ind_grp[i]], x[ind_grp[j]], dx);
                d = norm(dx);
                if (bConstr)
                {
                    fprintf(out, "%5d %5d %1d %10g\n", ind_grp[i]+1, ind_grp[j]+1, 2, d);
                }
                else
                {
                    if (cutoff < 0 || d < cutoff)
                    {
                        if (disre_frac > 0)
                        {
                            dd = min(disre_dist, disre_frac*d);
                        }
                        else
                        {
                            dd = disre_dist;
                        }
                        lo = max(0, d-dd);
                        hi = d+dd;
                        fprintf(out, "%5d %5d %1d %5d %10d %10g %10g %10g %10g\n",
                                ind_grp[i]+1, ind_grp[j]+1, 1, k, 1,
                                lo, hi, hi+1, 1.0);
                    }
                }
            }
        }
        gmx_ffclose(out);
    }
    else
    {
        printf("Select group to position restrain\n");
        get_index(atoms, nfn, 1, &igrp, &ind_grp, &gn_grp);

        out = ftp2FILE(efITP, NFILE, fnm, "w");
        fprintf(out, "; position restraints for %s of %s\n\n", gn_grp, title);
        fprintf(out, "[ position_restraints ]\n");
        fprintf(out, ";%3s %5s %9s %10s %10s\n", "i", "funct", "fcx", "fcy", "fcz");
        for (i = 0; i < igrp; i++)
        {
            fprintf(out, "%4d %4d %10g %10g %10g\n",
                    ind_grp[i]+1, 1, fc[XX], fc[YY], fc[ZZ]);
        }
        gmx_ffclose(out);
    }
    if (xfn)
    {
        sfree(x);
        sfree(v);
    }

    return 0;
}
Exemple #3
0
static int _while_exec(struct ast_channel *chan, const char *data, int end)
{
	int res=0;
	const char *while_pri = NULL;
	char *my_name = NULL;
	const char *condition = NULL, *label = NULL;
	char varname[VAR_SIZE], end_varname[VAR_SIZE];
	const char *prefix = "WHILE";
	size_t size=0;
	int used_index_i = -1, x=0;
	char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0";

	if (!chan) {
		/* huh ? */
		return -1;
	}

#if 0
	/* don't want run away loops if the chan isn't even up
	   this is up for debate since it slows things down a tad ......

	   Debate is over... this prevents While/EndWhile from working
	   within the "h" extension.  Not good.
	*/
	if (ast_waitfordigit(chan,1) < 0)
		return -1;
#endif

	for (x=0;;x++) {
		if (get_index(chan, prefix, x)) {
			used_index_i = x;
		} else 
			break;
	}
	
	snprintf(used_index, VAR_SIZE, "%d", used_index_i);
	snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1);
	
	if (!end)
		condition = ast_strdupa(data);

	size = strlen(chan->context) + strlen(chan->exten) + 32;
	my_name = alloca(size);
	memset(my_name, 0, size);
	snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority);
	
	ast_channel_lock(chan);
	if (end) {
		label = used_index;
	} else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) {
		label = new_index;
		pbx_builtin_setvar_helper(chan, my_name, label);
	}
	snprintf(varname, VAR_SIZE, "%s_%s", prefix, label);
	if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) {
		while_pri = ast_strdupa(while_pri);
		snprintf(end_varname,VAR_SIZE,"END_%s",varname);
	}
	ast_channel_unlock(chan);
	

	if ((!end && !pbx_checkcondition(condition)) || (end == 2)) {
		/* Condition Met (clean up helper vars) */
		const char *goto_str;
		pbx_builtin_setvar_helper(chan, varname, NULL);
		pbx_builtin_setvar_helper(chan, my_name, NULL);
		snprintf(end_varname,VAR_SIZE,"END_%s",varname);
		ast_channel_lock(chan);
		if ((goto_str = pbx_builtin_getvar_helper(chan, end_varname))) {
			ast_parseable_goto(chan, goto_str);
			pbx_builtin_setvar_helper(chan, end_varname, NULL);
		} else {
			int pri = find_matching_endwhile(chan);
			if (pri > 0) {
				ast_verb(3, "Jumping to priority %d\n", pri);
				chan->priority = pri;
			} else {
				ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority);
			}
		}
		ast_channel_unlock(chan);
		return res;
	}

	if (!end && !while_pri) {
		char *goto_str;
		size = strlen(chan->context) + strlen(chan->exten) + 32;
		goto_str = alloca(size);
		memset(goto_str, 0, size);
		snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority);
		pbx_builtin_setvar_helper(chan, varname, goto_str);
	}

	else if (end && while_pri) {
		/* END of loop */
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
		if (! pbx_builtin_getvar_helper(chan, end_varname)) {
			char *goto_str;
			size = strlen(chan->context) + strlen(chan->exten) + 32;
			goto_str = alloca(size);
			memset(goto_str, 0, size);
			snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1);
			pbx_builtin_setvar_helper(chan, end_varname, goto_str);
		}
		ast_parseable_goto(chan, while_pri);
	}

	return res;
}
Exemple #4
0
/*
 * Decode a "percent" prototype character.
 * A prototype string may include various "percent" escapes;
 * that is, a percent sign followed by a single letter.
 * Here we decode that letter and take the appropriate action,
 * usually by appending something to the message being built.
 */
static void
protochar(int c, int where)
{
	off_t pos;
	off_t len;
	int n;
	off_t linenum;
	off_t last_linenum;
	IFILE h;

#undef	PAGE_NUM
#define	PAGE_NUM(linenum)  ((((linenum) - 1) / (sc_height - 1)) + 1)

	switch (c) {
	case 'b':	/* Current byte offset */
		pos = curr_byte(where);
		if (pos != -1)
			ap_pos(pos);
		else
			ap_quest();
		break;
	case 'c':
		ap_int(hshift);
		break;
	case 'd':	/* Current page number */
		linenum = currline(where);
		if (linenum > 0 && sc_height > 1)
			ap_pos(PAGE_NUM(linenum));
		else
			ap_quest();
		break;
	case 'D':	/* Final page number */
		/* Find the page number of the last byte in the file (len-1). */
		len = ch_length();
		if (len == -1) {
			ap_quest();
		} else if (len == 0) {
			/* An empty file has no pages. */
			ap_pos(0);
		} else {
			linenum = find_linenum(len - 1);
			if (linenum <= 0)
				ap_quest();
			else
				ap_pos(PAGE_NUM(linenum));
		}
		break;
	case 'E':	/* Editor name */
		ap_str(editor);
		break;
	case 'f':	/* File name */
		ap_str(get_filename(curr_ifile));
		break;
	case 'F':	/* Last component of file name */
		ap_str(last_component(get_filename(curr_ifile)));
		break;
	case 'i':	/* Index into list of files */
		if (ntags())
			ap_int(curr_tag());
		else
			ap_int(get_index(curr_ifile));
		break;
	case 'l':	/* Current line number */
		linenum = currline(where);
		if (linenum != 0)
			ap_pos(linenum);
		else
			ap_quest();
		break;
	case 'L':	/* Final line number */
		len = ch_length();
		if (len == -1 || len == ch_zero() ||
		    (linenum = find_linenum(len)) <= 0)
			ap_quest();
		else
			ap_pos(linenum-1);
		break;
	case 'm':	/* Number of files */
		n = ntags();
		if (n)
			ap_int(n);
		else
			ap_int(nifile());
		break;
	case 'p':	/* Percent into file (bytes) */
		pos = curr_byte(where);
		len = ch_length();
		if (pos != -1 && len > 0)
			ap_int(percentage(pos, len));
		else
			ap_quest();
		break;
	case 'P':	/* Percent into file (lines) */
		linenum = currline(where);
		if (linenum == 0 ||
		    (len = ch_length()) == -1 || len == ch_zero() ||
		    (last_linenum = find_linenum(len)) <= 0)
			ap_quest();
		else
			ap_int(percentage(linenum, last_linenum));
		break;
	case 's':	/* Size of file */
	case 'B':
		len = ch_length();
		if (len != -1)
			ap_pos(len);
		else
			ap_quest();
		break;
	case 't':	/* Truncate trailing spaces in the message */
		while (mp > message && mp[-1] == ' ')
			mp--;
		*mp = '\0';
		break;
	case 'T':	/* Type of list */
		if (ntags())
			ap_str("tag");
		else
			ap_str("file");
		break;
	case 'x':	/* Name of next file */
		h = next_ifile(curr_ifile);
		if (h != NULL)
			ap_str(get_filename(h));
		else
			ap_quest();
		break;
	}
}
Exemple #5
0
int main(int argc,char *argv[])
{
  const char *desc[] = {
    "do_dssp ", 
    "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. do_dssp assumes that the dssp executable is",
    "/usr/local/bin/dssp. If this is not the case, then you should",
    "set an environment variable [BB]DSSP[bb] pointing to the dssp",
    "executable, e.g.: [PAR]",
    "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][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 xpm 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 [TT]g_sas[tt] 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 [TT]g_chi[tt]. Together",
    "these two programs can be used to analyze dihedral properties as a",
    "function of secondary structure type."
  };
  static bool bVerbose;
  static const char *ss_string="HEBT"; 
  t_pargs pa[] = {
    { "-v",  FALSE, etBOOL, {&bVerbose},
      "HIDDENGenerate miles of useless information" },
    { "-sss", FALSE, etSTR, {&ss_string},
      "Secondary structures for structure count"}
  };
  
  int        status;
  FILE       *tapein;
  FILE       *ss,*acc,*fTArea,*tmpf;
  char       *fnSCount,*fnArea,*fnTArea,*fnAArea;
  char *leg[] = { "Phobic", "Phylic" };
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;
  t_matrix   mat;
  int        nres,nr0,naccr,nres_plus_separators;
  bool       *bPhbres,bDoAccSurf;
  real       t;
  int        i,natoms,nframe=0;
  matrix     box;
  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;
  
  
  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)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT | PCA_BE_NICE ,
		    NFILE,fnm, asize(pa),pa, asize(desc),desc,0,NULL);
  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);
  sprintf(dssp,"%s %s %s %s > /dev/null %s",
	  dptr,bDoAccSurf?"":"-na",pdbfile,tmpfile,bVerbose?"":"2> /dev/null");
  if (bVerbose)
    fprintf(stderr,"dssp cmd='%s'\n",dssp);
  
  if (fnTArea) {
    fTArea=xvgropen(fnTArea,"Solvent Accessible Surface Area",
		    xvgr_tlabel(),"Area (nm\\S2\\N)");
    xvgr_legend(fTArea,2,leg);
  } else
    fTArea=NULL;
  
  mat.map=NULL;
  mat.nmap=getcmap(libopen(opt2fn("-map",NFILE,fnm)),
		   opt2fn("-map",NFILE,fnm),&(mat.map));
  
  natoms=read_first_x(&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;
  do {
    t = convert_time(t);
    if (bDoAccSurf && nframe>=naccr) {
      naccr+=10;
      srenew(accr,naccr);
      for(i=naccr-10; i<naccr; i++)
        snew(accr[i],2*atoms->nres-1);
    }
    rm_pbc(&(top.idef),ePBC,natoms,box,x,x);
    tapein=ffopen(pdbfile,"w");
    write_pdbfile_indexed(tapein,NULL,atoms,x,ePBC,box,0,-1,gnx,index,NULL);
    fclose(tapein);

#ifdef GMX_NO_SYSTEM
    printf("Warning-- No calls to system(3) supported on this platform.");
    printf("Warning-- Skipping execution of 'system(\"%s\")'.", dssp);
    exit(1);
#else
    if(0 != system(dssp))
    {
	gmx_fatal(FARGS,"Failed to execute command: %s",dssp);
    }
#endif

    /* 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);
    remove(tmpfile);
    remove(pdbfile);
    nframe++;
  } while(read_next_x(status,&t,natoms,x,box));
  fprintf(stderr,"\n");
  close_trj(status);
  if (fTArea)
    ffclose(fTArea);
  
  prune_ss_legend(&mat);
  
  ss=opt2FILE("-o",NFILE,fnm,"w");
  mat.flags = 0;  
  write_xpm_m(ss,mat);
  ffclose(ss);
  
  if (opt2bSet("-ssdump",NFILE,fnm)) {
    snew(ss_str,nres+1);
    for(i=0; (i<nres); i++)
      ss_str[i] = mat.map[mat.matrix[0][i]].code.c1;
    ss_str[i] = '\0';
    ss = opt2FILE("-ssdump",NFILE,fnm,"w");
    fprintf(ss,"%d\n%s\n",nres,ss_str);
    fclose(ss);
    sfree(ss_str);
  }
  analyse_ss(fnSCount,&mat,ss_string);

  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");
      for(i=0; (i<nres); i++)
	fprintf(acc,"%5d  %10g %10g\n",i+1,av_area[i], norm_av_area[i]);
      ffclose(acc);
    }
  }

  view_all(NFILE, fnm);

  thanx(stderr);
  
  return 0;
}
int gmx_traj(int argc,char *argv[])
{
  static char *desc[] = {
    "g_traj plots coordinates, velocities, forces and/or the box.",
    "With [TT]-com[tt] the coordinates, velocities and forces are",
    "calculated for the center of mass of each group.",
    "When [TT]-mol[tt] is set, the numbers in the index file are",
    "interpreted as molecule numbers and the same procedure as with",
    "[TT]-com[tt] is used for each molecule.[PAR]",
    "Option [TT]-ot[tt] plots the temperature of each group,",
    "provided velocities are present in the trajectory file.",
    "No corrections are made for constrained degrees of freedom!",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and",
    "rotational kinetic energy of each group,", 
    "provided velocities are present in the trajectory file.",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities",
    "and average forces as temperature factors to a pdb file with",
    "the average coordinates. The temperature factors are scaled such",
    "that the maximum is 10. The scaling can be changed with the option",
    "[TT]-scale[tt]. To get the velocities or forces of one",
    "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of",
    "desired frame. When averaging over frames you might need to use",
    "the [TT]-nojump[tt] option to obtain the correct average coordinates.",
    "If you select either of these option the average force and velocity",
    "for each atom are written to an xvg file as well",
    "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]",
    "Option [TT]-vd[tt] computes a velocity distribution, i.e. the",
    "norm of the vector is plotted. In addition in the same graph",
    "the kinetic energy distribution is given."
  };
  static bool bMol=FALSE,bCom=FALSE,bNoJump=FALSE;
  static bool bX=TRUE,bY=TRUE,bZ=TRUE,bNorm=FALSE;
  static int  ngroups=1;
  static real scale=0,binwidth=1;
  t_pargs pa[] = {
    { "-com", FALSE, etBOOL, {&bCom},
      "Plot data for the com of each group" },
    { "-mol", FALSE, etBOOL, {&bMol},
      "Index contains molecule numbers iso atom numbers" },
    { "-nojump", FALSE, etBOOL, {&bNoJump},
      "Remove jumps of atoms across the box" },
    { "-x", FALSE, etBOOL, {&bX},
      "Plot X-component" },
    { "-y", FALSE, etBOOL, {&bY},
      "Plot Y-component" },
    { "-z", FALSE, etBOOL, {&bZ},
      "Plot Z-component" },
    { "-ng",       FALSE, etINT, {&ngroups},
      "Number of groups to consider" },
    { "-len", FALSE, etBOOL, {&bNorm},
      "Plot vector length" },
    { "-bin", FALSE, etREAL, {&binwidth},
      "Binwidth for velocity histogram (nm/ps)" },
    { "-scale", FALSE, etREAL, {&scale},
      "Scale factor for pdb output, 0 is autoscale" }
    
  };
  FILE       *outx=NULL,*outv=NULL,*outf=NULL,*outb=NULL,*outt=NULL;
  FILE       *outekt=NULL,*outekr=NULL;
  t_topology top;
  int        ePBC;
  real       *mass,time;
  char       title[STRLEN],*indexfn;
  t_trxframe fr,frout;
  int        flags,nvhisto=0,*vhisto=NULL;
  rvec       *xtop,*xp=NULL;
  rvec       *sumxv=NULL,*sumv=NULL,*sumxf=NULL,*sumf=NULL;
  matrix     topbox;
  int        status,status_out=-1;
  int        i,j,n;
  int        nr_xfr,nr_vfr,nr_ffr;
  char       **grpname;
  int        *isize0,*isize;
  atom_id    **index0,**index;
  atom_id    *atndx;
  t_block    *mols;
  bool       bTop,bOX,bOXT,bOV,bOF,bOB,bOT,bEKT,bEKR,bCV,bCF;
  bool       bDim[4],bDum[4],bVD;
  char       *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" };

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPS, NULL, NULL, ffREAD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ox", "coord.xvg", ffOPTWR },
    { efTRX, "-oxt","coord.xtc", ffOPTWR },
    { efXVG, "-ov", "veloc.xvg", ffOPTWR },
    { efXVG, "-of", "force.xvg", ffOPTWR },
    { efXVG, "-ob", "box.xvg",   ffOPTWR },
    { efXVG, "-ot", "temp.xvg",  ffOPTWR },
    { efXVG, "-ekt","ektrans.xvg", ffOPTWR },
    { efXVG, "-ekr","ekrot.xvg", ffOPTWR },
    { efXVG, "-vd", "veldist.xvg", ffOPTWR },
    { efPDB, "-cv", "veloc.pdb", ffOPTWR },
    { efPDB, "-cf", "force.pdb", ffOPTWR },
    { efXVG, "-av", "all_veloc.xvg", ffOPTWR },
    { efXVG, "-af", "all_force.xvg", ffOPTWR }
  };
#define NFILE asize(fnm)

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

  if (bMol)
    fprintf(stderr,"Interpreting indexfile entries as molecules.\n"
	    "Using center of mass.\n");
  
  bOX  = opt2bSet("-ox",NFILE,fnm);
  bOXT = opt2bSet("-oxt",NFILE,fnm);
  bOV  = opt2bSet("-ov",NFILE,fnm);
  bOF  = opt2bSet("-of",NFILE,fnm);
  bOB  = opt2bSet("-ob",NFILE,fnm);
  bOT  = opt2bSet("-ot",NFILE,fnm);
  bEKT = opt2bSet("-ekt",NFILE,fnm);
  bEKR = opt2bSet("-ekr",NFILE,fnm);
  bCV  = opt2bSet("-cv",NFILE,fnm) || opt2bSet("-av",NFILE,fnm);
  bCF  = opt2bSet("-cf",NFILE,fnm) || opt2bSet("-af",NFILE,fnm);
  bVD  = opt2bSet("-vd",NFILE,fnm) || opt2parg_bSet("-bin",asize(pa),pa);
  if (bMol || bOT || bEKT || bEKR)
    bCom = TRUE;

  bDim[XX] = bX;
  bDim[YY] = bY;
  bDim[ZZ] = bZ;
  bDim[DIM] = bNorm;

  bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,
		       bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR));
  sfree(xtop);
  if ((bMol || bCV || bCF) && !bTop)
    gmx_fatal(FARGS,"Need a run input file for option -mol, -cv or -cf");

  if (bMol)
    indexfn = ftp2fn(efNDX,NFILE,fnm);
  else
    indexfn = ftp2fn_null(efNDX,NFILE,fnm);

  if (!(bCom && !bMol))
    ngroups = 1;
  snew(grpname,ngroups);
  snew(isize0,ngroups);
  snew(index0,ngroups);
  get_index(&(top.atoms),indexfn,ngroups,isize0,index0,grpname);
  
  if (bMol) {
    mols=&(top.mols);
    atndx = mols->index;
    ngroups = isize0[0];
    snew(isize,ngroups);
    snew(index,ngroups);
    for (i=0; i<ngroups; i++) {
      if (index0[0][i] < 0 || index0[0][i] >= mols->nr)
	gmx_fatal(FARGS,"Molecule index (%d) is out of range (%d-%d)",
		  index0[0][i]+1,1,mols->nr);
      isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]];
      snew(index[i],isize[i]);
      for(j=0; j<isize[i]; j++)
	index[i][j] = atndx[index0[0][i]] + j;
    }
  } else {
    isize = isize0;
    index = index0;
  }
  if (bCom) {
    snew(mass,top.atoms.nr);
    for(i=0; i<top.atoms.nr; i++)
      mass[i] = top.atoms.atom[i].m;
  } else
    mass = NULL;

  flags = 0;
  if (bOX) {
    flags = flags | TRX_READ_X;
    outx = xvgropen(opt2fn("-ox",NFILE,fnm),
		    bCom ? "Center of mass" : "Coordinate",
		    xvgr_tlabel(),"Coordinate (nm)");
    make_legend(outx,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOXT) {
    flags = flags | TRX_READ_X;
    status_out = open_trx(opt2fn("-oxt",NFILE,fnm),"w");
  }
  if (bOV) {
    flags = flags | TRX_READ_V;
    outv = xvgropen(opt2fn("-ov",NFILE,fnm),
		    bCom ? "Center of mass velocity" : "Velocity",
		    xvgr_tlabel(),"Velocity (nm/ps)");
   make_legend(outv,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); 
  }
  if (bOF) {
    flags = flags | TRX_READ_F;
    outf = xvgropen(opt2fn("-of",NFILE,fnm),"Force",
		    xvgr_tlabel(),"Force (kJ mol\\S-1\\N nm\\S-1\\N)");
    make_legend(outf,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOB) {
    outb = xvgropen(opt2fn("-ob",NFILE,fnm),"Box vector elements",
		    xvgr_tlabel(),"(nm)");
   
    xvgr_legend(outb,6,box_leg);
  }
  if (bOT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outt = xvgropen(opt2fn("-ot",NFILE,fnm),"Temperature",xvgr_tlabel(),"(K)");
    make_legend(outt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outekt = xvgropen(opt2fn("-ekt",NFILE,fnm),"Center of mass translation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKR) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_X | TRX_READ_V;
    outekr = xvgropen(opt2fn("-ekr",NFILE,fnm),"Center of mass rotation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekr,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bVD)
    flags = flags | TRX_READ_V;
  if (bCV)
    flags = flags | TRX_READ_X | TRX_READ_V;
  if (bCF)
    flags = flags | TRX_READ_X | TRX_READ_F;
  if ((flags == 0) && !bOB) {
    fprintf(stderr,"Please select one or more output file options\n");
    exit(0);
  }

  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags);

  if (bCV) {
    snew(sumxv,fr.natoms);
    snew(sumv,fr.natoms);
  }
  if (bCF) {
    snew(sumxf,fr.natoms);
    snew(sumf,fr.natoms);
  }
  nr_xfr = 0;
  nr_vfr = 0;
  nr_ffr = 0;
  
  do {
    time = convert_time(fr.time);

    if (fr.bX && bNoJump && fr.bBox) {
      if (xp)
	remove_jump(fr.box,fr.natoms,xp,fr.x);
      else 
	snew(xp,fr.natoms);
      for(i=0; i<fr.natoms; i++)
	copy_rvec(fr.x[i],xp[i]);
    }
    
    if (fr.bX && bCom)
      rm_pbc(&(top.idef),ePBC,fr.natoms,fr.box,fr.x,fr.x);

    if (bVD && fr.bV) 
      update_histo(isize[0],index[0],fr.v,&nvhisto,&vhisto,binwidth);
      
    if (bOX && fr.bX)
      print_data(outx,time,fr.x,mass,bCom,ngroups,isize,index,bDim);
    if (bOXT && fr.bX) {
      frout = fr;
      if (!frout.bAtoms) {
	frout.atoms  = &top.atoms;
	frout.bAtoms = TRUE;
      }
      write_trx_x(status_out,&frout,mass,bCom,ngroups,isize,index);
    }
    if (bOV && fr.bV)
      print_data(outv,time,fr.v,mass,bCom,ngroups,isize,index,bDim);
    if (bOF && fr.bF)
      print_data(outf,time,fr.f,NULL,bCom,ngroups,isize,index,bDim);
    if (bOB && fr.bBox)
      fprintf(outb,"\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",fr.time,
	      fr.box[XX][XX],fr.box[YY][YY],fr.box[ZZ][ZZ],
	      fr.box[YY][XX],fr.box[ZZ][XX],fr.box[ZZ][YY]);
    if (bOT && fr.bV) {
      fprintf(outt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outt,"\t%g",temp(fr.v,mass,isize[i],index[i]));
      fprintf(outt,"\n");
    }
    if (bEKT && fr.bV) {
      fprintf(outekt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekt,"\t%g",ektrans(fr.v,mass,isize[i],index[i]));
      fprintf(outekt,"\n");
    }
    if (bEKR && fr.bX && fr.bV) {
      fprintf(outekr," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekr,"\t%g",ekrot(fr.x,fr.v,mass,isize[i],index[i]));
      fprintf(outekr,"\n");
    }
    if (bCV) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxv[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bV) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumv[i],fr.v[i]);
	nr_vfr++;
      }
    }
    if (bCF) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxf[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bF) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumf[i],fr.f[i]);
	nr_ffr++;
      }
    }
    
  } while(read_next_frame(status,&fr));
  

  /* clean up a bit */
  close_trj(status);
  
  if (bOX) fclose(outx);
  if (bOXT) close_trx(status_out);
  if (bOV) fclose(outv);
  if (bOF) fclose(outf);
  if (bOB) fclose(outb);
  if (bOT) fclose(outt);
  if (bEKT) fclose(outekt);
  if (bEKR) fclose(outekr);

  if (bVD)
    print_histo(opt2fn("-vd",NFILE,fnm),nvhisto,vhisto,binwidth);
    
  if ((bCV || bCF) && (nr_vfr>1 || nr_ffr>1) && !bNoJump)
    fprintf(stderr,"WARNING: More than one frame was used for option -cv or -cf\n"
	    "If atoms jump across the box you should use the -nojump option\n");

  if (bCV)
    write_pdb_bfac(opt2fn("-cv",NFILE,fnm),
		   opt2fn("-av",NFILE,fnm),"average velocity",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxv,
		   nr_vfr,sumv,bDim,scale);
  if (bCF)
    write_pdb_bfac(opt2fn("-cf",NFILE,fnm),
		   opt2fn("-af",NFILE,fnm),"average force",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxf,
		   nr_ffr,sumf,bDim,scale);

  /* view it */
  view_all(NFILE, fnm);
  
  thanx(stderr);
  
  return 0;
}
Exemple #7
0
static void parse_dive_visibility(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->visibility = get_index(line); }
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;
    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 | PCA_BE_NICE,
                           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 = getcmap(libopen(opt2fn("-map", NFILE, fnm)),
                       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);

#ifdef GMX_NO_SYSTEM
        printf("Warning-- No calls to system(3) supported on this platform.");
        printf("Warning-- Skipping execution of 'system(\"%s\")'.", dssp);
        exit(1);
#else
        if (0 != system(dssp))
        {
            gmx_fatal(FARGS, "Failed to execute command: %s\n",
                      "Try specifying your dssp version with the -ver option.", dssp);
        }
#endif

        /* 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)
    {
        gmx_ffclose(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]);
            }
            gmx_ffclose(acc);
        }
    }

    view_all(oenv, NFILE, fnm);

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

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

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

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

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

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


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

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

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

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

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

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

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

        set_pbc(&pbc, ePBC, box);


        if (seed == 0)
        {
            // For now we make do with 32 bits to avoid changing the user input to 64 bit hex
            seed = static_cast<int>(gmx::makeRandomSeed());
        }
        fprintf(stderr, "Using random seed %d.\n", seed);

        gmx::DefaultRandomEngine rng(seed);

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

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

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

    return 0;
}
Exemple #10
0
int gmx_tilt(int argc, char *argv[])
{
    const char      *desc[] = {
        "\tLook at the tilt angle of RalGDS when docked to different\n",
        "GTPases: p21Ras (1LFD.pdb) and Rap1a (1GUA.pdb).",
        "\tUse -s for the simulated molecule topology.  Use -fr for\n",
        "the reference molecule topology.\n",
        "\n",
        "Workflow:\n",
        "\t1) VMD STAMP Structural alignment of reference structure to\n",
        "\t   1LFD.pdb chain B (Ras).\n",
        "\t2) Make a .tpr of the reference structure (which has already\n",
        "\t   been aligned to 1LFD.pdb, per step 1)\n"
        "\t3) Kabsch alignment of a single frame of the simulation\n",
        "\t   trajectory to the GTPase of the reference structure.\n",
        "\t4) Use trjconv to align the GTPase of the simulated trajectory\n",
        "\t    to the (aligned) frame from step 3.\n",
        "\t5) Run this code.\n",
    };

    gmx_bool        bVerbose = FALSE;
    const char      *struct_file, *traj_file;
    const char      *ndx_file, *xvg_file;
    const char      *ref_file;
    t_tiltdata  data;
    t_pargs         pa[] = {
        { "-v", FALSE, etBOOL, {&bVerbose},
          "Be slightly more verbose"},
    };
    t_filenm        fnm[] = {
        {efTPS, NULL, NULL, ffREAD},
        {efTRX, NULL, NULL, ffREAD},
        //{efGRO, "-fr", NULL, ffREAD},
        {efTPS, "-fr", NULL, ffREAD},
        {efXVG, "-o","tilt",ffOPTWR},
        {efNDX, NULL, NULL, ffREAD},
    };
#define NFILE asize(fnm)
#define NPA asize(pa)
    output_env_t    oenv;
    int             ngrps, nrefgrps;
    t_topology      struct_top, ref_top;
    t_atoms         *struct_atoms=NULL, *ref_atoms=NULL;
    t_trxframe      struct_fr, ref_fr;
    t_trxstatus     *struct_status, *ref_status;
    rvec            *struct_xtop, *ref_xtop;
    matrix          struct_box, ref_box;
    int             struct_ePBC, ref_ePBC;
    int             struct_flags=TRX_READ_X, ref_flags=TRX_READ_X;
    char            buffer[1024];

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

    /* Get inputs */
    struct_file = ftp2fn(efTPS, NFILE, fnm);
    traj_file   = opt2fn( "-f", NFILE, fnm);
    ref_file    = opt2fn("-fr", NFILE, fnm); 
    ndx_file    = ftp2fn(efNDX, NFILE, fnm);
    
    /* Open inputs */
    read_tps_conf(struct_file, buffer, &struct_top, &struct_ePBC,
                  &struct_xtop, NULL, struct_box, TRUE);
    sfree(struct_xtop);
    struct_atoms = &struct_top.atoms;

    read_tps_conf(ref_file, buffer, &ref_top, &ref_ePBC,
                  &ref_xtop, NULL, ref_box, TRUE);
    ref_atoms = &ref_top.atoms;

    /* open xvg file */
    data.fp = NULL;
    data.fp = xvgropen(opt2fn("-o", NFILE, fnm), "Center of Mass displacement","Time[ps]","Tilt Angle[degrees]", oenv);
    const char *flegend[] = {
                              "Time[ps]",
                              "tilt[deg]",
                              "rmsd[nm]",
                              "CoM displacement[nm]",
                              "Rotation axis x-component[nm]",
                              "Rotation axis y-component[nm]",
                              "Rotation axis z-component[nm]",
                              "X-axis rotation[deg]",
                              "Y-axis rotation[deg]",
                              "Z-axis rotation[deg]",
                            };
    xvgr_legend(data.fp,asize(flegend),flegend,oenv);

    /* Get index information */
    static int      n_structatoms, n_refatoms;
    atom_id         *ind_structatoms, *ind_refatoms;
    char            *gn_structatoms, *gn_refatoms;
    int             i_structatoms, i_refatoms;
    std::cout<< "\nSelect group from reference structure <" << ref_file << ">." << std::endl;
    get_index(ref_atoms, ndx_file, 1, &n_refatoms, &ind_refatoms, &gn_refatoms);
    std::cout<< "\nSelect group from simulation structure(s) <" << struct_file <<"> to compare to the reference structure, <" << ref_file << ">." << std::endl;
    get_index(struct_atoms, ndx_file, 1, &n_structatoms, &ind_structatoms, &gn_structatoms);

    if ( n_structatoms != n_refatoms ) 
    {
        gmx_fatal(FARGS, "\nThe number of atoms in the index groups are different.");
    }
     
    /* read the reference file and get coordinates */
    std::vector<float> ref_coords(n_refatoms*3,0);
    readCoords(n_refatoms, ind_refatoms, ref_xtop, &ref_top, ref_coords, bVerbose);

    /* read trajectory file and loop through frames */
    int nframes = 0;
    read_first_frame(oenv, &struct_status, traj_file, &struct_fr, struct_flags);
    do {
        std::vector<float> struct_coords(n_structatoms*3,0);
        readCoords(n_structatoms, ind_structatoms, &struct_fr, &struct_top, struct_coords, bVerbose);
        displacement(ref_coords, struct_coords, data, bVerbose);
        kabsch_alignment(ref_coords,struct_coords, data, bVerbose);
        data.time.push_back(struct_fr.time);
        nframes++;
    } while(read_next_frame(oenv, struct_status, &struct_fr));
    for (int i=0; i<nframes; i++)
    {
        fprintf(data.fp,"%8.2f %8.2f %8.3f %8.3f %12.6f %12.6f %12.6f %8.2f %8.2f %8.2f\n",data.time[i],data.rotation[i],data.rmsd[i],data.distance[i],data.x_rotation_axis[i],data.y_rotation_axis[i],data.z_rotation_axis[i],data.x_rotation[i],data.y_rotation[i],data.z_rotation[i]);
    }

    return 0;
}
Exemple #11
0
    std::vector<double> partition3d::interpolate(double ye, double temp,
        double rho, boost::uint32_t eosvalues)
    {
        double logrho = std::log10(rho);
        double logtemp = std::log10(temp);

        std::size_t idx_ye = get_index(dimension::ye, ye);
        std::size_t idx_logtemp = get_index(dimension::temp, logtemp);
        std::size_t idx_logrho = get_index(dimension::rho, logrho);

        double delta_ye = (ye - ye_values_[idx_ye]) / delta_[dimension::ye];
        double delta_logtemp = (logtemp - logtemp_values_[idx_logtemp]) / delta_[dimension::temp];
        double delta_logrho = (logrho - logrho_values_[idx_logrho]) / delta_[dimension::rho];

        std::vector<double> results;
        results.reserve(19);

        // Calculate all required values.
        if (eosvalues & logpress) {
            double value = tl_interpolate(logpress_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho);
            results.push_back(std::pow(10., value));
        }
        if (eosvalues & logenergy) {
            double value = tl_interpolate(logenergy_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho);
            results.push_back(std::pow(10., value) - energy_shift_);
        }
        if (eosvalues & entropy) {
            results.push_back(tl_interpolate(entropy_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }
        if (eosvalues & munu) {
            results.push_back(tl_interpolate(munu_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }
        if (eosvalues & cs2) {
            results.push_back(tl_interpolate(cs2_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }
        if (eosvalues & dedt) {
            results.push_back(tl_interpolate(dedt_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }
        if (eosvalues & dpdrhoe) {
            results.push_back(tl_interpolate(dpdrhoe_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }
        if (eosvalues & dpderho) {
            results.push_back(tl_interpolate(dpderho_values_.get(),
                idx_ye, idx_logtemp, idx_logrho,
                delta_ye, delta_logtemp, delta_logrho));
        }

        return results;
    }
static void parse_debug_cmdline(int argc, char **argv, CESA_DEBUG *cesa_debug)
{
	unsigned int i = 2,j;

        cesa_debug->mode = 0;
	for(j = i; j < argc; j++) {
		if(!strcmp(argv[j], "-v"))
			cesa_debug->mode++; 
	}

	if(argc < 3) {
                fprintf(stderr,"missing arguments\n");
		exit(1);
	}

	if(!strcmp(argv[i], "Sts")) 
        	cesa_debug->debug = STATUS;
	else if(!strcmp(argv[i], "Chan")) {
                cesa_debug->debug = CHAN;
		get_index(argc, argv, cesa_debug);
	}
        else if(!strcmp(argv[i], "Q"))
                cesa_debug->debug = QUEUE;
        else if(!strcmp(argv[i], "SA")) {
                cesa_debug->debug = SA;
		get_index(argc, argv, cesa_debug);
	}
        else if(!strcmp(argv[i], "Cache_idx")) {
                cesa_debug->debug = CACHE_IDX;
		get_index(argc, argv, cesa_debug);
	}
        else if(!strcmp(argv[i], "Sram"))
                cesa_debug->debug = SRAM;
        else if(!strcmp(argv[i], "SAD"))
                cesa_debug->debug = SAD;
        else if(!strcmp(argv[i], "Tst_req")) {
                cesa_debug->debug = TST_REQ;
        	for(j = i; j < argc; j++) {
                	if(!strcmp(argv[j], "-s")) {
				j++;
                        	break;
			}
		}
		if(!(j < argc)) {
			fprintf(stderr,"missing/illegal size\n");
			exit(1);
		}
		cesa_debug->size = atoi(argv[j]);
		get_index(argc, argv, cesa_debug);
	}
        else if(!strcmp(argv[i], "Tst_ses")) {
                cesa_debug->debug = TST_SES;
		get_index(argc, argv, cesa_debug);
	}
	else if(!strcmp(argv[i], "Tst_stats")) {
		cesa_debug->debug = TST_STATS;
        }
	else{
		fprintf(stderr,"illegal debug option\n");
		exit(1);
	}

}
            return i;
        }
    }
    return -1;
}

void DArray_free(DArray *arr) {
  free(arr->array);
}

/*your code here*/
int set(DArray* arr, int index, int value) {
    if (index >= arr->upto || index < 0) {
        return -1;
    }
    arr->array[index]=value;
    return index;
}

int delete(DArray* arr, int value) {
    int index = get_index(arr, value);
    if (index >= arr->upto || index < 0) {
        return -1;
    }
    int i;
    for(i=index;i< arr->upto-i; i++){
        arr->array[i] = arr->array[i+1];
    }
    
    return arr->upto--;
}
int gmx_bundle(int argc,char *argv[])
{
  static char *desc[] = {
    "g_bundle analyzes bundles of axes. The axes can be for instance",
    "helix axes. The program reads two index groups and divides both",
    "of them in [TT]-na[tt] parts. The centers of mass of these parts",
    "define the tops and bottoms of the axes.",
    "Several quantities are written to file:",
    "the axis length, the distance and the z-shift of the axis mid-points",
    "with respect to the average center of all axes, the total tilt,",
    "the radial tilt and the lateral tilt with respect to the average axis.",
    "[PAR]",
    "With options [TT]-ok[tt], [TT]-okr[tt] and [TT]-okl[tt] the total,",
    "radial and lateral kinks of the axes are plotted. An extra index",
    "group of kink atoms is required, which is also divided into [TT]-na[tt]",
    "parts. The kink angle is defined as the angle between the kink-top and",
    "the bottom-kink vectors.",
    "[PAR]",
    "With option [TT]-oa[tt] the top, mid (or kink when [TT]-ok[tt] is set)",
    "and bottom points of each axis",
    "are written to a pdb file each frame. The residue numbers correspond",
    "to the axis numbers. When viewing this file with [TT]rasmol[tt], use the",
    "command line option [TT]-nmrpdb[tt], and type [TT]set axis true[tt] to",
    "display the reference axis."
  };
  static int  n=0;
  static bool bZ=FALSE;
  t_pargs pa[] = {
    { "-na", FALSE, etINT, {&n},
	"Number of axes" },
    { "-z", FALSE, etBOOL, {&bZ},
	"Use the Z-axis as reference iso the average axis" }
  };
  FILE       *out,*flen,*fdist,*fz,*ftilt,*ftiltr,*ftiltl;
  FILE       *fkink=NULL,*fkinkr=NULL,*fkinkl=NULL;
  int        status,fpdb;
  t_topology top;
  int        ePBC;
  rvec       *xtop;
  matrix     box;
  t_trxframe fr;
  t_atoms    outatoms;
  real       t,comp;
  int        natoms;
  char       *grpname[MAX_ENDS],title[256],*anm="CA",*rnm="GLY";
  int        i,j,gnx[MAX_ENDS];
  atom_id    *index[MAX_ENDS];
  t_bundle   bun;
  bool       bKink;
  rvec       va,vb,vc,vr,vl;
#define NLEG asize(leg) 
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD }, 
    { efTPS, NULL, NULL, ffREAD }, 
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ol", "bun_len", ffWRITE },
    { efXVG, "-od", "bun_dist", ffWRITE },
    { efXVG, "-oz", "bun_z", ffWRITE },
    { efXVG, "-ot", "bun_tilt", ffWRITE },
    { efXVG, "-otr", "bun_tiltr", ffWRITE },
    { efXVG, "-otl", "bun_tiltl", ffWRITE },
    { efXVG, "-ok", "bun_kink", ffOPTWR },
    { efXVG, "-okr", "bun_kinkr", ffOPTWR },
    { efXVG, "-okl", "bun_kinkl", ffOPTWR },
    { efPDB, "-oa", "axes", ffOPTWR }
  }; 
#define NFILE asize(fnm) 

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

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

  bKink = opt2bSet("-ok",NFILE,fnm) || opt2bSet("-okr",NFILE,fnm) 
    || opt2bSet("-okl",NFILE,fnm);
  if (bKink)
    bun.nend = 3;
  else
    bun.nend = 2;
  
  fprintf(stderr,"Select a group of top and a group of bottom ");
  if (bKink)
    fprintf(stderr,"and a group of kink ");
  fprintf(stderr,"atoms\n");
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),bun.nend,
	    gnx,index,grpname);

  if (n<=0 || gnx[0] % n || gnx[1] % n || (bKink && gnx[2] % n))
    gmx_fatal(FARGS,
		"The size of one of your index groups is not a multiple of n");
  bun.n = n;
  snew(bun.end[0],n);
  snew(bun.end[1],n);
  if (bKink)
    snew(bun.end[2],n);
  snew(bun.mid,n);
  snew(bun.dir,n);
  snew(bun.len,n);

  flen   = xvgropen(opt2fn("-ol",NFILE,fnm),"Axis lengths",
		    xvgr_tlabel(),"(nm)");
  fdist  = xvgropen(opt2fn("-od",NFILE,fnm),"Distance of axis centers",
		    xvgr_tlabel(),"(nm)");
  fz     = xvgropen(opt2fn("-oz",NFILE,fnm),"Z-shift of axis centers",
		    xvgr_tlabel(),"(nm)");
  ftilt  = xvgropen(opt2fn("-ot",NFILE,fnm),"Axis tilts",
		    xvgr_tlabel(),"(degrees)");
  ftiltr = xvgropen(opt2fn("-otr",NFILE,fnm),"Radial axis tilts",
		    xvgr_tlabel(),"(degrees)");
  ftiltl = xvgropen(opt2fn("-otl",NFILE,fnm),"Lateral axis tilts",
		    xvgr_tlabel(),"(degrees)");
  
  if (bKink) {
    fkink  = xvgropen(opt2fn("-ok",NFILE,fnm),"Kink angles",
		      xvgr_tlabel(),"(degrees)");
    fkinkr = xvgropen(opt2fn("-okr",NFILE,fnm),"Radial kink angles",
		      xvgr_tlabel(),"(degrees)");
    if (bPrintXvgrCodes())
      fprintf(fkinkr,"@ subtitle \"+ = ) (   - = ( )\"\n");
    fkinkl = xvgropen(opt2fn("-okl",NFILE,fnm),"Lateral kink angles",
		      xvgr_tlabel(),"(degrees)");
  }

  if (opt2bSet("-oa",NFILE,fnm)) {
    init_t_atoms(&outatoms,3*n,FALSE);
    outatoms.nr = 3*n;
    for(i=0; i<3*n; i++) {
      outatoms.atomname[i] = &anm;
      outatoms.atom[i].resnr = i/3;
      outatoms.resname[i/3] = &rnm;
    }
    fpdb = open_trx(opt2fn("-oa",NFILE,fnm),"w");
  } else
    fpdb = -1;
  
  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_NEED_X); 
  
  do {
    rm_pbc(&top.idef,ePBC,fr.natoms,fr.box,fr.x,fr.x);
    calc_axes(fr.x,top.atoms.atom,gnx,index,!bZ,&bun);
    t = convert_time(fr.time);
    fprintf(flen," %10g",t);
    fprintf(fdist," %10g",t);
    fprintf(fz," %10g",t);
    fprintf(ftilt," %10g",t);
    fprintf(ftiltr," %10g",t);
    fprintf(ftiltl," %10g",t);
    if (bKink) {
      fprintf(fkink," %10g",t);
      fprintf(fkinkr," %10g",t);
      fprintf(fkinkl," %10g",t);
    }

    for(i=0; i<bun.n; i++) {
      fprintf(flen," %6g",bun.len[i]);
      fprintf(fdist," %6g",norm(bun.mid[i]));
      fprintf(fz," %6g",bun.mid[i][ZZ]);
      fprintf(ftilt," %6g",RAD2DEG*acos(bun.dir[i][ZZ]));
      comp = bun.mid[i][XX]*bun.dir[i][XX]+bun.mid[i][YY]*bun.dir[i][YY];
      fprintf(ftiltr," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      comp = bun.mid[i][YY]*bun.dir[i][XX]-bun.mid[i][XX]*bun.dir[i][YY];
      fprintf(ftiltl," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      if (bKink) {
	rvec_sub(bun.end[0][i],bun.end[2][i],va);
	rvec_sub(bun.end[2][i],bun.end[1][i],vb);
	unitv_no_table(va,va);
	unitv_no_table(vb,vb);
	fprintf(fkink," %6g",RAD2DEG*acos(iprod(va,vb)));
	cprod(va,vb,vc);
	copy_rvec(bun.mid[i],vr);
	vr[ZZ] = 0;
	unitv_no_table(vr,vr);
	fprintf(fkinkr," %6g",RAD2DEG*asin(iprod(vc,vr)));
	vl[XX] = vr[YY];
	vl[YY] = -vr[XX];
	vl[ZZ] = 0;
	fprintf(fkinkl," %6g",RAD2DEG*asin(iprod(vc,vl)));
      }
    }
    fprintf(flen,"\n");
    fprintf(fdist,"\n");
    fprintf(fz,"\n");
    fprintf(ftilt,"\n");
    fprintf(ftiltr,"\n");
    fprintf(ftiltl,"\n");
    if (bKink) {
      fprintf(fkink,"\n");
      fprintf(fkinkr,"\n");
      fprintf(fkinkl,"\n");
    }
    if (fpdb >= 0)
      dump_axes(fpdb,&fr,&outatoms,&bun);
  } while(read_next_frame(status,&fr));

  close_trx(status);
  
  if (fpdb >= 0)
    close_trx(fpdb);
  fclose(flen);
  fclose(fdist);
  fclose(fz);
  fclose(ftilt);
  fclose(ftiltr);
  fclose(ftiltl);
  if (bKink) {
    fclose(fkink);
    fclose(fkinkr);
    fclose(fkinkl);
  }
  
  thanx(stderr);
  
  return 0;
}
/********************************************************
 *	get_num_children
 *
 * Takes the a directory's ID and returns the directory's
 * number of child directories.
 ********************************************************/
inline uint32_t get_num_children( uint32_t id )
{
	return dirs[get_index(id)].num_children;
}
Exemple #16
0
HTREEITEM TreeView_InsertItem(HWND elem, int item, LPTVINSERTSTRUCT lpis) {

  LONG i;
  struct MUI_NListtree_TreeNode *listnode=NULL;
  struct MUI_NListtree_TreeNode *prevtreenode=NULL;
  struct MUI_NListtree_TreeNode *newnode=NULL;
  ULONG flags=0;

  DebOut("elem: %lx, item: %d\n", elem, item);
  DebOut("is.itemex.pszText: %s\n", lpis->itemex.pszText);
  
  i=get_index(elem, item);
  if(i<0) {
    elem=get_elem(item);
    i=get_index(elem, item);
  }
  
  if(i<0) {
    DebOut("ERROR: nIDDlgItem %d found nowhere!?\n", item);
    return NULL;
  }

  DebOut("elem[%d].obj: %lx\n", i, elem[i].obj);

  /* Handle to the parent item. 
   * If this member is the TVI_ROOT value or NULL, the item is inserted 
   * at the root of the tree-view control.
   */
#if 0
  if(!lpis->hParent || lpis->hParent==TVI_ROOT) {
    DebOut("New Root node\n");
  }
  else {
    DebOut("insert in hParent (TODO)!!\n");
    DebOut("hParent: %lx\n", lpis->hParent);
  }
#endif

  /* 
   * TVI_FIRST Inserts the item at the beginning of the list.
   * TVI_LAST  Inserts the item at the end of the list.
   * TVI_ROOT  Add the item as a root item.
   * TVI_SORT  Inserts the item into the list in alphabetical order.
   */
  if(lpis->itemex.state & TVIS_EXPANDED) {
    DebOut("TVIS_EXPANDED\n");
    flags=TNF_LIST | TNF_OPEN;
  }

  if(lpis->itemex.state & TVIS_SELECTED) {
    DebOut("TVIS_SELECTED\n");
    flags=flags | MUIV_NListtree_Insert_Flag_Active;
  }

  listnode=(struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root;
  if(lpis->hParent && lpis->hParent!=TVI_ROOT) {
    DebOut("we need to insert into node: %lx\n", lpis->hParent);
    listnode=(struct MUI_NListtree_TreeNode *) lpis->hParent;
  }

  /* save config (lParam) in UserData */
  newnode=(struct MUI_NListtree_TreeNode *) DoMethod(elem[i].obj, MUIM_NListtree_Insert, 
                    lpis->itemex.pszText, (IPTR) lpis->itemex.lParam,
                    listnode,
                    MUIV_NListtree_Insert_PrevNode_Tail,
                    flags);

  DebOut("newnode: %lx\n", newnode);
  
  return (HTREEITEM) newnode;
}
/********************************************************
 *	get_num_files
 *
 * Takes the a directory's ID and returns the directory's
 * file count.
 ********************************************************/
inline uint32_t get_num_files( uint32_t id )
{
	return dirs[get_index(id)].num_files;
}
Exemple #18
0
int process_input (char input_file[], char input_index_file[], char input_matrix_file[], int *pnum_vertices) {
	FILE *fp, *out_index, *out_matrix;
	int line_number;
	char *token1, *token2, *token3;
	char line[138327];  
	double a;  
	char first_line;
	char mark[40]; 
	int i, j, max_id, num_lines, index, num_names; 
	char name1[MAX_ATTR_NAME];
	char name2[MAX_ATTR_NAME];

	if ((fp = fopen(input_file, "r")) == NULL) {
		fprintf(stderr, "\nFailure to open file %s in read mode\n", input_file);
		fflush(NULL);
		return(-1);
	}
	if ((out_index = fopen(input_index_file, "w")) == NULL) {
		fprintf(stderr, "\nFailure to open file %s in read mode\n", input_index_file);
		fflush(NULL);
		return(-1);
	}
	if ((out_matrix = fopen(input_matrix_file, "w")) == NULL) {
		fprintf(stderr, "\nFailure to open file %s in read mode\n", input_matrix_file);
		fflush(NULL);
		return(-1);
	}
	i = 0; j = 0; num_lines = 0; index = 0; 
	while (fgets(line, sizeof(line), fp) != NULL) { 
		token1 = strtok(line, "\t"); 
		if (token1 == NULL) {continue;}
		strncpy(name1, token1, MAX_ATTR_NAME);
		token2 = strtok(NULL, "\t"); 
		if (token2 == NULL) {continue;}
		strncpy(name2, token2, MAX_ATTR_NAME);
		if (strcmp(name1, name2) == 0) { continue;}
		token3 = strtok(NULL, "\t\n"); 
		if (token3 == NULL) {continue;}
		num_lines ++; 
		if (num_lines == 1) { 
			vertices = (VertexPtr) malloc(2 * sizeof(VertexStr)) - 1; 
			index ++; 
			i = index; 
			(vertices + index)->index = index; 
			strcpy((vertices + index)->name, name1); 
			fprintf(out_index, "%d\t%s\n", index, name1); 
			index ++; 
			j = index; 
			(vertices + index)->index = index; 
			strcpy((vertices + index)->name, name2); 
			fprintf(out_index, "%d\t%s\n", index, name2); 
			fprintf(out_matrix, "%d\t%d\t%s\n", i, j, token3); 
			(*pnum_vertices) = index; 
		} else { 
			i = get_index(name1, index); 
			if (i > index) { index = i; fprintf(out_index, "%d\t%s\n", index, name1);}
			j = get_index(name2, index); 
			if (j > index) { index = j; fprintf(out_index, "%d\t%s\n", index, name2);}
			fprintf(out_matrix, "%d\t%d\t%s\n", i, j, token3); 
			(*pnum_vertices) = index; 
		}
	}
	fclose(fp); 
	fclose(out_index); 
	fclose(out_matrix); 
	return num_lines; 
}
Exemple #19
0
static void parse_dive_rating(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->rating = get_index(line); }
int gmx_gyrate(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the radius of gyration of a molecule",
        "and the radii of gyration about the [IT]x[it]-, [IT]y[it]- and [IT]z[it]-axes,",
        "as a function of time. The atoms are explicitly mass weighted.[PAR]",
        "The axis components corresponds to the mass-weighted root-mean-square",
        "of the radii components orthogonal to each axis, for example:[PAR]",
        "Rg(x) = sqrt((sum_i m_i (R_i(y)^2 + R_i(z)^2))/(sum_i m_i)).[PAR]",
        "With the [TT]-nmol[tt] option the radius of gyration will be calculated",
        "for multiple molecules by splitting the analysis group in equally",
        "sized parts.[PAR]",
        "With the option [TT]-nz[tt] 2D radii of gyration in the [IT]x-y[it] plane",
        "of slices along the [IT]z[it]-axis are calculated."
    };
    static int      nmol = 1, nz = 0;
    static gmx_bool bQ   = FALSE, bRot = FALSE, bMOI = FALSE;
    t_pargs         pa[] = {
        { "-nmol", FALSE, etINT, {&nmol},
          "The number of molecules to analyze" },
        { "-q", FALSE, etBOOL, {&bQ},
          "Use absolute value of the charge of an atom as weighting factor instead of mass" },
        { "-p", FALSE, etBOOL, {&bRot},
          "Calculate the radii of gyration about the principal axes." },
        { "-moi", FALSE, etBOOL, {&bMOI},
          "Calculate the moments of inertia (defined by the principal axes)." },
        { "-nz", FALSE, etINT, {&nz},
          "Calculate the 2D radii of gyration of this number of slices along the z-axis" },
    };
    FILE           *out;
    t_trxstatus    *status;
    t_topology      top;
    int             ePBC;
    rvec           *x, *x_s;
    rvec            xcm, gvec, gvec1;
    matrix          box, trans;
    gmx_bool        bACF;
    real          **moi_trans = NULL;
    int             max_moi   = 0, delta_moi = 100;
    rvec            d, d1; /* eigenvalues of inertia tensor */
    real            t, t0, tm, gyro;
    int             natoms;
    char           *grpname;
    int             j, m, gnx, nam, mol;
    atom_id        *index;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc   = NULL;
    const char     *leg[]  = { "Rg", "Rg\\sX\\N", "Rg\\sY\\N", "Rg\\sZ\\N" };
    const char     *legI[] = { "Itot", "I1", "I2", "I3" };
#define NLEG asize(leg)
    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efXVG, NULL,   "gyrate",   ffWRITE },
        { efXVG, "-acf", "moi-acf",  ffOPTWR },
    };
#define NFILE asize(fnm)
    int             npargs;
    t_pargs        *ppa;

    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs, pa);

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, npargs, ppa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }
    bACF = opt2bSet("-acf", NFILE, fnm);
    if (bACF && nmol != 1)
    {
        gmx_fatal(FARGS, "Can only do acf with nmol=1");
    }
    bRot = bRot || bMOI || bACF;
    /*
       if (nz > 0)
       bMOI = TRUE;
     */
    if (bRot)
    {
        printf("Will rotate system along principal axes\n");
        snew(moi_trans, DIM);
    }
    if (bMOI)
    {
        printf("Will print moments of inertia\n");
        bQ = FALSE;
    }
    if (bQ)
    {
        printf("Will print radius normalised by charge\n");
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, TRUE);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);

    if (nmol > gnx || gnx % nmol != 0)
    {
        gmx_fatal(FARGS, "The number of atoms in the group (%d) is not a multiple of nmol (%d)", gnx, nmol);
    }
    nam = gnx/nmol;

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

    j  = 0;
    t0 = t;
    if (bQ)
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Radius of Charge (total and around axes)", "Time (ps)", "Rg (nm)", oenv);
    }
    else if (bMOI)
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Moments of inertia (total and around axes)", "Time (ps)", "I (a.m.u. nm\\S2\\N)", oenv);
    }
    else
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Radius of gyration (total and around axes)", "Time (ps)", "Rg (nm)", oenv);
    }
    if (bMOI)
    {
        xvgr_legend(out, NLEG, legI, oenv);
    }
    else
    {
        if (bRot)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(out, "@ subtitle \"Axes are principal component axes\"\n");
            }
        }
        xvgr_legend(out, NLEG, leg, oenv);
    }
    if (nz == 0)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    }
    do
    {
        if (nz == 0)
        {
            gmx_rmpbc_copy(gpbc, natoms, box, x, x_s);
        }
        gyro = 0;
        clear_rvec(gvec);
        clear_rvec(gvec1);
        clear_rvec(d);
        clear_rvec(d1);
        for (mol = 0; mol < nmol; mol++)
        {
            tm    = sub_xcm(nz == 0 ? x_s : x, nam, index+mol*nam, top.atoms.atom, xcm, bQ);
            if (nz == 0)
            {
                gyro += calc_gyro(x_s, nam, index+mol*nam, top.atoms.atom,
                                  tm, gvec1, d1, bQ, bRot, bMOI, trans);
            }
            else
            {
                calc_gyro_z(x, box, nam, index+mol*nam, top.atoms.atom, nz, t, out);
            }
            rvec_inc(gvec, gvec1);
            rvec_inc(d, d1);
        }
        if (nmol > 0)
        {
            gyro /= nmol;
            svmul(1.0/nmol, gvec, gvec);
            svmul(1.0/nmol, d, d);
        }

        if (nz == 0)
        {
            if (bRot)
            {
                if (j >= max_moi)
                {
                    max_moi += delta_moi;
                    for (m = 0; (m < DIM); m++)
                    {
                        srenew(moi_trans[m], max_moi*DIM);
                    }
                }
                for (m = 0; (m < DIM); m++)
                {
                    copy_rvec(trans[m], moi_trans[m]+DIM*j);
                }
                fprintf(out, "%10g  %10g  %10g  %10g  %10g\n",
                        t, gyro, d[XX], d[YY], d[ZZ]);
            }
            else
            {
                fprintf(out, "%10g  %10g  %10g  %10g  %10g\n",
                        t, gyro, gvec[XX], gvec[YY], gvec[ZZ]);
            }
        }
        j++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);
    if (nz == 0)
    {
        gmx_rmpbc_done(gpbc);
    }

    xvgrclose(out);

    if (bACF)
    {
        int mode = eacVector;

        do_autocorr(opt2fn("-acf", NFILE, fnm), oenv,
                    "Moment of inertia vector ACF",
                    j, 3, moi_trans, (t-t0)/j, mode, FALSE);
        do_view(oenv, opt2fn("-acf", NFILE, fnm), "-nxy");
    }

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

    return 0;
}
Exemple #21
0
static void parse_dc_numberofoxygensensors(char *line, struct membuffer *str, void *_dc)
{ struct divecomputer *dc = _dc; dc->no_o2sensors = get_index(line); }
Exemple #22
0
 void set(const int x, const int y, const double r, const double g, const double b) {
     data[get_index(x,y)].r = r;
     data[get_index(x,y)].g = g;
     data[get_index(x,y)].b = b;
 }
Exemple #23
0
int gmx_rmsdist(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the root mean square deviation of atom distances,",
        "which has the advantage that no fit is needed like in standard RMS",
        "deviation as computed by [gmx-rms].",
        "The reference structure is taken from the structure file.",
        "The RMSD at time t is calculated as the RMS",
        "of the differences in distance between atom-pairs in the reference",
        "structure and the structure at time t.[PAR]",
        "[THISMODULE] can also produce matrices of the rms distances, rms distances",
        "scaled with the mean distance and the mean distances and matrices with",
        "NMR averaged distances (1/r^3 and 1/r^6 averaging). Finally, lists",
        "of atom pairs with 1/r^3 and 1/r^6 averaged distance below the",
        "maximum distance ([TT]-max[tt], which will default to 0.6 in this case)",
        "can be generated, by default averaging over equivalent hydrogens",
        "(all triplets of hydrogens named \\*[123]). Additionally a list of",
        "equivalent atoms can be supplied ([TT]-equiv[tt]), each line containing",
        "a set of equivalent atoms specified as residue number and name and",
        "atom name; e.g.:[PAR]",
        "[TT]HB* 3 SER  HB1 3 SER  HB2[tt][PAR]",
        "Residue and atom names must exactly match those in the structure",
        "file, including case. Specifying non-sequential atoms is undefined."

    };

    int             natom, i, j, teller, gi, gj;
    real            t;

    t_topology      top;
    int             ePBC;
    t_atoms        *atoms;
    matrix          box;
    rvec           *x;
    FILE           *fp;

    t_trxstatus    *status;
    int             isize, gnr = 0;
    atom_id        *index, *noe_index;
    char           *grpname;
    real          **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr;
    real          **dtot1_3 = NULL, **dtot1_6 = NULL;
    real            rmsnow, meanmax, rmsmax, rmscmax;
    real            max1_3, max1_6;
    t_noe_gr       *noe_gr = NULL;
    t_noe         **noe    = NULL;
    t_rgb           rlo, rhi;
    char            buf[255];
    gmx_bool        bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR;

    static int      nlevels  = 40;
    static real     scalemax = -1.0;
    static gmx_bool bSumH    = TRUE;
    static gmx_bool bPBC     = TRUE;
    output_env_t    oenv;

    t_pargs         pa[] = {
        { "-nlevels",   FALSE, etINT,  {&nlevels},
          "Discretize RMS in this number of levels" },
        { "-max",   FALSE, etREAL, {&scalemax},
          "Maximum level in matrices" },
        { "-sumh",  FALSE, etBOOL, {&bSumH},
          "Average distance over equivalent hydrogens" },
        { "-pbc",   FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions when computing distances" }
    };
    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-equiv", "equiv",   ffOPTRD },
        { efXVG, NULL,   "distrmsd", ffWRITE },
        { efXPM, "-rms", "rmsdist",  ffOPTWR },
        { efXPM, "-scl", "rmsscale", ffOPTWR },
        { efXPM, "-mean", "rmsmean",  ffOPTWR },
        { efXPM, "-nmr3", "nmr3",     ffOPTWR },
        { efXPM, "-nmr6", "nmr6",     ffOPTWR },
        { efDAT, "-noe", "noe",     ffOPTWR },
    };
#define NFILE asize(fnm)

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

    bRMS   = opt2bSet("-rms", NFILE, fnm);
    bScale = opt2bSet("-scl", NFILE, fnm);
    bMean  = opt2bSet("-mean", NFILE, fnm);
    bNOE   = opt2bSet("-noe", NFILE, fnm);
    bNMR3  = opt2bSet("-nmr3", NFILE, fnm);
    bNMR6  = opt2bSet("-nmr6", NFILE, fnm);
    bNMR   = bNMR3 || bNMR6 || bNOE;

    max1_3 = 0;
    max1_6 = 0;

    /* check input */
    if (bNOE && scalemax < 0)
    {
        scalemax = 0.6;
        fprintf(stderr, "WARNING: using -noe without -max "
                "makes no sense, setting -max to %g\n\n", scalemax);
    }

    /* get topology and index */
    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &x, NULL, box, FALSE);

    if (!bPBC)
    {
        ePBC = epbcNONE;
    }
    atoms = &(top.atoms);

    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    /* initialize arrays */
    snew(d, isize);
    snew(dtot, isize);
    snew(dtot2, isize);
    if (bNMR)
    {
        snew(dtot1_3, isize);
        snew(dtot1_6, isize);
    }
    snew(mean, isize);
    snew(rms, isize);
    snew(rmsc, isize);
    snew(d_r, isize);
    snew(resnr, isize);
    for (i = 0; (i < isize); i++)
    {
        snew(d[i], isize);
        snew(dtot[i], isize);
        snew(dtot2[i], isize);
        if (bNMR)
        {
            snew(dtot1_3[i], isize);
            snew(dtot1_6[i], isize);
        }
        snew(mean[i], isize);
        snew(rms[i], isize);
        snew(rmsc[i], isize);
        snew(d_r[i], isize);
        resnr[i] = i+1;
    }

    /*set box type*/
    calc_dist(isize, index, x, ePBC, box, d_r);
    sfree(x);

    /*open output files*/
    fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)",
                  oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname);
    }

    /*do a first step*/
    natom  = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    teller = 0;

    do
    {
        calc_dist_tot(isize, index, x, ePBC, box, d, dtot, dtot2, bNMR, dtot1_3, dtot1_6);

        rmsnow = rms_diff(isize, d, d_r);
        fprintf(fp, "%g  %g\n", t, rmsnow);
        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");

    xvgrclose(fp);

    close_trj(status);

    calc_rms(isize, teller, dtot, dtot2, mean, &meanmax, rms, &rmsmax, rmsc, &rmscmax);
    fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax);

    if (bNMR)
    {
        calc_nmr(isize, teller, dtot1_3, dtot1_6, &max1_3, &max1_6);
    }

    if (scalemax > -1.0)
    {
        rmsmax  = scalemax;
        rmscmax = scalemax;
        meanmax = scalemax;
        max1_3  = scalemax;
        max1_6  = scalemax;
    }

    if (bNOE)
    {
        /* make list of noe atom groups */
        snew(noe_index, isize+1);
        snew(noe_gr, isize);
        gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm),
                                     atoms, isize, index, bSumH, noe_index, noe_gr);
        fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n",
                gnr, isize);
        /* make half matrix of of noe-group distances from atom distances */
        snew(noe, gnr);
        for (i = 0; i < gnr; i++)
        {
            snew(noe[i], gnr);
        }
        calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe);
    }

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

    if (bRMS)
    {
        write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0,
                  "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels);
    }

    if (bScale)
    {
        write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0,
                  "Relative RMS", "RMS", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels);
    }

    if (bMean)
    {
        write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0,
                  "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels);
    }

    if (bNMR3)
    {
        write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels);
    }
    if (bNMR6)
    {
        write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels);
    }

    if (bNOE)
    {
        write_noe(opt2FILE("-noe", NFILE, fnm, "w"), gnr, noe, noe_gr, scalemax);
    }

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

    return 0;
}
Exemple #24
0
void do_corr(const char *trx_file, const char *ndx_file, const char *msd_file,
             const char *mol_file, const char *pdb_file, real t_pdb,
             int nrgrp, t_topology *top, int ePBC,
             gmx_bool bTen, gmx_bool bMW, gmx_bool bRmCOMM,
             int type, real dim_factor, int axis,
             real dt, real beginfit, real endfit, const gmx_output_env_t *oenv)
{
    t_corr        *msd;
    int           *gnx;   /* the selected groups' sizes */
    int          **index; /* selected groups' indices */
    char         **grpname;
    int            i, i0, i1, j, N, nat_trx;
    real          *DD, *SigmaD, a, a2, b, r, chi2;
    rvec          *x;
    matrix         box;
    int           *gnx_com     = NULL; /* the COM removal group size  */
    int          **index_com   = NULL; /* the COM removal group atom indices */
    char         **grpname_com = NULL; /* the COM removal group name */

    snew(gnx, nrgrp);
    snew(index, nrgrp);
    snew(grpname, nrgrp);

    fprintf(stderr, "\nSelect a group to calculate mean squared displacement for:\n");
    get_index(&top->atoms, ndx_file, nrgrp, gnx, index, grpname);

    if (bRmCOMM)
    {
        snew(gnx_com, 1);
        snew(index_com, 1);
        snew(grpname_com, 1);

        fprintf(stderr, "\nNow select a group for center of mass removal:\n");
        get_index(&top->atoms, ndx_file, 1, gnx_com, index_com, grpname_com);
    }

    if (mol_file)
    {
        index_atom2mol(&gnx[0], index[0], &top->mols);
    }

    msd = init_corr(nrgrp, type, axis, dim_factor,
                    mol_file == NULL ? 0 : gnx[0], bTen, bMW, dt, top,
                    beginfit, endfit);

    nat_trx =
        corr_loop(msd, trx_file, top, ePBC, mol_file ? gnx[0] : 0, gnx, index,
                  (mol_file != NULL) ? calc1_mol : (bMW ? calc1_mw : calc1_norm),
                  bTen, gnx_com, index_com, dt, t_pdb,
                  pdb_file ? &x : NULL, box, oenv);

    /* Correct for the number of points */
    for (j = 0; (j < msd->ngrp); j++)
    {
        for (i = 0; (i < msd->nframes); i++)
        {
            msd->data[j][i] /= msd->ndata[j][i];
            if (bTen)
            {
                msmul(msd->datam[j][i], 1.0/msd->ndata[j][i], msd->datam[j][i]);
            }
        }
    }

    if (mol_file)
    {
        if (pdb_file && x == NULL)
        {
            fprintf(stderr, "\nNo frame found need time tpdb = %g ps\n"
                    "Can not write %s\n\n", t_pdb, pdb_file);
        }
        i             = top->atoms.nr;
        top->atoms.nr = nat_trx;
        if (pdb_file && top->atoms.pdbinfo == NULL)
        {
            snew(top->atoms.pdbinfo, top->atoms.nr);
        }
        printmol(msd, mol_file, pdb_file, index[0], top, x, ePBC, box, oenv);
        top->atoms.nr = i;
    }

    DD     = NULL;
    SigmaD = NULL;

    if (beginfit == -1)
    {
        i0       = static_cast<int>(0.1*(msd->nframes - 1) + 0.5);
        beginfit = msd->time[i0];
    }
    else
    {
        for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++)
        {
            ;
        }
    }

    if (endfit == -1)
    {
        i1     = static_cast<int>(0.9*(msd->nframes - 1) + 0.5) + 1;
        endfit = msd->time[i1-1];
    }
    else
    {
        for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++)
        {
            ;
        }
    }
    fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit,
            output_env_get_time_unit(oenv));

    N = i1-i0;
    if (N <= 2)
    {
        fprintf(stdout, "Not enough points for fitting (%d).\n"
                "Can not determine the diffusion constant.\n", N);
    }
    else
    {
        snew(DD, msd->ngrp);
        snew(SigmaD, msd->ngrp);
        for (j = 0; j < msd->ngrp; j++)
        {
            if (N >= 4)
            {
                lsq_y_ax_b(N/2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2);
                lsq_y_ax_b(N/2, &(msd->time[i0+N/2]), &(msd->data[j][i0+N/2]), &a2, &b, &r, &chi2);
                SigmaD[j] = std::abs(a-a2);
            }
            else
            {
                SigmaD[j] = 0;
            }
            lsq_y_ax_b(N, &(msd->time[i0]), &(msd->data[j][i0]), &(DD[j]), &b, &r, &chi2);
            DD[j]     *= FACTOR/msd->dim_factor;
            SigmaD[j] *= FACTOR/msd->dim_factor;
            if (DD[j] > 0.01 && DD[j] < 1e4)
            {
                fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
            else
            {
                fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
        }
    }
    /* Print mean square displacement */
    corr_print(msd, bTen, msd_file,
               "Mean Square Displacement",
               "MSD (nm\\S2\\N)",
               msd->time[msd->nframes-1], beginfit, endfit, DD, SigmaD, grpname, oenv);
}
Exemple #25
0
/* function name: draw_contour
 * Input Parameter
 *   maze : maze array wich has maze information
 *   map  : array to draw contour map
 *   type : maze type to run mouse
 *   pos  : current mouse location in the maze
 */
void draw_contour(unsigned char *maze, unsigned char *map,
                  unsigned int type, unsigned char pos)
{
    int i, contour_lvl = 1;
    int index;
    unsigned int item;
    char found_mouse = 0;
    struct circular_buffer *cb, contour_buffer;

    cb = &contour_buffer;
    circular_buffer_init(cb, contour_cb_buffer,
                         CONTOUR_CB_BUFFER_MAX);

    /* Uninitialized contour map */
    memset(map, 0, MAZEMAX);

    /* Seed value 1 as a goal */
    switch (type) {
    case TO_GOAL_4X4:
        map[get_index(3, 3)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x33));
        break;
    case TO_GOAL_8X8:
        map[get_index(7, 7)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        break;
    case TO_GOAL_16X16:
        map[get_index(7, 7)] = contour_lvl;
        map[get_index(8, 7)] = contour_lvl;
        map[get_index(7, 8)] = contour_lvl;
        map[get_index(8, 8)] = contour_lvl;

        /* Add list of same level contour value */
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x78));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x87));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x88));
        break;
    case TO_START_4X4:
    case TO_START_8X8:
    case TO_START_16X16:
        map[get_index(0, 0)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x00));
        break;
    default:
        if (type < MAZEMAX) {
            map[type] = contour_lvl;
            circular_buffer_write(cb, gen_contour_pos(contour_lvl, type));
        } else {
            print_exit("Invalid target goal index!\n");
        }
        break;
    }

    /* Get one contour number from circular buffer.
     * Put next higher value in next block if there is
     * no wall to there and save it inti circular buffer.
     * If contour map reaches to current mouse or
     * circular buffer is empty then it's done.
     */
    while (!circular_buffer_empty(cb) && !found_mouse) {
        circular_buffer_read(cb, &item);
        index = get_contour_index(item);
        contour_lvl = get_contour_lvl(item) + 1;

        /* Calculate contour lvl around current cube */
        for (i = NI; i <= WI; i++) {
            if (!(maze[index] & wall_bit(i)) &&
                    (map[index + maze_dxy[i]] == 0)) {
                map[index + maze_dxy[i]] = contour_lvl;
                circular_buffer_write(cb,
                                      gen_contour_pos(contour_lvl,
                                                      index + maze_dxy[i]));
                if (index + maze_dxy[i] == pos)
                    found_mouse = 1;
            }
        }

#ifdef DEBUG
        if (debug_flag & DEBUG_CONTOUR) {
            print_map(map);
            usleep(20000);
        }
#endif
    }

    if (!found_mouse) {
        /* Mouse alorighm should never hit this location */
        print_map(map);
        print_exit("%s couldn't find mouse location\n",
                   __func__);
    }
}
Exemple #26
0
int gmx_gmx2pqr(int argc, const char * argv[])
{
    const char *desc[] = {
        "\tThis convert from gromacs to APBS pqr files.",
        "Use the -a1 flag for the start of the bond vector",
        "and the -a2 flag for the end of the bond vector."
        "\n"
    };
    t_topology      top;
    t_atoms         *atoms = NULL, useatoms;
    int             ePBC;
    char            title[STRLEN];
    t_trxframe      fr;
    rvec            *xtop;
    matrix          box;
    t_trxstatus     *status;
    int             flags = TRX_READ_X;
    const char      *parm_name, *atp_name;
    output_env_t    oenv;
    const char      *tpr_file, *xtc_file, *index_file, *out_file = NULL;
    char            tpr_title[256], pqr[256];
    rvec            bondvector,midpoint;
    double          bondlength;
    int             a1=-1, a2=-1;   // Initializing these negative as a check
    gmx_bool        nn=FALSE;
    float           pdie=1;
    double          pfield,pcfield,pnfield,psfield;
    gmx_bool        bVerbose=FALSE;     // Remember, 0=False, 1=True
    static char     *a3=NULL;
    
    t_pargs pa[] = {
        { "-nn", TRUE, etBOOL,
            {&nn}, "Use a separate index file for each frame, IE: dynamic index files created through g_select."},
        { "-a1", TRUE, etINT,
            {&a1}, "Atom number 1 (CNC CD, must be set!)"},
        { "-a2", TRUE, etINT,
            {&a2}, "Atom number 2 (CNC NE, must be set!)"},
        { "-a3", TRUE, etSTR,
            {&a3},"String, in quotations, for atoms you want to know the field due to"},
        { "-pdie", TRUE, etREAL,
            {&pdie}, "Protein dielectric"},
        { "-v", FALSE, etBOOL, {&bVerbose},
            "Be slightly more verbose"}
    };
    
    t_filenm fnm[] = {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efDAT, "-d", "/Users/ritchie/Utilities/apbs/AMBER.DAT", ffREAD },
        { efPQR, "-o", NULL, ffWRITE },
        { efXVG, "-of", "field_projection", ffWRITE },
        { efNDX, NULL, NULL, ffREAD }
    };
    
#define NFILE asize(fnm)
#define NPA asize(pa)
    
    CopyRight(stderr,argv[0]);
    
    parse_common_args(&argc, argv,
                      PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW |
                      PCA_TIME_UNIT | PCA_BE_NICE,
                      NFILE, fnm, NPA, pa, asize(desc), desc,
                      0, NULL, &oenv);
    tpr_file = ftp2fn(efTPS, NFILE, fnm);
    xtc_file = opt2fn("-f", NFILE, fnm);
    parm_name = opt2fn("-d", NFILE, fnm);
    atp_name = opt2fn("-a", NFILE, fnm);
    out_file = opt2fn("-o", NFILE,fnm);
    
    read_tps_conf(tpr_file, tpr_title, &top, &ePBC, &xtop, NULL, box, TRUE);
    sfree(xtop);
    atoms = &top.atoms;

    printf("Select group for to save atom coordinates:\n");
    index_file = ftp2fn(efNDX, NFILE, fnm);
//    int             *i_index = (int*)malloc(sizeof(int)*nn);
//    atom_id         **ind_index = (atom_id*)malloc(sizeof(atom_id)*nn);
//    char            **gn_index = (char*)malloc(sizeof(char)*nn);
    int i_index;
    atom_id *ind_index;
    char *gn_index;
    get_index(atoms,index_file,1,&i_index,&ind_index,&gn_index);

    
    /* The first time we read data is a little special */
    read_first_frame(oenv, &status, xtc_file, &fr, flags);
    
    /* check for required parameters */
    if( a1<1 || a2<1 )
        gmx_fatal(FARGS, "Atom numbers a1 and a2 defining the bond vector must be specified\n" );
    a1--;a2--; //internally, numbering starts at 0
    /* check that these atoms exists */
    if(a1<0 || a1>(top.atoms.nr))
    {
        fprintf(stderr,"Error: Atom number %d is out of range.\n",a1);
        exit(1);
    }
    if(a2<0 || a2>(top.atoms.nr))
    {
        fprintf(stderr,"Error: Atom number %d is out of range.\n",a2);
        exit(1);
    }
    
    /* Get all of the atoms indices for finding the field of */
    char *sep = " ,;:/'\"";
    char *word, *brkt;
    int field_due_to_atom[1000], n_field_atoms=0;
    if (a3) {
        for (word = strtok_r(a3, sep, &brkt); word; word = strtok_r(NULL, sep, &brkt))
        {
            int field_atom = atoi(word);
            if (field_atom>(top.atoms.nr))
            {
                fprintf(stderr,"Error: Atom number %d is out of range.\n",field_atom);
                exit(1);
            }
            field_due_to_atom[n_field_atoms] = field_atom - 1;
            n_field_atoms++;
        }
        printf("\nWill include field due to atoms: ");
        for (int i=0;i<n_field_atoms;i++){printf("%i ",field_due_to_atom[i]+1);}
        printf("\n");
    }
    
    fprintf(stderr,"\nWill read reference charges and radii from %s\n",(opt2fn("-d",NFILE,fnm)));
    gmx2amb_dat dat;
    dat = read_DAT(parm_name,atp_name,dat,bVerbose);
    
    /* This is the main loop over frames */
    int framen=0;
    int resid=0;
    double charge=0.0,radius;
    double radii[100000]; // lazy, I should make this dynamic
    char *atomname, *resname;
    char *pqr_file = out_file;
    pqr_file[strlen(pqr_file)-4] = 0;
    FILE *fout = ffopen( opt2fn("-of",NFILE,fnm),"w");
    fprintf(fout,";%13i-%i %18i %18i ",ind_index[0]+1,ind_index[i_index-1]+1,a1+1,a2+1);
    if (a3) {
        for (int i=0;i<n_field_atoms;i++){fprintf(fout,"%18i ",field_due_to_atom[i]+1); }
    }
    fprintf(fout,"%18s","F-excpt");
    do {
        if (nn && framen > 0) {
            get_index(atoms,index_file,1,&i_index,&ind_index,&gn_index);
        }
        
        sprintf(pqr,"%s%i.pqr",pqr_file,framen);
        FILE *pqrout = ffopen(pqr,"w");
        if ( pqrout == NULL ) {
            gmx_fatal(FARGS,"\nFailed to open output file, '%s'\n",pqr);
        }
        
        rvec_sub(fr.x[a2],fr.x[a1],bondvector); // Nitrile ond vector we're looking at
        bondlength = pow(iprod(bondvector,bondvector),.5);
        midpoint[0] = fr.x[a1][XX] + 0.5 * bondvector[0];
        midpoint[1] = fr.x[a1][YY] + 0.5 * bondvector[1];
        midpoint[2] = fr.x[a1][ZZ] + 0.5 * bondvector[2];

//        fprintf(stderr,"\n%1.12f %1.12f %1.12f : %1.12f\n",bondvector[0],bondvector[1],bondvector[2],bondlength);
        
        double x,y,z;
        int npoints = 50;
        for (int n=0; n < npoints+1 ; n++ )
        {
            x = fr.x[a1][XX]*10 + n*bondvector[0]*10/npoints;
            y = fr.x[a1][YY]*10 + n*bondvector[1]*10/npoints;
            z = fr.x[a1][ZZ]*10 + n*bondvector[2]*10/npoints;
            fprintf(pqrout,"ATOM %6i %4s %4s %5i %11.3f %7.3f %7.3f %7.4f %7.3f\n",0,"DUM","CNC",0,x,y,z,0.0,0.0);
        }

        pcfield = calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength) / pdie;
        pnfield = calculate_field(a2,a2,top,fr,midpoint,bondvector,bondlength) / pdie;
        pfield = 0;
//        fprintf(stderr,"\nfields, pdie=%.2f: %.4f %.4f\n",pdie,calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength)/pdie,calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength));

        // Let's get the radii from the first frame, then use the same radii for every other frame.
        // I don't see a significant performance increase relative to re-matching every frame.
        if ( framen == 0 ) {
            for (int n=0; n < i_index ; n++ ) {
                radii[n] = -1000. ;
                int i = ind_index[n];
                resid = top.atoms.atom[i].resind;
                charge = top.atoms.atom[i].q;
                atomname = *top.atoms.atomname[i];
                resname = *top.atoms.resinfo[resid].name;
                for ( int j=0; j < dat.n ; j++ ) {
                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
                    if (strncmp(*top.atoms.atomtype[i],dat.dat[j].ambername,(strlen(*top.atoms.atomtype[i])+1)) == 0 ) {
                        radii[n] = dat.dat[j].radius;
                        if (bVerbose){fprintf(stderr,"\nMatched %s on %s to %s! (%d/%d)\n",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
                        break;
                    }
                }
                if (radii[n] == -1000.0) {
                    fprintf(stderr,"\nFrame %d : Could not match %s %s %s %i\n",framen,atomname,resname,*top.atoms.atomtype[i],n+1);
                    exit(1);
                }
            }
        }
        for (int n=0 ; n < i_index ; n++ )
        {
            radius = -1000.;
            int i = ind_index[n];
            //
            pfield += calculate_field(i,i,top,fr,midpoint,bondvector,bondlength) / pdie;
            //
            resid = top.atoms.atom[i].resind;
            charge = top.atoms.atom[i].q;
            atomname = *top.atoms.atomname[i];
            resname = *top.atoms.resinfo[resid].name;
/*            for (int j=0;j<dat.n;j++){
//                if (strncmp(resname,dat.dat[j].resname,strlen(resname)+1) == 0 ) {
                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
//                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].resname,dat.dat[j].ambername,j,dat.n);}

                    if (strncmp(*top.atoms.atomtype[i],dat.dat[j].ambername,(strlen(*top.atoms.atomtype[i])+1)) == 0 ) {
                        radius = dat.dat[j].radius;
//                      fprintf(stderr,"\n%s =? %s -> %s", *top.atoms.atomtype[i], dat.dat[j].gmxname, dat.dat[j].ambername);
                            break;
                    }
//                }
            }
            if (radius == -1000.0) {
                fprintf(stderr,"\nFrame %d : Could not match %s %s %s %i\n",framen,atomname,resname,*top.atoms.atomtype[i],n+1);
                exit(1);
            }
 */
            fprintf(pqrout,"ATOM %6i %4s %4s %5i %11.3f %7.3f %7.3f %7.4f %7.3f\n",i+1,atomname,resname,resid+1,fr.x[i][XX]*10,fr.x[i][YY]*10,fr.x[i][ZZ]*10,charge,radii[n]);
        }
        fclose(pqrout);
        framen++;
        //
        fprintf(fout,"\n %18.6e %18.6e %18.6e ",pfield,pcfield,pnfield);
        double efield = pfield - pcfield - pnfield;
        if (a3) {
            for (int i=0;i<n_field_atoms;i++) {
                double afield = calculate_field(field_due_to_atom[i],field_due_to_atom[i],top,fr,midpoint,bondvector,bondlength)/pdie;
                fprintf(fout,"%18.6e ",afield);
                efield -= afield;
            }
        }
        fprintf(fout,"%18.6e\n",efield);

    } while(read_next_frame(oenv, status, &fr));
    fclose(fout);
    return 0;
}
Exemple #27
0
extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX,
                                    const char* fnXVG, const char *fnTRX,
                                    const char* fnDAT,
                                    real start_q, real end_q,
                                    real energy, int ng, const output_env_t oenv)
{
    int                     i, *isize, flags = TRX_READ_X, **index_atp;
    t_trxstatus            *status;
    char                  **grpname, title[STRLEN];
    atom_id               **index;
    t_topology              top;
    int                     ePBC;
    t_trxframe              fr;
    reduced_atom_t        **red;
    structure_factor       *sf;
    rvec                   *xtop;
    real                  **sf_table;
    matrix                  box;
    real                    r_tmp;

    gmx_structurefactors_t *gmx_sf;
    real                   *a, *b, c;

    snew(a, 4);
    snew(b, 4);


    gmx_sf = gmx_structurefactors_init(fnDAT);

    gmx_structurefactors_get_sf(gmx_sf, 0, a, b, &c);

    snew (sf, 1);
    sf->energy = energy;

    /* Read the topology informations */
    read_tps_conf (fnTPS, title, &top, &ePBC, &xtop, NULL, box, TRUE);
    sfree (xtop);

    /* groups stuff... */
    snew (isize, ng);
    snew (index, ng);
    snew (grpname, ng);

    fprintf (stderr, "\nSelect %d group%s\n", ng,
             ng == 1 ? "" : "s");
    if (fnTPS)
    {
        get_index (&top.atoms, fnNDX, ng, isize, index, grpname);
    }
    else
    {
        rd_index (fnNDX, ng, isize, index, grpname);
    }

    /* The first time we read data is a little special */
    read_first_frame (oenv, &status, fnTRX, &fr, flags);

    sf->total_n_atoms = fr.natoms;

    snew (red, ng);
    snew (index_atp, ng);

    r_tmp = std::max(box[XX][XX], box[YY][YY]);
    r_tmp = std::max(box[ZZ][ZZ], r_tmp);

    sf->ref_k = (2.0 * M_PI) / (r_tmp);
    /* ref_k will be the reference momentum unit */
    sf->n_angles = static_cast<int>(end_q / sf->ref_k + 0.5);

    snew (sf->F, ng);
    for (i = 0; i < ng; i++)
    {
        snew (sf->F[i], sf->n_angles);
    }
    for (i = 0; i < ng; i++)
    {
        snew (red[i], isize[i]);
        rearrange_atoms (red[i], &fr, index[i], isize[i], &top, TRUE, gmx_sf);
        index_atp[i] = create_indexed_atom_type (red[i], isize[i]);
    }

    sf_table = compute_scattering_factor_table (gmx_sf, (structure_factor_t *)sf);


    /* This is the main loop over frames */

    do
    {
        sf->nSteps++;
        for (i = 0; i < ng; i++)
        {
            rearrange_atoms (red[i], &fr, index[i], isize[i], &top, FALSE, gmx_sf);

            compute_structure_factor ((structure_factor_t *)sf, box, red[i], isize[i],
                                      start_q, end_q, i, sf_table);
        }
    }

    while (read_next_frame (oenv, status, &fr));

    save_data ((structure_factor_t *)sf, fnXVG, ng, start_q, end_q, oenv);


    sfree(a);
    sfree(b);

    gmx_structurefactors_done(gmx_sf);

    return 0;
}
Exemple #28
0
int gmx_spatial(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] calculates the spatial distribution function and",
        "outputs it in a form that can be read by VMD as Gaussian98 cube format.",
        "For a system of 32,000 atoms and a 50 ns trajectory, the SDF can be generated",
        "in about 30 minutes, with most of the time dedicated to the two runs through",
        "[TT]trjconv[tt] that are required to center everything properly.",
        "This also takes a whole bunch of space (3 copies of the trajectory file).",
        "Still, the pictures are pretty and very informative when the fitted selection is properly made.",
        "3-4 atoms in a widely mobile group (like a free amino acid in solution) works",
        "well, or select the protein backbone in a stable folded structure to get the SDF",
        "of solvent and look at the time-averaged solvation shell.",
        "It is also possible using this program to generate the SDF based on some arbitrary",
        "Cartesian coordinate. To do that, simply omit the preliminary [gmx-trjconv] steps.",
        "",
        "Usage:",
        "",
        "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the SDF",
        "2. [TT]gmx trjconv -s a.tpr -f a.tng -o b.tng -boxcenter tric -ur compact -pbc none[tt]",
        "3. [TT]gmx trjconv -s a.tpr -f b.tng -o c.tng -fit rot+trans[tt]",
        "4. run [THISMODULE] on the [TT]c.tng[tt] output of step #3.",
        "5. Load [TT]grid.cube[tt] into VMD and view as an isosurface.",
        "",
        "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] between steps 1 and 2.",
        "",
        "Warnings",
        "^^^^^^^^",
        "",
        "The SDF will be generated for a cube that contains all bins that have some non-zero occupancy.",
        "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that your system will be rotating",
        "and translating in space (in order that the selected group does not). Therefore the values that are",
        "returned will only be valid for some region around your central group/coordinate that has full overlap",
        "with system volume throughout the entire translated/rotated system over the course of the trajectory.",
        "It is up to the user to ensure that this is the case.",
        "",
        "Risky options",
        "^^^^^^^^^^^^^",
        "",
        "To reduce the amount of space and time required, you can output only the coords",
        "that are going to be used in the first and subsequent run through [gmx-trjconv].",
        "However, be sure to set the [TT]-nab[tt] option to a sufficiently high value since",
        "memory is allocated for cube bins based on the initial coordinates and the [TT]-nab[tt]",
        "option value."
    };
    const char       *bugs[] = {
        "When the allocated memory is not large enough, a segmentation fault may occur. This is usually detected "
        "and the program is halted prior to the fault while displaying a warning message suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) "
        "option. However, the program does not detect all such events. If you encounter a segmentation fault, run it again "
        "with an increased [TT]-nab[tt] value."
    };

    static gmx_bool   bPBC         = FALSE;
    static int        iIGNOREOUTER = -1;   /*Positive values may help if the surface is spikey */
    static gmx_bool   bCUTDOWN     = TRUE;
    static real       rBINWIDTH    = 0.05; /* nm */
    static gmx_bool   bCALCDIV     = TRUE;
    static int        iNAB         = 4;

    t_pargs           pa[] = {
        { "-pbc",      FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions for computing distances" },
        { "-div",      FALSE, etBOOL, {&bCALCDIV},
          "Calculate and apply the divisor for bin occupancies based on atoms/minimal cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to get accurate counts per frame" },
        { "-ign",      FALSE, etINT, {&iIGNOREOUTER},
          "Do not display this number of outer cubes (positive values may reduce boundary speckles; -1 ensures outer surface is visible)" },
        /*    { "-cut",      bCUTDOWN, etBOOL, {&bCUTDOWN},*/
        /*      "Display a total cube that is of minimal size" }, */
        { "-bin",      FALSE, etREAL, {&rBINWIDTH},
          "Width of the bins (nm)" },
        { "-nab",      FALSE, etINT, {&iNAB},
          "Number of additional bins to ensure proper memory allocation" }
    };

    double            MINBIN[3];
    double            MAXBIN[3];
    t_topology        top;
    int               ePBC;
    t_trxframe        fr;
    rvec             *xtop;
    matrix            box, box_pbc;
    t_trxstatus      *status;
    int               flags = TRX_READ_X;
    t_pbc             pbc;
    t_atoms          *atoms;
    int               natoms;
    char             *grpnm, *grpnmp;
    atom_id          *index, *indexp;
    int               i, nidx, nidxp;
    int               v;
    int               j, k;
    int            ***bin = NULL;
    int               nbin[3];
    FILE             *flp;
    int               x, y, z, minx, miny, minz, maxx, maxy, maxz;
    int               numfr, numcu;
    int               tot, maxval, minval;
    double            norm;
    gmx_output_env_t *oenv;
    gmx_rmpbc_t       gpbc = NULL;

    t_filenm          fnm[] = {
        { efTPS,  NULL,  NULL, ffREAD }, /* this is for the topology */
        { efTRX, "-f", NULL, ffREAD },   /* and this for the trajectory */
        { efNDX, NULL, NULL, ffOPTRD }
    };

#define NFILE asize(fnm)

    /* This is the routine responsible for adding default options,
     * calling the X/motif interface, etc. */
    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }

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

    atoms = &(top.atoms);
    printf("Select group to generate SDF:\n");
    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nidx, &index, &grpnm);
    printf("Select group to output coords (e.g. solute):\n");
    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nidxp, &indexp, &grpnmp);

    /* The first time we read data is a little special */
    natoms = read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);

    /* Memory Allocation */
    MINBIN[XX] = MAXBIN[XX] = fr.x[0][XX];
    MINBIN[YY] = MAXBIN[YY] = fr.x[0][YY];
    MINBIN[ZZ] = MAXBIN[ZZ] = fr.x[0][ZZ];
    for (i = 1; i < top.atoms.nr; ++i)
    {
        if (fr.x[i][XX] < MINBIN[XX])
        {
            MINBIN[XX] = fr.x[i][XX];
        }
        if (fr.x[i][XX] > MAXBIN[XX])
        {
            MAXBIN[XX] = fr.x[i][XX];
        }
        if (fr.x[i][YY] < MINBIN[YY])
        {
            MINBIN[YY] = fr.x[i][YY];
        }
        if (fr.x[i][YY] > MAXBIN[YY])
        {
            MAXBIN[YY] = fr.x[i][YY];
        }
        if (fr.x[i][ZZ] < MINBIN[ZZ])
        {
            MINBIN[ZZ] = fr.x[i][ZZ];
        }
        if (fr.x[i][ZZ] > MAXBIN[ZZ])
        {
            MAXBIN[ZZ] = fr.x[i][ZZ];
        }
    }
    for (i = ZZ; i >= XX; --i)
    {
        MAXBIN[i]  = (std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)+iNAB)*rBINWIDTH+MINBIN[i];
        MINBIN[i] -= iNAB*rBINWIDTH;
        nbin[i]    = static_cast<int>(std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH));
    }
    snew(bin, nbin[XX]);
    for (i = 0; i < nbin[XX]; ++i)
    {
        snew(bin[i], nbin[YY]);
        for (j = 0; j < nbin[YY]; ++j)
        {
            snew(bin[i][j], nbin[ZZ]);
        }
    }
    copy_mat(box, box_pbc);
    numfr = 0;
    minx  = miny = minz = 999;
    maxx  = maxy = maxz = 0;

    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    }
    /* This is the main loop over frames */
    do
    {
        /* Must init pbc every step because of pressure coupling */

        copy_mat(box, box_pbc);
        if (bPBC)
        {
            gmx_rmpbc_trxfr(gpbc, &fr);
            set_pbc(&pbc, ePBC, box_pbc);
        }

        for (i = 0; i < nidx; i++)
        {
            if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX] ||
                fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY] ||
                fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ])
            {
                printf("There was an item outside of the allocated memory. Increase the value given with the -nab option.\n");
                printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX], MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]);
                printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX], fr.x[index[i]][YY], fr.x[index[i]][ZZ]);
                exit(1);
            }
            x = static_cast<int>(std::ceil((fr.x[index[i]][XX]-MINBIN[XX])/rBINWIDTH));
            y = static_cast<int>(std::ceil((fr.x[index[i]][YY]-MINBIN[YY])/rBINWIDTH));
            z = static_cast<int>(std::ceil((fr.x[index[i]][ZZ]-MINBIN[ZZ])/rBINWIDTH));
            ++bin[x][y][z];
            if (x < minx)
            {
                minx = x;
            }
            if (x > maxx)
            {
                maxx = x;
            }
            if (y < miny)
            {
                miny = y;
            }
            if (y > maxy)
            {
                maxy = y;
            }
            if (z < minz)
            {
                minz = z;
            }
            if (z > maxz)
            {
                maxz = z;
            }
        }
        numfr++;
        /* printf("%f\t%f\t%f\n",box[XX][XX],box[YY][YY],box[ZZ][ZZ]); */

    }
    while (read_next_frame(oenv, status, &fr));

    if (bPBC)
    {
        gmx_rmpbc_done(gpbc);
    }

    if (!bCUTDOWN)
    {
        minx = miny = minz = 0;
        maxx = nbin[XX];
        maxy = nbin[YY];
        maxz = nbin[ZZ];
    }

    /* OUTPUT */
    flp = gmx_ffopen("grid.cube", "w");
    fprintf(flp, "Spatial Distribution Function\n");
    fprintf(flp, "test\n");
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp, (MINBIN[XX]+(minx+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[YY]+(miny+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[ZZ]+(minz+iIGNOREOUTER)*rBINWIDTH)*10./bohr);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx-minx+1-(2*iIGNOREOUTER), rBINWIDTH*10./bohr, 0., 0.);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy-miny+1-(2*iIGNOREOUTER), 0., rBINWIDTH*10./bohr, 0.);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz-minz+1-(2*iIGNOREOUTER), 0., 0., rBINWIDTH*10./bohr);
    for (i = 0; i < nidxp; i++)
    {
        v = 2;
        if (*(top.atoms.atomname[indexp[i]][0]) == 'C')
        {
            v = 6;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'N')
        {
            v = 7;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'O')
        {
            v = 8;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'H')
        {
            v = 1;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'S')
        {
            v = 16;
        }
        fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX]*10.0/bohr, fr.x[indexp[i]][YY]*10.0/bohr, fr.x[indexp[i]][ZZ]*10.0/bohr);
    }

    tot = 0;
    for (k = 0; k < nbin[XX]; k++)
    {
        if (!(k < minx || k > maxx))
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (!(j < miny || j > maxy))
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (!(i < minz || i > maxz))
                {
                    continue;
                }
                if (bin[k][j][i] != 0)
                {
                    printf("A bin was not empty when it should have been empty. Programming error.\n");
                    printf("bin[%d][%d][%d] was = %d\n", k, j, i, bin[k][j][i]);
                    exit(1);
                }
            }
        }
    }

    minval = 999;
    maxval = 0;
    for (k = 0; k < nbin[XX]; k++)
    {
        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
                {
                    continue;
                }
                tot += bin[k][j][i];
                if (bin[k][j][i] > maxval)
                {
                    maxval = bin[k][j][i];
                }
                if (bin[k][j][i] < minval)
                {
                    minval = bin[k][j][i];
                }
            }
        }
    }

    numcu = (maxx-minx+1-(2*iIGNOREOUTER))*(maxy-miny+1-(2*iIGNOREOUTER))*(maxz-minz+1-(2*iIGNOREOUTER));
    if (bCALCDIV)
    {
        norm = static_cast<double>(numcu*numfr)/tot;
    }
    else
    {
        norm = 1.0;
    }

    for (k = 0; k < nbin[XX]; k++)
    {
        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
                {
                    continue;
                }
                fprintf(flp, "%12.6f ", static_cast<double>(norm*bin[k][j][i])/numfr);
            }
            fprintf(flp, "\n");
        }
        fprintf(flp, "\n");
    }
    gmx_ffclose(flp);

    if (bCALCDIV)
    {
        printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0/norm);
        printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval*norm/numfr, maxval*norm/numfr);
    }
    else
    {
        printf("grid.cube contains counts per frame in all %d cubes\n", numcu);
        printf("Raw data: average %le, min %le, max %le\n", 1.0/norm, static_cast<double>(minval)/numfr, static_cast<double>(maxval)/numfr);
    }

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

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

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &x_ref, NULL, box, bMW);

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

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

    ffclose(out);

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

    return 0;
}
Exemple #30
0
int gmx_spol(int argc, char *argv[])
{
    t_topology  *top;
    t_inputrec  *ir;
    t_atom      *atom;
    char         title[STRLEN];
    t_trxstatus *status;
    int          nrefat, natoms, nf, ntot;
    real         t;
    rvec        *xtop, *x, xref, trial, dx = {0}, dip, dir;
    matrix       box;

    FILE        *fp;
    int         *isize, nrefgrp;
    atom_id    **index, *molindex;
    char       **grpname;
    real         rmin2, rmax2, rcut, rcut2, rdx2 = 0, rtry2, qav, q, dip2, invbw;
    int          nbin, i, m, mol, a0, a1, a, d;
    double       sdip, sdip2, sinp, sdinp, nmol;
    int         *hist;
    t_pbc        pbc;
    gmx_rmpbc_t  gpbc = NULL;


    const char     *desc[] = {
        "[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, bPBC = FALSE;
    static int      srefat = 1;
    static real     rmin   = 0.0, rmax = 0.32, refdip = 0, bw = 0.01;
    t_pargs         pa[]   = {
        { "-com",  FALSE, etBOOL,  {&bCom},
          "Use the center of mass as the reference postion" },
        { "-refat",  FALSE, etINT, {&srefat},
          "The reference atom of the solvent molecule" },
        { "-rmin",  FALSE, etREAL, {&rmin}, "Maximum distance (nm)" },
        { "-rmax",  FALSE, etREAL, {&rmax}, "Maximum distance (nm)" },
        { "-dip",   FALSE, etREAL, {&refdip}, "The average dipole (D)" },
        { "-bw",    FALSE, etREAL, {&bw}, "The bin width" }
    };

    t_filenm        fnm[] = {
        { efTRX, NULL,  NULL,  ffREAD },
        { efTPX, NULL,  NULL,  ffREAD },
        { efNDX, NULL,  NULL,  ffOPTRD },
        { efXVG, NULL,  "scdist.xvg",  ffWRITE }
    };
#define NFILE asize(fnm)

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

    snew(top, 1);
    snew(ir, 1);
    read_tpx_top(ftp2fn(efTPX, NFILE, fnm),
                 ir, box, &natoms, NULL, NULL, NULL, top);

    /* get index groups */
    printf("Select a group of reference particles and a solvent group:\n");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpname);

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

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

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

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

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

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

    molindex = top->mols.index;
    atom     = top->atoms.atom;

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

    /* 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[(int)(sqrt(rdx2)*invbw)+1]++;
            }
            if (rdx2 >= rmin2 && rdx2 < rmax2)
            {
                unitv(dx, dx);
                clear_rvec(dip);
                qav = 0;
                for (a = a0; a < a1; a++)
                {
                    qav += atom[a].q;
                }
                qav /= (a1 - a0);
                for (a = a0; a < a1; a++)
                {
                    q = atom[a].q - qav;
                    for (d = 0; d < DIM; d++)
                    {
                        dip[d] += q*x[a][d];
                    }
                }
                for (d = 0; d < DIM; d++)
                {
                    dir[d] = -x[a0][d];
                }
                for (a = a0+1; a < a0+3; a++)
                {
                    for (d = 0; d < DIM; d++)
                    {
                        dir[d] += 0.5*x[a][d];
                    }
                }
                unitv(dir, dir);

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

                ntot++;
            }
        }
        nf++;

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

    gmx_rmpbc_done(gpbc);

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

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

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

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

    return 0;
}