Example #1
0
// Gather general statistics on a particular band of a cube
Isis::Statistics GatherStatistics(Cube &icube, const int band, 
  double sampPercent, std::string maxCubeStr) {
  // Create our progress message
  iString curCubeStr (g_imageIndex+1);
  std::string statMsg = "";
  if (icube.Bands() == 1) {
    statMsg = "Calculating Statistics for Band 1 in Cube " + curCubeStr +
      " of " + maxCubeStr;
  }
  else {
    iString curBandStr (band);
    iString maxBandStr (icube.Bands());
    statMsg = "Calculating Statistics for Band " + curBandStr + " of " +
      maxBandStr + " in Cube " + curCubeStr + " of " + maxCubeStr;
  }
  
  int linc = (int) (100.0 / sampPercent + 0.5); // Calculate our line incrementer
  
  // Make sure band is valid
  if ((band <= 0) || (band > icube.Bands())) {
    string msg = "Invalid band in method [GatherStatistics]";
    throw Isis::iException::Message(Isis::iException::Programmer,msg,_FILEINFO_);
  }
  
  // Construct a line buffer manager and a statistics object
  Isis::LineManager line (icube);
  
  
  Isis::Progress progress;
  progress.SetText(statMsg);
  
  // Calculate the number of steps for the Progress object, and add an extra
  // step if the total lines and incrementer do not divide evenly
  int maxSteps = icube.Lines() / linc;
  if (icube.Lines() % linc != 0) maxSteps += 1;
  progress.SetMaximumSteps(maxSteps);
  progress.CheckStatus();
  
  // Add data to Statistics object by line
  Isis::Statistics stats;
  int i=1;
  while (i<=icube.Lines()) {
    line.SetLine(i,band);
    icube.Read(line);
    stats.AddData (line.DoubleBuffer(), line.size());
    
    // Make sure we consider the last line
    if (i+linc > icube.Lines() && i != icube.Lines()) {
      i = icube.Lines();
      progress.AddSteps(1);
    }
    else i += linc; // Increment the current line by our incrementer  
    
    progress.CheckStatus();
  }
  
  return stats;
}
Example #2
0
/**
 * This method performs pass1 on one image. It analyzes each framelet's
 * statistics and populates the necessary global variable.
 *
 * @param progress Progress message
 * @param theCube Current cube that needs processing
 *
 * @return bool True if the file contains a valid framelet
 */
bool CheckFramelets(string progress, Cube &theCube) {
    bool foundValidFramelet = false;
    LineManager mgr(theCube);
    Progress prog;
    prog.SetText(progress);
    prog.SetMaximumSteps(theCube.Lines());
    prog.CheckStatus();

    vector<double> frameletAvgs;
    // We need to store off the framelet information, because if no good
    //   framelets were found then no data should be added to the
    //   global variable for framelets, just files.
    vector< pair<int,double> > excludedFrameletsTmp;
    Statistics frameletStats;

    for(int line = 1; line <= theCube.Lines(); line++) {
        if((line-1) % numFrameLines == 0) {
            frameletStats.Reset();
        }

        mgr.SetLine(line);
        theCube.Read(mgr);
        frameletStats.AddData(mgr.DoubleBuffer(), mgr.size());

        if((line-1) % numFrameLines == numFrameLines-1) {
            if(IsSpecial(frameletStats.StandardDeviation()) ||
                    frameletStats.StandardDeviation() > maxStdev) {
                excludedFrameletsTmp.push_back(
                    pair<int,double>((line-1)/numFrameLines, frameletStats.StandardDeviation())
                );
            }
            else {
                foundValidFramelet = true;
            }

            frameletAvgs.push_back(frameletStats.Average());
        }

        prog.CheckStatus();
    }

    inputFrameletAverages.push_back(frameletAvgs);

    if(foundValidFramelet) {
        for(unsigned int i = 0; i < excludedFrameletsTmp.size(); i++) {
            excludedFramelets.insert(pair< pair<int,int>, double>(
                                         pair<int,int>(currImage, excludedFrameletsTmp[i].first),
                                         excludedFrameletsTmp[i].second
                                     )
                                    );
        }

    }

    return foundValidFramelet;
}
Example #3
0
//Helper function to get camera resolution.
void ComputePixRes () {
  Process p;
  UserInterface &ui = Application::GetUserInterface();
  Cube *latCube = p.SetInputCube("LATCUB");
  Cube *lonCube = p.SetInputCube("LONCUB");
  Brick latBrick(1,1,1,latCube->PixelType());
  Brick lonBrick(1,1,1,lonCube->PixelType());
  latBrick.SetBasePosition(1,1,1);
  latCube->Read(latBrick);

  lonBrick.SetBasePosition(1,1,1);
  lonCube->Read(lonBrick);
      
  double a = latBrick.at(0) * PI/180.0;
  double c = lonBrick.at(0) * PI/180.0;
  
  latBrick.SetBasePosition(latCube->Samples(),latCube->Lines(),1);
  latCube->Read(latBrick);

  lonBrick.SetBasePosition(lonCube->Samples(),lonCube->Lines(),1);     
  lonCube->Read(lonBrick);

  double b = latBrick.at(0) * PI/180.0;
  double d = lonBrick.at(0) * PI/180.0;

  double angle = acos(cos(a) * cos(b) * cos(c - d) + sin(a) * sin(b));
  angle *= 180/PI;

  double pixels = sqrt(pow(latCube->Samples() -1.0, 2.0) + pow(latCube->Lines() -1.0, 2.0));

  p.EndProcess();

  ui.Clear("RESOLUTION");
  ui.PutDouble("RESOLUTION", pixels/angle);

  ui.Clear("PIXRES");
  ui.PutAsString("PIXRES","PPD");
}
Example #4
0
/** 
 * @brief Loads the contents of a BLOB from a Cube object
 * 
 * Provides the I/O interface for the Cube object.  One thing to note here
 * is that it creates a CubeInfo object from the Cube object and then calls
 * the CubeInfo load method.  Hence, this method is required as an 
 * intermediary method that cascades to the actual method that does the real
 * work.
 * 
 * @param [in] cube (Cube&) Reference to an ISIS cube file that has been
 *                         opened or created in the Cube object.
 */
void Blobber::load(Cube &cube) {
  Table tbl(getBlobName());
  cube.Read(tbl);
  TableField data = tbl[0][getFieldName()];
  if (data.IsDouble()) {
    loadDouble(tbl);
  }
  else if (data.IsInteger()) {
    loadInteger(tbl);
  }
  else {
    string msg = "Field type for " + getFieldName() + 
                 " is not double or integer";
    throw iException::Message(iException::Programmer,msg,_FILEINFO_);
  }
}
Example #5
0
void IsisMain() {
  Process p;
  Cube *icube = p.SetInputCube("FROM");

  // Setup the histogram
  UserInterface &ui = Application::GetUserInterface();
  Histogram hist(*icube,1,p.Progress());
  if (ui.WasEntered("MINIMUM")) {
    hist.SetValidRange(ui.GetDouble("MINIMUM"),ui.GetDouble("MAXIMUM"));
  }
  if (ui.WasEntered("NBINS")) {
    hist.SetBins(ui.GetInteger("NBINS"));
  }

  // Loop and accumulate histogram
  p.Progress()->SetText("Gathering Histogram");
  p.Progress()->SetMaximumSteps(icube->Lines());
  p.Progress()->CheckStatus();
  LineManager line(*icube);
  for (int i=1; i<=icube->Lines(); i++) {
    line.SetLine(i);
    icube->Read(line);
    hist.AddData(line.DoubleBuffer(),line.size());
    p.Progress()->CheckStatus();
  }

  if(!ui.IsInteractive() || ui.WasEntered("TO")) {
    // Write the results

    if (!ui.WasEntered("TO")) {
      string msg = "The [TO] parameter must be entered";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    string outfile = ui.GetFilename("TO");
    ofstream fout;
    fout.open (outfile.c_str());
   
    fout << "Cube:           " << ui.GetFilename("FROM") << endl;
    fout << "Band:           " << icube->Bands() << endl;
    fout << "Average:        " << hist.Average() << endl;
    fout << "Std Deviation:  " << hist.StandardDeviation() << endl;
    fout << "Variance:       " << hist.Variance() << endl;
    fout << "Median:         " << hist.Median() << endl;
    fout << "Mode:           " << hist.Mode() << endl;
    fout << "Skew:           " << hist.Skew() << endl;
    fout << "Minimum:        " << hist.Minimum() << endl;
    fout << "Maximum:        " << hist.Maximum() << endl;
    fout << endl;
    fout << "Total Pixels:    " << hist.TotalPixels() << endl;
    fout << "Valid Pixels:    " << hist.ValidPixels() << endl;
    fout << "Null Pixels:     " << hist.NullPixels() << endl;
    fout << "Lis Pixels:      " << hist.LisPixels() << endl;
    fout << "Lrs Pixels:      " << hist.LrsPixels() << endl;
    fout << "His Pixels:      " << hist.HisPixels() << endl;
    fout << "Hrs Pixels:      " << hist.HrsPixels() << endl;
   
    //  Write histogram in tabular format
    fout << endl;
    fout << endl;
    fout << "DN,Pixels,CumulativePixels,Percent,CumulativePercent" << endl;
   
    Isis::BigInt total = 0;
    double cumpct = 0.0;
   
    for (int i=0; i<hist.Bins(); i++) {
      if (hist.BinCount(i) > 0) {
        total += hist.BinCount(i);
        double pct = (double)hist.BinCount(i) / hist.ValidPixels() * 100.;
        cumpct += pct;
   
        fout << hist.BinMiddle(i) << ",";
        fout << hist.BinCount(i) << ",";
        fout << total << ",";
        fout << pct << ",";
        fout << cumpct << endl;
      }
    }
    fout.close();
  }
  // If we are in gui mode, create a histogram plot
  if (ui.IsInteractive()) {
    // Set the title for the dialog
    string title;
    if (ui.WasEntered("TITLE")) {
      title = ui.GetString("TITLE");
    }
    else {
      title = "Histogram Plot for " + Filename(ui.GetAsString("FROM")).Name();
    }

    // Create the QHistogram, set the title & load the Isis::Histogram into it

    Qisis::HistogramToolWindow *plot = new Qisis::HistogramToolWindow(title.c_str(), ui.TheGui());

    // Set the xaxis title if they entered one
    if (ui.WasEntered("XAXIS")) {
      string xaxis(ui.GetString("XAXIS"));
      plot->setAxisLabel(QwtPlot::xBottom,xaxis.c_str());
    }

    // Set the yLeft axis title if they entered one
    if (ui.WasEntered("Y1AXIS")) {
      string yaxis(ui.GetString("Y1AXIS"));
      plot->setAxisLabel(QwtPlot::yLeft,yaxis.c_str());
    }

    // Set the yRight axis title if they entered one
    if (ui.WasEntered("Y2AXIS")) {
      string y2axis(ui.GetString("Y2AXIS"));
      plot->setAxisLabel(QwtPlot::yRight,y2axis.c_str());
    }

    //Transfer data from histogram to the plotcurve
    std::vector<double> xarray,yarray,y2array;
    double cumpct = 0.0;
    for (int i=0; i<hist.Bins(); i++) {
      if (hist.BinCount(i) > 0) {
        xarray.push_back(hist.BinMiddle(i));
        yarray.push_back(hist.BinCount(i));

        double pct = (double)hist.BinCount(i) / hist.ValidPixels() * 100.;
        cumpct += pct;
        y2array.push_back(cumpct);
      }
    }

    Qisis::HistogramItem *histCurve = new Qisis::HistogramItem();
    histCurve->setColor(Qt::darkCyan);
    histCurve->setTitle("Frequency");

    Qisis::PlotToolCurve *cdfCurve = new Qisis::PlotToolCurve();
    cdfCurve->setStyle(QwtPlotCurve::Lines);
    cdfCurve->setTitle("Percentage");

    QPen *pen = new QPen(Qt::red);
    pen->setWidth(2);
    histCurve->setYAxis(QwtPlot::yLeft);
    cdfCurve->setYAxis(QwtPlot::yRight);
    cdfCurve->setPen(*pen);

    //These are all variables needed in the following for loop.
    //----------------------------------------------
    QwtArray<QwtDoubleInterval> intervals(xarray.size());
    QwtArray<double> values(yarray.size());
    double maxYValue = DBL_MIN;
    double minYValue = DBL_MAX;
    // --------------------------------------------- 

    for(unsigned int y = 0; y < yarray.size(); y++) {

      intervals[y] = QwtDoubleInterval(xarray[y], xarray[y] + hist.BinSize());
  
      values[y] = yarray[y];  
      if(values[y] > maxYValue) maxYValue = values[y]; 
      if(values[y] < minYValue) minYValue = values[y];
    }
    
    histCurve->setData(QwtIntervalData(intervals, values));
    cdfCurve->setData(&xarray[0],&y2array[0],xarray.size());

    plot->add(histCurve);
    plot->add(cdfCurve);
    plot->fillTable();

    plot->setScale(QwtPlot::yLeft,0,maxYValue);
    plot->setScale(QwtPlot::xBottom,hist.Minimum(),hist.Maximum());

    QLabel *label = new QLabel("  Average = " + QString::number(hist.Average()) + '\n' +
    "\n  Minimum = " + QString::number(hist.Minimum()) + '\n' +
    "\n  Maximum = " + QString::number(hist.Maximum()) + '\n' +
    "\n  Stand. Dev.= " + QString::number(hist.StandardDeviation()) + '\n' +
    "\n  Variance = " + QString::number(hist.Variance()) + '\n' +
    "\n  Median = " + QString::number(hist.Median()) + '\n' +
    "\n  Mode = " + QString::number(hist.Mode()) +'\n' +
    "\n  Skew = " + QString::number(hist.Skew()), plot);
    plot->getDockWidget()->setWidget(label);
 
    plot->showWindow();
  }
  p.EndProcess();
}
Example #6
0
  void Histogram::InitializeFromCube(Cube &cube, const int band, Progress *progress) {
    // Make sure band is valid
    if ((band < 0) || (band > cube.Bands())) {
      string msg = "Invalid band in [Histogram constructor]";
      throw Isis::iException::Message(Isis::iException::Programmer,msg,_FILEINFO_);
    }

    double min,max;
    int nbins;

    if (cube.PixelType() == Isis::UnsignedByte) {
      min = 0.0 * cube.Multiplier() + cube.Base();
      max = 255.0 * cube.Multiplier() + cube.Base();
      nbins = 256;
    }
    else if (cube.PixelType() == Isis::SignedWord) {
      min = -32768.0 * cube.Multiplier() + cube.Base();
      max = 32767.0 * cube.Multiplier() + cube.Base();
      nbins = 65536;
    }
    else if (cube.PixelType() == Isis::Real) {
      // Determine the band for statistics
      int bandStart = band;
      int bandStop = band;
      int maxSteps = cube.Lines();
      if (band == 0){
        bandStart = 1;
        bandStop = cube.Bands();
        maxSteps = cube.Lines() * cube.Bands();
      }

      // Construct a line buffer manager and a statistics object
      LineManager line(cube);
      Statistics stats = Statistics();

      // Prep for reporting progress if necessary
      if (progress != NULL) {
        string save = progress->Text ();
        progress->SetText("Computing min/max for histogram");
        progress->SetMaximumSteps(maxSteps);
        progress->CheckStatus();
      }

      for (int useBand = bandStart ; useBand <= bandStop ; useBand++){
        // Loop and get the statistics for a good minimum/maximum
        for (int i=1; i<=cube.Lines(); i++) {
          line.SetLine(i,useBand);
          cube.Read(line);
          stats.AddData (line.DoubleBuffer(),line.size());
          if (progress != NULL) progress->CheckStatus();
        }
      }

      // Get the min/max for constructing a histogram object
      if (stats.ValidPixels() == 0) {
        min = 0.0;
        max = 1.0;
      }
      else {
        min = stats.BestMinimum ();
        max = stats.BestMaximum ();
      }

      nbins = 65536;
    }
    else {
      std::string msg = "Unsupported pixel type";
      throw iException::Message(Isis::iException::Programmer,msg,_FILEINFO_);
    }

    // Set the bins and range
    SetBinRange(min,max);
    SetBins(nbins);
  }
Example #7
0
void IsisMain() {
  //Create a process to create the input cubes
  Process p;
  //Create the input cubes, matching sample/lines
  Cube *inCube = p.SetInputCube ("FROM");
  Cube *latCube = p.SetInputCube("LATCUB", SpatialMatch);
  Cube *lonCube = p.SetInputCube("LONCUB", SpatialMatch);

  //A 1x1 brick to read in the latitude and longitude DN values from
  //the specified cubes
  Brick latBrick(1,1,1, latCube->PixelType());
  Brick lonBrick(1,1,1, lonCube->PixelType());

  UserInterface &ui = Application::GetUserInterface();

  //Set the sample and line increments
  int sinc = (int)(inCube->Samples() * 0.10);
  if(ui.WasEntered("SINC")) {
    sinc = ui.GetInteger("SINC");
  }

  int linc = (int)(inCube->Lines() * 0.10);
  if(ui.WasEntered("LINC")) {
    linc = ui.GetInteger("LINC");
  }

  //Set the degree of the polynomial to use in our functions
  int degree = ui.GetInteger("DEGREE");

  //We are using a polynomial with two variables
  PolynomialBivariate sampFunct(degree); 
  PolynomialBivariate lineFunct(degree);

  //We will be solving the function using the least squares method
  LeastSquares sampSol(sampFunct);
  LeastSquares lineSol(lineFunct);

  //Setup the variables for solving the stereographic projection
  //x = cos(latitude) * sin(longitude - lon_center)
  //y = cos(lat_center) * sin(latitude) - sin(lat_center) * cos(latitude) * cos(longitude - lon_center)

  //Get the center lat and long from the input cubes
  double lat_center = latCube->Statistics()->Average() * PI/180.0;
  double lon_center = lonCube->Statistics()->Average() * PI/180.0;


  /**
   * Loop through lines and samples projecting the latitude and longitude at those
   * points to stereographic x and y and adding these points to the LeastSquares 
   * matrix. 
   */
  for(int i = 1; i <= inCube->Lines(); i+= linc) {
    for(int j = 1; j <= inCube->Samples(); j+= sinc) {
      latBrick.SetBasePosition(j, i, 1);
      latCube->Read(latBrick);
      if(IsSpecial(latBrick.at(0))) continue;
      double lat = latBrick.at(0) * PI/180.0;
      lonBrick.SetBasePosition(j, i, 1);
      lonCube->Read(lonBrick);
      if(IsSpecial(lonBrick.at(0))) continue;
      double lon = lonBrick.at(0) * PI/180.0;

      //Project lat and lon to x and y using a stereographic projection
      double k = 2/(1 + sin(lat_center) * sin(lat) + cos(lat_center)*cos(lat)*cos(lon - lon_center));
      double x = k * cos(lat) * sin(lon - lon_center);
      double y = k * (cos(lat_center) * sin(lat)) - (sin(lat_center) * cos(lat) * cos(lon - lon_center));

      //Add x and y to the least squares matrix
      vector<double> data;
      data.push_back(x);
      data.push_back(y);
      sampSol.AddKnown(data, j);
      lineSol.AddKnown(data, i);

      //If the sample increment goes past the last sample in the line, we want to
      //always read the last sample..
      if(j != inCube->Samples() && j + sinc > inCube->Samples()) {
        j = inCube->Samples() - sinc;
      }
    }
    //If the line increment goes past the last line in the cube, we want to
    //always read the last line..
    if(i != inCube->Lines() && i + linc > inCube->Lines()) {    
      i = inCube->Lines() - linc;
    }
  }

  //Solve the least squares functions using QR Decomposition
  sampSol.Solve(LeastSquares::QRD);
  lineSol.Solve(LeastSquares::QRD);

  //If the user wants to save the residuals to a file, create a file and write
  //the column titles to it.
  TextFile oFile;
  if(ui.WasEntered("RESIDUALS")) {
    oFile.Open(ui.GetFilename("RESIDUALS"), "overwrite");
    oFile.PutLine("Sample,\tLine,\tX,\tY,\tSample Error,\tLine Error\n");
  }

  //Gather the statistics for the residuals from the least squares solutions
  Statistics sampErr;
  Statistics lineErr;
  vector<double> sampResiduals = sampSol.Residuals();
  vector<double> lineResiduals = lineSol.Residuals();
  for(int i = 0; i < (int)sampResiduals.size(); i++) {
    sampErr.AddData(sampResiduals[i]);
    lineErr.AddData(lineResiduals[i]);
  }

  //If a residuals file was specified, write the previous data, and the errors to the file.
  if(ui.WasEntered("RESIDUALS")) {
    for(int i = 0; i < sampSol.Rows(); i++) {
      vector<double> data = sampSol.GetInput(i);
      iString tmp = "";
      tmp += iString(sampSol.GetExpected(i));
      tmp += ",\t";
      tmp += iString(lineSol.GetExpected(i));
      tmp += ",\t";
      tmp += iString(data[0]);
      tmp += ",\t";
      tmp += iString(data[1]);
      tmp += ",\t";
      tmp += iString(sampResiduals[i]);
      tmp += ",\t";
      tmp += iString(lineResiduals[i]);
      oFile.PutLine(tmp + "\n");
    }
  }
  oFile.Close();

  //Records the error to the log
  PvlGroup error( "Error" );
  error += PvlKeyword( "Degree", degree );
  error += PvlKeyword( "NumberOfPoints", (int)sampResiduals.size() );
  error += PvlKeyword( "SampleMinimumError", sampErr.Minimum() );
  error += PvlKeyword( "SampleAverageError", sampErr.Average() );
  error += PvlKeyword( "SampleMaximumError", sampErr.Maximum() );
  error += PvlKeyword( "SampleStdDeviationError", sampErr.StandardDeviation() );
  error += PvlKeyword( "LineMinimumError", lineErr.Minimum() );
  error += PvlKeyword( "LineAverageError", lineErr.Average() );
  error += PvlKeyword( "LineMaximumError", lineErr.Maximum() );
  error += PvlKeyword( "LineStdDeviationError", lineErr.StandardDeviation() );
  Application::Log( error );

  //Close the input cubes for cleanup
  p.EndProcess();

  //If we want to warp the image, then continue, otherwise return
  if(!ui.GetBoolean("NOWARP")) {
    //Creates the mapping group
    Pvl mapFile;
    mapFile.Read(ui.GetFilename("MAP"));
    PvlGroup &mapGrp = mapFile.FindGroup("Mapping",Pvl::Traverse);

    //Reopen the lat and long cubes
    latCube = new Cube();
    latCube->SetVirtualBands(ui.GetInputAttribute("LATCUB").Bands());
    latCube->Open(ui.GetFilename("LATCUB"));

    lonCube = new Cube();
    lonCube->SetVirtualBands(ui.GetInputAttribute("LONCUB").Bands());
    lonCube->Open(ui.GetFilename("LONCUB"));

    PvlKeyword targetName;

    //If the user entered the target name
    if(ui.WasEntered("TARGET")) {
      targetName = PvlKeyword("TargetName", ui.GetString("TARGET"));
    }
    //Else read the target name from the input cube
    else {
      Pvl fromFile;
      fromFile.Read(ui.GetFilename("FROM"));
      targetName = fromFile.FindKeyword("TargetName", Pvl::Traverse);
    }

    mapGrp.AddKeyword(targetName, Pvl::Replace);

    PvlKeyword equRadius;
    PvlKeyword polRadius;


    //If the user entered the equatorial and polar radii
    if(ui.WasEntered("EQURADIUS") && ui.WasEntered("POLRADIUS")) {
      equRadius = PvlKeyword("EquatorialRadius", ui.GetDouble("EQURADIUS"));
      polRadius = PvlKeyword("PolarRadius", ui.GetDouble("POLRADIUS"));
    }
    //Else read them from the pck
    else {
      Filename pckFile("$base/kernels/pck/pck?????.tpc");
      pckFile.HighestVersion();

      string pckFilename = pckFile.Expanded();

      furnsh_c(pckFilename.c_str());

      string target = targetName[0];
      SpiceInt code;
      SpiceBoolean found;

      bodn2c_c (target.c_str(), &code, &found);

      if (!found) {
        string msg = "Could not convert Target [" + target +
                     "] to NAIF code";
        throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
      }

      SpiceInt n;
      SpiceDouble radii[3];

      bodvar_c(code,"RADII",&n,radii);

      equRadius = PvlKeyword("EquatorialRadius", radii[0] * 1000);
      polRadius = PvlKeyword("PolarRadius", radii[2] * 1000);
    }

    mapGrp.AddKeyword(equRadius, Pvl::Replace);
    mapGrp.AddKeyword(polRadius, Pvl::Replace);


    //If the latitude type is not in the mapping group, copy it from the input
    if(!mapGrp.HasKeyword("LatitudeType")) {
      if(ui.GetString("LATTYPE") == "PLANETOCENTRIC") {
        mapGrp.AddKeyword(PvlKeyword("LatitudeType","Planetocentric"), Pvl::Replace);
      }
      else {
        mapGrp.AddKeyword(PvlKeyword("LatitudeType","Planetographic"), Pvl::Replace);
      }
    }

    //If the longitude direction is not in the mapping group, copy it from the input
    if(!mapGrp.HasKeyword("LongitudeDirection")) {
      if(ui.GetString("LONDIR") == "POSITIVEEAST") {
        mapGrp.AddKeyword(PvlKeyword("LongitudeDirection","PositiveEast"), Pvl::Replace);
      }
      else {
        mapGrp.AddKeyword(PvlKeyword("LongitudeDirection","PositiveWest"), Pvl::Replace);
      }
    }

    //If the longitude domain is not in the mapping group, assume it is 360
    if(!mapGrp.HasKeyword("LongitudeDomain")) {
      mapGrp.AddKeyword(PvlKeyword("LongitudeDomain","360"), Pvl::Replace);
    }

    //If the default range is to be computed, use the input lat/long cubes to determine the range
    if(ui.GetString("DEFAULTRANGE") == "COMPUTE") {
      //NOTE - When computing the min/max longitude this application does not account for the 
      //longitude seam if it exists. Since the min/max are calculated from the statistics of
      //the input longitude cube and then converted to the mapping group's domain they may be
      //invalid for cubes containing the longitude seam. 
    
      Statistics *latStats = latCube->Statistics();
      Statistics *lonStats = lonCube->Statistics();

      double minLat = latStats->Minimum();
      double maxLat = latStats->Maximum();

      bool isOcentric = ((std::string)mapGrp.FindKeyword("LatitudeType")) == "Planetocentric";
 
      if(isOcentric) {
        if(ui.GetString("LATTYPE") != "PLANETOCENTRIC") {
          minLat = Projection::ToPlanetocentric(minLat, (double)equRadius, (double)polRadius);
          maxLat = Projection::ToPlanetocentric(maxLat, (double)equRadius, (double)polRadius);
        }
      }
      else {
        if(ui.GetString("LATTYPE") == "PLANETOCENTRIC") {
          minLat = Projection::ToPlanetographic(minLat, (double)equRadius, (double)polRadius);
          maxLat = Projection::ToPlanetographic(maxLat, (double)equRadius, (double)polRadius);
        }
      }

      int lonDomain = (int)mapGrp.FindKeyword("LongitudeDomain");
      double minLon = lonDomain == 360 ? Projection::To360Domain(lonStats->Minimum()) : Projection::To180Domain(lonStats->Minimum());
      double maxLon = lonDomain == 360 ? Projection::To360Domain(lonStats->Maximum()) : Projection::To180Domain(lonStats->Maximum());

      bool isPosEast = ((std::string)mapGrp.FindKeyword("LongitudeDirection")) == "PositiveEast";
      
      if(isPosEast) {
        if(ui.GetString("LONDIR") != "POSITIVEEAST") {
          minLon = Projection::ToPositiveEast(minLon, lonDomain);
          maxLon = Projection::ToPositiveEast(maxLon, lonDomain);
        }
      }
      else {
        if(ui.GetString("LONDIR") == "POSITIVEEAST") {
          minLon = Projection::ToPositiveWest(minLon, lonDomain);
          maxLon = Projection::ToPositiveWest(maxLon, lonDomain);
        }
      }

      if(minLon > maxLon) {
        double temp = minLon;
        minLon = maxLon;
        maxLon = temp;
      }

      mapGrp.AddKeyword(PvlKeyword("MinimumLatitude", minLat),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MaximumLatitude", maxLat),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MinimumLongitude", minLon),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MaximumLongitude", maxLon),Pvl::Replace);
    }

    //If the user decided to enter a ground range then override
    if (ui.WasEntered("MINLAT")) {
      mapGrp.AddKeyword(PvlKeyword("MinimumLatitude",
                                        ui.GetDouble("MINLAT")),Pvl::Replace);
    }
  
    if (ui.WasEntered("MAXLAT")) {
      mapGrp.AddKeyword(PvlKeyword("MaximumLatitude",
                                        ui.GetDouble("MAXLAT")),Pvl::Replace);
    }

    if (ui.WasEntered("MINLON")) {
      mapGrp.AddKeyword(PvlKeyword("MinimumLongitude",
                                        ui.GetDouble("MINLON")),Pvl::Replace);
    }
  
    if (ui.WasEntered("MAXLON")) {
      mapGrp.AddKeyword(PvlKeyword("MaximumLongitude",
                                        ui.GetDouble("MAXLON")),Pvl::Replace);
    }
  
    //If the pixel resolution is to be computed, compute the pixels/degree from the input
    if (ui.GetString("PIXRES") == "COMPUTE") {
      latBrick.SetBasePosition(1,1,1);
      latCube->Read(latBrick);

      lonBrick.SetBasePosition(1,1,1);
      lonCube->Read(lonBrick);

      //Read the lat and long at the upper left corner
      double a = latBrick.at(0) * PI/180.0;
      double c = lonBrick.at(0) * PI/180.0;
  
      latBrick.SetBasePosition(latCube->Samples(),latCube->Lines(),1);
      latCube->Read(latBrick);

      lonBrick.SetBasePosition(lonCube->Samples(),lonCube->Lines(),1);     
      lonCube->Read(lonBrick);

      //Read the lat and long at the lower right corner
      double b = latBrick.at(0) * PI/180.0;
      double d = lonBrick.at(0) * PI/180.0;

      //Determine the angle between the two points
      double angle = acos(cos(a) * cos(b) * cos(c - d) + sin(a) * sin(b));
      //double angle = acos((cos(a1) * cos(b1) * cos(b2)) + (cos(a1) * sin(b1) * cos(a2) * sin(b2)) + (sin(a1) * sin(a2)));
      angle *= 180/PI;

      //Determine the number of pixels between the two points
      double pixels = sqrt(pow(latCube->Samples() -1.0, 2.0) + pow(latCube->Lines() -1.0, 2.0));

      //Add the scale in pixels/degree to the mapping group
      mapGrp.AddKeyword(PvlKeyword("Scale",
                                        pixels/angle, "pixels/degree"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("PixelResolution")) {
        mapGrp.DeleteKeyword("PixelResolution");
      }
    }


    // If the user decided to enter a resolution then override
    if (ui.GetString("PIXRES") == "MPP") {
      mapGrp.AddKeyword(PvlKeyword("PixelResolution",
                                        ui.GetDouble("RESOLUTION"), "meters/pixel"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("Scale")) {
        mapGrp.DeleteKeyword("Scale");
      }
    }
    else if (ui.GetString("PIXRES") == "PPD") {
      mapGrp.AddKeyword(PvlKeyword("Scale",
                                        ui.GetDouble("RESOLUTION"), "pixels/degree"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("PixelResolution")) {
        mapGrp.DeleteKeyword("PixelResolution");
      }
    }

    //Create a projection using the map file we created
    int samples,lines;
    Projection *outmap = ProjectionFactory::CreateForCube(mapFile,samples,lines,false);

    //Write the map file to the log
    Application::GuiLog(mapGrp);

    //Create a process rubber sheet
    ProcessRubberSheet r;

    //Set the input cube
    inCube = r.SetInputCube("FROM");

    double tolerance = ui.GetDouble("TOLERANCE") * outmap->Resolution();

    //Create a new transform object
    Transform *transform = new nocam2map (sampSol, lineSol, outmap,
                                          latCube, lonCube,
                                          ui.GetString("LATTYPE") == "PLANETOCENTRIC",
                                          ui.GetString("LONDIR") == "POSITIVEEAST",
                                          tolerance, ui.GetInteger("ITERATIONS"),
                                          inCube->Samples(), inCube->Lines(),
                                          samples, lines);
  
    //Allocate the output cube and add the mapping labels
    Cube *oCube = r.SetOutputCube ("TO", transform->OutputSamples(),
                                              transform->OutputLines(),
                                              inCube->Bands());
    oCube->PutGroup(mapGrp);

    //Determine which interpolation to use
    Interpolator *interp = NULL;
    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);
    }
  
    //Warp the cube
    r.StartProcess(*transform, *interp);
    r.EndProcess();

    // add mapping to print.prt
    PvlGroup mapping = outmap->Mapping(); 
    Application::Log(mapping); 

    //Clean up
    delete latCube;
    delete lonCube;

    delete outmap;
    delete transform;
    delete interp;
  }
}
Example #8
0
void IsisMain () 
{
	UserInterface &ui = Application::GetUserInterface();
    Filename inFile = ui.GetFilename("FROM");

	// Set the processing object
	ProcessExportMiniRFLroPds cProcess;

	// Setup the input cube
	Cube *cInCube = cProcess.SetInputCube("FROM");	
	Pvl * cInLabel =  cInCube->Label();

	// Get the output label file
	Filename outFile(ui.GetFilename("TO", "lbl"));
	string outFilename(outFile.Expanded());

	cProcess.SetDetached  (true, outFilename);	

	cProcess.SetExportType ( ProcessExportPds::Fixed );

	//Set the resolution to  Kilometers  
	cProcess.SetPdsResolution( ProcessExportPds::Kilometer );	
	
	// 32bit
	cProcess.SetOutputType(Isis::Real);
    cProcess.SetOutputNull(Isis::NULL4);
    cProcess.SetOutputLrs(Isis::LOW_REPR_SAT4);
    cProcess.SetOutputLis(Isis::LOW_INSTR_SAT4);
    cProcess.SetOutputHrs(Isis::HIGH_REPR_SAT4);
    cProcess.SetOutputHis(Isis::HIGH_INSTR_SAT4);
	cProcess.SetOutputRange(-DBL_MAX, DBL_MAX);

	cProcess.SetOutputEndian(Isis::Msb);

	// Turn off Keywords
	cProcess.ForceScalingFactor(false);
    cProcess.ForceSampleBitMask(false);
    cProcess.ForceCoreNull     (false);
    cProcess.ForceCoreLrs      (false);
    cProcess.ForceCoreLis      (false);
    cProcess.ForceCoreHrs      (false);
    cProcess.ForceCoreHis      (false);	

	// Standard label Translation
	Pvl &pdsLabel = cProcess.StandardPdsLabel( ProcessExportPds::Image); 	

	// bLevel => Level 2 = True, Level 3 = False
	bool bLevel2 = cInCube->HasGroup("Instrument");

	// Translate the keywords from the original EDR PDS label that go in 
    // this RDR PDS label for Level2 images only
	if (bLevel2) {
		OriginalLabel cOriginalBlob;
		cInCube->Read(cOriginalBlob);
		Pvl cOrigLabel;
		PvlObject cOrigLabelObj = cOriginalBlob.ReturnLabels();
		cOrigLabelObj.SetName("OriginalLabelObject");
		cOrigLabel.AddObject(cOrigLabelObj);
	   
		// Translates the ISIS labels along with the original EDR labels
		cOrigLabel.AddObject( *(cInCube->Label()) );
		PvlTranslationManager cCubeLabel2(cOrigLabel, "$lro/translations/mrfExportOrigLabel.trn");
		cCubeLabel2.Auto(pdsLabel);	

		
		if (cInLabel->FindObject("IsisCube").FindGroup("Instrument").HasKeyword("MissionName")) {
			PvlKeyword & cKeyMissionName = cInLabel->FindObject("IsisCube").FindGroup("Instrument").FindKeyword("MissionName");			
			size_t sFound = cKeyMissionName[0].find("CHANDRAYAAN");
			if (sFound != string::npos ) {
				cCubeLabel2 = PvlTranslationManager(cOrigLabel, "$lro/translations/mrfExportOrigLabelCH1.trn");
				cCubeLabel2.Auto(pdsLabel);
			}
			else {
				cCubeLabel2 = PvlTranslationManager(cOrigLabel, "$lro/translations/mrfExportOrigLabelLRO.trn");
				cCubeLabel2.Auto(pdsLabel);
			}
		}
	}
	else { //Level3 - add Band_Name keyword 
		PvlGroup & cBandBinGrp = cInCube->GetGroup("BandBin");
		PvlKeyword cKeyBandBin = PvlKeyword("BAND_NAME");
		PvlKeyword cKeyInBandBin;
		if (cBandBinGrp.HasKeyword("OriginalBand")){
			cKeyInBandBin = cBandBinGrp.FindKeyword("OriginalBand");					
		}
		else if (cBandBinGrp.HasKeyword("FilterName")){
			cKeyInBandBin = cBandBinGrp.FindKeyword("FilterName");					
		}
		for (int i=0; i<cKeyInBandBin.Size(); i++) {
			cKeyBandBin += cKeyInBandBin[i];
		}
		PvlObject &cImageObject( pdsLabel.FindObject("IMAGE") );
		cImageObject += cKeyBandBin;
	}
	
	// Get the Sources Product ID if entered for Level2 only as per example
	if (ui.WasEntered("SRC") && bLevel2) {
		std::string sSrcFile = ui.GetFilename("SRC");
		std::string sSrcType = ui.GetString("TYPE");
		GetSourceProductID(sSrcFile, sSrcType, pdsLabel);
	}	
  
	// Get the User defined Labels
	if (ui.WasEntered("USERLBL")) {
		std::string sUserLbl = ui.GetFilename("USERLBL");
		GetUserLabel(sUserLbl, pdsLabel, bLevel2);
	}
	
	// Calculate CheckSum
	Statistics * cStats =  cInCube->Statistics();
	iCheckSum = (unsigned int )cStats->Sum();
		
	FixLabel(pdsLabel, bLevel2);	
	
	// Add an output format template to	the PDS PVL
	// Distinguish betweeen Level 2 and 3 images by calling the camera()
	// function as only non mosaic images(Level2) have a camera	
	if (bLevel2) {
		pdsLabel.SetFormatTemplate ("$lro/translations/mrfPdsLevel2.pft");
	} else {		
		pdsLabel.SetFormatTemplate ("$lro/translations/mrfPdsLevel3.pft");
	}

	size_t iFound = outFilename.find(".lbl");
	outFilename.replace(iFound, 4, ".img");
	ofstream oCube(outFilename.c_str());
	cProcess.OutputDetatchedLabel(); 		
	//cProcess.OutputLabel(oCube);		
	cProcess.StartProcess(oCube);		
	oCube.close();
	cProcess.EndProcess();	
}