Skip to content

Bump tidy3d to version >= 2.10 + fix a few bugs in meow making coverage testing fail#698

Merged
joamatab merged 11 commits into
gdsfactory:mainfrom
David-GERARD:fix/tidy3d-2.10
May 5, 2026
Merged

Bump tidy3d to version >= 2.10 + fix a few bugs in meow making coverage testing fail#698
joamatab merged 11 commits into
gdsfactory:mainfrom
David-GERARD:fix/tidy3d-2.10

Conversation

@David-GERARD
Copy link
Copy Markdown
Contributor

@David-GERARD David-GERARD commented Apr 26, 2026

Breaking changes

  • Bumped tidy3d to >=2.10

Fixes

  • In gplugins/meow/meow_eme.py, _compute_s_matrix(modes_per_cell, cells) was:
    • Using calling net["connections"] when the correct field name is net["nets"].
    • Not importing functions from meow.eme correctly.
  • In gplugins/tidy3d/modes.py, custom_serializer() couldn't handle tidy3d Medium objects, causing an error when instanciating a Waveguide object with td Mediums as arguments.
  • In gplugins/tidy3d/materials.py, ComplexNumber is deprecated and replaced by Complex.

Refactors

  • tidy3d.plugins.smatrix.ComponentModeler is deprecated -> tidy3d.plugins.smatrix.ModalComponentModeler.
  • gdsfactory.generic_tech is deprecated -> gdsfactory.gpdk

Docs

  • Added instructions on loading specific optional dependency groups with uv sync

Related issues

Closes #697

Summary by Sourcery

Update tidy3d- and meow-related integrations to support tidy3d>=2.10 and newer meow APIs while aligning type usage and documentation.

Bug Fixes:

  • Fix meow EME S-matrix construction by importing cascade utilities from the correct modules and using the updated netlist field name.
  • Allow tidy3d-based Waveguide models to serialize tidy3d Medium and related custom medium types without errors.

Enhancements:

  • Replace deprecated tidy3d ComponentModeler usage with ModalComponentModeler across component modeling helpers and docstrings.
  • Update tidy3d material handling to use the new Complex type instead of the deprecated ComplexNumber.
  • Relax Pydantic typing in the Waveguide model to permit arbitrary tidy3d types for improved compatibility.

Build:

  • Bump tidy3d dependency to version >=2.10 across relevant optional dependency groups and align meow optional dependency versions.

Documentation:

  • Clarify README instructions for installing gplugins with uv, including how to select specific optional dependency groups.

@David-GERARD David-GERARD requested a review from joamatab as a code owner April 26, 2026 14:41
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 26, 2026

Reviewer's Guide

Updates the project to require tidy3d>=2.10, migrates Tidy3D integration to newer APIs (ModalComponentModeler, Complex), fixes serialization and MEOW EME integration issues that were breaking tests, and refreshes docs for installing optional dependency groups with uv.

Sequence diagram for write_sparameters using ModalComponentModeler and web.run

sequenceDiagram
    participant User
    participant Tidy3dComponent as Tidy3dComponent
    participant ModalComponentModeler as ModalComponentModeler
    participant WebClient as web

    User->>Tidy3dComponent: write_sparameters(component, settings)
    Tidy3dComponent->>Tidy3dComponent: get_component_modeler(...)
    Tidy3dComponent-->>ModalComponentModeler: construct simulation, ports, freqs
    Tidy3dComponent-->>User: modeler

    User->>WebClient: web.run(modeler, task_name, verbose, path)
    WebClient->>ModalComponentModeler: read simulation and ports
    WebClient-->>User: modeler_data (Sparameters and results)
Loading

Class diagram for updated Tidy3D Waveguide model and serializer

classDiagram
    class BaseModel
    class Waveguide {
        <<pydantic_model>>
        +arbitrary_types_allowed bool
    }
    class td_Medium
    class td_CustomMedium
    class td_PoleResidue

    class Serializer {
        +custom_serializer(data)
    }

    BaseModel <|-- Waveguide

    Serializer --> BaseModel : serialize_json
    Serializer --> td_Medium : serialize_json
    Serializer --> td_CustomMedium : serialize_json
    Serializer --> td_PoleResidue : serialize_json
Loading

Class diagram for ModalComponentModeler migration and materials API

classDiagram
    class Tidy3dComponent {
        +get_component_modeler(wavelength, bandwidth, num_freqs, min_steps_per_wvl, center_z, sim_size_z, port_size_mult, run_only, element_mappings, extra_monitors, mode_spec, boundary_spec, run_time, shutoff, grid_eps, symmetry, kwargs) ModalComponentModeler
    }

    class ModalComponentModeler

    class MaterialsAPI {
        +get_epsilon(spec, wavelength) Complex
    }

    class Complex

    Tidy3dComponent --> ModalComponentModeler : builds
    MaterialsAPI --> Complex : returns
Loading

Flow diagram for updated MEOW EME S-matrix computation

flowchart TD
    A[modes_per_cell, cells] --> B[compute_propagation_s_matrices]
    A --> C[compute_interface_s_matrices]
    B --> D[build net dict]
    C --> D
    D --> E[_get_netlist]
    E --> F[net instances to sax.scoo]
    F --> G[connections_or_nets]
    G --> H{is dict?}
    H -- yes --> I["build nets list from key,value"]
    H -- no --> J[use existing nets]
    I --> K["net nets = nets list"]
    J --> K
    K --> L["sa = sax.circuit(net)"]
    L --> M[return S matrix]
Loading

File-Level Changes

Change Details Files
Migrate Tidy3D component modeling helpers from deprecated ComponentModeler APIs to ModalComponentModeler while keeping behavior and signatures effectively the same.
  • Change get_component_modeler return type and implementation to use ModalComponentModeler instead of ComponentModeler
  • Update write_sparameters and write_sparameters_batch docstrings and internal comments to reference ModalComponentModeler semantics
  • Adjust web.run call comment to reflect ModalComponentModeler limitation
gplugins/tidy3d/component.py
Fix MEOW EME S-matrix computation to use the correct netlist helpers and field names compatible with newer meow-sim and sax APIs.
  • Import compute_interface_s_matrices and compute_propagation_s_matrices from meow.eme instead of meow.eme.sax
  • Import _get_netlist from meow.eme.cascade
  • Use net['nets'] instead of deprecated net['connections'] and convert dict-style connections to nets list if needed
gplugins/meow/meow_eme.py
Extend custom serialization and Waveguide model to support tidy3d Medium and related objects so Waveguide construction works with td Medium instances.
  • Broaden custom_serializer argument type to include td.Medium
  • Treat BaseModel, td.CustomMedium, td.Medium, and td.PoleResidue uniformly as JSON-serializable via .json()
  • Allow arbitrary types in Waveguide Pydantic model by setting arbitrary_types_allowed=True
gplugins/tidy3d/modes.py
Update Tidy3D materials integration to use the new Complex type instead of deprecated ComplexNumber.
  • Import Complex from tidy3d.components.types
  • Change get_epsilon return type from ComplexNumber to Complex
gplugins/tidy3d/materials.py
Bump dependency versions to tidy3d>=2.10 and meow-sim>=0.15 and update optional dependency groups accordingly.
  • Raise tidy3d lower bound to >=2.10 for devsim, meow, and tidy3d extras
  • Relax meow-sim version constraint to >=0.15 and remove upper bound tied to 0.14.x
pyproject.toml
Improve README installation instructions to illustrate using uv sync with multiple optional extras including tidy3d.
  • Change wording from installing GDSFactory to installing gplugins and dependency groups
  • Update uv sync example command to include docs, dev, and mention other extras like tidy3d and femwell
README.md

Assessment against linked issues

Issue Objective Addressed Explanation
#697 Update gplugins.tidy3d.get_component_modeler() to use the new tidy3d>=2.10 ModalComponentModeler API (instead of the deprecated ComponentModeler) and stop passing invalid fields (folder_name, path_dir, verbose) that cause pydantic ValidationError.
#697 Migrate the tidy3d plugin codebase to be compatible with tidy3d>=2.10 and reflect this in dependency constraints (e.g., updated types, classes, and version pins).

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

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 found 2 issues, and left some high level feedback:

  • The custom_serializer function uses isinstance with a union type (str | None | np.ndarray and BaseModel | td.CustomMedium | td.Medium | td.PoleResidue), which will raise a TypeError at runtime; these should be changed to tuples like isinstance(data, (str, type(None), np.ndarray)) and isinstance(data, (BaseModel, td.CustomMedium, td.Medium, td.PoleResidue)).
  • The get_component_modeler docstring still documents folder_name, path_dir, and verbose arguments that are no longer in the function signature; either reintroduce these parameters if they are still needed or update the docstring and any call sites to keep the API and documentation consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `custom_serializer` function uses `isinstance` with a union type (`str | None | np.ndarray` and `BaseModel | td.CustomMedium | td.Medium | td.PoleResidue`), which will raise a `TypeError` at runtime; these should be changed to tuples like `isinstance(data, (str, type(None), np.ndarray))` and `isinstance(data, (BaseModel, td.CustomMedium, td.Medium, td.PoleResidue))`.
- The `get_component_modeler` docstring still documents `folder_name`, `path_dir`, and `verbose` arguments that are no longer in the function signature; either reintroduce these parameters if they are still needed or update the docstring and any call sites to keep the API and documentation consistent.

## Individual Comments

### Comment 1
<location path="gplugins/tidy3d/component.py" line_range="239-248" />
<code_context>
+        """Returns a ModalComponentModeler instance for the component.
</code_context>
<issue_to_address>
**issue:** Docstring still documents folder_name, path_dir, and verbose parameters that are no longer in the function signature.

Please update the docstring so its parameter list matches the current function signature—either remove `folder_name`, `path_dir`, and `verbose`, or add the parameters back if they’re still meant to be supported.
</issue_to_address>

### Comment 2
<location path="gplugins/tidy3d/modes.py" line_range="38-41" />
<code_context>


-def custom_serializer(data: str | float | BaseModel) -> str:
+def custom_serializer(data: str | float | BaseModel | td.Medium) -> str:
     # If data is a string, just return it.
     if isinstance(data, str | None | np.ndarray):
</code_context>
<issue_to_address>
**issue (bug_risk):** Using union types directly in isinstance will raise a TypeError at runtime.

`isinstance` doesn’t accept PEP 604 unions. This call will raise `TypeError: isinstance() argument 2 cannot be a union`. Use a tuple of types instead, e.g. `isinstance(data, (BaseModel, td.CustomMedium, td.Medium, td.PoleResidue))` to preserve the same behavior.
</issue_to_address>

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 gplugins/tidy3d/component.py
Comment thread gplugins/tidy3d/modes.py
Comment on lines +38 to 41
def custom_serializer(data: str | float | BaseModel | td.Medium) -> str:
# If data is a string, just return it.
if isinstance(data, str | None | np.ndarray):
return data
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.

issue (bug_risk): Using union types directly in isinstance will raise a TypeError at runtime.

isinstance doesn’t accept PEP 604 unions. This call will raise TypeError: isinstance() argument 2 cannot be a union. Use a tuple of types instead, e.g. isinstance(data, (BaseModel, td.CustomMedium, td.Medium, td.PoleResidue)) to preserve the same behavior.

@joamatab joamatab added the dependencies Pull requests that update a dependency file label May 5, 2026
tidy3d often introduces breaking API changes across minor releases,
so we pin to ~=2.11.1 (>=2.11.1, <2.12.0) to avoid unexpected breakage.
@joamatab
Copy link
Copy Markdown
Contributor

joamatab commented May 5, 2026

tidy3d often introduces breaking API changes across minor releases, hence the ~=2.11.1 pin to cap at <2.12.0.

@joamatab joamatab merged commit a74078a into gdsfactory:main May 5, 2026
15 checks passed
@David-GERARD
Copy link
Copy Markdown
Contributor Author

@joamatab could we get a new release soon to get this PR and #676 which fix the tidy3D plugin into the production version?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Breaking change in Tidy3d >= 2.10 breaking gplugin.get_component_modeler()

2 participants