""" PortPather tutorial: Using .at() syntax for fluent port manipulation """ from numpy import pi from masque import Pather, Library, Pattern, Port from masque.builder.tools import AutoTool from masque.file.gdsii import writefile from basic_shapes import GDS_OPTS # Reuse helper functions and constants from the basic pather tutorial from pather import ( M1_WIDTH, V1_WIDTH, M2_WIDTH, make_pad, make_via, make_bend, make_straight_wire, map_layer ) def main() -> None: # Reuse the same patterns (pads, bends, vias) and tools as in pather.py library, M1_tool, M2_tool = prepare_tools() library['pad'] = make_pad() library['m1_bend'] = make_bend(layer='M1', ptype='m1wire', width=M1_WIDTH) library['m2_bend'] = make_bend(layer='M2', ptype='m2wire', width=M2_WIDTH) library['v1_via'] = make_via( layer_top='M2', layer_via='V1', layer_bot='M1', width_top=M2_WIDTH, width_via=V1_WIDTH, width_bot=M1_WIDTH, ptype_bot='m1wire', ptype_top='m2wire', ) # Create a RenderPather and place some initial pads (same as Pather tutorial) rpather = RenderPather(library, tools=M2_tool) rpather.place('pad', offset=(18_000, 30_000), port_map={'wire_port': 'VCC'}) rpather.place('pad', offset=(18_000, 60_000), port_map={'wire_port': 'GND'}) rpather.pattern.label(layer='M2', string='VCC', offset=(18e3, 30e3)) rpather.pattern.label(layer='M2', string='GND', offset=(18e3, 60e3)) # # Routing with .at() # # The .at(port_name) method returns a PortPather object which wraps the Pather # and remembers the selected port(s). This allows method chaining. # Then we can route just like in the other pather tutorials: (rpather.at('VCC') .path(ccw=False, length=6_000) .path_to(ccw=None, x=0) ) rpather.at('GND').path(0, 5_000).path_to(None, x=rpather['VCC'].x) # We're using AutoTool so we could retool directly to M1_ptool like in the Pather # tutorial, but let's manually plug to demonstrate what it looks like: (rpather.at('GND') .plug('v1_via', 'top') .retool(M1_tool) # this only retools the 'GND' port ) # We can also pass multiple ports to .at(), and then use .mpath() on them: (rpather.at(['GND', 'VCC']) .mpath(ccw=True, xmax=-10_000, spacing=5_000) .retool(M1_tool) # this retools both ports .mpath(ccw=True, emax=50_000, spacing=1_200) # ...causing an automatic via on VCC here .mpath(ccw=False, emin=1_000, spacing=1_200) .mpath(ccw=False, emin=2_000, spacing=4_500) ) # Now we can finish up the equivalent to the other tutorials.. rpather.at('VCC').retool(M2_tool) rpather.at(['GND', 'VCC']).mpath(None, xmin=-28_000) rpather.at('VCC').path_to(None, x=-50_000, out_ptype='m1wire') with pather.toolctx(M2_tool, keys=['GND']): pather.at('GND').path_to(None, x=-40_000) pather.at('GND').path_to(None, x=-50_000) # # Save result # library['PortPather_Tutorial'] = pather.pattern library.map_layers(map_layer) writefile(library, 'port_pather.gds', **GDS_OPTS) if __name__ == '__main__': main()