ruby-gdsii 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.txt +113 -0
  3. data/bin/rgds-debug +43 -0
  4. data/bin/rgds-dump +38 -0
  5. data/bin/rgds-join +98 -0
  6. data/bin/rgds-layers +53 -0
  7. data/bin/rgds-sremove +135 -0
  8. data/bin/rgds-ssplit +113 -0
  9. data/bin/rgds-stats +134 -0
  10. data/bin/rgds-structs +41 -0
  11. data/bin/rgds-tree +166 -0
  12. data/bin/rgds2rb +99 -0
  13. data/lib/gdsii.rb +137 -0
  14. data/lib/gdsii/aref.rb +243 -0
  15. data/lib/gdsii/bnf.rb +309 -0
  16. data/lib/gdsii/boundary.rb +53 -0
  17. data/lib/gdsii/box.rb +65 -0
  18. data/lib/gdsii/byte_order.rb +36 -0
  19. data/lib/gdsii/element.rb +172 -0
  20. data/lib/gdsii/group.rb +98 -0
  21. data/lib/gdsii/library.rb +518 -0
  22. data/lib/gdsii/mixins.rb +378 -0
  23. data/lib/gdsii/node.rb +65 -0
  24. data/lib/gdsii/path.rb +169 -0
  25. data/lib/gdsii/property.rb +108 -0
  26. data/lib/gdsii/record.rb +606 -0
  27. data/lib/gdsii/record/consts.rb +384 -0
  28. data/lib/gdsii/record/datatypes/ascii.rb +145 -0
  29. data/lib/gdsii/record/datatypes/bitarray.rb +101 -0
  30. data/lib/gdsii/record/datatypes/data.rb +111 -0
  31. data/lib/gdsii/record/datatypes/int2.rb +67 -0
  32. data/lib/gdsii/record/datatypes/int4.rb +65 -0
  33. data/lib/gdsii/record/datatypes/nodata.rb +60 -0
  34. data/lib/gdsii/record/datatypes/real4.rb +51 -0
  35. data/lib/gdsii/record/datatypes/real8.rb +120 -0
  36. data/lib/gdsii/sref.rb +61 -0
  37. data/lib/gdsii/strans.rb +133 -0
  38. data/lib/gdsii/structure.rb +352 -0
  39. data/lib/gdsii/text.rb +203 -0
  40. data/pkg/ruby-gdsii.gem +23 -0
  41. data/samples/hello.gds +0 -0
  42. data/samples/hello.out.rb +84 -0
  43. data/samples/hello.rb +94 -0
  44. data/test/baseline/dcp1.gds +0 -0
  45. data/test/baseline/h_write.gds +0 -0
  46. data/test/h_pthru.rb +22 -0
  47. data/test/h_write.rb +117 -0
  48. data/test/hs_pthru.rb +31 -0
  49. data/test/l_pthru.rb +23 -0
  50. data/test/test_gds_group.rb +379 -0
  51. data/test/test_gds_record.rb +99 -0
  52. metadata +118 -0
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+ ##############################################################################
3
+ #
4
+ # == gdsssplit.rb
5
+ #
6
+ # Splits a GDSII file into separate GDSII files. A separate GDSII file will
7
+ # be created for each structure in the original GDSII file and the new GDSII
8
+ # files will be named after their structure name. At this time there are
9
+ # NO sref or aref intelligence (i.e. no hierarchy dependency checking) - so
10
+ # only one structure will exist per file.
11
+ #
12
+ # === Author
13
+ #
14
+ # James D. Masters (james.d.masters@gmail.com)
15
+ #
16
+ # === History
17
+ #
18
+ # * 03/26/2007 (jdm): Initial version
19
+ #
20
+ ##############################################################################
21
+
22
+
23
+ require 'getoptlong'
24
+ require 'gdsii'
25
+ include Gdsii
26
+
27
+ # Build usage message
28
+ usage = "
29
+ Splits a GDSII file into separate GDSII files. A separate GDSII file will
30
+ be created for each structure in the original GDSII file and the new GDSII
31
+ files will be named after their structure name. At this time there are
32
+ NO sref or aref intelligence (i.e. no hierarchy dependency checking) - so
33
+ only one structure will exist per file.
34
+
35
+ Usage: gdsssplit.rb [options] <gds-file> <output-dir>
36
+
37
+ Options:
38
+
39
+ -s, --structs Specify structure(s) in a space separated list to extract.
40
+ The default behavior is to extract all structures.
41
+ -f, --force Force overwritting of GDSII files in the output directory
42
+ if a file by the same name exists.
43
+ -e, --extension Specify the output file GDSII extension to use. Default
44
+ is 'gds'.
45
+ -h, --help Displays this usage message.
46
+
47
+ "
48
+
49
+ # Get command-line arguments
50
+ force = false
51
+ structs = []
52
+ ext = 'gds'
53
+
54
+ opts = GetoptLong.new(
55
+ ['--structs', '-s', GetoptLong::OPTIONAL_ARGUMENT],
56
+ ['--force', '-f', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT],
57
+ ['--extension', '-e', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT],
58
+ ['--help', '-h', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT]
59
+ )
60
+
61
+ opts.each do |option, argument|
62
+ case option
63
+ when '--help' : abort usage
64
+ when '--structs' : structs = argument.split(/\s+/)
65
+ when '--extension' : ext = argument
66
+ when '--force' : force = true
67
+ end
68
+ end
69
+
70
+ # Get GDSII file and output directory from command line
71
+ gds_file, output_dir = ARGV
72
+ unless gds_file and output_dir
73
+ abort usage
74
+ end
75
+
76
+ # Check that GDSII file is readable and that output dir is writable
77
+ unless File.readable? gds_file
78
+ abort "\nGDSII file does not exist or is not readable: #{gds_file}\n\n" + usage
79
+ end
80
+
81
+ # Check that output directory is writable
82
+ unless File.directory? output_dir and File.writable? output_dir
83
+ abort "\nOutput directory is not writable: #{output_dir}\n\n" + usage
84
+ end
85
+
86
+
87
+ # Read the GDSII file and write out resulting GDSII files
88
+ File.open(gds_file, 'rb') do |inf|
89
+ Library.read_header(inf) do |lib|
90
+ Structure.read_each_header(inf) do |struct|
91
+ if structs.empty? or structs.member?(struct.name)
92
+ # write lib & structure header to file
93
+ file_name = "#{output_dir}/#{struct.name}.#{ext}"
94
+ if File.exists? file_name and not force
95
+ warn "WARNING: #{file_name} already exists; use --force to override"
96
+ else
97
+ # open the file
98
+ File.open(file_name, 'wb') do |outf|
99
+ lib.write_header(outf)
100
+ struct.write_header(outf)
101
+ Element.read_each(inf) {|element| element.write(outf)}
102
+ struct.write_footer(outf)
103
+ lib.write_footer(outf)
104
+ end
105
+ end
106
+ else
107
+ # structure not on list; skip to next
108
+ Structure.seek_next(inf)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env ruby
2
+ ##############################################################################
3
+ #
4
+ # == gdsstats.rb
5
+ #
6
+ # Dumps statistical information from a GDSII file.
7
+ #
8
+ # === Author
9
+ #
10
+ # James D. Masters (james.d.masters@gmail.com)
11
+ #
12
+ # === History
13
+ #
14
+ # * 03/26/2007 (jdm): Initial version
15
+ #
16
+ ##############################################################################
17
+
18
+
19
+ require 'getoptlong'
20
+ require 'gdsii/record.rb'
21
+ include Gdsii
22
+
23
+ # Build usage message
24
+ usage = "
25
+ Dumps statistical information from a GDSII file.
26
+
27
+ Usage: gdsssplit.rb [options] <gds-file>
28
+
29
+ Options:
30
+
31
+ -s, --structs Specify structure(s) in a space separated list to process.
32
+ The default behavior is to process all structures.
33
+ -h, --help Displays this usage message.
34
+
35
+ "
36
+
37
+ # Get command-line arguments
38
+ structs = []
39
+
40
+ opts = GetoptLong.new(
41
+ ['--structs', '-s', GetoptLong::OPTIONAL_ARGUMENT],
42
+ ['--help', '-h', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT]
43
+ )
44
+
45
+ opts.each do |option, argument|
46
+ case option
47
+ when '--help' : abort usage
48
+ when '--structs' : structs = argument.split(/\s+/)
49
+ end
50
+ end
51
+
52
+ # Get GDSII file directory from command line
53
+ unless (gds_file = ARGV[0])
54
+ abort usage
55
+ end
56
+
57
+ # Read the GDSII file and write out resulting GDSII files
58
+ File.open(gds_file, 'rb') do |inf|
59
+
60
+ # Set statistics hashes:
61
+ # lib_stats = Hash.new {|h,k| h[k] = 0}
62
+ str_stats = Hash.new {|h,k| h[k] = Hash.new {|h2,k2| h2[k2] = 0}}
63
+
64
+ # Set parse flags
65
+ strname = nil
66
+ dt_cxt = nil
67
+ layer = nil
68
+
69
+ # Read each record in the GDSII file
70
+ Record.read_each(inf) do |record|
71
+
72
+ type = record.type
73
+
74
+ case type
75
+ when GRT_STRNAME
76
+ # New structure definition... print header
77
+ strname = record.data_value
78
+ if structs.empty? or structs.member?(strname)
79
+ puts
80
+ puts '#' * 78
81
+ puts
82
+ puts "STRUCTURE: #{strname}"
83
+ # lib_stats[type] += 1
84
+ end
85
+ when GRT_SREF, GRT_AREF
86
+ # increment count for sref, aref, text, node, box
87
+ str_stats[nil][type] += 1
88
+ when GRT_BOUNDARY
89
+ # set datatype context to BOUNDARY
90
+ dt_cxt = type
91
+ when GRT_PATH
92
+ # set datatype context to PATH
93
+ dt_cxt = type
94
+ when GRT_LAYER
95
+ # capture the layer number - record when context is reached
96
+ layer = record.data_value
97
+ when GRT_DATATYPE, GRT_TEXTTYPE, GRT_NODETYPE, GRT_BOXTYPE
98
+ # record the layer for the given layer context
99
+ datatype = record.data_value
100
+ rec_num = (dt_cxt) ? dt_cxt : type
101
+ str_stats[[layer, datatype]][rec_num] += 1
102
+ dt_cxt = nil
103
+ when GRT_ENDSTR
104
+ # end structure definition
105
+ if structs.empty? or structs.member?(strname)
106
+ puts
107
+ printf("SRefs: %-12d\n", str_stats[nil][GRT_SREF])
108
+ printf("ARefs: %-12d\n", str_stats[nil][GRT_AREF])
109
+ puts
110
+ puts "Layer Type # Bnd # Path # Text # Box # Node"
111
+ puts '-' * 78
112
+
113
+ # Show layer information
114
+ layers = str_stats.keys.compact.sort {|a, b| (a[0] <=> b[0]) <=> (a[1] <=> b[1])}
115
+ layers.each do |layer|
116
+ printf("%-6d %-6d %11d %11d %11d %11d %11d\n",
117
+ layer[0],
118
+ layer[1],
119
+ str_stats[layer][GRT_BOUNDARY],
120
+ str_stats[layer][GRT_PATH],
121
+ str_stats[layer][GRT_TEXTTYPE],
122
+ str_stats[layer][GRT_BOXTYPE],
123
+ str_stats[layer][GRT_NODETYPE]
124
+ )
125
+ end
126
+ puts
127
+ end
128
+ str_stats.delete_if {|key,value| true}
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ ##############################################################################
3
+ #
4
+ # == gdsstructs.rb
5
+ #
6
+ #
7
+ # === Author
8
+ #
9
+ # James D. Masters (james.d.masters@gmail.com)
10
+ #
11
+ # === History
12
+ #
13
+ # * 03/26/2007 (jdm): Initial version
14
+ #
15
+ ##############################################################################
16
+
17
+
18
+ require 'getoptlong'
19
+ require 'gdsii/record.rb'
20
+ include Gdsii
21
+
22
+ # Build usage message
23
+ if (file_name = ARGV[0]).nil? then
24
+ abort "
25
+ Dumps a of structure names defined in the GDSII file.
26
+
27
+ Usage: gdsstructs.rb <gds-file>
28
+
29
+ "
30
+ end
31
+
32
+ # Extract the structure names from the GDSII file
33
+ File.open(file_name, 'rb') do |file|
34
+ while (record = Record.read(file)) do
35
+ if record.is_strname?
36
+ puts record.data_value
37
+ end
38
+ end
39
+ end
40
+
41
+
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env ruby
2
+ ##############################################################################
3
+ #
4
+ # == gdstree.rb
5
+ #
6
+ # Dumps a hierarchy tree of structures used within a given GDSII file.
7
+ #
8
+ # === Author
9
+ #
10
+ # James D. Masters (james.d.masters@gmail.com)
11
+ #
12
+ # === History
13
+ #
14
+ # * 03/27/2007 (jdm): Initial version
15
+ #
16
+ #
17
+ ##############################################################################
18
+
19
+
20
+ require 'getoptlong'
21
+ require 'gdsii/record.rb'
22
+ include Gdsii
23
+
24
+ # Build usage message
25
+ usage = "
26
+ Dumps a hierarchy tree of structures used within a given GDSII file.
27
+
28
+ Usage: gdstree.rb [options] <gds-file>
29
+
30
+ Options:
31
+
32
+ -t, --top-structs Explicitly specify the top structure name(s) to use in
33
+ the tree. The default behavior is to identify the top
34
+ structure(s) in the hierarchy automatically.
35
+ -c, --inst-counts Include instantiation counts in the tree.
36
+ -b, --broken-refs Indicate how broken references are handled. Possible values
37
+ are 'annotate' or 'prune'. The default behavior is to
38
+ ignore broken references.
39
+ -d, --delimiter Set hierarchy delimiter (default is '/').
40
+ -h, --help Displays this usage message.
41
+
42
+ Examples:
43
+
44
+ ruby gdstree.rb design.gds
45
+ ruby gdstree.rb --delimiter . design.gds
46
+ ruby gdstree.rb --inst-counts design.gds
47
+ ruby gdstree.rb --top-structs 'mytop othertop' --broken-refs annotate
48
+
49
+ "
50
+
51
+ # Get command-line arguments
52
+ top_structs = []
53
+ show_inst_counts = false
54
+ broken_refs = nil
55
+ delimiter = '/'
56
+
57
+ opts = GetoptLong.new(
58
+ ['--top-structs', '-t', GetoptLong::OPTIONAL_ARGUMENT],
59
+ ['--inst-counts', '-c', GetoptLong::NO_ARGUMENT],
60
+ ['--broken-refs', '-b', GetoptLong::OPTIONAL_ARGUMENT],
61
+ ['--delimiter', '-d', GetoptLong::OPTIONAL_ARGUMENT],
62
+ ['--help', '-h', GetoptLong::NO_ARGUMENT]
63
+ )
64
+
65
+ opts.each do |option, argument|
66
+ case option
67
+ when '--top-structs' : top_structs = argument.split(/\s+/)
68
+ when '--inst-counts' : show_inst_counts = argument
69
+ when '--broken-refs' : broken_refs = argument
70
+ when '--delimiter' : delimiter = argument
71
+ when '--help' : abort usage
72
+ end
73
+ end
74
+
75
+ # Get GDSII file directory from command line
76
+ unless (gds_file = ARGV[0])
77
+ abort usage
78
+ end
79
+
80
+
81
+ #
82
+ # Class to define a structure within the hierarchy
83
+ #
84
+ class HierStruct
85
+ # Make the attributes accessible
86
+ attr_accessor :name, :children
87
+
88
+ # Create a new HierStruct
89
+ def initialize(name, delimiter, inst_counts, broken_refs)
90
+ @name = name
91
+ @delimiter = delimiter
92
+ @inst_counts = inst_counts
93
+ @broken_refs = broken_refs.to_sym unless broken_refs.nil?
94
+ @children = Hash.new {|hash, key| hash[key] = 0}
95
+ end
96
+
97
+ # Display the hierarchy of this HierStruct
98
+ def puts(structs, prefix='', suffix='')
99
+ # build the hierarchy string then display it
100
+ string = prefix + @delimiter + @name + suffix
101
+ $stdout.puts string
102
+
103
+ # display the hierarchy for all children of this struct
104
+ @children.each_pair do |struct_name, num_placed|
105
+
106
+ cnt_suffix = (@inst_counts) ? "(#{num_placed})" : ''
107
+
108
+ if (struct = structs[struct_name])
109
+ # display the child's hierarchy
110
+ struct.puts(structs, string, cnt_suffix)
111
+ else
112
+ # broken reference; deal with appropriately
113
+ case @broken_refs
114
+ when :annotate : $stdout.puts string + '(MISSING)'
115
+ when :prune : nil
116
+ else
117
+ $stdout.puts string + @delimiter + struct_name + cnt_suffix
118
+ end
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+
125
+
126
+ #
127
+ # Main code
128
+ #
129
+
130
+ # get the structure and instance placement from the gdsii file
131
+ structs = {}
132
+ has_parent = {}
133
+ File.open(gds_file, 'rb') do |file|
134
+ while (rec=Record.read(file)) do
135
+ if rec.is_strname?
136
+ # inside a structure definition
137
+ str = HierStruct.new(rec.data_value, delimiter, show_inst_counts, broken_refs)
138
+ structs[str.name] = str
139
+ has_parent[str.name] = false unless has_parent.has_key?(str.name)
140
+ elsif rec.is_sname?
141
+ # instance in this structure
142
+ ref_str = rec.data_value
143
+ str.children[ref_str] += 1
144
+ has_parent[ref_str] = true
145
+ end
146
+ end
147
+ end
148
+
149
+
150
+ # if the user provides a list of top structure names, then use that list;
151
+ # otherwise build our own.
152
+ if top_structs.empty?
153
+ top_structs = has_parent.delete_if {|key, value| value}.keys.sort
154
+ end
155
+
156
+ # Output hierarch(y/ies)...
157
+ unless top_structs.empty?
158
+ top_structs.each do |struct|
159
+ if structs.has_key?(struct)
160
+ structs[struct].puts(structs)
161
+ else
162
+ warn "WARNING: structure #{struct} not found"
163
+ end
164
+ end
165
+ end
166
+