From e684bd0e4081595ef4bd6086026e6673df16b6ed Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sat, 14 Mar 2020 15:52:49 -0700 Subject: [PATCH] add Pattern.find_toplevel() Topological sort for lists of Pattern objects, useful for finding top cell of gds --- masque/pattern.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/masque/pattern.py b/masque/pattern.py index c9fda68..cf1a372 100644 --- a/masque/pattern.py +++ b/masque/pattern.py @@ -2,7 +2,7 @@ Base object for containing a lithography mask. """ -from typing import List, Callable, Tuple, Dict, Union +from typing import List, Callable, Tuple, Dict, Union, Set import copy import itertools import pickle @@ -824,3 +824,35 @@ class Pattern: if not overdraw: pyplot.show() + + @staticmethod + def find_toplevel(patterns: List['Pattern']) -> List['Pattern']: + """ + Given a list of Pattern objects, return those that are not referenced by + any other pattern. + + Args: + patterns: A list of patterns to filter. + + Returns: + A filtered list in which no pattern is referenced by any other pattern. + """ + def get_children(pat: Pattern, memo: Set) -> Set: + if pat in memo: + return memo + + children = set(sp.pattern for sp in pat.subpatterns) + new_children = children - memo + memo |= children + + for child_pat in new_children: + memo |= get_children(child_pat, memo) + return memo + + patterns = set(patterns) + not_toplevel = set() + for pattern in patterns: + not_toplevel |= get_children(pattern, not_toplevel) + + toplevel = list(patterns - not_toplevel) + return toplevel