Commit 8cda49e6 authored by Kelvin Rodriguez's avatar Kelvin Rodriguez Committed by Stuart Sides
Browse files

updated lronacal to compute sun to body distance from cached ephem data (#3611)

* updated lronacal to compute sun -> body distance from cached ephem data

* removed forced exception

* added basic Spice test

* Added doc string to Spice::Spice(PVL, json) and removed debug print
parent 9d5f3002
Loading
Loading
Loading
Loading
+38 −19
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ namespace Isis {
    Pvl &lab = *cube.label();
    PvlGroup kernels = lab.findGroup("Kernels", Pvl::Traverse);
    bool hasTables = (kernels["TargetPosition"][0] == "Table");
    init(cube, !hasTables);
    init(lab, !hasTables);
  }

  /**
@@ -90,7 +90,18 @@ namespace Isis {
   * @param noTables Indicates the use of tables.
   */
  Spice::Spice(Cube &cube, bool noTables) {  
    init(cube, noTables);
    init(*cube.label(), noTables);
  }
 

  /**
   * Constructs a Spice Object
   *
   * @param lab Isis Cube Pvl Lavel
   * @param isd ALE Json ISD
   */
  Spice::Spice(Pvl &lab, json isd) {
    init(lab, true, isd);
  }

  /**
@@ -106,7 +117,7 @@ namespace Isis {
   * @internal
   *   @history 2011-02-08 Jeannie Walldren - Initialize pointers to null.
   */
  void Spice::init(Cube &cube, bool noTables) {
  void Spice::init(Pvl &lab, bool noTables, json isd) {
    NaifStatus::CheckErrors();
    
    // Initialize members
@@ -142,8 +153,6 @@ namespace Isis {

    // m_sky = false;
    
    Pvl &lab = *cube.label();
   
    // Get the kernel group and load main kernels
    PvlGroup kernels = lab.findGroup("Kernels", Pvl::Traverse);

@@ -166,7 +175,6 @@ namespace Isis {
    m_usingNaif = !lab.hasObject("NaifKeywords") || noTables;
    m_usingAle = false; 

    json isd; 
    //  Modified  to load planetary ephemeris SPKs before s/c SPKs since some
    //  missions (e.g., MESSENGER) may augment the s/c SPK with new planet
    //  ephemerides. (2008-02-27 (KJB))
@@ -179,6 +187,7 @@ namespace Isis {
          throw IException(IException::Programmer, msg, _FILEINFO_);
        }
        
        if (isd == NULL){
          // try using ALE
          std::ostringstream kernel_pvl;
          kernel_pvl << kernels;
@@ -186,7 +195,9 @@ namespace Isis {
          json props;
          props["kernels"] = kernel_pvl.str();

        isd = ale::load(cube.fileName().toStdString(), props.dump(), "isis");
          isd = ale::load(lab.fileName().toStdString(), props.dump(), "isis");
        }

        json aleNaifKeywords = isd["NaifKeywords"];
        m_naifKeywords = new PvlObject("NaifKeywords", aleNaifKeywords);
        
@@ -231,7 +242,6 @@ namespace Isis {
        }
      }
     
     
      // Moved the construction of the Target after the NAIF kenels have been loaded or the 
      // NAIF keywords have been pulled from the cube labels, so we can find target body codes 
      // that are defined in kernels and not just body codes build into spicelib
@@ -387,7 +397,6 @@ namespace Isis {
      m_bodyRotation->LoadCache(isd["BodyRotation"]);
      solarLongitude();
    }

    //  We can't assume InstrumentPointing & InstrumentPosition exist, old
    //  files may be around with the old keywords, SpacecraftPointing &
    //  SpacecraftPosition.  The old keywords were in existance before the
@@ -435,7 +444,6 @@ namespace Isis {
    NaifStatus::CheckErrors();
  } 


  /**
   * Loads/furnishes NAIF kernel(s)
   *
@@ -1340,6 +1348,17 @@ namespace Isis {
  }
  
  
  double Spice::sunToBodyDist() const {
    std::vector<double> sunPosition = m_sunPosition->Coordinate();
    std::vector<double> bodyRotation = m_bodyRotation->Matrix();
    
    double sunPosFromTarget[3];
    mxv_c(&bodyRotation[0], &sunPosition[0], sunPosFromTarget);
        
    return vnorm_c(sunPosFromTarget);  
  }


  /**
   * Computes the solar longitude for the given ephemeris time.  If the target
   * is sky, the longitude is set to -999.0.
+5 −2
Original line number Diff line number Diff line
@@ -296,6 +296,7 @@ namespace Isis {
      // constructors
      Spice(Cube &cube);
      Spice(Cube &cube, bool noTables);
      Spice(Pvl &lab, nlohmann::json);

      // destructor
      virtual ~Spice();
@@ -306,6 +307,8 @@ namespace Isis {
      void instrumentBodyFixedPosition(double p[3]) const;
      void sunPosition(double p[3]) const;
      double targetCenterDistance() const;
      double sunToBodyDist() const;
      
      Longitude solarLongitude();
      void instrumentBodyFixedVelocity(double v[3]) const;
      iTime time() const;
@@ -393,7 +396,7 @@ namespace Isis {
      Spice(const Spice &other);
      Spice &operator=(const Spice &other);
  
      void init(Cube &cube, bool noTables);
      void init(Pvl &pvl, bool noTables, nlohmann::json isd = NULL);

      void load(PvlKeyword &key, bool notab);
      void computeSolarLongitude(iTime et);
+36 −24
Original line number Diff line number Diff line
@@ -196,8 +196,19 @@ void IsisMain() {
    Pvl radPvl(radFileName.expanded());

    if(g_iof) {
      try {
      iTime startTime((QString) inst["StartTime"]);
      
      try {
        Camera *cam; 
        cam = iCube->camera();
        cam->setTime(startTime);
        g_solarDistance = cam->sunToBodyDist() / KM_PER_AU; 
        
      }
      catch(IException &e) {
        // Failed to instantiate a camera, try furnishing kernels directly 
        try {

          double etStart = startTime.Et();
          // Get the distance between the Moon and the Sun at the given time in
          // Astronomical Units (AU)
@@ -224,6 +235,7 @@ void IsisMain() {
          QString msg = "Unable to find the necessary SPICE kernels for converting to IOF";
          throw IException(e, IException::User, msg, _FILEINFO_);
        }
      }
      g_iofLeft = radPvl["IOF_LEFT"];
      g_iofRight = radPvl["IOF_RIGHT"];
    }
+194 −0
Original line number Diff line number Diff line
#include "Spice.h"
#include "IException.h"
#include "Pvl.h"
#include "Distance.h"
#include "iTime.h"
#include "Longitude.h"

#include <QString>
#include <iostream>

#include <nlohmann/json.hpp>
using json = nlohmann::json;

#include "gmock/gmock.h"

using namespace Isis;

class ConstVelIsd : public ::testing::Test {
  protected:
  json constVelIsdStr; 
  Pvl isisLabel; 

  void SetUp() {
    constVelIsdStr = json::parse(R"(
    {"CameraVersion": 2,
         "NaifKeywords": {
           "BODY301_RADII": [ 1000, 2000, 3000 ],
           "BODY_FRAME_CODE": 31001,
           "BODY_CODE": 301,
           "INS-85600_FOCAL_LENGTH" : 699.62,
           "INS-85600_CK_FRAME_ID": -85000,
           "FRAME_-85600_NAME": "LRO_LROCNACL"
       },
    "InstrumentPointing": {
      "TimeDependentFrames": [-85600, -85000, 1],
      "CkTableStartTime": 100,
      "CkTableEndTime": 100.1,
      "CkTableOriginalSize": 2,
      "EphemerisTimes": [
        100,
        100.1
      ],
      "Quaternions": [
        [0.0, -0.660435174378928, 0, 0.750883067090392],
        [0.0, -0.660435174378928, 0, 0.750883067090392]
      ],
      "AngularVelocity": [
        [0, 0, 0],
        [0, 0, 0]
      ],
      "ConstantFrames": [-85600],
      "ConstantRotation": [1, 0, 0, 0, 1, 0, 0, 0, 1]
    },
    "BodyRotation": {
      "TimeDependentFrames": [31006, 1],
      "CkTableStartTime": 100,
      "CkTableEndTime": 100.1,
      "CkTableOriginalSize": 2,
      "EphemerisTimes": [
        100,
        100.1
      ],
      "Quaternions": [
        [ 0, 0.8509035, 0, 0.525322 ],
        [ 0, 0.8509035, 0, 0.525322 ]
      ],
      "AngularVelocity": [
        [0, 0, 0],
        [0, 0, 0]
      ],
      "ConstantFrames": [31001, 31007, 31006],
      "ConstantRotation": [-0.4480736,  0,  0.8939967, 0,  1,  0, -0.8939967,  0, -0.4480736]
    },
    "InstrumentPosition": {
      "SpkTableStartTime": 100,
      "SpkTableEndTime": 100.1,
      "SpkTableOriginalSize": 2,
      "EphemerisTimes": [
        100,
        100.1
      ],
      "Positions": [
        [1000, 0, 0],
        [1000, 0, 0]
      ],
      "Velocities": [
        [0, 0, 0],
        [0, 0, 0]
      ]
    },
    "SunPosition": {
      "SpkTableStartTime": 100,
      "SpkTableEndTime": 100.1,
      "SpkTableOriginalSize": 2,
      "EphemerisTimes": [
        100,
        100.1
      ],
      "Positions": [
        [0, 20, 0]
      ],
      "Velocities": [
        [10,10,10]
      ]
    }
  })");

  std::istringstream isisLabelStr(R"(
    Object = IsisCube
      Object = Core
        StartByte   = 65537
        Format      = Tile
        TileSamples = 128
        TileLines   = 128
        
        Group = Dimensions
          Samples = 126
          Lines   = 126
          Bands   = 2
        End_Group

        Group = Pixels
          Type       = Real
          ByteOrder  = Lsb
          Base       = 0.0
          Multiplier = 1.0
        End_Group
      End_Object

      Group = Kernels
          NaifFrameCode = 310019
          LeapSecond                = NULL
          TargetAttitudeShape       = NULL
          TargetPosition            = NULL
          InstrumentPointing        = NULL
          Instrument                = NULL 
          SpacecraftClock           = NULL 
          InstrumentPosition        = NULL
          InstrumentAddendum        = NULL
          ShapeModel                = NULL
          InstrumentPositionQuality = NULL
          InstrumentPointingQuality = NULL
          CameraVersion             = NULL
      End_Group

      Group = Instrument
          SpacecraftName = NULL  
          InstrumentId   = NULL 
          TargetName     = NULL 
      End_Group
    End_Object

    Object = Label
      Bytes = 65536
    End_Object

    Object = History
      Name      = IsisCube
      StartByte = 196609
      Bytes     = 695
    End_Object
    End
  )"); 
  
  isisLabelStr >> isisLabel;

  }
};

TEST_F(ConstVelIsd, TestSpiceFromIsd) {
  Spice testSpice(isisLabel, constVelIsdStr); 
  testSpice.setTime(100); 
  
  EXPECT_DOUBLE_EQ(testSpice.time().Et(), 100);

  EXPECT_DOUBLE_EQ(testSpice.getDouble("INS-85600_FOCAL_LENGTH"), 699.62);
  EXPECT_STREQ(testSpice.getString("FRAME_-85600_NAME").toStdString().c_str(), "LRO_LROCNACL");
  EXPECT_EQ(testSpice.getInteger("INS-85600_CK_FRAME_ID"), -85000);
  
  Distance radii[3];
  testSpice.radii(radii);
  EXPECT_DOUBLE_EQ(radii[0].kilometers(), 1000);
  EXPECT_DOUBLE_EQ(radii[1].kilometers(), 2000);
  EXPECT_DOUBLE_EQ(radii[2].kilometers(), 3000);
  
  EXPECT_DOUBLE_EQ(testSpice.solarLongitude().positiveEast(), 3.1415926535897931);
  
}

TEST_F(ConstVelIsd, SunToBodyDist) {   
  Spice testSpice(isisLabel, constVelIsdStr); 
  EXPECT_DOUBLE_EQ(testSpice.sunToBodyDist(), 20);
}