ruby dcl メモ
サンプル
- 簡単なやつ
- 簡単なやつ (経度—緯度)
- 簡単なやつ (ベクトル)
- <URL:./scripts/mkfig_U.rb>
- <URL:./scripts/gphys_const_v1.2.rb>
- <URL:./scripts/gphys_methods_v2.00.rb>
リンク
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>
文字書き関係
- sgtxu, sgtxv, sgtxrで描く文字列のセンタリングオプションの設定
- sgtxu, sgtxv, sgtxrで描く文字列の回転角の設定
- sgtxu, sgtxv, sgtxrで描く文字の高さの設定
- sgtxu, sgtxv, sgtxrで描く文字のラインインデクスの設定
参考
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 を書き換えると良い.