[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:001970] Re: gpprint, gpview



竹広様
Cc: gtool4, dennou-ruby

塚原です.

> animate がオプションリストにありますが, まだ使えないようですね. 
> ニーズとしてはこちらが最優先なのですが, 難しいかな?

インスタントですが実装しました. 必ず回す軸を指定しなくてはならない,
アニメーション開始点を指定できないなど痒いところが多々あると思いま
すが, とりあえず動きます. 添付させていただきますのでよろしければ
お使いください. 不具合ありましたら報告お願いいたします.

今回有効になったオプションは

  * アニメーション関連
    --animate <dims>
    --smooth  <dims>
    --nowait
  * バッキングストア
    --alternate
  * ラインインデックス(折れ線のみ有効)
    --index <idx>

です. 利用感は gtview に準じています. 

直交座標以外の座標系への投影はやはり(僕には)すぐには出来なそうです.
また直交座標系の地図投影も領域切り出すと現状ではうまく書けません.
修論書き終えたら考えたいと思います. すみません.

以上, よろしくお願いいたします.

--------------------------------------
北海道大学院理学研究科 地球惑星科学専攻
地球流体力学研究室  M2  塚原大輔

email::daktu32@xxxxxxxxxxxxxxxxxxxx
--------------------------------------
#!/usr/bin/env ruby
##################################################
#=gpview
#
# quick viewer for the values of a variable specified by
# a gtool4-type URL.
#
#   2004/12/14  D Tsukahara && T Horinouti(parse_gturl)
#   2005/01/08  D Tsukahara (add option --exch and able to invalid value)
#   2005/01/09  D Tsukahara (add option --animate && proj )
#==USAGE
#
#     % gpview url
#
# where the format of the url is
#
#     path@varname[,dimname=pos1[:pos2[:thinning_intv]][,dimname=...]]
#
# if you want to get more description, please see
#
#     http://www.gfd-dennou.org/arch/gtool4/gtool4-1.0/doc/gtview.htm 
#
#==EXAMPLES
#
#    % gpview data.nc@temp
#    % gpview data.nc@temp,lon=130:150,lat=0:90:2
#    % gpview --nocont data.nc@temp,lon=130:150,lat=0    
#    % gpview --noshade data.nc@temp,lon=130:150,lat=0    
#    % gpview --mean lon data.nc@temp,lon=130:150,lat=0
#    % gpview --exch data.nc@temp,lon=130:150,lat=0
#    % gpview --animate lon data.nc@temp,lon=130:150
#    % gpview --animate lon --alternate data.nc@temp
#    % gpview --smooth lon data.nc@temp,lon=130:150    
#
##################################################

require "getopts"        # for option_parse
require "numru/ggraph"   # ggraph library
include NumRu

#####################################################
$VIEWPORT = [0.15,0.85,0.23,0.58]
URLfmt = "path@varname[,dimname=pos1[:pos2[:thinning_intv]][,dimname=...]]"

## -- parse gturl --

def parse_gturl(gturl)

  if /(.*)@(.*)/ =~ gturl
    file = $1
    var = $2
  else
    raise "invalid URL: '@' between path & variable is not found" +
           "URL format: " + URLfmt
  end
  if /,/ =~ var
    slice = Hash.new
    thinning = Hash.new
    var_descr = var.split(/,/)
    var = var_descr.shift
    var_descr.each do |s|
      if /(.*)=(.*)/ =~ s
        dimname = $1
        subset = $2
        case subset
        when /(.*):(.*):(.*)/
          slice[dimname] = ($1.to_f)..($2.to_f)
          thinning[dimname] = {0..-1,$3.to_i}
        when /(.*):(.*)/
          slice[dimname] = ($1.to_f)..($2.to_f)
        else
          slice[dimname] = subset.to_f
        end
      else
        raise "invalid URL: variable subset specification error\n\n"
           "URL format: " + URLfmt
      end
    end
    thinning = nil if thinning.length == 0
  else
    slice = nil
    thinning = nil
  end
  [file, var, slice, thinning]
end

=begin this method might be delete.. but now keep
def parse_optanim(var)
  if /(.*),(.*)/ =~ var
    slice = Hash.new
    thinning = Hash.new
    var_descr = var.split(/,/)
    var = var_descr.shift
    var_descr.each do |s|
      if /(.*)=(.*)/ =~ s
        dimname = $1
        subset = $2
        case subset
        when /(.*):(.*):(.*)/
          slice[dimname] = ($1.to_f)..($2.to_f)
          thinning[dimname] = {0..-1,$3.to_i}
        when /(.*):(.*)/
          slice[dimname] = ($1.to_f)..($2.to_f)
        else
          slice[dimname] = subset.to_f
        end
      else
        raise "invalid range: variable subset specification error\n\n"
      end
    end
  end
  [var, slice, thinning]
end

=end

def GGraph::annotate(str_ary)
  lnum = 0
  str_ary.each{ |str|lnum += 1 }
    charsize = 0.7 * DCL.uzpget('rsizec1')
  dvx = 0.01
  dvy = charsize*1.5
  raise TypeError,"Array expected" if ! str_ary.is_a?(Array)
  vxmin,vxmax,vymin,vymax = DCL.sgqvpt
  vx = 0.65
  vy = 0.045 + (lnum-1)*dvy
  str_ary.each{|str|
    DCL::sgtxzv(vx,vy,str,charsize,0,-1,1)
    vy -= dvy
  }
  nil
end

def GGraph::map(gphys, newframe=true, kind="coast_world")
  if newframe!=true && newframe!=false
    raise ArgumentError, "2nd arg (newframe) must be true or false"
  end
  gp = gphys.first2D
  gp = gp.transpose(1,0) if $OPT_exch
  xax = gp.coord(0)
  yax = gp.coord(1)
  if newframe
    fig(xax, yax)
    axes(xax, yax)
  end
  DCL::grstrn(10)
  DCL::grswnd(xax.val.min, xax.val.max, yax.val.min, yax.val.max)
  DCL::umpfit                      
  DCL::grstrf
  DCL::umpmap(kind) 
  nil
end




def draw_setup(gp)

  # set missing value
  DCLExt.gl_set_params('lmiss'=>true, 
                       'rmiss'=>gp.data.get_att('missing_value')[0]
                       ) if gp.data.get_att('missing_value')

  # fontsize
  DCL.sgpset('lcntl', false) ; DCL.uzfact(0.7)
  DCL.sgpset('lfull', true)  ; DCL.sgpset('lfprop',true)
  DCL.uscset('cyspos', 'B' )              # move unit y axis
  
  # viewport size
  GGraph.set_fig('viewport'=>$VIEWPORT)
  GGraph.set_fig('itr'=>($OPT_itr))
  GGraph.set_fig("xrev"=>"units:mb,units:hPa,units:millibar",  
                  "yrev"=>"units:mb,units:hPa,units:millibar") 
  
  # set options
  if $OPT_interval
    GGraph.set_linear_contour_options('int'=>$OPT_interval)
    GGraph.set_linear_tone_options('int'=>$OPT_interval)
  end

  # judge draw kind
  gp_rank = gp.rank
  gp_rank = gp_rank - 1 if ($OPT_animate || $OPT_smooth)
  if ($OPT_line || gp_rank == 1) 
    draw_flag = "line"
  elsif (!$OPT_line && gp_rank >= 2) && !$OPT_noshade && $OPT_nocont 
    draw_flag = "nocont"
  elsif (!$OPT_line && gp_rank >= 2) && $OPT_noshade && !$OPT_nocont 
    draw_flag = "noshade"
  elsif (!$OPT_line && gp_rank >= 2) && !$OPT_noshade && !$OPT_nocont
    draw_flag = "full"
  end  

  return draw_flag

end

def draw(gp, draw_flag)

  case draw_flag
  when "line"
    GGraph.line(gp, 
                true,
                "title"=>$OPT_title,
                "index"=>$OPT_index,
                "type"=>$OPT_type,
                "exchange"=>$OPT_exch
                )
  when "full"
    GGraph.tone(gp,
                true, 
                "title"=>$OPT_title,
                "transpose"=>$OPT_exch
                )
    GGraph.contour(gp, false, "transpose"=>$OPT_exch)
  when "nocont"
    GGraph.tone(gp,
                true, 
                "title"=>$OPT_title,
                "transpose"=>$OPT_exch
                )
  when "noshade"
    mj = DCL.udpget('indxmj')
    mn = DCL.udpget('indxmn')
    GGraph.contour(gp, 
                   true, 
                   "title"=>$OPT_title,
                   "label" =>true,
		   "transpose"=>$OPT_exch
                   )
  end
  
  if  draw_flag == ("full" || "nocont")
    #    color_bar#(if gphys colorbar options )
  end
  
  GGraph::map(gp, false, $OPT_map) if $OPT_map
    
  DCL.ueitlv  
end

def draw_info(gp, file, var)
  DCL::sgtxzv($VIEWPORT[1]-0.07,$VIEWPORT[3]+0.02,"(units:#{gp.data.units.to_s})",
              0.7*DCL.uzpget('rsizec2'),0,0,3)    
  DCL::sgtxzv($VIEWPORT[1]-0.61,
              $VIEWPORT[3]+0.02,
              "[#{File::basename(file)}@#{var}]",
              0.7*DCL.uzpget('rsizec2'),0,0,3)  
end

def each_along_dims(gphys, loopdim, loopsense_flag=false)

  raise ArgumentError,"1st argument must be GPhys object." if !gphys.is_a?(GPhys)
  if loopdim.is_a?(String)
    dimname = loopdim
  elsif
    if loopdim < 0 
      dimname = gphys.coord(gphys.rank + loopdim).name
    else
      dimname = gphys.coord(loopdim).name
    end
  else
    raise ArgumentError,"loopdims must consist of Integer and/or String"
  end

  loopdim_na = gphys.coord(dimname).val            # get coord ary
  loopdim_na = loopdim_na[-1..0] if loopsense_flag # transpose loop sense
  
  loopdim_na.each { |x|
    yield( gphys.cut(dimname=>x) )
  }
end


#####################################################
###++++++           Main Routine            ++++++###

unless getopts(
               "", 
               ###    global option   ###
               "wsn:", 
               "mean:", 
               "itr:1", 
               "title:", 
               "animate:",
               "smooth:", 
               "alternate", 
               "nowait", 
	       "exch",
               "map:", 
               ###     line option    ###
               "line", 
               "index:1",
	       "type:1",
               "interval:", 
               ### tone | cont option ###
               "nocont", 
               "noshade"
               )
  print "#{$0}:illegal options.\n"
  exit 1
end


# open netcdf variable
gturl = ARGV[0]
file, var, slice,thinning = parse_gturl(gturl)
gp = GPhys::IO.open(file,var)
gp = gp.cut(slice) if slice
gp = gp[thinning]  if thinning

# mean along any axis
if ($OPT_mean)
  mean = ($OPT_mean).to_s.split(/\s*,\s*/)
  mean.each{|mn|
    gp = gp.mean(gp.axnames.index(mn))
  }
end

DCL::swlset('lwait', false) if ($OPT_nowait) || ($OPT_smooth)
                                         # set wait or nowait
DCL::swlset('lalt',  true)  if ($OPT_smooth || $OPT_alternate)
                                         # set backing store option

# draw figure
DCL.gropn($OPT_wsn||1)
if ( $OPT_animate || $OPT_smooth )
  loopdim = ( $OPT_animate || $OPT_smooth ) 
  kind_of_fig = draw_setup(gp)
  each_along_dims(gp, loopdim){|gp|
    draw(gp, kind_of_fig)
    draw_info(gp, file, var)
  }
else
  kind_of_fig = draw_setup(gp)
  draw( gp, kind_of_fig )
  draw_info(gp, file, var)
end
DCL.grcls