This is a brief introduction to scikit-rf (aka skrf
). The intended audience are those who have a working python stack, and are somewhat familiar with python. If you are completely new to python, see scipy's Getting Started. First, import the scikit-rf module skrf
, as rf
In [ ]:
import skrf as rf
If this produces an error, please see the installation tutorial.
In [ ]:
ring_slot = rf.Network('data/ring slot.s2p')
If you cant find ring slot.s2p
, then just import it from the skrf.data
module.
In [ ]:
from skrf.data import ring_slot
A short description of the network will be printed out if entered onto the command line
In [ ]:
ring_slot
The basic attributes of a microwave Network are provided by the following properties,
Network.s
: Scattering Parameter matrix. Network.z0
: Port Impedance matrix.Network.frequency
: Frequency Object. The Network object has numerous other properties and methods which can found in it's docstring. If you are using IPython/Jupyter, then these properties and methods can be 'tabbed' out on the command line.
In [1]: ring_slot.s<TAB>
ring_slot.s ring_slot.s_arcl ring_slot.s_im
ring_slot.s11 ring_slot.s_arcl_unwrap ring_slot.s_mag
...
Element-wise mathematical operations on the s-parameters are accessible through overloaded operators. To illustrate, we load a couple Networks
stored in the skrf.data
module.
In [ ]:
short = rf.data.wr2p2_short
delayshort = rf.data.wr2p2_delayshort
The complex difference between their s-parameters is computed with
In [ ]:
short - delayshort
This returns a new Network. Other arrimetic operators are overloaded as well,
In [ ]:
short/delayshort
Cascading and de-embeding 2-port Networks can also be done though operators. Cascading is done through the power operator, **
.
In [ ]:
short = rf.data.wr2p2_short
line = rf.data.wr2p2_line
delayshort = line ** short
De-embedding can be accomplished by cascading the inverse of a network. The inverse of a network is accessed through the property Network.inv
.
In [ ]:
short = line.inv ** delayshort
skrf has a function which updates your matplotlib rcParams so that plots appear like the ones shown in these tutorials.
In [ ]:
# display plots in notebook
%matplotlib inline
from pylab import *
rf.stylely()
The methods of the Network class provide convenient ways to plot components of the network parameters,
Network.plot_s_db()
: plot magnitude of s-parameters in log scaleNetwork.plot_s_deg()
: plot phase of s-parameters in degreesNetwork.plot_s_smith()
: plot complex s-parameters on Smith ChartTo plot all four s-parameters of the ring_slot
in Mag, Phase, and on the Smith Chart.
In [ ]:
ring_slot.plot_s_db()
Or plot the phase of $S_{12}$
In [ ]:
ring_slot.plot_s_deg(m=0,n=1)
In [ ]:
ring_slot.plot_s_smith(lw=2)
title('Big ole Smith Chart')
For more detailed information about plotting see the Plotting tutorial
The NeworkSet object represents an unordered set of networks and provides methods for calculating statistical quantities and displaying uncertainty bounds.
A NeworkSet is created from a list or dict of
Networks's. This can be done quickly with
rf.read_all()
, which loads all skrf-readable objects
in a directory. The argument contains
is used to load only files
which match a given substring.
In [ ]:
rf.read_all('data/', contains='ro')
This dictionary can be passed directly to the NeworkSet constructor,
In [ ]:
from skrf import NetworkSet
ro_dict = rf.read_all('data/', contains='ro')
ro_ns = NetworkSet(ro_dict, name='ro set') # name is optional
ro_ns
NeworkSet's are list-like.
Statistical quantities can be calculated by accessing
properties of the NeworkSet. For example, to calculate the complex
average of the set, access the mean_s
property
In [ ]:
ro_ns.mean_s
The returned results are stored in a Networks s-parameters, regardless of the type of the output. Similarly, to calculate the complex standard deviation of the set,
In [ ]:
ro_ns.std_s
In [ ]:
ro_ns.std_s.plot_s_mag(label='S11')
ylabel('Standard Deviation')
title('Standard Deviation of RO');
Uncertainty bounds on any network parameter can be plotted through the methods
In [ ]:
ro_ns.plot_uncertainty_bounds_s_db(label='S11');
See the networkset tutorial for more information.
The skrf.vi module holds classes for GPIB/VISA instruments that are intricately related to skrf, mostly VNA's. The VNA classes were created for the sole purpose of retrieving data so that calibration and analysis could be done offline by skrf, so most other VNA capabilities is neglected.
A list of VNA's that are partially supported.
An example of using the PNA
class to retrieve some s-parameter data
from skrf.vi import vna
my_vna = vna.PNA(address=16)
#if an error is thrown at this point there is most likely a problem with your visa setup
dut_1 = my_vna.s11
dut_2 = my_vna.s21
dut_3 = my_vna.two_port
See the Virtual Instruments tutorial for more information.
Calibrations are performed through a Calibration class. In most cases, creating a Calibration object requires at least two pieces of information:
The Network elements in each list must all be similar (same #ports, frequency info, etc) and must be aligned to each other, meaning the first element of ideals list must correspond to the first element of measured list.
Below is an example script illustrating how to create a Calibration .
import skrf as rf
from skf.calibration import OnePort
my_ideals = rf.read_all('ideals/')
my_measured = rf.read_all('measured/')
duts = rf.read_all('measured/')
## create a Calibration instance
cal = rf.OnePort(
ideals = [my_ideals[k] for k in ['short','open','load']],
measured = [my_measured[k] for k in ['short','open','load']],
)
caled_duts = [cal.apply_cal(dut) for dut in duts.values()]
See the Calibration tutorial for more details and examples.
Simple transmission-line based networks can be created through methods of the Media class, which represents a transmission line object for a given medium. Once constructed, a Media object contains the neccesary properties such as propagation constant
and characteristic impedance
, that are needed to generate microwave circuits.
The basic usage looks something like this,
In [ ]:
from skrf import Frequency
from skrf.media import CPW, Coaxial
freq = Frequency(75,110,101,'ghz')
cpw = CPW(freq, w=10e-6, s=5e-6, ep_r=10.6)
cpw
In [ ]:
cpw.line(d=90,unit='deg', name='line')
In [ ]:
freq = Frequency(1,10,101,'ghz')
coax = Coaxial(frequency=freq, Dint=1e-3, Dout=2e-3)
coax
In [ ]: