Example #1
0
 /**
  *  @param island A list of all cubes that are on this island are desired
  *
  *  @returns A list of CubeSerialNumbers which are located on the given island
  */
 const QVector< QString > ControlGraph::GetCubesOnIsland(const int & island)
     const
 {
   if (connected)
   {
     std::string message = "\n\nGetCubesOnIsland called on connected graph ";
     message += "with no islands!!!\n\n";
     throw Isis::iException::Message(Isis::iException::Programmer, message,
                                     _FILEINFO_);
   }
   
   ASSERT(islands->size() != 0);
   
   if (island < 0 || island >= islands->size())
   {
     iString message = "\n\nA list of cubes was requested from island ";
     message += iString(island);
     message += "\nbut that island does not exist!!!";
     message += "\n\nThere are " + iString(islands->size()) + " islands ";
     message += "numbered from 0 to " + iString(islands->size() - 1) + "\n\n";
     throw Isis::iException::Message(Isis::iException::Programmer, message,
                                     _FILEINFO_);
   }
   
   QVector< QString > cubeList;
   for (int i = 0; i < (*islands)[island].size(); i++)
   {
     cubeList.push_back(cubeIndexToIdHash->value((*islands)[island][i]));
   }
   
   return cubeList;    
 }
Example #2
0
  void Histogram::SetBinRange(double binStart, double binEnd) {
    if(binEnd < binStart) {
      string msg = "The binning range start [" + iString(binStart) + 
        " must be less than the end [" + iString(binEnd) + ".";
      throw iException::Message(iException::Programmer,msg,_FILEINFO_);
    }

    p_binRangeStart = binStart;
    p_binRangeEnd = binEnd;
  }
Example #3
0
 /**
  * @brief Loops through PvlKeyword containing Kernel file names
  * 
  * This method interogates a PvlKeyword that is determined to
  * contain SPICE kernel names.  It will optionally load the
  * kernels if initially requested and then adds the name to the
  * internally managed list.
  * 
  * Some keywords may contain special keywords.  These are ignored in this
  * method and can be handled explicitly in other methods.
  * 
  * @param key PvlKeyword containing SPICE kernels
  * @see  loadKernelFromTable()
  */
 void Kernels::loadKernel(PvlKeyword &key) {
   for (int i=0; i<key.Size(); i++) {
     if (key[i] == "") continue;
     if (iString(key[i]).UpCase() == "NULL") continue;
     if (iString(key[i]).UpCase() == "NADIR") continue;
     if (iString(key[i]).UpCase() == "TABLE") continue;
     Isis::Filename file(key[i]);
     if (!file.exists()) {
       string msg = "Spice file does not exist [" + file.Expanded() + "]";
       throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
     }
     string fileName(file.Expanded());
     if (_furnish) furnsh_c(fileName.c_str());
   }
 }
void selector::Begin(TTree *) {
//  Can pass a string option which is 4th argument of runselector.C
//  You can retrieve the option in any function in this file.
  TString option = GetOption();
  printf("Begin: The option is %s\n",option.Data());
//  This code parses the options and finds options separated by white space
  TObjArray *Strings = option.Tokenize(" "); 
  if(Strings->GetEntriesFast()) {
    TIter iString(Strings);
    TObjString* os=0;
    Int_t j=0;
    while ((os=(TObjString*)iString())) {
      printf("token #%d ='%s'\n",j++,  os->GetString().Data());
    }
  }
  delete Strings;

//  Print help message to users
  if( option == "-h" ) {
    printf("selector_null: sample selector function\n");
    printf("    Edward Diehl  3/29/09\n");
    exit(0);    //Abort job
  }

//Book histograms
//  histlist = new TList();
  raw_adc = new TH1F("raw_adc","ADC",100,0.,500.);
  raw_tdc = new TH1F("raw_tdc","TDC",100,0.,3000.);
  raw_adc_ntube = new TH2F("raw_adc_ntube","ADC",100,0.,500.,1,0.,MAXCHAMBERS);
  rawMdt_gposX_gposY = new TH2F("rawMdt_gposX_gposY","rawMdt XvY",100,-15,15,100,-15,15);
  rawMdt_gposY_gposZ = new TH2F("rawMdt_gposY_gposZ","rawMdt YvZ",100,-15,15,100,-15,15);
//Loop over chambers
/*  for(int i=0;1<MAXCHAMBERS;i++){
     rawadc_chamber[i] = new TH1F(Form("rawADC_%s",chlist[i].calname),Form("%s raw ADC",chlist[i].calname),100,0,500); //chlist is array in chamberlist that contains detector names e.g BEE_1_2
 //  }

//loop over multilayer and chambers
  for(int j=0; j<MAXCHAMBERS; j++ ) {   //Chambers
    for( int i=0; i<2; i++ ) {           //ML
       int ml = i + 1 ;
       raw_adc[j][i] = 
       raw_tdc[j][i] =          
*/


   
  
}
Example #5
0
  /**
   * Sets the vector of Columns and writes out the first row of the file.
   * 
   * @param cols A vector of Columns, setting the format of the table
   */
  void WriteTabular::SetColumns(std::vector <Column> cols ){
    for (unsigned int index=0; index < cols.size(); index++) {
      Column thisCol = cols[index];
      std::string thisTitle = thisCol.Name();

      if (thisTitle.length() > thisCol.Width()) {
        std::string message = "Column header [" + thisTitle + "] is wider " +
          "than the set width for column [" + iString((int)index) + "]";
          throw Isis::iException::Message(Isis::iException::User,message,_FILEINFO_);
      }

      int iteration = 0;
      while (thisTitle.length() < thisCol.Width()) {
        if (thisCol.Alignment() == Column::Left) {
          thisTitle += " ";
        }
        else if (thisCol.Alignment() == Column::Right ||
                 thisCol.Alignment() == Column::Decimal) {
          thisTitle = " " + thisTitle;
        }
        else {
          std::string message = "Alignment is improperly set";
          throw Isis::iException::Message(Isis::iException::User,message,_FILEINFO_);
        }
        iteration++;
      }//end while

      p_cols.push_back(thisCol);
      p_outfile << thisTitle;
      if (index < (cols.size()-1)) {
        p_outfile << p_delimiter;
      }
    }//end for
    p_outfile << "\n";
  }//end function
Example #6
0
std::vector<TString> GA::split_string(TString line)
{

  std::vector<TString> vtokens;
  TObjArray* tokens = TString(line).Tokenize(",");

  if(tokens->GetEntriesFast()) {
    TIter iString(tokens);
    TObjString* os=0;
    while ((os=(TObjString*)iString())) {
      vtokens.push_back( os->GetString() );
    }
  }
  delete tokens;
  return vtokens;
}
Example #7
0
  void Spice::ComputeSolarLongitude(double et) {
    NaifStatus::CheckErrors();
    
    if (iString(Target()).UpCase() == "SKY") {
      p_solarLongitude = -999.0;
      return;
    } 

    if (p_bodyRotation->IsCached()) return;

    double tipm[3][3], npole[3];
    char frameName[32];
    SpiceInt frameCode;
    SpiceBoolean found;

    cidfrm_c (p_spkBodyCode, sizeof(frameName), &frameCode, frameName, &found);

    if ( found ) {
      pxform_c("J2000",frameName,et,tipm);
    }
    else {
      tipbod_c("J2000",p_spkBodyCode,et,tipm);
    }
 
    for (int i=0; i<3; i++) {
      npole[i] = tipm[2][i];
    }

    double state[6], lt;
    spkez_c(p_spkBodyCode,et,"J2000","NONE",10,state,&lt);

    double uavel[3];
    ucrss_c(state,&state[3],uavel);

    double x[3], y[3], z[3];
    vequ_c(uavel,z);
    ucrss_c(npole,z,x);
    ucrss_c(z,x,y);

    double trans[3][3];
    for (int i=0; i<3; i++) {
      trans[0][i] = x[i];
      trans[1][i] = y[i];
      trans[2][i] = z[i];
    }

    spkez_c(10,et,"J2000","LT+S",p_spkBodyCode,state,&lt);

    double pos[3];
    mxv_c(trans,state,pos);

    double radius, ls, lat;
    reclat_c(pos,&radius,&ls,&lat);
    ls *= 180.0 / Isis::PI;
    if (ls < 0.0) ls += 360.0;
    else if (ls > 360.0) ls -= 360.0;
    p_solarLongitude = ls;

    NaifStatus::CheckErrors();
  }
Example #8
0
 /**
   * Set the Hapke Henyey Greenstein coefficient for the single
   * particle phase function. This is one of two coefficients
   * needed for the single particle phase function. This parameter
   * is limited to values that are >=0 and <=1.
   *
   * @param hg2  Hapke Henyey Greenstein coefficient, default is 0.0
   */
  void HapkeHen::SetPhotoHg2 (const double hg2) {
    if (hg2 < 0.0 || hg2 > 1.0) {
      string msg = "Invalid value of Hapke Henyey Greenstein hg2 [" +
          iString(hg2) + "]";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    p_photoHg2 = hg2;
  }
Example #9
0
 /**
   * Set the Hapke Henyey Greenstein coefficient for the single
   * particle phase function. This is one of two coefficients
   * needed for the single particle phase function. This parameter
   * is limited to values that are >-1 and <1.
   *
   * @param hg1  Hapke Henyey Greenstein coefficient, default is 0.0
   */
  void HapkeHen::SetPhotoHg1 (const double hg1) {
    if (hg1 <= -1.0 || hg1 >= 1.0) {
      string msg = "Invalid value of Hapke Henyey Greenstein hg1 [" +
          iString(hg1) + "]";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    p_photoHg1 = hg1;
  }
Example #10
0
 /**
   * Set the normalization function parameter. This is the
   * reference incidence angle to which the image photometry will
   * be normalized. This parameter is limited to values that are
   * >=0 and <90.
   * 
   * @param incref  Normalization function parameter, default
   *                is 0.0
   */
  void Mixed::SetNormIncref (const double incref) {
    if (incref < 0.0 || incref >= 90.0) {
      std::string msg = "Invalid value of normalization incref [" +
          iString(incref) + "]";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }

    p_normIncref = incref;
  }
Example #11
0
  /**
   * Set the Atmospheric function parameter. This is the
   * atmospheric shell thickness normalized to the planet radius
   * and is used to modify angles to get more accurate path
   * lengths near the terminator (ratio of scale height to the
   * planetary radius). This parameter is limited to values that
   * are >=0.
   *
   * @param hnorm  Atmospheric function parameter, default is 0.003
   */
  void Anisotropic1::SetAtmosHnorm (const double hnorm) {
    if (hnorm < 0.0) {
      std::string msg = "Invalid value of Atmospheric hnorm [" +
                        iString(hnorm) + "]";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }

    p_atmosHnorm = hnorm;
  }
Example #12
0
 /**
  * Returns true if the kernel group has kernel files
  *
  * @param lab Label containing Instrument and Kernels groups.
  * @return bool - status of kernel files in the kernel group
  */
  bool Spice::HasKernels(Isis::Pvl &lab) {

    // Get the kernel group and check main kernels
    Isis::PvlGroup kernels = lab.FindGroup("Kernels",Isis::Pvl::Traverse);
    std::vector<string> keywords;
    keywords.push_back("TargetPosition");

    if (kernels.HasKeyword("SpacecraftPosition")) {
      keywords.push_back("SpacecraftPosition");
    }
    else {
      keywords.push_back("InstrumentPosition");
    }

    if (kernels.HasKeyword("SpacecraftPointing")) {
      keywords.push_back("SpacecraftPointing");
    }
    else {
      keywords.push_back("InstrumentPointing");
    }

    if (kernels.HasKeyword("Frame")) {
      keywords.push_back("Frame");
    }

    if (kernels.HasKeyword("Extra")) {
      keywords.push_back("Extra");
    }

    Isis::PvlKeyword key;
    for (int ikey = 0; ikey < (int) keywords.size(); ikey++) {
      key = kernels[ikey];

      for (int i=0; i<key.Size(); i++) {
        if (key[i] == "") return false;
        if (iString(key[i]).UpCase() == "NULL") return false;
        if (iString(key[i]).UpCase() == "NADIR") return false;
        if (iString(key[i]).UpCase() == "TABLE") return false;
      }
    }
    return true;
  }
Example #13
0
  //! Load/furnish NAIF kernel(s)
  void Spice::Load(Isis::PvlKeyword &key) {
    NaifStatus::CheckErrors();

    for (int i=0; i<key.Size(); i++) {
      if (key[i] == "") continue;
      if (iString(key[i]).UpCase() == "NULL") break;
      if (iString(key[i]).UpCase() == "NADIR") break;
      if (iString(key[i]).UpCase() == "TABLE") break;
      Isis::Filename file(key[i]);
      if (!file.exists()) {
        string msg = "Spice file does not exist [" + file.Expanded() + "]";
        throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
      }
      string fileName(file.Expanded());
      furnsh_c(fileName.c_str());
      p_kernels.push_back((string)key[i]);
    }

    NaifStatus::CheckErrors();
  }
Example #14
0
  /**
   * Writes a floating-point value out to the next column in the current row
   * 
   * @param item The value to be printed out
   */
  void WriteTabular::Write(double item){
    Column thisCol = p_cols[p_curCol];
    if (thisCol.DataType() != Column::Real &&
        thisCol.DataType() != Column::Pixel) {
      std::string message = "Wrong data type for this Column";
      throw Isis::iException::Message(Isis::iException::User,message,_FILEINFO_);
    }

    //Check for special pixels, if it's a pixel column
    if (thisCol.DataType() == Column::Pixel && IsSpecial(item)) {
      if (IsNullPixel(item)) {
        Write("Null");
        return;
      }
      if (IsHisPixel(item)) {
        Write("His");
        return;
      }
      if (IsHrsPixel(item)) {
        Write("Hrs");
        return;
      }
      if (IsLisPixel(item)) {
        Write("Lis");
        return;
      }
      if (IsLrsPixel(item)) {
        Write("Lrs");
        return;
      }
    }

    iString thisItem(item);


    if (thisCol.Alignment() == Column::Decimal) {

      //Format and round the number

      //First, split the number at the decimal point
      iString tempString = thisItem;
      iString intPart = tempString.Token(".");
      //Make the fractional portion appear as such, so the iomanipulators
      //handle it properly
      if (tempString != "") {
        tempString = "0." + tempString;
      }
      else tempString = "0.0";

      //Put the fractional portion into a stringstream, and use
      //stream manipulators to round it properly
      std::stringstream b;
      b << std::showpoint
        << std::setprecision(thisCol.Precision())
        << tempString.ToDouble();

      //if the rounding causes a rollover (i.e. the decimal portion is greater
      //than 0.95) increment the integer portion
      if (iString(b.str()).ToDouble() >= 1) {
        intPart = iString(intPart.ToInteger() + 1);
      }

      //Put it back into an iString, for easier manipulation
      tempString = b.str();
      tempString.Token(".");
      //Add any zeros necessary to pad the number
      while (tempString.size() < thisCol.Precision()) {
        tempString += "0";
      }

      //Put the number back together, adding the decimal point in the right location
      thisItem = intPart + "." + tempString;
    }
    std::stringstream tempStream;
    tempStream.width(thisCol.Width());
    tempStream.fill(' ');

    if (thisCol.Alignment() == Column::Left) {
      tempStream.setf(std::ios::left);
    }
    else tempStream.setf(std::ios::right);

    tempStream << thisItem;
    thisItem = tempStream.str();

    if (p_curCol == 0) {
      p_rows++;
    }

    //If the number is too wide for the column, replace with a string of stars
    if (thisItem.length() > thisCol.Width()) {
      thisItem = "*";
      while (thisItem.length() < thisCol.Width()) {
        thisItem += "*";
      }
    }

    if (p_curCol < (p_cols.size()-1)) {
      thisItem += p_delimiter;
      p_curCol++;
    }
    else {
      thisItem += "\n";
      p_curCol = 0;
    }
    p_outfile << thisItem;

  }
Example #15
0
  // TODO: DOCUMENT EVERYTHING
  Spice::Spice (Isis::Pvl &lab) {
    NaifStatus::CheckErrors();

    // Initialization
    p_startTime = 0.0;
    p_endTime = 0.0;
    p_cacheSize = 0;
    p_et = -DBL_MAX;
    p_allowDownsizing = false;

    // Get the kernel group and load main kernels
    Isis::PvlGroup kernels = lab.FindGroup("Kernels",Isis::Pvl::Traverse);

    // Get the time padding first
    if(kernels.HasKeyword("StartPadding")) {
      p_startTimePadding = kernels["StartPadding"][0];
    }
    else {
      p_startTimePadding = 0.0;
    }

    if(kernels.HasKeyword("EndPadding")) {
      p_endTimePadding  = kernels["EndPadding"][0];
    }
    else {
      p_endTimePadding = 0.0;
    }


//  Modified  to load planetary ephemeris SPKs before s/c SPKs since some 
//  missions (e.g., MESSENGER) may augment the s/c SPK with new planet 
//  ephemerides. (2008-02-27 (KJB))
    Load(kernels["TargetPosition"]);
    Load(kernels["InstrumentPosition"]);
    Load(kernels["InstrumentPointing"]);

    if (kernels.HasKeyword("Frame")) {
      Load(kernels["Frame"]);
    }

    if (kernels.HasKeyword("Extra")) {
      Load(kernels["Extra"]);
    }

    Load(kernels["TargetAttitudeShape"]);
    Load(kernels["Instrument"]);
    Load(kernels["InstrumentAddendum"]);  // Always load after instrument
    Load(kernels["LeapSecond"]);
    Load(kernels["SpacecraftClock"]);

    // Get NAIF ik, spk, sclk, and ck codes
    //
    //    Use ikcode to get parameters from instrument kernel such as focal
    //    length, distortions, focal plane maps, etc
    //
    //    Use spkcode to get spacecraft position from spk file
    //
    //    Use sclkcode to transform times from et to tics
    //
    //    Use ckcode to transform between frames
    //
    //    Use bodycode to obtain radii and attitude (pole position/omega0)
    //
    //    Use spkbodycode to read body position from spk
    
    string trykey = "NaifIkCode";
    if (kernels.HasKeyword("NaifFrameCode")) trykey = "NaifFrameCode";
    p_ikCode = (int) kernels[trykey];
    
    p_spkCode = p_ikCode / 1000;
    p_sclkCode = p_spkCode;
    p_ckCode = p_ikCode;
    
    Isis::PvlGroup &inst = lab.FindGroup("Instrument",Isis::Pvl::Traverse);
    p_target = (string) inst["TargetName"];
    
    if (iString(p_target).UpCase() == "SKY") {
      p_bodyCode = p_spkCode;
      p_radii[0] = p_radii[1] = p_radii[2] = 1.0;
      p_sky = true;
    }
    else {
      p_bodyCode = NaifBodyCode();
      SpiceInt n;
      bodvar_c(p_bodyCode,"RADII",&n,p_radii);
      p_sky = false;
    }
    p_spkBodyCode = p_bodyCode;
    
    // Override them if they exist in the labels
    if (kernels.HasKeyword("NaifSpkCode")) p_spkCode = (int) kernels["NaifSpkCode"];
    if (kernels.HasKeyword("NaifCkCode")) p_ckCode = (int) kernels["NaifCkCode"];
    if (kernels.HasKeyword("NaifSclkCode")) p_sclkCode = (int) kernels["NaifSclkCode"];
    if (kernels.HasKeyword("NaifBodyCode")) p_bodyCode = (int) kernels["NaifBodyCode"];
    if (!p_sky) {
      if (kernels.HasKeyword("NaifSpkBodyCode")) p_spkBodyCode = (int) kernels["NaifSpkBodyCode"];
    }
    
    // Create our SpicePosition and SpiceRotation objects
    p_bodyRotation = 0;
    p_instrumentRotation = 0;
    p_instrumentPosition = 0;
    p_sunPosition = 0;
    
    if (p_sky) {
      // Create the identity rotation for sky targets
      // Everything in bodyfixed will really be J2000
      p_bodyRotation = new SpiceRotation(1);
    }
    else {
      char frameName[32];
      SpiceInt frameCode;
      SpiceBoolean found;
      cidfrm_c (p_spkBodyCode, sizeof(frameName), &frameCode, frameName, &found);

      if (!found) { 
        string naifTarget = string("IAU_") + iString(p_target).UpCase();
        namfrm_c(naifTarget.c_str(),&frameCode);
        if (frameCode == 0) {
          string msg = "Can not find NAIF code for [" + naifTarget + "]";
          throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
        }
      }
      p_bodyRotation = new SpiceRotation(frameCode);
    }
    p_instrumentRotation = new SpiceRotation(p_ckCode);
    p_instrumentPosition = new SpicePosition(p_spkCode,p_spkBodyCode);
    p_sunPosition = new SpicePosition(10,p_bodyCode);
    
    // Check to see if we have nadir pointing that needs to be computed &
    // See if we have table blobs to load
    if (iString((std::string)kernels["TargetPosition"]).UpCase() == "TABLE") {
      Table t("SunPosition",lab.Filename());
      p_sunPosition->LoadCache(t);

      Table t2("BodyRotation",lab.Filename());
      p_bodyRotation->LoadCache(t2);
      if (t2.Label().HasKeyword("SolarLongitude")) {
        p_solarLongitude = t2.Label()["SolarLongitude"];
      }
      else {
        SolarLongitude();
      }
    }

    //  We can't assume InstrumentPointing & InstrumentPosition exist, old
    //  files may be around with the old keywords, SpacecraftPointing &
    //  SpacecraftPosition.  The old keywords were in existance before the
    //  Table option, so we don't need to check for Table under the old
    //  keywords.

    if(kernels["InstrumentPointing"].Size() == 0) {
      throw iException::Message(iException::Camera, 
                                "No camera pointing available", 
                                _FILEINFO_);
    }

    //  2009-03-18  Tracie Sucharski - Removed test for old keywords, any files
    // with the old keywords should be re-run through spiceinit.
    if (iString((std::string)kernels["InstrumentPointing"]).UpCase() == "NADIR") {
      delete p_instrumentRotation;
      p_instrumentRotation = new SpiceRotation(p_ikCode,p_spkBodyCode);
    }
    else if (iString((std::string)kernels["InstrumentPointing"]).UpCase() == "TABLE") {
      Table t("InstrumentPointing",lab.Filename());
      p_instrumentRotation->LoadCache(t);
    }

    if(kernels["InstrumentPosition"].Size() == 0) {
      throw iException::Message(iException::Camera, 
                                "No instrument position available", 
                                _FILEINFO_);
    }

    if (iString((std::string)kernels["InstrumentPosition"]).UpCase() == "TABLE") {
      Table t("InstrumentPosition",lab.Filename());
      p_instrumentPosition->LoadCache(t);
    }

    NaifStatus::CheckErrors();
  }
Example #16
0
  /** 
   * This method looks for any naif errors that might have occurred. It 
   * then compares the error to a list of known naif errors and converts
   * the error into an iException.
   * 
   * @param resetNaif True if the NAIF error status should be reset (naif calls valid)
   */
  void NaifStatus::CheckErrors(bool resetNaif) {
    if(!initialized) {
      SpiceChar returnAct[32] = "RETURN";
      SpiceChar printAct[32] = "NONE";
      erract_c ( "SET", sizeof(returnAct), returnAct); // Reset action to return
      errprt_c ( "SET", sizeof(printAct), printAct);   // ... and print nothing
      initialized = true;
    }

    // Do nothing if NAIF didn't fail
    //getmsg_c("", 0, NULL);
    if(!failed_c()) return;

    // This method has been documented with the information provided
    //   from the NAIF documentation at:
    //    naif/cspice61/packages/cspice/doc/html/req/error.html


    // This message is a character string containing a very terse, usually 
    // abbreviated, description of the problem. The message is a character 
    // string of length not more than 25 characters. It always has the form:
    // SPICE(...)
    // Short error messages used in CSPICE are CONSTANT, since they are 
    // intended to be used in code. That is, they don't contain any data which 
    // varies with the specific instance of the error they indicate.
    // Because of the brief format of the short error messages, it is practical 
    // to use them in a test to determine which type of error has occurred. 
    const int SHORT_DESC_LEN = 26;
    SpiceChar naifShort[SHORT_DESC_LEN];
    getmsg_c("SHORT", SHORT_DESC_LEN, naifShort);

    // This message may be up to 1840 characters long. The CSPICE error handling 
    // mechanism makes no use of its contents. Its purpose is to provide human-readable 
    // information about errors. Long error messages generated by CSPICE routines often 
    // contain data relevant to the specific error they describe.
    const int LONG_DESC_LEN = 1841;
    SpiceChar naifLong[LONG_DESC_LEN];
    getmsg_c("LONG", LONG_DESC_LEN, naifLong);

    // Search for known naif errors...
    iString errMsg;

    Pvl error;
    PvlGroup errorDescription("ErrorDescription");
    errorDescription.AddKeyword(PvlKeyword("ShortMessage", naifShort));
    errorDescription.AddKeyword(PvlKeyword("LongMessage", naifLong));
    error.AddGroup(errorDescription);

    PvlTranslationManager trans(error, "$base/translations/NaifErrors.trn");

    try {
      errMsg = trans.Translate("ShortMessage");
    }
    catch(iException &e) {
      e.Clear();
      errMsg = "An unknown NAIF error has been encountered.";
    }

    try {
      errMsg += " " + trans.Translate("LongMessage");
    }
    catch(iException &e) {
      e.Clear();
    }

    // Now process the error
    if(resetNaif) {
      reset_c();
    }

    errMsg += " The short explanation ";
    errMsg += "provided by NAIF is [" + iString(naifShort) + "]. "; 
    errMsg += "The Naif error is [" + iString(naifLong) + "]";

    throw iException::Message(iException::Spice, errMsg, _FILEINFO_);
  }