InputPrwv_t *OpenInputPrwv(char *file_name) /* !C****************************************************************************** !Description: 'OpenInputPrwv' sets up the 'input' data structure, opens the input file for read access. !Input Parameters: file_name input file name sds_name name of sds to be read iband band number for application of band offset rank rank of the input SDS dim dimension flags; the line and sample dimensions are indicated by a -1 and -2 in this array, respectively; the index in the other dimensions are indicated by a value of zero or greater input_space_type input space type; either 'SWATH_SPACE' for L1 and L2 input data or 'GRID_SPACE' for L2G, L3 and L4 input data !Output Parameters: dim dimension flags (returns) 'input' data structure or NULL when an error occurs !Team Unique Header: ! Design Notes: 1. When 'OpenInputPrwv' returns, the file is open for HDF access and the SDS is open for access. 2. For an input space type of 'GRID_SPACE', a band number of -1 should be given. 3. The only input HDF data types supported are CHAR8, UNIT8, INT16 and UNIT16. 4. An error status is returned when: a. the SDS rank is less than 2 or greater than 'MYHDF_MAX_RANK' b. the band number is less than -1 or greater than or equal to 'NBAND_OFFSET' c. either none or more than one dimension is given for the line or sample dimension d. an invalid dimension field is given e. duplicating strings is not successful f. errors occur when opening the input HDF file g. errors occur when reading SDS dimensions or attributes h. errors occur when opening the SDS for read access i. the given SDS rank or dimensions do not match the input file j. for a input space type of SWATH_SPACE, the dimensions of a swath are not 1, 2 or 4 times the nominal size of a MODIS swath k. for a input space type of SWATH_SPACE, the number of lines is not an integral multiple of the size of the scan at the given resolution l. memory allocation is not successful m. an invalid input data type is not supported. 5. Error messages are handled with the 'RETURN_ERROR' macro. 6. 'FreeInputPrwv' should be called to deallocate memory used by the 'input' data structures. 7. 'CloseInputPrwv' should be called after all of the data is written and before the 'input' data structure memory is released. !END**************************************************************************** */ { InputPrwv_t *this; char *error_string = (char *)NULL; char sds_name[40]; int ir; bool sds_open[NBAND_REFL_MAX]; Myhdf_dim_t *dim[3]; int ib,osize; float *buf = NULL; const char* input_names[INPUT_NBANDS]={INPUT_NAME1,INPUT_NAME2,INPUT_NAME3}; /* Create the Input data structure */ this = (InputPrwv_t *)malloc(sizeof(InputPrwv_t)); if (this == (InputPrwv_t *)NULL) RETURN_ERROR("allocating InputPrwv data structure", "OpenInputPrwv", (InputPrwv_t *)NULL); /* Populate the data structure */ this->file_name = DupString(file_name); if (this->file_name == (char *)NULL) { free(this); RETURN_ERROR("duplicating file name", "OpenInputPrwv", (InputPrwv_t *)NULL); } /* Open file for SD access */ this->sds_file_id = SDstart((char *)file_name, DFACC_RDONLY); if (this->sds_file_id == HDF_ERROR) { free(this->file_name); free(this); RETURN_ERROR("opening input file", "OpenInputPrwv", (InputPrwv_t *)NULL); } this->open = true; /* Get the input metadata */ if (!GetInputPrwvMeta(this)) { free(this->file_name); free(this); RETURN_ERROR("getting input metadata", "OpenInputPrwv", (InputPrwv_t *)NULL); } /* Get SDS information and start SDS access */ for (ib = 0; ib < this->nband; ib++) { this->sds[ib].name = (char *)NULL; this->sds[ib].dim[0].name = (char *)NULL; this->sds[ib].dim[1].name = (char *)NULL; this->sds[ib].dim[2].name = (char *)NULL; sds_open[ib] = false; this->buf[ib] = (float *)NULL; } for (ib = 0; ib < this->nband; ib++) { if (sprintf(sds_name, "%s", input_names[ib]) < 0) { error_string = "creating SDS name"; break; } this->sds[ib].name = DupString(sds_name); if (this->sds[ib].name == (char *)NULL) { error_string = "setting SDS name"; break; } if (!GetSDSInfo(this->sds_file_id, &this->sds[ib])) { error_string = "getting sds info"; break; } sds_open[ib] = true; /* Check rank */ if (this->sds[ib].rank != 2 && this->sds[ib].rank != 3 ) { error_string = "invalid rank"; break; } /* Check SDS type */ if (this->sds[ib].type != DFNT_FLOAT) { error_string = "invalid data type -- should be float"; break; } /* Get dimensions */ for (ir = 0; ir < this->sds[ib].rank; ir++) { dim[ir] = &this->sds[ib].dim[ir]; if (!GetSDSDimInfo(this->sds[ib].id, dim[ir], ir)) { error_string = "getting dimensions"; break; } } if (error_string != (char *)NULL) break; /* Save and check line and sample dimensions */ if (ib == 0) { this->size.ntime = dim[0]->nval; this->size.nlat = dim[1]->nval; this->size.nlon = dim[2]->nval; } else { if (this->size.ntime != dim[0]->nval) { error_string = "all time dimensions do not match"; break; } if (this->size.nlat != dim[1]->nval) { error_string = "all lat dimensions do not match"; break; } if (this->size.nlon != dim[2]->nval) { error_string = "all lat dimensions do not match"; break; } } /* Set the scale factor and offset since they don't exist in the global attributes */ this->scale_factor[ib] = 1.0; this->add_offset[ib] = 0.0; } /* Allocate input buffer */ osize= 3 * ( this->size.ntime * this->size.nlat * this->size.nlon ); buf = calloc((size_t)(osize), sizeof(float)); if (buf == NULL) error_string = "allocating input buffer"; else { this->buf[0] = buf; for (ib = 1; ib < this->nband; ib++) this->buf[ib] = this->buf[ib - 1] + ( this->size.ntime * this->size.nlat * this->size.nlon ); } if (error_string != (char *)NULL) { for (ib = 0; ib < this->nband; ib++) { for (ir = 0; ir < this->sds[ib].rank; ir++) { if (this->sds[ib].dim[ir].name != (char *)NULL) free(this->sds[ib].dim[ir].name); } if (sds_open[ib]) SDendaccess(this->sds[ib].id); if (this->sds[ib].name != (char *)NULL) free(this->sds[ib].name); if (this->buf[ib] != NULL) free(this->buf[ib]); } SDend(this->sds_file_id); free(this->file_name); free(this); RETURN_ERROR(error_string, "OpenInputPrwv", (InputPrwv_t *)NULL); } return this; }
Geoloc_t *OpenGeolocSwath(char *file_name) /* !C****************************************************************************** !Description: 'OpenGeolocSwath' sets up the 'geoloc' data structure and opens the input geolocation file for read access. !Input Parameters: file_name geolocation file name !Output Parameters: (returns) 'geoloc' data structure or NULL when an error occurs !Team Unique Header: ! Design Notes: 1. When 'OpenGeolocSwath' returns, the file is open for HDF access and the SDS is open for access. 2. An error status is returned when: a. duplicating strings is not successful b. errors occur when opening the input HDF file c. errors occur when opening the SDSs for read access d. errors occur when reading SDS dimensions or attributes e. the ranks of the SDSs are not 2 f. the number of lines is not an integral multiple of the size of a MODIS 1km scan ('NDET_1KM_MODIS') g. the dimensions of the latitude and longitude arrays don't match h. memory allocation is not successful 3. Error messages are handled with the 'LOG_RETURN_ERROR' macro. 4. 'FreeGeoloc' should be called to deallocate memory used by the 'geoloc' data structures. 5. 'CloseGeoloc' should be called after all of the data is written and before the 'geoloc' data structure memory is released. !END**************************************************************************** */ { Geoloc_t *this; Myhdf_sds_t *sds; int i, ir, ib, ib1; int ir1; size_t n; Img_coord_double_t *img_p; char *error_string = (char *)NULL; double fill[MYHDF_MAX_NATTR_VAL]; Myhdf_attr_t attr; /* Create the Geoloc data structure */ this = (Geoloc_t *)malloc(sizeof(Geoloc_t)); if (this == (Geoloc_t *)NULL) LOG_RETURN_ERROR("allocating Geoloc structure", "OpenGeolocSwath", (Geoloc_t *)NULL); /* Populate the data structure */ this->geoloc_type = SWATH_GEOLOC; this->file_name = DupString(file_name); if (this->file_name == (char *)NULL) { free(this); LOG_RETURN_ERROR("duplicating file name", "OpenGeolocSwath", (Geoloc_t *)NULL); } this->sds_lat.name = DupString(GEOLOC_LAT_SDS); if (this->sds_lat.name == (char *)NULL) { free(this->file_name); free(this); LOG_RETURN_ERROR("duplicating sds name", "OpenGeolocSwath", (Geoloc_t *)NULL); } this->sds_lon.name = DupString(GEOLOC_LON_SDS); if (this->sds_lon.name == (char *)NULL) { free(this->sds_lat.name); free(this->file_name); free(this); LOG_RETURN_ERROR("duplicating sds name", "OpenGeolocSwath", (Geoloc_t *)NULL); } /* Set up the band offsets */ for (ib = 0; ib < NBAND_MODIS; ib++) this->band_offset[ib].l = this->band_offset[ib].s = 0.0; for (ib = 0; ib < NBAND_OFFSET_GEN; ib++) { ib1 = ib + NBAND_MODIS; this->band_offset[ib1].l = band_offset_gen[ib].l; this->band_offset[ib1].s = band_offset_gen[ib].s; } /* Open file for SD access */ this->sds_file_id = SDstart((char *)file_name, DFACC_RDONLY); if (this->sds_file_id == HDF_ERROR) { free(this->sds_lat.name); free(this->sds_lon.name); free(this->file_name); free(this); LOG_RETURN_ERROR("opening geolocation file", "OpenGeolocSwath", (Geoloc_t *)NULL); } this->open = true; /* Open the latitude and longitude SDSs */ for (i = 0; i < 2; i++) { sds = (i == 1) ? &this->sds_lat : &this->sds_lon; /* Get SDS information and start SDS access */ if (!GetSDSInfo(this->sds_file_id, sds)) { SDend(this->sds_file_id); free(this->sds_lat.name); free(this->sds_lon.name); free(this->file_name); free(this); LOG_RETURN_ERROR("getting sds info", "OpenGeolocSwath", (Geoloc_t *)NULL); } /* Check rank and type */ if (sds->rank != 2) error_string = "invalid rank"; else if (sds->type != DFNT_FLOAT32) error_string = "invalid type"; /* Get dimensions */ if (error_string == (char *)NULL) { for (ir = 0; ir < sds->rank; ir++) { if (!GetSDSDimInfo(sds->id, &sds->dim[ir], ir)) { for (ir1 = 0; ir1 < ir; ir1++) free(sds->dim[ir1].name); error_string = "getting dimension"; } } } /* Get fill value */ if (error_string == (char *)NULL) { attr.name = FILL_ATTR_NAME; if (!GetAttrDouble(sds->id, &attr, fill)) error_string = "getting fill value"; else { if (i == 1) this->lat_fill = (float32)fill[0]; else this->lon_fill = (float32)fill[0]; } } if (error_string != (char *)NULL) { SDendaccess(sds->id); if (i > 0) { sds = &this->sds_lat; for (ir = 0; ir < sds->rank; ir++) free(sds->dim[ir].name); SDendaccess(sds->id); } SDend(this->sds_file_id); free(this->sds_lat.name); free(this->sds_lon.name); free(this->file_name); free(this); LOG_RETURN_ERROR(error_string, "OpenGeolocSwath", (Geoloc_t *)NULL); } } /* Check dimensions */ this->scan_size.l = NDET_1KM_MODIS; this->scan_size.s = this->sds_lat.dim[1].nval; this->scan_size_geo.l = this->scan_size.l; this->scan_size_geo.s = this->scan_size.s; this->size.l = this->sds_lat.dim[0].nval; this->size.s = this->sds_lat.dim[1].nval; this->nscan = this->size.l / this->scan_size.l; if ((this->nscan * this->scan_size.l) != this->size.l) error_string = "not an integral number of scans"; else if (this->size.l != this->sds_lon.dim[0].nval) error_string = "number of lines don't match"; else if (this->size.s != this->sds_lon.dim[1].nval) error_string = "number of samples don't match"; /* Allocate buffers */ this->n_nest = -1; this->img = (Img_coord_double_t **)NULL; this->geo = (Geo_coord_t **)NULL; this->lat_buf = (float32 *)NULL; this->lon_buf = (float32 *)NULL; if (error_string == (char *)NULL) { this->img = (Img_coord_double_t **)calloc((size_t)this->scan_size.l, sizeof(Img_coord_double_t *)); if (this->img == (Img_coord_double_t **)NULL) error_string = "allocating image location buffer array"; } if (error_string == (char *)NULL) { n = (size_t)(this->scan_size.l * this->scan_size.s); img_p = (Img_coord_double_t *)calloc(n, sizeof(Img_coord_double_t)); if (img_p == (Img_coord_double_t *)NULL) error_string = "allocating image location buffer"; } if (error_string == (char *)NULL) { for (i = 0; i < this->scan_size.l; i++) { this->img[i] = img_p; img_p += this->scan_size.s; } this->lat_buf = (float32 *)calloc(this->scan_size.s, sizeof(float32)); if (this->lat_buf == (float32 *)NULL) error_string = "allocating latitude buffer"; } if (error_string == (char *)NULL) { this->lon_buf = (float32 *)calloc(this->scan_size.s, sizeof(float32)); if (this->lon_buf == (float32 *)NULL) error_string = "allocating longitude buffer"; } if (error_string != (char *)NULL) { if (this->lon_buf != (float32 *)NULL) free(this->lon_buf); if (this->lat_buf != (float32 *)NULL) free(this->lat_buf); if (this->img != (Img_coord_double_t **)NULL) { if (this->img[0] != (Img_coord_double_t *)NULL) free(this->img[0]); free(this->img); } for (i = 0; i < 2; i++) { sds = (i == 1) ? &this->sds_lat : &this->sds_lon; for (ir = 0; ir < sds->rank; ir++) free(sds->dim[ir].name); SDendaccess(sds->id); } SDend(this->sds_file_id); free(this->sds_lat.name); free(this->sds_lon.name); free(this->file_name); free(this); LOG_RETURN_ERROR(error_string, "OpenGeolocSwath", (Geoloc_t *)NULL); } return this; }