Class | NumRu::NetCDFVar |
In: |
lib/netcdf_miss.rb
lib/netcdf.rb |
Parent: | Object |
NetCDFVar class に関して
new | -> | open |
ndims | -> | rank |
# File lib/netcdf.rb, line 225 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
# File lib/netcdf.rb, line 333 333: def unpack_type=(na_type) 334: if [NArray::BYTE, NArray::SINT, NArray::INT, 335: NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type) 336: @@unpack_type = na_type 337: else 338: raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT" 339: end 340: end
# File lib/netcdf.rb, line 620 620: def [](*a) 621: if a.length == 0 622: return self.get 623: end 624: a = __rubber_expansion(a) 625: first = Array.new 626: last = Array.new 627: stride = Array.new 628: set_stride = false 629: a.each{|i| 630: if(i.is_a?(Fixnum)) 631: first.push(i) 632: last.push(i) 633: stride.push(1) 634: elsif(i.is_a?(Range)) 635: first.push(i.first) 636: last.push(i.exclude_end? ? i.last-1 : i.last) 637: stride.push(1) 638: elsif(i.is_a?(Hash)) 639: r = (i.to_a[0])[0] 640: s = (i.to_a[0])[1] 641: if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) 642: raise TypeError, "Hash argument must be {a_Range, step}" 643: end 644: first.push(r.first) 645: last.push(r.exclude_end? ? r.last-1 : r.last) 646: stride.push(s) 647: set_stride = true 648: elsif(i.is_a?(TrueClass)) 649: first.push(0) 650: last.push(-1) 651: stride.push(1) 652: elsif( i.is_a?(Array) || i.is_a?(NArray)) 653: a_new = a.dup 654: at = a.index(i) 655: i = NArray.to_na(i) if i.is_a?(Array) 656: for n in 0..i.length-1 657: a_new[at] = i[n]..i[n] 658: na_tmp = self[*a_new] 659: if n==0 then 660: k = at 661: if at > 0 662: a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} 663: end 664: shape_tmp = na_tmp.shape 665: shape_tmp[k] = i.length 666: na = na_tmp.class.new(na_tmp.typecode,*shape_tmp) 667: index_tmp = Array.new(shape_tmp.length,true) 668: end 669: index_tmp[k] = n..n 670: na[*index_tmp] = na_tmp 671: end 672: return na 673: else 674: raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" 675: end 676: } 677: 678: if(set_stride) 679: na = self.get({"start"=>first, "end"=>last, "stride"=>stride}) 680: else 681: na = self.get({"start"=>first, "end"=>last}) 682: end 683: shape = na.shape 684: (a.length-1).downto(0){ |i| 685: shape.delete_at(i) if a[i].is_a?(Fixnum) 686: } 687: na.reshape!( *shape ) 688: na 689: end
# File lib/netcdf.rb, line 691 691: def []=(*a) 692: val = a.pop 693: a = __rubber_expansion(a) 694: first = Array.new 695: last = Array.new 696: stride = Array.new 697: set_stride = false 698: a.each{|i| 699: if(i.is_a?(Fixnum)) 700: first.push(i) 701: last.push(i) 702: stride.push(1) 703: elsif(i.is_a?(Range)) 704: first.push(i.first) 705: last.push(i.exclude_end? ? i.last-1 : i.last) 706: stride.push(1) 707: elsif(i.is_a?(Hash)) 708: r = (i.to_a[0])[0] 709: s = (i.to_a[0])[1] 710: if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) ) 711: raise ArgumentError, "Hash argument must be {first..last, step}" 712: end 713: first.push(r.first) 714: last.push(r.exclude_end? ? r.last-1 : r.last) 715: stride.push(s) 716: set_stride = true 717: elsif(i.is_a?(TrueClass)) 718: first.push(0) 719: last.push(-1) 720: stride.push(1) 721: elsif(i.is_a?(Array) || i.is_a?(NArray)) 722: a_new = a.dup 723: at = a.index(i) 724: i = NArray.to_na(i) if i.is_a?(Array) 725: val = NArray.to_na(val) if val.is_a?(Array) 726: rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length 727: if val.rank != rank_of_subset 728: raise "rank of the rhs (#{val.rank}) is not equal to the rank "+ 729: "of the subset specified by #{a.inspect} (#{rank_of_subset})" 730: end 731: k = at 732: a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end} 733: if i.length != val.shape[k] 734: raise "length of the #{k+1}-th dim of rhs is incorrect "+ 735: "(#{i.length} for #{val.shape[k]})" 736: end 737: index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like 738: for n in 0..i.length-1 739: a_new[at] = i[n]..i[n] 740: if !val.is_a?(Numeric) then 741: index_tmp[k] = n..n 742: self[*a_new] = val[*index_tmp] 743: else 744: self[*a_new] = val 745: end 746: end 747: return self 748: else 749: raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray" 750: end 751: } 752: 753: if(set_stride) 754: self.put(val, {"start"=>first, "end"=>last, "stride"=>stride}) 755: else 756: self.put(val, {"start"=>first, "end"=>last}) 757: end 758: end
# File lib/netcdf.rb, line 253 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
# File lib/netcdf.rb, line 247 247: def dim_names 248: ary = Array.new() 249: dims.each{|dim| ary.push(dim.name)} 250: ary 251: end
# File lib/netcdf.rb, line 239 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
# File lib/netcdf_miss.rb, line 8 8: def get_with_miss(*args) 9: __interpret_missing_params if !defined?(@missval) 10: data = simple_get(*args) 11: if @vmin || @vmax 12: if @vmin 13: mask = (data >= @vmin) 14: mask = mask.and(data <= @vmax) if @vmax 15: else 16: mask = (data <= @vmax) 17: end 18: data = NArrayMiss.to_nam(data, mask) 19: elsif @missval # only missing_value is present. 20: mask = (data.ne(@missval)) 21: data = NArrayMiss.to_nam(data, mask) 22: end 23: data 24: end
# File lib/netcdf_miss.rb, line 26 26: def get_with_miss_and_scaling(*args) 27: __interpret_missing_params if !defined?(@missval) 28: data = simple_get(*args) 29: if @vmin || @vmax 30: if @vmin 31: mask = (data >= @vmin) 32: mask = mask.and(data <= @vmax) if @vmax 33: else 34: mask = (data <= @vmax) 35: end 36: data = NArrayMiss.to_nam(data, mask) 37: elsif @missval # only missing_value is present. 38: mask = (data.ne(@missval)) 39: data = NArrayMiss.to_nam(data, mask) 40: end 41: data = unpack( data ) 42: data 43: end
The put and get methods in the NetCDFVar class
# File lib/netcdf.rb, line 289 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: end 322: end
# File lib/netcdf.rb, line 263 263: def put_att(attname,val,atttype=nil) 264: put_attraw(attname,val,atttype) 265: end
# File lib/netcdf_miss.rb, line 45 45: def put_with_miss(data, *args) 46: if data.is_a?( NArrayMiss ) 47: __interpret_missing_params if !defined?(@missval) 48: if @missval 49: simple_put(data.to_na(@missval), *args) 50: else 51: simple_put(data.to_na, *args) 52: end 53: else 54: simple_put(data, *args) 55: end 56: end
# File lib/netcdf_miss.rb, line 58 58: def put_with_miss_and_scaling(data, *args) 59: if data.is_a?( NArrayMiss ) 60: __interpret_missing_params if !defined?(@missval) 61: if @missval 62: data = pack( data ) 63: data = data.to_na(@missval) 64: else 65: data = pack( data ) 66: data = data.to_na 67: end 68: simple_put(data, *args) 69: else 70: scaled_put(data, *args) 71: end 72: end
# File lib/netcdf.rb, line 377 377: def scaled_get(hash=nil) 378: unpack( simple_get(hash) ) 379: end
# File lib/netcdf.rb, line 324 324: def scaled_put(var,hash=nil) 325: simple_put( pack(var), hash) 326: end
# File lib/netcdf.rb, line 279 279: def shape_current 280: sh = [] 281: dims.each{|d| 282: sh.push(d.length) 283: } 284: sh 285: end
# File lib/netcdf.rb, line 267 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
# File lib/netcdf.rb, line 487 487: def simple_get(hash=nil) 488: t_var = self.vartype 489: if hash == nil 490: if t_var == "char" 491: get_var_char 492: elsif t_var == "byte" 493: get_var_byte 494: elsif t_var == "sint" 495: get_var_sint 496: elsif t_var == "int" 497: get_var_int 498: elsif t_var == "sfloat" 499: get_var_sfloat 500: elsif t_var == "float" 501: get_var_float 502: else 503: raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" 504: end 505: elsif hash.key?("index")==true 506: ind = hash["index"] 507: if t_var == "char" 508: get_var1_char(ind) 509: elsif t_var == "byte" 510: get_var1_byte(ind) 511: elsif t_var == "sint" 512: get_var1_sint(ind) 513: elsif t_var == "int" 514: get_var1_int(ind) 515: elsif t_var == "sfloat" 516: get_var1_sfloat(ind) 517: elsif t_var == "float" 518: get_var1_float(ind) 519: else 520: raise NetcdfError,"variable type #{t_var} isn't supported in netCDF" 521: end 522: elsif hash.key?("start")==true 523: h_sta = hash["start"] 524: endq = hash.key?("end") 525: strq = hash.key?("stride") 526: if endq == false && strq == false 527: if t_var == "char" 528: get_vars_char(h_sta,nil,nil) 529: elsif t_var == "byte" 530: get_vars_byte(h_sta,nil,nil) 531: elsif t_var == "sint" 532: get_vars_sint(h_sta,nil,nil) 533: elsif t_var == "int" 534: get_vars_int(h_sta,nil,nil) 535: elsif t_var == "sfloat" 536: get_vars_sfloat(h_sta,nil,nil) 537: elsif t_var == "float" 538: get_vars_float(h_sta,nil,nil) 539: else 540: raise NetcdfError, "varialbe type #{t_var} isn't supported in netCDF" 541: end 542: elsif endq == true && strq == false 543: h_end = hash["end"] 544: if t_var == "char" 545: get_vars_char(h_sta,h_end,nil) 546: elsif t_var == "byte" 547: get_vars_byte(h_sta,h_end,nil) 548: elsif t_var == "sint" 549: get_vars_sint(h_sta,h_end,nil) 550: elsif t_var == "int" 551: get_vars_int(h_sta,h_end,nil) 552: elsif t_var == "sfloat" 553: get_vars_sfloat(h_sta,h_end,nil) 554: elsif t_var == "float" 555: get_vars_float(h_sta,h_end,nil) 556: else 557: raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" 558: end 559: elsif endq == false && strq == true 560: h_str = hash["stride"] 561: if t_var == "char" 562: get_vars_char(h_sta,nil,h_str) 563: elsif t_var == "byte" 564: get_vars_byte(h_sta,nil,h_str) 565: elsif t_var == "sint" 566: get_vars_sint(h_sta,nil,h_str) 567: elsif t_var == "int" 568: get_vars_int(h_sta,nil,h_str) 569: elsif t_var == "sfloat" 570: get_vars_sfloat(h_sta,nil,h_str) 571: elsif t_var == "float" 572: get_vars_float(h_sta,nil,h_str) 573: else 574: raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" 575: end 576: else endq == true && strq == true 577: h_end = hash["end"] 578: h_str = hash["stride"] 579: if t_var == "char" 580: get_vars_char(h_sta,h_end,h_str) 581: elsif t_var == "byte" 582: get_vars_byte(h_sta,h_end,h_str) 583: elsif t_var == "sint" 584: get_vars_sint(h_sta,h_end,h_str) 585: elsif t_var == "int" 586: get_vars_int(h_sta,h_end,h_str) 587: elsif t_var == "sfloat" 588: get_vars_sfloat(h_sta,h_end,h_str) 589: elsif t_var == "float" 590: get_vars_float(h_sta,h_end,h_str) 591: else 592: raise NetcdfError, "variable type #{t_var} isn't supported in netCDF" 593: end 594: end 595: else 596: raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed" 597: end 598: end
# File lib/netcdf.rb, line 381 381: def simple_put(var,hash=nil) 382: if hash==nil 383: if self.vartype == "char" 384: put_var_char(var) 385: elsif self.vartype == "byte" 386: put_var_byte(var) 387: elsif self.vartype == "sint" 388: put_var_sint(var) 389: elsif self.vartype == "int" 390: put_var_int(var) 391: elsif self.vartype == "sfloat" 392: put_var_sfloat(var) 393: elsif self.vartype == "float" 394: put_var_float(var) 395: else 396: raise NetcdfError,"variable type isn't supported in netCDF" 397: end 398: elsif hash.key?("index")==true 399: if self.vartype == "char" 400: put_var1_char(var,hash["index"]) 401: elsif self.vartype=="byte" 402: put_var1_byte(var,hash["index"]) 403: elsif self.vartype=="sint" 404: put_var1_sint(var,hash["index"]) 405: elsif self.vartype == "int" 406: put_var1_int(var,hash["index"]) 407: elsif self.vartype == "sfloat" 408: put_var1_sfloat(var,hash["index"]) 409: elsif self.vartype == "float" 410: put_var1_float(var,hash["index"]) 411: else 412: raise NetcdfError,"variable type isn't supported in netCDF" 413: end 414: elsif hash.key?("start")==true 415: if hash.key?("end")==false && hash.key?("stride")==false 416: if self.vartype == "char" 417: put_vars_char(var,hash["start"],nil,nil) 418: elsif self.vartype=="byte" 419: put_vars_byte(var,hash["start"],nil,nil) 420: elsif self.vartype=="sint" 421: put_vars_sint(var,hash["start"],nil,nil) 422: elsif self.vartype=="int" 423: put_vars_int(var,hash["start"],nil,nil) 424: elsif self.vartype=="sfloat" 425: put_vars_sfloat(var,hash["start"],nil,nil) 426: elsif self.vartype=="float" 427: put_vars_float(var,hash["start"],nil,nil) 428: else 429: raise NetcdfError, "variable type isn't supported in netCDF" 430: end 431: elsif hash.key?("end")==true && hash.key?("stride") == false 432: if self.vartype == "char" 433: put_vars_char(var,hash["start"],hash["end"],nil) 434: elsif self.vartype=="byte" 435: put_vars_byte(var,hash["start"],hash["end"],nil) 436: elsif self.vartype=="sint" 437: put_vars_sint(var,hash["start"],hash["end"],nil) 438: elsif self.vartype=="int" 439: put_vars_int(var,hash["start"],hash["end"],nil) 440: elsif self.vartype == "sfloat" 441: put_vars_sfloat(var,hash["start"],hash["end"],nil) 442: elsif self.vartype =="float" 443: put_vars_float(var,hash["start"],hash["end"],nil) 444: else 445: raise NetcdfError, "variable type isn't supported in netCDF" 446: end 447: elsif hash.key?("end")==false && hash.key?("stride")==true 448: if self.vartype == "char" 449: put_vars_char(var,hash["start"],nil,hash["stride"]) 450: elsif self.vartype=="byte" 451: put_vars_byte(var,hash["start"],nil,hash["stride"]) 452: elsif self.vartype=="sint" 453: put_vars_sint(var,hash["start"],nil,hash["stride"]) 454: elsif self.vartype=="int" 455: put_vars_int(var,hash["start"],nil,hash["stride"]) 456: elsif self.vartype=="sfloat" 457: put_vars_sfloat(var,hash["start"],nil,hash["stride"]) 458: elsif self.vartype=="float" 459: put_vars_float(var,hash["start"],nil,hash["stride"]) 460: else 461: raise NetcdfError, "variable type isn't supported in netCDF" 462: end 463: else hash.key?("end")==true && hash.key?("stride")==true 464: if self.vartype == "char" 465: put_vars_char(var,hash["start"],hash["end"],hash["stride"]) 466: elsif self.vartype=="byte" 467: put_vars_byte(var,hash["start"],hash["end"],hash["stride"]) 468: elsif self.vartype=="sint" 469: put_vars_sint(var,hash["start"],hash["end"],hash["stride"]) 470: elsif self.vartype=="int" 471: put_vars_int(var,hash["start"],hash["end"],hash["stride"]) 472: elsif self.vartype=="sfloat" 473: put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"]) 474: elsif self.vartype=="float" 475: put_vars_float(var,hash["start"],hash["end"],hash["stride"]) 476: else 477: raise NetcdfError, "variable type isn't supported in netCDF" 478: end 479: end 480: else 481: raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed" 482: end 483: end
# File lib/netcdf.rb, line 344 344: def unpack(na) 345: sf = att('scale_factor') 346: ao = att('add_offset') 347: if ( sf == nil && ao == nil ) then 348: na 349: else 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: una = na * csf + cao # csf & cao are NArray -> coerced to their types 367: elsif csf 368: una = na * csf 369: elsif cao 370: una = na + cao 371: end 372: una = una.to_type(@@unpack_type) if @@unpack_type 373: una 374: end 375: end
private ##########
# File lib/netcdf_miss.rb, line 76 76: def __interpret_missing_params 77: # Interprets the specification of missing data, 78: # either by valid_range, (valid_min and/or valid_max), or missing_value. 79: # (unlike the NetCDF User's guide (NUG), missing_value is interpreted, 80: # but valid_* has a higher precedence.) 81: # Always sets @missval whether missing_value is defined or not, 82: # since it will be used as a fill value for data missing. 83: # 84: @vmin = att('valid_min') 85: @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type 86: @vmax = att('valid_max') 87: @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type 88: vrange = att('valid_range') 89: vrange = vrange.get if vrange 90: if vrange 91: vrange.sort! 92: @vmin = vrange[0..0] # kept in... (same) 93: @vmax = vrange[-1..-1] # kept in... (same) 94: end 95: @missval = att('missing_value') || att('_FillValue') 96: @missval = @missval.get if @missval # kept in... (same) 97: 98: sf = att('scale_factor') 99: ao = att('add_offset') 100: if ( sf || ao ) 101: ## Both NUG & CF conventions requires to specify the valid 102: ## range with respect to the external (i.e. packed) values. 103: ## However, some conventions require specification 104: ## with respect to unpacked values. The following 105: ## is to support such cases as well: 106: thres_tp = [ self.typecode, NArray::LINT ].max 107: @missval = pack(@missval) if @missval && @missval.typecode > thres_tp 108: @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp 109: @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp 110: end 111: 112: if @missval 113: if @vmin && @vmax 114: if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0] 115: warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" 116: end 117: else 118: if @vmin && @missval[0] >= @vmin[0] 119: warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" 120: elsif @vmax && @missval[0] <= @vmax[0] 121: warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})" 122: end 123: end 124: else 125: realtc = NArray::SFLOAT 126: if @vmin 127: if @vmin[0] >= 0 128: @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 ) 129: else 130: @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 ) 131: end 132: elsif @vmax 133: if @vmax[0] >= 0 134: @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 ) 135: else 136: @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 ) 137: end 138: end 139: end 140: 141: end
# File lib/netcdf.rb, line 602 602: def __rubber_expansion( args ) 603: if (id = args.index(false)) # substitution into id 604: # false is incuded 605: alen = args.length 606: if args.rindex(false) != id 607: raise ArguemntError,"only one rubber dimension is permitted" 608: elsif alen > rank+1 609: raise ArgumentError, "too many args" 610: end 611: ar = ( id!=0 ? args[0..id-1] : [] ) 612: args = ar + [true]*(rank-alen+1) + args[id+1..-1] 613: elsif args.length == 0 # to support empty [], []= 614: args = [true]*rank 615: end 616: args 617: end