Tidy: modernize-use-nullptr
[alexxy/gromacs.git] / src / gromacs / selection / selelem.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \internal \file
36  * \brief
37  * Declares gmx::SelectionTreeElement and related things.
38  *
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.
42  *
43  * This is an implementation header: there should be no need to use it outside
44  * this directory.
45  *
46  * \author Teemu Murtola <teemu.murtola@gmail.com>
47  * \ingroup module_selection
48  */
49 #ifndef GMX_SELECTION_SELELEM_H
50 #define GMX_SELECTION_SELELEM_H
51
52 #include <memory>
53 #include <string>
54
55 #include "gromacs/selection/indexutil.h"
56 #include "gromacs/utility/classhelpers.h"
57 #include "gromacs/utility/real.h"
58
59 #include "selvalue.h"
60
61 struct gmx_ana_poscalc_t;
62 struct gmx_ana_selparam_t;
63 struct gmx_ana_selmethod_t;
64
65 struct gmx_sel_evaluate_t;
66 struct gmx_sel_mempool_t;
67
68 struct t_compiler_data;
69
70 namespace gmx
71 {
72 class SelectionTreeElement;
73 struct SelectionTopologyProperties;
74
75 //! Smart pointer type for selection tree element pointers.
76 typedef std::shared_ptr<SelectionTreeElement> SelectionTreeElementPointer;
77 } // namespace gmx
78
79 /********************************************************************/
80 /*! \name Enumerations for expression types
81  ********************************************************************/
82 //!\{
83
84 /** Defines the type of a gmx::SelectionTreeElement object. */
85 typedef enum
86 {
87     /** Constant-valued expression. */
88     SEL_CONST,
89     /** Method expression that requires evaluation. */
90     SEL_EXPRESSION,
91     /** Boolean expression. */
92     SEL_BOOLEAN,
93     /** Arithmetic expression. */
94     SEL_ARITHMETIC,
95     /** Root node of the evaluation tree. */
96     SEL_ROOT,
97     /** Subexpression that may be referenced several times. */
98     SEL_SUBEXPR,
99     /** Reference to a subexpression. */
100     SEL_SUBEXPRREF,
101     /** Unresolved reference to an external group. */
102     SEL_GROUPREF,
103     /** Post-processing of selection value. */
104     SEL_MODIFIER
105 } e_selelem_t;
106
107 /** Defines the boolean operation of gmx::SelectionTreeElement objects with type \ref SEL_BOOLEAN. */
108 typedef enum
109 {
110     BOOL_NOT,           /**< Not */
111     BOOL_AND,           /**< And */
112     BOOL_OR,            /**< Or */
113     BOOL_XOR            /**< Xor (not implemented). */
114 } e_boolean_t;
115
116 /** Defines the arithmetic operation of gmx::SelectionTreeElement objects with type \ref SEL_ARITHMETIC. */
117 typedef enum
118 {
119     ARITH_PLUS,         /**< Addition (`+`) */
120     ARITH_MINUS,        /**< Subtraction (`-`) */
121     ARITH_NEG,          /**< Unary `-` */
122     ARITH_MULT,         /**< Multiplication (`*`) */
123     ARITH_DIV,          /**< Division (`/`) */
124     ARITH_EXP           /**< Power (`^`) */
125 } e_arithmetic_t;
126
127 /** Returns a string representation of the type of a gmx::SelectionTreeElement. */
128 extern const char *
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. */
131 extern const char *
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. */
134 extern const char *
135 _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val);
136
137 //!\}
138
139
140 /********************************************************************/
141 /*! \name Selection expression flags
142  * \anchor selelem_flags
143  ********************************************************************/
144 //!\{
145 /*! \brief
146  * Selection value flags are set.
147  *
148  * If this flag is set, the flags covered by \ref SEL_VALFLAGMASK
149  * have been set properly for the element.
150  */
151 #define SEL_FLAGSSET    1
152 /*! \brief
153  * The element evaluates to a single value.
154  *
155  * This flag is always set for \ref GROUP_VALUE elements.
156  */
157 #define SEL_SINGLEVAL   2
158 /*! \brief
159  * The element evaluates to one value for each input atom.
160  */
161 #define SEL_ATOMVAL     4
162 /*! \brief
163  * The element evaluates to an arbitrary number of values.
164  */
165 #define SEL_VARNUMVAL   8
166 /*! \brief
167  * The element (or one of its children) is dynamic.
168  */
169 #define SEL_DYNAMIC     16
170 /*! \brief
171  * The element may contain atom indices in an unsorted order.
172  */
173 #define SEL_UNSORTED    32
174 /*! \brief
175  * Mask that covers the flags that describe the number of values.
176  */
177 #define SEL_VALTYPEMASK (SEL_SINGLEVAL | SEL_ATOMVAL | SEL_VARNUMVAL)
178 /*! \brief
179  * Mask that covers the flags that describe the value type.
180  */
181 #define SEL_VALFLAGMASK (SEL_FLAGSSET | SEL_VALTYPEMASK | SEL_DYNAMIC)
182 /*! \brief
183  * Data has been allocated for the \p v.u union.
184  *
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
188  * a selection.
189  *
190  * Even if the flag is set, \p v.u.ptr can be NULL during initialization.
191  *
192  * \todo
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.
198  */
199 #define SEL_ALLOCVAL    (1<<8)
200 /*! \brief
201  * Data has been allocated for the group/position structure.
202  *
203  * If not set, the memory allocated for fields in \p v.u.g or \p v.u.p is
204  * managed externally.
205  *
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.
208  */
209 #define SEL_ALLOCDATA   (1<<9)
210 /*! \brief
211  * \p method->init_frame should be called for the frame.
212  */
213 #define SEL_INITFRAME   (1<<10)
214 /*! \brief
215  * Parameter has been evaluated for the current frame.
216  *
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
219  * current frame.
220  * It is not set for \ref SEL_ATOMVAL elements, because they may need to
221  * be evaluated multiple times.
222  */
223 #define SEL_EVALFRAME   (1<<11)
224 /*! \brief
225  * \p method->init has been called.
226  */
227 #define SEL_METHODINIT  (1<<12)
228 /*! \brief
229  * \p method->outinit has been called.
230  *
231  * This flag is also used for \ref SEL_SUBEXPRREF elements.
232  */
233 #define SEL_OUTINIT     (1<<13)
234 //!\}
235
236
237 namespace gmx
238 {
239
240 class ExceptionInitializer;
241
242 //! \cond internal
243 /*! \brief
244  * Function pointer for evaluating a gmx::SelectionTreeElement.
245  */
246 typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t         *data,
247                              const SelectionTreeElementPointer &sel,
248                              gmx_ana_index_t                   *g);
249 //! \endcond
250
251 /*! \internal
252  * \brief
253  * Stores the location of a selection element in the selection text.
254  *
255  * The location is stored as a range in the pretty-printed selection text
256  * (where whitespace has been sanitized), and can be used to extract that text
257  * for error messages and other diagnostic purposes.
258  * During parsing, the extraction is done with _gmx_sel_lexer_get_text().
259  *
260  * This needs to be a plain C struct for Bison to properly deal with it.
261  */
262 struct SelectionLocation
263 {
264     //! Returns an empty location.
265     static SelectionLocation createEmpty()
266     {
267         SelectionLocation empty = {0, 0};
268         return empty;
269     }
270
271     //! Start index of the string where this element has been parsed from.
272     int  startIndex;
273     //! End index of the string where this element has been parsed from.
274     int  endIndex;
275 };
276
277 /*! \internal \brief
278  * Represents an element of a selection expression.
279  */
280 class SelectionTreeElement
281 {
282     public:
283         /*! \brief
284          * Allocates memory and performs common initialization.
285          *
286          * \param[in] type     Type of selection element to create.
287          * \param[in] location Location of the element.
288          *
289          * \a type is set to \p type,
290          * \a v::type is set to \ref GROUP_VALUE for boolean and comparison
291          * expressions and \ref NO_VALUE for others, and
292          * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA
293          * is also set for \ref SEL_BOOLEAN elements).
294          * All the pointers are set to NULL.
295          */
296         SelectionTreeElement(e_selelem_t type, const SelectionLocation &location);
297         ~SelectionTreeElement();
298
299         //! Frees the memory allocated for the \a v union.
300         void freeValues();
301         //! Frees the memory allocated for the \a u union.
302         void freeExpressionData();
303         /* In compiler.cpp */
304         /*! \brief
305          * Frees the memory allocated for the selection compiler.
306          *
307          * This function only frees the data for the given selection, not its
308          * children.  It is safe to call the function when compiler data has
309          * not been allocated or has already been freed; in such a case,
310          * nothing is done.
311          */
312         void freeCompilerData();
313
314         /*! \brief
315          * Reserves memory for value from a memory pool.
316          *
317          * \param[in]     count Number of values to reserve memory for.
318          *
319          * Reserves memory for the values of this element from the \a mempool
320          * memory pool.
321          * If no memory pool is set, nothing is done.
322          */
323         void mempoolReserve(int count);
324         /*! \brief
325          * Releases memory pool used for value.
326          *
327          * Releases the memory allocated for the values of this element from the
328          * \a mempool memory pool.
329          * If no memory pool is set, nothing is done.
330          */
331         void mempoolRelease();
332
333         //! Returns the name of the element.
334         const std::string &name() const { return name_; }
335         //! Returns the location of the element.
336         const SelectionLocation &location() const { return location_; }
337
338         /*! \brief
339          * Sets the name of the element.
340          *
341          * \param[in] name  Name to set (can be NULL).
342          * \throws    std::bad_alloc if out of memory.
343          */
344         void setName(const char *name) { name_ = (name != nullptr ? name : ""); }
345         //! \copydoc setName(const char *)
346         void setName(const std::string &name) { name_ = name; }
347         /*! \brief
348          * Sets the name of a root element if it is missing.
349          *
350          * \param[in] selectionText  Full selection text to use as a fallback.
351          * \throws    std::bad_alloc if out of memory.
352          *
353          * If index groups have not yet been set and the selection is a result
354          * of a group reference, the name may still be empty after this call.
355          *
356          * Strong exception safety guarantee.
357          */
358         void fillNameIfMissing(const char *selectionText);
359
360         /*! \brief
361          * Returns which topology properties the selection element subtree requires
362          * for evaluation.
363          *
364          * \returns   List of topology properties required for evaluation.
365          */
366         SelectionTopologyProperties requiredTopologyProperties() const;
367         /*! \brief
368          * Checks that this element and its children do not contain unsupported
369          * elements with unsorted atoms.
370          *
371          * \param[in] bUnsortedAllowed Whether this element's parents allow it
372          *     to have unsorted atoms.
373          * \param     errors           Object for reporting any error messages.
374          * \throws    std::bad_alloc if out of memory.
375          *
376          * Errors are reported as nested exceptions in \p errors.
377          */
378         void checkUnsortedAtoms(bool                  bUnsortedAllowed,
379                                 ExceptionInitializer *errors) const;
380         /*! \brief
381          * Checks whether the element or its children have unresolved index
382          * group references.
383          *
384          * Does not throw.
385          */
386         bool requiresIndexGroups() const;
387         /*! \brief
388          * Resolves an unresolved reference to an index group.
389          *
390          * \param[in] grps   Index groups to use to resolve the reference.
391          * \param[in] natoms Maximum number of atoms the selections can evaluate to
392          *     (zero if the topology/atom count is not set yet).
393          * \throws    std::bad_alloc if out of memory.
394          * \throws    InconsistentInputError if the reference cannot be
395          *     resolved.
396          */
397         void resolveIndexGroupReference(gmx_ana_indexgrps_t *grps, int natoms);
398         /*! \brief
399          * Checks that an index group has valid atom indices.
400          *
401          * \param[in] natoms Maximum number of atoms the selections can evaluate to.
402          * \throws    std::bad_alloc if out of memory.
403          * \throws    InconsistentInputError if there are invalid atom indices.
404          */
405         void checkIndexGroup(int natoms);
406
407         //! Type of the element.
408         e_selelem_t                         type;
409         /*! \brief
410          * Value storage of the element.
411          *
412          * This field contains the evaluated value of the element, as well as
413          * the output value type.
414          */
415         gmx_ana_selvalue_t                  v;
416         /*! \brief
417          * Evaluation function for the element.
418          *
419          * Can be either NULL (if the expression is a constant and does not
420          * require evaluation) or point to one of the functions defined in
421          * evaluate.h.
422          */
423         sel_evalfunc                        evaluate;
424         /*! \brief
425          * Information flags about the element.
426          *
427          * Allowed flags are listed here:
428          * \ref selelem_flags "flags for gmx::SelectionTreeElement".
429          */
430         int                                 flags;
431         //! Data required by the evaluation function.
432         union {
433             /*! \brief Index group data for several element types.
434              *
435              *  - \ref SEL_CONST : if the value type is \ref GROUP_VALUE,
436              *    this field holds the unprocessed group value.
437              *  - \ref SEL_ROOT : holds the group value for which the
438              *    selection subtree should be evaluated.
439              *  - \ref SEL_SUBEXPR : holds the group for which the subexpression
440              *    has been evaluated.
441              */
442             gmx_ana_index_t                 cgrp;
443             //! Data for \ref SEL_EXPRESSION and \ref SEL_MODIFIER elements.
444             struct {
445                 //! Pointer the the method used in this expression.
446                 struct gmx_ana_selmethod_t *method;
447                 //! Pointer to the data allocated by the method's \p init_data (see sel_datafunc()).
448                 void                       *mdata;
449                 //! Pointer to the position data passed to the method.
450                 struct gmx_ana_pos_t       *pos;
451                 //! Pointer to the evaluation data for \p pos.
452                 struct gmx_ana_poscalc_t   *pc;
453             }                               expr;
454             //! Operation type for \ref SEL_BOOLEAN elements.
455             e_boolean_t                     boolt;
456             //! Operation type for \ref SEL_ARITHMETIC elements.
457             struct {
458                 //! Operation type.
459                 e_arithmetic_t              type;
460                 //! String representation.
461                 char                       *opstr;
462             }                               arith;
463             //! Associated selection parameter for \ref SEL_SUBEXPRREF elements.
464             struct gmx_ana_selparam_t      *param;
465             //! The string/number used to reference the group.
466             struct {
467                 //! Name of the referenced external group.
468                 char                       *name;
469                 //! If \a name is NULL, the index number of the referenced group.
470                 int                         id;
471             }                               gref;
472         }                                   u;
473         //! Memory pool to use for values, or NULL if standard memory handling.
474         struct gmx_sel_mempool_t           *mempool;
475         //! Internal data for the selection compiler.
476         t_compiler_data                    *cdata;
477
478         /*! \brief The first child element.
479          *
480          * Other children can be accessed through the \p next field of \p child.
481          */
482         SelectionTreeElementPointer         child;
483         //! The next sibling element.
484         SelectionTreeElementPointer         next;
485
486     private:
487         /*! \brief
488          * Name of the element.
489          *
490          * This field is only used for diagnostic purposes.
491          */
492         std::string                         name_;
493         /*! \brief
494          * Location of the element in the selection text.
495          *
496          * This field is only used for diagnostic purposes (including error
497          * messages).
498          */
499         SelectionLocation                   location_;
500
501         GMX_DISALLOW_COPY_AND_ASSIGN(SelectionTreeElement);
502 };
503
504 } // namespace gmx
505
506 /********************************************************************/
507 /*! \name Selection expression functions
508  */
509 //!\{
510
511 /* In evaluate.c */
512 /** Writes out a human-readable name for an evaluation function. */
513 void
514 _gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc);
515
516 /** Sets the value type of a gmx::SelectionTreeElement. */
517 void
518 _gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer &sel,
519                        e_selvalue_t                            vtype);
520
521 /*! \brief
522  * Frees the memory allocated for a selection method parameter.
523  *
524  * \param[in] param Parameter to free.
525  */
526 void
527 _gmx_selelem_free_param(struct gmx_ana_selparam_t *param);
528 /*! \brief
529  * Frees the memory allocated for a selection method.
530  *
531  * \param[in] method Method to free.
532  * \param[in] mdata  Method data to free.
533  */
534 void
535 _gmx_selelem_free_method(struct gmx_ana_selmethod_t *method, void *mdata);
536
537 /** Prints a human-readable version of a selection element subtree. */
538 void
539 _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel,
540                         bool bValues, int level);
541 /* In compiler.c */
542 /** Prints a human-readable version of the internal compiler data structure. */
543 void
544 _gmx_selelem_print_compiler_info(FILE *fp, const gmx::SelectionTreeElement &sel,
545                                  int level);
546
547 /* In sm_insolidangle.c */
548 /** Returns true if the covered fraction of the selection can be calculated. */
549 bool
550 _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel);
551 /** Returns the covered fraction of the selection for the current frame. */
552 real
553 _gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement &sel);
554
555 //!\}
556
557 #endif