Merge release-5-0 into master
[alexxy/gromacs.git] / src / gromacs / selection / selection.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::Selection and supporting classes.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inpublicapi
41  * \ingroup module_selection
42  */
43 #ifndef GMX_SELECTION_SELECTION_H
44 #define GMX_SELECTION_SELECTION_H
45
46 #include <string>
47 #include <vector>
48
49 #include "../utility/arrayref.h"
50 #include "../utility/common.h"
51 #include "../utility/gmxassert.h"
52
53 #include "position.h"
54 #include "selectionenums.h"
55
56 struct t_topology;
57
58 namespace gmx
59 {
60
61 class SelectionOptionStorage;
62 class SelectionTreeElement;
63
64 class AnalysisNeighborhoodPositions;
65 class Selection;
66 class SelectionPosition;
67
68 //! Container of selections used in public selection interfaces.
69 typedef std::vector<Selection> SelectionList;
70
71 namespace internal
72 {
73
74 /*! \internal
75  * \brief
76  * Internal data for a single selection.
77  *
78  * This class is internal to the selection module, but resides in a public
79  * header because of efficiency reasons: it allows frequently used access
80  * methods in \ref Selection to be inlined.
81  *
82  * Methods in this class do not throw unless otherwise specified.
83  *
84  * \ingroup module_selection
85  */
86 class SelectionData
87 {
88     public:
89         /*! \brief
90          * Creates a new selection object.
91          *
92          * \param[in] elem   Root of the evaluation tree for this selection.
93          * \param[in] selstr String that was parsed to produce this selection.
94          * \throws    std::bad_alloc if out of memory.
95          */
96         SelectionData(SelectionTreeElement *elem, const char *selstr);
97         ~SelectionData();
98
99         //! Returns the name for this selection.
100         const char *name() const { return name_.c_str(); }
101         //! Returns the string that was parsed to produce this selection.
102         const char *selectionText() const { return selectionText_.c_str(); }
103         //! Returns true if the size of the selection (posCount()) is dynamic.
104         bool isDynamic() const { return bDynamic_; }
105         //! Returns the type of positions in the selection.
106         e_index_t type() const { return rawPositions_.m.type; }
107
108         //! Number of positions in the selection.
109         int posCount() const { return rawPositions_.count(); }
110         //! Returns the root of the evaluation tree for this selection.
111         SelectionTreeElement &rootElement() { return rootElement_; }
112
113         //! Returns whether the covered fraction can change between frames.
114         bool isCoveredFractionDynamic() const { return bDynamicCoveredFraction_; }
115
116         //! Returns true if the given flag is set.
117         bool hasFlag(SelectionFlag flag) const { return flags_.test(flag); }
118         //! Sets the flags for this selection.
119         void setFlags(SelectionFlags flags) { flags_ = flags; }
120
121         //! \copydoc Selection::initCoveredFraction()
122         bool initCoveredFraction(e_coverfrac_t type);
123
124         /*! \brief
125          * Updates the name of the selection if missing.
126          *
127          * \throws    std::bad_alloc if out of memory.
128          *
129          * If selections get their value from a group reference that cannot be
130          * resolved during parsing, the name is final only after group
131          * references have been resolved.
132          *
133          * This function is called by SelectionCollection::setIndexGroups().
134          */
135         void refreshName();
136         /*! \brief
137          * Computes total masses and charges for all selection positions.
138          *
139          * \param[in] top   Topology information.
140          * \throws    std::bad_alloc if out of memory.
141          *
142          * For dynamic selections, the values need to be updated after each
143          * evaluation with refreshMassesAndCharges().
144          * This is done by SelectionEvaluator.
145          *
146          * This function is called by SelectionCompiler.
147          *
148          * Strong exception safety guarantee.
149          */
150         void initializeMassesAndCharges(const t_topology *top);
151         /*! \brief
152          * Updates masses and charges after dynamic selection has been
153          * evaluated.
154          *
155          * \param[in] top   Topology information.
156          *
157          * Called by SelectionEvaluator.
158          */
159         void refreshMassesAndCharges(const t_topology *top);
160         /*! \brief
161          * Updates the covered fraction after a selection has been evaluated.
162          *
163          * Called by SelectionEvaluator.
164          */
165         void updateCoveredFractionForFrame();
166         /*! \brief
167          * Computes average covered fraction after all frames have been evaluated.
168          *
169          * \param[in] nframes  Number of frames that have been evaluated.
170          *
171          * \p nframes should be equal to the number of calls to
172          * updateCoveredFractionForFrame().
173          * Called by SelectionEvaluator::evaluateFinal().
174          */
175         void computeAverageCoveredFraction(int nframes);
176         /*! \brief
177          * Restores position information to state it was in after compilation.
178          *
179          * \param[in] top   Topology information.
180          *
181          * Depends on SelectionCompiler storing the original atoms in the
182          * \a rootElement_ object.
183          * Called by SelectionEvaluator::evaluateFinal().
184          */
185         void restoreOriginalPositions(const t_topology *top);
186
187     private:
188         //! Name of the selection.
189         std::string               name_;
190         //! The actual selection string.
191         std::string               selectionText_;
192         //! Low-level representation of selected positions.
193         gmx_ana_pos_t             rawPositions_;
194         //! Total masses for the current positions.
195         std::vector<real>         posMass_;
196         //! Total charges for the current positions.
197         std::vector<real>         posCharge_;
198         SelectionFlags            flags_;
199         //! Root of the selection evaluation tree.
200         SelectionTreeElement     &rootElement_;
201         //! Type of the covered fraction.
202         e_coverfrac_t             coveredFractionType_;
203         //! Covered fraction of the selection for the current frame.
204         real                      coveredFraction_;
205         //! The average covered fraction (over the trajectory).
206         real                      averageCoveredFraction_;
207         //! true if the value can change as a function of time.
208         bool                      bDynamic_;
209         //! true if the covered fraction depends on the frame.
210         bool                      bDynamicCoveredFraction_;
211
212         /*! \brief
213          * Needed to wrap access to information.
214          */
215         friend class gmx::Selection;
216         /*! \brief
217          * Needed for proper access to position information.
218          */
219         friend class gmx::SelectionPosition;
220
221         GMX_DISALLOW_COPY_AND_ASSIGN(SelectionData);
222 };
223
224 }   // namespace internal
225
226 /*! \brief
227  * Provides access to a single selection.
228  *
229  * This class provides a public interface for accessing selection information.
230  * General information about the selection can be accessed with methods name(),
231  * selectionText(), isDynamic(), and type().  The first three can be accessed
232  * any time after the selection has been parsed, and type() can be accessed
233  * after the selection has been compiled.
234  *
235  * There are a few methods that can be used to change the behavior of the
236  * selection.  setEvaluateVelocities() and setEvaluateForces() can be called
237  * before the selection is compiled to request evaluation of velocities and/or
238  * forces in addition to coordinates.
239  *
240  * Each selection is made of a set of positions.  Each position has associated
241  * coordinates, and possibly velocities and forces if they have been requested
242  * and are available.  It also has a set of atoms associated with it; typically
243  * the coordinates are the center-of-mass or center-of-geometry coordinates for
244  * that set of atoms.  To access the number of positions in the selection, use
245  * posCount().  To access individual positions, use position().
246  * See SelectionPosition for details of how to use individual positions.
247  * setOriginalId() can be used to adjust the return value of
248  * SelectionPosition::mappedId(); see that method for details.
249  *
250  * It is also possible to access the list of atoms that make up all the
251  * positions directly: atomCount() returns the total number of atoms in the
252  * selection and atomIndices() an array of their indices.
253  * Similarly, it is possible to access the coordinates and other properties
254  * of the positions as continuous arrays through coordinates(), velocities(),
255  * forces(), masses(), charges(), refIds(), and mappedIds().
256  *
257  * Both positions and atoms can be accessed after the selection has been
258  * compiled.  For dynamic selections, the return values of these methods change
259  * after each evaluation to reflect the situation for the current frame.
260  * Before any frame has been evaluated, these methods return the maximal set
261  * to which the selection can evaluate.
262  *
263  * There are two possible modes for how positions for dynamic selections are
264  * handled.  In the default mode, posCount() can change, and for each frame,
265  * only the positions that are selected in that frame can be accessed.  In a
266  * masked mode, posCount() remains constant, i.e., the positions are always
267  * evaluated for the maximal set, and SelectionPosition::selected() is used to
268  * determine whether a position is selected for a frame.  The masked mode can
269  * be requested with SelectionOption::dynamicMask().
270  *
271  * The class also provides methods for printing out information: printInfo()
272  * and printDebugInfo().  These are mainly for internal use by Gromacs.
273  *
274  * This class works like a pointer type: copying and assignment is lightweight,
275  * and all copies work interchangeably, accessing the same internal data.
276  *
277  * Methods in this class do not throw.
278  *
279  * \see SelectionPosition
280  *
281  * \inpublicapi
282  * \ingroup module_selection
283  */
284 class Selection
285 {
286     public:
287         /*! \brief
288          * Creates a selection wrapper that has no associated selection.
289          *
290          * Any attempt to call methods in the object before a selection is
291          * assigned results in undefined behavior.
292          * isValid() returns `false` for the selection until it is initialized.
293          */
294         Selection() : sel_(NULL) {}
295         /*! \brief
296          * Creates a new selection object.
297          *
298          * \param  sel  Selection data to wrap.
299          *
300          * Only for internal use by the selection module.
301          */
302         explicit Selection(internal::SelectionData *sel) : sel_(sel) {}
303
304         //! Returns whether the selection object is initialized.
305         bool isValid() const { return sel_ != NULL; }
306
307         //! Returns whether two selection objects wrap the same selection.
308         bool operator==(const Selection &other) const
309         {
310             return sel_ == other.sel_;
311         }
312         //! Returns whether two selection objects wrap different selections.
313         bool operator!=(const Selection &other) const
314         {
315             return !operator==(other);
316         }
317
318         //! Returns the name of the selection.
319         const char *name() const  { return data().name(); }
320         //! Returns the string that was parsed to produce this selection.
321         const char *selectionText() const { return data().selectionText(); }
322         //! Returns true if the size of the selection (posCount()) is dynamic.
323         bool isDynamic() const { return data().isDynamic(); }
324         //! Returns the type of positions in the selection.
325         e_index_t type() const { return data().type(); }
326
327         //! Total number of atoms in the selection.
328         int atomCount() const
329         {
330             return data().rawPositions_.m.mapb.nra;
331         }
332         //! Returns atom indices of all atoms in the selection.
333         ConstArrayRef<int> atomIndices() const
334         {
335             return ConstArrayRef<int>(sel_->rawPositions_.m.mapb.a,
336                                       sel_->rawPositions_.m.mapb.nra);
337         }
338         //! Number of positions in the selection.
339         int posCount() const { return data().posCount(); }
340         //! Access a single position.
341         SelectionPosition position(int i) const;
342         //! Returns coordinates for this selection as a continuous array.
343         ConstArrayRef<rvec> coordinates() const
344         {
345             return ConstArrayRef<rvec>(data().rawPositions_.x, posCount());
346         }
347         //! Returns whether velocities are available for this selection.
348         bool hasVelocities() const { return data().rawPositions_.v != NULL; }
349         /*! \brief
350          * Returns velocities for this selection as a continuous array.
351          *
352          * Must not be called if hasVelocities() returns false.
353          */
354         ConstArrayRef<rvec> velocities() const
355         {
356             GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable");
357             return ConstArrayRef<rvec>(data().rawPositions_.v, posCount());
358         }
359         //! Returns whether forces are available for this selection.
360         bool hasForces() const { return sel_->rawPositions_.f != NULL; }
361         /*! \brief
362          * Returns forces for this selection as a continuous array.
363          *
364          * Must not be called if hasForces() returns false.
365          */
366         ConstArrayRef<rvec> forces() const
367         {
368             GMX_ASSERT(hasForces(), "Forces accessed, but unavailable");
369             return ConstArrayRef<rvec>(data().rawPositions_.f, posCount());
370         }
371         //! Returns masses for this selection as a continuous array.
372         ConstArrayRef<real> masses() const
373         {
374             // posMass_ may have more entries than posCount() in the case of
375             // dynamic selections that don't have a topology
376             // (and thus the masses and charges are fixed).
377             GMX_ASSERT(data().posMass_.size() >= static_cast<size_t>(posCount()),
378                        "Internal inconsistency");
379             return ConstArrayRef<real>(data().posMass_.begin(),
380                                        data().posMass_.begin() + posCount());
381         }
382         //! Returns charges for this selection as a continuous array.
383         ConstArrayRef<real> charges() const
384         {
385             // posCharge_ may have more entries than posCount() in the case of
386             // dynamic selections that don't have a topology
387             // (and thus the masses and charges are fixed).
388             GMX_ASSERT(data().posCharge_.size() >= static_cast<size_t>(posCount()),
389                        "Internal inconsistency");
390             return ConstArrayRef<real>(data().posCharge_.begin(),
391                                        data().posCharge_.begin() + posCount());
392         }
393         /*! \brief
394          * Returns reference IDs for this selection as a continuous array.
395          *
396          * \see SelectionPosition::refId()
397          */
398         ConstArrayRef<int> refIds() const
399         {
400             return ConstArrayRef<int>(data().rawPositions_.m.refid, posCount());
401         }
402         /*! \brief
403          * Returns mapped IDs for this selection as a continuous array.
404          *
405          * \see SelectionPosition::mappedId()
406          */
407         ConstArrayRef<int> mappedIds() const
408         {
409             return ConstArrayRef<int>(data().rawPositions_.m.mapid, posCount());
410         }
411
412         //! Returns whether the covered fraction can change between frames.
413         bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); }
414         //! Returns the covered fraction for the current frame.
415         real coveredFraction() const { return data().coveredFraction_; }
416
417         /*! \brief
418          * Allows passing a selection directly to neighborhood searching.
419          *
420          * When initialized this way, AnalysisNeighborhoodPair objects return
421          * indices that can be used to index the selection positions with
422          * position().
423          *
424          * Works exactly like if AnalysisNeighborhoodPositions had a
425          * constructor taking a Selection object as a parameter.
426          * See AnalysisNeighborhoodPositions for rationale and additional
427          * discussion.
428          */
429         operator AnalysisNeighborhoodPositions() const;
430
431         /*! \brief
432          * Initializes information about covered fractions.
433          *
434          * \param[in] type Type of covered fraction required.
435          * \returns   true if the covered fraction can be calculated for the
436          *      selection.
437          */
438         bool initCoveredFraction(e_coverfrac_t type)
439         {
440             return data().initCoveredFraction(type);
441         }
442         /*! \brief
443          * Sets whether this selection evaluates velocities for positions.
444          *
445          * \param[in] bEnabled  If true, velocities are evaluated.
446          *
447          * If you request the evaluation, but then evaluate the selection for
448          * a frame that does not contain velocity information, results are
449          * undefined.
450          *
451          * \todo
452          * Implement it such that in the above case, hasVelocities() will
453          * return false for such frames.
454          *
455          * Does not throw.
456          */
457         void setEvaluateVelocities(bool bEnabled)
458         {
459             data().flags_.set(efSelection_EvaluateVelocities, bEnabled);
460         }
461         /*! \brief
462          * Sets whether this selection evaluates forces for positions.
463          *
464          * \param[in] bEnabled  If true, forces are evaluated.
465          *
466          * If you request the evaluation, but then evaluate the selection for
467          * a frame that does not contain force information, results are
468          * undefined.
469          *
470          * Does not throw.
471          */
472         void setEvaluateForces(bool bEnabled)
473         {
474             data().flags_.set(efSelection_EvaluateForces, bEnabled);
475         }
476
477         /*! \brief
478          * Sets the ID for the \p i'th position for use with
479          * SelectionPosition::mappedId().
480          *
481          * \param[in] i  Zero-based index
482          * \param[in] id Identifier to set.
483          *
484          * This method is not part of SelectionPosition because that interface
485          * only provides access to const data by design.
486          *
487          * This method can only be called after compilation, before the
488          * selection has been evaluated for any frame.
489          *
490          * \see SelectionPosition::mappedId()
491          */
492         void setOriginalId(int i, int id) { data().rawPositions_.m.orgid[i] = id; }
493
494         /*! \brief
495          * Prints out one-line description of the selection.
496          *
497          * \param[in] fp      Where to print the information.
498          *
499          * The output contains the name of the selection, the number of atoms
500          * and the number of positions, and indication of whether the selection
501          * is dynamic.
502          */
503         void printInfo(FILE *fp) const;
504         /*! \brief
505          * Prints out extended information about the selection for debugging.
506          *
507          * \param[in] fp      Where to print the information.
508          * \param[in] nmaxind Maximum number of values to print in lists
509          *      (-1 = print all).
510          */
511         void printDebugInfo(FILE *fp, int nmaxind) const;
512
513     private:
514         internal::SelectionData &data()
515         {
516             GMX_ASSERT(sel_ != NULL,
517                        "Attempted to access uninitialized selection");
518             return *sel_;
519         }
520         const internal::SelectionData &data() const
521         {
522             GMX_ASSERT(sel_ != NULL,
523                        "Attempted to access uninitialized selection");
524             return *sel_;
525         }
526
527         /*! \brief
528          * Pointer to internal data for the selection.
529          *
530          * The memory for this object is managed by a SelectionCollection
531          * object, and the \ref Selection class simply provides a public
532          * interface for accessing the data.
533          */
534         internal::SelectionData *sel_;
535
536         /*! \brief
537          * Needed to access the data to adjust flags.
538          */
539         friend class SelectionOptionStorage;
540 };
541
542 /*! \brief
543  * Provides access to information about a single selected position.
544  *
545  * Each position has associated coordinates, and possibly velocities and forces
546  * if they have been requested and are available.  It also has a set of atoms
547  * associated with it; typically the coordinates are the center-of-mass or
548  * center-of-geometry coordinates for that set of atoms.  It is possible that
549  * there are not atoms associated if the selection has been provided as a fixed
550  * position.
551  *
552  * After the selection has been compiled, but not yet evaluated, the contents
553  * of the coordinate, velocity and force vectors are undefined.
554  *
555  * Default copy constructor and assignment operators are used, and work as
556  * intended: the copy references the same position and works identically.
557  *
558  * Methods in this class do not throw.
559  *
560  * \see Selection
561  *
562  * \inpublicapi
563  * \ingroup module_selection
564  */
565 class SelectionPosition
566 {
567     public:
568         /*! \brief
569          * Constructs a wrapper object for given selection position.
570          *
571          * \param[in] sel    Selection from which the position is wrapped.
572          * \param[in] index  Zero-based index of the position to wrap.
573          *
574          * Asserts if \p index is out of range.
575          *
576          * Only for internal use of the library.  To obtain a SelectionPosition
577          * object in other code, use Selection::position().
578          */
579         SelectionPosition(const internal::SelectionData &sel, int index)
580             : sel_(&sel), i_(index)
581         {
582             GMX_ASSERT(index >= 0 && index < sel.posCount(),
583                        "Invalid selection position index");
584         }
585
586         /*! \brief
587          * Returns type of this position.
588          *
589          * Currently always returns the same as Selection::type().
590          */
591         e_index_t type() const { return sel_->type(); }
592         //! Returns coordinates for this position.
593         const rvec &x() const
594         {
595             return sel_->rawPositions_.x[i_];
596         }
597         /*! \brief
598          * Returns velocity for this position.
599          *
600          * Must not be called if Selection::hasVelocities() returns false.
601          */
602         const rvec &v() const
603         {
604             GMX_ASSERT(sel_->rawPositions_.v != NULL,
605                        "Velocities accessed, but unavailable");
606             return sel_->rawPositions_.v[i_];
607         }
608         /*! \brief
609          * Returns force for this position.
610          *
611          * Must not be called if Selection::hasForces() returns false.
612          */
613         const rvec &f() const
614         {
615             GMX_ASSERT(sel_->rawPositions_.f != NULL,
616                        "Velocities accessed, but unavailable");
617             return sel_->rawPositions_.f[i_];
618         }
619         /*! \brief
620          * Returns total mass for this position.
621          *
622          * Returns the total mass of atoms that make up this position.
623          * If there are no atoms associated or masses are not available,
624          * returns unity.
625          */
626         real mass() const
627         {
628             return sel_->posMass_[i_];
629         }
630         /*! \brief
631          * Returns total charge for this position.
632          *
633          * Returns the sum of charges of atoms that make up this position.
634          * If there are no atoms associated or charges are not available,
635          * returns zero.
636          */
637         real charge() const
638         {
639             return sel_->posCharge_[i_];
640         }
641         //! Returns the number of atoms that make up this position.
642         int atomCount() const
643         {
644             return sel_->rawPositions_.m.mapb.index[i_ + 1]
645                    - sel_->rawPositions_.m.mapb.index[i_];
646         }
647         //! Return atom indices that make up this position.
648         ConstArrayRef<int> atomIndices() const
649         {
650             const int *atoms = sel_->rawPositions_.m.mapb.a;
651             if (atoms == NULL)
652             {
653                 return ConstArrayRef<int>();
654             }
655             const int first = sel_->rawPositions_.m.mapb.index[i_];
656             return ConstArrayRef<int>(&atoms[first], atomCount());
657         }
658         /*! \brief
659          * Returns whether this position is selected in the current frame.
660          *
661          * The return value is equivalent to \c refid() == -1.  Returns always
662          * true if SelectionOption::dynamicMask() has not been set.
663          *
664          * \see refId()
665          */
666         bool selected() const
667         {
668             return refId() >= 0;
669         }
670         /*! \brief
671          * Returns reference ID for this position.
672          *
673          * For dynamic selections, this provides means to associate positions
674          * across frames.  After compilation, these IDs are consequently
675          * numbered starting from zero.  For each frame, the ID then reflects
676          * the location of the position in the original array of positions.
677          * If SelectionOption::dynamicMask() has been set for the parent
678          * selection, the IDs for positions not present in the current
679          * selection are set to -1, otherwise they are removed completely.
680          *
681          * Example:
682          * If a dynamic selection consists of at most three positions, after
683          * compilation refId() will return 0, 1, 2 for them, respectively.
684          * If for a particular frame, only the first and the third are present,
685          * refId() will return 0, 2.
686          * If SelectionOption::dynamicMask() has been set, all three positions
687          * can be accessed also for that frame and refId() will return 0, -1,
688          * 2.
689          */
690         int refId() const
691         {
692             return sel_->rawPositions_.m.refid[i_];
693         }
694         /*! \brief
695          * Returns mapped ID for this position.
696          *
697          * Returns ID of the position that corresponds to that set with
698          * Selection::setOriginalId().
699          *
700          * If for an array \c id, \c setOriginalId(i, id[i]) has been called
701          * for each \c i, then it always holds that
702          * \c mappedId()==id[refId()].
703          *
704          * Selection::setOriginalId() has not been called, the default values
705          * are dependent on type():
706          *  - ::INDEX_ATOM: atom indices
707          *  - ::INDEX_RES:  residue numbers
708          *  - ::INDEX_MOL:  molecule numbers
709          *  .
710          * All the default values are zero-based
711          */
712         int mappedId() const
713         {
714             return sel_->rawPositions_.m.mapid[i_];
715         }
716
717         /*! \brief
718          * Allows passing a selection position directly to neighborhood searching.
719          *
720          * When initialized this way, AnalysisNeighborhoodPair objects return
721          * the index that can be used to access this position using
722          * Selection::position().
723          *
724          * Works exactly like if AnalysisNeighborhoodPositions had a
725          * constructor taking a SelectionPosition object as a parameter.
726          * See AnalysisNeighborhoodPositions for rationale and additional
727          * discussion.
728          */
729         operator AnalysisNeighborhoodPositions() const;
730
731     private:
732         const internal::SelectionData  *sel_;
733         int                             i_;
734 };
735
736
737 inline SelectionPosition
738 Selection::position(int i) const
739 {
740     return SelectionPosition(data(), i);
741 }
742
743 } // namespace gmx
744
745 #endif