Gromacs  2021.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Functions
#include "gmxpre.h"
#include "evaluate.h"
#include <cstring>
#include <algorithm>
#include "gromacs/math/utilities.h"
#include "gromacs/math/vec.h"
#include "gromacs/selection/indexutil.h"
#include "gromacs/selection/selection.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
#include "mempool.h"
#include "poscalc.h"
#include "selectioncollection_impl.h"
#include "selelem.h"
#include "selmethod.h"
+ Include dependency graph for evaluate.cpp:

Description

Implements functions in evaluate.h.

Todo:
One of the major bottlenecks for selection performance is that all the evaluation is carried out for atoms. There are several cases when the evaluation could be done for residues or molecules instead, including keywords that select by residue and cases where residue centers are used as reference positions. Implementing this would require a mechanism for recognizing whether something can be evaluated by residue/molecule instead by atom, and converting selections by residue/molecule into selections by atom when necessary.
Author
Teemu Murtola teemu.nosp@m..mur.nosp@m.tola@.nosp@m.gmai.nosp@m.l.com

Classes

class  anonymous_namespace{evaluate.cpp}::MempoolSelelemReserver
 Reserves memory for a selection element from the evaluation memory pool. More...
 
class  anonymous_namespace{evaluate.cpp}::MempoolGroupReserver
 Reserves memory for an index group from the evaluation memory pool. More...
 
class  anonymous_namespace{evaluate.cpp}::SelelemTemporaryValueAssigner
 Assigns a temporary value for a selection element. More...
 

Functions

template<typename T >
void anonymous_namespace{evaluate.cpp}::expandValueForPositions (T value[], int *nr, gmx_ana_pos_t *pos)
 Expands a value array from one-per-position to one-per-atom. More...
 
void _gmx_sel_print_evalfunc_name (FILE *fp, gmx::sel_evalfunc evalfunc)
 Writes out a human-readable name for an evaluation function. More...
 
void _gmx_sel_evaluate_init (gmx_sel_evaluate_t *data, gmx_sel_mempool_t *mp, gmx_ana_index_t *gall, const gmx_mtop_t *top, t_trxframe *fr, t_pbc *pbc)
 Initializes an evaluation data structure. More...
 
static void init_frame_eval (SelectionTreeElementPointer sel)
 Recursively initializes the flags for evaluation. More...
 
void _gmx_sel_evaluate_children (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates the children of a general selection element. More...
 
void _gmx_sel_evaluate_root (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *)
 Evaluates a root selection element. More...
 
void _gmx_sel_evaluate_static (gmx_sel_evaluate_t *, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a static group selection element. More...
 
void _gmx_sel_evaluate_subexpr_simple (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a subexpression when there is only one reference. More...
 
void _gmx_sel_evaluate_subexpr_staticeval (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a subexpression when the evaluation group is static. More...
 
void _gmx_sel_evaluate_subexpr (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a subexpression. More...
 
void _gmx_sel_evaluate_subexprref_simple (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a subexpression reference when there are no other references. More...
 
void _gmx_sel_evaluate_subexprref (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a subexpression reference. More...
 
void _gmx_sel_evaluate_method_params (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates the children of a SEL_EXPRESSION element. More...
 
void _gmx_sel_evaluate_method (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a method expression. More...
 
void _gmx_sel_evaluate_modifier (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a modifier expression. More...
 
void _gmx_sel_evaluate_not (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a boolean NOT element. More...
 
void _gmx_sel_evaluate_and (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a boolean AND element with short-circuiting. More...
 
void _gmx_sel_evaluate_or (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates a boolean OR element with short-circuiting. More...
 
void _gmx_sel_evaluate_arithmetic (gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g)
 Evaluates an arithmetic expression element. More...
 

Function Documentation

void _gmx_sel_evaluate_and ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a boolean AND element with short-circuiting.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Short-circuiting evaluation of logical AND expressions.

Starts by evaluating the first child element in the group g. The each following child element is evaluated in the intersection of all the previous values until all children have been evaluated or the intersection becomes empty. The value of sel is set to the intersection of all the (evaluated) child values.

If the first child does not have an evaluation function, it is skipped and the evaluation is started at the second child. This happens if the first child is a constant expression and during compilation it was detected that the evaluation group is always a subset of the constant group (currently, the compiler never detects this).

This function is used as gmx::SelectionTreeElement::evaluate for SEL_BOOLEAN elements with BOOL_AND.

void _gmx_sel_evaluate_arithmetic ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates an arithmetic expression element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.
void _gmx_sel_evaluate_children ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates the children of a general selection element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates each child of sel in g.

void _gmx_sel_evaluate_init ( gmx_sel_evaluate_t data,
gmx_sel_mempool_t mp,
gmx_ana_index_t gall,
const gmx_mtop_t *  top,
t_trxframe *  fr,
t_pbc pbc 
)

Initializes an evaluation data structure.

Parameters
[out]dataEvaluation data structure to initialize.
[in]mpMemory pool for intermediate evaluation values.
[in]gallIndex group with all the atoms.
[in]topTopology structure for evaluation.
[in]frNew frame for evaluation.
[in]pbcNew PBC information for evaluation.
void _gmx_sel_evaluate_method ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a method expression.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates all child selections (using _gmx_sel_evaluate_method_params()) to evaluate any parameter values. If this is the first time this expression is evaluated for the frame, sel_framefunc() callback is called if one is provided. If a reference position calculation has been initialized for this element, the positions are also updated, and sel_updatefunc_pos() is used to evaluate the value. Otherwise, sel_updatefunc() is used.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_EXPRESSION elements.

void _gmx_sel_evaluate_method_params ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates the children of a SEL_EXPRESSION element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates each child of a SEL_EXPRESSION element. The value of sel is not touched.

This function is not used as gmx::SelectionTreeElement::evaluate, but is used internally.

void _gmx_sel_evaluate_modifier ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a modifier expression.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates all child selections (using _gmx_sel_evaluate_method_params()) to evaluate any parameter values. If this is the first time this expression is evaluated for the frame, sel_framefunc() callback is called if one is provided. The modifier is then evaluated using sel_updatefunc_pos().

This function is used as gmx::SelectionTreeElement::evaluate for SEL_MODIFIER elements.

void _gmx_sel_evaluate_not ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a boolean NOT element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates the child element (there should be only one) in the group g, and then sets the value of sel to the complement of the child value.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_BOOLEAN elements with BOOL_NOT.

void _gmx_sel_evaluate_or ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a boolean OR element with short-circuiting.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Short-circuiting evaluation of logical OR expressions.

Starts by evaluating the first child element in the group g. For each subsequent child, finds the part of g that is not included the value of any previous child, and evaluates the child in that group until the last child is evaluated or all of g is included in some child value. The value of sel is set to the union of all the (evaluated) child values.

If the first child does not have an evaluation function, its value is used without evaluation. This happens if the first child is a constant expression, the selection has been compiled, and the evaluation group is the same for each frame. In this case, the compiler has taken care of that the child value is a subset of g, making it unnecessary to evaluate it.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_BOOLEAN elements with BOOL_OR.

void _gmx_sel_evaluate_root ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a root selection element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which 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 sel->u.cgrp. If sel->u.cgrp is empty, nothing is done. The value of sel is not touched (root elements do not evaluate to values).

This function can be used as gmx::SelectionTreeElement::evaluate for SEL_ROOT elements.

void _gmx_sel_evaluate_static ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a static group selection element.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 for success.

Sets the value of sel to the intersection of g and sel->u.cgrp.

This function can be used as gmx::SelectionTreeElement::evaluate for SEL_CONST elements with value type GROUP_VALUE.

void _gmx_sel_evaluate_subexpr ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a subexpression.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Finds the part of g for which the subexpression has not yet been evaluated by comparing g to sel->u.cgrp. If the part is not empty, the child expression is evaluated for this part, and the results merged to the old values of the child. The value of sel itself is undefined after the call.

Todo:
The call to gmx_ana_index_difference() can take quite a lot of unnecessary time if the subexpression is evaluated either several times for the same group or for completely distinct groups. However, in the majority of cases, these situations occur when _gmx_sel_evaluate_subexpr_staticeval() can be used, so this should not be a major problem.
void _gmx_sel_evaluate_subexpr_simple ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a subexpression when there is only one reference.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

Evaluates the child element (there should be exactly one) in g. The compiler has taken care that the child actually stores the evaluated value in the value pointer of this element.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_SUBEXPR elements that are used only once, and hence do not need full subexpression handling.

void _gmx_sel_evaluate_subexpr_staticeval ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a subexpression when the evaluation group is static.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

If this is the first call for this frame, evaluates the child element there should be exactly one in g. The compiler has taken care that the child actually stores the evaluated value in the value pointer of this element. Assumes that g is persistent for the duration of the whole evaluation.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_SUBEXPR elements that have a static evaluation group, and hence do not need full subexpression handling.

void _gmx_sel_evaluate_subexprref ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a subexpression reference.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 on success, a non-zero error code on error.

If the value type is POS_VALUE, the value of the child is simply copied to set the value of 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 g, and the value of the child is then copied. There should be only one child element.

This function is used as gmx::SelectionTreeElement::evaluate for SEL_SUBEXPRREF elements.

void _gmx_sel_evaluate_subexprref_simple ( gmx_sel_evaluate_t data,
const gmx::SelectionTreeElementPointer sel,
gmx_ana_index_t g 
)

Evaluates a subexpression reference when there are no other references.

Parameters
[in]dataData for the current frame.
[in]selSelection element being evaluated.
[in]gGroup for which sel should be evaluated.
Returns
0 for success.

Sets the value pointers of the child and its child to point to the same memory as the value pointer of this element to avoid copying, and then evaluates evaluates the child.

This function is used as gmx::SelectionTreeElement:evaluate for SEL_SUBEXPRREF elements for which the SEL_SUBEXPR does not have other references.

void _gmx_sel_print_evalfunc_name ( FILE *  fp,
gmx::sel_evalfunc  evalfunc 
)

Writes out a human-readable name for an evaluation function.

Parameters
[in]fpFile handle to receive the output.
[in]evalfuncFunction pointer to print.
static void init_frame_eval ( SelectionTreeElementPointer  sel)
static

Recursively initializes the flags for evaluation.

Parameters
[in,out]selSelection element to clear.

The SEL_INITFRAME flag is set for SEL_EXPRESSION elements whose method defines the init_frame callback (see sel_framefunc()), and cleared for other elements.

The SEL_EVALFRAME flag is cleared for all elements.