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
298
Helped
29
Reputation
58
Reaction score
25
Trophy points
1,308
Activity points
4,095
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.
 

FlyingDutch

Advanced Member level 1
Joined
Dec 16, 2017
Messages
429
Helped
45
Reputation
92
Reaction score
51
Trophy points
28
Location
Bydgoszcz - Poland
Activity points
4,515
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
 

kaz1

Full Member level 4
Joined
Aug 15, 2019
Messages
192
Helped
14
Reputation
28
Reaction score
31
Trophy points
28
Location
UK
Activity points
1,278
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

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
23,045
Helped
4,716
Reputation
9,448
Reaction score
5,092
Trophy points
1,393
Activity points
152,662
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
 

kaz1

Full Member level 4
Joined
Aug 15, 2019
Messages
192
Helped
14
Reputation
28
Reaction score
31
Trophy points
28
Location
UK
Activity points
1,278
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.
 

wtr

Full Member level 5
Joined
May 1, 2014
Messages
298
Helped
29
Reputation
58
Reaction score
25
Trophy points
1,308
Activity points
4,095
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.
 

kaz1

Full Member level 4
Joined
Aug 15, 2019
Messages
192
Helped
14
Reputation
28
Reaction score
31
Trophy points
28
Location
UK
Activity points
1,278
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

Top