jfreeze-ruby-gdsii 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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/test/h_write.rb ADDED
@@ -0,0 +1,117 @@
1
+ ##############################################################################
2
+ #
3
+ # == write.rb
4
+ #
5
+ # Tests the capabilities of writing GDSII using the high-level group objects.
6
+ # This test should cover most of the capabilities of the high-level GDSII
7
+ # methods.
8
+ #
9
+ # === Author
10
+ #
11
+ # James D. Masters (james.d.masters@gmail.com)
12
+ #
13
+ ##############################################################################
14
+
15
+ require 'time'
16
+ require 'gdsii'
17
+
18
+ include Gdsii
19
+
20
+
21
+ # Get arguments / show usage...
22
+ unless (out_file = ARGV[0])
23
+ abort "
24
+ Uses high-level GDSII methods to write out a number of GDSII records using
25
+ many of the available method calls. This can be useful to verify that the
26
+ GDSII library is working and the output file can be compared against the
27
+ file found in ./test/baseline/h_write.gds to ensure that the platform is
28
+ reading and writing GDSII properly.
29
+
30
+ Usage: h_write.rb <out-file>
31
+
32
+ "
33
+ end
34
+
35
+
36
+ # Get a standard time (epoch; 12/31/1969) so we have the same time stamp for
37
+ # comparing GDSII output
38
+ time = Time.utc(2000, 1, 1, 0, 0, 0)
39
+
40
+ # Create a new GDSII library
41
+ lib = Library.new('MYLIB.DB')
42
+ lib.modify_time = time
43
+ lib.access_time = time
44
+
45
+ # Create a top level structure
46
+ top = Structure.new('top')
47
+ top.create_time = time
48
+ top.modify_time = time
49
+
50
+ # Create a box 5u square on layer 1:0 with the center at the origin
51
+ Boundary.new(1, 0, [-2500,-2500, -2500,2500, 2500,2500, 2500,-2500, -2500,-2500]) do |bnd|
52
+ bnd.add Property.new(1, 'testprop1')
53
+ bnd.add Property.new(1, 'testprop2')
54
+ bnd.add Property.new(2, 'testprop3')
55
+ top.add bnd
56
+ end
57
+
58
+ # Create text labels around the 5u box using different text label origins
59
+ top.add Text.new(1, 0, [0,0], 'c', 0, :c )
60
+ top.add Text.new(1, 0, [0,2500], 'n', 0, :n )
61
+ top.add Text.new(1, 0, [2500,2500], 'ne', 0, :ne)
62
+ top.add Text.new(1, 0, [2500,0], 'e', 0, :e )
63
+ top.add Text.new(1, 0, [2500,-2500], 'se', 0, :se)
64
+ top.add Text.new(1, 0, [0,-2500], 's', 0, :s )
65
+ top.add Text.new(1, 0, [-2500,-2500], 'sw', 0, :sw)
66
+ top.add Text.new(1, 0, [-2500,0], 'w', 0, :w )
67
+ top.add Text.new(1, 0, [-2500,2500], 'nw', 0, :nw)
68
+
69
+ # Test different fonts
70
+ 0.upto(3) do |font|
71
+ top.add Text.new(1, 0, [0, -500*font-3000], "font#{font}", font)
72
+ end
73
+
74
+ # Create a via/contact structure
75
+ via = Structure.new('via')
76
+ via.create_time = time
77
+ via.modify_time = time
78
+
79
+ lib.add via
80
+ via.add Boundary.new(1, 0, [-500,-500, -500,500, 500,500, 500,-500, -500,-500])
81
+ via.add Boundary.new(2, 0, [-800,-800, -800,800, 800,800, 800,-800, -800,-800])
82
+ via.add Boundary.new(3, 0, [-600,-600, -600,600, 600,600, 600,-600, -600,-600])
83
+
84
+ # Create a transistor structure - use our via cell for gate and source/drain
85
+ # terminals
86
+ lib.add trans = Structure.new('trans')
87
+ trans.create_time = time
88
+ trans.modify_time = time
89
+
90
+ trans.add Boundary.new(1, 0, [-2500,-5000, -2500,5000, 2500,5000, 2500,-5000, -2500,-5000])
91
+ trans.add Path.new(4, 0, 0, 800, [0,-7000, 0,7000])
92
+ trans.add SRef.new('via', [-1700,0])
93
+ trans.add SRef.new('via', [1700,0])
94
+ trans.add SRef.new('via', [0,7000])
95
+
96
+ # Drop transistor cell down every 1.5u using different rotations and flip/x
97
+ x_offset = 0
98
+ [false, true].each do |reflect_x|
99
+ 0.step(270, 90) do |angle|
100
+ # Create an sref with the reflection and angle
101
+ SRef.new('trans', [x_offset, 12000]) do |sref|
102
+ sref.strans.reflect_x = reflect_x
103
+ sref.strans.angle = angle.to_f
104
+ top.add sref
105
+ end
106
+
107
+ # Add annotation text indicating reflection and angle
108
+ top.add Text.new(1, 0, [x_offset, 20000], "reflect_x=#{reflect_x}", 0, :c)
109
+ top.add Text.new(1, 0, [x_offset, 20500], "angle=#{angle.to_f.to_s}", 0, :c)
110
+
111
+ x_offset += 15000
112
+ end
113
+ end
114
+
115
+ # Write the library to file
116
+ lib.add top
117
+ lib.write(out_file)
data/test/hs_pthru.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'gdsii'
2
+ include Gdsii
3
+
4
+ in_file, out_file = ARGV
5
+ unless in_file and out_file
6
+ abort "
7
+ Uses the GDSII high-level *streamlined* methods to read in a GDSII file and
8
+ write out the contents in one pass. The resulting GDSII file should be
9
+ identical - or at least just have just EOF null-padding differences.
10
+
11
+ hs_pthru.rb <in-file> <out-file>
12
+
13
+ "
14
+ end
15
+
16
+ File.open(in_file, 'rb') do |inf|
17
+ File.open(out_file, 'wb') do |outf|
18
+ puts "Reading from #{in_file}..."
19
+ puts "Writing to #{out_file}..."
20
+ Library.read_header(inf) do |lib|
21
+ lib.write_header(outf) do
22
+ Structure.read_each_header(inf) do |struct|
23
+ struct.write_header(outf) do
24
+ Element.read_each(inf) {|element| element.write(outf)}
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
data/test/l_pthru.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'gdsii/record'
2
+ include Gdsii
3
+
4
+ in_file, out_file = ARGV
5
+ unless in_file and out_file
6
+ abort "
7
+ Uses the GDSII low-level methods to read in a GDSII file and then write out
8
+ the same GDSII file. The file should be identical - or at least just have
9
+ just EOF null-padding differences.
10
+
11
+ l_pthru.rb <in-file> <out-file>
12
+
13
+ "
14
+ end
15
+
16
+ File.open(in_file, 'rb') do |inf|
17
+ File.open(out_file, 'wb') do |outf|
18
+ while (rec = Record.read(inf))
19
+ rec.write(outf)
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,379 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gdsii/boundary'
3
+ require 'gdsii/path'
4
+ require 'gdsii/strans'
5
+ require 'gdsii/text'
6
+ require 'gdsii/box'
7
+ require 'gdsii/node'
8
+ require 'gdsii/sref'
9
+ require 'gdsii/aref'
10
+ require 'gdsii/structure'
11
+ require 'gdsii/library'
12
+ require 'test/unit'
13
+
14
+
15
+ class GdsGroupTest < Test::Unit::TestCase
16
+
17
+ # This is just for Ruby In Steel bug
18
+ include Gdsii
19
+
20
+ # Test a property item
21
+ def test_property()
22
+ p = Property.new(1, 'test')
23
+ assert_equal 1, p.attr
24
+ assert_equal 'test', p.value
25
+ end
26
+
27
+ ############################################################################
28
+
29
+ # Test BOUNDARY items
30
+ def test_boundary()
31
+ b = Boundary.new(0, 1, [2,3])
32
+ assert_equal(0, b.layer)
33
+ assert_equal(1, b.datatype)
34
+ assert_equal([2,3], b.xy)
35
+
36
+ b.xy=[4,5]
37
+ b.layer = 10
38
+ b.datatype = 11
39
+ assert_equal(10, b.layer)
40
+ assert_equal(11, b.datatype)
41
+ assert_equal([4,5], b.xy)
42
+
43
+ # test setting/removing of properties
44
+ b.properties.add Property.new(0, 'test1')
45
+ b.properties.add Property.new(0, 'test2')
46
+ b.properties.add Property.new(1, 'test3')
47
+
48
+ assert_equal(3, b.properties.length)
49
+ assert_equal('test2', b.properties[1].value)
50
+
51
+ # test removing of properties
52
+ b.properties.remove {|p| p.attr == 0}
53
+ assert_equal(1, b.properties.length)
54
+ assert_equal('test3', b.properties[0].value)
55
+ end
56
+
57
+ ############################################################################
58
+
59
+ # Test Strans object
60
+ def test_strans(object=nil)
61
+ if object
62
+ #
63
+ # Test strans on an object
64
+ #
65
+ object.strans.abs_angle = true
66
+ object.strans.abs_mag = true
67
+ object.strans.reflect_x = true
68
+ object.strans.angle=50.0
69
+ object.strans.mag = 10.3
70
+ assert object.strans.abs_angle?
71
+ assert object.strans.abs_mag?
72
+ assert object.strans.reflect_x?
73
+ assert_equal(50.0, object.strans.angle)
74
+ assert_equal(10.3, object.strans.mag)
75
+ else
76
+ #
77
+ # stand alone test
78
+ #
79
+
80
+ s = Strans.new(2.2, 90.0)
81
+ assert_equal 2.2, s.mag
82
+ assert_equal 90.0, s.angle
83
+ assert_equal false, s.reflect_x?
84
+ assert_equal false, s.abs_mag?
85
+ assert_equal false, s.abs_angle?
86
+
87
+ # Tweak x-reflection
88
+ s.reflect_x = true
89
+ assert s.reflect_x?
90
+ s.reflect_x = false
91
+ assert_equal false, s.reflect_x?
92
+
93
+ # Tweak absolute magnification bit
94
+ s.abs_mag = true
95
+ assert s.abs_mag?
96
+ s.abs_mag = false
97
+ assert_equal false, s.abs_mag?
98
+
99
+ # Tweak absolute angle bit
100
+ s.abs_angle = true
101
+ assert s.abs_angle?
102
+ s.abs_angle = false
103
+ assert_equal false, s.abs_angle?
104
+ end
105
+ end
106
+
107
+ ############################################################################
108
+
109
+ # Test PATH items
110
+ def test_path()
111
+ # Create a new path; check properties
112
+ a = Path.new(5, 3, 0, 10, [1,2])
113
+ assert_equal([1,2], a.xy)
114
+ assert_equal(5, a.layer)
115
+ assert_equal(3, a.datatype)
116
+ assert_equal(10, a.width)
117
+ assert_equal(0, a.pathtype)
118
+ assert_equal(nil, a.bgnextn)
119
+ assert_equal(nil, a.endextn)
120
+
121
+ # Change layer, datatype, width, and path type; add begin/end extensions
122
+ # Also change xy coordinates
123
+ a.layer = 1
124
+ a.datatype = 0
125
+ a.width = 100
126
+ a.xy = [9,10]
127
+ a.pathtype = 4
128
+ a.bgnextn = 50
129
+ a.endextn = 25
130
+ assert_equal(1, a.layer)
131
+ assert_equal(0, a.datatype)
132
+ assert_equal(100, a.width)
133
+ assert_equal([9,10], a.xy)
134
+ assert_equal(4, a.pathtype)
135
+ assert_equal(50, a.bgnextn)
136
+ assert_equal(25, a.endextn)
137
+
138
+ # Try to set begin/end extensions for path type 0
139
+ a.pathtype = 0
140
+ assert_raise(TypeError) { a.bgnextn = 100 }
141
+ assert_raise(TypeError) { a.endextn = 100 }
142
+ assert_raise(TypeError) { a.pathtype = 3 }
143
+
144
+ # Create a path of type 4
145
+ b = Path.new4(2, 0, 100, 0, 50, [0,0, 2000,0, 2000,2000, 4000,2000])
146
+ assert_equal(4, b.pathtype)
147
+ assert_equal(0, b.bgnextn)
148
+ assert_equal(50, b.endextn)
149
+ end
150
+
151
+ ############################################################################
152
+
153
+ def test_text()
154
+ a = Text.new(1, 0, [0,0], 'test')
155
+ assert_equal(1, a.layer)
156
+ assert_equal(0, a.texttype)
157
+ assert_equal([0,0], a.xy)
158
+ assert_equal('test', a.string)
159
+
160
+ # Test font numbers
161
+ 0.upto(3) do |i|
162
+ a.font = i
163
+ assert_equal i, a.font
164
+ end
165
+ assert_raise(ArgumentError) { a.font = 4 }
166
+
167
+ # Test compass points
168
+ [:c, :n, :ne, :e, :se, :s, :sw, :w, :nw].each do |point|
169
+ a.origin = point
170
+ assert_equal point, a.origin
171
+ end
172
+ assert_raise(RuntimeError) { a.origin = :foo }
173
+ end
174
+
175
+ ############################################################################
176
+
177
+ # Test BOX items
178
+ def test_box()
179
+ a = Box.new(1, 0, [0,0, 0,10, 10,10, 10,0, 0,0])
180
+ assert_equal 1, a.layer
181
+ assert_equal 0, a.boxtype
182
+ assert_equal [0,0], a.xy[0,2]
183
+
184
+ a.layer = 5
185
+ a.boxtype = 3
186
+ assert_equal(5, a.layer)
187
+ assert_equal(3, a.boxtype)
188
+ end
189
+
190
+ ############################################################################
191
+
192
+ # Test NODE items
193
+ def test_node()
194
+ a = Node.new(1, 0, [0,0])
195
+ assert_equal 1, a.layer
196
+ assert_equal 0, a.nodetype
197
+ assert_equal [0,0], a.xy
198
+
199
+ a.layer = 5
200
+ a.nodetype = 3
201
+ assert_equal(5, a.layer)
202
+ assert_equal(3, a.nodetype)
203
+ end
204
+
205
+ ############################################################################
206
+
207
+ # Test SRef items
208
+ def test_sref()
209
+ a = SRef.new('TestCell', [1,2])
210
+ assert_equal("TestCell", a.sname)
211
+ assert_equal([1,2], a.xy)
212
+
213
+ a.sname = 'Test2'
214
+ a.xy = [8,9]
215
+ assert_equal('Test2', a.sname)
216
+ assert_equal([8,9], a.xy)
217
+
218
+ # run tests on strans of this object
219
+ test_strans(a)
220
+ end
221
+
222
+ ############################################################################
223
+
224
+ # Test AREF items
225
+ def test_aref()
226
+ # basic testing
227
+ a = ARef.new('TestCell', [0,0], [2,8], [200, 300])
228
+ assert_equal([0,0], a.ref_xy)
229
+ assert_equal(2, a.columns)
230
+ assert_equal(8, a.rows)
231
+ assert_equal(200, a.column_space)
232
+ assert_equal(300, a.row_space)
233
+ assert_equal([0,0, 400,0, 0,2400], a.xy)
234
+
235
+ # property change testing
236
+ a.ref_xy = [100, 100]
237
+ a.columns = 4
238
+ a.rows = 2
239
+ a.column_space = 50
240
+ a.row_space = 25
241
+ assert_equal([100,100], a.ref_xy)
242
+ assert_equal(4, a.columns)
243
+ assert_equal(2, a.rows)
244
+ assert_equal(50, a.column_space)
245
+ assert_equal(25, a.row_space)
246
+ assert_equal([100,100, 300,100, 100,150], a.xy)
247
+
248
+ # Test omission of required XY properties
249
+ b = ARef.new('Test2')
250
+ assert_nil b.ref_xy
251
+ assert_nil b.column_space
252
+ assert_nil b.row_space
253
+ assert_nil b.columns
254
+ assert_nil b.rows
255
+
256
+ assert_nil b.xy
257
+ b.ref_xy = [100, 100]
258
+ assert_nil b.xy
259
+ b.columns = 4
260
+ assert_nil b.xy
261
+ b.rows = 2
262
+ assert_nil b.xy
263
+ b.column_space = 50
264
+ assert_nil b.xy
265
+ b.row_space = 25
266
+ assert_equal([100,100, 300,100, 100,150], b.xy)
267
+
268
+ # run tests on strans of this object
269
+ test_strans(a)
270
+ end
271
+
272
+ ############################################################################
273
+
274
+ # Test Structure items
275
+ def test_structure()
276
+ a = Structure.new('MYNAME')
277
+ assert_equal("MYNAME", a.name)
278
+ assert (a.create_time and a.modify_time)
279
+ assert a.elements.empty?
280
+
281
+ # Change the name
282
+ a.name = 'NEWNAME'
283
+ assert_equal 'NEWNAME', a.name
284
+
285
+ # Set the time to an hour ahead
286
+ now = Time.new + 360
287
+ a.create_time = now
288
+ a.modify_time = now
289
+ assert_equal now, a.create_time
290
+ assert_equal now, a.modify_time
291
+
292
+ # Add some elements using the two different add methods
293
+ a.add Boundary.new(1, 0, [0,0, 0,10, 10,10, 10,0, 0,0])
294
+ a.elements.add Boundary.new(2, 0, [0,0, 0,10, 10,10, 10,0, 0,0])
295
+ assert_equal 2, a.elements.length
296
+ assert_equal 1, a.elements[0].layer
297
+
298
+ # Manipulate the strclass bitarray
299
+ a.strclass = 0x0002
300
+ assert_equal(0x0002, a.strclass)
301
+
302
+ # Try adding garbage
303
+ assert_raise(TypeError) { a.add 1234 }
304
+ end
305
+
306
+ ############################################################################
307
+
308
+
309
+ # Test library items
310
+ def test_library()
311
+ lib = Library.new('MYLIB')
312
+ assert_equal 'MYLIB', lib.name
313
+ assert_equal lib.units, DEF_LIB_UNITS
314
+ assert_equal lib.header, DEF_LIB_VERSION
315
+ assert_equal lib.version, DEF_LIB_VERSION
316
+ assert (lib.access_time and lib.modify_time)
317
+ assert lib.structures.empty?
318
+
319
+ # test defaults
320
+ assert_nil lib.fonts
321
+ assert_nil lib.format
322
+ assert_nil lib.generations
323
+ assert_nil lib.secur
324
+ assert_equal [], lib.mask
325
+ assert_nil lib.srfname
326
+
327
+ # test units
328
+ user = lib.user_units
329
+ db = lib.database_units
330
+ assert_equal [user, db], lib.units
331
+ assert_equal 1e-6, lib.m_units
332
+
333
+ # tweak then verify all values
334
+ lib.name = 'LIB2'
335
+ lib.version = 7
336
+ lib.units = [0.001, 2e-9]
337
+ lib.fonts = ["one","two/three", "four","five"]
338
+ lib.generations = 3
339
+ lib.dirsize = 30
340
+ lib.secur = [1,2,7]
341
+ lib.mask = ['0 2-5 6 ; 0-64']
342
+ lib.srfname = "test"
343
+ assert_equal('LIB2', lib.name)
344
+ assert_equal(7, lib.version)
345
+ assert_equal(7, lib.header)
346
+ assert_equal([0.001, 2e-9], lib.units)
347
+ assert_equal(2e-6, lib.m_units)
348
+ assert_equal(["one","two/three", "four","five"], lib.fonts)
349
+ assert_equal(3, lib.generations)
350
+ assert_equal(30, lib.dirsize)
351
+ assert_equal([1,2,7], lib.secur)
352
+ assert_equal(['0 2-5 6 ; 0-64'], lib.mask)
353
+ assert_equal("test", lib.srfname)
354
+
355
+ # mess with the format record
356
+ lib.format = 0
357
+ assert_equal(0, lib.format)
358
+ assert(lib.archive_format?)
359
+ lib.format = 1
360
+ assert_equal(1, lib.format)
361
+ assert(lib.filtered_format?)
362
+
363
+ # mess with the time
364
+ now = Time.new + 360
365
+ lib.access_time = now
366
+ lib.modify_time = now
367
+ assert_equal now, lib.access_time
368
+ assert_equal now, lib.modify_time
369
+
370
+ # test adding structures
371
+ lib.structures << Structure.new("first")
372
+ lib.structures.add(Structure.new("second"))
373
+ lib.add(Structure.new("third"))
374
+ assert_equal("first", lib.structures[0].name)
375
+ assert_equal("second", lib.structures[1].name)
376
+ assert_equal("third", lib.structures[2].name)
377
+ end
378
+
379
+ end