From 8edb7b0956c4299dd538af7ba365fdcd432cfb96 Mon Sep 17 00:00:00 2001 From: jan Date: Thu, 7 Jul 2022 16:06:06 -0700 Subject: [PATCH] round().astype() -> rint(...) --- masque/file/gdsii.py | 2 +- masque/file/oasis.py | 15 ++++++---- masque/file/python_gdsii.py | 57 +++++++++++++++++++++++-------------- masque/shapes/shape.py | 4 +-- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/masque/file/gdsii.py b/masque/file/gdsii.py index df5cf99..6bd4d1a 100644 --- a/masque/file/gdsii.py +++ b/masque/file/gdsii.py @@ -31,7 +31,7 @@ import pathlib import gzip import numpy -from numpy.typing import NDArray +from numpy.typing import NDArray, ArrayLike import klamath from klamath import records diff --git a/masque/file/oasis.py b/masque/file/oasis.py index ede49a0..27c8b71 100644 --- a/masque/file/oasis.py +++ b/masque/file/oasis.py @@ -670,15 +670,20 @@ def repetition_masq2fata( Tuple[int, int]]: frep: Union[fatamorgana.GridRepetition, fatamorgana.ArbitraryRepetition, None] if isinstance(rep, Grid): + a_vector = rint_cast(rep.a_vector) + b_vector = rint_cast(rep.b_vector) if rep.b_vector is not None else None + a_count = rint_cast(rep.a_count) + b_count = rint_cast(rep.b_count) if rep.b_count is not None else None frep = fatamorgana.GridRepetition( - a_vector=numpy.round(rep.a_vector).astype(int), - b_vector=numpy.round(rep.b_vector).astype(int), - a_count=numpy.round(rep.a_count).astype(int), - b_count=numpy.round(rep.b_count).astype(int)) + a_vector=a_vector, + b_vector=b_vector, + a_count=a_count, + b_count=b_count, + ) offset = (0, 0) elif isinstance(rep, Arbitrary): diffs = numpy.diff(rep.displacements, axis=0) - diff_ints = numpy.round(diffs).astype(int) + diff_ints = rint_cast(diffs) frep = fatamorgana.ArbitraryRepetition(diff_ints[:, 0], diff_ints[:, 1]) offset = rep.displacements[0, :] else: diff --git a/masque/file/python_gdsii.py b/masque/file/python_gdsii.py index b929a5b..6b89abc 100644 --- a/masque/file/python_gdsii.py +++ b/masque/file/python_gdsii.py @@ -29,7 +29,7 @@ import pathlib import gzip import numpy -from numpy.typing import ArrayLike, NDArray +from numpy.typing import NDArray, ArrayLike # python-gdsii import gdsii.library #type: ignore import gdsii.structure #type: ignore @@ -54,6 +54,10 @@ path_cap_map = { } +def rint_cast(val: ArrayLike) -> NDArray[numpy.int32]: + return numpy.rint(val, dtype=numpy.int32, casting='unsafe') + + def build( patterns: Union[Pattern, Sequence[Pattern]], meters_per_unit: float, @@ -409,18 +413,24 @@ def _subpatterns_to_refs( rep.a_vector * rep.a_count, b_vector * b_count, ] - ref = gdsii.elements.ARef(struct_name=encoded_name, - xy=numpy.round(xy).astype(int), - cols=numpy.round(rep.a_count).astype(int), - rows=numpy.round(rep.b_count).astype(int)) + ref = gdsii.elements.ARef( + struct_name=encoded_name, + xy=rint_cast(xy), + cols=rint_cast(rep.a_count), + rows=rint_cast(rep.b_count), + ) new_refs = [ref] elif rep is None: - ref = gdsii.elements.SRef(struct_name=encoded_name, - xy=numpy.round([subpat.offset]).astype(int)) + ref = gdsii.elements.SRef( + struct_name=encoded_name, + xy=rint_cast([subpat.offset]), + ) new_refs = [ref] else: - new_refs = [gdsii.elements.SRef(struct_name=encoded_name, - xy=numpy.round([subpat.offset + dd]).astype(int)) + new_refs = [gdsii.elements.SRef( + struct_name=encoded_name, + xy=rint_cast([subpat.offset + dd]), + ) for dd in rep.displacements] for ref in new_refs: @@ -470,8 +480,8 @@ def _shapes_to_elements( layer, data_type = _mlayer2gds(shape.layer) properties = _annotations_to_properties(shape.annotations, 128) if isinstance(shape, Path) and not polygonize_paths: - xy = numpy.round(shape.vertices + shape.offset).astype(int) - width = numpy.round(shape.width).astype(int) + xy = rint_cast(shape.vertices + shape.offset) + width = rint_cast(shape.width) path_type = next(k for k, v in path_cap_map.items() if v == shape.cap) # reverse lookup path = gdsii.elements.Path(layer=layer, data_type=data_type, @@ -482,11 +492,14 @@ def _shapes_to_elements( elements.append(path) else: for polygon in shape.to_polygons(): - xy_open = numpy.round(polygon.vertices + polygon.offset).astype(int) - xy_closed = numpy.vstack((xy_open, xy_open[0, :])) - boundary = gdsii.elements.Boundary(layer=layer, - data_type=data_type, - xy=xy_closed) + xy_closed = numpy.empty((polygon.vertices.shape[0] + 1, 2), dtype=numpy.int32) + numpy.rint(polygon.vertices + polygon.offset, out=xy_closed[:-1], casting='unsafe') + xy_closed[-1] = xy_closed[0] + boundary = gdsii.elements.Boundary( + layer=layer, + data_type=data_type, + xy=xy_closed, + ) boundary.properties = properties elements.append(boundary) return elements @@ -497,11 +510,13 @@ def _labels_to_texts(labels: List[Label]) -> List[gdsii.elements.Text]: for label in labels: properties = _annotations_to_properties(label.annotations, 128) layer, text_type = _mlayer2gds(label.layer) - xy = numpy.round([label.offset]).astype(int) - text = gdsii.elements.Text(layer=layer, - text_type=text_type, - xy=xy, - string=label.string.encode('ASCII')) + xy = rint_cast([label.offset]) + text = gdsii.elements.Text( + layer=layer, + text_type=text_type, + xy=xy, + string=label.string.encode('ASCII'), + ) text.properties = properties texts.append(text) return texts diff --git a/masque/shapes/shape.py b/masque/shapes/shape.py index a188ef5..c0a2baa 100644 --- a/masque/shapes/shape.py +++ b/masque/shapes/shape.py @@ -182,7 +182,7 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable xs2 = (xs[:-1] + xs[1:]) / 2 inds2 = get_grid_inds(xs2) - xinds = numpy.round(numpy.arange(gxi_min, gxi_max - 0.99, 1 / 3)).astype(int) + xinds = numpy.rint(numpy.arange(gxi_min, gxi_max - 0.99, 1 / 3), dtype=numpy.int64, casting='unsafe') # interleave the results yinds = xinds.copy() @@ -293,7 +293,7 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable for contour in contours: # /2 deals with supersampling # +.5 deals with the fact that our 0-edge becomes -.5 in the super-sampled contour output - snapped_contour = numpy.round((contour + .5) / 2).astype(int) + snapped_contour = numpy.rint((contour + .5) / 2, dtype=numpy.int64, casting='unsafe') vertices = numpy.hstack((grx[snapped_contour[:, None, 0] + offset_i[0]], gry[snapped_contour[:, None, 1] + offset_i[1]]))