GrADS のファイルを読み込む例を示して
を見ていきたいと思います。ファイルのオープンとクローズは File クラスまたは 組み込み関数 open を使用して
file = File.open(filename [,mode]) or file = open(filename [,mode]) : file.close |
File.open(filename [,mode]){|file|
:
}
|
読み込みには
line = file.gets # 1行読み込む
str = file.read(n) # nバイト読み込む
file.each_byte{|ch| hoge} # 1バイトづつ読み込んでブロックを実行する
file.each_line{|line| hoge} # 1行づつ読み込んでブロックを実行する
|
File.foreach(filename){|line| hoge} # File.open{|file|file.each_line{|line|hoge}}とほぼ同じ
lines = file.readlines # linesは各行の配列
|
書き込みは
file.puts(strings) file.print(strings) |
file << str1 << str2 |
では GrADS のコントロールファイルをよんでいきましょう
grads.ctl
ruby がもっとも得意とするのがこの文字列操作です。 String クラス には様々なメソッドが用意させており、 また強力な 正規表現 も使うことができます。
コントロールファイルの各行はスペースで区切られた要素から成り立っています。 この要素からなる Array クラス を作ってみましょう。
open('grads.ctl','r'){|file|
ary = file.gets.split # ary = ["DSET","^./data"]
}
|
data = Hash.new
open('grads.ctl','r'){|file|
while line = file.gets do
ary = line.split
data[ary[0]] = ary[1..-1]
end
}
|
if line =~ /^\s/ then data[last] = data[last]+ary else last = ary[0] data[last] = ary[1..-1] end |
変数は別の Hash に入れたいと思います。
longname = Hash.new
unit = Hash.new
var = false
if line =~ /^VARS/ then
nvar = line.split[1]
var = true
elsif line =~ /^ENDVARS/ then
var = false
elsif var then
ary = line.split
name = ary[0]
str = ary[3..-1].join(' ')
longname[name] = str[0..str.index('[')-2]
unit[name] = str[str.index('[')+1..-3]
end
|
軸は少し工夫が必要です。
dims = Hash.new
data.each_key{|key|
if key =~ /^.DEF$/
ary = data[key]
name = key[0].downcase
if ary[1] == 'LINEAR'
dims[name] = NArray.sfloat(ary[0].to_i).indgen!(ary[2].to_f,ary[3].to_f)
elsif ary[1] == 'LEVELS'
dims[name] = NArray.to_na( ary[2..-1].collect{|str| str.to_f} )
end
data.delete(key)
}
|
あとは個別の処理
data.each_key{|key|
if key == 'TITLE' then
data[key] = data[key].join(' ')
elsif key == 'UNDEF'
data[key] = data[key][0].to_f
end
}
|
以上まとめると
grads1.rb
となり各データがそろったことになります。
ではコントロールファイルが読めたところで
今度はバイナリファイルを読みたいと思います。
grads1.data
128(x) x 64(y) x 10(z) x 2(var) x 12(month) x 4(sfloat)
というようにデータが入っています。
NArray.to_na(str,"sfloat",dim0,dim1,..) |
idim = x.length
jdim = y.length
kdim = z.length
tdim = t.length
u = NArray.sfloat(idim,jdim,kdim,tdim)
v = NArray.sfloat(idim,jdim,kdim,tdim)
file = open('grads.data','r')
for m in 0..tdim-1
str = file.read(4*idim*jdim*kdim)
u[true,true,true,m] = NArray.to_na(str,"sfloat",idim,jdim,kdim)
str = file.read(4*idim*jdim*kdim)
v[true,true,true,m] = NArray.to_na(str,"sfloat",idim,jdim,kdim)
end
file.close
|
ary = str.unpack('f*')
|
もしこのデータのエンディアンが異なる場合
grads2.data
NArray.to_na(str,.....).swap_byte
str.unpack('e*') (リトルエンディアン) or str.unpack('g*') (ビッグエンディアン)
|
あとはこのデータを煮ても焼いてもあなた次第です。