Removed obsolete selection code.
[gromacs/qmmm-gamess-us.git] / src / gmxlib / selection / selelem.c
blobd886f5613b41eb465ba793448523b7e4e9056c14
1 /*
3 * This source code is part of
5 * G R O M A C S
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
31 /*! \internal \file
32 * \brief Implementation of functions in selelem.h.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #include <smalloc.h>
39 #include <gmx_fatal.h>
41 #include <indexutil.h>
42 #include <poscalc.h>
43 #include <position.h>
44 #include <selmethod.h>
46 #include "evaluate.h"
47 #include "keywords.h"
48 #include "mempool.h"
49 #include "selelem.h"
51 /*!
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.
59 const char *
60 _gmx_selelem_type_str(t_selelem *sel)
62 switch (sel->type)
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";
73 return NULL;
76 /*!
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.
83 const char *
84 _gmx_sel_value_type_str(gmx_ana_selvalue_t *val)
86 switch (val->type)
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";
95 return NULL;
98 /*! \copydoc _gmx_selelem_type_str() */
99 const char *
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;
109 return NULL;
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.
124 t_selelem *
125 _gmx_selelem_create(e_selelem_t type)
127 t_selelem *sel;
129 snew(sel, 1);
130 sel->name = NULL;
131 sel->type = 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;
138 else
140 sel->v.type = NO_VALUE;
142 _gmx_selvalue_clear(&sel->v);
143 sel->evaluate = NULL;
144 sel->mempool = NULL;
145 sel->child = NULL;
146 sel->next = NULL;
147 sel->refcount = 1;
149 return sel;
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");
169 return EINVAL;
171 if (sel->v.type != NO_VALUE && vtype != sel->v.type)
173 gmx_call("_gmx_selelem_set_vtype() called more than once");
174 return EINVAL;
176 sel->v.type = vtype;
177 if (vtype == GROUP_VALUE || vtype == POS_VALUE)
179 sel->flags |= SEL_ALLOCDATA;
181 return 0;
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)
195 int rc = 0;
197 if (!sel->mempool)
199 return 0;
201 switch (sel->v.type)
203 case INT_VALUE:
204 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.i,
205 sizeof(*sel->v.u.i)*count);
206 break;
208 case REAL_VALUE:
209 rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.r,
210 sizeof(*sel->v.u.r)*count);
211 break;
213 case GROUP_VALUE:
214 rc = _gmx_sel_mempool_alloc_group(sel->mempool, sel->v.u.g, count);
215 break;
217 default:
218 gmx_incons("mem pooling not implemented for requested type");
219 return -1;
221 return rc;
225 * \param[in,out] sel Selection element to release.
227 * Releases the memory allocated for the values of \p sel from the
228 * \p sel->mempool memory pool. If no memory pool is set, nothing is done.
230 void
231 _gmx_selelem_mempool_release(t_selelem *sel)
233 if (!sel->mempool)
235 return;
237 switch (sel->v.type)
239 case INT_VALUE:
240 case REAL_VALUE:
241 _gmx_sel_mempool_free(sel->mempool, sel->v.u.ptr);
242 break;
244 case GROUP_VALUE:
245 if (sel->v.u.g)
247 _gmx_sel_mempool_free_group(sel->mempool, sel->v.u.g);
249 break;
251 default:
252 gmx_incons("mem pooling not implemented for requested type");
253 break;
258 * \param[in] sel Selection to free.
260 void
261 _gmx_selelem_free_values(t_selelem *sel)
263 int i, n;
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
271 * size here. */
272 n = (sel->v.nalloc > 0) ? sel->v.nalloc : sel->v.nr;
273 switch (sel->v.type)
275 case STR_VALUE:
276 if (sel->v.nalloc == 0)
278 gmx_bug("SEL_ALLOCDATA should only be set for allocated STR_VALUE values");
279 break;
281 for (i = 0; i < n; ++i)
283 sfree(sel->v.u.s[i]);
285 break;
286 case POS_VALUE:
287 for (i = 0; i < n; ++i)
289 gmx_ana_pos_deinit(&sel->v.u.p[i]);
291 break;
292 case GROUP_VALUE:
293 for (i = 0; i < n; ++i)
295 gmx_ana_index_deinit(&sel->v.u.g[i]);
297 break;
298 default: /* No special handling for other types */
299 break;
302 if (sel->flags & SEL_ALLOCVAL)
304 sfree(sel->v.u.ptr);
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.
317 void
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
331 * access them. */
332 if (method)
334 int i, j;
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(&param->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(&param->val.u.p[j]);
359 if (param->val.nalloc > 0)
361 sfree(param->val.u.ptr);
365 sfree(method->param);
366 sfree(method);
368 /* Free method data. */
369 if (mdata)
371 if (free_func)
373 free_func(mdata);
375 sfree(mdata);
380 * \param[in] sel Selection to free.
382 void
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 */
391 if (sel->u.expr.pos)
393 gmx_ana_pos_free(sel->u.expr.pos);
394 sel->u.expr.pos = NULL;
396 /* Free position calculation data */
397 if (sel->u.expr.pc)
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
420 * reaches zero.
422 void
423 _gmx_selelem_free(t_selelem *sel)
425 /* Decrement the reference counter and do nothing if references remain */
426 sel->refcount--;
427 if (sel->refcount > 0)
429 return;
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);
446 sfree(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.
455 void
456 _gmx_selelem_free_chain(t_selelem *first)
458 t_selelem *child, *prev;
460 child = first;
461 while (child)
463 prev = child;
464 child = child->next;
465 _gmx_selelem_free(prev);
469 /*! \brief
470 * Writes out a human-readable name for the evaluation function.
472 * \param[in] fp File handle to receive the output.
473 * \param[in] sel Selection element for which the evaluation function is printed.
475 static void
476 print_evaluation_func(FILE *fp, t_selelem *sel)
478 fprintf(fp, " eval=");
479 if (!sel->evaluate)
480 fprintf(fp, "none");
481 else if (sel->evaluate == &_gmx_sel_evaluate_root)
482 fprintf(fp, "root");
483 else if (sel->evaluate == &_gmx_sel_evaluate_static)
484 fprintf(fp, "static");
485 else if (sel->evaluate == &_gmx_sel_evaluate_subexpr_simple)
486 fprintf(fp, "subexpr_simple");
487 else if (sel->evaluate == &_gmx_sel_evaluate_subexpr_staticeval)
488 fprintf(fp, "subexpr_staticeval");
489 else if (sel->evaluate == &_gmx_sel_evaluate_subexpr)
490 fprintf(fp, "subexpr");
491 else if (sel->evaluate == &_gmx_sel_evaluate_subexprref_simple)
492 fprintf(fp, "ref_simple");
493 else if (sel->evaluate == &_gmx_sel_evaluate_subexprref)
494 fprintf(fp, "ref");
495 else if (sel->evaluate == &_gmx_sel_evaluate_method)
496 fprintf(fp, "method");
497 else if (sel->evaluate == &_gmx_sel_evaluate_modifier)
498 fprintf(fp, "mod");
499 else if (sel->evaluate == &_gmx_sel_evaluate_not)
500 fprintf(fp, "not");
501 else if (sel->evaluate == &_gmx_sel_evaluate_and)
502 fprintf(fp, "and");
503 else if (sel->evaluate == &_gmx_sel_evaluate_or)
504 fprintf(fp, "or");
505 else if (sel->evaluate == &_gmx_sel_evaluate_arithmetic)
506 fprintf(fp, "arithmetic");
507 else
508 fprintf(fp, "%p", (void*)(sel->evaluate));
512 * \param[in] fp File handle to receive the output.
513 * \param[in] sel Root of the selection subtree to print.
514 * \param[in] bValues If TRUE, the evaluated values of selection elements
515 * are printed as well.
516 * \param[in] level Indentation level, starting from zero.
518 void
519 _gmx_selelem_print_tree(FILE *fp, t_selelem *sel, bool bValues, int level)
521 t_selelem *child;
522 int i;
524 fprintf(fp, "%*c %s %s", level*2+1, '*',
525 _gmx_selelem_type_str(sel), _gmx_sel_value_type_str(&sel->v));
526 if (sel->name)
528 fprintf(fp, " \"%s\"", sel->name);
530 fprintf(fp, " flg=");
531 if (sel->flags & SEL_FLAGSSET)
533 fprintf(fp, "s");
535 if (sel->flags & SEL_SINGLEVAL)
537 fprintf(fp, "S");
539 if (sel->flags & SEL_ATOMVAL)
541 fprintf(fp, "A");
543 if (sel->flags & SEL_VARNUMVAL)
545 fprintf(fp, "V");
547 if (sel->flags & SEL_DYNAMIC)
549 fprintf(fp, "D");
551 if (!(sel->flags & SEL_VALFLAGMASK))
553 fprintf(fp, "0");
555 if (sel->mempool)
557 fprintf(fp, "P");
559 if (sel->type == SEL_CONST)
561 if (sel->v.type == INT_VALUE)
563 fprintf(fp, " %d", sel->v.u.i[0]);
565 else if (sel->v.type == REAL_VALUE)
567 fprintf(fp, " %f", sel->v.u.r[0]);
569 else if (sel->v.type == GROUP_VALUE)
571 gmx_ana_index_t *g = sel->v.u.g;
572 if (!g || g->isize == 0)
573 g = &sel->u.cgrp;
574 fprintf(fp, " (%d atoms)", g->isize);
577 else if (sel->type == SEL_BOOLEAN)
579 fprintf(fp, " %s", _gmx_selelem_boolean_type_str(sel));
581 else if (sel->type == SEL_EXPRESSION
582 && sel->u.expr.method->name == sm_compare.name)
584 _gmx_selelem_print_compare_info(fp, sel->u.expr.mdata);
586 if (sel->evaluate)
588 print_evaluation_func(fp, sel);
590 if (sel->refcount > 1)
592 fprintf(fp, " refc=%d", sel->refcount);
594 if (!(sel->flags & SEL_ALLOCVAL))
596 fprintf(fp, " (ext. output)");
598 fprintf(fp, "\n");
600 if ((sel->type == SEL_CONST && sel->v.type == GROUP_VALUE) || sel->type == SEL_ROOT)
602 gmx_ana_index_t *g = sel->v.u.g;
603 if (!g || g->isize == 0 || sel->evaluate != NULL)
605 g = &sel->u.cgrp;
607 if (g->isize > 0)
609 fprintf(fp, "%*c group:", level*2+1, ' ');
610 if (g->isize <= 20)
612 for (i = 0; i < g->isize; ++i)
614 fprintf(fp, " %d", g->index[i] + 1);
617 else
619 fprintf(fp, " %d atoms", g->isize);
621 fprintf(fp, "\n");
624 else if (sel->type == SEL_EXPRESSION)
626 if (sel->u.expr.pc)
628 fprintf(fp, "%*c COM", level*2+3, '*');
629 fprintf(fp, "\n");
633 if (bValues && sel->type != SEL_CONST && sel->type != SEL_ROOT && sel->v.u.ptr)
635 fprintf(fp, "%*c value: ", level*2+1, ' ');
636 switch (sel->v.type)
638 case POS_VALUE:
639 /* In normal use, the pointer should never be NULL, but it's
640 * useful to have the check for debugging to avoid accidental
641 * segfaults when printing the selection tree. */
642 if (sel->v.u.p->x)
644 fprintf(fp, "(%f, %f, %f)",
645 sel->v.u.p->x[0][XX], sel->v.u.p->x[0][YY],
646 sel->v.u.p->x[0][ZZ]);
648 else
650 fprintf(fp, "(null)");
652 break;
653 case GROUP_VALUE:
654 fprintf(fp, "%d atoms", sel->v.u.g->isize);
655 if (sel->v.u.g->isize < 20)
657 if (sel->v.u.g->isize > 0)
659 fprintf(fp, ":");
661 for (i = 0; i < sel->v.u.g->isize; ++i)
663 fprintf(fp, " %d", sel->v.u.g->index[i] + 1);
666 break;
667 default:
668 fprintf(fp, "???");
669 break;
671 fprintf(fp, "\n");
674 /* Print the subexpressions with one more level of indentation */
675 child = sel->child;
676 while (child)
678 if (!(sel->type == SEL_SUBEXPRREF && child->type == SEL_SUBEXPR))
680 _gmx_selelem_print_tree(fp, child, bValues, level+1);
682 child = child->next;
687 * \param[in] root Root of the subtree to query.
688 * \returns TRUE if \p root or any any of its elements require topology
689 * information, FALSE otherwise.
691 bool
692 _gmx_selelem_requires_top(t_selelem *root)
694 t_selelem *child;
696 if (root->type == SEL_EXPRESSION || root->type == SEL_MODIFIER)
698 if (root->u.expr.method && (root->u.expr.method->flags & SMETH_REQTOP))
700 return TRUE;
702 if (root->u.expr.pc && gmx_ana_poscalc_requires_top(root->u.expr.pc))
704 return TRUE;
707 child = root->child;
708 while (child)
710 if (_gmx_selelem_requires_top(child))
712 return TRUE;
714 child = child->next;
716 return FALSE;