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