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>
51 * \param[in] sel Selection for which the string is requested
52 * \returns Pointer to a string that corresponds to \p sel->type.
54 * The return value points to a string constant and should not be \p free'd.
56 * The function returns NULL if \p sel->type is not one of the valid values.
59 _gmx_selelem_type_str(t_selelem *sel)
63 case SEL_CONST: return "CONST";
64 case SEL_EXPRESSION: return "EXPR";
65 case SEL_BOOLEAN: return "BOOL";
66 case SEL_ARITHMETIC: return "ARITH";
67 case SEL_ROOT: return "ROOT";
68 case SEL_SUBEXPR: return "SUBEXPR";
69 case SEL_SUBEXPRREF: return "REF";
70 case SEL_MODIFIER: return "MODIFIER";
76 * \param[in] val Value structore for which the string is requested.
77 * \returns Pointer to a string that corresponds to \p val->type,
78 * NULL if the type value is invalid.
80 * The return value points to a string constant and should not be \p free'd.
83 _gmx_sel_value_type_str(gmx_ana_selvalue_t *val)
87 case NO_VALUE: return "NONE";
88 case INT_VALUE: return "INT";
89 case REAL_VALUE: return "REAL";
90 case STR_VALUE: return "STR";
91 case POS_VALUE: return "VEC";
92 case GROUP_VALUE: return "GROUP";
97 /*! \copydoc _gmx_selelem_type_str() */
99 _gmx_selelem_gmx_boolean_type_str(t_selelem *sel)
101 switch (sel->u.boolt)
103 case BOOL_NOT: return "NOT"; break;
104 case BOOL_AND: return "AND"; break;
105 case BOOL_OR: return "OR"; break;
106 case BOOL_XOR: return "XOR"; break;
112 * \param[in] type Type of selection element to allocate.
113 * \returns Pointer to the newly allocated and initialized element.
115 * \c t_selelem::type is set to \p type,
116 * \c t_selelem::v::type is set to \ref GROUP_VALUE for gmx_boolean and comparison
117 * expressions and \ref NO_VALUE for others,
118 * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA is also
119 * set for \ref SEL_BOOLEAN elements),
120 * and \c t_selelem::refcount is set to one.
121 * All the pointers are set to NULL.
124 _gmx_selelem_create(e_selelem_t type)
131 sel->flags = (type != SEL_ROOT) ? SEL_ALLOCVAL : 0;
132 if (type == SEL_BOOLEAN)
134 sel->v.type = GROUP_VALUE;
135 sel->flags |= SEL_ALLOCDATA;
139 sel->v.type = NO_VALUE;
141 _gmx_selvalue_clear(&sel->v);
142 sel->evaluate = NULL;
152 * \param[in,out] sel Selection element to set the type for.
153 * \param[in] vtype Value type for the selection element.
154 * \returns 0 on success, EINVAL if the value type is invalid.
156 * If the new type is \ref GROUP_VALUE or \ref POS_VALUE, the
157 * \ref SEL_ALLOCDATA flag is also set.
159 * This function should only be called at most once for each element,
160 * preferably right after calling _gmx_selelem_create().
163 _gmx_selelem_set_vtype(t_selelem *sel, e_selvalue_t vtype)
165 if (sel->type == SEL_BOOLEAN && vtype != GROUP_VALUE)
167 gmx_bug("internal error");
170 if (sel->v.type != NO_VALUE && vtype != sel->v.type)
172 gmx_call("_gmx_selelem_set_vtype() called more than once");
176 if (vtype == GROUP_VALUE || vtype == POS_VALUE)
178 sel->flags |= SEL_ALLOCDATA;
184 * \param[in,out] sel Selection element to reserve.
185 * \param[in] count Number of values to reserve memory for.
186 * \returns 0 on success or if no memory pool, non-zero on error.
188 * Reserves memory for the values of \p sel from the \p sel->mempool
189 * memory pool. If no memory pool is set, nothing is done.
192 _gmx_selelem_mempool_reserve(t_selelem *sel, int count)
203 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.i,
204 sizeof(*sel->v.u.i)*count);
208 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.r,
209 sizeof(*sel->v.u.r)*count);
213 rc = _gmx_sel_mempool_alloc_group(sel->mempool, sel->v.u.g, count);
217 gmx_incons("mem pooling not implemented for requested type");
224 * \param[in,out] sel Selection element to release.
226 * Releases the memory allocated for the values of \p sel from the
227 * \p sel->mempool memory pool. If no memory pool is set, nothing is done.
230 _gmx_selelem_mempool_release(t_selelem *sel)
240 _gmx_sel_mempool_free(sel->mempool, sel->v.u.ptr);
241 _gmx_selvalue_setstore(&sel->v, NULL);
247 _gmx_sel_mempool_free_group(sel->mempool, sel->v.u.g);
252 gmx_incons("mem pooling not implemented for requested type");
258 * \param[in] sel Selection to free.
261 _gmx_selelem_free_values(t_selelem *sel)
265 _gmx_selelem_mempool_release(sel);
266 if ((sel->flags & SEL_ALLOCDATA) && sel->v.u.ptr)
268 /* The number of position/group structures is constant, so the
269 * backup of using sel->v.nr should work for them.
270 * For strings, we report an error if we don't know the allocation
272 n = (sel->v.nalloc > 0) ? sel->v.nalloc : sel->v.nr;
276 if (sel->v.nalloc == 0)
278 gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values");
281 for (i = 0; i < n; ++i)
283 sfree(sel->v.u.s[i]);
287 for (i = 0; i < n; ++i)
289 gmx_ana_pos_deinit(&sel->v.u.p[i]);
293 for (i = 0; i < n; ++i)
295 gmx_ana_index_deinit(&sel->v.u.g[i]);
298 default: /* No special handling for other types */
302 if (sel->flags & SEL_ALLOCVAL)
306 _gmx_selvalue_setstore(&sel->v, NULL);
307 if (sel->type == SEL_SUBEXPRREF && sel->u.param)
309 sel->u.param->val.u.ptr = NULL;
314 * \param[in] method Method to free.
315 * \param[in] mdata Method data to free.
318 _gmx_selelem_free_method(gmx_ana_selmethod_t *method, void *mdata)
320 sel_freefunc free_func = NULL;
322 /* Save the pointer to the free function. */
323 if (method && method->free)
325 free_func = method->free;
328 /* Free the method itself.
329 * Has to be done before freeing the method data, because parameter
330 * values are typically stored in the method data, and here we may
336 /* Free the memory allocated for the parameters that are not managed
337 * by the selection method itself. */
338 for (i = 0; i < method->nparams; ++i)
340 gmx_ana_selparam_t *param = &method->param[i];
342 if (param->val.u.ptr)
344 if (param->val.type == GROUP_VALUE)
346 for (j = 0; j < param->val.nr; ++j)
348 gmx_ana_index_deinit(¶m->val.u.g[j]);
351 else if (param->val.type == POS_VALUE)
353 for (j = 0; j < param->val.nr; ++j)
355 gmx_ana_pos_deinit(¶m->val.u.p[j]);
359 if (param->val.nalloc > 0)
361 sfree(param->val.u.ptr);
365 sfree(method->param);
368 /* Free method data. */
380 * \param[in] sel Selection to free.
383 _gmx_selelem_free_exprdata(t_selelem *sel)
385 if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER)
387 _gmx_selelem_free_method(sel->u.expr.method, sel->u.expr.mdata);
388 sel->u.expr.mdata = NULL;
389 sel->u.expr.method = NULL;
390 /* Free position data */
393 gmx_ana_pos_free(sel->u.expr.pos);
394 sel->u.expr.pos = NULL;
396 /* Free position calculation data */
399 gmx_ana_poscalc_free(sel->u.expr.pc);
400 sel->u.expr.pc = NULL;
403 if (sel->type == SEL_ARITHMETIC)
405 sfree(sel->u.arith.opstr);
406 sel->u.arith.opstr = NULL;
408 if (sel->type == SEL_SUBEXPR || sel->type == SEL_ROOT
409 || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE))
411 gmx_ana_index_deinit(&sel->u.cgrp);
416 * \param[in] sel Selection to free.
418 * Decrements \ref t_selelem::refcount "sel->refcount" and frees the
419 * memory allocated for \p sel and all its children if the reference count
423 _gmx_selelem_free(t_selelem *sel)
425 /* Decrement the reference counter and do nothing if references remain */
427 if (sel->refcount > 0)
432 /* Free the children.
433 * Must be done before freeing other data, because the children may hold
434 * references to data in this element. */
435 _gmx_selelem_free_chain(sel->child);
437 /* Free value storage */
438 _gmx_selelem_free_values(sel);
440 /* Free other storage */
441 _gmx_selelem_free_exprdata(sel);
443 /* Free temporary compiler data if present */
444 _gmx_selelem_free_compiler_data(sel);
450 * \param[in] first First selection to free.
452 * Frees \p first and all selections accessible through the
453 * \ref t_selelem::next "first->next" pointer.
456 _gmx_selelem_free_chain(t_selelem *first)
458 t_selelem *child, *prev;
465 _gmx_selelem_free(prev);
470 * \param[in] fp File handle to receive the output.
471 * \param[in] sel Root of the selection subtree to print.
472 * \param[in] bValues If TRUE, the evaluated values of selection elements
473 * are printed as well.
474 * \param[in] level Indentation level, starting from zero.
477 _gmx_selelem_print_tree(FILE *fp, t_selelem *sel, gmx_bool bValues, int level)
482 fprintf(fp, "%*c %s %s", level*2+1, '*',
483 _gmx_selelem_type_str(sel), _gmx_sel_value_type_str(&sel->v));
486 fprintf(fp, " \"%s\"", sel->name);
488 fprintf(fp, " flg=");
489 if (sel->flags & SEL_FLAGSSET)
493 if (sel->flags & SEL_SINGLEVAL)
497 if (sel->flags & SEL_ATOMVAL)
501 if (sel->flags & SEL_VARNUMVAL)
505 if (sel->flags & SEL_DYNAMIC)
509 if (!(sel->flags & SEL_VALFLAGMASK))
517 if (sel->type == SEL_CONST)
519 if (sel->v.type == INT_VALUE)
521 fprintf(fp, " %d", sel->v.u.i[0]);
523 else if (sel->v.type == REAL_VALUE)
525 fprintf(fp, " %f", sel->v.u.r[0]);
527 else if (sel->v.type == GROUP_VALUE)
529 gmx_ana_index_t *g = sel->v.u.g;
530 if (!g || g->isize == 0)
532 fprintf(fp, " (%d atoms)", g->isize);
535 else if (sel->type == SEL_BOOLEAN)
537 fprintf(fp, " %s", _gmx_selelem_gmx_boolean_type_str(sel));
539 else if (sel->type == SEL_EXPRESSION
540 && sel->u.expr.method->name == sm_compare.name)
542 _gmx_selelem_print_compare_info(fp, sel->u.expr.mdata);
546 fprintf(fp, " eval=");
547 _gmx_sel_print_evalfunc_name(fp, sel->evaluate);
549 if (sel->refcount > 1)
551 fprintf(fp, " refc=%d", sel->refcount);
553 if (!(sel->flags & SEL_ALLOCVAL))
555 fprintf(fp, " (ext. output)");
559 if ((sel->type == SEL_CONST && sel->v.type == GROUP_VALUE) || sel->type == SEL_ROOT)
561 gmx_ana_index_t *g = sel->v.u.g;
562 if (!g || g->isize == 0 || sel->evaluate != NULL)
568 fprintf(fp, "%*c group: (null)\n", level*2+1, ' ');
570 else if (g->isize > 0)
572 fprintf(fp, "%*c group:", level*2+1, ' ');
575 for (i = 0; i < g->isize; ++i)
577 fprintf(fp, " %d", g->index[i] + 1);
582 fprintf(fp, " %d atoms", g->isize);
587 else if (sel->type == SEL_EXPRESSION)
591 fprintf(fp, "%*c COM", level*2+3, '*');
598 _gmx_selelem_print_compiler_info(fp, sel, level);
601 if (bValues && sel->type != SEL_CONST && sel->type != SEL_ROOT && sel->v.u.ptr)
603 fprintf(fp, "%*c value: ", level*2+1, ' ');
607 /* In normal use, the pointer should never be NULL, but it's
608 * useful to have the check for debugging to avoid accidental
609 * segfaults when printing the selection tree. */
612 fprintf(fp, "(%f, %f, %f)",
613 sel->v.u.p->x[0][XX], sel->v.u.p->x[0][YY],
614 sel->v.u.p->x[0][ZZ]);
618 fprintf(fp, "(null)");
622 fprintf(fp, "%d atoms", sel->v.u.g->isize);
623 if (sel->v.u.g->isize < 20)
625 if (sel->v.u.g->isize > 0)
629 for (i = 0; i < sel->v.u.g->isize; ++i)
631 fprintf(fp, " %d", sel->v.u.g->index[i] + 1);
642 /* Print the subexpressions with one more level of indentation */
646 if (!(sel->type == SEL_SUBEXPRREF && child->type == SEL_SUBEXPR))
648 _gmx_selelem_print_tree(fp, child, bValues, level+1);
655 * \param[in] root Root of the subtree to query.
656 * \returns TRUE if \p root or any any of its elements require topology
657 * information, FALSE otherwise.
660 _gmx_selelem_requires_top(t_selelem *root)
664 if (root->type == SEL_EXPRESSION || root->type == SEL_MODIFIER)
666 if (root->u.expr.method && (root->u.expr.method->flags & SMETH_REQTOP))
670 if (root->u.expr.pc && gmx_ana_poscalc_requires_top(root->u.expr.pc))
678 if (_gmx_selelem_requires_top(child))