Example #1
0
CvVSModule::~CvVSModule()
{
    CvDefParam* p = m_pParamList;
    for(;p;)
    {
        CvDefParam* pf = p;
        p=p->next;
        FreeParam(&pf);
    }
    m_pParamList=NULL;
    if(m_pModuleTypeName)free(m_pModuleTypeName);
    if(m_pModuleName)free(m_pModuleName);
}
Example #2
0
void CvVSModule::DelParam(const char* name)
{
    CvDefParam* p = m_pParamList;
    CvDefParam* pPrev = NULL;
    for(;p;p=p->next)
    {
        if(cv_stricmp(p->pName,name)==0) break;
        pPrev = p;
    }
    if(p)
    {
        if(pPrev)
        {
            pPrev->next = p->next;
        }
        else
        {
            m_pParamList = p->next;
        }
        FreeParam(&p);
    }
}/* DelParam */
Example #3
0
int main(int argc, char *argv[]) {
  char train_file_name[256];
  char test_file_name[256];
  char output_file_name[256];
  char model_file_name[256];
  struct Problem *train, *test;
  struct Model *model;
  int num_correct = 0, num_empty = 0, num_multi = 0, num_incl = 0;
  double avg_conf = 0, avg_cred = 0;
  const char *error_message;

  ParseCommandLine(argc, argv, train_file_name, test_file_name, output_file_name, model_file_name);
  error_message = CheckParameter(&param);

  if (error_message != NULL) {
    std::cerr << error_message << std::endl;
    exit(EXIT_FAILURE);
  }

  train = ReadProblem(train_file_name);
  test = ReadProblem(test_file_name);

  std::ofstream output_file(output_file_name);
  if (!output_file.is_open()) {
    std::cerr << "Unable to open output file: " << output_file_name << std::endl;
    exit(EXIT_FAILURE);
  }

  std::chrono::time_point<std::chrono::steady_clock> start_time = std::chrono::high_resolution_clock::now();

  if (param.load_model == 1) {
    model = LoadModel(model_file_name);
    if (model == NULL) {
      exit(EXIT_FAILURE);
    }
  } else {
    model = TrainCP(train, &param);
  }

  if (param.save_model == 1) {
    if (SaveModel(model_file_name, model) != 0) {
      std::cerr << "Unable to save model file" << std::endl;
    }
  }

  for (int i = 0; i < test->num_ex; ++i) {
    double conf, cred;
    std::vector<int> predict_label;

    predict_label = PredictCP(train, model, test->x[i], conf, cred);

    avg_conf += conf;
    avg_cred += cred;

    output_file << std::resetiosflags(std::ios::fixed) << test->y[i] << ' ' << predict_label[0] << ' '
                << std::setiosflags(std::ios::fixed) << conf << ' ' << cred;
    if (predict_label[0] == test->y[i]) {
      ++num_correct;
    }

    if (predict_label.size() == 1) {
      ++num_empty;
      output_file << " Empty\n";
    } else {
      output_file << " set:";
      for (size_t j = 1; j < predict_label.size(); ++j) {
        output_file << ' ' << predict_label[j];
        if (predict_label[j] == test->y[i]) {
          ++num_incl;
        }
      }
      if (predict_label.size() > 2) {
        ++num_multi;
        output_file << " Multi\n";
      } else {
        output_file << " Single\n";
      }
    }
    std::vector<int>().swap(predict_label);
  }
  avg_conf /= test->num_ex;
  avg_cred /= test->num_ex;

  std::chrono::time_point<std::chrono::steady_clock> end_time = std::chrono::high_resolution_clock::now();

  std::cout << "Simple Accuracy: " << 100.0*num_correct/test->num_ex << '%'
            << " (" << num_correct << '/' << test->num_ex << ") "
            << "Mean Confidence: " << std::fixed << std::setprecision(4) << 100*avg_conf << "%, "
            << "Mean Credibility: " << 100*avg_cred << "%\n";
  std::cout << "Accuracy: " << 100.0*num_incl/test->num_ex << '%'
            << " (" << num_incl << '/' << test->num_ex << ") "
            << "Multi Prediction: " << std::fixed << std::setprecision(4) << 100.0*num_multi/test->num_ex << "%, "
            << "Empty Prediction: " << 100.0*num_empty/test->num_ex << "%\n";
  output_file.close();

  std::cout << "Time cost: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count()/1000.0 << " s\n";

  FreeProblem(train);
  FreeProblem(test);
  FreeModel(model);
  FreeParam(&param);

  return 0;
}
Example #4
0
int main(int argc, char *argv[]) {
  char data_file_name[256];
  char output_file_name[256];
  struct Problem *prob;
  int num_correct = 0, num_empty = 0, num_multi = 0, num_incl = 0;
  int *indices = NULL;
  double avg_conf = 0, avg_cred = 0;
  double *conf = NULL, *cred = NULL;
  std::vector<int> *predict_labels = NULL;
  const char *error_message;

  ParseCommandLine(argc, argv, data_file_name, output_file_name);
  error_message = CheckParameter(&param);

  if (error_message != NULL) {
    std::cerr << error_message << std::endl;
    exit(EXIT_FAILURE);
  }

  prob = ReadProblem(data_file_name);

  std::ofstream output_file(output_file_name);
  if (!output_file.is_open()) {
    std::cerr << "Unable to open output file: " << output_file_name << std::endl;
    exit(EXIT_FAILURE);
  }

  predict_labels = new std::vector<int>[prob->num_ex];
  conf = new double[prob->num_ex];
  cred = new double[prob->num_ex];
  indices = new int[prob->num_ex];

  std::chrono::time_point<std::chrono::steady_clock> start_time = std::chrono::high_resolution_clock::now();

  OnlinePredict(prob, &param, predict_labels, indices, conf, cred);

  std::chrono::time_point<std::chrono::steady_clock> end_time = std::chrono::high_resolution_clock::now();

  output_file << prob->y[indices[0]] << '\n';

  for (int i = 1; i < prob->num_ex; ++i) {
    avg_conf += conf[i];
    avg_cred += cred[i];

    output_file << std::resetiosflags(std::ios::fixed) << prob->y[indices[i]] << ' ' << predict_labels[i][0] << ' '
                << std::setiosflags(std::ios::fixed) << conf[i] << ' ' << cred[i];
    if (predict_labels[i][0] == prob->y[indices[i]]) {
      ++num_correct;
    }

    if (predict_labels[i].size() == 1) {
      ++num_empty;
      output_file << " Empty\n";
    } else {
      output_file << " set:";
      for (size_t j = 1; j < predict_labels[i].size(); ++j) {
        output_file << ' ' << predict_labels[i][j];
        if (predict_labels[i][j] == prob->y[indices[i]]) {
          ++num_incl;
        }
      }
      if (predict_labels[i].size() > 2) {
        ++num_multi;
        output_file << " Multi\n";
      } else {
        output_file << " Single\n";
      }
    }
    std::vector<int>().swap(predict_labels[i]);
  }
  avg_conf /= prob->num_ex - 1;
  avg_cred /= prob->num_ex - 1;

  std::cout << "Online Accuracy: " << 100.0*num_correct/(prob->num_ex-1) << '%'
            << " (" << num_correct << '/' << prob->num_ex-1 << ") "
            << "Mean Confidence: " << std::fixed << std::setprecision(4) << 100*avg_conf << "%, "
            << "Mean Credibility: " << 100*avg_cred << "%\n";
  std::cout << "Accuracy: " << 100.0*num_incl/(prob->num_ex-1) << '%'
            << " (" << num_incl << '/' << prob->num_ex-1 << ") "
            << "Multi Prediction: " << std::fixed << std::setprecision(4) << 100.0*num_multi/(prob->num_ex-1) << "%, "
            << "Empty Prediction: " << 100.0*num_empty/(prob->num_ex-1) << "%\n";
  output_file.close();

  std::cout << "Time cost: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count()/1000.0 << " s\n";

  FreeProblem(prob);
  FreeParam(&param);
  delete[] predict_labels;
  delete[] conf;
  delete[] cred;
  delete[] indices;

  return 0;
}
Example #5
0
File: param.c Project: Jwely/ledaps
Param_t *GetParam(int argc, const char **argv)
/* 
!C******************************************************************************

!Description: 'GetParam' sets up the 'param' data structure and populate with user
 parameters, either from the command line or from a parameter file.
 
!Input Parameters:
 argc           number of command line arguments
 argv           command line argument list

!Output Parameters:
 (returns)      'param' data structure or NULL when an error occurs

!Team Unique Header:

!END****************************************************************************
*/
{
  Param_t *this;
  char *error_string = NULL;
  FILE *fp;
  Key_t key;
  int len;
  char line[MAX_STR_LEN + 1];
  char temp[MAX_STR_LEN + 1];
  Param_key_t param_key;
  char *param_file_name;
  bool got_start, got_end;

  if (argc < 2) 
    RETURN_ERROR("no command line parameter", "GetParam", NULL);
  if (argc > 3) 
    RETURN_ERROR("too many command line parameters", "GetParam", NULL);
  if (strlen(argv[1]) < 1)
    RETURN_ERROR("no parameter file name", "GetParam", NULL);
  param_file_name = (char *)argv[1];

  /* Open the parameter file */
  if ((fp = fopen(param_file_name, "r")) == NULL)
    RETURN_ERROR("unable to open parameter file", "GetParam", NULL);

  /* Create the Param data structure */
  this = (Param_t *)malloc(sizeof(Param_t));
  if (this == NULL) {
    fclose(fp);
    RETURN_ERROR("allocating Input structure", "GetParam", NULL);
  }

  /* set default parameters */
  this->param_file_name         = NULL;
  this->input_xml_file_name     = NULL;
  this->LEDAPSVersion           = NULL;

  /* Populate the data structure */
  this->param_file_name = DupString(param_file_name);
  if (this->param_file_name == NULL)
    error_string = "duplicating parameter file name";

  if (error_string != NULL) {
    free(this->param_file_name);
    this->param_file_name = NULL;
    FreeParam(this);
    RETURN_ERROR(error_string, "GetParam", NULL);
  }

  /* Parse the header file */
  got_start = got_end = false;

  while((len = GetLine(fp, line)) > 0) {

    if (!StringParse(line, &key)) {
      sprintf(temp, "parsing header file; line = %s", line);
      error_string = temp;
      break;
    }
    if (key.len_key <= 0) continue;
    if (key.key[0] == '#') continue;

    param_key = (Param_key_t) KeyString(key.key, key.len_key, Param_string, 
       (int)PARAM_NULL, (int)PARAM_MAX);
    if (param_key == PARAM_NULL) {
      key.key[key.len_key] = '\0';
      sprintf(temp, "invalid key; key = %s", key.key);
      error_string = temp;
      break;
    }
    if (!got_start) {
      if (param_key == PARAM_START) {
        if (key.nval != 0) {
          error_string = "no value expected (start key)";
          break;
        }
        got_start = true;
        continue;
      } else {
        error_string  = "no start key in parameter file";
        break;
      }
    }

    /* Get the value for each keyword */
    switch (param_key) {

      case PARAM_XML_FILE:
        if (key.nval <= 0) {
          error_string = "no input XML metadata file name";
          break; 
        } else if (key.nval > 1) {
          error_string = "too many input XML metadata file names";
          break; 
        }
        if (key.len_value[0] < 1) {
          error_string = "no input XML metadata file name";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->input_xml_file_name = DupString(key.value[0]);
        if (this->input_xml_file_name == NULL) {
          error_string = "duplicating input XML metadata file name";
          break;
        }
        break;

      case PARAM_LEDAPSVERSION:
        if (key.nval <= 0) {
          error_string = "no LEDAPSVersion number";
          break;
        } else if (key.nval > 1) {
          error_string = "too many LEDAPSVersion numbers";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no LEDAPSVersion number";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->LEDAPSVersion = DupString(key.value[0]);
        if (this->LEDAPSVersion == NULL) {
          error_string = "duplicating LEDAPSVersion number";
          break;
        }
        break;

      case PARAM_END:
        if (key.nval != 0) {
          error_string = "no value expected (end key)";
          break; 
        }
        got_end = true;
        break;

      default:
        error_string = "key not implmented";
    }
    if (error_string != NULL) break;
    if (got_end) break;
  }

  /* Close the parameter file */
  fclose(fp);

  if (error_string == NULL) {
    if (!got_start) 
      error_string = "no start key in header";
    else if (!got_end)
      error_string = "no end key in header";
  }

  /* Handle null values */
  if (error_string == NULL) {
    if (this->input_xml_file_name == NULL) 
      error_string = "no input XML metadata file name given";
    if (this->LEDAPSVersion == NULL)
      error_string = "no LEDAPS Version given";
  }

  /* Handle errors */
  if (error_string != NULL) {
    free(this->param_file_name);
    free(this->input_xml_file_name);
    free(this->LEDAPSVersion);
    free(this);
    RETURN_ERROR(error_string, "GetParam", NULL);
  }
  
  return this;
}
int main (int argc, const char **argv) {
  Param_t *param = NULL;
  Input_t *input = NULL;
  Lut_t *lut = NULL;
  Output_t *output = NULL;
  Output_t *output_th = NULL;
  int iline, isamp,oline, ib, jb, iz, val;
  unsigned char *line_in = NULL;
  unsigned char *line_in_thz = NULL;
  unsigned char *line_out_qa = NULL;
  int16 *line_out = NULL;
  int16 *line_out_th = NULL;
  int16 *line_out_thz = NULL;
  Cal_stats_t cal_stats;
  Cal_stats6_t cal_stats6;
  int nps,nls, nps6, nls6;
  int zoomx, zoomy;
  int i,odometer_flag=0;
  char msgbuf[1024];
  char envi_file[STR_SIZE]; /* name of the output ENVI header file */
  char *cptr=NULL;          /* pointer to the file extension */
  size_t input_psize;
  int qa_band = QA_BAND_NUM;
  int nband_refl = NBAND_REFL_MAX;
  int ifill, num_zero;
  int maxth=0;
  int mss_flag=0;
  Espa_internal_meta_t xml_metadata;  /* XML metadata structure */
  Envi_header_t envi_hdr;   /* output ENVI header information */

  printf ("\nRunning lndcal ...\n");
  for (i=1; i<argc; i++)if ( !strcmp(argv[i],"-o") )odometer_flag=1;

  /* Read the parameters from the input parameter file */
  param = GetParam(argc, argv);
  if (param == (Param_t *)NULL) EXIT_ERROR("getting runtime parameters",
    "main");

  /* Validate the input metadata file */
  if (validate_xml_file (param->input_xml_file_name) != SUCCESS)
  {  /* Error messages already written */
      EXIT_ERROR("Failure validating XML file", "main");
  }

  /* Initialize the metadata structure */
  init_metadata_struct (&xml_metadata);

  /* Parse the metadata file into our internal metadata structure; also
     allocates space as needed for various pointers in the global and band
     metadata */
  if (parse_metadata (param->input_xml_file_name, &xml_metadata) != SUCCESS)
  {  /* Error messages already written */
    EXIT_ERROR("parsing XML file", "main");
  }

  /* Check to see if the gain and bias values were specified */
  if (!existRadGB (&xml_metadata))
    EXIT_ERROR("Gains and biases don't exist in XML file (TOA radiance gain "
      "and bias fields) for each band.  Make sure to utilize the latest LPGS "
      "MTL file for conversion to the ESPA internal raw binary format as the "
      "gains and biases should be in that file.", "main");
  
  /* Open input file */
  input = OpenInput (&xml_metadata);
  if (input == (Input_t *)NULL)
    EXIT_ERROR("setting up input from XML structure", "main");

  /* Get Lookup table */
  lut = GetLut(param, input->nband, input);
  if (lut == (Lut_t *)NULL) EXIT_ERROR("bad lut file", "main");

  nps6=  input->size_th.s;
  nls6=  input->size_th.l;
  nps =  input->size.s;
  nls =  input->size.l;
  zoomx= nint( (float)nps / (float)nps6 );
  zoomy= nint( (float)nls / (float)nls6 );

  for (ib = 0; ib < input->nband; ib++) 
    cal_stats.first[ib] = true;
  cal_stats6.first = true;
  if (input->meta.inst == INST_MSS)mss_flag=1; 

  /* Open the output files.  Raw binary band files will be be opened. */
  output = OpenOutput(&xml_metadata, input, param, lut, false /*not thermal*/,
    mss_flag);
  if (output == NULL) EXIT_ERROR("opening output file", "main");

  /* Allocate memory for the input buffer, enough for all reflectance bands */
  input_psize = sizeof(unsigned char);
  line_in = calloc (input->size.s * nband_refl, input_psize);
   if (line_in == NULL) 
     EXIT_ERROR("allocating input line buffer", "main");

  /* Create and open output thermal band, if one exists */
  if ( input->nband_th > 0 ) {
    output_th = OpenOutput (&xml_metadata, input, param, lut, true /*thermal*/,
      mss_flag);
    if (output_th == NULL)
      EXIT_ERROR("opening output therm file", "main");

    /* Allocate memory for the thermal input and output buffer, only holds
       one band */
    line_out_th = calloc(input->size_th.s, sizeof(int16));
    if (line_out_th == NULL) 
      EXIT_ERROR("allocating thermal output line buffer", "main");

    if (zoomx == 1) {
      line_out_thz = line_out_th;
      line_in_thz = line_in;
    }
    else {
      line_out_thz = calloc (input->size.s, sizeof(int16));
      if (line_out_thz == NULL) 
        EXIT_ERROR("allocating thermal zoom output line buffer", "main");
      line_in_thz = calloc (input->size.s, input_psize);
      if (line_in_thz == NULL) 
        EXIT_ERROR("allocating thermal zoom input line buffer", "main");
    }
  } else {
    printf("*** no output thermal file ***\n"); 
  }

  /* Allocate memory for output lines for both the image and QA data */
  line_out = calloc (input->size.s, sizeof (int16));
  if (line_out == NULL) 
    EXIT_ERROR("allocating output line buffer", "main");

  line_out_qa = calloc (input->size.s, sizeof(unsigned char));
  if (line_out_qa == NULL) 
    EXIT_ERROR("allocating qa output line buffer", "main");
  memset (line_out_qa, 0, input->size.s * sizeof(unsigned char));    

  /* Do for each THERMAL line */
  oline= 0;
  if (input->nband_th > 0) {
    ifill= (int)lut->in_fill;
    for (iline = 0; iline < input->size_th.l; iline++) {
      ib=0;
      if (!GetInputLineTh(input, iline, line_in))
        EXIT_ERROR("reading input data for a line", "main");

      if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0  ) ){ 
        if ( zoomy == 1 )
          printf("--- main loop BAND6 Line %d --- \r",iline); 
        else
          printf("--- main loop BAND6 Line in=%d out=%d --- \r",iline,oline); 
        fflush(stdout); 
      }

      memset(line_out_qa, 0, input->size.s*sizeof(unsigned char));    
      if (!Cal6(lut, input, line_in, line_out_th, line_out_qa, &cal_stats6,
        iline))
        EXIT_ERROR("doing calibration for a line", "main");

      if ( zoomx>1 ) {
        zoomIt(line_out_thz, line_out_th, nps/zoomx, zoomx );
        zoomIt8(line_in_thz, line_in, nps/zoomx, zoomx );
      }

      for ( iz=0; iz<zoomy; iz++ ) {
        for (isamp = 0; isamp < input->size.s; isamp++) {
          val= getValue(line_in_thz, isamp);
          if ( val> maxth) maxth=val;
          if ( val==ifill) line_out_qa[isamp] = lut->qa_fill; 
          else if ( val>=SATU_VAL6 ) line_out_qa[isamp] = ( 0x000001 << 6 ); 
        }

        if ( oline<nls ) {
          if (!PutOutputLine(output_th, ib, oline, line_out_thz)) {
            sprintf(msgbuf,"write thermal error ib=%d oline=%d iline=%d",ib,
              oline,iline);
            EXIT_ERROR(msgbuf, "main");
          }

          if (input->meta.inst != INST_MSS) 
            if (!PutOutputLine(output_th, ib+1, oline, line_out_qa)) {
	          sprintf(msgbuf,"write thermal QA error ib=%d oline=%d iline=%d",
                ib+1,oline,iline);
              EXIT_ERROR(msgbuf, "main");
            }
        }
        oline++;
      }
    } /* end loop for each thermal line */
  }
  if (odometer_flag) printf("\n");

  if (input->nband_th > 0)
    if (!CloseOutput(output_th))
      EXIT_ERROR("closing output thermal file", "main");

  /* Do for each REFLECTIVE line */
  ifill= (int)lut->in_fill;
  for (iline = 0; iline < input->size.l; iline++){
    /* Do for each band */

    if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0  ) )
     {printf("--- main reflective loop Line %d ---\r",iline); fflush(stdout);}

    memset(line_out_qa, 0, input->size.s*sizeof(unsigned char));
    
    for (ib = 0; ib < input->nband; ib++) {
      if (!GetInputLine(input, ib, iline, &line_in[ib*nps]))
        EXIT_ERROR("reading input data for a line", "main");
    }
    
    for (isamp = 0; isamp < input->size.s; isamp++){
      num_zero=0;
      for (ib = 0; ib < input->nband; ib++) {
        jb= (ib != 5 ) ? ib+1 : ib+2;
        val= getValue((unsigned char *)&line_in[ib*nps], isamp);
	    if ( val==ifill   )num_zero++;
        if ( val==SATU_VAL[ib] ) line_out_qa[isamp]|= ( 0x000001 <<jb ); 
      }
      /* Feng fixed bug by changing "|=" to "=" below (4/17/09) */
      if ( num_zero >  0 )line_out_qa[isamp] = lut->qa_fill; 
    }

    for (ib = 0; ib < input->nband; ib++) {
      if (!Cal(lut, ib, input, &line_in[ib*nps], line_out, line_out_qa,
        &cal_stats,iline))
        EXIT_ERROR("doing calibraton for a line", "main");

      if (!PutOutputLine(output, ib, iline, line_out))
        EXIT_ERROR("reading input data for a line", "main");
    } /* End loop for each band */
        
    if (input->meta.inst != INST_MSS) 
      if (!PutOutputLine(output, qa_band, iline, line_out_qa))
        EXIT_ERROR("writing qa data for a line", "main");
  } /* End loop for each line */

  if ( odometer_flag )printf("\n");

  for (ib = 0; ib < input->nband; ib++) {
    printf(
      " band %d rad min %8.5g max %8.4f  |  ref min  %8.5f max  %8.4f\n", 
      input->meta.iband[ib], cal_stats.rad_min[ib], cal_stats.rad_max[ib],
      cal_stats.ref_min[ib], cal_stats.ref_max[ib]);
  }

  if ( input->nband_th > 0 )
    printf(
      " band %d rad min %8.5g max %8.4f  |  tmp min  %8.5f max  %8.4f\n", 6,
      cal_stats6.rad_min,  cal_stats6.rad_max,
      cal_stats6.temp_min, cal_stats6.temp_max);

  /* Close input and output files */
  if (!CloseInput(input)) EXIT_ERROR("closing input file", "main");
  if (!CloseOutput(output)) EXIT_ERROR("closing input file", "main");

  /* Write the ENVI header for reflectance files */
  for (ib = 0; ib < output->nband; ib++) {
    /* Create the ENVI header file this band */
    if (create_envi_struct (&output->metadata.band[ib], &xml_metadata.global,
      &envi_hdr) != SUCCESS)
        EXIT_ERROR("Creating the ENVI header structure for this file.", "main");

    /* Write the ENVI header */
    strcpy (envi_file, output->metadata.band[ib].file_name);
    cptr = strchr (envi_file, '.');
    strcpy (cptr, ".hdr");
    if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS)
        EXIT_ERROR("Writing the ENVI header file.", "main");
  }

  /* Write the ENVI header for thermal files */
  for (ib = 0; ib < output_th->nband; ib++) {
    /* Create the ENVI header file this band */
    if (create_envi_struct (&output_th->metadata.band[ib], &xml_metadata.global,
      &envi_hdr) != SUCCESS)
        EXIT_ERROR("Creating the ENVI header structure for this file.", "main");

    /* Write the ENVI header */
    strcpy (envi_file, output_th->metadata.band[ib].file_name);
    cptr = strchr (envi_file, '.');
    strcpy (cptr, ".hdr");
    if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS)
        EXIT_ERROR("Writing the ENVI header file.", "main");
  }

  /* Append the reflective and thermal bands to the XML file */
  if (append_metadata (output->nband, output->metadata.band,
    param->input_xml_file_name) != SUCCESS)
    EXIT_ERROR("appending reflectance and QA bands", "main");
  if (input->nband_th > 0) {
    if (append_metadata (output_th->nband, output_th->metadata.band,
      param->input_xml_file_name) != SUCCESS)
      EXIT_ERROR("appending thermal and QA bands", "main");
  }

  /* Free the metadata structure */
  free_metadata (&xml_metadata);

  /* Free memory */
  if (!FreeParam(param)) 
    EXIT_ERROR("freeing parameter stucture", "main");

  if (!FreeInput(input)) 
    EXIT_ERROR("freeing input file stucture", "main");

  if (!FreeLut(lut)) 
    EXIT_ERROR("freeing lut file stucture", "main");

  if (!FreeOutput(output)) 
    EXIT_ERROR("freeing output file stucture", "main");

  free(line_out);
  line_out = NULL;
  free(line_in);
  line_in = NULL;
  free(line_out_qa);
  line_out_qa = NULL;
  free(line_out_th);
  line_out_th = NULL;
  if (zoomx != 1) {
    free(line_in_thz);
    free(line_out_thz);
  }
  line_in_thz = NULL;
  line_out_thz = NULL;

  /* All done */
  printf ("lndcal complete.\n");
  return (EXIT_SUCCESS);
}
Example #7
0
Param_t *GetParam(int argc, const char **argv)
/* 
!C******************************************************************************

!Description: 'GetParam' sets up the 'param' data structure and populate with user
 parameters, either from the command line or from a parameter file.
 
!Input Parameters:
 argc           number of command line arguments
 argv           command line argument list

!Output Parameters:
 (returns)      'param' data structure or NULL when an error occurs

!Team Unique Header:

 ! Design Notes:
   1. An error status is returned when:
       a. memory allocation is not successful
       b. an error is returned from the ReadCmdLine function
       c. certain required parameters are invalid or not entered:
            input file name, output file name, geolocation file name,
	    SDS name, output space projection number, 
	    output space pixel size, output space upper left corner, 
	    output space image size, either output space sphere or projection
	    parameter number 0
	    output space zone number not given for UTM
       d. the input is 'GRID_SPACE' then and certain required parameters 
          are invalid or not entered:
	    input space projection number, input space pixel size, 
	    input space upper left corner, either input space sphere or 
	    projection parameter number 0
       e. the input is 'GRID_SPACE' and the geolocation file name is given
       f. the resampling kernel is 'USER_KERNEL' and the kernel file name 
          is invalid or not entered.
   2. Error of type 'a' are handled with the 'RETURN_ERROR' macro and 
      the others are handled by writting the error messages to 'stderr' and 
      then printing the usage information.
   3. 'FreeParam' should be called to deallocate memory used by the 
      'param' data structures.

!END****************************************************************************
*/
{
  Param_t *this;
  char *error_string = (char *)NULL;
  FILE *fp;
  Key_t key;
  int len;
  char line[MAX_STR_LEN + 1];
  char temp[MAX_STR_LEN + 1];
  Param_key_t param_key;
  char *param_file_name;
  int itemp;
  bool got_start, got_end;

  if (argc < 2) 
    RETURN_ERROR("no command line parameter", "GetParam", 
                 (Param_t *)NULL);
  if (argc > 3) 
    RETURN_ERROR("too many command line parameters", "GetParam", 
                 (Param_t *)NULL);
  if (strlen(argv[1]) < 1)
    RETURN_ERROR("no paramter file name", "GetParam", 
                 (Param_t *)NULL);
  param_file_name = (char *)argv[1];

  /* Open the parameter file */
  
  if ((fp = fopen(param_file_name, "r")) == (FILE *)NULL)
    RETURN_ERROR("unable to open parameter file", "GetParam", 
                 (Param_t *)NULL);

  /* Create the Param data structure */

  this = (Param_t *)malloc(sizeof(Param_t));
  if (this == (Param_t *)NULL) {
    fclose(fp);
    RETURN_ERROR("allocating Input structure", "GetParam", 
                 (Param_t *)NULL);
  }

  /* set default parameters */

  this->param_file_name  = (char *)NULL;
  this->input_file_name  = (char *)NULL;
  this->input_therm_file_name  = (char *)NULL;
  this->lut_file_name    = (char *)NULL;
  this->output_file_name = (char *)NULL;
  this->PGEVersion              = (char *)NULL;
  this->ProcessVersion          = (char *)NULL;
  this->therm_flag  = false;
  this->apply_kernel =  0;
  this->ksize =         0;
  this->sieve_thresh =  0;

  /* Populate the data structure */

  this->param_file_name = DupString(param_file_name);
  if (this->param_file_name == (char *)NULL)
    error_string = "duplicating parameter file name";

  if (error_string == (char *)NULL) {
    this->lut_file_name = DupString(LUT_FILE_NAME);
    if (this->lut_file_name == (char *)NULL)
      error_string = "duplicating lookup table file name";
  }

  if (error_string != (char *)NULL) {
    if (this->param_file_name != (char *)NULL) 
      free(this->param_file_name);
    if (this->lut_file_name != (char *)NULL) 
      free(this->lut_file_name);
    FreeParam(this);
    RETURN_ERROR(error_string, "GetParam", (Param_t *)NULL);
  }

  /* Parse the header file */

  got_start = got_end = false;

  while((len = GetLine(fp, line)) > 0) {

    if (!StringParse(line, &key)) {
      sprintf(temp, "parsing header file; line = %s", line);
      error_string = temp;
      break;
    }
    if (key.len_key <= 0) continue;
    if (key.key[0] == '#') continue;

    param_key = (Param_key_t)
       KeyString(key.key, key.len_key, Param_string, 
		 (int)PARAM_NULL, (int)PARAM_MAX);
    if (param_key == PARAM_NULL) {
      key.key[key.len_key] = '\0';
      sprintf(temp, "invalid key; key = %s", key.key);
      error_string = temp;
      break;
    }
    if (!got_start) {
      if (param_key == PARAM_START) {
        if (key.nval != 0) {
	  error_string = "no value expected (start key)";
	  break;
	}
        got_start = true;
	continue;
      } else {
        error_string  = "no start key in parameter file";
        break;
      }
    }

    /* Get the value for each keyword */

    switch (param_key) {

      case PARAM_REF_FILE:
        if (key.nval <= 0) {
	  error_string = "no reflectance file name";
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many reflectance file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
	  error_string = "no reflectance file name";
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->input_file_name = DupString(key.value[0]);
	if (this->input_file_name == (char *)NULL) {
	  error_string = "duplicating reflectance file name";
	  break;
        }
        break;

      case PARAM_THERM_FILE:
        if (key.nval <= 0) {
          printf("warning %s \n","no band6 file name"); 
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many band6 file names";
          printf("error_string=(%s)\n",error_string); 
	  break; 
	}
	if (key.len_value[0] < 1) {
          printf("warning %s \n","no band6 file name"); 
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->input_therm_file_name = DupString(key.value[0]);
        this->therm_flag  = true;
	if (this->input_file_name == (char *)NULL) {
	  error_string = "duplicating band6 file name";
	  break;
        }
        break;

      case PARAM_CSM_FILE:
        if (key.nval <= 0) {
	  error_string = "no CLoud Mask file name";
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many Cloud Mask file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
	  error_string = "no Cloud Mask file name";
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->output_file_name = DupString(key.value[0]);
	if (this->output_file_name == (char *)NULL) {
	  error_string = "duplicating Cloud Mask file name";
	  break;
        }
        break;

      case PARAM_CSM_FILTER:
        if (key.nval <= 0) {
	  break; 
	} else if (key.nval > 3) {
	  error_string = "too many filter values";
	  break; 
	}
	if (key.len_value[0] < 1) {
	  break;
	}
	if (key.nval > 0)
	  {
          key.value[0][key.len_value[0]] = '\0';
          this->ksize = atoi(key.value[0]);
          this->apply_kernel = 1;
	  }
	if (key.nval > 1)
	  {
          key.value[1][key.len_value[1]] = '\0';
          itemp = atoi(key.value[1]);
          if ( itemp > this->apply_kernel )this->apply_kernel = itemp;
	  }
	if (key.nval > 2)
	  {
          key.value[2][key.len_value[2]] = '\0';
          this->sieve_thresh= atoi(key.value[2]);
	  }
        break;

      case PARAM_PGEVERSION:
        if (key.nval <= 0) {
          error_string = "no PGEVersion number";
          break;
        } else if (key.nval > 1) {
          error_string = "too many PGEVersion numbers";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no PGEVersion number";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->PGEVersion = DupString(key.value[0]);
        if (this->PGEVersion == (char *)NULL) {
          error_string = "duplicating PGEVersion number";
          break;
        }
        break;

      case PARAM_PROCESSVERSION:
        if (key.nval <= 0) {
          error_string = "no ProcessVersion number";
          break;
        } else if (key.nval > 1) {
          error_string = "too many ProcessVersion numbers";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no ProcessVersion number";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->ProcessVersion = DupString(key.value[0]);
        if (this->ProcessVersion == (char *)NULL) {
          error_string = "duplicating ProcessVersion number";
          break;
        }
        break;

      case PARAM_END:
        if (key.nval != 0) {
	  error_string = "no value expected (end key)";
	  break; 
	}
        got_end = true;
        break;

      default:
        error_string = "key not implmented";

    }
    if (error_string != (char *)NULL) break;
    if (got_end) break;

  }

  /* Close the parameter file */

  fclose(fp);

  if (error_string == (char *)NULL) {
    if (!got_start) 
      error_string = "no start key in header";
    else if (!got_end)
      error_string = "no end key in header";
  }

  /* Handle null values */
  
  if (error_string == (char *)NULL) {
    if (this->input_file_name == (char *)NULL) 
      error_string = "no input file name given";
    if (this->lut_file_name == (char *)NULL) 
      error_string = "no lookup table file name given";
    if (this->output_file_name == (char *)NULL) 
      error_string = "no output file name given";
    if (this->PGEVersion == (char *)NULL)
      error_string = "no PGE Version given";
    if (this->ProcessVersion == (char *)NULL)
      error_string = "no Process Version given";
  }

  /* Handle errors */

  if (error_string != (char *)NULL) {
    if (this->param_file_name != (char *)NULL) 
      free(this->param_file_name);
    if (this->input_file_name != (char *)NULL) 
      free(this->input_file_name);
    if (this->lut_file_name != (char *)NULL) 
      free(this->lut_file_name);
    if (this->output_file_name != (char *)NULL) 
      free(this->output_file_name);
    if (this->PGEVersion != (char *)NULL)
      free(this->PGEVersion);
    if (this->ProcessVersion != (char *)NULL)
      free(this->ProcessVersion);
    if (this != (Param_t *)NULL) free(this);
    RETURN_ERROR(error_string, "GetParam", (Param_t *)NULL);
  }
  
  return this;
}
Example #8
0
int main (int argc, const char **argv) 
/* 
!C******************************************************************************

!Description: 'main' is the main function for the 'resamp' program.
 
!Input Parameters:
 argc           number of run-time (command line) arguments
 argv           list of run-time argument values

!Output Parameters:
 (returns)      status:
                  'EXIT_SUCCESS' = okay
		  'EXIT_FAILURE' = fatal error

!Team Unique Header:

 ! Design Notes:
   1. See 'USAGE' in 'parser.h' for information on how to use the program.
   2. An error status is returned when:
       a. there is a problem getting runtime parameters
       b. there is a bad input image, geolocation or kernel file
       c. unable to set up the input grid, scan data structure, 
          or the output space
       d. unable to generate kernel
       f. unable to free memory for data structures
       g. unable to set up intermediate patches data structure
       h. there is an error reading geolocation for a scan
       i. there is an error mapping a scan
       j. there is an error generating geolocation for a scan
       k. there is an error copying a scan
       l. there is an error extending the scan
       m. there is an error reading input data for a scan
       n. there is an error resampling a scan
       o. there is an error writting patches to disk
       p. there is an error closing input image, geolocation, kernel or 
          output files
       q. there is an error untouching patches
       r. there is an error creating output image file
       s. there is an error opening output file
       t. there is an error unscrambling the output file
       u. there is an error writing metadata.
   3. Errors are handled with the 'LOG_ERROR' macro.

!END****************************************************************************
*/
{
  int i,j,k;
  int curr_sds, curr_band;        /* current SDS and current band in SDS */
  char tmp_sds_name[MAX_STR_LEN];
  char errstr[M_MSG_LEN+1];              /* error string for OpenInput */
  char sdsname[256];              /* SDS name without '/'s */
  char msg[M_MSG_LEN+1];
  Param_t *param = NULL;
  Param_t *param_save = NULL;
  Geoloc_t *geoloc = NULL;
  Kernel_t *kernel = NULL;
  Input_t *input = NULL;
  Scan_t *scan = NULL;
  Space_t *output_space = NULL;
  Patches_t *patches = NULL;
  int iscan, kscan;
  int il, nl;
  Output_t *output = NULL;
  Img_coord_double_t img;
  Geo_coord_t geo;
  FILE_ID *MasterGeoMem;    /* Output GeoTiff file */
  FILE *rbfile = NULL;       /* Output Raw Binary file */
  char HDF_File[1024], CharThisPid[256], FinalFileName[1024];
  Output_t output_mem;       /* Contains output HDF file */
  int32 exec_resamp, ThisPid; 
  char filename[1024];       /* name of raw binary file to be written to */
  time_t startdate, enddate;  /* start and end date struct */
  bool file_created;         /* was the current HDF file created? */

  /* Initialize the log file */
  InitLogHandler();

  /* Print the MRTSwath header */
  LogInfomsg(
     "*******************************************************************"
     "***********\n");
  sprintf(msg, "%s (%s)\n", RESAMPLER_NAME, RESAMPLER_VERSION);
  LogInfomsg(msg);
  startdate = time(NULL);
  sprintf(msg, "Start Time:  %s", ctime(&startdate));
  LogInfomsg(msg);
  LogInfomsg(
  "------------------------------------------------------------------\n");

  /* Get runtime parameters */
  if (NeedHelp(argc, argv))
    exit(EXIT_SUCCESS);

  param_save = GetParam(argc, argv);
  if (param_save == (Param_t *)NULL)
    LOG_ERROR("getting runtime parameters", "main");

  /* Print out the user-specified processing information */
  PrintParam(param_save);

  /* Loop through all the SDSs */
  for (curr_sds = 0; curr_sds < param_save->num_input_sds; curr_sds++)
  {
    /* Loop through all the bands in the current SDS */
    for (curr_band = 0; curr_band < param_save->input_sds_nbands[curr_sds];
         curr_band++)
    {
      /* Is this band one that should be processed? */
      if (!param_save->input_sds_bands[curr_sds][curr_band])
        continue;

      /* Assume the HDF file does not need to be created */
      file_created = false;

      /* Get a copy of the user parameters */
      param = CopyParam(param_save);
      if (param == (Param_t *)NULL)
        LOG_ERROR("copying runtime parameters", "main");

      /* Create the input_sds_name which is "SDSname, band" */
      if (param->input_sds_nbands[curr_sds] == 1)
      {
        /* 2D product so the band number is not needed */
        sprintf(tmp_sds_name, "%s", param->input_sds_name_list[curr_sds]);
      }
      else
      {
        /* 3D product so the band number is required */
        sprintf(tmp_sds_name, "%s, %d", param->input_sds_name_list[curr_sds],
          curr_band);
      }

      param->input_sds_name = strdup (tmp_sds_name);
      if (param->input_sds_name == NULL)
        LOG_ERROR("error creating input SDS band name", "main");
      sprintf(msg, "\nProcessing %s ...\n", param->input_sds_name);
      LogInfomsg(msg);

      /* Update the system to process the current SDS and band */
      if (!update_sds_info(curr_sds, param))
        LOG_ERROR("error updating SDS information", "main");

      /* Open input file for the specified SDS and band */
      input = OpenInput(param->input_file_name, param->input_sds_name, 
        param->iband, param->rank[curr_sds], param->dim[curr_sds], errstr);
      if (input == (Input_t *)NULL) {
        /* This is an invalid SDS for our processing so skip to the next
           SDS. We will only process SDSs that are at the 1km, 500m, or
           250m resolution (i.e. a factor of 1, 2, or 4 compared to the
           1km geolocation lat/long data). We also only process CHAR8,
           INT8, UINT8, INT16, and UINT16 data types. */
        LOG_WARNING(errstr, "main");
        LOG_WARNING("not processing SDS/band", "main");
        break;
      }

      /* Setup kernel */
      kernel = GenKernel(param->kernel_type);
      if (kernel == (Kernel_t *)NULL)
        LOG_ERROR("generating kernel", "main");

      /* Open geoloc file */
      geoloc = OpenGeolocSwath(param->geoloc_file_name);
      if (geoloc == (Geoloc_t *)NULL)
        LOG_ERROR("bad geolocation file", "main");

      /* Setup input scan */
      scan = SetupScan(geoloc, input, kernel);
      if (scan == (Scan_t *)NULL)
        LOG_ERROR("setting up scan data structure", "main");

      /* Set up the output space, using the current pixel size and
         number of lines and samples based on the current SDS (pixel size
         and number of lines and samples are the same for all the bands
         in the SDS) */
      param->output_space_def.img_size.l = param->output_img_size[curr_sds].l;
      param->output_space_def.img_size.s = param->output_img_size[curr_sds].s;
      param->output_space_def.pixel_size = param->output_pixel_size[curr_sds];
      sprintf(msg, "  output lines/samples: %d %d\n",
        param->output_space_def.img_size.l, param->output_space_def.img_size.s);
      LogInfomsg(msg);
      if (param->output_space_def.proj_num == PROJ_GEO)
      {
        sprintf(msg, "  output pixel size: %.4f\n",
          param->output_space_def.pixel_size * DEG);
	LogInfomsg(msg);
      }
      else
      {
        sprintf(msg, "  output pixel size: %.4f\n",
          param->output_space_def.pixel_size);
	LogInfomsg(msg);
      }
      LogInfomsg("  output data type: ");
      switch (param->output_data_type)
      {
          case DFNT_CHAR8:
              LogInfomsg("CHAR8\n");
              break;
          case DFNT_UINT8:
              LogInfomsg("UINT8\n");
              break;
          case DFNT_INT8:
              LogInfomsg("INT8\n");
              break;
          case DFNT_UINT16:
              LogInfomsg("UINT16\n");
              break;
          case DFNT_INT16:
              LogInfomsg("INT16\n");
              break;
          case DFNT_UINT32:
              LogInfomsg("UINT32\n");
              break;
          case DFNT_INT32:
              LogInfomsg("INT32\n");
              break;
          default:
              LogInfomsg("same as input\n");
              break;
      }

      output_space = SetupSpace(&param->output_space_def);
      if (output_space == (Space_t *)NULL) 
        LOG_ERROR("setting up output space", "main");

      /* Compute and print out the corners */
      img.is_fill = false;
      img.l = img.s = 0.0;
      if (!FromSpace(output_space, &img, &geo)) 
      {
        LOG_WARNING("unable to compute upper left corner", "main");
      }
      else
      {
        sprintf(msg,
          "  output upper left corner: lat %13.8f  long %13.8f\n", 
          (DEG * geo.lat), (DEG * geo.lon));
	LogInfomsg(msg);
      }

      img.is_fill = false;
      img.l = output_space->def.img_size.l - 1; 
      img.s = output_space->def.img_size.s - 1;
      if (!FromSpace(output_space, &img, &geo)) 
      {
        LOG_WARNING("unable to compute lower right corner", "main");
      }
      else
      {
        sprintf(msg,
          "  output lower right corner: lat %13.8f  long %13.8f\n", 
          (DEG * geo.lat), (DEG * geo.lon));
        LogInfomsg(msg);
      }

      /* If output data type not specified, then set to input data type
         (changes from SDS to SDS) */
      if (param->output_data_type == -1) 
        param->output_data_type = input->sds.type;

      /* Save the data type of this SDS for output to the metadata */
      param_save->output_dt_arr[curr_sds] = param->output_data_type;

      /* Setup intermediate patches. Setup as the input data type. Then we
         will convert to the output data type later. */
      patches = SetupPatches(&param->output_space_def.img_size, 
        param->patches_file_name, input->sds.type, input->fill_value, input->factor, input->offset);
      if (patches == (Patches_t *)NULL) 
        LOG_ERROR("setting up intermediate patches data structure","main");

      if (param->input_space_type != SWATH_SPACE)
        LOG_ERROR("input space type is not SWATH", "main");

      sprintf(msg, "  input lines/samples: %d %d\n", input->size.l,
        input->size.s);
      LogInfomsg(msg);
      sprintf(msg, "  input scale factor: %g\n", input->factor);
      LogInfomsg(msg);
      sprintf(msg, "  input offset: %lg\n", input->offset);
      LogInfomsg(msg);
      switch (input->ires)
      {
        case 1:
          LogInfomsg("  input resolution: 1 km\n");
          break;
        case 2:
          LogInfomsg("  input resolution: 500 m\n");
          break;
        case 4:
          LogInfomsg("  input resolution: 250 m\n");
          break;
      }
      LogInfomsg("  %% complete: 0%");

      /* For each input scan */
      kscan = 0;
      for (iscan = 0; iscan < geoloc->nscan; iscan++)
      {
        /* Update status? */
        if (100 * iscan / geoloc->nscan > kscan)
        {
          kscan = 100 * iscan / geoloc->nscan;
          if (kscan % 10 == 0)
          {
            sprintf(msg, " %d%%", kscan);
            LogInfomsg(msg);
	  }
        }

        /* Read the geolocation data for the scan and map to output space */
        if (!GetGeolocSwath(geoloc, output_space, iscan)) 
          LOG_ERROR("reading geolocation for a scan", "main");

        /* Map scan to input resolution */
        if (!MapScanSwath(scan, geoloc)) 
          LOG_ERROR("mapping a scan (swath)", "main");

        /* Extend the scan */
        if (!ExtendScan(scan)) LOG_ERROR("extending the scan", "main");

        /* Read input scan data into extended scan */
        il = iscan * input->scan_size.l;
        nl = input->scan_size.l;
        if (il + nl > input->size.l)
          nl = input->size.l - il;

        if (!GetScanInput(scan, input, il, nl))
          LOG_ERROR("reading input data for a scan", "main");

        /* Resample all of the points in the extended scan */
        if (!ProcessScan(scan, kernel, patches, nl, param->kernel_type))
          LOG_ERROR("resampling a scan", "main");

        /* Toss patches that were not touched */
        if (!TossPatches(patches, param->output_data_type))
          LOG_ERROR("writting patches to disk", "main");

      } /* End loop for each input scan */

      /* Finish the status message */
      LogInfomsg(" 100%\n");

      /* Save the background fill value from the patches data structure for
         output to the metadata */
      param_save->fill_value[curr_sds] = patches->fill_value;

      /* If output is raw binary, then we need the patches information
         so write the header before deleting the patches info */
      if (param->output_file_format == RB_FMT)
      { /* Output is raw binary */
        /* Create the raw binary header file */
        if (!WriteHeaderFile (param, patches))
          LOG_ERROR("writing raw binary header file", "main");
      }

      /* Done with scan and kernel strutures */
      if (!FreeScan(scan))
        LOG_ERROR("freeing scan structure", "main");
      if (!FreeKernel(kernel))
        LOG_ERROR("freeing kernel structure", "main");

      /* Close geolocation file */
      if (!CloseGeoloc(geoloc))
         LOG_ERROR("closing geolocation file", "main");

      /* Close input file */
      if (!CloseInput(input)) LOG_ERROR("closing input file", "main");

      /* Free the output space structure */
      if (!FreeSpace(output_space)) 
        LOG_ERROR("freeing output space structure", "main");

      /* Write remaining patches in memory to disk */
      if (!UntouchPatches(patches)) 
        LOG_ERROR("untouching patches", "main");
      if (!TossPatches(patches, param->output_data_type))
        LOG_ERROR("writting remaining patches to disk", "main");
      if (!FreePatchesInMem(patches))
        LOG_ERROR("freeing patches data structure in memory", "main");

      /* Output format can be HDF, GeoTiff, raw binary, or both HDF and
         GeoTiff */
      if (param->output_file_format == HDF_FMT ||
          param->output_file_format == BOTH)
      { /* Output is HDF */
        /* Create output file. If the output has multiple resolutions, then
           the resolution value will be used as an extension to the basename.
           Otherwise no resolution extension will be used. */
        if (param->multires)
        {
          if (param->output_space_def.proj_num != PROJ_GEO)
            /* Output the pixel size with only two decimal places, since
               the pixel size will be in meters */
            sprintf(HDF_File, "%s_%dm.hdf", param->output_file_name,
              (int) param->output_pixel_size[curr_sds]);
          else
            /* Output the pixel size with four decimal places, since the
               pixel size will be in degrees (need to convert from radians) */
            sprintf(HDF_File, "%s_%.04fd.hdf", param->output_file_name,
              param->output_pixel_size[curr_sds] * DEG);
        }
        else
        {
          sprintf(HDF_File, "%s.hdf", param->output_file_name);
        }

        /* Does the HDF file need to be created? */
        if (param->create_output[curr_sds])
        {
          /* Create the output HDF file */
          if (!CreateOutput(HDF_File))
            LOG_ERROR("creating output image file", "main");
          file_created = true;

          /* Loop through the rest of the SDSs and unmark the ones of the same
             resolution, since they will be output to this same HDF file
             and therefore do not need to be recreated. */
          for (k = curr_sds; k < param_save->num_input_sds; k++)
          {
            if (param->output_pixel_size[k] ==
                param->output_pixel_size[curr_sds])
              param_save->create_output[k] = false;
          }
        }

        /* Open output file */
        output = OutputFile(HDF_File, param->output_sds_name,
          param->output_data_type, &param->output_space_def);
        if (output == (Output_t *)NULL)
          LOG_ERROR("opening output HDF file", "main");
      }

      if (param->output_file_format == GEOTIFF_FMT ||
          param->output_file_format == BOTH)
      { /* Output is geotiff */
        /* Attach the SDS name to the output file name */
        if (param->output_file_format == GEOTIFF_FMT)
        {
          output = &output_mem;
          output->size.l = param->output_space_def.img_size.l;
          output->size.s = param->output_space_def.img_size.s;
          output->open   = true;
        }

        /* Open and initialize the GeoTiff File */
        MasterGeoMem = Open_GEOTIFF(param);
        if( ! MasterGeoMem ) {
           LOG_ERROR("allocating GeoTiff file id structure", "main");
        } else if( MasterGeoMem->error ) {
           LOG_ERROR(MasterGeoMem->error_msg, "main");
        }

/* Remove due to clash of tiff and hdf header files.
 *        if (!OpenGeoTIFFFile (param, &MasterGeoMem))
 *         LOG_ERROR("opening and initializing GeoTiff file", "main");
 */
      }

      if (param->output_file_format == RB_FMT)
      { /* Output is raw binary */
        output = &output_mem;
        output->size.l = param->output_space_def.img_size.l;
        output->size.s = param->output_space_def.img_size.s;
        output->open   = true;

        /* Get the size of the data type */
        switch (param->output_data_type)
        {
          case DFNT_INT8:
          case DFNT_UINT8:
            /* one byte in size */
            output->output_dt_size = 1;
            break;

          case DFNT_INT16:
          case DFNT_UINT16:
            /* two bytes in size */
            output->output_dt_size = 2;
            break;

          case DFNT_INT32:
          case DFNT_UINT32:
          case DFNT_FLOAT32:
            /* four bytes in size */
            output->output_dt_size = 4;
            break;
        }

        /* Copy the SDS name and remove any '/'s in the SDSname */
        j = 0;
        for (i = 0; i < (int)strlen(param->output_sds_name); i++)
        {
          if (param->output_sds_name[i] != '/' &&
              param->output_sds_name[i] != '\\')
          {
            sdsname[j++] = param->output_sds_name[i];
          }
          sdsname[j] = '\0';
        }

        /* Remove any spaces (from the SDS name) from the name */
        k = 0;
        while (sdsname[k])
        {
          if (isspace(sdsname[k]))
            sdsname[k] = '_';
          k++;
        }

        /* Add the SDS band name and dat extension to the filename */
        sprintf(filename, "%s_%s.dat", param->output_file_name,
          sdsname);

        rbfile = fopen(filename, "wb");
        if (rbfile == NULL)
          LOG_ERROR("opening output raw binary file", "main");
      }

      /* Read patches (in input data type) and write to output file (in
         output data type). If NN kernel, then fill any holes left from the
         resampling process. */
      if (!UnscramblePatches(patches, output, param->output_file_format,
          MasterGeoMem, rbfile, param->output_data_type, param->kernel_type))
        LOG_ERROR("unscrambling the output file", "main");

      /* Done with the patches */
      if (!FreePatches(patches))
        LOG_ERROR("freeing patches", "main");

      /* Close output HDF file */
      if (param->output_file_format == HDF_FMT ||
          param->output_file_format == BOTH)
      {
        if (!CloseOutput(output))
          LOG_ERROR("closing output file", "main");

        /* If not appending, write metadata to output HDF file */
        if (file_created)
        {
          if (!WriteMeta(output->file_name, &param->output_space_def)) 
            LOG_ERROR("writing metadata", "main");
        }
      }

      /* Close output GeoTiff file */
      if (param->output_file_format == GEOTIFF_FMT ||
          param->output_file_format == BOTH)
      {
        Close_GEOTIFF( MasterGeoMem );
        /* CloseGeoTIFFFile(&MasterGeoMem); */
        output->open = false;
      }

      /* Close output raw binary file */
      if (param->output_file_format == RB_FMT)
      {
        fclose(rbfile);
        output->open = false;
      }

      /* Free remaining memory */
      if (!FreeGeoloc(geoloc)) 
        LOG_ERROR("freeing geoloc file stucture", "main");
      if (!FreeInput(input)) 
        LOG_ERROR("freeing input file stucture", "main");
      if (param->output_file_format == HDF_FMT ||
          param->output_file_format == BOTH) {
        if (!FreeOutput(output)) 
          LOG_ERROR("freeing output file stucture", "main");
      }

      /* Get rid of patches file */
      ThisPid = getpid();
      sprintf(CharThisPid,"%d",(int)ThisPid);
      strcpy(FinalFileName,param->patches_file_name);
      strcat(FinalFileName,CharThisPid);

      exec_resamp = remove(FinalFileName);
      if(exec_resamp == -1)
      {
        LOG_ERROR("Something bad happened deleting patches file", "main");
      }  

      /* Free the parameter structure */
      if (!FreeParam(param)) 
        LOG_ERROR("freeing user parameter structure", "main");
    } /* loop through bands in the current SDS */
  } /* loop through SDSs */

  /* If output format is HDF then append the metadata, for all resolutions */
  if (param_save->output_file_format == HDF_FMT ||
      param_save->output_file_format == BOTH)
  {
    /* Initialize the create_output structure again for all the SDSs. This
       will be used to determine if the metadata needs to be appended. */
    for (curr_sds = 0; curr_sds < param_save->num_input_sds; curr_sds++)
      param_save->create_output[curr_sds] = true;

    /* Loop through all the SDSs */
    for (curr_sds = 0; curr_sds < param_save->num_input_sds; curr_sds++)
    {
      /* Do we need to append the metadata or has it already been done for
         the current SDSs HDF file? */
      if (!param_save->create_output[curr_sds])
        continue;

      /* Determine the name of the output HDF file */
      if (param_save->multires)
      {
        if (param_save->output_space_def.proj_num != PROJ_GEO)
          /* Output the pixel size with only two decimal places, since
             the pixel size will be in meters */
          sprintf(HDF_File, "%s_%dm.hdf", param_save->output_file_name,
            (int) param_save->output_pixel_size[curr_sds]);
        else
          /* Output the pixel size with four decimal places, since the
             pixel size will be in degrees (need to convert from radians) */
          sprintf(HDF_File, "%s_%.04fd.hdf", param_save->output_file_name,
            param_save->output_pixel_size[curr_sds] * DEG);
      }
      else
      {
        sprintf(HDF_File, "%s.hdf", param_save->output_file_name);
      }

      /* Append the metadata for this HDF file, only for the SDSs of the
         current resolution */
      if (!AppendMetadata(param_save, HDF_File, param_save->input_file_name,
        curr_sds)) 
      {
          /* NOTE: We won't flag this as an error, since in some cases the
             resolution file may not exist.  For example, if a MOD02HKM is
             specified and the Latitude or Longitude data is specified, then
             that data is at a different resolution (1000m) than the rest of
             the image SDS data (500m).  The software will think that there
             should be a 1000m product, however the Latitude and Longitude
             data didn't actually get processed .... since it is float data.
             So, AppendMetadata will flag an error since that HDF file will
             not really exist. */
/*        LOG_ERROR("appending metadata to the output HDF file","main"); */
      }

      /* Loop through the rest of the SDSs and unmark the ones of the same
         resolution, since they will be output to this same HDF file
         and therefore do not need to be recreated. */
      for (k = curr_sds; k < param_save->num_input_sds; k++)
      {
        if (param_save->output_pixel_size[k] ==
            param_save->output_pixel_size[curr_sds])
          param_save->create_output[k] = false;
      }
    }
  }

  /* Free the saved parameter structure */
  if (!FreeParam(param_save))
    LOG_ERROR("freeing saved user parameter structure", "main");

  /* Stop timer and print elapsed time */
  enddate = time(NULL);
  sprintf(msg, "\nEnd Time:  %s", ctime(&enddate));
  LogInfomsg(msg);
  LogInfomsg("Finished processing!\n");
  LogInfomsg( 
    "*********************************************************************"
    "*********\n");

  /* Close the log file */
  CloseLogHandler();

  /* All done */
  exit (EXIT_SUCCESS);
}
Example #9
0
Param_t *GetParam(int argc, const char **argv)
/* 
!C******************************************************************************

!Description: 'GetParam' sets up the 'param' data structure and populate with user
 parameters, either from the command line or from a parameter file.
 
!Input Parameters:
 argc           number of command line arguments
 argv           command line argument list

!Output Parameters:
 (returns)      'param' data structure or NULL when an error occurs

!Team Unique Header:

 ! Design Notes:
   1. An error status is returned when:
       a. memory allocation is not successful
       b. an error is returned from the ReadCmdLine function
       c. certain required parameters are invalid or not entered:
            input file name, output file name, geolocation file name,
	    SDS name, output space projection number, 
	    output space pixel size, output space upper left corner, 
	    output space image size, either output space sphere or projection
	    parameter number 0
	    output space zone number not given for UTM
   2. Error of type 'a' are handled with the 'LOG_RETURN_ERROR' macro and 
      the others are handled by writting the error messages to 'stderr' and 
      then printing the usage information.
   3. 'FreeParam' should be called to deallocate memory used by the 
      'param' data structures.

!END****************************************************************************
*/
{
  Param_t *this;
  Input_t *input = NULL;
  int i, j, ip, jp;
  char tmp_sds_name[MAX_STR_LEN];
  char errstr[M_MSG_LEN+1];            /* error string for OpenInput */
  char msg[M_MSG_LEN+1];
  char *extptr;                        /* ptr to the output file extension */
  double tmp_pixel_size;
  Geo_coord_t ul_corner;
  Geo_coord_t lr_corner;
  int copy_dim[MYHDF_MAX_RANK];

  /* Create the Param data structure */
  this = (Param_t *)malloc(sizeof(Param_t));
  if (this == (Param_t *)NULL)
    LOG_RETURN_ERROR("allocating Input structure", "GetParam",
                          (Param_t *)NULL);

  /* set default parameters */
  this->multires = false;
  this->input_file_name = (char *)NULL;
  this->output_file_name = (char *)NULL;
  this->geoloc_file_name = (char *)NULL;
  this->input_space_type = SWATH_SPACE;   /* Default is input swath */
  this->output_file_format = HDF_FMT;     /* Default is HDF output */

  this->num_input_sds = 0;                /* Default is no SDSs specified */
  this->output_space_def.pixel_size = -1.0;
  for (ip = 0; ip < MAX_SDS_DIMS; ip++)
  {
    this->input_sds_nbands[ip] = 0;
    this->output_pixel_size[ip] = -1.0;
    this->output_img_size[ip].l = -1;
    this->output_img_size[ip].s = -1;
    this->output_dt_arr[ip] = -1;
    this->ires[ip] = -1;
    this->fill_value[ip] = -1.0;

    for (jp = 0; jp < MAX_VAR_DIMS; jp++)
      this->input_sds_bands[ip][jp] = 0; /* Default is no bands processed */

    this->create_output[ip] = true;
    this->rank[ip] = 2;
    for (jp = 0; jp < MYHDF_MAX_RANK; jp++)
      this->dim[ip][jp] = 0;
    this->dim[ip][0] = -1;
    this->dim[ip][1] = -2;
  }

  this->input_sds_name = (char *)NULL;
  this->output_sds_name = (char *)NULL;
  this->iband = -1;
  this->kernel_type = NN;

  this->output_space_def.proj_num = -1;
  for (ip = 0; ip < NPROJ_PARAM; ip++)
    this->output_space_def.proj_param[ip] = 0.0;
  for (ip = 0; ip < NPROJ_PARAM; ip++)
    this->output_space_def.orig_proj_param[ip] = 0.0;
  this->output_space_def.ul_corner.x = -1.0;
  this->output_space_def.ul_corner.y = -1.0;
  this->output_space_def.ul_corner_geo.lat = -1.0;
  this->output_space_def.ul_corner_geo.lon = -1.0;
  this->output_space_def.ul_corner_set = false;
  this->output_space_def.lr_corner.x = -1.0;
  this->output_space_def.lr_corner.y = -1.0;
  this->output_space_def.lr_corner_geo.lat = -1.0;
  this->output_space_def.lr_corner_geo.lon = -1.0;
  this->output_space_def.lr_corner_set = false;
  this->output_space_def.img_size.l = -1;
  this->output_space_def.img_size.s = -1;
  this->output_space_def.zone = 0;
  this->output_space_def.zone_set = false;
  this->output_space_def.sphere = -1;
  this->output_space_def.isin_type = SPACE_NOT_ISIN;
  this->output_spatial_subset_type = LAT_LONG;

  /* Input space is not really used, since the MRTSwath will not
     work with Grids (only swath) */
  this->input_space_def.proj_num = -1;
  for (ip = 0; ip < NPROJ_PARAM; ip++)
    this->input_space_def.proj_param[ip] = 0.0;
  this->input_space_def.pixel_size = -1.0;
  this->input_space_def.ul_corner.x = -1.0;
  this->input_space_def.ul_corner.y = -1.0;
  this->input_space_def.ul_corner_set = false;
  this->input_space_def.img_size.l = -1;
  this->input_space_def.img_size.s = -1;
  this->input_space_def.zone = 0;
  this->input_space_def.zone_set = false;
  this->input_space_def.sphere = -1;
  this->input_space_def.isin_type = SPACE_NOT_ISIN;

  this->output_data_type = -1;
  this->patches_file_name = "patches.tmp";        

  /* Read the command-line and parameter file parameters */
  if (!ReadCmdLine(argc, argv, this)) {
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  /* Check to see that all of the parameters are entered */
  if ((this->input_file_name == (char *)NULL)  ||  
      (strlen(this->input_file_name) < 1)) {
    sprintf(msg, "resamp: input file name not given\n");
    LogInfomsg(msg);
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  /* Check the output filename */
  if ((this->output_file_name == (char *)NULL)  ||  
      (strlen(this->output_file_name) < 1)) {
    sprintf(msg, "resamp: output file name not given\n");
    LogInfomsg(msg);
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  /* Check to see if a .hdf, .hdr. or .tif extension was provided in the
     filename. If so, remove it since the output file format will specify
     the output extension. */
  extptr = strstr (this->output_file_name, ".hdf");
  if (extptr)
    extptr[0] = '\0';

  extptr = strstr (this->output_file_name, ".HDF");
  if (extptr)
    extptr[0] = '\0';

  extptr = strstr (this->output_file_name, ".hdr");
  if (extptr)
    extptr[0] = '\0';

  extptr = strstr (this->output_file_name, ".HDR");
  if (extptr)
    extptr[0] = '\0';

  extptr = strstr (this->output_file_name, ".tif");
  if (extptr)
    extptr[0] = '\0';

  extptr = strstr (this->output_file_name, ".TIF");
  if (extptr)
    extptr[0] = '\0';

  /* Check the output file format */
  if ((this->output_file_format != HDF_FMT) && 
      (this->output_file_format != GEOTIFF_FMT) &&
      (this->output_file_format != RB_FMT) &&
      (this->output_file_format != BOTH)) {
    sprintf(msg, "resamp: unsupported output file format\n");    
    LogInfomsg(msg);
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  if ((this->input_space_type == SWATH_SPACE)  &&
      ((this->geoloc_file_name == (char *)NULL)  ||  
       (strlen(this->input_file_name) < 1))) {
    sprintf(msg, "resamp: geolocation file name not given\n");
    LogInfomsg(msg);
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  /* If no SDS names were specified then process all of them in the file,
     otherwise fill in the rest of the SDS information. */
  if (this->num_input_sds == 0) {
    /* Process all the SDS names, by default */
#ifdef DEBUG
    printf ("Reading default SDSs\n");
#endif
    this->num_input_sds = ReadSDS(this);
    if (this->num_input_sds == 0) {
      sprintf(msg, "resamp: error reading default SDS names\n");
      LogInfomsg(msg);
      FreeParam(this);
      sprintf(msg, "%s\n", USAGE);
      LogInfomsg(msg);
      return (Param_t *)NULL; 
    }
  }
  else {
    /* Read the SDSs and determine the number of bands in each */
    if (!SDSInfo(this)) {
      sprintf(msg, "resamp: error reading SDS information\n");
      LogInfomsg(msg);
      FreeParam(this);
      sprintf(msg, "%s\n", USAGE);
      LogInfomsg(msg);
      return (Param_t *)NULL; 
    }
  }

  /* Check output space definition */
  if (this->output_space_def.proj_num < 0) {
    sprintf(msg, "resamp: output space projection number not given\n");
    LogInfomsg(msg);
    FreeParam(this);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    return (Param_t *)NULL; 
  }

  /* Loop through all the SDSs and determine their resolution */
  for (i = 0; i < this->num_input_sds; i++)
  {
    /* Loop through all the bands in the current SDS until we find one
       that will be processed. Use that band to get the resolution of the
       SDS, since all the bands in the SDS will be the same resolution. */
    for (j = 0; j < this->input_sds_nbands[i]; j++)
    {
      /* Is this band one that should be processed? */
      if (!this->input_sds_bands[i][j])
        continue;

      /* Create the input_sds_name which is "SDSname, band" */
      if (this->input_sds_nbands[i] == 1)
      {
        /* 2D product so the band number is not needed */
        sprintf(tmp_sds_name, "%s", this->input_sds_name_list[i]);
      }
      else
      {
        /* 3D product so the band number is required */
        sprintf(tmp_sds_name, "%s, %d", this->input_sds_name_list[i], j);
      }

      this->input_sds_name = strdup (tmp_sds_name);
      if (this->input_sds_name == NULL) {
        sprintf(msg, "resamp: error creating input SDS band name");
	LogInfomsg(msg);
        FreeParam(this);
        return (Param_t *)NULL;
      }

#ifdef DEBUG
      printf ("Getting param %s ...\n", this->input_sds_name);
#endif

      /* Update the system to process the current SDS and band */
      if (!update_sds_info(i, this)) {
        sprintf(msg, "resamp: error updating SDS information");
	LogInfomsg(msg);
        FreeParam(this);
        return (Param_t *)NULL;
      }

      /* Make a copy of the dim parameters, since they get modified */
      for (ip = 0; ip < MYHDF_MAX_RANK; ip++) {
        copy_dim[ip] = this->dim[i][ip];
      }

      /* Open input file for the specified SDS and band */
      input = OpenInput(this->input_file_name, this->input_sds_name,
                        this->iband, this->rank[i], copy_dim, errstr);
      if (input == (Input_t *)NULL) {
        /* This is an invalid SDS for our processing so skip to the next
           SDS. We will only process SDSs that are at the 1km, 500m, or
           250m resolution (i.e. a factor of 1, 2, or 4 compared to the
           1km geolocation lat/long data). We also only process CHAR8,
           INT8, UINT8, INT16, and UINT16 data types. */
#ifdef DEBUG
        printf("%s\n", errstr);
        printf("%s %ld: param, not processing SDS/band\n\n", (__FILE__),
          (long)(__LINE__));
#endif
        break;
      }

      /* Determine the resolution of each of the input SDSs */
      if (!DetermineResolution(&input->sds, &input->dim, &this->ires[i])) {
        sprintf(msg, "resamp: error determining input resolution\n");
	LogInfomsg(msg);
        CloseInput(input);
        FreeInput(input);
        FreeParam(this);
        return (Param_t *)NULL; 
      }

      /* Close input file */
      if (!CloseInput(input)) {
        sprintf(msg, "resamp: closing input file");
	LogInfomsg(msg);
        FreeInput(input);
        FreeParam(this);
        return (Param_t *)NULL; 
      }

      /* Free the input structure */
      if (!FreeInput(input)) {
        sprintf(msg, "resamp: freeing input file stucture");
	LogInfomsg(msg);
        FreeParam(this);
        return (Param_t *)NULL;
      }

      /* We only need one band in this SDS, so break out of the loop */
      break;
    }  /* for (j = 0; j < this->input_sds_nbands[i]; j++) */
  }  /* for (i = 0; i < this->num_input_sds; i++) */

  /* Verify that at least one output pixel size value is defined */
  if (this->output_pixel_size[0] < 0.0) {
    /* No pixel size was specified, so try to determine the resolution of
       the input SDSs and use that for the pixel size. It is assumed that
       the input swath product will have the same resolution for all SDSs. */
    if (!DeterminePixelSize(this->geoloc_file_name, this->num_input_sds,
      this->ires, this->output_space_def.proj_num,
      this->output_pixel_size)) {
      sprintf(msg, "resamp: error determining output pixel size. "
        "Therefore, in order to process this data, the output pixel size "
        "must be specified.\n");
      LogInfomsg(msg);
      FreeParam(this);
      sprintf(msg, "%s\n", USAGE);
      LogInfomsg(msg);
      return (Param_t *)NULL; 
    }

    /* Set multires to FALSE since the output product will have the same
       resolution for all SDSs */
    this->multires = false;
  }

  /* If not enough pixel sizes were provided, then fill the pixel sizes
     in with the very last valid pixel size */
  for (ip = 0; ip < this->num_input_sds; ip++) {
    if (this->output_pixel_size[ip] < 0.0) {
      /* This is the first undefined pixel size, so grab the previous
         pixel size since it was the last valid pixel size value */
      tmp_pixel_size = this->output_pixel_size[ip-1];
      break;
    }
  }

  /* Fill in the rest of the values with the saved pixel size value */
  for (; ip < this->num_input_sds; ip++) {
    this->output_pixel_size[ip] = tmp_pixel_size;
  }

  /* Check the user-specified pixel sizes to see if the output product
     is multiple resolutions */
  for (ip = 0; ip < this->num_input_sds; ip++) {
    if (this->output_pixel_size[ip] != this->output_pixel_size[0])
      this->multires = true;
  }

  /* If the UL or LR corner was not specified, then use the bounding coords */
  if (!this->output_space_def.ul_corner_set ||
      !this->output_space_def.lr_corner_set) {
    /* Read the BOUNDING coords, by default */
    if (!ReadBoundCoords(this->input_file_name, &ul_corner, &lr_corner)) {
      sprintf(msg, "resamp: error reading BOUNDING COORDS from metadata. "
        "Therefore, in order to process this data, the output spatial "
        "subsetting will need to be specified.\n");
      LogInfomsg(msg);
      sprintf(msg, "%s\n", USAGE);
      LogInfomsg(msg);
      FreeParam(this);
      return (Param_t *)NULL; 
    }
    else {
      /* Store all initial corner points in the x/y corner structure.
         The call to convert_corners will handle moving to the lat/long
         structure location. */
      this->output_space_def.ul_corner_set = true;
      this->output_space_def.lr_corner_set = true;
      this->output_space_def.ul_corner.x = ul_corner.lon;
      this->output_space_def.ul_corner.y = ul_corner.lat;
      this->output_space_def.lr_corner.x = lr_corner.lon;
      this->output_space_def.lr_corner.y = lr_corner.lat;
      this->output_spatial_subset_type = LAT_LONG;
    }
  }

  if ((this->output_space_def.proj_param[0] <= 0.0) && 
      (this->output_space_def.sphere < 0)) {
    sprintf(msg, "resamp: either output space sphere or projection "
            "parameter number 0 must be given\n");
    LogInfomsg(msg);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  if ((this->output_space_def.proj_num == 1)  &&  /* UTM => proj_num = 1 */
       !this->output_space_def.zone_set) { 
    sprintf(msg, "resamp: output space zone number not given for UTM\n");
    LogInfomsg(msg);
    sprintf(msg, "%s\n", USAGE);
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  if (this->output_space_def.proj_num == 31) /* ISINUS => proj_num = 31 */
    this->output_space_def.isin_type= SPACE_ISIN_NEST_1;

  /* Copy the projection parameters to orig_proj_param to use the decimal
     degree values later (GeoTiff output) */
  for (i = 0; i < NPROJ_PARAM; i++) {
    this->output_space_def.orig_proj_param[i] =
      this->output_space_def.proj_param[i];
  }

  /* Convert the output projection parameter lat/long values from decimal
     degrees to DMS */
  if (!Deg2DMS (this->output_space_def.proj_num,
                this->output_space_def.proj_param)) {
    sprintf(msg, "resamp: error converting projection parameters from"
            "decimal degrees to DMS\n");
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  /* Use the UL and LR corner points to get the UL corner in output
     space and the number of lines/samples in the output image. This must
     be done for each SDS, since the pixel size might be different. */
  if (!ConvertCorners (this)) {
    sprintf(msg, "resamp: error determining UL and lines/samples from "
            "the input UL and LR corners\n");
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  /* Make sure the lat/long values are between +-180 and +-90 */
  if (this->output_space_def.ul_corner_geo.lat < -90.0 ||
      this->output_space_def.ul_corner_geo.lat > 90.0  ||
      this->output_space_def.lr_corner_geo.lat < -90.0 ||
      this->output_space_def.lr_corner_geo.lat > 90.0  ||
      this->output_space_def.ul_corner_geo.lon < -180.0 ||
      this->output_space_def.ul_corner_geo.lon > 180.0  ||
      this->output_space_def.lr_corner_geo.lon < -180.0 ||
      this->output_space_def.lr_corner_geo.lon > 180.0) {
    sprintf(msg, "resamp: invalid output lat/lon corners\n");
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  /* MRTSwath will only process swath data */
  if (this->input_space_type != SWATH_SPACE) {
    sprintf(msg, "resamp: grid or point data detected. MRTSwath will "
            "only process swath data\n");
    LogInfomsg(msg);
    FreeParam(this);
    return (Param_t *)NULL; 
  }

  return this;
}
Example #10
0
Param_t *GetParam(int argc, const char **argv)
/* 
!C******************************************************************************

!Description: 'GetParam' sets up the 'param' data structure and populate with user
 parameters, either from the command line or from a parameter file.
 
!Input Parameters:
 argc           number of command line arguments
 argv           command line argument list

!Output Parameters:
 (returns)      'param' data structure or NULL when an error occurs

!Team Unique Header:

 ! Design Notes:
   1. An error status is returned when:
       a. memory allocation is not successful
       b. an error is returned from the ReadCmdLine function
       c. certain required parameters are invalid or not entered:
            input file name, output file name, geolocation file name,
	    SDS name, output space projection number, 
	    output space pixel size, output space upper left corner, 
	    output space image size, either output space sphere or projection
	    parameter number 0
	    output space zone number not given for UTM
       d. the input is 'GRID_SPACE' then and certain required parameters 
          are invalid or not entered:
	    input space projection number, input space pixel size, 
	    input space upper left corner, either input space sphere or 
	    projection parameter number 0
       e. the input is 'GRID_SPACE' and the geolocation file name is given
       f. the resampling kernel is 'USER_KERNEL' and the kernel file name 
          is invalid or not entered.
   2. Error of type 'a' are handled with the 'RETURN_ERROR' macro and 
      the others are handled by writting the error messages to 'stderr' and 
      then printing the usage information.
   3. 'FreeParam' should be called to deallocate memory used by the 
      'param' data structures.

!END****************************************************************************
*/
{
  Param_t *this;
  char *error_string = (char *)NULL;
  FILE *fp;
  Key_t key;
  int i,len;
  char line[MAX_STR_LEN + 1];
  char temp[MAX_STR_LEN + 1];
  Param_key_t param_key;
  char *param_file_name;
  bool got_start, got_end;

  if (argc < 2) 
    RETURN_ERROR("no command line parameter", "GetParam", 
                 (Param_t *)NULL);
  if (argc > 2) 
    RETURN_ERROR("too many command line parameters", "GetParam", 
                 (Param_t *)NULL);
  if (strlen(argv[1]) < 1)
    RETURN_ERROR("no paramter file name", "GetParam", 
                 (Param_t *)NULL);
  param_file_name = (char *)argv[1];

  /* Open the parameter file */
  
  if ((fp = fopen(param_file_name, "r")) == (FILE *)NULL)
    RETURN_ERROR("unable to open parameter file", "GetParam", 
                 (Param_t *)NULL);

  /* Create the Param data structure */

  this = (Param_t *)malloc(sizeof(Param_t));
  if (this == (Param_t *)NULL) {
    fclose(fp);
    RETURN_ERROR("allocating Input structure", "GetParam", 
                 (Param_t *)NULL);
  }

  /* set default parameters */

  this->param_file_name  = (char *)NULL;
  this->input_file_name  = (char *)NULL;
  this->lut_file_name    = (char *)NULL;
  this->output_file_name = (char *)NULL;
  this->PGEVersion       = (char *)NULL;
  this->ProcessVersion   = (char *)NULL;
  this->num_ncep_files   = 0;            /* number of NCEP files     */
  this->num_prwv_files   = 0;            /* number of PRWV hdf files */
  this->num_ozon_files   = 0;            /* number of OZONe hdf files */
  this->dem_file = (char *)NULL;
  this->dem_flag = false;
  this->cloud_flag= false;
  this->thermal_band=false;

  /* Populate the data structure */

  this->param_file_name = DupString(param_file_name);
  if (this->param_file_name == (char *)NULL)
    error_string = "duplicating parameter file name";

  if (error_string == (char *)NULL) {
    this->lut_file_name = DupString(LUT_FILE_NAME);
    if (this->lut_file_name == (char *)NULL)
      error_string = "duplicating lookup table file name";
  }

  if (error_string != (char *)NULL) {
    if (this->param_file_name != (char *)NULL) 
      free(this->param_file_name);
    if (this->lut_file_name != (char *)NULL) 
      free(this->lut_file_name);
    FreeParam(this);
    RETURN_ERROR(error_string, "GetParam", (Param_t *)NULL);
  }

  /* Parse the header file */

  got_start = got_end = false;

  while((len = GetLine(fp, line)) > 0) {

    if (!StringParse(line, &key)) {
      sprintf(temp, "parsing header file; line = %s", line);
      error_string = temp;
      break;
    }
    if (key.len_key <= 0) continue;
    if (key.key[0] == '#') continue;

    param_key = (Param_key_t)
       KeyString(key.key, key.len_key, Param_string, 
		 (int)PARAM_NULL, (int)PARAM_MAX);
    if (param_key == PARAM_NULL) {
      key.key[key.len_key] = '\0';
      sprintf(temp, "invalid key; key = %s", key.key);
      error_string = temp;
      break;
    }
    if (!got_start) {
      if (param_key == PARAM_START) {
        if (key.nval != 0) {
	  error_string = "no value expected (start key)";
	  break;
	}
        got_start = true;
	continue;
      } else {
        error_string  = "no start key in parameter file";
        break;
      }
    }

    /* Get the value for each keyword */


    switch (param_key) {

      case PARAM_REF_FILE:
        if (key.nval <= 0) {
	  error_string = "no reflectance file name";
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many reflectance file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
	  error_string = "no reflectance file name";
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->input_file_name = DupString(key.value[0]);
	if (this->input_file_name == (char *)NULL) {
	  error_string = "duplicating reflectance file name";
	  break;
        }
        break;

      case PARAM_L5_REF:
        if (key.nval <= 0) {
          error_string = "no reflectance file name";
          break;
        } else if (key.nval > 1) {
          error_string = "too many reflectance file names";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no reflectance file name";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->input_file_name = DupString(key.value[0]);
        if (this->input_file_name == (char *)NULL) {
          error_string = "duplicating reflectance file name";
          break;
        }
        break;

      case PARAM_L7_REF:
        if (key.nval <= 0) {
          error_string = "no reflectance file name";
          break;
        } else if (key.nval > 1) {
          error_string = "too many reflectance file names";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no reflectance file name";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->input_file_name = DupString(key.value[0]);
        if (this->input_file_name == (char *)NULL) {
          error_string = "duplicating reflectance file name";
          break;
        }
        break;

      case PARAM_KTM_FILE:
        if (key.nval <= 0) {
          error_string = "no reflectance file name";
          break;
        } else if (key.nval > 1) {
          error_string = "too many reflectance file names";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no reflectance file name";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->input_file_name = DupString(key.value[0]);
        if (this->input_file_name == (char *)NULL) {
          error_string = "duplicating reflectance file name";
          break;
        }
        break;

      case PARAM_CSM_FILE:
        if (key.nval <= 0) {
          this->cloud_flag= false;
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many cloud mask file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
          this->cloud_flag= false;
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->cloud_mask_file  = DupString(key.value[0]);
	if (this->cloud_mask_file == (char *)NULL) {
	  error_string = "duplicating cloud mask file name";
	  break;
        }
		  this->cloud_flag= true;  /** NAZMI **/
		  printf("cloud mask set to true\n");
        break;

      case PARAM_L5_CSM:
        if (key.nval <= 0) {
          this->cloud_flag= false;
          break;
        } else if (key.nval > 1) {
          error_string = "too many cloud mask file names";
          break;
        }
        if (key.len_value[0] < 1) {
          this->cloud_flag= false;
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->cloud_mask_file  = DupString(key.value[0]);
        if (this->cloud_mask_file == (char *)NULL) {
          error_string = "duplicating cloud mask file name";
          break;
        }
                  this->cloud_flag= true;  /** NAZMI **/
        break;

      case PARAM_L7_CSM:
        if (key.nval <= 0) {
          this->cloud_flag= false;
          break;
        } else if (key.nval > 1) {
          error_string = "too many cloud mask file names";
          break;
        }
        if (key.len_value[0] < 1) {
          this->cloud_flag= false;
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->cloud_mask_file  = DupString(key.value[0]);
        if (this->cloud_mask_file == (char *)NULL) {
          error_string = "duplicating cloud mask file name";
          break;
        }
                  this->cloud_flag= true;  /** NAZMI **/
        break;

      case PARAM_TEMP_FILE:
        if (key.nval <= 0) {
		  this->thermal_band=false;
	  error_string = "no Temp file name";
	  break; 
	} else if (key.nval > 1) {
		  this->thermal_band=false;
	  error_string = "too many Temp file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
		  this->thermal_band=false;
	  error_string = "no Temp file name";
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
	this->thermal_band=true;
        this->temp_file_name = DupString(key.value[0]);
	if (this->temp_file_name == (char *)NULL) {
		  this->thermal_band=false;
	  error_string = "duplicating Temp file name";
	  break;
        }
        break;


      case PARAM_SR_FILE:
        if (key.nval <= 0) {
	  error_string = "no Kal/Thomas file name";
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many Kal/Thomas file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
	  error_string = "no Kal/Thomas file name";
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->output_file_name = DupString(key.value[0]);
	if (this->output_file_name == (char *)NULL) {
	  error_string = "duplicating Kal/Thomas file name";
	  break;
        }
        break;

      case PARAM_SR1_FILE:
        if (key.nval <= 0) {
          error_string = "no Kal/Thomas file name";
          break;
        } else if (key.nval > 1) {
          error_string = "too many Kal/Thomas file names";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no Kal/Thomas file name";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->output_file_name = DupString(key.value[0]);
        if (this->output_file_name == (char *)NULL) {
          error_string = "duplicating Kal/Thomas file name";
          break;
        }
        break;

      case PARAM_NCEP_FILE:
        this->num_ncep_files   = key.nval;            
	if (key.nval > 4) {
	  error_string = "too many NCEP file names";
	  break; 
	}
	for (i=0;i<key.nval;i++) {
		if (key.len_value[i] < 1) {
	 	 error_string = "no NCEP file name";
	 	 break;
		}
		key.value[i][key.len_value[i]] = '\0';
                this->ncep_file_name[i] = DupString(key.value[i]);
		if (this->ncep_file_name[i] == (char *)NULL) {
	  		error_string = "duplicating NCEP file name";
	 	   break;
                }
	}
        break;

      case PARAM_PRWV_FILE:
        this->num_prwv_files   = key.nval;       
	if (key.nval > 1) {
	  error_string = "too many PRWV file names";
	  break; 
	}
	if (key.nval > 0) {
		if (key.len_value[0] < 1) {
	 	 error_string = "no PRWV hdf file name";
	 	 break;
		}
		key.value[0][key.len_value[0]] = '\0';
                this->prwv_file_name = DupString(key.value[0]);
		if (this->prwv_file_name == (char *)NULL) {
                   error_string = "duplicating PRWV hdf file name";
	 	   break;
                }
	}
        break;

      case PARAM_PRW1_FILE:
        this->num_prwv_files   = key.nval;
        if (key.nval > 1) {
          error_string = "too many PRWV file names";
          break;
        }
        if (key.nval > 0) {
                if (key.len_value[0] < 1) {
                 error_string = "no PRWV hdf file name";
                 break;
                }
                key.value[0][key.len_value[0]] = '\0';
                this->prwv_file_name = DupString(key.value[0]);
                if (this->prwv_file_name == (char *)NULL) {
                   error_string = "duplicating PRWV hdf file name";
                   break;
                }
        }
        break;

      case PARAM_OZON_FILE:
        this->num_ozon_files   = key.nval;       
	if (key.nval > 1) {
	  error_string = "too many OZON file names";
	  break; 
	}
	if (key.nval > 0) {
		if (key.len_value[0] < 1) {
	 	 error_string = "no OZON hdf file name";
	 	 break;
		}
		key.value[0][key.len_value[0]] = '\0';
                this->ozon_file_name = DupString(key.value[0]);
		if (this->ozon_file_name == (char *)NULL) {
                   error_string = "duplicating OZON hdf file name";
	 	   break;
                }
	}
        break;

      case PARAM_OZO1_FILE:
        this->num_ozon_files   = key.nval;
        if (key.nval > 1) {
          error_string = "too many OZON file names";
          break;
        }
        if (key.nval > 0) {
                if (key.len_value[0] < 1) {
                 error_string = "no OZON hdf file name";
                 break;
                }
                key.value[0][key.len_value[0]] = '\0';
                this->ozon_file_name = DupString(key.value[0]);
                if (this->ozon_file_name == (char *)NULL) {
                   error_string = "duplicating OZON hdf file name";
                   break;
                }
        }
        break;

      case PARAM_DEM_FILE:
        this->dem_flag = true;
        if (key.nval <= 0) {
          this->dem_flag = false;
	  break; 
	} else if (key.nval > 1) {
	  error_string = "too many DEM file names";
	  break; 
	}
	if (key.len_value[0] < 1) {
          this->dem_flag = false;
	  break;
	}
	key.value[0][key.len_value[0]] = '\0';
        this->dem_file  = DupString(key.value[0]);
	if (this->dem_file == (char *)NULL) {
	  error_string = "duplicating dem file name";
	  break;
        }
        break;

      case PARAM_PGEVERSION:
        if (key.nval <= 0) {
          error_string = "no PGEVersion number";
          break;
        } else if (key.nval > 1) {
          error_string = "too many PGEVersion numbers";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no PGEVersion number";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->PGEVersion = DupString(key.value[0]);
        if (this->PGEVersion == (char *)NULL) {
          error_string = "duplicating PGEVersion number";
          break;
        }
        break;

      case PARAM_PROCESSVERSION:
        if (key.nval <= 0) {
          error_string = "no ProcessVersion number";
          break;
        } else if (key.nval > 1) {
          error_string = "too many ProcessVersion numbers";
          break;
        }
        if (key.len_value[0] < 1) {
          error_string = "no ProcessVersion number";
          break;
        }
        key.value[0][key.len_value[0]] = '\0';
        this->ProcessVersion = DupString(key.value[0]);
        if (this->ProcessVersion == (char *)NULL) {
          error_string = "duplicating ProcessVersion number";
          break;
        }
        break;

      case PARAM_END:
        if (key.nval != 0) {
	  error_string = "no value expected (end key)";
	  break; 
	}
        got_end = true;
        break;

      default:
        error_string = "key not implmented";

    }
    if (error_string != (char *)NULL) break;
    if (got_end) break;

  }

  /* Close the parameter file */

  fclose(fp);

  if (error_string == (char *)NULL) {
    if (!got_start) 
      error_string = "no start key in header";
    else if (!got_end)
      error_string = "no end key in header";
  }

  /* Handle null values */
  
  if (error_string == (char *)NULL) {
    if (this->input_file_name == (char *)NULL) 
      error_string = "no input file name given";
    if (this->lut_file_name == (char *)NULL) 
      error_string = "no lookup table file name given";
    if (this->output_file_name == (char *)NULL) 
      error_string = "no output file name given";
    if (this->PGEVersion == (char *)NULL)
      error_string = "no PGE Version given";
    if (this->ProcessVersion == (char *)NULL)
      error_string = "no Process Version given";
  }

  /* Handle errors */

  if (error_string != (char *)NULL) {
    if (this->param_file_name != (char *)NULL) 
      free(this->param_file_name);
    if (this->input_file_name != (char *)NULL) 
      free(this->input_file_name);
    if (this->lut_file_name != (char *)NULL) 
      free(this->lut_file_name);
    if (this->output_file_name != (char *)NULL) 
      free(this->output_file_name);
    if (this->PGEVersion != (char *)NULL)
      free(this->PGEVersion);
    if (this->ProcessVersion != (char *)NULL)
      free(this->ProcessVersion);
    if (this != (Param_t *)NULL) free(this);
    RETURN_ERROR(error_string, "GetParam", (Param_t *)NULL);
  }
  
  return this;
}