
Security News
TypeScript is Porting Its Compiler to Go for 10x Faster Builds
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
Masque is a Python module for designing lithography masks.
The general idea is to implement something resembling the GDSII file-format, but with some vectorized element types (eg. circles, not just polygons) and the ability to output to multiple formats.
Requirements:
Optional requirements:
ezdxf
(DXF i/o): ezdxfoasis
(OASIS i/o): fatamorganasvg
(SVG output): svgwritevisualization
(shape plotting): matplotlibtext
(Text
shape): matplotlib, freetypeInstall with pip:
pip install 'masque[oasis,dxf,svg,visualization,text]'
A layout consists of a hierarchy of Pattern
s stored in a single Library
.
Each Pattern
can contain Ref
s pointing at other patterns, Shape
s, Label
s, and Port
s.
masque
departs from several "classic" GDSII paradigms:
Pattern
object does not store its own name. A name is only assigned when the pattern is placed
into a Library
, which is effectively a name->Pattern
mapping.Shape
ss and Label
s is not stored in the individual shape and label objects.
Instead, the layer is determined by the key for the container dict (e.g. pattern.shapes[layer]
).
Shape
s by layer, remapping layers, and checking if
a layer is empty.Ref
target names are also determined in the key of the container dict (e.g. pattern.refs[target_name]
).
Ref
s by target name, updating to a new target, and checking
if a given Pattern
is referenced.Pattern
names are set by their containing Library
and are not stored in the Pattern
objects.
Library
.Pattern
s) in a Library
is straightforward.Ref
, Shape
, or Label
can be repeated multiple times by attaching a repetition
object to it.
Ref
+ repetition
).Label
s do not have an orientation or presentation
Shape
s are allowed. For example, elliptical arcs are a basic shape type.
Shape
s provide a .to_polygons()
method for GDSII compatibility.Pattern
objects also contain Port
information, which can be used to "snap" together
multiple sub-components by matching up the requested port offsets and rotations.
None
in the case of non-oriented ports.ptype
string which is compared in order to catch mismatched connections at build time.Label
s stored directly in the layout,
editable from standard tools (e.g. KLayout). A default format is provided.In one important way, masque
stays very orthodox:
References are accomplished by listing the target's name, not its Pattern
object.
Pattern
and the Library
which is contains its reference targets.Library
remain unique at all times.
SINGLE_USE_PREFIX
(default: an underscore)
may be silently renamed in order to maintain uniqueness.
See masque.library.SINGLE_USE_PREFIX
, masque.library._rename_patterns()
,
and ILibrary.add()
for more details.Library
avoids having to perform a
tree traversal for every operation which needs to touch all Pattern
objects
(e.g. deleting a layer everywhere or scaling all patterns).Pattern
doesn't know its own name, you can't create a reference by passing in
a Pattern
object -- you need to know its name.Pattern
before it is created, so long as you have already decided
on its name.Pattern.place()
and Pattern.plug()
need to receive a pattern's name
in order to create a reference, but they also need to access the pattern's ports.
Abstract
, generated via
Library.abstract()
or through a Library.abstract_view()
.Builder.place()
or Builder.plug()
, which automatically creates
an Abstract
from its internally-referenced Library
.Library
: A collection of named cells. OASIS or GDS "library" or file.Tree
: Any {name: pattern}
mapping which has only one topcell.Pattern
: A collection of geometry, text labels, and reference to other patterns.
OASIS or GDS "Cell", DXF "Block".Ref
: A reference to another pattern. GDS "AREF/SREF", OASIS "Placement".Shape
: Individual geometric entity. OASIS or GDS "Geometry element", DXF "LWPolyline" or "Polyline".repetition
: Repetition operation. OASIS "repetition".
GDS "AREF" is a Ref
combined with a Grid
repetition.Label
: Text label. Not rendered into geometry. OASIS, GDS, DXF "Text".annotation
: Additional metadata. OASIS or GDS "property".Most syntax and behavior should follow normal python conventions. There are a few exceptions, either meant to catch common mistakes or to provide a shorthand for common operations:
Library
objects don't allow overwriting already-existing patternslibrary['mycell'] = pattern0
library['mycell'] = pattern1 # Error! 'mycell' already exists and can't be overwritten
del library['mycell'] # We can explicitly delete it
library['mycell'] = pattern1 # And now it's ok to assign a new value
library.delete('mycell') # This also deletes all refs pointing to 'mycell' by default
# Let's say we have a function which returns a new library containing one topcell (and possibly children)
tree = make_tree(...)
# To reference this cell in our layout, we have to add all its children to our `library` first:
top_name = tree.top() # get the name of the topcell
name_mapping = library.add(tree) # add all patterns from `tree`, renaming elgible conflicting patterns
new_name = name_mapping.get(top_name, top_name) # get the new name for the cell (in case it was auto-renamed)
my_pattern.ref(new_name, ...) # instantiate the cell
# This can be accomplished as follows
new_name = library << tree # Add `tree` into `library` and return the top cell's new name
my_pattern.ref(new_name, ...) # instantiate the cell
# In practice, you may do lots of
my_pattern.ref(lib << make_tree(...), ...)
# With a `Builder` and `place()`/`plug()` the `lib <<` portion can be implicit:
my_builder = Builder(library=lib, ...)
...
my_builder.place(make_tree(...))
We can also use this shorthand to quickly add and reference a single flat (as yet un-named) pattern:
anonymous_pattern = Pattern(...)
my_pattern.ref(lib << {'_tentative_name': anonymous_pattern}, ...)
# As above, we have a function that makes a new library containing one topcell (and possibly children)
tree = make_tree(...)
# We need to go get its port info to `place()` it into our existing layout,
new_name = library << tree # Add the tree to the library and return its name (see `<<` above)
abstract = library.abstract(tree) # An `Abstract` stores a pattern's name and its ports (but no geometry)
my_pattern.place(abstract, ...)
# With shorthand,
abstract = library <= tree
my_pattern.place(abstract, ...)
# or
my_pattern.place(library << make_tree(...), ...)
### Quickly add geometry, labels, or refs:
The long form for adding elements can be overly verbose:
```python3
my_pattern.shapes[layer].append(Polygon(vertices, ...))
my_pattern.labels[layer] += [Label('my text')]
my_pattern.refs[target_name].append(Ref(offset=..., ...))
There is shorthand for the most common elements:
my_pattern.polygon(layer=layer, vertices=vertices, ...)
my_pattern.rect(layer=layer, xctr=..., xmin=..., ymax=..., ly=...) # rectangle; pick 4 of 6 constraints
my_pattern.rect(layer=layer, ymin=..., ymax=..., xctr=..., lx=...)
my_pattern.path(...)
my_pattern.label(layer, 'my_text')
my_pattern.ref(target_name, offset=..., ...)
# Square brackets pull from the underlying `.ports` dict:
assert pattern['input'] is pattern.ports['input']
# And you can use them to read multiple ports at once:
assert pattern[('input', 'output')] == {
'input': pattern.ports['input'],
'output': pattern.ports['output'],
}
# But you shouldn't use them for anything except reading
pattern['input'] = Port(...) # Error!
has_input = ('input' in pattern) # Error!
library = Library(...)
my_pattern_name, my_pattern = library.mkpat(some_name_generator())
...
def _make_my_subpattern() -> str:
# This function can draw from the outer scope (e.g. `library`) but will not pollute the outer scope
# (e.g. the variable `subpattern` will not be accessible from outside the function; you must load it
# from within `library`).
subpattern_name, subpattern = library.mkpat(...)
subpattern.rect(...)
...
return subpattern_name
my_pattern.ref(_make_my_subpattern(), offset=..., ...)
pyclipper
)
FAQs
Lithography mask library
We found that masque demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.