netCDFとは
- netCDF とは UCAR Unidata によって開発された多次元配列データ向きのデータ形式です。公式サイトは https://www.unidata.ucar.edu/software/netcdf/ です。
- Unidata はデータフォーマットを公開しつつ、C および Java で書かれたアクセスライブラリをオープンソースで提供しています。C インターフェイスの上に Fortran や C++ バインディングがあるはず。
- netCDF と、それ以前のたとえば WMO GRIB (以前 概説 書きました)のようなデータ形式と比べての最大の革新は、netCDF はデータの表現に特化していることです。
- ここでデータの表現とは、整数や浮動小数点数の配列などという数値的構造をどうファイルで表現するか、です。通信でいえばレプレゼンテーション層にあたるものです。
- この革新は、半構造データに XML や JSON がもたらした革新とだいたい同じものです。
- 応用分野に依存した記載、たとえば経緯度や物理量の種類はどうやって記述するのかというようなことは、利用者が合意した規約 conventions で決めるということになっています。
- ソフトウェアはすべて上下のレイヤの間に定義されるという見方をするならば、netCDF の上位レイヤから見えるのはデータモデルだけであって、他次元変数や属性などのデータ構造に対する操作をnetCDFの言語APIを通じて発注すると、具体のバイト列として表現するやりかたを考えてくれて、下位レイヤ(通常はPOSIXファイル)に対してAPI呼び出し(つまりread(2)やwrite(2))を発行して実現してくれるわけです。
- netCDF バージョン3以前はファイル形式を Unidata で定義していたのですが、netCDF バージョン4以降は、物理的な表現に HDF を選択できるようになりました。申し訳ないですが HDF については詳しくありません。
ソフトウェアツールの全体像については Unidata netCDF Users' Guide の図 https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_architecture.png をご覧ください。
netCDF のデータモデル
皆さんが UML にお詳しければ、Unidata のドキュメントのデータモデルのところ、[the Classic Model の節]の図(https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_data_model.html#classic_model) をご覧ください。
いやまあ僕は正直 UML 見ろっていわれても頭に入らないので書き下しておきます。
- 図の一番上、ファイル File が管理対象で一番大きな構造です。
- これは通常はひとつの POSIX ファイルです。
- 下位ライブラリに pnetcdf を選んだ場合には File は MPI2ファイルAPIの管理する、ノード間に分散した何かファイルらしきものです。
- 下位ライブラリで opendap を選んだ場合には File はネットワークの向こうの OPeNDAP サーバ上の何かファイルらしきものです。
- ファイルには任意個の次元 Dimension を設けることができます。
- 次元には名前が必要です。ファイル内で同じ名前の次元を複数設けることはできません。
- 次元には長さがあります。数学でいう次元とは違います。
- 次元の長さは無制限 unlimited にすることができます。無制限でも「現時点での長さ」はあるので、無制限というよりは延長可能と訳したほうがいいかもしれません。長さ無制限の次元は1ファイルに1つしか作ることができません。
- ファイルには任意個の変数 Variable を設けることができます。
- 変数には名前が必要です。ファイル内で同じ名前の変数を複数設けることはできません。
- 些事:変数と次元の名前空間は別ですが、混乱するような使い方は規約レベルで抑制されます。
- 変数は任意個の次元を持たねばなりません。ゼロ個も許されます。複数の変数の次元セットが共通な場合は、格子配置が共通だということがすぐにわかります。
- 変数にはデータ型があります。型は char, byte, short, int, float, double があります。型のビット数は ILP32 モデルの C コンパイラと同じで、整数型はすべて符号付です。byte は char と同じ挙動ですが、整数値と文字で使い分けることが前提になっています。
- 変数には名前が必要です。ファイル内で同じ名前の変数を複数設けることはできません。
- 属性 attribute というメタデータ領域があります。
- ファイルには任意個の属性を設けることができます。ファイル内で同じ名前の属性を複数設けることはできません。
- 変数にも任意個の属性を設けることができます。変数について同じ名前の属性を複数設けることはできません。
- 属性にも変数と同じ型が選べます。
- 属性は1次元配列です。char型の配列は文字列とみなされます。
このデータモデルに、netCDFバージョン4からは様々な拡張がされましたが、さしあたって特に重要なのは、グループ Group という機能で、ファイル内にあたかもディレクトリのように階層的に任意個のグループを設け要ることができて、その中に次元や変数を置くことができます。しかしその拡張を使うためには netCDF v4 以降の API を用いて HDF ファイル形式に保存する必要があります。
いずれにしても、上記データモデルに地球だとか気圧だとかいった気象海洋分野に固有の概念は一切現れないことに注目してください。それはXMLやJSONのデータ構造に分野固有の概念が一切現れないことと同じわけです。そのレイヤ分離が情報技術の文明開化です。
netCDF 規約
データファイルが表現しようとする時空間や、変数が表わす物理量が何かなど、気象海洋の分野に固有の諸概念は、変数名、次元名、属性名をうまく使って表現する規約 conventions をユーザ間で合意しろと Unidata は言っています。あたかもXMLやJSONを使って(木構造が得意だけれど理論上は)あらゆる種類のデータが表現できるように、netCDFも利用者次第で(数値配列が得意だけれど理論上は)どんな種類のデータでも表現できるのです。
そうは言ってもいくつかの属性値についてはnetCDF界全体で共通に使ってほしい勧告があり、NetCDF Users' Guide Appendix A にあります。
そのうえで、規約は勝手に作ればよいのではありますが、届出制になっていて、以下にまとめられています。
https://www.unidata.ucar.edu/software/netcdf/conventions.html
CF 規約
そのなかで特に重要なものが、CF (Climate and Forecast) 規約で、ドキュメントが http://cfconventions.org/ にあります。最新バージョンは 1.7 ですが、バージョン 1.4 を日本語訳してありますので、よろしかったらどうぞ。
さいきん開発中の v1.8 ドラフトでは、長年 classic data model にこだわっていたのをついに放棄して、グループ機能の利用が盛り込まれるんだそうです。このへんもちゃんとレビューしなくちゃいかんのですが、だれかやってくれませんかね…
(2022-02-18追記)