Unverified Commit ad3d02c0 authored by Lauren Adoram-Kershner's avatar Lauren Adoram-Kershner Committed by GitHub
Browse files

Marcical update to be fully congruent with calibration method (#5004)

* Small clean up of single use variables and convoluted logic

* Update CHANGELOG

* update history in xml

* update CHNGLG and tests
parent f57caf15
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -34,18 +34,18 @@ release.
-->

## [Unreleased]
- Added check to determine if poles were a valid projection point in ImagePolygon when generating footprint for a map projected image. [#4390](https://github.com/USGS-Astrogeology/ISIS3/issues/4390)
- Updated the LRO photometry application Lronacpho, to use by default the current 2019 photometric model (LROC_Empirical). The model's coefficients are found in the PVL file that exists in the LRO data/mission/calibration directory. If the old parameter file is provided, the old algorithm(2014) will be used. This functionality is desired for calculation comparisons. Issue: [#4512](https://github.com/USGS-Astrogeology/ISIS3/issues/4512), PR: [#4519](https://github.com/USGS-Astrogeology/ISIS3/pull/4519)
- Added a new application, framestitch, for stitching even and odd push frame images back together prior to processing in other applications. [4924](https://github.com/USGS-Astrogeology/ISIS3/issues/4924)
- Added changes to lronaccal to use time-dependent dark files for dark correction and use of specific dark files for images with exp code of zero. Also added GTests for lronaccal and refactored code to make callable. Added 3 truth cubes to testing directory.  PR[#4520](https://github.com/USGS-Astrogeology/ISIS3/pull/4520)

### Changed
- Updated the LRO photometry application Lronacpho, to use by default the current 2019 photometric model (LROC_Empirical). The model's coefficients are found in the PVL file that exists in the LRO data/mission/calibration directory. If the old parameter file is provided, the old algorithm(2014) will be used. This functionality is desired for calculation comparisons. Issue: [#4512](https://github.com/USGS-Astrogeology/ISIS3/issues/4512), PR: [#4519](https://github.com/USGS-Astrogeology/ISIS3/pull/4519)
- Updated the LRO calibration application Lrowaccal to add a units label to the RadiometricType keyword of the Radiometry group in the output cube label if the RadiometricType parameter is Radiance. No functionality is changed if the RadiometricType parameter is IOF. Lrowaccal has also been refactored to be callable for testing purposes. Issue: [#4939](https://github.com/USGS-Astrogeology/ISIS3/issues/4939), PR: [#4940](https://github.com/USGS-Astrogeology/ISIS3/pull/4940)
- Changed how logs are reported so they no longer only printing at the end of the applications execution. [#4914](https://github.com/USGS-Astrogeology/ISIS3/issues/4914)


- Update marcical to include step 3 of the mission team's MARCI calibration process described [here](https://pds-imaging.jpl.nasa.gov/data/mro/mars_reconnaissance_orbiter/marci/mrom_1343/calib/marcical.txt). [#5004](https://github.com/USGS-Astrogeology/ISIS3/pull/5004)
### Added
- Improved functionality of msi2isis and MsiCamera model to support new Eros dataset, including support for Gaskell's SUMSPICE files that adjust timing, pointing and spacecraft position ephemeris. [#4886](https://github.com/USGS-Astrogeology/ISIS3/issues/4886)
- Added a new application, framestitch, for stitching even and odd push frame images back together prior to processing in other applications. [4924](https://github.com/USGS-Astrogeology/ISIS3/issues/4924)
- Re-added and refactored the LRO photometry application lrowacphomap to be callable for testing purposes. Issue: [#4960](https://github.com/USGS-Astrogeology/ISIS3/issues/4960), PR: [#4961](https://github.com/USGS-Astrogeology/ISIS3/pull/4961)
- Added check to determine if poles were a valid projection point in ImagePolygon when generating footprint for a map projected image. [#4390](https://github.com/USGS-Astrogeology/ISIS3/issues/4390)
- Added changes to lronaccal to use time-dependent dark files for dark correction and use of specific dark files for images with exp code of zero. Also added GTests for lronaccal and refactored code to make callable. Added 3 truth cubes to testing directory.  PR[#4520](https://github.com/USGS-Astrogeology/ISIS3/pull/4520)

### Deprecated

+26 −33
Original line number Diff line number Diff line
@@ -152,16 +152,6 @@ formula:

namespace Isis {

  const QString knownFilters[] = {
    "NIR",
    "RED",
    "ORANGE",
    "GREEN",
    "BLUE",
    "LONG_UV",
    "SHORT_UV"
  };

  Stretch stretch;

  void marcical(UserInterface &ui) {
@@ -175,7 +165,6 @@ namespace Isis {
    icube.open(FileName(ui.GetCubeName("FROM")).expanded());

    // Make sure it is a Marci cube
    FileName inFileName = ui.GetCubeName("FROM");
    try {
      if (icube.group("Instrument")["InstrumentID"][0] != "Marci") {
        throw IException();
@@ -186,6 +175,7 @@ namespace Isis {
      }
    }
    catch (IException &) {
      FileName inFileName = ui.GetCubeName("FROM");
      QString msg = "This program is intended for use on MARCI images only. [";
      msg += inFileName.expanded() + "] does not appear to be a MARCI image.";
      throw IException(IException::User, msg, _FILEINFO_);
@@ -318,20 +308,20 @@ namespace Isis {
    vector<int> filter;

    // Conversion from filter name to filter index
    map<QString, int> filterNameToFilterIndex;
    filterNameToFilterIndex.insert(pair<QString, int>("BLUE",     1));
    filterNameToFilterIndex.insert(pair<QString, int>("GREEN",    2));
    filterNameToFilterIndex.insert(pair<QString, int>("ORANGE",   3));
    filterNameToFilterIndex.insert(pair<QString, int>("RED",      4));
    filterNameToFilterIndex.insert(pair<QString, int>("NIR",      5));
    filterNameToFilterIndex.insert(pair<QString, int>("SHORT_UV", 6));
    filterNameToFilterIndex.insert(pair<QString, int>("LONG_UV",  7));
    map<QString, int> filterNameToFilterNumber;
    filterNameToFilterNumber.insert(pair<QString, int>("BLUE",     1));
    filterNameToFilterNumber.insert(pair<QString, int>("GREEN",    2));
    filterNameToFilterNumber.insert(pair<QString, int>("ORANGE",   3));
    filterNameToFilterNumber.insert(pair<QString, int>("RED",      4));
    filterNameToFilterNumber.insert(pair<QString, int>("NIR",      5));
    filterNameToFilterNumber.insert(pair<QString, int>("SHORT_UV", 6));
    filterNameToFilterNumber.insert(pair<QString, int>("LONG_UV",  7));

    PvlKeyword filtNames = icube.label()->findGroup("BandBin", Pvl::Traverse)["FilterName"];
    int numFilters = filtNames.size();
    for (int i = 0; i < filtNames.size(); i++) {
      if (filterNameToFilterIndex.find(filtNames[i]) != filterNameToFilterIndex.end()) {
        filter.push_back(filterNameToFilterIndex.find(filtNames[i])->second);
      if (filterNameToFilterNumber.find(filtNames[i]) != filterNameToFilterNumber.end()) {
        filter.push_back(filterNameToFilterNumber.find(filtNames[i])->second);
      }
      else {
        QString msg = "Unrecognized filter name [" + QString(filtNames[i]) + "]";
@@ -347,21 +337,14 @@ namespace Isis {
    PvlKeyword &colOff = icube.label()->findGroup("Instrument", Pvl::Traverse)["ColorOffset"];
    int colorOffset = toInt(colOff[0]);

    for (int filter = 0; filter < numFilters; filter++) {
    for (int i = 0; i < numFilters; i++) {
      if (colorOffset > 0) {
        // find the filter num
        int filtNum = 0;
        int numKnownFilters = sizeof(knownFilters) / sizeof(QString);

        while (filtNum < numKnownFilters &&
              (QString)icube.label()->findGroup("BandBin", Pvl::Traverse)["FilterName"][filter] != knownFilters[filtNum]) {
          filtNum ++;
        }
        int filtNum = filterNameToFilterNumber[filtNames[i]] - 1; // if first vis filter (Blue) there is no offset 1 -> 0

        padding[filter] = (colorOffset * filterHeight) * filtNum;
        padding[i] = (colorOffset * filterHeight) * filtNum;
      }
      else {
        padding[filter] = 0;
        padding[i] = 0;
      }
    }

@@ -507,8 +490,13 @@ namespace Isis {
        else if (IsSpecial(icubeMgr[i])) {
          ocubeMgr[i] = icubeMgr[i];
        }
        else {
          if ((*fcubeMgrs[fcubeIndex])[i] < 0.25) {
            ocubeMgr[i] = 0;
          }
          else {
            ocubeMgr[i] = stretch.Map(icubeMgr[i]) / (*fcubeMgrs[fcubeIndex])[i];
          }

          ocubeMgr[i] = ocubeMgr[i] / exposure / (summing * decimation[fcubeIndex]) / calibrationCoeffs[fcubeIndex].first;

@@ -524,6 +512,11 @@ namespace Isis {
      icubeMgr++;
      ocubeMgr++;

      // checks if we have reached the end before setting higher band
      if (ocubeMgr.end()) {
        break;
      }

      bool newFramelet = false;

      for (int i = 0; i < (int)fcubeMgrs.size(); i++) {
+11 −7
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@ K.D. Supulver, and P.C. Thomas
      Modified to use the exposure duration from the new label keywords added by
      marci2isis. Related #2034
    </change>
    <change name="Lauren Adoram-Kershner" date="2022-07-15">
    Implimented step 3 of marci calibration description, where if normalized flatfile DN value 
    is less than 0.25, the output cube DN is set to 0. 
    </change>
  </history>

  <groups>
+12 −12
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ TEST(Marcical, MarcicalTestDefault) {
  EXPECT_EQ( inst["VariableExposureDuration"][2].toStdString(), "17.5" );

  std::unique_ptr<Histogram> outHist (outCube.histogram());
  EXPECT_NEAR( outHist->Average(), 0.034876, 1e-6 );
  EXPECT_NEAR( outHist->Sum(), 1.39504, 1e-5 );
  EXPECT_NEAR( outHist->Average(), 0.046682, 1e-6 );
  EXPECT_NEAR( outHist->Sum(), 1.86728, 1e-5 );
  EXPECT_EQ( outHist->ValidPixels(), 40 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.0110666, 1e-7 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.0148127, 1e-7 );
}

TEST(Marcical, MarcicalTestDefaultNoIof) {
@@ -61,10 +61,10 @@ TEST(Marcical, MarcicalTestDefaultNoIof) {
  EXPECT_EQ( inst["VariableExposureDuration"][2].toStdString(), "17.5" );

  std::unique_ptr<Histogram> outHist (outCube.histogram());
  EXPECT_NEAR( outHist->Average(), 8.80655,  1e-5);
  EXPECT_NEAR( outHist->Sum(), 352.262, 1e-3 );
  EXPECT_NEAR( outHist->Average(), 11.78765,  1e-5);
  EXPECT_NEAR( outHist->Sum(), 471.5062, 1e-3 );
  EXPECT_EQ( outHist->ValidPixels(), 40 );
  EXPECT_NEAR( outHist->StandardDeviation(), 2.79442, 1e-5 );
  EXPECT_NEAR( outHist->StandardDeviation(), 3.74036, 1e-5 );
}

TEST(Marcical, MarcicalTestSingleDuration) {
@@ -86,10 +86,10 @@ TEST(Marcical, MarcicalTestSingleDuration) {
  EXPECT_EQ( inst["VariableExposureDuration"][0].toStdString(), "8.8" );

  std::unique_ptr<Histogram> outHist (outCube.histogram());
  EXPECT_NEAR( outHist->Average(), 0.00656912, 1e-7 );
  EXPECT_NEAR( outHist->Sum(), 0.131382, 1e-6 );
  EXPECT_NEAR( outHist->Average(), 0.00879284, 1e-7 );
  EXPECT_NEAR( outHist->Sum(), 0.175856, 1e-6 );
  EXPECT_EQ( outHist->ValidPixels(), 20 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.000671733, 1e-8 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.000899121, 1e-8 );
}

TEST(Marcical, MarcicalTestSingleDurationNoIof) {
@@ -111,8 +111,8 @@ TEST(Marcical, MarcicalTestSingleDurationNoIof) {
  EXPECT_EQ( inst["VariableExposureDuration"][0].toStdString(), "8.8" );

  std::unique_ptr<Histogram> outHist (outCube.histogram());
  EXPECT_NEAR( outHist->Average(), 1.61438, 1e-4 );
  EXPECT_NEAR( outHist->Sum(), 32.2875, 1e-4 );
  EXPECT_NEAR( outHist->Average(), 2.16086, 1e-4 );
  EXPECT_NEAR( outHist->Sum(), 43.2172, 1e-4 );
  EXPECT_EQ( outHist->ValidPixels(), 20 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.16508, 1e-4 );
  EXPECT_NEAR( outHist->StandardDeviation(), 0.22096, 1e-4 );
}