OpenWalnut  1.4.0
WDataSetTimeSeries_test.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_TEST_H
26 #define WDATASETTIMESERIES_TEST_H
27 
28 #include <vector>
29 #include <limits>
30 #include <algorithm>
31 #include <string>
32 
33 #ifndef Q_MOC_RUN
34 #include <boost/shared_ptr.hpp>
35 #endif
36 #include <cxxtest/TestSuite.h>
37 
38 #include "../../common/WLimits.h"
39 #include "../../common/WLogger.h"
40 
41 #include "../WDataSetTimeSeries.h"
42 
43 
44 /**
45  * Unit tests the time series class.
46  */
47 class WDataSetTimeSeriesTest : public CxxTest::TestSuite
48 {
49  //! a typedef
50  typedef std::vector< boost::shared_ptr< WDataSetScalar const > > DataSetPtrVector;
51 
52  //! a typdef
53  typedef std::vector< float > TimesVector;
54 
55 public:
56  /**
57  * The input should be sorted correctly and all data should be stored correctly.
58  * Also there should be only one grid for all datasets.
59  */
61  {
62  // test with 3 time slices
63  {
64  double data[] = { 1.0, 2.0, 3.0 };
65  DataSetPtrVector d;
66  TimesVector t;
67 
68  // test what happens when the input is empty
69  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
70 
71  // test what happens when the vector sizes don't match
72  createData( data, 3, d, t );
73  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
74  t.push_back( 4.0f );
75  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
76 
77  // test what happens when there is an invalid time value
78  t.resize( 3 );
79  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
80  t[ 2 ] = -0.0 / 0.0;
81  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
82 
83  // test what happens when there are equal time values
84  t[ 2 ] = t[ 1 ];
85  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
86 
87  // test what happens if the grids don't match
88  t[ 2 ] = 2.0;
89  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
90 
91  t.push_back( 4.0f );
92 
93  WMatrix< double > mat( 4, 4 );
94  boost::shared_ptr< std::vector< double > > v( new std::vector< double >( 27, 4 ) );
95  mat.makeIdentity();
96  mat( 0, 0 ) = 1.0;
97  mat( 1, 1 ) = 0.5;
98  mat( 2, 2 ) = 2.0;
99 
100  WGridTransformOrtho transform( mat );
101  boost::shared_ptr< WGridRegular3D > g( new WGridRegular3D( 3, 3, 3, transform ) );
102 
103  boost::shared_ptr< WValueSet< double > > vs( new WValueSet< double >( 0, 1, v, W_DT_DOUBLE ) );
104  d.push_back( boost::shared_ptr< WDataSetScalar const >( new WDataSetScalar( vs, g ) ) );
105  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
106 
107  // test what happens if the valuesets data types don't match
108  d.resize( 3 );
109  t.resize( 3 );
110  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
111 
112  t.push_back( 4.0f );
113  boost::shared_ptr< std::vector< float > > v2( new std::vector< float >( 27, 4 ) );
114  boost::shared_ptr< WValueSet< float > > vs2( new WValueSet< float >( 0, 1, v2, W_DT_FLOAT ) );
115  d.push_back( boost::shared_ptr< WDataSetScalar const >( new WDataSetScalar( vs2, d.front()->getGrid() ) ) );
116  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
117  }
118 
119  // test with 2 time slices
120  {
121  double data[] = { 1.0, 2.0 };
122  DataSetPtrVector d;
123  TimesVector t;
124 
125  // test what happens when the input is empty
126  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
127 
128  // test what happens when the vector sizes don't match
129  createData( data, 2, d, t );
130  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
131  t.push_back( 4.0f );
132  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
133 
134  // test what happens when there is an invalid time value
135  t.resize( 2 );
136  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
137  t[ 1 ] = 0.0f / 0.0f;
138  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
139 
140  // test what happens when there are equal time values
141  t[ 1 ] = t[ 0 ];
142  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
143 
144  // test what happens if the grids don't match
145  t[ 1 ] = 2.0;
146  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
147 
148  t.push_back( 4.0f );
149 
150  WMatrix< double > mat( 4, 4 );
151  boost::shared_ptr< std::vector< double > > v( new std::vector< double >( 27, 4 ) );
152  mat.makeIdentity();
153  mat( 0, 0 ) = 1.0;
154  mat( 1, 1 ) = 0.5;
155  mat( 2, 2 ) = 2.0;
156 
157  WGridTransformOrtho transform( mat );
158  boost::shared_ptr< WGridRegular3D > g( new WGridRegular3D( 3, 3, 3, transform ) );
159 
160  boost::shared_ptr< WValueSet< double > > vs( new WValueSet< double >( 0, 1, v, W_DT_DOUBLE ) );
161  d.push_back( boost::shared_ptr< WDataSetScalar const >( new WDataSetScalar( vs, g ) ) );
162  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
163 
164  // test what happens if the valuesets data types don't match
165  d.resize( 2 );
166  t.resize( 2 );
167  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
168 
169  t.push_back( 4.0f );
170  boost::shared_ptr< std::vector< float > > v2( new std::vector< float >( 27, 4 ) );
171  boost::shared_ptr< WValueSet< float > > vs2( new WValueSet< float >( 0, 1, v2, W_DT_FLOAT ) );
172  d.push_back( boost::shared_ptr< WDataSetScalar const >( new WDataSetScalar( vs2, d.front()->getGrid() ) ) );
173  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
174  }
175 
176  // test with 1 time slice
177  {
178  double data[] = { 1.0 };
179  DataSetPtrVector d;
180  TimesVector t;
181 
182  // test what happens when the input is empty
183  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
184 
185  // test what happens when the vector sizes don't match
186  createData( data, 1, d, t );
187  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
188  t.push_back( 4.0f );
189  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
190 
191  // test what happens when there is an invalid time value
192  t.resize( 1 );
193  TS_ASSERT_THROWS_NOTHING( WDataSetTimeSeries( d, t ) );
194  t[ 0 ] = -0.0f / 0.0f;
195  TS_ASSERT_THROWS( WDataSetTimeSeries( d, t ), WException );
196  }
197 
198  // datasets should be sorted by time
199  {
200  double data[] = { 1.0, 2.0, 3.0 };
201  DataSetPtrVector d;
202  TimesVector t;
203 
204  createData( data, 3, d, t );
205  std::swap( t[ 1 ], t[ 2 ] );
206  WDataSetTimeSeries ts( d, t );
207 
208  TS_ASSERT_EQUALS( d[ 0 ], ts.m_dataSets[ 0 ].first );
209  TS_ASSERT_EQUALS( d[ 2 ], ts.m_dataSets[ 1 ].first );
210  TS_ASSERT_EQUALS( d[ 1 ], ts.m_dataSets[ 2 ].first );
211  }
212  }
213 
214  /**
215  * The correct minimum and maximum times should be returned.
216  */
218  {
219  double data[] = { 1.0, 2.0, 3.0 };
220  DataSetPtrVector d;
221  TimesVector t;
222 
223  createData( data, 3, d, t );
224  {
225  WDataSetTimeSeries ts( d, t );
226 
227  TS_ASSERT_EQUALS( ts.getMinTime(), 0.0f );
228  TS_ASSERT_EQUALS( ts.getMaxTime(), 2.0f );
229  }
230 
231  createData( data, 3, d, t );
232  t[ 0 ] = 1.34f;
233  t[ 2 ] = 1.43f;
234  {
235  WDataSetTimeSeries ts( d, t );
236 
237  TS_ASSERT_EQUALS( ts.getMinTime(), 1.0f );
238  TS_ASSERT_EQUALS( ts.getMaxTime(), 1.43f );
239  }
240  }
241 
242  /**
243  * Times that were provided on construction should be found. Times outside of the
244  * interval [getMinTime(),getMaxTime()] should be rejected.
245  */
247  {
248  double data[] = { 1.0, 2.0, 3.0 };
249  DataSetPtrVector d;
250  TimesVector t;
251 
252  createData( data, 3, d, t );
253  {
254  WDataSetTimeSeries ts( d, t );
255  TS_ASSERT( ts.isTimeSlice( 0.0f ) );
256  TS_ASSERT( ts.isTimeSlice( 1.0f ) );
257  TS_ASSERT( ts.isTimeSlice( 2.0f ) );
258  TS_ASSERT( !ts.isTimeSlice( 5.0f ) );
259  TS_ASSERT( !ts.isTimeSlice( 0.0f / 0.0f ) );
260  TS_ASSERT( !ts.isTimeSlice( std::numeric_limits< float >::infinity() ) );
261  TS_ASSERT( !ts.isTimeSlice( 1.00001f ) );
262  TS_ASSERT( !ts.isTimeSlice( 2.345f ) );
263  TS_ASSERT( !ts.isTimeSlice( 0.5234f ) );
264  TS_ASSERT( !ts.isTimeSlice( -wlimits::FLT_EPS ) );
265  }
266 
267  createData( data, 3, d, t );
268  t[ 0 ] = 1.34f;
269  t[ 2 ] = 1.43f;
270  {
271  WDataSetTimeSeries ts( d, t );
272  TS_ASSERT( ts.isTimeSlice( 1.34f ) );
273  TS_ASSERT( ts.isTimeSlice( 1.43f ) );
274  TS_ASSERT( ts.isTimeSlice( 1.0f ) );
275  TS_ASSERT( !ts.isTimeSlice( 5.0f ) );
276  TS_ASSERT( !ts.isTimeSlice( 0.0f / 0.0f ) );
277  TS_ASSERT( !ts.isTimeSlice( std::numeric_limits< float >::infinity() ) );
278  TS_ASSERT( !ts.isTimeSlice( 1.00001f ) );
279  TS_ASSERT( !ts.isTimeSlice( 2.345f ) );
280  TS_ASSERT( !ts.isTimeSlice( 0.5234f ) );
281  TS_ASSERT( !ts.isTimeSlice( -wlimits::FLT_EPS ) );
282  }
283  }
284 
285  /**
286  * The nearest time slices should be calculated correctly. Boundary conditions must be
287  * handled correctly.
288  */
290  {
291  double data[] = { 1.0, 2.0, 3.0 };
292  DataSetPtrVector d;
293  TimesVector t;
294 
295  createData( data, 3, d, t );
296  WDataSetTimeSeries ts( d, t );
297 
298  float f = ts.findNearestTimeSlice( -std::numeric_limits< float >::infinity() );
299  TS_ASSERT_EQUALS( 0.0, f );
300  f = ts.findNearestTimeSlice( -3346.0 );
301  TS_ASSERT_EQUALS( 0.0, f );
302  f = ts.findNearestTimeSlice( -1.0 );
303  TS_ASSERT_EQUALS( 0.0, f );
304  f = ts.findNearestTimeSlice( -0.01 );
305  TS_ASSERT_EQUALS( 0.0, f );
307  TS_ASSERT_EQUALS( 0.0, f );
308  f = ts.findNearestTimeSlice( 0.0 );
309  TS_ASSERT_EQUALS( 0.0, f );
311  TS_ASSERT_EQUALS( 0.0, f );
312  f = ts.findNearestTimeSlice( 0.3 );
313  TS_ASSERT_EQUALS( 0.0, f );
314  f = ts.findNearestTimeSlice( 0.5 );
315  TS_ASSERT_EQUALS( 0.0, f );
316  f = ts.findNearestTimeSlice( 0.5 + wlimits::FLT_EPS );
317  TS_ASSERT_EQUALS( 1.0, f );
318  f = ts.findNearestTimeSlice( 1.0 - wlimits::FLT_EPS );
319  TS_ASSERT_EQUALS( 1.0, f );
320  f = ts.findNearestTimeSlice( 1.5 - wlimits::FLT_EPS );
321  TS_ASSERT_EQUALS( 1.0, f );
322  f = ts.findNearestTimeSlice( 1.5 );
323  TS_ASSERT_EQUALS( 1.0, f );
324  f = ts.findNearestTimeSlice( 2.0 - wlimits::FLT_EPS );
325  TS_ASSERT_EQUALS( 2.0f, f );
326  f = ts.findNearestTimeSlice( 2.0 );
327  TS_ASSERT_EQUALS( 2.0f, f );
328  f = ts.findNearestTimeSlice( std::numeric_limits< float >::infinity() );
329  TS_ASSERT_EQUALS( 2.0f, f );
330  TS_ASSERT_THROWS( ts.findNearestTimeSlice( 0.0 / 0.0 ), WException );
331  }
332 
333  /**
334  * Provided datasets should be returned for provided time slices.
335  */
337  {
338  double data[] = { 1.0, 2.0, 3.0 };
339  DataSetPtrVector d;
340  TimesVector t;
341 
342  createData( data, 3, d, t );
343  WDataSetTimeSeries ts( d, t );
344 
345  boost::shared_ptr< WDataSetScalar const > null;
346 
347  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 0.0f / 0.0f ), null );
348  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( -std::numeric_limits< float >::infinity() ), null );
349  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 0.0f ), d[ 0 ] );
350  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( wlimits::FLT_EPS ), null );
351  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 0.999f ), null );
352  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 1.0f ), d[ 1 ] );
353  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 2.0f ), d[ 2 ] );
354  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( 344643.0f ), null );
355  TS_ASSERT_EQUALS( ts.getDataSetPtrAtTimeSlice( std::numeric_limits< float >::infinity() ), null );
356  }
357 
358  /**
359  * Interpolated datasets need to be correct.
360  */
362  {
363  double data[] = { 1.0, 2.0, 3.0 };
364  DataSetPtrVector d;
365  TimesVector t;
366 
367  createData( data, 3, d, t );
368  WDataSetTimeSeries ts( d, t );
369 
370  boost::shared_ptr< WDataSetScalar const > null;
371  boost::shared_ptr< WDataSetScalar const > ds;
372  std::string name( "a name" );
373 
374  ds = ts.calcDataSetAtTime( -std::numeric_limits< float >::infinity(), name );
375  TS_ASSERT_EQUALS( ds, null );
376 
377  ds = ts.calcDataSetAtTime( -wlimits::FLT_EPS, name );
378  TS_ASSERT_EQUALS( ds, null );
379 
380  ds = ts.calcDataSetAtTime( std::numeric_limits< float >::infinity(), name );
381  TS_ASSERT_EQUALS( ds, null );
382 
383  ds = ts.calcDataSetAtTime( 2.0f + 2.0f * wlimits::FLT_EPS, name );
384  TS_ASSERT_EQUALS( ds, null );
385 
386  ds = ts.calcDataSetAtTime( 0.0f, name );
387  TS_ASSERT_EQUALS( ds, d[ 0 ] );
388 
389  ds = ts.calcDataSetAtTime( 1.0f, name );
390  TS_ASSERT_EQUALS( ds, d[ 1 ] );
391 
392  ds = ts.calcDataSetAtTime( 2.0f, name );
393  TS_ASSERT_EQUALS( ds, d[ 2 ] );
394 
395  {
396  std::vector< double > v( 27, 1.35 );
397  ds = ts.calcDataSetAtTime( 0.35f, name );
398  TS_ASSERT( ds );
399  boost::shared_ptr< WValueSet< double > > vs = boost::dynamic_pointer_cast< WValueSet< double > >( ds->getValueSet() );
400  TS_ASSERT( vs );
401  for( std::size_t k = 0; k < v.size(); ++k )
402  {
403  TS_ASSERT_DELTA( v[ k ], vs->rawData()[ k ], 1.0f * wlimits::FLT_EPS );
404  }
405  }
406  {
407  std::vector< double > v( 27, 1.99 );
408  ds = ts.calcDataSetAtTime( 0.99f, name );
409  TS_ASSERT( ds );
410  boost::shared_ptr< WValueSet< double > > vs = boost::dynamic_pointer_cast< WValueSet< double > >( ds->getValueSet() );
411  TS_ASSERT( vs );
412  for( std::size_t k = 0; k < v.size(); ++k )
413  {
414  TS_ASSERT_DELTA( v[ k ], vs->rawData()[ k ], 1.0f * wlimits::FLT_EPS );
415  }
416  }
417  {
418  std::vector< double > v( 27, 2.598 );
419  ds = ts.calcDataSetAtTime( 1.598f, name );
420  TS_ASSERT( ds );
421  boost::shared_ptr< WValueSet< double > > vs = boost::dynamic_pointer_cast< WValueSet< double > >( ds->getValueSet() );
422  TS_ASSERT( vs );
423  for( std::size_t k = 0; k < v.size(); ++k )
424  {
425  TS_ASSERT_DELTA( v[ k ], vs->rawData()[ k ], 1.0f * wlimits::FLT_EPS );
426  }
427  }
428  }
429 
430  /**
431  * Interpolation of values should be correct.
432  */
434  {
435  double data[] = { 1.0, 2.0, 3.0 };
436  DataSetPtrVector d;
437  TimesVector t;
438 
439  createData( data, 3, d, t );
440  WDataSetTimeSeries ts( d, t );
441 
442  float inf = std::numeric_limits< float >::infinity();
443  bool success;
444  double h;
445 
446  // test invalid times
447  WVector3d pos( 1.0, 0.5, 1.0 );
448 
449  TS_ASSERT_THROWS( h = ts.interpolate< double >( pos, -inf, &success ), WException );
450  TS_ASSERT( !success );
451  TS_ASSERT_THROWS( h = ts.interpolate< double >( pos, -3.0f, &success ), WException );
452  TS_ASSERT( !success );
453  TS_ASSERT_THROWS( h = ts.interpolate< double >( pos, -wlimits::FLT_EPS, &success ), WException );
454  TS_ASSERT( !success );
455  TS_ASSERT_THROWS( h = ts.interpolate< double >( pos, 2.0f + 2.0f * wlimits::FLT_EPS, &success ), WException );
456  TS_ASSERT( !success );
457  TS_ASSERT_THROWS( h = ts.interpolate< double >( pos, inf, &success ), WException );
458  TS_ASSERT( !success );
459 
460  // test invalid position
461  float time = 0.99f;
462  pos[ 0 ] = -wlimits::FLT_EPS;
463  h = ts.interpolate< double >( pos, time, &success );
464  TS_ASSERT( !success );
465 
466  // now test some valid cases
467  pos[ 0 ] = 1.0f;
468  h = ts.interpolate< double >( pos, time, &success );
469  TS_ASSERT( success );
470  TS_ASSERT_DELTA( h, 1.99, wlimits::FLT_EPS );
471  }
472 
473  /**
474  * Test the lower bound time helper routine.
475  * It should return the largest time slice that is smaller than or equal
476  * to the input time, or -inf if there is no such time slice.
477  */
478  void testLBTime()
479  {
480  double data[] = { 1.0, 2.0, 3.0 };
481  DataSetPtrVector d;
482  TimesVector t;
483 
484  createData( data, 3, d, t );
485  WDataSetTimeSeries ts( d, t );
486 
487  float neginf = -std::numeric_limits< float >::infinity();
488 
489  // not using TS_ASSERT_EQUALS here because of a bug
490  // passing inf as a parameter leads to an endless loop
491  TS_ASSERT( ts.getLBTimeSlice( neginf ) == neginf );
492  TS_ASSERT( ts.getLBTimeSlice( -0.01f ) == neginf );
493  TS_ASSERT( ts.getLBTimeSlice( 0.0f ) == 0.0f );
494  TS_ASSERT( ts.getLBTimeSlice( -wlimits::FLT_EPS ) == neginf );
495  TS_ASSERT( ts.getLBTimeSlice( wlimits::FLT_EPS ) == 0.0f );
496  TS_ASSERT( ts.getLBTimeSlice( 1.0f ) == 1.0f );
497  TS_ASSERT( ts.getLBTimeSlice( 1.2f ) == 1.0f );
498  TS_ASSERT( ts.getLBTimeSlice( 2.0f - wlimits::FLT_EPS ) == 1.0f );
499  TS_ASSERT( ts.getLBTimeSlice( 2.0f ) == 2.0f );
500  TS_ASSERT( ts.getLBTimeSlice( -neginf ) == 2.0f );
501 
502  // note that there is no test for nan, as these routines are private
503  // it is the callers responsibility to check for nan
504  }
505 
506  /**
507  * Test the upper bound time helper routine.
508  * It should return the smallest time slice that is larger than the input
509  * time, or inf if there is no such time slice.
510  */
511  void testUBTime()
512  {
513  double data[] = { 1.0, 2.0, 3.0 };
514  DataSetPtrVector d;
515  TimesVector t;
516 
517  createData( data, 3, d, t );
518  WDataSetTimeSeries ts( d, t );
519 
520  float inf = std::numeric_limits< float >::infinity();
521 
522  // not using TS_ASSERT_EQUALS here because of a bug
523  // passing inf as a parameter leads to an endless loop
524  TS_ASSERT( ts.getUBTimeSlice( -inf ) == 0.0f );
525  TS_ASSERT( ts.getUBTimeSlice( -0.01f ) == 0.0f );
526  TS_ASSERT( ts.getUBTimeSlice( 0.0f ) == 1.0f );
527  TS_ASSERT( ts.getUBTimeSlice( -wlimits::FLT_EPS ) == 0.0f );
528  TS_ASSERT( ts.getUBTimeSlice( wlimits::FLT_EPS ) == 1.0f );
529  TS_ASSERT( ts.getUBTimeSlice( 1.0f ) == 2.0f );
530  TS_ASSERT( ts.getUBTimeSlice( 1.2f ) == 2.0f );
531  TS_ASSERT( ts.getUBTimeSlice( 2.0f - wlimits::FLT_EPS ) == 2.0f );
532  TS_ASSERT( ts.getUBTimeSlice( 2.0f ) == inf );
533  TS_ASSERT( ts.getUBTimeSlice( inf ) == inf );
534 
535  // note that there is no test for nan, as these routines are private
536  // it is the callers responsibility to check for nan
537  }
538 
539 private:
540  /**
541  * A helper function that creates some input data.
542  *
543  * \param data An array of data values, one for each time slice.
544  * \param number The number of time slices.
545  * \param dsets The output datasets.
546  * \param times Some times for the output datasets.
547  */
548  void createData( double* data, int number, DataSetPtrVector& dsets, TimesVector& times ) // NOLINT
549  {
550  dsets.clear();
551  times.clear();
552 
553  WMatrix< double > mat( 4, 4 );
554  mat.makeIdentity();
555  mat( 0, 0 ) = 1.0;
556  mat( 1, 1 ) = 0.5;
557  mat( 2, 2 ) = 2.0;
558 
559  WGridTransformOrtho transform( mat );
560  boost::shared_ptr< WGridRegular3D > g( new WGridRegular3D( 3, 3, 3, transform ) );
561 
562  for( int i = 0; i < number; ++i )
563  {
564  boost::shared_ptr< std::vector< double > > v( new std::vector< double >( 27, data[i] ) );
565  boost::shared_ptr< WValueSet< double > > vs( new WValueSet< double >( 0, 1, v, W_DT_DOUBLE ) );
566  dsets.push_back( boost::shared_ptr< WDataSetScalar const >( new WDataSetScalar( vs, g ) ) );
567  times.push_back( static_cast< float >( i ) );
568  }
569  }
570 
571  /**
572  * Setup logger and other stuff for each test.
573  */
574  void setUp()
575  {
577  }
578 };
579 
580 #endif // WDATASETTIMESERIES_TEST_H
A grid that has parallelepiped cells which all have the same proportion.
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352
A dataset that stores a time series.
void testGetDataSetPtrAtTimeSlice()
Provided datasets should be returned for provided time slices.
void createData(double *data, int number, DataSetPtrVector &dsets, TimesVector &times)
A helper function that creates some input data.
void testUBTime()
Test the upper bound time helper routine.
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...
void testLBTime()
Test the lower bound time helper routine.
void setUp()
Setup logger and other stuff for each test.
void testInterpolate()
Interpolation of values should be correct.
void testInterpolatedDataSets()
Interpolated datasets need to be correct.
float getLBTimeSlice(float time) const
Find the largest time slice position that is smaller than or equal to time, or return -inf...
static void startup(std::ostream &output=std::cout, LogLevel level=LL_DEBUG)
Create the first and only instance of the logger as it is a singleton.
Definition: WLogger.cpp:41
boost::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...
const float FLT_EPS
Smallest float such: 1.0 + FLT_EPS == 1.0 is still true.
Definition: WLimits.cpp:37
void testGetNearestTimeSlice()
The nearest time slices should be calculated correctly.
float findNearestTimeSlice(float time) const
Find the nearest time slice for a given time.
Unit tests the time series class.
void testIsTimeSlice()
Times that were provided on construction should be found.
std::vector< float > TimesVector
a typdef
void testConstruction()
The input should be sorted correctly and all data should be stored correctly.
Base Class for all value set types.
Definition: WValueSet.h:48
bool isTimeSlice(float time) const
Check if there exists a predefined dataset at the given point in time, i.e.
std::vector< boost::shared_ptr< WDataSetScalar const > > DataSetPtrVector
a typedef
std::vector< TimeSlice > m_dataSets
the datasets that compose the time series
This data set type contains scalars as values.
float getMaxTime() const
Get the last point of time in the time series.
Data_T interpolate(WVector3d const &pos, float time, bool *success) const
Interpolate a value for a single point in space and time.
Basic exception handler.
Definition: WException.h:38
boost::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.
void testTimeMinMax()
The correct minimum and maximum times should be returned.
Implements an orthogonal grid transformation.
float getMinTime() const
Get the first point of time in the time series.