def test_connect_nport_2port(self): freq = rf.Frequency(1, 10, npoints=10, unit='GHz') # create a line which can be connected to each port med = rf.DefinedGammaZ0(freq) line = med.line(1, unit='m') line.z0 = [10, 20] for nport_portnum in [3,4,5,6,7,8]: # create a Nport network with port impedance i at port i nport = rf.Network() nport.frequency = freq nport.s = npy.zeros((10, nport_portnum, nport_portnum)) nport.z0 = npy.arange(nport_portnum) # Connect the line to each port and check for port impedance for port in range(nport_portnum): nport_line = rf.connect(nport, port, line, 0) z0_expected = nport.z0 z0_expected[:,port] = line.z0[:,1] npy.testing.assert_allclose( nport_line.z0, z0_expected )
def to_network(self, skrf_frequency: rf.Frequency, name: str = 'front-face') -> rf.Network: """Convert into a skrf Network. Assume the scattering parameters of the network are the same for all the frequencies of the network. Parameters ---------- skrf_frequency : :class:`skrf.frequency.Frequency` Frequency of the network (for compatibility with skrf) name : string, optional name of the network. Default is 'front-face' Returns ------- network : :class:`skrf.network.Network` """ network = rf.Network(name=name) network.s = np.tile(self.s, (len(skrf_frequency), 1, 1)) network.z0 = self.z0 network.frequency = skrf_frequency # take into deembbeding if necessary if self._deemb != 0: # create a coaxial line of length = deemb coax_media = rf.DefinedGammaZ0(network.frequency, z0=self.z0) # Create a circuit in which we connect the inverse of the coaxial # lines to each ports coax1 = coax_media.line(d=self._deemb, unit='m', name='line1').inv coax2 = coax_media.line(d=self._deemb, unit='m', name='line2').inv coax3 = coax_media.line(d=self._deemb, unit='m', name='line3').inv coax4 = coax_media.line(d=self._deemb, unit='m', name='line4').inv port1 = rf.Circuit.Port(network.frequency, 'port1', z0=self.z0) port2 = rf.Circuit.Port(network.frequency, 'port2', z0=self.z0) port3 = rf.Circuit.Port(network.frequency, 'port3', z0=self.z0) port4 = rf.Circuit.Port(network.frequency, 'port4', z0=self.z0) cnx = [ [(port1, 0), (coax1, 0)], [(coax1, 1), (network, 0)], [(port2, 0), (coax2, 0)], [(coax2, 1), (network, 1)], [(port3, 0), (coax3, 0)], [(coax3, 1), (network, 2)], [(port4, 0), (coax4, 0)], [(coax4, 1), (network, 3)], ] network = rf.Circuit(cnx).network.copy() return (network)
def setUp(self): self.freq = rf.Frequency(start=1, stop=2, npoints=101) self.media = rf.DefinedGammaZ0(self.freq)
def RLC2S_LPF(g, Wstart, Wstop, npoints=1001, dB_limit=-100, ladder_type="LC", W=True, plot=False): """ Function to plot S21 and S11 from g parameters. Main purpose of this function is to ensure that the g values are indeed correct. @param g: g parameters as a list [g_0, g_1, ..., g_{n+1}] @param start: starting frequency (avoid 0) @param stop: stop frequency @param npoints: number of points for plotting purpose """ if not ladder_type == "LC": warn("ladder_type must be LC for the time being") return freq = rf.Frequency(start=Wstart / (2 * pi), stop=Wstop / (2 * pi), unit="Hz", npoints=npoints) tl_media = rf.DefinedGammaZ0(freq, z0=1, gamma=1j * freq.w / rf.c) # GND and port elements gnd = rf.Circuit.Ground(freq, name="gnd") port1 = rf.Circuit.Port(freq, name="port1", z0=g[0]) port2 = rf.Circuit.Port(freq, name="port2", z0=g[-1]) g = g[1:-1] # L and C elements for LC ladder ckt_elements = [] ind_flag = True # L starts first for i in range(len(g)): ckt_elements.append(tl_media.inductor( g[i], name=str(i))) if ind_flag else ckt_elements.append( tl_media.capacitor(g[i], name=str(i))) ind_flag = not ind_flag # toggle between inductors and cpacitors # node connections cnx = [] for i in range(int(len(g) / 2) + 1): if i == 0: cnx.append([(port1, 0), (ckt_elements[i], 0)]) # starting elif i == int(len(g) / 2): if int(len(g)) % 2 == 0: # ending ... even order case cnx.append([ (ckt_elements[2 * i - 2], 1), (ckt_elements[2 * i - 1], 0), (port2, 0), ]) else: # ending ... odd order case cnx.append([ (ckt_elements[2 * i - 2], 1), (ckt_elements[2 * i - 1], 0), (ckt_elements[2 * i], 0), ]) cnx.append([ (ckt_elements[2 * i], 1), (port2, 0), ]) else: # in between cnx.append([ (ckt_elements[2 * i - 2], 1), (ckt_elements[2 * i - 1], 0), (ckt_elements[2 * i], 0), ]) # GND connections ... same for even and odd cases gnd_cnx = [] for i in range(int(len(g) / 2) + 1): if i == 0: gnd_cnx.append((gnd, 0)) elif i == int(len(g) / 2): gnd_cnx.append((ckt_elements[2 * i - 1], 1)) else: gnd_cnx.append((ckt_elements[2 * i - 1], 1)) cnx.append(gnd_cnx) # create a circuit out of all the elements and connections cir = rf.Circuit(cnx) ntw = cir.network freq = 2 * pi * ntw.frequency.f if W else ntw.frequency.f if plot: title = ("Transfer Functions vs Angular Frequency" if W else "Transfer Functions vs Frequency") xlabel = "w" if W else "f" ylabel = "|H(w)|" if W else "|H(f)|" rf.plotting.plot_rectangular( freq, cutoff(rf.mathFunctions.complex2dB(ntw.s[:, 1, 0]), dB_limit), x_label=xlabel, y_label=ylabel, title=title, show_legend=True, label="S21", ) rf.plotting.plot_rectangular( freq, cutoff(rf.mathFunctions.complex2dB(ntw.s[:, 0, 0]), dB_limit), label="S11", ) if not (port1.z0[0] == port2.z0[0]): warn("port2 and port2 impedances are not equal") s_ax = plt.gca() s_ax.axvspan(0, 1, facecolor="r", alpha=0.2) s_ax.axhspan(0, -3, facecolor="g", alpha=0.2) # s_ax.axvspan(0, 1.6, facecolor="r", alpha=0.2) plt.show() return freq, ntw.s[:, 0, 0], ntw.s[:, 1, 0]