2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Declares gmx::SelectionTreeElement and related things.
39 * The selection element trees constructed by the parser and the compiler
40 * are described on the respective pages:
41 * \ref page_module_selection_parser and \ref page_module_selection_compiler.
43 * This is an implementation header: there should be no need to use it outside
46 * \author Teemu Murtola <teemu.murtola@gmail.com>
47 * \ingroup module_selection
49 #ifndef GMX_SELECTION_SELELEM_H
50 #define GMX_SELECTION_SELELEM_H
54 #include <boost/shared_ptr.hpp>
56 #include "gromacs/utility/common.h"
57 #include "gromacs/utility/real.h"
59 #include "indexutil.h"
62 struct gmx_ana_poscalc_t;
63 struct gmx_ana_selparam_t;
64 struct gmx_ana_selmethod_t;
66 struct gmx_sel_evaluate_t;
67 struct gmx_sel_mempool_t;
69 struct t_compiler_data;
73 class SelectionTreeElement;
75 //! Smart pointer type for selection tree element pointers.
76 typedef boost::shared_ptr<SelectionTreeElement> SelectionTreeElementPointer;
79 /********************************************************************/
80 /*! \name Enumerations for expression types
81 ********************************************************************/
84 /** Defines the type of a gmx::SelectionTreeElement object. */
87 /** Constant-valued expression. */
89 /** Method expression that requires evaluation. */
91 /** Boolean expression. */
93 /** Arithmetic expression. */
95 /** Root node of the evaluation tree. */
97 /** Subexpression that may be referenced several times. */
99 /** Reference to a subexpression. */
101 /** Unresolved reference to an external group. */
103 /** Post-processing of selection value. */
107 /** Defines the boolean operation of gmx::SelectionTreeElement objects with type \ref SEL_BOOLEAN. */
110 BOOL_NOT, /**< Not */
111 BOOL_AND, /**< And */
113 BOOL_XOR /**< Xor (not implemented). */
116 /** Defines the arithmetic operation of gmx::SelectionTreeElement objects with type \ref SEL_ARITHMETIC. */
119 ARITH_PLUS, /**< Addition (`+`) */
120 ARITH_MINUS, /**< Subtraction (`-`) */
121 ARITH_NEG, /**< Unary `-` */
122 ARITH_MULT, /**< Multiplication (`*`) */
123 ARITH_DIV, /**< Division (`/`) */
124 ARITH_EXP /**< Power (`^`) */
127 /** Returns a string representation of the type of a gmx::SelectionTreeElement. */
129 _gmx_selelem_type_str(const gmx::SelectionTreeElement &sel);
130 /** Returns a string representation of the boolean type of a \ref SEL_BOOLEAN gmx::SelectionTreeElement. */
132 _gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement &sel);
133 /** Returns a string representation of the type of a \c gmx_ana_selvalue_t. */
135 _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val);
140 /********************************************************************/
141 /*! \name Selection expression flags
142 * \anchor selelem_flags
143 ********************************************************************/
146 * Selection value flags are set.
148 * If this flag is set, the flags covered by \ref SEL_VALFLAGMASK
149 * have been set properly for the element.
151 #define SEL_FLAGSSET 1
153 * The element evaluates to a single value.
155 * This flag is always set for \ref GROUP_VALUE elements.
157 #define SEL_SINGLEVAL 2
159 * The element evaluates to one value for each input atom.
161 #define SEL_ATOMVAL 4
163 * The element evaluates to an arbitrary number of values.
165 #define SEL_VARNUMVAL 8
167 * The element (or one of its children) is dynamic.
169 #define SEL_DYNAMIC 16
171 * The element may contain atom indices in an unsorted order.
173 #define SEL_UNSORTED 32
175 * Mask that covers the flags that describe the number of values.
177 #define SEL_VALTYPEMASK (SEL_SINGLEVAL | SEL_ATOMVAL | SEL_VARNUMVAL)
179 * Mask that covers the flags that describe the value type.
181 #define SEL_VALFLAGMASK (SEL_FLAGSSET | SEL_VALTYPEMASK | SEL_DYNAMIC)
183 * Data has been allocated for the \p v.u union.
185 * If not set, the \p v.u.ptr points to data allocated externally.
186 * This is the case if the value of the element is used as a parameter
187 * for a selection method or if the element evaluates the final value of
190 * Even if the flag is set, \p v.u.ptr can be NULL during initialization.
193 * This flag overlaps with the function of \p v.nalloc field, and could
194 * probably be removed, making memory management simpler. Currently, the
195 * \p v.nalloc field is not kept up-to-date in all cases when this flag
196 * is changed and is used in places where this flag is not, so this would
197 * require a careful investigation of the selection code.
199 #define SEL_ALLOCVAL (1<<8)
201 * Data has been allocated for the group/position structure.
203 * If not set, the memory allocated for fields in \p v.u.g or \p v.u.p is
204 * managed externally.
206 * This field has no effect if the value type is not \ref GROUP_VALUE or
207 * \ref POS_VALUE, but should not be set.
209 #define SEL_ALLOCDATA (1<<9)
211 * \p method->init_frame should be called for the frame.
213 #define SEL_INITFRAME (1<<10)
215 * Parameter has been evaluated for the current frame.
217 * This flag is set for children of \ref SEL_EXPRESSION elements (which
218 * describe method parameters) after the element has been evaluated for the
220 * It is not set for \ref SEL_ATOMVAL elements, because they may need to
221 * be evaluated multiple times.
223 #define SEL_EVALFRAME (1<<11)
225 * \p method->init has been called.
227 #define SEL_METHODINIT (1<<12)
229 * \p method->outinit has been called.
231 * This flag is also used for \ref SEL_SUBEXPRREF elements.
233 #define SEL_OUTINIT (1<<13)
240 class ExceptionInitializer;
243 * Function pointer for evaluating a gmx::SelectionTreeElement.
245 typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t *data,
246 const SelectionTreeElementPointer &sel,
250 * Represents an element of a selection expression.
252 class SelectionTreeElement
256 * Allocates memory and performs common initialization.
258 * \param[in] type Type of selection element to create.
260 * \a type is set to \p type,
261 * \a v::type is set to \ref GROUP_VALUE for boolean and comparison
262 * expressions and \ref NO_VALUE for others, and
263 * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA
264 * is also set for \ref SEL_BOOLEAN elements).
265 * All the pointers are set to NULL.
267 explicit SelectionTreeElement(e_selelem_t type);
268 ~SelectionTreeElement();
270 //! Frees the memory allocated for the \a v union.
272 //! Frees the memory allocated for the \a u union.
273 void freeExpressionData();
274 /* In compiler.cpp */
276 * Frees the memory allocated for the selection compiler.
278 * This function only frees the data for the given selection, not its
279 * children. It is safe to call the function when compiler data has
280 * not been allocated or has already been freed; in such a case,
283 void freeCompilerData();
286 * Reserves memory for value from a memory pool.
288 * \param[in] count Number of values to reserve memory for.
290 * Reserves memory for the values of this element from the \a mempool
292 * If no memory pool is set, nothing is done.
294 void mempoolReserve(int count);
296 * Releases memory pool used for value.
298 * Releases the memory allocated for the values of this element from the
299 * \a mempool memory pool.
300 * If no memory pool is set, nothing is done.
302 void mempoolRelease();
304 //! Returns the name of the element.
305 const std::string &name() const { return name_; }
307 * Sets the name of the element.
309 * \param[in] name Name to set (can be NULL).
310 * \throws std::bad_alloc if out of memory.
312 void setName(const char *name) { name_ = (name != NULL ? name : ""); }
313 //! \copydoc setName(const char *)
314 void setName(const std::string &name) { name_ = name; }
316 * Sets the name of a root element if it is missing.
318 * \param[in] selectionText Full selection text to use as a fallback.
319 * \throws std::bad_alloc if out of memory.
321 * If index groups have not yet been set and the selection is a result
322 * of a group reference, the name may still be empty after this call.
324 * Strong exception safety guarantee.
326 void fillNameIfMissing(const char *selectionText);
329 * Checks that this element and its children do not contain unsupported
330 * elements with unsorted atoms.
332 * \param[in] bUnsortedAllowed Whether this element's parents allow it
333 * to have unsorted atoms.
334 * \param errors Object for reporting any error messages.
335 * \throws std::bad_alloc if out of memory.
337 * Errors are reported as nested exceptions in \p errors.
339 void checkUnsortedAtoms(bool bUnsortedAllowed,
340 ExceptionInitializer *errors) const;
342 * Resolves an unresolved reference to an index group.
344 * \param[in] grps Index groups to use to resolve the reference.
345 * \param[in] natoms Maximum number of atoms the selections can evaluate to
346 * (zero if the topology/atom count is not set yet).
347 * \throws std::bad_alloc if out of memory.
348 * \throws InconsistentInputError if the reference cannot be
351 void resolveIndexGroupReference(gmx_ana_indexgrps_t *grps, int natoms);
353 * Checks that an index group has valid atom indices.
355 * \param[in] natoms Maximum number of atoms the selections can evaluate to.
356 * \throws std::bad_alloc if out of memory.
357 * \throws InconsistentInputError if there are invalid atom indices.
359 void checkIndexGroup(int natoms);
361 //! Type of the element.
364 * Value storage of the element.
366 * This field contains the evaluated value of the element, as well as
367 * the output value type.
369 gmx_ana_selvalue_t v;
371 * Evaluation function for the element.
373 * Can be either NULL (if the expression is a constant and does not
374 * require evaluation) or point to one of the functions defined in
377 sel_evalfunc evaluate;
379 * Information flags about the element.
381 * Allowed flags are listed here:
382 * \ref selelem_flags "flags for gmx::SelectionTreeElement".
385 //! Data required by the evaluation function.
387 /*! \brief Index group data for several element types.
389 * - \ref SEL_CONST : if the value type is \ref GROUP_VALUE,
390 * this field holds the unprocessed group value.
391 * - \ref SEL_ROOT : holds the group value for which the
392 * selection subtree should be evaluated.
393 * - \ref SEL_SUBEXPR : holds the group for which the subexpression
394 * has been evaluated.
396 gmx_ana_index_t cgrp;
397 //! Data for \ref SEL_EXPRESSION and \ref SEL_MODIFIER elements.
399 //! Pointer the the method used in this expression.
400 struct gmx_ana_selmethod_t *method;
401 //! Pointer to the data allocated by the method's \p init_data (see sel_datafunc()).
403 //! Pointer to the position data passed to the method.
404 struct gmx_ana_pos_t *pos;
405 //! Pointer to the evaluation data for \p pos.
406 struct gmx_ana_poscalc_t *pc;
408 //! Operation type for \ref SEL_BOOLEAN elements.
410 //! Operation type for \ref SEL_ARITHMETIC elements.
414 //! String representation.
417 //! Associated selection parameter for \ref SEL_SUBEXPRREF elements.
418 struct gmx_ana_selparam_t *param;
419 //! The string/number used to reference the group.
421 //! Name of the referenced external group.
423 //! If \a name is NULL, the index number of the referenced group.
427 //! Memory pool to use for values, or NULL if standard memory handling.
428 struct gmx_sel_mempool_t *mempool;
429 //! Internal data for the selection compiler.
430 t_compiler_data *cdata;
432 /*! \brief The first child element.
434 * Other children can be accessed through the \p next field of \p child.
436 SelectionTreeElementPointer child;
437 //! The next sibling element.
438 SelectionTreeElementPointer next;
442 * Name of the element.
444 * This field is only used for informative purposes.
448 GMX_DISALLOW_COPY_AND_ASSIGN(SelectionTreeElement);
453 /********************************************************************/
454 /*! \name Selection expression functions
459 /** Writes out a human-readable name for an evaluation function. */
461 _gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc);
463 /** Sets the value type of a gmx::SelectionTreeElement. */
465 _gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer &sel,
468 /** Frees the memory allocated for a selection method. */
470 _gmx_selelem_free_method(struct gmx_ana_selmethod_t *method, void *mdata);
472 /** Prints a human-readable version of a selection element subtree. */
474 _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel,
475 bool bValues, int level);
477 /** Prints a human-readable version of the internal compiler data structure. */
479 _gmx_selelem_print_compiler_info(FILE *fp, const gmx::SelectionTreeElement &sel,
482 /** Returns true if the selection element subtree requires topology information for evaluation. */
484 _gmx_selelem_requires_top(const gmx::SelectionTreeElement &root);
486 /* In sm_insolidangle.c */
487 /** Returns true if the covered fraction of the selection can be calculated. */
489 _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel);
490 /** Returns the covered fraction of the selection for the current frame. */
492 _gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement &sel);