Example #1
0
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;
}
Example #2
0
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;
}