3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
32 * \brief Selection compilation and optimization.
35 * Better error handling and memory management in error situations.
36 * At least, the main compilation function leaves the selection collection in
37 * a bad state if an error occurs.
40 * The memory usage could still be optimized.
41 * Use of memory pooling could still be extended, and a lot of redundant
42 * gmin/gmax data could be eliminated for complex arithmetic expressions.
45 * \page selcompiler Selection compilation
47 * The compiler takes the selection element tree from the selection parser
48 * (see \ref selparser) as input. The selection parser is quite independent of
49 * selection evaluation details, and the compiler processes the tree to
50 * conform to what the evaluation functions expect.
51 * For better control and optimization possibilities, the compilation is
52 * done on all selections simultaneously.
53 * Hence, all the selections should be parsed before the compiler can be
56 * The compiler initializes all fields in \c t_selelem not initialized by
57 * the parser: \c t_selelem::v (some fields have already been initialized by
58 * the parser), \c t_selelem::evaluate, and \c t_selelem::u (again, some
59 * elements have been initialized in the parser).
60 * The \c t_selelem::cdata field is used during the compilation to store
61 * internal data, but the data is freed when the compiler returns.
63 * In addition to initializing the elements, the compiler reorganizes the tree
64 * to simplify and optimize evaluation. The compiler also evaluates the static
65 * parts of the selection: in the end of the compilation, static parts have
66 * been replaced by the result of the evaluation.
68 * The compiler is called by calling gmx_ana_selcollection_compile().
69 * This functions then does the compilation in several passes over the
71 * -# Subexpressions are extracted: a separate root is created for each
72 * subexpression, and placed before the expression is first used.
73 * Currently, only variables and expressions used to evaluate parameter
74 * values are extracted, but common subexpression could also be detected
76 * -# A second pass with simple reordering and initialization is done:
77 * -# Boolean expressions are combined such that one element can evaluate,
78 * e.g., "A and B and C". The subexpressions in gmx_boolean expression are
79 * reordered such that static expressions come first without otherwise
80 * altering the relative order of the expressions.
81 * -# The \c t_selelem::evaluate field is set to the correct evaluation
82 * function from evaluate.h.
83 * -# The compiler data structure is allocated for each element, and
84 * the fields are initialized, with the exception of the contents of
85 * \c gmax and \c gmin fields. In reality, several passes are made
86 * to completely initialize the structure, because some flags are set
87 * recursively based on which elements refer to an element, and these
88 * flags need to be set to initialize other fields.
90 * -# The evaluation function of all elements is replaced with the
91 * analyze_static() function to be able to initialize the element before
92 * the actual evaluation function is called.
93 * The evaluation machinery is then called to initialize the whole tree,
94 * while simultaneously evaluating the static expressions.
95 * During the evaluation, track is kept of the smallest and largest
96 * possible selections, and these are stored in the internal compiler
97 * data structure for each element.
98 * To be able to do this for all possible values of dynamical expressions,
99 * special care needs to be taken with gmx_boolean expressions because they
100 * are short-circuiting. This is done through the
101 * \c SEL_CDATA_EVALMAX flag, which makes dynamic child expressions
102 * of \c BOOL_OR expressions evaluate to empty groups, while subexpressions
103 * of \c BOOL_AND are evaluated to largest possible groups.
104 * Memory is also allocated to store the results of the evaluation.
105 * For each element, analyze_static() calls the actual evaluation function
106 * after the element has been properly initialized.
107 * -# Another evaluation pass is done over subexpressions with more than
108 * one reference to them. These cannot be completely processed during the
109 * first pass, because it is not known whether later references require
110 * additional evaluation of static expressions.
111 * -# Unused subexpressions are removed. For efficiency reasons (and to avoid
112 * some checks), this is actually done several times already earlier in
113 * the compilation process.
114 * -# Most of the processing is now done, and the next pass simply sets the
115 * evaluation group of root elements to the largest selection as determined
116 * in pass 3. For root elements of subexpressions that should not be
117 * evaluated before they are referred to, the evaluation group/function is
118 * cleared. At the same time, position calculation data is initialized for
119 * for selection method elements that require it. Compiler data is also
120 * freed as it is no longer needed.
121 * -# A final pass initializes the total masses and charges in the
122 * \c gmx_ana_selection_t data structures.
124 * The actual evaluation of the selection is described in the documentation
125 * of the functions in evaluate.h.
128 * Some combinations of method parameter flags are not yet properly treated by
129 * the compiler or the evaluation functions in evaluate.c. All the ones used by
130 * currently implemented methods should work, but new combinations might not.
133 * \section selcompiler_tree Element tree after compilation
135 * After the compilation, the selection element tree is suitable for
136 * gmx_ana_selcollection_evaluate().
137 * Enough memory has been allocated for \ref t_selelem::v
138 * (and \ref t_selelem::cgrp for \ref SEL_SUBEXPR elements) to allow the
139 * selection to be evaluated without allocating any memory.
142 * \subsection selcompiler_tree_root Root elements
144 * The top level of the tree consists of a chain of \ref SEL_ROOT elements.
145 * These are used for two purposes:
146 * -# A selection that should be evaluated.
147 * These elements appear in the same order as the selections in the input.
148 * For these elements, \ref t_selelem::v has been set to the maximum
149 * possible group that the selection can evaluate to (only for dynamic
150 * selections), and \ref t_selelem::cgrp has been set to use a NULL group
152 * -# A subexpression that appears in one or more selections.
153 * Each selection that gives a value for a method parameter is a
154 * potential subexpression, as is any variable value.
155 * Only subexpressions that require evaluation for each frame are left
156 * after the selection is compiled.
157 * Each subexpression appears in the chain before any references to it.
158 * For these elements, \c t_selelem::cgrp has been set to the group
159 * that should be used to evaluate the subexpression.
160 * If \c t_selelem::cgrp is empty, the total evaluation group is not known
161 * in advance or it is more efficient to evaluate the subexpression only
162 * when it is referenced. If this is the case, \c t_selelem::evaluate is
165 * The children of the \ref SEL_ROOT elements can be used to distinguish
166 * the two types of root elements from each other; the rules are the same
167 * as for the parsed tree (see \ref selparser_tree_root).
168 * Subexpressions are treated as if they had been provided through variables.
170 * Selection names are stored as after parsing (see \ref selparser_tree_root).
173 * \subsection selcompiler_tree_const Constant elements
175 * All (sub)selections that do not require particle positions have been
176 * replaced with \ref SEL_CONST elements.
177 * Constant elements from the parser are also retained if present in
178 * dynamic parts of the selections.
179 * Several constant elements with a NULL \c t_selelem::evaluate are left for
180 * debugging purposes; of these, only the ones for \ref BOOL_OR expressions are
181 * used during evaluation.
183 * The value is stored in \c t_selelem::v, and for group values with an
184 * evaluation function set, also in \c t_selelem::cgrp.
185 * For \ref GROUP_VALUE elements, unnecessary atoms (i.e., atoms that
186 * could never be selected) have been removed from the value.
188 * \ref SEL_CONST elements have no children.
191 * \subsection selcompiler_tree_method Method evaluation elements
193 * All selection methods that need to be evaluated dynamically are described
194 * by a \ref SEL_EXPRESSION element. The \c t_selelem::method and
195 * \c t_selelem::mdata fields have already been initialized by the parser,
196 * and the compiler only calls the initialization functions in the method
197 * data structure to do some additional initialization of these fields at
198 * appropriate points. If the \c t_selelem::pc data field has been created by
199 * the parser, the compiler initializes the data structure properly once the
200 * required positions are known. If the \c t_selelem::pc field is NULL after
201 * the parser, but the method provides only sel_updatefunc_pos(), an
202 * appropriate position calculation data structure is created.
203 * If \c t_selelem::pc is not NULL, \c t_selelem::pos is also initialized
204 * to hold the positions calculated.
206 * Children of these elements are of type \ref SEL_SUBEXPRREF, and describe
207 * parameter values that need to be evaluated for each frame. See the next
208 * section for more details.
209 * \ref SEL_CONST children can also appear, and stand for parameters that get
210 * their value from a static expression. These elements are present only for
211 * debugging purposes: they always have a NULL evaluation function.
214 * \subsection selcompiler_tree_subexpr Subexpression elements
216 * As described in \ref selcompiler_tree_root, subexpressions are created
217 * for each variable and each expression that gives a value to a selection
218 * method parameter. As the only child of the \ref SEL_ROOT element,
219 * these elements have a \ref SEL_SUBEXPR element. The \ref SEL_SUBEXPR
220 * element has a single child, which evaluates the actual expression.
221 * After compilation, only subexpressions that require particle positions
222 * for evaluation are left.
223 * For non-variable subexpression, automatic names have been generated to
226 * For \ref SEL_SUBEXPR elements, memory has been allocated for
227 * \c t_selelem::cgrp to store the group for which the expression has been
228 * evaluated during the current frame. This is only done if full subexpression
229 * evaluation by _gmx_sel_evaluate_subexpr() is needed; the other evaluation
230 * functions do not require this memory.
232 * \ref SEL_SUBEXPRREF elements are used to describe references to
233 * subexpressions. They have always a single child, which is the
234 * \ref SEL_SUBEXPR element being referenced.
236 * If a subexpression is used only once, the evaluation has been optimized by
237 * setting the child of the \ref SEL_SUBEXPR element to evaluate the value of
238 * \ref SEL_SUBEXPRREF directly (in the case of memory pooling, this is managed
239 * by the evaluation functions). In such cases, the evaluation routines for the
240 * \ref SEL_SUBEXPRREF and \ref SEL_SUBEXPR elements only propagate some status
241 * information, but do not unnecessarily copy the values.
244 * \subsection selcompiler_tree_gmx_bool Boolean elements
246 * \ref SEL_BOOLEAN elements have been merged such that one element
247 * may carry out evaluation of more than one operation of the same type.
248 * The static parts of the expressions have been evaluated, and are placed
249 * in the first child. These are followed by the dynamic expressions, in the
250 * order provided by the user.
253 * \subsection selcompiler_tree_arith Arithmetic elements
255 * Constant and static expressions in \ref SEL_ARITHMETIC elements have been
257 * Currently, no other processing is done.
270 #include <indexutil.h>
272 #include <selection.h>
273 #include <selmethod.h>
275 #include "evaluate.h"
276 #include "keywords.h"
278 #include "selcollection.h"
287 * Whether a subexpression needs to evaluated for all atoms.
289 * This flag is set for \ref SEL_SUBEXPR elements that are used to
290 * evaluate non-atom-valued selection method parameters, as well as
291 * those that are used directly as values of selections.
293 SEL_CDATA_FULLEVAL = 1,
295 * Whether the whole subexpression should be treated as static.
297 * This flag is always FALSE if \ref SEL_DYNAMIC is set for the element,
298 * but it is also FALSE for static elements within common subexpressions.
300 SEL_CDATA_STATIC = 2,
301 /** Whether the subexpression will always be evaluated in the same group. */
302 SEL_CDATA_STATICEVAL = 4,
303 /** Whether the compiler evaluation routine should return the maximal selection. */
304 SEL_CDATA_EVALMAX = 8,
305 /** Whether memory has been allocated for \p gmin and \p gmax. */
306 SEL_CDATA_MINMAXALLOC = 16,
307 /** Whether subexpressions use simple pass evaluation functions. */
308 SEL_CDATA_SIMPLESUBEXPR = 32,
310 * Whether a static subexpression needs to support multiple evaluations.
312 * This flag may only be set on \ref SEL_SUBEXPR elements that also have
313 * SEL_CDATA_SIMPLESUBEXPR.
315 SEL_CDATA_STATICMULTIEVALSUBEXPR = 64,
316 /** Whether this expression is a part of a common subexpression. */
317 SEL_CDATA_COMMONSUBEXPR = 128
321 * Internal data structure used by the compiler.
323 typedef struct t_compiler_data
325 /** The real evaluation method. */
326 sel_evalfunc evaluate;
327 /** Flags for specifying how to treat this element during compilation. */
329 /** Smallest selection that can be selected by the subexpression. */
330 gmx_ana_index_t *gmin;
331 /** Largest selection that can be selected by the subexpression. */
332 gmx_ana_index_t *gmax;
336 /********************************************************************
337 * COMPILER UTILITY FUNCTIONS
338 ********************************************************************/
341 print_group_info(FILE *fp, const char *name, t_selelem *sel, gmx_ana_index_t *g)
343 fprintf(fp, " %s=", name);
346 fprintf(fp, "(null)");
348 else if (sel->cdata->flags & SEL_CDATA_MINMAXALLOC)
350 fprintf(fp, "(%d atoms, %p)", g->isize, (void*)g);
352 else if (sel->v.type == GROUP_VALUE && g == sel->v.u.g)
354 fprintf(fp, "(static, %p)", (void*)g);
358 fprintf(fp, "%p", (void*)g);
363 * \param[in] fp File handle to receive the output.
364 * \param[in] sel Selection element to print.
365 * \param[in] level Indentation level, starting from zero.
368 _gmx_selelem_print_compiler_info(FILE *fp, t_selelem *sel, int level)
374 fprintf(fp, "%*c cdata: flg=", level*2+1, ' ');
375 if (sel->cdata->flags & SEL_CDATA_FULLEVAL)
379 if (!(sel->cdata->flags & SEL_CDATA_STATIC))
383 if (sel->cdata->flags & SEL_CDATA_STATICEVAL)
387 if (sel->cdata->flags & SEL_CDATA_EVALMAX)
391 if (sel->cdata->flags & SEL_CDATA_MINMAXALLOC)
395 if (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
399 if (sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR)
403 if (sel->cdata->flags & SEL_CDATA_COMMONSUBEXPR)
407 if (!sel->cdata->flags)
411 fprintf(fp, " eval=");
412 _gmx_sel_print_evalfunc_name(fp, sel->cdata->evaluate);
413 print_group_info(fp, "gmin", sel, sel->cdata->gmin);
414 print_group_info(fp, "gmax", sel, sel->cdata->gmax);
419 * \param sel Selection to free.
421 * This function only frees the data for the given selection, not its children.
422 * It is safe to call the function when compiler data has not been allocated
423 * or has already been freed; in such a case, nothing is done.
426 _gmx_selelem_free_compiler_data(t_selelem *sel)
430 sel->evaluate = sel->cdata->evaluate;
431 if (sel->cdata->flags & SEL_CDATA_MINMAXALLOC)
433 sel->cdata->gmin->name = NULL;
434 sel->cdata->gmax->name = NULL;
435 gmx_ana_index_deinit(sel->cdata->gmin);
436 gmx_ana_index_deinit(sel->cdata->gmax);
437 sfree(sel->cdata->gmin);
438 sfree(sel->cdata->gmax);
446 * Allocates memory for storing the evaluated value of a selection element.
448 * \param sel Selection element to initialize
449 * \param[in] isize Maximum evaluation group size.
450 * \param[in] bChildEval TRUE if children have already been processed.
451 * \returns TRUE if the memory was allocated, FALSE if children need to
452 * be processed first.
454 * If called more than once, memory is (re)allocated to ensure that the
455 * maximum of the \p isize values can be stored.
457 * Allocation of POS_VALUE selection elements is a special case, and is
458 * handled by alloc_selection_pos_data().
461 alloc_selection_data(t_selelem *sel, int isize, gmx_bool bChildEval)
469 /* Find out the number of elements to allocate */
470 if (sel->flags & SEL_SINGLEVAL)
474 else if (sel->flags & SEL_ATOMVAL)
478 else /* sel->flags should contain SEL_VARNUMVAL */
486 child = (sel->type == SEL_SUBEXPRREF ? sel->child : sel);
487 if (child->type == SEL_SUBEXPR)
489 child = child->child;
491 nalloc = child->v.nr;
493 /* Allocate memory for sel->v.u if needed */
494 if (sel->flags & SEL_ALLOCVAL)
496 _gmx_selvalue_reserve(&sel->v, nalloc);
498 /* Reserve memory inside group structure if SEL_ALLOCDATA is set. */
499 if ((sel->flags & SEL_ALLOCDATA) && sel->v.type == GROUP_VALUE)
501 gmx_ana_index_reserve(sel->v.u.g, isize);
507 * Allocates memory for storing the evaluated value of a selection element.
509 * \param sel Selection element to initialize.
511 * Allocation of POS_VALUE selection elements is a special case, and is
512 * handled by this function instead of by alloc_selection_data().
515 alloc_selection_pos_data(t_selelem *sel)
526 if (sel->type == SEL_SUBEXPRREF)
528 child = sel->child->child;
530 nalloc = child->v.u.p->nr;
531 isize = child->v.u.p->m.b.nra;
533 /* For positions, we want to allocate just a single structure
534 * for nalloc positions. */
535 if (sel->flags & SEL_ALLOCVAL)
537 _gmx_selvalue_reserve(&sel->v, 1);
540 /* Reserve memory inside position structure if SEL_ALLOCDATA is set. */
541 if (sel->flags & SEL_ALLOCDATA)
543 gmx_ana_pos_reserve(sel->v.u.p, nalloc, isize);
548 * Replace the evaluation function of each element in the subtree.
550 * \param sel Root of the selection subtree to process.
551 * \param[in] eval The new evaluation function.
554 set_evaluation_function(t_selelem *sel, sel_evalfunc eval)
556 sel->evaluate = eval;
557 if (sel->type != SEL_SUBEXPRREF)
559 t_selelem *child = sel->child;
562 set_evaluation_function(child, eval);
569 /********************************************************************
570 * SUBEXPRESSION PROCESSING
571 ********************************************************************/
574 * Reverses the chain of selection elements starting at \p root.
576 * \param root First selection in the whole selection chain.
577 * \returns The new first element for the chain.
580 reverse_selelem_chain(t_selelem *root)
599 * Removes subexpressions that don't have any references.
601 * \param root First selection in the whole selection chain.
602 * \returns The new first element for the chain.
604 * The elements are processed in reverse order to correctly detect
605 * subexpressions only referred to by other subexpressions.
608 remove_unused_subexpressions(t_selelem *root)
614 root = reverse_selelem_chain(root);
615 while (root->child->type == SEL_SUBEXPR && root->child->refcount == 1)
618 _gmx_selelem_free(root);
626 if (item->child->type == SEL_SUBEXPR && item->child->refcount == 1)
629 _gmx_selelem_free(item);
637 return reverse_selelem_chain(root);
641 * Creates a name with a running number for a subexpression.
643 * \param[in,out] sel The subexpression to be named.
644 * \param[in] i Running number for the subexpression.
646 * The name of the selection becomes "SubExpr N", where N is \p i;
647 * Memory is allocated for the name and the name is stored both in
648 * \c t_selelem::name and \c t_selelem::u::cgrp::name; the latter
649 * is freed by _gmx_selelem_free().
652 create_subexpression_name(t_selelem *sel, int i)
657 len = 8 + (int)log10(abs(i)) + 3;
659 /* FIXME: snprintf used to be used here for extra safety, but this
660 * requires extra checking on Windows since it only provides a
661 * non-C99-conforming implementation as _snprintf()... */
662 ret = sprintf(name, "SubExpr %d", i);
663 if (ret < 0 || ret > len)
669 sel->u.cgrp.name = name;
673 * Processes and extracts subexpressions from a given selection subtree.
675 * \param sel Root of the subtree to process.
676 * \param subexprn Pointer to a subexpression counter.
677 * \returns Pointer to a chain of subselections, or NULL if none were found.
679 * This function finds recursively all \ref SEL_SUBEXPRREF elements below
680 * the given root element and ensures that their children are within
681 * \ref SEL_SUBEXPR elements. It also creates a chain of \ref SEL_ROOT elements
682 * that contain the subexpression as their children and returns the first
683 * of these root elements.
686 extract_item_subselections(t_selelem *sel, int *subexprn)
692 root = subexpr = NULL;
698 root = subexpr = extract_item_subselections(child, subexprn);
702 subexpr->next = extract_item_subselections(child, subexprn);
704 while (subexpr && subexpr->next)
706 subexpr = subexpr->next;
708 /* The latter check excludes variable references.
709 * It also excludes subexpression elements that have already been
710 * processed, because they are given a name when they are first
712 * TODO: There should be a more robust mechanism (probably a dedicated
713 * flag) for detecting parser-generated subexpressions than relying on
714 * a NULL name field. */
715 if (child->type == SEL_SUBEXPRREF && (child->child->type != SEL_SUBEXPR
716 || child->child->name == NULL))
718 /* Create the root element for the subexpression */
721 root = subexpr = _gmx_selelem_create(SEL_ROOT);
725 subexpr->next = _gmx_selelem_create(SEL_ROOT);
726 subexpr = subexpr->next;
728 /* Create the subexpression element and/or
729 * move the actual subexpression under the created element. */
730 if (child->child->type != SEL_SUBEXPR)
732 subexpr->child = _gmx_selelem_create(SEL_SUBEXPR);
733 _gmx_selelem_set_vtype(subexpr->child, child->v.type);
734 subexpr->child->child = child->child;
735 child->child = subexpr->child;
739 subexpr->child = child->child;
741 create_subexpression_name(subexpr->child, ++*subexprn);
742 subexpr->child->refcount++;
743 /* Set the flags for the created elements */
744 subexpr->flags |= (child->flags & SEL_VALFLAGMASK);
745 subexpr->child->flags |= (child->flags & SEL_VALFLAGMASK);
754 * Extracts subexpressions of the selection chain.
756 * \param sel First selection in the whole selection chain.
757 * \returns The new first element for the chain.
759 * Finds all the subexpressions (and their subexpressions) in the
760 * selection chain starting from \p sel and creates \ref SEL_SUBEXPR
762 * \ref SEL_ROOT elements are also created for each subexpression
763 * and inserted into the selection chain before the expressions that
767 extract_subexpressions(t_selelem *sel)
769 t_selelem *root, *item, *next;
777 item = extract_item_subselections(next, &subexprn);
805 /********************************************************************
806 * BOOLEAN OPERATION REORDERING
807 ********************************************************************/
810 * Removes redundant gmx_boolean selection elements.
812 * \param sel Root of the selection subtree to optimize.
814 * This function merges similar gmx_boolean operations (e.g., (A or B) or C becomes
815 * a single OR operation with three operands).
818 optimize_gmx_boolean_expressions(t_selelem *sel)
820 t_selelem *child, *prev;
822 /* Do recursively for children */
823 if (sel->type != SEL_SUBEXPRREF)
829 optimize_gmx_boolean_expressions(child);
830 /* Remove double negations */
831 if (child->type == SEL_BOOLEAN && child->u.boolt == BOOL_NOT
832 && child->child->type == SEL_BOOLEAN && child->child->u.boolt == BOOL_NOT)
834 /* Move the doubly negated expression up two levels */
837 sel->child = child->child->child;
842 prev->next = child->child->child;
845 child->child->child->next = child->next;
846 /* Remove the two negations */
847 child->child->child = NULL;
849 _gmx_selelem_free(child);
856 if (sel->type != SEL_BOOLEAN || sel->u.boolt == BOOL_NOT)
860 /* Merge subsequent binary operations */
865 if (child->type == SEL_BOOLEAN && child->u.boolt == sel->u.boolt)
869 sel->child = child->child;
874 prev->next = child->child;
880 prev->next = child->next;
894 * Reorders children of gmx_boolean expressions such that static selections
897 * \param sel Root of the selection subtree to reorder.
899 * The relative order of static expressions does not change.
900 * The same is true for the dynamic expressions.
903 reorder_gmx_boolean_static_children(t_selelem *sel)
905 t_selelem *child, *prev, *next;
907 /* Do recursively for children */
908 if (sel->type != SEL_SUBEXPRREF)
913 reorder_gmx_boolean_static_children(child);
918 /* Reorder gmx_boolean expressions such that static selections come first */
919 if (sel->type == SEL_BOOLEAN && (sel->flags & SEL_DYNAMIC))
923 start.next = sel->child;
928 /* child is the last handled static expression */
929 /* prev is the last handled non-static expression */
931 while (next && (next->flags & SEL_DYNAMIC))
936 /* next is now the first static expression after child */
941 /* Reorder such that next comes after child */
944 prev->next = next->next;
945 next->next = child->next;
952 /* Advance child by one */
956 sel->child = start.next;
961 /********************************************************************
962 * ARITHMETIC EXPRESSION PROCESSING
963 ********************************************************************/
966 * Processes arithmetic expressions to simplify and speed up evaluation.
968 * \param sel Root of the selection subtree to process.
970 * Currently, this function only converts integer constants to reals
971 * within arithmetic expressions.
974 optimize_arithmetic_expressions(t_selelem *sel)
979 /* Do recursively for children. */
980 if (sel->type != SEL_SUBEXPRREF)
985 bOk = optimize_arithmetic_expressions(child);
994 if (sel->type != SEL_ARITHMETIC)
999 /* Convert integer constants to reals. */
1003 if (child->v.type == INT_VALUE)
1007 if (child->type != SEL_CONST)
1009 gmx_impl("Non-constant integer expressions not implemented in arithmetic evaluation");
1013 r[0] = child->v.u.i[0];
1014 sfree(child->v.u.i);
1016 child->v.type = REAL_VALUE;
1018 else if (child->v.type != REAL_VALUE)
1020 gmx_bug("Internal error");
1023 child = child->next;
1029 /********************************************************************
1030 * EVALUATION PREPARATION COMPILER
1031 ********************************************************************/
1034 * Sets the evaluation functions for the selection (sub)tree.
1036 * \param[in,out] sel Root of the selection subtree to process.
1037 * \returns TRUE on success, FALSE if any subexpression fails.
1039 * This function sets the evaluation function (\c t_selelem::evaluate)
1040 * for the selection elements.
1043 init_item_evalfunc(t_selelem *sel)
1045 /* Process children. */
1046 if (sel->type != SEL_SUBEXPRREF)
1053 if (!init_item_evalfunc(child))
1057 child = child->next;
1061 /* Set the evaluation function */
1065 if (sel->v.type == GROUP_VALUE)
1067 sel->evaluate = &_gmx_sel_evaluate_static;
1071 case SEL_EXPRESSION:
1072 if (!(sel->flags & SEL_DYNAMIC) && sel->u.expr.method
1073 && sel->u.expr.method->init_frame)
1075 sel->flags |= SEL_INITFRAME;
1077 sel->evaluate = &_gmx_sel_evaluate_method;
1080 case SEL_ARITHMETIC:
1081 sel->evaluate = &_gmx_sel_evaluate_arithmetic;
1085 if (sel->v.type != NO_VALUE)
1087 sel->evaluate = &_gmx_sel_evaluate_modifier;
1092 switch (sel->u.boolt)
1094 case BOOL_NOT: sel->evaluate = &_gmx_sel_evaluate_not; break;
1095 case BOOL_AND: sel->evaluate = &_gmx_sel_evaluate_and; break;
1096 case BOOL_OR: sel->evaluate = &_gmx_sel_evaluate_or; break;
1098 gmx_impl("xor expressions not implemented");
1104 sel->evaluate = &_gmx_sel_evaluate_root;
1108 if (sel->refcount == 2
1109 && !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR))
1111 sel->evaluate = &_gmx_sel_evaluate_subexpr_simple;
1115 sel->evaluate = &_gmx_sel_evaluate_subexpr;
1119 case SEL_SUBEXPRREF:
1120 sel->name = sel->child->name;
1121 sel->evaluate = ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
1122 ? &_gmx_sel_evaluate_subexprref_simple
1123 : &_gmx_sel_evaluate_subexprref);
1126 sel->cdata->evaluate = sel->evaluate;
1131 * Sets the memory pool for selection elements that can use it.
1133 * \param sel Root of the selection subtree to process.
1134 * \param[in] mempool Memory pool to use.
1137 setup_memory_pooling(t_selelem *sel, gmx_sel_mempool_t *mempool)
1139 if (sel->type != SEL_SUBEXPRREF)
1146 if ((sel->type == SEL_BOOLEAN && (child->flags & SEL_DYNAMIC))
1147 || (sel->type == SEL_ARITHMETIC && child->type != SEL_CONST
1148 && !(child->flags & SEL_SINGLEVAL))
1149 || (sel->type == SEL_SUBEXPR && sel->refcount > 2))
1151 child->mempool = mempool;
1152 if (child->type == SEL_SUBEXPRREF
1153 && child->child->refcount == 2)
1155 child->child->child->mempool = mempool;
1158 setup_memory_pooling(child, mempool);
1159 child = child->next;
1165 * Prepares the selection (sub)tree for evaluation.
1167 * \param[in,out] sel Root of the selection subtree to prepare.
1169 * It also allocates memory for the \p sel->v.u.g or \p sel->v.u.p
1170 * structure if required.
1173 init_item_evaloutput(t_selelem *sel)
1175 /* Process children. */
1176 if (sel->type != SEL_SUBEXPRREF)
1183 init_item_evaloutput(child);
1184 child = child->next;
1188 if (sel->type == SEL_SUBEXPR && sel->refcount == 2
1189 && !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR))
1191 sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
1192 if (sel->v.type == GROUP_VALUE || sel->v.type == POS_VALUE)
1194 _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr);
1197 else if (sel->type == SEL_SUBEXPR
1198 && (sel->cdata->flags & SEL_CDATA_FULLEVAL))
1200 sel->evaluate = &_gmx_sel_evaluate_subexpr_staticeval;
1201 sel->cdata->evaluate = sel->evaluate;
1202 sel->child->mempool = NULL;
1203 sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
1204 if (sel->v.type == GROUP_VALUE || sel->v.type == POS_VALUE)
1206 _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr);
1209 else if (sel->type == SEL_SUBEXPRREF
1210 && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))
1214 _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr);
1215 _gmx_selelem_free_values(sel->child->child);
1216 sel->child->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
1217 sel->child->child->flags |= (sel->flags & SEL_ALLOCDATA);
1218 _gmx_selvalue_setstore(&sel->child->child->v, sel->v.u.ptr);
1220 else if (sel->v.type == GROUP_VALUE || sel->v.type == POS_VALUE)
1222 _gmx_selvalue_setstore(&sel->v, sel->child->child->v.u.ptr);
1224 sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
1227 /* Make sure that the group/position structure is allocated. */
1228 if (!sel->v.u.ptr && (sel->flags & SEL_ALLOCVAL))
1230 if (sel->v.type == GROUP_VALUE || sel->v.type == POS_VALUE)
1232 _gmx_selvalue_reserve(&sel->v, 1);
1239 /********************************************************************
1240 * COMPILER DATA INITIALIZATION
1241 ********************************************************************/
1244 * Allocates memory for the compiler data and initializes the structure.
1246 * \param sel Root of the selection subtree to process.
1249 init_item_compilerdata(t_selelem *sel)
1253 /* Allocate the compiler data structure */
1254 snew(sel->cdata, 1);
1256 /* Store the real evaluation method because the compiler will replace it */
1257 sel->cdata->evaluate = sel->evaluate;
1259 /* Initialize the flags */
1260 sel->cdata->flags = SEL_CDATA_STATICEVAL;
1261 if (!(sel->flags & SEL_DYNAMIC))
1263 sel->cdata->flags |= SEL_CDATA_STATIC;
1265 if (sel->type == SEL_SUBEXPR)
1267 sel->cdata->flags |= SEL_CDATA_EVALMAX;
1269 /* Set the full evaluation flag for subexpressions that require it;
1270 * the subexpression has already been initialized, so we can simply
1271 * access its compilation flags.*/
1272 if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER)
1277 if (!(child->flags & SEL_ATOMVAL) && child->child)
1279 child->child->cdata->flags |= SEL_CDATA_FULLEVAL;
1281 child = child->next;
1284 else if (sel->type == SEL_ROOT && sel->child->type == SEL_SUBEXPRREF)
1286 sel->child->child->cdata->flags |= SEL_CDATA_FULLEVAL;
1289 /* Initialize children */
1290 if (sel->type != SEL_SUBEXPRREF)
1295 init_item_compilerdata(child);
1296 child = child->next;
1300 /* Determine whether we should evaluate the minimum or the maximum
1301 * for the children of this element. */
1302 if (sel->type == SEL_BOOLEAN)
1306 bEvalMax = (sel->u.boolt == BOOL_AND);
1312 child->cdata->flags |= SEL_CDATA_EVALMAX;
1314 else if (child->type == SEL_BOOLEAN && child->u.boolt == BOOL_NOT)
1316 child->child->cdata->flags |= SEL_CDATA_EVALMAX;
1318 child = child->next;
1321 else if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER
1322 || sel->type == SEL_SUBEXPR)
1327 child->cdata->flags |= SEL_CDATA_EVALMAX;
1328 child = child->next;
1334 * Initializes the static evaluation flag for a selection subtree.
1336 * \param[in,out] sel Root of the selection subtree to process.
1338 * Sets the \c bStaticEval in the compiler data structure:
1339 * for any element for which the evaluation group may depend on the trajectory
1340 * frame, the flag is cleared.
1342 * reorder_gmx_boolean_static_children() should have been called.
1345 init_item_staticeval(t_selelem *sel)
1349 /* Subexpressions with full evaluation should always have bStaticEval,
1350 * so don't do anything if a reference to them is encountered. */
1351 if (sel->type == SEL_SUBEXPRREF
1352 && (sel->child->cdata->flags & SEL_CDATA_FULLEVAL))
1357 /* Propagate the bStaticEval flag to children if it is not set */
1358 if (!(sel->cdata->flags & SEL_CDATA_STATICEVAL))
1363 if ((sel->type != SEL_EXPRESSION && sel->type != SEL_MODIFIER)
1364 || (child->flags & SEL_ATOMVAL))
1366 if (child->cdata->flags & SEL_CDATA_STATICEVAL)
1368 child->cdata->flags &= ~SEL_CDATA_STATICEVAL;
1369 init_item_staticeval(child);
1372 /* If an expression is evaluated for a dynamic group, then also
1373 * atom-valued parameters need to be evaluated every time. */
1374 if ((sel->flags & SEL_DYNAMIC)
1375 && (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER)
1376 && (child->flags & SEL_ATOMVAL))
1378 child->flags |= SEL_DYNAMIC;
1379 child->cdata->flags &= ~SEL_CDATA_STATIC;
1381 child = child->next;
1384 else /* bStaticEval is set */
1386 /* For gmx_boolean expressions, any expression after the first dynamic
1387 * expression should not have bStaticEval. */
1388 if (sel->type == SEL_BOOLEAN)
1391 while (child && !(child->flags & SEL_DYNAMIC))
1393 child = child->next;
1397 child = child->next;
1401 child->cdata->flags &= ~SEL_CDATA_STATICEVAL;
1402 child = child->next;
1406 /* Process the children */
1410 init_item_staticeval(child);
1411 child = child->next;
1417 * Initializes compiler flags for subexpressions.
1419 * \param sel Root of the selection subtree to process.
1422 init_item_subexpr_flags(t_selelem *sel)
1424 if (sel->type == SEL_SUBEXPR)
1426 if (sel->refcount == 2)
1428 sel->cdata->flags |= SEL_CDATA_SIMPLESUBEXPR;
1430 else if (!(sel->cdata->flags & SEL_CDATA_FULLEVAL))
1432 sel->cdata->flags |= SEL_CDATA_COMMONSUBEXPR;
1435 else if (sel->type == SEL_SUBEXPRREF && sel->child->refcount == 2)
1437 /* See similar condition in init_item_staticeval(). */
1438 if ((sel->flags & SEL_ATOMVAL)
1439 && (sel->flags & SEL_DYNAMIC)
1440 && !(sel->child->flags & SEL_DYNAMIC))
1442 sel->child->cdata->flags |= SEL_CDATA_STATICMULTIEVALSUBEXPR;
1446 sel->cdata->flags |= SEL_CDATA_SIMPLESUBEXPR;
1450 /* Process children, but only follow subexpression references if the
1451 * common subexpression flag needs to be propagated. */
1452 if (sel->type != SEL_SUBEXPRREF
1453 || ((sel->cdata->flags & SEL_CDATA_COMMONSUBEXPR)
1454 && sel->child->refcount > 2))
1456 t_selelem *child = sel->child;
1460 if (!(child->cdata->flags & SEL_CDATA_COMMONSUBEXPR))
1462 if (sel->type != SEL_EXPRESSION || (child->flags & SEL_ATOMVAL))
1464 child->cdata->flags |=
1465 (sel->cdata->flags & SEL_CDATA_COMMONSUBEXPR);
1467 init_item_subexpr_flags(child);
1469 child = child->next;
1475 * Initializes the gmin and gmax fields of the compiler data structure.
1477 * \param sel Root of the selection subtree to process.
1480 init_item_minmax_groups(t_selelem *sel)
1482 /* Process children. */
1483 if (sel->type != SEL_SUBEXPRREF)
1490 init_item_minmax_groups(child);
1491 child = child->next;
1495 /* Initialize the minimum and maximum evaluation groups. */
1496 if (sel->type != SEL_ROOT && sel->v.type != NO_VALUE)
1498 if (sel->v.type == GROUP_VALUE
1499 && (sel->cdata->flags & SEL_CDATA_STATIC))
1501 sel->cdata->gmin = sel->v.u.g;
1502 sel->cdata->gmax = sel->v.u.g;
1504 else if (sel->type == SEL_SUBEXPR
1505 && ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
1506 || (sel->cdata->flags & SEL_CDATA_FULLEVAL)))
1508 sel->cdata->gmin = sel->child->cdata->gmin;
1509 sel->cdata->gmax = sel->child->cdata->gmax;
1513 sel->cdata->flags |= SEL_CDATA_MINMAXALLOC;
1514 snew(sel->cdata->gmin, 1);
1515 snew(sel->cdata->gmax, 1);
1521 /********************************************************************
1522 * EVALUATION GROUP INITIALIZATION
1523 ********************************************************************/
1526 * Initializes evaluation groups for root items.
1528 * \param[in,out] sc Selection collection data.
1530 * The evaluation group of each \ref SEL_ROOT element corresponding to a
1531 * selection in \p sc is set to NULL. The evaluation grop for \ref SEL_ROOT
1532 * elements corresponding to subexpressions that need full evaluation is set
1536 initialize_evalgrps(gmx_ana_selcollection_t *sc)
1543 if (root->child->type != SEL_SUBEXPR
1544 || (root->child->v.type != GROUP_VALUE && !(root->flags & SEL_ATOMVAL)))
1546 gmx_ana_index_set(&root->u.cgrp, -1, 0, root->u.cgrp.name, 0);
1548 else if (root->child->cdata->flags & SEL_CDATA_FULLEVAL)
1550 gmx_ana_index_set(&root->u.cgrp, sc->gall.isize, sc->gall.index,
1551 root->u.cgrp.name, 0);
1558 /********************************************************************
1560 ********************************************************************/
1563 * Marks a subtree completely dynamic or undoes such a change.
1565 * \param sel Selection subtree to mark.
1566 * \param[in] bDynamic If TRUE, the \p bStatic flag of the whole
1567 * selection subtree is cleared. If FALSE, the flag is restored to
1568 * using \ref SEL_DYNAMIC.
1570 * Does not descend into parameters of methods unless the parameters
1571 * are evaluated for each atom.
1574 mark_subexpr_dynamic(t_selelem *sel, gmx_bool bDynamic)
1578 if (!bDynamic && !(sel->flags & SEL_DYNAMIC))
1580 sel->cdata->flags |= SEL_CDATA_STATIC;
1584 sel->cdata->flags &= ~SEL_CDATA_STATIC;
1589 if (sel->type != SEL_EXPRESSION || child->type != SEL_SUBEXPRREF
1590 || (child->u.param->flags & SPAR_ATOMVAL))
1592 mark_subexpr_dynamic(child, bDynamic);
1594 child = child->next;
1599 * Frees memory for subexpressions that are no longer needed.
1601 * \param sel Selection subtree to check.
1603 * Checks whether the subtree rooted at \p sel refers to any \ref SEL_SUBEXPR
1604 * elements that are not referred to by anything else except their own root
1605 * element. If such elements are found, all memory allocated for them is freed
1606 * except the actual element. The element is left because otherwise a dangling
1607 * pointer would be left at the root element, which is not traversed by this
1608 * function. Later compilation passes remove the stub elements.
1611 release_subexpr_memory(t_selelem *sel)
1613 if (sel->type == SEL_SUBEXPR)
1615 if (sel->refcount == 2)
1617 release_subexpr_memory(sel->child);
1619 _gmx_selelem_free_chain(sel->child);
1620 _gmx_selelem_free_values(sel);
1621 _gmx_selelem_free_exprdata(sel);
1622 _gmx_selelem_free_compiler_data(sel);
1633 release_subexpr_memory(child);
1634 child = child->next;
1640 * Makes an evaluated selection element static.
1642 * \param sel Selection element to make static.
1644 * The evaluated value becomes the value of the static element.
1645 * The element type is changed to SEL_CONST and the children are
1649 make_static(t_selelem *sel)
1651 /* If this is a subexpression reference and the data is stored in the
1652 * child, we transfer data ownership before doing anything else. */
1653 if (sel->type == SEL_SUBEXPRREF
1654 && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))
1656 if (sel->child->child->flags & SEL_ALLOCDATA)
1658 sel->flags |= SEL_ALLOCDATA;
1659 sel->child->child->flags &= ~SEL_ALLOCDATA;
1661 if (sel->child->child->flags & SEL_ALLOCVAL)
1663 sel->flags |= SEL_ALLOCVAL;
1664 sel->v.nalloc = sel->child->child->v.nalloc;
1665 sel->child->child->flags &= ~SEL_ALLOCVAL;
1666 sel->child->child->v.nalloc = -1;
1669 /* When we reach here for parameter elements, the value is already
1670 * stored in the parent element, so make sure that it is not freed
1671 * through this element. */
1672 if (sel->type == SEL_SUBEXPRREF && sel->u.param)
1674 sel->u.param->val.nalloc = sel->v.nalloc;
1675 sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
1678 /* Free the children. */
1679 release_subexpr_memory(sel);
1680 _gmx_selelem_free_chain(sel->child);
1682 /* Free the expression data as it is no longer needed */
1683 _gmx_selelem_free_exprdata(sel);
1684 /* Make the item static */
1686 sel->type = SEL_CONST;
1687 sel->evaluate = NULL;
1688 sel->cdata->evaluate = NULL;
1689 /* Set the group value.
1690 * free_exprdata above frees the cgrp group, so we can just override it. */
1691 if (sel->v.type == GROUP_VALUE)
1693 gmx_ana_index_set(&sel->u.cgrp, sel->v.u.g->isize, sel->v.u.g->index, NULL, 0);
1698 * Evaluates a constant expression during analyze_static().
1700 * \param[in] data Evaluation data.
1701 * \param[in,out] sel Selection to process.
1702 * \param[in] g The evaluation group.
1703 * \returns 0 on success, a non-zero error code on error.
1706 process_const(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
1711 if (sel->v.type == GROUP_VALUE)
1713 if (sel->cdata->evaluate)
1715 rc = sel->cdata->evaluate(data, sel, g);
1718 /* Other constant expressions do not need evaluation */
1723 * Sets the parameter value pointer for \ref SEL_SUBEXPRREF params.
1725 * \param[in,out] sel Selection to process.
1727 * Copies the value pointer of \p sel to \c sel->u.param if one is present
1728 * and should receive the value from the compiler
1729 * (most parameter values are handled during parsing).
1730 * If \p sel is not of type \ref SEL_SUBEXPRREF, or if \c sel->u.param is NULL,
1731 * the function does nothing.
1732 * Also, if the \c sel->u.param does not have \ref SPAR_VARNUM or
1733 * \ref SPAR_ATOMVAL, the function returns immediately.
1736 store_param_val(t_selelem *sel)
1738 /* Return immediately if there is no parameter. */
1739 if (sel->type != SEL_SUBEXPRREF || !sel->u.param)
1744 /* Or if the value does not need storing. */
1745 if (!(sel->u.param->flags & (SPAR_VARNUM | SPAR_ATOMVAL)))
1750 if (sel->v.type == INT_VALUE || sel->v.type == REAL_VALUE
1751 || sel->v.type == STR_VALUE)
1753 _gmx_selvalue_setstore(&sel->u.param->val, sel->v.u.ptr);
1758 * Handles the initialization of a selection method during analyze_static() pass.
1760 * \param[in,out] sel Selection element to process.
1761 * \param[in] top Topology structure.
1762 * \param[in] isize Size of the evaluation group for the element.
1763 * \returns 0 on success, a non-zero error code on return.
1765 * Calls sel_initfunc() (and possibly sel_outinitfunc()) to initialize the
1767 * If no \ref SPAR_ATOMVAL parameters are present, multiple initialization
1768 * is prevented by using \ref SEL_METHODINIT and \ref SEL_OUTINIT flags.
1771 init_method(t_selelem *sel, t_topology *top, int isize)
1777 /* Find out whether there are any atom-valued parameters */
1782 if (child->flags & SEL_ATOMVAL)
1786 child = child->next;
1789 /* Initialize the method */
1790 if (sel->u.expr.method->init
1791 && (bAtomVal || !(sel->flags & SEL_METHODINIT)))
1793 sel->flags |= SEL_METHODINIT;
1794 rc = sel->u.expr.method->init(top, sel->u.expr.method->nparams,
1795 sel->u.expr.method->param, sel->u.expr.mdata);
1801 if (bAtomVal || !(sel->flags & SEL_OUTINIT))
1803 sel->flags |= SEL_OUTINIT;
1804 if (sel->u.expr.method->outinit)
1806 rc = sel->u.expr.method->outinit(top, &sel->v, sel->u.expr.mdata);
1811 if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE
1812 && !(sel->flags & SEL_VARNUMVAL))
1814 alloc_selection_data(sel, isize, TRUE);
1819 alloc_selection_data(sel, isize, TRUE);
1820 if ((sel->flags & SEL_DYNAMIC)
1821 && sel->v.type != GROUP_VALUE && sel->v.type != POS_VALUE)
1825 /* If the method is char-valued, pre-allocate the strings. */
1826 if (sel->u.expr.method->flags & SMETH_CHARVAL)
1830 /* A sanity check */
1831 if (sel->v.type != STR_VALUE)
1833 gmx_bug("internal error");
1836 sel->flags |= SEL_ALLOCDATA;
1837 for (i = 0; i < isize; ++i)
1839 if (sel->v.u.s[i] == NULL)
1841 snew(sel->v.u.s[i], 2);
1846 /* Clear the values for dynamic output to avoid valgrind warnings. */
1847 if ((sel->flags & SEL_DYNAMIC) && sel->v.type == REAL_VALUE)
1851 for (i = 0; i < sel->v.nr; ++i)
1853 sel->v.u.r[i] = 0.0;
1862 * Evaluates the static part of a gmx_boolean expression.
1864 * \param[in] data Evaluation data.
1865 * \param[in,out] sel Boolean selection element whose children should be
1867 * \param[in] g The evaluation group.
1868 * \returns 0 on success, a non-zero error code on error.
1870 * reorder_item_static_children() should have been called.
1873 evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
1876 t_selelem *child, *next;
1879 /* Find the last static subexpression */
1881 while (child->next && (child->next->cdata->flags & SEL_CDATA_STATIC))
1883 child = child->next;
1885 if (!(child->cdata->flags & SEL_CDATA_STATIC))
1890 /* Evalute the static part if there is more than one expression */
1891 if (child != sel->child)
1895 rc = sel->cdata->evaluate(data, sel, g);
1900 /* Replace the subexpressions with the result */
1901 _gmx_selelem_free_chain(sel->child);
1903 child->type = SEL_CONST;
1904 child->flags = SEL_FLAGSSET | SEL_SINGLEVAL | SEL_ALLOCVAL | SEL_ALLOCDATA;
1905 _gmx_selelem_set_vtype(child, GROUP_VALUE);
1906 child->evaluate = NULL;
1907 _gmx_selvalue_reserve(&child->v, 1);
1908 gmx_ana_index_copy(child->v.u.g, sel->v.u.g, TRUE);
1909 init_item_compilerdata(child);
1910 init_item_minmax_groups(child);
1911 child->cdata->flags &= ~SEL_CDATA_STATICEVAL;
1912 child->cdata->flags |= sel->cdata->flags & SEL_CDATA_STATICEVAL;
1916 else if (child->evaluate)
1918 rc = child->evaluate(data, child, g);
1924 /* Set the evaluation function for the constant element.
1925 * We never need to evaluate the element again during compilation,
1926 * but we may need to evaluate the static part again if the
1927 * expression is not an OR with a static evaluation group.
1928 * If we reach here with a NOT expression, the NOT expression
1929 * is also static, and will be made a constant later, so don't waste
1930 * time copying the group. */
1931 child->evaluate = NULL;
1932 if (sel->u.boolt == BOOL_NOT
1933 || ((sel->cdata->flags & SEL_CDATA_STATICEVAL)
1934 && sel->u.boolt == BOOL_OR))
1936 child->cdata->evaluate = NULL;
1940 child->cdata->evaluate = &_gmx_sel_evaluate_static;
1941 /* The cgrp has only been allocated if it originated from an
1942 * external index group. In that case, we need special handling
1943 * to preserve the name of the group and to not leak memory.
1944 * If cgrp has been set in make_static(), it is not allocated,
1945 * and hence we can overwrite it safely. */
1946 if (child->u.cgrp.nalloc_index > 0)
1948 char *name = child->u.cgrp.name;
1949 gmx_ana_index_copy(&child->u.cgrp, child->v.u.g, FALSE);
1950 gmx_ana_index_squeeze(&child->u.cgrp);
1951 child->u.cgrp.name = name;
1955 gmx_ana_index_copy(&child->u.cgrp, child->v.u.g, TRUE);
1962 * Evaluates the minimum and maximum groups for a gmx_boolean expression.
1964 * \param[in] sel \ref SEL_BOOLEAN element currently being evaluated.
1965 * \param[in] g Group for which \p sel has been evaluated.
1966 * \param[out] gmin Largest subset of the possible values of \p sel.
1967 * \param[out] gmax Smallest superset of the possible values of \p sel.
1969 * This is a helper function for analyze_static() that is called for
1970 * dynamic \ref SEL_BOOLEAN elements after they have been evaluated.
1971 * It uses the minimum and maximum groups of the children to calculate
1972 * the minimum and maximum groups for \p sel, and also updates the static
1973 * part of \p sel (which is in the first child) if the children give
1976 * This function may allocate some extra memory for \p gmin and \p gmax,
1977 * but as these groups are freed at the end of analyze_static() (which is
1978 * reached shortly after this function returns), this should not be a major
1982 evaluate_gmx_boolean_minmax_grps(t_selelem *sel, gmx_ana_index_t *g,
1983 gmx_ana_index_t *gmin, gmx_ana_index_t *gmax)
1987 switch (sel->u.boolt)
1990 gmx_ana_index_reserve(gmin, g->isize);
1991 gmx_ana_index_reserve(gmax, g->isize);
1992 gmx_ana_index_difference(gmax, g, sel->child->cdata->gmin);
1993 gmx_ana_index_difference(gmin, g, sel->child->cdata->gmax);
1997 gmx_ana_index_copy(gmin, sel->child->cdata->gmin, TRUE);
1998 gmx_ana_index_copy(gmax, sel->child->cdata->gmax, TRUE);
1999 child = sel->child->next;
2000 while (child && gmax->isize > 0)
2002 gmx_ana_index_intersection(gmin, gmin, child->cdata->gmin);
2003 gmx_ana_index_intersection(gmax, gmax, child->cdata->gmax);
2004 child = child->next;
2006 /* Update the static part if other expressions limit it */
2007 if ((sel->child->cdata->flags & SEL_CDATA_STATIC)
2008 && sel->child->v.u.g->isize > gmax->isize)
2010 gmx_ana_index_copy(sel->child->v.u.g, gmax, FALSE);
2011 gmx_ana_index_squeeze(sel->child->v.u.g);
2012 if (sel->child->u.cgrp.isize > 0)
2014 gmx_ana_index_copy(&sel->child->u.cgrp, gmax, FALSE);
2015 gmx_ana_index_squeeze(&sel->child->u.cgrp);
2021 /* We can assume here that the gmin of children do not overlap
2022 * because of the way _gmx_sel_evaluate_or() works. */
2023 gmx_ana_index_reserve(gmin, g->isize);
2024 gmx_ana_index_reserve(gmax, g->isize);
2025 gmx_ana_index_copy(gmin, sel->child->cdata->gmin, FALSE);
2026 gmx_ana_index_copy(gmax, sel->child->cdata->gmax, FALSE);
2027 child = sel->child->next;
2028 while (child && gmin->isize < g->isize)
2030 gmx_ana_index_merge(gmin, gmin, child->cdata->gmin);
2031 gmx_ana_index_union(gmax, gmax, child->cdata->gmax);
2032 child = child->next;
2034 /* Update the static part if other expressions have static parts
2035 * that are not included. */
2036 if ((sel->child->cdata->flags & SEL_CDATA_STATIC)
2037 && sel->child->v.u.g->isize < gmin->isize)
2039 gmx_ana_index_reserve(sel->child->v.u.g, gmin->isize);
2040 gmx_ana_index_copy(sel->child->v.u.g, gmin, FALSE);
2041 if (sel->child->u.cgrp.nalloc_index > 0)
2043 /* Keep the name as in evaluate_boolean_static_part(). */
2044 char *name = sel->child->u.cgrp.name;
2045 gmx_ana_index_reserve(&sel->child->u.cgrp, gmin->isize);
2046 gmx_ana_index_copy(&sel->child->u.cgrp, gmin, FALSE);
2047 sel->child->u.cgrp.name = name;
2051 sel->child->u.cgrp.isize = sel->child->v.u.g->isize;
2056 case BOOL_XOR: /* Should not be reached */
2057 gmx_impl("xor expressions not implemented");
2063 * Evaluates the static parts of \p sel and analyzes the structure.
2065 * \param[in] data Evaluation data.
2066 * \param[in,out] sel Selection currently being evaluated.
2067 * \param[in] g Group for which \p sel should be evaluated.
2068 * \returns 0 on success, a non-zero error code on error.
2070 * This function is used as the replacement for the \c t_selelem::evaluate
2072 * It does the single most complex task in the compiler: after all elements
2073 * have been processed, the \p gmin and \p gmax fields of \p t_compiler_data
2074 * have been properly initialized, enough memory has been allocated for
2075 * storing the value of each expression, and the static parts of the
2076 * expressions have been evaluated.
2077 * The above is exactly true only for elements other than subexpressions:
2078 * another pass is required for subexpressions that are referred to more than
2079 * once and whose evaluation group is not known in advance.
2082 analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
2084 t_selelem *child, *next;
2088 if (sel->type != SEL_ROOT && g)
2090 alloc_selection_data(sel, g->isize, FALSE);
2093 bDoMinMax = (sel->cdata->flags & SEL_CDATA_MINMAXALLOC);
2094 if (sel->type != SEL_SUBEXPR && bDoMinMax)
2096 gmx_ana_index_deinit(sel->cdata->gmin);
2097 gmx_ana_index_deinit(sel->cdata->gmax);
2100 /* TODO: This switch is awfully long... */
2105 rc = process_const(data, sel, g);
2108 case SEL_EXPRESSION:
2110 rc = _gmx_sel_evaluate_method_params(data, sel, g);
2115 rc = init_method(sel, data->top, g ? g->isize : 0);
2120 if (!(sel->flags & SEL_DYNAMIC))
2122 rc = sel->cdata->evaluate(data, sel, g);
2123 if (rc == 0 && (sel->cdata->flags & SEL_CDATA_STATIC))
2130 /* Modifiers need to be evaluated even though they process
2131 * positions to get the modified output groups from the
2132 * maximum possible selections. */
2133 if (sel->type == SEL_MODIFIER)
2135 rc = sel->cdata->evaluate(data, sel, g);
2139 gmx_ana_index_copy(sel->cdata->gmax, g, TRUE);
2145 if (!(sel->flags & SEL_DYNAMIC))
2147 rc = sel->cdata->evaluate(data, sel, g);
2148 if (rc == 0 && (sel->cdata->flags & SEL_CDATA_STATIC))
2155 /* Evalute the static part if there is more than one expression */
2156 rc = evaluate_gmx_boolean_static_part(data, sel, g);
2162 /* Evaluate the selection.
2163 * If the type is gmx_boolean, we must explicitly handle the
2164 * static part evaluated in evaluate_gmx_boolean_static_part()
2165 * here because g may be larger. */
2166 if (sel->u.boolt == BOOL_AND && sel->child->type == SEL_CONST)
2168 rc = sel->cdata->evaluate(data, sel, sel->child->v.u.g);
2172 rc = sel->cdata->evaluate(data, sel, g);
2179 /* Evaluate minimal and maximal selections */
2180 evaluate_gmx_boolean_minmax_grps(sel, g, sel->cdata->gmin,
2185 case SEL_ARITHMETIC:
2186 rc = sel->cdata->evaluate(data, sel, g);
2191 if (!(sel->flags & SEL_DYNAMIC))
2193 if (sel->cdata->flags & SEL_CDATA_STATIC)
2200 gmx_ana_index_copy(sel->cdata->gmax, g, TRUE);
2205 rc = sel->cdata->evaluate(data, sel, g);
2209 if (((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) &&
2210 !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR))
2211 || (sel->cdata->flags & SEL_CDATA_FULLEVAL))
2213 rc = sel->cdata->evaluate(data, sel, g);
2214 _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr);
2216 else if (sel->u.cgrp.isize == 0)
2218 gmx_ana_index_reserve(&sel->u.cgrp, g->isize);
2219 rc = sel->cdata->evaluate(data, sel, g);
2222 gmx_ana_index_copy(sel->cdata->gmin, sel->child->cdata->gmin, TRUE);
2223 gmx_ana_index_copy(sel->cdata->gmax, sel->child->cdata->gmax, TRUE);
2228 int isize = gmx_ana_index_difference_size(g, &sel->u.cgrp);
2231 isize += sel->u.cgrp.isize;
2232 gmx_ana_index_reserve(&sel->u.cgrp, isize);
2233 alloc_selection_data(sel, isize, FALSE);
2235 rc = sel->cdata->evaluate(data, sel, g);
2236 if (isize > 0 && bDoMinMax)
2238 gmx_ana_index_reserve(sel->cdata->gmin,
2239 sel->cdata->gmin->isize
2240 + sel->child->cdata->gmin->isize);
2241 gmx_ana_index_reserve(sel->cdata->gmax,
2242 sel->cdata->gmax->isize
2243 + sel->child->cdata->gmax->isize);
2244 gmx_ana_index_merge(sel->cdata->gmin, sel->cdata->gmin,
2245 sel->child->cdata->gmin);
2246 gmx_ana_index_merge(sel->cdata->gmax, sel->cdata->gmax,
2247 sel->child->cdata->gmax);
2252 case SEL_SUBEXPRREF:
2253 if (!g && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))
2255 /* The subexpression should have been evaluated if g is NULL
2256 * (i.e., this is a method parameter or a direct value of a
2258 if (sel->v.type == POS_VALUE)
2260 alloc_selection_pos_data(sel);
2264 alloc_selection_data(sel, sel->child->cdata->gmax->isize, TRUE);
2267 rc = sel->cdata->evaluate(data, sel, g);
2272 if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
2273 && (sel->child->child->flags & SEL_ALLOCVAL))
2275 _gmx_selvalue_setstore(&sel->v, sel->child->child->v.u.ptr);
2277 /* Store the parameter value if required */
2278 store_param_val(sel);
2279 if (!(sel->flags & SEL_DYNAMIC))
2281 if (sel->cdata->flags & SEL_CDATA_STATIC)
2288 if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) || !g)
2290 gmx_ana_index_copy(sel->cdata->gmin, sel->child->cdata->gmin, TRUE);
2291 gmx_ana_index_copy(sel->cdata->gmax, sel->child->cdata->gmax, TRUE);
2295 gmx_ana_index_reserve(sel->cdata->gmin,
2296 min(g->isize, sel->child->cdata->gmin->isize));
2297 gmx_ana_index_reserve(sel->cdata->gmax,
2298 min(g->isize, sel->child->cdata->gmax->isize));
2299 gmx_ana_index_intersection(sel->cdata->gmin,
2300 sel->child->cdata->gmin, g);
2301 gmx_ana_index_intersection(sel->cdata->gmax,
2302 sel->child->cdata->gmax, g);
2307 /* Exit if there was some problem */
2313 /* Update the minimal and maximal evaluation groups */
2316 gmx_ana_index_squeeze(sel->cdata->gmin);
2317 gmx_ana_index_squeeze(sel->cdata->gmax);
2318 sfree(sel->cdata->gmin->name);
2319 sfree(sel->cdata->gmax->name);
2320 sel->cdata->gmin->name = NULL;
2321 sel->cdata->gmax->name = NULL;
2324 /* Replace the result of the evaluation */
2325 /* This is not necessary for subexpressions or for gmx_boolean negations
2326 * because the evaluation function already has done it properly. */
2327 if (sel->v.type == GROUP_VALUE && (sel->flags & SEL_DYNAMIC)
2328 && sel->type != SEL_SUBEXPR
2329 && !(sel->type == SEL_BOOLEAN && sel->u.boolt == BOOL_NOT))
2331 if (sel->cdata->flags & SEL_CDATA_EVALMAX)
2333 gmx_ana_index_copy(sel->v.u.g, sel->cdata->gmax, FALSE);
2337 gmx_ana_index_copy(sel->v.u.g, sel->cdata->gmin, FALSE);
2345 /********************************************************************
2346 * EVALUATION GROUP INITIALIZATION
2347 ********************************************************************/
2350 * Initializes the evaluation group for a \ref SEL_ROOT element.
2352 * \param root Root element to initialize.
2353 * \param[in] gall Group of all atoms.
2355 * Checks whether it is necessary to evaluate anything through the root
2356 * element, and either clears the evaluation function or initializes the
2360 init_root_item(t_selelem *root, gmx_ana_index_t *gall)
2366 /* Subexpressions with non-static evaluation group should not be
2367 * evaluated by the root, and neither should be single-reference
2368 * subexpressions that don't evaluate for all atoms. */
2369 if (expr->type == SEL_SUBEXPR
2370 && (!(root->child->cdata->flags & SEL_CDATA_STATICEVAL)
2371 || ((root->child->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
2372 && !(root->child->cdata->flags & SEL_CDATA_FULLEVAL))))
2374 root->evaluate = NULL;
2377 root->cdata->evaluate = NULL;
2381 /* Set the evaluation group */
2382 name = root->u.cgrp.name;
2385 /* Non-atom-valued non-group expressions don't care about the group, so
2386 * don't allocate any memory for it. */
2387 if ((expr->flags & SEL_VARNUMVAL)
2388 || ((expr->flags & SEL_SINGLEVAL) && expr->v.type != GROUP_VALUE))
2390 gmx_ana_index_set(&root->u.cgrp, -1, NULL, NULL, 0);
2392 else if (expr->cdata->gmax->isize == gall->isize)
2394 /* Save some memory by only referring to the global group. */
2395 gmx_ana_index_set(&root->u.cgrp, gall->isize, gall->index, NULL, 0);
2399 gmx_ana_index_copy(&root->u.cgrp, expr->cdata->gmax, TRUE);
2401 /* For selections, store the maximum group for
2402 * gmx_ana_selcollection_evaluate_fin() as the value of the root
2403 * element (unused otherwise). */
2404 if (expr->type != SEL_SUBEXPR && expr->v.u.p->g)
2406 t_selelem *child = expr;
2408 /* TODO: This code is copied from parsetree.c; it would be better
2409 * to have this hardcoded only in one place. */
2410 while (child->type == SEL_MODIFIER)
2412 child = child->child;
2413 if (child->type == SEL_SUBEXPRREF)
2415 child = child->child->child;
2418 if (child->type == SEL_SUBEXPRREF)
2420 child = child->child->child;
2422 if (child->child->flags & SEL_DYNAMIC)
2424 _gmx_selelem_set_vtype(root, GROUP_VALUE);
2425 root->flags |= (SEL_ALLOCVAL | SEL_ALLOCDATA);
2426 _gmx_selvalue_reserve(&root->v, 1);
2427 gmx_ana_index_copy(root->v.u.g, expr->v.u.p->g, TRUE);
2433 gmx_ana_index_clear(&root->u.cgrp);
2435 root->u.cgrp.name = name;
2439 /********************************************************************
2440 * FINAL SUBEXPRESSION OPTIMIZATION
2441 ********************************************************************/
2444 * Optimizes subexpression evaluation.
2446 * \param sel Root of the selection subtree to process.
2448 * Optimizes away some unnecessary evaluation of subexpressions that are only
2452 postprocess_item_subexpressions(t_selelem *sel)
2454 /* Process children. */
2455 if (sel->type != SEL_SUBEXPRREF)
2462 postprocess_item_subexpressions(child);
2463 child = child->next;
2467 /* Replace the evaluation function of statically evaluated subexpressions
2468 * for which the static group was not known in advance. */
2469 if (sel->type == SEL_SUBEXPR && sel->refcount > 2
2470 && (sel->cdata->flags & SEL_CDATA_STATICEVAL)
2471 && !(sel->cdata->flags & SEL_CDATA_FULLEVAL))
2475 /* We need to free memory allocated for the group, because it is no
2476 * longer needed (and would be lost on next call to the evaluation
2477 * function). But we need to preserve the name. */
2478 name = sel->u.cgrp.name;
2479 gmx_ana_index_deinit(&sel->u.cgrp);
2480 sel->u.cgrp.name = name;
2482 sel->evaluate = &_gmx_sel_evaluate_subexpr_staticeval;
2485 sel->cdata->evaluate = sel->evaluate;
2487 _gmx_selelem_free_values(sel->child);
2488 sel->child->mempool = NULL;
2489 _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr);
2490 sel->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
2493 /* Adjust memory allocation flags for subexpressions that are used only
2494 * once. This is not strictly necessary, but we do it to have the memory
2495 * managed consistently for all types of subexpressions. */
2496 if (sel->type == SEL_SUBEXPRREF
2497 && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))
2499 if (sel->child->child->flags & SEL_ALLOCVAL)
2501 sel->flags |= SEL_ALLOCVAL;
2502 sel->flags |= (sel->child->child->flags & SEL_ALLOCDATA);
2503 sel->v.nalloc = sel->child->child->v.nalloc;
2504 sel->child->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
2505 sel->child->child->v.nalloc = -1;
2509 /* Do the same for subexpressions that are evaluated at once for all atoms. */
2510 if (sel->type == SEL_SUBEXPR
2511 && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
2512 && (sel->cdata->flags & SEL_CDATA_FULLEVAL))
2514 sel->flags |= SEL_ALLOCVAL;
2515 sel->flags |= (sel->child->flags & SEL_ALLOCDATA);
2516 sel->v.nalloc = sel->child->v.nalloc;
2517 sel->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA);
2518 sel->child->v.nalloc = -1;
2521 /* For static subexpressions with a dynamic evaluation group, there is
2522 * no need to evaluate them again, as the SEL_SUBEXPRREF takes care of
2523 * everything during evaluation. */
2524 if (sel->type == SEL_SUBEXPR
2525 && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
2526 && (sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR))
2528 sel->evaluate = NULL;
2529 sel->cdata->evaluate = NULL;
2534 /********************************************************************
2535 * COM CALCULATION INITIALIZATION
2536 ********************************************************************/
2539 * Initializes COM/COG calculation for method expressions that require it.
2541 * \param sel Selection subtree to process.
2542 * \param[in,out] pcc Position calculation collection to use.
2543 * \param[in] type Default position calculation type.
2544 * \param[in] flags Flags for default position calculation.
2545 * \returns 0 on success, a non-zero error code on error.
2547 * Searches recursively through the selection tree for dynamic
2548 * \ref SEL_EXPRESSION elements that define the \c gmx_ana_selmethod_t::pupdate
2550 * For each such element found, position calculation is initialized
2551 * for the maximal evaluation group.
2552 * The type of the calculation is determined by \p type and \p flags.
2553 * No calculation is initialized if \p type equals \ref POS_ATOM and
2554 * the method also defines the \c gmx_ana_selmethod_t::update method.
2557 init_item_comg(t_selelem *sel, gmx_ana_poscalc_coll_t *pcc,
2558 e_poscalc_t type, int flags)
2563 /* Initialize COM calculation for dynamic selections now that we know the maximal evaluation group */
2564 if (sel->type == SEL_EXPRESSION && sel->u.expr.method
2565 && sel->u.expr.method->pupdate)
2567 if (!sel->u.expr.method->update || type != POS_ATOM)
2569 /* Create a default calculation if one does not yet exist */
2572 if (!(sel->cdata->flags & SEL_CDATA_STATICEVAL))
2574 cflags |= POS_DYNAMIC;
2576 if (!sel->u.expr.pc)
2579 rc = gmx_ana_poscalc_create(&sel->u.expr.pc, pcc, type, cflags);
2587 gmx_ana_poscalc_set_flags(sel->u.expr.pc, cflags);
2589 gmx_ana_poscalc_set_maxindex(sel->u.expr.pc, sel->cdata->gmax);
2590 snew(sel->u.expr.pos, 1);
2591 gmx_ana_poscalc_init_pos(sel->u.expr.pc, sel->u.expr.pos);
2595 /* Call recursively for all children unless the children have already been processed */
2596 if (sel->type != SEL_SUBEXPRREF)
2601 rc = init_item_comg(child, pcc, type, flags);
2606 child = child->next;
2613 /********************************************************************
2614 * COMPILER DATA FREEING
2615 ********************************************************************/
2618 * Frees the allocated compiler data recursively.
2620 * \param sel Root of the selection subtree to process.
2622 * Frees the data allocated for the compilation process.
2625 free_item_compilerdata(t_selelem *sel)
2629 /* Free compilation data */
2630 _gmx_selelem_free_compiler_data(sel);
2632 /* Call recursively for all children unless the children have already been processed */
2633 if (sel->type != SEL_SUBEXPRREF)
2638 free_item_compilerdata(child);
2639 child = child->next;
2645 /********************************************************************
2646 * MASS AND CHARGE CALCULATION
2647 ********************************************************************/
2650 * Initializes total masses and charges for selections.
2652 * \param[in] top Topology information.
2653 * \param[in] ngrps Number of elements in the \p sel array.
2654 * \param[in,out] sel Array of selections to update.
2655 * \param[in] bMaskOnly TRUE if the positions will always be calculated
2656 * for all atoms, i.e., the masses/charges do not change.
2659 calculate_mass_charge(t_topology *top, int ngrps, gmx_ana_selection_t *sel[],
2664 for (g = 0; g < ngrps; ++g)
2666 sel[g]->g = sel[g]->p.g;
2667 snew(sel[g]->orgm, sel[g]->p.nr);
2668 snew(sel[g]->orgq, sel[g]->p.nr);
2669 for (b = 0; b < sel[g]->p.nr; ++b)
2671 sel[g]->orgq[b] = 0;
2674 sel[g]->orgm[b] = 0;
2675 for (i = sel[g]->p.m.mapb.index[b]; i < sel[g]->p.m.mapb.index[b+1]; ++i)
2677 sel[g]->orgm[b] += top->atoms.atom[sel[g]->g->index[i]].m;
2678 sel[g]->orgq[b] += top->atoms.atom[sel[g]->g->index[i]].q;
2683 sel[g]->orgm[b] = 1;
2686 if (sel[g]->bDynamic && !bMaskOnly)
2688 snew(sel[g]->m, sel[g]->p.nr);
2689 snew(sel[g]->q, sel[g]->p.nr);
2690 for (b = 0; b < sel[g]->p.nr; ++b)
2692 sel[g]->m[b] = sel[g]->orgm[b];
2693 sel[g]->q[b] = sel[g]->orgq[b];
2698 sel[g]->m = sel[g]->orgm;
2699 sel[g]->q = sel[g]->orgq;
2705 /********************************************************************
2706 * MAIN COMPILATION FUNCTION
2707 ********************************************************************/
2710 * \param[in,out] sc Selection collection to debug.
2711 * \param[in] bDebug If TRUE, later call to gmx_ana_selcollection_compile()
2712 * will print out intermediate selection trees.
2715 gmx_ana_selcollection_set_compile_debug(gmx_ana_selcollection_t *sc, gmx_bool bDebug)
2717 sc->bDebugCompile = bDebug;
2721 * \param[in,out] sc Selection collection to be compiled.
2722 * \returns 0 on successful compilation, a non-zero error code on error.
2724 * Before compilation, the selection collection should have been initialized
2725 * with gmx_ana_selcollection_parse_*().
2726 * The compiled selection collection can be passed to
2727 * gmx_ana_selcollection_evaluate() to evaluate the selection for a frame.
2728 * If an error occurs, \p sc is cleared.
2730 * The covered fraction information in \p sc is initialized to
2734 gmx_ana_selcollection_compile(gmx_ana_selcollection_t *sc)
2736 gmx_sel_evaluate_t evaldata;
2742 rc = _gmx_sel_mempool_create(&sc->mempool);
2747 _gmx_sel_evaluate_init(&evaldata, sc->mempool, &sc->gall,
2748 sc->top, NULL, NULL);
2750 /* Clear the symbol table because it is not possible to parse anything
2751 * after compilation, and variable references in the symbol table can
2752 * also mess up the compilation and/or become invalid.
2754 _gmx_selcollection_clear_symtab(sc);
2756 /* Remove any unused variables. */
2757 sc->root = remove_unused_subexpressions(sc->root);
2758 /* Extract subexpressions into separate roots */
2759 sc->root = extract_subexpressions(sc->root);
2761 /* Initialize the evaluation callbacks and process the tree structure
2762 * to conform to the expectations of the callback functions. */
2763 /* Also, initialize and allocate the compiler data structure */
2767 /* Process gmx_boolean and arithmetic expressions. */
2768 optimize_gmx_boolean_expressions(item);
2769 reorder_gmx_boolean_static_children(item);
2770 if (!optimize_arithmetic_expressions(item))
2772 /* FIXME: Clean up the collection */
2775 /* Initialize the compiler data */
2776 init_item_compilerdata(item);
2779 /* Initialize the static evaluation compiler flags.
2780 * Requires the FULLEVAL compiler flag for the whole tree. */
2784 init_item_staticeval(item);
2787 /* Initialize subexpression flags.
2788 * Requires compiler flags for the full tree. */
2792 init_item_subexpr_flags(item);
2795 /* Initialize evaluation.
2796 * Requires subexpression flags. */
2800 if (!init_item_evalfunc(item))
2802 /* FIXME: Clean up the collection */
2805 setup_memory_pooling(item, sc->mempool);
2806 init_item_evaloutput(item);
2809 /* Initialize minimum/maximum index groups.
2810 * Requires evaluation output for the full tree. */
2814 init_item_minmax_groups(item);
2817 /* Initialize the evaluation index groups */
2818 initialize_evalgrps(sc);
2820 if (sc->bDebugCompile)
2822 fprintf(stderr, "\nTree after initial compiler processing:\n");
2823 gmx_ana_selcollection_print_tree(stderr, sc, FALSE);
2826 /* Evaluate all static parts of the selection and analyze the tree
2827 * to allocate enough memory to store the value of each dynamic subtree. */
2831 if (item->child->cdata->flags & SEL_CDATA_COMMONSUBEXPR)
2833 mark_subexpr_dynamic(item->child, TRUE);
2835 set_evaluation_function(item, &analyze_static);
2836 rc = item->evaluate(&evaldata, item, NULL);
2839 /* FIXME: Clean up the collection */
2845 /* At this point, static subexpressions no longer have references to them,
2846 * so they can be removed. */
2847 sc->root = remove_unused_subexpressions(sc->root);
2849 if (sc->bDebugCompile)
2851 fprintf(stderr, "\nTree after first analysis pass:\n");
2852 gmx_ana_selcollection_print_tree(stderr, sc, FALSE);
2855 /* Do a second pass to evaluate static parts of common subexpressions */
2859 if (item->child->cdata->flags & SEL_CDATA_COMMONSUBEXPR)
2861 gmx_bool bMinMax = item->child->cdata->flags & SEL_CDATA_MINMAXALLOC;
2863 mark_subexpr_dynamic(item->child, FALSE);
2864 item->child->u.cgrp.isize = 0;
2865 /* We won't clear item->child->v.u.g here, because it may
2866 * be static, and hence actually point to item->child->cdata->gmax,
2867 * which is used below. We could also check whether this is the
2868 * case and only clear the group otherwise, but because the value
2869 * is actually overwritten immediately in the evaluate call, we
2870 * won't, because similar problems may arise if gmax handling ever
2871 * changes and the check were not updated.
2872 * For the same reason, we clear the min/max flag so that the
2873 * evaluation group doesn't get messed up. */
2874 set_evaluation_function(item, &analyze_static);
2875 item->child->cdata->flags &= ~SEL_CDATA_MINMAXALLOC;
2876 rc = item->evaluate(&evaldata, item->child, item->child->cdata->gmax);
2879 item->child->cdata->flags |= SEL_CDATA_MINMAXALLOC;
2883 /* FIXME: Clean up the collection */
2890 /* We need a yet another pass of subexpression removal to remove static
2891 * subexpressions referred to by common dynamic subexpressions. */
2892 sc->root = remove_unused_subexpressions(sc->root);
2894 if (sc->bDebugCompile)
2896 fprintf(stderr, "\nTree after second analysis pass:\n");
2897 gmx_ana_selcollection_print_tree(stderr, sc, FALSE);
2900 /* Initialize evaluation groups, position calculations for methods, perform
2901 * some final optimization, and free the memory allocated for the
2903 /* By default, use whole residues/molecules. */
2904 flags = POS_COMPLWHOLE;
2905 rc = gmx_ana_poscalc_type_from_enum(sc->rpost, &post, &flags);
2908 gmx_bug("invalid default reference position type");
2909 /* FIXME: Clean up the collection */
2915 init_root_item(item, &sc->gall);
2916 postprocess_item_subexpressions(item);
2917 rc = init_item_comg(item, sc->pcc, post, flags);
2920 /* FIXME: Clean up the collection */
2923 free_item_compilerdata(item);
2927 /* Allocate memory for the evaluation memory pool. */
2928 rc = _gmx_sel_mempool_reserve(sc->mempool, 0);
2934 /* Finish up by calculating total masses and charges. */
2935 calculate_mass_charge(sc->top, sc->nr, sc->sel, sc->bMaskOnly);