Python library for calculating cascaded performance metrics in RF transceivers.
Project description
📻 xcvr
xcvr is a Python library for RF transceiver cascaded analysis. Define components from S-parameter data or datasheet constants, cascade them into systems, and analyze gain, noise figure, linearity, compression, and link budgets — all frequency-aware and unit-safe via pint and xarray.
Built on top of scikit-rf, schemdraw, and xarray.
Installation
uv add xcvr
Or with pip:
pip install xcvr
Features
- Cascaded RF system analysis — gain, noise figure, OIP3, IIP3, P1dB, Psat, and noise temperature across the full device chain, frequency-resolved
- S-parameter based devices — load real
.sNptouchstone files via scikit-rf for accurate, broadband device models - Constant (datasheet) devices — quickly define devices from scalar gain and noise figure values for early-stage budgets
- Cable modeling — frequency-dependent coaxial cable loss from physical parameters (length, tan δ)
- Nested subsystems — compose
Systemobjects from otherSystemobjects; expand or collapse subsystems in analysis and diagrams - Link budget analysis — complete RF link budget with Eb/N0, CNR, link margin, G/T, BER, and max range calculations for M-ary PSK and QAM modulations
- Signal compression tracking — propagate signal level through the chain with Psat limiting at each stage
- Block diagrams — auto-generated schematic block diagrams via schemdraw with per-device symbols
- Power dissipation — track supply voltage, current, and cumulative power dissipation per device
- Rich DataFrame output — styled pandas tables with bar charts and compression highlighting
- Unit safety — all quantities carry pint units; dB, dBm, kelvin, Hz conversions are handled automatically
Quick Start
System Cascade
import skrf
import schemdraw
import xarray as xr
from xrench.units import ureg
from xcvr import Device, System, Symbol, plot_cascade, plot_signal_compression
from xcvr.symbols import Attenuator, Coupler
from xcvr.devices import Cable, Constant
# --- Define devices from S-parameter files ---
lna_net = skrf.Network("SKY55950_WB.s2p")
lna = Device(
"A1", "Skyworks", "SKY55950",
network=lna_net,
nf=2 * ureg.dB,
p1db=10 * ureg.dBm,
oip3=-5 * ureg.dBm,
vsup=2.8 * ureg.volt,
isup=2 * ureg.mA,
symbol=Symbol(schemdraw.dsp.Amp),
)
att_net = skrf.Network("GAT-1+.s2p")
attenuator = Device(
"R1", "Susumu", "PAT0510S-C-1DB",
network=att_net,
symbol=Attenuator,
)
# --- Build a system ---
rx = System(
"GPS RX", "xcvr inc.", "001",
[lna, attenuator, lna, attenuator],
)
# --- View the block diagram ---
rx.block_diagram()
# --- Cascaded NF at GPS L1 ---
rx.cascaded_nf.sel(frequency=1.575e9, method="nearest")
# --- Full cascade table at a single frequency ---
f = (1.575 * ureg.GHz).to("Hz")
rx.get_dataframe(input_power=0 * ureg.dBm, frequency=f.magnitude, method="nearest")
# --- Plot cascaded gain vs. device ---
ax = plot_cascade(rx, prop="gain", frequency=1.575e9)
ax.grid()
# --- Plot signal level and compression headroom ---
input_pwr = xr.DataArray([-20] * ureg.dBm, dims=("frequency",), coords={"frequency": [1.575e9]})
ax = plot_signal_compression(rx, input_pwr, frequency=1.575e9)
ax.grid()
Constant (Datasheet) Device
Use Constant to define a device from a single gain value when S-parameter files are not yet available:
from xcvr.devices import Constant
frequency = xr.DataArray(
[1.0e9, 1.5e9, 2.0e9] * ureg.Hz, dims=("frequency",), coords={"frequency": [1.0e9, 1.5e9, 2.0e9]}
)
amp = Constant(
"A1", "Generic", "AMP-001",
frequency=frequency,
gain=20 * ureg.dB,
noise_gain=20 * ureg.dB,
nf=3 * ureg.dB,
p1db=15 * ureg.dBm,
)
Cable
from xcvr.devices import Cable
cable = Cable(
"W1", "Times Microwave", "LMR-400",
frequency=frequency,
length=10 * ureg.inch,
tan_delta=0.002,
)
Nested Subsystems
frontend = System("Frontend", "xcvr", "FE-001", [lna, attenuator])
backend = System("Backend", "xcvr", "BE-001", [attenuator, lna, attenuator])
# Compose into a top-level system
full_rx = System("Full RX", "xcvr", "RX-001", [frontend, backend])
# Expand the frontend to show its individual devices in the block diagram
frontend.expand = True
full_rx.block_diagram()
Link Budget
from xcvr.linkbudget import LinkBudget
from xrench.units import ureg
lb = LinkBudget(
name="UHF Downlink",
pt=2 * ureg.watt,
gt=6 * ureg.dB,
gr=3 * ureg.dB,
nf=4 * ureg.dB,
distance=500 * ureg.km,
frequency=437 * ureg.MHz,
bandwidth=200 * ureg.kHz,
data_rate=9600 * ureg.bit / ureg.second,
ber_req=1e-6,
modulation="psk",
modulation_order=2,
)
print(lb.link_margin) # dB margin
print(lb.ebno) # achieved Eb/N0
print(lb.ebno_req) # required Eb/N0
print(lb.max_link_distance) # max range in km
# Rendered HTML table in Jupyter
from IPython.display import HTML, display
display(HTML(lb.view_link_table("tabular_margin")))
BER Curves
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from xrench.units import ureg
from xcvr.ber import mqam_ber
ebno = xr.DataArray(
np.linspace(0, 25, 101) * ureg.dB,
dims=("ebno",),
coords={"ebno": np.linspace(0, 25, 101)},
)
mqam_ber(ebno=ebno).plot.line(x="ebno", yscale="log")
plt.gca().set(xlabel="Eb/N0 [dB]", ylabel="BER")
plt.grid(True)
API Reference
Device
The base component. Wraps a skrf.Network and optional scalar performance parameters.
| Parameter | Description |
|---|---|
name |
Designator string (e.g. "A1") |
manufacturer |
Manufacturer name |
pn |
Part number |
network |
skrf.Network S-parameter data |
nf |
Noise figure (Quantity or DataArray) |
p1db |
Output-referred 1 dB compression point |
oip3 |
Output-referred IP3 |
psat |
Output-referred saturation power |
vsup / isup |
Supply voltage / current for power dissipation |
Key properties: .gain, .nf, .p1db, .oip3, .iip3, .psat, .noise_temperature, .noise_gain
System
A cascade of Device and/or nested System objects.
| Method / Property | Description |
|---|---|
.cascaded_gain |
Cumulative gain at each stage |
.cascaded_nf |
Cumulative Friis noise figure |
.cascaded_oip3 |
Cascaded OIP3 |
.cascaded_p1db |
Cascaded P1dB |
.cascaded_psat |
Cascaded Psat with limiting |
.cascaded_pdiss |
Cumulative power dissipation |
.get_signal_level(pin) |
Signal level at each stage with Psat limiting |
.get_dataframe(...) |
Styled pandas DataFrame of all parameters |
.get_dataset(...) |
xarray Dataset of all parameters |
.block_diagram() |
schemdraw block diagram |
.network |
Cascaded skrf.Network |
LinkBudget
Frozen dataclass representing a complete RF link.
Key properties: .eirp, .path_loss, .tsys, .g_over_t, .cnr, .ebno, .ebno_req, .link_margin, .ber, .max_path_loss, .max_link_distance
Tabular views: .tabular_margin, .tabular_cnr, .tabular_ebno (all return OrderedDict), rendered via .view_link_table()
BER Functions (xcvr.ber)
| Function | Description |
|---|---|
mqam_ber(p, ebno) |
M-QAM BER vs. Eb/N0 |
mpsk_ber(p, ebno) |
M-PSK BER vs. Eb/N0 |
mqam_ebno(p, ber) |
Required Eb/N0 for M-QAM at a target BER |
mpsk_ebno(p, ber) |
Required Eb/N0 for M-PSK at a target BER |
Modulation order p is the exponent: m = 2**p (e.g. p=2 → 4-QAM/QPSK, p=3 → 8-PSK).
Dependencies
- scikit-rf — S-parameter network manipulation
- schemdraw — block diagram drawing
- xarray — labeled N-D arrays
- pint — unit-aware quantities
- xrench — xarray + pint integration utilities
- numpy, scipy, pandas, matplotlib
License
MIT
Author
Created by Rob Scheeler
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xcvr-0.1.0.tar.gz.
File metadata
- Download URL: xcvr-0.1.0.tar.gz
- Upload date:
- Size: 24.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.6.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc1d20c0400830f1380838eb9cc8f74ac52bc7e57b20e8d6743f5db82a117d0c
|
|
| MD5 |
16b4efbee3dac2a7c7dd814697fbdeeb
|
|
| BLAKE2b-256 |
3dacac0db2e98152142d1a2f4f43a429121b9f9d2e304dd6144cc55b423bb58a
|
File details
Details for the file xcvr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: xcvr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.6.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9403e7d24d2dda23b393a560b8fbb6af2c5a681e54f0b245d6c4f34e19eb843
|
|
| MD5 |
cbb24ad4bf9d6066081fbb0bcf4c08b0
|
|
| BLAKE2b-256 |
8607cbd1cb56d6b287e2b53623836d1cfa23106170e5f90a3474ee4904ef5766
|