round().astype() -> rint(...)

This commit is contained in:
jan 2022-07-07 16:06:06 -07:00
parent 79d0373eeb
commit 8edb7b0956
4 changed files with 49 additions and 29 deletions

View File

@ -31,7 +31,7 @@ import pathlib
import gzip import gzip
import numpy import numpy
from numpy.typing import NDArray from numpy.typing import NDArray, ArrayLike
import klamath import klamath
from klamath import records from klamath import records

View File

@ -670,15 +670,20 @@ def repetition_masq2fata(
Tuple[int, int]]: Tuple[int, int]]:
frep: Union[fatamorgana.GridRepetition, fatamorgana.ArbitraryRepetition, None] frep: Union[fatamorgana.GridRepetition, fatamorgana.ArbitraryRepetition, None]
if isinstance(rep, Grid): 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( frep = fatamorgana.GridRepetition(
a_vector=numpy.round(rep.a_vector).astype(int), a_vector=a_vector,
b_vector=numpy.round(rep.b_vector).astype(int), b_vector=b_vector,
a_count=numpy.round(rep.a_count).astype(int), a_count=a_count,
b_count=numpy.round(rep.b_count).astype(int)) b_count=b_count,
)
offset = (0, 0) offset = (0, 0)
elif isinstance(rep, Arbitrary): elif isinstance(rep, Arbitrary):
diffs = numpy.diff(rep.displacements, axis=0) 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]) frep = fatamorgana.ArbitraryRepetition(diff_ints[:, 0], diff_ints[:, 1])
offset = rep.displacements[0, :] offset = rep.displacements[0, :]
else: else:

View File

@ -29,7 +29,7 @@ import pathlib
import gzip import gzip
import numpy import numpy
from numpy.typing import ArrayLike, NDArray from numpy.typing import NDArray, ArrayLike
# python-gdsii # python-gdsii
import gdsii.library #type: ignore import gdsii.library #type: ignore
import gdsii.structure #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( def build(
patterns: Union[Pattern, Sequence[Pattern]], patterns: Union[Pattern, Sequence[Pattern]],
meters_per_unit: float, meters_per_unit: float,
@ -409,18 +413,24 @@ def _subpatterns_to_refs(
rep.a_vector * rep.a_count, rep.a_vector * rep.a_count,
b_vector * b_count, b_vector * b_count,
] ]
ref = gdsii.elements.ARef(struct_name=encoded_name, ref = gdsii.elements.ARef(
xy=numpy.round(xy).astype(int), struct_name=encoded_name,
cols=numpy.round(rep.a_count).astype(int), xy=rint_cast(xy),
rows=numpy.round(rep.b_count).astype(int)) cols=rint_cast(rep.a_count),
rows=rint_cast(rep.b_count),
)
new_refs = [ref] new_refs = [ref]
elif rep is None: elif rep is None:
ref = gdsii.elements.SRef(struct_name=encoded_name, ref = gdsii.elements.SRef(
xy=numpy.round([subpat.offset]).astype(int)) struct_name=encoded_name,
xy=rint_cast([subpat.offset]),
)
new_refs = [ref] new_refs = [ref]
else: else:
new_refs = [gdsii.elements.SRef(struct_name=encoded_name, new_refs = [gdsii.elements.SRef(
xy=numpy.round([subpat.offset + dd]).astype(int)) struct_name=encoded_name,
xy=rint_cast([subpat.offset + dd]),
)
for dd in rep.displacements] for dd in rep.displacements]
for ref in new_refs: for ref in new_refs:
@ -470,8 +480,8 @@ def _shapes_to_elements(
layer, data_type = _mlayer2gds(shape.layer) layer, data_type = _mlayer2gds(shape.layer)
properties = _annotations_to_properties(shape.annotations, 128) properties = _annotations_to_properties(shape.annotations, 128)
if isinstance(shape, Path) and not polygonize_paths: if isinstance(shape, Path) and not polygonize_paths:
xy = numpy.round(shape.vertices + shape.offset).astype(int) xy = rint_cast(shape.vertices + shape.offset)
width = numpy.round(shape.width).astype(int) width = rint_cast(shape.width)
path_type = next(k for k, v in path_cap_map.items() if v == shape.cap) # reverse lookup path_type = next(k for k, v in path_cap_map.items() if v == shape.cap) # reverse lookup
path = gdsii.elements.Path(layer=layer, path = gdsii.elements.Path(layer=layer,
data_type=data_type, data_type=data_type,
@ -482,11 +492,14 @@ def _shapes_to_elements(
elements.append(path) elements.append(path)
else: else:
for polygon in shape.to_polygons(): for polygon in shape.to_polygons():
xy_open = numpy.round(polygon.vertices + polygon.offset).astype(int) xy_closed = numpy.empty((polygon.vertices.shape[0] + 1, 2), dtype=numpy.int32)
xy_closed = numpy.vstack((xy_open, xy_open[0, :])) numpy.rint(polygon.vertices + polygon.offset, out=xy_closed[:-1], casting='unsafe')
boundary = gdsii.elements.Boundary(layer=layer, xy_closed[-1] = xy_closed[0]
data_type=data_type, boundary = gdsii.elements.Boundary(
xy=xy_closed) layer=layer,
data_type=data_type,
xy=xy_closed,
)
boundary.properties = properties boundary.properties = properties
elements.append(boundary) elements.append(boundary)
return elements return elements
@ -497,11 +510,13 @@ def _labels_to_texts(labels: List[Label]) -> List[gdsii.elements.Text]:
for label in labels: for label in labels:
properties = _annotations_to_properties(label.annotations, 128) properties = _annotations_to_properties(label.annotations, 128)
layer, text_type = _mlayer2gds(label.layer) layer, text_type = _mlayer2gds(label.layer)
xy = numpy.round([label.offset]).astype(int) xy = rint_cast([label.offset])
text = gdsii.elements.Text(layer=layer, text = gdsii.elements.Text(
text_type=text_type, layer=layer,
xy=xy, text_type=text_type,
string=label.string.encode('ASCII')) xy=xy,
string=label.string.encode('ASCII'),
)
text.properties = properties text.properties = properties
texts.append(text) texts.append(text)
return texts return texts

View File

@ -182,7 +182,7 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable
xs2 = (xs[:-1] + xs[1:]) / 2 xs2 = (xs[:-1] + xs[1:]) / 2
inds2 = get_grid_inds(xs2) 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 # interleave the results
yinds = xinds.copy() yinds = xinds.copy()
@ -293,7 +293,7 @@ class Shape(PositionableImpl, LayerableImpl, DoseableImpl, Rotatable, Mirrorable
for contour in contours: for contour in contours:
# /2 deals with supersampling # /2 deals with supersampling
# +.5 deals with the fact that our 0-edge becomes -.5 in the super-sampled contour output # +.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]], vertices = numpy.hstack((grx[snapped_contour[:, None, 0] + offset_i[0]],
gry[snapped_contour[:, None, 1] + offset_i[1]])) gry[snapped_contour[:, None, 1] + offset_i[1]]))