Beispiel #1
0
//Function to translate the labels
void TranslateLrocNacLabels ( Filename &labelFile, Cube *ocube ) {

    //Pvl to store the labels
    Pvl outLabel;
    //Set up the directory where the translations are
    PvlGroup dataDir(Preference::Preferences().FindGroup("DataDirectory"));
    iString transDir = (string) dataDir["Lro"] + "/translations/";
    Pvl labelPvl(labelFile.Expanded());

    //Translate the Instrument group
    Filename transFile(transDir + "lronacInstrument.trn");
    PvlTranslationManager instrumentXlator(labelPvl, transFile.Expanded());
    instrumentXlator.Auto(outLabel);

    //Translate the Archive group
    transFile = transDir + "lronacArchive.trn";
    PvlTranslationManager archiveXlater(labelPvl, transFile.Expanded());
    archiveXlater.Auto(outLabel);

    // Set up the BandBin groups
    PvlGroup bbin("BandBin");
    bbin += PvlKeyword("FilterName", "BroadBand");
    bbin += PvlKeyword("Center", 0.650, "micrometers");
    bbin += PvlKeyword("Width", 0.150, "micrometers");

    Pvl lab(labelFile.Expanded());

    //Set up the Kernels group
    PvlGroup kern("Kernels");
    if (lab.FindKeyword("FRAME_ID")[0] == "LEFT")
        kern += PvlKeyword("NaifFrameCode", -85600);
    else
        kern += PvlKeyword("NaifFrameCode", -85610);

    PvlGroup inst = outLabel.FindGroup("Instrument", Pvl::Traverse);
    if (lab.FindKeyword("FRAME_ID")[0] == "LEFT") {
        inst.FindKeyword("InstrumentId") = "NACL";
        inst.FindKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA LEFT";
        g_flip = false;
    }
    else {
        inst.FindKeyword("InstrumentId") = "NACR";
        inst.FindKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA RIGHT";
    }

    inst += PvlKeyword("SpatialSumming", lab.FindKeyword("CROSSTRACK_SUMMING")[0] );
    inst += PvlKeyword("SampleFirstPixel", 0 );

    //Add all groups to the output cube
    ocube->PutGroup(inst);
    ocube->PutGroup(outLabel.FindGroup("Archive", Pvl::Traverse));
    ocube->PutGroup(bbin);
    ocube->PutGroup(kern);
}
Beispiel #2
0
//  Updates existing BandBin keywords with additional values to ensure
//  label compilancy (which should support Camera models).  It checks for the
//  existance of the keyword and uses its (assumed) first value to set nvals
//  values to a constant.  If the keyword doesn't exist, it uses the default
//  value.
void UpdateBandKey(const QString &keyname, PvlGroup &bb, const int &nvals,
                   const QString &default_value) {

  QString defVal(default_value);
  if ( bb.hasKeyword(keyname) ) {
    defVal = bb[keyname][0];
  }

  bb.addKeyword(makeKey(keyname, nvals, defVal), PvlContainer::Replace);
  return;
}
Beispiel #3
0
 void Stretch::Save(Isis::Pvl &pvl, QString &grpName) {
   PvlGroup *grp = new PvlGroup(grpName);
   PvlKeyword inputs("Input");
   PvlKeyword outputs("Output");
   for(int i = 0; i < Pairs(); i++) {
     inputs.addValue(toString(Input(i)));
     outputs.addValue(toString(Output(i)));
   }
   grp->addKeyword(inputs);
   grp->addKeyword(outputs);
   pvl.addGroup(*grp);
 }
Beispiel #4
0
  /**
   * Loads the stretch pairs from the pvl file into the Stretch
   * object.  The pvl should look similar to this:
   * @code
   * Group = Pairs
   *   Input = (0,100,255)
   *   Output = (255,100,0)
   * EndGroup
   * @endcode
   *
   * @param pvl - The pvl containing the stretch pairs
   * @param grpName - The group name to get the input and output
   *                keywords from
   */
  void Stretch::Load(Isis::Pvl &pvl, QString &grpName) {
    PvlGroup grp = pvl.findGroup(grpName, Isis::PvlObject::Traverse);
    PvlKeyword inputs = grp.findKeyword("Input");
    PvlKeyword outputs = grp.findKeyword("Output");

    if(inputs.size() != outputs.size()) {
      QString msg = "Invalid Pvl file: The number of Input values must equal the number of Output values";
      throw IException(IException::User, msg, _FILEINFO_);
    }
    for(int i = 0; i < inputs.size(); i++) {
      AddPair(toDouble(inputs[i]), toDouble(outputs[i]));
    }
  }
Beispiel #5
0
/**
 * Reads the DefFile having info about the different filters to
 * be used on the Control Network.
 *
 * @author Sharmila Prasad (9/7/2010)
 *
 * @param pcNetFilter
 * @param pvlDefFile
 */
void ReadDefFile(ControlNetFilter & pcNetFilter, Pvl & pvlDefFile)
{
  // prototype to ControlNetFilter member function
  void (ControlNetFilter::*pt2Filter)(const PvlGroup & pvlGrp, bool pbLastFilter);

  // Parse the Groups in Point Object
  PvlObject filtersObj = pvlDefFile.findObject("Filters", Pvl::Traverse);
  int iNumGroups = filtersObj.groups();

  for (int i=0; i<iNumGroups; i++) {
    PvlGroup pvlGrp = filtersObj.group(i);
    // Get the pointer to ControlNetFilter member function based on Group name
    pt2Filter=GetPtr2Filter(pvlGrp.name());
    if (pt2Filter != NULL) {
      (pcNetFilter.*pt2Filter)(pvlGrp, ((i==(iNumGroups-1)) ? true : false));
    }
  }
}
Beispiel #6
0
  //! Constructs a HiLab Object                                                                                                                                                                                                         
  HiLab::HiLab(Cube *cube){ 
    PvlGroup group = cube->GetGroup("Instrument");
    p_cpmmNumber = group["CpmmNumber"];
    p_channel = group["ChannelNumber"];

    if (group.HasKeyword("Summing")) {
       p_bin = group["Summing"];
    }
    else {
      std::string msg = "Cannot find required Summing keyword in label";
      throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
    }

    if (group.HasKeyword("Tdi")) {
      p_tdi = group["Tdi"];
    }
    else {
      std::string msg = "Cannot find required Tdi keyword in label";
      throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
    }
    
  }
Beispiel #7
0
/**
 * @brief Writes data specific to calibration statistics in Pvl Format
 * 
 * This method is a compartmentalization of the writing of the contents of
 * a HiImageClean object.  
 * 
 * This method dumps the calibration statistics computed from the HiRISE
 * cube specifed on construction or through the load methods.
 */
  void HiImageClean::PvlCalStats(PvlGroup &grp) const {
    grp.SetName("CalibrationStatistics");
    grp += PvlKeyword("Binning",_binning);
    grp += PvlKeyword("TDI",_tdi);
    grp += PvlKeyword("CPMM",_cpmm);
    grp += PvlKeyword("Channel",_channelNo);
    grp += PvlKeyword("FirstImageSample",_firstImageSample);         
    grp += PvlKeyword("FirstImageLine",_firstImageLine);          
    grp += PvlKeyword("FirstBufferSample",_firstBufferSample); 
    grp += PvlKeyword("FirstDarkSample",_firstDarkSample);
    grp += PvlKeyword("MaskInducedNulls", _totalMaskNulled);
    grp += PvlKeyword("DarkInducedNulls", _totalDarkNulled);
    grp += PvlKeyword("LastGoodLine",_lastGoodLine+1);
  }
Beispiel #8
0
  /**
   * Create and initialize a Latitude value using the mapping group's latitude
   * units and radii.
   *
   * @see ErrorChecking
   * @see CoordinateType
   * @param latitude The latitude value this instance will represent,
   *     in the mapping group's units
   * @param mapping A mapping group
   * @param latitudeUnits The angular units of the latitude value (degs, rads)
   * @param errors Error checking conditions
   */
  Latitude::Latitude(double latitude,
            PvlGroup mapping,
            Angle::Units latitudeUnits,
            ErrorChecking errors) : Angle(latitude, latitudeUnits) {
    m_equatorialRadius = NULL;
    m_polarRadius = NULL;

    if (mapping.hasKeyword("EquatorialRadius") && mapping.hasKeyword("PolarRadius")) {
      m_equatorialRadius = new Distance(toDouble(mapping["EquatorialRadius"][0]),
          Distance::Meters);
      m_polarRadius = new Distance(toDouble(mapping["PolarRadius"][0]),
          Distance::Meters);
    }
    else {
      PvlGroup radiiGrp = TProjection::TargetRadii(mapping["TargetName"]);

      m_equatorialRadius = new Distance(toDouble(radiiGrp["EquatorialRadius"][0]),
          Distance::Meters);
      m_polarRadius = new Distance(toDouble(radiiGrp["PolarRadius"][0]),
          Distance::Meters);
    }

    m_errors = errors;

    if(mapping["LatitudeType"][0] == "Planetographic") {
      setPlanetographic(latitude, latitudeUnits);
    }
    else if(mapping["LatitudeType"][0] == "Planetocentric") {
      setPlanetocentric(latitude, latitudeUnits);
    }
    else {
      IString msg = "Latitude type [" + IString(mapping["LatitudeType"][0]) +
        "] is not recognized";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }
  }
Beispiel #9
0
/**
 * With the Channel, CCD in the isis label, find the coefficient values
 * for this image
 *
 * @author Sharmila Prasad (11/24/2010)
 *
 * @param pCubeLabel
 */
void GetCCD_Channel_Coefficients(Pvl & pCubeLabel)
{
  int iChannel=-1, iSumming=-1;
  QString sCcd="";

  PvlGroup instrGrp = pCubeLabel.findObject("IsisCube").findGroup("Instrument");

  // Summing keyword
  if (!instrGrp.hasKeyword("Summing")) {
    QString sMsg = "Summing keyword not found";
    throw IException(IException::User, sMsg, _FILEINFO_);
  }
  else {
    PvlKeyword binKey = instrGrp.findKeyword("Summing");
    iSumming = toInt(binKey[0]);
    if (iSumming != 1 && iSumming != 2 && iSumming != 4) {
      QString sMsg = "Invalid Summing value in input file, must be 1,2,or 4";
      throw IException(IException::User, sMsg, _FILEINFO_);
    }
  }

  // CCD Keyword
  if (!instrGrp.hasKeyword("CcdId")) {
    QString sMsg = "CcdId keyword not found";
    throw IException(IException::User, sMsg, _FILEINFO_);
  }
  else {
    PvlKeyword ccdKey = instrGrp.findKeyword("CcdId");
    sCcd = ccdKey[0];
  }

  // Channel Keyword
  if (!instrGrp.hasKeyword("ChannelNumber")) {
    QString sMsg = "ChannelNumber keyword not found";
    throw IException(IException::User, sMsg, _FILEINFO_);
  }
  else {
    PvlKeyword channelKey = instrGrp.findKeyword("ChannelNumber");
    iChannel = toInt(channelKey[0]);
  }

  // Get the coefficient file name
  QString dCoeffFile = "$mro/calibration/HiRISE_Gain_Drift_Correction_Bin" + toString(iSumming) + ".0001.csv";
  //QString dCoeffFile = "/home/sprasad/isis3/isis/src/mro/apps/hicalproc/HiRISE_Gain_Drift_Correction_Bin" + toString(iSumming) + ".0001.csv";
#ifdef _DEBUG_
  cout << dCoeffFile << endl;
#endif

  // Get the coefficients
  ReadCoefficientFile(FileName(dCoeffFile).expanded(), sCcd, iChannel);
}
Beispiel #10
0
/**
 * @brief Writes data specific to image statistics out in Pvl format
 * 
 * This method creates a PvlGroup containing the image statistics
 * acculated during line-by-line processing of raw image data.
 */
  void HiImageClean::PvlImageStats(PvlGroup &grp) const {
    grp.SetName("ImageStatistics");
    grp += PvlKeyword("File",_filename.Name());
    grp += PvlKeyword("Lines",_lines);
    grp += PvlKeyword("Samples",_samples);

    BigInt nBad = _maskStats.TotalPixels() - _maskStats.ValidPixels();
    grp += PvlKeyword("MaskAverage", _maskStats.Average());
    grp += PvlKeyword("MaskStdDev", _maskStats.StandardDeviation());
    grp += PvlKeyword("BadMaskPixels", nBad);
    grp += PvlKeyword("MaskInducedNulls", _totalMaskNulled);

    nBad = _darkStats.TotalPixels() - _darkStats.ValidPixels();
    grp += PvlKeyword("DarkAverage", _darkStats.Average());
    grp += PvlKeyword("DarkStdDev", _darkStats.StandardDeviation());
    grp += PvlKeyword("BadDarkPixels", nBad);
    grp += PvlKeyword("DarkInducedNulls", _totalDarkNulled);

  }
Beispiel #11
0
void IsisMain() {
  // We will be processing by brick
  ProcessByBrick p;
  
  Isis::Cube *amatrixCube=NULL; 
  Isis::Cube *bmatrixCube=NULL; 

  // Setup the user input for the input/output files and the option
  UserInterface &ui = Application::GetUserInterface();

  // Setup the input HiRise cube
  Isis::Cube *icube = p.SetInputCube("FROM");

  if (icube->Bands() != 1) {
    std::string msg = "Only single-band HiRise cubes can be calibrated";
    throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
  }

  //Get pertinent label information to determine which band of matrix cube to use
  HiLab hilab(icube);

  int ccd = hilab.getCcd();

  int channel = hilab.getChannel();

  if (channel != 0  && channel != 1) {
    std::string msg = "Only unstitched cubes can be calibrated";
    throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
  }
  int band = 1 + ccd*2 + channel;

  string option = ui.GetString("OPTION");

  // Set attributes (input band number) for the matrix cube(s);
  CubeAttributeInput att("+" + iString(band));

  // Determine the file specification to the matrix file(s) if defaulted
  // and open 
  
  if (ui.WasEntered ("MATRIX") ) {
    if (option == "GAIN") {
      string matrixFile = ui.GetFilename("MATRIX");
      amatrixCube = p.SetInputCube(matrixFile, att);
    }
    else if (option == "OFFSET") {
      string matrixFile = ui.GetFilename("MATRIX");
      bmatrixCube = p.SetInputCube(matrixFile, att);
    }
    else { //(option == "BOTH")
      std::string 
        msg = "The BOTH option cannot be used if a MATRIX is entered";
      throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
    }
  }
  else {
    int tdi = hilab.getTdi();
    int bin = hilab.getBin();

    if (option == "OFFSET" || option == "BOTH") {
      std::string bmatrixFile = "$mro/calibration";
      bmatrixFile += "/B_matrix_tdi";
      bmatrixFile += iString(tdi) + "_bin" + iString(bin);
      bmatrixCube = p.SetInputCube(bmatrixFile, att);
    }
    if (option == "GAIN" || option == "BOTH") {
       std::string amatrixFile = "$mro/calibration";
       amatrixFile += "/A_matrix_tdi";
       amatrixFile += iString(tdi) + "_bin" + iString(bin);
       amatrixCube = p.SetInputCube(amatrixFile, att);
    }
  }

  // Open the output file and set processing parameters
  Cube *ocube = p.SetOutputCube ("TO");
  p.SetWrap (true);
  p.SetBrickSize ( icube->Samples(), 1, 1);

  // Add the radiometry group if it is not there yet.  Otherwise
  // read the current value of the keyword CalibrationParameters.
  // Then delete the keyword and rewrite it after appending the
  // new value to it.  Do it this way to avoid multiple Calibration
  // Parameter keywords.
  PvlGroup calgrp;
  PvlKeyword calKey;

  if (ocube->HasGroup("Radiometry")) {
    calgrp = ocube->GetGroup ("Radiometry");

    if (calgrp.HasKeyword("CalibrationParameters")) {
      calKey = calgrp.FindKeyword("CalibrationParameters");
      calgrp.DeleteKeyword( "CalibrationParameters" );
    }
    else {
      calKey.SetName ("CalibrationParameters");
    }
  }
  else {
    calgrp.SetName("Radiometry");
    calKey.SetName ("CalibrationParameters");
  }

  string keyValue = option;
  if (option == "GAIN") {
    keyValue += ":" + amatrixCube->Filename();
  }
  else if (option == "OFFSET") {
    keyValue += ":" + bmatrixCube->Filename();
  }
  else { // "BOTH"
    keyValue += ":"+bmatrixCube->Filename()+":"+amatrixCube->Filename();
  }

  calKey += keyValue;
  calgrp += calKey;
  ocube->PutGroup(calgrp);

  // Start the processing based on the option
  if (option == "GAIN") {
    p.StartProcess(mult);
  }
  else if (option == "OFFSET") {
    p.StartProcess(sub);
  }
  else { //(option == "BOTH") 
    p.StartProcess(multSub);
  }

  // Cleanup
  p.EndProcess();
}
Beispiel #12
0
  /**
   * Get Groups by translating from correct Translation table
   *
   * @param label A pvl formatted label to be used to generate the serial number
   */
  PvlGroup ObservationNumber::FindObservationTranslation(Pvl &label) {
    Pvl outLabel;
    static PvlGroup dataDir(Preference::Preferences().findGroup("DataDirectory"));

    // Get the mission name
    static QString missionTransFile = (QString) dataDir["base"] + "/translations/MissionName2DataDir.trn";
    static PvlTranslationManager missionXlater(missionTransFile);
    missionXlater.SetLabel(label);
    QString mission = missionXlater.Translate("MissionName");

    // Get the instrument name
    static QString instTransFile = (QString) dataDir["base"] + "/translations/Instruments.trn";
    static PvlTranslationManager instrumentXlater(instTransFile);
    instrumentXlater.SetLabel(label);
    QString instrument = instrumentXlater.Translate("InstrumentName");

    // We want to use this instrument's translation manager. It's much faster for
    //   ObservationNumberList if we keep the translation manager in memory, so re-reading
    //   from the disk is not necessary every time. To do this, we'll use a map to store
    //   the translation managers and observation number keys with a string identifier to find them.
    //   This identifier needs to have the mission name and the instrument name.
    static std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> > missionTranslators;
    QString key = mission + "_" + instrument;
    std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> >::iterator
    translationIterator = missionTranslators.find(key);

    if(translationIterator == missionTranslators.end()) {
      // Get the file
      FileName snFile((QString) dataDir[mission] + "/translations/" +
                                    instrument + "SerialNumber????.trn");
      snFile = snFile.highestVersion();

      // Delets the extra
      Pvl translation(snFile.expanded());
      PvlKeyword observationKeys;
      if(translation.hasKeyword("ObservationKeys")) {
        observationKeys = translation["ObservationKeys"];
      }

      // use the translation file to generate keywords
      missionTranslators.insert(
        std::pair<QString, std::pair<PvlTranslationManager, PvlKeyword> >
        (key, std::pair<PvlTranslationManager, PvlKeyword>(PvlTranslationManager(snFile.expanded()), observationKeys))
      );

      translationIterator = missionTranslators.find(key);
    }

    translationIterator->second.first.SetLabel(label);
    translationIterator->second.first.Auto(outLabel);
    PvlGroup snGroup = outLabel.findGroup("SerialNumberKeywords");

    // Delets the extra
    if(!translationIterator->second.second.name().isEmpty()) {
      snGroup += translationIterator->second.second;
    }
    else {
      snGroup += PvlKeyword("ObservationKeys", toString(snGroup.keywords()));
    }

    return snGroup;
  }
Beispiel #13
0
  /**
   * Find the lat/lon range of the image. This will use the image footprint,
   *   camera, or projection in order to find a good result.
   *
   * @param Cube* This is required for estimation. You can pass in NULL (it will
   *              disable estimation).
   * @param minLat This is an output: minimum latitude
   * @param maxLat This is an output: maximum latitude
   * @param minLon This is an output: minimum longitude
   * @param maxLon This is an output: maximum longitude
   * @param allowEstimation If this is true then extra efforts will be made to
   *     guess the ground range of the input. This can still fail.
   * @return True if a ground range was found, false if no ground range could
   *     be determined. Some lat/lon results may still be populated; their
   *     values are undefined.
   */
  bool UniversalGroundMap::GroundRange(Cube *cube, Latitude &minLat,
      Latitude &maxLat, Longitude &minLon, Longitude &maxLon,
      bool allowEstimation) {
    // Do we need a RingRange method?
    // For now just return false
    if (HasCamera())
      if (p_camera->target()->shape()->name() == "Plane") return false;
    if (HasProjection()) 
      if (p_projection->projectionType() == Projection::RingPlane) return false;

    minLat = Latitude();
    maxLat = Latitude();
    minLon = Longitude();
    maxLon = Longitude();

    // If we have a footprint, use it
    try {
      if (cube) {
        ImagePolygon poly;
        cube->read(poly);
        geos::geom::MultiPolygon *footprint = PolygonTools::MakeMultiPolygon(
            poly.Polys()->clone());

        geos::geom::Geometry *envelope = footprint->getEnvelope();
        geos::geom::CoordinateSequence *coords = envelope->getCoordinates();

        for (unsigned int i = 0; i < coords->getSize(); i++) {
          const geos::geom::Coordinate &coord = coords->getAt(i);

          Latitude coordLat(coord.y, Angle::Degrees);
          Longitude coordLon(coord.x, Angle::Degrees);

          if (!minLat.isValid() || minLat > coordLat)
            minLat = coordLat;
          if (!maxLat.isValid() || maxLat < coordLat)
            maxLat = coordLat;

          if (!minLon.isValid() || minLon > coordLon)
            minLon = coordLon;
          if (!maxLon.isValid() || maxLon < coordLon)
            maxLon = coordLon;
        }

        delete coords;
        coords = NULL;

        delete envelope;
        envelope = NULL;

        delete footprint;
        footprint = NULL;
      }
    }
    catch (IException &) {
    }

    if (!minLat.isValid() || !maxLat.isValid() ||
        !minLon.isValid() || !maxLon.isValid()) {
      if (HasCamera()) {
        // Footprint failed, ask the camera
        PvlGroup mappingGrp("Mapping");
        mappingGrp += PvlKeyword("LatitudeType", "Planetocentric");
        mappingGrp += PvlKeyword("LongitudeDomain", "360");
        mappingGrp += PvlKeyword("LongitudeDirection", "PositiveEast");

        Pvl mappingPvl;
        mappingPvl += mappingGrp;
        double minLatDouble;
        double maxLatDouble;
        double minLonDouble;
        double maxLonDouble;
        p_camera->GroundRange(
            minLatDouble, maxLatDouble,
            minLonDouble, maxLonDouble, mappingPvl);
        minLat = Latitude(minLatDouble, Angle::Degrees);
        maxLat = Latitude(maxLatDouble, Angle::Degrees);
        minLon = Longitude(minLonDouble, Angle::Degrees);
        maxLon = Longitude(maxLonDouble, Angle::Degrees);
      }
      else if (HasProjection()) {
        // Footprint failed, look in the mapping group
        PvlGroup mappingGrp = p_projection->Mapping();
        if (mappingGrp.hasKeyword("MinimumLatitude") &&
            mappingGrp.hasKeyword("MaximumLatitude") &&
            mappingGrp.hasKeyword("MinimumLongitude") &&
            mappingGrp.hasKeyword("MaximumLongitude")) {

          minLat = Latitude(mappingGrp["MinimumLatitude"],
                            mappingGrp, Angle::Degrees);
          maxLat = Latitude(mappingGrp["MaximumLatitude"],
                            mappingGrp, Angle::Degrees);
          minLon = Longitude(mappingGrp["MinimumLongitude"],
                             mappingGrp, Angle::Degrees);
          maxLon = Longitude(mappingGrp["MaximumLongitude"],
                             mappingGrp, Angle::Degrees);

        }
        else if (allowEstimation && cube) {
          // Footprint and mapping failed... no lat/lon range of any kind is
          //   available. Let's test points in the image to try to make our own
          //   extent.
          QList<QPointF> imagePoints;

          // Reset to TProjection
          TProjection *tproj = (TProjection *) p_projection;

                    /*
           * This is where we're testing:
           *
           *  |---------------|
           *  |***************|
           *  |**     *     **|
           *  |*  *   *   *  *|
           *  |*    * * *    *|
           *  |***************|
           *  |*    * * *    *|
           *  |*  *   *   *  *|
           *  |**     *     **|
           *  |***************|
           *  |---------------|
           *
           * We'll test at the edges, a plus (+) and an (X) to help DEMs work.
           */

          int sampleCount = cube->sampleCount();
          int lineCount = cube->lineCount();

          int stepsPerLength = 20; //number of steps per length
          double aspectRatio = (double)lineCount / (double)sampleCount;
          double xStepSize = sampleCount / stepsPerLength;
          double yStepSize = xStepSize * aspectRatio;

          if (lineCount > sampleCount) {
            aspectRatio = (double)sampleCount / (double)lineCount;
            yStepSize = lineCount / stepsPerLength;
            xStepSize = yStepSize * aspectRatio;
          }

          double yWalked = 0.5;

          //3 vertical lines
          for (int i = 0; i < 3; i++) {
            double xValue = 0.5 + ( i * (sampleCount / 2) );

            while (yWalked <= lineCount) {
              imagePoints.append( QPointF(xValue, yWalked) );
              yWalked += yStepSize;
            }

            yWalked = 0.5;
          }

          double xWalked = 0.5;

          //3 horizontal lines
          for (int i = 0; i < 3; i++) {
            double yValue = 0.5 + ( i * (lineCount / 2) );

            while (xWalked <= sampleCount) {
              imagePoints.append( QPointF(xWalked, yValue) );
              xWalked += xStepSize;
            }

            xWalked = 0.5;
          }

          double xDiagonalWalked = 0.5;
          double yDiagonalWalked = 0.5;
          xStepSize = sampleCount / stepsPerLength;
          yStepSize = lineCount / stepsPerLength;

          //Top-Down Diagonal
          while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked <= lineCount) ) {
            imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
            xDiagonalWalked += xStepSize;
            yDiagonalWalked += yStepSize;
          }

          xDiagonalWalked = 0.5;

          //Bottom-Up Diagonal
          while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked >= 0) ) {
            imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) );
            xDiagonalWalked += xStepSize;
            yDiagonalWalked -= yStepSize;
          }

          foreach (QPointF imagePoint, imagePoints) {
            if (tproj->SetWorld(imagePoint.x(), imagePoint.y())) {
              Latitude latResult(tproj->UniversalLatitude(),
                                 Angle::Degrees);
              Longitude lonResult(tproj->UniversalLongitude(),
                                  Angle::Degrees);
              if (minLat.isValid())
                minLat = qMin(minLat, latResult);
              else
                minLat = latResult;

              if (maxLat.isValid())
                maxLat = qMax(maxLat, latResult);
              else
                maxLat = latResult;

              if (minLon.isValid())
                minLon = qMin(minLon, lonResult);
              else
                minLon = lonResult;

              if (maxLon.isValid())
                maxLon = qMax(maxLon, lonResult);
              else
                maxLon = lonResult;
            }
          }
        }
      }
    }
Beispiel #14
0
void IsisMain() {
  // We will be warping a cube
  ProcessRubberSheet p;

  // Get the map projection file provided by the user
  UserInterface &ui = Application::GetUserInterface();
  Pvl userPvl(ui.GetFileName("MAP"));
  PvlGroup &userMappingGrp = userPvl.findGroup("Mapping", Pvl::Traverse);

  // Open the input cube and get the projection
  Cube *icube = p.SetInputCube("FROM");

  // Get the mapping group
  PvlGroup fromMappingGrp = icube->group("Mapping");
  TProjection *inproj = (TProjection *) icube->projection();
  PvlGroup outMappingGrp = fromMappingGrp;

  // If the default range is FROM, then wipe out any range data in user mapping file
  if(ui.GetString("DEFAULTRANGE").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) {
    if(userMappingGrp.hasKeyword("MinimumLatitude")) {
      userMappingGrp.deleteKeyword("MinimumLatitude");
    }

    if(userMappingGrp.hasKeyword("MaximumLatitude")) {
      userMappingGrp.deleteKeyword("MaximumLatitude");
    }

    if(userMappingGrp.hasKeyword("MinimumLongitude")) {
      userMappingGrp.deleteKeyword("MinimumLongitude");
    }

    if(userMappingGrp.hasKeyword("MaximumLongitude")) {
      userMappingGrp.deleteKeyword("MaximumLongitude");
    }
  }

  // Deal with user overrides entered in the GUI. Do this by changing the user's mapping group, which
  // will then overlay anything in the output mapping group.
  if(ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) {
    userMappingGrp.addKeyword(PvlKeyword("MinimumLatitude", toString(ui.GetDouble("MINLAT"))), Pvl::Replace);
  }

  if(ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) {
    userMappingGrp.addKeyword(PvlKeyword("MaximumLatitude", toString(ui.GetDouble("MAXLAT"))), Pvl::Replace);
  }

  if(ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) {
    userMappingGrp.addKeyword(PvlKeyword("MinimumLongitude", toString(ui.GetDouble("MINLON"))), Pvl::Replace);
  }

  if(ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) {
    userMappingGrp.addKeyword(PvlKeyword("MaximumLongitude", toString(ui.GetDouble("MAXLON"))), Pvl::Replace);
  }

  /**
   * If the user is changing from positive east to positive west, or vice-versa, the output minimum is really
   * the input maximum. However, the user mapping group must be left unaffected (an input minimum must be the
   * output minimum). To accomplish this, we swap the minimums/maximums in the output group ahead of time. This
   * causes the minimums and maximums to correlate to the output minimums and maximums. That way when we copy
   * the user mapping group into the output group a mimimum overrides a minimum and a maximum overrides a maximum.
   */
  bool sameDirection = true;
  if(userMappingGrp.hasKeyword("LongitudeDirection")) {
    if(((QString)userMappingGrp["LongitudeDirection"]).compare(fromMappingGrp["LongitudeDirection"]) != 0) {
      sameDirection = false;
    }
  }

  // Since the out mapping group came from the from mapping group, which came from a valid cube,
  // we can assume both min/max lon exists if min longitude exists.
  if(!sameDirection && outMappingGrp.hasKeyword("MinimumLongitude")) {
    double minLon = outMappingGrp["MinimumLongitude"];
    double maxLon = outMappingGrp["MaximumLongitude"];

    outMappingGrp["MaximumLongitude"] = toString(minLon);
    outMappingGrp["MinimumLongitude"] = toString(maxLon);
  }

  if(ui.GetString("PIXRES").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) {
    // Resolution will be in fromMappingGrp and outMappingGrp at this time
    //   delete from user mapping grp
    if(userMappingGrp.hasKeyword("Scale")) {
      userMappingGrp.deleteKeyword("Scale");
    }

    if(userMappingGrp.hasKeyword("PixelResolution")) {
      userMappingGrp.deleteKeyword("PixelResolution");
    }
  }
  else if(ui.GetString("PIXRES").compare("MAP") == 0 || ui.GetBoolean("MATCHMAP")) {
    // Resolution will be in userMappingGrp - delete all others
    if(outMappingGrp.hasKeyword("Scale")) {
      outMappingGrp.deleteKeyword("Scale");
    }

    if(outMappingGrp.hasKeyword("PixelResolution")) {
      outMappingGrp.deleteKeyword("PixelResolution");
    }

    if(fromMappingGrp.hasKeyword("Scale"));
    {
      fromMappingGrp.deleteKeyword("Scale");
    }

    if(fromMappingGrp.hasKeyword("PixelResolution")) {
      fromMappingGrp.deleteKeyword("PixelResolution");
    }
  }
  else if(ui.GetString("PIXRES").compare("MPP") == 0) {
    // Resolution specified - delete all and add to outMappingGrp
    if(outMappingGrp.hasKeyword("Scale")) {
      outMappingGrp.deleteKeyword("Scale");
    }

    if(outMappingGrp.hasKeyword("PixelResolution")) {
      outMappingGrp.deleteKeyword("PixelResolution");
    }

    if(fromMappingGrp.hasKeyword("Scale")) {
      fromMappingGrp.deleteKeyword("Scale");
    }

    if(fromMappingGrp.hasKeyword("PixelResolution")) {
      fromMappingGrp.deleteKeyword("PixelResolution");
    }

    if(userMappingGrp.hasKeyword("Scale")) {
      userMappingGrp.deleteKeyword("Scale");
    }

    if(userMappingGrp.hasKeyword("PixelResolution")) {
      userMappingGrp.deleteKeyword("PixelResolution");
    }

    outMappingGrp.addKeyword(PvlKeyword("PixelResolution", toString(ui.GetDouble("RESOLUTION")), "meters/pixel"), Pvl::Replace);
  }
  else if(ui.GetString("PIXRES").compare("PPD") == 0) {
    // Resolution specified - delete all and add to outMappingGrp
    if(outMappingGrp.hasKeyword("Scale")) {
      outMappingGrp.deleteKeyword("Scale");
    }

    if(outMappingGrp.hasKeyword("PixelResolution")) {
      outMappingGrp.deleteKeyword("PixelResolution");
    }

    if(fromMappingGrp.hasKeyword("Scale")) {
      fromMappingGrp.deleteKeyword("Scale");
    }

    if(fromMappingGrp.hasKeyword("PixelResolution")) {
      fromMappingGrp.deleteKeyword("PixelResolution");
    }

    if(userMappingGrp.hasKeyword("Scale")) {
      userMappingGrp.deleteKeyword("Scale");
    }

    if(userMappingGrp.hasKeyword("PixelResolution")) {
      userMappingGrp.deleteKeyword("PixelResolution");
    }

    outMappingGrp.addKeyword(PvlKeyword("Scale", toString(ui.GetDouble("RESOLUTION")), "pixels/degree"), Pvl::Replace);
  }

  // Rotation will NOT Propagate
  if(outMappingGrp.hasKeyword("Rotation")) {
    outMappingGrp.deleteKeyword("Rotation");
  }


  /**
   * The user specified map template file overrides what ever is in the
   * cube's mapping group.
   */
  for(int keyword = 0; keyword < userMappingGrp.keywords(); keyword ++) {
    outMappingGrp.addKeyword(userMappingGrp[keyword], Pvl::Replace);
  }

  /**
   * Now, we have to deal with unit conversions. We convert only if the following are true:
   *   1) We used values from the input cube
   *   2) The values are longitudes or latitudes
   *   3) The map file or user-specified information uses a different measurement system than
   *        the input cube for said values.
   *
   * The data is corrected for:
   *   1) Positive east/positive west
   *   2) Longitude domain
   *   3) planetographic/planetocentric.
   */

  // First, the longitude direction
  if(!sameDirection) {
    PvlGroup longitudes = inproj->MappingLongitudes();

    for(int index = 0; index < longitudes.keywords(); index ++) {
      if(!userMappingGrp.hasKeyword(longitudes[index].name())) {
        // use the from domain because that's where our values are coming from
        if(((QString)userMappingGrp["LongitudeDirection"]).compare("PositiveEast") == 0) {
          outMappingGrp[longitudes[index].name()] = toString(
            TProjection::ToPositiveEast(outMappingGrp[longitudes[index].name()],
                                        outMappingGrp["LongitudeDomain"]));
        }
        else {
          outMappingGrp[longitudes[index].name()] = toString(
              TProjection::ToPositiveWest(outMappingGrp[longitudes[index].name()],
                                          outMappingGrp["LongitudeDomain"]));
        }
      }
    }
  }

  // Second, longitude domain
  if(userMappingGrp.hasKeyword("LongitudeDomain")) { // user set a new domain?
    if((int)userMappingGrp["LongitudeDomain"] != (int)fromMappingGrp["LongitudeDomain"]) { // new domain different?
      PvlGroup longitudes = inproj->MappingLongitudes();

      for(int index = 0; index < longitudes.keywords(); index ++) {
        if(!userMappingGrp.hasKeyword(longitudes[index].name())) {
          if((int)userMappingGrp["LongitudeDomain"] == 180) {
            outMappingGrp[longitudes[index].name()] = toString(
                TProjection::To180Domain(outMappingGrp[longitudes[index].name()]));
          }
          else {
            outMappingGrp[longitudes[index].name()] = toString(
                TProjection::To360Domain(outMappingGrp[longitudes[index].name()]));
          }
        }
      }

    }
  }

  // Third, planetographic/planetocentric
  if(userMappingGrp.hasKeyword("LatitudeType")) { // user set a new domain?
    if(((QString)userMappingGrp["LatitudeType"]).compare(fromMappingGrp["LatitudeType"]) != 0) { // new lat type different?

      PvlGroup latitudes = inproj->MappingLatitudes();

      for(int index = 0; index < latitudes.keywords(); index ++) {
        if(!userMappingGrp.hasKeyword(latitudes[index].name())) {
          if(((QString)userMappingGrp["LatitudeType"]).compare("Planetographic") == 0) {
            outMappingGrp[latitudes[index].name()] = toString(TProjection::ToPlanetographic(
                  (double)fromMappingGrp[latitudes[index].name()],
                  (double)fromMappingGrp["EquatorialRadius"],
                  (double)fromMappingGrp["PolarRadius"]));
          }
          else {
            outMappingGrp[latitudes[index].name()] = toString(TProjection::ToPlanetocentric(
                  (double)fromMappingGrp[latitudes[index].name()],
                  (double)fromMappingGrp["EquatorialRadius"],
                  (double)fromMappingGrp["PolarRadius"]));
          }
        }
      }

    }
  }

  // Try a couple equivalent longitudes to fix the ordering of min,max for border cases
  if ((double)outMappingGrp["MinimumLongitude"] >=
      (double)outMappingGrp["MaximumLongitude"]) {

    if ((QString)outMappingGrp["MinimumLongitude"] == "180.0" &&
        (int)userMappingGrp["LongitudeDomain"] == 180)
      outMappingGrp["MinimumLongitude"] = "-180";

    if ((QString)outMappingGrp["MaximumLongitude"] == "-180.0" &&
        (int)userMappingGrp["LongitudeDomain"] == 180)
      outMappingGrp["MaximumLongitude"] = "180";

    if ((QString)outMappingGrp["MinimumLongitude"] == "360.0" &&
        (int)userMappingGrp["LongitudeDomain"] == 360)
      outMappingGrp["MinimumLongitude"] = "0";

    if ((QString)outMappingGrp["MaximumLongitude"] == "0.0" &&
        (int)userMappingGrp["LongitudeDomain"] == 360)
      outMappingGrp["MaximumLongitude"] = "360";
  }

  // If MinLon/MaxLon out of order, we weren't able to calculate the correct values
  if((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) {
    if(!ui.WasEntered("MINLON") || !ui.WasEntered("MAXLON")) {
      QString msg = "Unable to determine the correct [MinimumLongitude,MaximumLongitude].";
      msg += " Please specify these values in the [MINLON,MAXLON] parameters";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }
  }

  int samples, lines;
  Pvl mapData;
  // Copy to preserve cube labels so we can match cube size
  if(userPvl.hasObject("IsisCube")) {
    mapData = userPvl;
    mapData.findObject("IsisCube").deleteGroup("Mapping");
    mapData.findObject("IsisCube").addGroup(outMappingGrp);
  }
  else {
    mapData.addGroup(outMappingGrp);
  }

  // *NOTE: The UpperLeftX,UpperLeftY keywords will not be used in the CreateForCube
  //   method, and they will instead be recalculated. This is correct.
  TProjection *outproj = (TProjection *) ProjectionFactory::CreateForCube(mapData, samples, lines,
                        ui.GetBoolean("MATCHMAP"));

  // Set up the transform object which will simply map
  // output line/samps -> output lat/lons -> input line/samps
  Transform *transform = new map2map(icube->sampleCount(),
                                     icube->lineCount(),
                                     (TProjection *) icube->projection(),
                                     samples,
                                     lines,
                                     outproj,
                                     ui.GetBoolean("TRIM"));

  // Allocate the output cube and add the mapping labels
  Cube *ocube = p.SetOutputCube("TO", transform->OutputSamples(),
                                transform->OutputLines(),
                                icube->bandCount());

  PvlGroup cleanOutGrp = outproj->Mapping();

  // ProjectionFactory::CreateForCube updated mapData to have the correct
  //   upperleftcornerx, upperleftcornery, scale and resolution. Use these
  //   updated numbers.
  cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["UpperLeftCornerX"], Pvl::Replace);
  cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["UpperLeftCornerY"], Pvl::Replace);
  cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["Scale"], Pvl::Replace);
  cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["PixelResolution"], Pvl::Replace);

  ocube->putGroup(cleanOutGrp);

  // Set up the interpolator
  Interpolator *interp;
  if(ui.GetString("INTERP") == "NEARESTNEIGHBOR") {
    interp = new Interpolator(Interpolator::NearestNeighborType);
  }
  else if(ui.GetString("INTERP") == "BILINEAR") {
    interp = new Interpolator(Interpolator::BiLinearType);
  }
  else if(ui.GetString("INTERP") == "CUBICCONVOLUTION") {
    interp = new Interpolator(Interpolator::CubicConvolutionType);
  }
  else {
    QString msg = "Unknow value for INTERP [" + ui.GetString("INTERP") + "]";
    throw IException(IException::Programmer, msg, _FILEINFO_);
  }

  // Warp the cube
  p.StartProcess(*transform, *interp);
  p.EndProcess();

  Application::Log(cleanOutGrp);

  // Cleanup
  delete transform;
  delete interp;
}
Beispiel #15
0
// Populate cube label using filname and film code
// Code decrypted as specified in film decoder document (July 23, 1971 Revision)
//     available at ASU Apollo Resources archive
void TranslateApolloLabels (IString filename, Cube *opack) {
  //Instrument group
  PvlGroup inst("Instrument");
  PvlGroup kern("Kernels");
  PvlGroup codeGroup("Code");
  
  inst += PvlKeyword("SpacecraftName", apollo->SpacecraftName());
  inst += PvlKeyword("InstrumentId", apollo->InstrumentId());
  inst += PvlKeyword("TargetName", apollo->TargetName());
  
  if ( !IsValidCode() ){
    PvlGroup error("ERROR");
    error.addComment("The decrypted code is invalid.");
    for (int i=0; i<4; i++) {
      PvlKeyword keyword("Column"+toString(i+1));
      for (int j=0; j<32; j++) {
        keyword += toString((int)code[i][j]);
      }
      error.addKeyword(keyword);
      codeGroup += keyword;
    }
    Application::Log(error);
  }
  else {
    codeGroup += PvlKeyword("StartTime", FrameTime());
    codeGroup += PvlKeyword("SpacecraftAltitude", toString(Altitude()),"meters");
  
    if (apollo->IsMetric()){
      codeGroup += PvlKeyword("ExposureDuration", toString(ShutterInterval()), "milliseconds");
      codeGroup += PvlKeyword("ForwardMotionCompensation", FMC());
    }
    
    for (int i=0; i<4; i++) {
      PvlKeyword keyword("Column"+toString(i+1));
      for (int j=0; j<32; j++) {
        keyword += toString((int)code[i][j]);
      }
      codeGroup += keyword;
    }
  }
    
  PvlGroup bandBin("BandBin");
  // There are no filters on the camera, so the default is clear with id # of 1
  // the BandBin group is only included to work with the spiceinit application
  bandBin += PvlKeyword("FilterName", "CLEAR");
  bandBin += PvlKeyword("FilterId", "1");
  
  kern += PvlKeyword("NaifFrameCode", apollo->NaifFrameCode());

  // Set up the nominal reseaus group
  Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory");
  Process p;
  PvlTranslationTable tTable(
      (QString)p.MissionData("base", "translations/MissionName2DataDir.trn"));
  QString missionDir = dataDir[tTable.Translate("MissionName", apollo->SpacecraftName())][0];
  Pvl resTemplate(missionDir + "/reseaus/" + apollo->InstrumentId() + "_NOMINAL.pvl");
  PvlGroup *reseaus = &resTemplate.findGroup("Reseaus");
  
  // Update reseau locations based on refined code location
  for (int i=0; i<(reseaus->findKeyword("Type")).size(); i++) {
    double x = toDouble(reseaus->findKeyword("Sample")[i]) + sampleTranslation + 2278,
           y = toDouble(reseaus->findKeyword("Line")[i]) + lineTranslation - 20231;
    
    if (apollo->IsApollo17()) {
        x += 50;
        y += 20;
    }
    
    reseaus->findKeyword("Sample")[i] = toString(
        cos(rotation)*(x-sampleTranslation) - sin(rotation)*(y-lineTranslation) + sampleTranslation);
    reseaus->findKeyword("Line")[i] = toString(
        sin(rotation)*(x-sampleTranslation) + cos(rotation)*(y-lineTranslation) + lineTranslation);
  }
  inst += PvlKeyword("StartTime", utcTime);
    
  opack->putGroup(inst);
  opack->putGroup(bandBin);
  opack->putGroup(kern);
  opack->putGroup(*reseaus);
  opack->putGroup(codeGroup);
}
Beispiel #16
0
  /**
   * Set the output cube to specified file name and specified input images
   * and output attributes and lat,lons
   */
  Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes,
      double slat, double elat, double slon, double elon,
      CubeAttributeOutput &oAtt, const QString &mosaicFile) {
    if (propagationCubes.size() < 1) {
      QString msg = "The list does not contain any data";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    int samples, lines, bands = 0;
    Pvl label;
    label.read(propagationCubes[0].toString());
    PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse);
    mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace);
    mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace);

    if (mGroup.hasKeyword("UpperLeftCornerX"))
      mGroup.deleteKeyword("UpperLeftCornerX");

    if (mGroup.hasKeyword("UpperLeftCornerY"))
      mGroup.deleteKeyword("UpperLeftCornerY");

    Pvl mapPvl;
    mapPvl += mGroup;

    // Use CreateForCube because our range differs from any of the cubes (manually specified)
    Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false);

    double xmin, xmax, ymin, ymax;
    proj->XYRange(xmin, xmax, ymin, ymax);

    // The xmin/ymax should be rounded for the labels
    xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"];
    ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"];

    for (int i = 0; i < propagationCubes.size(); i++) {
      Cube cube;
      cube.open(propagationCubes[i].toString());
      bands = max(cube.bandCount(), bands);

      // See if the cube has a projection and make sure it matches
      // previous input cubes
      Projection *projNew =
          Isis::ProjectionFactory::CreateFromCube(*(cube.label()));

      if (proj == NULL) {
      }
      else if (*proj != *projNew) {
        QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() +
                     "] and [" + propagationCubes[0].toString() + "]";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      if (proj) delete proj;
      proj = projNew;
    }

    if (proj) delete proj;

    return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax,
                         slat, elat, slon, elon, bands, oAtt, mosaicFile);
  }
Beispiel #17
0
// Main program
void IsisMain(){
  
  // Create an object for exporting Isis data
  ProcessExport p;
  // Open the input cube
  Cube *icube = p.SetInputCube("FROM");
 
  // Conform to the Big-Endian format for FITS
  if(IsLsb()) p.SetOutputEndian(Isis::Msb);

  // Generate the name of the fits file and open it
  UserInterface &ui = Application::GetUserInterface();
    
  // specify the bits per pixel
  string bitpix;
  if (ui.GetString ("BITTYPE") == "8BIT") bitpix = "8";
  else if (ui.GetString ("BITTYPE") == "16BIT") bitpix = "16";
  else if (ui.GetString ("BITTYPE") == "32BIT") bitpix = "-32";
  else {
    string msg = "Pixel type of [" + ui.GetString("BITTYPE") + "] is unsupported"; 
    throw iException::Message(iException::User, msg, _FILEINFO_);
  }

  //  Determine bit size and calculate number of bytes to write
  //  for each line.
  if (bitpix == "8") p.SetOutputType(Isis::UnsignedByte);
  if (bitpix == "16") p.SetOutputType(Isis::SignedWord);
  if (bitpix == "-32") p.SetOutputType(Isis::Real);
  
  // determine core base and multiplier, set up the stretch
  PvlGroup pix = icube->Label()->FindObject("IsisCube").FindObject("Core").FindGroup("Pixels");
  double scale = pix["Multiplier"][0].ToDouble();
  double base = pix["Base"][0].ToDouble();

  if (ui.GetString("STRETCH") != "NONE" && bitpix != "-32") {
    if (ui.GetString("STRETCH") == "LINEAR") {
      p.SetInputRange();
    }
    else if (ui.GetString("STRETCH") == "MANUAL") {
       p.SetInputRange(ui.GetDouble("MINIMUM"), ui.GetDouble("MAXIMUM"));
    }
    
    // create a proper scale so pixels look like 32bit data.
    scale = ((p.GetInputMaximum() - p.GetInputMinimum()) *
            (p.GetOutputMaximum() - p.GetOutputMinimum()));

    // round off after 14 decimals to avoid system architecture differences
    scale = ((floor(scale * 1e14)) / 1e14);

    // create a proper zero point so pixels look like 32bit data.
    base = -1.0 * (scale * p.GetOutputMinimum()) + p.GetInputMinimum();
    // round off after 14 decimals to avoid system architecture differences
    base = ((floor(base * 1e14)) / 1e14);
  }

  
  //////////////////////////////////////////
  // Write the minimal fits header	  //
  //////////////////////////////////////////
  string header;
  
  // specify that this file conforms to simple fits standard
  header += FitsKeyword("SIMPLE", true, "T");  
  
  
  // specify the bits per pixel
  header += FitsKeyword("BITPIX", true, bitpix);
  
  // specify the number of data axes (2: samples by lines)
  int axes = 2;
  if (icube->Bands() > 1) {
    axes = 3;
  }
  
  header += FitsKeyword("NAXIS", true, iString(axes));
  
  // specify the limit on data axis 1 (number of samples)
  header += FitsKeyword("NAXIS1", true, iString(icube->Samples()));

  // specify the limit on data axis 2 (number of lines)
  header += FitsKeyword("NAXIS2", true, iString(icube->Lines()));
 
  if (axes == 3){
    header += FitsKeyword("NAXIS3", true, iString(icube->Bands()));
  }

  header += FitsKeyword("BZERO", true,  base);

  header += FitsKeyword("BSCALE", true, scale);
  
  // Sky and All cases  
  if (ui.GetString("INFO") == "SKY" || ui.GetString("INFO") == "ALL") {  
    iString msg = "cube has not been skymapped";
    PvlGroup map;

    if (icube->HasGroup("mapping")) {
      map = icube->GetGroup("mapping");   
      msg = (string)map["targetname"];
    }
    // If we have sky we want it
    if (msg == "Sky") {
      double midRa = 0, midDec = 0;
  
      midRa = ((double)map["MaximumLongitude"] +
               (double)map["MinimumLongitude"])/2;
  
      midDec = ((double)map["MaximumLatitude"] +
                (double)map["MinimumLatitude"])/2;
  
      header += FitsKeyword("OBJCTRA", true, iString(midRa));
  
      // Specify the Declination
      header += FitsKeyword("OBJCTDEC", true, iString(midDec));
  
    }

    if (ui.GetString("INFO") == "ALL") {
      header += WritePvl("INSTRUME","Instrument","InstrumentId", icube, true);  
      header += WritePvl("OBSERVER","Instrument","SpacecraftName", icube, true);
      header += WritePvl("OBJECT  ","Instrument","TargetName", icube, true);
      // StartTime is sometimes middle of the exposure and somtimes beginning, 
      // so StopTime can't be calculated off of exposure reliably.
      header += WritePvl("DATE-OBS","Instrument","StartTime", icube, true);
      // Some cameras don't have StopTime
      if (icube->HasGroup("Instrument")) {
        PvlGroup inst = icube->GetGroup("Instrument");
        if (inst.HasKeyword("StopTime")) {
          header += WritePvl("TIME_END","Instrument","StopTime", icube, true);
        }
        if (inst.HasKeyword("ExposureDuration")) {
          header += WritePvl("EXPTIME","Instrument","ExposureDuration", icube, false);
        }
      }
    }  
    // If we were set on SKY and Sky doesn't exist
    else if (msg != "Sky") {  
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }
  }
  
  // signal the end of the header
  header += FitsKeyword("END", false, "");

  // fill the rest of the fits header with space so to conform with the fits header
  // size of 2880 bytes
  for (int i = header.length() % 2880 ; i < 2880 ; i++) header += " ";

  // open the cube for writing
  string to = ui.GetFilename("TO","fits");
  ofstream fout;  
  fout.open (to.c_str (), ios::out|ios::binary);
  if (!fout.is_open ()) {
    string msg = "Cannot open fits output file";
    throw iException::Message(iException::Programmer,msg,_FILEINFO_);
  }
 
  fout.seekp(0);
  fout.write(header.c_str(),header.length());
  // write the raw cube data
  p.StartProcess (fout);

  // Finish off data area to a number n % 2880 == 0 is true
  // 2880 is the size of the data blocks
  int count = 2880 - (fout.tellp() % 2880);
  for (int i = 0; i < count; i++) {
    // Write nul characters as needed. ascii 0, hex 00...
    fout.write("\0", 1);  
  }
  fout.close();  
  p.EndProcess();
}
Beispiel #18
0
bool TryKernels(Cube *icube, Process &p,
                Kernel lk, Kernel pck, 
                Kernel targetSpk, Kernel ck,
                Kernel fk, Kernel ik, Kernel sclk, 
                Kernel spk, Kernel iak, 
                Kernel dem, Kernel exk) {
  Pvl lab = *icube->Label();

  // Add the new kernel files to the existing kernels group
  PvlKeyword lkKeyword("LeapSecond");
  PvlKeyword pckKeyword("TargetAttitudeShape");
  PvlKeyword targetSpkKeyword("TargetPosition");
  PvlKeyword ckKeyword("InstrumentPointing");
  PvlKeyword ikKeyword("Instrument");
  PvlKeyword sclkKeyword("SpacecraftClock");
  PvlKeyword spkKeyword("InstrumentPosition");
  PvlKeyword iakKeyword("InstrumentAddendum");
  PvlKeyword demKeyword("ShapeModel");
  PvlKeyword exkKeyword("Extra");

  for (int i=0; i<lk.size(); i++) {
    lkKeyword.AddValue(lk[i]);
  }
  for (int i=0; i<pck.size(); i++) {
    pckKeyword.AddValue(pck[i]);
  }
  for (int i=0; i<targetSpk.size(); i++) {
    targetSpkKeyword.AddValue(targetSpk[i]);
  }
  for (int i=0; i<ck.size(); i++) {
    ckKeyword.AddValue(ck[i]);
  }
  for (int i=0; i<ik.size(); i++) {
    ikKeyword.AddValue(ik[i]);
  }
  for (int i=0; i<sclk.size(); i++) {
    sclkKeyword.AddValue(sclk[i]);
  }
  for (int i=0; i<spk.size(); i++) {
    spkKeyword.AddValue(spk[i]);
  }
  for (int i=0; i<iak.size(); i++) {
    iakKeyword.AddValue(iak[i]);
  }
  for (int i=0; i<dem.size(); i++) {
    demKeyword.AddValue(dem[i]);
  }
  for (int i=0; i<exk.size(); i++) {
    exkKeyword.AddValue(exk[i]);
  }

  PvlGroup originalKernels = icube->GetGroup("Kernels");
  PvlGroup currentKernels = originalKernels;
  currentKernels.AddKeyword(lkKeyword, Pvl::Replace);
  currentKernels.AddKeyword(pckKeyword, Pvl::Replace);
  currentKernels.AddKeyword(targetSpkKeyword, Pvl::Replace);
  currentKernels.AddKeyword(ckKeyword, Pvl::Replace);
  currentKernels.AddKeyword(ikKeyword, Pvl::Replace);
  currentKernels.AddKeyword(sclkKeyword, Pvl::Replace);
  currentKernels.AddKeyword(spkKeyword, Pvl::Replace);
  currentKernels.AddKeyword(iakKeyword, Pvl::Replace);
  currentKernels.AddKeyword(demKeyword, Pvl::Replace);

  // report qualities
  PvlKeyword spkQuality("InstrumentPositionQuality");
  spkQuality.AddValue(spiceInit::kernelTypeEnum(spk.kernelType));
  currentKernels.AddKeyword(spkQuality, Pvl::Replace);

  PvlKeyword ckQuality("InstrumentPointingQuality");
  ckQuality.AddValue(spiceInit::kernelTypeEnum(ck.kernelType));
  currentKernels.AddKeyword(ckQuality, Pvl::Replace);

  if (!exkKeyword.IsNull()) {
    currentKernels.AddKeyword(exkKeyword, Pvl::Replace);
  }
  else if( currentKernels.HasKeyword("EXTRA") ) {
    currentKernels.DeleteKeyword( "EXTRA" );
  }

  // Get rid of old keywords from previously inited cubes
  if (currentKernels.HasKeyword("SpacecraftPointing")) {
    currentKernels.DeleteKeyword("SpacecraftPointing");
  }
  if (currentKernels.HasKeyword("SpacecraftPosition")) {
    currentKernels.DeleteKeyword("SpacecraftPosition");
  }
  if (currentKernels.HasKeyword("ElevationModel")) {
    currentKernels.DeleteKeyword("ElevationModel");
  }
  if (currentKernels.HasKeyword("Frame")) {
    currentKernels.DeleteKeyword("Frame");
  }
  if (currentKernels.HasKeyword("StartPadding")) {
    currentKernels.DeleteKeyword("StartPadding");
  }
  if (currentKernels.HasKeyword("EndPadding")) {
    currentKernels.DeleteKeyword("EndPadding");
  }

  UserInterface &ui = Application::GetUserInterface();
  // Add any time padding the user specified to the spice group
  if(ui.GetDouble("STARTPAD") > DBL_EPSILON) {
     currentKernels.AddKeyword(PvlKeyword("StartPadding", ui.GetDouble("STARTPAD"), "seconds"));
  }

  if(ui.GetDouble("ENDPAD") > DBL_EPSILON) {
     currentKernels.AddKeyword(PvlKeyword("EndPadding", ui.GetDouble("ENDPAD"), "seconds"));
  }

  currentKernels.AddKeyword(PvlKeyword("CameraVersion",CameraFactory::CameraVersion(lab)), Pvl::Replace);

  // Add the modified Kernels group to the input cube labels
  icube->PutGroup(currentKernels);

  // Create the camera so we can get blobs if necessary
  try {
    Camera *cam;
    try {
      cam = icube->Camera();
      Application::Log(currentKernels);
    } catch (iException &e) {
      Pvl errPvl = e.PvlErrors();

      if(errPvl.Groups() > 0) {
        currentKernels += PvlKeyword("Error", errPvl.Group(errPvl.Groups()-1)["Message"][0]); 
      }
      
      Application::Log(currentKernels);
      icube->PutGroup(originalKernels);
      throw e;
    }
    if (ui.GetBoolean("ATTACH")) {
      Table ckTable = cam->InstrumentRotation()->Cache("InstrumentPointing");
      ckTable.Label() += PvlKeyword("Description", "Created by spiceinit");
      ckTable.Label() += PvlKeyword("Kernels");

      for (int i=0; i<ckKeyword.Size(); i++) {
        ckTable.Label()["Kernels"].AddValue(ckKeyword[i]);
      }
      icube->Write(ckTable);

      Table spkTable = cam->InstrumentPosition()->Cache("InstrumentPosition");
      spkTable.Label() += PvlKeyword("Description", "Created by spiceinit");
      spkTable.Label() += PvlKeyword("Kernels");
      for (int i=0; i<spkKeyword.Size(); i++) {
        spkTable.Label()["Kernels"].AddValue(spkKeyword[i]);
      }
      icube->Write(spkTable);

      Table bodyTable = cam->BodyRotation()->Cache("BodyRotation");
      bodyTable.Label() += PvlKeyword("Description", "Created by spiceinit");
      bodyTable.Label() += PvlKeyword("Kernels");
      for (int i=0; i<targetSpkKeyword.Size(); i++) {
        bodyTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]);
      }
      for (int i=0; i<pckKeyword.Size(); i++) {
        bodyTable.Label()["Kernels"].AddValue(pckKeyword[i]);
      }
      bodyTable.Label() += PvlKeyword("SolarLongitude", cam->SolarLongitude());
      icube->Write(bodyTable);

      Table sunTable = cam->SunPosition()->Cache("SunPosition");
      sunTable.Label() += PvlKeyword("Description", "Created by spiceinit");
      sunTable.Label() += PvlKeyword("Kernels");
      for (int i=0; i<targetSpkKeyword.Size(); i++) {
        sunTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]);
      }
      icube->Write(sunTable);

      //  Save original kernels in keyword before changing to Table
      PvlKeyword origCk = currentKernels["InstrumentPointing"];
      PvlKeyword origSpk = currentKernels["InstrumentPosition"];
      PvlKeyword origTargPos = currentKernels["TargetPosition"];

      currentKernels["InstrumentPointing"] = "Table";
      for (int i=0; i<origCk.Size(); i++) {
        currentKernels["InstrumentPointing"].AddValue(origCk[i]);
      }
      currentKernels["InstrumentPosition"] = "Table";
      for (int i=0; i<origSpk.Size(); i++) {
        currentKernels["InstrumentPosition"].AddValue(origSpk[i]);
      }
      currentKernels["TargetPosition"] = "Table";
      for (int i=0; i<origTargPos.Size(); i++) {
        currentKernels["TargetPosition"].AddValue(origTargPos[i]);
      }
      icube->PutGroup(currentKernels);
    }
    //modify Kernels group only
    else {
      Pvl *label = icube->Label();
      int i=0;
      while (i < label->Objects()) {
        PvlObject currObj = label->Object(i);
        if (currObj.IsNamed("Table")) {
          if (currObj["Name"][0] == iString("InstrumentPointing")) {
            label->DeleteObject(i);
          } else if (currObj["Name"][0] == iString("InstrumentPosition")) {
            label->DeleteObject(i);
          } else if (currObj["Name"][0] == iString("BodyRotation")) {
            label->DeleteObject(i);
          } else if (currObj["Name"][0] == iString("SunPosition")) {
            label->DeleteObject(i);
          } else {
            i++;
          }
        } else {
          i++;
        }
      }
    }

    p.WriteHistory(*icube);
  } catch (iException &e) {
    e.Clear();
    icube->PutGroup(originalKernels);
    return false;
  }

  return true;
}
Beispiel #19
0
  /**
   * GetPointInfo builds the PvlGroup containing all the important
   * information derived from the Camera.
   *
   * @return PvlGroup* Data taken directly from the Camera and
   *         drived from Camera information. Ownership passed.
   */
  PvlGroup *CameraPointInfo::GetPointInfo(bool passed, bool allowOutside, bool allowErrors) {
    PvlGroup *gp = new PvlGroup("GroundPoint");
    {
      gp->addKeyword(PvlKeyword("Filename"));
      gp->addKeyword(PvlKeyword("Sample"));
      gp->addKeyword(PvlKeyword("Line"));
      gp->addKeyword(PvlKeyword("PixelValue"));
      gp->addKeyword(PvlKeyword("RightAscension"));
      gp->addKeyword(PvlKeyword("Declination"));
      gp->addKeyword(PvlKeyword("PlanetocentricLatitude"));
      gp->addKeyword(PvlKeyword("PlanetographicLatitude"));
      gp->addKeyword(PvlKeyword("PositiveEast360Longitude"));
      gp->addKeyword(PvlKeyword("PositiveEast180Longitude"));
      gp->addKeyword(PvlKeyword("PositiveWest360Longitude"));
      gp->addKeyword(PvlKeyword("PositiveWest180Longitude"));
      gp->addKeyword(PvlKeyword("BodyFixedCoordinate"));
      gp->addKeyword(PvlKeyword("LocalRadius"));
      gp->addKeyword(PvlKeyword("SampleResolution"));
      gp->addKeyword(PvlKeyword("LineResolution"));
      gp->addKeyword(PvlKeyword("SpacecraftPosition"));
      gp->addKeyword(PvlKeyword("SpacecraftAzimuth"));
      gp->addKeyword(PvlKeyword("SlantDistance"));
      gp->addKeyword(PvlKeyword("TargetCenterDistance"));
      gp->addKeyword(PvlKeyword("SubSpacecraftLatitude"));
      gp->addKeyword(PvlKeyword("SubSpacecraftLongitude"));
      gp->addKeyword(PvlKeyword("SpacecraftAltitude"));
      gp->addKeyword(PvlKeyword("OffNadirAngle"));
      gp->addKeyword(PvlKeyword("SubSpacecraftGroundAzimuth"));
      gp->addKeyword(PvlKeyword("SunPosition"));
      gp->addKeyword(PvlKeyword("SubSolarAzimuth"));
      gp->addKeyword(PvlKeyword("SolarDistance"));
      gp->addKeyword(PvlKeyword("SubSolarLatitude"));
      gp->addKeyword(PvlKeyword("SubSolarLongitude"));
      gp->addKeyword(PvlKeyword("SubSolarGroundAzimuth"));
      gp->addKeyword(PvlKeyword("Phase"));
      gp->addKeyword(PvlKeyword("Incidence"));
      gp->addKeyword(PvlKeyword("Emission"));
      gp->addKeyword(PvlKeyword("NorthAzimuth"));
      gp->addKeyword(PvlKeyword("EphemerisTime"));
      gp->addKeyword(PvlKeyword("UTC"));
      gp->addKeyword(PvlKeyword("LocalSolarTime"));
      gp->addKeyword(PvlKeyword("SolarLongitude"));
      if (allowErrors) gp->addKeyword(PvlKeyword("Error"));
    }

    bool noErrors = passed;
    QString error = "";
    if (!m_camera->HasSurfaceIntersection()) {
      error = "Requested position does not project in camera model; no surface intersection";
      noErrors = false;
      if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_);
    }
    if (!m_camera->InCube() && !allowOutside) {
      error = "Requested position does not project in camera model; not inside cube";
      noErrors = false;
      if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_);
    }

    if (!noErrors) {
      for (int i = 0; i < gp->keywords(); i++) {
        QString name = (*gp)[i].name();
        // These three keywords have 3 values, so they must have 3 N/As
        if (name == "BodyFixedCoordinate" || name == "SpacecraftPosition" ||
            name == "SunPosition") {
          (*gp)[i].addValue("N/A");
          (*gp)[i].addValue("N/A");
          (*gp)[i].addValue("N/A");
        }
        else {
          (*gp)[i].setValue("N/A");
        }
      }
      // Set all keywords that still have valid information
      gp->findKeyword("Error").setValue(error);
      gp->findKeyword("FileName").setValue(m_currentCube->fileName());
      gp->findKeyword("Sample").setValue(toString(m_camera->Sample()));
      gp->findKeyword("Line").setValue(toString(m_camera->Line()));
      gp->findKeyword("EphemerisTime").setValue(
                      toString(m_camera->time().Et()), "seconds");
      gp->findKeyword("EphemerisTime").addComment("Time");
      QString utc = m_camera->time().UTC();
      gp->findKeyword("UTC").setValue(utc);
      gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information");
      gp->findKeyword("SunPosition").addComment("Sun Information");
      gp->findKeyword("Phase").addComment("Illumination and Other");
    }

    else {

      Brick b(3, 3, 1, m_currentCube->pixelType());

      int intSamp = (int)(m_camera->Sample() + 0.5);
      int intLine = (int)(m_camera->Line() + 0.5);
      b.SetBasePosition(intSamp, intLine, 1);
      m_currentCube->read(b);

      double pB[3], spB[3], sB[3];
      QString utc;
      double ssplat, ssplon, sslat, sslon, pwlon, oglat;

      {
        gp->findKeyword("FileName").setValue(m_currentCube->fileName());
        gp->findKeyword("Sample").setValue(toString(m_camera->Sample()));
        gp->findKeyword("Line").setValue(toString(m_camera->Line()));
        gp->findKeyword("PixelValue").setValue(PixelToString(b[0]));
        gp->findKeyword("RightAscension").setValue(toString(
                        m_camera->RightAscension()));
        gp->findKeyword("Declination").setValue(toString(
                        m_camera->Declination()));
        gp->findKeyword("PlanetocentricLatitude").setValue(toString(
                        m_camera->UniversalLatitude()));

        // Convert lat to planetographic
        Distance radii[3];
        m_camera->radii(radii);
        oglat = TProjection::ToPlanetographic(m_camera->UniversalLatitude(),
                                                    radii[0].kilometers(), 
                                                    radii[2].kilometers());
        gp->findKeyword("PlanetographicLatitude").setValue(toString(oglat));

        gp->findKeyword("PositiveEast360Longitude").setValue(toString(
                        m_camera->UniversalLongitude()));

        //Convert lon to -180 - 180 range
        gp->findKeyword("PositiveEast180Longitude").setValue(toString(
                        TProjection::To180Domain(m_camera->UniversalLongitude())));

        //Convert lon to positive west
        pwlon = TProjection::ToPositiveWest(
                               m_camera->UniversalLongitude(), 360);
        gp->findKeyword("PositiveWest360Longitude").setValue(toString(pwlon));

        //Convert pwlon to -180 - 180 range
        gp->findKeyword("PositiveWest180Longitude").setValue(toString(
                        TProjection::To180Domain(pwlon)));

        m_camera->Coordinate(pB);
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[0]), "km");
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[1]), "km");
        gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[2]), "km");

        gp->findKeyword("LocalRadius").setValue(toString(
                        m_camera->LocalRadius().meters()), "meters");
        gp->findKeyword("SampleResolution").setValue(toString(
                        m_camera->SampleResolution()), "meters/pixel");
        gp->findKeyword("LineResolution").setValue(toString(
                        m_camera->LineResolution()), "meters/pixel");

        //body fixed
        m_camera->instrumentPosition(spB);
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[0]), "km");
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[1]), "km");
        gp->findKeyword("SpacecraftPosition").addValue(toString(spB[2]), "km");
        gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information");

        gp->findKeyword("SpacecraftAzimuth").setValue(toString(
                        m_camera->SpacecraftAzimuth()));
        gp->findKeyword("SlantDistance").setValue(toString(
                        m_camera->SlantDistance()), "km");
        gp->findKeyword("TargetCenterDistance").setValue(toString(
                        m_camera->targetCenterDistance()), "km");
        m_camera->subSpacecraftPoint(ssplat, ssplon);
        gp->findKeyword("SubSpacecraftLatitude").setValue(toString(ssplat));
        gp->findKeyword("SubSpacecraftLongitude").setValue(toString(ssplon));
        gp->findKeyword("SpacecraftAltitude").setValue(toString(
                        m_camera->SpacecraftAltitude()), "km");
        gp->findKeyword("OffNadirAngle").setValue(toString(
                        m_camera->OffNadirAngle()));
        double subspcgrdaz;
        subspcgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), 
                                              m_camera->UniversalLongitude(),
                                              ssplat, ssplon);
        gp->findKeyword("SubSpacecraftGroundAzimuth").setValue(toString(subspcgrdaz));

        m_camera->sunPosition(sB);
        gp->findKeyword("SunPosition").addValue(toString(sB[0]), "km");
        gp->findKeyword("SunPosition").addValue(toString(sB[1]), "km");
        gp->findKeyword("SunPosition").addValue(toString(sB[2]), "km");
        gp->findKeyword("SunPosition").addComment("Sun Information");

        gp->findKeyword("SubSolarAzimuth").setValue(toString(m_camera->SunAzimuth()));
        gp->findKeyword("SolarDistance").setValue(toString(
                        m_camera->SolarDistance()), "AU");
        m_camera->subSolarPoint(sslat, sslon);
        gp->findKeyword("SubSolarLatitude").setValue(toString(sslat));
        gp->findKeyword("SubSolarLongitude").setValue(toString(sslon));
        double subsolgrdaz;
        subsolgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), 
                                              m_camera->UniversalLongitude(),
                                              sslat, sslon);
        gp->findKeyword("SubSolarGroundAzimuth").setValue(toString(subsolgrdaz));

        gp->findKeyword("Phase").setValue(toString(m_camera->PhaseAngle()));
        gp->findKeyword("Phase").addComment("Illumination and Other");
        gp->findKeyword("Incidence").setValue(toString(
                        m_camera->IncidenceAngle()));
        gp->findKeyword("Emission").setValue(toString(
                        m_camera->EmissionAngle()));
        gp->findKeyword("NorthAzimuth").setValue(toString(
                        m_camera->NorthAzimuth()));

        gp->findKeyword("EphemerisTime").setValue(toString(
                        m_camera->time().Et()), "seconds");
        gp->findKeyword("EphemerisTime").addComment("Time");
        utc = m_camera->time().UTC();
        gp->findKeyword("UTC").setValue(utc);
        gp->findKeyword("LocalSolarTime").setValue(toString(
                        m_camera->LocalSolarTime()), "hour");
        gp->findKeyword("SolarLongitude").setValue(toString(
                        m_camera->solarLongitude().degrees()));
        if (allowErrors) gp->findKeyword("Error").setValue("N/A");
      }
    }
    return gp;
  }
Beispiel #20
0
void TranslateLabels(FileName in, Cube *ocube) {
  // Get the directory where the Clementine translation tables are.
  PvlGroup &dataDir = Preference::Preferences().findGroup("DataDirectory");

  // Transfer the instrument group to the output cube
  QString transDir = (QString) dataDir["clementine1"];
  FileName transFile(transDir + "/translations/clementine.trn");

  Pvl pdsLab(in.expanded());
  PvlTranslationManager labelXlater(pdsLab, transFile.expanded());

  // Pvl outputLabels;
  Pvl *outputLabel = ocube->label();
  labelXlater.Auto(*(outputLabel));

  //Instrument group
  PvlGroup inst = outputLabel->findGroup("Instrument", Pvl::Traverse);

  PvlKeyword &startTime = inst.findKeyword("StartTime");
  startTime.setValue(startTime[0].mid(0, startTime[0].size() - 1));

  // Old PDS labels used keyword INSTRUMENT_COMPRESSION_TYPE & PDS Labels now use ENCODING_TYPE
  if(pdsLab.findObject("Image").hasKeyword("InstrumentCompressionType")) {
    inst += PvlKeyword("EncodingFormat", (QString) pdsLab.findObject("Image")["InstrumentCompressionType"]);
  }
  else {
    inst += PvlKeyword("EncodingFormat", (QString) pdsLab.findObject("Image")["EncodingType"]);
  }

  if(((QString)inst["InstrumentId"]) == "HIRES") {
    inst += PvlKeyword("MCPGainModeID", (QString)pdsLab["MCP_Gain_Mode_ID"], "");
  }

  ocube->putGroup(inst);

  PvlGroup bBin = outputLabel->findGroup("BandBin", Pvl::Traverse);
  QString filter = pdsLab["FilterName"];
  if(filter != "F") {
    //Band Bin group
    double center = pdsLab["CenterFilterWavelength"];
    center /= 1000.0;
    bBin.findKeyword("Center").setValue(toString(center), "micrometers");
  }
  double width = pdsLab["Bandwidth"];
  width /= 1000.0;
  bBin.findKeyword("Width").setValue(toString(width), "micrometers");
  ocube->putGroup(bBin);

  //Kernel group
  PvlGroup kern("Kernels");
  if(((QString)inst["InstrumentId"]) == "HIRES") {
    kern += PvlKeyword("NaifFrameCode", "-40001");
  }
  if(((QString)inst["InstrumentId"]) == "UVVIS") {
    kern += PvlKeyword("NaifFrameCode", "-40002");
  }
  if(((QString)inst["InstrumentId"]) == "NIR") {
    kern += PvlKeyword("NaifFrameCode", "-40003");
  }
  if(((QString)inst["InstrumentId"]) == "LWIR") {
    kern += PvlKeyword("NaifFrameCode", "-40004");
  }
  ocube->putGroup(kern);

  OriginalLabel org(pdsLab);
  ocube->write(org);
}
Beispiel #21
0
  /**
   * GetPointInfo builds the PvlGroup containing all the important 
   * information derived from the Camera.  
   * 
   * @return PvlGroup* Data taken directly from the Camera and 
   *         drived from Camera information. Ownership passed.
   */
  PvlGroup * CameraPointInfo::GetPointInfo() {
    CheckConditions();

    Brick b(3,3,1,currentCube->PixelType());
    
    int intSamp = (int)(camera->Sample() + 0.5);
    int intLine = (int)(camera->Line() + 0.5);
    b.SetBasePosition(intSamp, intLine, 1);
    currentCube->Read(b);

    double pB[3], spB[3], sB[3];
    string utc;
    double ssplat, ssplon, sslat, sslon, pwlon, oglat;

    // Create group with ground position
    PvlGroup * gp = new PvlGroup("GroundPoint");
    {
      gp->AddKeyword(PvlKeyword("Filename",currentCube->Filename()));
      gp->AddKeyword(PvlKeyword("Sample",camera->Sample()));
      gp->AddKeyword(PvlKeyword("Line",camera->Line()));
      gp->AddKeyword(PvlKeyword("PixelValue",PixelToString(b[0])));
      gp->AddKeyword(PvlKeyword("RightAscension",camera->RightAscension()));
      gp->AddKeyword(PvlKeyword("Declination",camera->Declination()));
      gp->AddKeyword(PvlKeyword("PlanetocentricLatitude",
                                camera->UniversalLatitude()));
  
      // Convert lat to planetographic
      double radii[3];
      camera->Radii(radii);
      oglat = Isis::Projection::ToPlanetographic(camera->UniversalLatitude(),
                                                 radii[0],radii[2]);
      gp->AddKeyword(PvlKeyword("PlanetographicLatitude",oglat));
      
      gp->AddKeyword(PvlKeyword("PositiveEast360Longitude",
                                camera->UniversalLongitude()));
  
      //Convert lon to -180 - 180 range
      gp->AddKeyword(PvlKeyword("PositiveEast180Longitude",
                                Isis::Projection::To180Domain(
                                  camera->UniversalLongitude())));

      //Convert lon to positive west
      pwlon = Isis::Projection::ToPositiveWest(camera->UniversalLongitude(),
                                               360);
      gp->AddKeyword(PvlKeyword("PositiveWest360Longitude",pwlon));

      //Convert pwlon to -180 - 180 range
      gp->AddKeyword(PvlKeyword("PositiveWest180Longitude",
                                Isis::Projection::To180Domain(pwlon)));
  
      camera->Coordinate(pB);
      PvlKeyword coord("BodyFixedCoordinate");
      coord.AddValue(pB[0],"km");
      coord.AddValue(pB[1],"km");
      coord.AddValue(pB[2],"km");
      gp->AddKeyword(coord);
  
      gp->AddKeyword(PvlKeyword("LocalRadius",camera->LocalRadius(),"m"));
      gp->AddKeyword(PvlKeyword("SampleResolution",camera->SampleResolution(),"m"));
      gp->AddKeyword(PvlKeyword("LineResolution",camera->LineResolution(),"m"));
  
      camera->InstrumentPosition(spB);
      PvlKeyword spcoord("SpacecraftPosition");
      spcoord.AddValue(spB[0],"km");
      spcoord.AddValue(spB[1],"km");
      spcoord.AddValue(spB[2],"km");
      spcoord.AddComment("Spacecraft Information");
      gp->AddKeyword(spcoord);
  
  
      gp->AddKeyword(PvlKeyword("SpacecraftAzimuth",camera->SpacecraftAzimuth()));
      gp->AddKeyword(PvlKeyword("SlantDistance",camera->SlantDistance(),"km"));
      gp->AddKeyword(PvlKeyword("TargetCenterDistance",camera->TargetCenterDistance(),"km"));
      camera->SubSpacecraftPoint(ssplat,ssplon);
      gp->AddKeyword(PvlKeyword("SubSpacecraftLatitude",ssplat));
      gp->AddKeyword(PvlKeyword("SubSpacecraftLongitude",ssplon));
      gp->AddKeyword(PvlKeyword("SpacecraftAltitude",camera->SpacecraftAltitude(),"km"));
      gp->AddKeyword(PvlKeyword("OffNadirAngle",camera->OffNadirAngle()));
      double subspcgrdaz;
      subspcgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(),
        ssplat,ssplon);
      gp->AddKeyword(PvlKeyword("SubSpacecraftGroundAzimuth",subspcgrdaz));
  
      camera->SunPosition(sB);
      PvlKeyword scoord("SunPosition");
      scoord.AddValue(sB[0],"km");
      scoord.AddValue(sB[1],"km");
      scoord.AddValue(sB[2],"km");
      scoord.AddComment("Sun Information");
      gp->AddKeyword(scoord);
  
      gp->AddKeyword(PvlKeyword("SubSolarAzimuth",camera->SunAzimuth()));
      gp->AddKeyword(PvlKeyword("SolarDistance",camera->SolarDistance(),"AU"));
      camera->SubSolarPoint(sslat,sslon);
      gp->AddKeyword(PvlKeyword("SubSolarLatitude",sslat));
      gp->AddKeyword(PvlKeyword("SubSolarLongitude",sslon));
      double subsolgrdaz;
      subsolgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(),
        sslat,sslon);
      gp->AddKeyword(PvlKeyword("SubSolarGroundAzimuth",subsolgrdaz));
  
      PvlKeyword phase("Phase",camera->PhaseAngle());
      phase.AddComment("Illumination and Other");
      gp->AddKeyword(phase);
      gp->AddKeyword(PvlKeyword("Incidence",camera->IncidenceAngle()));
      gp->AddKeyword(PvlKeyword("Emission",camera->EmissionAngle()));
      gp->AddKeyword(PvlKeyword("NorthAzimuth",camera->NorthAzimuth()));
  
      PvlKeyword et("EphemerisTime",camera->EphemerisTime(),"seconds");
      et.AddComment("Time");
      gp->AddKeyword(et);
      iTime t(camera->EphemerisTime());
      utc = t.UTC();
      gp->AddKeyword(PvlKeyword("UTC",utc));
      gp->AddKeyword(PvlKeyword("LocalSolarTime",camera->LocalSolarTime(),"hour"));
      gp->AddKeyword(PvlKeyword("SolarLongitude",camera->SolarLongitude()));
    }
    return gp;
  }
Beispiel #22
0
void IsisMain() {

  Preference::Preferences(true);

  cout << "Testing Isis::ProcessMapMosaic Class ... " << endl;

  // Create the temp parent cube
  FileList cubes;
  cubes.read("unitTest.lis");

  cout << "Testing Mosaic 1" << endl;
  ProcessMapMosaic m1;
  CubeAttributeOutput oAtt;
  ProcessMosaic::ImageOverlay priority = ProcessMapMosaic::PlaceImagesOnTop;
  m1.SetBandBinMatch(false);
  m1.SetOutputCube(cubes, oAtt, "./unitTest.cub");

  //set priority
  m1.SetImageOverlay(priority);

  for(int i = 0; i < cubes.size(); i++) {
    if(m1.StartProcess(cubes[i].toString())) {
      cout << cubes[i].toString() << " is inside the mosaic" << endl;
    }
    else {
      cout << cubes[i].toString() << " is outside the mosaic" << endl;
    }
  }

  m1.EndProcess();
  cout << "Mosaic label: " << endl;

  Pvl labels("./unitTest.cub");
  cout << labels << endl;

  remove("./unitTest.cub");

  cout << "Testing Mosaic 2" << endl;
  ProcessMapMosaic m2;
  m2.SetBandBinMatch(false);
  m2.SetOutputCube(cubes, -6, -4, 29, 31, oAtt, "./unitTest.cub");

  //set priority
  m2.SetImageOverlay(priority);

  for(int i = 0; i < cubes.size(); i++) {
    if(m2.StartProcess(cubes[i].toString())) {
      cout << cubes[i].toString() << " is inside the mosaic" << endl;
    }
    else {
      cout << cubes[i].toString() << " is outside the mosaic" << endl;
    }
  }

  m2.EndProcess();
  cout << "Mosaic label: " << endl;

  labels.clear();
  labels.read("./unitTest.cub");
  cout << labels << endl;

  Cube tmp;
  tmp.open("./unitTest.cub");
  LineManager lm(tmp);
  lm.SetLine(1, 1);

  while(!lm.end()) {
    tmp.read(lm);
    cout << "Mosaic Data: " << lm[lm.SampleDimension()/4] << '\t' <<
              lm[lm.SampleDimension()/2] << '\t' <<
              lm[(3*lm.SampleDimension())/4] << endl;
    lm++;
  }

  tmp.close();
  remove("./unitTest.cub");  // Create the temp parent cube

  cout << endl << "Testing Mosaic where the input (x, y) is negative,"
          " according to the output cube." << endl;
  QString inputFile = "./unitTest1.cub";
  Cube inCube;
  inCube.open(inputFile);
  PvlGroup mapGroup = inCube.label()->findGroup("Mapping", Pvl::Traverse);

  mapGroup.addKeyword(PvlKeyword("MinimumLatitude",  toString(-4.9)), Pvl::Replace);
  mapGroup.addKeyword(PvlKeyword("MaximumLatitude",  toString(-4.7)), Pvl::Replace);
  mapGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(30.7)), Pvl::Replace);
  mapGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(31)), Pvl::Replace);
  
  inCube.close();
  CubeAttributeOutput oAtt2( FileName("./unitTest3.cub") );
  ProcessMapMosaic m3;
  
  m3.SetBandBinMatch(false);
  m3.SetOutputCube(inputFile, mapGroup, oAtt2, "./unitTest3.cub");

  //set priority
  m3.SetImageOverlay(priority);
  m3.SetHighSaturationFlag(false);
  m3.SetLowSaturationFlag(false);
  m3.SetNullFlag(false);

  if(m3.StartProcess(inputFile)) {
    cout << "The mosaic was successfull." << endl;
  }
  else {
    cout << "The mosaic was not successfull." << endl;
  }

  m3.EndProcess();
  cout << "Mosaic label: " << endl;

  Pvl labels2("./unitTest3.cub");
  cout << labels2 << endl;

  remove("./unitTest3.cub");

}
Beispiel #23
0
void IsisMain() {
  const QString caminfo_program  = "caminfo";
  UserInterface &ui = Application::GetUserInterface();

  QList< QPair<QString, QString> > *general = NULL, *camstats = NULL, *statistics = NULL;
  BandGeometry *bandGeom = NULL;

  // Get input filename
  FileName in = ui.GetFileName("FROM");

  // Get the format
  QString sFormat = ui.GetAsString("FORMAT");

  // if true then run spiceinit, xml default is FALSE
  // spiceinit will use system kernels
  if(ui.GetBoolean("SPICE")) {
    QString parameters = "FROM=" + in.expanded();
    ProgramLauncher::RunIsisProgram("spiceinit", parameters);
  }

  Process p;
  Cube *incube = p.SetInputCube("FROM");

  // General data gathering
  general = new QList< QPair<QString, QString> >;
  general->append(MakePair("Program",     caminfo_program));
  general->append(MakePair("IsisVersion", Application::Version()));
  general->append(MakePair("RunDate",     iTime::CurrentGMT()));
  general->append(MakePair("IsisId",      SerialNumber::Compose(*incube)));
  general->append(MakePair("From",        in.baseName() + ".cub"));
  general->append(MakePair("Lines",       toString(incube->lineCount())));
  general->append(MakePair("Samples",     toString(incube->sampleCount())));
  general->append(MakePair("Bands",       toString(incube->bandCount())));

  // Run camstats on the entire image (all bands)
  // another camstats will be run for each band and output
  // for each band.
  if(ui.GetBoolean("CAMSTATS")) {
    camstats = new QList< QPair<QString, QString> >;

    QString filename = ui.GetAsString("FROM");
    int sinc = ui.GetInteger("SINC");
    int linc = ui.GetInteger("LINC");
    CameraStatistics stats(filename, sinc, linc);
    Pvl camPvl = stats.toPvl();

    PvlGroup cg = camPvl.findGroup("Latitude", Pvl::Traverse);
    camstats->append(MakePair("MinimumLatitude", cg["latitudeminimum"][0]));
    camstats->append(MakePair("MaximumLatitude", cg["latitudemaximum"][0]));

    cg = camPvl.findGroup("Longitude", Pvl::Traverse);
    camstats->append(MakePair("MinimumLongitude", cg["longitudeminimum"][0]));
    camstats->append(MakePair("MaximumLongitude", cg["longitudemaximum"][0]));

    cg = camPvl.findGroup("Resolution", Pvl::Traverse);
    camstats->append(MakePair("MinimumResolution", cg["resolutionminimum"][0]));
    camstats->append(MakePair("MaximumResolution", cg["resolutionmaximum"][0]));

    cg = camPvl.findGroup("PhaseAngle", Pvl::Traverse);
    camstats->append(MakePair("MinimumPhase", cg["phaseminimum"][0]));
    camstats->append(MakePair("MaximumPhase", cg["phasemaximum"][0]));

    cg = camPvl.findGroup("EmissionAngle", Pvl::Traverse);
    camstats->append(MakePair("MinimumEmission", cg["emissionminimum"][0]));
    camstats->append(MakePair("MaximumEmission", cg["emissionmaximum"][0]));

    cg = camPvl.findGroup("IncidenceAngle", Pvl::Traverse);
    camstats->append(MakePair("MinimumIncidence", cg["incidenceminimum"][0]));
    camstats->append(MakePair("MaximumIncidence", cg["incidencemaximum"][0]));

    cg = camPvl.findGroup("LocalSolarTime", Pvl::Traverse);
    camstats->append(MakePair("LocalTimeMinimum", cg["localsolartimeMinimum"][0]));
    camstats->append(MakePair("LocalTimeMaximum", cg["localsolartimeMaximum"][0]));
  }

  // Compute statistics for entire cube
  if(ui.GetBoolean("STATISTICS")) {
    statistics = new QList< QPair<QString, QString> >;

    LineManager iline(*incube);
    Statistics stats;
    Progress progress;
    progress.SetText("Statistics...");
    progress.SetMaximumSteps(incube->lineCount()*incube->bandCount());
    progress.CheckStatus();
    iline.SetLine(1);
    for(; !iline.end() ; iline.next()) {
      incube->read(iline);
      stats.AddData(iline.DoubleBuffer(), iline.size());
      progress.CheckStatus();
    }

    //  Compute stats of entire cube
    double nPixels     = stats.TotalPixels();
    double nullpercent = (stats.NullPixels() / (nPixels)) * 100;
    double hispercent  = (stats.HisPixels() / (nPixels)) * 100;
    double hrspercent  = (stats.HrsPixels() / (nPixels)) * 100;
    double lispercent  = (stats.LisPixels() / (nPixels)) * 100;
    double lrspercent  = (stats.LrsPixels() / (nPixels)) * 100;

    // Statitics output for band
    statistics->append(MakePair("MeanValue", toString(stats.Average())));
    statistics->append(MakePair("StandardDeviation", toString(stats.StandardDeviation())));
    statistics->append(MakePair("MinimumValue", toString(stats.Minimum())));
    statistics->append(MakePair("MaximumValue", toString(stats.Maximum())));
    statistics->append(MakePair("PercentHIS", toString(hispercent)));
    statistics->append(MakePair("PercentHRS", toString(hrspercent)));
    statistics->append(MakePair("PercentLIS", toString(lispercent)));
    statistics->append(MakePair("PercentLRS", toString(lrspercent)));
    statistics->append(MakePair("PercentNull", toString(nullpercent)));
    statistics->append(MakePair("TotalPixels", toString(stats.TotalPixels())));
  }

  bool getFootBlob = ui.GetBoolean("USELABEL");
  bool doGeometry = ui.GetBoolean("GEOMETRY");
  bool doPolygon = ui.GetBoolean("POLYGON");
  if(doGeometry || doPolygon || getFootBlob) {
    Camera *cam = incube->camera();

    QString incType = ui.GetString("INCTYPE");
    int polySinc, polyLinc;
    if(doPolygon && incType.toUpper() == "VERTICES") {
      ImagePolygon poly;
      poly.initCube(*incube);
      polySinc = polyLinc = (int)(0.5 + (((poly.validSampleDim() * 2) +
                                 (poly.validLineDim() * 2) - 3.0) /
                                 ui.GetInteger("NUMVERTICES")));
    }
    else if (incType.toUpper() == "LINCSINC"){
      if(ui.WasEntered("POLYSINC")) {
        polySinc = ui.GetInteger("POLYSINC");
      }
      else {
        polySinc = (int)(0.5 + 0.10 * incube->sampleCount());
        if(polySinc == 0) polySinc = 1;
      }
      if(ui.WasEntered("POLYLINC")) {
        polyLinc = ui.GetInteger("POLYLINC");
      }
      else {
        polyLinc = (int)(0.5 + 0.10 * incube->lineCount());
        if(polyLinc == 0) polyLinc = 1;
      }
    }
    else {
      QString msg = "Invalid INCTYPE option[" + incType + "]";
      throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    bandGeom = new BandGeometry();
    bandGeom->setSampleInc(polySinc);
    bandGeom->setLineInc(polyLinc);
    bandGeom->setMaxIncidence(ui.GetDouble("MAXINCIDENCE"));
    bandGeom->setMaxEmission(ui.GetDouble("MAXEMISSION"));
    bool precision = ui.GetBoolean("INCREASEPRECISION");

    if (getFootBlob) {
      // Need to read history to obtain parameters that were used to
      // create the footprint
      History hist("IsisCube", in.expanded());
      Pvl pvl = hist.ReturnHist();
      PvlObject::PvlObjectIterator objIter;
      bool found = false;
      PvlGroup fpgrp;
      for (objIter=pvl.endObject()-1; objIter>=pvl.beginObject(); objIter--) {
        if (objIter->name().toUpper() == "FOOTPRINTINIT") {
          found = true;
          fpgrp = objIter->findGroup("UserParameters");
          break;
        }
      }
      if (!found) {
        QString msg = "Footprint blob was not found in input image history";
        throw IException(IException::User, msg, _FILEINFO_);
      }
      QString prec = (QString)fpgrp.findKeyword("INCREASEPRECISION");
      prec = prec.toUpper();
      if (prec == "TRUE") {
        precision = true;
      }
      else {
        precision = false;
      }
      QString inctype = (QString)fpgrp.findKeyword("INCTYPE");
      inctype = inctype.toUpper();
      if (inctype == "LINCSINC") {
        int linc = fpgrp.findKeyword("LINC");
        int sinc = fpgrp.findKeyword("SINC");
        bandGeom->setSampleInc(sinc);
        bandGeom->setLineInc(linc);
      }
      else {
        int vertices = fpgrp.findKeyword("NUMVERTICES");
        int lincsinc = (int)(0.5 + (((incube->sampleCount() * 2) +
                       (incube->lineCount() * 2) - 3.0) /
                       vertices));
        bandGeom->setSampleInc(lincsinc);
        bandGeom->setLineInc(lincsinc);
      }
      if (fpgrp.hasKeyword("MAXINCIDENCE")) {
        double maxinc = fpgrp.findKeyword("MAXINCIDENCE");
        bandGeom->setMaxIncidence(maxinc);
      }
      if (fpgrp.hasKeyword("MAXEMISSION")) {
        double maxema = fpgrp.findKeyword("MAXEMISSION");
        bandGeom->setMaxEmission(maxema);
      }
    }
    
    bandGeom->collect(*cam, *incube, doGeometry, doPolygon, getFootBlob, precision);

    // Check if the user requires valid image center geometry
    if(ui.GetBoolean("VCAMERA") && (!bandGeom->hasCenterGeometry())) {
      QString msg = "Image center does not project in camera model";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }
  }

  if(sFormat.toUpper() == "PVL")
    GeneratePVLOutput(incube, general, camstats, statistics, bandGeom);
  else
    GenerateCSVOutput(incube, general, camstats, statistics, bandGeom);

  // Clean the data
  delete general;
  general = NULL;
  if(camstats) {
    delete camstats;
    camstats = NULL;
  }
  if(statistics) {
    delete statistics;
    statistics = NULL;
  }
  if(bandGeom) {
    delete bandGeom;
    bandGeom = NULL;
  }

}
Beispiel #24
0
void IsisMain() {
  UserInterface &ui = Application::GetUserInterface();
  SerialNumberList serialNumbers(true);

  FileList images(ui.GetFileName("FROMLIST"));
  // list of sns/filenames sorted by serial number
  vector< pair<QString, QString> > sortedList;

  // We want to sort the input data by serial number so that the same
  //   results are produced every time this program is run with the same
  //   images. This is a modified insertion sort.
  for(int image = 0; image < images.size(); image++) {
    unsigned int insertPos = 0;
    QString sn = SerialNumber::Compose(images[image].toString());

    for(insertPos = 0; insertPos < sortedList.size(); insertPos++) {
      if(sn.compare(sortedList[insertPos].first) < 0) break;
    }

    pair<QString, QString> newPair = pair<QString, QString>(sn, images[image].toString());
    sortedList.insert(sortedList.begin() + insertPos, newPair);
  }

  // Add the serial numbers in sorted order now
  for(unsigned int i = 0; i < sortedList.size(); i++) {
    serialNumbers.Add(sortedList[i].second);
  }

  // Now we want the ImageOverlapSet to calculate our overlaps
  ImageOverlapSet overlaps(true);

  // Use multi-threading to create the overlaps
  overlaps.FindImageOverlaps(serialNumbers, FileName(ui.GetFileName(
      "OVERLAPLIST")).expanded());


  // This will only occur when "CONTINUE" was true, so we can assume "ERRORS" was
  //   an entered parameter.
  if(overlaps.Errors().size() != 0 && ui.WasEntered("ERRORS")) {
    Pvl outFile;

    bool filenamesOnly = !ui.GetBoolean("DETAILED");

    vector<PvlGroup> errorList = overlaps.Errors();

    for(unsigned int err = 0; err < errorList.size(); err++) {
      if(!filenamesOnly) {
        outFile += errorList[err];
      }
      else if(errorList[err].hasKeyword("FileNames")) {
        PvlGroup origError = errorList[err];
        PvlGroup err("ImageOverlapError");

        for(int keyword = 0; keyword < origError.keywords(); keyword++) {
          if(origError[keyword].name() == "FileNames") {
            err += origError[keyword];
          }
        }

        outFile += err;
      }
    }

    outFile.write(FileName(ui.GetFileName("ERRORS")).expanded());
  }

  PvlGroup results("Results");
  results += PvlKeyword("ErrorCount", toString((BigInt)overlaps.Errors().size()));
  Application::Log(results);
}
Beispiel #25
0
void IsisMain() {

  // Get the list of cubes to mosaic

  UserInterface &ui = Application::GetUserInterface();
  FileList flist(ui.GetFileName("FROMLIST"));


  vector<Cube *> clist;
  try {
    if(flist.size() < 1) {
      QString msg = "the list file [" + ui.GetFileName("FROMLIST") +
                    "does not contain any data";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // open all the cube and place in vector clist

    for(int i = 0; i < flist.size(); i++) {
      Cube *c = new Cube();
      clist.push_back(c);
      c->open(flist[i].toString());
    }



    // run the compair function here.  This will conpair the
    // labels of the first cube to the labels of each following cube.
    PvlKeyword sourceProductId("SourceProductId");
    QString ProdId;
    for(int i = 0; i < (int)clist.size(); i++) {
      Pvl *pmatch = clist[0]->label();
      Pvl *pcomp = clist[i]->label();
      CompareLabels(*pmatch, *pcomp);
      PvlGroup g = pcomp->findGroup("Instrument", Pvl::Traverse);
      if(g.hasKeyword("StitchedProductIds")) {
        PvlKeyword k = g["StitchedProductIds"];
        for(int j = 0; j < (int)k.size(); j++) {
          sourceProductId += g["stitchedProductIds"][j];
        }
      }
      ProdId = (QString)pmatch->findGroup("Archive", Pvl::Traverse)["ObservationId"];
      QString bandname = (QString)pmatch->findGroup("BandBin", Pvl::Traverse)["Name"];
      bandname = bandname.toUpper();
      ProdId = ProdId + "_" + bandname;
    }
    bool runXY = true;

    //calculate the min and max lon
    double minLat = DBL_MAX;
    double maxLat = -DBL_MAX;
    double minLon = DBL_MAX;
    double maxLon = -DBL_MAX;
    double avgLat;
    double avgLon;
    for(int i = 0; i < (int)clist.size(); i++) {
      TProjection *proj = (TProjection *) clist[i]->projection();
      if(proj->MinimumLatitude() < minLat) minLat = proj->MinimumLatitude();
      if(proj->MaximumLatitude() > maxLat) maxLat = proj->MaximumLatitude();
      if(proj->MinimumLongitude() < minLon) minLon = proj->MinimumLongitude();
      if(proj->MaximumLongitude() > maxLon) maxLon = proj->MaximumLongitude();
    }
    avgLat = (minLat + maxLat) / 2;
    avgLon = (minLon + maxLon) / 2;
    TProjection *proj = (TProjection *) clist[0]->projection();
    proj->SetGround(avgLat, avgLon);
    avgLat = proj->UniversalLatitude();
    avgLon = proj->UniversalLongitude();

    // Use camera class to get Inc., emi., phase, and other values
    double Cemiss;
    double Cphase;
    double Cincid;
    double ClocalSolTime;
    double CsolarLong;
    double CsunAzimuth;
    double CnorthAzimuth;
    for(int i = 0; i < (int)clist.size(); i++) {
      Camera *cam = clist[i]->camera();
      if(cam->SetUniversalGround(avgLat, avgLon)) {
        Cemiss = cam->EmissionAngle();
        Cphase = cam->PhaseAngle();
        Cincid = cam->IncidenceAngle();
        ClocalSolTime = cam->LocalSolarTime();
        CsolarLong = cam->solarLongitude().degrees();
        CsunAzimuth = cam->SunAzimuth();
        CnorthAzimuth = cam->NorthAzimuth();
        runXY = false;
        break;
      }
    }

    //The code within the if runXY was added in 10/07 to find an intersect with
    //pole images that would fail when using projection set universal ground.
    // This is run if no intersect is found when using lat and lon in
    // projection space.
    if(runXY) {
      double startX = DBL_MAX;
      double endX = DBL_MIN;
      double startY = DBL_MAX;
      double endY =  DBL_MIN;
      for(int i = 0; i < (int)clist.size(); i++) {
        TProjection *proj = (TProjection *) clist[i]->projection();
        proj->SetWorld(0.5, 0.5);
        if(i == 0) {
          startX = proj->XCoord();
          endY = proj->YCoord();
        }
        else {
          if(proj->XCoord() < startX) startX =  proj->XCoord();
          if(proj->YCoord() > endY) endY = proj->YCoord();
        }
        Pvl *p = clist[i]->label();
        double nlines = p->findGroup("Dimensions", Pvl::Traverse)["Lines"];
        double nsamps = p->findGroup("Dimensions", Pvl::Traverse)["Samples"];

        proj->SetWorld((nsamps + 0.5), (nlines + 0.5));
        if(i == 0) {
          endX = proj->XCoord();
          startY = proj->YCoord();
        }
        else {
          if(proj->XCoord() > endX) endX =  proj->XCoord();
          if(proj->YCoord() < startY) startY = proj->YCoord();
        }
      }

      double avgX = (startX + endX) / 2;
      double avgY = (startY + endY) / 2;
      double sample = proj->ToWorldX(avgX);
      double line = proj->ToWorldY(avgY);

      for(int i = 0; i < (int)clist.size(); i++) {
        Camera *cam = clist[i]->camera();
        if(cam->SetImage(sample, line)) {
          Cemiss = cam->EmissionAngle();
          Cphase = cam->PhaseAngle();
          Cincid = cam->IncidenceAngle();
          ClocalSolTime = cam->LocalSolarTime();
          CsolarLong = cam->solarLongitude().degrees();
          CsunAzimuth = cam->SunAzimuth();
          CnorthAzimuth = cam->NorthAzimuth();
          runXY = false;
          break;
        }
      }
    }
    if(runXY) {
      QString msg = "Camera did not intersect images to gather stats";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // get the min and max SCLK values ( do this with QString comp.)
    // get the value from the original label blob
    QString startClock;
    QString stopClock;
    QString startTime;
    QString stopTime;
    for(int i = 0; i < (int)clist.size(); i++) {
      OriginalLabel origLab;
      clist[i]->read(origLab);
      PvlGroup timegrp = origLab.ReturnLabels().findGroup("TIME_PARAMETERS", Pvl::Traverse);
      if(i == 0) {
        startClock = (QString)timegrp["SpacecraftClockStartCount"];
        stopClock = (QString)timegrp["SpacecraftClockStopCount"];
        startTime = (QString)timegrp["StartTime"];
        stopTime = (QString)timegrp["StopTime"];
      }
      else {
        QString testStartTime = (QString)timegrp["StartTime"];
        QString testStopTime = (QString)timegrp["StopTime"];
        if(testStartTime < startTime) {
          startTime = testStartTime;
          startClock = (QString)timegrp["SpacecraftClockStartCount"];
        }
        if(testStopTime > stopTime) {
          stopTime = testStopTime;
          stopClock = (QString)timegrp["spacecraftClockStopCount"];
        }
      }
    }

    //  Concatenate all TDI's and summing and specialProcessingFlat into one keyword
    PvlKeyword cpmmTdiFlag("cpmmTdiFlag");
    PvlKeyword cpmmSummingFlag("cpmmSummingFlag");
    PvlKeyword specialProcessingFlag("SpecialProcessingFlag");
    for(int i = 0; i < 14; i++) {
      cpmmTdiFlag += (QString)"";
      cpmmSummingFlag += (QString)"";
      specialProcessingFlag += (QString)"";
    }

    for(int i = 0; i < (int)clist.size(); i++) {
      Pvl *clab = clist[i]->label();
      PvlGroup cInst = clab->findGroup("Instrument", Pvl::Traverse);
      OriginalLabel cOrgLab;
      clist[i]->read(cOrgLab);
      PvlGroup cGrp = cOrgLab.ReturnLabels().findGroup("INSTRUMENT_SETTING_PARAMETERS", Pvl::Traverse);
      cpmmTdiFlag[(int)cInst["CpmmNumber"]] = (QString) cGrp["MRO:TDI"];
      cpmmSummingFlag[(int)cInst["CpmmNumber"]] = (QString) cGrp["MRO:BINNING"];

      if(cInst.hasKeyword("Special_Processing_Flag")) {
        specialProcessingFlag[cInst["CpmmNumber"]] = (QString) cInst["Special_Processing_Flag"];
      }
      else {
        // there may not be the keyword Special_Processing_Flag if no
        //keyword then set the output to NOMINAL
        specialProcessingFlag[cInst["CpmmNumber"]] = "NOMINAL";
      }
    }


    // Get the blob of original labels from first image in list
    OriginalLabel org;
    clist[0]->read(org);

    //close all cubes
    for(int i = 0; i < (int)clist.size(); i++) {
      clist[i]->close();
      delete clist[i];
    }
    clist.clear();

    // automos step
    QString list = ui.GetFileName("FROMLIST");
    QString toMosaic = ui.GetFileName("TO");
    QString MosaicPriority = ui.GetString("PRIORITY");

    QString parameters = "FROMLIST=" + list + " MOSAIC=" + toMosaic + " PRIORITY=" + MosaicPriority;
    ProgramLauncher::RunIsisProgram("automos", parameters);

    // write out new information to new group mosaic

    PvlGroup mos("Mosaic");
    mos += PvlKeyword("ProductId ", ProdId);
    mos += PvlKeyword(sourceProductId);
    mos += PvlKeyword("StartTime ", startTime);
    mos += PvlKeyword("SpacecraftClockStartCount ", startClock);
    mos += PvlKeyword("StopTime ", stopTime);
    mos += PvlKeyword("SpacecraftClockStopCount ", stopClock);
    mos += PvlKeyword("IncidenceAngle ", toString(Cincid), "DEG");
    mos += PvlKeyword("EmissionAngle ", toString(Cemiss), "DEG");
    mos += PvlKeyword("PhaseAngle ", toString(Cphase), "DEG");
    mos += PvlKeyword("LocalTime ", toString(ClocalSolTime), "LOCALDAY/24");
    mos += PvlKeyword("SolarLongitude ", toString(CsolarLong), "DEG");
    mos += PvlKeyword("SubSolarAzimuth ", toString(CsunAzimuth), "DEG");
    mos += PvlKeyword("NorthAzimuth ", toString(CnorthAzimuth), "DEG");
    mos += cpmmTdiFlag;
    mos += cpmmSummingFlag;
    mos += specialProcessingFlag;

    Cube mosCube;
    mosCube.open(ui.GetFileName("TO"), "rw");
    PvlObject &lab = mosCube.label()->findObject("IsisCube");
    lab.addGroup(mos);
    //add orginal label blob to the output cube
    mosCube.write(org);
    mosCube.close();

  }
  catch(IException &e) {
    for(int i = 0; i < (int)clist.size(); i++) {
      clist[i]->close();
      delete clist[i];
    }
    QString msg = "The mosaic [" + ui.GetFileName("TO") + "] was NOT created";
    throw IException(IException::User, msg, _FILEINFO_);
  }
} // end of isis main
Beispiel #26
0
void IsisMain() {

  // Create a process so we can output the noproj'd labels without overwriting
  Process p;

  // Open the user interface and get the input file and the ideal specs file
  UserInterface &ui = Application::GetUserInterface();
  Cube *mcube, *icube;

  // If a MATCH cube is entered, make sure to SetInputCube it first to get the SPICE blobs
  // from it propagated to the TO labels

  // Until polygon blobs are detached without "/" don't propagate them
  p.PropagatePolygons(false);

  if((ui.WasEntered("MATCH"))) {
    mcube = p.SetInputCube("MATCH");
    icube = p.SetInputCube("FROM");
  }
  else {
    mcube = icube = p.SetInputCube("FROM");
  }

  Camera *incam = mcube->camera();

  // Extract Instrument groups from input labels for the output match and noproj'd cubes
  PvlGroup inst = mcube->group("Instrument");
  PvlGroup fromInst = icube->group("Instrument");
  QString groupName = (QString) inst["SpacecraftName"] + "/";
  groupName += (QString) inst.findKeyword("InstrumentId");

  // Get Ideal camera specifications
  FileName specs;
  if((ui.WasEntered("SPECS"))) {
    specs = ui.GetFileName("SPECS");
  }
  else {
    specs = "$base/applications/noprojInstruments???.pvl";
    specs = specs.highestVersion();
  }
  Pvl idealSpecs(specs.expanded());
  PvlObject obSpecs = idealSpecs.findObject("IdealInstrumentsSpecifications");

  PvlGroup idealGp = obSpecs.findGroup(groupName);
  double transx, transy, transl, transs;
  transx = transy = transl = transs = 0.;
  if(idealGp.hasKeyword("TransX")) transx = idealGp["TransX"];
  if(idealGp.hasKeyword("TransY")) transy = idealGp["TransY"];
  if(idealGp.hasKeyword("ItransL")) transl = idealGp["ItransL"];
  if(idealGp.hasKeyword("ItransS")) transs = idealGp["ItransS"];
  int detectorSamples = mcube->sampleCount();
  if(idealGp.hasKeyword("DetectorSamples")) detectorSamples = idealGp["DetectorSamples"];
  int numberLines = mcube->lineCount();
  int numberBands = mcube->bandCount();

  if(idealGp.hasKeyword("DetectorLines")) numberLines = idealGp["DetectorLines"];

  int xDepend = incam->FocalPlaneMap()->FocalPlaneXDependency();

  // Get output summing mode
  if(ui.GetString("SOURCE") == "FROMMATCH") {
    LoadMatchSummingMode();
  }
  else if(ui.GetString("SOURCE") == "FROMINPUT") {
    LoadInputSummingMode();
  }

  double pixPitch = incam->PixelPitch() * ui.GetDouble("SUMMINGMODE");
  detectorSamples /= (int)(ui.GetDouble("SUMMINGMODE"));
  // Get the user options
  int sampleExpansion = int((ui.GetDouble("SAMPEXP") / 100.) * detectorSamples + .5);
  int lineExpansion = int((ui.GetDouble("LINEEXP") / 100.) * numberLines + .5);
  QString instType;

  // Adjust translations for summing mode
  transl /= ui.GetDouble("SUMMINGMODE");
  transs /= ui.GetDouble("SUMMINGMODE");

  detectorSamples += sampleExpansion;
  numberLines += lineExpansion;

  // Determine whether this ideal camera is a line scan or framing camera and
  // set the instrument id and exposure
  int detectorLines;
  int expandFlag;

  if(incam->DetectorMap()->LineRate() != 0.0) {
    instType = "LINESCAN";
    // Isis3 line rate is always in seconds so convert to milliseconds for the
    // Ideal instrument
    detectorLines = 1;
    expandFlag = 1;
  }
  else {
    instType = "FRAMING";
    detectorLines = numberLines;
    expandFlag = 0;
    // Framing cameras don't need exposure time
  }

  // Adjust focal plane translations with line expansion for scanners since
  // the CCD is only 1 line
  if(expandFlag) {
    transl += lineExpansion / 2;

    if(xDepend == CameraFocalPlaneMap::Line) {
      transx -= lineExpansion / 2.*pixPitch * expandFlag;
    }
    else {
      transy -= lineExpansion / 2.*pixPitch * expandFlag;
    }
  }

  // Get the start time for parent line 1
  AlphaCube alpha(*icube);
  double sample = alpha.BetaSample(.5);
  double line = alpha.BetaLine(.5);
  incam->SetImage(sample, line);
  double et = incam->time().Et();

  // Get the output file name and set its attributes
  CubeAttributeOutput cao;

  // Can we do a regular label? Didn't work on 12-15-2006
  cao.setLabelAttachment(Isis::DetachedLabel);

  // Determine the output image size from
  //   1) the idealInstrument pvl if there or
  //   2) the input size expanded by user specified percentage
  Cube *ocube = p.SetOutputCube("match.cub", cao, 1, 1, 1);

  // Extract the times and the target from the instrument group
  QString startTime = inst["StartTime"];
  QString stopTime;
  if(inst.hasKeyword("StopTime")) stopTime = (QString) inst["StopTime"];

  QString target = inst["TargetName"];

  // rename the instrument groups
  inst.setName("OriginalInstrument");
  fromInst.setName("OriginalInstrument");

  // add it back to the IsisCube object under a new group name
  ocube->putGroup(inst);

  // and remove the version from the IsisCube Object
  ocube->deleteGroup("Instrument");

  // Now rename the group back to the Instrument group and clear out old keywords
  inst.setName("Instrument");
  inst.clear();

  // Add keywords for the "Ideal" instrument
  Isis::PvlKeyword key("SpacecraftName", "IdealSpacecraft");
  inst.addKeyword(key);

  key.setName("InstrumentId");
  key.setValue("IdealCamera");
  inst.addKeyword(key);

  key.setName("TargetName");
  key.setValue(target);
  inst.addKeyword(key);

  key.setName("SampleDetectors");
  key.setValue(Isis::toString(detectorSamples));
  inst.addKeyword(key);

  key.setName("LineDetectors");
  key.setValue(Isis::toString(detectorLines));
  inst.addKeyword(key);

  key.setName("InstrumentType");
  key.setValue(instType);
  inst.addKeyword(key);

  Pvl &ocubeLabel = *ocube->label();
  PvlObject *naifKeywordsObject = NULL;

  if (ocubeLabel.hasObject("NaifKeywords")) {
    naifKeywordsObject = &ocubeLabel.findObject("NaifKeywords");

    // Clean up the naif keywords object... delete everything that isn't a radii
    for (int keyIndex = naifKeywordsObject->keywords() - 1; keyIndex >= 0; keyIndex--) {
      QString keyName = (*naifKeywordsObject)[keyIndex].name();
      
      if (!keyName.contains("RADII")) {
        naifKeywordsObject->deleteKeyword(keyIndex);
      }
    }

    // Clean up the kernels group... delete everything that isn't internalized or the orig frame
    //   code
    PvlGroup &kernelsGroup = ocube->group("Kernels");
    for (int keyIndex = kernelsGroup.keywords() - 1; keyIndex >= 0; keyIndex--) {
      PvlKeyword &kernelsKeyword = kernelsGroup[keyIndex];

      bool isTable = false;
      bool isFrameCode = kernelsKeyword.isNamed("NaifFrameCode") ||
                         kernelsKeyword.isNamed("NaifIkCode");
      bool isShapeModel = kernelsKeyword.isNamed("ShapeModel");

      for (int keyValueIndex = 0; keyValueIndex < kernelsKeyword.size(); keyValueIndex++) {
        if (kernelsKeyword[keyValueIndex] == "Table") {
          isTable = true;
        }
      }

      if (!isTable && !isFrameCode && !isShapeModel) {
        kernelsGroup.deleteKeyword(keyIndex);
      }
    }
  }

  if (naifKeywordsObject) {
    naifKeywordsObject->addKeyword(PvlKeyword("IDEAL_FOCAL_LENGTH", toString(incam->FocalLength())),
                                   Pvl::Replace);
  }
  else {
    inst.addKeyword(PvlKeyword("FocalLength", toString(incam->FocalLength()), "millimeters"));
  }

  double newPixelPitch = incam->PixelPitch() * ui.GetDouble("SUMMINGMODE");
  if (naifKeywordsObject) {
    naifKeywordsObject->addKeyword(PvlKeyword("IDEAL_PIXEL_PITCH", toString(newPixelPitch)),
                                   Pvl::Replace);
  }
  else {
    inst.addKeyword(PvlKeyword("PixelPitch", toString(newPixelPitch), "millimeters"));
  }

  key.setName("EphemerisTime");
  key.setValue(Isis::toString(et), "seconds");
  inst.addKeyword(key);

  key.setName("StartTime");
  key.setValue(startTime);
  inst.addKeyword(key);

  if(stopTime != "") {
    key.setName("StopTime");
    key.setValue(stopTime);
    inst.addKeyword(key);
  }

  key.setName("FocalPlaneXDependency");
  key.setValue(toString((int)incam->FocalPlaneMap()->FocalPlaneXDependency()));
  inst.addKeyword(key);

  int xDependency = incam->FocalPlaneMap()->FocalPlaneXDependency();

  double newInstrumentTransX = incam->FocalPlaneMap()->SignMostSigX();
  inst.addKeyword(PvlKeyword("TransX", toString(newInstrumentTransX)));

  double newInstrumentTransY = incam->FocalPlaneMap()->SignMostSigY();
  inst.addKeyword(PvlKeyword("TransY", toString(newInstrumentTransY)));

  storeSpice(&inst, naifKeywordsObject, "TransX0", "IDEAL_TRANSX", transx,
             newPixelPitch * newInstrumentTransX, (xDependency == CameraFocalPlaneMap::Sample));

  storeSpice(&inst, naifKeywordsObject, "TransY0", "IDEAL_TRANSY", transy,
             newPixelPitch * newInstrumentTransY, (xDependency == CameraFocalPlaneMap::Line));

  double transSXCoefficient = 1.0 / newPixelPitch * newInstrumentTransX;
  double transLXCoefficient = 1.0 / newPixelPitch * newInstrumentTransY;

  if (xDependency == CameraFocalPlaneMap::Line) {
    swap(transSXCoefficient, transLXCoefficient);
  }

  storeSpice(&inst, naifKeywordsObject, "TransS0", "IDEAL_TRANSS",
             transs, transSXCoefficient, (xDependency == CameraFocalPlaneMap::Sample));
  storeSpice(&inst, naifKeywordsObject, "TransL0", "IDEAL_TRANSL",
             transl, transLXCoefficient, (xDependency == CameraFocalPlaneMap::Line));

  if(instType == "LINESCAN") {
    key.setName("ExposureDuration");
    key.setValue(Isis::toString(incam->DetectorMap()->LineRate() * 1000.), "milliseconds");
    inst.addKeyword(key);
  }

  key.setName("MatchedCube");
  key.setValue(mcube->fileName());
  inst.addKeyword(key);

  ocube->putGroup(inst);

  p.EndProcess();

// Now adjust the label to fake the true size of the image to match without
// taking all the space it would require for the image data
  Pvl label;
  label.read("match.lbl");
  PvlGroup &dims = label.findGroup("Dimensions", Pvl::Traverse);
  dims["Lines"] = toString(numberLines);
  dims["Samples"] = toString(detectorSamples);
  dims["Bands"] = toString(numberBands);
  label.write("match.lbl");

// And run cam2cam to apply the transformation
  QString parameters;
  parameters += " FROM= " + ui.GetFileName("FROM");
  parameters += " MATCH= " + QString("match.cub");
  parameters += " TO= " + ui.GetFileName("TO");
  parameters += " INTERP=" + ui.GetString("INTERP");
  ProgramLauncher::RunIsisProgram("cam2cam", parameters);

//  Cleanup by deleting the match files
  remove("match.History.IsisCube");
  remove("match.lbl");
  remove("match.cub");
  remove("match.OriginalLabel.IsisCube");
  remove("match.Table.BodyRotation");
  remove("match.Table.HiRISE Ancillary");
  remove("match.Table.HiRISE Calibration Ancillary");
  remove("match.Table.HiRISE Calibration Image");
  remove("match.Table.InstrumentPointing");
  remove("match.Table.InstrumentPosition");
  remove("match.Table.SunPosition");

// Finally finish by adding the OriginalInstrument group to the TO cube
  Cube toCube;
  toCube.open(ui.GetFileName("TO"), "rw");
// Extract label and create cube object
  Pvl *toLabel = toCube.label();
  PvlObject &o = toLabel->findObject("IsisCube");
  o.deleteGroup("OriginalInstrument");
  o.addGroup(fromInst);
  toCube.close();
}
Beispiel #27
0
void IsisMain() {
  UserInterface &ui = Application::GetUserInterface();
  Isis::FileName fromFile = ui.GetFileName("FROM");

  Isis::Cube inputCube;
  inputCube.open(fromFile.expanded());

  //Check to make sure we got the cube properly
  if(!inputCube.isOpen()) {
    QString msg = "Could not open FROM cube" + fromFile.expanded();
    throw IException(IException::User, msg, _FILEINFO_);
  }
  Process p;
  Cube *icube = p.SetInputCube("FROM");

  int totalSamples = icube->sampleCount();
  int totalLines   = icube->lineCount();

  Isis::LineManager lineManager(inputCube);
  lineManager.begin();

  int leftFringe, rightFringe;
  int binningMode = icube->group("Instrument")["Summing"];

  //determine the edges between which no statistics should be gathered
  leftFringe = 48 / binningMode;
  rightFringe = totalSamples - leftFringe;


  int numSections = ui.GetInteger("SECTIONS");
  if(numSections > 9) {
    QString msg = "You may have no more than 9 sections per side";
    throw IException(IException::User, msg, _FILEINFO_);
  }

  int sectionLength = 0;
  if(!ui.WasEntered("LINESIZE")) { //User didn't enter number of lines
    if(numSections == 0) {
      sectionLength = 0;
    }
    else {
      sectionLength = totalLines / numSections;
    }
  }
  else {
    sectionLength = ui.GetInteger("LINESIZE");
    if((sectionLength * numSections > totalLines) || sectionLength < 1) {
      sectionLength = totalLines / numSections;
    }
  }

  Statistics sections[numSections][2];
  Statistics leftTotal, rightTotal;
  int sectionStarts[numSections];
  sectionStarts[0] = 0;
  for(int i = 1 ; i < numSections - 1 ; i ++) {
    sectionStarts[i] = (totalLines / numSections) * i;
  }
  if(numSections > 0) {
    sectionStarts[numSections -1] = totalLines - sectionLength;
  }

  int currentSection = 0;
  Buffer leftFringeBuf(leftFringe, 1, 1, lineManager.PixelType());
  Buffer rightFringeBuf(leftFringe, 1, 1, lineManager.PixelType());

  //Walk down the cube
  for(int lineCount = 0 ; lineCount < totalLines ; lineCount++) {
    inputCube.read(lineManager);
    //Read the edges into the fringe buffers
    for(int i = 0 ; i < leftFringe ; i++) {
      leftFringeBuf[i] = lineManager[i];
    }
    for(int i = rightFringe ; i < totalSamples ; i++) {
      rightFringeBuf[i - rightFringe] = lineManager[i];
    }

    //No matter what, add the fringe buffers to the totals for that side
    leftTotal.AddData(leftFringeBuf.DoubleBuffer(), leftFringeBuf.size());
    rightTotal.AddData(rightFringeBuf.DoubleBuffer(), rightFringeBuf.size());

    if(numSections == 0) {
      continue;
    }
    //Index is not too large for this fringe section
    if(lineCount < sectionStarts[currentSection] + sectionLength) {
      //Index is not too small for this fringe section
      if(lineCount >= sectionStarts[currentSection]) {
        sections[currentSection][0].AddData(leftFringeBuf.DoubleBuffer(),
                                            leftFringeBuf.size());
        sections[currentSection][1].AddData(rightFringeBuf.DoubleBuffer(),
                                            rightFringeBuf.size());
      }
    }
    else {
      currentSection++;
      //Since sections may butt up against each other, it is possible that
      // we have to add this data to the next section.
      if(lineCount >= sectionStarts[currentSection]) {
        sections[currentSection][0].AddData(leftFringeBuf.DoubleBuffer(),
                                            leftFringeBuf.size());
        sections[currentSection][1].AddData(rightFringeBuf.DoubleBuffer(),
                                            rightFringeBuf.size());
      }
    }
  }

  // Write the results to the output file if the user specified one
  PvlObject leftSide("LeftSide"), rightSide("RightSide");
  for(int i = 0 ; i < numSections ; i++) {
    QString sectionName = "Section" + toString(i + 1);
    pvlOut(sections[i][0], //Stats to add to the left Object
           sections[i][1], //Stats to add to the right Object
           sectionName,    //Name for the new groups
           sectionStarts[i], //start line
           sectionStarts[i] + sectionLength, //end line
           &leftSide,      //Object to add left group to
           &rightSide      //Object to add right group to
          );
  }
  pvlOut(leftTotal,   //Stats to add to the left Object
         rightTotal,  //Stats to add to the right Object
         "Total",     //Name for the new groups
         0,           //start line
         totalLines,  //end line
         &leftSide,   //Object to add left group to
         &rightSide   //Object to add right group to
        );
  Pvl outputPvl;
  PvlGroup sourceInfo("SourceInfo");

  sourceInfo += PvlKeyword("From", fromFile.expanded());
  sourceInfo += icube->group("Archive")["ProductId"];
  outputPvl.addGroup(sourceInfo);
  if(numSections > 0) {
    outputPvl.addObject(leftSide);
    outputPvl.addObject(rightSide);
  }
  else {
    PvlGroup leftGroup = leftSide.findGroup("Total");
    PvlGroup rightGroup = rightSide.findGroup("Total");
    leftGroup.setName("LeftSide");
    rightGroup.setName("RightSide");
    outputPvl.addGroup(leftGroup);
    outputPvl.addGroup(rightGroup);
  }
  outputPvl.write(ui.GetFileName("TO"));
}