ruby dcl メモ

サンプル

リンク

gropn

iws = (ARGV[0] || (puts ' WORKSTATION ID (I)  ? ;'; DCL::sgpwsn; gets)).to_i
DCL.gropn(iws)

変数名

gphys.name = "variable name"

long_name

gphys.long_name = "long name"

units

gphys.units = "unit"

missing_value

欠損値確認

rmiss = gphys.get_att('missing_value')[0]

欠損値設定

DCL.glpset('lmiss',true)
DCL.glpset('rmiss',rmiss)

color map

DCL.sgscmn(4)  # blue-cyan-white-yellow-red
DCL.sgscmn(5)  # gray-scale
DCL.sgscmn(14) # blue-white-red

see also here.

copy

gphyscopied = gphys.copy

グローバル属性/大域属性

gphys = GPhys::IO.open('....','hoge')
val = file.att(name).get

name が属性名.

参考ページ

分割

DCL.sldiv('y',1,2)

<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node24.html>

フレーム進行

DCL.sgfrm

<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node24.html>

GPhys オブジェクト作成

非GPhysデータの書出し -- GPhysオブジェクトを一から作る

require "numru/gphys"
include NumRu

nlon = 36
nlat = 18

va_lon = VArray.new( NArray.sfloat(nlon).indgen(0,360.0/nlon),
                  {"long_name"=>"longitude", "units"=>"degrees_east"},
                  "lon" )
ax_lon = Axis.new.set_pos(va_lon)

va_lat = VArray.new( NArray.sfloat(nlat).indgen(0,180/nlat),
                  {"long_name"=>"latitude","units"=>"degrees_north"},
                  "lat" )
ax_lat = Axis.new.set_pos(va_lat)

va_data = VArray.new( NArray.sfloat(nlon,nlat).indgen,
                 {"long_name"=>"temperature", "units"=>"K"},
                 "T" )
gphys = GPhys.new( Grid.new(ax_lon,ax_lat), va_data )

file = NetCDF.create("tmp.nc")
GPhys::NetCDF_IO.write(file,gphys)
file.close

欠損値追加

def addmissingvalue( gp )
  ax_press = gp.axis('Press')
  nam_data = NArrayMiss.to_nam_no_dup(gp.val)
  nam_data.set_missing_value( $missing_value )
  va_data = VArray.new( nam_data,
                        {"long_name"=>gp.long_name, "units"=>gp.units.to_s},
                        gp.name )
  gp = GPhys.new( Grid.new(ax_press), va_data )
  return gp
end

配列次元変更

2 次元から 3 次元

na_val = gp.val.reshape!(gp.shape[0],gp.shape[1],1)

時間軸指定

tas = GPhys::IO.open("tas.nc","tas")
tas.cut("time"=>DateTime.parse("20061202"))

軸情報取得・変換

z = gphys.axis(namelev).pos.convert_units( Units['Pa'] )
z.long_name = 'pressure'
gphys.axis(namelev).set_pos(z)

z = gphys.axis(namelev).pos.convert_units( Units['days since 1979-1-1 00:00:0.0'] )
gphys.axis(namelev).set_pos(z)

time = gphys.coord('time').val

ls = gphys.coord('ls').val
ls = ls + 360
ls = ls % 360
varraytime = VArray.new( ls,
                { "long_name"=>'Ls',
                  "units"=>'degree' }, "ls" )
gphys.axis('ls').set_pos(varraytime)

km = gphyscopied.shape[1]

時間軸指定のための変換

Date.parse("2010-01-04")

軸の太さなど

#DCLExt.uz_set_params 'indext1'=>3,'indext2'=>5,'indexl1'=>5,'indexl2'=>5
DCLExt.uz_set_params 'indext1'=>9,'indext2'=>9,'indexl1'=>9,'indexl2'=>9

references:

緯度経度分布の時

GGraph.set_fig 'itr'=>10, 'viewport'=>[vpx1,vpx2,vpy1,vpy2], 'yrev'=>'units:Pa', 'window'=>[x1,x2,y1,y2]
GGraph.set_map 'coast_world'=>false, 'grid'=>false
GGraph.set_axes('xlabelint'=>90)
GGraph.set_axes('ylabelint'=>30)
...
GGraph.tone true, ... 'map_axes'=>true

配列サイズ情報

size = gphys.length

shapearray = gphys.shape

mask

mask = gphys.val.get_mask

k = 0
while k < km
  j = 0
  while j < jm
    if mask[j,k] == 1 then
      gphysout[j,k] = ( RPlanet * cos( lat[j] * PI / 180.0 ) * Omega + gphysout.val[j,k] ) * RPlanet * cos( lat[j] * PI / 180.0 )
    end
    j = j + 1
  end
  k = k + 1
end

or

gphyszm[ (gphyszm.gt 1.0e3) ] = 1.0e3

(gphyszm.gt 1.0e3) が byte 型配列 (マスク) を作っている.

描画範囲クリップ

DCL.sgpset('lclip', true)

or

下のようにすると, ビューポートからはみ出した部分は描かれない.

DCL.sglset( 'LCLIP', true )

連続描画・動画

DCL::swlset('lwait', false)   # wait or no wait
DCL::swlset('lalt' , true )   # using backing store

legend

line(gphys, true, ..., 'legend'=>'xxx', 'legend_vx'=>0.2, ... )

文字

フォントの変更 1

環境変数を変える.

$ export SW_LSYSFNT=true
$ export SW_FONTNAME="Helvetica"

ruby スクリプト内から実行するなら

ENV['SW_LSYSFNT'] = 'true'
ENV['SW_FONTNAME'] = "Helvetica"

要するに環境変数を変える.

フォントの変更 2

DCL.sgiset('IFONT', 2)
DCL.sgstxi(3)

see <URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node24.html>

サイズ

DCL.uzfact(0.75)

sgtxu/sgtxv で文字を書く時の文字サイズ

rsize = DCL.sgqtxs()
DCL.sgstxs( rsize*0.25 )
DCL.sgstxc(1)

DCL.sgtxu( lone, late+(late-lats)*0.05, label )
  or
DCL.sgtxv( 0.85, 0.56, label )

DCL.sgstxc(0)
DCL.sgstxs( rsize )
DCL.sglset('LCLIP', true)

sgtxu/sgtxv で文字を書く時の文字インデクス

iindex = DCL.sgqtxi()
DCL.sgstxi(3)
DCL.sgstxi(iindex)

<URL:http://dennou-q.geo.kyushu-u.ac.jp/arch/dcl/dcl-f77doc/rc1/grph1/node67.html>

図のシンボル (a), (b), ...

# panel symbol (a), (b), ...
icharnum = "a".ord - 1
icharnum += 1
label = "("+icharnum.chr+")"
rsize = DCL.sgqtxs()
iind  = DCL.sgqtxi()
DCL.sgstxs( rsize*0.5 )
DCL.sgstxi(3)
DCL.sgstxc(-1)
DCL.sglset('LCLIP', false)
DCL.sgtxv( vpx1, vpy2*1.05, label )
DCL.sglset('LCLIP', true)
DCL.sgstxi(iind)
DCL.sgstxs( rsize )

上付き・下付き

DCL.sglset('LCNTL', true)

| または _ で始めて " が終了の記号. " は必須.

DCL.ussttl( 'wavenumber', 'cm|-1"', 'up.flux', 'Wm|-2"(cm|-1")|-1"' )

特殊文字とか

× --- DCL::csgi(194)  # "x" (multiply)

<URL:https://www.gfd-dennou.org/library/dcl/dcl-f90/doc/table/font.htm>

<URL:http://133.5.166.3/library/dcl/dcl-f77doc/doc_numaguti/rakuraku/append/append.html#フォント一覧>

<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node24.html>

文字書き関係

参考

ruby-DCL で線・点を描く

DCL::uuslnt(2)            # 線のタイプ
DCL::uuslni(21)           # 線のインデクス
DCL::uulin(a_lon, a_lat)  # 線を引く
#DCL::uusmks(0.015)        # マークのサイズ
DCL::uusmki(25)           # マークの線の太さ
DCL::uusmkt(2)            # マークの種類
DCL::uumrk(a_lon, a_lat)  # マークを描く

複数に分かれたファイルの読み込み

vname = "GMQH2OVap"

# case 1
ncfn = "????/Temp_rank??????.nc"
url = ncfn + "@" + vname
gphys = GPhys::IO.open_gturl( url )

# case 2
fns = 3
fne = 6
path = Array.new(fne-fns+1)
for i in fns..fne do
  path[i-fns] = "data/GMQH2OVap_rank" + i.to_s.rjust(6,'0') + ".nc"
end
p path
gphys = GPhys::NetCDF_IO.open( path, vname )

# case 3
path = /data\/GMQH2OVap_rank(\d\d\d\d\d\d).nc/
p path
gphys = GPhys::NetCDF_IO.open( path, vname )

複数に分かれたファイルの読み込み (gpview)

$ gpview U_rank00000\?.nc@U --mean lon

画像ファイル名

下のようにすると, 出力ファイル名は file.pdf となる.

DCL.swcset( 'FNAME', 'file' )

画像フォーマット変更

iws=2
DCL.swpset("ifl",1)
DCL.gropn(iws)

'ifl' は出力するファイルフォーマット番号で, 1:png,2:eps,3:SVG,4:PDF. 初期値は 4 です.

(GRPH1 のマニュアル http://www.gfd-dennou.org/arch/dcl/pdf/grph1.pdf の 103 ページ(SWPACK) のサブルーチン使用します.)

連続ページ描画

DCL.swpset("lwait", false)
DCL.swpset("lalt" , true )

lwait は, 改ページのタイミングで一時停止するかどうか, lalt は裏画面で描画するかどうかの指定らしい.

<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node176.html>

等値線 (コンター) メッセージ

DCL.udlset('LMSG', false)

<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node52.html>

サイズの大きな 2 時元データの描画

  • GGraph.tone には, "auto", "tonf" 等のオプションがある.
    • "auto"=>false, "tonf"=>true とすることで, uetonf を使って描画する
    • tone はデータサイズに制限がある.
    • tonf ならば描ける
      • ただし, ggraph.rb 内の l.2777 辺りの uwsgya (uwsgxa) を コメントアウトする必要があるようだ
  • contour はデータサイズに制限がある

tone 覚書 (この問題は解決したのかも)

GGraph.tone には, "auto"=>false のオプションを付けておく方が良い.

GGraph.tone のオプション "auto"=>true (デフォルト) の場合, 与える配列サイズが大きいと, 自動的に uetonf を使って描画される. 現状, uetonf を使って, itr=10 などで描画すると, 枠が描かれてしまう (GGraph.set_map('vpt_boundary'=>true) としていたとしても). 原因は不明.

とりあえず, "auto"=>false として, uetone で描画することにより, (GGraph.set_map('vpt_boundary'=>true) としておけば) 枠が描かれない.

線の色

DCL.uuslni(XXXX)

XXXX の十の位の数字で指定

確認.

lidx = DCL.uuqlni()

複数の図の配置

軸ラベルの詳細設定

GGraph.set_axes('xlabelint'=>90)
GGraph.set_axes('ylabelint'=>30)

正負の値があるときの対数グラフ

1 つの図に複数の線を描く場合. (gp を GPhys オブジェクトの配列にする. 配列でなくても動く.)

def line_x_log( itr, svx1, svx2, svy1, svy2, x1, x2, y1, y2, gp )

 if gp.instance_of?(Array) then
   gp_list = gp
 else
   gp_list = [gp]
 end

 gpn_list = []
 gpp_list = []
 gp_list.each { |gp_each|
   # negative
   gpn = gp_each.copy
   for k in 0..(gp_each.val.size-1)
     gpn[k] = [gp_each.val[k],-1e-10].min
   end
   # positive
   gpp = gp_each.copy
   for k in 0..(gp_each.val.size-1)
     gpp[k] = [gp_each.val[k],1e-10].max
   end
   gpn_list << gpn
   gpp_list << gpp
 }


 DCL.sgfrm

 svx1_local = svx1
 svx2_local = svx1 + ( svx2 - svx1 ) / 2 - ( svx2 - svx1 ) / 2 * 0.02
 x1_local   = -x2
 x2_local   = -x1
 #
 DCL.grfig
 #
 DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2)
 DCL.sgswnd(x1_local,x2_local,y1,y2)
 DCL.grstrn(itr)
 DCL.grstrf
 #
 lidx = DCL.uuqlni()
 gpn_list.each_with_index { |gpn, i|
   DCL.uuslni((i+1)*10)
   DCL.uulin(gpn.val, gpn.coord('Press').val)
 }
 DCL.uuslni(lidx)
 #
#  DCL.ussttl( gp2outsign.long_name.to_s, '', gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )
 #
 DCL.uzlset( 'labelxt', false )
 DCL.uzlset( 'labelxb', false )
 DCL.uzlset( 'labelyl', true  )
 DCL.uzlset( 'labelyr', false )
#  DCL.uscset( 'cxside', 'bt' )
#  DCL.uscset( 'cyside', 'lr' )
 DCL.usdaxs
 # numeric labels for x
 flabels=[]
 clabels=[]
 log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i|
   flabels << -10**i
   clabels << '-10|' + i.to_s + '"'
 end
 DCL.uxplbl('b',1,flabels,clabels,4)


 svx1_local = svx1 + ( svx2 - svx1 ) / 2 + ( svx2 - svx1 ) / 2 * 0.02
 svx2_local = svx2
 x1_local   = x1
 x2_local   = x2
 #
 DCL.grfig
 #
 DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2)
 DCL.sgswnd(x1_local,x2_local,y1,y2)
 DCL.grstrn(itr)
 DCL.grstrf
 #
 lidx = DCL.uuqlni()
 gpp_list.each_with_index { |gpp, i|
   DCL.uuslni((i+1)*10)
   DCL.uulin(gpp.val, gpp.coord('Press').val)
 }
 DCL.uuslni(lidx)
 #
#  DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )
 DCL.uzlset( 'labelxt', false )
 DCL.uzlset( 'labelxb', false )
 DCL.uzlset( 'labelyl', false )
 DCL.uzlset( 'labelyr', false )
 DCL.usdaxs
 # numeric labels for x
 flabels=[]
 clabels=[]
 log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i|
   flabels << 10**i
   clabels << '10|' + i.to_s + '"'
 end
 DCL.uxplbl('b',1,flabels,clabels,4)
 #
 # Label
 DCL.sgsvpt(svx1,svx2,svy1,svy2)
 DCL.grstrf
 rsize = DCL.sgqtxs()
 DCL.sgstxs( rsize*0.5 )
 rsizec = DCL.uzpget( 'rsizec1' )
 DCL.uzpset( 'rsizec1', rsizec * 0.75 )
 DCL.uxsttl('b',"("+gpp_list[0].units.to_s+")",1)
 DCL.uzpset( 'rsizec1', rsizec )
 DCL.sgstxs( rsize )
 DCL.uxsttl('b',gpp_list[0].long_name.to_s,0)
#  DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )

 # reset setting
 DCL.uzlset( 'labelxb', true )
 DCL.uzlset( 'labelyl', true )

end

1 つの図に一本の線を描く場合. (gp は単なる GPhys オブジェクト.)

def line_x_log( itr, svx1, svx2, svy1, svy2, x1, x2, y1, y2, gp )

 # negative
 gpn = gp.copy
 for k in 0..(gp.val.size-1)
   gpn[k] = [gp.val[k],-1e-10].min
 end
 # positive
 gpp = gp.copy
 for k in 0..(gp.val.size-1)
   gpp[k] = [gp.val[k],1e-10].max
 end


 DCL.sgfrm

 svx1_local = svx1
 svx2_local = svx1 + ( svx2 - svx1 ) / 2 - ( svx2 - svx1 ) / 2 * 0.02
 x1_local   = -x2
 x2_local   = -x1
 #
 DCL.grfig
 #
 DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2)
 DCL.sgswnd(x1_local,x2_local,y1,y2)
 DCL.grstrn(itr)
 DCL.grstrf
 #
 DCL.uulin(gpn.val, gpn.coord('Press').val)
 #
#  DCL.ussttl( gp2outsign.long_name.to_s, '', gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )
 #
 DCL.uzlset( 'labelxt', false )
 DCL.uzlset( 'labelxb', false )
 DCL.uzlset( 'labelyl', true  )
 DCL.uzlset( 'labelyr', false )
#  DCL.uscset( 'cxside', 'bt' )
#  DCL.uscset( 'cyside', 'lr' )
 DCL.usdaxs
 # numeric labels for x
 flabels=[]
 clabels=[]
 log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i|
   flabels << -10**i
   clabels << '-10|' + i.to_s + '"'
 end
 DCL.uxplbl('b',1,flabels,clabels,4)


 svx1_local = svx1 + ( svx2 - svx1 ) / 2 + ( svx2 - svx1 ) / 2 * 0.02
 svx2_local = svx2
 x1_local   = x1
 x2_local   = x2
 #
 DCL.grfig
 #
 DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2)
 DCL.sgswnd(x1_local,x2_local,y1,y2)
 DCL.grstrn(itr)
 DCL.grstrf
 #
 DCL.uulin(gpp.val, gpp.coord('Press').val)
 #
#  DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )
 DCL.uzlset( 'labelxt', false )
 DCL.uzlset( 'labelxb', false )
 DCL.uzlset( 'labelyl', false )
 DCL.uzlset( 'labelyr', false )
 DCL.usdaxs
 # numeric labels for x
 flabels=[]
 clabels=[]
 log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i|
   flabels << 10**i
   clabels << '10|' + i.to_s + '"'
 end
 DCL.uxplbl('b',1,flabels,clabels,4)
 #
 # Label
 DCL.sgsvpt(svx1,svx2,svy1,svy2)
 DCL.grstrf
 rsize = DCL.sgqtxs()
 DCL.sgstxs( rsize*0.5 )
 rsizec = DCL.uzpget( 'rsizec1' )
 DCL.uzpset( 'rsizec1', rsizec * 0.75 )
 DCL.uxsttl('b',"("+gpp.units.to_s+")",1)
 DCL.uzpset( 'rsizec1', rsizec )
 DCL.sgstxs( rsize )
 DCL.uxsttl('b',gpp.long_name.to_s,0)
#  DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s )

 # reset setting
 DCL.uzlset( 'labelxb', true )
 DCL.uzlset( 'labelyl', true )

end

出力先選択

iws = (ARGV[0] || (puts ' WORKSTATION ID (I)  ? ;'; DCL::sgpwsn; gets)).to_i
DCL.gropn(iws)

or

print "1: Display,  2: File\n"
citr = gets
citr = citr.chomp!
DCL.gropn(citr.to_i)

内挿

データのファイル出力

outfile = NetCDF.create('data.nc')
...
gptmp = gp.copy
gptmp.rename( "XXX" )
gptmp.long_name = "long name"
gptmp.del_att( 'standard_name' )
GPhys::NetCDF_IO.write( outfile, gptmp )
...
outfile.close

動画作成メモ書き

> convert -rotate 90 -background white -flatten dcl.pdf dcl.tif
> convert -crop 776x388+33+65 dcl.tif dcl.jpg

> convert -crop 778x389+32+64 dcl.tif dcl.jpg

$ convert -rotate 90 dcl.pdf  \( +clone -alpha opaque -fill white -colorize 100% \) +swap -geometry +0+0 -compose Over -composite -alpha off dcl.png

参考ページ

注意

convert 使用時に下のようなエラーが出ることがある.

convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/408.
convert-im6.q16: image sequence is required `+clone' @ error/convert.c/ConvertImageCommand/980.

エラーメッセージで検索すると色々出てくる.

/etc/ImageMagick-6/policy.xml を書き換えると良い.