// ========================================================================= // @author Leonardo Florez Valencia // @email florez-l@javeriana.edu.co // ========================================================================= #include #include // ------------------------------------------------------------------------- fpa::Generic::PeakDetector:: PeakDetector( ) : m_K( 3 ), m_T( 3.5 ), m_I( 0.5 ) { } // ------------------------------------------------------------------------- fpa::Generic::PeakDetector:: ~PeakDetector( ) { } // ------------------------------------------------------------------------- unsigned long fpa::Generic::PeakDetector:: GetKernelSize( ) const { return( this->m_K ); } // ------------------------------------------------------------------------- double fpa::Generic::PeakDetector:: GetThreshold( ) const { return( this->m_T ); } // ------------------------------------------------------------------------- double fpa::Generic::PeakDetector:: GetInfluence( ) const { return( this->m_I ); } // ------------------------------------------------------------------------- void fpa::Generic::PeakDetector:: SetKernelSize( unsigned long k ) { this->m_K = k; this->Clear( ); } // ------------------------------------------------------------------------- void fpa::Generic::PeakDetector:: SetThreshold( double t ) { this->m_T = t; this->Clear( ); } // ------------------------------------------------------------------------- void fpa::Generic::PeakDetector:: SetInfluence( double i ) { this->m_I = i; this->Clear( ); } // ------------------------------------------------------------------------- void fpa::Generic::PeakDetector:: Clear( ) { this->m_X.clear( ); this->m_Y.clear( ); this->m_YF.clear( ); this->m_Avg.clear( ); this->m_STD.clear( ); this->m_Peaks.clear( ); this->m_Mean = 0; this->m_Vari = 0; } // ------------------------------------------------------------------------- unsigned long fpa::Generic::PeakDetector:: GetNumberOfSamples( ) const { return( this->m_X.size( ) ); } // ------------------------------------------------------------------------- fpa::Generic::PeakDetector:: TPeak fpa::Generic::PeakDetector:: AddValue( double x, double y ) { this->m_X.push_back( x ); this->m_Y.push_back( y ); if( this->m_YF.size( ) < this->m_K ) { double n = double( this->m_YF.size( ) + 1 ); this->m_YF.push_back( y ); this->m_Avg.push_back( double( 0 ) ); this->m_STD.push_back( double( 0 ) ); this->m_Peaks.push_back( Self::NoPeak ); if( n > double( 1 ) ) this->m_Vari = ( ( ( n - 2.0 ) / ( n - 1.0 ) ) * this->m_Vari ) + ( ( ( y - this->m_Mean ) * ( y - this->m_Mean ) ) / n ); this->m_Mean += ( y - this->m_Mean ) / n; if( this->m_YF.size( ) == this->m_K ) { this->m_Avg.push_back( this->m_Mean ); this->m_STD.push_back( std::sqrt( this->m_Vari ) ); } // fi } else { unsigned long i = this->m_X.size( ) - 1; if( ( std::fabs( y - this->m_Avg[ i - 1 ] ) ) > ( this->m_T * this->m_STD[ i - 1 ] ) ) { this->m_Peaks.push_back( ( y > this->m_Avg[ i - 1 ] )? Self::PosPeak: Self::NegPeak ); this->m_YF.push_back( ( this->m_I * y ) + ( ( 1.0 - this->m_I ) * this->m_YF[ i - 1 ] ) ); } else { this->m_Peaks.push_back( Self::NoPeak ); this->m_YF.push_back( y ); } // fi double avg = double( 0 ); double var = double( 0 ); unsigned long k = 0; for( unsigned long j = i - this->m_K; j <= i; ++j, ++k ) { double v = this->m_YF[ j ]; double n = double( k + 1 ); if( k > 1 ) var = ( ( ( n - 2.0 ) / ( n - 1.0 ) ) * var ) + ( ( ( v - avg ) * ( v - avg ) ) / n ); avg += ( v - avg ) / n; } // rof this->m_Avg.push_back( avg ); this->m_STD.push_back( std::sqrt( var ) ); } // fi return( this->m_Peaks.back( ) ); } // eof - $RCSfile$