Skip to content

Latest commit

 

History

History
339 lines (286 loc) · 19.4 KB

BUFR.md

File metadata and controls

339 lines (286 loc) · 19.4 KB

BUFRとは

BUFR とは、WMO(世界気象機関)がGTS(全球気象通信網)での国際データ交換に用いるために開発したデータ形式(通報式)のひとつです。 現在 WMO は通報式を GRIB と BUFR に集約する方針ですが、 格子データに特化したGRIBになじまないような時空間構造を持つデータ、 強いて今風に言うならば半構造データを表現するために、BUFR は用いられます。

BUFR は Binary Universal Form for the Representation of meteorological data の略で、データ構造を問わないという意図を表現した名前です。

そもそも BUFR は 1980 年代、テレタイプ専用線から X.25(TCP/IPに敗れ去った技術) によるデジタル通信に置き換わりようやく可能になったバイナリ伝送を活用するために 開発され、最初のエディションは1989年制定され、 1990 年代には電文長がテキスト電文より圧縮できることが利点と宣伝され、 なのでそういう作りこみが増やされ、 2000 年代に入ると普及が進まないのは受信利用ソフトウェアの複雑性のためと 認識されテンプレート(後述)のような方向に転換し、 そうは言っても各国大規模システム更新は長い年数の周期です。 普及はまあ時折という感じで、 2014年11月に通報実態はさておいて文字形式の通報を WMO GTS 計画としては 廃止するといういささか強引な手段に出たところです。 次第に普及が進むと思いますが、そもそも何のためにと言われても 今は亡き X.25 とか出てきて困ってしまいますが、まあ、 パソコン買い換えるようにはいかないライフサイクルの長い仕事なんです。

以下、一般的な解説に交えて本 bufrconv パッケージの説明をしているところには 米印(※)を付します。

BUFR の節構造

長さ/オクテット 必須 説明
0 8 必須 マジックナンバー "BUFR"、電文長、版edition番号
1 17以上(第3版), 22以上(第4版) 必須 識別節 identification section
2 可変 任意 任意節 optional section (有無は次表参照)
3 可変 必須 資料記述節 data description section (データ構造記述)
4 可変 必須 資料節 data section (データ本体)
5 4 必須 マジックナンバー "7777"

BUFR に従うデータ表現は BUFR 報 (BUFR message) と呼ばれます。 データサンプルなどでは単独の BUFR 報("BUFR" から "7777" まで一組)を 独のファイルに保存することもありますが、たいていの実務においては WMO バッチ FTP 形式などなんらかの形式 (気象庁内でもシステム毎に 異なる) のファイルに多数の BUFR 報が格納されます。

第0節の電文長と第1~4節の冒頭3オクテットは、ビッグエンディアンの整数値で オクテット数を指示します。データファイルからマジックナンバー "BUFR" を 探索するだけでは他のテキストなどと偶然一致してしまうことが あるかもしれませんが、第1節から順に節の長さを追って "7777" が見つかる ならば、正当な BUFR 報の構造と言えるでしょう。

※ bufrscan.rb では特定のファイル形式を仮定せず、マジックナンバー "BUFR" を探索して節構造を検証することで BUFR 報を漏れなく 探すようにしています。

BUFR第1節 (識別節) の構造

※略称 第3版 第4版 説明
0-2 0-2 節の長さ
:mastab 3 3 マスター表番号(つまり分野番号)
:ctr 5 4-5 作成中枢番号
:subctr 4 6-7 作成副中枢番号(作成中枢で管理)
:upd 6 8 更新一連番号
7 9 MSBが立っていたら第2節が存在する
:cat 8 10 カテゴリ番号
:subcat 11 サブカテゴリ番号(国際管理)
:subcat 9 サブカテゴリ番号(作成中枢で管理)
12 サブカテゴリ番号(作成中枢で管理)
:masver 10 13 マスター表のバージョン番号
:locver 11 14 ローカル表のバージョン番号
:reftime 15-16 参照日時(年)
12 参照日時(年の下2桁)
13 17 参照日時(月)
14 18 参照日時(日)
15 19 参照日時(時)
16 20 参照日時(分)
21 参照日時(秒)

※ bufrscan.rb 内の Bufrdcd#[] にこの略称を与えると解読結果が返ります。

BUFR 第1節はオクテット単位の構造をもち、 どんな通報にも共通のメタデータが入っています。

  • 誰が作ったか(:ctr, :subctr)
  • データの日時(:reftime)
  • データ種別(:cat, :subcat)
  • 更新一連番号 = 訂正数(:upd)
  • データ本体解読用の表のバージョン情報(:masver, :locver)

若干おせっかいな説明:

  • マスター表番号(分野番号)(:mastab)は 0: 気象分野 (WMO管理) 10: 海洋分野(UNESCO/IOC管理) というように管理主体ごとに名前空間を分けられるように設計されたものですが、 実際問題 0 以外見たことがありません。
  • 作成中枢番号(:ctr)は GRIB と共通です。 http://codes.wmo.int/common/_centre 第4版では名前空間が 8 ビットから 16 ビットに拡張されましたが、 256 以上の値が活用されている例は知りません。
  • マスター表のバージョン番号(:masver)は 14以上と 13 の区別だけ気を付けましょう。 同じ記述子(後述)でもビット幅が異なるなど酷い非互換性があります。 バージョン13からバージョン14への改正で大混乱を起こして反省して、 上位互換の改正しか行われなくなったので、 14以上の版数は全部最新版 http://codes.wmo.int/bufr4/b とみなしてOKです。 バージョン12以前にはさらに非互換性があるのですが、 さいわいリアルタイム通報ではもう見かけません。
  • 参照日時 reference time (:reftime)は データの種類により色々の使われ方をしています。 データ本体の日時の最初を取るものもあれば、切り上げているものもあり。 実務上、2000年問題がめんどくさいです。 BUFR第3版では常に年に 2000 を加算しなければなりませんし、 BUFR第4版ですら16ビットの年数欄に年の下二桁が書かれていることがあります。
  • 更新一連番号(:upd)は、デフォルトで0、 同一地点、同一時刻、同一種類の観測で訂正を打つときに1つづつ増やして 発信します。 まあ実際には GTSヘッダが CCA なのにサボって 0 になっていることもありますし、 GTS ヘッダで CCA を付けそこなっていることもありますから、 実務上は後手必勝ルールみたいなものが求められます。 実際に後発が正しいかどうかは知りませんけど、何かに決めなきゃ仕事にならん。

もうちょっと評論家的なことをいうと、第1節に記載される情報は、 「データ種別、データの日時、訂正数」としてみると GTS 電文ヘッダ https://qiita.com/e_toyoda/items/9893b4386084528f2af5#%E3%83%98%E3%83%83%E3%83%80%E3%81%AE%E6%A7%8B%E9%80%A0 とほぼ同じ情報です。 1980 年代の設計当初何を考えていたのかわかりませんが、 伝送路が GTS から電文ヘッダを用いないものに変わっても、 リアルタイム通報受信処理が影響を受けないで維持できるようになっています。

カテゴリ番号・サブカテゴリ番号の表(抜粋)

最新版は通報式の共通符号表 C-13 です。

BUFR 第3版では国際共通サブカテゴリ欄がなく、 発信中枢管理のサブカテゴリを付けることになっていたので、 必ずしも下表にはよりません。

:cat カテゴリ :subcat サブカテゴリ
0 陸上地表 0 固定地点地上観測(毎時)(SYNOP)
0 陸上地表 1 固定地点地上観測(中間時)(SYNOP)
0 陸上地表 2 固定地点地上観測(主要時)(SYNOP)
0 陸上地表 3 移動地上観測(毎時)(SYNOP MOBIL)
0 陸上地表 4 移動地上観測(中間時)(SYNOP MOBIL)
0 陸上地表 5 移動地上観測(主要時)(SYNOP MOBIL)
0 陸上地表 7 地上自動観測(分単位)
0 陸上地表 50 固定地点地上観測(毎時)過去1時間の補助データつき(SYNOP)
0 陸上地表 51 固定地点地上観測(中間時)過去1時間の補助データつき(SYNOP)
0 陸上地表 52 固定地点地上観測(主要時)過去1時間の補助データつき(SYNOP)
1 海上海表 0 船舶観測 (SHIP)
1 海上海表 25 ブイ観測 (BUOY)
2 鉛直サウンディング 1 固定地点高層風観測 (PILOT)
2 鉛直サウンディング 2 船上高層風観測 (PILOT SHIP)
2 鉛直サウンディング 3 移動高層風観測 (PILOT MOBIL)
2 鉛直サウンディング 4 固定地点ラジオゾンデ観測 (TEMP)
2 鉛直サウンディング 5 船上ラジオゾンデ観測 (TEMP SHIP)
2 鉛直サウンディング 6 移動ラジオゾンデ観測 (TEMP MOBIL)
2 鉛直サウンディング 10 ウィンドプロファイラ観測
2 鉛直サウンディング 20 航空機観測 (AMDAR)
6 レーダー 1 ドップラーウィンドプロファイラ

BUFR第3節 (資料記述節)

ここまでは GRIB 並みにわかりやすいんだ。地獄はここからだ

オクテット位置 説明
0-2 節の長さ
3 保留
4-5 データサブセットの数 n
6 フラグ: 0x80=観測資料、0x40=圧縮
7‐ 記述子列(1つあたり2オクテット)
末尾 BUFR第3版では各節の長さが偶数でなければならなかったので埋め草が1オクテット置かれていた
  • BUFR第3節は、BUFR第4節の書かれるデータ本体の構造を、各16ビットの記述子descriptorの羅列で記述します。
  • 記述子のうちもっとも基礎的な要素記述子 element descriptorは、 それぞれ次表のようにビット幅をもったデータを記述します。 記述子の順にビット列を切り出せば値が得られます。
  • もっと嫌らしい記述子もあるのですが後述。
  • データサブセットが2以上なら、記述子列をその数だけ適用します。 複数地点の観測を1つのBUFR報に格納する場合などに使います。
  • 第3節フラグで 0x40 ビットが立っていると、圧縮というもので、 データ構造が変わります。後述。

記述子の概説

記述子はひとつ16ビットですが、先頭(先のオクテットのMSB側)2ビット、中位6ビット、ついで末尾8ビットの3つの整数に分解してそれぞれ F, X, Y と呼びます。

要素記述子の例

F=0 な記述子を要素記述子といい、次のような表で定められるデータを表わします。

F X Y 意味 単位 尺度 参照値 ビット数
0 01 001 WMO ブロック番号 無名数 0 0 7
0 01 002 WMO 地点番号 無名数 0 0 10
0 01 015 地点名 文字列 0 0 160
0 02 002 風速観測方法 フラグ表 0 0 4
0 04 001 0 0 12
0 04 002 0 0 4
0 04 003 0 0 6
0 04 004 0 0 5
0 04 005 0 0 6
0 04 006 0 0 6
0 04 014 時間変位 0 -1024 11
0 05 001 緯度(高精度) 5 -90 00000 25
0 06 001 経度(高精度) 5 -180 00000 26
0 11 001 風向 度(真方位) 0 0 9
0 11 002 風速 m/s 1 0 12
0 12 004 気温・乾球温度 K 1 0 12
0 20 003 現在天気 符号表 0 0 9
0 31 000 遅延反復の反復数 0 0 1
0 31 001 遅延反復の反復数 0 0 8
0 31 002 遅延反復の反復数 0 0 16
  • 最新バージョンの表は http://codes.wmo.int/bufr4/_b にあります。 X の値 (0~63, クラスという) にしたがって分類されています。
  • 単位欄が「文字列」(通報式文書上は CCITT IA5 となっています)、 「符号表」「フラグ表」となっている場合は、ビット列を素直に解釈すればいいです。 それ以外の単位の場合は数値データで、ビット列を整数とし、 参照値を加算してから 10^(-尺度) を乗じたものが値です。 たとえば 0 12 004 気温の尺度1とは 0.1 K 単位で通報が行われていることを示し、 0 05 001 緯度の尺度5とは 0.00001 度単位で通報が行われていることを示します。
  • 数値データの場合、ビット列がすべて立っていると欠損値になります。
  • 文字列の欠損値も、規則上はビット列をすべて立てろということになっているの ですが、これは混乱のあとでできた規則で励行されておらず、 実際には全部ビットが寝ていたり SPC が並んでいる場合もあります。
  • 符号表やフラグ表についても、ほとんどの場合、全ビットが立つと欠損になるよう 設計されていますが一部例外もあります。
  • クラス 0~8 の要素は、座標記述子と呼ばれ、 時系列や観測地点などのメタデータを与えます。 このメタデータが後続のデータを修飾するのです。 なので、地点番号・日時・緯度経度などの座標記述子が先に並んで、 風・気温などの要素記述子が後に並びます。
  • この座標の修飾関係を機械的に解決したくなりますね。やめときましょう。 0 04 014 時間変位のように名前に displacement とついているものは、 先の同クラスの座標値を変位させます。 さらに名前に increment とついているものは 複数回適用で累積します(近年は見ませんが)。 また同一座標記述子が連続で出現した場合には範囲を表わし、 たぶんこれら規則で年月日時分秒は一体とみなされますが、 何が一体視されるべきかについては明確ではありません。 実はもっと複雑な規則がありますが、 コーディングできるに足る明確な仕様はありません。
  • 上述のようにバージョン13の表はビット幅など諸元が異なり 用心しなければいけません。
  • もうひとつ、Y >= 192 は国際共通のマスター表では保留になっており、 そこは作成中枢がローカル表というもので埋めてよいことになっています。 この要素をローカル記述子 local descriptor と言いますが、 これでは幅がわからなくて困るんで後述します。

反復記述子

F=1 な記述子は反復記述子 replication descriptor と呼ばれ、 後続する X 個の記述子が Y 回反復されることを示します。 「雲向が最大3個報じられる」というような場合に使います。 まあ shorthand ですね。

さらに、Y=0 なる反復記述子は遅延反復記述子 delayed replication descriptor と呼ばれ、必ずクラス31の要素記述子が後続しなければなりません。 反復回数は、BUFR第4節のデータ内から読み出されます。 幅 8 ビットの 0 31 001 や幅 16 ビットの 0 31 002 が用意されており、 高層観測の鉛直層数など、あらかじめ定めがたい場合に使われます。 まあ必要性はわからなくもない。

なお、反復対象記述子数 X にはこのクラス31の要素記述子は数えませんが、 反復の中に反復がある場合は内側のクラス31の要素記述子は数えます (なんという規則でしょう)。

ところで反復数 0 31 000 は幅が1ビットしかありません。 つまり反復数 0 または 1 です(クラス31は例外的に全ビットが立っても欠損ではありません)。 つまり必要がない場合にはデータ列をまるっとなくしてしまい、 電文長を短くできるという目的で使われます。 正しくプログラムできるならいいのですが、 このへんで壊れて解読できないデータを寄越してくる国が でてきます。やめてほしいです。

操作記述子

F=2 な記述子は操作記述子 operation descriptor とか operator と呼ばれ、 後続する要素記述子のビット幅を臨時変更したり、いろいろな特殊加工をします。

ローカル記述子を国際配信する場合には、 2 06 YYY を前置して、 その幅を YYY として記載することで幅が分かるようにします。

集約記述子

F=3 な記述子は集約記述子 sequence descriptor と呼ばれ、 他の記述子列の代わりに用いられます。 このご利益は BUFR第3節 が短くできるということです。

たとえば 3 01 001 は 0 01 001, 0 01 002 すなわち WMO 地点番号に展開されます。

反復の中に集約がある場合は反復対象の記述子数は集約の展開前に数えます。

集約記述子はさらに集約記述子を含む記述子列に展開され得て、 非常に長い展開結果になる集約記述子も作られています。

とくに2000年代に入ってからは記述子列を標準化しないと解読が困難だということが 認識され、テンプレートと呼んで標準化が進みました。 たとえば

標準化されたテンプレートは WMO のサイトにあります。 https://www.wmo.int/pages/prog/www/WMOCodes/WMO306_vI2/TemplateExamples.html (このサイトも近く移転するらしいので後で要フォロー)

テンプレートはどうしても最小公倍数的になりますので、 電文長が短くなることが BUFR の利点という宣伝文句は放棄されました。 高層観測ではジオポテンシャル高度の上位桁が暗黙でなくなるとか、 そもそも電文に年月や地点経緯度がないなどの問題が解消するなど、 データ品質・データ管理上の利点を地味ですが評価していくしかありません。

BUFR第4節の構造

オクテット位置 説明
0-2 節の長さ
3 保留
4‐ ビット列
末尾 BUFR第3版では各節の長さが偶数でなければならなかったので埋め草が1オクテット置かれうる

圧縮形式

非圧縮の電文では、 記述子列に従ったBUFR 第4節のビット列の切り出しはサブセット数だけ 反復されます。

これに対し、圧縮形式の場合、要素記述子ごとにサブセット数個の値が BUFR 第4節のビット列から切り出されます。 この値が連長圧縮されていて、さらに電文を小さくできます。

なお、遅延反復を圧縮する場合、 反復数はすべてのサブセットについて同一数でなければなりません。 意味が分からなくなるからです。