Ejemplo n.º 1
0
    def test_2ports_complex_characteristic_impedance(self):
        '''
        Connect two 2-ports networks in a resulting  2-ports network,
        same complex charact impedance (1+1j) for all ports
        '''
        z0 = 1 + 1j
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(4).reshape(2, 2)
        a.z0 = z0

        b = rf.Network(name='b')
        b.frequency = freq
        b.s = np.random.rand(4).reshape(2, 2)
        b.z0 = z0

        # classic connecting
        c = rf.connect(a, 1, b, 0)

        # Circuit connecting
        port1 = rf.Circuit.Port(freq, z0=z0, name='port1')
        port2 = rf.Circuit.Port(freq, z0=z0, name='port2')

        connections = [[(port1, 0), (a, 0)],
                       [(a, 1), (b, 0)],
                       [(b, 1), (port2, 0)]]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(c.s, circuit.s_external)
Ejemplo n.º 2
0
    def test_2ports_different_characteristic_impedances(self):
        '''
        Connect two 2-ports networks in a resulting  2-ports network,
        different characteristic impedances for each network ports
        '''
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(4).reshape(2,2)
        a.z0 = [1, 2]  #  Z0 should never be zero

        b = rf.Network(name='b')
        b.frequency = freq
        b.s = np.random.rand(4).reshape(2,2)
        b.z0 = [11, 12]

        # classic connecting
        c = rf.connect(a, 1, b, 0)

        # Circuit connecting
        port1 = rf.Circuit.Port(freq, z0=1, name='port1')
        port2 = rf.Circuit.Port(freq, z0=12, name='port2')

        connections = [[(port1, 0), (a, 0)],
                       [(a, 1), (b, 0)],
                       [(b, 1), (port2, 0)] ]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(c.s, circuit.s_external)
Ejemplo n.º 3
0
    def test_4ports_different_characteristic_impedances(self):
        """
        Connect two 4-ports networks in a resulting 4-ports network,
        with different characteristic impedances
        """
        z0 = [1, 2, 3, 4]
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(16).reshape(4, 4)
        a.z0 = z0

        b = rf.Network(name='b')
        b.frequency = freq
        b.s = np.random.rand(16).reshape(4, 4)
        b.z0 = [11, 12, 13, 14]

        # classic connecting
        _c = rf.connect(a, 2, b, 0)
        c = rf.innerconnect(_c, 2, 3)

        # Circuit connecting
        port1 = rf.Circuit.Port(freq, z0=1, name='port1')
        port2 = rf.Circuit.Port(freq, z0=2, name='port2')
        port3 = rf.Circuit.Port(freq, z0=13, name='port3')
        port4 = rf.Circuit.Port(freq, z0=14, name='port4')

        connections = [[(port1, 0), (a, 0)], [(port2, 0), (a, 1)],
                       [(a, 2), (b, 0)], [(a, 3), (b, 1)], [(b, 2),
                                                            (port3, 0)],
                       [(b, 3), (port4, 0)]]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(c.s, circuit.s_external)
Ejemplo n.º 4
0
    def test_4ports_complex_characteristic_impedances(self):
        '''
        Connect two 4-ports networks in a resulting 4-ports network,
        with same complex characteric impedances
        '''
        z0 = 5 + 4j
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(16).reshape(4, 4)
        a.z0 = z0

        b = rf.Network(name='b')
        b.frequency = freq
        b.s = np.random.rand(16).reshape(4, 4)
        b.z0 = z0

        # classic connecting
        c = rf.connect(a, 2, b, 0, 2)

        # circuit connecting
        port1 = rf.Circuit.Port(freq, z0=z0, name='port1')
        port2 = rf.Circuit.Port(freq, z0=z0, name='port2')
        port3 = rf.Circuit.Port(freq, z0=z0, name='port3')
        port4 = rf.Circuit.Port(freq, z0=z0, name='port4')

        connections = [ [(port1, 0), (a, 0)],
                        [(port2, 0), (a, 1)],
                        [(a, 2), (b, 0)],
                        [(a, 3), (b, 1)],
                        [(b, 2), (port3, 0)],
                        [(b, 3), (port4, 0)]]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(c.s, circuit.s_external)
Ejemplo n.º 5
0
    def setUp(self):
        # setup a test transmission line randomly excited
        self.P_f = np.random.rand()  # forward power in Watt
        self.phase_f = np.random.rand()  # forward phase in rad
        self.Z = np.random.rand(
        )  # source internal impedance, line characteristic impedance and load impedance
        self.L = np.random.rand()  # line length in [m]
        self.freq = rf.Frequency(1, 10, 10, unit='GHz')
        self.line_media = rf.media.DefinedGammaZ0(
            self.freq, z0=self.Z)  # lossless line medium
        self.line = self.line_media.line(
            d=self.L, unit='m', name='line')  # transmission line Network

        # forward voltages and currents at the input of the test line
        self.V_in = np.sqrt(2 * self.Z * self.P_f) * np.exp(1j * self.phase_f)
        self.I_in = np.sqrt(2 * self.P_f / self.Z) * np.exp(1j * self.phase_f)
        # forward voltages and currents at the output of the test line
        theta = rf.theta(self.line_media.gamma, self.freq.f,
                         self.L)  # electrical length
        self.V_out, self.I_out = rf.tlineFunctions.voltage_current_propagation(
            self.V_in, self.I_in, self.Z, theta)

        # Equivalent model with Circuit
        port1 = rf.Circuit.Port(frequency=self.freq, name='port1', z0=self.Z)
        port2 = rf.Circuit.Port(frequency=self.freq, name='port2', z0=self.Z)
        cnx = [[(port1, 0), (self.line, 0)], [(port2, 0), (self.line, 1)]]
        self.crt = rf.Circuit(cnx)
        # power and phase arrays for Circuit.voltages() and currents()
        self.power = [self.P_f, 0]
        self.phase = [self.phase_f, 0]
Ejemplo n.º 6
0
    def test_shunt_element(self):
        '''
        Compare a shunt element network (here a capacitor) 
        '''
        freq = rf.Frequency(start=1, stop=2, npoints=101)
        line = rf.media.DefinedGammaZ0(frequency=freq, z0=50)
        # usual way
        cap_shunt_manual = line.shunt_capacitor(50e-12)
        
        # A Circuit way
        port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=50)
        port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=50)
        cap_shunt = line.capacitor(50e-12, name='cap_shunt')
        ground = rf.Circuit.Ground(frequency=freq, name='ground', z0=50)

        connections = [
            [(port1, 0), (cap_shunt, 0), (port2, 0)],
            [(cap_shunt, 1), (ground, 0)]
        ]
        
        # # Another possibility could have been without ground :
        # shunt_cap = line.shunt_capacitor(50e-12)
        # shunt_cap.name='shunt_cap'
        # connections = [
        #     [(port1, 0), (shunt_cap, 0)],
        #     [(shunt_cap ,1), (port2, 0)]
        # ]
        
        cap_shunt_from_circuit = rf.Circuit(connections).network

        assert_array_almost_equal(cap_shunt_manual.s, cap_shunt_from_circuit.s)
Ejemplo n.º 7
0
    def test_1port_short(self):
        """
        Connect a short directly to the port
        """
        freq = rf.Frequency(start=1, npoints=1)
        port1 = rf.Circuit.Port(freq, name='port1')
        line = rf.media.DefinedGammaZ0(frequency=freq)
        short = line.short(name='short')
        gnd1 = rf.Circuit.Ground(freq, name='gnd')
        # method 1 : use the Ground Network (which 2 port actually)
        cnx = [[(port1, 0), (gnd1, 0)]]
        cir = rf.Circuit(cnx)
        assert_array_almost_equal(short.s, cir.s_external)
        # method 2 : use a short Network (1 port)
        cnx = [[(port1, 0), (short, 0)]]
        cir = rf.Circuit(cnx)

        assert_array_almost_equal(short.s, cir.s_external)
Ejemplo n.º 8
0
    def setUp(self):
        """
        Circuit setup
        """
        self.test_dir = os.path.dirname(os.path.abspath(__file__)) + '/'
        self.freq = rf.Frequency(start=1, stop=2, npoints=101)
        # characteristic impedance of the ports
        Z0_ports = 50

        # resistor
        self.R = 100
        self.line_resistor = rf.media.DefinedGammaZ0(frequency=self.freq,
                                                     Z0=self.R)
        self.resistor = self.line_resistor.resistor(self.R, name='resistor')

        # branches
        Z0_branches = np.sqrt(2) * Z0_ports
        self.line_branches = rf.media.DefinedGammaZ0(frequency=self.freq,
                                                     Z0=Z0_branches)
        self.branch1 = self.line_branches.line(90, unit='deg', name='branch1')
        self.branch2 = self.line_branches.line(90, unit='deg', name='branch2')

        # ports
        port1 = rf.Circuit.Port(self.freq, name='port1')
        port2 = rf.Circuit.Port(self.freq, name='port2')
        port3 = rf.Circuit.Port(self.freq, name='port3')

        # Connection setup
        self.connections = [[(port1, 0), (self.branch1, 0), (self.branch2, 0)],
                            [(port2, 0), (self.branch1, 1),
                             (self.resistor, 0)],
                            [(port3, 0), (self.branch2, 1),
                             (self.resistor, 1)]]

        self.C = rf.Circuit(self.connections)

        # theoretical results from ref P.Hallbjörner (2003)
        self.X1_nn = np.array([1 - np.sqrt(2), -1, -1]) / (1 + np.sqrt(2))
        self.X2_nn = np.array([
            1 - np.sqrt(2), -3 + np.sqrt(2), -1 - np.sqrt(2)
        ]) / (3 + np.sqrt(2))

        self.X1_m1 = 2 / (1 + np.sqrt(2))
        self.X1_m2 = np.sqrt(2) / (1 + np.sqrt(2))
        self.X1_m3 = np.sqrt(2) / (1 + np.sqrt(2))

        self.X2_m1 = 4 / (3 + np.sqrt(2))
        self.X2_m2 = 2 * np.sqrt(2) / (3 + np.sqrt(2))
        self.X2_m3 = 2 / (3 + np.sqrt(2))

        self.X1 = np.array([[0, self.X1_m2, self.X1_m3],
                            [self.X1_m1, 0, self.X1_m3],
                            [self.X1_m1, self.X1_m2, 0]]) + np.diag(self.X1_nn)
        self.X2 = np.array([[0, self.X2_m2, self.X2_m3],
                            [self.X2_m1, 0, self.X2_m3],
                            [self.X2_m1, self.X2_m2, 0]]) + np.diag(self.X2_nn)
Ejemplo n.º 9
0
    def test_cascade(self):
        '''
        Compare ntwk3 to the Circuit of ntwk1 and ntwk2.
        '''
        connections = [  [(self.port1, 0), (self.ntwk1, 0)],
                         [(self.ntwk1, 1), (self.ntwk2, 0)],
                         [(self.ntwk2, 1), (self.port2, 0)] ]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(circuit.s_external, self.ntwk3.s)
Ejemplo n.º 10
0
    def test_cascade2(self):
        '''
        Same thing with different ordering of the connections.
        Demonstrate that changing the connections setup order does not change
        the result.
        '''
        connections = [  [(self.port1, 0), (self.ntwk1, 0)],
                         [(self.ntwk2, 0), (self.ntwk1, 1)],
                         [(self.port2, 0), (self.ntwk2, 1)] ]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(circuit.s_external, self.ntwk3.s)
Ejemplo n.º 11
0
 def test_cascade3(self):
     '''
     Inverting the cascading network order
     Demonstrate that changing the connections setup order does not change
     the result (at the requirement that port impedance are the same).
     '''
     connections = [  [(self.port1, 0), (self.ntwk2, 0)],
                      [(self.ntwk2, 1), (self.ntwk1, 0)],
                      [(self.port2, 0), (self.ntwk1, 1)] ]
     circuit = rf.Circuit(connections)
     ntw = self.ntwk2 ** self.ntwk1
     assert_array_almost_equal(circuit.s_external, ntw.s)
Ejemplo n.º 12
0
 def test_s_active(self):
     '''
     Test the active s-parameter of a 2-ports network
     '''
     connections = [[(self.port1, 0), (self.ntwk1, 0)],
                    [(self.ntwk1, 1), (self.ntwk2, 0)],
                    [(self.ntwk2, 1), (self.port2, 0)]]
     circuit = rf.Circuit(connections)
     # s_act should be equal to s11 if a = [1,0]
     assert_array_almost_equal(circuit.s_active([1, 0])[:,0], circuit.s_external[:,0,0])
     # s_act should be equal to s22 if a = [0,1]
     assert_array_almost_equal(circuit.s_active([0, 1])[:,1], circuit.s_external[:,1,1])
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    def test_1port_matched_load(self):
        """
        Connect a matched load directly to the port
        """
        freq = rf.Frequency(start=1, npoints=1)
        port1 = rf.Circuit.Port(freq, name='port1')
        line = rf.media.DefinedGammaZ0(frequency=freq)
        match_load = line.match(name='match_load')

        cnx = [[(port1, 0), (match_load, 0)]]
        cir = rf.Circuit(cnx)

        assert_array_almost_equal(match_load.s, cir.s_external)
Ejemplo n.º 15
0
    def test_1port_random_load(self):
        """
        Connect a random load directly to the port
        """
        freq = rf.Frequency(start=1, npoints=1)
        port1 = rf.Circuit.Port(freq, name='port1')
        line = rf.media.DefinedGammaZ0(frequency=freq)
        gamma = np.random.rand(1, 1) + 1j * np.random.rand(1, 1)
        load = line.load(gamma, name='load')

        cnx = [[(port1, 0), (load, 0)]]
        cir = rf.Circuit(cnx)

        assert_array_almost_equal(load.s, cir.s_external)
Ejemplo n.º 16
0
    def test_1port_matched_network_default_impedance(self):
        '''
        Connect a 2 port network to a matched load
        '''
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(4).reshape(2, 2)
        line = rf.media.DefinedGammaZ0(frequency=freq)
        match_load = line.match(name='match_load')

        # classic connecting
        b = a ** match_load

        # Circuit connecting
        port1 = rf.Circuit.Port(freq,  name='port1')
        connections = [[(port1, 0), (a, 0)], [(a, 1), (match_load, 0)]]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(b.s, circuit.s_external)
Ejemplo n.º 17
0
    def setUp(self):
        """
        Dummy Circuit setup

        Setup a circuit which has various interconnections (2 or 3)
        """
        self.freq = rf.Frequency(start=1, stop=2, npoints=101)

        # dummy components
        self.R = 100
        self.line_resistor = rf.media.DefinedGammaZ0(frequency=self.freq,
                                                     Z0=self.R)
        resistor1 = self.line_resistor.resistor(self.R, name='resistor1')
        resistor2 = self.line_resistor.resistor(self.R, name='resistor2')
        resistor3 = self.line_resistor.resistor(self.R, name='resistor3')
        port1 = rf.Circuit.Port(self.freq, name='port1')

        # Connection setup
        self.connections = [[(port1, 0), (resistor1, 0), (resistor3, 0)],
                            [(resistor1, 1), (resistor2, 0)],
                            [(resistor2, 1), (resistor3, 1)]]

        self.C = rf.Circuit(self.connections)
Ejemplo n.º 18
0
    def test_1port_matched_network_complex_impedance(self):
        '''
        Connect a 2 port network to a complex impedance.
        Both ports are complex.
        '''
        z01, z02 = 1-1j, 2+4j
        freq = rf.Frequency(start=1, npoints=1)
        a = rf.Network(name='a')
        a.frequency = freq
        a.s = np.random.rand(4).reshape(2, 2)
        a.z0 = [z01, z02]
        line = rf.media.DefinedGammaZ0(frequency=freq, z0=z02)
        match_load = line.match(name='match_load')

        # classic connecting
        b = a ** match_load

        # Circuit connecting
        port1 = rf.Circuit.Port(freq, z0=z01, name='port1')
        connections = [[(port1, 0), (a,0)], [(a, 1), (match_load, 0)]]
        circuit = rf.Circuit(connections)

        assert_array_almost_equal(b.s, circuit.s_external)
Ejemplo n.º 19
0
    def variable_coupler_circuit(self, phase_deg):
        ps = self.phase_shifter(phase_deg)
        ps.name = 'ps'  # do not forget the name of the network !
        hybrid1, hybrid2 = self.hybrid('hybrid1'), self.hybrid('hybrid2')

        port1 = rf.Circuit.Port(ps.frequency, 'port1')
        port2 = rf.Circuit.Port(ps.frequency, 'port2')
        port3 = rf.Circuit.Port(ps.frequency, 'port3')
        port4 = rf.Circuit.Port(ps.frequency, 'port4')
        # Note that the order of port appearance is important.
        # 1st port to appear in the connection setup will be the 1st port (0),
        # then second to appear the second port (1), etc...
        # There is no constraint for the order of the connections.
        connections = [
                       [(port1, 0), (hybrid1, 3)],
                       [(port2, 0), (hybrid2, 2)],
                       [(port3, 0), (hybrid2, 1)],
                       [(port4, 0), (hybrid1, 0)],
                       [(hybrid1, 2), (ps, 0)],
                       [(hybrid1, 1), (hybrid2, 0)],
                       [(ps, 1), (hybrid2, 3)],
                      ]

        return rf.Circuit(connections)
Ejemplo n.º 20
0
    def setUp(self):
        self.f0 = rf.Frequency(75.8, npoints=1, unit='GHz')
        # initial s-param values of A 2 ports network
        self.s0 = np.array([  # dummy values 
            [-0.1000 -0.2000j, -0.3000 +0.4000j],
            [-0.3000 +0.4000j, 0.5000 -0.6000j]]).reshape(-1,2,2)

        # build initial network (under z0=50)
        self.ntw0 = rf.Network(frequency=self.f0, s=self.s0, z0=50, name='dut')

        # complex characteristic impedance to renormalize to
        self.zdut = 100 + 10j
        
        # reference solutions obtained from ANSYS Circuit or ADS (same res) 
        # when z0=[50, zdut]
        self.z_ref = np.array([  # not affected by z0
            [18.0000 -16.0000j, 20.0000 +40.0000j],
            [20.0000 +40.0000j, 10.0000 -80.0000j]]).reshape(-1,2,2)

        self.y_ref = np.array([  # not affected by z0
            [0.0251 +0.0023j, 0.0123 -0.0066j],
            [0.0123 -0.0066j, 0.0052 +0.0055j]]).reshape(-1,2,2)
        
        self.s_ref = np.array([  # renormalized s (power-waves)
            [-0.1374 -0.2957j, -0.1995 +0.5340j],
            [-0.1995 +0.5340j, -0.0464 -0.7006j]]).reshape(-1,2,2)

        # Creating equivalent reference circuit
        port1 = rf.Circuit.Port(self.f0, z0=50, name='port1')
        port2 = rf.Circuit.Port(self.f0, z0=50, name='port2')
        ntw0 = rf.Network(frequency=self.f0, z0=50, s=self.s0, name='dut')

        cnx = [  # z0=[50,50]
            [(port1, 0), (ntw0, 0)],
            [(ntw0, 1), (port2, 0)]
            ]
        self.cir = rf.Circuit(cnx)

        # Creating equivalent circuit with z0 real
        port2_real = rf.Circuit.Port(self.f0, z0=100, name='port2')
        cnx_real = [  # z0=[50,100]
            [(port1, 0), (ntw0, 0)],
            [(ntw0, 1), (port2_real, 0)]
            ]
        self.cir_real = rf.Circuit(cnx_real)

        # Creating equivalent circuit with z0 complex
        port2_complex = rf.Circuit.Port(self.f0, z0=self.zdut, name='port2')
        cnx_complex = [  # z0=[50,zdut]
            [(port1, 0), (ntw0, 0)],
            [(ntw0, 1), (port2_complex, 0)]
            ]
        self.cir_complex = rf.Circuit(cnx_complex)

        # references for each s-param definition
        self.s_legacy = rf.renormalize_s(self.s0, [50,50], [50,self.zdut],
                                         s_def='traveling')
        self.s_power = rf.renormalize_s(self.s0, [50,50], [50,self.zdut],
                                         s_def='power')
        self.s_pseudo = rf.renormalize_s(self.s0, [50,50], [50,self.zdut],
                                         s_def='pseudo')
        # for real values, should be = whatever s-param definition
        self.s_real = rf.renormalize_s(self.s0, [50,50], [50,100])
Ejemplo n.º 21
0
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]