!
! This example shows how to write and read a hyperslab.  
!

     PROGRAM H5_HYPEF 

     USE HDF5 ! This module contains all necessary modules 
        
     IMPLICIT NONE

     CHARACTER(LEN=8), PARAMETER :: filename = "hypef.h5"  ! File name
     CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name

     INTEGER(HID_T) :: file_id       ! File identifier 
     INTEGER(HID_T) :: dset_id       ! Dataset identifier 
     INTEGER(HID_T) :: dataspace     ! Dataspace identifier 
     INTEGER(HID_T) :: memspace      ! memspace identifier 

     !
     ! To change the subset size, modify size of dimsm, sdata, dim0_sub,
     ! dim1_sub, and count
     !
     INTEGER(HSIZE_T), DIMENSION(2) :: dimsm = (/3,4/) ! Dataset dimensions
     INTEGER, DIMENSION(3,4) :: sdata                  ! Subset buffer
     INTEGER :: dim0_sub = 3   
     INTEGER :: dim1_sub = 4 
     INTEGER(HSIZE_T), DIMENSION(2) :: count = (/3, 4/) ! Size of hyperslab
     INTEGER(HSIZE_T), DIMENSION(2) :: offset = (/1,2/) ! Hyperslab offset
     INTEGER(HSIZE_T), DIMENSION(2) :: stride = (/1,1/) ! Hyperslab stride 

     INTEGER(HSIZE_T), DIMENSION(2) :: dimsf = (/8,10/) ! Dataset dimensions


     INTEGER, DIMENSION(8,10) :: data     ! Data to write
     INTEGER, DIMENSION(8,10) :: rdata    ! Data to read 

     INTEGER :: rank = 2     ! Dataset rank ( in file )
     INTEGER :: dim0 = 8     ! Dataset size in file
     INTEGER :: dim1 = 10
 
     INTEGER :: i, j, k 

     INTEGER :: error        ! Error flag
     INTEGER(HSIZE_T), DIMENSION(2) :: data_dims


   !
   ! Write data to the HDF5 file.  
   !

     !
     ! Data initialization. 
     !
     do i = 1, dim1 
          do j = 1, dim0 
             if (i .le. (dim1 / 2)) then
               data(j,i) = 1 
             else 
               data(j,i) = 2 
             end if
          end do
     end do
     
     !
     ! Initialize FORTRAN interface. 
     !
     CALL h5open_f(error) 

     !
     ! Create a new file using default properties.
     ! 
     CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error)

     !
     ! Create the data space for the  dataset. 
     !
     CALL h5screate_simple_f(rank, dimsf, dataspace, error)

     !
     ! Create the dataset with default properties.
     !
     CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, dataspace, &
                      dset_id, error)

     !
     ! Write the dataset.
     !
     data_dims(1) = dim0 
     data_dims(2) = dim1 
     CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, data, data_dims, error)

     !
     ! Data Written to File 
     !
     print *, "Original Data Written to File:"
     do i = 1, dim0 
         print *, (data(i,j), j = 1, dim1)
     end do
     print *, " "

     !
     !
     ! Close the dataspace, dataset, and file.
     !
     CALL h5sclose_f(dataspace, error)
     CALL h5dclose_f(dset_id, error)
     CALL h5fclose_f(file_id, error)

     !
     ! Initialize subset data array.
     !
     do i = 1, dim0_sub
          do j = 1, dim1_sub
                  sdata(i,j) = 5
          end do
     end do

     !
     ! Open the file.
     !
     CALL h5fopen_f (filename, H5F_ACC_RDWR_F, file_id, error)
       
     !
     ! Open the  dataset.
     !
     CALL h5dopen_f(file_id, dsetname, dset_id, error)

     !
     ! Get dataset's dataspace identifier and select subset.
     !
     CALL h5dget_space_f(dset_id, dataspace, error)
     CALL h5sselect_hyperslab_f(dataspace, H5S_SELECT_SET_F, &
                                offset, count, error, stride) 
     !
     ! Create memory dataspace.
     !
     CALL h5screate_simple_f(rank, dimsm, memspace, error)

     !
     ! Write subset to dataset  
     !
     data_dims(1) = dim0_sub 
     data_dims(2) = dim1_sub 
     CALL H5dwrite_f(dset_id, H5T_NATIVE_INTEGER, sdata, data_dims, error, &
                    memspace, dataspace)

     data_dims(1) = dim0 
     data_dims(2) = dim1 
     CALL H5dread_f(dset_id, H5T_NATIVE_INTEGER, rdata, data_dims, error, &
                    H5S_ALL_F, H5S_ALL_F)
     
     !
     ! Read entire dataset back 
     !
     print *,"Data After Subset Written to File:"
     do i = 1, dim0 
         print *,(rdata(i,j), j = 1, dim1)
     end do
     print *, " "
 
     !
     ! Close everything opened.
     !
     CALL h5sclose_f(dataspace, error)
     CALL h5sclose_f(memspace, error)
     CALL h5dclose_f(dset_id, error)
     CALL h5fclose_f(file_id, error)

     !
     ! Close FORTRAN interface.
     !
     CALL h5close_f(error)

     END PROGRAM H5_HYPEF 

