2024-07-28 19:33:16 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from typing import Any
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from collections.abc import Sequence, Callable
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from pprint import pformat
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import numpy
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from numpy import pi
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-04-07 18:08:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from masque import Pattern, Builder, LazyLibrary
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from masque.file.gdsii import writefile, load_libraryfile
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import pcgen
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import basic_shapes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import devices
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from devices import ports_to_data, data_to_ports
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from basic_shapes import GDS_OPTS
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								def main() -> None:
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Define a `LazyLibrary`, which provides lazy evaluation for generating
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #   patterns and lazy-loading of GDS contents.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib = LazyLibrary()
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Load some devices from a GDS file
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Scan circuit.gds and prepare to lazy-load its contents
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    gds_lib, _properties = load_libraryfile('circuit.gds', postprocess=data_to_ports)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Add it into the device library by providing a way to read port info
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #   This maintains the lazy evaluation from above, so no patterns
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # are actually read yet.
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib.add(gds_lib)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    print('Patterns loaded from GDS into library:\n' + pformat(list(lib.keys())))
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Add some new devices to the library, this time from python code rather than GDS
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib['triangle'] = lambda: basic_shapes.triangle(devices.RADIUS)
							 | 
						
					
						
							
								
									
										
										
										
											2023-07-17 20:22:04 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts: dict[str, Any] = dict(
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        lattice_constant = devices.LATTICE_CONSTANT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        hole = 'triangle',
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        )
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Triangle-based variants. These are defined here, but they won't run until they're
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #   retrieved from the library.
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib['tri_wg10'] = lambda: devices.waveguide(length=10, mirror_periods=5, **opts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib['tri_wg05'] = lambda: devices.waveguide(length=5, mirror_periods=5, **opts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib['tri_wg28'] = lambda: devices.waveguide(length=28, mirror_periods=5, **opts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib['tri_bend0'] = lambda: devices.bend(mirror_periods=5, **opts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib['tri_ysplit'] = lambda: devices.y_splitter(mirror_periods=5, **opts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    lib['tri_l3cav'] = lambda: devices.perturbed_l3(xy_size=(4, 10), **opts, hole_lib=lib)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Build a mixed waveguide with an L3 cavity in the middle
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Immediately start building from an instance of the L3 cavity
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ2 = Builder(library=lib, ports='tri_l3cav')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    #   First way to get abstracts is `lib.abstract(name)`
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-15 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # We can use this syntax directly with `Pattern.plug()` and `Pattern.place()` as well as through `Builder`.
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ2.plug(lib.abstract('wg10'), {'input': 'right'})
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    #   Second way to get abstracts is to use an AbstractView
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-15 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # This also works directly with `Pattern.plug()` / `Pattern.place()`.
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    abstracts = lib.abstract_view()
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ2.plug(abstracts['wg10'], {'output': 'left'})
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Third way to specify an abstract works by automatically getting
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-15 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # it from the library already within the Builder object.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # This wouldn't work if we only had a `Pattern` (not a `Builder`).
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Just pass the pattern name!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ2.plug('tri_wg10', {'input': 'right'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ2.plug('tri_wg10', {'output': 'left'})
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Add the circuit to the device library.
							 | 
						
					
						
							
								
									
										
										
										
											2023-07-17 20:22:04 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib['mixed_wg_cav'] = circ2.pattern
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Build a device that could plug into our mixed_wg_cav and joins the two ports
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # We'll be designing against an existing device's interface...
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ3 = Builder.interface(source=circ2)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # ... that lets us continue from where we left off.
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_bend0', {'input': 'right'})
							 | 
						
					
						
							
								
									
										
										
										
											2023-07-17 20:22:04 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_bend0', {'input': 'left'}, mirrored=True) # mirror since no tri y-symmetry
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-25 23:57:02 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_bend0', {'input': 'right'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('bend0', {'output': 'left'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('bend0', {'output': 'left'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('bend0', {'output': 'left'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_wg10', {'input': 'right'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_wg28', {'input': 'right'})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    circ3.plug('tri_wg10', {'input': 'right', 'output': 'left'})
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-07-17 20:22:04 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    lib['loop_segment'] = circ3.pattern
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # Write all devices into a GDS file
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    #
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    print('Writing library to file...')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    writefile(lib, 'library.gds', **GDS_OPTS)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								if __name__ == '__main__':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    main()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#class prout:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#    def place(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            self,
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#            other: Pattern,
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            label_layer: layer_t = 'WATLAYER',
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            *,
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-23 13:15:32 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#            port_map: Dict[str, str | None] | None = None,
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            **kwargs,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            ) -> 'prout':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-24 23:25:10 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#        Pattern.place(self, other, port_map=port_map, **kwargs)
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-23 13:15:32 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#        name: str | None
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#        for name in other.ports:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            if port_map:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#                assert(name is not None)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#                name = port_map.get(name, name)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#            if name is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#                continue
							 | 
						
					
						
							
								
									
										
										
										
											2023-07-17 20:22:04 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#            self.pattern.label(string=name, offset=self.ports[name].offset, layer=label_layer)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-27 21:21:44 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#        return self
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 |