Beispiel #1
0
  /** Set the coefficients of a polynomial fit to each
   * of the three camera angles for the time period covered by the
   * cache, angle = a + bt + ct**2, where t = (time - p_baseTime)/ p_timeScale.
   *
   */
  void PixelOffset::SetPolynomial () {
    Isis::PolynomialUnivariate function1(p_degree);       //!< Basis function fit to 1st rotation angle
    Isis::PolynomialUnivariate function2(p_degree);       //!< Basis function fit to 2nd rotation angle
                                    //
    LeastSquares *fitAng1 = new LeastSquares ( function1 );
    LeastSquares *fitAng2 = new LeastSquares ( function2 );

    std::vector<double> time;

    // Load the known values to compute the fit equation
    for (std::vector<double>::size_type pos=0;pos < p_cacheTime.size();pos++) {
      double t = p_cacheTime.at(pos);

// Base fit on extent of coverage in the input offset file
      if (t >= p_times[0] && t <= p_times[p_times.size()-1]) {
        time.push_back( (t - p_baseTime) / p_timeScale );
        SetEphemerisTime( t );
        fitAng1->AddKnown ( time, p_cacheAngle1[pos] );
        fitAng2->AddKnown ( time, p_cacheAngle2[pos] );
        time.clear();
      }
    }

    if (fitAng1->Knowns() == 0) {
      std::string msg;
      msg = "Cube time range is not covered by jitter file";
      throw iException::Message(Isis::iException::User,msg,_FILEINFO_);
    }

    //Solve the equations for the coefficients
    fitAng1->Solve();
    fitAng2->Solve();

    // Delete the least squares objects now that we have all the coefficients
    delete fitAng1;
    delete fitAng2;

    // For now assume both angles are fit to a polynomial.  Later they may
    // each be fit to a unique basis function.
    // Fill the coefficient vectors

    for ( int i = 0;  i < function1.Coefficients(); i++) {
      p_ang1Coefficients.push_back( function1.Coefficient( i ) );
      p_ang2Coefficients.push_back( function2.Coefficient( i ) );
    }

//    std::cout<<"Angle1 coeff="<<p_ang1Coefficients[0]<<" "<<p_ang1Coefficients[1]<<" "<<p_ang1Coefficients[2]<<std::endl;
//    std::cout<<"Angle2 coeff="<<p_ang2Coefficients[0]<<" "<<p_ang2Coefficients[1]<<" "<<p_ang2Coefficients[2]<<std::endl;

    }
Beispiel #2
0
  HiresCamera::HiresCamera (Pvl &lab) : FramingCamera(lab) {

    // Get the camera characteristics
    iString filter = (string)(lab.FindGroup("BandBin", Pvl::Traverse))["FilterName"];
    filter = filter.UpCase();

    SetFocalLength ();
    SetPixelPitch ();

    // Get the start time in et
    PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
    string stime = inst["StartTime"];

    double time; 
    str2et_c(stime.c_str(),&time);



    // Do not correct time for center of the exposure duration. This is because
    // the kernels were built to accept the start times of the images. 
    // time += ((double)inst["ExposureDuration"] / 1000.0) / 2.0; // Add half
    // exposure duration in milliseconds

    // Setup detector map
    new CameraDetectorMap(this);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());

    focalMap->SetDetectorOrigin (
                   Spice::GetDouble("INS" + (iString)(int)NaifIkCode() +
                                    "_BORESIGHT_SAMPLE"), 
                   Spice::GetDouble("INS" + (iString)(int)NaifIkCode() +
                                    "_BORESIGHT_LINE"));

    // Setup distortion map 
    new CameraDistortionMap(this);

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    SetEphemerisTime(time);
    LoadCache();
  }
Beispiel #3
0
  /** Cache J2000 rotation quaternion over a time range.
   *
   * This method will load an internal cache with frames over a time
   * range.  This prevents the NAIF kernels from being read over-and-over
   * again and slowing an application down due to I/O performance.  Once the
   * cache has been loaded then the kernels can be unloaded from the NAIF
   * system.
   *
   * @param startTime   Starting ephemeris time in seconds for the cache
   * @param endTime     Ending ephemeris time in seconds for the cache
   * @param size        Number of frames to keep in the cache
   *
   */
  void PixelOffset::LoadAngles ( std::vector<double> cacheTime ) {
    p_cacheTime = cacheTime;
    // Make sure angles aren't already loaded TBD
/*    if () {
      std::string msg = "An angle cache has already been created";
      throw Isis::iException::Message(Isis::iException::Programmer,msg,_FILEINFO_);
    } */

    // Loop and load the angle caches
    for (size_t i=0; i<p_cacheTime.size(); i++) {
      double et = p_cacheTime[i];
      SetEphemerisTime(et);
      p_cacheAngle1.push_back( (p_angle1 - p_sampOff)/p_sampScale );
      p_cacheAngle2.push_back( (p_angle2 - p_lineOff)/p_lineScale);

//      std::cout<<p_angle1<<"     "<<p_angle2<<"     "<<et <<std::endl;
    }
  }
Beispiel #4
0
  IssWACamera::IssWACamera (Pvl &lab) : FramingCamera(lab) {
    PvlGroup bandBin = lab.FindGroup ("BandBin",Pvl::Traverse);
    // Get the camera characteristics
    iString key = string("INS"+(iString)(int)NaifIkCode()+"_")+ (string)bandBin["FilterName"] + "_FOCAL_LENGTH";
    key = key.Convert("/",'_');
    double focalLength = Spice::GetDouble(key);
    
    SetFocalLength (focalLength);
    SetPixelPitch ();
    InstrumentRotation()->SetFrame(Spice::GetInteger("INS_"+(iString)(int)NaifIkCode()+"_FRAME_ID"));


    // Get the start time in et
    PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
    string stime = inst["StartTime"];
    double et; 
    str2et_c(stime.c_str(),&et);
    double exposureDuration = (double)inst["ExposureDuration"] /1000.0;
    et += exposureDuration / 2.0;

    // Setup detector map
    int summingMode = inst["SummingMode"];
    CameraDetectorMap *detectorMap = new CameraDetectorMap(this);
    detectorMap->SetDetectorLineSumming(summingMode);
    detectorMap->SetDetectorSampleSumming(summingMode);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());

    focalMap->SetDetectorOrigin (Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_BORESIGHT_SAMPLE"), 
                                 Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_BORESIGHT_LINE"));

    // Setup distortion map
    double k1 = Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_K1");
    new RadialDistortionMap(this, k1);

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);
  
    SetEphemerisTime(et);
    LoadCache();
  }
Beispiel #5
0
    // constructors
    LoHighCamera::LoHighCamera (Pvl &lab) : FramingCamera(lab) {
      // Get the Instrument label information needed to define the camera for this frame
      PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
      iString spacecraft = (string)inst["SpacecraftName"];
      iString instId = (string)inst["InstrumentId"];

      // Turn off the aberration corrections for the instrument position object
        InstrumentPosition()->SetAberrationCorrection("NONE");

        // Get the camera characteristics
      SetFocalLength ();
      SetPixelPitch ();

      // Get the start time in et
      string stime = inst["StartTime"];
      double time; 
      str2et_c(stime.c_str(),&time);

      // Setup focal plane map

      LoCameraFiducialMap fid( inst, NaifIkCode());

      // Setup detector map
      new CameraDetectorMap(this);

      // Setup focalplane map
      CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());
      // Try (0.,0.)
      focalMap->SetDetectorOrigin(0.0,0.0);

      // Setup distortion map
      LoHighDistortionMap *distortionMap = new LoHighDistortionMap(this);
      distortionMap->SetDistortion(NaifIkCode());
      // Setup the ground and sky map
      new CameraGroundMap(this);
      new CameraSkyMap(this);

      SetEphemerisTime(time);
      LoadCache();
    }
Beispiel #6
0
  /** Set ephemeris time for the high pass filtered rotation
   * from the instrument frame to the true (corrected) instrument
   * frame.  [TC] = [angle2 - Pangle2(t)]  [angle1 - Pangle1(t)]
   *                                  2                   1
   * where t = (time - p_baseTime) / p_timeScale, and n = p_degree.
   *
   * @param [in] et Ephemeris time
   *
   */
  std::vector<double> PixelOffset::SetEphemerisTimeHPF ( const double et ) {

    Isis::PolynomialUnivariate function1( p_degree );
    Isis::PolynomialUnivariate function2( p_degree );

    //If outside the range of the offsets just return the identity matrix
    if (et < p_times[0] || et > p_times[p_times.size()-1]) {
      return (p_I);
    }

    // Load the functions with the coefficients
    function1.SetCoefficients ( p_ang1Coefficients );
    function2.SetCoefficients ( p_ang2Coefficients );

    // Compute polynomial approximations to angles, pangle1 and pangle2
    std::vector<double> rtime;
    rtime.push_back((et - p_baseTime) / p_timeScale);
    double pangle1 = p_sampOff + p_sampScale*function1.Evaluate (rtime);
    double pangle2 = p_lineOff + p_lineScale*function2.Evaluate (rtime);

    // Compute p_angles for this time
    SetEphemerisTime(et);
    double angle1 = p_angleScale*(p_angle1 - pangle1);
    double angle2 = p_angleScale*(p_angle2 - pangle2);


//    std::cout<<"  "<<p_angle1*p_angleScale<<"  "<<pangle1*p_angleScale<<"  "<<angle1<<"  "<<et<<std::endl;
//   std::cout<<"  "<<p_angle2*p_angleScale<<"  "<<pangle2*p_angleScale<<"  "<<angle2<<"  "<<et<<std::endl;

    std::vector<double> TC(9);

    eul2m_c ( (SpiceDouble) 0., (SpiceDouble) angle2, (SpiceDouble) angle1,
                             3,                    2,                    1,
               (SpiceDouble(*) [3]) &TC[0]);

    return (TC);
  }
  /** Cache J2000 rotation over existing cached time range using polynomials
   *
   * This method will reload an internal cache with matrices
   * formed from rotation angles fit to polynomials over a time
   * range.
   *
   * @param function1   The first polynomial function used to
   *                    find the rotation angles
   * @param function2   The second polynomial function used to
   *                    find the rotation angles
   * @param function3   The third polynomial function used to
   *                    find the rotation angles
   */
  void LineScanCameraRotation::ReloadCache() {
    NaifStatus::CheckErrors();

    // Make sure caches are already loaded
    if(!p_cachesLoaded) {
      QString msg = "A LineScanCameraRotation cache has not been loaded yet";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    // Clear existing matrices from cache
    p_cache.clear();

    // Create polynomials fit to angles & use to reload cache
    Isis::PolynomialUnivariate function1(p_degree);
    Isis::PolynomialUnivariate function2(p_degree);
    Isis::PolynomialUnivariate function3(p_degree);

    // Get the coefficients of the polynomials already fit to the angles of rotation defining [CI]
    std::vector<double> coeffAng1;
    std::vector<double> coeffAng2;
    std::vector<double> coeffAng3;
    GetPolynomial(coeffAng1, coeffAng2, coeffAng3);

    // Reset linear term to center around zero -- what works best is either roll-avg & pitchavg+ or pitchavg+ & yawavg-
//    coeffAng1[1] -= 0.0000158661225;
//    coeffAng2[1] = 0.0000308433;
//    coeffAng3[0] = -0.001517547;
    if(p_pitchRate)  coeffAng2[1] = p_pitchRate;
    if(p_yaw)  coeffAng3[0] = p_yaw;

    // Load the functions with the coefficients
    function1.SetCoefficients(coeffAng1);
    function2.SetCoefficients(coeffAng2);
    function3.SetCoefficients(coeffAng3);

    double CI[3][3];
    double IJ[3][3];
    std::vector<double> rtime;
    SpiceRotation *prot = p_spi->bodyRotation();
    std::vector<double> CJ;
    CJ.resize(9);

    for(std::vector<double>::size_type pos = 0; pos < p_cacheTime.size(); pos++) {
      double et = p_cacheTime.at(pos);
      rtime.push_back((et - GetBaseTime()) / GetTimeScale());
      double angle1 = function1.Evaluate(rtime);
      double angle2 = function2.Evaluate(rtime);
      double angle3 = function3.Evaluate(rtime);
      rtime.clear();

// Get the first angle back into the range Naif expects [180.,180.]
      if(angle1 < -1 * pi_c()) {
        angle1 += twopi_c();
      }
      else if(angle1 > pi_c()) {
        angle1 -= twopi_c();
      }

      eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1,
              p_axis3,                    p_axis2,                    p_axis1,
              CI);
      mxm_c((SpiceDouble( *)[3]) & (p_jitter->SetEphemerisTimeHPF(et))[0], CI, CI);

      prot->SetEphemerisTime(et);
      mxm_c((SpiceDouble( *)[3]) & (p_cacheIB.at(pos))[0], (SpiceDouble( *)[3]) & (prot->Matrix())[0], IJ);
      mxm_c(CI, IJ, (SpiceDouble( *)[3]) &CJ[0]);

      p_cache.push_back(CJ);   // J2000 to constant frame
    }

    // Set source to cache to get updated values
    SetSource(SpiceRotation::Memcache);

    // Make sure SetEphemerisTime updates the matrix by resetting it twice (in case the first one
    // matches the current et.  p_et is private and not available from the child class
    NaifStatus::CheckErrors();
    SetEphemerisTime(p_cacheTime[0]);
    SetEphemerisTime(p_cacheTime[1]);

    NaifStatus::CheckErrors();
  }