USGS

Isis 3.0 Object Programmers' Reference

Home

Kernels.cpp

Go to the documentation of this file.
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