Lut_t *GetLut(int nband, Input_meta_t *meta, Img_coord_int_t *input_size) {
  Lut_t *this;

  /* Create the lookup table data structure */

  this = (Lut_t *)malloc(sizeof(Lut_t));
  if (this == NULL) 
    RETURN_ERROR("allocating Input data structure", "OpenInput", NULL);

  /* Populate the data structure */
  this->nband = nband;
  this->in_fill = meta->fill;
  this->output_fill = OUTPUT_FILL;
  this->in_satu = INPUT_SATU;
  this->output_satu = OUTPUT_SATU;
  this->aerosol_fill = AEROSOL_FILL;
  this->ar_region_size.l = AEROSOL_REGION_NLINE;
  this->ar_region_size.s = AEROSOL_REGION_NSAMP;
  this->ar_size.l = ((input_size->l - 1) / this->ar_region_size.l) + 1;
  this->ar_size.s = ((input_size->s - 1) / this->ar_region_size.s) + 1;
  this->min_valid_sr = MIN_VALID_SR;
  this->max_valid_sr = MAX_VALID_SR;
  this->atmos_opacity_scale_factor= ATMOS_OPACITY_SCALE_FACTOR;
  this->scale_factor=     SCALE_FACTOR;     /* scale factor            */
  this->scale_factor_err= SCALE_FACTOR_ERR; /* scale factor error      */
  this->add_offset=       ADD_OFFSET;       /* add offset              */
  this->add_offset_err=   ADD_OFFSET_ERR;   /* add offset error        */
  this->calibrated_nt=    CALIBRATED_NT;    /* calibrated nt           */

  this->long_name_prefix = DupString(LONG_NAME_PREFIX);
  if (this->long_name_prefix == NULL) {
    free(this);
    RETURN_ERROR("duplicating long name prefix", "GetLut", NULL);
  }

  this->units = DupString(UNITS);
  if (this->units == NULL) {
    free(this);
    RETURN_ERROR("duplicating ref units", "GetLut", NULL);
  }

  if (!InputMetaCopy(meta, nband, &this->meta)) {
    free(this);
    RETURN_ERROR("copying input metadata", "GetLut", NULL);
  }

  return this;
}
Beispiel #2
0
Lut_t *GetLut(Param_t *param, int nband, Input_t *input) {
  Lut_t *this;
  int ib, iband;
  int jdoy, i;
  float dsun;
  char msgbuf[1024];
  Input_meta_t *input_meta= &(input->meta);

  /* Create the lookup table data structure */
  this = (Lut_t *)malloc(sizeof(Lut_t));
  if (this == NULL) 
    RETURN_ERROR("allocating Input data structure", "OpenInput", NULL);

  /* Populate the data structure */
  this->in_fill = 0;
  this->qa_fill = QA_FILL;
  this->qa_satu =  QA_SATU;

  /* Copy some information from the input metadata to the metadata for
     the look-up table, like path, row, satellite, instrument, gains, biases,
     K1/K2 consts, bands, etc. */
  if (!InputMetaCopy(input_meta, nband, &this->meta)) {
    free(this);
    RETURN_ERROR("copying input metadata", "GetLut", NULL);
  }
  this->out_fill = OUTPUT_FILL;
  this->out_satu = OUTPUT_SATU;

  /* Check the dates for MSS
     Notes: values for Landsats 4, 5 are only valid for data acquired after
     4/1/83 and 11/9/84, respectively.  Values for data *processed* during
     1972-1978 may be different for Landsat 1-3. */                            
  if (input_meta->inst == INST_MSS) {
    if ( input_meta->sat == SAT_LANDSAT_1 ||
         input_meta->sat == SAT_LANDSAT_2 ||
         input_meta->sat == SAT_LANDSAT_3 ) {
      if ( input_meta->prod_date.year > 1971 &&
           input_meta->prod_date.year < 1979 ) {
        sprintf(msgbuf,"Landsat_%1.1d production year=%4.4d valid only "
          "between 1972 and 1978", (int)(input_meta->sat+1),
          input_meta->prod_date.year );
        RETURN_ERROR(msgbuf, "GetLut", false);
      }
    }
    if ( input_meta->sat == SAT_LANDSAT_4 ) {
      if ( input_meta->acq_date.year < 1983 || 
         ( input_meta->acq_date.year == 1983 &&
           input_meta->acq_date.doy <= 91 ) ) {
        sprintf(msgbuf,"Landsat_%1.1d acq date (%2.2d/%2.2d/%4.4d) invalid "
          "before 4/1/83", (int)(input_meta->sat+1),
          input_meta->acq_date.month, input_meta->acq_date.day,
          input_meta->acq_date.year);
        RETURN_ERROR(msgbuf, "GetLut", false);
      }
    }
    if ( input_meta->sat == SAT_LANDSAT_5 ) {
      if ( input_meta->acq_date.year < 1984 || 
         ( input_meta->acq_date.year == 1984 &&
           input_meta->acq_date.doy <= 314 ) ) {
        sprintf(msgbuf,"Landsat_%1.1d acq date (%2.2d/%2.2d/%4.4d) invalid "
          "before 11/19/84", (int)(input_meta->sat+1),
          input_meta->acq_date.month, input_meta->acq_date.day,
          input_meta->acq_date.year);
        RETURN_ERROR(msgbuf, "GetLut", false);
      }
    }
  }  /* end if inst == MSS */
  
  /* Compute the coefficients for the reflectance. Use the K1,K2 thermal consts
     from the XML file if they are available. */
  for (ib = 0; ib < nband; ib++) {
    iband = input_meta->iband[ib] - 1;
    switch (input_meta->sat) {
      case SAT_LANDSAT_1:
        this->esun[ib] = esun_mss_1[iband];
        break;

      case SAT_LANDSAT_2:
        this->esun[ib] = esun_mss_2[iband];
        break;

      case SAT_LANDSAT_3:
        this->esun[ib] = esun_mss_3[iband];
        break;

      case SAT_LANDSAT_4:
        if (input_meta->inst == INST_TM) {
          this->esun[ib] = esun_tm_4[iband];
          if ( ib==0 ){
            if (input_meta->use_toa_refl_consts) {
              this->K1 = input_meta->k1_const;
              this->K2 = input_meta->k2_const;
            }
            else {
              this->K1 = K1_tm_4;
              this->K2 = K2_tm_4;
            }
          }
        }
        else
          this->esun[ib] = esun_mss_4[iband];
        break;

      case SAT_LANDSAT_5:
        if (input_meta->inst == INST_TM) {
          this->esun[ib] = esun_tm_5[iband];
          if ( ib==0 ){
            if (input_meta->use_toa_refl_consts) {
              this->K1 = input_meta->k1_const;
              this->K2 = input_meta->k2_const;
            }
            else {
              this->K1 = K1_tm_5;
              this->K2 = K2_tm_5;
            }
          }
        }
        else
          this->esun[ib] = esun_mss_5[iband];
        break;

      case SAT_LANDSAT_7:
        this->esun[ib] = esun_etm[iband];
        if ( ib==0 ){
          if (input_meta->use_toa_refl_consts) {
            this->K1 = input_meta->k1_const;
            this->K2 = input_meta->k2_const;
          }
          else {
            this->K1 = K1_etm;
            this->K2 = K2_etm;
          }
        }
        break;

      case SAT_NULL: break;
      case SAT_MAX: break;
    }  /* switch satellite */
  }  /* for iband for coefficients */

  this->cos_sun_zen = cos(input_meta->sun_zen);
  jdoy = input_meta->acq_date.doy;

  /* Use the earth sun distance from the XML file if it was available otherwise
     calculate from the DSUN table */
  if (input_meta->use_toa_refl_consts) {
    dsun = input_meta->earth_sun_dist;
  }
  else { /* calculate from the table */
    for (i = 0; i < (NDSUN - 1); i++) {
      if (jdoy >= dsun_table[i].doy  &&  jdoy <= dsun_table[i+1].doy)
        break;
    }

    if (i >= (NDSUN - 1)) {
      free(this);
      RETURN_ERROR("finding sun-earth distance", "GetLut", false);
    }

    dsun = dsun_table[i].dsun + 
           ((jdoy - dsun_table[i].doy) * 
            ((dsun_table[i + 1].dsun - dsun_table[i].dsun) /
         (dsun_table[i + 1].doy - dsun_table[i].doy)));
  }
  this->dsun2 = dsun * dsun;

  if (input_meta->inst == INST_MSS) {
    for (ib = 0; ib < nband; ib++) {
      this->refl_conv[ib] = (PI * this->dsun2) /
        (this->esun[ib] * this->cos_sun_zen);  
    }
  }

  this->long_name_prefix_ref = DupString(LONG_NAME_PREFIX_REF);
  if (this->long_name_prefix_ref == NULL) {
    free(this);
    RETURN_ERROR("duplicating long name prefix ref", "GetLut", NULL);
  }

  this->units_ref = DupString(UNITS_REF);
  if (this->units_ref == NULL) {
    free(this);
    RETURN_ERROR("duplicating ref units", "GetLut", NULL);
  }

  this->valid_range_ref[0]=     VALID_MIN_REF;
  this->valid_range_ref[1]=     VALID_MAX_REF;
  this->scale_factor_ref=       SCALE_FACTOR_REF;
  this->scale_factor_err_ref=   SCALE_FACTOR_ERR_REF;
  this->add_offset_ref=         ADD_OFFSET_REF;
  this->add_offset_err_ref=     ADD_OFFSET_ERR_REF;

  this->long_name_prefix_th = DupString(LONG_NAME_PREFIX_TH);
  if (this->long_name_prefix_th == NULL) {
    free(this);
    RETURN_ERROR("duplicating long name prefix th", "GetLut", NULL);
  }

  this->units_th = DupString(UNITS_TH);
  if (this->units_th == NULL) {
    free(this);
    RETURN_ERROR("duplicating th units", "GetLut", NULL);
  }

  this->valid_range_th[0]=     VALID_MIN_TH;
  this->valid_range_th[1]=     VALID_MAX_TH;
  this->scale_factor_th=       SCALE_FACTOR_TH;
  this->scale_factor_err_th=   SCALE_FACTOR_ERR_TH;
  this->add_offset_th=         ADD_OFFSET_TH;
  this->add_offset_err_th=     ADD_OFFSET_ERR_TH;

  return this;
}