Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Is pythons FFT function broken?

Status
Not open for further replies.

wtr

Full Member level 5
Joined
May 1, 2014
Messages
299
Helped
29
Reputation
58
Reaction score
25
Trophy points
1,308
Activity points
4,108
I've read this, https://www.edaboard.com/threads/arduinofft-h-generates-weird-results.400524/

Posted about my dip in magnitude here https://www.edaboard.com/threads/so...ictim-of-transceiver-agc.400674/#post-1725359.

However now I've stepped back and generated a stimulus. I know that the results I was previously getting is not a symptom of my captured data, but rather the processing.

This generated sinusoidal is then fed into the fft. I change the frequency. Please watch the magnitude. Is specgram broken?

Please run the following python code for yourself and see what happens.


Code Python - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import numpy as np
from matplotlib import mlab
import matplotlib.pyplot as plt
import matplotlib.animation as animation
 
 
def safe_log10(values, minval=1e-16):  # pragma: no cover
    """Safely do log10."""
    return np.log10(values.clip(min=minval))
 
 
def animate(i):
    A = 10
    fs = 44100
    sample = fs
    nfft = 4096
 
    f = 11440 + (i * 10)  # Steps by
    # f = 11440 + (i * (fs / nfft))  # Steps by
 
    x = np.arange(sample * 10)
    y = A * np.sin(2 * np.pi * f * x / fs)
 
    ax = plt.axes(projection='3d')
    spec, freqs, t = mlab.specgram(y, NFFT=nfft, noverlap=0, Fs=fs, mode='magnitude')
    X, Y, Z = t[None, :], freqs[:, None], 20.0 * safe_log10(spec)
    ax.plot_surface(X, Y, Z, cmap='viridis', cstride=4, rstride=4)
    ax.set_xlabel('time (s)')
    ax.set_ylabel('frequencies (Hz)')
    ax.set_zlabel('amplitude (dB)')
    ax.set_zlim(-140, 0)
 
 
animation_1 = animation.FuncAnimation(plt.gcf(), animate, interval=100)
plt.show()



Thanks in advance.
 

I've read this, https://www.edaboard.com/threads/arduinofft-h-generates-weird-results.400524/

Posted about my dip in magnitude here https://www.edaboard.com/threads/so...ictim-of-transceiver-agc.400674/#post-1725359.

However now I've stepped back and generated a stimulus. I know that the results I was previously getting is not a symptom of my captured data, but rather the processing.

This generated sinusoidal is then fed into the fft. I change the frequency. Please watch the magnitude. Is specgram broken?

Please run the following python code for yourself and see what happens.


Code Python - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import numpy as np
from matplotlib import mlab
import matplotlib.pyplot as plt
import matplotlib.animation as animation
 
 
def safe_log10(values, minval=1e-16):  # pragma: no cover
    """Safely do log10."""
    return np.log10(values.clip(min=minval))
 
 
def animate(i):
    A = 10
    fs = 44100
    sample = fs
    nfft = 4096
 
    f = 11440 + (i * 10)  # Steps by
    # f = 11440 + (i * (fs / nfft))  # Steps by
 
    x = np.arange(sample * 10)
    y = A * np.sin(2 * np.pi * f * x / fs)
 
    ax = plt.axes(projection='3d')
    spec, freqs, t = mlab.specgram(y, NFFT=nfft, noverlap=0, Fs=fs, mode='magnitude')
    X, Y, Z = t[None, :], freqs[:, None], 20.0 * safe_log10(spec)
    ax.plot_surface(X, Y, Z, cmap='viridis', cstride=4, rstride=4)
    ax.set_xlabel('time (s)')
    ax.set_ylabel('frequencies (Hz)')
    ax.set_zlabel('amplitude (dB)')
    ax.set_zlim(-140, 0)
 
 
animation_1 = animation.FuncAnimation(plt.gcf(), animate, interval=100)
plt.show()



Thanks in advance.
Hello,
I run given code in python - I confirned: amplitude of FFT is c hanging on plot depending on current fequency.

Best Regards
 

I've read this, https://www.edaboard.com/threads/arduinofft-h-generates-weird-results.400524/

Posted about my dip in magnitude here https://www.edaboard.com/threads/so...ictim-of-transceiver-agc.400674/#post-1725359.

However now I've stepped back and generated a stimulus. I know that the results I was previously getting is not a symptom of my captured data, but rather the processing.

This generated sinusoidal is then fed into the fft. I change the frequency. Please watch the magnitude. Is specgram broken?

Please run the following python code for yourself and see what happens.


Code Python - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import numpy as np
from matplotlib import mlab
import matplotlib.pyplot as plt
import matplotlib.animation as animation
 
 
def safe_log10(values, minval=1e-16):  # pragma: no cover
    """Safely do log10."""
    return np.log10(values.clip(min=minval))
 
 
def animate(i):
    A = 10
    fs = 44100
    sample = fs
    nfft = 4096
 
    f = 11440 + (i * 10)  # Steps by
    # f = 11440 + (i * (fs / nfft))  # Steps by
 
    x = np.arange(sample * 10)
    y = A * np.sin(2 * np.pi * f * x / fs)
 
    ax = plt.axes(projection='3d')
    spec, freqs, t = mlab.specgram(y, NFFT=nfft, noverlap=0, Fs=fs, mode='magnitude')
    X, Y, Z = t[None, :], freqs[:, None], 20.0 * safe_log10(spec)
    ax.plot_surface(X, Y, Z, cmap='viridis', cstride=4, rstride=4)
    ax.set_xlabel('time (s)')
    ax.set_ylabel('frequencies (Hz)')
    ax.set_zlabel('amplitude (dB)')
    ax.set_zlim(-140, 0)
 
 
animation_1 = animation.FuncAnimation(plt.gcf(), animate, interval=100)
plt.show()



Thanks in advance.
Any FFT will show amplitude differences between tones due to leakage.. If your tones fall exactly on bin centres then you will have no leakage and all power will fall on one bin and then no difference of amplitude is expected.
 
  • Like
Reactions: wtr

Hi,

and it depends on window function - if used.

try to calculate: Amplitude = sqrt ( Amplitude1^2 + Amplitude2^2 + Amplitude3^2 ...)

Where Amplitudes 1, 2, 3 are the "center amplitudes" plus the amplitudes next to it.
(left, center, right)


Klaus
 

Hi,

and it depends on window function - if used.

try to calculate: Amplitude = sqrt ( Amplitude1^2 + Amplitude2^2 + Amplitude3^2 ...)

Where Amplitudes 1, 2, 3 are the "center amplitudes" plus the amplitudes next to it.
(left, center, right)


Klaus
Or compute total power (all the bins). This should be same irrespective of tone location. And it will be same as input power if fft is set to unity gain across input to output.
 

Any FFT will show amplitude differences between tones due to leakage.. If your tones fall exactly on bin centres then you will have no leakage and all power will fall on one bin and then no difference of amplitude is expected.
Given that resolution is 30KHz and steps are about 100KHz, then as I jump from one bin to another, I'm aware that I may not be on the center, but shouldn't the worst case scenario be 3DB drop as power is split nearly evenly between bin1 and bin2.
 

Given that resolution is 30KHz and steps are about 100KHz, then as I jump from one bin to another, I'm aware that I may not be on the center, but shouldn't the worst case scenario be 3DB drop as power is split nearly evenly between bin1 and bin2.
The best check for your fft is to check total bins power between one tone test and next as well as check power level of input in both cases.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top