@@ -106,33 +106,6 @@ GraphSpectrumCalc.dataLoadFrequency = function() {
106106 return fftData ;
107107} ;
108108
109- GraphSpectrumCalc . dataLoadPSD = function ( analyserZoomY ) {
110- const flightSamples = this . _getFlightSamplesFreq ( false ) ;
111-
112- let pointsPerSegment = 512 ;
113- const multipiler = Math . floor ( 1 / analyserZoomY ) ; // 0. ... 10
114- if ( multipiler == 0 ) {
115- pointsPerSegment = 256 ;
116- } else if ( multipiler > 1 ) {
117- pointsPerSegment *= 2 ** Math . floor ( multipiler / 2 ) ;
118- }
119- pointsPerSegment = Math . min ( pointsPerSegment , flightSamples . samples . length ) ;
120- const overlapCount = Math . floor ( pointsPerSegment / 2 ) ;
121-
122- const psd = this . _psd ( flightSamples . samples , pointsPerSegment , overlapCount ) ;
123-
124- const psdData = {
125- fieldIndex : this . _dataBuffer . fieldIndex ,
126- fieldName : this . _dataBuffer . fieldName ,
127- psdLength : psd . psdOutput . length ,
128- psdOutput : psd . psdOutput ,
129- blackBoxRate : this . _blackBoxRate ,
130- minimum : psd . min ,
131- maximum : psd . max ,
132- maxNoiseIdx : psd . maxNoiseIdx ,
133- } ;
134- return psdData ;
135- } ;
136109
137110GraphSpectrumCalc . _dataLoadFrequencyVsX = function ( vsFieldNames , minValue = Infinity , maxValue = - Infinity ) {
138111
@@ -310,7 +283,7 @@ GraphSpectrumCalc._getFlightChunks = function() {
310283 return allChunks ;
311284} ;
312285
313- GraphSpectrumCalc . _getFlightSamplesFreq = function ( scaled = true ) {
286+ GraphSpectrumCalc . _getFlightSamplesFreq = function ( ) {
314287
315288 const allChunks = this . _getFlightChunks ( ) ;
316289
@@ -320,11 +293,7 @@ GraphSpectrumCalc._getFlightSamplesFreq = function(scaled = true) {
320293 let samplesCount = 0 ;
321294 for ( const chunk of allChunks ) {
322295 for ( const frame of chunk . frames ) {
323- if ( scaled ) {
324- samples [ samplesCount ] = this . _dataBuffer . curve . lookupRaw ( frame [ this . _dataBuffer . fieldIndex ] ) ;
325- } else {
326- samples [ samplesCount ] = frame [ this . _dataBuffer . fieldIndex ] ;
327- }
296+ samples [ samplesCount ] = ( this . _dataBuffer . curve . lookupRaw ( frame [ this . _dataBuffer . fieldIndex ] ) ) ;
328297 samplesCount ++ ;
329298 }
330299 }
@@ -515,116 +484,3 @@ GraphSpectrumCalc._normalizeFft = function(fftOutput, fftLength) {
515484
516485 return fftData ;
517486} ;
518-
519- /**
520- * Compute PSD for data samples by Welch method follow Python code
521- */
522- GraphSpectrumCalc . _psd = function ( samples , pointsPerSegment , overlapCount , scaling = 'density' ) {
523- // Compute FFT for samples segments
524- const fftOutput = this . _fft_segmented ( samples , pointsPerSegment , overlapCount ) ;
525-
526- const dataCount = fftOutput [ 0 ] . length ;
527- const segmentsCount = fftOutput . length ;
528- const psdOutput = new Float64Array ( dataCount ) ;
529-
530- // Compute power scale coef
531- let scale = 1 ;
532- if ( userSettings . analyserHanning ) {
533- const window = Array ( pointsPerSegment ) . fill ( 1 ) ;
534- this . _hanningWindow ( window , pointsPerSegment ) ;
535- if ( scaling == 'density' ) {
536- let skSum = 0 ;
537- for ( const value of window ) {
538- skSum += value ** 2 ;
539- }
540- scale = 1 / ( this . _blackBoxRate * skSum ) ;
541- } else if ( scaling == 'spectrum' ) {
542- let sum = 0 ;
543- for ( const value of window ) {
544- sum += value ;
545- }
546- scale = 1 / sum ** 2 ;
547- }
548- } else if ( scaling == 'density' ) {
549- scale = 1 / pointsPerSegment ;
550- } else if ( scaling == 'spectrum' ) {
551- scale = 1 / pointsPerSegment ** 2 ;
552- }
553-
554- // Compute average for scaled power
555- let min = 1e6 ,
556- max = - 1e6 ;
557- // Early exit if no segments were processed
558- if ( segmentsCount === 0 ) {
559- return {
560- psdOutput : new Float64Array ( 0 ) ,
561- min : 0 ,
562- max : 0 ,
563- maxNoiseIdx : 0 ,
564- } ;
565- }
566- const maxFrequency = ( this . _blackBoxRate / 2.0 ) ;
567- const noise50HzIdx = 50 / maxFrequency * dataCount ;
568- const noise3HzIdx = 3 / maxFrequency * dataCount ;
569- let maxNoiseIdx = 0 ;
570- let maxNoise = - 100 ;
571- for ( let i = 0 ; i < dataCount ; i ++ ) {
572- psdOutput [ i ] = 0.0 ;
573- for ( let j = 0 ; j < segmentsCount ; j ++ ) {
574- let p = scale * fftOutput [ j ] [ i ] ** 2 ;
575- if ( i != dataCount - 1 ) {
576- p *= 2 ;
577- }
578- psdOutput [ i ] += p ;
579- }
580-
581- const min_avg = 1e-7 ; // limit min value for -70db
582- let avg = psdOutput [ i ] / segmentsCount ;
583- avg = Math . max ( avg , min_avg ) ;
584- psdOutput [ i ] = 10 * Math . log10 ( avg ) ;
585- if ( i > noise3HzIdx ) { // Miss big zero freq magnitude
586- min = Math . min ( psdOutput [ i ] , min ) ;
587- max = Math . max ( psdOutput [ i ] , max ) ;
588- }
589- if ( i > noise50HzIdx && psdOutput [ i ] > maxNoise ) {
590- maxNoise = psdOutput [ i ] ;
591- maxNoiseIdx = i ;
592- }
593- }
594-
595- const maxNoiseFrequency = maxNoiseIdx / dataCount * maxFrequency ;
596-
597- return {
598- psdOutput : psdOutput ,
599- min : min ,
600- max : max ,
601- maxNoiseIdx : maxNoiseFrequency ,
602- } ;
603- } ;
604-
605-
606- /**
607- * Compute FFT for samples segments by lenghts as pointsPerSegment with overlapCount overlap points count
608- */
609- GraphSpectrumCalc . _fft_segmented = function ( samples , pointsPerSegment , overlapCount ) {
610- const samplesCount = samples . length ;
611- let output = [ ] ;
612- for ( let i = 0 ; i <= samplesCount - pointsPerSegment ; i += pointsPerSegment - overlapCount ) {
613- const fftInput = samples . slice ( i , i + pointsPerSegment ) ;
614-
615- if ( userSettings . analyserHanning ) {
616- this . _hanningWindow ( fftInput , pointsPerSegment ) ;
617- }
618-
619- const fftComplex = this . _fft ( fftInput ) ;
620- const magnitudes = new Float64Array ( pointsPerSegment / 2 ) ;
621- for ( let i = 0 ; i < pointsPerSegment / 2 ; i ++ ) {
622- const re = fftComplex [ 2 * i ] ;
623- const im = fftComplex [ 2 * i + 1 ] ;
624- magnitudes [ i ] = Math . hypot ( re , im ) ;
625- }
626- output . push ( magnitudes ) ;
627- }
628-
629- return output ;
630- } ;
0 commit comments