Permit comparison of only first frames
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 23 Sep 2020 14:56:57 +0000 (14:56 +0000)
committerPascal Merz <pascal.merz@me.com>
Wed, 23 Sep 2020 14:56:57 +0000 (14:56 +0000)
Integration tests of mdrun sometimes want to compare only the
quantities from the first frame of a trajectory.  This is now
permitted.

src/programs/mdrun/tests/comparison_helpers.h [new file with mode: 0644]
src/programs/mdrun/tests/energycomparison.cpp
src/programs/mdrun/tests/energycomparison.h
src/programs/mdrun/tests/exactcontinuation.cpp
src/programs/mdrun/tests/periodicactions.cpp
src/programs/mdrun/tests/rerun.cpp
src/programs/mdrun/tests/simulator.cpp
src/programs/mdrun/tests/simulatorcomparison.cpp
src/programs/mdrun/tests/trajectorycomparison.cpp
src/programs/mdrun/tests/trajectorycomparison.h

diff --git a/src/programs/mdrun/tests/comparison_helpers.h b/src/programs/mdrun/tests/comparison_helpers.h
new file mode 100644 (file)
index 0000000..0cde6c8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, 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 Declares types and functions common to comparing either
+ * energies or trajectories produced by mdrun.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun_integration_tests
+ */
+#ifndef GMX_PROGRAMS_MDRUN_TESTS_COMPARISON_HELPERS_H
+#define GMX_PROGRAMS_MDRUN_TESTS_COMPARISON_HELPERS_H
+
+namespace gmx
+{
+
+namespace test
+{
+
+//! Enumeration controlling which trajectory frames are compared
+enum class FramesToCompare : int
+{
+    AllFrames,
+    OnlyFirstFrame, // e.g. because step-0 quantities are most useful to compare
+    Count
+};
+
+} // namespace test
+} // namespace gmx
+
+#endif
index 3112960f90985fcd542dfdabffdfc07f89ab7faa..f32520330c36a1a6c8819054f85c2bcdcc0ceaee 100644 (file)
@@ -77,8 +77,10 @@ EnergyTermsToCompare EnergyComparison::defaultEnergyTermsToCompare()
     };
 };
 
-EnergyComparison::EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare) :
-    energyTermsToCompare_(energyTermsToCompare)
+EnergyComparison::EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare,
+                                   FramesToCompare             framesToCompare) :
+    energyTermsToCompare_(energyTermsToCompare),
+    framesToCompare_(framesToCompare)
 {
 }
 
@@ -95,6 +97,12 @@ std::vector<std::string> EnergyComparison::getEnergyNames() const
 
 void EnergyComparison::operator()(const EnergyFrame& reference, const EnergyFrame& test) const
 {
+    if (framesToCompare_ == FramesToCompare::OnlyFirstFrame && firstFrameHasBeenCompared_)
+    {
+        // Nothing should be compared
+        return;
+    }
+
     SCOPED_TRACE("Comparing energy reference frame " + reference.frameName() + " and test frame "
                  + test.frameName());
     for (auto referenceIt = reference.begin(); referenceIt != reference.end(); ++referenceIt)
@@ -114,6 +122,7 @@ void EnergyComparison::operator()(const EnergyFrame& reference, const EnergyFram
             ADD_FAILURE() << "Could not find energy component from reference frame in test frame";
         }
     }
+    firstFrameHasBeenCompared_ = true;
 }
 
 void checkEnergiesAgainstReferenceData(const std::string&          energyFilename,
@@ -124,7 +133,7 @@ void checkEnergiesAgainstReferenceData(const std::string&          energyFilenam
 
     if (thisRankChecks)
     {
-        EnergyComparison energyComparison(energyTermsToCompare);
+        EnergyComparison energyComparison(energyTermsToCompare, FramesToCompare::AllFrames);
         auto energyReader = openEnergyFileToReadTerms(energyFilename, energyComparison.getEnergyNames());
 
         std::unordered_map<std::string, TestReferenceChecker> checkers;
index c715e7acf5cd88f36ff51e9156a733c139c531d4..b43d45692d670b4e48e103cbd38c866fcecad942 100644 (file)
@@ -47,6 +47,8 @@
 
 #include "testutils/testasserts.h"
 
+#include "comparison_helpers.h"
+
 namespace gmx
 {
 
@@ -69,7 +71,7 @@ public:
     //! Defaults for energy comparisons
     static EnergyTermsToCompare defaultEnergyTermsToCompare();
     //! Constructor
-    EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare);
+    EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare, FramesToCompare framesToCompare);
     /*! \brief Return the names of energies that will be compared
      *
      * This function can be used to provide an input for
@@ -89,8 +91,18 @@ public:
      * key. */
     void operator()(const EnergyFrame& reference, const EnergyFrame& test) const;
 
+private:
     //! Energy terms to match with given tolerances.
     EnergyTermsToCompare energyTermsToCompare_;
+    //! Which frames should be compared.
+    FramesToCompare framesToCompare_ = FramesToCompare::AllFrames;
+    /*! \brief Whether the first frame has been compared yet
+     *
+     * This field is mutable because the need to update the flag
+     * after the first frame is merely an implementation detail,
+     * rather than a proper change of internal state triggered
+     * by the caller. */
+    mutable bool firstFrameHasBeenCompared_ = false;
 };
 
 /*! \brief Check a subset of the energies found in an energy file
index ca57f3422c548152063d2a7e634b04eacd614539..f3ff5f6279196825c11d38ab26eb71e1b3ea253f 100644 (file)
@@ -303,7 +303,7 @@ void runTest(TestFileManager*            fileManager,
 
     // Build the functor that will compare energy frames on the chosen
     // energy terms.
-    EnergyComparison energyComparison(energyTermsToCompare);
+    EnergyComparison energyComparison(energyTermsToCompare, FramesToCompare::AllFrames);
 
     // Build the manager that will present matching pairs of frames to compare.
     //
index 887d1a8d9ab7b6b4037e25f037e1df5ff3f1a03f..4f17a587959ce3f6efded8e74496c2238e1e9c0b 100644 (file)
@@ -106,7 +106,8 @@ public:
     //! Names for the output files from the reference mdrun call
     ReferenceFileNames referenceFileNames_ = { fileManager_.getTemporaryFilePath("reference.edr") };
     //! Functor for energy comparison
-    EnergyComparison energyComparison_{ EnergyComparison::defaultEnergyTermsToCompare() };
+    EnergyComparison energyComparison_{ EnergyComparison::defaultEnergyTermsToCompare(),
+                                        FramesToCompare::AllFrames };
     //! Names of energies compared by energyComparison_
     std::vector<std::string> namesOfEnergiesToMatch_ = energyComparison_.getEnergyNames();
 };
index 72b23235840b3a881b81945017f11f02be28543a..6f1946cfa3420545085d293f6daf1a0fef1c1e79 100644 (file)
@@ -105,7 +105,8 @@ const TrajectoryFrameMatchSettings MdrunRerunTest::trajectoryMatchSettings = {
     true,
     ComparisonConditions::MustCompare,
     ComparisonConditions::NoComparison,
-    ComparisonConditions::MustCompare
+    ComparisonConditions::MustCompare,
+    FramesToCompare::AllFrames
 };
 
 void executeRerunTest(TestFileManager*            fileManager,
index 94984490c679345fe3b435bc42a94f6cef1fd06d..004b31e2afb6e1f92f0d015ab87ee2a273d29b70 100644 (file)
@@ -157,7 +157,8 @@ TEST_P(SimulatorComparisonTest, WithinTolerances)
                                                           true,
                                                           ComparisonConditions::MustCompare,
                                                           ComparisonConditions::MustCompare,
-                                                          ComparisonConditions::MustCompare };
+                                                          ComparisonConditions::MustCompare,
+                                                          FramesToCompare::AllFrames };
     TrajectoryTolerances trajectoryTolerances = TrajectoryComparison::s_defaultTrajectoryTolerances;
     if (simulationName != "argon12")
     {
index f79f2ae6111cb0c8426da4b1bc194f703ac22875..64a841f16eb175c6292a6b22b9386c61d927fcf1 100644 (file)
@@ -90,7 +90,7 @@ void compareEnergies(const std::string&          edr1Name,
 {
     // Build the functor that will compare energy frames on the chosen
     // energy terms.
-    EnergyComparison energyComparison(energyTermsToCompare);
+    EnergyComparison energyComparison(energyTermsToCompare, FramesToCompare::AllFrames);
 
     // Build the manager that will present matching pairs of frames to compare.
     //
index e70fd92ec072be78e72f65d8d034f7e588ec9ef8..b4573bbeca10de29f28e1da3d6f0b4ce72da0ad7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, 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.
@@ -252,6 +252,11 @@ TrajectoryComparison::TrajectoryComparison(const TrajectoryFrameMatchSettings& m
 
 void TrajectoryComparison::operator()(const TrajectoryFrame& reference, const TrajectoryFrame& test) const
 {
+    if (matchSettings_.framesToCompare == FramesToCompare::OnlyFirstFrame && firstFrameHasBeenCompared_)
+    {
+        // Nothing should be compared
+        return;
+    }
     SCOPED_TRACE("Comparing trajectory reference frame " + reference.frameName()
                  + " and test frame " + test.frameName());
     EXPECT_EQ(reference.step(), test.step());
@@ -260,6 +265,7 @@ void TrajectoryComparison::operator()(const TrajectoryFrame& reference, const Tr
     compareCoordinates(reference, test, matchSettings_, tolerances_.coordinates);
     compareVelocities(reference, test, matchSettings_, tolerances_.velocities);
     compareForces(reference, test, matchSettings_, tolerances_.forces);
+    firstFrameHasBeenCompared_ = true;
 }
 
 } // namespace test
index 444336efe0d6e43805a9f2a74110f1bdb40ed617..187045baa66fce3870c93042c30c6249ed9bd03f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, 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.
@@ -45,6 +45,8 @@
 
 #include "testutils/testasserts.h"
 
+#include "comparison_helpers.h"
+
 namespace gmx
 {
 
@@ -97,6 +99,8 @@ struct TrajectoryFrameMatchSettings
     ComparisonConditions velocitiesComparison = ComparisonConditions::CompareIfBothFound;
     //! Whether forces must be compared.
     ComparisonConditions forcesComparison = ComparisonConditions::CompareIfBothFound;
+    //! Which frames will be compared
+    FramesToCompare framesToCompare = FramesToCompare::AllFrames;
 };
 
 /*! \internal
@@ -124,10 +128,19 @@ public:
     /*! \brief Compare reference with test given the \c
      * matchSettings_ within \c tolerances_ */
     void operator()(const TrajectoryFrame& reference, const TrajectoryFrame& test) const;
+
+private:
     //! Specifies expected behavior in comparisons
     TrajectoryFrameMatchSettings matchSettings_;
     //! Trajectory fields to match with given tolerances.
     TrajectoryTolerances tolerances_;
+    /*! \brief Whether the first frame has been compared yet
+     *
+     * This field is mutable because the need to update the flag
+     * after the first frame is merely an implementation detail,
+     * rather than a proper change of internal state triggered
+     * by the caller. */
+    mutable bool firstFrameHasBeenCompared_ = false;
 };
 
 } // namespace test