<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% netCDFユーザーズガイド(version 2.4日本語訳) by K.Ishioka 96/11/04
%
%\documentstyle[a4j]{jbook}
\documentstyle[a4j]{myjbook}

%\textheight 25cm
\textheight 26cm
\textwidth 18cm
%\topmargin -1cm
\topmargin -1.5cm
\oddsidemargin -0.5cm
\evensidemargin -1.5cm

\newlength{\vs}
%\setlength{\vs}{1.3zh plus 0.1zh minus 0.1zh}
\setlength{\vs}{1.3zh minus 0.1zh}

\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tableofcontents

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter*{}

%\chapter*{序文}
\section*{序文}

UnidataはNational Science Foundataionによって支援されているprogram
で, 米国の大学が革新的なコンピュータおよびネットワークのアプリケーショ
ンを通して, 教育および研究のために大気および関連するデータを活用できる
ようにするものである.
これらのデータを解析および表示するために, Unidata Program Centerでは
大学に対して, University of Wisconsin, Purdue University, NASA, および
National Weather Serviceを含む他の組織によって開発されたソフトウェアパッ
ケージを提供している. 
これらの基礎をなすのが, リアルタイムでデータを取得および扱うために
Unidataによって開発されたシステムであり, 各大学が各自の所有データをロー
カルな必要に応じて取得および扱えるべきであるというUnidataの原則を実地
にするものである.
Unidata programはデータセンターを持たないとうことが重要な点である --
データのマネージメントは分配された任務である.

このガイドで記述されているNetwork Common Data Form (netCDF)ソフトウェ
アは, 本来, いろいろなUnidataアプリケーションに対して共通のデータアク
セス法を供給することを意図したものである.
これらは, 一点観測, 時系列, 規則的に配置された格子点, および衛星または
レーダーイメージを含んだいろいろな種類のデータを扱うものである.

netCDFソフトウェアはI/Oライブラリとして機能し, CまたはFORTRANから呼び
出せ, 自己記述的で機種依存の無いファイルにデータを格納および引出すこと
ができる. 各netCDFファイルは, 無制限の多次元の名づけられた変数(整数,
実数, 文字, バイト, 等々のように型が異っていてもよい)を含み, 各変数は
測定の単位や説明書きのような補助データを伴っていてもよい.
インターフェースは既存のnetCDFファイルに既定の方法でデータを追加する手
段を含んでおり, これは(固定長の)レコード構造とは非なる機能性である.
しかし, netCDFライブラリは, 変数の名前およびインデクスによりデータを直
接アクセスで格納および引出すことをも許容しており, それゆえにディスク上
にある(またはメモリ上にある)ファイルに対してのみ有用なものである.

これまでのところ, Unidataソフトウェアの約半分がnetCDFアクセスを用いる
ようになっており, このような共通性がすべてのUnidataアプリケーションに
わたって拡張されるべく計画されている. このことは以下の目的を持つ:

\begin{itemize}
 \item 共通データを異なるアプリケーションによって使用することを促進する.
 \item 異なるコンピュータ間でデータファイルが透明, すなわち変換なしで
       転送または共有されるのを可能にする.
 \item フォーマットを解釈するために通常費されるFORTRANおよびCプログラ
       マのプログラミング労力を等しく減らす.
 \item データおよび補助データの誤解に由来するエラーを減らす.
 \item あるアプリケーションからの出力を他の入力として使用することを容
       易にする.
 \item インターフェースの標準を確立し, Unidataシステムに新しいソフトウェ
       アを含めることを簡単にする.
\end{itemize}

このプロジェクトはある面ではすでに成功を収めている.
netCDFは現在, CRAYからパーソナルコンピュータにわたり殆どのUNIXワークス
テーションを含むコンピューティングプラットフォームで使用されている.
netCDFはあるコンピュータ上で(例えばFORTRANを用いて)複雑なデータセット
を作成し, 同一の自己記述的なデータセットを他のコンピュータ上で(例えばC
を用いて)中間での変換なしで引出すために使うことができる ---
netCDFファイルはネットワークを越えて転送することができ, また, 適切なネッ
トワークファイルシステムを使ってリモートアクセスすることもできる.

Unidata以外のソフトウェアがnetCDFアクセスを使用することはUnidataの主要
な顧客の利益になる --- このような使用が結果的にUnidataの情報を解析およ
び表示するためのより多くのオプションを与える --- と信じているので,
netCDFのライブラリはライセンスや他の重大な制約など無しで配布されており,
最新のバージョンをアノニマスFTPで取得することができる.
見たところ, このソフトウェアは大気科学のコミュニティを越えて, 広範囲の
学会で大いに受け入れられているようであり, 現在, 多数のパブリックドメイ
ンおよび商用のデータ解析システムがnetCDFファイルを入力として受け入れる
ことができるようになっている.

幾つかの組織がnetCDFをデータアクセスの標準として採用しており, National
Center for Supercomputer Applications (NCSA, Urabana-Champaignの
the University of Illinoisに関連している)では, netCDFプログラミングイ
ンターフェースを``HDFファイル''にデータを格納および引出すための手段とし
てサポートしようという努力が進行中である. この``HDFファイル''は一般的な
NCSAのツールによって使われているフォーマットである.
我々はこれらの努力を支援し, 協力してきている.

netCDFソフトウェアに対して提供されているサポートのレベルについての質問
が時々寄せられる.
Unidataの公式な立場は, netCDFライブラリに添付されている著作権注意書に
言明されているが, ソフトウェアは``そのまま''配布されるということである.
実際, ソフトウェアは時々更新されており, Unidataは近い将来に向けて改善
を続けるつもりである.
Unidataのミッションは米国の大学の地球科学者に奉仕することであるので,
そのコミュニティによる問題の報告は必ず最大限の注意を払われる.

我々は, 読者がこのソフトウェアを有用なものでると感じ, 改良の提案だけで
なくアプリケーションにおけるフィードバックをも我々に与えてくれることを
期待している.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\chapter*{概要}
\section*{概要}

Network Common Data Form (netCDF)インターフェースの目的は, 配列指向の
データを, 自己記述的でネットワーク透過性のある形式で作成, アクセス, お
よび共有することを可能にすることである.
``自己記述的''というのは, ファイルがその内包するデータを定義する情報を
含んでいるということを意味している.
``ネットワーク透過性''というのは, 整数, 文字および浮動小数点数を異なった
方法で格納するコンピュータによってアクセスすることができるような形式で
ファイルが表現されているということを意味している.
新しいデータセットを作成するためにnetCDFインターフェースを使うことによ
り, データに可搬性を持たせることができる.
データアクセス, 管理, 解析および表示するためのソフトウェアにnetCDFイン
ターフェースを用いることにより, ソフトウェアをより一般的に便利にするこ
とができる.

netCDFソフトウェアはnetCDFデータにアクセスするためのCおよびFORTRANイン
ターフェースを含んでいる.
これらのライブラリは普通のコンピューティングプラットフォームの多くで利
用できる.
netCDFデータアクセスのためのC++およびperlインターフェースもまたUnidata
から取得可能である.
netCDFのユーザのコミュニティはソフトウェアの付加的なプラットフォームへ
の移植および他のプログラミング言語のためのインターフェースにも貢献して
きた.
netCDFソフトウェアライブラリのソースコードは自由に取得することができ,
そのことは配列指向データおよびデータを便利にするソフトウェアの両方を共
有するのを支援するものである.

このユーザーズガイドはnetCDFデータモデルを提出しているが, Cおよび
FORTRANインターフェースのみだけしかドキュメントしていない.
UNIXシステムのための参考文書は, CおよびFORTRANインターフェースのための
UNIX`man'ページの形式のものとして, netCDFソフトウェアと一緒に取得でき
る.
netCDFについてのより広範な付加的情報, それはnetCDFデータを扱う他のソフ
トウェアへのポインタを含んでいる, はnetCDF World Wide Webサイト
({\tt `http://www.unidata.ucar.edu/packages/netcdf/'})
から取得することができる.

%-----------------------------------------------------------------------
\section*{参考文献}

\begin{enumerate}
\item
Brown, S. A, M. Folk, G. Goucher, and R. Rew,
``Software for Portable Scientific Data Management,''
{\it Computers in Physics},
American Institute of Physics, Vol. 7, No. 3, May/June 1993.
\item
Fahle, J., {\it TeraScan Applications Programming Interface}, SeaSpace,
San Diego, California, 1989.
\item
Fulker, D. W., ``The netCDF: Self-Describing, Portable Files---a Basis
for `Plug-Compatible' Software Modules Connectable by Networks,''
{\it ICSU Workshop on Geophysical Informatics}, Moscow, USSR, August
1988.
\item
Fulker, D. W., ``Unidata Strawman for Storing Earth-Referencing Data,''
{\it Seventh International Conference on Interactive Information
and Processing Systems for Meteorology, Oceanography, and Hydrology}, New
Orleans, La., American Meteorology Society, January 1991.
\item
Gough, M. L., {\it NSSDC CDF Implementer's Guide (DEC VAX/VMS) Version
1.1}, National Space Science Data Center, 88-17, NASA/Goddard Space
Flight Center, 1988.
\item
Jenter, H. L. and R. P. Signell, ``NetCDF: A Freely-Available
Software-Solution to Data-Access Problems for Numerical Modelers,''
{\it Proceedings of the American Society of Civil Engineers Conference
on Estuarine and Coastal Modeling}, Tampa, Florida, 1992.
\item
Raymond, D. J., ``A C Language-Based Modular System for Analyzing and
Displaying Gridded Numerical Data,'' {\it Journal of Atmospheric and Oceanic
Technology}, {\bf 5}, 501-511, 1988.
\item
Rew, R. K. and G. P. Davis, ``The Unidata netCDF: Software for
Scientific Data Access,'' {\it Sixth International Conference on Interactive
Information and Processing Systems for Meteorology, Oceanography, and
Hydrology}, Anaheim, California, American Meteorology Society, February 1990.
\item
Rew, R. K. and G. P. Davis, ``NetCDF: An Interface for
Scientific Data Access,'' {\it Computer Graphics and Applications},
IEEE, pp. 76-82, July 1990.
\item
Treinish, L. A. and M. L. Gough, ``A Software Package for the Data
Independent Management of Multi-Dimensional Data,'' {\it EOS
Transactions}, American Geophysical Union, {\bf 68}, 633-635, 1987.
\end{enumerate}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{イントロダクション}
\label{イントロダクション}

%-----------------------------------------------------------------------
\section{netCDFデータインターフェース}

Network Common Data Form, すなわちnetCDF, はデータを配列の形で格納およ
び引出すためのデータアクセス関数のライブラリへのインターフェースである.
{\bf 配列}はn次元(nは0,1,2,...)の矩形構造ですべて同じデータタイプ(例え
ば, 8ビット文字, 32ビット整数)の要素を含んでいるものである.
{\bf スカラー}(単なる一つの値)は0次元の配列である.

netCDFはデータを自己記述的でネットワーク透過性のオブジェクトで単純なイ
ンターフェースを通じてアクセスできるものの集合体として見ることをサポー
トする抽象概念である.
配列の値は, データがどのように格納されているかの詳細を知らなくとも直接
アクセスできる.
どんな単位が使われているかといったようなデータに関する補助情報は,
データとともに格納することができる.
一般的なユーティリティおよびアプリケーションプログラムはnetCDFファイル
にアクセスして, 指定されたデータフィールドを変換, 結合, 解析, および表
示することができる.
このようなアプリケーションの発展はデータへのアクセシビリティの改善およ
び配列指向のデータを管理, 解析および表示するためのソフトウェアの再利用
性の改善につながるものである.

netCDFソフトウェアは{\bf 抽象的データタイプ}を実装するものである, これは
netCDFファイルのデータにアクセスし扱うためのすべての命令は, インターフェー
スによって提供されている関数のみを使わねばならないということを意味して
いる.
データの表現はインターフェースを使うアプリケーションからは隠されており,
そのため, データの格納法は既存のプログラムに影響を与えることなく変更す
ることができる.
netCDFの物理的な表現はデータが書かれたコンピュータに独立であるように設
計されている.

UnidataはC, FORTRAN, C++, およびperlのため, およびいろいろなUNIXオペレー
ティングシステムのためのnetCDFインターフェースをサポートしている.
このソフトウェアは, 毎回のメジャーリリースの前に, 他の2, 3のオペレーティ
ングシステムについても, それらのシステムにアクセスするユーザの助力によっ
て移植およびテストされている.
UnidataのnetCDFソフトウェアはFTPによって無料で得ることができ, そのこと
は広範な使用を支援している.

%-----------------------------------------------------------------------
\section{netCDFはデータベース管理システムではない}

配列指向のデータを格納するためになぜ既存のデータベース管理システムを使
わないのか?
これは, 相関的データベースソフトウェアはnetCDFインターフェースでサポー
トされているようなデータアクセスには適していないからである.

まず第一に, 相関モデルをサポートする既存のデータベースシステムは,
多次元のオブジェクト(配列)をデータアクセスの基本単位としてはサポートし
ていない.
配列を関係として表現することは便利なデータアクセスの種類のいくつかを不
便にしてしまい, 多次元データおよび座標系についての抽象化を殆ど与えない.
配列指向のデータを引出し, 修正し, 数学的に扱いそして可視化するためには
全く異なったデータモデルが必要である.

このことに関連して, 一般的な目的を持つデータベースシステムには第二の問
題点がある: 大きな配列に対してはパフォーマンスが悪いということである.
衛星画像の集積, 科学的モデルの出力および長期間の全球気象観測は, 殆どの
データベースシステムが組織化し効率的な引出しのための索引づけする能力を
超えている.

最後に, 一般目的のデータベースシステムは, 資源およびアクセス効率を非常
に犠牲にして, 配列指向のデータを解析, 管理および表示するためには不必要
な機能を提供している.
例えば, 手の込んだアップデート機能, 履歴の検査, フォーマットの報告,
および業務処理のために設計された機構は, 殆どの科学的アプリケーションに
は不要である.

%-----------------------------------------------------------------------
\section{ファイルフォーマット}

ネットワーク透過性(マシン独立性)を達成するために, netCDFは
XDR (eXternal Data Representation, \\
{\tt `ftp://ds.internic.net/rfd/rfc1832.txt'}を参照), すなわちデータの
表現およびコード化のために提案されている標準プロトコル, によって実装さ
れている.
XDRはデータをマシン独立なビットの列へコード化する方法を提供している.
XDRは幅広い種類のコンピューターに実装されており, この実装には, 8ビット
のバイトがコンシステントにコード化およびデコード化できるということだけ
が必要とされる.

netCDFファイルの全体の構造は第9章[netCDFファイル構造および性能]
\pageref{netCDFファイル構造および性能}ページで記述する.

フォーマットの詳細はAppendix B[ファイルフォーマット仕様]
\pageref{ファイルフォーマット仕様}ページで記述する.
しかし, ユーザがこのフォーマット仕様を用いてnetCDFファイルを読み書きす
るための独立した低レベルのソフトウェアを開発するというのはお勧めできな
い, なぜなら, このような行為はフォーマットが変更された際に互換性の問題
を引き起こす可能性があるからである.

%-----------------------------------------------------------------------
\section{性能は?}

netCDFの目標の一つは大きなデータセットの小さな部分集合への効率的なアク
セスをサポートすることである.
この目標をサポートするために, netCDFは順次アクセスではなくむしろ直接ア
クセスを使用する.

XDRのオーバヘッドの量は, データタイプ, コンピューターのタイプ, データ
アクセスの不均一性, および実装がコンピューターに合せてどれだけ上手くチュー
ンされているかといったことを含む多くの要素に依存している. 
このオーバヘッドはアプリケーションに使われる全体の資源に比較すれば概し
て小さい.
どんな場合においても, XDRレイヤーのオーバヘッドは, 移植性のある, ネッ
トワーク透過なデータアクセスのために払う対価として, たいてい理にかなっ
たものである.

データアクセスの効率はnetCDFを設計し実装する際の重要な関心事であるが,
非効率的な方法でデータにアクセスするためにnetCDFインターフェースを用い
てしまうようなこともまだありうる: 例えば, 各記録から単一の値だけを必要
とするようなデータの断面を要求してしまうようなことによって.
インターフェースをいかに効率的に用いるかについての指針は9章[netCDFファ
イル構造および性能]\pageref{netCDFファイル構造および性能}ページに与えている.

%-----------------------------------------------------------------------
\section{netCDFはよい記録フォーマットか?}

netCDFは配列を格納するための一般目的の記録フォーマットとして使うことが
できる.
netCDFでデータを圧縮することは可能である(例えば, 低精度の浮動小数点数
をコード化するのに32ビットの数の配列の代わりに8ビットまたは16ビット整
数の配列を使うなど)が, netCDFの現行バージョンはデータを最適に圧縮する
ようには設計されていない.
そのため, netCDFは特定のデータセットの特別な性質についての知識を使った
特別な目的の記録フォーマットより多くのスペースを必要とするかもしれない.

%-----------------------------------------------------------------------
\section{慣習に従った自己記述的データの生成}

単にnetCDFを使うだけではデータを``自己記述的''かつ人間および機械の両方
に意味があるようにするためには不十分である.
変数および次元の名前は意味を持ち, あらゆる関連した慣習に従っている
べきである.
次元は対応する座標変数の値を(測定できる場合には)持っているべきである.

属性は補助情報を供給する上で重要な役割を果す.
関連する慣習を用いた関連した標準属性すべてを使うことは重要なことで
ある.
\ref{属性の慣習}節[属性の慣習]\pageref{属性の慣習}ページ
では, 予約された属性(netCDFライブラリによっ
て使用される)および一般的なアプリケーションソフトウェアのための属性の
慣習を記述する.

数多くの団体がそれら自体の付加的な慣習およびnetCDFデータの形式を定
義している.
これらの慣習の記述は, それらを組み込んだサンプルとともにnetCDF
Conventions site\\
({\tt `http://www.unidata.ucar.edu/packages/netcdf/conventions.html'})
から参照することができる.

これらの慣習は, ふさわしいところに使われるべきものである.
付加的な慣習はローカルな使用のためにしばしば必要とされている.
このような慣習は, もし同じ分野の他のユーザに関心を持たせたいと思う
ならば, 上記のnetCDF Conventions siteに寄せられるべきである.

%-----------------------------------------------------------------------
\section{netCDFインターフェースの背景と発展}

netCDFインターフェースの開発はUnidataの必要に関連した控え目な目標:
すなわちUnidataアプリケーションと取り込まれたリアルタイムの気象データ
との間の共通インターフェースを提供するという目標を持って始まった.
Unidataのソフトウェアは, CおよびFORTRANの両方からのアクセスを受け付け,
多様なハードウェアプラットフォーム上で実行されるよう意図されていたので,
Unidataの目標を達成することは, より広い状況で有用なパッケージを提供し
うる可能性を持っていた.
このパッケージを幅広く取得可能なものにし, かつ同じような必要を持つ他の
組織と共同することによって, 科学的なデータアクセスのためのソフトウェア
が同じ学問分野の他の人々にはまれにしか再利用されず, 学問分野間では殆ど
全く再利用されなかった(Fulker, 1988)という当時の状況を改善することを我々
は希望したのである.

netCDFソフトウェアに採用された重要なコンセプトは, NASA Goddard
National Space Science Data Center (NSSDC)で開発されたデータアクセスソ
フトウェアを記述した論文(Treinish and Gough, 1987)に由来する.
このソフトウェアによって供給されていたインターフェースは, Common Data
Format(CDF) と呼ばれていた.
NASA CDFは当初, 配列を格納するための抽象化をサポートするための, プラッ
トフォームに特化したFORTRANライブラリとして開発された.

NASA CDFパッケージは, 広範なアプリケーションの山の中で数多くの異る種類
のデータを使うために使用されてきていた.
これは, (13サブルーチンのみという)簡明さ, 格納フォーマットからの独立性,
一般性, ユーザのデータについての論理的な見方をサポートする能力, および
一般的なアプリケーションのサポート, のおかげによるものである.

UnidataはCDFに関するワークショップを1987年8月にBoulderで開いた.
我々は, CDF FORTRANライブラリを拡張し, Cインターフェースを定義し, かつ
既存のNASAインターフェースとの互換性を保ちつつ単一の呼び出しでデータ集
合体へのアクセスを許容するために, NASAと共同する可能性を探究することを
提案した.

これとは独立に, New Mexico Institute of Minig and TechnologyのDave
Raymondは, 自己記述的で配列指向のデータへの順次アクセス, およびデータの
加工, 解析および表示への``パイプとフィルター''(すなわち``データフロー'')
的アプローチをサポートするUNIX上のCソフトウェアパッケージを開発してい
た.
このパッケージもまた``Common Data Format''という名前を使っていたが, こ
れは後にC-Based Analysis and Display System (CANDIS)と改められた.
UnidataはRaymondの仕事(Raymond, 1988)を知り, 名前つきの次元および単一
のデータオブジェクト内で型の違いをもつ変数を使用するなどといった彼のア
イディアのいくつかをUnidataのnetCDFインターフェースに組み込んだ.

1988年初頭, UnidataのGlenn DavisはXDRの上に被せる形でnetCDFパッケージ
のプロトタイプをCで開発した.
このプロトタイプは, CDFインターフェースの単一ファイルでネットワーク透
過な実装を達成するためのコストが許容範囲内であること, および得られたプ
ログラムはUNIXとVMSシステムの両方に移植可能であること, を証明した.
しかし, そのプロトタイプはまた, 小型で移植性がありかつNASA CDF互換で
FORTRANインターフェースで望まれるような一般性をもつようなものは実際的
でないことも示した.
以来, NASAのCDFとUnidataのnetCDFは別々に発展してきたが, 最近のCDFバー
ジョンはnetCDFと多くの共通点を持っている.

1988年初頭, 1987年のUnidata CDFワークショップの参加者の一人であった,
SeaSpace社(California州SanDiegoにある商用ソフトウェア開発会社)の
Joe Fahleは, NASA CDFソフトウェアをいくつか重要な面で拡張したCDFパッケー
ジをCで独立に開発した(Fahle, 1989).
Raymondのパッケージと同様に, SeaSpace CDFソフトウェアは関連しない型を
持った変数が同じデータオブジェクトに含まれることを許容し, 多次元配列へ
のアクセスの一般的な形を可能にしていた.
Fahleの実装は, SeaSpace社において, 画像処理システムのいろいろな段階で
の中間的な格納形式として使われていた.
このインターフェースとフォーマットはその後Terascanデータフォーマットに
発展していっている.

我々は, Fahleのインターフェースを研究した後, このインターフェースが
NASAインターフェースを我々の目的に拡張しようとして我々が確認した問題の
多くを解決しているという結論に達した.
我々は, 1988年8月, 一つのUnidata netCDFインターフェースについての合意
を達成し, かつ残った未解決問題を解決するための小規模なワークショップを
召集した.
参加者は, SeaSpaceのJoe Fahle, AppleのMichael Gough(NASA CDFの著者の一
人), University of MiamiのAngel Li(我々のnetCDFのプロトタイプをVMS上に
実装し, ユーザになる可能性もあった), およびUnidataのシステム開発スタッ
フであった.
このワークショップでは, いくつかの簡易化法が見いだされた後に合意が達成
された.
提案されたUnidata netCDFインターフェース仕様にこのワークショップの結果
を組み込んだドキュメントは, Glenn DavisとRuss Rewがこのソフトウェアの
ファーストバージョンを実装する前に, 意見を求めるために広く配布された.
他のデータアクセスインターフェースとの比較およびnetCDFを使った経験は,
(Rew and Davis, 1990a), (Rew and Davis, 1990b), (Jenter and Singnell,
1992), および(Brown, Folk, Goucher, and Rew, 1993)で議論されている.

1991年10月, 我々はバージョン2.0のnetCDFソフトウェア配布を発表した.
Cインターフェースのちょっとした修正(次元のサイズを{\tt int}ではなく
{\tt long}と宣言するようにした)によって, MS-DOSコンピューターのような
安価なプラットフォーム上でのnetCDFの利便性を向上させた, しかも他のプラッ
トフォーム上での再コンパイルも必要としなかった.
インターフェースへのこのこの変更によって, 関連したファイルフォーマット
への変更が必要となることもなかった.

1993年6月にリリースされたnetCDFバージョン2.3.2は同じファイルフォーマッ
トを維持したが, 記録への単一呼び出しアクセス, 不連続なデータを含む断面
へのアクセスの最適化, 特定の次元に沿った部分サンプリング(`stride'を使
う), 不連続なデータへのアクセス(`mapped array sections'を使う), ncdump
とncgenユーティリティの改良, および試験的なC++インターフェース, を追加
した.

%-----------------------------------------------------------------------
\section{過去のリリースから何が新しくなったか?}

このガイドは, netCDF2.4の1996年2月版を文書化したものであり, この版は
以前の版と同じファイルフォーマットを維持しているが, バージョン2.3.2か
らの以下の変更を含んでいる:
\begin{itemize}
 \begin{itemize}
  \item 新しいプラットフォームのサポート
  \item Cray上での著しい最適化
  \item インストールの簡単化
  \item ドキュメントの改善
  \item C++インターフェースの追加
  \item 報告されているバグのフィックス
 \end{itemize}
\end{itemize}

{\tt long}のサイズが{\tt int}のサイズより大きいような新しいプラットフォー
ム上でnetCDFをサポートするために, 新しいリリースでは, CおよびC++インター
フェースにおいては{\tt nclong}型宣言を使用するように完全に統合した.

C++インターフェースに追加と変更が加えられ, 記録を渡り歩いたり, 複数の
netCDFファイルへの同一座標アクセス, および単一記録へのアクセスすること
をより容易にした.

%-----------------------------------------------------------------------
\section{netCDFの制限}

netCDFデータモデルは名前付き属性を持つ名前付き配列変数の集合に系統だて
られるデータに広く適用できるが, このモデルおよびソフトウェアの実装には
にはいくつか重要な制限がある.

このデータモデルはデータのネスト構造をサポートしていない.
netCDFインターフェースは, ツリー表現, ネストした配列, または他の再帰的
なデータ構造, について殆ど役に立つものを提供していないが, これは主に,
FORTRANインターフェースがあらゆるnetCDFデータセットを読み書きできなけ
ればならないという要請によるものである.
間接的な使用および慣習によって, 表現可能なネスト構造もあるが, これ
は結果として, netCDFの最終目標である``自己記述的データ''の性質を失って
しまう.

現在の実装の著しい制限は, 各netCDFデータセットに対して無制限な次元はたっ
た一つしか許容されていいないということである.
複数の変数が一つの無制限な次元を共有しても良いが, それらはすべて一緒に
発展せねばならない.
そのため, netCDFモデルは複数の可変な次元サイズを持つ変数を扱えない.
また, 同一ファイル内で異なる変数が異なる可変次元を持つことも不可能であ
る.
矩形でない形を持つ変数(例えば, ``不調和な配列'')は便利には表現できない.

インターフェースは座標変数に特化した機能, すなわち, 通常の番号付けの代
りに次元に沿った位置を指定するために座標変数を使うような, は提供しない.
データをビット列にパックする機能もまだない(XDRはこのような能力がない).
このため, 9ビットのデータの配列は, 便利にアクセスされるために16ビット
の配列として格納されていなければならない.
データセットのサイズは現在2ギガバイトに制限されている, これは, 32ビッ
トの符号付きオフセットを使っているからである.

最後に, 現在の実装はnetCDFファイルへの同時アクセスを制限している.
単一のファイルを同時に一人が書き込み, 複数人が読み込むことは許されるが,
複数人が同時に書き込むことはサポートしていない.

%-----------------------------------------------------------------------
\section{netCDFの将来計画}

XDRは開発中の新しいソフトウェアに置き換えられる予定である.
これによって, 機能の追加およびよりよい効率がもたらされる予定である.

現在の計画では, 透過なデータパッキング, 改善された同時性のサポート,
データへのキーまたは座標値によるアクセス, 効率的な構造変更(例えば, 新
しい変数および属性)のサポート, 新しいデータタイプ, および格納形態に関
係なく特定の型としてデータにアクセスするための, 型を気にしないCおよび
FORTRANインターフェースの追加, を加える予定である.
加えられうる他の望まれる拡張では, もし実現可能ならば, 他のファイルのデー
タ断面へのポインタ, ネストした配列(不調和な配列の表現, ツリーおよび他
の再帰的データ構造の許容), 2ギガバイト以上のデータセットへのアクセスで
きる機能, および複数の無制限な次元, のサポートを加える.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{netCDFファイルの構成要素}
\label{netCDFファイルの構成要素}

%-----------------------------------------------------------------------
\section{netCDFデータモデル}

netCDFファイルは, {\bf 次元}, {\bf 変数}, および{\bf 属性}を含み,
それらはすべて, それらを特定するための名前およびIDナンバーの両方を持っ
ている.
これらの構成要素は共に, データの意味および配列指向のデータセット中のデー
タフィールド間の関係を保存するために用いることができる.
netCDFライブラリは, 通常のファイル名に加えて, ファイルIDナンバーによっ
て指定された複数のnetCDFファイルに同時にアクセスすることを許容している.

netCDFファイルは, 変数についてその名前, データタイプ, ランク(次元数), 
次元および先頭のディスクアドレスを含んだシンボルテーブルを含んでいる.
各要素は, それらが特定される配列番号(添字)の線形関数のディスクアドレス
に格納される.
これにより, これらの番号を記録中のフィールドとして, または記録の索引の
中(相関データベースのように)に格納する必要がなくなっている.
このことは, 欠損値が多くなければ, 高速でコンパクトな格納法を提供してい
る.

%-----------------------------------------------------------------------
\subsection{名前付けの慣習}

次元, 変数および属性の名前は, 任意の英数字(と, アンダースコア`\_'および
ハイフン`-')の列で構成され, 先頭は文字またはアンダースコアでなければな
らない.
(しかし, アンダースコアから始まる名前はシステム用途のために予約されて
いる.)
netCDFファイルにおいては大文字小文字は区別される.

\subsection{network Common Data Form Language (CDL)}
\label{CDL}

小さなnetCDFの例を使ってnetCDFデータモデルの概念を説明しよう.
このファイルは次元, 変数, および属性を含んでいる.
この簡単なnetCDFオブジェクトを記述するのに使われる表記は, CDL(network
Common Data form Language)と呼ばれ, netCDFファイルを記述するための便利
な手段を与える.
netCDFファイルシステムは, バイナリのnetCDFファイルから人間指向のCDLテ
キストファイルを生成, およびその逆を行うユーティリティを含んでいる.

\begin{quote}
\baselineskip=\vs
\begin{verbatim}
netcdf example_1 {  // netCDFファイルに対するCDL表記の例

dimensions:          // 次元名およびサイズがまず宣言される
        lat = 5, lon = 10, level = 4, time = unlimited;

variables:           // 変数の型, 名前, 形, 属性
        float   temp(time,level,lat,lon);
                    temp:long_name     = "temperature";
                    temp:units         = "celsius";
        float   rh(time,lat,lon);
                    rh:long_name = "relative humidity";
                    rh:valid_range = 0.0, 1.0;      // 最小, 最大値
        int     lat(lat), lon(lon), level(level);
                    lat:units       = "degrees_north";
                    lon:units       = "degrees_east";
                    level:units     = "millibars";
        short   time(time);
                    time:units      = "hours since 1996-1-1";
        // グローバル属性
                    :source = "Fictional Model Output";

data:                // オプションのデータ割り当て
        level   = 1000, 850, 700, 500;
        lat     = 20, 30, 40, 50, 60;
        lon     = -160,-140,-118,-96,-84,-52,-45,-35,-25,-15;
        time    = 12;
        rh      =.5,.2,.4,.2,.3,.2,.4,.5,.6,.7,
                 .1,.3,.1,.1,.1,.1,.5,.7,.8,.8,
                 .1,.2,.2,.2,.2,.5,.7,.8,.9,.9,
                 .1,.2,.3,.3,.3,.3,.7,.8,.9,.9,
                  0,.1,.2,.4,.4,.4,.4,.7,.9,.9;
}
\end{verbatim}
\end{quote}

netCDFファイルのCDL表記は, 後で説明する(\ref{ncdump}節[ncdump]\pageref{ncdump}
ページを参照)ユーティリティプログラム{\bf ncdump}を使って自動的に生成される.
もう一つのnetCDFユーティリティ{\bf ncgen}はCDLの入力からnetCDFファイル
を生成する(または, オプションで, netCDFファイルを生成するのに必要な呼
び出しを含んだCまたはFORTRANソースコードを生成する)
(\ref{ncgen}節[ncgen]\pageref{ncgen}ページを参照).

CDL表記は簡単でしかも非常に自己説明的である.
netCDFファイルの構成要素を説明すれば, より完全な説明になる.
さしあたって, CDL文がセミコロンで終っていることに注意されたい.
読み易いように, 空白, タブ, および改行を使うのは自由である.
CDL中, どの行でも`{\tt //}'以下は注釈である.
netCDFファイルのCDL記述は以下のような形をとる:
\begin{quote}
\begin{verbatim}
  netCDF 名前 {
    dimensions: ...
    variables: ...
    data: ...
  }
\end{verbatim}
\end{quote}
ここに, {\bf 名前}は{\tt ncgen}ユーティリティによってファイル名が生成
される際のデフォルトとしてのみ使われる.
CDF表記は3つのオプション部分から成り, それらは{\tt dimensions}, {\tt
variables}, および{\tt data}のキーワードで導入される.
netCDFの次元の宣言は{\tt dimensions}キーワードの後になされ, netCDF変数
と属性は{\tt variables}キーワードの後で定義され, 変数のデータ割り付け
は{\tt data}キーワードの後になされる.

%-----------------------------------------------------------------------
\section{次元}

次元は実際の物理的な次元を表すために使われうる, 例えば, 時刻, 緯度, 経
度, または高度などである.
次元は, 他の量, 例えば, 観測ステーションやモデルの実行番号など, を索引
づけするために使うこともできる.

netCDFの次元は{\bf 名前}と{\bf サイズ}の両方を持っている.
次元のサイズは任意の正の整数である, ただし, netCDFファイルの一つの次元
は{\tt UNLIMITED}のサイズを持つことができる.

このような次元は{\bf 無制限次元}または{\bf 記録次元}と呼ばれる.
無制限次元を持った変数は, その次元に沿ってどんな長さにすることもできる.
無制限次元の番号は, 伝統的な記録指向のファイル中の記録番号にようなもの
である.
netCDFファイルは無制限次元を一つまでしか持てないが, これは無くてもよい.
変数が無制限次元を持つ場合には, その次元は最も意味のある(最もゆっくり
変わる)次元でなければならない.
従って, あらゆる無制限次元はCDL形式における最初の次元でなければならな
い(Cの宣言では最初の FORTRANでは最後の次元である).

CDLの次元宣言はCDLキーワード{\tt dimensions}の後の一つまたはそれ以上の
行ですることができる.
同一行で複数の次元を宣言することもでき, その場合はコンマで区切る.
各宣言は{\bf 名前}$=${\bf サイズ}の形式である.

上の例では4つの次元: {\tt lat}, {\tt lon}, {\tt level},
および{\tt time}がある. 最初の3つは割り当てられた固定サイズである;
{\tt time}は{\tt UNLIMITED}のサイズを割り当てられているが,
これは, {\bf 無制限}次元であることを意味している.

netCDFファイル中の名づけられた基本単位は{\bf 変数}である.
変数が定義されると, その{\bf 形}は次元のリストとして明示される.
これらの次元はすでに存在している.

次元の数は{\bf ランク}(別名 ディメンショナリティ)と呼ばれる.
スカラー変数はランク0であり, ベクトルはランク1, および行列はランク2で
ある.

変数の形を特定する際に, 同じ次元を一度以上使うことができる.
例えば, {\tt correlation(instrument, instrument)}は異なる測器を用いた
測定間の相関を与える相関行列とすることができる.
しかし, 物理的な空間/時間の次元に対応する次元を持つデータは, 異なる次
元からなる形を持っているべきである, たとえこれらのうちのいくつかが同じ
サイズであっても.

%-----------------------------------------------------------------------
\section{変数}

変数は, データの大部分をnetCDFファイルに格納するために用いられる.
{\bf 変数}は同じ型の値の配列を表現する.
スカラー値は0次元配列として扱われる.
変数は名前, データ型, および変数が生成さえた際に指定された次元のリスト
で記述された形を持っている.
変数は関連した属性も持つことができ, それは変数が生成さえた後に追加, 削
除, または変更することができる.

変数データ型は, netCDFの{\bf 型}の小さな集合の一つであり,
その集合は, Cインターフェースでは名前{\tt NC\_BYTE}, {\tt NC\_CHAR},
{\tt NC\_SHORT}, {\tt NC\_LONG}, {\tt NC\_FLOAT}, および{\tt NC\_DOUBLE}
を持ち, FORTRANインターフェースでは対応する名前{\tt NCBYTE},
{\tt NCCHAR}, {\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
{\tt NCDOUBLE}を持っている.
CDL表記では, これらの型はより簡単な{\tt byte}, {\tt char}, {\tt short}, 
{\tt long}, {\tt float}, および{\tt double}で与えられる.
CDL表記では, {\tt int}は{\tt long}の同意語として使ってもよく, ま
た{\tt real}は{\tt float}の同義語として使ってもよい.
各タイプの正確な意味については後に
\ref{netCDFデータ型}節[netCDFデータ型]\pageref{netCDFデータ型}ページ
での議論する.

CDL変数宣言はCDLユニット中でキーワード{\tt variables}の後でなされる.
それらは以下の型をとる.
次元を持つ変数の場合:
\begin{quote}
{\bf 型\ \ 変数名} ({\bf 次元名1}, {\bf 次元名2}, ... );
\end{quote}
スカラー変数の場合:
\begin{quote}
{\bf 型\ \ 変数名};
\end{quote}

上記のCDLの例において, 6つの変数がある.
以下で議論するように, これらのうちの4つは座標変数である.
残りの変数(主変数と呼ばれることもある){\tt temp}および{\tt rh}は一般的
にデータと見なされるものを含んでいる.
これらの各変数は無制限次元の{\tt time}を第一次元として持っているので,
それらは{\bf 記録変数}と呼ばれる.
記録変数ではない変数は, その次元サイズの積で与えられる固定サイズ(デー
タ値の数)を持つ.
記録変数のサイズも次元サイズの積であるが, この場合にはこの積は変化する.
なぜなら, この積には変化しうる無制限次元のサイズを含んでいるからである.
無制限次元のサイズは記録の数である.

%-----------------------------------------------------------------------
\subsection{座標変数}

変数が次元と同じ名前を持つのは正当なことである.
このような変数はnetCDFライブラリにおいて特別な意味は持たない.
しかし, このような変数はこのライブラリを用いて特別に扱われるという慣習
がある.

次元と同じ名前を持つ変数は{\bf 座標変数}と呼ばれる.
概して, この変数は, その次元に対応する物理的な座標を定義する.
上記のCDLの例は{\tt lat}, {\tt lon}, {\tt level}, および{\tt time}の座
標変数を含み, それらは以下のように定義されている:
\begin{verbatim}
        int     lat(lat), lon(lon), level(level);
        short   time(time);
   ...
 data:
        level   = 1000, 850, 700, 500;
        lat     = 20, 30, 40, 50, 60;
        lon     = -160,-140,-118,-96,-84,-52,-45,-35,-25,-15;
        time    = 12;
\end{verbatim}

これらは, これらの座標に沿った位置に対応する緯度, 経度, 気圧, および時
刻を定義している.
従って, 1000, 850, 700, および500ミリバールに対応する高度, および北緯
20, 30, 40, 50, 60度でのデータがある.
各座標変数はベクトルであり, 同じ名前の次元のみから構成される形を持つこ
とに注意されたい.

次元に沿った位置は{\bf 番号}によって特定される.
これは最小値としてCプログラムでは0, FORTRANでは1を持つ整数である.
従って, 700ミリバールレベルは番号としてCでは2をFORTRANでは3を持つ.

次元が対応する座標変数を持つ場合, この座標変数は, 次元に沿った位置を特
定するための, 代替的でかつより便利なことも多い手段を提供する.
座標変数を利用する現在のアプリケーションパッケージは共通して, 座標変数
が狭義の単調(すべての値が異なりかつ増加または減少している)な数値ベクト
ルであることを仮定している.
座標変数の値として, 文字ラベルのようなものをも許容するようなより一般的
な慣習を定義しようという計画がある.

%-----------------------------------------------------------------------
\section{属性}

netCDFの{\bf 属性}はデータについてのデータ(補助データまたはメタデータ)
を格納するために使われる. これは伝統的なデータベースにおけるデータ辞書
および図表に格納される情報に多くの面で類似したものである.
殆どの属性は特定の変数に関する情報を提供する.
これらはその変数の名前(またはID)にその属性の名前を付加したものによって
識別される.

いくつかの属性はファイルに関する情報を総括して与え, {\bf グローバル}属
性と呼ばれる.
これらは空白の変数名(CDLでは)または特別な空白変数ID(CまたはFortranで)
に属性名を付加したもので識別される.

属性は関連する変数(グローバル属性に対してはない), 名前, データ型, 長さ,
および値を持っている.
現在のバージョンでは, 全ての属性をベクトルとして扱う;
スカラー値は単一要素ベクトルとして扱われる.

慣習的な属性名は, それが適当な場合には使わるべきである.
新しい名前はできるだけ意味あるものにするべきである.

属性の型は生成の際に指定される.
属性のために許されている型は, 変数のためのnetCDFデータ型と同一である.
同じ名前の属性でも, 対応する変数が異なっていれば, 型が異なっている場合
もある.
例えば, {\tt long}型の変数に対して有効なデータの最大値を指定する属性
{\tt valid\_max}は{\tt long}型であるべきである一方, {\tt double}型の変
数に対する属性{\tt valid\_max}は{\tt double}型であるべきである.

属性は変数や次元よりも動的である;
すなわち, 生成された後でも削除することができ, かつそれらの型, 長さ, お
よび値を変えることができる. 一方, netCDFインターフェースは変数を削除し
たり, その型や形を変えるための手段を提供していない.

属性を定義するCDL表記は以下の形をとる.
変数の属性の場合:
\begin{quote}
{\bf 変数名:属性名} = {\bf 値のリスト};
\end{quote}
グローバル属性の場合:
\begin{quote}
{\it :属性名} = {\bf 値のリスト};
\end{quote}
各属性の型および長さはCDLにおいて陽には宣言されない;
これらは属性に割り当てられた値から得られる.
属性のすべての値は同じ型でなければならない.
いろいろなnetCDF型の定数値のために使われる記法は後で議論する
(\ref{データ定数に対するCDL表記}節[データ定数に対するCDL表記]
\pageref{データ定数に対するCDL表記}ページを参照).

netCDFの例(2章[CDL例]\pageref{CDL}ページを参照)において, {\tt units} は変数
{\tt lat} に対する属性であり, 13文字列の値 {\tt `degrees\_north'} を持つ.
そして, {\tt valid\_range}は変数{\tt rh}に対する属性であり, 長さ2で値
{\tt `0.0'}および{\tt `1.0'}を持つ.

例として挙げたnetCDFファイルに対して一つのグローバル属性---{\tt
source}---が定義されている.
これはデータを説明するための文字列である.
現実のnetCDFファイルでは, その源, 来歴, 慣習, およびファイルの他の
性質を総括して記述するためのより多くのグローバル属性を持ちうる.

netCDFファイルを加工する一般的なアプリケーションの多くは, 標準的な属性
の慣習を前提としており, 特に理由がなければその慣習に従うことを強く勧め
る.
{\tt units}, {\tt long\_name}, {\tt valid\_min}, {\tt valid\_max},
{\tt valid\_range}, {\tt scale\_factor}, {\tt add\_offset},
{\tt \_FillValue}, および他の慣習的な属性の情報については
\ref{属性の慣習}節[属性の慣習]\pageref{属性の慣習}ページを参照.

netCDFファイルが最初に定義されてからずっと後になっても, 属性は追加する
ことができるので, 後で便利になるかもしれない属性すべてを見越して使う必
要はない.
しかし, 既存のファイルに新しい属性を追加することは, そのファイルをコピー
するのと同じコストがかかってしまう.
より広範な議論については, 9章[netCDFファイル構造および性能]
\pageref{netCDFファイル構造および性能}ページを参照のこと.

%-----------------------------------------------------------------------
\section{属性と変数の違い}

データ大部分のために使われる変数とは対照的に, 属性は補助的データまたは
データに関する情報のために使われる.
netCDFオブジェクトに関連, 属性に格納される補助的データの総量は, 概して
メモリ上に常駐できるほど小さい.
しかし, 変数はメモリ上に完全にはめこむには大き過ぎることが多く,
加工のためには部分に分ける必要がある.

属性と変数との間のもう一つの違いは, 変数は複数次元を持ちうるということ
である.
属性はすべてスカラー(単一の値)またはベクトル(一つの固定された次元)のど
ちらかである.

変数は, データ値を割り当てられる前に, 名前, 型, および形を決められて生
成されるので, 変数は値をもたずに存在しうる.
属性の値は属性が生成される際に指定されるので, 属性は値を持たずには存在
できない.

変数は属性を持つことができるが, 属性は属性を持つことができない.
変数に割り当てられた属性はその変数と同じ単位を持ってもよいし(例:
{\tt valid\_range}), または単位を持たなくてもよい
(例: {\tt scale\_factor}).
関連する変数の単位と異なる単位を必要とするデータを格納したい場合は,
属性よりむしろ変数を使うべきである.
より一般には, もしデータがそれらを説明するための補助データを必要とする
か, 複数次元であるか, それらの値を索引づけするための定義されたnetCDF次
元のいずれかを必要とするか, または重大な格納量を必要とする場合には, そ
のようなデータは属性としてではなくむしろ変数として表現されるべきである.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{データ}
\label{データ}

この章では6つの基本netCDFデータ型, netCDFでサポートされているデータア
クセスの種類, および配列以外のデータ構造をnetCDFファイルにいかに実装で
きるかということについて議論する.

%-----------------------------------------------------------------------
\section{netCDFデータ型}
\label{netCDFデータ型}

netCDFでサポートされている基本の型は現在以下のようになっている:
\begin{quote}
\begin{tabular}{ll}
\tt character &amp; 文を表現するための8ビット文字\\
\tt byte &amp; 符号つきまたは符号なしの8ビット整数(以下の議論を参照)\\
\tt short &amp; 符号つき16ビット整数\\
\tt long &amp; 符号つき32ビット整数\\
\tt float &amp; 32ビットIEEE浮動小数点数\\
\tt double &amp; 64ビットIEEE浮動小数点数
\end{tabular}
\end{quote}

{\tt byte}が追加されていることおよび符号なしの型が足りないことを除けば,
netCDFはCと同じ基本データ型をサポートしている.
基本データ型の名前はCDLの予約語になっているので, 変数, 次元, および属
性の名前として型の名前を使ってはならない.

今のところ, {\tt byte}は符号つき(-128から127)または符号なし(0から255)
のどちらとも解釈できる.
netCDFの現在のバージョンは8ビットのバイトをそれが符号つきかどうかを知
る必要なしに単純に読み書きする.
しかし, netCDFの将来のバージョンでデータの詰め込み機能が追加されれば,
値の算術演算が必要となるので, このような目的のために{\tt byte}データは
{\bf 符号つき}と解釈されるようになるだろう.

これらの型は, CおよびFORTRANプログラマにとってなじみがあり, 特定のコン
ピューターに独立した(XDRを使えば)明確な外部表現を持ち, かつデータ精度
と各データを表現するのに必要なビット数との間のトレードオフ関係を適度に
広い範囲で与える, といった理由で選ばれた.
netCDFデータ型と言語のデータ型との間の対応については, 
\ref{変数}節[変数]\pageref{変数}ページを参照のこと.

64ビット整数およびnビットへの詰め込みを含んだ新しいデータ型も計画され
ている.

%-----------------------------------------------------------------------
\section{データアクセス}

netCDFデータにアクセス(読みまたは書き)するために, オープンされたnetCDF
ファイル, netCDF変数, および変数の要素を特定する情報(例えば番号)を指定
する.
さらに, netCDFインターフェースは記録指向のデータアクセス形式もサポート
している.

データへのアクセスは{\bf 直接}である. これはすなわち大きなデータセット
中の小さな部分集合に, 最初にその前にあるすべてのデータにアクセスするよ
うなことなく効率的にアクセスできるということを意味している.
変数を指定してデータの読み書きをすると, ファイル中での位置を指定してい
なければ, ファイル中に他の変数がどのくらいあるかということと独立してデー
タアクセスができ, データにより多くの変数を追加するようなデータフォーマッ
トの変更によってプログラムが影響されなくなる.

CおよびFORTRANインターフェースにおいて, データにアクセスしようとするた
びにファイルを名前で指定するのではなく, 代わりにファイルIDと呼ばれる小
さな整数(これはファイルが最初に生成またはオープンされた際に得られる)に
よって指定される.
同様に, 変数もデータアクセスのたびに名前で指定されるわけではなく,
変数ID(netCDFファイル中の変数を特定するために使われる小さな整数)で指定
される.
(C++インターフェースにおいては, オープンされたnetCDFファイルおよび変数
はオブジェクトであるので, IDは必要ない.)

%-----------------------------------------------------------------------
\subsection{データアクセスの形式}

netCDFインターフェースは, オープンされたnetCDFファイル中のデータ値への
直接アクセスについていくつかの形式をサポートしている.
これらのアクセスの形式一つ一つを, 一般性を増していく順番で説明する:
\begin{itemize}
\item {\bf インデックスベクトル}を指定した個々の要素へのアクセス;
\item {\bf インデックスベクトル}および{\bf カウントベクトル}を指定した
配列部分へのアクセス;
\item {\bf インデックスベクトル}, {\bf カウントベクトル}および{\bf
ストライドベクトル}を指定した部分的にサンプルされた配列部分へのアクセ
ス; および
\item {\bf インデックスベクトル}, {\bf カウントベクトル}, {\bf
ストライドベクトル}および{\bf インデックスマッピングベクトル}を指定し
たマップされた配列部分へのアクセス
\end{itemize}

これらの4つの型のベクトル({\bf インデックスベクトル}, {\bf カウントベ
クトル}, {\bf ストライドベクトル}および{\bf インデックスマッピングベク
トル})はすべて各次元の要素を持ったベクトルである.
n次元(ランク = n)の変数について, n要素のベクトルが必要である.
変数がスカラー(次元なし)なら, これらのベクトルは無視される.

{\bf 配列部分}は``板きれ''すなわち2つのベクトルで指定された連続した矩
形のブロックである.
{\bf インデックスベクトル}は原点に最も近い隅の要素の番号を与える.
{\bf カウントベクトル}は, 変数の各次元に沿った縁の長さを順番に与える.

{\bf 部分的にサンプルされた配列部分}は, {\bf ストライドベクトル}が追加
されてサンプリングを指定するということを除いて{\bf 配列部分}に類似して
いる.
このベクトルは, 各次元について, その次元に沿ってとられるべきストライド
の長さを与える要素を持つ.
例えば, ストライドが4であるというのは, 対応する次元に沿って4つおきの値
という意味である.
アクセスされる値の総数は, 各縁の長さ({\bf カウントベクトル}で定義され
る)を対応するストライドで割ったものの上限(すなわち, 整数へ丸め)の積で
ある.

{\bf マップされた配列部分}は, {\bf インデックスマッピングベクトル}が追
加され, メモリ上に並べられたnetCDF変数に関連したデータ値にどのようにア
クセスするかを指定できるようになっているという点を除けば{\bf 部分的に
サンプルされた配列部分}に類似している.
参照位置からの各値の(バイトでの)オフセットは, 各インデックスに対応する
インデックスマッピングベクトルの要素を掛けたものの和で与えられる.
アクセスされる値の個数は{\bf 部分的にサンプルされた配列部分}の場合と同
じである.

マップされた配列部分の使用については以下でより完全に議論するが, より普
通に使われる配列部分アクセスの例を示すことにする.

%-----------------------------------------------------------------------
\subsection{配列部分アクセスの例}

先のnetCDFファイルの例(第2章[CDL例]\pageref{CDL}ページ参照)において, 
{\tt temp}すべての値のあるレベル(例えば, 2番目)における断面を読み込み
たいとし, そのnetCDFファイルには現在3つの記録({\tt time}の値)があると
する. 次元が
\begin{verbatim}
        lat = 5, lon = 10, level = 4, time = unlimited;
\end{verbatim}
と定義されており, 変数{\tt temp}がCDL表記において
\begin{verbatim}
        float   temp(time, level, lat, lon);
\end{verbatim}
と宣言されていることを思い出そう.

対応するC変数で, ある唯一のレベルのデータを保持するものは以下のように宣
言される:
\begin{quote}
\begin{verbatim}
#define LATS  5
#define LONS 10
#define LEVELS 1
#define TIMES 3                 /* 今のところでは */
    ...
float   temp[TIMES*LEVELS*LATS*LONS];
\end{verbatim}
\end{quote}
これはデータを1次元配列に保持するためのもので, 
\begin{quote}
\begin{verbatim}
    ...
float   temp[TIMES][LEVELS][LATS][LONS];
\end{verbatim}
\end{quote}
とすれば多次元配列のための宣言になる.

FORTRANでは, 次元はCDL宣言とは逆で, 第一次元が先に変化し, 記録変数の最
後の次元が記録次元となる.
従って, 唯一のレベルのデータを保持する対応変数のFORTRAN宣言は以下のよう
になる:
\begin{quote}
\begin{verbatim}
      INTEGER LATS, LONS, LEVELS, TIMES
      PARAMETER (LATS=5, LONS=10, LEVELS=1, TIMES=3)
         ...
      REAL TEMP(LONS, LATS, LEVELS, TIMES)
\end{verbatim}
\end{quote}
第2レベルのみで, すべての時刻, すべての緯度, そしてすべての経度を表現
するデータブロックを指定するには, 隅と縁の長さを与えなければならない.
この隅はCでは(0,1,0,0)で, --- または, FORTRANでは(1,1,2,1) --- である.
なぜなら, {\tt time}, {\tt lon}, および{\tt lat}の各次元については最初
から, {\tt level}次元については2番目の値から始めたいからである.
縁の長さはCでは(3,1,5,10), --- FORTRANでは(10,5,1,3) --- になる.
これは, {\tt time}についてはすべての3つの値, {\tt level}の唯一の値,
{\tt lat}のすべての5つの値, および{\tt lon}のすべての10個の値を取得し
たいからである.
全部で150(3*1*5*10)の浮動小数点数の値が返されるので, この数に十分な配
列のスペースを用意しておかなければならない.
データが返される順番は, Cでは最後の次元{\tt lon}が最初に変化し,
FORTRANでは最後の次元{\tt LON}が最初に変化する:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
              C                  FORTRAN

     temp[0][1][0][0]      TEMP(1, 1, 2, 1)
     temp[0][1][0][1]      TEMP(2, 1, 2, 1)
     temp[0][1][0][2]      TEMP(3, 1, 2, 1)
     temp[0][1][0][3]      TEMP(4, 1, 2, 1)
           ...                 ...

     temp[2][1][4][7]      TEMP( 8, 5, 2, 3)
     temp[2][1][4][8]      TEMP( 9, 5, 2, 3)
     temp[2][1][4][9]      TEMP(10, 5, 2, 3)
\end{verbatim}
\end{quote}

CおよびFORTRANインターフェースにおける次元の順番の相違は, ディスク上に
値が格納されている順番が異なっているということではなく, 単にこの2つの
言語の手続きインターフェースによってサポートされている順番が異なってい
るということの反映である.
一般に, netCDFファイルがCかFORTRANのどちらで書かれたかということは意味
がない; どちらの言語一方で書かれたnetCDFファイルは, 他の言語で書かれた
プログラムによっても読むことができる.

%-----------------------------------------------------------------------
\subsection{一般的な配列部分アクセスについてもうすこし}

マップされた配列部分を使うことによって, 変数要素のディスクアドレスとそ
れらがメモリ上に収納されているアドレスとの間に意味のある関係づけをする
ことができる.
例えば, メモリ上の行列は, ディスク上の行列を並べ変えて, 要素の順番を全
く異なるようにすることができる.
正常な配列部分において, ディスクとメモリアドレスとの間のマッピングは当
たり前なものである: メモリ内の値の構造(すなわち, 次元サイズとその順番)
は配列部分のそれに一致している.
しかし, マップされた配列部分では, {\bf インデックスマッピングベクトル}
が使われ, netCDF変数の要素の順番とそれらのメモリアドレスとの間のマッピ
ングを定義する.
メモリに常駐している配列の原点からある特別の点へのオフセット(バイト単
位)は, インデックスマッピングベクトルとその点の{\bf インデックスベクト
ル}
\footnote{ある点の{\bf 座標オフセットベクトル}は, 各次元に対して, 
その点を含む配列の原点からその点へのオフセットを与える.
Cでは, ある点の座標オフセットベクトルはその座標ベクトルと同じである.
しかし, FORTRANではある点の座標オフセットベクトルは, その点の座標ベク
トルの対応する値より一つ少ない値である.}
との{\bf 内積}
\footnote{二つのベクトル[x0, x1, ..., xn]と[y0, y1, ..., yn]との{\bf 
内積}は単にx0*y0 + x1*y1 + ... + xn*yn である.}
で与えられる.
正常な配列部分のインデックスマッピングベクトルは, --- 最も速く変化する
次元から最も遅い次元への順番で --- メモリに常駐するデータのバイトサイズ
(例えば, 浮動小数点数の値なら4), そして, その値に配列部分の最も速く変
化する次元の縁の長さを掛けたもの, そして, その値に次に速く変化する次元
の縁の長さを掛けたもの, 以下同様, といった要素を持つ.
しかし, マップされた配列においては, netCDF変数のディスク位置とメモリ位
置との間の関係は根本的に異なりうる.
例えば, 以下のC定義
\begin{quote}
\begin{verbatim}
struct vel {
    int flags;
    float u;
    float v;
} vel[NX][NY];
long imap[2] = {
    sizeof(struct vel),
    sizeof(struct vel)*NY};
\end{verbatim}
\end{quote}
(ここに{\tt imap}はインデックスマッピングベクトルである)は,
メモリ上にあるnetCDF変数({\tt vel(NY,NX)})の値にアクセスするために使う
ことができる. たとえ次元が並べ変えられたり, かつデータが浮動小数点数の
値の2次元配列ではなく構造体の2次元配列に含まれているような場合でも.

マップされた配列アクセスのより詳細な例は, マップされた配列アクセスのた
めのCおよびFORTRANインターフェースの記述の中で与えられる.
\ref{NCVPTG}節
[部分的にサンプルされたまたはマップされた値の配列を書き出す:
NCVPTGおよびNCVPGC]\pageref{NCVPTG}ページを参照.

netCDF抽象化は, もし状況によって正当化されていれば, 部分的にサンプルさ
れたまたはマップされた配列部分へのアクセスを使うことを許容しているが,
それらは要求されているものではない.
もし, これらの, より一般的なアクセス形態を必要としないならば, これらの
機能を無視して, 代わりに単一の値へのアクセスまたは正常な配列部分へのア
クセスを使ってもよい.

%-----------------------------------------------------------------------
\section{データ構造}

netCDF抽象化によって直接サポートされている唯一の種類のデータ構造は,
ベクトル属性を付加された名前つき配列の集合である.
netCDFは, 結合されたリスト, ツリー, 粗な行列, 不均一な配列, またはポイ
ンタを必要とするような他種のデータ構造, を格納するのに特に適合している
わけではない.
一つの配列中のデータを他の配列へのポインタとして使うことに関する種々の慣
例を採用して, 配列の集合から多種のデータ構造を構築することも可能である.
netCDFライブラリはこのようなデータ構造について手助けも妨げもしないが,
netCDFはこのような慣習が設計できるような機構は提供している.

以下の例では, 各列の始点のインデックスを与える関連インデックス変数を名
付ける属性{\tt row\_index}使って, 不均一な配列{\tt ragged\_mat}を格納
している.
第一の列は12個(12-0)の要素を含んでおり, 第二の列は7個(19-12)を含んでい
る, 等々である.
\begin{quote}
\begin{verbatim}
        float   ragged_mat(max_elements);
                ragged_mat:row_index = "row_start";
        int     row_start(max_rows);
data:
        row_start   = 0, 12, 19, ...
\end{verbatim}
\end{quote}

もう一つの例を挙げると, 各グループの変数の名前を空白やコンマのような伝
統的な区切り文字で区切ってリスト化する属性を定義することによって
netCDF変数を一つのnetCDFファイル中にグループ化できる.
このようなグループ化のために特別な種類の属性名を使うために慣習を使うこ
とができ, それによって, 変数の名前つきグループを任意の個数サポートする
ことができる.
もし必要ならば, 各変数に対する特別な慣習的属性により, その変数がメンバー
になっているグループの名前をリスト化することができる.
属性, または他の属性か変数を参照する変数を使うことにより, netCDFファイ
ルにおけるいくつかの種類の複雑な構造を表現するための柔軟な機構が得られ
る.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{netCDFライブラリの使用}
\label{netCDFライブラリの使用}

別にnetCDFライブラリすべてについて知っていなくとも, netCDFライブラリを
使うことができる.
netCDFファイルを作るだけなら, 必要なのは, 必要な次元, 変数および属性を
定義し, netCDFファイルにデータを書き出すのに必要な一握りのルーチンだけ
である. ({\tt ncgen}ユーティリティを使ってファイルを作っておいてから,
プログラムを走らせ, netCDFライブラリを使ってデータを書けば, 必要なライ
ブラリはずっと少なくて済む.)
同様に, 特定のnetCDFオブジェクトに格納されたデータにアクセスするための
ソフトウェアを書くには, netCDFファイルをオープンし, データにアクセスす
るためのほんの一部のnetCDFライブラリが必要なだけである.
任意のnetCDFファイルにアクセスする包括的なアプリケーションを書くには,
より多くのnetCDFライブラリに精通している必要がある.

本章では, 通常の使用に必要な一般的netCDFサブルーチン呼び出しの一覧表を
与える.
明解にするために, ルーチンの名前だけを提示し; 宣言およびエラーチェッ
クを省略し; 一般に複数回呼び出される文を字下げし; さらに記号...を使っ
て他の文の任意の列を表している.
手続きおよびサブルーチンの引数の完全なリストは後の章で説明する.

%-----------------------------------------------------------------------
\section{netCDFファイルの生成}

新規にnetCDFファイルを生成するのに使われる一般的な一連のnetCDF呼び出し
は以下のようである.

{\baselineskip=\vs
\begin{verbatim}
    NCCRE              ! netCDFファイルを生成: 定義モードに入る
         ...
       NCDDEF          ! 次元の定義: 名前とサイズから
         ...
       NCVDEF          ! 変数の定義: 名前, 型, および次元から
         ...
       NCAPT or NCAPTC ! 属性を置く: 属性値を割り当てる
         ...
    NCENDF             ! 定義の終了: 定義モードから抜ける
         ...
       NCVPT or NCVPTC ! 変数を置く: 変数に値を与える
         ...
    NCCLOS             ! 閉じる: 新しいnetCDFファイルを保存する
\end{verbatim} }

netCDFファイルを生成するためにはたった一つの呼び出ししか必要なく,
その際に2つのnetCDF{\bf モード}のうちの最初のモードに入る.
オープンされたnetCDFファイルにアクセスする際には, そのアクセスは
{\bf 定義モード}または{\bf データモード}のいずれかで行われる.
定義モードでは, 次元, 変数および新規の属性を生成できるが, 変数データ
の読み書きはできない.
データモードでは, データへのアクセスおよび既存の属性を変えるとができる
が, 新規の次元, 変数または属性を生成することはできない.

それぞれの次元を生成するためには, {\tt NCDDEF}
を1回ずつ呼び出す必要がある.
同様に, それぞれの変数を生成するためには, {\tt NCVDEF}を1回ずつ呼び出
す必要があり,
それぞれの属性を定義しかつ値を割り当てるためには{\tt NCAPT}または{\tt
NCAPTC}を1回ずつ呼び出す必要がある.
定義モードを抜けてデータモードに入るには, {\tt NCENDF}を呼び出せばよい.

いったんデータモードに入れば, 変数に新しいデータを追加したり, 古い値を
変えたり, 既存の属性の値を変えたり(その属性の変更がより多くの格納スペー
スを必要としない限り)することができる.
FORTRANインターフェースは, 属性を定義し, 変数に値を与えるサブルーチン
を2つ用意している. これは, 数か文字列かのどちらの値が使われるかという
ことに依存している.
単一の値を変数に書き出すには{\tt NCVPT1}または
{\tt NCVPT1C}を使う; 一方, 任意のデータ配列を書くには
{\tt NCVPT}, {\tt NCVPTC}, {\tt NCVPTG}, または{\tt NCVPTGC}を代りに使う.
複数変数のデータ記録を書くには, {\tt NCVPT}を複
数回呼び出せばよい.

最後に, 書き込みのためにオープンされているnetCDFファイルすべてを
{\tt NCCLOS}を呼び出して陽にクローズしなければならない.
書き込みのためにnetCDFファイルをオープンしたままプログラムが異常終了す
ると, {\tt NCSNC}を最後に呼び出してから最も新しく
書かれた記録変数データおよび任意の属性の変更の1つまたはそれ以上のデー
タが失われてしまう可能性がある.
異常終了によるデータ損失の可能性を減らすには, netCDF変数に書き出したり,
属性値を変更したりするたびごとに{\tt NCSNC}を陽に
呼び出せば可能である.
このようなことはコンピューター資源において高くつくので, このような呼び
出しは通常, 必要なとき以外には省略するべきである.

%-----------------------------------------------------------------------
\section{名前を知って, netCDFファイルを読む}

ここでは, netCDFファイルの名前だけではなく, それらの次元, 変数および属
性の名前を知っている場合を考える. (そうでない場合は, ``問い合わせ''呼
び出しをしなければならない.)
netCDFファイル中のそれらの変数からデータを読むための一般的なFORTRAN呼び出し
の順番は以下のようである:

{\baselineskip=\vs
\begin{verbatim}
    NCOPN               !  既存のnetCDFファイルをオープンする
         ...
       NCDID            !  次元のIDを取得する
         ...
       NCVID            !  変数のIDを取得する
         ...
       NCAGT or NCAGTC  !  属性の値を取得する
         ...
       NCVGT or NCVGTC  !  変数の値を取得する
         ...
    NCCLOS              !  netCDFファイルをクローズする
\end{verbatim} }

最初に, 単一の呼び出しにより, 与えられたファイル名でnetCDFファイルがオー
プンされ, オープンされたnetCDFファイルを参照するために以降のすべての呼
び出しで使われるnetCDF IDが返される.

次に, 興味のある各次元について{\tt NCDID}を呼び出
して次元の名前から次元のIDを取得する.
同様にして, 必要な変数IDはそれぞれ, {\tt NCVID}を
呼び出すことによって名前から決定される.
一旦, 変数IDが分かれば, 変数の属性値は, 要求される属性それぞれについて,
netCDF ID, 変数ID, および要求される属性名を
{\tt NCAGT}または{\tt NCAGT}の入力として与えれば引き出せる.
変数データ値はnetCDFファイルから直接アクセスできる;
単一の値の場合には{\tt NCVGT1}または
{\tt NCVG1C}を使って, 値の断面については
{\tt NCVGT}, {\tt NCVGTC}, {\tt NCVGTG}, または{\tt NCVGGC}を使って.

最後に, netCDFファイルは{\tt NCCLOS}を使ってクローズされる.
単に読むだけなら, ファイルをクローズする必要はない.

%-----------------------------------------------------------------------
\section{名前を知らずに, netCDFファイルを読む}

多くのプログラム(例えば, 総括的なソフトウェア)は(訳注: この部分が原文
で落丁している)を取得する必要がある.
各変数を(多分, 座標変数は除いて), それらの変数の名前を前もって知ること
なしに, 何らかの方法で加工するようなプログラム(例えば, 総括的なソフト
ウェア)を書くことは可能である.
たとえ, 次元および属性の名前が分かっていなくとも.

名前および他の情報は問合せ関数を呼び出すことによってnetCDFファイルから
得ることができる.
これらの呼び出しは, netCDFファイル全体, 次元, 変数, または属性について
の情報を返す.
以下の表は, それらの呼び出しの使われ方を説明するものである:
{\baselineskip=\vs
\begin{verbatim}
    NCOPN                 !  既存のnetCDFファイルをオープンする
      ...
    NCINQ                 !  中身を調べる
         ...
       NCDINQ             !  次元の名前, サイズを取得する
         ...
       NCVINQ             !  変数の名前, 型, 形を取得する
            ...
          NCANAM          !  属性の名前を取得する
            ...
          NCAINQ          !  属性の型と長さを取得する
            ...
          NCAGT or NCAGTC !  属性の値を取得する
            ...
       NCVGT or NCVGTC    !  変数の値を取得する
         ...
    NCCLOS                !  netCDFファイルをクローズする
\end{verbatim} }

前の例と同様に, 単一の呼び出しによって既存のnetCDFファイルがオープンさ
れ, netCDF IDが返される.
このnetCDFは{\tt NCINQ}ルーチンに与えられ, 次元
の数, 変数の数, グローバル属性の数, および, もしあれば無制限次元のID,
を返す.

問合せ関数のすべては, 使用にあたってのコストは非常に少なくかつI/Oを必
要としない, なぜなら, それらが与える情報はメモリ上に格納されているから
である.
Cインターフェースにおいては, 必要ない情報については有効なアドレスの代
わりにヌルポインタを与えるようにして, 情報の一部を得ることもサポートし
ている.

次元のIDは連続した整数(Cでは0から, FORTRANでは1から始まる)を使って割り
当てられる.
次元もまた, 一旦生成されてしまうと, 削除できない.
従って, あるnetCDFファイル中の次元IDの数を知るということは, すべての次
元IDを知ることを意味している:
それらは, 0, 1, 2, ...(FORTRANでは1, 2, 3, ...)という整数である.
各次元IDについて, 呼び出し{\tt NCDINQ}は次元の名前とサイズを返す.

変数IDもまた連続した整数0, 1, 2, ...(FORTRANでは1, 2, 3, ...)が割り当
てられる.
これらのIDは, 各変数に割り当てられた名前, 型, 形, および属性の数を調べ
るために, {\tt NCVINQ}呼び出しで使われる.

変数の属性の数が一旦分かれば, 以下の{\tt NCANAM}の呼び出しにより, 与え
られたnetCDF ID, 変数ID, および属性番号から, 各属性の名前が返される.
属性名が分かれば, {\tt NCAINQ}の呼び出しにより,
その型および長さが返される.
型と長さが与えられれば, 属性の値を保持するのに十分なスペースを割り付け
ることができる.
それから, {\tt NCAGT}または{\tt NCAGlTC}を呼び出
すと, 属性の値が返される.

すべてのnetCDF構成要素の名前, 型, 形, および長さが一旦分かれば, データ
値はアクセス可能である; 単一の値については{\tt NCVGT1}または{\tt
NCVGT1C}を, 配列アクセスを使う値の集合体につい
ては{\tt NCVGT}, {\tt NCVGTC}, {\tt NCVGTG}, または{\tt NCVGGC}を,
呼び出すことによって.

%-----------------------------------------------------------------------
\section{新しい次元, 変数, 属性を追加する}

既存のnetCDFファイルは幅広く変更可能である.
新しい次元, 変数, 属性を追加したり, 既存のものの名前を変更したり,
既存の属性を削除したりできる.
既存の次元, 変数, および属性は名前を変更できる.
以下のコード表は, 既存のファイルに新しいnetCDF構成要素を加えるための一
般的な一連の呼び出しをリスト化したものである:
{\baselineskip=\vs
\begin{verbatim}
    NCOPN             !  既存のnetCDFファイルをオープンする
      ...
    NCREDF            !  定義モードに入る
        ...
      NCDDEF          !  追加する次元を定義する (もしあれば)
        ...
      NCVDEF          !  追加する変数を定義する (もしあれば)
        ...
      NCAPT or NCAPTC !  追加する属性を定義する (もしあれば)
        ...
    NCENDF            !  定義をチェックし, 定義モードから抜ける
        ...
      NCVPT or NCVPTC !  新しい変数に値を与える
        ...
    NCCLOS            !  netCDFをクローズする
\end{verbatim} }

netCDFファイルはまず{\tt NCOPN}呼び出しによってオープンされる.
この呼び出しにより, {\bf データモード}に入り, それによって既存のデータ
値へのアクセスおよび変更が可能であり, 既存の属性が変更できる(それらが
大きくならない限り)が, 何も追加することができない.
新しいnetCDF次元, 変数, または属性を追加するためには, データモードを抜
けて{\bf 定義モード}に入らねばならず, このために{\tt NCREDF}を呼び出せばよい.
定義モードにおいては, {\tt NCDDEF}を呼び出して
新しい次元を定義し, {\tt NCVDEF})により新しい変数
を定義し, {\tt NCAPT}または{\tt NCAPTC}により変
数に新しい属性を割り当てたり古い属性を大きくしたりする.

{\tt NCENDF}を呼び出すことによって, 
定義モードを抜けて再びデータモードに入る;
この際, 新しい定義すべてに矛盾がないかチェックされ, 変更がディスクへ書
き出される.
データモードに再び入る必要がないなら, 単に{\tt NCCLOS}を呼び出せばよい; 
これは先に{\tt NCENDF}を呼び出したのと同じ効果がある.

{\tt NCENDF}を呼び出すまでは, {\tt NCABOR}を呼び出すことによって, 定義
モードでなされた再定義すべてを外してnetCDFデータセットの前の状態を復旧できる.
また, {\tt NCENDF}呼び出しが失敗した場合に,
{\tt NCABOR}を呼び出すことによってnetCDFデータセッ
トを矛盾のない状態に復旧できる.
定義モードから{\tt NCCLOS}を呼び出した際に暗に呼
び出される{\tt NCENDF}が失敗すると, 
{\tt NCABOR}が自動的に呼び出され, netCDFファイル
がクローズされ, ファイルは前の矛盾のない状態(定義モードに入る前の状態)
のままになる.

%-----------------------------------------------------------------------
\section{エラー処理}
\label{エラー処理}

netCDFライブラリは柔軟にエラーを処理するために必要な機能を提供している.
しかし, エラー処理について何か指定する必要はたいていない, なぜなら, デ
フォルトではすべてのnetCDFライブラリルーチンはエラーが生じると単にエラー
メッセージを出力して終了してしまうだけだからである.
もし, このような(確かに徹底的な)エラー時の挙動が容認できるものであれば,
返り値をチェックする必要はない; なぜなら, エラーに至るようなどのような
状態でも説明メッセージを出力して終了してしまうからである.
簡単のために, このガイドにおける例では, このデフォルトのエラー処理の挙
動を仮定するので, 返り値のチェックはしない.

FORTRANインターフェースにおいては, エラーオプションには{\tt NCPOPT}お
よび{\tt NCGOPT}ルーチンを使ってアクセスできる.
エラー処理の2つの面: エラーメッセージの抑制およびエラーの致死性
が独立に修正できる.
エラーが生じるとメッセージを出力して終了するというデフォルトの挙動は, 
以下の文に等しい:
\begin{verbatim}
      CALL NCPOPT(NCVERBOS+NCFATAL)
\end{verbatim}
ここに, {\tt NCVERBOS}および{\tt NCFATAL}の値はFORTRANインクルードファイル
`{\tt netcdf.inc}'で事前に定義されている定数である.
もし, エラーメッセージは残して, エラー時に終了したくない場合には,
致死的エラーフラグを以下のように切ればよい:
\begin{verbatim}
      CALL NCPOPT(NCVERBOS)
\end{verbatim}
もし, エラーメッセージもエラー時の終了もさせたくないならば, 両方のフラ
グを以下のように切ればよい:
\begin{verbatim}
      CALL NCPOPT(0)
\end{verbatim}
エラーオプションの現在の値を取得するには, 以下のように使う:
\begin{verbatim}
      CALL NCGOPT(NCOPTS)
\end{verbatim}

どちらの場合においても, 整数の返り値(すべてのFORTRANサブルーチンおよび
関数の最後のパラメター)は, エラーの性質を決定するために使うことができ
る0以外のnetCDF特定のエラーナンバーを含んでいる.
netCDFエラーコードの名前および記述は`{\tt netcdf.inc}'ファイルに含まれ
ている.

時折, netCDFライブラリの下のXDRライブラリ層で下位レベルの書き込みエラー
が起きる可能性がある.
例えば, 書き込みのオペレーションにより, ディスクの割り当てを超えたり,
もはや使えないデバイスに書き込もうとしたりすると, netCDFライブラリから
ではなく, XDR関数の一つからエラーメッセージを受け取る可能性がある.

%-----------------------------------------------------------------------
\section{netCDFライブラリのコンパイルとリンク}

netCDFのCまたはFORTRANインターフェースを使うプログラムのコンパイルおよ
びリンクの仕方の詳細は, オペレーティングシステム, 使えるコンパイラ, お
よびnetCDFライブラリおよびインクルードファイルがどこにインストールされ
ているか, に依存して異なる.
ではあるが, ここではUnixプラットフォーム上でnetCDFライブラリを使うプロ
グラムのコンパイルおよびリンク方法の例を与えるので, これらの例をインス
トールの状況に応じて直せばよい.

netCDF関数または定数を参照するFORTRANファイルはそれぞれ, そのような最
初の参照の前に適切な{\tt INCLUDE}文を含んでいなければならない:
\begin{verbatim}
      INCLUDE 'netcdf.inc'
\end{verbatim}

`{\tt netcdf.inc}'ファイルがFORTRANコンパイラがいつも参照する標準的ディ
レクトリにインストールされていない場合には, コンパイラを呼び出す際に
{\tt -I}オプションを使って`{\tt netcdf.inc}'がインストールされているディ
レクトリを指定しなければならない, 例えば:
\begin{verbatim}
      f77 -c -I/usr/local/netcdf/include myprogram.f
\end{verbatim}
代わりに, {\tt INCLUDE}文に絶対パスを指定することもできるが, そうする
とnetCDFが異なった位置にインストールされている他のプラットフォームでそ
のプログラムがコンパイルできなくなってしまう.

netCDFライブラリがリンカがいつも参照する標準的ディレクトリにインストー
ルされていない場合には, ライブラリを使うオブジェクトファイルをリンクす
るために{\tt -L}および{\tt -l}オプションを使わねばならない, 例えば:
\begin{verbatim}
      f77 -o myprogram myprogram.o -L/usr/local/netcdf/lib -lnetcdf
\end{verbatim}
代わりに, ライブラリの絶対パスを指定することもできる:
\begin{verbatim}
      f77 -o myprogram myprogram.o -l/usr/local/netcdf/lib/libnetcdf.a
\end{verbatim}

netCDFライブラリに加えて, システムのXDRライブラリのあるライブラリを追加
して指定しなければならないシステムもある.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{ファイル}
\label{ファイル}

この章では, netCDFファイル全体を扱うnetCDFルーチンのインターフェースに
ついて述べる.

まだオープンされていないnetCDFファイルはそのファイル名によってのみ参照
できる.
いったんnetCDFファイルがオープンされた後は, そのファイルは{\bf netCDF
ID}によって参照することができ, そのIDはファイルを生成またはオープンし
た際に返される小さな非負の整数である.
netCDF IDはCにおけるファイル記述子またはFORTRANにおける論理装置番号に
よく似たものである.
単一のプログラムにおいてはいつも, オープンされた異なるnetCDFファイルの
netCDF IDは別々である.
一つのetCDFファイルは複数回オープンすることができ, 従って複数の異なる
netCDF IDを持つことになる; しかし, 一つのnetCDFファイルに対してオープ
ンされている装置のうち一つまでしか書き込みは許されない.
オープンされていたnetCDFファイルがクローズされると, そのIDはもはや
netCDFファイルとは関連しなくなる.

netCDFファイル上で一つのオブジェクトとしてサポートされている操作は:
\begin{itemize}
\item ファイル名および上書きするかどうかを決めて, ファイルを生成する.
\item ファイル名および読み/書きどちらを行うかを決めて, アクセスのため
にファイルをオープンする.
\item 次元, 変数, 属性を追加するために定義モードに入る.
\item 追加した内容の一貫性をチェックして定義モードから抜ける.
\item 必要ならばディスクに書き込んでからファイルをクローズする.
\item 次元の数, 変数の数, グローバル属性の数, およびもしあれば無制限次
元のID, を取得する.
\item 現在の状態を確保するためにディスクとの同期をとる.
\item 最適な連続的書き込みのための{\bf nofill}モードをセットまたは解除
する.
\end{itemize}
この章では, netCDFのCおよびFORTRANインターフェースを記述するのに使われ
る慣習をまとめたあと, 残りの部分でこれらの操作のためのインターフェー
スについて述べる.

%-----------------------------------------------------------------------
\section{netCDFライブラリインターフェースの記述}

本章および後の章における, ある特定のnetCDF関数に対する各インターフェー
スの記述は以下の事項を含む:
\begin{itemize}
\item 関数の目的の記述
\item 起りうるエラー状態のリスト
\item FOTRAN関数のプロトタイプ:
そのFORTRAN関数への正式なパラメターの型および順序を示す.
\item そのFORTRANインターフェースにおける正式パラメターそれぞれについ
ての説明
\item そのnetCDF関数(および他のnetCDF関数)を呼び出すFORTRANプログラム
断片の例
\end{itemize}

FORTRAN関数のプロトタイプは正式なパラメターの型および順序を簡潔に示す.

%-----------------------------------------------------------------------
\section{netCDFファイルの生成: NCCRE}

関数{\tt NCCRE}は新たなnetCDFファイルを生成し, 以降そのnetCDFを参照す
るために使われるnetCDF IDを返す.
そのnetCDFファイルは定義モードになっている.

エラーが起きた場合には, {\tt NCCRE}は{\tt RCODE}に零以外の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 存在しないディレクトリを含んだファイル名を渡している場合.
\item すでに存在しているファイルを指定し, かつ{\tt NCNOCLOB}を指定した
場合.
\item ファイルを作成するためのパーミッションが与えられていないディレク
トリにファイルを生成しようとしている場合.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCCRE (CHARACTER*(*) FILENAME, INTEGER CMODE, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt FILENAME] 新規のnetCDFファイルのファイル名.
\item[\tt CMODE] {\tt NCCLOB}または{\tt NCNOCLOB}のどちらかを指定する.
 これらの定数は, インクルードファイル`{\tt netcdf.inc}'で定義される.
 {\tt NCCLOB}は, たとえファイルがすでに存在しても, 古いファイルの内容を
 消去して同じ名前の新しいファイルを作成したい場合に指定する.
 {\tt NCCLOB}は, 与えられたファイル名が既存のファイルを指していない場合
 のみに新規のnetCDFファイルを作成したい場合に指定する.
\item[\tt RCODE]  返されたエラーコード. エラーが生じていなければ, 0
 が返される.
\end{description}
\end{quote}

以下の例では, `{\tt foo.nc}'という名前のnetCDFファイルを作成している.
ここでは, その名前のファイルがまだ存在していない場合のみ, カレントディ
レクトリにそのファイルを作成したい場合であるとしている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID
         ...
      NCID = NCCRE('foo.nc', NCNOCLOB, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{アクセスのためにnetCDFファイルをオープンする: NCOPN}

関数{\tt NCOPN}はアクセスのために既存のnetCDFファイルをオープンする.

エラーが生じた場合には, {\tt NCOPN}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたnetCDFファイルが存在していない.
\item 指定されたモードが{\tt NCWRITE}または{\tt NCNOWRITE}以外である.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCOPN (CHARACTER*(*) FILENAME, INTEGER RWMODE, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt FILENAME] オープンするnetCDFファイルの名前.
\item[\tt RWMODE] ファイルを書き込みのためにオープンする{\tt NCWRITE}
 または, ファイルを読み込みのみでオープンする{\tt NCNOWRIT}のどちらかを
 指定する. ``書き込み''は, データの変更, 次元, 変数および属性の追加また
 は名前のつけかえ, または属性の削除, を含んだあらゆる種類のファイルの変
 更を意味している.
\item[\tt RCODE] 返されたエラーコードを. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCOPN}を使って`{\tt foo.nc}'という名前の既存の
netCDFファイルを読み込みのためにオープンしている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID
         ...
      NCID = NCOPN('foo.nc', NCNOWRIT, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{netCDFファイルを定義モードにする: NCREDF}

関数{\tt NCREDF}はオープンされたnetCDFファイルを定義モードにし,
次元, 変数および属性を追加またはその名前を変更できるように, また属性を
削除できるようにする.

エラーが生じた場合には, {\tt NCREDF}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたnetCDFファイルがすでに定義モードになっている.
\item 指定されたnetCDFファイルが読み込みのみでオープンされている.
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCREDF (INTEGER NCID, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID]  以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCREDF}を使って`{\tt foo.nc}'という名前の既存の
netCDFファイルをオープンし, それを定義モードにしている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID
         ...
      NCID = NCOPN('foo.nc', NCWRITE, RCODE)
         ...
      CALL  NCREDF(NCID, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{定義モードから抜ける: NCENDF}

関数{\tt NCENDF}はオープンされたnetCDFファイルを定義モードから出す.
定義モードになっているうちに加えられたnetCDFファイルへの変更はチェック
され, 問題が生じていなければディスクに書き込まれる.
このとき, netCDFファイルはデータモードになっており, 変数データが読み書
きできる.

この呼び出しは, ある環境においては記録変数ではない変数の初期化およびデー
タのコピーを含むので, コストがかかる.
より広範な議論については, 9章[netCDFファイル構造および性能]
\pageref{netCDFファイル構造および性能}ページを参照.

エラーが生じた場合には, {\tt NCENDF}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたnetCDFファイルが定義モードになっていない.
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCENDF (INTEGER NCID, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCENDF}を使って`{\tt foo.nc}'という名前の新しい
netCDFファイルの定義モードを終了し, それをデータモードにしている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID
         ...
      NCID = NCCRE('foo.nc', NCNOCLOB, RCODE)
         ... ! 次元, 変数, 属性を作成する.
      CALL  NCENDF(NCID, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{netCDFファイルをクローズする: NCCLOS}

関数{\tt NCCLOS}はオープンされたnetCDFファイルをクローズする.
もしそのファイルが定義モードであれば, クローズする前に{\tt NCENDF}が呼
び出される.
(この場合, もし{\tt NCENDF}がエラーを返せば, {\tt NCABOR}が自動的に呼
び出され, 定義モードに最後に入る前の矛盾のない状態に復旧する.)
オープンされたnetCDFファイルがクローズされた後では, そのnetCDF IDは次
にオープンまたは作成されるnetCDFファイルに割り当てられる.

エラーが生じた場合には, {\tt NCCLOS}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 定義モードになっていて, {\tt NCENDF}の自動的な呼び出しが失敗した.
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCENDF (INTEGER NCID, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCCLOS}を使って`{\tt foo.nc}'という名前の新しい
netCDFファイルの定義モードを終了し, そのnetCDF IDを解放している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID
         ...
      NCID = NCCRE('foo.nc', NCNOCLOB, RCODE)
         ... ! 次元, 変数, 属性を作成する.
      CALL  NCCLOS(NCID, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{オープンされたnetCDFファイルについて問合せをする: NCINQ}

関数{\tt NCINQ}は, netCDF IDを与えて, オープンされたnetCDFファイル
についての情報を返す.
それは定義モードまたはデータモードから呼び出すことができる.
それは, 次元の数, 変数の数, グローバル属性の数, および, 無制限サイズを
持つ次元の次元ID(もしあれば)を返す.
これまたはnetCDFインターフェース中の他のあらゆる`問合せ'関数が呼び出さ
れてもI/Oは要求されない. なぜなら, それらの関数はオープンされた各
netCDFファイルについての表に格納された情報を返すだけだからである.

エラーが生じた場合には, {\tt NCINQ}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCINQ (INTEGER NCID, INTEGER NDIMS, INTEGER NVARS,
     *                  INTEGER NGATTS, INTEGER RECDIM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt NCDIMS] このnetCDFファイルに定義されている次元の数を返す.
\item[\tt NCVARS] このnetCDFファイルに定義されている変数の数を返す.
\item[\tt NCGATTS] このnetCDFファイルに定義されているグローバル属性の数を
返す.
\item[\tt RECDIM] このnetCDFファイルに定義されていれば, 無制限次元のIDを
返す. 無制限サイズの次元が定義されていなければ, {\tt RECDIM}の値として
$-1$が返される.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCINQ}を使って`{\tt foo.nc}'という名前のnetCDFファ
イルについて調べている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, NDIMS, NVARS, NATTS, RECDIM, RCODE
         ...
      NCID = NCCRE('foo.nc', NCNOWRIT, RCODE)
         ...
      CALL  NCINQ(NCID, NDIMS, NVARS, NATTS, RECDIM, RCODE)
\end{verbatim}}


%-----------------------------------------------------------------------
\section{オープンされたnetCDFファイルをディスクに同期する: NCSNC}

関数{\tt NCSNC}は, 書き込みのためにオープンされているnetCDFファイルの
ディスク上のコピーが現在の状態であるようにする.
定義モードにあるnetCDFファイルは{\tt NCENDF}が呼び出されたときにのみディ
スクに同期される.
他のプロセスが書き込んでいるnetCDFファイルを読み込んでいるプロセスが,
そのファイルをクローズして再オープンしたりせずに,
{\tt NCSNC}を呼び出して書き込みプロセスによってなされた変更(例えば,
書かれた記録の数など)に対応した更新をすることもできる.

変数データの書き込みまたは属性値の変更のたびにいつもディスクと同期をと
ると, コンピューター資源におけるコストが大きくなってしまいうる.
書き込みの後で同期をとりたい理由として, 以下の2つが挙げられる:
\begin{itemize}
\item 異常終了の場合のデータ損失を最小にする.
\item データが書かれた直後にそれを読む他のプロセスがそのデータにアクセ
スできるようにする. しかし, 読み込みのためにそのファイルをすでにオープ
ンしているプロセスは, 書き込みプロセスが{\tt NCSNC}を呼び出した際の記
録数の増大を感知できないということに注意が必要である;
これを感知するためには, 読み込みプロセスが{\tt NCSNC}を呼び出す必要が
ある.
\end{itemize}

netCDFファイルがクローズされるか, または定義モードを抜ける際いつでも
データは自動的にディスクに同期される.

エラーが生じた場合には, {\tt NCSNC}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item そのnetCDFファイルが定義モードにある.
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCSNC (INTEGER NCID, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返されたnetCDF ID.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCSNC}を使って`{\tt foo.nc}'という名前の
netCDFファイルのディスク書き込みの同期をとっている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE
         ...
      NCID = NCOPN('foo.nc', NCWRITE, RCODE)
         ...
* データを書く, または属性を変更する.
         ...
      CALL  NCSNC(NCID, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{最新の定義をやめる: NCABOR}

関数{\tt NCABOR}は, もし定義モードになっていなければ, netCDFファイルを
クローズする.
もしそのファイルが作成されたばかりでまだ定義モードにあれば, そのファイ
ルは削除される.
{\tt NCREDF}の呼び出しによって定義モードに入っているなら, netCDFファイ
ルはその定義モードに入る前の状態に復旧され, そのファイルはクローズされ
る.
{\tt NCABOR}を呼び出す主な理由は, 新しい次元, 変数, または属性を定義し
ている間に何か障害が起った場合に, 既知の矛盾のない状態にファイルを復旧
するということである.

この関数は, 定義モードから{\tt NCCLOS}が呼び出されたり, クローズの前に
定義モードから抜けるための呼び出しが失敗したりした場合に自動的に呼び出
される.

エラーが生じた場合には, {\tt NCABOR}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item netCDFファイルを生成している際の定義モードから呼び出された場合に, 
ファイルの削除が失敗した.
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCABOR (INTEGER NCID, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返されたnetCDF ID.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCABOR}を使って`{\tt foo.nc}'という名前のファイルの
再定義をやめている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, LATID
         ...
      NCID = NCOPN('foo.nc', NCWRITE, RCODE)
         ...
      CALL  NCREDF(NCID, RCODE)
         ...
      LATID = NCDDEF(NCID, 'LAT', 18, RCODE)
      IF (RCODE .EQ. -1) THEN  ! 次元の定義が失敗
         CALL NCABOR(NCID, RCODE)  ! 再定義をやめる
      END IF
         ...
\end{verbatim}}

%-----------------------------------------------------------------------
\section{書き込みのフィルモードの設定: NCSFIL}
\label{NCSFIL}

この呼び出しは, 以下に述べるようないくつかの環境における書き込みを最適
化するための, 高度な使用のために意図されたものである.
関数{\tt NCSFIL}は, 書き込みのためにオープンされているnetCDFファイルに
{\bf フィルモード}を設定し, 現在のモードを返す.
フィルモードは{\tt NCFILL}または{\tt NCNOFILL}のどちらかが指定できる.
{\tt NCFILL}に対応するデフォルトの動作では, データはフィル値で前もって
満される. すなわち, 記録のない変数を生成したり, まだ書かれていないとこ
ろのデータを越えて値を書いたりする際にフィル値が書かれる.
これによって, データを, それが書かれる前に読もうとしているような試みを
検出することができる.
フィル値の使用についてのより多くの情報については\ref{フィル値}節
[フィル値]\pageref{フィル値}ページを参照.
独自のフィル値の定義法についての情報は\ref{属性の慣習}節[属性の慣習]
\pageref{属性の慣習}ページを参照.

{\tt NCNOFILL}に対応した動作では, データを前もってフィル値で満すという
デフォルトの動作を無効にする.
これは効率を上げるために使うことができる. なぜなら, netCDFライブラリが
直後にデータで上書きされてしまうようなフィル値を書き込むときに生じる重
複書き込みを回避できるからである.

返り値によって, netCDFファイルがどのモードにあったかということが分かる.
この値を使って, オープンされたnetCDFファイルのフィルモードを一時的に変
えて, それから元のモードに復旧することができる. 

オープンされたnetCDFファイルを{\tt NCNOFILL}モードにした後は,
後で読まれるすべての位置に必ず妥当なデータを書き込まなければならない.
{\tt NCNOFILL}モードは書き込みのためにオープンされたnetCDFファイルの一
時的な性質でしかないことに注意が必要である:
もしそのファイルをクローズして再オープンすると, デフォルトの動作に戻る.
{\tt NCFILL}に陽に設定するために, {\tt NCSFIL}を再び呼び出して, デフォ
ルトの動作に戻ることもできる.

ノーフィルモードに設定するのが有効な状況としては, 以下の3つが考えられ
る:
\begin{enumerate}
\item netCDFファイルを生成または初期化しているとき. この場合, {\tt
NCENDF}を呼び出す前にノーフィルモードを設定し, それからすべての記録な
し変数および初期化したいすべての記録変数の初期記録を{\bf 完璧に}書くべ
きである.
\item 記録指向の既存のnetCDFファイルを拡張しているとき. 書き込みのため
にファイルをオープンした後でノーフィルモードに設定し, その後, 書かれて
いない記録が入り込まないように, 追加の記録をファイルに完璧に追加するこ
と.
\item 初期化する予定の新しい変数を既存のnetCDFファイルに追加するとき.
{\tt NCENDF}を呼び出す前にノーフィルモードを設定し, それから新しい変数
を完璧に書くこと.
\end{enumerate}

netCDFファイルが無制限次元を持ち, その最後の記録が{\tt NCNOFILL}モード
で書かれた場合には, ファイルは{\tt NCNOFILL}モードが設定されていない場
合よりも4バイト長くなるが, netCDFインターフェースだけを使ってデータに
アクセスしていればこの変化は全く透過性を損わない.

エラーが生じた場合には, {\tt NCSFIL}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたnetCDF IDがnetCDFファイルを参照していない.
\item 指定されたnetCDF IDが読み込みのみでオープンされているファイルを
参照している.
\item フィルモードの引数が{\tt NCNOFILL}および{\tt NCFILL}のどちらでも
ない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCSFIL (INTEGER NCID, INTEGER FILLMODE, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返されたnetCDF ID.
\item[\tt FILLMODE] そのファイルに対して希望するフィルモード. {\tt
NCNOFILL}または{\tt NCFILL}のどちらか.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返さ
れる.
\item[\tt NCSFIL] この呼び出しの前のファイルのフィルモードの現状を返す.
{\tt NCNOFILL}または{\tt NCFILL}のどちらか.
\end{description}
\end{quote}

以下の例では, {\tt NCSFIL}を使って`{\tt foo.nc}'という名前のnetCDFファ
イルに対してノーフィルモードを設定している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, OMODE
         ...
* 前もってフィル値を満すデフォルトの動作でデータを書く
         ...
      OMODE = NCSFIL(NCID, NCNOFILL, RCODE)
         ...
* 前もってフィル値を満さずにデータを書く
         ...
\end{verbatim}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{次元}
\label{次元}

netCDFファイルにおける次元は, 生成される際に定義される. これはnetCDFファ
イルが定義モードにある間に行われる.
再び定義モードに入ることによって, 後で追加の次元を追加することもできる.
netCDFの次元は名前とサイズを持っている.
一つのnetCDFファイルにおいては, 一つの次元までが{\tt NC\_UNLIMITED}サイ
ズを持つことができる. このサイズは, この次元を使う変数がこの次元に沿っ
て成長できるということを意味している.

一つのnetCDFファイルで定義できる次元の数には上限(100)が提唱されている.
この上限は前もって定義されているマクロ{\tt MAXNCDIM}の値である.
この上限の目的は, 一般的なアプリケーションをより簡明に書くことである.
それによって, これらのアプリケーションは, {\tt MAXNCDIM}次元の配列さえ
用意しておけば, 任意のnetCDFファイルを扱うことができる.
netCDFライブラリの実装においてはこの勧告された上限を強要してはいないの
で, もし必要ならばより多くの次元を使うことができる.
しかし, できたnetCDFファイルを一般的なアプリケーションやnetCDFユーティ
リティが扱えると思ってはならない.

通常, 次元の名前とサイズは, その次元が最初に定義されたときに固定される.
その名前は後で変えることができるが, 次元のサイズを変えるためには, 次元
サイズを再定義した新しいnetCDFファイルにすべてのデータをコピーしなけれ
ばならない.

Cインターフェースにおける次元サイズは{\tt int}型ではなく{\tt long}型で
ある. これはMSDOSのように, 16ビット{\tt int}データ型しかサポートしていな
いプラットフォーム上でもnetCDFファイル内のすべてのデータにアクセスする
ことを可能にするためである.
そうでなく, もし次元サイズが{\tt int}だと, 16ビット{\tt int}が収容でき
るのより大きな次元サイズをもつ変数からのデータにアクセスすることができ
なくなってしまう.

オープンされたnetCDFファイル中のnetCDF次元は, CおよびFORTRANインターフェー
スにおいて{\bf 次元ID}と呼ばれる小さな整数によて参照される.
Cインターフェースにおいては, 次元IDは0, 1, 2, ..., であるが, FORTRANイ
ンターフェースにおいては, 対応するIDは次元が定義された順番に1, 2, 3,
..., となる.

次元に対してサポートされている操作は以下のようである:
\begin{itemize}
\item 名前とサイズを与えて次元を生成する.
\item 名前から次元IDを取得する.
\item そのIDから次元の名前とサイズを取得する.
\item 次元の名前を変える.
\end{itemize}

%-----------------------------------------------------------------------
\section{次元を生成する: NCDDEF}

関数{\tt NCDDEF}は定義モードにあるオープンされたnetCDFファイルに新しい
次元を追加する.
これは, netCDF ID, 次元名, および次元サイズを与えると次元IDを返す.
それぞれのnetCDFファイルに対して, 一つまでの無制限サイズ次元(これは記
録次元と呼ばれる)がが定義できる.

エラーが生じた場合には, {\tt NCDDEF}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item netCDFファイルが定義モードになっていない.
\item 指定された次元名が他の既存の次元の名前である.
\item 指定されたサイズが0以下である.
\item 指定されたサイズが無制限だが, このnetCDFファイルに対してすでに無
制限サイズの次元が定義されている.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCDDEF (INTEGER NCID, CHARACTER*(*) DIMNAM, 
     +                         INTEGER DIMSIZ, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返されたnetCDF ID.
\item[\tt DIMNAM] 次元名. アルファベット文字で始まり, アンダースコア
('{\tt \_}')を含む零またはそれ以上の英数字が続かねばならない.
大文字小文字は区別される.
\item[\tt DIMSIZ] 次元のサイズ; すなわち, この次元を使う変数へのインデッ
クスとしてのこの次元に対する値の数である.
これは正の整数か, 前もって定義されている定数{\tt NCUNLIM}のどちらかで
なければならない.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCDDEF}を使って{\tt lat}という名前でサイズ18の次元
および{\tt rec}という名前の記録次元を`{\tt foo.nc}'という名前の新しい
netCDFファイルに生成している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, LATID, RECID
         ...
      NCID = NCCRE('foo.nc', NCNOCLOB, RCODE)
         ...
      LATID = NCDDEF(NCID, 'lat', 18, RCODE)
      RECID = NCDDEF(NCID, 'rec', NCUNLIM, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{名前から次元IDを取得する: NCDID}

関数{\tt NCDID}は, 名前を与えて, netCDF次元のIDを返す. {\tt ndims}は
netCDFファイルで定義されている次元の数で, それぞれの次元は{\tt 1}から
{\tt ndims}の間のIDを持つ.

エラーが生じた場合には, {\tt NCDDEF}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された名前がそのneCDFファイル中で現在定義されているどの次元
の名前でもない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCDID (INTEGER NCID, CHARACTER*(*) DIMNAME, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt DIMNAME] 次元名. アルファベット文字で始まり, アンダースコア
 ('{\tt \_}')を含む零またはそれ以上の英数字が続かねばならない.
 大文字小文字は区別される.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCDID}を使って, {\tt lat}という名前の次元の次元IDを
決定している(既存の`{\tt foo.nc}'という名前のnetCDFファイルにおいて過
去に定義されていると仮定している):
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, LATID
         ...
      NCID = NCOPN('foo.nc', NCNOWRIT, RCODE)
         ...
      LATID = NCDDEF(NCID, 'lat', RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{次元について問合せる: NCDINQ}

関数{\tt NCDINQ}は, 次元IDを与えて, 次元の名前とサイズを返す.
無制限次元(もしあれば)のサイズはそれまで書かれている記録の数である.

エラーが生じた場合には, {\tt NCDINQ}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたneCDFファイルにおいて, その次元IDが不適当である.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCDINQ (INTEGER NCID, INTEGER DIMID, CHARACTER*(*) DIMNAM, 
     +                   INTEGER DIMSIZ, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt DIMID] 以前の{\tt NClDID}または{\tt NCDDEF}呼び出しで返された
 次元ID. 
\item[\tt DIMNAM] 返された次元名. 返される名前のためのスペースを割り当て
 ておかねばならない. 次元名の可能な最大文字長は, 前もって定義されている
定数{\tt MAXNCNAM}で与えられている.
\item[\tt DIMSIZ] 返された次元サイズ. 無制限次元については, これは, この
 次元をもつ任意の変数に書き込むのに使われた現在の最大値である.
 すなわち, 記録数の最大値である.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCDINQ}を使って, 既存の`{\tt foo.nc}'という名前の
netCDFファイルについて, {\tt lat}という名前の次元のサイズ, および無制
限(記録)次元の名前と現在の最大サイズを決めている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, LATID, LATSIZ
      INTEGER NDIMS, NVARS, NGATTS, RECID, NRECS
* 以下の宣言における31はパラメターMAXNCNAMである.
      CHARACTER*31 LATNAM, RECNAM
         ...
      NCID = NCOPN('foo.nc', NCNOWRIT, RCODE)
         ...
      LATID = NCDDEF(NCID, 'lat', RCODE)
* latの名前とサイズを取得する(すでに名前は知っているが)
      CALL NCDINQ(NCID, LATID, LATNAM, LATSIZ, RCODE)
* 記録次元のIDを取得する(まず第1に)
      CALL NCINQ(NCID, NDIMS, NVARS, NGATTS, RECID, RCODE)
* 記録次元の名前と現在のサイズを取得する
      CALL NCDINQ(NCID, RECID, RECNAME, NRECS, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{次元の名前を変える: NCDREN}

関数{\tt NCDREN}は, 書き込みのためにオープンされているnetCDFファイルに
おける既存の次元の名前を変える.
もし新しい名前が古い名前より長ければ, そのnetCDFデータセットは定義モー
ドでなければならない.
ある次元の名前を他の次元と同じ名前にるすることはできない.

エラーが生じた場合には, {\tt NCDREN}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 新しい名前が他の次元の名前である.
\item 指定されたneCDFファイルにおいて, その次元IDが不適当である.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\item 新しい名前が古い名前より長く, かつnetCDFファイルが定義モードにな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCDREN (INTEGER NCID, INTEGER DIMID, CHARACTER*(*) DIMNAME, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt DIMID] 以前の{\tt NClDID}または{\tt NCDDEF}呼び出しで返された
 次元ID.
\item[\tt DIMNAM] 次元の新しい名前.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCDREN}を使って, 既存の`{\tt foo.nc}'という名前の
netCDFファイルについて, 次元の名前を{\tt ``lat''}から{\tt ``latitude''}
に変えている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE, LATID
         ...
      NCID = NCOPN('foo.nc', NCNOWRIT, RCODE)
         ...
* 次元名を変えるために定義モードに入る
      CALL NCREDF(NCID, RCODE)
      LATID = NCDID(NCID, 'lat', RCODE)
      CALL NCDREN(NCID, LATID, 'latitude', RCODE)
* 定義モードを抜ける
      CALL NCENDF(NCID, RCODE)
\end{verbatim}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{変数}
\label{変数}

netCDFファイルにおける変数はファイルが生成される際に定義される. 
これはnetCDFファイルが定義モードにある間に行われる.
再び定義モードに入ることによって, 後で他の変数を追加することもできる.
netCDFの変数は名前, 型, および形を持ち, これらは変数が定義される際に
定義される.
変数は値も持つことができ, これは後にデータモードで確定される.

通常, 名前, 型, および形は変数が最初に定義される際に固定される.
名前は変えることができるが, 変数の型および形は変えることができない.
しかし, 無制限次元を使って定義されている変数はその次元における上限なし
で成長できる.

オープンされたnetCDFファイル中のnetCDF変数は, CおよびFORTRANインターフェー
スにおいて{\bf 変数ID}と呼ばれる小さな整数で参照される.
変数IDはnetCDFファイル内で変数が定義された順番を反映している.
FORTRANインターフェースにおいては, 変数IDは変数が定義された順番に1, 2,
3, ..., である.
どちらのインターフェースにおいても, 変数名から変数IDを取得およびその逆
を行うための関数が用意されている.

単位のような性質を指定するために, 変数に属性(8章[属性]
\pageref{属性}ページを参照)を伴っていてもよい.

変数に対してサポートされている操作は以下のようである:
\begin{itemize}
\item 名前, データ型, および形を与えて変数を生成する.
\item 名前から変数IDを取得する.
\item そのIDから変数の名前, データ型, 形および属性の数を取得する.
\item 変数ID, 番号, および値を与えて変数にデータ値を入れる.
\item 変数ID, 隅の番号, 縁の長さ, および一まとまりのデータを与えて変数
に値の配列を入れる.
\item 変数ID, 隅の番号, 縁の長さ, ストライドベクトル, インデックスマッ
ピングベクトルおよび一まとまりのデータを与えて部分的にサンプルされたま
たはマップされた値の配列断面を変数に入れる.
\item 記録番号, および値のまとまりへのポインタを与えて値を記録変数に入
れる.
\item 変数IDおよび番号を与えて変数からデータを取得する.
\item 変数ID, 隅の番号および縁の長さを与えて変数から値の配列を取得する.
\item 変数ID, 隅の番号, 縁の長さ, ストライドベクトルおよびインデックス
マッピングベクトルを与えて部分的にサンプルされたまたはマップされた値の
配列断面を変数から取得する.
\item 記録番号, および各記録変数のデータがどこに格納されているかを示す
ポインタを与えて, 記録変数から値を取得する.
\item 変数の名前を変える.
\item 与えられたデータ型のバイト数を取得する.
\item 記録変数の数, それらのID, およびそれらの記録サイズを取得する.
\end{itemize}

%---------------------------------------------------------------------
\section{netCDFデータ型に対応した言語の型}

以下の表にnetCDFデータ型とFOTRANデータ型との対応を示す:
\begin{quote}
\begin{tabular}{l|ll|r}
netCDF/CDL &amp; \multicolumn{2}{c|}{FORTRAN}   &amp; \\
\multicolumn{1}{c|}{Data Type}  
&amp; \multicolumn{1}{c}{Data Type}  
&amp; \multicolumn{1}{c|}{API Mnemonic}  &amp; Bits \\\hline
{\tt byte} &amp; {\tt BYTE, LOGICAL*1 (INTEGER)} &amp; {\tt NCBYTE} &amp; {\tt 8} \\
{\tt char} &amp; {\tt CHARACTER } &amp; {\tt NCCHAR} &amp; {\tt 8} \\
{\tt short} &amp; {\tt INTEGER*2 (INTEGER) } &amp; {\tt NCSHORT} &amp; {\tt 16} \\
{\tt long} &amp; {\tt INTEGER*4 (INTEGER) } &amp; {\tt NCLONG} &amp; {\tt 32} \\
{\tt float} &amp; {\tt REAL*4 (REAL) } &amp; {\tt NCFLOAT} &amp; {\tt 32} \\
{\tt double} &amp; {\tt REAL*8 (DOUBLEPRECISION) } &amp; {\tt NCDOUBLE} &amp; {\tt 64} 
\end{tabular}
\end{quote}

最初のコラムはnetCDFデータを与えているが, これはCDLデータ型と同じであ
る.
次の一組のコラムは, それぞれ, 最初のコラムに対応するFORTRANデータ型お
よび, netCDFルーチンを呼び出す際に使われる対応するFORTRANパラメターで
ある(このパラメターはnetCDF FORTRANインクルードファイル{\tt
netcdf.inc}で定義されている).
できれば, 括弧で括っていないFORTRAN型を使った方がよい.
手持ちのFORTRANコンパイラがサポートしていない型については, 対応する括
弧で括られた型を使うこと.
最後のコラムは対応する型の値を外部表現するのに使われるビット数である.

netCDFライブラリの現在のバージョンでは, 64ビット整数または複数バイトの
文字に対応するnetCDF型が無いことに注意されたい.

%-----------------------------------------------------------------------
\section{変数を生成する: NCVDEF}

関数{\tt NCVDEF}は, 定義モードにあるオープンされているnetCDFファイルに
新しい変数を追加する.
netCDF ID, 変数名, 変数型, 次元の数, および次元IDのリストを与えると,
変数IDが返される.

エラーが生じた場合には, {\tt NCVDEF}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item netCDFファイルが定義モードにない.
\item 指定された変数名が他の既存の変数名である.
\item 指定された型が, 適当なnetCDF型でない.
\item 指定された次元の数が負であるか, または定数{\tt MAX\_VAR\_DIMS}
より大きい; この定数は, netCDF変数に対して許されている次元の最大数である.
\item 次元のリストにおける一つまたはそれ以上の次元IDがそのnetCDFファイルに対して適当でない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCVDEF (INTEGER NCID, CHARACTER*(*) VARNAM, INTEGER VARTYP,
     +                         INTEGER NVDIMS, INTEGER VDIMS(*), INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
netCDF ID.
\item[\tt VARNAM] 変数名. アルファベット文字で始まり, アンダースコア
 ('{\tt \_}')を含む零またはそれ以上の英数字が続かねばならない.
 大文字小文字は区別される.
\item[\tt VARTYP] 前もって定義されているnetCDFデータ型集合の一つ. 適当な
netCDFデータ型は{\tt NCBYTE}, {\tt NCCHAR}, {\tt NCSHORT},
{\tt NCLONG}, {\tt NCFLOAT}, および{\tt NCDOUBLE}である.
\item[\tt NVDIMS] その変数に対する次元の数. 例えば, {\tt 2}は行列, {\tt
1}はベクトル, および{\tt 0}はその変数が次元を持たないスカラーであるこ
とを意味する. これは負であったり, 前もって定義されている定数{\tt
MAXVDIMS}より大きくてはならない.
\item[\tt VDIMS] 変数次元に対応する次元IDの{\tt NVDIMS}ベクトル.
無制限次元のIDが含まれている場合には, それば最後でなければならない.
この引数は, {\tt NVDIMS}が{\tt 0}の場合には無視される.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVDEF}を使って, 既存の`{\tt foo.nc}'という名前の
新しいnetCDFファイルについて, 3つの次元{\tt time}, {\tt lat}, および
{\tt lon}を持つ名前{\tt rh}の{\tt long}型変数を生成している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  LATDIM, LONDIM, TIMDIM  ! 次元ID
      INTEGER  RHID                    ! 変数ID
      INTEGER  RHDIMS(3)               ! 変数形
         ...
      NCID = NCCRE ('foo.nc', NC_CLOBBER, RCODE)
         ...
                                       ! 次元の定義
      LATDIM = NCDDEF(NCID, 'lat', 5, RCODE)
      LONDIM = NCDDEF(NCID, 'lon', 10, RCODE)
      TIMDIM = NCDDEF(NCID, 'time', NCUNLIM, RCODE)
         ...
                                       ! 変数の定義
      RHDIMS(1) = LONDIM
      RHDIMS(2) = LATDIM
      RHDIMS(3) = TIMDIM
      RHID = NCVDEF (NCID, 'rh', NCDOUBLE, 3, RHDIMS, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{名前から変数IDを取得する: NCVID}

関数{\tt NCVID}は, 名前を与えて, netCDF変数のIDを返す.

エラーが生じた場合には, {\tt NCVID}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数名が, 指定されたnetCDFファイル中の変数名として適当
でない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCVID (INTEGER NCID, CHARACTER*(*) VARNAM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARNAM] IDが欲しい変数名.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVID}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数のIDを調べている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID                    ! 変数ID
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{IDから変数についての情報を取得する: NCVINQ}

関数{\tt NCVINQ}は, IDを与えて, netCDF変数についての情報を返す.
返される情報は, 名前, 型, 次元の数, 変数の形を記述する次元IDのリスト,
および変数に割り当てられている変数属性の数, である.

エラーが生じた場合には, {\tt NCVINQ}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVINQ (INTEGER NCID, INTEGER VARID, CHARACTER*(*) VARNAM,
     +                   INTEGER VARTYP, INTEGER NVDIMS, INTEGER VDIMS(*),
     +                   INTEGER NVATTS, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt VARNAM] 返された変数名. 返される名前のためのスペースを割り当て
ておかねばならない. 変数名の可能な最大文字長は, 前もって定義されている
定数{\tt MAXNCNAM}で与えられている.
\item[\tt VARTYP] 返されるデータ型であり, 前もって定義されているnetCDFデー
 タ型集合の一つ. 適当なnetCDFデータ型は{\tt NCBYTE}, {\tt NCCHAR}, {\tt
 NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および{\tt NCDOUBLE}である.
\item[\tt NVDIMS] その変数に対する次元の数が返される. 例えば, {\tt 2}は行
 列, {\tt 1}はベクトル, および{\tt 0}はその変数が次元を持たないスカラー
 であることを意味する.
\item[\tt VDIMS] 変数次元に対応する次元IDの{\tt NVDIMS}ベクトルが返される.
 少なくとも, {\tt NVDIMS}の整数のベクトルが返されるのに十分なスペースを
 割り当てておかねばならない.
 変数に対する次元数の可能な最大値は前もって定義されている定数{\tt
 MAXVDIMS}で与えられている.
\item[\tt NVATS] この変数に割り当てられている変数属性の数を返す.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVINQ}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数について調べている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
      CHARACTER*31 RHNAME         ! 変数名
      INTEGER  RHTYPE             ! 変数型
      INTEGER  RHN                ! 次元の数
      INTEGER  RHDIMS(MAXVDIMS)   ! 変数の形
      INTEGER  RHNATT             ! 属性の数
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)  ! IDを取得
      CALL NCVINQ (NCID, RHID, RHNAME, RHTYPE, RHN, RHDIMS, RHNATT, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{単一のデータ値を書き込む: NCVPT1およびNCVP1C}

関数{\tt NCVPT1}または{\tt NCVP1C}は, データモードにあるオープンされた
netCDFファイルの変数に単一のデータ値を書く.
入力は, netCDF ID, 変数ID, どの値が追加または変更されるかを指定する複
数次元のインデックス, およびデータ値, である.

エラーが生じた場合には, {\tt NCVPT1}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定されたインデックスが指定された変数のランクの範囲から外れてい
る. 例えば, 負のインデックスまたは, 対応する次元サイズより大きなインデッ
クス, はエラーを起す.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVPT1 (INTEGER NCID, INTEGER VARID, INTEGER MINDEX(*),
     +                   型 VALUE, INTEGER RCODE)

      SUBROUTINE NCVP1C (INTEGER NCID, INTEGER VARID, INTEGER MINDEX(*),
     +                   CHARACTER CHVAL, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVPT1}および{\tt NCVP1C}は変数に単一の値
を書く.
最初のものは数値型の変数に数値を書き, 2番目のものは文字型変数に文字値
を書く.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt MINDEX] 書くデータ値の複数次元のインデックス.
 このインデックスは1に相対的なものであり, それゆえ, 例えば2次元変数の
 最初のデータ値はインデックス{\tt (1,1)}を持つ.
 {\tt MINDEX}の要素はその変数の次元に対応していなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスは記録数に対応
 していなければならない.
\item[\tt VALUE] {\tt NCVPT1}における, 書くデータ値である.
 このデータはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, netCDF変数の型として適当
 でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt CHVAL] {\tt NCVP1C}における, 書くデータ値である.
 このデータはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応した文字型でな
 ければならない.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVPT1}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数の{\tt (4,3,2)}要素に
{\tt 0.5}をセットしている.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていることを知っているとする. そこで, {\tt lon}の4番目
の値, {\tt lat}の3番目の値, および{\tt time}の2番目の値に対応する{\tt
rh}の値をセットしたいわけである:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
      INTEGER  RHINDX(3)          ! 値を書く場所
      DATA RHINDX /4, 3, 2/
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)  ! IDを取得
      CALL NCVPT1 (NCID, RHID, RHINDX, 0.5, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{値の配列を書き込む: NCVPT(C)}

関数{\tt NCVPT}または{\tt NCVPTC}は, オープンされたnetCDFファイルの変
数に値を書く.
書きこむnetCDF変数の部分は, netCDF変数の配列断面を示す隅および縁の長さ
のベクトルを与えることによって指定される.
書かれる値は, netCDF変数の第1次元が最も先に変わるような順番で, netCDF
変数と関係づけられる.
そのnetCDFファイルはデータモードになければならない.
\footnote{MSDOSシステム上におけるXDRの現在の実装では, {\tt NCVPT}およ
び{\tt NCVPTC}の各呼び出しにおいてアクセスされるデータの量は, 64Kバイ
ト以下に制限されている.}

エラーが生じた場合には, {\tt NCVPT}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定された隅のインデックスが, 指定された変数のランクの範囲から外
れている. 例えば, 負のインデックスまたは, 対応する次元サイズより大きな
インデックス, はエラーを起す.
\item 指定された隅のインデックスに指定された縁の長さを加えたものが,
指定された変数のランクの範囲を外れたデータを参照している.
例えば, 縁の長さが(対応する次元サイズ)$-$(隅のインデックス)より大きい
場合はエラーを引き起こす.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVPT (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                  INTEGER COUNT(*), 型 VALUES, INTEGER RCODE)

      SUBROUTINE NCVPTC (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNTS(*), CHARACTER*(*) STRING,
     +                   INTEGER LENSTER, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVPT}および{\tt NCVPTC}はnetCDF変数に値
の配列を書く. 最初のものは数値型の変数に数値を書き, 2番目のものは文字
型変数に文字値を書く.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt START] データ値の先頭が書かれる変数のインデックスを指定する整数
 のベクトルである. このインデックスは1に相対的なものであり, それゆえ, 
 例えば変数の最初のデータ値はインデックス{\tt (1, 1, ..., 1)}を持つ.
 {\tt START}のサイズは, 指定された変数の次元数と同じでなければならない.
 {\tt START}の要素は, 変数の次元に順番に対応しなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスはデータ値を書
 くための開始記録番号に対応していなければならない.
\item[\tt COUNT] 書かれるデータ値のブロックの, 各次元に沿った縁の長さを指
 定する整数のベクトル.
 例えば, 単一の値を書くには, {\tt COUNT}を{\tt (1, 1, ..., 1)}と指定す
 る.
 {\tt COUNT}のサイズは, 指定された変数の次元数である.
 {\tt COUNT}の要素は, 変数の次元に対応している.
 従って, その変数が記録変数ならば, {\tt COUNT}の最後の要素は, 書く記録
 数の総計に対応している.
\item[\tt VALUES] {\tt NCVPT}において, 書かれるデータ値のブロックである.
 データが指定された変数に書かれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, そのnetCDF変数の型
として適当でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt STRING] {\tt NCVPTC}において, 書かれる文字である.
 netCDF変数に文字が書かれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応する型が許される.
\item[\tt LENSTR] {\tt NCVPTC}において, {\tt STRING}引数の宣言されている
 文字長の総計である. 
 これは, {\tt COUNT}ベクトルの要素の積以上の値であるはずである.
 引数として配列が与えられることもあるので, この値は, FORTRANの{\tt LEN}
 関数が返す値と必ずしも同じであるとは限らないことに注意されたい.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVPT}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数のすべての値を
{\tt 0.5}にしている.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていること, および{\tt lon}の値が10個, {\tt lat}の値が
5個, および{\tt time}の値が3個, であることを知っているとする:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      PARAMETER (NDIMS=3)         ! 次元の数
      PARAMETER (TIMES=3, LATS=5, LONS=10) ! 次元のサイズ
      INTEGER  NCID, RCODE, TIMES
      INTEGER  RHID               ! 変数ID
      INTEGER  START(NDIMS), COUNT(NDIMS)
      DOUBLE RHVALS(LONS, LATS, TIMES)
      DATA START /1, 1, 1/        ! 最初の値からスタート
      DATA COUNT /LONS, LATS, TIMES/
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)   ! IDを取得
      DO 10 ILON = 1, LONS
         DO 10 ILAT = 1, LATS
            DO 10 ITIME = 1, TIMES
               RHVALS(ILON, ILAT, ITIME) = 0.5
   10 CONTINUE
      CALL NCVPT (NCID, RHID, START, COUNT, RHVALS, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{部分的にサンプルされた, またはマップされた値の配列
を書く: NCVPTGおよびNCVPGC}
\label{NCVPTG}

関数{\tt NCVPTG}または{\tt NCVPGC}は, 部分的にサンプルされた, または
マップされた値の配列断面をオープンされたnetCDFファイルの変数に書き込む.
部分的にサンプルされた, またはマップされた値の配列断面は, 隅, 縁の長さ
のベクトル, ストライドベクトル, およびインデックスマッピングベクトル,
を与えて指定される.
データ配列の次元の順番またはサイズに関しては特に制限はない.
そのnetCDFはデータモードになければならない.

エラーが生じた場合には, {\tt NCVPTG}および{\tt NCVPGC}は{\tt RCODE}と
して非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定された隅のインデックスが, 指定された変数のランクの範囲から外
れている. 例えば, 負のインデックスまたは, 対応する次元サイズより大きな
インデックス, はエラーを起す.
\item 指定された隅のインデックスに指定された縁の長さおよびストライド
を加えたものが, 指定された変数のランクの範囲を外れたデータを参照してい
る. 例えば, 縁の長さが(対応する次元サイズ)$-$(隅のインデックス)より大
きい場合や, そのnetCDF変数の対応する次元のサイズより大きなストライドを
使って2つまたはそれ以上の値にアクセスしようとした場合, にはエラーを引
き起こす. 
\item ストライドが正でない.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVPTG (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNT(*), INTEGER STRIDE(*), INTEGER IMAP(*),
     +                   型 VALUES, INTEGER RCODE)

      SUBROUTINE NCVPGC (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNT(*), INTEGER STRIDE(*), INTEGER IMAP(*),
     +                   CHARACTER*(*) STRING, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVPTG}および{\tt NCVPGC}はnetCDF変数に
部分的にサンプルされた, またはマップされた値の配列断面を書き込む.
最初のものは数値型の変数に数値を書き, 2番目のものは文字型変数に文字値
を書く.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt START] データ値の先頭が書かれる変数のインデックスを指定する整数
 のベクトルである. このインデックスは1に相対的なものであり, それゆえ, 
 例えば変数の最初のデータ値はインデックス{\tt (1, 1, ..., 1)}を持つ.
 {\tt START}のサイズは, 指定された変数の次元数と同じでなければならない.
 {\tt START}の要素は, 変数の次元に順番に対応しなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスはデータ値を書
 くための開始記録番号に対応していなければならない.
\item[\tt COUNT] 書かれるデータ値のブロックの, 各次元に沿った縁の長さを指
 定する整数のベクトル.
 例えば, 単一の値を書くには, {\tt COUNT}を{\tt (1, 1, ..., 1)}と指定する.
 {\tt COUNT}のサイズは, 指定された変数の次元数である.
 {\tt COUNT}の要素は, 変数の次元に対応している.
 従って, その変数が記録変数ならば, {\tt COUNT}の最後の要素は, 書く記録
 数の総計に対応している.
\item[\tt STRIDE] 各次元に対して, アクセスされるnetCDF変数の値の間隔また
 は{\tt 0}を指定する整数のベクトルまたは, 値{\tt 0}, である.
 ベクトルの要素は, 順番に, 変数の次元に対応している.
 この値が1なら, netCDF変数の対応する次元の隣接した値にアクセスしてい
 く; 値が2なら, netCDF変数の対応する次元の1つおきの値にアクセスしていく; 
 等々である.
 引数が{\tt 0}なら, は各次元に沿って, 隣接した値にアクセスしていくとい
 うデフォルトの動作になる.
\item[\tt IMAP] 各次元に対して, netCDF変数に関連したデータ値がメモリ上に
 どのように並べられているかを指定する整数のベクトル, または値{\tt 0}で
 ある.
 {\tt VALUE}引数で指されるメモリ上の位置から特定のデータへのオフセット
 (バイト単位)は, インデックスマッピングベクトルとデータの(原点を0とした)
 座標との内積で与えられる. 
 (二つのベクトル[x0, x1, ..., xn]と[y0, y1, ..., yn]と{\bf 内積}は,
 単純にx0*y0 + x1*y1 + ... + xn*yn である.)
 {\tt VALUE}引数が適切に指定されていれば, このベクトルは負の値を含んで
 いてもよい.
 引数が{\tt 0}なら, メモリ上の値が, 関連するnetCDF変数と同じ構造をして
 いうことが仮定されるデフォルトの動作になる.
\item[\tt VALUES] {\tt NCVPTG}において, 書かれるデータ値のブロックである.
 データが指定された変数に書かれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, そのnetCDF変数の型
 として適当でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt STRING] {\tt NCVPGC}において, 書かれる文字である.
 netCDF変数に文字が書かれる順番は, 部分的にサンプルされたまたはマップさ
 れた配列断面の1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応する型が許される.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVPTG}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数の各次元の1つおきの値
を{\tt 0.5}にしている.
同じ次元のストライドを用いて, netCDF変数と次元が逆である2をパラメター
とする配列から値を取り出している.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていること, および{\tt lon}の値が10個, {\tt lat}の値が
5個, および{\tt time}の値が3個, であることを知っているとする:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      PARAMETER (NDIMS=3)         ! 次元数
      PARAMETER (TIMES=3, LATS=5, LONS=10) ! 次元サイズ
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! variable ID
      INTEGER  START(NDIMS), COUNT(NDIMS), STRIDE(NDIMS), IMAP(NDIMS)  
                                  ! 部分的にサンプルされたまたはマップされた配列
      DOUBLE DATA(2, TIMES, LATS, LONS)    ! rhは2番目のパラメターである
      DATA START /1, 1, 1/        ! 最初の値からスタートする
      DATA COUNT /LONS, LATS, TIMES/
      DATA STRIDE /2, 2, 2/
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)   ! IDを取得
      DO 10 ILON = 1, LONGS, STRIDE(1)
         DO 10 ILAT = 1, LATS, STRIDE(2)
            DO 10 ITIME = 1, TIMES, STRIDE(3)
               DATA(2, ITIME, ILAT, ILON) = 0.5
   10 CONTINUE
      IMAP(3) = 8*2*2   ! 倍精度変数2個組のベクトルの一つおきの値
      IMAP(2) = IMAP(3)*(1+(TIMES-1)/STRIDE(3))*2
      IMAP(1) = IMAP(2)*(1+(LATS-1)/STRIDE(2))*2
      CALL NCVPTG (NCID, RHID, START, COUNT, STRIDE, IMAP, DATA(2,1,1,1), RCODE)
\end{verbatim}}


%-----------------------------------------------------------------------
\section{単一のデータ値を読む: NCVGT1およびNCVG1C}

関数{\tt NCVGT1}または{\tt NCVG1C}は, データモードにあるオープンされた
netCDFファイルの変数から単一のデータ値を読む.
入力は, netCDF ID, 変数ID, どの値が追加または変更されるかを指定する複
数次元のインデックス, およびデータ値が読みこまれる位置アドレス, である.

エラーが生じた場合には, {\tt NCVGT1}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定されたインデックスが指定された変数のランクの範囲から外れてい
る. 例えば, 負のインデックスまたは, 対応する次元サイズより大きなインデッ
クス, はエラーを起す.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVGT1 (INTEGER NCID, INTEGER VARID, INTEGER MINDEX(*),
     +                   型 VALUE, INTEGER RCODE)

      SUBROUTINE NCVG1C (INTEGER NCID, INTEGER VARID, INTEGER MINDEX(*),
     +                   CHARACTER CHVAL, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVGT1}および{\tt NCVG1C}は変数から単一の
値を読む.
最初のものは数値型の変数中の数値を読み, 2番目のものは文字型変数の文字
値を読む.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt MINDEX] 読むデータ値の複数次元のインデックス.
 このインデックスは1に相対的なものであり, それゆえ, 例えば2次元変数の
 最初のデータ値はインデックス{\tt (1,1)}を持つ.
 {\tt MINDEX}の要素はその変数の次元に対応していなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスは記録数に対応
 していなければならない.
\item[\tt VALUE] {\tt NCVPT1}における, データ値を読みこむ位置である.
 このデータはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, netCDF変数の型として適当
 でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt CHVAL] {\tt NCVP1C}における, データ値を読みこむ位置である.
 このデータはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応した文字型でな
 ければならない.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVGT1}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数の{\tt (4,3,2)}要素
を取得している.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていることを知っているとする. そこで, {\tt lon}の4番目
の値, {\tt lat}の3番目の値, および{\tt time}の2番目の値に対応する{\tt
rh}の値を取得したいわけである:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER NCID, RCODE
      INTEGER RHID ! 変数ID
      INTEGER RHINDX(3) ! 値を取得する位置
      DOUBLE PRECISION RHVAL ! ここに入れる
      DATA RHINDX /4, 3, 2/
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)   ! IDを取得
      CALL NCVGT1 (NCID, RHID, RHINDX, RHVAL, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{値の配列を読み込む: NCVGT(C)}

関数{\tt NCVGT}または{\tt NCVGTC}は, オープンされたnetCDFファイルの変
数から値の配列を読む.
配列は, 隅および縁の長さのベクトルを与えることによって指定される.
値は, netCDF変数の第1次元が最も先に変わるような順番で, 連続的な位置に
読み込まれる.
そのnetCDFファイルはデータモードになければならない.
\footnote{MSDOSシステム上におけるXDRの現在の実装では, {\tt NCVGT}およ
び{\tt NCVGTC}の各呼び出しにおいてアクセスされるデータの量は, 64Kバイ
ト以下に制限されている.}

エラーが生じた場合には, {\tt NCVGT}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定された隅のインデックスが, 指定された変数のランクの範囲から外
れている. 例えば, 負のインデックスまたは, 対応する次元サイズより大きな
インデックス, はエラーを起す.
\item 指定された隅のインデックスに指定された縁の長さを加えたものが,
指定された変数のランクの範囲を外れたデータを参照している.
例えば, 縁の長さが(対応する次元サイズ)$-$(隅のインデックス)より大きい
場合はエラーを引き起こす.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVGT (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                  INTEGER COUNT(*), 型 VALUES, INTEGER RCODE)

      SUBROUTINE NCVGTC (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNTS(*), CHARACTER*(*) STRING,
     +                   INTEGER LENSTER, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVGT}および{\tt NCVGTC}はnetCDF変数から
値の配列を読む.
最初のものは数値型の変数からの数値を読み, 2番目のものは文字型変数から
文字値を読む.

\begin{quote}
\begin{description}
\item[\tt NCID]以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt START] データ値の先頭が読まれる変数のインデックスを指定する整数
 のベクトルである. このインデックスは1に相対的なものであり, それゆえ, 
 例えば変数の最初のデータ値はインデックス{\tt (1, 1, ..., 1)}を持つ.
 {\tt START}のサイズは, 指定された変数の次元数と同じでなければならない.
 {\tt START}の要素は, 変数の次元に順番に対応しなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスはデータ値を読
 むための開始記録番号に対応していなければならない.
\item[\tt COUNT] 読まれるデータ値のブロックの, 各次元に沿った縁の長さを指
 定する整数のベクトル. 例えば, 単一の値を読むには, {\tt COUNT}を
 {\tt (1, 1, ..., 1)}と指定する.
 {\tt COUNT}のサイズは, 指定された変数の次元数である.
 {\tt COUNT}の要素は, 変数の次元に対応している.
 従って, その変数が記録変数ならば, {\tt COUNT}の最後の要素は, 読む記録
 数の総計に対応している.
\item[\tt VALUES] {\tt NCVGT}において, データ値が読み込まれる位置である.
 データが指定された変数から読まれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, そのnetCDF変数の型
 として適当でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt STRING] {\tt NCVGTC}において, 文字データが読み込まれる文字である.
 netCDF変数に文字が書かれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応する型が許される.
\item[\tt LENSTR] {\tt NCVGTC}において, {\tt STRING}引数の宣言されている
 文字長の総計である. 
 これは, {\tt COUNT}ベクトルの要素の積以上の値であるはずである.
 引数として配列が与えられることもあるので, この値は, FORTRANの{\tt LEN}
 関数が返す値と必ずしも同じであるとは限らないことに注意されたい.
 {\tt NCVGTC}は, 要求されるデータが{\tt LENSTR}個の文字に合っていること
 をチェックする.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVGT}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数のすべての値を
読み込んでいる.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていること, および{\tt lon}の値が10個, {\tt lat}の値が
5個, および{\tt time}の値が3個, であることを知っているとする:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      PARAMETER (NDIMS=3) ! 次元の数
      PARAMETER (TIMES=3, LATS=5, LONS=10) ! 次元のサイズ
      INTEGER NCID, RCODE
      INTEGER RHID ! 次元ID
      INTEGER START(NDIMS), COUNT(NDIMS)
      DOUBLE RHVALS(LONS, LATS, TIMES)
      DATA START /1, 1, 1/ ! 最初の値からスタート
      DATA COUNT /LONS, LATS, TIMES/
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)! IDを取得
      CALL NCVGT (NCID, RHID, START, COUNT, RHVALS, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{部分的にサンプルされた, またはマップされた値の配列
を読む: NCVGTGおよびNCVGGC}

関数{\tt NCVGTG}または{\tt NCVGGC}は, 部分的にサンプルされた, または
マップされた値の配列断面をオープンされたnetCDFファイルの変数から読む.
部分的にサンプルされた, またはマップされた値の配列断面は, 隅, 縁の長さ
のベクトル, ストライドベクトル, およびインデックスマッピングベクトル,
を与えて指定される.
値は第1次元が先に変わるような順番で読まれる.
そのnetCDFはデータモードになければならない.

エラーが生じた場合には, {\tt NCVGTG}および{\tt NCVGGC}は{\tt RCODE}と
して非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDが, 指定されたnetCDFファイルに対して適当でない.
\item 指定された隅のインデックスが, 指定された変数のランクの範囲から外
れている. 例えば, 負のインデックスまたは, 対応する次元サイズより大きな
インデックス, はエラーを起す.
\item 指定された隅のインデックスに指定された縁の長さおよびストライド
を加えたものが, 指定された変数のランクの範囲を外れたデータを参照してい
る. 例えば, 縁の長さが(対応する次元サイズ)$-$(隅のインデックス)より大
きい場合や, そのnetCDF変数の対応する次元のサイズより大きなストライドを
使って2つまたはそれ以上の値にアクセスしようとした場合, にはエラーを引
き起こす. 
\item ストライドが正でない.
\item 指定されたnetCDFファイルがデータモードでなはく, 定義モードにある.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVGTG (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNT(*), INTEGER STRIDE(*),
     +                   INTEGER IMAP(*), 型 VALUES, INTEGER RCODE)

      SUBROUTINE NCVGGC (INTEGER NCID, INTEGER VARID, INTEGER START(*),
     +                   INTEGER COUNT(*), INTEGER STRIDE(*),
     +                   INTEGER IMAP(*), CHARACTER*(*) STRING, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCVGTG}および{\tt NCVGGC}はnetCDF変数から
部分的にサンプルされた, またはマップされた値の配列断面を読み込む.
最初のものは数値型の変数から数値を読み, 2番目のものは文字型変数から文
字値を読む.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt START] データ値の先頭が読まれる変数のインデックスを指定する整数
 のベクトルである. このインデックスは1に相対的なものであり, それゆえ, 
 例えば変数の最初のデータ値はインデックス{\tt (1, 1, ..., 1)}を持つ.
 {\tt START}のサイズは, 指定された変数の次元数と同じでなければならない.
 {\tt START}の要素は, 変数の次元に順番に対応しなければならない.
 従って, もしその変数が記録変数ならば, 最後のインデックスはデータ値を読
 むための開始記録番号に対応していなければならない.
\item[\tt COUNT] 読まれるデータ値のブロックの, 各次元に沿った縁の長さを指
 定する整数のベクトル.
 例えば, 単一の値を読むには, {\tt COUNT}を{\tt (1, 1, ..., 1)}と指定する.
 {\tt COUNT}のサイズは, 指定された変数の次元数である.
 {\tt COUNT}の要素は, 変数の次元に対応している.
 従って, その変数が記録変数ならば, {\tt COUNT}の最後の要素は, 読む記録
 数の総計に対応している.
\item[\tt STRIDE] 各次元に対して, アクセスされるnetCDF変数の値の間隔また
 は{\tt 0}を指定する整数のベクトルまたは, 値{\tt 0}, である.
 ベクトルの要素は, 順番に, 変数の次元に対応している.
 この値が1なら, netCDF変数の対応する次元の隣接した値にアクセスしてい
 く; 値が2なら, netCDF変数の対応する次元の1つおきの値にアクセスしていく;
 等々である.
 引数が{\tt 0}なら, は各次元に沿って, 隣接した値にアクセスしていくとい
 うデフォルトの動作になる.
\item[\tt IMAP] 各次元に対して, netCDF変数に関連したデータ値がメモリ上に
 どのように並べられているかを指定する整数のベクトル, または値{\tt 0}で
 ある.
 {\tt VALUE}引数で指されるメモリ上の位置から特定のデータへのオフセット
 (バイト単位)は, インデックスマッピングベクトルとデータの(原点を0とした)
 座標との内積で与えられる. 
 (二つのベクトル[x0, x1, ..., xn]と[y0, y1, ..., yn]と{\bf 内積}は,
 単純にx0*y0 + x1*y1 + ... + xn*yn である.)
 {\tt VALUE}引数が適切に指定されていれば, このベクトルは負の値を含んで
 いてもよい.
 引数が{\tt 0}なら, メモリ上の値が, 関連するnetCDF変数と同じ構造をして
 いうことが仮定されるデフォルトの動作になる.
\item[\tt VALUES] {\tt NCVGTG}において, データ値が読み込まれる位置である.
 データがnetCDF変数から読まれる順番は, 1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および
 {\tt NCDOUBLE}, のどれに対応していてもよいが, そのnetCDF変数の型
 として適当でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt STRING] {\tt NCVGGC}において, 文字データが読み込まれる文字列で
 ある.
 netCDF変数から文字が読まれる順番は, 部分的にサンプルされたまたはマップさ
 れた配列断面の1番目の次元から先に変わるよう
 な順番である(通常のFORTRANの慣習どおり).
 データはnetCDF型{\tt NCCHAR}または{\tt NCBYTE}に対応する型が許される.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVGTG}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 名前{\tt rh}の変数の各次元の1つおきの値
を読んでいる.
同じ次元のストライドを用いて, netCDF変数と次元が逆である2をパラメター
とする配列に値を割り当てている.
この例においては簡単のため, {\tt rh}が次元{\tt lon}, {\tt lat}, および
{\tt time}を持っていること, および{\tt lon}の値が10個, {\tt lat}の値が
5個, および{\tt time}の値が3個, であることを知っているとする:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      PARAMETER (NDIMS=3) ! 次元の数
      PARAMETER (TIMES=3, LATS=5, LONS=10) ! 次元サイズ
      INTEGER NCID, RCODE
      INTEGER RHID ! 変数ID
      INTEGER START(NDIMS), COUNT(NDIMS), STRIDE(NDIMS), IMAP(NDIMS)
      DOUBLE DATA(2, TIMES, LATS, LONS) ! rhは2番目のパラメターであ
      DATA START /1, 1, 1/ ! 最初の値からスタートする
      DATA COUNT /LONS, LATS, TIMES/
      DATA STRIDE /2, 2, 2/
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)  ! IDを取得
      IMAP(3) = 8*2*2 ! 倍精度変数2個組のベクトルの一つおきの値
      IMAP(2) = IMAP(3)*(1+(TIMES-1)/STRIDE(3))*2
      IMAP(1) = IMAP(2)*(1+(LATS-1)/STRIDE(2))*2
      CALL NCVGTG (NCID, RHID, START, COUNT, STRIDE, IMAP, DATA(2,1,1,1), RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{文字列値を読み書きする}

文字列は, 基本的なnetCDFデータ型ではない. これは一つには, FORTRANが可変
長の文字列の抽象化をサポートしていないからである(FORTRAN{\tt LEN}関数
は, 文字列の動的長さではなく, 静的長さを返す).
結果として, netCDFインターフェース中において, 文字列は単一のオブジェク
トとして読み書きできない.
その代わりに, 文字列は文字の配列として扱われねばならず, 文字列をnetCDF
ファイル中の変数データとして読み書きするには, 配列アクセスを使う必要が
ある.
さらに, 可変長の文字列は, 慣習による場合を除いて, netCDFインターフェー
スではサポートされていない;
このような慣習の例として, 零のバイトを文字列を終了するものとして扱うこ
とができるが, netCDF変数から読み込まれるまたはそれに書き込まれる文字列
の長さは陽に指定しなければならない.

属性値として文字列は, もっと使いやすい; なぜなら, 文字列がアクセスの単
一単位として扱われるからである.
しかし, それでも, 文字列属性の値は, その属性が定義された際に指定されて
いるはずの長さを陽に与えた文字の配列である.

文字列値を持つ変数を定義する際には, その変数の最も先に変わる次元
(FORTRANでは第1次元)を{\bf 文字位置次元}として使わねばならない.
このとき, 文字位置次元のサイズは, 文字列変数に格納されるあらゆる文字列
値の最大の長さになる.
最大サイズの列のためのスペースは, そのスペースを使う使わないにかかわら
ず, 文字列変数のディスク表現の中に割り当てられる.
2つまたはそれ以上の変数が同じ最大長を持つ場合は, 変数の形を定義するの
に同じ文字位置次元を使うことができる.

文字列値を文字列変数に書き込むには, 配列アクセスを使わねばならない.
このためには, 隅および縁の長さのベクトルの両方を指定しなければならない.
隅の文字位置次元は1になる.
もし, 書かれる文字列の長さが{\tt n}であるなら, 縁の長さのベクトルの
文字位置次元には{\tt n}が, 他のすべての次元には1が, 指定される;
すなわち, {\tt (n, 1, 1, ..., 1)}である.

FORTRANにおいては, 固定サイズの文字列は, 終了文字なしでnetCDFファイル
に書くことができ, これによりスペースを節約することができる.
可変長の文字列はCの慣習に従って, 終了文字である0のバイトを付けて書かれ
る; これは, 後でCまたはFORTRANインターフェースで読まれる際に文字列の長
さが決められるようにするためである.

文字列を読み書きするためのFORTRANインターフェースでは, 文字列値と数値
にアクセスするためには, 異るサブルーチンを用いなければならない;
なぜなら, 標準FORTRANでは, 同じ正式のパラメターが文字値と数値の両方に
使われることが許されていないからである.
{\tt NCVPTC}および{\tt NCVGTC}では, 値として渡される宣言された文字列長
を指定する余分の引数が必要である.
文字列の実際の長さは, 縁の長さベクトルの文字位置次元に対応する値として
指定される.

以下の例では, 文字列のために{\tt tx}なる記録変数を定義し,
{\tt NCVPTC}を使って3番目の記録に文字列値を格納している.
この例では, この文字列変数およびデータを, 無制限記録次元{\tt time}を既
に持つ{\tt `foo.nc'}という名前の既存のnetCDFファイルに追加するという状
況を考えている.
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER   TDIMS, TXLEN
      PARAMETER (TDIMS=2)    ! TX次元の数
      PARAMETER (TXLEN = 15) ! 文字列例の長さ
      INTEGER  NCID, RCODE
      INTEGER  CHID          ! 文字位置次元のid
      INTEGER  TIMEID        ! 記録次元のid
      INTEGER  TXID          ! 変数ID
      INTEGER  TXDIMS(TDIMS) ! 変数の形
      INTEGER  TSTART(TDIMS), TCOUNT(TDIMS)
      CHARACTER*40 TXVAL     ! 最大長40
      DATA TXVAL /'example string'/
         ...
      TXVAL(TXLEN:TXLEN) = CHAR(0)   ! ヌル文字で終了
         ...
      NCID = NCOPN('foo.nc', NCWRITE, RCODE)
      CALL NCREDF(NCID, RCODE) ! 定義モードに入る
         ...
* 最大長40の文字列のための文字位置次元を定義する
      CHID = NCDDEF(NCID, "chid", 40, RCODE)
         ...
* 文字列変数を定義する
      TXDIMS(1) = CHID   ! 文字位置次元が先
      TXDIMS(2) = TIMEID
      TXID = NCVDEF(NCID, "tx", NCCHAR, TDIMS, TXDIMS, RCODE)
         ...
      CALL NCENDF(NCID, RCODE) ! 定義モードから抜ける
         ...
* 3番目の記録中のnetCDF変数txにtxvalを書き込む
      TSTART(1) = 0      ! 変数の始めからスタート
      TSTART(2) = 3      ! 書き込む記録番号
      TCOUNT(1) = TXLEN  ! 書き込む文字の数
      TCOUNT(2) = 1      ! 1つの記録だけを書く
      CALL NCVPTC (NCID, TXID, TSTART, TCOUNT, TXVAL, 40, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{フィル値}
\label{フィル値}

オープンされたnetCDFファイルに一度も書かれていない変数を読もうとすると
どうなるか?
これはいつもエラーとなって, エラーメッセージが得られるかエラー状態が返
されると考えるかもしれない.
確かに, 読み込みのためにオープンされていないnetCDFファイルからデータを
読もうとしたり, 指定されたnetCDFにおいて変数IDが不適当であったり, 指定
されたインデックスが指定された次元サイズで定義される範囲に適切に収まっ
ていなかったり, する場合には, エラーとなる.
一方, 書かれていない値を読むと, netCDFファイルが最初に書かれた際に定義
されなかったすべての値を埋めるために使われる特別の{\bf フィル値}が返さ
れる.

フィル値を無視し, netCDFデータ型の全範囲を使うことができるが, この場合,
読む前に, すべてのデータ値をちゃんと書いておかねばならない.
読む前にすべてのデータを書くことが確かな場合には, 書く前に{\tt ncsetfill}
を呼び出すことによって, 前もってフィル値で変数を埋めるのを止めるように
指定することができる.
これによって, netCDFの書き込みの効率が著しく向上することもある.

フィル値を指定するためには変数属性 {\tt \_FillValue} が使われる.
デフォルトのフィル値はインクルードファイル {\tt `netcdf.inc'} 
で定義される.

netCDFバイト型と文字型の一つの違いは, この二つの型は異なるデフォルトの
フィル値を持つということである.
文字のデフォルトのフィル値は0のバイトであり, これは可変長のC文字列の末
尾を検出するのに便利な値である.
もし, バイト型にフィル値が必要なら, 適切な{\tt \_FillValue}属性を陽に定
義することを勧める; なぜなら, {\tt ncdump}のような一般的なユーティリティ
はバイト型のデフォルトのフィル値を仮定しないからである.

%-----------------------------------------------------------------------
\section{変数の名前を変える: NCVREN}

関数{\tt NCVREN}は, オープンされたnetCDFファイル中の変数の名前を変える.
新しい名前が古い名前より長い場合には, そのnetCDFファイルは定義モードに
なければならない.
変数の名前を既存の変数と同じ名前に変えることはできない.

エラーが生じた場合には, {\tt NCVREN}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 新しい名前が他の変数の名前として使われている.
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCVREN (INTEGER NCID, INTEGER VARID,
     +                   CHARACTER*(*) NEWNAM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt NEWNAM] 指定された変数の新しい名前.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCVREN}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 変数{\tt rh}の名前を{\tt rel\_hum}に変え
ている.
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      CALL NCREDF (CDFFID, RCODE)  ! enter definition mode
      RHID = NCVID (NCID, 'rh', RCODE)  ! IDを取得
      CALL NCVREN (NCID, RHID, 'rel_hum', RCODE)
      CALL NCENDF (CDFFID, RCODE)  ! 定義モードを抜ける
\end{verbatim}}

%-----------------------------------------------------------------------
\section{あるデータ型を表現するためのバイト数を得る: NCTLEN}

関数{\tt NCTLEN}は, netCDF型あたりのバイト数を返す.

エラーが生じた場合には, {\tt NCTLEN}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定されたデータ型がnetCDFデータ型として適当でない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      INTEGER FUNCTION NCTLEN (INTEGER TYPE ,INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt TYPE] 前もって定義されているnetCDFデータ型集合のうちの一つ.
 適当なnetCDFデータ型は{\tt NCBYTE}, {\tt NCCHAR}, {\tt NCSHORT},
 {\tt NCLONG}, {\tt NCFLOAT}, および{\tt NCDOUBLE}である.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCTLEN}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, 変数{\tt rh}の単一の値を格納するのに必要
なバイト数を決めている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID               ! netCDF ID
      INTEGER  RHID               ! 変数ID
      CHARACTER*31 RHNAME         ! 変数名
      INTEGER  RHTYPE             ! 変数型
      INTEGER  RHN                ! 次元の数
      INTEGER  RHDIMS(MAXVDIMS)   ! 変数形
      INTEGER  RHNATT             ! 属性の数
      INTEGER  RHBYTS             ! 値あたりのバイト
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)
* "rh"の型を取得
      CALL NCVINQ (NCID, RHID, RHNAME, RHTYPE, RHN, RHDIMS, RHNATT, RCODE)
      RHBYTS = NCTLEN (RHTYPE)
\end{verbatim}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{属性}
\label{属性}

各netCDF変数は, 単位, 特別な値, 有効な値の最大および最小値, スケーリン
グファクター, およびオフセットのような性質を指定するために属性を伴って
いてもよい.
netCDFファイルに対する属性は, そのファイルが最初に生成される際に, それ
が定義モードにある間に定義される. 
後で再び定義モードに入ることによって, 属性を追加することができる.
netCDF属性は, その属性が割り当てられている変数, 名前, 型, 長さ, および
一つまたはそれ以上の値の並び, を持っている.
属性は, その変数IDおよび名前で示される. ただし, 一つの場合({\tt
NCANAM})を除いて; そこでは, 属性の名前が不明なので, 属性は変数IDおよび
番号で示される.

変数に関連している属性は, 普通, その変数が生成された直後で, まだ定義モー
ドにあるうちに定義される.
属性のデータ型, 長さ, および値はデータモードにおいても変更できる;
その変更によって, 属性が初めに定義されたときよりも多くのスペースが必要
とならない限りは.

どの変数とも関連しない属性を持つことも可能である.
これらは, {\bf グローバル属性}と呼ばれ, {\tt NC\_GLOBAL}を仮の変数IDと
して使って見分けられる.
グローバル属性は, 大抵, netCDFファイル全体と関連づけられており, netCDF
データセットに対してタイトルまたは作業記録を付けるために使うことができ
る.

属性に対してサポートされている操作は以下のようである:
\begin{itemize}
\item 変数ID, 名前, データ型, 長さ, および値を与えて属性を生成する.
\item 変数IDおよび名前から, 属性のデータ型と長さを取得する.
\item 変数IDおよび名前から属性の値を取得する.
\item あるnetCDF変数から他の変数に属性をコピーする.
\item 番号から属性名を取得する.
\item 属性の名前を変える.
\item 属性を削除する.
\end{itemize}

%-----------------------------------------------------------------------
\section{属性の慣習}
\label{属性の慣習}

アンダースコア(`{\tt \_}')から始まる名前はnetCDFライブラリの使用のため
に予約されている.
netCDFファイルを加工する一般の多くのアプリケーションは, 標準的な属性の
慣習を仮定しており, そうしないだけの正当な理由が無い限りは, これら
のとりめに従うことを強く勧める.
以下に, 推奨される標準的な属性(便利であることがすでに示されている)の名
前および意味のリストを示す.
これらのうち, 数値データが仮定され, 文字データとしては使われないものも
ある(例えば, {\tt units}, {\tt valid\_range}, {\tt scale\_factor})こと
に注意が必要である.

\begin{description}

\item[{\tt units}] 
 変数データに対して使われている単位を指定する文字列.
 Unidataは, 自由に取得可能なルーチンのライブラリを提供しており, それに
 よって文字列と単位記述のバイナリ形式との間の変換を行うことができ,
 さらにそのバイナリ形式においては, いろいろと便利な操作を実行できる.
 このライブラリはいくつかのnetCDFアプリケーションにおいて使われている.
 推奨される単位構文を使えば, 整合単位で表現されたデータを, 算術
 演算できる一般的な単位に自動的に変換できる. より多くの情報について
 は, Appendix A [単位]\pageref{単位}ページを参照.

\item[{\tt long\_name}] 長い記述的な名前. これは, 例えば, プロットのラ
 ベルづけに使うことができる. もし, 変数に{\tt long\_name}属性が割り当
 てられていなければ, 変数名がデフォルトとして使われる.

\item[{\tt valid\_min}] この変数に対する有効な値の最小値を示すスカラー.

\item[{\tt valid\_max}] この変数に対する有効な値の最大値を示すスカラー.

\item[{\tt valid\_range}] この変数に対する有効な値の最小値および最大値
 を示す2つの数値のベクトルであり, {\tt valid\_min}および{\tt valid\_max}
 属性の両方の値を指定するのに等しい.
 これらのどれもが{\bf 有効範囲}を定義する. もし, {\tt valid\_min}また
 は{\tt valid\_max}のどちらかが定義されている場合には{\tt valid\_range}
 を定義してはならない.

 一般的なアプリケーションは, {\bf 有効範囲}を外れた値を欠損として扱う. 
 {\tt valid\_range}, {\tt valid\_min}, および{\tt valid\_max}のそれぞ
 れの型は, その変数の型に合っていなければならない(ただし, {\tt byte}型
 データを除く. この場合は, これらの属性の型は, 意図する範囲を指定する
 ために, 符号つきの整数型であってもよい).

 {\tt valid\_min}, {\tt valid\_max}, および{\tt valid\_range}のどれも
 定義されていない場合には, 一般的なアプリケーションは, 有効範囲を以下
 のように定義する. データ型がバイト型で, {\tt \_FillValue}が陽に定義さ
 れていない場合は, 有効範囲はすべての可能な値を含む. 一方, 有効範囲は,
 {\tt \_FillValue}を以下のように除外する. もし, {\tt \_FillValue}が正な
 らば, それが有効な最大値を定義し, そうでなければ, それは有効な最小値
 を定義する. 整数型については, {\tt \_FillValue}とこの有効な最大または
 最小値との間には1だけ違いがある. 浮動小数点型については, この違いは
 丸め誤差を許すために, 表現可能な最小値(最も下位のビットが1)の2倍の値
 である.

\item[{\tt scale\_factor}] ある変数についてこの属性が与えられている場
 合, データは, それにアクセスするアプリケーションによって読み込まれる
 際にこのファクター倍される.

\item[{\tt add\_offset}] ある変数についてこの属性が与えられている場
 合, データは, それにアクセスするアプリケーションによって読み込まれた
 後にこの数が加えられる. {\tt scale\_factor}および{\tt add\_offset}の
 両方の属性が与えられている場合には, データはまずスケールされ, その後
 にオフセットが加えられる. {\tt scale\_factor}および{\tt add\_offset}
 属性を同時に使うことによって, 簡単なデータ圧縮を行うことができる;
 有効桁数の小さい浮動小数点データを小さな整数としてnetCDFファイルに格
 納することによって. スケールされたデータを書く際には, アプリケーショ
 ンは, まずオフセットを引いて, その後でスケールファクターで割ればよい.

 {\tt scale\_factor}および{\tt add\_offset}を圧縮のために使う際には,
 関係する変数(圧縮されたデータを格納している)は, 普通, byte型または
 short型である; 一方, 解凍されたデータはfloatまたはdouble型になるよう
 にしたい. というわけで, {\tt scale\_factor}および{\tt add\_offset}属
 性は両方とも, 解凍されたデータの持つべき型(例えば, floatまたはdouble
 型)でなければならない.

\item[{\tt \_FillValue}] {\tt \_FillValue}属性は, 変数に割り当てられて
 いるディスクスペースを前もって埋めるために使われる{\bf フィル値}を指
 定する. このような前もって埋める動作は, {\tt NCSFIL}を使って{\bf ノー
 フィルモード}が設定されていない場合になされる. 詳細については, \ref{NCSFIL}節
 [書き込みのためのフィルモードの設定: NCSFIL]\pageref{NCSFIL}ページを参照.
 {\bf フィル値}は, まだ書かれていない値を読むと返される. 
 {\tt \_FillValue}が定義される場合, それはスカラーで, 変数と同じ型でな
 ければならない. {\tt \_FillValue}は通常, 有効範囲の外側にあり, それゆ
 え, 一般のアプリケーションではでは欠損として扱われる. 
 しかし, {\tt \_FillValue}を有効範囲内にして, 他の有効な値のように扱え
 るようにするのは正当なことである. 変数の型に対するデフォルトの{\bf フィ
 ル値}が適当であれば, 独自の{\tt \_FillValue}を定義する必要はない.
 しかし, byteデータ型に対しては, デフォルトのフィル値を使うことは勧め
 られない. この属性の値を変えた場合, その変更された値は引き続く書き込
 みにのみ適用されることに注意されたい; すなわち, それまでに書かれたデー
 タは変更されない. より多くの情報については, \ref{フィル値}節[フィル値]
 \pageref{フィル値}ページを参照.

\item[{\tt missing\_value}] この属性は, ライブラリまたは慣習に従っ
 た一般的なアプリケーションで特別に扱われるわけではないが, 記録として
 便利なこともあり, また特定のアプリケーションで使われることもありうる.
 {\tt missing\_value}属性は, 欠損データを示す値を含むスカラーまたはベ
 クトルでありうる. これらの値はすべて, 一般的なアプリケーションが欠損
 として扱えるように, {\bf 有効範囲}の外側にあるべきである.
 より多くの情報については, \ref{フィル値}節[フィル値]
 \pageref{フィル値}ページを参照.
 
\item[{\tt signedness}] 価値のなくなった属性である; もともとは, バイト
 値が符号つきまたは符号なしのどちらで扱われるべきかを指定するように作
 られたものである.  {\tt valid\_min}および{\tt valid\_max}属性をこの目
 的のために使うことができる. 例えば, バイト変数を非負の値として格納し
 たい場合には, {\tt valid\_min = 0}および{\tt valid\_max = 255}を使う
 ことができる. この属性は, netCDFライブラリでは無視される.

\item[{\tt C\_format}] この変数の値をプリントするCアプリケーションにお
 いて使われるフォーマットを与える文字列である. 例えば, 変数が有効数字3
 桁の精度しかないことが分かっているなら, {\tt C\_format}属性を
 {\tt "\%.3g"}と定義するのが適当である. {\tt ncdump}ユーティリティプロ
 グラムは, この属性を, それが定義されている変数に対して使う. このフォー
 マットは, スケーリングを行う{\tt scale\_factor}および{\tt
 add\_offset}属性のあるなしにかかわらず, スケールされた(内部の)型およ
 び値に対して適用される.

\item[{\tt FORTRAN\_format}] この変数の値をプリントするFORTRANアプリケー
 ションにおいて使われるフォーマットを与える文字列である. 例えば, 変数
 が有効数字3桁の精度しかないことが分かっているなら, {\tt
 FORTRAN\_format}属性を{\tt "(G10.3)"}と定義するのが適当である.

\item[{\tt title}] グローバル属性で, そのデータセットの中身を簡単に記述
 する文字列.

\item[{\tt history}] 履歴の検査のためのグローバル属性. これはそのファ
 イルを修正したプログラムの各呼び出しに対する行からなる文字配列である.
 たちのよい一般的なnetCDFアプリケーションは, 日付, 時刻, ユーザ名, プ
 ログラム名, およびコマンド引数, を含む行を追加する.

\item[{\tt Conventions}] ある変数についてこの属性が与えられている場合, 
 `{\tt Conventions}'は, グローバル属性で, そのファイルが従っている慣習の
 名前を表す文字配列である; それは, 分野に特化した慣習の集合を記述
 した文書を貯蔵しているディレクトリからの, 相対ディレクトリ名として解
 釈できる文字列の形式になっている.
 これによって, 慣習の階層構造が可能となり, 場所を与えて, 慣習
 の記述および例を, それを定義している機関およびグループに維持してもら
 うことができる.
 慣習のディレクトリ名は, 現在, ホストマシン
 {\tt ftp.unidata.ucar.edu}の{\tt put/netcdf/Conventions/}ディレクトリ
 から相対的に解釈される.
 代わりに, 慣習を記述する文章が維持されているWWWサイトを指定するた
 めに, 完全なURL指定子を使ってもよい.

 例えば, NUWGという名前のグループにおいて, 次元名, 変数名, 必要な属性, 
 およびある分野に特化したデータ構造のためのnetCDF表現, に対する一まと
 まりの慣習についての合意ができているのなら, その合意されたとりき
 めを記述する文章を, 慣習のディレクトリのサブディレクトリ{\tt NUWG/}
 以下のファイルに保管しておくことができる.
 これらの慣習に従ったファイルは, {\tt "NUWG"}という値を持つグロー
 バル{\tt Conventions}属性を含むことになる.

 後になって, もしそのグループが, NUWGデータの特定の部分集合, 例えば, 
 時系列データ, に対する追加の慣習について合意したなら, その追加の
 慣習の記述はサブディレクトリ{\tt NUWG/TIME\_series/}に保管される
 ことになる; また, これらの追加の慣習に従ったファイルは, 
 {\tt "NUWG/Time\_series"}という値を持つグロー バル{\tt Conventions}属
 性を使って, このファイルがNUWGの慣習および追加的なNUWGの時系列の
 慣習, に従っていることを示すことになる.
\end{description}

%-----------------------------------------------------------------------
\section{属性を生成する: NCAPTおよびNCAPTC}

関数{\tt NCAPT}または{\tt NCAPTC}は, オープンされたnetCDFファイルにお
いて, 変数属性またはグローバル属性を追加または変更する.
この属性が新しいものであるか, またはその属性を格納するのに必要なスペー
スが以前より大きな場合には, netCDFファイルは定義モードになければならな
い.

エラーが生じた場合には, {\tt NCAPT}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定されたnetCDF型が適当でない.
\item 指定された長さが負である.
\item 指定されたオープンされているnetCDFファイルがデータモードであり, 
      かつ指定された属性の大きさが大きくなっている.
\item 指定されたオープンされているnetCDFファイルがデータモードであり, 
      かつ指定された属性がまだ存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCAPT (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM,
     +                  INTEGER ATTYPE, INTEGER ATTLEN, 型 VALUE, INTEGER RCODE)

      SUBROUTINE NCAPTC (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM, INTEGER ATTYPE,
     +                   INTEGER LENSTR, CHARACTER*(*) STRING, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCAPT}および{\tt NCAPTC}は属性を生成する.
最初のものは数値型の属性に対するもので, 2番目のものは文字列型の属性に
対するものである.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 変数ID.
\item[\tt ATTNAM] 属性名. アルファベット文字で始まり, アンダースコア
 ('{\tt \_}')を含む零またはそれ以上の英数字が続かねばならない.
 大文字小文字は区別される. いくつかのnetCDF一般アプリケーションでは, 
 属性名の慣習が仮定されている, 例えば, {\tt units}はnetCDF変数に対
 する単位を与える文字列属性の名前である. 慣習的な属性名の表はnetCDFイ
 ンターフェースに関する前の章で提示している.
\item[\tt ATTTYP] 前もって定義されているnetCDFデータ型集合の一つ. 適当な
 netCDFデータ型は{\tt NCBYTE}, {\tt NCCHAR}, {\tt NCSHORT},
 {\tt NCLONG}, {\tt NCFLOAT}, および{\tt NCDOUBLE}である. 
 {\tt NCAPTC}においては, これは常に{\tt NCCHAR}でなければならない
 (このインターフェースの欠点であるが, 以前とのコンパチビリティのために
  必要である).
\item[\tt ATTLEN] {\tt NCAPT}において, その属性に与えられる数値の数である.
\item[\tt VALUE] {\tt NCAPT}において, {\tt ATTLEN}のデータ値の配列である.
 このデータは, そのnetCDF属性として適当な型でなければならない.
 {\bf 警告: コンパイラもnetCDFソフトウェアも間違ったデータ型が使われて
 いるかどうかを検出できない.}
\item[\tt STRING] {\tt NCAPTC}において, 属性の文字列値である.
\item[\tt LENSTR] {\tt NCAPTC}において, {\tt STRING}パラメターの宣言され
 ている文字長の総計である. 
 引数として配列が与えられることもあるので, この値は, FORTRANの{\tt LEN}
 関数が返す値と必ずしも同じであるとは限らないことに注意されたい.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCAPT}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
{\tt valid\_range}という名前の属性および, {\tt title}という名前のグ
ローバル属性, を追加している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
      DOUBLE RHRNGE(2)
      DATA RHRNGE /0.0D0, 100.0D0/
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      CALL NCREDF (NCID, RCODE)     ! 定義モードに入る
      RHID = NCVID (NCID, 'rh', RCODE)! IDを取得
         ...
      CALL NCAPT (NCID, RHID, 'valid_range', NCDOUBLE, 2, RHRNGE, RCODE)
      CALL NCAPTC (NCID, NCGLOBAL, 'title', NCCHAR, 19, 'example netCDF file', RCODE)
         ...
      CALL NCENDF (NCID, RCODE)     ! 定義モードを抜ける
\end{verbatim}}

%-----------------------------------------------------------------------
\section{属性に関する情報を取得する: NCAINQ}

関数{\tt NCAINQ}は, 変数IDおよび名前を与えて, netCDF属性に関する情報を
返す. 返される情報は, 属性の型および長さである.

エラーが生じた場合には, {\tt NCAINQ}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定された属性が存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCAINQ (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM,
     +                   INTEGER ATTYPE, INTEGER ATTLEN,INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 属性変数の変数ID, または, グローバル属性については
 {\tt NCGLOBAL}.
\item[\tt ATTNAM] 属性名.
\item[\tt ATTTYP] 属性の型(前もって定義されているnetCDFデータ型集合の一つ)
 が返される. 適当なnetCDFデータ型は{\tt NCBYTE}, {\tt NCCHAR}, {\tt
 NCSHORT}, {\tt NCLONG}, {\tt NCFLOAT}, および{\tt NCDOUBLE}である. 
\item[\tt ATTLEN] その属性に現在格納されている値の数が返される.
 文字列値を持つ属性については, これは文字列中の文字数となる.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCAINQ}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
{\tt valid\_range}という名前の属性および, {\tt title}という名前のグ
ローバル属性, を調べている:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
      INTEGER  VRTYPE, TTYPE      ! 属性の型
      INTEGER  VRLEN, TLEN        ! 属性の長さ
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)! IDを取得
         ...
      CALL NCAINQ (NCID, RHID, 'valid_range', VRTYPE, VRLEN, RCODE)
      CALL NCAINQ (NCID, NCGLOBAL, 'title', TTYPE, TLEN, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{属性値を取得する: NCAGT(C)}

関数{\tt NCAGT}または{\tt NCAGTC}は, 変数IDおよび名前を与えて, netCDF
属性の値を返す.

エラーが生じた場合には, {\tt NCAGT}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定された属性が存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCAGT (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM,
     +                  型 VALUES, INTEGER RCODE)

      SUBROUTINE NCAGTC (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM,
     +                   CHARACTER*(*) STRING, INTEGER LENSTR, INTEGER RCODE)
\end{verbatim}
\end{quote}

2つのFORTRANサブルーチン{\tt NCAGT}および{\tt NCAGTC}は属性値を取り出
す. 最初のものは数値型の属性に対するもので, 2番目のものは文字列型の属
性に対するものである.

\begin{quote}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 属性変数の変数ID, または, グローバル属性については
 {\tt NCGLOBAL}.
\item[\tt ATTNAM] 属性名.
\item[\tt VALUES] 属性値が返される. 属性値ベクトルのすべての要素が返され
 るので, それらを保持するのに十分なスペースを与えておかねばならない.
 どれだけのスペースを用意しておかねばならないか不明な場合には, 
 まず{\tt NCAINQ}を呼び出して属性の長さを調べればよい.
\item[\tt STRING] {\tt NCAGTC}において, 属性の文字列値である.
\item[\tt LENSTR] {\tt NCAGTC}において, 呼び出し時の{\tt STRING}パラメター
 の宣言されている文字長の総計である. 
 引数として配列が与えられることもあるので, この値は, FORTRANの{\tt LEN}
 関数が返す値と必ずしも同じであるとは限らないことに注意されたい.
 {\tt NCAGTC}は, 要求されるデータが{\tt LENSTR}個の文字に合っていること
 をチェックする.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCAGT}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
{\tt valid\_range}という名前の属性および, {\tt title}という名前のグ
ローバル属性, を決定している.
この例において, どれだけ多くの値が返されるかを知らないとしている.
そのため, まず属性の長さを問い合わせ, 値を格納するのに十分なスペースを
確保している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      PARAMETER (MVRLEN=3) ! "valid_range"の値の最大数
      PARAMETER (MTLEN=80) ! "title"属性の最大長さ
      INTEGER  NCID, RCODE
      INTEGER  RHID               ! 変数ID
      INTEGER  VRTYPE, TTYPE      ! 属性の型
      INTEGER  VRLEN, TLEN        ! 属性の長さ
      DOUBLE PRECISION VRVAL(MVRLEN) ! vr属性の値
      CHARACTER*80 TITLE          ! title属性の値
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE) ! IDを取得
         ...
* 属性の長さを調べ, 十分なスペースを確保している
      CALL NCAINQ (NCID, RHID, 'valid_range', VRTYPE, VRLEN, RCODE)
      CALL NCAINQ (NCID, NCGLOBAL, 'title', TTYPE, TLEN, RCODE)
* もし大きすぎないならば, 属性の値を取得する
      IF (VRLEN .GT. MVRLEN) THEN
          WRITE (*,*) 'valid_range attribute too big!'
          CALL EXIT
      ELSE
          CALL NCAGT (NCID, RHID, 'valid_range', VRVAL, RCODE)
      ENDIF
      IF (TLEN .GT. MTLEN) THEN
          WRITE (*,*) 'title attribute too big!'
          CALL EXIT
      ELSE
          CALL NCAGTC (NCID, NCGLOBAL, 'title', TITLE, MTLEN, RCODE)
      ENDIF
\end{verbatim}}

%-----------------------------------------------------------------------
\section{あるnetCDFから他へ属性をコピーする: NCACPY}

関数{\tt NCACPY}または{\tt NCAGTC}は, あるオープンされたnetCDFファイル
から他へ属性をコピーする.
これは, 同一のnetCDFファイル内で, 一つの変数から他の変数へ属性をコピー
するのにも使うことができる.

エラーが生じた場合には, {\tt NCACPY}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 入力または出力の変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定された属性が存在していない.
\item 出力のnetCDFが定義モードになく, かつその出力ファイルにおいて
 その属性が新しいまたは既存の属性より大きい.
\item 入力または出力の指定されたnetCDF IDがオープンされたnetCDFファ
 イルを参照していない.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCACPY (INTEGER INCDF, INTEGER INVAR, CHARACTER*(*) ATTNAM,
     +                   INTEGER OUTCDF, INTEGER OUTVAR, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt INCDF] 属性がそこからコピーされるべき入力netCDFファイルのnetCDF
 IDであり, 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返される.
\item[\tt INVAR] 属性がそこからコピーされるべき入力netCDFファイル中の変数ID
 または, グローバル属性については{\tt NCGLOBAL}.
\item[\tt ATTNAM] コピーされる入力netCDFファイル中の属性名.
\item[\tt OUTCDF] 属性がコピーされるべき宛先の出力netCDFファイルのnetCDF ID
 であり, 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返される.
 入力と出力のnetCDF IDが同じでもよい.
 コピーされるべき属性が宛先の変数にまだ存在しない場合, またはコピーによっ
 て既存の宛先となる属性が大きくなる場合, には出力netCDFファイルは定義モー
 ドになければならない.
\item[\tt OUTVAR] 属性がコピーされるべき宛先の出力netCDFファイルの変数ID,
または, グローバル属性へコピーする際には, {\tt NCGLOBAL}.
\end{description}
\end{quote}

以下の例では, {\tt NCACPY}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイル中の{\tt rh}という名前のnetCDF変数から変数属性
{\tt units}を, 他の既存の`{\tt bar.nc}'という名前のnetCDFファイル中の
{\tt avgrh}という名前のnetCDF変数へコピーしている;
ここで, 変数{\tt avgrh}が既に存在しているが, まだ{\tt units}属性を持っ
ていないということを仮定している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID1, NCID2     ! netCDF ID
      INTEGER  RHID, AVRHID       ! 変数ID
         ...
      NCID1 = NCOPN ('foo.nc', NCNOWRIT, RCODE)
      NCID2 = NCOPN ('bar.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID1, 'rh', RCODE)
      AVRHID = NCVID (NCID2, 'avgrh', RCODE)
         ...
      CALL NCREDF (NCID2, RCODE)  ! 定義モードに入る
* 変数属性を"rh"から"avgrh"へコピーする
      CALL NCACPY (NCID1, RHID, 'units', NCID2, AVRHID, RCODE)
         ...
      CALL NCENDF (NCID2, RCODE)  ! 定義モードから抜ける
\end{verbatim}}

%-----------------------------------------------------------------------
\section{番号から属性名を取得する: NCANAM}

関数{\tt NCANAM}は, 変数IDおよび番号を与えて, 属性の名前を取得する.
この関数は, ある変数に関連したすべての変数の名前を取得する必要がある一
般アプリケーションにおいて便利である, なぜなら, 他のすべての属性関数は
番号ではなく名前で属性にアクセスするからである.
属性の番号は, 名前よりも変わりやすい, なぜなら, 同じ変数の他の属性が削
除された際に, 番号は変わりうるからである.
属性番号が属性IDとは呼ばれないのはこのためである.

エラーが生じた場合には, {\tt NCANAM}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 指定された属性番号が負であるか, 指定された変数に対して定義されて
      いる属性の数より大きい.
\item 指定された属性が存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCANAM (INTEGER NCID, INTEGER VARID, INTEGER ATTNUM, 
     +                   CHARACTER*(*) ATTNAM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 属性変数の変数ID, または, グローバル属性については
 {\tt NCGLOBAL}.
\item[\tt ATTNUM] 属性の数. 各変数に対する属性は1(第1属性)から
 {\tt NVATTS}まで番号づけられている.
 ここに, {\tt NVATTS}は変数に対する属性の数で, {\tt NCVINQ}呼び出しで
 返される.
\item[\tt ATTNAM] 属性名が返される. 返される名前のためのスペースを割り当
 てておかねばならない. 属性名の可能な最大文字長は, 前もって定義されて
 いる定数{\tt MAXNCNAM}で与えられている.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCANAM}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
第1属性の名前を決定している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID     ! netCDF ID
      INTEGER  RHID      ! 変数ID
* 以下の31は, MAXNCNAMである
      CHARACTER*31 ATTNAM
         ...
      NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)
         ...
* 第1属性(番号1)の名前を取得する
      CALL NCANAM (NCID, RHID, 1, ATTNAM, RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{属性名を変更する: NCAREN}

関数{\tt NCAREN}は, 属性名を変更する.
新しい名前がもとの名前より長い場合には, netCDFファイルは定義モードにな
ければならない.
同じ変数の他の属性と同じ名前となってしまうような属性名の変更はできない.

エラーが生じた場合には, {\tt NCAREN}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 変数IDが指定されたnetCDFファイルにおいて適当でない.
\item 新しい属性名が, 指定された変数の他の属性にすでに使われている.
\item 指定されたnetCDFファイルがデータモードにあり, かつ新しい名前が古
      い名前よりも長い.
\item 指定された属性が存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCAREN (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM,
     +                   CHARACTER*(*) NEWNAM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 属性変数の変数ID, または, グローバル属性については
 {\tt NCGLOBAL}.
\item[\tt ATTNAM] もとの属性名.
\item[\tt NEWNAM] 指定された属性に割り当てられる新しい名前.
 新しい名前が古い名前よりも長い場合には, netCDFファイルは定義モードに
 なければならない.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCAREN}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
変数属性の名前を{\tt units}から{\tt Units}に変更している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE "netcdf.inc"
         ...
      INTEGER  NCID     ! netCDF ID
      INTEGER  RHID      ! 変数ID
         ...
      NCID = NCOPN ("foo.nc", NCNOWRIT, RCODE)
         ...
      RHID = NCVID (NCID, "rh", RCODE)
         ...
* 属性名を変更
      CALL NCAREN (NCID, RHID, "units", "Units", RCODE)
\end{verbatim}}

%-----------------------------------------------------------------------
\section{属性を削除する: NCADEL}

関数{\tt NCADEL}は, オープンされているnetCDFファイルからnetCDF属性を削
除する. netCDFファイルは定義モードになければならない.

エラーが生じた場合には, {\tt NCADEL}は{\tt RCODE}として非零の値を返す.
エラーの原因として考えられるものとしては以下のようなものが挙げられる:
\begin{itemize}
\item 指定された変数IDがて適当でない.
\item 指定されたnetCDFファイルがデータモードにない.
\item 指定された属性が存在していない.
\item 指定されたnetCDF IDがオープンされたnetCDFファイルを参照していな
      い.
\end{itemize}

\begin{quote}
\begin{verbatim}
      SUBROUTINE NCADEL (INTEGER NCID, INTEGER VARID, CHARACTER*(*) ATTNAM, INTEGER RCODE)
\end{verbatim}
\begin{description}
\item[\tt NCID] 以前の{\tt NCOPN}または{\tt NCCRE}呼び出しで返された
 netCDF ID.
\item[\tt VARID] 属性変数の変数ID, または, グローバル属性については
 {\tt NCGLOBAL}.
\item[\tt ATTNAM] もとの属性名.
\item[\tt RCODE] 返されたエラーコード. エラーが生じていなければ, 0が返される.
\end{description}
\end{quote}

以下の例では, {\tt NCADEL}を使って, 既存の`{\tt foo.nc}'という名前の
既存のnetCDFファイルにおいて, {\tt rh}という名前のnetCDF変数に対する
変数属性{\tt Units}を削除している:
{\baselineskip=\vs
\begin{verbatim}
      INCLUDE 'netcdf.inc'
         ...
      INTEGER  NCID     ! netCDF ID
      INTEGER  RHID      ! 変数ID
         ...
      NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
         ...
      RHID = NCVID (NCID, 'rh', RCODE)
         ...
* 属性を削除
      CALL NCREDF (NCID, RCODE)  ! 定義モードに入る
      CALL NCADEL (NCID, RHID, 'Units', RCODE)
      CALL NCENDF (NCID, RCODE)  ! 定義モードから抜ける
\end{verbatim}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{netCDFファイル構造および性能}
\label{netCDFファイル構造および性能}

netCDFは, 配列指向のデータアクセスのためのデータ抽象化, およびその抽象
化をサポートするインターフェースの具体的な実装を与えるソフトウェアライ
ブラリである.
その実装によって, 配列を表現するための機種独立なフォーマットが与えられ
る.
netCDFファイルフォーマットはインターフェースから隠されているが, 実装お
よび関連したファイル構造をいくらかでも理解することによって, どのnetCDF
操作になぜコストがかかるかを明白にする手助けになる.

netCDF{\bf フォーマット}のより詳細な記述については, Appendix B[ファイ
ルフォーマット仕様]\pageref{ファイルフォーマット仕様}ページを参照.
これは, netCDFファイルを読み書きしたり, 効率に関することを理解したりす
るためには必要ない.
文書化されたインターフェースだけを使い, かつフォーマットについて他の仮
定をしていないプログラムは, 将来, netCDFフォーマットがたとえ変更されて
も機能し続けるであろう, なぜなら, このようなあらゆる変更は, 文書化され
たインターフェースの下層でなされ, かつ以前のバージョンのnetCDFデータも
サポートされるからである.

この章では, netCDFファイルの構造, およびネットワーク透過性を与えるXDR
層のいくつかの性質を, netCDFの性能の点について理解するのに十分なくらい
詳細に記述する.

%-----------------------------------------------------------------------
\section{netCDFファイルの部分部分}

netCDFデータセットは, 2つの部分より成る1つのファイルに格納される.
\begin{itemize}
\item {\bf ヘッダ}: 次元, 属性, および変数データを除く変数, に関するす
      べての情報を含む.
\item {\bf データ}部分: {\bf 固定サイズデータ}(無制限次元を持たない変
 数に対するデータを含む)および{\bf 記録データ}(無制限次元を持つ変数に
 対するデータ記録を含む)
\end{itemize}

すべてのデータは, 機種独立にするためにXDR形式で表現される.

netCDFファイルの初めにある記述的なヘッダは, ファイル中の次元, 変数, お
よび属性に関する情報を表す高度なデータ構造をXDRでコード化したものであ
る.
このヘッダにおける変数記述には, 各変数データの先頭へのオフセット, また
は, ある記録中のある変数の相対オフセットが含まれている.
この記述には, 次元サイズ, および各変数に対する複数次元のインデックスを
適切なオフセットにどのようにマップするかを決定するために必要な情報も
含まれている.

このヘッダには使用可能な余分スペースはない; 各netCDFファイル内の次元, 
変数, および属性のために必要な大きさしかない.
これにより, netCDFファイルがコンパクトになり, ファイルを自己記述的にす
るための補助データを格納するために殆どオーバヘッドを必要としない, とい
う利点がある.
この機構の潜在的な欠点は, ヘッダを拡張する必要のあるnetCDFファイルへの
操作, 例えば, 既存のnetCDFファイルに新しい次元,および新しい変数を追加
するなど, はそのファイルをコピーするのと同じコストがかかる.
このコストは, {\tt NCREDF}が呼ばれた後で{\tt NCENDF}が呼ばれる際
にかかる.
必要なすべての次元, 変数, および属性を変数データを書く{\bf 前に}生成し,
後になってファイルのヘッダ部分により多くのスペースを必要とするような
netCDF要素の追加および名前の変更をしないようにすれば,
ヘッダの拡張に伴うコストを回避することができる.

ヘッダに続く固定サイズデータ部分は, 無次元(記録)次元を使っていない変数
に対するすべての変数データを含む.
各変数のデータはファイルのこの部分に連続的に格納される.
もし無制限次元がなければ, これはnetCDFファイルの最後の部分である.

固定サイズデータに続く記録データ部分は, 可変数の記録を含み, 各記録が
すべての記録変数のためのデータを含んでいる.
各変数に対する記録データは, 各記録内に連続的に格納される.

固定サイズデータ部分内および各記録内にデータが現れる順番は, 変数が定義
されたのと同じ順番であり, これはnetCDF変数IDの昇順である.
この知識は, データアクセス性能を向上させるために使われることもある;
なぜなら, 最もよいデータアクセスは今のところ, データを順次的に読み書き
することによって達成されるからである.

%-----------------------------------------------------------------------
\section{XDR層}

XDRは, データの記述およびコード化の標準であり, 外部データ表現のためのライ
ブラリである. これを使って, 機種独立な形でデータ構造をコード化すること
ができる.
netCDFはヘッダ部分およびデータ部分の両方において, すべてのデータの表現
のためにXDRを採用している.
XDRは, XDRライブラリが実装されている他のマシン上で読めるような可搬性の
あるデータを書くために使われる.

%-----------------------------------------------------------------------
\section{XDRについての一般的考察}

多くのベンダが, Cランタイムライブラリと一緒にXDRを提供している.
配布されるnetCDFソフトウェアもまた, ベンダーがまだXDRライブラリを供給
していないプラットフォームのために, Sunの可搬的なXDRの実装を含んでいる.

XDR層がXDRでコード化されたデータをnetCDFファイルに読み書きするには,
C標準I/O(stdio)ライブラリとそっくりに実装されているI/O層を使う.
従って, データに同時にアクセスする多重プロセス, I/Oバッファの使用,
およびnetCDFファイルをオープン/クローズするコスト, についてのほとんど
の質問には, 標準I/Oライブラリを理解すれば答えられる.
特に, あるプロセスがnetCDFファイルを書いて, その間に他のプロセスがそれ
を読むということが可能である.
データの読み書きには, stdioの{\tt fread()}および{\tt fread()}より下位
の呼び出しは使っていない.
{\tt NCSNC()}は標準I/Oライブラリの{\tt fflush()}に類似したものであり,
まだ書かれていないバッファされてるデータを書き出して, 他のプロセスがそ
れを読めるようにする; {\tt NCSYNC()}はヘッダの変更を最新のものにする
(例えば, 属性値への変更など).

stdioライブラリのときと同様に, ファイルの異なる領域への``探索''が生じ
た際にflushが実行される.
従って, 読み書きの操作の順番は, I/Oの性能に著しく影響を与えうる.
各記録中にデータが書かれたのと同じ順番でデータを読めば, バッファの
flushは最小限になる.

状況がより複雑になる普通でない場合が一つある: 他のプロセスも読み込みの
ためにオープンしている既存のnetCDFファイルに, 
いくつかの追加次元, 変数, または属性, を追加するために, 書き込み側が定
義モードに入るような場合である.
この場合, 書き込み側が定義モードから抜けると, 新しい次元, 属性, または
変数, と古いデータを持つファイルのコピーが新しく生成されるが, そのファ
イルをまだオープンしている読み込み側は, そのファイルをクローズして, 再
オープンしない限り, その変更を感知できない.

同じファイルを同時に書き込みオープンしている書き込みが多重にあるような
場合には, netCDFデータアクセスはまともに機能しないかもしれない.

XDR下のI/O層を, プラットフォームに特化した他のI/O層に置き換えることに
よって, netCDFの実装をチューンできるプラットフォームもある.
これは, 例えば, Crayについてなされている.
これによって, netCDFと標準I/Oの類似性が変わってしまい, それゆえにデー
タの共有化, バッファリング, およびI/O操作のコストに関連した性質も変わっ
てしまう可能性はある.

XDRのような, データに対するまっとうな表現を使うことによるコストは, デー
タの型および, そのデータに対するそのマシン本来形式がXDR形式と同じであ
るかどうかに依存して変わりうる.
XDRは, byte, character, およびshort整数データについては特に効率が
良い.

とあるマシン上におけるとあるデータ型については, データをXDR(に/から)変
換するのに必要な時間が重大になることもある.
最もよいのは, byteの配列で, そのためには, ほとんど変換コストが生じない;
なぜなら, XDRライブラリは, それらに対するサポートを内蔵しているからで
ある.
netCDFの実装には, short(16ビット)整数の配列に対する同様なサポートをXDR
に追加したものが含まれている.
最悪の場合は, IEEE浮動小数点をそれ本来の表現としていないマシン上で浮動
小数点データの大きな配列を読み書きする場合である.
XDRライブラリは, 浮動小数点数がアクセスされるたびごとに, 関数を呼出し,
コストがかかる.
各浮動小数点数のための関数呼び出しのコストが, 浮動小数点部分へのnetCDF
アクセスのコストの大半を占めてしまうようなマシンもある.

配布されているnetCDFの実装は, 可搬性を旨としている.
I/Oの性能をよりよくするための実装のさらなる最適化を行ったり, long整数
および浮動小数点の配列のXDR変換を最適化するためにXDRライブラリ中のルー
プのアンローリングを行ったりするような, プラットフォームに特化した移植
は, データアクセスにより高い性能が求められるような場合には実際的であり
かつ望まれるものである.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{netCDFユーティリティ}
\label{netCDFユーティリティ}

配列を扱うアプリケーションがnetCDFインターフェースを使う主な理由の一つ
は, 高位レベルのnetCDFユーティリティおよびnetCDFデータに対する一般的な
アプリケーションを利用するためである.
現在, netCDFソフトウェア配布の一部として, 2つのnetCDFユーティリティ:
{\tt ncgen}および{\tt ncdump}が利用できる.
多くの利用者が他のnetCDFユーティリティを提供しており, netCDFデータにア
クセスする様々な可視化および解析パッケージが利用可能である.
netCDFデータにアクセスまたはそれを扱う無料の, および商用のソフトウェア
の最新のリストについては, netCDFソフトウェアリスト
(`{\tt http://www.unidata.ucar.edu/packages/netcdf/software.html}')
を参照されたい.

この章では, {\tt ncgen}および{\tt ncdump}ユーティリティについて説明す
る.
これら2つのツールは, バイナリのnetCDFファイルと, netCDFファイルのテキ
スト表現との間の変換をするものである.
{\tt ncdump}の出力および{\tt ncgen}の入力は, netCDFファイルを
CDL(network Common data form Description Language)として知られるささや
かな言語によってテキスト表現したものである.

%-----------------------------------------------------------------------
\section{CDL構文}

以下のCDLの例では, 数個の名前つき次元({\tt lat}, {\tt lon}, {\tt
time}), 変数({\tt z}, {\tt t}, {\tt p}, {\tt rh}, {\tt lat}, {\tt
lon}, {\tt time}), 変数属性({\tt units}, {\tt \_FillValue}, 
{\tt valid\_range}), およびいくらかのデータを持ったnetCDFファイルを記
述している.
{\baselineskip=\vs
\begin{verbatim}
netcdf foo {    // CDLによるnetCDF指定の例

dimensions:
lat = 10, lon = 5, time = unlimited ;

variables:
  long    lat(lat), lon(lon), time(time);
  float   z(time,lat,lon), t(time,lat,lon);
  double  p(time,lat,lon);
  long    rh(time,lat,lon);

  lat:units = "degrees_north";
  lon:units = "degrees_east";
  time:units = "seconds";
  z:units = "meters";
  z:valid_range = 0., 5000.;
  p:_FillValue = -9999.;
  rh:_FillValue = -1;

data:
  lat   = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90;
  lon   = -140, -118, -96, -84, -52;
}
\end{verbatim}}

すべてのCDF文の終りはセミコロンである. 可読性のために, 空白, タブ, お
よび改行を使うのは自由である.
すべての行において, ダブルスラッシュ{\tt //}以下に続くものはコメントで
ある.

CDL記述は, 3つのオプション部分: 次元, 変数, およびデータ, から成る.
変数部は, 変数宣言および属性の割り当てを含んでいてもよい.

次元は, このCDL記述で記述される1つまたはそれ以上の複数次元の変数の形を
定義するために使われる.
次元は名前およびサイズを持つ.
CDL記述の中の1つの次元だけが無制限サイズを持つことができる. すなわち, 
この次元を持つデータは任意の長さに成長しうる(ファイル中の記録数と同様
に). 

変数は, 同じ型の値の複数次元の配列を表現する. 変数は, 名前, データ型,
および, その次元のリストで記述される形持つ.
各変数はデータ値だけではなく, 関連した属性(以下参照)も持てる.
名前, データ型, および変数の形は, CDL記述の変数部分における宣言によっ
て指定される.
変数は次元と同じ名前を持ってもよい; 慣習では, このような変数はその
名前の次元の座標値を含んでいる.

属性は, 変数またはnetCDFデータセット全体についての情報を含んでいる.
属性は, 単位, 特別な値, 有効な値の最大および最小, および圧縮パラメター
のような特性を指定するために使うことができる.
属性情報は, 単一の値または値の配列によって表現される.
例えば, {\tt units}は{\tt celsius}のような文字配列で表現される属性で
ある.
属性は, 関連する変数, 名前, データ型, 長さ, および値を持っている.
データを格納するための変数とは対照的に, 属性は, 補助データ(データにつ
いてのデータ)を格納するためのものである.

CDLにおいては, 属性は変数および属性の名前をコロン(`{\tt :}')で区切った
もので指定される.
変数名を省略し, 属性名をコロン(`{\tt :}')で始めることによって, netCDF
ファイル全体にグローバル属性を割り当てることができる.
CDL中の属性のデータ型は, それに割り当てられている値の型で決まる.
属性の長さは, データ値の数またはその属性に割り当てられている文字列中の
文字数である.
値をコンマ(`{\tt ,}')で区切ることによって, 文字でない属性に複数の値を
割り当てることができる.
属性に割り当てられているすべての値は, 同じ型でなければならない.

変数, 属性, および次元に対するCDL名には, 英文字または数字と(`{\tt \_}')
および(`{\tt -}')文字の任意の組合せが許されるが, (`{\tt \_}')から始ま
る名前はライブラリのために予約されている.
CDL名では大文字小文字は区別される.
netCDFライブラリはnetCDF名に何ら制限を設けていないので, CDL名として適
当でない名前をもつ変数を定義することも(愚かなことではあるが)可能である.
基本的なデータ型の名前はCDL中の予約語なので, 変数, 次元および属性の名
前は型の名前であってはならない.

CDL記述のオプショナルデータ部分では, netCDF変数が初期化される.
初期化の構文は簡単である:
\begin{quote}
{\bf 変数} = {\bf 値1}, {\bf 値2},...;
\end{quote}

コンマで区切られた定数のリストは, 空白, タブ, および改行で分けることが
できる.
複数次元の配列については, 最後の次元が先に変わる.
というわけで, 行列については, 行順ではなく列順が使われる.
変数を満すのに必要なのよりも少ない値しか与えられない場合には, フィル値
が展開される.
その定数の型は変数に宣言された型と合致している必要はない;
例えば, 整数を強制的に浮動小数点に変換するといった操作がなされる.
意味のあるすべての型変換がサポートされている.

フィル値のための特別の記法がサポートされている: `{\tt \_}'文字は, 変数
のためのフィル値を示す.

%-----------------------------------------------------------------------
\section{CDLデータ型}

CDLデータ型は以下のようである:

\begin{quote}
\begin{description}
\item[{\tt char}] 文字
\item[{\tt byte}] 8ビット整数
\item[{\tt short}] 16ビット符号つき整数
\item[{\tt long}] 32ビット符号つき整数
\item[{\tt int}] longと同義
\item[{\tt float}] IEEE単精度浮動小数点(32ビット)
\item[{\tt real}] floatと同義
\item[{\tt double}] IEEE倍精度浮動小数点(64ビット)
\end{description}
\end{quote}

{\tt byte}データ型が追加されていること, および{\tt unsigned}修飾子が無
いことを除けば, CDLはCと同じ基本データ型をサポートしている.
宣言文において, データ型は, 大文字または小文字のどちらかで指定される.

{\tt byte}型は, 8ビットデータを格納するためにあるという点において,
{\tt char}型と異なっており, 0のバイトは, 文字データにおけるような特別
な意味を持たない.
{\tt ncgen}ユーティリティは{\tt byte}宣言を, 出力FORTRANコードでは,
{\tt BYTE}, {\tt INTEGER*1}, または同様のプラットフォーム依存の宣言
に変換する.

{\tt short}型は -32768から32767までの値を保持する.
{\tt ncgen}ユーティリティは{\tt byte}宣言を, 出力FORTRANコードでは,
{\tt INTEGER*2}宣言に変換する.

{\tt long}型は -2147483648から2147483647までの値を保持する.
{\tt ncgen}ユーティリティは{\tt byte}宣言を, 出力FORTRANコードでは,
{\tt INTEGER}宣言に変換する.
CDL宣言においては, {\tt int}と{\tt integer}は{\tt long}の同義語として
解釈される.

{\tt float}型は -3.4{\tt +}38から3.4{\tt +}38までの値を,
32ビットIEEE規格の単精度浮動小数点数の外部表現を用いて保持する.
{\tt ncgen}ユーティリティは{\tt float}宣言を, 出力FORTRANコードでは,
{\tt REAL}宣言に変換する.
CDL宣言においては, {\tt real}は{\tt float}の同義語として解釈される.

{\tt double}型は -1.7{\tt +}308から1.7{\tt +}308までの値を,
64ビットIEEE規格の単精度浮動小数点数の外部表現を用いて保持する.
{\tt ncgen}ユーティリティは{\tt double}宣言を, 出力FORTRANコードでは,
{\tt DOUBLE PRECISION}宣言に変換する.

%-----------------------------------------------------------------------
\section{データ定数に対するCDL表記}
\label{データ定数に対するCDL表記}

この節では, 定数に対するCDL表記について説明する.

属性は, CDL記述の{\tt variables}節において, 属性の型および長さを決める
定数のリストを与えることによって初期化される.
(netCDFライブラリへのCおよびFORTRAN手続きインターフェースにおいて,
属性の型および長さは, それが定義される再に陽に与えられなければならない.)
CDLは異なるnetCDF型の中から型を区別できるような, 定数値のための構文を
定義している.
CDL定数のための構文は, Cの構文に類似しているが, {\tt shorts}および
{\tt floats}を{\tt long}および{\tt double}から区別するために, 型を示す
添字が追加されている.

{\tt byte}定数は単一の文字または, シングルクオートで囲まれた複数文字のエ
スケープ列, で表現される. 例えば:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
'a'     // ASCII a
'\0'    // 0のバイト
'\n'    // ASCII改行文字
'\33'   // ASCIIエスケープ文字 (8進数で33)
'\x2b'  // ASCIIプラス (16進数で2b)
'\376'  // 8進数で377 = 10進数で-127 (または254)
\end{verbatim}
\end{quote}

文字定数はダブルクオートで囲まれる. 文字配列はダブルクオートで囲まれた
文字列で表現できる.
複数の文字列は, 1つの文字配列に連結される; これによって, 長い文字配列
を複数行に書くことができる.
複数の可変長の文字列値をサポートするために, `{\tt ,}'のような慣習的な
区切り文字を使うことはできるが, 文字列区切りのためのこのような慣習
は, netCDFライブラリ層の上のソフトウェアで実装されなければならない.
C文字列に対する通常のエスケープ文字の慣習はそのまま使える.
例えば:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
"a"            // ASCII `a'
"Two\nlines\n" // 2つの改行文字を埋めこまれた10文字の文字列
"a bell:\007"  // ASCII ベルを含んだ文字列
"ab","cde"     // "abcde"に同じ
\end{verbatim}
\end{quote}

{\tt short}定数の形式は, `{\tt s}'または`{\tt S}'を付加した整定数であ
る.
{\tt short}定数が`{\tt 0}'で始まっている場合は, 8進数であると解釈され
る.
`{\tt 0x}'で始まっている場合は, 16進数であると解釈される.
例えば:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
2s      // short型の2
0123s   // 8進数
0x7ffs  // 16進数
\end{verbatim}
\end{quote}

{\tt long}定数の形式は, 通常の整定数である; ただし, オプションとして
`{\tt l}'または`{\tt L}'を付加してもよい.
{\tt long}定数が`{\tt 0}'で始まっている場合は, 8進数であると解釈される.
`{\tt 0x}'で始まっている場合は, 16進数であると解釈される.
妥当な{\tt long}定数の例は以下のようである:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
-2
1234567890L
0123            // 8進数
0x7ff           // 16進数
\end{verbatim}
\end{quote}

{\tt float}型は, 有効数字約7桁の精度を持つデータを表現するのに適当なも
のである.
{\tt float}型の形式は, Cの浮動小数点定数に`{\tt f}'または`{\tt F}'を付
加したものと同じである.
CDL{\tt float}においては, 整数と区別するために, 小数点が必須である.
妥当な{\tt float}定数の例は以下のようになる:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
-2.0f
3.14159265358979f       // 低精度に丸められる
1.f
.1f
\end{verbatim}
\end{quote}

{\tt double}型は, 有効数字約16桁の精度を持つデータを表現するのに適当なも
のである.
{\tt double}型の形式は, Cの浮動小数点定数と同じである.
オプションとして`{\tt d}'または`{\tt D}'を付加してもよい.
CDL{\tt double}においては, 整数と区別するために, 小数点が必須である.
妥当な{\tt double}定数の例は以下のようになる:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
-2.0
3.141592653589793
1.0e-20
1.d
\end{verbatim}
\end{quote}

%-----------------------------------------------------------------------
\section{ncgen}
\label{ncgen}

{\tt ncgen}ツールは, netCDFファイルまたは, netCDFファイルを生成するCま
たはFORTRANプログラム, を作成する.
{\tt ncgen}を呼び出す際にオプションを指定しなければ, このプログラムは
CDL入力の構文をチェックするのみで, CDL構文違反についてのエラーメッセー
ジを出すだけである.

{\tt ncgen}をUNIXで呼び出すための書式は:
\begin{quote}
\begin{verbatim}
ncgen [-b] [-o netCDFファイル] [-c] [-f] [-n] [入力ファイル]
\end{verbatim}
\end{quote}
ここに, 
\begin{description}
\item[`{\tt -b}']  (バイナリの)netCDFファイルを生成する. `{\tt -o}'が
 指定されていない場合は, デフォルトのファイル名がnetCDF名(入力中の{\tt
 netcdf}キーワードの後に指定される)から, 拡張子`{\tt .nc}'に付加して作
 成される.
 {\bf 警告: もし指定された名前のファイルが既に存在していると, それは上
 書きされる.}
\item[`{\tt -o netcdfファイル}']  生成されるnetCDFファイルの名前を指定
 する. このオプションが指定されると, `{\tt -b}'オプションが暗黙に仮定
 される.
 (netCDFファイルは探索呼び出しによって生成される直接参照ファイルであり,
 そのため標準出力に書くことができないので, このオプションが必要である.)
\item[`{\tt -c}'] netCDF指定に合致したnetCDFファイルを生成するCのソー
 スコードを作成する. このCソースコードは, 標準出力に出力される.
 これは, 比較的小さなCDLファイルについてのみ有用なものでである;
 なぜなら, 作成されたプログラム中ではすべてのデータは変数初期化の中に
 含まれてしまうからである.
\item[`{\tt -f}'] netCDF指定に合致したnetCDFファイルを生成する
 FORTRANのソースコードを作成する. このFORTRANソースコードは, 標準出力
 に出力される.
 これは, 比較的小さなCDLファイルについてのみ有用なものでである;
 なぜなら, 作成されたプログラム中ではすべてのデータは変数初期化の中に
 含まれてしまうからである.
\item[`{\tt -n}'] `{\tt -b}'オプションと同様であるが, `{\tt -o}'オプショ
 ンで出力ファイル名が指定されていない場合には`{\tt .nc}'拡張子の代わり
 に旧式の`{\tt .cdf}'拡張子を持ったnetCDFファイルを生成する.
 このオプションは以前とのコンパチビリティのためにサポートされているだ
 けである.
\end{description}

%-----------------------------------------------------------------------
\section*{例}

CDLファイル`{\tt foo.cdl}'の構文をチェックする:
\begin{quote}
\begin{verbatim}
ncgen foo.cdl
\end{verbatim}
\end{quote}

CDLファイル`{\tt foo.cdl}'から,`{\tt bar.nc}'という名前の等価なバイナ
リファイルを作成する.
\begin{quote}
\begin{verbatim}
ncgen -o bar.nc foo.cdl
\end{verbatim}
\end{quote}

CDLファイル`{\tt foo.cdl}'から, 等価なバイナリファイルを生成するために
必要なnetCDF関数呼出しを含むCプログラムを作成する:
\begin{quote}
\begin{verbatim}
ncgen -c foo.cdl &gt; foo.c
\end{verbatim}
\end{quote}

%-----------------------------------------------------------------------
\section{ncdump}
\label{ncdump}

{\tt ncdump}ツールは, netCDFファイルのCDLテキスト表現を標準出力に出力
する; オプションで, 入力中のデータの変数の一部または全てを除外すること
もできる.
{\tt ncdump}の出力は, {\tt ncgen}への入力として使えるようになっている.
従って, {\tt ncdump}および{\tt ncgen}は, バイナリおよびテキスト表現の
間でデータ表現を変換するための正逆変換として使うことができる.

{\tt ncdump}は, netCDFデータファイルの簡単な閲覧手段として使うことがで
き, netCDFファイルの中身について以下のような表示ができる:
次元名およびサイズ; 変数名, 型および形; 属性名および値; およびオプ
ションですべての変数または選択された変数の値.

{\tt ncdump}は, netCDF変数データの各型に使われるデフォルトのフォーマッ
トを定義しているが, これは{\tt C\_format}属性がnetCDF変数に対して定義
されていれば上書きされる.
この場合, {\tt ncdump}は{\tt C\_format}属性を使って, その変数の値のフォー
マットを行う.
例えば, netCDF変数{\tt Z}に対する浮動小数データが有効数字3桁の精度しか
ないことが分かっているならば, この変数属性を使うのが適当である.

{\tt ncdump}は, `{\tt \_}'を使って, 変数に対する{\tt \_FillValue}属性
(これはまだ書かれていないデータを表現するためのものである)と等しいデー
タ値を表す.
もし, 変数が{\tt \_FillValue}属性を持っていなければ, その変数型に対す
るデフォルトのフィル値が使われる; その変数がバイト型でなければ.
\begin{quote}
\begin{verbatim}
Z:C_format = "%.3g"
\end{verbatim}
\end{quote}

{\tt ncdump}をUNIXで呼び出すための書式は:
\begin{quote}
\begin{verbatim}
ncdump  [ -c | -h]  [-v 変数1,...]  [-b 言語]  [-f 言語]
[-l 長さ]  [ -d floatの桁[,doubleの桁] [ -n 名前]  [入力ファイル]
\end{verbatim}
\end{quote}
ここに,
\begin{description}
\item[`{\tt -c}'] 全ての次元, 変数, および属性値の宣言と, 
 {\tt 座標}変数(次元にもなっている変数)の値を表示する.
 座標変数でない変数のデータ値は出力には含まれない.
 これは, netCDFファイルの構造および中身を簡潔に見るのに
 たいてい最も適したオプションである.

\item[`{\tt -h}'] {\bf ヘッダ}の情報のみを出力する, すなわち,
 入力ファイルのnetCDF次元, 変数, および属性の宣言のみを出力し,
 変数のデータ値は出力しない.
 出力は, 座標変数の値が含まれないことを除けば, `{\tt -c}'オプション
 を使うのと同じである. (`{\tt -c}'または`{\tt -h}'オプションのどちらか
 一方しか指定してはならない.)

\item[`{\tt -v 変数1,...}'] すべての次元, 変数, および属性の宣言に加え
て, 指定された変数のデータ値が出力に含まれる.
このオプションに続けてコンマで区切った名前のリストを与えることによって,
1つまたはそれ以上の変数を指定しなければならない.
このリストはコマンドへの単一の引数でなければならないので, 空白または他
の空白文字を含めることはできない.
名前つき変数は, 入力ファイル中の妥当なnetCDF変数でなければならない.
このオプションおよび`{\tt -c}'または`{\tt -h}'オプションを指定しないデ
フォルトでは, {\bf すべての}変数に対するデータ値が出力に含まれる.

\item[`{\tt -b 言語}'] CDLコメント(`{\tt //}'で始まる文字)の形式の
 簡潔な注釈が, 出力のデータ節中におけるデータの各`列'に対して含まれる
 ようになり, 複数次元の変数に対するデータ値を確認する助けになる.
 {\bf 言語}が`{\tt C}'または`{\tt c}'で始まっている場合には, C言語の慣
 例が使われる(0を基準としたインデックス, 最後の次元が真っ先に変わる).
 {\bf 言語}が`{\tt F}'または`{\tt f}'で始まっている場合には, FORTRAN言
 語の慣習が使われる(1を基準としたインデックス, 最初の次元が真っ先に変
 わる).
 どちらの場合においても, データは同じ順番で表示される; 注釈のみが異な
 る. このオプションは, 大量の複数次元のデータを一覧するのに便利なオプ
 ションである.

\item[`{\tt -f 言語}'] CDLコメント(`{\tt //}'で始まる文字)の形式の, 
 各データ値(文字配列の個々の文字は除いて)に対する完全な注釈がデータ節
 に含まれるようになる.
 {\bf 言語}が`{\tt C}'または`{\tt c}'で始まっている場合には, C言語の慣
 例が使われる(0を基準としたインデックス, 最後の次元が真っ先に変わる).
 {\bf 言語}が`{\tt F}'または`{\tt f}'で始まっている場合には, FORTRAN言
 語の慣習が使われる(1を基準としたインデックス, 最初の次元が真っ先に変
 わる).
 どちらの場合においても, データは同じ順番で表示される; 注釈のみが異な
 る. このオプションは, データを他のフィルターにパイプするのに便利なオ
 プションである; なぜなら, 各データ値は別々の行に表示され, 完全に識別
 されるからである. (`{\tt -b}'または`{\tt -f}'オプションのどちらか
 一方しか指定してはならない.)

\item[`{\tt -l 長さ}'] 文字でないデータ値のリストをフォーマットする際
 に使われる行の最大長のデフォルト(80)を変更する.

\item[`{\tt -d floatの桁[,doubleの桁]}'] {\tt C\_format}属性を持たない
 変数に対する浮動小数点または倍精度のデータ値を表示するのに使われる有
 効数字の数のデフォルトを指定する.
 浮動小数点データは{\bf floatの桁}の有効桁で表示される.
 {\bf doubleの桁}も指定された場合には, 倍精度値はその分の有効桁で表示
 される.
 変数が{\tt C\_format}属性を持っている場合には, 指定されたすべての浮動
 小数点のデフォルトが上書きされる.
 `{\tt -d}'オプションが指定されなければ, 浮動小数点および倍精度データ
 は, それぞれ有効桁7および15で表示される.
 もし, より低い精度しか必要ないなら, CDLファイルはより小さくできる.
 浮動小数点および倍精度の精度の両方が指定される場合は, この2つの値は
 コマンドに対する単一の引数となるようにコンマ(空白はなし)で区切って与
 えねばならない.

\item[`{\tt -n 名前}'] CDLでは, `{\tt ncgen -b}'でデフォルトのnetCDFファ
 イル名を生成する際に使うために, netCDFデータセットの名前が必要である.
 デフォルトでは, {\tt ncdump}は入力netCDFファイルの名前の最後の要素
 より任意の拡張子を取り除いたものからこの名前を構成する.
 異なる名前を指定するためには`{\tt -n}'オプションを使う.
 `{\tt ncgen -b}'で使われる出力ファイル名を指定することはできるが,
 {\tt ncdump}を使って生成されるCDLファイルを編集し, さらに
 `{\tt ncgen -b}'を使ってその編集したCDLファイルから新しいnetCDFファイ
 ルを生成したりする際に, うっかりと貴重なnetCDFファイルを上書きしてし
 まうのを避けるために, {\tt ncdump}を使ってデフォルトの名前を変更して
 おくのが賢明である.
\end{description}


%-----------------------------------------------------------------------
\section*{例}

netCDLファイル`{\tt foo.nc}'内のデータ構造を見る:
\begin{quote}
\begin{verbatim}
ncdump -c foo.nc
\end{verbatim}
\end{quote}

注釈のためにCスタイルのインデックスづけを使って,
netCDLファイル`{\tt foo.nc}'内の構造およびデータのCDL版を
注釈つきで生成する.
\begin{quote}
\begin{verbatim}
ncdump -b c foo.nc &gt; foo.cdl
\end{verbatim}
\end{quote}

netCDLファイル`{\tt foo.nc}'から変数{\tt uwind}および{\tt vwind}のみに
対するデータを出力し, 浮動小数点データを有効数字3桁だけの精度で表示す
る:
\begin{quote}
\begin{verbatim}
ncdump -v uwind,vwind -d 3 foo.nc
\end{verbatim}
\end{quote}

インデックスづけにFORTRANの慣習を使って, 変数{\tt omega}に対するデータ
の完全な注釈つき(1行につき1つのデータ)のリストを生成し,
生成されるCDLファイル中のnetCDFデータセット名を{\tt omega}に変更する.
\begin{quote}
\begin{verbatim}
ncdump -v omega -f fortran -n omega foo.nc &gt; Z.cdl
\end{verbatim}
\end{quote}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{よくある質問への答}
\label{よくある質問への答}

この章では, netCDFについて最もよくある質問のうちのいくつかへの答を書い
ている. netCDFについてのより包括的で最新のFAQ文書は, 
\begin{quote}
`{\tt http://www.unidata.ucar.edu/packages/netcdf/faq.html}'
\end{quote}
に維持されている.

%-----------------------------------------------------------------------
\section*{netCDFとは?}

netCDF(network Common Data Form)は配列指向のデータアクセスのためのイン
ターフェース, およびそのインターフェースの実装を与えるC, FORTRAN, C++
ソフトウェアライブラリの収集物で, これらは無償で配布される.
netCDFソフトウェアはColorado州BoulderにあるUnidata Program Centerの
Glenn Davis, Russ Rew, およびSteve Emmersonによって開発され, 
他のnetCDFユーザからの貢献によって増強された.
netCDFライブラリは配列を表現するための機種独立のフォーマットを定義して
いる.
同時に, このインターフェース, ライブラリおよびフォーマットは, 配列の生
成, アクセス, および共有, をサポートしている.

netCDFデータは:
\begin{itemize}
\item 自己記述的である. netCDFファイルはその中身のデータについての情報
 を含んでいる.
\item ネットワーク透過である. netCDFファイルは, 整数, 文字, および浮動
 小数点数を異なる形式で格納するコンピューターでもアクセスできる形式で表
 現されている.
\item 直接アクセスである. 大きなデータセットの小さな部分集合に効率的に
 アクセスできる; 最初にその前のすべてのデータを読み込んだりすることな
 しに.
\item 追加ができる. 1つの次元に沿ってnetCDFデータセットにデータを追加
 することができる; そのデータをコピーしたり, 構造を再定義したりするこ
 となしに.
 netCDFデータセットの構造は変更できる; この場合, データセットのコピー
 を引き起こしてしまうこともあるが.
\item 共有できる. 1つの書き込みおよび複数の読み込みが同一のnetCDFファ
 イルに同時にアクセスできる.
\end{itemize}

%-----------------------------------------------------------------------
\section*{netCDFソフトウェアパッケージはどのように取得できるか?}

配布されているソースは, 以下のディレクトリからアノニマスFTPで取得でき
る:
\begin{quote}
`{\tt ftp://ftp.unidata.ucar.edu/pub/netcdf/}'
\end{quote}

このディレクトリには, 以下のファイルが含まれている:
\begin{description}
\item[{\tt netcdf.tar.Z}] 一般的な最新版のソースコードのtarファイルを
 圧縮したもの.
\item[{\tt netcdf-beta.tar.Z}] 現在のベータテスト版.
\end{description}
いくつかのプラットフォームのためのバイナリ配布は以下のディレクトリから
取得できる:
\begin{quote}
`{\tt ftp://ftp.unidata.ucar.edu/pub/binary/}'
\end{quote}

perlインターフェースのソースは, 別のパッケージとして以下のディレクトリ
からアノニマスFTPで取得できる:
\begin{quote}
`{\tt ftp://ftp.unidata.ucar.edu/pub/netcdf-perl/}'
\end{quote}

%-----------------------------------------------------------------------
\section*{World Wide Web上でnetCDFの情報にアクセスできるか?}

はい. netCDFユーザーズガイドのハイパーテキスト版およびnetCDFについて
の他の情報, さらにこのFAQ文章の最新版は, 以下から取得できる:
\begin{quote}
`{\tt http://www.unidata.ucar.edu/packages/netcdf}'
\end{quote}

%-----------------------------------------------------------------------
\section*{以前の版から何が変わったか?}

2.4版は, 新しいプラットフォームのサポートおよび以前からサポートされて
いたプラットフォームの最新版を組込み, Cray/UNICOSのための新しい最適化
を与え, 報告されていたバグを修正し, 文章を改良し, さらにインストールを
より簡単にした. より詳細については, 以下を参照:
\begin{quote}
`{\tt http://www.unidata.ucar.edu/packages/netcdf/release-notes.html}'
\end{quote}

%-----------------------------------------------------------------------
\section*{netCDFについての議論および質問のためのメイリングリストは
ありますか?}

はい. このメイリングリスト, およびどうしたら参加/脱退ができるかに
ついての情報については,
\begin{quote}
\begin{verbatim}
majordomo@unidata.ucar.edu
\end{verbatim}
\end{quote}
にサブジェクトなしで本文に以下の行を
書いたメッセージを送られたい:
\begin{quote}
\begin{verbatim}
info netcdfgroup
\end{verbatim}
\end{quote}

%-----------------------------------------------------------------------
\section*{他の誰がnetCDFを使っていますか?}

netCDFメイリングリストは15の国にわたる500程のアドレスを持っている(この
うちのいくつかはより多くのアドレスへのエイリアスである).
多くのグループがnetCDFをいくつかの形式の配列指向データを表現する標準手
法として採用している; この中には, 大気科学, 水理学, 海洋学, 環境モデリ
ング, 地球物理学, クロマトグラフィ, 質量分光学, およびニューロイメージ
ング, が含まれている.

netCDFを使っているプロジェクトおよびグループのいくつかについての記述は,
以下から取得できる:
\begin{quote}
`{\tt http://www.unidata.ucar.edu/packages/netcdf/usage.html}'
\end{quote}

%-----------------------------------------------------------------------
\section*{netCDFファイルの物理的なフォーマットはどのようなものです
か?}

9章[netCDFファイル構造および性能]\pageref{netCDFファイル構造および性能}
ページを参照されたい.
ここでは, netCDFデータの物理的構造を説明しており, その説明は, 異なった
データ構成の性能の含みを明解にするのに十分なレベルである.
ファイルフォーマットの詳細な指定については, 
Appendix B[ファイルフォーマット仕様]\pageref{ファイルフォーマット仕様}
ページを参照されたい.

netCDFデータにアクセスするプログラムは, すべてのアクセスを文書化された
インターフェースを通して実行するべきであり, netCDFデータの物理フォーマッ
トに依存すべきではない.
そうすることにより, たとえ将来, このフォーマットが変更されても, プログ
ラムの変更の必要はなくなる; なぜなら, このような変更の際にはライブラリ
も変更され, 旧版および新版の両方のフォーマットがサポートされるからであ
る.

%-----------------------------------------------------------------------
\section*{netCDFはどこで動作しているか?}

netCDFの現在の版は, 以下のプラットフォーム上でテストされ, うまくいって
いる:
\begin{itemize}
\item AIX-4.1
\item HPUX-9.05
\item IRIX-5.3
\item IRIX64-6.1
\item MSDOS (gcc, f2c, およびGNU makeを使う)
\item OSF1-3.2
\item OpenVMS-6.2
\item OS/2 2.1
\item SUNOS-4.1.4
\item SUNOS-5.5
\item ULTRIX-4.5
\item UNICOS-8
\item Windows NT-3.51
\end{itemize}

%-----------------------------------------------------------------------
\section*{netCDFデータに対して, 他にどんなソフトウェアが使えるか?}

Unidataから配布されている現在のnetCDFで取得可能なユーティリティは,
netCDFファイルを可読なASCII形式に変換する{\tt ncdump}, および
可読なASCII形式からバイナリのnetCDFファイル, またはそのnetCDFファ
イルを生成するCまたはFORTRANプログラム, に戻す{\tt ncgen}である.

多くの商用または無償の解析およびデータ可視化パッケージがnetCDFデータア
クセスに適応している.
これらのパッケージおよび, netCDFデータを処理または表示するために使える
他のソフトウェア, についてのより多くの情報は, 以下から取得できる:
\begin{quote}
`{\tt http://www.unidata.ucar.edu/packages/netcdf/software.html}'
\end{quote}

%-----------------------------------------------------------------------
\section*{配列指向のデータには, 他にどんなフォーマットが使えるか?}

{\bf 科学データフォーマット情報FAQ}が以下から取得できる:
\begin{quote}
`{\tt http://www.cis.ohio-state.edu/hypertext/faq/usenet/sci-data-formats/faq.html}'
\end{quote}
ここでは, 他のアクセスインターフェースおよび, CDFとHDFを含む配列指向デー
タのためのフォーマット, について詳述されている.

%-----------------------------------------------------------------------
\section*{なぜnetCDF呼出しは, エラー標識を返す代わりに単に終了して
しまうのか?}

すべてのnetCDF関数のデフォルトのエラー処理の動作は, エラーがあると終了
してしまうというものであるが, この動作はプログラマがコントロールできる.
エラーの致命度, およびnetCDFライブラリ呼出しで検出されるエラーからのメッ
セージの表示, は独立にコントロールできる.
より多くの情報については, \ref{エラー処理}節[エラー処理]\pageref{エラー
処理}ページを参照.

%-----------------------------------------------------------------------
\section*{バグ報告はどうしたらよいですか?}

もしバグを見つけたら, {\tt support@unidata.ucar.edu}に報告を送って下
さい.
これは, netCDFについての質問または議論のために使われているアドレスでも
ある. 質問または議論を{\tt netcdfgroup}メイリングリスト全体に送ること
は適当ではない.

%-----------------------------------------------------------------------
\section*{過去の問題の報告はどうしたら検索できますか?}

netCDFホームページの一番下に検索フォームがあり, Unidataサポートスタッ
フによって提供されているサポートの質問および回答について, 完全なテキスト
検索ができるようになっている.

%-----------------------------------------------------------------------
\section*{C++インターフェースはCインターフェースとどう違いますか?}

C++のインターフェースはCインターフェースのすべての機能を提供しており
({\tt ncvarputg}および{\tt ncvargetg}における部分的にサンプルされた, 
またはマップされた配列アクセスを除く), {\tt void*}ポインタの使用をやめ
て型の安全性を改善し, Cインターフェースよりもいくらか簡単に使えるよう
になっている.
C++インターフェースを使うと, netCDF要素にIDは不要になり, 属性を生成す
る際に型の指定が不要になり, さらに次元をより直接的に扱うことができる.
しかし, C++インターフェースはCインターフェースよりも成熟しておらず, か
つそれほど広く使われていない. さらに, C++インターフェースの文章は, 
netCDFデータモデルおよびCインターフェースに慣れていることを前提として
おり, あまり広範なものではない. 

%-----------------------------------------------------------------------
\section*{FORTRANインターフェースはCインターフェースとどう違いますか?}

FORTRANインターフェースはCインターフェースのすべての機能を提供してい
る. FORTRANインターフェースは, 配列のインデックス, 添字の順番, および
文字列に対するFORTRANの慣習を使っている.
異なる言語インターフェースから書かれたデータについて, ディスク上のフォー
マットの違いはない.
C言語で書かれたデータはFORTRANプログラムから読むことができ, 逆も可能で
ある.

%-----------------------------------------------------------------------
\section*{PerlインターフェースはCインターフェースとどう違いますか?}

PerlインターフェースはCインターフェースのすべての機能を提供している. 
Perlインターフェースは, 配列および文字列に対するPerlの慣習を使っている.
異なる言語インターフェースから書かれたデータについて, ディスク上のフォー
マットの違いはない.
C言語で書かれたデータはPerlプログラムから読むことができ, 逆も可能であ
る.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\appendix
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{単位}
\label{単位}

Unidata Program Centerは, フォーマットされたおよびバイナリ形の単位
間の変換を行い, かつバイナリ形式における単位の代数演算を行う
単位ライブラリを開発している. 
単位ライブラリは自己完結的であり, それとnetCDFライブラリとの間には依存
関係はないが, それでも, このライブラリは一般的なnetCDFプログラムを書く
際に有用であるので取得することを勧める.
このライブラリおよび関連文書は,
`{\tt http://www.unidata.ucar.edu/packages/udunits/}'
から取得できる.

以下は, Unidata単位ライブラリの関数{\tt utScan()}で解釈できる単位の文
字列の例である:
\begin{quote}
\baselineskip=\vs
\begin{verbatim}
10 kilogram.meters/seconds2
10 kg-m/sec2
10 kg m/s^2
10 kilogram meter second-2
(PI radian)2
degF
100rpm
geopotential meters
33 feet water
milliseconds since 1992-12-31 12:34:0.1 -7:00
\end{verbatim}
\end{quote}

単位は, 単位名の任意の整数羃に任意の定数を掛けたものとして指定される.
割り算はスラッシュ`{\tt /}'で表される.
乗算は, 空白, ピリオド`{\tt .}', またはハイフン`{\tt -}'で表される.
羃乗は, 整数の添字, または羃乗演算子`\verb-^-'
および`{\tt **}'によって表される.
グループ分けおよび明瞭化のために括弧を用いてもよい.
最後の例のタイムスタンプは特別な場合として扱われる.

任意のガリレオ変換(すなわち, $y=ax+b$)が許されている.
特に, 温度の変換は正しく扱える.
以下の指定:
\begin{quote}
\begin{verbatim}
degF @ 32
\end{verbatim}
\end{quote}
は, 原点を華氏32度分シフト(すなわち, 摂氏0度)した華氏目盛を指す.
従って, 摂氏目盛は, 以下の単位に等しい:
\begin{quote}
\begin{verbatim}
1.8 degF @ 32
\end{verbatim}
\end{quote}

原点移動演算は乗算より優先されることに注意.
演算の優先順位は(下位から上位へ),
除算, 乗算, 原点移動, 羃乗, の順である.

{\tt utScan()}はすべてのSI接頭語(例えば, ``mega''および``milli'')およ
びそのそれらの短縮形(例えば, ``M''および``m'')

関数{\tt utPrint()}は常に, 単位指定を一意にコード化する.
間違いを減らすために,, このコード化スタイルをデフォルトとして使うこと
を勧める.
基本単位は空白で区切られ, 任意の指数は対応する単位に直接付加される.
上の例は以下のようにコード化される:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
10 kilogram meter second-2
9.8696044 radian2
0.555556 kelvin @ 255.372
10.471976 radian second-1
9.80665 meter2 second-2
98636.5 kilogram meter-1 second-2
0.001 seconds since 1992-12-31 19:34:0.1000 UTC
\end{verbatim}
\end{quote}

(華氏単位は原点255.372kelvinからの分数の偏差としてコード化されており,
最後の例における時刻は, UTCに変換されていることに注意.)

単位ライブラリのためのデータベースは, 単位定義を含むフォーマットされた
ファイルであり, このパッケージを初期化するために使われる.
妥当な名前と記号を見付けるために, まずここが参照される.

この単位ファイルのフォーマットは内部に説明があり, 必要ならば, このファ
イルはユーザが修正できる.
特に, 付加的な単位および定数は簡単に追加できる(既存の単位または定数の
異なる綴りを含む).

{\tt utScan()}は大文字小文字を区別する.
もしこれで支障があるなら, 単位ファイルに適当な項目を追加してもよい.

デフォルトの単位ファイルにおける単位短縮形は, 直感に反することもある.
特に, 以下に注意されたい:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
For       Use               Not     Which Instead Means

Celsius   `Celsius'         `C'     coulomb
gram      `gram'            `g'     &lt;standard free fall&gt;
gallon    `gallon'          `gal'   &lt;acceleration&gt;
radian    `radian'          `rad'   &lt;absorbed dose&gt;
Newton    `newton' or `N'   `nt'    nit (unit of photometry)
\end{verbatim}
\end{quote}

この単位ライブラリについてのさらなる情報については, 配布版に付属のマニュ
アルページを参照されたい.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{ファイルフォーマット仕様}
\label{ファイルフォーマット仕様}

このappendixではnetCDFファイルフォーマットバージョン1の仕様を述べる.
このフォーマットは, 少なくともnetCDFライブラリバージョン3.0までは使わ
れる予定である.

このフォーマットは, BNF文法表記で正式に表現される.
この文法では, オプションの要素は括弧(`{\tt [}'と`{\tt ]}')で囲まれて
いる.
`{\tt //}'以下は注釈である.
端末語でないものは小文字で, 端末語は大文字で表記されている.
0またはそれ以上の項目を並べる場合は, 
`{\tt [entity ...]}'と表記される.

%-----------------------------------------------------------------------
\section*{ファイルフォーマット仕様}

\begin{quote}\baselineskip=\vs
\begin{verbatim}
netcdf_file := header  data

header  := magic  numrecs  dim_array  gatt_array  var_array

magic   := 'C'  'D'  'F'  VERSION_BYTE

VERSION_BYTE := '\001'    // ファイルフォーマットのバージョン数

numrecs    := NON_NEG

dim_array  :=  ABSENT | NC_DIMENSION  nelems  [dim ...]

gatt_array :=  att_array  // グローバル属性

att_array  :=  ABSENT | NC_ATTRIBUTE  nelems  [attr ...]

var_array  :=  ABSENT | NC_VARIABLE   nelems  [var ...]

ABSENT  := ZERO  ZERO     // 配列が無いことを意味する(nelems == 0に同じ).

nelems  := NON_NEG        // 以下の並ぶ要素の数

dim     := name  dim_size

name    := string

dim_size := NON_NEG       // もし0なら, これは記録次元である. 
                          // 記録次元は1つまでである.

attr    := name  nc_type  nelems  [values]

nc_type := NC_BYTE | NC_CHAR | NC_SHORT | NC_LONG | NC_FLOAT | NC_DOUBLE

var     := name  nelems  [dimid ...]  vatt_array  nc_type  vsize  begin
                          // nelemsは変数のランク(次元数)である.
                          // スカラーなら0, ベクトルなら1, 行列なら2, ...

vatt_array :=  att_array  // 変数を特定した属性

dimid   := NON_NEG        // 変数形状のための次元ID(dim_arrayへのインデックス).
                          // もし最初の次元(のみ)が記録次元ならば, 
                          // これは記録変数と呼ばれる.

vsize    := NON_NEG       // 変数サイズ. 記録変数でない場合は, その変数データ
                          // に割り当てられるバイト単位のスペースの量である.
                          // この数は, 次元サイズの積に型のサイズを掛けたものを
                          // 4バイトの境界に合せて詰め込んだものである.
                          // もし記録変数なら, これは各記録あたりのスペースの量
                          // である. netCDF"記録サイズ"は記録変数のvsizeの和と
                          // して計算される.

begin   := NON_NEG        // 変数のスタート位置. この変数データの先頭の
                          // ファイル中におけるバイト単位のオフセット.

data    := non_recs  recs

non_recs := [values ...]  // 記録変数でない最初の変数, 2番目の変数, ... のデータ

recs    := [rec ...]      // 最初の記録, 2番目の記録, ...

rec     := [values ...]   // 記録nに対する最初の記録変数, 記録nに対する2番目の
                          // 記録変数, ... のデータ.
                          // 特別の場合については以下の注意を参照.

values  := [bytes] | [chars] | [shorts] | [ints] | [floats] | [doubles]

string  := nelems  [chars]

bytes   := [BYTE ...]  padding

chars   := [CHAR ...]  padding

shorts  := [SHORT ...]  padding

ints    := [INT ...]

floats  := [FLOAT ...]

doubles := [DOUBLE ...]

padding := &lt;次の4バイト境界までの0, 1, 2, または3バイト&gt;
                          // ヘッダでは, 詰め込むのは0のバイトである.
                          // データでは, 詰め込むのは変数のフィル値である.

NON_NEG := &lt;非負の値を持つ整数&gt;

ZERO    := &lt;0の値を持つ整数&gt;

BYTE    := &lt;8ビットbyte&gt;

CHAR    := &lt;8ビットACSII/ISOでコード化されたcharacter&gt;

SHORT   := &lt;16ビット符号つき, ビッグエンディアン, 2の補数表現&gt;

INT     := &lt;32ビット符号つき, ビッグエンディアン, 2の補数表現&gt;

FLOAT   := &lt;32ビットIEEE単精度浮動小数点, ビッグエンディアン&gt;

DOUBLE  := &lt;64ビットIEEE単精度浮動小数点, ビッグエンディアン&gt;

// タグは32ビット整数である.
NC_BYTE      := 1         // データは8ビットの符号つき整数の配列
NC_CHAR      := 2         // データは文字の配列, すなわちテキスト
NC_SHORT     := 3         // データは16ビットの符号つき整数の配列
NC_LONG      := 4         // データは32ビットの符号つき整数の配列
NC_FLOAT     := 5         // データはIEEE符号つきの単精度浮動小数点の配列
NC_DOUBLE    := 6         // データはIEEE符号つきの倍精度浮動小数点の配列
NC_DIMENSION := 10
NC_VARIABLE  := 11
NC_ATTRIBUTE := 12
\end{verbatim}
\end{quote}

%-----------------------------------------------------------------------
\section*{ファイルオフセットの計算}

指定されたデータ値のオフセット(ファイル中の位置)を計算するために,
指定された変数に対する適当な型のデータ値1つの外部サイズ(バイト単位)を
{\it external\_sizeof}とする.
各{\it nc\_type}に対する{\it external\_sizeof}は以下のようである:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
NC_BYTE         1
NC_CHAR         1
NC_SHORT        2
NC_LONG         4
NC_FLOAT        4
NC_DOUBLE       8
\end{verbatim}
\end{quote}

open() (または endef() )においては, まえもって{\it var\_array}で示された
変数の並びが調べられ, {\it recsize}を計算するために, ``記録''変数の
{\it vsize}を合計する.

変数の次元サイズの積を右から左にとっていき, 記録変数に対しては最も左の
(記録)次元はとばして, その結果を各変数について{\it product}配列に格納する.
例えば:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
非記録変数:
        dimension sizes:        [  5  3  2 7]
        product:                [210 42 14 7]

記録変数:
        dimension sizes:        [0  2  9 4]
        product:                [0 72 36 4]
\end{verbatim}
\end{quote}

この段階において, 最も左の積を次の4の倍数に丸めたものが変数サイズ,
すなわち, 上の文法における{\it vsize}である.
例えば, 上記の非記録変数に対しては, {\it vsize}フィールドの値は212
(210を4の倍数に丸めたもの)である.
記録変数に対しては, {\it vsize}の値はちょうど72である. なぜなら, これ
はすでに4の倍数であるからである.

求めるデータ値の座標の配列を{\it coord}とし, 求める結果を{\it offset}
とする.
このとき, {\it offset}は単に, 求める変数の最初のデータ値のオフセット(その
変数の{\it begin}フィールド)に, {\it coord}および{\it product}ベクトル
の内積を変数の各データのサイズ(バイト単位)倍したものを加えたものになる.
最後に, 変数が記録変数である場合には, 記録数(`{\tt coord[0]}')と記録サ
イズ({\it recsize})の積が加えられ, それが最終的な{\it offset}値になる.

{\it offset}を計算するC的なコードは以下のようになる:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
for (innerProduct = i = 0; i &lt; var.rank; i++)
        innerProduct += product[i] * coord[i]
offset = var.begin;
offset += external_sizeof * innerProduct
if(IS_RECVAR(var))
        offset += coord[0] * recsize;
\end{verbatim}
\end{quote}
そこで, (外部表現の)データ値を取得するには,
\begin{quote}\baselineskip=\vs
\begin{verbatim}
lseek(fd, offset, SEEK_SET);
read(fd, buf, external_sizeof);
\end{verbatim}
\end{quote}

{\bf 特別な場合}: 記録変数が1つしかない場合には, 各記録が4バイト境界に
合っていなければならないという制約が無いので, この場合は記録の詰め込み
は行われない.


%-----------------------------------------------------------------------
\section*{例}

上の文法を使うと, 次元, 変数, 属性を持たず, 従ってデータも持たない妥当
なnetCDFファイルで最も小さいものが導かれる.
この空のnetCDFファイルのCDL表現は以下のようになる.
\begin{quote}\baselineskip=\vs
\begin{verbatim}
netcdf empty { }
\end{verbatim}
\end{quote}

この空netCDFファイルは32バイトの大きさがあり, これは
`{\tt ncgen -b empty.cdl}'を使って, CDL表現から空netCDFファイルを生成
して確認することができる.
この空netCDFファイルは, 4バイトの``マジックナンバー''から始まり, これは
それがnetCDFバージョン1ファイルと認識するためのものである.
このマジックナンバーは: `{\tt C}',`{\tt D}','{\tt F}',`\verb-\001-'
である.
その次には, 32ビットの0が7個の続く. これは以下のことを表している:
記録数が0, 次元の並びが空, グローバル属性が空, および変数の並びが空.

以下は, Unixコマンド{\tt od -xcs empty.nc}
を使って, ビッグエンディアンのマシン上において生成されたファイルの
(編集された)ダンプを表示したものである.

ファイルは, 16バイトの各部分が4行で表示されている.
第1行はバイトを16進数表示している.
第2行はバイトを文字表示している.
第3行は2バイトごとをグループ化して, それを符号つき16ビット整数として表
示している.
第4行(手作業で追加されたものである)は,
netCDF要素および値としてバイトを解釈して表示したものである.
\begin{quote}\baselineskip=\vs
\begin{verbatim}
   4344    4601    0000    0000    0000    0000    0000    0000
  C   D   F 001  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
  17220   17921   00000   00000   00000   00000   00000   00000
[magic number ] [  0 records  ] [  0 dimensions   (ABSENT)    ]

   0000    0000    0000    0000    0000    0000    0000    0000
 \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
  00000   00000   00000   00000   00000   00000   00000   00000
[  0 global atts  (ABSENT)    ] [  0 variables    (ABSENT)    ]
\end{verbatim}
\end{quote}

もう少し意味のある例として, 以下のCDLを考える:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
netcdf tiny {
dimensions:
        dim = 5;
variables:
        short vx(dim);
data:
        vx = 3, 1, 4, 1, 5 ;
}
\end{verbatim}
\end{quote}
これは92バイトのnetCDFファイルに対応する.
以下はこのファイルの編集されたダンプである:
\begin{quote}\baselineskip=\vs
\begin{verbatim}
   4344    4601    0000    0000    0000    000a    0000    0001
  C   D   F 001  \0  \0  \0  \0  \0  \0  \0  \n  \0  \0  \0 001
  17220   17921   00000   00000   00000   00010   00000   00001
[magic number ] [  0 records  ] [NC_DIMENSION ] [ 1 dimension ]

   0000    0003    6469    6d00    0000    0005    0000    0000
 \0  \0  \0 003   d   i   m  \0  \0  \0  \0 005  \0  \0  \0  \0
  00000   00003   25705   27904   00000   00005   00000   00000
[  3 char name = "dim"        ] [ size = 5    ] [ 0 global atts

   0000    0000    0000    000b    0000    0001    0000    0002
 \0  \0  \0  \0  \0  \0  \0 013  \0  \0  \0 001  \0  \0  \0 002
  00000   00000   00000   00011   00000   00001   00000   00002
 (ABSENT)     ] [NC_VARIABLE  ] [ 1 variable  ] [ 2 char name =

   7678    0000    0000    0001    0000    0000    0000    0000
  v   x  \0  \0  \0  \0  \0 001  \0  \0  \0  \0  \0  \0  \0  \0
  30328   00000   00000   00001   00000   00000   00000   00000
 "vx"         ] [1 dimension  ] [ with ID 0   ] [ 0 attributes

   0000    0000    0000    0003    0000    000c    0000    0050
 \0  \0  \0  \0  \0  \0  \0 003  \0  \0  \0  \f  \0  \0  \0   P
  00000   00000   00000   00003   00000   00012   00000   00080
 (ABSENT)     ] [type NC_SHORT] [size 12 bytes] [offset:    80]

   0003    0001    0004    0001    0005    8001
 \0 003  \0 001  \0 004  \0 001  \0 005 200 001
  00003   00001   00004   00001   00005  -32767
[    3] [    1] [    4] [    1] [    5] [fill ]
\end{verbatim}
\end{quote}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{FORTRANインターフェースのまとめ}
\label{FORTRANインターフェースのまとめ}

入力引数を大文字で, 出力引数を小文字で表記している.
すべての引数のFORTRAN型のリスト(引数のファベット順)は, 
サブルーチンおよび関数の宣言の下に付けてある.
\begin{quote}\baselineskip=\vs
\begin{verbatim}
INTEGER FUNCTION NCCRE (FILENAME,CLOBMODE, rcode)
INTEGER FUNCTION NCOPN (FILENAME,RWMODE, rcode)
SUBROUTINE NCREDF (NCID, rcode)
SUBROUTINE NCENDF (NCID, rcode)
SUBROUTINE NCCLOS (NCID, rcode)
SUBROUTINE NCINQ (NCID, ndims,nvars,natts,recdim,rcode)
SUBROUTINE NCSNC (NCID, rcode)
SUBROUTINE NCABOR (NCID, rcode)
INTEGER FUNCTION NCDDEF (NCID,DIMNAME,SIZE, rcode)
INTEGER FUNCTION NCDID (NCID,DIMNAME, rcode)
SUBROUTINE NCDINQ (NCID,DIMID, dimname,size,rcode)
SUBROUTINE NCDREN (NCID,DIMID,DIMNAME, rcode)
INTEGER FUNCTION NCVDEF (NCID,VARNAME,DATATYPE,NVDIMS,VDIMS, rcode)
INTEGER FUNCTION NCVID (NCID,VARNAME, rcode)
SUBROUTINE NCVINQ (NCID,VARID, varname,datatype,nvdims,vdims,nvatts,rcode)
SUBROUTINE NCVPT1 (NCID,VARID,INDICES,VALUE, rcode)
SUBROUTINE NCVP1C (NCID,VARID,INDICES, CHVAL, rcode)
SUBROUTINE NCVGT1 (NCID,VARID,INDICES, value, rcode)
SUBROUTINE NCVG1C (NCID,VARID,INDICES, chval, rcode)
SUBROUTINE NCVPT (NCID,VARID,START,COUNTS,VALUE, rcode)
SUBROUTINE NCVPTC (NCID,VARID,START,COUNTS,STRING,LENSTR, rcode)
SUBROUTINE NCVPTG (NCID,VARID,START,COUNTS,STRIDE,IMAP,VALUE, rcode)
SUBROUTINE NCVPGC (NCID,VARID,START,COUNTS,STRIDE,IMAP,STRING,rcode)
SUBROUTINE NCVGT (NCID,VARID,START,COUNTS, value,rcode)
SUBROUTINE NCVGTC (NCID,VARID,START,COUNTS, string,LENSTR,rcode)
SUBROUTINE NCVGTG (NCID,VARID,START,COUNTS,STRIDE,IMAP,value,rcode)
SUBROUTINE NCVGGC (NCID,VARID,START,COUNTS,STRIDE,IMAP,string,rcode)
SUBROUTINE NCVREN (NCID,VARID,VARNAME, rcode)
SUBROUTINE NCAPT (NCID,VARID,ATTNAME,DATATYPE,ATTLEN,VALUE, rcode)
SUBROUTINE NCAPTC (NCID,VARID,ATTNAME,DATATYPE,LENSTR,STRING, rcode)
SUBROUTINE NCAINQ (NCID,VARID,ATTNAME, datatype,attlen,rcode)
SUBROUTINE NCAGT (NCID,VARID,ATTNAME, value,rcode)
SUBROUTINE NCAGTC (NCID,VARID,ATTNAME, string,LENSTR,rcode)
SUBROUTINE NCACPY (INNCID,INVARID,ATTNAME,OUTNCID,OUTVARID, rcode)
SUBROUTINE NCANAM (NCID,VARID,ATTNUM, attname,rcode)
SUBROUTINE NCAREN (NCID,VARID,ATTNAME,NEWNAME, rcode)
SUBROUTINE NCADEL (NCID,VARID,ATTNAME, rcode)
INTEGER FUNCTION NCTLEN (DATATYPE, rcode)
SUBROUTINE NCPOPT (NCOPTS)
SUBROUTINE NCGOPT (ncopts)
INTEGER FUNCTION NCSFIL (NCID,FILLMODE, rcode)
\end{verbatim}
\end{quote}

\begin{quote}\baselineskip=\vs
\begin{verbatim}
INTEGER ATTLEN          ! 属性ベクトル中の要素数
CHARACTER*(*) ATTNAME   ! 属性名
INTEGER ATTNUM          ! 属性数
CHARACTER CHVAL         ! 変数または属性の文字値
INTEGER CLOBMODE        ! NCCLOBまたはNCNOCLOB
INTEGER COUNTS(NVDIMS)  ! 値のブロックの縁の長さ
INTEGER DATATYPE        ! 型: NCBYTE, ..., または NCDOUBLE
INTEGER DIMID           ! 次元ID
CHARACTER*(*) DIMNAME   ! 次元名
CHARACTER*(*) FILENAME  ! netCDFファイル名
INTEGER FILLMODE        ! フィルモードの設定: NCNOFILLまたはNCFILL
INTEGER IMAP(NVDIMS)    ! インデックスマッピングベクトル
INTEGER INDICES(NDIMS)  ! 変数の単一要素の座標
INTEGER INNCID          ! 入力netCDF ID
INTEGER INVARID         ! 入力変数 ID
INTEGER LENSTR          ! 文字配列の長さ
INTEGER NATTS           ! グローバル属性の数
INTEGER NCID            ! NCCREまたはNCOPNで返されるnetCDF ID
INTEGER NCOPTS          ! エラー処理オプションのフラグ
INTEGER NDIMS           ! 次元数
CHARACTER*(*) NEWNAME   ! 新規の属性名
INTEGER NVARS           ! 変数の数
INTEGER NVATTS          ! 変数に割り当てられている属性の数
INTEGER NVDIMS          ! 変数中の次元数
INTEGER OUTNCID         ! 出力netCDF ID
INTEGER OUTVARID        ! 出力変数ID
INTEGER RCODE           ! 返されるエラーコード. エラーがなければ0.
INTEGER RECDIM          ! 無制限次元のID
INTEGER RWMODE          ! NCWRITEまたはNCNOWRIT
INTEGER SIZE            ! 次元サイズ
INTEGER START(NVDIMS)   ! アクセスされる最初の値のインデックス
INTEGER STRIDE(NVDIMS)  ! netCDF変数次元のストライド
CHARACTER*(*) STRING    ! 変数または属性の文字配列値
DOUBLE VALUE            ! 変数または属性の倍精度値
REAL VALUE              ! 変数または属性の実数値
INTEGER VALUE           ! 変数または属性の整数値
INTEGER VARID           ! NCVDEFまたはNCVIDから得られる変数ID, またはNCGLOBAL
CHARACTER*(*) VARNAME   ! 変数名
INTEGER VDIMS(NDIMS)    ! 変数の次元ID. 変数の形を与える.
\end{verbatim}
\end{quote}

\end{document}</pre></body></html>