class NumRu::NetCDFVar
Public Class Methods
new(file,varname,mode="r",share=false)
click to toggle source
# File lib/netcdf.rb, line 279 def new(file,varname,mode="r",share=false) if(file.is_a?(String)) file = NetCDF.open(file,mode,share) elsif(!file.is_a?(NetCDF)) raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)" end file.var(varname) end
Also aliased as: open, open
unpack_type()
click to toggle source
# File lib/netcdf.rb, line 385 def unpack_type @@unpack_type end
unpack_type=(na_type)
click to toggle source
# File lib/netcdf.rb, line 388 def unpack_type=(na_type) if [NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type) @@unpack_type = na_type else raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT" end end
Public Instance Methods
[](*a)
click to toggle source
# File lib/netcdf.rb, line 637 def [](*a) if a.length == 0 return self.get end a = __rubber_expansion(a) first = Array.new last = Array.new stride = Array.new set_stride = false a.each{|i| if(i.is_a?(Fixnum)) first.push(i) last.push(i) stride.push(1) elsif(i.is_a?(Range)) first.push(i.first) last.push(i.exclude_end? ? i.last-1 : i.last) stride.push(1) elsif(i.is_a?(Hash)) r = (i.to_a[0])[0] s = (i.to_a[0])[1] if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) raise TypeError, "Hash argument must be {a_Range, step}" end first.push(r.first) last.push(r.exclude_end? ? r.last-1 : r.last) stride.push(s) set_stride = true elsif(i.is_a?(TrueClass)) first.push(0) last.push(-1) stride.push(1) elsif( i.is_a?(Array) || i.is_a?(NArray)) a_new = a.dup at = a.index(i) i = NArray.to_na(i) if i.is_a?(Array) for n in 0..i.length-1 a_new[at] = i[n]..i[n] na_tmp = self[*a_new] if n==0 then k = at if at > 0 a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} end shape_tmp = na_tmp.shape shape_tmp[k] = i.length na = na_tmp.class.new(na_tmp.typecode,*shape_tmp) index_tmp = Array.new(shape_tmp.length,true) end index_tmp[k] = n..n na[*index_tmp] = na_tmp end return na else raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" end } if(set_stride) na = self.get({"start"=>first, "end"=>last, "stride"=>stride}) else na = self.get({"start"=>first, "end"=>last}) end shape = na.shape (a.length-1).downto(0){ |i| shape.delete_at(i) if a[i].is_a?(Fixnum) } na.reshape!( *shape ) na end
[]=(*a)
click to toggle source
# File lib/netcdf.rb, line 708 def []=(*a) val = a.pop a = __rubber_expansion(a) first = Array.new last = Array.new stride = Array.new set_stride = false a.each{|i| if(i.is_a?(Fixnum)) first.push(i) last.push(i) stride.push(1) elsif(i.is_a?(Range)) first.push(i.first) last.push(i.exclude_end? ? i.last-1 : i.last) stride.push(1) elsif(i.is_a?(Hash)) r = (i.to_a[0])[0] s = (i.to_a[0])[1] if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) raise ArgumentError, "Hash argument must be {first..last, step}" end first.push(r.first) last.push(r.exclude_end? ? r.last-1 : r.last) stride.push(s) set_stride = true elsif(i.is_a?(TrueClass)) first.push(0) last.push(-1) stride.push(1) elsif(i.is_a?(Array) || i.is_a?(NArray)) a_new = a.dup at = a.index(i) i = NArray.to_na(i) if i.is_a?(Array) val = NArray.to_na(val) if val.is_a?(Array) rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length if val.rank != rank_of_subset raise "rank of the rhs (#{val.rank}) is not equal to the rank "+ "of the subset specified by #{a.inspect} (#{rank_of_subset})" end k = at a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} if i.length != val.shape[k] raise "length of the #{k+1}-th dim of rhs is incorrect "+ "(#{i.length} for #{val.shape[k]})" end index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like for n in 0..i.length-1 a_new[at] = i[n]..i[n] if !val.is_a?(Numeric) then index_tmp[k] = n..n self[*a_new] = val[*index_tmp] else self[*a_new] = val end end return self else raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" end } if(set_stride) self.put(val, {"start"=>first, "end"=>last, "stride"=>stride}) else self.put(val, {"start"=>first, "end"=>last}) end end
att_names()
click to toggle source
# File lib/netcdf.rb, line 307 def att_names num_att=natts() names=[] for attnum in 0..num_att-1 obj_Att=id2att(attnum) names=names+[obj_Att.name] end return names end
dim_names()
click to toggle source
# File lib/netcdf.rb, line 301 def dim_names ary = Array.new() dims.each{|dim| ary.push(dim.name)} ary end
each_att() { |obj_Att| ... }
click to toggle source
# File lib/netcdf.rb, line 293 def each_att num_att=natts() for attnum in 0..num_att-1 obj_Att=id2att(attnum) yield(obj_Att) end end
get_with_miss(*args)
click to toggle source
# File lib/netcdf_miss.rb, line 8 def get_with_miss(*args) __interpret_missing_params if !defined?(@missval) data = simple_get(*args) if @vmin || @vmax if @vmin mask = (data >= @vmin) mask = mask.and(data <= @vmax) if @vmax else mask = (data <= @vmax) end data = NArrayMiss.to_nam(data, mask) elsif @missval # only missing_value is present. mask = (data.ne(@missval)) data = NArrayMiss.to_nam(data, mask) end data end
get_with_miss_and_scaling(*args)
click to toggle source
# File lib/netcdf_miss.rb, line 26 def get_with_miss_and_scaling(*args) __interpret_missing_params if !defined?(@missval) data = simple_get(*args) if @vmin || @vmax if @vmin mask = (data >= @vmin) mask = mask.and(data <= @vmax) if @vmax else mask = (data <= @vmax) end data = NArrayMiss.to_nam(data, mask) elsif @missval # only missing_value is present. mask = (data.ne(@missval)) data = NArrayMiss.to_nam(data, mask) end data = unpack( data ) data end
inspect()
click to toggle source
# File lib/netcdf.rb, line 777 def inspect 'NetCDFVar:'+file.path+'?var='+name end
pack(na)
click to toggle source
The put and get methods in the NetCDFVar class
# File lib/netcdf.rb, line 343 def pack(na) sf = att('scale_factor') ao = att('add_offset') if ( sf == nil && ao == nil ) then na else na = NArray.to_na(na) if na.is_a?(Array) if sf csf = sf.get raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) raise NetcdfError, "scale_factor is not unique" if csf.length != 1 raise NetcdfError, "zero scale_factor" if csf[0] == 0 else csf = nil end if ao cao = ao.get raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) raise NetcdfError, "add_offset is not unique" if cao.length != 1 else cao = nil end if csf and cao packed = (na - cao) / csf elsif csf packed = na / csf elsif cao packed = na - cao end if self.typecode <= NArray::LINT packed = packed.round end packed end end
put_att(attname,val,atttype=nil)
click to toggle source
# File lib/netcdf.rb, line 317 def put_att(attname,val,atttype=nil) put_attraw(attname,val,atttype) end
put_with_miss(data, *args)
click to toggle source
# File lib/netcdf_miss.rb, line 45 def put_with_miss(data, *args) if data.is_a?( NArrayMiss ) __interpret_missing_params if !defined?(@missval) if @missval simple_put(data.to_na(@missval), *args) else simple_put(data.to_na, *args) end else simple_put(data, *args) end end
put_with_miss_and_scaling(data, *args)
click to toggle source
# File lib/netcdf_miss.rb, line 58 def put_with_miss_and_scaling(data, *args) if data.is_a?( NArrayMiss ) __interpret_missing_params if !defined?(@missval) if @missval data = pack( data ) data = data.to_na(@missval) else data = pack( data ) data = data.to_na end simple_put(data, *args) else scaled_put(data, *args) end end
scaled_get(hash=nil)
click to toggle source
# File lib/netcdf.rb, line 432 def scaled_get(hash=nil) unpack( simple_get(hash) ) end
scaled_put(var,hash=nil)
click to toggle source
# File lib/netcdf.rb, line 379 def scaled_put(var,hash=nil) simple_put( pack(var), hash) end
shape_current()
click to toggle source
# File lib/netcdf.rb, line 333 def shape_current sh = [] dims.each{|d| sh.push(d.length) } sh end
shape_ul0()
click to toggle source
# File lib/netcdf.rb, line 321 def shape_ul0 sh = [] dims.each{|d| if d.unlimited? then sh.push(0) else sh.push(d.length) end } sh end
simple_get(hash=nil)
click to toggle source
# File lib/netcdf.rb, line 542 def simple_get(hash=nil) t_var = self.vartype if hash == nil if t_var == "char" get_var_char elsif t_var == "byte" get_var_byte elsif t_var == "sint" get_var_sint elsif t_var == "int" get_var_int elsif t_var == "sfloat" get_var_sfloat elsif t_var == "float" get_var_float else raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" end elsif hash.key?("index")==true ind = hash["index"] if t_var == "char" get_var1_char(ind) elsif t_var == "byte" get_var1_byte(ind) elsif t_var == "sint" get_var1_sint(ind) elsif t_var == "int" get_var1_int(ind) elsif t_var == "sfloat" get_var1_sfloat(ind) elsif t_var == "float" get_var1_float(ind) else raise NetcdfError,"variable type #{t_var} isn't supported in netCDF" end elsif hash.key?("start")==true h_sta = hash["start"] h_end = hash["end"] # can be nill h_str = hash["stride"] # can be nill if NetCDF.nc4? && h_str && ((xstr=h_str[0]) != 1) # Tentative treatment for the very slow netcdf-4 reading with step. # Reading with step is generally slow with NetCDF 4, but it is # particularly so for the first dimension. # Ref: http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2013/msg00311.html h_str[0] = 1 nc4remedy = true else nc4remedy = false end if t_var == "char" v = get_vars_char(h_sta,h_end,h_str) elsif t_var == "byte" v = get_vars_byte(h_sta,h_end,h_str) elsif t_var == "sint" v = get_vars_sint(h_sta,h_end,h_str) elsif t_var == "int" v = get_vars_int(h_sta,h_end,h_str) elsif t_var == "sfloat" v = get_vars_sfloat(h_sta,h_end,h_str) elsif t_var == "float" v = get_vars_float(h_sta,h_end,h_str) else raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" end if nc4remedy idx = [] (0...v.shape[0]).step(xstr){|k| idx.push(k)} v = v[idx,false] end v else raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed" end end
Also aliased as: get, get
simple_put(var,hash=nil)
click to toggle source
# File lib/netcdf.rb, line 436 def simple_put(var,hash=nil) if hash==nil if self.vartype == "char" put_var_char(var) elsif self.vartype == "byte" put_var_byte(var) elsif self.vartype == "sint" put_var_sint(var) elsif self.vartype == "int" put_var_int(var) elsif self.vartype == "sfloat" put_var_sfloat(var) elsif self.vartype == "float" put_var_float(var) else raise NetcdfError,"variable type isn't supported in netCDF" end elsif hash.key?("index")==true if self.vartype == "char" put_var1_char(var,hash["index"]) elsif self.vartype=="byte" put_var1_byte(var,hash["index"]) elsif self.vartype=="sint" put_var1_sint(var,hash["index"]) elsif self.vartype == "int" put_var1_int(var,hash["index"]) elsif self.vartype == "sfloat" put_var1_sfloat(var,hash["index"]) elsif self.vartype == "float" put_var1_float(var,hash["index"]) else raise NetcdfError,"variable type isn't supported in netCDF" end elsif hash.key?("start")==true if hash.key?("end")==false && hash.key?("stride")==false if self.vartype == "char" put_vars_char(var,hash["start"],nil,nil) elsif self.vartype=="byte" put_vars_byte(var,hash["start"],nil,nil) elsif self.vartype=="sint" put_vars_sint(var,hash["start"],nil,nil) elsif self.vartype=="int" put_vars_int(var,hash["start"],nil,nil) elsif self.vartype=="sfloat" put_vars_sfloat(var,hash["start"],nil,nil) elsif self.vartype=="float" put_vars_float(var,hash["start"],nil,nil) else raise NetcdfError, "variable type isn't supported in netCDF" end elsif hash.key?("end")==true && hash.key?("stride") == false if self.vartype == "char" put_vars_char(var,hash["start"],hash["end"],nil) elsif self.vartype=="byte" put_vars_byte(var,hash["start"],hash["end"],nil) elsif self.vartype=="sint" put_vars_sint(var,hash["start"],hash["end"],nil) elsif self.vartype=="int" put_vars_int(var,hash["start"],hash["end"],nil) elsif self.vartype == "sfloat" put_vars_sfloat(var,hash["start"],hash["end"],nil) elsif self.vartype =="float" put_vars_float(var,hash["start"],hash["end"],nil) else raise NetcdfError, "variable type isn't supported in netCDF" end elsif hash.key?("end")==false && hash.key?("stride")==true if self.vartype == "char" put_vars_char(var,hash["start"],nil,hash["stride"]) elsif self.vartype=="byte" put_vars_byte(var,hash["start"],nil,hash["stride"]) elsif self.vartype=="sint" put_vars_sint(var,hash["start"],nil,hash["stride"]) elsif self.vartype=="int" put_vars_int(var,hash["start"],nil,hash["stride"]) elsif self.vartype=="sfloat" put_vars_sfloat(var,hash["start"],nil,hash["stride"]) elsif self.vartype=="float" put_vars_float(var,hash["start"],nil,hash["stride"]) else raise NetcdfError, "variable type isn't supported in netCDF" end else hash.key?("end")==true && hash.key?("stride")==true if self.vartype == "char" put_vars_char(var,hash["start"],hash["end"],hash["stride"]) elsif self.vartype=="byte" put_vars_byte(var,hash["start"],hash["end"],hash["stride"]) elsif self.vartype=="sint" put_vars_sint(var,hash["start"],hash["end"],hash["stride"]) elsif self.vartype=="int" put_vars_int(var,hash["start"],hash["end"],hash["stride"]) elsif self.vartype=="sfloat" put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"]) elsif self.vartype=="float" put_vars_float(var,hash["start"],hash["end"],hash["stride"]) else raise NetcdfError, "variable type isn't supported in netCDF" end end else raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed" end end
Also aliased as: put, put
unpack(na)
click to toggle source
# File lib/netcdf.rb, line 399 def unpack(na) sf = att('scale_factor') ao = att('add_offset') if ( sf == nil && ao == nil ) then na else if sf csf = sf.get raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String) raise NetcdfError, "scale_factor is not unique" if csf.length != 1 raise NetcdfError, "zero scale_factor" if csf[0] == 0 else csf =nil end if ao cao = ao.get raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String) raise NetcdfError, "add_offset is not unique" if cao.length != 1 else cao = nil end if csf and cao una = na * csf + cao # csf & cao are NArray -> coerced to their types elsif csf una = na * csf elsif cao una = na + cao end una = una.to_type(@@unpack_type) if @@unpack_type una end end
Private Instance Methods
__interpret_missing_params()
click to toggle source
private ##########
# File lib/netcdf_miss.rb, line 76 def __interpret_missing_params # Interprets the specification of missing data, # either by valid_range, (valid_min and/or valid_max), or missing_value. # (unlike the NetCDF User's guide (NUG), missing_value is interpreted, # but valid_* has a higher precedence.) # Always sets @missval whether missing_value is defined or not, # since it will be used as a fill value for data missing. # @vmin = att('valid_min') @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type @vmax = att('valid_max') @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type vrange = att('valid_range') vrange = vrange.get if vrange if vrange vrange.sort! @vmin = vrange[0..0] # kept in... (same) @vmax = vrange[-1..-1] # kept in... (same) end @missval = att('missing_value') || att('_FillValue') @missval = @missval.get if @missval # kept in... (same) sf = att('scale_factor') ao = att('add_offset') if ( sf || ao ) ## Both NUG & CF conventions requires to specify the valid ## range with respect to the external (i.e. packed) values. ## However, some conventions require specification ## with respect to unpacked values. The following ## is to support such cases as well: thres_tp = [ self.typecode, NArray::LINT ].max @missval = pack(@missval) if @missval && @missval.typecode > thres_tp @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp end if @missval if @vmin && @vmax if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0] warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" end else if @vmin && @missval[0] >= @vmin[0] warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" elsif @vmax && @missval[0] <= @vmax[0] warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" end end else realtc = NArray::SFLOAT if @vmin if @vmin[0] >= 0 @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 ) else @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 ) end elsif @vmax if @vmax[0] >= 0 @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 ) else @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 ) end end end end
__rubber_expansion( args )
click to toggle source
# File lib/netcdf.rb, line 619 def __rubber_expansion( args ) if (id = args.index(false)) # substitution into id # false is incuded alen = args.length if args.rindex(false) != id raise ArguemntError,"only one rubber dimension is permitted" elsif alen > rank+1 raise ArgumentError, "too many args" end ar = ( id!=0 ? args[0..id-1] : [] ) args = ar + [true]*(rank-alen+1) + args[id+1..-1] elsif args.length == 0 # to support empty [], []= args = [true]*rank end args end