netcdf を新たに作成 (ruby-netcdf)

「netcdf を新たに作成 (ruby-netcdf)」の編集履歴(バックアップ)一覧はこちら

netcdf を新たに作成 (ruby-netcdf)」(2012/06/22 (金) 13:34:14) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

目次 #contents #br **NetDCF を新たに作る例 -Dennou-ruby チュートリアルの[[ 5. Ruby-NetCDFでデータの読み書き>http://ruby.gfd-dennou.org/tutorial/gokuraku/#h2-5]] の「NetCDFファイルを新たに作る」の部分を参照 以下の手順で NetCDF ファイルを作成することができる +次元の定義 (def_dim) ・変数の定義 (def_var)・属性の定義 (put_att) +enddef とするとNetCDF ファイルの先頭部分が作成される +put メソッドを用いて値を書き込む --変数の一部にだけ書き込みたい場合などには, "start"や"end"といったオプショナルな引数をつける ---これは 「ハッシュ」を用いて実現されている 例: nccreate.rb require "numru/netcdf" include NumRu file = NetCDF.create("test.nc") # 新規作成 nx, ny = 10, 5 file.def_dim("x",nx) # 次元の定義 file.def_dim("y",ny) file.def_dim("t",0) # tはUNLIMITED require "date" file.put_att("history","created by #{$0} #{Date.today}") # グローバル属性の設定 x = file.def_var("x","sfloat",["x"]) # 変数の定義 y = file.def_var("y","sfloat",["y"]) t = file.def_var("t","sfloat",["t"]) v1 = file.def_var("v1","sfloat",["x","y"]) v1.put_att("long_name","test 1") o# 属性の設定 v1.put_att("units","1") v2 = file.def_var("v2","sfloat",["x","y","t"]) v2.put_att("long_name","test 2") v2.put_att("units","1") file.enddef # defineモード終わり x.put( NArray.float(nx).indgen! ) # 値を入れる y.put( NArray.float(ny).indgen! ) z = NArray.float(nx,ny).indgen!*0.1 v1.put(z) v1.put( NArray.float(nx).fill!(20), "start"=>[0,2],"end"=>[-1,2]) # startからendまで値を入れる v2.put(z, "start"=>[0,0,0],"end"=>[-1,-1,0]) t.put( 0, "index"=>[0]) # indexの場所に値を入れる v2.put(-z, "start"=>[0,0,1],"end"=>[-1,-1,1]) t.put( 1, "index"=>[1]) file.close print `ncdump test.nc` # できたファイルを見る #br できたファイルを見る $ ncdump test.nc netcdf test { dimensions: x = 10 ; y = 5 ; t = UNLIMITED ; // (2 currently) variables: float x(x) ; float y(y) ; float t(t) ; float v1(y, x) ; v1:long_name = "test 1" ; v1:units = "1" ; float v2(t, y, x) ; v2:long_name = "test 2" ; v2:units = "1" ; // global attributes: :history = "created by nccreate.rb 2012-06-09" ; data: x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; y = 0, 1, 2, 3, 4 ; t = 0, 1 ; v1 = 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9 ; v2 = 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, -0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1, -1.1, -1.2, -1.3, -1.4, -1.5, -1.6, -1.7, -1.8, -1.9, -2, -2.1, -2.2, -2.3, -2.4, -2.5, -2.6, -2.7, -2.8, -2.9, -3, -3.1, -3.2, -3.3, -3.4, -3.5, -3.6, -3.7, -3.8, -3.9, -4, -4.1, -4.2, -4.3, -4.4, -4.5, -4.6, -4.7, -4.8, -4.9 ; } #br **時間の次元の出力を想定して NetCDF を新たに作る モデルによる時間積分などを想定して, 時間の次元を出力した形で NetCDF を新たに作る例を示す. nccreate_time.rb require "numru/netcdf" include NumRu file = NetCDF.create("test2.nc") # 新規作成 nx, ny = 4, 2 file.def_dim("x",nx) # 次元の定義 file.def_dim("y",ny) file.def_dim("t",0) # t~UNLIMITED require "date" file.put_att("history","created by #{$0} #{Date.today}") # グローバル属性の設定 x = file.def_var("lon","sfloat",["x"]) # 変数の定義 y = file.def_var("lat","sfloat",["y"]) t = file.def_var("t","sfloat",["t"]) x.put_att("long_name","longitude") # 属性の設定 x.put_att("units","deg") y.put_att("long_name","latitude") y.put_att("units","deg") t.put_att("long_name","time") t.put_att("units","s") velx = file.def_var("VelX","sfloat",["x","y","t"]) velx.put_att("long_name","longitudinal velocity") velx.put_att("units","m/s") file.enddef # defineモード終わり x.put( NArray.float(nx).indgen!*120 ) # 値を入れる y.put( NArray.float(ny).indgen!*20 ) dt = 10.0 # time interval nt = 3 # total time step n=0 for n in 0..(nt-1) time = n * dt print "n=#{n}, time=#{time}\n" z = NArray.float(nx,ny).indgen! * n * dt velx.put(z, "start"=>[0,0,n],"end"=>[-1,-1,n]) # startからendまで値を入れる t.put( time, "index"=>[n]) # indexの場所に値を入れる end file.close print `ncdump test2.nc` # できたファイルを見る 実行結果 $ ruby nccreate_time.rb n=0, time=0.0 n=1, time=10.0 n=2, time=20.0 netcdf test2 { dimensions: x = 4 ; y = 2 ; t = UNLIMITED ; // (3 currently) variables: float lon(x) ; lon:long_name = "longitude" ; lon:units = "deg" ; float lat(y) ; lat:long_name = "latitude" ; lat:units = "deg" ; float t(t) ; t:long_name = "time" ; t:units = "s" ; float VelX(t, y, x) ; VelX:long_name = "longitudinal velocity" ; VelX:units = "m/s" ; // global attributes: :history = "created by nccreate_time.rb 2012-06-10" ; data: lon = 0, 120, 240, 360 ; lat = 0, 20 ; t = 0, 10, 20 ; VelX = 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, 50, 60, 70, 0, 20, 40, 60, 80, 100, 120, 140 ; } #br **NetCDFを読んでNetCDFで書き出す 上の演習問題のような、 NetCDFを読みこみ何らかの解析処理を施してNetCDFで書き出す、といったことをおこなうために、 NetCDFクラスを自分用に拡張していきます。まずはNetCDFファイルを読み込み、それをそのままNetCDFファイルに書き出してみます。 例: nccopy.rb # /usr/bin/env ruby require "numru/netcdf" include NumRu module NumRu class NetCDF def copy(outfilename) outfile = NetCDF.create(outfilename) self.each_dim{ |d| # outfile.def_dim(d.name, d.length_ul0) outfile.def_dim(d.name, d.length) # 次元の定義 } vlist = [] # 変数リスト self.each_var{ |v| # vdims = v.dim_names.collect{ |nm| outfile.dim(nm) } # vout = outfile.def_var(v.name, v.vartype, vdims ) # 変数の定義 vout = outfile.def_var(v.name, v.vartype, outfile.dims(v.dim_names) ) v.each_att{ |a| a.copy(vout) } # 属性のコピー vlist.push(vout) # 変数リストの最後に加える } self.each_att{ |a| a.copy(outfile) } # グローバル属性のコピー outfile.enddef self.each_var{ |v| vout = vlist.shift # 変数リストの先頭を取り出し vout.put(v.get) # 変数のコピー p vout.name } outfile.close end end end file = NetCDF.open("T.jan.nc") # 入力ファイル file.copy("nccopy.nc") # 出力ファイル file.close #print `diff T.jan.nc nccopy.nc` each_dim, each_var, each_att といったイテレータを用いています。イテレータに慣れていないとちょっとややこしいですが、汎用性が高くなっています
目次 #contents #br **NetDCF を新たに作る例 -Dennou-ruby チュートリアルの[[ 5. Ruby-NetCDFでデータの読み書き>http://ruby.gfd-dennou.org/tutorial/gokuraku/#h2-5]] の「NetCDFファイルを新たに作る」の部分を参照 以下の手順で NetCDF ファイルを作成することができる +次元の定義 (def_dim) ・変数の定義 (def_var)・属性の定義 (put_att) +enddef とするとNetCDF ファイルの先頭部分が作成される +put メソッドを用いて値を書き込む --変数の一部にだけ書き込みたい場合などには, "start"や"end"といったオプショナルな引数をつける ---これは 「ハッシュ」を用いて実現されている 例: nccreate.rb require "numru/netcdf" include NumRu file = NetCDF.create("test.nc") # 新規作成 nx, ny = 10, 5 file.def_dim("x",nx) # 次元の定義 file.def_dim("y",ny) file.def_dim("t",0) # tはUNLIMITED require "date" file.put_att("history","created by #{$0} #{Date.today}") # グローバル属性の設定 x = file.def_var("x","sfloat",["x"]) # 変数の定義 y = file.def_var("y","sfloat",["y"]) t = file.def_var("t","sfloat",["t"]) v1 = file.def_var("v1","sfloat",["x","y"]) v1.put_att("long_name","test 1") o# 属性の設定 v1.put_att("units","1") v2 = file.def_var("v2","sfloat",["x","y","t"]) v2.put_att("long_name","test 2") v2.put_att("units","1") file.enddef # defineモード終わり x.put( NArray.float(nx).indgen! ) # 値を入れる y.put( NArray.float(ny).indgen! ) z = NArray.float(nx,ny).indgen!*0.1 v1.put(z) v1.put( NArray.float(nx).fill!(20), "start"=>[0,2],"end"=>[-1,2]) # startからendまで値を入れる v2.put(z, "start"=>[0,0,0],"end"=>[-1,-1,0]) t.put( 0, "index"=>[0]) # indexの場所に値を入れる v2.put(-z, "start"=>[0,0,1],"end"=>[-1,-1,1]) t.put( 1, "index"=>[1]) file.close print `ncdump test.nc` # できたファイルを見る #br できたファイルを見る $ ncdump test.nc netcdf test { dimensions: x = 10 ; y = 5 ; t = UNLIMITED ; // (2 currently) variables: float x(x) ; float y(y) ; float t(t) ; float v1(y, x) ; v1:long_name = "test 1" ; v1:units = "1" ; float v2(t, y, x) ; v2:long_name = "test 2" ; v2:units = "1" ; // global attributes: :history = "created by nccreate.rb 2012-06-09" ; data: x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; y = 0, 1, 2, 3, 4 ; t = 0, 1 ; v1 = 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9 ; v2 = 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, -0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1, -1.1, -1.2, -1.3, -1.4, -1.5, -1.6, -1.7, -1.8, -1.9, -2, -2.1, -2.2, -2.3, -2.4, -2.5, -2.6, -2.7, -2.8, -2.9, -3, -3.1, -3.2, -3.3, -3.4, -3.5, -3.6, -3.7, -3.8, -3.9, -4, -4.1, -4.2, -4.3, -4.4, -4.5, -4.6, -4.7, -4.8, -4.9 ; } #br **時間の次元の出力を想定して NetCDF を新たに作る モデルによる時間積分などを想定して, 時間の次元を出力した形で NetCDF を新たに作る例を示す. nccreate_time.rb require "numru/netcdf" include NumRu file = NetCDF.create("test2.nc") # 新規作成 nx, ny = 4, 2 file.def_dim("x",nx) # 次元の定義 file.def_dim("y",ny) file.def_dim("t",0) # t~UNLIMITED require "date" file.put_att("history","created by #{$0} #{Date.today}") # グローバル属性の設定 x = file.def_var("lon","sfloat",["x"]) # 変数の定義 y = file.def_var("lat","sfloat",["y"]) t = file.def_var("t","sfloat",["t"]) x.put_att("long_name","longitude") # 属性の設定 x.put_att("units","deg") y.put_att("long_name","latitude") y.put_att("units","deg") t.put_att("long_name","time") t.put_att("units","s") velx = file.def_var("VelX","sfloat",["x","y","t"]) velx.put_att("long_name","longitudinal velocity") velx.put_att("units","m/s") file.enddef # defineモード終わり x.put( NArray.float(nx).indgen!*120 ) # 値を入れる y.put( NArray.float(ny).indgen!*20 ) dt = 10.0 # time interval nt = 3 # total time step n=0 for n in 0..(nt-1) time = n * dt print "n=#{n}, time=#{time}\n" z = NArray.float(nx,ny).indgen! * n * dt velx.put(z, "start"=>[0,0,n],"end"=>[-1,-1,n]) # startからendまで値を入れる t.put( time, "index"=>[n]) # indexの場所に値を入れる end file.close print `ncdump test2.nc` # できたファイルを見る 実行結果 $ ruby nccreate_time.rb n=0, time=0.0 n=1, time=10.0 n=2, time=20.0 netcdf test2 { dimensions: x = 4 ; y = 2 ; t = UNLIMITED ; // (3 currently) variables: float lon(x) ; lon:long_name = "longitude" ; lon:units = "deg" ; float lat(y) ; lat:long_name = "latitude" ; lat:units = "deg" ; float t(t) ; t:long_name = "time" ; t:units = "s" ; float VelX(t, y, x) ; VelX:long_name = "longitudinal velocity" ; VelX:units = "m/s" ; // global attributes: :history = "created by nccreate_time.rb 2012-06-10" ; data: lon = 0, 120, 240, 360 ; lat = 0, 20 ; t = 0, 10, 20 ; VelX = 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, 50, 60, 70, 0, 20, 40, 60, 80, 100, 120, 140 ; } -1次元([[nccreate_time_1dim.rb]]) #br **NetCDFを読んでNetCDFで書き出す 上の演習問題のような、 NetCDFを読みこみ何らかの解析処理を施してNetCDFで書き出す、といったことをおこなうために、 NetCDFクラスを自分用に拡張していきます。まずはNetCDFファイルを読み込み、それをそのままNetCDFファイルに書き出してみます。 例: nccopy.rb # /usr/bin/env ruby require "numru/netcdf" include NumRu module NumRu class NetCDF def copy(outfilename) outfile = NetCDF.create(outfilename) self.each_dim{ |d| # outfile.def_dim(d.name, d.length_ul0) outfile.def_dim(d.name, d.length) # 次元の定義 } vlist = [] # 変数リスト self.each_var{ |v| # vdims = v.dim_names.collect{ |nm| outfile.dim(nm) } # vout = outfile.def_var(v.name, v.vartype, vdims ) # 変数の定義 vout = outfile.def_var(v.name, v.vartype, outfile.dims(v.dim_names) ) v.each_att{ |a| a.copy(vout) } # 属性のコピー vlist.push(vout) # 変数リストの最後に加える } self.each_att{ |a| a.copy(outfile) } # グローバル属性のコピー outfile.enddef self.each_var{ |v| vout = vlist.shift # 変数リストの先頭を取り出し vout.put(v.get) # 変数のコピー p vout.name } outfile.close end end end file = NetCDF.open("T.jan.nc") # 入力ファイル file.copy("nccopy.nc") # 出力ファイル file.close #print `diff T.jan.nc nccopy.nc` each_dim, each_var, each_att といったイテレータを用いています。イテレータに慣れていないとちょっとややこしいですが、汎用性が高くなっています

表示オプション

横に並べて表示:
変化行の前後のみ表示: