Problem using Time Domain Transform Methods for Bandpass Filter Tuning

61 views
Skip to first unread message

Nathan Meddings

unread,
Jan 22, 2023, 10:05:48 AMJan 22
to scikit-rf
Hi All,

I'm trying to get a script going to implement RF band-pass filter tuning in the time domain.

The script takes as input two s-parameter files, one the template to tune against and the other the filter design to be tuned in an iterative loop between the script and a 3D EM simulator.

The script then plots the s11 magnitude (in dB) of both s-parameter files in the time domain to enable the tuning method.

The snag is that I can't seem to achieve time domain s11 plots with enough resolution as would be expected from the time domain transform on a network anaylser (see plots below).

Time Domain BPF Tuning.png

What I need to see is a plot similar to this:

J Dunsmore PhD Thesis p26.png
Any ideas on how I can achieve this/where I'm going wrong?

Cheers,

Nath

vinc0110

unread,
Jan 22, 2023, 11:35:19 AMJan 22
to scikit-rf
Hi Nath,

one thing I noticed is the very different time span in your time plots compared to your textbook example below that: your time span is 9 ns (from -3 ns to 6 ns), the textbook plot has 60 ns (from -10 ns to 50 ns).

The time resolution depends on the frequency span and the time span depends on the frequency resolution: dt = 1 / f_span and t_span = 1 / df.

Try increasing the frequency resolution to get a larger time span.

Regards, Vincent

Nathan Meddings

unread,
Jan 22, 2023, 3:17:10 PMJan 22
to scikit-rf
Hi Vincent,

Thanks for your quick reply.

I completely agree with your analysis and it is becoming apparent to me that for bandpass filter tuning (which is admittedly a bit of a special case) interpolation of the time domain transform s11 result is needed.

So, for the text book example above (from Joel Dunsmore's* PhD thesis on the bandpass filter tuning method p26) the frequency span is 320 MHz which means the IFFT output resolution is 3.125 ns.

But, examination of the corresponding time domain response shows that the resolution is far finer than 3.125 ns which suggests interpolation of the time domain response is needed prior to plotting which is what happens in networks analysers with time domain as an option.

Since the time domain transform of the frequency domain s11 of a bandpass filter results in a response which is full of peaks and nulls, curve fitting the IFFT s11 output data is not going to work well!

Therefore, the IFFT s11 output data needs to be converted to a linear quantity (e.g. reflection coefficient or scalar input impedance) first which will have a much smoother response which can then be curve fitted much more closely.

This curve-fitted data can then finally be converted to time domain s11 to give a time-domain response like the text book example.

The problem I'm having is trying to implement this since the other network time domain methods in scikit-rf all seem to involve convolution with an impulse to derive TDR-like responses which is not the same as simply performing an IFFT on s11 data.

The only two methods that give the result I need (plot_s_db_time() and plot_s_time_db()) are both plotting methods and so I can't seem to get hold of the output data to implement the interpolation.

Does that explain my challenge a bit better?

Cheers,

Nath

*For those that don't know him he's a top Jedi at Keysight.

vinc0110

unread,
Jan 23, 2023, 2:23:55 PMJan 23
to scikit-rf
Hi Nath,

your message does not quite make sense to me, I'm sorry! If I understood correctly, you want to increase the resolution in the time domain to be able to see the nulls. Again, you can do that by increasing the frequency span. I don't see the need for interpolation or curve fitting.

Maybe it's better to discuss a real example. See this these four cases with the same 3rd order Chebyshev bandpass (code below).

Regards, Vincent

Case 1:
bandpass_2GHz_1MHz.png
Case 2:
bandpass_2GHz_10MHz.png
Case 3:
bandpass_20GHz_10MHz.png
Case 4:
bandpass_20GHz_100MHz.png


import matplotlib.pyplot as mplt
import skrf

c1 = 1.729e-12
c2 = 9.172e-12
c3 = c1
l1 = 24.42e-9
l2 = 4.603e-9
l3 = l1

freq = skrf.Frequency(start=100e6, stop=20.1e9, unit='Hz', npoints=2001)

f_span = freq.span
df = freq.df[0]
t_span = 1 / df

dt = 1 / f_span

tl_media = skrf.DefinedGammaZ0(freq, z0=50, gamma=1j*freq.w/skrf.c)

nw_c1 = tl_media.capacitor(c1, name='C1')
nw_c2 = tl_media.capacitor(c2, name='C2')
nw_c3 = tl_media.capacitor(c3, name='C3')
nw_l1 = tl_media.inductor(l1, name='L1')
nw_l2 = tl_media.inductor(l2, name='L2')
nw_l3 = tl_media.inductor(l3, name='L3')
nw_gnd = skrf.Circuit.Ground(freq, name='GND')
nw_port1 = skrf.Circuit.Port(freq, name='port1', z0=50)
nw_port2 = skrf.Circuit.Port(freq, name='port2', z0=50)

netlist = [[(nw_port1, 0), (nw_l1, 0)],
[(nw_l1, 1), (nw_c1, 0)],
[(nw_c1, 1), (nw_l2, 1), (nw_c2, 1), (nw_c3, 0)],
[(nw_c3, 1), (nw_l3, 0)],
[(nw_l3, 1), (nw_port2, 0)],
[(nw_l2, 0), (nw_c2, 0), (nw_gnd, 0)]]
cir = skrf.Circuit(netlist)
nw_bandpass = cir.network.extrapolate_to_dc()

fig, ax = mplt.subplots(2, 1)
ax[0].set_title(f'f_span = {f_span * 1e-6} MHz, df = {df * 1e-6} MHz')
ax[1].set_title(f't_span = {t_span * 1e9} ns, dt = {dt * 1e9} ns')
nw_bandpass.plot_s_db(0, 0, ax=ax[0])
nw_bandpass.plot_s_db(1, 0, ax=ax[0])
nw_bandpass.plot_s_time_db(0, 0, ax=ax[1])
mplt.tight_layout()
mplt.show()

Nathan Meddings

unread,
Jan 26, 2023, 1:11:13 PMJan 26
to scikit-rf
Hi Vincent,

Many thanks for the plots and code, although it looks like it's more complicated than that unfortunately...

Joel Dunsmore's PhD thesis explains things a bit better - see section 3.2.1 (p50) onwards for more details.

In essence, the IFFT is not the tool for the job since the output resolution is limited to 1/Fspan whereas other transform methods provide much finer time resolution suitable for tuning band-pass filters in the time-domain.

So, it's back to school for me and hopefully the scipy library has the functions I need.

Cheers,

Nath

vinc0110

unread,
Jan 26, 2023, 4:34:25 PMJan 26
to scikit-rf
In my opinion, the good old IFFT as implemented in scikit-rf is enough. But it's obviously for you to decide what works for your application and what doesn't. It would be interesting to learn what exactly you want to achieve and why it does not work with scikit-rf.

One final attempt to convince you (or at least understand your problem), then I'll let it go:

I did not fully read Joel's thesis and only browsed through, but I think the basic idea is to tune the filter elements so they create distinct notches/nulls in the time domain response of S11. Although the step-by-step tuning process as outlined in Table 4-1 of the thesis did not work for me, the general concept can be demonstrated in scikit-rf with the example from my last message. The discrepancy probably has to do with what Joel calls "VNA time-domain response", which he uses for his examples, and which is different from the regular impulse response obtained from an IFFT. See his Figure 5-6.

I tried another 3rd order bandpass, this time with much smaller bandwidth, similar to Figure 4-16 in the thesis. The frequency settings (and resulting time-domain settings) are printed in the figures; I used start=100e6, stop=2.1e9, npoints=1001 for the frequency, but I manually decreased the plotted frequency range for visibility. As you see, the characteristic notches in the time-domain are clearly visible for the tuned filter and they fade away as the filter gets out of tune.

Case 1 - Tuned:
c1 = 132.8e-15
c2 = 121.7e-12
c3 = c1
l1 = 273.6e-9
l2 = 298.5e-12
l3 = l1
bandpass_tuned.png

Case 2 - slightly detuned:
c1 = 140e-15
c2 = 120e-12
c3 = c1
l1 = 250e-9
l2 = 300e-12
l3 = l1
bandpass_detuned.png

Case 3 - totally detuned:
c1 = 100e-15
c2 = 100e-12
c3 = c1
l1 = 200e-9
l2 = 400e-12
l3 = l1
bandpass_totallydetuned.png
Reply all
Reply to author
Forward
0 new messages