Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 52 additions & 21 deletions gplugins/tidy3d/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
import matplotlib.pyplot as plt
import numpy as np
import tidy3d as td
import tidy3d.web.api.webapi as web
from gdsfactory.component import Component
from gdsfactory.pdk import get_layer_stack
from gdsfactory.technology import LayerStack
from pydantic import NonNegativeFloat
from tidy3d.components.geometry.base import from_shapely
from tidy3d.components.monitor import FieldMonitor
from tidy3d.components.types import Symmetry
from tidy3d.plugins.smatrix import ComponentModeler, Port

Expand Down Expand Up @@ -277,7 +279,7 @@ def get_component_modeler(

cz = np.round(cz, abs(int(np.log10(grid_eps)))).item()

freqs = td.C_0 / np.linspace(
freqs = td.constants.C_0 / np.linspace(
wavelength - bandwidth / 2, wavelength + bandwidth / 2, num_freqs
)

Expand Down Expand Up @@ -445,6 +447,7 @@ def write_sparameters(
plot_epsilon: bool = False,
filepath: PathType | None = None,
overwrite: bool = False,
upload_only: bool = False,
**kwargs: Any,
) -> Sparameters:
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The function can return None when the simulation status is not "completed" (due to the inverted condition on line 613). The return type annotation specifies Sparameters, which does not include None as a valid return type. This creates a type safety issue. The return type should be updated to Sparameters | None or the logic should ensure a valid return in all paths.

Suggested change
) -> Sparameters:
) -> Sparameters | None:

Copilot uses AI. Check for mistakes.
"""Writes the S-parameters for a component.
Expand Down Expand Up @@ -490,7 +493,7 @@ def write_sparameters(
filepath: Optional file path for the S-parameters. If None, uses hash of simulation.
overwrite: Whether to overwrite existing S-parameters. Defaults to False.
kwargs: Additional keyword arguments for the tidy3d Simulation constructor.

upload_only: Whether to upload the simulation to the cloud only. Defaults to False.
"""
layer_stack = layer_stack or get_layer_stack()

Expand Down Expand Up @@ -591,25 +594,53 @@ def write_sparameters(
return dict(np.load(filepath))
else:
time.sleep(0.2)
s = modeler.run()
for port_in in s.port_in.values:
for port_out in s.port_out.values:
for mode_index_in in s.mode_index_in.values:
for mode_index_out in s.mode_index_out.values:
sp[f"{port_in}@{mode_index_in},{port_out}@{mode_index_out}"] = (
s.sel(
port_in=port_in,
port_out=port_out,
mode_index_in=mode_index_in,
mode_index_out=mode_index_out,
).values
)

frequency = s.f.values
sp["wavelengths"] = td.constants.C_0 / frequency
np.savez_compressed(filepath, **sp)
print(f"Simulation saved to {filepath!r}")
return sp
if upload_only:
plot_sources = [
modeler.to_source(port=p, mode_index=0) for p in modeler.ports
]
plot_monitors = [modeler.to_monitor(port=p) for p in modeler.ports]

cz = c.get_layer_center("core")[2]
birdseye = FieldMonitor(
name="birdseye",
interval_space=(4, 4, 1),
freqs=td.constants.C_0 / wavelength,
center=(c.center[0], c.center[1], cz),
size=(c.size[0], c.size[1], 0),
)

sim_with_sources = modeler.simulation.copy(
update={
"sources": plot_sources,
"monitors": list(modeler.simulation.monitors)
+ plot_monitors
+ [birdseye],
}
)

s = web.upload(sim_with_sources, task_name=folder_name)
return s
if not upload_only:
s = modeler.run()
if s.status != "completed":
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The logic condition if s.status != "completed" appears inverted. When the status is NOT completed (e.g., failed, pending, etc.), the code proceeds to extract S-parameters and save results. This should only happen when the status IS "completed". The condition should be if s.status == "completed" instead.

Suggested change
if s.status != "completed":
if s.status == "completed":

Copilot uses AI. Check for mistakes.
for port_in in s.port_in.values:
for port_out in s.port_out.values:
for mode_index_in in s.mode_index_in.values:
for mode_index_out in s.mode_index_out.values:
sp[
f"{port_in}@{mode_index_in},{port_out}@{mode_index_out}"
] = s.sel(
port_in=port_in,
port_out=port_out,
mode_index_in=mode_index_in,
mode_index_out=mode_index_out,
).values

frequency = s.f.values
sp["wavelengths"] = td.constants.C_0 / frequency
np.savez_compressed(filepath, **sp)
print(f"Simulation saved to {filepath!r}")
return sp


def write_sparameters_batch(
Expand Down
Loading