/*! \cond libapi */
/*! \brief
* Wraps a given option object.
+ *
+ * Does not throw.
*/
explicit OptionInfo(AbstractOptionStorage *option);
* Adds a value to a temporary storage.
*
* \param[in] value Value to add. A copy is made.
+ * \throws std::bad_alloc if out of memory.
* \throws InvalidInputError if the maximum value count has been reached.
*
* Derived classes should call this function from the convertValue()
* implementation to add converted values to the storage.
- * If the maximum value cont has been reached, the value is discarded
+ * If the maximum value count has been reached, the value is discarded
* and an exception is thrown.
*
* If adding values outside convertValue() (e.g., to set a custom
/*! \brief
* Commits values added with addValue().
*
+ * \throws std::bad_alloc if out of memory.
+ *
* If this function succeeds, values added with addValue() since the
* previous clearSet() are added to the storage for the option.
* Only throws in out-of-memory conditions, and provides the strong
* \brief
* Provides functionality for initializing and evaluating selections.
*
- * \internal
+ * The core of the selection engine is accessed through
+ * gmx::SelectionCollection, which manages a set of selections.
+ * Documentation for that class explains the general selection mechanisms.
+ *
+ * For each selection that is parsed using a gmx::SelectionCollection, a
+ * gmx::Selection handle is returned and can be used to access information
+ * about that selection. gmx::SelectionPosition is a helper class used to
+ * access information about individual positions in a selection. These classes
+ * refer to internal state within the gmx::SelectionCollection, and their
+ * contents update automatically when the gmx::SelectionCollection is compiled
+ * or evaluated.
+ *
+ * This module also provides gmx::SelectionOption and gmx::SelectionOptionInfo
+ * classes for declaring options that evaluate to selections (see \ref
+ * module_options for general explanation of the options mechanism). These
+ * classes provide the main interface to obtain gmx::Selection objects in
+ * trajectory analysis using gmx::TrajectoryAnalysisModule.
+ *
+ * \if libapi
+ * The selection module contains some lower-level functionality that is
+ * currently internal to it (centerofmass.h, indexutil.h, poscalc.h,
+ * position.h), but could possibly be useful also outside the module.
+ * It should be considered whether they should be moved somewhere else.
+ * \endif
+ *
+ * \if internal
* Implementation details of different parts of the module are discussed on
* separate pages:
* - \ref page_module_selection_custom
* - \ref page_module_selection_parser
* - \ref page_module_selection_compiler
* - \ref page_module_selection_insolidangle
+ * \endif
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
*/
#define GMX_SELECTION_H
#include "selection/selection.h"
+#include "selection/selectioncollection.h"
#include "selection/selectionoption.h"
+#include "selection/selectionoptioninfo.h"
#endif
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${SELECTION_SOURCES} PARENT_SCOPE)
set(SELECTION_PUBLIC_HEADERS
- centerofmass.h
nbsearch.h
- poscalc.h
indexutil.h
position.h
selection.h
+ selectioncollection.h
selectionenums.h
selectionoption.h
- selectionoptioninfo.h
- selparam.h
- selmethod.h
- selvalue.h)
+ selectionoptioninfo.h)
install(FILES ${SELECTION_PUBLIC_HEADERS}
DESTINATION ${INCL_INSTALL_DIR}/gromacs/selection
COMPONENT development)
*/
/*! \internal \file
* \brief
- * Implements gmx::Selection.
+ * Implements classes in selection.h.
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \ingroup module_selection
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <statutil.h>
-#include <string2.h>
-#include <xvgr.h>
-
-#include "gromacs/selection/position.h"
-#include "gromacs/selection/selection.h"
-#include "gromacs/selection/selvalue.h"
+#include "selection.h"
+#include "position.h"
#include "selelem.h"
+#include "selvalue.h"
namespace gmx
{
void
Selection::printDebugInfo(FILE *fp, int nmaxind) const
{
- const gmx_ana_pos_t &p = sel_->rawPositions_;
+ const gmx_ana_pos_t &p = data().rawPositions_;
fprintf(fp, " ");
printInfo(fp);
*/
/*! \file
* \brief
- * Declares gmx::Selection.
+ * Declares gmx::Selection and supporting classes.
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \inpublicapi
*
* This class is internal to the selection module, but resides in a public
* header because of efficiency reasons: it allows frequently used access
- * methods to be inlined.
+ * methods in \ref Selection to be inlined.
+ *
+ * Methods in this class do not throw unless otherwise specified.
*
* \ingroup module_selection
*/
*
* \param[in] elem Root of the evaluation tree for this selection.
* \param[in] selstr String that was parsed to produce this selection.
+ * \throws std::bad_alloc if out of memory.
*/
SelectionData(t_selelem *elem, const char *selstr);
~SelectionData();
/*! \brief
* Computes total masses and charges for all selection positions.
*
- * \param[in] top Topology information.
+ * \param[in] top Topology information.
+ * \throws std::bad_alloc if out of memory.
*
* Computed values are cached, and need to be updated for dynamic
* selections with refreshMassesAndCharges() after the selection has
* been evaluated. This is done by SelectionEvaluator.
*
* This function is called by SelectionCompiler.
+ *
+ * Strong exception safety guarantee.
*/
void initializeMassesAndCharges(const t_topology *top);
/*! \brief
*
* This structure contains information about positions in the
* selection that is not stored in ::gmx_ana_pos_t.
+ *
+ * Methods in this class do not throw.
*/
struct PositionInfo
{
bool bDynamicCoveredFraction_;
/*! \brief
- * Needed for to wrap access to information.
+ * Needed to wrap access to information.
*/
friend class gmx::Selection;
/*! \brief
/*! \brief
* Provides access to a single selection.
*
+ * This class provides a public interface for accessing selection information.
+ * General information about the selection can be accessed with methods name(),
+ * selectionText(), isDynamic(), and type(). The first three can be accessed
+ * any time after the selection has been parsed, and type() can be accessed
+ * after the selection has been compiled.
+ *
+ * Each selection is made of a set of positions. Each position has associated
+ * coordinates, and possibly velocities and forces if they have been requested
+ * and are available. It also has a set of atoms associated with it; typically
+ * the coordinates are the center-of-mass or center-of-geometry coordinates for
+ * that set of atoms. To access the number of positions in the selection, use
+ * posCount(). To access individual positions, use position().
+ * See SelectionPosition for details of how to use individual positions.
+ * setOriginalId() can be used to adjust the return value of
+ * SelectionPosition::mappedId(); see that method for details.
+ *
+ * It is also possible to access the list of atoms that make up all the
+ * positions directly: atomCount() returns the total number of atoms in the
+ * selection and atomIndices() an array of their indices.
+ *
+ * Both positions and atoms can be accessed after the selection has been
+ * compiled. For dynamic selections, the return values of these methods change
+ * after each evaluation to reflect the situation for the current frame.
+ * Before any frame has been evaluated, these methods return the maximal set
+ * to which the selection can evaluate.
+ *
+ * There are two possible modes for how positions for dynamic selections are
+ * handled. In the default mode, posCount() can change, and for each frame,
+ * only the positions that are selected in that frame can be accessed. In a
+ * masked mode, posCount() remains constant, i.e., the positions are always
+ * evaluated for the maximal set, and SelectionPosition::selected() is used to
+ * determine whether a position is selected for a frame. The masked mode can
+ * be requested with SelectionOption::dynamicMask().
+ *
+ * The class also provides methods for printing out information: printInfo()
+ * and printDebugInfo(). These are mainly for internal use by Gromacs.
+ *
+ * This class works like a pointer type: copying and assignment is lightweight,
+ * and all copies work interchangeably, accessing the same internal data.
+ *
+ * Methods in this class do not throw.
+ *
+ * \see SelectionPosition
+ *
* \inpublicapi
* \ingroup module_selection
*/
* Creates a new selection object.
*
* \param sel Selection data to wrap.
+ *
+ * Only for internal use by the selection module.
*/
explicit Selection(internal::SelectionData *sel) : sel_(sel) {}
//! Returns the type of positions in the selection.
e_index_t type() const { return data().rawPositions_.m.type; }
- //! Number of positions in the selection.
- int posCount() const { return data().posCount(); }
//! Total number of atoms in the selection.
int atomCount() const
{
return ConstArrayRef<int>(data().rawPositions_.g->isize,
data().rawPositions_.g->index);
}
+ //! Number of positions in the selection.
+ int posCount() const { return data().posCount(); }
//! Access a single position.
SelectionPosition position(int i) const;
/*! \brief
* Sets the ID for the \p i'th position for use with
* SelectionPosition::mappedId().
*
+ * \param[in] i Zero-based index
+ * \param[in] id Identifier to set.
+ *
* This method is not part of SelectionPosition because that interface
* only provides access to const data by design.
+ *
+ * This method can only be called after compilation, before the
+ * selection has been evaluated for any frame.
+ *
+ * \see SelectionPosition::mappedId()
*/
void setOriginalId(int i, int id) { data().rawPositions_.m.orgid[i] = id; }
+ //! Deprecated method for direct access to position data.
+ const gmx_ana_pos_t *positions() const { return &data().rawPositions_; }
+
//! Returns whether the covered fraction can change between frames.
bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); }
//! Returns the covered fraction for the current frame.
real coveredFraction() const { return data().coveredFraction_; }
-
- //! Deprecated method for direct access to position data.
- const gmx_ana_pos_t *positions() const { return &data().rawPositions_; }
-
/*! \brief
* Initializes information about covered fractions.
*
* \param[in] type Type of covered fraction required.
- * \returns True if the covered fraction can be calculated for the
+ * \returns true if the covered fraction can be calculated for the
* selection.
*/
bool initCoveredFraction(e_coverfrac_t type)
* Prints out one-line description of the selection.
*
* \param[in] fp Where to print the information.
+ *
+ * The output contains the name of the selection, the number of atoms
+ * and the number of positions, and indication of whether the selection
+ * is dynamic.
*/
void printInfo(FILE *fp) const;
/*! \brief
return *sel_;
}
+ /*! \brief
+ * Pointer to internal data for the selection.
+ *
+ * The memory for this object is managed by a SelectionCollection
+ * object, and the \ref Selection class simply provides a public
+ * interface for accessing the data.
+ */
internal::SelectionData *sel_;
/*! \brief
};
/*! \brief
- * Wrapper object to access information about a single selected position.
+ * Provides access to information about a single selected position.
+ *
+ * Each position has associated coordinates, and possibly velocities and forces
+ * if they have been requested and are available. It also has a set of atoms
+ * associated with it; typically the coordinates are the center-of-mass or
+ * center-of-geometry coordinates for that set of atoms. It is possible that
+ * there are not atoms associated if the selection has been provided as a fixed
+ * position.
+ *
+ * After the selection has been compiled, but not yet evaluated, the contents
+ * of the coordinate, velocity and force vectors are undefined.
*
* Default copy constructor and assignment operators are used, and work as
* intended: the copy references the same position and works identically.
*
* Methods in this class do not throw.
*
+ * \see Selection
+ *
* \inpublicapi
* \ingroup module_selection
*/
* \param[in] sel Selection from which the position is wrapped.
* \param[in] index Zero-based index of the position to wrap.
*
- * Does not throw. Asserts if \p index is out of range.
+ * Asserts if \p index is out of range.
+ *
+ * Only for internal use of the library. To obtain a SelectionPosition
+ * object in other code, use Selection::position().
*/
SelectionPosition(const internal::SelectionData &sel, int index)
: sel_(&sel), i_(index)
/*! \brief
* Returns type of this position.
*
- * Currently returns the same as Selection::type().
+ * Currently always returns the same as Selection::type().
*/
e_index_t type() const { return sel_->rawPositions_.m.type; }
//! Returns coordinates for this position.
//! Returns whether force is available for this position.
bool hasForce() const { return sel_->rawPositions_.f != NULL; }
/*! \brief
- * Returns velocity for this position.
+ * Returns force for this position.
*
* Must not be called if hasForce() returns false.
*/
* Returns total mass for this position.
*
* Returns the total mass of atoms that make up this position.
- * If there are not atoms associated or masses are not available,
+ * If there are no atoms associated or masses are not available,
* returns unity.
*/
real mass() const
* Returns total charge for this position.
*
* Returns the sum of charges of atoms that make up this position.
- * If there are not atoms associated or masses are not available,
+ * If there are no atoms associated or charges are not available,
* returns zero.
*/
real charge() const
return ConstArrayRef<int>(atomCount(),
&sel_->rawPositions_.g->index[first]);
}
+ /*! \brief
+ * Returns whether this position is selected in the current frame.
+ *
+ * The return value is equivalent to \c refid() == -1. Returns always
+ * true if SelectionOption::dynamicMask() has not been set.
+ *
+ * \see refId()
+ */
+ bool selected() const
+ {
+ return refId() >= 0;
+ }
/*! \brief
* Returns reference ID for this position.
*
* selection are set to -1, otherwise they are removed completely.
*
* Example:
- * If a dynamic selection consists of three positions, after
+ * If a dynamic selection consists of at most three positions, after
* compilation refId() will return 0, 1, 2 for them, respectively.
* If for a particular frame, only the first and the third are present,
* refId() will return 0, 2.
* If SelectionOption::dynamicMask() has been set, all three positions
- * can be accessed also in this case and refId() will return 0, -1, 2.
+ * can be accessed also for that frame and refId() will return 0, -1,
+ * 2.
*/
int refId() const
{
* Returns ID of the position that corresponds to that set with
* Selection::setOriginalId().
*
- * If for an array \c id, \c setOriginalId(i, c[i]) has been called
+ * If for an array \c id, \c setOriginalId(i, id[i]) has been called
* for each \c i, then it always holds that
- * \c mappedId()==c[refId()].
+ * \c mappedId()==id[refId()].
+ *
+ * Selection::setOriginalId() has not been called, the default values
+ * are dependent on type():
+ * - ::INDEX_ATOM: atom indices
+ * - ::INDEX_RES: residue numbers
+ * - ::INDEX_MOL: molecule numbers
+ * .
+ * All the default values are zero-based
*/
int mappedId() const
{
{
//! Smart pointer for managing an internal selection data object.
typedef gmx_unique_ptr<internal::SelectionData>::type SelectionDataPointer;
-//! Shorthand for storing a list of selections internally.
+//! Container for storing a list of selections internally.
typedef std::vector<SelectionDataPointer> SelectionDataList;
}
class SelectionCollection::Impl
{
public:
+ /*! \brief
+ * Request for postponed parsing of selections.
+ *
+ * Used to communicate what needs to be parsed with
+ * parseRequestedFromStdin() or parseRequstedFromString().
+ */
struct SelectionRequest
{
+ //! Initializes a request for the given option.
SelectionRequest(const std::string &name, const std::string &descr,
SelectionOptionStorage *storage)
: name(name), descr(descr), storage(storage)
*/
int count() const;
+ //! Name of the option to which this request relates to.
std::string name;
+ //! Description of the option to which this request relates to.
std::string descr;
+ //! Storage object to which the selections will be added.
SelectionOptionStorage *storage;
};
- //! Shorthand for a list of selection requests.
+ //! Collection for a list of selection requests.
typedef std::vector<SelectionRequest> RequestList;
+ /*! \brief
+ * Helper class that clears a request list on scope exit.
+ *
+ * Methods in this class do not throw.
+ */
class RequestsClearer
{
public:
- RequestsClearer(RequestList *requests) : requests_(requests)
+ //! Constructs an object that clears given list on scope exit.
+ explicit RequestsClearer(RequestList *requests)
+ : requests_(requests)
{
}
+ //! Clears the request list given to the constructor.
~RequestsClearer()
{
requests_->clear();
Impl();
~Impl();
- //! Clears the symbol table of the selection collection.
+ /*! \brief
+ * Clears the symbol table of the selection collection.
+ *
+ * Does not throw.
+ */
void clearSymbolTable();
/*! \brief
* Helper function that runs the parser once the tokenizer has been
* (if -1, parse as many as provided by the user).
* \param[out] output Vector to which parsed selections are
* appended.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if there is a parsing error.
*
- * Does not clear \p output.
+ * Parsed selections are appended to \p output without clearing it
+ * first. If parsing fails, \p output is not modified.
+ *
+ * Used internally to implement parseFromStdin(), parseFromFile() and
+ * parseFromString().
*/
void runParser(void *scanner, int maxnr,
SelectionList *output);
* \param[in] name Name for the requested selections.
* \param[in] descr Description of the requested selections.
* \param storage Storage object to receive the selections.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * Strong exception safety.
*
* \see parseRequestedFromStdin()
*/
* \a _grps and replaces the reference with a constant element that
* contains the atoms from the referenced group. Any failures to
* resolve references are reported to \p errors.
+ *
+ * Does not throw currently, but this is subject to change when more
+ * underlying code is converted to C++.
*/
void resolveExternalGroups(struct t_selelem *root,
MessageStringCollector *errors);
* - 4: combine 2 and 3
*/
int _debugLevel;
- //! Whether external groups have been set for the collection.
+ //! Whether setIndexGroups() has been called.
bool _bExternalGroupsSet;
//! External index groups (can be NULL).
gmx_ana_indexgrps_t *_grps;
#include <cstdio>
-#include <smalloc.h>
-#include <statutil.h>
-#include <string2.h>
-#include <xvgr.h>
+#include "futil.h"
+#include "oenv.h"
+#include "smalloc.h"
+#include "xvgr.h"
#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/fatalerror/gmxassert.h"
if (bOk)
{
SelectionDataList::const_iterator i;
+ output->reserve(output->size() + nr);
for (i = _sc.sel.begin() + oldCount; i != _sc.sel.end(); ++i)
{
output->push_back(Selection(i->get()));
}
}
+ // TODO: Remove added selections from the collection if parsing failed?
if (!bOk || !errors.isEmpty())
{
void
-SelectionCollection::setDebugLevel(int debuglevel)
+SelectionCollection::setDebugLevel(int debugLevel)
{
- _impl->_debugLevel = debuglevel;
+ _impl->_debugLevel = debugLevel;
}
void
SelectionCollection::setTopology(t_topology *top, int natoms)
{
- gmx_ana_selcollection_t *sc = &_impl->_sc;
- sc->pcc.setTopology(top);
- sc->top = top;
-
- /* Get the number of atoms from the topology if it is not given */
+ GMX_RELEASE_ASSERT(natoms > 0 || top != NULL,
+ "The number of atoms must be given if there is no topology");
+ // Get the number of atoms from the topology if it is not given.
if (natoms <= 0)
{
- if (sc->top == NULL)
- {
- GMX_THROW(APIError("Selections need either the topology or the number of atoms"));
- }
- natoms = sc->top->atoms.nr;
+ natoms = top->atoms.nr;
}
-
+ gmx_ana_selcollection_t *sc = &_impl->_sc;
+ // Do this first, as it allocates memory, while the others don't throw.
gmx_ana_index_init_simple(&sc->gall, natoms, NULL);
+ sc->pcc.setTopology(top);
+ sc->top = top;
}
*
* For more info, check our website at http://www.gromacs.org
*/
-/*! \libinternal \file
+/*! \file
* \brief
* Declares gmx::SelectionCollection.
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
- * \inlibraryapi
+ * \inpublicapi
* \ingroup module_selection
*/
#ifndef GMX_SELECTION_SELECTIONCOLLECTION_H
class SelectionEvaluator;
class SelectionOptionStorage;
-/*! \libinternal \brief
+/*! \brief
* Collection of selections.
*
- * Some default values must then be set with
- * gmx_ana_selcollection_set_refpostype() and
- * gmx_ana_selcollection_set_outpostype().
+ * This class is the main interface to the core of the selection engine.
+ * It is used to initialize and manage a collection of selections that share
+ * the same topology. Selections within one collection can share variables and
+ * can be optimized together. Selections from two different collections do not
+ * interact.
+ *
+ * The constructor creates an empty selection collection object. To initialize
+ * the object, either call initOptions(), or both setReferencePosType() and
+ * setOutputPosType(). See these methods for more details on the
+ * initialization options.
+ *
+ * After setting the default values, one or more selections can be parsed with
+ * one or more calls to parseFromStdin(), parseFromFile(), and/or
+ * parseFromString(). parseRequestedFromStdin() and parseRequestedFromString()
+ * are provided for integration with SelectionOption. After all selections are
+ * parsed, the topology must be set with setTopology() unless
+ * requiresTopology() returns false (the topology can also be set earlier).
+ * setIndexGroups() must also be called if external index group references are
+ * used in the selections; it can be called at any point before compile().
+ * Once all selections are parsed, they must be compiled all at once using
+ * compile().
*
- * After setting the default values, one or more selections can be parsed
- * with one or more calls to parseFromStdin(), parseFromFile(), and/or
- * parseFromString(). After all selections are parsed, the topology must be
- * set with setTopology() unless requiresTopology() returns false (the topology
- * can also be set earlier). Once all selections are parsed, they must be
- * compiled all at once using compile().
* After compilation, dynamic selections have the maximum number of atoms they
- * can evaluate to, but positions have undefined values. evaluate() can be
- * used to update the selections for a new frame.
- * evaluateFinal() can be called after all the frames have been processed to
- * restore the selection values back to the ones they were after compile().
+ * can evaluate to, but positions have undefined values (see \ref Selection and
+ * SelectionPosition). evaluate() can be used to update the selections for a
+ * new frame. evaluateFinal() can be called after all the frames have been
+ * processed to restore the selection values back to the ones they were after
+ * compile().
*
* At any point, requiresTopology() can be called to see whether the
* information provided so far requires loading the topology.
* printTree() can be used to print the internal representation of the
* selections (mostly useful for debugging).
*
- * \inlibraryapi
+ * Note that for trajectory analysis using TrajectoryAnalysisModule, the
+ * SelectionCollection object is managed by Gromacs, and \ref Selection objects
+ * are obtained from SelectionOption.
+ *
+ * \inpublicapi
* \ingroup module_selection
*/
class SelectionCollection
/*! \brief
* Initializes options for setting global properties on the collection.
+ *
+ * \returns Initialized options object.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The returned options can be used to set the default position types
+ * (see setReferencePosType() and setOutputPosType()) and debugging
+ * options.
*/
Options &initOptions();
* \param[in] type Default selection reference position type
* (one of the strings acceptable for
* PositionCalculationCollection::typeFromEnum()).
+ * \throws InternalError if \p type is invalid.
*
* Should be called before calling the parser functions, unless
* initOptions() has been called. In the latter case, can still be
- * used to override the default value and/or the value provided through
- * the Options object.
+ * used to override the default value (before initOptions() is called)
+ * and/or the value provided through the Options object.
+ *
+ * Strong exception safety.
*/
void setReferencePosType(const char *type);
/*! \brief
* \param[in] type Default selection output position type
* (one of the strings acceptable for
* PositionCalculationCollection::typeFromEnum()).
+ * \throws InternalError if \p type is invalid.
*
* Should be called before calling the parser functions, unless
* initOptions() has been called. In the latter case, can still be
- * used to override the default value and/or the value provided through
- * the Options object.
+ * used to override the default value (before initOptions() is called)
+ * and/or the value provided through the Options object.
+ *
+ * Strong exception safety.
*/
void setOutputPosType(const char *type);
/*! \brief
* Sets the debugging level for the selection collection.
+ *
+ * \param[in] debugLevel Debug level to set (0 = no debug
+ * information).
+ *
+ * initOptions() creates debugging options that can also be used to set
+ * the debug level. These are normally hidden, but if this method is
+ * called before initOptions() with a non-zero \p debugLevel, they are
+ * made visible.
+ *
+ * Mostly useful for debugging tools.
+ *
+ * Does not throw.
*/
- void setDebugLevel(int debuglevel);
+ void setDebugLevel(int debugLevel);
/*! \brief
* Returns true if the collection requires topology information for
* based just on the position types set.
* After parser functions have been called, the return value also takes
* into account the selection keywords used.
+ *
+ * Does not throw.
*/
bool requiresTopology() const;
/*! \brief
* \param[in] top Topology data.
* \param[in] natoms Number of atoms. If <=0, the number of
* atoms in the topology is used.
- * \retval 0 on success.
- * \retval ::eeInvalidValue if \p top is NULL and \p natoms <= 0.
*
- * The topology is also set for the position calculation collection
- * associated with the collection.
+ * Either the topology must be provided, or \p natoms must be > 0.
*
* \p natoms determines the largest atom index that can be selected by
* the selection: even if the topology contains more atoms, they will
* not be selected.
+ *
+ * Does not throw currently, but this is subject to change when more
+ * underlying code is converted to C++.
*/
void setTopology(t_topology *top, int natoms);
/*! \brief
* Sets the external index groups to use for the selections.
*
- * Can be called only once with non-NULL \p grps.
+ * \param[in] grps Index groups to use for the selections.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if a group reference cannot be resolved.
+ *
+ * Only the first call to this method can have a non-NULL \p grps.
+ * At this point, any selections that have already been provided are
+ * searched for references to external groups, and the references are
+ * replaced by the contents of the groups. If any referenced group
+ * cannot be found in \p grps (or if \p grps is NULL and there are any
+ * references), InvalidInputError is thrown.
+ *
+ * The selection collection keeps a reference to \p grps until this
+ * method is called with a NULL \p grps.
+ * If this method is not called before compile(), it is automatically
+ * called as setIndexGroups(NULL).
*/
void setIndexGroups(gmx_ana_indexgrps_t *grps);
/*! \brief
*
* \param[in] bInteractive Whether the parser should behave
* interactively.
+ * \throws unspecified Can throw any exception thrown by
+ * parseFromStdin().
+ * \throws std::bad_alloc if out of memory.
*
* This method cooperates with SelectionOption to allow interactive
* input of missing selections after all options have been processed.
* It should be called after the Options::finish() method has been
* called on all options that add selections to this collection.
+ * For each required selection option that has not been given, as well
+ * as for optional selection options that have been specified without
+ * values, it will prompt the user to input the necessary selections.
*/
void parseRequestedFromStdin(bool bInteractive);
/*! \brief
* Parses selection(s) from a string for options not yet provided.
*
* \param[in] str String to parse.
+ * \throws unspecified Can throw any exception thrown by
+ * parseFromString().
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if
+ * - the number of selections in \p str doesn't match the number
+ * requested.
+ * - any selection uses a feature that is not allowed for the
+ * corresponding option.
+ * \throws APIError if there is a request for any number of
+ * selections that is not the last (in which case it is not
+ * possible to determine which selections belong to which
+ * request).
+ *
+ * This method behaves as parseRequestedFromStdin(), but reads the
+ * selections from a string instead of standard input.
+ * This method is mainly used for testing.
*
* \see parseRequestedFromStdin()
*/
* \param[in] bInteractive Whether the parser should behave
* interactively.
* \param[out] output Vector to which parsed selections are appended.
- * \retval 0 on success.
- * \retval ::eeInvalidInput on syntax error (an interactive parser
- * only returns this if an incorrect number of selections is
- * provided).
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if there is a parsing error
+ * (an interactive parser only throws this if too few selections
+ * are provided and the user forced the end of input).
*
* Parsed selections are appended to \p output without clearing it
* first. If parsing fails, \p output is not modified.
*
* The objects returned in \p output remain valid for the lifetime of
- * the selection collection, and should not be freed by the user.
+ * the selection collection.
* Some information about the selections only becomes available once
- * compile() has been called.
+ * compile() has been called; see \ref Selection.
*/
void parseFromStdin(int count, bool bInteractive,
SelectionList *output);
*
* \param[in] filename Name of the file to parse selections from.
* \param[out] output Vector to which parsed selections are appended.
- * \retval 0 on success.
- * \retval ::eeInvalidInput on syntax error.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if there is a parsing error.
*
* Parsed selections are appended to \p output without clearing it
* first. If parsing fails, \p output is not modified.
*
* The objects returned in \p output remain valid for the lifetime of
- * the selection collection, and should not be freed by the user.
+ * the selection collection.
* Some information about the selections only becomes available once
- * compile() has been called.
+ * compile() has been called; see \ref Selection.
*/
void parseFromFile(const std::string &filename,
SelectionList *output);
*
* \param[in] str String to parse selections from.
* \param[out] output Vector to which parsed selections are appended.
- * \retval 0 on success.
- * \retval ::eeInvalidInput on syntax error.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if there is a parsing error.
*
* Parsed selections are appended to \p output without clearing it
* first. If parsing fails, \p output is not modified.
*
* The objects returned in \p output remain valid for the lifetime of
- * the selection collection, and should not be freed by the user.
+ * the selection collection.
* Some information about the selections only becomes available once
- * compile() has been called.
+ * compile() has been called; see \ref Selection.
*/
void parseFromString(const std::string &str,
SelectionList *output);
/*! \brief
* Prepares the selections for evaluation and performs optimizations.
*
- * \retval 0 on successful compilation, a non-zero error code on error.
+ * \throws InconsistentInputError if topology is required but not set.
+ * \throws InvalidInputError if setIndexGroups() has not been called
+ * and there are index group references.
+ * \throws unspecified if compilation fails (TODO: list/reduce these).
*
* Before compilation, selections should have been added to the
* collection using the parseFrom*() functions.
* The compiled selection collection can be passed to evaluate() to
* evaluate the selection for a frame.
+ * Before the compiled selection is evaluated, the selections indicate
+ * the maximal set of atoms/positions to which they can be evaluated;
+ * see \ref Selection.
+ *
* If an error occurs, the collection is cleared.
*
* The covered fraction information is initialized to ::CFRAC_NONE for
*
* \param[in] fr Frame for which the evaluation should be carried out.
* \param[in] pbc PBC data, or NULL if no PBC should be used.
- * \returns 0 on successful evaluation, a non-zero error code on error.
+ * \throws unspeficied Multiple possible exceptions to indicate
+ * evaluation failure (TODO: enumerate).
*/
void evaluate(t_trxframe *fr, t_pbc *pbc);
/*! \brief
*
* \param[in] nframes Total number of frames.
*
- * This function does not throw.
+ * This method restores the selections to the state they were after
+ * compile().
+ *
+ * \p nframes should equal the number of times evaluate() has been
+ * called.
+ *
+ * Does not throw.
*/
void evaluateFinal(int nframes);
* \param[in] fp File handle to receive the output.
* \param[in] bValues If true, the evaluated values of selection
* elements are printed as well.
+ *
+ * The output is very techical, and intended for debugging purposes.
+ *
+ * Does not throw.
*/
void printTree(FILE *fp, bool bValues) const;
/*! \brief
*
* \param[in] fp Output file.
* \param[in] oenv Output options structure.
+ *
+ * Does not throw.
*/
void printXvgrInfo(FILE *fp, output_env_t oenv) const;
void SelectionOptionStorage::setAllowedValueCount(int count)
{
+ // TODO: It should be possible to have strong exception safety here.
MessageStringCollector errors;
errors.startContext("In option '" + name() + "'");
if (count >= 0)
void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet)
{
- _selectionFlags.set(flag, bSet);
ValueList::iterator i;
for (i = values().begin(); i != values().end(); ++i)
{
- if (_selectionFlags.test(efOnlyStatic) && i->isDynamic())
+ if (flag == efOnlyStatic && bSet && i->isDynamic())
{
MessageStringCollector errors;
errors.startContext("In option '" + name() + "'");
errors.finishContext();
GMX_THROW(InvalidInputError(errors.toString()));
}
+ }
+ _selectionFlags.set(flag, bSet);
+ for (i = values().begin(); i != values().end(); ++i)
+ {
i->data().setFlags(_selectionFlags);
}
}
} // namespace
-/*! \cond libapi */
void setSelectionCollectionForOptions(Options *options,
SelectionCollection *selections)
{
SelectionCollectionSetter(selections).visitSubSection(options);
}
-//! \endcond
} // namespace gmx
/*! \brief
* Specifies an option that provides selection(s).
*
+ * Public methods in this class do not throw.
+ *
* \inpublicapi
* \ingroup module_selection
*/
/*! \brief
* Request velocity evaluation for output positions.
+ *
+ * Note that even with this flag set, velocities may not be available,
+ * in which case SelectionPosition::hasVelocity() returns false.
*/
MyClass &evaluateVelocities()
{ _selectionFlags.set(efEvaluateVelocities); return me(); }
/*! \brief
* Request force evaluation for output positions.
+ *
+ * Note that even with this flag set, forces may not be available,
+ * in which case SelectionPosition::hasForce() returns false.
*/
MyClass &evaluateForces()
{ _selectionFlags.set(efEvaluateForces); return me(); }
/*! \brief
* Handle dynamic selections for this option with position masks.
*
- * \if internal
- * Sets ::POS_MASKONLY on the positions for this selection.
- * \endif
+ * \see Selection
+ * \see SelectionPosition::selected()
*/
MyClass &dynamicMask()
{ _selectionFlags.set(efDynamicMask); return me(); }
class SelectionOptionInfo : public OptionInfo
{
public:
- //! Creates option info object for given storage object.
+ /*! \brief
+ * Creates option info object for given storage object.
+ *
+ * Does not throw.
+ */
explicit SelectionOptionInfo(SelectionOptionStorage *option);
/*! \brief
* Set selection collection into which this option adds selections.
*
+ * \param selections Selection collection to set.
+ *
* This must be called before the values are added.
*
* Typically it is called through setSelectionCollectionForOptions(),
* which recursively sets the collection for all selection options in
* an Options object.
+ *
+ * Does not throw.
*/
void setSelectionCollection(SelectionCollection *selections);
* Sets the number of selections allowed for the option.
*
* \param[in] count Number of allowed selections.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if values have already been provided
+ * and their count does not match.
*/
void setValueCount(int count);
- //! \copydoc SelectionOption::evaluateVelocities()
+ /*! \brief
+ * Sets whether this option evaluates velocities for positions.
+ *
+ * \param[in] bEnabled If true, velocities are evaluated.
+ *
+ * Does not throw.
+ *
+ * \see SelectionOption::evaluateVelocities()
+ */
void setEvaluateVelocities(bool bEnabled);
- //! \copydoc SelectionOption::evaluateForces()
+ /*! \brief
+ * Sets whether this option evaluates forces for positions.
+ *
+ * \param[in] bEnabled If true, forces are evaluated.
+ *
+ * Does not throw.
+ *
+ * \see SelectionOption::evaluateForces()
+ */
void setEvaluateForces(bool bEnabled);
- //! \copydoc SelectionOption::onlyAtoms()
+ /*! \brief
+ * Sets whether this option accepts positions that come from multiple
+ * atoms.
+ *
+ * \param[in] bEnabled If true, the option accepts only positions that
+ * evaluate to atom positions.
+ *
+ * TODO: This is not yet implemented.
+ *
+ * \see SelectionOption::onlyAtoms()
+ */
void setOnlyAtoms(bool bEnabled);
- //! \copydoc SelectionOption::onlyStatic()
+ /*! \brief
+ * Sets whether this option accepts dynamic selections.
+ *
+ * \param[in] bEnabled If true, the option accepts only static
+ * selections.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if dynamic selections have already been
+ * provided.
+ *
+ * Strong exception safety guarantee.
+ *
+ * \see SelectionOption::onlyStatic()
+ */
void setOnlyStatic(bool bEnabled);
- //! \copydoc SelectionOption::dynamicMask()
+ /*! \brief
+ * Sets whether this option uses position masks for dynamic selections.
+ *
+ * \param[in] bEnabled If true, the position masks are used.
+ *
+ * Does not throw.
+ *
+ * \see SelectionOption::dynamicMask()
+ */
void setDynamicMask(bool bEnabled);
- //! \copydoc SelectionOption::dynamicOnlyWhole()
+ /*! \brief
+ * Sets whether atom coordinates are allowed as reference positions.
+ *
+ * \param[in] bEnabled If true, the option does not accept atom
+ * coordinates as reference positions.
+ *
+ * TODO: This is not yet implemented.
+ *
+ * \see SelectionOption::dynamicOnlyWhole()
+ */
void setDynamicOnlyWhole(bool bEnabled);
private:
const SelectionOptionStorage &option() const;
};
-/*! \cond libapi */
-/*! \libinternal \brief
+/*! \brief
* Set selection collection for all selection options.
*
* Recursively sets the selection collection to \p selections for all selection
*
* Does not throw.
*
- * \inlibraryapi
+ * \inpublicapi
*/
void setSelectionCollectionForOptions(Options *options,
SelectionCollection *selections);
* \param[in] selections List of selections to add.
* \param[in] bFullValue If true, the provided selections are the full
* value of the option, and additional checks are performed.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if
+ * - There is an incorrect number of selections in \p selections.
+ * - Any selection in \p selections is not allowed for this
+ * option.
*
* This function is used to implement the methods
* SelectionCollection::parseRequestedFromStdin() and
// Required to access the number of values in selection requests.
// See SelectionCollection::Impl.
using MyBase::maxValueCount;
- /*! \brief
- * Sets the number of selections allowed for this selection.
- *
- * \param[in] count Required number of selections for this option.
- *
- * If values have already been provided, it is checked that a correct
- * number has been provided. If requests have already been made, but
- * have not yet been processed, they are also affected.
- */
+ //! \copydoc SelectionOptionInfo::setValueCount()
void setAllowedValueCount(int count);
/*! \brief
* Alters flags for the selections created by this option.
*
* \param[in] flag Flag to change.
* \param[in] bSet Whether to set or clear the flag.
+ * \throws std::bad_alloc if out of memory.
+ * \throws InvalidInputError if selections have already been
+ * provided and conflict with the given flags.
+ *
+ * If selections have already been provided, it is checked that they
+ * match the limitations enforced by the flags. Pending requests are
+ * also affected.
*
- * If values have already been provided, it is checked that they match
- * the limitations enforced by the flags. If requests have already
- * been made, but have not yet been processed, they are also affected.
+ * Strong exception safety guarantee.
*/
void setSelectionFlag(SelectionFlag flag, bool bSet);