Netcdf
NetCDF簡介 NetCDF(network Common Data Format),即網絡通用數據格式。最早是由美國國家科學委員會資助之計劃--Unidata --所發展,其用意是在Unidata計劃中不同的應用項目下,提供一種可以通用的數據存取方式,數據的形狀包括單點的觀測值、時間序列、規則排列的網格、以及人造衛星或雷達之影像檔案。 NetCDF 可簡單的視為一種存取接口,任何使用?NetCDF 存取格式的檔案就可稱為 NetCDF 檔案;至于 NetCDF 這套軟件的功能,在于提供C、Fortran、C++、Perl、或其它語言I/O的鏈接庫,以讓程序發展者可以讀寫數據文件,其本身具有說明的能力、并且可以跨越平臺和機器的限制。每一個NetCDF檔案可以含括多維度的、具有名稱的變量,包括長短的整數、單倍與雙倍精度的實數、字符等,且每一個變量都有其自我介紹的數據,包括量度的單位、全名及意義等文字說明,在此摘要性的檔頭之后,才是真正的數據本身。 NetCDF接口是一種多維的數據分布系統,由這個接口所產生的檔案,具有多維的數據格式,當你需要其中的某一筆數據時,程序將不會從第一筆數據讀到你所需要的數據處,而是由 NetCDF 軟件直接存取那一個數據。如此一來將會大量的降低模式運算時數據存取的時間。但也就是因為這樣, NetCDF 所需要的空間是很大的,因為他多了很多的自解釋的申明。
?
?NetCDF文件結構
???
對NETCDF文件的操作主要有讀和寫兩個方面,在了解這兩個方面內容之前,首先需要了解NETCDF文件的結構,NETCDF文件主要是Dimensions, Variables, Attributes, Data 四個部分組成的:
Dimensions主要是多維資料的結構,如經度、緯度、時間等
Variables各種變量,像溫度等 Attributes一些輔助記憶的說明,如變量的單位等
Data主要資料部分
?
下面是NETCDF文件基本結構圖(箭頭指向為可操作的對象)
NETCDF文件基本結構圖根據NETCDF文件的這種特殊的結構,所使用的NcFile類中包含了NcDim, NcVar, NcAtt幾個類的對象作為成員,分別對應了上面的Dimensions, Variables, Attributes部分。
NetCDF文件的讀寫 ?
1.1?????建工程文件用
vc6建立一個工程,使用動態鏈接庫netcdf,然后把文件netcdfcpp.h netcdfcpp.cpp ,ncvalues.h ncvalues.cpp,ncconfig.h包含到工程中。
1.2?????NETCDF文件的讀取
首先,定義一個NcFile類的對象,用NcFile類的構造函數直接對其初始化 NcFile(const char * path, FileMode = ReadOnly , … … );
path為文件的存儲路徑,FileMode為文件的打開方式,除了ReadOnly還有Write, New, Replace 等方式我們只是讀文件可以選擇ReadOnly,其他方式后面會介紹到,其他參數可以使用默認值,例如: NcFile nc("G://File.nc", NcFile::ReadOnly);
使用nc.is_valid()來判斷文件打開是否成功,以便進行下一步對NETCDF文件數據進行讀取。 ?
NETCDF文件主要是Dimensions, Variables, Attributes, Data 四個部分組成的,下面讀出文件各個部分的內容。???
??? Dimensions: ?
可以使用NETCDF 的成員函數num_dims()獲得文件中的Dimensions的個數,然后用NcFile類的另一個成員函數get_dim(int id),或get_dim(NcToken name)---參數可以是id號(int),也可以是dim名字(NcToken),獲得每一個文件的Dimensions,用NcDim類的成員函數id(),name(),size()可以依次讀出每一個Dimensions的id號,名稱,和size。
例如: ?
? for (int i=0;i<nc.num_dims()-1;i++) ??
?{?
????????? String.Format(String+"dimid=%d?? name=%s?length=%d/n",nc.get_dim(i)->id(),
????????? nc.get_dim(i)->name(),nc.get_dim(i)->size()); ??
} ???
利用一個for循環,依據dim的id號可以一次讀出所有dim的信息 ? ?
??? ?Variables:???????
??????同理用NETCDF 的成員函數num_vars()可以獲得文件中Variables數量,用NcFile類get_var(int id)或 get_var(NcToken name)可以讀出每一個文件中的Variables,也可以讀出id,name這些信息,所不同的是,Variables還可以用num_dims()讀出其所包含的Dimensions的個數,Variables還可以用get_dim(int id)讀出其包含的Dimensions的相關信息,同時文件的Data信息也是通過Variables來操作的。
?????? Data的讀出:????????????
?????????首先,我們要根據Variables包含的每一個Dimensions的size計算出數據的大小,定義一個相應大小的數組,用來存放數據。 ???????????????????
???????? 然后,用Variables的get(TYPE *array,long *num)第一個參數是剛才定義的存放數據的數組,第二個參數是自定義的一維數組,數組的元素用來存放每一維的size.一般用于多維數據。
例如:
???????????? float rhs[50];
???????????? long array[3];
???????????? array[0]=1;
?????????????array[1]=5;
???????????? array[2]=10;
????????????? nc.get_var("rh")->get(rhs,array);
??????????????還可以用Variables的get( TYPE* vals,long edge0=0,long edge1=0,long edge2=0,long edge3=0,long edge4=0) const?第一個參數是存放數據的數組,后面的參數分別記錄第1,2,3,4,5維的size,默認值為0,
例如:
??????????????????? int n=nc.get_dim("lat")->size();
??????????????????? int lats[5];
?????????????????? nc.get_var("lat")->get(lats,n);
??????????????????? for (i=0;i<5;i++)
?????????????????? { ?
????????????????????????? String.Format(String+"??? %d",lats[i]);
??????????????????? }
????????????如果Variables中還包含說明的Attributes,可以使用函數get_att(int id),參數為Attributes的id,讀出其Attributes。
例如:
???????????? String.Format("/natt:/n%s:%s/n",nc.get_var(0)->get_att(0)->name(),
???????????????? nc.get_var(0)->get_att(0)->as_string(0));
???? ? Attributes:
?????????? Attributes可分為兩種一種是整個文件的說明,即global attributes可以通過NcFile類的get_att(int id)函數來獲得,參數為id號,
例如:
?? ?String.Format(String+"/n%s:?%s",nc.get_att(0)->name(),nc.get_att(0)->as_string(0));
還有一種是的說明,可以通過在Variables說明的方法獲得,從讀出的信息主要包括名稱和相應的內容,可以通過name()和as_Type(long id),Type根據Attributes數據的類型來確定,如as_string(long id),as_int(long id)等,as_Type(long id)函數主要是用來取出每個Variables的內容。例子在Variables后面。 ????? ???
???? ? Data:???????????
? 通過Variables我們已經把數據讀出。
?1.3?????NETCDF文件的寫入
和讀文件時一樣,首先要定義一個NcFile類的對象,
如:
?NcFile nc("G://File.nc", NcFile:: Replace);
用nc.is_valid()來判斷文件打開是否成功,文件的打開方式我們可以選擇New建立一個新的文件,用這種方式如果文件已經存在會返回錯誤,也可以用Write和Replace。選擇Replace,如果文件已存在原文件就會被覆蓋掉。用Write時文件必須已經存在,寫入文件的數據會加在文件已存在數據的后面。
?????首先,建立一個NETCDF文件,需要寫入的數據和剛才讀出的數據是一樣的,有Dimensions, Variables, Attributes, Data;
?Dimensions:
用NcFile類的add_dim(NcToken?name,long dimsize)成員函數加入Dimensions,如果size 為unlimited用NcFile類的add_dim(NcToken name)函數,NcFile類會自動把其size處理為unlimited。
例如:
?nc.add_dim("lat",5);
nc.add_dim("time");//size 為unlimited時 ?
Variables:
用NcFile類的add_var(NcToken name,NcType type,type dim1,type dim2,… …)成員函數加入Variables,dim1,…,dimn,為Variables中包含的Dimensions。
?例如:
?nc.add_var("lat",ncInt,nc.get_dim(0));//一個dim時
?nc.add_var("rh",ncFloat,nc.get_dim("time"),
?nc.get_dim("lat"),nc.get_dim("lon"));//多個dim時
?Attributes:
整個文件的Attributes用NcFile的add_att(NcToken attname,Type value)函數Type根據加入Attributes的類型來判斷;Variables可以用其成員函數add_att(attname, Type value)加入。
例如:
????? //寫入文件的主要參數
???? nc.add_att("sourse","Fictional Model Output");
???? //寫入單個變量的參數
???? nc.get_var(0)->add_att("long_name","Temperature");
?? Data:
先定義一個數組,把要寫入文件的數據寫入數組,用 Variables的函數put(TYPE *arr,const long *count)TYPE 為數據類型或Variable的函數put( TYPE* vals,long edge0=0,long edge1=0,long edge2=0,long edge3=0,long edge4=0) const,第一個參數是存放數據的數組,后面的參數分別記錄第1,2,3,4,5維的size,默認值為0,例如:
??? int lats[5]={20,30,40,50,60};???????????????????????????? //lat
??? nc.get_var("lat")->put(lats,5);
???? float rhss[50]; ??? for (int i=0;i<1;i++)
??????? for (int j=0;j<5;j++)
??????????? for (int k=0;k<10;k++)
??????????? {
????????????????rhss[i*5*10+j*10+k]= (float)(i*5*10+j*10+k+1)/100;?
??????????? }
???? long count[3];?????????????????? //由于rh有多個dim,要定義一個一維數組
???? count[0] = 1;??????????????????? //來說明其每一維的size
???? count[1] = 5;
???? count[2] = 10;
???? nc.get_var("rh")->put(rhss,count);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
netcdf入門
作者:laomai
審核者: ybb
轉載時請注明出處:?http://blog.csdn.net/laomai
最近在做一個和數據采集有關的項目,里面用到了netcdf庫,大致看了一下,這里把心得寫出來,供后來者參考。一、概述? NetCDF全稱為network Common Data Format,中文譯法為“網絡通用數據格式”,
對程序員來說,它和zip、jpeg、bmp文件格式類似,都是一種文件格式的標準。netcdf文件開始的目的是用于存儲氣象科學中的數據,現在已經成為許多數據采集軟件的生成文件的格式。??
?從數學上來說,netcdf存儲的數據就是一個多自變量的單值函數。用公式來說就是f(x,y,z,...)=value, 函數的自變量x,y,z等在netcdf中叫做維(dimension)或坐標軸(axix),函數值value在netcdf中叫做變量(Variables).而自變量和函數值在物理學上的一些性質,比如計量單位(量綱)、物理學名稱等等在netcdf中就叫屬性(Attributes).
二、netcdf的下載
?netcdf的是官方網站為http://www.unidata.ucar.edu/software/netcdf/。
?在本文中,我們主要討論在windows平臺上使用netcdf軟件庫。我們將要從這個網站上下載如下資源
⑴netcdf的源代碼,目前的地址為?
ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-4/netcdf-beta.tar.gz
⑵netcdf的在windows平臺預編譯好的dll,地址為?
ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/win32/netcdf-3.6.1-win32.zip?
解壓后里面有如下東西?
netcdf.dll? 為編譯好的dll?
ncgen.exe? 為生成netcdf文件的工具?
ncdump.exe 為讀取netcdf文件的工具?
netcdf.lib 和?netcdf.exp在編程時會用到,后面會講。
⑶netcdf的相關文檔,包括?
①netcdf的用戶手冊,下載地址為http://www.unidata.ucar.edu/software/netcdf/docs/netcdf.pdf??
②netcdf的入門教程, 下載地址為http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial.pdf?
③netcdf的c接口api手冊,下載地址為http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.pdf?
下面我們來看netcdf文件的具體內容。
三、netcdf文件的內容
一個netcdf文件的結構包括以下對象:
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,很好理解。
三、CDL結構
?? CDL全稱為network Common data form Description Language,它是用來描述netcdf文件的結構的一種語法格式。它包括前面所說的三種netcdf對象(變量、維、屬性)的具體定義。看一個具體例子(這個例子cdl文件是從netcdf教程中的2.1 節The simple xy Example摘出來的)
?netcdf simple_xy {
dimensions:
x = 6 ;
y = 12 ;
variables:int data(x, y) ;
data:
data =
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ;
}
上面的代碼定義了一個符合netcdf格式的結構simple_xy,?
?這個結構包括三個部分
1、維的定義,以dimensions:關鍵字開頭
?? dimensions:
?x = 6 ;
?y = 12 ;?
定義了兩個軸(或者說兩維),名字分別為x和y,x軸的長度(準確的說是坐標點的個數)為6,?y軸的長度為12。
2、變量的定義:以variables:開頭
?variables:
??int data(x, y);?
?定義了一個以x軸和y軸為自變量的函數data,數學公式就是f(x,y)=data;??注意維出現的順序是有序的,它決定data段中的具體賦值結果.
3、數據的定義,以data:開頭
?data:
data =
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ;
這個段數據用數學的函數公式f(x,y)=data來看,就是?
?x=0,y=0時,data = 0;
???? x=0,y=1時,data = 1;
?????????????? x=5,y=11是,data=71
;要注意的是,
1、賦值順序:
我們給出的是c格式的cdl文件,因此這里的賦值順序和c語言中的一致,也就是通常所說的“行式賦值”,而fortran語言中則是“列式賦值”,因此在fortran格式的cdl文件中,data段的數值順序和這里正好行列互換。?????
2、自變量的默認取值和坐標變量?
? 如果只給出維的長度,那么維的值默認從0開始,然后自動加1,到(長度-1)停止,?? 很多情況下我們要自己給出每個點的坐標值,這時就需要用到netcdf里的坐標變量?? "coordinate varibles":增加一個和只和維相關的一元函數(自變量)并給出它的取值范圍。??
比如下面的cdl文件(摘自netcdf教程中的2.2 The sfc pres temp Example)
?? netcdf sfc_pres_temp {
?dimensions:?latitude = 6 ;??????? //緯度軸
?longitude = 12 ;????? //經度軸?
variables:
?float latitude(latitude) ;??? //坐標變量,存儲具體緯度
?latitude:units = "degrees_north" ;
?float longitude(longitude) ;? //坐標變量,存儲具體緯度
?longitude:units = "degrees_east" ;?
float pressure(latitude, longitude) ;?? //某個點(經度和緯度的交點)的大氣壓值
?pressure:units = "hPa" ;?????????? //大氣壓的單位為
?float temperature(latitude, longitude) ; //某個點(經度和緯度的交點)的溫度值
?temperature:units = "celsius" ;??? //溫度的單位為?
data:
?latitude = 25, 30, 35, 40, 45, 50 ;?
longitude = -125, -120, -115, -110, -105, -100, -95, -90, -85, -80, -75, -70 ;?
pressure =?
900, 906, 912, 918, 924, 930, 936, 942, 948, 954, 960, 966,
901, 907, 913, 919, 925, 931, 937, 943, 949, 955, 961, 967,?
902, 908, 914, 920, 926, 932, 938, 944, 950, 956, 962, 968,?
903, 909, 915, 921, 927, 933, 939, 945, 951, 957, 963, 969,?
904, 910, 916, 922, 928, 934, 940, 946, 952, 958, 964, 970,?
905, 911, 917, 923, 929, 935, 941, 947, 953, 959, 965, 971 ;?
temperature =?
9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 24, 25.5,?
9.25, 10.75, 12.25, 13.75, 15.25, 16.75, 18.25, 19.75, 21.25, 22.75, 24.25,?25.75,?
9.5, 11, 12.5, 14, 15.5, 17, 18.5, 20, 21.5, 23, 24.5, 26,?
9.75, 11.25, 12.75, 14.25, 15.75, 17.25, 18.75, 20.25, 21.75, 23.25, 24.75,?26.25,?
10, 11.5, 13, 14.5, 16, 17.5, 19, 20.5, 22, 23.5, 25, 26.5,?
10.25, 11.75, 13.25, 14.75, 16.25, 17.75, 19.25, 20.75, 22.25, 23.75,?25.25?
對于上面的數據,就是
?latitude = 25,longitude = -125時,pressure =?900,temperature =? 9;?
latitude = 25,longitude = -120時,pressure =?906,temperature =? 10.5;?
以此類推。?
?
四、netcdf文件的讀寫??
“學以致用”?,前面講的都是netcdf的基本知識,都是為了本節的核心問題——讀寫netcdf格式的文件做鋪墊之用,下面我們就來看看如何建立一個netcdf格式文件,以及如何再讀出它的內容。
1、在命令行下讀寫netcdf文件?
⑴建立一個simple_xy.cdl文件,內容就是上一節“CDL結構”中的第一個例子。?
⑵用ncgen.exe工具(下載地址見前面的第二節)建立netcdf文件? ?
??? ?①將ncgen所在目錄加到系統path變量中或者直接將ncgen.exe拷到simple_xy.cdl所在目錄下? ?
?? ??②執行ncgen -o simple_xy.nc simple_xy.cdl生成netcdf格式文件simple_xy.nc?
⑶生成的simple_xy.nc是一個二進制文件,要想從這個文件中還原出數據信息,就要用ncdump工具
???? ①將ncdump所在目錄加到系統path變量中或者直接將ncdump.exe拷到simple_xy.nc所在目錄下
???? ②在命令行下執行ncdump simple_xy.nc,這時屏幕的輸出和simple_xy.cdl內容完全一樣。說明???? 我們的文件讀寫操作都是正確的。?
2、編程讀寫netcdf文件
?前面我們知道如何手工去建立和讀取netddf文件,下面我們來看看如何在程序中用代碼實現netcdf文件的建立和分析。我的編程環境為win2000+vc6.0 并安裝了vc sp6補丁包。例子代碼選自netcdf教程中的2.1節The simple xy Example
⑴將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->add to project->files)
⑸把netcdf.lib加入到項目的lib列表中
?(具體菜單操作project->add to project->settings->Link->object/library modules)
⑹編譯并運行這個項目,會在項目目錄下生成一個simple_xy.nc文件,其內容和我們手工生成的文件內容完全一樣。
simple_xy_wr.c文件是建立netcdf文件的c代碼,而examples/C/simple_xy_rd.c文件則是分析netcdf文件的代碼,讀者可以用和剛才類似的步驟在vc6中編譯這個文件。運行時把把剛才生成的simple_xy.nc拷貝到項目的目錄下,如果文件格式沒錯誤,會提示
*** SUCCESS reading example file simple_xy.nc!
然后退出。
3、用ncgen命令自動生成c代碼?
給定了simple_xy.cdl文件后,可以用?
?ncgen -c? simple_xy.cdl?
?命令直接在屏幕上輸出c代碼.?
?不過,這個辦法只限于cdl的數據比較簡單時才可以采用。對于真正的項目,
?是需要我們自己去編寫代碼的。
??五、小結
?通過以上內容的介紹,相信讀者對netcdf已經有了大致的了解。總體來說,netcdf的核心內容就是通過cdl描述文法來建立一個netcdf格式文件。抓住了這一點,讀者再繼續深入看netcdf的其他資料時,應該就沒什么太大的難度了。如是,作者的目的也就達到了。
六、附錄
為便于讀者對照,現本文中用到的幾個文件的內容在此列出
1、simple_xy.cdl文件的內容
netcdf simple_xy {
dimensions:
x = 6 ;
y = 12 ;
variables:
int data(x, y) ;
data:
data =
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ;
}
2、simple_xy-wr.c文件的內容
/* This is part of the netCDF package.
?? Copyright 2006 University Corporation for Atmospheric Research/Unidata.?
? See COPYRIGHT file for conditions of use.
?
?? This is a very simple example which writes a 2D array of
?? sample data. To handle this in netCDF we create two shared
?? dimensions, "x" and "y", and a netCDF variable, called "data".
?
?? This example demonstrates the netCDF C API. This is part of the
?? netCDF tutorial, which can be found at:
???http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial??
?? Full documentation of the netCDF C API can be found at:??
??http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c
?
?? $Id: simple_xy_wr.c,v 1.12 2007/02/14 20:59:21 ed Exp $
*/
#include <stdlib.h>
#include <stdio.h>
#include <netcdf.h>
/* This is the name of the data file we will create. */
#define FILE_NAME "simple_xy.nc"
/* We are writing 2D data, a 6 x 12 grid. */
#define NDIMS 2
#define NX 6
#define NY 12
/* Handle errors by printing an error message and exiting with a?* non-zero status. */
#define ERRCODE 2
#define ERR(e)
?{printf("Error: %s/n", nc_strerror(e)); exit(ERRCODE);}
int
main()
{
?? /* When we create netCDF variables and dimensions, we get back an
??? * ID for each one. */
?? int ncid, x_dimid, y_dimid, varid;
?? int dimids[NDIMS];
?? /* This is the data array we will write. It will be filled with a
??? * progression of numbers for this example. */
?? int data_out[NX][NY];
?? /* Loop indexes, and error handling. */
?? int x, y, retval;
?? /* Create some pretend data. If this wasn't an example program, we
??? * would have some real data to write, for example, model
??? * output. */
?? for (x = 0; x < NX; x++)
????? for (y = 0; y < NY; y++)
? data_out[x][y] = x * NY + y;
?? /* Always check the return code of every netCDF function call. In
??? * this example program, any retval which is not equal to NC_NOERR
??? * (0) will cause the program to print an error message and exit
??? * with a non-zero return code. */
?? /* Create the file. The NC_CLOBBER parameter tells netCDF to
??? * overwrite this file, if it already exists.*/
?? if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid)))
????? ERR(retval);
?? /* Define the dimensions. NetCDF will hand back an ID for each. */
?? if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid)))
????? ERR(retval);
?? if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
????? ERR(retval);
?? /* The dimids array is used to pass the IDs of the dimensions of
??? * the variable. */
?? dimids[0] = x_dimid;
?? dimids[1] = y_dimid;
?? /* Define the variable. The type of the variable in this case is?
?? * NC_INT (4-byte integer). */
?? if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS,
??????? dimids, &varid)))
????? ERR(retval);
?? /* End define mode. This tells netCDF we are done defining
??? * metadata. */
?? if ((retval = nc_enddef(ncid)))
????? ERR(retval);
?? /* Write the pretend data to the file. Although netCDF supports?
??? * reading and writing subsets of data, in this case we write all
??? * the data in one operation. */
?? if ((retval = nc_put_var_int(ncid, varid, &data_out[0][0])))
????? ERR(retval);
?? /* Close the file. This frees up any internal netCDF resources
??? * associated with the file, and flushes any buffers. */
?? if ((retval = nc_close(ncid)))
????? ERR(retval);
?? printf("*** SUCCESS writing example file simple_xy.nc!/n");
?? return 0;
}
3、simple_xy_rd.c文件的內容
/* This is part of the netCDF package.
?? Copyright 2006 University Corporation for Atmospheric Research/Unidata.
?? See COPYRIGHT file for conditions of use.
?? This is a simple example which reads a small dummy array, which was
?? written by simple_xy_wr.c. This is intended to illustrate the use
?? of the netCDF C API.
?? This program is part of the netCDF tutorial:
???http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
?? Full documentation of the netCDF C API can be found at:???
? http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c
?? $Id: simple_xy_rd.c,v 1.9 2006/08/17 23:00:55 russ Exp $
*/
#include <stdlib.h>
#include <stdio.h>
#include <netcdf.h>
/* This is the name of the data file we will read. */
#define FILE_NAME "simple_xy.nc"
/* We are reading 2D data, a 6 x 12 grid. */
#define NX 6
#define NY 12
/* Handle errors by printing an error message and exiting with a?
* non-zero status. */
#define ERRCODE 2
#define ERR(e)
{printf("Error: %s/n", nc_strerror(e)); exit(ERRCODE);}
?
int
main()
{
?? /* This will be the netCDF ID for the file and data variable. */
?? int ncid, varid;
?? int data_in[NX][NY];
?? /* Loop indexes, and error handling. */
?? int x, y, retval;
?? /* Open the file. NC_NOWRITE tells netCDF we want read-only access
??? * to the file.*/
?? if ((retval = nc_open(FILE_NAME, NC_NOWRITE, &ncid)))
????? ERR(retval);
?? /* Get the varid of the data variable, based on its name. */
?? if ((retval = nc_inq_varid(ncid, "data", &varid)))
????? ERR(retval);
?? /* Read the data. */
?? if ((retval = nc_get_var_int(ncid, varid, &data_in[0][0])))
????? ERR(retval);
?? /* Check the data. */
?? for (x = 0; x < NX; x++)
????? for (y = 0; y < NY; y++)
? if (data_in[x][y] != x * NY + y)
???? return ERRCODE;
?? /* Close the file, freeing all resources. */
?? if ((retval = nc_close(ncid)))
????? ERR(retval);
?? printf("*** SUCCESS reading example file %s!/n", FILE_NAME);
?? return 0;
}
總結
- 上一篇: 精确记算程序的运行时间或者某段代码的运行
- 下一篇: OpenCV分配与释放图像空间