diff --git a/examples/tutorial/README.md b/examples/tutorial/README.md index 6e5730b..7210a93 100644 --- a/examples/tutorial/README.md +++ b/examples/tutorial/README.md @@ -18,14 +18,11 @@ Contents * Design a pattern which is meant to plug into an existing pattern (via `.interface()`) - [pather](pather.py) * Use `Pather` to route individual wires and wire bundles - * Use `AutoTool` to generate paths - * Use `AutoTool` to automatically transition between path types -- [renderpather](renderpather.py) + * Use `BasicTool` to generate paths + * Use `BasicTool` to automatically transition between path types +- [renderpather](rendpather.py) * Use `RenderPather` and `PathTool` to build a layout similar to the one in [pather](pather.py), but using `Path` shapes instead of `Polygon`s. -- [port_pather](port_pather.py) - * Use `PortPather` and the `.at()` syntax for more concise routing - * Advanced port manipulation and connections Additionaly, [pcgen](pcgen.py) is a utility module for generating photonic crystal lattices. diff --git a/examples/tutorial/basic_shapes.py b/examples/tutorial/basic_shapes.py index 8664b4d..5b5aab7 100644 --- a/examples/tutorial/basic_shapes.py +++ b/examples/tutorial/basic_shapes.py @@ -2,8 +2,9 @@ import numpy from numpy import pi -from masque import layer_t, Pattern, Circle, Arc, Polygon, Ref -from masque.repetition import Grid +from masque import ( + layer_t, Pattern, Circle, Arc, Polygon, + ) import masque.file.gdsii @@ -36,45 +37,6 @@ def hole( return pat -def hole_array( - radius: float, - num_x: int = 5, - num_y: int = 3, - pitch: float = 2000, - layer: layer_t = (1, 0), - ) -> Pattern: - """ - Generate an array of circular holes using `Repetition`. - - Args: - radius: Circle radius. - num_x, num_y: Number of holes in x and y. - pitch: Center-to-center spacing. - layer: Layer to draw the holes on. - - Returns: - Pattern containing a grid of holes. - """ - # First, make a pattern for a single hole - hpat = hole(radius, layer) - - # Now, create a pattern that references it multiple times using a Grid - pat = Pattern() - pat.refs['hole'] = [ - Ref( - offset=(0, 0), - repetition=Grid(a_vector=(pitch, 0), a_count=num_x, - b_vector=(0, pitch), b_count=num_y) - )] - - # We can also add transformed references (rotation, mirroring, etc.) - pat.refs['hole'].append( - Ref(offset=(0, -pitch), rotation=pi / 4, mirrored=True) - ) - - return pat, hpat - - def triangle( radius: float, layer: layer_t = (1, 0), @@ -96,7 +58,9 @@ def triangle( ]) * radius pat = Pattern() - pat.polygon(layer, vertices=vertices) + pat.shapes[layer].extend([ + Polygon(offset=(0, 0), vertices=vertices), + ]) return pat @@ -145,13 +109,9 @@ def main() -> None: lib['smile'] = smile(1000) lib['triangle'] = triangle(1000) - # Use a Grid to make many holes efficiently - lib['grid'], lib['hole'] = hole_array(1000) - masque.file.gdsii.writefile(lib, 'basic_shapes.gds', **GDS_OPTS) lib['triangle'].visualize() - lib['grid'].visualize(lib) if __name__ == '__main__': diff --git a/examples/tutorial/pather.py b/examples/tutorial/pather.py index a9d9af9..c212bc5 100644 --- a/examples/tutorial/pather.py +++ b/examples/tutorial/pather.py @@ -239,7 +239,7 @@ def main() -> None: pather.path_to('GND', None, x=pather['VCC'].offset[0]) # Now, start using M1_tool for GND. - # Since we have defined an M2-to-M1 transition for Pather, we don't need to place one ourselves. + # Since we have defined an M2-to-M1 transition for BasicPather, we don't need to place one ourselves. # If we wanted to place our via manually, we could add `pather.plug('m1_via', {'GND': 'top'})` here # and achieve the same result without having to define any transitions in M1_tool. # Note that even though we have changed the tool used for GND, the via doesn't get placed until diff --git a/examples/tutorial/renderpather.py b/examples/tutorial/renderpather.py index ecc8bc8..87e58f2 100644 --- a/examples/tutorial/renderpather.py +++ b/examples/tutorial/renderpather.py @@ -12,7 +12,7 @@ from pather import M1_WIDTH, V1_WIDTH, M2_WIDTH, map_layer, make_pad, make_via def main() -> None: # # To illustrate the advantages of using `RenderPather`, we use `PathTool` instead - # of `AutoTool`. `PathTool` lacks some sophistication (e.g. no automatic transitions) + # of `BasicTool`. `PathTool` lacks some sophistication (e.g. no automatic transitions) # but when used with `RenderPather`, it can consolidate multiple routing steps into # a single `Path` shape. # @@ -34,7 +34,7 @@ def main() -> None: ptype_top = 'm2wire', ) - # `PathTool` is more limited than `AutoTool`. It only generates one type of shape + # `PathTool` is more limited than `BasicTool`. It only generates one type of shape # (`Path`), so it only needs to know what layer to draw on, what width to draw with, # and what port type to present. M1_ptool = PathTool(layer='M1', width=M1_WIDTH, ptype='m1wire') @@ -77,7 +77,6 @@ def main() -> None: # to account for it. v1pat = library['v1_via'] via_size = abs(v1pat.ports['top'].x - v1pat.ports['bottom'].x) - # alternatively, via_size = v1pat.ports['top'].measure_travel(v1pat.ports['bottom'])[0][0] # would take into account the port orientations if we didn't already know they're along x rpather.path_to('VCC', None, -50_000 + via_size) diff --git a/masque/label.py b/masque/label.py index 8b67c65..4bd2c4a 100644 --- a/masque/label.py +++ b/masque/label.py @@ -104,12 +104,10 @@ class Label(PositionableImpl, RepeatableImpl, AnnotatableImpl, Bounded, Pivotabl def flip_across(self, axis: int | None = None, *, x: float | None = None, y: float | None = None) -> Self: """ - Flip the label across a line in the pattern's coordinate system. - - This operation mirrors the label's offset relative to the pattern's origin. + Mirror the object across a line. Args: - axis: Axis to mirror across. 0 mirrors across y=0. 1 mirrors across x=0. + axis: Axis to mirror across. 0 mirrors across x=0. 1 mirrors across y=0. x: Vertical line x=val to mirror across. y: Horizontal line y=val to mirror across. diff --git a/masque/ports.py b/masque/ports.py index 45aedb5..c40cf55 100644 --- a/masque/ports.py +++ b/masque/ports.py @@ -108,9 +108,7 @@ class Port(PivotableImpl, PositionableImpl, Mirrorable, Flippable, Copyable): def flip_across(self, axis: int | None = None, *, x: float | None = None, y: float | None = None) -> Self: """ - Mirror the object across a line in the container's coordinate system. - - Note this operation is performed relative to the pattern's origin and modifies the port's offset. + Mirror the object across a line. Args: axis: Axis to mirror across. 0 mirrors across y=0. 1 mirrors across x=0. diff --git a/masque/traits/mirrorable.py b/masque/traits/mirrorable.py index deddddd..644db61 100644 --- a/masque/traits/mirrorable.py +++ b/masque/traits/mirrorable.py @@ -18,11 +18,7 @@ class Mirrorable(metaclass=ABCMeta): @abstractmethod def mirror(self, axis: int = 0) -> Self: """ - Mirror the entity across an axis through its origin. - - This operation is performed relative to the object's internal origin (ignoring - its offset). For objects like `Polygon` and `Path` where the offset is forced - to (0, 0), this is equivalent to mirroring in the container's coordinate system. + Mirror the entity across an axis through its origin, ignoring its offset. Args: axis: Axis to mirror across (0: x-axis, 1: y-axis). @@ -74,14 +70,10 @@ class Flippable(Positionable, metaclass=ABCMeta): @abstractmethod def flip_across(self, axis: int | None = None, *, x: float | None = None, y: float | None = None) -> Self: """ - Mirror the object across a line in the container's coordinate system. - - Unlike `mirror()`, this operation is performed relative to the container's origin - (e.g. the `Pattern` origin, in the case of shapes) and takes the object's offset - into account. + Mirror the object across a line. Args: - axis: Axis to mirror across. 0 mirrors across y=0. 1 mirrors across x=0. + axis: Axis to mirror across. 0 mirrors across x=0. 1 mirrors across y=0. x: Vertical line x=val to mirror across. y: Horizontal line y=val to mirror across.