jfreeze-ruby-gdsii 1.0.1

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 (54) hide show
  1. data/CHANGELOG.txt +6 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.txt +113 -0
  4. data/Rakefile +30 -0
  5. data/bin/rgds-debug +43 -0
  6. data/bin/rgds-dump +38 -0
  7. data/bin/rgds-join +98 -0
  8. data/bin/rgds-layers +53 -0
  9. data/bin/rgds-sremove +136 -0
  10. data/bin/rgds-ssplit +113 -0
  11. data/bin/rgds-stats +134 -0
  12. data/bin/rgds-structs +41 -0
  13. data/bin/rgds-tree +167 -0
  14. data/bin/rgds2rb +99 -0
  15. data/lib/gdsii.rb +137 -0
  16. data/lib/gdsii/aref.rb +243 -0
  17. data/lib/gdsii/bnf.rb +309 -0
  18. data/lib/gdsii/boundary.rb +53 -0
  19. data/lib/gdsii/box.rb +65 -0
  20. data/lib/gdsii/byte_order.rb +36 -0
  21. data/lib/gdsii/element.rb +172 -0
  22. data/lib/gdsii/group.rb +98 -0
  23. data/lib/gdsii/library.rb +518 -0
  24. data/lib/gdsii/mixins.rb +378 -0
  25. data/lib/gdsii/node.rb +65 -0
  26. data/lib/gdsii/path.rb +169 -0
  27. data/lib/gdsii/property.rb +108 -0
  28. data/lib/gdsii/record.rb +606 -0
  29. data/lib/gdsii/record/consts.rb +384 -0
  30. data/lib/gdsii/record/datatypes/ascii.rb +145 -0
  31. data/lib/gdsii/record/datatypes/bitarray.rb +101 -0
  32. data/lib/gdsii/record/datatypes/data.rb +111 -0
  33. data/lib/gdsii/record/datatypes/int2.rb +67 -0
  34. data/lib/gdsii/record/datatypes/int4.rb +65 -0
  35. data/lib/gdsii/record/datatypes/nodata.rb +60 -0
  36. data/lib/gdsii/record/datatypes/real4.rb +51 -0
  37. data/lib/gdsii/record/datatypes/real8.rb +120 -0
  38. data/lib/gdsii/sref.rb +61 -0
  39. data/lib/gdsii/strans.rb +133 -0
  40. data/lib/gdsii/structure.rb +352 -0
  41. data/lib/gdsii/text.rb +203 -0
  42. data/pkg/ruby-gdsii.gem +46 -0
  43. data/samples/hello.gds +0 -0
  44. data/samples/hello.out.rb +84 -0
  45. data/samples/hello.rb +94 -0
  46. data/test/baseline/dcp1.gds +0 -0
  47. data/test/baseline/h_write.gds +0 -0
  48. data/test/h_pthru.rb +22 -0
  49. data/test/h_write.rb +117 -0
  50. data/test/hs_pthru.rb +31 -0
  51. data/test/l_pthru.rb +23 -0
  52. data/test/test_gds_group.rb +379 -0
  53. data/test/test_gds_record.rb +99 -0
  54. metadata +117 -0
data/bin/rgds-ssplit ADDED
@@ -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: #{File.basename($PROGRAM_NAME)} [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
+
data/bin/rgds-stats ADDED
@@ -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: #{File.basename($PROGRAM_NAME)} [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
+
data/bin/rgds-structs ADDED
@@ -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: #{File.basename($PROGRAM_NAME)} <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
+
data/bin/rgds-tree ADDED
@@ -0,0 +1,167 @@
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
+ program = File.basename($PROGRAM_NAME)
26
+ usage = "
27
+ Dumps a hierarchy tree of structures used within a given GDSII file.
28
+
29
+ Usage: #{File.basename($PROGRAM_NAME)} [options] <gds-file>
30
+
31
+ Options:
32
+
33
+ -t, --top-structs Explicitly specify the top structure name(s) to use in
34
+ the tree. The default behavior is to identify the top
35
+ structure(s) in the hierarchy automatically.
36
+ -c, --inst-counts Include instantiation counts in the tree.
37
+ -b, --broken-refs Indicate how broken references are handled. Possible values
38
+ are 'annotate' or 'prune'. The default behavior is to
39
+ ignore broken references.
40
+ -d, --delimiter Set hierarchy delimiter (default is '/').
41
+ -h, --help Displays this usage message.
42
+
43
+ Examples:
44
+
45
+ ruby #{program} design.gds
46
+ ruby #{program} --delimiter . design.gds
47
+ ruby #{program} --inst-counts design.gds
48
+ ruby #{program} --top-structs 'mytop othertop' --broken-refs annotate
49
+
50
+ "
51
+
52
+ # Get command-line arguments
53
+ top_structs = []
54
+ show_inst_counts = false
55
+ broken_refs = nil
56
+ delimiter = '/'
57
+
58
+ opts = GetoptLong.new(
59
+ ['--top-structs', '-t', GetoptLong::OPTIONAL_ARGUMENT],
60
+ ['--inst-counts', '-c', GetoptLong::NO_ARGUMENT],
61
+ ['--broken-refs', '-b', GetoptLong::OPTIONAL_ARGUMENT],
62
+ ['--delimiter', '-d', GetoptLong::OPTIONAL_ARGUMENT],
63
+ ['--help', '-h', GetoptLong::NO_ARGUMENT]
64
+ )
65
+
66
+ opts.each do |option, argument|
67
+ case option
68
+ when '--top-structs' : top_structs = argument.split(/\s+/)
69
+ when '--inst-counts' : show_inst_counts = argument
70
+ when '--broken-refs' : broken_refs = argument
71
+ when '--delimiter' : delimiter = argument
72
+ when '--help' : abort usage
73
+ end
74
+ end
75
+
76
+ # Get GDSII file directory from command line
77
+ unless (gds_file = ARGV[0])
78
+ abort usage
79
+ end
80
+
81
+
82
+ #
83
+ # Class to define a structure within the hierarchy
84
+ #
85
+ class HierStruct
86
+ # Make the attributes accessible
87
+ attr_accessor :name, :children
88
+
89
+ # Create a new HierStruct
90
+ def initialize(name, delimiter, inst_counts, broken_refs)
91
+ @name = name
92
+ @delimiter = delimiter
93
+ @inst_counts = inst_counts
94
+ @broken_refs = broken_refs.to_sym unless broken_refs.nil?
95
+ @children = Hash.new {|hash, key| hash[key] = 0}
96
+ end
97
+
98
+ # Display the hierarchy of this HierStruct
99
+ def puts(structs, prefix='', suffix='')
100
+ # build the hierarchy string then display it
101
+ string = prefix + @delimiter + @name + suffix
102
+ $stdout.puts string
103
+
104
+ # display the hierarchy for all children of this struct
105
+ @children.each_pair do |struct_name, num_placed|
106
+
107
+ cnt_suffix = (@inst_counts) ? "(#{num_placed})" : ''
108
+
109
+ if (struct = structs[struct_name])
110
+ # display the child's hierarchy
111
+ struct.puts(structs, string, cnt_suffix)
112
+ else
113
+ # broken reference; deal with appropriately
114
+ case @broken_refs
115
+ when :annotate : $stdout.puts string + '(MISSING)'
116
+ when :prune : nil
117
+ else
118
+ $stdout.puts string + @delimiter + struct_name + cnt_suffix
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ #
128
+ # Main code
129
+ #
130
+
131
+ # get the structure and instance placement from the gdsii file
132
+ structs = {}
133
+ has_parent = {}
134
+ File.open(gds_file, 'rb') do |file|
135
+ while (rec=Record.read(file)) do
136
+ if rec.is_strname?
137
+ # inside a structure definition
138
+ str = HierStruct.new(rec.data_value, delimiter, show_inst_counts, broken_refs)
139
+ structs[str.name] = str
140
+ has_parent[str.name] = false unless has_parent.has_key?(str.name)
141
+ elsif rec.is_sname?
142
+ # instance in this structure
143
+ ref_str = rec.data_value
144
+ str.children[ref_str] += 1
145
+ has_parent[ref_str] = true
146
+ end
147
+ end
148
+ end
149
+
150
+
151
+ # if the user provides a list of top structure names, then use that list;
152
+ # otherwise build our own.
153
+ if top_structs.empty?
154
+ top_structs = has_parent.delete_if {|key, value| value}.keys.sort
155
+ end
156
+
157
+ # Output hierarch(y/ies)...
158
+ unless top_structs.empty?
159
+ top_structs.each do |struct|
160
+ if structs.has_key?(struct)
161
+ structs[struct].puts(structs)
162
+ else
163
+ warn "WARNING: structure #{struct} not found"
164
+ end
165
+ end
166
+ end
167
+