How to Read HDF-EOS5 Swath Data in Fortran

This page explains how to read data fields and geolocation fields from HDF-EOS5 swath data using HDF-EOS5 Fortran APIs. The example will simply read the entire elements in one data field and two geolocation fields, and dump several elements.

First of all, we assume that you have installed the HDF-EOS5 Fortran library correctly. Please make sure that you included -Df2cFortran in the compiler option when you built it. You may want to review our How to build HDF-EOS page.

An HDF-EOS5 file consists of multiple grids, swaths and points. An swath object consists of dimensions, data fields, attributes, geolocation fields and dimension maps. Note that a swath object can have geolocation fields and dimension maps, which are not allowed in a grid object. Geolocation fields provide spatial and/or temporal information of data fields.

In most cases, a swath object has at least two geolocation fields: Longitude and Latitude. As their names indicate, both fields are about locations where elements of data fields were measured.

Briefly speaking, dimension maps can be used to save space by keeping only small number of elements in geolocation fields. The trade-off is that associating geolocation fields with data fields is complicated. For more information about the dimension map, refer to HDF-EOS5 Data Model, File Format and Libraryexternal.

We will use one OMI Aura data. Download the file explained in this page here. This file does not use dimension maps.

Assuming that we know the swath object name, the data field name, and the geolocation field name, we can access the data field through the following steps:

For those who are familiar with the HDF-EOS5 grid interface, the above step is straightforward. All grid interfaces start with he5_gd, and all swath interfaces start with he5_sw.

An HDF-EOS5 API he5_swopen function opens an existing HDF-EOS5 file. The first argument is the file name, and the second argument specifies the mode to access the file. In our example, we just want to read the data. So the mode is the read-only mode.

Figure 1 Opening an HDF-EOS5 swath file
integer swathfileid
swathfileid = he5_swopen
$ ('OMI-Aura_L2-OMAERO_2004m1001t0003-o01132_v003.he5',
$HE5F_ACC_RDONLY)
Note that the file name is OMI-Aura_L2-OMAERO_2004m1001t0003-o01132_v003.he5, not its original name. We renamed the file to avoid an extremely long string in the example code.

This HDF-EOS5 file has one swath object ColumnAmountAerosol. This swath object should be opened using the he5_swattach function to access all data fields, dimensions, attributes and geolocation fields.

Figure 2 Attaching to a swath object
integer swathid
swathid = he5_swattach(swathfileid, 'ColumnAmountAerosol')
The first argument is the descriptor returned by the he5_swopen function. The second argument is the name of the swath object.

ColumnAmountAerosol has several data fields. Let's read data from AerosolIndexUV data field. One can find the datatype, rank and dimension sizes using the HDF Viewexternal Java browser or the h5dumpexternal command-line tool. Assuming that we know the datatype, the rank and dimension sizes of this data field, data can be read using the he5_swrdfld function.

Figure 3 Reading data from a data field
integer status
integer*4 start(2)
integer*4 stride(2)
integer*4 edge(2)
integer*2 indexuv(60,1644)
start(1) = 0
stride(1) = 1
edge(1) = 60
start(2) = 0
stride(2) = 1
edge(2) = 1644
status = he5_swrdfld(swathid, 'AerosolIndexUV'
$ , start, stride, edge,
$indexuv)
The first argument is the descriptor returned by the he5_swattach function. The second argument specifies the name of the data field. The third, fourth and fifth arguments can specify a subset of the data field. Here, we specify the entire elements by setting starting point as (0, 0), stride as (1, 1), and edge (60, 1644). The last argument indexuv is the buffer for the output; the value of the data field is saved in this buffer after the he5_swrdfld function is called. This code assumes that the datatype of this field is the signed 16-bit integer.

If you use a 64-bit machine, you need to change the type of integer*4 to integer*8 for start, stride and edge variables.

Figure 4 Reading data from a data field on 64-bit machine
integer status
integer*8 start(2)
integer*8 stride(2)
integer*8 edge(2)
integer*2 indexuv(60,1644)
start(1) = 0
stride(1) = 1
edge(1) = 60
start(2) = 0
stride(2) = 1
edge(2) = 1644
status = he5_swrdfld(swathid, 'AerosolIndexUV'
$ , start, stride, edge,
$indexuv)
Otherwise, you'll get a run time error even if the unmodified program compiles successfully.

Note that passing insufficient buffer to the he5_swrdfld function results in buffer-overrun. In this example, the data field is a 60-by-1644 array, and its datatype is the 16-bit integer.

On the other hand, ColumnAmountAerosol swath has several geolocation fields including Time, Longitude and Latitude. We will retrieve elements from Longitude and Latitude. The same API, he5_swrdfld, can be used to read data in a geolocation field.

Figure 5 Reading data from geolocation fields
real*4 longitude(60,1644)
real*4 latitude(60,1644)
status = he5_swrdfld(swathid, 'Longitude', start,
$stride, edge, longitude)
status = he5_swfldinfo(swathid, 'Latitude', start,
$stride, edge, latitude)

After retrieving data, the swath object can be detached using the he5_swdetach function. Note that this function and the he5_swattach function form a pair. The descriptor returned by the he5_swattach function is the argument of the he5_swdetach function.

Figure 6 Detaching from the swath object
status = he5_swdetach(swathid)

Now that we get all necessary data from the file, we can close the file. The he5_swclose function closes the file. Its argument is the descriptor returned by the he5_swopen function.

Figure 7 Closing the file
status = he5_swclose(swathfileid)

We have read one data field AerosolIndexUV, and two geolocation fields, Longitude and Latitude, and stored them at indexuv, longitude and latitude, respectively. One can print their values as follows:

Figure 8 Using retrieved data
integer*4 i, j
do i = 1, 1644
do j = 1, 60
write(*,*), approxres(j,i), longitude(j,i), latitude(j,i)
enddo
enddo
This code assumes that those three fields have the same rank and number of elements. Note that this is not the case if dimension maps are used. If dimension maps are used, users need to do interpolation or sampling to get the latitude and longitude values where an element of data fields was measured.

Also, one need to note that data fields can have more dimensions than geolocation fields. For example, a data field AerosolOpticalThicknessMW is a 14-by-60-by-1644 array. Given that Longitude and Latitude are 60-by-1644 arrays, we can conclude that the last two dimensions of the data field are related to both Longitude and Latitude, and the first dimension is related to something else. This implies that 14 elements of the data field are measured at the same location.

As the above code omits some parts, see here to get the full source code. How to build this code is explained here. For more Fortran examples of accessing HDF-EOS5 swath files, click here.


Last modified: 11/11/2020
About Us | Contact Info | Archive Info | Disclaimer
Sponsored by Subcontract number 4400528183 under Raytheon Contract number NNG15HZ39C, funded by NASA / Maintained by The HDF Group