|
Isis 3.0 Object Programmers' Reference |
Home |
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