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

3.9 SD Dimension and Dimension Scale Operations

A description of dimensions is in Section 3.2.1.4 on page 20.

3.9.1 Selecting a Dimension: SDgetdimid

SDS dimensions are uniquely identified by dimension ids, which are assigned when a dimension is created. These dimension ids are used to refer within a program to a particular dimension, its scale and its attributes. Before working with a dimension, a program must first obtain a dimension id by calling the SDgetdimid routine:

C:		dim_id = SDgetdimid(sds_id, dim_index);

FORTRAN:	dim_id = sfdimid(sds_id, dim_index)

SDgetdimid has two arguments; sds_id and dim_index, and returns a dimension identifier, dim_id. The argument dim_index is a zero-based integer indicating the location of the dimension in the data set.

The number of dimensions in a data set is specified at the time the data set is created. Specifying a dimension index larger than the number of dimensions in the data set returns an error.

Unlike file and data set identifiers, dimension identifiers do not require explicit disposal.

3.9.2 Naming a Dimension: SDsetdimname

SDsetdimname assigns a name to the selected dimension. The name of the dimension will also appear as the name of the dimension scale. If the dimension name is not unique, it is assumed that both dimensions refer to the same object and changes to one will be reflected in the other. Naming dimensions is optional but encouraged. Dimensions that are not explicitly named by the user will have names generated by the HDF library. Use SDdiminfo to read existing dimension names.

The following steps are required to name a dimension and its scale:

1. Get the identifier of the dimension.
2. Assign a name to the dimension - the dimension scale will be set automatically.
The following routine calls are required to do this:

C:		dim_id = SDgetdimid(dim_id, dim_index);
		status = SDsetdimname(dim_id, dim_name);

FORTRAN:	dim_id = sfdimid(dim_id, dim_index)
		status = sfsdimname(dim_id, dim_name)

The argument dim_id in SDsetdimname is the dimension identifier returned by SDgetdimid and dim_name is the name for the selected dimension. An attempt to rename a dimension using SDsetdimname will cause the old name to be deleted and a new one to be assigned.

What should be remembered when naming dimensions is that the name or a particular dimension must be set before attributes are assigned - and, once the attributes have been set, the name should not be changed. In other words, SDsetdimname should only be called before any calls to SDsetdimscale (described in Section 3.9.4.1 on page 74), SDsetattr (described in Section 3.10.1 on page 81) or SDsetdimstrs (described in Section 3.11.2.1 on page 89).

TABLE 3R SDsetdimname Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDsetdimname

(sfsdimname)

dim_id

int32

integer

Dimension identifier.

dim_name

char *

character* (*)

Dimension name.

3.9.3 Old and New Dimension Implementations

Up to and including HDF version 4.0 beta1, dimensions were vgroup objects containing a single field vdata with a class name of "DimVal0.0". The vdata had the same number of records as the size of the dimension, which consisted of the values 0, 1, 2, . . . n - 1, where n is the size of the dimension. These values weren't strictly necessary and for applications that create large one dimensional array datasets the disk space taken by these unnecessary values would nearly double the size of the HDF file. In order to avoid these situations, a new representation of dimensions was implemented for HDF version 4.0 beta 2 and later versions.

Dimensions are still vgroups in the new representation: the only differences are that the vdata has only one record with a value of <dimension size> and the class name of the vdata has been changed to "DimVal0.1" to distinguish it from the old version.

Until HDF version 4.1, the old and new dimension representation will be written by default for each dimension created, and both representations will be recognized by routines that operate on dimensions. HDF version 4.1 routines will only recognize the new representation. During the transitional period, two routines will be provided to allow HDF programs to distinguish between the two dimension representations, or compatibility modes: - SDsetdimval_comp and SDsetdimval_bwcomp.

3.9.3.1 Setting the Future Compatibility Mode of a Dimension: SDsetdimval_comp

SDsetdimval_comp determines whether the specified dimension will have the old and new representations or the new representation only, by setting the compatibility mode for the specified dimension. The routine's syntax is the following:

C:		status = SDsetdimval_comp(dim_id, comp_mode);

FORTRAN:	status = sfsdmvc(dim_id, comp_mode)

The comp_mode parameter determines the compatibility mode. It can be set to either SD_DIMVAL_BW_COMP, which specifies compatible mode and that the old and new dimension representations will be written to file , or SD_DIMVAL_BW_INCOMP, which specifies incompatible mode and that only the new dimension representation will be written to file.

Unlimited dimensions are always backward compatible. Therefore, SDsetdimval_comp takes no action on these dimensions.

SDsetdimval_comp returns either SUCCEED on successful completion, or FAIL otherwise.

TABLE 3S SDsetdimval_comp Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDsetdimval_comp

(sfsdmvc)

dim_id

int32

integer

Dimension identifier.

comp_mode

intn

integer

Compatibility mode.

3.9.3.2 Setting the Current Compatibility Mode of a Dimension: SDisdimval_bwcomp

SDisdimval_bwcomp determines whether the specified dimension has the old and new representations or the new representation only. The function's syntax is the following:

C:		comp_mode = SDisdimval_bwcomp(dim_id);

FORTRAN:	comp_mode = sfisdmvc(dim_id)

SDisdimval_bwcomp returns one of three values: either SD_DIMVAL_BW_COMP, SD_DIMVAL_BW_INCOMP or ERROR. SD_DIMVAL_BW_COMP and SD_DIMVAL_BW_INCOMP are interpreted as they are by SDisdimval_comp.

TABLE 3T SDisdimval_bwcomp Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDisdimval_bwcomp

(sfisdmvc)

dim_id

int32

integer

Dimension identifier.

3.9.4 Dimension Scales

A dimension scale is a series of numbers placed along a dimension to demarcate intervals in a data set. One scale is assigned per dimension. In the SDS data model, each dimension scale is a one-dimensional array with size and name equal to its assigned dimension name and size. For example, if a dimension of length 6 named "depth" is assigned a dimension scale, its scale is a one-dimensional array of length 6 and is also assigned the name "depth".

Although dimension scales are conceptually different from SDS arrays, they are both arrays and are often treated in the same way by the SDS API. For example, when the SDfileinfo routine returns the number of data sets in a file, it includes dimension scales in that number. The SDiscoordvar routine (described in Section 3.9.5 on page 78) distinguishes data sets from dimension scales.

3.9.4.1 Writing Dimension Scales: SDsetdimscale

Selecting a dimension with SDgetdimid assigns a default dimension scale. Default dimension scales have the data type of the corresponding SDS array. To assign a non-default scale with a non-default data type, use SDsetdimscale.

To create a non-default scale, the following steps are required:

1. Get the identifier of the dimension.
2. Create the dimension scale, setting the data type and size to the desired values.
To do this, the calling program must execute the following calls:

C:		dim_id = SDgetdimid(sds_id, dim_index);
		status = SDsetdimscale(dim_id, count, data_type, data);

FORTRAN:	dim_id = sfdimid(sds_id, dim_index)
		status = sfsdscale(dim_id, count, data_type, data)

The argument count is the size of the scale, data_type defines the data type for the scale values and data is an array containing the scale values. Assigning a value to count is optional: it exists to insure backward compatibility.

3.9.4.2 Obtaining Dimension Scale and Other Dimension Information: SDdiminfo

Before working with an existing dimension scale, it is often necessary to determine its characteristics. For instance, to allocate the proper amount of memory for a scale requires knowledge of its size and data type. SDdiminfo provides this basic information, as well as the name and attribute count for a specified dimension.

To obtain dimension information the following steps are required:

1. Get the identifier of the dimension.
2. Retrieve the dimension information.
The calling program must call the following routines in order:

C:		dim_id = SDgetdimid(sds_id, dim_index);
		status = SDdiminfo(dim_id, name, count, data_type, nattrs);

FORTRAN:	dim_id = sfdimid(sds_id, dim_index)
		status = sfgdinfo(dim_id, name, count, data_type, nattrs)

In SDdiminfo the arguments name, count, data_type and nattrs define buffers allocated to respectively hold the dimension name and size, the data type for the scale values and the number of attributes assigned to the dimension.

Dimensions are always named. However, if you don't wish to explicitly provide a name, NULL can be passed as the name parameter to SDdiminfo and a default name will be assigned by the SD API. If scale information is available for the dimension, data_type will contain the data type of the scale values, otherwise data_type will be 0.

3.9.4.3 Reading Dimension Scales: SDgetdimscale

To read a scale, the following steps are required:

1. Get the identifier of the dimension.
2. Read the scale.
The calling program must contain the following sequence of calls:

C:		dim_id = SDgetdimid(sds_id, dim_index);
		status = SDgetdimscale(dim_id, data);

FORTRAN:	dim_id = sfdimid(sds_id, dim_index)
		status = sfgdscale(dim_id, data)

In SDgetdimscale the argument data is the buffer allocated to hold the scale values. As SDgetdimscale returns all of the values associated with a given scale, it is assumed that the size of the scale buffer is greater than or equal to the dimension size.

TABLE 3U SDgetdimid, SDsetdimname, SDsetdimscale, SDdiminfo and SDgetdimscale Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDgetdimid

(sfdimid)

sds_id

int32

integer

Data set identifier.

dim_index

intn

integer

Index of the dimension.

SDsetdimname

(sfsdmname)

dim_id

int32

integer

Dimension identifier.

dim_name

char *

character* (*)

Dimension name.

SDsetdimscale

(sfsdscale)

dim_id

int32

integer

Dimension identifier.

count

int32 *

integer

Number of scale values.

data_type

int32 *

integer

Data type of the scale values.

data

VOIDP

<valid numeric data type>

Buffer for the scale values.

SDdiminfo

(sfgdinfo)

dim_id

int32

integer

Dimension identifier.

name

char *

character* (*)

Buffer for the dimension name.

count

int32 *

integer

Buffer for the dimension size.

number_type

int32 *

integer

Buffer for the scale data type.

nattrs

int32 *

integer

Buffer for the attribute count.

SDgetdimscale

(sfgdscale)

dim_id

int32

integer

Dimension identifier.

data

VOIDP

<valid numeric data type>

Buffer for the scale values.

EXAMPLE 17. Writing Dimension Information

The dimensions of the SDS created in Example 4 are created and scales assigned to them in these examples.

C:

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

main( ) 
{
	int32 sd_id, sds_id, dim_index, dim_id, sds_index, status;
	int32 count, num_type, num_attrs;
	int16 dim_scale[] = {6,5,4,3,2,1};
	char dim_name[MAX_NC_NAME];

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

	/* Get the index of the "Ex_array_4" array data set. */
	sds_index = SDnametoindex(sd_id, "Ex_array_4");

	/* Select the data set corresponding to the returned index. */
	sds_id = SDselect(sd_id, sds_index);

	/* For each dimension of the "Ex_array_4" array data set, */
	for (dim_index = 0; dim_index < 3; dim_index++) {

	/* - select the dimension id, */
		dim_id = SDgetdimid(sds_id, dim_index);

	/* - get the information about the selected dimension, */
		status = SDdiminfo(dim_id, dim_name, &count, &num_type, \
	                       &num_attrs);
		num_type = DFNT_INT16;

	/* - alter the dimension names, */
		switch(dim_index) {
			case 0:	SDsetdimname(dim_id, "Z_Axis"); 
					break;
			case 1:	SDsetdimname(dim_id, "Y_Axis"); 
	 				break;
			case 2:	SDsetdimname(dim_id, "X_Axis"); 
					break;
			default:	break;
		}

	/* - then alter the dimension scale and write it to the data set. */
		dim_scale[0] = 3;
		dim_scale[1] = 2;
		dim_scale[2] = 1;
		status = SDsetdimscale(dim_id, count, num_type, (VOIDP)dim_scale);
	}

	/* 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 ALTER DIMENSION 

      integer*4 sd_id, sds_id, dim_index, dim_id, status
      integer*4 count, num_attrs
      integer sfstart, sfn2index, sfdimid, sfgdinfo
      integer sfsdscale, sfsdmname, sfendacc
      integer sfend, sfselect, num_type, i, dim_scale(6)
      integer DFACC_RDWR, MAX_NC_NAME, DFNT_INT16
      parameter (DFACC_RDWR = 3, MAX_NC_NAME = 256, DFNT_INT16 = 22)
      character dim_name(MAX_NC_NAME)

C     For each dimension of the 'Ex_array_4' array data set, 
      do 5 i = 1, 6
         dim_scale(i) = i
5     continue

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

C     Get the index of the 'Ex_array_4' array data set. 
      sds_index = sfn2index(sd_id, 'Ex_array_4')

C     Select the data set corresponding to the returned index.
      sds_id = sfselect(sd_id, sds_index)

C     For each dimension of the 'Ex_array_4' array data set, 
      do 10 dim_index = 1, 3

C      - select the dimension id, 
         dim_id = sfdimid(sds_id, dim_index-1)

C      - get the information about the selected dimension, 
         status = sfgdinfo(dim_id, dim_name, count, num_type, 
     +                     num_attrs)

C      - alter the dimension names. 
         if (dim_index .eq. 1) then
         status = sfsdmname(dim_id, 'Z_Axis') 
         end if
         if (dim_index .eq. 2) then
         status = sfsdmname(dim_id, 'Y_Axis') 
         end if
         if (dim_index .eq. 3) then
         status = sfsdmname(dim_id, 'X_Axis') 
         end if

         num_type = DFNT_INT16

C     - and, alter the dimension scale, write it to the data set, 
         dim_scale(1) = 3
         dim_scale(2) = 2
         dim_scale(3) = 1
         dim_scale(4) = 0
         dim_scale(5) = -1
         dim_scale(6) = -2
         status = sfsdscale(dim_id, count, num_type, dim_scale)
10    continue

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.9.5 Distinguishing SDS Arrays from Dimension Scales: SDiscoordvar

Although dimension scales, or coordinate variables in netCDF, can for the most part be ignored, it is important to note that, in HDF, they are also SDSs and are assigned the same tag (DFTAG_SD) as other SDSs. As a result, dimension scales are treated as SDSs, and are included in the SDS count returned by SDfileinfo. The function SDiscoordvar is available to determine whether or not a given SDS is a dimension scale.

SDiscoordvar takes an SDS id as its only argument and returns TRUE if the data set is a dimension scale, and FALSE if it isn't. If SDiscoordvar returns TRUE, a subsequent call to SDgetinfo will fill the specified locations with information about the dimension scale, rather than the data set array.

TABLE 3V SDiscoordvar Parameter List
Routine Name

(Fortran-77)

Parameter

Data Type

Description

C

Fortran-77

SDiscoordvar

(sfiscvar)

sds_id

int32

integer

Data set identifier.

EXAMPLE 18. Retrieving SDS Information from an HDF File

SDgetinfo and SDiscoordvar provide information that may be needed in order to read in an array successfully, as the following examples show.

C:

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

#define X_LENGTH 5
#define Y_LENGTH 16

main( ) 
{

	int32 sd_id, sds_id, status;
	int32 rank, nt, dims[MAX_VAR_DIMS], nattrs;
	int32 start[2], edges[2];
	int16 array_data[Y_LENGTH][X_LENGTH];
	char name[MAX_NC_NAME];

	/* Open the file and initiate the SD interface. */
	sd_id = SDstart("Example3.hdf", DFACC_RDONLY);

	/* Select the first (and in this case, only) data set in the file. */
	sds_id = SDselect(sd_id, 0);

	/* Confirm that the data set is not a coordinate variable. */
	if (FALSE == SDiscoordvar(sds_id)) {

	/* Verify the characteristics of the array. */
		status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);

	/* Define the location, pattern, and size of the data to read from \
		the data set. */
		start[0] = start[1] = 0;
		edges[0] = dims[0];
		edges[1] = dims[1];

	/* Read the array data set created in Example 3. */
		status = SDreaddata(sds_id, start, NULL, edges, (VOIDP)array_data);

	}

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

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

}

FORTRAN:

	PROGRAM CONFIRM FILE

      integer*4 sd_id, sds_id, rank, nt, nattrs, status
      integer start(2), edge(2), stride(2)
      integer datavar
      integer sfstart, sfselect, sfiscvar, sfginfo
      integer sfrdata, sfendacc, sfend

C     DFACC_RDONLY is defined in hdf.h. MAX_NC_NAME and MAX_VAR_DIMS
C     are defined in netcdf.h.
      integer*4 DFACC_RDONLY, MAX_NC_NAME, MAX_VAR_DIMS
      integer*4 X_LENGTH, Y_LENGTH
      parameter (DFACC_RDONLY = 1, MAX_NC_NAME = 256, 
     +           MAX_VAR_DIMS = 32, X_LENGTH = 4, Y_LENGTH = 15)
      integer*2 array_data(X_LENGTH, Y_LENGTH)
      character name(MAX_NC_NAME)
      integer dims(MAX_VAR_DIMS)

C     Open the file and initiate the SD interface.
      sd_id = sfstart('Example3.hdf', DFACC_RDONLY)

C     Select the first (and in this case, only) data set in the file.
      sds_id = sfselect(sd_id, 0)

C     Confirm that the data set is not a coordinate variable.
      datavar = sfiscvar(sds_id)
      if (datavar .eq. 0) then

C        Verify the characteristics of the array.
         status = sfginfo(sds_id, name, rank, dims, nt, nattrs)

C        Define the location, pattern, and size of the data to read
C        from the data set.
         start(1) = 0
         start(2) = 0
         stride(1) = 1
         stride(2) = 1
         edge(1) = dims(1)
         edge(2) = dims(2)

C        Read the array data set.
         status = sfrdata(sds_id, start, stride, edge, array_data)
      endif

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

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

3.9.6 Dimension Scales for Multiple Data Sets

SD scientific data sets with one or more dimensions with the same name and size are considered to be related. Examples of related data sets are cross-sections from the same simulation, frames in an animation or images collected from the same apparatus. HDF attempts to preserve this relationship by unifying their dimension scales and attributes. To understand how related data sets are handled, it is necessary to understand how dimension records are created.

In the SD interface, dimension records are only created for dimensions of a unique name and size. To illustrate this, consider a case where there are three scientific data sets, each representing a unique variable, in an HDF file. (See Figure 3d.) The first two data sets have two dimensions each assigned to it and the third data set has three dimensions. There are a total of five dimensions in the file and the name mapping between the data sets and the dimensions are shown in the figure. Note that if, for example, the creation of a second dimension named "Altitude" is attempted and the size of the dimension is different from the existing dimension named "Altitude", an error condition will be generated.

As expected, assigning a dimension attribute to dimension 1 of either data set will create the required dimension scale and assign the appropriate attribute. However, because related data sets share dimension records, they also share dimension attributes. Therefore, it is impossible to assign an attribute to a dimension without assigning the same attribute to all dimensions of identical name and size, either within one data set or related data sets.

FIGURE 3d Dimension Records and Attributes Shared Between Related Data Sets



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

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