AnalysisTemplate::AnalysisTemplate()
: options_("template", "Template options"), cutoff_(0.0)
{
+ registerAnalysisDataset(&data_, "avedist");
}
const TopologyInformation & /*top*/)
{
data_.setColumnCount(sel_.size());
- registerAnalysisDataset(&data_, "avedist");
avem_.reset(new AnalysisDataAverageModule());
data_.addModule(avem_);
_bSplit1(false), _bSplit2(false), _bMulti(false), _bAll(false),
_bDumpDist(false), _natoms1(0), _natoms2(0), _vt0(NULL)
{
+ registerAnalysisDataset(&_data, "angle");
}
_vt0 = new rvec[na];
}
- registerAnalysisDataset(&_data, "angle");
-
AnalysisDataPlotModulePointer plotm(
new AnalysisDataPlotModule(settings.plotSettings()));
plotm->setFileName(_fnAngle);
Distance::Distance()
: _options(name, shortDescription), _avem(new AnalysisDataAverageModule())
{
+ _data.setColumnCount(4);
+ registerAnalysisDataset(&_data, "distance");
}
{
GMX_THROW(InvalidInputError("The second selection does not define a single position"));
}
- _data.setColumnCount(4);
- registerAnalysisDataset(&_data, "distance");
_data.addModule(_avem);
AnalysisDataPlotModulePointer _plotm(new AnalysisDataPlotModule());
_bDump(false), _bTotNorm(false), _bFracNorm(false), _bResInd(false),
_top(NULL)
{
+ registerAnalysisDataset(&_sdata, "size");
+ registerAnalysisDataset(&_cdata, "cfrac");
+ _idata.setColumnCount(2);
+ _idata.setMultipoint(true);
+ registerAnalysisDataset(&_idata, "index");
+ registerAnalysisDataset(&_mdata, "mask");
}
// TODO: For large systems, a float may not have enough precision
_sdata.setColumnCount(_sel.size());
- registerAnalysisDataset(&_sdata, "size");
_totsize.reserve(_sel.size());
for (size_t g = 0; g < _sel.size(); ++g)
{
}
_cdata.setColumnCount(_sel.size());
- registerAnalysisDataset(&_cdata, "cfrac");
if (!_fnFrac.empty())
{
AnalysisDataPlotModulePointer plot(
}
// TODO: For large systems, a float may not have enough precision
- _idata.setColumnCount(2);
- _idata.setMultipoint(true);
- registerAnalysisDataset(&_idata, "index");
if (!_fnIndex.empty())
{
AnalysisDataPlotModulePointer plot(
}
_mdata.setColumnCount(_sel[0].posCount());
- registerAnalysisDataset(&_mdata, "mask");
if (!_fnMask.empty())
{
if (_sel.size() > 1U)
+gmx_add_unit_test(TrajectoryAnalysisUnitTests trajectoryanalysis-test
+ moduletest.cpp
+ select.cpp)
+
add_executable(test_selection test_selection.cpp)
target_link_libraries(test_selection libgromacs)
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes in moduletest.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_trajectoryanalysis
+ */
+#include "moduletest.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "gromacs/trajectoryanalysis/analysismodule.h"
+#include "gromacs/trajectoryanalysis/cmdlinerunner.h"
+#include "gromacs/utility/file.h"
+
+#include "testutils/cmdlinetest.h"
+#include "testutils/datapath.h"
+#include "testutils/datatest.h"
+#include "testutils/refdata.h"
+
+namespace gmx
+{
+namespace test
+{
+
+/********************************************************************
+ * AbstractTrajectoryAnalysisModuleTestFixture::Impl
+ */
+
+class AbstractTrajectoryAnalysisModuleTestFixture::Impl
+{
+ public:
+ struct OutputFileInfo
+ {
+ OutputFileInfo(const char *option, const std::string &path)
+ : option(option), path(path)
+ {
+ }
+
+ std::string option;
+ std::string path;
+ };
+
+ typedef std::set<std::string> DatasetNames;
+ typedef std::vector<OutputFileInfo> OutputFileList;
+
+ explicit Impl(AbstractTrajectoryAnalysisModuleTestFixture *parent);
+
+ TrajectoryAnalysisModule &module();
+ void ensureModuleCreated();
+
+ AbstractTrajectoryAnalysisModuleTestFixture &parent_;
+ TrajectoryAnalysisModulePointer module_;
+ TestReferenceData data_;
+ CommandLine cmdline_;
+ TestFileManager tempFiles_;
+ DatasetNames moduleDatasets_;
+ DatasetNames outputDatasets_;
+ OutputFileList outputFiles_;
+ bool bDatasetsIncluded_;
+};
+
+AbstractTrajectoryAnalysisModuleTestFixture::Impl::Impl(
+ AbstractTrajectoryAnalysisModuleTestFixture *parent)
+ : parent_(*parent), bDatasetsIncluded_(false)
+{
+ cmdline_.append("module");
+ cmdline_.append("-quiet");
+}
+
+TrajectoryAnalysisModule &
+AbstractTrajectoryAnalysisModuleTestFixture::Impl::module()
+{
+ ensureModuleCreated();
+ return *module_;
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::Impl::ensureModuleCreated()
+{
+ if (module_.get() == NULL)
+ {
+ module_ = parent_.createModule();
+ const std::vector<std::string> &datasetNames(module_->datasetNames());
+ moduleDatasets_.clear();
+ moduleDatasets_.insert(datasetNames.begin(), datasetNames.end());
+ outputDatasets_ = moduleDatasets_;
+ }
+}
+
+/********************************************************************
+ * AbstractTrajectoryAnalysisModuleTestFixture
+ */
+
+AbstractTrajectoryAnalysisModuleTestFixture::AbstractTrajectoryAnalysisModuleTestFixture()
+ : impl_(new Impl(this))
+{
+}
+
+AbstractTrajectoryAnalysisModuleTestFixture::~AbstractTrajectoryAnalysisModuleTestFixture()
+{
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::setTopology(const char *filename)
+{
+ impl_->cmdline_.append("-s");
+ impl_->cmdline_.append(TestFileManager::getTestFilePath(filename));
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::setTrajectory(const char *filename)
+{
+ impl_->cmdline_.append("-f");
+ impl_->cmdline_.append(TestFileManager::getTestFilePath(filename));
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::setOutputFile(const char *option,
+ const char *filename)
+{
+ std::string fullFilename = impl_->tempFiles_.getTemporaryFilePath(filename);
+ impl_->cmdline_.append(option);
+ impl_->cmdline_.append(fullFilename);
+ impl_->outputFiles_.push_back(Impl::OutputFileInfo(option, fullFilename));
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::includeDataset(const char *name)
+{
+ impl_->ensureModuleCreated();
+ if (!impl_->bDatasetsIncluded_)
+ {
+ impl_->outputDatasets_.clear();
+ }
+ bool bFound = (impl_->moduleDatasets_.find(name) != impl_->moduleDatasets_.end());
+ GMX_RELEASE_ASSERT(bFound, "Attempted to include a non-existent dataset");
+ impl_->outputDatasets_.insert(name);
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::excludeDataset(const char *name)
+{
+ impl_->ensureModuleCreated();
+ bool bFound = (impl_->outputDatasets_.erase(name) > 0);
+ GMX_RELEASE_ASSERT(bFound, "Attempted to exclude a non-existent dataset");
+}
+
+void
+AbstractTrajectoryAnalysisModuleTestFixture::runTest(const CommandLine &args)
+{
+ TrajectoryAnalysisModule &module = impl_->module();
+ // Skip first argument if it is the module name.
+ int firstArg = (args.arg(0)[0] == '-' ? 0 : 1);
+ for (int i = firstArg; i < args.argc(); ++i)
+ {
+ impl_->cmdline_.append(args.arg(i));
+ }
+
+ TestReferenceChecker rootChecker(impl_->data_.rootChecker());
+
+ rootChecker.checkString(args.toString(), "CommandLine");
+
+ if (!impl_->outputDatasets_.empty())
+ {
+ TestReferenceChecker dataChecker(
+ rootChecker.checkCompound("OutputData", "Data"));
+ Impl::DatasetNames::const_iterator dataset;
+ for (dataset = impl_->outputDatasets_.begin();
+ dataset != impl_->outputDatasets_.end();
+ ++dataset)
+ {
+ const char *name = dataset->c_str();
+ AbstractAnalysisData &dataset = module.datasetFromName(name);
+ AnalysisDataTestFixture::addReferenceCheckerModule(
+ dataChecker, name, &dataset);
+ }
+ }
+
+ TrajectoryAnalysisCommandLineRunner runner(&module);
+ runner.setPrintCopyright(false);
+ int rc = 0;
+ EXPECT_NO_THROW(rc = runner.run(impl_->cmdline_.argc(), impl_->cmdline_.argv()));
+ EXPECT_EQ(0, rc);
+
+ if (!impl_->outputFiles_.empty())
+ {
+ TestReferenceChecker outputChecker(
+ rootChecker.checkCompound("OutputFiles", "Files"));
+ Impl::OutputFileList::const_iterator outfile;
+ for (outfile = impl_->outputFiles_.begin();
+ outfile != impl_->outputFiles_.end();
+ ++outfile)
+ {
+ std::string output = File::readToString(outfile->path);
+ outputChecker.checkStringBlock(output, outfile->option.c_str());
+ }
+ }
+}
+
+} // namespace test
+} // namespace gmx
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \internal \file
+ * \brief
+ * Declares test fixture for TrajectoryAnalysisModule subclasses.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_trajectoryanalysis
+ */
+#ifndef GMX_TRAJECTORYANALYSIS_TESTS_MODULETEST_H
+#define GMX_TRAJECTORYANALYSIS_TESTS_MODULETEST_H
+
+#include <gtest/gtest.h>
+
+#include "gromacs/trajectoryanalysis/analysismodule.h"
+#include "gromacs/utility/common.h"
+
+namespace gmx
+{
+
+class TrajectoryAnalysisModule;
+
+namespace test
+{
+
+class CommandLine;
+
+/*! \internal \brief
+ * Test fixture for trajectory analysis modules.
+ *
+ * This class implements common logic for all tests for trajectory analysis
+ * modules. The tests simply need to specify the type of the module to test,
+ * input files and any additional options, names of datasets to test (if not
+ * all), and possible output files to explicitly test by calling the different
+ * methods in this class. runTest() then runs the specified module with the
+ * given options and performs all the requested tests against reference data.
+ *
+ * The actual module to be tested is constructed in the pure virtual
+ * createModule() method, which should be implemented in a subclass.
+ * Typically, the TrajectoryAnalysisModuleTestFixture template can be used.
+ *
+ * Any method in this class may throw std::bad_alloc if out of memory.
+ *
+ * \ingroup module_trajectoryanalysis
+ */
+class AbstractTrajectoryAnalysisModuleTestFixture : public ::testing::Test
+{
+ public:
+ AbstractTrajectoryAnalysisModuleTestFixture();
+ virtual ~AbstractTrajectoryAnalysisModuleTestFixture();
+
+ /*! \brief
+ * Sets the topology file to use for the test.
+ *
+ * \param[in] filename Name of input topology file.
+ *
+ * \p filename is interpreted relative to the test input data
+ * directory, see getTestDataPath().
+ *
+ * Must be called at most once. Either this method or setTrajectory()
+ * must be called before runTest().
+ */
+ void setTopology(const char *filename);
+ /*! \brief
+ * Sets the trajectory file to use for the test.
+ *
+ * \param[in] filename Name of input trajectory file.
+ *
+ * \p filename is interpreted relative to the test input data
+ * directory, see getTestDataPath().
+ *
+ * Must be called at most once. Either this method or setTopology()
+ * must be called before runTest().
+ */
+ void setTrajectory(const char *filename);
+ /*! \brief
+ * Sets an output file to use for the test.
+ *
+ * \param[in] option Option to set.
+ * \param[in] filename Name of the output file.
+ *
+ * This method:
+ * - Sets \p option in the tested module to a temporary file name
+ * constructed from \p filename.
+ * - Makes runTest() to check the contents of the file against
+ * reference data after running the module.
+ * - Marks the temporary file for removal at test teardown.
+ *
+ * \p filename is given to TestTemporaryFileManager to make a unique
+ * filename for the temporary file, but is not otherwise used.
+ *
+ * Currently, this method should not be called for an XVG file, because
+ * the comments in the beginning of the file contain timestamps and
+ * other variable information, causing the test to fail. Best used
+ * only for custom data formats. For numeric data, testing the
+ * underlying dataset is typically sufficient.
+ */
+ void setOutputFile(const char *option, const char *filename);
+ /*! \brief
+ * Includes only specified dataset for the test.
+ *
+ * \param[in] name Name of dataset to include.
+ *
+ * If this method is not called, all datasets are tested by default.
+ * If called once, only the specified dataset is tested.
+ * If called more than once, also the additional datasets are tested.
+ *
+ * \p name should be one of the names registered for the tested module
+ * using TrajectoryAnalysisModule::registerBasicDataset() or
+ * TrajectoryAnalysisModule::registerAnalysisDataset().
+ */
+ void includeDataset(const char *name);
+ /*! \brief
+ * Excludes specified dataset from the test.
+ *
+ * \param[in] name Name of dataset to exclude.
+ *
+ * If includeDataset() has been called, \p name must be one of the
+ * included datasets.
+ *
+ * \p name should be one of the names registered for the tested module
+ * using TrajectoryAnalysisModule::registerBasicDataset() or
+ * TrajectoryAnalysisModule::registerAnalysisDataset().
+ */
+ void excludeDataset(const char *name);
+
+ /*! \brief
+ * Runs the analysis module with the given additional options.
+ *
+ * \param[in] args Options to provide to the module.
+ *
+ * \p args should be formatted as command-line options, and contain the
+ * name of the module as the first argument (the latter requirement is
+ * for clarity only). They are passed to the module in addition to
+ * those specified using other methods in this class.
+ *
+ * All other methods should be called before calling this method.
+ *
+ * Exceptions thrown by the module are caught by this method.
+ */
+ void runTest(const CommandLine &args);
+
+ protected:
+ /*! \brief
+ * Constructs the analysis module to be tested.
+ */
+ virtual TrajectoryAnalysisModulePointer createModule() = 0;
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
+/*! \internal \brief
+ * Test fixture for a trajectory analysis module.
+ *
+ * \tparam ModuleType Type of the analysis module to test.
+ *
+ * \p ModuleType should derive from TrajectoryAnalysisModule and be
+ * default-constructible.
+ *
+ * \ingroup module_trajectoryanalysis
+ */
+template <class ModuleType>
+class TrajectoryAnalysisModuleTestFixture
+ : public AbstractTrajectoryAnalysisModuleTestFixture
+{
+ protected:
+ virtual TrajectoryAnalysisModulePointer createModule()
+ {
+ return TrajectoryAnalysisModulePointer(new ModuleType);
+ }
+};
+
+} // namespace test
+} // namespace gmx
+
+#endif
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="CommandLine">select -select 'y < 2.5' 'resname RA'</String>
+ <OutputData Name="Data">
+ <AnalysisData Name="index">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">0</Int>
+ <Int Name="LastColumn">0</Int>
+ <DataValue>
+ <Real Name="Value">8.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">2.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">5.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">6.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">9.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">10.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">13.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">14.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">0</Int>
+ <Int Name="LastColumn">0</Int>
+ <DataValue>
+ <Real Name="Value">6.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">2.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">3.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">7.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">8.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">9.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ <AnalysisData Name="mask">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">15</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ <AnalysisData Name="size">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">2</Int>
+ <DataValue>
+ <Real Name="Value">8.000000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">6.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ </OutputData>
+ <OutputFiles Name="Files">
+ <String Name="-oi"><![CDATA[
+ 0.000 8 1 2 5 6 9 10 13 14 6 1 2 3 7 8 9
+]]></String>
+ <String Name="-on"><![CDATA[
+[ y_<_2.5_f0_t0.000 ]
+ 1 2 5 6 9 10 13 14
+
+[ resname_RA ]
+ 1 2 3 7 8 9
+]]></String>
+ </OutputFiles>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="CommandLine">select -select 'y < 2.5' -dump</String>
+ <OutputData Name="Data">
+ <AnalysisData Name="index">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">0</Int>
+ <Int Name="LastColumn">0</Int>
+ <DataValue>
+ <Real Name="Value">8.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">2.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">5.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">6.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">9.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">10.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">13.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">14.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ </OutputData>
+ <OutputFiles Name="Files">
+ <String Name="-oi"><![CDATA[
+ 1 2 5 6 9 10 13 14
+]]></String>
+ </OutputFiles>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="CommandLine">select -select 'y < 2.5' 'resname RA and y < 2.5' 'resname RA' -norm</String>
+ <OutputData Name="Data">
+ <AnalysisData Name="size">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">3</Int>
+ <DataValue>
+ <Real Name="Value">0.533333</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">0.500000</Real>
+ </DataValue>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ </OutputData>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="CommandLine">select -select 'res_com of resname RA RD' -resnr index</String>
+ <OutputData Name="Data">
+ <AnalysisData Name="index">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">0</Int>
+ <Int Name="LastColumn">0</Int>
+ <DataValue>
+ <Real Name="Value">3.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">3.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">5.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ </OutputData>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="CommandLine">select -select 'res_com of resname RA RD'</String>
+ <OutputData Name="Data">
+ <AnalysisData Name="index">
+ <DataFrame Name="Frame0">
+ <Real Name="X">0.000000</Real>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">0</Int>
+ <Int Name="LastColumn">0</Int>
+ <DataValue>
+ <Real Name="Value">3.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">2.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">4.000000</Real>
+ </DataValue>
+ </Sequence>
+ <Sequence Name="Y">
+ <Int Name="Length">1</Int>
+ <Int Name="FirstColumn">1</Int>
+ <Int Name="LastColumn">1</Int>
+ <DataValue>
+ <Real Name="Value">1.000000</Real>
+ </DataValue>
+ </Sequence>
+ </DataFrame>
+ </AnalysisData>
+ </OutputData>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+This file is currently duplicated to each directory containing reference data
+XML files. This is to make it compatible with more browsers.
+To keep these files in sync, please only modify the version in
+ src/testutils/
+and use the copy_xsl.sh script to copy it to relevant locations.
+-->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:import href="common-referencedata.xsl"/>
+
+<xsl:template match="AnalysisData">
+ <xsl:variable name="has-columnspec"
+ select="DataFrame/Sequence[@Name='Y']/Int[@Name='FirstColumn']"/>
+ <table border="1">
+ <tr>
+ <th>Frame</th>
+ <th>X</th>
+ <xsl:if test="$has-columnspec">
+ <th>Columns</th>
+ </xsl:if>
+ <th>Values</th>
+ </tr>
+ <xsl:for-each select="DataFrame/Sequence[@Name='Y']">
+ <tr>
+ <td><xsl:value-of select="../@Name"/></td>
+ <td><xsl:value-of select="../Real[@Name='X']"/></td>
+ <xsl:if test="$has-columnspec">
+ <td>
+ <xsl:choose>
+ <xsl:when test="Int[@Name='FirstColumn']">
+ <xsl:value-of select="Int[@Name='FirstColumn']"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="Int[@Name='LastColumn']"/>
+ </xsl:when>
+ <xsl:otherwise>all</xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:if>
+ <td><xsl:call-template name="SequenceAsCSV"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+</xsl:template>
+
+<xsl:template match="DataValue">
+ <xsl:value-of select="Real[@Name='Value']"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+This file is currently duplicated to each directory containing reference data
+XML files. This is to make it compatible with more browsers.
+To keep these files in sync, please only modify the version in
+ src/testutils/
+and use the copy_xsl.sh script to copy it to relevant locations.
+-->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/">
+ <html><body>
+ <xsl:apply-templates/>
+ </body></html>
+</xsl:template>
+
+<xsl:template match="/ReferenceData">
+ <h1>Test Reference Data</h1>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="Vector">
+ (<xsl:value-of select="*[@Name='X']"/>;
+ <xsl:value-of select="*[@Name='Y']"/>;
+ <xsl:value-of select="*[@Name='Z']"/>)
+</xsl:template>
+
+<xsl:template name="SequenceAsHorizontalTable">
+ <xsl:param name="root" select="."/>
+ <table border="1">
+ <tr><th>Count</th><th>Items</th></tr>
+ <tr>
+ <td><xsl:value-of select="$root/Int[@Name='Length']"/></td>
+ <td>
+ <xsl:call-template name="SequenceAsCSV">
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+</xsl:template>
+
+<xsl:template name="SequenceAsCSV">
+ <xsl:param name="root" select="."/>
+ <xsl:for-each select="$root/*">
+ <xsl:if test="not(.[@Name])">
+ <xsl:apply-templates select="."/>
+ <xsl:if test="position() < last()">, </xsl:if>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="Bool">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template name="String">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template name="Int">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template name="Real">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:import href="common-referencedata.xsl"/>
+<xsl:import href="analysisdata-referencedata.xsl"/>
+
+<xsl:template match="String[@Name='CommandLine']">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template match="OutputData">
+ <h2>Raw Output Data</h2>
+ <xsl:apply-templates />
+</xsl:template>
+
+<xsl:template match="AnalysisData">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <xsl:apply-imports />
+</xsl:template>
+
+<xsl:template match="OutputFiles">
+ <h2>Output Files</h2>
+ <xsl:for-each select="*">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <pre>
+ <xsl:value-of select="."/>
+ </pre>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \internal \file
+ * \brief
+ * Tests for functionality of the "select" trajectory analysis module.
+ *
+ * These tests test most of the functionality of the module, but currently
+ * missing are:
+ * - Tests related to -oc output. This would require a more complex input
+ * structure for reasonable testing (the same structure could also be used
+ * in selection unit tests for 'insolidangle' keyword).
+ * - Tests for XVG labels. This is a limitation of the current testing
+ * framework.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_trajectoryanalysis
+ */
+#include <gtest/gtest.h>
+
+#include "gromacs/trajectoryanalysis/modules/select.h"
+
+#include "testutils/cmdlinetest.h"
+
+#include "moduletest.h"
+
+namespace
+{
+
+using gmx::test::CommandLine;
+
+/********************************************************************
+ * Tests for gmx::analysismodules::Select.
+ */
+
+typedef gmx::test::TrajectoryAnalysisModuleTestFixture<gmx::analysismodules::Select>
+ SelectModuleTest;
+
+TEST_F(SelectModuleTest, BasicTest)
+{
+ const char *const cmdline[] = {
+ "select",
+ "-select", "y < 2.5", "resname RA"
+ };
+ setTopology("simple.gro");
+ setOutputFile("-oi", "index.dat");
+ setOutputFile("-on", "index.ndx");
+ excludeDataset("cfrac");
+ runTest(CommandLine::create(cmdline));
+}
+
+TEST_F(SelectModuleTest, HandlesDumpOption)
+{
+ const char *const cmdline[] = {
+ "select",
+ "-select", "y < 2.5",
+ "-dump"
+ };
+ setTopology("simple.gro");
+ setOutputFile("-oi", "index.dat");
+ includeDataset("index");
+ runTest(CommandLine::create(cmdline));
+}
+
+TEST_F(SelectModuleTest, NormalizesSizes)
+{
+ const char *const cmdline[] = {
+ "select",
+ "-select", "y < 2.5", "resname RA and y < 2.5", "resname RA",
+ "-norm"
+ };
+ setTopology("simple.gro");
+ includeDataset("size");
+ runTest(CommandLine::create(cmdline));
+}
+
+TEST_F(SelectModuleTest, WritesResidueNumbers)
+{
+ const char *const cmdline[] = {
+ "select",
+ "-select", "res_com of resname RA RD"
+ };
+ setTopology("simple.gro");
+ includeDataset("index");
+ runTest(CommandLine::create(cmdline));
+}
+
+TEST_F(SelectModuleTest, WritesResidueIndices)
+{
+ const char *const cmdline[] = {
+ "select",
+ "-select", "res_com of resname RA RD",
+ "-resnr", "index"
+ };
+ setTopology("simple.gro");
+ includeDataset("index");
+ runTest(CommandLine::create(cmdline));
+}
+
+} // namespace
--- /dev/null
+Test system
+ 15
+ 2RA CB 1 1.000 1.000 0.000
+ 2RA S1 2 1.000 2.000 0.000
+ 2RA S2 3 1.000 3.000 0.000
+ 3RB CB 4 1.000 4.000 0.000
+ 3RB S1 5 2.000 1.000 0.000
+ 3RB S2 6 2.000 2.000 0.000
+ 4RA CB 7 2.000 3.000 0.000
+ 4RA S1 8 2.000 4.000 0.000
+ 4RA S2 9 3.000 1.000 0.000
+ 5RC CB 10 3.000 2.000 0.000
+ 5RC S1 11 3.000 3.000 0.000
+ 5RC S2 12 3.000 4.000 0.000
+ 1RD CB 13 4.000 1.000 0.000
+ 1RD S1 14 4.000 2.000 0.000
+ 1RD S2 15 4.000 3.000 0.000
+ 10.00000 10.00000 10.00000
cd `dirname $0`
cd ../../
-for destdir in analysisdata selection ; do
+for destdir in analysisdata selection trajectoryanalysis ; do
cp -f src/testutils/common-referencedata.xsl \
src/gromacs/$destdir/tests/refdata/
done
-for destdir in analysisdata ; do
+for destdir in analysisdata trajectoryanalysis ; do
cp -f src/testutils/analysisdata-referencedata.xsl \
src/gromacs/$destdir/tests/refdata/
done
void
-AnalysisDataTestFixture::addReferenceCheckerModule(const TestReferenceChecker &checker,
+AnalysisDataTestFixture::addReferenceCheckerModule(TestReferenceChecker checker,
+ const char *id,
AbstractAnalysisData *source)
{
MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0));
- module->setupReferenceCheck(checker, source);
+ module->setupReferenceCheck(checker.checkCompound("AnalysisData", id), source);
source->addModule(module);
}
AnalysisDataTestFixture::addReferenceCheckerModule(const char *id,
AbstractAnalysisData *source)
{
- TestReferenceChecker checker(data_.rootChecker().checkCompound("AnalysisData", id));
- addReferenceCheckerModule(checker, source);
+ addReferenceCheckerModule(data_.rootChecker(), id, source);
}
} // namespace test
* Adds a mock module that verifies output against reference data.
*
* \param[in] checker Reference data checker to use for comparison.
+ * \param[in] id Identifier for reference data compound to use.
* \param source Data object to verify.
*
* Creates a mock module that verifies that the
* AnalysisDataModuleInterface methods are called correctly by
* \p source. Parameters for the calls are verified against reference
- * data using \p checker.
+ * data using a child compound \p id of \p checker.
* Adds the created module to \p source using \p data->addModule().
* Any exceptions from the called functions should be caught by the
* caller.
*
* \see TestReferenceData
*/
- static void addReferenceCheckerModule(const TestReferenceChecker &checker,
+ static void addReferenceCheckerModule(TestReferenceChecker checker,
+ const char *id,
AbstractAnalysisData *source);
/*! \brief