Isis 3.0 Application Source Code Reference |
Home |
00001 /** 00002 * @file 00003 * $Revision: 1.5 $ 00004 * $Date: 2008/08/01 20:39:26 $ 00005 * 00006 * Unless noted otherwise, the portions of Isis written by the USGS are public 00007 * domain. See individual third-party library and package descriptions for 00008 * intellectual property information,user agreements, and related information. 00009 * 00010 * Although Isis has been used by the USGS, no warranty, expressed or implied, 00011 * is made by the USGS as to the accuracy and functioning of such software 00012 * and related material nor shall the fact of distribution constitute any such 00013 * warranty, and no responsibility is assumed by the USGS in connection 00014 * therewith. 00015 * 00016 * For additional information, launch 00017 * $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see 00018 * the Privacy & Disclaimers page on the Isis website, 00019 * http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on 00020 * http://www.usgs.gov/privacy.html. 00021 */ 00022 00023 #include <iostream> 00024 #include <algorithm> 00025 #include "SpiceDbGen.h" 00026 #include "NaifStatus.h" 00027 00028 using namespace std; 00029 using namespace Isis; 00030 00031 /** 00032 * Constructs a new SpiceDbGen. 00033 * 00034 * @param type The type of kernel to be processed. Either, "SPK" or "CK. 00035 */ 00036 SpiceDbGen::SpiceDbGen(iString type){ 00037 p_type = type; 00038 calForm = "YYYY MON DD HR:MN:SC.### TDB ::TDB"; 00039 } 00040 00041 /** 00042 * Creates a Pvl object that stores all of the kernels under the condition 00043 * specified by the filter. 00044 * 00045 * @param quality The quality of the kernels that are being filtered into 00046 * the database. For example, "Reconstructed". 00047 * 00048 * @param location The directory in which the method searches for kernels. 00049 * 00050 * @param filter The regular expression used to match kernels of a 00051 * particular quality. This parameter is important, since it 00052 * is necessary to distinguish between kernels of different 00053 * qualities and/or different missions that may be placed in 00054 * the same directory. 00055 * 00056 * @return PvlObject 00057 * 00058 * @throws Isis::iException::Message 00059 */ 00060 PvlObject SpiceDbGen::Direct(iString quality, iString location, iString filter){ 00061 PvlObject result; 00062 00063 //Create a list of all of the files 00064 QStringList files = GetFiles(Filename(location), filter); 00065 PvlObject pvlKernel("change"); 00066 00067 //throw an error if no files are being added to this database 00068 if (files.size() == 0){ 00069 string message = "Your filter [" + location + "/" + filter + "]" 00070 + "has not detected any " + quality + " kernels"; 00071 throw Isis::iException::Message(Isis::iException::User,message,_FILEINFO_); 00072 } 00073 00074 for (int fileNum = 0 ; fileNum < files.size() ; fileNum++){ 00075 Filename currFile = ((string) location + "/" + files[fileNum].toStdString()); 00076 PvlGroup selection = AddSelection(currFile); 00077 selection += PvlKeyword("Type", quality); 00078 result.AddGroup(selection); 00079 } 00080 //check each group to make sure it is the same type as others 00081 PvlObject::PvlGroupIterator grp = result.BeginGroup(); 00082 iString type = "none"; 00083 while(grp != result.EndGroup()){ 00084 if (grp->Name() == "No coverage" || grp->Name() == "Null"){ 00085 result.DeleteGroup(grp->Name()); 00086 } 00087 else if (type == "none"){ 00088 type = grp->Name(); 00089 } 00090 else if (grp->Name() == type){ 00091 grp->SetName("Selection"); 00092 grp++; 00093 } 00094 else{ 00095 string message = "A kernel of type [" + grp->Name() +"] has been found in a directory for type [" + type +"]" ; 00096 throw Isis::iException::Message(Isis::iException::Programmer,message,_FILEINFO_); 00097 break; 00098 } 00099 } 00100 if (type == "SPK"){result.SetName("SpacecraftPosition");} 00101 else if (type == "CK"){result.SetName("SpacecraftPointing");} 00102 return result; 00103 } 00104 00105 /** 00106 * Essenetially a method call to the underlying QDir class which will filter 00107 * the files needed by Direct(). Files are returned in order of the time they 00108 * were most recently modified, the oldest file being first and the most 00109 * recently modified being last. 00110 * 00111 * @param location The directory in which the method searches for files. 00112 * 00113 * @param filter The regular expression used to match files of a 00114 * particular quality. This parameter is important, since it 00115 * is necessary to distinguish between kernels of different 00116 * qualities and/or different missions that may be placed in 00117 * the same directory. 00118 * 00119 * @return QStringList 00120 * 00121 */ 00122 QStringList SpiceDbGen::GetFiles(Filename location, iString filter){ 00123 filter.Remove("\\"); 00124 QDir dir(location.Expanded().c_str(), filter.c_str(), 00125 QDir::Time|QDir::Reversed); 00126 dir.setFilter(QDir::Files); 00127 return dir.entryList(); 00128 } 00129 00130 /** 00131 * Format a single kernel file to include the file. 00132 * 00133 * @param quality The quality of the kernels that are being filtered into 00134 * the database. For example, "Reconstructed". 00135 * 00136 * @param location The directory in which the method searches for kernels. 00137 * 00138 * @param filter The regular expression used to match kernels of a 00139 * particular quality. This parameter is important, since it 00140 * is necessary to distinguish between kernels of different 00141 * qualities and/or different missions that may be placed in 00142 * the same directory. 00143 * 00144 * @return PvlObject 00145 * 00146 * @throws Isis::iException::Message 00147 */ 00148 PvlGroup SpiceDbGen::AddSelection(Filename fileIn){ 00149 NaifStatus::CheckErrors(); 00150 00151 //finalize the filename so that it may be used in spice routines 00152 std::string tmp = fileIn.Expanded(); 00153 // const char* file = fileIn.Expanded().c_str(); 00154 furnsh_c(tmp.c_str()); 00155 SpiceChar fileType[32], source[2048]; 00156 SpiceInt handle; 00157 00158 SpiceBoolean found; 00159 kinfo_c(tmp.c_str(), 32, 2048, fileType, source, &handle, &found); 00160 iString currFile = fileType; 00161 00162 //create a spice cell capable of containing all the objects in the kernel. 00163 SPICEINT_CELL (currCell, 1000); 00164 //this resizing is done because otherwise a spice cell will append new data 00165 //to the last "currCell" 00166 ssize_c(0, &currCell); 00167 ssize_c(1000, &currCell); 00168 00169 //select which spice coverage routine to use. If a text kernel is detected, it 00170 //will be returned here and weeded out at the end of Direct(). This helps 00171 //to protect the user from inadvertently adding "." and ".." to their filters 00172 if (currFile == "SPK"){spkobj_c(tmp.c_str(), &currCell);} 00173 else if (currFile == "CK"){ckobj_c(tmp.c_str(), &currCell);} 00174 else if (currFile == "TEXT"){return PvlGroup("No coverage");} 00175 00176 PvlGroup result; 00177 //iterate through every body in the kernel 00178 for (int bodyCount = 0 ; bodyCount < card_c(&currCell) ; bodyCount++){ 00179 //get the NAIF body code 00180 int body = SPICE_CELL_ELEM_I(&currCell, bodyCount); 00181 00182 //only provide coverage for negative NAIF codes 00183 //(Positive codes indicate planetary bodies, negatives indicate 00184 // spacecraft and instruments) 00185 if (body < 0){ 00186 NaifStatus::CheckErrors(); 00187 00188 //find the correct coverage window 00189 if (currFile == "SPK") { 00190 // 2000 is the max coverage window size for an SPK kernel 00191 SPICEDOUBLE_CELL (cover, 2000); 00192 ssize_c(0, &cover); 00193 ssize_c(2000, &cover); 00194 spkcov_c(tmp.c_str(), body, &cover); 00195 00196 NaifStatus::CheckErrors(); 00197 00198 result = FormatIntervals(cover, currFile); 00199 } 00200 else if (currFile == "CK") { 00201 // 200,000 is the max coverage window size for a CK kernel 00202 SPICEDOUBLE_CELL (cover, 200000); 00203 ssize_c(0, &cover); 00204 ssize_c(200000, &cover); 00205 ckcov_c(tmp.c_str(), body, SPICEFALSE, "SEGMENT", 0.0, "TDB", &cover); 00206 00207 NaifStatus::CheckErrors(); 00208 00209 result = FormatIntervals(cover, currFile); 00210 } 00211 } 00212 } 00213 00214 iString outFile = fileIn.OriginalPath(); 00215 result += PvlKeyword("File", outFile + "/" + fileIn.Name()); 00216 00217 NaifStatus::CheckErrors(); 00218 return result; 00219 } 00220 00221 PvlGroup SpiceDbGen::FormatIntervals(SpiceCell &coverage, string type){ 00222 NaifStatus::CheckErrors(); 00223 00224 PvlGroup result(type); 00225 SpiceChar begStr[32], endStr[32]; 00226 //Get the number of intervals in the object. 00227 int niv = card_c ( &coverage ) / 2; 00228 //Convert the coverage interval start and stop times to TDB 00229 double begin, end; 00230 for (int j = 0; j < niv; j++ ){ 00231 //Get the endpoints of the jth interval. 00232 wnfetd_c ( &coverage, j, &begin, &end ); 00233 //Convert the endpoints to TDB calendar 00234 timout_c ( begin, calForm, 32, begStr); 00235 timout_c ( end, calForm, 32, endStr); 00236 result += PvlKeyword("Time", "(\"" + (string)begStr + 00237 "\", \"" + (string)endStr + "\")"); 00238 } 00239 00240 NaifStatus::CheckErrors(); 00241 00242 return result; 00243 } 00244 00245 void SpiceDbGen::FurnishDependencies(string sclk, string lsk){ 00246 NaifStatus::CheckErrors(); 00247 00248 //furnish the lsk file 00249 furnsh_c(lsk.c_str()); 00250 00251 //get the sclk, if such a file was specified 00252 if (sclk != ""){ 00253 furnsh_c(sclk.c_str()); 00254 } 00255 00256 NaifStatus::CheckErrors(); 00257 }