【问题标题】:Reading array of floats from HDF5 file in Fortran从 Fortran 中的 HDF5 文件中读取浮点数组
【发布时间】:2017-09-24 04:32:51
【问题描述】:

我可以使用 h5py 在 Python 中创建 HDF5 文件,例如

    import numpy as np
    import h5py


    outfile = np.zeros((5,2))
    for i in range(5):
        outfile[i] = i


    print(outfile)
    print(outfile.dtype)

    f = h5py.File('TF.hdf5', 'w')
    dset = f.create_dataset('FT', data = outfile, dtype = 'd')

这会打印数据,验证数据是否为float64 类型,然后将数据保存到 HDF5 文件中,使数据类型明确。

然后我可以在 Fortran 中读取这个 HDF5 文件,

    PROGRAM HDF_READER

    USE HDF5

    USE HDF5 ! This module contains all necessary modules

    IMPLICIT NONE

    CHARACTER(LEN=8), PARAMETER :: filename = "TF.hdf5" ! File name
    CHARACTER(LEN=4), PARAMETER :: dsetname = "FT"     ! Dataset name

    INTEGER(HID_T) :: file_id       ! File identifier
    INTEGER(HID_T) :: dset_id       ! Dataset identifier
    INTEGER(HID_T) :: space_id       ! Dataspace identifier
    INTEGER(HID_T) :: dtype_id       ! Dataspace identifier

    INTEGER     ::   error ! Error flag
    INTEGER     ::  i, j, cols, rows

    REAL(KIND = 8), DIMENSION(:,:), ALLOCATABLE :: dset_data
    INTEGER(HSIZE_T), DIMENSION(2) :: data_dims
    INTEGER(HSIZE_T), DIMENSION(2) :: max_dims                  


    print *, 'Starting HDF5 Fortran Read'



   ! Initialize FORTRAN interface.

   CALL h5open_f(error)


   ! Open an existing file.

   CALL h5fopen_f (filename, H5F_ACC_RDWR_F, file_id, error)


   ! Open an existing dataset.

   CALL h5dopen_f(file_id, dsetname, dset_id, error)


   !Get dataspace ID
   CALL h5dget_space_f(dset_id, space_id,error)


   !Get dataspace dims

   CALL h5sget_simple_extent_dims_f(space_id,data_dims, max_dims, error)

   cols = data_dims(1)
   rows = data_dims(2)

   !Allocate dimensions to dset_data for reading
   ALLOCATE(dset_data(cols, rows))


   !Get data
   CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, dset_data, data_dims, error)



   print *, dset_data

   CALL h5close_f(error)



   END PROGRAM HDF_READER

但是,这会打印出一堆极端数字,表明没有从 HDF5 文件中正确读取数据。

然而如果我将我的dset_data 数组设置为整数类型,即INTEGER, DIMENSION(:,:), ALLOCATABLE :: dset_data,那么就没有问题,并且整数数字打印正确。

关于如何使它适用于双精度浮点数的任何想法?

谢谢

【问题讨论】:

    标签: python fortran gfortran hdf


    【解决方案1】:

    在 HDF5 中,数据以给定的数据类型存储。读取数据时,您还可以明确指定“内存中”数据类型。 HDF5 将处理文件内部 的文件格式,并将其动态转换(如果需要)为您指定的“内存中”数据类型。 Fortran 中的 HDF5 基于 C 库,最终需要知道这些信息。

    因此,您必须指定数组的数据类型,而不是 H5T_NATIVE_INTEGER。在这里,real(kind=8) 可能是H5T_NATIVE_DOUBLE,但你不妨声明你的数组double precision 我会说。

    您会看到整数的正确数据,因为您将圆形浮点数存储在文件中。否则结果会在读取时四舍五入。

    【讨论】:

    • 非常感谢!出于兴趣,您知道 Fortran 的 HDF 资源吗?
    • 我可以指向特定的库,例如 Thomas Robitaille github.com/astrofrog/fortranlib/blob/master/src/lib_hdf5.f90 的通用库和我的一个专注于附加分子轨迹的库 github.com/pdebuyl/fortran_h5md 他们可以让您了解“如何使用”HDF5 和 Fortran。否则,我广泛使用官方 HDF5 参考
    • 在现代 Fortran 中比双精度更好的是使用 h5kind_to_type 来获取一种数据类型到 HDF5 句柄的映射。并且不要使用明确的种类。 Kind=8 for reals 是不可移植的,我可以向您展示它中断的示例。使用 selected_real_kind 或 iso_fortran_env 内部模块中的常量
    • 谢谢你们的帮助
    猜你喜欢
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多