=begin
=ToDo list
* Support a temporay attribute (@tmp_attr = Attribute.new)
=end
require "numru/gphys/grads_gridded"
require "numru/gphys/varray"
module NumRu
class VArrayGrADS < VArray
## < initialization redefined > ##
def initialize(aGrADSVar)
@name = aGrADSVar.name
@mapping = nil
@varray = nil
raise ArgumentError,"Not a GrADSVar" if ! aGrADSVar.is_a?(GrADSVar)
@ary = aGrADSVar
@attr = aGrADSVar.attr
end
def inspect
# "<'#{@name}' in '#{@ary.file.path}' #{@ary.ntype}#{shape_current.inspect}>"
"<'#{@name}' #{shape_current.inspect}>"
end
class << self
## < redefined class methods > ##
def new2(file, name, ntype, dimensions, attr=nil)
va = new( file.def_var(name, ntype, dimensions) )
if attr; attr.each{|key,val| va.attr[key]=val}; end
va
end
## < additional class methods > ##
def write_control(file, gphys)
raise ArgumentError, "1st arg: not a GrADS_Gridded" if !file.is_a?(GrADS_Gridded)
rank = gphys.data.rank
raise ArgumentError, "only 4D data is supported" if rank != 4
for i in 0..2 # lon, lat, lev
c = ""
if ( i==1 && (gphys.coord(i).length > 1) &&
(gphys.coord(i).val[1]-gphys.coord(i).val[0] < 0) )
file.put_att("yrev",true)
gphys.axis(i).pos.val[-1..0].each{|j| c += (j.to_s + " ")}
elsif( i==2 && (gphys.coord(i).length > 1) &&
(gphys.coord(i)[1].val-gphys.coord(i)[0].val > 0) )
file.put_att("zrev",true)
gphys.axis(i).pos.val[-1..0].each{|j| c += (j.to_s + " ")}
else
gphys.axis(i).pos.val.each{|j| c += (j.to_s + " ")}
end
file.dimensions[i] = {
:len=>gphys.axis(i).pos.length,
:flag=> "LEVELS",
:spec=>c
}
end
i = 3 # time
tunit = Units.new(gphys.coord(i).get_att("units"))
basedate = Date.new(1950,1,1).jd # temporary base date
baseunits = Units.new("days since 1950-01-01 0:0:0 +0:00")
days_since_basedate = tunit.convert(gphys.coord(i).val[0],baseunits)
startjd = basedate + days_since_basedate
if( gphys.coord(i).length > 1 )
increment = gphys.coord(i)[1].val - gphys.coord(i)[0].val
else
increment = 1.0 # anything is possible
end
# c = Date.jd(gphys.axis(i).pos.val[0]).strftime("%d%b%Y") + " <increment>"
file.dimensions[i] = {
:len=>gphys.axis(i).pos.length,
:flag=> "LINEAR",
# :spec=>c
:startjd=> startjd,
:increment=> increment,
:increment_units=> "day"
}
# end
# file.def_var(gphys.name, gphys.data.get_att("nlev"),
# 99, gphys.data.get_att("long_name") )
nlev1 = gphys.coord(2).length
if( nlev = gphys.data.get_att("nlev") )
nlev = nlev.to_i
if( (nlev1 != nlev) && !(nlev1==1 && nlev==0) )
raise "inconsistent attribute nlev (#{nlev} and #{nlev1})"
end
else
nlev = nlev1
end
file.def_var(gphys.name, nlev, 99, gphys.data.get_att("long_name") )
ctlfile = File.open(file.path,"w")
ctlfile << file.to_ctl
ctlfile.close
end
def write_binary(file, vary, rename=nil, dimnames=nil)
raise ArgumentError, "1st arg: not a GrADS_Gridded" if !file.is_a?(GrADS_Gridded)
raise ArgumentError, "2nd arg: not a VArray" if !vary.is_a?(VArray)
rank=vary.rank
raise ArgumentError, "only 4D data is supported" if rank != 4
file.put(vary.val)
end
end
## < redefined instance methods > ##
def val
# mode_switched = @ary.file.enddef
v = @ary.get
# if mode_switched; @ary.file.redef; end
# v
end
def val=(narray)
@ary.put( __check_ary_class2(narray) )
narray
end
# It is safer not to have the method "shape" to avoid misconfusion of
# shape_ul0 and shape_current:
def shape
raise "The shape method is not available. Use shape_ul0 or shape_current instead."
end
def name=(nm)
@ary.name = nm
@name = nm
end
def rename!(nm)
@ary.name = nm
@name = nm
self
end
def rename_no_file_change(nm)
@name = nm
self
end
def rename(nm)
self.dup.rename_no_file_change(nm)
end
def ntype
@ary.ntype
end
def total
len = 1
@ary.shape_current.each{|i| len *= i}
len
end
alias length total
def rank
shape_current.length
end
# def reshape!( *args )
# raise "cannot reshape a #{class}. Use copy first to make it a VArray with NArray"
# end
undef reshape!
## < additional instance methods > ##
def dim_names
@ary.dim_names
end
def shape_ul0
@ary.shape_ul0
end
def shape_current
@ary.shape_current
end
def file
@ary.file
end
end
end
###########################################################
### < test >
if $0 == __FILE__
# $DEBUG = true
include NumRu
begin
grvar = GrADSVar.new("../../testdata/T.jan.ctl","T")
rescue
grvar = GrADSVar.new("../../../testdata/T.jan.ctl","T")
end
va = VArrayGrADS.new(grvar)
p va.dim_names
p va.shape_ul0
p va.val
p va.att_names
p va.get_att("long_name")
va2 = va[3..9,5..15,0,0]
p va2.shape
p va2.val
p va2.get_att("long_name")
# va2.get_att("units")
# va2[3,true,true,true] = 5.0
# va2.val
va3 = (va2*3).val
p va3
end
syntax highlighted by Code2HTML, v. 0.9.1