various fixes and cleanup

mainly involving ports_to_data and data_to_ports
master
Jan Petykiewicz 1 year ago committed by jan
parent 16567c8a66
commit 963918d1d9

@ -8,7 +8,7 @@ from masque import (
layer_t, Pattern, Ref, Label, Builder, Port, Polygon,
WrapLibrary, Library,
)
from masque.builder import port_utils
from masque.utils import ports2data
from masque.file.gdsii import writefile, check_valid_names
import pcgen
@ -20,20 +20,20 @@ LATTICE_CONSTANT = 512
RADIUS = LATTICE_CONSTANT / 2 * 0.75
def dev2pat(dev: Pattern) -> Pattern:
def ports_to_data(pat: Pattern) -> Pattern:
"""
Bake port information into the pattern.
This places a label at each port location on layer (3, 0) with text content
'name:ptype angle_deg'
"""
return port_utils.dev2pat(dev, layer=(3, 0))
return ports2data.ports_to_data(pat, layer=(3, 0))
def pat2dev(lib: Mapping[str, Pattern], name: str, pat: Pattern) -> Pattern:
def data_to_ports(lib: Mapping[str, Pattern], name: str, pat: Pattern) -> Pattern:
"""
Scans the Pattern to determine port locations. Same format as `dev2pat`
Scans the Pattern to determine port locations. Same port format as `ports_to_data`
"""
return port_utils.pat2dev(layers=[(3, 0)], library=lib, pattern=pat, name=name)
return ports2data.data_to_ports(layers=[(3, 0)], library=lib, pattern=pat, name=name)
def perturbed_l3(
@ -103,7 +103,7 @@ def perturbed_l3(
output=Port((extent, 0), rotation=pi, ptype='pcwg'),
)
dev2pat(pat)
ports_to_data(pat)
return pat
@ -142,8 +142,8 @@ def waveguide(
left=Port((-extent, 0), rotation=0, ptype='pcwg'),
right=Port((extent, 0), rotation=pi, ptype='pcwg'),
)
dev2pat(pat)
print(pat)
ports_to_data(pat)
return pat
@ -183,7 +183,7 @@ def bend(
extent * numpy.sqrt(3) / 2),
rotation=pi * 4 / 3, ptype='pcwg'),
)
dev2pat(pat)
ports_to_data(pat)
return pat
@ -222,7 +222,7 @@ def y_splitter(
'bot': Port((extent / 2, -extent * numpy.sqrt(3) / 2), rotation=pi * 2 / 3, ptype='pcwg'),
}
dev2pat(pat)
ports_to_data(pat)
return pat
@ -311,7 +311,7 @@ def main(interactive: bool = True) -> None:
# We can also add text labels for our circuit's ports.
# They will appear at the uppermost hierarchy level, while the individual
# device ports will appear further down, in their respective cells.
dev2pat(circ.pattern)
ports_to_data(circ.pattern)
# Add the pattern into our library
lib['my_circuit'] = circ.pattern

@ -10,7 +10,7 @@ from masque.file.gdsii import writefile, load_libraryfile
import pcgen
import basic_shapes
import devices
from devices import pat2dev, dev2pat
from devices import ports_to_data, data_to_ports
from basic_shapes import GDS_OPTS
@ -24,7 +24,7 @@ def main() -> None:
#
# Scan circuit.gds and prepare to lazy-load its contents
gds_lib, _properties = load_libraryfile('circuit.gds', postprocess=pat2dev)
gds_lib, _properties = load_libraryfile('circuit.gds', postprocess=data_to_ports)
# Add it into the device library by providing a way to read port info
# This maintains the lazy evaluation from above, so no patterns
@ -59,13 +59,18 @@ def main() -> None:
# Immediately start building from an instance of the L3 cavity
circ2 = Builder(library=lib, ports='tri_l3cav')
print(lib['wg10'].ports)
# First way to get abstracts is `lib.abstract(name)`
circ2.plug(lib.abstract('wg10'), {'input': 'right'})
abstracts = lib.abstract_view() # Alternate way to get abstracts
# Second way to get abstracts is to use an AbstractView
abstracts = lib.abstract_view()
circ2.plug(abstracts['wg10'], {'output': 'left'})
circ2.plug(abstracts['tri_wg10'], {'input': 'right'})
circ2.plug(abstracts['tri_wg10'], {'output': 'left'})
# Third way to specify an abstract works by automatically getting
# it from the library already within the Builder object:
# Just pass the pattern name!
circ2.plug('tri_wg10', {'input': 'right'})
circ2.plug('tri_wg10', {'output': 'left'})
# Add the circuit to the device library.
# It has already been generated, so we can use `set_const` as a shorthand for
@ -81,15 +86,15 @@ def main() -> None:
circ3 = Builder.interface(source=circ2)
# ... that lets us continue from where we left off.
circ3.plug(abstracts['tri_bend0'], {'input': 'right'})
circ3.plug(abstracts['tri_bend0'], {'input': 'left'}, mirrored=(True, False)) # mirror since no tri y-symmetry
circ3.plug(abstracts['tri_bend0'], {'input': 'right'})
circ3.plug(abstracts['bend0'], {'output': 'left'})
circ3.plug(abstracts['bend0'], {'output': 'left'})
circ3.plug(abstracts['bend0'], {'output': 'left'})
circ3.plug(abstracts['tri_wg10'], {'input': 'right'})
circ3.plug(abstracts['tri_wg28'], {'input': 'right'})
circ3.plug(abstracts['tri_wg10'], {'input': 'right', 'output': 'left'})
circ3.plug('tri_bend0', {'input': 'right'})
circ3.plug('tri_bend0', {'input': 'left'}, mirrored=(True, False)) # mirror since no tri y-symmetry
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'})
lib.set_const('loop_segment', circ3.pattern)

@ -27,12 +27,13 @@
"""
from .utils import layer_t, annotations_t, SupportsBool
from .error import MasqueError, PatternError, LibraryError, BuildError
from .shapes import Shape, Polygon, Path, Circle, Arc, Ellipse
from .label import Label
from .ref import Ref
from .pattern import Pattern
from .utils import layer_t, annotations_t
from .library import Library, MutableLibrary, WrapROLibrary, WrapLibrary, LazyLibrary, AbstractView
from .ports import Port, PortList
from .abstract import Abstract

@ -10,16 +10,16 @@ from abc import ABCMeta, abstractmethod
import numpy
from numpy.typing import ArrayLike, NDArray
from .error import PatternError
from .utils import rotation_matrix_2d, AutoSlots
from .traits import Copyable, Scalable, Rotatable, Mirrorable
from .error import PatternError
from .utils import rotation_matrix_2d
class Repetition(Copyable, Rotatable, Mirrorable, Scalable, metaclass=ABCMeta):
"""
Interface common to all objects which specify repetitions
"""
__slots__ = ()
__slots__ = () # Allow subclasses to use __slots__
@property
@abstractmethod
@ -30,7 +30,7 @@ class Repetition(Copyable, Rotatable, Mirrorable, Scalable, metaclass=ABCMeta):
pass
class Grid(Repetition, metaclass=AutoSlots):
class Grid(Repetition):
"""
`Grid` describes a 2D grid formed by two basis vectors and two 'counts' (sizes).
@ -279,7 +279,7 @@ class Grid(Repetition, metaclass=AutoSlots):
return True
class Arbitrary(Repetition, metaclass=AutoSlots):
class Arbitrary(Repetition):
"""
`Arbitrary` is a simple list of (absolute) displacements for instances.

@ -7,12 +7,12 @@ from numpy import pi
from numpy.typing import NDArray, ArrayLike
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..utils import is_scalar, layer_t, AutoSlots, annotations_t
from ..utils import is_scalar, layer_t, annotations_t
class Arc(Shape, metaclass=AutoSlots):
class Arc(Shape):
"""
An elliptical arc, formed by cutting off an elliptical ring with two rays which exit from its
center. It has a position, two radii, a start and stop angle, a rotation, and a width.

@ -6,12 +6,12 @@ from numpy import pi
from numpy.typing import NDArray, ArrayLike
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..utils import is_scalar, layer_t, AutoSlots, annotations_t
from ..utils import is_scalar, layer_t, annotations_t
class Circle(Shape, metaclass=AutoSlots):
class Circle(Shape):
"""
A circle, which has a position and radius.
"""

@ -7,12 +7,12 @@ from numpy import pi
from numpy.typing import ArrayLike, NDArray
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..utils import is_scalar, rotation_matrix_2d, layer_t, AutoSlots, annotations_t
from ..utils import is_scalar, rotation_matrix_2d, layer_t, annotations_t
class Ellipse(Shape, metaclass=AutoSlots):
class Ellipse(Shape):
"""
An ellipse, which has a position, two radii, and a rotation.
The rotation gives the angle from x-axis, counterclockwise, to the first (x) radius.

@ -7,9 +7,9 @@ from numpy import pi, inf
from numpy.typing import NDArray, ArrayLike
from . import Shape, normalized_shape_tuple, Polygon, Circle
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..utils import is_scalar, rotation_matrix_2d, layer_t, AutoSlots
from ..utils import is_scalar, rotation_matrix_2d, layer_t
from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t
@ -21,7 +21,7 @@ class PathCap(Enum):
# # defined by path.cap_extensions
class Path(Shape, metaclass=AutoSlots):
class Path(Shape):
"""
A path, consisting of a bunch of vertices (Nx2 ndarray), a width, an end-cap shape,
and an offset.

@ -6,13 +6,13 @@ from numpy import pi
from numpy.typing import NDArray, ArrayLike
from . import Shape, normalized_shape_tuple
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..utils import is_scalar, rotation_matrix_2d, layer_t, AutoSlots
from ..utils import is_scalar, rotation_matrix_2d, layer_t
from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t
class Polygon(Shape, metaclass=AutoSlots):
class Polygon(Shape):
"""
A polygon, consisting of a bunch of vertices (Nx2 ndarray) which specify an
implicitly-closed boundary, and an offset.

@ -6,10 +6,10 @@ from numpy import pi, inf
from numpy.typing import NDArray, ArrayLike
from . import Shape, Polygon, normalized_shape_tuple
from .. import PatternError
from ..error import PatternError
from ..repetition import Repetition
from ..traits import RotatableImpl
from ..utils import is_scalar, get_bit, normalize_mirror, layer_t, AutoSlots
from ..utils import is_scalar, get_bit, normalize_mirror, layer_t
from ..utils import annotations_t
# Loaded on use:
@ -17,7 +17,7 @@ from ..utils import annotations_t
# from matplotlib.path import Path
class Text(RotatableImpl, Shape, metaclass=AutoSlots):
class Text(RotatableImpl, Shape):
"""
Text (to be printed e.g. as a set of polygons).
This is distinct from non-printed Label objects.

@ -35,7 +35,7 @@ class Positionable(metaclass=ABCMeta):
@offset.setter
@abstractmethod
def offset(self, val: ArrayLike):
def offset(self, val: ArrayLike) -> None:
pass
@abstractmethod

@ -1,4 +1,4 @@
from typing import TypeVar, cast
from typing import TypeVar, cast, Any
from abc import ABCMeta, abstractmethod
import numpy
@ -114,6 +114,9 @@ class PivotableImpl(Pivotable, metaclass=ABCMeta):
"""
__slots__ = ()
offset: Any # TODO see if we can get around defining `offset` in PivotableImpl
""" `[x_offset, y_offset]` """
def rotate_around(self: J, pivot: ArrayLike, rotation: float) -> J:
pivot = numpy.array(pivot, dtype=float)
cast(Positionable, self).translate(-pivot)

@ -2,7 +2,6 @@
Various helper functions, type definitions, etc.
"""
from .types import layer_t, annotations_t, SupportsBool
from .array import is_scalar
from .autoslots import AutoSlots
from .deferreddict import DeferredDict

Loading…
Cancel
Save