various doc updates
This commit is contained in:
parent
04e15f7c85
commit
e2c7f8c8cc
7 changed files with 132 additions and 41 deletions
|
|
@ -495,12 +495,12 @@ def _labels_to_texts(labels: dict[layer_t, list[Label]]) -> list[klamath.element
|
|||
xy=xy,
|
||||
string=label.string.encode('ASCII'),
|
||||
properties=properties,
|
||||
presentation=0, # TODO maybe set some of these?
|
||||
angle_deg=0,
|
||||
invert_y=False,
|
||||
width=0,
|
||||
path_type=0,
|
||||
mag=1,
|
||||
presentation=0, # font number & alignment -- unused by us
|
||||
angle_deg=0, # rotation -- unused by us
|
||||
invert_y=False, # inversion -- unused by us
|
||||
width=0, # stroke width -- unused by us
|
||||
path_type=0, # text path endcaps, unused
|
||||
mag=1, # size -- unused by us
|
||||
)
|
||||
texts.append(text)
|
||||
return texts
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Library classes for managing unique name->pattern mappings and
|
||||
deferred loading or creation.
|
||||
|
||||
# TODO documentn all library classes
|
||||
# TODO documennt all library classes
|
||||
# TODO toplevel documentation of library, classes, and abstracts
|
||||
"""
|
||||
from typing import Callable, Self, Type, TYPE_CHECKING, cast
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""
|
||||
Base object representing a lithography mask.
|
||||
Object representing a one multi-layer lithographic layout.
|
||||
A single level of hierarchical references is included.
|
||||
"""
|
||||
from typing import Callable, Sequence, cast, Mapping, Self, Any, Iterable, TypeVar, MutableMapping
|
||||
import copy
|
||||
|
|
@ -27,7 +28,7 @@ logger = logging.getLogger(__name__)
|
|||
class Pattern(PortList, AnnotatableImpl, Mirrorable):
|
||||
"""
|
||||
2D layout consisting of some set of shapes, labels, and references to other Pattern objects
|
||||
(via Ref). Shapes are assumed to inherit from masque.shapes.Shape or provide equivalent functions.
|
||||
(via Ref). Shapes are assumed to inherit from `masque.shapes.Shape` or provide equivalent functions.
|
||||
"""
|
||||
__slots__ = (
|
||||
'shapes', 'labels', 'refs', '_ports',
|
||||
|
|
@ -864,6 +865,19 @@ TT = TypeVar('TT')
|
|||
|
||||
|
||||
def chain_elements(*args: Mapping[Any, Iterable[TT]]) -> Iterable[TT]:
|
||||
"""
|
||||
Iterate over each element in one or more {layer: elements} mappings.
|
||||
|
||||
Useful when you want to do some operation on all shapes and/or labels,
|
||||
disregarding which layer they are on.
|
||||
|
||||
Args:
|
||||
*args: One or more {layer: [element0, ...]} mappings.
|
||||
Can also be applied to e.g. {target: [ref0, ...]} mappings.
|
||||
|
||||
Returns:
|
||||
An iterable containing all elements, regardless of layer.
|
||||
"""
|
||||
return chain(*(chain.from_iterable(aa.values()) for aa in args))
|
||||
|
||||
|
||||
|
|
@ -871,6 +885,20 @@ def map_layers(
|
|||
elements: Mapping[layer_t, Sequence[TT]],
|
||||
map_layer: Callable[[layer_t], layer_t],
|
||||
) -> defaultdict[layer_t, list[TT]]:
|
||||
"""
|
||||
Move all the elements from one layer onto a different layer.
|
||||
Can also handle multiple such mappings simultaneously.
|
||||
|
||||
Args:
|
||||
elements: Mapping of {old_layer: geometry_or_labels}.
|
||||
map_layer: Callable which may be called with each layer present in `elements`,
|
||||
and should return the new layer to which it will be mapped.
|
||||
A simple example which maps `old_layer` to `new_layer` and leaves all others
|
||||
as-is would look like `lambda layer: {old_layer: new_layer}.get(layer, layer)`
|
||||
|
||||
Returns:
|
||||
Mapping of {new_layer: geometry_or_labels}
|
||||
"""
|
||||
new_elements: defaultdict[layer_t, list[TT]] = defaultdict(list)
|
||||
for old_layer, seq in elements.items():
|
||||
new_layer = map_layer(old_layer)
|
||||
|
|
@ -882,6 +910,20 @@ def map_targets(
|
|||
refs: Mapping[str | None, Sequence[Ref]],
|
||||
map_target: Callable[[str | None], str | None],
|
||||
) -> defaultdict[str | None, list[Ref]]:
|
||||
"""
|
||||
Change the target of all references to a given cell.
|
||||
Can also handle multiple such mappings simultaneously.
|
||||
|
||||
Args:
|
||||
refs: Mapping of {old_target: ref_objects}.
|
||||
map_target: Callable which may be called with each target present in `refs`,
|
||||
and should return the new target to which it will be mapped.
|
||||
A simple example which maps `old_target` to `new_target` and leaves all others
|
||||
as-is would look like `lambda target: {old_target: new_target}.get(target, target)`
|
||||
|
||||
Returns:
|
||||
Mapping of {new_target: ref_objects}
|
||||
"""
|
||||
new_refs: defaultdict[str | None, list[Ref]] = defaultdict(list)
|
||||
for old_target, seq in refs.items():
|
||||
new_target = map_target(old_target)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
"""
|
||||
Ref provides basic support for nesting Pattern objects within each other, by adding
|
||||
offset, rotation, scaling, and other such properties to the reference.
|
||||
Ref provides basic support for nesting Pattern objects within each other.
|
||||
It carries offset, rotation, mirroring, and scaling data for each individual instance.
|
||||
"""
|
||||
#TODO more top-level documentation for ref
|
||||
|
||||
from typing import Mapping, TYPE_CHECKING, Self
|
||||
import copy
|
||||
|
||||
|
|
@ -28,10 +26,15 @@ class Ref(
|
|||
PivotableImpl, Copyable, RepeatableImpl, AnnotatableImpl,
|
||||
):
|
||||
"""
|
||||
`Ref` provides basic support for nesting Pattern objects within each other, by adding
|
||||
offset, rotation, scaling, and associated methods.
|
||||
`Ref` provides basic support for nesting Pattern objects within each other.
|
||||
|
||||
Note: Order is (mirror, rotate, scale, translate, repeat)
|
||||
It containts the transformation (mirror, rotation, scale, offset, repetition)
|
||||
and annotations for a single instantiation of a `Pattern`.
|
||||
|
||||
Note that the target (i.e. which pattern a `Ref` instantiates) is not stored within the
|
||||
`Ref` itself, but is specified by the containing `Pattern`.
|
||||
|
||||
Order of operations is (mirror, rotate, scale, translate, repeat).
|
||||
"""
|
||||
__slots__ = (
|
||||
'_mirrored',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class Path(Shape):
|
|||
A path, consisting of a bunch of vertices (Nx2 ndarray), a width, an end-cap shape,
|
||||
and an offset.
|
||||
|
||||
Note that the setter for `Path.vertices` may (but may not) create a copy of the
|
||||
passed vertex coordinates. See `numpy.array(..., copy=False)` for details.
|
||||
|
||||
A normalized_form(...) is available, but can be quite slow with lots of vertices.
|
||||
"""
|
||||
__slots__ = (
|
||||
|
|
@ -61,12 +64,14 @@ class Path(Shape):
|
|||
def cap(self) -> PathCap:
|
||||
"""
|
||||
Path end-cap
|
||||
|
||||
Note that `cap_extensions` will be reset to default values if
|
||||
`cap` is changed away from `PathCap.SquareCustom`.
|
||||
"""
|
||||
return self._cap
|
||||
|
||||
@cap.setter
|
||||
def cap(self, val: PathCap) -> None:
|
||||
# TODO: Document that setting cap can change cap_extensions
|
||||
self._cap = PathCap(val)
|
||||
if self.cap != PathCap.SquareCustom:
|
||||
self.cap_extensions = None
|
||||
|
|
@ -80,6 +85,9 @@ class Path(Shape):
|
|||
"""
|
||||
Path end-cap extension
|
||||
|
||||
Note that `cap_extensions` will be reset to default values if
|
||||
`cap` is changed away from `PathCap.SquareCustom`.
|
||||
|
||||
Returns:
|
||||
2-element ndarray or `None`
|
||||
"""
|
||||
|
|
@ -101,13 +109,16 @@ class Path(Shape):
|
|||
@property
|
||||
def vertices(self) -> Any: # mypy#3004 NDArray[numpy.float64]]:
|
||||
"""
|
||||
Vertices of the path (Nx2 ndarray: `[[x0, y0], [x1, y1], ...]`)
|
||||
Vertices of the path (Nx2 ndarray: `[[x0, y0], [x1, y1], ...]`
|
||||
|
||||
When setting, note that a copy of the provided vertices may or may not be made,
|
||||
following the rules from `numpy.array(.., copy=False)`.
|
||||
"""
|
||||
return self._vertices
|
||||
|
||||
@vertices.setter
|
||||
def vertices(self, val: ArrayLike) -> None:
|
||||
val = numpy.array(val, dtype=float) # TODO document that these might not be copied
|
||||
val = numpy.array(val, dtype=float)
|
||||
if len(val.shape) < 2 or val.shape[1] != 2:
|
||||
raise PatternError('Vertices must be an Nx2 array')
|
||||
if val.shape[0] < 2:
|
||||
|
|
@ -218,7 +229,7 @@ class Path(Shape):
|
|||
Returns:
|
||||
The resulting Path object
|
||||
"""
|
||||
# TODO: needs testing
|
||||
# TODO: Path.travel() needs testing
|
||||
direction = numpy.array([1, 0])
|
||||
|
||||
verts = [numpy.zeros(2)]
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Polygon(Shape):
|
|||
implicitly-closed boundary, and an offset.
|
||||
|
||||
Note that the setter for `Polygon.vertices` may (but may not) create a copy of the
|
||||
passed vertex coordinates. See `numpy.array()` for details.
|
||||
passed vertex coordinates. See `numpy.array(..., copy=False)` for details.
|
||||
|
||||
A `normalized_form(...)` is available, but can be quite slow with lots of vertices.
|
||||
"""
|
||||
|
|
@ -36,12 +36,15 @@ class Polygon(Shape):
|
|||
def vertices(self) -> Any: # mypy#3004 NDArray[numpy.float64]:
|
||||
"""
|
||||
Vertices of the polygon (Nx2 ndarray: `[[x0, y0], [x1, y1], ...]`)
|
||||
|
||||
When setting, note that a copy of the provided vertices may or may not be made,
|
||||
following the rules from `numpy.array(.., copy=False)`.
|
||||
"""
|
||||
return self._vertices
|
||||
|
||||
@vertices.setter
|
||||
def vertices(self, val: ArrayLike) -> None:
|
||||
val = numpy.array(val, dtype=float) # note that this hopefully won't create a copy
|
||||
val = numpy.array(val, dtype=float)
|
||||
if len(val.shape) < 2 or val.shape[1] != 2:
|
||||
raise PatternError('Vertices must be an Nx2 array')
|
||||
if val.shape[0] < 3:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue