Writing and Reading a HDF-EOS File


The following sections detail how a user may utilize the commands of the HDF-EOS APIs within a computer program to write or read data in HDF/HDF-EOS. As a teaching tool, this tutorial will concentrate on using the FORTRAN programming language and mainly focus on the Swath and Grid interfaces for examples. Many of the steps are very similar to those outlined in Section 15 - Writing a SDS to an HDF File and Section 16 - Reading a SDS from an HDF File and some material will be a duplicate from these sections. In other instances, the reader will be referred back for certain detailed discussions. In a simplistic form the novice user should pay attention to the following questions


Previous Main Topic

Next Main Topic

Return to Main Topics

 

Is the HDF library installed on the user's platform?

The user should make sure that the HDF library is previously installed. As detailed elsewhere in the tutorial, the HDF-EOS library is an extension of and built upon the base HDF libray and thus needs the HDF library to be properly installed as discussed inSection 4 - The HDF Library.

Does the current version of HDF support your computer platform?

As outlined in Section 5 - The HDF-EOS Library, the HDF-EOS library can be run on the following platforms: Sun Sparc, Dec Alpha, HP 9000, SGI, IBM RS6000, and PC-Windows. Before downloading the library software, the user should make sure that the current release of HDF-EOS supports his/her computer and operating system.

Return to top

How do I download and install the HDF-EOS library?

The HDF-EOS library and software is public domain software and available free to all users. The library and code can be downloaded from the several places, including the GSFC HDF-EOS Information Resources Pageunder the heading/button of "original HDF-EOS". Directions on how to install the HDF-EOS library can also be found at this location as well as briefly documented in Section 5 - The HDF-EOS Library.

Return to top

Are all libraries and programs properly linked and compiled?

In order to make use of the HDF-EOS APIs, the library and the needed application routines and programs must first be properly compiled and linked.

The HDF-EOS include and library files must be accessed in order to compile and link the program. The following can be done within the user's makefiles:

	INCLUDE = -I. -I$(HDFEOS_INC) -I$(HDFINC)	
	LIBRARY = -L. -L(HDFEOS_LIB) -L$(HDFLIB)	
	LDFLAGS = -lhdfeos -1Gctp -lmfhdf -ldf -ljpeg -lnsl -lz -lm       (For Sun Systems)	
	LDFLAGS = -lhdfeos -1Gctp -lmfhdf -ldf -ljpeg -lz -lm       (Others)	

To compile a C or FORTRAN program (as an example, readswath.c) that utilizes the HDF-EOS library, the user may also use the following:

	cc -DHDFSYS -o readswath.o -I$HDFINC -I$HDFEOS INC -c readswath.c	
	cc -DHDFSYS -o readswath readswath.o -L$HDFLIB -L$HDFEOS LIB/	
	-lhdfeos -lGctp -lmfhdf -ldf -ljpeg -lz -lnsl -lm	

Just as with the HDF library, the order of the libraries is important and should not be switched. Please note that both the HDF and HDF-EOS libraries are being linked, with the HDF-EOS library coming first. The "-lGctp" is for the map projections for gridded HDF-EOS data.

Return to top

How do I write a program to write/read data using HDF-EOS

The next seven steps are mainly for the writing data using the HDF-EOS APIs


or

Finally, for all programs

Return to top

Select a programming language

As mentioned previously, the HDF and HDF-EOS library and programs can only be run by using either the C or FORTRAN programming language. This choice is up to the user depending on availability and the language he or she feels most familiar and comfortable with. All HDF-EOS API routines which allow the user to work with swath/grid data sets either have the "sw"/"gd" prefix (FORTRAN) or the "SW"/"GD" prefix (C). Examples of the routines used to open, create, read, write, etc. SDS are given in the following sections.

Return

Make sure all include files are in place

As HDF-EOS data sets and files are actually HDF data sets with added geolocation inforamtion, this step is very similar to the steps shown for working with the HDF library. In section 4 - The HDF Library: Software and Hardware , it was noted that a series of standard HDF definitions and declarations of file access codes (i.e. read, write, etc.) and data types (i.e. integer, character) must be included within the programs that the user writes to utilize the various application routines. In the C programs, this is accomplished simply by adding the line #include "hdf.h" at the beginning of the program. This line effectively includes all the needed constants and definitions from the HDF software. When writing FORTRAN programs, this may also be done by simply adding an include statement that brings in only the needed definitions and declarations (constants.f) from the hdf.h header file. This is done by the following code: "include constants.f". However, all FORTRAN compilers (particularly the older ones) do not support the use of include statements. In this event, the user must type in/declare all the constants and definitions found in the constants.f file. It is advised that all declarations, whether through include statements or not, should be done at the beginning of the program.

Return

Make all variable and parameter declarations

As with any program, the scientist/user should declare and initialize all variables and parameters at the beginning of the program. This includes all variables and arguments that will be used by the HDF/HDF-EOS commands to follow.

Return

Open file containing existing non-HDF/HDF-EOS data set and store in array

Before writing any data into HDF or HDF-EOS, the actual data first has to be accessed within the program. As is normally done in non-HDF applications, the file containing the data that the user wishes to convert into HDF must first be opened. After opening the file, the user reads and stores the data into a multi-dimensional array that can be accessed by the HDF commands.

As an example a non-HDF data set can be read from an existing file called wind.dat into a multi-dimensional real arrays called rwind(XL,YL), lat(XL,YL), Long(XL,YL) where XL= 30 and YL = 30.

FORTRAN:

        real rwind(30,30),lat(30,30),long(30,30)
XL = 30
YL = 30
Open(unit=15, file='wind.dat',form='formatted')
Do I=1,XL
Do j=1,YL
Read(15,25)rwind(I,J),lat(i,j),long(i,j)
Enddo
Enddo

Return

Initialize access to the SW/GD interface and open new HDF file

In this case, we will be writing grid or swath data to an existing HDF file. The first programming step actually accomplishes 2 things:

This is done by the following code:

	swfid = swopen(filename, access_mode)  (FORTRAN)

gdfid = gdopen(filename, access_mode)

or

	swfid = SWopen(filename, access_mode);  (C)

gdfid = GDopen(filename, access_mode);

where

	swfid = HDF file id returned by the swopen/SWopen command
gdfid = HDF file id returned by the gdopen/GDopen command
filename = the name of the new HDF file (character string)
access_mode = Type of access required for this file

All available options for the access-mode argument are defined in the hdf.h header file mentioned previously and need only to be identified for all C and most FORTRAN operations. All options begin with the prefix "DFACC_" and include:

	DFACC_CREATE (File Creation Access)
DFACC_RDONLY (Read Access)
DFACC_RDWR (Read and Write Access)

In the event that the user's FORTRAN compiler can not handle include statements such as those found in the hdf.h header file, the DFACC_ variable must be defined, along with its assigned value, at the beginning of the program. This is done by code lines such as:

	parameter (DFACC_RDONLY = 1) (For FORTRAN only)
parameter (DFACC_CREATE = 4)

As an example, we can call an existing file swath1.hdf or grid1.hdf and:

FORTRAN:


parameter (DFACC_RDWR = 3)
swfid = swopen(swath1.hdf, DFACC_RDWR)
gdfid = gdopen(grid1.hdf, DFACC_RDWR)

If the swath or grid file can not be found a -1 will be returned for swfid or gdfid.

Return

Open or create a HDF-EOS Swath object

After initializing the SW interface and opening and assigning a file id (swfid) to the HDF file to be used, the next step is to open or create a swath data set by obtaining a swath id (swid). For a swath, we have the following:

	swid = swcreate (swfid, name) (FORTRAN)

or

	swid = SWcreate (swfid, name); ( C )

 

(It should be noted that swattach/SWattach may also be used to write to a previously defined HDF data set.)

where

	swid = swath id returned by the swcreate/SWcreate command
swfid = the new HDF file id created in the previous step (swopen/SWOPEN)
name = name of new swath

Open or create a HDF-EOS Grid object

For grid data sets, a little more information is needed when a new grid is created. To create a new grid, we also need to specify information about the map projection and the grid resolution. This can be done as follows:
	gdid= gdcreate(gdfid,gridname,xdim,ydim,upleft,lowright)      (FORTRAN)
or
	gdid= GDcreate(gdfid,gridname,xdim,ydim,upleft,lowright)      (C)
where
	gdfid = grid file id returned by gdopen/GDopen
gridname = name of grid to be created
xdim = number of columns in i direction
ydim = number of rows in j direction
upleft = location of upper left corner (lat/long)
lowright = location of lower right corner (lat/long)

As an example, for a grid to be named "geogrid" with a geographic projection between 30N and 60N and 120W and 150W, with a resolution of 1 degree in both the x(long) and y(lat) direction, we would have the following FORTRAN code:

	projcode=0   !for geographic map projection)
xdim=30
ydim=30
uleft(1)=120000000.00 !x or longitude
uleft(2)=60000000.00 !y or latitude
lright(1)=150000000.00 !x or longitude
lrigh(2)=30000000.00 !y or latitude
c
	gdid=gdcreate(gdfid. Geogrid,xdim,ydim,uleft,lright)

As with the swath, it should be boted that the GDattach/gdattach commands can be used to write to existing grids and that a -1 will be returned for gdid if there is an error.

For grids, the GCTP projection and projection parameters then need to be defined using:

	status=gddefproj(gdid,projcode,zonecode,spherecode,projparam)      (FORTRAN)
or
	status=GDdefproj(gdid,projcode,zonecode,spherecode,projparam)      (C)
where
	gdid = grid id returned by gdcreate/GDcreate
projcode= GCTP projection code
zonecode= GCTP zone code
spherecode= GCTP spheroid code
projparam= GCTP projection parameters (array)

The zonecode is only non-zero for the UTM projection. A listing of all the projection, zone, and spheroid codes can can be found in Volume 1, Chapter 6 of the HDF-EOS Library User's Guide. For the geographic projection mentioned above, only the GCTP projection code in non-zero ((GCTP_GEO) so we have:

	status=gddefproj(gdid,GCTP_GEO,0,0,0)       (FORTRAN)
status=GDdefproj(gdid,GCTP_GEO,NULL,NULL,NULL) (C)

Return

Define dimensions

The next step in the process might be to define dimensions (name and size) that will be used to define the size of the wath and grid fields later on. The GD API commands gddefdim/GDdefdim for grids could be substituted for the the use of the swath commands below:

	status= swdefdim(swid, filename, dimsize)   (FORTRAN)

or

	status=SWdefdim(swid, filename, dimsize; ( C )

where

	swid = swath id returned by the swcreate/SWcreate command
fieldname = name of dimension
dimsize= size of dimension

This command be used in FORTRAN in the following manner:

	status=swdefdim(swid,Geotrack,30)      
status=swdefdim(swid,Geo_cross_track,30)

Return

Define data fields

After defining the dimensions, the next logical step might be to define the data and geolocation fields to be written to. First off, we define the new data fields within a grid or swath. For grids (swaths would have the same form), the commands would be:

	status=gddeffld(gdid, fieldname, dimlist,  number type, merge)   (FORTRAN)

or

	status=GDdeffield(gdid, fieldname, dimlist, number type, merge); ( C )

where

	gdid = grid id returned by the gdcreate/GDcreate command
fieldname = name of data field to be defined
dimlist= list of data dimensions defing the field (string)
merge= merge code (HDFE_NOMERGE for no merging)
number type= numbe type of data

This argument always takes the form of DFNT_X, where X is the data type to be used. A list of all the data types supported by the API can be found in the HDF User's Guide. For most of the data types, 8,16,32 and 64-bit types are supported. A few of the available options are provided below:

 


HDF Data Type Description
DFNT_FLOAT32 32 bit floating point real
DFNT_DOUBLE double precision reals
DFNT_CHAR8 8 bit character type
DFNT_UCHAR8 8 bit unsigned character type
DFNT_INT16 16 bit integer type
DFNT_UINT16 16 bit unsigned integer type
DFNT_NINT16 16 bit native integer
DFNT_NUINT16 16 bit native unsigned integer
DFNT_NFLOAT32 32 bit native floating point real

Similar to the DFACC_ argument, all data types are defined in hdf.h. Once again, for FORTRAN compilers unable to access these include files, the DFNT_ argument, and its' assigned value, must be defined at the beginning of the program using code like this:

	parameter (DFNT_INT16 = 22) (taken from constants.f within the hdf.h file)

An example of this command would be something like (in FORTRAN):

	xdim=30      
ydim=30
status=gddeffld(gdid,wind,"xdim,ydim",DFNT_FLOAT32,0)

The Swath API can be used similarly to define fields along the satellite cross track (GeoXTrack) and alongtrack (DeoTrack) dimensions with the following:

	status=swdeffld(swid,wind,"GeoTrack,GeoXTrack,DFNT_FLOAT32,0)

Return

Define Geolocation fields

While the projection information mentioned previously is used to define the geolocation fields for grids, the geolocation fields for swaths can be defined using the SWdefgeofld/swdefgfld where:

	status=swdefgfld(swid, fieldname, dimlist,  number type, merge)   (FORTRAN)

or

	status=SWdefgeofld(gdid, fieldname, dimlist, number type, merge); ( C )

where all paramaters are as before.

The most important geolocation fields needed for swaths are latitude and longitude. A FORTRAN example of this command would be:

	status=swdefgeofld(swid,latitude,"GeoTrack,GeoXTrack",DFNT_FLOAT32,0)     
status=swdefgeofld(swid,latitude,"GeoTrack,GeoXTrack",DFNT_FLOAT32,0)

Return

Define mapping relationships (for swaths)

If dealing with swaths, the relationship between the geolocation dimensions and the data dimensions must be defined. This can be done using the following command:

	status=swdefmap(swid, geodim, datadim,  offset, increment)   (FORTRAN)

or

	status=SWdefdimmap(swid, geodim, datadim,  offset, increment); ( C )

where

	swid = swath id returned by the swcreate/SWcreate command
geodim = geolocation dimension name
datadim= data dimension name
offset= offset between geolocation and data dimensions
increment= increment of geolocation dimensions with respect to the data dimensions

It should be noted that both the offset and increment paramaters can have both positive and negative valeus. In most cases, the data dimensions and geolocation dimensions are the same (offset=0; increment=0) but, in some cases, the data dimensions (size of the data array) might be smaller or thinned in comparison to the geolocation dimensions (or visa versa). The latter would have negative values for offset and increment. A possible example would be to have data for every second geolocation point. Thus the offset= -1 and increment= -2.

An example for Swath dimension (GeoTrack, GeoXTrack) in FORTRAN would be:

	status=swdefmap(swid,"GeoTrack",xdim,0,0)
status=swdefmap(swid,"GeoXTrack",ydim,0,0)

Return

Detaching and re-attaching the HDF-EOS APIs

The detaching of the APIs is done to store the swath or grid information AND must always be done before re-attaching to read or write a swath. The example for the Swath API is provided below, with the only change needed for the Grid API is to change the command name (substitute gd for sw and GD for SW):

	status=swdetach(swid)   		(FORTRAN)
swid=swattach(swfid, swathname)

or

	status=SWdetach(swid);   	(C)
SWattach(swfid, swathname)

Return

Write existing data set/array to a new data array in HDF/HDF-EOS

The next step is to actually write the existing non-HDF data into the HDF/HDF-EOS data fields in the HDF file. This is done using the following command:

	status=swwrfld(swid,fieldname,start,stride,edge,data) (FORTRAN)
status=gdwrfld(gdid,fieldname,start,stride,edge,data)

or

	status=SWwritefield(swid,fieldname,start,stride,edge,data) (C)
status=GDwritefield(gdid,fieldname,start,stride,edge,data)

where

	swid= swath id returned by SWcreate/swattach
gdid= grid id returned by GDcreate/gdattach
fieldname=Name of field to write
start= Array defining the starting location of each dimension
stride= Array defining number of values to skip or increment
edge= Array defining total number of values to write in each dimension
data= data array to be written

This command is identical to those used for the HDF SD API and a complete description of these parameters is given in Section 15 - Writing a SDS to an HDF file as well as the HDF User's Guide. An example (FORTRAN) of how to use this command is:

	status=swwrfld(swid,Wind,0,0,0,rwinddat)
status=swwrfld(swid,latitude,0,0,0,rlat)
status=gdwrfld(gdid,longitude,0,0,0,rlong)


Return

Optional operation: Provide metadata for HDF-EOS files or data sets

More of this is also discussed in Section 12 - Attributes and Metadata in HDF-EOS, but the following commands can be used to write attributes in a grid or swath. The example below is for a Swath, but grids can be done in the same fashion.

	status=swwrattr(swid, attrname,ntype,count,data)   (FORTRAN)

or

	status=SWwriteattr(swid, attrname,ntype,count,data)   (C);

where

	swid = swath id returned by the swcreate/SWcreate command
attrname= name of attribute
ntype= number type of attribut (described previously)
count= number of values in each attribute
data= attribute values (character string in ODL is an option).

Return

Reading from an HDF-EOS data set/file

As with the writing of the data set to an existing file, an existing file (and the HDF-EOS API) must be opened and attached as shown previously. Information on attributes, geolocation fields, data fields, dimensions, etc.. can be obtained using the commands outline in Section 14 - Obtaining Information on Existing HDF-EOS Files. Upon knowing the names and informatiom on these fields, the HDF-EOS data can then be read. TRhe below example is for reading a data field:

	status=swrdfld(swid,fieldname,start,stride,edge,data) (FORTRAN)
status=gdrdfld(gdid,fieldname,start,stride,edge,data)

or

	status=SWreadfield(swid,fieldname,start,stride,edge,data) (C)
status=GDreadfield(gdid,fieldname,start,stride,edge,data)

where the parameters are the same as in the previously described write commands. A FORTRAN example for the reading of an HDF-EOS swath or grid is:

	status=swrdfld(swid,Wind,0,0,0,rwinddat)
gdwrfld(gdid,longitude,0,0,0,rlong)

Return

Terminate / close access to all files, data sets, and APIs

After writing or reading the new grid or swath fields, it is necessary to detach or close the HDF-EOS data sets by detaching the swath/grid id and to also terminate access to the file and the interface. This is done by the following (a swath example):

	status=swdetach(swid)		(FORTRAN)
swclose(swfid)

or

	status=SWdetach(swid)		(C)
SWclose(swfid)

Return

Execute program

Execute like a normal FORTRAN or C program.

Return