[Top] [Prev] [Next] [Bottom]

3.10 User-defined Attributes

User-defined attributes are attributes defined by the calling program that contains auxiliary information about a file, SDS array or dimension. This auxiliary information is sometimes called metadata, because it is data about data. There are two ways to store metadata, as a user-defined attribute or predefined attribute.

They take the form label=value, where label is a character string containing MAX_NC_NAME or fewer characters and value contains one or more entries of the same data type as defined at the time the attribute is created. Attributes can be attached to three types of objects: files, data sets and dimensions. These are referred to, respectively, as file attributes , array attributes and dimension attributes:

For each object, a separate attribute count is maintained that identifies the number of attributes associated with the object. The attribute count begins at zero and is increased by one for every new attribute assigned to an object. Each attribute associated with an object has a unique attribute index, a value between 1 and the total number of attributes. The attribute index is used to retrieve an attribute's value or information about an attribute.

The data types permitted for attributes are the same as those allowed for SDS arrays. SDS arrays with general attributes of the same name can have different data types. For example, the attribute valid_range specifying the valid range of data value for an array of 16-bit integers might be of type 16-bit integer, whereas the attribute valid_range for a variable of 32-bit floats could be of type 32-bit floating-point integer.

Attribute names follow the same rules as dimension names. Providing meaningful names for attributes is important, however using standardized conventional names may be necessary if generic applications and utility programs are to be used. For example, every variable assigned a unit should have an attribute name of "units" defined. Furthermore, if an HDF file is to be used with software that recognizes "units" attributes, the values of the "units" attributes should be expressed in a conventional form as a character string that can be interpreted by that software.

The SD interface uses the same functions to access all attributes regardless of their object assignments. The difference between accessing a file, array or dimension attribute lies in the use of identifiers. File ids, SDS ids and dimension ids are used to respectively access file attributes, SDS attributes and dimension attributes.

3.10.1 Writing User-defined Attributes: SDsetattr

Attributes are not actually written out to a file until access to the object is terminated. Creating an attribute increases the attribute count by one for the given object. Writing an attribute involves the following steps:

1. Obtain the appropriate identifiers:
2. Create the attribute.
3. Terminate access by disposing of any existing identifiers:
To assign an attribute to a file, the calling program must contain a call to SDsetattr:

C:		status = SDsetattr(sd_id, attr_name, data_type, count, value);

FORTRAN:	status = sfsnatt(sd_id, attr_name, data_type, count, value)

In SDsetattr the argument sd_id is the identifier for the HDF object to be assigned the attribute and it can be a file id, SDS id or dimension id. The argument attr_name is an ASCII string containing the name of the attribute. It represents the label in the label=value equation and can be no more than MAX_NC_NAME characters. If this is set to the name of an existing attribute the value portion of the attribute will be overwritten. Do not use SDsetattr to assign a name to a dimension, use SDsetdimname instead.

The arguments, data_type, count and value describe the right side of the label=value equation. The value argument contain one or more values of the same data type. The data_type argument describes the data type for the attribute values and count defines the total number of values in the attribute.

There are two Fortran-77 versions of this routine: sfsnatt and sfscatt. The sfsnatt routine writes numeric attribute data and sfscatt writes character attribute data.

The parameters of SDsetattr are further described below. (See Table 3W on page 84.) Note that, because there are two Fortran-77 versions of SDsetattr, there are correspondingly two entries in the "Data Type" field of the values parameter.

EXAMPLE 19. Setting Attribute Values

The following examples call SDsetattr with an SDS id as the first parameter, which assigns an SDS attribute to the selected data set. If a file id were passed instead, SDsetattr would assign a file attribute to the entire file.

C:

#include "hdf.h"
#include "mfhdf.h"

main( ) 
{

	int32 sd_id, sds_id, dim_id, dim_index, status;
	int32 num_values[2];

	/* Open the file and get the identifier for the file. */
	sd_id = SDstart("Example4.hdf", DFACC_RDWR);

	/* Set an attribute that describes the file contents. */
	status = SDsetattr(sd_id, "file_contents", DFNT_CHAR8, 16, \
					(VOIDP)"storm_track_data");

	/* Get the identifier for the first data set. */
	sds_id = SDselect(sd_id, 0);

	/* Set an attribute the specifies a valid range of values. */
	num_values[0] = 2;
	num_values[1] = 10;
	status = SDsetattr(sds_id, "valid_range", DFNT_INT32, 2, \
						(VOIDP)num_values);

	/* Get the identifier for the first dimension. */
	dim_id = SDgetdimid(sds_id, 0);

	/* Set an attribute that specifies the dimension metric. */
	status = SDsetattr(dim_id, "dim_metric", DFNT_CHAR8, 9, 
					(VOIDP)"millibars");

	/* Terminate access to the array */
	status = SDendaccess(sds_id);

	/* Terminate access to the SD interface and close the file */
	status = SDend(sd_id);

}

FORTRAN:

	PROGRAM SET ATTRIBS

      integer*4 sd_id, sds_id, dim_id, status
      integer num_values(2)
      integer sfstart, sfsnatt, sfselect, sfdimid
      integer sfendacc, sfend
      integer DFACC_RDWR, DFNT_CHAR8, DFNT_INT32
      parameter (DFACC_RDWR = 3, DFNT_CHAR8 = 4, DFNT_INT32 = 24)

C     Open the file and get the identifier for the file. 
      sd_id = sfstart('Example4.hdf', DFACC_RDWR)

C     Set an attribute that describes the file contents. 
      status = sfsnatt(sd_id, 'file_contents', DFNT_CHAR8, 16, 
     +                 'storm_track_data')
C     Get the identifier for the first data set. 
      sds_id = sfselect(sd_id, 0)

C     Set an attribute the specifies a valid range of values. 
      num_values(1) = 2
      num_values(2) = 10
      status = sfsnatt(sds_id, 'valid_range', DFNT_INT32, 2, 
     +			num_values)

C     Get the identifier for the first dimension. 
      dim_id = sfdimid(sds_id, 0)

C     Set an attribute that specifies the dimension metric. 
      status = sfsnatt(dim_id, 'dim_metric', DFNT_CHAR8, 9, 
     +			'millibars')

C     Terminate access to the array 
      status = sfendacc(sds_id)

C     Terminate access to the SD interface and close the file 
      status = sfend(sd_id)
      end

3.10.2 Querying User-defined Attributes: SDfindattr and SDattrinfo

Given a file, array or dimension id and an attribute name, SDfindattr will return a valid attribute index if the corresponding attribute exists. The attribute index can then be used to retrieve information about an attribute or its values. Given a file, array or dimension id and a valid attribute index SDattrinfo returns the name, data type and count for the corresponding attribute if it exists.

The syntax for SDfindattr and SDattrinfo is as follows:

C:		attr_index = SDfindattr(id, attr_name);
		status = SDattrinfo(id, attr_index, attr_name, num_type, count);

FORTRAN:	attr_index = sffattr(id, attr_name)
		status = sfgainfo(id, attr_index, attr, name, number_type,
				count)

The parameters of SDfindattr and SDattrinfo are further described below. (See Table 3W.)

An attribute's index may also be determined by keeping track of the number and order of attributes as they are written or dumping the contents of a file using a dumping utility.

3.10.3 Reading User-defined Attributes: SDreadattr

SDreadattr reads the value or values of an attribute. The syntax for SDreadattr is as follows:

C:		status = SDreadattr(sds_id, attr_index, data);

FORTRAN:	status = sfrattr(sd_id, attr_index, data)

SDreadattr takes a file, array, or dimension identifier and an attribute index specified in the attr_index parameter as input parameters and returns the attribute values in the buffer data. SDreadaddr will also read attributes and annotations created by the DFSD interface.

It's assumed that the buffer data, allocated to hold the attribute values, is large enough to hold the data. The size of the buffer must be at least count*DFKNTsize(number_type) bytes long. It is not possible to read a subset of values.

There are two Fortran-77 versions of this routine: sfrnatt and sfrcatt. The sfrnatt routine reads numeric attribute data and sfrcatt reads character attribute dataset.

The parameters of SDreadattr are further described in Table 3W. Note that, because there are two Fortran-77 versions of SDreadattr, there are correspondingly two entries in the "Data Type" field of the data parameter.

TABLE 3W SDsetattr, SDfindattr, SDattrinfo and SDreadattr Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDsetattr

(sfsnatt/

sfscatt)

file_id, sds_id or dim_id

int32

integer

File, array or dimension identifier.

attr_name

char *

character* (*)

Attribute name.

data_type

int32

integer

Data type of the attribute.

count

int32

integer

Number of values in the attribute.

values

VOIDP

<valid numeric data type>

Buffer for the data to be written.

SDfindattr

(sffattr)

file_id, sds_id or dim_id

int32

integer

File, array or dimension identifier.

attr_name

char *

character* (*)

Attribute name.

SDattrinfo

(sfgainfo)

file_id, sds_id or dim_id

int32

integer

File, array or dimension identifier.

attr_index

int32

integer

Index of the attribute to be read.

attr_name

char *

character* (*)

Buffer for the name of the dimension attribute.

data_type

int32 *

integer

Buffer for the data type of the values in the attribute.

count

int32 *

integer

Buffer for the total number of values in the attribute.

SDreadattr

(sfrnatt/

sfrcatt)

file_id, sds_id or dim_id

int32

integer

File, array or dimension identifier.

attr_index

int32

integer

Index for the attribute to be read.

data

VOIDP

<valid numeric data type>

Buffer for the attribute values.

EXAMPLE 20. Retrieving Attribute Information

The attribute information stored in the "Example4.hdf" HDF file in Example 15 are read from the file in these examples.

C:

#include "hdf.h"
#include "mfhdf.h"

main( ) 
{

	int32 sd_id, sds_id, status, *buffer1;
	int32 attr_index, data_type, count; 
	char attr_name[MAX_NC_NAME];
	int8 *buffer;

	/* Open the file. */
	sd_id = SDstart("Example4.hdf", DFACC_RDONLY);

	/* Find the file attribute named "file_contents". */
	attr_index = SDfindattr(sd_id, "file_contents");

	/* Get information about the file attribute. */
	status = SDattrinfo(sd_id, attr_index, attr_name, &data_type, &count);

	/* Allocate a buffer to hold the attribute data. */
	buffer = (int8 *)malloc(count * DFKNTsize(data_type));

	/* Read the attribute data. */
	status = SDreadattr(sd_id, attr_index, buffer);

	/* Get the identifier for the first data set. */
	sds_id = SDselect(sd_id, 0);

	/* Find the data set attribute named "valid_range". */
	attr_index = SDfindattr(sds_id, "valid_range");

	/* Get information about the data set attribute. */
	status = SDattrinfo(sds_id, attr_index, attr_name, &data_type, &count);

	/* Allocate a buffer to hold the attribute data. */
	buffer1 = (int32 *)malloc(count * DFKNTsize(data_type));

	/* Read the attribute data. */
	status = SDreadattr(sd_id, attr_index, buffer1);

	/* Terminate access to the array */
	status = SDendaccess(sds_id);

	/* Terminate access to the SD interface and close the file */
	status = SDend(sd_id);

}

FORTRAN:

	PROGRAM ATTRIB INFO

      integer*4 sd_id, sds_id, range_buffer(2)
      integer attr_index, data_type, count, status
      character attr_name *13
      character char_buffer *20
      integer sfstart, sffattr, sfgainfo, sfrattr, sfselect
      integer sfendacc, sfend

C     DFACC_RDWR is defined in hdf.h.
      integer DFACC_RDWR
      parameter (DFACC_RDWR = 3)

C     Open the file. 
      sd_id = sfstart('Example4.hdf', DFACC_RDONLY)

C     Find the file attribute named 'file_contents'. 
      attr_index = sffattr(sd_id, 'file_contents')

C     Get information about the file attribute. 
      status = sfgainfo(sd_id, attr_index, attr_name, data_type, 
     +			count)

C     Read the attribute data. 
      status = sfrattr(sd_id, attr_index, char_buffer)

C     Get the identifier for the first data set. 
      sds_id = sfselect(sd_id, 0)

C     Find the data set attribute named 'valid_range'. 
      attr_index = sffattr(sds_id, 'valid_range')

C     Get information about the data set attribute. 
      status = sfgainfo(sds_id, attr_index, attr_name, data_type, 
     +			count)

C     Read the attribute data. 
      status = sfrattr(sd_id, attr_index, range_buffer)

C     Terminate access to the array 
      status = sfendacc(sds_id)

C     Terminate access to the SD interface and close the file 
      status = sfend(sd_id)

      end



[Top] [Prev] [Next] [Bottom]

hdfhelp@ncsa.uiuc.edu
HDF User's Guide - 06/04/97, NCSA HDF Development Group.