lots of fixes to get test_rep running
This commit is contained in:
		
							parent
							
								
									92f7fce6ff
								
							
						
					
					
						commit
						b75c8de0c4
					
				| @ -1,103 +1,135 @@ | ||||
| from pprint import pprint | ||||
| from pathlib import Path | ||||
| 
 | ||||
| import numpy | ||||
| from numpy import pi | ||||
| 
 | ||||
| import masque | ||||
| import masque.file.gdsii | ||||
| import masque.file.klamath | ||||
| import masque.file.dxf | ||||
| import masque.file.oasis | ||||
| from masque import shapes, Pattern, SubPattern | ||||
| from masque import Pattern, Ref, Arc, WrapLibrary | ||||
| from masque.repetition import Grid | ||||
| from masque.file import gdsii, dxf, oasis | ||||
| 
 | ||||
| from pprint import pprint | ||||
| 
 | ||||
| 
 | ||||
| def main(): | ||||
|     pat = masque.Pattern(name='ellip_grating') | ||||
|     lib = WrapLibrary() | ||||
| 
 | ||||
|     cell_name = 'ellip_grating' | ||||
|     pat = masque.Pattern() | ||||
|     for rmin in numpy.arange(10, 15, 0.5): | ||||
|         pat.shapes.append(shapes.Arc( | ||||
|         pat.shapes.append(Arc( | ||||
|             radii=(rmin, rmin), | ||||
|             width=0.1, | ||||
|             angles=(0*-numpy.pi/4, numpy.pi/4), | ||||
|             angles=(0 * -pi/4, pi/4), | ||||
|             annotations={'1': ['blah']}, | ||||
|             )) | ||||
| 
 | ||||
|     pat.scale_by(1000) | ||||
| #    pat.visualize() | ||||
|     pat2 = pat.copy() | ||||
|     pat2.name = 'grating2' | ||||
| 
 | ||||
|     pat3 = Pattern('sref_test') | ||||
|     pat3.subpatterns = [ | ||||
|         SubPattern(pat, offset=(1e5, 3e5), annotations={'4': ['Hello I am the base subpattern']}), | ||||
|         SubPattern(pat, offset=(2e5, 3e5), rotation=pi/3), | ||||
|         SubPattern(pat, offset=(3e5, 3e5), rotation=pi/2), | ||||
|         SubPattern(pat, offset=(4e5, 3e5), rotation=pi), | ||||
|         SubPattern(pat, offset=(5e5, 3e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, mirrored=(True, False), offset=(1e5, 4e5)), | ||||
|         SubPattern(pat, mirrored=(True, False), offset=(2e5, 4e5), rotation=pi/3), | ||||
|         SubPattern(pat, mirrored=(True, False), offset=(3e5, 4e5), rotation=pi/2), | ||||
|         SubPattern(pat, mirrored=(True, False), offset=(4e5, 4e5), rotation=pi), | ||||
|         SubPattern(pat, mirrored=(True, False), offset=(5e5, 4e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, mirrored=(False, True), offset=(1e5, 5e5)), | ||||
|         SubPattern(pat, mirrored=(False, True), offset=(2e5, 5e5), rotation=pi/3), | ||||
|         SubPattern(pat, mirrored=(False, True), offset=(3e5, 5e5), rotation=pi/2), | ||||
|         SubPattern(pat, mirrored=(False, True), offset=(4e5, 5e5), rotation=pi), | ||||
|         SubPattern(pat, mirrored=(False, True), offset=(5e5, 5e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, mirrored=(True, True), offset=(1e5, 6e5)), | ||||
|         SubPattern(pat, mirrored=(True, True), offset=(2e5, 6e5), rotation=pi/3), | ||||
|         SubPattern(pat, mirrored=(True, True), offset=(3e5, 6e5), rotation=pi/2), | ||||
|         SubPattern(pat, mirrored=(True, True), offset=(4e5, 6e5), rotation=pi), | ||||
|         SubPattern(pat, mirrored=(True, True), offset=(5e5, 6e5), rotation=3*pi/2), | ||||
|         ] | ||||
| 
 | ||||
|     pprint(pat3) | ||||
|     pprint(pat3.subpatterns) | ||||
|     lib[cell_name] = pat | ||||
|     print(f'\nAdded {cell_name}:') | ||||
|     pprint(pat.shapes) | ||||
| 
 | ||||
|     rep = Grid(a_vector=[1e4, 0], | ||||
|                b_vector=[0, 1.5e4], | ||||
|                a_count=3, | ||||
|                b_count=2,) | ||||
|     pat4 = Pattern('aref_test') | ||||
|     pat4.subpatterns = [ | ||||
|         SubPattern(pat, repetition=rep, offset=(1e5, 3e5)), | ||||
|         SubPattern(pat, repetition=rep, offset=(2e5, 3e5), rotation=pi/3), | ||||
|         SubPattern(pat, repetition=rep, offset=(3e5, 3e5), rotation=pi/2), | ||||
|         SubPattern(pat, repetition=rep, offset=(4e5, 3e5), rotation=pi), | ||||
|         SubPattern(pat, repetition=rep, offset=(5e5, 3e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, False), offset=(1e5, 4e5)), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, False), offset=(2e5, 4e5), rotation=pi/3), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, False), offset=(3e5, 4e5), rotation=pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, False), offset=(4e5, 4e5), rotation=pi), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, False), offset=(5e5, 4e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(False, True), offset=(1e5, 5e5)), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(False, True), offset=(2e5, 5e5), rotation=pi/3), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(False, True), offset=(3e5, 5e5), rotation=pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(False, True), offset=(4e5, 5e5), rotation=pi), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(False, True), offset=(5e5, 5e5), rotation=3*pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, True), offset=(1e5, 6e5)), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, True), offset=(2e5, 6e5), rotation=pi/3), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, True), offset=(3e5, 6e5), rotation=pi/2), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, True), offset=(4e5, 6e5), rotation=pi), | ||||
|         SubPattern(pat, repetition=rep, mirrored=(True, True), offset=(5e5, 6e5), rotation=3*pi/2), | ||||
|     new_name = lib.get_name(cell_name) | ||||
|     lib[new_name] = pat.copy() | ||||
|     print(f'\nAdded a copy of {cell_name} as {new_name}') | ||||
| 
 | ||||
|     pat3 = Pattern() | ||||
|     pat3.refs = [ | ||||
|         Ref(cell_name, offset=(1e5, 3e5), annotations={'4': ['Hello I am the base Ref']}), | ||||
|         Ref(cell_name, offset=(2e5, 3e5), rotation=pi/3), | ||||
|         Ref(cell_name, offset=(3e5, 3e5), rotation=pi/2), | ||||
|         Ref(cell_name, offset=(4e5, 3e5), rotation=pi), | ||||
|         Ref(cell_name, offset=(5e5, 3e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, mirrored=(True, False), offset=(1e5, 4e5)), | ||||
|         Ref(cell_name, mirrored=(True, False), offset=(2e5, 4e5), rotation=pi/3), | ||||
|         Ref(cell_name, mirrored=(True, False), offset=(3e5, 4e5), rotation=pi/2), | ||||
|         Ref(cell_name, mirrored=(True, False), offset=(4e5, 4e5), rotation=pi), | ||||
|         Ref(cell_name, mirrored=(True, False), offset=(5e5, 4e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, mirrored=(False, True), offset=(1e5, 5e5)), | ||||
|         Ref(cell_name, mirrored=(False, True), offset=(2e5, 5e5), rotation=pi/3), | ||||
|         Ref(cell_name, mirrored=(False, True), offset=(3e5, 5e5), rotation=pi/2), | ||||
|         Ref(cell_name, mirrored=(False, True), offset=(4e5, 5e5), rotation=pi), | ||||
|         Ref(cell_name, mirrored=(False, True), offset=(5e5, 5e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, mirrored=(True, True), offset=(1e5, 6e5)), | ||||
|         Ref(cell_name, mirrored=(True, True), offset=(2e5, 6e5), rotation=pi/3), | ||||
|         Ref(cell_name, mirrored=(True, True), offset=(3e5, 6e5), rotation=pi/2), | ||||
|         Ref(cell_name, mirrored=(True, True), offset=(4e5, 6e5), rotation=pi), | ||||
|         Ref(cell_name, mirrored=(True, True), offset=(5e5, 6e5), rotation=3*pi/2), | ||||
|         ] | ||||
| 
 | ||||
|     folder = 'layouts/' | ||||
|     masque.file.klamath.writefile((pat, pat2, pat3, pat4), folder + 'rep.gds.gz', 1e-9, 1e-3) | ||||
|     lib['sref_test'] = pat3 | ||||
|     print('\nAdded sref_test:') | ||||
|     pprint(pat3) | ||||
|     pprint(pat3.refs) | ||||
| 
 | ||||
|     cells = list(masque.file.klamath.readfile(folder + 'rep.gds.gz')[0].values()) | ||||
|     masque.file.klamath.writefile(cells, folder + 'rerep.gds.gz', 1e-9, 1e-3) | ||||
|     rep = Grid( | ||||
|         a_vector=[1e4, 0], | ||||
|         b_vector=[0, 1.5e4], | ||||
|         a_count=3, | ||||
|         b_count=2, | ||||
|         ) | ||||
|     pat4 = Pattern() | ||||
|     pat4.refs = [ | ||||
|         Ref(cell_name, repetition=rep, offset=(1e5, 3e5)), | ||||
|         Ref(cell_name, repetition=rep, offset=(2e5, 3e5), rotation=pi/3), | ||||
|         Ref(cell_name, repetition=rep, offset=(3e5, 3e5), rotation=pi/2), | ||||
|         Ref(cell_name, repetition=rep, offset=(4e5, 3e5), rotation=pi), | ||||
|         Ref(cell_name, repetition=rep, offset=(5e5, 3e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, False), offset=(1e5, 4e5)), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, False), offset=(2e5, 4e5), rotation=pi/3), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, False), offset=(3e5, 4e5), rotation=pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, False), offset=(4e5, 4e5), rotation=pi), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, False), offset=(5e5, 4e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(False, True), offset=(1e5, 5e5)), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(False, True), offset=(2e5, 5e5), rotation=pi/3), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(False, True), offset=(3e5, 5e5), rotation=pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(False, True), offset=(4e5, 5e5), rotation=pi), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(False, True), offset=(5e5, 5e5), rotation=3*pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, True), offset=(1e5, 6e5)), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, True), offset=(2e5, 6e5), rotation=pi/3), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, True), offset=(3e5, 6e5), rotation=pi/2), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, True), offset=(4e5, 6e5), rotation=pi), | ||||
|         Ref(cell_name, repetition=rep, mirrored=(True, True), offset=(5e5, 6e5), rotation=3*pi/2), | ||||
|         ] | ||||
| 
 | ||||
|     masque.file.dxf.writefile(pat4, folder + 'rep.dxf.gz') | ||||
|     dxf, info = masque.file.dxf.readfile(folder + 'rep.dxf.gz') | ||||
|     masque.file.dxf.writefile(dxf, folder + 'rerep.dxf.gz') | ||||
|     lib['aref_test'] = pat4 | ||||
|     print('\nAdded aref_test') | ||||
| 
 | ||||
|     folder = Path('./layouts/') | ||||
|     print(f'...writing files to {folder}...') | ||||
| 
 | ||||
|     gds1 = folder / 'rep.gds.gz' | ||||
|     gds2 = folder / 'rerep.gds.gz' | ||||
|     print(f'Initial write to {gds1}') | ||||
|     gdsii.writefile(lib, gds1, 1e-9, 1e-3) | ||||
| 
 | ||||
|     print(f'Read back and rewrite to {gds2}') | ||||
|     readback_lib, _info = gdsii.readfile(gds1) | ||||
|     gdsii.writefile(readback_lib, gds2, 1e-9, 1e-3) | ||||
| 
 | ||||
|     dxf1 = folder / 'rep.dxf.gz' | ||||
|     dxf2 = folder / 'rerep.dxf.gz' | ||||
|     print(f'Write aref_test to {dxf1}') | ||||
|     dxf.writefile(lib, 'aref_test', dxf1) | ||||
| 
 | ||||
|     print(f'Read back and rewrite to {dxf2}') | ||||
|     dxf_lib, _info = dxf.readfile(dxf1) | ||||
|     print(WrapLibrary(dxf_lib)) | ||||
|     dxf.writefile(dxf_lib, 'Model', dxf2) | ||||
| 
 | ||||
|     layer_map = {'base': (0,0), 'mylabel': (1,2)} | ||||
|     masque.file.oasis.writefile((pat, pat2, pat3, pat4), folder + 'rep.oas.gz', 1000, layer_map=layer_map) | ||||
|     oas, info = masque.file.oasis.readfile(folder + 'rep.oas.gz') | ||||
|     masque.file.oasis.writefile(list(oas.values()), folder + 'rerep.oas.gz', 1000, layer_map=layer_map) | ||||
|     print(info) | ||||
|     oas1 = folder / 'rep.oas' | ||||
|     oas2 = folder / 'rerep.oas' | ||||
|     print(f'Write lib to {oas1}') | ||||
|     oasis.writefile(lib, oas1, 1000, layer_map=layer_map) | ||||
| 
 | ||||
|     print(f'Read back and rewrite to {oas2}') | ||||
|     oas_lib, oas_info = oasis.readfile(oas1) | ||||
|     oasis.writefile(oas_lib, oas2, 1000, layer_map=layer_map) | ||||
| 
 | ||||
|     print('OASIS info:') | ||||
|     pprint(oas_info) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|  | ||||
| @ -35,7 +35,9 @@ from .pattern import Pattern | ||||
| from .utils import layer_t, annotations_t | ||||
| from .library import Library, MutableLibrary, WrapROLibrary, WrapLibrary, LazyLibrary, AbstractView | ||||
| from .ports import Port, PortList | ||||
| from .builder import Builder, Abstract, Tool | ||||
| from .abstract import Abstract | ||||
| from .builder import Builder, Tool | ||||
| 
 | ||||
| 
 | ||||
| __author__ = 'Jan Petykiewicz' | ||||
| 
 | ||||
|  | ||||
| @ -3,13 +3,12 @@ from typing import MutableMapping, TYPE_CHECKING | ||||
| import copy | ||||
| import logging | ||||
| 
 | ||||
| from ..pattern import Pattern | ||||
| from ..library import MutableLibrary | ||||
| from ..ports import PortList, Port | ||||
| from .tools import Tool | ||||
| from .pattern import Pattern | ||||
| from .ports import PortList, Port | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from .builder import Builder | ||||
|     from .builder import Builder, Tool | ||||
|     from .library import MutableLibrary | ||||
| 
 | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| @ -34,8 +33,8 @@ class Abstract(PortList): | ||||
| 
 | ||||
|     def build( | ||||
|             self, | ||||
|             library: MutableLibrary, | ||||
|             tools: Union[None, Tool, MutableMapping[Optional[str], Tool]] = None, | ||||
|             library: 'MutableLibrary', | ||||
|             tools: Union[None, 'Tool', MutableMapping[Optional[str], 'Tool']] = None, | ||||
|             ) -> 'Builder': | ||||
|         """ | ||||
|         Begin building a new device around an instance of the current device | ||||
| @ -1,4 +1,3 @@ | ||||
| from .builder import Builder | ||||
| from .abstract import Abstract | ||||
| from .utils import ell | ||||
| from .tools import Tool | ||||
|  | ||||
| @ -12,9 +12,9 @@ from ..ref import Ref | ||||
| from ..library import MutableLibrary | ||||
| from ..error import PortError, BuildError | ||||
| from ..ports import PortList, Port | ||||
| from ..abstract import Abstract | ||||
| from .tools import Tool | ||||
| from .utils import ell | ||||
| from .abstract import Abstract | ||||
| 
 | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| @ -14,27 +14,29 @@ import pathlib | ||||
| import gzip | ||||
| 
 | ||||
| import numpy | ||||
| import ezdxf        # type: ignore | ||||
| import ezdxf | ||||
| 
 | ||||
| from .. import Pattern, Ref, PatternError, Label, Shape | ||||
| from ..shapes import Polygon, Path | ||||
| from .. import Pattern, Ref, PatternError, Label | ||||
| from ..library import Library, WrapROLibrary | ||||
| from ..shapes import Shape, Polygon, Path | ||||
| from ..repetition import Grid | ||||
| from ..utils import rotation_matrix_2d, layer_t | ||||
| from .utils import is_gzipped | ||||
| 
 | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| logger.warning('DXF support is experimental and only slightly tested!') | ||||
| logger.warning('DXF support is experimental!') | ||||
| 
 | ||||
| 
 | ||||
| DEFAULT_LAYER = 'DEFAULT' | ||||
| 
 | ||||
| 
 | ||||
| def write( | ||||
|         library: Mapping[str, Pattern],    # TODO could allow library=None for flat DXF | ||||
|         top_name: str, | ||||
|         library: Mapping[str, Pattern], | ||||
|         stream: io.TextIOBase, | ||||
|         stream: TextIO, | ||||
|         *, | ||||
|         dxf_version='AC1024', | ||||
|         ) -> None: | ||||
| @ -65,17 +67,23 @@ def write( | ||||
|      array with rotated instances must be manhattan _after_ having a compensating rotation applied. | ||||
| 
 | ||||
|     Args: | ||||
|         top_name: Name of the top-level pattern to write. | ||||
|         library: A {name: Pattern} mapping of patterns. Only `top_name` and patterns referenced | ||||
|             by it are written. | ||||
|         top_name: Name of the top-level pattern to write. | ||||
|         stream: Stream object to write to. | ||||
|         disambiguate_func: Function which takes a list of patterns and alters them | ||||
|             to make their names valid and unique. Default is `disambiguate_pattern_names`. | ||||
|             WARNING: No additional error checking is performed on the results. | ||||
|     """ | ||||
|     #TODO consider supporting DXF arcs? | ||||
|     if not isinstance(library, Library): | ||||
|         if isinstance(library, dict): | ||||
|             library = WrapROLibrary(library) | ||||
|         else: | ||||
|             library = WrapROLibrary(dict(library)) | ||||
| 
 | ||||
|     pattern = library[top_name] | ||||
|     subtree = library.subtree(top_name) | ||||
| 
 | ||||
|     # Create library | ||||
|     lib = ezdxf.new(dxf_version, setup=True) | ||||
| @ -85,8 +93,11 @@ def write( | ||||
|     _mrefs_to_drefs(msp, pattern.refs) | ||||
| 
 | ||||
|     # Now create a block for each referenced pattern, and add in any shapes | ||||
|     for name, pat in library.items(): | ||||
|     for name, pat in subtree.items(): | ||||
|         assert pat is not None | ||||
|         if name == top_name: | ||||
|             continue | ||||
| 
 | ||||
|         block = lib.blocks.new(name=name) | ||||
| 
 | ||||
|         _shapes_to_elements(block, pat.shapes) | ||||
| @ -97,8 +108,8 @@ def write( | ||||
| 
 | ||||
| 
 | ||||
| def writefile( | ||||
|         top_name: str, | ||||
|         library: Mapping[str, Pattern], | ||||
|         top_name: str, | ||||
|         filename: Union[str, pathlib.Path], | ||||
|         *args, | ||||
|         **kwargs, | ||||
| @ -109,9 +120,9 @@ def writefile( | ||||
|     Will automatically compress the file if it has a .gz suffix. | ||||
| 
 | ||||
|     Args: | ||||
|         top_name: Name of the top-level pattern to write. | ||||
|         library: A {name: Pattern} mapping of patterns. Only `top_name` and patterns referenced | ||||
|             by it are written. | ||||
|         top_name: Name of the top-level pattern to write. | ||||
|         filename: Filename to save to. | ||||
|         *args: passed to `dxf.write` | ||||
|         **kwargs: passed to `dxf.write` | ||||
| @ -181,19 +192,19 @@ def read( | ||||
|     lib = ezdxf.read(stream) | ||||
|     msp = lib.modelspace() | ||||
| 
 | ||||
|     npat = _read_block(msp, clean_vertices) | ||||
|     npat = _read_block(msp) | ||||
|     patterns_dict = dict( | ||||
|         [npat] + [_read_block(bb, clean_vertices) for bb in lib.blocks if bb.name != '*Model_Space'] | ||||
|         [npat] + [_read_block(bb) for bb in lib.blocks if bb.name != '*Model_Space'] | ||||
|         ) | ||||
| 
 | ||||
|     library_info = { | ||||
|         'layers': [ll.dxfattribs() for ll in lib.layers] | ||||
|         } | ||||
|     library_info = dict( | ||||
|         layers=[ll.dxfattribs() for ll in lib.layers], | ||||
|         ) | ||||
| 
 | ||||
|     return patterns_dict, library_info | ||||
| 
 | ||||
| 
 | ||||
| def _read_block(block, clean_vertices: bool) -> Tuple[str, Pattern]: | ||||
| def _read_block(block) -> Tuple[str, Pattern]: | ||||
|     name = block.name | ||||
|     pat = Pattern() | ||||
|     for element in block: | ||||
| @ -225,18 +236,13 @@ def _read_block(block, clean_vertices: bool) -> Tuple[str, Pattern]: | ||||
|                 else: | ||||
|                     shape = Path(layer=layer, width=width, vertices=points[:, :2]) | ||||
| 
 | ||||
|             if clean_vertices: | ||||
|                 try: | ||||
|                     shape.clean_vertices() | ||||
|                 except PatternError: | ||||
|                     continue | ||||
| 
 | ||||
|             pat.shapes.append(shape) | ||||
| 
 | ||||
|         elif eltype in ('TEXT',): | ||||
|             args = {'offset': numpy.array(element.get_pos()[1])[:2], | ||||
|                     'layer': element.dxfattribs().get('layer', DEFAULT_LAYER), | ||||
|                    } | ||||
|             args = dict( | ||||
|                 offset=numpy.array(element.get_pos()[1])[:2], | ||||
|                 layer=element.dxfattribs().get('layer', DEFAULT_LAYER), | ||||
|                 ) | ||||
|             string = element.dxfattribs().get('text', '') | ||||
| #            height = element.dxfattribs().get('height', 0) | ||||
| #            if height != 0: | ||||
| @ -257,20 +263,21 @@ def _read_block(block, clean_vertices: bool) -> Tuple[str, Pattern]: | ||||
| 
 | ||||
|             offset = numpy.array(attr.get('insert', (0, 0, 0)))[:2] | ||||
| 
 | ||||
|             args = { | ||||
|                 'target': (attr.get('name', None),), | ||||
|                 'offset': offset, | ||||
|                 'scale': scale, | ||||
|                 'mirrored': mirrored, | ||||
|                 'rotation': rotation, | ||||
|                 'pattern': None, | ||||
|                 } | ||||
|             args = dict( | ||||
|                 target=attr.get('name', None), | ||||
|                 offset=offset, | ||||
|                 scale=scale, | ||||
|                 mirrored=mirrored, | ||||
|                 rotation=rotation, | ||||
|                 ) | ||||
| 
 | ||||
|             if 'column_count' in attr: | ||||
|                 args['repetition'] = Grid(a_vector=(attr['column_spacing'], 0), | ||||
|                 args['repetition'] = Grid( | ||||
|                     a_vector=(attr['column_spacing'], 0), | ||||
|                     b_vector=(0, attr['row_spacing']), | ||||
|                     a_count=attr['column_count'], | ||||
|                                           b_count=attr['row_count']) | ||||
|                     b_count=attr['row_count'], | ||||
|                     ) | ||||
|             pat.ref(**args) | ||||
|         else: | ||||
|             logger.warning(f'Ignoring DXF element {element.dxftype()} (not implemented).') | ||||
| @ -286,12 +293,12 @@ def _mrefs_to_drefs( | ||||
|             continue | ||||
|         encoded_name = ref.target | ||||
| 
 | ||||
|         rotation = (ref.rotation * 180 / numpy.pi) % 360 | ||||
|         attribs = { | ||||
|             'xscale': ref.scale * (-1 if ref.mirrored[1] else 1), | ||||
|             'yscale': ref.scale * (-1 if ref.mirrored[0] else 1), | ||||
|             'rotation': rotation, | ||||
|             } | ||||
|         rotation = numpy.rad2deg(ref.rotation) % 360 | ||||
|         attribs = dict( | ||||
|             xscale=ref.scale * (-1 if ref.mirrored[1] else 1), | ||||
|             yscale=ref.scale * (-1 if ref.mirrored[0] else 1), | ||||
|             rotation=rotation, | ||||
|             ) | ||||
| 
 | ||||
|         rep = ref.repetition | ||||
|         if rep is None: | ||||
| @ -338,7 +345,7 @@ def _shapes_to_elements( | ||||
|                 ' Please call library.wrap_repeated_shapes() before writing to file.' | ||||
|                 ) | ||||
| 
 | ||||
|         attribs = {'layer': _mlayer2dxf(shape.layer)} | ||||
|         attribs = dict(layer=_mlayer2dxf(shape.layer)) | ||||
|         for polygon in shape.to_polygons(): | ||||
|             xy_open = polygon.vertices + polygon.offset | ||||
|             xy_closed = numpy.vstack((xy_open, xy_open[0, :])) | ||||
| @ -350,7 +357,7 @@ def _labels_to_texts( | ||||
|         labels: List[Label], | ||||
|         ) -> None: | ||||
|     for label in labels: | ||||
|         attribs = {'layer': _mlayer2dxf(label.layer)} | ||||
|         attribs = dict(layer=_mlayer2dxf(label.layer)) | ||||
|         xy = label.offset | ||||
|         block.add_text(label.string, dxfattribs=attribs).set_pos(xy, align='BOTTOM_LEFT') | ||||
| 
 | ||||
|  | ||||
| @ -30,7 +30,7 @@ import string | ||||
| from pprint import pformat | ||||
| 
 | ||||
| import numpy | ||||
| from numpy.typing import NDArray, ArrayLike | ||||
| from numpy.typing import ArrayLike, NDArray | ||||
| import klamath | ||||
| from klamath import records | ||||
| 
 | ||||
| @ -54,7 +54,7 @@ path_cap_map = { | ||||
| 
 | ||||
| 
 | ||||
| def rint_cast(val: ArrayLike) -> NDArray[numpy.int32]: | ||||
|     return numpy.rint(val, dtype=numpy.int32, casting='unsafe') | ||||
|     return numpy.rint(val).astype(numpy.int32) | ||||
| 
 | ||||
| 
 | ||||
| def write( | ||||
|  | ||||
| @ -39,7 +39,7 @@ from ..utils import layer_t, normalize_mirror, annotations_t | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| logger.warning('OASIS support is experimental and mostly untested!') | ||||
| logger.warning('OASIS support is experimental!') | ||||
| 
 | ||||
| 
 | ||||
| path_cap_map = { | ||||
| @ -51,7 +51,7 @@ path_cap_map = { | ||||
| #TODO implement more shape types? | ||||
| 
 | ||||
| def rint_cast(val: ArrayLike) -> NDArray[numpy.int64]: | ||||
|     return numpy.rint(val, dtype=numpy.int64, casting='unsafe') | ||||
|     return numpy.rint(val).astype(numpy.int64) | ||||
| 
 | ||||
| 
 | ||||
| def build( | ||||
|  | ||||
| @ -22,7 +22,7 @@ from .error import LibraryError, PatternError | ||||
| from .utils import rotation_matrix_2d, normalize_mirror | ||||
| from .shapes import Shape, Polygon | ||||
| from .label import Label | ||||
| from .builder.abstract import Abstract | ||||
| from .abstract import Abstract | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from .pattern import Pattern | ||||
| @ -37,7 +37,7 @@ ML = TypeVar('ML', bound='MutableLibrary') | ||||
| LL = TypeVar('LL', bound='LazyLibrary') | ||||
| 
 | ||||
| 
 | ||||
| class Library(Mapping[str, Pattern], metaclass=ABCMeta): | ||||
| class Library(Mapping[str, 'Pattern'], metaclass=ABCMeta): | ||||
|     # inherited abstract functions | ||||
|     #def __getitem__(self, key: str) -> 'Pattern': | ||||
|     #def __iter__(self) -> Iterator[str]: | ||||
| @ -61,7 +61,7 @@ class Library(Mapping[str, Pattern], metaclass=ABCMeta): | ||||
|         return Abstract(name=name, ports=self[name].ports) | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         return '<Library with keys ' + repr(list(self.keys())) + '>' | ||||
|         return '<Library with keys\n' + pformat(list(self.keys())) + '>' | ||||
| 
 | ||||
|     def dangling_references( | ||||
|             self, | ||||
| @ -142,7 +142,11 @@ class Library(Mapping[str, Pattern], metaclass=ABCMeta): | ||||
|         Returns: | ||||
|             A `WrapROLibrary` containing only `tops` and the patterns they reference. | ||||
|         """ | ||||
|         if isinstance(tops, str): | ||||
|             tops = (tops,) | ||||
| 
 | ||||
|         keep: Set[str] = self.referenced_patterns(tops) - set((None,))      # type: ignore | ||||
|         keep |= set(tops) | ||||
| 
 | ||||
|         filtered = {kk: vv for kk, vv in self.items() if kk in keep} | ||||
|         new = WrapROLibrary(filtered) | ||||
| @ -405,7 +409,7 @@ class Library(Mapping[str, Pattern], metaclass=ABCMeta): | ||||
| VVV = TypeVar('VVV') | ||||
| 
 | ||||
| 
 | ||||
| class MutableLibrary(Generic[VVV], Library, metaclass=ABCMeta): | ||||
| class MutableLibrary(Library, Generic[VVV], metaclass=ABCMeta): | ||||
|     # inherited abstract functions | ||||
|     #def __getitem__(self, key: str) -> 'Pattern': | ||||
|     #def __iter__(self) -> Iterator[str]: | ||||
| @ -627,7 +631,11 @@ class MutableLibrary(Generic[VVV], Library, metaclass=ABCMeta): | ||||
|         Returns: | ||||
|             A `Library` containing only `tops` and the patterns they reference. | ||||
|         """ | ||||
|         if isinstance(tops, str): | ||||
|             tops = (tops,) | ||||
| 
 | ||||
|         keep: Set[str] = self.referenced_patterns(tops) - set((None,))      # type: ignore | ||||
|         keep |= set(tops) | ||||
| 
 | ||||
|         new = type(self)() | ||||
|         for key in keep: | ||||
| @ -654,7 +662,7 @@ class WrapROLibrary(Library): | ||||
|         return len(self.mapping) | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         return f'<WrapROLibrary ({type(self.mapping)}) with keys ' + repr(list(self.keys())) + '>' | ||||
|         return f'<WrapROLibrary ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>' | ||||
| 
 | ||||
| 
 | ||||
| class WrapLibrary(MutableLibrary): | ||||
| @ -662,8 +670,11 @@ class WrapLibrary(MutableLibrary): | ||||
| 
 | ||||
|     def __init__( | ||||
|             self, | ||||
|             mapping: MutableMapping[str, 'Pattern'], | ||||
|             mapping: Optional[MutableMapping[str, 'Pattern']] = None, | ||||
|             ) -> None: | ||||
|         if mapping is None: | ||||
|             self.mapping = {} | ||||
|         else: | ||||
|             self.mapping = mapping | ||||
| 
 | ||||
|     def __getitem__(self, key: str) -> 'Pattern': | ||||
| @ -688,7 +699,7 @@ class WrapLibrary(MutableLibrary): | ||||
|         self[key] = other[key] | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         return f'<WrapLibrary ({type(self.mapping)}) with keys ' + repr(list(self.keys())) + '>' | ||||
|         return f'<WrapLibrary ({type(self.mapping)}) with keys\n' + pformat(list(self.keys())) + '>' | ||||
| 
 | ||||
| 
 | ||||
| class LazyLibrary(MutableLibrary): | ||||
| @ -745,7 +756,7 @@ class LazyLibrary(MutableLibrary): | ||||
|             self._set(key, other[key]) | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         return '<LazyLibrary with keys ' + repr(list(self.keys())) + '>' | ||||
|         return '<LazyLibrary with keys\n' + pformat(list(self.keys())) + '>' | ||||
| 
 | ||||
|     def precache(self: LL) -> LL: | ||||
|         """ | ||||
|  | ||||
| @ -88,7 +88,9 @@ class Pattern(PortList, AnnotatableImpl, Mirrorable, metaclass=AutoSlots): | ||||
|             self.refs = list(refs) | ||||
| 
 | ||||
|         if ports is not None: | ||||
|             ports = dict(copy.deepcopy(ports)) | ||||
|             self.ports = dict(copy.deepcopy(ports)) | ||||
|         else: | ||||
|             self.ports = {} | ||||
| 
 | ||||
|         self.annotations = annotations if annotations is not None else {} | ||||
| 
 | ||||
|  | ||||
| @ -178,8 +178,8 @@ class Ref( | ||||
|     def get_bounds( | ||||
|             self, | ||||
|             *, | ||||
|             pattern: Optional[Pattern] = None, | ||||
|             library: Optional[Mapping[str, Pattern]] = None, | ||||
|             pattern: Optional['Pattern'] = None, | ||||
|             library: Optional[Mapping[str, 'Pattern']] = None, | ||||
|             ) -> Optional[NDArray[numpy.float64]]: | ||||
|         """ | ||||
|         Return a `numpy.ndarray` containing `[[x_min, y_min], [x_max, y_max]]`, corresponding to the | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user