Isis 3.0 Application Source Code Reference |
Home |
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