@@ -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 }
@@ -516,116 +485,3 @@ GraphSpectrumCalc._normalizeFft = function(fftOutput, fftLength) {
516485
517486 return fftData ;
518487} ;
519-
520- /**
521- * Compute PSD for data samples by Welch method follow Python code
522- */
523- GraphSpectrumCalc . _psd = function ( samples , pointsPerSegment , overlapCount , scaling = 'density' ) {
524- // Compute FFT for samples segments
525- const fftOutput = this . _fft_segmented ( samples , pointsPerSegment , overlapCount ) ;
526-
527- const dataCount = fftOutput [ 0 ] . length ;
528- const segmentsCount = fftOutput . length ;
529- const psdOutput = new Float64Array ( dataCount ) ;
530-
531- // Compute power scale coef
532- let scale = 1 ;
533- if ( userSettings . analyserHanning ) {
534- const window = Array ( pointsPerSegment ) . fill ( 1 ) ;
535- this . _hanningWindow ( window , pointsPerSegment ) ;
536- if ( scaling == 'density' ) {
537- let skSum = 0 ;
538- for ( const value of window ) {
539- skSum += value ** 2 ;
540- }
541- scale = 1 / ( this . _blackBoxRate * skSum ) ;
542- } else if ( scaling == 'spectrum' ) {
543- let sum = 0 ;
544- for ( const value of window ) {
545- sum += value ;
546- }
547- scale = 1 / sum ** 2 ;
548- }
549- } else if ( scaling == 'density' ) {
550- scale = 1 / pointsPerSegment ;
551- } else if ( scaling == 'spectrum' ) {
552- scale = 1 / pointsPerSegment ** 2 ;
553- }
554-
555- // Compute average for scaled power
556- let min = 1e6 ,
557- max = - 1e6 ;
558- // Early exit if no segments were processed
559- if ( segmentsCount === 0 ) {
560- return {
561- psdOutput : new Float64Array ( 0 ) ,
562- min : 0 ,
563- max : 0 ,
564- maxNoiseIdx : 0 ,
565- } ;
566- }
567- const maxFrequency = ( this . _blackBoxRate / 2.0 ) ;
568- const noise50HzIdx = 50 / maxFrequency * dataCount ;
569- const noise3HzIdx = 3 / maxFrequency * dataCount ;
570- let maxNoiseIdx = 0 ;
571- let maxNoise = - 100 ;
572- for ( let i = 0 ; i < dataCount ; i ++ ) {
573- psdOutput [ i ] = 0.0 ;
574- for ( let j = 0 ; j < segmentsCount ; j ++ ) {
575- let p = scale * fftOutput [ j ] [ i ] ** 2 ;
576- if ( i != dataCount - 1 ) {
577- p *= 2 ;
578- }
579- psdOutput [ i ] += p ;
580- }
581-
582- const min_avg = 1e-7 ; // limit min value for -70db
583- let avg = psdOutput [ i ] / segmentsCount ;
584- avg = Math . max ( avg , min_avg ) ;
585- psdOutput [ i ] = 10 * Math . log10 ( avg ) ;
586- if ( i > noise3HzIdx ) { // Miss big zero freq magnitude
587- min = Math . min ( psdOutput [ i ] , min ) ;
588- max = Math . max ( psdOutput [ i ] , max ) ;
589- }
590- if ( i > noise50HzIdx && psdOutput [ i ] > maxNoise ) {
591- maxNoise = psdOutput [ i ] ;
592- maxNoiseIdx = i ;
593- }
594- }
595-
596- const maxNoiseFrequency = maxNoiseIdx / dataCount * maxFrequency ;
597-
598- return {
599- psdOutput : psdOutput ,
600- min : min ,
601- max : max ,
602- maxNoiseIdx : maxNoiseFrequency ,
603- } ;
604- } ;
605-
606-
607- /**
608- * Compute FFT for samples segments by lenghts as pointsPerSegment with overlapCount overlap points count
609- */
610- GraphSpectrumCalc . _fft_segmented = function ( samples , pointsPerSegment , overlapCount ) {
611- const samplesCount = samples . length ;
612- let output = [ ] ;
613- for ( let i = 0 ; i <= samplesCount - pointsPerSegment ; i += pointsPerSegment - overlapCount ) {
614- const fftInput = samples . slice ( i , i + pointsPerSegment ) ;
615-
616- if ( userSettings . analyserHanning ) {
617- this . _hanningWindow ( fftInput , pointsPerSegment ) ;
618- }
619-
620- const fftComplex = this . _fft ( fftInput ) ;
621- const magnitudes = new Float64Array ( pointsPerSegment / 2 ) ;
622- for ( let i = 0 ; i < pointsPerSegment / 2 ; i ++ ) {
623- const re = fftComplex [ 2 * i ] ;
624- const im = fftComplex [ 2 * i + 1 ] ;
625- magnitudes [ i ] = Math . hypot ( re , im ) ;
626- }
627- output . push ( magnitudes ) ;
628- }
629-
630- return output ;
631- } ;
0 commit comments