You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fatamorgana/fatamorgana/test/test_files_ctrapezoids.py

248 lines
8.0 KiB
Python

# type: ignore
from typing import List, Tuple, Iterable
from itertools import chain
from io import BytesIO, BufferedIOBase
import struct
import pytest # type: ignore
import numpy
from numpy.testing import assert_equal
from .utils import HEADER, FOOTER
from ..basic import write_uint, write_sint, read_uint, read_sint, write_bstring, write_byte, PathExtensionScheme
from ..basic import InvalidRecordError, InvalidDataError
from ..main import OasisLayout
def base_tests(layout: OasisLayout) -> None:
assert layout.version.string == '1.0'
assert layout.unit == 1000
assert layout.validation.checksum_type == 0
assert not layout.properties
assert not layout.propnames
assert not layout.xnames
assert not layout.textstrings
assert not layout.cellnames
assert not layout.layers
def write_file_1(buf: BufferedIOBase) -> BufferedIOBase:
'''
'''
buf.write(HEADER)
write_uint(buf, 14) # CELL record (explicit)
write_bstring(buf, b'A') # Cell name
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b1111_1011) # TWHX_YRDL
write_uint(buf, 1) # layer
write_uint(buf, 2) # datatype
write_uint(buf, 24) # ctrapezoid type
write_uint(buf, 100) # width
write_uint(buf, 200) # height
write_sint(buf, -100) # geometry-x (absolute)
write_sint(buf, 200) # geometry-y (absolute)
write_uint(buf, 16) # XYRELATIVE record
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b0000_1000) # TWHX_YRDL
write_sint(buf, 400) # geometry-y (relative)
write_uint(buf, 20) # RECTANGLE record
write_byte(buf, 0b0000_0011) # SWHX_YRDL
write_uint(buf, 2) # layer
write_uint(buf, 3) # datatype
h = [250, 100]
v = [100, 250]
wh = [h] * 8 + [v] * 8 + [h] * 6 + [v] * 2 + [h] * 2
wh_en = ([0b11] * 16
+ [0b10] * 4
+ [0b01] * 2
+ [0b10] * 2
+ [0b11, 0b10])
for t, (x, x_en) in enumerate(zip(wh, wh_en)):
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b1000_1011 | (x_en << 5)) # TWHX_YRDL
write_uint(buf, 1) # layer
write_uint(buf, 2) # datatype
write_uint(buf, t) # ctrapezoid type
if x_en & 0b10:
write_uint(buf, x[0]) # width
if x_en & 0b01:
write_uint(buf, x[1]) # height
write_sint(buf, 400) # geometry-y (relative)
write_uint(buf, 20) # RECTANGLE record
write_byte(buf, 0b0000_0011) # SWHX_YRDL
write_uint(buf, 2) # layer
write_uint(buf, 3) # datatype
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b0000_1100) # TWHX_YRDL
write_sint(buf, 400) # geometry-y (relative)
write_uint(buf, 1) # repetition (3x4 matrix)
write_uint(buf, 1) # (repetition) x-dimension
write_uint(buf, 2) # (repetition) y-dimension
write_uint(buf, 400) # (repetition) x-spacing
write_uint(buf, 300) # (repetition) y-spacing
buf.write(FOOTER)
return buf
def test_file_1() -> None:
buf = write_file_1(BytesIO())
buf.seek(0)
layout = OasisLayout.read(buf)
base_tests(layout)
assert len(layout.cells) == 1
assert layout.cells[0].name.string == 'A'
assert not layout.cells[0].properties
geometry = layout.cells[0].geometry
assert len(geometry) == 3 + 26 * 2 + 1
for ii, gg in enumerate(geometry):
msg = f'Failed on shape {ii}'
assert gg.x == -100, msg
assert gg.y == 200 + 400 * ((ii + 1) // 2), msg
if ii < 2 or (3 <= ii < 55 and ii % 2 == 1):
assert gg.layer == 1, msg
assert gg.datatype == 2, msg
else:
assert gg.layer == 2, msg
assert gg.datatype == 3, msg
if ii < 3:
assert gg.width == 100, msg
assert gg.height == 200, msg
assert not gg.properties, msg
if 3 <= ii < 55:
ct_type = (ii - 3) // 2
is_ctrapz = ii % 2 == 1
if is_ctrapz:
assert gg.ctrapezoid_type == ct_type, msg
if ct_type in range(16, 20):
assert gg.height == [250, None][is_ctrapz], msg
elif ct_type in (20, 21):
assert gg.width == [250, None][is_ctrapz], msg
elif ct_type in range(22, 24) or ct_type == 25:
assert gg.height == [100, None][is_ctrapz], msg
else:
if ct_type < 8 or 16 <= ct_type < 25 or 26 <= ct_type :
assert gg.width == 250, msg
assert gg.height == 100, msg
else:
assert gg.width == 100, msg
assert gg.height == 250, msg
elif ii < 3 and ii % 2:
assert gg.ctrapezoid_type == 24, msg
elif ii == 55:
assert gg.ctrapezoid_type == 25, msg
assert geometry[55].repetition.a_count == 3
assert geometry[55].repetition.b_count == 4
assert geometry[55].repetition.a_vector == [400, 0]
assert geometry[55].repetition.b_vector == [0, 300]
def write_file_2(buf: BufferedIOBase) -> BufferedIOBase:
'''
'''
buf.write(HEADER)
write_uint(buf, 14) # CELL record (explicit)
write_bstring(buf, b'A') # Cell name
# Shouldn't access (undefined) height modal, despite not having a height.
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b1101_1011) # TWHX_YRDL
write_uint(buf, 1) # layer
write_uint(buf, 2) # datatype
write_uint(buf, 16) # ctrapezoid type
write_uint(buf, 200) # width
write_sint(buf, -100) # geometry-x (absolute)
write_sint(buf, 200) # geometry-y (absolute)
write_uint(buf, 16) # XYRELATIVE record
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b0000_1000) # TWHX_YRDL
write_sint(buf, 400) # geometry-y (relative)
write_uint(buf, 14) # CELL record (explicit)
write_bstring(buf, b'B') # Cell name
# Shouldn't access (undefined) width modal, despite not having a width.
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b1011_1011) # TWHX_YRDL
write_uint(buf, 1) # layer
write_uint(buf, 2) # datatype
write_uint(buf, 20) # ctrapezoid type
write_uint(buf, 200) # height
write_sint(buf, -100) # geometry-x (absolute)
write_sint(buf, 200) # geometry-y (absolute)
write_uint(buf, 16) # XYRELATIVE record
write_uint(buf, 26) # CTRAPEZOID record
write_byte(buf, 0b0000_1000) # TWHX_YRDL
write_sint(buf, 400) # geometry-y (relative)
buf.write(FOOTER)
return buf
def test_file_2() -> None:
buf = write_file_2(BytesIO())
buf.seek(0)
layout = OasisLayout.read(buf)
base_tests(layout)
assert len(layout.cells) == 2
assert layout.cells[0].name.string == 'A'
assert layout.cells[1].name.string == 'B'
assert not layout.cells[0].properties
assert not layout.cells[1].properties
for ii, cc in enumerate(layout.cells):
for jj, gg in enumerate(cc.geometry):
msg = f'Fail in cell {ii}, ctrapezoid {jj}'
assert not gg.properties, msg
assert gg.layer == 1, msg
assert gg.datatype == 2, msg
assert gg.x == -100, msg
geometry = layout.cells[0].geometry
assert geometry[0].width == 200
assert geometry[1].width == 200
assert geometry[0].ctrapezoid_type == 16
assert geometry[1].ctrapezoid_type == 16
assert geometry[0].y == 200
assert geometry[1].y == 600
geometry = layout.cells[1].geometry
assert geometry[0].height == 200
assert geometry[1].height == 200
assert geometry[0].ctrapezoid_type == 20
assert geometry[1].ctrapezoid_type == 20
assert geometry[0].y == 200
assert geometry[1].y == 600