First of all let's understand what fft(y) and fftfreq(N, T) do:
The fft(y) is the function that performs the Fast Fourier Transform on the input array of samples y. the function returns an array of values which are called DFT bins. The returned array has the same size as the input array y.
The magnitude of these DFT bins tells you something about the magnitude of each tone corresponding to each DFT bin.
While the fftfreq(N, T) gives you back an array of N values representing the frequencies of N DFT bins returned by performing an fft() on N samples of a signal sampled with sampling frequency fs= 1/T where T is the sampling time.
Now back to your question:
Please help me to use the correct values for N and T.
T is the sampling time of your input signal, T = 4e-10.
Talking about how we can choose N, theoretically, if you want the best result and you don't care about how much it takes to compute the signal fft, you can put N being the size of your input y array then:
y = df['signal'].values
yf = fft(y)
# Number of sample points
N = y.size
# sample spacing
T = 4e-10
xf = fftfreq(N, T)[:N//2]
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
plt.grid()
plt.show()
but this is not wise, especially, because based on your data, the signal you want to analyze is periodic and just by looking at it, it seems like it contains several cycles at the apparent fundamental frequency which you want to find. Thus we can find the dominant frequency without the need of performing the fft on all 999.999 samples.
we can choose N to be great enough to contain at least a cycle and which gives us a good frequency resolution, based on the formula df = fs/N where df is the frequency resolution.
The frequency resolution is the frequency distance between the fft output bins, which means that when you perform the fft output values fft[0],fft[1],....fft[N-1] correspond to the frequencies 0, df,2df,3df,4df.....(N-1)df. The smaller the frequency resolution the more accurate the spectrum analysis, but this is at the cost of performing the FFT on a large number of points (not efficient).
let's choose N to contain for example 20 cycles (to lower spectral leakage), which appears to me around N=40000.
This gives us a frequency resolution of df = 62.5 kHz which is good compared to the scale of the fundamental frequency.
To the question
what portion of the data should be used to find discrete Fourier transformation of the given signal
If your data set contains several cycles of the periodic signal (which is the case) then it doesn't matter the portion of the data.
Answering this question:
Please plot the frequency spectrum
If you wanna plot the DFT magnitude:
# Number of sample points
N = 40000
# sample spacing
T = 4e-10
y = df['signal'].values
# notice that I'm taking the first N samples of y
yf = fft(y[:N])
'''
you can plot fewer bins of the fft since all the spectrum energy is concentrated under 10 MHz
'''
n_bins = 130
xf = fftfreq(N, T)[:n_bins]
plt.plot(xf, 2.0/N * np.abs(yf[0:n_bins]))
plt.grid()
plt.show()
to the question:
Please find the dominant frequency
The dominant frequency is just the frequency that corresponds to the DFT bin with the largest magnitude, thus:
df = 1/(N*T)
mag_fft = abs(yf)
largest_dft = max(mag_fft)
indx_largest_dft = mag_fft.index(largest_dft)
# dominant frequency in Hz
dominant_frequency = indx_largest_dft*df
By increasing N you get a more accurate value of the dominant frequency as df decreases.