dphox package#

Submodules#

dphox.prefab.active module#

class dphox.prefab.active.Clearout(clearout_etch, clearout_etch_stop_grow, clearout_layer=CommonLayer.CLEAROUT, clearout_etch_stop_layer=CommonLayer.ALUMINA, name='clearout')[source]#

Bases: dphox.device.Device

Clearout device which is generally useful for sacrificial etches in MEMS devices.

clearout_etch#

THe clearout etch box, which selectively removes silicon dioxide.

Type

dphox.pattern.Box

clearout_etch_stop_grow#

The etch stop offset factor beyond the size of the clearout etch box

Type

float

clearout_layer#

The clearout layer

Type

str

clearout_etch_stop_layer#

The clearout etch stop layer (this can vary more than the clearout layer).

Type

str

clearout_etch: dphox.pattern.Box#
clearout_etch_stop_grow: float#
clearout_etch_stop_layer: str = 'alumina'#
clearout_layer: str = 'clearout'#
name: str = 'clearout'#
class dphox.prefab.active.GndAnchorWaveguide(rib_waveguide, gnd_pad, gnd_connector, via, offset_into_rib, dope_expand_tuple=(0, 0), ridge=CommonLayer.RIDGE_SI, gnd_pad_dope=CommonLayer.PPP_SI, name='gnd_anchor_waveguide')[source]#

Bases: dphox.device.Device

Ground anchor waveguide device useful for connecting a waveguide to the ground plane.

rib_waveguide#

Transition waveguide for connecting to ground pads

Type

dphox.prefab.passive.RibDevice

gnd_pad#

Ground pad for ultimately connecting the waveguide to the ground plane

Type

dphox.pattern.Box

gnd_connector#

Ground connector for connecting the anchor waveguide to the ground pad gnd_pad.

Type

dphox.pattern.Box

offset_into_rib#

Offset of the ground connector into the rib.

Type

float

dope_expand_tuple#

Dope expand tuple (first applies expand, then grow operation on ground pad)

Type

Tuple[float, float]

ridge#

Waveguide layer (usually silicon)

Type

str

gnd_pad_dope#

Electrode dope setting

Type

str

dope_expand_tuple: Tuple[float, float] = (0, 0)#
gnd_connector: dphox.pattern.Box#
gnd_pad: dphox.pattern.Box#
gnd_pad_dope: str = 'pppdoped_si'#
name: str = 'gnd_anchor_waveguide'#
offset_into_rib: float#
rib_waveguide: dphox.prefab.passive.RibDevice#
ridge: str = 'ridge_si'#
via: dphox.device.Via#
class dphox.prefab.active.HTree(splitter, depth, pitch, root_dx=0, leaf_dx=0, name='htree', wg_layer=CommonLayer.RIDGE_SI, top_level=True)[source]#

Bases: dphox.device.Device

An H-tree for optical phased array and transceiver applications.

Parameters
  • splitter (Device) – Splitter for the h tree (t splitter)

  • depth (int) – Depth of the H-tree

  • pitch (float) – Pitch of the final H-tree devices

  • root_dx (float) – Optional user-calculated value to adjust waveguide length for the root of the h-tree

  • leaf_dx (float) – Optional user-calculated value to adjust waveguide length for the leaves of the h-tree This could be based on distances calculated in final device to maintain pitch.

  • wg_layer (str) – Waveguide layer for the H-tree photonic routing and splitting

  • top_level (bool) – Whether this layer should be considered the top level of the tree (useful for labelling ports)

Returns

The H-tree with devices attached if provided.

depth: int#
fill_ports(device)[source]#
leaf_dx: float = 0#
name: str = 'htree'#
pitch: float#
root_dx: float = 0#
splitter: dphox.device.Device#
top_level: bool = True#
wg_layer: str = 'ridge_si'#
class dphox.prefab.active.LateralNemsPS(waveguide_w, phase_shifter_waveguide, gnd_anchor_waveguide, clearout, actuator, trace_w, clearout_pos_sep, clearout_gnd_sep, ridge=CommonLayer.RIDGE_SI, pos_metal_layer=CommonLayer.METAL_1, gnd_metal_layer=CommonLayer.METAL_2, name='lateral_nems_ps')[source]#

Bases: dphox.device.Device

Lateral NEMS phase shifter, which is actuated by the specified actuator (pull-in or -out).

phase_shifter_waveguide#

Phase shifter waveguide (including the nanofins)

Type

dphox.pattern.Pattern

gnd_anchor_waveguide#

Ground anchor waveguide connecting the waveguide to ground.

Type

dphox.prefab.active.GndAnchorWaveguide

clearout#

Clearout of the oxide cladding material for the MEMS actuation.

Type

dphox.prefab.active.Clearout

actuator#

Actuator (pull-out or pull-in) for controlling the phase shift.

Type

Union[dphox.prefab.active.PullInNemsActuator, dphox.prefab.active.PullOutNemsActuator]

ridge#

Ridge silicon waveguide.

Type

str

trace_w#

Trace width for the metal routing.

Type

float

clearout_pos_sep#

Clearout trace separation for the pos terminal avoiding metal accidental etching (HF nasty).

Type

float

clearout_gnd_sep#

Clearout trace separation for the gnd terminal avoiding metal accidental etching (HF nasty).

Type

float

pos_metal_layer#

Positive electrode metal layer.

Type

str

gnd_metal_layer#

Ground electrode metal layer.

Type

str

actuator: Union[dphox.prefab.active.PullInNemsActuator, dphox.prefab.active.PullOutNemsActuator]#
clearout: dphox.prefab.active.Clearout#
clearout_gnd_sep: float#
clearout_pos_sep: float#
gnd_anchor_waveguide: dphox.prefab.active.GndAnchorWaveguide#
gnd_metal_layer: str = 'metal_2'#
name: str = 'lateral_nems_ps'#
phase_shifter_waveguide: dphox.pattern.Pattern#
pos_metal_layer: str = 'metal_1'#
ridge: str = 'ridge_si'#
trace_w: float#
waveguide_w: float#
class dphox.prefab.active.LocalMesh(mzi, n, triangular=True, name='mesh')[source]#

Bases: dphox.device.Device

A locally interacting rectangular mesh, or triangular mesh if specified. Note: triangular meshes can self-configure, but rectangular meshes cannot.

mzi#

The MZI object, which acts as the unit cell for the mesh.

Type

dphox.prefab.active.MZI

n#

The number of inputs and outputs for the mesh.

Type

int

triangular#

Triangular mesh, otherwise rectangular mesh

Type

bool

name#

Name of the device

Type

str

demo_3d_arrays(ps_w_factor=4, height=0.22, sep=0.22)[source]#
demo_polys(ps_w_factor=4)[source]#

Demo polygons, useful for plotting stuff, using only the polygons in the silicon layer.

Note

This method is generally useless unless used for demo purposes and will be deleted once a cleaner solution is found.

Parameters

ps_w_factor (float) – phase shifter width factor

Returns

NOT numbers)

Return type

A numpy array consisting of lists of polygons (note

mzi: dphox.prefab.active.MZI#
n: int#
name: str = 'mesh'#
triangular: bool = True#
class dphox.prefab.active.MZI(coupler, ridge=CommonLayer.RIDGE_SI, top_internal=<factory>, bottom_internal=<factory>, top_external=<factory>, bottom_external=<factory>, name='mzi')[source]#

Bases: dphox.device.Device

An MZI with multilayer devices in the arms (e.g., phase shifters and/or grating taps).

Note

This class assumes that the arms begin and end along the horizontal (\(x\)-axis).

coupler#

Directional coupler or MMI for MZI

Type

dphox.prefab.passive.DC

ridge#

Waveguide layer string

Type

str

top_internal#

Top center arm (waveguide matching bottom arm length if None)

Type

List[Union[dphox.pattern.Pattern, dphox.device.Device, dphox.prefab.active.MultilayerPath, float]]

bottom_internal#

Bottom center arm (waveguide matching top arm length if None)

Type

List[Union[dphox.pattern.Pattern, dphox.device.Device, dphox.prefab.active.MultilayerPath, float]]

top_external#

Top input (waveguide matching bottom arm length if None)

Type

List[Union[dphox.pattern.Pattern, dphox.device.Device, dphox.prefab.active.MultilayerPath, float]]

bottom_external#

Bottom input (waveguide matching top arm length if None)

Type

List[Union[dphox.pattern.Pattern, dphox.device.Device, dphox.prefab.active.MultilayerPath, float]]

name#

Name of the MZI

Type

str

bottom_external: List[Union[dphox.pattern.Pattern, dphox.device.Device, MultilayerPath, float]]#
bottom_internal: List[Union[dphox.pattern.Pattern, dphox.device.Device, MultilayerPath, float]]#
coupler: dphox.prefab.passive.DC#
name: str = 'mzi'#
path(flip=False)[source]#
ridge: str = 'ridge_si'#
top_external: List[Union[dphox.pattern.Pattern, dphox.device.Device, MultilayerPath, float]]#
top_internal: List[Union[dphox.pattern.Pattern, dphox.device.Device, MultilayerPath, float]]#
class dphox.prefab.active.MultilayerPath(waveguide_w, sequence, path_layer, name='multilayer_path', start_port=Port(x=0, y=0, a=0, w=1, z=0, h=0, layer=<CommonLayer.PORT: 'port'>))[source]#

Bases: dphox.device.Device

Multilayer path for appending a linear sequence of elements end-to-end

waveguide_w#

Waveguide width.

Type

float

sequence#

Sequence of Device, Pattern or float`s. The :code:`float corresponds to straight waveguides of such lengths and waveguide width waveguide_w).

Type

List[Union[dphox.pattern.Pattern, dphox.device.Device, dphox.prefab.active.MultilayerPath, float]]

path_layer#

Pattern layer.

Type

str

name#

Name of the device.

Type

str

extend(path)[source]#

Extend this multilayer path using a path in the path_layer.

Parameters

path (Union[float, Pattern]) – The path to add (either a float for straight segment or a path pattern)

Returns

The updated multilayer path.

name: str = 'multilayer_path'#
path_layer: str#
sequence: List[Union[dphox.pattern.Pattern, dphox.device.Device, MultilayerPath, float]]#
start_port: dphox.port.Port = Port(x=0, y=0, a=0, w=1, z=0, h=0, layer=<CommonLayer.PORT: 'port'>)#
waveguide_w: float#
class dphox.prefab.active.PullInNemsActuator(pos_pad, connector, via, dope_expand_tuple=(0, 0), ridge=CommonLayer.RIDGE_SI, dopes=CommonLayer.PPP_SI, name='pull_in_actuator')[source]#

Bases: dphox.device.Device

Pull in NEMS actuator moves material toward the core waveguide to change the phase.

Actually, this class is really not an actuator, but it provides the electrode that produces the actuation. However, in terms of constructing the phase shifter object, it serves the same purpose as the pull-out variety in terms of functionality.

pos_pad#

Pad for the positive terminal for the NEMS actuation

Type

dphox.pattern.Box

connector#

Connector box for connecting the device

Type

dphox.pattern.Box

dope_expand_tuple#

Dope expand tuple (first applies expand, then grow operation on ground pad)

Type

Tuple[float, float]

ridge#

Waveguide layer (usually silicon)

Type

str

dope#

Electrode dope setting

connector: dphox.pattern.Box#
dope_expand_tuple: Tuple[float, float] = (0, 0)#
dopes: str = 'pppdoped_si'#
name: str = 'pull_in_actuator'#
pos_pad: dphox.pattern.Box#
ridge: str = 'ridge_si'#
via: dphox.device.Via#
class dphox.prefab.active.PullOutNemsActuator(pos_pad, pad_sep, flexure, connector, via, dope_expand_tuple=(0, 0), ridge=CommonLayer.RIDGE_SI, actuator_dope=CommonLayer.P_SI, pos_pad_dope=CommonLayer.PPP_SI, name='pull_out_actuator')[source]#

Bases: dphox.device.Device

Pull out NEMS actuator moves material away from the core waveguide to change the phase.

pos_pad#

Electrode box

Type

dphox.pattern.Box

flexure#

Connector box

Type

dphox.pattern.MEMSFlexure

dope_expand_tuple#

Dope expand tuple. This first applies expand, then grow operation on pos pad. For the crab-leg flexure, this applies a grow operation that is the sum of the two tuple elements

Type

Tuple[float, float]

ridge#

Waveguide layer (usually silicon)

Type

str

actuator_dope#

Actuator dope setting (set lower than pos_pad dope if possible to improve spring mechanics)

Type

str

pos_pad_dope#

Electrode dope setting

Type

str

actuator_dope: str = 'p_si'#
connector: dphox.pattern.Box#
dope_expand_tuple: Tuple[float, float] = (0, 0)#
flexure: dphox.pattern.MEMSFlexure#
name: str = 'pull_out_actuator'#
pad_sep: float#
pos_pad: dphox.pattern.Box#
pos_pad_dope: str = 'pppdoped_si'#
ridge: str = 'ridge_si'#
via: dphox.device.Via#
class dphox.prefab.active.ThermalPS(waveguide, ps_w, via, ridge=CommonLayer.RIDGE_SI, heater=CommonLayer.HEATER, name='thermal_ps')[source]#

Bases: dphox.device.Device

Thermal phase shifter (e.g. TiN phase shifter).

waveguide#

Waveguide under the phase shifter

Type

dphox.pattern.Pattern

ps_w#

Phase shifter width

Type

float

via#

Via to connect heater to the top metal layer

Type

dphox.device.Via

ridge#

Waveguide layer

Type

str

ps_layer#

Phase shifter layer (e.g. TiN)

heater: str = 'heater'#
name: str = 'thermal_ps'#
ps_w: float#
ridge: str = 'ridge_si'#
via: dphox.device.Via#
waveguide: dphox.pattern.Pattern#

dphox.prefab.passive module#

class dphox.prefab.passive.Array(unit, grid_shape, pitch=None)[source]#

Bases: dphox.pattern.Pattern

Array of boxes or ellipses for 2D photonic crystals.

This class can generate large circle arrays which may be used for photonic crystal designs or for slow light applications.

unit#

The pattern to repeat in the array

Type

dphox.pattern.Pattern

grid_shape#

Number of rows and columns

Type

Tuple[int, int]

pitch#

The distance between the circles in the Hole array

Type

Optional[Union[float, Tuple[float, float]]]

grid_shape: Tuple[int, int]#
pitch: Optional[Union[float, Tuple[float, float]]] = None#
unit: dphox.pattern.Pattern#
class dphox.prefab.passive.Cross(waveguide)[source]#

Bases: dphox.pattern.Pattern

waveguide#

waveguide to form the crossing (used to implement tapering)

Type

dphox.pattern.Pattern

waveguide: dphox.pattern.Pattern#
class dphox.prefab.passive.DC(waveguide_w, radius, interport_distance, gap_w, interaction_l, euler=0.2, end_l=0, coupler_waveguide_w=None)[source]#

Bases: dphox.pattern.Pattern

Directional coupler

A directional coupler is a symmetric component (across x and y dimensions) that contains two waveguides that interact and couple light by adiabatically bending the waveguides towards each other, interacting over some interaction length interaction_l, and then adiabatically bending out to the original interport distance. An MMI can actually be created if the gap_w is set to be negative.

waveguide_w#

Waveguide width at the inputs and outputs.

Type

float

radius#

The bend radius of the directional coupler

Type

float

interport_distance#

Distance between the ports of the directional coupler.

Type

float

gap_w#

Gap between the waveguides in the interaction region.

Type

float

interaction_l#

Interaction length for the interaction region.

Type

float

euler#

The euler parameter for the directional coupler bend.

Type

float

end_l#

End length for the coupler (before and after the bends).

Type

float

coupler_waveguide_w#

Coupling waveguide width

Type

Optional[float]

coupler_waveguide_w: Optional[float] = None#
device(layer=CommonLayer.RIDGE_SI)[source]#
end_l: float = 0#
euler: float = 0.2#
gap_w: float#
interaction_l: float#
property interaction_points: numpy.ndarray#
Return type

ndarray

interport_distance: float#
property path_array#
radius: float#
waveguide_w: float#
class dphox.prefab.passive.Escalator(bottom_waveguide, top_waveguide=None, bottom=CommonLayer.RIDGE_SI, top=CommonLayer.RIDGE_SIN, name='escalator')[source]#

Bases: dphox.device.Device

Escalator device implemented using tapers facing each other

bottom_waveguide#

The bottom waveguide of escalator represented as a Waveguide object to allow features such as tapering and coupling.

Type

dphox.pattern.Pattern

top_waveguide#

The top waveguide of escalator represented as a Waveguide object to allow features such as tapering and coupling.

Type

Optional[dphox.pattern.Pattern]

bottom#

Bottom layer of escalator.

Type

str

top#

Top layer of escalator.

Type

str

name#

The device name for the escalator.

Type

str

bottom: str = 'ridge_si'#
bottom_waveguide: dphox.pattern.Pattern#
name: str = 'escalator'#
top: str = 'ridge_sin'#
top_waveguide: Optional[dphox.pattern.Pattern] = None#
class dphox.prefab.passive.FocusingGrating(waveguide_w=0.5, angle=22.5, n_env=1.0, n_core=3.4784, min_period=40, num_periods=30, wavelength=1.55, fiber_angle=82, duty_cycle=0.5, grating_frac=1, resolution=99, rib_grow=1, waveguide_extra_l=0, name='focusing_grating', ridge=CommonLayer.RIDGE_SI, slab=CommonLayer.RIB_SI)[source]#

Bases: dphox.device.Device

Focusing grating with partial etch.

angle#

The opening angle for the focusing grating.

Type

float

waveguide_w#

The waveguide width.

Type

float

wavelength#

wavelength accepted by the grating.

Type

float

duty_cycle#

duty cycle for the grating

Type

float

n_clad#

clad material index of refraction (assume oxide by default).

n_core#

core material index of refraction (assume silicon by default).

Type

int

fiber_angle#

angle of the fiber in degrees from horizontal (not NOT vertical).

Type

float

num_periods#

number of grating periods

Type

int

resolution#

Number of evaluations for the curve.

Type

int

grating_frac#

The fraction of the distance radiating from the center occupied by the grating (otherwise ridge).

Type

float

rib_grow#

Offset the rib / slab layer in size (usually positive).

Type

float

waveguide_extra_l#

The extra length of the waveguide

Type

float

name#

Name of the device.

Type

str

ridge#

The ridge layer for the partial etch.

Type

dphox.foundry.CommonLayer

slab#

The slab layer for the partial etch.

Type

dphox.foundry.CommonLayer

angle: float = 22.5#
duty_cycle: float = 0.5#
fiber_angle: float = 82#
grating_frac: float = 1#
min_period: int = 40#
n_core: int = 3.4784#
n_env: int = 1.0#
name: str = 'focusing_grating'#
num_periods: int = 30#
resolution: int = 99#
rib_grow: float = 1#
ridge: dphox.foundry.CommonLayer = 'ridge_si'#
slab: dphox.foundry.CommonLayer = 'rib_si'#
waveguide_extra_l: float = 0#
waveguide_w: float = 0.5#
wavelength: float = 1.55#
class dphox.prefab.passive.Interposer(waveguide_w, n, init_pitch, final_pitch, radius=None, euler=0, trombone_radius=5, self_coupling_final=True, self_coupling_init=False, self_coupling_radius=None, self_coupling_extension=0, additional_x=0, num_trombones=1, trombone_at_end=True)[source]#

Bases: dphox.pattern.Pattern

Pitch-changing array of waveguides with path length correction.

waveguide_w#

The waveguide width.

Type

float

n#

The number of I/O (waveguides) for interposer.

Type

int

init_pitch#

The initial pitch (distance between successive waveguides) entering the interposer.

Type

float

radius#

The radius of bends for the interposer.

Type

Optional[float]

trombone_radius#

The trombone bend radius for path equalization.

Type

float

final_pitch#

The final pitch (distance between successive waveguides) for the interposer.

Type

float

self_coupling_extension_extent#

The self coupling for alignment, which is useful since a major use case of the interposer is for fiber array coupling.

additional_x#

The additional horizontal distance (useful in fiber array coupling for wirebond clearance).

Type

float

num_trombones#

The number of trombones for path equalization.

Type

int

trombone_at_end#

Whether to use a path-equalizing trombone near the waveguides spaced at final_period.

Type

bool

additional_x: float = 0#
device(layer=CommonLayer.RIDGE_SI)[source]#
euler: float = 0#
final_pitch: float#
init_pitch: float#
n: int#
num_trombones: int = 1#
radius: Optional[float] = None#
self_coupling_extension: float = 0#
self_coupling_final: bool = True#
self_coupling_init: bool = False#
self_coupling_radius: float = None#
trombone_at_end: bool = True#
trombone_radius: float = 5#
waveguide_w: float#
with_gratings(grating, layer=CommonLayer.RIDGE_SI)[source]#
class dphox.prefab.passive.RibDevice(ridge_waveguide, slab_waveguide=None, ridge=CommonLayer.RIDGE_SI, slab=CommonLayer.RIB_SI, name='rib_wg')[source]#

Bases: dphox.device.Device

Waveguide cross section allowing specification of ridge and slab waveguides.

ridge_waveguide#

The ridge waveguide (the thick section of the rib), represented as a Waveguide object to allow features such as tapering and coupling. Generally this should be smaller than slab_waveguide. The port of this device is defined using the port of the ridge waveguide.

Type

dphox.pattern.Pattern

slab_waveguide#

The slab waveguide (the thin section of the rib), represented as a Waveguide object to allow features such as tapering and coupling. Generally this should be larger than ridge_waveguide. If not specified, this merely implements a waveguide pattern.

Type

Optional[dphox.pattern.Pattern]

ridge#

Ridge layer.

Type

str

slab#

Slab layer.

Type

str

name#

The device name.

Type

str

name: str = 'rib_wg'#
ridge: str = 'ridge_si'#
ridge_waveguide: dphox.pattern.Pattern#
slab: str = 'rib_si'#
slab_waveguide: Optional[dphox.pattern.Pattern] = None#
class dphox.prefab.passive.StraightGrating(extent, waveguide, pitch, duty_cycle=0.5, rib_grow=0, num_periods=None, name='straight_grating', ridge=CommonLayer.RIDGE_SI, slab=CommonLayer.RIB_SI)[source]#

Bases: dphox.device.Device

Straight (non-focusing) grating with partial etch.

extent#

Dimension of the extent of the grating.

Type

Tuple[float, float]

waveguide#

The waveguide to connect to the grating structure (can be tapered if desired)

Type

dphox.pattern.Pattern

pitch#

The pitch between the grating teeth.

Type

float

duty_cycle#

The fill factor for the grating.

Type

float

rib_grow#

Offset the rib / slab layer in size (usually positive).

Type

float

num_periods#

The number of periods (uses maximum given extent and pitch if not specified).

Type

Optional[int]

name#

Name of the device.

Type

str

ridge#

The ridge layer for the partial etch.

Type

dphox.foundry.CommonLayer

slab#

The slab layer for the partial etch.

Type

dphox.foundry.CommonLayer

duty_cycle: float = 0.5#
extent: Tuple[float, float]#
name: str = 'straight_grating'#
num_periods: Optional[int] = None#
pitch: float#
rib_grow: float = 0#
ridge: dphox.foundry.CommonLayer = 'ridge_si'#
slab: dphox.foundry.CommonLayer = 'rib_si'#
waveguide: dphox.pattern.Pattern#
class dphox.prefab.passive.TSplitter(waveguide_w, splitter_l, radius, splitter_mmi_w=None, input_l=0, output_l=0)[source]#

Bases: dphox.pattern.Pattern

Pitch-changing array of waveguides with path length correction.

Parameters
  • waveguide_w (float) – The waveguide width.

  • splitter_l (float) – The splitter length (ignoring the turns).

  • radius (float) – The radius.

  • splitter_mmi_w (Optional[float]) – Splitter MMI width (use twice the waveguide width by default).

  • input_l (float) – The input extension length.

  • output_l (float) – The output extension length.

input_l: float = 0#
output_l: float = 0#
radius: float#
splitter_l: float#
splitter_mmi_w: Optional[float] = None#
waveguide_w: float#
class dphox.prefab.passive.TapDC(dc, radius, angle=90, euler=0, ridge=CommonLayer.RIDGE_SI, name='tap')[source]#

Bases: dphox.pattern.Pattern

Tap directional coupler

dc#

the directional coupler that acts as a tap coupler

Type

dphox.prefab.passive.DC

grating_pad#

the grating pad for the tap

turn_radius#

The turn radius for the tap DC

angle: float = 90#
dc: dphox.prefab.passive.DC#
euler: float = 0#
name: str = 'tap'#
radius: float#
ridge: str = 'ridge_si'#
with_gratings(grating)[source]#

dphox.demo module#

dphox.demo.lateral_nems_ps(ps_l=100, anchor_length=3.1, clearout_height=12, via_extent=(0.5, 0.5), ps_taper_change=- 0.2, flexure_box_w=31, nominal_gap=0.201, waveguide_w=0.5, nanofin_w=0.2, taper_l=10, anchor_taper_l=1.4, pull_in=False, trace_w=1, smooth=0)[source]#

dphox.device module#

class dphox.device.Device(name, devices=None)[source]#

Bases: object

A Device defines a device (active or passive) in a GDS.

A Device is a core object in DPhox, which enables composition of multiple Pattern or Polygon mapped to process stack layers into a single Device. Once the process is defined, Trimesh may be used to show a full 3D model of the device. Additionally, a Device can be mapped to a GDSPY or Nazca cell.

A Device is more or less the same as a GDS cell, including hierarchical design and transform data for subcells in the hierarchy.

name#

Name of the device. This name can be anything you choose, ideally not repeating any previously defined Device.

devices#

A list of devices, either a Device OR a Pattern or PolygonLike followed by a layer label (integer or string). None of these devices should have existing children (will throw and error if they do, since these should be added via place not this contructor).

child_to_device#

A map between child names and actual devices (cells)

child_to_transform#

A map between child names and the GDS-formatted transforms (used for fast GDS generation)

add(pattern, layer)[source]#

Add pattern, layer to Multilayer

Parameters
  • pattern (Pattern) – Pattern to add.

  • layer (str) – Layer to incorporate Pattern.

Returns:

classmethod aggregate(devices, name=None)[source]#

Aggregate many devices in the list into a single device (non-annotated)

Parameters
  • devices (List[Device]) – List of devices.

  • name (Optional[str]) – Name of the new aggregated device.

Returns

The aggregated Device.

align(c=(0, 0))[source]#

Align center of pattern

Parameters

c (Union[Geometry, Device, Tuple[float, float]]) – A pattern (align to the pattern’s center) or a center point for alignment.

Return type

Device

Returns

Aligned pattern

property bbox: numpy.ndarray#

Returns: The linestring along the diagonal of the bbox

Return type

ndarray

property bbox_pattern: dphox.pattern.Box#

Returns: The linestring along the diagonal of the bbox

Return type

Box

property bounds: numpy.ndarray#

Bounding box of the form (minx, miny, maxx, maxy)

Return type

ndarray

Returns

Bounding box ndarray.

property center: Tuple[float, float]#

Center (x, y) for the device.

Return type

Tuple[float, float]

Returns

Center for the component.

clear(device)[source]#

Clear the device or its name from the children of this device. Do nothing if the device isn’t present.

Parameters

device (Union[str, Device]) – Child device to remove

Returns

This device.

property copy: dphox.device.Device#

Return a copy of this device for repeated use.

Return type

Device

Returns

A deep copy of this device.

property dummy_port_pattern: dphox.pattern.Box#

Returns: The linestring along the diagonal of the bbox

Return type

Box

classmethod from_gds(filepath, foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True))[source]#

Generate non-annotated device from GDS file based on the provided layer map in foundry.

Parameters
  • filepath (str) – The filepath to read the GDS device.

  • foundry (Foundry) – The foundry to get the device.

  • name – The name of the device (top cell) from the GDS file, if None return a dictionary

Return type

Dict[str, Device]

Returns

The non-annotated Device generated from reading a GDS file.

classmethod from_nazca_cell(cell)[source]#

Get the Device from a nazca cell (assumes nazca is installed).

Parameters

cell (nd.Cell) – Nazca cell to get Multilayer

Returns

The Device with the nazca cell.

classmethod from_pattern(pattern, name, layer)[source]#

A class method to convert a Pattern into a Device.

Note

The ports from pattern is “raised” to the pattern in ths device.

Parameters
  • pattern (Pattern) – The pattern that is being used to generate the device.

  • name (str) – Name for the component.

  • layer (str) – The layer for the pattern.

Returns

The Device containing the Pattern at the specified layer.

property full_layer_to_pattern#
property full_layer_to_polys#

Using breadth-first search of children, get all polygons in this device (useful for plotting purposes).

Returns

The full layer to polygon representation of this device hierarchy (call this on-demand).

gds_elements(foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), user_units_per_db_unit=0.001)[source]#

Use klamath to convert to GDS elements using a foundry object and user units.

Parameters
  • foundry (Foundry) – The foundry used for the layer map.

  • user_units_per_db_unit (float) – User units per unit (to convert from nm to um, need to use 0.001 to convert).

Returns

The klamath GDS elements for the device.

property gdspy_cell#

Turn this multilayer into a gdspy cell.

Parameters

cell (Foundry for creating the gdspy) –

Returns

A GDSPY cell.

halign(c=0, left=True, opposite=False)[source]#

Horizontal alignment of device

Parameters
  • c (Union[Geometry, Device, float]) – A device (horizontal align to the device’s boundary) or a center x for alignment.

  • left (bool) – (if c is pattern) Align to left boundary of component, otherwise right boundary.

  • opposite (bool) – (if c is pattern) Align opposite faces (left-right, right-left).

Return type

Device

Returns

Horizontally aligned device

property hash#
hvplot(foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), exclude_layer=None, alpha=0.5)[source]#

Plot this device on a holoviews plot.

Parameters
  • foundry (Foundry) – Foundry object for holoviews plotting.

  • exclude_layer (Optional[List[CommonLayer]]) – Exclude all layers in this list when plotting.

  • alpha (float) – The transparency factor for the plot (to see overlay of structures from many layers).

Returns

The holoviews Overlay for displaying all of the polygons.

property layer_to_pattern#
merge_patterns()[source]#
nazca_cell(foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True))[source]#

Turn this multilayer into a nazca cell (need to install nazca for this to work).

Parameters

cell (Foundry for creating the nazca) –

Return type

nd.Cell

Returns

A Nazca cell.

place(device, placement, from_port=None, flip_y=False, return_ports=False)[source]#

Place another device into this device at a specified placement (location and angle) or list of them.

Parameters
  • device (Device) – The child device to place.

  • placement (Union[GDSTransform, Tuple, ndarray, Port, List[Port]]) – The transform to apply OR the port to which the device should be connected. Note that the transform to apply can be the form of an xya (x, y, angle) tuple or a port.

  • from_port (Union[str, Port, tuple, None]) – The port name corresponding to child device’s port that should be connected according to placement. This effectively acts like a reference position/orientation for placement.

  • flip_y (bool) – Whether to flip the design vertically (to be applied to all GDS transforms, UNLESS placement is a GDS transform, in which case this arg is ignored)

  • return_ports (bool) – Return the ports of the placed device according to the format of placement.

Returns

The ports of the placed device, according to the specification of return_ports.

plot(ax=None, foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), exclude_layer=None, alpha=0.5, plot_ports=False)[source]#

Plot this device on a matplotlib plot.

Parameters
  • ax – Matplotlib axis handle to plot the device.

  • foundryFoundry object for matplotlib plotting.

  • exclude_layer – Exclude all layers in this list when plotting.

  • alpha – The transparency factor for the plot (to see overlay of structures from many layers).

Returns:

property port_copy#

The copy of ports in this device.

Note

Whenever using the ports of a given geometry in another geometry, it is highly recommended to extract port_copy, which creates fresh copies of the ports.

Returns

The port dictionary copy.

reflect(center=(0, 0), horiz=False)[source]#

Reflected the multilayer about center (vertical, or about x-axis, by default)

Parameters
  • center (Tuple[float, float]) – center about which to reflect.

  • horiz (bool) – reflect horizontally instead of vertically.

Return type

Device

Returns

Reflected pattern.

rotate(angle, origin=(0, 0))[source]#

Rotate the device by rotating all the patterns within it.

Parameters
  • angle (float) – rotation angle in degrees.

  • origin (Tuple[float, float]) – origin of rotation.

Return type

Device

Returns

The rotated device.

set_port(port)[source]#
property size: Tuple[float, float]#

Size of the pattern.

Return type

Tuple[float, float]

Returns

Tuple of the form (sizex, sizey).

smooth_layer(distance, layer)[source]#

Smooth a layer in the device (useful for sharp corners that may appear)

Parameters
  • distance (float) – Smooth the device by some distance.

  • layer (str) – Layer to smooth

Returns

Device with smoothed layer.

to(port, from_port=None)[source]#

Lego-connect this device’s from_port (origin if not specified) to another device’s port.

Parameters
  • port (Port) – The port to which the device should be connected.

  • from_port (Optional[str]) – The port name corresponding to this device’s port that should be connected to port.

Returns

This device, translated and rotated after connection.

to_gds(filepath, foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), user_units_per_db_unit=0.001, meters_per_db_unit=1e-09)[source]#

Use klamath to convert to GDS using a foundry object and a provided filepath.

Parameters
  • filepath (str) – The filepath to output the GDS.

  • foundry (Foundry) – The foundry used for the layer map.

  • user_units_per_db_unit (float) – User units per unit (to convert from nm to um, need to use 0.001 to convert).

  • meters_per_db_unit (float) – Meters per unit (usually nanometers, hence 1e-9).

Returns:

to_gds_stream(stream, foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), user_units_per_db_unit=0.001)[source]#

Use klamath to add device struct to GDS.

Parameters
  • stream (BinaryIO) – Stream for a GDS file.

  • foundry (Foundry) – The foundry used for the layer map.

  • user_units_per_db_unit (float) – User units per unit (to convert from nm to um, need to use 0.001 to convert).

Returns:

translate(dx=0, dy=0)[source]#

Translate the device by translating all of the patterns within it.

Parameters
  • dx (float) – translation in x.

  • dy (float) – translation in y.

Return type

Device

Returns

The translated device.

property tree#

Tree / hierarchical representation of the device.

Returns

A dictionary containing the tree representation of the device (ignoring transforms).

trimesh(foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), exclude_layer=None)[source]#

Fabricate this device based on a Foundry.

This method is fairly rudimentary and will not implement things like conformal deposition. At the moment, you can implement things like rib etches which can be determined using 2d shape operations. Depositions in layers above etched layers will just start from the maximum z extent of the previous layer. This is specified by the Foundry stack.

Parameters
  • foundry (Foundry) – The foundry for each layer which converts it into a trimesh

  • exclude_layer (Optional[List[CommonLayer]]) – Exclude all layers in this list.

Returns

The device Scene to visualize.

valign(c=0, bottom=True, opposite=False)[source]#

Vertical alignment of device.

Parameters
  • c (Union[Geometry, Device, float]) – A pattern (vertical align to the pattern’s boundary) or a center y for alignment.

  • bottom (bool) – (if c is pattern) Align to upper boundary of component, otherwise lower boundary.

  • opposite (bool) – (if c is pattern) Align opposite faces (upper-lower, lower-upper).

Return type

Device

Returns

Vertically aligned device

class dphox.device.Via(via_extent, boundary_grow, metal=(<CommonLayer.METAL_1: 'metal_1'>, <CommonLayer.METAL_2: 'metal_2'>), via=CommonLayer.VIA_1_2, pitch=0, shape=None, decimals=2, name='via')[source]#

Bases: dphox.device.Device

Via / metal multilayer stack (currently all params should be specified to 2 decimal places)

via_extent#

Dimensions of the via (or each via in via array).

Type

Tuple[float, float]

boundary_grow#

Boundary growth around the via or via array.

Type

Union[float, Tuple[float, float]]

metal#

Metal layer labels for the via (the thin metal layers).

Type

Union[str, List[str]]

via#

Via layer labels for the via (the actual tall vias).

Type

Union[str, List[str]]

pitch#

Pitch of the vias (center to center).

Type

float

shape#

Shape of the array (rows, cols).

Type

Optional[Tuple[int, int]]

name#

Name of the via.

Type

str

boundary_grow: Union[float, Tuple[float, float]]#
decimals: int = 2#
metal: Union[str, List[str]] = (<CommonLayer.METAL_1: 'metal_1'>, <CommonLayer.METAL_2: 'metal_2'>)#
name: str = 'via'#
pitch: float = 0#
shape: Optional[Tuple[int, int]] = None#
via: Union[str, List[str]] = 'via_1_2'#
via_extent: Tuple[float, float]#

dphox.foundry module#

class dphox.foundry.CommonLayer(value)[source]#

Bases: str, enum.Enum

Common layers used in foundries. These are just strings representing common layers, no other functionality,

RIDGE_SI#

Ridge silicon waveguide layer (waveguiding portion of the waveguide).

RIDGE_SI_2#

Another ridge silicon waveguide layer.

RIB_SI#

Rib silicon waveguide layer (slab portion of the waveguide).

RIB_SI_2#

Another rib silicon waveguide layer.

PDOPED_SI#

Lightly P-doped silicon (implants into the crystalline silicon layer).

NDOPED_SI#

Lightly N-doped silicon (implants into the crystalline silicon layer).

PPDOPED_SI#

Medium P-doped silicon (implants into the crystalline silicon layer).

NNDOPED_SI#

Medium N-doped silicon (implants into the crystalline silicon layer).

PPPDOPED_SI#

Highly P-doped silicon (implants into the crystalline silicon layer).

NNNDOPED_SI#

Highly N-doped silicon (implants into the crystalline silicon layer).

RIDGE_SIN#

Silicon nitride ridge layer (usually above silicon).

ALUMINA#

Alumina layer (for etch stop and waveguides, usually done in post-processing).

POLY_SI_1#

Polysilicon layer 1 (typically used in MEMS process).

POLY_SI_2#

Polysilicon layer 2 (typically used in MEMS process).

POLY_SI_3#

Polysilicon layer 3 (typically used in MEMS process).

VIA_SI_1#

Via metal connection from si to metal_1.

METAL_1#

Metal layer corresponding to an intermediate routing layer (1).

VIA_1_2#

Via metal connection from metal_1 to metal_2.

METAL_2#

Metal layer corresponding to an intermediate routing layer (2).

VIA_2_PAD#

Via metal connection from metal_2 to metal_pad.

METAL_PAD#

Metal layer corresponding to pads that can be wirebonded or solder-bump bonded from the chip surface.

HEATER#

Heater layer (usually titanium nitride).

VIA_HEATER_2#

Via metal connection from heater to metal_2.

CLAD#

Cladding layer (usually oxide).

CLEAROUT#

Clearout layer for a MEMS release process.

PHOTONIC_KEEPOUT#

A layer specifying where photonics cannot be routed.

METAL_KEEPOUT#

A layer specifying where metal cannot be routed.

BBOX#

Layer for the bounding box of the design.

PORT#

Default port layer (unless foundries specify port by layer)

ALUMINA = 'alumina'#
BBOX = 'bbox'#
BBOX_LABEL = 'bbox_label'#
BBOX_METAL = 'bbox_metal'#
BBOX_METAL_1 = 'bbox_metal_1'#
BBOX_METAL_2 = 'bbox_metal_2'#
BBOX_RIB_SI = 'bbox_rib_si'#
BBOX_SI = 'bbox_si'#
BBOX_SIN = 'bbox_sin'#
BBOX_SI_SIN = 'bbox_si_sin'#
CLAD = 'clad'#
CLEAROUT = 'clearout'#
GERMANIUM_ANODE = 'ge_anode'#
GERMANIUM_CATHODE = 'ge_cathode'#
GERMANIUM_OPEN = 'ge_open'#
HEATER = 'heater'#
METAL_1 = 'metal_1'#
METAL_2 = 'metal_2'#
METAL_KEEPOUT = 'metal_keepout'#
NNN_SI = 'nnndoped_si'#
NN_SI = 'nn_si'#
N_SI = 'n_si'#
OXIDE_OPEN = 'oxide_open'#
PAD = 'pad'#
PAD_OPEN = 'pad_open'#
PHOTONIC_KEEPOUT = 'photonic_keepout'#
POLY_SI_1 = 'poly_si_1'#
POLY_SI_2 = 'poly_si_2'#
POLY_SI_3 = 'poly_si_3'#
PORT = 'port'#
PPP_SI = 'pppdoped_si'#
PP_SI = 'pp_si'#
P_SI = 'p_si'#
RIB_SI = 'rib_si'#
RIB_SIN = 'rib_sin'#
RIB_SI_2 = 'rib_si_2'#
RIDGE_SI = 'ridge_si'#
RIDGE_SIN = 'ridge_sin'#
RIDGE_SIN_2 = 'ridge_sin_2'#
RIDGE_SI_2 = 'ridge_si_2'#
TRENCH = 'trench'#
VGROOVE = 'vgroove'#
VIA_1_2 = 'via_1_2'#
VIA_2_PAD = 'via_2_pad'#
VIA_HEATER_2 = 'via_heater_2'#
VIA_SI_1 = 'via_si_1'#
class dphox.foundry.Foundry(stack, height, cladding=None, port_layers=<factory>, use_port_boxes=True, use_port_layers=True)[source]#

Bases: object

The Foundry class defines the full stack of process steps.

For any step where the start_height si not specified, the Foundry class will assume a start height that is directly above the previously deposited layer. Note this does not support conformal deposition as this assumes all layers below are planarized.

stack#

List of process steps that when applied sequentially lead to a full foundry stack

Type

List[dphox.foundry.ProcessStep]

height#

Overall height of the foundry stack.

Type

float

cladding#

The cladding material used by the foundry (usually OXIDE). This material will more-or-less cover the entire

Type

dphox.foundry.Material

port_layers#

A list of common layers for extracting the appropriate ports.

Type

List[dphox.foundry.CommonLayer]

use_port_boxes#

Whether the foundry uses boxes to indicate port widths (useful for loading PDKs).

Type

bool

cladding: dphox.foundry.Material = None#
color(layer)[source]#
fabricate(layer_to_geom, exclude_layer=None)[source]#

Fabricate a device based on a layer-to-geometry dict, Foundry, and initial device (type Scene).

This method is fairly rudimentary and will not implement things like conformal deposition. At the moment, you can implement things like rib etches which can be determined using 2d shape operations. Depositions in layers above etched layers will just start from the maximum z extent of the previous layer. This is specified by the Foundry stack.

Note

Custom fabricate methods may be built if this foundry class is extended. However, the same template is recommended.

Parameters
  • layer_to_geom (Dict[str, MultiPolygon]) – A dictionary mapping each layer to the full Shapely geometry for that layer.

  • exclude_layer (Optional[List[CommonLayer]]) – Exclude all layers in this list.

Returns

The device Scene to visualize.

property gds_label_to_layer#
height: float#
property layer_to_gds_label#
port_layers: List[dphox.foundry.CommonLayer]#
stack: List[dphox.foundry.ProcessStep]#
use_port_boxes: bool = True#
use_port_layers: bool = True#
class dphox.foundry.Material(name, eps=1, color=(0, 0, 0), alpha=1)[source]#

Bases: object

Helper class for materials.

name#

Name of the material.

Type

str

eps#

Constant epsilon (relative permittivity) assigned for the material.

Type

float

facecolor#

Facecolor in red-green-blue (RGB) for drawings (default is black or (0, 0, 0)).

alpha#

transparency of the material for visualization

Type

float

alpha: float = 1#
color: Tuple[float, float, float] = (0, 0, 0)#
eps: float = 1#
property n#
name: str#
class dphox.foundry.ProcessOp(value)[source]#

Bases: str, enum.Enum

Enumeration for process operations which describe what happens at each step in a foundry process.

ISO_ETCH#

isotropic etch under a pattern stencil (not yet supported)

DRI_ETCH#

directed-reactive ion etch (simply etch downward under a pattern stencil)

SAC_ETCH#

sacrificial etch (only affects cladding material in a process)

GROW#

grow over the previously deposited layer

DOPE#

dopes the previously deposited layer

DUMMY#

No process step associated with this

DOPE = 'dope'#
DRI_ETCH = 'dri_etch'#
DUMMY = 'dummy'#
GROW = 'grow'#
ISO_ETCH = 'iso_etch'#
SAC_ETCH = 'sac_etch'#
class dphox.foundry.ProcessStep(process_op, thickness, mat, layer, gds_label, start_height=None, inverse=False)[source]#

Bases: object

The ProcessStep class is an object that stores all the information about a layer in a foundry process.

process_op#

Process operation, specified in the enum for ProcessOp

Type

dphox.foundry.ProcessOp

thickness#

The thickness spec for the process step.

Type

float

mat#

Material (relevant to the non-etch ProcessOp.grow and ProcessOp.dope process ops)

Type

dphox.foundry.Material

layer#

The device layer corresponding to the process step (should NOT vary by foundry, use CommonLayer interface unless layers are hyper-specific).

Type

str

gds_label#

The GDS label used for GDS file creation of the device (SHOULD vary by foundry).

Type

Union[int, str, Tuple[int, int]]

start_height#

The starting height for the process step.

Type

Optional[float]

inverse#

Whether to assign this process step as an inverse (data clear) mask

Type

bool

gds_label: Union[int, str, Tuple[int, int]]#
inverse: bool = False#
layer: str#
mat: dphox.foundry.Material#
process_op: dphox.foundry.ProcessOp#
start_height: Optional[float] = None#
thickness: float#

dphox.geometry module#

class dphox.geometry.Geometry(geoms, port, refs, tangents=None)[source]#

Bases: object

align(geom_or_center=(0, 0), other=None)[source]#

Align center of geom

Parameters
  • geom_or_center (Union[Geometry, Tuple[float, float]]) – A geom (align to the geom’s center) or a center point for alignment.

  • other (Union[Geometry, Tuple[float, float], None]) – If specified, instead of aligning based on this geom’s center, align based on another geom’s center and translate accordingly.

Return type

Geometry

Returns

Aligned geom

property bbox#

Opposing diagonal corners of the bounding box (bbox).

Returns

A numpy array of bottom left and top right corners of bounding box (bbox).

property bounds: Tuple[float, float, float, float]#

Bounds of the geom.

Return type

Tuple[float, float, float, float]

Returns

Tuple of the form (minx, miny, maxx, maxy)

property center: Tuple[float, float]#

Center of the geom.

Return type

Tuple[float, float]

Returns

Center for the component.

property copy: dphox.geometry.Geometry#

Copies the pattern using deepcopy.

Return type

Geometry

Returns

A copy of the Pattern so that changes do not propagate to the original Pattern.

flip_ends(front_port='b0', back_port='a0')[source]#
halign(c, left=True, opposite=False)[source]#

Horizontal alignment of geom

Parameters
  • c (Union[Geometry, float]) – A geom (horizontal align to the geom’s boundary) or a center x for alignment

  • left (bool) – (if c is geom) Align to left boundary of component, otherwise right boundary

  • opposite (bool) – (if c is geom) Align opposite faces (left-right, right-left)

Return type

Geometry

Returns

Horizontally aligned geom

hstack(other_geom, left=False)[source]#
Return type

Geometry

property num_geoms: int#
Return type

int

property num_points: int#
Return type

int

property points: numpy.ndarray#
Return type

ndarray

property port_copy#

The copy of ports in this device.

Note

Whenever using the ports of a given geometry in another geometry, it is highly recommended to extract port_copy, which creates fresh copies of the ports.

Returns

The port dictionary copy.

reflect(center=(0, 0), horiz=False)[source]#

Reflect the component across a center point (default (0, 0))

Parameters
  • center (Tuple[float, float]) – The center point about which to flip

  • horiz (bool) – do horizontal flip, otherwise vertical flip

Return type

Geometry

Returns

Flipped geom

reverse()[source]#

Reverse the geometry and the direction of the tangents along the path.

Return type

Geometry

Returns

The reversed geometry.

rotate(angle, origin=(0, 0))[source]#

Rotate the geometry about origin.

Parameters
  • angle (float) – rotation angle in degrees.

  • origin (Union[Tuple[float, float], ndarray]) – origin of rotation.

Return type

Geometry

Returns

Rotated geom by angle about origin

scale(xfact=1, yfact=None, origin=None)[source]#

Affine scale operation on the geometry about origin.

Parameters
  • xfact (float) – x scale factor.

  • yfact (Optional[float]) – y scale factor (same as x scale factor if not specified).

  • origin (Optional[Tuple[float, float]]) – origin of rotation (uses center of geom if None).

Return type

Geometry

Returns

Rotated geom by angle about origin

set_port(port)[source]#
property shapely#
property size: Tuple[float, float]#

Size of the geom.

Return type

Tuple[float, float]

Returns

Tuple of the form (sizex, sizey).

skew(xs=0, ys=0, origin=None)[source]#

Affine skew operation on the geometry about origin.

Parameters
  • xs (float) – x skew factor.

  • ys (float) – y skew factor.

  • origin (Optional[Tuple[float, float]]) – origin of rotation (uses center of geom if None).

Return type

Geometry

Returns

Rotated geom by angle about origin

symmetrized(front_port='b0')[source]#

Symmetrize this curve across a mirror plane decided by one of the curves in the curve set.

Parameters
  • front_port (str) – Front port label.

  • back_port – Back port label.

Return type

Geometry

Returns

The symmetrized curve

to(port=(0, 0), from_port=None)[source]#
transform(transform)[source]#
translate(dx=0, dy=0)[source]#

Translate patter

Parameters
  • dx (float) – Displacement in x

  • dy (float) – Displacement in y

Return type

Geometry

Returns

The translated geom

valign(c, bottom=True, opposite=False)[source]#

Vertical alignment of geom

Parameters
  • c (Union[Geometry, float]) – A geom (vertical align to the geom’s boundary) or a center y for alignment

  • bottom (bool) – (if c is geom) Align to upper boundary of component, otherwise lower boundary

  • opposite (bool) – (if c is geom) Align opposite faces (upper-lower, lower-upper)

Return type

Geometry

Returns

Vertically aligned geom

vstack(other_geom, bottom=False)[source]#
Return type

Geometry

dphox.path module#

class dphox.path.Curve(*curves)[source]#

Bases: dphox.geometry.Geometry

A discrete curve consisting of points and tangents that used to define paths of varying widths.

Note

In our definition of curve, we allow for multiple curve segments that are unconnected to each other.

curve#

A function \(f(t) = (x(t), y(t))\), given \(t \in [0, 1]\), or a length (float), or a list of points, or a tuple of points and tangents.

resolution#

Number of evaluations to define \(f(t)\) (number of points in the curve).

angles(path=True)[source]#

Calculate the angles for the tangents along the curve.

Parameters

path (bool) – Whether to report the angles for the full coalesced curve.

Returns

The angles of the tangents along the curve.

coalesce()[source]#

Coalesce path segments into a single path

Note

Caution: This assumes a C1 path, so paths with discontinuities will have incorrect tangents.

Returns

The coalesced Curve.

property copy: dphox.path.Curve#

Copies the pattern using deepcopy.

Return type

Curve

Returns

A copy of the Pattern so that changes do not propagate to the original Pattern.

curvature(path=True, min_frac=0.001)[source]#

Calculate the curvature vs length along the curve.

Parameters
  • path (bool) – Whether to report the curvature vs length for the full coalesced curve.

  • min_frac (float) – The minimum

Returns

A tuple of the lengths and curvature along the length.

hvplot(line_width=2, color='black', bounds=None, alternate_color=None, plot_ports=True)[source]#

Plot this device on a matplotlib plot.

Parameters
  • line_width (float) – The width of the line for plotting.

  • color (str) – The color for plotting the pattern.

  • alternate_color (Optional[str]) – Plot segments of the curve alternating color and :code`alternate_color`.

  • bounds (Optional[Tuple[float, float, float, float]]) – Bounds of the plot.

  • plot_ports (bool) – Plot the ports of the curve.

Returns

The holoviews Overlay for displaying all of the polygons.

property interpolated#

Interpolated curve such that all segments have equal length.

Returns

The interpolated path.

lengths(path=True)[source]#

Calculate the lengths of each line segment of the curve.

Parameters

path (bool) – Whether to report the lengths of the segments for the full coalesced curve.

Returns

The lengths for the individual line segments of the curve.

property normals#

Calculate the normals (perpendicular to the tangents) along the curve.

Returns

The normals for the curve.

path(width=1, offset=0, decimals=6)[source]#

Path (pattern) converted from this curve using width and offset specifications.

Parameters
  • width (Union[float, Iterable[Union[Callable, float, Tuple[float, ...], ndarray]]]) – Width of the path. If a list of callables, apply a parametric width to each curve segment.

  • offset (Union[float, Iterable[Union[Callable, float, Tuple[float, ...], ndarray]]]) – Offset of the path. If a list of callables, apply a parametric offset to each curve segment.

  • decimals (int) – Decimal precision of the path.

Return type

Pattern

Returns

A pattern representing the path.

path_port(w=1)[source]#

Get the port and orientations from the normals of the curve assuming it is a piecewise path.

Note

This function will not make sense if there are multiple unconnected curves. This is generally reserved for path-related operations. Unexpected behavior will occur if this method is used for arbitrary curve sets.

Parameters

w (float) – width of the port.

Returns

The ports for the curve.

property pathlength#
property pattern#
property segments#
property shapely#

Shapely geometry

Returns

The multiline string for the geometries.

total_length(path=True)[source]#

Calculate the total length at the end of each line segment of the curve.

Parameters

path (bool) – Whether to report the lengths of the segments for the full coalesced curve.

Returns

The lengths for the individual line segments of the curve.

dphox.path.curve_to_path(points, widths, tangents, offset=0, decimals=6, max_num_points=8096)[source]#

Converts a curve to a path.

Parameters
  • points (ndarray) – The points along the curve.

  • tangents (ndarray) – The normal directions / derivatives evaluated at the points along the curve.

  • widths (Union[float, ndarray]) – The widths at each point along the curve (measured perpendicular to the tangents).

  • offset (Union[float, ndarray]) – Offset of the path.

  • decimals (int) – Number of decimals precision for the curve output.

  • max_num_points (int) – Maximum number of points allowed in the curve (otherwise, break it apart). Note that the polygon will have twice this amount.

Returns

The resulting Pattern.

dphox.path.get_ndarray_curve(curvelike_list)[source]#

A recursive list of lists of curvelike objects, which turned into a flat list of 2d ndarray polygons.

Parameters

curvelike_list (Iterable[Union[float, Curve, LineString, ndarray, CurveTuple, List[Union[LineString, ndarray, CurveTuple]]]]) – List of polygon-like objects including CurveSet, shapely linestrings, CurveTuple (tuple of points and tangents), and more.

Returns

A list of \(M\) polygons that are each represented as \(2 \times N_m\) ndarray’s.

Link many separate curves or paths into a single geometry, assuming each geometry has a front and back port.

Note

This is a simple linking function that simply uses the type of the first item in the list to attach either a set of paths or a set of curves to each other.

Parameters
  • geoms (Union[Pattern, Curve, float]) – The paths to link, assuming the curve is the first ref in each path.

  • front_port (str) – Front port name.

  • back_port (str) – Back port name.

Returns

The resulting geometry (path or curve) after linking many curves together into a single one.

dphox.path.straight(length)[source]#

Just a straight line along the x axis, generally this only needs 2 evaluations unless there is a taper.

Parameters

length (float) – Length of the straight line.

Returns

A straight segment.

dphox.pattern module#

class dphox.pattern.Box(extent=(1, 1), decimals=6)[source]#

Bases: dphox.pattern.Pattern

Box with default center at origin

extent#

Dimension (box width, box height)

Type

Tuple[float, float]

decimals#

The decimal places to resolve the box.

Type

int

cup(thickness)[source]#

Return a cup-shaped (U-shaped) within the confines of the box extent.

Parameters

thickness (float) – thickness of the border.

Return type

Pattern

Returns

A cup-shaped block of thickness thickness.

decimals: int = 6#
ell(thickness)[source]#

Return an ell-shaped (L-shaped) pattern within the confines of the box extent.

Parameters

thickness (float) – thickness of the border.

Return type

Pattern

Returns

An L-shaped block of thickness thickness.

expand(grow)[source]#

An aligned box that grows by amount grow

Parameters

grow (float) – The amount to grow the box

Return type

Box

Returns

The box after the grow transformation

extent: Tuple[float, float] = (1, 1)#
flexure(spring_extent, connector_extent=None, stripe_w=1, symmetric=True, spring_center=False)[source]#

A crab-leg flexure (useful for MEMS actuation).

Parameters
  • spring_extent (Tuple[float, float]) – Spring extent (x, y).

  • connector_extent (Optional[Tuple[float, float]]) – Connector extent (x, y).

  • stripe_w (float) – Stripe width (useful for etch holes, calls the striped method).

  • symmetric (bool) – Whether to specify a symmetric connector.

Return type

Pattern

Returns

The flexure Pattern

hollow(thickness)[source]#

A hollow box of thickness thickness on all four sides within the confines of the box extent.

Parameters

thickness (float) – thickness of the box.

Return type

Pattern

Returns

A box of specified thickness with no filling inside.

striped(stripe_w, pitch=None, along_x=True, along_y=True, include_boundary=True)[source]#

A stripe hatch pattern in the confines of the box, useful for etching and arrays of square holes.

Parameters
  • stripe_w (float) – Stripe width (useful for etch holes).

  • pitch (Optional[Tuple[float, float]]) – Pitch of the stripes

  • along_x (bool) – Stripes / grating along x

  • along_y (bool) – Stripes / grating along y

Return type

Pattern

Returns

The striped Pattern

class dphox.pattern.Circle(radius=1, resolution=16)[source]#

Bases: dphox.pattern.Pattern

Ellipse with default center at origin.

diameter#

diameter of the circle.

resolution#

Resolution is (number of points on circle) / 2.

Type

int

radius: float = 1#
resolution: int = 16#
class dphox.pattern.Ellipse(radius_extent=(1, 1), resolution=16)[source]#

Bases: dphox.pattern.Pattern

Ellipse with default center at origin.

radius_extent#

Dimension (ellipse x radius, ellipse y radius).

Type

Tuple[float, float]

resolution#

Resolution is (number of points on circle) / 2.

Type

int

radius_extent: Tuple[float, float] = (1, 1)#
resolution: int = 16#
class dphox.pattern.MEMSFlexure(extent, stripe_w, pitch, spring_extent, connector_extent=None, spring_center=False)[source]#

Bases: dphox.pattern.Pattern

connector_extent: Tuple[float, float] = None#
extent: Tuple[float, float]#
pitch: Union[float, Tuple[float, float]]#
spring_center: bool = False#
spring_extent: Tuple[float, float]#
stripe_w: float#
class dphox.pattern.Pattern(*patterns, decimals=6)[source]#

Bases: dphox.geometry.Geometry

Pattern corresponding to a patterned layer of material that may be used in a layout.

A Pattern is a core object in DPhox, which enables composition of multiple polygons or patterns into a single Pattern. It allows for composition of a myriad of different objects such as GDSPY Polygons and Shapely polygons into a single pattern. Since Pattern is a simple wrapper around Shapely’s MultiPolygon, this class interfaces easily with other libraries such as Trimesh and simulators codes such as MEEP and simphox for simulating the generated designs straightforwardly.

polygons#

the numpy array representation for the polygons in this pattern.

decimals#

decimal places for rounding (in case of tiny errors in polygons)

property bbox_pattern: dphox.pattern.Box#

Returns: The linestring along the diagonal of the bbox

Return type

Box

buffer(distance, join_style=1, cap_style=3)[source]#
Return type

Pattern

property copy: dphox.pattern.Pattern#

Copies the pattern using deepcopy.

Return type

Pattern

Returns

A copy of the Pattern so that changes do not propagate to the original Pattern.

difference(other_pattern)[source]#

Difference between this pattern and provided pattern.

Apply an difference operation provided by Shapely’s interface. Note the distinction between difference and symmetric_difference.

Parameters

other_pattern (Pattern) – Other pattern

Return type

Pattern

Returns

The new differenced pattern

hvplot(color='black', name='pattern', alpha=0.5, bounds=None, plot_ports=True)[source]#

Plot this device on a matplotlib plot.

Parameters
  • color (str) – The color for plotting the pattern.

  • name (str) – Name of the pattern / label of the plot.

  • alpha (float) – The transparency factor for the plot (to see overlay of structures from many layers).

  • plot_ports (bool) – Plot the ports (triangle indicators and text labels).

Returns

The holoviews Overlay for displaying all of the polygons.

intersection(other_pattern)[source]#

Intersection between this pattern and provided pattern.

Apply an intersection operation provided by Shapely’s interface.

Parameters

other_pattern (Pattern) – Other pattern

Return type

Pattern

Returns

The new intersected pattern

mask(shape, spacing, smooth_feature=0)[source]#

Pixelized mask used for simulating this component

Parameters
  • shape (Union[Tuple[int, int], Tuple[int, int, int]]) – Shape of the mask

  • spacing (Union[float, Tuple[float, float, float]]) – The grid spacing resolution to use for the pixelated mask

  • smooth_feature (float) – The shapely smooth feature factor, which erodes, dilates twice, then erodes the geometry by smooth_feature units.

Return type

ndarray

Returns

An array of indicators of whether a volumetric image contains the mask

nazca_cell(cell_name, layer)[source]#
plot(ax=None, color='gray', plot_ports=True, alpha=1)[source]#

Plot the pattern

Parameters
  • ax – Axis for plotting (if none, use the default matplotlib plot axis

  • color – Color of the pattern

  • plot_ports – Whether to plot the ports.

  • alpha – the alpha property for plotting.

Returns:

replace(pattern, center=None, raise_port=True)[source]#

Replace the polygons in some part of the image with pattern.

This is a useful property for inverse design. Note that the entire bounding box of the pattern is replaced by pattern which may not always be desirable, but we estimate this is sufficient for most inverse design use cases.

Parameters
  • pattern (Pattern) – The pattern which replaces this pattern.

  • center (Optional[Tuple[float, float]]) – The center where to replace the pattern.

  • raise_port (bool) – Whether to raise the port of this current pattern and add those ports to the new pattern.

Returns

The new pattern with pattern replacing the appropriate region of the image.

property shapely: shapely.geometry.multipolygon.MultiPolygon#
Return type

MultiPolygon

property shapely_union: shapely.geometry.multipolygon.MultiPolygon#
Return type

MultiPolygon

smooth(distance, min_area=None, join_style=1, cap_style=3)[source]#
Return type

Pattern

symmetric_difference(other_pattern)[source]#

Union between this pattern and provided pattern.

Apply a symmetric difference operation provided by Shapely’s interface.

Parameters

other_pattern (Pattern) – Other pattern

Return type

Pattern

Returns

The new symmetric difference pattern

to_gdspy(cell)[source]#

Add to an existing GDSPY cell.

Parameters

cell – GDSPY cell to add polygon

Returns

The GDSPY cell corresponding to the Pattern

trimesh(foundry=Foundry(stack=[ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIDGE_SI: 'ridge_si'>, gds_label=(100, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='p_si', eps=1, color=(0, 0.3, 0.4), alpha=0.3), layer=<CommonLayer.P_SI: 'p_si'>, gds_label=(400, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='n_si', eps=1, color=(0.4, 0.3, 0), alpha=0.3), layer=<CommonLayer.N_SI: 'n_si'>, gds_label=(401, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='pp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.5), layer=<CommonLayer.PP_SI: 'pp_si'>, gds_label=(402, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.5), layer=<CommonLayer.NN_SI: 'nn_si'>, gds_label=(403, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='ppp_si', eps=1, color=(0, 0.3, 0.4), alpha=0.7), layer=<CommonLayer.PPP_SI: 'pppdoped_si'>, gds_label=(404, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.DOPE: 'dope'>, thickness=0.1, mat=Material(name='nnn_si', eps=1, color=(0.4, 0.3, 0), alpha=0.7), layer=<CommonLayer.NNN_SI: 'nnndoped_si'>, gds_label=(405, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='si', eps=12.09926656, color=(0.3, 0.3, 0.3), alpha=1), layer=<CommonLayer.RIB_SI: 'rib_si'>, gds_label=(101, 0), start_height=2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='si3n4', eps=3.984016, color=(0, 0, 0.7), alpha=1), layer=<CommonLayer.RIDGE_SIN: 'ridge_sin'>, gds_label=(300, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.1, mat=Material(name='al2o3', eps=1.75, color=(0.2, 0, 0.2), alpha=1), layer=<CommonLayer.ALUMINA: 'alumina'>, gds_label=(200, 0), start_height=2.5, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=1, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_SI_1: 'via_si_1'>, gds_label=(500, 0), start_height=2.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_1: 'metal_1'>, gds_label=(501, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_1_2: 'via_1_2'>, gds_label=(502, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.METAL_2: 'metal_2'>, gds_label=(503, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.VIA_2_PAD: 'via_2_pad'>, gds_label=(504, 0), start_height=4.1000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.3, mat=Material(name='al', eps=1, color=(0, 0.5, 0), alpha=1), layer=<CommonLayer.PAD: 'pad'>, gds_label=(600, 0), start_height=4.6000000000000005, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.2, mat=Material(name='tin', eps=1, color=(0.8, 0.8, 0), alpha=1), layer=<CommonLayer.HEATER: 'heater'>, gds_label=(700, 0), start_height=3.2, inverse=False), ProcessStep(process_op=<ProcessOp.GROW: 'grow'>, thickness=0.5, mat=Material(name='cu', eps=1, color=(1, 0.6, 0), alpha=1), layer=<CommonLayer.VIA_HEATER_2: 'via_heater_2'>, gds_label=(505, 0), start_height=3.4000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.SAC_ETCH: 'sac_etch'>, thickness=4, mat=Material(name='etch', eps=1, color=(0, 0, 0), alpha=1), layer=<CommonLayer.CLEAROUT: 'clearout'>, gds_label=(800, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.TRENCH: 'trench'>, gds_label=(41, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.PHOTONIC_KEEPOUT: 'photonic_keepout'>, gds_label=(42, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.METAL_KEEPOUT: 'metal_keepout'>, gds_label=(43, 0), start_height=3.9000000000000004, inverse=False), ProcessStep(process_op=<ProcessOp.DUMMY: 'dummy'>, thickness=4, mat=Material(name='dummy', eps=1, color=(0.7, 0.7, 0.7), alpha=1), layer=<CommonLayer.BBOX: 'bbox'>, gds_label=(44, 0), start_height=3.9000000000000004, inverse=False)], height=5, cladding=None, port_layers=[], use_port_boxes=True, use_port_layers=True), layer=CommonLayer.RIDGE_SI)[source]#

Fabricate this pattern based on a Foundry.

This method is fairly rudimentary and will not implement things like conformal deposition. At the moment, you can implement things like rib etches which can be determined using 2d shape operations. Depositions in layers above etched layers will just start from the maximum z extent of the previous layer. This is specified by the Foundry stack.

Parameters
  • foundry (Union[str, Foundry]) – The foundry for each layer.

  • layer (CommonLayer) – The layer for this pattern.

Returns

The device Scene to visualize.

union(other_pattern)[source]#

Union between this pattern and provided pattern.

Apply an union operation provided by Shapely’s interface.

Parameters

other_pattern (Pattern) – Other pattern

Return type

Pattern

Returns

The new union pattern

class dphox.pattern.Quad(start, end)[source]#

Bases: dphox.pattern.Pattern

end: dphox.port.Port#
start: dphox.port.Port#
class dphox.pattern.Sector(radius=1, angle=180, resolution=16)[source]#

Bases: dphox.pattern.Pattern

Sector of a circle with center at origin.

radius#

radius of the circle boundary of the sector.

Type

float

angle#

angle of the sector.

Type

float

resolution#

Resolution is (number of points on circle) / 2.

Type

int

angle: float = 180#
radius: float = 1#
resolution: int = 16#
class dphox.pattern.StripedBox(extent, stripe_w, pitch)[source]#

Bases: dphox.pattern.Pattern

extent: Tuple[float, float]#
pitch: Union[float, Tuple[float, float]]#
stripe_w: float#
dphox.pattern.get_ndarray_polygons(polylike_list, decimals=6)[source]#

A recursive list of lists of polylike objects, which turned into a flat list of 2d ndarray polygons.

Parameters
  • polylike_list (Iterable[Union[Pattern, Polygon, MultiPolygon, ndarray, List[Union[Polygon, MultiPolygon, ndarray, Pattern]]]]) – List of polygon-like objects including Pattern, shapely geometry collections, GDSPY geometries, and more.

  • decimals (int) – decimal precision of the resulting polygons

Returns

A list of \(M\) polygons that are each represented as \(2 \times N_m\) ndarray’s.

dphox.pattern.text(string, size=12)[source]#

A simple function to generate text pattern from a string.

Parameters
  • string (str) – The string to turn into a pattern

  • size (float) – The fontsize size of the string.

Returns

The text Pattern.

dphox.port module#

class dphox.port.Port(x=0, y=0, a=0, w=1, z=0, h=0, layer=CommonLayer.PORT)[source]#

Bases: object

Port used in components in DPhox

A port defines the center, width and angle/orientation of a port in a design. Note that ports always are considered to have a width, and if a width is not provided the width is assumed to be 1 in the units of the file.

x#

x position of the port.

Type

float

y#

y position of the port.

Type

float

w#

width of the port

Type

float

a#

Angle (orientation) of the port (in degrees).

Type

float

z#

z position of the port (optional, not specified in design, mostly used for simulation).

Type

float

h#

the height / thickness of the port (optional, not specified in design, mostly used for simulation).

Type

float

a: float = 0#
property copy: dphox.port.Port#

Return a copy of this port for repeated use.

Return type

Port

Returns

A deep copy of this port.

flip()[source]#
classmethod from_points(points, z=0, h=0, decimals=6)[source]#

Initialize a Port using a LineString in Shapely.

The port can be unambiguously defined using a tangent whose port faces 90 degrees counterclockwise (normal/perpendicular direction) from that tangent. The width of the port is the magnitude of the vector and the location of the port is the centroid of the vector.

Parameters
  • points (ndarray) – Points representing the vector.

  • z (float) – The z position of the port.

  • h (float) – The height / thickness of the port.

  • decimals (float) – decimal precision for the points

Return type

Port

Returns

The Port represented by the shapely Polygon triangle.

h: float = 0#
hvplot(name='port')[source]#
layer: str = 'port'#
property line#
normal(scale=1)[source]#

The normal vector perpendicular to the direction of the port (e.g. useful for turns)

Parameters

scale (float) – The magnitude of the normal vector

Returns

Return the vector normal to the port

orient_xyaf(xyaf, flip_y=False)[source]#

Orient xyaf (x, y , angle, flip) based on this port.

Note

The orientation is only modified if the port specified is not the default port.

Parameters
  • xyaf (ndarray) – The x, y, angle, and flip objects.

  • flip_y (bool) – If only xya is provided, specify the flip.

Returns

The new xyaf after orienting based on this port.

rotate(angle, origin=(0, 0))[source]#

Rotate the geometry about origin.

Parameters
  • angle (float) – Angle of rotation in degrees

  • origin (Tuple[float, float]) – Rotation origin

Return type

Port

Returns

The rotated port

property shapely: shapely.geometry.polygon.Polygon#

Return the Polygon triangle corresponding to the Port.

Based on center and orientation of the Port, return the corresponding Shapely triangle. This is effectively the inverse of the from_shapely classmethod of this class.

Return type

Polygon

Returns

The shapely Polygon triangle represented by the Port.

property size#

Get the size of the Port for simulation-related applications.

Returns

The size of the Port in 3D space, i.e., (x, y, z).

tangent(scale=1)[source]#

The vector tangent (parallel) to the direction of the port

Parameters

scale (float) – The magnitude of the normal vector

Returns

Return the vector normal to the port

transform(transform, decimals=6)[source]#

Transform.

Parameters
  • transform (ndarray) – affine transform tensor whose final two dimensions transform the port

  • decimals (float) – decimal precision for port x, y after the rotation.

Returns:

transform_xyaf(xyaf)[source]#

Transform

Parameters

xyaf (Tuple[float, float, float, bool]) – The x, y, angle, and flip objects.

Returns:

transformed_line(transform)[source]#
translate(dx=0, dy=0)[source]#

Translate port.

Parameters
  • dx (float) – Displacement in x

  • dy (float) – Displacement in y

Return type

Port

Returns

The translated port

w: float = 1#
x: float = 0#
y: float = 0#
z: float = 0#

dphox.prefab module#

dphox.route module#

dphox.route.loopify(curve, radius, euler=0, resolution=99)[source]#

Automatically create a loop by connecting the ends of a curve

Note

This only works in some cases, as there are no self-intersection checks.

Parameters
  • curve (Curve) – Curve to loopify.

  • radius (float) – Radius of the turns.

  • euler (float) – Euler parameter for the turn.

  • resolution (int) – Number of evaluations for the curves in the loop.

Returns

The loopified curve.

dphox.route.manhattan_route(start, lengths, include_width=True)[source]#

Manhattan route (intended for metal routing).

Starting with horizontal and switching back and forth with vertical, make alternating turns. A positive length indicates moving in a +x or +y direction, whereas a negative length indicates moving in a -x or -y direction.

Parameters
  • start (Port) – Start port for the route.

  • lengths (ndarray) – List of dx and dy segments (alternating left and right turns).

  • include_width (bool) – Include width returns a path instead of a curve.

Returns

The manhattan route path.

dphox.route.spiral_delay(n_turns, min_radius, separation, resolution=1000, turn_resolution=99, include_straightening_bend=True)[source]#

Spiral delay (large waveguide delay in minimal area).

Parameters
  • n_turns (int) – Number of turns in the spiral

  • min_radius (float) – Minimum radius of the spiral (affects the inner part of the design)

  • separation (float) – Separation of waveguides in the spiral.

  • resolution (int) – Number of evaluations for the spiral.

  • turn_resolution (int) – Number of evaluations for the turns.

  • include_straightening_bend (bool) – Include input and output bends to straighten spiral delay along a line

Returns

The spiral delay waveguide.

dphox.route.turn_connect(start, end, radius, radius_end=None, euler=0, resolution=99, include_width=True)[source]#

Turn connect.

Parameters
  • start (Port) – Start port

  • end (Port) – End port

  • radius (float) – Start turn effective radius

  • radius_end (Optional[float]) – End turn effective radius (use radius if None)

  • euler (float) – Euler path contribution (see turn method).

  • resolution (int) – Number of evaluations for the turns.

  • include_width (bool) – Whether to include the width (cubic taper) of the turn connect

Return type

Union[Pattern, Curve]

Returns

A path connecting the start and end port using a turn-straight-turn approach

dphox.transform module#

class dphox.transform.AffineTransform(transform)[source]#

Bases: object

Affine transformer.

An affine transform

transform#

The …x3x3 transform or list of sequential 3x3 transforms that are multiplied together.

property ndim#
transform_geoms(geoms, tangents=False, decimals=6)[source]#
transform_points(points, tangents_only=False, decimals=6)[source]#

Transform a list of points (or tangents).

This method runs the transformation \(AP\), where \(A \in M \times 2 \times 3\) and \(P \in 3 \times N\), where a list of ones is concatenated in the final dimension.

In the case we need to transform tangents, the third dimension is irrelevant since translations do not change the tangent and normal vectors. So now we have \(A \in M \times 2 \times 2\) and \(P \in 2 \times N\) where now we don’t concatenate any 1’s for the transformation.

Parameters
  • points (ndarray) – The 2xN array of points to be transformed.

  • tangents_only (bool) – Ignore the third dimension of the transform (for tangents).

  • decimals (int) – The number of decimal places of precision for the transform.

Returns

The 2xN transformed points

class dphox.transform.GDSTransform(x=0, y=0, angle=0, flip_y=False, mag=1)[source]#

Bases: dphox.transform.AffineTransform

GDS transform class

x#

x translation

Type

float

y#

y translation

Type

float

angle#

rotation angle

Type

float

flip_y#

Whether to flip the design about the x-axis (in y direction)

Type

bool

mag#

scale magnification

Type

float

angle: float = 0#
flip_y: bool = False#
mag: float = 1#
classmethod parse(transform, existing_transform=None)[source]#

Turns representations like (x, y, angle) or a numpy array into convenient GDS/affine transforms.

Parameters
  • transform (Union[GDSTransform, Tuple, ndarray, None]) – The transform array in the order (x, y, angle, mag) or just a GDS transform.

  • existing_transform (Optional[Tuple[AffineTransform, List[GDSTransform]]]) – Given an existing transform(s), apply the new transform on top of the existing one.

Return type

Tuple[AffineTransform, List[GDSTransform]]

Returns

A tuple of AffineTransform representation and a list of GDS transforms for gds output.

set_xya(xya)[source]#
set_xyaf(xyaf)[source]#
x: float = 0#
property xya#
property xyaf#
y: float = 0#
dphox.transform.reflect2d(origin=(0, 0), horiz=False, flip=True)[source]#
dphox.transform.rotate2d(angle, origin=(0, 0))[source]#
dphox.transform.scale2d(scale=(0, 0), origin=(0, 0))[source]#
dphox.transform.skew2d(skew=(0, 0), origin=(0, 0))[source]#
dphox.transform.translate2d(shift=(0, 0))[source]#

dphox.typing module#

class dphox.typing.CurveTuple(points, tangents)#

Bases: tuple

points#

Alias for field number 0

tangents#

Alias for field number 1

dphox.utils module#

dphox.utils.bounds(points)[source]#

Bounding box of points of the form (minx, miny, maxx, maxy)

Parameters
  • polygons – The ndarray polygon representation.

  • overall – Get the overall bounds rather than a list of bounds for each polygon

Returns

Bounding box tuple.

dphox.utils.fix_dataclass_init_docs(cls)[source]#

Fix the __init__ documentation for a dataclasses.dataclass.

Parameters

cls – The class whose docstring needs fixing

Returns

The class that was passed so this function can be used as a decorator

dphox.utils.linestring_points(geom, decimals=None)[source]#

Get the exterior points of a given polygon geometry

Parameters
  • geom (LineString) – Geometry from which to get exterior points

  • decimals (Optional[int]) – Number of decimal places to round the points

Returns

The numpy array representing the points of the polygon.

dphox.utils.min_aspect_bounds(b, min_aspect=0.25)[source]#

Minimum aspect ratio (needed for plotting)

We adjust the bounds of the smaller dimension to achieve the min aspect ratio if it is not already exceeded. An aspect ratio of 0.25 indicates that one dimension cannot exceed 4 times the other.

Parameters
  • b (Union[ndarray, Tuple[float, float, float, float]]) – bounds.

  • min_aspect (float) – minimum aspect ratio.

Returns

The new bounds.

dphox.utils.poly_bounds(polygons, overall=False)[source]#

Bounding box of polygons of the form (minx, miny, maxx, maxy)

Parameters
  • polygons (List[ndarray]) – The ndarray polygon representation.

  • overall (bool) – Get the overall bounds rather than a list of bounds for each polygon

Returns

Bounding box tuple.

dphox.utils.poly_points(geom, decimals=None)[source]#

Get the exterior points of a given polygon geometry

Parameters
  • geom (Polygon) – Geometry from which to get exterior points

  • decimals (Optional[int]) – Number of decimal places to round the points

Returns

The numpy array representing the points of the polygon.

dphox.utils.shapely_patch(geom, **kwargs)[source]#

Get the shapely patch for plotting in matplotlib (remove descartes dependency).

Parameters
  • geom (Union[MultiPolygon, Polygon]) – geometry

  • kwargs – keyword arguments for matplotlib’s PathPatch

Returns

The Matplotlib PathPatch for plotting in matplotlib.

dphox.utils.split_holes(geom, along_y=True)[source]#

Fracture a shapely geometry into polygon along x or y direction (depending on along_x).

If there are no holes, just return the input geometry geom. Otherwise, recursively run the algorithm on the split geometries.

Parameters
  • geom (Union[Polygon, MultiPolygon, GeometryCollection, ndarray]) – Geometry that potentially has holes.

  • along_y (bool) – Split the geometry along y (flips the split direction on each recursive call).

Return type

MultiPolygon

Returns

MultiPolygon representing the fractured geometry.

dphox.utils.split_max_points(geom, max_num_points=8096, along_y=True)[source]#

Fracture shapely geometry into polygons that possess a specified maximum number of points max_num_points.

If the number of points in yhe geometry is already less than or equal to max_num_points, just return the input geometry geom. Otherwise, recursively run the algorithm on the split geometries.

Parameters
  • geom (Union[Polygon, MultiPolygon, ndarray]) – Geometry that potentially has holes.

  • max_num_points (int) – Maximum number of points.

  • along_y (bool) – Split the geometry along y.

Returns

MultiPolygon representing the fractured geometry.

Module contents#