Takashi Unuma's blog.

地上観測データの把握

はじめに

地上気象観測は、気象観測の中でも歴史が長く、古くから世界各地で実施されている。昔訊いた話では、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 データのデコードは幾つかのやり方があるようだ。 ecCodesNCEPLIBS-bufrLibECBUFRbufrconvPyBufrKit等が見つかった。今回は C 言語で扱いたかったので LibECBUFR にお世話になった。LibECBUFR のコンパイル・インストールについてはこちらを、下記で利用するサンプルプログラム等はこちらをそれぞれ参照されたし。

方針

LibECBUFR のインストールが出来ていることを前提に話を進める。LibECBUFR は、Table ファイルを参照しながらデコードするようなプログラム構成になっている。気象庁が配信する BUFR 報は、独自 Table でデータが格納されているため LibECBUFR のデフォルトのままではデコード出来ない。そこで、前述の配信資料に関する技術資料を見ながら Table に要素を追記し、その Table ファイルを読ませてデコードするという流れとなる。LibECBUFR には bufr_decoder というユーティリティプログラムが同梱されているので、これを使いながら修正箇所を特定しつつデコードしてみる。

デコード

LibECBUFR に Table ファイルが同梱されているので、まずはこれを使ってみる。Table は、table_b_bufrtable_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 報のデコードから可視化までを扱った。

更新履歴

  • 2021-08-16: 初稿
  • 2021-08-19: サンプルプログラム等置き場所を GitLab の snippets に変更
  • 2021-08-22: 誤字脱字を修正

— Aug 16, 2021