/** * This is the main loop over the cube data. Statistics are used to * calculate which brick actually contains DNs. The framelet with DNs * is corrected by RemoveSeam and this also clears remembered offsets * (used for speed optimization) when the band changes. */ void FixSeams(vector<Buffer *> &inBuffers, vector<Buffer *> &outBuffers) { Buffer &evenBuffer = *inBuffers[0]; Buffer &oddBuffer = *inBuffers[1]; Buffer &outEvenBuffer = *outBuffers[0]; Buffer &outOddBuffer = *outBuffers[1]; outEvenBuffer.Copy(evenBuffer); outOddBuffer.Copy(oddBuffer); Statistics evenStats; evenStats.AddData(evenBuffer.DoubleBuffer(), evenBuffer.size()); Statistics oddStats; oddStats.AddData(oddBuffer.DoubleBuffer(), oddBuffer.size()); int framelet = (evenBuffer.Line() - 1) / frameletSize; if(framelet == 0) { frameletOffsetsForBand.clear(); } if(evenStats.ValidPixels() > oddStats.ValidPixels()) { RemoveSeam(outEvenBuffer, framelet, evenBuffer.Band(), false); } else { RemoveSeam(outOddBuffer, framelet, oddBuffer.Band(), true); } }
//********************************************************** // Get statistics on a line of pixels and break it into phases //********************************************************** //add all the data to the stats statistics object. When we compare which of // the lines (%4 = 0, %4 = 1, %4 = 2, %4 = 3) is the furtherest from the // total average, we use stats for the "total average" void getStats(Buffer &in) { stats.AddData(in.DoubleBuffer(), in.size()); //Phase 1 processing { Buffer proc(phases[0], 1, 1, in.PixelType()); for(int quad1 = 0 ; quad1 < phases[0] ; quad1++) { proc[quad1] = in[quad1]; } Statistics temp; temp.AddData(proc.DoubleBuffer(), proc.size()); lines[0].push_back(temp); stats.AddData(proc.DoubleBuffer(), proc.size()); lineStats[0].AddData(proc.DoubleBuffer(), proc.size()); } //Phase 2 processing { Buffer proc(phases[1] - phases[0], 1, 1, in.PixelType()); for(int quad2 = phases[0] ; quad2 < phases[1] ; quad2++) { proc[quad2 - phases[0]] = in[quad2]; } Statistics temp; temp.AddData(proc.DoubleBuffer(), proc.size()); lines[1].push_back(temp); stats.AddData(proc.DoubleBuffer(), proc.size()); lineStats[1].AddData(proc.DoubleBuffer(), proc.size()); } //Phase 3 processing { Buffer proc(phases[2] - phases[1], 1, 1, in.PixelType()); for(int quad3 = phases[1] ; quad3 < phases[2] ; quad3++) { proc[quad3 - phases[1]] = in[quad3]; } Statistics temp; temp.AddData(proc.DoubleBuffer(), proc.size()); lines[2].push_back(temp); stats.AddData(proc.DoubleBuffer(), proc.size()); lineStats[2].AddData(proc.DoubleBuffer(), proc.size()); } //Phase 4 processing { Buffer proc(phases[3] - phases[2], 1, 1, in.PixelType()); for(int quad4 = phases[2] ; quad4 < phases[3] ; quad4++) { proc[quad4 - phases[2]] = in[quad4]; } Statistics temp; temp.AddData(proc.DoubleBuffer(), proc.size()); lines[3].push_back(temp); stats.AddData(proc.DoubleBuffer(), proc.size()); lineStats[3].AddData(proc.DoubleBuffer(), proc.size()); } myIndex++; }
// translate the code once it is found void TranslateCode() { // read the code from the image Chip chip(8*RADIUS, 64*RADIUS); chip.TackCube(codeSample+3*RADIUS, codeLine+31*RADIUS); chip.Load(cube); for (int j=0; j<32; j++) { for (int i=0; i<4; i++) { Statistics stats; // Get the average of the subchip for (int x=1; x<=2*RADIUS; x++) { for (int y=1; y<=2*RADIUS; y++) { stats.AddData(chip.GetValue(i*2*RADIUS + x,j*2*RADIUS + y)); } } // see if it is on or off if (stats.Average() > 20000) code[i][31-j] = true; else code[i][31-j] = false; } } for (int j=0; j<32; j++) { for (int i=0; i<4; i++) { } } }
//! Compute automatic stretch for a portion of the cube void ChipViewport::computeStretch(Stretch &stretch, bool force) { if (p_stretchLocked && !force) { stretch = *p_stretch; } else { Statistics stats; for (int line = 1; line < p_chip->Lines(); line++) { for (int samp = 1; samp < p_chip->Samples(); samp++) { double value = p_chip->GetValue(samp, line); stats.AddData(&value, 1); } } Histogram hist(stats.BestMinimum(), stats.BestMaximum()); for (int line = 1; line <= p_chip->Lines(); line++) { for (int samp = 1; samp <= p_chip->Samples(); samp++) { double value = p_chip->GetValue(samp, line); hist.AddData(&value, 1); } } stretch.ClearPairs(); if (hist.Percent(0.5) != hist.Percent(99.5)) { stretch.AddPair(hist.Percent(0.5), 0.0); stretch.AddPair(hist.Percent(99.5), 255.0); } else { stretch.AddPair(-DBL_MAX, 0.0); stretch.AddPair(DBL_MAX, 255.0); } *p_stretch = stretch; } }
/** * @brief Compute the initial guess of the fit * * This method provides the non-linear fit with an initial guess of the * solution. It involves a linear fit to the latter half of the data to * provide the first two coefficents, the difference of the averages of the * residuals at both ends of the data set and 5 times the last line time as * the final (fourth) element...a bit involved really. * * @return NLVector 4-element vector of the initial guess coefficients */ NonLinearLSQ::NLVector DriftCorrect::guess() { int n = _data.dim(); int nb = n - _badLines; HiVector b1 = _data.subarray(0, nb-1); LowPassFilterComp gfilter(b1, _history, _sWidth, _sIters); int nb2 = nb/2; _b2 = gfilter.ref(); HiVector cc = poly_fit(_b2.subarray(nb2,_b2.dim()-1), nb2-1); // Compute the 3rd term guess by getting the average of the residual // at both ends of the data set. Statistics s; // Get the head of the data set int n0 = MIN(nb, 20); for ( int k = 0 ; k < n0 ; k++ ) { double d = _b2[k] - (cc[0] + cc[1] * _timet(k)); s.AddData(&d, 1); } double head = s.Average(); // Get the tail of the data set s.Reset(); n0 = (int) (0.9 * nb); for ( int l = n0 ; l < nb ; l++ ) { double d = _b2[l] - (cc[0] + cc[1] * _timet(l)); s.AddData(&d, 1); } double tail = s.Average(); // Populate the guess with the results NLVector g(4, 0.0); g[0] = cc[0]; g[1] = cc[1]; g[2] = head-tail; g[3] = -5.0/_timet(nb-1); _guess = g; _history.add("Guess["+ToString(_guess[0])+ ","+ ToString(_guess[1])+ ","+ ToString(_guess[2])+ ","+ ToString(_guess[3])+ "]"); return (g); }
/** * 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; }
// Gather statistics for the cube void GatherStatistics(Buffer &in) { // Number of samples per line that intersect with the next and the // previous images unsigned int intersect; // Check if samples equal 682 or 683 if (in.size() == 682 || in.size() == 683) { intersect = 18; } // If not the above case, then we perform an algorithm to account for binning else { // Number of intersecting samples is directly related to total // number of samples in the line, with 2048 being the maximum possible unsigned int div = 2048 / in.size(); intersect = 48 / div; } g_s.AddData(&in[0], in.size()); g_sl.AddData(&in[0], intersect); g_sr.AddData(&in[in.size()-intersect], intersect); }
void HiImageClean::cimage_dark() { // Combine calibration region std::vector<H2DBuf> blobs; blobs.push_back(_caldark); blobs.push_back(_ancdark); H2DBuf dark = appendLines(blobs); int nsamples(dark.dim2()); int nlines(dark.dim1()); // Compute averages for the mask area int firstDark(4); int ndarks(dark.dim2()-firstDark); _predark = H1DBuf(nlines); for (int line = 0 ; line < nlines ; line++) { Statistics darkave; darkave.AddData(&dark[line][firstDark], ndarks); _predark[line] = darkave.Average(); } // Get statistics to determine state of mask and next course of action _darkStats.Reset(); _darkStats.AddData(&_predark[0], _predark.dim1()); if (_darkStats.ValidPixels() <= 0) { std::ostringstream mess; mess << "No valid pixels in calibration/ancillary dark regions, " << "binning = " << _binning << std::ends; throw(iException::Message(iException::Programmer,mess.str(),_FILEINFO_)); } // Now apply a smoothing filter QuickFilter smooth(_predark.dim1(), _filterWidth, 1); smooth.AddLine(&_predark[0]); nsamples = smooth.Samples(); _dark = H1DBuf(nsamples); for (int s = 0 ; s < nsamples ; s++) { _dark[s] = smooth.Average(s); } // Now apply to all calibration data BigInt nbad(0); _calimg = row_apply(_calimg, _dark, 0, nbad, 1.0); _calbuf = row_apply(_calbuf, _dark, 0, nbad, 1.0); _caldark = row_apply(_caldark, _dark, 0, nbad, 1.0); _ancbuf = row_apply(_ancbuf, _dark, _firstImageLine, nbad, 1.0); _ancdark = row_apply(_ancdark, _dark, _firstImageLine, nbad, 1.0); return; }
void gatherAverages(Buffer &in) { Statistics lineStats; lineStats.AddData(in.DoubleBuffer(), in.size()); double average = lineStats.Average(); lineAverages[in.Band() - 1][in.Line() - 1] = average; // The cube average will finish being calculated before the correction is applied. if(!IsSpecial(average)) { cubeAverage[in.Band() - 1] += average; } else { numIgnoredLines ++; } }
//********************************************************** // DOUSER - Get statistics on a column or row of pixels //********************************************************** void getStats(Buffer &in) { Statistics stats; stats.AddData(in.DoubleBuffer(), in.size()); band.push_back(in.Band()); element.push_back(in.Sample()); // Sort the input buffer vector<double> pixels; for(int i = 0; i < in.size(); i++) { if(IsValidPixel(in[i])) pixels.push_back(in[i]); } sort(pixels.begin(), pixels.end()); // Now obtain the median value and store in the median vector int size = pixels.size(); if(size != 0) { int med = size / 2; if(size % 2 == 0) { median.push_back((pixels[med-1] + pixels[med]) / 2.0); } else { median.push_back(pixels[med]); } } else { median.push_back(Isis::Null); } // Store the statistics in the appropriate vectors average.push_back(stats.Average()); stddev.push_back(stats.StandardDeviation()); validpixels.push_back(stats.ValidPixels()); minimum.push_back(stats.Minimum()); maximum.push_back(stats.Maximum()); }
void IsisMain() { // We will be processing by line ProcessByLine p; // Setup the input and output cubes Cube *icube = p.SetInputCube("FROM"); PvlKeyword &status = icube->group("RESEAUS")["STATUS"]; UserInterface &ui = Application::GetUserInterface(); QString in = ui.GetFileName("FROM"); // Check reseau status and make sure it is not nominal or removed if((QString)status == "Nominal") { QString msg = "Input file [" + in + "] appears to have nominal reseau status. You must run findrx first."; throw IException(IException::User, msg, _FILEINFO_); } if((QString)status == "Removed") { QString msg = "Input file [" + in + "] appears to already have reseaus removed."; throw IException(IException::User, msg, _FILEINFO_); } status = "Removed"; p.SetOutputCube("TO"); // Start the processing p.StartProcess(cpy); p.EndProcess(); // Get the user entered dimensions sdim = ui.GetInteger("SDIM"); ldim = ui.GetInteger("LDIM"); // Get other user entered options QString out = ui.GetFileName("TO"); resvalid = ui.GetBoolean("RESVALID"); action = ui.GetString("ACTION"); // Open the output cube Cube cube; cube.open(out, "rw"); PvlGroup &res = cube.label()->findGroup("RESEAUS", Pvl::Traverse); // Get reseau line, sample, type, and valid Keywords PvlKeyword lines = res.findKeyword("LINE"); PvlKeyword samps = res.findKeyword("SAMPLE"); PvlKeyword type = res.findKeyword("TYPE"); PvlKeyword valid = res.findKeyword("VALID"); int numres = lines.size(); Brick brick(sdim, ldim, 1, cube.pixelType()); for(int res = 0; res < numres; res++) { if((resvalid == 0 || toInt(valid[res]) == 1) && toInt(type[res]) != 0) { int baseSamp = (int)(toDouble(samps[res]) + 0.5) - (sdim / 2); int baseLine = (int)(toDouble(lines[res]) + 0.5) - (ldim / 2); brick.SetBasePosition(baseSamp, baseLine, 1); cube.read(brick); if(action == "NULL") { for(int i = 0; i < brick.size(); i++) brick[i] = Isis::Null; } else if(action == "BILINEAR") { Statistics stats; double array[sdim][ldim]; for(int s = 0; s < sdim; s++) { for(int l = 0; l < ldim; l++) { int index = l * sdim + s; array[s][l] = brick[index]; // Add perimeter data to stats object for calculations if(s == 0 || l == 0 || s == (sdim - 1) || l == (ldim - 1)) { stats.AddData(&array[s][l], 1); } } } // Get the average and standard deviation of the perimeter of the brick double avg = stats.Average(); double sdev = stats.StandardDeviation(); // Top Edge Reseau if(toInt(type[res]) == 2) { int l1 = 0; int l2 = ldim - 1; for(int s = 0; s < sdim; s++) { array[s][l1] = array[s][l2]; } } // Left Edge Reseau else if(toInt(type[res]) == 4) { int s1 = 0; int s2 = sdim - 1; for(int l = 0; l < ldim; l++) { array[s1][l] = array[s2][l]; } } // Right Edge Reseau else if(toInt(type[res]) == 6) { int s1 = 0; int s2 = sdim - 1; for(int l = 0; l < ldim; l++) { array[s2][l] = array[s1][l]; } } // Bottom Edge Reseau else if(toInt(type[res]) == 8) { int l1 = 0; int l2 = ldim - 1; for(int s = 0; s < sdim; s++) { array[s][l2] = array[s][l1]; } } // Walk top edge & replace data outside of 2devs with the avg for(int s = 0; s < sdim; s++) { int l = 0; double diff = fabs(array[s][l] - avg); if(diff > (2 * sdev)) array[s][l] = avg; } // Walk bottom edge & replace data outside of 2devs with the avg for(int s = 0; s < sdim; s++) { int l = ldim - 1; double diff = fabs(array[s][l] - avg); if(diff > (2 * sdev)) array[s][l] = avg; } // Walk left edge & replace data outside of 2devs with the avg for(int l = 0; l < ldim; l++) { int s = 0; double diff = fabs(array[s][l] - avg); if(diff > (2 * sdev)) array[s][l] = avg; } // Walk right edge & replace data outside of 2devs with the avg for(int l = 0; l < ldim; l++) { int s = sdim - 1; double diff = fabs(array[s][l] - avg); if(diff > (2 * sdev)) array[s][l] = avg; } srand(0); double dn, gdn1, gdn2; for(int l = 0; l < ldim; l++) { int c = l * sdim; //count // Top Edge Reseau if(toInt(type[res]) == 2 && l < (ldim / 2)) continue; // Bottom Edge Reseau if(toInt(type[res]) == 8 && l > (ldim / 2 + 1)) continue; for(int s = 0; s < sdim; s++, c++) { // Left Edge Reseau if(toInt(type[res]) == 4 && s < (sdim / 2)) continue; // Right Edge Reseau if(toInt(type[res]) == 6 && s > (sdim / 2 + 1)) continue; double sum = 0.0; int gline1 = 0; int gline2 = ldim - 1; gdn1 = array[s][gline1]; gdn2 = array[s][gline2]; // Linear Interpolation to get pixel value dn = gdn2 + (l - gline2) * (gdn1 - gdn2) / (gline1 - gline2); sum += dn; int gsamp1 = 0; int gsamp2 = sdim - 1; gdn1 = array[gsamp1][l]; gdn2 = array[gsamp2][l]; // Linear Interpolation to get pixel value dn = gdn2 + (s - gsamp2) * (gdn1 - gdn2) / (gsamp1 - gsamp2); sum += dn; dn = sum / 2; int rdm = rand(); double drandom = rdm / (double)RAND_MAX; double offset = 0.0; if(drandom < .333) offset = -1.0; if(drandom > .666) offset = 1.0; brick[c] = dn + offset; } } } } cube.write(brick); } cube.close(); }
void HiImageClean::cimage_mask() { // Combine calibration region std::vector<H2DBuf> blobs; blobs.push_back(_calbuf); blobs.push_back(_calimg); blobs.push_back(_caldark); H2DBuf calibration = appendSamples(blobs); // Set the mask depending on the binning mode _firstMaskLine = 20; _lastMaskLine = 39; switch (_binning) { case 1: _firstMaskLine = 21; _lastMaskLine = 38; break; case 2: _firstMaskLine = 21; _lastMaskLine = 29; break; case 3: _firstMaskLine = 21; _lastMaskLine = 26; break; case 4: _firstMaskLine = 21; _lastMaskLine = 24; break; case 8: _firstMaskLine = 21; _lastMaskLine = 22; break; case 16: _firstMaskLine = 21; _lastMaskLine = 21; break; default: std::ostringstream msg; msg << "Invalid binning mode (" << _binning << ") - valid are 1-4, 8 and 16" << std::ends; throw(iException::Message(iException::Programmer,msg.str(),_FILEINFO_)); } // Initialize lines and samples of mask area of interest int nsamples(calibration.dim2()); int nlines(_lastMaskLine - _firstMaskLine + 1); // Compute averages for the mask area _premask = H1DBuf(nsamples); for (int samp = 0 ; samp < nsamples; samp++) { H1DBuf maskcol = slice(calibration, samp); Statistics maskave; maskave.AddData(&maskcol[_firstMaskLine], nlines); _premask[samp] = maskave.Average(); } _mask = _premask.copy(); // Get statistics to determine state of mask and next course of action _maskStats.Reset(); _maskStats.AddData(&_premask[0], nsamples); if (_maskStats.ValidPixels() <= 0) { std::ostringstream mess; mess << "No valid pixels in calibration mask region in lines " << (_firstMaskLine+1) << " to " << (_lastMaskLine+1) << ", binning = " << _binning << std::ends; throw(iException::Message(iException::Programmer,mess.str(),_FILEINFO_)); } // If there are any missing values, replace with mins/maxs of region if (_maskStats.TotalPixels() != _maskStats.ValidPixels()) { for (int samp = 0 ; samp < nsamples ; samp++) { if (Pixel::IsLow(_premask[samp]) || Pixel::IsNull(_premask[samp])) { _mask[samp] = _maskStats.Minimum(); } else if (Pixel::IsHigh(_premask[samp])) { _mask[samp] = _maskStats.Maximum(); } } } // Now apply to all calibration data BigInt nbad(0); _calimg = column_apply(_calimg, _mask, _firstImageSample, nbad, 1.0); _calbuf = column_apply(_calbuf, _mask, _firstBufferSample, nbad, 1.0); _caldark = column_apply(_caldark, _mask, _firstDarkSample, nbad, 1.0); _ancbuf = column_apply(_ancbuf, _mask, _firstBufferSample, nbad, 1.0); _ancdark = column_apply(_ancdark, _mask, _firstDarkSample, nbad, 1.0); return; }
/** * This calculates the coefficients for specific energy corrections */ void calculateSpecificEnergy(Cube *icube) { PvlGroup &inst = icube->label()->findGroup("Instrument", Pvl::Traverse); bool vis = (inst["Channel"][0] != "IR"); double coefficient = 1.0; if(inst["GainMode"][0] == "HIGH") { coefficient /= 2; } if(vis && inst["SamplingMode"][0] == "HI-RES") { coefficient *= 3; } if(vis) { coefficient /= toDouble(inst["ExposureDuration"][1]) / 1000.0; } else { coefficient /= (toDouble(inst["ExposureDuration"][0]) * 1.01725) / 1000.0 - 0.004; } QString specEnergyFile = "$cassini/calibration/vims/"; if(vis) { specEnergyFile += "vis_perf_v????.cub"; } else { specEnergyFile += "ir_perf_v????.cub"; } QString waveCalFile = "$cassini/calibration/vims/wavecal_v????.cub"; FileName specEnergyFileName(specEnergyFile); specEnergyFileName = specEnergyFileName.highestVersion(); FileName waveCalFileName(waveCalFile); waveCalFileName = waveCalFileName.highestVersion(); Cube specEnergyCube; specEnergyCube.open(specEnergyFileName.expanded()); Cube waveCalCube; waveCalCube.open(waveCalFileName.expanded()); LineManager specEnergyMgr(specEnergyCube); LineManager waveCalMgr(waveCalCube); for(int i = 0; i < icube->bandCount(); i++) { Statistics specEnergyStats; Statistics waveCalStats; if(vis) { specEnergyMgr.SetLine(1, i + 1); waveCalMgr.SetLine(1, i + 1); } else { specEnergyMgr.SetLine(1, i + 1); // ir starts at band 97 waveCalMgr.SetLine(1, i + 96 + 1); } specEnergyCube.read(specEnergyMgr); waveCalCube.read(waveCalMgr); specEnergyStats.AddData(specEnergyMgr.DoubleBuffer(), specEnergyMgr.size()); waveCalStats.AddData(waveCalMgr.DoubleBuffer(), waveCalMgr.size()); double bandCoefficient = coefficient * specEnergyStats.Average() * waveCalStats.Average(); specificEnergyCorrections.push_back(bandCoefficient); } }
/** * Retrieve the statistics based on the box size * and point on the cube. * * @param p */ void StatisticsTool::getStatistics(QPoint p) { MdiCubeViewport *cvp = cubeViewport(); if(cvp == NULL) return; double sample, line; cvp->viewportToCube(p.x(), p.y(), sample, line); // If we are outside of the cube, do nothing if((sample < 0.5) || (line < 0.5) || (sample > cvp->cubeSamples() + 0.5) || (line > cvp->cubeLines() + 0.5)) { return; } int isamp = (int)(sample + 0.5); int iline = (int)(line + 0.5); Statistics stats; Brick *brick = new Brick(1, 1, 1, cvp->cube()->pixelType()); QVector<QVector<double> > pixelData(p_boxLines, QVector<double>(p_boxSamps, Null)); double lineDiff = p_boxLines / 2.0; double sampDiff = p_boxSamps / 2.0; p_ulSamp = isamp - (int)floor(sampDiff); p_ulLine = iline - (int)floor(lineDiff); int x, y; y = p_ulLine; for(int i = 0; i < p_boxLines; i++) { x = p_ulSamp; if(y < 1 || y > cvp->cubeLines()) { y++; continue; } for(int j = 0; j < p_boxSamps; j++) { if(x < 1 || x > cvp->cubeSamples()) { x++; continue; } brick->SetBasePosition(x, y, cvp->grayBand()); cvp->cube()->read(*brick); stats.AddData(brick->at(0)); pixelData[i][j] = brick->at(0); x++; } y++; } p_visualDisplay->setPixelData(pixelData, p_ulSamp, p_ulLine); if (stats.ValidPixels()) { p_minLabel->setText(QString("Minimum: %1").arg(stats.Minimum())); p_maxLabel->setText(QString("Maximum: %1").arg(stats.Maximum())); p_avgLabel->setText(QString("Average: %1").arg(stats.Average())); p_stdevLabel->setText(QString("Standard Dev: %1").arg(stats.StandardDeviation(), 0, 'f', 6)); } else { p_minLabel->setText(QString("Minimum: n/a")); p_maxLabel->setText(QString("Maximum: n/a")); p_avgLabel->setText(QString("Average: n/a")); p_stdevLabel->setText(QString("Standard Dev: n/a")); } p_set = true; resizeScrollbars(); }
void IsisMain() { Process p; // Get the list of names of input CCD cubes to stitch together FileList flist; UserInterface &ui = Application::GetUserInterface(); flist.Read(ui.GetFilename("FROMLIST")); if (flist.size() < 1) { string msg = "The list file[" + ui.GetFilename("FROMLIST") + " does not contain any filenames"; throw iException::Message(iException::User,msg,_FILEINFO_); } string projection("Equirectangular"); if(ui.WasEntered("MAP")) { Pvl mapfile(ui.GetFilename("MAP")); projection = (string) mapfile.FindGroup("Mapping")["ProjectionName"]; } if(ui.WasEntered("PROJECTION")) { projection = ui.GetString("PROJECTION"); } // Gather other user inputs to projection string lattype = ui.GetString("LATTYPE"); string londir = ui.GetString("LONDIR"); string londom = ui.GetString("LONDOM"); int digits = ui.GetInteger("PRECISION"); // Fix them for mapping group lattype = (lattype == "PLANETOCENTRIC") ? "Planetocentric" : "Planetographic"; londir = (londir == "POSITIVEEAST") ? "PositiveEast" : "PositiveWest"; Progress prog; prog.SetMaximumSteps(flist.size()); prog.CheckStatus(); Statistics scaleStat; Statistics longitudeStat; Statistics latitudeStat; Statistics equiRadStat; Statistics poleRadStat; PvlObject fileset("FileSet"); // Save major equitorial and polar radii for last occuring double eqRad; double eq2Rad; double poleRad; string target("Unknown"); for (unsigned int i = 0 ; i < flist.size() ; i++) { // Set the input image, get the camera model, and a basic mapping // group Cube cube; cube.Open(flist[i]); int lines = cube.Lines(); int samples = cube.Samples(); PvlObject fmap("File"); fmap += PvlKeyword("Name",flist[i]); fmap += PvlKeyword("Lines", lines); fmap += PvlKeyword("Samples", samples); Camera *cam = cube.Camera(); Pvl mapping; cam->BasicMapping(mapping); PvlGroup &mapgrp = mapping.FindGroup("Mapping"); mapgrp.AddKeyword(PvlKeyword("ProjectionName",projection),Pvl::Replace); mapgrp.AddKeyword(PvlKeyword("LatitudeType",lattype),Pvl::Replace); mapgrp.AddKeyword(PvlKeyword("LongitudeDirection",londir),Pvl::Replace); mapgrp.AddKeyword(PvlKeyword("LongitudeDomain",londom),Pvl::Replace); // Get the radii double radii[3]; cam->Radii(radii); eqRad = radii[0] * 1000.0; eq2Rad = radii[1] * 1000.0; poleRad = radii[2] * 1000.0; target = cam->Target(); equiRadStat.AddData(&eqRad, 1); poleRadStat.AddData(&poleRad, 1); // Get resolution double lowres = cam->LowestImageResolution(); double hires = cam->HighestImageResolution(); scaleStat.AddData(&lowres, 1); scaleStat.AddData(&hires, 1); double pixres = (lowres+hires)/2.0; double scale = Scale(pixres, poleRad, eqRad); mapgrp.AddKeyword(PvlKeyword("PixelResolution",pixres),Pvl::Replace); mapgrp.AddKeyword(PvlKeyword("Scale",scale,"pixels/degree"),Pvl::Replace); mapgrp += PvlKeyword("MinPixelResolution",lowres,"meters"); mapgrp += PvlKeyword("MaxPixelResolution",hires,"meters"); // Get the universal ground range double minlat,maxlat,minlon,maxlon; cam->GroundRange(minlat,maxlat,minlon,maxlon,mapping); 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); fmap.AddGroup(mapgrp); fileset.AddObject(fmap); longitudeStat.AddData(&minlon, 1); longitudeStat.AddData(&maxlon, 1); latitudeStat.AddData(&minlat, 1); latitudeStat.AddData(&maxlat, 1); p.ClearInputCubes(); prog.CheckStatus(); } // Construct the output mapping group with statistics PvlGroup mapping("Mapping"); double avgPixRes((scaleStat.Minimum()+scaleStat.Maximum())/2.0); double avgLat((latitudeStat.Minimum()+latitudeStat.Maximum())/2.0); double avgLon((longitudeStat.Minimum()+longitudeStat.Maximum())/2.0); double avgEqRad((equiRadStat.Minimum()+equiRadStat.Maximum())/2.0); double avgPoleRad((poleRadStat.Minimum()+poleRadStat.Maximum())/2.0); double scale = Scale(avgPixRes, avgPoleRad, avgEqRad); mapping += PvlKeyword("ProjectionName",projection); mapping += PvlKeyword("TargetName", target); mapping += PvlKeyword("EquatorialRadius",eqRad,"meters"); mapping += PvlKeyword("PolarRadius",poleRad,"meters"); mapping += PvlKeyword("LatitudeType",lattype); mapping += PvlKeyword("LongitudeDirection",londir); mapping += PvlKeyword("LongitudeDomain",londom); mapping += PvlKeyword("PixelResolution", SetRound(avgPixRes, digits), "meters/pixel"); mapping += PvlKeyword("Scale", SetRound(scale, digits), "pixels/degree"); mapping += PvlKeyword("MinPixelResolution",scaleStat.Minimum(),"meters"); mapping += PvlKeyword("MaxPixelResolution",scaleStat.Maximum(),"meters"); mapping += PvlKeyword("CenterLongitude", SetRound(avgLon,digits)); mapping += PvlKeyword("CenterLatitude", SetRound(avgLat,digits)); mapping += PvlKeyword("MinimumLatitude", MAX(SetFloor(latitudeStat.Minimum(),digits), -90.0)); mapping += PvlKeyword("MaximumLatitude", MIN(SetCeil(latitudeStat.Maximum(),digits), 90.0)); mapping += PvlKeyword("MinimumLongitude",MAX(SetFloor(longitudeStat.Minimum(),digits), -180.0)); mapping += PvlKeyword("MaximumLongitude",MIN(SetCeil(longitudeStat.Maximum(),digits), 360.0)); PvlKeyword clat("PreciseCenterLongitude", avgLon); clat.AddComment("Actual Parameters without precision applied"); mapping += clat; mapping += PvlKeyword("PreciseCenterLatitude", avgLat); mapping += PvlKeyword("PreciseMinimumLatitude", latitudeStat.Minimum()); mapping += PvlKeyword("PreciseMaximumLatitude", latitudeStat.Maximum()); mapping += PvlKeyword("PreciseMinimumLongitude",longitudeStat.Minimum()); mapping += PvlKeyword("PreciseMaximumLongitude",longitudeStat.Maximum()); Application::GuiLog(mapping); // Write the output file if requested if (ui.WasEntered("TO")) { Pvl temp; temp.AddGroup(mapping); temp.Write(ui.GetFilename("TO","map")); } if (ui.WasEntered("LOG")) { Pvl temp; temp.AddObject(fileset); temp.Write(ui.GetFilename("LOG","log")); } p.EndProcess(); }
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; } }
void IsisMain() { //get the number of samples to skip from the left and right ends // of the prefix and suffix data UserInterface &ui = Application::GetUserInterface(); int imageLeft = 0; int imageRight = 0; int rampLeft = 0; int rampRight = 0; int calLeftBuffer = 0; int calRightBuffer = 0; int calLeftDark = 0; int calRightDark = 0; int leftBuffer = 0; int rightBuffer = 0; int leftDark = 0; int rightDark = 0; if(ui.GetBoolean("USEOFFSETS")) { imageLeft = ui.GetInteger("LEFTIMAGE"); imageRight = ui.GetInteger("RIGHTIMAGE"); rampLeft = ui.GetInteger("LEFTIMAGE"); rampRight = ui.GetInteger("RIGHTIMAGE"); calLeftBuffer = ui.GetInteger("LEFTCALBUFFER"); calRightBuffer = ui.GetInteger("LEFTCALBUFFER"); calLeftDark = ui.GetInteger("LEFTCALDARK"); calRightDark = ui.GetInteger("RIGHTCALDARK"); leftBuffer = ui.GetInteger("LEFTBUFFER"); rightBuffer = ui.GetInteger("RIGHTBUFFER"); leftDark = ui.GetInteger("LEFTDARK"); rightDark = ui.GetInteger("RIGHTDARK"); } 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"); // Get statistics from the cube prefix and suffix data Table hifix("HiRISE Ancillary"); icube->read(hifix); Statistics darkStats, bufStats, rampDarkStats; int tdi = icube->group("Instrument")["Tdi"]; int binning_mode = icube->group("Instrument")["Summing"]; //This gets us the statistics for the dark and buffer pixels // alongside of the image itself for(int rec = 2; rec < hifix.Records(); rec++) { vector<int> dark = hifix[rec]["DarkPixels"]; vector<int> buf = hifix[rec]["BufferPixels"]; if(buf.size() <= (unsigned int)(leftBuffer + rightBuffer)) { ThrowException(buf.size(), leftBuffer, rightBuffer, "image buffer"); } if(dark.size() <= (unsigned int)(leftDark + rightDark)) { ThrowException(dark.size(), leftDark, rightDark, "image dark reference"); } for(int i = leftDark; i < (int)dark.size() - rightDark; i++) { double d; if(dark[i] == NULL2) d = NULL8; else if(dark[i] == LOW_REPR_SAT2) d = LOW_REPR_SAT8; else if(dark[i] == LOW_INSTR_SAT2) d = LOW_INSTR_SAT8; else if(dark[i] == HIGH_INSTR_SAT2) d = HIGH_INSTR_SAT8; else if(dark[i] == HIGH_REPR_SAT2) d = HIGH_REPR_SAT8; else d = dark[i]; darkStats.AddData(&d, 1); } for(int i = leftBuffer; i < (int)buf.size() - rightBuffer; i++) { double d; if(buf[i] == NULL2) d = NULL8; else if(buf[i] == LOW_REPR_SAT2) d = LOW_REPR_SAT8; else if(buf[i] == LOW_INSTR_SAT2) d = LOW_INSTR_SAT8; else if(buf[i] == HIGH_INSTR_SAT2) d = HIGH_INSTR_SAT8; else if(buf[i] == HIGH_REPR_SAT2) d = HIGH_REPR_SAT8; else d = buf[i]; bufStats.AddData(&d, 1); } } // Get statistics from the calibration image //Calculate boundaries of the reverse readout lines, // Masked lines, and ramp lines. //There are always 20 reverse readout lines int reverseReadoutLines = 20; //Number of mask pixels depends on Binning mode int maskLines; maskLines = 20 / binning_mode; //mask lines go after reverse lines maskLines += reverseReadoutLines; // Actual starting line, number Ramp lines int rampStart = maskLines; int rampLines = tdi / binning_mode; Table calimg("HiRISE Calibration Image"); icube->read(calimg); Statistics calStats; //Statistics for the Reverse readout lines of the cal image Statistics reverseStats; //Statistics for the masked lines of the cal image Statistics maskStats; //Statistics for the ramped lines of the cal image Statistics rampStats; //Iterate through the calibration image //Add in reverse data for(int rec = 2 ; rec <= 18 ; rec++) { //Lines [2,18] vector<int> lineBuffer = calimg[rec]["Calibration"]; for(unsigned int i = 2 ; i < lineBuffer.size() - 1 ; i++) { //Samples [2, * -1] double d = lineBuffer[i]; if(lineBuffer[i] == NULL2) { d = NULL8; } else if(lineBuffer[i] == LOW_REPR_SAT2) { d = LOW_REPR_SAT8; } else if(lineBuffer[i] == LOW_INSTR_SAT2) { d = LOW_INSTR_SAT8; } else if(lineBuffer[i] == HIGH_INSTR_SAT2) { d = HIGH_INSTR_SAT8; } else if(lineBuffer[i] == HIGH_REPR_SAT2) { d = HIGH_REPR_SAT8; } reverseStats.AddData(&d, 1); } } //Add in the mask data for(int rec = 22 ; rec < maskLines - 1 ; rec++) {//Lines [22, 38] !!!!dependant on bin vector<int> lineBuffer = calimg[rec]["Calibration"]; for(int i = 2 ; i < (int)lineBuffer.size() - 1 ; i++) { //Samples [2, *-1] double d = lineBuffer[i]; if(d == NULL2) { d = NULL8; } else if(d == LOW_REPR_SAT2) { d = LOW_REPR_SAT8; } else if(d == LOW_INSTR_SAT2) { d = LOW_INSTR_SAT8; } else if(d == HIGH_INSTR_SAT2) { d = HIGH_INSTR_SAT8; } else if(d == HIGH_REPR_SAT2) { d = HIGH_REPR_SAT8; } maskStats.AddData(&d, 1); } } //Add in the ramp data for(int rec = maskLines + 2; rec < calimg.Records() - 1; rec++) { vector<int> buf = calimg[rec]["Calibration"]; //loop through all but the first and last sample of the calibration image for(int i = rampLeft; i < (int)buf.size() - rampRight; i++) { double d; if(buf[i] == NULL2) d = NULL8; else if(buf[i] == LOW_REPR_SAT2) d = LOW_REPR_SAT8; else if(buf[i] == LOW_INSTR_SAT2) d = LOW_INSTR_SAT8; else if(buf[i] == HIGH_INSTR_SAT2) d = HIGH_INSTR_SAT8; else if(buf[i] == HIGH_REPR_SAT2) d = HIGH_REPR_SAT8; else d = buf[i]; //Determine which group of stats to add to rampStats.AddData(&d, 1); } } // Get statistics from the calibration prefix and suffix data Table calfix("HiRISE Calibration Ancillary"); icube->read(calfix); Statistics calDarkStats, calBufStats; int rampLine0 = rampStart + 1; int rampLineN = (rampStart + rampLines - 1) - 1; rampLineN = calfix.Records() - 1; for(int rec = 0; rec < calfix.Records(); rec++) { vector<int> dark = calfix[rec]["DarkPixels"]; vector<int> buf = calfix[rec]["BufferPixels"]; if(buf.size() <= (unsigned int)(calLeftBuffer + calRightBuffer)) { ThrowException(buf.size(), calLeftBuffer, calRightBuffer, "calibration buffer"); } if(dark.size() <= (unsigned int)(calLeftDark + calRightDark)) { ThrowException(dark.size(), calLeftDark, calRightDark, "calibration dark reference"); } for(int i = calLeftDark; i < (int)dark.size() - calRightDark; i++) { double d; if(dark[i] == NULL2) d = NULL8; else if(dark[i] == LOW_REPR_SAT2) d = LOW_REPR_SAT8; else if(dark[i] == LOW_INSTR_SAT2) d = LOW_INSTR_SAT8; else if(dark[i] == HIGH_INSTR_SAT2) d = HIGH_INSTR_SAT8; else if(dark[i] == HIGH_REPR_SAT2) d = HIGH_REPR_SAT8; else d = dark[i]; calDarkStats.AddData(&d, 1); if((rec > rampLine0) && (rec < rampLineN)) { rampDarkStats.AddData(&d, 1); } } for(int i = calLeftBuffer; i < (int)buf.size() - calRightBuffer; i++) { double d; if(buf[i] == NULL2) d = NULL8; else if(buf[i] == LOW_REPR_SAT2) d = LOW_REPR_SAT8; else if(buf[i] == LOW_INSTR_SAT2) d = LOW_INSTR_SAT8; else if(buf[i] == HIGH_INSTR_SAT2) d = HIGH_INSTR_SAT8; else if(buf[i] == HIGH_REPR_SAT2) d = HIGH_REPR_SAT8; else d = buf[i]; calBufStats.AddData(&d, 1); } } Statistics linesPostrampStats; Statistics imageStats; Isis::LineManager imageBuffer(inputCube); imageBuffer.begin(); Buffer out(imageBuffer.SampleDimension() - (imageLeft + imageRight), imageBuffer.LineDimension(), imageBuffer.BandDimension(), imageBuffer.PixelType()); for(int postRampLine = 0 ; postRampLine < LINES_POSTRAMP ; postRampLine++) { inputCube.read(imageBuffer); for(int postRampSamp = 0 ; postRampSamp < out.SampleDimension() ; postRampSamp++) { out[postRampSamp] = imageBuffer[postRampSamp + imageLeft]; } linesPostrampStats.AddData(out.DoubleBuffer(), out.size()); imageBuffer++; } for(int imageLine = LINES_POSTRAMP; imageLine < inputCube.lineCount(); imageLine++) { inputCube.read(imageBuffer); for(int imageSample = 0 ; imageSample < out.SampleDimension(); imageSample++) { out[imageSample] = imageBuffer[imageSample + imageLeft]; } imageStats.AddData(out.DoubleBuffer(), out.size()); imageBuffer++; } // Generate the statistics in pvl form const int NUM_GROUPS = 10; PvlGroup groups[NUM_GROUPS]; groups[0] = PvlStats(linesPostrampStats, "IMAGE_POSTRAMP"); groups[1] = PvlStats(imageStats, "IMAGE"); groups[2] = PvlStats(darkStats, "IMAGE_DARK"); groups[3] = PvlStats(bufStats, "IMAGE_BUFFER"); groups[4] = PvlStats(reverseStats, "CAL_REVERSE"); groups[5] = PvlStats(maskStats, "CAL_MASK"); groups[6] = PvlStats(rampStats, "CAL_RAMP"); groups[7] = PvlStats(calDarkStats, "CAL_DARK"); groups[8] = PvlStats(rampDarkStats, "CAL_DARK_RAMP"); groups[9] = PvlStats(calBufStats, "CAL_BUFFER"); // Write the results to the output file if the user specified one if(ui.WasEntered("TO")) { Pvl temp; for(int i = 0 ; i < NUM_GROUPS ; i++) { temp.addGroup(groups[i]); } temp.write(ui.GetFileName("TO")); } else { // Log the results for(int i = 0 ; i < NUM_GROUPS ; i++) { Application::Log(groups[i]); } } }
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); }
/** * This method is the pass 2 processing routine. A ProcessByBrick * will call this method for sets of data (depending on the camera * type) and this method is responsible for writing the entire output * temporary cube. * * @param in Input raw image data, not including excluded files */ void CreateTemporaryData(Buffer &in) { /** * Line scan cameras process by frame columns. */ if(cameraType == LineScan) { // The statistics of every column of data need to be known // before we can write to the temp file. Gather stats for this // column. Statistics inputColStats; for(int i = 0; i < in.size(); i++) { inputColStats.AddData(in[i]); // We'll also need the stats for the entire frame in order to // normalize and in order to decide whether or not we want // to toss out the frame inputFrameStats.AddData(in[i]); } // Store off the column stats outputTmpAverages[in.Sample()-1] = inputColStats.Average(); outputTmpCounts[in.Sample()-1] = inputColStats.ValidPixels(); // Test if this is the last column and we've got all of our stats if(in.Sample() == numOutputSamples) { // Decide if we want this data if(IsSpecial(inputFrameStats.StandardDeviation()) || inputFrameStats.StandardDeviation() > maxStdev) { // We don't want this data... // CreateNullData is a helper method for this case that // nulls out the stats CreateNullData(); // Record the exclusion PvlGroup currExclusion("ExcludedLines"); currExclusion += PvlKeyword("FrameStartLine", iString(in.Line())); currExclusion += PvlKeyword("ValidPixels", iString(inputFrameStats.ValidPixels())); if(!IsSpecial(inputFrameStats.StandardDeviation())) currExclusion += PvlKeyword("StandardDeviation", inputFrameStats.StandardDeviation()); else currExclusion += PvlKeyword("StandardDeviation", "N/A"); excludedDetails[excludedDetails.size()-1].AddGroup(currExclusion); } // Let's write our data... CreateNullData took care of nulls for us // Band 1 is our normalized average oLineMgr->SetLine(oLineMgr->Line(),1); for(int i = 0; i < (int)outputTmpAverages.size(); i++) { if(!IsSpecial(outputTmpAverages[i])) { (*oLineMgr)[i] = outputTmpAverages[i] / inputFrameStats.Average(); } else { (*oLineMgr)[i] = Isis::Null; } } ocube->Write(*oLineMgr); oLineMgr->SetLine(oLineMgr->Line(),2); // band 2 is our valid dn counts for(int i = 0; i < (int)outputTmpCounts.size(); i++) { (*oLineMgr)[i] = outputTmpCounts[i]; numInputDns[i] += (int)(outputTmpCounts[i] + 0.5); } ocube->Write(*oLineMgr); (*oLineMgr) ++; inputFrameStats.Reset(); } } else if(cameraType == Framing || cameraType == PushFrame) { // Framing cameras and push frames are treated identically; // the framelet size for a framelet in the framing camera // is the entire image! int framelet = (in.Line()-1) / numFrameLines; double stdev; bool excluded = Excluded(currImage, framelet, stdev); if(excluded && ((in.Line()-1) % numFrameLines == 0)) { PvlGroup currExclusion("ExcludedFramelet"); currExclusion += PvlKeyword("FrameletStartLine", iString(in.Line())); currExclusion += PvlKeyword("FrameletNumber", (in.Line()-1) / numFrameLines); if(!IsSpecial(stdev)) { currExclusion += PvlKeyword("StandardDeviation", stdev); } else { currExclusion += PvlKeyword("StandardDeviation", "N/A"); } excludedDetails[excludedDetails.size()-1].AddGroup(currExclusion); } // Since this is a line by line iterative process, we need to get the current // data in the temp file oLineMgr->SetLine(((in.Line() - 1) % numFrameLines) + 1, 1); if(!excluded || !cubeInitialized) { ocube->Read(*oLineMgr); } if(!cubeInitialized) { for(int i = 0; i < oLineMgr->size(); i++) { (*oLineMgr)[i] = Isis::Null; } } vector<bool> isValidData; if(!excluded || !cubeInitialized) { isValidData.resize(in.size()); for(int samp = 0; samp < in.size(); samp++) { if(IsSpecial((*oLineMgr)[samp]) && !IsSpecial(in[samp])) { (*oLineMgr)[samp] = 0.0; } if(!IsSpecial(in[samp])) { isValidData[samp] = true; (*oLineMgr)[samp] += in[samp] / inputFrameletAverages[currImage][framelet]; } else { isValidData[samp] = false; } } } if(!excluded || !cubeInitialized) { ocube->Write(*oLineMgr); } oLineMgr->SetLine(oLineMgr->Line(), 2); if(!excluded || !cubeInitialized) { ocube->Read(*oLineMgr); } if(!cubeInitialized) { for(int i = 0; i < oLineMgr->size(); i++) { (*oLineMgr)[i] = Isis::Null; } if(ocube->Lines() == oLineMgr->Line()) cubeInitialized = true; } if(!excluded || !cubeInitialized) { for(int i = 0; i < (int)isValidData.size(); i++) { if(IsSpecial((*oLineMgr)[i])) { (*oLineMgr)[i] = 0.0; } if(isValidData[i]) { (*oLineMgr)[i] ++; } } } if(!excluded || !cubeInitialized) { ocube->Write(*oLineMgr); } } }
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; } }
//function to add stats data to the stats object. //also tests if the line and samp are valid void buildStats (Camera *cam, int &sample, int &line){ cam->SetImage(sample, line); if (cam->HasSurfaceIntersection()) { latStat.AddData(cam->UniversalLatitude()); lonStat.AddData(cam->UniversalLongitude()); resStat.AddData(cam->PixelResolution()); sampleResStat.AddData(cam->SampleResolution()); lineResStat.AddData(cam->LineResolution()); phaseStat.AddData(cam->PhaseAngle()); emissionStat.AddData(cam->EmissionAngle()); incidenceStat.AddData(cam->IncidenceAngle()); localSolarTimeStat.AddData(cam->LocalSolarTime()); localRaduisStat.AddData(cam->LocalRadius()); northAzimuthStat.AddData(cam->NorthAzimuth()); double Aratio = cam->LineResolution() / cam->SampleResolution(); aspectRatioStat.AddData(Aratio); } }