【179】IDL 讀寫 NetCDF 文件


  NetCDF(network Common Data Form)由位於科羅拉多州波爾市的 Unidata 程序中心開發,主要應用於大氣科學的研究。NetCDF 的數據模式具有簡單性和靈活性的特點。NetCDF 文件的基本組成為變量、屬性和維數:

  • 變量為標量或多維數組。NetCDF 所支持的 IDL 數據類型有 string、byte、int、long、float 和 double
  • 屬性包含一個變量或這個文件的附加性質。包含變量信息(如單位、有效范圍、尺度因子等)的屬性稱作變量屬性;包含文件信息的屬性稱作全局屬性。屬性可以是標量或一維數組,支持的數據類型為 string、byte、int、long、float 和 double
  • 維數為長整形標量,記錄了一個或多個變量的大小

參考:NetCDF 格式文件入門
參考:NetCDF 入門

       從數學上來說,NetCDF 存儲的數據就是一個多自變量的單值函數。 用公式來說就是 f(x,y,z,...) = value,函數的自變量 x,y,z 等在 NetCDF 中叫做 (dimension) 或坐標軸 (axis),函數值 value 在 NetCDF 中叫做變量 (Variables)。而自變量和函數值在物理學上的一些性質,比如計量單位 (量綱)、物理學名稱等等在 NetCDF 中就叫屬性 (Attributes)。

       注意:IDL讀取數據與在其他軟件上顯示的數據位置相反,左上對右下!

       注意:NetCDF記錄數據與實際數據是通過一個數量關系獲取的,如下圖所示:

            實際結果 = 顯示結果 × scale_factor + add_offset  

      


數據:可以從 http://www.gumley.com 中下載這些例子的數據文件:

  • image.nc
  • sao.nc

常用的 NetCDF 程序

名     稱 功     能 名     稱 功     能
NCDF_OPEN() 打開一個 NetCDF 文件 NCDF_ATTNAME() 返回一個屬性名稱
NCDF_CLOSE 關閉一個 NetCDF 文件 NCDF_CREATE() 創建一個 NetCDF 文件
NCDF_VARID() 返回一個變量標識符 NCDF_DIMDEF() 創建一個維度
NCDF_VARGET 讀取一個變量 NCDF_VARDEF() 創建一個變量
NCDF_ATTGET 讀取一個屬性 NCDF_ATTPUT 寫入屬性數據
NCDF_INQUIRE() 返回文件信息 NCDF_CONTROL 開始或結束定義模式
NCDF_VARINQ() 返回變量信息 NCDF_VARPUT 寫入變量數據

常用的標准 NetCDF 文件屬性

屬性名稱 定      義
long_name 詳細描述變量的字符串(如“Northwards velocity component”)
units 描述變量單位的字符串(如“meters/second”)
valid_range 一個兩元素的數組,包含變量有效的最小和最大值(如 [0.0, 5.0]),
該屬性的類型必須和變量類型一致
scale_factor 變量讀取以后作用於變量的一個乘數(允許 float 值存在 short 或 byte 類型),
該屬性的類型必須和需要的變量類型一致(如浮點型)
add_offset 變量讀取完畢,並且 scale_factor 使用后,加入到變量的一個偏值,
該屬性的類型必須和需要的變量類型一致(如浮點型)
FillValue 表示沒有數據寫入的一個值,該屬性的類型必須和變量的類型一致

 

  • NCDF_OPEN:【函數】打開一個 NetCDF 文件,返回值是這個文件的 NetCDF ID 值。
           語法:Result = NCDF_OPEN( Filename [, /NOWRITE | , /WRITE] )
  • NCDF_CLOSE:關閉一個 NetCDF 文件。
           語法:NCDF_CLOSE, Cdfid
  • NCDF_VARID:【函數】返回一個變量標識符,變量 ID,如果返回值為 -1 說明變量不存在。
           語法:Result = NCDF_VARID(Cdfid, Name)
  • NCDF_VARGET:讀取一個變量。
           語法:NCDF_VARGET, Cdfid, Varid, Value [, COUNT=vector] [, OFFSET=vector] [, STRIDE=vector]
           說明:Cdfid 是 NCDF_OPEN 函數獲取的返回值;
                       Varid 是 NCDF_VARID 函數獲取的返回值;
                       Value 是讀取變量的結果;
                       COUNT 是每維中讀取元素的數目(默認情況是從當前 offset 的位置到每維的最后一個元素);
                       OFFSET 是每維中讀取的第一個元素(從零開始,默認為 [0, 0, ... ,0];
                       STRIDE 是在每維中提取的間隔(默認為 [1, 1, ... , 1],意味着每個元素均被選中)。
           注意:如果 offset、count 或 stride 導致變量超出了范圍,則 IDL 在讀取時將舍去超出的部分,並給出錯誤信息。
    image.nc 在 HDFView 中顯示如下:

    IDL> cd, 'F:\IDL\netCDF'
    IDL> cdfid = ncdf_open('image.nc')
    IDL> varid = ncdf_varid(cdfid, 'image')
    IDL> ncdf_varget, cdfid, varid, data
    IDL> help,data
    DATA            BYTE      = Array[1200, 600]
    IDL> tvscl, data
    IDL> cdfid = ncdf_open('image.nc')
    IDL> varid = ncdf_varid(cdfid, 'image')
    IDL> ncdf_varget, cdfid, varid, data, offset=[600,0], count=[256,256], stride=[2,2]
    IDL> help, data
    DATA            BYTE      = Array[256, 256]
    IDL> tvscl, data
    IDL> ncdf_varget, cdfid, varid, data, offset=[600,0], count=[256,512], stride=[2,2]
    % NCDF_VARGET: Requested read is larger than data in dimension 1. Reducing COUNT
                    to 300.
  • NCDF_ATTGET:讀取一個屬性。
           語法:NCDF_ATTGET, Cdfid [, Varid] , Name, Value [, /GLOBAL]
           說明:Name 是包含屬性名稱的字符串;
                       Value 獲取變量結果。
    IDL> cdfid = ncdf_open('sao.nc')
    IDL> varid = ncdf_varid(cdfid, 'PRECIP')
    IDL> ncdf_attget, cdfid, varid, 'long_name', attvalue
    IDL> print, attvalue
     112 114 101  99 105 112 105 116  97 116 105 111 110  32  97 109 111 117 110 116
    IDL> string(attvalue)
    precipitation amount
  • NCDF_INQUIRE:返回文件信息
         【函數】返回值是一個結構體,{ NDIMS:0L, NVARS:0L, NGATTS:0L, RECDIM:0L }
           說明:Ndims 這個 NetCDF 文件定義維度的數目;
                       Nvars 這個 NetCDF 文件定義變量的數目;
                       Ngatts 這個 NetCDF 文件定義全局屬性的數目;
                       RecDim The ID of the unlimited dimension, if there is one, for this NetCDF file. If there is no unlimited dimension, RecDim is set to -1.

           語法:Result = NCDF_INQUIRE(Cdfid)
  • NCDF_VARINQ:返回變量信息
         【函數】返回值是一個結構體,{ NAME:"", DATATYPE:"", NDIMS:0L, NATTS:0L, DIM:LONARR(NDIMS) }
           說明:Name 變量的名稱;
                       DataType 變量數據類型,'BYTE', 'CHAR', 'INT', 'LONG', 'FLOAT', or 'DOUBLE';
                       Ndims 維度的數目;
                       Natts 給這個變量分配屬性的數目;
                       Dim A vector of the dimension IDs for the variable dimensions.

           語法:Result = NCDF_VARINQ(Cdfid, Varid)
    Function ncdf_vardir, cdfid
      ;- Check arguments
      if(n_params() ne 1) then $
        message, 'Usage: result=ncdf_vardir(cdfid)'
      if(n_elements(cdfid) eq 0) then $
        message, 'Argument cdfid is undefined'
        
      ;- Set default return value
      varnames=''
      
      ;- Get file information
      fileinfo = ncdf_inquire(cdfid)
      nvars=fileinfo.nvars
      
      ;- If variables were found, get variable names
      if(nvars gt 0) then begin
        varnames = strarr(nvars)
        for index = 0L, nvars - 1L do begin
          varinfo = ncdf_varinq(cdfid, index)
          varnames[index] = varinfo.name
        endfor
      endif
      
      ; -return the result
      return, varnames
    end
    IDL> cdfid = ncdf_open('sao.nc')
    IDL> varnames = ncdf_vardir(cdfid)
    IDL> help, varnames
    VARNAMES        STRING    = Array[25]
    IDL> print, varnames
    id region time lat lon elev T TD PSL ALTIM SPD
    DIR GUST WX ZCL CC cloudtype VIS Ptend delP
    PRECIP reftime_PRECIP Tmax Tmin remarks
  • NCDF_ATTNAME:返回一個屬性名稱。
         【函數】返回屬性名稱,如果沒有,就返回空。
           語法:Result = NCDF_ATTNAME( Cdfid [, Varid] , Attnum [, /GLOBAL])
  • NCDF_CREATE:創建一個 NetCDF 文件。
         【函數】創建成功的話就會返回 NetCDF ID 值。文件自動轉入定義模式(define mode),意味着新的變量、屬性和維度可以加入文件中。
           語法:Result = NCDF_CREATE( Filename [, /CLOBBER | /NOCLOBBER] [, /NETCDF3_64BIT] [, /NETCDF4_FORMAT] )
           說明:CLOBBER 設置此關鍵字,並且文件存在,那么在創建新的版本之前直接擦除文件內容;
                       NOCLOBBER 設置此關鍵字,只有不存在此文件的情況下才能創建成功,否則報錯。

  • NCDF_DIMDEF:創建一個維度。
         【函數】如果成功,返回維度的 ID 值。      
           語法:Result = NCDF_DIMDEF( Cdfid, DimName, Size [, /UNLIMITED] )
           說明:DimName 被定義緯度的字符串名稱;
                       Size 維度的大小。可以用任何數量的表達式來表達。如果使用了關鍵字 UNLIMITEDSize 相當於無效;
                       UNLIMITED 設置此關鍵字可以創建一個無限大小的維度。

  • NCDF_VARDEF:創建一個變量。
         【函數】如果成功,返回變量的 ID 值。如果不能創建這個新的變量,就會返回-1。
           語法:Result = NCDF_VARDEF( Cdfid, Name [, Dim] [, /BYTE | , /CHAR | , /DOUBLE | , /FLOAT | , /LONG | , /SHORT] [, CHUNK_DIMENSIONS] [, /CONTIGUOUS] [, GZIP=value] [, /SHUFFLE] [, /STRING] [, /UBYTE] [, /UINT64] [, /ULONG] [, /USHORT])
           說明:如果類型關鍵字沒有數據,默認使用 FLOAT
                       Dim 包括變量維度的 dimension IDs。如果 ID 是無限大小的,那必須放在數組的最右面。如果沒有設置 Dim,變量默認為一個標量。

  • NCDF_ATTPUT:寫入屬性數據。
           語法:NCDF_ATTPUT, Cdfid [, Varid] , Name , Value [, /GLOBAL] [, LENGTH=value] [, /BYTE | , /CHAR | , /DOUBLE | , /FLOAT | , /LONG | , /SHORT] [, /STRING] [, /UBYTE] [, /UINT64] [, /ULONG] [, / USHORT]
           說明:GLOBAL 設置此關鍵字去創建全局屬性。
  • NCDF_CONTROL:開始或結束定義模式。
           語法:NCDF_CONTROL, Cdfid [, /ABORT] [, /ENDEF] [, /FILL | , /NOFILL] [, /NOVERBOSE | , /VERBOSE] [, OLDFILL=variable] [, /REDEF] [, /SYNC]
           說明: 設置此關鍵字可以將一個打開的 NetCDF 文件結束定義模式(define mode),進入數據模式(data mode)文件只有在數據模式下才能寫入變量。
  • NCDF_VARPUT:寫入變量數據。
           語法:NCDF_VARPUT, Cdfid, Varid, Value [, COUNT=vector] [, OFFSET=vector] [, STRIDE=vector]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM