various fixes and cleanup
mainly involving ports_to_data and data_to_ports
This commit is contained in:
parent
6599dad48f
commit
089e5192e3
@ -8,7 +8,7 @@ from masque import (
|
|||||||
layer_t, Pattern, Ref, Label, Builder, Port, Polygon,
|
layer_t, Pattern, Ref, Label, Builder, Port, Polygon,
|
||||||
WrapLibrary, Library,
|
WrapLibrary, Library,
|
||||||
)
|
)
|
||||||
from masque.builder import port_utils
|
from masque.utils import ports2data
|
||||||
from masque.file.gdsii import writefile, check_valid_names
|
from masque.file.gdsii import writefile, check_valid_names
|
||||||
|
|
||||||
import pcgen
|
import pcgen
|
||||||
@ -20,20 +20,20 @@ LATTICE_CONSTANT = 512
|
|||||||
RADIUS = LATTICE_CONSTANT / 2 * 0.75
|
RADIUS = LATTICE_CONSTANT / 2 * 0.75
|
||||||
|
|
||||||
|
|
||||||
def dev2pat(dev: Pattern) -> Pattern:
|
def ports_to_data(pat: Pattern) -> Pattern:
|
||||||
"""
|
"""
|
||||||
Bake port information into the pattern.
|
Bake port information into the pattern.
|
||||||
This places a label at each port location on layer (3, 0) with text content
|
This places a label at each port location on layer (3, 0) with text content
|
||||||
'name:ptype angle_deg'
|
'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(
|
def perturbed_l3(
|
||||||
@ -103,7 +103,7 @@ def perturbed_l3(
|
|||||||
output=Port((extent, 0), rotation=pi, ptype='pcwg'),
|
output=Port((extent, 0), rotation=pi, ptype='pcwg'),
|
||||||
)
|
)
|
||||||
|
|
||||||
dev2pat(pat)
|
ports_to_data(pat)
|
||||||
return pat
|
return pat
|
||||||
|
|
||||||
|
|
||||||
@ -142,8 +142,8 @@ def waveguide(
|
|||||||
left=Port((-extent, 0), rotation=0, ptype='pcwg'),
|
left=Port((-extent, 0), rotation=0, ptype='pcwg'),
|
||||||
right=Port((extent, 0), rotation=pi, ptype='pcwg'),
|
right=Port((extent, 0), rotation=pi, ptype='pcwg'),
|
||||||
)
|
)
|
||||||
dev2pat(pat)
|
|
||||||
print(pat)
|
ports_to_data(pat)
|
||||||
return pat
|
return pat
|
||||||
|
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ def bend(
|
|||||||
extent * numpy.sqrt(3) / 2),
|
extent * numpy.sqrt(3) / 2),
|
||||||
rotation=pi * 4 / 3, ptype='pcwg'),
|
rotation=pi * 4 / 3, ptype='pcwg'),
|
||||||
)
|
)
|
||||||
dev2pat(pat)
|
ports_to_data(pat)
|
||||||
return 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'),
|
'bot': Port((extent / 2, -extent * numpy.sqrt(3) / 2), rotation=pi * 2 / 3, ptype='pcwg'),
|
||||||
}
|
}
|
||||||
|
|
||||||
dev2pat(pat)
|
ports_to_data(pat)
|
||||||
return pat
|
return pat
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ def main(interactive: bool = True) -> None:
|
|||||||
# We can also add text labels for our circuit's ports.
|
# We can also add text labels for our circuit's ports.
|
||||||
# They will appear at the uppermost hierarchy level, while the individual
|
# They will appear at the uppermost hierarchy level, while the individual
|
||||||
# device ports will appear further down, in their respective cells.
|
# device ports will appear further down, in their respective cells.
|
||||||
dev2pat(circ.pattern)
|
ports_to_data(circ.pattern)
|
||||||
|
|
||||||
# Add the pattern into our library
|
# Add the pattern into our library
|
||||||
lib['my_circuit'] = circ.pattern
|
lib['my_circuit'] = circ.pattern
|
||||||
|
@ -10,7 +10,7 @@ from masque.file.gdsii import writefile, load_libraryfile
|
|||||||
import pcgen
|
import pcgen
|
||||||
import basic_shapes
|
import basic_shapes
|
||||||
import devices
|
import devices
|
||||||
from devices import pat2dev, dev2pat
|
from devices import ports_to_data, data_to_ports
|
||||||
from basic_shapes import GDS_OPTS
|
from basic_shapes import GDS_OPTS
|
||||||
|
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ def main() -> None:
|
|||||||
#
|
#
|
||||||
|
|
||||||
# Scan circuit.gds and prepare to lazy-load its contents
|
# 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
|
# Add it into the device library by providing a way to read port info
|
||||||
# This maintains the lazy evaluation from above, so no patterns
|
# 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
|
# Immediately start building from an instance of the L3 cavity
|
||||||
circ2 = Builder(library=lib, ports='tri_l3cav')
|
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'})
|
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['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.
|
# Add the circuit to the device library.
|
||||||
# It has already been generated, so we can use `set_const` as a shorthand for
|
# 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)
|
circ3 = Builder.interface(source=circ2)
|
||||||
|
|
||||||
# ... that lets us continue from where we left off.
|
# ... that lets us continue from where we left off.
|
||||||
circ3.plug(abstracts['tri_bend0'], {'input': 'right'})
|
circ3.plug('tri_bend0', {'input': 'right'})
|
||||||
circ3.plug(abstracts['tri_bend0'], {'input': 'left'}, mirrored=(True, False)) # mirror since no tri y-symmetry
|
circ3.plug('tri_bend0', {'input': 'left'}, mirrored=(True, False)) # mirror since no tri y-symmetry
|
||||||
circ3.plug(abstracts['tri_bend0'], {'input': 'right'})
|
circ3.plug('tri_bend0', {'input': 'right'})
|
||||||
circ3.plug(abstracts['bend0'], {'output': 'left'})
|
circ3.plug('bend0', {'output': 'left'})
|
||||||
circ3.plug(abstracts['bend0'], {'output': 'left'})
|
circ3.plug('bend0', {'output': 'left'})
|
||||||
circ3.plug(abstracts['bend0'], {'output': 'left'})
|
circ3.plug('bend0', {'output': 'left'})
|
||||||
circ3.plug(abstracts['tri_wg10'], {'input': 'right'})
|
circ3.plug('tri_wg10', {'input': 'right'})
|
||||||
circ3.plug(abstracts['tri_wg28'], {'input': 'right'})
|
circ3.plug('tri_wg28', {'input': 'right'})
|
||||||
circ3.plug(abstracts['tri_wg10'], {'input': 'right', 'output': 'left'})
|
circ3.plug('tri_wg10', {'input': 'right', 'output': 'left'})
|
||||||
|
|
||||||
lib.set_const('loop_segment', circ3.pattern)
|
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 .error import MasqueError, PatternError, LibraryError, BuildError
|
||||||
from .shapes import Shape, Polygon, Path, Circle, Arc, Ellipse
|
from .shapes import Shape, Polygon, Path, Circle, Arc, Ellipse
|
||||||
from .label import Label
|
from .label import Label
|
||||||
from .ref import Ref
|
from .ref import Ref
|
||||||
from .pattern import Pattern
|
from .pattern import Pattern
|
||||||
from .utils import layer_t, annotations_t
|
|
||||||
from .library import Library, MutableLibrary, WrapROLibrary, WrapLibrary, LazyLibrary, AbstractView
|
from .library import Library, MutableLibrary, WrapROLibrary, WrapLibrary, LazyLibrary, AbstractView
|
||||||
from .ports import Port, PortList
|
from .ports import Port, PortList
|
||||||
from .abstract import Abstract
|
from .abstract import Abstract
|
||||||
|
@ -10,16 +10,16 @@ from abc import ABCMeta, abstractmethod
|
|||||||
import numpy
|
import numpy
|
||||||
from numpy.typing import ArrayLike, NDArray
|
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 .traits import Copyable, Scalable, Rotatable, Mirrorable
|
||||||
|
from .error import PatternError
|
||||||
|
from .utils import rotation_matrix_2d
|
||||||
|
|
||||||
|
|
||||||
class Repetition(Copyable, Rotatable, Mirrorable, Scalable, metaclass=ABCMeta):
|
class Repetition(Copyable, Rotatable, Mirrorable, Scalable, metaclass=ABCMeta):
|
||||||
"""
|
"""
|
||||||
Interface common to all objects which specify repetitions
|
Interface common to all objects which specify repetitions
|
||||||
"""
|
"""
|
||||||
__slots__ = ()
|
__slots__ = () # Allow subclasses to use __slots__
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -30,7 +30,7 @@ class Repetition(Copyable, Rotatable, Mirrorable, Scalable, metaclass=ABCMeta):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Grid(Repetition, metaclass=AutoSlots):
|
class Grid(Repetition):
|
||||||
"""
|
"""
|
||||||
`Grid` describes a 2D grid formed by two basis vectors and two 'counts' (sizes).
|
`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
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Arbitrary(Repetition, metaclass=AutoSlots):
|
class Arbitrary(Repetition):
|
||||||
"""
|
"""
|
||||||
`Arbitrary` is a simple list of (absolute) displacements for instances.
|
`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 numpy.typing import NDArray, ArrayLike
|
||||||
|
|
||||||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
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
|
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.
|
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 numpy.typing import NDArray, ArrayLike
|
||||||
|
|
||||||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
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.
|
A circle, which has a position and radius.
|
||||||
"""
|
"""
|
||||||
|
@ -7,12 +7,12 @@ from numpy import pi
|
|||||||
from numpy.typing import ArrayLike, NDArray
|
from numpy.typing import ArrayLike, NDArray
|
||||||
|
|
||||||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_POINTS
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
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.
|
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.
|
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 numpy.typing import NDArray, ArrayLike
|
||||||
|
|
||||||
from . import Shape, normalized_shape_tuple, Polygon, Circle
|
from . import Shape, normalized_shape_tuple, Polygon, Circle
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
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
|
from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t
|
||||||
|
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ class PathCap(Enum):
|
|||||||
# # defined by path.cap_extensions
|
# # 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,
|
A path, consisting of a bunch of vertices (Nx2 ndarray), a width, an end-cap shape,
|
||||||
and an offset.
|
and an offset.
|
||||||
|
@ -6,13 +6,13 @@ from numpy import pi
|
|||||||
from numpy.typing import NDArray, ArrayLike
|
from numpy.typing import NDArray, ArrayLike
|
||||||
|
|
||||||
from . import Shape, normalized_shape_tuple
|
from . import Shape, normalized_shape_tuple
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
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
|
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
|
A polygon, consisting of a bunch of vertices (Nx2 ndarray) which specify an
|
||||||
implicitly-closed boundary, and an offset.
|
implicitly-closed boundary, and an offset.
|
||||||
|
@ -6,10 +6,10 @@ from numpy import pi, inf
|
|||||||
from numpy.typing import NDArray, ArrayLike
|
from numpy.typing import NDArray, ArrayLike
|
||||||
|
|
||||||
from . import Shape, Polygon, normalized_shape_tuple
|
from . import Shape, Polygon, normalized_shape_tuple
|
||||||
from .. import PatternError
|
from ..error import PatternError
|
||||||
from ..repetition import Repetition
|
from ..repetition import Repetition
|
||||||
from ..traits import RotatableImpl
|
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
|
from ..utils import annotations_t
|
||||||
|
|
||||||
# Loaded on use:
|
# Loaded on use:
|
||||||
@ -17,7 +17,7 @@ from ..utils import annotations_t
|
|||||||
# from matplotlib.path import Path
|
# 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).
|
Text (to be printed e.g. as a set of polygons).
|
||||||
This is distinct from non-printed Label objects.
|
This is distinct from non-printed Label objects.
|
||||||
|
@ -35,7 +35,7 @@ class Positionable(metaclass=ABCMeta):
|
|||||||
|
|
||||||
@offset.setter
|
@offset.setter
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def offset(self, val: ArrayLike):
|
def offset(self, val: ArrayLike) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TypeVar, cast
|
from typing import TypeVar, cast, Any
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
@ -114,6 +114,9 @@ class PivotableImpl(Pivotable, metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
__slots__ = ()
|
__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:
|
def rotate_around(self: J, pivot: ArrayLike, rotation: float) -> J:
|
||||||
pivot = numpy.array(pivot, dtype=float)
|
pivot = numpy.array(pivot, dtype=float)
|
||||||
cast(Positionable, self).translate(-pivot)
|
cast(Positionable, self).translate(-pivot)
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
Various helper functions, type definitions, etc.
|
Various helper functions, type definitions, etc.
|
||||||
"""
|
"""
|
||||||
from .types import layer_t, annotations_t, SupportsBool
|
from .types import layer_t, annotations_t, SupportsBool
|
||||||
|
|
||||||
from .array import is_scalar
|
from .array import is_scalar
|
||||||
from .autoslots import AutoSlots
|
from .autoslots import AutoSlots
|
||||||
from .deferreddict import DeferredDict
|
from .deferreddict import DeferredDict
|
||||||
|
Loading…
Reference in New Issue
Block a user