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 #include <algorithm>
00026 #include <limits>
00027 #include <string>
00028 #include <vector>
00029
00030 #include "../common/WAssert.h"
00031 #include "../common/WLimits.h"
00032 #include "WDataSetTimeSeries.h"
00033
00034
00035 boost::shared_ptr< WPrototyped > WDataSetTimeSeries::m_prototype = boost::shared_ptr< WPrototyped >();
00036
00037 WDataSetTimeSeries::WDataSetTimeSeries( std::vector< boost::shared_ptr< WDataSetScalar const > > datasets,
00038 std::vector< float > times )
00039 : m_dataSets()
00040 {
00041 WAssert( !datasets.empty(), "" );
00042 WAssert( datasets.size() == times.size(), "" );
00043 std::vector< boost::shared_ptr< WDataSetScalar const > >::iterator dit;
00044 std::vector< float >::iterator tit;
00045 boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( datasets.front()->getGrid() );
00046 WAssert( g, "" );
00047 dataType d = datasets.front()->getValueSet()->getDataType();
00048 m_minValue = datasets.front()->getMin();
00049 m_maxValue = datasets.front()->getMax();
00050 for( dit = datasets.begin(), tit = times.begin(); dit != datasets.end() && tit != times.end(); ++dit, ++tit )
00051 {
00052 WAssert( *dit, "" );
00053 WAssert( g == boost::shared_dynamic_cast< WGridRegular3D >( ( *dit )->getGrid() ), "" );
00054 WAssert( !wlimits::isnan( *tit ), "" );
00055 WAssert( d == ( *dit )->getValueSet()->getDataType(), "" );
00056 WAssert( ( *dit )->getValueSet()->dimension() == 1, "" );
00057 WAssert( ( *dit )->getValueSet()->order() == 0, "" );
00058 m_dataSets.push_back( TimeSlice( *dit, *tit ) );
00059 if( m_minValue > ( *dit )->getMin() )
00060 {
00061 m_minValue = ( *dit )->getMin();
00062 }
00063 if( m_maxValue < ( *dit )->getMax() )
00064 {
00065 m_maxValue = ( *dit )->getMax();
00066 }
00067 }
00068 std::sort( m_dataSets.begin(), m_dataSets.end(), TimeSliceCompare() );
00069 for( std::size_t k = 1; k < m_dataSets.size(); ++k )
00070 {
00071 if( m_dataSets[ k ].second == m_dataSets[ k - 1 ].second )
00072 {
00073 throw WException( std::string( "There are multiple time slices at the same point in time!" ) );
00074 }
00075 }
00076 }
00077
00078 WDataSetTimeSeries::~WDataSetTimeSeries()
00079 {
00080 }
00081
00082 std::string const WDataSetTimeSeries::getName() const
00083 {
00084 return std::string( "WDataSetTimeSeries" );
00085 }
00086
00087 std::string const WDataSetTimeSeries::getDescription() const
00088 {
00089 return std::string( "A time series." );
00090 }
00091
00092 boost::shared_ptr< WPrototyped > WDataSetTimeSeries::getPrototype()
00093 {
00094 if( !m_prototype )
00095 {
00096 m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetTimeSeries() );
00097 }
00098
00099 return m_prototype;
00100 }
00101
00102 bool WDataSetTimeSeries::isTimeSlice( float time ) const
00103 {
00104 std::vector< TimeSlice >::const_iterator f = std::lower_bound( m_dataSets.begin(), m_dataSets.end(), time, TimeSliceCompare() );
00105 return f != m_dataSets.end() && f->second == time;
00106 }
00107
00108 float WDataSetTimeSeries::findNearestTimeSlice( float time ) const
00109 {
00110 WAssert( !wlimits::isnan( time ), "" );
00111 if( time > getMaxTime() )
00112 {
00113 return getMaxTime();
00114 }
00115 float lb = getLBTimeSlice( time );
00116 float ub = getUBTimeSlice( time );
00117 return time - lb <= ub - time ? lb : ub;
00118 }
00119
00120 boost::shared_ptr< WDataSetScalar const > WDataSetTimeSeries::getDataSetPtrAtTimeSlice( float time ) const
00121 {
00122 std::vector< TimeSlice >::const_iterator f = std::lower_bound( m_dataSets.begin(), m_dataSets.end(), time, TimeSliceCompare() );
00123 if( f != m_dataSets.end() && f->second == time )
00124 {
00125 return f->first;
00126 }
00127 return boost::shared_ptr< WDataSetScalar const >();
00128 }
00129
00130 boost::shared_ptr< WDataSetScalar const > WDataSetTimeSeries::calcDataSetAtTime( float time, std::string const& name ) const
00131 {
00132 WAssert( !wlimits::isnan( time ), "" );
00133 if( time < getMinTime() || time > getMaxTime() )
00134 {
00135 return boost::shared_ptr< WDataSetScalar const >();
00136 }
00137 float lb = getLBTimeSlice( time );
00138 float ub = getUBTimeSlice( time );
00139 if( lb == time || ub == time )
00140 {
00141
00142 return getDataSetPtrAtTimeSlice( time );
00143 }
00144
00145 boost::shared_ptr< WValueSetBase > vs;
00146 switch( m_dataSets.front().first->getValueSet()->getDataType() )
00147 {
00148 case W_DT_UINT8:
00149 vs = calcInterpolatedValueSet< uint8_t >( lb, ub, time );
00150 break;
00151 case W_DT_INT8:
00152 vs = calcInterpolatedValueSet< int8_t >( lb, ub, time );
00153 break;
00154 case W_DT_UINT16:
00155 vs = calcInterpolatedValueSet< uint16_t >( lb, ub, time );
00156 break;
00157 case W_DT_INT16:
00158 vs = calcInterpolatedValueSet< int16_t >( lb, ub, time );
00159 break;
00160 case W_DT_UINT32:
00161 vs = calcInterpolatedValueSet< uint32_t >( lb, ub, time );
00162 break;
00163 case W_DT_SIGNED_INT:
00164 vs = calcInterpolatedValueSet< int32_t >( lb, ub, time );
00165 break;
00166 case W_DT_UINT64:
00167 vs = calcInterpolatedValueSet< uint64_t >( lb, ub, time );
00168 break;
00169 case W_DT_INT64:
00170 vs = calcInterpolatedValueSet< int64_t >( lb, ub, time );
00171 break;
00172 case W_DT_FLOAT:
00173 vs = calcInterpolatedValueSet< float >( lb, ub, time );
00174 break;
00175 case W_DT_DOUBLE:
00176 vs = calcInterpolatedValueSet< double >( lb, ub, time );
00177 break;
00178 default:
00179 throw WException( std::string( "Unsupported datatype in WDataSetTimeSeries::calcDataSetAtTime()" ) );
00180 break;
00181 }
00182 boost::shared_ptr< WDataSetScalar > ds( new WDataSetScalar( vs, m_dataSets.front().first->getGrid() ) );
00183 ds->setFileName( name );
00184 return ds;
00185 }
00186
00187 bool WDataSetTimeSeries::TimeSliceCompare::operator() ( TimeSlice const& t0, TimeSlice const& t1 )
00188 {
00189 return t0.second < t1.second;
00190 }
00191
00192 bool WDataSetTimeSeries::TimeSliceCompare::operator() ( float const& t0, TimeSlice const& t1 )
00193 {
00194 return t0 < t1.second;
00195 }
00196
00197 bool WDataSetTimeSeries::TimeSliceCompare::operator() ( TimeSlice const& t0, float const& t1 )
00198 {
00199 return t0.second < t1;
00200 }
00201
00202 float WDataSetTimeSeries::getLBTimeSlice( float time ) const
00203 {
00204 std::vector< TimeSlice >::const_iterator f = std::lower_bound( m_dataSets.begin(), m_dataSets.end(), time, TimeSliceCompare() );
00205 float t = -std::numeric_limits< float >::infinity();
00206 if( f != m_dataSets.end() && f->second == time )
00207 {
00208 return time;
00209 }
00210 if( f != m_dataSets.begin() )
00211 {
00212 --f;
00213 t = f->second;
00214 }
00215 return t;
00216 }
00217
00218 float WDataSetTimeSeries::getUBTimeSlice( float time ) const
00219 {
00220 std::vector< TimeSlice >::const_iterator g = std::upper_bound( m_dataSets.begin(), m_dataSets.end(), time, TimeSliceCompare() );
00221 float t = std::numeric_limits< float >::infinity();
00222 if( g != m_dataSets.end() )
00223 {
00224 t = g->second;
00225 }
00226 return t;
00227 }
00228
00229 WDataSetTimeSeries::WDataSetTimeSeries()
00230 : m_dataSets()
00231 {
00232 }
00233
00234 double WDataSetTimeSeries::getMinValue()
00235 {
00236 return m_minValue;
00237 }
00238
00239 double WDataSetTimeSeries::getMaxValue()
00240 {
00241 return m_maxValue;
00242 }