Commit feab4a12 authored by Tyler Wilson's avatar Tyler Wilson
Browse files

PROG: Merging IPCE classes SpiceRotation/Target into ISIS. Unit tests and...

PROG:  Merging IPCE classes SpiceRotation/Target into ISIS.  Unit tests and documentation to follow.  This is to unblock ticket #3997.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@6803 41f8697f-d340-4b68-9986-7bafba869bb8
parent cf346b78
Loading
Loading
Loading
Loading
+995 −57

File changed.

Preview size limit exceeded, changes collapsed.

+195 −15
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <SpiceZfc.h>
#include <SpiceZmc.h>

#include "Angle.h"
#include "Table.h"
#include "Quaternion.h"
#include "PolynomialUnivariate.h"
@@ -183,10 +184,31 @@ namespace Isis {
   *                           New Horizons which had ck's with both type 2 and type 3 segments.
   *   @history 2014-03-11 Stuart Sides - Programmers notes - Fixed a bug in the copy constructor
   *                           that was going out of array bounds.
   *   @history 2015-02-20 Jeannie Backer - Improved error messages.
   *   @history 2015-07-21 Kristin Berry - Added additional NaifStatus::CheckErrors() calls to see if
   *                           any NAIF errors were signaled. References #2248.
   *   @history 2015-08-05 Debbie A. Cook - Programmer notes - Modified LoadCache, 
   *                           and ComputeAv.
   *                           Added new methods 
   *                           loadPCFromSpice, loadPCFromTable, toJ2000Partial, poleRaCoefs,
   *                           poleDecCoefs, pmCoefs, poleRaNutPrecCoefs, poleDecNutPrecCoefs, 
   *                           mNutPrecCoefs, sysNutPrecConstants, sysNutPrecCoefs,
   *                           usePckPolynomial, setPckPolynomial(raCoef, decCoef, pmCoef),
   *                           getPckPolynomial, setEphemerisTimePckPolyFunction, getFrameType
   *                           and members m_frameType, m_tOrientationAvailable, 
   *                           m_raPole, m_decPole, m_pm, m_raNutPrec, m_decNutPrec, m_pmNutPrec,
   *                           m_sysNutPrec0, m_sysNutPrec1, m_dscale, m_Tscale  to support request for 
   *                           solving for target body parameters.
   *                           Also added a new enumerated value for Source, PckPolyFunction, 
   *                            and 
   *                           PartialType, WRT_RotationRate.
   *   @history 2016-02-15 Debbie A. Cook - Programmer notes - Added private method
   *                           setFrameType to set the frame type.  It also loads the planetary 
   *                           constants for a PCK type. 
   *
   *  @todo Downsize using Hermite cubic spline and allow Nadir tables to be downsized again.
   *  @todo Consider making this a base class with child classes based on frame type or 
   *              storage type (polynomial, polynomial over cache, cache, etc.)
   */
  class SpiceRotation {
    public:
@@ -210,21 +232,35 @@ namespace Isis {
      /**
       * The rotation can come from one of 3 places for an Isis cube.  The class
       * expects function to be after Memcache.
       *       Spice - the rotation is calculated by Naif Spice routines with data 
       *                  read directly from Naif kernels.
       *       Nadir - the rotation is calculated using the Naif routine twovec with 
       *                  the position and velocity vectors of the spacecraft.
       *       Memcache - the rotation is linearly interpolated from time-based 
       *                  values in a table.
       *       PolyFunction - the rotation is calculated from an nth degree 
       *                  polynomial in one variable (time in scaled seconds)
       *       PolyFunctionOverSpice - the rotation is calculated from an nth
       *                  degree polynomial fit over the Naif Spice results.
       *       PckPolyFunction - The rotation is calculated using the IAU fit 
       *                  polynomials in one variable (time in Julian centuries and days).
       */
      enum Source { Spice,                              //!< Directly from the kernels 
                               Nadir,                   //!< Nadir pointing
                               Memcache,                //!< From cached table
                               PolyFunction,            //!< From nth degree polynomial
                    PolyFunctionOverSpice   //!< Kernels plus nth degree 
                  };                          //   polynomial
                               PolyFunctionOverSpice ,  //!< Kernels plus nth degree polynomial 
                               PckPolyFunction          //!< Quadratic polynomial function with
                                                        //   linear trignometric terms
                  };            

      /** 
       * This enumeration indicates whether the partial derivative is taken with 
       * respect to Right Ascension, Declination, or Twist. 
       * respect to Right Ascension, Declination, or Twist (or Rotation). 
       */ 
      enum PartialType { WRT_RightAscension, //!< With respect to Right Ascension
                         WRT_Declination,    //!< With respect to Declination
                         WRT_Twist           //!< With respect to Twist
                         WRT_Twist          //!< With respect to Twist or Prime Meridian Rotation
                       };

      /** 
@@ -238,11 +274,14 @@ namespace Isis {
      /** 
       *  
       */ 
      enum NaifFrameType { INERTL = 1,       //!< 
                           PCK = INERTL + 1, //!< 
                           CK = PCK + 1,     //!< 
                           TK = CK + 1,      //!< 
                           DYN = TK + 1      //!< 
      enum FrameType {UNKNOWN = 0,  // Isis specific code for unknown frame type
                           INERTL = 1,       //!< See Naif Frames.req document for 
                           PCK  = 2,         //!< definitions
                           CK = 3,           //!< 
                           TK = 4,           //!< 
                           DYN = 5,          //!<
                           BPC = 6,          //!< Isis specific code for binary pck
                           NOTJ2000PCK = 7   //!< PCK frame not referenced to J2000
      };                                   

      void SetEphemerisTime(double et);
@@ -265,10 +304,29 @@ namespace Isis {

      std::vector<double> J2000Vector(const std::vector<double>& rVec);

      std::vector<Angle> poleRaCoefs();

      std::vector<Angle> poleDecCoefs();

      std::vector<Angle> pmCoefs();

      std::vector<double> poleRaNutPrecCoefs();

      std::vector<double> poleDecNutPrecCoefs();

      std::vector<double> pmNutPrecCoefs();

      std::vector<Angle> sysNutPrecConstants();

      std::vector<Angle> sysNutPrecCoefs();

      std::vector<double> ReferenceVector(const std::vector<double>& jVec);

      std::vector<double> EvaluatePolyFunction();

      void loadPCFromSpice(int CenterBodyCode);
      void loadPCFromTable(const PvlObject &Label);

      void MinimizeCache(DownsizeStatus status);

      void LoadCache(double startTime, double endTime, int size);
@@ -287,6 +345,7 @@ namespace Isis {
      void LoadTimeCache();

      std::vector<double> Angles(int axis3, int axis2, int axis1);
      void SetAngles(std::vector<double> angles, int axis3, int axis2, int axis1);

      bool IsCached() const;

@@ -297,24 +356,40 @@ namespace Isis {
                         const std::vector<double>& abcAng3,
                         const Source type = PolyFunction);

      void usePckPolynomial();
      void setPckPolynomial(const std::vector<Angle>& raCoeff,
                            const std::vector<Angle>& decCoeff,
                            const std::vector<Angle>& pmCoeff);

      void GetPolynomial(std::vector<double>& abcAng1,
                         std::vector<double>& abcAng2,
                         std::vector<double>& abcAng3);

      void getPckPolynomial(std::vector<Angle>& raCoeff,
                            std::vector<Angle>& decCoeff,
                            std::vector<Angle>& pmCoeff);

      // Set the polynomial degree
      void SetPolynomialDegree(int degree);
      Source GetSource();
      void SetSource(Source source);
      void ComputeBaseTime();
      FrameType getFrameType();
      double GetBaseTime();
      double GetTimeScale();

      void SetOverrideBaseTime(double baseTime, double timeScale);

      // Derivative methods
      double DPolynomial(const int coeffIndex);
      double DPckPolynomial(PartialType partialVar, const int coeffIndex);

      std::vector<double> toJ2000Partial(const std::vector<double>& lookT,
                                             PartialType partialVar, int coeffIndex);
      std::vector<double> ToReferencePartial(std::vector<double>& lookJ,
                                             PartialType partialVar, int coeffIndex);
      void DCJdt(std::vector<double> &dRJ);

      double WrapAngle(double compareAngle, double angle);
      void SetAxes(int axis1, int axis2, int axis3);
      std::vector<double> GetFullCacheTime();
@@ -324,20 +399,21 @@ namespace Isis {
      std::vector<int>  ConstantFrameChain();
      std::vector<int>  TimeFrameChain();
      void InitConstantRotation(double et);
      void DCJdt(std::vector<double> &dRJ);
      bool HasAngularVelocity();

      void ComputeAv();
      std::vector<double> Extrapolate(double timeEt);

      void checkForBinaryPck();

    protected:
      void SetFullCacheParameters(double startTime, double endTime, int cacheSize);
      void SetEphemerisTimeMemcache();
      void SetEphemerisTimeNadir();
      void SetEphemerisTimeSpice();
      void SetEphemerisTimePolyFunction();
      void SetEphemerisTimePolyFunctionOverSpice();
      void setEphemerisTimeMemcache();
      void setEphemerisTimeNadir();
      void setEphemerisTimeSpice();
      void setEphemerisTimePolyFunction();
      void setEphemerisTimePolyFunctionOverSpice();
      void setEphemerisTimePckPolyFunction();
      std::vector<double> p_cacheTime;  //!< iTime for corresponding rotation
      std::vector<std::vector<double> > p_cache; /**< Cached rotations, stored as 
                                                      rotation matrix from J2000 
@@ -350,6 +426,8 @@ namespace Isis {
      int p_axis3;                      //!< Axis of rotation for angle 3 of rotation

    private:
      // method
      void setFrameType();
      std::vector<int> p_constantFrames;  /**< Chain of Naif frame codes in constant 
                                               rotation TC. The first entry will always 
                                               be the target frame code*/
@@ -363,7 +441,10 @@ namespace Isis {
                                                                  rotation at et*/

      bool p_matrixSet;                    //!< Flag indicating p_TJ has been set
      bool m_tOrientationAvailable;  //!< Target orientation constants are available
 

      FrameType m_frameType;  //!< The type of rotation frame
      Source p_source;                    //!< The source of the rotation data
      int p_axisP;                        /**< The axis defined by the spacecraft
                                               vector for defining a nadir rotation*/
@@ -398,6 +479,105 @@ namespace Isis {
                                               includes angular velocity*/
      std::vector<double> StateTJ();      /**< State matrix (6x6) for rotating state 
                                               vectors from J2000 to target frame*/
      // The remaining items are only used for PCK frame types.  In this case the  
      // rotation is  stored as a cache, but the coefficients are available for display
      // or comparison, and the first three coefficient sets can be solved for and 
      // updated in jigsaw.   The initial coefficient values are read from a Naif PCK.
      //
      // The general equation for the right ascension of the pole is
      //
      // raPole  =  raPole[0] + raPole[1]*Time  + raPole[2]*Time**2 + raNutPrec,
      //    where 
      //    raNutPrec  =  raNutPrec1[0]*sin(sysNutPrec[0][0] + sysNutPrec[0][1]*Time) + 
      //                          raNutPrec1[1]*sin(sysNutPrec[1][0] + sysNutPrec[1][1]*Time) + ...
      //                          raNutPrec1[N-1]*sin(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time) +
      // (optional for multiples of nutation precession angles)
      //                          raNutPrec2[0]*sin(2*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                          raNutPrec2[1]*sin(2*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                          raNutPrec2[N-1]*sin(2*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) + 
      //                          raNutPrecM[0]*sin(M*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                          raNutPrecM[1]*sin(M*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                          raNutPrecM[N-1]*sin(M*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) +
      //
      // The general equation for the declination of the pole is
      //
      // decPole  =  p_decPole[0] + p_decPole[1]*Time  + p_decPole[2]*Time**2 + decNutPrec,
      //    where 
      //    decNutPrec  =  decNutPrec1[0]*cos(sysNutPrec[0][0] + sysNutPrec[0][1]*Time) + 
      //                          decNutPrec1[1]*cos(sysNutPrec[1][0] + sysNutPrec[1][1]*Time) + ...
      //                          decNutPrec1[N-1]*cos(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time) +
      //                          decNutPrec2[0]*cos(2*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                          decNutPrec2[1]*cos(2*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                          decNutPrec2[N-1]*cos(2*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) +
      // (optional for multiples of nutation precession angles)
      //                          decNutPrecM[0]*sin(M*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                          decNutPrecM[1]*sin(M*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                          decNutPrecM[N-1]*sin(M*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) 
      //
      //     and Time is julian centuries since J2000.
      //
      // The general equation for the prime meridian rotation is
      //
      // pm  =  p_pm[0] + p_pm[1]*Dtime  + p_pm[2]*Dtime**2 + pmNutPrec,
      //    where 
      //    pmNutPrec  =  pmNutPrec1[0]*sin(sysNutPrec[0][0] + sysNutPrec[0][1]*Time) + 
      //                            pmNutPrec1[1]*sin(sysNutPrec[1][0] + sysNutPrec[1][1]*Time) + ...
      //                            pmNutPrec1[N-1]*sin(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time) +
      // (optional for multiples of nutation precession angles)
      //                            pmNutPrec2[0]*sin(2*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                            pmNutPrec2[1]*sin(2*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                            pmNutPrec2[N-1]*sin(2*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) +
      //                            pmNutPrecM[0]*sin(M*(sysNutPrec[0][0] + sysNutPrec[0][1]*Time)) +
      //                            pmNutPrecM[1]*sin(M*(sysNutPrec[1][0] + sysNutPrec[1][1]*Time)) + ...
      //                            pmNutPrecM[N-1]*sin(M*(sysNutPrec[N-1][0] + sysNutPrec[N-1][1]*Time)) 
      //
      //     Time is interval in Julian centuries since the standard epoch, 
      //     dTime is interval in days from the standard epoch (J2000),
      //
      //     N is the number of nutation/precession terms for the planetary system of the target 
      //     body,  (possibly including multiple angles as unique terms, 
      //                                                   ie. 2*sysNutPrec[0][0] + sysNutPrec[][1]*Time).
      //
      //     Many of the constants in this equation are 0. for a given body.
      //
      //     M is included as an option for future improvements.  M = highest multiple (period) 
      //     of any of the nutation/precession angles included in the equations.
      //
      //     ***NOTE*** Currently Naif stores multiples (amplitudes) as if they were additional 
      //                       nutation/precession terms (periods) in the equation.  This method works as 
      //                       long as jigsaw does not solve for those values.  In order to solve for 
      //                       those values, the multiples will need to be known so that the partial 
      //                       derivatives can be correctly calculated.  Some possible ways of doing this
      //                       are 1) Convince Naif to change their data format indicating the relation
      //                             2) Make an Isis version of the PCK data and have Isis software to
      //                                 calculate the rotation and partials.
      //                             3) Have an Isis addendum file that identifies the repeated periods
      //                                 and software to apply them when calculating the rotation and partials.
      //
      //                       For now this software will handle any terms with the same period and different
      //                       amplitudes as unique terms in the equation (raNutPrec, decNutPrec, 
      //                       and pmNutPrec).
      //
      // The next three vectors will have length 3 (for a quadratic polynomial) if used.
      std::vector<Angle>m_raPole;        //!< Coefficients of a quadratic polynomial fitting pole ra
      std::vector<Angle>m_decPole;      //!< Coefficients of a quadratic polynomial fitting pole dec
      std::vector<Angle>m_pm ;             //!< Coefficients of a quadratic polynomial fitting pole pm
      //
      // Currently multiples (terms with periods matching other terms but varying amplitudes) 
      // are handled as additional terms added to the end of the vector as Naif does (see 
      // comments in any of the standard Naif PCK. 
      std::vector<double>m_raNutPrec;    //!< Coefficients of pole right ascension nut/prec terms.  
      std::vector<double>m_decNutPrec;  //!< Coefficients of pole decliniation nut/prec terms. 
      std::vector<double>m_pmNutPrec;   //!< Coefficients of prime meridian nut/prec terms.  

      // The periods of bodies in the same system are modeled with a linear equation
      std::vector<Angle>m_sysNutPrec0; //!< Constants of planetary system nut/prec periods
      std::vector<Angle>m_sysNutPrec1; //!< Linear terms of planetary system nut/prec periods

      // The following scalers are used in the IAU equations to convert p_et to the appropriate time
      // units for calculating target body ra, dec, and w.  These need to be initialized in every constructor.
      static const double m_centScale;   //!<  Seconds per Julian century for scaling time in seconds *** may need to put static in front of const
      static const double m_dayScale;    //!< Seconds per day for scaling time in seconds to get target body w
  };
};

+9 −9
Original line number Diff line number Diff line
@@ -29,15 +29,15 @@ int main(int argc, char *argv[]) {
  QString pck(dir + "pck00006.tpc");
  //QString mocadd(dir+"mocAddendum.ti");
  QString mocspice(dir + "mocSpiceRotationUnitTest.ti");
  furnsh_c(naif.toAscii().data());
  furnsh_c(mgs.toAscii().data());
  furnsh_c(mocti.toAscii().data());
  furnsh_c(mocbc.toAscii().data());
  furnsh_c(mocbsp.toAscii().data());
  furnsh_c(de.toAscii().data());
  furnsh_c(pck.toAscii().data());
//  furnsh_c(mocadd.toAscii().data());
  furnsh_c(mocspice.toAscii().data());
  furnsh_c(naif.toLatin1().data());
  furnsh_c(mgs.toLatin1().data());
  furnsh_c(mocti.toLatin1().data());
  furnsh_c(mocbc.toLatin1().data());
  furnsh_c(mocbsp.toLatin1().data());
  furnsh_c(de.toLatin1().data());
  furnsh_c(pck.toLatin1().data());
//  furnsh_c(mocadd.toLatin1().data());
  furnsh_c(mocspice.toLatin1().data());

  double startTime = -69382819.0;
  double endTime = -69382512.0;
+97 −6
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
 */
#include "Target.h"

#include "Angle.h"
#include "Distance.h"
#include "EllipsoidShape.h"
#include "FileName.h"
@@ -54,6 +55,7 @@ namespace Isis {
    // Initialize members
    init();
    m_bodyCode = new SpiceInt;
    m_systemCode = new SpiceInt;
    m_radii.resize(3, Distance());

      m_spice = spice;
@@ -65,7 +67,12 @@ namespace Isis {
    m_name = new QString;
    *m_name = inst["TargetName"][0];
    QString trykey = "NaifIkCode";
    if (kernels.hasKeyword("NaifFrameCode")) trykey = "NaifFrameCode";

    m_systemName = new QString;

    if (kernels.hasKeyword("NaifFrameCode")) {
      trykey = "NaifFrameCode";
    }

    if (name().toUpper() == "SKY") {
      m_radii[0] = m_radii[1] = m_radii[2] = Distance(1000.0, Distance::Meters);
@@ -73,12 +80,26 @@ namespace Isis {
      int ikCode = toInt(kernels[trykey][0]);
      *m_bodyCode  = ikCode / 1000;
      // Check for override in kernel group
      if (kernels.hasKeyword("NaifSpkCode"))
      if (kernels.hasKeyword("NaifSpkCode")) {
        *m_bodyCode = (int) kernels["NaifSpkCode"];
      }

      *m_systemCode = -1;
      (*m_systemName).append("THE COSMOS");

    }
    else {
      *m_bodyCode = lookupNaifBodyCode(lab);
      m_sky = false;

      *m_systemCode = (*m_bodyCode/100)*100 + 99;

      SpiceChar naifBuf[40];
      SpiceBoolean found;
      bodc2n_c((SpiceInt) *m_systemCode, sizeof(naifBuf), naifBuf, &found);
      string s(naifBuf);
      (*m_systemName).append(s.c_str());

      // QString radiiKey = "BODY" + QString((BigInt) naifBodyCode()) + "_RADII";
      // m_radii[0] = Distance(getDouble(radiiKey, 0), Distance::Kilometers);
      // m_radii[1] = Distance(getDouble(radiiKey, 1), Distance::Kilometers);
@@ -100,10 +121,11 @@ namespace Isis {
   * @internal
   * @history 2012-08-29 Debbie A. Cook - Original version
   */

  Target::Target() {
    m_bodyCode = NULL;
    m_systemCode = NULL;
    m_name = NULL;
    m_systemName = NULL;
    m_spice = NULL;
    init();
  }
@@ -124,7 +146,6 @@ namespace Isis {
  }



  /**
   * Destroys the Target object
   */
@@ -134,9 +155,15 @@ namespace Isis {
    delete m_bodyCode;
    m_bodyCode = NULL;

    delete m_systemCode;
    m_systemCode = NULL;

    delete m_name;
    m_name = NULL;

    delete m_systemName;
    m_systemName = NULL;

    if (m_radii.size() != 0) {
      m_radii.clear();
    }
@@ -207,7 +234,7 @@ namespace Isis {
    NaifStatus::CheckErrors();
    SpiceInt code;
    SpiceBoolean found;
    bodn2c_c(name.toAscii().data(), &code, &found);
    bodn2c_c(name.toLatin1().data(), &code, &found);
    if (!found) {
      QString msg = "Could not convert Target [" + name +
                   "] to NAIF body code";
@@ -400,7 +427,7 @@ namespace Isis {
    QString kernName = kern.expanded();

    if(!pckLoaded) {
      furnsh_c(kernName.toAscii().data());
      furnsh_c(kernName.toLatin1().data());
      pckLoaded = true;
    }
    
@@ -439,12 +466,31 @@ namespace Isis {
  }


  /**
   * This returns the NAIF planet system body code of the target
   *
   * @return @b SpiceInt NAIF system body code
   *
   * e.g. Enceladus is in the Saturn system
   *
   */
  SpiceInt Target::naifPlanetSystemCode() const {
    return *m_systemCode;
  }


  //! Return target name
  QString Target::name() const {
    return *m_name;
  }


  //! Return planet system name
  QString Target::systemName() const {
    return *m_systemName;
  }


  /**
   * Returns the radii of the body in km. The radii are obtained from the
   * appropriate SPICE kernel for the body specified by TargetName in the
@@ -455,6 +501,51 @@ namespace Isis {
  }


  int Target::frameType() {
    return spice()->bodyRotation()->getFrameType();
  }


  std::vector<Angle> Target::poleRaCoefs() {
    return spice()->bodyRotation()->poleRaCoefs();
  }


  std::vector<Angle> Target::poleDecCoefs() {
    return spice()->bodyRotation()->poleDecCoefs();
  }


  std::vector<Angle> Target::pmCoefs() {
    return spice()->bodyRotation()->pmCoefs();
  }


  std::vector<double> Target::poleRaNutPrecCoefs() {
    return spice()->bodyRotation()->poleRaNutPrecCoefs();
  }


  std::vector<double> Target::poleDecNutPrecCoefs() {
    return spice()->bodyRotation()->poleDecNutPrecCoefs();
  }


  std::vector<double> Target::pmNutPrecCoefs() {
    return spice()->bodyRotation()->pmNutPrecCoefs();
  }


  std::vector<Angle> Target::sysNutPrecConstants() {
    return spice()->bodyRotation()->sysNutPrecConstants();
  }


  std::vector<Angle> Target::sysNutPrecCoefs() {
    return spice()->bodyRotation()->sysNutPrecCoefs();
  }


  /**
   * Restores the shape to the original after setShapeEllipsoid has overridden it.
   */
+34 −7
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
 *   http://www.usgs.gov/privacy.html.
 */

#include <QSharedPointer>

#include <vector>

#include <SpiceUsr.h>
@@ -32,6 +34,7 @@
class QString;

namespace Isis {
  class Angle;
  class Distance;
  class Pvl;
  class PvlGroup;
@@ -58,6 +61,7 @@ namespace Isis {
   *                          References #3934.
   */
  class Target {

    public:
      // constructors
      Target(Spice *spice, Pvl &label);
@@ -69,7 +73,9 @@ namespace Isis {
      void init();
      bool isSky() const;
      SpiceInt naifBodyCode() const;
      SpiceInt naifPlanetSystemCode() const;
      QString name() const;
      QString systemName() const;
      std::vector<Distance> radii() const;
      void restoreShape();
      void setShapeEllipsoid();
@@ -77,11 +83,25 @@ namespace Isis {
      ShapeModel *shape() const;
      Spice *spice() const;

      int frameType();

      std::vector<Angle> poleRaCoefs();
      std::vector<Angle> poleDecCoefs();
      std::vector<Angle> pmCoefs();

      static SpiceInt lookupNaifBodyCode(QString name);
      // Static conversion methods
      static PvlGroup radiiGroup(QString target);
      static PvlGroup radiiGroup(Pvl &cubeLab, const PvlGroup &mapGroup);

      std::vector<double> poleRaNutPrecCoefs();
      std::vector<double> poleDecNutPrecCoefs();

      std::vector<double> pmNutPrecCoefs();

      std::vector<Angle> sysNutPrecConstants();
      std::vector<Angle> sysNutPrecCoefs();

    private:
      SpiceInt lookupNaifBodyCode(Pvl &lab) const;
      static PvlGroup radiiGroup(int bodyFrameCode);
@@ -89,17 +109,24 @@ namespace Isis {
                                       labels. Otherwise, if the target is sky,
                                       it's the SPK code and if not sky then it's
                                       calculated by the NaifBodyCode() method.*/
      QString *m_name;   //!< Name of the target
      std::vector<Distance> m_radii; //!< The radii of the target
      ShapeModel *m_originalShape; //!< The shape model of the target
      ShapeModel *m_shape; //!< The shape model of the target
      bool m_sky; //!< Indicates whether the target of the observation is the sky
      SpiceInt *m_systemCode;        /**< The NaifBodyCode of the targets planetary system
                                       If the target is sky, then what should this be???*/
      QString *m_name;               //!< target name
      QString *m_systemName;         //!< name of the planetary system of the target
      std::vector<Distance> m_radii; //!< target radii
      ShapeModel *m_originalShape;   //!< target original shape model
      ShapeModel *m_shape;           //!< target shape model
      bool m_sky;                    //!< flag indicating target is the sky

      // TODO should this be an enum(ring, sky, or naifBody), created Naif body for sky, or ???
      // TODO should the target body kernels go in here too bodyRotation and position??? I don't
      //           think so.  They are SPICE kernels and belong in the Spice class (DAC).  What do others
      //           think.
      Spice *m_spice;     //!< The parent Spice object.  This is needed to get pixel resolution in ShapeModels
  };
      Spice *m_spice;                /**< parent Spice object, needed to get pixel resolution in
                                       ShapeModels*/
  };

  typedef QSharedPointer<Target> TargetQsp;
}

#endif