Commit 777b45c4 authored by Kris Becker's avatar Kris Becker
Browse files

Fixed problem where right/left CK reference frames where not present in the...

Fixed problem where right/left CK reference frames where not present in the TimeDependentFrames label keywords; user comments are now added to generic comments rather than replace them; added OVERLAP parameter to specify how start/end time conflicts are handled; Fixes #1737

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@5755 41f8697f-d340-4b68-9986-7bafba869bb8
parent 5e2ebe63
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ class SpiceSegment;
 * the handle need to write the segment and the addComment() method to add
 * details in the kernel file regarding the segment being written.
 *
 * @author ????-??-?? Unknown
 * @author 2010-11-25 Kris Becker
 *
 * @internal
 */
+65 −9
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
 *   http://www.usgs.gov/privacy.html.
 */
#include <QString>
#include <QStringList>

#include <vector>
#include <numeric>
#include <iostream>
@@ -88,6 +90,44 @@ QString SpiceKernel::getSummary(const QString &commfile) const {
  return (comment);
}

bool SpiceKernel::validate() const {

 QVector<const SpiceSegment *> seglist;
  for ( int i = 0 ; i < size() ; i++) {
    seglist.push_back(&m_segments[i]);
  }

  // Sorts the Segment pointers
  stable_sort(seglist.begin(), seglist.end(), CheckSegment);

  // Now check for overlapping times.  In general, any segment that overlaps
  // another is suspect and will be flagged as an error.  An IException is
  // created and thrown when all images have been evaluated and overlaps are
  // found to exist.
  QStringList errors;
  for (int seg = 1 ; seg < seglist.size() ; seg++) {
    if ( (seglist[seg-1]->endTime() > seglist[seg]->startTime()) &&
         (seglist[seg-1]->InstCode() == seglist[seg]->InstCode()) ) {
      errors  << "CKSegment " + seglist[seg]->Id() + " overlaps CKSegment "
                  + seglist[seg-1]->Id();
    }
  }

  //  Now check for problems
  if ( 0 < errors.size() ) {
     QString mess = "Time overlap conflicts are present in segment (image) list. "
                    "This will likely create erroneous pointing in one or more "
                    "images.  You should create a seperate kernel for conflicting "
                    "images that overlap another.  Images with time overlap "
                    "conflicts are:   \n"
                    + errors.join("; ");
     throw IException(IException::User, mess, _FILEINFO_);
  }

  return (true); 
}


 void SpiceKernel::write(const QString &kname, const QString &comfile,
                         const int cktype) const {
   vector<const SpiceSegment *> seglist;
@@ -138,14 +178,8 @@ QString SpiceKernel::getSummary(const QString &commfile) const {

 QString SpiceKernel::getCkComment(const QString &comFile) const {
   ostringstream comment;
   if ( !comFile.isEmpty() ) {
     TextFile txt(comFile);
     QString cline;
     while ( txt.GetLineNoFilter(cline )) {
       comment << cline << "\n";
     }
   }
   else {

   // Write generic comment
   comment << "\
****************************************************************************\n\
  USGS ISIS (ckwriter) Generated CK Kernel\n\
@@ -212,6 +246,29 @@ Usage Note\n\
      appropriate content to satisfy NAIF\'s SPICE kernel storage\n\
      requirements.  The contents of this kernel are summarized below.\n\
\n\
User Comments\n\
-----------------------------------------------------------------------\n\
\n";

// Now write any user comments provided
   if ( !comFile.isEmpty() ) {

     // Write user comment header
     TextFile txt(comFile);
     QString cline;
     while ( txt.GetLineNoFilter(cline )) {
       comment << cline << "\n";
     }
   }
   else {
     // None provided
     comment << "\
      NONE\n";
   }

   //  Finish comments for segement data
   comment << "\
\n\
Segment (by file) Summary\n\
-----------------------------------------------------------------------\n\
\n\
@@ -220,7 +277,6 @@ Segment (by file) Summary\n\
      the kernels listed for each file should be supplied to ensure proper\n\
      geometry can be reproduced accurately.\n\
\n";
   }

   return (QString(comment.str().c_str()));
}
+4 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ namespace Isis {
 * @history 2010-12-09 Kris Becker Add documentation and example 
 * @history 2013-07-10 Kris Becker Updated to better conform with coding 
 *                                 standards
 * @history 2013-12-17 Kris Becker Include user comments in generic comments 
 *                                 rather than replacing them. 
 */
class SpiceKernel {
  public:
@@ -81,6 +83,8 @@ class SpiceKernel {

    QString getSummary(const QString &commfile = "") const;

    bool validate() const;

    void write(const QString &kname, const QString &commfile = "",
               const int ckType = 3) const;

+51 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
 *   http://www.usgs.gov/privacy.html.
 */
#include <QString>
#include <QStringList>
#include <vector>
#include <numeric>
#include <iostream>
@@ -222,6 +223,11 @@ void SpiceSegment::import(Cube &cube, const QString &tblname) {
    // Load necessary kernels (IAK for Cassini, mainly)
    _kernels.Load("FK,SCLK,LSK,IAK");

//    _kernels.Load("FK,SCLK,LSK,IAK,SPK");
//   QStringList loaded = _kernels.getLoadedList();
//   cout << "\nKernels prior to conversion...\n" << loaded.join("\n");


    //  Here's where all the heavy lifting occurs.
    SMatSeq lmats, rmats;
    SVector sclks;
@@ -258,6 +264,10 @@ void SpiceSegment::import(Cube &cube, const QString &tblname) {
    _utcEndTime   = toUTC(endTime());
    _kernels.UnLoad("FK,SCLK,LSK,IAK");

//    _kernels.UnLoad("FK,SCLK,LSK,IAK,SPK");
//    loaded = _kernels.getLoadedList();
//    cout << "\nKernels after unloading...\n" << loaded.join("\n");

  } catch ( IException &ie  ) {
    ostringstream mess;
    mess << "Failed to construct CK content from ISIS file " << _fname;
@@ -342,7 +352,11 @@ bool SpiceSegment::getTimeDependentFrameIds(Table &table, int &toId, int &fromId
 * Note that if there is no rotation required, an empty or 1 element vector is 
 * returned.  It is up to the caller to decide how to handle this situation.
 * 
 * @author kbecker 2013-06-07
 * @author 2013-06-07 Kris Becker 
 * @internal 
 *   @history 2012-12-16 Kris Becker - Fixed problem when the
 *                         TimeDependentFrames keyword does not contain one or
 *                         both of the CK reference frames.  Fixes #1737.
 * 
 * @param table 
 * @param leftBase 
@@ -372,18 +386,50 @@ bool SpiceSegment::getFrameChains(Table &table, const int &leftBase,
    return (false);
  }

  //  First, check to see if any of the ID are in the list.  Gotta have at
  // least 1.
  int nfound(0);
  BOOST_FOREACH (int fid, tdfids) {
    if ( rightBase == fid ) nfound++;
    if ( leftBase  == fid ) nfound++;
  }

  if ( (nfound == 0) || (nfound > 2) ) {
    ostringstream mess;
    mess << "Left/Right CK frame ids invalid in TimeDependentFrames label keyword." 
         <<  " Must have at least 1 and no more than 2 ids but have " 
         << QString::number(nfound);
    throw IException(IException::User, mess.str(), _FILEINFO_);
  }

  // Get the left CK ID chain
  int lastLeft(leftBase);
  BOOST_FOREACH (int leftId, tdfids) {
    //  Order is important in this code section!
    if ( rightBase == leftId ) break;  // Reached right reference frame
    leftChain.push_back(leftId);
    lastLeft = leftId;  // Record last valid one
    if (leftId == leftBase) break;
  }

  // Ensure the left chain is complete
  if ( leftBase != lastLeft) leftChain.push_back(leftBase);

    // Get the right CK ID chain
  int lastRight(rightBase); 
  BOOST_REVERSE_FOREACH (int rightId, tdfids) {
//    if  (rightId == 1) continue;  //  REMOVE THIS - its only testing B1950!
    //  Order is important in this code section!
    if ( leftBase == rightId ) break;  // Reached left reference frame
    if ( lastLeft == rightId ) break;  // Reach last left id that we cannot ignore
    rightChain.push_front(rightId);
    lastRight = rightId;
    if (rightId == rightBase) break;
  }

   // Ensure the right chain is complete
  if ( rightBase != lastRight) rightChain.push_front(rightBase);

  return (true);
}

@@ -449,6 +495,9 @@ SpiceSegment::SMatrix SpiceSegment::computeStateRotation(const QString &frame1,
                                                         double etTime) const {
  SMatrix state(6,6);
  NaifStatus::CheckErrors();
//  cout << "StateRotations for frame1 = " << frame1 
//       << " to frame2 = " << frame2 << "\n";

  try {
    // Get pointing w/AVs
    sxform_c(frame1.toAscii().data(), frame2.toAscii().data(), etTime,
@@ -480,6 +529,7 @@ SpiceSegment::SMatrix SpiceSegment::computeChainRotation(
  // Set up identity default
  SMatrix state = computeStateRotation("J2000", "J2000", etTime);

//  cout << "\nCompute Chain Rotations...\n";
  if ( fChain.size() > 0 ) {
    QVector<int> chain = fChain;

+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ class SpiceSegment {
    // Elements for writing NAIF SPICE kernels
    int FurnshKernelType(const QString &ktypes) const;
    int UnloadKernelType(const QString &ktypes = "") const;
    const Kernels &kernels() const { return (_kernels); }

    /** Returns CK segment reference frame */
    QString ReferenceFrame() const { return (_refFrame); }
Loading