Isis 3.0 Object Programmers' Reference |
Home |
00001 00024 #include <string> 00025 #include <vector> 00026 #include <numeric> 00027 #include <iostream> 00028 #include <fstream> 00029 #include <iomanip> 00030 #include <sstream> 00031 00032 #include "Kernels.h" 00033 #include "Filename.h" 00034 #include "PvlKeyword.h" 00035 #include "Pvl.h" 00036 #include "iException.h" 00037 #include "naif/SpiceUsr.h" 00038 #include "NaifStatus.h" 00039 00040 using namespace std; 00041 00042 namespace Isis { 00043 00045 Kernels::Kernels() { 00046 _kernels.clear(); 00047 _camVersion = -1; 00048 } 00049 00050 00065 Kernels::Kernels(const Kernels &kernels) { 00066 _kernels = kernels._kernels; 00067 _camVersion = kernels._camVersion; 00068 UpdateLoadStatus(); 00069 UpdateManagedStatus(); 00070 } 00071 00089 Kernels &Kernels::operator=(const Kernels &kernels) { 00090 if (this != &kernels) { 00091 Clear(); 00092 _kernels = kernels._kernels; 00093 _camVersion = kernels._camVersion; 00094 UpdateLoadStatus(); 00095 UpdateManagedStatus(); 00096 } 00097 return (*this); 00098 } 00099 00105 Kernels::Kernels(const std::string &filename) { 00106 Pvl pvl(filename); 00107 Init(pvl); 00108 } 00109 00115 Kernels::Kernels(Cube &cube) { 00116 Init(*cube.getLabel()); 00117 } 00118 00124 Kernels::Kernels(Pvl &pvl) { 00125 Init(pvl); 00126 } 00127 00133 int Kernels::Missing() const { 00134 int nMissing(0); 00135 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00136 if (!_kernels[i].exists) nMissing++; 00137 } 00138 return (nMissing); 00139 } 00140 00155 void Kernels::Init(Pvl &pvl) { 00156 UnLoad(); 00157 _kernels.clear(); 00158 addKernels(findKernels(pvl, "TargetPosition")); 00159 addKernels(findKernels(pvl, "InstrumentPosition")); 00160 addKernels(findKernels(pvl, "InstrumentPointing")); 00161 addKernels(findKernels(pvl, "Frame")); 00162 addKernels(findKernels(pvl, "TargetAttitudeShape")); 00163 addKernels(findKernels(pvl, "Instrument")); 00164 addKernels(findKernels(pvl, "InstrumentAddendum")); 00165 addKernels(findKernels(pvl, "LeapSecond")); 00166 addKernels(findKernels(pvl, "SpacecraftClock")); 00167 addKernels(findKernels(pvl, "ShapeModel")); 00168 addKernels(findKernels(pvl, "Extra")); 00169 _camVersion = getCameraVersion(pvl); 00170 return; 00171 } 00172 00191 bool Kernels::Add(const std::string &kfile) { 00192 if (!findByName(kfile)) { 00193 _kernels.push_back(examine(kfile, true)); 00194 return (true); 00195 } 00196 return (false); 00197 } 00198 00208 void Kernels::Clear() { 00209 _kernels.clear(); 00210 } 00211 00248 int Kernels::Discover() { 00249 _kernels.clear(); 00250 SpiceInt count; 00251 ktotal_c("ALL", &count); 00252 int nfound(0); 00253 for (int i = 0 ; i < count ; i++) { 00254 SpiceChar file[128]; 00255 SpiceChar ktype[32]; 00256 SpiceChar source[128]; 00257 SpiceInt handle; 00258 SpiceBoolean found; 00259 kdata_c(i, "ALL", sizeof(file), sizeof(ktype), sizeof(source), 00260 file, ktype,source, &handle, &found); 00261 if (found == SPICETRUE) { 00262 _kernels.push_back(examine(file, false)); 00263 nfound++; 00264 } 00265 } 00266 return (nfound); 00267 } 00268 00269 00280 void Kernels::Manage() { 00281 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00282 _kernels[i].managed = true; 00283 } 00284 return; 00285 } 00286 00287 00299 void Kernels::UnManage() { 00300 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00301 _kernels[i].managed = false; 00302 } 00303 return; 00304 } 00305 00319 bool Kernels::IsManaged() const { 00320 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00321 if (!_kernels[i].managed) return (false);; 00322 } 00323 return (true); 00324 } 00325 00326 00344 void Kernels::InitializeNaifKernelPool() { 00345 kclear_c(); 00346 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00347 _kernels[i].loaded = false; 00348 } 00349 return; 00350 } 00351 00352 00373 int Kernels::Load(const std::string &ktypes) { 00374 // If no types specified, return them all 00375 int nLoaded(0); 00376 if (ktypes.empty()) { 00377 for (unsigned int k = 0 ; k < _kernels.size() ; k++) { 00378 if (Load(_kernels[k])) { nLoaded++; } 00379 } 00380 } 00381 else { 00382 // Find types and return requested types 00383 vector<string> tlist = getTypes(ktypes); 00384 for (unsigned int t = 0 ; t < tlist.size() ; t++) { 00385 for (unsigned int k = 0; k < _kernels.size() ; k++) { 00386 if (_kernels[k].ktype == tlist[t]) { 00387 if (Load(_kernels[k])) { nLoaded++; } 00388 } 00389 } 00390 } 00391 } 00392 return (nLoaded); 00393 } 00394 00395 00414 int Kernels::Load() { 00415 // If not types specified, return them all 00416 int nLoaded(0); 00417 for (unsigned int k = 0 ; k < _kernels.size() ; k++) { 00418 if (Load(_kernels[k])) { nLoaded++; } 00419 } 00420 return (nLoaded); 00421 } 00422 00423 00434 int Kernels::UnLoad() { 00435 int nUnloaded(0); 00436 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00437 if (UnLoad(_kernels[i])) nUnloaded++; 00438 } 00439 return (nUnloaded); 00440 } 00441 00462 int Kernels::UnLoad(const std::string &ktypes) { 00463 // If not types specified, return them all 00464 int nUnloaded(0); 00465 if (ktypes.empty()) { 00466 nUnloaded = UnLoad(); 00467 } 00468 else { 00469 // Find types and return requested types 00470 vector<string> tlist = getTypes(ktypes); 00471 for (unsigned int t = 0 ; t < tlist.size() ; t++) { 00472 for (unsigned int k = 0; k < _kernels.size() ; k++) { 00473 if (_kernels[k].ktype == tlist[t]) { 00474 if (UnLoad(_kernels[k])) nUnloaded++; 00475 } 00476 } 00477 } 00478 } 00479 return (nUnloaded); 00480 } 00481 00500 int Kernels::UpdateLoadStatus() { 00501 int nchanged(0); 00502 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00503 // Use NAIF to determine if it is loaded 00504 if (IsNaifType(_kernels[i].ktype)) { 00505 SpiceChar ktype[32]; 00506 SpiceChar source[128]; 00507 SpiceInt handle; 00508 SpiceBoolean found; 00509 kinfo_c(_kernels[i].fullpath.c_str(), sizeof(ktype), sizeof(source), 00510 ktype,source, &handle, &found); 00511 if (found == SPICETRUE) { 00512 if (!_kernels[i].loaded) nchanged++; 00513 _kernels[i].loaded = true; 00514 } 00515 else { 00516 if (_kernels[i].loaded) nchanged++; 00517 _kernels[i].loaded = false; 00518 } 00519 } 00520 } 00521 00522 return (nchanged); 00523 } 00524 00544 int Kernels::UpdateManagedStatus() { 00545 int nchanged(0); 00546 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00547 if (_kernels[i].loaded) { 00548 _kernels[i].managed = false; 00549 nchanged++; 00550 } 00551 else { 00552 _kernels[i].managed = true; 00553 } 00554 } 00555 return (nchanged); 00556 } 00557 00604 int Kernels::Merge(const Kernels &other) { 00605 int nAdded(0); 00606 for (unsigned int i = 0 ; i < other._kernels.size() ; i++) { 00607 KernelFile *kernel = findByName(other._kernels[i].fullpath); 00608 if (kernel == 0) { 00609 KernelFile kfile = other._kernels[i]; 00610 kfile.managed = false; 00611 _kernels.push_back(kfile); 00612 nAdded++; 00613 } 00614 else { 00615 if (other._kernels[i].loaded) { 00616 kernel->loaded = true; 00617 kernel->managed = false; 00618 } 00619 } 00620 } 00621 return (nAdded); 00622 } 00623 00624 00654 std::vector<std::string> Kernels::getKernelTypes() const { 00655 TypeList kmap = categorizeByType(); 00656 std::vector<std::string> types; 00657 for (int i = 0 ; i < kmap.size() ; i++) { 00658 types.push_back(kmap.key(i)); 00659 } 00660 return (types); 00661 } 00662 00663 00676 std::vector<std::string> Kernels::getKernelList(const std::string &ktypes) const { 00677 00678 // If not types specified, return them all 00679 vector<string> flist; 00680 if (ktypes.empty()) { 00681 for (unsigned int k = 0; k < _kernels.size() ; k++) { 00682 flist.push_back(_kernels[k].pathname); 00683 } 00684 } 00685 else { 00686 // Find types and return requested types 00687 vector<string> tlist = getTypes(ktypes); 00688 for (unsigned int t = 0 ; t < tlist.size() ; t++) { 00689 for (unsigned int k = 0; k < _kernels.size() ; k++) { 00690 if (_kernels[k].ktype == tlist[t]) { 00691 flist.push_back(_kernels[k].pathname); 00692 } 00693 } 00694 } 00695 } 00696 return (flist); 00697 } 00698 00699 00724 std::vector<std::string> Kernels::getLoadedList(const std::string &ktypes) 00725 const { 00726 std::vector<std::string> flist; 00727 if (ktypes.empty()) { 00728 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00729 if (_kernels[i].loaded) flist.push_back(_kernels[i].pathname); 00730 } 00731 } 00732 else { 00733 std::vector<std::string> tlist = getTypes(ktypes); 00734 for (unsigned int t = 0 ; t < tlist.size() ; t++ ) { 00735 for (unsigned int k = 0; k < _kernels.size() ; k++) { 00736 if (_kernels[k].ktype == tlist[t]) { 00737 flist.push_back(_kernels[k].pathname); 00738 } 00739 } 00740 } 00741 } 00742 return (flist); 00743 } 00744 00745 00756 std::vector<std::string> Kernels::getMissingList() const { 00757 std::vector<std::string> flist; 00758 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00759 if (!_kernels[i].exists) flist.push_back(_kernels[i].pathname); 00760 } 00761 return (flist); 00762 } 00763 00778 bool Kernels::Load(Kernels::KernelFile &kfile) { 00779 if (IsNaifType(kfile.ktype)) { 00780 if (!kfile.loaded) { 00781 NaifStatus::CheckErrors(); 00782 try { 00783 furnsh_c(kfile.fullpath.c_str()); 00784 NaifStatus::CheckErrors(); 00785 kfile.loaded = true; 00786 kfile.managed = true; 00787 } catch (iException &ie) { 00788 ie.Clear(); 00789 return (false); 00790 } 00791 } 00792 } 00793 return (kfile.loaded); 00794 } 00795 00818 bool Kernels::UnLoad(KernelFile &kfile) { 00819 // If its loaded assume its a loaded NAIF kernel and unload it 00820 bool wasLoaded(false); 00821 if (kfile.loaded) { 00822 if (kfile.managed) { 00823 NaifStatus::CheckErrors(); 00824 try { 00825 unload_c(kfile.fullpath.c_str()); 00826 NaifStatus::CheckErrors(); 00827 } catch (iException &ie) { 00828 // Errors are trapped and ignored. It may be unloaded by other source 00829 ie.Clear(); 00830 } 00831 kfile.loaded = false; 00832 wasLoaded = true; 00833 } 00834 } 00835 return (wasLoaded); 00836 } 00837 00869 std::vector<std::string> Kernels::getTypes(const std::string &ktypes) const { 00870 // Find types and return requested types 00871 vector<string> tlist; 00872 iString::Split(',', ktypes, tlist); 00873 for (unsigned int k = 0 ; k < tlist.size() ; k++) { 00874 tlist[k] = iString(tlist[k]).Trim(" \r\n\t\v\b\f").UpCase(); 00875 } 00876 return (tlist); 00877 } 00878 00886 void Kernels::addKernels(const KernelList &klist) { 00887 copy(klist.begin(), klist.end(), back_inserter(_kernels)); 00888 return; 00889 } 00890 00891 00908 Kernels::KernelList Kernels::findKernels(Pvl &pvl, 00909 const std::string &kname, 00910 const bool &manage) { 00911 KernelList klist; 00912 // Get the kernel group and load main kernels 00913 PvlGroup &kernels = pvl.FindGroup("Kernels",Pvl::Traverse); 00914 // Check for the keyword 00915 if (kernels.HasKeyword(kname)) { 00916 PvlKeyword &kkey = kernels[kname]; 00917 for (int i = 0 ; i < kkey.Size() ; i++) { 00918 if (!kkey.IsNull(i)) { 00919 if (!iString::Equal(kkey[i], "Table")) { 00920 klist.push_back(examine(kkey[i], manage)); 00921 } 00922 } 00923 } 00924 } 00925 00926 return (klist); 00927 } 00928 00929 00954 Kernels::KernelFile *Kernels::findByName(const std::string &kfile) { 00955 KernelList::iterator klist; 00956 for (klist = _kernels.begin() ; klist != _kernels.end() ; ++klist) { 00957 if (klist->pathname == kfile) { return (&(*klist)); } 00958 if (klist->name == kfile) { return (&(*klist)); } 00959 if (klist->fullpath == kfile) { return (&(*klist)); } 00960 } 00961 return (0); 00962 } 00963 00964 00973 Kernels::TypeList Kernels::categorizeByType() const { 00974 TypeList ktypes; 00975 for (unsigned int i = 0 ; i < _kernels.size() ; i++) { 00976 KernelFile *kfile = const_cast<KernelFile *> (&_kernels[i]); 00977 if (ktypes.exists(_kernels[i].ktype)) { 00978 ktypes.get(_kernels[i].ktype).push_back(kfile); 00979 } 00980 else { 00981 ktypes.add(_kernels[i].ktype, KernelFileList(1, kfile)); 00982 } 00983 } 00984 return (ktypes); 00985 } 00986 00987 00996 bool Kernels::IsNaifType(const std::string &ktype) const { 00997 if (iString::Equal(ktype, "UNKNOWN")) return (false); 00998 if (iString::Equal(ktype, "DEM")) return (false); 00999 return (true); 01000 } 01049 Kernels::KernelFile Kernels::examine(const std::string &kfile, 01050 const bool &manage) const { 01051 01052 Filename kernfile(kfile); 01053 KernelFile kf; 01054 kf.pathname = kfile; 01055 kf.name = kernfile.Name(); 01056 kf.fullpath = kernfile.Expanded(); 01057 kf.exists = kernfile.Exists(); 01058 kf.ktype = "UNKNOWN"; 01059 kf.loaded = false; // Assumes its not loaded 01060 kf.managed = manage; 01061 01062 // Determine type and load info 01063 if (kf.exists) { 01064 kf.ktype = resolveType(kf.fullpath); 01065 01066 // Use NAIF to determine if it is loaded 01067 if (IsNaifType(kf.ktype)) { 01068 SpiceChar ktype[32]; 01069 SpiceChar source[128]; 01070 SpiceInt handle; 01071 SpiceBoolean found; 01072 kinfo_c(kf.fullpath.c_str(), sizeof(ktype), sizeof(source), ktype, 01073 source, &handle, &found); 01074 if (found == SPICETRUE) { 01075 kf.loaded = true; 01076 kf.managed = false; 01077 kf.ktype = iString(ktype).UpCase(); 01078 } 01079 } 01080 } 01081 01082 return (kf); 01083 } 01084 01109 std::string Kernels::resolveType(const std::string &kfile) const { 01110 Filename kernFile(kfile); 01111 string kpath = kernFile.Expanded(); 01112 ifstream ifile(kpath.c_str(), ios::in | ios::binary); 01113 string ktype("UNKNOWN"); 01114 if (ifile) { 01115 char ibuf[10]; 01116 ifile.read(ibuf, 8); 01117 ibuf[8] = '\0'; 01118 for (int i = 0 ; i < 8 ; i++) 01119 if (ibuf[i] == '\n') ibuf[i] = '\0'; 01120 01121 // See if the file is a known NAIF type. Assume it has been 01122 // extracted from a NAIF compliant kernel 01123 string istr = iString(ibuf).Trim(" \n\r\f\t\v\b"); 01124 if (!istr.empty()) { 01125 vector<string> parts; 01126 iString::Split('/', istr, parts); 01127 if (parts.size() > 1) { 01128 ktype = parts[parts.size()-1]; 01129 } 01130 } 01131 01132 // If type is not resolved, check file extensions and special ISIS types 01133 if ((ktype == "UNKNOWN") || (ktype == "DAF")) { 01134 ktype = resolveTypeByExt(kfile, ktype); 01135 } 01136 01137 } 01138 return (ktype); 01139 } 01140 01184 std::string Kernels::resolveTypeByExt(const std::string &kfile, 01185 const std::string &iktype) const { 01186 01187 string ktype(iktype); // Set default condition 01188 01189 // Deciminate file parts 01190 Filename kf(kfile); 01191 string ext = iString(kf.Extension()).DownCase(); 01192 01193 // Check extensions for types 01194 if (ext == "cub") { 01195 ktype = "DEM"; 01196 } 01197 else if (ext == "ti") { 01198 // Assume its an instrument kernel but check for ISIS IAK file 01199 ktype = "IK"; 01200 string base = iString(kf.Basename()).DownCase(); 01201 string::size_type idx = base.find("addendum"); 01202 if (idx != string::npos) { // This is an ISIS IK addendum (IAK) 01203 ktype = "IAK"; 01204 } 01205 } 01206 else if (ext == "tsc") { 01207 ktype = "SCLK"; 01208 } 01209 else if (ext == "tf") { 01210 ktype = "FK"; 01211 } 01212 else if (ext == "tls") { 01213 ktype = "LSK"; 01214 } 01215 else if (ext == "tpc") { 01216 ktype = "PCK"; 01217 } 01218 else if (ext == "bc") { 01219 ktype = "CK"; 01220 } 01221 else if (ext == "bsp") { 01222 ktype = "SPK"; 01223 } 01224 else if (ext == "bes") { 01225 ktype = "EK"; 01226 } 01227 01228 return (ktype); 01229 } 01230 01231 01232 01246 int Kernels::getCameraVersion(Pvl &pvl) const { 01247 PvlGroup &kernels = pvl.FindGroup("Kernels",Pvl::Traverse); 01248 int cv(0); 01249 // Check for the keyword 01250 if (kernels.HasKeyword("CameraVersion")) { 01251 PvlKeyword &kkey = kernels["CameraVersion"]; 01252 cv = iString(kkey[0]).ToInteger(); 01253 } 01254 return (cv); 01255 } 01256 01257 } // namespace Isis 01258 01259