def _sweep_oneport(self, fstart, fstop, points, navg, port): sw = self.sweep(fstart, fstop, points, navg=navg) return rf.Network(f=sw.f / 1e9, z0=sw.z0, s=sw.s[:, port, port])
def test_open_saved_touchstone(self): self.ntwk1.write_touchstone('ntwk1Saved',dir=self.test_dir) ntwk1Saved = rf.Network(os.path.join(self.test_dir, 'ntwk1Saved.s2p')) self.assertEqual(self.ntwk1, ntwk1Saved) os.remove(os.path.join(self.test_dir, 'ntwk1Saved.s2p'))
def Q(basepath): ListofFiles = [] DataToSave = [] ResonantFrequencyGHz = [] PlotDataListReflection = [] PlotDataListWCCFX = [] TheCorrectedSparameter = [] testoveoti = [] o = 0 for entry in os.listdir(basepath): if entry.endswith(".s2p") or entry.endswith(".S2P"): o += 1 if os.path.isfile(os.path.join(basepath, entry)): ListofFiles.append(entry) print(str(o) + '. ' + entry) Dict.ListofFiles = ListofFiles ############################################################### #### Prepare the Files into Network Files ############################################################### NetworkList = [] for touchstone in ListofFiles: ring_slot = rf.Network(os.path.join(basepath, touchstone)) NetworkList.append(ring_slot) ############################################################### #### Prepare the Network Files into a Panda Dataframe ############################################################### DataFrameList = [] for networkentry in NetworkList: df = networkentry.to_dataframe() DataFrameList.append(df) print("All Data Loaded") print("Number of elements " + str(len(ListofFiles))) ############################################################### #### Determination of Resonant Frequency ############################################################### print("Starting Determination of Resonant Frequency") for df in DataFrameList: ResonantFrequencyGHz.append(Lorentz(df)) time.sleep(0.2) print('Resonances') print(ResonantFrequencyGHz) print("Determination of Resonant Frequency Finished") ############################################################### #### Determination of Delta and Complex Circle Fit ############################################################### print("Starting Weighted Complex Circle Fit") WCCFXList = [] PlotDataList = [] AnotherBar = IncrementalBar(max=len(NetworkList)) PercentageList = [] for number in range(len(NetworkList)): [S11, S21, S12, S22, tau] = PhaseUnwrappingCorrection(NetworkList[number], DataFrameList[number]) AnotherBar.next() print(ListofFiles[number]) [fres, Ql, reals21, imags21, realwcs21, imagwcs21, Percantage ] = ComplexFit(NetworkList[number], ResonantFrequencyGHz[number], DataFrameList[number], ListofFiles[number], S21[0]) WCCFXList.append((fres, Ql)) PercentageList.append(Percantage) PlotDataListWCCFX.append((reals21, imags21, realwcs21, imagwcs21)) AnotherBar.finish() print(WCCFXList) print("Weighted Complex Circle Fit Finished") #################################################################################### #### Phase Corrections of DataFiles and Scalar Betas as well as new Beta Function #################################################################################### print("Starting Phase Correction") for net in range(len(NetworkList)): [S11, S21, S12, S22, tau] = PhaseUnwrappingCorrection(NetworkList[net], DataFrameList[net]) #[NonScalarBetas, re11, im11, xc11, yc11, xo11, yo11, re22, im22, xc22, yc22, xo22, yo22, f, S1111List, S2222List, S2121List] = BetaFunction(NetworkList[net], DataFrameList[net]) [ b1, b2, re11, im11, xc11, yc11, xo11, yo11, re22, im22, xc22, yc22, xo22, yo22, f, S1111List, S2222List, S2121List ] = BetaFunction(NetworkList[net], DataFrameList[net], S11[0], S22[0], S21[0], tau, 1, WCCFXList[net][0], WCCFXList[net][1]) #PlotDataListReflection.append(BetaFunction(NetworkList[net], DataFrameList[net],S11[net], S22[net], S21[net], tau, 1)) testoveoti.append((b1, b2)) PlotDataListReflection.append( (re11, im11, xc11, yc11, xo11, yo11, re22, im22, xc22, yc22, xo22, yo22, f, S1111List, S2222List, S2121List)) print(testoveoti) time.sleep(0.2) PlotDataList.append( (PlotDataListWCCFX[net][0], PlotDataListWCCFX[net][1], PlotDataListWCCFX[net][2], PlotDataListWCCFX[net][3], PlotDataListReflection[net][0], PlotDataListReflection[net][1], PlotDataListReflection[net][2], PlotDataListReflection[net][3], PlotDataListReflection[net][4], PlotDataListReflection[net][5], PlotDataListReflection[net][6], PlotDataListReflection[net][7], PlotDataListReflection[net][8], PlotDataListReflection[net][9], PlotDataListReflection[net][10], PlotDataListReflection[net][11], PlotDataListReflection[net][12], PlotDataListReflection[net][13], PlotDataListReflection[net][14], PlotDataListReflection[net][15])) print("Phase Correction Finished") Q0 = [] for value in range(len(NetworkList)): Q0.append(WCCFXList[value][1] * (1 + testoveoti[value][0] + testoveoti[value][1])) ############################################################### #### Prepare the Data to be stored in a file ############################################################### # # DataToSave.append( # np.column_stack( # ( # ListofFiles, # WCCFXList, # NonScalarBetas, # Q0,PercentageList # ) # ) # ) freq = [] quali = [] beta1 = [] beta2 = [] quali0 = [] prozent = [] for i in range(len(ListofFiles)): freq.append(WCCFXList[i][0]) quali.append(WCCFXList[i][1]) beta1.append(testoveoti[i][0]) beta2.append(testoveoti[i][1]) quali0.append(Q0[i]) prozent.append(PercentageList[i]) Data = { "Filenames": ListofFiles, "Resonant Frequency": freq, "Loaded Quality Factor": quali, "Coupling Factor S11": beta1, "Coupling Factor S22": beta2, "Unloaded Quality Factor": quali0, "Percentage of Data Removed": prozent } DataToSave = pd.DataFrame(Data) return ListofFiles, WCCFXList, PlotDataList, Q0, DataToSave
def test_constructor_empty(self): rf.Network()
def test_constructor_from_touchstone(self): rf.Network(os.path.join(self.test_dir, 'ntwk1.s2p'))
print("start:", fr_start, "stop:", fr_stop, "points:", points) sark110 = Sark110() sark110.open() sark110.connect() if not sark110.is_connected: print("Device not connected") exit(-1) else: print("Device connected") print(sark110.fw_protocol, sark110.fw_version) sark110.buzzer(1000, 800) y = [] x = [] rs = [0] xs = [0] for i in range(points): fr = int(fr_start + i * (fr_stop - fr_start) / (points - 1)) sark110.measure(fr, rs, xs) x.append(fr / 1e9) # Units in GHz y.append(z2gamma(rs[0][0], xs[0][0])) ring_slot = rf.Network(frequency=x, s=y, z0=50) ring_slot.plot_s_smith(draw_labels=True) print("\nDone !") sark110.close() exit(1)
@author: joslaton """ import skrf as rf import numpy as np import pandas as pd import matplotlib.pyplot as plt # %% 1 RF1_Path = r"****" RF2_Path = r"****" DUTpath = r"****" # %% 2 DUT = rf.Network(DUTpath) DUT.name = 'DUT' RF1 = rf.Network(RF1_Path).interpolate(DUT.frequency) RF2 = rf.Network(RF2_Path).interpolate(DUT.frequency) DUTd = RF1.inv**DUT**RF2.inv # %% 3 DUTd.name = 'DUTd' # %% 4 fig, axarr = plt.subplots(2, 2, sharex=True, figsize=(10, 6)) ax = axarr[0, 0] DUTd.plot_s_db(m=0, n=0, ls='-', ax=ax) DUT.plot_s_db(m=0, n=0, ax=ax, ls=':', color='0.0')
# Reads block data from the specified file location. ''' ###LOW POWER BLOCK from 13### ''' #Low Power Setting #open flashdrive path as bytes usbf_13L = open(sdir + lna_num + '_13L.s2p', 'rb') #PC path location path_low = dir + lna_num + '_13L.s2p' with open(path_low, 'wb') as AO: AO.write(usbf_13L.read()) #Saving the produced images as .png files at specified locations rs = rf.Network(path_low) #Plot S21 for rs plt.tight_layout() my_dpi = 96 S21 = rs.plot_s_db(1, 0) plt.savefig(dir + lna_num + '_13L.jpg', bbox_inches="tight", dpi=my_dpi * 10) plt.close() rs.plot_s_db() plt.savefig(dir + lna_num + '_13LA.jpg', dpi=my_dpi * 10) plt.close() # Reads block data from the specified file location. ''' ###LOW POWER BLOCK from 23###
def touchstone2tikz(sourcedir, resultdir): # Define all Requirements for the Project requirement11 = ClassRequirements(r'Requirements $S_{11}$', 'max', '') requirement11.set_data(0.4, 6, -20) requirement22 = ClassRequirements(r'Requirements $S_{22}$ and $S_{33}$', 'max', '', '0,0,0') requirement22.set_data(0.4, 6, -15) requirement32 = ClassRequirements(r'Requirements Isolation ($S_{32}$)', 'max', '') requirement32.set_data(0.4, 6, -20) requirement21 = ClassRequirements( r'Requirements Coupling ($S_{21}$ and $S_{31}$)', 'is', '', reqscale=0.2) requirement21.set_data(0.4, 6, -6) # Create a tex file to plot all created pictures when included importtemplate = Template(r'\instikz{$tikzfilename}{$desc}' + '\n') teximport = '' touchstone_list = glob(os.path.join(sourcedir, "*.s*p")) if not touchstone_list: print('No touchstone files found in ' + sourcedir + '! Skipping...') return for touchstone in touchstone_list: # read Touchstone files netw = rf.Network(touchstone) print('Now processing: ' + netw.name + ' ...') # export tikz files spara_db_2tikz( netw, 'GHz', [(1, 1), (2, 2), (3, 3)], [' - Matching Port 1', ' - Matching Port 2', ' - Matching Port 3'], requirements=[requirement11, requirement22], filename=os.path.join(resultdir, netw.name + '_ANP.tikz')) teximport += importtemplate.substitute({ 'tikzfilename': netw.name + '_ANP', 'desc': netw.name.replace('_', ' ') + ' - Matching' }) spara_db_2tikz(netw, 'GHz', [(2, 1), (3, 1)], [' - Coupling Port 1 to 2', ' - Coupling Port 1 to 3'], requirements=requirement21, filename=os.path.join(resultdir, netw.name + '_KOP.tikz')) teximport += importtemplate.substitute({ 'tikzfilename': netw.name + '_KOP', 'desc': netw.name.replace('_', ' ') + ' - Coupling' }) spara_db_2tikz(netw, 'GHz', [(3, 2)], [' - Isolation between Port 2 and 3'], requirements=requirement32, filename=os.path.join(resultdir, netw.name + '_ISO.tikz')) teximport += importtemplate.substitute({ 'tikzfilename': netw.name + '_ISO', 'desc': netw.name.replace('_', ' ') + ' - Isolation' }) teximport += '\n' createImportFile(os.path.join(resultdir, 'importallpictures.tex'), teximport) print('Done!')
def get_snp_network(self, ports, **kwargs): """ return n-port network as an Network object Parameters ---------- ports : Iterable a iterable of integers designating the ports to query kwargs : dict channel(int) [ default 'self.active_channel' ] sweep(bool) [default True] name(str) [default \"\"] f_unit(str) [ default \"GHz\" ] raw_data(bool) [default False] Returns ------- Network general function to take in a list of ports and return the full snp network as a Network object """ self.resource.clear() # force activate channel to avoid possible errors: self.active_channel = channel = kwargs.get("channel", self.active_channel) sweep = kwargs.get("sweep", True) name = kwargs.get("name", "") f_unit = kwargs.get("f_unit", "GHz") raw_data = kwargs.get("raw_data", False) ports = [int(port) for port in ports ] if type(ports) in (list, tuple) else [int(ports)] if not name: name = "{:}Port Network".format(len(ports)) if sweep: self.sweep(channel=channel) npoints = self.scpi.query_sweep_n_points(channel) snp_fmt = self.scpi.query_snp_format() self.scpi.set_snp_format("RI") if raw_data is True: if self.scpi.query_channel_correction_state(channel): self.scpi.set_channel_correction_state(channel, False) data = self.scpi.query_snp_data(channel, ports) self.scpi.set_channel_correction_state(channel, True) else: data = self.scpi.query_snp_data(channel, ports) else: data = self.scpi.query_snp_data(channel, ports) self.scpi.set_snp_format( snp_fmt) # restore the value before we got the RI data self.scpi.set_snp_format( snp_fmt) # restore the value before we got the RI data nrows = int(len(data) / npoints) nports = int(np.sqrt((nrows - 1) / 2)) data = data.reshape([nrows, -1]) fdata = data[0] sdata = data[1:] ntwk = skrf.Network() ntwk.frequency = skrf.Frequency.from_f(fdata, unit="Hz") ntwk.s = np.empty(shape=(sdata.shape[1], nports, nports), dtype=complex) for n in range(nports): for m in range(nports): i = n * nports + m ntwk.s[:, m, n] = sdata[i * 2] + 1j * sdata[i * 2 + 1] ntwk.frequency.unit = f_unit ntwk.name = name return ntwk
server = app.server """ FYI The device under test was made with this air = rf.air air.npoints =1001 dut = air.shunt_delay_load(.2,180)**\ air.line(100)**\ air.shunt_delay_load(.4,100)**\ air.line(4000)**\ air.shunt(air.load(.7))**\ air.line(1000)**\ air.impedance_mismatch(1,3) #**air.short() dut.add_noise_polar(.01,3e-5) """ dut = rf.Network("dut.s2p") # pull out some frequency info to set slider bounds on center/span freq = dut.frequency dt = freq.t_ns[1] - freq.t_ns[0] t_max = freq.t_ns.max() ######## ## the APP app.layout = html.Div( className="page", children=[ html.Div( className="sub_page", children=[ # html.Div(className='col-2'), html.Div(children=[
def d4s(self, pads='PadShort.s2p', pado='PadOpen.s2p', duto='Open.s2p', shop='ShortOpen.s2p', opsh='OpenShort.s2p'): ''' Perform Kolding 4-step deembedding on raw data pads = short at the RF pads (simple short) pado = open at the RF pads (simple open) duto = open at the DUT ref plane (dut open) shop = At DUT ref plane, short at P1 and open at P2 opsh = At DUT ref plane, open at P1 and short at P2 Returns a new rfnpn object (by returning self)' ''' # Create network objects pads = rf.Network(pads) pado = rf.Network(pado) duto = rf.Network(duto) shop = rf.Network(shop) opsh = rf.Network(opsh) # Simple short Zc Zc1 = pads.z[:, 0, 0] Zc2 = pads.z[:, 1, 1] Zc = (2 / 3) * (Zc1.real + Zc2.real) / 2 # average contact res of ports, Eq. (6) mfactor = np.array([[3 / 2, 0], [0, 3 / 2]]) mfactor = np.repeat(mfactor[np.newaxis, :, :], int(np.size(self.f)), axis=0) Z1 = np.einsum('ijk,i->ijk', mfactor, Zc) self.data.z = self.data.z - Z1 # Eq. (2) # Simple open Zp Zp1 = pado.z[:, 0, 0] - pads.z[:, 0, 0] Zp2 = pado.z[:, 1, 1] - pads.z[:, 1, 1] Zp = (Zp1 + Zp2) / 2 # average open impedance of ports, Eq. (7) mfactor = np.array([[1, 0], [0, 1]]) mfactor = np.repeat(mfactor[np.newaxis, :, :], int(np.size(self.f)), axis=0) Y2 = np.einsum('ijk,i->ijk', mfactor, 1 / Zp) self.data.y = self.data.y - Y2 # Eq. (3) # Extended de-embedding # do simple short open deembedding for rest of the fixture structures d_duto = rf.Network() d_duto.z0 = self.z0 d_duto.f = self.f * 1e-9 d_duto.z = duto.z - pads.z d_duto.y = d_duto.y - pado.y d_shop = rf.Network() d_shop.z0 = self.z0 d_shop.f = self.f * 1e-9 d_shop.z = shop.z - pads.z d_shop.y = d_shop.y - pado.y d_opsh = rf.Network() d_opsh.z0 = self.z0 d_opsh.f = self.f * 1e-9 d_opsh.z = opsh.z - pads.z d_opsh.y = d_opsh.y - pado.y # Find impedance of dangling grounding leg (DL) ZDL = (1 / 4) * (d_shop.z[:, 1, 0] + d_shop.z[:, 0, 1] + d_opsh.z[:, 1, 0] + d_opsh.z[:, 0, 1]) # Eq. (15) # Find series impedance sum of feed line and ground line # but first average the short impedance measurements z11s = (1 / 2) * (d_shop.z[:, 0, 0] + d_opsh.z[:, 1, 1]) alpha = 0 # accuracy adjustment factor (see the Kolding paper) ZiZ1 = (z11s - ZDL) / (1 + alpha) # Eq. (16) a1 = np.dstack((ZiZ1 + ZDL, ZDL)) a2 = np.dstack((ZDL, ZiZ1 + ZDL)) a3 = np.dstack((a1, a2)) Z3 = np.reshape(a3, (int(np.size(self.f)), 2, 2)) self.data.z = self.data.z - Z3 # Eq. (4) # Find impedance of the input / output to the dangling gnd leg, and across input/output of dut Zio = d_duto.z[:, 1, 0] + d_duto.z[:, 0, 0] - 2 * ZDL - ZiZ1 # Eq. (17) Zf = Zio * ((Zio / (d_duto.z[:, 1, 0] - ZDL)) - 2) # Eq. (18) a1 = np.dstack((1 / Zio, -1 / Zf)) a2 = np.dstack((-1 / Zf, 1 / Zio)) a3 = np.dstack((a1, a2)) Y4 = np.reshape(a3, (int(np.size(self.f)), 2, 2)) self.data.y = self.data.y - Y4 return self
def ideal_cal_standard(self, sweep_freqs): ideal_open = rf.Network(f=sweep_freqs, s=np.ones(points), z0=50) ideal_short = rf.Network(f=sweep_freqs, s=-1 * np.ones(points), z0=50) ideal_load = rf.Network(f=sweep_freqs, s=np.zeros(points), z0=50) return [ideal_short, ideal_open, ideal_load]
def setUp(self): """ Read in all the network data required for tests """ self.data_dir_qucs = os.path.dirname(os.path.abspath(__file__)) + \ '/qucs_prj/' self.data_dir_ads = os.path.dirname(os.path.abspath(__file__)) + \ '/ads/' self.ref_qucs = [ {'model': 'hammerstadjensen', 'disp': 'hammerstadjensen', 'color': 'r', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,hammerstad,hammerstad.s2p'))}, {'model': 'hammerstadjensen', 'disp': 'kirschningjansen', 'color': 'c', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,hammerstad,kirschning.s2p'))}, {'model': 'hammerstadjensen', 'disp': 'kobayashi', 'color': 'k', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,hammerstad,kobayashi.s2p'))}, {'model': 'hammerstadjensen', 'disp': 'yamashita', 'color': 'g', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,hammerstad,yamashita.s2p'))}, {'model': 'wheeler', 'disp': 'schneider', 'color': 'm', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,wheeler,schneider.s2p'))}, {'model': 'schneider', 'disp': 'schneider', 'color': 'b', 'n': rf.Network(os.path.join(self.data_dir_qucs, 'mline,schneider,schneider.s2p'))} ] self.ref_ads = [ {'diel': 'frequencyinvariant', 'disp': 'kirschningjansen', 'color': 'r', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,freqencyinvariant,kirschning.s2p'))}, {'diel': 'djordjevicsvensson', 'disp': 'kirschningjansen', 'color': 'c', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,djordjevicsvensson,kirschning.s2p'))}, {'diel': 'frequencyinvariant', 'disp': 'kobayashi', 'color': 'k', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,freqencyinvariant,kobayashi.s2p'))}, {'diel': 'djordjevicsvensson', 'disp': 'kobayashi', 'color': 'g', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,djordjevicsvensson,kobayashi.s2p'))}, {'diel': 'frequencyinvariant', 'disp': 'yamashita', 'color': 'm', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,freqencyinvariant,yamashita.s2p'))}, {'diel': 'djordjevicsvensson', 'disp': 'yamashita', 'color': 'b', 'n': rf.Network(os.path.join(self.data_dir_ads, 'mlin,djordjevicsvensson,yamashita.s2p'))} ] # default parameter set for tests self.verbose = False # output comparison plots if True self.w = 3.00e-3 self.h = 1.55e-3 self.t = 35e-6 self.l = 25e-3 self.ep_r = 4.413 self.tand = 0.0182 self.rho = 1.7e-8 self.d = 0.15e-6 self.f_et = 1e9
import pylab import skrf as rf # create a Network type from a touchstone file ring_slot = rf.Network('ring slot.s2p') ring_slot.plot_s_smith() pylab.show()
app = dash.Dash(__name__, external_stylesheets=external_stylesheets) ''' FYI The device under test was made with this air = rf.air air.npoints =1001 dut = air.shunt_delay_load(.2,180)**\ air.line(100)**\ air.shunt_delay_load(.4,100)**\ air.line(4000)**\ air.shunt(air.load(.7))**\ air.line(1000)**\ air.impedance_mismatch(1,3) #**air.short() dut.add_noise_polar(.01,3e-5) ''' dut = rf.Network('dut.s2p') # pull out some frequency info to set slider bounds on center/span freq = dut.frequency dt = (freq.t_ns[1] - freq.t_ns[0]) t_max = freq.t_ns.max() ######## ## the APP app.layout = html.Div( className='page', children=[ html.Div( className='sub_page', children=[ #html.Div(className='col-2'), html.Div(children=[
import pylab import skrf as rf # from the extension you know this is a 2-port network ring_slot_sim = rf.Network('ring slot array simulation.s2p') ring_slot_meas = rf.Network('ring slot array measured.s2p') pylab.figure(1) pylab.title('WR-10 Ringslot Array Simulated vs Measured') # if no indices are passed to the plot command it will plot all # available s-parameters ring_slot_sim.plot_s_db(0, 0, label='Simulated') ring_slot_meas.plot_s_db(0, 0, label='Measured') pylab.show()
def test_cst_touchstone_V2_2_network(self): ''' Test the conversion into a Network of a CST-generated touchstone V2 format file (.ts) ''' nw_cst_6ports = rf.Network( os.path.join(self.test_dir, 'cst_example_6ports_V2.ts'))
def skrf_network(self, x): import skrf as sk n = sk.Network() n.frequency = sk.Frequency.from_f(self.frequencies / 1e6, unit='mhz') n.s = x return n
def test_constructor_from_hfss_touchstone(self): # HFSS can provide the port characteric impedances in its generated touchstone file. # Check if reading a HFSS touchstone file with non-50Ohm impedances ntwk_hfss = rf.Network( os.path.join(self.test_dir, 'hfss_threeport_DB.s3p')) self.assertFalse(npy.isclose(ntwk_hfss.z0[0, 0], 50))
import skrf as rf import os from matplotlib import pyplot as plt from matplotlib import style start = 0 freq_s = '3.6ghz' freq_v = float(freq_s[:-3]) * 1e9 ff1 = rf.Network("..\\Adapters\\ff1.s2p") ff2 = rf.Network("..\\Adapters\\ff1.s2p") # cascade 2 f-f adapters ff_total = ff1**ff2 #ff_total.plot_s_db(m=0, n=0) for chan in range(1, 4): plt.figure("Bad Adapters") mm = rf.Network("..\\Adapters\\" + str(chan) + ".s2p") # mm.plot_s_db(m=0, n=1) #deembed the 2 adapters from the m-m measurement adapter = mm**ff_total.inv adapter.plot_s_db(m=1, n=0) # label the plot # plt.figure("Good Adapter") good_adapter = rf.Network("..\\Adapters\\goodmm.s2p") good_adapter = good_adapter**ff_total.inv good_adapter.plot_s_db(m=1, n=0)
def test_constructor_from_fid_touchstone(self): filename = os.path.join(self.test_dir, 'ntwk1.s2p') with open(filename, 'rb') as fid: rf.Network(fid)
def test_constructor_from_values(self): rf.Network(f=[1,2],s=[1,2],z0=[1,2] )
def test_is_symmetric(self): # 2-port a = rf.Network(f=[1, 2], s=[[-1, 0], [0, -1]], z0=50) self.assertTrue(a.is_symmetric(), 'A short is symmetric.') self.assertRaises(ValueError, a.is_symmetric, port_order={1: 2}) # error raised by renumber() a.s[0, 0, 0] = 1 self.assertFalse(a.is_symmetric(), 'non-symmetrical') # 3-port b = rf.Network(f=[1, 2], s=[[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]], z0=50) with self.assertRaises(ValueError) as context: b.is_symmetric() self.assertEqual( str(context.exception), 'test of symmetric is only valid for a 2N-port network') # 4-port c = rf.Network(f=[1, 2], s=[[0, 1j, 1, 0], [1j, 0, 0, 1], [1, 0, 0, 1j], [0, 1, 1j, 0]], z0=50) self.assertTrue(c.is_symmetric(n=2), 'This quadrature hybrid coupler is symmetric.') self.assertTrue( c.is_symmetric(n=2, port_order={ 0: 1, 1: 2, 2: 3, 3: 0 }), 'This quadrature hybrid coupler is symmetric even after rotation.') with self.assertRaises(ValueError) as context: c.is_symmetric(n=3) self.assertEqual( str(context.exception), 'specified order n = 3 must be between 1 and N = 2, inclusive') d = rf.Network(f=[1, 2], s=[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 1], [0, 1, 0, 1]], z0=50) self.assertTrue( d.is_symmetric(n=1), 'This contrived non-reciprocal device has a line of symmetry.') self.assertFalse(d.is_symmetric(n=2), 'This device only has first-order line symmetry.') self.assertFalse( d.is_symmetric(port_order={ 0: 1, 1: 0 }), 'This device is no longer symmetric after reordering ports 1 and 2.' ) self.assertTrue( d.is_symmetric(port_order={ 0: 1, 1: 0, 2: 3, 3: 2 }), 'This device is symmetric after swapping ports 1 with 2 and 3 with 4.' ) # 6-port x = rf.Network(f=[1, 2], s=[[0, 0, 0, 0, 0, 0], [0, 1, 9, 0, 0, 0], [0, 0, 2, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 0, 0, 9, 1, 0], [0, 0, 0, 0, 0, 0]], z0=50) self.assertFalse(x.is_symmetric(n=3)) self.assertFalse(x.is_symmetric(n=2)) self.assertTrue(x.is_symmetric(n=1)) self.assertTrue( x.is_symmetric(n=1, port_order={ -3: -1, -1: -3, 0: 2, 2: 0 })) # 8-port s8p_diag = [1j, -1j, -1j, 1j, 1j, -1j, -1j, 1j] s8p_mat = npy.identity(8, dtype=complex) for row in range(8): s8p_mat[row, :] *= s8p_diag[row] y = rf.Network(f=[1, 2], s=s8p_mat, z0=50) self.assertTrue(y.is_symmetric()) self.assertTrue(y.is_symmetric(n=2)) self.assertFalse(y.is_symmetric(n=4)) return
def test_constructor_from_pickle(self): if six.PY2: rf.Network(os.path.join(self.test_dir, 'ntwk1.ntwk'))
def test_noise(self): a = rf.Network(os.path.join(self.test_dir, 'ntwk_noise.s2p')) nf = 10**(0.05) self.assertTrue(a.noisy) self.assertTrue( abs(a.nfmin[0] - nf) < 1.e-6, 'noise figure does not match original spec') self.assertTrue( abs(a.z_opt[0] - 50.) < 1.e-6, 'optimal resistance does not match original spec') self.assertTrue( abs(a.rn[0] - 0.1159 * 50.) < 1.e-6, 'equivalent resistance does not match original spec') self.assertTrue( npy.all(abs(a.g_opt) < 1.e-6), 'calculated optimal reflection coefficient does not match original coefficients' ) b = rf.Network(f=[1, 2], s=[[[0, 1], [1, 0]], [[0, 1], [1, 0]]], z0=50).interpolate(a.frequency) with self.assertRaises(ValueError) as context: b.n with self.assertRaises(ValueError) as context: b.f_noise self.assertEqual(str(context.exception), 'network does not have noise') c = a**b self.assertTrue(a.noisy) self.assertTrue( abs(c.nfmin[0] - nf) < 1.e-6, 'noise figure does not match original spec') self.assertTrue( abs(c.z_opt[0] - 50.) < 1.e-6, 'optimal resistance does not match original spec') self.assertTrue( abs(c.rn[0] - 0.1159 * 50.) < 1.e-6, 'equivalent resistance does not match original spec') d = b**a self.assertTrue(d.noisy) self.assertTrue( abs(d.nfmin[0] - nf) < 1.e-6, 'noise figure does not match original spec') self.assertTrue( abs(d.z_opt[0] - 50.) < 1.e-6, 'optimal resistance does not match original spec') self.assertTrue( abs(d.rn[0] - 0.1159 * 50.) < 1.e-6, 'equivalent resistance does not match original spec') e = a**a self.assertTrue( abs(e.nfmin[0] - (nf + (nf - 1) / (10**2))) < 1.e-6, 'noise figure does not match Friis formula') self.assertTrue(a.noisy) self.assertTrue( abs(a.nfmin[0] - nf) < 1.e-6, 'noise figure was altered') self.assertTrue( abs(a.z_opt[0] - 50.) < 1.e-6, 'optimal resistance was altered') self.assertTrue( abs(a.rn[0] - 0.1159 * 50.) < 1.e-6, 'equivalent resistance was altered') tem = DistributedCircuit(z0=50) inductor = tem.inductor(1e-9).interpolate(a.frequency) f = inductor**a expected_zopt = 50 - 2j * npy.pi * 1e+9 * 1e-9 self.assertTrue( abs(f.z_opt[0] - expected_zopt) < 1.e-6, 'optimal resistance was not 50 ohms - inductor') return
def readP2S(self, file): ts = rf.Network(file) self.re = ts.s21.s_re[:, 0, 0] self.im = ts.s21.s_im[:, 0, 0] self.freq = ts.f self.calcTDR()
def test_noise_deembed(self): f1_ = [75.5, 75.5] f2_ = [75.5, 75.6] npt_ = [1, 2] # single freq and multifreq for f1, f2, npt in zip(f1_, f2_, npt_): freq = rf.Frequency(f1, f2, npt, 'ghz') ntwk4_n = rf.Network(os.path.join(self.test_dir, 'ntwk4_n.s2p'), f_unit='GHz').interpolate(freq) ntwk4 = rf.Network(os.path.join(self.test_dir, 'ntwk4.s2p'), f_unit='GHz').interpolate(freq) thru = rf.Network(os.path.join(self.test_dir, 'thru.s2p'), f_unit='GHz').interpolate(freq) ntwk4_thru = ntwk4**thru ntwk4_thru.name = 'ntwk4_thru' retrieve_thru = ntwk4.inv**ntwk4_thru retrieve_thru.name = 'retrieve_thru' self.assertEqual(retrieve_thru, thru) self.assertTrue(ntwk4_thru.noisy) self.assertTrue(retrieve_thru.noisy) self.assertTrue( (abs(thru.nfmin - retrieve_thru.nfmin) < 1.e-6).all(), 'nf not retrieved by noise deembed') self.assertTrue((abs(thru.rn - retrieve_thru.rn) < 1.e-6).all(), 'rn not retrieved by noise deembed') self.assertTrue( (abs(thru.z_opt - retrieve_thru.z_opt) < 1.e-6).all(), 'noise figure does not match original spec') ntwk4_n_thru = ntwk4_n**thru ntwk4_n_thru.name = 'ntwk4_n_thru' retrieve_n_thru = ntwk4_n.inv**ntwk4_n_thru retrieve_n_thru.name = 'retrieve_n_thru' self.assertTrue(ntwk4_n_thru.noisy) self.assertEqual(retrieve_n_thru, thru) self.assertTrue(ntwk4_n_thru.noisy) self.assertTrue(retrieve_n_thru.noisy) self.assertTrue( (abs(thru.nfmin - retrieve_n_thru.nfmin) < 1.e-6).all(), 'nf not retrieved by noise deembed') self.assertTrue((abs(thru.rn - retrieve_n_thru.rn) < 1.e-6).all(), 'rn not retrieved by noise deembed') self.assertTrue( (abs(thru.z_opt - retrieve_n_thru.z_opt) < 1.e-6).all(), 'noise figure does not match original spec') tuner, x, y, g = tuner_constellation() newnetw = thru.copy() nfmin_set = 4.5 gamma_opt_set = complex(.7, -0.2) rn_set = 1 newnetw.set_noise_a(thru.noise_freq, nfmin_db=nfmin_set, gamma_opt=gamma_opt_set, rn=rn_set) z = newnetw.nfdb_gs(g)[:, 0] freq = thru.noise_freq.f[0] gamma_opt_rb, nfmin_rb = plot_contour(freq, x, y, z, min0max1=0, graph=False) self.assertTrue( abs(nfmin_set - nfmin_rb) < 1.e-2, 'nf not retrieved by noise deembed') self.assertTrue( abs(gamma_opt_rb.s[0, 0, 0] - gamma_opt_set) < 1.e-1, 'nf not retrieved by noise deembed')
import sys import skrf import matplotlib.pyplot as plt import numpy as np skrf.stylely() os = skrf.Network('open_short.s2p') so = skrf.Network('short_open.s2p') ls = skrf.Network('load_short.s2p') sl = skrf.Network('short_load.s2p') ss = skrf.Network('short_short.s2p') ll = skrf.Network('load_load.s2p') through = skrf.Network('through.s2p') dut = skrf.Network(sys.argv[1]) def tline_input(zl, z0, t, f): c = 299792458 w = c/f b = np.pi*2/w l = t*c return z0*(zl+1j*z0*np.tan(b*l))/(z0+1j*zl*np.tan(b*l)) def gamma(zl, z0): return (zl-z0)/(zl+z0) def make_standards(): open_c = [20e-15, -1140e-27, 2176e-36, -213e-45] open_offset_t = 35.7e-12 open_offset_z0 = 50.0
def sweep(self, fstart, fstop, points, navg=1, align_lo=False, sw_terms=False, rawplot=False): sweep_freqs = np.linspace(fstart, fstop, points) sweep_s11 = 1j * np.zeros(points) sweep_s21 = 1j * np.zeros(points) sweep_s12 = 1j * np.zeros(points) sweep_s22 = 1j * np.zeros(points) sweep_fwd_sw = 1j * np.zeros(points) sweep_rev_sw = 1j * np.zeros(points) for (fidx, f) in enumerate(sweep_freqs): tfstart = time.time() lo_freq = (f + IF_FREQ) * self.lo_to_rf_offset_ratio doubler = False if lo_freq > DOUBLER_CUTOFF: lo_freq = lo_freq / 2.0 doubler = True self.vna_io.set_multiplier(status=ENABLE) else: self.vna_io.set_multiplier(status=DISABLE) self.lo_synth.set_freq(lo_freq) self.rf_synth.set_freq(f) tfstop = time.time() tlevels = time.time() self.lo_synth.level_pow(LO_CAL) self.rf_synth.level_pow(RF_CAL) tlevele = time.time() self.lo_synth.wait_for_lock() self.rf_synth.wait_for_lock() print('freq change time: {} seconds'.format(tfstop - tfstart)) print('power level time: {} seconds'.format(tlevele - tlevels)) #raw_input('press enter to continue') print('{}/{} measuring {} GHz '.format(fidx, points, f / 1e9)) print('measuring s11, s21') s11, s21, fwd_sw = self._grab_s_raw(navg=navg, rfport=PORT1, rawplot=rawplot) print('measuring s21, s22') s22, s12, rev_sw = self._grab_s_raw(navg=navg, rfport=PORT2, rawplot=rawplot) print('s11: {} , mag {}'.format(s11, abs(s11))) print('s22: {} , mag {}'.format(s22, abs(s22))) print('s21: {} , mag {}'.format(s21, abs(s21))) print('s12: {} , mag {}'.format(s12, abs(s12))) sweep_s11[fidx] = s11 sweep_s12[fidx] = s12 sweep_s21[fidx] = s21 sweep_s22[fidx] = s22 sweep_fwd_sw[fidx] = fwd_sw sweep_rev_sw[fidx] = rev_sw s11 = rf.Network(f=sweep_freqs / 1e9, s=sweep_s11, z0=50) s12 = rf.Network(f=sweep_freqs / 1e9, s=sweep_s12, z0=50) s21 = rf.Network(f=sweep_freqs / 1e9, s=sweep_s21, z0=50) s22 = rf.Network(f=sweep_freqs / 1e9, s=sweep_s22, z0=50) sw_fwd = rf.Network(f=sweep_freqs / 1e9, s=sweep_fwd_sw, z0=50) sw_rev = rf.Network(f=sweep_freqs / 1e9, s=sweep_rev_sw, z0=50) if sw_terms: return rf.network.four_oneports_2_twoport(s11, s12, s21, s22), sw_fwd, sw_rev else: return rf.network.four_oneports_2_twoport(s11, s12, s21, s22)