Coverage for qpdk / samples / sample_to_3d.py: 100%
17 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-14 10:27 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-14 10:27 +0000
1# ---
2# jupyter:
3# jupytext:
4# text_representation:
5# extension: .py
6# format_name: percent
7# format_version: '1.3'
8# jupytext_version: 1.17.3
9# ---
11# %% [markdown]
12# # Sample 3D Visualization
13#
14# This sample demonstrates how to create a 3D visualization of a layout with different cross-sections.
16# %%
17import gdsfactory as gf
19from qpdk import PDK, cells, tech
20from qpdk.cells.helpers import apply_additive_metals, fill_magnetic_vortices
22# %% [markdown]
23# ## 3D Sample Function
24#
25# Creates a transmon coupled to a resonator with a chip edge for 3D visualization.
28# %%
29@gf.cell
30def sample_to_3d() -> gf.Component:
31 """Returns a transmon with a resonator and chip edge for 3D visualization.
33 This function demonstrates the full workflow of adding logical components,
34 filling with magnetic vortices, adding a simulation area, and finally
35 applying the additive metal transformation for mask generation and 3D visualization.
36 """
37 c = gf.Component()
39 # Create the transmon with resonator
40 tr = c << cells.double_pad_transmon_with_resonator()
42 # Add a chip edge around the component
43 bbox = tr.bbox()
44 margin = 100.0
45 chip_size = (bbox.width() + 2 * margin, bbox.height() + 2 * margin)
47 ce = c << cells.chip_edge(size=chip_size, width=20.0)
48 ce.center = tr.center
50 # fill_magnetic_vortices adds small etch holes for magnetic flux trapping.
51 # It returns a new component cell.
52 c = fill_magnetic_vortices(c)
54 # We must use .dup() because apply_additive_metals flattens the component and removes layers,
55 # and we want to perform these modifications on a fresh copy to avoid LockedErrors
56 # since we are inside a @cell-decorated function and the result of fill_magnetic_vortices is also a cell.
57 c = c.dup()
59 # For 3D visualization, we need to add the SIM_AREA layer which acts as the bulk metal/substrate
60 # from which etched regions are subtracted in the LayerStack.
61 # We match the SIM_AREA to the chip edge area.
62 bbox_total = c.bbox()
63 c.add_polygon(
64 [
65 (bbox_total.left, bbox_total.bottom),
66 (bbox_total.right, bbox_total.bottom),
67 (bbox_total.right, bbox_total.top),
68 (bbox_total.left, bbox_total.top),
69 ],
70 layer=tech.LAYER.SIM_AREA,
71 )
73 # apply_additive_metals generates the final negative mask on M1_ETCH by subtracting M1_DRAW.
74 return apply_additive_metals(c)
77# %% [markdown]
78# ## Visualization
79#
80# Shows the component in 2D (KLayout) and 3D.
82# %%
83if __name__ == "__main__":
84 PDK.activate()
86 c = sample_to_3d()
87 c.show()
88 s = c.to_3d(layer_stack=tech.LAYER_STACK_NO_VACUUM)
89 s.show()