GDT netCDF 規約 version 1.3

−気象データのための統一netCDF規約−

原文(英語):Jonathan Gregory1, Bob Drach2 and Simon Tett1
(1) Hadley Centre, UK Met Office; (2) PCMDI, LLNL
14th March 1999

日本語訳:安形康(東京大学生産技術研究所)

プログラマよALMAをめざせ


0  目次


1  目的

GDTは,netCDFで作られたファイルの交換・共有を促進するために作られた標準規格です.これはnetCDF2.4(http://www.unidata.ucar.edu/packages/netcdf/)に準拠しています.ちなみに「GDT」とは,作者らの名前の頭文字に由来しています.

GDTは,気候データを扱うことを主眼として作成されました.もともとは,とりわけGCMが出力するデータを念頭において策定されたものです.この種の規約というのは,どうしてもある程度の限界があることに鑑み,私たちは気候のメタデータの設計において一般的でかつしばしば用いられると思われる部分についてのみ規約を策定することにしました.GDT自体はnetCDFに立脚したものですが,その考え方はおそらく他のファイルフォーマットにおいても適用可能であると思います.さて,GDTを策定した目的ですが,それは,「気候データに求められる,明確かつ十分で,フレキシブルなメタデータ定義を提示すること」です.メタデータオブジェクト自体はnetCDFでない形式で格納されるかもしれません.しかし,あるファイル形式から他のファイル形式へのコンバートは,それが同じようなGDT的アイデアに基づく限り,容易でしょう.

GDTは,ほとんどCOARDSがスポンサーとなった規約(ftp://ftp.unidata.ucar.edu/pub/netcdf/Conventions/COARDS)に対する追加です.さらに,特に断りのない限りはUNIDATA(訳注:netCDF開発元)の推奨をサポートしています.標準と異なる部分についてはコメントを付してそれがわかるようにしています.つまり,文中のnon-standardという字体やコード例の

	non-standard

といった表記は,それらが標準規約にのっとっていないことを表しています.なお,CDLなどのコード例は,該当するセクションで議論されている部分について詳しく表示をしていますが,必ずしも必要となるコード全体を書いているのではない場合があります.つまりこういうコードはそれ自体では完全ではありません.ご注意ください.

データの受け渡しがうまくいくには,相手方がそのデータを正しく扱えることが必要です.したがって,アトリビュートやエンコードの拡張使用に当たっては可能な限り慎重・保守的になるという戦略が,結局はデータのポータビリティを高めることになります.

GDTはまた,UNIDATAがサポートして作られたudunits標準をベースにしています.udinitsパッケージはanonymous ftp(ftp.unidata.ucar.edu)経由で取得できます(訳注:WWWサイトはhttp://www.unidata.ucar.edu/packages/udunits/index.html).このパッケージがGDTの物理量単位制定にどのように使われたかという詳細は,セクション11を参照してください.

GDTの策定は, Karl Taylor, John Sheldon, Jan Polcher, Bryant McAvaney, Harvey Davies, John Caron, Steve Hankin各氏から頂いた有意義なコメントと,netCDF ニュースグループ参加者各位の寄与に大いに支えられました.NCAR CSM netCDF標準とかなりの部分で互換性を持てるようにGDTを変更しました.


2  ファイル名

netCDFファイルは,ファイル名拡張子が.ncになるようにしてください.


3  データタイプ

 netCDFのデータタイプ(char, short, long, float, double)は全て使用可能です.また,すべて符号付(signed)とします.ただし,byte型の使用はお勧めできません.これは,netCDF内でこの型がsignedかunsignedかについては決められていないからです.COARDS規約ではbyteでなくむしろchar型の使用に異を唱えています

netCDFは(訳注:変数の値としては)文字列型をサポートしていません.それらはchar型数値の配列で表現する必要があります.ただしGDTでは,こういう形式の変数をstring型として表記します.string型の配列は,2次元のchar型配列として扱います.それぞれの文字列は固定長となり,CDL上での2番目の添え字(Fortranでは最初の添え字となります)が文字列の数を表すことになります.


4  アトリビュート

GDTではたくさんのアトリビュートを指定しています.その中には必須のものもオプショナルなものもあります.が,ファイル自体にはそれ以外の(標準でない)アトリビュートを自由につけることができます.そのようなアトリビュートをつけても,標準の侵害とはなりません.そのファイルを読む方のプログラムでは,理解できないかあるいは道理に合わないアトリビュートは無視するようにしてください.

規約で定められているアトリビュートについては,その指定アトリビュート名を必ず使用するようにしてください.また,規約外のアトリビュートについても,できるだけ内容がよく分かるような名前を付けてください.

アトリビュートを導入するに当たっては,そのアトリビュートの含む情報が,もしかしたら別個の変数として与えられた方がよりよいのではないかという可能性をよく考慮してください.一般的には,そのアトリビュート(案)が

にはアトリビュートとしてではなく変数として表現した方がよいでしょう.

この規約では,決められた文字列のうちどれかを指定することになる文字列アトリビュートに関しては,その選択肢を小文字で示すことにします.ただし,プログラムではアトリビュートの大文字小文字は区別しない(not case sensitive)で下さい.

また,「blank-separated list」で与えられると指定したアトリビュートもあります.このようなアトリビュートの扱いは,その単語リストを連続した空白で分けられたいくつかの単語に分割して扱うことになります.リストの最初と最後には任意個のスペースが入っても構いません(訳注:空白がなくてもよいかどうかは確認中).GDTで定められているアトリビュートの表については,Appendix Aを参照してください.


5  グローバルアトリビュート

この標準,つまりGDT1.3に準拠したファイルには,UNIDATA標準のtext型アトリビュートであるConventionsを定義し,値GDT 1.3を与えてください.GDTはUNIDATAのftp(ftp://ftp.unidata.ucar.edu/pub/netcdf/Conventions)上でGDTという名前で登録されており,また,http://www-pcmdi.llnl.gov/drach/GDT_convention.htmlないしhttp://www-pcmdi.llnl.gov/drach/GDT_convention.htmlで詳細を知ることができます.

つぎに,float型アトリビュートappendicesも指定することを推奨します.これはそのファイルを作ったプログラムが使用した(GDTの)appendicesのバージョン番号です.(セクション12参照).この情報はもしかしたらConventionsに含まれるかもしれません.しかしこのように別にアトリビュートを持つことにより,アプリケーション側で文字列(訳注:Conventionsの内容)をパースする必要がなくなります

text型アトリビュートquantity_tableに,使用したquantity tableのURLを書き込みます(セクション12参照). もしこのアトリビュートが空文字列の場合,appendicesで指定したバージョンのAppendix Dが用いられたと仮定します.

text型アトリビュートcommentも指定可能です.これは,ファイルに関するその他の追加情報を書き込みます.例えば,GCM出力にはmodel integration情報を入れるといった具合です.

これは必須ではありませんが,UNIDATA標準のアトリビュートであるhistoryの使用も推奨します.これはnetCDFファイル中にあるデータの,それまでの変更記録が含まれます.netCDFを取り扱い,改変するプログラムはこのアトリビュートに自らの足跡を記すことができます.なお,ここではグローバルアトリビュートとしてのhistoryを紹介しましたが,これは全ての変数に共通したヒストリを書き込むものです.一方,各変数に関しても同様にhistoryアトリビュートを指定することができ,それぞれの変数固有の変更記録や固有の情報を格納できます(セクション12参照).

text型アトリビュートinstitutionおよびproductionも推奨します.前者は,データの作成者・配布者を表します.なお,centerないしcentreという名前よりもこちらのほうがいいと思います.というのは,centercentreという二通りの書き方があって混乱するからです.後者は,データ作成方法を表示します.たとえば,そのデータが何らかのモデルによって作られたものなら,データの使用に役立つようにできるだけ詳しくモデルの名前とバージョンが入るでしょう.一方,観測データならば,前者はたとえばSurface observationradiosondeといった値になるでしょう.これらのグローバルアトリビュートは,同様のアトリビュートを持たないすべての変数について適用されるとみなされます(セクション12参照).

calendarアトリビュート(セクション23参照)もグローバルアトリビュートとして指定することができます.このアトリビュートは,全ての時間軸についてのデフォルトとみなされます.


6  変数の名前

変数名はアルファベットで始まり,アルファベット・数字・アンダースコアで構成されます.大文字小文字は区別されますが,大文字小文字だけで変数名を分ける(訳注:tempTempの同時使用など)のはやめたほうがいいでしょう.万一大文字小文字が同一視された場合,混乱が生じるからです.

また,可能ならば変数名は変数の意味がはっきりわかるようにつけるべきです.そうすると,そのファイルを読む人にとってnetCDFはより自己記述的になります.ただし,GDTそれ自体は変数名は特に指定しませんし,特定の変数名に依拠した標準は策定していません.


7  データ変数

物理量を格納するnetCDF変数を,ここでは「データ変数」と呼ぶことにします.これはUNIDATAが「primary variables」と呼んでいるものと同じです.

これらの変数の名前ですが,一般的なルール(上記セクション6参照)のほかには,GDT自体では規約は定めていません(それは,一般的には,同じ物理量に対して複数の変数を格納する場合があるからです).


8  座標変数

一つあるいは複数のデータ変数に関して,その次元を表す1次元変数のことを「座標変数」と呼ぶことにします.また,この規約では,必要ならば座標変数のうちその次元名が変数名と同じものを特に「主座標変数」と呼ぶことにします(セクション17, セクション18,セクション19,セクション20参照).

これらの変数の名前ですが,一般的なルール(上記セクション6参照)のほかには,GDT自体では規約は定めていません(それは,一般的には,同じ方向の軸を表す次元に対して複数の座標変数を格納する場合があるからです).主座標変数の値は厳密に単調増加ないし単調減少でなければなりません(厳密に,とは同じ値が複数あってはならないということです).これはそう仮定するプログラムが非常に多いためです


9  データ変数の軸と次元

データ変数は任意のランクの次元を取ることができます.0次元というのも可能です.そして,各次元はすべて違う名前を取らねばなりません.COARDSでは次元数を4以下にすることを強く推奨していますが,私たちはむしろより柔軟性が高いほうを望むのです

データ変数の次元は,それが含む値の軸を規定します.それらは,時間軸・空間軸以外の軸も含んでかまいません.その例はこのドキュメント内で何回か出てきます.ベクトルあるいはテンソルもまた,次元を指定することにより一つのデータ変数に押し込むことができます.ただ,そのような変数を扱うことにはいささかの利点もあるものの,netCDFにそういった複雑さを持ち込むことはそれほど有益なこととは思えません.ですからあまり推奨はしません.ある種の状況下では,一つの量に対して複数の次元が必要になるかもしれません(セクション28−多重時間軸−参照).たとえば,2次元確率密度関数を格納するデータ変数においては,2つの異なるレベルでの温度の相関を取り,したがって両方の軸に関する温度を持つ,といった場合があります.

データ変数の次元のうち,全部または一部が「時刻(T)」,「高さまたは深さ(Z)」,「緯度(Y)」,「経度(X)」のいずれかの意味を持つ物であった場合,それらの次元は,対応するCDL文中ではT, Z, Y, Xの順に並ぶように定義されている必要があります. (Fortranの場合は,配列添え字の順番はこの逆となります.たとえば,X軸が入っている場合,その軸に対応する添え字は配列の最初の添え字となります.)これらの時空間軸以外の次元については,時空間軸より左(訳注:CDLで言うと前)におかれる必要があります.(Fortranでは,時空間軸を表す添え字のあとに,これらの軸の添え字が続きます)

このように定めた理由は,これらの時空間軸は特定のアプリケーションにとっては特別な意味を持つ場合があるからです.たとえば,緯度−経度マップを描く・垂直積分する・時系列をextractする…といった具合です.COARDS標準では,次元の順番の指定と座標変数のアトリビュート内にある情報の両方によって,必要な軸がどれか指示する必要がありました.この標準との互換性を保つために,GDTでもCOARDS標準もすべてサポートしますが,それとは別に,下記に示すもう一つのアトリビュートを導入して,どの座標変数がどの軸に対応するか,簡潔かつ明確に示すようにしました.

あるデータ変数について,もし最後の4つの次元がTZYXの意味のものでない場合(次元数が4以下の場合はそれに対応してTZYXの数を減らして調査する),axisアトリビュートを指定する必要があります.そうでない場合はこのアトリビュートはオプショナルですが,しかしその場合でもやはりこのアトリビュートをつけることを推奨します.このアトリビュートはtext型の,データ変数の次元数と同じ長さを持ったもので,各文字はCDL内で宣言されている次元のどれがT,Z,Y,Xのうちどれに相当するか指定します.どれにも相当しない場合には,「-」を書き込みます.T,Z,Y,Xは,一回しか現れることができません.

また,データ変数が,特定の意味を持つ可能性がある次元を複数もつ場合,axisアトリビュートを用いてどの次元がどの意味をもつか明示的に示す必要があります.さらに,一つの軸だけがcollapseされていない多重時間軸(セクション28参照)がある場合,その唯一の「気候値をあらわす時間軸」に相当する次元が普通はT軸として指定されます. axisアトリビュートが指定されている場合,次元はどの順番でも指定することが可能といえば可能ですが,標準の順番と違う順番をとるのは可能な限り避けてください.これはアプリケーションによっては次元の指定順をきめ打ちしているものがあり,好き勝手な順番で指定された次元を持つファイルがトラブルの元となる可能性があるからです.

標準的な時間平均「経度−緯度−高度」変数の次元指定

  dimensions:
    lat=18;
    lon=36;
    pressure=15;
    con_time=1;
  variables:
    float xwind(con_time,pressure,lat,lon); // order T Z Y X
      xwind:axis="TZYX";
    float lon(lon);
    float lat(lat);
    float pressure(pressure);
    float con_time(con_time);

経度・緯度・高さ・時間の各軸に対する規約の詳細は,それぞれセクション14, セクション15, セクション16,セクション23を参照してください.

データ変数内の点の座標は,各座標変数(セクション8参照)の値を単純に並べたものとなります.もし座標変数を持たない軸があった場合,その軸に対応する座標値は0からはじまるインデクスとなります.

次元のサイズは任意で,サイズ1ということも可能です.ある単一の量が,一つのデータ変数内の全ての値に適用される(訳注:たとえば時間軸上1点の値を含むデータ変数の場合,時間を表す変数はすべての値に対して共通)場合,その情報をデータ変数に格納するのに推奨される方法は,1次元座標変数をもつ,サイズ1の次元(singleton dimension)を設定してしまう方法です.この方法の利点は,座標変数のすべてのアトリビュート(量・コンポーネント・境界等々)がその単一の値の記述のためにも使えるということです.Singleton dimensionは次元のcontraction(セクション22参照)の結果として生じる場合もあります.

ある一つの気圧面における温度の経度−緯度場:pressure軸にsingleton dimensionを設定します:

  dimensions:
    lon=96;
    lat=72;
    pressure=1; // single-valued coordinate variable
  variables:
    float temperature(pressure,lat,lon); // axes in order Z Y X
      temperature:axis="ZYX";
    float pressure(pressure);
      pressure:long_name="pressure";
      pressure:units="kPa";
  data:
    pressure=50.0; // Pressure level of 50 kPa = 500 mbar
units および long_name アトリビュートについては,セクション12を参照してください.

地表気温の例:地上観測は,例えば高さ1.5mの点で行われることを考えると,定義はこんな感じになるでしょう:

  variables:
    float temperature(height,lat,lon);
      temperature:axis="ZYX";
      temperature:long_name="atmospheric temperature";
      temperature:units="K";
    float height(height);
      height:long_name="height above the surface";
      height:units="m";
  data:
    height=1.5;

ただし,観測面がquantityの名に含まれている場合は明示的にheightを指定してはいけません.

10  いろいろな座標系

axisアトリビュートがXおよびY軸を指定し,かつ各軸がそれぞれ経度および緯度をそのまま表すならば,これらの軸が作る面はは地球表面を経度緯度平面に投影したものとなり,XYボックスの面積はその過程のもとに計算できます.

地球表面のrectiliniarな投影法(座標系)としては, このような地理座標に依拠したもののほかに極座標によるものもあります.これを「rotated grid」と呼びます.rotated gridを表すには,2次元のfloat型アトリビュートnorth_poleをつけ,その投影法で「北極」となる地点を(経度,緯度)の形で指定します.もし指定がない場合は(0., 90.)(つまり北極そのものです)とみなされます.

さて,他の地球投影座標系の中にはrectilinearな軸を持たないもあります.このような座標系も除外したくはないものです. しかし,現時点においてはこのような座標系についての標準は策定されておりません.私たちは,適切な標準規約についての,将来このような投影座標系をGDTで使うことになるであろうユーザからのコメントを期待しております. COARDS標準はこのような座標軸を除外しています.原則として,どの座標系も2あるいはそれ以上の軸を一つの軸(点へのインデクスが入る)にまとめて,点から点への投影を表す座標変数を導入すれば,一応(かなりぎこちない場合もあるにせよ)扱うことができます.


11  単位

The udunitsパッケージにはudunits.datというファイルが入っています.このファイルは単位のカタログが入っています.このファイルの最新版に入っている単位名およびその複数形についてを,GDT標準で使用可能な単位名とします.ただしAppendix Cに示したようにわ改変した例外(追加)も少数認めています. COARDSは同様の改変を標準規約内で挙げていますが,将来の改変が容易になるように,あまりやりすぎないようにし,Appendexにおいておくほうがいいと私たちは思います. GDTに従うユーザは,かってにオリジナルの単位を定義しないようにしてください.そうするとファイルのポータビリティが下がってしまいます.新しい単位を加えてほしい場合にはUNIDATAにリクエストを出してみてください.

udunitsパッケージは,単位換算の式も定義してます(線形式:オフセットとファクターを定義).この方式が許されるのは,そのように定義した方がよい場合です. 例を挙げると,海水密度をkg m-3で表したときに,1000kg m-3を越える値を,udunits単位"kg m-3 @ 1000"を定義して表すことも可能です. ただしCOARDSの方ではこの機能の使用は認められていません. なお,この機能の使用は,圧縮のためだけに行ってはなりません.圧縮に関しては別に方法があります(セクション32参照).


12  変数の物理量

 ここでは,3つの文字列型アトリビュートにおける規約に関して述べます.これらのアトリビュートは,データ変数ならびに座標変数における物理量を指定するものです.

 まず,unitsアトリビュートを,UNIDATA udunitsパッケージの推奨に従った方式(セクション11参照)および時間変数に関する指定方式(セクション25参照)で指定する必要があります.このアトリビュートにおいては,大文字小文字を区別します.unitsは,物理量が無次元(単位を持たない)場合を除いて,必須です.単位を持たない場合,unitsを数値のみで与えることも可能です. いくつか,無次元のunitsも定義されています.たとえばpercentなどです.しかし,海氷密度・雲量・確率などなどといった種々の量についていろいろな無次元単位を定める必要はありません.そういった記述的情報は,unitsよりはむしろlong_nameにいれるものです.なお,スケールファクターとオフセットをここで指定することもできます.たとえば,海氷密度を1/10を単位として表す場合,units0.1fと指定することができます.スケールファクターとオフセットを指定しない無次元単位は1.0fであり,これはあるいはunityと書くこともできます.

 次に,文字列型アトリビュートlong_nameについて説明します.これはUnidata標準アトリビュートで,変数の説明が入ります.ただし,単位自体の説明を入れてはいけません.このアトリビュートはオプショナルなものです.

 そして最後にquantityアトリビュートは,定義済みリストdefined listの中から選んだ記述によってその物理量が何であるか指定するものです.さらにオプションとしてカッコの中により詳しい情報が書き込まれる場合もあります. 定義済みリスト(を用いて記述の幅を狭めること)の目的は,データを用いるユーザが,異なるデータソースから得たデータのどれとどれを比較すればよいか決定できるようにすることです.quantityアトリビュートにおいては,大文字小文字の区別はありません.

 さて,quantityとして指定可能なものを集めたリストをquantity tableと呼ぶことにします.このtableはquantityとそれに用いることができる単位を定義したものです.ここに定められた単位,および物理的に同値な単位をunitsに指定できます.

 さて,quantity tableの選択に当たっては二つの選択肢があります.一つはGDTのAppendix Dを使う方法です.このAppendixはやがてWWWで利用可能となります.この場合,グローバルアトリビュートquantity_tableを空文字列にセットしてください.Appendix Dに含まれる各物理量には,その元となったAppendixのバージョン番号をも含んだラベルが付けられます.そうすることによって,そのファイルを使うアプリケーションは,そのファイルを作成したアプリケーションにとって有効だった物理量の完全なセットを推定することができます.

 もう一つの選択肢は,使用される可能性のあるquantity名をすべて含んだリストを作ってしまう方法です.そのリストでは,各物理量にたいして[1]有効な単位と[2]Appendix D内の相当する物理量の名,を与えます.この自家製リストもWWWで公開されるべきです.そして,グローバルアトリビュートquantity_tableにそのURLを指定します.

 標準化された物理量セットの使用はオプショナルです.グローバルアトリビュートquantity_tableの存在は,このオプション(標準化された物理量セットの使用)を暗黙的に有効にします(The presence of the global quantity_table attribute implies that this option is being followed.).

 物理量の名前は,場合によってはlong_nameアトリビュートに入れることも出来ます(long_namequantityが同一になってしまうのを避けるためです).従って,物理量を扱いたいアプリケーションは,もし(ある変数について)quantityアトリビュートを見つけられなかった場合は,long_nameアトリビュートからquantityの値を得ることになります.この文書の残り部分では,quantityアトリビュートは直接は使わず,long_nameアトリビュートにquantityの情報を入れることにします.

quantityアトリビュートの例

    float tempt(pressure,lat,lon);
      tempt:long_name="potential temperature";
      tempt:quantity="atmospheric potential temperature "
        "(after timestep)";
      tempt:units="K";

"potential temperature"が,プロットのタイトルに使われ得る説明文字列となります.そして,"atmospheric potential temperature"が標準化された物理量,また,"(after timestep)"が追加情報です.後者は通常のアプリケーションでは無視することができます.

二つの物理量が同じ物なのか違うものなのか?という問いは,大抵の場合はっきりとした答えがないものです.確かに,同じ物理量なら単位は同じでしょうが,しかし,違う物理量が同じ単位を持つこともあります:たとえば,「atmospheric potential temperature」と「soil temperature」です.実際問題としては,可能な限りもっとも詳しい記述・説明を行うべきです. 私達は,GDTユーザの方々からのリクエストに答えて,Appendix Dを拡張してゆきたいと思っています.私達だけでは全てを見通すことは不可能であるからです.新しい物理量が必要かどうか不明確なときは,出来るだけそれを取り入れるようにし,制限よりは拡張の方向性を保っていたいと思います(and we will err on the side of expansion, rather than restriction, when it is unclear whether a new quantity is needed.).

 アトリビュートsubgridセクション21参照)はquantityのモディファイアとみなすことも出来ます.ただし,これはデータ変数の場合だけであり,座標変数には適用されません.quantitysubgrid両者は,Appendix Bとquantity table内に記述された情報を通じて)物理量の次元を定義します.そして,unitsアトリビュートはこれに整合している必要があります.

 アトリビュートlong_nameは,subgridアトリビュートで詳細に記述された情報の繰り返しとなるかもしれません.たとえば,long_name"maximum temperature"であるとしましょう.このとき,subgridには最高気温の求め方の詳細な記述が入るでしょう.

 データ変数にはhistoryアトリビュートをつけることもできます.これは標準的な形,すなわちquantitysubgridアトリビュートのカッコの中に記述するという方法では記述できない,値の導出法に関する情報を記述します.このアトリビュートの使用は「最後の手段」としてください.グローバルアトリビュートhistoryが存在する場合は,それもまた全てのデータ変数に対して適用されます(セクション5参照).

 また,データ変数はinstitutionproductionを持つことができます.これらは各変数のもともとの取得方法・取得者を示すものです(セクション5参照).

 各データ変数に対するこれらのアトリビュートは,グローバルアトリビュートよりも優先されます.

 historyinstitutionそしてproductionは,ファイル内においてデータ変数間の区別をする目的で使ってはならず,また,一般的なアプリケーションはこれを無視することができます.

物理量に対するこれらオプショナル情報の例

上記に挙げたオプショナル情報を,観測降雨グリッドデータの記述に使った例です:

    float precipitation(lat,lon);
      precipitation:history="gridded using Thiessen polygon weighting";
      precipitation:institution="Climatic Research Unit, "
        "University of East Anglia, UK";
      precipitation:long_name="rate of precipitation";
      precipitation:production="surface station observation";
      precipitation:units="mm day-1";
これは,この変数が含まれているファイルが他の組織によって作られたり,違うデータ作成法によって生成されていた場合に適切な方法です.

 さらにオプショナルなアトリビュートとして,moduloがあります.これが指定されている場合は,このアトリビュートの値(の整数倍)を変数の値に足しても引いてもその値の有効性や意味は変わりません.moduloの値は,変数と同じ単位で与えられる必要があります. これは経度を表す座標変数(セクション14参照)にとくに適しています.この変数に対して,moduloアトリビュートを値360で設定するのです(安形注:もちろん単位がdegrees_eastの場合).また,季節変化や日内変化を表す各種気候データの時間軸についてもこのアトリビュートを用いるのは有効です(セクション25およびセクション28に実例があります)

 なお,Unidata標準であるFORTRAN_formatアトリビュートも,座標変数・データ変数双方に対して有効であることを指摘しておきます.

 さらに,モデル固有のアトリビュートを,変数の物理量の定義のために加えることが可能です.たとえば,Hadley Centreモデルでは各変数にstashおよびsubmodelという整数型のアトリビュートを付しています.これはGCMの診断出力変数を識別するコードとなっています.

 変数は連続量でなく離散量である場合もあります.つまりあらかじめ定められた値しかとらない変数もありうるということです.これはデータ変数よりも座標変数の場合によく見られることでしょう.たとえば,フーリエ解析や球面調和解析の結果を格納する変数は,軸の一つとしてharmonic numberの軸を持つでしょう.また,セクション25では時間軸としてこのような離散座標軸が使われる例を紹介しています.


13  軸のトポロジTopology of an axis

 「circular topololgy」を持つ軸とは,軸上にある全ての点をその軸に沿って「一つの端点の点のあった場所にもう一つの端点が来るように(あるいはその移動量の整数倍の移動を行って)」動かすという変形ができる軸のことです(An axis with ``circular topology'' is one which can be legitimately transformed by shifting all the points one place along the axis, moving the last point to the beginning, any number of times.).この主の軸に対する主座標変数は,topologyアトリビュートをもち,その値はcircularです. たとえば,全球を対象にしたときの経度軸がその一例です. また,topologyアトリビュートがないか,あるいはその値がlinearである軸は「linear topology」を持つとみなされます.なお,トポロジは主座標変数によってのみ指定されますが,これは軸自体の属性ですから,その軸に関する関連変数・境界変数にも同様にそのトポロジが適用されます.

「circular」な軸が回転変形を受けたとき,軸がモノトニックになるように主座標変数(の値)を変更しなければなりません.したがって,こういった軸にはかならずmoduloアトリビュート(セクション12参照)をつける必要があります.

topologyアトリビュートとmoduloアトリビュートが含む情報は異なるということに注意してください.たとえば,グリニッジから日付変更線までの「東半球」のみを含んだ経度軸を考えてみましょう(e.g. 0E, 25E, 120E, 130E, 180E).この軸はcurcularなトポロジを持ちません.この軸を利用したマップにおいてコンターマップ(等値線図)を作るときは,東半球内のどこの点においても自由に補間を行うことができますが,しかし西半球内の点における値までも勝手に補間して全球のコンターマップを書くことはできません.西半球を無理やり書くとしたら,欠測扱いにします.つまりcircularトポロジとは,ユーザがマップの左に任意の地点があるものと想定できると暗黙のうちに示すものなのです(The implication of circular topology would be that one could put any longitude at all on the left-hand side of the map. ).しかし,この軸はまた別にmoduloアトリビュートを持っています(値は360.これはセクション14において要求されているとおりです).ですから,データポイントの経度値はこの値を法として合同なあらゆる値をとることができます.例を挙げると,「0,25,120,130,180」という値の列は「-360,-335,-240,-230,-180」と同値なのです.


14  経度を表す次元

経度を表す座標変数には,明示的にunitsアトリビュートを指定しなければなりません.このアトリビュートにはdefault値はありませんので注意してください.unitsアトリビュートは,UNIDATA udunitsパッケージの推奨に従った文字列形式です. 経度の単位として推奨されているのは,degrees_eastです(東向きに正).また,degree_east, degree_E, degrees_Eでも構いません.ただし,degrees_west(西向きが正)はお勧めできません.これはdegrees_eastから変換するのに負のファクターを必要とするからです.

経度軸に関するアトリビュートとして,float型のmodulo(=360)が必要です.これにより,たとえば-180,180,540はどれも経度として有効な表現となり,どれも日付変更線の経度を表します.また,0と360についてもいずれも有効な表現で,グリニッジ子午線を意味します.COARDSでは経度はつねにこの方法で扱うものとしています.私たちはmoduloアトリビュートを導入してからは,このアトリビュートを指定するように要求しています. また,全球にわたるな経度軸については,アトリビュートtopology(=circular)の指定が必要です.(ここで,moduloアトリビュートを指定しても,それは必ずしもその軸がcircularトポロジを持つことを意味しない,ということに注意してください.セクション13参照)また,地球の一部しかカバーしない経度軸については,その点を回転することはできません.経度の主座標変数については,netCDFファイル中に,単調増加(or単調減少)となるように,かつ値が0〜360の範囲で(non-module sence)入るようにしなければなりません.

全球にわたる経度軸

    float lon(lon);
      lon:long_name="longitude";
      lon:modulo=360.0f;
      lon:topology="circular";
      lon:units="degrees_east";

quantity tableを使っているときは,longituteは標準リスト内におけるquantityの名前で,それはquantityアトリビュートに代わりに入れることができます.


15  緯度を表す次元

緯度を表す座標変数には,明示的にunitsアトリビュートを指定しなければなりません.このアトリビュートにはdefault値はありませんので注意してください.unitsアトリビュートは,UNIDATA udunitsパッケージの推奨に従った文字列形式です. 緯度の単位として推奨されているのは,degrees_northです(北向きに正).また,degree_north, degree_N, degrees_Nでも構いません.

緯度軸の定義:

    float lat(lat);
      lat:long_name="latitude";
      lat:units="degrees_north";

quantity tableを使っているときは,latituteは標準リスト内におけるquantityの名前で,それはquantityアトリビュートに代わりに入れることができます.


16  高さ・深さを表す次元

平面座標を表す二つの次元,つまり緯度と経度,についてはその向きは上記のように明確に決められていますが,垂直軸をもつ物理量がある場合,その軸には実にいろいろな量が使われます. 垂直軸とみなされる軸については,long_name(セクション12参照)およびpositiveの二つのアトリビュートを指定しなければなりません. 後者については,取りうる値は二つだけで,それらはupdownで,上向きと下向きのどちらが正の向き(座標変数の値が増加する向き)か指定します.(これはデータを表示するアプリケーションにとって有用な情報となりうるからです)

垂直軸の例:気圧軸

  dimensions:
    pressure=15;
  variables:
    float pressure(pressure);
      pressure:long_name="pressure";
      pressure:positive="down";
      pressure:units="hPa";
  data:
    pressure=850, 700, 500, 300, 200, 150, 100, 50, 30, 20, 10;

COARDS標準では垂直軸の単位として,指定されたリストの中から選ぶように要求しています.これは,垂直軸がその単位だけでどの種類のものかわかるためです.この基準では,垂直軸にpressure単位を使うときは正の向きがすでに決まっているという特例となりますが,その他の単位を垂直軸に使う場合にはかならずpositiveアトリビュートの指定が必要になります.

しかし私たちは違う方法をとりました.これにはいくつもの理由があります.まず,垂直軸に単位指定を要求するということは座標変数のために使われるかもしれない無次元量に対して無次元単位を定義するということを意味します.これはデータ変数に対する取り扱いと整合性を欠くのです(標準では,データ変数においては,無次元物理量に対して無次元単位を作り上げて当てはめることを要求していません).第二に,データ変数の垂直軸に対応する次元はaxisアトリビュートあるいは次元の並び順で分かります(セクション9参照).そのような次元を用いるアプリケーションは,わざわざ他の情報をつけなくてもどれがその次元か分かるわけです.第三に,quantityアトリビュートが使われている場合は,それは単位よりももっと情報を多く含んでいるからです.

正の向きは本当にデータ構造の中に含まれるべきかどうかという点については私たち自身まだ確信を持っていません.正の向きはデータ表示の際に考慮の対象となることがほとんどで,そしてある程度個人の好みの問題でもあります.垂直軸にこのような特別の扱いをするなら,なぜ他の軸にも正の向きを記録しないのでしょうか?たとえば,緯度軸がもし水平軸であれば左右どちらが北なのでしょうか.このことは同じ種類の問題ではありますが,しかし単にグラフィックアプリケーション側が考慮すればいい問題という以上に私たちを苦しめます(This is the same kind of question, but it strikes us as more a matter for a graphics application to consider).それでも,この基準ではCOARDSとの互換性のためにpositiveアトリビュートの指定を要求してます.

たとえば,海洋データを格納するnetCDFファイルを考えましょう.垂直軸を,海面を「0」,海面下1000mを「1000」とするように設定します.このとき,アトリビュートは次のようになるでしょう

  units="m"
  long_name="depth below the surface"
  positive="down"
一方,海面下1000mが「-1000」となるように軸を設定した場合はこうなります:

  units="m"
  long_name="height above the surface"
  positive="up"

17  コンポーネント変数Component variables

 連続量を取る物理変数は,各点における「値」を表現するのに二つ以上の数値を必要とする場合があります.この各数値を「コンポーネント」と呼び,それぞれが格納される変数を「コンポーネント変数」と呼ぶことにします.各コンポーネントが属する変数,言い換えれば各コンポーネントをまとめる変数を「ヘッド変数」と呼ぶことにします. ヘッド変数のcomponentアトリビュートの中に,コンポーネント変数の名前を空白で区切ったリストとして並べて記述します.コンポーネント変数の次元はヘッド変数のそれと同一でなければいけません. OGDTではコンポーネントを座標変数にのみ限定していましたが,現在では一般の変数にまでその対象を広げています.これは座標変数として使われる物理量というものはデータ変数としても要求されうるからです.

一つの座標変数が(複数の)コンポーネントを持つとき,この標準ではコンポーネントの組み合わせを表現する主座標変数が与えられることを要求します.この主座標変数は,軸に沿って点を配列することができるようなものとします(When a coordinate variable has components,this standard requires that a main coordinate variable should nonetheless be supplied which represents a combination of the components that can be used to order the points on the axis). 通常,この主座標変数は単調(増加or減少)でなければなりません.しかし各コンポーネントはそうである必然性はありません.コンポーネントを用いた主座標変数の定義は,componentアトリビュートのカッコ内で行うことができます.この情報は標準化されておらず,一般のアプリケーションがこれを利用できることを仮定してはいけません.

コンポーネント変数を用いたハイブリッド垂直軸

ある種のGCMでは,垂直座標としてη≡p/p0+σが使われます.この場合,垂直方向の高さは(p,σ)のペアで表されます.ここで,pは気圧,p0は定数,σは地表気圧のfraction(変数)です.ηの値はこれら二つの線形結合ではありますが,η自体から(p,σ)のペアを逆算することは不可能です.そこで,この垂直軸を表すには次のようにコンポーネント変数を利用します:

    float eta(eta); // main coordinate variable
      eta:component="pressure sigma "
        "(eta=pressure/p0+sigma; p0=100 kPa)";
    float pressure(eta);
    float sigma(eta);

通常のアプリケーションは,コンポーネントと主座標に関する情報をを独立したものとして取り扱うでしょう.これらを関連付けるためのさらに詳しい情報は,それを必要とする特別なアプリケーションの中にあることでしょう.ハイブリッド垂直軸は,コンポーネント変数の唯一の自明な応用事例です.しかし,この規約自体は同様の目的(そういう要求が今後あれば)のために使うことができます.


18  関連変数Associated variables

データ変数の一つの軸(あるいは複数の軸のセット)は,別の座標変数の組を撮り得ることがあります.この交代可能な座標変数を,関連変数associated variableといい,固有のunits,long_name属性および適切な説明用属性をもちます.

関連変数の名前を,データ変数または該当する軸の主座標変数のassociate属性(文字列型)中に,スペースで区切ったリストとして記述します.なお,データ変数が関連変数と組み合わさっているときは,その組み合わせはそのデータ変数に固有のものですが,主座標変数と組み合わさっているときは,その組み合わせはその主座標変数を使う全てのデータ変数に適用されます.主座標変数に対する関連変数の設定は,ですから便利なものである一方柔軟性に欠けるという二面性を持つことになります.

データ変数に関する関連変数の組み合わせは,軸がいくつかありしかも主座標変数がないときには単なるオプショナルなものです.具体例は後述の例を参照してください.

associate属性はまた,coordinates属性として設定することができ,両者は同値です.これはCSM標準との互換性のために組み入れられたものです.しかし,現在のGDT標準ではこの仕様に反対しています.というのは,通常の「座標変数」(セクション8参照)の定義と紛らわしく,また,関連変数の使用は通常の座標変数に比べるとより広い概念であるからです.

変数は複数のデータ変数や座標変数を関連変数としてとることができます.関連変数自体がassociate属性をもつ場合,その属性で指定された変数もまた関連付けされます(variables named by this attribute are also regarded as being associated).

関連変数はその次元(軸)として,それと関連付けられている任意のデータ変数の全ての次元を持たねばなりません(An associated variable must have dimensions which are all dimensions of any data variable with which it is associated).すなわち,関連変数は,これらの軸にそったインデクスの函数とみなすことができます.なお,関連変数の値についてはモノトニック(単調増加ないし単調減少)でなければならない必要はありません.

なお,通常のアプリケーションは関連変数が使用できることを要求されてはいません.

関連変数はデータ変数のaxis属性(セクション9参照)で指定されません.しかしながら,CDLファイルの可読性を高めるために,   データ変数のassociate属性で指定された変数がaxis属性でいうところの T, Z, Y, X で表記されるような意味を持っている場合,各変数はリストの中でその順番に並べる(他の意味を持つ変数はリストの先頭に置く)ことを推奨します.

垂直軸の例:

多くの関連変数は1次元のもので,その軸にそった値の集合(主座標変数のそれとは異なるもの)を与えます.以下はその例の一つで,物理的な垂直座標のほかにモデルのレベル番号を指定しています:

  dimensions:
    lat=90;
    sigma=19;
  variables:
    float xwind(sigma,lat); // 2D data variable
      xwind:axis="ZY";
    float lat(lat);
      lat:long_name="latitude";
      lat:units="degrees_north";
    float sigma(sigma); // physical height coordinate
      sigma:associate="model_level";
      sigma:long_name="sigma";
      sigma:positive="down";
    int model_level(sigma); // model level number at each height
      model_level:long_name="model level number";
      model_level:positive="up";

変数model_levelが座標変数sigmaに関連付けられているので,sigma軸をとる全てのデータ変数はmodel_levelとも関連付けられることになります.この関連付けはxwindにだけ適用されるのではないわけです.

トラジェクトリ:

1次元のトラジェクトリ(軌跡)に沿った値を考えます.この値に対する座標変数としては,移動中の「時刻」で表した座標のほかに,各データポイントにおける緯度経度を表す関連座標変数を指定したくなるでしょう:

  dimensions:
    day=10; // 10 sample times along a trajectory
  variables:
    float hice(day); // sea-ice thickness measured as the floe drifts
      hice:associate="lat lon";
      hice:axis="T";
      hice:units="m";
    float day(day); // time since the beginning of the journey
      day:long_name="time";
      day:units="day";
    float lon(day); // longitude at each time
      lon:long_name="longitude";
      lon:units="degrees_east";
    float lat(day); // latitude at each time
      lat:long_name="latitude";
      lat:units="degrees_north";

主座標変数(day)はモノトニックでなければなりませんが,関連変数はそうでなければならないというものではありません.なお,これと似た重要な応用例がセクション19に載っています.なお,上記の例でいうと変数latおよびlonaxisアトリビュート(セクション9参照)のXおよびYに対応付けられないことに注意して下さい.これは,これらの変数が,たとえ緯度経度という意味を持っているにせよ,こういった軸を使用するアプリケーションが通常予想する意味での独立した次元ではないということを考えると,合理的なことです.

変数lonlatはデータ変数hiceと関連付けられているのですから,この関連付けはdayを座標変数とするほかの変数にはそのままでは適用されません.もしそうしたいなら,各座標変数ごとにその関連付けを指定することになります.この手法は,同じday変数がさまざまに異なった変数(の組)と関連付けされることを許容するものです.たとえば,トラジェクトリが複数あるとき,同じday座標は異なった緯度経度座標と関連付けされる場合があります.

変換された座標:

2次元以上の関連変数を,異なる座標系を表すために使うことができます.たとえば,大気の湿度の垂直プロファイルデータにおけるデータポイントの表示法を考えるとき,それは通常の緯度経度でも表示できますが,それと同様に,各国固有の座標系を用いたくなる場合もあります.このとき,各国固有座標系による座標は緯度経度の函数です(ただし,x座標は経度だけの函数とは限りませんし,y座標は緯度だけの函数とは限りません).これらを正しく設定するCDLの例を以下に示します:

  dimensions:
    lon=10;
    lat=20;
    pressure=15;
  variables:
    float humidity(pressure,lat,lon);
      humidity:associate="y x";
    float pressure(pressure);
      pressure:long_name="pressure";
      pressure:positive="down";
      pressure:units="kPa";
    float lon(lon); // 1D main coordinate variable
      lon:long_name="longitude";
      lon:modulo=360.0f;
      lon:units="degrees_east";
    float lat(lat);
      lat:long_name="latitude";
      lat:units="degrees_north";
    float x(lat,lon); // 2D associated coordinate variable
      x:long_name="UK national grid eastings";
    float y(lat,lon);
      y:long_name="UK national grid northings";

この例では,humidity[*][10][5]は緯度lat[10],経度lon[5]の点における湿度の垂直プロファイルを表します.この点はまた,国固有座標系におけるx座標x[10][5],y座標y[10][5]の点に該当します.また,この例では関連変数は多次元であるため,軸対軸の1対1対応がとれません.したがって,関連付けは主座標変数にではなく,データ変数にたいして行うことになります.

主座標変数がない場合

2次元座標系が何らかの幾何学的方法で変形される(staggered or transformed geometrically in some way)場合を考えてみましょう.ただしここでは回転(セクション10参照)の場合を除きます.つまり,軸に対する1次元座標変数を与えることが不可能ないし困難な場合を考えるわけです.この場合,主座標変数を設定せず,plain indexesをapplyするということが考えられます.物理的な座標は2次元座標の函数であり,上記の例と同様にデータ変数の関連変数として与えられます(The physical coordinates are functions of the 2D gridpoint indices, and would be given in associated variables of the data variable just as above):

  dimensions:
    x=90;
    y=45;
  variables:
    float orog(y,x); // 2D variable on a horizontal grid
      orog:associate="lat lon";
      orog:axis="--";
      orog:long_name="height of the surface above sea-level";
      orog:units="m";
    float lon(y,x); // 2D coordinate variable on the same grid
      lon:long_name="longitude";
      lon:modulo=360.0f;
      lon:units="degrees_east";
    float lat(y,x);
      lat:long_name="latitude";
      lat:units="degrees_north";

変数latおよびlonaxisアトリビュートのXY(セクション9参照)に対応付けられません.緯度や経度を参照するアプリケーションは,それらに該当する変数が2次元であることを想定していない場合があります.もしそれができる場合は,これらの軸をlong_nameおよびunits属性でidentifyしているはずです.

3次元の関連変数

3次元座標系による座標表示を複数使いたい場合に用いられ得る方法です.たとえば,普通のCartesianグリッドと円柱座標系ないし球面座標系を両方使いたい場合などです.主な座標系でないほうの座標系における座標値は,Cartesianグリッドの値を用いて表すことができるでしょう.たとえば:

    float temperature(z,y,x); // 3D variable on a Cartesian grid
      temperature:associate="radius theta phi";
    float radius(z,y,x);
    float theta(z,y,x);
    float phi(z,y,x);

1次元関連変数の,とりわけテクニカルな応用例の一つは,次元サイズが無制限(未定)である軸(unlimited軸)が一つしか設定できないというnetCDFの制限に対処することです.いくつかのデータ変数が,サイズの違う又は物理的意味が異なる複数のunlimited軸を含んでいる場合,名目上の軸を一つ設定して,それを各変数でシェアするという手法が使えるのです.そして,各変数ごとにこの「名目軸」に本当の軸を表す変数を関連付けします.

複数のunlimited軸:

異なるサンプリング頻度による経過時間軸(つまり,長さもそれぞれ異なります)を含んだ複数のデータ変数が入っているファイルを考えてみましょう:

  dimensions:
    time_counter=UNLIMITED;
  variables:
    float sw(time_counter); // sampled every 3 hours
      sw:associate="time_3h";
      sw:axis="T";
      sw:long_name="vertical component of "
        "shortwave radiative flux density";
      sw:units="W m-2";
    float latent(time_counter); // sampled every 30 minutes
      latent:associate="time_30min";
      latent:axis="T";
      latent:long_name="latent heat flux density";
      latent:units="W m-2";
    float time_3h(time_counter)";
      time_3h:long_name="elapsed time";
      time_3h:units="h";
    float time_30min(time_counter);
      time_30min:long_name="elapsed time";
      time_30min:units="min";

19  変数のバンドル

 同じ物理量を格納するいくつかのデータ配列が,いくつかの同じ軸を持ち,かつそれらがsingleton dimensionを持つ他の座標変数によって区別されている場合は,これらを全部まとめて一つのデータ変数に格納してしまうほうが便利な場合があります. この場合,もともとの(別々の)データ変数間で共通していた軸は,新しい(統合された)変数の軸となります.そして,一つあるいは複数の新たな軸が,もともとのデータ配列をバンドルする(統合する)ために導入されます.この新たな軸は,連続量としての物理量に対応するものではなく,単にバンドルされた変数へのインデクスとしての働きだけをもちます.

 もともとの配列にあったsingleton valueは,bundling次元(軸)の座標変数に格納されます(The singleton values of the separate arrays are recorded in associated coordinate variables for the bundling dimension.).これらは,連続的な座標変数と解釈してはいけません.

時系列:

Hadley Centre GCMは,各点における物理量の値について時系列を生成することができます.典型的には,多数の異なる点における時系列が,同じ物理量・同じサンプル回数のデータを用いて作られます.そこで一つの軸を,これらのすべての時系列に共通する時間軸とし,サンプリング時刻を表す共通軸とします.そして,他の軸は離散的な座標変数を設定し,それを2あるいはそれ以上の次元空間内に不規則に散らばった点に対応する各時系列のバンドル用に用います.この例を下に示します:

  dimensions:
    points=15; // measurement locations
    times=20; // sampling times
  variables:
    float snowdepth(times,points);
      snowdepth:associate="sitename lat lon";
      snowdepth:axis="T-";
    float lon(points); // longitude of sites
      lon:long_name="longitude";
      lon:modulo=360.0f;
      lon:units="degrees_east";
    float lat(points); // latitude of sites
      lat:long_name="latitude";
      lat:units="degrees_north";
    char sitename(points,StringMaxLength); // string array of sitenames
    double times(times); // times of measurement

時間座標については,セクション23を参照してください.このフォーマットは,ステーション観測の時系列にも同様に用いることができます.上の例では,バンドル用の軸pointsは単なるインデクスとして働きます.そして,関連変数associated variableのアトリビュートlong_nameおよびunitsが,各変数の意味を表します.

垂直プロファイル:

同様の例は,いくつかの観測点における垂直プロファイルデータの取り扱いにも見ることができます.たとえば,海洋におけるいくつかの点の水温プロファイル(scattered vertical temperature profiles through the ocean)や多数の点におけるラジオゾンデ観測データなどです.:

  dimensions:
    station=10; // measurement locations
    pressure=11; // pressure levels
  variables:
    float humidity(pressure,station);
      humidity:associate="lat lon";
      humidity:axis="Z-";
    int station(station); // station numbers
    float lon(station); // longitude of stations
    float lat(station); // latitude of stations
    float pressure(pressure)

Parcel trajectoryのいくつか

ここではいくつかのLagrangian parcel trajectoriesの組(たとえばocean drifters)を考えてみましょう. 各軌跡において,その開始時刻からの設定(固定)した経過時間ごとにたくさんのパラメータが算定されます.それぞれの軌跡は,開始位置によって識別され,そして各時刻における位置は時刻および軌跡番号の関数となります.したがって,位置情報は,多次元の関連変数の組に格納されることになります:

  dimensions:
    parcel=15; // number of trajectories
    times=20;
    max_len_parcel_name=64; // max length of trajectory name
  variables:
    float temperature(parcel,times);
      temperature:associate="parcel_name lat lon";
      temperature:axis="-T";
    float salinity(parcel,times);
      salinity:associate="parcel_name lat lon";
      salinity:axis="-T";
    float times(times);
      times:units="days";
    char parcel_name(parcel,max_len_parcel_name);
    float lon(parcel,times);
    float lat(parcel,times);

この例では,データ変数について関連変数の設定associationが行われなければなりません.というのは,parecel_nameは主座標変数を持たず,一方lonおよびlatは多次元であるからです.

さて,このセクションをここまで読まれた方は次のような疑問を持たれるかと思います.「単一の時系列,ないし単一の垂直プロファイルなどを格納するベストなやり方は何だろうか?」 このセクションのやり方に従えば,サイズが1のバンドル用次元をもつ2次元データ変数に格納するという手法がその答えとなります.関連情報−たとえば緯度や経度−はサイズ1の(singleton)座標変数の中に格納され,全てが同じ軸に関連付けられます. しかしそれとは別に,このようなデータはそれぞれ別のサイズ1の(sigleton)軸に格納することもできます(セクション9の流儀です).

私達は,この問いについては何も推奨すべきものをもっていません.どちらの方法もそれなりに適切です.どの方法がより自然であるかは,連続的な軸からデータがどのように引き出されているかという点によります(which is more natural perhaps depends on how the data was extracted from the continuous axes).


20  境界変数

データ変数の値は,軸に沿ったある「点」(該当する座標変数の値そのもの)に対応する場合も,連続的にせよ連続的でないにせよ何らかの「範囲」(セル)に対応する場合もあります.後者の場合,そのセルの境界(これは「点」です)を「点」の場合と同様に明示する必要があります.GDTでは,この境界の明示法として,2次元の「境界変数boundary variable」を導入することとしています.この変数はright-hand dimension(FORTRANでは,配列の最初の次元)のサイズが2となります.この次元のインデクスが0(以下,Cの表記法にならって,この次元が0オリジンであるとします)の場合,当該セルの境界のうち主座標変数が小さい方の値(下限)を示します.そしてインデクスが1の場合は,同様に上限の値を示します.ここで,「大小」とは単に数値の大小だけを問題にしており,物理的な方向は考慮しません. 上限ならびに下限を別に指定するので,各セルが必ずしも連続的でなくてもよいことになります.さらには,各セルがオーバーラップすることさえ可能です. もしあるセルの下限が座標変数のアトリビュートvalid_min(セクション29参照)に等しい場合,そのセルは下限をもちません.同様に,上限が座標変数のvalid_maxに等しいセルは上限をもちません 境界変数の名前は,主座標変数のアトリビュートboundsstring型)に格納されます.(変数名に関しては制限がありませんが,)私達は座標名の前にbounds_をつけた名前を付けることを推奨します.また,境界変数の単位は主座標変数の単位と同じです.

1次元緯度軸に設定した境界変数

    float lat(lat);
      lat:bounds="bounds_lat";
    float bounds_lat(lat,2);

C言語の場合,lat[0]は軸の最初の点を表します.それに対応する境界変数は,bounds_lat[0][0]が下限,bounds_lat[0][1]が上限となります. 一方,FORTRANの場合,lat(lat)に対応する境界変数は,下限がbounds_lat(1,lat),上限がbounds_lat(2,lat)となります.一つの有効な例を示すと,座標変数bounds_lat(1)に対応して,bounds_lat(1,1)bounds_lat(2,1)がそれぞれ下限・上限となります.

波長と積雪面積の関数としてのアルビード

アルベドの特性値は,いろいろな波長に対して与えられ,それらはまた積雪深にも依存します:

  dimensions:
    lambda=4; // number of shortwave frequency bands
    snowdepth=10; // number of snowdepth categories
  variables:
    float albedo(lambda,snowdepth); // no units for albedo
      albedo:axis="--";
      albedo:long_name="surface albedo";
    float lambda(lambda);
      lambda:bounds="bounds_lambda";
      lambda:long_name="wavelength";
      lambda:units="nm";
    float bounds_lambda(lambda,2);
    float snowdepth(snowdepth);
      snowdepth:bounds="bounds_snowdepth";
      snowdepth:long_name="mass per unit area of lying snow";
      snowdepth:units="kg m-2";
      snowdepth:valid_max=1e9;
    float bounds_snowdepth(snowdepth,2);
  data:
    lambda=250, 385, 570, 795;
    bounds_lambda=175,320, 320,450, 450,690, 690,900;
    snowdepth=0.05, 0.15, 0.35, 0.75, 1.25, 1.75, ..., 450.0, 1000.0;
    bounds_snowdepth=0.0,0.1, 0.1,0.2, 0.2,0.5, 0.5,1.0,
                     1.0,1.5, 1.5,2.0, ..., 400.0,500.0, 500.0,1e9;

たとえば,lambda軸の最初のインデクス0に該当するセルは「波長が175〜320nm」の範囲になります.また積雪深の一番大きなセルは,「500kg/m2以上」を表し,上限はありません(1e+9を越えると無効値になる).

いくつかの例(たとえばすぐ上の例)では,境界変数はきちんと定義できるにもかかわらず座標変数(点を指定する)の指定が任意性をもっています.こういう場合は,GDTではセルの中央に相当する値をグリッド値として指定するように推奨しています. この方法には2つの利点があります:第一は,境界変数を有するグリッド点の比較には,常にその点が属するセルを決定しなければならないこと,第二は,プロットやグリッド点に対する演算(たとえば微分)に関してはこの方法が適切であると思われること,です.しかしながら,上記の例でいえばsnowdepthのように上限がないセルが設定されている場合,必ずしも中間点という選択は合理的なものとはならないでしょう.

降水量の確率密度関数

  dimensions:
    ppn=10;
  variables:
    float pdf(ppn,lat,lon);
      pdf:axis="-YX";
      pdf:long_name="probability density of "
        "depth of water-equivalent precipitation";
      pdf:units="mm-1";
    float ppn(ppn);
      ppn:units="mm";
      ppn:long_name="depth of water-equivalent precipitation";
      ppn:bounds="bounds_ppn";
    float bounds_ppn(ppn,2);
  data:
    bounds_ppn=0.0,0.1, 0.1,0.2, 0.2,0.35, 0.35,0.5, 0.5,1.0, ...;

pdf[3][10][12]が,「位置lat[10] lon[12]に降水量0.35〜0.5mmの降水が降る確率」を表します.

主座標変数の値が等間隔でない場合,あるいはその座標のサイズが1である場合は,境界変数を設定することを推奨します.一方,主座標変数が等間隔であり,境界変数が指定されていない場合は,通常のアプリケーションでは主座標変数が暗黙的なセルの中央に位置していると仮定することができます. また,境界変数は,主座標変数のみならず,コンポーネント変数や関連変数にも指定することができます.その要素は,対応する主座標変数の要素にきちんと対応するような順番に並べられます.したがって,それらの値は単調でない場合が出てきますし,インデクス0の値と1の値(0オリジンの場合)の前者に小さな値・後者に大きな値が入るというルールも適用されません.

ハイブリッド垂直軸に対する境界値

大気の気柱を,ここでは三つのセルに垂直方向に分割します.それらは「地表〜σ=0.7」「σ=0.7〜20kPa」「20kPa〜大気のトップ」の三つです.これを,セクション17でコンポーネント変数の例として用いたハイブリッド垂直軸を例として設定します:

  dimensions:
    eta=3;
  variables:
    float(eta);
      eta:long_name="pressure-sigma hybrid";
      eta:component="pressure sigma";
      eta:bounds="bounds_eta";
      eta:positive="down";
    float bounds_eta(eta,2);
    float pressure(eta);
      pressure:units="kPa";
      pressure:long_name="pressure";
      pressure:bounds="bounds_pressure";
    float bounds_pressure(eta,2);
    float sigma(eta);
      sigma:long_name="sigma";
      sigma:bounds="bounds_sigma";
    float bounds_sigma(eta,2);
  data:
    eta=0.75, 0.45, 0.05;
    bounds_eta=0.7,1.0, 0.3,0.7, 0.0,0.3;
    pressure=0.0, 10.0, 5.0;  // does not need to be monotonic
    bounds_pressure=0.0,0.0, 20.0,0.0, 0.0,20.0; // note order
    sigma=0.75, 0.35, 0.0;
    bounds_sigma=0.7,1.0, 0.1,0.7, 0.0,0.1;

ここで,bounds_pressure[1][0]bounds_pressure[1][1]より大きいことに注意してください.これは,bounds_pressurebounds_etaと対応するように並べられているからです.

境界変数は,関連付けられた多次元座標変数(セクション18参照)にも設定することができます.この場合,主変数main variableのそれぞれの次元ごとに,境界変数専用にサイズ2の次元を付け加える必要があります.この付加された次元は座標の右(FORTRANの内部表記では左)側につけられ,そして座標と同じ順序になります(訳注:文で書くととても分かりにくいので下の例を参照.実はとても簡単です).

2次元の緯度座標変数に境界変数を設定する例:

    float lat(y,x);
      lat:bounds="bounds_lat";
    float bounds_lat(y,x,2,2);

この例では,bounds_lat[4][5][0][0]が,グリッドボックス[4][5]におけるxおよびyが小さい方の「角」(lower left)の緯度を表します.同様に, bounds_lat[4][5][0][1]は「xが大きくyが小さい」コーナー(lower right), bounds_lat[4][5][1][0]は「xが小さくyが大きい」コーナー(upper left), bounds_lat[4][5][1][1]は「xが大きくyも大きい」コーナー(upper right)の緯度を,それぞれ表します. また,FORTRAN的表記でこの例を示します(配列の添え字のみ書きます)と,これらはそれぞれ (1,1,6,5)(2,1,6,5)(1,2,6,5)(2,2,6,5) となります.


21  サブグリッドヴァリエーションの表現

データ変数は,軸に沿って連続的に変化する物理量を表すのが普通です.が,そうすると,二つのグリッド点間においてもその値にさまざまなパターンの変化が起きているのが一般的です.データ変数自体は当該セルにおけるその物理量の値を示しているにすぎず,グリッド間隔より小さいスケールでの変動,つまりサブグリッドヴァリエーションについては無視されてしまいます.もっとも,多くの用途においては,このデータ変数値をセルの「代表値」として捉え,サブグリッドヴァリエーションがどのようになっているか詳細に明示する必要はないでありましょう.

さて.ある変数の特定の軸に沿ったサブグリッドヴァリエーションを明確に示すためには,subgridアトリビュートをそのデータ変数に付与します. このアトリビュートの最も重要な使用法は,セクション22の縮約次元やcollapsed axesを用いるときに共に用いる方法です. これは文字列型アトリビュートで,スペース区切りの文字列リストとなります.リストの各要素の内容は「name: method」という文字列組で,nameで示される軸に関するサブグリッドヴァリエーションがmethodで示される方法によって与えられることを意味します.このmethodは,Appendix Bに掲げるもののうちから選ばねばなりません(ただしこれらのうちの複数の単語で構成されることもあります):それらは, mean, maximum, minimum, mid-range, standard deviation, variance, mode, median, cell, point です.なお,大文字小文字の区別,パンクチュエーションについては無視されます.Appendix Dと同様に,Appendix BもGDTユーザの要望により拡張されるかもしれません. また,単位の変更を仮定するmethodもあります(Appendix B参照).上記のリストでいうと,varianceがそうです.

さて,pointについてはもうすこし説明します.これは,データ変数の値が各グリッドポイントのみに適用されること,そして該当軸における隣接グリッドポイント間のヴァリエーションに何ら関係ない(代表していない)ことを示しています. また,cellについても説明が必要でしょう.これは,データ変数の値が該当する軸に沿った各セルのそれぞれ全体を代表しているある数値であることを意味しています.これはたとえばセル内における何かの値の和あるいは積分値であるような場合です.

どのデータ変数についても,methodは,複数の軸についてそれぞれ独自に設定することができます. サブグリッドヴァリエーションの設定は,指定された軸についてのみ行われることによく注意してください.たとえば,緯度・経度・時間を軸として持つ降水量の変数について,緯度軸と経度軸についてのみmaximumが設定されていたときは,そのデータ変数は地理的なセル内における降水量の最大値を表すものであり,時間軸については最大をとっていないと解釈されます.

上記に述べたようなサブグリッドヴァリエーションがなんら指定されていない場合,データを扱うプログラムは,それぞれの必要に応じてその変数がどのようなサブグリッドヴァリエーションを持っているか自由に解釈することができます. グリッド点における値を計算する数値モデルにより算出されたデータについては,このようなデータ解釈(サブグリッドヴァリエーションのみつもり)のあいまいさは避けて通れないものです.たとえば,緯度経度場における気温データセットを考えましょう.モデル出力が各グリッド点における気温だった場合,このデータからコンター図を描こうとするプログラムは,ごく普通にはそのデータは「当該の点のみについての値」だと解釈し,そして何らかの補間方法をもちいて各点の間における気温を推定しようとするでしょう.ところが,場全体の平均値を計算しようとするプログラムの場合は,最初のデータの値を「各セルを代表するもの」として捉え,それぞれのセルの面積で重み付けして場全体の平均値を算出するでしょう.どちらの方法も,それぞれの目的にかなったものなのです. また,差分法はその定義によりサブグリッドヴァリエーションについては一切斟酌しませんが,値の扱い方は次の二通りがあります:一つは,各値をあるグリッド点における値だと解釈し,その間の勾配を求める方法です.もう一つは,物理量の保存則を重視し,各値をセル平均値として捉える方法です. ただし,データ値を極値とみなすのは,そう明示されていない限り一般的ではありません.

データ変数がpoint以外のサブグリッドヴァリエーションをもつと指定されているとき,その当該軸に関する座標系をどう設定するかは一意に決まりません. たとえば,時間軸にそった平均を表すデータ変数については,それぞれの値は時間軸上のどの点に対応すると考えればいいのでしょうか? GDTにおいては,各セルの境界がはっきりと定義されている場合には,各データ値に対する座標値を各セルの中央値に定めることを推奨します(セクション20参照).

時間軸におけるサブグリッドヴァリエーションの設定

多くの観測点における12ヶ月分の気圧・気温・降水量データがあるとしましょう.ここに,気圧は瞬間値,気温は最高気温が最高温度計で測定され,そして降水量は雨量計による積算値だとします.1998年4月19日午前6時から48時間分のデータセットは,たとえば次のようになるでしょう:

  dimensions:
    instanttime=5; // 5 instantaneous measurements at 12-hour intervals
    periodtime=4; // 4 intervening 12-hour periods
    station=10;
  variables:
    float pressure(station,instanttime);
      pressure:axis="-T";
      pressure:long_name="pressure";
      pressure:subgrid="instanttime: point";
      pressure:units="kPa";
    float maxtemp(station,periodtime);
      maxtemp:axis="-T";
      maxtemp:long_name="temperature";
      maxtemp:subgrid="periodtime: maximum";
      maxtemp:units="K";
    float ppn(station,periodtime);
      ppn:axis="-T";
      ppn:long_name="depth of water-equivalent precipitation";
      ppn:subgrid="periodtime: cell";
      ppn:units="mm";
    double instanttime(instanttime);
      instanttime:long_name="time";
      instanttime:units="h since 1998-19-4 6:0:0";
    double periodtime(periodtime);
      periodtime:bounds="bounds_periodtime";
      periodtime:long_name="time";
      periodtime:units="h since 1998-19-4 6:0:0";
    double bounds_periodtime(periodtime,2);
  data:
    instanttime=0., 12., 24., 36., 48.;
    periodtime=6., 18., 30., 42.;
    bounds_periodtime=0.,12., 12.,24., 24.,36., 36.,48.;

ここで,station軸にはsubgridアトリビュートを設定するのは不適切です.というのはこれは一つにはバンドルされた座標変数だからであり(セクション 19参照),また,連続物理量ではないからでもあります. 瞬間測定と定時測定の値はそれぞれ異なる時間軸を持たねばなりません.これは一つには次元が異なるからであり,そして必ずしも観測が同時に行われるわけではないからです.ただし,仮に気圧の観測が気温の定期観測が2回行われるちょうど中間の時刻に行われるなら,時間軸の共有は可能です. 降水量については積算量で与えられるため,各時間間隔における合計と定義します.なお,たとえば変数ppnsubgirdcellでなくmeanと設定した場合,この値は降水強度mm h-1として表され得るでしょう.

厚さ(geopotential difference)

ここでいう「厚さ」とは,大気中における二つの気圧面間におけるジオポテンシャルの差のことです.この値は,定義により,垂直軸に沿った各セルの範囲全体に関係します.

  variables:
    float thickness(pressure,lat,lon);
      thickness:long_name="thickness";
      thickness:subgrid="pressure: cell";
      thickness:units="m2 s-2";
    float pressure(pressure);
      pressure:bounds="bounds_pressure";
      pressure:long_name="pressure";
      pressure:units="hPa";
    float bounds_pressure(pressure,2);

ここに,bounds_pressure[0][0]およびbounds_pressure[0][1]はそれぞれ厚さを表す変数の一つの要素thickness[0][*][*]に該当する大気コラムの上端と下端を表します.

複数のsubgridアトリビュートが設定されたときは,それが現れた順番に適用されます.つまり,もっとも左に書いてあるmethodがまず最初に適用されます. 経度軸および時間軸についてサブグリッドヴァリエーションをもつ変数を考えてみましょう(ここに,経度軸の変数名はlon,時間軸変数名はtimeとします). たとえばそのサブグリッドヴァリエーションが「セル内における経度方向の最大値の時間方向平均」(time-average of the zonal maximum)ならば,そのsubgird"lon: maximum time: mean"と定義されます.つまり具体的に言うと,セル内の各時刻において経度方向にもとのデータ値を見てその最大値を探し,しかる後にその(セル内各時刻における)最大値を今度は時間方向に平均したのがその変数値であると解釈されるのです./ 今度はそのサブグリッドヴァリエーションが「時間方向平均の経度方向最大値」(zonal maximum of time-averages)ならば,話は変わってきます.今度はsubgird"time: mean lon: maximum"と定義されます./ なお,複数のmethodが指定され,かつ順番をどう書いてもその意味が変わらない場合は,それらはどの順番に並べても差し支えありません.

データ値が複数の軸にわたるサブグリッドヴァリエーションを反映している場合,subgirdアトリビュートには関係する軸全てを並べ(順序は任意です)同一のmethodを付与します.それぞれの軸にそれぞれmethodを付与する場合にくらべて全く違う結果となるときのみ,複数の軸を上記の方法でグルーピングすることができます. 例を挙げましょう.緯度経度場における地表面高度についてグリッド内の標準偏差を表す変数についてはsubgird"lat: lon: standard deviation"と設定します.これは"lon: standard deviation lat: standard deviation"とは全く異なるということに注意してください.後者はグリッド内を経度方向に分けた各矩形内の標準偏差をとったその後に,今度は(今計算した)緯度が異なる各矩形に対する標準偏差値の標準偏差をとるのです.

サブグリッドヴァリエーションがどのように適用されているかより詳しく記述するためには,subgridアトリビュートの中でmethodを指定した後にカッコをつけ,その中に詳しい情報を書きます.ただしこれはまだ標準的な方法ではなく,全てのアプリケーションがこれに対応する必要はありません. たとえば,緯度方向の平均値は面積で重み付けられている場合があります(訳者注:緯度ごとにグリッド面積が変わる効果を織り込んでいる場合).これは"lat: mean (area-weighted)"というsubgirdを設定することになります

データ変数についてのsubgridアトリビュートは,その変数が含んでいない軸にそってのサブグリッドヴァリエーションを表現するのに用いることはできません.もしこのようなことを行いたければ,long_nameアトリビュートをその代わりに使うことができます.ただ,その目的に合ったsingleton dimensionを導入したほうがより情報が豊富で詳細になるでしょう. たとえば,ある変数についてその示す値が単なる時間的変動であるとlong_name中に書くことも可能ではあります.しかし,同じことをサブグリッドヴァリエーションの形で記述した方がもっと情報が豊富になります.つまり,その変数に時間を表すsingleton dimensionをつけ,その軸に沿ったサブグリッドヴァリエーションを設定するのです.この新たな軸は,また,時間軸がカバーする範囲や時間変動を計算するのに使った時間間隔を表すのにも用いることができます(we could describe a quantity in its long_name as being simply a temporal variance, but it would be more informative to record it as a subgrid method, by giving the variable a singleton time dimension, which could also be used to should the range of times it covers and the time-interval of the data from which the variance was calculated.).これについてはセクション22も参照してください.


22  縮約次元Contracted dimensions

A contracted axis is one which is formed by aggregating the values of an axis with a larger dimension into a smaller number of groups. In the commonest case, the dimension is collapsed completely to a singleton dimension (i.e. a size of unity, section 9), where all data points share the entire collapsed axis. The collapsed dimension indicates the relationship of the data variable which is being described to another variable of higher dimensionality. The boundaries of the cells along a contracted axis will be the outside boundaries of the groups of cells along the uncontracted axis, or the outside coordinates if boundaries were not given. The main coordinate values of a contracted axis will be values representative of the coordinate ranges spanned by the groups. A collapsed dimension has a single representative main coordinate value and boundary coordinate values supplying the complete range of the uncollapsed axis. These boundaries will be the extreme boundary coordinate values of the uncollapsed axis, or the extreme main coordinate values if boundaries were not supplied. A very important application of collapsed axes is to indicate climatological time. This is discussed in section 28.

The subgrid attribute (section 21) of the data variable with contracted axes can be used to indicate how the data values of the variable with uncontracted axes were aggregated to reduce the dimensions. The new subgrid information will be appended to the existing attribute, if any, indicating the name of the newly contracted dimension. Any existing references to the uncontracted dimension in the subgrid attribute should be modified to refer to the contracted dimension, since the uncontracted dimension will no longer be a dimension of the data variable.

As explained in section 21, this attribute will indicate that the data value is the mean, maximum, minimum, etc. The allowed subgrid ``methods'' are listed in Appendix B, which will be expanded as need arises. As foreseen at the moment, the idea is limited to operations which give a single value representative of each contracted group of values, without reference to any external constants. For example, the number which exceeds 20% of the values in the group, or equivalently the 20th percentile, is a single number representing the group, but the procedure of finding it is not treated as a subgrid method because it requires the constant 0.2 to define it. Instead, the relationship of this new variable to the old should be shown by changing its long_name to indicate that it is a percentile value, and giving it a new singleton percentage axis with value 20, or cumulative probability with value 0.2. This kind of transformation is analogous to reducing a variable on three spatial dimensions (say) to two by extracting its values on a specified surface. The contraction or collapse is a special case, because, in general, the percentile axis need not have a size of unity; it might be a new multi-valued axis (in cumulative probability) replacing the old one (in some spatial dimension, for instance). This is like regridding a vertical axis of height onto pressure. Having said all this, however, we note that median is in fact a named instance of this operation-extraction of the 50th percentile-but we allow it on the grounds that it is a common method for choosing a single representative value.

Singleton axes are not necessarily the result of collapsing an axis. In section 9, we recommend singleton axes as the means of attaching characteristic single physical values to a data variable, for instance the height or pressure of the surface on which a variable is supplied. If no subgrid method is specified, the application knows only that the single value characterises the data in some way. All information in the subgrid attribute is entirely optional. For instance, a time-mean quantity should generally have a singleton time dimension to indicate the range of times to which it applies, but it is not mandatory to indicate in the subgrid attribute that it is a mean over time.

On the coordinate variable of a contracted axis, the optional old_interval attribute specifies the typical spacing between two adjacent coordinates of the uncontracted axis, where ``typical'' is not well defined. The old_interval attribute should be given in the same units as the coordinates. Further information may be given by the the optional old_spacing attribute, which may have value uniform, indicating that the coordinates were evenly spaced with the old_interval specified (if any) and the cells contiguous, or variable, if they were not evenly spaced but still contiguous, or disjoint, which means there may have been gaps between them. The coordinates of the uncontracted axis may be explicitly recorded in separate variables; if so, the main uncontracted coordinate variable should be named by the attribute expand of the main contracted coordinate variable.


Area-averaging a longitude-latitude field to one of lower resolution: The original resolution was 1 degree, and the field has been averaged into 10-degree boxes.

  dimensions:
    con_lat=18; // contracted dimension
    con_lon=36;
    lat=180; // original uncontracted dimension
    lon=360;
  variables:
    float sst(con_lat,con_lon);
      sst:axis="YX";
      sst:long_name="sea surface temperature";
      sst:subgrid="con_lat: mean con_lon: mean";
      sst:units="degC";
    float con_lat(con_lat); // contracted latitude axis
      con_lat:bounds="bounds_con_lat";
      con_lat:expand="lat";
      con_lat:old_interval=1.0f; // original resolution in latitude
      con_lat:long_name="latitude";
      con_lat:units="degree_north";
    float bounds_con_lat(con_lat,2);
    float lat(lat); // original uncontracted latitude axis
      lat:bounds="bounds_lat";
    float bounds_lat(lat,2);
  data:
    con_lat=-85, -75, -65, ...;
    bounds_con_lat=-90.,-80., -80.,-70., -70.,-60., ..., 80.,90.;
    lat=-89.5, -88.5, -87.5, ...;
    bounds_lat=-90,-89, -89,-88, -88,-87, ..., 89,90;
Instead of an area-average, the contracted field might instead have represented the subgrid spatial variation of SST. In that case, subgrid="con_lat: con_lon: standard deviation".


Mean over time and longitude: Here, the time-mean zonal-mean humidity is given as a function of latitude and height. The means have been formed over the complete time and longitude intervals of the original data, so these dimensions are collapsed.

  dimensions:
    con_lon=1; // collapsed longitude dimension
    con_time=1; // collapsed time dimension
    lon=72;
    sigma=6;
  variables:
    float humidity(con_time,sigma,lat,con_lon);
      humidity:axis="TZYX";
      humidity:long_name="specific humidity";
      humidity:subgrid="con_time: mean con_lon: mean";
    double con_time(con_time);
      con_time:bounds="bounds_con_time";
      con_time:old_interval=0.125; // originally at intervals of 3 h
      con_time:units="days as %Y%m%d.%f";
    float bounds_con_time(con_time,2);
    float con_lon(con_lon);
      con_lon:bounds="bounds_con_lon";
      con_lon:long_name="longitude";
      con_lon:modulo=360f;
      con_lon:topology="circular";
      con_lon:units="degree_east";
    float bounds_con_lon(con_lon,2);
    float sigma(sigma);
      sigma:bounds="bounds_sigma";
      sigma:long_name="sigma";
    float bounds_sigma(sigma,2);
  data:
    con_time=19960901.0;
    bounds_con_time=19960301.0, 19970301.0;
    con_lon=180;
    bounds_con_lon=0, 360;
    sigma=0.99, 0.96, 0.92, 0.8, 0.5, 0.1;
    bounds_sigma=0.98,1.00, 0.94,0.98, 0.86,0.94,
                 0.65,0.86, 0.30,0.65, 0.05,0.30;
This is a mean over the complete range of longitude from 1 March 1996 to 1 March 1997 (see section 25 concerning the time coordinate). The longitude axis indicates circular topology because this was the case before it was collapsed; after collapse, the topology is not really meaningful. If the humidity was subsequently meaned over the depth of the atmosphere as well, subgrid would be suffixed with con_sigma: mean, and con_sigma would have bounds 0.05 and 1.00.

If the same axis is contracted repeatedly, the methods may all be recorded in the subgrid attribute of the data variable, but only the most recent old_interval and old_spacing will be shown on the contracted coordinate variable. But if the axis before contraction is retained in the file (identified by an expand attribute), and was itself the result of a contraction, it can record the previous old_interval and old_spacing.

Repeated operations of some methods can be regarded as equivalent to a single operation. For instance, meaning longitude cells of 1 degree width to 5 degrees, and then from 5 to 45 degrees, gives the same result as meaning in one step from 1 degree to 45 degrees (apart from complications with missing data). Similarly, meaning a time axis from days into months, then into seasons, and finally into years could be represented as a single operation of meaning from days to years. In that case, the subgrid, old_interval and old_spacing attributes need not be modified for successive operations. The choice of whether to take this approach is left to the application.


23  時間変数と時間間隔

 「時間変数」とは,日付や時刻を表す変数のことで,以後は単に「時間」ないし「時刻」と呼ぶことにします.また,「時間間隔」とは二つの「時刻」の間の時間を表します.

 netCDFで時間を表すとすれば,たとえば種々の型の6つのコンポーネント変数を使い,そのコンポーネント(年・月・日・時・分・秒)を成分して表すことが可能でありましょう.しかしながら,もっと有効で,そして多くの用途にとってはより便利な方法があります.それは,時刻を一つの値で表すことです.この値は,時刻をある基準時刻からの経過時間として表したものです.基準時刻は暗黙に定められる場合も明示的に指示する場合もあります.ここで,私たちは年月日時分秒のコンポーネントからこの単一時刻値に変換することを「エンコード」,その逆を「デコード」と書くことにします.エンコードとデコードは,簡単な作業ではありません.というのは,年と月は固有の長さを持った単位であり,しかもその長さはそれぞれの日付や使用しているカレンダー(暦システム)に依存するからです.ですから,時間軸の設定に当たっては特別な準備が必要になります.

 「カレンダー」は有効な年・月・日の集合を定義します.標準で使われるカレンダーはグレゴリオ暦(Gregorian)で,これはudunitsで定義されているカレンダーでもあります.ただし,気象モデルが常にこのカレンダーを使うとは限りません.たとえば,Hadley CentereのGCMで使用しているカレンダーでは,各月が30日固定となっています.長さが一定の単位(日・時・分・秒)を用いて測った2時刻間の時間差は,カレンダーごとに異なる場合があります.これはカレンダーごとに有効な年月日の組み合わせが異なるからです.たとえば,「1996年2月1日」から「同年3月1日」までの時間間隔は,もちろん「1ヶ月」ではありますが,しかし標準カレンダーでは「29日」,Hadley Centre GCMのカレンダーでは「30日」と異なる値を取ります.これは,後者では「2月30日」という日付も有効になっているからです.

 それゆえ,時刻をelapsed intervalにエンコードすることは,カレンダー依存となり,エンコードの際にはカレンダーの種類がわからないといけないということになります.さて,GDTでは標準カレンダー(セクション26参照)もそうでないカレンダー(セクション27参照)も選択できるようになっています.これに続くセクションで説明するアトリビュートcalendarは,該当する時間軸で使用しているカレンダーを明示するものです.もし時間軸の座標変数にcalendarアトリビュートが設定されてないのであれば,グローバルアトリビュート(セクション5参照)のcalendarを探し,もしそれが設定されていたらその設定を採用します.

 時刻を値に換算する「エンコード」については,GDTでは二つのやり方を認めています.それらは,「相対時間」と「絶対時間」で,アトリビュートunitsで見分けることができます.これらは,後に続くセクション(セクション24 および セクション25)で説明しています.相対時間の方がどちらかというと馴染み深いものですが,絶対時間の方にも重要な利点があります.

 時間変数はtime_formatアトリビュートを持つ場合があります.これは,日付・時刻をプリントする場合のフォーマットを指示するもので,UNIXTMdate命令におけるフォーマットに従ったものです.

 なお,時間軸に関する座標変数は,かならずunitsアトリビュートが設定されていなければなりません.このアトリビュートにはデフォルトの値はありません.


24  相対時間

 相対時間としてエンコードされた時間とは,ある基準時刻からの経過時間を表すものです.この場合,アトリビュートunitsは,time-unit since reference-timeの形をとります.これはUnidata udunitsパッケージの推奨記法によるものです(ただし,time-unitについては下記を参照). 例:unitsの値がseconds since 1992-10-8 15:15:42.5である場合,この時間軸の値で表される時刻は「1992年10月8日15時15分42.5秒(GMT:なお,タイムゾーン自体も扱うことができます)からの経過時間」となります.

 相対時間の時間軸におけるデコードのためには,普通はカレンダーの指定がなければなりません.逆にいえば,エンコードされて単一の値となった時間値は,カレンダーに関する情報がなければ何の意味もないのです.さらに言えば,同一の時間値を同一のunitsでデコードするという条件下でも,カレンダーが異なれば違った答えが得られる場合があります. 例:1996-2-1 15:00:00という値をunits=days since 1995-12-1 0:0:0でデコードすると,標準カレンダーでは62.625days since 1995-12-1 0:0:0となりますが,360-dayカレンダーでは60.625days since 1995-12-1 0:0:0となります.

 udunitsのファイルudunits.datでは,second, minute, hour, dayを時間の単位として認めています.ただし,GDTではyear, monthの使用を認めていません.というのは,これらは定義があいまいだからです.udunitsでは年をtropical year,つまり31556925.97秒(365日より674.03秒短い),月を年のちょうど1/12としてそれぞれ定義していますので,これらの単位の使用は,ことによると予期せぬ結果が得られることにつながりかねないのです. たとえば,1 month since 1995-4-1 0:0:0とは,30.4368 days since 1995-4-1 0:0:0であり,これはおおよそ1995-5-1 10:29に該当します.1995-5-1 0:0:0ではないのです(!).同様に,1 year since 1995-4-1 0:0:0とは,1996-4-1 0:0:0ではなく,おおよそ1996-3-31 5:49となってしまいます. udunitsの単位common_yearはちょうど365日という意味で,これも一応認められていますが,お勧めはできません.

 ある量の瞬間測定値を表す相対時間軸

ここでは,1996年11月2日〜5日の各日正午に測定が行われたとしますと,次のように軸を定義することになります:

  dimensions:
    time=4;
  variables:
    double time(time);
      time:long_name="time";
      time:units="days since 1996-1-1 0:0:0";
  data:
    time=1.5, 2.5, 3.5, 4.5;

月平均値を表す相対時間軸

ここでは,1990年の2,3,4月について,それぞれ月平均値が得られている場合のCDLはこのようになります:

  dimensions:
    time=3;
  variables:
    double time(time);
      time:bounds="bounds_time";
      time:long_name="time";
      time:units="days since 1990-1-1 0:0:0";
    double bounds_time(time,2);
  data:
    time=45.0, 74.5, 105.0;
    bounds_time=31.0,59.0, 59.0,90.0, 90.0,120.0;

この例では,時間軸の主座標変数は,各月のちょうど真中の日の値であり,単なる代表値にすぎません.これらをデコードすると,それぞれ1990-2-15 0:0:0, 1990-3-16 12:0:0, 1990-4-16 0:0:0となります.


25  絶対時間

 絶対時間を用いて時間をエンコードする方法では,固定した単位を持つ一つの値を用いて時刻を表すのではなく,複数のコンポーネント(訳注:各コンポーネントの値をそのまま活かした十進整数および小数)で時刻を表します.これは二つの利点を持ちます:[1]エンコードされた時間はそれ自体意味がわかりやすく,カレンダーに関する情報がなくとも時間のコンポーネントにデコード可能です.ただし,二つの時刻間の時間間隔を算出するのには依然としてカレンダーに関する情報がひつようとなりますが.[2]「部分的」な時間表現が可能となります.すなわち,「年」・「季節」(年内における時間や,季節内における時間)・「日内時刻」(日内の時刻・日周期内の時刻)などを必要としない時刻表現が可能になるのです.一方,相対時間表現ではつねに上の三つの内容を全て含んだ「完全な」時刻表現が必要となります.

 絶対時間表現では,unitsアトリビュートに,time-unit as time-stringという値を設定します.取りうるデータの種類とその意味を次の表に示します:

Format Data type Interpretation
second as %S.%f float Diurnal phase
minute as %M.%f float Diurnal phase
hour as %H.%f float Diurnal phase
day as %Y%m%d.%f double Time
day as %Y%m%d int Year and seasonal phase
day as %m%d.%f double Seasonal phase and diurnal phase
day as %m%d int Seasonal phase
day as .%f float Diurnal phase
calendar_month as %Y%m.%f double Year and seasonal phase
calendar_month as %m.%f float Seasonal phase
calendar_year as %Y.%f double Year and seasonal phase
calendar_year as %Y int Year
calendar_year as .%f float Seasonal phase
単位名については,標準的な省略記法や複数形も通常どおり利用可能です.なお,GDTでは,時間単位としてcalendar_yearおよびcalendar_monthも独自に定義しています(Appendix C参照).

 上記time-string codeは,年・月・日・時刻をどのように一つの値にエンコードするか指定する文字列です.この文字列はUNIXTMdateprintfコマンドと同じ方式を用います.

Format letter Interpretation
%Y 年(4桁)
%m 月(2桁.01=1月)
%d 日(2桁)
%H
%M 分(0時0分からの)
%S 秒(0時0分からの)
%f 指定単位の端数を小数で表したもの
. 十進の小数点
エンコードされた値は単なる数値であるため,整数部分の頭のゼロは省略できます.データの型については精度の点から推奨しているものですが,強制ではありません.もし端数%fを含むと指定されているはずの値に整数型が使われていたら,その端数は0とみなされます.逆に,端数%fを含んでいないはずの値に浮動小数点型が指定されていたら,その小数点以下(端数)は無視されます.

 絶対時間においては,「1998年4月5日午後3時」は値が19980405.625unitsアトリビュートがday as %Y%m%d.fとエンコーディングされます.このエンコード法の利点は,カレンダーに関する情報が全くなくてもエンコードが可能であるという点です.一方,相対時間軸を用いてunits=days since 1900-1-1でこの時刻をエンコードする場合,その値は標準カレンダーでは36888.625,360-dayカレンダーでは35374.625と異なる値になります.また,絶対時間軸のもう一つの長所は,たとえば19980605.625は上記19980405.625の正確に2ヶ月後であり,また19970405.625はちょうど1年あとであるといったことが,カレンダーに関する知識がなくてもわかるという点です.しかし,他の時間単位−日数・時間等−でこの間隔を表現するには,やはりカレンダーに関する知識が必要になります.

 絶対時間を表す唯一の完全な形式はday as %Y%m%d.fです.とくに注意していただきたいのは,calendar_month as %Y%m.fcalendar_year as %Y.fは部分時間値であり,日内の時間に関しては情報をもっていないという点です(Note in particular that the forms "calendar_month as %Y%m.%f"and "calendar_year as %Y.%f" are partial times which imply no information about the diurnal phase. ). これは極めて重要なポイントです.たとえば,1998.25 calendar_year as %Y.%fは「1998年という1年分の時間のうち1/4経過したときの時刻」を表すものであり,それ以上の意味はもっていないのです.この意味はグレゴリオ暦でも360-dayカレンダーでも全く同じ意味です.この表現方法では日内の時刻に関しては何も情報がありませんので,この値を,グレゴリオ暦の場合1998-4-2 3:00:00(つまり年の初めから91.25日あと),あるいは360-dayカレンダーの場合1998-4-1 0:00:00のようにデコードしなおすことはできません. 同様に,199804.3 calendar_month as %Y%m.%fは「1998年4月の時間が30%経過した時刻」です.この部分時間値の使い方を,以下の例で示しています

 月・日・時分秒をもつ唯一の部分時間値表現はday as %m%f.%fです.月と日をcalendar_yearやcalendar_monthの端数として表し,同時に日内の時分秒をも表すという方法はありません.それが必要な場合には,アプリケーションは2成分のコンポーネント関数として時刻を表すことになります. この制限は合理的なもののようです.というのは季節サイクルや日周期は既知のカレンダーに依存しなければならず(たとえば,1年が何日であるか明示しなければならない),季節サイクルは月・日でもって表せるからです(This exclusion seems reasonable because data which resolves both the seasonal and diurnal cycles must belong to a known calendar (it will exhibit a certain number of days in a year, for instance) and so its seasonal cycle can be labelled by month and day.). カレンダーに依存しない季節サイクルの表現法を下の例に示しましたが,これは季節サイクルの一部が平均されているとき,つまり季節サイクルと日サイクルがもし両方あればそれらが異なる軸に関連付けられているという場合にさらに有効な手段となります(The calendar-independent representations of the seasonal cycle, shown in examples below, are more useful when portions of the seasonal cycle have been averaged, in which case the seasonal and diurnal cycles, if both present, will be on separate axes).

 time-stringに端数.%fを含まない部分時間値は離散的な変数です. このような形式の一つを用いた時間軸によりコンバートされた,日あるいは年で数えた時間間隔のカウントには,軸の両端をもそのカウントに含めます.あるいは軸両端の時間差に1を加えると言ってもよいでしょう. たとえば,unitscalendar_year as %Yと設定された時間軸を考えてみましょう.この軸の範囲が1930から1939までだったとすると,その(時間)範囲は「10」年となります.「9」(訳注:1939と1930の差)年ではありません.これは軸の両端が範囲に含まれるからです.この表記法では単に年だけを表し,年内の時間(月・日など)は一切含まれません. 逆に季節サイクルが入った軸も対照として考えてみましょう:たとえばunitscalendar_year as %Y.%fとなっている場合で,値の範囲が1930.0から1939.0となっているとします.この軸は,今度は9年分の範囲しかありません.というのは,軸は「1939年の始め」から始まり,「1939年の始め」で終わるので,1939年そのものが範囲に含まれないからです.下記の例では,この点をさらに詳しく説明しています.

瞬間測定値を表す絶対時間軸

1996年6月2日〜5日の各正午に観測が行われたとします.このとき,時間軸の設定は次のようになるでしょう:

  dimensions:
    time=4;
  variables:
    double time(time);
      time:long_name="time";
      time:units="days as %Y%m%d.%f";
  data:
    time=19960602.5, 19960603.5, 19960604.5, 19960605.5;

月平均値を表す絶対時間軸:日でエンコード

  dimensions:
    time=3;
  variables:
    double time(time);
      time:bounds="bounds_time";
      time:long_name="time";
      time:units="days as %Y%m%d.%f";
    double bounds_time(time,2);
  data:
    time=19900215.0, 19900316.5, 19900416.0;
    bounds_time=19900201.0,19900301.0, 19900301.0,19900401.0,
                19900401.0,19900501.0;

相対時間で表した同じ例の場合と同様に,時間軸の主座標変数が表すのは各月の中間の日付です.これらはごく素直にエンコードされているのですが,しかしカレンダー依存です.もしこれらの月の平均値を,違うカレンダーを用いたデータソースからのデータと比較しようとする人がいた場合は,この方式は不便です.その不具合を除いたのが次の例です:

月平均値を表す絶対時間軸:月でエンコード

  dimensions:
    time=3;
  variables:
    double time(time);
      time:bounds="bounds_time";
      time:long_name="year and seasonal phase";
      time:units="calendar_months as %Y%m.%f";
    double bounds_time(time,2);
  data:
    time=199002.5, 199003.5, 199004.5;
    bounds_time=199002.0,199003.0, 199003.0,199004.0, 199004.0,199005.0;

時間軸の主座標変数は,各月の中間を直接表していることがはっきり分かるでしょう This method shows directly that the main coordinates are half-way through their months.

年だけを表す部分時間値

この主の軸は,たとえば何らかのイベントが年に何回起こったかというようなデータに用いられるでしょう.

  dimensions:
    year=3;
  variables:
    int year(year);
      year:long_name="year";
      year:units="calendar_year as %Y";
    int count(year);
  data:
    year=1991,1992,1993,1994,1995;
    count=0,2,1,0,1;

前述したとおり,この時間軸は5年間という範囲を取ります.ここで,変数countはそれぞれ単一の年に該当するので,境界は設定しません.したがって,変数yearの上限と下限は,各yearの値に一致します.

「年」をベースに定義した年・季節サイクル

すぐ上の例とは異なり,もし各時間座標値に対するデータ値がその年連続的な時間全体に関連付けるのがふさわしい場合は,次のようにします

  variables:
    double year(year);
      year:bounds="bounds_year";
      year:long_name="year and seasonal phase";
      year:units="calendar_year as %Y.%f";
    double bounds_year(year,2);
    int count(year);
  data:
    year=1991.5, 1992.5, 1993.5, 1994.5, 1995.5;
    bounds_year=1991.0,1992.0, 1992.0,1993.0, 1993.0,1994.0,
                1994.0,1995.0, 1995.0,1996.0;
    count=0,2,1,0,1;

年を浮動小数点で表す手法は,各年の始まり・終わり・中間点などを明確に指示する場合に便利な方法です.もちろん,グレゴリオ暦の場合には「1992.0」と「1993.0」の間の時間間隔はその他の年の間の時間間隔より長くなります.しかし目的によっては,各時間間隔が暦年であると記録した方がさらに有効でしょう.これはとりわけ,他のカレンダーを使用しているデータセットとの比較に有効です(But for some purposes, it might be more useful to record that each interval is a calendar year. This could be especially helpful when comparing data from different calendars.).

年の関数として季節サイクルを指定する

特定のイベント,たとえば日最高気温・モンスーンのオンセットなどの生起日を年内の部分時間値として定義する方法を紹介します:

  dimensions:
    year=5;
  variables:
    int year(year);
      year:long_name="year";
      year:units="calendar_year as %Y";
    int date(year);
      date:long_name="seasonal phase";
      date:units="day as %m%d";
  data:
    year=2011, 2013, 2027, 2028, 2051;
    date=629, 627, 626, 703, 710;

このイベントは,2011年6月29日,2013年6月27日,2027年6月26日,2028年7月3日,2051年7月10日に起きました.明らかに,date変数は完全な時間値−相対時間軸の場合もあります−で指定することが可能です.しかし,そうすると余計(不要)な「年」情報が入ってしまうことになります.

 季節サイクルを指定し,しかし年情報を含まないという時間変数は,つまり1年をmoduloとして合同なわけです.もしその範囲が1年を完全に覆う場合,それは循環的circularなトポロジを持ちます.同様に,月・日情報をもたず日周期だけを表す時間変数は1日を法として合同です.この種の時間座標は,とりわけ縮約次元と共に用いて気候値を表す時間軸を表すのに有効です.詳細はセクション28を参考にしてください.

「月」をベースに表した平均季節サイクル

太陽放射の3ヶ月平均を表す時間軸設定例です:

  dimensions:
    time=4;
    lat=72;
    lon=96;
  variables:
    float sol(time,lat,lon);
      sol:axis="TYX";
      sol:long_name="vertical component of "
        "solar radiative flux density";
      sol:units="W m-2";
    float time(time); 
      time:bounds="bounds_time";
      time:long_name="seasonal phase";
      time:modulo=12.0f;
      time:topology="circular";
      time:units="calendar_month as %m.%f";
    float bounds_time(time,2);
  data:
    time=10.5, 13.5, 16.5, 19.5;
    bounds_time=9.0,12.0, 12.0,15.0, 15.0,18.0, 18.0,21.0;

時間軸の最初の点は,「9月の最初」から「12月の最初」に関連付けられます.つまり9月〜11月を表します.主座標変数の値は10月の中間として与えられています.同様に,2番目の時間軸点は「15月」,つまり3月(moduloアトリビュートの設定により,12を法としているので)のはじめまでをカバーします.つまり12月〜2月というわけです.このようにmoduloアトリビュートを用いることにより,主座標変数を−普通そうすることが求められているように−単調増加(or単調減少)にすることが可能になります.軸のトポロジ(アトリビュートtopologyで指定)がcircularですので,別の季節から始まるように値を回転させることも可能です(Because the axis is also circular, it would be permissible to rotate the values in order to begin with a different season.).

「年」をベースにして表した平均季節サイクル

上記の例は,また「年」をベースにして同様に上手く設計することが可能です:

  dimensions:
    double time(time); 
      time:bounds="bounds_time";
      time:long_name="seasonal phase";
      time:modulo=1.0;
      time:topology="circular";
      time:units="calendar_year as .%f";
    float bounds_time(time,2);
  data:
    time=0.7917, 1.0417, 1.2917, 1.5417;
    bounds_time=0.6667,0.9167, 0.9167,1.1667,
                1.1667,1.4167, 1.4167,1.6667;

ここでは,最初の期間は年の2/3から始まり,各期間が正確に「1年の1/4」となるように設定されています.360-dayカレンダーにおいては,この指定は上記の例−各期間が3ヶ月で,最初が9月1日から始まる−と全く同じになります.しかしグレゴリオ暦(標準カレンダー)ではほんの少しですが異なります.というのは「1年の1/4」が正確には3ヶ月ではないからです.


26  グレゴリオ暦

 GDTでは,時間軸の表記法として,「グレゴリオ暦(Gregorian)で表した時間をdays as %Y%m%d.%fで表す」(セクション25参照)手法を推奨しています.ただし,絶対時間を取り扱えないアプリケーションとの互換性を取ることが必須であるばあいは,この限りではありません.この場合には,グレゴリオ暦ではかった時間を,Unidata udunitsパッケージの推奨法に従った時間表記−単位と基準時間を明示した相対時間(セクション24参照)−で表すことになります. グレゴリオ暦表記における単位はdays,データ型はdoubleとしてください.

 二つの時刻間の,グレゴリオ暦における時間間隔はUnidata udunitsパッケージを用いて計算することができます. udunitsでは,英国での例のようにグレゴリオ暦/ユリウス暦の混合カレンダー系を実装しています.このカレンダー系では,1582-10-15以前はユリウス暦であるとみなされます.他のソフトウェアでは同じやり方でカレンダー系の変化に追従しているかどうかは確かではありません.したがって,時間軸の確実性を増すためには,基準時刻を1582年以降の時点に設定した方がいいでしょう.もしそれより古い時間を扱う必要がある場合には別の注意もあります:unidataはA.D.0年をA.D.1年として扱うということです.

 double型の数値は,おおよそ10進16桁の精度があります.したがって,時間軸にこの型の数値を用いると,相対時間では100万年のオーダーまで0.1秒単位の制度を持つことができます.一方絶対時間においてはすこし精度がおちます.というのは,一年を365日でなく10000日であるかのように扱うからです.年の値が大きくなると,絶対時間における時間変数の精度は悪くなります.もし非常に大きな年の値を取り扱い,変数の精度が足りなくなった場合は,基準時刻を変更して,時間値が小さくなるように(十分な精度が得られるように)しなければなりません.

 時間変数に対してcalendarアトリビュートが設定されていない場合,デフォルトで正規グレゴリオ暦が仮定されます.これは,このアトリビュートをstandardないしgregorianに明示的に設定しても同じ効果が得られます.


27  グレゴリオ暦以外のカレンダー

 グレゴリオ暦以外のカレンダーにおいては,時間値はdays as %Y%m%d.%fという単位のDouble型数値で表すことが推奨されます(セクション25参照). 相対時間として軸を設定することも許されています.この場合units(の基準時刻)としてはdays since 1-1-1,変数の型はdoubleが推奨されます.Unidataのudunitsパッケージは標準カレンダーしか取り扱っていませんので,それ以外のカレンダーにおいては相対時間を取り扱うのにいくらかの拡張が必要になります.

 さて,グレゴリオ暦以外にGDTで認めているカレンダーは,julian(ユリウス暦.4で割れる西暦年はすべてうるう年となる),noleap(毎年が365日),360(毎月が30日),です.もし他の種類のカレンダーが用いられた場合,適切な記述をcalendarアトリビュートに書き込む必要がありますが,一般的なアプリケーションがそのカレンダーにおいて相対時間のエンコード・デコードを正しく行ったり,2時刻間の時間間隔を計算したりすることができるとは期待できないでしょう.


28  多重時間軸Multiple time axes と気候値を表す時刻値climatological time

一つのデータ変数が,特定の量に関して二つ以上の次元を持つことは,各々の次元に異なる名前がついている限り,許されます. この手法が役立つ際立った例としては, 時間軸を,いくつかがcollapse(セクション 22参照)していることがある複数の部分的な時間次元に分解(セクション 25参照)する場合です[A particular use of this is to decompose time into multiple partial time dimensions(section 25), of which one or may be collapsed (section 22).]. 季節サイクルや日サイクルの対応する部分に属する不定間隔の時刻を表すことが,これにより可能になります. ある変数が2ないし3個の時間軸を持つとき,これらの[統合]時間軸の最初の時刻間隔(first interval of time)は,全軸の最も早い時刻から始まるものと仮定されます. 時間軸のうち一つがuncollpasedで,他がcollapsedであるとき,その軸は「気候値を表す仮想の時刻」を表す軸となります. 気候値を表す時間軸は一つでない場合があります.下記の例参照.

COARDSは気候値を表すためには年の値に0を用いるように推奨しています. しかし我々はこれに賛同しません. まず,これではその気候値の作成にどの年度のデータが用いられたのか判断できません. 次に,udunitsは「0年」と「1年」を同じだとみなすからです (これはAD1年とBC1年が連続しており「0年」という年はなかったことから考えると妥当です)

数年間にわたる,特定の季節だけの平均値1961年から1990年までの,1月の降水量の気候値を表す緯度経度グリッドデータです.

  dimensions:
    con_year=1;
    year=30;
    month=1;
  variables:
    float precipitation(con_year,month,lat,lon);
      precipitation:axis="-TYX";
      precipitation:subgrid="month: mean con_year: mean";
    int con_year(con_year);
      con_year:bounds="bounds_con_year";
      con_year:expand="year";
      con_year:long_name="year";
      con_year:old_interval=1;
      con_year:units="calendar_year as %Y";
    int bounds_con_year(con_year,2);
    int year(year);
    float month(month);
      month:bounds="bounds_month";
      month:long_name="seasonal phase";
      month:units="calendar_month as %m.%f";
    float bounds_month(month,2);
  data:
    con_year=1975;
    bounds_con_year=1961, 1990;
    year=1961, 1962, 1963, ..., 1990;
    month=1.5;
    bounds_month=1.0, 2.0;

代表的な年なる値(1975)はこの場合取り立てて意味はありません.むしろ重要なのはその境界です.これが気候値を計算する際に用いられた年の範囲を表すのです. These years are also given explicitly, and optionally, for reference. ここで,con_year軸の時間はdiscreteな形をしています(%.fはセクション25で述べた時刻を表す文字列の中には入っていません). 従って平均値の計算に使われた年度については,始まりの年と終わりの年をともに含む必要があります:. bounds_con_year変数が指し示すのは「1961年から1990年」であり,この両端も含めて30年分が気候値の計算に使われたことになります.

ここで,上のデータにさらに1969〜1980年の12月のデータも付け加えたい場合を考えてみましょう. これを行うには,変数monthに属性modulo=12.0fを与え(これは先ほど不要だったものです),軸monthのサイズを2にします. そして,以下のように変数を設定します.

    month=0.5, 1.5;
    bounds_month=0.0,1.0, 1.0,2.0;

規約により,この例のようなcombined axesの指し示す最初のタイムステップは,全ての軸の始まりの時刻から始まります. つまり上記の場合は1961年の「0月」から最初のタイムステップが始まることになります.これはmoduloが12となっている場合は1960年の12月と等値になるわけです. 別法として,次のような指定方法もあります.

    bounds_con_year=1960,1989;
    month=12.5, 13.5;
    bounds_month=12.0,13.0, 13.0,14.0;

これは前の例と全く等値です.今度は最後のタイムステップの方が問題になると思われるかもしれませんが,最後のタイムステップは1989年の「14月」の最初で終わることになっていますので,これは1990年2月の最初で終わるということと一緒になるのです.

平均値の算出に用いられなかった月を表すするには標準的な方法がありません. 変数con_yearの属性old_spacingに値"disjoint"を与えることが定められているくらいです. ここで,たとえば1974年12月がそういう月だったとしましょう. これを明示する一つの方法として考えられるのは,属性subgridに注釈を加え,"con_year: mean (December 1974 missing)"のように書くことです.


Climatological seasonal means for several decades: This is an extension of the previous case, and of the example of an average seasonal cycle in section 25. Here, the axes are set up to indicate climatological means for two of the seasons in three successive decades.

  dimensions:
    decade=3;
    season=2;
  variables:
    float precipitation(decade,season,lat,lon);
      precipitation:axis="-TYX";
      precipitation:subgrid="season: mean decade: mean";
    int decade(decade);
      decade:bounds="bounds_decade";
      decade:old_interval=1;
      decade:units="calendar_year as %Y";
    int bounds_decade(decade,2);
    int season(season);
      season:bounds="bounds_season";
      season:calendar="standard";
      season:modulo=1200;
      season:units="day as %m%d";
    int bounds_season(season,2);
  data:
    decade=1966, 1976, 1986;
    bounds_decade=1961,1970, 1971,1980, 1981,1990;
    season=115, 415;
    bounds_season=1,228, 301,531;
Here, precipitation[0][0][*][*] is the data for December-February (i.e. 1 December to 28 February inclusive) of the decade 1960-1970 (first December in 1960, last February in 1970), while [2][1][*][*] is March-May 1981-1990. The choice has been made to give the seasonal phase in months and days, rather than months alone; hence the modulo is 1200 rather than 12. Under modulo 1200, midnight on 1 December can be expressed equivalently as 1 or 1201. If 1201 were specified, it would mean that the first interval of time began on 1 December 1961 (rather than 1960), taking the combination of the lower boundaries of both time axes; the value 1 is a year earlier. The drawback of this %m%d scheme is that it is awkward or impossible to give accurate representative dates for the middle of the periods, especially since February has variable length. The absolute time format %m.%f for seasonal phase is better from this point of view. The season axis is not shown as having circular topology because no information is implied about the other two seasons.


Average early June maximum temperatures for several years: In this example, the dimensions indicate that maximum daily temperatures (between 9 a.m. on the day of record and 9 a.m. of the previous day) were recorded for 1-10 June, and an average maximum found for these ten days in each of the years 1980-1984.

  dimensions:
    year=5;
    con_season=1;
    con_day=1;
  variables:
    float temperature(year,con_season,con_day);
      temperature:axis="T--";
      temperature:subgrid="con_day: maximum con_season: mean";
    int year(year);
      year:long_name="year";
      year:units="calendar_year as %Y";
    int con_season(con_season);
      con_season:bounds="bounds_con_season";
      con_season:long_name="seasonal phase";
      con_season:old_interval=1;
      con_season:units="day as %m%d";
    int bounds_con_season(con_season,2);
    float con_day(con_day);
      con_day:bounds="bounds_con_day";
      con_day:long_name="diurnal phase";
      con_day:modulo=24.0f;
      con_day:units="hour as %H.%f";
    float bounds_con_day(con_day,2);
  data:
    year=1980, 1981, 1982, 1983, 1984;
    con_season=605;
    bounds_con_season=601, 610;
    con_day=-3.0;
    bounds_con_day=-15.0, 9.0;
The diurnal phase of -15 h means 15 hours before the beginning of the day in question, i.e. 9 a.m. on the previous day. No bounds are given for the year, because it is a discrete quantity, and there is no further information which could be added. But if the five years were averaged together, this would collapse the year axis, and the extreme years of 1980 and 1984 would be recorded as the boundaries of the collapsed axis. If, say, 1981 were not used in forming the average, the collapsed axis would have attribute old_spacing="disjoint".


Daily values as an average of subdaily values: Instantaneous pressure measurements are made at intervals of 3 hours (first measurement at midnight) throughout the days 6 May to 9 June 1937, and daily means formed from midnight to midnight.

  dimensions:
    con_subday=1;
    day=35;
  variables:
    float pressure(day,con_subday);
      pressure:axis="T-";
      pressure:subgrid="con_subday: point con_subday: mean";
    float con_subday(con_subday);
      con_subday:bounds="bounds_con_subday";
      con_subday:long_name="diurnal phase";
      con_subday:old_interval=0.125f;
      con_subday:old_spacing="uniform";
      con_subday:units="days as .%f";
    float bounds_con_subday(con_subday,2);
    int day(day);
      day:long_name="year and seasonal phase";
      day:units="days as %Y%m%d";
  data:
    con_subday=0.5;
    bounds_con_subday=0.0, 0.875;
    day=19370506, 19370507, ..., 19370608, 19370609;
Note that the con_subday axis is shown with two subgrid methods, referring to subgrid variation before and after its collapse. The only point here in having separate axes for day and diurnal phase is to show when the first and last instantaneous measurements were made in each day. If this is not important to record, the two axes could be merged together thus:
  dimensions:
    day=35;
  variables:
    float pressure(day);
      pressure:subgrid="day: point day: mean";
    float day(day);
      con_subday:bounds="bounds_day";
      con_subday:old_interval=0.125f;
      con_subday:long_name="time";
      con_subday:old_spacing="uniform";
      con_subday:units="days as %Y%m%d.%f";
    float bounds_day(day,2);
  data:
    day=19370506.5, 19370507.5, ..., 19370608.5, 19370609.5;
    bounds_day=19370506.0,19370507.0, 19370507.0,19370508.0, ...,
               19370608.0,19370609.0, 19370609.0,19370610.0;
If the 35 days were then averaged together, the date axis would collapse with bounds of 19370506.0 and 19370610.0. The subgrid attribute would not need modification since it is already shown as a mean over the day axis.


Average diurnal cycle: The following axes are appropriate for the average diurnal cycle of precipitation rate in July 1970-1979 as a function of latitude:

  dimensions:
    con_year=1;
    con_month=1;
    hour=8;
    lat=45;
    con_lon=1;
  variables:
    float ppnrate(con_year,con_month,hour,lat,con_lon);
      ppnrate:axis="--TYX";
      ppnrate:subgrid="con_lon: mean con_month: mean "
        "con_year: mean";
      ppnrate:units="kg m-2 s-1";
    int con_year(con_year);
      con_year:bounds="bounds_con_year";
      con_year:old_interval=1;
      con_year:units="calendar_year as %Y";
    int bounds_con_year(con_year,2);
    float con_month(con_month);
      con_month:bounds="bounds_con_month";
      con_month:units="calendar_month as %m.%f";
    float bounds_con_month(con_month,2);
    float hour(hour);
      hour:bounds="bounds_hour";
      hour:modulo=24.0f;
      hour:topology="circular";
      hour:units="hour as %H.%f";
    float bounds_hour(bounds_hour,2);
  data:
    con_year=1975;
    bounds_con_year=1970, 1979;
    con_month=7.5;
    bounds_con_month=7.0, 8.0;
    hour=1.5, 4.5, 7.5, 10.5, 13.5, 16.5, 19.5, 22.5;
    bounds_hour=0.0,3.0, 3.0,6.0, 6.0,9.0, 9.0,12.0,
                12.0,15.0, 15.0,18.0, 18.0,21.0, 21.0,24.0;

29  データ変数の無効値Invalid values

無効値invalid valueとは,定められた範囲外又はフィル値fill valueに等しい値のことをを言います.定められた範囲およびフィル値は,この文書で述べているUnidataの標準アトリビュートで決められます.無効値は,たとえばソフトウェア的トラブルによって生じた低品質のデータのことであり,unknown値や欠測値(セクション30参照)とは異なります. 無効値を座標変数に与えることはできませんが,有効範囲を定める境界変数(セクション20参照)アトリビュートを通して,範囲に制限を持たないセルを設定することはできます(Invalid values are not permitted in a coordinate variable, but the attributes which define the valid range may be used in boundary variables (section 20) to indicate unbounded cells. ).

数値スカラー型アトリビュートvalid_minを,当該変数の有効範囲の下限を示すものとして用います.valid_maxは有効範囲の上限を表すものです. 両者を同時に表すベクトル形アトリビュートがvalid_rangeです(valid_minvalid_maxを順に指定する.この両者を指定したことと等価です).このどれを用いても,変数の有効範囲を指定したことになります. ただし,valid_rangevalid_minあるいはvalid_maxが指定されているときは用いることができません. このようにして指定された有効範囲外の値については,アプリケーションはその値を無効値として扱わねばなりません. なお,valid_rangevalid_minvalid_maxのデータ型は,該当する変数の型と等しいものです. ここでは,byte型に対するUnidataの特別な扱い方に言及していないことに注意してください.これは,私達はこの型の使用を勧めていないからです(セクション3参照)

一方,スカラー数値型アトリビュート_FillValue(数値の型は変数の型と同じ)が,変数のフィル値を示すのに用いられます.netCDFでは,変数の型に応じてデフォルトのフィル値_FillValueが自動的に定められていますから,その値をそのまま用いるのであればユーザが明示的に_FillValueを定義する必要はありません.

The purpose of the fill value is to save the applications programmer the work of prefilling the data and also to eliminate the duplicate writes that result from netCDF filling in undefined data with its default fill value, only to be immediately overwritten by the programmer's preferred value. This value is considered to be a special value that indicates undefined data, and is returned when reading values that were not written. The _FillValue should be outside the range specified by valid_range (if used) for a variable. In cases where the data variable is packed using the scale_factor and add_offset attributes (section 32), the _FillValue attribute applies the numbers as packed, so they must be checked against it before unpacking.

If none of valid_min, valid_max or valid_range is defined then generic applications should define a valid range by using the fill value (whether defined explicitly or by default); if the fill value is positive then it defines a valid maximum, otherwise it defines a valid minimum. For integer types, there should be a difference of 1 between the fill value and this valid minimum or maximum. For floating point types, the valid extreme should have a magnitude which is half the magnitude of the fill value. We recommend a factor of two, rather than a difference of one bit, because it is easier for applications programmers. There is no special treatment for byte as we do not recommend that type (see section 3).


30  データ変数の欠測値

 欠測値missing valuesは座標変数には許されていません.したがってこのセクションはデータ変数についてだけ言及することになります. さて,missing_valueアトリビュートは,unknown値または欠測として扱われる値を示します.これは_FillValue属性(セクション29参照)とは異なり,netCDF組み込みの特別なアトリビュートではありません. missing_valueアトリビュートは,通常のアプリケーションが正しくそれを扱えるように,有効範囲(セクション29参照)外の値でなければなりません.

missing_valueアトリビュートに与えるnetCDFデータ型は,該当するデータ変数の型と一致している必要があります.ただし,もしデータ変数がscale_factorならびにadd_offset各アトリビュートによってパックされている場合(セクション32参照),missing_valueアトリビュートは,パックをはずしたデータ変数と同じ型でなければならず,また,パックをはずした後のデータ変数についてこの値と比較し,それが欠測値かどうか判定します (In cases where the data variable is packed via the scale_factor and add_offset attributes (section 32), the missing_value attribute matches the type of and should be compared with the data after unpacking.). GDTは,missing_value_FillValueの差異について特別な解釈をしているという点でCOARDSと異なります.


31  gatheringによる圧縮

 netCDFのファイルサイズを小さくするために,間違いなく計算に必要ないという点についてはデータセットから除外することが望ましいです.このようなデータ圧縮は,一つあるいは隣接した複数の軸について行われ,実際にデータが格納される点のリストのリファレンスが作られて完成します. このリストは,圧縮が行われる軸だけを軸とする「マスク配列」を考慮に入れ,そしてこの配列をreorderingなしに一つの次元にマップすることで作られます(The list is constructed by considering a mask array which has just the axes to be compressed, and mapping this array onto one dimension without reordering.). 圧縮後の配列においては,圧縮を受けた軸はすべて1つの軸に置き換えられています.その軸のサイズは,圧縮を受けた軸のなす空間の中で実際にデータが格納されていた点(wanted points)の数です.wanted pointsは,この1つの軸の中で,圧縮前の配列において並んでいたのと同じ順番に格納されています(もちろん,wanted points以外の点はこの並びから除外されています).圧縮及び解凍はこのリストに関するloopによって行われます.

 このリストは,座標変数(訳注:以下「リスト変数」)として格納され,それはデータ変数の軸に用いられます.従って,リストの変数及びこの軸の次元名は同じ名前となります.リスト変数は文字列型のアトリビュートcompressを持ちます.これはスペースで区切った次元名の並びで,ここに書かれた各次元が圧縮を受けていることを意味し,またその順番は圧縮前の配列におけるCDL宣言の順番どおり(in the order of the CDL declaration of the uncompressed array)です.このアトリビュートが存在することにより,その変数がリスト変数であることが分かります. リスト・オリジナルの座標変数(コンポーネント変数,アソシエイト変数,境界変数も含めて)・圧縮されたデータ変数・圧縮前変数の全てのアトリビュートが,圧縮後のnetCDFファイルに書き込まれます(The list, the original dimensions and coordinate variables (including component, associated and boundary variables), and the compressed data variables with all the attributes of the uncompressed variables are written to the archived netCDF file). これらの情報を使えば,すべての圧縮された変数を元通りに解凍することができます.ただし,もとの変数の名前だけはわかりません.

3次元配列の水平方向圧縮

 地温を表す経度−緯度−深さの3次元配列において,全ての深さについて海の点を除外します.この場合,圧縮によって影響を受ける(圧縮される)のは経度軸と緯度軸のみです.リスト変数としてlandpointを設定し,地表を表す点を格納します:

  dimensions:
    lat=73;
    lon=96;
    landpoint=2381;
    depth=4;
  variables:
    long landpoint(landpoint);
      landpoint:compress="lat lon";
    float landsoilt(depth,landpoint);
      landsoilt:axis="Z-";
      landsoilt:long_name="soil temperature";
      landsoilt:units="K";
    float depth(depth);
    float lat(lat);
    float lon(lon);
  data:
    landpoint=363, 364, 365, ...;

上記の例では,例えばlandpoint[0]は363ですから,landsoilt[*][0](lat,lon)という次元を持つオリジナルのデータの「363番目」の点に該当することが分かります.これは[3][75]という点にあたります.

3次元場の圧縮

海洋の塩分濃度をあらわす経度−緯度−深度3次元場を,海底下のデータをのぞく事により圧縮します.この場合は,全ての次元が圧縮により影響を受けます.というのは,深度が大きくなってゆくとデータが格納される点の数が次第に少なくなってゆくからです:

  variables:
    float salinity(oceanpoint);
      salinity:axis="-";
    long oceanpoint(oceanpoint);
      oceanpoint:compress="depth lat lon";
    float depth(depth);
    float lat(lat);
    float lon(lon);

このCDL情報からは,塩分濃度データは(depth, lat, lon)という次元を持つ配列に解凍されうることが読み取れます.


32  スケールとオフセットを利用した圧縮

This standard endorses the use of the optional Unidata-standard attributes scale_factor and add_offset for data and coordinate variables. These attributes can be used to provide simple number compression (packing), to store low-resolution floating-point data as small integers in a netCDF file. After the data values of the variable have been read in, they are to be multiplied by the scale_offset, and have add_offset added to them. If both scale_factor and add_offset attributes are present, the data are scaled before the offset is added. When scaled data are written, the application should first subtract the offset and then divide by the scale factor. This procedure is concerned only with storage. It does not affect the unit of the quantity. For instance, a pressure variable with values in the range 900.0-1100.0 Pa could be converted to short integers in the range 20000 by subtracting 1000 and dividing by 0.005 i.e. multiplying by 200. The units of the compressed variable are still recorded as pascals.

This standard is more restrictive than the netCDF Users' Guide with respect to the use of the scale_factor and add_offset attributes; ambiguities and precision problems related to data type conversions are resolved by these restrictions. If the scale_factor and add_offset attributes are of the same data type as the associated variable no restrictions apply; the unpacked data is assumed to be of the same data type as the packed data. However, if the scale_factor and add_offset attributes are of a different data type from the variable (containing the packed data) then in files adhering to this standard the variable may only be of type short or long. We exclude byte on grounds discussed in section 3. The attributes scale_factor and add_offset (which must match in data type) must be of type float or double. The data type of the attributes should match the intended type of the unpacked data. (It is not advised to unpack a long into a float as there is a potential precision loss.) Users should note that Unidata may provide a built-in means of packing data in netCDF files in future.


Appendix A  アトリビュート

アトリビュート名 タイプ場所関連セクション説明
add_offset N CD 29 32 Additive offset for packing data
appendices S G 5 Version number of these appendices
associate S CD 18 19 Identifies variables containing alternative sets of coordinates
axis S D 9 16 18 Identifies spatiotemporal dimensions
bounds N C 20 22 28 Identifies a bounday variable
calendar S GD 5 23 26 27 Calendar used for encoding time axes
comment S G 5 Additional information about the file
component S CD 17 20 Identifies variables containing components of a variable
compress S D 31 Records dimensions which have been compressed by gathering
Conventions S G 5 Identifies the netCDF standard
coordinates S CD 18 Synonym for associate
expand S C 22 28 Coordinates before contraction
_FillValue N D 29 Indicator of invalid data
FORTRAN_format S CD 12 Format for a variable
history S GD 5 12 Evolution of the data in the file
institution S GD 5 12 Who made or supplied the data
long_name S CD 12 Long description of a physical quantity
modulo N CD 12 14 25 Arithmetic modulo of a variable
north_pole N D 10 Long.,lat. of rotated North Pole
old_interval N C 22 28 The typical separation between points on an axis before contraction
old_spacing S C 22 28 Indicates the spacing of points along an axis before contraction
positive S C 16 Direction of positive for a vertical axis
production S GD 5 12 How the data was produced
quantity S CD 12 Standardised description of a physical quantity
quantity_table S G 5 12 URL of the quantity table
scale_factor N CD 29 32 Multiplicative factor for packing data
subgrid S D 21 22 28 Records how the data values represent subgrid variation
topology S C 13 14 25 Topology of an axis (circular or not)
time_format S CD 23 Format for printing a time and date
units S CD 12 14 15 23-27 Units of a physical quantity
valid_max N CD 20 29 Largest valid value of a variable
valid_min N CD 20 29 Smallest valid value of a variable
valid_range N CD 29 Smallest and largest valid values of a variable

タイプ : S=文字列型, N=数値型.

場所G=グローバルアトリビュート,C=座標変数用(multidimensional座標変数を含む), D=データ変数用


Appendix B  サブグリッドヴァリエーションを記述する方法

セクション21を参照.

Methodの値 単位説明
cell u セル全体を説明する値(例.積分値)
maximum u 最大値
median u メディアン
mid-range u 最大値と最小値の平均
minimum u 最小値
mean u 平均
mode u モード (頻度最大の値)
point u グリッドポイントだけにおける値
standard deviation u 標準偏差
variance u2分散(ヴァリアンス)

単位について: uは,この方法でサブグリッドヴァリエーションが表される変数の単位のことです.


Appendix C  udunits.datからの変更点

単位についてはセクション11参照.

新たな単位unityが,無次元定数「1」を示すために導入されています.

単位degreesは使えません.これは緯度や経度の変数を微分(差分)しようとしたときにあいまいな点が出てきてしまうからです.この単位は,現バージョンのGDTファイルには用いることができません.

また,時間(時刻)の単位としてcalendar_monthcalendar_yearを用いることができますが,これらは(12calendar_monthおよびその倍数が相当するcalendar_yearに変換できることを除いては)相互に変換できませんし,また他の時間単位に換算することもできません.なお,単位yearおよびmonthは用いることができません.これらを使用すると混乱が生じるからです.


Appendix D  物理量のlong name

See section 12. This TD is not yet available. As well as existing as part of this standard, it will be made available on the web.

Version long_name units
1.0 depth below the surface m
1.0 height above the surface m
1.0 latitude degree_north
1.0 longitude degree_east
1.0 pressure Pa
1.0 soil temperature K
1.0 specific humidity unity
1.0 temperature K
1.0 time s

Version: The version of the appendices at which this quantity was introduced.
long_name: Case, spaces and punctuation are not significant in the long_name.


Jonathan Gregory | jmgregory@meto.gov.uk
Robert Drach | drach@llnl.gov
Japanese Translation by AGATASHI | agata@iis.u-tokyo.ac.jp

LLNL Disclaimers

UCRL-MI-127703


File translated from TEX by TTH, version 1.96.
On 18 Mar 1999, 09:20.