OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 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 // prototype instance as singleton 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::dynamic_pointer_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::dynamic_pointer_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 // not optimal if the compiler does not inline 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 }