#!/usr/bin/env ruby
##################################################
=begin
=NAME

gpvect - drawing 2-dim vector fiels. Contour/tone of scalar field can be plotted simultaneously.

==USAGE

The first command form is for only vector field plotting.

     % gpvect [options] gturl_x gturl_y ....

where the format of the gturl is

     path[@|/]varname[,dimname=pos1[:pos2[:thinning_intv]][,dimname=...]]

The command loads two gphys variables in each time and draws
vector field whose x and y components are the first and the second argument,
gturl_x gturl_y.

When the slice parameters are the same throughout the all Gphys
variables, the following form can be used:

     % gpvect --slice <slice> [options] file@var_x file@var_y ...

where the format of the slice is

     dimname=pos1[:pos2[:thinning_intv]][,dimname=...]]

The second command form is

     % gpvect --scalar [options] gturl_c gturl_x gturl_y ....

In this case the command loads three gphys variables in each time and
draws a contour/tone of the first argument gturl_c, and vector fields
whose x and y components are the second and the thrid argument,
gturl_x gturl_y.

==OPTIONS

===GLOBAL OPTIONS

:--help:
  print this message.

:--slice url:
  set the slicing parameters.

:--wsn [1-4]:
  set work staion number. each number represent output device.
  1: X window.
  2: PS file. (named dcl.ps)
  3: Tektronix output.
  4: GTK Windows (depend on dcl-5.3)

:--clrmap [1-]:
  set colormap to draw tone/contour. default is 1.

:--itr [1-4,5-7,10-15,20-23,30-33]:
  set axis scale. default is 1.
  1: linear scale for x/y axis
  2: linear scale for x , log scale for y axis
  3: log scale for x , linear scale for y axis
  4: log scale for x/y axis

:--similar [simfac,vxoff,vyoff]:
  (for 5<=itr<=7) set similarity parameters which are fed in DCL.grssim.

:--map_axis [uxc,uyc,rot]:
  (for 10<=itr<=33) set mapping parameters which are fed in DCL.umpcnt.

:--title:
  set title of figure

:--aspect <aspect>:
  set aspect ratio of Viewport. default is 2.0.

:--noannotate:
  not draw annotations.

:--animate/anim <dim>:
  plot animation along <dim>. <dim> must be name of dimension.

:--alternate, --Ga:
  enable to backing store.

:--nowait, --Gw:
  not wait for any actions if animate

:--reverse, --Gr:
  plot animation reversible if animate

:--smooth, --Gaw:
  equal to --anlternate && --nowait

:--exch:
  exchange(transpose) x/y axis.

:--mean <dim>:
  mean along axis <dim>.

:--eddy <dim>:
  deviation from mean along axis <dim>.

:--m, --map <map_type>:
  plot map. itr number must be set.  this option is neglect if itr
  number is 1-4.  abailable map type is coast_world, border_world,
  plate_world, state_usa, coast_japan, pref_japan

:--scalar:
  plot scaler field (contour,tone)

:-xx:yyyy=value:
  specify Dennou Club Library internal variable.
  'xx' is a package name prefix of DCL (eg. sg=>sgpack).
  'yy' is a variable name of DCL.
  'value' is a value of the DCL variable.


===CONTOUR/TONE OPTIONS

:--shade:
  make contour and tone plot.

:--noshade:
  make contour plot, without tone.

:--nocont:
  make tone plot, without contour.

:--range [min:max]:
  set min/max value for contour/tone plot. min or max must be set.

:--crange:
  set min/max value for contour plot. this is more dominant than --range

:--srange:
  set min/max value for tone plot. this is more dominant than --interval/int

:--interval,--int [num]:
  set interval value for contour/tone plot.set the number of lines if
  you set negative value.

:--cint:
  set interval value for contour plot. this is more dominant than --interval/int

:--sint:
  set interval value for tone plot. this is more dominant than --interval/int.

:--levels:
  set values of contour/tone levels.

:--clevels:
  set values of contour levels.

:--slevels:
  set tone of contour levels.

:--patterns:
  set each patterns for tone plot.

:--tone [a|e|f|b|c]:
  set tone subroutine:
    a (=> tone routine is selected automatically depending on the datasize)
    e (=> DCL.uetone is used)
    f (=> DCL.uetonf is used)
    b (=> DCL.uetonb is used)
    c (=> DCL.uetonc is used)

:--nocolorbar:
  do not draw color bar

:--nozero:
  do not draw zero contour

:--udsfmt [strings]:
  change contour label format. see UDCNTR/DCL manual for the format.


===VECTOR OPTIONS

:--noflow_vect:
  DCL::ugvect is used.

:--xintv <xintv>:
  interval of data sampling in x

:--yintv <yintv>:
  interval of data sampling in y

:--factor <factor>:
  (Effective only if flow_vect) scaling factor to strech/reduce the
  arrow lengths

:--unit_vect:
  Show the unit vector

:--max_unit_vect:
  (Effective only if flow_vect && unit_vect) use the maximum arrows to
  scale the unit vector

:--ux_unit <value>:
  (Effective only if flow_vect) length of the x direction unit vector
  (precedence of this option is lower than max_unit_vect)

:--uy_unit <value>:
  (Effective only if flow_vect) length of the y direction unit vector
  (precedence of this option is lower than max_unit_vect)

:--xscale <value>:
  (Effective only if noflow_vect) scaling of the x direction vector

:--yscale <value>:
  (Effective only if noflow_vect) scaling of the y direction vector


==EXAMPLES

For the first command format,

    % gpvect data.nc@vx data.nc@vy
    % gpvect data.nc@vx,lon=0 data.nc@vy,lon=0
    % gpvect --scalar data.nc@temp datax.nc@vx datay.nc@vy
    % gpvect --scalar --anim t --nocont data.nc@temp data.nc@vx data.nc@vy

For the second command format,
    % gpvect --scalar --slice lat=0 data.nc@temp data.nc@vx data.nc@vy


==HISTORY

  2007/07/02  S Takehiro (created based on gpview)
  2007/07/04  S Takehiro (polar coodinate vector component conversion
                          from U to N coordinates moved to ggraph.rb)
  2007/07/06  S Takehiro (default title was set when --scalar option is given)
  2009/09/30  S Takehiro (option --nocolorbar and --nozero implemented)
  2010/03/10  Y SASAKI (change help block into RD format)
  2010/07/16  Y SASAKI (option --clrmap implemented)
  2011/07/29  S Takehiro (option --clrmap fixed)
  2012/02/19  S Takehiro (description for gturl format updated)
  2012/07/28  S Takehiro (option --ux_unit, --uy_unit, --xscale, --yscale
                          implemented)
  2014/02/21  Y Naito && S Takehiro (implement DCL internal variable setting,
                                     add option --udsfmt)
  2014/02/23  S Takehiro (option --tonf is changed to --tone)
  2014/03/10  Y Kawai && S Takehiro (setting labels for contours)

=end
#################################################
require "getoptlong"        # for option_parse
require "numru/ggraph"      # ggraph library
require "numru/gphys/gpcommon"

include NumRu

#####################################################
## Default param.

VIEWPORT = [0.15,0.85,0.2,0.55]
URLfmt = "path[@|/]varname[,dimname=pos1[:pos2[:thinning_intv]][,dimname=...]]"

#####################################################
def GGraph::annotate(str_ary)
  lclip = DCL.sgpget('lclip')
  DCL.sgpset('lclip',nil)
  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.70
  vy = 0.045 + (lnum-1)*dvy
  str_ary.each{|str|
    DCL::sgtxzv(vx,vy,str,charsize,0,-1,1)
    vy -= dvy
  }
  DCL.sgpset('lclip',lclip)
  nil
end

def each_along_dims(gp1, gp2, gp3, loopdim)

  raise ArgumentError,"1st argument must be an GPhys." if !gp1.is_a?(GPhys)
  raise ArgumentError,"1st argument must be an GPhys." if !gp2.is_a?(GPhys)
  raise ArgumentError,"1st argument must be an GPhys." if !gp3.is_a?(GPhys)

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

  loopdim_na = gp1.coord(dimname).val                      # get coord ary
  loopdim_na = loopdim_na[-1..0] if $OPT_reverse || $OPT_Gr  # reverse
  loopdim_na.each { |x|
    yield( gp1.cut(dimname=>x), gp2.cut(dimname=>x), gp3.cut(dimname=>x) )
  }
end


def draw_setup(gp)

  # set missing value
  DCLExt.gl_set_params('lmiss'=>true)

  # fontsize
  DCL.sgpset('lcntl', false)
#  DCL.uzfact(0.7)
  DCL.sgpset('lfull', true)               # use full area in the window
  DCL.sgpset('lfprop',true)               # use proportional font
  DCL.uscset('cyspos', 'B' )              # move unit y axis

  # viewport size
  GGraph.set_fig('viewport'=>$VIEWPORT)
  GGraph.set_fig( 'itr'=>($OPT_itr == nil) ? 1 : $OPT_itr.to_i )
  GGraph.set_fig("xrev"=>"units:mb,units:hPa,units:millibar,positive:down",
                 "yrev"=>"units:mb,units:hPa,units:millibar,positive:down")

  # set options
  min_range,  max_range  = __split_range($OPT_range)
  min_crange, max_crange = __split_range($OPT_crange)
  min_srange, max_srange = __split_range($OPT_srange)
  if ( $OPT_cint   || $OPT_interval || $OPT_int )
    cont_interval = ( $OPT_cint   || $OPT_interval || $OPT_int ).to_f
  else
    cont_interval = nil
  end
  if ( $OPT_sint   || $OPT_interval || $OPT_int )
    tone_interval =  ( $OPT_sint   || $OPT_interval || $OPT_int ).to_f
  else
    tone_interval = nil
  end
  GGraph.set_linear_contour_options(
                                    'int' => cont_interval,
                                    'min' => ( min_crange  || min_range ),
                                    'max' => ( max_crange  || max_range )
                                    )
  GGraph.set_linear_tone_options(
                                    'int' => tone_interval,
                                    'min' => ( min_srange  || min_range ),
                                    'max' => ( max_srange  || max_range )
                                 )
  if ( $OPT_clevels || $OPT_levels )
    $OPT_label=($OPT_clevels || $OPT_levels).split(',')
    $OPT_clevels=($OPT_clevels || $OPT_levels).split(',').map!{|v| v.to_f }
  end

  if ( $OPT_slevels || $OPT_levels )
    $OPT_slevels=($OPT_slevels||$OPT_levels).split(',').map!{|v| v.to_f }
  end

  if ( $OPT_patterns )
    $OPT_patterns=$OPT_patterns.split(',').map!{|v| v.to_f }
  end

  # judge draw kind
  gp_rank = gp.rank
  gp_rank = gp_rank - 1 if ( $OPT_animate || $OPT_anim )

  raise "The rank of gphys variables must be >=2 " if (gp_rank < 2)

  if ( $OPT_scalar )
    if ( !$OPT_noshade && $OPT_nocont )
      draw_flag = "nocont"
    elsif ( $OPT_noshade && !$OPT_nocont )
      draw_flag = "noshade"
    elsif ( !$OPT_noshade && !$OPT_nocont )
      draw_flag = "full"
    end
  else
    draw_flag = 'noscalar'
  end

  # similar projection
  if ($OPT_similar)
    if /([\d\-.]*),([\d\-.]*),([\d\-.]*)/ =~ $OPT_similar
      similar=[$1.to_f,$2.to_f,$3.to_f]
    elsif /([\d\-.]*),([\d\-.]*)/ =~ $OPT_similar
      similar=[$1.to_f,$2.to_f,0]
    elsif /([\d\-.]*)/ =~ $OPT_similar
      similar=[$1.to_f,0,0]
    end
    GGraph.set_fig('similar'=>similar)
  end

  # similar projection
  if ($OPT_map_axis)
    if /([\d\-.]*),([\d\-.]*),([\d\-.]*)/ =~ $OPT_map_axis
      map_axis=[$1.to_f,$2.to_f,$3.to_f]
    elsif /([\d\-.]*),([\d\-.]*)/ =~ $OPT_map_axis
      map_axis=[$1.to_f,$2.to_f,0]
    elsif /([\d\-.]*)/ =~ $OPT_similar
      map_axis=[$1.to_f,0,0]
    end
    GGraph.set_fig('map_axis'=>map_axis)
  end


  # map
  if ( $OPT_m || $OPT_map)
    map_type = "coast_world"     if $OPT_m
    map_type = $OPT_map          if $OPT_map
    GGraph::set_map(map_type=>true)
  end

  # vector
  if ($OPT_noflow_vect)
    $flow_vect = false
  else
    $flow_vect = true
  end

  if ($OPT_unit_vect)
    $unit_vect = true
  else
    $unit_vect = false
  end

  if ($OPT_max_unit_vect)
    $max_unit_vect = true
  else
    $max_unit_vect = false
  end

  if ($OPT_ux_unit)
    $ux_unit = $OPT_ux_unit.to_f
  else
    $ux_unit = nil
  end

  if ($OPT_uy_unit)
    $uy_unit = $OPT_uy_unit.to_f
  else
    $uy_unit = nil
  end

  if ($OPT_xscale)
    xscale = $OPT_xscale.to_f
    DCL.ugpset('LNRMAL',false)
    vx_unit=DCL.ugpget('VXUNIT')
    DCL.ugpset('XFACT1',vx_unit/xscale)
  end

  if ($OPT_yscale)
    yscale = $OPT_yscale.to_f
    DCL.ugpset('LNRMAL',false)
    vy_unit=DCL.ugpget('VYUNIT')
    DCL.ugpset('YFACT1',vy_unit/yscale)
  end

  $xintv=($OPT_xintv||1).to_i
  $yintv=($OPT_yintv||1).to_i
  $factor=($OPT_factor||1).to_f

  return draw_flag

end

def draw(gp, gpux, gpuy, draw_flag)

  # draw contour/tone
  case draw_flag
  when "full"
    GGraph.tone(gp,
                true,
                "title"=>$OPT_title,
                "annotate"=>$annotate,
                "transpose"=>$OPT_exch,
                "levels"=>$OPT_slevels,
                "patterns"=>$OPT_patterns,
                "auto"=>$auto,
                "tonf"=>$tonf,
                "tonb"=>$tonb,
                "tonc"=>$tonc
                )
    GGraph.contour(gp,
		   false,
		   "transpose"=>$OPT_exch,
		   "levels"=>$OPT_clevels,
		   "nozero"=>$OPT_nozero,
                   "label"=>$OPT_label
		   )
    vnewframe = false

  when "nocont"
    GGraph.tone(gp,
                true,
                "title"=>$OPT_title,
                "annotate"=>$annotate,
                "transpose"=>$OPT_exch,
                "levels"=>$OPT_slevels,
                "patterns"=>$OPT_patterns,
                "auto"=>$auto,
                "tonf"=>$tonf,
                "tonb"=>$tonb,
                "tonc"=>$tonc
                )
    vnewframe = false

  when "noshade"
    mj = DCL.udpget('indxmj')
    mn = DCL.udpget('indxmn')
    GGraph.contour(gp,
                   true,
                   "title"    =>$OPT_title,
                   "label"    =>true,
                   "annotate"=>$annotate,
		   "transpose"=>$OPT_exch,
                   "levels"=>$OPT_clevels,
		   "nozero"=>$OPT_nozero,
                   "label"=>$OPT_label
                   )
    vnewframe = false

  when "noscalar"
    vnewframe = true
  end

  # draw vector

  if ($OPT_itr == '5')
    GGraph.vector( gpux, gpuy, newframe=vnewframe,
                  "title"=>$OPT_title,
                  "annotate"=>$annotate,
                  "exchange"=>$OPT_exch,
                  "flow_vect"=>false,
                  "flow_itr5"=>true,
                  "xintv"=>$xintv,
                  "yintv"=>$yintv,
                  "factor"=>$factor,
                  "unit_vect"=>$unit_vect,
                  "max_unit_vect"=>$max_unit_vect,
                  "ux_unit"=>$ux_unit,
                  "uy_unit"=>$uy_unit
                  )
  else
    GGraph.vector(gpux, gpuy, newframe=vnewframe,
                  "title"=>$OPT_title,
                  "annotate"=>$annotate,
                  "exchange"=>$OPT_exch,
                  "flow_vect"=>$flow_vect,
                  "xintv"=>$xintv,
                  "yintv"=>$yintv,
                  "factor"=>$factor,
                  "unit_vect"=>$unit_vect,
                  "max_unit_vect"=>$max_unit_vect,
                  "ux_unit"=>$ux_unit,
                  "uy_unit"=>$uy_unit
                  )
   end

  # color bar
  if ( ( draw_flag == "full") || ( draw_flag == "nocont") ) && $colorbar
    GGraph::color_bar(
                      "left"      => true,
                      "landscape" => true
                      )
  end

end


def set_vpsize( default_vp, aspect=2.0 )

  raise "#{aspect} must be a positive Numeric" if (aspect.to_f <= 0.0)
  aspect = aspect.to_f

  # default viewport
  x0 = default_vp[0]; x1 = default_vp[1]
  y0 = default_vp[2]; y1 = default_vp[3]
  # viewport size
  hlength =   x1 - x0
  vlength =   y1 - y0
  # center grid of viewport
  cen_of_vp = [ x0 + hlength/2.0, y0 + vlength/2.0  ]

  if aspect <= 2.0
    hlength = vlength * aspect
    x0 = cen_of_vp[0] - hlength/2.0
    x1 = cen_of_vp[0] + hlength/2.0
  else
    vlength = hlength / aspect
    y0 = cen_of_vp[1] - vlength/2.0
    y1 = cen_of_vp[1] + vlength/2.0
  end

  return [ x0, x1, y0, y1 ]

end

def __split_range(range)

  if /(.*):(.*)/ =~ range
    if $1 == ""
      min = nil
    else
      min = $1.to_f
    end
    if $2 == ""
      max = nil
    else
      max = $2.to_f
    end
  elsif range == nil
    min = max = nil
  else
    raise "invalid range: variable subset specification error. split range with ':'\n\n"
  end

  return min, max
end

def check_dclopts

  indices = []
    ARGV.each_index{|i|
    if /^-(.)(.):(.*)=(.*)/ =~ ARGV[i]
      indices << i
    end
    }

  dclopts = []
    indices.reverse_each{|i|
    dclopts << ARGV[i]
    ARGV.slice!(i)
    }

  dclopts.each{|opt|
    pkg = opt[1..2]
    name = opt[4..-1].split('=')[0]
    value = opt[4..-1].split('=')[1]
    dcl_set_params(pkg,name,value)
  }

end

def dcl_set_params(pkg,name,value)

  set = 'stx'
  case name
  when /^c/i
    eval( "DCL.#{pkg}c#{set}(name,value.to_s)" )
  when /^l/i
    if /(.*)(T|t)(.*)/ =~ value
      eval( "DCL.#{pkg}l#{set}(name,true)" )
    else
    if /(.*)(F|f)(.*)/ =~ value
      eval( "DCL.#{pkg}l#{set}(name,false)" )
    else
      raise "value of logical parameter must include 't' or 'f'"
    end
    end
  when /^[i-n]/i
    eval( "DCL.#{pkg}i#{set}(name,value.to_i)" )
  else
    eval( "DCL.#{pkg}r#{set}(name,value.to_f)" )
  end

end

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

## options for DCL
check_dclopts

## parse options
parser = GetoptLong.new
parser.set_options(
                   ###    global option   ###
                   ['--slice',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--wsn',                      GetoptLong::REQUIRED_ARGUMENT],
                   ['--clrmap',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--itr',                      GetoptLong::REQUIRED_ARGUMENT],
                   ['--similar',                  GetoptLong::REQUIRED_ARGUMENT],
                   ['--map_axis',                 GetoptLong::REQUIRED_ARGUMENT],
                   ['--title',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--aspect',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--anim',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--animate',                  GetoptLong::REQUIRED_ARGUMENT],
                   ['--noannotate',               GetoptLong::NO_ARGUMENT],
                   ['--alternate',                GetoptLong::NO_ARGUMENT],
                   ['--Ga',                       GetoptLong::NO_ARGUMENT],
                   ['--nowait',                   GetoptLong::NO_ARGUMENT],
                   ['--Gw',                       GetoptLong::NO_ARGUMENT],
                   ['--smooth',                   GetoptLong::NO_ARGUMENT],
                   ['--Gaw',                      GetoptLong::NO_ARGUMENT],
                   ['--exch',                     GetoptLong::NO_ARGUMENT],
                   ['--reverse',                  GetoptLong::NO_ARGUMENT],
                   ['--Gr',                       GetoptLong::NO_ARGUMENT],
                   ['--mean',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--eddy',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--map',                      GetoptLong::REQUIRED_ARGUMENT],
                   ['--m',                        GetoptLong::NO_ARGUMENT],
                   ['--scalar',                   GetoptLong::NO_ARGUMENT],
                   ### tone or cont option ###
                   ['--nocont',                   GetoptLong::NO_ARGUMENT],
                   ['--noshade',                  GetoptLong::NO_ARGUMENT],
                   ['--range',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--crange',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--srange',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--interval',                 GetoptLong::REQUIRED_ARGUMENT],
                   ['--int',                      GetoptLong::REQUIRED_ARGUMENT],
                   ['--cint',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--sint',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--levels',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--clevels',                  GetoptLong::REQUIRED_ARGUMENT],
                   ['--slevels',                  GetoptLong::REQUIRED_ARGUMENT],
                   ['--patterns',                  GetoptLong::REQUIRED_ARGUMENT],
                   ['--tone',                     GetoptLong::REQUIRED_ARGUMENT],
                   ['--udsfmt',                   GetoptLong::REQUIRED_ARGUMENT],
                   ['--nocolorbar',               GetoptLong::NO_ARGUMENT],
                   ['--nozero',                   GetoptLong::NO_ARGUMENT],
                   ###    vector option    ###
                   ['--noflow_vect',              GetoptLong::NO_ARGUMENT],
                   ['--xintv',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--yintv',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--factor',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--unit_vect',              GetoptLong::NO_ARGUMENT],
                   ['--max_unit_vect',          GetoptLong::NO_ARGUMENT],
                   ['--ux_unit',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--uy_unit',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--xscale',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--yscale',                    GetoptLong::REQUIRED_ARGUMENT],
                   ['--help',                     GetoptLong::NO_ARGUMENT]
#                   ['--version',                  GetoptLong::NO_ARGUMENT]  # to be defined
                   )
begin
  parser.each_option do |name, arg|
    eval "$OPT_#{name.sub(/^--/, '').gsub(/-/, '_')} = '#{arg}'"  # strage option value to $OPT_val
  end
rescue
  help
  raise
end

## Print out help message
if ($OPT_help)
  help
  exit(1)
end

## set some figure option
DCL::swlset('lwait', false) if ($OPT_nowait    || $OPT_Gw || $OPT_smooth || $OPT_Gaw)
                                           # set wait or nowait
DCL::swlset('lalt',  true)  if ($OPT_alternate || $OPT_Ga || $OPT_smooth || $OPT_Gaw)
                                           # set backing store option
if ($OPT_noannotate)
  $annotate = false
else
  $annotate = true
end

if ($OPT_nocolorbar)
  $colorbar = false
else
  $colorbar = true
end

if ($OPT_tone)
  case $OPT_tone
  when "a"
    $auto, $tonf, $tona, $toneb, $tonec = true,false,false,false
  when "e"
    $auto, $tonf, $tona, $toneb, $tonec = false,false,false,false
  when "f"
    $auto, $tonf, $tona, $toneb, $tonec = false,true,false,false
  when "b"
    $auto, $tonf, $tona, $toneb, $tonec = false,false,true,false
  when "c"
    $auto, $tonf, $tona, $toneb, $tonec = false,false,false,true
  else
    raise "The value of option --tone should be 'a','e','f','b' or 'c'."
  end
else
  $auto, $tonf, $tona, $toneb, $tonec = true,false,false,false
end

## decide VIEWPORT
$VIEWPORT = set_vpsize( VIEWPORT, ($OPT_aspect||2.0) )

## tune the size of axis parameters.
DCL.uzfact(0.7)

## set the format of contour labels.
udsfmt = ($OPT_udsfmt||DCL.udqfmt())
DCL.udsfmt(udsfmt)

## draw figure
loopdim   = ( $OPT_animate || $OPT_anim )
loopdim = loopdim.to_i if loopdim.to_i.to_s == loopdim

## set colormap
DCL.sgscmn($OPT_clrmap||1)
## open work station
if NumRu::DCL::DCLVERSION.to_f >= 6
  DCL.gropn($OPT_wsn||1)
else
  DCL.gropn($OPT_wsn||4)
end

## open netcdf variables

while ARGV[0] do
  gturl = ARGV[0]
  gturl = gturl+','+$OPT_slice if $OPT_slice
  gp = GPhys::IO.open_gturl(gturl)
  print "  Reading #{gturl}\n"

  ARGV.shift

  if ( $OPT_scalar )
    gturlx = ARGV[0]
    gturlx = gturlx+','+$OPT_slice if $OPT_slice

    gpux = GPhys::IO.open_gturl(gturlx)
    print "  Reading #{gturlx}\n"
    ARGV.shift
  else
    gpux = gp
  end

  gturly = ARGV[0]
  gturly = gturly+','+$OPT_slice if $OPT_slice

  gpuy = GPhys::IO.open_gturl(gturly)
  print "  Reading #{gturly}\n"
  ARGV.shift

  sh = gp.shape
  if sh != gpux.shape
    raise ArgumentError, "shapes of 1st and 2nd variables do not agree with each other"
  elsif sh != gpuy.shape
    raise ArgumentError, "shapes of 1st and 3rd variables do not agree with each other"
  end

## mean along any axis
  if ($OPT_mean)
    dims = ($OPT_mean).split(/\s*,\s*/)
    dims.each{|dim|
      dim = dim.to_i if dim.to_i.to_s == dim
      gp = gp.mean(dim)
      gpux = gpux.mean(dim)
      gpuy = gpuy.mean(dim)
    }
  end

## deviation from mean along any axis
  if ($OPT_eddy)
    dims = ($OPT_eddy).split(/\s*,\s*/)
    dims.each{|dim|
      dim = dim.to_i if dim.to_i.to_s == dim
      gp = gp.eddy(dim)
      gpux = gpux.eddy(dim)
      gpuy = gpuy.eddy(dim)
    }
  end

  # set title
  if !$OPT_title && $OPT_scalar
    gpnm   = gp.data.get_att('long_name')   || gp.name
    gpuxnm = gpux.data.get_att('long_name') || gpux.name
    gpuynm = gpuy.data.get_att('long_name') || gpuy.name
    $OPT_title = gpnm+'('+gpuxnm+','+gpuynm+')'
  end

  # draw margin infomation
  GGraph.margin_info($0, gturl+'('+gturlx+','+gturly+')') if $annotate && $OPT_scalar
  GGraph.margin_info($0, gturl+','+gturly) if $annotate && !$OPT_scalar

  kind_of_fig = draw_setup(gp)                # determine figure kind

  if loopdim           # animation
    each_along_dims(gp, gpux, gpuy, loopdim){|gp_sub,gpux_sub,gpuy_sub|
      draw(gp_sub,gpux_sub,gpuy_sub, kind_of_fig)
    }
  else
    draw( gp, gpux, gpuy, kind_of_fig )       # single figure
  end

end

DCL.grcls
