Commit 9dccfa01 authored by Tyler Wilson's avatar Tyler Wilson Committed by Adam Paquette
Browse files

Added I/F calibration step to hyb2onccal (#3132)

* Added AlphaCube group to outputlabel in the event the image is cropped.

* Fix libtiff dependency (#636) (#644)

* Upgrade libtiff to 4.0.10 (#636)

* Switch libtiff to 4.0.9 or higher to remove geotiff conflict

* Moved ISIS3 conda-build recipe from ISIS3_deps repository (#650)

* Fixed warning in Pixel unit tests

* Made a tweak to the dimensions of the alpha cube for cropped images to give it the correct dimensions.

* Changed the transform function so it could process an array of doubles instead of an array of ints.

* Smear correction was being incorrectly applied to onboard smear corrected images and screwing things up.  Fixed it.

* Added gtest capability to hyb2onc2isis

* Removing build numbers from external libraries (#660)

* Moved ISIS3 conda-build recipe from ISIS3_deps repository

* Un-pinned non-astro build numbers

* Removing build numbers from external libraries in the environment and meta.yeml files

* Final merging

* Added pixel type attribute to the output image of program shadow. Fixes #5187 (#659)

* Removed bolding of some text to decrease distraction.

* Fixed some typos.

* Reworded documentation.

* Added section for Environment and PreferemcesSetup in the Getting Started Section. (#663)

* Updated .gitmodules to use https rather than ssh (#673)

* Added build type release to conda recipe (#676)

* Modified isis/tests/CMakeLists.txt as well as hyb2onc2isis to fix unresolved symbol errors (CMakeLists.txt) and to fix some bugs in hyb2onc2isis involved with turning it into a callable function.

* Added w1 test to hyb2onc2isisTests.cpp

* Modified hyb2onccal to be a callable function.

* Updates README with Discourse (#690)

* Updates README with Discourse

* Update README.md

* Update README.md

* Changed the Pvl label output for Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttributeOutput att, QString target)

* Added Newton-Rapheson method to Hyb2OncCalUtils.h to solve the linearity equation.

* Final push of hayabusa2 changes made to the ingestion/calibration applications.

* Added I/F calibration step.  Cleaned up code base and worked on the documentation.  The documentation will need to be corrected before this is merged into dev.

* Fixed a missing </li> tag in hyb2onccal.xml
parent e3016f1c
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ void hyb2onc2isis(UserInterface &ui) {

Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttributeOutput att, QString target) {

  Pvl finalPvl;
  ProcessImportFits importFits;
  importFits.setFitsFile(FileName(fitsFileName));
  importFits.setProcessFileStructure(0);
@@ -138,7 +139,7 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttribute

  // Translate the Instrument group

  FileName transFile(transDir + "hyb2oncInstrument1.trn");
  FileName transFile(transDir + "hyb2oncInstrument.trn");

  if (updatedKeywords) {
    transFile = transDir+"hyb2oncInstrumentUpdated.trn";
@@ -255,14 +256,16 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttribute

  // Convert the image data
  importFits.Progress()->SetText("Importing Hayabusa2 image");
   Pvl finalLabel = *(outputCube->label() );

  importFits.StartProcess();
  importFits.Finalize();

  return finalLabel;

  return outputLabel;

  }

  }



+84 −144
Original line number Diff line number Diff line
@@ -120,14 +120,12 @@ static double g_compfactor(1.0); // Default if OutputMode = LOSS-LESS; 16.0 for
static QString g_iofCorrection("IOF");  //!< Is I/F correction to be applied?

//  I/F variables
static double g_solarDist(1.0);  /**< Distance from the Sun to the target body
(used to calculate g_iof) */
static double g_iof(1.0);        //!< I/F conversion value

static double g_iofScale(1.0);
static double g_solarFlux(1.0);  //!< The solar flux (used to calculate g_iof).
// TODO: we do not have this conversion factor for Hayabusa 2 ONC.
static double g_v_standard(1.0);
// static double g_v_standard(3.42E-3);//!< Base conversion for all filters (Tbl. 9)
static double g_sensitivity(1.0);
static double g_effectiveBandwidth(1.0);


namespace Isis {

@@ -186,12 +184,74 @@ bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double e


/**
* @brief Apply radiometric correction to each line of an AMICA image.
 * @brief linearFun:  The linear correction function (used by the newton_rapheson method)
 * @author 2019-02-12  Tyler Wilson
 * @param Iobs:  The observed intensity
 * @param x:  The ideal intensity.
 * @param g:  The vector of empirically derived coefficients for the third-order polynomial
 * modelling the linear correction (for DN values < 3400 DN)
 * @return The value of the function at the point x.
 */
double linearFun(double Iobs,double x, double g[3]) {
  return Iobs - g[0]*x -g[1]*pow(x,2.0) -g[2]*pow(x,3.0);

}

/**
 * @brief dFun:  The first-order derivative of linearFun
 * @author 2019-02-12  Tyler Wilson
 * @param x:  The ideal intensity.
 * @param g:  The vector of empirically derived coefficients for the third-order polynomial
 * modelling the linear correction (for DN values < 3400 DN)
 * @return
 */
double dFun(double x, double g[3]) {
  return -g[0] - 2*g[1]*x -3*g[2]*pow(x,2.0);

}

/**
 * @brief newton_rapheson
 * @author 2019-02-12 Tyler Wilson
 * @param Iobs:  The observed DN intensity
 * @param x0:  The starting value for the Newton-Rapheson method
 * @param g:  A vector of the coefficients for the linearity function.  It is a third-order
 * polynomial.
 * @param result:  The final approximation of the root of the equation.
 * @param epsilon:  The tolerance on the final solution.
 * @return A root of the linearity correction function, centered near the origin.
 */
bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double epsilon=1e-6 )  {

   double x[2];
   double dx = 1.0;
   int iter = 0;
   int maxIterations=500;
   x[0] = x0;
   while (dx > epsilon)  {

     x[1]=x[0] - linearFun(Iobs,x[0],g)/dFun(x[0],g);
     dx = fabs(x[1]-x[0]) ;
     x[0]=x[1];
     iter++;
     if (iter > maxIterations) {

       return false;
     }
   }
   result = x[1];
   return true;
}


/**
* @brief Apply radiometric correction to each line of a Hayabusa2 image.
* @author 2016-03-30 Kris Becker
* @param in   Raw image and flat field
* @param out  Radometrically corrected image
* @internal
*   @history 2017-07-2017 Ian Humphrey & Kaj Williams - Adapted from amicacal.
*   @history 2019-02-12 Tyler Wilson - Modified to support new calibration settings/formulas.
*/
void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {

@@ -218,8 +278,6 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {
  for (int i = 0; i < imageIn.size(); i++) {
    imageOut[i] = imageIn[i]*pow(2.0,12-g_bitDepth);



    // Check for special pixel in input image and pass through
    if ( IsSpecial(imageOut[i]) ) {
      imageOut[i] = imageIn[i];
@@ -227,12 +285,10 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {
    }

    // Apply compression factor here to raise LOSSY dns to proper response
    imageOut[i] *= g_compfactor;


    // 1) BIAS Removal - Only needed if not on-board corrected


    if ( !g_onBoardSmearCorrection ) {


@@ -241,31 +297,24 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {
        continue;
      }
      else {

        imageOut[i] = imageOut[i] - g_bias;
      }
    }


    double dn = imageOut[i];    
    double linearCorrection;
    double result = 1.0;
    double x0 = 1.0;
    newton_rapheson(imageOut[i],x0, g_L,result );    
    newton_rapheson(dn,x0, g_L,result );   
    imageOut[i] = result;

    //qDebug() << dn << ","<< result;


    // DARK Current
    imageOut[i] = imageOut[i] - g_darkCurrent;    




    // READOUT Smear Removal - Not needed if on-board corrected.  Binning is
    //    accounted for in computation of c1 before loop.
    // if (nsubImages <= 1) {
    //  imageOut[i] = c1*(imageOut[i] - smear);
    // }
    //Smear correction
    if (!g_onBoardSmearCorrection) {

      double smear = 0;
@@ -277,10 +326,6 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {

      }

    //Linearity Correction
    //In the SIS this adjustment is made just after the bias, but
    //in the Calibration paper it happens just before the flat field correction.


    // FLATFIELD correction
    //  Check for any special pixels in the flat field (unlikely)
@@ -294,16 +339,11 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {
      }
      else {
        if (flatField[i] != 0) {
          imageOut[i] /= flatField[i];
          imageOut[i] /= (flatField[i]*g_sensitivity*g_texp);
        }
      }
    }

    // TODO: once the radiance values are known for each band, we can correctly compute I/F.
    // For now, g_iof is 1, so output will be in DNs.
    // 7) I/F or Radiance Conversion (or g_iof might = 1, in which case the output will be in DNs)
    imageOut[i] *= g_iof;

  }


@@ -312,107 +352,6 @@ void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out) {



/**
 * @brief Load required NAIF kernels required for timing needs.
 *
 * This method maintains the loading of kernels for HAYABUSA timing and
 * planetary body ephemerides to support time and relative positions of planet
 * bodies.
 */
/* Helper function for sunDistanceAu, don't need this until we have radiance calibration
   parameters for Hayabusa2 ONC-T filters to calculate radiance and I/F
static void loadNaifTiming() {
  static bool naifLoaded = false;
  if (!naifLoaded) {

//  Load the NAIF kernels to determine timing data
    Isis::FileName leapseconds("$base/kernels/lsk/naif????.tls");
    leapseconds = leapseconds.highestVersion();
    Isis::FileName sclk("$hayabusa2/kernels/sclk/hyb2_20141203-20161231_v01.tsc");    
    Isis::FileName pck1("$hayabusa2/kernels/tspk/de430.bsp");
    Isis::FileName pck2("$hayabusa2/kernels/tspk/jup329.bsp");
    Isis::FileName pck3("$hayabusa2/kernels/tspk/sat375.bsp");
    Isis::FileName pck4("$hayabusa2/kernels/spk/hyb2_20141203-20141214_0001m_final_ver1.oem.bsp");
    Isis::FileName pck5("$hayabusa2/kernels/spk/hyb2_20141203-20151231_0001h_final_ver1.oem.bsp");
    Isis::FileName pck6("$hayabusa2/kernels/spk/hyb2_20151123-20151213_0001m_final_ver1.oem.bsp");

//  Load the kernels
    QString leapsecondsName(leapseconds.expanded());
    QString sclkName(sclk.expanded());

    QString pckName1(pck1.expanded());
    QString pckName2(pck2.expanded());
    QString pckName3(pck3.expanded());
    QString pckName4(pck4.expanded());
    QString pckName5(pck5.expanded());
    QString pckName6(pck6.expanded());

    furnsh_c(leapsecondsName.toLatin1().data());
    furnsh_c(sclkName.toLatin1().data());

    furnsh_c(pckName1.toLatin1().data());
    furnsh_c(pckName2.toLatin1().data());
    furnsh_c(pckName3.toLatin1().data());
    furnsh_c(pckName4.toLatin1().data());
    furnsh_c(pckName5.toLatin1().data());
    furnsh_c(pckName6.toLatin1().data());


//  Ensure it is loaded only once
    naifLoaded = true;
  }
  return;
}
*/


/**
 * @brief Computes the distance from the Sun to the observed body.
 *
 * This method requires the appropriate NAIK kernels to be loaded that
 * provides instrument time support, leap seconds and planet body ephemeris.
 *  
 * @return @b double Distance in AU between Sun and observed body.
 */
/* commented out until we have radiance values (RAD/IOF group in calibration trn) for Hayabusa2.
 static bool sunDistanceAU(const QString &scStartTime,
                          const QString &target,
                          double &sunDist) {

  //  Ensure NAIF kernels are loaded
  loadNaifTiming();
  sunDist = 1.0;

  //  Determine if the target is a valid NAIF target
  SpiceInt tcode;
  SpiceBoolean found;
  bodn2c_c(target.toLatin1().data(), &tcode, &found);

  if (!found) return (false);

  //  Convert starttime to et
  double obsStartTime;
  scs2e_c(-37, scStartTime.toLatin1().data(), &obsStartTime);

  //  Get the vector from target to sun and determine its length
  double sunv[3];
  double lt;
  spkpos_c(target.toLatin1().data(), obsStartTime, "J2000", "LT+S", "sun",
                  sunv, &lt);
  NaifStatus::CheckErrors();

  double sunkm = vnorm_c(sunv);


  //  Return in AU units
  sunDist = sunkm / 1.49597870691E8;

  //cout << "sunDist = " << sunDist << endl;
  return (true);
}
*/


/**
 * @brief Translates a 1-banded Isis::Cube to an OpenMat object
 *
@@ -538,13 +477,16 @@ void translate(Cube *flatField,double *transform, QString fname) {
* @return FileName Path and name of flat file file
* @internal
*   @history 2017-07-27 Ian Humphrey & Kaj Williams - Adapted from amicacal.
*   @history 2019-02-12 Tyler Wilson - Modified to support new calibration settings/formulas.
*/
FileName DetermineFlatFieldFile(const QString &filter) {

  QString fileName = "$hayabusa2/calibration/flatfield/";
  // FileName consists of binned/notbinned, camera, and filter
  fileName += "flat_" + filter.toLower() + ".cub";
  fileName += "flat_" + filter.toLower() + "_norm.cub";

  FileName final(fileName);

  return final;
}

@@ -574,6 +516,8 @@ QString loadCalibrationVariables(const QString &config) {
  PvlGroup &DarkCurrent = g_configFile.findGroup("DarkCurrent");
  PvlGroup &Smear = g_configFile.findGroup("SmearRemoval");
  PvlGroup &solar = g_configFile.findGroup("SOLARFLUX");
  PvlGroup &sensitivity = g_configFile.findGroup("SENSITIVITYFACTOR");
  PvlGroup & effectiveBW = g_configFile.findGroup("EFFECTIVEBW");
  PvlGroup &linearity = g_configFile.findGroup("Linearity");
  // PvlGroup &iof = g_configFile.findGroup("RAD");

@@ -614,11 +558,13 @@ QString loadCalibrationVariables(const QString &config) {

  // Compute BIAS correction factor (it's a constant so do it once!)
  g_bias = g_b0+g_b1*g_CCD_T_temperature+g_b2*g_ECT_T_temperature;
  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //correction factor
  qDebug() << "Bias: " << g_bias;
  //double correction_factor = (g_bae0 + g_bae1*g_AEtemperature);
  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //bias correction factor

  // Load the Solar Flux for the specific filter
  g_solarFlux = solar[g_filter.toLower()];
  g_sensitivity = sensitivity[g_filter.toLower()];
  g_effectiveBandwidth = effectiveBW[g_filter.toLower()];

  //Load the linearity variables
  g_L[0] = linearity["L"][0].toDouble();
@@ -626,16 +572,10 @@ QString loadCalibrationVariables(const QString &config) {
  g_L[2] = linearity["L"][2].toDouble();



  // radiance = g_v_standard * g_iofScale
  // iof      = radiance * pi *dist_au^2
  // g_iofScale   = iof[g_filter];

  return ( calibFile.original() );
}



}

#endif
+34 −28
Original line number Diff line number Diff line
@@ -39,9 +39,6 @@
using namespace std;


//void Calibrate(vector<Buffer *>& in, vector<Buffer *>& out);

//QString loadCalibrationVariables(const QString &config);



@@ -126,7 +123,6 @@ void hyb2onccal(UserInterface &ui) {
  catch (IException &e) {
    QString msg = "Unable to read [BitDepth] keyword in the Instrument group "
    "from input file [" + icube->fileName() + "]";
    //qDebug() << msg;
    g_bitDepth = 12;

  }
@@ -151,7 +147,7 @@ void hyb2onccal(UserInterface &ui) {

  try {
    g_AEtemperature = inst["ONCAETemperature"][0].toDouble();
    qDebug() << "g_AEtemperature:  " << g_AEtemperature;

  }
  catch(IException &e) {
    QString msg = "Unable to read [ONCAETemperature] keyword in the Instrument group "
@@ -162,7 +158,7 @@ void hyb2onccal(UserInterface &ui) {

  try {
    g_CCD_T_temperature = inst["ONCTCCDTemperature"][0].toDouble();
    qDebug() << "g_CCD_T_Temperature:  " << g_CCD_T_temperature;

  }
  catch(IException &e) {
    QString msg = "Unable to read [ONCTCCDTemperature] keyword in the Instrument group "
@@ -172,7 +168,7 @@ void hyb2onccal(UserInterface &ui) {

  try {
    g_ECT_T_temperature = inst["ONCTElectricCircuitTemperature"][0].toDouble();
    qDebug() << "g_ECT_T_temperature: " << g_ECT_T_temperature;

  }
  catch(IException &e) {
    QString msg = "Unable to read [ONCTElectricCircuitTemperature] keyword in the Instrument group "
@@ -208,11 +204,16 @@ void hyb2onccal(UserInterface &ui) {
  if (smearCorrection=="ONBOARD") {
    g_onBoardSmearCorrection=true;
  }
  else {
      qDebug() << icube->fileName();

  }

  QString compmode = inst["Compression"];
  // TODO: verify that the compression factor/scale is actually 16 for compressed Hayabusa2 images.
  g_compfactor = ( "lossy" == compmode.toLower() ) ? 16.0 : 1.0;


  QString target = inst["TargetName"];
  g_target = target;

@@ -273,14 +274,12 @@ void hyb2onccal(UserInterface &ui) {

      Cube *flatOriginal = new Cube(flatfile.expanded() );

      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};

      double alphaStartSample = alphaCube["AlphaStartingSample"][0].toDouble();
      double alphaStartLine = alphaCube["AlphaStartingLine"][0].toDouble();
      double alphaEndSample = alphaCube["AlphaEndingSample"][0].toDouble();
      double alphaEndLine = alphaCube["AlphaEndingLine"][0].toDouble();

      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
      double transform[5] = {(double)binning,alphaStartSample,alphaStartLine,alphaEndSample,alphaEndLine};

      // Translates and scales the flatfield image.  Scaling
@@ -302,13 +301,14 @@ void hyb2onccal(UserInterface &ui) {


  Cube *ocube  = p.SetOutputCube("TO");
  //QString fname = ocube->fileName();


  QString calfile = loadCalibrationVariables(ui.GetAsString("CONFIG"));



  g_timeRatio = g_Tvct/(g_texp + g_Tvct);

  g_iof = 1.0;  // Units of DN

  QString g_units = "DN";
  // if ( "radiance" == g_iofCorrection.toLower() ) {
@@ -350,7 +350,10 @@ void hyb2onccal(UserInterface &ui) {
  calibrationLog.addKeyword(PvlKeyword("CalibrationFile", calfile));
  calibrationLog.addKeyword(PvlKeyword("FlatFieldFile", flatfile.originalPath()
  + "/" + flatfile.name()));
  calibrationLog.addKeyword(PvlKeyword("CompressionFactor", toString(g_compfactor, 2)));

  PvlKeyword sensitivityFactor("SensitivityFactor");
  sensitivityFactor.addValue(toString(g_sensitivity,16));
  calibrationLog.addKeyword(sensitivityFactor);

  // Parameters
  PvlKeyword bn("Bias_Bn");
@@ -363,17 +366,6 @@ void hyb2onccal(UserInterface &ui) {
  bnae.addValue(toString(g_bae0, 8));
  bnae.addValue(toString(g_bae1, 8));
  calibrationLog.addKeyword(bnae);  

#if 0
  PvlKeyword linearityCoefs("Linearity");
  linearityCoefs.addValue(toString(g_L0,8));
  linearityCoefs.addValue(toString(g_L1,8));
  linearityCoefs.addValue(toString(g_L2,8));
  calibrationLog.addKeyword(linearityCoefs);

#endif


  calibrationLog.addKeyword(PvlKeyword("Bias_AETemp", toString(g_AEtemperature, 16)));


@@ -400,13 +392,27 @@ void hyb2onccal(UserInterface &ui) {
  calibrationLog.addKeyword(PvlKeyword("Smear_texp", toString(g_texp, 16)));

  calibrationLog.addKeyword(PvlKeyword("CalibrationUnits", g_iofCorrection));
  calibrationLog.addKeyword(PvlKeyword("RadianceStandard", toString(g_v_standard, 16)));

  calibrationLog.addKeyword(PvlKeyword("RadianceScaleFactor", toString(g_iofScale, 16)));
  calibrationLog.addKeyword(PvlKeyword("SolarDistance", toString(g_solarDist, 16), "AU"));
  calibrationLog.addKeyword(PvlKeyword("SolarFlux", toString(g_solarFlux, 16)));  
  calibrationLog.addKeyword(PvlKeyword("IOFFactor", toString(g_iof, 16)));
  calibrationLog.addKeyword(PvlKeyword("Units", g_units));

  PvlKeyword linearityCoefs("LinearityCoefficients");
  linearityCoefs.addValue(toString(g_L[0],16));
  linearityCoefs.addValue(toString(g_L[1],16));
  linearityCoefs.addValue(toString(g_L[2],16));
  calibrationLog.addKeyword(linearityCoefs);

  PvlKeyword darkCurrentCoefs("DarkCurrentCoefficients");
  darkCurrentCoefs.addValue(toString(g_d0,16));
  darkCurrentCoefs.addValue(toString(g_d1,16));
  calibrationLog.addKeyword(darkCurrentCoefs);

  PvlKeyword darkCurrent("DarkCurrent");
  darkCurrent.addValue(toString(g_darkCurrent,16));
  calibrationLog.addKeyword(darkCurrent);


  // Write Calibration group to output file
  ocube->putGroup(calibrationLog);
  Application::Log(calibrationLog);
+19 −167
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$ -->

<application name="hyb2oncal" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<application name="hyb2onccal" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd">
  <brief>
    Calibrates Hayabusa 2 ONC-T images. Calibration includes bias and dark current correction as
@@ -66,91 +66,6 @@ xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Applica

    </div>
  </p>

<!--
  <p>
    <h1><a id="Smear">Step 2: Read-out smear:</a ></h1>
    The ONC-T instrument is shuttered electronically.  Images are exposed for a certain
    exposure time in addition to the vertical charge-transfer period. <strong>We could not determine
    of locate this value. Additionally, note that on-board smear correction can be performed.
    </strong>
    It is during the charge-transfer period that a read-out smear in the vertical direction
    is produced. The read-out smear brightness <strong>I<sub>smear</sub></strong>
    for unbinned images is modeled from the observed images as follows:

    <div style="font-size:90%; font-family:monospace; margin:5px; margin-left:30px;">
    <br/><br/>
    <center><strong>I<sub>smear</sub>(H) = SUM(H=0...N<sub>v</sub> -1) { [K*[(I<sub>raw</sub>(H,V) -
    I<sub>sky</sub>(H,V)]/N<sub>v</sub>] } </strong></center>
    <br/><br/>
           <center>Where:  <strong>K = t<sub>VCT</sub>/(t<sub>VCT</sub>+t<sub>exp</sub>)
           </strong></center>
    <br/><br/>



    For binned images a different formula is applied:


     <center><strong>I<sub>smear</sub>(H) = SUM(H=0...N<sub>v</sub> - 1)
     { [ K1*I<sub>raw</sub>(H,V) ] }</strong>
     </center>

    <br/><br/>
           <center>Where:  <strong>K1 = (1/N<sub>v</sub>)*[t<sub>VCT</sub>/
           (t<sub>VCT</sub>+t<sub>exp</sub>)]
           </strong></center>

    <br/><br/>

    A correction factor is then applied after the smear component is subtracted
    from the input image (I<sub>raw</sub>):

    <center> <strong> I<sub>out</sub> = C*(I<sub>raw></sub> - I<sub>smear</sub>)</strong></center>
    <br/><br/>

    <center>Where:  <strong>C = 1/( 1 + K1 * ( (B - 1)/2*B ) ) </strong></center>

    <br/><br/>

    <center><table border = "1" cellpadding="5">
    <tr>
      <td>Variable</td><td>Description</td>
    </tr>
    <tr>
      <td>I<sub>smear</sub></td><td>The read-out smear.</td>
    </tr>
    <tr>
      <td>I<sub>raw</sub></td><td>The intensity of the raw data taken with exposure time
      t<sub>exp</sub>.</td>
    </tr>
    <tr>
      <td>I<sub>sky</sub></td><td>The sum of the bias and the dark current (~300 DN).</td>
    </tr>

    <tr>
      <td>t<sub>VCT</sub></td><td>The vertical charge-transfer period (0.012288 microseconds).</td>
    </tr>
    <tr>
      <td>t<sub>exp</sub></td><td>The exposure time (in microseconds).</td>
    </tr>
    <tr>
      <td>N<sub>v</sub></td><td>The number of pixels along the V-direction (1024).</td>
    </tr>
    <tr>
      <td>H</td><td>The line number of the pixel.</td>
    </tr>
    <tr>
      <td>L</td><td>The sample number of the pixel.</td>
    </tr>
    <tr>
      <td>B</td><td>The binning number.</td>
    </tr>
    </table></center>
    </div>
  </p>
-->

  <p>
    <h1><a id="Flatfield">Step 2: Flat-field correction:</a ></h1>
    Performs a correction for pixel-to-pixel variation in CCD response and vignetting
@@ -162,93 +77,24 @@ xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Applica
    pixel in the flat-field image.
  </p>

<!-- We cannot correctly determine I/F or radiance output because we do not have the radiance
values for each band for Hayabusa2 ONC.
  <p>
    <h1><a id="ConvertIOF">Step 3 (Optional): Convert output units to Radiance or I over F:</a ></h1>
    This step is optional, and the formula used depends on the value of the UNITS user parameter.
    <em>Note: we do not currently have the radiance values for the filters, so we cannot correctly
    convert the output units to Radiance.

    If UNITS=RADIANCE, the following formula will be used to convert the raw DN values to radiance
    (W/m2/sr/µm):

    <br/><br/>
     <div style="font-size:90%; font-family:monospace; margin:5px; margin-left:30px;">
      <center><strong>R = Raw*RadianceStandard*RadianceScaleFactor</strong></center>
      <br/><br/>
      <center><table border="1" cellpadding="5">
      <tr>
          <td>Variable</td><td>Description</td>
     </tr>
     <tr>
          <td>R</td><td>The calibrated radiance (w/m2/sr/µm). </td>
     </tr>
     <tr>
          <td>Raw</td><td>The raw DN value. </td>
     </tr>
     <tr>
          <td>RadianceStandard</td><td>The standard conversion factor from DNs to radiance. </td>
     </tr>
     <tr>
          <td>RadianceScaleFactor</td><td>An adjustment factor for each filter.</td>
     </tr>
     </table></center>
     </div>

    If UNITS = IOF, first the above formula will be used to convert from raw DNs to calibrated Radiance, and then
    the following formula will be used to convert the raw DN values to I/F (radiance) units:
    <br/><br/>
     <div style="font-size:90%; font-family:monospace; margin:5px; margin-left:30px;">
      <center><strong>IoF = R*[pi*(R<sub>s</sub>)<sup>2</sup>]/F</strong></center>
      <br/><br/>
      <center><table border="1" cellpadding="5">
      <tr>
          <td>Variable</td><td>Description</td>
     </tr>
     <tr>
          <td>IoF</td><td>The calibrated radiance in units of I over F.</td>
     </tr>
     <tr>
          <td>R</td><td>The calibrated radiance (w/m2/sr/µm). </td>
     </tr>
     <tr>
         <td>R<sub>s</sub></td><td>The distance in Astronomical Units (AU) between the Sun
         and the target body.
         </td>
     </tr>
     <tr>
          <td>F</td><td>The solar flux (w/m2/µm) at 1 AU. </td>
     </tr>
     </table></center>
     </div>

    If UNITS=DN, no output conversion will be performed and the output units will be in raw DNs.
  </p>
-->

  <p>
  <h1><a id="Notes">Notes</a></h1>
  <ol>
    <li>
      Smear correction is not currently provided, as we do not have the readout time
      (charge-transfer period) for the instrument.
    </li>
    <li>
      Similarly, since no radiance values could be found for the instrument filters, the output
      cannot be correctly converted to radiance or I/F.
    </li>
    <li>
    </li>
  </ol>
  </p>

  <p>
    <h1><a id="References">References:</a></h1>
    <ol>
      <li>S. Kameda et al.  <i>"Preflight Calibration Test Results for Optical Navigation
      Camera Telescope (ONC-T) Onboard the Hayabusa2 Spacecraft"</i>.
      Space Sci Rev (2017) 208:17-31.</li>
      Space Sci Rev (2017) 208:17-31.
      </li>
      <li>E. Tatsumi et al.  <i>"Updated Inflight Calibration of Hayabusa2’s Optical Navigation Camera (ONC) for
      Scientific Observations during the Cruise Phase"</i>.
      https://arxiv.org/abs/1810.11065 [astro-ph.IM] 25 Oct, 2018.
      </li>
      <li>H. Suzuki et al. <i>"Initial inflight calibration for Hayabusa2 optical navigation camera
      (ONC) for science observations of asteroid Ryugu"</i>.
      Icarus. 300. 10.1016/j.icarus.2017.09.011
      </li>
    </ol>

  </p>
@@ -270,6 +116,9 @@ values for each band for Hayabusa2 ONC.
    <change name="Ian Humphrey and Kaj Williams" date="2017-07-27">
      Original version. Adapted from amicacal.
    </change>
    <change name="Tyler Wilson" date="2019-02-12">
      Modified version to handle the updated calibration values/formulas.
    </change>
  </history>

  <groups>
@@ -315,11 +164,14 @@ values for each band for Hayabusa2 ONC.
           the parameters as needed.
        </description>
        <filter>*.trn</filter>
        <!--
        <default><item>$hayabusa2/calibration/onc/hyb2oncCalibration????.trn</item></default>
         <!-->
        <default><item>/scratch/isis3data/hayabusa2/calibration/onc/hyb2oncCalibration????.trn</item></default>
        -->

        <default><item>/usgs/cpkgs/isis3/datalocal/hayabusa2/calibration/onc/hyb2oncCalibration????.trn</item></default>

      </parameter>
      
    </group>

    <!-- Recall no radiance values have been provided for the filters, so radiance and i/f cannot be
+26 −6

File changed.

Preview size limit exceeded, changes collapsed.