ruby-gdsii 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+