OpenWalnut  1.5.0dev
WDataSetTimeSeries.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WDATASETTIMESERIES_H
26 #define WDATASETTIMESERIES_H
27 
28 #include <limits>
29 #include <memory>
30 #include <string>
31 #include <utility>
32 #include <vector>
33 
34 #include "../common/WLimits.h"
35 #include "../common/WProperties.h"
36 #include "../common/WTransferable.h"
37 #include "WDataSetScalar.h"
38 
39 
40 //! forward declaration
42 
43 /**
44  * A dataset that stores a time series.
45  *
46  * \note Only works for scalar datasets at the moment!
47  * \note this is only a temporary solution
48  */
50 {
51  //! the test is a friend
52  friend class WDataSetTimeSeriesTest;
53 
54  //! a conveniance typedef
56 
57  //! a time slice
58  typedef std::pair< std::shared_ptr< WDataSetScalar const >, float > TimeSlice;
59 
60 public:
61  /**
62  * Returns a name.
63  *
64  * \return A name.
65  */
66  std::string const getName() const;
67 
68  /**
69  * Returns a description.
70  *
71  * \return A description.
72  */
73  std::string const getDescription() const;
74 
75  /**
76  * Returns a prototype instantiated with the true type of the deriving class.
77  *
78  * \return the prototype.
79  */
80  static std::shared_ptr< WPrototyped > getPrototype();
81 
82  /**
83  * Construct time series from multiple 3D datasets. They do not have to be sorted by time.
84  *
85  * \param datasets A list of datasets to add.
86  * \param times A list of times for the datasets.
87  */
88  WDataSetTimeSeries( std::vector< std::shared_ptr< WDataSetScalar const > > datasets, std::vector< float > times );
89 
90  /**
91  * Destructor.
92  */
93  virtual ~WDataSetTimeSeries();
94 
95  /**
96  * Get the first point of time in the time series.
97  *
98  * \return The first point of time.
99  */
100  inline float getMinTime() const;
101 
102  /**
103  * Get the last point of time in the time series.
104  *
105  * \return The last point of time.
106  */
107  inline float getMaxTime() const;
108 
109  /**
110  * Check if there exists a predefined dataset at the given point in time, i.e.
111  * no interpolation has to be done to access data at that point in time.
112  *
113  * If the time is not in the represented interval [getMinTime(),getMaxTime()],
114  * it will return false.
115  *
116  * \param time The point in time to test.
117  * \return true, iff the time is one of those that were given in the constructor.
118  */
119  bool isTimeSlice( float time ) const;
120 
121  /**
122  * Find the nearest time slice for a given time. If there are two
123  * nearest time slices, the smaller one will be returned.
124  *
125  * \param time The time.
126  * \return The nearest time slice.
127  */
128  float findNearestTimeSlice( float time ) const;
129 
130  /**
131  * Get a pointer to the dataset at a given time or a NULL-pointer, if there
132  * was no dataset given for that point in time.
133  *
134  * \note You need to provide the exact time.
135  *
136  * \param time The time.
137  * \return A pointer to the appropriate dataset or a NULL-pointer.
138  */
139  std::shared_ptr< WDataSetScalar const > getDataSetPtrAtTimeSlice( float time ) const;
140 
141  /**
142  * Calculates a new dataset with values interpolated between the two nearest
143  * time slices. if the time is not in the interval [getMinTime(),getMaxTime()],
144  * a NULL-pointer will be returned.
145  *
146  * \param time The time.
147  * \param name The name of the new dataset.
148  * \return A new interpolated dataset.
149  */
150  std::shared_ptr< WDataSetScalar const > calcDataSetAtTime( float time, std::string const& name ) const;
151 
152  /**
153  * Interpolate a value for a single point in space and time.
154  *
155  * \param pos The spatial location.
156  * \param time The temporal location.
157  * \param[out] success A flag indicating if the position was in the dataset.
158  * \return The value at the given location.
159  */
160  template< typename Data_T >
161  Data_T interpolate( WVector3d const& pos, float time, bool* success ) const;
162 
163  /**
164  * Get the smallest value in all datasets.
165  *
166  * \return The smallest value.
167  */
168  double getMinValue();
169 
170  /**
171  * Get the largest value in all datasets.
172  *
173  * \return The largest value.
174  */
175  double getMaxValue();
176 
177 private:
178  /**
179  * Find the largest time slice position that is smaller than or equal to time,
180  * or return -inf, if there is no such time slice.
181  *
182  * \param time The time.
183  * \return The largest time slice that is smaller than or equal to time or -inf.
184  */
185  float getLBTimeSlice( float time ) const;
186 
187  /**
188  * Find the smallest time slice position that is larger than time, or return
189  * inf, if there is no such time slice.
190  *
191  * \param time The time.
192  * \return The largest time slice that is smaller than time or inf.
193  */
194  float getUBTimeSlice( float time ) const;
195 
196  /**
197  * Interpolate a valueset from two neighboring slices.
198  *
199  * \param lb Time of one slice.
200  * \param ub Time of the other slice.
201  * \param time The actual time of the interpolated slice.
202  * \return A valueset with linearly interpolated values.
203  */
204  template< typename Data_T >
205  std::shared_ptr< WValueSetBase > calcInterpolatedValueSet( float lb, float ub, float time ) const;
206 
207  /**
208  * Standard constructor.
209  */
211 
212  /**
213  * A compare functor for time slices.
214  */
216  {
217  public:
218  /**
219  * Compares the time of two time slices.
220  *
221  * \param t0 The first time slice.
222  * \param t1 The other time slice.
223  * \return true, iff the time of the first slice is smaller than that of the other one.
224  */
225  bool operator() ( TimeSlice const& t0, TimeSlice const& t1 );
226 
227  /**
228  * Compares the time of two time slices.
229  *
230  * \param t0 The first time slice.
231  * \param t1 The other time slice.
232  * \return true, iff the time of the first slice is smaller than that of the other one.
233  */
234  bool operator() ( float const& t0, TimeSlice const& t1 );
235 
236  /**
237  * Compares the time of two time slices.
238  *
239  * \param t0 The first time slice.
240  * \param t1 The other time slice.
241  * \return true, iff the time of the first slice is smaller than that of the other one.
242  */
243  bool operator() ( TimeSlice const& t0, float const& t1 );
244  };
245 
246  //! the datasets that compose the time series
247  std::vector< TimeSlice > m_dataSets;
248 
249  //! The prototype as singleton.
250  static std::shared_ptr< WPrototyped > m_prototype;
251 
252  //! the smallest value
253  double m_minValue;
254 
255  //! the largest value
256  double m_maxValue;
257 };
258 
259 template< typename Data_T >
260 Data_T WDataSetTimeSeries::interpolate( WVector3d const& pos, float time, bool* success ) const
261 {
262  static const float inf = std::numeric_limits< float >::infinity();
263  WAssert( success, "" );
264  WAssert( !wlimits::isNaN( length( pos ) ), "" );
265  WAssert( !wlimits::isNaN( time ), "" );
266  if( time < getMinTime() || time > getMaxTime() )
267  {
268  *success = false;
269  throw WException( std::string( "The provided time is not in the interval of this time series." ) );
270  }
271  float lb = getLBTimeSlice( time );
272  float ub = getUBTimeSlice( time );
273  if( lb == time || ub == time )
274  {
275  std::shared_ptr< WDataSetScalar const > ds = getDataSetPtrAtTimeSlice( time );
276  return static_cast< Data_T >( const_cast< WDataSetScalar& >( *ds ).interpolate( pos, success ) );
277  }
278  WAssert( lb != -inf && ub != inf, "" );
279  std::shared_ptr< WDataSetScalar const > f = getDataSetPtrAtTimeSlice( lb );
280  std::shared_ptr< WDataSetScalar const > g = getDataSetPtrAtTimeSlice( ub );
281  WAssert( f && g, "" );
282  float ml = ( ub - time ) / ( ub - lb );
283  float mu = ( time - lb ) / ( ub - lb );
284  return static_cast< Data_T >( ml * const_cast< WDataSetScalar& >( *f ).interpolate( pos, success )
285  + mu * const_cast< WDataSetScalar& >( *g ).interpolate( pos, success ) );
286 }
287 
288 template< typename Data_T >
289 std::shared_ptr< WValueSetBase > WDataSetTimeSeries::calcInterpolatedValueSet( float lb, float ub, float time ) const
290 {
291  static const float inf = std::numeric_limits< float >::infinity();
292  WAssert( lb != -inf && ub != inf, "" );
293  std::shared_ptr< WDataSetScalar const > f = getDataSetPtrAtTimeSlice( lb );
294  std::shared_ptr< WDataSetScalar const > g = getDataSetPtrAtTimeSlice( ub );
295  WAssert( f && g, "" );
296  std::shared_ptr< WValueSet< Data_T > > vf = std::dynamic_pointer_cast< WValueSet< Data_T > >( f->getValueSet() );
297  std::shared_ptr< WValueSet< Data_T > > vg = std::dynamic_pointer_cast< WValueSet< Data_T > >( g->getValueSet() );
298  WAssert( vf && vg, "" );
299  std::shared_ptr< std::vector< Data_T > > values( new std::vector< Data_T >( vf->size() ) );
300  float ml = ( ub - time ) / ( ub - lb );
301  float mu = ( time - lb ) / ( ub - lb );
302  for( std::size_t k = 0; k < values->size(); ++k )
303  {
304  ( *values )[ k ] = ml * vf->getScalar( k ) + mu * vg->getScalar( k );
305  }
306  return std::shared_ptr< WValueSetBase >( new WValueSet< Data_T >( 0, 1, values, DataType< Data_T >::type ) );
307 }
308 
310 {
311  return m_dataSets.front().second;
312 }
313 
315 {
316  return m_dataSets.back().second;
317 }
318 
319 #endif // WDATASETTIMESERIES_H
This data set type contains scalars as values.
double interpolate(const WPosition &pos, bool *success) const
Interpolate the value for the valueset at the given position.
Unit tests the time series class.
A compare functor for time slices.
bool operator()(TimeSlice const &t0, TimeSlice const &t1)
Compares the time of two time slices.
A dataset that stores a time series.
float getLBTimeSlice(float time) const
Find the largest time slice position that is smaller than or equal to time, or return -inf,...
static std::shared_ptr< WPrototyped > m_prototype
The prototype as singleton.
std::pair< std::shared_ptr< WDataSetScalar const >, float > TimeSlice
a time slice
std::vector< TimeSlice > m_dataSets
the datasets that compose the time series
float getMinTime() const
Get the first point of time in the time series.
float getMaxTime() const
Get the last point of time in the time series.
WDataSetTimeSeries()
Standard constructor.
float findNearestTimeSlice(float time) const
Find the nearest time slice for a given time.
std::shared_ptr< WDataSetScalar const > getDataSetPtrAtTimeSlice(float time) const
Get a pointer to the dataset at a given time or a NULL-pointer, if there was no dataset given for tha...
double getMaxValue()
Get the largest value in all datasets.
virtual ~WDataSetTimeSeries()
Destructor.
double getMinValue()
Get the smallest value in all datasets.
Data_T interpolate(WVector3d const &pos, float time, bool *success) const
Interpolate a value for a single point in space and time.
std::shared_ptr< WValueSetBase > calcInterpolatedValueSet(float lb, float ub, float time) const
Interpolate a valueset from two neighboring slices.
double m_minValue
the smallest value
static std::shared_ptr< WPrototyped > getPrototype()
Returns a prototype instantiated with the true type of the deriving class.
WDataSetTimeSeries This
a conveniance typedef
std::shared_ptr< WDataSetScalar const > calcDataSetAtTime(float time, std::string const &name) const
Calculates a new dataset with values interpolated between the two nearest time slices.
std::string const getName() const
Returns a name.
std::string const getDescription() const
Returns a description.
double m_maxValue
the largest value
bool isTimeSlice(float time) const
Check if there exists a predefined dataset at the given point in time, i.e.
float getUBTimeSlice(float time) const
Find the smallest time slice position that is larger than time, or return inf, if there is no such ti...
Base class for all data set types.
Definition: WDataSet.h:50
Basic exception handler.
Definition: WException.h:39
Base Class for all value set types.
Definition: WValueSet.h:47
bool isNaN(T value)
Determines if a number is considered as NaN (aka Not a Number) or not.
Definition: WLimits.h:96
An object that knows an appropriate dataType flag for the typename T.