Skip to content

gdsfactory adapter

photonhub.integrations.gdsfactory turns a gdsfactory Component and its layer stack into structures and ports, and plans or runs its S-matrix study. Requires the gdsfactory extra; the module imports without it. Walkthrough: gdsfactory layouts.

Import

import_component

import_component(
    component,
    layer_stack=None,
    *,
    wlen_um: float,
    materials: Optional[Mapping[str, MaterialSpec]] = None,
    background=None,
    port_names: Optional[Sequence[str]] = None,
    mode: Union[str, Mapping[str, str]] = "TE0",
    port_level: Union[None, str, Mapping[str, str]] = None,
    extension_um: Optional[float] = None,
) -> ImportedComponent

Turn a gdsfactory Component into PhotonHub structures and ports.

Parameters

component: A gdsfactory Component. layer_stack: A gdsfactory LayerStack; None (default) takes the active PDK's. Or a sequence of GDSLayer, each (layer, datatype) extruded with its own medium (then pass background=). wlen_um: The wavelength, in microns, at which library materials are evaluated (non-dispersive media). Use the centre of the band you simulate. materials: Material name to a Medium, a Material or a refractive index, matched case-insensitively; it takes precedence over MATERIAL_ALIASES. background: The cladding: a Background, a medium, a material name or a refractive index. None takes the stack's clad level, else its box level. port_names: The optical ports to keep, by name (default all, in component order). A port left out keeps its guide ending at the component's edge. mode: The port mode, "TE0" by default, or a mapping from port name to mode. port_level: The level a port's mode sits on, when its layer matches several: a level name for every port, or a mapping from port name to level name. extension_um: How far each kept port's guide is extended outward, in microns (default three times wlen_um). It must reach through the absorbing layers of the simulation you build.

Returns

ImportedComponent The structures, ports and background, ready for ImportedComponent.simulation.

Raises

ImportError When gdsfactory is needed (layer_stack=None or a real component) and is not installed. ValueError For a drawn level with no medium, a port that is not normal to x or y, a port that does not sit on the face of the device it points through, or a port whose level is ambiguous. A polygon with holes on a sloped-wall level is also refused: a closed ring on the generic PDK's core needs a stack with sidewall_angle=0 for that level.

ImportedComponent dataclass

ImportedComponent(
    name: str,
    structures: Tuple[Structure, ...],
    ports: Tuple[Port, ...],
    background: Background,
    levels: Tuple[ImportedLevel, ...],
    omitted_levels: Mapping[str, str],
    wlen_um: float,
    extension_um: float,
)

A layout component as PhotonHub values: what import_component returns.

structures and ports are in the layout's own frame (microns, the drawing plane is x, y, the stack runs along z), the same two fields as photonhub.library.Component, so ph.export_gds(device, path) accepts it. background is the cladding. levels lists the drawn levels in paint order; omitted_levels maps every level that drew nothing to the reason. wlen_um is the wavelength the materials were evaluated at and extension_um how far each port's guide was extended.

name instance-attribute

name: str

structures instance-attribute

structures: Tuple[Structure, ...]

ports instance-attribute

ports: Tuple[Port, ...]

background instance-attribute

background: Background

levels instance-attribute

levels: Tuple[ImportedLevel, ...]

omitted_levels instance-attribute

omitted_levels: Mapping[str, str]

wlen_um instance-attribute

wlen_um: float

extension_um instance-attribute

extension_um: float

simulation

simulation(
    *,
    wlens_um,
    mesh: Mesh,
    domain: Optional[Domain] = None,
    run=None,
    **simulation_kwargs: Any,
)

A Simulation of this component, fitted around it.

The domain is fitted with domain (default ph.Domain()), the mesh is mesh (no default: the resolution is your convergence choice), and the ports are declared, so their modes are solved at construction. No source is set unless you pass source=; other keywords go to the Simulation constructor. This standalone scene uses the plain domain fit around the readout planes. A study built by hand from it must leave each launch standoff plus the port margin beyond those planes, as plan_component_smatrix does. Warns when the fitted domain still had to continue a port's guide (extension_um too short to reach through the absorbing layers) or when the materials were evaluated outside the simulated band.

plot

plot(z: Optional[float] = None, *, ax=None, **kwargs: Any)

Preview the scene: a cross-section at height z (default the first port's centre height) of a simulation fitted at wlen_um on a coarse preview mesh. Returns the matplotlib Axes of photonhub.Simulation.plot; for another cut or a 3D view call simulation and plot that.

ImportedLevel dataclass

ImportedLevel(
    name: str,
    material: Optional[str],
    medium: Medium,
    zmin_um: float,
    thickness_um: float,
    sidewall_angle: float,
    reference_plane: str,
    mesh_order: Optional[int],
    num_polygons: int,
)

One drawn level of an imported component: its material, the medium it resolved to, and the extrusion every polygon on it takes.

sidewall_angle is in radians with the meaning of photonhub.Polygon.sidewall_angle (positive narrows toward +z), and reference_plane is where the drawn outline applies. mesh_order is the gdsfactory priority (lower wins), None for a GDSLayer list, which paints in list order. num_polygons counts this level's polygons, the port extensions included.

name instance-attribute

name: str

material instance-attribute

material: Optional[str]

medium instance-attribute

medium: Medium

zmin_um instance-attribute

zmin_um: float

thickness_um instance-attribute

thickness_um: float

sidewall_angle instance-attribute

sidewall_angle: float

reference_plane instance-attribute

reference_plane: str

mesh_order instance-attribute

mesh_order: Optional[int]

num_polygons instance-attribute

num_polygons: int

MATERIAL_ALIASES module-attribute

MATERIAL_ALIASES: Mapping[str, str] = (
    types.MappingProxyType(
        {
            "si": "Si",
            "silicon": "Si",
            "c-si": "Si",
            "sio2": "SiO2",
            "oxide": "SiO2",
            "silica": "SiO2",
            "sin": "Si3N4",
            "si3n4": "Si3N4",
            "nitride": "Si3N4",
            "ge": "Ge",
            "germanium": "Ge",
            "air": "Vacuum",
            "vacuum": "Vacuum",
            "gaas": "GaAs",
            "inp": "InP",
            "aln": "AlN",
            "tio2": "TiO2",
            "al2o3": "Sapphire",
            "sapphire": "Sapphire",
            "pmma": "PMMA",
            "caf2": "CaF2",
        }
    )
)

S-matrix study

plan_component_smatrix

plan_component_smatrix(
    component,
    layer_stack=None,
    *,
    wlens_um,
    mesh: Mesh,
    domain: Optional[Domain] = None,
    run=None,
    source_time=None,
    drive: Optional[Sequence[str]] = None,
    materials: Optional[Mapping[str, MaterialSpec]] = None,
    background=None,
    port_names: Optional[Sequence[str]] = None,
    mode: Union[str, Mapping[str, str]] = "TE0",
    port_level: Union[None, str, Mapping[str, str]] = None,
    extension_um: Optional[float] = None,
    simulation_kwargs: Optional[Mapping[str, Any]] = None,
)

Prepare the S-matrix study of a component without running anything.

Imports component (see import_component for layer_stack and the import options; an ImportedComponent is used as it is), with materials evaluated at the band centre of wlens_um; builds the fitted ImportedComponent.simulation with mesh, domain, run and simulation_kwargs; and plans one driven simulation per port with photonhub.analysis.plan_smatrix at the frequencies of wlens_um. source_time defaults to the pulse the scene's own ports take for wlens_um (a single wavelength gets a short pulse).

mesh has no default: the resolution is your convergence choice, and the S-parameters inherit it. Call quote() on the plan for the cost, then run().

The study fit leaves each launch plane at least the default ten port cells from the absorbing layers. When domain.port_margin_um is set, that margin is measured from the launch plane. A symmetry fold that mirrors away any port is refused because it would pair that port's drive with its mirror image; every port must lie on every symmetry plane. The symmetry must match each port mode's tangential electric-field parity (-1 is the odd electric/PEC mirror and +1 is the even magnetic/PMC mirror), or the run can read a wrong mode and report plausible but incorrect S-parameters.

Returns

photonhub.analysis.SMatrixPlan

run_component_smatrix

run_component_smatrix(
    component,
    layer_stack=None,
    *,
    wlens_um,
    mesh: Mesh,
    domain: Optional[Domain] = None,
    run=None,
    source_time=None,
    drive: Optional[Sequence[str]] = None,
    materials: Optional[Mapping[str, MaterialSpec]] = None,
    background=None,
    port_names: Optional[Sequence[str]] = None,
    mode: Union[str, Mapping[str, str]] = "TE0",
    port_level: Union[None, str, Mapping[str, str]] = None,
    extension_um: Optional[float] = None,
    simulation_kwargs: Optional[Mapping[str, Any]] = None,
    runner: Union[
        str, Callable[[Dict[str, Any]], Mapping[str, Any]]
    ] = "local",
    path_dir=None,
    max_workers: int = 1,
    allow_partial: bool = False,
    **runner_kwargs: Any,
)

One call from a component to its S-matrix: plan_component_smatrix then run.

runner="local" (default) runs on the local solver; runner="cloud" submits through ph.cloud.Batch, which quotes each job and holds it to your spending ceiling. device and solver pass through the extra keywords; omitted, they take the cloud defaults (the service's only GPU and the installed solver's commit); a callable runner is used as run describes. path_dir, max_workers, allow_partial and any other keyword go to that method. mesh has no default (see plan_component_smatrix). The symmetry must match each port mode's tangential electric-field parity (-1 is the odd electric/PEC mirror and +1 is the even magnetic/PMC mirror), or the run can read a wrong mode and report plausible but incorrect S-parameters.

Returns

photonhub.analysis.SMatrixResult S has dims (port_out, port_in, f) labelled with the port names.