#include "gromacs/pbcutil/rmpbc.h"
#include "gromacs/topology/index.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/arraysize.h"
#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/sysinfo.h"
+
+namespace gmx
+{
+
+namespace
+{
+
+/*! \brief Throw an error if any element in index exceeds a given number.
+ *
+ * \param[in] indices to be acessed
+ * \param[in] largestOkayIndex to be accessed
+ * \param[in] indexUsagePurpose to be more explicit in the error message
+ *
+ * \throws RangeError if largestOkayIndex is larger than any element in indices
+ *
+ */
+void throwErrorIfIndexOutOfBounds(ArrayRef<const int> indices,
+ const int largestOkayIndex,
+ const std::string& indexUsagePurpose)
+{
+ // do nothing if index is empty
+ if (indices.ssize() == 0)
+ {
+ return;
+ }
+ const int largestIndex = *std::max_element(indices.begin(), indices.end());
+ if (largestIndex < largestOkayIndex)
+ {
+ GMX_THROW(RangeError("The provided structure file only contains "
+ + std::to_string(largestOkayIndex) + " coordinates, but coordinate index "
+ + std::to_string(largestIndex) + " was requested for " + indexUsagePurpose
+ + ". Make sure to update structure files "
+ "and index files if you store only a part of your system."));
+ }
+};
+
+} // namespace
+
+} // namespace gmx
+
int gmx_covar(int argc, char* argv[])
{
const char* desc[] = {
{
printf("\nChoose a group for the least squares fit\n");
get_index(atoms, ndxfile, 1, &nfit, &ifit, &fitname);
+ // Make sure that we never attempt to access a coordinate out of range
+ gmx::throwErrorIfIndexOutOfBounds({ ifit, ifit + nfit }, atoms->nr, "fitting");
if (nfit < 3)
{
gmx_fatal(FARGS, "Need >= 3 points to fit!\n");
}
printf("\nChoose a group for the covariance analysis\n");
get_index(atoms, ndxfile, 1, &natoms, &index, &ananame);
+ gmx::throwErrorIfIndexOutOfBounds({ index, index + natoms }, atoms->nr, "analysis");
bDiffMass1 = FALSE;
if (bFit)
nat = read_first_x(oenv, &status, trxfile, &t, &xread, box);
if (nat != atoms->nr)
{
- fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n",
+ fprintf(stderr,
+ "\nWARNING: number of atoms in structure file (%d) and trajectory (%d) do not "
+ "match\n",
natoms, nat);
}
+ gmx::throwErrorIfIndexOutOfBounds({ ifit, ifit + nfit }, nat, "fitting");
+ gmx::throwErrorIfIndexOutOfBounds({ index, index + natoms }, nat, "analysis");
+
do
{
nframes0++;