bool GetSDSDimInfo(int32 sds_id, Myhdf_dim_t *dim, int irank) /* !C****************************************************************************** !Description: 'GetSDSDimInfo' reads information for a specific SDS dimension. !Input Parameters: sds_id SDS id !Output Parameters: dim Dimension data structure; the following fields are updated: id, nval, type, nattr, name (returns) Status: 'true' = okay 'false' = error reading the dimension information !Team Unique Header: ! Design Notes: 1. The HDF file is assumed to be open for SD (Science Data) access. 2. An dimension name of less than 'DIM_MAX_NCHAR' is expected. 3. Error messages are handled with the 'RETURN_ERROR' macro. !END**************************************************************************** */ { char dim_name[DIM_MAX_NCHAR]; dim->id = SDgetdimid(sds_id, irank); if (dim->id == HDF_ERROR) RETURN_ERROR("getting dimension id", "GetSDSDimInfo", false); if (SDdiminfo(dim->id, dim_name, &dim->nval, &dim->type, &dim->nattr) == HDF_ERROR) RETURN_ERROR("getting dimension information", "GetSDSDimInfo", false); dim->name = DupString(dim_name); if (dim->name == (char *)NULL) RETURN_ERROR("copying dimension name", "GetSDSDimInfo", false); return true; }
bool PutSDSDimInfo(int32 sds_id, Myhdf_dim_t *dim, int irank) /* !C****************************************************************************** !Description: 'PutSDSDimInfo' writes information for a SDS dimension. !Input Parameters: sds_id SDS id dim Dimension data structure; the following field is used: name irank Dimension rank !Output Parameters: dim Dimension data structure; the following field is updated: id (returns) Status: 'true' = okay 'false' = error writing the dimension information !Team Unique Header: ! Design Notes: 1. The HDF file is assumed to be open for SD (Science Data) access. 2. Error messages are handled with the 'RETURN_ERROR' macro. 3. Setting the type of the dimension is not currently implemented. !END**************************************************************************** */ { dim->id = SDgetdimid(sds_id, irank); if (dim->id == HDF_ERROR) RETURN_ERROR("getting dimension id", "PutSDSDimInfo", false); if (SDsetdimname(dim->id, dim->name) == HDF_ERROR) RETURN_ERROR("setting dimension name", "PutSDSDimInfo", false); /* Set dimension type */ /* !! do it !! */ return true; }
/* Given the file ID, variable ID, and name of the dimension, return * the dimension ID. */ int cudimid_hdf(CuFile* file, int varid, const char* name){ int32 sds_idx, sds_id; /* Search for the index of the named array data set. */ if ((sds_idx=SDnametoindex(file->internid1, name)) == -1) { CuError(CU_DRIVER,"Obtaining dataset in file %s",file->controlpath); cuerrorreport_hdf(); return -1; } /* Select the data set corresponding to the returned index. */ if ((sds_id=SDselect(file->internid1, sds_idx)) == -1) { CuError(CU_DRIVER,"Obtaining dataset in file %s",file->controlpath); cuerrorreport_hdf(); return -1; } /* Return dimension ID or failure ( -1 ). */ return (SDgetdimid(sds_id, 0) - file->internid2); /* pass back the dimension id */ }
/* Get information about the variable. Return success (0) if the * variable information was obtained sucessfully, otherwise this * function returns the failure status (-1). */ int cuvarinq_hdf(CuFile* file, int varid, char* name, CuType* datatype, int* ndims, int dimids[], int* natts){ int err, i; hdf_type dtype; char t_name[H4_MAX_NC_NAME+1]; int t_ndims, t_natts, numdims; int t_dimids[H4_MAX_VAR_DIMS]; int32 sds_id, index; int32 dim_sizes[H4_MAX_VAR_DIMS]; /* Select the data set corresponding to the returned index. */ sds_id = SDselect(file->internid1, varid); /* Get the variable information. */ if ((err=SDgetinfo(sds_id, (name ? name : t_name), (ndims ? ndims : &t_ndims), dim_sizes, &dtype, (natts ? natts : &t_natts))) != -1) { if(datatype) { cumapdatatype_hdf(dtype,datatype); if (*datatype==CuInvalidType) return -1; } /* Retrieve dimension IDs. */ if (dimids) { numdims = (ndims ? *ndims : t_ndims); for (i=0; i < numdims; ++i) /* reverse the order */ dimids[i] = SDgetdimid (sds_id, i) - file->internid2; } } /* Return variable ID, or failure ( -1 ). */ return (err==-1 ? -1 : CU_SUCCESS); }
int do_lone(char* file_name, int do_diffs) { char sds_name[] = "lone"; int32 rank = 1; int32 dim_sds[1] = {5}; /* dimension of the data set */ int32 data[5] = {1, 2, 3, 4, 5}; int32 start[1]; /* start position to write for each dimension */ int32 edges[1]; /* number of elements to be written along each dimension */ int32 sds_id; int32 dim_id; int32 sd_id; if ( do_diffs ) { data[1] = data[2] = 0; } sd_id = SDstart(file_name, DFACC_CREATE); /* create the SDS */ if ((sds_id = SDcreate (sd_id, sds_name, DFNT_INT32, rank, dim_sds))<0) { printf( "Could not create SDS <%s>\n",sds_name); goto fail; } dim_id = SDgetdimid(sds_id, 0); SDsetdimname(dim_id, sds_name); /* define the location and size of the data to be written to the data set */ start[0] = 0; edges[0] = 5; /* write the stored data to the data set */ if (SDwritedata (sds_id, start, NULL, edges, (VOIDP)data)==FAIL) { printf( "Failed to set write for SDS <%s>\n", sds_name); goto fail; } SDendaccess(sds_id); /* create the SDS */ if ((sds_id = SDcreate (sd_id, "sds", DFNT_INT32, rank, dim_sds))<0) { printf( "Could not create SDS <%s>\n"); goto fail; } if (SDwritedata (sds_id, start, NULL, edges, (VOIDP)data)==FAIL) { printf( "Failed to set write for SDS <%s>\n"); goto fail; } SDendaccess(sds_id); SDend(sd_id); { int32 file1_id; /* HDF file identifier */ int32 an_id; /* AN interface identifier */ int32 file_label_id; /* file label identifier */ /* open file */ if ((file1_id = Hopen (file_name, DFACC_WRITE, (int16)0))<0) { printf("Error: Could not open file <%s>\n",file_name); return FAIL; } /* Initialize the AN interface */ an_id = ANstart (file1_id); /* Create the file label */ file_label_id = ANcreatef (an_id, AN_FILE_LABEL); /* Write the annotations to the file label */ if (ANwriteann (file_label_id,FILE_LABEL_TXT,strlen (FILE_LABEL_TXT))==FAIL) { printf( "Could not write AN\n"); return FAIL; } /* Terminate access to annotation */ if (ANendaccess (file_label_id)==FAIL) { printf( "Could not end AN\n"); return FAIL; } /* Terminate access to the AN interface */ if (ANend (an_id)==FAIL) { printf( "Could not end AN\n"); return FAIL; } /* close the HDF file */ if (Hclose (file1_id)==FAIL) { printf( "Could not close file\n"); return FAIL; } } return SUCCEED; fail: SDend(sd_id); return FAIL; }
int init_output_sds(int32 sd_id, unsigned char *process, SDS outsds[Nbands], SDS sds[Nitems], int gzip, int verbose) { int ib; int32 dim_id; char *dimname1, *dimname2; HDF_CHUNK_DEF chunk_def; /* same fill value will be used for all output SDSs */ static int16 fillvalue = FILL_INT16; /* band naming convention will be "CorrRefl_XX" (11 characters + terminating null) */ char name[16]; /* write SDS-specific attributes and dimension names */ for (ib = 0; ib < Nbands; ib++) { if (!process[ib]) continue; outsds[ib].num_type = DFNT_INT16; outsds[ib].factor = 0.0001; outsds[ib].offset = 0; outsds[ib].rank = 2; sprintf(name, "CorrRefl_%2.2d", ib + 1); if ( !(outsds[ib].name = strdup(name)) ) return 1; outsds[ib].Nl = outsds[ib].dim_sizes[0] = sds[ib].Nl; outsds[ib].Np = outsds[ib].dim_sizes[1] = sds[ib].Np; outsds[ib].rowsperscan = sds[ib].rowsperscan; if (verbose) printf("Creating SDS %s: %dx%d\n", outsds[ib].name, outsds[ib].Np, outsds[ib].Nl); if ((outsds[ib].id = SDcreate(sd_id, outsds[ib].name, outsds[ib].num_type, outsds[ib].rank, outsds[ib].dim_sizes)) == -1) { fprintf(stderr, "Cannot create SDS %s\n", outsds[ib].name); return 1; } outsds[ib].fillvalue = &fillvalue; if ( SDsetfillvalue(outsds[ib].id, outsds[ib].fillvalue) ) { fprintf(stderr, "Cannot write fill value of SDS %s\n", outsds[ib].name); return 1; } if ( SDsetattr(outsds[ib].id, "scale_factor", DFNT_FLOAT64, 1, &outsds[ib].factor) == -1 || SDsetattr(outsds[ib].id, "add_offset", DFNT_FLOAT64, 1, &outsds[ib].offset) == -1 ) { fprintf(stderr, "Cannot write scale factor and offset of SDS \"%s\"\n", outsds[ib].name); return 1; } if ( SDsetattr(outsds[ib].id, "units", DFNT_CHAR8, 4, "none") == -1 ) { fprintf(stderr, "Cannot write units attribute of SDS \"%s\"\n", outsds[ib].name); return 1; } /* set dimensions */ outsds[ib].start[1] = 0; outsds[ib].edges[0] = outsds[ib].rowsperscan; outsds[ib].edges[1] = outsds[ib].Np; /* allocate memory for band output data */ outsds[ib].data = malloc(outsds[ib].rowsperscan * outsds[ib].Np * DFKNTsize(outsds[ib].num_type)); if (!outsds[ib].data) { fputs("Error allocating memory.\n", stderr); return 1; } /* set optional compression */ if (gzip) { chunk_def.chunk_lengths[0] = chunk_def.comp.chunk_lengths[0] = outsds[ib].edges[0]; chunk_def.chunk_lengths[1] = chunk_def.comp.chunk_lengths[1] = outsds[ib].edges[1]; chunk_def.comp.comp_type = COMP_CODE_DEFLATE; chunk_def.comp.cinfo.deflate.level = 4; if (SDsetchunk(outsds[ib].id, chunk_def, HDF_CHUNK | HDF_COMP) == FAIL) { fprintf(stderr, "Cannot set chunks for SDS %s\n", outsds[ib].name); return 1; } } set_dimnames(outsds[ib].Np, &dimname1, &dimname2); if (verbose) printf("(%s x %s)\n", dimname1, dimname2); /* dimension names */ if ((dim_id = SDgetdimid(outsds[ib].id, 0)) == -1) { fputs("Error getting dimension ID1.\n", stderr); return 1; } if (SDsetdimname(dim_id, dimname1) == -1) { fprintf(stderr, "Cannot set first dimension name for SDS %s\n", outsds[ib].name); return 1; } if ((dim_id = SDgetdimid(outsds[ib].id, 1)) == -1) { fputs("Error getting dimension ID2.\n", stderr); return 1; } if (SDsetdimname(dim_id, dimname2) == -1) { fprintf(stderr, "Cannot set second dimension name for SDS %s\n", outsds[ib].name); return 1; } } return 0; }
/* Open and read the HDF file. Return the file ID if successful, or * report error and send back failure status (-1). */ int cuopenread_hdf(const char* controlpath, const char* datapath){ CuFile* file; int32 cdfid; int nvars=0, natts=0; int varid, ndims, dimidx, maxdim, mindim; int32 dimid, sds_id; CuDim *dim; /* Open the HDF file. DFACC_RDONLY is defined in hdf.h. */ if ((cdfid=SDstart(controlpath, DFACC_RDONLY))==-1) { CuError(CU_EOPEN,"Opening HDF file %s",controlpath); cuerrorreport_hdf(); return -1; } /* Make sure there is a scientific dataset */ SDfileinfo(cdfid, &nvars, &natts); if (nvars==0 && natts==0){ CuError(CU_EOPEN,"HDF file %s does not contain any scientific datasets",controlpath); cuerrorreport_hdf(); return -1; } if((file = CuCreateFile(CuHdf))==(CuFile*)0){ return -1; } /* Set the file path and file ID */ strncpy(file->controlpath,controlpath,CU_MAX_PATH); file->internid1 = cdfid; /* Set up a mapping of cdunif dimid to HDF dimid: */ /* Go through all the dimensions, find min and max HDF_dimid. */ /* ASSUME THAT DIMENSION IDS ARE CONSECUTIVE NONNEGATIVE NUMBERS. */ /* Store base dimid in file->internid2. */ /* The mapping is 0 --> mindim, 1 --> mindim+1, etc. */ mindim = maxdim = -1; for (varid=0; varid<nvars; varid++){ if (cuvarinq_hdf(file, varid, NULL, NULL, &ndims, NULL, NULL)) return -1; if ((sds_id=SDselect(file->internid1, varid)) == -1) { cuerrorreport_hdf(); return -1; } for (dimidx=0; dimidx<ndims; dimidx++){ if((dimid=SDgetdimid(sds_id, dimidx))==-1){ cuerrorreport_hdf(); return -1; } if (maxdim==-1){ mindim = maxdim = dimid; } else{ mindim = MIN(mindim, dimid); maxdim = MAX(maxdim, dimid); } } } file->internid2 = mindim; file->ndims = maxdim-mindim+1; /* Return file ID */ return file->id; }
/* Get dimension coordinates values. Return success (0) if the * dimension values were obtained sucessfully, otherwise this * function returns the failure status (-1). */ int cudimget_hdf(CuFile* file, int dimidx, void* values){ char dimname[H4_MAX_NC_NAME+1]; float *fp; int cdfid; int get_dimid; int dimvarid; int found; int ndims; int saveopts; long i; long length; long start; char varname[H4_MAX_NC_NAME+1]; hdf_type hdftype; int natts; int32 dimid; int32 sds_id, datatype, nattrs, attr_index, num_type, count; int32 dim_sizes[H4_MAX_VAR_DIMS]; char attr_name[H4_MAX_NC_NAME]; cdfid = file->internid1; if((dimid = cudimid2hdf(file, dimidx))==-1) return -1; /* Get information about the selected dimension. */ if(SDdiminfo(dimid, attr_name, &length, &datatype, &nattrs)==-1){ return -1; } /* Inquire a variable with */ /* - the same name as dimname, */ /* - a single dimension, and */ /* - a (single) dimension id which equals dimid */ if((dimvarid = SDnametoindex(cdfid, attr_name)) != -1){ sds_id = SDselect(cdfid, dimvarid); if (SDgetinfo(sds_id, varname, &ndims, dim_sizes, &hdftype, &natts) == -1){ cuerrorreport_hdf(); return -1; } /* pass back the dimension id */ if ((get_dimid = SDgetdimid(sds_id, 0)) == -1){ cuerrorreport_hdf(); return -1; } found = (ndims == 1 && get_dimid == dimid); } else found = 0; /* If the dimension variable was found, read it */ if(found){ start = 0; if(values && SDgetdimscale(dimid, (VOIDP) values)==-1) return -1; } else{ /* Otherwise assign the default dimension */ if(values){ for(i=0, fp=(float*)values; i<length; i++){ *fp++ = (float)i; } } } /* Return success ( 0 ). */ return CU_SUCCESS; }
/* Get information about the dimension. Return success (0) if the * dimension information was obtained sucessfully, otherwise this * function returns the failure status (-1). */ int cudiminq_hdf(CuFile* file, int dimidx, char* dimname, char* dimunits, CuType* dataType, CuDimType* dimtype, int* varid, long* length){ char dname[H4_MAX_NC_NAME+1]; int cdfid; int dimvarid; /* HDF ID of variable associated with this dimension. */ int found; /* True iff a dimension variable was found. */ int ndims; int get_dimid; int saveopts; long len; hdf_type hdftype, hdfunitstype; int natts; char varname[H4_MAX_NC_NAME+1]; int attlen; int32 sds_id, attr_index, datatype, nattrs; int32 dim_sizes[H4_MAX_VAR_DIMS]; char attr_name[H4_MAX_NC_NAME]; int32 dimid; cdfid = file->internid1; if((dimid = cudimid2hdf(file, dimidx))==-1) return -1; /* Get information about the selected dimension. */ if(SDdiminfo(dimid, dname, &len, &datatype, &nattrs)==-1){ cuerrorreport_hdf(); return -1; } if(dimname) strncpy(dimname,dname,CU_MAX_NAME); if(length) *length = len; /* HDF dimensions are always global */ if(varid) *varid = CU_GLOBAL; if(dimtype) *dimtype = CuGlobalDim; /* Inquire a variable with */ /* - the same name as dimname, */ /* - a single dimension, and */ /* - a dimension name which equals the variable name. */ if((dimvarid = SDnametoindex(cdfid, dname)) != -1){ sds_id = SDselect(cdfid, dimvarid); if (SDgetinfo(sds_id, varname, &ndims, dim_sizes, &hdftype, &natts) == -1){ cuerrorreport_hdf(); return -1; } /* pass back the dimension id */ if ((get_dimid = SDgetdimid(sds_id, 0)) == -1){ cuerrorreport_hdf(); return -1; } found = (ndims == 1 && get_dimid == dimid); } else found = 0; /* If dimension variable was found, */ /* inquire the units attribute (if any) */ if(found){ sds_id = SDselect(cdfid, dimvarid); /* Set the length of an unlimited dimension. */ if (len==0 && length) *length = dim_sizes[0]; /* Find the data set attribute name index. */ attr_index = SDfindattr(sds_id, "units"); /* Get information about the data set attribute. */ if(SDattrinfo(sds_id, attr_index, attr_name, &hdfunitstype, &attlen) != -1 && hdfunitstype == DFNT_CHAR) { if(dimunits && SDreadattr(sds_id, attr_index, dimunits)==-1) return -1; } /* Dimension variable was found, but no character units string */ else{ if(dimunits) strcpy(dimunits,""); } if(dataType) { cumapdatatype_hdf(hdftype, dataType); if (*dataType==CuInvalidType) return -1; } } else{ /* The dimension variable was not found: */ /* return default units and datatype */ if(dimunits) strcpy(dimunits,""); if(dataType) *dataType = CuFloat; } /* Return success ( 0 ). */ return CU_SUCCESS; }
static intn test_dim1_SDS1(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 out_data[5]; int32 dimsize[1]; int32 sds_id, file_id, dim_id, index; int32 start=0, stride=1; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 num_type, array_rank, count; int32 n_datasets, n_file_attrs, n_local_attrs, n_vars = 0; intn datanum, ranknum, status =0, i, idx, idx1, idx2; hdf_varlist_t* var_list; intn is_coord = FALSE; char attr_name[H4_MAX_NC_NAME], attr_values[80]; intn num_errs = 0; /* number of errors so far */ file_id = SDstart(FILE1, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); /* Create a one-dim dataset named VAR1_NAME, of type DFNT_FLOAT32. */ dimsize[0] = 5; sds_id = SDcreate(file_id, VAR1_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as its dataset. */ dim_id = SDgetdimid(sds_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, VAR1_NAME); /* status = SDsetdimname(dim_id, VAR1_NAME); */ CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there is 1 dataset in the file. */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 1, "SDfileinfo"); /* Set an attribute to dimension VAR1_NAME. */ status = SDsetattr(dim_id, ATTR1_NAME, DFNT_CHAR8, ATTR1_LEN, ATTR1_VAL); CHECK(status, FAIL, "SDsetattr"); /* Set an attribute to dataset VAR1_NAME. */ status = SDsetattr(sds_id, ATTR2_NAME, DFNT_CHAR8, ATTR2_LEN, ATTR2_VAL); CHECK(status, FAIL, "SDsetattr"); /* Get file info and verify that there are 2 datasets in the file: 1 SDS and 1 coordinate variable (because of SDsetattr dim) */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); /* Write data to the SDS */ status = SDwritedata(sds_id, &start, &stride, dimsize, (VOIDP)sds1_data); CHECK(status, FAIL, "SDwritedata"); /* Close dataset and file. */ status = SDendaccess(sds_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Open the file again to check its data */ file_id = SDstart(FILE1, DFACC_RDWR); CHECK(file_id, FAIL, "SDstart"); /* Check variable type and attributes of each element in the file */ /* Get the number of variables of name VAR1_NAME */ status = SDgetnumvars_byname(file_id, VAR1_NAME, &n_vars); if (n_vars == 1) { /* Get index of dataset VAR1_NAME */ index = SDnametoindex(file_id, VAR1_NAME); CHECK(index, FAIL, "SDnametoindex"); } else { /* Get the list of all variables of named VAR1_NAME */ var_list = (hdf_varlist_t *)HDmalloc(n_vars * sizeof(hdf_varlist_t)); status = SDnametoindices(file_id, VAR1_NAME, var_list); /* In this case, the first variable is a dataset */ for (idx = 0; idx < n_vars; idx++) { if (var_list[idx].var_type == IS_SDSVAR) { index = var_list[idx].var_index; VERIFY(index, 0, "SDnametoindices"); } } } sds_id = SDselect(file_id, index); CHECK(sds_id, FAIL, "SDselect"); /* Verify that this variable is a dataset. */ is_coord = SDiscoordvar(sds_id); VERIFY(is_coord, FALSE, "SDiscoordvar"); /* Read and verify the information of the SDS' first attribute. */ status = SDattrinfo(sds_id, 0, attr_name, &num_type, &count); CHECK(status, FAIL, "SDattrinfo"); VERIFY(count, ATTR2_LEN, "SDattrinfo"); VERIFY(HDstrncmp(attr_name, ATTR2_NAME, 14), 0, "SDattrinfo"); /* Read and verify the values of the SDS' first attribute. */ status = SDreadattr(sds_id, 0, attr_values); CHECK(status, FAIL, "SDreadattr"); if (HDstrncmp(attr_values, ATTR2_VAL, ATTR2_LEN) != 0) { fprintf(stderr, "Unmatched attribute values for SDS %s: is <%s>, should be <%s>\n", VAR1_NAME, attr_values, ATTR2_VAL); num_errs++; } /* Get access to the SDS' first dimension. */ dim_id = SDgetdimid(sds_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); /* Read and verify the information of the dimension's first attribute. */ status = SDattrinfo(dim_id, 0, attr_name, &num_type, &count); CHECK(status, FAIL, "SDattrinfo"); VERIFY(count, 19, "SDattrinfo"); VERIFY(HDstrncmp(attr_name, ATTR1_NAME, 21), 0, "SDattrinfo"); /* Read and verify the values of the dimension's first attribute. */ status = SDreadattr(dim_id, 0, attr_values); CHECK(status, FAIL, "SDreadattr"); if (HDstrncmp(attr_values, ATTR1_VAL, ATTR1_LEN) != 0) { fprintf(stderr, "Unmatched attribute values for dimension %s: is <%s>, should be <%s>\n", VAR1_NAME, attr_values, ATTR1_VAL); num_errs++; } /* Verify again that the number of datasets in the file is 2, 1 SDS and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); VERIFY(n_file_attrs, 0, "SDfileinfo"); /* Read and verify the dataset's data */ status = SDreaddata (sds_id, &start, NULL, dimsize, &out_data); CHECK(status, FAIL, "SDreaddata"); for (idx1 = 0; idx1 < dimsize[0]; idx1++) if (out_data[idx1] != sds1_data[idx1]) { fprintf(stderr, "Read value (%f) differs from written (%f) at [%d]\n", out_data[idx1], sds1_data[idx1], idx1); num_errs++; } /* Close dataset and file. */ status = SDendaccess(sds_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_dim1_SDS1 */
static intn test_named_vars(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 sds2_data[2][3] = {{0.1, 2.3, 4.5}, {4.5, 6.7, 8.9}}; int32 dimsize[1], dimsize2[2]; int32 sds_id, sds1_id, sds2_id, sds3_id, sds4_id, sds5_id; int32 file_id, dim_id, index; int32 start=0, stride=1, stat; int32 start2[2]={0,0}, stride2[2]={1,1}; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 array_rank; int32 n_datasets, n_file_attrs, n_local_attrs, n_vars=0; float32 out_data2[2][3]; intn datanum, ranknum, status =0, idx, idx1, idx2; intn is_coordvar=FALSE; hdf_varlist_t *allvars, *varlistp; intn num_errs = 0; /* number of errors so far */ char line[40]; char contents[7][40]={ "#0 SDS 2-dim 'Common Name'", "#1 SDS 2-dim 'Common Name'", "#2 SDS 1-dim 'One Dimension'", "#3 Coordinate 1-dim 'Common Name'", "#4 SDS 1-dim 'One Dimension'", "#5 SDS 1-dim 'Another Name'", "#6 Coordinate 1-dim 'Another Name'"}; file_id = SDstart(FILE3, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); dimsize2[0] = 2; dimsize2[1] = 3; /* Create first COMMON_NAME data set. */ sds1_id = SDcreate(file_id, COMMON_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds1_id, FAIL, "SDcreate"); status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); /* Create second COMMON_NAME data set. */ sds2_id = SDcreate(file_id, COMMON_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds2_id, FAIL, "SDcreate"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); dimsize[0] = 5; sds3_id = SDcreate(file_id, ONEDIM_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds3_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the previous 2 datasets */ dim_id = SDgetdimid(sds3_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, COMMON_NAME); CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there are 3 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); /* Write values to the dimension COMMON_NAME (same name as first 2 datasets) */ status = SDsetdimscale (dim_id, dimsize[0], DFNT_INT32, scale1); CHECK(status, FAIL, "SDsetdimscale"); /* Get file info and verify that there are 4 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 4, "SDfileinfo"); dimsize[0] = 8; sds4_id = SDcreate(file_id, ONEDIM_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds4_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the previous 2 datasets */ dim_id = SDgetdimid(sds4_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, ANOTHER_NAME); CHECK(status, FAIL, "SDsetdimname"); sds5_id = SDcreate(file_id, ANOTHER_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds5_id, FAIL, "SDcreate"); /* Get file info and verify that there are 6 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 6, "SDfileinfo"); status = SDsetattr(dim_id, ATTR1_NAME, DFNT_CHAR8, ATTR1_LEN, ATTR1_VAL); CHECK(status, FAIL, "SDsetattr"); /* Get file info and verify that there are 7 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 7, "SDfileinfo"); /* Verify again that the number of datasets in the file is 7 */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 7, "SDfileinfo"); /* There are 3 variables of name COMMON_NAME */ status = SDgetnumvars_byname(file_id, COMMON_NAME, &n_vars); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_vars, 3, "SDfileinfo"); allvars = (hdf_varlist_t *)HDmalloc(n_vars * sizeof(hdf_varlist_t)); status = SDnametoindices(file_id, COMMON_NAME, allvars); CHECK(status, FAIL, "SDfileinfo"); /* Compare file contents with predefined text to verify */ for (idx = 0; idx < n_datasets; idx++) { sds_id = SDselect(file_id, idx); CHECK(sds_id, FAIL, "SDselect"); status = SDgetinfo(sds_id, sds_name, &array_rank, NULL, NULL, NULL); CHECK(status, FAIL, "SDgetinfo"); is_coordvar = SDiscoordvar(sds_id); if (is_coordvar) sprintf(line,"#%d Coordinate %d-dim '%s'\n", idx, array_rank, sds_name); else sprintf(line,"#%d SDS %d-dim '%s'\n", idx, array_rank, sds_name); if (strncmp(contents[idx], line, strlen(contents[idx])) != 0) { fprintf(stderr, "File contents are incorrect in testing variable types at variable of index %d\n", idx); } } status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_named_vars */
static intn test_dim1_SDS2(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 sds2_data[2][3] = {{0.1, 2.3, 4.5}, {4.5, 6.7, 8.9}}; int32 dimsize[1], dimsize2[2]; int32 sds1_id, sds2_id, file_id, dim_id, index; int32 start=0, stride=1, stat; int32 start2[2]={0,0}, stride2[2]={1,1}; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 num_type, array_rank, attributes; int32 n_datasets, n_file_attrs, n_local_attrs; float32 out_data2[2][3]; intn datanum, ranknum, status =0, i, idx, idx1, idx2; intn num_errs = 0; /* number of errors so far */ file_id = SDstart(FILE2, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); dimsize[0] = 5; dimsize2[0] = 2; dimsize2[1] = 3; sds1_id = SDcreate(file_id, VAR1_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds1_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the next dataset (not created yet) */ dim_id = SDgetdimid(sds1_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, VAR2_NAME); CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there is 1 dataset in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 1, "SDfileinfo"); /* Create and write data to the second dataset VAR2_NAME */ sds2_id = SDcreate(file_id, VAR2_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds2_id, FAIL, "SDcreate"); stat = SDwritedata(sds2_id, start2, stride2, dimsize2, sds2_data); CHECK(status, FAIL, "SDwritedata"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); /* Get file info and verify that there are 2 datasets in the file. */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); /* Write values to the dimension VAR2_NAME (same name as VAR2_NAME) */ status = SDsetdimscale (dim_id, dimsize[0], DFNT_INT32, scale1); CHECK(status, FAIL, "SDsetdimscale"); /* Get file info and verify that there are 3 datasets in the file: 2 SDS and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); /* Close dataset and file */ status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Open the file again to check its data */ file_id = SDstart(FILE2, DFACC_RDWR); CHECK(file_id, FAIL, "SDstart"); /* Verify dimension scale of the first dimension of SDS VAR1_NAME */ /* Get access to dataset VAR1_NAME */ index = SDnametoindex(file_id, VAR1_NAME); CHECK(index, FAIL, "SDnametoindex"); sds1_id = SDselect(file_id, index); CHECK(sds1_id, FAIL, "SDselect"); /* Get access to its first dimension */ dim_id = SDgetdimid(sds1_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); /* Get dimension scale and verify the values */ status = SDgetdimscale (dim_id, scale1_out); CHECK(status, FAIL, "SDgetdimscale"); for (idx = 0; idx < dimsize[0]; idx++) if (scale1_out[idx] != scale1[idx]) { fprintf(stderr, "Read value (%d) differs from written (%d) at [%d]\n", scale1_out[idx], scale1[idx], idx); num_errs++; } /* End verifying dimension scale */ /* Verify dimension scale of the first dimension of SDS VAR1_NAME */ /* Get access to dataset VAR2_NAME */ index = SDnametoindex(file_id, VAR2_NAME); CHECK(index, FAIL, "SDnametoindex"); sds2_id = SDselect(file_id, index); CHECK(sds2_id, FAIL, "SDselect"); /* Get dataset's info and verify them */ status = SDgetinfo(sds2_id, sds_name, &array_rank, dimsize2, &num_type, &n_local_attrs); CHECK(status, FAIL, "SDgetinfo"); VERIFY(array_rank, 2, "SDfileinfo"); VERIFY(num_type, DFNT_FLOAT32, "SDfileinfo"); VERIFY(n_local_attrs, 0, "SDfileinfo"); /* Read and verify the dataset's data */ status = SDreaddata (sds2_id, start2, NULL, dimsize2, &out_data2); CHECK(status, FAIL, "SDreaddata"); for (idx1 = 0; idx1 < dimsize2[0]; idx1++) for (idx2 = 0; idx2 < dimsize2[1]; idx2++) { if (out_data2[idx1][idx2] != sds2_data[idx1][idx2]) { fprintf(stderr, "Read value (%f) differs from written (%f) at [%d][%d]\n", out_data2[idx1][idx2], sds2_data[idx1][idx2], idx1, idx2); num_errs++; } } /* Verify again that the number of datasets in the file is 3, 2 SDSs and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_dim1_SDS2 */
int main(int argc,char **argv) { int32 sdsout_id; int32 dimout_id; int32 sdout_id; int32 index,count,start[MAX_VAR_DIMS]; int32 edge[MAX_VAR_DIMS]; int32 rank,data_type; int32 dim_sizes[MAX_VAR_DIMS]; char name[MAX_NC_NAME]; char names[2][MAX_NC_NAME]; int write_metadata; float32 scalef=1.0; float32 addoff=0.0; char* oz_units= "Dobson"; int16 doy; int idoy,year,nlats,nlons; float minlat, minlon, maxlat, maxlon, latsteps,lonsteps; short int* data; int16 base_date[3]; float lat_array[1024], lon_array[1024]; char* platform= argc>3 ? argv[3] : (char*) "Earthprobe"; if (argc<3) { fprintf(stderr,"usage: %s <input> <output> <platform>\n",argv[0]); exit(-1); } verbose=0; /**** open input ****/ /* determine NLINE by sensor - Feng */ if(strstr(argv[1], "omi")) { NLINE = 15; longline = 25; shortline = 10; } else { NLINE =12; longline =25; shortline = 13; } printf("%d %d %d\n", NLINE, longline, shortline); read_ozone(argv[1], &data, &idoy, &year, &nlats,&nlons, &minlat, &minlon, &maxlat, &maxlon, &latsteps, &lonsteps, lat_array, lon_array); if ( nlats!=180 || fabs(minlat+ 89.500)>0.0001 || fabs(maxlat- 89.500)>0.0001 || nlons!=288 || fabs(minlon+179.375)>0.0001 || fabs(maxlon-179.375)>0.0001 || fabs(latsteps-1.0)>0.0001 || fabs(lonsteps-1.25)>0.0001 )printf( "*** unexpected values ***\n nlats=%d nlons=%d minlat=%f maxlat=%f minlon=%f maxlon=%f\n" ,nlats,nlons,minlat,maxlat,minlon,maxlon); /**** check and open output ****/ write_metadata=0; if ((sdout_id=SDstart(argv[2], DFACC_RDONLY))<0) { if ((sdout_id=SDstart(argv[2], DFACC_CREATE))<0) { fprintf(stderr,"can't create output %s\n",argv[2]); exit(-1); } write_metadata=1; } else { SDend(sdout_id); if ((sdout_id=SDstart(argv[2], DFACC_WRITE))<0) { fprintf(stderr,"can't open output %s\n",argv[2]); exit(-1); } } doy=(int16)idoy; /**** Determine the contents of the file ****/ if (write_metadata) { /**** Copy global attributes to output if creating a new file Write Day Of Year to output ****/ base_date[0]= year; base_date[1]=1; base_date[2]=1; SDsetattr(sdout_id, "base_date", DFNT_INT16,3,base_date); SDsetattr(sdout_id, "Day Of Year", DFNT_INT16,1,&doy); count=strlen(platform)+1; printf("*** platform=(%s) len=%d ***\n",platform,count); SDsetattr(sdout_id,"Platform",DFNT_CHAR8,count,(void*)platform); /**** Copy lat/lon SDS ****/ /************************/ /**** Latitude (lat) ****/ /************************/ dim_sizes[0]= nlats; strcpy(name,"lat"); strcpy(names[0],"lat"); rank=1; if ((sdsout_id=SDcreate(sdout_id,name,DFNT_FLOAT32,rank,&dim_sizes[0]))<0) return -1; start[0]=0; edge[0]=dim_sizes[0]; if (SDwritedata(sdsout_id,start,NULL,edge,lat_array)<0) return -1; dimout_id=SDgetdimid(sdsout_id, 0); SDsetdimname(dimout_id, name); /*************************/ /**** Longitude (lon) ****/ /*************************/ dim_sizes[0]= nlons; strcpy(name,"lon"); strcpy(names[1],"lon"); rank=1; if ((sdsout_id=SDcreate(sdout_id,name,DFNT_FLOAT32,rank,&dim_sizes[0]))<0) return -1; start[0]=0; edge[0]=dim_sizes[0]; if (SDwritedata(sdsout_id,start,NULL,edge,lon_array)<0) return -1; dimout_id=SDgetdimid(sdsout_id, 0); SDsetdimname(dimout_id, name); /************************/ /**** Ozone (ozone) ****/ /************************/ dim_sizes[0]= nlats; dim_sizes[1]= nlons; strcpy(name,"ozone"); rank=2; if ((sdsout_id=SDcreate(sdout_id,name,DFNT_INT16,rank,&dim_sizes[0]))<0) return -1; start[0]=0; start[1]=0; edge[0]=dim_sizes[0]; edge[1]=dim_sizes[1]; if (SDwritedata(sdsout_id,start,NULL,edge,data)<0) return -1; for (index=0;index<rank;index++) { dimout_id=SDgetdimid(sdsout_id, index); SDsetdimname(dimout_id, names[index]); } strcpy(name,"scale_factor"); count=1; data_type= DFNT_FLOAT32; SDsetattr(sdsout_id, name, data_type, count, (void*)&scalef); strcpy(name,"add_offset"); count=1; data_type= DFNT_FLOAT32; SDsetattr(sdsout_id, name, data_type, count, (void*)&addoff); strcpy(name,"units"); count=strlen(oz_units)+1; data_type= DFNT_CHAR8; SDsetattr(sdsout_id, name, data_type, count, (void*)oz_units); } /**** Close input & output ****/ SDend(sdout_id); return 0; }
int main(int argc, char **argv) { printf("\n*** Testing HDF4/NetCDF-4 interoperability...\n"); printf("*** testing that netCDF can read a HDF4 file with some ints..."); { #define PRES_NAME "pres" #define LAT_LEN 3 #define LON_LEN 2 #define DIMS_2 2 int32 sd_id, sds_id; int32 dim_size[DIMS_2] = {LAT_LEN, LON_LEN}; int32 start[DIMS_2] = {0, 0}, edge[DIMS_2] = {LAT_LEN, LON_LEN}; int ncid, nvars_in, ndims_in, natts_in, unlimdim_in; size_t len_in; int data_out[LAT_LEN][LON_LEN], data_in[LAT_LEN][LON_LEN]; size_t nstart[DIMS_2] = {0, 0}, ncount[DIMS_2] = {LAT_LEN, LON_LEN}; size_t nindex[DIMS_2] = {0, 0}; int scalar_data_in = 0; int i, j; /* Create some data. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) data_out[i][j] = j; /* Create a file with one SDS, containing our phony data. */ sd_id = SDstart(FILE_NAME, DFACC_CREATE); sds_id = SDcreate(sd_id, PRES_NAME, DFNT_INT32, DIMS_2, dim_size); if (SDwritedata(sds_id, start, NULL, edge, (void *)data_out)) ERR; if (SDendaccess(sds_id)) ERR; if (SDend(sd_id)) ERR; /* Now open with netCDF and check the contents. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR; if (ndims_in != 2 || nvars_in != 1 || natts_in != 0 || unlimdim_in != -1) ERR; if (nc_inq_dim(ncid, 0, NULL, &len_in)) ERR; if (len_in != LAT_LEN) ERR; if (nc_inq_dim(ncid, 1, NULL, &len_in)) ERR; if (len_in != LON_LEN) ERR; /* Read the data through a vara function from the netCDF API. */ if (nc_get_vara(ncid, 0, nstart, ncount, data_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (data_in[i][j] != data_out[i][j]) ERR; /* Reset for next test. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) data_in[i][j] = -88; /* Read the data through a vara_int function from the netCDF API. */ if (nc_get_vara_int(ncid, 0, nstart, ncount, data_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (data_in[i][j] != data_out[i][j]) ERR; /* Reset for next test. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) data_in[i][j] = -88; /* Read the data through a var_int function from the netCDF API. */ if (nc_get_var_int(ncid, 0, data_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (data_in[i][j] != data_out[i][j]) ERR; /* Read the data through a var1 function from the netCDF API. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) { nindex[0] = i; nindex[1] = j; if (nc_get_var1(ncid, 0, nindex, &scalar_data_in)) ERR; if (scalar_data_in != data_out[i][j]) ERR; scalar_data_in = -88; /* reset */ if (nc_get_var1_int(ncid, 0, nindex, &scalar_data_in)) ERR; if (scalar_data_in != data_out[i][j]) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing with a more complex HDF4 file..."); { #define Z_LEN 3 #define Y_LEN 2 #define X_LEN 5 #define DIMS_3 3 #define NUM_TYPES 8 int32 sd_id, sds_id; int32 dim_size[DIMS_3] = {Z_LEN, Y_LEN, X_LEN}; int dimids_in[DIMS_3]; int ncid, nvars_in, ndims_in, natts_in, unlimdim_in; size_t len_in; nc_type type_in; int hdf4_type[NUM_TYPES] = {DFNT_FLOAT32, DFNT_FLOAT64, DFNT_INT8, DFNT_UINT8, DFNT_INT16, DFNT_UINT16, DFNT_INT32, DFNT_UINT32}; int netcdf_type[NUM_TYPES] = {NC_FLOAT, NC_DOUBLE, NC_BYTE, NC_UBYTE, NC_SHORT, NC_USHORT, NC_INT, NC_UINT}; char tmp_name[NC_MAX_NAME + 1], name_in[NC_MAX_NAME + 1]; char dim_name[NC_MAX_NAME + 1][DIMS_3] = {"z", "y", "x"}; int d, t; /* Create a HDF4 SD file. */ sd_id = SDstart (FILE_NAME, DFACC_CREATE); /* Create some HDF4 datasets. */ for (t = 0; t < NUM_TYPES; t++) { sprintf(tmp_name, "hdf4_dataset_type_%d", t); if ((sds_id = SDcreate(sd_id, tmp_name, hdf4_type[t], DIMS_3, dim_size)) == FAIL) ERR; /* Set up dimensions. By giving them the same names for each * dataset, I am specifying that they are shared * dimensions. */ for (d = 0; d < DIMS_3; d++) { int32 dimid; if ((dimid = SDgetdimid(sds_id, d)) == FAIL) ERR; if (SDsetdimname(dimid, dim_name[d])) ERR; } if (SDendaccess(sds_id)) ERR; } if (SDend(sd_id)) ERR; /* Open the file with netCDF and check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR; if (ndims_in != DIMS_3 || nvars_in != NUM_TYPES || natts_in != 0 || unlimdim_in != -1) ERR; if (nc_inq_dim(ncid, 0, NULL, &len_in)) ERR; if (len_in != Z_LEN) ERR; if (nc_inq_dim(ncid, 1, NULL, &len_in)) ERR; if (len_in != Y_LEN) ERR; if (nc_inq_dim(ncid, 2, NULL, &len_in)) ERR; if (len_in != X_LEN) ERR; for (t = 0; t < NUM_TYPES; t++) { if (nc_inq_var(ncid, t, name_in, &type_in, &ndims_in, dimids_in, &natts_in)) ERR; if (type_in != netcdf_type[t] || ndims_in != DIMS_3 || dimids_in[0] != 0 || dimids_in[2] != 2 || dimids_in[2] != 2 || natts_in != 0) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }