API Reference

This page documents the public API of simpleLOMs.

Package

Simple Lumped Oscillator Models for superconducting quantum device design.

class simpleLOMs.AnalyticalFit(mode: int = 2)[source]

Bases: BaseFit

Lumped LC model via the closed-form λ/2 CPW approximation.

Parameters:

mode (int, optional) – Resonance mode number (default 2 for the fundamental λ/2 mode). The formula C_r = m·π / (2·ω_r·Z0) generalises to higher modes.

L

Effective inductance in Henries. None before fit().

Type:

float or None

C

Effective capacitance in Farads. None before fit().

Type:

float or None

Examples

from simpleLOMs.models.analytical import AnalyticalFit
import skrf as rf

freq  = rf.Frequency(4e9, 10e9, 10_001, unit="Hz")
model = AnalyticalFit()

# Provide f_r and Z0 directly — no network needed
model.fit(freq, f_r=8.581e9, Z0=45.926)

print(model.get_params())
# {'L': 5.55e-10, 'C': 6.18e-13, 'f_r_Hz': 8.581e9, 'Z0': 45.926}

net = model.get_network(freq, Cc1=5e-15, Cc2=5e-15,
                        Ctog1=1e-14, Ctog2=1e-14)
fit(freq: Frequency, f_r: float, Z0: float, **kwargs) None[source]

Compute L and C from the closed-form λ/2 approximation.

Parameters:
  • freq (rf.Frequency) – Frequency sweep (not used in the calculation itself, but kept for a consistent BaseFit interface).

  • f_r (float) – Resonance frequency in Hz.

  • Z0 (float) – Characteristic impedance of the CPW line in Ohms.

  • **kwargs – Ignored.

get_network(freq: Frequency, Cc1: float, Cc2: float, Z0: float = 50.0, with_grounds: bool = True, Ctog1: float = None, Ctog2: float = None, **kwargs) Network[source]

Build the 2-port LC LOM network from the analytical L and C.

Parameters:
  • freq (rf.Frequency)

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Z0 (float) – Reference impedance in Ohms.

  • with_grounds (bool) – If True (default), include Ctog shunt capacitors. The analytical model is typically compared alongside the full CPW topology so including the grounds is more representative.

  • Ctog1 (float or None) – Required when with_grounds=True.

  • Ctog2 (float or None) – Required when with_grounds=True.

Return type:

rf.Network

get_params() dict[source]

Return the analytically computed parameters.

Returns:

Keys: “L” (H), “C” (F), “f_r_Hz”, “Z0”.

Return type:

dict

class simpleLOMs.CPWParams(w: float = 1.17e-05, s: float = 5.1e-06, t: float = 0.0, h: float = 0.0005, rho: float = 1e-19, ep_r: float = 11.45, has_metal_backside: bool = False, tand: float = 0.0)[source]

Bases: object

Physical geometry and material parameters for a Coplanar Waveguide (CPW).

w

Center conductor width (m). Default 11.7 µm.

Type:

float

s

Gap spacing between center conductor and ground plane (m). Default 5.1 µm.

Type:

float

t

Metal thickness (m). Set to 0 to ignore (for an ideal thin film). This quantity is generally on the order of 100-200 nm.

Type:

float

h

Substrate height (m). Default 500 µm.

Type:

float

rho

Metal resistivity (Ω·m). Set near 0 for superconducting limit.

Type:

float

ep_r

Substrate relative permittivity. Defaults to 11.45 (ultracold silicon).

Type:

float

has_metal_backside

Whether the substrate has a metal ground plane on its back side.

Type:

bool

tand

Loss tangent of the substrate. Set to 0 for a lossless superconducting circuit.

Type:

float

Examples

Use the defaults (ultracold silicon chip):
>>> cpw = CPWParams()
Override just the substrate:
>>> cpw = CPWParams(ep_r=11.9, has_metal_backside=False)
Pass into a network builder:
>>> net = cpw_resonator_network_2port(freq, d=7e-3, cpw_params=cpw, ...)
ep_r: float = 11.45
h: float = 0.0005
has_metal_backside: bool = False
rho: float = 1e-19
s: float = 5.1e-06
t: float = 0.0
tand: float = 0.0
w: float = 1.17e-05
class simpleLOMs.FosterFit(cpw_params: CPWParams = None, port_z0: float = 500.0)[source]

Bases: BaseFit

Lumped LC model via Foster admittance synthesis on a bare CPW line.

Parameters:
  • cpw_params (CPWParams, optional) – Physical geometry and material parameters for the CPW. Uses default CPWParams() (11.7 µm / 5.1 µm gap, ultracold Si) if not provided.

  • port_z0 (float, optional) – Port impedance used when building the bare CPW network for synthesis. Default 500 Ω (high impedance → weakly loaded line, closer to the unloaded resonator condition).

L

Fitted effective inductance in Henries. None before fit().

Type:

float or None

C

Fitted effective capacitance in Farads. None before fit().

Type:

float or None

yin

Complex input admittance array computed during fit(). Stored for diagnostics / plotting without recomputing.

Type:

np.ndarray or None

Examples

Basic usage:

from simpleLOMs.params import CPWParams
from simpleLOMs.models.foster import FosterFit
import skrf as rf

freq = rf.Frequency(4e9, 10e9, 10_001, unit="Hz")
cpw  = CPWParams(ep_r=11.45)

model = FosterFit(cpw_params=cpw)
model.fit(freq, d=7e-3)

print(model.get_params())
# {'L': 5.53e-10, 'C': 6.22e-13, 'f0_Hz': 8.58e9}

net = model.get_network(freq, Cc1=5e-15, Cc2=5e-15,
                        Ctog1=1e-14, Ctog2=1e-14)
fit(freq: Frequency, d: float, **kwargs) None[source]

Run Foster synthesis on a bare CPW line of length d.

Computes the input admittance Yin(ω), finds ω0 from a peak in Im(S22), then extracts C_eq from the admittance slope and L_eq from the resonance constraint ω0² L C = 1.

Parameters:
  • freq (rf.Frequency) – Frequency sweep. Should span at least one resonance of the bare CPW line at length d.

  • d (float) – Physical resonator length in metres.

  • **kwargs – Ignored — included for a consistent BaseFit interface.

get_network(freq: Frequency, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Z0: float = 50.0, **kwargs) Network[source]

Build the 2-port LC LOM network using the Foster-synthesised L and C.

Uses the “with grounds” topology so that Ctog1/Ctog2 are included, matching the structure of the CPW model that was synthesised.

Parameters:
  • freq (rf.Frequency) – May differ from the freq used in fit().

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port LC network with ground capacitors.

Return type:

rf.Network

get_params() dict[source]

Return fitted parameters.

Returns:

Keys: “L” (H), “C” (F), “f0_Hz” (resonance used for synthesis).

Return type:

dict

class simpleLOMs.OptimizationConfig(w0_window_frac: float = 1e-05, n_w0: int = 20, n_dense: int = 100, n_kappa: float = 0.75, n_widths: float = 1.0, max_nfev: int = 100, verbose: bool = False, fit_phase: bool = False, s_params: Sequence[str] = <factory>, weights: dict[str, float] | None=None)[source]

Bases: object

Tuning knobs for the two-stage OptimizedFit algorithm.

Core algorithm knobs

w0_window_fracfloat

Half-width of the ω0 scan window as a fraction of ω0_guess.

n_w0int

Number of ω0 grid points in the coarse scan.

n_denseint

Number of data points sampled around resonance in Stage 1.

n_kappafloat

Half-width of the dense sampling window in units of κ (linewidth).

n_widthsfloat

Half-width of each residual window in Stage 2, in units of κ.

max_nfevint

Maximum function evaluations for the Stage 2 least_squares call.

verbosebool

If True, least_squares prints iteration progress.

Residual configuration

fit_phasebool

If True, a global scalar phase φ is added to the free parameters so that the model prediction is e^{i·φ} · S_model. The fitted phase is stored in OptimizedFit.phase (radians) after fit().

s_paramssequence of str

Which S-parameter channels to include in Stage 2. Any non-empty subset of {“S11”, “S22”, “S21”, “S12”}. Default: (“S11”, “S22”).

weightsdict[str, float] or None

Manual per-channel weight multipliers applied after depth normalisation. None → equal weights (all 1.0). Example: {“S11”: 2.0, “S22”: 2.0, “S21”: 1.0}

channel_weight(name: str) float[source]

Return the manual weight for a channel (default 1.0).

fit_phase: bool = False
max_nfev: int = 100
n_dense: int = 100
n_kappa: float = 0.75
n_w0: int = 20
n_widths: float = 1.0
s_params: Sequence[str]
verbose: bool = False
w0_window_frac: float = 1e-05
weights: dict[str, float] | None = None
class simpleLOMs.OptimizedFit(config: OptimizationConfig = None)[source]

Bases: BaseFit

Lumped LC model via two-stage numerical optimisation.

Parameters:

config (OptimizationConfig, optional) – Hyperparameters and residual options. Defaults to OptimizationConfig() (S11 + S22, no phase fitting).

L

Fitted effective inductance in Henries.

Type:

float or None

C

Fitted effective capacitance in Farads.

Type:

float or None

phase

Fitted global phase in radians. None if config.fit_phase is False or before fit() is called.

Type:

float or None

scan_results

Diagnostic array from the Stage 1 ω0 scan, shape (n_w0, 4): columns are [ω0, Ceff, Leff, sse].

Type:

np.ndarray or None

Examples

from simpleLOMs.models.optimized_fit import OptimizedFit, OptimizationConfig

# Fit using only S21, with phase as a free parameter
cfg   = OptimizationConfig(s_params=["S21"], fit_phase=True)
model = OptimizedFit(config=cfg)
model.fit(freq, data_ntw=cpw_net, Cc1=3e-14, Cc2=7e-14,
          Ctog1=4e-14, Ctog2=6e-14, d=7e-3,
          cpw_params=cpw_params, Z0=50)
print(model)           # OptimizedFit(L=…, C=…, phase=…)
net = model.get_network(freq, Cc1=3e-14, Cc2=7e-14, Z0=50)
config: OptimizationConfig
fit(freq: Frequency, data_ntw: Network, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, d: float, cpw_params, Z0: float = 50.0, **kwargs) None[source]

Two-stage optimisation to fit Leff, Ceff (and optionally phase) to data_ntw.

Stage 1: coarse Nelder-Mead scan over ω0, constrained Ceff.

Uses an explicitly constructed 1-port CPW network so that the Stage 1 data points come from a true single-port reflection measurement rather than a 2-port S11 view.

Stage 2: windowed least_squares refinement on the channels specified

in config.s_params.

Parameters:
  • freq (rf.Frequency) – Frequency grid for the optimisation (should be centred on the resonance with enough bandwidth to capture the linewidth).

  • data_ntw (rf.Network) – 2-port reference network (CPW model or measured data).

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • d (float) – Resonator length in metres.

  • cpw_params (CPWParams) – CPW geometry parameters.

  • Z0 (float) – Reference impedance in Ohms.

get_network(freq: Frequency, Cc1: float, Cc2: float, Z0: float = 50.0, with_grounds: bool = False, Ctog1: float = None, Ctog2: float = None, shifted: bool = False, **kwargs) Network[source]

Build the 2-port LC LOM network from the optimised L and C.

Note: the optional fitted phase is not applied here because it is a calibration correction for the data, not a physical property of the LC network. Apply it separately if you need to compare against phase-corrected data:

net_s = net.s * np.exp(1j * model.phase)

Parameters:
  • freq (rf.Frequency)

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Z0 (float) – Reference impedance in Ohms.

  • with_grounds (bool) – If True, include Ctog1/Ctog2 shunt caps.

  • Ctog1 (float or None) – Required when with_grounds=True.

  • Ctog2 (float or None) – Required when with_grounds=True.

Return type:

rf.Network

get_params() dict[source]

Return fitted parameters and scan diagnostics.

Returns:

Keys: “L” (H), “C” (F), “phase” (rad or None),

”scan_results” (ndarray or None).

Return type:

dict

phase: float | None
scan_results: ndarray | None
class simpleLOMs.SweepConfig(cpw_params: CPWParams, freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, Z0: float = 50.0, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None)[source]

Bases: object

A complete snapshot of a device and its operating conditions.

Every parameter that any sweep might want to vary is a field here. The sweep machinery calls dataclasses.replace(config, field=new_value) to create a modified copy at each sweep point — the original is never mutated.

Parameters:
  • cpw_params (CPWParams) – Physical geometry of the CPW line.

  • freq (rf.Frequency) – Frequency sweep used for network construction. Should be wide enough to contain all resonances of interest.

  • d (float) – Resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Cload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Lload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Cload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Z0 (float) – Reference impedance in Ohms (default 50 Ω).

  • analytical_Z0 (float or None) – Characteristic impedance used in the AnalyticalFit formula. If None, Z0 is used.

  • opt_config (OptimizationConfig or None) – Hyperparameters for OptimizedFit. Uses defaults if None.

Examples

Creating a base config:

base = SweepConfig(
    cpw_params=CPWParams(),
    freq=rf.Frequency(4e9, 12e9, 10_001, unit="Hz"),
    d=7e-3,
    Cc1=5e-15, Cc2=5e-15,
    Ctog1=1e-14, Ctog2=1e-14,
    Lload1=5e-10, Cload1=6e-13,
    Lload2=5e-10, Cload2=6e-13,
)

Manually overriding one field:

longer = dataclasses.replace(base, d=9e-3)
Cc1: float
Cc2: float
Cload1: float
Cload2: float
Ctog1: float
Ctog2: float
Lload1: float
Lload2: float
Z0: float = 50.0
analytical_Z0: float | None = None
cpw_params: CPWParams
d: float
freq: Frequency
opt_config: OptimizationConfig | None = None
simpleLOMs.analyze_system(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, cpw_params: CPWParams | None = None, Z0: float = 50.0, analytical_f_r: float | None = None, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None, verbose: bool = False, shifted: bool = False) dict[source]

Compare FosterFit, OptimizedFit, and AnalyticalFit against a CPW reference.

Uses reflection circle fits on S11 and S22 for f0 and kappa extraction.

simpleLOMs.analyze_system_load_grid(*, freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, load1_freqs_hz: ndarray, load2_freqs_hz: ndarray, cpw_params: CPWParams | None = None, Z0: float = 50.0, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None, verbose: bool = False, shifted: bool = False, Cload1_fixed: float = 6e-13, Cload2_fixed: float = 6e-13) dict[source]
simpleLOMs.run_accuracy_sweep(sweep_params: dict, fixed_params: dict, save_path: str | None = None, skip_errors: bool = True, verbose: bool = True) list[source]

Run analyze_system() over a grid of parameter combinations.

simpleLOMs.run_accuracy_sweep_load_grid(*, sweep_params: dict, fixed_params: dict, load1_freqs_hz: ndarray, load2_freqs_hz: ndarray, save_path: str | None = None, skip_errors: bool = True, verbose: bool = True, n_jobs: int = 1) list[source]
simpleLOMs.sweep(param: str, values: ndarray, base_config: SweepConfig, extract: list[str], model: str = 'cpw', refit: bool | None = None) DataFrame[source]

Sweep a single parameter across a range of values and extract quantities.

At each sweep point, the chosen model is either rebuilt from scratch (for CPW or when the swept parameter changes L/C) or reuses the L/C fitted at the first sweep point (for Cc, Ctog, and load parameters).

Parameters:
  • param (str) – Name of the SweepConfig field to vary. Must be an attribute of SweepConfig, e.g. “d”, “Cc1”, “Cc2”, “Ctog1”, “Lload1”, “Cload1”. Use “Lload1_Lload2” or “Cload1_Cload2” to sweep both loads together.

  • values (np.ndarray) – Array of values for the swept parameter.

  • base_config (SweepConfig) – Fixed device state. Not mutated.

  • extract (list of str) –

    Quantities to compute at each sweep point. Supported values:

    ”f0_s11”

    S11 resonance frequency (GHz)

    ”f0_s22”

    S22 resonance frequency (GHz)

    ”kappa_s11”

    S11 linewidth / FWHM (MHz)

    ”kappa_s22”

    S22 linewidth / FWHM (MHz)

    ”Q_s11”

    Quality factor from S11 = f0 / kappa

    ”Q_s22”

    Quality factor from S22

  • model (str) – Which model to use: “cpw” (default), “foster”, “optimized”, or “analytical”.

  • refit (bool or None) – Whether to re-fit the LC model at every sweep point. None (default) means automatic: refit when sweeping a parameter in {d, cpw_params}, reuse L/C otherwise. Setting refit=True forces refitting at every point (slower but safer when sweeping Cc1/Cc2 with OptimizedFit). Setting refit=False always reuses the first-point L/C (fastest).

Returns:

One row per sweep point. Columns are the swept parameter value plus all requested extract quantities.

Return type:

pd.DataFrame

Examples

Sweep resonator length with CPW ground truth:

df = sweep("d", np.linspace(5e-3, 10e-3, 20), base,
           extract=["f0_s11", "kappa_s11"])

Sweep coupling cap with FosterFit (reuses L/C — fast):

df = sweep("Cc1", np.linspace(1e-15, 20e-15, 30), base,
           extract=["f0_s11", "kappa_s11", "Q_s11"],
           model="foster")
simpleLOMs.sweep_coupling(Cc_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw', symmetric: bool = True, refit: bool = False) DataFrame[source]

Sweep coupling capacitor(s).

Parameters:
  • Cc_values (np.ndarray) – Array of coupling capacitance values in Farads.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “kappa_s11”, “Q_s11”] if not provided.

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

  • symmetric (bool) – If True (default), sweeps Cc1 and Cc2 together. If False, sweeps only Cc1 and leaves Cc2 fixed.

  • refit (bool) – Whether to re-fit the LC model at every point. Default False because Cc does not change L or C — reusing is valid and fast. Set to True if you suspect OptimizedFit is sensitive to Cc during Stage 1 (unlikely but possible for very asymmetric coupling).

Returns:

Columns: “Cc” (the swept value), plus all extract quantities.

Return type:

pd.DataFrame

simpleLOMs.sweep_length(d_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw') DataFrame[source]

Sweep resonator length d.

Always refits the model at every point because d directly sets L and C.

Parameters:
  • d_values (np.ndarray) – Array of resonator lengths in metres.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “kappa_s11”] if not provided.

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

Returns:

Columns: “d”, plus all extract quantities.

Return type:

pd.DataFrame

simpleLOMs.sweep_load_frequency(f_load_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw', side: str = 'both', load_impedance: float = 50.0, refit: bool = False) DataFrame[source]

Sweep the bare load resonance frequency.

Converts each target frequency to a (L, C) pair by fixing the load characteristic impedance Z_load = sqrt(L/C), then sweeping C = 1/(ω²L).

Parameters:
  • f_load_values (np.ndarray) – Array of target load resonance frequencies in Hz.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “shift_mode1”, “shift_mode2”, “shift_mode3”].

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

  • side ({"both", "1", "2"}) – Which load to sweep. “both” sweeps load 1 and load 2 together (useful when the two loads are identical, e.g. symmetric qubits).

  • load_impedance (float) – Characteristic impedance of the load resonator in Ohms. Used to fix L from Z_load = sqrt(L/C) → L = Z_load / ω₀. Default 50 Ω.

  • refit (bool) – Whether to re-fit the LC model at every point. Default False.

Returns:

Columns: “f_load_GHz” (the swept load frequency in GHz), “Lload” (H), “Cload” (F), plus all extract quantities.

Return type:

pd.DataFrame

Parameters

params.py

Shared parameter dataclasses used across simpleLOMs.

Here we define CPWParams once. Every function that needs CPW geometry accepts a single CPWParams.

class simpleLOMs.params.CPWParams(w: float = 1.17e-05, s: float = 5.1e-06, t: float = 0.0, h: float = 0.0005, rho: float = 1e-19, ep_r: float = 11.45, has_metal_backside: bool = False, tand: float = 0.0)[source]

Bases: object

Physical geometry and material parameters for a Coplanar Waveguide (CPW).

w

Center conductor width (m). Default 11.7 µm.

Type:

float

s

Gap spacing between center conductor and ground plane (m). Default 5.1 µm.

Type:

float

t

Metal thickness (m). Set to 0 to ignore (for an ideal thin film). This quantity is generally on the order of 100-200 nm.

Type:

float

h

Substrate height (m). Default 500 µm.

Type:

float

rho

Metal resistivity (Ω·m). Set near 0 for superconducting limit.

Type:

float

ep_r

Substrate relative permittivity. Defaults to 11.45 (ultracold silicon).

Type:

float

has_metal_backside

Whether the substrate has a metal ground plane on its back side.

Type:

bool

tand

Loss tangent of the substrate. Set to 0 for a lossless superconducting circuit.

Type:

float

Examples

Use the defaults (ultracold silicon chip):
>>> cpw = CPWParams()
Override just the substrate:
>>> cpw = CPWParams(ep_r=11.9, has_metal_backside=False)
Pass into a network builder:
>>> net = cpw_resonator_network_2port(freq, d=7e-3, cpw_params=cpw, ...)
ep_r: float = 11.45
h: float = 0.0005
has_metal_backside: bool = False
rho: float = 1e-19
s: float = 5.1e-06
t: float = 0.0
tand: float = 0.0
w: float = 1.17e-05

System

system.py

Top-level orchestration: runs all three fitting methods and compares them against the CPW reference network using reflection circle fits.

simpleLOMs.system.analyze_system(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, cpw_params: CPWParams | None = None, Z0: float = 50.0, analytical_f_r: float | None = None, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None, verbose: bool = False, shifted: bool = False) dict[source]

Compare FosterFit, OptimizedFit, and AnalyticalFit against a CPW reference.

Uses reflection circle fits on S11 and S22 for f0 and kappa extraction.

simpleLOMs.system.analyze_system_cf(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, cpw_params: CPWParams | None = None, Z0: float = 50.0, analytical_f_r: float | None = None, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None, verbose: bool = False, shifted: bool = False) dict

Compare FosterFit, OptimizedFit, and AnalyticalFit against a CPW reference.

Uses reflection circle fits on S11 and S22 for f0 and kappa extraction.

simpleLOMs.system.run_accuracy_sweep(sweep_params: dict, fixed_params: dict, save_path: str | None = None, skip_errors: bool = True, verbose: bool = True) list[source]

Run analyze_system() over a grid of parameter combinations.

simpleLOMs.system.run_accuracy_sweep_cf(sweep_params: dict, fixed_params: dict, save_path: str | None = None, skip_errors: bool = True, verbose: bool = True) list

Run analyze_system() over a grid of parameter combinations.

Analysis

analysis.py

Pure numerical analysis functions for extracting resonance frequencies and linewidths from S-parameter networks.

None of these functions build networks or do optimization — they only inspect existing rf.Network objects. This makes them easy to test independently and reuse across models.

simpleLOMs.analysis.circle_fit_f0_kappa(ntwk: Network, m: int = 0, n: int = 0, smooth_window: int | None = 51, smooth_polyorder: int = 3) tuple[float, float][source]

Extract resonance frequency (f0) and linewidth (kappa) from a circle fit to S[m,n] in the complex plane (reflection S11/S22).

Returns:

  • f0 (float) – Resonance frequency in Hz.

  • kappa (float) – Linewidth (FWHM of the angular velocity peak) in Hz.

simpleLOMs.analysis.circle_fit_modes(ntwk: Network, m: int = 0, n: int = 0, n_modes: int = 3, prominence: float = None, min_spacing_hz: float = None, smooth_window: int | None = 51, smooth_polyorder: int = 3) tuple[ndarray, ndarray][source]

Find multiple resonance modes in S[m,n] using the reflection circle fit.

Returns:

  • f0s (np.ndarray) – Mode frequencies in Hz, length n_modes (NaN-padded).

  • kappas (np.ndarray) – Mode linewidths in Hz, length n_modes (NaN-padded).

simpleLOMs.analysis.find_resonant_frequency(network: Network) complex[source]
simpleLOMs.analysis.fwhm_from_res11(ntwk: Network) float[source]

Linewidth from zero crossings of Re(S11).

Re(S11) crosses zero at the two half-power frequencies of the resonance. Uses linear interpolation between samples for accuracy.

Parameters:

ntwk (rf.Network)

Returns:

Linewidth (distance between the two zero crossings) in Hz.

Return type:

float

Raises:

ValueError – If fewer than two zero crossings are found.

simpleLOMs.analysis.fwhm_from_trace_db(ntwk: Network, m: int = 0, n: int = 0, kind: str = 'dip', smooth: int = None) float[source]

Full-Width at Half Maximum (FWHM) from S-parameter magnitude in dB.

Uses crossing-interpolation to find the two frequencies where the magnitude crosses the half-depth level, giving a more accurate result than a pure index-based approach.

Parameters:
  • ntwk (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • kind ({"dip", "peak"}) – “dip” — resonance appears as a downward dip (typical for S11/S22). “peak” — resonance appears as an upward peak (typical for S12/S21).

  • smooth (int or None) – Optional moving-average window length for noisy traces. Use an odd integer; None disables smoothing.

Returns:

FWHM linewidth in Hz.

Return type:

float

Raises:

ValueError – If two crossings at the half-depth level cannot be found.

simpleLOMs.analysis.resonance(ntwk: Network, m: int = 0, n: int = 0, use_max: bool = False, method: str = 'min_re') float[source]

Estimate resonance frequency from S[m,n].

Parameters:
  • ntwk (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • use_max (bool) – Only used for method=’min_re’. If True, find frequency of maximum Re(S) instead of minimum.

  • method (str) –

    Resonance estimator. Supported:
    • ’min_re’ : min/max of Re(S)

    • ’circle_fit’ : circle fit in complex plane

Returns:

Resonance frequency in Hz.

Return type:

float

simpleLOMs.analysis.resonance_circle_fit(ntwk: Network, m: int = 0, n: int = 0, smooth_window: int | None = 51, smooth_polyorder: int = 3) float[source]

Estimate resonance frequency from a circle fit to S[m,n] in the complex plane.

Strategy

  1. Fit a circle to the complex trace S[m,n](f).

  2. Compute the angle of each point about the fitted center.

  3. Take the frequency where |d(theta)/df| is largest.

This is usually a good reflection-based estimator for S11/S22.

param ntwk:

type ntwk:

rf.Network

param m:

S-parameter indices.

type m:

int

param n:

S-parameter indices.

type n:

int

param smooth_window:

Optional Savitzky-Golay smoothing window for theta before differentiation. Must be odd if provided.

type smooth_window:

int or None

param smooth_polyorder:

Polynomial order for Savitzky-Golay smoothing.

type smooth_polyorder:

int

returns:

Resonance frequency in Hz.

rtype:

float

simpleLOMs.analysis.resonance_from_res11(ntwk: Network) float[source]

Resonance frequency from the minimum of Re(S11).

Thin convenience wrapper around resonance for the common single-port S11 case.

Parameters:

ntwk (rf.Network)

Returns:

Resonance frequency in Hz.

Return type:

float

simpleLOMs.analysis.resonance_from_s_max(network: Network, m: int = 0, n: int = 0) float[source]

Resonance frequency from the dominant peak in |S[m,n]|.

Finds all peaks in the magnitude and returns the frequency of the largest one. Useful for transmission parameters (S12/S21) where the resonance appears as a peak rather than a dip.

Parameters:
  • network (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

Returns:

Dominant resonance frequency in GHz.

Return type:

float

Raises:

ValueError – If no peaks are found in |S[m,n]|.

simpleLOMs.analysis.resonances(ntwk: Network, m: int = 0, n: int = 0, n_modes: int = 3, method: str = 'min_re', prominence: float = None, min_spacing_hz: float = None) ndarray[source]

Estimate resonance frequencies for multiple modes from S[m,n].

Parameters:
  • ntwk (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • n_modes (int) – Number of resonant modes to find.

  • method (str) –

    Resonance estimator. Supported:
    • ’min_re’ : finds n_modes minima of Re(S)

    • ’circle_fit’ : finds n_modes peaks of |dθ/df| from circle fit

  • prominence (float, optional) – Minimum peak prominence passed to scipy.signal.find_peaks. If None, defaults to 0.1 * (max - min) of the trace being searched.

  • min_spacing_hz (float, optional) – Minimum frequency separation between modes in Hz. If None, defaults to (f_max - f_min) / (10 * n_modes).

Returns:

Resonance frequencies in Hz, sorted ascending, length n_modes. If fewer than n_modes peaks are found, the array is padded with NaN.

Return type:

np.ndarray

simpleLOMs.analysis.resonances_from_s(network: Network, m: int = 0, n: int = 0) ndarray[source]

Find all resonance frequencies from peaks in Re(S[m,n]).

Parameters:
  • network (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

Returns:

Array of resonance frequencies in GHz.

Return type:

np.ndarray

simpleLOMs.analysis.resonances_from_s_max(network: Network, m: int = 0, n: int = 0) float[source]

Resonance frequency from the dominant peak in |S[m,n]|.

Finds all peaks in the magnitude and returns the frequency of the largest one. Useful for transmission parameters (S12/S21) where the resonance appears as a peak rather than a dip.

Parameters:
  • network (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

Returns:

Dominant resonance frequency in GHz.

Return type:

float

Raises:

ValueError – If no peaks are found in |S[m,n]|.

simpleLOMs.analysis.stitch_shifted_freqs(*arrays: ndarray, dedup_tol_ghz: float = 0.05, return_sources: bool = False)[source]

Merge S11/S22 mode frequency lists, deduplicating nearby modes.

Models

Elements

elements.py

Primitive lumped-element circuit blocks built on top of scikit-rf. Each function returns an rf.Network (a 2-port element) that can be wired into an rf.Circuit connection list.

For netowrks built using these eleemnts see simpleLOMs/networks/.

simpleLOMs.elements.coupling_capacitor(C: float, freq: Frequency, name: str = 'cc', Z0: float = 50) Network[source]

Series coupling capacitor.

Implemented as a SeriesImpedance with Z = 1 / (jωC).

Parameters:
  • C (float) – Capacitance in Farads.

  • freq (rf.Frequency) – Frequency sweep object.

  • name (str) – Label used inside rf.Circuit.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port series capacitor network.

Return type:

rf.Network

simpleLOMs.elements.lc_resonator(L: float, C: float, freq: Frequency, name: str = 'lc', Z0: float = 50) Network[source]

Parallel LC resonator shunted to ground.

Implemented as a ShuntAdmittance with Y = jωC + 1/(jωL), the admittance of a parallel LC tank.

Parameters:
  • L (float) – Inductance in Henries.

  • C (float) – Capacitance in Farads.

  • freq (rf.Frequency) – Frequency sweep object.

  • name (str) – Label used inside rf.Circuit.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port shunt parallel-LC network.

Return type:

rf.Network

simpleLOMs.elements.shunt_capacitor(C: float, freq: Frequency, name: str = 'ctog', Z0: float = 50) Network[source]

Shunt (to-ground) capacitor.

Implemented as a ShuntAdmittance with Y = jωC.

Parameters:
  • C (float) – Capacitance in Farads.

  • freq (rf.Frequency) – Frequency sweep object.

  • name (str) – Label used inside rf.Circuit.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port shunt capacitor network.

Return type:

rf.Network

Networks

networks/cpw.py

Network builders for CPW (Coplanar Waveguide) resonator topologies.

Each function takes a CPWParams dataclass for device geometry plus circuit-level parameters (coupling caps, frequency, etc.) and returns an rf.Network.

Topology overview

All networks follow the same chain:

[Port1] – Cc1 – Ctog1 – [CPW line] – Ctog2 – Cc2 – [Port2 or Open]

The “loaded” variants insert an LC resonator between the port and the coupling capacitor on each side:

[Port1] – cc_port1 – load1 – Cc1 – Ctog1 – [CPW line] – …

simpleLOMs.networks.cpw.cpw_resonator_loaded_network_2port(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, cpw_params: CPWParams = None, Z0: float = 50) Network[source]

Two-port CPW resonator with an LC load on each port side.

The loads model external resonators (e.g. qubits or readout resonators) weakly coupled to each port via small series capacitors.

Topology:
[Port1] – cc_port1 – load1 (shunt LC) – Cc1 – Ctog1 – [CPW line]

– Ctog2 – Cc2 – load2 (shunt LC) – cc_port2 – [Port2]

Parameters:
  • freq (rf.Frequency)

  • d (float) – Resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Cload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Lload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Cload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • cpw_params (CPWParams, optional) – CPW geometry. Uses default CPWParams() if not provided.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port loaded transmission network.

Return type:

rf.Network

simpleLOMs.networks.cpw.cpw_resonator_network(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, cpw_params: CPWParams = None, Z0: float = 50) Network[source]

Single-port CPW resonator (reflection measurement, port + open termination).

Topology:

[Port1] – Cc1 (series) – Ctog1 (shunt) – [CPW line] – Ctog2 (shunt) – Cc2 (shunt) – [Open]

Parameters:
  • freq (rf.Frequency)

  • d (float) – Physical resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • cpw_params (CPWParams, optional) – CPW geometry. Uses default CPWParams() if not provided.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

1-port reflection network.

Return type:

rf.Network

simpleLOMs.networks.cpw.cpw_resonator_network_2port(freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, cpw_params: CPWParams = None, Z0: float = 50) Network[source]

Two-port CPW resonator (transmission measurement, port on each side).

Topology:

[Port1] – Cc1 (series) – Ctog1 (shunt) – [CPW line] – Ctog2 (shunt) – Cc2 (series) – [Port2]

Parameters:
  • freq (rf.Frequency)

  • d (float) – Physical resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • cpw_params (CPWParams, optional) – CPW geometry. Uses default CPWParams() if not provided.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port transmission network.

Return type:

rf.Network

simpleLOMs.networks.cpw.cpw_resonator_single_load_network_2port(freq: Frequency, d: float, Cc1: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, cpw_params: CPWParams = None, Z0: float = 50) Network[source]

Two-port CPW resonator with an LC load on each port side.

The loads model external resonators (e.g. qubits or readout resonators) weakly coupled to each port via small series capacitors.

Topology:
[Port1] – cc_port1 – load1 (shunt LC) – Cc1 – Ctog1 – [CPW line]

– Ctog2 – Cc2 – load2 (shunt LC) – cc_port2 – [Port2]

Parameters:
  • freq (rf.Frequency)

  • d (float) – Resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Cload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Lload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Cload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • cpw_params (CPWParams, optional) – CPW geometry. Uses default CPWParams() if not provided.

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port loaded transmission network.

Return type:

rf.Network

networks/lc.py

Network builders for lumped-element LC resonator topologies.

Topology families

Basic 2-port:

[Port1] – Cc1 – [LC shunt] – Cc2 – [Port2]

With grounds (mirrors CPW Ctog capacitors):

[Port1] – Cc1 – Ctog1 – [LC shunt] – Ctog2 – Cc2 – [Port2]

Loaded variants insert an LC load (e.g. a qubit) on each port side:

[Port1] – cc_port – load – Cc1 – … – Cc2 – load – cc_port – [Port2]

simpleLOMs.networks.lc.lc_load_bare_network(Lload: float, Cload: float, Cc_port: float, freq: Frequency, Z0: float = 50) Network[source]

Single isolated LC load resonator coupled to one port via Cc_port. Used to extract the ‘true’ bare frequency of a load as seen from the port, accounting for the capacitive loading of the coupler.

Topology:

[Port1] – Cc_port (series) – [LC shunt] – [Open]

Parameters:
  • Lload (float) – Inductance (H) and capacitance (F) of the load resonator.

  • Cload (float) – Inductance (H) and capacitance (F) of the load resonator.

  • Cc_port (float) – Coupling capacitance to the port (F).

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

1-port reflection network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_load_dressed_network(Lload: float, Cload: float, Cc_port: float, Cc1: float, freq: Frequency, Z0: float = 50) Network[source]
simpleLOMs.networks.lc.lc_load_dressed_network_2(Lload: float, Cload: float, Cc_port: float, Cc1: float, freq: Frequency, Z0: float = 50) Network[source]

Isolated LC load with both port coupler and CPW coupler attached, to extract the ‘dressed’ bare frequency accounting for capacitive loading from both sides.

Topology:

[Port1] – Cc_port (series) – [LC shunt] – Cc1 (series) – [Open]

Parameters:
  • Lload (float) – Inductance (H) and capacitance (F) of the load resonator.

  • Cload (float) – Inductance (H) and capacitance (F) of the load resonator.

  • Cc_port (float) – Port coupling capacitance (F) — hardcoded as 1e-15 in your topology.

  • Cc1 (float) – CPW-side coupling capacitance (F).

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

1-port reflection network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_loaded_network_2port(Leff: float, Ceff: float, Cc1: float, Cc2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with LC loads on each port side.

Topology:

[Port1] – cc_port1 – load1 – Cc1 – [LC shunt] – Cc2 – load2 – cc_port2 – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Lload1 (float) – Load resonator on port 1 side.

  • Cload1 (float) – Load resonator on port 1 side.

  • Lload2 (float) – Load resonator on port 2 side.

  • Cload2 (float) – Load resonator on port 2 side.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port loaded transmission network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_loaded_network_2port_shifted(Leff: float, Ceff: float, Cc1: float, Cc2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port loaded LC resonator with π-phase correction on S21/S12.

Identical to lc_resonator_loaded_network_2port but negates S21/S12 to account for the missing half-wave CPW phase. See lc_resonator_network_2port_shifted for full explanation.

Topology:

[Port1] – cc_port1 – load1 – Cc1 – [LC shunt] – Cc2 – load2 – cc_port2 – [Port2] (then S21, S12 negated)

simpleLOMs.networks.lc.lc_resonator_loaded_network_with_grounds_2port(Leff: float, Ceff: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with both ground capacitors and LC loads.

This is the most complete LC LOM topology: it includes the shunt Ctog capacitors that model CPW ground geometry AND external load resonators on each port side.

Topology:

[Port1] – cc_port1 – load1 – Cc1 – Ctog1 – [LC shunt] – Ctog2 – Cc2 – load2 – cc_port2 – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Load resonator on port 1 side.

  • Cload1 (float) – Load resonator on port 1 side.

  • Lload2 (float) – Load resonator on port 2 side.

  • Cload2 (float) – Load resonator on port 2 side.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port fully-loaded transmission network with ground caps.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_network(Leff: float, Ceff: float, Cc1: float, Cc2: float, freq: Frequency, Z0: float = 50) Network[source]

Single-port LC resonator (reflection measurement).

Topology:

[Port1] – Cc1 (series) – [LC shunt] – Cc2 (shunt to open) – [Open]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

1-port reflection network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_network_2port(Leff: float, Ceff: float, Cc1: float, Cc2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator (transmission measurement).

Topology:

[Port1] – Cc1 (series) – [LC shunt] – Cc2 (series) – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port transmission network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_network_2port_shifted(Leff: float, Ceff: float, Cc1: float, Cc2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with π-phase correction on S21/S12.

Identical to lc_resonator_network_2port but negates the off-diagonal S-matrix elements to account for the π electrical phase that a half-wave CPW resonator accumulates at resonance. A lumped LC shunt has no transmission line length so it does not pick up this phase naturally; the correction restores the correct sign convention for comparison against CPW reference networks.

Topology:

[Port1] – Cc1 (series) – [LC shunt] – Cc2 (series) – [Port2] (then S21, S12 negated)

simpleLOMs.networks.lc.lc_resonator_network_with_grounds_2port(Leff: float, Ceff: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with shunt-to-ground capacitors on each side.

These Ctog capacitors mirror the geometry of the CPW model, where the ground capacitance at each gap is an important feature of the distributed line.

Topology:

[Port1] – Cc1 – Ctog1 (shunt) – [LC shunt] – Ctog2 (shunt) – Cc2 – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the LC resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port transmission network with ground capacitances.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_single_load_network_2port(Leff: float, Ceff: float, Cc1: float, Lload1: float, Cload1: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with LC loads on each port side.

Topology:

[Port1] – cc_port1 – load1 – Cc1 – [LC shunt] – Cc2 – load2 – cc_port2 – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Lload1 (float) – Load resonator on port 1 side.

  • Cload1 (float) – Load resonator on port 1 side.

  • Lload2 (float) – Load resonator on port 2 side.

  • Cload2 (float) – Load resonator on port 2 side.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port loaded transmission network.

Return type:

rf.Network

simpleLOMs.networks.lc.lc_resonator_single_load_network_with_grounds_2port(Leff: float, Ceff: float, Cc1: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, freq: Frequency, Z0: float = 50) Network[source]

Two-port LC resonator with both ground capacitors and LC loads.

This is the most complete LC LOM topology: it includes the shunt Ctog capacitors that model CPW ground geometry AND external load resonators on each port side.

Topology:

[Port1] – cc_port1 – load1 – Cc1 – Ctog1 – [LC shunt] – Ctog2 – Cc2 – load2 – cc_port2 – [Port2]

Parameters:
  • Leff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Ceff (float) – Effective inductance (H) and capacitance (F) of the main resonator.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Load resonator on port 1 side.

  • Cload1 (float) – Load resonator on port 1 side.

  • Lload2 (float) – Load resonator on port 2 side.

  • Cload2 (float) – Load resonator on port 2 side.

  • freq (rf.Frequency)

  • Z0 (float) – Reference impedance in Ohms.

Returns:

2-port fully-loaded transmission network with ground caps.

Return type:

rf.Network

Plotting

plotting.py

Plotting functions for notebooks or scripts after running fits.

simpleLOMs.plotting.fancy_plot(lom_network: Network, data_network: Network, m: int = 0, n: int = 0, lom_label: str = 'LOM', data_label: str = 'Data') None[source]
simpleLOMs.plotting.fancy_plot_all_models(networks: dict[str, Network], m: int = 0, n: int = 0, quantity: str = 're', title: str = None) None[source]

Plot one S-parameter quantity for multiple networks on a single axes. Useful for comparing CPW, FosterFit, OptimizedFit, and AnalyticalFit in one call.

Parameters:
  • networks (dict[str, rf.Network]) – Mapping of label → network, e.g. {“CPW”: cpw_net, “Foster”: foster_net, “Optimized”: opt_net}

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • quantity ({"re", "im", "db", "abs"}) – Which quantity to plot.

  • title (str, optional) – Plot title.

simpleLOMs.plotting.plot_all_models(networks: dict[str, Network], m: int = 0, n: int = 0, quantity: str = 're', title: str = None) None[source]

Plot one S-parameter quantity for multiple networks on a single axes.

Useful for comparing CPW, FosterFit, OptimizedFit, and AnalyticalFit in one call.

Parameters:
  • networks (dict[str, rf.Network]) – Mapping of label → network, e.g. {“CPW”: cpw_net, “Foster”: foster_net, “Optimized”: opt_net}

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • quantity ({"re", "im", "db", "abs"}) – Which quantity to plot.

  • title (str, optional) – Plot title.

simpleLOMs.plotting.plot_complex_network_comparison(network1: Network, network2: Network, label1: str = 'Network 1', label2: str = 'Network 2', color1: str = '#1f77b4', color2: str = '#d62728')[source]
simpleLOMs.plotting.plot_error_heatmap(results_grid: list[list[dict]], param1_values, param2_values, param1_label: str, param2_label: str, model: str, metric: str, param1_scale: float = 1.0, param2_scale: float = 1.0, param1_unit: str = '', param2_unit: str = '', vmin: float = None, vmax: float = None, cmap: str = 'RdBu_r', title: str = None, ax=None, save_path: str = None)[source]

Heatmap of signed percent error from a 2D grid of analyze_system() runs.

Parameters:
  • results_grid (list[list[dict]]) – 2D list of analyze_system() output dicts. Shape: [len(param1_values)][len(param2_values)]. Axis 0 = param1 (y-axis), axis 1 = param2 (x-axis).

  • param1_values (array-like) – The swept parameter values. param1 → y-axis, param2 → x-axis.

  • param2_values (array-like) – The swept parameter values. param1 → y-axis, param2 → x-axis.

  • param1_label (str) – Human-readable axis labels (e.g. “Cc1”, “Load frequency”).

  • param2_label (str) – Human-readable axis labels (e.g. “Cc1”, “Load frequency”).

  • model (str) – “optimized”, “foster”, or “analytical”.

  • metric (str) –

    One of: “f0_s11”, “f0_s22”, “kappa_s11”, “kappa_s22”,

    ”shift_mode1”, “shift_mode2”, “shift_mode3”, “shift_max”.

  • param1_scale (float) – Multiply parameter values before display (e.g. 1e15 to show fF).

  • param2_scale (float) – Multiply parameter values before display (e.g. 1e15 to show fF).

  • param1_unit (str) – Unit string appended to axis labels (e.g. “fF”, “GHz”).

  • param2_unit (str) – Unit string appended to axis labels (e.g. “fF”, “GHz”).

  • vmin (float, optional) – Colour scale limits. If None, uses symmetric limits around zero based on the data range.

  • vmax (float, optional) – Colour scale limits. If None, uses symmetric limits around zero based on the data range.

  • cmap (str) – Matplotlib colormap name. Default “RdBu_r” (red = positive error, blue = negative error, white = zero).

  • title (str, optional)

  • ax (matplotlib.axes.Axes, optional) – If provided, draws into this axes (used by plot_error_heatmap_trio).

  • save_path (str, optional) – Only used when ax is None (i.e. this is a standalone call).

Returns:

The image object (needed by plot_error_heatmap_trio to set shared limits).

Return type:

matplotlib.image.AxesImage

simpleLOMs.plotting.plot_error_heatmap_trio(results_grid: list[list[dict | None]], param1_values, param2_values, param1_label: str, param2_label: str, metric: str, param1_scale: float = 1.0, param2_scale: float = 1.0, param1_unit: str = '', param2_unit: str = '', cmap: str = 'RdBu_r', title: str = None, save_path: str = None)[source]
simpleLOMs.plotting.plot_fit_residuals(data_ntw, lom_networks: dict, m: int = 0, n: int = 0, title: str = None, save_path: str = None)[source]

Plot the complex residual S_lom - S_data for one or more LOM networks.

Residuals are shown as Re and Im separately. A perfect fit is a flat zero line. Systematic errors (frequency offset, linewidth mismatch) appear as structured curves — much more diagnostic than an overlay.

Parameters:
  • data_ntw (rf.Network) – Reference (CPW or measured) network.

  • lom_networks (dict[str, rf.Network]) – Mapping of label → fitted LOM network. Labels should be “optimized”, “foster”, or “analytical” to get automatic colours, or any string for a custom label.

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • title (str, optional)

  • save_path (str, optional) – If provided, saves figure to this path at 300 dpi.

simpleLOMs.plotting.plot_fit_summary(results: dict, port: str = 's11', title: str = None, save_path: str = None)[source]

Three-panel summary of fitting quality for all three LC models vs CPW.

Panels:

Left — Overlay of Re(S) for CPW + all three models Centre — f₀ and κ percent errors as a grouped bar chart Right — Complex residual magnitude |S_lom - S_cpw| across the window

Parameters:
  • results (dict) – Output dict from analyze_system().

  • port ({"s11", "s22"}) – Which reflection port to summarise.

  • title (str, optional)

  • save_path (str, optional)

simpleLOMs.plotting.plot_lom_vs_data_re_im(lom_network: Network, data_network: Network, m: int = 0, n: int = 0, lom_label: str = 'LOM', data_label: str = 'Data') None[source]

Overlay Re and Im of a fitted LOM network against a reference (data/CPW).

Parameters:
  • lom_network (rf.Network) – The fitted lumped-element model.

  • data_network (rf.Network) – The reference (measured or CPW simulation).

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • lom_label (str) – Legend labels.

  • data_label (str) – Legend labels.

simpleLOMs.plotting.plot_pole_fit(network: Network, pole: complex)[source]
simpleLOMs.plotting.plot_re_im(network: Network, m: int = 0, n: int = 0, dpi: int = 300, title: str = None) None[source]

Plot Re(S[m,n]) and Im(S[m,n]) side by side.

Parameters:
  • network (rf.Network)

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • dpi (int) – Save DPI (does not affect the displayed figure).

  • title (str, optional) – Super-title for the figure.

simpleLOMs.plotting.plot_shift_errors(results: dict, title: str = None, save_path: str = None)[source]
simpleLOMs.plotting.plot_transmission_spectrum(networks: dict, m: int = 0, n: int = 1, annotate_resonances: bool = True, prominence: float = 3.0, title: str = None, save_path: str = None)[source]

Plot |S_mn| in dB for one or more networks, resembling a VNA screenshot.

Resonance dips/peaks are found automatically and annotated with their frequency and depth. Designed to look like a measurement so that simulation and data can be compared at a glance.

Parameters:
  • networks (dict[str, rf.Network]) – Mapping of label → network. Use “cpw”, “optimized”, etc. for automatic colours, or any string.

  • m (int) – S-parameter indices (0-based). Default S21 (0,1).

  • n (int) – S-parameter indices (0-based). Default S21 (0,1).

  • annotate_resonances (bool) – If True, marks each resonance with a vertical line and frequency label.

  • prominence (float) – Minimum prominence in dB for peak/dip detection.

  • title (str, optional)

  • save_path (str, optional)

simpleLOMs.plotting.upgraded_plot_lom_vs_data_re_im(lom_network: Network, data_network: Network, m: int = 0, n: int = 0, lom_label: str = 'LOM', data_label: str = 'Data') None[source]

Overlay Re and Im of a fitted LOM network against a reference (data/CPW).

Parameters:
  • lom_network (rf.Network) – The fitted lumped-element model.

  • data_network (rf.Network) – The reference (measured or CPW simulation).

  • m (int) – S-parameter indices (0-based).

  • n (int) – S-parameter indices (0-based).

  • lom_label (str) – Legend labels.

  • data_label (str) – Legend labels.

Sweeps

class simpleLOMs.sweeps.SweepConfig(cpw_params: CPWParams, freq: Frequency, d: float, Cc1: float, Cc2: float, Ctog1: float, Ctog2: float, Lload1: float, Cload1: float, Lload2: float, Cload2: float, Z0: float = 50.0, analytical_Z0: float | None = None, opt_config: OptimizationConfig | None = None)[source]

Bases: object

A complete snapshot of a device and its operating conditions.

Every parameter that any sweep might want to vary is a field here. The sweep machinery calls dataclasses.replace(config, field=new_value) to create a modified copy at each sweep point — the original is never mutated.

Parameters:
  • cpw_params (CPWParams) – Physical geometry of the CPW line.

  • freq (rf.Frequency) – Frequency sweep used for network construction. Should be wide enough to contain all resonances of interest.

  • d (float) – Resonator length in metres.

  • Cc1 (float) – Coupling capacitances in Farads.

  • Cc2 (float) – Coupling capacitances in Farads.

  • Ctog1 (float) – Shunt-to-ground capacitances in Farads.

  • Ctog2 (float) – Shunt-to-ground capacitances in Farads.

  • Lload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Cload1 (float) – Inductance (H) and capacitance (F) of the load on port 1 side.

  • Lload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Cload2 (float) – Inductance (H) and capacitance (F) of the load on port 2 side.

  • Z0 (float) – Reference impedance in Ohms (default 50 Ω).

  • analytical_Z0 (float or None) – Characteristic impedance used in the AnalyticalFit formula. If None, Z0 is used.

  • opt_config (OptimizationConfig or None) – Hyperparameters for OptimizedFit. Uses defaults if None.

Examples

Creating a base config:

base = SweepConfig(
    cpw_params=CPWParams(),
    freq=rf.Frequency(4e9, 12e9, 10_001, unit="Hz"),
    d=7e-3,
    Cc1=5e-15, Cc2=5e-15,
    Ctog1=1e-14, Ctog2=1e-14,
    Lload1=5e-10, Cload1=6e-13,
    Lload2=5e-10, Cload2=6e-13,
)

Manually overriding one field:

longer = dataclasses.replace(base, d=9e-3)
Cc1: float
Cc2: float
Cload1: float
Cload2: float
Ctog1: float
Ctog2: float
Lload1: float
Lload2: float
Z0: float = 50.0
analytical_Z0: float | None = None
cpw_params: CPWParams
d: float
freq: Frequency
opt_config: OptimizationConfig | None = None
simpleLOMs.sweeps.sweep(param: str, values: ndarray, base_config: SweepConfig, extract: list[str], model: str = 'cpw', refit: bool | None = None) DataFrame[source]

Sweep a single parameter across a range of values and extract quantities.

At each sweep point, the chosen model is either rebuilt from scratch (for CPW or when the swept parameter changes L/C) or reuses the L/C fitted at the first sweep point (for Cc, Ctog, and load parameters).

Parameters:
  • param (str) – Name of the SweepConfig field to vary. Must be an attribute of SweepConfig, e.g. “d”, “Cc1”, “Cc2”, “Ctog1”, “Lload1”, “Cload1”. Use “Lload1_Lload2” or “Cload1_Cload2” to sweep both loads together.

  • values (np.ndarray) – Array of values for the swept parameter.

  • base_config (SweepConfig) – Fixed device state. Not mutated.

  • extract (list of str) –

    Quantities to compute at each sweep point. Supported values:

    ”f0_s11”

    S11 resonance frequency (GHz)

    ”f0_s22”

    S22 resonance frequency (GHz)

    ”kappa_s11”

    S11 linewidth / FWHM (MHz)

    ”kappa_s22”

    S22 linewidth / FWHM (MHz)

    ”Q_s11”

    Quality factor from S11 = f0 / kappa

    ”Q_s22”

    Quality factor from S22

  • model (str) – Which model to use: “cpw” (default), “foster”, “optimized”, or “analytical”.

  • refit (bool or None) – Whether to re-fit the LC model at every sweep point. None (default) means automatic: refit when sweeping a parameter in {d, cpw_params}, reuse L/C otherwise. Setting refit=True forces refitting at every point (slower but safer when sweeping Cc1/Cc2 with OptimizedFit). Setting refit=False always reuses the first-point L/C (fastest).

Returns:

One row per sweep point. Columns are the swept parameter value plus all requested extract quantities.

Return type:

pd.DataFrame

Examples

Sweep resonator length with CPW ground truth:

df = sweep("d", np.linspace(5e-3, 10e-3, 20), base,
           extract=["f0_s11", "kappa_s11"])

Sweep coupling cap with FosterFit (reuses L/C — fast):

df = sweep("Cc1", np.linspace(1e-15, 20e-15, 30), base,
           extract=["f0_s11", "kappa_s11", "Q_s11"],
           model="foster")
simpleLOMs.sweeps.sweep_coupling(Cc_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw', symmetric: bool = True, refit: bool = False) DataFrame[source]

Sweep coupling capacitor(s).

Parameters:
  • Cc_values (np.ndarray) – Array of coupling capacitance values in Farads.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “kappa_s11”, “Q_s11”] if not provided.

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

  • symmetric (bool) – If True (default), sweeps Cc1 and Cc2 together. If False, sweeps only Cc1 and leaves Cc2 fixed.

  • refit (bool) – Whether to re-fit the LC model at every point. Default False because Cc does not change L or C — reusing is valid and fast. Set to True if you suspect OptimizedFit is sensitive to Cc during Stage 1 (unlikely but possible for very asymmetric coupling).

Returns:

Columns: “Cc” (the swept value), plus all extract quantities.

Return type:

pd.DataFrame

simpleLOMs.sweeps.sweep_length(d_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw') DataFrame[source]

Sweep resonator length d.

Always refits the model at every point because d directly sets L and C.

Parameters:
  • d_values (np.ndarray) – Array of resonator lengths in metres.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “kappa_s11”] if not provided.

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

Returns:

Columns: “d”, plus all extract quantities.

Return type:

pd.DataFrame

simpleLOMs.sweeps.sweep_load_frequency(f_load_values: ndarray, base_config: SweepConfig, extract: list[str] = None, model: str = 'cpw', side: str = 'both', load_impedance: float = 50.0, refit: bool = False) DataFrame[source]

Sweep the bare load resonance frequency.

Converts each target frequency to a (L, C) pair by fixing the load characteristic impedance Z_load = sqrt(L/C), then sweeping C = 1/(ω²L).

Parameters:
  • f_load_values (np.ndarray) – Array of target load resonance frequencies in Hz.

  • base_config (SweepConfig)

  • extract (list of str, optional) – Defaults to [“f0_s11”, “shift_mode1”, “shift_mode2”, “shift_mode3”].

  • model (str) – “cpw” (default), “foster”, “optimized”, or “analytical”.

  • side ({"both", "1", "2"}) – Which load to sweep. “both” sweeps load 1 and load 2 together (useful when the two loads are identical, e.g. symmetric qubits).

  • load_impedance (float) – Characteristic impedance of the load resonator in Ohms. Used to fix L from Z_load = sqrt(L/C) → L = Z_load / ω₀. Default 50 Ω.

  • refit (bool) – Whether to re-fit the LC model at every point. Default False.

Returns:

Columns: “f_load_GHz” (the swept load frequency in GHz), “Lload” (H), “Cload” (F), plus all extract quantities.

Return type:

pd.DataFrame

Utilities

utils.py

Ease of use functions for processing and viewing data.

simpleLOMs.utils.make_params_table(results: dict) DataFrame[source]

Summarize fitted L and C for all three models as a tidy DataFrame.

Parameters:

results (dict) – Output from analyze_system().

Returns:

Indexed by model name, columns L (H) and C (F).

Return type:

pd.DataFrame

simpleLOMs.utils.make_results_table(results: dict, round_decimals: int = 4) DataFrame[source]

Summarise analyze_system() output as a tidy DataFrame.

Rows are models (CPW, Optimized, Foster, Analytical). Columns are f₀, κ, and percent errors for S11 and S22.

Parameters:
  • results (dict) – Output from analyze_system().

  • round_decimals (int) – Decimal places to round to. Default 4.

Returns:

Indexed by model name.

Return type:

pd.DataFrame

simpleLOMs.utils.make_shift_error_table(results: dict, round_decimals: int = 3) DataFrame[source]

Signed percent shift errors vs CPW reference for all three models.

Parameters:
  • results (dict) – Output from analyze_system().

  • round_decimals (int)

Returns:

Rows are modes, columns are models.

Return type:

pd.DataFrame

simpleLOMs.utils.make_shift_table(results: dict, port: str = 'S11', round_decimals: int = 5) DataFrame[source]

Hybridised mode frequencies for all models as a tidy DataFrame.

Parameters:
  • results (dict) – Output from analyze_system().

  • port ({"S11", "S22"})

  • round_decimals (int)

Returns:

Rows are modes, columns are models.

Return type:

pd.DataFrame