「netcdf を新たに作成 (ruby-netcdf)」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
目次
#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 といったイテレータを用いています。イテレータに慣れていないとちょっとややこしいですが、汎用性が高くなっています