Пример #1
0
void IsisMain() {
  // Create a process by line object
  ProcessByLine p;

  // Get the size of the cube
  Cube *icube = p.SetInputCube("FROM");

  //  Open output text file
  UserInterface &ui = Application::GetUserInterface();
  QString to = ui.GetFileName("TO", "txt");
  fout.open(to.toAscii().data());

  // Print header if needed
  if(ui.GetBoolean("HEADER")) {
    fout << "Input Cube:  " << icube->fileName() << endl;
    fout << "Samples:Lines:Bands:  " << icube->sampleCount() << ":" <<
         icube->lineCount() << ":" << icube->bandCount() << endl;
  }

  // List the cube
  p.StartProcess(isis2ascii);
  p.EndProcess();

  fout.close();
}
Пример #2
0
  /**
   * Constructs a UniversalGroundMap object from a cube
   *
   * @param cube The Cube to create the UniversalGroundMap from
   * @param priority Try to make a camera or projection first
   */
  UniversalGroundMap::UniversalGroundMap(Cube &cube, CameraPriority priority) {
    p_camera = NULL;
    p_projection = NULL;

    Pvl &pvl = *cube.label();
    try {
      if(priority == CameraFirst)
        p_camera = CameraFactory::Create(cube);
      else
        p_projection = Isis::ProjectionFactory::CreateFromCube(pvl);
    }
    catch (IException &firstError) {
      p_camera = NULL;
      p_projection = NULL;

      try {
        if(priority == CameraFirst)
          p_projection = Isis::ProjectionFactory::CreateFromCube(pvl);
        else
          p_camera = CameraFactory::Create(cube);
      }
      catch (IException &secondError) {
        p_projection = NULL;
        QString msg = "Could not create camera or projection for [" +
                          cube.fileName() + "]";
        IException realError(IException::Unknown, msg, _FILEINFO_);
        realError.append(firstError);
        realError.append(secondError);
        throw realError;
      }
    }
  }
Пример #3
0
QList<ControlPoint *> getValidPoints(Cube &cube, STRtree &coordTree) {
  ImagePolygon poly;
  try {
    cube.read(poly);
  }
  catch (IException &e) {
    QString msg = "Footprintinit must be run prior to running cnetadd";
    msg += " with POLYGON=TRUE for cube [" + cube.fileName() + "]";
    throw IException(e, IException::User, msg, _FILEINFO_);
  }

  std::vector<void *> matches;
  MultiPolygon *polys = poly.Polys();
  for (unsigned int i = 0; i < polys->getNumGeometries(); i++) {
    const Geometry *geometry = polys->getGeometryN(i);
    const Envelope *boundingBox = geometry->getEnvelopeInternal();

    coordTree.query(boundingBox, matches);
  }

  QList<ControlPoint *> results;
  for (unsigned int i = 0; i < matches.size(); i++) {
    results.append((ControlPoint *) matches[i]);
  }

  return results;
}
Пример #4
0
/**
 * @brief Initializes an ISIS cube converting it into a SPICE segment
 *
 * This method is called to extract the perinent contents of an ISIS cube file
 * and accumulate generic information that is used to create the output SPICE
 * kernel segment.  Other specific kernel types can use this class as its base
 * class and add to it additional elements to complete the needed content for
 * the NAIF kernel.
 *
 * @param cube ISIS cube file to accumulate information from
 */
void SpiceSegment::init(Cube &cube) {

  _kernels.UnLoad();  // Unload all active, owned kernels
  init();            // Init local variables

  _fname = cube.fileName();

  //  Extract ISIS CK blob and transform to CK 3 content
  NaifStatus::CheckErrors();
  try {

    // Order is somewhat important here.  The call to initialize Kernels
    // object checks the NAIF pool for existance.  It logs their NAIF
    // status as loaded which may cause trouble from here on...
    Pvl *label = cube.label();
    _kernels.Init(*label);
    Camera *camera = cube.camera();

    //  Determine segment ID from product ID if it exists, otherwise basename
    if ( _name.isEmpty() ) {
      _name = getKeyValue(*label, "ProductId");
      if (_name.isEmpty() ) {
        _name = FileName(_fname).baseName();
      }
    }

    // Get instrument and target ids
    QString value("");
    value = getKeyValue(*label, "InstrumentId");
    if (!value.isEmpty()) { _instId = value; }
    value = getKeyValue(*label, "TargetName");
    if (!value.isEmpty()) { _target = value; }

    // Get default times for sorting purposes
    setStartTime(camera->cacheStartTime().Et());
    setEndTime(camera->cacheEndTime().Et());

  } catch ( IException &ie  ) {
    ostringstream mess;
    mess << "Failed to construct Spice Segment basics from ISIS file " << _fname;
    throw IException(ie, IException::User, mess.str(), _FILEINFO_);
  }

  return;
}
Пример #5
0
void IsisMain(){

  const QString hical_program = "hicalbeta";
  const QString hical_version = "5.0";
  const QString hical_revision = "$Revision: 1.15 $";
  const QString hical_runtime = Application::DateTime();

  UserInterface &ui = Application::GetUserInterface();

  QString procStep("prepping phase");
  try {
//  The output from the last processing is the input into subsequent processing
    ProcessByLine p;

    Cube *hifrom = p.SetInputCube("FROM");
    int nsamps = hifrom->sampleCount();
    int nlines = hifrom->lineCount();

//  Initialize the configuration file
    QString conf(ui.GetAsString("CONF"));
    HiCalConf hiconf(*(hifrom->label()), conf);
    DbProfile hiprof = hiconf.getMatrixProfile();

// Check for label propagation and set the output cube
    Cube *ocube = p.SetOutputCube("TO");
    if ( !IsTrueValue(hiprof,"PropagateTables", "TRUE") ) {
      RemoveHiBlobs(*(ocube->label()));
    }

//  Set specified profile if entered by user
    if (ui.WasEntered("PROFILE")) {
      hiconf.selectProfile(ui.GetAsString("PROFILE"));
    }


//  Add OPATH parameter to profiles
    if (ui.WasEntered("OPATH")) {
      hiconf.add("OPATH",ui.GetAsString("OPATH"));
    }
    else {
      //  Set default to output directory
      hiconf.add("OPATH", FileName(ocube->fileName()).path());
    }

//  Do I/F output DN conversions
    QString units = ui.GetString("UNITS");

    //  Allocate the calibration list
    calVars = new MatrixList;

//  Set up access to HiRISE ancillary data (tables, blobs) here.  Note it they
//  are gone, this will error out. See PropagateTables in conf file.
    HiCalData caldata(*hifrom);

////////////////////////////////////////////////////////////////////////////
//  Drift Correction (Zf) using buffer pixels
//    Extracts specified regions of the calibration buffer pixels and runs
//    series of lowpass filters.  Apply spline fit if any missing data
//    remains.  Config file contains parameters for this operation.
    procStep = "ZeroBufferSmooth module";
    hiconf.selectProfile("ZeroBufferSmooth");
    hiprof = hiconf.getMatrixProfile();
    HiHistory ZbsHist;
    ZbsHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      ZeroBufferSmooth zbs(caldata, hiconf);
      calVars->add("ZeroBufferSmooth", zbs.ref());
      ZbsHist = zbs.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        zbs.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      //  NOT RECOMMENDED!  This is required for the next step!
      //  SURELY must be skipped with ZeroBufferSmooth step as well!
      calVars->add("ZeroBufferSmooth", HiVector(nlines, 0.0));
      ZbsHist.add("Debug::SkipModule invoked!");
    }

/////////////////////////////////////////////////////////////////////
// ZeroBufferFit
//  Compute second level of drift correction.  The high level noise
//  is removed from a modeled non-linear fit.
//
    procStep = "ZeroBufferFit module";
    HiHistory ZbfHist;
    hiconf.selectProfile("ZeroBufferFit");
    hiprof = hiconf.getMatrixProfile();
    ZbfHist.add("Profile["+ hiprof.Name()+"]");
    if (!SkipModule(hiprof) ) {
      ZeroBufferFit zbf(hiconf);

      calVars->add(hiconf.getProfileName(),
                   zbf.Normalize(zbf.Solve(calVars->get("ZeroBufferSmooth"))));
      ZbfHist = zbf.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        zbf.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nlines, 0.0));
      ZbfHist.add("Debug::SkipModule invoked!");
    }


 ////////////////////////////////////////////////////////////////////
 //  ZeroReverse
    procStep = "ZeroReverse module";
    hiconf.selectProfile("ZeroReverse");
    hiprof = hiconf.getMatrixProfile();
    HiHistory ZrHist;
    ZrHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      ZeroReverse zr(caldata, hiconf);
      calVars->add(hiconf.getProfileName(), zr.ref());
      ZrHist = zr.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        zr.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nsamps, 0.0));
      ZrHist.add("Debug::SkipModule invoked!");
    }

/////////////////////////////////////////////////////////////////
// ZeroDark removes dark current
//
    procStep = "ZeroDark module";
    hiconf.selectProfile("ZeroDark");
    hiprof =  hiconf.getMatrixProfile();
    HiHistory ZdHist;
    ZdHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      ZeroDark zd(hiconf);
      calVars->add(hiconf.getProfileName(), zd.ref());
      ZdHist = zd.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        zd.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nsamps, 0.0));
      ZdHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
// GainLineDrift correct for gain-based drift
//
    procStep = "GainLineDrift module";
    hiconf.selectProfile("GainLineDrift");
    hiprof = hiconf.getMatrixProfile();
    HiHistory GldHist;
    GldHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainLineDrift gld(hiconf);
      calVars->add(hiconf.getProfileName(), gld.ref());
      GldHist = gld.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        gld.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nlines, 1.0));
      GldHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
//  GainNonLinearity  Correct for non-linear gain
    procStep = "GainNonLinearity module";
    hiconf.selectProfile("GainNonLinearity");
    hiprof =  hiconf.getMatrixProfile();
    HiHistory GnlHist;
    GnlHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainNonLinearity gnl(hiconf);
      calVars->add(hiconf.getProfileName(), gnl.ref());
      GnlHist = gnl.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        gnl.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(1, 0.0));
      GnlHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
//  GainChannelNormalize  Correct for sample gain with the G matrix
    procStep = "GainChannelNormalize module";
    hiconf.selectProfile("GainChannelNormalize");
    hiprof =  hiconf.getMatrixProfile();
    HiHistory GcnHist;
    GcnHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainChannelNormalize gcn(hiconf);
      calVars->add(hiconf.getProfileName(), gcn.ref());
      GcnHist = gcn.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        gcn.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0));
      GcnHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
//  GainFlatField  Flat field correction with A matrix
    procStep = "GainFlatField module";
    hiconf.selectProfile("GainFlatField");
    hiprof =  hiconf.getMatrixProfile();
    HiHistory GffHist;
    GffHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainFlatField gff(hiconf);
      calVars->add(hiconf.getProfileName(), gff.ref());
      GffHist = gff.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        gff.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0));
      GffHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
// GainTemperature -  Temperature-dependant gain correction
    procStep = "GainTemperature module";
    hiconf.selectProfile("GainTemperature");
    hiprof =  hiconf.getMatrixProfile();
    HiHistory GtHist;
    GtHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainTemperature gt(hiconf);
      calVars->add(hiconf.getProfileName(), gt.ref());
      GtHist = gt.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        gt.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0));
      GtHist.add("Debug::SkipModule invoked!");
    }

////////////////////////////////////////////////////////////////////
//  GainUnitConversion converts to requested units
//
    procStep = "GainUnitConversion module";
    hiconf.selectProfile("GainUnitConversion");
    hiprof = hiconf.getMatrixProfile();
    HiHistory GucHist;
    GucHist.add("Profile["+ hiprof.Name()+"]");
    if ( !SkipModule(hiprof) ) {
      GainUnitConversion guc(hiconf, units);
      calVars->add(hiconf.getProfileName(), guc.ref());
      GucHist = guc.History();
      if ( hiprof.exists("DumpModuleFile") ) {
        guc.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof));
      }
    }
    else {
      calVars->add(hiconf.getProfileName(), HiVector(1,1.0));
      GucHist.add("Debug::SkipModule invoked!");
      GucHist.add("Units[Unknown]");
    }

    //  Reset the profile selection to default
    hiconf.selectProfile();

//----------------------------------------------------------------------
//
/////////////////////////////////////////////////////////////////////////
//  Call the processing function
    procStep = "calibration phase";
    p.StartProcess(calibrate);

    // Get the default profile for logging purposes
    hiprof = hiconf.getMatrixProfile();
    const QString conf_file = hiconf.filepath(conf);

    // Quitely dumps parameter history to alternative format file.  This
    // is completely controlled by the configuration file
    if ( hiprof.exists("DumpHistoryFile") ) {
      procStep = "logging/reporting phase";
      FileName hdump(hiconf.getMatrixSource("DumpHistoryFile",hiprof));
      QString hdumpFile = hdump.expanded();
      ofstream ofile(hdumpFile.toAscii().data(), ios::out);
      if (!ofile) {
        QString mess = "Unable to open/create history dump file " +
                      hdump.expanded();
        IException(IException::User, mess, _FILEINFO_).print();
      }
      else {
        ofile << "Program:  " << hical_program << endl;
        ofile << "RunTime:  " << hical_runtime << endl;
        ofile << "Version:  " << hical_version << endl;
        ofile << "Revision: " << hical_revision << endl << endl;

        ofile << "FROM:     " << hifrom->fileName() << endl;
        ofile << "TO:       " << ocube->fileName()  << endl;
        ofile << "CONF:     " << conf_file  << endl << endl;

        ofile << "/* " << hical_program << " application equation */\n"
              << "/* hdn = (idn - ZeroBufferFit(ZeroBufferSmooth) - ZeroReverse - ZeroDark) */\n"
              << "/* odn = hdn / GainLineDrift * GainNonLinearity * GainChannelNormalize */\n"
              << "/*           * GainFlatField  * GainTemperature / GainUnitConversion */\n\n";

        ofile << "****** PARAMETER GENERATION HISTORY *******" << endl;
        ofile << "\nZeroBufferSmooth   = " << ZbsHist << endl;
        ofile << "\nZeroBufferFit   = " << ZbfHist << endl;
        ofile << "\nZeroReverse   = " << ZrHist << endl;
        ofile << "\nZeroDark   = " << ZdHist << endl;
        ofile << "\nGainLineDrift   = " << GldHist << endl;
        ofile << "\nGainNonLinearity   = " << GnlHist << endl;
        ofile << "\nGainChannelNormalize = " << GcnHist << endl;
        ofile << "\nGainFlatField   = " << GffHist << endl;
        ofile << "\nGainTemperature   = " << GtHist << endl;
        ofile << "\nGainUnitConversion = " << GucHist << endl;

        ofile.close();
      }
    }

//  Ensure the RadiometricCalibration group is out there
    const QString rcalGroup("RadiometricCalibration");
    if (!ocube->hasGroup(rcalGroup)) {
      PvlGroup temp(rcalGroup);
      ocube->putGroup(temp);
    }

    PvlGroup &rcal = ocube->group(rcalGroup);
    rcal += PvlKeyword("Program", hical_program);
    rcal += PvlKeyword("RunTime", hical_runtime);
    rcal += PvlKeyword("Version",hical_version);
    rcal += PvlKeyword("Revision",hical_revision);

    PvlKeyword key("Conf", conf_file);
    key.addCommentWrapped("/* " + hical_program + " application equation */");
    key.addComment("/* hdn = idn - ZeroBufferFit(ZeroBufferSmooth) */");
    key.addComment("/*           - ZeroReverse - ZeroDark */");
    key.addComment("/* odn = hdn / GainLineDrift * GainNonLinearity */");
    key.addComment("/*           * GainChannelNormalize * GainFlatField */");
    key.addComment("/*           * GainTemperature / GainUnitConversion */");
    rcal += key;

    //  Record parameter generation history.  Controllable in configuration
    //  file.  Note this is optional because of a BUG!! in the ISIS label
    //  writer as this application was initially developed
    if ( IsEqual(ConfKey(hiprof,"LogParameterHistory",QString("TRUE")),"TRUE")) {
      rcal += ZbsHist.makekey("ZeroBufferSmooth");
      rcal += ZbfHist.makekey("ZeroBufferFit");
      rcal += ZrHist.makekey("ZeroReverse");
      rcal += ZdHist.makekey("ZeroDark");
      rcal += GldHist.makekey("GainLineDrift");
      rcal += GnlHist.makekey("GainNonLinearity");
      rcal += GcnHist.makekey("GainChannelNormalize");
      rcal += GffHist.makekey("GainFlatField");
      rcal += GtHist.makekey("GainTemperature");
      rcal += GucHist.makekey("GainUnitConversion");
    }

    p.EndProcess();
  }
  catch (IException &ie) {
    delete calVars;
    calVars = 0;
    QString mess = "Failed in " + procStep;
    throw IException(ie, IException::User, mess, _FILEINFO_);
  }

// Clean up parameters
  delete calVars;
  calVars = 0;
}
Пример #6
0
void IsisMain() {

  UserInterface &ui = Application::GetUserInterface();
  Process p;

  // Get the histogram
  Cube *icube = p.SetInputCube("FROM");

  double validMin = Isis::ValidMinimum;
  double validMax = Isis::ValidMaximum;

  if(ui.WasEntered("VALIDMIN")) {
    validMin = ui.GetDouble("VALIDMIN");
  }

  if(ui.WasEntered("VALIDMAX")) {
    validMax = ui.GetDouble("VALIDMAX");
  }
  
  // Set a global Pvl for storing results
  Pvl mainpvl;
  
  // Get the number of bands to process
  int bandcount = icube->bandCount();
  
  for (int i = 1; i <= bandcount; i++) {
    Histogram *stats = icube->histogram(i, validMin, validMax);

    // Construct a label with the results
    PvlGroup results("Results");  
    results += PvlKeyword("From", icube->fileName());
    results += PvlKeyword("Band", toString(icube->physicalBand(i)));
    if(stats->ValidPixels() != 0) {
      results += PvlKeyword("Average", toString(stats->Average()));
      results += PvlKeyword("StandardDeviation", toString(stats->StandardDeviation()));
      results += PvlKeyword("Variance", toString(stats->Variance()));
      // These statistics only worked on a histogram
      results += PvlKeyword("Median", toString(stats->Median()));
      results += PvlKeyword("Mode", toString(stats->Mode()));
      results += PvlKeyword("Skew", toString(stats->Skew()));
      results += PvlKeyword("Minimum", toString(stats->Minimum()));
      results += PvlKeyword("Maximum", toString(stats->Maximum()));
      results += PvlKeyword("Sum", toString(stats->Sum()));
    }
    results += PvlKeyword("TotalPixels", toString(stats->TotalPixels()));
    results += PvlKeyword("ValidPixels", toString(stats->ValidPixels()));
    results += PvlKeyword("OverValidMaximumPixels", toString(stats->OverRangePixels()));
    results += PvlKeyword("UnderValidMinimumPixels", toString(stats->UnderRangePixels()));
    results += PvlKeyword("NullPixels", toString(stats->NullPixels()));
    results += PvlKeyword("LisPixels", toString(stats->LisPixels()));
    results += PvlKeyword("LrsPixels", toString(stats->LrsPixels()));
    results += PvlKeyword("HisPixels", toString(stats->HisPixels()));
    results += PvlKeyword("HrsPixels", toString(stats->HrsPixels()));
    
    mainpvl.addGroup(results);
    
    delete stats;
    // Write the results to the log
    Application::Log(results);
  }
  
  // Write the results to the output file if the user specified one
  if(ui.WasEntered("TO")) {
    QString outFile = FileName(ui.GetFileName("TO")).expanded();
    bool exists = FileName(outFile).fileExists();
    bool append = ui.GetBoolean("APPEND");
    ofstream os;
    bool writeHeader = false;
    //write the results in the requested format.
    if(ui.GetString("FORMAT") == "PVL") {
      if(append) {
        mainpvl.append(outFile);
      }
      else {
        mainpvl.write(outFile);
      }
    }
    else {
      //if the format was not PVL, write out a flat file.
      if(append) {
        os.open(outFile.toAscii().data(), ios::app);
        if(!exists) {
          writeHeader = true;
        }
      }
      else {
        os.open(outFile.toAscii().data(), ios::out);
        writeHeader = true;
      }

      if(writeHeader) {
        for(int i = 0; i < mainpvl.group(0).keywords(); i++) {
          os << mainpvl.group(0)[i].name();
          if( i < mainpvl.group(0).keywords() - 1 ) {
            os << ",";
          }
        }
        os << endl;
      }
      
      for(int i = 0; i < mainpvl.groups(); i++) {
        for (int j = 0; j < mainpvl.group(i).keywords(); j++) {
          os << (QString)mainpvl.group(i)[j];
          if(j < mainpvl.group(i).keywords() - 1) {
            os << ",";
          }
        }
        os << endl;
      }
    }
  }
}
Пример #7
0
void IsisMain() {
  // We will be processing by line
  ProcessByBrick p;
  UserInterface &ui = Application::GetUserInterface();

  // Use the def file for filter constants
  Pvl uvvisDef("$clementine1/calibration/uvvis/uvvis.def");

  // Setup the input and output cubes
  Cube *icube = p.SetInputCube("FROM");

  Cube *dccube;
  if(ui.WasEntered("DCFILE")) {
    dccube = p.SetInputCube("DCFILE");
  }
  else {
    QString dcfileloc = "$clementine1/calibration/uvvis/";
    dcfileloc += "dark_5_15_96.cub";
    CubeAttributeInput cubeAtt;
    dccube = p.SetInputCube(dcfileloc, cubeAtt);
  }

  QString filter = (QString)(icube->group("BandBin"))["FilterName"];
  filter = filter.toLower();

  Cube *ffcube;
  if(ui.WasEntered("FFFILE")) {
    ffcube = p.SetInputCube("FFFILE");
  }
  else {
    // compute default fffile
    double compressRatio = (icube->group("Instrument"))["EncodingCompressionRatio"];

    // check to see if cube is compressed or uncompressed
    if(compressRatio == 1.0) {
      QString fffileLoc = "$clementine1/calibration/uvvis/";
      fffileLoc += "lu" + filter + "_uncomp_flat_long.cub";
      CubeAttributeInput cubeAtt;
      ffcube = p.SetInputCube(fffileLoc, cubeAtt);
    }
    else {
      QString fffileLoc = "$clementine1/calibration/uvvis/";
      fffileLoc += "lu" + filter + "_comp_flat_long.cub";
      CubeAttributeInput cubeAtt;
      ffcube = p.SetInputCube(fffileLoc, cubeAtt);
    }
  }

  Cube *ocube = p.SetOutputCube("TO");

  avgFF = uvvisDef.findGroup("Filter" + filter.toUpper())["AVGFF"];
  cr = uvvisDef.findGroup("Filter" + filter.toUpper())["CO"];
  gain = uvvisDef.findGroup(QString("GainModeID") + QString(icube->group("Instrument")["GainModeID"][0]))["GAIN"];

  useDcconst = ui.WasEntered("DCCONST");
  if(useDcconst) {
    dcconst = ui.GetDouble("DCCONST");
  }
  else {
    dcconst = 0.0;
  }

  conv = ui.GetBoolean("CONV");
  exposureDuration = icube->group("Instrument")["ExposureDuration"];
  offsetModeID = icube->group("Instrument")["OffsetModeID"];

  if(((QString)icube->group("Instrument")["FocalPlaneTemperature"]).compare("UNK") == 0) {
    //if FocalPlaneTemp is unknown set it to zero
    focalPlaneTemp = 0.0;
  }
  else {
    focalPlaneTemp = icube->group("Instrument")["FocalPlaneTemperature"];
  }

  Camera *cam = icube->camera();
  bool camSuccess = cam->SetImage(icube->sampleCount() / 2, icube->lineCount() / 2);

  if(!camSuccess) {
    throw IException(IException::Unknown, "Unable to calculate the Solar Distance for this cube.", _FILEINFO_);
  }

  dist = cam->SolarDistance();

  // If temp. correction set to true, or focal plane temp is zero then use temperature correction
  if(ui.GetBoolean("TCOR") || abs(focalPlaneTemp) <= DBL_EPSILON) {
    // Temperature correction requires the use of the mission phase
    //   (PRELAUNCH, EARTH, LUNAR) and the product ID.
    QString productID = (QString)(icube->group("Archive")["ProductID"]);
    QChar missionPhase = ((QString)((icube->group("Archive"))["MissionPhase"])).at(0);
    QString n1subQString(productID.mid(productID.indexOf('.') + 1, productID.length() - 1));
    QString n2subQString(productID.mid(4, productID.indexOf('.') - 5));
    int n1 = toInt(n1subQString);
    int n2 = toInt(n2subQString);
    int phase = 0;

    if(missionPhase == 'L') {
      phase = 0;
    }
    else if(missionPhase == 'E') {
      phase = 1;
    }
    else if(missionPhase == 'P') {
      phase = 2;
    }
    else {
      throw IException(IException::Unknown, "Invalid Mission Phase", _FILEINFO_);
    }

    // This formula makes the primary search critera the original product ID's extension,
    //   the secondary search criteria the mission phase and finally the numerical part of the
    //   original product ID.
    int imageID = (100000 * n1) + (10000 * phase) + n2;
    FixTemp(imageID);
  }

  if(focalPlaneTemp <= 0.0) {
    focalPlaneTemp = 272.5;
  }

  // Start the processing
  p.SetBrickSize(icube->sampleCount(), icube->lineCount(), 1);
  p.StartProcess(UvVisCal);

  // Add the radiometry group
  PvlGroup calgrp("Radiometry");
  calgrp += PvlKeyword("FlatFieldFile", ffcube->fileName());

  if(ui.GetString("DARKCURRENT").compare("DCFILE") == 0) {
    calgrp += PvlKeyword("DarkCurrentFile", dccube->fileName());
  }
  else {
    calgrp += PvlKeyword("DarkCurrentConstant", toString(dcconst));
  }

  calgrp += PvlKeyword("CorrectedFocalPlaneTemp", toString(focalPlaneTemp));
  calgrp += PvlKeyword("C1", toString(avgFF));
  calgrp += PvlKeyword("C2", toString(C2));
  calgrp += PvlKeyword("C3", toString(C3));
  calgrp += PvlKeyword("C4", toString(C4));
  calgrp += PvlKeyword("C5", toString(C5));
  calgrp += PvlKeyword("CR", toString(cr));
  calgrp += PvlKeyword("FrameTransferTimePerRow", toString(cr));
  calgrp += PvlKeyword("Gain", toString(gain));
  calgrp += PvlKeyword("CorrectedExposureDuration", toString(correctedExposureDuration));
  calgrp += PvlKeyword("ConvertToRadiance", toString(conv));

  calgrp += PvlKeyword("ACO", toString(ACO));
  calgrp += PvlKeyword("BCO", toString(BCO));
  calgrp += PvlKeyword("CCO", toString(CCO));
  calgrp += PvlKeyword("DCO", toString(DCO));

  ocube->putGroup(calgrp);
  p.EndProcess();
}
Пример #8
0
void IsisMain() {
  // We will be processing by line
  ProcessByLine p;

  // Setup the input and make sure it is a mariner10 file
  UserInterface & ui = Application::GetUserInterface();

  Isis::Pvl lab(ui.GetFileName("FROM"));
  Isis::PvlGroup & inst = lab.findGroup("Instrument", Pvl::Traverse);

  QString mission = inst["SpacecraftName"];
  if (mission != "Mariner_10") {
    string msg = "This is not a Mariner 10 image.  Mar10cal requires a Mariner 10 image.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  Cube * icube = p.SetInputCube("FROM", OneBand);

  // If it is already calibrated then complain
  if (icube->hasGroup("Radiometry")) {
    QString msg = "This Mariner 10 image [" + icube->fileName() + "] has "
                  "already been radiometrically calibrated";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  // Get label parameters we will need for calibration equation
  QString instId = inst["InstrumentId"];
  QString camera = instId.mid(instId.size()-1);

  QString filter = (QString)(icube->group("BandBin"))["FilterName"];
  filter = filter.toUpper().mid(0,3);

  QString target = inst["TargetName"];

  iTime startTime((QString) inst["StartTime"]);

  double exposure = inst["ExposureDuration"];
  double exposureOffset = 0.0;
  if (ui.WasEntered("EXPOFF")) {
    exposureOffset = ui.GetDouble("EXPOFF");
  }
  else {
    if (camera == "A") {
      exposureOffset = 0.316;
    }
    else if (camera == "B") {
      exposureOffset = 3.060;
    }
    else {
      QString msg = "Camera [" + camera + "] is not supported.";
      throw IException(IException::User, msg, _FILEINFO_);
    }
  }
  correctedExp = exposure + exposureOffset;

  Cube * dcCube;
  if (ui.WasEntered ("DCCUBE") ) {
    dcCube = p.SetInputCube("DCCUBE");
  }
  else {
    //  Mercury Dark current
    //   ??? NOTE:  Need to find Mark's dc for venus and moon ????
    QString dcFile("$mariner10/calibration/mariner_10_" + camera +
                  "_dc.cub");
    CubeAttributeInput cubeAtt;
    dcCube = p.SetInputCube(dcFile, cubeAtt);
  }


  //  Open blemish removal file
  Cube * blemCube = 0;
  useBlem = (ui.GetBoolean("BLEMMASK")) ? true : false;
  if (useBlem) {
    QString blemFile("$mariner10/calibration/mariner_10_blem_" + camera + ".cub");
    CubeAttributeInput cubeAtt;
    blemCube = p.SetInputCube(blemFile, cubeAtt);
  }

  if (filter == "FAB" || filter == "WAF") {
    QString msg = "Filter type [" + filter + "] is not supported at this time.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  if (ui.WasEntered ("COEFCUBE")) {
    coCube.open(ui.GetFileName("COEFCUBE"));
  }
  else {
    FileName coFile("$mariner10/calibration/mariner_10_" + filter + "_" +
        camera + "_coef.cub");
    coCube.open(coFile.expanded());
  }
  coef = new Brick(icube->sampleCount(), 1, 6, coCube.pixelType());

  if (ui.WasEntered("ABSCOEF")) {
    absCoef = ui.GetDouble("ABSCOEF");
  }
  else {
    if (camera == "A") {
      absCoef = 16.0;
    }
    else if (camera == "B") {
      absCoef = 750.0;
    }
    else {
      QString msg = "Camera [" + camera + "] is not supported.";
      throw IException(IException::User, msg, _FILEINFO_);
    }
  }

  mask = ui.GetBoolean("MASK");
  xparm = ui.GetDouble("XPARM");

  // Get the distance between Mars and the Sun at the given time in
  // Astronomical Units (AU)
  Camera * cam = icube->camera();
  bool camSuccess = cam->SetImage(icube->sampleCount()/2,icube->lineCount()/2);
  if (!camSuccess) {
    throw IException(IException::Unknown,
        "Unable to calculate the Solar Distance on [" +
        icube->fileName() + "]", _FILEINFO_);
  }
  sunDist = cam->SolarDistance();

  // Setup the output cube
  Cube  *ocube = p.SetOutputCube("TO");

  // Add the radiometry group
  PvlGroup calgrp("Radiometry");

  calgrp += PvlKeyword("DarkCurrentCube", dcCube->fileName());
  if (useBlem) {
    calgrp += PvlKeyword("BlemishRemovalCube", blemCube->fileName());
  }
  calgrp += PvlKeyword("CoefficientCube", coCube.fileName());
  calgrp += PvlKeyword("AbsoluteCoefficient", toString(absCoef));

  ocube->putGroup(calgrp);

  // Start the line-by-line calibration sequence
  p.StartProcess(Mar10Cal);
  p.EndProcess();
}
Пример #9
0
// Main moccal routine
void IsisMain() {
  // We will be processing by line
  ProcessByLine p;

  // Setup the input and make sure it is a ctx file
  UserInterface &ui = Application::GetUserInterface();

  Isis::Pvl lab(ui.GetFileName("FROM"));
  Isis::PvlGroup &inst =
    lab.findGroup("Instrument", Pvl::Traverse);

  QString instId = inst["InstrumentId"];
  if(instId != "CTX") {
    QString msg = "This is not a CTX image.  Ctxcal requires a CTX image.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  Cube *icube = p.SetInputCube("FROM", OneBand);

  Cube flatFile;
  if(ui.WasEntered("FLATFILE")) {
    flatFile.open(ui.GetFileName("FLATFILE"));
  }
  else {
    FileName flat = FileName("$mro/calibration/ctxFlat_????.cub").highestVersion();
    flatFile.open(flat.expanded());
  }
  flat = new Brick(5000, 1, 1, flatFile.pixelType());
  flat->SetBasePosition(1, 1, 1);
  flatFile.read(*flat);

  // If it is already calibrated then complain
  if(icube->hasGroup("Radiometry")) {
    QString msg = "The CTX image [" + icube->fileName() + "] has already "
                 "been radiometrically calibrated";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  // Get label parameters we will need for calibration equation
  iTime startTime((QString) inst["StartTime"]);
  double etStart = startTime.Et();

  //  Read exposure and convert to milliseconds
  exposure = inst["LineExposureDuration"];
  //exposure *= 1000.;

  sum = inst["SpatialSumming"];
  //  If firstSamp > 0, adjust by 38 to account for prefix pixels.
  firstSamp = inst["SampleFirstPixel"];
  if(firstSamp > 0) firstSamp -= 38;

  //  Read dark current info, if no dc exit?
  Table dcTable("Ctx Prefix Dark Pixels");
  icube->read(dcTable);
  //  TODO::  make sure dc records match cube nlines.

  //  If summing mode = 1 , average odd & even dc pixels separately for
  //  a & b channels.
  //  If summing mode != 1, average all dc pixels and use for both


  for(int rec = 0; rec < dcTable.Records(); rec++) {
    vector<int> darks = dcTable[rec]["DarkPixels"];

    bool aChannel = true;
    double dcASum = 0.;
    double dcBSum = 0.;
    int dcACount = 0;
    int dcBCount = 0;

    double dcSum = 0;
    int dcCount = 0;

    for(int i = 0; i < (int)darks.size(); i++) {

      if(sum == 1) {
        if(aChannel == true) {
          dcASum += (double)darks.at(i);
          dcACount++;
        }
        else {
          dcBSum += (double)darks.at(i);
          dcBCount++;
        }
        aChannel = !aChannel;
      }
      else if(sum > 1) {
        dcSum += (double)darks.at(i);
        dcCount ++;
      }
    }
    if(sum == 1) {
      dcA.push_back(dcASum / (double)dcACount);
      dcB.push_back(dcBSum / (double)dcBCount);
    }
    else {
      dc.push_back(dcSum / (double)dcCount);
    }
  }

  // See if the user wants counts/ms or i/f
  //    iof = conversion factor from counts/ms to i/f
  bool convertIOF = ui.GetBoolean("IOF");
  if(convertIOF) {
    // Get the distance between Mars and the Sun at the given time in
    // Astronomical Units (AU)
    QString bspKernel = p.MissionData("base", "/kernels/spk/de???.bsp", true);
    furnsh_c(bspKernel.toAscii().data());
    QString pckKernel = p.MissionData("base", "/kernels/pck/pck?????.tpc", true);
    furnsh_c(pckKernel.toAscii().data());
    double sunpos[6], lt;
    spkezr_c("sun", etStart, "iau_mars", "LT+S", "mars", sunpos, &lt);
    double dist1 = vnorm_c(sunpos);
    unload_c(bspKernel.toAscii().data());
    unload_c(pckKernel.toAscii().data());

    double dist = 2.07E8;
    double w0 = 3660.5;
    double w1 = w0 * ((dist * dist) / (dist1 * dist1));
    if(exposure *w1 == 0.0) {
      QString msg = icube->fileName() + ": exposure or w1 has value of 0.0 ";
      throw IException(IException::User, msg, _FILEINFO_);
    }
    iof = 1.0 / (exposure * w1);
  }
  else {
    iof = 1.0;
  }

  // Setup the output cube
  Cube *ocube = p.SetOutputCube("TO");

  // Add the radiometry group
  PvlGroup calgrp("Radiometry");

  calgrp += PvlKeyword("FlatFile", flatFile.fileName());
  calgrp += PvlKeyword("iof", toString(iof));


  ocube->putGroup(calgrp);

  // Start the line-by-line calibration sequence
  p.StartProcess(Calibrate);
  p.EndProcess();

}
Пример #10
0
void IsisMain () {
  ResetGlobals();
  UserInterface &ui = Application::GetUserInterface();

  ProcessByBrick p;
  Cube *icube = p.SetInputCube("FROM");

  // Make sure it is a WAC cube
  Isis::PvlGroup &inst = icube->label()->findGroup("Instrument", Pvl::Traverse);
  QString instId = (QString) inst["InstrumentId"];
  instId = instId.toUpper();
  if (instId != "WAC-VIS" && instId != "WAC-UV") {
    QString msg = "This program is intended for use on LROC WAC images only. [";
    msg += icube->fileName() + "] does not appear to be a WAC image.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  // And check if it has already run through calibration
  if (icube->label()->findObject("IsisCube").hasGroup("Radiometry")) {
    QString msg = "This image has already been calibrated";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  if (icube->label()->findObject("IsisCube").hasGroup("AlphaCube")) {
    QString msg = "This application can not be run on any image that has been geometrically transformed (i.e. scaled, rotated, sheared, or reflected) or cropped.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  g_dark = ui.GetBoolean("DARK");
  g_flatfield = ui.GetBoolean("FLATFIELD");
  g_radiometric = ui.GetBoolean("RADIOMETRIC");
  g_iof = (ui.GetString("RADIOMETRICTYPE") == "IOF");
  g_specpix = ui.GetBoolean("SPECIALPIXELS");
  g_temprature = ui.GetBoolean("TEMPERATURE");

  // Determine the dark/flat files to use
  QString offset = (QString) inst["BackgroundOffset"];
  QString mode = (QString) inst["Mode"];
  QString instModeId = (QString) inst["InstrumentModeId"];
  instModeId = instModeId.toUpper();

  if (instModeId == "COLOR" && (QString) inst["InstrumentId"] == "WAC-UV")
    instModeId = "UV";
  else if (instModeId == "VIS")
    instModeId = "COLOR";

  g_startTemperature = (double) inst["BeginTemperatureFpa"];
  g_endTemperature = (double) inst["EndTemperatureFpa"];

  g_numFrames = (int) inst["NumFramelets"];

  vector<QString> darkFiles;
  ui.GetAsString("DARKFILE", darkFiles);
  QString flatFile = ui.GetAsString("FLATFIELDFILE");
  QString radFile = ui.GetAsString("RADIOMETRICFILE");
  QString specpixFile = ui.GetAsString("SPECIALPIXELSFILE");
  QString tempFile = ui.GetAsString("TEMPERATUREFILE");

  // Figure out which bands are input
  for (int i = 1; i <= icube->bandCount(); i++) {
    g_bands.push_back(icube->physicalBand(i));
  }

  Isis::PvlGroup &bandBin = icube->label()->findGroup("BandBin", Pvl::Traverse);
  QString filter = (QString) bandBin["Center"][0];
  QString filterNum = (QString) bandBin["FilterNumber"][0];
  //We have to pay special attention incase we are passed a 
  //single band image that has been "exploded" from a multiband wac
  if (instModeId == "COLOR" && g_bands.size() == 1)
   g_bands[0] = (toInt(filterNum) -2);
  else if (instModeId == "UV" && g_bands.size() == 1)
   g_bands[0] = (toInt(filterNum));

  if (g_dark) {
    if (darkFiles.size() == 0 || darkFiles[0] =="Default" || darkFiles[0].length() == 0) {
      darkFiles.resize(2);
      double temp = (double) inst["MiddleTemperatureFpa"];
      double time = iTime(inst["StartTime"][0]).Et();
      QString darkFile = "$lro/calibration/wac_darks/WAC_" + instModeId;
      if (instModeId == "BW")
        darkFile += "_" + filter + "_Mode" + mode;
      darkFile += "_Offset" + offset + "_*C_*T_Dark.????.cub";
      GetDark (darkFile, temp, time, g_darkCube1, g_darkCube2, g_temp1, g_temp2, darkFiles[0], darkFiles[1]);
    }
    else if (darkFiles.size() == 1) {
      CopyCubeIntoBuffer(darkFiles[0], g_darkCube1);
      g_temp1 = 0.0;
      g_darkCube2 = new Buffer(*g_darkCube1);
      g_temp2 = g_temp1;
    }
    else {
      CopyCubeIntoBuffer(darkFiles[0], g_darkCube1);
      int index = darkFiles[0].lastIndexOf("_");
      g_temp1 = IString(darkFiles[0].mid( darkFiles[0].lastIndexOf("_", index-1), index)).ToDouble();
      CopyCubeIntoBuffer(darkFiles[1], g_darkCube2);
      index = darkFiles[1].lastIndexOf("_");
      g_temp2 = IString(darkFiles[1].mid( darkFiles[1].lastIndexOf("_", index-1), index)).ToDouble();
    }
  }

  if (g_flatfield) {
    if (flatFile.toLower() == "default" || flatFile.length() == 0) {
      flatFile = "$lro/calibration/wac_flats/WAC_" + instModeId;
      if (instModeId == "BW")
        flatFile += "_" + filter + "_Mode" + mode;
      flatFile += "_Flatfield.????.cub";
    }
    CopyCubeIntoBuffer(flatFile, g_flatCube);

    // invert the flat-field data here so we don't have to divide for every pixel of the wac
    for (int i = 0; i < g_flatCube->size(); i++) {
      (*g_flatCube)[i] = 1.0 / (*g_flatCube)[i];
    }
  }

  PvlKeyword responsivity;

  if (g_radiometric) {

    Isis::PvlKeyword &bands = icube->label()->findGroup("BandBin", Pvl::Traverse).findKeyword("FilterNumber");

    if (radFile.toLower() == "default" || radFile.length() == 0)
      radFile = "$lro/calibration/WAC_RadiometricResponsivity.????.pvl";

    FileName radFileName(radFile);
    if (radFileName.isVersioned())
      radFileName = radFileName.highestVersion();
    if (!radFileName.fileExists()) {
      QString msg = radFile + " does not exist.";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    Pvl radPvl(radFileName.expanded());

    if (g_iof) {
      responsivity = radPvl["IOF"];

      for (int i = 0; i < bands.size(); i++)
        g_iofResponsivity.push_back(toDouble(responsivity[toInt(bands[i]) - 1]));

      try {
        iTime startTime((QString) inst["StartTime"]);
        double etStart = startTime.Et();
        // Get the distance between the Moon and the Sun at the given time in
        // Astronomical Units (AU)
        QString bspKernel1 = p.MissionData("lro", "/kernels/tspk/moon_pa_de421_1900-2050.bpc", false);
        QString bspKernel2 = p.MissionData("lro", "/kernels/tspk/de421.bsp", false);
        furnsh_c(bspKernel1.toAscii().data());
        furnsh_c(bspKernel2.toAscii().data());
        QString pckKernel1 = p.MissionData("base", "/kernels/pck/pck?????.tpc", true);
        QString pckKernel2 = p.MissionData("lro", "/kernels/pck/moon_080317.tf", false);
        QString pckKernel3 = p.MissionData("lro", "/kernels/pck/moon_assoc_me.tf", false);
        furnsh_c(pckKernel1.toAscii().data());
        furnsh_c(pckKernel2.toAscii().data());
        furnsh_c(pckKernel3.toAscii().data());
        double sunpos[6], lt;
        spkezr_c("sun", etStart, "MOON_ME", "LT+S", "MOON", sunpos, &lt);
        g_solarDistance = vnorm_c(sunpos) / KM_PER_AU;
        unload_c(bspKernel1.toAscii().data());
        unload_c(bspKernel2.toAscii().data());
        unload_c(pckKernel1.toAscii().data());
        unload_c(pckKernel2.toAscii().data());
        unload_c(pckKernel3.toAscii().data());
      }
      catch (IException &e) {
        QString msg = "Can not find necessary SPICE kernels for converting to IOF";
        throw IException(e, IException::User, msg, _FILEINFO_);
      }
    }
    else {
      responsivity = radPvl["Radiance"];
      for (int i = 0; i < bands.size(); i++)
        g_radianceResponsivity.push_back(toDouble(responsivity[toInt(bands[i]) - 1]));
    }
  }

  if (g_specpix) {
    if (specpixFile.toLower() == "default" || specpixFile.length() == 0) {
      specpixFile = "$lro/calibration/wac_masks/WAC_" + instModeId;
      double temp = (double) inst["MiddleTemperatureFpa"];
      if (instModeId == "BW")
        specpixFile += "_" + filter + "_Mode" + mode;
      specpixFile += "_*C_SpecialPixels.????.cub";
      GetMask(specpixFile, temp, g_specpixCube);
    }
    else
      CopyCubeIntoBuffer(specpixFile, g_specpixCube);
  }

  if (g_temprature) {
    if (tempFile.toLower() == "default" || tempFile.length() == 0)
      tempFile = "$lro/calibration/WAC_TempratureConstants.????.pvl";

    FileName tempFileName(tempFile);
    if (tempFileName.isVersioned())
      tempFileName = tempFileName.highestVersion();
    if (!tempFileName.fileExists()) {
      QString msg = tempFile + " does not exist.";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    Isis::PvlKeyword &bands = icube->label()->findGroup("BandBin", Pvl::Traverse).findKeyword("FilterNumber");
    Pvl tempPvl(tempFileName.expanded());
    for (int b = 0; b < bands.size(); b++){
        g_TempratureConstants[g_bands[b]][0]=toDouble(tempPvl[bands[b]][0]);
        g_TempratureConstants[g_bands[b]][1]=toDouble(tempPvl[bands[b]][1]);
    }
  }

  if (instModeId == "BW") {
    if (mode == "1" || mode == "0")
      p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size()));
    else
      p.SetBrickSize(POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size()));
  }
  else if (instModeId == "COLOR") {
    p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(COLOR_BANDS, g_bands.size()));
  }
  else if (instModeId == "UV") {
    p.SetBrickSize(UV_SAMPLES, UV_LINES, (int)min(UV_BANDS, g_bands.size()));
  }

  g_exposure = inst["ExposureDuration"];

  Cube *ocube = p.SetOutputCube("TO");
  p.ProcessCube(Calibrate, false);

  // Add an output group with the appropriate information
  PvlGroup calgrp("Radiometry");
  if (g_dark) {
    PvlKeyword darks("DarkFiles");
    darks.addValue(darkFiles[0]);
    if (darkFiles.size() > 1)
      darks.addValue(darkFiles[1]);
    calgrp += darks;
  }
  if (g_flatfield)
    calgrp += PvlKeyword("FlatFile", flatFile);
  if (g_radiometric) {
    PvlKeyword vals("ResponsivityValues");
    if (g_iof) {
      calgrp += PvlKeyword("RadiometricType", "IOF");
      for (unsigned int i=0; i< g_iofResponsivity.size(); i++)
        vals.addValue(toString(g_iofResponsivity[i]));
    }
    else {
      calgrp += PvlKeyword("RadiometricType", "AbsoluteRadiance");
      for (unsigned int i=0; i< g_radianceResponsivity.size(); i++)
        vals.addValue(toString(g_radianceResponsivity[i]));
    }
    calgrp += vals;
    calgrp += PvlKeyword("SolarDistance", toString(g_solarDistance));
  }
  if (g_specpix)
    calgrp += PvlKeyword("SpecialPixelsFile", specpixFile);
  ocube->putGroup(calgrp);

}
Пример #11
0
// Main moccal routine
void IsisMain() {
  // We will be processing by line
  ProcessByLine p;

  // Setup the input and make sure it is a moc file
  UserInterface &ui = Application::GetUserInterface();
  Cube *icube = p.SetInputCube("FROM", OneBand);
  gbl::moc = new MocLabels(ui.GetFileName("FROM"));

  // If it is already calibrated then complain
  if(icube->hasGroup("Radiometry")) {
    QString msg = "The MOC image [" + icube->fileName() + "] has already "
                 "been radiometrically calibrated";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  // Get label parameters we will need for calibration equation
  gbl::a = gbl::moc->Gain();
  gbl::off = gbl::moc->Offset();
  gbl::ex = gbl::moc->ExposureDuration();

  // Get the starting, ending, and activation et's.  For now, the
  // activation et is set to the largest double precision value.  If
  // The narrow angle B detectors ever get activated then the value
  // will need to be changed to the appropriate et
  iTime startTime(gbl::moc->StartTime());
  double etStart = startTime.Et();
  double etNABActivation = DBL_MAX;

  // Open the calibration kernel that contains constants for each camera
  // and internalize it in a pvl object
  QString calKernelFile;
  if(ui.WasEntered("CALKERNEL")) {
    calKernelFile = ui.GetFileName("CALKERNEL");
  }
  else {
    calKernelFile = p.MissionData("mgs", "/calibration/moccal.ker.???", true);
  }
  Pvl calKernel(calKernelFile);

  // Point to the right group of camera parameters
  QString camera;
  if(gbl::moc->WideAngleRed()) {
    camera = "WideAngleRed";
  }
  else if(gbl::moc->WideAngleBlue()) {
    camera = "WideAngleBlue";
  }
  else if(etStart > etNABActivation) {
    camera = "NarrowAngleB";
  }
  else {
    camera = "NarrowAngleA";
  }
  PvlGroup &calCamera = calKernel.findGroup(camera);

  // Get the camera specific calibration parameters from the kernel file
  // and load detector coefficients (gain/offsets at each pixel)
  gbl::z = calCamera["Z"];
  gbl::dc = calCamera["DC"];
  gbl::g = calCamera["G"];
  gbl::w0 = calCamera["W0"];
  QString coefFile = calCamera["CoefFile"];
  gbl::LoadCoefficients(coefFile, icube->sampleCount());

#if 0
  // Override with these with any user selected parameters
  if(ui.WasEntered("Z")) gbl::z = ui.GetDouble("Z");
  if(ui.WasEntered("DC")) gbl::dc = ui.GetDouble("DC");
  if(ui.WasEntered("G")) gbl::g = ui.GetDouble("G");
  if(ui.WasEntered("W0")) gbl::w0 = ui.GetDouble("W0");
#endif
  gbl::nullWago = ui.GetBoolean("NULLWAGO");

  // Get the distance between Mars and the Sun at the given time in
  // Astronomical Units (AU)
  QString bspKernel = p.MissionData("base", "/kernels/spk/de???.bsp", true);
  furnsh_c(bspKernel.toAscii().data());
  QString pckKernel = p.MissionData("base", "/kernels/pck/pck?????.tpc", true);
  furnsh_c(pckKernel.toAscii().data());
  double sunpos[6], lt;
  spkezr_c("sun", etStart, "iau_mars", "LT+S", "mars", sunpos, &lt);
  double dist = vnorm_c(sunpos);
  double kmPerAU = 1.4959787066E8;
  double sunAU = dist / kmPerAU;
  unload_c(bspKernel.toAscii().data());
  unload_c(pckKernel.toAscii().data());

  // See if the user wants counts/ms or i/f but if w0 is 0 then
  // we must go to counts/ms
  //    iof = conversion factor from counts/ms to i/f
  bool convertIOF = ui.GetBoolean("IOF") && (gbl::w0 > 0.0);
  if(convertIOF) {
    gbl::iof = sunAU * sunAU / gbl::w0;
  }
  else {
    gbl::iof = 1.0;
  }

  // Setup the output cube
  Cube *ocube = p.SetOutputCube("TO");

  // Add the radiometry group
  PvlGroup calgrp("Radiometry");
  calgrp += PvlKeyword("CalibrationKernel", calKernelFile);
  calgrp += PvlKeyword("CoefficientFile", coefFile);

  calgrp += PvlKeyword("a", toString(gbl::a));
  calgrp["a"].addComment("Radiometric equation in moccal");
  calgrp["a"].addComment("r = (pixel - z + off) / a - g / ex - dc");
  calgrp += PvlKeyword("off", toString(gbl::off));
  calgrp += PvlKeyword("ex", toString(gbl::ex));
  calgrp += PvlKeyword("z", toString(gbl::z));
  calgrp += PvlKeyword("dc", toString(gbl::dc));
  calgrp += PvlKeyword("g", toString(gbl::g));

  calgrp += PvlKeyword("w0", toString(gbl::w0));
  calgrp["w0"].addComment("Reflectance = r * iof, where iof = (s * s) / w0");
  calgrp += PvlKeyword("s", toString(sunAU));
  calgrp += PvlKeyword("iof", toString(gbl::iof));

  ocube->putGroup(calgrp);

  // Start the line-by-line calibration sequence
  p.StartProcess(gbl::Calibrate);
  p.EndProcess();

  // Now go fix errors around the wago changes
  gbl::FixWagoLines(ui.GetFileName("TO"));

  // Cleanup
  gbl::pixelGain.clear();
  gbl::pixelOffset.clear();
  gbl::inLineAvg.clear();
  gbl::outLineAvg.clear();
}
Пример #12
0
/** The ISIS smtk main application */
void IsisMain() {
  UserInterface &ui = Application::GetUserInterface();

  // Open the first cube.  It is the left hand image.
  Cube lhImage;
  CubeAttributeInput &attLeft = ui.GetInputAttribute("FROM");
  vector<QString> bandLeft = attLeft.bands();
  lhImage.setVirtualBands(bandLeft);
  lhImage.open(ui.GetFileName("FROM"),"r");

  // Open the second cube, it is geomertricallty altered.  We will be matching the
  // first to this one by attempting to compute a sample/line offsets
  Cube rhImage;
  CubeAttributeInput &attRight = ui.GetInputAttribute("MATCH");
  vector<QString> bandRight = attRight.bands();
  rhImage.setVirtualBands(bandRight);
  rhImage.open(ui.GetFileName("MATCH"),"r");

  // Ensure only single bands
  if (lhImage.bandCount() != 1 || rhImage.bandCount() != 1) {
    QString msg = "Input Cubes must have only one band!";
    throw IException(IException::User,msg,_FILEINFO_);
  }

  //  Both images must have a Camera and can also have a Projection.  We will
  //  only deal with a Camera, however as a projected, non-mosaicked image
  //  uses a Projection internal to the Camera object.
  Camera *lhCamera = NULL;
  Camera *rhCamera = NULL;
  try {
    lhCamera = lhImage.camera();
    rhCamera = rhImage.camera();
  }
  catch (IException &ie) {
    QString msg = "Both input images must have a camera";
    throw IException(ie, IException::User, msg, _FILEINFO_);
  }

  //  Since we are generating a DEM, we must turn off any existing
  //  DEM that may have been initialized with spiceinit.
  lhCamera->IgnoreElevationModel(true);
  rhCamera->IgnoreElevationModel(true);

  // Get serial number
  QString serialLeft = SerialNumber::Compose(lhImage, true);
  QString serialRight = SerialNumber::Compose(rhImage, true);

//  This still precludes band to band registrations.
  if (serialLeft == serialRight) {
    QString sLeft = FileName(lhImage.fileName()).name();
    QString sRight = FileName(rhImage.fileName()).name();
    if (sLeft == sRight) {
      QString msg = "Cube Serial Numbers must be unique - FROM=" + serialLeft +
                   ", MATCH=" + serialRight;
      throw IException(IException::User,msg,_FILEINFO_);
    }
    serialLeft = sLeft;
    serialRight = sRight;
  }

  Progress prog;
  prog.SetText("Finding Initial Seeds");

  int nl = lhImage.lineCount();
  int ns = lhImage.sampleCount();
  BigInt numAttemptedInitialPoints = 0;

  //  Declare Gruen matcher
  SmtkMatcher matcher(ui.GetFileName("REGDEF"), &lhImage, &rhImage);

  // Get line/sample linc/sinc parameters
  int space   = ui.GetInteger("SPACE");
  int linc (space), sinc(space);

  // Do we have a seed points from a control net file?
  bool useseed = ui.WasEntered("CNET");

  // Base points on an input cnet
  SmtkQStack gstack;
  double lastEigen(0.0);
  if (useseed) {
    ControlNet cnet(ui.GetFileName("CNET"));
    prog.SetMaximumSteps(cnet.GetNumPoints());
    prog.CheckStatus();

    gstack.reserve(cnet.GetNumPoints());

    for (int cpIndex = 0; cpIndex < cnet.GetNumPoints(); cpIndex ++) {
      ControlPoint *cp = cnet.GetPoint(cpIndex);

      if (!cp->IsIgnored()) {
        ControlMeasure *cmLeft(0), *cmRight(0);
        for(int cmIndex = 0; cmIndex < cp->GetNumMeasures(); cmIndex ++) {
          ControlMeasure *cm = cp->GetMeasure(cmIndex);
          if (!cm->IsIgnored()) {
            if (cm->GetCubeSerialNumber() == serialLeft)
              cmLeft = cp->GetMeasure(cmIndex);
            if (cm->GetCubeSerialNumber() == serialRight)
              cmRight = cp->GetMeasure(cmIndex);
          }
        }

        //  If we have both left and right images in the control point, save it
        if ( (cmLeft != 0) && (cmRight != 0) ) {
          Coordinate left = Coordinate(cmLeft->GetLine(), cmLeft->GetSample());
          Coordinate right = Coordinate(cmRight->GetLine(), cmRight->GetSample());
          SmtkPoint spnt = matcher.Create(left, right);

          // Insert the point (unregistered)
          if ( spnt.isValid() ) {
            int line = (int) cmLeft->GetLine();
            int samp = (int) cmLeft->GetSample();
            matcher.isValid(spnt);
            gstack.insert(qMakePair(line, samp), spnt);
            lastEigen = spnt.GoodnessOfFit();
          }
        }
      }

      prog.CheckStatus();
    }
  }
  else {
  // We want to create a grid of control points that is N rows by M columns.

    int rows = (lhImage.lineCount() + linc - 1)/linc;
    int cols = (lhImage.sampleCount() + sinc - 1)/sinc;

    prog.SetMaximumSteps(rows * cols);
    prog.CheckStatus();

    // First pass stack and eigen value statistics
    SmtkQStack fpass;
    fpass.reserve(rows * cols);
    Statistics temp_mev;

    // Loop through grid of points and get statistics to compute
    // initial set of points
    for (int line = linc / 2 + 1; line < nl; line += linc) {
      for (int samp = sinc / 2 + 1 ; samp < ns; samp += sinc) {
        numAttemptedInitialPoints ++;
        SmtkPoint spnt = matcher.Register(Coordinate(line,samp));
        if ( spnt.isValid() ) {
          matcher.isValid(spnt);
          fpass.insert(qMakePair(line, samp), spnt);
          temp_mev.AddData(spnt.GoodnessOfFit());
        }
        prog.CheckStatus();
      }
    }

    //  Now select a subset of fpass points as the seed points
    cout << "Number of Potential Seed Points: " << fpass.size() << "\n";
    cout << "Min / Max Eigenvalues Matched: " << temp_mev.Minimum() << ", "
         << temp_mev.Maximum() << "\n";

    // How many seed points are requested
    double nseed = ui.GetDouble("NSEED");
    int inseed;
    if (nseed >= 1.0) inseed = (int) nseed;
    else if (nseed > 0.0) inseed = (int) (nseed * (double) (fpass.size()));
    else inseed = (int) ((double) (fpass.size()) * 0.05);

    double seedsample = ui.GetDouble("SEEDSAMPLE");

    // Generate a new stack
    gstack.reserve(inseed);
    while ((gstack.size() < inseed) && (!fpass.isEmpty() )) {
      SmtkQStack::iterator bestm;
      if (seedsample <= 0.0) {
        bestm = matcher.FindSmallestEV(fpass);
      }
      else {
        bestm = matcher.FindExpDistEV(fpass, seedsample, temp_mev.Minimum(),
                                      temp_mev.Maximum());
      }

      //  Add point to stack
      if (bestm != fpass.end()) {
        Coordinate right = bestm.value().getRight();
        matcher.isValid(bestm.value());
        gstack.insert(bestm.key(), bestm.value());
        lastEigen = bestm.value().GoodnessOfFit();
        fpass.erase(bestm);
      }
    }

    // If a user wants to see the seed network, write it out here
    if (ui.WasEntered("OSEEDNET")) {
      WriteCnet(ui.GetFileName("OSEEDNET"), gstack,
                lhCamera->target()->name(), serialLeft, serialRight);
    }

  }

  ///////////////////////////////////////////////////////////////////////
  // All done with seed points.  Sanity check ensures we actually found
  // some.
  ///////////////////////////////////////////////////////////////////////
  if (gstack.size() <= 0) {
    QString msg = "No seed points found - may need to check Gruen parameters.";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  //  Report seed point status
  if (!useseed) {
    cout << "Number of Seed Points used: " << gstack.size() << "\n";
    cout << "EV of last Seed Point:      " << lastEigen << "\n";
  }
  else {
    cout << "Number of Manual Seed Points:   " << gstack.size() << "\n";
  }

  // Use seed points (in stack) to grow
  SmtkQStack bmf;
  bmf.reserve(gstack.size());  // Probably need much more but for starters...

  BigInt numOrigPoints = gstack.size();
  BigInt passpix2 = 0;

  int subcbox = ui.GetInteger("SUBCBOX");
  int halfBox((subcbox-1)/2);
  while (!gstack.isEmpty()) {

    SmtkQStackIter cstack = matcher.FindSmallestEV(gstack);

    // Print number on stack
    if ((gstack.size() % 1000) == 0) {
      cout << "Number on Stack: " << gstack.size()
           << ". " << cstack.value().GoodnessOfFit() << "\n";
    }

    // Test to see if already determined
    SmtkQStackIter bmfPt = bmf.find(cstack.key());
    if (bmfPt == bmf.end()) {
      // Its not in the final stack, process it

      //  Retrieve the point
      SmtkPoint spnt = cstack.value();
      //  Register if its not already registered
      if (!spnt.isRegistered()) {
        spnt = matcher.Register(spnt, spnt.getAffine());
      }

      // Still must check for validity if the point was just registered,
      // otherwise should be good
      if ( spnt.isValid() ) {
        passpix2++;
        bmf.insert(cstack.key(), spnt);  // inserts (0,0) offset excluded below
        int line   = cstack.key().first;
        int sample = cstack.key().second;

        //  Determine match points
        double eigen(spnt.GoodnessOfFit());
        for (int sampBox = -halfBox ; sampBox <= halfBox ; sampBox++ ) {
          int csamp = sample + sampBox;
          for (int lineBox = -halfBox ; lineBox <= halfBox ; lineBox++) {
            int cline = line + lineBox;
            if ( !( (sampBox == 0) && (lineBox == 0)) ) {// Already added above
              SmtkQPair dupPair(cline, csamp);
              SmtkQStackIter temp = bmf.find(dupPair);
              SmtkPoint bmfpnt;
              if (temp != bmf.end()) {
                if (temp.value().GoodnessOfFit() > eigen) {
                  // Create cloned point with better fit
                  bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp));
                }
              }
              else {  // ISIS2 is BMF(SAMP,LINE,7) .EQ VALID_MAX4)
                // Clone new point for insert
                bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp));
              }

              //  Add if good point
              if (bmfpnt.isValid()) {
                bmf.insert(dupPair, bmfpnt);
              }
            }
          }
        }

        // Grow stack with spacing adding info to stack
        for (int i = -1 ; i <= 1 ; i ++) {  // Sample
          for (int j = -1 ; j <= 1 ; j ++) {  // Line
            // Don't re-add the original sample, line
            if ( !((i == 0) && (j == 0)) ) {
              //  Grow based upon spacing
              double ssamp = sample + (i * space);
              double sline = line   + (j * space);
              Coordinate pnt = Coordinate(sline, ssamp);
              SmtkPoint gpnt = matcher.Clone(spnt, pnt);

              if ( gpnt.isValid() ) {
                SmtkQPair growpt((int) sline, (int) ssamp);

                // double check we don't have a finalized result at this position
                SmtkQStackIter temp = bmf.find(growpt);
                if(temp == bmf.end()) {
                  gstack.insert(growpt, gpnt);
                }
              }
            }
          }
        }
      }
    }

    // Remove the current point from the grow stack (hole)
    gstack.erase(cstack);
  }

/////////////////////////////////////////////////////////////////////////
// All done with creating points.  Perform output options.
/////////////////////////////////////////////////////////////////////////

  // If a TO parameter was specified, create DEM with errors
  if (ui.WasEntered("TO")) {
    //  Create the output DEM
    cout << "\nCreating output DEM from " << bmf.size() << " points.\n";
    Process  p;
    Cube *icube = p.SetInputCube("FROM");
    Cube *ocube = p.SetOutputCube("TO", icube->sampleCount(),
                                  icube->lineCount(), 3);
    p.ClearInputCubes();

    int boxsize = ui.GetInteger("BOXSIZE");
    double plotdist = ui.GetDouble("PLOTDIST");

    TileManager dem(*ocube), eigen(*ocube), stErr(*ocube);
    dem.SetTile(1, 1);      //  DEM Data/elevation
    stErr.SetTile(1, 2);    //  Error in stereo computation
    eigen.SetTile(1, 3);    //  Eigenvalue of the solution

    int nBTiles(eigen.Tiles()/3);  // Total tiles / 3 bands

    prog.SetText("Creating DEM");
    prog.SetMaximumSteps(nBTiles);
    prog.CheckStatus();

    Statistics stAng;
    while ( !eigen.end() ) {   // Must use the last band for this!!
      PointPlot tm = for_each(bmf.begin(), bmf.end(), PointPlot(dem, plotdist));
      tm.FillPoints(*lhCamera, *rhCamera, boxsize, dem, stErr, eigen, &stAng);

      ocube->write(dem);
      ocube->write(stErr);
      ocube->write(eigen);

      dem.next();
      stErr.next();
      eigen.next();

      prog.CheckStatus();
    }

    //  Report Stereo separation angles
    PvlGroup stresultsPvl("StereoSeparationAngle");
    stresultsPvl += PvlKeyword("Minimum", toString(stAng.Minimum()), "deg");
    stresultsPvl += PvlKeyword("Average", toString(stAng.Average()), "deg");
    stresultsPvl += PvlKeyword("Maximum", toString(stAng.Maximum()), "deg");
    stresultsPvl += PvlKeyword("StandardDeviation", toString(stAng.StandardDeviation()), "deg");
    Application::Log(stresultsPvl);

    // Update the label with BandBin keywords
    PvlKeyword filter("FilterName", "Elevation", "meters");
    filter.addValue("ElevationError", "meters");
    filter.addValue("GoodnessOfFit", "unitless");
    PvlKeyword center("Center", "1.0");
    center.addValue("1.0");
    center.addValue("1.0");

    PvlGroup &bandbin = ocube->label()->findGroup("BandBin", PvlObject::Traverse);
    bandbin.addKeyword(filter, PvlContainer::Replace);
    bandbin.addKeyword(center, PvlContainer::Replace);
    center.setName("Width");
    bandbin.addKeyword(center, PvlContainer::Replace);


    p.EndProcess();
  }

  // If a cnet file was entered, write the ControlNet pvl to the file
  if (ui.WasEntered("ONET")) {
    WriteCnet(ui.GetFileName("ONET"), bmf, lhCamera->target()->name(), serialLeft,
              serialRight);
  }

  // Create output data
  PvlGroup totalPointsPvl("Totals");
  totalPointsPvl += PvlKeyword("AttemptedPoints", toString(numAttemptedInitialPoints));
  totalPointsPvl += PvlKeyword("InitialSuccesses", toString(numOrigPoints));
  totalPointsPvl += PvlKeyword("GrowSuccesses", toString(passpix2));
  totalPointsPvl += PvlKeyword("ResultingPoints", toString(bmf.size()));

  Application::Log(totalPointsPvl);

  Pvl arPvl = matcher.RegistrationStatistics();
  PvlGroup smtkresultsPvl("SmtkResults");
  smtkresultsPvl += PvlKeyword("SpiceOffImage", toString(matcher.OffImageErrorCount()));
  smtkresultsPvl += PvlKeyword("SpiceDistanceError", toString(matcher.SpiceErrorCount()));
  arPvl.addGroup(smtkresultsPvl);

  for(int i = 0; i < arPvl.groups(); i++) {
    Application::Log(arPvl.group(i));
  }

  // add the auto registration information to print.prt
  PvlGroup autoRegTemplate = matcher.RegTemplate();
  Application::Log(autoRegTemplate);

  // Don't need the cubes opened anymore
  lhImage.close();
  rhImage.close();
}