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