• 【180】IDL 读写 HDF 文件


      HDF(Hierarchical Data Formats)数据格式由 NCSA 开发。HDF 提供了大量的数据模式,包括多维数组、表格、图像、注解和调色板。在下面的章节中,将描述 HDF 科学数据系列(SDS)的数据模式,因为它是 HDF 中最具灵活性的,并且它和 NetCDF 具有相似性。也就是说,HDF SDS 的基本组成也是变量、属性和维数。

          注意:IDL读取数据与在其他软件上显示的数据位置相反,左上对右下!

          注意:HDF记录数据与实际数据是通过一个数量关系获取的,如下图所示:

               实际结果 = 显示结果 × slope + intercept  

            


      数据:可以从 http://www.gumley.com 中下载这些例子的数据文件:

    • EarthProbe5_31_99.hdf
    • Manassas.hdf

    常用的 HDF SDS 程序

    名     称 功     能
    HDF_SD_START() 打开一个 SDS 模式的 HDF 文件
    HDF_SD_END 关闭一个 SDS 模式的 HDF 文件
    HDF_SD_NAMETOINDEX() 返回变量索引
    HDF_SD_SELECT 返回变量标识符
    HDF_SD_GETDATA 读取变量数据
    HDF_SD_ENDACCESS 结束到一个变量的通道
    HDF_SD_ATTRFIND() 返回属性索引
    HDF_SD_ATTRINFO 读取属性数据
    HDF_SD_ATTRFIND() 返回全局属性索引
    HDF_SD_ATTRINFO 读取全局属性数据
    HDF_SD_FILEINFO 返回文件信息
    HDF_SD_GETINFO 返回变量信息
    HDF_SD_ATTRINFO 返回属性名称
    HDF_SD_START() 创建一个 HDF 文件(参数不同)
    HDF_SD_CREATE() 创建一个变量
    HDF_SD_DIMGETID() 创建一个维度
    HDF_SD_DIMSET 设置维度信息
    HDF_SD_ADDDATA 写入变量数据
    HDF_SD_ATTRSET 写入属性数据
    • HDF_SD_START:打开一个 SDS模式的 HDF 文件。
           【函数】返回值是这个 HDF 文件的 SD ID。如果没有设置关键字,则以只读形式打开。
             语法:Result = HDF_SD_START( Filename [, /READ | , /RDWR] [, /CREATE] )
             说明:READ ----- 只读模式,默认模式;
                          RDWR ----- 读写模式;
                          CREATE ----- 创建一个新的 SD 文件。

    • HDF_SD_END:关闭一个 SDS 模式的 HDF 文件。
      语法:HDF_SD_END, SDinterface_id

    • HDF_SD_NAMETOINDEX:返回变量索引。(通过名称获取相应的索引值)
           【函数】返回值为指定 SD 数据集的索引值。
             语法:Result = HDF_SD_NAMETOINDEX(SDinterface_id, SDS_Name)
             说明:SDinterface_id ----- 由 HDF_SD_START 返回的 SD ID 值;
                          SDS_Name ----- 指定 SD 数据集中某个字符串名称。

             代码说明:读取变量中的数组(hdf_sd_nametoindexhdf_sd_selecthdf_sd_getdata
      file='D:IDLA20080200505006.L2_LAC'
      hdfid=HDF_SD_START(file, /rdwr)
      
      ;读取数据中的lat数据
      ;通过latitude来获取相应的索引值
      index=HDF_SD_NAMETOINDEX(hdfid, 'latitude')
      ;通过索引值获取ID值
      varid=HDF_SD_SELECT(hdfid, index)
      ;通过ID值获取数组值
      HDF_SD_GETDATA, varid, latdata
      
    • HDF_SD_SELECT:返回变量标识符。(根据索引值返回相应的 SD 数据集 ID 值)
           【函数】返回值为指定 SD 数据集 ID 值。
            
      语法:Result = HDF_SD_SELECT(SDinterface_id, Number)
             说明:SDinterface_id ----- 由 HDF_SD_START 返回的 SD ID 值;
                          Number ----- SD 数据集索引值。


    • HDF_SD_GETDATA读取变量数据
             语法:HDF_SD_GETDATA, SDdataset_id, Data [, COUNT=vector] [, /NOREVERSE] [, START=vector] [, STRIDE=vector]
             说明:START ----- 每维中读取的第一个元素(从零开始;默认为 [0, 0, ..., 0])
                          COUNT -----每维中读取元素的数目(默认情况是从当前 start 的位置到每维的最后一个元素)
                          STRIDE ----- 在每维中提取的间隔(默认为 [1, 1, ..., 1],意味着每个元素都被选中)
             注意:如果 STARTCOUNT 或 STRIDE 导致变量超出了范围,则 IDL 在读取时将舍去超出的部分,并给出错误信息。
             在下面的例子中,从 0 列、100 行开始读取 100×1 的变量子集,读取时在列的维度上元素一个隔一个地读取(左右)。

            
      代码说明:读取变量数据(hdf_sd_nametoindexhdf_sd_selecthdf_sd_getdata
      IDL> hdfid = hdf_sd_start('EarthProbe5_31_99.hdf')
      IDL> index = hdf_sd_nametoindex(hdfid, 'TOTAL_OZONE')
      IDL> varid = hdf_sd_select(hdfid, index)
      IDL> hdf_sd_getdata, varid, data, start=[0, 100], count=[100,1], stride=[2,1]
      IDL> help, data
      DATA            INT       = Array[100]
      IDL> data[0:3]
           257       0       0     258
      IDL> hdf_sd_endaccess, varid
      IDL> hdf_sd_end, hdfid
      IDL> tvscl, data
      
    • HDF_SD_ENDACCESS结束到一个变量的通道。
             语法:HDF_SD_ENDACCESS, SDinterface_id

             代码说明:访问变量数据后,需要结束(hdf_sd_endaccesshdf_sd_end
      IDL> cd, '..HDF'
      IDL> hdfid = hdf_sd_start('EarthProbe5_31_99.hdf')
      IDL> index = hdf_sd_nametoindex(hdfid, 'TOTAL_OZONE')
      IDL> hdfid
           1441793
      IDL> index
                 0
      IDL> varid = hdf_sd_select(hdfid, index)
      IDL> varid
           1310720
      IDL> hdf_sd_getdata, varid, data
      IDL> help, data
      DATA            INT       = Array[288, 180]
      IDL> data[0:3,0:3]
           415     415     415     415
           411     411     411     411
           395     395     395     395
           386     386     386     386
      IDL> hdf_sd_endaccess, varid
      IDL> hdf_sd_end, hdfid
      IDL> tvscl, data
      
    • HDF_SD_ATTRFIND返回属性索引。(使用 hdfid 读取全局属性)
             语法:Result = HDF_SD_ATTRFIND(SD_id, Name)
             说明:SD_id ----- 由 HDF_SD_START, or HDF_SD_SELECT/HDF_SD_CREATE 得到的 SD ID 值,可以是 hdfid 或者 varid;
                          Name ----- 属性的名称。

    • HDF_SD_ATTRINFO读取属性数据。(使用 hdfid 读取全局属性)
             语法:HDF_SD_ATTRINFO, SD_id, Attr_Index [, COUNT=variable] [, DATA=variable] [, HDF_TYPE=variable] [, NAME=variable] [, TYPE=variable]
             说明:SD_id ----- 由 HDF_SD_START, or HDF_SD_SELECT/HDF_SD_CREATE 得到的 SD ID 值,可以是 hdfid 或者 varid;
                          Attr_Index ----- 索引值;
                         COUNT ----- Set this keyword to a named variable in which the total number of values in the specified attribute is returned.
                         DATA ----- 返回属性数据;
                         HDF_TYPE ----- 返回属性的 HDF type;
                         NAME ----- 返回属性的名称;
                         TYPE ----- 返回数据的类型。

             代码实现:读取属性数据(hdf_attrfindhdf_sd_attrinfohdf_sd_nametoindexhdf_sd_selecthdf_sd_getdata

      IDL> hdfid = hdf_sd_start('Manassas.hdf')
      IDL> index = hdf_sd_nametoindex(hdfid, 'CEL0: ELEVATION')
      IDL> varid = hdf_sd_select(hdfid, index)
      IDL> attindex = hdf_sd_attrfind(varid, 'valid_range')
      IDL> hdf_sd_attrinfo, varid, attindex, data=attvalue
      IDL> attvalue
         17134   17394
      IDL> hdf_sd_attrinfo, varid, attindex, COUNT=count , DATA=data, HDF_TYPE=HDF_type , NAME=name , TYPE=type
      IDL> count
                 2
      IDL> data
         17134   17394
      IDL> hdf_type
      DFNT_INT16
      IDL> name
      valid_range
      IDL> type
      INT 
      
    • HDF_SD_FILEINFO返回文件信息。
             语法:HDF_SD_FILEINFO, SDinterface_id, Datasets, Attributes
             说明:SDinterface_id ----- 由 HDF_SD_START 返回的 SD ID 值;
                          Datasets ----- 变量的总数;
                          Attributes ----- 全局属性的总数。

    • HDF_SD_GETINFO:返回变量信息。
             语法:HDF_SD_GETINFO, SDdataset_id [, CALDATA=variable] [, COORDSYS=variable] [, DIMS=variable] [, FILL=variable] [, FORMAT=variable] [, HDF_TYPE=variable] [, LABEL=variable] [, NAME=variable] [, NATTS=variable] [, NDIMS=variable] [, /NOREVERSE] [, RANGE=variable] [, TYPE=variable] [, UNIT=variable]
             说明:SDdataset_id ----- varid,SD 数据集 ID,变量 ID;
                          NATTS ----- 属性的数目;
                          NDIMS ----- 维度的数目;
                          DIMS ----- 具体的维度。

             代码实现:获取变量信息(hdf_sd_getinfohdf_sd_select

      IDL> hdfid = hdf_sd_start('Manassas.hdf')
      IDL> hdf_sd_fileinfo, hdfid, nvars, ngatts
      IDL> nvars
                 1
      IDL> ngatts
                 6
      IDL> hdfid = hdf_sd_start('EarthProbe5_31_99.hdf')
      IDL> hdf_sd_fileinfo, hdfid, nvars, ngatts
      IDL> nvars
                 4
      IDL> ngatts
                 0
      IDL> varid = hdf_sd_select(hdfid, 0)
      IDL> hdf_sd_getinfo, varid, name=name, ndims=ndims, type=type, dims=dims
      IDL> name
      TOTAL_OZONE
      IDL> ndims
                 2
      IDL> type
      INT
      IDL> dims
               288         180
      IDL> hdf_sd_getinfo, varid, name=name, ndims=ndims, type=type, dims=dims, unit=unit, format=format
      IDL> unit
      MATM_CM
      IDL> format
      I3
      
    • HDF_SD_ATTRINFO返回属性名称(使用 hdfid 读取全局属性)
             语法:HDF_SD_ATTRINFO, SD_id, Attr_Index [, COUNT=variable] [, DATA=variable] [, HDF_TYPE=variable] [, NAME=variable] [, TYPE=variable]
             说明:SD_id ----- 由 HDF_SD_START, or HDF_SD_SELECT/HDF_SD_CREATE 得到的 SD ID 值,可以是 hdfid 或者 varid;

             代码实现:读取指定属性的信息(hdf_sd_attrinfo

      IDL> hdf_sd_attrinfo, varid, 0, count=count, data=data, HDF_type=hdf_type, name=name, type=type
      IDL> count
                 1
      IDL> data
             1.0000000000000000
      IDL> hdf_type
      DFNT_FLOAT64
      IDL> name
      scale_factor
      IDL> type
      DOUBLE
      
    • HDF_SD_CREATE:创建一个变量
             【函数】The HDF_SD_CREATE function creates and defines a Scientific Dataset (SD) for an HDF file. Keywords can be set to specify the data type. If no keywords are present a floating-point dataset is created.
               语法:Result = HDF_SD_CREATE( SDinterface_id, Name, Dims [, /BYTE] [, /DFNT_CHAR8] [, /DFNT_FLOAT32] [, /DFNT_FLOAT64] [, /DFNT_INT8] [, /DFNT_INT16] [, /DFNT_INT32] [, /DFNT_UINT8] [, /DFNT_UINT16] [, /DFNT_UINT32] [, /DOUBLE] [, /FLOAT] [, HDF_TYPE=type] [, /INT] [, /LONG] [, /SHORT] [, /STRING] )

               参考:idl下Hdf5格式文件的读取并转换为hdf
               参考:Adding a product to l1a - l2 processing sequence
               代码实现:新建HDF文件,并添加变量值(hdf_sd_createhdf_sd_adddata
        ;新建HDF的文件路径
        file='D:IDLsst13.hdf'
        ;以create的形式打开文件
        hdfid=HDF_SD_START(file, /create)
        ;新建latitude变量,在HDF上显示1354列,2040行,默认是浮点型数组
        sds_id=HDF_SD_CREATE(hdfid, 'latitude', [1354, 2040], /float)
        ;由于从HDF中读取的数据与实际数据存在一个中心对称的关系,因此通过两个reverse实现
        ;latdata就是从其他HDF中读取的数组,将数组的结果添加到变量latitude中去
        HDF_SD_ADDDATA, sds_id, reverse(reverse(latdata), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'longitude', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(londata), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'sst', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(sstdata1), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'sd', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(sddata1), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'tsm', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(tsmdata1), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'chl', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(chldata1), 2)
        
        sds_id=HDF_SD_CREATE(hdfid, 'chlor_a', [1354, 2040], /float)
        HDF_SD_ADDDATA, sds_id, reverse(reverse(chlordata1), 2)
        
        HDF_SD_ENDACCESS, sds_id
        HDF_SD_END, hdfid
      

    • HDF_SD_DIMGETID:创建一个维度
           【函数】返回值为维度标识符。
             语法:Result = HDF_SD_DIMGETID(SDdataset_id, Dimension_Number)

    • HDF_SD_DIMSET:设置维度信息
             语法:HDF_SD_DIMSET, Dim_ID [, /BW_INCOMP] [, FORMAT=string] [, LABEL=string] [, NAME=string] [, SCALE=vector] [, UNIT=string]

    • HDF_SD_ADDDATA:写入变量数据(修改变量的值)
             语法:HDF_SD_ADDDATA, SDdataset_id, Data [, COUNT=vector] [, /NOREVERSE] [, START=vector] [, STRIDE=vector]

             代码实现:参见 hdf_sd_create 代码实现

    • HDF_SD_ATTRSET:写入属性数据(将某个变量的某个属性值进行修改)
             语法:HDF_SD_ATTRSET, SD_id, Attr_Name, Values [, Count] [, /BYTE] [, /DFNT_CHAR] [, /DFNT_FLOAT32] [, /DFNT_FLOAT64] [, /DFNT_INT8] [, /DFNT_INT16] [, /DFNT_INT32] [, /DFNT_UINT8] [, /DFNT_UINT16] [, /DFNT_UINT32] [, /DOUBLE] [, /FLOAT] [, /INT] [, /LONG] [, /SHORT] [, /STRING]
  • 相关阅读:
    【HeadFirst设计模式学习笔记】10 组合模式
    【HeadFirst 设计模式学习笔记】12 代理模式
    【HeadFirst 设计模式学习笔记】15 享元模式拾零
    【HeadFirst 设计模式学习笔记】16 建筑者(Builder)模式拾零
    【HeadFirst 设计模式学习笔记】11 状态模式
    搜索引擎设计实用教程(1)以百度为例 之一:查询处理以及分词技术
    最容易写错的100个字
    看完这个我流泪了,人生有太多的误会和无奈……
    哈佛成功金言
    上海的朋友注意了,周六气温可能骤降到1℃
  • 原文地址:https://www.cnblogs.com/alex-bn-lee/p/4978157.html
Copyright © 2020-2023  润新知