Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / analysisdata / dataframe.h
index 3cd87b29a796eaaae58d8baf935c01a4bcdb9a87..5502063042bdf347db0e104c194bfd92ea28c926 100644 (file)
@@ -1,38 +1,42 @@
 /*
+ * This file is part of the GROMACS molecular simulation package.
  *
- *                This source code is part of
+ * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
  *
- *                 G   R   O   M   A   C   S
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
  *
- *          GROningen MAchine for Chemical Simulations
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
  *
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
  *
  * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
+ * the research papers on the package. Check out http://www.gromacs.org.
  */
 /*! \file
  * \brief
  * Declares classes for accessing data frame information.
  *
- * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \inpublicapi
  * \ingroup module_analysisdata
  */
 
 #include <vector>
 
-#include "../legacyheaders/types/simple.h"
-
-#include "../utility/arrayref.h"
-#include "../utility/flags.h"
-#include "../utility/gmxassert.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/flags.h"
+#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/real.h"
 
 namespace gmx
 {
@@ -260,6 +263,71 @@ class AnalysisDataFrameHeader
 };
 
 
+/*! \cond libinternal */
+/*! \libinternal \brief
+ * Value type for internal indexing of point sets.
+ *
+ * This class contains the necessary data to split an array of
+ * AnalysisDataValue objects into point sets.  It is always specified in the
+ * context of an array of AnalysisDataValues: the point set specified by this
+ * class contains valueCount() values, starting from the array index
+ * valueOffset().
+ * The value at location valueOffset() corresponds to column firstColumn().
+ * It is not necessary for code using the analysis data framework to know of
+ * this class, but it is declared in a public header to allow using it in other
+ * types.
+ *
+ * Default copy constructor and assignment operator are used and work as
+ * intended.
+ * Typically new objects of this type are only constructed internally by the
+ * library and in classes that are derived from AbstractAnalysisData.
+ *
+ * Methods in this class do not throw, but may contain asserts for incorrect
+ * usage.
+ *
+ * Note that it is not possible to change the contents of an initialized
+ * object, except by assigning a new object to replace it completely.
+ *
+ * \inlibraryapi
+ * \ingroup module_analysisdata
+ */
+class AnalysisDataPointSetInfo
+{
+    public:
+        //! Construct point set data object with the given values.
+        AnalysisDataPointSetInfo(int valueOffset, int valueCount,
+                                 int dataSetIndex, int firstColumn)
+            : valueOffset_(valueOffset), valueCount_(valueCount),
+              dataSetIndex_(dataSetIndex), firstColumn_(firstColumn)
+        {
+            GMX_ASSERT(valueOffset  >= 0, "Negative value offsets are invalid");
+            GMX_ASSERT(valueCount   >= 0, "Negative value counts are invalid");
+            GMX_ASSERT(dataSetIndex >= 0, "Negative data set indices are invalid");
+            GMX_ASSERT(firstColumn  >= 0, "Negative column indices are invalid");
+        }
+
+        //! Returns the offset of the first value in the referenced value array.
+        int valueOffset() const { return valueOffset_; }
+        //! Returns the number of values in this point set.
+        int valueCount() const { return valueCount_; }
+        //! Returns the data set index for this point set.
+        int dataSetIndex() const { return dataSetIndex_; }
+        //! Returns the index of the first column in this point set.
+        int firstColumn() const { return firstColumn_; }
+
+    private:
+        int                     valueOffset_;
+        int                     valueCount_;
+        int                     dataSetIndex_;
+        int                     firstColumn_;
+};
+
+//! Shorthand for reference to an array of point set data objects.
+typedef ConstArrayRef<AnalysisDataPointSetInfo> AnalysisDataPointSetInfosRef;
+
+//! \endcond
+
+
 /*! \brief
  * Value type wrapper for non-mutable access to a set of data column values.
  *
@@ -286,16 +354,16 @@ class AnalysisDataPointSetRef
         /*! \brief
          * Constructs a point set reference from given values.
          *
-         * \param[in] header      Header for the frame.
-         * \param[in] firstColumn Zero-based index of the first column.
-         *     Must be >= 0.
-         * \param[in] values      Values for each column.
+         * \param[in] header       Header for the frame.
+         * \param[in] pointSetInfo Information about the point set.
+         * \param[in] values       Values for each column.
          *
-         * The first element in \p values should correspond to \p firstColumn.
+         * The first element of the point set should be found from \p values
+         * using the offset in \p pointSetInfo.
          */
-        AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header,
-                                int firstColumn,
-                                const AnalysisDataValuesRef &values);
+        AnalysisDataPointSetRef(const AnalysisDataFrameHeader  &header,
+                                const AnalysisDataPointSetInfo &pointSetInfo,
+                                const AnalysisDataValuesRef    &values);
         /*! \brief
          * Constructs a point set reference from given values.
          *
@@ -305,7 +373,7 @@ class AnalysisDataPointSetRef
          * The first element in \p values should correspond to the first
          * column.
          */
-        AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header,
+        AnalysisDataPointSetRef(const AnalysisDataFrameHeader        &header,
                                 const std::vector<AnalysisDataValue> &values);
         /*! \brief
          * Constructs a point set reference to a subset of columns.
@@ -350,6 +418,11 @@ class AnalysisDataPointSetRef
         {
             return header_.dx();
         }
+        //! Returns zero-based index of the dataset that this set is part of.
+        int dataSetIndex() const
+        {
+            return dataSetIndex_;
+        }
         //! Returns zero-based index of the first column included in this set.
         int firstColumn() const
         {
@@ -422,6 +495,7 @@ class AnalysisDataPointSetRef
 
     private:
         AnalysisDataFrameHeader header_;
+        int                     dataSetIndex_;
         int                     firstColumn_;
         AnalysisDataValuesRef   values_;
 };
@@ -441,9 +515,6 @@ class AnalysisDataPointSetRef
  * Note that it is not possible to change the contents of an initialized
  * object, except by assigning a new object to replace it completely.
  *
- * \todo
- * Support for multipoint data.
- *
  * \inpublicapi
  * \ingroup module_analysisdata
  */
@@ -462,17 +533,21 @@ class AnalysisDataFrameRef
          *
          * \param[in] header      Header for the frame.
          * \param[in] values      Values for each column.
+         * \param[in] pointSets   Point set data.
          */
-        AnalysisDataFrameRef(const AnalysisDataFrameHeader &header,
-                             const AnalysisDataValuesRef &values);
+        AnalysisDataFrameRef(const AnalysisDataFrameHeader      &header,
+                             const AnalysisDataValuesRef        &values,
+                             const AnalysisDataPointSetInfosRef &pointSets);
         /*! \brief
          * Constructs a frame reference from given values.
          *
          * \param[in] header      Header for the frame.
          * \param[in] values      Values for each column.
+         * \param[in] pointSets   Point set data.
          */
-        AnalysisDataFrameRef(const AnalysisDataFrameHeader &header,
-                             const std::vector<AnalysisDataValue> &values);
+        AnalysisDataFrameRef(const AnalysisDataFrameHeader               &header,
+                             const std::vector<AnalysisDataValue>        &values,
+                             const std::vector<AnalysisDataPointSetInfo> &pointSets);
         /*! \brief
          * Constructs a frame reference to a subset of columns.
          *
@@ -519,63 +594,54 @@ class AnalysisDataFrameRef
             return header().dx();
         }
         /*! \brief
-         * Returns point set reference to the column values of this frame.
+         * Returns the number of point sets for this frame.
          *
-         * Should not be called for invalid frames.
+         * Returns zero for an invalid frame.
          */
-        AnalysisDataPointSetRef points() const
+        int pointSetCount() const
         {
-            GMX_ASSERT(isValid(), "Invalid data frame accessed");
-            return AnalysisDataPointSetRef(header_, 0, values_);
+            return pointSets_.size();
         }
         /*! \brief
-         * Returns number of columns in this frame.
+         * Returns point set reference for a given point set.
          *
-         * Returns zero for an invalid frame.
+         * Should not be called for invalid frames.
          */
-        int columnCount() const
+        AnalysisDataPointSetRef pointSet(int index) const
         {
-            return values_.size();
-        }
-        /*! \brief
-         * Returns reference container for all column values.
-         */
-        const AnalysisDataValuesRef &values() const
-        {
-            return values_;
+            GMX_ASSERT(isValid(), "Invalid data frame accessed");
+            GMX_ASSERT(index >= 0 && index < pointSetCount(),
+                       "Out of range data access");
+            return AnalysisDataPointSetRef(header_, pointSets_[index], values_);
         }
         /*! \brief
-         * Convenience method for accessing a column value.
+         * Convenience method for accessing a column value in simple data.
          *
          * \copydetails AnalysisDataPointSetRef::y()
          */
         real y(int i) const
         {
-            GMX_ASSERT(isValid(), "Invalid data frame accessed");
-            GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
-            return values_[i].value();
+            return singleColumnValue(i).value();
         }
         /*! \brief
-         * Convenience method for accessing error for a column value.
+         * Convenience method for accessing error for a column value in simple
+         * data.
          *
          * \copydetails AnalysisDataPointSetRef::dy()
          */
         real dy(int i) const
         {
-            GMX_ASSERT(isValid(), "Invalid data frame accessed");
-            GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
-            return values_[i].error();
+            return singleColumnValue(i).error();
         }
         /*! \brief
-         * Convenience method for accessing present status for a column.
+         * Convenience method for accessing present status for a column in
+         * simple data.
          *
          * \copydetails AnalysisDataPointSetRef::present()
          */
         bool present(int i) const
         {
-            GMX_ASSERT(isValid(), "Invalid data frame accessed");
-            GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
-            return values_[i].isPresent();
+            return singleColumnValue(i).isPresent();
         }
         /*! \brief
          * Returns true if all points in this frame are present.
@@ -583,8 +649,20 @@ class AnalysisDataFrameRef
         bool allPresent() const;
 
     private:
-        AnalysisDataFrameHeader header_;
-        AnalysisDataValuesRef   values_;
+        //! Helper method for accessing single columns in simple data.
+        const AnalysisDataValue &singleColumnValue(int i) const
+        {
+            GMX_ASSERT(isValid(), "Invalid data frame accessed");
+            GMX_ASSERT(pointSets_.size() == 1U && pointSets_[0].firstColumn() == 0,
+                       "Convenience method not available for multiple point sets");
+            GMX_ASSERT(i >= 0 && i < static_cast<int>(values_.size()),
+                       "Out of range data access");
+            return values_[i];
+        }
+
+        AnalysisDataFrameHeader      header_;
+        AnalysisDataValuesRef        values_;
+        AnalysisDataPointSetInfosRef pointSets_;
 };
 
 } // namespace gmx