USGS

Isis 3.0 Application Source Code Reference

Home

SpiceDbGen.cpp

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