netCDF

netCDF

NetCDF(network Common Data Form)網路通用數據格式是由美國大學大氣研究協會(University Corporation for Atmospheric Research,UCAR)的Unidata項目科學家針對科學數據的特點開發的,是一種面向數組型並適於網路共享的數據的描述和編碼標準。目前,NetCDF廣泛應用於大氣科學、水文、海洋學、環境模擬、地球物理等諸多領域。用戶可以藉助多種方式方便地管理和操作 NetCDF 數據集。

簡單介紹


對程序員來說,它和zip、jpeg、bmp文件格式類似,都是一種文件格式的標準。netcdf文件開始的目的是用於存儲氣象科學中的數據,現在已經成為許多數據採集軟體的生成文件的格式。利用NetCDF可以對網格數據進行高效地存儲、管理、獲取和分發等操作。由於其靈活性,能夠傳輸海量的面向陣列(array-oriented)數據,目前廣泛應用於大氣科學、水文、海洋學、環境模擬、地球物理等諸多領域,例如,NCEP(美國國家環境預報中心)發布的再分析資料,NOAA的CDC(氣候數據中心)發布的海洋與大氣綜合數據集(COADS)均採用NetCDF作為標準。
從數學上來說,netcdf存儲的數據就是一個多自變數的單值函數。用公式來說就是f(x,y,z,...)=value,函數的自變數x,y,z等在netcdf中叫做維(dimension)或坐標軸(axis),函數值value在netcdf中叫做變數(Variables).而自變數和函數值在物理學上的一些性質,比如計量單位(量綱)、物理學名稱等等在netcdf中就叫屬性(Attributes) .
NetCDF軟體實現形式是一個免費的NetCDF 軟體包 ,內含可訪問 NetCDF 數據的工具程序和多種語言的介面函數庫。

數據結構


NetCDF數據集(文件名後綴為.nc) 的格式不是固定的,它是使用者根據需求 自己定義的。一個NetCDF數據集包含維(dimensions)、變數(variables)和屬性(attributes)三種描述類型,每種類型都會被分配一個名字和一個ID,這些類型共同描述了一個數據集,NetCDF庫可以同時訪問多個數據集,用ID來識別不同數據集。變數存儲實際數據,維給出了變數維度信息,屬性則給出了變數或數據集本身的輔助信息屬性,又可以分為適用於整個文件的全局屬性和適用於特定變數的局部屬性,全局屬性則描述了數據集的基本屬性以及數據集的來源。一個NetCDF文件的結構包括以下對象:
NetCDF name{
Dimensions:… //定義維數
Variables:… //定義變數
Attributes:… //屬性
Data:…//數據
}

主要特點


1)自描述性:它是一種自描述的二進位數據格式,包含自身的描述信息;
2)易用性:它是網路透明的,可以使用多種方式管理和操作這些數據;
3)高可用性:可以高效訪問該數據,在讀取大數據集中的子數據集時不用按順序讀取,可以直接讀取需要訪問的數據;
4)可追加性:對於新數據,可沿某一維進行追加,不用複製數據集和重新定義數據結構;
5)平台無關性:NetCDF數據集支持在異構的網路平台間進行數據傳輸和數據共享。可以由多種軟體讀取並使用多種語言編寫,其中包括C語言,C++,Fortran,IDL,Python,Perl和Java語言等。

文件內容


1、變數(Variables)變數對應著真實的物理數據。比如我們家裡的電錶,每個時刻顯示的讀數表示用戶的到該時刻的耗電量。這個讀數值就可以用netcdf里的變數來表示。它是一個以時間為自變數(或者說自變數個數為一維)的單值函數。再比如在氣象學中要作出一個氣壓圖,就是“東經xx度,北緯yy度的點的大氣壓值為多少帕”,這是一個二維單值函數,兩維分別是經度和緯度。函數值為大氣壓。
從上面的例子可以看出,netcdf中的變數就是一個N維數組,數組的維數就是實際問題中的自變數個數,數組的值就是觀測得到的物理值。變數(數組值)在netcdf中的存儲類型有六種,ascii字元(char),位元組(byte),短整型(short),整型(int),浮點(float),雙精度(double).顯然這些類型和c中的類型一致,搞C的朋友應該很快就能明白。
2、維(dimension)一個維對應著函數中的某個自變數,或者說函數圖象中的一個坐標軸,在線性代數中就是一個N維向量的一個分量(這也是維這個名稱的由來)。在netcdf中,一個維具有一個名字和範圍(或者說長度,也就是數學上所說的定義域,可以是離散的點集合或者連續的區間)。在netcdf中,維的長度基本都是有限的,最多只能有一個具有無限長度的維。
3、屬性(Attribute)屬性對變數值和維的具體物理含義的註釋或者說解釋。因為變數和維在netcdf中都只是無量綱的數字,要想讓人們明白這些數字的具體含義,就得靠屬性這個對象了。
在netcdf中,屬性由一個屬性名和一個屬性值(一般為字元串)組成。比如,在某個cdl文件(cdl文件的具體格式在下一節中講述)中有這樣的代碼段temperature:units="celsius"
前面的temperature是一個已經定義好的變數(Variable),即溫度,冒號後面的units就是屬性名,表示物理單位,=後面的就是units這個屬性的值,為“celsius”,即攝氏度,整個一行代碼的意思就是溫度這個物理量的單位為celsius,很好理解。

介面函數庫


NetCDF 介面函數庫是提供給用戶以編程方式訪問 NetCDF 數據的工具。NetCDF 數據的介面函數庫有支持諸如 C、C+ +和Fortran等語言的不同版本。對於Fortran 語言 ,Unidata 又提供分別支持 F77 和 F90標準的介面函數庫 ,後者是在前者基礎上的進一步封裝 ,其包含的庫函數更少 ,更便於編程 ;目前主流的 Fortran 編譯器都支持 F90 標準。因此 ,本文只介紹支持 Fortran 90 版本的介面函數庫。
Fortran 90 版本的介面函數庫只包含 26 個庫函數 ,對應於 NetCDF 文件結構 ,可分為以下 4 類 :
①文件處理函數 ,實現以寫或創建的形式打開文件 ,關閉文件等。
②變數處理函數 ,實現變數的定義或檢索 ,包括定義或檢索變數名、變數 ID。
③維數處理函數 ,實現維數的定義或檢索 ,包括定義或檢索維數名稱、維數 ID。
④屬性處理函數 ,實現屬性的定義或檢索。

文件的讀寫


1、在命令行下讀寫netcdf文件
⑴建立一個simple_xy.cdl文件,內容就是上一節“CDL結構”中的第一個例子。
⑵用ncgen.exe工具(下載地址見前面的第二節)建立netcdf文件:①將ncgen所在目錄加到系統path變數中或者直接將ncgen.exe拷到simple_xy.cdl所在目錄下;②執行ncgen-osimple_xy.ncsimple_xy.cdl生成netcdf格式文件simple_xy.nc ;
⑶生成的simple_xy.nc是一個二進位文件,要想從這個文件中還原出數據信息,就要用ncdump工具:①將ncdump所在目錄加到系統path變數中或者直接將ncdump.exe拷到simple_xy.nc所在目錄下;②在命令行下執行ncdumpsimple_xy.nc,這時屏幕的輸出和simple_xy.cdl內容完全一樣。說明文件讀寫操作都是正確的。
2、編程讀寫netcdf文件
前面我們知道如何手工去建立和讀取netddf文件,下面我們來看看如何在程序中用代碼實現netcdf文件的建立和分析。我的編程環境為win2000vc6.0並安裝了vcsp6補丁包。
⑴將netcdf的源代碼解壓。我們將用到裡面的libsrc\netcdf.h頭文件
⑵在vc6中建立一個空的win32控制台項目。名字為SimpleXyWrite,這個項目用來建立netcdf文件
⑶把如下文件拷貝到項目目錄中:①netcdf源代碼中的libsrc\netcdf.h頭文件;②netcdf源代碼中的examples\C\simple_xy_wr.c文件,並改名為simple_xy_wr.cpp;③netcdf預編譯包中的netcdf.dll文件和netcdf.lib文件
⑷把netcdf.h文件和simple_xy_wr.cpp加入到項目的文件列表中(具體菜單操作project->addtoproject->files)
⑸把netcdf.lib加入到項目的lib列表中(具體菜單操作project->addtoproject->settings->Link->object/librarymodules)
⑹編譯並運行這個項目,會在項目目錄下生成一個simple_xy.nc文件,其內容和我們手工生成的文件內容完全一樣。
simple_xy_wr.c文件是建立netcdf文件的c代碼,而examples\C\simple_xy_rd.c文件則是分析netcdf文件的代碼,讀者可以用和剛才類似的步驟在vc6中編譯這個文件。運行時把把剛才生成的simple_xy.nc拷貝到項目的目錄下,如果文件格式沒錯誤,會提示。
3、用ncgen命令自動生成c代碼給定了simple_xy.cdl文件后,可以ncgen-csimple_xy.cdl命令直接在屏幕上輸出c代碼。不過,這個辦法只限於cdl的數據比較簡單時才可以採用。