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.
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.
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.
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.
|
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.
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.
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.
|
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.
|
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.
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.
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.
3.9.4.3 Reading Dimension Scales: SDgetdimscale
To read a scale, the following steps are required:
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
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); }
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. 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.
|
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); }
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.
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