Commit a630a813 authored by Kristin's avatar Kristin Committed by Stuart Sides
Browse files

Update photomet's LunarLambertEmperical model to handle PVL input in photemplate format. (#3614)

* Update LunarLambertEmpherical model to handle frompvl input with values of the form PvlKeyword = (1,2,3,3,4) in addition to  PvlKeyword = 1,2,3,3,4

* Added tests for new functionality
parent 8cda49e6
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ namespace Isis {
    p_photoPhaseCurveList.clear();
  }


  /**
    * Set the empirical Lunar Lambert function phase angle list.  This is the list
    * of phase angles that Lunar Lambert L values and phase curve list values will
@@ -86,6 +87,40 @@ namespace Isis {
    }
  }


  /**
    * Set the empirical Lunar Lambert function phase angle list.  This is the list
    * of phase angles that Lunar Lambert L values and phase curve list values will
    * be provided for. A spline curve will be used to interpolate L 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 LunarLambertEmpirical::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 Lunar Lambert phase angle list value [" +
                          toString(phaseAngle) + "]";
        throw IException(IException::User, msg, _FILEINFO_);
      }
      p_photoPhaseList.push_back(phaseAngle);
    }
  }


  /**
    * Set the empirical Lunar Lambert function L exponent list.  This is used to
    * govern the limb-darkening in the Lunar Lambert photometric function.  Values
@@ -107,6 +142,32 @@ namespace Isis {
    }
  }


  /**
    * Set the empirical Lunar Lambert function L exponent list.  This is used to
    * govern the limb-darkening in the Lunar Lambert photometric function.  Values
    * of the Lunar Lambert exponent generally fall in the range from 0.0
    * (Lambert function) to 1.0 (Lommel-Seeliger or "lunar" function). There are
    * no limits on the value of this parameter, but values far outside the 0 to 1
    * range will not be very useful.
    *
    * @param llist  PvkKeyword containing List of Lunar Lambert function exponents to interpolate
    */
  void LunarLambertEmpirical::SetPhotoLList(PvlKeyword lstrList) {

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

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


  /**
    * Set the empirical Lunar Lambert function phase curve list.  This list provides
    * the brightness values that correspond to the limb-darkening values in the
@@ -125,6 +186,30 @@ namespace Isis {
    }
  }


  /**
    * Set the empirical Lunar Lambert function phase curve list.  This list provides
    * the brightness values that correspond to the limb-darkening values in the
    * empirical Lunar Lambert photometric function.
    *
    * @param phasecurvelist  PvlKeyword containing list of brightness values corresponding 
    * to Lunar Lambert function exponents
    */
  void LunarLambertEmpirical::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 LunarLambertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
                                       double emission) {
    static double pht_lunarlambert_empirical;
+7 −0
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ namespace Isis {
   *
   * @internal
   *  @history 2011-08-17 Janet Barrett - Ported from ISIS2 to ISIS3.
   *  @history 2019-12-19 Kristin Berry - Updated to add support for PvlKeywords to
   *                         SetPhotoPhaseList, SetPhotoLList, and SetPhotoPhaseCurveList
   *                         Fixes #3608, this allows photomet to work with this model
   *                         using FROMPVL, rather than specifying the lists directly. 
   */
  class LunarLambertEmpirical : public PhotoModel {
    public:
@@ -62,8 +66,11 @@ namespace Isis {
      virtual ~LunarLambertEmpirical();

      void SetPhotoPhaseList(QString phasestrlist);
      void SetPhotoPhaseList(PvlKeyword phaselist); 
      void SetPhotoLList(QString kstrlist);
      void SetPhotoLList(PvlKeyword lstrList);
      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.0087672
Test phase=180.0, incidence=90.0, emission=90.0 ...
Albedo = -0

Object = PhotometricModel
  Group = Algorithm
    Name           = LunarLambertEmpirical
    PhaseList      = (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
                      130, 140)
    LList          = (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.13647
Test phase=65.0, incidence=45.0, emission=30.0 ...
Albedo = 1.62206
Test phase=127.0, incidence=52.0, emission=33.0 ...
Albedo = 3.4634
Test phase=180.0, incidence=90.0, emission=90.0 ...
Albedo = 9.72
+59 −0
Original line number Diff line number Diff line
@@ -62,5 +62,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", "LunarLambertEmpirical");

  PvlKeyword phaseList("PhaseList");
  PvlKeyword lList("LList"); 
  PvlKeyword phaseCurveList("PhaseCurveList");

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

  algOtherFormat += phaseList; 
  algOtherFormat += lList; 
  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;
}