地上気象観測は、気象観測の中でも歴史が長く、古くから世界各地で実施されている。昔訊いた話では、SYNOP と呼ばれる形式により電文が GTS に手打ちで送信されるなどしていたそうだ。最近では自動化が進み、電文が管轄する気象官署等で集約された上で自動で一定時刻に流通するようだ (例: 地上気象観測; AMeDAS)。地上観測では、ある地点の時系列データが得られる。
データの形式については、複数地点を集約した離散的なデータとなるためひと工夫必要となる。気象レーダー・ライダーの観測値や数値予報モデルなどは格子点データなので GRIB 形式で格納される場合が多い。一方、地上観測データの場合は離散的な地点データとなるため、主に格子点データを扱う GRIB 形式ではデータを格納しづらくなる。このような非格子点形式のデータを表現するために BUFR 形式が採用されている。気象庁では、地上観測データ (気象庁内外含む) は本庁で集約・品質管理され、気象庁HPや気象業務支援センターで公開される。気象庁HPでは csv フォーマットで任意の日時・要素のデータが取得可能になっており、とても便利になった。こちらについては特に言及しない。他方、気象業務支援センターで公開されているデータは、前述の BUFR 形式であり実際に扱ってみるとなかなか苦労した。本稿は BUFR 形式データをデコードし、そのデータを用いて地理空間分布を描くところまでの備忘録である。
気象業務支援センターでは、実際に配信されたデータによるサンプル提供のページでサンプルデータが公開されている。この中から地域気象観測報を選びダウンロードする。圧縮ファイルを展開すると2020年02月13日 15:10 UTC ~ 2020年02月14日 15:00 UTC のデータが入っている。この中から、下記のデータを例にデコードしてみる。
OBS_AMDSxx_Rjp_Nx/AMDS/Z__C_RJTD_20200214000000_OBS_AMDS_Rjp_N2_bufr4.bin
気象業務支援センターから得たサンプルデータは、BUFR version 4 形式となっている。気象業務支援センターのページに配信資料に関する技術資料 (気象編) 第273号という資料があり、これを参照しながらデコードする。もっと詳しい資料として、国際気象通報式・別冊というものがあり、これも読解に役立つ。
BUFR データのデコードは幾つかのやり方があるようだ。 ecCodes、NCEPLIBS-bufr、LibECBUFR、bufrconv、PyBufrKit等が見つかった。今回は C 言語で扱いたかったので LibECBUFR にお世話になった。LibECBUFR のコンパイル・インストールについてはこちらを、下記で利用するサンプルプログラム等はこちらをそれぞれ参照されたし。
LibECBUFR のインストールが出来ていることを前提に話を進める。LibECBUFR は、Table ファイルを参照しながらデコードするようなプログラム構成になっている。気象庁が配信する BUFR 報は、独自 Table でデータが格納されているため LibECBUFR のデフォルトのままではデコード出来ない。そこで、前述の配信資料に関する技術資料を見ながら Table に要素を追記し、その Table ファイルを読ませてデコードするという流れとなる。LibECBUFR には bufr_decoder
というユーティリティプログラムが同梱されているので、これを使いながら修正箇所を特定しつつデコードしてみる。
LibECBUFR に Table ファイルが同梱されているので、まずはこれを使ってみる。Table は、table_b_bufr
と table_d_bufr
の 2 種類。環境変数 BUFR_TABLES
で Table ファイルの場所を指定する。データは先程のサンプルデータを引数で下記のように与えてみる。
BUFR_TABLES=./Tables ./bufr_decoder -inbufr Z__C_RJTD_20200214000000_OBS_AMDS_Rjp_N2_bufr4.bin -debug
すると、下記のような標準出力とファイル (DEBUG.decoder
) が吐き出される。
標準出力
### BUFR Edition : 4
### length : 167201
### Section 0
### length : 8
### Section 1
### length : 22
### BUFR master table : 0
### originating center : 34
### sub center : 0
### update sequence number : 0
### Data category : 0
### International sub category : 255
### Local sub category : 255
### master table version : 13
### local table version : 1
### Year : 2020
### Month : 2
### Day : 14
### Hour : 0
### Min : 0
### Sec : 0
### octet 8 : 0
### optional section : No
### Section 2
### length : 0
### Section 3
### length : 207
### datasubsets : 1298
### octet 7 : 128
### compression : No
### observed data
### Section 4
### length : 166960
### Section 5
### length : 4
###
Error: can't decode messages
DEBUG.decoder
(長いので要所のみ)
### Converting BUFR Message into Dataset
Warning: master Table B version: 35 differs from message's: 13
Warning: Unknown BUFR descriptor: 25219
Warning: 25219 is a local descriptor
Error: unknown descriptor 25219
どうやら、Table ファイルに未定義の descriptor があるようだ。そこで、DEBUG.decoder
でエラーになっている番号とフォーマットの番号とを比較しながら table_b_bufr
に追記する。集約演算子がある場合は、table_d_bufr
にも追記が必要となる (今回は必要なかった)。最終的にファイルが読めるようになった Table はここから取得出来る。
修正した Table ファイルを読み込ませると、下記のように出力される (一部のみ)。
コマンド
BUFR_TABLES=./Tables ./bufr_decoder -inbufr Z__C_RJTD_20200214000000_OBS_AMDS_Rjp_N2_bufr4.bin
標準出力
### BUFR Edition : 4
### length : 167201
### Section 0
### length : 8
### Section 1
### length : 22
### BUFR master table : 0
### originating center : 34
### sub center : 0
### update sequence number : 0
### Data category : 0
### International sub category : 255
### Local sub category : 255
### master table version : 13
### local table version : 1
### Year : 2020
### Month : 2
### Day : 14
### Hour : 0
### Min : 0
### Sec : 0
### octet 8 : 0
### optional section : No
### Section 2
### length : 0
### Section 3
### length : 207
### datasubsets : 1298
### octet 7 : 128
### compression : No
### observed data
### Section 4
### length : 166960
### Section 5
### length : 4
###
## Subset 1 : 132 descriptors
001202 INSTUTUTION NUMBER CODE TABLE 1
001200 PREFECTURE DISPLAY NUMBER NUMERIC 11
001201 POINT DISPLAY NUMBER NUMERIC 1
002001 TYPE OF STATION CODE TABLE 0
# 301011
004001 YEAR YEAR 2020
004002 MONTH MONTH 2
004003 DAY DAY 14
# 301012
004004 HOUR HOUR 0
004005 MINUTE MINUTES 0
# 301021
005001 LATITUDE(HIGH ACCURACY) DEGREE 45.52111
006001 LONGITUDE (HIGH ACCURACY) DEGREE 141.93611
007030 HEIGHT OF STATION GROUND ABV MSL M 26.0
001197 OBS REPORT TYPE CODE TABLE 1
... (以下略) ...
これで Table の準備が出来、BUFR データが読めるようになった。同梱されている他のプログラムも、この Table を用いれば利用可能となる。
次に、出力する要素を絞り、それらに緯度経度座標値を付加し、地理空間分布を描画してみる。その際、品質管理情報(AQC)を取得しておき、異常データを出来る限り省いた状態で出力してみる。LibECBUFR に同梱されているサンプルプログラムを改修し、こちらのようなプログラムを書いた。コンパイルし、Table ファイルを用意した上で引数に BUFR ファイルを指定すると、出力ファイルに緯度・経度・前10分間雨量・前10分間雨量 AQC 情報・前60分間雨量・前60分間雨量 AQC 情報をそれぞれ 1 地点 1 行で表示する。
コマンド
BUFR_TABLES=. ./decode_bufr_sample Z__C_RJTD_20200214000000_OBS_AMDS_Rjp_N2_bufr4.bin
出力ファイル OUTPUT.txt
(一部のみ表示)
45.521111 141.936111 0.000000 0 0.000000 0
45.415279 141.678604 0.000000 0 0.000000 0
45.305279 141.045837 0.000000 0 0.000000 0
... (中略) ...
24.396391 124.245003 0.000000 0 0.000000 0
24.264999 123.872223 0.000000 0 0.000000 0
24.055559 123.768059 0.000000 0 0.000000 0
ようやく BUFR 形式のデータが読めるようになったので、可視化してみる。
元のデータは丸印で色分け、nearest neighbor 法で水平内挿したものを陰影でそれぞれ示している。このときは、九州南部から四国南西部にかけて数 mm 〜 10 mm 程度の降水があったようだ。
地上のデータはすぐ手が届きそうな場所にあるようで、扱おうとするとなかなか遠い道のりだった。でも、これで地上観測データも Table さえ用意すれば読めるようになったので百人力である。今回は C 言語で LibECBUFR を利用した AMeDAS BUFR 報のデコードから可視化までを扱った。
Miscellaneous — Aug 16, 2021
Made with ❤ and at Japan.