From ac11b26fe9a3671231b7c3f5e4276dfc62bf9d37 Mon Sep 17 00:00:00 2001 From: acpaquette Date: Wed, 8 Jul 2020 14:26:23 -0700 Subject: [PATCH] ALE Spice Reduction (#3940) * Reduced incoming ALE ephemeris data to be in the same source state as it would be from an ISIS spiceinit * Fixed keys accessing ale json * Minor doc string fix * Updated test for SpicePosition to check the cache size * Updated SpiceRotation unit test to check the cache size * Updated linux truth data * Added zerod out angular velocities to the spice rotation unit test * Updated mac 10.13 truth data * Updated angular velocity unit test * Updated linux truth data * Updated mac 10.15 truth data * Updated linux truth again * One more change to linux truth data * Re-add space to SpiceRotation truth data Co-authored-by: Jesse Mapel --- isis/src/base/objs/Spice/Spice.cpp | 148 ++++++++++-------- .../base/objs/SpicePosition/SpicePosition.h | 5 + .../objs/SpicePosition/SpicePosition.truth | 1 + isis/src/base/objs/SpicePosition/unitTest.cpp | 1 + .../base/objs/SpiceRotation/SpiceRotation.cpp | 4 +- .../base/objs/SpiceRotation/SpiceRotation.h | 4 + .../objs/SpiceRotation/SpiceRotation.truth | 1 + ...ceRotation_Darwin_x86_64_MacOSX10_13.truth | 1 + ...ceRotation_Darwin_x86_64_MacOSX10_15.truth | 1 + isis/src/base/objs/SpiceRotation/unitTest.cpp | 9 +- 10 files changed, 102 insertions(+), 73 deletions(-) diff --git a/isis/src/base/objs/Spice/Spice.cpp b/isis/src/base/objs/Spice/Spice.cpp index 235404dd7f..9b45ccfa0f 100644 --- a/isis/src/base/objs/Spice/Spice.cpp +++ b/isis/src/base/objs/Spice/Spice.cpp @@ -89,10 +89,10 @@ namespace Isis { * @param lab Pvl labels. * @param noTables Indicates the use of tables. */ - Spice::Spice(Cube &cube, bool noTables) { + Spice::Spice(Cube &cube, bool noTables) { init(*cube.label(), noTables); } - + /** * Constructs a Spice Object @@ -121,7 +121,7 @@ namespace Isis { NaifStatus::CheckErrors(); // Initialize members m_solarLongitude = new Longitude; - + m_et = NULL; m_kernels = new QVector; @@ -151,7 +151,7 @@ namespace Isis { m_naifKeywords = new PvlObject("NaifKeywords"); // m_sky = false; - + // Get the kernel group and load main kernels PvlGroup kernels = lab.findGroup("Kernels", Pvl::Traverse); @@ -168,11 +168,11 @@ namespace Isis { } else { *m_endTimePadding = 0.0; - } + } - // We should remove this completely in the near future + // We should remove this completely in the near future m_usingNaif = !lab.hasObject("NaifKeywords") || noTables; - m_usingAle = false; + m_usingAle = false; // 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 @@ -185,7 +185,7 @@ namespace Isis { QString msg = "Falling back to ISIS generation of nadir pointing"; throw IException(IException::Programmer, msg, _FILEINFO_); } - + if (isd == NULL){ // try using ALE std::ostringstream kernel_pvl; @@ -196,17 +196,17 @@ namespace Isis { isd = ale::load(lab.fileName().toStdString(), props.dump(), "ale"); } - + json aleNaifKeywords = isd["naif_keywords"]; m_naifKeywords = new PvlObject("NaifKeywords", aleNaifKeywords); - - // Still need to load clock kernels for now + + // Still need to load clock kernels for now load(kernels["LeapSecond"], noTables); if ( kernels.hasKeyword("SpacecraftClock")) { load(kernels["SpacecraftClock"], noTables); } - m_usingAle = true; - } + m_usingAle = true; + } catch(...) { // Backup to stadnard ISIS implementation if (noTables) { @@ -227,12 +227,12 @@ namespace Isis { if (kernels.hasKeyword("InstrumentAddendum")) { load(kernels["InstrumentAddendum"], noTables); } - - // Still need to load clock kernels for now + + // Still need to load clock kernels for now load(kernels["LeapSecond"], noTables); if ( kernels.hasKeyword("SpacecraftClock")) { load(kernels["SpacecraftClock"], noTables); - } + } // Modified to load extra kernels last to allow overriding default values // (2010-04-07) (DAC) @@ -240,14 +240,14 @@ namespace Isis { load(kernels["Extra"], noTables); } } - - // 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 + + // 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 // TODO: Move this below the else once the rings code below has been refactored m_target = new Target(this, lab); - // This should not be here. Consider having spiceinit add the necessary rings kernels to the + // This should not be here. Consider having spiceinit add the necessary rings kernels to the // Extra parameter if the user has set the shape model to RingPlane. // If Target is Saturn and ShapeModel is RingPlane, load the extra rings pck file // which changes the prime meridian values to report longitudes with respect to @@ -259,9 +259,9 @@ namespace Isis { } else { *m_naifKeywords = lab.findObject("NaifKeywords"); - - // 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 + + // 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 // TODO: Move this below the else once the rings code above has been refactored m_target = new Target(this, lab); @@ -344,7 +344,7 @@ namespace Isis { QString naifTarget = "IAU_" + m_target->name().toUpper(); namfrm_c(naifTarget.toLatin1().data(), &frameCode); if (frameCode == 0) { - QString msg = "Can not find NAIF BODY_FRAME_CODE for target [" + QString msg = "Can not find NAIF BODY_FRAME_CODE for target [" + m_target->name() + "]"; throw IException(IException::Io, msg, _FILEINFO_); } @@ -360,10 +360,10 @@ namespace Isis { m_bodyRotation = new SpiceRotation(frameCode); *m_bodyFrameCode = frameCode; } - + m_instrumentRotation = new SpiceRotation(*m_ckCode); - // Set up for observer/target and light time correction to between s/c + // Set up for observer/target and light time correction to between s/c // and target body. LightTimeCorrectionState ltState(*m_ikCode, this); ltState.checkSpkKernelsForAberrationCorrection(); @@ -374,13 +374,20 @@ namespace Isis { ltState, targetRadius); m_sunPosition = new SpicePosition(10, m_target->naifBodyCode()); - + // Check to see if we have nadir pointing that needs to be computed & - // See if we have table blobs to load + // See if we have table blobs to load if (m_usingAle) { m_sunPosition->LoadCache(isd["sun_position"]); + if (m_sunPosition->cacheSize() > 3) { + m_sunPosition->Memcache2HermiteCache(0.01); + } m_bodyRotation->LoadCache(isd["body_rotation"]); + m_bodyRotation->MinimizeCache(SpiceRotation::DownsizeStatus::Yes); + if (m_bodyRotation->cacheSize() > 5) { + m_bodyRotation->LoadTimeCache(); + } solarLongitude(); } else if (kernels["TargetPosition"][0].toUpper() == "TABLE") { @@ -397,13 +404,13 @@ namespace Isis { 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 // Table option, so we don't need to check for Table under the old // keywords. - + if (kernels["InstrumentPointing"].size() == 0) { throw IException(IException::Unknown, "No camera pointing available", @@ -411,7 +418,7 @@ namespace Isis { } // 2009-03-18 Tracie Sucharski - Removed test for old keywords, any files - // with the old keywords should be re-run through spiceinit. + // with the old keywords should be re-run through spiceinit. if (kernels["InstrumentPointing"][0].toUpper() == "NADIR") { if (m_instrumentRotation) { delete m_instrumentRotation; @@ -422,30 +429,37 @@ namespace Isis { } else if (m_usingAle) { m_instrumentRotation->LoadCache(isd["instrument_pointing"]); + m_instrumentRotation->MinimizeCache(SpiceRotation::DownsizeStatus::Yes); + if (m_instrumentRotation->cacheSize() > 5) { + m_instrumentRotation->LoadTimeCache(); + } } else if (kernels["InstrumentPointing"][0].toUpper() == "TABLE") { Table t("InstrumentPointing", lab.fileName(), lab); m_instrumentRotation->LoadCache(t); } - + if (kernels["InstrumentPosition"].size() == 0) { throw IException(IException::Unknown, "No instrument position available", _FILEINFO_); } - + if (m_usingAle) { m_instrumentPosition->LoadCache(isd["instrument_position"]); + if (m_instrumentPosition->cacheSize() > 3) { + m_instrumentPosition->Memcache2HermiteCache(0.01); + } } else if (kernels["InstrumentPosition"][0].toUpper() == "TABLE") { Table t("InstrumentPosition", lab.fileName(), lab); m_instrumentPosition->LoadCache(t); } - - + + NaifStatus::CheckErrors(); - } + } /** * Loads/furnishes NAIF kernel(s) @@ -850,9 +864,9 @@ namespace Isis { * spacecraft and sun positions. * * @return @b iTime the currently set ephemeris time - * - * @throws IException::Programmer "Unable to retrieve the time Spice::setTime must be called - * first." + * + * @throws IException::Programmer "Unable to retrieve the time Spice::setTime must be called + * first." */ iTime Spice::time() const { if (m_et == NULL) { @@ -901,7 +915,7 @@ namespace Isis { * @param r[] Radii of the target in kilometers */ void Spice::radii(Distance r[3]) const { - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) r[i] =m_target->radii()[i]; } @@ -953,7 +967,7 @@ namespace Isis { } /** - * This returns the NAIF body frame code. It is read from the labels, if it + * This returns the NAIF body frame code. It is read from the labels, if it * exists. Otherwise, it's calculated by the init() method. * * @return @b SpiceInt NAIF body frame code @@ -965,7 +979,7 @@ namespace Isis { /** - * This returns the PvlObject that stores all of the requested Naif data + * This returns the PvlObject that stores all of the requested Naif data * and can be a replacement for furnishing text kernels. */ PvlObject Spice::getStoredNaifKeywords() const { @@ -1015,10 +1029,10 @@ namespace Isis { /** * This converts the spacecraft clock ticks value (clockValue) to an iTime. - * - * If the clock ticks value is provided directly, rather than the spacecraft - * clock string, set clockTicks=true. - * + * + * If the clock ticks value is provided directly, rather than the spacecraft + * clock string, set clockTicks=true. + * * Use this when possible because naif calls (such as scs2e_c) cannot be * called when not using naif. */ @@ -1036,10 +1050,10 @@ namespace Isis { SpiceDouble timeOutput; NaifStatus::CheckErrors(); if (clockTicks) { - sct2e_c(sclkCode, (SpiceDouble) clockValue.toDouble(), &timeOutput); + sct2e_c(sclkCode, (SpiceDouble) clockValue.toDouble(), &timeOutput); } else { - scs2e_c(sclkCode, clockValue.toLatin1().data(), &timeOutput); + scs2e_c(sclkCode, clockValue.toLatin1().data(), &timeOutput); } NaifStatus::CheckErrors(); storedClockTime = timeOutput; @@ -1274,7 +1288,7 @@ namespace Isis { SpiceBoolean found; SpiceDouble subB[3]; - + surfpt_c(originB, usB, a, b, c, subB, &found); SpiceDouble mylon, mylat; @@ -1309,7 +1323,7 @@ namespace Isis { SpiceDouble uuB[3], dist; unorm_c(m_uB, uuB, &dist); std::vector radii = target()->radii(); - + SpiceDouble a = radii[0].kilometers(); SpiceDouble b = radii[1].kilometers(); SpiceDouble c = radii[2].kilometers(); @@ -1349,16 +1363,16 @@ namespace Isis { QString Spice::targetName() const { return m_target->name(); } - - + + double Spice::sunToBodyDist() const { std::vector sunPosition = m_sunPosition->Coordinate(); std::vector bodyRotation = m_bodyRotation->Matrix(); - + double sunPosFromTarget[3]; mxv_c(&bodyRotation[0], &sunPosition[0], sunPosFromTarget); - - return vnorm_c(sunPosFromTarget); + + return vnorm_c(sunPosFromTarget); } @@ -1377,22 +1391,22 @@ namespace Isis { } if (m_usingAle) { - double og_time = m_bodyRotation->EphemerisTime(); + double og_time = m_bodyRotation->EphemerisTime(); m_bodyRotation->SetEphemerisTime(et.Et()); m_sunPosition->SetEphemerisTime(et.Et()); - std::vector bodyRotMat = m_bodyRotation->Matrix(); - std::vector sunPos = m_sunPosition->Coordinate(); + std::vector bodyRotMat = m_bodyRotation->Matrix(); + std::vector sunPos = m_sunPosition->Coordinate(); std::vector sunVel = m_sunPosition->Velocity(); double sunAv[3]; ucrss_c(&sunPos[0], &sunVel[0], sunAv); - + double npole[3]; for (int i = 0; i < 3; i++) { npole[i] = bodyRotMat[6+i]; } - + double x[3], y[3], z[3]; vequ_c(sunAv, z); ucrss_c(npole, z, x); @@ -1410,17 +1424,17 @@ namespace Isis { double radius, ls, lat; reclat_c(pos, &radius, &ls, &lat); - + *m_solarLongitude = Longitude(ls, Angle::Radians).force360Domain(); - + NaifStatus::CheckErrors(); m_bodyRotation->SetEphemerisTime(og_time); m_sunPosition->SetEphemerisTime(og_time); return; } - if (m_bodyRotation->IsCached()) return; - + if (m_bodyRotation->IsCached()) return; + double tipm[3][3], npole[3]; char frameName[32]; SpiceInt frameCode; @@ -1540,9 +1554,9 @@ namespace Isis { /** * Returns true if time has been initialized. - * + * * @author 2016-10-19 Kristin Berry - * + * * @return @b bool true if time has been set */ bool Spice::isTimeSet(){ @@ -1593,7 +1607,7 @@ namespace Isis { SpiceRotation *Spice::instrumentRotation() const { return m_instrumentRotation; } - + bool Spice::isUsingAle(){ return m_usingAle; } diff --git a/isis/src/base/objs/SpicePosition/SpicePosition.h b/isis/src/base/objs/SpicePosition/SpicePosition.h index e770949877..f727d4553a 100644 --- a/isis/src/base/objs/SpicePosition/SpicePosition.h +++ b/isis/src/base/objs/SpicePosition/SpicePosition.h @@ -250,6 +250,11 @@ namespace Isis { return (p_cache.size() > 0); }; + //! Get the size of the current cached positions + int cacheSize() const { + return p_cache.size(); + }; + void SetPolynomial(const Source type = PolyFunction); void SetPolynomial(const std::vector& XC, diff --git a/isis/src/base/objs/SpicePosition/SpicePosition.truth b/isis/src/base/objs/SpicePosition/SpicePosition.truth index faaf3dc128..6592dd3bbc 100644 --- a/isis/src/base/objs/SpicePosition/SpicePosition.truth +++ b/isis/src/base/objs/SpicePosition/SpicePosition.truth @@ -62,6 +62,7 @@ Velocity (J) = -3.5732696 1.5440214 -2.5639247 Time = -69382512 Spacecraft (J) = -2908.5545 -1132.3409 1981.0142 Velocity (J) = -3.4897306 1.5779899 -2.6234689 +Cache Size: 10 Testing tables ... Time = -69382819 diff --git a/isis/src/base/objs/SpicePosition/unitTest.cpp b/isis/src/base/objs/SpicePosition/unitTest.cpp index 7f9c263059..ba367d4dad 100644 --- a/isis/src/base/objs/SpicePosition/unitTest.cpp +++ b/isis/src/base/objs/SpicePosition/unitTest.cpp @@ -61,6 +61,7 @@ int main(int argc, char *argv[]) { cout << "Spacecraft (J) = " << p[0] << " " << p[1] << " " << p[2] << endl; cout << "Velocity (J) = " << v[0] << " " << v[1] << " " << v[2] << endl; } + std::cout << "Cache Size: " << pos.cacheSize() << '\n'; cout << endl; // Test table options diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp b/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp index ce0ded752b..d21091e021 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation.cpp @@ -442,8 +442,8 @@ namespace Isis { p_cache.push_back(CJ); } - if (isdRot["angular_velocity"].size() != 0) { - for (auto it = isdRot["angular_velocity"].begin(); it != isdRot["angular_velocity"].end(); it++) { + if (isdRot["angular_velocities"].size() != 0) { + for (auto it = isdRot["angular_velocities"].begin(); it != isdRot["angular_velocities"].end(); it++) { std::vector av = {it->at(0).get(), it->at(1).get(), it->at(2).get()}; p_cacheAv.push_back(av); } diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation.h b/isis/src/base/objs/SpiceRotation/SpiceRotation.h index 4fac02f418..8effc6eef7 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation.h +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation.h @@ -425,6 +425,10 @@ namespace Isis { void checkForBinaryPck(); + int cacheSize() { + return p_cache.size(); + } + protected: void SetFullCacheParameters(double startTime, double endTime, int cacheSize); void setEphemerisTimeMemcache(); diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation.truth b/isis/src/base/objs/SpiceRotation/SpiceRotation.truth index 5978be72bd..de5c26eef0 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation.truth +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation.truth @@ -93,6 +93,7 @@ CJ(9) = -0.61729588 0.4060182 -0.67386573 0.010223693 0.86060645 0.50916796 0.78666465 0.30741789 -0.53539982 av(9) = -1.2932496e-05 -0.0010747293 -0.00063276804 +Cache Size: 10 Testing with functions ... Source = 3 diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_13.truth b/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_13.truth index dd0c2fcebc..a8558bd9b8 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_13.truth +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_13.truth @@ -93,6 +93,7 @@ CJ(9) = -0.61729588 0.4060182 -0.67386573 0.010223693 0.86060645 0.50916796 0.78666465 0.30741789 -0.53539982 av(9) = -1.2932496e-05 -0.0010747293 -0.00063276804 +Cache Size: 10 Testing with functions ... Source = 3 diff --git a/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_15.truth b/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_15.truth index dd0c2fcebc..a8558bd9b8 100644 --- a/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_15.truth +++ b/isis/src/base/objs/SpiceRotation/SpiceRotation_Darwin_x86_64_MacOSX10_15.truth @@ -93,6 +93,7 @@ CJ(9) = -0.61729588 0.4060182 -0.67386573 0.010223693 0.86060645 0.50916796 0.78666465 0.30741789 -0.53539982 av(9) = -1.2932496e-05 -0.0010747293 -0.00063276804 +Cache Size: 10 Testing with functions ... Source = 3 diff --git a/isis/src/base/objs/SpiceRotation/unitTest.cpp b/isis/src/base/objs/SpiceRotation/unitTest.cpp index 4dba794aec..0097f78bff 100644 --- a/isis/src/base/objs/SpiceRotation/unitTest.cpp +++ b/isis/src/base/objs/SpiceRotation/unitTest.cpp @@ -102,6 +102,7 @@ int main(int argc, char *argv[]) { cout << "av(" << i << ") = " << av[0] << " " << av[1] << " " << av[2] << endl; } } + std::cout << "Cache Size: " << rot.cacheSize() << '\n'; cout << endl; // Save off cache for polynomial over SPICE test @@ -664,10 +665,10 @@ int main(int argc, char *argv[]) { cout << endl << endl << "Testing loading cache from ALE ISD with time dependent quaternions and AV ..." << endl; SpiceRotation aleQuatAVRot(-94031); json aleQuatAVIsd(aleQuatIsd); - aleQuatAVIsd["angular_velocity"] = {{-Isis::PI / 2, 0.0, 0.0}, - {0.0, Isis::PI, 0.0}, - {0.0, 0.0, Isis::PI / 2}, - {0.0, 0.0, Isis::PI / 2}}; + aleQuatAVIsd["angular_velocities"] = {{-Isis::PI / 2, 0.0, 0.0}, + {0.0, Isis::PI, 0.0}, + {0.0, 0.0, Isis::PI / 2}, + {0.0, 0.0, Isis::PI / 2}}; aleQuatAVRot.LoadCache(aleQuatAVIsd); cout << "Has AV? " << (aleQuatAVRot.HasAngularVelocity() ? "Yes" : "No") << endl; -- GitLab