def setUp(self): """ Initialize tests. """ # Touchstone files self.test_dir = os.path.dirname(os.path.abspath(__file__))+'/' self.ntwk1 = rf.Network(os.path.join(self.test_dir, 'ntwk1.s2p')) self.ntwk2 = rf.Network(os.path.join(self.test_dir, 'ntwk2.s2p')) self.ntwk3 = rf.Network(os.path.join(self.test_dir, 'ntwk3.s2p')) self.ntwk4 = rf.Network(os.path.join(self.test_dir, 'ntwk4.s2p')) # dummy networks of various frequency and port shapes self.freq1 = rf.Frequency(75, 110, 101, 'ghz') self.freq2 = rf.Frequency(75, 110, 201, 'ghz') self.ntwk_freq1_1p = rf.Network(frequency=self.freq1) self.ntwk_freq1_1p.s = np.random.rand(len(self.freq1), 1, 1) self.ntwk_freq1_2p = rf.Network(frequency=self.freq1) self.ntwk_freq1_2p.s = np.random.rand(len(self.freq1), 2, 2) self.ntwk_freq2_1p = rf.Network(frequency=self.freq2) self.ntwk_freq2_1p.s = np.random.rand(len(self.freq2), 1, 1) self.ntwk_freq2_2p = rf.Network(frequency=self.freq2) self.ntwk_freq2_2p.s = np.random.rand(len(self.freq2), 2, 2) # Test nominal self.ns = rf.NetworkSet([self.ntwk1, self.ntwk2, self.ntwk3])
def test_init_from_attenuation_VF_array_att(self): """ Test passing array as attenuation in the Coaxial classmethod `from_attenuation_VF_units`. """ # create a Coaxial media for frequency-dependant attenuation and # test the resulting alpha values (real part of gamma) frequency = rf.Frequency(start=1, stop=2, unit='GHz', npoints=101) # k0k1k2 attenuation model # values taken for HUBER+SUHNER DATA SHEET Coaxial Cable S_10172_B-1 # attenuation in dB/m for frequency in GHz att = 0 + 0.0826 * npy.sqrt( frequency.f_scaled) + 0.0129 * frequency.f_scaled coax = Coaxial.from_attenuation_VF(frequency=frequency, att=att, unit='dB/m') # check alpha in gamma assert_array_almost_equal(rf.db_2_np(att), coax.gamma.real) # if the attenuation array length does not match the frequency, # should raise a ValueError frequency2 = rf.Frequency(start=1, stop=2, unit='GHz', npoints=10) with self.assertRaises(ValueError): coax = Coaxial.from_attenuation_VF(frequency=frequency2, att=att)
def update_plot(self, change: dict): ''' Update the plot Parameters ---------- change : dict The change dictionary at least holds a 'type' key. https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Events.html#Traitlet-events Returns ------- None. ''' with self.output: if self.is_valid(): frequency = rf.Frequency(self.f_min, self.f_max, unit='MHz', npoints=501) plt.clf() # avoid superposing curves ntwk = self.to_network(frequency) ax = plt.gca() ax = plt.subplot(3, 1, 1) ax.plot(ntwk.frequency.f_scaled, ntwk.s_db.squeeze()) # find min and display f_match = ntwk.frequency.f_scaled[np.argmin(ntwk.s_mag)] ax.set_title(f'Match Freq: {f_match:0.2f} MHz') ax.set_ylim(-30, 1) f0 = self.f_vi # MHz frequency = rf.Frequency(f0, f0, unit='MHz', npoints=1) Pin = self.Pin * 1e3 # W L_left, L_right, V_left, V_right, I_left, I_right = self.voltage_current( frequency, Pin) # Voltages ax2 = plt.subplot(3, 1, 2) ax2.plot(L_right, np.abs(V_right) / 1e3) ax2.plot(-L_left, np.abs(V_left) / 1e3) ax2.set_ylim(0, 60) ax2.axhline(50, ls='--', color='gray') ax2.set_ylabel('V [kV]') ax2.set_xticks([]) ax2.set_xticks([], minor=True) # Currents ax3 = plt.subplot(3, 1, 3) ax3.plot(L_right, np.abs(I_right) / 1e3) ax3.plot(-L_left, np.abs(I_left) / 1e3) ax3.set_ylim(0, 4) ax3.set_ylabel('I [kA]') ax3.axhline(2.7, ls='--', color='gray')
def setUp(self): """ Initialize tests. """ # Touchstone files self.test_dir = os.path.dirname(os.path.abspath(__file__))+'/' self.ntwk1 = rf.Network(os.path.join(self.test_dir, 'ntwk1.s2p')) self.ntwk2 = rf.Network(os.path.join(self.test_dir, 'ntwk2.s2p')) self.ntwk3 = rf.Network(os.path.join(self.test_dir, 'ntwk3.s2p')) self.ntwk4 = rf.Network(os.path.join(self.test_dir, 'ntwk4.s2p')) # dummy networks of various frequency and port shapes self.freq1 = rf.Frequency(75, 110, 101, 'ghz') self.freq2 = rf.Frequency(75, 110, 201, 'ghz') self.ntwk_freq1_1p = rf.Network(frequency=self.freq1) self.ntwk_freq1_1p.s = np.random.rand(len(self.freq1), 1, 1) self.ntwk_freq1_2p = rf.Network(frequency=self.freq1) self.ntwk_freq1_2p.s = np.random.rand(len(self.freq1), 2, 2) self.ntwk_freq2_1p = rf.Network(frequency=self.freq2) self.ntwk_freq2_1p.s = np.random.rand(len(self.freq2), 1, 1) self.ntwk_freq2_2p = rf.Network(frequency=self.freq2) self.ntwk_freq2_2p.s = np.random.rand(len(self.freq2), 2, 2) # dummy networks with associated parameters # total number of different networks self.params = [ {'a':0, 'X':10, 'c':'A'}, {'a':1, 'X':10, 'c':'A'}, {'a':2, 'X':10, 'c':'A'}, {'a':1, 'X':20, 'c':'A'}, {'a':0, 'X':20, 'c':'A'}, ] # for write_mdif self.params_datatypes = {'a': 'int', 'X': 'double', 'c': 'string'} # create M dummy networks self.ntwks_params = [rf.Network(frequency=self.freq1, s=np.random.rand(len(self.freq1),2,2), name=f'ntwk_{m}', comment=f'ntwk_{m}', params=params) \ for (m, params) in enumerate(self.params) ] # Test nominal self.ns = rf.NetworkSet([self.ntwk1, self.ntwk2, self.ntwk3]) # Create NetworkSet from a list of Network containing a .params dict parameters self.ns_params = rf.NetworkSet(self.ntwks_params)
def test_IEEEP370_interpolation_not_implemented(self): """ Test if IEEEP370 methods fails when interpolation is required. TODO: add interpolation handling """ self.s2xthru = rf.Network(os.path.join(self.test_dir, 's2xthru.s2p')) self.fdf = rf.Network(os.path.join(self.test_dir, 'fdf.s2p')) # with non-uniform frequencies nonuniform_freq = rf.Frequency(self.s2xthru.f[0], self.s2xthru.f[-1], npoints=len(self.s2xthru), unit='Hz', sweep_type='log') self.s2xthru_nu = self.s2xthru.interpolate(nonuniform_freq) self.fdf_nu = self.fdf.interpolate(nonuniform_freq) with self.assertRaises(NotImplementedError) as context: self.dm_nzc_nu = rf.IEEEP370_SE_NZC_2xThru( dummy_2xthru=self.s2xthru_nu, name='2xthru') self.dm_zc_nu = rf.IEEEP370_SE_ZC_2xThru( dummy_2xthru=self.s2xthru_nu, dummy_fix_dut_fix=self.fdf_nu, bandwidth_limit=10e9, pullback1=0, pullback2=0, leadin=0, NRP_enable=False, name='zc2xthru')
def generateThru(): IL = 0.001 RL = 0.001 S = np.array([[RL, 1 - IL], [1 - IL, RL]]) N = skrf.Network(frequency=skrf.Frequency(0, 1e12, 2), s=np.broadcast_to(S, (2, 2, 2))) return N
def test_sparam_conversion_vs_sdefinition(self): ''' Check that power-wave or pseudo-waves scattering parameters definitions give same results for real characteristic impedances ''' f0 = rf.Frequency(75.8, npoints=1, unit='GHz') s_ref = npy.array([[ # random values [-0.1000 -0.2000j, -0.3000 +0.4000j], [-0.3000 +0.4000j, 0.5000 -0.6000j]]]) ntw = rf.Network(frequency=f0, s=s_ref, z0=50, name='dut') # renormalize s parameter according one of the definition. # As characteristic impedances are all real, should be all equal npy.testing.assert_allclose(ntw.s, s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='power'), s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='pseudo'), s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='traveling'), s_ref) # also check Z and Y matrices, just in case z_ref = npy.array([[ [18.0000 -16.0000j, 20.0000 + 40.0000j], [20.0000 +40.0000j, 10.0000 -80.0000j]]]) npy.testing.assert_allclose(ntw.z, z_ref, atol=1e-4) y_ref = npy.array([[ [0.0251 +0.0023j, 0.0123 -0.0066j], [0.0123 -0.0066j, 0.0052 +0.0055j]]]) npy.testing.assert_allclose(ntw.y, y_ref, atol=1e-4) # creating network by specifying s-params definition ntw_power = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='power') ntw_pseudo = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='pseudo') ntw_legacy = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='traveling') self.assertTrue(ntw_power == ntw_pseudo) self.assertTrue(ntw_power == ntw_legacy)
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)
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)
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]
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 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)
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)
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)
def setUp(self): self.frequency = rf.Frequency(75,110,101,'ghz') self.media = rf.media.CPW(\ frequency=self.frequency, w=10e-6, s=5e-6, ep_r=11.7, t=1e-6, rho=22e-9)
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)
def measureSParam(self, result): self.device.write(":INITIATE:IMMEDIATE") self.device.query("*OPC?") asc = self.device.query_ascii_values("CALC1:DATA? SDAT") stm = self.device.query_ascii_values("CALC1:DATA:STIM?") self.device.write("DISP:WINDOW1:TRACE1:Y:AUTO ONCE") reSparam = asc[::2] imSparam = asc[1::2] result['freq'] = rf.Frequency(stm[0], stm[-1], len(stm), 'hz') result['Sparam'] = [x + y * 1j for x, y in zip(reSparam, imSparam)]
def init_antenna(_): # Create antenna object for the given frequency span and number of points freq = rf.Frequency(start=frequency_range.value[0], stop=frequency_range.value[1], npoints=frequency_npoints.value, unit='MHz') Cs = [C1.value, C2.value, C3.value, C4.value] return WestIcrhAntenna(frequency=freq, front_face=front_face.value, Cs=Cs)
def setUp(self): ''' ''' self.files_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'qucs_prj') self.dummy_media = rf.media.Media( frequency=rf.Frequency(1, 100, 21, 'ghz'), propagation_constant=1j, characteristic_impedance=50, )
def test_all_networks_have_same_frequency(self): ''' Check that a Network with a different frequency than the other raises an exception ''' _ntwk1 = self.ntwk1.copy() connections = [[(self.port1, 0), (_ntwk1, 0)], [(_ntwk1, 1), (self.ntwk2, 0)], [(self.ntwk2, 1), (self.port2, 0)]] _ntwk1.frequency = rf.Frequency(start=1, stop=1, npoints=1) self.assertRaises(AttributeError, rf.Circuit, connections)
def calcNetworkStatistics(networks): logger = logging.getLogger() # Determine Overlapping frequency range and minimum step size freqMin = None freqMax = None freqStep = None for net in networks: if freqMin is None: freqMin = net.frequency.start else: if freqMin < net.frequency.start: freqMin = net.frequency.start if freqMax is None: freqMax = net.frequency.stop else: if freqMax > net.frequency.stop: freqMax = net.frequency.stop if freqStep is None: freqStep = net.frequency.step else: if freqStep < net.frequency.step: freqStep = net.frequency.step msg = 'Freq Min: {:g}, Max {:g}, Step {:g}'.format(freqMin, freqMax, freqStep) logger.debug(msg) print(msg) fStats = skrf.Frequency(freqMin, freqMax, (freqMax - freqMin) / freqStep + 1, 'Hz') fStats.unit = net.frequency.unit allS = [] for net in networks: netTemp = net.interpolate(fStats) allS.append(netTemp.s) dataAvg = skrf.network.Network() dataAvg.frequency = fStats ## Rectangular domain #dataAvg.s = np.mean(allS, axis=0) # Polar domain dataAvg.s = np.mean(np.abs(allS), axis=0) * np.exp( 1j * np.mean(np.unwrap(np.angle(allS), axis=0), axis=0)) dataAvg.name = 'Mean' return dataAvg
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)
def test_create_log_sweep(self): freq = rf.Frequency(1, 10, 10, 'ghz', sweep_type='log') #Check end points self.assertTrue((freq.f[0] == 1e9)) self.assertTrue((freq.f[-1] == 10e9)) spacing = [freq.f[i + 1] / freq.f[i] for i in range(len(freq.f) - 1)] #Check that frequency is increasing self.assertTrue(all(s > 1 for s in spacing)) #Check that ratio of adjacent frequency points is identical self.assertTrue( all( abs(spacing[i] - spacing[0]) < 1e-10 for i in range(len(spacing))))
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)
def test_R(self): freq = rf.Frequency(0, 100, 2) rho = 1e-7 dint = 0.44e-3 coax = Coaxial(freq, z0=50, Dint=dint, Dout=1.0e-3, sigma=1 / rho) dc_res = rho / (npy.pi * (dint / 2)**2) # Old R calculation valid only when skin depth is much smaller # then inner conductor radius R_simple = coax.Rs / (2 * npy.pi) * (1 / coax.a + 1 / coax.b) self.assertTrue(abs(1 - coax.R[0] / dc_res) < 1e-2) self.assertTrue(abs(1 - coax.R[1] / R_simple[1]) < 1e-2)
def test_init_from_attenuation_VF_units(self): """ Test the attenuation unit conversions in the Coaxial classmethod `from_attenuation_VF_units`. """ # create a dummy Coaxial media for various attenuation and test the # resulting alpha values (real part of gamma) frequency = rf.Frequency(npy.random.rand(), unit='GHz', npoints=1) _att = npy.random.rand() # dB/m coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='dB/m') assert_almost_equal(coax.gamma.real, rf.db_2_np(_att)) # dB/100m coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='dB/100m') assert_almost_equal(coax.gamma.real, rf.db_2_np(_att) / 100) # dB/feet coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='dB/feet') assert_almost_equal(coax.gamma.real, rf.db_2_np(_att) * rf.meter_2_feet()) # dB/100m coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='dB/100feet') assert_almost_equal(coax.gamma.real, rf.db_2_np(_att) / 100 * rf.meter_2_feet()) # Neper/m coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='Np/m') assert_almost_equal(coax.gamma.real, _att) # Neper/feet coax = Coaxial.from_attenuation_VF(frequency=frequency, VF=1, att=_att, unit='Np/feet') assert_almost_equal(coax.gamma.real, _att * rf.meter_2_feet())
def test_sparam_conversion_with_complex_char_impedance(self): ''' Renormalize a 2-port network wrt to complex characteristic impedances using power-waves definition of s-param Example based on scikit-rf issue #313 ''' f0 = rf.Frequency(75.8, npoints=1, unit='GHz') s0 = npy.array([[-0.194 - 0.228j, -0.721 + 0.160j], [-0.721 + 0.160j, +0.071 - 0.204j]]) ntw = rf.Network(frequency=f0, s=s0, z0=50, name='dut') # complex characteristic impedance to renormalize to zdut = 100 + 10j # reference solutions obtained from ANSYS Circuit or ADS (same res) # case 1: z0=[50, zdut] s_ref = npy.array( [[[-0.01629813 - 0.29764199j, -0.6726785 + 0.24747539j], [-0.6726785 + 0.24747539j, -0.30104687 - 0.10693578j]]]) npy.testing.assert_allclose(rf.z2s(ntw.z, z0=[50, zdut]), s_ref) npy.testing.assert_allclose( rf.renormalize_s(ntw.s, [50, 50], [50, zdut]), s_ref) # case 2: z0=[zdut, zdut] s_ref = npy.array([[[ -0.402829859501534 - 0.165007172677339j, -0.586542065592524 + 0.336098534178339j ], [ -0.586542065592524 + 0.336098534178339j, -0.164707376748782 - 0.21617153431756j ]]]) npy.testing.assert_allclose(rf.z2s(ntw.z, z0=[zdut, zdut]), s_ref) npy.testing.assert_allclose( rf.renormalize_s(ntw.s, [50, 50], [zdut, zdut]), s_ref) # Compararing Z and Y matrices from reference ones (from ADS) # Z or Y matrices do not depend of characteristic impedances. # Precision is 1e-4 due to rounded results in ADS export files z_ref = npy.array([[[34.1507 - 65.6786j, -37.7994 + 73.7669j], [-37.7994 + 73.7669j, 55.2001 - 86.8618j]]]) npy.testing.assert_allclose(ntw.z, z_ref, atol=1e-4) y_ref = npy.array([[[0.0926 + 0.0368j, 0.0770 + 0.0226j], [0.0770 + 0.0226j, 0.0686 + 0.0206j]]]) npy.testing.assert_allclose(ntw.y, y_ref, atol=1e-4)
def setUp(self): ''' this also tests the ability to read touchstone files without an error ''' setup_pylab() self.test_dir = os.path.dirname(os.path.abspath(__file__)) + '/' self.ntwk1 = rf.Network(os.path.join(self.test_dir, 'ntwk1.s2p')) self.ntwk2 = rf.Network(os.path.join(self.test_dir, 'ntwk2.s2p')) self.ntwk3 = rf.Network(os.path.join(self.test_dir, 'ntwk3.s2p')) self.freq = rf.Frequency(75, 110, 101, 'ghz') self.cpw = CPW(self.freq, w=10e-6, s=5e-6, ep_r=10.6) l1 = self.cpw.line(0.20, 'm', z0=50) l2 = self.cpw.line(0.07, 'm', z0=50) l3 = self.cpw.line(0.47, 'm', z0=50) self.Fix = rf.concat_ports([l1, l1, l1, l1]) self.DUT = rf.concat_ports([l2, l2, l2, l2]) self.Meas = rf.concat_ports([l3, l3, l3, l3])
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)
def setUp(self): self.files_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'qucs_prj') fname = os.path.join(self.files_dir, 'cpw.s2p') self.qucs_ntwk = rf.Network(fname) # create various examples self.freq = rf.Frequency(start=1, stop=20, npoints=21, unit='GHz') # infinite dielectric substrate, infinitely thin metal self.cpw1 = CPW(frequency=self.freq, w=40e-6, s=20e-6, ep_r=3) # infinite GaAs substrate, infinitely thin metal self.cpw2 = CPW(frequency=self.freq, w=75e-6, s=50e-6, ep_r=12.9) # infinite GaAs substrate, finite metal thickness # TODO: not used yet self.cpw3 = CPW(frequency=self.freq, w=75e-6, s=50e-6, ep_r=12.9, t=1e-6)