# HDF4 --- Hierarchical Data Format Release 4 (HDF4)

There are two HDF formats, HDF4 (4.x and previous releases) and HDF5. These formats are completely different and NOT compatible. This driver intended for HDF4 file formats importing. NASA's Earth Observing System (EOS) maintains its own HDF modification called HDF-EOS. This modification is suited for use with remote sensing data and fully compatible with underlying HDF. This driver can import HDF4-EOS files. Currently EOS use HDF4-EOS for data storing (telemetry form `Terra' and `Aqua' satellites). In the future they will switch to HDF5-EOS format, which will be used for telemetry from `Aura' satellite.

## Multiple Image Handling (Subdatasets)

Hierarchical Data Format is a container for several different datasets. For data storing Scientific Datasets (SDS) used most often. SDS is a multidimensional array filled by data. One HDF file may contain several different SDS arrays. They may differ in size, number of dimensions and may represent data for different regions.

If the file contains only one SDS that appears to be an image, it may be accessed normally, but if it contains multiple images it may be necessary to import the file via a two step process. The first step is to get a report of the components images (SDS arrays) in the file using gdalinfo, and then to import the desired images using gdal_translate. The gdalinfo utility lists all multidimensional subdatasets from the input HDF file. The name of individual images (subdatasets) are assigned to the SUBDATASET_n_NAME metadata item. The description for each image is found in the SUBDATASET_n_DESC metadata item. For HDF4 images the subdataset names will be formatted like this:

HDF4_SDS:subdataset_type:file_name:subdataset_index

where subdataset_type shows predefined names for some of the well known HDF datasets, file_name is the name of the input file, and subdataset_index is the index of the image to use (for internal use in GDAL).

On the second step you should provide this name for gdalinfo or gdal_translate for actual reading of the data.

For example, we want to read data from the MODIS Level 1B dataset:

    $ gdalinfo GSUB1.A2001124.0855.003.200219309451.hdf
    Driver: HDF4/Hierarchical Data Format Release 4
    Size is 512, 512
    Coordinate System is `'
    Metadata:
      HDFEOSVersion=HDFEOS_V2.7
      Number of Scans=204
      Number of Day mode scans=204
      Number of Night mode scans=0
      Incomplete Scans=0

...a lot of metadata output skipped...

    Subdatasets:
      SUBDATASET_1_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:0
      SUBDATASET_1_DESC=[408x271] Latitude (32-bit floating-point)
      SUBDATASET_2_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:1
      SUBDATASET_2_DESC=[408x271] Longitude (32-bit floating-point)
      SUBDATASET_3_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:2
      SUBDATASET_3_DESC=[12x2040x1354] EV_1KM_RefSB (16-bit unsigned integer)
      SUBDATASET_4_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:3
      SUBDATASET_4_DESC=[12x2040x1354] EV_1KM_RefSB_Uncert_Indexes (8-bit unsigned integer)
      SUBDATASET_5_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:4
      SUBDATASET_5_DESC=[408x271] Height (16-bit integer)
      SUBDATASET_6_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:5
      SUBDATASET_6_DESC=[408x271] SensorZenith (16-bit integer)
      SUBDATASET_7_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:6
      SUBDATASET_7_DESC=[408x271] SensorAzimuth (16-bit integer)
      SUBDATASET_8_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:7
      SUBDATASET_8_DESC=[408x271] Range (16-bit unsigned integer)
      SUBDATASET_9_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:8
      SUBDATASET_9_DESC=[408x271] SolarZenith (16-bit integer)
      SUBDATASET_10_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:9
      SUBDATASET_10_DESC=[408x271] SolarAzimuth (16-bit integer)
      SUBDATASET_11_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:10
      SUBDATASET_11_DESC=[408x271] gflags (8-bit unsigned integer)
      SUBDATASET_12_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:12
      SUBDATASET_12_DESC=[16x10] Noise in Thermal Detectors (8-bit unsigned integer)
      SUBDATASET_13_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:13
      SUBDATASET_13_DESC=[16x10] Change in relative responses of thermal detectors (8-bit unsigned integer)
      SUBDATASET_14_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:14
      SUBDATASET_14_DESC=[204x16x10] DC Restore Change for Thermal Bands (8-bit integer)
      SUBDATASET_15_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:15
      SUBDATASET_15_DESC=[204x2x40] DC Restore Change for Reflective 250m Bands (8-bit integer)
      SUBDATASET_16_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:16
      SUBDATASET_16_DESC=[204x5x20] DC Restore Change for Reflective 500m Bands (8-bit integer)
      SUBDATASET_17_NAME=HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:17
      SUBDATASET_17_DESC=[204x15x10] DC Restore Change for Reflective 1km Bands (8-bit integer)
    Corner Coordinates:
    Upper Left  (    0.0,    0.0)
    Lower Left  (    0.0,  512.0)
    Upper Right (  512.0,    0.0)
    Lower Right (  512.0,  512.0)
    Center      (  256.0,  256.0)

Now select one of the subdatasets, described as `[12x2040x1354] EV_1KM_RefSB (16-bit unsigned integer)`:

    $ gdalinfo HDF4_SDS:MODIS_L1B:GSUB1.A2001124.0855.003.200219309451.hdf:2
    Driver: HDF4Image/HDF4 Internal Dataset
    Size is 1354, 2040
    Coordinate System is `'
    Metadata:
      long_name=Earth View 1KM Reflective Solar Bands Scaled Integers

...metadata skipped...

    Corner Coordinates:
    Upper Left  (    0.0,    0.0)
    Lower Left  (    0.0, 2040.0)
    Upper Right ( 1354.0,    0.0)
    Lower Right ( 1354.0, 2040.0)
    Center      (  677.0, 1020.0)
    Band 1 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 2 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 3 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 4 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 5 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 6 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 7 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 8 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 9 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 10 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 11 Block=1354x2040 Type=UInt16, ColorInterp=Undefined
    Band 12 Block=1354x2040 Type=UInt16, ColorInterp=Undefined

Or you may use gdal_translate for reading image bands from this dataset.

Note that you should provide exactly the contents of the line marked SUBDATASET_n_NAME to GDAL, including the HDF4_SDS: prefix.

This driver is intended only for importing remote sensing and geospatial datasets in form of raster images. If you want explore all data contained in HDF file you should use another tools (you can find information about different HDF tools using links at end of this page).

## Georeference

There is no universal way of storing georeferencing in HDF files. However, some product types have mechanisms for saving georeferencing, and some of these are supported by GDAL. Currently supported are (subdataset_type shown in parenthesis):

- HDF4 files created by GDAL (GDAL_HDF4)
- ASTER Level 1A (ASTER_L1A)
- ASTER Level 1B (ASTER_L1B)
- ASTER Level 2 (ASTER_L2)
- ASTER DEM (AST14DEM)
- MODIS Level 1B Earth View products (MODIS_L1B)
- MODIS Level 3 products (MODIS_L3)
- SeaWiFS Level 3 Standard Mapped Image Products (SEAWIFS_L3)

By default the hdf4 driver only reads the gcps from every 10th row and column from EOS_SWATH datasets. You can change this behaviour by setting the GEOL_AS_GCPS environment variable to PARTIAL (default), NONE, or FULL.

## Creation Issues

This driver supports creation of the HDF4 Scientific Datasets. You may create set of 2D datasets (one per each input band) or single 3D dataset where the third dimension represents band numbers. All metadata and band descriptions from the input dataset are stored as HDF4 attributes. Projection information (if it exists) and affine transformation coefficients also stored in form of attributes. Files, created by GDAL have the special attribute:

"Signature=Created with GDAL (http://www.remotesensing.org/gdal/)"

and are automatically recognised when read, so the projection info and transformation matrix restored back.

Creation Options:

- RANK=n: Create n-dimensional SDS. Currently only 2D and 3D datasets supported. By default a 3-dimensional dataset will be created.

## Metadata

All HDF4 attributes are transparently translated as GDAL metadata. In the HDF file attributes may be assigned assigned to the whole file as well as to particular subdatasets.

## Driver building

This driver builded on top of NCSA HDF library, so you need one to compile GDAL with HDF4 support. You may search your operating system distribution for the precompiled binaries or download source code or binaries from the NCSA HDF Home Page (see links below).

Please note, that NCSA HDF library compiled with several defaults which is defined in hlimits.h file. For example, hlimits.h defines the maximum number of opened files:

    #   define MAX_FILE   32

If you need open more HDF4 files simultaneously you should change this value and rebuild HDF4 library (and relink GDAL if using static HDF libraries).

## See Also:

- Implemented as `gdal/frmts/hdf4/hdf4dataset.cpp` and `gdal/frmts/hdf4/hdf4imagedataset.cpp`.

- The HDF Group

- Sources of the data in HDF4 and HDF4-EOS formats:

  Earth Observing System Data Gateway

Documentation to individual products, supported by this driver:

- Geo-Referencing ASTER L1B Data
- ASTER Standard Data Product Specifications Document
- MODIS Level 1B Product Information and Status
- MODIS Ocean User's Guide