HDF数据结构研究.docx
《HDF数据结构研究.docx》由会员分享,可在线阅读,更多相关《HDF数据结构研究.docx(23页珍藏版)》请在冰点文库上搜索。
HDF数据结构研究
HDF数据结构研究
1.HDF概念
HDF,HierarchicalDataFormat,分层数据格式,美国国家高级计算应用中心NCSA
(NationalCenterforSupercomputingApplications)为了满足各领域研究需求而研制的一种能高效存储和分发科学数据的新型数据格式,是一种分层式数据管理结构,被地球观测系统数据和信息系统核心系统所选用作为标准数据格式。
它的表现形式是一种多目标的文件格式,目的是为了在分布式环境中共享科学数据。
HDF文件格式的优势在于:
可移植性强(独立于操作平台);属于超文本文件;可以存储并处理大数据量;一个文件集可以管理多种类型的数据结构;具有可扩展性。
由于HDF的诸多优点,这种格式已经被广泛用于目前国外各种卫星传感器的标准数据格式。
在影像数据库多源数据管理中,HDF格式发挥了很好的作用,利用HDF数据结构建立远程图象工程,并与数据库进行交互;可以进行远程图像处理;远程影像解译,统计分析;影像运算、信息挖掘、影像分类;综合处理影像、矢量、高程数据,三维可视显示等。
2.HDF数据结构
HDF文件有六种主要数据类型,如图:
1.栅格图像RasterImage:
数据模式提供一种灵活方式存储、描述栅格图像数据,包括8bit栅格图像。
2.调色板Palette:
也叫作彩色查对表,它提供图像的色谱。
3.科学数据集ScientificDataSet:
用来存储和描述多维科学数据陈列。
4.HDF注释Annotation:
是文字串,用来描述HDF文件或HDF数据目标。
5.Vdata:
是一个框架,用于存储和描述数据表。
6.Vgroup:
是用来把相关数据目标联系起来。
一个Vgroup可以含有其它Vgroup,以及数据目标。
任一个HDF目标均可以包括进某个Vgroup中。
而在HDF5中,建立一个新的HDF文件后,会有5种数据格式显示:
HDF4中只有前三种,但nasa下来的数据再HDFview
里面显示的是版本4.
3.对于NASA的MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf进行的格式研究。
其中有基于SD(sciencedata)和GD(VgroupID)两种方式对HDF文件进行处理,例
如下图,EOSGRID就是一个Vgroup,而PS就是一个SD的datafield。
利用SD方式进行读写
1)SD方式读取的变量,是整个HDF文件的变量,没有层次结构的显示,下面是输出的和HDFview比对的结果。
FUNCTIONHDF_SD_VARDIR,HDFID
varnames=''
hdf_sd_fileinfo,hdfid,nvars,ngatts
if(nvarsgt0)thenbegin
varnames=strarr(nvars)
forindex=0L,nvars-1Ldobegin
varid=hdf_sd_select(hdfid,index)
hdf_sd_getinfo,varid,name=name
hdf_sd_endaccess,varid
varnames[index]=name
endfor
endif
return,varnames
END
IDL>pp=hdf_sd_vardir(hdfid)
IDL>print,pp
PSDELPTUVQVO3XDim:
EOSGRIDYDim:
EOSGRID
Height:
EOSGRIDTIME:
EOSGRIDXDimYDim
HeightTime
2)SD方式读取的属性,当变量输入为空时,显示的是整个HDF文件的属性。
下面是输出的和HDFview比对的结果。
FUNCTIONHDF_SD_ATTDIR,HDFID,VARNAME
if(n_elements(hdfid)eq0)then$
message,'HDFIDisundefined'
attnames=''
if(varnameeq'')thenbegin
hdf_sd_fileinfo,hdfid,nvars,natts
endifelsebegin
index=hdf_sd_nametoindex(hdfid,varname)
varid=hdf_sd_select(hdfid,index)
hdf_sd_getinfo,varid,natts=natts
endelse
if(nattsgt0)thenbegin
attnames=strarr(natts)
forindex=0L,natts-1dobegin
if(varnameeq'')thenbegin
hdf_sd_attrinfo,hdfid,index,name=name
endifelsebegin
hdf_sd_attrinfo,varid,index,name=name
endelse
attnames[index]=name
endfor
endif
if(varnamene'')thenhdf_sd_endaccess,varid
return,attnames
END
IDL>kk=HDF_SD_ATTDIR(hdfid,'')
IDL>print,kk
HDFEOSVersionStructMetadata.0missing_valueConventionstitlehistoryinstitution
sourcereferencescommentcontactksnstepptoppintakbkCoreMetadata.0
ArchivedMetadata.0
3)SD的一些概念(即上例打开文件所用的hdfid)
科学数据集即SD(ScienceDataSet)的ID号和已在HDF文件结构中定义的地球物理参数名的关系,然后读取数据HDF_SD_GETDATA到内存中,关闭数据文件HDF_SD_ENDACCESS,HDF_END。
每打开一个HDF文件将会分配个SD_ID,应该是相当于临时的内存号之类的。
(每次的ID值不一样)
IDL>hdfid=hdf_sd_start('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf')
%LoadedDLM:
HDF.
IDL>print,hdfid
393216
IDL>hdfid=hdf_sd_start('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf')
IDL>print,hdfid
17170433
IDL>hdfid=hdf_sd_start('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf')
IDL>print,hdfid
33947650
4)SD方式将已有HDF文件的数据写入单个Vgroup的HDF文件。
以读取MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf的EOSGRID(Vgroup)下的PSdatafield为例:
fid=EOS_GD_OPEN('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf',/READ)
grid=EOS_GD_ATTACH(fid,'EOSGRID')
r7=EOS_GD_FIELDINFO(grid,'PS',rank,dims,numbertype,dimlist)
r6=EOS_GD_READFIELD(grid,'PS',data)
k=dims
pp=fltarr(dims)
pp=data
hdfid=hdf_sd_start('20100531.hdf',/create)
varid=hdf_sd_create(hdfid,'PSD',k,/DFNT_FLOAT32)
dimid=hdf_sd_dimgetid(varid,0)
hdf_sd_dimset,dimid,name='xdim'
dimid=hdf_sd_dimgetid(varid,1)
hdf_sd_dimset,dimid,name='ydim'
dimid=hdf_sd_dimgetid(varid,2)
hdf_sd_dimset,dimid,name='time'
hdf_sd_adddata,varid,data
hdf_sd_attrset,varid,'qym','IDLexamples'
hdf_sd_attrset,hdfid,'creation_data',systime()
hdf_sd_endaccess,varid
hdf_sd_end,hdfid
此程序是将PS中的数据写入到新建的20100531.hdf文件的PSDdatafield中,在HDFview中的效果:
如果在打开它们的时候调整它们的维度选择,以图形方式打开:
注意:
1.在HDFview中自己添加datafield在IDL程序中识别不了。
2.HDFview中不能删去元素。
利用GD方式进行读写
1)多个Vgroup(由gridID标识)打开方法的探究
1.读取Vgroup相关信息
A.相关信息:
Result=EOS_GD_GRIDINFO(gridID,xdimsize,ydimsize,upleft,lowright)---Thisfunctionreturnsthenumberofrows,columnsandthelocation,inmeters,oftheupperleftandlowerrightcornersofthegridimage.
B.Vgroup数目:
Result=EOS_GD_INQGRID(filename,gridlist[, LENGTH=variable])
C.直接从filename和gridname读取相关信息:
Result=EOS_GD_QUERY(Filename,GridName,[Info])
2.读取某个Vgroup下某个属性的相关东西
A.值:
Result=EOS_GD_READATTR(gridID,attrname,datbuf)—值将datbuf中,ReturnsSUCCEED(0)ifsuccessfulandFAIL(–1)otherwise.
B.相关信息:
Result=EOS_GD_ATTRINFO(gridID,attrname,numbertype,count)—Attributename(string).Anamedvariablethatwillcontainthenumbertype(long)ofanattribute.ReturnsSUCCEED(0)ifsuccessfulandFAIL(–1)otherwise.
C.属性数目:
Result=EOS_GD_INQATTRS(gridID,attrlist[, LENGTH=variable])
3.读取某个Vgroup下dataset的相关信息
A.相关信息:
Result=EOS_GD_FIELDINFO(gridID,fieldname,rank,dims,numbertype,dimlist)--Thisfunctionretrievesinformationonaspecificdatafield.
B.dataset数目:
Result=EOS_GD_INQFIELDS(gridID,fieldlist,rank,numbertype)
C.值:
Result=EOS_GD_READFIELD(gridID,fieldname,buffer[, EDGE=array][, START=array][, STRIDE=array])
4.下面以打开MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf分析相关datafields和attributes为例
proanalysisHDF
;根据文件名和Vgroup名获取信息
r1=EOS_GD_QUERY('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf',$
'EOSGRID',Info)
print,'info=',info
;根据文件名获取Vgroup个数信息(好像有些识别不了)--------------------------------
r2=EOS_GD_INQGRID('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf',gridlist,LENGTH=length)
print,gridlist,length
;打开一个确定的Vgroup
;openthefile
fid=EOS_GD_OPEN('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf',/READ)
;getthegrid
grid=EOS_GD_ATTACH(fid,'EOSGRID')
;读取属性数目
r3=EOS_GD_INQATTRS(grid,attrlist,LENGTH=length1)
print,attrlist,length1
;读取_FV_U属性相关信息和值
r4=EOS_GD_ATTRINFO(grid,'_FV_U',numbertype,count)
r5=EOS_GD_READATTR(grid,'_FV_U',datbuf)
print,numbertype,count,datbuf
;读取datafield数目
r6=EOS_GD_INQFIELDS(grid,fieldlist,rank,numbertype)
print,fieldlist,rank,numbertype
;读取名为PS的datafield值和相关信息
r7=EOS_GD_FIELDINFO(grid,'PS',rank,dims,numbertype,dimlist)
r6=EOS_GD_READFIELD(grid,'PS',data)
print,rank,dims,numbertype,dimlist
end
运行结果:
info={missing_valueTIME,Height472
PS,DELP,T,U,V,QV,O3,XDim,YDim,Height,Time
34444
44111
1
55555
55666
6
0
0.000000000.000000000.00000000
0.000000000.000000000.00000000
0.000000000.000000000.00000000
0.000000000.000000000.00000000
0.00000000
0-1
1.8000000e+008-90000000.
-1.8000000e+00890000000.
54036112-1
-111-120}
EOSGRID7
missing_value13
541.00000e+0150.0000000.000000
0.000000
PS,DELP,T,U,V,QV,O3,XDim,YDim,Height,Time3
44444
41111
55555
55666
6
35403614
5XDim,YDim,TIME
其中绿色字体标识的是:
直接从filename和gridname读取相关信息:
Result=EOS_GD_QUERY(Filename,GridName,[Info])中Info的值,参数解释如下:
Field
IDLDataType
Description
ATTRIBUTES
Stringarray
Arrayofattributenames
DIMENSION_NAMES
Stringarray
Namesofdimensions
DIMENSION_SIZES
Longarray
Sizesofdimensions
FIELD_NAMES
Stringarray
Namesoffields
FIELD_RANKS
Longarray
Ranks(dimensions)offields
FIELD_TYPES
Longarray
IDLtypesoffields
GCTP_PROJECTION
Long
GCTPprojectioncode
GCTP_PROJECTION_PARM
Doublearray
GCTPprojectionparameters
GCTP_SPHEROID
Long
GCTPspheroidcode
GCTP_ZONE
Long
GCTPzonecode(forUTMprojection)
IMAGE_LOWRIGHT
Double[2]
Locationoflowerrightcorner(meters)
IMAGE_UPLEFT
Double[2]
Locationofupperleftcorner(meters)
IMAGE_X_DIM
Long
Numberofcolumnsingridimage
IMAGE_Y_DIM
Long
Numberofrowsingridimage
NUM_ATTRIBUTES
Long
Numberofattributes
NUM_DIMS
Long
Numberofdimensions
NUM_IDX_MAPS
Long
Numberofindexeddimensionmappingentries
NUM_MAPS
Long
Numberofdimensionmappingentries
NUM_FIELDS
Long
Numberoffields
NUM_GEO_FIELDS
Long
Numberofgeolocationfieldentries
ORIGIN_CODE
Long
Origincode
PIX_REG_CODE
Long
Pixelregistrationcode
附:
EOSGRID在HDFview中结构图
2)多个Vgroup下的添加HDF文件----------------------------------------------------------现在有问题
;file=filepath('ctscan.dat',subdir='examples/data')
;openr,lun,file,/get_lun
;data=bytarr(256,256)
;readu,lun,data
;free_lun,lun
fid=EOS_GD_OPEN("GDQ.hdf",/CREATE)
help,fid
upleftpt=fltarr
(2)
lowrightpt=fltarr
(2)
upleftpt[0]=10584.50041d
upleftpt[1]=3322395.95445d
lowrightpt[0]=813931.10959d
lowrightpt[1]=214162.53278d
xdimsize=120
ydimsize=200
grid=EOS_GD_CREATE(fid,'WHO',xdimsize,ydimsize,upleftpt,lowrightpt)
help,grid
status=EOS_GD_DETACH(grid)
grid1=EOS_GD_ATTACH(fid,'WHO')
s1=EOS_GD_DEFDIM(grid1,"YDim",2)
s2=EOS_GD_DEFDIM(grid1,"XDim",2)
print,s1,s2
f32=3.14
s4=EOS_GD_WRITEATTR(grid1,"ScalarFloat",f32)
help,s4
s3=EOS_GD_DEFFIELD(grid1,"Temperature","YDim,XDim",5)
help,s3
;temperature=indgen(2,2)
;s2=EOS_GD_WRITEFIELD(grid,"Temperature",temperature)
r6=eos_gd_detach(grid1)
help,r6
r7=eos_gd_close(fid)
help,r7
参考网址:
http:
//hdfeos.org/forums/index.php
http:
//hdfeos.org/forums/archive/index.php?
t-339.html
问题:
1.定义的Vgroup显示成功了,但是在HDFview中看不了()
2.EOS_GD_DEFFIELD总是定义不成功()
3.3写入和读出无格式二进制文件,并利用IDL的一个demo实现3维可视化
1.注意这里是用writeu进行写入,写入的是二进制,如果用printf写入,那就是ASCII码。
probecomedat
hdfid=hdf_sd_start('MERRA300.prod.assim.inst6_3d_ana_Nv.20100531.hdf')
index=hdf_sd_nametoindex(hdfid,'PS')
if(indexlt0)then$
message,'SDSwasnotfound:
'+varname
;-SelectandreadtheSDS
varid=hdf_sd_select(hdfid,index)
hdf_sd_getdata,varid,data
hdf_sd_endaccess,varid
help,data
;data=di