データ読み書きの基本はNetCDFを参照。 NetCDF †NCLのファイル読み書きをNetCDFを基本に説明する。NCLはNetCDFの変数を読み込んだ時に自動的に格子情報やattributionを読み込んでくれる。NCLの利点のひとつである。 読む †まずは開きたいファイルをNCLに伝える作業を行う(Fortranでいうところのopen)。
無事にファイルを開けたら変数を取り出す。ファイル内の変数を指定するさいには->という記号を使う。
addfilesで開いたファイルから変数を読む場合,すべてのファイルで変数名が共通で,最も左の次元以外のサイズが同じでなくてはならない。
$ ncdump -h precip.mon.mean.nc とすると netcdf precip.mon.mean { dimensions: lon = 144 ; lat = 72 ; time = UNLIMITED ; // (449 currently) variables: ... (途中省略) ... float precip(time, lat, lon) ; precip:long_name = "Average Monthly Rate of Precipitation" ; precip:valid_range = 0.f, 70.f ; precip:units = "mm/day" ; precip:add_offset = 0.f ; precip:scale_factor = 1.f ; precip:missing_value = -9.96921e+36f ; ... (以下省略) のように出る。このとき,NCLスクリプト in = addfile("precip.mon.mean.nc","r") ; ファイルを開く x = in->precip ; ファイル内の変数precipをNCL変数xに入れる printVarSummary(x) ; 変数xについての情報を表示 を実行すると,xにprecipのデータが入って, Variable: precip Type: float Total Size: 18620928 bytes 4655232 values Number of Dimensions: 3 Dimensions and sizes: [time | 449] x [lat | 72] x [lon | 144] Coordinates: time: [1569072..1896312] lat: [88.75..-88.75] lon: [1.25..358.75] Number Of Attributes: 15 long_name : Average Monthly Rate of Precipitation valid_range : ( 0, 70 ) units : mm/day add_offset : 0 scale_factor : 1 missing_value : -9.96921e+36 ... (途中省略) ... _FillValue : -9.96921e+36 のように出る。 書く †NetCDFでの書き出しも,読み込みと同様にすることでできる。つまり,まずは書き出したいファイルをaddfileを用いて指定する。 out = addfile(outfile,"c") とする。スクリプト内の変数uをuという変数名で,変数vをvという変数名で書き出したいときには, out->u = u out->v = v とすれば書き込みできるし,スクリプト内の変数名とファイルでの変数名を変えることも,もちろん可能である。 out->ucomp = u out->vcomp = v
なお,デフォルトでは2GB以上のファイルを書き出すことができないと思われる。大きなNetCDFファイルを作成したい場合には,あらかじめ,setfileoptionでNetCDFの"Format"オプションを"LargeFile"に指定する。 setfileoption("nc","Format","LargeFile")
GRIB †基本的にNetCDFと同じ。ただし読み込みしかできない。変数名はコマンドラインからncl_filedumpで確認してもよいし,getfilevarnamesで知ることもできる。 4byteバイナリ(GrADSの形式) †
DSET ^hoge.grd OPTIONS BIG_ENDIAN XDEF 360 LINEAR 0 1. YDEF 181 LINEAR -90 1. ZDEF 1 LEVELS 0 TDEF 12 LINEAR 01JAN2000 1mn VARS 1 hoge 0 99 ENDVARS のとき1ステップ目(01JAN2000)を持って来たい時は setfileoption("bin", "ReadByteOrder", "BigEndian") hoge= fbindirread("hoge.grd",0,(/1,181,360/),"float") のようにする。 Attributesで未定義値(undef)を設定するとよい xdef = 360 ; 経度方向のサイズ ydef = 181 ; 緯度方向のサイズ tdef = 12 ; 時間方向のサイズ msgval = -1.e21 ; 未定義値が-1.e21だとする ;;; varの座標情報となる緯度,経度,時間の配列をつくる lat = fspan(-90,90,ydef) lat@units = "degree_N" lon = fspan(0,359,xdef) lon@units = "degree_E" time = ispan(0,tdef-1,1) time@units = "months since 2000-01-01 00:00:00" ;;; 座標変数自体にも座標をつけたほうがお行儀が良い(別に必要ないことも多い) lat!0 = "lat" lat&lat = lat lon!0 = "lon" lon&lon = lon time!0 = "time" time&time = time ;;; 読む setfileoption("bin", "ReadByteOrder", "BigEndian") var = fbindirread("./hoge.grd",0,-1,"float") var := reshape(var,(/tdef,ydef,xdef/)) ;;; varに座標情報などを付加する var!0 = "time" var!1 = "lat" var!2 = "lon" var&time = time var&lat = lat var&lon = lon var@_FillValue = msgval var@units = "degC" var@longname = "temperature" ;;; NetCDFで出力 system("rm -f ./hoge.nc") out = addfile("./hoge.nc","c") att = True att@title = "temperature data hogehoge" att@source_file = "hoge.grd" att@creation_date = systemfunc("date") fileattdef(out,att) ; ファイル全体についての情報を付加 filedimdef(out,"time",-1,True) ; 時間次元をunlimitedに out->hoge = var ASCIIデータ †ASCIIデータを読むにはasciireadを使う。
読みたいASCIIデータのファイルにヘッダーやフッターの行が含まれていて,それを除外して値を読みたい場合,readAsciiTableが使えるかもしれない。
この関数では,xがいかなる形の配列であっても,値は各行に一つずつ書き込まれる。表のようなフォーマットで出力したいときにはwrite_tableが使えるかもしれない。 CSV †単に数値のみから構成されるCSVを読む方法は基本的にはASCIIと同じで,asciireadなどを使えばよい。 2015,1,10.0,A 2015,2,10.5,B 2015,3,11.0,C 2015,4,11.5,D 2015,5,12.0,E をstr_splitを用いて読むスクリプト例 in = asciiread("test1.csv",-1,"string") ROW = dimsizes(in) dum = str_split(in(0),",") COL = dimsizes(dum) var = new((/ROW,COL/),"string") var(0,:) = dum do i = 1, ROW-1 var(i,:) = str_split(in(i),",") end do delete([/in,dum/]) X = tofloat(var(:,2)) Y = var(:,3) print(X) print(Y) この結果として, Variable: X Type: float Total Size: 20 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] Coordinates: Number Of Attributes: 1 _FillValue : 9.96921e+36 (0) 10 (1) 10.5 (2) 11 (3) 11.5 (4) 12 Variable: Y Type: string Total Size: 40 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] Coordinates: Number Of Attributes: 1 _FillValue : missing (0) A (1) B (2) C (3) D (4) E を得る。 2015,1,10.0,A 2015,2,,B 2015,3,11.0,C 2015,4,11.5, 2015,5,12.0,E をstr_split_csvを用いて読むスクリプト例 var = asciiread("test2.csv",-1,"string") var := str_split_csv(var,",",0) X = tofloat(var(:,2)) Y = var(:,3) print(X) print(Y) この結果として, Variable: X Type: float Total Size: 20 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] Coordinates: Number Of Attributes: 1 _FillValue : 9.96921e+36 (0) 10 (1) 9.96921e+36 (2) 11 (3) 11.5 (4) 12 Variable: Y Type: string Total Size: 40 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] Coordinates: Number Of Attributes: 1 _FillValue : missing (0) A (1) B (2) C (3) missing (4) E を得る。 |