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,
309 /** Whether this expressions is a part of a common subexpression. */
310 SEL_CDATA_COMMONSUBEXPR
= 64
314 * Internal data structure used by the compiler.
316 typedef struct t_compiler_data
318 /** The real evaluation method. */
319 sel_evalfunc evaluate
;
320 /** Flags for specifying how to treat this element during compilation. */
322 /** Smallest selection that can be selected by the subexpression. */
323 gmx_ana_index_t
*gmin
;
324 /** Largest selection that can be selected by the subexpression. */
325 gmx_ana_index_t
*gmax
;
329 /********************************************************************
330 * COMPILER UTILITY FUNCTIONS
331 ********************************************************************/
334 print_group_info(FILE *fp
, const char *name
, t_selelem
*sel
, gmx_ana_index_t
*g
)
336 fprintf(fp
, " %s=", name
);
339 fprintf(fp
, "(null)");
341 else if (sel
->cdata
->flags
& SEL_CDATA_MINMAXALLOC
)
343 fprintf(fp
, "(%d atoms, %p)", g
->isize
, (void*)g
);
345 else if (sel
->v
.type
== GROUP_VALUE
&& g
== sel
->v
.u
.g
)
347 fprintf(fp
, "(static, %p)", (void*)g
);
351 fprintf(fp
, "%p", (void*)g
);
356 * \param[in] fp File handle to receive the output.
357 * \param[in] sel Selection element to print.
358 * \param[in] level Indentation level, starting from zero.
361 _gmx_selelem_print_compiler_info(FILE *fp
, t_selelem
*sel
, int level
)
367 fprintf(fp
, "%*c cdata: flg=", level
*2+1, ' ');
368 if (sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
)
372 if (!(sel
->cdata
->flags
& SEL_CDATA_STATIC
))
376 if (sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
)
380 if (sel
->cdata
->flags
& SEL_CDATA_EVALMAX
)
384 if (sel
->cdata
->flags
& SEL_CDATA_MINMAXALLOC
)
388 if (sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
)
392 if (sel
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
)
396 if (!sel
->cdata
->flags
)
400 fprintf(fp
, " eval=");
401 _gmx_sel_print_evalfunc_name(fp
, sel
->cdata
->evaluate
);
402 print_group_info(fp
, "gmin", sel
, sel
->cdata
->gmin
);
403 print_group_info(fp
, "gmax", sel
, sel
->cdata
->gmax
);
408 * \param sel Selection to free.
410 * This function only frees the data for the given selection, not its children.
411 * It is safe to call the function when compiler data has not been allocated
412 * or has already been freed; in such a case, nothing is done.
415 _gmx_selelem_free_compiler_data(t_selelem
*sel
)
419 sel
->evaluate
= sel
->cdata
->evaluate
;
420 if (sel
->cdata
->flags
& SEL_CDATA_MINMAXALLOC
)
422 sel
->cdata
->gmin
->name
= NULL
;
423 sel
->cdata
->gmax
->name
= NULL
;
424 gmx_ana_index_deinit(sel
->cdata
->gmin
);
425 gmx_ana_index_deinit(sel
->cdata
->gmax
);
426 sfree(sel
->cdata
->gmin
);
427 sfree(sel
->cdata
->gmax
);
435 * Allocates memory for storing the evaluated value of a selection element.
437 * \param sel Selection element to initialize
438 * \param[in] isize Maximum evaluation group size.
439 * \param[in] bChildEval TRUE if children have already been processed.
440 * \returns TRUE if the memory was allocated, FALSE if children need to
441 * be processed first.
443 * If called more than once, memory is (re)allocated to ensure that the
444 * maximum of the \p isize values can be stored.
447 alloc_selection_data(t_selelem
*sel
, int isize
, gmx_bool bChildEval
)
455 /* Find out the number of elements to allocate */
456 if (sel
->flags
& SEL_SINGLEVAL
)
460 else if (sel
->flags
& SEL_ATOMVAL
)
464 else /* sel->flags should contain SEL_VARNUMVAL */
472 child
= (sel
->type
== SEL_SUBEXPRREF
? sel
->child
: sel
);
473 if (child
->type
== SEL_SUBEXPR
)
475 child
= child
->child
;
477 nalloc
= (sel
->v
.type
== POS_VALUE
) ? child
->v
.u
.p
->nr
: child
->v
.nr
;
479 /* For positions, we actually want to allocate just a single structure
480 * for nalloc positions. */
481 if (sel
->v
.type
== POS_VALUE
)
486 /* Allocate memory for sel->v.u if needed */
487 if (sel
->flags
& SEL_ALLOCVAL
)
489 _gmx_selvalue_reserve(&sel
->v
, nalloc
);
491 /* Reserve memory inside group and position structures if
492 * SEL_ALLOCDATA is set. */
493 if (sel
->flags
& SEL_ALLOCDATA
)
495 if (sel
->v
.type
== GROUP_VALUE
)
497 gmx_ana_index_reserve(sel
->v
.u
.g
, isize
);
499 else if (sel
->v
.type
== POS_VALUE
)
501 gmx_ana_pos_reserve(sel
->v
.u
.p
, isize
, 0);
508 * Replace the evaluation function of each element in the subtree.
510 * \param sel Root of the selection subtree to process.
511 * \param[in] eval The new evaluation function.
514 set_evaluation_function(t_selelem
*sel
, sel_evalfunc eval
)
516 sel
->evaluate
= eval
;
517 if (sel
->type
!= SEL_SUBEXPRREF
)
519 t_selelem
*child
= sel
->child
;
522 set_evaluation_function(child
, eval
);
529 /********************************************************************
530 * SUBEXPRESSION PROCESSING
531 ********************************************************************/
534 * Reverses the chain of selection elements starting at \p root.
536 * \param root First selection in the whole selection chain.
537 * \returns The new first element for the chain.
540 reverse_selelem_chain(t_selelem
*root
)
559 * Removes subexpressions that don't have any references.
561 * \param root First selection in the whole selection chain.
562 * \returns The new first element for the chain.
564 * The elements are processed in reverse order to correctly detect
565 * subexpressions only referred to by other subexpressions.
568 remove_unused_subexpressions(t_selelem
*root
)
574 root
= reverse_selelem_chain(root
);
575 while (root
->child
->type
== SEL_SUBEXPR
&& root
->child
->refcount
== 1)
578 _gmx_selelem_free(root
);
586 if (item
->child
->type
== SEL_SUBEXPR
&& item
->child
->refcount
== 1)
589 _gmx_selelem_free(item
);
597 return reverse_selelem_chain(root
);
601 * Creates a name with a running number for a subexpression.
603 * \param[in,out] sel The subexpression to be named.
604 * \param[in] i Running number for the subexpression.
606 * The name of the selection becomes "SubExpr N", where N is \p i;
607 * Memory is allocated for the name and the name is stored both in
608 * \c t_selelem::name and \c t_selelem::u::cgrp::name; the latter
609 * is freed by _gmx_selelem_free().
612 create_subexpression_name(t_selelem
*sel
, int i
)
617 len
= 8 + (int)log10(abs(i
)) + 3;
619 /* FIXME: snprintf used to be used here for extra safety, but this
620 * requires extra checking on Windows since it only provides a
621 * non-C99-conforming implementation as _snprintf()... */
622 ret
= sprintf(name
, "SubExpr %d", i
);
623 if (ret
< 0 || ret
> len
)
629 sel
->u
.cgrp
.name
= name
;
633 * Processes and extracts subexpressions from a given selection subtree.
635 * \param sel Root of the subtree to process.
636 * \param subexprn Pointer to a subexpression counter.
637 * \returns Pointer to a chain of subselections, or NULL if none were found.
639 * This function finds recursively all \ref SEL_SUBEXPRREF elements below
640 * the given root element and ensures that their children are within
641 * \ref SEL_SUBEXPR elements. It also creates a chain of \ref SEL_ROOT elements
642 * that contain the subexpression as their children and returns the first
643 * of these root elements.
646 extract_item_subselections(t_selelem
*sel
, int *subexprn
)
652 root
= subexpr
= NULL
;
658 root
= subexpr
= extract_item_subselections(child
, subexprn
);
662 subexpr
->next
= extract_item_subselections(child
, subexprn
);
664 while (subexpr
&& subexpr
->next
)
666 subexpr
= subexpr
->next
;
668 /* The latter check excludes variable references.
669 * It also excludes subexpression elements that have already been
670 * processed, because they are given a name when they are first
672 * TODO: There should be a more robust mechanism (probably a dedicated
673 * flag) for detecting parser-generated subexpressions than relying on
674 * a NULL name field. */
675 if (child
->type
== SEL_SUBEXPRREF
&& (child
->child
->type
!= SEL_SUBEXPR
676 || child
->child
->name
== NULL
))
678 /* Create the root element for the subexpression */
681 root
= subexpr
= _gmx_selelem_create(SEL_ROOT
);
685 subexpr
->next
= _gmx_selelem_create(SEL_ROOT
);
686 subexpr
= subexpr
->next
;
688 /* Create the subexpression element and/or
689 * move the actual subexpression under the created element. */
690 if (child
->child
->type
!= SEL_SUBEXPR
)
692 subexpr
->child
= _gmx_selelem_create(SEL_SUBEXPR
);
693 _gmx_selelem_set_vtype(subexpr
->child
, child
->v
.type
);
694 subexpr
->child
->child
= child
->child
;
695 child
->child
= subexpr
->child
;
699 subexpr
->child
= child
->child
;
701 create_subexpression_name(subexpr
->child
, ++*subexprn
);
702 subexpr
->child
->refcount
++;
703 /* Set the flags for the created elements */
704 subexpr
->flags
|= (child
->flags
& SEL_VALFLAGMASK
);
705 subexpr
->child
->flags
|= (child
->flags
& SEL_VALFLAGMASK
);
714 * Extracts subexpressions of the selection chain.
716 * \param sel First selection in the whole selection chain.
717 * \returns The new first element for the chain.
719 * Finds all the subexpressions (and their subexpressions) in the
720 * selection chain starting from \p sel and creates \ref SEL_SUBEXPR
722 * \ref SEL_ROOT elements are also created for each subexpression
723 * and inserted into the selection chain before the expressions that
727 extract_subexpressions(t_selelem
*sel
)
729 t_selelem
*root
, *item
, *next
;
737 item
= extract_item_subselections(next
, &subexprn
);
765 /********************************************************************
766 * BOOLEAN OPERATION REORDERING
767 ********************************************************************/
770 * Removes redundant gmx_boolean selection elements.
772 * \param sel Root of the selection subtree to optimize.
774 * This function merges similar gmx_boolean operations (e.g., (A or B) or C becomes
775 * a single OR operation with three operands).
778 optimize_gmx_boolean_expressions(t_selelem
*sel
)
780 t_selelem
*child
, *prev
;
782 /* Do recursively for children */
783 if (sel
->type
!= SEL_SUBEXPRREF
)
789 optimize_gmx_boolean_expressions(child
);
790 /* Remove double negations */
791 if (child
->type
== SEL_BOOLEAN
&& child
->u
.boolt
== BOOL_NOT
792 && child
->child
->type
== SEL_BOOLEAN
&& child
->child
->u
.boolt
== BOOL_NOT
)
794 /* Move the doubly negated expression up two levels */
797 sel
->child
= child
->child
->child
;
802 prev
->next
= child
->child
->child
;
805 child
->child
->child
->next
= child
->next
;
806 /* Remove the two negations */
807 child
->child
->child
= NULL
;
809 _gmx_selelem_free(child
);
816 if (sel
->type
!= SEL_BOOLEAN
|| sel
->u
.boolt
== BOOL_NOT
)
820 /* Merge subsequent binary operations */
825 if (child
->type
== SEL_BOOLEAN
&& child
->u
.boolt
== sel
->u
.boolt
)
829 sel
->child
= child
->child
;
834 prev
->next
= child
->child
;
840 prev
->next
= child
->next
;
854 * Reorders children of gmx_boolean expressions such that static selections
857 * \param sel Root of the selection subtree to reorder.
859 * The relative order of static expressions does not change.
860 * The same is true for the dynamic expressions.
863 reorder_gmx_boolean_static_children(t_selelem
*sel
)
865 t_selelem
*child
, *prev
, *next
;
867 /* Do recursively for children */
868 if (sel
->type
!= SEL_SUBEXPRREF
)
873 reorder_gmx_boolean_static_children(child
);
878 /* Reorder gmx_boolean expressions such that static selections come first */
879 if (sel
->type
== SEL_BOOLEAN
&& (sel
->flags
& SEL_DYNAMIC
))
883 start
.next
= sel
->child
;
888 /* child is the last handled static expression */
889 /* prev is the last handled non-static expression */
891 while (next
&& (next
->flags
& SEL_DYNAMIC
))
896 /* next is now the first static expression after child */
901 /* Reorder such that next comes after child */
904 prev
->next
= next
->next
;
905 next
->next
= child
->next
;
912 /* Advance child by one */
916 sel
->child
= start
.next
;
921 /********************************************************************
922 * ARITHMETIC EXPRESSION PROCESSING
923 ********************************************************************/
926 * Processes arithmetic expressions to simplify and speed up evaluation.
928 * \param sel Root of the selection subtree to process.
930 * Currently, this function only converts integer constants to reals
931 * within arithmetic expressions.
934 optimize_arithmetic_expressions(t_selelem
*sel
)
939 /* Do recursively for children. */
940 if (sel
->type
!= SEL_SUBEXPRREF
)
945 bOk
= optimize_arithmetic_expressions(child
);
954 if (sel
->type
!= SEL_ARITHMETIC
)
959 /* Convert integer constants to reals. */
963 if (child
->v
.type
== INT_VALUE
)
967 if (child
->type
!= SEL_CONST
)
969 gmx_impl("Non-constant integer expressions not implemented in arithmetic evaluation");
973 r
[0] = child
->v
.u
.i
[0];
976 child
->v
.type
= REAL_VALUE
;
978 else if (child
->v
.type
!= REAL_VALUE
)
980 gmx_bug("Internal error");
989 /********************************************************************
990 * EVALUATION PREPARATION COMPILER
991 ********************************************************************/
994 * Sets the evaluation functions for the selection (sub)tree.
996 * \param[in,out] sel Root of the selection subtree to process.
997 * \returns TRUE on success, FALSE if any subexpression fails.
999 * This function sets the evaluation function (\c t_selelem::evaluate)
1000 * for the selection elements.
1003 init_item_evalfunc(t_selelem
*sel
)
1005 /* Process children. */
1006 if (sel
->type
!= SEL_SUBEXPRREF
)
1013 if (!init_item_evalfunc(child
))
1017 child
= child
->next
;
1021 /* Set the evaluation function */
1025 if (sel
->v
.type
== GROUP_VALUE
)
1027 sel
->evaluate
= &_gmx_sel_evaluate_static
;
1031 case SEL_EXPRESSION
:
1032 if (!(sel
->flags
& SEL_DYNAMIC
) && sel
->u
.expr
.method
1033 && sel
->u
.expr
.method
->init_frame
)
1035 sel
->flags
|= SEL_INITFRAME
;
1037 sel
->evaluate
= &_gmx_sel_evaluate_method
;
1040 case SEL_ARITHMETIC
:
1041 sel
->evaluate
= &_gmx_sel_evaluate_arithmetic
;
1045 if (sel
->v
.type
!= NO_VALUE
)
1047 sel
->evaluate
= &_gmx_sel_evaluate_modifier
;
1052 switch (sel
->u
.boolt
)
1054 case BOOL_NOT
: sel
->evaluate
= &_gmx_sel_evaluate_not
; break;
1055 case BOOL_AND
: sel
->evaluate
= &_gmx_sel_evaluate_and
; break;
1056 case BOOL_OR
: sel
->evaluate
= &_gmx_sel_evaluate_or
; break;
1058 gmx_impl("xor expressions not implemented");
1064 sel
->evaluate
= &_gmx_sel_evaluate_root
;
1068 sel
->evaluate
= (sel
->refcount
== 2
1069 ? &_gmx_sel_evaluate_subexpr_simple
1070 : &_gmx_sel_evaluate_subexpr
);
1073 case SEL_SUBEXPRREF
:
1074 sel
->name
= sel
->child
->name
;
1075 sel
->evaluate
= (sel
->child
->refcount
== 2
1076 ? &_gmx_sel_evaluate_subexprref_simple
1077 : &_gmx_sel_evaluate_subexprref
);
1085 * Sets the memory pool for selection elements that can use it.
1087 * \param sel Root of the selection subtree to process.
1088 * \param[in] mempool Memory pool to use.
1091 setup_memory_pooling(t_selelem
*sel
, gmx_sel_mempool_t
*mempool
)
1093 if (sel
->type
!= SEL_SUBEXPRREF
)
1100 if ((sel
->type
== SEL_BOOLEAN
&& (child
->flags
& SEL_DYNAMIC
))
1101 || (sel
->type
== SEL_ARITHMETIC
&& child
->type
!= SEL_CONST
1102 && !(child
->flags
& SEL_SINGLEVAL
))
1103 || (sel
->type
== SEL_SUBEXPR
&& sel
->refcount
> 2))
1105 child
->mempool
= mempool
;
1106 if (child
->type
== SEL_SUBEXPRREF
1107 && child
->child
->refcount
== 2)
1109 child
->child
->child
->mempool
= mempool
;
1112 setup_memory_pooling(child
, mempool
);
1113 child
= child
->next
;
1119 * Prepares the selection (sub)tree for evaluation.
1121 * \param[in,out] sel Root of the selection subtree to prepare.
1123 * It also allocates memory for the \p sel->v.u.g or \p sel->v.u.p
1124 * structure if required.
1127 init_item_evaloutput(t_selelem
*sel
)
1129 /* Process children. */
1130 if (sel
->type
!= SEL_SUBEXPRREF
)
1137 init_item_evaloutput(child
);
1138 child
= child
->next
;
1142 if (sel
->type
== SEL_SUBEXPR
&& sel
->refcount
== 2)
1144 sel
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
1145 if (sel
->v
.type
== GROUP_VALUE
|| sel
->v
.type
== POS_VALUE
)
1147 _gmx_selvalue_setstore(&sel
->v
, sel
->child
->v
.u
.ptr
);
1150 else if (sel
->type
== SEL_SUBEXPR
1151 && (sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
1153 sel
->evaluate
= &_gmx_sel_evaluate_subexpr_staticeval
;
1154 sel
->cdata
->evaluate
= sel
->evaluate
;
1155 sel
->child
->mempool
= NULL
;
1156 sel
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
1157 if (sel
->v
.type
== GROUP_VALUE
|| sel
->v
.type
== POS_VALUE
)
1159 _gmx_selvalue_setstore(&sel
->v
, sel
->child
->v
.u
.ptr
);
1162 else if (sel
->type
== SEL_SUBEXPRREF
&& sel
->child
->refcount
== 2)
1166 _gmx_selvalue_setstore(&sel
->child
->v
, sel
->v
.u
.ptr
);
1167 _gmx_selelem_free_values(sel
->child
->child
);
1168 sel
->child
->child
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
1169 sel
->child
->child
->flags
|= (sel
->flags
& SEL_ALLOCDATA
);
1170 _gmx_selvalue_setstore(&sel
->child
->child
->v
, sel
->v
.u
.ptr
);
1172 else if (sel
->v
.type
== GROUP_VALUE
|| sel
->v
.type
== POS_VALUE
)
1174 _gmx_selvalue_setstore(&sel
->v
, sel
->child
->child
->v
.u
.ptr
);
1176 sel
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
1179 /* Make sure that the group/position structure is allocated. */
1180 if (!sel
->v
.u
.ptr
&& (sel
->flags
& SEL_ALLOCVAL
))
1182 if (sel
->v
.type
== GROUP_VALUE
|| sel
->v
.type
== POS_VALUE
)
1184 _gmx_selvalue_reserve(&sel
->v
, 1);
1191 /********************************************************************
1192 * COMPILER DATA INITIALIZATION
1193 ********************************************************************/
1196 * Allocates memory for the compiler data and initializes the structure.
1198 * \param sel Root of the selection subtree to process.
1201 init_item_compilerdata(t_selelem
*sel
)
1205 /* Allocate the compiler data structure */
1206 snew(sel
->cdata
, 1);
1208 /* Store the real evaluation method because the compiler will replace it */
1209 sel
->cdata
->evaluate
= sel
->evaluate
;
1211 /* Initialize the flags */
1212 sel
->cdata
->flags
= SEL_CDATA_STATICEVAL
;
1213 if (!(sel
->flags
& SEL_DYNAMIC
))
1215 sel
->cdata
->flags
|= SEL_CDATA_STATIC
;
1217 if (sel
->type
== SEL_SUBEXPR
)
1219 sel
->cdata
->flags
|= SEL_CDATA_EVALMAX
;
1221 /* Set the full evaluation flag for subexpressions that require it;
1222 * the subexpression has already been initialized, so we can simply
1223 * access its compilation flags.*/
1224 if (sel
->type
== SEL_EXPRESSION
|| sel
->type
== SEL_MODIFIER
)
1229 if (!(child
->flags
& SEL_ATOMVAL
) && child
->child
)
1231 child
->child
->cdata
->flags
|= SEL_CDATA_FULLEVAL
;
1233 child
= child
->next
;
1236 else if (sel
->type
== SEL_ROOT
&& sel
->child
->type
== SEL_SUBEXPRREF
)
1238 sel
->child
->child
->cdata
->flags
|= SEL_CDATA_FULLEVAL
;
1241 /* Initialize children */
1242 if (sel
->type
!= SEL_SUBEXPRREF
)
1247 init_item_compilerdata(child
);
1248 child
= child
->next
;
1252 /* Determine whether we should evaluate the minimum or the maximum
1253 * for the children of this element. */
1254 if (sel
->type
== SEL_BOOLEAN
)
1258 bEvalMax
= (sel
->u
.boolt
== BOOL_AND
);
1264 child
->cdata
->flags
|= SEL_CDATA_EVALMAX
;
1266 else if (child
->type
== SEL_BOOLEAN
&& child
->u
.boolt
== BOOL_NOT
)
1268 child
->child
->cdata
->flags
|= SEL_CDATA_EVALMAX
;
1270 child
= child
->next
;
1273 else if (sel
->type
== SEL_EXPRESSION
|| sel
->type
== SEL_MODIFIER
1274 || sel
->type
== SEL_SUBEXPR
)
1279 child
->cdata
->flags
|= SEL_CDATA_EVALMAX
;
1280 child
= child
->next
;
1286 * Initializes the static evaluation flag for a selection subtree.
1288 * \param[in,out] sel Root of the selection subtree to process.
1290 * Sets the \c bStaticEval in the compiler data structure:
1291 * for any element for which the evaluation group may depend on the trajectory
1292 * frame, the flag is cleared.
1294 * reorder_gmx_boolean_static_children() should have been called.
1297 init_item_staticeval(t_selelem
*sel
)
1301 /* Subexpressions with full evaluation should always have bStaticEval,
1302 * so don't do anything if a reference to them is encountered. */
1303 if (sel
->type
== SEL_SUBEXPRREF
1304 && (sel
->child
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
1309 /* Propagate the bStaticEval flag to children if it is not set */
1310 if (!(sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
))
1315 if ((sel
->type
!= SEL_EXPRESSION
&& sel
->type
!= SEL_MODIFIER
)
1316 || (child
->flags
& SEL_ATOMVAL
))
1318 if (child
->cdata
->flags
& SEL_CDATA_STATICEVAL
)
1320 child
->cdata
->flags
&= ~SEL_CDATA_STATICEVAL
;
1321 init_item_staticeval(child
);
1324 child
= child
->next
;
1327 else /* bStaticEval is set */
1329 /* For gmx_boolean expressions, any expression after the first dynamic
1330 * expression should not have bStaticEval. */
1331 if (sel
->type
== SEL_BOOLEAN
)
1334 while (child
&& !(child
->flags
& SEL_DYNAMIC
))
1336 child
= child
->next
;
1340 child
= child
->next
;
1344 child
->cdata
->flags
&= ~SEL_CDATA_STATICEVAL
;
1345 child
= child
->next
;
1349 /* Process the children */
1353 init_item_staticeval(child
);
1354 child
= child
->next
;
1360 * Initializes compiler flags for subexpressions.
1362 * \param sel Root of the selection subtree to process.
1365 init_item_subexpr_flags(t_selelem
*sel
)
1367 if (sel
->type
== SEL_SUBEXPR
)
1369 if (sel
->refcount
== 2)
1371 sel
->cdata
->flags
|= SEL_CDATA_SIMPLESUBEXPR
;
1373 else if (!(sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
1375 sel
->cdata
->flags
|= SEL_CDATA_COMMONSUBEXPR
;
1378 else if (sel
->type
== SEL_SUBEXPRREF
&& sel
->child
->refcount
== 2)
1380 sel
->cdata
->flags
|= SEL_CDATA_SIMPLESUBEXPR
;
1383 /* Process children, but only follow subexpression references if the
1384 * common subexpression flag needs to be propagated. */
1385 if (sel
->type
!= SEL_SUBEXPRREF
1386 || ((sel
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
)
1387 && sel
->child
->refcount
> 2))
1389 t_selelem
*child
= sel
->child
;
1393 if (!(child
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
))
1395 if (sel
->type
!= SEL_EXPRESSION
|| (child
->flags
& SEL_ATOMVAL
))
1397 child
->cdata
->flags
|=
1398 (sel
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
);
1400 init_item_subexpr_flags(child
);
1402 child
= child
->next
;
1408 * Initializes the gmin and gmax fields of the compiler data structure.
1410 * \param sel Root of the selection subtree to process.
1413 init_item_minmax_groups(t_selelem
*sel
)
1415 /* Process children. */
1416 if (sel
->type
!= SEL_SUBEXPRREF
)
1423 init_item_minmax_groups(child
);
1424 child
= child
->next
;
1428 /* Initialize the minimum and maximum evaluation groups. */
1429 if (sel
->type
!= SEL_ROOT
&& sel
->v
.type
!= NO_VALUE
)
1431 if (sel
->v
.type
== GROUP_VALUE
1432 && (sel
->cdata
->flags
& SEL_CDATA_STATIC
))
1434 sel
->cdata
->gmin
= sel
->v
.u
.g
;
1435 sel
->cdata
->gmax
= sel
->v
.u
.g
;
1437 else if (sel
->type
== SEL_SUBEXPR
1438 && ((sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
)
1439 || (sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
)))
1441 sel
->cdata
->gmin
= sel
->child
->cdata
->gmin
;
1442 sel
->cdata
->gmax
= sel
->child
->cdata
->gmax
;
1446 sel
->cdata
->flags
|= SEL_CDATA_MINMAXALLOC
;
1447 snew(sel
->cdata
->gmin
, 1);
1448 snew(sel
->cdata
->gmax
, 1);
1454 /********************************************************************
1455 * EVALUATION GROUP INITIALIZATION
1456 ********************************************************************/
1459 * Initializes evaluation groups for root items.
1461 * \param[in,out] sc Selection collection data.
1463 * The evaluation group of each \ref SEL_ROOT element corresponding to a
1464 * selection in \p sc is set to \p gall. The same is done for \ref SEL_ROOT
1465 * elements corresponding to subexpressions that need full evaluation.
1468 initialize_evalgrps(gmx_ana_selcollection_t
*sc
)
1475 if (root
->child
->type
!= SEL_SUBEXPR
1476 || (root
->child
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
1478 gmx_ana_index_set(&root
->u
.cgrp
, sc
->gall
.isize
, sc
->gall
.index
,
1479 root
->u
.cgrp
.name
, 0);
1486 /********************************************************************
1488 ********************************************************************/
1491 * Marks a subtree completely dynamic or undoes such a change.
1493 * \param sel Selection subtree to mark.
1494 * \param[in] bDynamic If TRUE, the \p bStatic flag of the whole
1495 * selection subtree is cleared. If FALSE, the flag is restored to
1496 * using \ref SEL_DYNAMIC.
1498 * Does not descend into parameters of methods unless the parameters
1499 * are evaluated for each atom.
1502 mark_subexpr_dynamic(t_selelem
*sel
, gmx_bool bDynamic
)
1506 if (!bDynamic
&& !(sel
->flags
& SEL_DYNAMIC
))
1508 sel
->cdata
->flags
|= SEL_CDATA_STATIC
;
1512 sel
->cdata
->flags
&= ~SEL_CDATA_STATIC
;
1517 if (sel
->type
!= SEL_EXPRESSION
|| child
->type
!= SEL_SUBEXPRREF
1518 || (child
->u
.param
->flags
& SPAR_ATOMVAL
))
1520 mark_subexpr_dynamic(child
, bDynamic
);
1522 child
= child
->next
;
1527 * Frees memory for subexpressions that are no longer needed.
1529 * \param sel Selection subtree to check.
1531 * Checks whether the subtree rooted at \p sel refers to any \ref SEL_SUBEXPR
1532 * elements that are not referred to by anything else except their own root
1533 * element. If such elements are found, all memory allocated for them is freed
1534 * except the actual element. The element is left because otherwise a dangling
1535 * pointer would be left at the root element, which is not traversed by this
1536 * function. Later compilation passes remove the stub elements.
1539 release_subexpr_memory(t_selelem
*sel
)
1541 if (sel
->type
== SEL_SUBEXPR
)
1543 if (sel
->refcount
== 2)
1545 release_subexpr_memory(sel
->child
);
1547 _gmx_selelem_free_chain(sel
->child
);
1548 _gmx_selelem_free_values(sel
);
1549 _gmx_selelem_free_exprdata(sel
);
1550 _gmx_selelem_free_compiler_data(sel
);
1561 release_subexpr_memory(child
);
1562 child
= child
->next
;
1568 * Makes an evaluated selection element static.
1570 * \param sel Selection element to make static.
1572 * The evaluated value becomes the value of the static element.
1573 * The element type is changed to SEL_CONST and the children are
1577 make_static(t_selelem
*sel
)
1579 /* If this is a subexpression reference and the data is stored in the
1580 * child, we transfer data ownership before doing anything else. */
1581 if (sel
->type
== SEL_SUBEXPRREF
1582 && (sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
))
1584 if (sel
->child
->child
->flags
& SEL_ALLOCDATA
)
1586 sel
->flags
|= SEL_ALLOCDATA
;
1587 sel
->child
->child
->flags
&= ~SEL_ALLOCDATA
;
1589 if (sel
->child
->child
->flags
& SEL_ALLOCVAL
)
1591 sel
->flags
|= SEL_ALLOCVAL
;
1592 sel
->v
.nalloc
= sel
->child
->child
->v
.nalloc
;
1593 sel
->child
->child
->flags
&= ~SEL_ALLOCVAL
;
1594 sel
->child
->child
->v
.nalloc
= -1;
1597 /* When we reach here for parameter elements, the value is already
1598 * stored in the parent element, so make sure that it is not freed
1599 * through this element. */
1600 if (sel
->type
== SEL_SUBEXPRREF
&& sel
->u
.param
)
1602 sel
->u
.param
->val
.nalloc
= sel
->v
.nalloc
;
1603 sel
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
1606 /* Free the children. */
1607 release_subexpr_memory(sel
);
1608 _gmx_selelem_free_chain(sel
->child
);
1610 /* Free the expression data as it is no longer needed */
1611 _gmx_selelem_free_exprdata(sel
);
1612 /* Make the item static */
1614 sel
->type
= SEL_CONST
;
1615 sel
->evaluate
= NULL
;
1616 sel
->cdata
->evaluate
= NULL
;
1617 /* Set the group value.
1618 * free_exprdata above frees the cgrp group, so we can just override it. */
1619 if (sel
->v
.type
== GROUP_VALUE
)
1621 gmx_ana_index_set(&sel
->u
.cgrp
, sel
->v
.u
.g
->isize
, sel
->v
.u
.g
->index
, NULL
, 0);
1626 * Evaluates a constant expression during analyze_static().
1628 * \param[in] data Evaluation data.
1629 * \param[in,out] sel Selection to process.
1630 * \param[in] g The evaluation group.
1631 * \returns 0 on success, a non-zero error code on error.
1634 process_const(gmx_sel_evaluate_t
*data
, t_selelem
*sel
, gmx_ana_index_t
*g
)
1639 if (sel
->v
.type
== GROUP_VALUE
)
1641 if (sel
->cdata
->evaluate
)
1643 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
1646 /* Other constant expressions do not need evaluation */
1651 * Sets the parameter value pointer for \ref SEL_SUBEXPRREF params.
1653 * \param[in,out] sel Selection to process.
1655 * Copies the value pointer of \p sel to \c sel->u.param if one is present
1656 * and should receive the value from the compiler
1657 * (most parameter values are handled during parsing).
1658 * If \p sel is not of type \ref SEL_SUBEXPRREF, or if \c sel->u.param is NULL,
1659 * the function does nothing.
1660 * Also, if the \c sel->u.param does not have \ref SPAR_VARNUM or
1661 * \ref SPAR_ATOMVAL, the function returns immediately.
1664 store_param_val(t_selelem
*sel
)
1666 /* Return immediately if there is no parameter. */
1667 if (sel
->type
!= SEL_SUBEXPRREF
|| !sel
->u
.param
)
1672 /* Or if the value does not need storing. */
1673 if (!(sel
->u
.param
->flags
& (SPAR_VARNUM
| SPAR_ATOMVAL
)))
1678 if (sel
->v
.type
== INT_VALUE
|| sel
->v
.type
== REAL_VALUE
1679 || sel
->v
.type
== STR_VALUE
)
1681 _gmx_selvalue_setstore(&sel
->u
.param
->val
, sel
->v
.u
.ptr
);
1686 * Handles the initialization of a selection method during analyze_static() pass.
1688 * \param[in,out] sel Selection element to process.
1689 * \param[in] top Topology structure.
1690 * \param[in] isize Size of the evaluation group for the element.
1691 * \returns 0 on success, a non-zero error code on return.
1693 * Calls sel_initfunc() (and possibly sel_outinitfunc()) to initialize the
1695 * If no \ref SPAR_ATOMVAL parameters are present, multiple initialization
1696 * is prevented by using \ref SEL_METHODINIT and \ref SEL_OUTINIT flags.
1699 init_method(t_selelem
*sel
, t_topology
*top
, int isize
)
1705 /* Find out whether there are any atom-valued parameters */
1710 if (child
->flags
& SEL_ATOMVAL
)
1714 child
= child
->next
;
1717 /* Initialize the method */
1718 if (sel
->u
.expr
.method
->init
1719 && (bAtomVal
|| !(sel
->flags
& SEL_METHODINIT
)))
1721 sel
->flags
|= SEL_METHODINIT
;
1722 rc
= sel
->u
.expr
.method
->init(top
, sel
->u
.expr
.method
->nparams
,
1723 sel
->u
.expr
.method
->param
, sel
->u
.expr
.mdata
);
1729 if (bAtomVal
|| !(sel
->flags
& SEL_OUTINIT
))
1731 sel
->flags
|= SEL_OUTINIT
;
1732 if (sel
->u
.expr
.method
->outinit
)
1734 rc
= sel
->u
.expr
.method
->outinit(top
, &sel
->v
, sel
->u
.expr
.mdata
);
1739 if (sel
->v
.type
!= POS_VALUE
&& sel
->v
.type
!= GROUP_VALUE
)
1741 alloc_selection_data(sel
, isize
, TRUE
);
1746 alloc_selection_data(sel
, isize
, TRUE
);
1747 if ((sel
->flags
& SEL_DYNAMIC
)
1748 && sel
->v
.type
!= GROUP_VALUE
&& sel
->v
.type
!= POS_VALUE
)
1752 /* If the method is char-valued, pre-allocate the strings. */
1753 if (sel
->u
.expr
.method
->flags
& SMETH_CHARVAL
)
1757 /* A sanity check */
1758 if (sel
->v
.type
!= STR_VALUE
)
1760 gmx_bug("internal error");
1763 sel
->flags
|= SEL_ALLOCDATA
;
1764 for (i
= 0; i
< isize
; ++i
)
1766 if (sel
->v
.u
.s
[i
] == NULL
)
1768 snew(sel
->v
.u
.s
[i
], 2);
1773 /* Clear the values for dynamic output to avoid valgrind warnings. */
1774 if ((sel
->flags
& SEL_DYNAMIC
) && sel
->v
.type
== REAL_VALUE
)
1778 for (i
= 0; i
< sel
->v
.nr
; ++i
)
1780 sel
->v
.u
.r
[i
] = 0.0;
1789 * Evaluates the static part of a gmx_boolean expression.
1791 * \param[in] data Evaluation data.
1792 * \param[in,out] sel Boolean selection element whose children should be
1794 * \param[in] g The evaluation group.
1795 * \returns 0 on success, a non-zero error code on error.
1797 * reorder_item_static_children() should have been called.
1800 evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t
*data
, t_selelem
*sel
,
1803 t_selelem
*child
, *next
;
1806 /* Find the last static subexpression */
1808 while (child
->next
&& (child
->next
->cdata
->flags
& SEL_CDATA_STATIC
))
1810 child
= child
->next
;
1812 if (!(child
->cdata
->flags
& SEL_CDATA_STATIC
))
1817 /* Evalute the static part if there is more than one expression */
1818 if (child
!= sel
->child
)
1822 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
1827 /* Replace the subexpressions with the result */
1828 _gmx_selelem_free_chain(sel
->child
);
1830 child
->type
= SEL_CONST
;
1831 child
->flags
= SEL_FLAGSSET
| SEL_SINGLEVAL
| SEL_ALLOCVAL
| SEL_ALLOCDATA
;
1832 _gmx_selelem_set_vtype(child
, GROUP_VALUE
);
1833 child
->evaluate
= NULL
;
1834 _gmx_selvalue_reserve(&child
->v
, 1);
1835 gmx_ana_index_copy(child
->v
.u
.g
, sel
->v
.u
.g
, TRUE
);
1836 init_item_compilerdata(child
);
1837 init_item_minmax_groups(child
);
1838 child
->cdata
->flags
&= ~SEL_CDATA_STATICEVAL
;
1839 child
->cdata
->flags
|= sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
;
1843 else if (child
->evaluate
)
1845 rc
= child
->evaluate(data
, child
, g
);
1851 /* Set the evaluation function for the constant element.
1852 * We never need to evaluate the element again during compilation,
1853 * but we may need to evaluate the static part again if the
1854 * expression is not an OR with a static evaluation group.
1855 * If we reach here with a NOT expression, the NOT expression
1856 * is also static, and will be made a constant later, so don't waste
1857 * time copying the group. */
1858 child
->evaluate
= NULL
;
1859 if (sel
->u
.boolt
== BOOL_NOT
1860 || ((sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
)
1861 && sel
->u
.boolt
== BOOL_OR
))
1863 child
->cdata
->evaluate
= NULL
;
1867 child
->cdata
->evaluate
= &_gmx_sel_evaluate_static
;
1868 /* The cgrp has only been allocated if it originated from an
1869 * external index group. In that case, we need special handling
1870 * to preserve the name of the group and to not leak memory.
1871 * If cgrp has been set in make_static(), it is not allocated,
1872 * and hence we can overwrite it safely. */
1873 if (child
->u
.cgrp
.nalloc_index
> 0)
1875 char *name
= child
->u
.cgrp
.name
;
1876 gmx_ana_index_copy(&child
->u
.cgrp
, child
->v
.u
.g
, FALSE
);
1877 gmx_ana_index_squeeze(&child
->u
.cgrp
);
1878 child
->u
.cgrp
.name
= name
;
1882 gmx_ana_index_copy(&child
->u
.cgrp
, child
->v
.u
.g
, TRUE
);
1889 * Evaluates the minimum and maximum groups for a gmx_boolean expression.
1891 * \param[in] sel \ref SEL_BOOLEAN element currently being evaluated.
1892 * \param[in] g Group for which \p sel has been evaluated.
1893 * \param[out] gmin Largest subset of the possible values of \p sel.
1894 * \param[out] gmax Smallest superset of the possible values of \p sel.
1896 * This is a helper function for analyze_static() that is called for
1897 * dynamic \ref SEL_BOOLEAN elements after they have been evaluated.
1898 * It uses the minimum and maximum groups of the children to calculate
1899 * the minimum and maximum groups for \p sel, and also updates the static
1900 * part of \p sel (which is in the first child) if the children give
1903 * This function may allocate some extra memory for \p gmin and \p gmax,
1904 * but as these groups are freed at the end of analyze_static() (which is
1905 * reached shortly after this function returns), this should not be a major
1909 evaluate_gmx_boolean_minmax_grps(t_selelem
*sel
, gmx_ana_index_t
*g
,
1910 gmx_ana_index_t
*gmin
, gmx_ana_index_t
*gmax
)
1914 switch (sel
->u
.boolt
)
1917 gmx_ana_index_reserve(gmin
, g
->isize
);
1918 gmx_ana_index_reserve(gmax
, g
->isize
);
1919 gmx_ana_index_difference(gmax
, g
, sel
->child
->cdata
->gmin
);
1920 gmx_ana_index_difference(gmin
, g
, sel
->child
->cdata
->gmax
);
1924 gmx_ana_index_copy(gmin
, sel
->child
->cdata
->gmin
, TRUE
);
1925 gmx_ana_index_copy(gmax
, sel
->child
->cdata
->gmax
, TRUE
);
1926 child
= sel
->child
->next
;
1927 while (child
&& gmax
->isize
> 0)
1929 gmx_ana_index_intersection(gmin
, gmin
, child
->cdata
->gmin
);
1930 gmx_ana_index_intersection(gmax
, gmax
, child
->cdata
->gmax
);
1931 child
= child
->next
;
1933 /* Update the static part if other expressions limit it */
1934 if ((sel
->child
->cdata
->flags
& SEL_CDATA_STATIC
)
1935 && sel
->child
->v
.u
.g
->isize
> gmax
->isize
)
1937 gmx_ana_index_copy(sel
->child
->v
.u
.g
, gmax
, FALSE
);
1938 gmx_ana_index_squeeze(sel
->child
->v
.u
.g
);
1939 if (sel
->child
->u
.cgrp
.isize
> 0)
1941 gmx_ana_index_copy(&sel
->child
->u
.cgrp
, gmax
, FALSE
);
1942 gmx_ana_index_squeeze(&sel
->child
->u
.cgrp
);
1948 /* We can assume here that the gmin of children do not overlap
1949 * because of the way _gmx_sel_evaluate_or() works. */
1950 gmx_ana_index_reserve(gmin
, g
->isize
);
1951 gmx_ana_index_reserve(gmax
, g
->isize
);
1952 gmx_ana_index_copy(gmin
, sel
->child
->cdata
->gmin
, FALSE
);
1953 gmx_ana_index_copy(gmax
, sel
->child
->cdata
->gmax
, FALSE
);
1954 child
= sel
->child
->next
;
1955 while (child
&& gmin
->isize
< g
->isize
)
1957 gmx_ana_index_merge(gmin
, gmin
, child
->cdata
->gmin
);
1958 gmx_ana_index_union(gmax
, gmax
, child
->cdata
->gmax
);
1959 child
= child
->next
;
1961 /* Update the static part if other expressions have static parts
1962 * that are not included. */
1963 if ((sel
->child
->cdata
->flags
& SEL_CDATA_STATIC
)
1964 && sel
->child
->v
.u
.g
->isize
< gmin
->isize
)
1966 gmx_ana_index_reserve(sel
->child
->v
.u
.g
, gmin
->isize
);
1967 gmx_ana_index_copy(sel
->child
->v
.u
.g
, gmin
, FALSE
);
1968 if (sel
->child
->u
.cgrp
.isize
> 0)
1970 gmx_ana_index_reserve(&sel
->child
->u
.cgrp
, gmin
->isize
);
1971 gmx_ana_index_copy(&sel
->child
->u
.cgrp
, gmin
, FALSE
);
1976 case BOOL_XOR
: /* Should not be reached */
1977 gmx_impl("xor expressions not implemented");
1983 * Evaluates the static parts of \p sel and analyzes the structure.
1985 * \param[in] data Evaluation data.
1986 * \param[in,out] sel Selection currently being evaluated.
1987 * \param[in] g Group for which \p sel should be evaluated.
1988 * \returns 0 on success, a non-zero error code on error.
1990 * This function is used as the replacement for the \c t_selelem::evaluate
1992 * It does the single most complex task in the compiler: after all elements
1993 * have been processed, the \p gmin and \p gmax fields of \p t_compiler_data
1994 * have been properly initialized, enough memory has been allocated for
1995 * storing the value of each expression, and the static parts of the
1996 * expressions have been evaluated.
1997 * The above is exactly true only for elements other than subexpressions:
1998 * another pass is required for subexpressions that are referred to more than
1999 * once and whose evaluation group is not known in advance.
2002 analyze_static(gmx_sel_evaluate_t
*data
, t_selelem
*sel
, gmx_ana_index_t
*g
)
2004 t_selelem
*child
, *next
;
2008 if (sel
->type
!= SEL_ROOT
&& g
)
2010 alloc_selection_data(sel
, g
->isize
, FALSE
);
2013 bDoMinMax
= (sel
->cdata
->flags
& SEL_CDATA_MINMAXALLOC
);
2014 if (sel
->type
!= SEL_SUBEXPR
&& bDoMinMax
)
2016 gmx_ana_index_deinit(sel
->cdata
->gmin
);
2017 gmx_ana_index_deinit(sel
->cdata
->gmax
);
2020 /* TODO: This switch is awfully long... */
2025 rc
= process_const(data
, sel
, g
);
2028 case SEL_EXPRESSION
:
2030 rc
= _gmx_sel_evaluate_method_params(data
, sel
, g
);
2035 rc
= init_method(sel
, data
->top
, g
->isize
);
2040 if (!(sel
->flags
& SEL_DYNAMIC
))
2042 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2043 if (rc
== 0 && (sel
->cdata
->flags
& SEL_CDATA_STATIC
))
2050 /* Modifiers need to be evaluated even though they process
2051 * positions to get the modified output groups from the
2052 * maximum possible selections. */
2053 if (sel
->type
== SEL_MODIFIER
)
2055 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2059 gmx_ana_index_copy(sel
->cdata
->gmax
, g
, TRUE
);
2065 if (!(sel
->flags
& SEL_DYNAMIC
))
2067 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2068 if (rc
== 0 && (sel
->cdata
->flags
& SEL_CDATA_STATIC
))
2075 /* Evalute the static part if there is more than one expression */
2076 rc
= evaluate_gmx_boolean_static_part(data
, sel
, g
);
2082 /* Evaluate the selection.
2083 * If the type is gmx_boolean, we must explicitly handle the
2084 * static part evaluated in evaluate_gmx_boolean_static_part()
2085 * here because g may be larger. */
2086 if (sel
->u
.boolt
== BOOL_AND
&& sel
->child
->type
== SEL_CONST
)
2088 rc
= sel
->cdata
->evaluate(data
, sel
, sel
->child
->v
.u
.g
);
2092 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2099 /* Evaluate minimal and maximal selections */
2100 evaluate_gmx_boolean_minmax_grps(sel
, g
, sel
->cdata
->gmin
,
2105 case SEL_ARITHMETIC
:
2106 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2111 if (!(sel
->flags
& SEL_DYNAMIC
))
2113 if (sel
->cdata
->flags
& SEL_CDATA_STATIC
)
2120 gmx_ana_index_copy(sel
->cdata
->gmax
, g
, TRUE
);
2125 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2129 if (sel
->cdata
->flags
& (SEL_CDATA_SIMPLESUBEXPR
| SEL_CDATA_FULLEVAL
))
2131 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2132 _gmx_selvalue_setstore(&sel
->v
, sel
->child
->v
.u
.ptr
);
2134 else if (sel
->u
.cgrp
.isize
== 0)
2136 gmx_ana_index_reserve(&sel
->u
.cgrp
, g
->isize
);
2137 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2140 gmx_ana_index_copy(sel
->cdata
->gmin
, sel
->child
->cdata
->gmin
, TRUE
);
2141 gmx_ana_index_copy(sel
->cdata
->gmax
, sel
->child
->cdata
->gmax
, TRUE
);
2146 int isize
= gmx_ana_index_difference_size(g
, &sel
->u
.cgrp
);
2149 isize
+= sel
->u
.cgrp
.isize
;
2150 gmx_ana_index_reserve(&sel
->u
.cgrp
, isize
);
2151 alloc_selection_data(sel
, isize
, FALSE
);
2153 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2154 if (isize
> 0 && bDoMinMax
)
2156 gmx_ana_index_reserve(sel
->cdata
->gmin
,
2157 sel
->cdata
->gmin
->isize
2158 + sel
->child
->cdata
->gmin
->isize
);
2159 gmx_ana_index_reserve(sel
->cdata
->gmax
,
2160 sel
->cdata
->gmax
->isize
2161 + sel
->child
->cdata
->gmax
->isize
);
2162 gmx_ana_index_merge(sel
->cdata
->gmin
, sel
->cdata
->gmin
,
2163 sel
->child
->cdata
->gmin
);
2164 gmx_ana_index_merge(sel
->cdata
->gmax
, sel
->cdata
->gmax
,
2165 sel
->child
->cdata
->gmax
);
2170 case SEL_SUBEXPRREF
:
2171 if (!g
&& !(sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
))
2173 /* The subexpression should have been evaluated if g is NULL
2174 * (i.e., this is a method parameter or a direct value of a
2176 alloc_selection_data(sel
, sel
->child
->cdata
->gmax
->isize
, TRUE
);
2178 rc
= sel
->cdata
->evaluate(data
, sel
, g
);
2183 if ((sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
)
2184 && (sel
->child
->child
->flags
& SEL_ALLOCVAL
))
2186 _gmx_selvalue_setstore(&sel
->v
, sel
->child
->child
->v
.u
.ptr
);
2188 /* Store the parameter value if required */
2189 store_param_val(sel
);
2190 if (!(sel
->flags
& SEL_DYNAMIC
))
2192 if (sel
->cdata
->flags
& SEL_CDATA_STATIC
)
2199 if ((sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
) || !g
)
2201 gmx_ana_index_copy(sel
->cdata
->gmin
, sel
->child
->cdata
->gmin
, TRUE
);
2202 gmx_ana_index_copy(sel
->cdata
->gmax
, sel
->child
->cdata
->gmax
, TRUE
);
2206 gmx_ana_index_reserve(sel
->cdata
->gmin
,
2207 min(g
->isize
, sel
->child
->cdata
->gmin
->isize
));
2208 gmx_ana_index_reserve(sel
->cdata
->gmax
,
2209 min(g
->isize
, sel
->child
->cdata
->gmax
->isize
));
2210 gmx_ana_index_intersection(sel
->cdata
->gmin
,
2211 sel
->child
->cdata
->gmin
, g
);
2212 gmx_ana_index_intersection(sel
->cdata
->gmax
,
2213 sel
->child
->cdata
->gmax
, g
);
2218 /* Exit if there was some problem */
2224 /* Update the minimal and maximal evaluation groups */
2227 gmx_ana_index_squeeze(sel
->cdata
->gmin
);
2228 gmx_ana_index_squeeze(sel
->cdata
->gmax
);
2229 sfree(sel
->cdata
->gmin
->name
);
2230 sfree(sel
->cdata
->gmax
->name
);
2231 sel
->cdata
->gmin
->name
= NULL
;
2232 sel
->cdata
->gmax
->name
= NULL
;
2235 /* Replace the result of the evaluation */
2236 /* This is not necessary for subexpressions or for gmx_boolean negations
2237 * because the evaluation function already has done it properly. */
2238 if (sel
->v
.type
== GROUP_VALUE
&& (sel
->flags
& SEL_DYNAMIC
)
2239 && sel
->type
!= SEL_SUBEXPR
2240 && !(sel
->type
== SEL_BOOLEAN
&& sel
->u
.boolt
== BOOL_NOT
))
2242 if (sel
->cdata
->flags
& SEL_CDATA_EVALMAX
)
2244 gmx_ana_index_copy(sel
->v
.u
.g
, sel
->cdata
->gmax
, FALSE
);
2248 gmx_ana_index_copy(sel
->v
.u
.g
, sel
->cdata
->gmin
, FALSE
);
2256 /********************************************************************
2257 * EVALUATION GROUP INITIALIZATION
2258 ********************************************************************/
2261 * Initializes the evaluation group for a \ref SEL_ROOT element.
2263 * \param root Root element to initialize.
2264 * \param[in] gall Group of all atoms.
2266 * Checks whether it is necessary to evaluate anything through the root
2267 * element, and either clears the evaluation function or initializes the
2271 init_root_item(t_selelem
*root
, gmx_ana_index_t
*gall
)
2277 /* Subexpressions with non-static evaluation group should not be
2278 * evaluated by the root, and neither should be single-reference
2279 * subexpressions that don't evaluate for all atoms. */
2280 if (expr
->type
== SEL_SUBEXPR
2281 && (!(root
->child
->cdata
->flags
& SEL_CDATA_STATICEVAL
)
2282 || ((root
->child
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
)
2283 && !(root
->child
->cdata
->flags
& SEL_CDATA_FULLEVAL
))))
2285 root
->evaluate
= NULL
;
2288 root
->cdata
->evaluate
= NULL
;
2292 /* Set the evaluation group */
2293 name
= root
->u
.cgrp
.name
;
2296 /* Non-atom-valued non-group expressions don't care about the group, so
2297 * don't allocate any memory for it. */
2298 if ((expr
->flags
& SEL_VARNUMVAL
)
2299 || ((expr
->flags
& SEL_SINGLEVAL
) && expr
->v
.type
!= GROUP_VALUE
))
2301 gmx_ana_index_set(&root
->u
.cgrp
, -1, NULL
, NULL
, 0);
2303 else if (expr
->cdata
->gmax
->isize
== gall
->isize
)
2305 /* Save some memory by only referring to the global group. */
2306 gmx_ana_index_set(&root
->u
.cgrp
, gall
->isize
, gall
->index
, NULL
, 0);
2310 gmx_ana_index_copy(&root
->u
.cgrp
, expr
->cdata
->gmax
, TRUE
);
2312 /* For selections, store the maximum group for
2313 * gmx_ana_selcollection_evaluate_fin() as the value of the root
2314 * element (unused otherwise). */
2315 if (expr
->type
!= SEL_SUBEXPR
&& expr
->v
.u
.p
->g
)
2317 t_selelem
*child
= expr
;
2319 /* TODO: This code is copied from parsetree.c; it would be better
2320 * to have this hardcoded only in one place. */
2321 while (child
->type
== SEL_MODIFIER
)
2323 child
= child
->child
;
2324 if (child
->type
== SEL_SUBEXPRREF
)
2326 child
= child
->child
->child
;
2329 if (child
->type
== SEL_SUBEXPRREF
)
2331 child
= child
->child
->child
;
2333 if (child
->child
->flags
& SEL_DYNAMIC
)
2335 _gmx_selelem_set_vtype(root
, GROUP_VALUE
);
2336 root
->flags
|= (SEL_ALLOCVAL
| SEL_ALLOCDATA
);
2337 _gmx_selvalue_reserve(&root
->v
, 1);
2338 gmx_ana_index_copy(root
->v
.u
.g
, expr
->v
.u
.p
->g
, TRUE
);
2344 gmx_ana_index_clear(&root
->u
.cgrp
);
2346 root
->u
.cgrp
.name
= name
;
2350 /********************************************************************
2351 * FINAL SUBEXPRESSION OPTIMIZATION
2352 ********************************************************************/
2355 * Optimizes subexpression evaluation.
2357 * \param sel Root of the selection subtree to process.
2359 * Optimizes away some unnecessary evaluation of subexpressions that are only
2363 postprocess_item_subexpressions(t_selelem
*sel
)
2365 /* Process children. */
2366 if (sel
->type
!= SEL_SUBEXPRREF
)
2373 postprocess_item_subexpressions(child
);
2374 child
= child
->next
;
2378 /* Replace the evaluation function of statically evaluated subexpressions
2379 * for which the static group was not known in advance. */
2380 if (sel
->type
== SEL_SUBEXPR
&& sel
->refcount
> 2
2381 && (sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
)
2382 && !(sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
2386 /* We need to free memory allocated for the group, because it is no
2387 * longer needed (and would be lost on next call to the evaluation
2388 * function). But we need to preserve the name. */
2389 name
= sel
->u
.cgrp
.name
;
2390 gmx_ana_index_deinit(&sel
->u
.cgrp
);
2391 sel
->u
.cgrp
.name
= name
;
2393 sel
->evaluate
= &_gmx_sel_evaluate_subexpr_staticeval
;
2396 sel
->cdata
->evaluate
= sel
->evaluate
;
2398 _gmx_selelem_free_values(sel
->child
);
2399 sel
->child
->mempool
= NULL
;
2400 _gmx_selvalue_setstore(&sel
->child
->v
, sel
->v
.u
.ptr
);
2401 sel
->child
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
2404 /* Adjust memory allocation flags for subexpressions that are used only
2405 * once. This is not strictly necessary, but we do it to have the memory
2406 * managed consistently for all types of subexpressions. */
2407 if (sel
->type
== SEL_SUBEXPRREF
2408 && (sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
))
2410 if (sel
->child
->child
->flags
& SEL_ALLOCVAL
)
2412 sel
->flags
|= SEL_ALLOCVAL
;
2413 sel
->flags
|= (sel
->child
->child
->flags
& SEL_ALLOCDATA
);
2414 sel
->v
.nalloc
= sel
->child
->child
->v
.nalloc
;
2415 sel
->child
->child
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
2416 sel
->child
->child
->v
.nalloc
= -1;
2420 /* Do the same for subexpressions that are evaluated at once for all atoms. */
2421 if (sel
->type
== SEL_SUBEXPR
2422 && !(sel
->cdata
->flags
& SEL_CDATA_SIMPLESUBEXPR
)
2423 && (sel
->cdata
->flags
& SEL_CDATA_FULLEVAL
))
2425 sel
->flags
|= SEL_ALLOCVAL
;
2426 sel
->flags
|= (sel
->child
->flags
& SEL_ALLOCDATA
);
2427 sel
->v
.nalloc
= sel
->child
->v
.nalloc
;
2428 sel
->child
->flags
&= ~(SEL_ALLOCVAL
| SEL_ALLOCDATA
);
2429 sel
->child
->v
.nalloc
= -1;
2434 /********************************************************************
2435 * COM CALCULATION INITIALIZATION
2436 ********************************************************************/
2439 * Initializes COM/COG calculation for method expressions that require it.
2441 * \param sel Selection subtree to process.
2442 * \param[in,out] pcc Position calculation collection to use.
2443 * \param[in] type Default position calculation type.
2444 * \param[in] flags Flags for default position calculation.
2445 * \returns 0 on success, a non-zero error code on error.
2447 * Searches recursively through the selection tree for dynamic
2448 * \ref SEL_EXPRESSION elements that define the \c gmx_ana_selmethod_t::pupdate
2450 * For each such element found, position calculation is initialized
2451 * for the maximal evaluation group.
2452 * The type of the calculation is determined by \p type and \p flags.
2453 * No calculation is initialized if \p type equals \ref POS_ATOM and
2454 * the method also defines the \c gmx_ana_selmethod_t::update method.
2457 init_item_comg(t_selelem
*sel
, gmx_ana_poscalc_coll_t
*pcc
,
2458 e_poscalc_t type
, int flags
)
2463 /* Initialize COM calculation for dynamic selections now that we know the maximal evaluation group */
2464 if (sel
->type
== SEL_EXPRESSION
&& sel
->u
.expr
.method
2465 && sel
->u
.expr
.method
->pupdate
)
2467 if (!sel
->u
.expr
.method
->update
|| type
!= POS_ATOM
)
2469 /* Create a default calculation if one does not yet exist */
2472 if (!(sel
->cdata
->flags
& SEL_CDATA_STATICEVAL
))
2474 cflags
|= POS_DYNAMIC
;
2476 if (!sel
->u
.expr
.pc
)
2479 rc
= gmx_ana_poscalc_create(&sel
->u
.expr
.pc
, pcc
, type
, cflags
);
2487 gmx_ana_poscalc_set_flags(sel
->u
.expr
.pc
, cflags
);
2489 gmx_ana_poscalc_set_maxindex(sel
->u
.expr
.pc
, sel
->cdata
->gmax
);
2490 snew(sel
->u
.expr
.pos
, 1);
2491 gmx_ana_poscalc_init_pos(sel
->u
.expr
.pc
, sel
->u
.expr
.pos
);
2495 /* Call recursively for all children unless the children have already been processed */
2496 if (sel
->type
!= SEL_SUBEXPRREF
)
2501 rc
= init_item_comg(child
, pcc
, type
, flags
);
2506 child
= child
->next
;
2513 /********************************************************************
2514 * COMPILER DATA FREEING
2515 ********************************************************************/
2518 * Frees the allocated compiler data recursively.
2520 * \param sel Root of the selection subtree to process.
2522 * Frees the data allocated for the compilation process.
2525 free_item_compilerdata(t_selelem
*sel
)
2529 /* Free compilation data */
2530 _gmx_selelem_free_compiler_data(sel
);
2532 /* Call recursively for all children unless the children have already been processed */
2533 if (sel
->type
!= SEL_SUBEXPRREF
)
2538 free_item_compilerdata(child
);
2539 child
= child
->next
;
2545 /********************************************************************
2546 * MASS AND CHARGE CALCULATION
2547 ********************************************************************/
2550 * Initializes total masses and charges for selections.
2552 * \param[in] top Topology information.
2553 * \param[in] ngrps Number of elements in the \p sel array.
2554 * \param[in,out] sel Array of selections to update.
2555 * \param[in] bMaskOnly TRUE if the positions will always be calculated
2556 * for all atoms, i.e., the masses/charges do not change.
2559 calculate_mass_charge(t_topology
*top
, int ngrps
, gmx_ana_selection_t
*sel
[],
2564 for (g
= 0; g
< ngrps
; ++g
)
2566 sel
[g
]->g
= sel
[g
]->p
.g
;
2567 snew(sel
[g
]->orgm
, sel
[g
]->p
.nr
);
2568 snew(sel
[g
]->orgq
, sel
[g
]->p
.nr
);
2569 for (b
= 0; b
< sel
[g
]->p
.nr
; ++b
)
2571 sel
[g
]->orgq
[b
] = 0;
2574 sel
[g
]->orgm
[b
] = 0;
2575 for (i
= sel
[g
]->p
.m
.mapb
.index
[b
]; i
< sel
[g
]->p
.m
.mapb
.index
[b
+1]; ++i
)
2577 sel
[g
]->orgm
[b
] += top
->atoms
.atom
[sel
[g
]->g
->index
[i
]].m
;
2578 sel
[g
]->orgq
[b
] += top
->atoms
.atom
[sel
[g
]->g
->index
[i
]].q
;
2583 sel
[g
]->orgm
[b
] = 1;
2586 if (sel
[g
]->bDynamic
&& !bMaskOnly
)
2588 snew(sel
[g
]->m
, sel
[g
]->p
.nr
);
2589 snew(sel
[g
]->q
, sel
[g
]->p
.nr
);
2590 for (b
= 0; b
< sel
[g
]->p
.nr
; ++b
)
2592 sel
[g
]->m
[b
] = sel
[g
]->orgm
[b
];
2593 sel
[g
]->q
[b
] = sel
[g
]->orgq
[b
];
2598 sel
[g
]->m
= sel
[g
]->orgm
;
2599 sel
[g
]->q
= sel
[g
]->orgq
;
2605 /********************************************************************
2606 * MAIN COMPILATION FUNCTION
2607 ********************************************************************/
2610 * \param[in,out] sc Selection collection to debug.
2611 * \param[in] bDebug If TRUE, later call to gmx_ana_selcollection_compile()
2612 * will print out intermediate selection trees.
2615 gmx_ana_selcollection_set_compile_debug(gmx_ana_selcollection_t
*sc
, gmx_bool bDebug
)
2617 sc
->bDebugCompile
= bDebug
;
2621 * \param[in,out] sc Selection collection to be compiled.
2622 * \returns 0 on successful compilation, a non-zero error code on error.
2624 * Before compilation, the selection collection should have been initialized
2625 * with gmx_ana_selcollection_parse_*().
2626 * The compiled selection collection can be passed to
2627 * gmx_ana_selcollection_evaluate() to evaluate the selection for a frame.
2628 * If an error occurs, \p sc is cleared.
2630 * The covered fraction information in \p sc is initialized to
2634 gmx_ana_selcollection_compile(gmx_ana_selcollection_t
*sc
)
2636 gmx_sel_evaluate_t evaldata
;
2642 rc
= _gmx_sel_mempool_create(&sc
->mempool
);
2647 _gmx_sel_evaluate_init(&evaldata
, sc
->mempool
, &sc
->gall
,
2648 sc
->top
, NULL
, NULL
);
2650 /* Clear the symbol table because it is not possible to parse anything
2651 * after compilation, and variable references in the symbol table can
2652 * also mess up the compilation and/or become invalid.
2654 _gmx_selcollection_clear_symtab(sc
);
2656 /* Remove any unused variables. */
2657 sc
->root
= remove_unused_subexpressions(sc
->root
);
2658 /* Extract subexpressions into separate roots */
2659 sc
->root
= extract_subexpressions(sc
->root
);
2661 /* Initialize the evaluation callbacks and process the tree structure
2662 * to conform to the expectations of the callback functions. */
2663 /* Also, initialize and allocate the compiler data structure */
2667 /* Process gmx_boolean and arithmetic expressions. */
2668 optimize_gmx_boolean_expressions(item
);
2669 reorder_gmx_boolean_static_children(item
);
2670 if (!optimize_arithmetic_expressions(item
))
2672 /* FIXME: Clean up the collection */
2675 /* Initialize evaluation function. */
2676 if (!init_item_evalfunc(item
))
2678 /* FIXME: Clean up the collection */
2681 setup_memory_pooling(item
, sc
->mempool
);
2682 /* Initialize the compiler data */
2683 init_item_compilerdata(item
);
2684 init_item_staticeval(item
);
2687 /* Initialize subexpression flags and evaluation output.
2688 * Requires compiler flags for the full tree. */
2692 init_item_subexpr_flags(item
);
2693 init_item_evaloutput(item
);
2696 /* Initialize minimum/maximum index groups.
2697 * Requires evaluation output for the full tree. */
2701 init_item_minmax_groups(item
);
2704 /* Initialize the evaluation index groups */
2705 initialize_evalgrps(sc
);
2707 if (sc
->bDebugCompile
)
2709 fprintf(stderr
, "\nTree after initial compiler processing:\n");
2710 gmx_ana_selcollection_print_tree(stderr
, sc
, FALSE
);
2713 /* Evaluate all static parts of the selection and analyze the tree
2714 * to allocate enough memory to store the value of each dynamic subtree. */
2718 if (item
->child
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
)
2720 mark_subexpr_dynamic(item
->child
, TRUE
);
2722 set_evaluation_function(item
, &analyze_static
);
2723 rc
= item
->evaluate(&evaldata
, item
, NULL
);
2726 /* FIXME: Clean up the collection */
2732 /* At this point, static subexpressions no longer have references to them,
2733 * so they can be removed. */
2734 sc
->root
= remove_unused_subexpressions(sc
->root
);
2736 if (sc
->bDebugCompile
)
2738 fprintf(stderr
, "\nTree after first analysis pass:\n");
2739 gmx_ana_selcollection_print_tree(stderr
, sc
, FALSE
);
2742 /* Do a second pass to evaluate static parts of common subexpressions */
2746 if (item
->child
->cdata
->flags
& SEL_CDATA_COMMONSUBEXPR
)
2748 gmx_bool bMinMax
= item
->child
->cdata
->flags
& SEL_CDATA_MINMAXALLOC
;
2750 mark_subexpr_dynamic(item
->child
, FALSE
);
2751 item
->child
->u
.cgrp
.isize
= 0;
2752 /* We won't clear item->child->v.u.g here, because it may
2753 * be static, and hence actually point to item->child->cdata->gmax,
2754 * which is used below. We could also check whether this is the
2755 * case and only clear the group otherwise, but because the value
2756 * is actually overwritten immediately in the evaluate call, we
2757 * won't, because similar problems may arise if gmax handling ever
2758 * changes and the check were not updated.
2759 * For the same reason, we clear the min/max flag so that the
2760 * evaluation group doesn't get messed up. */
2761 set_evaluation_function(item
, &analyze_static
);
2762 item
->child
->cdata
->flags
&= ~SEL_CDATA_MINMAXALLOC
;
2763 rc
= item
->evaluate(&evaldata
, item
->child
, item
->child
->cdata
->gmax
);
2766 item
->child
->cdata
->flags
|= SEL_CDATA_MINMAXALLOC
;
2770 /* FIXME: Clean up the collection */
2777 /* We need a yet another pass of subexpression removal to remove static
2778 * subexpressions referred to by common dynamic subexpressions. */
2779 sc
->root
= remove_unused_subexpressions(sc
->root
);
2781 if (sc
->bDebugCompile
)
2783 fprintf(stderr
, "\nTree after second analysis pass:\n");
2784 gmx_ana_selcollection_print_tree(stderr
, sc
, FALSE
);
2787 /* Initialize evaluation groups, position calculations for methods, perform
2788 * some final optimization, and free the memory allocated for the
2790 /* By default, use whole residues/molecules. */
2791 flags
= POS_COMPLWHOLE
;
2792 rc
= gmx_ana_poscalc_type_from_enum(sc
->rpost
, &post
, &flags
);
2795 gmx_bug("invalid default reference position type");
2796 /* FIXME: Clean up the collection */
2802 init_root_item(item
, &sc
->gall
);
2803 postprocess_item_subexpressions(item
);
2804 rc
= init_item_comg(item
, sc
->pcc
, post
, flags
);
2807 /* FIXME: Clean up the collection */
2810 free_item_compilerdata(item
);
2814 /* Allocate memory for the evaluation memory pool. */
2815 rc
= _gmx_sel_mempool_reserve(sc
->mempool
, 0);
2821 /* Finish up by calculating total masses and charges. */
2822 calculate_mass_charge(sc
->top
, sc
->nr
, sc
->sel
, sc
->bMaskOnly
);