Skip to content

Refactor waveguide models to use sax[rf]#344

Merged
nikosavola merged 8 commits intomainfrom
refactor-waveguides-to-sax
Mar 31, 2026
Merged

Refactor waveguide models to use sax[rf]#344
nikosavola merged 8 commits intomainfrom
refactor-waveguides-to-sax

Conversation

@nikosavola
Copy link
Copy Markdown
Member

@nikosavola nikosavola commented Mar 13, 2026

Refactors CPW and microstrip waveguide models to utilize sax[rf] instead of local JAX-jittable implementations.

  • Replaces local electromagnetic functions in qpdk/models/cpw.py (cpw_epsilon_eff, cpw_z0, cpw_thickness_correction, microstrip_epsilon_eff, microstrip_z0, microstrip_thickness_correction, propagation_constant, transmission_line_s_params) with re-exports from sax.models.rf. Layout-to-model helpers (get_cpw_dimensions, cpw_parameters, etc.) are retained.
  • Wraps sax.models.rf.coplanar_waveguide in straight(), extracting width/gap from the cross_section and substrate parameters from the PDK layer stack.
  • Wraps sax.models.rf.microstrip in straight_microstrip(), mapping qpdk parameter names to the upstream model.
  • Consolidates sax.models.rf imports into a single grouped import block in waveguides.py.
  • Updates dependencies in pyproject.toml to include sax[rf].

Drafted until flaport/sax#100 is in a release

Summary by Sourcery

Refactor CPW and microstrip waveguide models to delegate electromagnetic calculations to shared sax[rf] implementations while preserving qpdk-specific layout-to-model helpers.

Enhancements:

  • Replace local JAX electromagnetic CPW/microstrip functions with re-exports from sax.models.rf to centralize RF modeling logic.
  • Adapt straight CPW and microstrip waveguide S-parameter models to wrap sax.models.rf.coplanar_waveguide and sax.models.rf.microstrip using dimensions and substrate parameters from the qpdk layer stack.
  • Expose a curated all in qpdk.models.cpw for the RF functions and layout helper utilities.
  • Consolidate RF-related imports in waveguides to use the sax.models.rf wrappers.

Build:

  • Update project dependencies to require sax[rf]>=0.16.14 and add scikit-rf for RF modeling support.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Mar 13, 2026

Reviewer's Guide

Refactors the CPW and microstrip waveguide models to source all electromagnetic core calculations from sax.models.rf, updating the straight/straight_microstrip wrappers accordingly and adding sax[rf] (and scikit-rf) as dependencies.

Sequence diagram for straight and straight_microstrip using sax.models.rf

sequenceDiagram
    participant qpdk_waveguides as qpdk_models_waveguides
    participant qpdk_cpw as qpdk_models_cpw
    participant sax_rf as sax_models_rf

    rect rgb(235, 245, 255)
    qpdk_waveguides->>qpdk_cpw: get_cpw_dimensions(cross_section)
    qpdk_cpw-->>qpdk_waveguides: width, gap
    qpdk_waveguides->>qpdk_cpw: get_cpw_substrate_params()
    qpdk_cpw-->>qpdk_waveguides: h, t, ep_r
    qpdk_waveguides->>sax_rf: coplanar_waveguide(f, length, width, gap, thickness=t, substrate_thickness=h, ep_r=ep_r)
    sax_rf-->>qpdk_waveguides: SDict
    end

    rect rgb(245, 235, 255)
    qpdk_waveguides->>sax_rf: microstrip(f, length, width, substrate_thickness=h, thickness=t, ep_r=ep_r, tand=tand)
    sax_rf-->>qpdk_waveguides: SDict
    end
Loading

Class diagram for updated qpdk RF waveguide model structure

classDiagram
    class qpdk_models_cpw {
        +cpw_ep_r_from_cross_section()
        +cpw_epsilon_eff()
        +cpw_thickness_correction()
        +cpw_z0()
        +cpw_z0_from_cross_section()
        +get_cpw_dimensions(cross_section)
        +get_cpw_substrate_params()
        +microstrip_epsilon_eff()
        +microstrip_thickness_correction()
        +microstrip_z0()
        +propagation_constant()
        +transmission_line_s_params()
        +cpw_parameters(width, gap)
    }

    class qpdk_models_waveguides {
        +straight(f, length, cross_section)
        +straight_microstrip(f, length, width, h, t, ep_r, tand)
        +straight_shorted(f, length, cross_section)
    }

    class sax_models_rf {
        +cpw_epsilon_eff()
        +cpw_thickness_correction()
        +cpw_z0()
        +microstrip_epsilon_eff()
        +microstrip_thickness_correction()
        +microstrip_z0()
        +propagation_constant()
        +transmission_line_s_params()
        +coplanar_waveguide(f, length, width, gap, thickness, substrate_thickness, ep_r)
        +microstrip(f, length, width, substrate_thickness, thickness, ep_r, tand)
    }

    qpdk_models_cpw ..> sax_models_rf : reexports_functions
    qpdk_models_waveguides ..> qpdk_models_cpw : uses_helpers
    qpdk_models_waveguides ..> sax_models_rf : wraps_coplanar_waveguide_microstrip
Loading

File-Level Changes

Change Details Files
Replace in-house EM/JAX implementations for CPW/microstrip with re-exports and wrappers around sax.models.rf.
  • Remove local JAX implementations of CPW and microstrip analytical formulas (epsilon_eff, Z0, thickness corrections, propagation_constant, transmission_line_s_params) and import their equivalents from sax.models.rf.
  • Add an all list in the CPW module that now re-exports sax-based EM functions while retaining layout-to-model helpers (dimension/substrate extraction and cpw_parameters).
  • Update cpw_parameters docstring to reference sax.models.rf as the implementation source.
qpdk/models/cpw.py
Wrap sax.models.rf line models in waveguide S-parameter helpers.
  • Change straight() to delegate to sax.models.rf.coplanar_waveguide, extracting width/gap from the cross_section and substrate parameters from the PDK layer stack, instead of manually computing gamma and S-parameters with local functions.
  • Change straight_microstrip() to delegate to sax.models.rf.microstrip, mapping qpdk parameter names (length, width, substrate_thickness, thickness, ep_r, tand) to the upstream model instead of implementing the EM formulas locally.
  • Slightly adjust the docstrings of straight() and straight_microstrip() to describe the sax-based wrapping behavior and remove references to qpdk.models.cpw as the computational backend.
qpdk/models/waveguides.py
Update RF modeling dependencies to include sax[rf] and scikit-rf and consolidate imports.
  • Require sax[rf]>=0.16.14 instead of sax>=0.16.11 and add scikit-rf to the models extra in pyproject.toml.
  • Consolidate sax.models.rf-related imports into a grouped import block (e.g., for the coplanar/microstrip wrappers) in the waveguide modeling modules.
  • Regenerate uv.lock to capture the new dependency set.
pyproject.toml
uv.lock
qpdk/models/waveguides.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file tests Relating to testing models Related to simulation models labels Mar 13, 2026
Comment thread qpdk/models/media.py Outdated
from qpdk.helper import deprecated
from qpdk.tech import material_properties

DEPRECATION_MSG = "Prefer cpw_parameters or the functions in qpdk.models.cpw for JAX-jittable analysis."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deprecation message and several docstrings in this file still reference qpdk.models.cpw, which was deleted in this PR. Anyone following the deprecated API guidance will hit an ImportError.

The message and docs on lines 41, 104, and 144 should be updated to point to sax.models.rf instead:

Suggested change
DEPRECATION_MSG = "Prefer cpw_parameters or the functions in qpdk.models.cpw for JAX-jittable analysis."
DEPRECATION_MSG = "Prefer cpw_parameters or the functions in sax.models.rf for JAX-jittable analysis."

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In straight and straight_microstrip, the previous implementations explicitly converted length/geometry from µm to meters, whereas the new sax coplanar_waveguide/microstrip calls receive raw length, width, gap, thickness, and substrate_thickness values—please confirm and, if necessary, fix the unit conventions so they match the expectations of the sax RF models.
  • The DEPRECATION_MSG in qpdk/models/media.py still references qpdk.models.cpw, which has been removed; update this message to point to the new recommended API (e.g., sax RF models) so it remains accurate.
  • The commented-out adjustments to sax_stype_functions in tests/models/test_models_imported.py look like temporary debugging scaffolding; either remove them or replace them with a more permanent mechanism if they are needed for maintaining the models registry consistency.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `straight` and `straight_microstrip`, the previous implementations explicitly converted length/geometry from µm to meters, whereas the new sax `coplanar_waveguide`/`microstrip` calls receive raw `length`, `width`, `gap`, `thickness`, and `substrate_thickness` values—please confirm and, if necessary, fix the unit conventions so they match the expectations of the sax RF models.
- The `DEPRECATION_MSG` in `qpdk/models/media.py` still references `qpdk.models.cpw`, which has been removed; update this message to point to the new recommended API (e.g., sax RF models) so it remains accurate.
- The commented-out adjustments to `sax_stype_functions` in `tests/models/test_models_imported.py` look like temporary debugging scaffolding; either remove them or replace them with a more permanent mechanism if they are needed for maintaining the models registry consistency.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tests/models/test_models_imported.py Outdated
Comment on lines +150 to +154
# sax_stype_functions.add("straight")
# sax_stype_functions.add("straight_microstrip")
# sax_stype_functions.discard("coplanar_waveguide")
# sax_stype_functions.discard("microstrip")
# sax_stype_functions.discard("ellipk_ratio")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commented-out lines look like debugging artifacts left over from developing this test. They should be removed before merging.

Suggested change
# sax_stype_functions.add("straight")
# sax_stype_functions.add("straight_microstrip")
# sax_stype_functions.discard("coplanar_waveguide")
# sax_stype_functions.discard("microstrip")
# sax_stype_functions.discard("ellipk_ratio")

@nikosavola nikosavola self-assigned this Mar 13, 2026
@nikosavola nikosavola marked this pull request as draft March 13, 2026 10:11
@nikosavola nikosavola requested a review from Copilot March 13, 2026 14:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors QPDK’s CPW and microstrip waveguide modeling to rely on sax.models.rf implementations rather than maintaining local JAX-jittable CPW/microstrip formulations.

Changes:

  • Replace straight / straight_microstrip implementations with wrappers around sax.models.rf models.
  • Remove local CPW/microstrip analysis module (qpdk/models/cpw.py) and its dedicated tests.
  • Update optional dependency set to use sax[rf] (and lockfile accordingly).

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pyproject.toml Switches models extra dependency from sax to sax[rf].
uv.lock Updates locked requirement metadata to include the rf extra for sax.
qpdk/models/waveguides.py Re-implements CPW and microstrip straight models via sax.models.rf; updates cross-section helper import usage.
qpdk/models/media.py Replaces CPW analysis imports with sax.models.rf equivalents.
qpdk/models/__init__.py Re-exports RF analysis helpers from sax.models.rf instead of qpdk.models.cpw.
tests/models/test_models_imported.py Adds commented-out adjustment lines (currently inactive) around model discovery assertion.
qpdk/models/cpw.py Deleted (previous local CPW/microstrip analytic implementations).
tests/models/test_cpw.py Deleted (tests for removed local CPW analysis and straight CPW JIT checks).
tests/models/test_microstrip.py Deleted (tests for removed local microstrip analysis and straight_microstrip).
Comments suppressed due to low confidence (1)

qpdk/models/media.py:24

  • DEPRECATION_MSG (and nearby docstrings) still references qpdk.models.cpw as the preferred JAX-jittable analysis module, but this PR deletes qpdk/models/cpw.py and now imports these helpers from sax.models.rf. Please update the message/docs to point to the new canonical location (e.g., sax.models.rf or the re-exports in qpdk.models) to avoid broken guidance.
from qpdk.tech import material_properties

DEPRECATION_MSG = "Prefer cpw_parameters or the functions in qpdk.models.cpw for JAX-jittable analysis."


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread qpdk/models/waveguides.py
Comment on lines 50 to 68
def straight_microstrip(
f: sax.FloatArrayLike = DEFAULT_FREQUENCY,
length: sax.Float = 1000,
width: sax.Float = 10.0,
h: sax.Float = 500.0,
t: sax.Float = 0.2,
ep_r: sax.Float = 11.45,
tand: sax.Float = 0.0,
) -> sax.SDict:
r"""S-parameter model for a straight microstrip transmission line.

Computes S-parameters analytically using the Hammerstad-Jensen
:cite:`hammerstadAccurateModelsMicrostrip1980` closed-form expressions
for effective permittivity and characteristic impedance, as described
in Pozar :cite:`m.pozarMicrowaveEngineering2012` (ch. 3, §3.8).
Conductor thickness corrections follow
Gupta et al. :cite:`guptaMicrostripLinesSlotlines1996` (§2.2.4).

All computation is done with pure-JAX functions
(see :mod:`qpdk.models.cpw`) so the model composes with ``jax.jit``,
``jax.grad``, and ``jax.vmap``.

Args:
f: Array of frequency points in Hz.
length: Physical length in µm.
width: Strip width in µm.
h: Substrate height in µm.
t: Conductor thickness in µm (default 0.2 µm = 200 nm).
ep_r: Relative permittivity of the substrate (default 11.45 for Si).
tand: Dielectric loss tangent (default 0 — lossless).

Returns:
sax.SDict: S-parameters dictionary.
"""
f = jnp.asarray(f)
f_flat = f.ravel()

# Convert to SI (metres)
w_m = width * 1e-6
h_m = h * 1e-6
t_m = t * 1e-6
length_m = jnp.asarray(length) * 1e-6

# Effective permittivity (Hammerstad-Jensen)
ep_eff = microstrip_epsilon_eff(w_m, h_m, ep_r)

# Apply conductor thickness correction if t > 0
_w_eff, ep_eff_t, z0_val = microstrip_thickness_correction(
w_m, h_m, t_m, ep_r, ep_eff
"""S-parameter model for a straight microstrip line."""
return _microstrip(
f=f,
length=length,
width=width,
substrate_thickness=h,
thickness=t,
ep_r=ep_r,
tand=tand,
)
Comment thread qpdk/models/waveguides.py Outdated
Comment on lines +12 to +17
)
from sax.models.rf import (
electrical_open,
electrical_short,
)
from sax.models.rf import (
Comment thread tests/models/test_models_imported.py Outdated
nikosavola and others added 3 commits March 18, 2026 19:26
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Resolve conflicts in pyproject.toml and uv.lock
- Restore and update CPW and microstrip models in qpdk/models/cpw.py
- Align waveguide models with main's analytical implementations
- Update imports in qpdk/models/__init__.py to fix ImportError
@github-actions github-actions Bot removed tests Relating to testing models Related to simulation models labels Mar 27, 2026
@nikosavola
Copy link
Copy Markdown
Member Author

@copilot could you refactor the coplanar waveguide, microstrip and related elementary Sax models to use the versions from sax.models.rf (in latest Sax version). For example, you should likely wrap the models like straight to the coplanar_waveguide model from Sax. Note that you should keep the qpdk parametrization of using cross_section, the waveguide width etc. need to be inferred from that.

- Replace local CPW/microstrip implementations in cpw.py with re-exports
  from sax.models.rf
- Wrap sax.models.rf.coplanar_waveguide in straight(), extracting
  width/gap from cross_section and substrate params from PDK layer stack
- Wrap sax.models.rf.microstrip in straight_microstrip()
- Consolidate sax.models.rf imports into single block in waveguides.py

Agent-Logs-Url: https://github.com/gdsfactory/quantum-rf-pdk/sessions/ab5b541c-1ae0-451b-8a90-ef62bdd60941

Co-authored-by: nikosavola <7860886+nikosavola@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

@copilot could you refactor the coplanar waveguide, microstrip and related elementary Sax models to use the versions from sax.models.rf (in latest Sax version). For example, you should...

Done in dab1078. Refactored straight to wrap sax.models.rf.coplanar_waveguide — it extracts width/gap from the cross_section and substrate_thickness/thickness/ep_r from the PDK layer stack, then delegates to the sax model. Similarly, straight_microstrip now wraps sax.models.rf.microstrip. The local electromagnetic functions in cpw.py (like cpw_epsilon_eff, propagation_constant, etc.) are replaced with re-exports from sax.models.rf, while the layout-to-model helpers (get_cpw_dimensions, cpw_parameters, etc.) remain in qpdk. All 787 tests pass.

@nikosavola nikosavola marked this pull request as ready for review March 31, 2026 17:05
@nikosavola nikosavola enabled auto-merge March 31, 2026 17:05
@github-actions github-actions Bot added the models Related to simulation models label Mar 31, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In both straight and straight_microstrip, the old implementations explicitly converted geometry and length from µm to metres before calling the EM routines, whereas the new wrappers pass the raw values through to sax.models.rf; please double‑check and, if needed, normalise units so the upstream models still see SI units.
  • The previous straight/straight_microstrip implementations built a partial S‑matrix and then enforced reciprocity via sax.reciprocal, while the new versions return the S‑dict from sax.models.rf directly; confirm that the upstream models already produce symmetric/reciprocal 2‑port S‑parameters with the expected port naming to avoid behavioral changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In both `straight` and `straight_microstrip`, the old implementations explicitly converted geometry and length from µm to metres before calling the EM routines, whereas the new wrappers pass the raw values through to `sax.models.rf`; please double‑check and, if needed, normalise units so the upstream models still see SI units.
- The previous `straight`/`straight_microstrip` implementations built a partial S‑matrix and then enforced reciprocity via `sax.reciprocal`, while the new versions return the S‑dict from `sax.models.rf` directly; confirm that the upstream models already produce symmetric/reciprocal 2‑port S‑parameters with the expected port naming to avoid behavioral changes.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@nikosavola nikosavola added this pull request to the merge queue Mar 31, 2026
Merged via the queue into main with commit 393cb4b Mar 31, 2026
23 of 24 checks passed
@nikosavola nikosavola deleted the refactor-waveguides-to-sax branch March 31, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file models Related to simulation models

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants