masque/masque/test/test_gdsii.py

71 lines
2.2 KiB
Python

from pathlib import Path
from typing import cast
import numpy
from numpy.testing import assert_equal, assert_allclose
from ..pattern import Pattern
from ..library import Library
from ..file import gdsii
from ..shapes import Path as MPath, Polygon
def test_gdsii_roundtrip(tmp_path: Path) -> None:
lib = Library()
# Simple polygon cell
pat1 = Pattern()
pat1.polygon((1, 0), vertices=[[0, 0], [10, 0], [10, 10], [0, 10]])
lib["poly_cell"] = pat1
# Path cell
pat2 = Pattern()
pat2.path((2, 5), vertices=[[0, 0], [100, 0]], width=10)
lib["path_cell"] = pat2
# Cell with Ref
pat3 = Pattern()
pat3.ref("poly_cell", offset=(50, 50), rotation=numpy.pi / 2)
lib["ref_cell"] = pat3
gds_file = tmp_path / "test.gds"
gdsii.writefile(lib, gds_file, meters_per_unit=1e-9)
read_lib, info = gdsii.readfile(gds_file)
assert "poly_cell" in read_lib
assert "path_cell" in read_lib
assert "ref_cell" in read_lib
# Check polygon
read_poly = cast("Polygon", read_lib["poly_cell"].shapes[(1, 0)][0])
# GDSII closes polygons, so it might have an extra vertex or different order
assert len(read_poly.vertices) >= 4
# Check bounds as a proxy for geometry correctness
assert_equal(read_lib["poly_cell"].get_bounds(), [[0, 0], [10, 10]])
# Check path
read_path = cast("MPath", read_lib["path_cell"].shapes[(2, 5)][0])
assert isinstance(read_path, MPath)
assert read_path.width == 10
assert_equal(read_path.vertices, [[0, 0], [100, 0]])
# Check Ref
read_ref = read_lib["ref_cell"].refs["poly_cell"][0]
assert_equal(read_ref.offset, [50, 50])
assert_allclose(read_ref.rotation, numpy.pi / 2, atol=1e-5)
def test_gdsii_annotations(tmp_path: Path) -> None:
lib = Library()
pat = Pattern()
# GDS only supports integer keys in range [1, 126] for properties
pat.polygon((1, 0), vertices=[[0, 0], [1, 0], [1, 1]], annotations={"1": ["hello"]})
lib["cell"] = pat
gds_file = tmp_path / "test_ann.gds"
gdsii.writefile(lib, gds_file, meters_per_unit=1e-9)
read_lib, _ = gdsii.readfile(gds_file)
read_ann = read_lib["cell"].shapes[(1, 0)][0].annotations
assert read_ann is not None
assert read_ann["1"] == ["hello"]