Merge "Merge release-4-6 into master"
[alexxy/gromacs.git] / src / gromacs / selection / selection.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
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.
13
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.
18  *
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.
25  *
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.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Declares gmx::Selection and supporting classes.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inpublicapi
37  * \ingroup module_selection
38  */
39 #ifndef GMX_SELECTION_SELECTION_H
40 #define GMX_SELECTION_SELECTION_H
41
42 #include <string>
43 #include <vector>
44
45 #include "../legacyheaders/typedefs.h"
46
47 #include "../utility/arrayref.h"
48 #include "../utility/common.h"
49 #include "../utility/gmxassert.h"
50
51 #include "position.h"
52 #include "indexutil.h"
53 #include "selectionenums.h"
54
55 namespace gmx
56 {
57
58 class SelectionOptionStorage;
59 class SelectionTreeElement;
60
61 class Selection;
62 class SelectionPosition;
63
64 //! Container of selections used in public selection interfaces.
65 typedef std::vector<Selection> SelectionList;
66
67 namespace internal
68 {
69
70 /*! \internal \brief
71  * Internal data for a single selection.
72  *
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.
76  *
77  * Methods in this class do not throw unless otherwise specified.
78  *
79  * \ingroup module_selection
80  */
81 class SelectionData
82 {
83     public:
84         /*! \brief
85          * Creates a new selection object.
86          *
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.
90          */
91         SelectionData(SelectionTreeElement *elem, const char *selstr);
92         ~SelectionData();
93
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_; }
102
103         //! Returns whether the covered fraction can change between frames.
104         bool isCoveredFractionDynamic() const { return bDynamicCoveredFraction_; }
105
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; }
110
111         //! \copydoc Selection::initCoveredFraction()
112         bool initCoveredFraction(e_coverfrac_t type);
113
114         /*! \brief
115          * Computes total masses and charges for all selection positions.
116          *
117          * \param[in] top   Topology information.
118          * \throws    std::bad_alloc if out of memory.
119          *
120          * For dynamic selections, the values need to be updated after each
121          * evaluation with refreshMassesAndCharges().
122          * This is done by SelectionEvaluator.
123          *
124          * This function is called by SelectionCompiler.
125          *
126          * Strong exception safety guarantee.
127          */
128         void initializeMassesAndCharges(const t_topology *top);
129         /*! \brief
130          * Updates masses and charges after dynamic selection has been
131          * evaluated.
132          *
133          * \param[in] top   Topology information.
134          *
135          * Called by SelectionEvaluator.
136          */
137         void refreshMassesAndCharges(const t_topology *top);
138         /*! \brief
139          * Updates the covered fraction after a selection has been evaluated.
140          *
141          * Called by SelectionEvaluator.
142          */
143         void updateCoveredFractionForFrame();
144         /*! \brief
145          * Computes average covered fraction after all frames have been evaluated.
146          *
147          * \param[in] nframes  Number of frames that have been evaluated.
148          *
149          * \p nframes should be equal to the number of calls to
150          * updateCoveredFractionForFrame().
151          * Called by SelectionEvaluator::evaluateFinal().
152          */
153         void computeAverageCoveredFraction(int nframes);
154         /*! \brief
155          * Restores position information to state it was in after compilation.
156          *
157          * \param[in] top   Topology information.
158          *
159          * Depends on SelectionCompiler storing the original atoms in the
160          * \a rootElement_ object.
161          * Called by SelectionEvaluator::evaluateFinal().
162          */
163         void restoreOriginalPositions(const t_topology *top);
164
165     private:
166         //! Name of the selection.
167         std::string               name_;
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.
186         bool                      bDynamic_;
187         //! true if the covered fraction depends on the frame.
188         bool                      bDynamicCoveredFraction_;
189
190         /*! \brief
191          * Needed to wrap access to information.
192          */
193         friend class gmx::Selection;
194         /*! \brief
195          * Needed for proper access to position information.
196          */
197         friend class gmx::SelectionPosition;
198
199         GMX_DISALLOW_COPY_AND_ASSIGN(SelectionData);
200 };
201
202 }   // namespace internal
203
204 /*! \brief
205  * Provides access to a single selection.
206  *
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.
212  *
213  * There are a few methods that can be used to change the behavior of the
214  * selection.  setEvaluateVelocities() and setEvaluateForces() can be called
215  * before the selection is compiled to request evaluation of velocities and/or
216  * forces in addition to coordinates.
217  *
218  * Each selection is made of a set of positions.  Each position has associated
219  * coordinates, and possibly velocities and forces if they have been requested
220  * and are available.  It also has a set of atoms associated with it; typically
221  * the coordinates are the center-of-mass or center-of-geometry coordinates for
222  * that set of atoms.  To access the number of positions in the selection, use
223  * posCount().  To access individual positions, use position().
224  * See SelectionPosition for details of how to use individual positions.
225  * setOriginalId() can be used to adjust the return value of
226  * SelectionPosition::mappedId(); see that method for details.
227  *
228  * It is also possible to access the list of atoms that make up all the
229  * positions directly: atomCount() returns the total number of atoms in the
230  * selection and atomIndices() an array of their indices.
231  * Similarly, it is possible to access the coordinates and other properties
232  * of the positions as continuous arrays through coordinates(), velocities(),
233  * forces(), masses(), charges(), refIds(), and mappedIds().
234  *
235  * Both positions and atoms can be accessed after the selection has been
236  * compiled.  For dynamic selections, the return values of these methods change
237  * after each evaluation to reflect the situation for the current frame.
238  * Before any frame has been evaluated, these methods return the maximal set
239  * to which the selection can evaluate.
240  *
241  * There are two possible modes for how positions for dynamic selections are
242  * handled.  In the default mode, posCount() can change, and for each frame,
243  * only the positions that are selected in that frame can be accessed.  In a
244  * masked mode, posCount() remains constant, i.e., the positions are always
245  * evaluated for the maximal set, and SelectionPosition::selected() is used to
246  * determine whether a position is selected for a frame.  The masked mode can
247  * be requested with SelectionOption::dynamicMask().
248  *
249  * The class also provides methods for printing out information: printInfo()
250  * and printDebugInfo().  These are mainly for internal use by Gromacs.
251  *
252  * This class works like a pointer type: copying and assignment is lightweight,
253  * and all copies work interchangeably, accessing the same internal data.
254  *
255  * Methods in this class do not throw.
256  *
257  * \see SelectionPosition
258  *
259  * \inpublicapi
260  * \ingroup module_selection
261  */
262 class Selection
263 {
264     public:
265         /*! \brief
266          * Creates a selection wrapper that has no associated selection.
267          *
268          * Any attempt to call methods in the object before a selection is
269          * assigned results in undefined behavior.
270          */
271         Selection() : sel_(NULL) {}
272         /*! \brief
273          * Creates a new selection object.
274          *
275          * \param  sel  Selection data to wrap.
276          *
277          * Only for internal use by the selection module.
278          */
279         explicit Selection(internal::SelectionData *sel) : sel_(sel) {}
280
281         //! Returns the name of the selection.
282         const char *name() const  { return data().name_.c_str(); }
283         //! Returns the string that was parsed to produce this selection.
284         const char *selectionText() const { return data().selectionText(); }
285         //! Returns true if the size of the selection (posCount()) is dynamic.
286         bool isDynamic() const { return data().isDynamic(); }
287         //! Returns the type of positions in the selection.
288         e_index_t type() const { return data().rawPositions_.m.type; }
289
290         //! Total number of atoms in the selection.
291         int atomCount() const
292         {
293             return data().rawPositions_.g != NULL ? data().rawPositions_.g->isize : 0;
294         }
295         //! Returns atom indices of all atoms in the selection.
296         ConstArrayRef<int> atomIndices() const
297         {
298             if (data().rawPositions_.g == NULL)
299             {
300                 return ConstArrayRef<int>();
301             }
302             return ConstArrayRef<int>(data().rawPositions_.g->index,
303                                       data().rawPositions_.g->isize);
304         }
305         //! Number of positions in the selection.
306         int posCount() const { return data().posCount(); }
307         //! Access a single position.
308         SelectionPosition position(int i) const;
309         //! Returns coordinates for this selection as a continuous array.
310         ConstArrayRef<rvec> coordinates() const
311         {
312             return ConstArrayRef<rvec>(data().rawPositions_.x, posCount());
313         }
314         //! Returns whether velocities are available for this selection.
315         bool hasVelocities() const { return data().rawPositions_.v != NULL; }
316         /*! \brief
317          * Returns velocities for this selection as a continuous array.
318          *
319          * Must not be called if hasVelocities() returns false.
320          */
321         ConstArrayRef<rvec> velocities() const
322         {
323             GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable");
324             return ConstArrayRef<rvec>(data().rawPositions_.v, posCount());
325         }
326         //! Returns whether forces are available for this selection.
327         bool hasForces() const { return sel_->rawPositions_.f != NULL; }
328         /*! \brief
329          * Returns forces for this selection as a continuous array.
330          *
331          * Must not be called if hasForces() returns false.
332          */
333         ConstArrayRef<rvec> forces() const
334         {
335             GMX_ASSERT(hasForces(), "Forces accessed, but unavailable");
336             return ConstArrayRef<rvec>(data().rawPositions_.f, posCount());
337         }
338         //! Returns masses for this selection as a continuous array.
339         ConstArrayRef<real> masses() const
340         {
341             // posMass_ may have more entries than posCount() in the case of
342             // dynamic selections that don't have a topology
343             // (and thus the masses and charges are fixed).
344             GMX_ASSERT(data().posMass_.size() >= static_cast<size_t>(posCount()),
345                        "Internal inconsistency");
346             return ConstArrayRef<real>(data().posMass_.begin(),
347                                        data().posMass_.begin() + posCount());
348         }
349         //! Returns charges for this selection as a continuous array.
350         ConstArrayRef<real> charges() const
351         {
352             // posCharge_ may have more entries than posCount() in the case of
353             // dynamic selections that don't have a topology
354             // (and thus the masses and charges are fixed).
355             GMX_ASSERT(data().posCharge_.size() >= static_cast<size_t>(posCount()),
356                        "Internal inconsistency");
357             return ConstArrayRef<real>(data().posCharge_.begin(),
358                                        data().posCharge_.begin() + posCount());
359         }
360         /*! \brief
361          * Returns reference IDs for this selection as a continuous array.
362          *
363          * \see SelectionPosition::refId()
364          */
365         ConstArrayRef<int> refIds() const
366         {
367             return ConstArrayRef<int>(data().rawPositions_.m.refid, posCount());
368         }
369         /*! \brief
370          * Returns mapped IDs for this selection as a continuous array.
371          *
372          * \see SelectionPosition::mappedId()
373          */
374         ConstArrayRef<int> mappedIds() const
375         {
376             return ConstArrayRef<int>(data().rawPositions_.m.mapid, posCount());
377         }
378
379         //! Deprecated method for direct access to position data.
380         const gmx_ana_pos_t *positions() const { return &data().rawPositions_; }
381
382         //! Returns whether the covered fraction can change between frames.
383         bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); }
384         //! Returns the covered fraction for the current frame.
385         real coveredFraction() const { return data().coveredFraction_; }
386
387         /*! \brief
388          * Initializes information about covered fractions.
389          *
390          * \param[in] type Type of covered fraction required.
391          * \returns   true if the covered fraction can be calculated for the
392          *      selection.
393          */
394         bool initCoveredFraction(e_coverfrac_t type)
395         {
396             return data().initCoveredFraction(type);
397         }
398         /*! \brief
399          * Sets whether this selection evaluates velocities for positions.
400          *
401          * \param[in] bEnabled  If true, velocities are evaluated.
402          *
403          * If you request the evaluation, but then evaluate the selection for
404          * a frame that does not contain velocity information, results are
405          * undefined.
406          *
407          * \todo
408          * Implement it such that in the above case, hasVelocities() will
409          * return false for such frames.
410          *
411          * Does not throw.
412          */
413         void setEvaluateVelocities(bool bEnabled)
414         {
415             data().flags_.set(efSelection_EvaluateVelocities, bEnabled);
416         }
417         /*! \brief
418          * Sets whether this selection evaluates forces for positions.
419          *
420          * \param[in] bEnabled  If true, forces are evaluated.
421          *
422          * If you request the evaluation, but then evaluate the selection for
423          * a frame that does not contain force information, results are
424          * undefined.
425          *
426          * Does not throw.
427          */
428         void setEvaluateForces(bool bEnabled)
429         {
430             data().flags_.set(efSelection_EvaluateForces, bEnabled);
431         }
432
433         /*! \brief
434          * Sets the ID for the \p i'th position for use with
435          * SelectionPosition::mappedId().
436          *
437          * \param[in] i  Zero-based index
438          * \param[in] id Identifier to set.
439          *
440          * This method is not part of SelectionPosition because that interface
441          * only provides access to const data by design.
442          *
443          * This method can only be called after compilation, before the
444          * selection has been evaluated for any frame.
445          *
446          * \see SelectionPosition::mappedId()
447          */
448         void setOriginalId(int i, int id) { data().rawPositions_.m.orgid[i] = id; }
449
450         /*! \brief
451          * Prints out one-line description of the selection.
452          *
453          * \param[in] fp      Where to print the information.
454          *
455          * The output contains the name of the selection, the number of atoms
456          * and the number of positions, and indication of whether the selection
457          * is dynamic.
458          */
459         void printInfo(FILE *fp) const;
460         /*! \brief
461          * Prints out extended information about the selection for debugging.
462          *
463          * \param[in] fp      Where to print the information.
464          * \param[in] nmaxind Maximum number of values to print in lists
465          *      (-1 = print all).
466          */
467         void printDebugInfo(FILE *fp, int nmaxind) const;
468
469     private:
470         internal::SelectionData &data()
471         {
472             GMX_ASSERT(sel_ != NULL,
473                        "Attempted to access uninitialized selection");
474             return *sel_;
475         }
476         const internal::SelectionData &data() const
477         {
478             GMX_ASSERT(sel_ != NULL,
479                        "Attempted to access uninitialized selection");
480             return *sel_;
481         }
482
483         /*! \brief
484          * Pointer to internal data for the selection.
485          *
486          * The memory for this object is managed by a SelectionCollection
487          * object, and the \ref Selection class simply provides a public
488          * interface for accessing the data.
489          */
490         internal::SelectionData *sel_;
491
492         /*! \brief
493          * Needed to access the data to adjust flags.
494          */
495         friend class SelectionOptionStorage;
496 };
497
498 /*! \brief
499  * Provides access to information about a single selected position.
500  *
501  * Each position has associated coordinates, and possibly velocities and forces
502  * if they have been requested and are available.  It also has a set of atoms
503  * associated with it; typically the coordinates are the center-of-mass or
504  * center-of-geometry coordinates for that set of atoms.  It is possible that
505  * there are not atoms associated if the selection has been provided as a fixed
506  * position.
507  *
508  * After the selection has been compiled, but not yet evaluated, the contents
509  * of the coordinate, velocity and force vectors are undefined.
510  *
511  * Default copy constructor and assignment operators are used, and work as
512  * intended: the copy references the same position and works identically.
513  *
514  * Methods in this class do not throw.
515  *
516  * \see Selection
517  *
518  * \inpublicapi
519  * \ingroup module_selection
520  */
521 class SelectionPosition
522 {
523     public:
524         /*! \brief
525          * Constructs a wrapper object for given selection position.
526          *
527          * \param[in] sel    Selection from which the position is wrapped.
528          * \param[in] index  Zero-based index of the position to wrap.
529          *
530          * Asserts if \p index is out of range.
531          *
532          * Only for internal use of the library.  To obtain a SelectionPosition
533          * object in other code, use Selection::position().
534          */
535         SelectionPosition(const internal::SelectionData &sel, int index)
536             : sel_(&sel), i_(index)
537         {
538             GMX_ASSERT(index >= 0 && index < sel.posCount(),
539                        "Invalid selection position index");
540         }
541
542         /*! \brief
543          * Returns type of this position.
544          *
545          * Currently always returns the same as Selection::type().
546          */
547         e_index_t type() const { return sel_->rawPositions_.m.type; }
548         //! Returns coordinates for this position.
549         const rvec &x() const
550         {
551             return sel_->rawPositions_.x[i_];
552         }
553         /*! \brief
554          * Returns velocity for this position.
555          *
556          * Must not be called if Selection::hasVelocities() returns false.
557          */
558         const rvec &v() const
559         {
560             GMX_ASSERT(sel_->rawPositions_.v != NULL,
561                        "Velocities accessed, but unavailable");
562             return sel_->rawPositions_.v[i_];
563         }
564         /*! \brief
565          * Returns force for this position.
566          *
567          * Must not be called if Selection::hasForces() returns false.
568          */
569         const rvec &f() const
570         {
571             GMX_ASSERT(sel_->rawPositions_.f != NULL,
572                        "Velocities accessed, but unavailable");
573             return sel_->rawPositions_.f[i_];
574         }
575         /*! \brief
576          * Returns total mass for this position.
577          *
578          * Returns the total mass of atoms that make up this position.
579          * If there are no atoms associated or masses are not available,
580          * returns unity.
581          */
582         real mass() const
583         {
584             return sel_->posMass_[i_];
585         }
586         /*! \brief
587          * Returns total charge for this position.
588          *
589          * Returns the sum of charges of atoms that make up this position.
590          * If there are no atoms associated or charges are not available,
591          * returns zero.
592          */
593         real charge() const
594         {
595             return sel_->posCharge_[i_];
596         }
597         //! Returns the number of atoms that make up this position.
598         int atomCount() const
599         {
600             return sel_->rawPositions_.m.mapb.index[i_ + 1]
601                    - sel_->rawPositions_.m.mapb.index[i_];
602         }
603         //! Return atom indices that make up this position.
604         ConstArrayRef<int> atomIndices() const
605         {
606             if (sel_->rawPositions_.g == NULL)
607             {
608                 return ConstArrayRef<int>();
609             }
610             int first = sel_->rawPositions_.m.mapb.index[i_];
611             return ConstArrayRef<int>(&sel_->rawPositions_.g->index[first],
612                                       atomCount());
613         }
614         /*! \brief
615          * Returns whether this position is selected in the current frame.
616          *
617          * The return value is equivalent to \c refid() == -1.  Returns always
618          * true if SelectionOption::dynamicMask() has not been set.
619          *
620          * \see refId()
621          */
622         bool selected() const
623         {
624             return refId() >= 0;
625         }
626         /*! \brief
627          * Returns reference ID for this position.
628          *
629          * For dynamic selections, this provides means to associate positions
630          * across frames.  After compilation, these IDs are consequently
631          * numbered starting from zero.  For each frame, the ID then reflects
632          * the location of the position in the original array of positions.
633          * If SelectionOption::dynamicMask() has been set for the parent
634          * selection, the IDs for positions not present in the current
635          * selection are set to -1, otherwise they are removed completely.
636          *
637          * Example:
638          * If a dynamic selection consists of at most three positions, after
639          * compilation refId() will return 0, 1, 2 for them, respectively.
640          * If for a particular frame, only the first and the third are present,
641          * refId() will return 0, 2.
642          * If SelectionOption::dynamicMask() has been set, all three positions
643          * can be accessed also for that frame and refId() will return 0, -1,
644          * 2.
645          */
646         int refId() const
647         {
648             return sel_->rawPositions_.m.refid[i_];
649         }
650         /*! \brief
651          * Returns mapped ID for this position.
652          *
653          * Returns ID of the position that corresponds to that set with
654          * Selection::setOriginalId().
655          *
656          * If for an array \c id, \c setOriginalId(i, id[i]) has been called
657          * for each \c i, then it always holds that
658          * \c mappedId()==id[refId()].
659          *
660          * Selection::setOriginalId() has not been called, the default values
661          * are dependent on type():
662          *  - ::INDEX_ATOM: atom indices
663          *  - ::INDEX_RES:  residue numbers
664          *  - ::INDEX_MOL:  molecule numbers
665          *  .
666          * All the default values are zero-based
667          */
668         int mappedId() const
669         {
670             return sel_->rawPositions_.m.mapid[i_];
671         }
672
673     private:
674         const internal::SelectionData  *sel_;
675         int                             i_;
676 };
677
678
679 inline SelectionPosition
680 Selection::position(int i) const
681 {
682     return SelectionPosition(data(), i);
683 }
684
685 } // namespace gmx
686
687 #endif