TOOL

TOOL

令和6年3月

はじめに

免責事項

本文書はDS2022データセットを利用しようと考えている方向けに提供している情報です。 しかし、本文書を利用して生じるいかなる損害についても、責任は負いません。 利用者の責任での利用をお願いします。

前書き

気候予測データセット2022の主要なファイル・フォーマットやその描画ツール等について、サンプルデータを用いて解説する。 ツール類のインストール等については、環境構築を参照されたい。 なお、サンプルデータには、参考資料の充実度を考慮し、必要に応じて気候予測データ以外のデータを用いる。

DS2022気候予測データの主要なファイル・フォーマット

GRIB / GRIB2

世界気象機関(WMO)で策定したフォーマットであり、数値気象予報モデルの出力であるグリッドデータを各国の気象現業機関の間で交換することなどに使用されている。 GRIBは気象庁55年長期再解析(JRA-55)でも使用されている第1版と、現行の第2版(GRIB2)の二つの版が広く利用されている。 なお、以降の解説では、区別のため第1版についてはGRIB1と表記する場合がある。 座標系や各種パラメータが格納されており、ファイルサイズを小さくするためにデータの圧縮が行われる。 そのため同じデータをGRIB1/GRIB2と後述するNetCDFファイルに格納した場合では、GRIB1/GRIB2のファイルサイズが小さいことが多い。 またデータファイルに格納されている変数の名前や単位は、パラメータについてのテーブル(parameter table)を参照する形となっている。 例えば「 JRA-55プロダクト利用手引書 1.25度緯度/経度格子データ編」の等圧面解析値(anl_p125)の出力要素の表4-5を見たとき、 表の一番左のカラムの「数字符号」に対応するパラメータ(変数名)と単位がその右側に書かれている。

表1. JRA-55 表4.5の抜粋

このような情報をそれぞれのツールのparameter tableのフォーマットに従ってテキストファイルに書き出しておく必要がある。

NetCDF

米国のUniversity Corporation of Atmospheric Research (UCAR) の Unidata プログラムで開発されたデータフォーマット。 「世界気候研究計画(WCRP)」のもとで実施されている「結合モデル相互比較プロジェクト(CMIP)」に提出される気候モデルのデータはこのNetCDF形式のフォーマットに格納したものである。 データファイルは、ヘッダー部(格子の情報などを含む)とデータ部からなる。 ファイルの中には格子やデータ自体に関する属性も格納されており、データファイルを読むだけで、どのようなデータがファイルに格納されているのかを理解できる(自己記述式)。 通常は4バイト実数でデータを格納するが、そのままではファイルサイズが大きくなることが多く、 過去に用いられていたコンピューターのファイルシステムではデータを格納できないことがあった(例えばFAT32では1ファイルの容量は最大4GBであった)。 そのため”y = ix * scale + offset”という変換式を利用して符号付き2バイト整数(short int)で格納してファイルサイズを小さくすることがあった (例えば1990年代後半に公開されたNCEP-NCAR大気再解析データ)。 なお、最新のNetCDF4ライブラリでは圧縮ライブラリを用いてファイルサイズを小さくすることができるようになっている。

いわゆる「GrADS形式」

次の枠の中のコード片のようにFortranでunformattedかつdirectで書き出したバイナリファイル(時にはsequentialで書き出したものもある)。

real varray(ix, iy) open(10, file=’tmp.bin’, form=’unformatted’, access=’direct’, recl=ix*iy*4) write(10, rec=1) varray

通常は4バイト(32ビット)の実数(float)で書き出す。 一方、ファイルサイズを小さくするために、“y = ix * scale + offset”という変換式を利用して、2バイト符号あり整数(short int)に変換して書き出すこともある。 GrADSでは4バイト実数で格納されたファイルも2バイト符号あり整数で格納されたファイルも読み込むことができる。 またデータファイル自身にはデータが格納されているのみであり、「どのような変数がどのような次元をもっているのか」などの情報は別途コントロールファイルとして提供される。 特に、データが北から南に向けて格納されているのか、データがlittle endianで書き出されたものなのかそれともbig endianで書き出されたのかといった情報もコントロールファイルに含まれている。

サンプルデータ

本文書で使用するサンプルデータを列挙する。それぞれの公開先からダウンロードをすること。

NOAA Extended Reconstructed SST V5

米国 NOAA Physical Sciences Laboratory から公開されている海面水温データ “NOAA Extended Reconstructed SST V5 (ERSST)”をダウンロードする。

$ wget https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc # ファイルに含まれているデータの情報を確認。 $ ncdump -h sst.mnmean.nc netcdf sst.mnmean { dimensions: lat = 89 ; lon = 180 ; time = UNLIMITED ; // (2026 currently) nbnds = 2 ; variables: float lat(lat) ; lat:units = "degrees_north" ; lat:long_name = "Latitude" ; lat:actual_range = 88.f, -88.f ; lat:standard_name = "latitude" ; lat:axis = "Y" ; lat:coordinate_defines = "center" ; float lon(lon) ; lon:units = "degrees_east" ; lon:long_name = "Longitude" ; lon:actual_range = 0.f, 358.f ; lon:standard_name = "longitude" ; lon:axis = "X" ; lon:coordinate_defines = "center" ; double time_bnds(time, nbnds) ; time_bnds:long_name = "Time Boundaries" ; double time(time) ; time:units = "days since 1800-1-1 00:00:00" ; time:long_name = "Time" ; time:delta_t = "0000-01-00 00:00:00" ; time:avg_period = "0000-01-00 00:00:00" ; time:prev_avg_period = "0000-00-07 00:00:00" ; time:standard_name = "time" ; time:axis = "T" ; time:actual_range = 19723., 81357. ; float sst(time, lat, lon) ; sst:long_name = "Monthly Means of Sea Surface Temperature" ; sst:units = "degC" ; sst:var_desc = "Sea Surface Temperature" ; sst:level_desc = "Surface" ; sst:statistic = "Mean" ; sst:missing_value = -9.96921e+36f ; sst:dataset = "NOAA Extended Reconstructed SST V5" ; sst:parent_stat = "Individual Values" ; sst:actual_range = -1.8f, 42.32636f ; sst:valid_range = -1.8f, 45.f ; // global attributes: <<以下省略>>

変数としてlat, lon, time_bnds, time, sstが含まれている。 このうちlat, lon, timeは次元を表現する1次元データであり、 海面水温sstはsst(time, lat, lon)と表示されており、経度・緯度・時間の3次元データであることがわかる。 また、sst:long_name = “Monthly Means of Sea Surface Temperature”や sst:units = “degC”などは変数sstの属性である。 NetCDFでは属性を適切に付与することにより、どのようなデータがこのファイルに格納されているのかを知ることができるようになっている。

気象庁55年長期再解析(JRA-55)

DIASから公開されている気象庁55年長期再解析(JRA-55)のうち、anl_surf125の気候値(/jra55/Clim9120/Monthly/anl_surf125)のデータをダウンロードする。 そして、拡張子が”.ctl”となっているコントロールファイルと”.idx”となっているインデックスファイルも入手する。 また、anl_surf125の月別データ(/jra55/Hist/Monthly/anl_surf125)の2022年1月のデータを入手する。

図1. DIASでのJRA-55 anl_surf125検索画面

# 上の赤枠のところに表示されている【一括ダウンロードスクリプト】を利用する際 # Python2が必要となる。condaで $ conda create -n py27 python=2.7 # として、Python 2.7が動く仮想環境を作成しておく。 # 仮想環境py27をアクティベートして、 # 一括ダウンロードスクリプトを用いてデータをダウンロードする。 # UsernameにはDIASのアカウントを、PasswordにはDIASのパスワードを入力する。 $ conda activate py27 $ python2 ./download.py Username:abcd1234@example.com Password:xxxxxxxxxxx # ダウンロード終了後にconda環境を終了する。 $ conda deactivate

d4PDF_RCM

気候予測データセット2022の「全球及び日本域確率的気候予測データ(d4PDFシリーズ)」の日本域ダウンスケーリングデータである d4PDF_RCMの過去実験(HPB)のアンサンブルメンバーm001の2000年1月の地上大気データと実験共通の標高分布・海陸分布データをダウンロードする。 d4PDFのダウンロードは 「d4PDFダウンロード」 から実行できる。

図2. DIASでのd4PDF_RCMの地上要素検索画面

図3. DIASでのd4PDF_RCMのfixedデータ検索画面

まずは2000年1月のデータをダウンロードする。 files.tar という名前でダウンロードされるので、ダウンロードしたら

$ tar xvf files.tar

として解凍する。その後は

$ mv files.tar files.surf20001.tar

のように改名しておく。同様に標高分布・海陸分布データをダウンロードし解凍する。

過去実験データは d4PDF_RCM/HPB/m001/1999 以下に

surf_HPB_m001_200001.ctl, surf_HPB_m001_200001.grib, surf_HPB_m001_200001.idx

が書き出される。 標高分布・海陸分布データは d4PDF_RCM/fixed 以下に

topo_essp20.ctl, topo_essp20.dat

が書き出される。

GrADSのexampleデータ

米国 George Mason University の The Center for Ocean-Land-Atmosphere Studies の GrADS のウェブページにある example.tar.gz をダウンロードする。

$ wget ftp://cola.gmu.edu/grads/example.tar.gz $ tar zxvf example.tar.gz model.ctl model.dat tutorial

データ・ビューアー

ncview

米国 Scripps Institution of Oceanography の Pierce 氏が作成したNetCDF形式ファイル用のデータ・ビューアー。

ターミナルの中で以下のようにして起動。

$ ncview sst.mnmean.nc

図4. ncview のメイン画面

図5. ncview のデータ表示画面

Panoply

米国 NASA Goddard Institute for Space Studiesで開発されたデータ・ビューアー。 NetCDF / HDF / GRIB形式ファイルの可視化に利用できる。

$ panoply.sh

として、起動。ファイル選択画面からファイルを選択。

図6. Panoplyのメイン画面

図7. Panoplyで描画した画面

wgrib / wgrib2

米国のNOAA Climate Prediction Centerから公開されている。

  • wgrib : GRIBのデータを処理するときに使用する。
  • wgrib2 : GRIB2のデータを処理するときに使用する。
  • 【参考】日本自動車研究所の早崎氏が公開されているwgrib/wgrib2の使い方の情報のページ。

パラメータテーブル

wgrib / wgrib2に内蔵されていないGRIBのパラメータテーブルを使用しているデータを読む際には、ユーザーがパラメータテーブルを用意する必要がある。 JRA-55の場合、「JRA-55プロダクト利用手引書」を参照すればよい。 または、GrADS用のコントロールファイルがあれば、そこから数字符号を入手することもできる。

JRA-55のパラメータテーブルを作成し、エクスポートする。

$ less JRA55_anl_surf_ptable_wgrib.txt -1:34:241:200 1:pres:"surface pressure [Pa]" 2:msl:"mean sea level pressure [Pa]" 11:airt:"air temperature [K]" 13:pott:"potential temperature [K]" 18:depr:"dewpoint depression [K]" 51:sphum:"speciphic humidity [kg/kg]" 52:rhum:"relative humidity [%]" 33:uwnd:"eastward wind [m/s]" 34:vwnd:"northward wind [m/s]" $ export GRIBTAB=./JRA55_anl_surf_ptable_wgrib.txt

ファイルの確認

JRA-55のanl_surf125 の平年値ファイルの中味を確認する。

$ wgrib anl_surf125.clim9120.mon01 1:0:d=91010100:pres:kpds5=1:kpds6=1:kpds7=0:TR=51:P1=0:P2=1:TimeU=3:sfc:0-1mon product:ave@1yr:NAve=30 2:62748:d=91010100:pott:kpds5=13:kpds6=1:kpds7=0:TR=51:P1=0:P2=1:TimeU=3:sfc:0-1mon product:ave@1yr:NAve=30 3:125496:d=91010100:msl:kpds5=2:kpds6=102:kpds7=0:TR=51:P1=0:P2=1:TimeU=3:MSL:0-1mon product:ave@1yr:NAve=30 4:188244:d=91010100:airt:kpds5=11:kpds6=105:kpds7=2:TR=51:P1=0:P2=1:TimeU=3:2 m above gnd:0-1mon product:ave@1yr:NAve=30 5:250992:d=91010100:depr:kpds5=18:kpds6=105:kpds7=2:TR=51:P1=0:P2=1:TimeU=3:2 m above gnd:0-1mon product:ave@1yr:NAve=30 6:313740:d=91010100:sphum:kpds5=51:kpds6=105:kpds7=2:TR=51:P1=0:P2=1:TimeU=3:2 m above gnd:0-1mon product:ave@1yr:NAve=30 7:376488:d=91010100:rhum:kpds5=52:kpds6=105:kpds7=2:TR=51:P1=0:P2=1:TimeU=3:2 m above gnd:0-1mon product:ave@1yr:NAve=30 8:439236:d=91010100:uwnd:kpds5=33:kpds6=105:kpds7=10:TR=51:P1=0:P2=1:TimeU=3:10 m above gnd:0-1mon product:ave@1yr:NAve=30 9:501984:d=91010100:vwnd:kpds5=34:kpds6=105:kpds7=10:TR=51:P1=0:P2=1:TimeU=3:10 m above gnd:0-1mon product:ave@1yr:NAve=30

Unix環境ではwgrib/wgrib2とcatやgrepなどの併用で、データの追加または抽出ができる。 また、GRIB形式のファイルからGrADSで用いられるバイナリファイルに変換することができる。

データの抽出

anl_surf125の平年値ファイルから気圧データだけを抽出し、バイナリファイルに変換する。なお”\“は継続行を意味する。

$ wgrib anl_surf125.clim9120.mon01 | grep “:pres:” | \ wgrib anl_surf125.clim9120.mon01 -i -bin -nh \ -o anl_surf125.clim9120.mon01.pres.bin

Climate Data Operators (cdo)

ドイツのMax-Planck-Institut fur Meteorologie から公開されている。 NetCDF形式、GRIB形式、GrADS形式のファイルの操作をすることができるツールである。

パラメータテーブル

cdoに含まれていないGRIBのパラメータテーブルを用いたファイルをcdoで処理する際には、ユーザーがパラメータテーブルを作成する必要がある。 JRA-55の場合、「JRA-55プロダクト利用手引書」を参照すればよい。 または、GrADS用のコントロールファイルがあれば、そこから数字符号を入手することもできる。

$ less JRA55_anl_surf_ptable_cdo.txt 1 pres pressure  [Pa] 2 msl mean sea level pressure [Pa] 11 airt air temperature  [K] 13 pott potential temperature [K] 18 depr dewpoint depression [K] 51 sphum speciphic humidity [kg/kg] 52 rhum relative humidity [%] 33 uwnd eastward wind  [m/s] 34 vwnd northward wind  [m/s] $

ファイルの確認

パラメータテーブルを"-t"のオプションで指定して、ファイルの中味を確認する。

# ファイルの中味の確認。 # JRA-55のファイルの時間平均のパラメータが理解できないとエラーが出力されるが、データは読むことができる。 $ cdo -t JRA55_anl_surf_ptable_cdo.txt infon anl_surf125.clim9120.mon01 ECCODES ERROR : Unknown stepType=[51] timeRangeIndicator=[51] <<エラー中略>> -1 : Date Time Level Gridsize Miss : Minimum Mean Maximum : Parameter name 1 : 1991-01-01 00:00:00 0 41760 0 : 51862. 96635. 1.0284e+05 : pres 2 : 1991-01-01 00:00:00 0 41760 0 : 239.76 280.06 323.57 : pott 3 : 1991-01-01 00:00:00 0 41760 0 : 98292. 1.0101e+05 1.0417e+05 : msl 4 : 1991-01-01 00:00:00 2 41760 0 : 239.19 277.04 306.51 : airt 5 : 1991-01-01 00:00:00 2 41760 0 : 0.80086 3.5672 26.121 : depr 6 : 1991-01-01 00:00:00 2 41760 0 : 0.00014653 0.0072782 0.020822 : sphum 7 : 1991-01-01 00:00:00 2 41760 0 : 18.014 79.283 92.421 : rhum 8 : 1991-01-01 00:00:00 10 41760 0 : -10.454 -0.060975 9.4525 : uwnd 9 : 1991-01-01 00:00:00 10 41760 0 : -9.5364 -0.20628 9.3699 : vwnd cdo infon: Processed 375840 values from 9 variables over 1 timestep [0.06s 47MB].

GRIB1形式からNetCDF形式への変換

GRIB1形式であるJRA-55のデータをNetCDF形式に変換する。 "-f nc copy" で変換できる。

$ cdo -t JRA55_anl_surf_ptable_cdo.txt -f nc copy anl_surf125.clim9120.mon01 anl_surf125.clim9120.mon01.nc ECCODES ERROR : Unknown stepType=[51] timeRangeIndicator=[51] <<エラー中略>> cdo copy: Processed 375840 values from 9 variables over 1 timestep [0.15s 51MB].

GrADS用バイナリファイルからNetCDF形式への変換

GrADS用バイナリファイルをNetCDF形式に変換するには"-f nc import_binary"を用いる。 なおバイナリファイナル自身ではなく、コントロールファイルを引数として与える。

$ cdo -f nc import_binary model.ctl model.nc cdo import_binary: Processed 8 variables [0.22s 44MB]. $ cdo sinfon model.nc File format : NetCDF2 -1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter name 1 : unknown unknown v instant 1 1 3312 1 F32 : ps 2 : unknown unknown v instant 7 2 3312 1 F32 : u 3 : unknown unknown v instant 7 2 3312 1 F32 : v 4 : unknown unknown v instant 7 2 3312 1 F32 : hgt 5 : unknown unknown v instant 7 2 3312 1 F32 : tair 6 : unknown unknown v instant 5 3 3312 1 F32 : q 7 : unknown unknown v instant 1 1 3312 1 F32 : tsfc 8 : unknown unknown v instant 1 1 3312 1 F32 : p Grid coordinates : 1 : lonlat : points=3312 (72x46) lon : 0 to 355 by 5 degrees_east circular lat : -90 to 90 by 4 degrees_north Vertical coordinates : 1 : surface : levels=1 2 : generic : levels=7 lev : 1000 to 100 3 : generic : levels=5 lev_2 : 1000 to 300 Time coordinate : time : 5 steps RefTime = 1987-01-02 00:00:00 Units = hours Calendar = standard YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss 1987-01-02 00:00:00 1987-01-03 00:00:00 1987-01-04 00:00:00 1987-01-05 00:00:00 1987-01-06 00:00:00 cdo sinfon: Processed 8 variables over 5 timesteps [0.01s 45MB].

指定した変数の抽出

複数の変数が格納されているファイルから指定した変数だけを抽出する。

# 地上気圧データを抽出する。 $ cdo select,name=ps model.nc ps.nc # 気温データを抽出する。 $ cdo select,name=tair model.nc tair.nc

指定した年のデータの抽出

NetCDF形式のERSSTのデータファイルから指定した年のデータを抽出する。

# 1991年の海面水温データを抽出する。 $ cdo select,year=1991/1991/1 sst.mnmean.nc sst.1991.nc # ファイルの中味の確認。 $ cdo sinfo sst.1991.nc File format : NetCDF4 classic -1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID 1 : unknown In situ v instant 1 1 2 1 F64 : -1 2 : unknown In situ v instant 1 1 16020 2 F32 : -2 Grid coordinates : 1 : generic : points=2 2 : lonlat : points=16020 (180x89) lon : 0 to 358 by 2 degrees_east circular lat : 88 to -88 by -2 degrees_north Vertical coordinates : 1 : surface : levels=1 Time coordinate : time : 12 steps RefTime = 1800-01-01 00:00:00 Units = days Calendar = standard YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss 1991-01-01 00:00:00 1991-02-01 00:00:00 1991-03-01 00:00:00 1991-04-01 00:00:00 1991-05-01 00:00:00 1991-06-01 00:00:00 1991-07-01 00:00:00 1991-08-01 00:00:00 1991-09-01 00:00:00 1991-10-01 00:00:00 1991-11-01 00:00:00 1991-12-01 00:00:00 cdo sinfo: Processed 2 variables over 12 timesteps [0.02s 45MB].

1991年の各月の月初の時刻が表示され、1991年の12個のデータが抽出されたことがわかる。

同様にして、1992年のデータだけを格納しているファイルと、1993年のデータだけを格納しているファイルを作成する。

$ cdo select,year=1992/1992/1 sst.mnmean.nc sst.1992.nc $ cdo select,year=1993/1993/1 sst.mnmean.nc sst.1993.nc

ファイルの結合

緯度・経度・高さ/深さの各次元の格子数が同一である年別のデータファイルを"mergetime"を用いて結合できる。1991年、1992年、1993年の海面水温データを一つのファイルに結合する。

$ cdo mergetime sst.1991.nc sst.1992.nc sst.1993.nc sst.1991-1993.nc cdo mergetime: Processed 576792 values from 6 variables over 36 timesteps [0.17s 51MB].

ファイルの中味の確認。

$ cdo sinfo sst.1991-1993.nc File format : NetCDF4 classic -1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID 1 : unknown In situ v instant 1 1 2 1 F64 : -1 2 : unknown In situ v instant 1 1 16020 2 F32 : -2 Grid coordinates : 1 : generic : points=2 2 : lonlat : points=16020 (180x89) lon : 0 to 358 by 2 degrees_east circular lat : 88 to -88 by -2 degrees_north Vertical coordinates : 1 : surface : levels=1 Time coordinate : time : 36 steps RefTime = 1800-01-01 00:00:00 Units = days Calendar = standard YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss 1991-01-01 00:00:00 1991-02-01 00:00:00 1991-03-01 00:00:00 1991-04-01 00:00:00 1991-05-01 00:00:00 1991-06-01 00:00:00 1991-07-01 00:00:00 1991-08-01 00:00:00 1991-09-01 00:00:00 1991-10-01 00:00:00 1991-11-01 00:00:00 1991-12-01 00:00:00 1992-01-01 00:00:00 1992-02-01 00:00:00 1992-03-01 00:00:00 1992-04-01 00:00:00 1992-05-01 00:00:00 1992-06-01 00:00:00 1992-07-01 00:00:00 1992-08-01 00:00:00 1992-09-01 00:00:00 1992-10-01 00:00:00 1992-11-01 00:00:00 1992-12-01 00:00:00 1993-01-01 00:00:00 1993-02-01 00:00:00 1993-03-01 00:00:00 1993-04-01 00:00:00 1993-05-01 00:00:00 1993-06-01 00:00:00 1993-07-01 00:00:00 1993-08-01 00:00:00 1993-09-01 00:00:00 1993-10-01 00:00:00 1993-11-01 00:00:00 1993-12-01 00:00:00 cdo sinfo: Processed 2 variables over 36 timesteps [0.02s 45MB].

指定した領域のデータの切り出し

領域を指定してデータを切り出す。次の例は、東経120度から東経180度、北緯20度から北緯50度の領域の海面水温データを切り出す。

$ cdo sellonlatbox,120,180,20,50 sst.1991.nc sst.1991.sub.nc $ cdo sinfo sst.1991.sub.nc File format : NetCDF4 classic -1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID 1 : unknown In situ v instant 1 1 2 1 F64 : -1 2 : unknown In situ v instant 1 1 496 2 F32 : -2 Grid coordinates : 1 : generic : points=2 2 : lonlat : points=496 (31x16) lon : 120 to 180 by 2 degrees_east lat : 50 to 20 by -2 degrees_north Vertical coordinates : 1 : surface : levels=1 Time coordinate : time : 12 steps RefTime = 1800-01-01 00:00:00 Units = days Calendar = standard YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss 1991-01-01 00:00:00 1991-02-01 00:00:00 1991-03-01 00:00:00 1991-04-01 00:00:00 1991-05-01 00:00:00 1991-06-01 00:00:00 1991-07-01 00:00:00 1991-08-01 00:00:00 1991-09-01 00:00:00 1991-10-01 00:00:00 1991-11-01 00:00:00 1991-12-01 00:00:00 cdo sinfo: Processed 2 variables over 12 timesteps [0.02s 46MB].

図8. 日本付近のERSST切り出し

panoplyで表示すると上のように日本付近が切り出されていることがわかる。

統計値の作成

月平均値から各年の年平均値を作成。

$ cdo yearmonmean sst.1991-1993.nc sst.1991-1993.yearmean.nc $ cdo sinfo sst.1991-1993.yearmean.nc File format : NetCDF4 classic -1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID 1 : unknown In situ v instant 1 1 2 1 F64 : -1 2 : unknown In situ v instant 1 1 16020 2 F32 : -2 Grid coordinates : 1 : generic : points=2 2 : lonlat : points=16020 (180x89) lon : 0 to 358 by 2 degrees_east circular lat : 88 to -88 by -2 degrees_north Vertical coordinates : 1 : surface : levels=1 Time coordinate : time : 3 steps RefTime = 1800-01-01 00:00:00 Units = days Calendar = standard Bounds = true YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss 1991-06-16 00:00:00 1992-06-16 00:00:00 1993-06-16 00:00:00 cdo sinfo: Processed 2 variables over 3 timesteps [0.02s 46MB]. $ ncview sst.1991-1993.yearmean.nc

図9. ncviewで時間を確認する

GrADS

  • 米国 George Mason University の The Center for Ocean-Land-Atmosphere Studiesで開発されたソフトウェア。
  • バイナリファイルは, コントロールファイルを”open test.ctl”として読み込む。
  • NetCDFファイル(COARDS convention / CF convention)を”sdfopen test.nc”として読み込む。
  • 読み込むことができないNetCDFファイルは、コントロールファイルを作成して、xdfopenコマンドを利用してデータを読み込む。
  • GRIBのファイルは “grib2ctl.pl”、 GRIB2のファイルは “g2ctl” を用いてコントロールファイルを作成し、gribmapでインデックスファイルを作成することによりGrADSでGRIBデータを読み込むことができる。
  • 公式チュートリアル(英文)
  • 【参考】東北大学大学院気象学・大気力学分野が公開されている 「GrADSのTips
  • 【参考】筑波大学生命環境系の釜江陽一氏が公開されている 「GrADS-Note

GrADS用バイナリファイルmodel.datを読む

GrADSのチュートリアルに用いられる”model.dat”を読む。

$ grads Grid Analysis and Display System (GrADS) Version 2.2.1 Copyright (C) 1988-2018 by George Mason University GrADS comes with ABSOLUTELY NO WARRANTY See file COPYRIGHT for more information Config: v2.2.1 little-endian readline grib2 netcdf hdf4-sds hdf5 opendap-grids,stn geotiff shapefile Issue 'q config' and 'q gxconfig' commands for more detailed configuration information Landscape mode? ('n' for portrait): GX Package Initialization: Size = 11 8.5 ga-> open model.ctl Scanning description file: model.ctl Data file model.dat is open as file 1 LON set to 0 360 LAT set to -90 90 LEV set to 1000 1000 Time values set: 1987:1:2:0 1987:1:2:0 E set to 1 1 # ファイルの中味を確認。 ga -> q file 1 File 1 : 5 Days of Sample Model Output Descriptor: model.ctl Binary: model.dat Type = Gridded Xsize = 72 Ysize = 46 Zsize = 7 Tsize = 5 Esize = 1 # 経度方向に72格子、緯度方向に46格子、鉛直方向に7層、 # 時間方向に5個のタイムステップ、アンサンブル数は1。 Number of Variables = 8 ps 0 99 Surface Pressure u 7 99 U Winds v 7 99 V Winds hgt 7 99 Geopotential Heights tair 7 99 Air Temperature q 5 99 Specific Humidity tsfc 0 99 Surface Temperature p 0 99 Precipitation # 変数が8個。一番左が変数名。変数名のすぐ右が鉛直の層数。 # 層数”0”は地表面1層だけであることを示す。 # u / v / hgt / tairは層数が7で、qは5層だけデータがある。 # その右の”99”はここではダミー。 # その右が変数の説明となっている。 # 次元を確認 ga -> q dims Default file number is: 1 X is varying Lon = 0 to 360 X = 1 to 73 Y is varying Lat = -90 to 90 Y = 1 to 46 Z is fixed Lev = 1000 Z = 1 T is fixed Time = 00Z02JAN1987 T = 1 E is fixed Ens = 1 E = 1 # 1000hPaの気温の空間分布を描く。実際には黒い背景に図が描かれる。 # set background 1 とすると背景を白くすることもできる。 ga-> d tair Contouring: 245 to 300 interval 5

図10. 1000hPaの気温の空間分布

ga -> c # 100hPaの気温の空間分布を描く。 ga -> set lev 100 ga -> d tair

図11. 100hPaの気温の空間分布

ga -> c # 気温の鉛直断面を描く。 ga -> set lon 180 LON set to 180 180 ga -> set z 1 7 LEV set to 1000 100 ga -> d tair

図12. 気温の鉛直断面

NetCDF形式のSSTデータを読む

NetCDF形式のERSSTデータの2000年1月の分布図を描画する。

$ grads Grid Analysis and Display System (GrADS) Version 2.2.1 Copyright (C) 1988-2018 by George Mason University GrADS comes with ABSOLUTELY NO WARRANTY See file COPYRIGHT for more information Config: v2.2.1 little-endian readline grib2 netcdf hdf4-sds hdf5 opendap-grids,stn geotiff shapefile Issue 'q config' and 'q gxconfig' commands for more detailed configuration information Landscape mode? ('n' for portrait): GX Package Initialization: Size = 11 8.5 ga-> sdfopen sst.mnmean.nc Scanning self-describing file: sst.mnmean.nc SDF file sst.mnmean.nc is open as file 1 LON set to 0 360 LAT set to -88 88 LEV set to 0 0 Time values set: 1854:1:1:0 1854:1:1:0 E set to 1 1 ga-> set time 1jan2000 Time values set: 2000:1:1:0 2000:1:1:0 ga-> d sst Contouring: -0 to 30 interval 3

図13. 2000年1月の海面水温分布図

GRIB1形式のJRA-55データをGrADSで読む

“anl_surf125.202201”というファイルの中味を確認する。
まず、wgrib用のパラメータテーブルの環境変数GRIBTABをエクスポートする。

$ export GRIBTAB=./JRA55_anl_surf_ptable_wgrib.txt

wgribを用いてファイルの一番初めのデータの情報を得る.オプションの”-d 1”は最初のデータという意味。

$ wgrib -V -d 1 anl_surf125.202201 rec 1:0:date 2022010100 pres kpds5=1 kpds6=1 kpds7=0 levels=(0,0) grid=255 sfc anl:ave@6hr: pres="surface pressure [Pa]" timerange 123 P1 0 P2 6 TimeU 1 nx 288 ny 145 GDS grid 0 num_in_ave 124 missing 0 center 34 subcenter 241 process 201 Table 200 scan: WE:NS winds(N/S) latlon: lat 90.000000 to -90.000000 by 1.250000 nxny 41760 long 0.000000 to -1.250000 by 1.250000, (288 x 145) scan 0 mode 128 bdsgrid 1 min/max data 51808.9 102921 num bits 12 BDS_Ref 518.089 DecScale -2 BinScale -3

ファイルに格納されている最初のデータは気圧”pres”であり、気象庁の番号表”Table 200”を使用し、 緯度・経度の範囲と格子数、データの最小値と最大値、圧縮に関する情報が表示される。

次に、grib2ctl.plを用いてコントロールファイルを作成する。grib2ctl.plも環境変数GRIBTABを参照する。

$ grib2ctl.pl anl_surf125.202201 > anl_surf125.202201.ctl

作成されたコントロールファイルの中味は以下のようになっている。

dset ^./anl_surf125.202201 index ^./anl_surf125.202201.idx undef 9.999E+20 title ./anl_surf125.202201 * produced by grib2ctl v0.9.15 * command line options: ./anl_surf125.202201 dtype grib 255 options yrev ydef 145 linear -90.000000 1.25 xdef 288 linear 0.000000 1.250000 tdef 1 linear 00Z01jan2022 1mo zdef 1 linear 1 1 vars 9 airt2m 0 11,105,2 ** 2 m above ground "air temperature [K]" depr2m 0 18,105,2 ** 2 m above ground "dewpoint depression [K]" mslmsl 0 2,102,0 ** mean-sea level "mean sea level pressure [Pa]" pottsfc 0 13,1,0 ** surface "potential temperature [K]" pressfc 0 1,1,0 ** surface "surface pressure [Pa]" rhum2m 0 52,105,2 ** 2 m above ground "relative humidity [%]" sphum2m 0 51,105,2 ** 2 m above ground "speciphic humidity [kg/kg]" uwnd10m 0 33,105,10 ** 10 m above ground "eastward wind [m/s]" vwnd10m 0 34,105,10 ** 10 m above ground "northward wind [m/s]" ENDVARS

“pressfc”の行をみると、変数名の右の最初の数字は鉛直の層数を示すが、ここでは”0”になっている。 これはanl_surf125が地表面という1層だけのデータなのでこのようになっている。
その右の”1,1,0”はwgribの結果のkpds5 / kpds6 / kpds7にあたる。 kpds5が変数の数字符号であり、kpds6は鉛直層の種類、kpds7は鉛直層の高度を表している。

gribmapを用いてインデックスファイルを作成する。

$ gribmap -i anl_surf125.202201.ctl gribmap: opening GRIB file anl_surf125.202201 gribmap: reached end of files gribmap: writing the GRIB1 index file (version 5) $ ls anl_surf125.202201 anl_surf125.202201.ctl anl_surf125.202201.idx $ grads ga-> open anl_surf125.202201.ctl Scanning description file: anl_surf125.202201.ctl Data file ./anl_surf125.202201 is open as file 1 LON set to 0 360 LAT set to -90 90 LEV set to 1 1 Time values set: 2022:1:1:0 2022:1:1:0 E set to 1 1 # 海面更正気圧を描く ga -> d mslmsl

図14. 海面更正気圧の空間分布

NCL

  • 米国NCARで開発された“NCAR Command Language”
  • Fortranに似たスクリプト言語である。ただし、次元の並びはC言語と同じである。Fortranでa(lon,lat,lev,time)とした場合、NCLではa(time,lev,lat,lon)となる。
  • NCLをインストールすると多くのスクリプトが利用可能である。また既存のFortranで書かれたサブルーチンをWRAPITすることにより、NCLで利用することができる。
  • 大量の解析や作図の事例集が公開されている。
  • GrADSに比べるとnetCDF/GRIB/HDF等のファイルの取り扱いに制限が少ない。
  • 【参考】東京大学先端科学技術研究センターの関澤氏が公開されている「NCL tips

NetCDFファイルの読み方

$ conda activate ncl_stable $ ncl # ERSSTデータを読み込む準備。 ncl 0> fin = addfile("sst.mnmean.nc","r") # 時刻データを読み込む。 ncl 1> time = fin->time ncl 2> printVarSummary(time) Variable: time Type: double Total Size: 16208 bytes 2026 values Number of Dimensions: 1 Dimensions and sizes: [time | 2026] Coordinates: time: [19723..81357] Number Of Attributes: 8 units : days since 1800-1-1 00:00:00 long_name : Time delta_t : 0000-01-00 00:00:00 avg_period : 0000-01-00 00:00:00 prev_avg_period : 0000-00-07 00:00:00 standard_name : time axis : T actual_range : ( 19723, 81357 ) # cd_calendar()を用いてYYYYMMのフォーマットで時刻を確認。 ncl 3> print(cd_calendar(time,-1)) Variable: unnamed (return) Type: integer Total Size: 8104 bytes 2026 values Number of Dimensions: 1 Dimensions and sizes: [2026] Coordinates: Number Of Attributes: 1 calendar : standard (0) 185401 (1) 185402 (2) 185403 (3) 185404 (4) 185405 (5) 185406 (6) 185407 (7) 185408 (8) 185409 (9) 185410 (10) 185411 (11) 185412 (12) 185501 <<以下省略>> # 1854年1月から毎月の時刻が格納されている。 # 1855年1月のSST(インデックス=12が1855年01月)を読み込む ncl 6> sst = fin->sst(12,:,:) ncl 7> printVarSummary(sst) Variable: sst Type: float Total Size: 64080 bytes 16020 values Number of Dimensions: 2 Dimensions and sizes: [lat | 89] x [lon | 180] Coordinates: lat: [88..-88] lon: [ 0..358] Number Of Attributes: 12 time : 20088 long_name : Monthly Means of Sea Surface Temperature units : degC var_desc : Sea Surface Temperature level_desc : Surface statistic : Mean missing_value : -9.96921e+36 dataset : NOAA Extended Reconstructed SST V5 parent_stat : Individual Values actual_range : ( -1.8, 42.32636 ) valid_range : ( -1.8, 45 ) _FillValue : -9.96921e+36 # ある月だけのデータを読み込んだため、sst の次元は [lat | 89] x [lon | 180] の # 2次元になっている。このデータの空間分布図を作成してみる。 ncl 8> wks = gsn_open_wks("x11","test") ncl 9> plot = gsn_csm_contour_map(wks, sst, False) ncl 10> quit $ conda deactivate

図15. ERSSTの1855年1月の海面水温分布図

左上の変数名はsstの属性”long_name”が反映されており、右上の単位はsstの属性”units”が反映されている。

JRA-55の読み方

パラメータテーブルを作成し、環境変数NCL_GRIB_PTABLE_PATHをエクスポートする。

$ less JRA55_anl_surf_ptable_ncl.txt -1:34:241:200 1 : pres : Pa : surface pressure 2 : msl : Pa : mean sea level pressure 11 : airt : K : air temperature 13 : pott : K : potential temperature 18 : depr : K : dewpoint depression 51 : sphum : kg/kg : speciphic humidity 52 : rhum : % : relative humidity 33 : uwnd : m/s : eastward wind 34 : vwnd : m/s : northward wind $ export NCL_GRIB_PTABLE_PATH=./JRA55_anl_surf_ptable_ncl.txt

condaの仮想環境”ncl_stable”をアクティベートする。

$ conda activate ncl_stable $ ncl Copyright (C) 1995-2019 - All Rights Reserved University Corporation for Atmospheric Research NCAR Command Language Version 6.6.2 The use of this software is governed by a License Agreement. See http://www.ncl.ucar.edu/ for more details. ncl 0> fin = addfile(“anl_surf125.202201”,”r”)

“.grib”と拡張子が付けられている場合はGRIBと判断すると公式webサイトに記述があるが、“.grib”という拡張子なしでも読めている。 しかし、確実にGRIBとしてファイルを読むためには

ln -s anl_surf125.202201 anl_surf125.202201.grib

として、シンボリックリンクを張ればよい。

# ファイルに格納されている変数等の情報を確認する。 ncl 1> print(fin) Variable: fin Type: file filename: anl_surf125.202201 path: anl_surf125.202201 file global attributes: dimensions: g0_lat_0 = 145 g0_lon_1 = 288 variables: float pres_GDS0_SFC_S123 ( g0_lat_0, g0_lon_1 ) sub_center : 241 center : Japanese Meteorological Agency - Tokyo (RSMC) long_name : surface pressure units : Pa _FillValue : 1e+20 level_indicator : 1 gds_grid_type : 0 parameter_table_version : 200 parameter_number : 1 forecast_time : 0 forecast_time_units : hours initial_time : 01/01/2022 (00:00) statistical_process_descriptor : average of N uninitialized analyses statistical_process_duration : instantaneous (beginning at reference time at intervals of 6 hours) N : 124 float msl_GDS0_MSL_S123 ( g0_lat_0, g0_lon_1 ) sub_center : 241 << 以下省略 >> # 気圧のデータを読み込む。 ncl 2> pres = fin->pres_GDS0_SFC_S123 # 読み込んだ気圧の情報を確認する。 ncl 3> printVarSummary(pres) Variable: pres Type: float Total Size: 167040 bytes 41760 values Number of Dimensions: 2 Dimensions and sizes: [g0_lat_0 | 145] x [g0_lon_1 | 288] Coordinates: g0_lat_0: [90..-90] g0_lon_1: [ 0..358.75] Number Of Attributes: 15 sub_center : 241 center : Japanese Meteorological Agency - Tokyo (RSMC) long_name : surface pressure units : Pa _FillValue : 1e+20 level_indicator : 1 gds_grid_type : 0 parameter_table_version : 200 parameter_number : 1 forecast_time : 0 forecast_time_units : hours initial_time : 01/01/2022 (00:00) statistical_process_descriptor : average of N uninitialized analyses statistical_process_duration : instantaneous (beginning at reference time at intervals of 6 hours) N : 124 ncl 4> quit $ conda deactivate

GrADS形式バイナリファイルの読み方

$ ncl # GrADSのチュートリアルに使われるサンプルデータを読んでみる。 # model.dat は little endian で書き出されているので、オプションを設定する。 ncl 0> setfileoption("bin","ReadByteOrder","LittleEndian") # 経度方向に72格子、緯度方向に46格子なので、次元の大きさを指定する。 ncl 1> dims = (/46,72/) # 最初のデータ(インデックス=0)を読み込むため nrec を指定する。 ncl 2> nrec = 0 # 最初のデータを読み込む。 ncl 3> x = fbindirread("model.dat", nrec, dims, "float") # xがどのようなものか確認。 ncl 4> printVarSummary(x) Variable: x Type: float Total Size: 13248 bytes 3312 values Number of Dimensions: 2 Dimensions and sizes: [46] x [72] Coordinates: # “Coordinates”がないので、緯度・経度を作成して付与する。 # model.ctlの記述からlat/lonを作成する。 ncl 5> lat=-90.0+ispan(0,45,1)*4.0 ncl 6> lat!0 = "lat" ncl 7> lat&lat = lat ncl 8> lat@units = "degrees_north" ncl 9> lon = 0.0 + ispan(0,71,1)*5.0 ncl 10> lon!0 = "lon" ncl 11> lon&lon = lon ncl 12> lon@units = "degrees_east" # 作成した緯度・経度をxに付与する。 ncl 13> x!0 = "lat" ncl 14> x!1 = "lon" ncl 15> x&lat = lat ncl 16> x&lon = lon # model.datの最初のデータは地上気圧なので、long_name、units、_FillValue、 # missing_valueをmodel.ctlを見ながら付与する。 ncl 17> x@long_name = "Surface Pressure" ncl 18> x@units = "hPa" ncl 19> x@_FillValue = -2.56E33 ncl 20> x@missing_value = -2.56E33 # 変数xの情報を確認する。 ncl 21> printVarSummary(x) Variable: x Type: float Total Size: 13248 bytes 3312 values Number of Dimensions: 2 Dimensions and sizes: [lat | 46] x [lon | 72] Coordinates: lat: [-90..90] lon: [ 0..355] Number Of Attributes: 4 missing_value : -2.56e+33 _FillValue : -2.56e+33 units : hPa long_name : Surface Pressure ncl 22> wks = gsn_open_wks("x11","test") ncl 23> plot = gsn_csm_contour_map(wks, x, False) ncl 24> quit

図16. model.datの地上気圧データ

地上気圧の空間分布が描かれた。左上の”Surface Pressure”は気圧の属性x@long_name、右上の”hPa”は気圧の属性x@unitsが反映されている。

d4PDF_RCMの可視化

d4PDF_RCMのtopo_essp20.datを用意する。NCLを用いてtopo_essp20.datをNetCDF形式に変換する。topo_essp20.datはFortranでsequential accessで出力されているので、スクリプトの中でfbinrecreadを用いる。“;”以降はコメント。

$ less proc01.ncl begin nameIn="topo_essp20.dat" setfileoption("bin","ReadByteOrder","BigEndian") dims = (/155,191/) lat2d = fbinrecread(nameIn,0,dims,"float") lon2d = fbinrecread(nameIn,1,dims,"float") alt = fbinrecread(nameIn,2,dims,"float") land = fbinrecread(nameIn,3,dims,"float") lat = ispan(0,154,1)*0.1 ;; 仮の緯度。ダミー lat!0 = "lat" lat&lat = lat lat@units = "degrees_north" lon = ispan(0,190,1)*0.1 ;; 仮の経度。ダミー lon!0 = "lon" lon&lon = lon lon@units = "degrees_east" lat2d!0 = "lat" lat2d!1 = "lon" lat2d&lat = lat lat2d&lon = lon lat2d@units = "degrees_north" lat2d@long_name = "latitude" lon2d!0 = "lat" lon2d!1 = "lon" lon2d&lat = lat lon2d&lon = lon lon2d@units = "degrees_east" lon2d@long_name = "longitude" alt!0 = "lat" alt!1 = "lon" alt&lat = lat alt&lon = lon alt@units = "m" alt@long_name = "surface elevation" land!0 = "lat" land!1 = "lon" land&lat = lat land&lon = lon land@units = "none" land@long_name = "land sea fraction" fout = addfile("topo_essp20.nc","c") fAtt = True fAtt@title = "d4PDF_RCM. Topography, Lans-sea fraction, latitude, longitude data" fAtt@source_file = "topo_essp20.dat / topo_essp20.ctl" fAtt@Conventions = "None" fileattdef( fout, fAtt ) fout->alt = alt fout->land = land fout->lat2d = lat2d fout->lon2d = lon2d end $ ncl ./proc01.ncl $ ncdump -h topo_essp20.nc netcdf topo_essp20 { dimensions: lat = 155 ; lon = 191 ; variables: float alt(lat, lon) ; alt:long_name = "surface elevation" ; alt:units = "m" ; float lat(lat) ; lat:units = "degrees_north" ; float lon(lon) ; lon:units = "degrees_east" ; float land(lat, lon) ; land:long_name = "land sea fraction" ; land:units = "none" ; float lat2d(lat, lon) ; lat2d:long_name = "latitude" ; lat2d:units = "degrees_north" ; float lon2d(lat, lon) ; lon2d:long_name = "longitude" ; lon2d:units = "degrees_east" ; // global attributes: :Conventions = "None" ; :source_file = "topo_essp20.dat / topo_essp20.ctl" ; :title = "d4PDF_RCM. Topography, Lans-sea fraction, latitude, longitude data" ; } # 変数lat2dは各格子の緯度の値を保持し、変数lon2dは各格子の経度の値を保持している。 $ ncview topo_essp20.nc

図17. d4PDF_RCMの標高分布

図中の白い線は、緯度・経度がダミーなため描かれてしまったものなので無視すること。

surf_HPB_m001_200001.gribから気温のデータを1タイムステップだけ切り出す。

$ wgrib surf_HPB_m001_200001.grib -d 11 -grib -o test.1.grib 11:474510:d=00010101:TMP:kpds5=11:kpds6=1:kpds7=0:TR=0:P1=0:P2=0:TimeU=2:sfc:anl:NAve=0

NCLを用いた可視化ではtopo_essp20.ncに格納されているlon2dとlat2dを読み込み、作図したい変数の属性として付与する必要がある。
なお、NCL のスクリプト内部では“;”以降はコメントである。

$ less mkfig1.ncl begin fin1 = addfile("test.1.grib","r") ;; airt = fin1->TMP_GDS0_SFC ;;気温データを読み込む fin2 = addfile("topo_essp20.nc","r") lat2d = fin2->lat2d ;; 緯度情報のデータを読み込む lon2d = fin2->lon2d ;; 経度情報のデータを読み込む ;; airtの属性としてlat2d/lon2dを付与する。 airt@lat2d = lat2d airt@lon2d = lon2d wks = gsn_open_wks("x11","fig1") res = True res@gsnMaximize = True res@mpLambertParallel1F = 30.0 ;; ランベルト正角円錐図法の基準緯度1 res@mpLambertParalle12F = 60.0 ;; ランベルト正角円錐図法の基準緯度2 res@mpLambertMeridianF = 135.0 ;; ランベルト正角円錐図法の基準経度 res@mpLimitMode = "Corners" res@mpLeftCornerLatF = 15.0 res@mpLeftCornerLonF = 105.0 res@mpRightCornerLatF = 52.0 res@mpRightCornerLonF = 165.0 res@mpDataBaseVersion = "MediumRes" res@pmTickMarkDisplayMode = "Always" res@cnFillOn = True res@cnLinesOn = False plot = gsn_csm_contour_map(wks, airt, res) end $ $ ncl ./mkfig1.ncl

図18. NCLでd4PDF_RCMの気温分布を描画

NCLを用いたd4PDF_RCMのデータ処理では、

  • x方向191格子、y方向に155格子の単純なマトリックス(配列)としてデータを見て、同一格子上での変数間の四則演算や、時間方向の処理を行う。ただし緯度や経度を考慮しなくてもよい処理のみ。
  • 空間的な処理を行う(例えば緯度や経度を考慮すべき処理や内挿処理)、または可視化するときには、topo_esssp20.datに格納されている緯度と経度の情報を読み込んで処理をする。

という手順が現実的である。

ところで、GrADSを用いたd4PDF_RCMの可視化はd4PDF_RCMの一部として配布しているコントロールファイルを用いれば簡単にできる。

$ less surf_HPB_m001_200001.ctl ***output grads ctl file for surf*** dset surf_HPB_m001_200001.grib index surf_HPB_m001_200001.idx pdef 191 155 LCCR 35 135 97 77 30 60 135 20000 20000 dtype grib 255 undef -9.9999e+20 <<以下省略>>

GrADSの場合はコントロールファイルのpdefの行が重要である。 この行の意味は、x方向に191格子、y方向に155格子、ランベルト正角円錐図法で風の成分の方向転換済み(LCCR)、 データのある一点の緯度・経度(35N,135E)と対応する格子のインデックス番号(97,77)、 投影法の基準緯度二つ(30N, 60N)、投影法の基準経度(135E)、格子のx方向の間隔(20000m)、 格子のy方向の間隔(20000m)となっている。 GrADSはこの情報を利用して、データを地図上に描いてゆく。

現実的には解析担当者が意識をせず、通常通りにコントロールファイルを開いて、’d tmp’とすれば可視化が実行される。

ga -> open surf_HPB_m001_200001.ctl <<以下省略>> ga -> d tmp

図19. GrADSでd4PDF_RCMの気温分布を描画

【参考】Python

Python言語は、習得することはそれほど難しくないとされる言語である。 まずは、numpy、scipy、pandas、matplotlibの使い方を覚えると良い。 そしてPythonは、急速に様々なパッケージ(ライブラリ)開発が進んでいる言語であるため、 あるパッケージがほかのどのパッケージに依存しているのかなど、自分で調査して試してみる必要がある。 なにか問題が生じた場合、パッケージがGitHubを使用しているのならばissueは要チェックであり、stackoverflowでの投稿などを検索することも必要となる。 そして情報の多くは英語であるため、気候データ処理の初心者がPythonを使用することは少しハードルが高いかもしれない。 だが、今後は気候学のデータ処理の中心はPythonに移行することは明確なので (米国UCAR/NCARが今後はNCLの開発は停止して、PythonのライブラリGeoCATの整備に注力することを宣言済み)、 頑張って使い方を覚えると、先々良いことがあると思われる。

  • netcdf4-python
    NetCDFライブラリを作成したUnidata作成のNetCDF読み書き用パッケージ。
  • Iris
    英国気象局などが開発中の気候データ読み書き・作図パッケージ。
  • xarray
    現在活発に開発が続いている多次元データを取り扱うパッケージ。
  • PyNIO/PyNGL
    UCARで開発されていたNetCDF等の読み書きパッケージとNCLから移植した作図パッケージ。 UCARでは新たなPythonをベースとしたパッケージ群を開発中で、その一部が GeoCATである。
  • 【参考】国立環境研究所の山下氏が公開されている
    気象データ解析のためのmatplotlibの使い方」。

【参考】統計解析向けのプログラミング言語:R言語

R言語には地理情報関係のパッケージ群が存在する。 それらのパッケージ群を使用して観測地点に最も近い領域気候モデルのグリッドポイントを検索する例を示す。

図20. Rstudioの画面

  • 左上のペインはスクリプトファイルの編集画面になっている。
  • 左下のペインはRのコマンドを実行するコンソール画面となっている。
  • 右上のペインは変数やオブジェクトの情報や、コンソールで実行したコマンドの履歴などの情報が得られるようになっている。
  • 右下のペインは作成した図を表示する画面やパッケージの管理画面にもなっている。

今回紹介する例の実行に必要なパッケージを、左下のコンソールで"install.packages()"関数を用いてインストールする。 例えば"ncdf4"をインストールするには、以下のようにする。

> install.packages(“ncdf4”)

インストールするパッケージ:

パッケージ 内容
readr ファイルを読むためのパッケージ
dplyr データフレームを処理するためのパッケージ
ggplot2 作図に用いるパッケージ
ncdf4 NetCDFを読み書きするためのパッケージ
sf 地理情報関係のパッケージ
geosphere 球面上の距離や角度を計算するパッケージ
rnaturalearth 地図データのパッケージ
rnaturalearthdata 地図データのパッケージ
SearchTrees ツリー構造のデータの検索パッケージ

国内のラジオゾンデ観測地点の地点番号、緯度、経度、標高、地点名のリストを用意する。 なお、緯度・経度は度と分に分かれている。

$ less ./stn_list.2.txt 47401 45 24.9 141 40.7 12 Wakkanai 47412 43 03.6 141 19.7 17 Sapporo 47580 40 42.0 141 22.0 39 Misawa 47582 39 43.1 140 06.0 6 Akita 47600 37 23.5 136 53.7 5 Wajima 47646 36 03.5 140 07.5 25 Tateno 47681 34 45 137 42 47 Hamamatsu 47778 33 27.1 135 45.7 73 Shionomisaki 47807 33 35.0 130 23.0 12 Fukuoka 47827 31 33.3 130 32.9 31 Kagoshima 47918 24 20.2 124 09.8 6 Ishigakijima

以下のスクリプトを適当な名前を付けて保存する。ただし、”#”で始まる行は除く。
なおこのスクリプトはtidyverseな仕様なので “%>%” というあまり見慣れない演算子があらわれるが、そのまま打ち込むこと。

library(SearchTrees) library(ncdf4) library(sf) library(geosphere) library(rnaturalearth) library(rnaturalearthdata) library(ggplot2) library(readr) library(dplyr) rm(list=ls()) nameSTN <- "./stn_list.2.txt" stndf <- read_table(nameSTN, col_types = "cnnnnnc", col_names = c("StnIdx","latD","latM","lonD","lonM", "height","StnName")) # 緯度・経度を度分から度に直して、mutateする。 # sfオブジェクトにする際に緯度・経度が別に必要となるので、mutateする。 stndf <- stndf %>% mutate(lon = lonD + lonM / 60.0, lat = latD + latM / 60.0) %>% mutate(lonX = lon, latY = lat) # sfオブジェクトに変換する。それぞれのデータ(行)にgeometryが付加される。 # また日本測地系2000における地理座標系(JGD2000, EPSG=4612)を利用する。 stndf2<- st_as_sf(stndf, coords = c("lonX", "latY"), crs = 4612) # 領域気候モデルd4PDF_RCMの緯度と経度のデータを読む。 nameTopo <- "./topo_essp20.nc" ncin <- nc_open(nameTopo) lat <- ncvar_get(ncin, "lat2d") lon <- ncvar_get(ncin, "lon2d") # 2次元データであるlat / lon をベクトルに変換する。 lonX <- as.vector(lon) latY <- as.vector(lat) # モデルのx方向とy方向の格子数から各格子の格子番号を作成する。 nlat <- 155 nlon <- 191 ii <- seq(1, nlon, 1) jj <- seq(1, nlat, 1) ij <- as.matrix(expand.grid(ii, jj)) # モデルの格子情報をデータフレームにする。 tmp_df <- data.frame(cbind(ij, lonX, latY, lonX, latY)) colnames(tmp_df) <- c("ii","jj","lon","lat","lonX","latY") # 以下のようなデータフレームを作った。 # ii jj lon lat lonX latY # 1 1 1 117.5693 19.67914 117.5693 19.67914 # 2 2 1 117.7452 19.71560 117.7452 19.71560 # 3 3 1 117.9214 19.75170 117.9214 19.75170 # sfオブジェクトに変換する。sfオブジェクトに変換するとplot()が利用できる。 griddf<- st_as_sf(tmp_df, coords = c("lonX", "latY"), crs = 4612) # griddf は以下のような構造。 # 各行(=各格子点)にgeometryが付加された。 # Simple feature collection with 6 features and 4 fields # Geometry type: POINT # Dimension: XY # Bounding box: xmin: 117.5693 ymin: 19.67914 xmax: 118.4508 ymax: 19.85786 # Geodetic CRS: JGD2000 # ii jj lon lat geometry # 1 1 1 117.5693 19.67914 POINT (117.5693 19.67914) # 2 2 1 117.7452 19.71560 POINT (117.7452 19.7156) # 3 3 1 117.9214 19.75170 POINT (117.9214 19.7517) # griddfをプロット。 plot(griddf) # スクリプトは後に続く

図21. griddfの表示

x方向のインデックスiiも、y方向のインデックスjjもカーブをもった分布をしている。 一方で経度lonは縦方向で、緯度latは横方向できれいにそろっている。 つまり正しくデータがsfオブジェクトに格納されたことを意味している。

スクリプトの続き。

# 各格子点の緯度・経度の値からツリー構造のデータを作成する。 # なおこの時点では、座標系などを考慮しない単なる数字の羅列になってしまう。 tree <- createTree( st_coordinates( griddf ) ) # 各ラジオゾンデ観測地点の緯度・経度を “newx” / “newy” に代入して、 # 一番近い格子点を探す(k=1)。 # ”inds”には格子点のインデックス(griddfの行番号)が返される。 # 行番号とはgriddfの構造を見たときの一番左側の数字のこと。 inds <- knnLookup( tree, newx = stndf2$lon, newy = stndf2$lat, k = 1 ) # 各ラジオゾンデ観測地点にもっとも近いモデル格子点の情報をデータフレームにする。 x <- griddf[inds,]$lon y <- griddf[inds,]$lat ii2 <- griddf[inds,]$ii jj2 <- griddf[inds,]$jj dfOut <- data.frame(StnIdx=stndf$StnIdx, ii=ii2, jj=jj2, lon=x, lat=y) # 得られた結果を csv ファイルに保存する。 write.csv(dfOut, "./nhrcm_raob.csv", row.names = FALSE) # 出力は以下の様な形をしている。ii はx方向の格子番号、jjはy方向の格子番号 # "StnIdx","ii","jj","lon","lat" # "47401",122,134,141.635116577148,45.3641014099121 # "47412",122,122,141.3818359375,43.1371574401855 # 検索したグリッドがラジオゾンデ観測地点に本当に近いのか図にして確認。 gridpoint <- st_as_sf(data.frame(lon=x, lat=y), coords=c("lon","lat"), crs = 4612) world <- ne_countries(scale = 'medium', returnclass = 'sf') plt1 <- ggplot() + geom_sf(data = world) + geom_sf(data = gridpoint, shape = 16, size = 4, color = "red") + coord_sf(xlim = c(123,146), ylim = c(24,46)) + theme_bw() plot(plt1)

図22. ラジオゾンデ観測点に最も近いグリッドの分布図

  • 47401(稚内)の経度は141.6783、緯度は45.415なので、観測点ともっとも近いモデルのグリッドは、経度方向で0.043度、緯度方向で0.05度離れている。 例えば geosphere::distVincentySphere() で距離を計算すると約6.6km離れている。
  • knnLookup()で”k=3”とすると、観測点近傍の3グリッドの情報が返ってくる。 この情報を利用し、geosphereの距離計算関数を用いて観測点と気候モデルのグリッドの距離を比較して、計算結果が正しいのかを確認してもよい。
  • 稚内にもっとも近いグリッドのデータをd4PDF_RCMのファイルから取り出すには、x方向のインデックスii、y方向のインデックスjjである位置にある値を選択すればよい。
  • なお、気候モデルは地球を楕円体として取り扱っていないので、あまり厳密な比較は避けるべきである。