Пример #1
0
SelectionData::SelectionData(SelectionTreeElement *elem,
                             const char           *selstr)
    : name_(elem->name()), selectionText_(selstr),
      rootElement_(*elem), coveredFractionType_(CFRAC_NONE),
      coveredFraction_(1.0), averageCoveredFraction_(1.0),
      bDynamic_(false), bDynamicCoveredFraction_(false)
{
    gmx_ana_pos_clear(&rawPositions_);

    if (elem->child->type == SEL_CONST)
    {
        // TODO: This is not exception-safe if any called function throws.
        gmx_ana_pos_copy(&rawPositions_, elem->child->v.u.p, true);
    }
    else
    {
        SelectionTreeElementPointer child = elem->child;
        child->flags     &= ~SEL_ALLOCVAL;
        _gmx_selvalue_setstore(&child->v, &rawPositions_);
        /* We should also skip any modifiers to determine the dynamic
         * status. */
        while (child->type == SEL_MODIFIER)
        {
            child = child->child;
            if (child->type == SEL_SUBEXPRREF)
            {
                child = child->child;
                /* Because most subexpression elements are created
                 * during compilation, we need to check for them
                 * explicitly here.
                 */
                if (child->type == SEL_SUBEXPR)
                {
                    child = child->child;
                }
            }
        }
        /* For variable references, we should skip the
         * SEL_SUBEXPRREF and SEL_SUBEXPR elements. */
        if (child->type == SEL_SUBEXPRREF)
        {
            child = child->child->child;
        }
        bDynamic_ = (child->child->flags & SEL_DYNAMIC);
    }
    initCoveredFraction(CFRAC_NONE);
}
Пример #2
0
/*!
 * \param[in]     top   Topology data structure.
 * \param[in,out] out   Pointer to output data structure.
 * \param[in,out] data  Should point to \c t_methoddata_permute.
 */
static void
init_output_permute(t_topology *top, gmx_ana_selvalue_t *out, void *data)
{
    t_methoddata_permute *d = (t_methoddata_permute *)data;
    int                   i, j, b;

    gmx_ana_pos_copy(out->u.p, &d->p, true);
    gmx_ana_pos_set_evalgrp(out->u.p, &d->g);
    d->g.isize = 0;
    gmx_ana_pos_empty_init(out->u.p);
    for (i = 0; i < d->p.nr; i += d->n)
    {
        for (j = 0; j < d->n; ++j)
        {
            b = i + d->rperm[j];
            gmx_ana_pos_append_init(out->u.p, &d->g, &d->p, b);
        }
    }
}
Пример #3
0
/*!
 * \param[in,out] sc    Selection collection to append to.
 * \param         sel   Selection to append to \p sc (can be NULL, in which
 *   case nothing is done).
 * \param         last  Last selection in \p sc, or NULL if not present or not
 *   known.
 * \returns       The last selection in \p sc after the append.
 *
 * Appends \p sel after the last root element in \p sc, and returns either
 * \p sel (if it was non-NULL) or the last element in \p sc (if \p sel was
 * NULL).
 */
t_selelem *
_gmx_sel_append_selection(gmx_ana_selcollection_t *sc, t_selelem *sel,
                          t_selelem *last)
{
    if (last)
    {
        last->next = sel;
    }
    else
    {
        if (sc->root)
        {
            last = sc->root;
            while (last->next)
            {
                last = last->next;
            }
            last->next = sel;
        }
        else
        {
            sc->root = sel;
        }
    }
    if (sel)
    {
        last = sel;
        /* Add the new selection to the collection if it is not a variable. */
        if (sel->child->type != SEL_SUBEXPR)
        {
            int        i;

            sc->nr++;
            srenew(sc->sel, sc->nr);
            i = sc->nr - 1;
            snew(sc->sel[i], 1);

            if (sel->child->type == SEL_CONST)
            {
                gmx_ana_pos_copy(&sc->sel[i]->p, sel->child->v.u.p, TRUE);
                sc->sel[i]->bDynamic = FALSE;
            }
            else
            {
                t_selelem *child;

                child = sel->child;
                child->flags     &= ~SEL_ALLOCVAL;
                _gmx_selvalue_setstore(&child->v, &sc->sel[i]->p);
                /* We should also skip any modifiers to determine the dynamic
                 * status. */
                while (child->type == SEL_MODIFIER)
                {
                    child = child->child;
                }
                /* For variable references, we should skip the
                 * SEL_SUBEXPRREF and SEL_SUBEXPR elements. */
                if (child->type == SEL_SUBEXPRREF)
                {
                    child = child->child->child;
                }
                sc->sel[i]->bDynamic = (child->child->flags & SEL_DYNAMIC);
            }
            /* The group will be set after compilation */
            sc->sel[i]->g        = NULL;
            sc->sel[i]->selelem  = sel;
            gmx_ana_selection_init_coverfrac(sc->sel[i], CFRAC_NONE);
        }
    }
    return last;
}
Пример #4
0
/*!
 * \param[in] data Data for the current frame.
 * \param[in] sel Selection element being evaluated.
 * \param[in] g   Group for which \p sel should be evaluated.
 * \returns   0 on success, a non-zero error code on error.
 *
 * If the value type is \ref POS_VALUE, the value of the child is simply
 * copied to set the value of \p sel (the child subexpression should
 * already have been evaluated by its root).
 * If the value type is something else, the child is evaluated for the
 * group \p g, and the value of the child is then copied.
 * There should be only one child element.
 *
 * This function is used as \c t_selelem::evaluate for \ref SEL_SUBEXPRREF
 * elements.
 */
void
_gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
{
    t_selelem *expr;
    int        i, j;

    if (g)
    {
        sel->child->evaluate(data, sel->child, g);
    }
    expr = sel->child;
    switch (sel->v.type)
    {
        case INT_VALUE:
            if (!g)
            {
                sel->v.nr = expr->v.nr;
                memcpy(sel->v.u.i, expr->v.u.i, sel->v.nr*sizeof(*sel->v.u.i));
            }
            else
            {
                sel->v.nr = g->isize;
                /* Extract the values corresponding to g */
                for (i = j = 0; i < g->isize; ++i, ++j)
                {
                    while (sel->child->u.cgrp.index[j] < g->index[i])
                    {
                        ++j;
                    }
                    sel->v.u.i[i] = expr->v.u.i[j];
                }
            }
            break;

        case REAL_VALUE:
            if (!g)
            {
                sel->v.nr = expr->v.nr;
                memcpy(sel->v.u.r, expr->v.u.r, sel->v.nr*sizeof(*sel->v.u.r));
            }
            else
            {
                sel->v.nr = g->isize;
                /* Extract the values corresponding to g */
                for (i = j = 0; i < g->isize; ++i, ++j)
                {
                    while (sel->child->u.cgrp.index[j] < g->index[i])
                    {
                        ++j;
                    }
                    sel->v.u.r[i] = expr->v.u.r[j];
                }
            }
            break;

        case STR_VALUE:
            if (!g)
            {
                sel->v.nr = expr->v.nr;
                memcpy(sel->v.u.s, expr->v.u.s, sel->v.nr*sizeof(*sel->v.u.s));
            }
            else
            {
                sel->v.nr = g->isize;
                /* Extract the values corresponding to g */
                for (i = j = 0; i < g->isize; ++i, ++j)
                {
                    while (sel->child->u.cgrp.index[j] < g->index[i])
                    {
                        ++j;
                    }
                    sel->v.u.s[i] = expr->v.u.s[j];
                }
            }
            break;

        case POS_VALUE:
            /* Currently, there is no need to do anything fancy here,
             * but some future extensions may need a more flexible
             * implementation. */
            gmx_ana_pos_copy(sel->v.u.p, expr->v.u.p, false);
            break;

        case GROUP_VALUE:
            if (!g)
            {
                gmx_ana_index_copy(sel->v.u.g, expr->v.u.g, false);
            }
            else
            {
                gmx_ana_index_intersection(sel->v.u.g, expr->v.u.g, g);
            }
            break;

        default: /* should not be reached */
            GMX_THROW(gmx::InternalError("Invalid subexpression reference type"));
    }
    /* Store the number of values if needed */
    if (sel->u.param)
    {
        sel->u.param->val.nr = sel->v.nr;
        if (sel->u.param->nvalptr)
        {
            *sel->u.param->nvalptr = sel->u.param->val.nr;
        }
    }
}