// 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; }
/** * 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; }
//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"); }
/** * @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_); } }
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(); }
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); }
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; } }
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(); }