Update energy and trajectory frame types
authorMark Abraham <mark.j.abraham@gmail.com>
Thu, 29 Mar 2018 07:04:02 +0000 (09:04 +0200)
committerDavid van der Spoel <spoel@xray.bmc.uu.se>
Fri, 22 Jun 2018 21:22:43 +0000 (23:22 +0200)
Introduced new classes that may eventually replace t_enxframe and
t_trxframe. Currently only used in tests that compare mdrun results.

Consolidated energy.h with the new energyframe.h

Change-Id: Ia49ece9ff99d8604112f8e3e0807fc9bede5fe8d

28 files changed:
src/gromacs/awh/awh.cpp
src/gromacs/awh/biaswriter.cpp
src/gromacs/fileio/enxio.cpp
src/gromacs/fileio/enxio.h
src/gromacs/gmxana/gmx_awh.cpp
src/gromacs/gmxana/gmx_dipoles.cpp
src/gromacs/gmxana/gmx_eneconv.cpp
src/gromacs/gmxana/gmx_enemat.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/gmxana/gmx_lie.cpp
src/gromacs/mdlib/coupling.cpp
src/gromacs/mdlib/ebin.cpp
src/gromacs/mdlib/ebin.h
src/gromacs/mdlib/mdebin.cpp
src/gromacs/tools/check.cpp
src/gromacs/tools/dump.cpp
src/gromacs/trajectory/CMakeLists.txt
src/gromacs/trajectory/energy.h [deleted file]
src/gromacs/trajectory/energyframe.cpp [new file with mode: 0644]
src/gromacs/trajectory/energyframe.h [new file with mode: 0644]
src/gromacs/trajectory/trajectoryframe.cpp
src/gromacs/trajectory/trajectoryframe.h
src/programs/mdrun/tests/energyreader.cpp
src/programs/mdrun/tests/energyreader.h
src/programs/mdrun/tests/initialconstraints.cpp
src/programs/mdrun/tests/pmetest.cpp
src/programs/mdrun/tests/trajectoryreader.cpp
src/programs/mdrun/tests/trajectoryreader.h

index 0f573e96c17f713a9e7749c7f74662e660cf4bec..e03bea12084354c01e9f46733073ef07d38800d4 100644 (file)
@@ -68,6 +68,7 @@
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pulling/pull.h"
 #include "gromacs/timing/wallcycle.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/pleasecite.h"
index 30bedd64407d9fce7b9514f7fb900587beda1743..06a021fde7359b970b48e29a93442bfda745c3a7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -42,9 +42,9 @@
 #include <cmath>
 
 #include "gromacs/awh/awh.h"
-#include "gromacs/fileio/enxio.h"
 #include "gromacs/mdtypes/awh-params.h"
 #include "gromacs/mdtypes/commrec.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
 
index 498f70faaade99ec515610c4ef303b978422ec5f..d3661e47a5e869f511410cef066a6615b8536c4b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -53,6 +53,7 @@
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/compare.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/futil.h"
index db4d20a24475715488f30cf831bd4c89f45db6eb..86e1a08798e7f45aba71e3a74a63c59aa7a79b65 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
 #define GMX_FILEIO_ENXIO_H
 
 #include "gromacs/fileio/xdr_datatype.h"
-#include "gromacs/trajectory/energy.h"
 #include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/real.h"
 
 struct gmx_groups_t;
+struct t_energy;
+struct t_enxframe;
 struct t_fileio;
 struct t_inputrec;
 class t_state;
@@ -118,31 +120,14 @@ struct t_enxsubblock
     int sval_alloc;
 };
 
-
 /* the energy file blocks. Each block contains a number of sub-blocks
    of a single type that contain the actual data. */
-typedef struct t_enxblock{
+struct t_enxblock
+{
     int            id;         /* block id, from the enx enums above */
     int            nsub;       /* number of subblocks */
     t_enxsubblock *sub;        /* the subblocks */
     int            nsub_alloc; /* number of allocated subblocks */
-} t_enxblock;
-
-
-/* The frames that are read/written */
-struct t_enxframe {
-    double          t;            /* Timestamp of this frame                        */
-    gmx_int64_t     step;         /* MD step                                */
-    gmx_int64_t     nsteps;       /* The number of steps between frames            */
-    double          dt;           /* The MD time step                              */
-    int             nsum;         /* The number of terms for the sums in ener      */
-    int             nre;          /* Number of energies                             */
-    int             e_size;       /* Size (in bytes) of energies                    */
-    int             e_alloc;      /* Allocated size (in elements) of ener          */
-    t_energy       *ener;         /* The energies                                  */
-    int             nblock;       /* Number of following energy blocks             */
-    t_enxblock     *block;        /* The blocks                                    */
-    int             nblock_alloc; /* The number of blocks allocated                */
 };
 
 /* file handle */
index fa7804d961f93924e30c3a89b2815089a5954f86..36f3aa3a13b969c0ab0a33d4076758b667aedb99 100644 (file)
@@ -65,6 +65,7 @@
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/fatalerror.h"
index 169a028d2f7aaf2c108a894f140479d7a203fd3a..b3f237bf08fd0e12cce750e36355df99fbd49d62 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -63,6 +63,7 @@
 #include "gromacs/statistics/statistics.h"
 #include "gromacs/topology/index.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/binaryinformation.h"
 #include "gromacs/utility/cstringutil.h"
index 6b089b1dd3889be18b63c708edb21254357af8f7..8e82735738502c71b0655ff9f072c0e342077516 100644 (file)
@@ -50,6 +50,7 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
index 23fd17953a70fe842a0f3edec324ce68de2624a4..c58c92e4e9fc8b6527aeb8dea0af3c787033f7a2 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -51,6 +51,7 @@
 #include "gromacs/math/vec.h"
 #include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
index 77de9a322276b520d18fd9f480a8495f9fab2745..7b529e6403f7014a80bbc6b1da1ce99de9e0bc15 100644 (file)
@@ -62,6 +62,7 @@
 #include "gromacs/topology/mtop_lookup.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
index 9ba2b1b966882dbfa380a693a81a4e780c3e56fa..17dba3971f2d9a444d63aac4bdf47bb51589b066 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,2018, 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.
@@ -51,6 +51,7 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/topology/ifunc.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/smalloc.h"
index 4a1cc52eb1971ecb36a2afaddae3210dd3c258f4..94b44bc60525c3df319b993c7300872b1c079c34 100644 (file)
@@ -63,7 +63,6 @@
 #include "gromacs/random/tabulatednormaldistribution.h"
 #include "gromacs/random/threefry.h"
 #include "gromacs/random/uniformrealdistribution.h"
-#include "gromacs/trajectory/energy.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
index 802c1253069c9c8f37d0584949ff04180c8b21db..0985f9e5dc32c12acd2ce82bb8265a9c6d404c7f 100644 (file)
@@ -47,6 +47,7 @@
 #include "gromacs/math/utilities.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/topology/ifunc.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
index 8f53f1648e8e5e5f9856e1d13560da6bd2c7083a..d1f29fc41cbf603bc7f109058a541ac6faa212a9 100644 (file)
@@ -40,7 +40,7 @@
 #include <stdio.h>
 
 #include "gromacs/fileio/enxio.h"
-#include "gromacs/trajectory/energy.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/basedefinitions.h"
 
 /* This is a running averaging structure ('energy bin') for use during mdrun. */
index 3dcd361ecce6bee57fa2e8f4ecaeaee21d421d1c..a238548b92939248df2bd9b599357c1b21544790 100644 (file)
@@ -64,6 +64,7 @@
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pulling/pull.h"
 #include "gromacs/topology/mtop_util.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
index e9ab81b00f087dea13d44ea327e5ca5bef285b57..8ce34d5a76782c6fe1952d0a175da2d76b58642f 100644 (file)
@@ -63,6 +63,7 @@
 #include "gromacs/topology/index.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/trajectory/trajectoryframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/fatalerror.h"
index 77ade935314be6a5929e3a53e3ab2e0e9130b857..f5bec85997ab87b3be3081e11a878f5181e870f5 100644 (file)
@@ -64,6 +64,7 @@
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/trajectory/trajectoryframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/basedefinitions.h"
index e6f935930714e163a23c2dab294c4eb239263bbc..b18cabb5db14b2d53672acdd0040bcbc43dc87a4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2015,2016,2018, 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.
 # the research papers on the package. Check out http://www.gromacs.org.
 
 gmx_add_libgromacs_sources(
+    energyframe.cpp
     trajectoryframe.cpp
     )
 
 gmx_install_headers(
-    energy.h
+    energyframe.h
     trajectoryframe.h
     )
diff --git a/src/gromacs/trajectory/energy.h b/src/gromacs/trajectory/energy.h
deleted file mode 100644 (file)
index 781ec92..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2010,2014,2015, 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.
- *
- * 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.
- *
- * 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.
- *
- * 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 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 research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef GMX_TRAJECTORY_ENERGY_H
-#define GMX_TRAJECTORY_ENERGY_H
-
-#include "gromacs/utility/real.h"
-
-struct t_energy {
-    //! The current energy.
-    real   e;
-    //! The running average of the energy
-    double eav;
-    //! The sum of energies until now.
-    double esum;
-};
-
-#endif
diff --git a/src/gromacs/trajectory/energyframe.cpp b/src/gromacs/trajectory/energyframe.cpp
new file mode 100644 (file)
index 0000000..5629a3e
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018, 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 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 research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \internal \file
+ * \brief Implementions of related classes for tests that want to
+ * inspect energies produced by mdrun.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun_integration_tests
+ */
+#include "gmxpre.h"
+
+#include "energyframe.h"
+
+#include <map>
+#include <string>
+
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/stringutil.h"
+
+namespace gmx
+{
+
+EnergyFrame::EnergyFrame(const t_enxframe &enxframe,
+                         const std::map<std::string, int> indicesOfEnergyFields)
+    : values_(), step_(enxframe.step), time_(enxframe.t)
+{
+    for (auto &index : indicesOfEnergyFields)
+    {
+        if (index.second >= enxframe.nre)
+        {
+            GMX_THROW(InternalError(formatString("Index %d for energy %s not present in energy frame with %d energies",
+                                                 index.second, index.first.c_str(), enxframe.nre)));
+        }
+        values_[index.first] = enxframe.ener[index.second].e;
+    }
+}
+
+std::string EnergyFrame::frameName() const
+{
+    return formatString("Time %f Step %" GMX_PRId64, time_, step_);
+}
+
+const real &EnergyFrame::at(const std::string &name) const
+{
+    auto valueIterator = values_.find(name);
+    if (valueIterator == values_.end())
+    {
+        GMX_THROW(APIError("Cannot get energy value " + name + " unless previously registered when constructing EnergyFrameReader"));
+    }
+    return valueIterator->second;
+}
+
+EnergyFrame::MapConstIterator EnergyFrame::begin() const
+{
+    return values_.begin();
+}
+
+EnergyFrame::MapConstIterator EnergyFrame::end() const
+{
+    return values_.end();
+}
+
+EnergyFrame::MapConstIterator EnergyFrame::find(const std::string &key) const
+{
+    return values_.find(key);
+}
+
+} // namespace
diff --git a/src/gromacs/trajectory/energyframe.h b/src/gromacs/trajectory/energyframe.h
new file mode 100644 (file)
index 0000000..90d9eab
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 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 research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMX_TRAJECTORY_ENERGYFRAME_H
+#define GMX_TRAJECTORY_ENERGYFRAME_H
+
+#include <map>
+#include <string>
+
+#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/real.h"
+
+struct t_enxblock;
+
+struct t_energy
+{
+    //! The current energy.
+    real   e;
+    //! The running average of the energy
+    double eav;
+    //! The sum of energies until now.
+    double esum;
+};
+
+/* The frames that are read/written */
+struct t_enxframe
+{
+    double          t;            /* Timestamp of this frame                        */
+    gmx_int64_t     step;         /* MD step                                */
+    gmx_int64_t     nsteps;       /* The number of steps between frames            */
+    double          dt;           /* The MD time step                              */
+    int             nsum;         /* The number of terms for the sums in ener      */
+    int             nre;          /* Number of energies                             */
+    int             e_size;       /* Size (in bytes) of energies                    */
+    int             e_alloc;      /* Allocated size (in elements) of ener          */
+    t_energy       *ener;         /* The energies                                  */
+    int             nblock;       /* Number of following energy blocks             */
+    t_enxblock     *block;        /* The blocks                                    */
+    int             nblock_alloc; /* The number of blocks allocated                */
+};
+
+namespace gmx
+{
+
+/*! \internal
+ * \brief Contains the content of an .edr frame read by an EnergyFrameReader
+ *
+ * The interface of this class is intended to resemble a subset of std::map. */
+class EnergyFrame
+{
+    public:
+        //! Convenience type
+        using MapType = std::map<std::string, real>;
+        //! Convenience type
+        using MapConstIterator = MapType::const_iterator;
+        //! Constructor
+        EnergyFrame(const t_enxframe &enxframe,
+                    const std::map<std::string, int> indicesOfEnergyFields);
+        /*! \brief Return string that helps users identify this frame, containing time and step number.
+         *
+         * \throws std::bad_alloc  when out of memory */
+        std::string frameName() const;
+        /*! \brief Return the value read for energy \c name.
+         *
+         * \throws APIError  if \c name was not registered with EnergyFileReader. */
+        const real &at(const std::string &name) const;
+        //! Return const interator to first element of values.
+        MapConstIterator begin() const;
+        //! Return const interator to past the end element of values.
+        MapConstIterator end() const;
+        //! Return a const interator to the element with \c key, or end() if not found.
+        MapConstIterator find(const std::string &key) const;
+    private:
+        //! Container for energy values, indexed by name
+        MapType      values_;
+        //! Step number read from the .edr file frame
+        std::int64_t step_;
+        //! Time read from the .edr file frame
+        double       time_;
+};
+
+} // namespace
+
+#endif
index 7508d1c7f443e623f9ec70df9d9cc70222219294..68500a628b39fc64e50e8719643f786f13e138c8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018, 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.
@@ -43,7 +43,9 @@
 #include "gromacs/math/veccompare.h"
 #include "gromacs/topology/atoms.h"
 #include "gromacs/utility/compare.h"
+#include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
 
 void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2,
                 gmx_bool bRMSD, real ftol, real abstol)
@@ -101,3 +103,97 @@ void done_frame(t_trxframe *frame)
     sfree(frame->v);
     sfree(frame->f);
 }
+
+namespace gmx
+{
+
+TrajectoryFrame::TrajectoryFrame(const t_trxframe &frame)
+    : frame_(frame)
+{
+    // This would be nicer as an initializer, but once uncrustify is
+    // happy, Doxygen can't parse it.
+    box_ = {{{{0}}}};
+
+    if (!frame.bStep)
+    {
+        GMX_THROW(APIError("Cannot handle trajectory frame that lacks a step number"));
+    }
+    if (!frame.bTime)
+    {
+        GMX_THROW(APIError("Cannot handle trajectory frame that lacks a time"));
+    }
+    if (frame.bBox)
+    {
+        for (int d = 0; d < DIM; ++d)
+        {
+            for (int dd = 0; dd < DIM; ++dd)
+            {
+                box_[d][dd] = frame.box[d][dd];
+            }
+        }
+    }
+}
+
+std::string TrajectoryFrame::frameName() const
+{
+    return formatString("Time %f Step %" GMX_PRId64, frame_.time, frame_.step);
+}
+
+std::int64_t TrajectoryFrame::step() const
+{
+    return frame_.step;
+}
+
+double TrajectoryFrame::time() const
+{
+    return frame_.time;
+}
+
+int TrajectoryFrame::pbc() const
+{
+    return frame_.ePBC;
+}
+
+ArrayRef<const RVec> TrajectoryFrame::x() const
+{
+    return arrayRefFromArray(reinterpret_cast<RVec *>(frame_.x),
+                             frame_.natoms);
+}
+
+ArrayRef<const RVec> TrajectoryFrame::v() const
+{
+    if (frame_.bV)
+    {
+        return arrayRefFromArray(reinterpret_cast<RVec *>(frame_.v),
+                                 frame_.natoms);
+    }
+    else
+    {
+        return EmptyArrayRef();
+    }
+}
+
+ArrayRef<const RVec> TrajectoryFrame::f() const
+{
+    if (frame_.bF)
+    {
+        return arrayRefFromArray(reinterpret_cast<RVec *>(frame_.f),
+                                 frame_.natoms);
+    }
+    else
+    {
+        return EmptyArrayRef();
+    }
+}
+
+bool TrajectoryFrame::hasBox() const
+{
+    return frame_.bBox;
+}
+
+const BoxMatrix &TrajectoryFrame::box() const
+{
+    return box_;
+}
+
+} // namespace gmx
index 3901eaaef71daabab692c0447ca2c539cf6ed9ea..04fbf601ca4ef2a8ba83c5915e5322c9c5c320d8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
 
 #include <cstdio>
 
+#include <array>
+
 #include "gromacs/math/vectypes.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
@@ -86,4 +89,63 @@ void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2,
 
 void done_frame(t_trxframe *frame);
 
+namespace gmx
+{
+
+/*!\brief A 3x3 matrix data type useful for simulation boxes
+ *
+ * \todo Implement a full replacement for C-style real[DIM][DIM] */
+using BoxMatrix = std::array <std::array<real, DIM>, DIM>;
+
+/*! \internal
+ * \brief Contains a valid trajectory frame.
+ *
+ * Valid frames have a step and time, but need not have any particular
+ * other fields.
+ *
+ * \todo Eventually t_trxframe should be replaced by a class such as
+ * this. Currently we need to introduce BoxMatrix so that we can have
+ * a normal C++ getter that returns the contents of a box matrix,
+ * since you cannot use a real[DIM][DIM] as a function return type.
+ *
+ * \todo Consider a std::optional work-alike type for expressing that
+ * a field may or may not have content. */
+class TrajectoryFrame
+{
+    public:
+        /*! \brief Constructor
+         *
+         * \throws APIError If \c frame lacks either step or time.
+         */
+        explicit TrajectoryFrame(const t_trxframe &frame);
+        /*! \brief Return a string that helps users identify this frame, containing time and step number.
+         *
+         * \throws std::bad_alloc  when out of memory */
+        std::string frameName() const;
+        //! Step number read from the trajectory file frame.
+        std::int64_t step() const;
+        //! Time read from the trajectory file frame.
+        double time() const;
+        //! The PBC characteristics of the box.
+        int pbc() const;
+        //! Get a view of position coordinates of the frame (which could be empty).
+        ArrayRef<const RVec> x() const;
+        //! Get a view of velocity coordinates of the frame (which could be empty).
+        ArrayRef<const RVec> v() const;
+        //! Get a view of force coordinates of the frame (which could be empty).
+        ArrayRef<const RVec> f() const;
+        //! Return whether the frame has a box.
+        bool hasBox() const;
+        //! Return a handle to the frame's box, which is all zero if the frame has no box.
+        const BoxMatrix &box() const;
+        // TODO make this private when updating trajectory comparison code
+        //! Handle to trajectory data
+        const t_trxframe &frame_;
+    private:
+        //! Box matrix data from the frame_.
+        BoxMatrix         box_;
+};
+
+} // namespace gmx
+
 #endif
index 0fe91c7e1e78b9ea6ed13df16313b9bc1fe79b9b..3edbc9ce9fed40ae944ae711b9b597bc29e03e7d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018, 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.
@@ -51,6 +51,7 @@
 #include <vector>
 
 #include "gromacs/fileio/enxio.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/stringutil.h"
 
@@ -174,8 +175,6 @@ EnergyFrameReader::readNextFrame()
 EnergyFrame
 EnergyFrameReader::frame()
 {
-    EnergyFrame energyFrame;
-
     if (!haveProbedForNextFrame_)
     {
         readNextFrame();
@@ -185,44 +184,12 @@ EnergyFrameReader::frame()
         GMX_THROW(APIError("There is no next frame, so there should have been no attempt to use the data, e.g. by reacting to a call to readNextFrame()."));
     }
 
-    // The probe filled enxframe_ with new data, so now we use that data to fill energyFrame
-    t_enxframe *enxframe = enxframeGuard_.get();
-    energyFrame.time_ = enxframe->t;
-    energyFrame.step_ = enxframe->step;
-    for (auto &index : indicesOfEnergyFields_)
-    {
-        if (index.second >= enxframe->nre)
-        {
-            GMX_THROW(InternalError(formatString("Index %d for energy %s not present in energy frame with %d energies",
-                                                 index.second, index.first.c_str(), enxframe->nre)));
-        }
-        energyFrame.values_[index.first] = enxframe->ener[index.second].e;
-    }
-
     // Prepare for reading future frames
     haveProbedForNextFrame_ = false;
     nextFrameExists_        = false;
 
-    return energyFrame;
-}
-
-// === EnergyFrame ===
-
-EnergyFrame::EnergyFrame() : values_(), step_(), time_() {};
-
-std::string EnergyFrame::getFrameName() const
-{
-    return formatString("Time %f Step %" GMX_PRId64, time_, step_);
-}
-
-const real &EnergyFrame::at(const std::string &name) const
-{
-    auto valueIterator = values_.find(name);
-    if (valueIterator == values_.end())
-    {
-        GMX_THROW(APIError("Cannot get energy value " + name + " unless previously registered when constructing EnergyFrameReader"));
-    }
-    return valueIterator->second;
+    // The probe filled enxframe_ with new data, so now we use that data to fill energyFrame
+    return EnergyFrame(*enxframeGuard_.get(), indicesOfEnergyFields_);
 }
 
 void compareFrames(const std::pair<EnergyFrame, EnergyFrame> &frames,
@@ -231,15 +198,15 @@ void compareFrames(const std::pair<EnergyFrame, EnergyFrame> &frames,
     auto &reference = frames.first;
     auto &test      = frames.second;
 
-    for (auto referenceIt = reference.values_.begin(); referenceIt != reference.values_.end(); ++referenceIt)
+    for (auto referenceIt = reference.begin(); referenceIt != reference.end(); ++referenceIt)
     {
-        auto testIt = test.values_.find(referenceIt->first);
-        if (testIt != test.values_.end())
+        auto testIt = test.find(referenceIt->first);
+        if (testIt != test.end())
         {
             auto energyFieldInReference = referenceIt->second;
             auto energyFieldInTest      = testIt->second;
             EXPECT_REAL_EQ_TOL(energyFieldInReference, energyFieldInTest, tolerance)
-            << referenceIt->first << " didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+            << referenceIt->first << " didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
         }
     }
 }
index b33af5466dcbc22b57d938752a2f6088e36fe50b..3b6bad900e479583df88147be4d00979259ee0e3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018, 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.
@@ -66,6 +66,9 @@
 
 namespace gmx
 {
+
+class EnergyFrame;
+
 namespace test
 {
 
@@ -88,8 +91,6 @@ typedef std::unique_ptr<EnergyFrameReader> EnergyFrameReaderPtr;
 EnergyFrameReaderPtr openEnergyFileToReadFields(const std::string              &filename,
                                                 const std::vector<std::string> &requiredEnergyFieldNames);
 
-class EnergyFrame;
-
 //! Convenience smart pointer typedef
 typedef unique_cptr<ener_file, done_ener_file> ener_file_ptr;
 //! Helper function to free resources (NB free_enxframe only frees the contents, not the pointer itself)
@@ -158,40 +159,6 @@ class EnergyFrameReader
 void compareFrames(const std::pair<EnergyFrame, EnergyFrame> &frames,
                    FloatingPointTolerance tolerance);
 
-/*! \internal
- * \brief Contains the content of an .edr frame read by an EnergyFrameReader
- *
- * The interface of this class is intended to resemble a subset of std::map.
- *
- * Objects of this type are intended to be constructed by
- * EnergyFrameReader objects, and as such will always contain valid
- * data from an .edr file frame. */
-class EnergyFrame
-{
-    public:
-        /*! \brief Return string that helps users identify this frame, containing time and step number.
-         *
-         * \throws std::bad_alloc  when out of memory */
-        std::string getFrameName() const;
-        /*! \brief Return the value read for energy \c name.
-         *
-         * \throws APIError  if \c name was not registered with EnergyFileReader. */
-        const real &at(const std::string &name) const;
-        //! Constructor
-        EnergyFrame();
-    private:
-        //! Container for energy values, indexed by name
-        std::map<std::string, real> values_;
-        //! Step number read from the .edr file frame
-        std::int64_t                step_;
-        //! Time read from the .edr file frame
-        double time_;
-
-        friend class EnergyFrameReader;
-        friend void compareFrames(const std::pair<EnergyFrame, EnergyFrame> &frames,
-                                  FloatingPointTolerance tolerance);
-};
-
 } // namespace
 } // namespace
 
index 2c077a769d9cfa06f609cb07ceecd47edce63714..8441ef7a7344657725e592cbe0c385cc9c21f6a0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018, 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.
@@ -49,6 +49,7 @@
 
 #include <string>
 
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/stringutil.h"
 
 #include "energyreader.h"
index dc4cff55e132d5e5c4d19c95d9eee7b13f4242aa..287ebe9d2ee64d18bd629c251ee24525d2f2ad7c 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "gromacs/gpu_utils/gpu_utils.h"
 #include "gromacs/hardware/gpu_hw_info.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/gmxmpi.h"
 #include "gromacs/utility/stringutil.h"
@@ -170,7 +171,7 @@ void PmeTest::runTest(const RunModesList &runModes)
             while (energyReader->readNextFrame())
             {
                 const EnergyFrame &frame            = energyReader->frame();
-                const std::string  stepName         = frame.getFrameName();
+                const std::string  stepName         = frame.frameName();
                 const real         conservedEnergy  = frame.at("Total Energy");
                 const real         reciprocalEnergy = frame.at("Coul. recip.");
                 if (firstIteration)
index fb237221b4c76cff6c47193859ab4a58e8e616de..6dfdd28b087c6f03cb807ab2138e3069bf24c0dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018, 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.
@@ -141,8 +141,6 @@ TrajectoryFrameReader::readNextFrame()
 TrajectoryFrame
 TrajectoryFrameReader::frame()
 {
-    TrajectoryFrame frame;
-
     if (!haveProbedForNextFrame_)
     {
         readNextFrame();
@@ -157,29 +155,7 @@ TrajectoryFrameReader::frame()
     nextFrameExists_        = false;
 
     // The probe filled trxframeGuard_ with new data, so return it
-    frame.frame_ = trxframeGuard_.get();
-
-    if (!frame.frame_->bStep)
-    {
-        GMX_THROW(APIError("Cannot handle trajectory frame that lacks a step number"));
-    }
-
-    if (!frame.frame_->bTime)
-    {
-        GMX_THROW(APIError("Cannot handle trajectory frame that lacks a time"));
-    }
-
-    return frame;
-}
-
-// === TrajectoryFrame ===
-
-TrajectoryFrame::TrajectoryFrame() : frame_(nullptr) {};
-
-std::string TrajectoryFrame::getFrameName() const
-{
-    GMX_RELEASE_ASSERT(frame_, "Cannot get name of invalid frame");
-    return formatString("Time %f Step %" GMX_PRId64, frame_->time, frame_->step);
+    return TrajectoryFrame(*trxframeGuard_.get());
 }
 
 void compareFrames(const std::pair<TrajectoryFrame, TrajectoryFrame> &frames,
@@ -190,30 +166,30 @@ void compareFrames(const std::pair<TrajectoryFrame, TrajectoryFrame> &frames,
 
     // NB We checked earlier for both frames that bStep and bTime are set
 
-    EXPECT_EQ(reference.frame_->step, test.frame_->step)
-    << "step didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+    EXPECT_EQ(reference.frame_.step, test.frame_.step)
+    << "step didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
 
-    EXPECT_EQ(reference.frame_->time, test.frame_->time)
-    << "time didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+    EXPECT_EQ(reference.frame_.time, test.frame_.time)
+    << "time didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
 
-    for (int i = 0; i < reference.frame_->natoms && i < test.frame_->natoms; ++i)
+    for (int i = 0; i < reference.frame_.natoms && i < test.frame_.natoms; ++i)
     {
         for (int d = 0; d < DIM; ++d)
         {
-            if (reference.frame_->bX && test.frame_->bX)
+            if (reference.frame_.bX && test.frame_.bX)
             {
-                EXPECT_REAL_EQ_TOL(reference.frame_->x[i][d], test.frame_->x[i][d], tolerance)
-                << " x[" << i << "][" << d <<"] didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+                EXPECT_REAL_EQ_TOL(reference.frame_.x[i][d], test.frame_.x[i][d], tolerance)
+                << " x[" << i << "][" << d <<"] didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
             }
-            if (reference.frame_->bV && test.frame_->bV)
+            if (reference.frame_.bV && test.frame_.bV)
             {
-                EXPECT_REAL_EQ_TOL(reference.frame_->v[i][d], test.frame_->v[i][d], tolerance)
-                << " v[" << i << "][" << d <<"] didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+                EXPECT_REAL_EQ_TOL(reference.frame_.v[i][d], test.frame_.v[i][d], tolerance)
+                << " v[" << i << "][" << d <<"] didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
             }
-            if (reference.frame_->bF && test.frame_->bF)
+            if (reference.frame_.bF && test.frame_.bF)
             {
-                EXPECT_REAL_EQ_TOL(reference.frame_->f[i][d], test.frame_->f[i][d], tolerance)
-                << " f[" << i << "][" << d <<"] didn't match between reference run " << reference.getFrameName() << " and test run " << test.getFrameName();
+                EXPECT_REAL_EQ_TOL(reference.frame_.f[i][d], test.frame_.f[i][d], tolerance)
+                << " f[" << i << "][" << d <<"] didn't match between reference run " << reference.frameName() << " and test run " << test.frameName();
             }
         }
     }
index 9184cb141bcb25e422635da5ee815b70473858d5..b209015f137c55c2f5ddc465ec5efaadf1f2df5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016, by the GROMACS development team, led by
+ * Copyright (c) 2016,2018, 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.
@@ -63,12 +63,13 @@ struct gmx_output_env_t;
 
 namespace gmx
 {
-namespace test
-{
 
 //! Forward declaration
 class TrajectoryFrame;
 
+namespace test
+{
+
 //! Convenience smart pointer typedef
 typedef unique_cptr<gmx_output_env_t, output_env_done> oenv_ptr;
 //! Convenience smart pointer typedef
@@ -150,26 +151,6 @@ typedef std::unique_ptr<TrajectoryFrameReader> TrajectoryFrameReaderPtr;
 void compareFrames(const std::pair<TrajectoryFrame, TrajectoryFrame> &frames,
                    FloatingPointTolerance tolerance);
 
-/*! \internal
- * \brief Contains the content of a trajectory frame read by an TrajectoryFrameReader
- *
- * Objects of this type are intended to be constructed by
- * TrajectoryFrameReader objects, and as such will always contain valid
- * data from an trajectory file frame. */
-class TrajectoryFrame
-{
-    public:
-        /*! \brief Return string that helps users identify this frame, containing time and step number.
-         *
-         * \throws std::bad_alloc  when out of memory */
-        std::string getFrameName() const;
-        //! Constructor
-        TrajectoryFrame();
-
-        //! Handle to trajectory data
-        t_trxframe *frame_;
-};
-
 } // namespace
 } // namespace