> 文章列表 > NCL读取hdf5文件——以AMSR2海冰密集度数据为例

NCL读取hdf5文件——以AMSR2海冰密集度数据为例

NCL读取hdf5文件——以AMSR2海冰密集度数据为例

由于大部分计算都是在服务器进行。因此考虑增进NCL和Shell脚本水平,之前的博文Python读取HDF5介绍了HDF5文件及其读写,但是由于服务器本身系统版本较老,且属于内网原因,决定直接使用自带的NCL脚本对其进行撰写记录。

读取

NCL6版本以后便支持HDF5文件的读写,官方文档也给出了读写HDF5文件的实例

;----------------------------------------------------------------------
; hdf5_1.ncl
;
; Concepts illustrated:
;   - Reading group data off an HDF5 file using two methods
;   - Creating a color map using RGB triplets
;   - Drawing raster contours for faster results
;----------------------------------------------------------------------
; These files are loaded by default in NCL V6.2.0 and newer
; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"
; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"
; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
;----------------------------------------------------------------------begin
;---It is necessary to use advanced file structure to read group datasetfileoption("nc", "FileStructure", "Advanced")fname = "MSG3-SEVI-MSG15-0100-NA-20130521001244.164000000Z-1074164.h5"f     = addfile(fname,"r");------------------------------------------------------------
; There are two ways to read variables off a files
; containing nested groups.
;
; Method 1: 
;     - Open the group with the "=>" syntax
;     - Read the data using the usual "->" syntax
;
; Method 2:
;     - Open the variable directly using the full path 
;       to the file
;
; Note: there's an inconsistency with how the group names
; are constructed for the two methods. We have opened a
; trouble ticket for this.
;------------------------------------------------------------USE_FULL_PATH = Trueif(.not.USE_FULL_PATH) then
;---First method; open group, then read data from it.group_name  ="/U_MARF/MSG/Level1_5/DATA/Channel_07"iname      = "IMAGE_DATA"pname      = "Palette"gp         = f=>$group_name$fdata      = tofloat(gp->$iname$)palette    = tofloat(gp->$pname$)else
;---Second method; use full path to variable.group_name = "/U-MARF/MSG/Level1.5/DATA/Channel 07"iname      = group_name + "/IMAGE_DATA"pname      = group_name + "/Palette"fdata      = tofloat(f->$iname$)palette    = tofloat(f->$pname$)end ifwks = gsn_open_wks("png","hdf5")              ; send graphics to PNG fileres                      = True               ; plot mods desiredres@gsnMaximize          = True               ; maximize plot in frameres@cnFillOn             = True               ; color fill res@cnFillMode           = "RasterFill"       ; Raster mode is much faster; and uses less memory.res@cnFillPalette        = palette/255.res@cnLinesOn            =  False             ; turn off contour linesres@cnLevelSelectionMode = "ManualLevels"     ; set manual contour levelsres@cnMinLevelValF       = min(fdata)         ; set min contour levelres@cnMaxLevelValF       = max(fdata)         ; set max contour levelres@cnLevelSpacingF      =  10.0              ; set contour spacingres@lbOrientation        = "vertical"         ; vertical labelbarres@lbBoxLinesOn         = Falseres@gsnTickMarksOn       = Falseif(USE_FULL_PATH)res@tiMainString = "Variable read using full group path"elseres@tiMainString = "Variable read by opening group first"end ifplot = gsn_csm_contour(wks,fdata, res) ; create plot
end

主要有两种读法,但不论哪一种,都需要对HDF5文件本身的结构有所了解,在上一篇博文中。我主要使用了matlab的h5info函数来直接查看,而NCL也提供了对应的函数:ncl_filedump
其用法也非常简单:

ncl_filedump K1VHR_15NOV2013_1200_L02_OLR.h5 | less

或者直接:

setfileoption("h5", "FileStructure", "Advanced")
f = addfile("ncl_wrt_uvt.h5", "r")
print(f)

也可查看
值得注意的是:
matlab h5info返回的信息与NCL返回的信息并不一致,这导致很多时候我们并不能像matlab或者python、NCL官方示例一样,从不同的GROUP中读取数据,NCL对于HDF5数据的处理很多时候和nc一样,直接给出变量名。
举个实例,同样是AMSR2文件,matlab给出的结构为:

 Group '/HDFEOS' Group '/HDFEOS/ADDITIONAL' Group '/HDFEOS/ADDITIONAL/FILE_ATTRIBUTES' Group '/HDFEOS/GRIDS' Group '/HDFEOS/GRIDS/NpPolarGrid12km' Dataset 'XDim' Size:  608MaxSize:  608Datatype:   H5T_IEEE_F32LE (single)ChunkSize:  []Filters:  noneFillValue:  0.000000Attributes:'CLASS':  'DIMENSION_SCALE''NAME':  'This is a netCDF dimension but not a netCDF variable.''axis':  'X''long_name':  'x-coordinate in Cartesian system''REFERENCE_LIST':  H5T_COMPOUNDDataset 'YDim' Size:  896MaxSize:  896Datatype:   H5T_IEEE_F32LE (single)ChunkSize:  []Filters:  noneFillValue:  0.000000Attributes:'CLASS':  'DIMENSION_SCALE''NAME':  'This is a netCDF dimension but not a netCDF variable.''axis':  'Y''long_name':  'y-coordinate in Cartesian system''REFERENCE_LIST':  H5T_COMPOUNDDataset 'lat' Size:  608x896MaxSize:  608x896Datatype:   H5T_IEEE_F32LE (single)ChunkSize:  []Filters:  noneFillValue:  0.000000Attributes:'DIMENSION_LIST':  H5T_VLEN'long_name':  'Latitude''units':  'degrees_north''standard_name':  'latitude'Dataset 'lon' Size:  608x896MaxSize:  608x896Datatype:   H5T_IEEE_F32LE (single)ChunkSize:  []Filters:  noneFillValue:  0.000000Attributes:'DIMENSION_LIST':  H5T_VLEN'long_name':  'Longitude''standard_name':  'longitude''units':  'degrees_east'Group '/HDFEOS/GRIDS/NpPolarGrid12km/Data Fields' Dataset 'SI_12km_NH_18H_ASC' Size:  608x896MaxSize:  608x896Datatype:   H5T_STD_I32LE (int32)ChunkSize:  []Filters:  noneFillValue:  0Attributes:'DIMENSION_LIST':  H5T_VLEN'coordinates':  'lon lat''long_name':  '18.7 GHz horizontal daily average ascending Tbs''units':  'degree_kelvin''standard_name':  'brightness_temperature''packing_convention':  'netCDF''packing_convention_description':  'unpacked = scale_factor x packed + add_offset''scale_factor':  0.100000 'add_offset':  0.000000 '_FillValue':  0 

算是标准的HDF5结构了,而NCL print出来则是:

dimensions:YDim_NpPolarGrid12km = 896XDim_NpPolarGrid12km = 608YDim_SpPolarGrid12km = 664XDim_SpPolarGrid12km = 632variables:double GridLat_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )projection :   Polar Stereographiccorners :      ( -39.29786148540076, -39.29786148540076, -41.51518496442763, -41.51518496442763 )long_name :    latitudeunits :        degrees_northdouble GridLon_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )projection :   Polar Stereographiccorners :      ( -42.23673723653989, 42.23673723653989,  135, -135 )long_name :    longitudeunits :        degrees_eastinteger SI_12km_SH_SNOWDEPTH_5DAY_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      110 -- missing/not calculated, 120 -- Land, 130 -- Open water, 140 -- multiyear sea ice, 150 -- variability in snow depth, 160 -- snow meltunits :        cmlong_name :    5-day snow depthcoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    5-day snow depthprojection :   Polar Stereographicinteger SI_12km_SH_ICEDIFF_DAY_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 1 to 100 or -1 to -100 -- Percent difference between algorithms, 120 -- Land, 200 to 300 -- Missing NT2 value (200+BBA), -200 to -300 -- Missing BBA value (-200 - NT2)units :        percentlong_name :    Sea ice concentration daily average using the difference between BBA and NT2 algorithmscoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily average using the difference between BBA and NT2 algorithmsprojection :   Polar Stereographicinteger SI_12km_SH_ICEDIFF_DSC_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 1 to 100 or -1 to -100 -- Percent difference between algorithms, 120 -- Land, 200 to 300 -- Missing NT2 value (200+BBA), -200 to -300 -- Missing BBA value (-200 - NT2)units :        percentlong_name :    Sea ice concentration daily descending average using the difference between BBA and NT2 algorithmscoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily descending average using the difference between BBA and NT2 algorithmsprojection :   Polar Stereographicinteger SI_12km_SH_ICEDIFF_ASC_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 1 to 100 or -1 to -100 -- Percent difference between algorithms, 120 -- Land, 200 to 300 -- Missing NT2 value (200+BBA), -200 to -300 -- Missing BBA value (-200 - NT2)units :        percentlong_name :    Sea ice concentration daily ascending average using the difference between BBA and NT2 algorithmscoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily ascending average using the difference between BBA and NT2 algorithmsprojection :   Polar Stereographicinteger SI_12km_SH_ICECON_DAY_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 110 -- missing/not calculated, 120 -- Landunits :        percentlong_name :    Sea ice concentration daily averagecoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily averageprojection :   Polar Stereographicinteger SI_12km_SH_ICECON_DSC_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 110 -- missing/not calculated, 120 -- Landunits :        percentlong_name :    Sea ice concentration daily descending averagecoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily descending averageprojection :   Polar Stereographicinteger SI_12km_SH_ICECON_ASC_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmcomment :      data value meaning: 0 -- Open Water, 110 -- missing/not calculated, 120 -- Landunits :        percentlong_name :    Sea ice concentration daily ascending averagecoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    Sea ice concentration daily ascending averageprojection :   Polar Stereographicinteger SI_12km_SH_89H_DAY_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12km_FillValue :   0add_offset :    0scale_factor : 0.1packing_convention_description :       unpacked = scale_factor x packed + add_offsetpacking_convention :   netCDFstandard_name :        brightness_temperatureunits :        degree_kelvinlong_name :    89.0 GHz horizontal daily average Tbscoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    89.0 GHz horizontal daily average Tbsprojection :   Polar Stereographicinteger SI_12km_SH_89H_DSC_SpPolarGrid12km ( YDim_SpPolarGrid12km, XDim_SpPolarGrid12km )coordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12km_FillValue :   0add_offset :    0scale_factor : 0.1packing_convention_description :       unpacked = scale_factor x packed + add_offsetpacking_convention :   netCDFstandard_name :        brightness_temperatureunits :        degree_kelvinlong_name :    89.0 GHz horizontal daily average descending Tbscoordinates :  GridLat_SpPolarGrid12km, GridLon_SpPolarGrid12kmlong_name :    89.0 GHz horizontal daily average descending Tbsprojection :   Polar Stereographic

没有了Grouo信息,而是直接将变量提取出来。
因此,在使用NCL读取HDF5时,应当注意其NCL对其的处理方式。

实例AMSR2海冰数据

接下来介绍实例,用ncl读取AMSR2 12.5Km的海冰密集度数据:

;   - Reading am AMSR2 h5 file containing "sea ice"
;   - Creating the appropriate grid and time coordinates
;   - Chang format to WPS_int fileload "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"
load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"
load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
load "$NCARG_ROOT/lib/ncarg/nclscripts/wrf/WRFUserARW.ncl"
load "$NCARG_ROOT/lib/ncarg/nclscripts/esmf/ESMF_regridding.ncl"beginsetfileoption("h5", "FileStructure", "Advanced")ymdd1="20191201"ymdd2="2019-12-01"
; ymdd1=getenv("basedate1")
; ymdd2=getenv("basedate2")data_filename="/public/home/zhangzilu/AMSR/2019/AMSR_U2_L3_SeaIce12km_B04_"+ymdd1+".he5"print(data_filename)f = addfile(data_filename, "r")lat=f->GridLat_NpPolarGrid12kmlon=f->GridLon_NpPolarGrid12kmice_con=tofloat(f->SI_12km_NH_ICECON_DAY_NpPolarGrid12km)printVarSummary(ice_con)
; print(lat)
end

便可,批量读取只要与shell脚本结合便可高效批量完成。
读取HDF5数据唯一的难点便在于对于数据结构的理解。