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.
40 #include <indexutil.h>
43 #include <selmethod.h>
50 * \param[in] sel Selection for which the string is requested
51 * \returns Pointer to a string that corresponds to \p sel->type.
53 * The return value points to a string constant and should not be \p free'd.
55 * The function returns NULL if \p sel->type is not one of the valid values.
58 _gmx_selelem_type_str(t_selelem
*sel
)
62 case SEL_CONST
: return "CONST";
63 case SEL_EXPRESSION
: return "EXPR";
64 case SEL_BOOLEAN
: return "BOOL";
65 case SEL_ROOT
: return "ROOT";
66 case SEL_SUBEXPR
: return "SUBEXPR";
67 case SEL_SUBEXPRREF
: return "REF";
68 case SEL_MODIFIER
: return "MODIFIER";
74 * \param[in] val Value structore for which the string is requested.
75 * \returns Pointer to a string that corresponds to \p val->type,
76 * NULL if the type value is invalid.
78 * The return value points to a string constant and should not be \p free'd.
81 _gmx_sel_value_type_str(gmx_ana_selvalue_t
*val
)
85 case NO_VALUE
: return "NONE";
86 case INT_VALUE
: return "INT";
87 case REAL_VALUE
: return "REAL";
88 case STR_VALUE
: return "STR";
89 case POS_VALUE
: return "VEC";
90 case GROUP_VALUE
: return "GROUP";
95 /*! \copydoc _gmx_selelem_type_str() */
97 _gmx_selelem_boolean_type_str(t_selelem
*sel
)
101 case BOOL_NOT
: return "NOT"; break;
102 case BOOL_AND
: return "AND"; break;
103 case BOOL_OR
: return "OR"; break;
104 case BOOL_XOR
: return "XOR"; break;
110 * \param[in] type Type of selection element to allocate.
111 * \returns Pointer to the newly allocated and initialized element.
113 * \c t_selelem::type is set to \p type,
114 * \c t_selelem::v::type is set to \ref GROUP_VALUE for boolean and comparison
115 * expressions and \ref NO_VALUE for others,
116 * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA is also
117 * set for \ref SEL_BOOLEAN elements),
118 * and \c t_selelem::refcount is set to one.
119 * All the pointers are set to NULL.
122 _gmx_selelem_create(e_selelem_t type
)
129 sel
->flags
= (type
!= SEL_ROOT
) ? SEL_ALLOCVAL
: 0;
130 if (type
== SEL_BOOLEAN
)
132 sel
->v
.type
= GROUP_VALUE
;
133 sel
->flags
|= SEL_ALLOCDATA
;
137 sel
->v
.type
= NO_VALUE
;
139 _gmx_selvalue_clear(&sel
->v
);
140 sel
->evaluate
= NULL
;
149 * \param[in,out] sel Selection element to set the type for.
150 * \param[in] vtype Value type for the selection element.
151 * \returns 0 on success, EINVAL if the value type is invalid.
153 * If the new type is \ref GROUP_VALUE or \ref POS_VALUE, the
154 * \ref SEL_ALLOCDATA flag is also set.
156 * This function should only be called at most once for each element,
157 * preferably right after calling _gmx_selelem_create().
160 _gmx_selelem_set_vtype(t_selelem
*sel
, e_selvalue_t vtype
)
162 if (sel
->type
== SEL_BOOLEAN
&& vtype
!= GROUP_VALUE
)
164 gmx_bug("internal error");
167 if (sel
->v
.type
!= NO_VALUE
&& vtype
!= sel
->v
.type
)
169 gmx_call("_gmx_selelem_set_vtype() called more than once");
173 if (vtype
== GROUP_VALUE
|| vtype
== POS_VALUE
)
175 sel
->flags
|= SEL_ALLOCDATA
;
181 * \param[in] sel Selection to free.
184 _gmx_selelem_free_values(t_selelem
*sel
)
188 if ((sel
->flags
& SEL_ALLOCDATA
) && sel
->v
.u
.ptr
)
190 /* The number of position/group structures is constant, so the
191 * backup of using sel->v.nr should work for them.
192 * For strings, we report an error if we don't know the allocation
194 n
= (sel
->v
.nalloc
> 0) ? sel
->v
.nalloc
: sel
->v
.nr
;
198 if (sel
->v
.nalloc
== 0)
200 gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values");
203 for (i
= 0; i
< n
; ++i
)
205 sfree(sel
->v
.u
.s
[i
]);
209 for (i
= 0; i
< n
; ++i
)
211 gmx_ana_pos_deinit(&sel
->v
.u
.p
[i
]);
215 for (i
= 0; i
< n
; ++i
)
217 gmx_ana_index_deinit(&sel
->v
.u
.g
[i
]);
220 default: /* No special handling for other types */
224 if (sel
->flags
& SEL_ALLOCVAL
)
228 _gmx_selvalue_setstore(&sel
->v
, NULL
);
232 * \param[in] sel Selection to free.
235 _gmx_selelem_free_exprdata(t_selelem
*sel
)
239 if (sel
->type
== SEL_EXPRESSION
|| sel
->type
== SEL_MODIFIER
)
241 /* Free method data */
242 if (sel
->u
.expr
.mdata
)
244 if (sel
->u
.expr
.method
&& sel
->u
.expr
.method
->free
)
246 sel
->u
.expr
.method
->free(sel
->u
.expr
.mdata
);
248 sfree(sel
->u
.expr
.mdata
);
249 sel
->u
.expr
.mdata
= NULL
;
251 /* Free the method itself */
252 if (sel
->u
.expr
.method
)
254 /* If the method has not yet been initialized, we must free the
255 * memory allocated for parameter values here. */
256 if (!(sel
->flags
& SEL_METHODINIT
))
258 for (i
= 0; i
< sel
->u
.expr
.method
->nparams
; ++i
)
260 gmx_ana_selparam_t
*param
= &sel
->u
.expr
.method
->param
[i
];
262 if ((param
->flags
& (SPAR_VARNUM
| SPAR_ATOMVAL
))
263 && param
->val
.type
!= GROUP_VALUE
264 && param
->val
.type
!= POS_VALUE
)
266 /* We don't need to check for enum values here, because
267 * SPAR_ENUMVAL cannot be combined with the flags
268 * required above. If it ever will be, this results
269 * in a double free within this function, which should
270 * be relatively easy to debug.
272 if (param
->val
.type
== STR_VALUE
)
276 for (j
= 0; j
< param
->val
.nr
; ++j
)
278 sfree(param
->val
.u
.s
[j
]);
281 sfree(param
->val
.u
.ptr
);
285 /* And even if it is, the arrays allocated for enum values need
287 for (i
= 0; i
< sel
->u
.expr
.method
->nparams
; ++i
)
289 gmx_ana_selparam_t
*param
= &sel
->u
.expr
.method
->param
[i
];
291 if (param
->flags
& SPAR_ENUMVAL
)
293 sfree(param
->val
.u
.ptr
);
297 sfree(sel
->u
.expr
.method
->param
);
298 sfree(sel
->u
.expr
.method
);
299 sel
->u
.expr
.method
= NULL
;
301 /* Free position data */
304 gmx_ana_pos_free(sel
->u
.expr
.pos
);
305 sel
->u
.expr
.pos
= NULL
;
307 /* Free position calculation data */
310 gmx_ana_poscalc_free(sel
->u
.expr
.pc
);
311 sel
->u
.expr
.pc
= NULL
;
317 * \param[in] sel Selection to free.
319 * Decrements \ref t_selelem::refcount "sel->refcount" and frees the
320 * memory allocated for \p sel and all its children if the reference count
324 _gmx_selelem_free(t_selelem
*sel
)
326 t_selelem
*child
, *prev
;
328 /* Decrement the reference counter and do nothing if references remain */
330 if (sel
->refcount
> 0)
335 /* Free the children */
341 _gmx_selelem_free(prev
);
344 /* Free value storage */
345 _gmx_selelem_free_values(sel
);
347 /* Free other storage */
348 _gmx_selelem_free_exprdata(sel
);
349 if (sel
->type
== SEL_SUBEXPR
|| sel
->type
== SEL_ROOT
350 || (sel
->type
== SEL_CONST
&& sel
->v
.type
== GROUP_VALUE
))
352 gmx_ana_index_deinit(&sel
->u
.cgrp
);
355 /* Free temporary compiler data if present */
356 _gmx_selelem_free_compiler_data(sel
);
362 * \param[in] first First selection to free.
364 * Frees \p first and all selections accessible through the
365 * \ref t_selelem::next "first->next" pointer.
368 _gmx_selelem_free_chain(t_selelem
*first
)
370 t_selelem
*child
, *prev
;
377 _gmx_selelem_free(prev
);
382 * Writes out a human-readable name for the evaluation function.
384 * \param[in] fp File handle to receive the output.
385 * \param[in] sel Selection element for which the evaluation function is printed.
388 print_evaluation_func(FILE *fp
, t_selelem
*sel
)
390 fprintf(fp
, " eval=");
393 else if (sel
->evaluate
== &_gmx_sel_evaluate_root
)
395 else if (sel
->evaluate
== &_gmx_sel_evaluate_static
)
396 fprintf(fp
, "static");
397 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexpr_pass
)
398 fprintf(fp
, "subexpr_pass");
399 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexpr
)
400 fprintf(fp
, "subexpr");
401 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexprref_pass
)
402 fprintf(fp
, "ref_pass");
403 else if (sel
->evaluate
== &_gmx_sel_evaluate_subexprref
)
405 else if (sel
->evaluate
== &_gmx_sel_evaluate_method
)
406 fprintf(fp
, "method");
407 else if (sel
->evaluate
== &_gmx_sel_evaluate_modifier
)
409 else if (sel
->evaluate
== &_gmx_sel_evaluate_not
)
411 else if (sel
->evaluate
== &_gmx_sel_evaluate_and
)
413 else if (sel
->evaluate
== &_gmx_sel_evaluate_or
)
416 fprintf(fp
, "%p", (void*)(sel
->evaluate
));
420 * \param[in] fp File handle to receive the output.
421 * \param[in] sel Root of the selection subtree to print.
422 * \param[in] bValues If TRUE, the evaluated values of selection elements
423 * are printed as well.
424 * \param[in] level Indentation level, starting from zero.
427 _gmx_selelem_print_tree(FILE *fp
, t_selelem
*sel
, bool bValues
, int level
)
432 fprintf(fp
, "%*c %s %s", level
*2+1, '*',
433 _gmx_selelem_type_str(sel
), _gmx_sel_value_type_str(&sel
->v
));
436 fprintf(fp
, " \"%s\"", sel
->name
);
438 fprintf(fp
, " flg=");
439 if (sel
->flags
& SEL_FLAGSSET
)
443 if (sel
->flags
& SEL_SINGLEVAL
)
447 if (sel
->flags
& SEL_ATOMVAL
)
451 if (sel
->flags
& SEL_VARNUMVAL
)
455 if (sel
->flags
& SEL_DYNAMIC
)
459 if (!(sel
->flags
& SEL_VALFLAGMASK
))
463 if (sel
->type
== SEL_CONST
)
465 if (sel
->v
.type
== INT_VALUE
)
467 fprintf(fp
, " %d", sel
->v
.u
.i
[0]);
469 else if (sel
->v
.type
== REAL_VALUE
)
471 fprintf(fp
, " %f", sel
->v
.u
.r
[0]);
473 else if (sel
->v
.type
== GROUP_VALUE
)
475 gmx_ana_index_t
*g
= sel
->v
.u
.g
;
476 if (!g
|| g
->isize
== 0)
478 fprintf(fp
, " (%d atoms)", g
->isize
);
481 else if (sel
->type
== SEL_BOOLEAN
)
483 fprintf(fp
, " %s", _gmx_selelem_boolean_type_str(sel
));
485 else if (sel
->type
== SEL_EXPRESSION
486 && sel
->u
.expr
.method
->name
== sm_compare
.name
)
488 _gmx_selelem_print_compare_info(fp
, sel
->u
.expr
.mdata
);
492 print_evaluation_func(fp
, sel
);
494 if (sel
->refcount
> 1)
496 fprintf(fp
, " refc=%d", sel
->refcount
);
498 if (!(sel
->flags
& SEL_ALLOCVAL
))
500 fprintf(fp
, " (ext. output)");
504 if ((sel
->type
== SEL_CONST
&& sel
->v
.type
== GROUP_VALUE
) || sel
->type
== SEL_ROOT
)
506 gmx_ana_index_t
*g
= sel
->v
.u
.g
;
507 if (!g
|| g
->isize
== 0 || sel
->evaluate
!= NULL
)
513 fprintf(fp
, "%*c group:", level
*2+1, ' ');
516 for (i
= 0; i
< g
->isize
; ++i
)
518 fprintf(fp
, " %d", g
->index
[i
] + 1);
523 fprintf(fp
, " %d atoms", g
->isize
);
528 else if (sel
->type
== SEL_EXPRESSION
)
532 fprintf(fp
, "%*c COM", level
*2+3, '*');
537 if (bValues
&& sel
->type
!= SEL_CONST
&& sel
->type
!= SEL_ROOT
&& sel
->v
.u
.ptr
)
539 fprintf(fp
, "%*c value: ", level
*2+1, ' ');
543 fprintf(fp
, "(%f, %f, %f)",
544 sel
->v
.u
.p
->x
[0][XX
], sel
->v
.u
.p
->x
[0][YY
], sel
->v
.u
.p
->x
[0][ZZ
]);
547 fprintf(fp
, "%d atoms", sel
->v
.u
.g
->isize
);
548 if (sel
->v
.u
.g
->isize
< 20)
550 if (sel
->v
.u
.g
->isize
> 0)
554 for (i
= 0; i
< sel
->v
.u
.g
->isize
; ++i
)
556 fprintf(fp
, " %d", sel
->v
.u
.g
->index
[i
] + 1);
567 /* Print the subexpressions with one more level of indentation */
571 if (!(sel
->type
== SEL_SUBEXPRREF
&& child
->type
== SEL_SUBEXPR
))
573 _gmx_selelem_print_tree(fp
, child
, bValues
, level
+1);
580 * \param[in] root Root of the subtree to query.
581 * \returns TRUE if \p root or any any of its elements require topology
582 * information, FALSE otherwise.
585 _gmx_selelem_requires_top(t_selelem
*root
)
589 if (root
->type
== SEL_EXPRESSION
|| root
->type
== SEL_MODIFIER
)
591 if (root
->u
.expr
.method
&& (root
->u
.expr
.method
->flags
& SMETH_REQTOP
))
595 if (root
->u
.expr
.pc
&& gmx_ana_poscalc_requires_top(root
->u
.expr
.pc
))
603 if (_gmx_selelem_requires_top(child
))