From 4796676a4e31e3585a38554d788792761245f157 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Tue, 22 Jun 2021 18:59:13 -0700 Subject: [PATCH] use ArrayLike when accepting pseudo-ndarrays --- masque/builder/devices.py | 5 +++-- masque/pattern.py | 5 +++-- masque/repetition.py | 9 +++++---- masque/shapes/path.py | 11 ++++++----- masque/shapes/polygon.py | 9 +++++---- masque/shapes/shape.py | 9 +++++---- masque/utils.py | 7 ++++--- 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/masque/builder/devices.py b/masque/builder/devices.py index 384c5a4..f2f3501 100644 --- a/masque/builder/devices.py +++ b/masque/builder/devices.py @@ -8,6 +8,7 @@ from collections import Counter import numpy # type: ignore from numpy import pi +from numpy.typing import ArrayLike from ..pattern import Pattern from ..subpattern import SubPattern @@ -48,7 +49,7 @@ class Port(PositionableImpl, Rotatable, PivotableImpl, Copyable, Mirrorable, met """ Port types must match to be plugged together if both are non-zero """ def __init__(self, - offset: numpy.ndarray, + offset: ArrayLike, rotation: Optional[float], ptype: str = 'unk', ) -> None: @@ -730,7 +731,7 @@ class Device(Copyable, Mirrorable): return s -def rotate_offsets_around(offsets: numpy.ndarray, pivot: numpy.ndarray, angle: float) -> numpy.ndarray: +def rotate_offsets_around(offsets: ArrayLike, pivot: ArrayLike, angle: float) -> numpy.ndarray: offsets -= pivot offsets[:] = (rotation_matrix_2d(angle) @ offsets.T).T offsets += pivot diff --git a/masque/pattern.py b/masque/pattern.py index 75173b9..030ca4f 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -11,6 +11,7 @@ from collections import defaultdict import numpy # type: ignore from numpy import inf +from numpy.typing import ArrayLike # .visualize imports matplotlib and matplotlib.collections from .subpattern import SubPattern @@ -333,8 +334,8 @@ class Pattern(LockableImpl, AnnotatableImpl, Mirrorable, metaclass=AutoSlots): return self def manhattanize(self: P, - grid_x: numpy.ndarray, - grid_y: numpy.ndarray, + grid_x: ArrayLike, + grid_y: ArrayLike, ) -> P: """ Calls `.polygonize()` and `.flatten()` on the pattern, then calls `.manhattanize()` on all the diff --git a/masque/repetition.py b/masque/repetition.py index 396d351..4bf289b 100644 --- a/masque/repetition.py +++ b/masque/repetition.py @@ -8,6 +8,7 @@ import copy from abc import ABCMeta, abstractmethod import numpy # type: ignore +from numpy.typing import ArrayLike from .error import PatternError from .utils import rotation_matrix_2d, vector2, AutoSlots @@ -61,9 +62,9 @@ class Grid(LockableImpl, Repetition, metaclass=AutoSlots): """ Number of instances along the direction specified by the `b_vector` """ def __init__(self, - a_vector: numpy.ndarray, + a_vector: ArrayLike, a_count: int, - b_vector: Optional[numpy.ndarray] = None, + b_vector: Optional[ArrayLike] = None, b_count: Optional[int] = 1, locked: bool = False,): """ @@ -303,13 +304,13 @@ class Arbitrary(LockableImpl, Repetition, metaclass=AutoSlots): return self._displacements @displacements.setter - def displacements(self, val: Union[Sequence[Sequence[float]], numpy.ndarray]): + def displacements(self, val: ArrayLike): val = numpy.array(val, float) val = numpy.sort(val.view([('', val.dtype)] * val.shape[1]), 0).view(val.dtype) # sort rows self._displacements = val def __init__(self, - displacements: numpy.ndarray, + displacements: ArrayLike, locked: bool = False,): """ Args: diff --git a/masque/shapes/path.py b/masque/shapes/path.py index 1cad032..1d64ca2 100644 --- a/masque/shapes/path.py +++ b/masque/shapes/path.py @@ -4,6 +4,7 @@ from enum import Enum import numpy # type: ignore from numpy import pi, inf +from numpy.typing import ArrayLike from . import Shape, normalized_shape_tuple, Polygon, Circle from .. import PatternError @@ -102,7 +103,7 @@ class Path(Shape, metaclass=AutoSlots): return self._vertices @vertices.setter - def vertices(self, val: numpy.ndarray): + def vertices(self, val: ArrayLike): val = numpy.array(val, dtype=float) # TODO document that these might not be copied if len(val.shape) < 2 or val.shape[1] != 2: raise PatternError('Vertices must be an Nx2 array') @@ -119,7 +120,7 @@ class Path(Shape, metaclass=AutoSlots): return self.vertices[:, 0] @xs.setter - def xs(self, val: numpy.ndarray): + def xs(self, val: ArrayLike): val = numpy.array(val, dtype=float).flatten() if val.size != self.vertices.shape[0]: raise PatternError('Wrong number of vertices') @@ -134,18 +135,18 @@ class Path(Shape, metaclass=AutoSlots): return self.vertices[:, 1] @ys.setter - def ys(self, val: numpy.ndarray): + def ys(self, val: ArrayLike): val = numpy.array(val, dtype=float).flatten() if val.size != self.vertices.shape[0]: raise PatternError('Wrong number of vertices') self.vertices[:, 1] = val def __init__(self, - vertices: numpy.ndarray, + vertices: ArrayLike, width: float = 0.0, *, cap: PathCap = PathCap.Flush, - cap_extensions: numpy.ndarray = None, + cap_extensions: Optional[ArrayLike] = None, offset: vector2 = (0.0, 0.0), rotation: float = 0, mirrored: Sequence[bool] = (False, False), diff --git a/masque/shapes/polygon.py b/masque/shapes/polygon.py index 4b2c37c..6bfa4b3 100644 --- a/masque/shapes/polygon.py +++ b/masque/shapes/polygon.py @@ -3,6 +3,7 @@ import copy import numpy # type: ignore from numpy import pi +from numpy.typing import ArrayLike from . import Shape, normalized_shape_tuple from .. import PatternError @@ -33,7 +34,7 @@ class Polygon(Shape, metaclass=AutoSlots): return self._vertices @vertices.setter - def vertices(self, val: numpy.ndarray): + def vertices(self, val: ArrayLike): val = numpy.array(val, dtype=float) # TODO document that these might not be copied if len(val.shape) < 2 or val.shape[1] != 2: raise PatternError('Vertices must be an Nx2 array') @@ -50,7 +51,7 @@ class Polygon(Shape, metaclass=AutoSlots): return self.vertices[:, 0] @xs.setter - def xs(self, val: numpy.ndarray): + def xs(self, val: ArrayLike): val = numpy.array(val, dtype=float).flatten() if val.size != self.vertices.shape[0]: raise PatternError('Wrong number of vertices') @@ -65,14 +66,14 @@ class Polygon(Shape, metaclass=AutoSlots): return self.vertices[:, 1] @ys.setter - def ys(self, val: numpy.ndarray): + def ys(self, val: ArrayLike): val = numpy.array(val, dtype=float).flatten() if val.size != self.vertices.shape[0]: raise PatternError('Wrong number of vertices') self.vertices[:, 1] = val def __init__(self, - vertices: numpy.ndarray, + vertices: ArrayLike, *, offset: vector2 = (0.0, 0.0), rotation: float = 0.0, diff --git a/masque/shapes/shape.py b/masque/shapes/shape.py index 0603ec7..8dcf465 100644 --- a/masque/shapes/shape.py +++ b/masque/shapes/shape.py @@ -2,6 +2,7 @@ from typing import List, Tuple, Callable, TypeVar, Optional, TYPE_CHECKING from abc import ABCMeta, abstractmethod import numpy # type: ignore +from numpy.typing import ArrayLike from ..traits import (PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable, Copyable, Scalable, @@ -93,8 +94,8 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable ---- Non-abstract methods ''' def manhattanize_fast(self, - grid_x: numpy.ndarray, - grid_y: numpy.ndarray, + grid_x: ArrayLike, + grid_y: ArrayLike, ) -> List['Polygon']: """ Returns a list of polygons with grid-aligned ("Manhattan") edges approximating the shape. @@ -200,8 +201,8 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable return manhattan_polygons def manhattanize(self, - grid_x: numpy.ndarray, - grid_y: numpy.ndarray + grid_x: ArrayLike, + grid_y: ArrayLike, ) -> List['Polygon']: """ Returns a list of polygons with grid-aligned ("Manhattan") edges approximating the shape. diff --git a/masque/utils.py b/masque/utils.py index 9588ee6..7b4cc2a 100644 --- a/masque/utils.py +++ b/masque/utils.py @@ -5,10 +5,11 @@ from typing import Any, Union, Tuple, Sequence, Dict, List from abc import ABCMeta import numpy # type: ignore +from numpy.typing import ArrayLike # Type definitions -vector2 = Union[numpy.ndarray, Tuple[float, float], Sequence[float]] +vector2 = ArrayLike layer_t = Union[int, Tuple[int, int], str] annotations_t = Dict[str, List[Union[int, float, str]]] @@ -89,7 +90,7 @@ def normalize_mirror(mirrored: Sequence[bool]) -> Tuple[bool, float]: return mirror_x, angle -def remove_duplicate_vertices(vertices: numpy.ndarray, closed_path: bool = True) -> numpy.ndarray: +def remove_duplicate_vertices(vertices: ArrayLike, closed_path: bool = True) -> numpy.ndarray: """ Given a list of vertices, remove any consecutive duplicates. @@ -107,7 +108,7 @@ def remove_duplicate_vertices(vertices: numpy.ndarray, closed_path: bool = True) return vertices[~duplicates] -def remove_colinear_vertices(vertices: numpy.ndarray, closed_path: bool = True) -> numpy.ndarray: +def remove_colinear_vertices(vertices: ArrayLike, closed_path: bool = True) -> numpy.ndarray: """ Given a list of vertices, remove any superflous vertices (i.e. those which lie along the line formed by their neighbors)