From: David van der Spoel Date: Thu, 28 Mar 2013 16:25:38 +0000 (+0100) Subject: New analysis tool to compute the free volume and total volume. X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=13d8138935594153868d73aac6404cdd41482964;p=alexxy%2Fgromacs.git New analysis tool to compute the free volume and total volume. Works with selections, such that the freevolume in a box containing a subset of all atoms can be computed. Added excessive comments so that others can use this as a reference for implementing analysis tools as well. Added a test system as well, but this is somewhat tricky due to real precision and the Monte Carlo algorithm. literature reference. valgrind. Change-Id: I2acb48b829c9495e399c60e9dc927662e2958d69 --- diff --git a/src/gromacs/gmxlib/rmpbc.c b/src/gromacs/gmxlib/rmpbc.c index 70b70dc632..3560c53e07 100644 --- a/src/gromacs/gmxlib/rmpbc.c +++ b/src/gromacs/gmxlib/rmpbc.c @@ -138,6 +138,7 @@ void gmx_rmpbc_done(gmx_rmpbc_t gpbc) for (i = 0; i < gpbc->ngraph; i++) { done_graph(gpbc->graph[i].gr); + sfree(gpbc->graph[i].gr); } if (gpbc->graph != NULL) { diff --git a/src/gromacs/gmxlib/tpxio.c b/src/gromacs/gmxlib/tpxio.c index 9cf04d86de..c94caa3cf8 100644 --- a/src/gromacs/gmxlib/tpxio.c +++ b/src/gromacs/gmxlib/tpxio.c @@ -2099,6 +2099,10 @@ static void do_block(t_fileio *fio, t_block *block, gmx_bool bRead, int file_ver } if (bRead) { + if ((block->nalloc_index > 0) && (NULL != block->index)) + { + sfree(block->index); + } block->nalloc_index = block->nr+1; snew(block->index, block->nalloc_index); } @@ -2855,6 +2859,7 @@ static void do_mtop(t_fileio *fio, gmx_mtop_t *mtop, gmx_bool bRead, { if (file_version >= 57) { + done_block(&mtop->mols); mtop->mols = mtop_mols(mtop); } if (gmx_debug_at) @@ -3436,6 +3441,27 @@ gmx_bool fn2bTPX(const char *file) } } +static void done_gmx_groups_t(gmx_groups_t *g) +{ + int i; + + for (i = 0; (i < egcNR); i++) + { + if (NULL != g->grps[i].nm_ind) + { + sfree(g->grps[i].nm_ind); + g->grps[i].nm_ind = NULL; + } + if (NULL != g->grpnr[i]) + { + sfree(g->grpnr[i]); + g->grpnr[i] = NULL; + } + } + /* The contents of this array is in symtab, don't free it here */ + sfree(g->grpname); +} + gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *ePBC, rvec **x, rvec **v, matrix box, gmx_bool bMass) { @@ -3463,6 +3489,8 @@ gmx_bool read_tps_conf(const char *infile, char *title, t_topology *top, int *eP *ePBC = read_tpx(infile, NULL, box, &natoms, (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, NULL, mtop); *top = gmx_mtop_t_to_t_topology(mtop); + /* In this case we need to throw away the group data too */ + done_gmx_groups_t(&mtop->groups); sfree(mtop); strcpy(title, *top->name); tpx_make_chain_identifiers(&top->atoms, &top->mols); diff --git a/src/gromacs/gmxlib/typedefs.c b/src/gromacs/gmxlib/typedefs.c index cc90ecb549..82d2b4a5fd 100644 --- a/src/gromacs/gmxlib/typedefs.c +++ b/src/gromacs/gmxlib/typedefs.c @@ -651,6 +651,16 @@ void done_state(t_state *state) sfree(state->cg_gl); } state->cg_gl_nalloc = 0; + if (state->lambda) + { + sfree(state->lambda); + } + if (state->ngtc > 0) + { + sfree(state->nosehoover_xi); + sfree(state->nosehoover_vxi); + sfree(state->therm_integral); + } } static void do_box_rel(t_inputrec *ir, matrix box_rel, matrix b, gmx_bool bInit) diff --git a/src/gromacs/legacyheaders/vec.h b/src/gromacs/legacyheaders/vec.h index fd86b8c942..85d887754c 100644 --- a/src/gromacs/legacyheaders/vec.h +++ b/src/gromacs/legacyheaders/vec.h @@ -114,6 +114,21 @@ #include "physics.h" #ifdef __cplusplus + +static gmx_inline real det(const matrix a) +{ + return ( a[XX][XX]*(a[YY][YY]*a[ZZ][ZZ]-a[ZZ][YY]*a[YY][ZZ]) + -a[YY][XX]*(a[XX][YY]*a[ZZ][ZZ]-a[ZZ][YY]*a[XX][ZZ]) + +a[ZZ][XX]*(a[XX][YY]*a[YY][ZZ]-a[YY][YY]*a[XX][ZZ])); +} + +static gmx_inline void mvmul(const matrix a, const rvec src, rvec dest) +{ + dest[XX] = a[XX][XX]*src[XX]+a[XX][YY]*src[YY]+a[XX][ZZ]*src[ZZ]; + dest[YY] = a[YY][XX]*src[XX]+a[YY][YY]*src[YY]+a[YY][ZZ]*src[ZZ]; + dest[ZZ] = a[ZZ][XX]*src[XX]+a[ZZ][YY]*src[YY]+a[ZZ][ZZ]*src[ZZ]; +} + extern "C" { #elif 0 } /* avoid screwing up indentation */ @@ -709,6 +724,7 @@ static gmx_inline real det(matrix a) +a[ZZ][XX]*(a[XX][YY]*a[YY][ZZ]-a[YY][YY]*a[XX][ZZ])); } + static gmx_inline void m_add(matrix a, matrix b, matrix dest) { dest[XX][XX] = a[XX][XX]+b[XX][XX]; @@ -801,6 +817,7 @@ static gmx_inline void mvmul(matrix a, const rvec src, rvec dest) dest[ZZ] = a[ZZ][XX]*src[XX]+a[ZZ][YY]*src[YY]+a[ZZ][ZZ]*src[ZZ]; } + static gmx_inline void mvmul_ur0(matrix a, const rvec src, rvec dest) { dest[ZZ] = a[ZZ][XX]*src[XX]+a[ZZ][YY]*src[YY]+a[ZZ][ZZ]*src[ZZ]; diff --git a/src/gromacs/trajectoryanalysis/modules.cpp b/src/gromacs/trajectoryanalysis/modules.cpp index 428c88af07..b5770a4878 100644 --- a/src/gromacs/trajectoryanalysis/modules.cpp +++ b/src/gromacs/trajectoryanalysis/modules.cpp @@ -47,6 +47,7 @@ #include "modules/angle.h" #include "modules/distance.h" +#include "modules/freevolume.h" #include "modules/select.h" namespace gmx @@ -128,6 +129,7 @@ void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager) using namespace gmx::analysismodules; manager->registerModule >(); manager->registerModule >(); + manager->registerModule >(); manager->registerModule >(); } diff --git a/src/gromacs/trajectoryanalysis/modules/freevolume.cpp b/src/gromacs/trajectoryanalysis/modules/freevolume.cpp new file mode 100644 index 0000000000..67fb4d494f --- /dev/null +++ b/src/gromacs/trajectoryanalysis/modules/freevolume.cpp @@ -0,0 +1,389 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2013, by the GROMACS development team, led by + * David van der Spoel, Berk Hess, 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 + * Implements gmx::analysismodules::Freevolume. + * + * \author David van der Spoel + * \ingroup module_trajectoryanalysis + */ +#include "freevolume.h" + +#include "gromacs/legacyheaders/pbc.h" +#include "gromacs/legacyheaders/vec.h" +#include "gromacs/legacyheaders/atomprop.h" +#include "gromacs/legacyheaders/copyrite.h" + +#include "gromacs/analysisdata/analysisdata.h" +#include "gromacs/analysisdata/modules/plot.h" +#include "gromacs/options/basicoptions.h" +#include "gromacs/options/filenameoption.h" +#include "gromacs/options/options.h" +#include "gromacs/selection/selection.h" +#include "gromacs/selection/selectionoption.h" +#include "gromacs/trajectoryanalysis/analysissettings.h" +#include "gromacs/utility/exceptions.h" +#include "gromacs/utility/stringutil.h" + +namespace gmx +{ + +namespace analysismodules +{ + +const char FreeVolume::name[] = "freevolume"; +const char FreeVolume::shortDescription[] = + "Calculate free volume"; + +// Constructor. Here it is important to initialize the pointer to +// subclasses that are elements of the main class. Here we have only +// one. The type of this depends on what kind of tool you need. +// Here we only have simple value/time kind of data. +FreeVolume::FreeVolume() + : TrajectoryAnalysisModule(name, shortDescription), + adata_(new AnalysisDataAverageModule()) +{ + // We only compute two numbers per frame + data_.setColumnCount(2); + // Tell the analysis framework that this component exists + registerAnalysisDataset(&data_, "freevolume"); + rng_ = NULL; + nbsearch_ = NULL; + nmol_ = 0; + mtot_ = 0; + cutoff_ = 0; + probeRadius_ = 0; + seed_ = -1; + ninsert_ = 1000; +} + + +FreeVolume::~FreeVolume() +{ + // Destroy C structures where there is no automatic memory release + // C++ takes care of memory in classes (hopefully) + if (NULL != rng_) + { + gmx_rng_destroy(rng_); + } + if (NULL != nbsearch_) + { + gmx_ana_nbsearch_free(nbsearch_); + } +} + + +void +FreeVolume::initOptions(Options *options, + TrajectoryAnalysisSettings *settings) +{ + static const char *const desc[] = { + "g_freevol can calculate the free volume in a box as", + "a function of time. The free volume is", + "plotted as a fraction of the total volume.", + "The program tries to insert a probe with a given radius,", + "into the simulations box and if the distance between the", + "probe and any atom is less than the sums of the", + "van der Waals radii of both atoms, the position is", + "considered to be occupied, i.e. non-free. By using a", + "probe radius of 0, the true free volume is computed.", + "By using a larger radius, e.g. 0.14 nm, roughly corresponding", + "to a water molecule, the free volume for a hypothetical", + "particle with that size will be produced.", + "Note however, that since atoms are treated as hard-spheres", + "these number are very approximate, and typically only", + "relative changes are meaningful, for instance by doing a", + "series of simulations at different temperature.[PAR]", + "The group specified by the selection is considered to", + "delineate non-free volume.", + "The number of insertions per unit of volume is important", + "to get a converged result. About 1000/nm^3 yields an overall", + "standard deviation that is determined by the fluctuations in", + "the trajectory rather than by the fluctuations due to the", + "random numbers.[PAR]", + "The results are critically dependent on the van der Waals radii;", + "we recommend to use the values due to Bondi (1964).[PAR]", + "The Fractional Free Volume (FFV) that some authors like to use", + "is given by 1 - 1.3*(1-Free Volume). This value is printed on", + "the terminal." + }; + + // Add the descriptive text (program help text) to the options + options->setDescription(concatenateStrings(desc)); + + // Add option for optional output file + options->addOption(FileNameOption("o").filetype(eftPlot).outputFile() + .store(&fnFreevol_).defaultBasename("freevolume") + .description("Computed free volume")); + + // Add option for selecting a subset of atoms + options->addOption(SelectionOption("select").required().valueCount(1) + .store(&sel_) + .onlyAtoms()); + + // Add option for the probe radius and initialize it + options->addOption(DoubleOption("radius").store(&probeRadius_) + .description("Radius of the probe to be inserted (nm, 0 yields the true free volume)")); + + // Add option for the random number seed and initialize it to + // generate a value automatically + options->addOption(IntegerOption("seed").store(&seed_) + .description("Seed for random number generator.")); + + // Add option to determine number of insertion trials per frame + options->addOption(IntegerOption("ninsert").store(&ninsert_) + .description("Number of probe insertions per cubic nm to try for each frame in the trajectory.")); + + // Control input settings + settings->setFlags(TrajectoryAnalysisSettings::efRequireTop | + TrajectoryAnalysisSettings::efNoUserPBC); + settings->setPBC(true); +} + + +void +FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, + const TopologyInformation &top) +{ + // Add the module that will contain the averaging and the time series + // for our calculation + data_.addModule(adata_); + + // Add a module for plotting the data automatically at the end of + // the calculation. With this in place you only have to add data + // points to the data et. + AnalysisDataPlotModulePointer plotm_(new AnalysisDataPlotModule()); + plotm_->setSettings(settings.plotSettings()); + plotm_->setFileName(fnFreevol_); + plotm_->setTitle("Free Volume"); + plotm_->setXAxisIsTime(); + plotm_->setYLabel("Free Volume (%)"); + plotm_->appendLegend("Free Volume"); + plotm_->appendLegend("Volume"); + + data_.addModule(plotm_); + + // Initiate variable + cutoff_ = 0; + int nnovdw = 0; + gmx_atomprop_t aps = gmx_atomprop_init(); + t_atoms *atoms = &(top.topology()->atoms); + + // Compute total mass + mtot_ = 0; + for (int i = 0; (i < atoms->nr); i++) + { + mtot_ += atoms->atom[i].m; + } + + // Extracts number of molecules + nmol_ = top.topology()->mols.nr; + + // Loop over atoms in the selection using an iterator + const int maxnovdw = 10; + ConstArrayRef atomind = sel_.atomIndices(); + for (ConstArrayRef::iterator ai = atomind.begin(); (ai < atomind.end()); ++ai) + { + // Dereference the iterator to obtain an atom number + int i = *ai; + real value; + + // Lookup the Van der Waals radius of this atom + int resnr = atoms->atom[i].resind; + if (TRUE == gmx_atomprop_query(aps, epropVDW, + *(atoms->resinfo[resnr].name), + *(atoms->atomname[i]), + &value)) + { + vdw_radius_.push_back(value); + if (value > cutoff_) + { + cutoff_ = value; + } + } + else + { + nnovdw++; + if (nnovdw < maxnovdw) + { + fprintf(stderr, "Could not determine VDW radius for %s-%s. Set to zero.\n", + *(atoms->resinfo[resnr].name), + *(atoms->atomname[i])); + } + vdw_radius_.push_back(0.0); + } + } + gmx_atomprop_destroy(aps); + + // Increase cutoff by proberadius to make sure we do not miss + // anything + cutoff_ += probeRadius_; + + if (nnovdw >= maxnovdw) + { + fprintf(stderr, "Could not determine VDW radius for %d particles. These were set to zero.\n", nnovdw); + } + + // Print parameters to output. Maybe should make dependent on + // verbosity flag? + printf("cutoff = %g nm\n", cutoff_); + printf("probe_radius = %g nm\n", probeRadius_); + printf("seed = %d\n", seed_); + printf("ninsert = %d probes per nm^3\n", ninsert_); + + // Initiate the random number generator + rng_ = gmx_rng_init(seed_); + + // Initiate the neighborsearching code + nbsearch_ = gmx_ana_nbsearch_create(cutoff_, atoms->nr); +} + +void +FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, + TrajectoryAnalysisModuleData *pdata) +{ + AnalysisDataHandle dh = pdata->dataHandle(data_); + const Selection &sel = pdata->parallelSelection(sel_); + + GMX_RELEASE_ASSERT(NULL != pbc, "You have no periodic boundary conditions"); + + // Analysis framework magic + dh.startFrame(frnr, fr.time); + + // Compute volume and number of insertions to perform + real V = det(fr.box); + int Ninsert = static_cast(ninsert_*V); + + // Use neighborsearching tools! + gmx_ana_nbsearch_pos_init(nbsearch_, pbc, sel.positions()); + + // Then loop over insertions + int NinsTot = 0; + for (int i = 0; (i < Ninsert); i++) + { + rvec rand, ins, dx; + + for (int m = 0; (m < DIM); m++) + { + // Generate random number between 0 and 1 + rand[m] = gmx_rng_uniform_real(rng_); + } + // Generate random 3D position within the box + mvmul(fr.box, rand, ins); + + // Find the first reference position within the cutoff. + bool bOverlap = false; + int jp = NOTSET; + if (gmx_ana_nbsearch_first_within(nbsearch_, ins, &jp)) + { + do + { + // Compute distance vector to first atom in the neighborlist + pbc_dx(pbc, ins, sel.position(jp).x(), dx); + + // See whether the distance is smaller than allowed + bOverlap = (norm(dx) < + probeRadius_+vdw_radius_[sel.position(jp).refId()]); + + // Finds the next reference position within the cutoff. + } + while (!bOverlap && + (gmx_ana_nbsearch_next_within(nbsearch_, &jp))); + } + + if (!bOverlap) + { + // We found some free volume! + NinsTot++; + } + } + // Compute total free volume for this frame + double frac = 0; + if (Ninsert > 0) + { + frac = (100.0*NinsTot)/Ninsert; + } + // Add the free volume fraction to the data set in column 0 + dh.setPoint(0, frac); + // Add the total volume to the data set in column 1 + dh.setPoint(1, V); + + // Magic + dh.finishFrame(); +} + + +void +FreeVolume::finishAnalysis(int nframes) +{ + please_cite(stdout, "Bondi1964a"); +} + +void +FreeVolume::writeOutput() +{ + // Final results come from statistics module in analysis framework + double FVaver = adata_->average(0); + double FVerror = adata_->stddev(0); + printf("Free volume %.2f +/- %.2f %%\n", FVaver, FVerror); + + double Vaver = adata_->average(1); + double Verror = adata_->stddev(1); + printf("Total volume %.2f +/- %.2f nm^3\n", Vaver, Verror); + + printf("Number of molecules %d total mass %.2f Dalton\n", nmol_, mtot_); + double RhoAver = mtot_ / (adata_->average(1) * 1e-24 * AVOGADRO); + double RhoError = sqr(RhoAver / Vaver)*Verror; + printf("Average molar mass: %.2f Dalton\n", mtot_/nmol_); + + double VmAver = Vaver/nmol_; + double VmError = Verror/nmol_; + printf("Density rho: %.2f +/- %.2f nm^3\n", RhoAver, RhoError); + printf("Molecular volume Vm assuming homogeneity: %.4f +/- %.4f nm^3\n", + VmAver, VmError); + + double VvdWaver = (1-FVaver/100)*VmAver; + double VvdWerror = 0; + printf("Molecular van der Waals volume assuming homogeneity: %.4f +/- %.4f nm^3\n", + VvdWaver, VvdWerror); + + double FFVaver = 1-1.3*((100-FVaver)/100); + double FFVerror = (FVerror/FVaver)*FFVaver; + printf("Fractional free volume %.3f +/- %.3f\n", FFVaver, FFVerror); +} + +} // namespace analysismodules + +} // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/modules/freevolume.h b/src/gromacs/trajectoryanalysis/modules/freevolume.h new file mode 100644 index 0000000000..6c4f2151d4 --- /dev/null +++ b/src/gromacs/trajectoryanalysis/modules/freevolume.h @@ -0,0 +1,125 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2013, by the GROMACS development team, led by + * David van der Spoel, Berk Hess, 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 trajectory analysis module for distance calculations. + * + * \author David van der Spoel + * \ingroup module_trajectoryanalysis + */ +#ifndef GMX_TRAJECTORYANALYSIS_MODULES_FREEVOLUME_H +#define GMX_TRAJECTORYANALYSIS_MODULES_FREEVOLUME_H + +#include +#include "gromacs/legacyheaders/gmx_random.h" +#include "../analysismodule.h" +#include "gromacs/selection/nbsearch.h" +#include "gromacs/selection/indexutil.h" +#include "gromacs/analysisdata/analysisdata.h" +#include "gromacs/analysisdata/modules/average.h" +#include "gromacs/selection/selection.h" + +namespace gmx +{ + +namespace analysismodules +{ + +/*! \brief + * Class used to compute free volume in a simulations box. + * + * Inherits TrajectoryAnalysisModule and all functions from there. + * Does not implement any new functionality. + * + * \inpublicapi + * \ingroup module_trajectoryanalysis + */ +class FreeVolume : public TrajectoryAnalysisModule +{ + public: + //! Name of the tool + static const char name[]; + + //! One line description + static const char shortDescription[]; + + //! Constructor + FreeVolume(); + + //! Destructor + virtual ~FreeVolume(); + + //! Set the options and setting + virtual void initOptions(Options *options, + TrajectoryAnalysisSettings *settings); + + //! First routine called by the analysis frame work + virtual void initAnalysis(const TrajectoryAnalysisSettings &settings, + const TopologyInformation &top); + + //! Call for each frame of the trajectory + virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, + TrajectoryAnalysisModuleData *pdata); + + //! Last routine called by the analysis frame work + virtual void finishAnalysis(int nframes); + + //! Routine to write output, that is additional over the built-in + virtual void writeOutput(); + + private: + std::string fnFreevol_; + Selection sel_; + AnalysisData data_; + AnalysisDataAverageModulePointer adata_; + + int nmol_; + double mtot_; + double cutoff_; + double probeRadius_; + gmx_rng_t rng_; + int seed_, ninsert_; + gmx_ana_nbsearch_t *nbsearch_; + //! The van der Waals radius per atom + std::vector vdw_radius_; + + // Copy and assign disallowed by base. +}; + +} // namespace analysismodules + +} // namespace gmx + +#endif diff --git a/src/gromacs/trajectoryanalysis/tests/CMakeLists.txt b/src/gromacs/trajectoryanalysis/tests/CMakeLists.txt index 215e8c3731..ccf7b85607 100644 --- a/src/gromacs/trajectoryanalysis/tests/CMakeLists.txt +++ b/src/gromacs/trajectoryanalysis/tests/CMakeLists.txt @@ -35,6 +35,7 @@ gmx_add_unit_test(TrajectoryAnalysisUnitTests trajectoryanalysis-test moduletest.cpp angle.cpp + freevolume.cpp select.cpp) add_executable(test_selection test_selection.cpp) diff --git a/src/gromacs/trajectoryanalysis/tests/freevolume.cpp b/src/gromacs/trajectoryanalysis/tests/freevolume.cpp new file mode 100644 index 0000000000..e31bbac57f --- /dev/null +++ b/src/gromacs/trajectoryanalysis/tests/freevolume.cpp @@ -0,0 +1,85 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2013, by the GROMACS development team, led by + * David van der Spoel, Berk Hess, 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 + * Tests for functionality of the "angle" trajectory analysis module. + * + * \author David van der Spoel + * \ingroup module_trajectoryanalysis + */ +#include + +#include "gromacs/trajectoryanalysis/modules/freevolume.h" + +#include "testutils/cmdlinetest.h" + +#include "moduletest.h" + +namespace +{ + +using gmx::test::CommandLine; + +/******************************************************************** + * Tests for gmx::analysismodules::Angle. + */ + +//! Test fixture for the angle analysis module. +typedef gmx::test::TrajectoryAnalysisModuleTestFixture + FreeVolumeModuleTest; + +TEST_F(FreeVolumeModuleTest, ComputesFreeVolume) +{ + const char *const cmdline[] = { + "freevolume", + "-select", "all", "-seed", "13" + }; + setTopology("freevolume.tpr"); + setTrajectory("freevolume.xtc"); + runTest(CommandLine::create(cmdline)); +} + +TEST_F(FreeVolumeModuleTest, ComputesFreeVolumeSelection) +{ + const char *const cmdline[] = { + "freevolume", + "-select", "not resname = CO2", "-seed", "17" + }; + setTopology("freevolume.tpr"); + setTrajectory("freevolume.xtc"); + runTest(CommandLine::create(cmdline)); +} + +} // namespace diff --git a/src/gromacs/trajectoryanalysis/tests/freevolume.tpr b/src/gromacs/trajectoryanalysis/tests/freevolume.tpr new file mode 100644 index 0000000000..a06c635d43 Binary files /dev/null and b/src/gromacs/trajectoryanalysis/tests/freevolume.tpr differ diff --git a/src/gromacs/trajectoryanalysis/tests/freevolume.xtc b/src/gromacs/trajectoryanalysis/tests/freevolume.xtc new file mode 100644 index 0000000000..6cfc635b3c Binary files /dev/null and b/src/gromacs/trajectoryanalysis/tests/freevolume.xtc differ diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolume.xml b/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolume.xml new file mode 100644 index 0000000000..a423d2cfdc --- /dev/null +++ b/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolume.xml @@ -0,0 +1,21 @@ + + + + freevolume -select all -seed 13 + + + + 0.000000 + + 2 + + 37.199112 + + + 68.921501 + + + + + + diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolumeSelection.xml b/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolumeSelection.xml new file mode 100644 index 0000000000..a0f75cb0b7 --- /dev/null +++ b/src/gromacs/trajectoryanalysis/tests/refdata/FreeVolumeModuleTest_ComputesFreeVolumeSelection.xml @@ -0,0 +1,21 @@ + + + + freevolume -select 'not resname = CO2' -seed 17 + + + + 0.000000 + + 2 + + 38.779182 + + + 68.921501 + + + + + +