Merge "Merge release-4-6 into master"
[alexxy/gromacs.git] / src / gromacs / selection / evaluate.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
5  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6  * others, as listed in the AUTHORS file in the top-level source
7  * directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \internal \file
36  * \brief
37  * Implements functions in evaluate.h.
38  *
39  * \todo
40  * One of the major bottlenecks for selection performance is that all the
41  * evaluation is carried out for atoms.
42  * There are several cases when the evaluation could be done for residues
43  * or molecules instead, including keywords that select by residue and
44  * cases where residue centers are used as reference positions.
45  * Implementing this would require a mechanism for recognizing whether
46  * something can be evaluated by residue/molecule instead by atom, and
47  * converting selections by residue/molecule into selections by atom
48  * when necessary.
49  *
50  * \author Teemu Murtola <teemu.murtola@gmail.com>
51  * \ingroup module_selection
52  */
53 #include <string.h>
54
55 #include "gromacs/legacyheaders/maths.h"
56 #include "gromacs/legacyheaders/smalloc.h"
57 #include "gromacs/legacyheaders/vec.h"
58
59 #include "gromacs/selection/indexutil.h"
60 #include "gromacs/selection/poscalc.h"
61 #include "gromacs/selection/selection.h"
62 #include "gromacs/selection/selmethod.h"
63 #include "gromacs/utility/exceptions.h"
64 #include "gromacs/utility/gmxassert.h"
65
66 #include "evaluate.h"
67 #include "mempool.h"
68 #include "selectioncollection-impl.h"
69 #include "selelem.h"
70
71 using gmx::SelectionTreeElement;
72 using gmx::SelectionTreeElementPointer;
73
74 namespace
75 {
76
77 /*! \internal \brief
78  * Reserves memory for a selection element from the evaluation memory pool.
79  *
80  * This class implements RAII semantics for allocating memory for selection
81  * element values from a selection evaluation memory pool.
82  *
83  * \ingroup module_selection
84  */
85 class MempoolSelelemReserver
86 {
87     public:
88         //! Constructs a reserver without initial reservation.
89         MempoolSelelemReserver() {}
90         /*! \brief
91          * Constructs a reserver with initial reservation.
92          *
93          * \param[in,out] sel    Selection element for which to reserve.
94          * \param[in]     count  Number of values to reserve.
95          *
96          * \see reserve()
97          */
98         MempoolSelelemReserver(const SelectionTreeElementPointer &sel, int count)
99         {
100             reserve(sel, count);
101         }
102         //! Frees any memory allocated using this reserver.
103         ~MempoolSelelemReserver()
104         {
105             if (sel_)
106             {
107                 sel_->mempoolRelease();
108             }
109         }
110
111         /*! \brief
112          * Reserves memory for selection element values using this reserver.
113          *
114          * \param[in,out] sel    Selection element for which to reserve.
115          * \param[in]     count  Number of values to reserve.
116          *
117          * Allocates space to store \p count output values in \p sel from the
118          * memory pool associated with \p sel, or from the heap if there is no
119          * memory pool.  Type of values to allocate is automatically determined
120          * from \p sel.
121          */
122         void reserve(const SelectionTreeElementPointer &sel, int count)
123         {
124             GMX_RELEASE_ASSERT(!sel_,
125                                "Can only reserve one element with one instance");
126             sel->mempoolReserve(count);
127             sel_ = sel;
128         }
129
130     private:
131         SelectionTreeElementPointer     sel_;
132 };
133
134 /*! \internal \brief
135  * Reserves memory for an index group from the evaluation memory pool.
136  *
137  * This class implements RAII semantics for allocating memory for an index
138  * group from a selection evaluation memory pool.
139  *
140  * \ingroup module_selection
141  */
142 class MempoolGroupReserver
143 {
144     public:
145         /*! \brief
146          * Creates a reserver associated with a given memory pool.
147          *
148          * \param    mp  Memory pool from which to reserve memory.
149          */
150         explicit MempoolGroupReserver(gmx_sel_mempool_t *mp)
151             : mp_(mp), g_(NULL)
152         {
153         }
154         //! Frees any memory allocated using this reserver.
155         ~MempoolGroupReserver()
156         {
157             if (g_ != NULL)
158             {
159                 _gmx_sel_mempool_free_group(mp_, g_);
160             }
161         }
162
163         /*! \brief
164          * Reserves memory for an index group using this reserver.
165          *
166          * \param[in,out] g      Index group to reserve.
167          * \param[in]     count  Number of atoms to reserve space for.
168          *
169          * Allocates memory from the memory pool to store \p count atoms in
170          * \p g.
171          */
172         void reserve(gmx_ana_index_t *g, int count)
173         {
174             GMX_RELEASE_ASSERT(g_ == NULL, "Can only reserve one element with one instance");
175             _gmx_sel_mempool_alloc_group(mp_, g, count);
176             g_ = g;
177         }
178
179     private:
180         gmx_sel_mempool_t      *mp_;
181         gmx_ana_index_t        *g_;
182 };
183
184 /*! \internal \brief
185  * Assigns a temporary value for a selection element.
186  *
187  * This class implements RAII semantics for temporarily assigning the value
188  * pointer of a selection element to point to a different location.
189  *
190  * \ingroup module_selection
191  */
192 class SelelemTemporaryValueAssigner
193 {
194     public:
195         //! Constructs an assigner without an initial assignment.
196         SelelemTemporaryValueAssigner()
197             : old_ptr_(NULL), old_nalloc_(0)
198         {
199         }
200         /*! \brief
201          * Constructs an assigner with an initial assignment.
202          *
203          * \param[in,out] sel     Selection element for which to assign.
204          * \param[in]     vsource Element to which \p sel values will point to.
205          *
206          * \see assign()
207          */
208         SelelemTemporaryValueAssigner(const SelectionTreeElementPointer &sel,
209                                       const SelectionTreeElement        &vsource)
210         {
211             assign(sel, vsource);
212         }
213         //! Undoes any temporary assignment done using this assigner.
214         ~SelelemTemporaryValueAssigner()
215         {
216             if (sel_)
217             {
218                 _gmx_selvalue_setstore_alloc(&sel_->v, old_ptr_, old_nalloc_);
219             }
220         }
221
222         /*! \brief
223          * Assigns a temporary value pointer.
224          *
225          * \param[in,out] sel     Selection element for which to assign.
226          * \param[in]     vsource Element to which \p sel values will point to.
227          *
228          * Assigns the value pointer in \p sel to point to the values in
229          * \p vsource, i.e., any access/modification to values in \p sel
230          * actually accesses values in \p vsource.
231          */
232         void assign(const SelectionTreeElementPointer &sel,
233                     const SelectionTreeElement        &vsource)
234         {
235             GMX_RELEASE_ASSERT(!sel_,
236                                "Can only assign one element with one instance");
237             GMX_RELEASE_ASSERT(sel->v.type == vsource.v.type,
238                                "Mismatching selection value types");
239             old_ptr_    = sel->v.u.ptr;
240             old_nalloc_ = sel->v.nalloc;
241             _gmx_selvalue_setstore(&sel->v, vsource.v.u.ptr);
242             sel_ = sel;
243         }
244
245     private:
246         SelectionTreeElementPointer     sel_;
247         void                           *old_ptr_;
248         int                             old_nalloc_;
249 };
250
251 } // namespace
252
253 /*!
254  * \param[in] fp       File handle to receive the output.
255  * \param[in] evalfunc Function pointer to print.
256  */
257 void
258 _gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc)
259 {
260     if (!evalfunc)
261     {
262         fprintf(fp, "none");
263     }
264     else if (evalfunc == &_gmx_sel_evaluate_root)
265     {
266         fprintf(fp, "root");
267     }
268     else if (evalfunc == &_gmx_sel_evaluate_static)
269     {
270         fprintf(fp, "static");
271     }
272     else if (evalfunc == &_gmx_sel_evaluate_subexpr_simple)
273     {
274         fprintf(fp, "subexpr_simple");
275     }
276     else if (evalfunc == &_gmx_sel_evaluate_subexpr_staticeval)
277     {
278         fprintf(fp, "subexpr_staticeval");
279     }
280     else if (evalfunc == &_gmx_sel_evaluate_subexpr)
281     {
282         fprintf(fp, "subexpr");
283     }
284     else if (evalfunc == &_gmx_sel_evaluate_subexprref_simple)
285     {
286         fprintf(fp, "ref_simple");
287     }
288     else if (evalfunc == &_gmx_sel_evaluate_subexprref)
289     {
290         fprintf(fp, "ref");
291     }
292     else if (evalfunc == &_gmx_sel_evaluate_method)
293     {
294         fprintf(fp, "method");
295     }
296     else if (evalfunc == &_gmx_sel_evaluate_modifier)
297     {
298         fprintf(fp, "mod");
299     }
300     else if (evalfunc == &_gmx_sel_evaluate_not)
301     {
302         fprintf(fp, "not");
303     }
304     else if (evalfunc == &_gmx_sel_evaluate_and)
305     {
306         fprintf(fp, "and");
307     }
308     else if (evalfunc == &_gmx_sel_evaluate_or)
309     {
310         fprintf(fp, "or");
311     }
312     else if (evalfunc == &_gmx_sel_evaluate_arithmetic)
313     {
314         fprintf(fp, "arithmetic");
315     }
316     else
317     {
318         fprintf(fp, "%p", (void*)(evalfunc));
319     }
320 }
321
322 /*!
323  * \param[out] data Evaluation data structure to initialize.
324  * \param[in]  mp   Memory pool for intermediate evaluation values.
325  * \param[in]  gall Index group with all the atoms.
326  * \param[in]  top  Topology structure for evaluation.
327  * \param[in]  fr   New frame for evaluation.
328  * \param[in]  pbc  New PBC information for evaluation.
329  */
330 void
331 _gmx_sel_evaluate_init(gmx_sel_evaluate_t *data,
332                        gmx_sel_mempool_t *mp, gmx_ana_index_t *gall,
333                        t_topology *top, t_trxframe *fr, t_pbc *pbc)
334 {
335     data->mp   = mp;
336     data->gall = gall;
337     data->top  = top;
338     data->fr   = fr;
339     data->pbc  = pbc;
340 }
341
342 /*! \brief
343  * Recursively initializes the flags for evaluation.
344  *
345  * \param[in,out] sel Selection element to clear.
346  *
347  * The \ref SEL_INITFRAME flag is set for \ref SEL_EXPRESSION elements whose
348  * method defines the \p init_frame callback (see sel_framefunc()), and
349  * cleared for other elements.
350  *
351  * The \ref SEL_EVALFRAME flag is cleared for all elements.
352  */
353 static void
354 init_frame_eval(SelectionTreeElementPointer sel)
355 {
356     while (sel)
357     {
358         sel->flags &= ~(SEL_INITFRAME | SEL_EVALFRAME);
359         if (sel->type == SEL_EXPRESSION)
360         {
361             if (sel->u.expr.method && sel->u.expr.method->init_frame)
362             {
363                 sel->flags |= SEL_INITFRAME;
364             }
365         }
366         if (sel->child && sel->type != SEL_SUBEXPRREF)
367         {
368             init_frame_eval(sel->child);
369         }
370         sel = sel->next;
371     }
372 }
373
374 namespace gmx
375 {
376
377 SelectionEvaluator::SelectionEvaluator()
378 {
379 }
380
381 /*!
382  * \param[in,out] coll  The selection collection to evaluate.
383  * \param[in] fr  Frame for which the evaluation should be carried out.
384  * \param[in] pbc PBC data, or NULL if no PBC should be used.
385  * \returns   0 on successful evaluation, a non-zero error code on error.
386  *
387  * This functions sets the global variables for topology, frame and PBC,
388  * clears some information in the selection to initialize the evaluation
389  * for a new frame, and evaluates \p sel and all the selections pointed by
390  * the \p next pointers of \p sel.
391  *
392  * This is the only function that user code should call if they want to
393  * evaluate a selection for a new frame.
394  */
395 void
396 SelectionEvaluator::evaluate(SelectionCollection *coll,
397                              t_trxframe *fr, t_pbc *pbc)
398 {
399     gmx_ana_selcollection_t *sc = &coll->impl_->sc_;
400     gmx_sel_evaluate_t       data;
401
402     _gmx_sel_evaluate_init(&data, sc->mempool, &sc->gall, sc->top, fr, pbc);
403     init_frame_eval(sc->root);
404     SelectionTreeElementPointer sel = sc->root;
405     while (sel)
406     {
407         /* Clear the evaluation group of subexpressions */
408         if (sel->child && sel->child->type == SEL_SUBEXPR)
409         {
410             sel->child->u.cgrp.isize = 0;
411             /* Not strictly necessary, because the value will be overwritten
412              * during first evaluation of the subexpression anyways, but we
413              * clear the group for clarity. Note that this is _not_ done during
414              * compilation because of some additional complexities involved
415              * (see compiler.c), so it should not be relied upon in
416              * _gmx_sel_evaluate_subexpr(). */
417             if (sel->child->v.type == GROUP_VALUE)
418             {
419                 sel->child->v.u.g->isize = 0;
420             }
421         }
422         if (sel->evaluate)
423         {
424             sel->evaluate(&data, sel, NULL);
425         }
426         sel = sel->next;
427     }
428     /* Update selection information */
429     SelectionDataList::const_iterator isel;
430     for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
431     {
432         internal::SelectionData &sel = **isel;
433         sel.refreshMassesAndCharges(sc->top);
434         sel.updateCoveredFractionForFrame();
435     }
436 }
437
438 /*!
439  * \param[in,out] coll  The selection collection to evaluate.
440  * \param[in]     nframes Total number of frames.
441  */
442 void
443 SelectionEvaluator::evaluateFinal(SelectionCollection *coll, int nframes)
444 {
445     gmx_ana_selcollection_t          *sc = &coll->impl_->sc_;
446
447     SelectionDataList::const_iterator isel;
448     for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
449     {
450         internal::SelectionData &sel = **isel;
451         sel.restoreOriginalPositions(sc->top);
452         sel.computeAverageCoveredFraction(nframes);
453     }
454 }
455
456 } // namespace gmx
457
458 /*!
459  * \param[in] data Data for the current frame.
460  * \param[in] sel  Selection element being evaluated.
461  * \param[in] g    Group for which \p sel should be evaluated.
462  * \returns   0 on success, a non-zero error code on error.
463  *
464  * Evaluates each child of \p sel in \p g.
465  */
466 void
467 _gmx_sel_evaluate_children(gmx_sel_evaluate_t                *data,
468                            const SelectionTreeElementPointer &sel,
469                            gmx_ana_index_t                   *g)
470 {
471     SelectionTreeElementPointer child = sel->child;
472     while (child)
473     {
474         if (child->evaluate)
475         {
476             child->evaluate(data, child, g);
477         }
478         child = child->next;
479     }
480 }
481
482 /*!
483  * \param[in] data Data for the current frame.
484  * \param[in] sel Selection element being evaluated.
485  * \param[in] g   Group for which \p sel should be evaluated
486  *   (not used, can be NULL).
487  * \returns   0 on success, a non-zero error code on error.
488  *
489  * Evaluates the first child element in the group defined by \p sel->u.cgrp.
490  * If \p sel->u.cgrp is empty, nothing is done.
491  * The value of \p sel is not touched (root elements do not evaluate to
492  * values).
493  *
494  * This function can be used as gmx::SelectionTreeElement::evaluate for
495  * \ref SEL_ROOT elements.
496  */
497 void
498 _gmx_sel_evaluate_root(gmx_sel_evaluate_t                *data,
499                        const SelectionTreeElementPointer &sel,
500                        gmx_ana_index_t                   *g)
501 {
502     if (sel->u.cgrp.isize == 0 || !sel->child->evaluate)
503     {
504         return;
505     }
506
507     sel->child->evaluate(data, sel->child,
508                          sel->u.cgrp.isize < 0 ? NULL : &sel->u.cgrp);
509 }
510
511 /*!
512  * \param[in] data Data for the current frame.
513  * \param[in] sel Selection element being evaluated.
514  * \param[in] g   Group for which \p sel should be evaluated.
515  * \returns   0 for success.
516  *
517  * Sets the value of \p sel to the intersection of \p g and \p sel->u.cgrp.
518  *
519  * This function can be used as gmx::SelectionTreeElement::evaluate for
520  * \ref SEL_CONST elements with value type \ref GROUP_VALUE.
521  */
522 void
523 _gmx_sel_evaluate_static(gmx_sel_evaluate_t                *data,
524                          const SelectionTreeElementPointer &sel,
525                          gmx_ana_index_t                   *g)
526 {
527     gmx_ana_index_intersection(sel->v.u.g, &sel->u.cgrp, g);
528 }
529
530
531 /*********************************************************************
532  * SUBEXPRESSION EVALUATION
533  *********************************************************************/
534
535 /*!
536  * \param[in] data Data for the current frame.
537  * \param[in] sel  Selection element being evaluated.
538  * \param[in] g    Group for which \p sel should be evaluated.
539  * \returns   0 on success, a non-zero error code on error.
540  *
541  * Evaluates the child element (there should be exactly one) in \p g.
542  * The compiler has taken care that the child actually stores the evaluated
543  * value in the value pointer of this element.
544  *
545  * This function is used as gmx::SelectionTreeElement::evaluate for
546  * \ref SEL_SUBEXPR elements that are used only once, and hence do not need
547  * full subexpression handling.
548  */
549 void
550 _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t                *data,
551                                  const SelectionTreeElementPointer &sel,
552                                  gmx_ana_index_t                   *g)
553 {
554     if (sel->child->evaluate)
555     {
556         sel->child->evaluate(data, sel->child, g);
557     }
558     sel->v.nr = sel->child->v.nr;
559 }
560
561 /*!
562  * \param[in] data Data for the current frame.
563  * \param[in] sel  Selection element being evaluated.
564  * \param[in] g    Group for which \p sel should be evaluated.
565  * \returns   0 on success, a non-zero error code on error.
566  *
567  * If this is the first call for this frame, evaluates the child element
568  * there should be exactly one in \p g.
569  * The compiler has taken care that the child actually stores the evaluated
570  * value in the value pointer of this element.
571  * Assumes that \p g is persistent for the duration of the whole evaluation.
572  *
573  * This function is used as gmx::SelectionTreeElement::evaluate for
574  * \ref SEL_SUBEXPR elements that have a static evaluation group, and hence do
575  * not need full subexpression handling.
576  */
577 void
578 _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t                *data,
579                                      const SelectionTreeElementPointer &sel,
580                                      gmx_ana_index_t                   *g)
581 {
582     if (sel->u.cgrp.isize == 0)
583     {
584         sel->child->evaluate(data, sel->child, g);
585         sel->v.nr = sel->child->v.nr;
586         if (!g)
587         {
588             sel->u.cgrp.isize = -1;
589         }
590         else
591         {
592             gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, sel->u.cgrp.name, 0);
593         }
594     }
595 }
596
597 /*!
598  * \param[in]  data  Data for the current frame.
599  * \param[in]  sel   Selection element being evaluated.
600  * \param[in]  g     Group for which \p sel should be evaluated.
601  * \returns    0 on success, a non-zero error code on error.
602  *
603  * Finds the part of \p g for which the subexpression
604  * has not yet been evaluated by comparing \p g to \p sel->u.cgrp.
605  * If the part is not empty, the child expression is evaluated for this
606  * part, and the results merged to the old values of the child.
607  * The value of \p sel itself is undefined after the call.
608  *
609  * \todo
610  * The call to gmx_ana_index_difference() can take quite a lot of unnecessary
611  * time if the subexpression is evaluated either several times for the same
612  * group or for completely distinct groups.
613  * However, in the majority of cases, these situations occur when
614  * _gmx_sel_evaluate_subexpr_staticeval() can be used, so this should not be a
615  * major problem.
616  */
617 void
618 _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t                *data,
619                           const SelectionTreeElementPointer &sel,
620                           gmx_ana_index_t                   *g)
621 {
622     gmx_ana_index_t      gmiss;
623
624     MempoolGroupReserver gmissreserver(data->mp);
625     if (sel->u.cgrp.isize == 0)
626     {
627         {
628             SelelemTemporaryValueAssigner assigner(sel->child, *sel);
629             sel->child->evaluate(data, sel->child, g);
630         }
631         /* We need to keep the name for the cgrp across the copy to avoid
632          * problems if g has a name set. */
633         char *name = sel->u.cgrp.name;
634         gmx_ana_index_copy(&sel->u.cgrp, g, false);
635         sel->u.cgrp.name = name;
636         gmiss.isize      = 0;
637     }
638     else
639     {
640         gmissreserver.reserve(&gmiss, g->isize);
641         gmx_ana_index_difference(&gmiss, g, &sel->u.cgrp);
642         gmiss.name = NULL;
643     }
644     if (gmiss.isize > 0)
645     {
646         MempoolSelelemReserver reserver(sel->child, gmiss.isize);
647         /* Evaluate the missing values for the child */
648         sel->child->evaluate(data, sel->child, &gmiss);
649         /* Merge the missing values to the existing ones. */
650         if (sel->v.type == GROUP_VALUE)
651         {
652             gmx_ana_index_merge(sel->v.u.g, sel->child->v.u.g, sel->v.u.g);
653         }
654         else
655         {
656             int  i, j, k;
657
658             i = sel->u.cgrp.isize - 1;
659             j = gmiss.isize - 1;
660             /* TODO: This switch is kind of ugly, but it may be difficult to
661              * do this portably without C++ templates. */
662             switch (sel->v.type)
663             {
664                 case INT_VALUE:
665                     for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
666                     {
667                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
668                         {
669                             sel->v.u.i[k] = sel->child->v.u.i[j--];
670                         }
671                         else
672                         {
673                             sel->v.u.i[k] = sel->v.u.i[i--];
674                         }
675                     }
676                     break;
677
678                 case REAL_VALUE:
679                     for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
680                     {
681                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
682                         {
683                             sel->v.u.r[k] = sel->child->v.u.r[j--];
684                         }
685                         else
686                         {
687                             sel->v.u.r[k] = sel->v.u.r[i--];
688                         }
689                     }
690                     break;
691
692                 case STR_VALUE:
693                     // Note: with the currently allowed syntax, this case is never
694                     // reached.
695                     for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
696                     {
697                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
698                         {
699                             sel->v.u.s[k] = sel->child->v.u.s[j--];
700                         }
701                         else
702                         {
703                             sel->v.u.s[k] = sel->v.u.s[i--];
704                         }
705                     }
706                     break;
707
708                 case POS_VALUE:
709                     /* TODO: Implement this */
710                     GMX_THROW(gmx::NotImplementedError("position subexpressions not implemented properly"));
711
712                 case NO_VALUE:
713                 case GROUP_VALUE:
714                     GMX_THROW(gmx::InternalError("Invalid subexpression type"));
715             }
716         }
717         gmx_ana_index_merge(&sel->u.cgrp, &sel->u.cgrp, &gmiss);
718     }
719 }
720
721 /*!
722  * \param[in] data Data for the current frame.
723  * \param[in] sel Selection element being evaluated.
724  * \param[in] g   Group for which \p sel should be evaluated.
725  * \returns   0 for success.
726  *
727  * Sets the value pointers of the child and its child to point to the same
728  * memory as the value pointer of this element to avoid copying, and then
729  * evaluates evaluates the child.
730  *
731  * This function is used as gmx::SelectionTreeElement:evaluate for
732  * \ref SEL_SUBEXPRREF elements for which the \ref SEL_SUBEXPR does not have
733  * other references.
734  */
735 void
736 _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t                *data,
737                                     const SelectionTreeElementPointer &sel,
738                                     gmx_ana_index_t                   *g)
739 {
740     if (g)
741     {
742         _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr);
743         _gmx_selvalue_setstore_alloc(&sel->child->child->v, sel->v.u.ptr,
744                                      sel->child->child->v.nalloc);
745         sel->child->evaluate(data, sel->child, g);
746     }
747     sel->v.nr = sel->child->v.nr;
748     if (sel->u.param)
749     {
750         sel->u.param->val.nr = sel->v.nr;
751         if (sel->u.param->nvalptr)
752         {
753             *sel->u.param->nvalptr = sel->u.param->val.nr;
754         }
755     }
756 }
757
758 /*!
759  * \param[in] data Data for the current frame.
760  * \param[in] sel Selection element being evaluated.
761  * \param[in] g   Group for which \p sel should be evaluated.
762  * \returns   0 on success, a non-zero error code on error.
763  *
764  * If the value type is \ref POS_VALUE, the value of the child is simply
765  * copied to set the value of \p sel (the child subexpression should
766  * already have been evaluated by its root).
767  * If the value type is something else, the child is evaluated for the
768  * group \p g, and the value of the child is then copied.
769  * There should be only one child element.
770  *
771  * This function is used as gmx::SelectionTreeElement::evaluate for
772  * \ref SEL_SUBEXPRREF elements.
773  */
774 void
775 _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t                *data,
776                              const SelectionTreeElementPointer &sel,
777                              gmx_ana_index_t                   *g)
778 {
779     int        i, j;
780
781     if (g)
782     {
783         sel->child->evaluate(data, sel->child, g);
784     }
785     const SelectionTreeElementPointer &expr = sel->child;
786     switch (sel->v.type)
787     {
788         case INT_VALUE:
789             if (!g)
790             {
791                 sel->v.nr = expr->v.nr;
792                 memcpy(sel->v.u.i, expr->v.u.i, sel->v.nr*sizeof(*sel->v.u.i));
793             }
794             else
795             {
796                 sel->v.nr = g->isize;
797                 /* Extract the values corresponding to g */
798                 for (i = j = 0; i < g->isize; ++i, ++j)
799                 {
800                     while (sel->child->u.cgrp.index[j] < g->index[i])
801                     {
802                         ++j;
803                     }
804                     sel->v.u.i[i] = expr->v.u.i[j];
805                 }
806             }
807             break;
808
809         case REAL_VALUE:
810             if (!g)
811             {
812                 sel->v.nr = expr->v.nr;
813                 memcpy(sel->v.u.r, expr->v.u.r, sel->v.nr*sizeof(*sel->v.u.r));
814             }
815             else
816             {
817                 sel->v.nr = g->isize;
818                 /* Extract the values corresponding to g */
819                 for (i = j = 0; i < g->isize; ++i, ++j)
820                 {
821                     while (sel->child->u.cgrp.index[j] < g->index[i])
822                     {
823                         ++j;
824                     }
825                     sel->v.u.r[i] = expr->v.u.r[j];
826                 }
827             }
828             break;
829
830         case STR_VALUE:
831             if (!g)
832             {
833                 sel->v.nr = expr->v.nr;
834                 memcpy(sel->v.u.s, expr->v.u.s, sel->v.nr*sizeof(*sel->v.u.s));
835             }
836             else
837             {
838                 sel->v.nr = g->isize;
839                 /* Extract the values corresponding to g */
840                 for (i = j = 0; i < g->isize; ++i, ++j)
841                 {
842                     while (sel->child->u.cgrp.index[j] < g->index[i])
843                     {
844                         ++j;
845                     }
846                     sel->v.u.s[i] = expr->v.u.s[j];
847                 }
848             }
849             break;
850
851         case POS_VALUE:
852             /* Currently, there is no need to do anything fancy here,
853              * but some future extensions may need a more flexible
854              * implementation. */
855             gmx_ana_pos_copy(sel->v.u.p, expr->v.u.p, false);
856             break;
857
858         case GROUP_VALUE:
859             if (!g)
860             {
861                 gmx_ana_index_copy(sel->v.u.g, expr->v.u.g, false);
862             }
863             else
864             {
865                 gmx_ana_index_intersection(sel->v.u.g, expr->v.u.g, g);
866             }
867             break;
868
869         default: /* should not be reached */
870             GMX_THROW(gmx::InternalError("Invalid subexpression reference type"));
871     }
872     /* Store the number of values if needed */
873     if (sel->u.param)
874     {
875         sel->u.param->val.nr = sel->v.nr;
876         if (sel->u.param->nvalptr)
877         {
878             *sel->u.param->nvalptr = sel->u.param->val.nr;
879         }
880     }
881 }
882
883 /********************************************************************
884  * METHOD EXPRESSION EVALUATION
885  ********************************************************************/
886
887 /*!
888  * \param[in] data Data for the current frame.
889  * \param[in] sel Selection element being evaluated.
890  * \param[in] g   Group for which \p sel should be evaluated.
891  * \returns   0 on success, a non-zero error code on error.
892  *
893  * Evaluates each child of a \ref SEL_EXPRESSION element.
894  * The value of \p sel is not touched.
895  *
896  * This function is not used as gmx::SelectionTreeElement::evaluate,
897  * but is used internally.
898  */
899 void
900 _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t                *data,
901                                 const SelectionTreeElementPointer &sel,
902                                 gmx_ana_index_t                   *g)
903 {
904     SelectionTreeElementPointer child = sel->child;
905     while (child)
906     {
907         if (child->evaluate && !(child->flags & SEL_EVALFRAME))
908         {
909             if (child->flags & SEL_ATOMVAL)
910             {
911                 child->evaluate(data, child, g);
912             }
913             else
914             {
915                 child->flags |= SEL_EVALFRAME;
916                 child->evaluate(data, child, NULL);
917             }
918         }
919         child = child->next;
920     }
921 }
922
923 /*!
924  * \param[in] data Data for the current frame.
925  * \param[in] sel Selection element being evaluated.
926  * \param[in] g   Group for which \p sel should be evaluated.
927  * \returns   0 on success, a non-zero error code on error.
928  *
929  * Evaluates all child selections (using _gmx_sel_evaluate_method_params())
930  * to evaluate any parameter values.
931  * If this is the first time this expression is evaluated for
932  * the frame, sel_framefunc() callback is called if one is provided.
933  * If a reference position calculation has been initialized for this element,
934  * the positions are also updated, and sel_updatefunc_pos() is used to
935  * evaluate the value. Otherwise, sel_updatefunc() is used.
936  *
937  * This function is used as gmx::SelectionTreeElement::evaluate for
938  * \ref SEL_EXPRESSION elements.
939  */
940 void
941 _gmx_sel_evaluate_method(gmx_sel_evaluate_t                *data,
942                          const SelectionTreeElementPointer &sel,
943                          gmx_ana_index_t                   *g)
944 {
945     _gmx_sel_evaluate_method_params(data, sel, g);
946     if (sel->flags & SEL_INITFRAME)
947     {
948         sel->flags &= ~SEL_INITFRAME;
949         sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
950                                        sel->u.expr.mdata);
951     }
952     if (sel->u.expr.pc)
953     {
954         gmx_ana_poscalc_update(sel->u.expr.pc, sel->u.expr.pos, g,
955                                data->fr, data->pbc);
956         sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
957                                     sel->u.expr.pos, &sel->v,
958                                     sel->u.expr.mdata);
959     }
960     else
961     {
962         sel->u.expr.method->update(data->top, data->fr, data->pbc, g,
963                                    &sel->v, sel->u.expr.mdata);
964     }
965 }
966
967 /*!
968  * \param[in] data Data for the current frame.
969  * \param[in] sel Selection element being evaluated.
970  * \param[in] g   Group for which \p sel should be evaluated.
971  * \returns   0 on success, a non-zero error code on error.
972  *
973  * Evaluates all child selections (using _gmx_sel_evaluate_method_params())
974  * to evaluate any parameter values.
975  * If this is the first time this expression is evaluated for
976  * the frame, sel_framefunc() callback is called if one is provided.
977  * The modifier is then evaluated using sel_updatefunc_pos().
978  *
979  * This function is used as gmx::SelectionTreeElement::evaluate for
980  * \ref SEL_MODIFIER elements.
981  */
982 void
983 _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t                *data,
984                            const SelectionTreeElementPointer &sel,
985                            gmx_ana_index_t                   *g)
986 {
987     _gmx_sel_evaluate_method_params(data, sel, g);
988     if (sel->flags & SEL_INITFRAME)
989     {
990         sel->flags &= ~SEL_INITFRAME;
991         sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
992                                        sel->u.expr.mdata);
993     }
994     GMX_RELEASE_ASSERT(sel->child != NULL,
995                        "Modifier element with a value must have a child");
996     if (sel->child->v.type != POS_VALUE)
997     {
998         GMX_THROW(gmx::NotImplementedError("Non-position valued modifiers not implemented"));
999     }
1000     sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
1001                                 sel->child->v.u.p,
1002                                 &sel->v, sel->u.expr.mdata);
1003 }
1004
1005
1006 /********************************************************************
1007  * BOOLEAN EXPRESSION EVALUATION
1008  ********************************************************************/
1009
1010 /*!
1011  * \param[in] data Data for the current frame.
1012  * \param[in] sel Selection element being evaluated.
1013  * \param[in] g   Group for which \p sel should be evaluated.
1014  * \returns   0 on success, a non-zero error code on error.
1015  *
1016  * Evaluates the child element (there should be only one) in the group
1017  * \p g, and then sets the value of \p sel to the complement of the
1018  * child value.
1019  *
1020  * This function is used as gmx::SelectionTreeElement::evaluate for
1021  * \ref SEL_BOOLEAN elements with \ref BOOL_NOT.
1022  */
1023 void
1024 _gmx_sel_evaluate_not(gmx_sel_evaluate_t                *data,
1025                       const SelectionTreeElementPointer &sel,
1026                       gmx_ana_index_t                   *g)
1027 {
1028     MempoolSelelemReserver reserver(sel->child, g->isize);
1029     sel->child->evaluate(data, sel->child, g);
1030     gmx_ana_index_difference(sel->v.u.g, g, sel->child->v.u.g);
1031 }
1032
1033 /*!
1034  * \param[in] data Data for the current frame.
1035  * \param[in] sel Selection element being evaluated.
1036  * \param[in] g   Group for which \p sel should be evaluated.
1037  * \returns   0 on success, a non-zero error code on error.
1038  *
1039  * Short-circuiting evaluation of logical AND expressions.
1040  *
1041  * Starts by evaluating the first child element in the group \p g.
1042  * The each following child element is evaluated in the intersection
1043  * of all the previous values until all children have been evaluated
1044  * or the intersection becomes empty.
1045  * The value of \p sel is set to the intersection of all the (evaluated)
1046  * child values.
1047  *
1048  * If the first child does not have an evaluation function, it is skipped
1049  * and the evaluation is started at the second child.
1050  * This happens if the first child is a constant expression and during
1051  * compilation it was detected that the evaluation group is always a subset
1052  * of the constant group
1053  * (currently, the compiler never detects this).
1054  *
1055  * This function is used as gmx::SelectionTreeElement::evaluate for
1056  * \ref SEL_BOOLEAN elements with \ref BOOL_AND.
1057  */
1058 void
1059 _gmx_sel_evaluate_and(gmx_sel_evaluate_t                *data,
1060                       const SelectionTreeElementPointer &sel,
1061                       gmx_ana_index_t                   *g)
1062 {
1063     SelectionTreeElementPointer child = sel->child;
1064     /* Skip the first child if it does not have an evaluation function. */
1065     if (!child->evaluate)
1066     {
1067         child = child->next;
1068     }
1069     /* Evaluate the first child */
1070     {
1071         MempoolSelelemReserver reserver(child, g->isize);
1072         child->evaluate(data, child, g);
1073         gmx_ana_index_copy(sel->v.u.g, child->v.u.g, false);
1074     }
1075     child = child->next;
1076     while (child && sel->v.u.g->isize > 0)
1077     {
1078         MempoolSelelemReserver reserver(child, sel->v.u.g->isize);
1079         child->evaluate(data, child, sel->v.u.g);
1080         gmx_ana_index_intersection(sel->v.u.g, sel->v.u.g, child->v.u.g);
1081         child = child->next;
1082     }
1083 }
1084
1085 /*!
1086  * \param[in] data Data for the current frame.
1087  * \param[in] sel Selection element being evaluated.
1088  * \param[in] g   Group for which \p sel should be evaluated.
1089  * \returns   0 on success, a non-zero error code on error.
1090  *
1091  * Short-circuiting evaluation of logical OR expressions.
1092  *
1093  * Starts by evaluating the first child element in the group \p g.
1094  * For each subsequent child, finds the part of \p g that is not
1095  * included the value of any previous child, and evaluates the child
1096  * in that group until the last child is evaluated or all of \p g
1097  * is included in some child value.
1098  * The value of \p sel is set to the union of all the (evaluated)
1099  * child values.
1100  *
1101  * If the first child does not have an evaluation function, its value is
1102  * used without evaluation.
1103  * This happens if the first child is a constant expression, the selection
1104  * has been compiled, and the evaluation group is the same for each frame.
1105  * In this case, the compiler has taken care of that the child value is a
1106  * subset of \p g, making it unnecessary to evaluate it.
1107  *
1108  * This function is used as gmx::SelectionTreeElement::evaluate for
1109  * \ref SEL_BOOLEAN elements with \ref BOOL_OR.
1110  */
1111 void
1112 _gmx_sel_evaluate_or(gmx_sel_evaluate_t                *data,
1113                      const SelectionTreeElementPointer &sel,
1114                      gmx_ana_index_t                   *g)
1115 {
1116     gmx_ana_index_t             tmp, tmp2;
1117
1118     SelectionTreeElementPointer child = sel->child;
1119     if (child->evaluate)
1120     {
1121         MempoolSelelemReserver reserver(child, g->isize);
1122         child->evaluate(data, child, g);
1123         gmx_ana_index_partition(sel->v.u.g, &tmp, g, child->v.u.g);
1124     }
1125     else
1126     {
1127         gmx_ana_index_partition(sel->v.u.g, &tmp, g, child->v.u.g);
1128     }
1129     child = child->next;
1130     while (child && tmp.isize > 0)
1131     {
1132         tmp.name = NULL;
1133         {
1134             MempoolSelelemReserver reserver(child, tmp.isize);
1135             child->evaluate(data, child, &tmp);
1136             gmx_ana_index_partition(&tmp, &tmp2, &tmp, child->v.u.g);
1137         }
1138         sel->v.u.g->isize += tmp.isize;
1139         tmp.isize          = tmp2.isize;
1140         tmp.index          = tmp2.index;
1141         child              = child->next;
1142     }
1143     gmx_ana_index_sort(sel->v.u.g);
1144 }
1145
1146
1147 /********************************************************************
1148  * ARITHMETIC EVALUATION
1149  ********************************************************************/
1150
1151 /*!
1152  * \param[in] data Data for the current frame.
1153  * \param[in] sel  Selection element being evaluated.
1154  * \param[in] g    Group for which \p sel should be evaluated.
1155  * \returns   0 on success, a non-zero error code on error.
1156  */
1157 void
1158 _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t                *data,
1159                              const SelectionTreeElementPointer &sel,
1160                              gmx_ana_index_t                   *g)
1161 {
1162     int         n, i, i1, i2;
1163     real        lval, rval = 0., val = 0.;
1164
1165     const SelectionTreeElementPointer &left  = sel->child;
1166     const SelectionTreeElementPointer &right = left->next;
1167
1168     SelelemTemporaryValueAssigner      assigner;
1169     MempoolSelelemReserver             reserver;
1170     if (left->mempool)
1171     {
1172         assigner.assign(left, *sel);
1173         if (right)
1174         {
1175             reserver.reserve(right, g->isize);
1176         }
1177     }
1178     else if (right && right->mempool)
1179     {
1180         assigner.assign(right, *sel);
1181     }
1182     _gmx_sel_evaluate_children(data, sel, g);
1183
1184     n         = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize;
1185     sel->v.nr = n;
1186
1187     bool bArithNeg = (sel->u.arith.type == ARITH_NEG);
1188     GMX_ASSERT(right || bArithNeg,
1189                "Right operand cannot be null except for negations");
1190     for (i = i1 = i2 = 0; i < n; ++i)
1191     {
1192         lval = left->v.u.r[i1];
1193         if (!bArithNeg)
1194         {
1195             rval = right->v.u.r[i2];
1196         }
1197         switch (sel->u.arith.type)
1198         {
1199             case ARITH_PLUS:    val = lval + rval;     break;
1200             case ARITH_MINUS:   val = lval - rval;     break;
1201             case ARITH_NEG:     val = -lval;           break;
1202             case ARITH_MULT:    val = lval * rval;     break;
1203             case ARITH_DIV:     val = lval / rval;     break;
1204             case ARITH_EXP:     val = pow(lval, rval); break;
1205         }
1206         sel->v.u.r[i] = val;
1207         if (!(left->flags & SEL_SINGLEVAL))
1208         {
1209             ++i1;
1210         }
1211         if (!bArithNeg && !(right->flags & SEL_SINGLEVAL))
1212         {
1213             ++i2;
1214         }
1215     }
1216 }