/* set program name, command line, and default values for output options */
gmx_output_env_t* oenv;
- gmx::TimeUnit timeUnit = gmx::TimeUnit_Default;
+ gmx::TimeUnit timeUnit = gmx::TimeUnit::Default;
bool bView{ false }; // argument that says we don't want to view graphs.
- int xvgFormat{ 0 };
- output_env_init(&oenv, gmx::getProgramContext(),
- static_cast<time_unit_t>(timeUnit + 1), // NOLINT(misc-misplaced-widening-cast)
- bView, static_cast<xvg_format_t>(xvgFormat + 1), 0);
+ output_env_init(&oenv, gmx::getProgramContext(), timeUnit, bView, XvgFormat::Xmgrace, 0);
double run_t = irInstance.init_step * irInstance.delta_t + irInstance.init_t;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/utility/stringutil.h"
#include "gromacs/utility/unique_cptr.h"
-namespace
-{
-
-//! Enum values for plot formats.
-const char* const g_plotFormats[] = { "none", "xmgrace", "xmgr" };
-
-} // namespace
-
namespace gmx
{
AnalysisDataPlotSettings::AnalysisDataPlotSettings() :
selections_(nullptr),
- timeUnit_(TimeUnit_Default),
- plotFormat_(1)
+ timeUnit_(TimeUnit::Default),
+ plotFormat_(XvgFormat::Xmgrace)
{
}
selections_ = selections;
}
+/*! \brief Names for XvgFormat
+ *
+ * Technically this duplicates a definition in pargs.cpp for legacy
+ * support code, but as the latter will go away and the alternatives
+ * are ugly, the duplication is acceptable. */
+const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = { { "xmgrace", "xmgr",
+ "none" } };
void AnalysisDataPlotSettings::initOptions(IOptionsContainer* options)
{
options->addOption(
- EnumIntOption("xvg").enumValue(g_plotFormats).store(&plotFormat_).description("Plot formatting"));
+ EnumOption<XvgFormat>("xvg").enumValue(c_xvgFormatNames).store(&plotFormat_).description("Plot formatting"));
}
}
else
{
- // NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
- time_unit_t time_unit = static_cast<time_unit_t>(impl_->settings_.timeUnit() + 1);
- xvg_format_t xvg_format = (impl_->settings_.plotFormat() > 0
- ? static_cast<xvg_format_t>(impl_->settings_.plotFormat())
- : exvgNONE);
+ const TimeUnit timeUnit = impl_->settings_.timeUnit();
+ const XvgFormat xvgFormat = impl_->settings_.plotFormat();
gmx_output_env_t* oenv;
- output_env_init(&oenv, getProgramContext(), time_unit, FALSE, xvg_format, 0);
+ output_env_init(&oenv, getProgramContext(), timeUnit, FALSE, xvgFormat, 0);
const unique_cptr<gmx_output_env_t, output_env_done> oenvGuard(oenv);
impl_->fp_ = xvgropen(impl_->filename_.c_str(), impl_->title_.c_str(), impl_->xlabel_,
impl_->ylabel_, oenv);
const SelectionCollection* selections = impl_->settings_.selectionCollection();
- if (selections != nullptr && output_env_get_xvg_format(oenv) != exvgNONE)
+ if (selections != nullptr && output_env_get_xvg_format(oenv) != XvgFormat::None)
{
selections->printXvgrInfo(impl_->fp_);
}
#include "gromacs/options/timeunitmanager.h"
#include "gromacs/utility/classhelpers.h"
+enum class XvgFormat : int;
+
namespace gmx
{
TimeUnit timeUnit() const { return timeUnit_; }
/*! \brief
* Returns the plot format.
- *
- * \todo Use a proper enum.
*/
- int plotFormat() const { return plotFormat_; }
+ XvgFormat plotFormat() const { return plotFormat_; }
/*! \brief
* Set selection collection to print as comments into the output.
private:
const SelectionCollection* selections_;
TimeUnit timeUnit_;
- int plotFormat_;
+ XvgFormat plotFormat_;
};
/*! \brief
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
/*! \brief
* The methods that determine how amplitudes are spread on a grid in density guided simulations.
*/
-enum class DensityFittingAmplitudeMethod
+enum class DensityFittingAmplitudeMethod : int
{
Unity, //!< same spread amplitude, unity, for all atoms
Mass, //!< atom mass is the spread amplitude
Count
};
-//! The names of the methods to determine the amplitude of the atoms to be spread on a grid
-const EnumerationArray<DensityFittingAmplitudeMethod, const char* const> c_densityFittingAmplitudeMethodNames = {
- { "unity", "mass", "charge" }
-};
-
class DensityFittingAmplitudeLookupImpl;
/*! \internal \brief Class that translates atom properties into amplitudes.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/optionsection.h"
#include "gromacs/selection/indexutil.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/keyvaluetreebuilder.h"
#include "gromacs/utility/keyvaluetreetransform.h"
c_adaptiveForceScalingTimeConstantTag_);
}
+//! Name the methods that may be used to evaluate similarity between densities
+static const EnumerationArray<DensitySimilarityMeasureMethod, const char*> c_densitySimilarityMeasureMethodNames = {
+ { "inner-product", "relative-entropy", "cross-correlation" }
+};
+//! The names of the methods to determine the amplitude of the atoms to be spread on a grid
+static const EnumerationArray<DensityFittingAmplitudeMethod, const char*> c_densityFittingAmplitudeMethodNames = {
+ { "unity", "mass", "charge" }
+};
+
void DensityFittingOptions::buildMdpOutput(KeyValueTreeObjectBuilder* builder) const
{
section.addOption(StringOption(c_groupTag_.c_str()).store(&groupString_));
section.addOption(EnumOption<DensitySimilarityMeasureMethod>(c_similarityMeasureTag_.c_str())
- .enumValue(c_densitySimilarityMeasureMethodNames.m_elements)
+ .enumValue(c_densitySimilarityMeasureMethodNames)
.store(¶meters_.similarityMeasureMethod_));
section.addOption(EnumOption<DensityFittingAmplitudeMethod>(c_amplitudeMethodTag_.c_str())
- .enumValue(c_densityFittingAmplitudeMethodNames.m_elements)
+ .enumValue(c_densityFittingAmplitudeMethodNames)
.store(¶meters_.amplitudeLookupMethod_));
section.addOption(RealOption(c_forceConstantTag_.c_str()).store(¶meters_.forceConstant_));
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basenetwork.h"
#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxassert.h"
namespace
{
-/*! \brief
- * Returns the index of the default xvg format.
+//! Names for XvgFormat
+const gmx::EnumerationArray<XvgFormat, const char*> c_xvgFormatNames = { { "xmgrace", "xmgr",
+ "none" } };
+
+/*! \brief Returns the default xvg format, as modified by GMX_VIEW_XVG
+ * if that environment variable is set.
*
* \ingroup module_commandline
*/
-int getDefaultXvgFormat(gmx::ArrayRef<const char* const> xvgFormats)
+XvgFormat getDefaultXvgFormat()
{
const char* const select = getenv("GMX_VIEW_XVG");
if (select != nullptr)
{
- ArrayRef<const char* const>::const_iterator i =
- std::find(xvgFormats.begin(), xvgFormats.end(), std::string(select));
- if (i != xvgFormats.end())
- {
- return std::distance(xvgFormats.begin(), i);
- }
- else
+ for (XvgFormat c : keysOf(c_xvgFormatNames))
{
- return exvgNONE - 1;
+ if (std::strcmp(select, c_xvgFormatNames[c]) == 0)
+ {
+ return c;
+ }
}
+ return XvgFormat::None;
}
- /* The default is the first option */
- return 0;
+ return XvgFormat::Xmgrace;
}
/*! \brief
return;
case etENUM:
{
+ // TODO This is the only use of LegacyEnumOption. It
+ // exists to support dozens of analysis tools use that
+ // don't make sense to fix without either test coverage or
+ // automated refactoring. No new uses of LegacyEnumOption
+ // should be made.
const int defaultIndex = (pa->u.c[0] != nullptr ? nenum(pa->u.c) - 1 : 0);
- data.optionInfo = options->addOption(EnumIntOption(name)
+ data.optionInfo = options->addOption(LegacyEnumOption<int>(name)
.store(&data.enumIndex)
.defaultValue(defaultIndex)
.enumValueFromNullTerminatedArray(pa->u.c + 1)
const char** bugs,
gmx_output_env_t** oenv)
{
- /* This array should match the order of the enum in oenv.h */
- const char* const xvg_formats[] = { "xmgrace", "xmgr", "none" };
-
// Lambda function to test the (local) Flags parameter against a bit mask.
auto isFlagSet = [Flags](unsigned long bits) { return (Flags & bits) == bits; };
{
double tbegin = 0.0, tend = 0.0, tdelta = 0.0;
bool bBeginTimeSet = false, bEndTimeSet = false, bDtSet = false;
- bool bView = false;
- int xvgFormat = 0;
+ bool bView = false;
gmx::OptionsAdapter adapter(*argc, argv);
gmx::Options options;
gmx::OptionsBehaviorCollection behaviors(&options);
options.addOption(gmx::DoubleOption("dt").store(&tdelta).storeIsSet(&bDtSet).timeValue().description(
"Only use frame when t MOD dt = first time (default unit %t)"));
}
- gmx::TimeUnit timeUnit = gmx::TimeUnit_Default;
+ gmx::TimeUnit timeUnit = gmx::TimeUnit::Default;
if (isFlagSet(PCA_TIME_UNIT))
{
std::shared_ptr<gmx::TimeUnitBehavior> timeUnitBehavior(new gmx::TimeUnitBehavior());
{
bXvgr = bXvgr || (fnm[i].ftp == efXVG);
}
- xvgFormat = gmx::getDefaultXvgFormat(xvg_formats);
+ XvgFormat xvgFormat = gmx::getDefaultXvgFormat();
if (bXvgr)
{
- options.addOption(
- gmx::EnumIntOption("xvg").enumValue(xvg_formats).store(&xvgFormat).description("xvg plot formatting"));
+ options.addOption(gmx::EnumOption<XvgFormat>("xvg")
+ .enumValue(gmx::c_xvgFormatNames)
+ .store(&xvgFormat)
+ .description("xvg plot formatting"));
}
/* Now append the program specific arguments */
/* set program name, command line, and default values for output options */
// NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
- output_env_init(oenv, gmx::getProgramContext(), static_cast<time_unit_t>(timeUnit + 1),
- bView, static_cast<xvg_format_t>(xvgFormat + 1), 0);
+ output_env_init(oenv, gmx::getProgramContext(), timeUnit, bView, xvgFormat, 0);
/* Extract Time info from arguments */
if (bBeginTimeSet)
#include "gromacs/options/filenameoption.h"
#include "gromacs/options/options.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/stringstream.h"
#include "gromacs/utility/textwriter.h"
options.addOption(DoubleOption("time").description("Time option (%t)").timeValue().defaultValue(10.0));
options.addOption(StringOption("string").description("String option").defaultValue("test"));
const char* const enumValues[] = { "no", "opt1", "opt2" };
+ enum class TestEnum : int
+ {
+ No,
+ Opt1,
+ Opt2,
+ Count
+ };
+ const gmx::EnumerationArray<TestEnum, const char*> testEnumNames = { { "no", "opt1", "opt2" } };
+
options.addOption(
StringOption("enum").description("Enum option").enumValue(enumValues).defaultEnumIndex(0));
options.addOption(
- EnumIntOption("ienum").description("Enum option").enumValue(enumValues).defaultValue(1));
+ EnumOption<TestEnum>("ienum").description("Enum option").enumValue(testEnumNames).defaultValue(TestEnum::Opt1));
std::string filename;
options.addOption(FileNameOption("f")
}
//! Enum value for testing.
-enum TestEnum
+enum class TestEnum : int
{
- eFoo,
- eBar
+ Foo,
+ Bar,
+ Count
};
/*
svalues.emplace_back("foo");
options.addOption(StringOption("str").description("String option").storeVector(&svalues).multiValue());
- TestEnum evalue = eBar;
- const char* const allowed[] = { "foo", "bar" };
+ TestEnum evalue = TestEnum::Bar;
+ const gmx::EnumerationArray<TestEnum, const char*> allowed = { { "foo", "bar" } };
options.addOption(
EnumOption<TestEnum>("enum").description("Enum option").enumValue(allowed).store(&evalue));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
}
//! Enum class for setting basic flags in a t_trxframe
-enum class ChangeSettingType
+enum class ChangeSettingType : int
{
PreservedIfPresent,
Always,
- Never
+ Never,
+ Count
};
-//! Mapping for enums from \ref ChangeSettingType.
-const char* const cChangeSettingTypeEnum[] = { "preserved-if-present", "always", "never" };
//! Enum class for t_atoms settings
enum class ChangeAtomsType
PreservedIfPresent,
AlwaysFromStructure,
Never,
- Always
+ Always,
+ Count
};
-//! Mapping for enums from \ref ChangeAtomsType.
-const char* const cChangeAtomsTypeEnum[] = { "preserved-if-present", "always-from-structure",
- "never", "always" };
-
//! Enum class for setting fields new or not.
enum class ChangeFrameInfoType
{
PreservedIfPresent,
- Always
+ Always,
+ Count
};
-//! Mapping for enums from \ref ChangeFrameInfoType.
-const char* const cChangeFrameInfoTypeEnum[] = { "preserved-if-present", "always" };
//! Enum class for setting frame time from user input.
enum class ChangeFrameTimeType
PreservedIfPresent,
StartTime,
TimeStep,
- Both
+ Both,
+ Count
};
-//! Mapping for values from \ref ChangeFrameTimeType.
-const char* const cChangeFrameTimeTypeEnum[] = { "preserved-if-present", "starttime", "timestep",
- "both" };
-
-
} // namespace gmx
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
#include "gromacs/options/ioptionscontainer.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
namespace gmx
{
+//! Mapping for enums from \ref ChangeSettingType.
+static const EnumerationArray<ChangeSettingType, const char*> c_changeSettingTypeNames = {
+ { "preserved-if-present", "always", "never" }
+};
+//! Mapping for enums from \ref ChangeAtomsType.
+static const EnumerationArray<ChangeAtomsType, const char*> c_changeAtomsTypeNames = {
+ { "preserved-if-present", "always-from-structure", "never", "always" }
+};
+/* Currently unused
+//! Mapping for enums from \ref ChangeFrameInfoType.
+static const EnumerationArray<ChangeFrameInfoType, const char*> c_changeFrameInfoTypeNames = { {
+"preserved-if-present", "always" } };
+//! Mapping for values from \ref ChangeFrameTimeType.
+static const EnumerationArray<ChangeFrameTimeType, const char*> c_changeFrameTimeTypeNames = { {
+"preserved-if-present", "starttime", "timestep", "both" } };
+*/
+
void OutputRequirementOptionDirector::initOptions(IOptionsContainer* options)
{
options->addOption(EnumOption<ChangeSettingType>("vel")
- .enumValue(cChangeSettingTypeEnum)
+ .enumValue(c_changeSettingTypeNames)
.store(&velocity_)
.description("Save velocities from frame if possible"));
options->addOption(EnumOption<ChangeSettingType>("force")
- .enumValue(cChangeSettingTypeEnum)
+ .enumValue(c_changeSettingTypeNames)
.store(&force_)
.description("Save forces from frame if possible"));
options->addOption(
- EnumOption<ChangeAtomsType>("atoms").enumValue(cChangeAtomsTypeEnum).store(&atoms_).description("Decide on providing new atom information from topology or using current frame atom information"));
+ EnumOption<ChangeAtomsType>("atoms").enumValue(c_changeAtomsTypeNames).store(&atoms_).description("Decide on providing new atom information from topology or using current frame atom information"));
options->addOption(IntegerOption("precision")
.store(&prec_)
.defaultValue(prec_)
#include "oenv.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/smalloc.h"
{
explicit gmx_output_env_t(const gmx::IProgramContext& context) :
programContext(context),
- time_unit(time_ps),
+ timeUnit(gmx::TimeUnit::Picoseconds),
view(FALSE),
- xvg_format(exvgNONE),
+ xvgFormat(XvgFormat::None),
verbosity(0),
trajectory_io_verbosity(0)
{
const gmx::IProgramContext& programContext;
- /* the time unit, enum defined in oenv.h */
- time_unit_t time_unit;
+ /* the time unit, enum defined in timeunitmanager.h */
+ gmx::TimeUnit timeUnit;
/* view of file requested */
gmx_bool view;
/* xvg output format, enum defined in oenv.h */
- xvg_format_t xvg_format;
+ XvgFormat xvgFormat;
/* The level of verbosity for this program */
int verbosity;
/* The level of verbosity during trajectory I/O. Default=1, quiet=0. */
******************************************************************/
/* read only time names */
-/* These must correspond to the time units type time_unit_t in oenv.h */
-static const real timefactors[] = { real(0), real(1e3), real(1), real(1e-3),
- real(1e-6), real(1e-9), real(1e-12), real(0) };
-static const real timeinvfactors[] = { real(0), real(1e-3), real(1), real(1e3),
- real(1e6), real(1e9), real(1e12), real(0) };
-static const char* time_units_str[] = { nullptr, "fs", "ps", "ns", "us", "\\mus", "ms", "s" };
-static const char* time_units_xvgr[] = { nullptr, "fs", "ps", "ns", "ms", "s", nullptr };
+static const gmx::EnumerationArray<gmx::TimeUnit, real> c_picosecondsInTimeUnit = {
+ { real(1e3), real(1), real(1e-3), real(1e-6), real(1e-9), real(1e-12) }
+};
+static const gmx::EnumerationArray<gmx::TimeUnit, real> c_timeUnitsInPicoseconds = {
+ { real(1e-3), real(1), real(1e3), real(1e6), real(1e9), real(1e12) }
+};
+static const gmx::EnumerationArray<gmx::TimeUnit, const char*> c_timeUnitNames = {
+ { "fs", "ps", "ns", "us", "ms", "s" }
+};
+static const gmx::EnumerationArray<gmx::TimeUnit, const char*> c_timeUnitNamesForXvgr = {
+ { "fs", "ps", "ns", "\\mus", "ms", "s" }
+};
/***** OUTPUT_ENV MEMBER FUNCTIONS ******/
void output_env_init(gmx_output_env_t** oenvp,
const gmx::IProgramContext& context,
- time_unit_t tmu,
+ gmx::TimeUnit tmu,
gmx_bool view,
- xvg_format_t xvg_format,
+ XvgFormat xvgFormat,
int verbosity)
{
try
{
gmx_output_env_t* oenv = new gmx_output_env_t(context);
*oenvp = oenv;
- oenv->time_unit = tmu;
+ oenv->timeUnit = tmu;
oenv->view = view;
- oenv->xvg_format = xvg_format;
+ oenv->xvgFormat = xvgFormat;
oenv->verbosity = verbosity;
const char* env = getenv("GMX_TRAJECTORY_IO_VERBOSITY");
oenv->trajectory_io_verbosity = (env != nullptr ? strtol(env, nullptr, 10) : 1);
std::string output_env_get_time_unit(const gmx_output_env_t* oenv)
{
- return time_units_str[oenv->time_unit];
+ return c_timeUnitNames[oenv->timeUnit];
}
std::string output_env_get_time_label(const gmx_output_env_t* oenv)
{
- return gmx::formatString(
- "Time (%s)", time_units_str[oenv->time_unit] ? time_units_str[oenv->time_unit] : "ps");
+ return gmx::formatString("Time (%s)", c_timeUnitNames[oenv->timeUnit]);
}
std::string output_env_get_xvgr_tlabel(const gmx_output_env_t* oenv)
{
- return gmx::formatString(
- "Time (%s)", time_units_xvgr[oenv->time_unit] ? time_units_xvgr[oenv->time_unit] : "ps");
+ return gmx::formatString("Time (%s)", c_timeUnitNamesForXvgr[oenv->timeUnit]);
}
real output_env_get_time_factor(const gmx_output_env_t* oenv)
{
- return timefactors[oenv->time_unit];
+ return c_picosecondsInTimeUnit[oenv->timeUnit];
}
real output_env_get_time_invfactor(const gmx_output_env_t* oenv)
{
- return timeinvfactors[oenv->time_unit];
+ return c_timeUnitsInPicoseconds[oenv->timeUnit];
}
real output_env_conv_time(const gmx_output_env_t* oenv, real time)
{
- return time * timefactors[oenv->time_unit];
+ return time * c_picosecondsInTimeUnit[oenv->timeUnit];
}
void output_env_conv_times(const gmx_output_env_t* oenv, int n, real* time)
{
int i;
- double fact = timefactors[oenv->time_unit];
+ double fact = c_picosecondsInTimeUnit[oenv->timeUnit];
if (fact != 1.)
{
return oenv->view;
}
-xvg_format_t output_env_get_xvg_format(const gmx_output_env_t* oenv)
+XvgFormat output_env_get_xvg_format(const gmx_output_env_t* oenv)
{
- return oenv->xvg_format;
+ return oenv->xvgFormat;
}
const char* output_env_get_program_display_name(const gmx_output_env_t* oenv)
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2017,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.
There are still legacy functions for the program name, and the command
line, but the output_env versions are now preferred.*/
-typedef enum
+namespace gmx
{
- timeNULL,
- time_fs,
- time_ps,
- time_ns,
- time_us,
- time_ms,
- time_s
-} time_unit_t;
-/* the time units. For the time being, ps means no conversion. */
-
-typedef enum
+
+/*! \brief
+ * Time values for TimeUnitManager and legacy oenv module.
+ *
+ * \inpublicapi
+ */
+enum class TimeUnit : int
{
- exvgNULL,
- exvgXMGRACE,
- exvgXMGR,
- exvgNONE
-} xvg_format_t;
-/* the xvg output formattings */
+ Femtoseconds,
+ Picoseconds,
+ Nanoseconds,
+ Microseconds,
+ Milliseconds,
+ Seconds,
+ Count,
+ Default = Picoseconds
+};
+
+} // namespace gmx
+//! The xvg output format
+enum class XvgFormat : int
+{
+ // Select,
+ Xmgrace,
+ Xmgr,
+ None,
+ Count
+};
void output_env_init_default(gmx_output_env_t** oenvp);
/* initialize an output_env structure, with reasonable default settings.
gmx_bool output_env_get_view(const gmx_output_env_t* oenv);
/* Return TRUE when user requested viewing of the file */
-xvg_format_t output_env_get_xvg_format(const gmx_output_env_t* oenv);
+XvgFormat output_env_get_xvg_format(const gmx_output_env_t* oenv);
/* Returns enum (see above) for xvg output formatting */
/*! \brief
void output_env_init(gmx_output_env_t** oenvp,
const gmx::IProgramContext& context,
- time_unit_t tmu,
+ gmx::TimeUnit tmu,
gmx_bool view,
- xvg_format_t xvg_format,
+ XvgFormat xvgFormat,
int verbosity);
/* initialize an output_env structure, setting the command line,
the default time value a gmx_boolean view that is set to TRUE when the
gmx_bool output_env_get_print_xvgr_codes(const gmx_output_env_t* oenv)
{
- int xvg_format;
+ XvgFormat xvgFormat = output_env_get_xvg_format(oenv);
- xvg_format = output_env_get_xvg_format(oenv);
-
- return (xvg_format == exvgXMGRACE || xvg_format == exvgXMGR);
+ return (xvgFormat == XvgFormat::Xmgrace || xvgFormat == XvgFormat::Xmgr);
}
static char* xvgrstr(const std::string& gmx, const gmx_output_env_t* oenv, char* buf, int buflen)
const char* sym[] = { "beta", "chi", "delta", "eta", "lambda", "mu",
"omega", "phi", "psi", "rho", "theta", nullptr };
const char symc[] = { 'b', 'c', 'd', 'h', 'l', 'm', 'w', 'f', 'y', 'r', 'q', '\0' };
- int xvgf;
gmx_bool bXVGR;
int g, b, i;
char c;
- xvgf = output_env_get_xvg_format(oenv);
- bXVGR = (xvgf == exvgXMGRACE || xvgf == exvgXMGR);
+ XvgFormat xvgf = output_env_get_xvg_format(oenv);
+ bXVGR = (xvgf == XvgFormat::Xmgrace || xvgf == XvgFormat::Xmgr);
g = 0;
b = 0;
/* Backward compatibility for xmgr normal font "\4" */
switch (xvgf)
{
- case exvgXMGRACE: sprintf(buf + b, "%s", "\\f{}"); break;
- case exvgXMGR: sprintf(buf + b, "%s", "\\4"); break;
+ case XvgFormat::Xmgrace: sprintf(buf + b, "%s", "\\f{}"); break;
+ case XvgFormat::Xmgr: sprintf(buf + b, "%s", "\\4"); break;
default: buf[b] = '\0'; break;
}
g++;
/* Backward compatibility for xmgr symbol font "\8" */
switch (xvgf)
{
- case exvgXMGRACE: sprintf(buf + b, "%s", "\\x"); break;
- case exvgXMGR: sprintf(buf + b, "%s", "\\8"); break;
+ case XvgFormat::Xmgrace: sprintf(buf + b, "%s", "\\x"); break;
+ case XvgFormat::Xmgr: sprintf(buf + b, "%s", "\\8"); break;
default: buf[b] = '\0'; break;
}
g++;
}
switch (xvgf)
{
- case exvgXMGRACE: sprintf(buf + b, "%s%c%s", "\\x", c, "\\f{}"); break;
- case exvgXMGR: sprintf(buf + b, "%s%c%s", "\\8", c, "\\4"); break;
+ case XvgFormat::Xmgrace:
+ sprintf(buf + b, "%s%c%s", "\\x", c, "\\f{}");
+ break;
+ case XvgFormat::Xmgr: sprintf(buf + b, "%s%c%s", "\\8", c, "\\4"); break;
default:
std::strncat(buf + b, &gmx[g], std::strlen(sym[i]));
b += std::strlen(sym[i]);
switch (exvg_graph_type)
{
case exvggtXNY:
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(fp, "@TYPE nxy\n");
}
{
if (!stringIsEmpty(setname[i]))
{
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(out, "@ legend string %d \"%s\"\n", i, xvgrstr(setname[i], oenv, buf, STRLEN));
}
{
if (setname[i])
{
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(out, "@ legend string %d \"%s\"\n", i + nr_first,
xvgrstr(setname[i], oenv, buf, STRLEN));
real ymin, ymax, xsp, ysp;
out = gmx_ffopen(file, "w");
- if (output_env_get_xvg_format(oenv) == exvgXMGRACE)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgrace)
{
fprintf(out, "@ autoscale onread none\n");
}
tau2 = fitparm[2];
}
fprintf(stdout, "Set %3d: err.est. %g a %g tau1 %g tau2 %g\n", s + 1, ee, a, tau1, tau2);
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(fp, "@ legend string %d \"av %f\"\n", 2 * s, av[s]);
fprintf(fp, "@ legend string %d \"ee %6g\"\n", 2 * s + 1,
optimal_error_estimate(sig[s], fitparm, n * dt));
}
- else if (output_env_get_xvg_format(oenv) == exvgXMGRACE)
+ else if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgrace)
{
fprintf(fp, "@ s%d legend \"av %f\"\n", 2 * s, av[s]);
fprintf(fp, "@ s%d legend \"ee %6g\"\n", 2 * s + 1,
if (output_env_get_print_xvgr_codes(oenv))
{
char str1[STRLEN], str2[STRLEN];
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
sprintf(str1, "@ legend string ");
sprintf(str2, " ");
}
else
{
- if (output_env_get_xvg_format(oenv) == exvgXMGR)
+ if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgr)
{
fprintf(out[nnn], "@ legend string %d \"%s\"\n", nset[nnn], buf);
}
- else if (output_env_get_xvg_format(oenv) == exvgXMGRACE)
+ else if (output_env_get_xvg_format(oenv) == XvgFormat::Xmgrace)
{
fprintf(out[nnn], "@ s%d legend \"%s\"\n", nset[nnn], buf);
}
#include "gromacs/topology/topology.h"
#include "gromacs/trajectory/trajectoryframe.h"
#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
using gmx::RVec;
/* enum for random rotations of inserted solutes */
-enum RotationType
+enum class RotationType : int
{
- en_rotXYZ,
- en_rotZ,
- en_rotNone
+ XYZ,
+ Z,
+ None,
+ Count
};
-const char* const cRotationEnum[] = { "xyz", "z", "none" };
+static const gmx::EnumerationArray<RotationType, const char*> c_rotationTypeNames = { { "xyz", "z",
+ "none" } };
static void center_molecule(gmx::ArrayRef<RVec> x)
{
real alfa = 0.0, beta = 0.0, gamma = 0.0;
switch (enum_rot)
{
- case en_rotXYZ:
+ case RotationType::XYZ:
alfa = dist(*rng);
beta = dist(*rng);
gamma = dist(*rng);
break;
- case en_rotZ:
+ case RotationType::Z:
alfa = beta = 0.;
gamma = dist(*rng);
break;
- case en_rotNone: alfa = beta = gamma = 0.; break;
+ case RotationType::None: alfa = beta = gamma = 0.; break;
+ default: GMX_THROW(gmx::InternalError("Invalid RotationType"));
}
- if (enum_rot == en_rotXYZ || enum_rot == en_rotZ)
+ if (enum_rot == RotationType::XYZ || enum_rot == RotationType::Z)
{
rotate_conf(xout->size(), as_rvec_array(xout->data()), nullptr, alfa, beta, gamma);
}
seed_(0),
defaultDistance_(0.105),
scaleFactor_(0.57),
- enumRot_(en_rotXYZ)
+ enumRot_(RotationType::XYZ)
{
clear_rvec(newBox_);
clear_rvec(deltaR_);
options->addOption(RealOption("dr").vector().store(deltaR_).description(
"Allowed displacement in x/y/z from positions in [TT]-ip[tt] file"));
options->addOption(EnumOption<RotationType>("rot")
- .enumValue(cRotationEnum)
+ .enumValue(c_rotationTypeNames)
.store(&enumRot_)
.description("Rotate inserted molecules randomly"));
}
}
}
-/* enum for chain separation */
-enum ChainSepType
+enum class ChainSeparationType : int
{
- enChainSep_id_or_ter,
- enChainSep_id_and_ter,
- enChainSep_ter,
- enChainSep_id,
- enChainSep_interactive
+ IdOrTer,
+ IdAndTer,
+ Ter,
+ Id,
+ Interactive,
+ Count
};
-static const char* ChainSepEnum[] = { "id_or_ter", "id_and_ter", "ter", "id", "interactive" };
-static const char* ChainSepInfoString[] = {
- "Splitting chemical chains based on TER records or chain id changing.\n",
- "Splitting chemical chains based on TER records and chain id changing.\n",
- "Splitting chemical chains based on TER records only (ignoring chain id).\n",
- "Splitting chemical chains based on changing chain id only (ignoring TER records).\n",
- "Splitting chemical chains interactively.\n"
+static const gmx::EnumerationArray<ChainSeparationType, const char*> c_chainSeparationTypeNames = {
+ { "id_or_ter", "id_and_ter", "ter", "id", "interactive" }
+};
+static const gmx::EnumerationArray<ChainSeparationType, const char*> c_chainSeparationTypeNotificationMessages = {
+ { "Splitting chemical chains based on TER records or chain id changing.\n",
+ "Splitting chemical chains based on TER records and chain id changing.\n",
+ "Splitting chemical chains based on TER records only (ignoring chain id).\n",
+ "Splitting chemical chains based on changing chain id only (ignoring TER records).\n",
+ "Splitting chemical chains interactively.\n" }
};
-static void modify_chain_numbers(t_atoms* pdba, ChainSepType enumChainSep, const gmx::MDLogger& logger)
+static void modify_chain_numbers(t_atoms* pdba, ChainSeparationType chainSeparation, const gmx::MDLogger& logger)
{
int i;
char old_prev_chainid;
char this_chainid;
/* The default chain enumeration is based on TER records only */
- printf("%s", ChainSepInfoString[enumChainSep]);
+ printf("%s", c_chainSeparationTypeNotificationMessages[chainSeparation]);
old_prev_chainid = '?';
old_prev_chainnum = -1;
this_resnum = ri->nr;
this_chainid = ri->chainid;
- switch (enumChainSep)
+ switch (chainSeparation)
{
- case enChainSep_id_or_ter:
+ case ChainSeparationType::IdOrTer:
if (old_this_chainid != old_prev_chainid || old_this_chainnum != old_prev_chainnum)
{
new_chainnum++;
}
break;
- case enChainSep_id_and_ter:
+ case ChainSeparationType::IdAndTer:
if (old_this_chainid != old_prev_chainid && old_this_chainnum != old_prev_chainnum)
{
new_chainnum++;
}
break;
- case enChainSep_id:
+ case ChainSeparationType::Id:
if (old_this_chainid != old_prev_chainid)
{
new_chainnum++;
}
break;
- case enChainSep_ter:
+ case ChainSeparationType::Ter:
if (old_this_chainnum != old_prev_chainnum)
{
new_chainnum++;
}
break;
- case enChainSep_interactive:
+ case ChainSeparationType::Interactive:
if (old_this_chainid != old_prev_chainid || old_this_chainnum != old_prev_chainnum)
{
if (i > 0)
}
}
break;
- default: gmx_fatal(FARGS, "Internal inconsistency - this shouldn't happen...");
+ case ChainSeparationType::Count:
+ gmx_fatal(FARGS, "Internal inconsistency - this shouldn't happen...");
}
old_prev_chainid = old_this_chainid;
old_prev_chainnum = old_this_chainnum;
std::vector<gmx::RVec> x;
};
-// TODO make all enums into scoped enums
-/* enum for vsites */
-enum VSitesType
+enum class VSitesType : int
{
- enVSites_none,
- enVSites_hydrogens,
- enVSites_aromatics
+ None,
+ Hydrogens,
+ Aromatics,
+ Count
+};
+static const gmx::EnumerationArray<VSitesType, const char*> c_vsitesTypeNames = {
+ { "none", "hydrogens", "aromatics" }
};
-static const char* VSitesEnum[] = { "none", "hydrogens", "aromatics" };
-/* enum for water model */
-enum WaterType
+enum class WaterType : int
{
- enWater_select,
- enWater_none,
- enWater_spc,
- enWater_spce,
- enWater_tip3p,
- enWater_tip4p,
- enWater_tip5p,
- enWater_tips3p
+ Select,
+ None,
+ Spc,
+ SpcE,
+ Tip3p,
+ Tip4p,
+ Tip5p,
+ Tips3p,
+ Count
+};
+static const gmx::EnumerationArray<WaterType, const char*> c_waterTypeNames = {
+ { "select", "none", "spc", "spce", "tip3p", "tip4p", "tip5p", "tips3p" }
};
-static const char* WaterEnum[] = { "select", "none", "spc", "spce",
- "tip3p", "tip4p", "tip5p", "tips3p" };
-/* enum for merge */
-enum MergeType
+enum class MergeType : int
{
- enMerge_no,
- enMerge_all,
- enMerge_interactive
+ No,
+ All,
+ Interactive,
+ Count
};
-static const char* MergeEnum[] = { "no", "all", "interactive" };
+static const gmx::EnumerationArray<MergeType, const char*> c_mergeTypeNames = { { "no", "all",
+ "interactive" } };
namespace gmx
{
bVsites_(FALSE),
bPrevWat_(FALSE),
bVsiteAromatics_(FALSE),
- enumChainSep_(enChainSep_id_or_ter),
- enumVSites_(enVSites_none),
- enumWater_(enWater_select),
- enumMerge_(enMerge_no),
+ chainSeparation_(ChainSeparationType::IdOrTer),
+ vsitesType_(VSitesType::None),
+ waterType_(WaterType::Select),
+ mergeType_(MergeType::No),
itp_file_(nullptr),
mHmult_(0)
{
std::string outFile_;
std::string ff_;
- ChainSepType enumChainSep_;
- VSitesType enumVSites_;
- WaterType enumWater_;
- MergeType enumMerge_;
+ ChainSeparationType chainSeparation_;
+ VSitesType vsitesType_;
+ WaterType waterType_;
+ MergeType mergeType_;
FILE* itp_file_;
char forcefield_[STRLEN];
RealOption("lb").store(&long_bond_dist_).defaultValue(0.25).hidden().description("Long bond warning distance"));
options->addOption(
RealOption("sb").store(&short_bond_dist_).defaultValue(0.05).hidden().description("Short bond warning distance"));
- options->addOption(
- EnumOption<ChainSepType>("chainsep").enumValue(ChainSepEnum).store(&enumChainSep_).description("Condition in PDB files when a new chain should be started (adding termini)"));
+ options->addOption(EnumOption<ChainSeparationType>("chainsep")
+ .enumValue(c_chainSeparationTypeNames)
+ .store(&chainSeparation_)
+ .description("Condition in PDB files when a new chain should be "
+ "started (adding termini)"));
options->addOption(EnumOption<MergeType>("merge")
- .enumValue(MergeEnum)
- .store(&enumMerge_)
+ .enumValue(c_mergeTypeNames)
+ .store(&mergeType_)
.description("Merge multiple chains into a single [moleculetype]"));
options->addOption(StringOption("ff").store(&ff_).defaultValue("select").description(
"Force field, interactive by default. Use [TT]-h[tt] for information."));
options->addOption(
- EnumOption<WaterType>("water").store(&enumWater_).enumValue(WaterEnum).description("Water model to use"));
+ EnumOption<WaterType>("water").store(&waterType_).enumValue(c_waterTypeNames).description("Water model to use"));
options->addOption(BooleanOption("inter").store(&bInter_).defaultValue(false).description(
"Set the next 8 options to interactive"));
options->addOption(BooleanOption("ss").store(&bCysMan_).defaultValue(false).description(
BooleanOption("v").store(&bVerbose_).defaultValue(false).description("Be slightly more verbose in messages"));
options->addOption(
RealOption("posrefc").store(&posre_fc_).defaultValue(1000).description("Force constant for position restraints"));
- options->addOption(
- EnumOption<VSitesType>("vsite").store(&enumVSites_).enumValue(VSitesEnum).description("Convert atoms to virtual sites"));
+ options->addOption(EnumOption<VSitesType>("vsite")
+ .store(&vsitesType_)
+ .enumValue(c_vsitesTypeNames)
+ .description("Convert atoms to virtual sites"));
options->addOption(BooleanOption("heavyh").store(&bHeavyH_).defaultValue(false).description(
"Make hydrogen atoms heavy"));
options->addOption(
.asParagraph()
.appendTextFormatted("Using the %s force field in directory %s", ffname_, ffdir_);
- choose_watermodel(WaterEnum[enumWater_], ffdir_, &watermodel_, logger);
+ choose_watermodel(c_waterTypeNames[waterType_], ffdir_, &watermodel_, logger);
- switch (enumVSites_)
+ switch (vsitesType_)
{
- case enVSites_none:
+ case VSitesType::None:
bVsites_ = false;
bVsiteAromatics_ = false;
break;
- case enVSites_hydrogens:
+ case VSitesType::Hydrogens:
bVsites_ = true;
bVsiteAromatics_ = false;
break;
- case enVSites_aromatics:
+ case VSitesType::Aromatics:
bVsites_ = true;
bVsiteAromatics_ = true;
break;
- default:
- gmx_fatal(FARGS, "Internal inconsistency: VSitesEnum='%s'", VSitesEnum[enumVSites_]);
+ case VSitesType::Count:
+ gmx_fatal(FARGS, "Internal inconsistency: VSitesType='%s'", c_vsitesTypeNames[vsitesType_]);
} /* end switch */
/* Open the symbol table */
GMX_LOG(logger.info).asParagraph().appendTextFormatted("Analyzing pdb file");
int nwaterchain = 0;
- modify_chain_numbers(&pdba_all, enumChainSep_, logger);
+ modify_chain_numbers(&pdba_all, chainSeparation_, logger);
int nchainmerges = 0;
bMerged = false;
if (i > 0 && !bWat_)
{
- if (!strncmp(MergeEnum[enumMerge_], "int", 3))
+ if (!strncmp(c_mergeTypeNames[mergeType_], "int", 3))
{
GMX_LOG(logger.info)
.asParagraph()
}
bMerged = (select[0] == 'y');
}
- else if (!strncmp(MergeEnum[enumMerge_], "all", 3))
+ else if (!strncmp(c_mergeTypeNames[mergeType_], "all", 3))
{
bMerged = true;
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/mdspan/extensions.h"
#include "gromacs/utility/classhelpers.h"
-#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/real.h"
namespace gmx
/*! \brief
* The methods that determine how two densities are compared to one another.
*/
-enum class DensitySimilarityMeasureMethod
+enum class DensitySimilarityMeasureMethod : int
{
/*! \brief Measure similarity between densities as normalized inner product of their
* voxel values.
Count,
};
-//! Name the methods that may be used to evaluate similarity between densities
-const EnumerationArray<DensitySimilarityMeasureMethod, const char* const> c_densitySimilarityMeasureMethodNames = {
- { "inner-product", "relative-entropy", "cross-correlation" }
-};
-
/* Forward declaration of implementation class outside class to allow
* choose implementation class during construction of the DensitySimilarityMeasure*/
class DensitySimilarityMeasureImpl;
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/options/abstractoption.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/gmxassert.h"
#include "ivaluestore.h"
//! \{
/*! \brief
- * Specifies an option that accepts enumerated string values and writes the
- * selected index into an `enum` variable.
- *
- * \tparam EnumType Type of the variable that receives the values
- * (can also be `int`).
- *
- * Examples:
- * \code
- enum MyEnum { eAtom, eRes, eMol };
- using gmx::EnumOption;
- const char * const allowed[] = { "atom", "residue", "molecule" };
- MyEnum value = eAtom; // default value
- options.addOption(EnumOption<MyEnum>("type").enumValue(allowed).store(&value));
- * \endcode
- *
- * storeCount() is not currently implemented for this option type, and
- * providing multiple default values through an array passed to store() does
- * not work consistently in all cases.
- * In the current implementation, the values of the enum type should correspond
- * to indices in the array passed to enumValue(), i.e., be consencutive
- * starting from zero. Only values corresponding to valid indices are accepted
- * as parameters to, e.g., defaultValue(). However, other values can be used
- * as the initial value of the variable (`value` in the above example), and
- * those will be preserved if the option is not set.
- *
- * Public methods in this class do not throw.
- *
- * \inpublicapi
- */
+* Specifies an option that accepts an EnumerationArray of string values and writes the
+* selected index into an `enum` variable.
+*
+* \tparam EnumType DataType of the variable that receives the values
+*
+* Examples:
+* \code
+ enum class MyEnum { Atom, Res, Mol, Count } : int;
+ EnumerationArray<MyEnum, const char *> myEnumNames = { "atom", "residue", "molecule" };
+ MyEnum value = MyEnum::Atom; // default value
+ options.addOption(EnumOption<MyEnum>("type").enumValue(myEnumNames).store(&value));
+* \endcode
+*
+* storeCount() is not currently implemented for this option type, and
+* providing multiple default values through an array passed to store() does
+* not work consistently in all cases.
+* In the current implementation, the values of the enum type should correspond
+* to indices in the array passed to enumValue(), i.e., be consecutive
+* starting from zero. Only values corresponding to valid indices are accepted
+* as parameters to, e.g., defaultValue(). However, other values can be used
+* as the initial value of the variable (`value` in the above example), and
+* those will be preserved if the option is not set.
+*
+* Public methods in this class do not throw.
+*
+* \inpublicapi
+*/
template<typename EnumType>
class EnumOption : public OptionTemplate<EnumType, EnumOption<EnumType>>
{
{
}
+ /*! \brief
+ * Sets the option to only accept one of a fixed set of strings.
+ *
+
+ * \param[in] values Array of strings to accept.
+ *
+ * Also accepts prefixes of the strings; if a prefix matches more than
+ * one of the possible strings, the shortest one is used (in a tie, the
+ * first one is).
+ *
+ * The strings are copied once the option is created.
+ */
+ EnumOption& enumValue(const EnumerationArray<EnumType, const char*>& values)
+ {
+ GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified");
+ enumValues_ = values.data();
+ enumValuesCount_ = values.size();
+ return MyBase::me();
+ }
+
+private:
+ //! Helper function to convert default values for storage initialization.
+ static int convertToInt(const EnumType* defaultValue)
+ {
+ return defaultValue != nullptr ? static_cast<int>(*defaultValue) : -1;
+ }
+
+ //! Creates a EnumOptionStorage object.
+ AbstractOptionStorage* createStorage(const OptionManagerContainer& /*managers*/) const override
+ {
+ // TODO: Implement storeCount() if necessary.
+ return internal::createEnumOptionStorage(*this, enumValues_, enumValuesCount_,
+ convertToInt(MyBase::defaultValue()),
+ convertToInt(MyBase::defaultValueIfSet()),
+ std::make_unique<internal::EnumIndexStore<EnumType>>(
+ MyBase::store(), MyBase::storeVector()));
+ }
+
+ const char* const* enumValues_;
+ int enumValuesCount_;
+
+ /*! \brief
+ * Needed to initialize EnumOptionStorage from this class without
+ * otherwise unnecessary accessors.
+ */
+ friend class EnumOptionStorage;
+};
+
+/*! \brief
+* Specifies an option that accepts enumerated string values and writes the
+* selected index into an `enum` variable.
+*
+* \tparam EnumType Type of the variable that receives the values
+* (can also be `int`).
+*
+* Examples:
+* \code
+ enum MyEnum { eAtom, eRes, eMol };
+ using gmx::LegacyEnumOption;
+ const char * const allowed[] = { "atom", "residue", "molecule" };
+ MyEnum value = eAtom; // default value
+ options.addOption(LegacyEnumOption<MyEnum>("type").enumValue(allowed).store(&value));
+* \endcode
+*
+* Works exactly as EnumOption.
+*
+* This is legacy support for pargsToOptions and can be removed when it
+* is removed. No new uses of it should be made.
+*
+* Public methods in this class do not throw.
+*
+* \inpublicapi
+*/
+template<typename EnumType>
+class LegacyEnumOption : public OptionTemplate<EnumType, LegacyEnumOption<EnumType>>
+{
+public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef EnumOptionInfo InfoType;
+
+ // This needs to be duplicated from OptionTemplate because this class
+ // is a template.
+ //! Short-hand for the base class.
+ typedef OptionTemplate<EnumType, LegacyEnumOption<EnumType>> MyBase;
+
+ //! Initializes an option with the given name.
+ explicit LegacyEnumOption(const char* name) :
+ MyBase(name),
+ enumValues_(nullptr),
+ enumValuesCount_(0)
+ {
+ }
+
/*! \brief
* Sets the option to only accept one of a fixed set of strings.
*
* The strings are copied once the option is created.
*/
template<size_t count>
- EnumOption& enumValue(const char* const (&values)[count])
+ LegacyEnumOption& enumValue(const char* const (&values)[count])
{
GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified");
enumValues_ = values;
*
* \see enumValue()
*/
- EnumOption& enumValueFromNullTerminatedArray(const char* const* values)
+ LegacyEnumOption& enumValueFromNullTerminatedArray(const char* const* values)
{
GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified");
enumValues_ = values;
}
private:
- //! Helper function to convert default values for storate initialization.
+ //! Helper function to convert default values for storage initialization.
static int convertToInt(const EnumType* defaultValue)
{
return defaultValue != nullptr ? static_cast<int>(*defaultValue) : -1;
friend class EnumOptionStorage;
};
-//! Shorthand for an enumerated option that stores into an `int` variable.
-typedef EnumOption<int> EnumIntOption;
-
/*! \brief
* Wrapper class for accessing boolean option information.
*
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2017, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
*/
//! Enum type for EnumOption tests.
-enum TestEnum
+enum class TestEnum : int
{
- etestNone,
- etestTest,
- etestValue,
- etestNR
+ None,
+ Test,
+ Value,
+ Count
};
+//! Set of allowed values for enum option tests.
+const gmx::EnumerationArray<TestEnum, const char*> c_testEnumNames = { { "none", "test", "value" } };
TEST(OptionsAssignerEnumTest, StoresSingleValue)
{
gmx::Options options;
- TestEnum value = etestNone;
+ TestEnum value = TestEnum::None;
using gmx::EnumOption;
- ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_allowed)));
- EXPECT_EQ(etestNone, value);
+ ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_testEnumNames)));
+ EXPECT_EQ(TestEnum::None, value);
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(etestTest, value);
+ EXPECT_EQ(TestEnum::Test, value);
}
TEST(OptionsAssignerEnumTest, StoresVectorValues)
std::vector<TestEnum> values;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
- EnumOption<TestEnum>("p").storeVector(&values).multiValue().enumValue(c_allowed)));
+ EnumOption<TestEnum>("p").storeVector(&values).multiValue().enumValue(c_testEnumNames)));
EXPECT_TRUE(values.empty());
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(options.finish());
ASSERT_EQ(2U, values.size());
- EXPECT_EQ(etestTest, values[0]);
- EXPECT_EQ(etestValue, values[1]);
+ EXPECT_EQ(TestEnum::Test, values[0]);
+ EXPECT_EQ(TestEnum::Value, values[1]);
}
TEST(OptionsAssignerEnumTest, HandlesInitialValueOutOfRange)
{
gmx::Options options;
- TestEnum value = etestNR;
+ TestEnum value = TestEnum::Count;
using gmx::EnumOption;
- ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_allowed)));
- EXPECT_EQ(etestNR, value);
+ ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_testEnumNames)));
+ EXPECT_EQ(TestEnum::Count, value);
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(etestNR, value);
+ EXPECT_EQ(TestEnum::Count, value);
}
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValue)
{
gmx::Options options;
- TestEnum value = etestNone;
+ TestEnum value = TestEnum::None;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
- EnumOption<TestEnum>("p").store(&value).enumValue(c_allowed).defaultValue(etestTest)));
- EXPECT_EQ(etestTest, value);
+ EnumOption<TestEnum>("p").store(&value).enumValue(c_testEnumNames).defaultValue(TestEnum::Test)));
+ EXPECT_EQ(TestEnum::Test, value);
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(etestTest, value);
+ EXPECT_EQ(TestEnum::Test, value);
}
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVariable)
{
gmx::Options options;
- TestEnum value = etestTest;
+ TestEnum value = TestEnum::Test;
using gmx::EnumOption;
- ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_allowed)));
- EXPECT_EQ(etestTest, value);
+ ASSERT_NO_THROW(options.addOption(EnumOption<TestEnum>("p").store(&value).enumValue(c_testEnumNames)));
+ EXPECT_EQ(TestEnum::Test, value);
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
- EXPECT_EQ(etestTest, value);
+ EXPECT_EQ(TestEnum::Test, value);
}
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVector)
{
gmx::Options options;
std::vector<TestEnum> value;
- value.push_back(etestNone);
- value.push_back(etestTest);
+ value.push_back(TestEnum::None);
+ value.push_back(TestEnum::Test);
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
- EnumOption<TestEnum>("p").storeVector(&value).valueCount(2).enumValue(c_allowed)));
+ EnumOption<TestEnum>("p").storeVector(&value).valueCount(2).enumValue(c_testEnumNames)));
ASSERT_EQ(2U, value.size());
- EXPECT_EQ(etestNone, value[0]);
- EXPECT_EQ(etestTest, value[1]);
+ EXPECT_EQ(TestEnum::None, value[0]);
+ EXPECT_EQ(TestEnum::Test, value[1]);
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
EXPECT_NO_THROW(options.finish());
ASSERT_EQ(2U, value.size());
- EXPECT_EQ(etestNone, value[0]);
- EXPECT_EQ(etestTest, value[1]);
+ EXPECT_EQ(TestEnum::None, value[0]);
+ EXPECT_EQ(TestEnum::Test, value[1]);
}
} // namespace
TEST(TimeUnitManagerTest, BasicOperations)
{
gmx::TimeUnitManager manager;
- EXPECT_EQ(gmx::TimeUnit_ps, manager.timeUnit());
+ EXPECT_EQ(gmx::TimeUnit::Picoseconds, manager.timeUnit());
EXPECT_DOUBLE_EQ(1.0, manager.timeScaleFactor());
- manager.setTimeUnit(gmx::TimeUnit_ns);
- EXPECT_EQ(gmx::TimeUnit_ns, manager.timeUnit());
+ manager.setTimeUnit(gmx::TimeUnit::Nanoseconds);
+ EXPECT_EQ(gmx::TimeUnit::Nanoseconds, manager.timeUnit());
EXPECT_DOUBLE_EQ(1e3, manager.timeScaleFactor());
EXPECT_DOUBLE_EQ(1e-3, manager.inverseTimeScaleFactor());
}
EXPECT_NO_THROW_GMX(assigner.finish());
EXPECT_DOUBLE_EQ(1.5, value);
- behavior.setTimeUnit(gmx::TimeUnit_ns);
+ behavior.setTimeUnit(gmx::TimeUnit::Nanoseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1500, value);
EXPECT_NO_THROW_GMX(options.finish());
- behavior.setTimeUnit(gmx::TimeUnit_us);
+ behavior.setTimeUnit(gmx::TimeUnit::Microseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1500000, value);
- behavior.setTimeUnit(gmx::TimeUnit_fs);
+ behavior.setTimeUnit(gmx::TimeUnit::Femtoseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(0.0015, value);
- behavior.setTimeUnit(gmx::TimeUnit_ps);
+ behavior.setTimeUnit(gmx::TimeUnit::Picoseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1.5, value);
}
EXPECT_NO_THROW_GMX(options.finish());
EXPECT_DOUBLE_EQ(2.5, value2);
- behavior.setTimeUnit(gmx::TimeUnit_ns);
+ behavior.setTimeUnit(gmx::TimeUnit::Nanoseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1.5, value);
EXPECT_DOUBLE_EQ(2.5, value2);
EXPECT_NO_THROW_GMX(options.finish());
EXPECT_DOUBLE_EQ(1.5, value);
- behavior.setTimeUnit(gmx::TimeUnit_ns);
+ behavior.setTimeUnit(gmx::TimeUnit::Nanoseconds);
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1500, value);
}
EXPECT_NO_THROW_GMX(assigner.finish());
EXPECT_DOUBLE_EQ(1.5, value);
- EXPECT_EQ(gmx::TimeUnit_ns, behavior.timeUnit());
+ EXPECT_EQ(gmx::TimeUnit::Nanoseconds, behavior.timeUnit());
behavior.optionsFinishing(&options);
EXPECT_DOUBLE_EQ(1500, value);
/*
* 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.
runTest();
}
-TEST_F(TreeValueSupportTest, SupportsEnumIntOption)
-{
- const char* const values[] = { "foo", "bar" };
- options_.addOption(gmx::EnumIntOption("a").enumValue(values).defaultValue(0));
- runTest();
-}
-
//! Enum for testing EnumOption.
-enum class TestEnum
+enum class TestEnum : int
{
Foo,
Bar
TEST_F(TreeValueSupportTest, SupportsEnumOption)
{
- const char* const values[] = { "foo", "bar" };
- options_.addOption(gmx::EnumOption<TestEnum>("a").enumValue(values).defaultValue(TestEnum::Foo));
+ enum class TestEnum : int
+ {
+ Foo,
+ Bar,
+ Count
+ };
+ const gmx::EnumerationArray<TestEnum, const char*> testEnumNames = { { "foo", "bar" } };
+ options_.addOption(gmx::EnumOption<TestEnum>("a").enumValue(testEnumNames).defaultValue(TestEnum::Foo));
runTest();
}
#include "gromacs/options/options.h"
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
+namespace gmx
+{
+
namespace
{
*
* These must correspond to the TimeUnit enum in the header!
*/
-const char* const g_timeUnits[] = { "fs", "ps", "ns", "us", "ms", "s" };
+const EnumerationArray<TimeUnit, const char*> c_timeUnitNames = { { "fs", "ps", "ns", "us", "ms",
+ "s" } };
/*! \brief
* Scaling factors from each time unit to internal units (=picoseconds).
*
* These must correspond to the TimeUnit enum in the header!
*/
-const double g_timeScaleFactors[] = { 1e-3, 1, 1e3, 1e6, 1e9, 1e12 };
+const EnumerationArray<TimeUnit, double> c_timeUnitScaleFactors = { { 1e-3, 1, 1e3, 1e6, 1e9, 1e12 } };
} // namespace
-namespace gmx
-{
-
-TimeUnitManager::TimeUnitManager() : timeUnit_(TimeUnit_Default) {}
+TimeUnitManager::TimeUnitManager() : timeUnit_(TimeUnit::Default) {}
-TimeUnitManager::TimeUnitManager(TimeUnit unit) : timeUnit_(unit)
-{
- GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit");
-}
+TimeUnitManager::TimeUnitManager(TimeUnit unit) : timeUnit_(unit) {}
void TimeUnitManager::setTimeUnit(TimeUnit unit)
{
- GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit");
timeUnit_ = unit;
}
const char* TimeUnitManager::timeUnitAsString() const
{
- GMX_RELEASE_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, "Invalid time unit");
- return g_timeUnits[timeUnit_];
+ return c_timeUnitNames[timeUnit_];
}
double TimeUnitManager::timeScaleFactor() const
{
- GMX_RELEASE_ASSERT(timeUnit_ >= 0
- && static_cast<size_t>(timeUnit_)
- < sizeof(g_timeScaleFactors) / sizeof(g_timeScaleFactors[0]),
- "Time unit index has become out-of-range");
- return g_timeScaleFactors[timeUnit_];
+ return c_timeUnitScaleFactors[timeUnit_];
}
double TimeUnitManager::inverseTimeScaleFactor() const
* TimeUnitBehavior
*/
-TimeUnitBehavior::TimeUnitBehavior() : timeUnit_(TimeUnit_Default), timeUnitStore_(nullptr) {}
+TimeUnitBehavior::TimeUnitBehavior() : timeUnit_(TimeUnit::Default), timeUnitStore_(nullptr) {}
void TimeUnitBehavior::setTimeUnit(TimeUnit unit)
{
- GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit");
timeUnit_ = unit;
if (timeUnitStore_ != nullptr)
{
const char* const value = std::getenv("GMXTIMEUNIT");
if (value != nullptr)
{
- ArrayRef<const char* const> timeUnits(g_timeUnits);
- ArrayRef<const char* const>::const_iterator i =
- std::find(timeUnits.begin(), timeUnits.end(), std::string(value));
- if (i == timeUnits.end())
+ TimeUnit result = TimeUnit::Count;
+ for (TimeUnit t : keysOf(c_timeUnitNames))
+ {
+ if (std::strcmp(value, c_timeUnitNames[t]) == 0)
+ {
+ result = t;
+ break;
+ }
+ }
+ if (result == TimeUnit::Count)
{
std::string message = formatString(
"Time unit provided with environment variable GMXTIMEUNIT=%s "
"is not recognized as a valid time unit.\n"
"Possible values are: %s",
- value, joinStrings(timeUnits, ", ").c_str());
+ value, joinStrings(c_timeUnitNames, ", ").c_str());
GMX_THROW(InvalidInputError(message));
}
- setTimeUnit(static_cast<TimeUnit>(i - timeUnits.begin()));
+ setTimeUnit(result);
}
}
void TimeUnitBehavior::addTimeUnitOption(IOptionsContainer* options, const char* name)
{
options->addOption(
- EnumOption<TimeUnit>(name).enumValue(g_timeUnits).store(&timeUnit_).description("Unit for time values"));
+ EnumOption<TimeUnit>(name).enumValue(c_timeUnitNames).store(&timeUnit_).description("Unit for time values"));
}
namespace
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,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.
#ifndef GMX_OPTIONS_TIMEUNITMANAGER_H
#define GMX_OPTIONS_TIMEUNITMANAGER_H
+#include "gromacs/fileio/oenv.h"
#include "gromacs/options/ioptionsbehavior.h"
#include "gromacs/utility/classhelpers.h"
-#include "gromacs/utility/gmxassert.h"
namespace gmx
{
class IOptionsContainer;
class Options;
-/*! \brief
- * Time values for TimeUnitManager.
- *
- * \if internal
- * Currently, this should match with the time_unit_t enum defined in oenv.h
- * except that there is no NULL first item in this enum.
- * \endif
- *
- * \inpublicapi
- */
-enum TimeUnit
-{
- TimeUnit_fs, //!< Femtoseconds.
- TimeUnit_ps, //!< Picoseconds.
- TimeUnit_ns, //!< Nanoseconds.
- TimeUnit_us, //!< Microseconds.
- TimeUnit_ms, //!< Milliseconds.
- TimeUnit_s, //!< Seconds.
- TimeUnit_Default = TimeUnit_ps //!< Default time unit.
-};
-
/*! \brief
* Provides common functionality for time unit conversions.
*
explicit TimeUnitManager(TimeUnit unit);
//! Returns the currently selected time unit.
- TimeUnit timeUnit() const
- {
- GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s,
- "Time unit index has become out-of-range");
- return timeUnit_;
- }
+ TimeUnit timeUnit() const { return timeUnit_; }
//! Set a new time unit for the manager.
void setTimeUnit(TimeUnit unit);
TimeUnitBehavior();
//! Returns the current time unit.
- TimeUnit timeUnit() const
- {
- GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s,
- "Time unit index has become out-of-range");
- return static_cast<TimeUnit>(timeUnit_);
- }
+ TimeUnit timeUnit() const { return timeUnit_; }
//! Sets the time unit.
void setTimeUnit(TimeUnit unit);
e_poscalc_t post;
size_t i;
int flags;
- bool bDebug = (coll->impl_->debugLevel_ >= 2 && coll->impl_->debugLevel_ != 3);
+ bool bDebug = (coll->impl_->debugLevel_ == SelectionCollection::Impl::DebugLevel::Compiled
+ && coll->impl_->debugLevel_ == SelectionCollection::Impl::DebugLevel::Full);
/* FIXME: Clean up the collection on exceptions */
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2010-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
* SelectionCollection::Impl
*/
-SelectionCollection::Impl::Impl() : debugLevel_(0), bExternalGroupsSet_(false), grps_(nullptr)
+SelectionCollection::Impl::Impl() :
+ debugLevel_(DebugLevel::None),
+ bExternalGroupsSet_(false),
+ grps_(nullptr)
{
sc_.nvars = 0;
sc_.varstrs = nullptr;
void SelectionCollection::initOptions(IOptionsContainer* options, SelectionTypeOption selectionTypeOption)
{
- const char* const debug_levels[] = { "no", "basic", "compile", "eval", "full" };
+ static const EnumerationArray<Impl::DebugLevel, const char*> s_debugLevelNames = {
+ { "no", "basic", "compile", "eval", "full" }
+ };
const char* const* postypes = PositionCalculationCollection::typeEnumValues;
options->addOption(StringOption("selrpos")
{
impl_->spost_ = postypes[0];
}
- GMX_RELEASE_ASSERT(impl_->debugLevel_ >= 0 && impl_->debugLevel_ <= 4,
- "Debug level out of range");
- options->addOption(EnumIntOption("seldebug")
- .hidden(impl_->debugLevel_ == 0)
- .enumValue(debug_levels)
+ GMX_RELEASE_ASSERT(impl_->debugLevel_ != Impl::DebugLevel::Count, "Debug level out of range");
+ options->addOption(EnumOption<Impl::DebugLevel>("seldebug")
+ .hidden(impl_->debugLevel_ == Impl::DebugLevel::None)
+ .enumValue(s_debugLevelNames)
.store(&impl_->debugLevel_)
.description("Print out selection trees for debugging"));
}
void SelectionCollection::setDebugLevel(int debugLevel)
{
- impl_->debugLevel_ = debugLevel;
+ impl_->debugLevel_ = Impl::DebugLevel(debugLevel);
}
{
setIndexGroups(nullptr);
}
- if (impl_->debugLevel_ >= 1)
+ if (impl_->debugLevel_ != Impl::DebugLevel::None)
{
printTree(stderr, false);
}
SelectionCompiler compiler;
compiler.compile(this);
- if (impl_->debugLevel_ >= 1)
+ if (impl_->debugLevel_ != Impl::DebugLevel::None)
{
std::fprintf(stderr, "\n");
printTree(stderr, false);
std::fprintf(stderr, "\n");
}
impl_->sc_.pcc.initEvaluation();
- if (impl_->debugLevel_ >= 1)
+ if (impl_->debugLevel_ != Impl::DebugLevel::None)
{
impl_->sc_.pcc.printTree(stderr);
std::fprintf(stderr, "\n");
SelectionEvaluator evaluator;
evaluator.evaluate(this, fr, pbc);
- if (impl_->debugLevel_ >= 3)
+ if (impl_->debugLevel_ == Impl::DebugLevel::Evaluated || impl_->debugLevel_ == Impl::DebugLevel::Full)
{
std::fprintf(stderr, "\n");
printTree(stderr, true);
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2009-2016, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
SelectionTopologyProperties requiredTopologyPropertiesForPositionType(const std::string& post,
bool forces) const;
+ //! Describes the available debugging levels
+ enum class DebugLevel : int
+ {
+ //! No debugging
+ None,
+ //! Print selection trees after parsing and compilation
+ Basic,
+ //! As PrintCompiled, also print intermediate compilation trees
+ Compiled,
+ //! As PrintCompiled, also print the tree after evaluation
+ Evaluated,
+ //! Combine Compiled and Evaluated
+ Full,
+ //! Ends the enumeration
+ Count
+ };
+
//! Internal data, used for interfacing with old C code.
gmx_ana_selcollection_t sc_;
//! Default reference position type for selections.
std::string spost_;
//! Atoms needed for evaluating the selections.
gmx_ana_index_t requiredAtoms_;
- /*! \brief
- * Debugging level for the collection.
- *
- * Possible values:
- * - 0: no debugging
- * - 1: print selection trees after parsing and compilation
- * - 2: like 1, also print intermediate compilation trees
- * - 3: like 1, also print the tree after evaluation
- * - 4: combine 2 and 3
- */
- int debugLevel_;
+ //! Debugging level for the collection.
+ DebugLevel debugLevel_;
//! Whether setIndexGroups() has been called.
bool bExternalGroupsSet_;
//! External index groups (can be NULL).
public:
//! Initializes the default values for the settings object.
Impl() :
- timeUnit(TimeUnit_Default),
+ timeUnit(TimeUnit::Default),
flags(0),
frflags(0),
bRmPBC(true),
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
#include "gromacs/trajectory/trajectoryframe.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
*/
//! How to interpret the selections in -group1.
-enum Group1Type
+enum class Group1Type : int
{
- Group1Type_Angle,
- Group1Type_Dihedral,
- Group1Type_Vector,
- Group1Type_Plane
+ Angle,
+ Dihedral,
+ Vector,
+ Plane,
+ Count
};
//! How to interpret the selections in -group2.
-enum Group2Type
+enum class Group2Type : int
{
- Group2Type_None,
- Group2Type_Vector,
- Group2Type_Plane,
- Group2Type_TimeZero,
- Group2Type_Z,
- Group2Type_SphereNormal
+ None,
+ Vector,
+ Plane,
+ TimeZero,
+ Z,
+ SphereNormal,
+ Count
};
//! String values corresponding to Group1Type.
-const char* const cGroup1TypeEnum[] = { "angle", "dihedral", "vector", "plane" };
+const EnumerationArray<Group1Type, const char*> c_group1TypeEnumNames = { { "angle", "dihedral",
+ "vector", "plane" } };
//! String values corresponding to Group2Type.
-const char* const cGroup2TypeEnum[] = { "none", "vector", "plane", "t0", "z", "sphnorm" };
+const EnumerationArray<Group2Type, const char*> c_group2TypeEnumNames = {
+ { "none", "vector", "plane", "t0", "z", "sphnorm" }
+};
class Angle : public TrajectoryAnalysisModule
{
Angle::Angle() :
sel1info_(nullptr),
sel2info_(nullptr),
- g1type_(Group1Type_Angle),
- g2type_(Group2Type_None),
+ g1type_(Group1Type::Angle),
+ g2type_(Group2Type::None),
binWidth_(1.0),
natoms1_(0),
natoms2_(0)
.defaultBasename("anghist")
.description("Histogram of the angles"));
+ options->addOption(EnumOption<Group1Type>("g1")
+ .enumValue(c_group1TypeEnumNames)
+ .store(&g1type_)
+ .description("Type of analysis/first vector group"));
options->addOption(
- EnumOption<Group1Type>("g1").enumValue(cGroup1TypeEnum).store(&g1type_).description("Type of analysis/first vector group"));
- options->addOption(
- EnumOption<Group2Type>("g2").enumValue(cGroup2TypeEnum).store(&g2type_).description("Type of second vector group"));
+ EnumOption<Group2Type>("g2").enumValue(c_group2TypeEnumNames).store(&g2type_).description("Type of second vector group"));
options->addOption(
DoubleOption("binw").store(&binWidth_).description("Binwidth for -oh in degrees"));
void Angle::optionsFinished(TrajectoryAnalysisSettings* /* settings */)
{
- const bool bSingle = (g1type_ == Group1Type_Angle || g1type_ == Group1Type_Dihedral);
+ const bool bSingle = (g1type_ == Group1Type::Angle || g1type_ == Group1Type::Dihedral);
- if (bSingle && g2type_ != Group2Type_None)
+ if (bSingle && g2type_ != Group2Type::None)
{
GMX_THROW(
InconsistentInputError("Cannot use a second group (-g2) with "
InconsistentInputError("Cannot provide a second selection "
"(-group2) with -g1 angle or dihedral"));
}
- if (!bSingle && g2type_ == Group2Type_None)
+ if (!bSingle && g2type_ == Group2Type::None)
{
GMX_THROW(
InconsistentInputError("Should specify a second group (-g2) "
// Set up the number of positions per angle.
switch (g1type_)
{
- case Group1Type_Angle: natoms1_ = 3; break;
- case Group1Type_Dihedral: natoms1_ = 4; break;
- case Group1Type_Vector: natoms1_ = 2; break;
- case Group1Type_Plane: natoms1_ = 3; break;
+ case Group1Type::Angle: natoms1_ = 3; break;
+ case Group1Type::Dihedral: natoms1_ = 4; break;
+ case Group1Type::Vector: natoms1_ = 2; break;
+ case Group1Type::Plane: natoms1_ = 3; break;
default: GMX_THROW(InternalError("invalid -g1 value"));
}
switch (g2type_)
{
- case Group2Type_None: natoms2_ = 0; break;
- case Group2Type_Vector: natoms2_ = 2; break;
- case Group2Type_Plane: natoms2_ = 3; break;
- case Group2Type_TimeZero: natoms2_ = 0; break;
- case Group2Type_Z: natoms2_ = 0; break;
- case Group2Type_SphereNormal: natoms2_ = 1; break;
+ case Group2Type::None: natoms2_ = 0; break;
+ case Group2Type::Vector: natoms2_ = 2; break;
+ case Group2Type::Plane: natoms2_ = 3; break;
+ case Group2Type::TimeZero: // Intended to fall through
+ case Group2Type::Z: natoms2_ = 0; break;
+ case Group2Type::SphereNormal: natoms2_ = 1; break;
default: GMX_THROW(InternalError("invalid -g2 value"));
}
if (natoms2_ == 0 && sel2info_->isSet())
"divisible by %d",
static_cast<int>(g + 1), natoms2_)));
}
- if (g2type_ == Group2Type_SphereNormal && posCount2 != 1)
+ if (g2type_ == Group2Type::SphereNormal && posCount2 != 1)
{
GMX_THROW(InconsistentInputError(
"The second group should contain a single position with -g2 sphnorm"));
{
angles_.setColumnCount(i, angleCount_[i]);
}
- double histogramMin = (g1type_ == Group1Type_Dihedral ? -180.0 : 0);
+ double histogramMin = (g1type_ == Group1Type::Dihedral ? -180.0 : 0);
histogramModule_->init(histogramFromRange(histogramMin, 180.0).binWidth(binWidth_).includeAll());
- if (g2type_ == Group2Type_TimeZero)
+ if (g2type_ == Group2Type::TimeZero)
{
vt0_.resize(sel1_.size());
for (size_t g = 0; g < sel1_.size(); ++g)
switch (g2type_)
{
- case Group2Type_Z: v2[ZZ] = 1.0; break;
- case Group2Type_SphereNormal: copy_rvec(sel2_[g].position(0).x(), c2); break;
+ case Group2Type::Z: v2[ZZ] = 1.0; break;
+ case Group2Type::SphereNormal: copy_rvec(sel2_[g].position(0).x(), c2); break;
default:
// do nothing
break;
iter1.getCurrentPositions(x);
switch (g1type_)
{
- case Group1Type_Angle:
+ case Group1Type::Angle:
if (pbc)
{
pbc_dx(pbc, x[0], x[1], v1);
}
angle = gmx_angle(v1, v2);
break;
- case Group1Type_Dihedral:
+ case Group1Type::Dihedral:
{
rvec dx[3];
if (pbc)
}
break;
}
- case Group1Type_Vector:
- case Group1Type_Plane:
+ case Group1Type::Vector:
+ case Group1Type::Plane:
calc_vec(natoms1_, x, pbc, v1, c1);
switch (g2type_)
{
- case Group2Type_Vector:
- case Group2Type_Plane:
+ case Group2Type::Vector:
+ case Group2Type::Plane:
iter2.getCurrentPositions(x);
calc_vec(natoms2_, x, pbc, v2, c2);
break;
- case Group2Type_TimeZero:
+ case Group2Type::TimeZero:
// FIXME: This is not parallelizable.
if (frnr == 0)
{
}
copy_rvec(vt0_[g][n], v2);
break;
- case Group2Type_Z: c1[XX] = c1[YY] = 0.0; break;
- case Group2Type_SphereNormal:
+ case Group2Type::Z: c1[XX] = c1[YY] = 0.0; break;
+ case Group2Type::SphereNormal:
if (pbc)
{
pbc_dx(pbc, c1, c2, v2);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,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.
//! \{
//! Enum value to store the selected value for `-type`.
-enum DistanceType
+enum class DistanceType : int
{
- eDistanceType_Min,
- eDistanceType_Max
+ Min,
+ Max,
+ Count
};
//! Enum value to store the selected value for `-refgrouping`/`-selgrouping`.
-enum GroupType
+enum class GroupType : int
{
- eGroupType_All,
- eGroupType_Residue,
- eGroupType_Molecule,
- eGroupType_None
+ All,
+ Residue,
+ Molecule,
+ None,
+ Count
};
//! Strings corresponding to DistanceType.
-const char* const c_distanceTypes[] = { "min", "max" };
+const EnumerationArray<DistanceType, const char*> c_distanceTypeNames = { { "min", "max" } };
//! Strings corresponding to GroupType.
-const char* const c_groupTypes[] = { "all", "res", "mol", "none" };
+const EnumerationArray<GroupType, const char*> c_groupTypeNames = { { "all", "res", "mol",
+ "none" } };
/*! \brief
* Implements `gmx pairdist` trajectory analysis module.
PairDistance::PairDistance() :
cutoff_(0.0),
- distanceType_(eDistanceType_Min),
- refGroupType_(eGroupType_All),
- selGroupType_(eGroupType_All),
+ distanceType_(DistanceType::Min),
+ refGroupType_(GroupType::All),
+ selGroupType_(GroupType::All),
refGroupCount_(0),
maxGroupCount_(0),
initialDist2_(0.0),
DoubleOption("cutoff").store(&cutoff_).description("Maximum distance to consider"));
options->addOption(EnumOption<DistanceType>("type")
.store(&distanceType_)
- .enumValue(c_distanceTypes)
+ .enumValue(c_distanceTypeNames)
.description("Type of distances to calculate"));
options->addOption(
EnumOption<GroupType>("refgrouping")
.store(&refGroupType_)
- .enumValue(c_groupTypes)
+ .enumValue(c_groupTypeNames)
.description("Grouping of -ref positions to compute the min/max over"));
options->addOption(
EnumOption<GroupType>("selgrouping")
.store(&selGroupType_)
- .enumValue(c_groupTypes)
+ .enumValue(c_groupTypeNames)
.description("Grouping of -sel positions to compute the min/max over"));
options->addOption(SelectionOption("ref").store(&refSel_).required().description(
}
//! Helper function to initialize the grouping for a selection.
-int initSelectionGroups(Selection* sel, const gmx_mtop_t* top, int type)
+int initSelectionGroups(Selection* sel, const gmx_mtop_t* top, GroupType type)
{
e_index_t indexType = INDEX_UNKNOWN;
switch (type)
{
- case eGroupType_All: indexType = INDEX_ALL; break;
- case eGroupType_Residue: indexType = INDEX_RES; break;
- case eGroupType_Molecule: indexType = INDEX_MOL; break;
- case eGroupType_None: indexType = INDEX_ATOM; break;
+ case GroupType::All: indexType = INDEX_ALL; break;
+ case GroupType::Residue: indexType = INDEX_RES; break;
+ case GroupType::Molecule: indexType = INDEX_MOL; break;
+ case GroupType::None: indexType = INDEX_ATOM; break;
+ case GroupType::Count: GMX_THROW(InternalError("Invalid GroupType"));
}
return sel->initOriginalIdsToGroup(top, indexType);
}
{
AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings()));
plotm->setFileName(fnDist_);
- if (distanceType_ == eDistanceType_Max)
+ if (distanceType_ == DistanceType::Max)
{
plotm->setTitle("Maximum distance");
}
{
initialDist2_ = cutoff_ * cutoff_;
}
- if (distanceType_ == eDistanceType_Max)
+ if (distanceType_ == DistanceType::Max)
{
initialDist2_ = 0.0;
}
const int selIndex = selPos.mappedId();
const int index = selIndex * refGroupCount_ + refIndex;
const real r2 = pair.distance2();
- if (distanceType_ == eDistanceType_Min)
+ if (distanceType_ == DistanceType::Min)
{
if (distArray[index] > r2)
{
// update the distance if necessary and the count.
if (countArray[index] < totalCount)
{
- if (distanceType_ == eDistanceType_Max)
+ if (distanceType_ == DistanceType::Max)
{
distArray[index] = cutoff2_;
}
*/
//! Normalization for the computed distribution.
-enum Normalization
+enum class Normalization : int
{
- Normalization_Rdf,
- Normalization_NumberDensity,
- Normalization_None
+ Rdf,
+ NumberDensity,
+ None,
+ Count
};
//! String values corresponding to Normalization.
-const char* const c_NormalizationEnum[] = { "rdf", "number_density", "none" };
+const EnumerationArray<Normalization, const char*> c_normalizationNames = {
+ { "rdf", "number_density", "none" }
+};
//! Whether to compute RDF wrt. surface of the reference group.
-enum SurfaceType
+enum class SurfaceType : int
{
- SurfaceType_None,
- SurfaceType_Molecule,
- SurfaceType_Residue
+ None,
+ Molecule,
+ Residue,
+ Count
};
//! String values corresponding to SurfaceType.
-const char* const c_SurfaceEnum[] = { "no", "mol", "res" };
+const EnumerationArray<SurfaceType, const char*> c_surfaceTypeNames = { { "no", "mol", "res" } };
/*! \brief
* Implements `gmx rdf` trajectory analysis module.
};
Rdf::Rdf() :
- surface_(SurfaceType_None),
+ surface_(SurfaceType::None),
pairCounts_(new AnalysisDataSimpleHistogramModule()),
normAve_(new AnalysisDataAverageModule()),
localTop_(nullptr),
binwidth_(0.002),
cutoff_(0.0),
rmax_(0.0),
- normalization_(Normalization_Rdf),
+ normalization_(Normalization::Rdf),
bNormalizationSet_(false),
bXY_(false),
bExclusions_(false),
options->addOption(DoubleOption("bin").store(&binwidth_).description("Bin width (nm)"));
options->addOption(EnumOption<Normalization>("norm")
- .enumValue(c_NormalizationEnum)
+ .enumValue(c_normalizationNames)
.store(&normalization_)
.storeIsSet(&bNormalizationSet_)
.description("Normalization"));
DoubleOption("rmax").store(&rmax_).description("Largest distance (nm) to calculate"));
options->addOption(EnumOption<SurfaceType>("surf")
- .enumValue(c_SurfaceEnum)
+ .enumValue(c_surfaceTypeNames)
.store(&surface_)
.description("RDF with respect to the surface of the reference"));
void Rdf::optionsFinished(TrajectoryAnalysisSettings* settings)
{
- if (surface_ != SurfaceType_None)
+ if (surface_ != SurfaceType::None)
{
settings->setFlag(TrajectoryAnalysisSettings::efRequireTop);
- if (bNormalizationSet_ && normalization_ != Normalization_None)
+ if (bNormalizationSet_ && normalization_ != Normalization::None)
{
GMX_THROW(InconsistentInputError("-surf cannot be combined with -norm"));
}
- normalization_ = Normalization_None;
+ normalization_ = Normalization::None;
if (bExclusions_)
{
GMX_THROW(InconsistentInputError("-surf cannot be combined with -excl"));
normFactors_.setColumnCount(0, sel_.size() + 1);
- const bool bSurface = (surface_ != SurfaceType_None);
+ const bool bSurface = (surface_ != SurfaceType::None);
if (bSurface)
{
if (!refSel_.hasOnlyAtoms())
{
GMX_THROW(InconsistentInputError("-surf only works with -ref that consists of atoms"));
}
- const e_index_t type = (surface_ == SurfaceType_Molecule ? INDEX_MOL : INDEX_RES);
+ const e_index_t type = (surface_ == SurfaceType::Molecule ? INDEX_MOL : INDEX_RES);
surfaceGroupCount_ = refSel_.initOriginalIdsToGroup(top.mtop(), type);
}
// through the dataset registration mechanism.
AverageHistogramPointer finalRdf = pairCounts_->averager().resampleDoubleBinWidth(true);
- if (normalization_ != Normalization_None)
+ if (normalization_ != Normalization::None)
{
// Normalize by the volume of the bins (volume of sphere segments or
// length of circle segments).
}
finalRdf->scaleAllByVector(invBinVolume.data());
- if (normalization_ == Normalization_Rdf)
+ if (normalization_ == Normalization::Rdf)
{
// Normalize by particle density.
for (size_t g = 0; g < sel_.size(); ++g)
*/
//! How to identify residues in output files.
-enum ResidueNumbering
+enum class ResidueNumbering : int
{
- ResidueNumbering_ByNumber,
- ResidueNumbering_ByIndex
+ ByNumber,
+ ByIndex,
+ Count
};
//! Which atoms to write out to PDB files.
-enum PdbAtomsSelection
+enum class PdbAtomsSelection : int
{
- PdbAtomsSelection_All,
- PdbAtomsSelection_MaxSelection,
- PdbAtomsSelection_Selected
+ All,
+ MaxSelection,
+ Selected,
+ Count
};
//! String values corresponding to ResidueNumbering.
-const char* const cResNumberEnum[] = { "number", "index" };
+const EnumerationArray<ResidueNumbering, const char*> c_residueNumberingTypeNames = { { "number",
+ "index" } };
//! String values corresponding to PdbAtomsSelection.
-const char* const cPDBAtomsEnum[] = { "all", "maxsel", "selected" };
+const EnumerationArray<PdbAtomsSelection, const char*> c_pdbAtomsTypeNames = { { "all", "maxsel",
+ "selected" } };
class Select : public TrajectoryAnalysisModule
{
bFracNorm_(false),
bResInd_(false),
bCumulativeLifetimes_(true),
- resNumberType_(ResidueNumbering_ByNumber),
- pdbAtoms_(PdbAtomsSelection_All),
+ resNumberType_(ResidueNumbering::ByNumber),
+ pdbAtoms_(PdbAtomsSelection::All),
top_(nullptr),
occupancyModule_(new AnalysisDataAverageModule()),
lifetimeModule_(new AnalysisDataLifetimeModule())
BooleanOption("cfnorm").store(&bFracNorm_).description("Normalize by covered fraction with -os"));
options->addOption(EnumOption<ResidueNumbering>("resnr")
.store(&resNumberType_)
- .enumValue(cResNumberEnum)
+ .enumValue(c_residueNumberingTypeNames)
.description("Residue number output type with -oi and -on"));
options->addOption(EnumOption<PdbAtomsSelection>("pdbatoms")
.store(&pdbAtoms_)
- .enumValue(cPDBAtomsEnum)
+ .enumValue(c_pdbAtomsTypeNames)
.description("Atoms to write with -ofpdb"));
options->addOption(BooleanOption("cumlt")
.store(&bCumulativeLifetimes_)
void Select::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top)
{
- bResInd_ = (resNumberType_ == ResidueNumbering_ByIndex);
+ bResInd_ = (resNumberType_ == ResidueNumbering::ByIndex);
for (SelectionList::iterator i = sel_.begin(); i != sel_.end(); ++i)
{
switch (pdbAtoms_)
{
- case PdbAtomsSelection_All:
+ case PdbAtomsSelection::All:
{
t_trxstatus* status = open_trx(fnPDB_.c_str(), "w");
write_trxframe(status, &fr, nullptr);
close_trx(status);
break;
}
- case PdbAtomsSelection_MaxSelection:
+ case PdbAtomsSelection::MaxSelection:
{
std::set<int> atomIndicesSet;
for (size_t g = 0; g < sel_.size(); ++g)
close_trx(status);
break;
}
- case PdbAtomsSelection_Selected:
+ case PdbAtomsSelection::Selected:
{
std::vector<int> indices;
for (int i = 0; i < atoms->nr; ++i)
close_trx(status);
break;
}
- default:
+ case PdbAtomsSelection::Count:
GMX_RELEASE_ASSERT(false,
"Mismatch between -pdbatoms enum values and implementation");
}
{
return;
}
- time_unit_t time_unit = static_cast<time_unit_t>(settings_.timeUnit() + 1); // NOLINT(bugprone-misplaced-widening-cast)
- output_env_init(&oenv_, getProgramContext(), time_unit, FALSE, exvgNONE, 0);
+ output_env_init(&oenv_, getProgramContext(), settings_.timeUnit(), FALSE, XvgFormat::None, 0);
int frflags = settings_.frflags();
frflags |= TRX_NEED_X;
Atoms stored in the trajectory file (if not set, assume first N
atoms)
-xvg <enum> (xmgrace)
- Plot formatting: none, xmgrace, xmgr
+ Plot formatting: xmgrace, xmgr, none
-[no]rmpbc (yes)
Make molecules whole for each frame
-[no]pbc (yes)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
settings->setHelpText(desc);
- const char* const cNbnxmSimdStrings[] = { "auto", "no", "4xm", "2xmm" };
- const char* const cCombRuleStrings[] = { "geometric", "lb", "none" };
- const char* const cCoulombTypeStrings[] = { "ewald", "reaction-field" };
+ static const EnumerationArray<Nbnxm::BenchMarkKernels, const char*> c_nbnxmSimdStrings = {
+ { "auto", "no", "4xm", "2xmm" }
+ };
+ static const EnumerationArray<Nbnxm::BenchMarkCombRule, const char*> c_combRuleStrings = {
+ { "geometric", "lb", "none" }
+ };
+ static const EnumerationArray<Nbnxm::BenchMarkCoulomb, const char*> c_coulombTypeStrings = {
+ { "ewald", "reaction-field" }
+ };
options->addOption(
IntegerOption("size").store(&sizeFactor_).description("The system size is 3000 atoms times this value"));
IntegerOption("nt").store(&benchmarkOptions_.numThreads).description("The number of OpenMP threads to use"));
options->addOption(EnumOption<Nbnxm::BenchMarkKernels>("simd")
.store(&benchmarkOptions_.nbnxmSimd)
- .enumValue(cNbnxmSimdStrings)
+ .enumValue(c_nbnxmSimdStrings)
.description("SIMD type, auto runs all supported SIMD setups or no "
"SIMD when SIMD is not supported"));
options->addOption(EnumOption<Nbnxm::BenchMarkCoulomb>("coulomb")
.store(&benchmarkOptions_.coulombType)
- .enumValue(cCoulombTypeStrings)
+ .enumValue(c_coulombTypeStrings)
.description("The functional form for the Coulomb interactions"));
options->addOption(
BooleanOption("table")
.description("Use lookup table for Ewald correction instead of analytical"));
options->addOption(EnumOption<Nbnxm::BenchMarkCombRule>("combrule")
.store(&benchmarkOptions_.ljCombinationRule)
- .enumValue(cCombRuleStrings)
+ .enumValue(c_combRuleStrings)
.description("The LJ combination rule"));
options->addOption(BooleanOption("halflj")
.store(&benchmarkOptions_.useHalfLJOptimization)
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
*/
TestReferenceDataImplPointer g_referenceData;
//! Global reference data mode set with setReferenceDataMode().
-ReferenceDataMode g_referenceDataMode = erefdataCompare;
+ReferenceDataMode g_referenceDataMode = ReferenceDataMode::Compare;
//! Returns the global reference data mode.
ReferenceDataMode getReferenceDataMode()
void initReferenceData(IOptionsContainer* options)
{
- // Needs to correspond to the enum order in refdata.h.
- const char* const refDataEnum[] = { "check", "create", "update-changed", "update-all" };
+ static const gmx::EnumerationArray<ReferenceDataMode, const char*> s_refDataNames = {
+ { "check", "create", "update-changed", "update-all" }
+ };
options->addOption(EnumOption<ReferenceDataMode>("ref-data")
- .enumValue(refDataEnum)
+ .enumValue(s_refDataNames)
.store(&g_referenceDataMode)
.description("Operation mode for tests that use reference data"));
::testing::UnitTest::GetInstance()->listeners().Append(new ReferenceDataTestEventListener);
switch (mode)
{
- case erefdataCompare:
+ case ReferenceDataMode::Compare:
if (File::exists(fullFilename_, File::throwOnError))
{
compareRootEntry_ = readReferenceDataFile(fullFilename_);
}
break;
- case erefdataCreateMissing:
+ case ReferenceDataMode::CreateMissing:
if (File::exists(fullFilename_, File::throwOnError))
{
compareRootEntry_ = readReferenceDataFile(fullFilename_);
outputRootEntry_ = ReferenceDataEntry::createRoot();
}
break;
- case erefdataUpdateChanged:
+ case ReferenceDataMode::UpdateChanged:
if (File::exists(fullFilename_, File::throwOnError))
{
compareRootEntry_ = readReferenceDataFile(fullFilename_);
outputRootEntry_ = ReferenceDataEntry::createRoot();
updateMismatchingEntries_ = true;
break;
- case erefdataUpdateAll:
+ case ReferenceDataMode::UpdateAll:
compareRootEntry_ = ReferenceDataEntry::createRoot();
outputRootEntry_ = ReferenceDataEntry::createRoot();
break;
+ case ReferenceDataMode::Count: GMX_THROW(InternalError("Invalid reference data mode"));
}
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2011-2018, The GROMACS development team.
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 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.
*
* \ingroup module_testutils
*/
-enum ReferenceDataMode
+enum class ReferenceDataMode : int
{
/*! \brief
* Compare to existing reference data.
* If reference data does not exist, or if the test results differ from
* those in the reference data, the test fails.
*/
- erefdataCompare,
+ Compare,
/*! \brief
* Create missing reference data.
*
* If reference data does not exist for a test, that test behaves as if
- * ::erefdataUpdateAll had been specified. Tests for which reference data
- * exists, behave like with ::erefdataCompare.
+ * ReferenceDataMode::UpdateAll had been specified. Tests for which reference data
+ * exists, behave like with ReferenceDataMode::Compare.
*/
- erefdataCreateMissing,
+ CreateMissing,
/*! \brief
* Update reference data that does not pass comparison.
*
* Tests utilizing reference data should always pass in this mode unless
* there is an I/O error.
*/
- erefdataUpdateChanged,
+ UpdateChanged,
/*! \brief
* Update reference data, overwriting old data.
*
* Tests utilizing reference data should always pass in this mode unless
* there is an I/O error.
*/
- erefdataUpdateAll
+ UpdateAll,
+ //! Marks the end of the enum
+ Count
};
/*! \libinternal \brief
* Initializes reference data handling.
*
* Adds command-line options to \p options to set the reference data mode.
- * By default, ::erefdataCompare is used, but ``--ref-data create`` or
+ * By default, ReferenceDataMode::Compare is used, but ``--ref-data create`` or
* ``--ref-data update`` can be used to change it.
*
* This function is automatically called by initTestUtils().
* \code
int functionToTest(int param);
+ namespace gmx
+ {
+ namespace test
+ {
TEST(MyTest, SimpleTest)
{
- gmx::test::TestReferenceData data;
+ TestReferenceData data;
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(functionToTest(3), "ValueWith3");
checker.checkInteger(functionToTest(5), "ValueWith5");
- gmx::test::TestReferenceChecker compound(
+ TestReferenceChecker compound(
checker.checkCompound("CustomCompound", "Item"));
compound.checkInteger(function2ToTest(3), "ValueWith3");
compound.checkInteger(function2ToTest(5), "ValueWith5");
checker.checkInteger(functionToTest(4), "ValueWith4");
}
+ } // namespace test
+ } // namespace gmx
* \endcode
*
* If rootChecker() is never called, no comparison is done (i.e., missing
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,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.
#include "testutils/refdata.h"
+namespace gmx
+{
+namespace test
+{
namespace
{
class InteractiveSession
{
public:
- explicit InteractiveSession(gmx::test::ReferenceDataMode mode) :
+ explicit InteractiveSession(ReferenceDataMode mode) :
data_(mode),
helper_(data_.rootChecker()),
nextInputLine_(0)
// The latter is the output string.
typedef std::pair<EventType, const char*> Event;
- gmx::test::TestReferenceData data_;
- gmx::test::InteractiveTestHelper helper_;
- std::vector<const char*> inputLines_;
- size_t nextInputLine_;
- std::vector<Event> events_;
+ TestReferenceData data_;
+ InteractiveTestHelper helper_;
+ std::vector<const char*> inputLines_;
+ size_t nextInputLine_;
+ std::vector<Event> events_;
};
TEST(InteractiveTestHelperTest, ChecksSimpleSession)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n");
session.addOutput("> ");
session.addInput("input");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n");
session.addOutput("> ");
session.addInput("input");
TEST(InteractiveTestHelperTest, ChecksSessionWithoutLastNewline)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n");
session.addOutput("> ");
session.addInput("input");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n");
session.addOutput("> ");
session.addInput("input");
TEST(InteractiveTestHelperTest, ChecksSessionWithMissingOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n> ");
session.addInput("input");
session.addInput("input2");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addInput("input2");
TEST(InteractiveTestHelperTest, ChecksSessionWithEquivalentOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n");
session.addOutput("> ");
session.addInput("input");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Second line\n");
TEST(InteractiveTestHelperTest, DetectsIncorrectOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Second line\n> ");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Incorrect line\n> ");
TEST(InteractiveTestHelperTest, DetectsMissingOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Second line\n> ");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addInput("input2");
TEST(InteractiveTestHelperTest, DetectsMissingFinalOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Second line\n> ");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Second line\n> ");
TEST(InteractiveTestHelperTest, DetectsExtraOutput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addOutput("First line\n> ");
session.addInput("input");
session.addInput("input2");
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addOutput("First line\n> ");
session.addInput("input");
session.addOutput("Extra output\n> ");
TEST(InteractiveTestHelperTest, DetectsMissingInput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addInput("input");
session.addInput("input2");
session.addReadInput();
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addInputLine("input");
session.addInputLine("input2");
session.addReadInput();
TEST(InteractiveTestHelperTest, DetectsExtraInput)
{
{
- InteractiveSession session(gmx::test::erefdataUpdateAll);
+ InteractiveSession session(ReferenceDataMode::UpdateAll);
session.addInput("input");
session.addInput("input2");
session.addReadInput();
session.run();
}
{
- InteractiveSession session(gmx::test::erefdataCompare);
+ InteractiveSession session(ReferenceDataMode::Compare);
session.addInputLine("input");
session.addInputLine("input2");
session.addReadInput();
}
} // namespace
+} // namespace test
+} // namespace gmx
#include "testutils/testasserts.h"
#include "testutils/testexceptions.h"
+
+namespace gmx
+{
+namespace test
+{
namespace
{
-using gmx::test::TestReferenceChecker;
-using gmx::test::TestReferenceData;
-
TEST(ReferenceDataTest, HandlesSimpleData)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkBoolean(true, "bool");
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkBoolean(true, "bool");
checker.checkInteger(1, "int");
const double doubleValue = 4.0 / 3.0;
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkDouble(doubleValue, "double");
checker.checkReal(doubleValue, "real");
checker.checkFloat(floatValue, "float");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkDouble(doubleValue, "double");
checker.checkReal(floatValue, "real");
TEST(ReferenceDataTest, HandlesPresenceChecks)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
EXPECT_TRUE(checker.checkPresent(true, "present"));
checker.checkInteger(1, "present");
EXPECT_FALSE(checker.checkPresent(false, "absent"));
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
// Assigned to avoid warnings about potentially uninitialized value.
bool bRet = true;
TEST(ReferenceDataTest, HandlesStringBlockData)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkTextBlock("Line1\nLine2\n", "block");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkTextBlock("Line1\nLine2\n", "block");
checker.checkString("Line1\nLine2\n", "block");
double vecd[3] = { -2.3, 1.43, 2.5 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkVector(veci, "ivec");
checker.checkVector(vecf, "fvec");
checker.checkVector(vecd, "dvec");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkVector(veci, "ivec");
checker.checkVector(vecf, "fvec");
const int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkSequenceArray(5, seq, "seq");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkSequenceArray(5, seq, "seq");
}
const dvec seq[] = { { -3, 4, 5 }, { -2.3, 5, 0 } };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkSequence(std::begin(seq), std::end(seq), "seq", checkCustomVector);
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkSequence(std::begin(seq), std::end(seq), "seq", checkCustomVector);
}
int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkDouble(0.5, "real");
checker.checkSequenceArray(5, seq, "seq");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkInteger(2, "int"), "");
EXPECT_NONFATAL_FAILURE(checker.checkDouble(0.3, "real"), "");
TEST(ReferenceDataTest, HandlesIncorrectDataType)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkCompound("Compound", "compound");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkString("1", "int"), "");
EXPECT_NONFATAL_FAILURE(checker.checkCompound("OtherCompound", "compound"), "");
const int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkSequenceArray(5, seq, "seq");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkInteger(1, "missing"), "");
EXPECT_NONFATAL_FAILURE(checker.checkSequenceArray(5, seq, "missing"), "");
const int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkSequenceArray(5, seq, "seq");
checker.checkUnusedEntries();
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
EXPECT_NONFATAL_FAILURE(checker.checkUnusedEntries(), "");
const int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkSequenceArray(5, seq, "seq");
checker.checkUnusedEntries();
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
EXPECT_NONFATAL_FAILURE(checker.checkSequenceArray(3, seq, "seq"), "");
TEST(ReferenceDataTest, HandlesUncheckedDataInCompound)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
TestReferenceChecker compound(checker.checkCompound("Compound", "Compound"));
compound.checkInteger(1, "int1");
checker.checkUnusedEntries();
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
TestReferenceChecker compound(checker.checkCompound("Compound", "Compound"));
compound.checkInteger(1, "int1");
{
using gmx::Any;
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkAny(Any::create<bool>(true), "bool");
checker.checkAny(Any::create<int>(1), "int");
checker.checkAny(Any::create<std::string>("foo"), "str");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkAny(Any::create<bool>(true), "bool");
checker.checkAny(Any::create<int>(1), "int");
{
gmx::KeyValueTreeObject tree = buildKeyValueTree(true);
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkKeyValueTreeObject(tree, "tree");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkKeyValueTreeObject(tree, "tree");
}
TEST(ReferenceDataTest, HandlesKeyValueTreeExtraKey)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkKeyValueTreeObject(buildKeyValueTree(false), "tree");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(true), "tree"),
"");
TEST(ReferenceDataTest, HandlesKeyValueTreeMissingKey)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkKeyValueTreeObject(buildKeyValueTree(true), "tree");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(false), "tree"),
"");
{
using gmx::Any;
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkAny(Any::create<bool>(true), "bool");
checker.checkAny(Any::create<int>(1), "int");
checker.checkAny(Any::create<std::string>("foo"), "str");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkAny(Any::create<bool>(false), "bool"), "");
EXPECT_NONFATAL_FAILURE(checker.checkAny(Any::create<int>(2), "int"), "");
{
using gmx::Any;
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkAny(Any::create<bool>(true), "bool");
checker.checkAny(Any::create<int>(1), "int");
checker.checkAny(Any::create<double>(3.5), "real");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_NONFATAL_FAILURE(checker.checkAny(Any::create<int>(1), "bool"), "");
EXPECT_NONFATAL_FAILURE(checker.checkAny(Any::create<bool>(true), "int"), "");
EXPECT_NONFATAL_FAILURE(
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkDouble(0.5, "real");
TEST(ReferenceDataTest, HandlesSpecialCharactersInStrings)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
// Note that '\r' is not handled correctly in string or
// stringblock (see the TODO in createElementContents), so
checker.checkTextBlock("\"<'>\n&\\/;", "stringblock");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("\"<'>\n&\\/;", "string");
checker.checkTextBlock("\"<'>\n&\\/;", "stringblock");
const char* strings[] = { " test", "test ", " test ", "the test",
"\ntest", "\n\ntest", "test\n", "test\n\n" };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
for (const auto& s : strings)
{
}
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
for (const auto& s : strings)
{
TEST(ReferenceDataTest, HandlesEmptyStrings)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("", "Empty");
// GROMACS cannot use an empty line in a reference data String
// until https://github.com/leethomason/tinyxml2/issues/432 is
// resolved.
- EXPECT_THROW_GMX(checker.checkString("\n", "EmptyLine"), gmx::test::TestException);
+ EXPECT_THROW_GMX(checker.checkString("\n", "EmptyLine"), TestException);
checker.checkTextBlock("", "EmptyBlock");
checker.checkTextBlock("\n", "EmptyLineBlock");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("", "Empty");
- EXPECT_THROW_GMX(checker.checkString("\n", "EmptyLine"), gmx::test::TestException);
+ EXPECT_THROW_GMX(checker.checkString("\n", "EmptyLine"), TestException);
checker.checkTextBlock("", "EmptyBlock");
checker.checkTextBlock("\n", "EmptyLineBlock");
}
don't actually depend on this behaviour, but it might be nice
to have / know about.) */
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkTextBlock(" ]]> ", "stringblock");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkTextBlock(" ]]> ", "stringblock");
}
int seq[5] = { -1, 3, 5, 2, 4 };
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkSequenceArray(5, seq, "seq");
checker.checkSequenceArray(5, seq, "seq2");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
seq[0] = 2;
EXPECT_NONFATAL_FAILURE(checker.checkSequenceArray(5, seq, "seq"), "seq/[0]");
TEST(ReferenceDataTest, HandlesMultipleChecksAgainstSameData)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", "string");
EXPECT_NONFATAL_FAILURE(checker.checkString("Test2", "string"), "");
EXPECT_NONFATAL_FAILURE(checker.checkTextBlock("TestString2", "stringblock"), "");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", "string");
EXPECT_NONFATAL_FAILURE(checker.checkString("Test2", "string"), "");
TEST(ReferenceDataTest, HandlesMultipleNullIds)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", nullptr);
checker.checkString("Test2", nullptr);
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", nullptr);
checker.checkString("Test2", nullptr);
TEST(ReferenceDataTest, HandlesMultipleComparisonsAgainstNullIds)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int1");
checker.checkString("Test", nullptr);
checker.checkString("Test2", nullptr);
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int1");
checker.checkString("Test", nullptr);
TEST(ReferenceDataTest, HandlesReadingValues)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkUChar('A', "char");
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
EXPECT_EQ('A', checker.readUChar("char"));
EXPECT_EQ(1, checker.readInteger("int"));
TEST(ReferenceDataTest, HandlesUpdateChangedWithoutChanges)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
compound.checkInteger(2, "int");
}
{
- TestReferenceData data(gmx::test::erefdataUpdateChanged);
+ TestReferenceData data(ReferenceDataMode::UpdateChanged);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
compound.checkInteger(2, "int");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
TEST(ReferenceDataTest, HandlesUpdateChangedWithValueChanges)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataUpdateChanged);
+ TestReferenceData data(ReferenceDataMode::UpdateChanged);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(2, "int");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(2, "int");
checker.checkString("Test", "string");
TEST(ReferenceDataTest, HandlesUpdateChangedWithTypeChanges)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "foo");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataUpdateChanged);
+ TestReferenceData data(ReferenceDataMode::UpdateChanged);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("foo", "foo");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("foo", "foo");
checker.checkString("Test", "string");
TEST(ReferenceDataTest, HandlesUpdateChangedWithCompoundChanges)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "1");
TestReferenceChecker compound(checker.checkCompound("Compound", "2"));
compound.checkInteger(2, "int");
}
{
- TestReferenceData data(gmx::test::erefdataUpdateChanged);
+ TestReferenceData data(ReferenceDataMode::UpdateChanged);
TestReferenceChecker checker(data.rootChecker());
TestReferenceChecker compound(checker.checkCompound("Compound", "1"));
compound.checkInteger(2, "int");
checker.checkString("Test", "2");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
TestReferenceChecker compound(checker.checkCompound("Compound", "1"));
compound.checkInteger(2, "int");
TEST(ReferenceDataTest, HandlesUpdateChangedWithRemovedEntries)
{
{
- TestReferenceData data(gmx::test::erefdataUpdateAll);
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(1, "int");
checker.checkString("Test", "string");
}
{
- TestReferenceData data(gmx::test::erefdataUpdateChanged);
+ TestReferenceData data(ReferenceDataMode::UpdateChanged);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(2, "int");
}
{
- TestReferenceData data(gmx::test::erefdataCompare);
+ TestReferenceData data(ReferenceDataMode::Compare);
TestReferenceChecker checker(data.rootChecker());
checker.checkInteger(2, "int");
}
}
} // namespace
+} // namespace test
+} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,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.
#include "testutils/refdata.h"
#include "testutils/testasserts.h"
+namespace gmx
+{
+namespace test
+{
namespace
{
-using gmx::test::checkXvgFile;
-using gmx::test::XvgMatchSettings;
-
//! Input testing data - an inline xvg file.
const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437",
"0.4 5262.44 -409.399", "0.6 5994.69 -405.763",
{
{
// Create new data
- gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
+ TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
// Now read it back
- gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceData data(ReferenceDataMode::Compare);
+ TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
checkXvgFile(&sis, &checker, XvgMatchSettings());
{
{
// Create new data
- gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
+ TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
checkXvgFile(&sis, &checker, XvgMatchSettings());
const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437",
"0.4 5262.44 -409.399" };
// Now check with missing data
- gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
- gmx::StringInputStream sis(input);
+ TestReferenceData data(ReferenceDataMode::Compare);
+ TestReferenceChecker checker(data.rootChecker());
+ gmx::StringInputStream sis(input);
EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()),
"not used in test");
}
{
{
// Create new data
- gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
+ TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
checkXvgFile(&sis, &checker, XvgMatchSettings());
"0.8 5941.37 -408.337", "1 5869.87 -411.124",
"1.2 5889.87 -413.124" };
// Now check with missing data
- gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
- gmx::StringInputStream sis(input);
+ TestReferenceData data(ReferenceDataMode::Compare);
+ TestReferenceChecker checker(data.rootChecker());
+ gmx::StringInputStream sis(input);
EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "Row6");
}
}
{
{
// Create new data
- gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
+ TestReferenceData data(ReferenceDataMode::UpdateAll);
+ TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
checkXvgFile(&sis, &checker, XvgMatchSettings());
"0.4 5262.44 -409.399", "0.6 5994.69 -405.763",
"0.8 5941.37 -408.337", "1 5869.87 -421.124" };
// Now check with incorrect data
- gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
- gmx::test::TestReferenceChecker checker(data.rootChecker());
- gmx::StringInputStream sis(input);
+ TestReferenceData data(ReferenceDataMode::Compare);
+ TestReferenceChecker checker(data.rootChecker());
+ gmx::StringInputStream sis(input);
EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "-411");
}
}
} // namespace
+} // namespace test
+} // namespace gmx