Пример #1
0
/*!
 * \param[in]  pc  Position calculation data structure.
 * \param[out] p   Output positions.
 *
 * Calls to gmx_ana_poscalc_update() using \p pc should use only positions
 * initialized with this function.
 * The \c p->g pointer is initialized to point to an internal group that
 * contains the maximum index group set with gmx_ana_poscalc_set_maxindex().
 */
void
gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p)
{
    e_index_t          ptype;

    ptype = index_type_for_poscalc(pc->type);
    gmx_ana_indexmap_init(&p->m, &pc->gmax, pc->coll->top, ptype);
    gmx_ana_pos_reserve(p, p->m.nr, 0);
    p->g = &pc->gmax;
}
Пример #2
0
/*!
 * \param[out]    pos  Position data structure to initialize.
 * \param[in]     x    Position vector to use.
 */
void
gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x)
{
    snew(pos->x, 1);
    snew(pos->v, 1);
    snew(pos->f, 1);
    pos->nalloc_x = 1;
    copy_rvec(x, pos->x[0]);
    clear_rvec(pos->v[0]);
    clear_rvec(pos->f[0]);
    gmx_ana_indexmap_init(&pos->m, NULL, NULL, INDEX_UNKNOWN);
}
Пример #3
0
/*!
 * \param[in]  pc  Position calculation data structure.
 * \param[out] p   Output positions.
 *
 * Calls to gmx_ana_poscalc_update() using \p pc should use only positions
 * initialized with this function.
 * The \c p->g pointer is initialized to point to an internal group that
 * contains the maximum index group set with gmx_ana_poscalc_set_maxindex().
 */
void
gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p)
{
    gmx_ana_indexmap_init(&p->m, &pc->gmax, pc->coll->top_, pc->itype);
    /* Only do the static optimization when there is no completion */
    if (!(pc->flags & POS_DYNAMIC) && pc->b.nra == pc->gmax.isize)
    {
        gmx_ana_indexmap_set_static(&p->m, &pc->b);
    }
    gmx_ana_pos_reserve(p, p->m.mapb.nr, 0);
    if (pc->flags & POS_VELOCITIES)
    {
        gmx_ana_pos_reserve_velocities(p);
    }
    if (pc->flags & POS_FORCES)
    {
        gmx_ana_pos_reserve_forces(p);
    }
}
Пример #4
0
int
gmx_select(int argc, char *argv[])
{
    const char *desc[] = {
        "g_select writes out basic data about dynamic selections.",
        "It can be used for some simple analyses, or the output can",
        "be combined with output from other programs and/or external",
        "analysis programs to calculate more complex things.",
        "Any combination of the output options is possible, but note",
        "that [TT]-om[tt] only operates on the first selection.[PAR]",
        "With [TT]-os[tt], calculates the number of positions in each",
        "selection for each frame. With [TT]-norm[tt], the output is",
        "between 0 and 1 and describes the fraction from the maximum",
        "number of positions (e.g., for selection 'resname RA and x < 5'",
        "the maximum number of positions is the number of atoms in",
        "RA residues). With [TT]-cfnorm[tt], the output is divided",
        "by the fraction covered by the selection.",
        "[TT]-norm[tt] and [TT]-cfnorm[tt] can be specified independently",
        "of one another.[PAR]",
        "With [TT]-oc[tt], the fraction covered by each selection is",
        "written out as a function of time.[PAR]",
        "With [TT]-oi[tt], the selected atoms/residues/molecules are",
        "written out as a function of time. In the output, the first",
        "column contains the frame time, the second contains the number",
        "of positions, followed by the atom/residue/molecule numbers.",
        "If more than one selection is specified, the size of the second",
        "group immediately follows the last number of the first group",
        "and so on. With [TT]-dump[tt], the frame time and the number",
        "of positions is omitted from the output. In this case, only one",
        "selection can be given.[PAR]",
        "With [TT]-om[tt], a mask is printed for the first selection",
        "as a function of time. Each line in the output corresponds to",
        "one frame, and contains either 0/1 for each atom/residue/molecule",
        "possibly selected. 1 stands for the atom/residue/molecule being",
        "selected for the current frame, 0 for not selected.",
        "With [TT]-dump[tt], the frame time is omitted from the output.",
    };

    bool                bDump     = FALSE;
    bool                bFracNorm = FALSE;
    bool                bTotNorm  = FALSE;
    t_pargs             pa[] = {
        {"-dump",   FALSE, etBOOL, {&bDump},
         "Do not print the frame time (-om, -oi) or the index size (-oi)"},
        {"-norm",   FALSE, etBOOL, {&bTotNorm},
         "Normalize by total number of positions with -os"},
        {"-cfnorm", FALSE, etBOOL, {&bFracNorm},
         "Normalize by covered fraction with -os"},
    };

    t_filenm            fnm[] = {
        {efXVG, "-os", "size.xvg",  ffOPTWR},
        {efXVG, "-oc", "cfrac.xvg", ffOPTWR},
        {efDAT, "-oi", "index.dat", ffOPTWR},
        {efDAT, "-om", "mask.dat",  ffOPTWR},
    };
#define NFILE asize(fnm)

    gmx_ana_traj_t       *trj;
    t_topology           *top;
    int                   ngrps;
    gmx_ana_selection_t **sel;
    char                **grpnames;
    t_dsdata              d;
    char                 *fnSize, *fnFrac, *fnIndex, *fnMask;
    int                   g;
    int                   rc;

    CopyRight(stderr, argv[0]);
    gmx_ana_traj_create(&trj, 0);
    gmx_ana_set_nanagrps(trj, -1);
    parse_trjana_args(trj, &argc, argv, 0,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL);
    gmx_ana_get_nanagrps(trj, &ngrps);
    gmx_ana_get_anagrps(trj, &sel);
    gmx_ana_init_coverfrac(trj, CFRAC_SOLIDANGLE);

    /* Get output file names */
    fnSize  = opt2fn_null("-os", NFILE, fnm);
    fnFrac  = opt2fn_null("-oc", NFILE, fnm);
    fnIndex = opt2fn_null("-oi", NFILE, fnm);
    fnMask  = opt2fn_null("-om", NFILE, fnm);
    /* Write out sizes if nothing specified */
    if (!fnFrac && !fnIndex && !fnMask)
    {
        fnSize = opt2fn("-os", NFILE, fnm);
    }

    if (bDump && ngrps > 1)
    {
        gmx_fatal(FARGS, "Only one index group allowed with -dump");
    }
    if (fnMask && ngrps > 1)
    {
        fprintf(stderr, "warning: the mask (-om) will only be written for the first group\n");
    }
    if (fnMask && !sel[0]->bDynamic)
    {
        fprintf(stderr, "warning: will not write the mask (-om) for a static selection\n");
        fnMask = NULL;
    }

    /* Initialize reference calculation for masks */
    if (fnMask)
    {
        gmx_ana_get_topology(trj, FALSE, &top, NULL);
        snew(d.mmap, 1);
        gmx_ana_indexmap_init(d.mmap, sel[0]->g, top, sel[0]->p.m.type);
    }

    /* Initialize calculation data */
    d.bDump     = bDump;
    d.bFracNorm = bFracNorm;
    snew(d.size,  ngrps);
    for (g = 0; g < ngrps; ++g)
    {
        d.size[g] = bTotNorm ? sel[g]->p.nr : 1;
    }

    /* Open output files */
    d.sfp = d.cfp = d.ifp = d.mfp = NULL;
    gmx_ana_get_grpnames(trj, &grpnames);
    if (fnSize)
    {
        d.sfp = xvgropen(fnSize, "Selection size", "Time (ps)", "Number");
        xvgr_selections(d.sfp, trj);
        xvgr_legend(d.sfp, ngrps, grpnames);
    }
    if (fnFrac)
    {
        d.cfp = xvgropen(fnFrac, "Covered fraction", "Time (ps)", "Fraction");
        xvgr_selections(d.cfp, trj);
        xvgr_legend(d.cfp, ngrps, grpnames);
    }
    if (fnIndex)
    {
        d.ifp = ffopen(fnIndex, "w");
        xvgr_selections(d.ifp, trj);
    }
    if (fnMask)
    {
        d.mfp = ffopen(fnMask, "w");
        xvgr_selections(d.mfp, trj);
    }

    /* Do the analysis and write out results */
    gmx_ana_do(trj, 0, &print_data, &d);

    /* Close the files */
    if (d.sfp)
    {
        fclose(d.sfp);
    }
    if (d.cfp)
    {
        fclose(d.cfp);
    }
    if (d.ifp)
    {
        fclose(d.ifp);
    }
    if (d.mfp)
    {
        fclose(d.mfp);
    }

    thanx(stderr);

    return 0;
}
Пример #5
0
/*! \brief
 * Parses the values for a parameter that takes a variable number of values.
 * 
 * \param[in] nval   Number of values in \p values.
 * \param[in] values Pointer to the list of values.
 * \param     param  Parameter to parse.
 * \param     root   Selection element to which child expressions are added.
 * \returns   TRUE if the values were parsed successfully, FALSE otherwise.
 *
 * For integer ranges, the sequence of numbers from the first to second value
 * is stored, each as a separate value.
 */
static gmx_bool
parse_values_varnum(int nval, t_selexpr_value *values,
                    gmx_ana_selparam_t *param, t_selelem *root)
{
    t_selexpr_value    *value;
    int                 i, j;

    param->flags &= ~SPAR_DYNAMIC;
    /* Update nval if there are integer ranges. */
    if (param->val.type == INT_VALUE)
    {
        value = values;
        while (value)
        {
            if (value->type == INT_VALUE && !value->bExpr)
            {
                nval += abs(value->u.i.i2 - value->u.i.i1);
            }
            value = value->next;
        }
    }

    /* Check that the value type is actually implemented */
    if (param->val.type != INT_VALUE && param->val.type != REAL_VALUE
        && param->val.type != STR_VALUE && param->val.type != POS_VALUE)
    {
        gmx_bug("internal error");
        return FALSE;
    }

    /* Reserve appropriate amount of memory */
    if (param->val.type == POS_VALUE)
    {
        gmx_ana_pos_reserve(param->val.u.p, nval, 0);
        gmx_ana_pos_set_nr(param->val.u.p, nval);
        gmx_ana_indexmap_init(&param->val.u.p->m, NULL, NULL, INDEX_UNKNOWN);
    }
    else
    {
        _gmx_selvalue_reserve(&param->val, nval);
    }

    value = values;
    i     = 0;
    while (value)
    {
        if (value->bExpr)
        {
            _gmx_selparser_error("expressions not supported within value lists");
            return FALSE;
        }
        if (value->type != param->val.type)
        {
            gmx_bug("internal error");
            return FALSE;
        }
        switch (param->val.type)
        {
            case INT_VALUE:
                if (value->u.i.i1 <= value->u.i.i2)
                {
                    for (j = value->u.i.i1; j <= value->u.i.i2; ++j)
                    {
                        param->val.u.i[i++] = j;
                    }
                }
                else
                {
                    for (j = value->u.i.i1; j >= value->u.i.i2; --j)
                    {
                        param->val.u.i[i++] = j;
                    }
                }
                break;
            case REAL_VALUE:
                if (value->u.r.r1 != value->u.r.r2)
                {
                    _gmx_selparser_error("real ranges not supported for parameter '%s'", param->name);
                    return FALSE;
                }
                param->val.u.r[i++] = value->u.r.r1;
                break;
            case STR_VALUE:  param->val.u.s[i++] = strdup(value->u.s); break;
            case POS_VALUE:  copy_rvec(value->u.x, param->val.u.p->x[i++]); break;
            default: /* Should not be reached */
                gmx_bug("internal error");
                return FALSE;
        }
        value = value->next;
    }
    param->val.nr = i;
    if (param->nvalptr)
    {
        *param->nvalptr = param->val.nr;
    }
    param->nvalptr = NULL;
    /* Create a dummy child element to store the string values.
     * This element is responsible for freeing the values, but carries no
     * other function. */
    if (param->val.type == STR_VALUE)
    {
        t_selelem *child;

        child = _gmx_selelem_create(SEL_CONST);
        _gmx_selelem_set_vtype(child, STR_VALUE);
        child->name = param->name;
        child->flags &= ~SEL_ALLOCVAL;
        child->flags |= SEL_FLAGSSET | SEL_VARNUMVAL | SEL_ALLOCDATA;
        child->v.nr = param->val.nr;
        _gmx_selvalue_setstore(&child->v, param->val.u.s);
        /* Because the child is not group-valued, the u union is not used
         * for anything, so we can abuse it by storing the parameter value
         * as place_child() expects, but this is really ugly... */
        child->u.param = param;
        place_child(root, child, param);
    }

    return TRUE;
}