More selection unit tests for variables and fixes.
authorTeemu Murtola <teemu.murtola@gmail.com>
Sun, 16 Sep 2012 10:40:22 +0000 (13:40 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 3 Oct 2012 03:36:56 +0000 (05:36 +0200)
- Added unit tests for more complex selections where either numeric or
  position values were assigned to variables.
- Fixed handling of subexpressions in these cases (will back-port to
  older branches separately).
- Added unit tests for constant expressions in variables (in particular
  constant positions were not handled right during initial development
  of selections).
- Added comments in the code for some parts that are currently
  unreachable.

Part of #651.

Change-Id: Ifbb585ca00fd7a9715b4c9cb004c3a895551c1a6

13 files changed:
src/gromacs/selection/compiler.cpp
src/gromacs/selection/evaluate.cpp
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/selelem.cpp
src/gromacs/selection/selmethod.cpp
src/gromacs/selection/sm_compare.cpp
src/gromacs/selection/sm_keywords.cpp
src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesComplexNumericVariables.xml [new file with mode: 0644]
src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesConstantPositionInVariable.xml [new file with mode: 0644]
src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericComparisons.xml [new file with mode: 0644]
src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericConstantsInVariables.xml [new file with mode: 0644]
src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariables.xml [new file with mode: 0644]
src/gromacs/selection/tests/selectioncollection.cpp

index 13a3953da3c588ffa80eaa4c2115a5c255ffe7d9..8e118fce1029b132972bb7c7c150eba1efb5d35b 100644 (file)
@@ -470,6 +470,9 @@ void SelectionTreeElement::freeCompilerData()
  *
  * If called more than once, memory is (re)allocated to ensure that the
  * maximum of the \p isize values can be stored.
+ *
+ * Allocation of POS_VALUE selection elements is a special case, and is
+ * handled by alloc_selection_pos_data().
  */
 static void
 alloc_selection_data(const SelectionTreeElementPointer &sel,
@@ -477,6 +480,8 @@ alloc_selection_data(const SelectionTreeElementPointer &sel,
 {
     int        nalloc;
 
+    GMX_RELEASE_ASSERT(sel->v.type != POS_VALUE,
+            "Wrong allocation method called");
     if (sel->mempool)
     {
         return;
@@ -492,6 +497,7 @@ alloc_selection_data(const SelectionTreeElementPointer &sel,
     }
     else /* sel->flags should contain SEL_VARNUMVAL */
     {
+        // TODO: Consider whether the bChildEval is any longer necessary.
         if (!bChildEval)
         {
             return;
@@ -505,32 +511,65 @@ alloc_selection_data(const SelectionTreeElementPointer &sel,
             GMX_RELEASE_ASSERT(child,
                 "Subexpression elements should always have a child element");
         }
-        nalloc = (sel->v.type == POS_VALUE) ? child->v.u.p->nr : child->v.nr;
-    }
-    /* For positions, we actually want to allocate just a single structure
-     * for nalloc positions. */
-    if (sel->v.type == POS_VALUE)
-    {
-        isize  = nalloc;
-        nalloc = 1;
+        nalloc = child->v.nr;
     }
     /* Allocate memory for sel->v.u if needed */
     if (sel->flags & SEL_ALLOCVAL)
     {
         _gmx_selvalue_reserve(&sel->v, nalloc);
     }
-    /* Reserve memory inside group and position structures if
-     * SEL_ALLOCDATA is set. */
+    /* Reserve memory inside group structure if SEL_ALLOCDATA is set. */
+    if ((sel->flags & SEL_ALLOCDATA) && sel->v.type == GROUP_VALUE)
+    {
+        gmx_ana_index_reserve(sel->v.u.g, isize);
+    }
+}
+
+/*! \brief
+ * Allocates memory for storing the evaluated value of a selection element.
+ *
+ * \param     sel   Selection element to initialize.
+ *
+ * Allocation of POS_VALUE selection elements is a special case, and is
+ * handled by this function instead of by alloc_selection_data().
+ */
+static void
+alloc_selection_pos_data(const SelectionTreeElementPointer &sel)
+{
+    int nalloc, isize;
+
+    GMX_RELEASE_ASSERT(sel->v.type == POS_VALUE,
+            "Wrong allocation method called");
+    GMX_RELEASE_ASSERT(!(sel->flags & SEL_ATOMVAL),
+            "Per-atom evaluated positions not implemented");
+    if (sel->mempool)
+    {
+        return;
+    }
+
+    SelectionTreeElementPointer child = sel;
+    if (sel->type == SEL_SUBEXPRREF)
+    {
+        GMX_RELEASE_ASSERT(sel->child && sel->child->type == SEL_SUBEXPR,
+            "Subexpression expected for subexpression reference");
+        child = sel->child->child;
+        GMX_RELEASE_ASSERT(child,
+            "Subexpression elements should always have a child element");
+    }
+    nalloc = child->v.u.p->nr;
+    isize = child->v.u.p->m.b.nra;
+
+    /* For positions, we want to allocate just a single structure
+     * for nalloc positions. */
+    if (sel->flags & SEL_ALLOCVAL)
+    {
+        _gmx_selvalue_reserve(&sel->v, 1);
+    }
+    sel->v.nr = 1;
+    /* Reserve memory inside position structure if SEL_ALLOCDATA is set. */
     if (sel->flags & SEL_ALLOCDATA)
     {
-        if (sel->v.type == GROUP_VALUE)
-        {
-            gmx_ana_index_reserve(sel->v.u.g, isize);
-        }
-        else if (sel->v.type == POS_VALUE)
-        {
-            gmx_ana_pos_reserve(sel->v.u.p, isize, 0);
-        }
+        gmx_ana_pos_reserve(sel->v.u.p, nalloc, isize);
     }
 }
 
@@ -1530,8 +1569,9 @@ init_item_minmax_groups(const SelectionTreeElementPointer &sel)
  * \param[in,out] sc   Selection collection data.
  *
  * The evaluation group of each \ref SEL_ROOT element corresponding to a
- * selection in \p sc is set to \p gall.  The same is done for \ref SEL_ROOT
- * elements corresponding to subexpressions that need full evaluation.
+ * selection in \p sc is set to NULL.  The evaluation grop for \ref SEL_ROOT
+ * elements corresponding to subexpressions that need full evaluation is set
+ * to \c sc->gall.
  */
 static void
 initialize_evalgrps(gmx_ana_selcollection_t *sc)
@@ -1542,7 +1582,11 @@ initialize_evalgrps(gmx_ana_selcollection_t *sc)
         GMX_RELEASE_ASSERT(root->child,
                            "Root elements should always have a child");
         if (root->child->type != SEL_SUBEXPR
-            || (root->child->cdata->flags & SEL_CDATA_FULLEVAL))
+            || (root->child->v.type != GROUP_VALUE && !(root->flags & SEL_ATOMVAL)))
+        {
+            gmx_ana_index_set(&root->u.cgrp, -1, 0, root->u.cgrp.name, 0);
+        }
+        else if (root->child->cdata->flags & SEL_CDATA_FULLEVAL)
         {
             gmx_ana_index_set(&root->u.cgrp, sc->gall.isize, sc->gall.index,
                               root->u.cgrp.name, 0);
@@ -1778,13 +1822,20 @@ init_method(const SelectionTreeElementPointer &sel, t_topology *top, int isize)
         if (sel->u.expr.method->outinit)
         {
             sel->u.expr.method->outinit(top, &sel->v, sel->u.expr.mdata);
-            if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE)
+            if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE
+                && !(sel->flags & SEL_VARNUMVAL))
             {
                 alloc_selection_data(sel, isize, true);
             }
         }
         else
         {
+            GMX_RELEASE_ASSERT(sel->v.type != POS_VALUE,
+                    "Output initialization must be provided for "
+                    "position-valued selection methods");
+            GMX_RELEASE_ASSERT(!(sel->flags & SEL_VARNUMVAL),
+                    "Output initialization must be provided for "
+                    "SMETH_VARNUMVAL selection methods");
             alloc_selection_data(sel, isize, true);
             if ((sel->flags & SEL_DYNAMIC)
                 && sel->v.type != GROUP_VALUE && sel->v.type != POS_VALUE)
@@ -2066,9 +2117,8 @@ analyze_static(gmx_sel_evaluate_t *data,
 
         case SEL_EXPRESSION:
         case SEL_MODIFIER:
-            GMX_ASSERT(g, "group cannot be null");
             _gmx_sel_evaluate_method_params(data, sel, g);
-            init_method(sel, data->top, g->isize);
+            init_method(sel, data->top, g ? g->isize : 0);
             if (!(sel->flags & SEL_DYNAMIC))
             {
                 sel->cdata->evaluate(data, sel, g);
@@ -2086,7 +2136,7 @@ analyze_static(gmx_sel_evaluate_t *data,
                 {
                     sel->cdata->evaluate(data, sel, g);
                 }
-                if (bDoMinMax)
+                if (bDoMinMax && g)
                 {
                     gmx_ana_index_copy(sel->cdata->gmax, g, true);
                 }
@@ -2194,7 +2244,14 @@ analyze_static(gmx_sel_evaluate_t *data,
                 /* The subexpression should have been evaluated if g is NULL
                  * (i.e., this is a method parameter or a direct value of a
                  * selection). */
-                alloc_selection_data(sel, sel->child->cdata->gmax->isize, true);
+                if (sel->v.type == POS_VALUE)
+                {
+                    alloc_selection_pos_data(sel);
+                }
+                else
+                {
+                    alloc_selection_data(sel, sel->child->cdata->gmax->isize, true);
+                }
             }
             sel->cdata->evaluate(data, sel, g);
             if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
index 0fce0a9e2bda327bcb60bddb857aa62a53228712..7b6d932ae24e64c2797b9cf8d2113a38405d4efa 100644 (file)
@@ -553,7 +553,14 @@ _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data,
     {
         sel->child->evaluate(data, sel->child, g);
         sel->v.nr = sel->child->v.nr;
-        gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, sel->u.cgrp.name, 0);
+        if (!g)
+        {
+            sel->u.cgrp.isize = -1;
+        }
+        else
+        {
+            gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, sel->u.cgrp.name, 0);
+        }
     }
 }
 
@@ -602,6 +609,7 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data,
     {
         gmissreserver.reserve(&gmiss, g->isize);
         gmx_ana_index_difference(&gmiss, g, &sel->u.cgrp);
+        gmiss.name = NULL;
     }
     if (gmiss.isize > 0)
     {
@@ -628,11 +636,11 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data,
                     {
                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                         {
-                            sel->v.u.i[k] = sel->v.u.i[j--];
+                            sel->v.u.i[k] = sel->child->v.u.i[j--];
                         }
                         else
                         {
-                            sel->v.u.i[k] = sel->child->v.u.i[i--];
+                            sel->v.u.i[k] = sel->v.u.i[i--];
                         }
                     }
                     break;
@@ -642,25 +650,27 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data,
                     {
                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                         {
-                            sel->v.u.r[k] = sel->v.u.r[j--];
+                            sel->v.u.r[k] = sel->child->v.u.r[j--];
                         }
                         else
                         {
-                            sel->v.u.r[k] = sel->child->v.u.r[i--];
+                            sel->v.u.r[k] = sel->v.u.r[i--];
                         }
                     }
                     break;
 
                 case STR_VALUE:
+                    // Note: with the currently allowed syntax, this case is never
+                    // reached.
                     for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
                     {
                         if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                         {
-                            sel->v.u.s[k] = sel->v.u.s[j--];
+                            sel->v.u.s[k] = sel->child->v.u.s[j--];
                         }
                         else
                         {
-                            sel->v.u.s[k] = sel->child->v.u.s[i--];
+                            sel->v.u.s[k] = sel->v.u.s[i--];
                         }
                     }
                     break;
index 19b5727599103d59f79bde2a5c030b9451dc2156..91123a6288d4ea09451b6960ce7a3a6f75e5fd05 100644 (file)
@@ -91,8 +91,10 @@ SelectionCollection::Impl::Impl()
 SelectionCollection::Impl::~Impl()
 {
     clearSymbolTable();
-    sc_.sel.clear();
+    // The tree must be freed before the SelectionData objects, since the
+    // tree may hold references to the position data in SelectionData.
     sc_.root.reset();
+    sc_.sel.clear();
     for (int i = 0; i < sc_.nvars; ++i)
     {
         sfree(sc_.varstrs[i]);
index f841994ba8b880d8bb68b6767bcb721a2e1a98ac..37afc3189fc642b20db1f2bd066563249d3a04fc 100644 (file)
@@ -426,6 +426,14 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel,
     {
         fprintf(fp, "0");
     }
+    if (sel.flags & SEL_ALLOCVAL)
+    {
+        fprintf(fp, "Av");
+    }
+    if (sel.flags & SEL_ALLOCDATA)
+    {
+        fprintf(fp, "Ad");
+    }
     if (sel.mempool)
     {
         fprintf(fp, "P");
@@ -464,7 +472,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel,
     }
     if (!(sel.flags & SEL_ALLOCVAL))
     {
-        fprintf(fp, " (ext. output)");
+        fprintf(fp, " (ext)");
     }
     fprintf(fp, "\n");
 
index 529c13db7dc9e01f5fd41e39b3ec25ca5989566c..9e01450c432d79dec7bfe699f533c7e9c80c7be6 100644 (file)
@@ -444,6 +444,12 @@ check_callbacks(FILE *fp, gmx_ana_selmethod_t *method)
         report_error(fp, method->name, "error: outinit should be provided because the method has POS_VALUE");
         bOk = false;
     }
+    /* Check presence of outinit for variable output count methods */
+    if ((method->flags & SMETH_VARNUMVAL) && !method->outinit)
+    {
+        report_error(fp, method->name, "error: outinit should be provided because the method has SMETH_VARNUMVAL");
+        bOk = false;
+    }
     /* Warn of dynamic callbacks in static methods */
     if (!(method->flags & SMETH_MODIFIER))
     {
index 0c4090b9915e829f0569b7e46e6e5775d755664f..970f24576028ba971098cf852bce8e3168831dbb 100644 (file)
@@ -418,6 +418,11 @@ init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         GMX_THROW(gmx::InternalError("Invalid comparison type"));
     }
     /* Convert the values to the same type */
+    /* TODO: Currently, there are no dynamic integer-valued selection methods,
+     * which means that only the branches with convert_int_real() will ever be
+     * taken. It should be considered whether it is necessary to support these
+     * other cases at all.
+     */
     if ((d->left.flags & CMP_REALVAL) && !(d->right.flags & CMP_REALVAL))
     {
         if (d->left.flags & d->right.flags & CMP_DYNAMICVAL)
index 6533c651f183542968df01d3cbf019c094fcdc18..58fcfefa25fb90e697fd5284d7de382fa7a17cd9 100644 (file)
@@ -648,6 +648,7 @@ init_output_kweval(t_topology *top, gmx_ana_selvalue_t *out, void *data)
     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
 
     out->nr = d->g.isize;
+    _gmx_selvalue_reserve(out, out->nr);
 }
 
 /*!
diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesComplexNumericVariables.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesComplexNumericVariables.xml
new file mode 100644 (file)
index 0000000..e8d7e98
--- /dev/null
@@ -0,0 +1,207 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <ParsedSelections Name="Parsed">
+    <ParsedVariable Name="Variable1">
+      <String Name="Input">value = x + y</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection1">
+      <String Name="Input">resname RA and value &lt;= 4</String>
+      <String Name="Name">resname RA and value &lt;= 4</String>
+      <String Name="Text">resname RA and value &lt;= 4</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection2">
+      <String Name="Input">resname RA RB and x &lt; 3 and value &lt;= 4</String>
+      <String Name="Name">resname RA RB and x &lt; 3 and value &lt;= 4</String>
+      <String Name="Text">resname RA RB and x &lt; 3 and value &lt;= 4</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedVariable Name="Variable2">
+      <String Name="Input">index = atomnr</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection3">
+      <String Name="Input">resname RA and index &lt; 3</String>
+      <String Name="Name">resname RA and index &lt; 3</String>
+      <String Name="Text">resname RA and index &lt; 3</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection4">
+      <String Name="Input">resname RB and y &lt; 3 and index &lt; 6</String>
+      <String Name="Name">resname RB and y &lt; 3 and index &lt; 6</String>
+      <String Name="Text">resname RB and y &lt; 3 and index &lt; 6</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+  </ParsedSelections>
+  <CompiledSelections Name="Compiled">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">9</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">2</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+      </Sequence>
+    </Selection>
+  </CompiledSelections>
+  <EvaluatedSelections Name="Frame1">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">4</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>8</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">4</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">5</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">5</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">2</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">2</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">1</Int>
+        <Int>4</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">1</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+  </EvaluatedSelections>
+</ReferenceData>
diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesConstantPositionInVariable.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesConstantPositionInVariable.xml
new file mode 100644 (file)
index 0000000..25226de
--- /dev/null
@@ -0,0 +1,273 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <ParsedSelections Name="Parsed">
+    <ParsedVariable Name="Variable1">
+      <String Name="Input">constpos = [1.0, 2.5, 0.5]</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection1">
+      <String Name="Input">constpos</String>
+      <String Name="Name">constpos</String>
+      <String Name="Text">constpos</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection2">
+      <String Name="Input">within 2 of constpos</String>
+      <String Name="Name">within 2 of constpos</String>
+      <String Name="Text">within 2 of constpos</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+  </ParsedSelections>
+  <CompiledSelections Name="Compiled">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">0</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">1</Int>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">0</Int>
+          </Sequence>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">15</Int>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>0</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>1</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>2</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>3</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>4</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>5</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>6</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>7</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>8</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>9</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>10</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>11</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>12</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>13</Int>
+          </Sequence>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>14</Int>
+          </Sequence>
+        </Position>
+      </Sequence>
+    </Selection>
+  </CompiledSelections>
+  <EvaluatedSelections Name="Frame1">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">0</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">1</Int>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">0</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.500000</Real>
+            <Real Name="Z">0.500000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">8</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">8</Int>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>0</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>1</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>2</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>3</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>4</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>5</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>6</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Sequence Name="Atoms">
+            <Int Name="Length">1</Int>
+            <Int>7</Int>
+          </Sequence>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+  </EvaluatedSelections>
+</ReferenceData>
diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericComparisons.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericComparisons.xml
new file mode 100644 (file)
index 0000000..6d9a284
--- /dev/null
@@ -0,0 +1,402 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <ParsedSelections Name="Parsed">
+    <ParsedSelection Name="Selection1">
+      <String Name="Input">x &gt; 2</String>
+      <String Name="Name">x &gt; 2</String>
+      <String Name="Text">x &gt; 2</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection2">
+      <String Name="Input">2 &lt; x</String>
+      <String Name="Name">2 &lt; x</String>
+      <String Name="Text">2 &lt; x</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection3">
+      <String Name="Input">y &gt; resnr</String>
+      <String Name="Name">y &gt; resnr</String>
+      <String Name="Text">y &gt; resnr</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection4">
+      <String Name="Input">resnr &lt; 2.5</String>
+      <String Name="Name">resnr &lt; 2.5</String>
+      <String Name="Text">resnr &lt; 2.5</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection5">
+      <String Name="Input">2.5 &gt; resnr</String>
+      <String Name="Name">2.5 &gt; resnr</String>
+      <String Name="Text">2.5 &gt; resnr</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+  </ParsedSelections>
+  <CompiledSelections Name="Compiled">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection5">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+      </Sequence>
+    </Selection>
+  </CompiledSelections>
+  <EvaluatedSelections Name="Frame1">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">7</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">7</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">4.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">4</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>7</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">4</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">6</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection5">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">6</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+  </EvaluatedSelections>
+</ReferenceData>
diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericConstantsInVariables.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesNumericConstantsInVariables.xml
new file mode 100644 (file)
index 0000000..d37473a
--- /dev/null
@@ -0,0 +1,217 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <ParsedSelections Name="Parsed">
+    <ParsedVariable Name="Variable1">
+      <String Name="Input">constint = 4</String>
+    </ParsedVariable>
+    <ParsedVariable Name="Variable2">
+      <String Name="Input">constreal1 = 0.5</String>
+    </ParsedVariable>
+    <ParsedVariable Name="Variable3">
+      <String Name="Input">constreal2 = 2.7</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection1">
+      <String Name="Input">resnr &lt; constint</String>
+      <String Name="Name">resnr &lt; constint</String>
+      <String Name="Text">resnr &lt; constint</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection2">
+      <String Name="Input">x + constreal1 &lt; constreal2</String>
+      <String Name="Name">x + constreal1 &lt; constreal2</String>
+      <String Name="Text">x + constreal1 &lt; constreal2</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+  </ParsedSelections>
+  <CompiledSelections Name="Compiled">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">9</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+  </CompiledSelections>
+  <EvaluatedSelections Name="Frame1">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">9</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">9</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">8</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">8</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">4.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+  </EvaluatedSelections>
+</ReferenceData>
diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariables.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariables.xml
new file mode 100644 (file)
index 0000000..a77d3ea
--- /dev/null
@@ -0,0 +1,255 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <ParsedSelections Name="Parsed">
+    <ParsedVariable Name="Variable1">
+      <String Name="Input">foo = res_cog of resname RA</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection1">
+      <String Name="Input">foo</String>
+      <String Name="Name">foo</String>
+      <String Name="Text">foo</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection2">
+      <String Name="Input">within 1 of foo</String>
+      <String Name="Name">within 1 of foo</String>
+      <String Name="Text">within 1 of foo</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+    <ParsedVariable Name="Variable2">
+      <String Name="Input">bar = cog of resname RA</String>
+    </ParsedVariable>
+    <ParsedSelection Name="Selection3">
+      <String Name="Input">bar</String>
+      <String Name="Name">bar</String>
+      <String Name="Text">bar</String>
+      <Bool Name="Dynamic">false</Bool>
+    </ParsedSelection>
+    <ParsedSelection Name="Selection4">
+      <String Name="Input">within 1 of bar</String>
+      <String Name="Name">within 1 of bar</String>
+      <String Name="Text">within 1 of bar</String>
+      <Bool Name="Dynamic">true</Bool>
+    </ParsedSelection>
+  </ParsedSelections>
+  <CompiledSelections Name="Compiled">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">15</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>3</Int>
+        <Int>4</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+        <Int>11</Int>
+        <Int>12</Int>
+        <Int>13</Int>
+        <Int>14</Int>
+      </Sequence>
+    </Selection>
+  </CompiledSelections>
+  <EvaluatedSelections Name="Frame1">
+    <Selection Name="Selection1">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">2</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.333333</Real>
+            <Real Name="Y">2.666667</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection2">
+      <Sequence Name="Atoms">
+        <Int Name="Length">7</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+        <Int>9</Int>
+        <Int>10</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">7</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">1.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">3.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection3">
+      <Sequence Name="Atoms">
+        <Int Name="Length">6</Int>
+        <Int>0</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>6</Int>
+        <Int>7</Int>
+        <Int>8</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">1</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.666667</Real>
+            <Real Name="Y">2.333333</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+    <Selection Name="Selection4">
+      <Sequence Name="Atoms">
+        <Int Name="Length">4</Int>
+        <Int>1</Int>
+        <Int>2</Int>
+        <Int>5</Int>
+        <Int>6</Int>
+      </Sequence>
+      <Sequence Name="Positions">
+        <Int Name="Length">4</Int>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">1.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">2.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+        <Position>
+          <Vector Name="Coordinates">
+            <Real Name="X">2.000000</Real>
+            <Real Name="Y">3.000000</Real>
+            <Real Name="Z">0.000000</Real>
+          </Vector>
+        </Position>
+      </Sequence>
+    </Selection>
+  </EvaluatedSelections>
+</ReferenceData>
index 8601b497dbb7fd09e1e688149427146f163e2a27..784017fb4fade7b9f4971bcd58c556cb285ab1be 100644 (file)
@@ -812,6 +812,21 @@ TEST_F(SelectionCollectionDataTest, HandlesBasicBoolean)
 }
 
 
+TEST_F(SelectionCollectionDataTest, HandlesNumericComparisons)
+{
+    static const char * const selections[] = {
+        "x > 2",
+        "2 < x",
+        "y > resnr",
+        "resnr < 2.5",
+        "2.5 > resnr",
+        NULL
+    };
+    setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
+    runTest("simple.gro", selections);
+}
+
+
 TEST_F(SelectionCollectionDataTest, HandlesArithmeticExpressions)
 {
     static const char * const selections[] = {
@@ -840,6 +855,67 @@ TEST_F(SelectionCollectionDataTest, HandlesNumericVariables)
 }
 
 
+TEST_F(SelectionCollectionDataTest, HandlesComplexNumericVariables)
+{
+    static const char * const selections[] = {
+        "value = x + y",
+        "resname RA and value <= 4",
+        "resname RA RB and x < 3 and value <= 4",
+        "index = atomnr",
+        "resname RA and index < 3",
+        "resname RB and y < 3 and index < 6",
+        NULL
+    };
+    setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
+    runTest("simple.gro", selections);
+}
+
+
+TEST_F(SelectionCollectionDataTest, HandlesPositionVariables)
+{
+    static const char * const selections[] = {
+        "foo = res_cog of resname RA",
+        "foo",
+        "within 1 of foo",
+        "bar = cog of resname RA",
+        "bar",
+        "within 1 of bar",
+        NULL
+    };
+    setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
+    runTest("simple.gro", selections);
+}
+
+
+TEST_F(SelectionCollectionDataTest, HandlesConstantPositionInVariable)
+{
+    static const char * const selections[] = {
+        "constpos = [1.0, 2.5, 0.5]",
+        "constpos",
+        "within 2 of constpos",
+        NULL
+    };
+    setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates
+            | efTestPositionAtoms);
+    runTest("simple.gro", selections);
+}
+
+
+TEST_F(SelectionCollectionDataTest, HandlesNumericConstantsInVariables)
+{
+    static const char * const selections[] = {
+        "constint = 4",
+        "constreal1 = 0.5",
+        "constreal2 = 2.7",
+        "resnr < constint",
+        "x + constreal1 < constreal2",
+        NULL
+    };
+    setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates);
+    runTest("simple.gro", selections);
+}
+
+
 /********************************************************************
  * Tests for complex boolean syntax
  */