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 Implementation of functions in selelem.h.
39 #include <gmx_fatal.h>
41 #include <indexutil.h>
44 #include <selmethod.h>
52 * \param[in] sel Selection for which the string is requested
53 * \returns Pointer to a string that corresponds to \p sel->type.
55 * The return value points to a string constant and should not be \p free'd.
57 * The function returns NULL if \p sel->type is not one of the valid values.
60 _gmx_selelem_type_str(t_selelem
*sel
)
64 case SEL_CONST
: return "CONST";
65 case SEL_EXPRESSION
: return "EXPR";
66 case SEL_BOOLEAN
: return "BOOL";
67 case SEL_ARITHMETIC
: return "ARITH";
68 case SEL_ROOT
: return "ROOT";
69 case SEL_SUBEXPR
: return "SUBEXPR";
70 case SEL_SUBEXPRREF
: return "REF";
71 case SEL_MODIFIER
: return "MODIFIER";
77 * \param[in] val Value structore for which the string is requested.
78 * \returns Pointer to a string that corresponds to \p val->type,
79 * NULL if the type value is invalid.
81 * The return value points to a string constant and should not be \p free'd.
84 _gmx_sel_value_type_str(gmx_ana_selvalue_t
*val
)
88 case NO_VALUE
: return "NONE";
89 case INT_VALUE
: return "INT";
90 case REAL_VALUE
: return "REAL";
91 case STR_VALUE
: return "STR";
92 case POS_VALUE
: return "VEC";
93 case GROUP_VALUE
: return "GROUP";
98 /*! \copydoc _gmx_selelem_type_str() */
100 _gmx_selelem_boolean_type_str(t_selelem
*sel
)
102 switch (sel
->u
.boolt
)
104 case BOOL_NOT
: return "NOT"; break;
105 case BOOL_AND
: return "AND"; break;
106 case BOOL_OR
: return "OR"; break;
107 case BOOL_XOR
: return "XOR"; break;
113 * \param[in] type Type of selection element to allocate.
114 * \returns Pointer to the newly allocated and initialized element.
116 * \c t_selelem::type is set to \p type,
117 * \c t_selelem::v::type is set to \ref GROUP_VALUE for boolean and comparison
118 * expressions and \ref NO_VALUE for others,
119 * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA is also
120 * set for \ref SEL_BOOLEAN elements),
121 * and \c t_selelem::refcount is set to one.
122 * All the pointers are set to NULL.
125 _gmx_selelem_create(e_selelem_t type
)
132 sel
->flags
= (type
!= SEL_ROOT
) ? SEL_ALLOCVAL
: 0;
133 if (type
== SEL_BOOLEAN
)
135 sel
->v
.type
= GROUP_VALUE
;
136 sel
->flags
|= SEL_ALLOCDATA
;
140 sel
->v
.type
= NO_VALUE
;
142 _gmx_selvalue_clear(&sel
->v
);
143 sel
->evaluate
= NULL
;
153 * \param[in,out] sel Selection element to set the type for.
154 * \param[in] vtype Value type for the selection element.
155 * \returns 0 on success, EINVAL if the value type is invalid.
157 * If the new type is \ref GROUP_VALUE or \ref POS_VALUE, the
158 * \ref SEL_ALLOCDATA flag is also set.
160 * This function should only be called at most once for each element,
161 * preferably right after calling _gmx_selelem_create().
164 _gmx_selelem_set_vtype(t_selelem
*sel
, e_selvalue_t vtype
)
166 if (sel
->type
== SEL_BOOLEAN
&& vtype
!= GROUP_VALUE
)
168 gmx_bug("internal error");
171 if (sel
->v
.type
!= NO_VALUE
&& vtype
!= sel
->v
.type
)
173 gmx_call("_gmx_selelem_set_vtype() called more than once");
177 if (vtype
== GROUP_VALUE
|| vtype
== POS_VALUE
)
179 sel
->flags
|= SEL_ALLOCDATA
;
185 * \param[in,out] sel Selection element to reserve.
186 * \param[in] count Number of values to reserve memory for.
187 * \returns 0 on success or if no memory pool, non-zero on error.
189 * Reserves memory for the values of \p sel from the \p sel->mempool
190 * memory pool. If no memory pool is set, nothing is done.
193 _gmx_selelem_mempool_reserve(t_selelem
*sel
, int count
)
204 rc
= _gmx_sel_mempool_alloc_group(sel
->mempool
, sel
->v
.u
.g
, count
);
208 gmx_bug("mem pooling not implemented for non-group values");
215 * \param[in,out] sel Selection element to release.
217 * Releases the memory allocated for the values of \p sel from the
218 * \p sel->mempool memory pool. If no memory pool is set, nothing is done.
221 _gmx_selelem_mempool_release(t_selelem
*sel
)
232 _gmx_sel_mempool_free(sel
->mempool
, sel
->v
.u
.g
->index
);
233 sel
->v
.u
.g
->index
= NULL
;
238 gmx_bug("mem pooling not implemented for non-group values");
244 * \param[in] sel Selection to free.
247 _gmx_selelem_free_values(t_selelem
*sel
)
251 _gmx_selelem_mempool_release(sel
);
252 if ((sel
->flags
& SEL_ALLOCDATA
) && sel
->v
.u
.ptr
)
254 /* The number of position/group structures is constant, so the
255 * backup of using sel->v.nr should work for them.
256 * For strings, we report an error if we don't know the allocation
258 n
= (sel
->v
.nalloc
> 0) ? sel
->v
.nalloc
: sel
->v
.nr
;
262 if (sel
->v
.nalloc
== 0)
264 gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values");
267 for (i
= 0; i
< n
; ++i
)
269 sfree(sel
->v
.u
.s
[i
]);
273 for (i
= 0; i
< n
; ++i
)
275 gmx_ana_pos_deinit(&sel
->v
.u
.p
[i
]);
279 for (i
= 0; i
< n
; ++i
)
281 gmx_ana_index_deinit(&sel
->v
.u
.g
[i
]);
284 default: /* No special handling for other types */
288 if (sel
->flags
& SEL_ALLOCVAL
)
292 _gmx_selvalue_setstore(&sel
->v
, NULL
);
296 * \param[in] method Method to free.
297 * \param[in] mdata Method data to free.
298 * \param[in] bFreeParamData If TRUE, free also the values of parameters.
301 _gmx_selelem_free_method(gmx_ana_selmethod_t
*method
, void *mdata
,
304 /* Free method data */
307 if (method
&& method
->free
)
313 /* Free the method itself */
318 /* If the method has not yet been initialized, we must free the
319 * memory allocated for parameter values here. */
322 for (i
= 0; i
< method
->nparams
; ++i
)
324 gmx_ana_selparam_t
*param
= &method
->param
[i
];
326 if ((param
->flags
& (SPAR_VARNUM
| SPAR_ATOMVAL
))
327 && param
->val
.type
!= GROUP_VALUE
328 && param
->val
.type
!= POS_VALUE
)
330 /* We don't need to check for enum values here, because
331 * SPAR_ENUMVAL cannot be combined with the flags
332 * required above. If it ever will be, this results
333 * in a double free within this function, which should
334 * be relatively easy to debug.
336 if (param
->val
.type
== STR_VALUE
)
340 for (j
= 0; j
< param
->val
.nr
; ++j
)
342 sfree(param
->val
.u
.s
[j
]);
345 sfree(param
->val
.u
.ptr
);
349 /* And even if it is, the arrays allocated for enum values need
351 for (i
= 0; i
< method
->nparams
; ++i
)
353 gmx_ana_selparam_t
*param
= &method
->param
[i
];
355 if (param
->flags
& SPAR_ENUMVAL
)
357 sfree(param
->val
.u
.ptr
);
361 sfree(method
->param
);
367 * \param[in] sel Selection to free.
370 _gmx_selelem_free_exprdata(t_selelem
*sel
)
372 if (sel
->type
== SEL_EXPRESSION
|| sel
->type
== SEL_MODIFIER
)
374 _gmx_selelem_free_method(sel
->u
.expr
.method
, sel
->u
.expr
.mdata
,
375 !(sel
->flags
& SEL_METHODINIT
));
376 sel
->u
.expr
.mdata
= NULL
;
377 sel
->u
.expr
.method
= NULL
;
378 /* Free position data */
381 gmx_ana_pos_free(sel
->u
.expr
.pos
);
382 sel
->u
.expr
.pos
= NULL
;
384 /* Free position calculation data */
387 gmx_ana_poscalc_free(sel
->u
.expr
.pc
);
388 sel
->u
.expr
.pc
= NULL
;
391 if (sel
->type
== SEL_ARITHMETIC
)
393 sfree(sel
->u
.arith
.opstr
);
394 sel
->u
.arith
.opstr
= NULL
;
396 if (sel
->type
== SEL_SUBEXPR
|| sel
->type
== SEL_ROOT
397 || (sel
->type
== SEL_CONST
&& sel
->v
.type
== GROUP_VALUE
))
399 gmx_ana_index_deinit(&sel
->u
.cgrp
);
404 * \param[in] sel Selection to free.
406 * Decrements \ref t_selelem::refcount "sel->refcount" and frees the
407 * memory allocated for \p sel and all its children if the reference count
411 _gmx_selelem_free(t_selelem
*sel
)
413 t_selelem
*child
, *prev
;
415 /* Decrement the reference counter and do nothing if references remain */
417 if (sel
->refcount
> 0)
422 /* Free the children */
428 _gmx_selelem_free(prev
);
431 /* Free value storage */
432 _gmx_selelem_free_values(sel
);
434 /* Free other storage */
435 _gmx_selelem_free_exprdata(sel
);
437 /* Free temporary compiler data if present */
438 _gmx_selelem_free_compiler_data(sel
);
444 * \param[in] first First selection to free.
446 * Frees \p first and all selections accessible through the
447 * \ref t_selelem::next "first->next" pointer.
450 _gmx_selelem_free_chain(t_selelem
*first
)
452 t_selelem
*child
, *prev
;
459 _gmx_selelem_free(prev
);
464 * Writes out a human-readable name for the evaluation function.
466 * \param[in] fp File handle to receive the output.
467 * \param[in] sel Selection element for which the evaluation function is printed.
470 print_evaluation_func(FILE *fp
, t_selelem
*sel
)
472 fprintf(fp
, " eval=");
475 else if (sel
->evaluate
== &_gmx_sel_evaluate_root
)
477 else if (sel
->evaluate
== &_gmx_sel_evaluate_static
)
478 fprintf(fp
, "static");
479 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexpr_pass
)
480 fprintf(fp
, "subexpr_pass");
481 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexpr
)
482 fprintf(fp
, "subexpr");
483 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexprref_pass
)
484 fprintf(fp
, "ref_pass");
485 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexprref
)
487 else if (sel
->evaluate
== &_gmx_sel_evaluate_method
)
488 fprintf(fp
, "method");
489 else if (sel
->evaluate
== &_gmx_sel_evaluate_modifier
)
491 else if (sel
->evaluate
== &_gmx_sel_evaluate_not
)
493 else if (sel
->evaluate
== &_gmx_sel_evaluate_and
)
495 else if (sel
->evaluate
== &_gmx_sel_evaluate_or
)
497 else if (sel
->evaluate
== &_gmx_sel_evaluate_arithmetic
)
498 fprintf(fp
, "arithmetic");
500 fprintf(fp
, "%p", (void*)(sel
->evaluate
));
504 * \param[in] fp File handle to receive the output.
505 * \param[in] sel Root of the selection subtree to print.
506 * \param[in] bValues If TRUE, the evaluated values of selection elements
507 * are printed as well.
508 * \param[in] level Indentation level, starting from zero.
511 _gmx_selelem_print_tree(FILE *fp
, t_selelem
*sel
, bool bValues
, int level
)
516 fprintf(fp
, "%*c %s %s", level
*2+1, '*',
517 _gmx_selelem_type_str(sel
), _gmx_sel_value_type_str(&sel
->v
));
520 fprintf(fp
, " \"%s\"", sel
->name
);
522 fprintf(fp
, " flg=");
523 if (sel
->flags
& SEL_FLAGSSET
)
527 if (sel
->flags
& SEL_SINGLEVAL
)
531 if (sel
->flags
& SEL_ATOMVAL
)
535 if (sel
->flags
& SEL_VARNUMVAL
)
539 if (sel
->flags
& SEL_DYNAMIC
)
543 if (!(sel
->flags
& SEL_VALFLAGMASK
))
551 if (sel
->type
== SEL_CONST
)
553 if (sel
->v
.type
== INT_VALUE
)
555 fprintf(fp
, " %d", sel
->v
.u
.i
[0]);
557 else if (sel
->v
.type
== REAL_VALUE
)
559 fprintf(fp
, " %f", sel
->v
.u
.r
[0]);
561 else if (sel
->v
.type
== GROUP_VALUE
)
563 gmx_ana_index_t
*g
= sel
->v
.u
.g
;
564 if (!g
|| g
->isize
== 0)
566 fprintf(fp
, " (%d atoms)", g
->isize
);
569 else if (sel
->type
== SEL_BOOLEAN
)
571 fprintf(fp
, " %s", _gmx_selelem_boolean_type_str(sel
));
573 else if (sel
->type
== SEL_EXPRESSION
574 && sel
->u
.expr
.method
->name
== sm_compare
.name
)
576 _gmx_selelem_print_compare_info(fp
, sel
->u
.expr
.mdata
);
580 print_evaluation_func(fp
, sel
);
582 if (sel
->refcount
> 1)
584 fprintf(fp
, " refc=%d", sel
->refcount
);
586 if (!(sel
->flags
& SEL_ALLOCVAL
))
588 fprintf(fp
, " (ext. output)");
592 if ((sel
->type
== SEL_CONST
&& sel
->v
.type
== GROUP_VALUE
) || sel
->type
== SEL_ROOT
)
594 gmx_ana_index_t
*g
= sel
->v
.u
.g
;
595 if (!g
|| g
->isize
== 0 || sel
->evaluate
!= NULL
)
601 fprintf(fp
, "%*c group:", level
*2+1, ' ');
604 for (i
= 0; i
< g
->isize
; ++i
)
606 fprintf(fp
, " %d", g
->index
[i
] + 1);
611 fprintf(fp
, " %d atoms", g
->isize
);
616 else if (sel
->type
== SEL_EXPRESSION
)
620 fprintf(fp
, "%*c COM", level
*2+3, '*');
625 if (bValues
&& sel
->type
!= SEL_CONST
&& sel
->type
!= SEL_ROOT
&& sel
->v
.u
.ptr
)
627 fprintf(fp
, "%*c value: ", level
*2+1, ' ');
631 /* In normal use, the pointer should never be NULL, but it's
632 * useful to have the check for debugging to avoid accidental
633 * segfaults when printing the selection tree. */
636 fprintf(fp
, "(%f, %f, %f)",
637 sel
->v
.u
.p
->x
[0][XX
], sel
->v
.u
.p
->x
[0][YY
],
638 sel
->v
.u
.p
->x
[0][ZZ
]);
642 fprintf(fp
, "(null)");
646 fprintf(fp
, "%d atoms", sel
->v
.u
.g
->isize
);
647 if (sel
->v
.u
.g
->isize
< 20)
649 if (sel
->v
.u
.g
->isize
> 0)
653 for (i
= 0; i
< sel
->v
.u
.g
->isize
; ++i
)
655 fprintf(fp
, " %d", sel
->v
.u
.g
->index
[i
] + 1);
666 /* Print the subexpressions with one more level of indentation */
670 if (!(sel
->type
== SEL_SUBEXPRREF
&& child
->type
== SEL_SUBEXPR
))
672 _gmx_selelem_print_tree(fp
, child
, bValues
, level
+1);
679 * \param[in] root Root of the subtree to query.
680 * \returns TRUE if \p root or any any of its elements require topology
681 * information, FALSE otherwise.
684 _gmx_selelem_requires_top(t_selelem
*root
)
688 if (root
->type
== SEL_EXPRESSION
|| root
->type
== SEL_MODIFIER
)
690 if (root
->u
.expr
.method
&& (root
->u
.expr
.method
->flags
& SMETH_REQTOP
))
694 if (root
->u
.expr
.pc
&& gmx_ana_poscalc_requires_top(root
->u
.expr
.pc
))
702 if (_gmx_selelem_requires_top(child
))