3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
33 * Declares gmx::Selection and supporting classes.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
37 * \ingroup module_selection
39 #ifndef GMX_SELECTION_SELECTION_H
40 #define GMX_SELECTION_SELECTION_H
45 #include "../legacyheaders/typedefs.h"
47 #include "../utility/arrayref.h"
48 #include "../utility/common.h"
49 #include "../utility/gmxassert.h"
52 #include "indexutil.h"
53 #include "selectionenums.h"
58 class SelectionOptionStorage;
59 class SelectionTreeElement;
62 class SelectionPosition;
64 //! Container of selections used in public selection interfaces.
65 typedef std::vector<Selection> SelectionList;
71 * Internal data for a single selection.
73 * This class is internal to the selection module, but resides in a public
74 * header because of efficiency reasons: it allows frequently used access
75 * methods in \ref Selection to be inlined.
77 * Methods in this class do not throw unless otherwise specified.
79 * \ingroup module_selection
85 * Creates a new selection object.
87 * \param[in] elem Root of the evaluation tree for this selection.
88 * \param[in] selstr String that was parsed to produce this selection.
89 * \throws std::bad_alloc if out of memory.
91 SelectionData(SelectionTreeElement *elem, const char *selstr);
94 //! Returns the string that was parsed to produce this selection.
95 const char *selectionText() const { return selectionText_.c_str(); }
96 //! Returns true if the size of the selection (posCount()) is dynamic.
97 bool isDynamic() const { return bDynamic_; }
98 //! Number of positions in the selection.
99 int posCount() const { return rawPositions_.nr; }
100 //! Returns the root of the evaluation tree for this selection.
101 SelectionTreeElement &rootElement() { return rootElement_; }
103 //! Returns whether the covered fraction can change between frames.
104 bool isCoveredFractionDynamic() const { return bDynamicCoveredFraction_; }
106 //! Returns true if the given flag is set.
107 bool hasFlag(SelectionFlag flag) const { return flags_.test(flag); }
108 //! Sets the flags for this selection.
109 void setFlags(SelectionFlags flags) { flags_ = flags; }
111 //! \copydoc Selection::initCoveredFraction()
112 bool initCoveredFraction(e_coverfrac_t type);
115 * Computes total masses and charges for all selection positions.
117 * \param[in] top Topology information.
118 * \throws std::bad_alloc if out of memory.
120 * For dynamic selections, the values need to be updated after each
121 * evaluation with refreshMassesAndCharges().
122 * This is done by SelectionEvaluator.
124 * This function is called by SelectionCompiler.
126 * Strong exception safety guarantee.
128 void initializeMassesAndCharges(const t_topology *top);
130 * Updates masses and charges after dynamic selection has been
133 * \param[in] top Topology information.
135 * Called by SelectionEvaluator.
137 void refreshMassesAndCharges(const t_topology *top);
139 * Updates the covered fraction after a selection has been evaluated.
141 * Called by SelectionEvaluator.
143 void updateCoveredFractionForFrame();
145 * Computes average covered fraction after all frames have been evaluated.
147 * \param[in] nframes Number of frames that have been evaluated.
149 * \p nframes should be equal to the number of calls to
150 * updateCoveredFractionForFrame().
151 * Called by SelectionEvaluator::evaluateFinal().
153 void computeAverageCoveredFraction(int nframes);
155 * Restores position information to state it was in after compilation.
157 * \param[in] top Topology information.
159 * Depends on SelectionCompiler storing the original atoms in the
160 * \a rootElement_ object.
161 * Called by SelectionEvaluator::evaluateFinal().
163 void restoreOriginalPositions(const t_topology *top);
166 //! Name of the selection.
168 //! The actual selection string.
169 std::string selectionText_;
170 //! Low-level representation of selected positions.
171 gmx_ana_pos_t rawPositions_;
172 //! Total masses for the current positions.
173 std::vector<real> posMass_;
174 //! Total charges for the current positions.
175 std::vector<real> posCharge_;
176 SelectionFlags flags_;
177 //! Root of the selection evaluation tree.
178 SelectionTreeElement &rootElement_;
179 //! Type of the covered fraction.
180 e_coverfrac_t coveredFractionType_;
181 //! Covered fraction of the selection for the current frame.
182 real coveredFraction_;
183 //! The average covered fraction (over the trajectory).
184 real averageCoveredFraction_;
185 //! true if the value can change as a function of time.
187 //! true if the covered fraction depends on the frame.
188 bool bDynamicCoveredFraction_;
191 * Needed to wrap access to information.
193 friend class gmx::Selection;
195 * Needed for proper access to position information.
197 friend class gmx::SelectionPosition;
199 GMX_DISALLOW_COPY_AND_ASSIGN(SelectionData);
202 } // namespace internal
205 * Provides access to a single selection.
207 * This class provides a public interface for accessing selection information.
208 * General information about the selection can be accessed with methods name(),
209 * selectionText(), isDynamic(), and type(). The first three can be accessed
210 * any time after the selection has been parsed, and type() can be accessed
211 * after the selection has been compiled.
213 * Each selection is made of a set of positions. Each position has associated
214 * coordinates, and possibly velocities and forces if they have been requested
215 * and are available. It also has a set of atoms associated with it; typically
216 * the coordinates are the center-of-mass or center-of-geometry coordinates for
217 * that set of atoms. To access the number of positions in the selection, use
218 * posCount(). To access individual positions, use position().
219 * See SelectionPosition for details of how to use individual positions.
220 * setOriginalId() can be used to adjust the return value of
221 * SelectionPosition::mappedId(); see that method for details.
223 * It is also possible to access the list of atoms that make up all the
224 * positions directly: atomCount() returns the total number of atoms in the
225 * selection and atomIndices() an array of their indices.
227 * Both positions and atoms can be accessed after the selection has been
228 * compiled. For dynamic selections, the return values of these methods change
229 * after each evaluation to reflect the situation for the current frame.
230 * Before any frame has been evaluated, these methods return the maximal set
231 * to which the selection can evaluate.
233 * There are two possible modes for how positions for dynamic selections are
234 * handled. In the default mode, posCount() can change, and for each frame,
235 * only the positions that are selected in that frame can be accessed. In a
236 * masked mode, posCount() remains constant, i.e., the positions are always
237 * evaluated for the maximal set, and SelectionPosition::selected() is used to
238 * determine whether a position is selected for a frame. The masked mode can
239 * be requested with SelectionOption::dynamicMask().
241 * The class also provides methods for printing out information: printInfo()
242 * and printDebugInfo(). These are mainly for internal use by Gromacs.
244 * This class works like a pointer type: copying and assignment is lightweight,
245 * and all copies work interchangeably, accessing the same internal data.
247 * Methods in this class do not throw.
249 * \see SelectionPosition
252 * \ingroup module_selection
258 * Creates a selection wrapper that has no associated selection.
260 * Any attempt to call methods in the object before a selection is
261 * assigned results in undefined behavior.
263 Selection() : sel_(NULL) {}
265 * Creates a new selection object.
267 * \param sel Selection data to wrap.
269 * Only for internal use by the selection module.
271 explicit Selection(internal::SelectionData *sel) : sel_(sel) {}
273 //! Returns the name of the selection.
274 const char *name() const { return data().name_.c_str(); }
275 //! Returns the string that was parsed to produce this selection.
276 const char *selectionText() const { return data().selectionText(); }
277 //! Returns true if the size of the selection (posCount()) is dynamic.
278 bool isDynamic() const { return data().isDynamic(); }
279 //! Returns the type of positions in the selection.
280 e_index_t type() const { return data().rawPositions_.m.type; }
282 //! Total number of atoms in the selection.
283 int atomCount() const
285 return data().rawPositions_.g != NULL ? data().rawPositions_.g->isize : 0;
287 //! Returns atom indices of all atoms in the selection.
288 ConstArrayRef<int> atomIndices() const
290 if (data().rawPositions_.g == NULL)
292 return ConstArrayRef<int>();
294 return ConstArrayRef<int>(data().rawPositions_.g->isize,
295 data().rawPositions_.g->index);
297 //! Number of positions in the selection.
298 int posCount() const { return data().posCount(); }
299 //! Access a single position.
300 SelectionPosition position(int i) const;
302 * Sets the ID for the \p i'th position for use with
303 * SelectionPosition::mappedId().
305 * \param[in] i Zero-based index
306 * \param[in] id Identifier to set.
308 * This method is not part of SelectionPosition because that interface
309 * only provides access to const data by design.
311 * This method can only be called after compilation, before the
312 * selection has been evaluated for any frame.
314 * \see SelectionPosition::mappedId()
316 void setOriginalId(int i, int id) { data().rawPositions_.m.orgid[i] = id; }
318 //! Deprecated method for direct access to position data.
319 const gmx_ana_pos_t *positions() const { return &data().rawPositions_; }
321 //! Returns whether the covered fraction can change between frames.
322 bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); }
323 //! Returns the covered fraction for the current frame.
324 real coveredFraction() const { return data().coveredFraction_; }
326 * Initializes information about covered fractions.
328 * \param[in] type Type of covered fraction required.
329 * \returns true if the covered fraction can be calculated for the
332 bool initCoveredFraction(e_coverfrac_t type)
334 return data().initCoveredFraction(type);
338 * Prints out one-line description of the selection.
340 * \param[in] fp Where to print the information.
342 * The output contains the name of the selection, the number of atoms
343 * and the number of positions, and indication of whether the selection
346 void printInfo(FILE *fp) const;
348 * Prints out extended information about the selection for debugging.
350 * \param[in] fp Where to print the information.
351 * \param[in] nmaxind Maximum number of values to print in lists
354 void printDebugInfo(FILE *fp, int nmaxind) const;
357 internal::SelectionData &data()
359 GMX_ASSERT(sel_ != NULL,
360 "Attempted to access uninitialized selection");
363 const internal::SelectionData &data() const
365 GMX_ASSERT(sel_ != NULL,
366 "Attempted to access uninitialized selection");
371 * Pointer to internal data for the selection.
373 * The memory for this object is managed by a SelectionCollection
374 * object, and the \ref Selection class simply provides a public
375 * interface for accessing the data.
377 internal::SelectionData *sel_;
380 * Needed to access the data to adjust flags.
382 friend class SelectionOptionStorage;
386 * Provides access to information about a single selected position.
388 * Each position has associated coordinates, and possibly velocities and forces
389 * if they have been requested and are available. It also has a set of atoms
390 * associated with it; typically the coordinates are the center-of-mass or
391 * center-of-geometry coordinates for that set of atoms. It is possible that
392 * there are not atoms associated if the selection has been provided as a fixed
395 * After the selection has been compiled, but not yet evaluated, the contents
396 * of the coordinate, velocity and force vectors are undefined.
398 * Default copy constructor and assignment operators are used, and work as
399 * intended: the copy references the same position and works identically.
401 * Methods in this class do not throw.
406 * \ingroup module_selection
408 class SelectionPosition
412 * Constructs a wrapper object for given selection position.
414 * \param[in] sel Selection from which the position is wrapped.
415 * \param[in] index Zero-based index of the position to wrap.
417 * Asserts if \p index is out of range.
419 * Only for internal use of the library. To obtain a SelectionPosition
420 * object in other code, use Selection::position().
422 SelectionPosition(const internal::SelectionData &sel, int index)
423 : sel_(&sel), i_(index)
425 GMX_ASSERT(index >= 0 && index < sel.posCount(),
426 "Invalid selection position index");
430 * Returns type of this position.
432 * Currently always returns the same as Selection::type().
434 e_index_t type() const { return sel_->rawPositions_.m.type; }
435 //! Returns coordinates for this position.
436 const rvec &x() const
438 return sel_->rawPositions_.x[i_];
440 //! Returns whether velocity is available for this position.
441 bool hasVelocity() const { return sel_->rawPositions_.v != NULL; }
443 * Returns velocity for this position.
445 * Must not be called if hasVelocity() returns false.
447 const rvec &v() const
449 GMX_ASSERT(hasVelocity(), "Velocities accessed, but unavailable");
450 return sel_->rawPositions_.v[i_];
452 //! Returns whether force is available for this position.
453 bool hasForce() const { return sel_->rawPositions_.f != NULL; }
455 * Returns force for this position.
457 * Must not be called if hasForce() returns false.
459 const rvec &f() const
461 GMX_ASSERT(hasForce(), "Forces accessed, but unavailable");
462 return sel_->rawPositions_.f[i_];
465 * Returns total mass for this position.
467 * Returns the total mass of atoms that make up this position.
468 * If there are no atoms associated or masses are not available,
473 return sel_->posMass_[i_];
476 * Returns total charge for this position.
478 * Returns the sum of charges of atoms that make up this position.
479 * If there are no atoms associated or charges are not available,
484 return sel_->posCharge_[i_];
486 //! Returns the number of atoms that make up this position.
487 int atomCount() const
489 return sel_->rawPositions_.m.mapb.index[i_ + 1]
490 - sel_->rawPositions_.m.mapb.index[i_];
492 //! Return atom indices that make up this position.
493 ConstArrayRef<int> atomIndices() const
495 if (sel_->rawPositions_.g == NULL)
497 return ConstArrayRef<int>();
499 int first = sel_->rawPositions_.m.mapb.index[i_];
500 return ConstArrayRef<int>(atomCount(),
501 &sel_->rawPositions_.g->index[first]);
504 * Returns whether this position is selected in the current frame.
506 * The return value is equivalent to \c refid() == -1. Returns always
507 * true if SelectionOption::dynamicMask() has not been set.
511 bool selected() const
516 * Returns reference ID for this position.
518 * For dynamic selections, this provides means to associate positions
519 * across frames. After compilation, these IDs are consequently
520 * numbered starting from zero. For each frame, the ID then reflects
521 * the location of the position in the original array of positions.
522 * If SelectionOption::dynamicMask() has been set for the parent
523 * selection, the IDs for positions not present in the current
524 * selection are set to -1, otherwise they are removed completely.
527 * If a dynamic selection consists of at most three positions, after
528 * compilation refId() will return 0, 1, 2 for them, respectively.
529 * If for a particular frame, only the first and the third are present,
530 * refId() will return 0, 2.
531 * If SelectionOption::dynamicMask() has been set, all three positions
532 * can be accessed also for that frame and refId() will return 0, -1,
537 return sel_->rawPositions_.m.refid[i_];
540 * Returns mapped ID for this position.
542 * Returns ID of the position that corresponds to that set with
543 * Selection::setOriginalId().
545 * If for an array \c id, \c setOriginalId(i, id[i]) has been called
546 * for each \c i, then it always holds that
547 * \c mappedId()==id[refId()].
549 * Selection::setOriginalId() has not been called, the default values
550 * are dependent on type():
551 * - ::INDEX_ATOM: atom indices
552 * - ::INDEX_RES: residue numbers
553 * - ::INDEX_MOL: molecule numbers
555 * All the default values are zero-based
559 return sel_->rawPositions_.m.mapid[i_];
563 const internal::SelectionData *sel_;
568 inline SelectionPosition
569 Selection::position(int i) const
571 return SelectionPosition(data(), i);