import 0.2.1
This commit is contained in:
commit
5a4c7db6b4
35 changed files with 3888 additions and 0 deletions
36
scripts/gds2txt
Executable file
36
scripts/gds2txt
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#! /usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright © 2010 Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
# This file is licensed under GNU Lesser General Public License version 3 or later.
|
||||
"""Demonstration program for basic gdsii reading function."""
|
||||
from __future__ import print_function
|
||||
from gdsii import types
|
||||
from gdsii.record import Record
|
||||
import sys
|
||||
|
||||
def show_data(rec):
|
||||
"""Shows data in a human-readable format."""
|
||||
if rec.tag_type == types.ASCII:
|
||||
return '"%s"' % rec.data.decode() # TODO escape
|
||||
elif rec.tag_type == types.BITARRAY:
|
||||
return str(rec.data)
|
||||
return ', '.join('{0}'.format(i) for i in rec.data)
|
||||
|
||||
def main(name):
|
||||
with open(name, 'rb') as a_file:
|
||||
for rec in Record.iterate(a_file):
|
||||
if rec.tag_type == types.NODATA:
|
||||
print(rec.tag_name)
|
||||
else:
|
||||
print('%s: %s' % (rec.tag_name, show_data(rec)))
|
||||
|
||||
def usage(prog):
|
||||
print('Usage: %s <file.gds>' % prog)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if (len(sys.argv) > 1):
|
||||
main(sys.argv[1])
|
||||
else:
|
||||
usage(sys.argv[0])
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
222
scripts/gds2yaml
Executable file
222
scripts/gds2yaml
Executable file
|
|
@ -0,0 +1,222 @@
|
|||
#! /usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright © 2010 Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
# This file is licensed under GNU Lesser General Public License version 3 or later.
|
||||
from __future__ import print_function
|
||||
from gdsii.library import Library
|
||||
from gdsii import elements
|
||||
import sys
|
||||
from yaml.dumper import Dumper
|
||||
from yaml import events
|
||||
|
||||
# standard tags
|
||||
STR = 'tag:yaml.org,2002:str'
|
||||
TIMESTAMP = 'tag:yaml.org,2002:timestamp'
|
||||
FLOAT = 'tag:yaml.org,2002:float'
|
||||
INT = 'tag:yaml.org,2002:int'
|
||||
SEQ = 'tag:yaml.org,2002:seq'
|
||||
MAP = 'tag:yaml.org,2002:map'
|
||||
|
||||
# non-standard tags
|
||||
LIBRARY = 'tag:gdsii,2010:library'
|
||||
STRUCTURE = 'tag:gdsii,2010:structure'
|
||||
|
||||
BOUNDARY = 'tag:gdsii,2010:element:boundary'
|
||||
PATH = 'tag:gdsii,2010:element:path'
|
||||
SREF = 'tag:gdsii,2010:element:sref'
|
||||
AREF = 'tag:gdsii,2010:element:aref'
|
||||
TEXT = 'tag:gdsii,2010:element:text'
|
||||
NODE = 'tag:gdsii,2010:element:node'
|
||||
BOX = 'tag:gdsii,2010:element:box'
|
||||
|
||||
def emit_string(dumper, prop, tag, value):
|
||||
dumper.emit(events.ScalarEvent(None, STR, (True, False), prop))
|
||||
dumper.emit(events.ScalarEvent(None, tag, (True, False), value))
|
||||
|
||||
def start_named_seq(dumper, name):
|
||||
dumper.emit(events.ScalarEvent(None, STR, (True, False), name))
|
||||
dumper.emit(events.SequenceStartEvent(None, SEQ, True))
|
||||
|
||||
def end_named_seq(dumper):
|
||||
dumper.emit(events.SequenceEndEvent())
|
||||
|
||||
def simple_dumper(name, tag):
|
||||
def dump_fn(dumper, obj):
|
||||
value = getattr(obj, name)
|
||||
emit_string(dumper, name, tag, str(value))
|
||||
return dump_fn
|
||||
|
||||
def simple_string_dumper(name):
|
||||
def dump_fn(dumper, obj):
|
||||
value = getattr(obj, name)
|
||||
emit_string(dumper, name, STR, value.decode())
|
||||
return dump_fn
|
||||
|
||||
def timestamp_dumper(name):
|
||||
def dump_fn(dumper, obj):
|
||||
value = getattr(obj, name)
|
||||
emit_string(dumper, name, TIMESTAMP, value.isoformat(' '))
|
||||
return dump_fn
|
||||
|
||||
def optional_dumper(name, tag):
|
||||
def dump_fn(dumper, obj):
|
||||
try:
|
||||
value = getattr(obj, name)
|
||||
except AttributeError:
|
||||
value = None
|
||||
if value is not None:
|
||||
emit_string(dumper, name, tag, str(value))
|
||||
return dump_fn
|
||||
|
||||
def optional_flags_dumper(name, tag):
|
||||
def dump_fn(dumper, obj):
|
||||
try:
|
||||
value = getattr(obj, name)
|
||||
except AttributeError:
|
||||
value = None
|
||||
if value is not None:
|
||||
emit_string(dumper, name, tag, '0x%x'%value)
|
||||
return dump_fn
|
||||
|
||||
def xy_dumper(name):
|
||||
def dump_fn(dumper, obj):
|
||||
points = getattr(obj, name)
|
||||
start_named_seq(dumper, name)
|
||||
for point in points:
|
||||
dumper.emit(events.SequenceStartEvent(None, SEQ, True, flow_style=True))
|
||||
dumper.emit(events.ScalarEvent(None, INT, (True, False), str(point[0])))
|
||||
dumper.emit(events.ScalarEvent(None, INT, (True, False), str(point[1])))
|
||||
dumper.emit(events.SequenceEndEvent())
|
||||
end_named_seq(dumper)
|
||||
return dump_fn
|
||||
|
||||
def properties_dumper(name):
|
||||
def dump_fn(dumper, obj):
|
||||
properties = getattr(obj, name)
|
||||
if (properties):
|
||||
start_named_seq(dumper, name)
|
||||
for (prop, value) in properties:
|
||||
dumper.emit(events.MappingStartEvent(None, MAP, True))
|
||||
dumper.emit(events.ScalarEvent(None, INT, (True, False), str(prop)))
|
||||
dumper.emit(events.ScalarEvent(None, STR, (True, False), value.decode()))
|
||||
dumper.emit(events.MappingEndEvent())
|
||||
end_named_seq(dumper)
|
||||
return dump_fn
|
||||
|
||||
def strans_dumper(name):
|
||||
my_dumper = optional_flags_dumper('strans', INT)
|
||||
mag = optional_dumper('mag', FLOAT)
|
||||
angle = optional_dumper('angle', FLOAT)
|
||||
def dump_fn(dumper, obj):
|
||||
try:
|
||||
value = getattr(obj, name)
|
||||
except AttributeError:
|
||||
value = None
|
||||
if value is not None:
|
||||
my_dumper(dumper, obj)
|
||||
mag(dumper, obj)
|
||||
angle(dumper, obj)
|
||||
return dump_fn
|
||||
|
||||
elflags = optional_flags_dumper('elflags', INT)
|
||||
plex = optional_dumper('plex', INT)
|
||||
layer = simple_dumper('layer', INT)
|
||||
data_type = simple_dumper('data_type', INT)
|
||||
path_type = optional_dumper('path_type', INT)
|
||||
width = optional_dumper('width', INT)
|
||||
bgn_extn = optional_dumper('bgn_extn', INT)
|
||||
end_extn = optional_dumper('end_extn', INT)
|
||||
struct_name = simple_string_dumper('struct_name')
|
||||
strans = strans_dumper('strans')
|
||||
cols = simple_dumper('cols', INT)
|
||||
rows = simple_dumper('rows', INT)
|
||||
text_type = optional_dumper('text_type', INT)
|
||||
presentation = optional_flags_dumper('presentation', INT)
|
||||
string = simple_string_dumper('string')
|
||||
node_type = simple_dumper('node_type', INT)
|
||||
box_type = simple_dumper('box_type', INT)
|
||||
xy = xy_dumper('xy')
|
||||
properties = properties_dumper('properties')
|
||||
|
||||
DUMPERS = (
|
||||
(elements.Boundary, BOUNDARY, (elflags, plex, layer, data_type, xy, properties)),
|
||||
(elements.Path, PATH, (elflags, plex, layer, data_type, path_type, width, bgn_extn, end_extn, xy, properties)),
|
||||
(elements.SRef, SREF, (elflags, plex, struct_name, strans, xy, properties)),
|
||||
(elements.ARef, AREF, (elflags, plex, struct_name, strans, cols, rows, xy, properties)),
|
||||
(elements.Text, TEXT, (elflags, plex, layer, text_type, presentation, path_type, width, strans, xy, string, properties)),
|
||||
(elements.Node, NODE, (elflags, plex, layer, node_type, xy)),
|
||||
(elements.Box, BOX, (elflags, plex, layer, box_type, xy, properties))
|
||||
)
|
||||
|
||||
def dump_element(dumper, elem):
|
||||
for rec in DUMPERS:
|
||||
if isinstance(elem, rec[0]):
|
||||
tag = rec[1]
|
||||
dumpers = rec[2]
|
||||
dumper.emit(events.MappingStartEvent(None, tag, False))
|
||||
for fn in dumpers:
|
||||
fn(dumper, elem)
|
||||
dumper.emit(events.MappingEndEvent())
|
||||
break
|
||||
else:
|
||||
raise Exception('Unsupported element: %s' % str(elem))
|
||||
|
||||
name = simple_string_dumper('name')
|
||||
mod_time = timestamp_dumper('mod_time')
|
||||
acc_time = timestamp_dumper('acc_time')
|
||||
strclass = optional_dumper('strclass', INT)
|
||||
|
||||
def dump_structure(dumper, struc):
|
||||
dumper.emit(events.MappingStartEvent(None, STRUCTURE, False))
|
||||
name(dumper, struc)
|
||||
mod_time(dumper, struc)
|
||||
acc_time(dumper, struc)
|
||||
strclass(dumper, struc)
|
||||
start_named_seq(dumper, 'elements')
|
||||
for elem in struc:
|
||||
dump_element(dumper, elem)
|
||||
end_named_seq(dumper)
|
||||
dumper.emit(events.MappingEndEvent())
|
||||
|
||||
physical_unit = simple_dumper('physical_unit', FLOAT)
|
||||
logical_unit = simple_dumper('logical_unit', FLOAT)
|
||||
libdirsize = optional_dumper('libdirsize', INT)
|
||||
|
||||
def dump_library(dumper, lib):
|
||||
dumper.emit(events.StreamStartEvent(encoding='utf-8'))
|
||||
dumper.emit(events.DocumentStartEvent(explicit=False))
|
||||
|
||||
dumper.emit(events.MappingStartEvent(None, LIBRARY, False))
|
||||
emit_string(dumper, 'version', INT, '0x%x'%lib.version)
|
||||
name(dumper, lib)
|
||||
mod_time(dumper, lib)
|
||||
acc_time(dumper, lib)
|
||||
libdirsize(dumper, lib)
|
||||
# TODO
|
||||
physical_unit(dumper, lib)
|
||||
logical_unit(dumper, lib)
|
||||
start_named_seq(dumper, 'structures')
|
||||
for struc in lib:
|
||||
dump_structure(dumper, struc)
|
||||
end_named_seq(dumper)
|
||||
dumper.emit(events.MappingEndEvent())
|
||||
|
||||
dumper.emit(events.DocumentEndEvent(explicit=False))
|
||||
dumper.emit(events.StreamEndEvent())
|
||||
|
||||
def main(name):
|
||||
with open(name, 'rb') as a_file:
|
||||
lib = Library.load(stream=a_file)
|
||||
dumper = Dumper(sys.stdout)
|
||||
dump_library(dumper, lib)
|
||||
|
||||
def usage(prog):
|
||||
print('Usage: %s <file.gds>' % prog)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if (len(sys.argv) > 1):
|
||||
main(sys.argv[1])
|
||||
else:
|
||||
usage(sys.argv[0])
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
65
scripts/txt2gds
Executable file
65
scripts/txt2gds
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
#! /usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright © 2011 Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
# This file is licensed under GNU Lesser General Public License version 3 or later.
|
||||
"""Converter from format produced by gds2txt back to GDSII."""
|
||||
from __future__ import print_function
|
||||
from gdsii import tags, types
|
||||
from gdsii.record import Record
|
||||
import sys
|
||||
import getopt
|
||||
import re
|
||||
|
||||
def parse_file(ifile, ofile):
|
||||
rexp = re.compile(r'^(?P<tag>[^:]+)(:\s*(?P<rest>.*))?$')
|
||||
lineno = 1
|
||||
for line in ifile:
|
||||
stripped = line.strip()
|
||||
m = rexp.match(stripped)
|
||||
if not m:
|
||||
print('Parse error at line {0}'.format(lineno), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
tag_name = m.group('tag')
|
||||
rest = m.group('rest')
|
||||
|
||||
tag = tags.DICT[tag_name]
|
||||
|
||||
tag_type = tags.type_of_tag(tag)
|
||||
|
||||
if tag_type == types.NODATA:
|
||||
data = None
|
||||
elif tag_type == types.ASCII:
|
||||
data = rest[1:-1].encode() # FIXME
|
||||
elif tag_type == types.BITARRAY:
|
||||
data = int(rest)
|
||||
elif tag_type == types.REAL8:
|
||||
data = [float(s) for s in rest.split(',')]
|
||||
elif tag_type == types.INT2 or tag_type == types.INT4:
|
||||
data = [int(s) for s in rest.split(',')]
|
||||
else:
|
||||
raise Exception('Unsupported type')
|
||||
rec = Record(tag, data)
|
||||
rec.save(ofile)
|
||||
lineno += 1
|
||||
|
||||
def main(argv):
|
||||
opts, args = getopt.gnu_getopt(argv[1:], 'o:')
|
||||
if len(opts) != 1 or opts[0][0] != '-o' or len(args) > 1:
|
||||
usage(argv[0])
|
||||
sys.exit(2)
|
||||
with open(opts[0][1], 'wb') as ofile:
|
||||
if len(args) == 0:
|
||||
parse_file(sys.stdin, ofile)
|
||||
else:
|
||||
with open(args[0], 'r') as ifile:
|
||||
parse_file(ifile, ofile)
|
||||
|
||||
def usage(prog):
|
||||
print('Usage: %s -o <file.gds> [<input.txt>]' % prog)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
main(sys.argv)
|
||||
else:
|
||||
usage(sys.argv[0])
|
||||
sys.exit(1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue