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 classes for accessing data frame information.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
37 * \ingroup module_analysisdata
39 #ifndef GMX_ANALYSISDATA_DATAFRAME_H
40 #define GMX_ANALYSISDATA_DATAFRAME_H
44 #include "../legacyheaders/types/simple.h"
46 #include "../utility/arrayref.h"
47 #include "../utility/flags.h"
48 #include "../utility/gmxassert.h"
54 * Value type for representing a single value in analysis data objects.
56 * Default copy constructor and assignment operator are used and work as
59 * Methods in this class do not throw.
61 * Non-const methods are provided for use within the library only; currently
62 * it is not possible to access a non-const AnalysisDataValue through the
66 * \ingroup module_analysisdata
68 class AnalysisDataValue
72 * Constructs an unset value.
74 AnalysisDataValue() : value_(0.0), error_(0.0) {}
76 * Constructs a value object with the given value.
78 * The constructed object is marked as set and present.
80 explicit AnalysisDataValue(real value)
81 : value_(value), error_(0.0)
84 flags_.set(efPresent);
88 * Direct access to the value.
90 * Assigning a value to this does not mark the value as set; setValue()
91 * must be used for this.
93 real &value() { return value_; }
95 * Direct access to the error estimate.
97 * Assigning a value to this does not mark the error estimate as set;
98 * setValue() must be used for this.
100 real &error() { return error_; }
101 //! Returns the value for this value.
102 real value() const { return value_; }
103 //! Returns the error estimate for this value, or zero if not set.
104 real error() const { return error_; }
106 * Returns whether this value has been set.
108 * If this method returns false, the return value of value() and
109 * error() are undefined.
111 bool isSet() const { return flags_.test(efSet); }
113 * Returns whether the error estimate for this value has been set.
115 * If this method returns false, but isSet() returns true, error()
118 bool hasError() const { return flags_.test(efErrorSet); }
120 * Returns whether this value has been marked as present.
122 * If this method returns false, it is up to the source data to define
123 * whether isSet() may return true.
125 bool isPresent() const { return flags_.test(efPresent); }
127 //! Clears and unsets this value.
130 *this = AnalysisDataValue();
133 void setValue(real value, bool bPresent = true)
137 flags_.set(efPresent, bPresent);
139 //! Sets this value and its error estimate.
140 void setValue(real value, real error, bool bPresent = true)
145 flags_.set(efErrorSet);
146 flags_.set(efPresent, bPresent);
148 //! Set only error estimate for this value.
149 void setError(real error)
152 flags_.set(efErrorSet);
156 //! Possible flags for \a flags_.
159 efSet = 1<<0, //!< Value has been set.
160 efErrorSet = 1<<1, //!< Error estimate has been set.
161 efPresent = 1<<2 //!< Value is set as present.
164 //! Value for this value.
166 //! Error estimate for this value, zero if not set.
168 //! Status flags for thise value.
169 FlagsTemplate<Flag> flags_;
172 //! Shorthand for reference to an array of data values.
173 typedef ConstArrayRef<AnalysisDataValue> AnalysisDataValuesRef;
177 * Value type for storing frame-level information for analysis data.
179 * Default copy constructor and assignment operator are used and work as
181 * Typically new objects of this type are only constructed internally by the
182 * library and in classes that are derived from AbstractAnalysisData.
184 * Methods in this class do not throw, but may contain asserts for incorrect
187 * Note that it is not possible to change the contents of an initialized
188 * object, except by assigning a new object to replace it completely.
191 * \ingroup module_analysisdata
193 class AnalysisDataFrameHeader
197 * Constructs an invalid frame header.
199 * Return values of other methods than isValid() are unspecified for
200 * the constructed object.
202 AnalysisDataFrameHeader();
204 * Constructs a frame header from given values.
206 * \param[in] index Index of the frame. Must be >= 0.
207 * \param[in] x x coordinate for the frame.
208 * \param[in] dx Error estimate for x.
210 AnalysisDataFrameHeader(int index, real x, real dx);
213 * Returns whether the frame header corresponds to a valid frame.
215 * If returns false, return values of other methods are not specified.
222 * Returns zero-based index of the frame.
224 * The return value is >= 0 for valid frames.
225 * Should not be called for invalid frames.
229 GMX_ASSERT(isValid(), "Tried to access invalid frame header");
233 * Returns the x coordinate for the frame.
235 * Should not be called for invalid frames.
239 GMX_ASSERT(isValid(), "Tried to access invalid frame header");
243 * Returns error in the x coordinate for the frame (if applicable).
245 * All data do not provide error estimates.
246 * Typically returns zero in those cases.
248 * Should not be called for invalid frames.
252 GMX_ASSERT(isValid(), "Tried to access invalid frame header");
264 * Value type wrapper for non-mutable access to a set of data column values.
266 * Default copy constructor and assignment operator are used and work as
268 * Typically new objects of this type are only constructed internally by the
269 * library and in classes that are derived from AbstractAnalysisData.
271 * Methods in this class do not throw, but may contain asserts for incorrect
274 * The design of the interfaces is such that all objects of this type should be
275 * valid, i.e., header().isValid() should always return true.
277 * Note that it is not possible to change the contents of an initialized
278 * object, except by assigning a new object to replace it completely.
281 * \ingroup module_analysisdata
283 class AnalysisDataPointSetRef
287 * Constructs a point set reference from given values.
289 * \param[in] header Header for the frame.
290 * \param[in] firstColumn Zero-based index of the first column.
292 * \param[in] values Values for each column.
294 * The first element in \p values should correspond to \p firstColumn.
296 AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header,
298 const AnalysisDataValuesRef &values);
300 * Constructs a point set reference from given values.
302 * \param[in] header Header for the frame.
303 * \param[in] values Values for each column.
305 * The first element in \p values should correspond to the first
308 AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header,
309 const std::vector<AnalysisDataValue> &values);
311 * Constructs a point set reference to a subset of columns.
313 * \param[in] points Point set to use as source.
314 * \param[in] firstColumn First column index to include.
315 * \param[in] columnCount Number of columns to include.
317 * Creates a point set that contains \p columnCount columns starting
318 * from \p firstColumn from \p points, or a subset if all requested
319 * columns are not present in \p points. If the requested column range
320 * and the range in \p points do not intersect, the result has
321 * columnCount() == 0.
323 * \p firstColumn is relative to the whole data set, i.e., not relative
324 * to points.firstColumn().
326 * Mainly intended for internal use.
328 AnalysisDataPointSetRef(const AnalysisDataPointSetRef &points,
329 int firstColumn, int columnCount);
332 * Returns the frame header for the frame of this point set.
334 const AnalysisDataFrameHeader &header() const
338 //! \copydoc AnalysisDataFrameHeader::index()
339 int frameIndex() const
341 return header_.index();
343 //! \copydoc AnalysisDataFrameHeader::x()
348 //! \copydoc AnalysisDataFrameHeader::dx()
353 //! Returns zero-based index of the first column included in this set.
354 int firstColumn() const
358 //! Returns the number of columns included in this set.
359 int columnCount() const
361 return values().size();
363 //! Returns zero-based index of the last column included in this set (inclusive).
364 int lastColumn() const
366 return firstColumn_ + columnCount() - 1;
369 * Returns reference container for all values.
371 * First value in the returned container corresponds to firstColumn().
373 const AnalysisDataValuesRef &values() const
378 * Returns data value for a column in this set.
380 * \param[in] i Zero-based column index relative to firstColumn().
381 * Should be >= 0 and < columnCount().
385 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
386 return values()[i].value();
389 * Returns error estimate for a column in this set if applicable.
391 * \param[in] i Zero-based column index relative to firstColumn().
392 * Should be >= 0 and < columnCount().
394 * Currently, this method returns zero if the source data does not
399 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
400 return values()[i].error();
403 * Returns whether a column is present in this set.
405 * \param[in] i Zero-based column index relative to firstColumn().
406 * Should be >= 0 and < columnCount().
408 * If present(i) returns false, it is depends on the source data
409 * whether y(i) and/or dy(i) are defined.
411 bool present(int i) const
413 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
414 return values()[i].isPresent();
417 * Returns true if all points in this point set are present.
419 * That is, if present() would return true for all points.
421 bool allPresent() const;
424 AnalysisDataFrameHeader header_;
426 AnalysisDataValuesRef values_;
431 * Value type wrapper for non-mutable access to a data frame.
433 * Default copy constructor and assignment operator are used and work as
435 * Typically new objects of this type are only constructed internally by the
436 * library and in classes that are derived from AbstractAnalysisData.
438 * Methods in this class do not throw, but may contain asserts for incorrect
441 * Note that it is not possible to change the contents of an initialized
442 * object, except by assigning a new object to replace it completely.
445 * Support for multipoint data.
448 * \ingroup module_analysisdata
450 class AnalysisDataFrameRef
454 * Constructs an invalid frame reference.
456 * Return values of other methods than isValid() are unspecified for
457 * the constructed object.
459 AnalysisDataFrameRef();
461 * Constructs a frame reference from given values.
463 * \param[in] header Header for the frame.
464 * \param[in] values Values for each column.
466 AnalysisDataFrameRef(const AnalysisDataFrameHeader &header,
467 const AnalysisDataValuesRef &values);
469 * Constructs a frame reference from given values.
471 * \param[in] header Header for the frame.
472 * \param[in] values Values for each column.
474 AnalysisDataFrameRef(const AnalysisDataFrameHeader &header,
475 const std::vector<AnalysisDataValue> &values);
477 * Constructs a frame reference to a subset of columns.
479 * \param[in] frame Frame to use as source.
480 * \param[in] firstColumn First column index to include.
481 * \param[in] columnCount Number of columns to include.
483 * Creates a frame reference that contains \p columnCount columns
484 * starting from \p firstColumn from \p frame, or a subset if all
485 * requested columns are not present in \p frame.
487 * Mainly intended for internal use.
489 AnalysisDataFrameRef(const AnalysisDataFrameRef &frame,
490 int firstColumn, int columnCount);
493 * Returns whether the object refers to a valid frame.
495 * If returns false, return values of other methods are not specified.
499 return header().isValid();
501 //! Returns the header for this frame.
502 const AnalysisDataFrameHeader &header() const
506 //! \copydoc AnalysisDataFrameHeader::index()
507 int frameIndex() const
509 return header().index();
511 //! \copydoc AnalysisDataFrameHeader::x()
516 //! \copydoc AnalysisDataFrameHeader::dx()
519 return header().dx();
522 * Returns point set reference to the column values of this frame.
524 * Should not be called for invalid frames.
526 AnalysisDataPointSetRef points() const
528 GMX_ASSERT(isValid(), "Invalid data frame accessed");
529 return AnalysisDataPointSetRef(header_, 0, values_);
532 * Returns number of columns in this frame.
534 * Returns zero for an invalid frame.
536 int columnCount() const
538 return values_.size();
541 * Returns reference container for all column values.
543 const AnalysisDataValuesRef &values() const
548 * Convenience method for accessing a column value.
550 * \copydetails AnalysisDataPointSetRef::y()
554 GMX_ASSERT(isValid(), "Invalid data frame accessed");
555 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
556 return values_[i].value();
559 * Convenience method for accessing error for a column value.
561 * \copydetails AnalysisDataPointSetRef::dy()
565 GMX_ASSERT(isValid(), "Invalid data frame accessed");
566 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
567 return values_[i].error();
570 * Convenience method for accessing present status for a column.
572 * \copydetails AnalysisDataPointSetRef::present()
574 bool present(int i) const
576 GMX_ASSERT(isValid(), "Invalid data frame accessed");
577 GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access");
578 return values_[i].isPresent();
581 * Returns true if all points in this frame are present.
583 bool allPresent() const;
586 AnalysisDataFrameHeader header_;
587 AnalysisDataValuesRef values_;