00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WDATASETTIMESERIES_H
00026 #define WDATASETTIMESERIES_H
00027
00028 #include <limits>
00029 #include <string>
00030 #include <utility>
00031 #include <vector>
00032
00033 #include <boost/enable_shared_from_this.hpp>
00034 #include <boost/shared_ptr.hpp>
00035
00036 #include "../common/WLimits.h"
00037 #include "../common/WProperties.h"
00038 #include "../common/WTransferable.h"
00039 #include "WDataSetScalar.h"
00040 #include "WExportDataHandler.h"
00041
00042
00043 class WDataSetTimeSeriesTest;
00044
00045
00046
00047
00048
00049
00050
00051 class OWDATAHANDLER_EXPORT WDataSetTimeSeries : public WDataSet
00052 {
00053
00054 friend class WDataSetTimeSeriesTest;
00055
00056
00057 typedef WDataSetTimeSeries This;
00058
00059
00060 typedef std::pair< boost::shared_ptr< WDataSetScalar const >, float > TimeSlice;
00061
00062 public:
00063
00064
00065
00066
00067
00068 std::string const getName() const;
00069
00070
00071
00072
00073
00074
00075 std::string const getDescription() const;
00076
00077
00078
00079
00080
00081
00082 static boost::shared_ptr< WPrototyped > getPrototype();
00083
00084
00085
00086
00087
00088
00089
00090 WDataSetTimeSeries( std::vector< boost::shared_ptr< WDataSetScalar const > > datasets, std::vector< float > times );
00091
00092
00093
00094
00095 virtual ~WDataSetTimeSeries();
00096
00097
00098
00099
00100
00101
00102 inline float getMinTime() const;
00103
00104
00105
00106
00107
00108
00109 inline float getMaxTime() const;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 bool isTimeSlice( float time ) const;
00122
00123
00124
00125
00126
00127
00128
00129
00130 float findNearestTimeSlice( float time ) const;
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 boost::shared_ptr< WDataSetScalar const > getDataSetPtrAtTimeSlice( float time ) const;
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 boost::shared_ptr< WDataSetScalar const > calcDataSetAtTime( float time, std::string const& name ) const;
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 template< typename Data_T >
00163 Data_T interpolate( WVector3d const& pos, float time, bool* success ) const;
00164
00165
00166
00167
00168
00169
00170 double getMinValue();
00171
00172
00173
00174
00175
00176
00177 double getMaxValue();
00178
00179 private:
00180
00181
00182
00183
00184
00185
00186
00187 float getLBTimeSlice( float time ) const;
00188
00189
00190
00191
00192
00193
00194
00195
00196 float getUBTimeSlice( float time ) const;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 template< typename Data_T >
00207 boost::shared_ptr< WValueSetBase > calcInterpolatedValueSet( float lb, float ub, float time ) const;
00208
00209
00210
00211
00212 WDataSetTimeSeries();
00213
00214
00215
00216
00217 class TimeSliceCompare
00218 {
00219 public:
00220
00221
00222
00223
00224
00225
00226
00227 bool operator() ( TimeSlice const& t0, TimeSlice const& t1 );
00228
00229
00230
00231
00232
00233
00234
00235
00236 bool operator() ( float const& t0, TimeSlice const& t1 );
00237
00238
00239
00240
00241
00242
00243
00244
00245 bool operator() ( TimeSlice const& t0, float const& t1 );
00246 };
00247
00248
00249 std::vector< TimeSlice > m_dataSets;
00250
00251
00252 static boost::shared_ptr< WPrototyped > m_prototype;
00253
00254
00255 double m_minValue;
00256
00257
00258 double m_maxValue;
00259 };
00260
00261 template< typename Data_T >
00262 Data_T WDataSetTimeSeries::interpolate( WVector3d const& pos, float time, bool* success ) const
00263 {
00264 static const float inf = std::numeric_limits< float >::infinity();
00265 WAssert( success, "" );
00266 WAssert( !wlimits::isnan( length( pos ) ), "" );
00267 WAssert( !wlimits::isnan( time ), "" );
00268 if( time < getMinTime() || time > getMaxTime() )
00269 {
00270 *success = false;
00271 throw WException( std::string( "The provided time is not in the interval of this time series." ) );
00272 }
00273 float lb = getLBTimeSlice( time );
00274 float ub = getUBTimeSlice( time );
00275 if( lb == time || ub == time )
00276 {
00277 boost::shared_ptr< WDataSetScalar const > ds = getDataSetPtrAtTimeSlice( time );
00278 return static_cast< Data_T >( const_cast< WDataSetScalar& >( *ds ).interpolate( pos, success ) );
00279 }
00280 WAssert( lb != -inf && ub != inf, "" );
00281 boost::shared_ptr< WDataSetScalar const > f = getDataSetPtrAtTimeSlice( lb );
00282 boost::shared_ptr< WDataSetScalar const > g = getDataSetPtrAtTimeSlice( ub );
00283 WAssert( f && g, "" );
00284 float ml = ( ub - time ) / ( ub - lb );
00285 float mu = ( time - lb ) / ( ub - lb );
00286 return static_cast< Data_T >( ml * const_cast< WDataSetScalar& >( *f ).interpolate( pos, success )
00287 + mu * const_cast< WDataSetScalar& >( *g ).interpolate( pos, success ) );
00288 }
00289
00290 template< typename Data_T >
00291 boost::shared_ptr< WValueSetBase > WDataSetTimeSeries::calcInterpolatedValueSet( float lb, float ub, float time ) const
00292 {
00293 static const float inf = std::numeric_limits< float >::infinity();
00294 WAssert( lb != -inf && ub != inf, "" );
00295 boost::shared_ptr< WDataSetScalar const > f = getDataSetPtrAtTimeSlice( lb );
00296 boost::shared_ptr< WDataSetScalar const > g = getDataSetPtrAtTimeSlice( ub );
00297 WAssert( f && g, "" );
00298 boost::shared_ptr< WValueSet< Data_T > > vf = boost::shared_dynamic_cast< WValueSet< Data_T > >( f->getValueSet() );
00299 boost::shared_ptr< WValueSet< Data_T > > vg = boost::shared_dynamic_cast< WValueSet< Data_T > >( g->getValueSet() );
00300 WAssert( vf && vg, "" );
00301 boost::shared_ptr< std::vector< Data_T > > values = boost::shared_ptr< std::vector< Data_T > >( new std::vector< Data_T >( vf->size() ) );
00302 float ml = ( ub - time ) / ( ub - lb );
00303 float mu = ( time - lb ) / ( ub - lb );
00304 for( std::size_t k = 0; k < values->size(); ++k )
00305 {
00306 ( *values )[ k ] = ml * vf->getScalar( k ) + mu * vg->getScalar( k );
00307 }
00308 return boost::shared_ptr< WValueSetBase >( new WValueSet< Data_T >( 0, 1, values, DataType< Data_T >::type ) );
00309 }
00310
00311 float WDataSetTimeSeries::getMinTime() const
00312 {
00313 return m_dataSets.front().second;
00314 }
00315
00316 float WDataSetTimeSeries::getMaxTime() const
00317 {
00318 return m_dataSets.back().second;
00319 }
00320
00321 #endif // WDATASETTIMESERIES_H