2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2009, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
39 * \brief Implementation of functions in selelem.h.
46 #include <gmx_fatal.h>
48 #include <indexutil.h>
51 #include <selmethod.h>
58 * \param[in] sel Selection for which the string is requested
59 * \returns Pointer to a string that corresponds to \p sel->type.
61 * The return value points to a string constant and should not be \p free'd.
63 * The function returns NULL if \p sel->type is not one of the valid values.
66 _gmx_selelem_type_str(t_selelem *sel)
70 case SEL_CONST: return "CONST";
71 case SEL_EXPRESSION: return "EXPR";
72 case SEL_BOOLEAN: return "BOOL";
73 case SEL_ARITHMETIC: return "ARITH";
74 case SEL_ROOT: return "ROOT";
75 case SEL_SUBEXPR: return "SUBEXPR";
76 case SEL_SUBEXPRREF: return "REF";
77 case SEL_MODIFIER: return "MODIFIER";
83 * \param[in] val Value structore for which the string is requested.
84 * \returns Pointer to a string that corresponds to \p val->type,
85 * NULL if the type value is invalid.
87 * The return value points to a string constant and should not be \p free'd.
90 _gmx_sel_value_type_str(gmx_ana_selvalue_t *val)
94 case NO_VALUE: return "NONE";
95 case INT_VALUE: return "INT";
96 case REAL_VALUE: return "REAL";
97 case STR_VALUE: return "STR";
98 case POS_VALUE: return "VEC";
99 case GROUP_VALUE: return "GROUP";
104 /*! \copydoc _gmx_selelem_type_str() */
106 _gmx_selelem_gmx_boolean_type_str(t_selelem *sel)
108 switch (sel->u.boolt)
110 case BOOL_NOT: return "NOT"; break;
111 case BOOL_AND: return "AND"; break;
112 case BOOL_OR: return "OR"; break;
113 case BOOL_XOR: return "XOR"; break;
119 * \param[in] type Type of selection element to allocate.
120 * \returns Pointer to the newly allocated and initialized element.
122 * \c t_selelem::type is set to \p type,
123 * \c t_selelem::v::type is set to \ref GROUP_VALUE for gmx_boolean and comparison
124 * expressions and \ref NO_VALUE for others,
125 * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA is also
126 * set for \ref SEL_BOOLEAN elements),
127 * and \c t_selelem::refcount is set to one.
128 * All the pointers are set to NULL.
131 _gmx_selelem_create(e_selelem_t type)
138 sel->flags = (type != SEL_ROOT) ? SEL_ALLOCVAL : 0;
139 if (type == SEL_BOOLEAN)
141 sel->v.type = GROUP_VALUE;
142 sel->flags |= SEL_ALLOCDATA;
146 sel->v.type = NO_VALUE;
148 _gmx_selvalue_clear(&sel->v);
149 sel->evaluate = NULL;
159 * \param[in,out] sel Selection element to set the type for.
160 * \param[in] vtype Value type for the selection element.
161 * \returns 0 on success, EINVAL if the value type is invalid.
163 * If the new type is \ref GROUP_VALUE or \ref POS_VALUE, the
164 * \ref SEL_ALLOCDATA flag is also set.
166 * This function should only be called at most once for each element,
167 * preferably right after calling _gmx_selelem_create().
170 _gmx_selelem_set_vtype(t_selelem *sel, e_selvalue_t vtype)
172 if (sel->type == SEL_BOOLEAN && vtype != GROUP_VALUE)
174 gmx_bug("internal error");
177 if (sel->v.type != NO_VALUE && vtype != sel->v.type)
179 gmx_call("_gmx_selelem_set_vtype() called more than once");
183 if (vtype == GROUP_VALUE || vtype == POS_VALUE)
185 sel->flags |= SEL_ALLOCDATA;
191 * \param[in,out] sel Selection element to reserve.
192 * \param[in] count Number of values to reserve memory for.
193 * \returns 0 on success or if no memory pool, non-zero on error.
195 * Reserves memory for the values of \p sel from the \p sel->mempool
196 * memory pool. If no memory pool is set, nothing is done.
199 _gmx_selelem_mempool_reserve(t_selelem *sel, int count)
210 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.i,
211 sizeof(*sel->v.u.i)*count);
215 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.r,
216 sizeof(*sel->v.u.r)*count);
220 rc = _gmx_sel_mempool_alloc_group(sel->mempool, sel->v.u.g, count);
224 gmx_incons("mem pooling not implemented for requested type");
231 * \param[in,out] sel Selection element to release.
233 * Releases the memory allocated for the values of \p sel from the
234 * \p sel->mempool memory pool. If no memory pool is set, nothing is done.
237 _gmx_selelem_mempool_release(t_selelem *sel)
247 _gmx_sel_mempool_free(sel->mempool, sel->v.u.ptr);
248 _gmx_selvalue_setstore(&sel->v, NULL);
254 _gmx_sel_mempool_free_group(sel->mempool, sel->v.u.g);
259 gmx_incons("mem pooling not implemented for requested type");
265 * \param[in] sel Selection to free.
268 _gmx_selelem_free_values(t_selelem *sel)
272 _gmx_selelem_mempool_release(sel);
273 if ((sel->flags & SEL_ALLOCDATA) && sel->v.u.ptr)
275 /* The number of position/group structures is constant, so the
276 * backup of using sel->v.nr should work for them.
277 * For strings, we report an error if we don't know the allocation
279 n = (sel->v.nalloc > 0) ? sel->v.nalloc : sel->v.nr;
283 if (sel->v.nalloc == 0)
285 gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values");
288 for (i = 0; i < n; ++i)
290 sfree(sel->v.u.s[i]);
294 for (i = 0; i < n; ++i)
296 gmx_ana_pos_deinit(&sel->v.u.p[i]);
300 for (i = 0; i < n; ++i)
302 gmx_ana_index_deinit(&sel->v.u.g[i]);
305 default: /* No special handling for other types */
309 if (sel->flags & SEL_ALLOCVAL)
313 _gmx_selvalue_setstore(&sel->v, NULL);
314 if (sel->type == SEL_SUBEXPRREF && sel->u.param)
316 sel->u.param->val.u.ptr = NULL;
321 * \param[in] method Method to free.
322 * \param[in] mdata Method data to free.
325 _gmx_selelem_free_method(gmx_ana_selmethod_t *method, void *mdata)
327 sel_freefunc free_func = NULL;
329 /* Save the pointer to the free function. */
330 if (method && method->free)
332 free_func = method->free;
335 /* Free the method itself.
336 * Has to be done before freeing the method data, because parameter
337 * values are typically stored in the method data, and here we may
343 /* Free the memory allocated for the parameters that are not managed
344 * by the selection method itself. */
345 for (i = 0; i < method->nparams; ++i)
347 gmx_ana_selparam_t *param = &method->param[i];
349 if (param->val.u.ptr)
351 if (param->val.type == GROUP_VALUE)
353 for (j = 0; j < param->val.nr; ++j)
355 gmx_ana_index_deinit(¶m->val.u.g[j]);
358 else if (param->val.type == POS_VALUE)
360 for (j = 0; j < param->val.nr; ++j)
362 gmx_ana_pos_deinit(¶m->val.u.p[j]);
366 if (param->val.nalloc > 0)
368 sfree(param->val.u.ptr);
372 sfree(method->param);
375 /* Free method data. */
387 * \param[in] sel Selection to free.
390 _gmx_selelem_free_exprdata(t_selelem *sel)
392 if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER)
394 _gmx_selelem_free_method(sel->u.expr.method, sel->u.expr.mdata);
395 sel->u.expr.mdata = NULL;
396 sel->u.expr.method = NULL;
397 /* Free position data */
400 gmx_ana_pos_free(sel->u.expr.pos);
401 sel->u.expr.pos = NULL;
403 /* Free position calculation data */
406 gmx_ana_poscalc_free(sel->u.expr.pc);
407 sel->u.expr.pc = NULL;
410 if (sel->type == SEL_ARITHMETIC)
412 sfree(sel->u.arith.opstr);
413 sel->u.arith.opstr = NULL;
415 if (sel->type == SEL_SUBEXPR || sel->type == SEL_ROOT
416 || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE))
418 gmx_ana_index_deinit(&sel->u.cgrp);
423 * \param[in] sel Selection to free.
425 * Decrements \ref t_selelem::refcount "sel->refcount" and frees the
426 * memory allocated for \p sel and all its children if the reference count
430 _gmx_selelem_free(t_selelem *sel)
432 /* Decrement the reference counter and do nothing if references remain */
434 if (sel->refcount > 0)
439 /* Free the children.
440 * Must be done before freeing other data, because the children may hold
441 * references to data in this element. */
442 _gmx_selelem_free_chain(sel->child);
444 /* Free value storage */
445 _gmx_selelem_free_values(sel);
447 /* Free other storage */
448 _gmx_selelem_free_exprdata(sel);
450 /* Free temporary compiler data if present */
451 _gmx_selelem_free_compiler_data(sel);
457 * \param[in] first First selection to free.
459 * Frees \p first and all selections accessible through the
460 * \ref t_selelem::next "first->next" pointer.
463 _gmx_selelem_free_chain(t_selelem *first)
465 t_selelem *child, *prev;
472 _gmx_selelem_free(prev);
477 * \param[in] fp File handle to receive the output.
478 * \param[in] sel Root of the selection subtree to print.
479 * \param[in] bValues If TRUE, the evaluated values of selection elements
480 * are printed as well.
481 * \param[in] level Indentation level, starting from zero.
484 _gmx_selelem_print_tree(FILE *fp, t_selelem *sel, gmx_bool bValues, int level)
489 fprintf(fp, "%*c %s %s", level*2+1, '*',
490 _gmx_selelem_type_str(sel), _gmx_sel_value_type_str(&sel->v));
493 fprintf(fp, " \"%s\"", sel->name);
495 fprintf(fp, " flg=");
496 if (sel->flags & SEL_FLAGSSET)
500 if (sel->flags & SEL_SINGLEVAL)
504 if (sel->flags & SEL_ATOMVAL)
508 if (sel->flags & SEL_VARNUMVAL)
512 if (sel->flags & SEL_DYNAMIC)
516 if (!(sel->flags & SEL_VALFLAGMASK))
524 if (sel->type == SEL_CONST)
526 if (sel->v.type == INT_VALUE)
528 fprintf(fp, " %d", sel->v.u.i[0]);
530 else if (sel->v.type == REAL_VALUE)
532 fprintf(fp, " %f", sel->v.u.r[0]);
534 else if (sel->v.type == GROUP_VALUE)
536 gmx_ana_index_t *g = sel->v.u.g;
537 if (!g || g->isize == 0)
539 fprintf(fp, " (%d atoms)", g->isize);
542 else if (sel->type == SEL_BOOLEAN)
544 fprintf(fp, " %s", _gmx_selelem_gmx_boolean_type_str(sel));
546 else if (sel->type == SEL_EXPRESSION
547 && sel->u.expr.method->name == sm_compare.name)
549 _gmx_selelem_print_compare_info(fp, sel->u.expr.mdata);
553 fprintf(fp, " eval=");
554 _gmx_sel_print_evalfunc_name(fp, sel->evaluate);
556 if (sel->refcount > 1)
558 fprintf(fp, " refc=%d", sel->refcount);
560 if (!(sel->flags & SEL_ALLOCVAL))
562 fprintf(fp, " (ext. output)");
566 if ((sel->type == SEL_CONST && sel->v.type == GROUP_VALUE) || sel->type == SEL_ROOT)
568 gmx_ana_index_t *g = sel->v.u.g;
569 if (!g || g->isize == 0 || sel->evaluate != NULL)
575 fprintf(fp, "%*c group: (null)\n", level*2+1, ' ');
577 else if (g->isize > 0)
579 fprintf(fp, "%*c group:", level*2+1, ' ');
582 for (i = 0; i < g->isize; ++i)
584 fprintf(fp, " %d", g->index[i] + 1);
589 fprintf(fp, " %d atoms", g->isize);
594 else if (sel->type == SEL_EXPRESSION)
598 fprintf(fp, "%*c COM", level*2+3, '*');
605 _gmx_selelem_print_compiler_info(fp, sel, level);
608 if (bValues && sel->type != SEL_CONST && sel->type != SEL_ROOT && sel->v.u.ptr)
610 fprintf(fp, "%*c value: ", level*2+1, ' ');
614 /* In normal use, the pointer should never be NULL, but it's
615 * useful to have the check for debugging to avoid accidental
616 * segfaults when printing the selection tree. */
619 fprintf(fp, "(%f, %f, %f)",
620 sel->v.u.p->x[0][XX], sel->v.u.p->x[0][YY],
621 sel->v.u.p->x[0][ZZ]);
625 fprintf(fp, "(null)");
629 fprintf(fp, "%d atoms", sel->v.u.g->isize);
630 if (sel->v.u.g->isize < 20)
632 if (sel->v.u.g->isize > 0)
636 for (i = 0; i < sel->v.u.g->isize; ++i)
638 fprintf(fp, " %d", sel->v.u.g->index[i] + 1);
649 /* Print the subexpressions with one more level of indentation */
653 if (!(sel->type == SEL_SUBEXPRREF && child->type == SEL_SUBEXPR))
655 _gmx_selelem_print_tree(fp, child, bValues, level+1);
662 * \param[in] root Root of the subtree to query.
663 * \returns TRUE if \p root or any any of its elements require topology
664 * information, FALSE otherwise.
667 _gmx_selelem_requires_top(t_selelem *root)
671 if (root->type == SEL_EXPRESSION || root->type == SEL_MODIFIER)
673 if (root->u.expr.method && (root->u.expr.method->flags & SMETH_REQTOP))
677 if (root->u.expr.pc && gmx_ana_poscalc_requires_top(root->u.expr.pc))
685 if (_gmx_selelem_requires_top(child))