Add continuous array accessors for selection data.
authorTeemu Murtola <teemu.murtola@gmail.com>
Fri, 8 Feb 2013 13:28:58 +0000 (15:28 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 13 Feb 2013 21:27:18 +0000 (22:27 +0100)
It is now possible to access most selection data (coordinates, masses,
etc.) as continuous arrays for easier use with functions that expect
C arrays as input.

Change-Id: I285b4ff79137e2ca57c8e40b426b364572e3c13e

src/gromacs/selection/selection.h
src/gromacs/selection/selectionoption.h

index f1a6801729df37ba3f0303cd078f6f1504fc01bc..ca2af5783fc6c6c232b7927d5fec61cc26c79cbb 100644 (file)
@@ -223,6 +223,9 @@ class SelectionData
  * It is also possible to access the list of atoms that make up all the
  * positions directly: atomCount() returns the total number of atoms in the
  * selection and atomIndices() an array of their indices.
+ * Similarly, it is possible to access the coordinates and other properties
+ * of the positions as continuous arrays through coordinates(), velocities(),
+ * forces(), masses(), charges(), refIds(), and mappedIds().
  *
  * Both positions and atoms can be accessed after the selection has been
  * compiled.  For dynamic selections, the return values of these methods change
@@ -298,6 +301,75 @@ class Selection
         int posCount() const { return data().posCount(); }
         //! Access a single position.
         SelectionPosition position(int i) const;
+        //! Returns coordinates for this selection as a continuous array.
+        ConstArrayRef<rvec> coordinates() const
+        {
+            return ConstArrayRef<rvec>(posCount(), data().rawPositions_.x);
+        }
+        //! Returns whether velocities are available for this selection.
+        bool hasVelocities() const { return data().rawPositions_.v != NULL; }
+        /*! \brief
+         * Returns velocities for this selection as a continuous array.
+         *
+         * Must not be called if hasVelocities() returns false.
+         */
+        ConstArrayRef<rvec> velocities() const
+        {
+            GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable");
+            return ConstArrayRef<rvec>(posCount(), data().rawPositions_.v);
+        }
+        //! Returns whether forces are available for this selection.
+        bool hasForces() const { return sel_->rawPositions_.f != NULL; }
+        /*! \brief
+         * Returns forces for this selection as a continuous array.
+         *
+         * Must not be called if hasForces() returns false.
+         */
+        ConstArrayRef<rvec> forces() const
+        {
+            GMX_ASSERT(hasForces(), "Forces accessed, but unavailable");
+            return ConstArrayRef<rvec>(posCount(), data().rawPositions_.f);
+        }
+        //! Returns masses for this selection as a continuous array.
+        ConstArrayRef<real> masses() const
+        {
+            // posMass_ may have more entries than posCount() in the case of
+            // dynamic selections that don't have a topology
+            // (and thus the masses and charges are fixed).
+            GMX_ASSERT(data().posMass_.size() >= static_cast<size_t>(posCount()),
+                       "Internal inconsistency");
+            return ConstArrayRef<real>(data().posMass_.begin(),
+                                       data().posMass_.begin() + posCount());
+        }
+        //! Returns charges for this selection as a continuous array.
+        ConstArrayRef<real> charges() const
+        {
+            // posCharge_ may have more entries than posCount() in the case of
+            // dynamic selections that don't have a topology
+            // (and thus the masses and charges are fixed).
+            GMX_ASSERT(data().posCharge_.size() >= static_cast<size_t>(posCount()),
+                       "Internal inconsistency");
+            return ConstArrayRef<real>(data().posCharge_.begin(),
+                                       data().posCharge_.begin() + posCount());
+        }
+        /*! \brief
+         * Returns reference IDs for this selection as a continuous array.
+         *
+         * \see SelectionPosition::refId()
+         */
+        ConstArrayRef<int> refIds() const
+        {
+            return ConstArrayRef<int>(posCount(), data().rawPositions_.m.refid);
+        }
+        /*! \brief
+         * Returns mapped IDs for this selection as a continuous array.
+         *
+         * \see SelectionPosition::mappedId()
+         */
+        ConstArrayRef<int> mappedIds() const
+        {
+            return ConstArrayRef<int>(posCount(), data().rawPositions_.m.mapid);
+        }
         /*! \brief
          * Sets the ID for the \p i'th position for use with
          * SelectionPosition::mappedId().
@@ -437,28 +509,26 @@ class SelectionPosition
         {
             return sel_->rawPositions_.x[i_];
         }
-        //! Returns whether velocity is available for this position.
-        bool hasVelocity() const { return sel_->rawPositions_.v != NULL; }
         /*! \brief
          * Returns velocity for this position.
          *
-         * Must not be called if hasVelocity() returns false.
+         * Must not be called if Selection::hasVelocities() returns false.
          */
         const rvec &v() const
         {
-            GMX_ASSERT(hasVelocity(), "Velocities accessed, but unavailable");
+            GMX_ASSERT(sel_->rawPositions_.v != NULL,
+                       "Velocities accessed, but unavailable");
             return sel_->rawPositions_.v[i_];
         }
-        //! Returns whether force is available for this position.
-        bool hasForce() const { return sel_->rawPositions_.f != NULL; }
         /*! \brief
          * Returns force for this position.
          *
-         * Must not be called if hasForce() returns false.
+         * Must not be called if Selection::hasForces() returns false.
          */
         const rvec &f() const
         {
-            GMX_ASSERT(hasForce(), "Forces accessed, but unavailable");
+            GMX_ASSERT(sel_->rawPositions_.f != NULL,
+                       "Velocities accessed, but unavailable");
             return sel_->rawPositions_.f[i_];
         }
         /*! \brief
index 98b067350ab3af342976a944f4fcf9f75155d720..e5aa27c35ef92f596cfb93a38031822af36e67b9 100644 (file)
@@ -80,7 +80,7 @@ class SelectionOption : public OptionTemplate<Selection, SelectionOption>
          * Request velocity evaluation for output positions.
          *
          * Note that even with this flag set, velocities may not be available,
-         * in which case SelectionPosition::hasVelocity() returns false.
+         * in which case Selection::hasVelocities() returns false.
          */
         MyClass &evaluateVelocities()
         { selectionFlags_.set(efSelection_EvaluateVelocities); return me(); }
@@ -88,7 +88,7 @@ class SelectionOption : public OptionTemplate<Selection, SelectionOption>
          * Request force evaluation for output positions.
          *
          * Note that even with this flag set, forces may not be available,
-         * in which case SelectionPosition::hasForce() returns false.
+         * in which case Selection::hasForces() returns false.
          */
         MyClass &evaluateForces()
         { selectionFlags_.set(efSelection_EvaluateForces); return me(); }