USGS

Isis 3.0 Application Source Code Reference

Home

SpiceManager.cpp

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * $Revision: 1.9 $
00004  * $Date: 2009/12/29 23:03:50 $
00005  * $Id: SpiceManager.cpp,v 1.9 2009/12/29 23:03:50 ehyer Exp $
00006  *
00007  *   Unless noted otherwise, the portions of Isis written by the USGS are
00008  *   public domain. See individual third-party library and package descriptions
00009  *   for intellectual property information, user agreements, and related
00010  *   information.
00011  *
00012  *   Although Isis has been used by the USGS, no warranty, expressed or
00013  *   implied, is made by the USGS as to the accuracy and functioning of such
00014  *   software and related material nor shall the fact of distribution
00015  *   constitute any such warranty, and no responsibility is assumed by the
00016  *   USGS in connection therewith.
00017  *
00018  *   For additional information, launch
00019  *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
00020  *   in a browser or see the Privacy & Disclaimers page on the Isis website,
00021  *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
00022  *   http://www.usgs.gov/privacy.html.
00023  */
00024 #include <string>
00025 #include <vector>
00026 #include <numeric>
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <sstream>
00030 
00031 #include "SpiceManager.h"
00032 #include "Filename.h"
00033 #include "PvlKeyword.h"
00034 #include "Pvl.h"
00035 #include "iException.h"
00036 #include "naif/SpiceUsr.h"
00037 
00038 using namespace std;
00039 
00040 namespace Isis {
00041 
00042   /**
00043    * @brief Construct using an ISIS file name
00044    *
00045    * @param filename Name of ISIS cube file
00046    * @param furnish Do we load the kernels we find?
00047    */
00048   SpiceManager::SpiceManager(const std::string &filename, bool furnish) {
00049     Pvl pvl(filename);
00050     Load(pvl, furnish);
00051   }
00052 
00053   /**
00054    * @brief Construct using an ISIS Cube object
00055    *
00056    * @param cube    Cube object of ISIS file
00057    * @param furnish Do we load the kernels we find?
00058    */
00059   SpiceManager::SpiceManager(Cube &cube, bool furnish) {
00060     Load(*cube.getLabel(), furnish);
00061   }
00062 
00063   /**
00064    * @brief Construct from an ISIS label
00065    *
00066    * @param pvl  ISIS label to get kernel information from
00067    * @param furnish  Do we load the kernels we find?
00068    */
00069   SpiceManager::SpiceManager(Pvl &pvl, bool furnish) {
00070     Load(pvl, furnish);
00071   }
00072 
00073 
00074   /**
00075    * @brief Perform the hunt for Spice kernels in an ISIS label
00076    *
00077    * This method must traverse the ISIS label hierarchy to find all the
00078    * pertinent kernel files.  Many of them are found in the Kernel Group, but
00079    * others exist in Table objects that are SPICE blobs.  The actual names are
00080    * found in the Kernels keyword in the named Table object.
00081    *
00082    * @param pvl  ISIS label
00083    * @param furnish Do we actually load the kernel files as we find them?
00084    */
00085   void SpiceManager::Load(Pvl &pvl, bool furnish) {
00086     Unload();
00087     _furnish = furnish;
00088 
00089     std::string kernlist;
00090     // Get the kernel group and load main kernels
00091     PvlGroup kernels = pvl.FindGroup("Kernels", Pvl::Traverse);
00092     //  Changed 2008-02-27 to load planetary ephemeris before spacecraft
00093     //  since MESSENGER team may update planet data in the s/c SPK.
00094     loadKernelFromTable(kernels["TargetPosition"], "SunPosition", pvl);
00095 
00096     //  Now do s/c ephemeris
00097     if(kernels.HasKeyword("SpacecraftPosition")) {
00098       loadKernel(kernels["SpacecraftPosition"]);
00099     }
00100     else {
00101       loadKernelFromTable(kernels["InstrumentPosition"], "InstrumentPosition",
00102                           pvl);
00103     }
00104 
00105     if(kernels.HasKeyword("SpacecraftPointing")) {
00106       loadKernel(kernels["SpacecraftPointing"]);
00107     }
00108     else {
00109       loadKernelFromTable(kernels["InstrumentPointing"], "InstrumentPointing",
00110                           pvl);
00111     }
00112 
00113     if(kernels.HasKeyword("Frame")) {
00114       loadKernel(kernels["Frame"]);
00115     }
00116 
00117     if(kernels.HasKeyword("Extra")) {
00118       loadKernel(kernels["Extra"]);
00119     }
00120 
00121 
00122     loadKernel(kernels["TargetAttitudeShape"]);
00123     loadKernel(kernels["Instrument"]);
00124     loadKernel(kernels["InstrumentAddendum"]);  // Always load after instrument
00125     loadKernel(kernels["LeapSecond"]);
00126     loadKernel(kernels["SpacecraftClock"]);
00127     return;
00128   }
00129 
00130   /**
00131    * @brief Add a specified kernel file to the pool
00132    *
00133    * This method adds a specified kernel file to the NAIF pool.  The caller can
00134    * provide a file pattern with "?" in the filename as this method will
00135    * determine the highest occuring version.
00136    *
00137    * @param kernel  Name of kernel file (or pattern) to add
00138    */
00139   void SpiceManager::add(const std::string &kernfile) {
00140 
00141     string kfile(kernfile);
00142 
00143     //  Check for versionized file naming
00144     string::size_type start = kfile.find_first_of("?");
00145     if(start != string::npos) {
00146       Filename efile(kfile);
00147       efile.HighestVersion();
00148       kfile = efile.Expanded();
00149     }
00150 
00151     //  Add a specific kernel to the list
00152     PvlKeyword kernel("Kernels", kfile);
00153     loadKernel(kernel);
00154     return;
00155   }
00156 
00157   /**
00158    * @brief Provide a list of all the kernels found
00159    *
00160    * This method will return all the kernel file references as found in the ISIS
00161    * label.  It will optionally remove the file paths and return only the kernel
00162    * file name if requested.  If removePath is false, it returns the complete
00163    * path to the SPICE kernels.
00164    *
00165    * @param removePath Do we remove the file paths and return only the file
00166    *                   names?
00167    *
00168    * @return std::vector<std::string> A vector of filenames of SPICE kernels
00169    */
00170   std::vector<std::string> SpiceManager::getList(bool removePath) const {
00171     std::vector<std::string> flist;
00172     for(unsigned int i = 0 ; i < _kernlist.size() ; i++) {
00173       if(removePath) {
00174         Filename kfile(_kernlist[i]);
00175         flist.push_back(kfile.Name());
00176       }
00177       else {
00178         flist.push_back(_kernlist[i]);
00179       }
00180     }
00181     return (flist);
00182   }
00183 
00184   /**
00185    * @brief Unloads all kernels if they were loaded when found
00186    */
00187   void SpiceManager::Unload() {
00188     if(_furnish) {
00189       for(unsigned int i = 0 ; i < _kernlist.size() ; i++) {
00190         /**
00191         *  Changed to work with hipeaks crappy compiler.
00192         *  string kernName(Filename(_kernlist[i]).Expanded());
00193         *  unload_c(kernName.c_str());
00194         */
00195         Filename f(_kernlist[i]);
00196         string kernName(f.Expanded());
00197         unload_c(kernName.c_str());
00198       }
00199     }
00200     _kernlist.clear();
00201     return;
00202   }
00203 
00204   /**
00205    * @brief Loops through PvlKeyword containing Kernel file names
00206    *
00207    * This method interogates a PvlKeyword that is determined to
00208    * contain SPICE kernel names.  It will optionally load the
00209    * kernels if initially requested and then adds the name to the
00210    * internally managed list.
00211    *
00212    * Some keywords may contain special keywords.  These are ignored in this
00213    * method and can be handled explicitly in other methods.
00214    *
00215    * @param key PvlKeyword containing SPICE kernels
00216    * @see  loadKernelFromTable()
00217    */
00218   void SpiceManager::loadKernel(PvlKeyword &key) {
00219     for(int i = 0; i < key.Size(); i++) {
00220       if(key[i] == "") continue;
00221       if(iString(key[i]).UpCase() == "NULL") continue;
00222       if(iString(key[i]).UpCase() == "NADIR") continue;
00223       if(iString(key[i]).UpCase() == "TABLE") continue;
00224       Isis::Filename file(key[i]);
00225       if(!file.exists()) {
00226         string msg = "Spice file does not exist [" + file.Expanded() + "]";
00227         throw Isis::iException::Message(Isis::iException::Io, msg, _FILEINFO_);
00228       }
00229       string fileName(file.Expanded());
00230       if(_furnish) furnsh_c(fileName.c_str());
00231       addKernelName((string)key[i]);
00232     }
00233   }
00234 
00235   /**
00236    * @brief Interogate a PvlKeyword for location of kernel file names
00237    *
00238    * This method is intended to find keywords that refer to SPICE Table Blobs
00239    * and look in those Table objects for the actual names of SPICE kernel files.
00240    * They are then loaded via the loadKernel() method.
00241    *
00242    * @param key PvlKeyword containing SPICE kernel names
00243    * @param tblname Name of Table where the SPICE blob is located in the label
00244    * @param pvl Pvl label to search for the SPICE Table Object Blob
00245    */
00246   void SpiceManager::loadKernelFromTable(PvlKeyword &key,
00247                                          const std::string &tblname, Pvl &pvl) {
00248     if(iString::UpCase(key[0]) != "TABLE") {
00249       loadKernel(key);
00250     }
00251     else {
00252       PvlObject::PvlObjectIterator objIter;
00253       for(objIter = pvl.BeginObject() ; objIter != pvl.EndObject() ; ++objIter) {
00254         if(iString::UpCase(objIter->Name()) == "TABLE") {
00255           if(objIter->HasKeyword("Name")) {
00256             if(iString::Equal(objIter->FindKeyword("Name")[0], tblname)) {
00257               loadKernel(objIter->FindKeyword("Kernels"));
00258               return;
00259             }
00260           }
00261         }
00262       }
00263     }
00264     return;
00265   }
00266   /**
00267    * @brief Adds the named kernel file to the internal list
00268    *
00269    * This method will add the name of the kernel file to the list.  It will
00270    * first determine if it already exists.  If it does, it will not be added a
00271    * second time.
00272    *
00273    * @param kname Name of SPICE kernel file to add
00274    */
00275   void SpiceManager::addKernelName(const std::string &kname) {
00276     for(unsigned int i = 0 ; i < _kernlist.size() ; i++) {
00277       if(_kernlist[i] == kname)  return;
00278     }
00279     _kernlist.push_back(kname);
00280     return;
00281   }
00282 
00283 }  // namespace Isis
00284 
00285