From 4ed9d7b8d52f6a030935a3a4de2ae839774c7254 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Thu, 29 Mar 2018 09:04:02 +0200 Subject: [PATCH] Update energy and trajectory frame types 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 --- src/gromacs/awh/awh.cpp | 1 + src/gromacs/awh/biaswriter.cpp | 4 +- src/gromacs/fileio/enxio.cpp | 3 +- src/gromacs/fileio/enxio.h | 27 ++---- src/gromacs/gmxana/gmx_awh.cpp | 1 + src/gromacs/gmxana/gmx_dipoles.cpp | 3 +- src/gromacs/gmxana/gmx_eneconv.cpp | 1 + src/gromacs/gmxana/gmx_enemat.cpp | 3 +- src/gromacs/gmxana/gmx_energy.cpp | 1 + src/gromacs/gmxana/gmx_lie.cpp | 3 +- src/gromacs/mdlib/coupling.cpp | 1 - src/gromacs/mdlib/ebin.cpp | 1 + src/gromacs/mdlib/ebin.h | 2 +- src/gromacs/mdlib/mdebin.cpp | 1 + src/gromacs/tools/check.cpp | 1 + src/gromacs/tools/dump.cpp | 1 + src/gromacs/trajectory/CMakeLists.txt | 5 +- src/gromacs/trajectory/energy.h | 51 ----------- src/gromacs/trajectory/energyframe.cpp | 101 ++++++++++++++++++++ src/gromacs/trajectory/energyframe.h | 117 ++++++++++++++++++++++++ src/gromacs/trajectory/trajectoryframe.cpp | 98 +++++++++++++++++++- src/gromacs/trajectory/trajectoryframe.h | 64 ++++++++++++- src/programs/mdrun/tests/energyreader.cpp | 49 ++-------- src/programs/mdrun/tests/energyreader.h | 41 +-------- src/programs/mdrun/tests/initialconstraints.cpp | 3 +- src/programs/mdrun/tests/pmetest.cpp | 3 +- src/programs/mdrun/tests/trajectoryreader.cpp | 56 ++++-------- src/programs/mdrun/tests/trajectoryreader.h | 27 +----- 28 files changed, 442 insertions(+), 227 deletions(-) delete mode 100644 src/gromacs/trajectory/energy.h create mode 100644 src/gromacs/trajectory/energyframe.cpp create mode 100644 src/gromacs/trajectory/energyframe.h diff --git a/src/gromacs/awh/awh.cpp b/src/gromacs/awh/awh.cpp index 0f573e96c1..e03bea1208 100644 --- a/src/gromacs/awh/awh.cpp +++ b/src/gromacs/awh/awh.cpp @@ -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" diff --git a/src/gromacs/awh/biaswriter.cpp b/src/gromacs/awh/biaswriter.cpp index 30bedd6440..06a021fde7 100644 --- a/src/gromacs/awh/biaswriter.cpp +++ b/src/gromacs/awh/biaswriter.cpp @@ -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 #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" diff --git a/src/gromacs/fileio/enxio.cpp b/src/gromacs/fileio/enxio.cpp index 498f70faaa..d3661e47a5 100644 --- a/src/gromacs/fileio/enxio.cpp +++ b/src/gromacs/fileio/enxio.cpp @@ -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" diff --git a/src/gromacs/fileio/enxio.h b/src/gromacs/fileio/enxio.h index db4d20a244..86e1a08798 100644 --- a/src/gromacs/fileio/enxio.h +++ b/src/gromacs/fileio/enxio.h @@ -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. @@ -38,10 +38,12 @@ #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 */ diff --git a/src/gromacs/gmxana/gmx_awh.cpp b/src/gromacs/gmxana/gmx_awh.cpp index fa7804d961..36f3aa3a13 100644 --- a/src/gromacs/gmxana/gmx_awh.cpp +++ b/src/gromacs/gmxana/gmx_awh.cpp @@ -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" diff --git a/src/gromacs/gmxana/gmx_dipoles.cpp b/src/gromacs/gmxana/gmx_dipoles.cpp index 169a028d2f..b3f237bf08 100644 --- a/src/gromacs/gmxana/gmx_dipoles.cpp +++ b/src/gromacs/gmxana/gmx_dipoles.cpp @@ -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" diff --git a/src/gromacs/gmxana/gmx_eneconv.cpp b/src/gromacs/gmxana/gmx_eneconv.cpp index 6b089b1dd3..8e82735738 100644 --- a/src/gromacs/gmxana/gmx_eneconv.cpp +++ b/src/gromacs/gmxana/gmx_eneconv.cpp @@ -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" diff --git a/src/gromacs/gmxana/gmx_enemat.cpp b/src/gromacs/gmxana/gmx_enemat.cpp index 23fd17953a..c58c92e4e9 100644 --- a/src/gromacs/gmxana/gmx_enemat.cpp +++ b/src/gromacs/gmxana/gmx_enemat.cpp @@ -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" diff --git a/src/gromacs/gmxana/gmx_energy.cpp b/src/gromacs/gmxana/gmx_energy.cpp index 77de9a3222..7b529e6403 100644 --- a/src/gromacs/gmxana/gmx_energy.cpp +++ b/src/gromacs/gmxana/gmx_energy.cpp @@ -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" diff --git a/src/gromacs/gmxana/gmx_lie.cpp b/src/gromacs/gmxana/gmx_lie.cpp index 9ba2b1b966..17dba3971f 100644 --- a/src/gromacs/gmxana/gmx_lie.cpp +++ b/src/gromacs/gmxana/gmx_lie.cpp @@ -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" diff --git a/src/gromacs/mdlib/coupling.cpp b/src/gromacs/mdlib/coupling.cpp index 4a1cc52eb1..94b44bc605 100644 --- a/src/gromacs/mdlib/coupling.cpp +++ b/src/gromacs/mdlib/coupling.cpp @@ -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" diff --git a/src/gromacs/mdlib/ebin.cpp b/src/gromacs/mdlib/ebin.cpp index 802c125306..0985f9e5dc 100644 --- a/src/gromacs/mdlib/ebin.cpp +++ b/src/gromacs/mdlib/ebin.cpp @@ -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" diff --git a/src/gromacs/mdlib/ebin.h b/src/gromacs/mdlib/ebin.h index 8f53f1648e..d1f29fc41c 100644 --- a/src/gromacs/mdlib/ebin.h +++ b/src/gromacs/mdlib/ebin.h @@ -40,7 +40,7 @@ #include #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. */ diff --git a/src/gromacs/mdlib/mdebin.cpp b/src/gromacs/mdlib/mdebin.cpp index 3dcd361ecc..a238548b92 100644 --- a/src/gromacs/mdlib/mdebin.cpp +++ b/src/gromacs/mdlib/mdebin.cpp @@ -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" diff --git a/src/gromacs/tools/check.cpp b/src/gromacs/tools/check.cpp index e9ab81b00f..8ce34d5a76 100644 --- a/src/gromacs/tools/check.cpp +++ b/src/gromacs/tools/check.cpp @@ -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" diff --git a/src/gromacs/tools/dump.cpp b/src/gromacs/tools/dump.cpp index 77ade93531..f5bec85997 100644 --- a/src/gromacs/tools/dump.cpp +++ b/src/gromacs/tools/dump.cpp @@ -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" diff --git a/src/gromacs/trajectory/CMakeLists.txt b/src/gromacs/trajectory/CMakeLists.txt index e6f9359307..b18cabb5db 100644 --- a/src/gromacs/trajectory/CMakeLists.txt +++ b/src/gromacs/trajectory/CMakeLists.txt @@ -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. @@ -33,10 +33,11 @@ # 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 index 781ec924ec..0000000000 --- a/src/gromacs/trajectory/energy.h +++ /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 index 0000000000..5629a3e78f --- /dev/null +++ b/src/gromacs/trajectory/energyframe.cpp @@ -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 + * \ingroup module_mdrun_integration_tests + */ +#include "gmxpre.h" + +#include "energyframe.h" + +#include +#include + +#include "gromacs/utility/exceptions.h" +#include "gromacs/utility/stringutil.h" + +namespace gmx +{ + +EnergyFrame::EnergyFrame(const t_enxframe &enxframe, + const std::map 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 index 0000000000..90d9eab538 --- /dev/null +++ b/src/gromacs/trajectory/energyframe.h @@ -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 +#include + +#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; + //! Convenience type + using MapConstIterator = MapType::const_iterator; + //! Constructor + EnergyFrame(const t_enxframe &enxframe, + const std::map 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 diff --git a/src/gromacs/trajectory/trajectoryframe.cpp b/src/gromacs/trajectory/trajectoryframe.cpp index 7508d1c7f4..68500a628b 100644 --- a/src/gromacs/trajectory/trajectoryframe.cpp +++ b/src/gromacs/trajectory/trajectoryframe.cpp @@ -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 TrajectoryFrame::x() const +{ + return arrayRefFromArray(reinterpret_cast(frame_.x), + frame_.natoms); +} + +ArrayRef TrajectoryFrame::v() const +{ + if (frame_.bV) + { + return arrayRefFromArray(reinterpret_cast(frame_.v), + frame_.natoms); + } + else + { + return EmptyArrayRef(); + } +} + +ArrayRef TrajectoryFrame::f() const +{ + if (frame_.bF) + { + return arrayRefFromArray(reinterpret_cast(frame_.f), + frame_.natoms); + } + else + { + return EmptyArrayRef(); + } +} + +bool TrajectoryFrame::hasBox() const +{ + return frame_.bBox; +} + +const BoxMatrix &TrajectoryFrame::box() const +{ + return box_; +} + +} // namespace gmx diff --git a/src/gromacs/trajectory/trajectoryframe.h b/src/gromacs/trajectory/trajectoryframe.h index 3901eaaef7..04fbf601ca 100644 --- a/src/gromacs/trajectory/trajectoryframe.h +++ b/src/gromacs/trajectory/trajectoryframe.h @@ -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. @@ -44,7 +44,10 @@ #include +#include + #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 , 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 x() const; + //! Get a view of velocity coordinates of the frame (which could be empty). + ArrayRef v() const; + //! Get a view of force coordinates of the frame (which could be empty). + ArrayRef 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 diff --git a/src/programs/mdrun/tests/energyreader.cpp b/src/programs/mdrun/tests/energyreader.cpp index 0fe91c7e1e..3edbc9ce9f 100644 --- a/src/programs/mdrun/tests/energyreader.cpp +++ b/src/programs/mdrun/tests/energyreader.cpp @@ -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 #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 &frames, @@ -231,15 +198,15 @@ void compareFrames(const std::pair &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(); } } } diff --git a/src/programs/mdrun/tests/energyreader.h b/src/programs/mdrun/tests/energyreader.h index b33af5466d..3b6bad900e 100644 --- a/src/programs/mdrun/tests/energyreader.h +++ b/src/programs/mdrun/tests/energyreader.h @@ -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 EnergyFrameReaderPtr; EnergyFrameReaderPtr openEnergyFileToReadFields(const std::string &filename, const std::vector &requiredEnergyFieldNames); -class EnergyFrame; - //! Convenience smart pointer typedef typedef unique_cptr 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 &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 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 &frames, - FloatingPointTolerance tolerance); -}; - } // namespace } // namespace diff --git a/src/programs/mdrun/tests/initialconstraints.cpp b/src/programs/mdrun/tests/initialconstraints.cpp index 2c077a769d..8441ef7a73 100644 --- a/src/programs/mdrun/tests/initialconstraints.cpp +++ b/src/programs/mdrun/tests/initialconstraints.cpp @@ -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 +#include "gromacs/trajectory/energyframe.h" #include "gromacs/utility/stringutil.h" #include "energyreader.h" diff --git a/src/programs/mdrun/tests/pmetest.cpp b/src/programs/mdrun/tests/pmetest.cpp index dc4cff55e1..287ebe9d2e 100644 --- a/src/programs/mdrun/tests/pmetest.cpp +++ b/src/programs/mdrun/tests/pmetest.cpp @@ -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) diff --git a/src/programs/mdrun/tests/trajectoryreader.cpp b/src/programs/mdrun/tests/trajectoryreader.cpp index fb237221b4..6dfdd28b08 100644 --- a/src/programs/mdrun/tests/trajectoryreader.cpp +++ b/src/programs/mdrun/tests/trajectoryreader.cpp @@ -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 &frames, @@ -190,30 +166,30 @@ void compareFrames(const std::pair &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(); } } } diff --git a/src/programs/mdrun/tests/trajectoryreader.h b/src/programs/mdrun/tests/trajectoryreader.h index 9184cb141b..b209015f13 100644 --- a/src/programs/mdrun/tests/trajectoryreader.h +++ b/src/programs/mdrun/tests/trajectoryreader.h @@ -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 oenv_ptr; //! Convenience smart pointer typedef @@ -150,26 +151,6 @@ typedef std::unique_ptr TrajectoryFrameReaderPtr; void compareFrames(const std::pair &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 -- 2.11.4.GIT