USGS

Isis 3.0 Object Programmers' Reference

Home

KernelDb.cpp

Go to the documentation of this file.
00001 
00023 #include <iomanip>
00024 #include "iException.h"
00025 #include "CameraFactory.h"
00026 #include "Preference.h"
00027 #include "Filename.h"
00028 #include "iString.h"
00029 #include "KernelDb.h"
00030 
00031 using namespace std; 
00032 using namespace Isis;
00033 
00034 // Create a new empty KernelDb
00035 KernelDb::KernelDb(const unsigned int kernelTypes) {
00036   p_filename = "None";
00037   p_kernelTypes = kernelTypes;
00038 }
00039 
00040 
00041 // Create a new KernelDb object using a filename
00042 KernelDb::KernelDb(const std::string &dbName, const unsigned int kernelTypes) :
00043             p_kernelData (dbName) {
00044   p_filename = dbName;
00045   p_kernelTypes = kernelTypes;
00046 }
00047 
00048 
00049 // Create a new KernelDb object using a stream
00050 KernelDb::KernelDb(std::istream &dbStream, const unsigned int kernelTypes) {
00051   dbStream >> p_kernelData;
00052   p_filename = "internal stream";
00053   p_kernelTypes = kernelTypes;
00054 }
00055 
00056 
00057 // Return the highest version of all LeapSecond kernels identified by the DB
00058 Kernel KernelDb::LeapSecond (Pvl &lab) {
00059   return FindLast("LeapSecond", lab);
00060 }
00061 
00062 
00063 // Return the highest version of all TargetAttitudeShape kernels identified
00064 // by the DB
00065 Kernel KernelDb::TargetAttitudeShape (Pvl &lab) {
00066   return FindLast("TargetAttitudeShape", lab);
00067 }
00068 
00069 
00070 // Return the highest version of all TargetPosition kernels identified
00071 // by the DB
00072 Kernel KernelDb::TargetPosition (Pvl &lab) {
00073   return FindLast("TargetPosition", lab);
00074 }
00075 
00076 
00077 // Return the last matching time of all SpacecraftPointing kernels identified
00078 // by the DB
00079 std::priority_queue< Kernel > KernelDb::SpacecraftPointing (Pvl &lab) {
00080   return FindAll("SpacecraftPointing", lab);
00081 }
00082 
00083 
00084 // Return the highest version of all SpaceCraftClock kernels identified
00085 // by the DB
00086 Kernel KernelDb::SpacecraftClock (Pvl &lab) {
00087   return FindLast("SpacecraftClock", lab);
00088 }
00089 
00090 
00091 // Return the last matching time of all SpacecraftPosition kernels identified
00092 // by the DB
00093 Kernel KernelDb::SpacecraftPosition (Pvl &lab) {
00094   return FindLast("SpacecraftPosition", lab);
00095 }
00096 
00097 
00098 // Return the last Instrument kernal found which matches the criteria in the DB
00099 Kernel KernelDb::Instrument (Pvl &lab) {
00100   return FindLast("Instrument", lab);
00101 }
00102 
00103 
00104 // Return the highest version of all Frame kernels identified
00105 // by the DB
00106 Kernel KernelDb::Frame (Pvl &lab) {
00107   return FindLast("Frame", lab);
00108 }
00109 
00110 
00111 // Return the last InstrumentAddendum kernal found which matches the
00112 // criteria in the DB
00113 Kernel KernelDb::InstrumentAddendum (Pvl &lab) {
00114   return FindLast("InstrumentAddendum", lab);
00115 }
00116 
00117 
00118 // Return the highest version DEM found which matches the criteria in the DB
00119 Kernel KernelDb::Dem (Pvl &lab) {
00120   return FindLast("Dem", lab);
00121 }
00122 
00123 Kernel KernelDb::FindLast(const std::string &entry, Isis::Pvl &lab) {
00124   std::priority_queue< Kernel > all = FindAll(entry, lab);
00125   Kernel last;
00126 
00127   if(all.size() > 0) {
00128     last = all.top();
00129   }
00130 
00131   return last;
00132 }
00133 
00134 std::priority_queue< Kernel > KernelDb::FindAll(const std::string &entry, Isis::Pvl &lab) {
00135   std::priority_queue< Kernel > filesFound;
00136   int cameraVersion = CameraFactory::CameraVersion(lab);
00137   Isis::PvlObject &cube = lab.FindObject("IsisCube");
00138 
00139   // Make sure the entry has been loaded into memory
00140   if (!p_kernelData.HasObject(entry)) {
00141     return filesFound;
00142   }
00143 
00144   // Get the start and end time for the cube
00145   iTime start(((string) cube.FindGroup("Instrument")["StartTime"]));
00146   iTime end;
00147   if (cube.FindGroup("Instrument").HasKeyword("StopTime")) {
00148     end = ((string) cube.FindGroup("Instrument")["StopTime"]);
00149   }
00150   else {
00151     end = ((string) cube.FindGroup("Instrument")["StartTime"]);
00152   }
00153 
00154   // lastType will be used to check if the new group's type is better/worse than the last match
00155   string lastType;
00156   lastType.clear();
00157 
00158   // Get the object and search through it's groups
00159   PvlObject &obj = p_kernelData.FindObject(entry);
00160   for (int group = obj.Groups()-1; group >= 0; group--) {
00161     // Get the group and start testing the cases in the keywords to see if they all match this cube
00162     PvlGroup &grp = obj.Group(group);
00163 
00164     // These are the conditions that make this test pass:
00165     //   1) No time OR At least one matching time
00166     //   2) All keyword matches are true OR No keyword matches present
00167     // 
00168     // In order to accomplish this, matchTime is initialized to true and remains as such if and only if
00169     // there are no time conditionals. If Time keywords exist, one of them has to set matchTime to true.
00170     // The matchKeywords is true until a mismatch is found.
00171     bool matchTime = !grp.HasKeyword("Time");
00172     bool matchKeywords = true;
00173 
00174     // If the group name isn't selection, skip it.
00175     if (!grp.IsNamed("Selection")) {
00176       continue;
00177     }
00178 
00179     iString type = "";
00180 
00181     // Make sure the type is better
00182     if(grp.HasKeyword("Type")) {
00183       type = (string) grp["Type"];
00184       if (!(spiceInit::kernelTypeEnum(type) & p_kernelTypes)) {
00185         continue;
00186       }
00187     }
00188 
00189     // First, the time search. Loop through the keywords, if the name isn't Time then
00190     // skip it. If it is, then get the start/end times and keep looking until one is found.
00191     for (int keyword = 0; keyword < grp.Keywords(); keyword ++) {
00192       PvlKeyword key = grp[keyword];
00193 
00194       if (key.IsNamed("Time")) {
00195         // Pull the selections start and end time out
00196         iTime kernelStart = (string) key[0];
00197         iTime kernelEnd   = (string) key[1];
00198 
00199         // If the kernel times inside of the requested times we 
00200         // set the matchTime to be true.
00201         if ((kernelStart <= start) && (kernelEnd >= end)) {
00202           matchTime = true;
00203         }
00204       }
00205       else if (key.IsNamed("Match")) {
00206         try {
00207           iString matchGroup = key[0];
00208           iString matchKey   = key[1];
00209           iString matchValue = key[2];
00210 
00211           iString cubeValue = (string)cube.FindGroup(matchGroup)[matchKey];
00212           cubeValue.ConvertWhiteSpace();
00213           cubeValue.Compress();
00214           cubeValue.Trim(" ");
00215           cubeValue.UpCase();
00216   
00217           matchValue.ConvertWhiteSpace();
00218           matchValue.Compress();
00219           matchValue.Trim(" ");
00220           matchValue.UpCase();
00221 
00222           // If strings are not the same, match automatically fails
00223           if (cubeValue.compare(matchValue) != 0) {
00224             matchKeywords = false;
00225           }
00226         } catch (Isis::iException &e) {
00227           // This error is thrown if the group or keyword do not exist in 'lab'
00228           matchKeywords = false;
00229         }
00230       }
00231       else if(key.IsNamed("CameraVersion")) {
00232         try {
00233           for(int camVersionKeyIndex = 0; camVersionKeyIndex < key.Size(); camVersionKeyIndex++) {
00234             bool versionMatch = false;
00235             iString val = (std::string)key[camVersionKeyIndex];
00236             iString commaTok;
00237   
00238             while ((commaTok = val.Token(",")).length() > 0) {
00239               if (commaTok.find('-') != std::string::npos) {
00240                 iString dashTok;
00241                 int start = commaTok.Token("-").ToInteger();
00242                 int end = commaTok.Token("-").ToInteger();
00243                 int direction;
00244                 direction = (start<=end) ? 1 : -1;
00245                 // Save the entire range of bands
00246                 for (int version = start; version != end+direction; version+=direction) {
00247                   if(version == cameraVersion) {
00248                     versionMatch = true;
00249                   }
00250                 }
00251               }
00252               // This token is a single band specification
00253               else {
00254                 if(commaTok.ToInteger() == cameraVersion) {
00255                   versionMatch = true;
00256                 }
00257               }
00258             }
00259   
00260             if(!versionMatch)  {
00261               matchKeywords = false;
00262             }
00263 
00264           }
00265         } catch (Isis::iException &e) {
00266           matchKeywords = false;
00267         }
00268       }
00269     }
00270 
00271     if(matchKeywords && matchTime) {
00272       lastType = type;
00273       filesFound.push(Kernel(spiceInit::kernelTypeEnum(type), GetFile(grp)));
00274     }
00275   }
00276 
00277   return filesFound;
00278 }
00279 
00280 // Load the DB with the defined BASE and MISSION info for each type of kernel
00281 void KernelDb::LoadSystemDb (const std::string &mission) {
00282 
00283   // Get the base DataDirectory
00284   PvlGroup &datadir = Preference::Preferences().FindGroup("DataDirectory");
00285   string baseDir = datadir["Base"];
00286 
00287   // Get the mission DataDirectory
00288   string missionDir = datadir[mission];
00289 
00290   // Load the leapsecond DB
00291   Isis::Filename lsDb(baseDir + "/" + "kernels/lsk/kernels.????.db");
00292   lsDb.HighestVersion();
00293   p_kernelData.Read (lsDb.Expanded());
00294 
00295   // Load the target attitude shape DB
00296   Isis::Filename tasDbPath(missionDir + "/" + "kernels/pck");
00297   if( tasDbPath.Exists()) {
00298     Isis::Filename tasDb(missionDir + "/" + "kernels/pck/kernels.????.db");
00299     tasDb.HighestVersion();
00300     p_kernelData.Read (tasDb.Expanded());
00301   }
00302   else {
00303     Isis::Filename baseTasDb(baseDir + "/" + "kernels/pck/kernels.????.db");
00304     baseTasDb.HighestVersion();
00305     p_kernelData.Read (baseTasDb.Expanded());
00306   }
00307 
00308   // Load the target position DB
00309   Isis::Filename tpDbPath(missionDir + "/" + "kernels/tspk");
00310   if( tpDbPath.Exists()) {
00311     Isis::Filename tpDb(missionDir + "/" + "kernels/tspk/kernels.????.db");
00312     tpDb.HighestVersion();
00313     p_kernelData.Read (tpDb.Expanded());
00314   }
00315   else {
00316     Isis::Filename baseTpDb(baseDir + "/" + "kernels/spk/kernels.????.db");
00317     baseTpDb.HighestVersion();
00318     p_kernelData.Read (baseTpDb.Expanded());
00319   }
00320 
00321   // Load the DEM DB
00322   Isis::Filename demDb(baseDir + "/" + "dems/kernels.????.db");
00323   demDb.HighestVersion();
00324   p_kernelData.Read (demDb.Expanded());
00325 
00326   // Load the mission specific spacecraft pointing DB
00327   Isis::Filename spDb(missionDir + "/" + "kernels/ck/kernels.????.db");
00328   spDb.HighestVersion();
00329   p_kernelData.Read (spDb.Expanded());
00330 
00331   // Load the mission specific frame DB
00332   Isis::Filename fDb(missionDir + "/" + "kernels/fk/kernels.????.db");
00333   fDb.HighestVersion();
00334   p_kernelData.Read (fDb.Expanded());
00335 
00336   // Load the mission specific instrument DB
00337   Isis::Filename iDb(missionDir + "/" + "kernels/ik/kernels.????.db");
00338   iDb.HighestVersion();
00339   p_kernelData.Read (iDb.Expanded());
00340 
00341   // Load the mission specific spacecraft clock DB
00342   Isis::Filename scDb(missionDir + "/" + "kernels/sclk/kernels.????.db");
00343   scDb.HighestVersion();
00344   p_kernelData.Read (scDb.Expanded());
00345 
00346   // Load the mission specific spacecraft position DB
00347   Isis::Filename sposDb(missionDir + "/" + "kernels/spk/kernels.????.db");
00348   sposDb.HighestVersion();
00349   p_kernelData.Read (sposDb.Expanded());
00350 
00351   // Load the mission specific instrument addendum DB
00352   Isis::Filename iakDb(missionDir + "/" + "kernels/iak/kernels.????.db");
00353   iakDb.HighestVersion();
00354   p_kernelData.Read (iakDb.Expanded());
00355 }
00356 
00357 std::vector<std::string> KernelDb::GetFile (PvlGroup &grp) {
00358   std::vector<std::string> files;
00359   //PvlKeyword kfile = grp["File"];
00360 
00361   for (int i=0; i<grp.Keywords(); i++) {
00362     PvlKeyword kfile = grp[i];
00363     if (kfile.Name()!="File") continue;
00364 
00365     // Two values in the "File" keyword from the DB,
00366     // indicates an ISIS preference in the DataDirectory section
00367     // and a filename
00368     if (kfile.Size() == 2) {
00369       string pref = kfile[0];
00370       string version = kfile[1];
00371       Isis::Filename filename("$" + pref + "/" + version);
00372       if (filename.Expanded().find('?') != string::npos) filename.HighestVersion();
00373       files.push_back(filename.OriginalPath() + "/" + filename.Name());
00374     }
00375     // One value in "File" indicates a full file spec
00376     else if (kfile.Size() == 1) {
00377       Isis::Filename filename(kfile[0]);
00378       if (filename.Expanded().find('?') != string::npos) filename.HighestVersion();
00379       files.push_back(filename.OriginalPath() + "/" + filename.Name());
00380     } else {
00381       string msg = "Invalid File keyword value in [Group = ";
00382       msg += grp.Name() + "] in database file [";
00383       msg += p_filename + "]";
00384       throw iException::Message(iException::Parse,msg, _FILEINFO_);
00385     }
00386   }
00387 
00388   return files;
00389 }
00390 
00391 const bool KernelDb::Better (const std::string newType, const std::string oldType) {
00392   return Better(spiceInit::kernelTypeEnum(newType), spiceInit::kernelTypeEnum(oldType));
00393 }
00394 
00395 const bool KernelDb::Better (const spiceInit::kernelTypes nType, const spiceInit::kernelTypes oType) {
00396   if ((nType & p_kernelTypes) && (nType >= oType)) return true;
00397 
00398   return false;
00399 }
00400