#!/usr/bin/env ruby
=begin
= mknc_25means.rb -- $BG/(B/$B5(@aJ?6Q(B $B5$8uCM(B netCDF $B%U%!%$%k(B.

$B0J2<$NNL$NBS>uJ?6QNL$rJ]B8(B.

   (a)$B%*%$%i!<J?6Q<ANLN.@~4X?t(B,
   (b)$BEl@>Iw(B,
   (c)$B29EY(B,
   (d)$BHf<>(B,
   (e)$BJ|<M<};Y(B($BBg5$>eC<@5L#C;GH%U%i%C%/%9(B,
               $BBg5$>eC<>e8~$-D9GH%U%i%C%/%9(B,
               $BCOI=LL@5L#C;GH%U%i%C%/%9(B,
               $BCOI=LL@5L#D9GH%U%i%C%/%9(B),
   (f)$BG.<};Y(B($BCOI=LL@5L#@xG.%U%i%C%/%9(B,
             $BCOI=LL@5L#82G.%U%i%C%/%9(B,
             $B9_?e(B),
   (g)$BFnKL4%Ag@EE*%(%M%k%.!<M"AwNL(B
      ($B9g7W(B, $BBS>uJ?6Q@.J,(B, $BBS>u>qMp@.J,(B),
   (h)$BFnKL@xG.M"AwNL(B
      ($B9g7W(B, $BBS>uJ?6Q@.J,(B, $BBS>u>qMp@.J,(B),
   (i)EP $B%U%i%C%/%9$H$=$NH/;6(B
      (EP $B%U%i%C%/%9(B, $BH/;6(B),
   (j)$B;D:9=[4D$N<ANLN.@~4X?t(B $B$r0lKg$K$^$H$a$??^(B.

== $B%*%W%7%g%s(B

  1979 - 2003 $BG/(B $B$NG/J?6QCM(B
    $ ruby mknc_25means.rb --output hoge.nc --kikan annual --range 1979:2003

  1979 $BG/(B $B$NE_J?6QCM(B
    $ ruby mknc_25means.rb --kikan winter --range 1979:1979
  ...
  

=end

require "getopts"        # for option_parse
require "numru/ggraph"
require "libgphys-n"
include NumRu
include Misc::EMath


##-----------------------
## 25 $BG/J?6Q$N%*%V%8%'%/%H$r:n@.(B

def make_mean_gphys(phys, src, season, year, var=phys)
  pathary = []
  y1 = year[0]; y2 = year[1]
#  (M. Ishiwatari,  2005/03/22)  path $BJQ99(B
#  path = "../#{phys}.#{src}/"
#  path = "../../#{phys}.#{src}/"
  path = "/GFD_Dennou_Work3/dcchart/atmos_global/NCEP/#{phys}.#{src}/"
  season.each do |m|
    y1.upto(y2) do |y|
      y = y-1 if m == "12"
      fn = path + "#{phys}.#{y}.#{src}/#{phys}_#{y}-#{m}_#{src}.nc"
      pathary << fn
    end
  end
#  gp     = mean_gphys_date_weight(pathary, phys.downcase)
  gp     = mean_gphys(pathary, var.downcase)
  return gp
end


##################################################################

unless getopts(
               "", 
               "kikan:", # "annual", "winter", "spring", "summer", "fall" $B$r;XDj(B
               "range:", # $BJ?6Q$9$kG/$r;XDj(B. $B$H$"$k0lG/$NJ?6Q$N>l9g(B
               "output:mknc_25means.nc" # $B=PNO$9$k%U%!%$%k(B.
               )
  print "#{$0}:illegal options. please exec this program with -h/--help. \n"
  exit 1
end


# make gphys objects

## set kikan
year  =   $OPT_range.split(/:/).collect{|y| y.to_i }

months =  ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
winter = ["12", "01", "02"];  spring = ["03", "04", "05"]
summer = ["06", "07", "08"];  fall = ["09", "10", "11"]
annual = winter + spring + summer + fall


case $OPT_kikan
when "annual"
  kikan = annual
when "winter"
  kikan = winter
when "spring"
  kikan = spring
when "summer"
  kikan = summer
when "fall"
  kikan = fall
else
  if months.delete($OPT_kikan)
    kikan = [ $OPT_kikan ]
  else
    raise "#{$OPT_kikan} is invalid value."
  end
end

## define Constants
Infty = 1.0/0.0
L = UNumeric.new(2.5008e6, 'J.Kg-1')
Rad = UNumeric.new(6.37E6, 'm')
G =   UNumeric.new(9.81  , 'm.s-2')


## $B<ANLN.@~4X?t(B
  strm = make_mean_gphys('STRM', 'NCEP', kikan, year).cut( 'level'=>1000..100 )
## $BEl@>IwB.(B
  uwnd = make_mean_gphys('UWND', 'NCEP', kikan, year).mean('lon').cut( 'level'=>1000..100 )
## $B29EY>l(B
  temp = make_mean_gphys('T',    'NCEP', kikan, year).mean('lon').cut( 'level'=>1000..100 )
## $BHf<>(B
  shum = make_mean_gphys('SHUM', 'NCEP', kikan, year).mean('lon').cut( 'level'=>1000..100 )

## $BJ|<M(B

  ## $BJ|<M(B
  dswrf = make_mean_gphys('DSWRF', 'NCEP', kikan, year).mean('lon')
  uswrf = make_mean_gphys('USWRF', 'NCEP', kikan, year).mean('lon')
  nswrf = uswrf - dswrf                                   # $B@5L#$NC;GHJ|<M%U%i%C%/%9(B
  nswrf.data.set_att('long_name',  'NSR at TOP')
  ulwrf = make_mean_gphys('ULWRF', 'NCEP', kikan, year).mean('lon')
  ulwrf.data.set_att('long_name',  'OLR at TOP')
  nlwrs = make_mean_gphys('NLWRS', 'NCEP', kikan, year).mean('lon')  # $B@5L#$ND9GHJ|<M%U%i%C%/%9(B
  nlwrs.data.set_att('long_name',  'NLR at SFC')
  nswrs = make_mean_gphys('NSWRS', 'NCEP', kikan, year).mean('lon')  # $BCOI=LL@5L#$NC;GHJ|<M%U%i%C%/%9(B
  nswrs.data.set_att('long_name',  'NSR at SFC')
  nsw = (-nswrf + nswrs).abs # $BBg5$$N5[<}NL(B($BC;GHJ|<M(B)
  nsw.data.set_att('long_name',  'SW HEAT. by ATOM.')
  nlw = (-ulwrf + nlwrs).abs # $BBg5$$N5[<}NL(B($BD9GHJ|<M(B)
  nlw.data.set_att('long_name',  'LW COOL. by ATOM.')
  nrw = (nlw   - nsw).abs   # $BBg5$$N5[<}NL(B($B%H!<%?%k(B)
  nrw.data.set_att('long_name',  'RW COOL. by ATOM.')
  radiation = [ nswrf.abs, ulwrf, nswrs.abs, nlwrs, nsw, nlw, nrw ] 

  #### $B@xG.%U%i%C%/%9(B
  lhtfl = make_mean_gphys('LHTFL', 'NCEP', kikan, year).mean('lon')
  lhtfl.data.set_att('long_name', 'net latent heat flux at surface')
  #### $B82G.%U%i%C%/%9(B
  shtfl = make_mean_gphys('SHTFL', 'NCEP', kikan, year).mean('lon')
  shtfl.data.set_att('long_name', 'net sensible heat flux at surface')
  #### $B9_?e(B($B@xG.$K49;;$7$?$b$N(B)
  prate = make_mean_gphys('PRATE', 'NCEP', kikan, year).mean('lon')
  lheat = prate*L
  lheat.data.set_att('long_name', 'latent heat with precipitation')
  heat = [ lhtfl, shtfl, lheat, nrw ]
  
  ## $B4%Ag@EE*%(%M%k%.!<(B
  dsefl  =      make_mean_gphys('DSEFL', 'NCEP', kikan, year, 'dsefl')
  dsefl_bar   = make_mean_gphys('DSEFL', 'NCEP', kikan, year, 'dsefl_bar')
  dsefl_dash  = make_mean_gphys('DSEFL', 'NCEP', kikan, year, 'dsefl_dash')
  
  ## $B@xG.M"AwNL(B
  lhefl  =      make_mean_gphys('LHEFL', 'NCEP', kikan, year, 'lhefl')
  lhefl_bar   = make_mean_gphys('LHEFL', 'NCEP', kikan, year, 'lhefl_bar')
  lhefl_dash  = make_mean_gphys('LHEFL', 'NCEP', kikan, year, 'lhefl_dash')
  
  # get cos
  lat     = lhefl.coord('lat')
  grid    = Grid.new(lhefl.axis('lat'))
  cos_lat = GPhys.new(grid, cos(lat*2*PI/360.0))
  
  
  dse =      dsefl.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  dse_bar =  dsefl_bar.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  dse_dash = dsefl_dash.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  dse.data.set_att('units', 'W')
  dse_bar.data.set_att('units', 'W')
  dse_dash.data.set_att('units', 'W')  
  
  lhe =      lhefl.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  lhe_bar =  lhefl_bar.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  lhe_dash = lhefl_dash.integrate('level') /G * Rad * cos_lat * 2 * PI * 100
  lhe.data.set_att('units', 'W')
  lhe.data.set_att('long_name', 'latent heat energy transport (total)')
  lhe_bar.data.set_att('units', 'W')
  lhe_dash.data.set_att('units', 'W')
  
  # $B<>=a@EE*%(%M%k%.!<(B
  mse = lhe + dse
  mse.data.set_att('long_name', 'moist static energy transport (total)')

  dry_ene = [ dse, dse_bar, dse_dash, mse ]
  lat_ene = [ lhe, lhe_bar, lhe_dash, mse ]
  
  ## EP $B%U%i%C%/%9(B
  epflx_phi = make_mean_gphys('EPFLX', 'NCEP', kikan, year, 'epflx_phi')
  epflx_p   = make_mean_gphys('EPFLX', 'NCEP', kikan, year, 'epflx_p')
  epflx_div = make_mean_gphys('EPFLX', 'NCEP', kikan, year, 'epflx_div')
  ## $B;D:9=[4D(B
  strm_rmean = make_mean_gphys('STRM_RMEAN', 'NCEP', kikan, year)
    

####### delete valid_range

[shum, strm, uwnd, temp, 
 dse, dse_bar, dse_dash, 
 lhe, lhe_bar, lhe_dash,
 epflx_phi, epflx_p, epflx_div,
 strm_rmean,
 nswrf,
 ulwrf,
 nswrs,
 nlwrs,
 lhtfl,
 shtfl,
 lheat
].each{|gp|
  gp.data.att_names.each{|nm|
    gp.del_att(nm) if /^valid_/ =~ nm
    gp.del_att(nm) if /^actual_/ =~ nm
  }
}      
            
#############################################################################

## netCDF $B%U%!%$%k$KJ]B8(B

nc = NetCDF::create('300hPa_'+$OPT_output)
GPhys::IO.write( nc, shum )  	 # $BHf<>(B
nc.close

nc = NetCDF::create('100hPa_'+$OPT_output)
GPhys::IO.write( nc, strm )  	 # $B<ANLN.@~4X?t(B
GPhys::IO.write( nc, uwnd )  	 # $BEl@>IwB.(B
GPhys::IO.write( nc, temp )  	 # $B29EY>l(B

GPhys::IO.write( nc, dse )       # $B4%Ag@EE*%(%M%k%.!<M"AwNL(B($B9g7W(B)
GPhys::IO.write( nc, dse_bar )   #                         ($BJ?6Q(B)
GPhys::IO.write( nc, dse_dash )  #                         ($B>qMp(B)
GPhys::IO.write( nc, lhe ) 	 # $B@xG.M"AwNL(B              ($B9g7W(B)
GPhys::IO.write( nc, lhe_bar )   #                         ($BJ?6Q(B)
GPhys::IO.write( nc, lhe_dash )  #                         ($B>qMp(B)

GPhys::IO.write( nc, epflx_phi ) # EP $B%U%i%C%/%9(B $B0^EY@.J,(B
GPhys::IO.write( nc, epflx_p   ) #               $B1tD>(B($B05NO(B)$B@.J,(B
GPhys::IO.write( nc, epflx_div ) # EP $B%U%i%C%/%9(B $BH/;6(B
GPhys::IO.write( nc, strm_rmean) # $B;D:9;R8aLL=[4D(B $B<ANLN.@~4X?t(B
nc.close

nc = NetCDF::create('GAUSSIAN_'+$OPT_output)
GPhys::IO.write( nc, nswrf ) 	 # $BBg5$>eC<@5L#$NC;GHJ|<M%U%i%C%/%9(B 
GPhys::IO.write( nc, ulwrf ) 	 # $BBg5$>eC<>e8~$-D9GHJ|<M%U%i%C%/%9(B 
GPhys::IO.write( nc, nswrs ) 	 # $BCOI=LL@5L#$NC;GHJ|<M%U%i%C%/%9(B
GPhys::IO.write( nc, nlwrs ) 	 # $BCOI=LL@5L#$ND9GHJ|<M%U%i%C%/%9(B
GPhys::IO.write( nc, lhtfl ) 	 # $B@xG.%U%i%C%/%9(B
GPhys::IO.write( nc, shtfl ) 	 # $B82G.%U%i%C%/%9(B
GPhys::IO.write( nc, lheat ) 	 # $B9_?e(B
nc.close                  

