gentooboontoo-ruby-netcdf 0.6.6.2

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.
@@ -0,0 +1,792 @@
1
+ require 'narray'
2
+ require 'numru/netcdfraw'
3
+
4
+ # NetCDF$B%/%i%9$K4X$7$F(B
5
+ module NumRu
6
+ class NetCDF
7
+
8
+ Max_Try = 100
9
+
10
+ def NetCDF.open(filename,mode="r",share=false)
11
+ call_create=false # false-> nc_open; true->nc_create
12
+ case(mode)
13
+ when "r","rb" # read only
14
+ mode=NC_NOWRITE
15
+ when "w","w+","wb","w+b" # overwrite if exits
16
+ call_create=true
17
+ mode=NC_CLOBBER
18
+ when "a","a+","r+","ab","a+b","r+b" # append if exits
19
+ if( File.exists?(filename) )
20
+ mode=NC_WRITE
21
+ else
22
+ call_create=true #(nonexsitent --> create)
23
+ mode=NC_CLOBBER
24
+ end
25
+ else
26
+ raise NetcdfError, "Mode #{mode} is not supported"
27
+ end
28
+ case(share)
29
+ when false
30
+ share=0
31
+ when true
32
+ share=NC_SHARE
33
+ else
34
+ raise NetcdfError, "We can't use the sharing mode you typed"
35
+ end
36
+ omode = mode | share
37
+ if(!call_create)
38
+ nc_open(filename,omode)
39
+ else
40
+ nc_create(filename,omode)
41
+ end
42
+ end
43
+
44
+ class << NetCDF
45
+ alias new open
46
+ end
47
+
48
+
49
+ def NetCDF.create(filename,noclobber=false,share=false)
50
+ case(noclobber)
51
+ when false
52
+ noclobber=NC_CLOBBER
53
+ when true
54
+ noclobber=NC_NOCLOBBER
55
+ else
56
+ raise NetcdfError,"noclobber (2nd argument) must be true or false"
57
+ end
58
+ case(share)
59
+ when false
60
+ share=0
61
+ when true
62
+ share=NC_SHARE
63
+ else
64
+ raise NetcdfError,"share (3rd argument) must be true or false"
65
+ end
66
+
67
+ cmode=noclobber | share
68
+ nc_create(filename,cmode)
69
+ end
70
+
71
+ class << NetCDF
72
+ def clean_tmpfile(path)
73
+ proc {
74
+ print "removing ", path, "..." if $DEBUG
75
+ if File.exist?(path)
76
+ File.unlink(path)
77
+ end
78
+ print "done\n" if $DEBUG
79
+ }
80
+ end
81
+ protected :clean_tmpfile
82
+ end
83
+
84
+ def NetCDF.create_tmp(tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'.',
85
+ share=false)
86
+ basename = 'temp'
87
+ if $SAFE > 0 and tmpdir.tainted?
88
+ tmpdir = '.'
89
+ end
90
+
91
+ n = 0
92
+ while true
93
+ begin
94
+ tmpname = sprintf('%s/%s%d_%d.nc', tmpdir, basename, $$, n)
95
+ unless File.exist?(tmpname)
96
+ netcdf = NetCDF.create(tmpname, true, share)
97
+ ObjectSpace.define_finalizer(netcdf,
98
+ NetCDF.clean_tmpfile(tmpname))
99
+ break
100
+ end
101
+ rescue
102
+ raise NetcdfError, "cannot generate tempfile `%s'" % tmpname if n >= Max_Try
103
+ end
104
+ n += 1
105
+ end
106
+ netcdf
107
+ end
108
+
109
+
110
+ def put_att(attname,val,atttype=nil)
111
+ put_attraw(attname,val,atttype)
112
+ end
113
+
114
+ def def_var_with_dim(name, vartype, shape_ul0, dimnames)
115
+ # Same as def_var but defines dimensions first if needed.
116
+ # Use zero in shape to define an unlimited dimension.
117
+ if (shape_ul0.length != dimnames.length ) then
118
+ raise ArgumentError, 'lengths of shape and dimnames do not agree'
119
+ end
120
+ dims = []
121
+ dimnames.each_index{ |i|
122
+ dim = self.dim( dimnames[i] )
123
+ if ( dim != nil ) then
124
+ # dim exists --> check the length
125
+ if (shape_ul0[i] != dim.length_ul0 ) then
126
+ raise ArgumentError, "dimension length do not agree: #{i}th dim: "+\
127
+ "#{shape_ul0[i]} and #{dim.length_ul0}"
128
+ end
129
+ dims.push(dim)
130
+ else
131
+ # dim does not exist --> define it
132
+ dims.push( def_dim( dimnames[i], shape_ul0[i] ) )
133
+ end
134
+ }
135
+ def_var(name, vartype, dims)
136
+ end
137
+
138
+ # Iterators:
139
+ def each_dim
140
+ num_dim=ndims()
141
+ for dimid in 0..num_dim-1
142
+ obj_Dim=id2dim(dimid)
143
+ yield(obj_Dim)
144
+ end
145
+ end
146
+
147
+ def each_var
148
+ num_var=nvars()
149
+ for varid in 0..num_var-1
150
+ obj_Var=id2var(varid)
151
+ yield(obj_Var)
152
+ end
153
+ end
154
+
155
+ def each_att
156
+ num_att=natts()
157
+ for attnum in 0..num_att-1
158
+ obj_Att=id2att(attnum)
159
+ yield(obj_Att)
160
+ end
161
+ end
162
+
163
+ def dims( names=nil ) # return all if names==nil
164
+ if names == nil
165
+ dims = (0..ndims()-1).collect{|dimid| id2dim(dimid)}
166
+ else
167
+ raise TypeError, "names is not an array" if ! names.is_a?(Array)
168
+ dims = names.collect{|name| dim(name)}
169
+ raise ArgumentError, "One or more dimensions do not exist" if dims.include?(nil)
170
+ end
171
+ dims
172
+ end
173
+
174
+ def vars( names=nil ) # return all if names==nil
175
+ if names == nil
176
+ vars = (0..nvars()-1).collect{ |varid| id2var(varid) }
177
+ else
178
+ raise TypeError, "names is not an array" if ! names.is_a?(Array)
179
+ vars = names.collect{|name| var(name)}
180
+ raise ArgumentError, "One or more variables do not exist" if vars.include?(nil)
181
+ end
182
+ vars
183
+ end
184
+
185
+ def dim_names
186
+ num_dim=ndims()
187
+ names=[]
188
+ for dimid in 0..num_dim-1
189
+ obj_Dim=id2dim(dimid)
190
+ names=names+[obj_Dim.name]
191
+ end
192
+ return names
193
+ end
194
+
195
+ def var_names
196
+ num_var=nvars()
197
+ names=[]
198
+ for varid in 0..num_var-1
199
+ obj_Var=id2var(varid)
200
+ names=names+[obj_Var.name]
201
+ end
202
+ return names
203
+ end
204
+
205
+ def att_names
206
+ num_att=natts()
207
+ names=[]
208
+ for attnum in 0..num_att-1
209
+ obj_Att=id2att(attnum)
210
+ names=names+[obj_Att.name]
211
+ end
212
+ return names
213
+ end
214
+
215
+ def inspect
216
+ "NetCDF:"+path
217
+ end
218
+
219
+ end
220
+
221
+ #NetCDFVar class $B$K4X$7$F(B
222
+ class NetCDFVar
223
+
224
+ class << NetCDFVar
225
+ def new(file,varname,mode="r",share=false)
226
+ if(file.is_a?(String))
227
+ file = NetCDF.open(file,mode,share)
228
+ elsif(!file.is_a?(NetCDF))
229
+ raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)"
230
+ end
231
+ file.var(varname)
232
+ end
233
+
234
+ alias open new
235
+ end
236
+
237
+ alias :rank :ndims
238
+
239
+ def each_att
240
+ num_att=natts()
241
+ for attnum in 0..num_att-1
242
+ obj_Att=id2att(attnum)
243
+ yield(obj_Att)
244
+ end
245
+ end
246
+
247
+ def dim_names
248
+ ary = Array.new()
249
+ dims.each{|dim| ary.push(dim.name)}
250
+ ary
251
+ end
252
+
253
+ def att_names
254
+ num_att=natts()
255
+ names=[]
256
+ for attnum in 0..num_att-1
257
+ obj_Att=id2att(attnum)
258
+ names=names+[obj_Att.name]
259
+ end
260
+ return names
261
+ end
262
+
263
+ def put_att(attname,val,atttype=nil)
264
+ put_attraw(attname,val,atttype)
265
+ end
266
+
267
+ def shape_ul0
268
+ sh = []
269
+ dims.each{|d|
270
+ if d.unlimited? then
271
+ sh.push(0)
272
+ else
273
+ sh.push(d.length)
274
+ end
275
+ }
276
+ sh
277
+ end
278
+
279
+ def shape_current
280
+ sh = []
281
+ dims.each{|d|
282
+ sh.push(d.length)
283
+ }
284
+ sh
285
+ end
286
+
287
+ # The put and get methods in the NetCDFVar class
288
+
289
+ def pack(na)
290
+ sf = att('scale_factor')
291
+ ao = att('add_offset')
292
+ if ( sf == nil && ao == nil ) then
293
+ na
294
+ else
295
+ na = NArray.to_na(na) if na.is_a?(Array)
296
+ if sf
297
+ csf = sf.get
298
+ raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
299
+ raise NetcdfError, "scale_factor is not unique" if csf.length != 1
300
+ raise NetcdfError, "zero scale_factor" if csf[0] == 0
301
+ else
302
+ csf = nil
303
+ end
304
+ if ao
305
+ cao = ao.get
306
+ raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
307
+ raise NetcdfError, "add_offset is not unique" if cao.length != 1
308
+ else
309
+ cao = nil
310
+ end
311
+ if csf and cao
312
+ packed = (na - cao) / csf
313
+ elsif csf
314
+ packed = na / csf
315
+ elsif cao
316
+ packed = na - cao
317
+ end
318
+ if self.typecode <= NArray::LINT
319
+ packed = packed.round
320
+ end
321
+ packed
322
+ end
323
+ end
324
+
325
+ def scaled_put(var,hash=nil)
326
+ simple_put( pack(var), hash)
327
+ end
328
+
329
+ @@unpack_type = nil
330
+ class << NetCDFVar
331
+ def unpack_type
332
+ @@unpack_type
333
+ end
334
+ def unpack_type=(na_type)
335
+ if [NArray::BYTE, NArray::SINT, NArray::INT,
336
+ NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type)
337
+ @@unpack_type = na_type
338
+ else
339
+ raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT"
340
+ end
341
+ end
342
+
343
+ end
344
+
345
+ def unpack(na)
346
+ sf = att('scale_factor')
347
+ ao = att('add_offset')
348
+ if ( sf == nil && ao == nil ) then
349
+ na
350
+ else
351
+ if sf
352
+ csf = sf.get
353
+ raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
354
+ raise NetcdfError, "scale_factor is not unique" if csf.length != 1
355
+ raise NetcdfError, "zero scale_factor" if csf[0] == 0
356
+ else
357
+ csf =nil
358
+ end
359
+ if ao
360
+ cao = ao.get
361
+ raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
362
+ raise NetcdfError, "add_offset is not unique" if cao.length != 1
363
+ else
364
+ cao = nil
365
+ end
366
+ if csf and cao
367
+ una = na * csf + cao # csf & cao are NArray -> coerced to their types
368
+ elsif csf
369
+ una = na * csf
370
+ elsif cao
371
+ una = na + cao
372
+ end
373
+ una = una.to_type(@@unpack_type) if @@unpack_type
374
+ una
375
+ end
376
+ end
377
+
378
+ def scaled_get(hash=nil)
379
+ unpack( simple_get(hash) )
380
+ end
381
+
382
+ def simple_put(var,hash=nil)
383
+ if hash==nil
384
+ if self.vartype == "char"
385
+ put_var_char(var)
386
+ elsif self.vartype == "byte"
387
+ put_var_byte(var)
388
+ elsif self.vartype == "sint"
389
+ put_var_sint(var)
390
+ elsif self.vartype == "int"
391
+ put_var_int(var)
392
+ elsif self.vartype == "sfloat"
393
+ put_var_sfloat(var)
394
+ elsif self.vartype == "float"
395
+ put_var_float(var)
396
+ else
397
+ raise NetcdfError,"variable type isn't supported in netCDF"
398
+ end
399
+ elsif hash.key?("index")==true
400
+ if self.vartype == "char"
401
+ put_var1_char(var,hash["index"])
402
+ elsif self.vartype=="byte"
403
+ put_var1_byte(var,hash["index"])
404
+ elsif self.vartype=="sint"
405
+ put_var1_sint(var,hash["index"])
406
+ elsif self.vartype == "int"
407
+ put_var1_int(var,hash["index"])
408
+ elsif self.vartype == "sfloat"
409
+ put_var1_sfloat(var,hash["index"])
410
+ elsif self.vartype == "float"
411
+ put_var1_float(var,hash["index"])
412
+ else
413
+ raise NetcdfError,"variable type isn't supported in netCDF"
414
+ end
415
+ elsif hash.key?("start")==true
416
+ if hash.key?("end")==false && hash.key?("stride")==false
417
+ if self.vartype == "char"
418
+ put_vars_char(var,hash["start"],nil,nil)
419
+ elsif self.vartype=="byte"
420
+ put_vars_byte(var,hash["start"],nil,nil)
421
+ elsif self.vartype=="sint"
422
+ put_vars_sint(var,hash["start"],nil,nil)
423
+ elsif self.vartype=="int"
424
+ put_vars_int(var,hash["start"],nil,nil)
425
+ elsif self.vartype=="sfloat"
426
+ put_vars_sfloat(var,hash["start"],nil,nil)
427
+ elsif self.vartype=="float"
428
+ put_vars_float(var,hash["start"],nil,nil)
429
+ else
430
+ raise NetcdfError, "variable type isn't supported in netCDF"
431
+ end
432
+ elsif hash.key?("end")==true && hash.key?("stride") == false
433
+ if self.vartype == "char"
434
+ put_vars_char(var,hash["start"],hash["end"],nil)
435
+ elsif self.vartype=="byte"
436
+ put_vars_byte(var,hash["start"],hash["end"],nil)
437
+ elsif self.vartype=="sint"
438
+ put_vars_sint(var,hash["start"],hash["end"],nil)
439
+ elsif self.vartype=="int"
440
+ put_vars_int(var,hash["start"],hash["end"],nil)
441
+ elsif self.vartype == "sfloat"
442
+ put_vars_sfloat(var,hash["start"],hash["end"],nil)
443
+ elsif self.vartype =="float"
444
+ put_vars_float(var,hash["start"],hash["end"],nil)
445
+ else
446
+ raise NetcdfError, "variable type isn't supported in netCDF"
447
+ end
448
+ elsif hash.key?("end")==false && hash.key?("stride")==true
449
+ if self.vartype == "char"
450
+ put_vars_char(var,hash["start"],nil,hash["stride"])
451
+ elsif self.vartype=="byte"
452
+ put_vars_byte(var,hash["start"],nil,hash["stride"])
453
+ elsif self.vartype=="sint"
454
+ put_vars_sint(var,hash["start"],nil,hash["stride"])
455
+ elsif self.vartype=="int"
456
+ put_vars_int(var,hash["start"],nil,hash["stride"])
457
+ elsif self.vartype=="sfloat"
458
+ put_vars_sfloat(var,hash["start"],nil,hash["stride"])
459
+ elsif self.vartype=="float"
460
+ put_vars_float(var,hash["start"],nil,hash["stride"])
461
+ else
462
+ raise NetcdfError, "variable type isn't supported in netCDF"
463
+ end
464
+ else hash.key?("end")==true && hash.key?("stride")==true
465
+ if self.vartype == "char"
466
+ put_vars_char(var,hash["start"],hash["end"],hash["stride"])
467
+ elsif self.vartype=="byte"
468
+ put_vars_byte(var,hash["start"],hash["end"],hash["stride"])
469
+ elsif self.vartype=="sint"
470
+ put_vars_sint(var,hash["start"],hash["end"],hash["stride"])
471
+ elsif self.vartype=="int"
472
+ put_vars_int(var,hash["start"],hash["end"],hash["stride"])
473
+ elsif self.vartype=="sfloat"
474
+ put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"])
475
+ elsif self.vartype=="float"
476
+ put_vars_float(var,hash["start"],hash["end"],hash["stride"])
477
+ else
478
+ raise NetcdfError, "variable type isn't supported in netCDF"
479
+ end
480
+ end
481
+ else
482
+ raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed"
483
+ end
484
+ end
485
+
486
+ alias put simple_put
487
+
488
+ def simple_get(hash=nil)
489
+ t_var = self.vartype
490
+ if hash == nil
491
+ if t_var == "char"
492
+ get_var_char
493
+ elsif t_var == "byte"
494
+ get_var_byte
495
+ elsif t_var == "sint"
496
+ get_var_sint
497
+ elsif t_var == "int"
498
+ get_var_int
499
+ elsif t_var == "sfloat"
500
+ get_var_sfloat
501
+ elsif t_var == "float"
502
+ get_var_float
503
+ else
504
+ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
505
+ end
506
+ elsif hash.key?("index")==true
507
+ ind = hash["index"]
508
+ if t_var == "char"
509
+ get_var1_char(ind)
510
+ elsif t_var == "byte"
511
+ get_var1_byte(ind)
512
+ elsif t_var == "sint"
513
+ get_var1_sint(ind)
514
+ elsif t_var == "int"
515
+ get_var1_int(ind)
516
+ elsif t_var == "sfloat"
517
+ get_var1_sfloat(ind)
518
+ elsif t_var == "float"
519
+ get_var1_float(ind)
520
+ else
521
+ raise NetcdfError,"variable type #{t_var} isn't supported in netCDF"
522
+ end
523
+ elsif hash.key?("start")==true
524
+ h_sta = hash["start"]
525
+ endq = hash.key?("end")
526
+ strq = hash.key?("stride")
527
+ if endq == false && strq == false
528
+ if t_var == "char"
529
+ get_vars_char(h_sta,nil,nil)
530
+ elsif t_var == "byte"
531
+ get_vars_byte(h_sta,nil,nil)
532
+ elsif t_var == "sint"
533
+ get_vars_sint(h_sta,nil,nil)
534
+ elsif t_var == "int"
535
+ get_vars_int(h_sta,nil,nil)
536
+ elsif t_var == "sfloat"
537
+ get_vars_sfloat(h_sta,nil,nil)
538
+ elsif t_var == "float"
539
+ get_vars_float(h_sta,nil,nil)
540
+ else
541
+ raise NetcdfError, "varialbe type #{t_var} isn't supported in netCDF"
542
+ end
543
+ elsif endq == true && strq == false
544
+ h_end = hash["end"]
545
+ if t_var == "char"
546
+ get_vars_char(h_sta,h_end,nil)
547
+ elsif t_var == "byte"
548
+ get_vars_byte(h_sta,h_end,nil)
549
+ elsif t_var == "sint"
550
+ get_vars_sint(h_sta,h_end,nil)
551
+ elsif t_var == "int"
552
+ get_vars_int(h_sta,h_end,nil)
553
+ elsif t_var == "sfloat"
554
+ get_vars_sfloat(h_sta,h_end,nil)
555
+ elsif t_var == "float"
556
+ get_vars_float(h_sta,h_end,nil)
557
+ else
558
+ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
559
+ end
560
+ elsif endq == false && strq == true
561
+ h_str = hash["stride"]
562
+ if t_var == "char"
563
+ get_vars_char(h_sta,nil,h_str)
564
+ elsif t_var == "byte"
565
+ get_vars_byte(h_sta,nil,h_str)
566
+ elsif t_var == "sint"
567
+ get_vars_sint(h_sta,nil,h_str)
568
+ elsif t_var == "int"
569
+ get_vars_int(h_sta,nil,h_str)
570
+ elsif t_var == "sfloat"
571
+ get_vars_sfloat(h_sta,nil,h_str)
572
+ elsif t_var == "float"
573
+ get_vars_float(h_sta,nil,h_str)
574
+ else
575
+ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
576
+ end
577
+ else endq == true && strq == true
578
+ h_end = hash["end"]
579
+ h_str = hash["stride"]
580
+ if t_var == "char"
581
+ get_vars_char(h_sta,h_end,h_str)
582
+ elsif t_var == "byte"
583
+ get_vars_byte(h_sta,h_end,h_str)
584
+ elsif t_var == "sint"
585
+ get_vars_sint(h_sta,h_end,h_str)
586
+ elsif t_var == "int"
587
+ get_vars_int(h_sta,h_end,h_str)
588
+ elsif t_var == "sfloat"
589
+ get_vars_sfloat(h_sta,h_end,h_str)
590
+ elsif t_var == "float"
591
+ get_vars_float(h_sta,h_end,h_str)
592
+ else
593
+ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
594
+ end
595
+ end
596
+ else
597
+ raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed"
598
+ end
599
+ end
600
+
601
+ alias get simple_get
602
+
603
+ def __rubber_expansion( args )
604
+ if (id = args.index(false)) # substitution into id
605
+ # false is incuded
606
+ alen = args.length
607
+ if args.rindex(false) != id
608
+ raise ArguemntError,"only one rubber dimension is permitted"
609
+ elsif alen > rank+1
610
+ raise ArgumentError, "too many args"
611
+ end
612
+ ar = ( id!=0 ? args[0..id-1] : [] )
613
+ args = ar + [true]*(rank-alen+1) + args[id+1..-1]
614
+ elsif args.length == 0 # to support empty [], []=
615
+ args = [true]*rank
616
+ end
617
+ args
618
+ end
619
+ private :__rubber_expansion
620
+
621
+ def [](*a)
622
+ if a.length == 0
623
+ return self.get
624
+ end
625
+ a = __rubber_expansion(a)
626
+ first = Array.new
627
+ last = Array.new
628
+ stride = Array.new
629
+ set_stride = false
630
+ a.each{|i|
631
+ if(i.is_a?(Fixnum))
632
+ first.push(i)
633
+ last.push(i)
634
+ stride.push(1)
635
+ elsif(i.is_a?(Range))
636
+ first.push(i.first)
637
+ last.push(i.exclude_end? ? i.last-1 : i.last)
638
+ stride.push(1)
639
+ elsif(i.is_a?(Hash))
640
+ r = (i.to_a[0])[0]
641
+ s = (i.to_a[0])[1]
642
+ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
643
+ raise TypeError, "Hash argument must be {a_Range, step}"
644
+ end
645
+ first.push(r.first)
646
+ last.push(r.exclude_end? ? r.last-1 : r.last)
647
+ stride.push(s)
648
+ set_stride = true
649
+ elsif(i.is_a?(TrueClass))
650
+ first.push(0)
651
+ last.push(-1)
652
+ stride.push(1)
653
+ elsif( i.is_a?(Array) || i.is_a?(NArray))
654
+ a_new = a.dup
655
+ at = a.index(i)
656
+ i = NArray.to_na(i) if i.is_a?(Array)
657
+ for n in 0..i.length-1
658
+ a_new[at] = i[n]..i[n]
659
+ na_tmp = self[*a_new]
660
+ if n==0 then
661
+ k = at
662
+ if at > 0
663
+ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
664
+ end
665
+ shape_tmp = na_tmp.shape
666
+ shape_tmp[k] = i.length
667
+ na = na_tmp.class.new(na_tmp.typecode,*shape_tmp)
668
+ index_tmp = Array.new(shape_tmp.length,true)
669
+ end
670
+ index_tmp[k] = n..n
671
+ na[*index_tmp] = na_tmp
672
+ end
673
+ return na
674
+ else
675
+ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
676
+ end
677
+ }
678
+
679
+ if(set_stride)
680
+ na = self.get({"start"=>first, "end"=>last, "stride"=>stride})
681
+ else
682
+ na = self.get({"start"=>first, "end"=>last})
683
+ end
684
+ shape = na.shape
685
+ (a.length-1).downto(0){ |i|
686
+ shape.delete_at(i) if a[i].is_a?(Fixnum)
687
+ }
688
+ na.reshape!( *shape )
689
+ na
690
+ end
691
+
692
+ def []=(*a)
693
+ val = a.pop
694
+ a = __rubber_expansion(a)
695
+ first = Array.new
696
+ last = Array.new
697
+ stride = Array.new
698
+ set_stride = false
699
+ a.each{|i|
700
+ if(i.is_a?(Fixnum))
701
+ first.push(i)
702
+ last.push(i)
703
+ stride.push(1)
704
+ elsif(i.is_a?(Range))
705
+ first.push(i.first)
706
+ last.push(i.exclude_end? ? i.last-1 : i.last)
707
+ stride.push(1)
708
+ elsif(i.is_a?(Hash))
709
+ r = (i.to_a[0])[0]
710
+ s = (i.to_a[0])[1]
711
+ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
712
+ raise ArgumentError, "Hash argument must be {first..last, step}"
713
+ end
714
+ first.push(r.first)
715
+ last.push(r.exclude_end? ? r.last-1 : r.last)
716
+ stride.push(s)
717
+ set_stride = true
718
+ elsif(i.is_a?(TrueClass))
719
+ first.push(0)
720
+ last.push(-1)
721
+ stride.push(1)
722
+ elsif(i.is_a?(Array) || i.is_a?(NArray))
723
+ a_new = a.dup
724
+ at = a.index(i)
725
+ i = NArray.to_na(i) if i.is_a?(Array)
726
+ val = NArray.to_na(val) if val.is_a?(Array)
727
+ rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length
728
+ if val.rank != rank_of_subset
729
+ raise "rank of the rhs (#{val.rank}) is not equal to the rank "+
730
+ "of the subset specified by #{a.inspect} (#{rank_of_subset})"
731
+ end
732
+ k = at
733
+ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
734
+ if i.length != val.shape[k]
735
+ raise "length of the #{k+1}-th dim of rhs is incorrect "+
736
+ "(#{i.length} for #{val.shape[k]})"
737
+ end
738
+ index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like
739
+ for n in 0..i.length-1
740
+ a_new[at] = i[n]..i[n]
741
+ if !val.is_a?(Numeric) then
742
+ index_tmp[k] = n..n
743
+ self[*a_new] = val[*index_tmp]
744
+ else
745
+ self[*a_new] = val
746
+ end
747
+ end
748
+ return self
749
+ else
750
+ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
751
+ end
752
+ }
753
+
754
+ if(set_stride)
755
+ self.put(val, {"start"=>first, "end"=>last, "stride"=>stride})
756
+ else
757
+ self.put(val, {"start"=>first, "end"=>last})
758
+ end
759
+ end
760
+
761
+ def inspect
762
+ 'NetCDFVar:'+file.path+'?var='+name
763
+ end
764
+
765
+ end
766
+
767
+ class NetCDFAtt
768
+
769
+ def put(val,atttype=nil)
770
+ putraw(val,atttype)
771
+ end
772
+
773
+ def inspect
774
+ 'NetCDFAtt:'+name
775
+ end
776
+ end
777
+
778
+ class NetCDFDim
779
+ def inspect
780
+ 'NetCDFDim:'+name
781
+ end
782
+
783
+ def length_ul0
784
+ if unlimited?
785
+ 0
786
+ else
787
+ length
788
+ end
789
+ end
790
+
791
+ end
792
+ end