diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
index 2681484..03a6e4c 100644
--- a/.github/release-drafter.yml
+++ b/.github/release-drafter.yml
@@ -1,6 +1,6 @@
name-template: '$RESOLVED_VERSION'
tag-template: '$RESOLVED_VERSION'
-change-template: '- $TITLE [#$NUMBER](https://github.com/flaport/sax/pull/$NUMBER)'
+change-template: '- $TITLE [#$NUMBER](https://github.com/gdsfactory/sax/pull/$NUMBER)'
template: |
# What's Changed
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index b8431c0..f6f5c4a 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -43,14 +43,6 @@ jobs:
uses: astral-sh/setup-uv@v5
- name: Install Just
uses: taiki-e/install-action@just
- - name: Install Rust
- uses: actions-rs/toolchain@v1
- with:
- toolchain: stable
- override: true
- components: rustfmt, clippy, cargo
- - name: Install svgbob
- run: cargo install svgbob_cli
- name: Build docs
run: just dev nbdocs docs
- name: Upload artifact [site]
diff --git a/README.md b/README.md
index a256532..28b4799 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ dive in...
## Quick Start
-[Full Quick Start page](https://flaport.github.io/sax/nbs/examples/01_quick_start) - [Documentation](https://flaport.github.io/sax).
+[Full Quick Start page](https://gdsfactory.github.io/sax/nbs/examples/01_quick_start) - [Documentation](https://gdsfactory.github.io/sax).
Let's first import the SAX library, along with JAX and the JAX-version of numpy:
@@ -119,7 +119,7 @@ plt.show()

Those are the basics. For more info, check out the **full**
-[SAX Quick Start page](https://flaport.github.io/sax/nbs/examples/01_quick_start) or the rest of the [Documentation](https://flaport.github.io/sax).
+[SAX Quick Start page](https://gdsfactory.github.io/sax/nbs/examples/01_quick_start) or the rest of the [Documentation](https://gdsfactory.github.io/sax).
## Installation
@@ -138,4 +138,4 @@ pip install 'sax[dev]'
## License
-Copyright © 2025, Floris Laporte, [Apache-2.0 License](https://github.com/flaport/sax/blob/master/LICENSE)
+Copyright © 2025, Floris Laporte, [Apache-2.0 License](https://github.com/gdsfactory/sax/blob/main/LICENSE)
diff --git a/docs/hooks.py b/docs/hooks.py
deleted file mode 100644
index 98569d9..0000000
--- a/docs/hooks.py
+++ /dev/null
@@ -1,281 +0,0 @@
-"""MkDocs hooks for SAX-specific preprocessing."""
-
-import hashlib
-import re
-import shutil
-import subprocess
-import tempfile
-from pathlib import Path
-from textwrap import dedent
-from typing import Any
-
-import matplotlib.pyplot as plt
-
-import sax
-
-plt.rcParams.update(
- {
- "figure.figsize": (6, 2.5),
- "axes.grid": True,
- "lines.color": "grey",
- "patch.edgecolor": "grey",
- "text.color": "grey",
- "axes.facecolor": "ffffff00",
- "axes.edgecolor": "grey",
- "axes.labelcolor": "grey",
- "xtick.color": "grey",
- "ytick.color": "grey",
- "grid.color": "grey",
- "figure.facecolor": "ffffff00",
- "figure.edgecolor": "ffffff00",
- "savefig.facecolor": "ffffff00",
- "savefig.edgecolor": "ffffff00",
- }
-)
-
-
-def on_startup(command: str, dirty: bool, **kwargs: Any) -> None:
- """Called once when the MkDocs build starts."""
-
-
-def on_shutdown(**kwargs: Any) -> None:
- """Called once when the MkDocs build ends."""
-
-
-def on_serve(server: Any, config: Any, builder: Any, **kwargs: Any) -> None:
- """Called when the MkDocs development server starts."""
-
-
-def on_config(config: Any, **kwargs: Any) -> Any:
- """Called after config file is loaded but before validation."""
- return config
-
-
-def on_pre_build(config: Any, **kwargs: Any) -> None:
- """Called before the build starts."""
-
-
-def on_files(files: Any, config: Any, **kwargs: Any) -> Any:
- """Called after files are gathered but before processing."""
- return files
-
-
-def on_nav(nav: Any, config: Any, files: Any, **kwargs: Any) -> Any:
- """Called after navigation is built."""
- return nav
-
-
-def on_env(env: Any, config: Any, files: Any, **kwargs: Any) -> Any:
- """Called after Jinja2 environment is created."""
- return env
-
-
-def on_post_build(config: Any, **kwargs: Any) -> None:
- """Called after the build is complete."""
-
-
-def on_pre_template(
- template: Any, template_name: str, config: Any, **kwargs: Any
-) -> Any:
- """Called before a template is rendered."""
- return template
-
-
-def on_template_context(
- context: Any, template_name: str, config: Any, **kwargs: Any
-) -> Any:
- """Called after template context is created."""
- return context
-
-
-def on_post_template(
- output: str, template_name: str, config: Any, **kwargs: Any
-) -> str:
- """Called after template is rendered."""
- return output
-
-
-def on_pre_page(page: Any, config: Any, files: Any, **kwargs: Any) -> Any:
- """Called before a page is processed."""
- return page
-
-
-def on_page_read_source(page: Any, config: Any, **kwargs: Any) -> str | None:
- """Called to read the raw source of a page."""
- return None
-
-
-def on_page_markdown(
- markdown: str, page: Any, config: Any, files: Any, **kwargs: Any
-) -> str:
- """Process markdown content before it's converted to HTML."""
- blocks = markdown.split("```")
-
- for i, block in enumerate(blocks):
- if i % 2:
- # This is a code block
- if (special := _parse_special(block)) is not None:
- blocks[i] = special
- else:
- blocks[i] = f"```{block}```"
- continue
-
- # This is regular markdown content
- lines = block.split("\n")
- _insert_cross_refs(lines)
- blocks[i] = "\n".join(lines)
-
- content = "".join(blocks)
- return content
-
-
-def on_page_content( # noqa: C901
- html: str, page: Any, config: Any, files: Any, **kwargs: Any
-) -> str:
- """Called after markdown is converted to HTML."""
- if "```{svgbob}" not in html:
- return html
-
- source_parts = []
- for part in html.split("```"):
- if not part.startswith("{svgbob}"):
- continue
- lines = part.split("\n")[1:]
- for i, line in enumerate(lines):
- lines[i] = "".join(re.split(r"[<>]", line)[::2])
- part = dedent("\n".join(lines))
- source_parts.append(lines)
-
- rendered_parts = []
- for i, part in enumerate(html.split('
')):
- if i > 0:
- part = f'
{part}'
- first, *rest = part.split("
")
- rest = "
".join(rest)
- first = f"{first}"
- rendered_parts.append(first)
- rendered_parts.append(rest)
-
- for i, part in enumerate(rendered_parts):
- if not part.startswith(''):
- continue
- lines = part.split("\n")
- if (svgbob_source := _svgbob_source(lines, source_parts)) is None:
- continue
- if (svg := _svgbob_svg(svgbob_source)) is None:
- continue
- rendered_parts[i] = svg
-
- return "".join(rendered_parts)
-
-
-def on_page_context(
- context: Any, page: Any, config: Any, nav: Any, **kwargs: Any
-) -> Any:
- """Called after page context is created."""
- return context
-
-
-def on_post_page(output: str, page: Any, config: Any, **kwargs: Any) -> str:
- """Called after page is fully processed."""
- return output
-
-
-def _parse_special(content: str) -> str | None:
- """Format contents of a special code block differently."""
- lines = content.strip().split("\n")
- first = lines[0].strip()
- rest = lines[1:]
- if not (first.startswith("{") and first.endswith("}")):
- return None
- code_block_type = first[1:-1].strip()
- if code_block_type == "svgbob":
- source = "\n".join(rest)
- content_hash = hashlib.md5(source.encode()).hexdigest()
- svg_content = _svgbob_svg(source)
- if not svg_content:
- return None
- docs_dir = Path(__file__).parent
- svg_path = docs_dir / "assets" / "svgbob" / f"svgbob_{content_hash}.svg"
- svg_path.parent.mkdir(exist_ok=True, parents=True)
- svg_path.write_text(svg_content or "")
- return f"\n\n})\n\n"
- return _format_admonition(code_block_type, rest)
-
-
-def _format_admonition(admonition_type: str, lines: list[str]) -> str:
- """Format lines as an admonition."""
- if admonition_type == "hint":
- admonition_type = "info"
- ret = f"!!! {admonition_type}\n\n"
- for line in lines:
- ret += f" {line.strip()}\n"
- return ret
-
-
-def _svgbob_svg(source: str) -> str | None:
- source = source.replace("<", "<").replace(">", ">")
- svgbob = shutil.which("svgbob_cli")
- if not svgbob:
- print("Warning: svgbob_cli is not installed or not found in PATH.") # noqa: T201
- return None
- content_hash = hashlib.md5(source.encode()).hexdigest()
- txt_filename = f"svgbob_{content_hash}.txt"
- temp_path = Path(tempfile.gettempdir()).resolve() / "svgbob" / txt_filename
- temp_path.parent.mkdir(exist_ok=True)
- try:
- temp_path.write_text(source)
- return subprocess.check_output( # noqa: S603
- [
- svgbob,
- "--background",
- "#00000000",
- "--stroke-color",
- "grey",
- "--fill-color",
- "grey",
- str(temp_path),
- ]
- ).decode()
- except Exception as e: # noqa: BLE001
- print(f"Warning: Error generating SVG with svgbob: {e}") # noqa: T201
- return None
- finally:
- temp_path.unlink()
-
-
-def _svgbob_source(
- rendered_lines: list[str], source_parts: list[list[str]]
-) -> str | None:
- for source_lines in source_parts:
- if all(
- sl.strip() in rl
- for sl, rl in zip(source_lines, rendered_lines, strict=False)
- ):
- return "\n".join(source_lines)
- return None
-
-
-def _insert_cross_refs(lines: list[str]) -> None: # noqa: C901
- """Insert cross-references in the markdown lines."""
- cross_refs = {}
- for line in lines:
- parts = line.split("`")
- for k, part in enumerate(parts):
- if k % 2 == 0:
- continue
- *first, short_part = part.split(".")
- if first and first[0] != "sax":
- continue
- if hasattr(sax, short_part):
- cross_refs[f"`{part}`"] = f"[`{part}`][sax.{short_part}]"
- elif hasattr(sax.fit, short_part):
- cross_refs[f"`{part}`"] = f"[`{part}`][sax.fit.{short_part}]"
- elif hasattr(sax.models, part):
- cross_refs[f"`{part}`"] = f"[`{part}`][sax.models.{short_part}]"
- elif hasattr(sax.parsers, part):
- cross_refs[f"`{part}`"] = f"[`{part}`][sax.parsers.{short_part}]"
- for j, line in enumerate(lines):
- for k, v in cross_refs.items():
- line = line.replace(k, v)
- lines[j] = line
diff --git a/docs/models_rf.md b/docs/models_rf.md
index 813bc58..c94b52e 100644
--- a/docs/models_rf.md
+++ b/docs/models_rf.md
@@ -1,6 +1,6 @@
# Radio frequency (RF) Models
-For more information on these RF models, see Ref. [@pozar-2012].
+For more information on these RF models, see Pozar (2012).
## Coplanar Waveguides (CPW) and Microstrips
@@ -8,16 +8,16 @@ Sax includes JAX-jittable functions for computing the characteristic impedance,
### CPW Theory
-The quasi-static CPW analysis follows the conformal-mapping approach described by Simons [@simonsCoplanarWaveguideCircuits2001] (ch. 2) and Ghione & Naldi [@ghioneAnalyticalFormulasCoplanar1984]. Conductor thickness corrections use the first-order formulae of Gupta, Garg, Bahl & Bhartia [@guptaMicrostripLinesSlotlines1996] (§7.3, Eqs. 7.98-7.100).
+The quasi-static CPW analysis follows the conformal-mapping approach described by Simons (ch. 2) and Ghione & Naldi. Conductor thickness corrections use the first-order formulae of Gupta, Garg, Bahl & Bhartia (§7.3, Eqs. 7.98-7.100).
### Microstrip Theory
-The microstrip analysis uses the Hammerstad-Jensen [@hammerstadAccurateModelsMicrostrip1980] closed-form expressions for effective permittivity and characteristic impedance, as presented in Pozar [@pozar-2012] (ch. 3, §3.8).
+The microstrip analysis uses the Hammerstad-Jensen closed-form expressions for effective permittivity and characteristic impedance, as presented in Pozar (ch. 3, §3.8).
### General
-The ABCD-to-S-parameter conversion is the standard microwave-network relation from Pozar [@pozar-2012] (ch. 4).
+The ABCD-to-S-parameter conversion is the standard microwave-network relation from Pozar (ch. 4).
-The implementation was cross-checked against the Qucs-S model (see Qucs technical documentation [@qucs_technical_papers], §12 for CPW, §11 for microstrip) and the `scikit-rf` CPW class.
+The implementation was cross-checked against the Qucs-S model (see Qucs technical documentation, §12 for CPW, §11 for microstrip) and the `scikit-rf` CPW class.
::: sax.models.rf
diff --git a/docs/references.bib b/docs/references.bib
deleted file mode 100644
index c160b28..0000000
--- a/docs/references.bib
+++ /dev/null
@@ -1,89 +0,0 @@
-@article{ghioneAnalyticalFormulasCoplanar1984,
- title = {Analytical Formulas for Coplanar Lines in Hybrid and Monolithic {{MICs}}},
- author = {Ghione, G. and Naldi, C.},
- year = {1984},
- month = feb,
- journal = {Electronics Letters},
- volume = {20},
- number = {4},
- pages = {179--181},
- publisher = {The Institution of Engineering and Technology},
- doi = {10.1049/el:19840120},
- abstract = {Some analytical formulas for the parameters of coplanar lines are discussed and validated; a chart is given for the design of coplanar waveguides on GaAs. The formulas discussed here, together with those presented previously by us (1983) represent a suitable set for the design of coplanar lines for hybrid and monolithic MICs (microwave integrated circuits).}
-}
-@book{guptaMicrostripLinesSlotlines1996,
- title = {Microstrip Lines and Slotlines},
- author = {Gupta, Kuldip C. and Garg, R. and Bahl, I. and Bhartia, P.},
- year = {1996},
- edition = {2. ed},
- publisher = {Artech House},
- address = {Boston},
- isbn = {978-0-89006-766-6},
- langid = {english}
-}
-@inproceedings{hammerstadAccurateModelsMicrostrip1980,
- title = {Accurate {{Models}} for {{Microstrip Computer-Aided Design}}},
- booktitle = {1980 {{IEEE MTT-S International Microwave}} Symposium {{Digest}}},
- author = {Hammerstad, E. and Jensen, O.},
- year = {1980},
- pages = {407--409},
- publisher = {IEEE},
- address = {Washington, DC, USA},
- doi = {10.1109/MWSYM.1980.1124303}
-}
-@misc{numpy-docs,
- title = {Numpy Documentation},
- author = {Travis Oliphant},
- booktitle = {Numpy},
- year = {2006},
- url = {https://numpy.org/doc/stable/index.html}
-}
-@book{pozar-2012,
- title = {Microwave {{Engineering}}},
- author = {M. Pozar, David},
- year = {2012},
- edition = {4},
- publisher = {John Wiley \& Sons, Inc.},
- isbn = {978-0-470-63155-3}
-}
-@book{python,
- title = {Python reference manual},
- author = {Van Rossum, Guido and Drake Jr, Fred L},
- year = {1995},
- publisher = {Centrum voor Wiskunde en Informatica Amsterdam}
-}
-@misc{python-loops,
- title = {Loop like a native},
- author = {Ned Batchelder},
- booktitle = {PyCon},
- year = {2013},
- url = {https://www.youtube.com/watch?v=EnSu9hHGq5o&t=1519s}
-}
-@misc{pythonformaths,
- title = {Python for Maths},
- author = {Andreas Ernst},
- booktitle = {github},
- year = {2021},
- url = {https://github.erc.monash.edu.au/andrease/Python4Maths}
-}
-@manual{qucs_technical_papers,
- title = {Qucs Technical Papers},
- author = {Stefan Jahn and Michael Margraf and Vincent Habchi and Raimund Jacob},
- organization = {Qucs (Quite Universal Circuit Simulator) Project},
- year = {2007},
- month = dec,
- url = {https://qucs.sourceforge.net/docs/technical/technical.pdf},
- urldate = {2026-03-13}
-}
-@book{simonsCoplanarWaveguideCircuits2001,
- title = {Coplanar Waveguide Circuits, Components, and Systems},
- author = {Simons, Rainee},
- year = {2001},
- series = {Wiley {{Series}} in {{Microwave}} and {{Optical Engineering}}},
- number = {v. 165},
- publisher = {Wiley Interscience},
- address = {New York},
- doi = {10.1002/0471224758},
- isbn = {978-0-471-22475-4 978-0-471-46393-1},
- langid = {english}
-}
diff --git a/justfile b/justfile
index 88db06b..220eed7 100644
--- a/justfile
+++ b/justfile
@@ -26,10 +26,10 @@ cov: ipykernel
docs:
sed 's|](docs/|](|g' README.md > docs/index.md
sed 's|^#|###|g' CHANGELOG.md | sed 's|^### \[0|## [0|g' > docs/changelog.md
- uv run mkdocs build
+ uv run zensical build
serve:
- uv run mkdocs serve -a localhost:8080
+ uv run zensical serve
nbrun: ipykernel
find nbs -maxdepth 2 -mindepth 1 -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" -not -path "./.venv/*" | xargs parallel -j `nproc --all` uv run papermill {} {} -k sax :::
@@ -42,13 +42,7 @@ _nbdocs:
find nbs/internals -maxdepth 1 -mindepth 1 -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" -not -path "./.venv/*" | xargs parallel -j `nproc --all` uv run jupyter nbconvert --to markdown --embed-images {} --output-dir docs/nbs/internals ':::'
find nbs/examples -maxdepth 1 -mindepth 1 -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" -not -path "./.venv/*" | xargs parallel -j `nproc --all` uv run jupyter nbconvert --to markdown --embed-images {} --output-dir docs/nbs/examples ':::'
-[macos]
nbdocs: _nbdocs
- find docs/nbs -name "*.md" | xargs sed -i '' 's|```svgbob|```{svgbob}|g'
-
-[linux]
-nbdocs: _nbdocs
- find docs/nbs -name "*.md" | xargs sed -i 's|```svgbob|```{svgbob}|g'
nbclean-all:
find . -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" -not -path "./.venv/*" | xargs just nbclean
diff --git a/mkdocs.yml b/mkdocs.yml
deleted file mode 100644
index 642c450..0000000
--- a/mkdocs.yml
+++ /dev/null
@@ -1,145 +0,0 @@
-site_name: sax
-repo_url: https://github.com/flaport/sax
-site_url: https://flaport.github.io/sax
-site_description: Autograd and XLA for S-parameters
-site_author: Floris Laporte
-repo_name: flaport/sax
-copyright: Copyright © 2025, Floris Laporte, Apache-2.0
-
-theme:
- name: material
- logo: assets/logo.svg
- favicon: assets/favicon.ico
- font:
- text: Roboto
- code: Roboto Mono
- palette:
- - media: "(prefers-color-scheme)"
- toggle:
- icon: material/brightness-auto
- name: Switch to light mode
- - media: "(prefers-color-scheme: light)"
- scheme: default
- toggle:
- icon: material/weather-sunny
- name: Switch to dark mode
- primary: blue
- accent: deep purple
- - media: "(prefers-color-scheme: dark)"
- scheme: slate
- toggle:
- icon: material/weather-night
- name: Switch to system default
- primary: blue
- accent: deep purple
- features:
- - content.code.copy
- - navigation.footer
- search: true
-
-nav:
- - home: index.md
- - examples:
- - quick start: nbs/examples/01_quick_start.md
- - all pass: nbs/examples/02_all_pass_filter.md
- - circuit from yaml: nbs/examples/03_circuit_from_yaml.md
- - multimode: nbs/examples/04_multimode_simulations.md
- - thin film: nbs/examples/05_thinfilm.md
- - additive: nbs/examples/06_additive_backend.md
- - layout aware: nbs/examples/07_layout_aware.md
- - sparse (coo): nbs/examples/08_sparse_coo.md
- - forward only: nbs/examples/09_forward_only_backend.md
- - neff dispersion: nbs/examples/10_wavelength_dependent_neff.md
- - hierarchical circuits: nbs/examples/11_hierarchical_circuits.md
- - data parsers: nbs/examples/12_data_parsers.md
- - surface models: nbs/examples/13_surface_models.md
- - probes: nbs/examples/14_probes.md
- - multi link: nbs/examples/15_multi_link.md
- - internals:
- - backends: nbs/internals/03_backends.md
- - circuit: nbs/internals/02_circuit.md
- - models: nbs/internals/01_models.md
- - all models: nbs/internals/04_all_models.md
- - api reference:
- - sax: api.md
- - sax.fit: fit.md
- - sax.models: models.md
- - sax.models.rf: models_rf.md
- - changelog: changelog.md
-
-extra_css:
- - assets/custom.css
-
-extra_javascript:
- - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
-
-plugins:
- - search
- - autorefs
- - mkdocs_matplotlib
- - bibtex:
- bib_file: "docs/references.bib"
- - mkdocstrings:
- handlers:
- python:
- paths: [src]
- inventories:
- - https://docs.jax.dev/en/latest/objects.inv
- - https://docs.kidger.site/jaxtyping/objects.inv
- - https://docs.python.org/3/objects.inv
- - https://docs.xarray.dev/en/stable/objects.inv
- - https://matplotlib.org/stable/objects.inv
- - https://numpy.org/doc/stable/objects.inv
- - https://pandas.pydata.org/docs/objects.inv
- - https://python-markdown.github.io/objects.inv
- - https://scipy.github.io/devdocs/objects.inv
- - https://typing.readthedocs.io/en/latest/objects.inv
- - https://www.mkdocs.org/objects.inv
- options:
- docstring_options:
- ignore_init_summary: true
- docstring_section_style: table
- docstring_style: google
- filters: ["!^_"]
- heading_level: 1
- inherited_members: true
- line_length: 88
- merge_init_into_class: true
- separate_signature: true
- show_root_full_path: false
- show_root_heading: true
- show_signature_annotations: true
- show_source: true
- show_symbol_type_heading: true
- show_symbol_type_toc: true
- signature_crossrefs: true
- summary: true
-
-markdown_extensions:
- - attr_list
- - footnotes
- - toc:
- permalink: true
- - pymdownx.emoji
- - pymdownx.highlight:
- anchor_linenums: true
- line_spans: __span
- pygments_lang_class: true
- - pymdownx.inlinehilite
- - pymdownx.snippets
- - pymdownx.magiclink
- - pymdownx.tabbed:
- alternate_style: true
- - admonition
- - pymdownx.details
- - pymdownx.arithmatex:
- generic: true
- - pymdownx.superfences
-
-hooks:
- - docs/hooks.py
-
-extra:
- social:
- - icon: fontawesome/brands/github
- link: https://github.com/flaport
diff --git a/pyproject.toml b/pyproject.toml
index 82bb3ea..5642cb5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -19,17 +19,12 @@ docs = [
"altair>=6.0.0,<7.0.0",
"griffe>=2.0.0,<3.0.0",
"ipykernel>=7.2.0,<8.0.0",
- "mkautodoc>=0.2.0,<0.3.0",
- "mkdocs-autorefs>=1.4.4,<1.5.0",
- "mkdocs-bibtex>=4.4.0,<5.0.0",
- "mkdocs-material>=9.7.6,<10.0.0",
- "mkdocs-matplotlib>=0.10.1,<0.11.0",
- "mkdocs>=1.6.1,<2.0.0",
- "mkdocstrings[python]>=1.0.4,<2.0.0",
+ "mkdocstrings-python>=2.0.0,<3.0.0",
"nbconvert>=7.16.6,<8.0.0",
"plotly>=6.0.0,<7.0.0",
"pydot>=4.0.1,<5.0.0",
- "vega-datasets>=0.9.0,<0.10.0"
+ "vega-datasets>=0.9.0,<0.10.0",
+ "zensical>=0.0.43,<0.1.0"
]
lint = [
"nb-clean>=4.0.1,<5.0.0",
@@ -179,12 +174,6 @@ select = ["ALL"]
"SLF001", # private-member-access
"T201" # print
]
-"docs/hooks.py" = [
- "INP001", # implicit-namespace-package
- "ARG001", # unused-function-argument
- "ANN401", # any-type
- "FBT001" # boolean-type-hint-positional-argument
-]
"src/sax/parsers/*.py" = [
"E501", # line-too-long
"N802" # invalid-function-name
diff --git a/src/sax/models/bends.py b/src/sax/models/bends.py
index ef1ef61..de31621 100644
--- a/src/sax/models/bends.py
+++ b/src/sax/models/bends.py
@@ -55,7 +55,6 @@ def bend(
Basic bend simulation:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/couplers.py b/src/sax/models/couplers.py
index fc3f6c8..56a8432 100644
--- a/src/sax/models/couplers.py
+++ b/src/sax/models/couplers.py
@@ -43,7 +43,6 @@ def coupler_ideal(
Ideal coupler:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -137,7 +136,6 @@ def coupler(
Basic dispersive coupler:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -239,7 +237,6 @@ def grating_coupler(
Basic grating coupler:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/crossings.py b/src/sax/models/crossings.py
index 7bf73a2..af12a74 100644
--- a/src/sax/models/crossings.py
+++ b/src/sax/models/crossings.py
@@ -36,7 +36,6 @@ def crossing_ideal(wl: sax.FloatArrayLike = sax.WL_C) -> sax.SDict:
Ideal crossing:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import jax.numpy as jnp
diff --git a/src/sax/models/isolators.py b/src/sax/models/isolators.py
index de19296..6db7aa5 100644
--- a/src/sax/models/isolators.py
+++ b/src/sax/models/isolators.py
@@ -40,7 +40,6 @@ def isolator(
Isolator with 1 dB insertion loss and 30 dB isolation:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -109,7 +108,6 @@ def circulator(
3-port circulator:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/mmis.py b/src/sax/models/mmis.py
index 2416a6e..7c2e513 100644
--- a/src/sax/models/mmis.py
+++ b/src/sax/models/mmis.py
@@ -33,7 +33,6 @@ def mmi1x2_ideal(wl: sax.FloatArrayLike = sax.WL_C) -> sax.SDict:
Ideal 1x2 MMI:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -78,7 +77,6 @@ def mmi2x2_ideal(*, wl: sax.FloatArrayLike = sax.WL_C) -> sax.SDict:
Ideal 2x2 MMI:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -131,7 +129,6 @@ def mmi1x2(
Basic 1x2 MMI:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -206,7 +203,6 @@ def mmi2x2(
Basic 2x2 MMI:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/reflectors.py b/src/sax/models/reflectors.py
index 7ddae07..2bb7a2d 100644
--- a/src/sax/models/reflectors.py
+++ b/src/sax/models/reflectors.py
@@ -43,7 +43,6 @@ def reflector(
50% reflector:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -106,7 +105,6 @@ def mirror(
Perfect mirror:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/rf.py b/src/sax/models/rf.py
index 64664ac..76d57f2 100644
--- a/src/sax/models/rf.py
+++ b/src/sax/models/rf.py
@@ -44,7 +44,6 @@ def gamma_0_load(
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -101,7 +100,6 @@ def tee(*, f: sax.FloatArrayLike = DEFAULT_FREQUENCY) -> sax.SDict:
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -155,7 +153,6 @@ def impedance(
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -203,7 +200,6 @@ def admittance(
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -251,11 +247,10 @@ def resistor(
S-dictionary representing the resistor element
References:
- [@pozar2012]
+ Pozar
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -298,7 +293,6 @@ def capacitor(
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -346,7 +340,6 @@ def inductor(
Examples:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/splitters.py b/src/sax/models/splitters.py
index 23325d1..ab93e99 100644
--- a/src/sax/models/splitters.py
+++ b/src/sax/models/splitters.py
@@ -41,7 +41,6 @@ def splitter_ideal(
Ideal 1x2 splitter:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/straight.py b/src/sax/models/straight.py
index 54e79a8..2fc42ae 100644
--- a/src/sax/models/straight.py
+++ b/src/sax/models/straight.py
@@ -42,7 +42,6 @@ def straight(
Lossless waveguide:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -98,7 +97,6 @@ def attenuator(
Attenuator:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
@@ -157,7 +155,6 @@ def phase_shifter(
Phase shifter:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/models/terminators.py b/src/sax/models/terminators.py
index 8273f0c..eeb9442 100644
--- a/src/sax/models/terminators.py
+++ b/src/sax/models/terminators.py
@@ -38,7 +38,6 @@ def terminator(
Ideal terminator:
```python
- # mkdocs: render
import matplotlib.pyplot as plt
import numpy as np
import sax
diff --git a/src/sax/parsers/lumerical.py b/src/sax/parsers/lumerical.py
index 1c938a6..ae9b13f 100644
--- a/src/sax/parsers/lumerical.py
+++ b/src/sax/parsers/lumerical.py
@@ -45,7 +45,7 @@ def parse_lumerical_dat(
msg = (
"The `parse_lumerical_dat` function is experimental. "
"If you encounter any issues, "
- "Please file a bug report here: https://github.com/flaport/sax/issues ."
+ "Please file a bug report here: https://github.com/gdsfactory/sax/issues ."
)
warnings.warn(msg, stacklevel=2, category=sax.ExperimentalWarning)
content = sax.read(content_or_filename)
diff --git a/zensical.toml b/zensical.toml
new file mode 100644
index 0000000..60ef3cb
--- /dev/null
+++ b/zensical.toml
@@ -0,0 +1,161 @@
+[project]
+copyright = "Copyright © 2025, Floris Laporte, Apache-2.0"
+dev_addr = "localhost:8080"
+docs_dir = "docs"
+extra_css = ["assets/custom.css"]
+extra_javascript = ["https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"]
+nav = [
+ {"home" = "index.md"},
+ {"examples" = [
+ {"quick start" = "nbs/examples/01_quick_start.md"},
+ {"all pass" = "nbs/examples/02_all_pass_filter.md"},
+ {"circuit from yaml" = "nbs/examples/03_circuit_from_yaml.md"},
+ {"multimode" = "nbs/examples/04_multimode_simulations.md"},
+ {"thin film" = "nbs/examples/05_thinfilm.md"},
+ {"additive" = "nbs/examples/06_additive_backend.md"},
+ {"layout aware" = "nbs/examples/07_layout_aware.md"},
+ {"sparse (coo)" = "nbs/examples/08_sparse_coo.md"},
+ {"forward only" = "nbs/examples/09_forward_only_backend.md"},
+ {"neff dispersion" = "nbs/examples/10_wavelength_dependent_neff.md"},
+ {"hierarchical circuits" = "nbs/examples/11_hierarchical_circuits.md"},
+ {"data parsers" = "nbs/examples/12_data_parsers.md"},
+ {"surface models" = "nbs/examples/13_surface_models.md"},
+ {"probes" = "nbs/examples/14_probes.md"},
+ {"multi link" = "nbs/examples/15_multi_link.md"}
+ ]},
+ {"internals" = [
+ {"backends" = "nbs/internals/03_backends.md"},
+ {"circuit" = "nbs/internals/02_circuit.md"},
+ {"models" = "nbs/internals/01_models.md"},
+ {"all models" = "nbs/internals/04_all_models.md"}
+ ]},
+ {"api reference" = [
+ {"sax" = "api.md"},
+ {"sax.fit" = "fit.md"},
+ {"sax.models" = "models.md"},
+ {"sax.models.rf" = "models_rf.md"}
+ ]},
+ {"changelog" = "changelog.md"}
+]
+repo_name = "gdsfactory/sax"
+repo_url = "https://github.com/gdsfactory/sax"
+site_author = "Floris Laporte"
+site_description = "Autograd and XLA for S-parameters"
+site_dir = "site"
+site_name = "sax"
+site_url = "https://gdsfactory.github.io/sax"
+
+# ----------------------------------------------------------------------------
+# Social configuration
+# ----------------------------------------------------------------------------
+[[project.extra.social]]
+icon = "fontawesome/brands/github"
+link = "https://github.com/gdsfactory/sax"
+
+[project.markdown_extensions.admonition]
+
+# ----------------------------------------------------------------------------
+# Markdown extensions configuration
+# ----------------------------------------------------------------------------
+[project.markdown_extensions.attr_list]
+
+[project.markdown_extensions.footnotes]
+
+[project.markdown_extensions.pymdownx.arithmatex]
+generic = true
+
+[project.markdown_extensions.pymdownx.details]
+
+[project.markdown_extensions.pymdownx.emoji]
+emoji_generator = "zensical.extensions.emoji.to_svg"
+emoji_index = "zensical.extensions.emoji.twemoji"
+
+[project.markdown_extensions.pymdownx.highlight]
+anchor_linenums = true
+line_spans = "__span"
+pygments_lang_class = true
+
+[project.markdown_extensions.pymdownx.inlinehilite]
+
+[project.markdown_extensions.pymdownx.magiclink]
+
+[project.markdown_extensions.pymdownx.snippets]
+
+[project.markdown_extensions.pymdownx.superfences]
+
+[project.markdown_extensions.pymdownx.tabbed]
+alternate_style = true
+
+[project.markdown_extensions.toc]
+permalink = true
+
+# ----------------------------------------------------------------------------
+# Plugins configuration
+# ----------------------------------------------------------------------------
+[project.plugins.mkdocstrings.handlers.python]
+inventories = [
+ "https://docs.jax.dev/en/latest/objects.inv",
+ "https://docs.kidger.site/jaxtyping/objects.inv",
+ "https://docs.python.org/3/objects.inv",
+ "https://docs.xarray.dev/en/stable/objects.inv",
+ "https://matplotlib.org/stable/objects.inv",
+ "https://numpy.org/doc/stable/objects.inv",
+ "https://pandas.pydata.org/docs/objects.inv",
+ "https://python-markdown.github.io/objects.inv",
+ "https://scipy.github.io/devdocs/objects.inv",
+ "https://typing.readthedocs.io/en/latest/objects.inv",
+ "https://www.mkdocs.org/objects.inv"
+]
+paths = ["src"]
+
+[project.plugins.mkdocstrings.handlers.python.options]
+docstring_options = {ignore_init_summary = true}
+docstring_section_style = "table"
+docstring_style = "google"
+filters = ["!^_"]
+heading_level = 1
+inherited_members = true
+line_length = 88
+merge_init_into_class = true
+separate_signature = true
+show_root_full_path = false
+show_root_heading = true
+show_signature_annotations = true
+show_source = true
+show_symbol_type_heading = true
+show_symbol_type_toc = true
+signature_crossrefs = true
+summary = true
+
+# ----------------------------------------------------------------------------
+# Theme configuration
+# ----------------------------------------------------------------------------
+[project.theme]
+favicon = "assets/favicon.ico"
+features = [
+ "content.code.copy",
+ "navigation.footer"
+]
+language = "en"
+logo = "assets/logo.svg"
+
+[[project.theme.palette]]
+media = "(prefers-color-scheme)"
+toggle.icon = "material/brightness-auto"
+toggle.name = "Switch to light mode"
+
+[[project.theme.palette]]
+accent = "deep-purple"
+media = "(prefers-color-scheme: light)"
+primary = "blue"
+scheme = "default"
+toggle.icon = "material/weather-sunny"
+toggle.name = "Switch to dark mode"
+
+[[project.theme.palette]]
+accent = "deep-purple"
+media = "(prefers-color-scheme: dark)"
+primary = "blue"
+scheme = "slate"
+toggle.icon = "material/weather-night"
+toggle.name = "Switch to system default"