示例#1
0
文件: ctxcal.cpp 项目: corburn/ISIS
// 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();

}
示例#2
0
文件: moccal.cpp 项目: corburn/ISIS
// 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();
}