Unverified Commit 89850b70 authored by Christine Kim's avatar Christine Kim Committed by GitHub
Browse files

Update photomet's MinnaertEmpirical model to handle PVL input in photemplate...

Update photomet's MinnaertEmpirical model to handle PVL input in photemplate format. Fixes #3621. (#5175)

* Update photomet's MinnaertEmpirical model to handle PVL input in photemplate format

* Updated CHANGELOG
parent 6646d96d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ release.

### Fixed
- Updated History constructor to check for invalid BLOB before copying History BLOB to output cube [#4966](https://github.com/DOI-USGS/ISIS3/issues/4966)
- Updated photomet MinnaertEmpirical model to support photemplate-style PVL format [#3621](https://github.com/DOI-USGS/ISIS3/issues/3621)

## [8.0.0] - 2023-04-19

+79 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ namespace Isis {
    * phase curve values that exist between the given phase angles. The values
    * in the phase angle list are limited to values that are >=0 and <=180.
    *
    * @param phaselist  List of phase angles to interpolate
    * @param phasestrlist  List of phase angles to interpolate
    */
  void MinnaertEmpirical::SetPhotoPhaseList(QString phasestrlist) {
    double phaseangle;
@@ -92,6 +92,38 @@ namespace Isis {
    }
  }

  /**
    * Set the empirical Minnaert function phase angle list.  This is the list
    * of phase angles that Minnaert K values and phase curve list values will
    * be provided for. A spline curve will be used to interpolate K values and
    * phase curve values that exist between the given phase angles. The values
    * in the phase angle list are limited to values that are >=0 and <=180.
    *
    * @param phaselist  PvlKeyword containing phase angles to interpolate
    */
  void MinnaertEmpirical::SetPhotoPhaseList(PvlKeyword phaseList) {

    // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5) 
    if (phaseList.size() == 1) {
      SetPhotoPhaseList(QString(phaseList));
      return;
    }

    double phaseAngle;
    p_photoPhaseList.clear();

    for (int i=0; i< phaseList.size(); i++) {
      phaseAngle = phaseList[i].toDouble();

      if (phaseAngle < 0.0 || phaseAngle > 180.0) {
        QString msg = "Invalid value of empirical Minnaert phase angle list value [" +
                          toString(phaseAngle) + "]";
        throw IException(IException::User, msg, _FILEINFO_);
      }
      p_photoPhaseList.push_back(phaseAngle);
    }
  }

  /**
    * Set the empirical Minnaert function K exponent list.  This is used to
    * govern the limb-darkening in the Minnaert photometric function.  Values
@@ -99,7 +131,7 @@ namespace Isis {
    * almost no limb darkening) to 1.0 (Lambert function).  This
    * parameter is limited to values that are >=0.
    *
    * @param klist  List of Minnaert function exponents to interpolate
    * @param kstrlist  List of Minnaert function exponents to interpolate
    */
  void MinnaertEmpirical::SetPhotoKList(QString kstrlist) {
    double kvalue;
@@ -117,6 +149,29 @@ namespace Isis {
    }
  }

  /**
    * Set the empirical Minnaert function K exponent list.  This is used to
    * govern the limb-darkening in the Minnaert photometric function.  Values
    * of the Minnaert exponent generally fall in the range from 0.5 ("lunar-like",
    * almost no limb darkening) to 1.0 (Lambert function).  This
    * parameter is limited to values that are >=0.
    *
    * @param kstrList  PvkKeyword containing List of Minnaert function exponents to interpolate
    */
  void MinnaertEmpirical::SetPhotoKList(PvlKeyword kstrList) {

    // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5) 
    if (kstrList.size() == 1) {
      SetPhotoKList(QString(kstrList));
      return;
    }

    p_photoKList.clear();
    for (int i=0; i<kstrList.size(); i++) {
      p_photoKList.push_back(kstrList[i].toDouble());
    }
  }

  /**
    * Set the empirical Minnaert function phase curve list.  This list provides
    * the brightness values that correspond to the limb-darkening values in the
@@ -135,6 +190,28 @@ namespace Isis {
    }
  }

  /**
    * Set the empirical Minnaert function phase curve list.  This list provides
    * the brightness values that correspond to the limb-darkening values in the
    * empirical Minnaert photometric function.
    *
    * @param phasecurvelist  PvlKeyword containing list of brightness values corresponding 
    * to Minnaert function exponents
    */
  void MinnaertEmpirical::SetPhotoPhaseCurveList(PvlKeyword photocurvestrList) {

    // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5) 
    if (photocurvestrList.size() == 1) {
      SetPhotoPhaseCurveList(QString(photocurvestrList));
      return;
    }

    p_photoPhaseCurveList.clear();
    for (int i=0; i<photocurvestrList.size(); i++) {
      p_photoPhaseCurveList.push_back(photocurvestrList[i].toDouble());
    }
  }

  double MinnaertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
                                       double emission) {
    static double pht_minnaert_empirical;
+3 −0
Original line number Diff line number Diff line
@@ -46,8 +46,11 @@ namespace Isis {
      virtual ~MinnaertEmpirical();

      void SetPhotoPhaseList(QString phasestrlist);
      void SetPhotoPhaseList(PvlKeyword phaselist);
      void SetPhotoKList(QString kstrlist);
      void SetPhotoKList(PvlKeyword kstrlist);
      void SetPhotoPhaseCurveList(QString phasecurvestrlist);
      void SetPhotoPhaseCurveList(PvlKeyword phasecurvestrlist);

      //! Return photometric phase angle list
//      inline std::vector<double> PhotoPhaseList() const {
+24 −0
Original line number Diff line number Diff line
@@ -26,3 +26,27 @@ Albedo = 0.008174
Test phase=180.0, incidence=90.0, emission=90.0 ...
Albedo = 0

Object = PhotometricModel
  Group = Algorithm
    Name           = MinnaertEmpirical
    PhaseList      = (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
                      130, 140)
    KList          = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1,
                      1.2, 1.3, 1.4)
    PhaseCurveList = (0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3, 3.3,
                      3.6, 3.9, 4.2)
  End_Group
End_Object
End

Test phase=0.0, incidence=0.0, emission=0.0 ...
Albedo = 0
Test phase=38.0, incidence=11.0, emission=20.0 ...
Albedo = 1.1765
Test phase=65.0, incidence=45.0, emission=30.0 ...
Albedo = 1.63706
Test phase=127.0, incidence=52.0, emission=33.0 ...
Albedo = 1.96227
Test phase=180.0, incidence=90.0, emission=90.0 ...
Albedo = 0
+59 −0
Original line number Diff line number Diff line
@@ -68,5 +68,64 @@ int main() {
    e.print();
  }

  // Test Keyword = (1,2,3,4,5) format for input
  // 
  // The actual numbers used for this test are not relevant -- this test's primary purpose is to 
  // ensure that this format of input is usable for the calculations done by the class without the 
  // program error-ing out. 
  PvlGroup algOtherFormat("Algorithm");
  algOtherFormat += PvlKeyword("Name", "MinnaertEmpirical");

  PvlKeyword phaseList("PhaseList");
  PvlKeyword kList("KList"); 
  PvlKeyword phaseCurveList("PhaseCurveList");

  for (int i=0; i < 15; i++) {
    phaseList += QString::number(i*10);
    kList += QString::number(i*0.1); 
    phaseCurveList += QString::number(i*0.3);
  }

  algOtherFormat += phaseList; 
  algOtherFormat += kList; 
  algOtherFormat += phaseCurveList; 

  PvlObject photometricModel("PhotometricModel");
  photometricModel.addGroup(algOtherFormat);

  Pvl pvlOtherFormat;
  pvlOtherFormat.addObject(photometricModel);
  std::cout << pvlOtherFormat << std::endl << std::endl;

  try {
    PhotoModel *pm = PhotoModelFactory::Create(pvlOtherFormat);

    std::vector<double>phaselist = pm->PhotoPhaseList();

    std::cout << "Test phase=0.0, incidence=0.0, emission=0.0 ..." <<
              std::endl;
    std::cout << "Albedo = " << pm->CalcSurfAlbedo(0.0, 0.0, 0.0) <<
              std::endl;
    std::cout << "Test phase=38.0, incidence=11.0, emission=20.0 ..." <<
              std::endl;
    std::cout << "Albedo = " << pm->CalcSurfAlbedo(38.0, 11.0, 20.0) <<
              std::endl;
    std::cout << "Test phase=65.0, incidence=45.0, emission=30.0 ..." <<
              std::endl;
    std::cout << "Albedo = " << pm->CalcSurfAlbedo(65.0, 45.0, 30.0) <<
              std::endl;
    std::cout << "Test phase=127.0, incidence=52.0, emission=33.0 ..." <<
              std::endl;
    std::cout << "Albedo = " << pm->CalcSurfAlbedo(127.0, 52.0, 33.0) <<
              std::endl;
    std::cout << "Test phase=180.0, incidence=90.0, emission=90.0 ..." <<
              std::endl;
    std::cout << "Albedo = " << pm->CalcSurfAlbedo(180.0, 90.0, 90.0) <<
              std::endl << std::endl;
  }
  catch(IException &e) {
    e.print();
  }

  return 0;
}