allow more freedom in pattern names (e.g. names which violate spec, longer suffixes, filter warning, etc)
This commit is contained in:
parent
0118bf0eb3
commit
09711116a7
@ -6,7 +6,7 @@ import gdsii.library
|
|||||||
import gdsii.structure
|
import gdsii.structure
|
||||||
import gdsii.elements
|
import gdsii.elements
|
||||||
|
|
||||||
from typing import List, Any, Dict, Tuple
|
from typing import List, Any, Dict, Tuple, Callable
|
||||||
import re
|
import re
|
||||||
import io
|
import io
|
||||||
import copy
|
import copy
|
||||||
@ -46,7 +46,8 @@ def write(patterns: Pattern or List[Pattern],
|
|||||||
meters_per_unit: float,
|
meters_per_unit: float,
|
||||||
logical_units_per_unit: float = 1,
|
logical_units_per_unit: float = 1,
|
||||||
library_name: str = 'masque-gdsii-write',
|
library_name: str = 'masque-gdsii-write',
|
||||||
modify_originals: bool = False):
|
modify_originals: bool = False,
|
||||||
|
disambiguate_func: Callable[[List[Pattern]], None] = None):
|
||||||
"""
|
"""
|
||||||
Write a Pattern or list of patterns to a GDSII file, by first calling
|
Write a Pattern or list of patterns to a GDSII file, by first calling
|
||||||
.polygonize() to change the shapes into polygons, and then writing patterns
|
.polygonize() to change the shapes into polygons, and then writing patterns
|
||||||
@ -77,13 +78,20 @@ def write(patterns: Pattern or List[Pattern],
|
|||||||
:param modify_originals: If True, the original pattern is modified as part of the writing
|
:param modify_originals: If True, the original pattern is modified as part of the writing
|
||||||
process. Otherwise, a copy is made.
|
process. Otherwise, a copy is made.
|
||||||
Default False.
|
Default False.
|
||||||
|
:param disambiguate_func: Function which takes a list of patterns and alters them
|
||||||
|
to make their names valid and unique. Default is `disambiguate_pattern_names`, which
|
||||||
|
attempts to adhere to the GDSII standard as well as possible.
|
||||||
|
WARNING: No additional error checking is performed on the results.
|
||||||
"""
|
"""
|
||||||
if not modify_originals:
|
|
||||||
patterns = copy.deepcopy(patterns)
|
|
||||||
|
|
||||||
if isinstance(patterns, Pattern):
|
if isinstance(patterns, Pattern):
|
||||||
patterns = [patterns]
|
patterns = [patterns]
|
||||||
|
|
||||||
|
if disambiguate_func is None:
|
||||||
|
disambiguate_func = disambiguate_pattern_names
|
||||||
|
|
||||||
|
if not modify_originals:
|
||||||
|
patterns = copy.deepcopy(patterns)
|
||||||
|
|
||||||
# Create library
|
# Create library
|
||||||
lib = gdsii.library.Library(version=600,
|
lib = gdsii.library.Library(version=600,
|
||||||
name=library_name.encode('ASCII'),
|
name=library_name.encode('ASCII'),
|
||||||
@ -95,7 +103,7 @@ 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())
|
disambiguate_func(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():
|
||||||
@ -506,12 +514,16 @@ def _labels_to_texts(labels: List[Label]) -> List[gdsii.elements.Text]:
|
|||||||
return texts
|
return texts
|
||||||
|
|
||||||
|
|
||||||
def _disambiguate_pattern_names(patterns):
|
def disambiguate_pattern_names(patterns,
|
||||||
|
max_name_length: int = 32,
|
||||||
|
suffix_length: int = 6,
|
||||||
|
dup_warn_filter: Callable[[str,], bool] = None, # If returns False, don't warn about this name
|
||||||
|
):
|
||||||
used_names = []
|
used_names = []
|
||||||
for pat in patterns:
|
for pat in patterns:
|
||||||
if len(pat.name) > 32:
|
if len(pat.name) > max_name_length:
|
||||||
shortened_name = pat.name[:26]
|
shortened_name = pat.name[:max_name_length - suffix_length]
|
||||||
logger.warning('Pattern name "{}" is too long ({}/32 chars),\n'.format(pat.name, len(pat.name)) +
|
logger.warning('Pattern name "{}" is too long ({}/{} chars),\n'.format(pat.name, len(pat.name), max_name_length) +
|
||||||
' shortening to "{}" before generating suffix'.format(shortened_name))
|
' shortening to "{}" before generating suffix'.format(shortened_name))
|
||||||
else:
|
else:
|
||||||
shortened_name = pat.name
|
shortened_name = pat.name
|
||||||
@ -529,6 +541,7 @@ def _disambiguate_pattern_names(patterns):
|
|||||||
if sanitized_name == '':
|
if sanitized_name == '':
|
||||||
logger.warning('Empty pattern name saved as "{}"'.format(suffixed_name))
|
logger.warning('Empty pattern name saved as "{}"'.format(suffixed_name))
|
||||||
elif suffixed_name != sanitized_name:
|
elif suffixed_name != sanitized_name:
|
||||||
|
if dup_warn_filter is None or dup_warn_filter(pat.name):
|
||||||
logger.warning('Pattern name "{}" ({}) appears multiple times;\n renaming to "{}"'.format(
|
logger.warning('Pattern name "{}" ({}) appears multiple times;\n renaming to "{}"'.format(
|
||||||
pat.name, sanitized_name, suffixed_name))
|
pat.name, sanitized_name, suffixed_name))
|
||||||
|
|
||||||
@ -536,8 +549,8 @@ def _disambiguate_pattern_names(patterns):
|
|||||||
if len(encoded_name) == 0:
|
if len(encoded_name) == 0:
|
||||||
# Should never happen since zero-length names are replaced
|
# Should never happen since zero-length names are replaced
|
||||||
raise PatternError('Zero-length name after sanitize+encode,\n originally "{}"'.format(pat.name))
|
raise PatternError('Zero-length name after sanitize+encode,\n originally "{}"'.format(pat.name))
|
||||||
if len(encoded_name) > 32:
|
if len(encoded_name) > max_name_length:
|
||||||
raise PatternError('Pattern name "{}" length > 32 after encode,\n originally "{}"'.format(encoded_name, pat.name))
|
raise PatternError('Pattern name "{}" length > {} after encode,\n originally "{}"'.format(encoded_name, max_name_length, pat.name))
|
||||||
|
|
||||||
pat.name = encoded_name
|
pat.name = encoded_name
|
||||||
used_names.append(suffixed_name)
|
used_names.append(suffixed_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user