# properly windowing for better FFT signal

I have an analog signal as shown below.
As you can see it has a DC component, a 1MHz component and some high order component.
The period of the signal is 8.0199667µs.
I want to see a good accurate frequencies up to 10MHz.
I have captured a signal 78.97518µs long. Its edges are not absolutely equal so my fft will get distorted because of the discontinuity.

Also the LTSPICE program is not sampling the signal equally so I am doing cubic spline to create a "continues" signal which I will try to resample again using cubic spline.

The full sample table which I interpolate is shown in the link below. I have made cubic spline interpolation and resampled it in python at 1/1e7 time gaps as shown in the code below.

How do I create in python a proper windowing to cancel the discontinuity as much as possible?

https://files.fm/u/dpr36h6ce

from scipy.fftpack import fft
#import plotly
#import chart_studio.plotly as py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
from gekko import GEKKO
#%matplotlib qt
new_x=np.arange(0,7.89752e-05,1/(1e7))
array_fft=dataset_fft.values
m=GEKKO()
m.x=m.Param(new_x)
m.y=m.Var()
m.cspline(m.x,m.y,array_fft[:,0],array_fft[:,1])
m.options.IMODE=2
m.solve(disp=False)
fig=plt.figure()

ax=fig.subplots()
ax.grid()
cursor=Cursor(ax, horizOn=True,vertOn=True,useblit=True,color='r',linewidth =1)
#plt.plot(array_fft[:,0],array_fft[:,1])

plt.plot(m.x,m.y)
plt.xlabel("time")
plt.ylabel("amp")
plt.show()

• Are you sure LTSpice is not sampling at a consistent rate? Or could you show more details how you came to that conclusion (such as a zoom in or 10 consecutive values it returns as the raw values without your interpolation, what the frequency is and what the points you get vs what you would have predicted? (Without further processing) — or perhaps more directly the time samples if it returns that? I want to understand the amount of variation motivating the additional interpolation Apr 14, 2023 at 1:14
• Hello Dan,the time spacing is as follows,using python code is shown bellow,also i have attached a link of my raw LTSPICE data: If you could please help me with how to properly windowing my interpolated signal.Thanks. ibb.co/hHYdv6y files.fm/f/ggvaex7qm Apr 14, 2023 at 6:54
• I wonder if you really need to window your time-domain signal sequence. Will windowing be of any benefit in your spectrum analysis activity? Will the benefit of windowing (spectral sidelobe reduction) outweigh the detrimental effect (the “smearing” of your spectral components) of windowing? Only you can answer that. Apr 14, 2023 at 9:43

LTSpice similar to other SPICE simulators use an adaptive time step as needed by the time change. This results in efficient computation and keeps the computed derivatives used from exploding. The OP's solution to interpolate the result is a good solution and wants to know how to properly window the fixed time result before computing the DFT.

Another approach to get a uniform time spacing is to export a .Wav file using the .wave command. I believe this is limited to +1/-1V output, so if taking that approach the waveform should be properly scaled to that range before exporting. More details on using the .wave command can be found here as well as in the LTSpice documentation.

Windowing a waveform in MATLAB, Octave and Scipy.signal is very straight forward as all the common windows are precomputed. For the OP's purpose I recommend using the Kaiser window, where the window is computed using kaiser(N, b) with N as the number of samples (matching the number of samples to use in the FFT) and b as the $$\beta$$ parameter for this window. With that window, the trade between dynamic range and resolution bandwidth can be adjusted directly with the $$\beta$$ parameter. Typical values I use are in the range of 6 to 22, but by adjusting this you can get similar performance to many other window types used for the OP's purpose.

The Kaiser (and other) windows is part of the Signal Processing Toolbox in MATLAB, and the signal package in Octave (loaded from a standard Octave install by typing pkg load signal), and the scipy.signal package in Python. Example use in Python is shown below for a waveform file named wfm:

import scipy.signal as sig
import scipy.fft as fft
fs = 1
N = len(sig)
win = sig.kaiser(N, 12)
fft_result = fft.fft(win * wfm)
freqaxis = fft.fftfreq(N, fs)


In the example, I used a normalized sample rate of 1 cycle/sample, and a $$\beta$$ of 12. $$\beta$$ can be increased if greater sidelobe rejection is needed, or decreased to reduce that but increase frequency resolution.

I have detailed in the following existing posts the considerations with windowing, overall time duration and zero padding with regards to the impact on frequency resolution that should be helpful to the OP:

How to calculate resolution of DFT with Hamming/Hann window?

Specific Frequency Resolution

• Hello Dan,My interpolated signal is 7.89752e-05 samplig rate is 1/1e7 seconds so i got 1993 samples. I have done a DB FFT plot on my resampled interpolated signal .So this is my starting point. 1993 bins is not enough to represent 10MHz. So should i make my interpolated signal longer? or zero pdding ? or should i do windowing? what to you reccomend? What do recomment to improve the situation? My fft plot ,python code,LTSPICE samples shown in the links bellow. fft plot: ibb.co/YyDYTgg python code: files.fm/u/768ecwhk3 raw data: files.fm/f/ggvaex7qm Apr 14, 2023 at 14:23
• @lub2354 I have other posts here already that relate the windowing and time duration to the resulting frequency resolution which is what I think you are missing. Zero padding just smooths the result but does not increase the actual frequency resolution. I'll add these posts to the bottom of the answer as I think it will clear up your remaining questions, but please do let me know if they were helpful (and comment under them if you have further specific questions to what is provided there). Apr 14, 2023 at 18:08
• @lub2354 and to answer your specific question, if your time gap is 1/1e7 seconds then your sampling rate is 1e7 Hz (10 MHz). If that's true your issue is not the number of samples but the sampling rate itself. To represent 10 MHz, the sampling rate must be greater than 2x that (I would use 30 MHz or greater to keep the images apart). Once you sample fast enough, the total number of samples would give you the total time duration of the capture, and the inverse of that is your resolution bandwidth (how closely you can resolve two different frequencies spaced close together) Apr 15, 2023 at 14:46
• @lub2354 I see now that you meant 1 MHz not 10 MHz in your last comment, as I looked at your first linked picture. I recommend subtracting the mean to remove DC as that is contributing a lot of spectral leakage swamping out your 1 MHz signal. Further you will benefit by using a window as I suggested - try doing what I showed in the code in my answer and you should get much better results. If you want the resulting peak to be narrower once you see what you get after windowing, you will then need to increase your total capture time duration and then window that Apr 17, 2023 at 2:50