/*
+ * This file is part of the GROMACS molecular simulation package.
*
- * This source code is part of
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
*
- * G R O M A C S
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
*
- * GROningen MAchine for Chemical Simulations
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
*
* To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
+ * the research papers on the package. Check out http://www.gromacs.org.
*/
/*! \internal \file
* \brief
* converting selections by residue/molecule into selections by atom
* when necessary.
*
- * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_selection
*/
-#include <string.h>
+#include "gmxpre.h"
-#include "gromacs/legacyheaders/maths.h"
-#include "gromacs/legacyheaders/smalloc.h"
-#include "gromacs/legacyheaders/vec.h"
+#include "evaluate.h"
+#include <string.h>
+
+#include "gromacs/math/utilities.h"
+#include "gromacs/math/vec.h"
#include "gromacs/selection/indexutil.h"
-#include "gromacs/selection/poscalc.h"
#include "gromacs/selection/selection.h"
-#include "gromacs/selection/selmethod.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/smalloc.h"
-#include "evaluate.h"
#include "mempool.h"
+#include "poscalc.h"
#include "selectioncollection-impl.h"
#include "selelem.h"
+#include "selmethod.h"
using gmx::SelectionTreeElement;
using gmx::SelectionTreeElementPointer;
namespace
{
-/*! \internal \brief
+/*! \brief
* Reserves memory for a selection element from the evaluation memory pool.
*
* This class implements RAII semantics for allocating memory for selection
void reserve(const SelectionTreeElementPointer &sel, int count)
{
GMX_RELEASE_ASSERT(!sel_,
- "Can only reserve one element with one instance");
+ "Can only reserve one element with one instance");
sel->mempoolReserve(count);
sel_ = sel;
}
SelectionTreeElementPointer sel_;
};
-/*! \internal \brief
+/*! \brief
* Reserves memory for an index group from the evaluation memory pool.
*
* This class implements RAII semantics for allocating memory for an index
gmx_ana_index_t *g_;
};
-/*! \internal \brief
+/*! \brief
* Assigns a temporary value for a selection element.
*
* This class implements RAII semantics for temporarily assigning the value
* \see assign()
*/
SelelemTemporaryValueAssigner(const SelectionTreeElementPointer &sel,
- const SelectionTreeElement &vsource)
+ const SelectionTreeElement &vsource)
{
assign(sel, vsource);
}
* actually accesses values in \p vsource.
*/
void assign(const SelectionTreeElementPointer &sel,
- const SelectionTreeElement &vsource)
+ const SelectionTreeElement &vsource)
{
GMX_RELEASE_ASSERT(!sel_,
"Can only assign one element with one instance");
GMX_RELEASE_ASSERT(sel->v.type == vsource.v.type,
"Mismatching selection value types");
- old_ptr_ = sel->v.u.ptr;
+ old_ptr_ = sel->v.u.ptr;
old_nalloc_ = sel->v.nalloc;
_gmx_selvalue_setstore(&sel->v, vsource.v.u.ptr);
sel_ = sel;
_gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc)
{
if (!evalfunc)
+ {
fprintf(fp, "none");
+ }
else if (evalfunc == &_gmx_sel_evaluate_root)
+ {
fprintf(fp, "root");
+ }
else if (evalfunc == &_gmx_sel_evaluate_static)
+ {
fprintf(fp, "static");
+ }
else if (evalfunc == &_gmx_sel_evaluate_subexpr_simple)
+ {
fprintf(fp, "subexpr_simple");
+ }
else if (evalfunc == &_gmx_sel_evaluate_subexpr_staticeval)
+ {
fprintf(fp, "subexpr_staticeval");
+ }
else if (evalfunc == &_gmx_sel_evaluate_subexpr)
+ {
fprintf(fp, "subexpr");
+ }
else if (evalfunc == &_gmx_sel_evaluate_subexprref_simple)
+ {
fprintf(fp, "ref_simple");
+ }
else if (evalfunc == &_gmx_sel_evaluate_subexprref)
+ {
fprintf(fp, "ref");
+ }
else if (evalfunc == &_gmx_sel_evaluate_method)
+ {
fprintf(fp, "method");
+ }
else if (evalfunc == &_gmx_sel_evaluate_modifier)
+ {
fprintf(fp, "mod");
+ }
else if (evalfunc == &_gmx_sel_evaluate_not)
+ {
fprintf(fp, "not");
+ }
else if (evalfunc == &_gmx_sel_evaluate_and)
+ {
fprintf(fp, "and");
+ }
else if (evalfunc == &_gmx_sel_evaluate_or)
+ {
fprintf(fp, "or");
+ }
else if (evalfunc == &_gmx_sel_evaluate_arithmetic)
+ {
fprintf(fp, "arithmetic");
+ }
else
+ {
fprintf(fp, "%p", (void*)(evalfunc));
+ }
}
/*!
t_trxframe *fr, t_pbc *pbc)
{
gmx_ana_selcollection_t *sc = &coll->impl_->sc_;
- gmx_sel_evaluate_t data;
+ gmx_sel_evaluate_t data;
_gmx_sel_evaluate_init(&data, sc->mempool, &sc->gall, sc->top, fr, pbc);
init_frame_eval(sc->root);
while (sel)
{
/* Clear the evaluation group of subexpressions */
- if (sel->child && sel->child->type == SEL_SUBEXPR)
+ if (sel->child && sel->child->type == SEL_SUBEXPR
+ && sel->child->evaluate != NULL)
{
sel->child->u.cgrp.isize = 0;
/* Not strictly necessary, because the value will be overwritten
* during first evaluation of the subexpression anyways, but we
* clear the group for clarity. Note that this is _not_ done during
* compilation because of some additional complexities involved
- * (see compiler.c), so it should not be relied upon in
+ * (see compiler.cpp), so it should not be relied upon in
* _gmx_sel_evaluate_subexpr(). */
if (sel->child->v.type == GROUP_VALUE)
{
for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
{
internal::SelectionData &sel = **isel;
- sel.refreshMassesAndCharges();
+ sel.refreshMassesAndCharges(sc->top);
sel.updateCoveredFractionForFrame();
}
}
void
SelectionEvaluator::evaluateFinal(SelectionCollection *coll, int nframes)
{
- gmx_ana_selcollection_t *sc = &coll->impl_->sc_;
+ gmx_ana_selcollection_t *sc = &coll->impl_->sc_;
SelectionDataList::const_iterator isel;
for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
{
internal::SelectionData &sel = **isel;
- sel.restoreOriginalPositions();
+ sel.restoreOriginalPositions(sc->top);
sel.computeAverageCoveredFraction(nframes);
}
}
* Evaluates each child of \p sel in \p g.
*/
void
-_gmx_sel_evaluate_children(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_children(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
SelectionTreeElementPointer child = sel->child;
while (child)
}
}
-/*!
- * \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
- * (not used, can be NULL).
- * \returns 0 on success, a non-zero error code on error.
- *
- * Evaluates the first child element in the group defined by \p sel->u.cgrp.
- * If \p sel->u.cgrp is empty, nothing is done.
- * The value of \p sel is not touched (root elements do not evaluate to
- * values).
- *
- * This function can be used as gmx::SelectionTreeElement::evaluate for
- * \ref SEL_ROOT elements.
- */
void
-_gmx_sel_evaluate_root(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_root(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t * /* g */)
{
if (sel->u.cgrp.isize == 0 || !sel->child->evaluate)
{
sel->u.cgrp.isize < 0 ? NULL : &sel->u.cgrp);
}
-/*!
- * \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 for success.
- *
- * Sets the value of \p sel to the intersection of \p g and \p sel->u.cgrp.
- *
- * This function can be used as gmx::SelectionTreeElement::evaluate for
- * \ref SEL_CONST elements with value type \ref GROUP_VALUE.
- */
void
-_gmx_sel_evaluate_static(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_static(gmx_sel_evaluate_t * /* data */,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
- gmx_ana_index_intersection(sel->v.u.g, &sel->u.cgrp, g);
+ if (sel->flags & SEL_UNSORTED)
+ {
+ // This only works if g contains all the atoms, but that is currently
+ // the only supported case.
+ gmx_ana_index_copy(sel->v.u.g, &sel->u.cgrp, false);
+ }
+ else
+ {
+ gmx_ana_index_intersection(sel->v.u.g, &sel->u.cgrp, g);
+ }
}
* full subexpression handling.
*/
void
-_gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
if (sel->child->evaluate)
{
* not need full subexpression handling.
*/
void
-_gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
if (sel->u.cgrp.isize == 0)
{
}
else
{
- gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, sel->u.cgrp.name, 0);
+ gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, 0);
}
}
}
* major problem.
*/
void
-_gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
- gmx_ana_index_t gmiss;
+ gmx_ana_index_t gmiss;
MempoolGroupReserver gmissreserver(data->mp);
if (sel->u.cgrp.isize == 0)
SelelemTemporaryValueAssigner assigner(sel->child, *sel);
sel->child->evaluate(data, sel->child, g);
}
- /* We need to keep the name for the cgrp across the copy to avoid
- * problems if g has a name set. */
- char *name = sel->u.cgrp.name;
gmx_ana_index_copy(&sel->u.cgrp, g, false);
- sel->u.cgrp.name = name;
- gmiss.isize = 0;
+ gmiss.isize = 0;
}
else
{
gmissreserver.reserve(&gmiss, g->isize);
gmx_ana_index_difference(&gmiss, g, &sel->u.cgrp);
- gmiss.name = NULL;
}
if (gmiss.isize > 0)
{
* other references.
*/
void
-_gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
if (g)
{
* \ref SEL_SUBEXPRREF elements.
*/
void
-_gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
int i, j;
- if (g)
+ if (g != NULL && sel->child->evaluate != NULL)
{
sel->child->evaluate(data, sel->child, g);
}
* but is used internally.
*/
void
-_gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
SelectionTreeElementPointer child = sel->child;
while (child)
* \ref SEL_EXPRESSION elements.
*/
void
-_gmx_sel_evaluate_method(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_method(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
_gmx_sel_evaluate_method_params(data, sel, g);
if (sel->flags & SEL_INITFRAME)
* \ref SEL_MODIFIER elements.
*/
void
-_gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
_gmx_sel_evaluate_method_params(data, sel, g);
if (sel->flags & SEL_INITFRAME)
{
sel->flags &= ~SEL_INITFRAME;
sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
- sel->u.expr.mdata);
+ sel->u.expr.mdata);
}
GMX_RELEASE_ASSERT(sel->child != NULL,
"Modifier element with a value must have a child");
* \returns 0 on success, a non-zero error code on error.
*
* Evaluates the child element (there should be only one) in the group
- * \p g, and then sets the value of \p sel to the complement of the
+ * \p g, and then sets the value of \p sel to the complement of the
* child value.
*
* This function is used as gmx::SelectionTreeElement::evaluate for
* \ref SEL_BOOLEAN elements with \ref BOOL_NOT.
*/
void
-_gmx_sel_evaluate_not(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_not(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
MempoolSelelemReserver reserver(sel->child, g->isize);
sel->child->evaluate(data, sel->child, g);
* \ref SEL_BOOLEAN elements with \ref BOOL_AND.
*/
void
-_gmx_sel_evaluate_and(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_and(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
SelectionTreeElementPointer child = sel->child;
/* Skip the first child if it does not have an evaluation function. */
* \ref SEL_BOOLEAN elements with \ref BOOL_OR.
*/
void
-_gmx_sel_evaluate_or(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_or(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
- gmx_ana_index_t tmp, tmp2;
+ gmx_ana_index_t tmp, tmp2;
SelectionTreeElementPointer child = sel->child;
if (child->evaluate)
child = child->next;
while (child && tmp.isize > 0)
{
- tmp.name = NULL;
{
MempoolSelelemReserver reserver(child, tmp.isize);
child->evaluate(data, child, &tmp);
gmx_ana_index_partition(&tmp, &tmp2, &tmp, child->v.u.g);
}
sel->v.u.g->isize += tmp.isize;
- tmp.isize = tmp2.isize;
- tmp.index = tmp2.index;
- child = child->next;
+ tmp.isize = tmp2.isize;
+ tmp.index = tmp2.index;
+ child = child->next;
}
gmx_ana_index_sort(sel->v.u.g);
}
* \returns 0 on success, a non-zero error code on error.
*/
void
-_gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data,
- const SelectionTreeElementPointer &sel,
- gmx_ana_index_t *g)
+_gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data,
+ const gmx::SelectionTreeElementPointer &sel,
+ gmx_ana_index_t *g)
{
int n, i, i1, i2;
- real lval, rval=0., val=0.;
+ real lval, rval = 0., val = 0.;
const SelectionTreeElementPointer &left = sel->child;
const SelectionTreeElementPointer &right = left->next;
- SelelemTemporaryValueAssigner assigner;
- MempoolSelelemReserver reserver;
+ SelelemTemporaryValueAssigner assigner;
+ MempoolSelelemReserver reserver;
if (left->mempool)
{
assigner.assign(left, *sel);
}
_gmx_sel_evaluate_children(data, sel, g);
- n = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize;
+ n = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize;
sel->v.nr = n;
bool bArithNeg = (sel->u.arith.type == ARITH_NEG);