Automatically disambiguate repeated pattern names.
Also check for >32 char names
This commit is contained in:
parent
3815069136
commit
3094aa4043
@ -9,6 +9,9 @@ import gdsii.elements
|
|||||||
from typing import List, Any, Dict, Tuple
|
from typing import List, Any, Dict, Tuple
|
||||||
import re
|
import re
|
||||||
import numpy
|
import numpy
|
||||||
|
import base64
|
||||||
|
import struct
|
||||||
|
import logging
|
||||||
|
|
||||||
from .utils import mangle_name, make_dose_table
|
from .utils import mangle_name, make_dose_table
|
||||||
from .. import Pattern, SubPattern, GridRepetition, PatternError, Label, Shape
|
from .. import Pattern, SubPattern, GridRepetition, PatternError, Label, Shape
|
||||||
@ -19,6 +22,9 @@ from ..utils import rotation_matrix_2d, get_bit, set_bit, vector2, is_scalar
|
|||||||
__author__ = 'Jan Petykiewicz'
|
__author__ = 'Jan Petykiewicz'
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def write(patterns: Pattern or List[Pattern],
|
def write(patterns: Pattern or List[Pattern],
|
||||||
filename: str,
|
filename: str,
|
||||||
meters_per_unit: float,
|
meters_per_unit: float,
|
||||||
@ -65,13 +71,11 @@ def write(patterns: Pattern or List[Pattern],
|
|||||||
for pattern in patterns:
|
for pattern in patterns:
|
||||||
patterns_by_id.update(pattern.referenced_patterns_by_id())
|
patterns_by_id.update(pattern.referenced_patterns_by_id())
|
||||||
|
|
||||||
|
_disambiguate_pattern_names(patterns_by_id.values())
|
||||||
|
|
||||||
# Now create a structure for each pattern, and add in any Boundary and SREF elements
|
# Now create a structure for each pattern, and add in any Boundary and SREF elements
|
||||||
for pat in patterns_by_id.values():
|
for pat in patterns_by_id.values():
|
||||||
sanitized_name = re.compile('[^A-Za-z0-9_\?\$]').sub('_', pat.name)
|
structure = gdsii.structure.Structure(name=pat.name)
|
||||||
encoded_name = sanitized_name.encode('ASCII')
|
|
||||||
if len(encoded_name) == 0:
|
|
||||||
raise PatternError('Zero-length name after sanitize+encode, originally "{}"'.format(pat.name))
|
|
||||||
structure = gdsii.structure.Structure(name=encoded_name)
|
|
||||||
lib.append(structure)
|
lib.append(structure)
|
||||||
|
|
||||||
# Add a Boundary element for each shape
|
# Add a Boundary element for each shape
|
||||||
@ -384,10 +388,7 @@ def _subpatterns_to_refs(subpatterns: List[SubPattern or GridRepetition]
|
|||||||
# strans must be set for angle and mag to take effect
|
# strans must be set for angle and mag to take effect
|
||||||
refs = []
|
refs = []
|
||||||
for subpat in subpatterns:
|
for subpat in subpatterns:
|
||||||
sanitized_name = re.compile('[^A-Za-z0-9_\?\$]').sub('_', subpat.pattern.name)
|
encoded_name = subpat.pattern.name
|
||||||
encoded_name = sanitized_name.encode('ASCII')
|
|
||||||
if len(encoded_name) == 0:
|
|
||||||
raise PatternError('Zero-length name after sanitize+encode, originally "{}"'.format(subpat.pattern.name))
|
|
||||||
|
|
||||||
if isinstance(subpat, GridRepetition):
|
if isinstance(subpat, GridRepetition):
|
||||||
mirror_signs = (-1) ** numpy.array(subpat.mirrored)
|
mirror_signs = (-1) ** numpy.array(subpat.mirrored)
|
||||||
@ -446,3 +447,29 @@ def _labels_to_texts(labels: List[Label]) -> List[gdsii.elements.Text]:
|
|||||||
xy=xy,
|
xy=xy,
|
||||||
string=label.string.encode('ASCII')))
|
string=label.string.encode('ASCII')))
|
||||||
return texts
|
return texts
|
||||||
|
|
||||||
|
|
||||||
|
def _disambiguate_pattern_names(patterns):
|
||||||
|
used_names = []
|
||||||
|
for pat in patterns:
|
||||||
|
sanitized_name = re.compile('[^A-Za-z0-9_\?\$]').sub('_', pat.name)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
suffixed_name = sanitized_name
|
||||||
|
while suffixed_name in used_names:
|
||||||
|
suffix = base64.b64encode(struct.pack('>Q', i), b'$?').decode('ASCII')
|
||||||
|
|
||||||
|
suffixed_name = sanitized_name + '$' + suffix[:-1].lstrip('A')
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if suffixed_name != sanitized_name:
|
||||||
|
logger.warning('Pattern name "{}" appears multiple times; renaming to "{}"'.format(pat.name, suffixed_name))
|
||||||
|
|
||||||
|
encoded_name = sanitized_name.encode('ASCII')
|
||||||
|
if len(encoded_name) == 0:
|
||||||
|
raise PatternError('Zero-length name after sanitize+encode, originally "{}"'.format(pat.name))
|
||||||
|
if len(encoded_name) > 32:
|
||||||
|
raise PatternError('Pattern name "{}" length > 32 after encode, originally "{}"'.format(encoded_name, pat.name))
|
||||||
|
|
||||||
|
pat.name = encoded_name
|
||||||
|
used_names.append(suffixed_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user