I have measurements of a transfer function $H(f)$ in the frequency domain between 1-6 GHz. I also have an input signal, which is pulsed chirp $x(t)$. The goal is to build the time-domain response of the system. To that end, I take a Fourier transform of the initial signal which gives me $X(f)$. Then I build the $H(f)$ by adding it to its conjugate mirror vector (in Python). Then I multiply it to $X(f)$ and then I take the Inverse Fourier Transform to find the time-domain response $y(t)$. First, I'd like to know if this process is correct. We had a discussion that we might just need to consider the positive frequencies by zeroing out the negative ones right before the IFFT. Which one of these two are technically correct?
Secondly, when I plot the real and imaginary parts of $y(t)$, the shapes make sense but there is an imaginary part about one order of of magnitude smaller than the real part. Shouldn't the imaginary part be much smaller than that?
Third, when I take the Fourier transform of $H(f)$, I find that there is an imaginary part. Is that Ok?
Finally, what is the significance of the small rise at the very end?
Here $g_21(t)$ is indeed $h(t)$ and $G_21(f)$ is $H(f)$ in the above description. $y_2(t)$ is the time domain response of my system. I changed the dataset because the imaginary part is more pronounced here.
Here's my entire code.
from scipy.signal import chirp import numpy as np import matplotlib.pyplot as plt N = 16000; sig_duration = 320e-9; dt = sig_duration/N; fs = 1/dt; density = 320; t = np.linspace(0, sig_duration, N); x = chirp(t, 1.5e9, sig_duration, 5.5e9, method='linear', phi=-90) x[:int(N/4)] = 0; x[int(3*N/4):] = 0;
import pandas as pd
import numpy as np
data = "/content/Meas S21 Complex_DARPA Cyl_EXT Excitn Apert 1_0 Absorbers.xlsx"
real_impulse_response = pd.read_excel(data, sheet_name="S21 Real", usecols="B", skiprows=5, nrows=1601, header=None)
imag_impulse_response = pd.read_excel(data, sheet_name="S21 Imag", usecols="B", skiprows=5, nrows=1601, header=None)
impulse_response = np.vectorize(complex)(real_impulse_response.values, imag_impulse_response.values)
experimental_frequencies = pd.read_excel(data, sheet_name="S21 Real", usecols="A", skiprows=5, nrows=1601, header=None)
plt.plot(experimental_frequencies, abs(impulse_response))
plt.yscale("log")
plt.xlabel("Freq in Hz")
plt.ylabel("$G_{21}(f)$")
from numpy.fft.helper import fftshift
f = np.fft.fftfreq(N, dt)
G21 = np.zeros(len(f), dtype=np.complex_)
impulse_response = impulse_response.flatten()
G21[int(len(f)/2)+density: int(len(f)/2) +density+len(impulse_response)] = impulse_response
#G21_ds = G21 + np.conj(G21[::-1])
#G21_ds = np.fft.fftshift(G21_ds)
G21_ds = G21 + np.conj(G21[::-1])
G21_ds = np.fft.fftshift(G21_ds)
G21_ds[int(N/2):] = 0
G21_sym = (G21_ds + np.conj(G21_ds[::-1]))/2
g = np.fft.ifft(G21_sym)*N
plt.plot(f/1e9, abs(np.fft.fft(x, N)/N))
plt.yscale("log")
plt.xlim(0, 6)
plt.ylim(bottom=1e-4)
plt.xlabel("Freq(GHz)")
plt.ylabel("$X_1(f)$")
#G21_ds[int(N/2):] = 0
#g =np.fft.ifft(G21_ds)N
plt.subplot(211)
plt.plot(1e9t, g.real)
plt.xlabel("time(ns)")
plt.ylabel("$Re [g_{21}(t)]$")
plt.subplot(212)
plt.plot(1e9*t, g.imag)
plt.ylabel("$Im[g_{21}(t)]$")
plt.xlabel("time(ns)")
#plt.legend(bbox_to_anchor=(1.0, 1))
plt.show()
y2 = np.fft.ifft(G21_sym * np.fft.fft(x, N))
#plt.axvline(x = 0.8e2, color = 'r', label = 'Chirp Starts')
#plt.axvline(x = 2.4e2, color = 'g', label = 'Chirp Ends')
plt.subplot(311)
plt.plot(1e9*t, x)
plt.xlim([0,320])
plt.ylabel("$x(t)$")
plt.xlabel("time(ns)")
plt.subplot(312)
plt.plot(1e9*t, y2.real, label = "Re(y_2(t))")
plt.ylabel("$REAL~ y_2(t)$")
plt.xlabel("time(ns)")
plt.xlim([0,320])
plt.subplot(313)
plt.plot(1e9*t, y2.imag)
plt.ylabel("$IMAG ~ y_2(t)$")
plt.xlabel("time(ns)")
plt.xlim([0,320])
plt.legend(bbox_to_anchor=(1, 1))
plt.show()

