int main () { Isis::Preference::Preferences(true); try { PvlGroup op("Operator"); op += PvlKeyword("Name","Gradient"); op += PvlKeyword("DeltaLine", 100); op += PvlKeyword("DeltaSamp", 100); op += PvlKeyword("Samples", 15); op += PvlKeyword("Lines", 15); op += PvlKeyword("MinimumInterest", 1); PvlObject o("InterestOperator"); o.AddGroup(op); Pvl pvl; pvl.AddObject(o); std::cout << pvl << std::endl; InterestOperator *iop = InterestOperatorFactory::Create(pvl); Cube c; c.Open("$mgs/testData/ab102401.cub"); iop->Operate(c, 100, 350); std::cout << "Sample: " << iop->CubeSample() << std::endl << "Line : " << iop->CubeLine() << std::endl << "Interest: " << iop->InterestAmount() << std::endl; } catch (iException &e) { e.Report(); } return 0; }
void IsisMain() { // We will be processing by line ProcessByBrick p; p.SetBrickSize(1,1,1); p.SetOutputBrickSize(1,1,1); UserInterface &ui = Application::GetUserInterface(); // Basic settings p.SetInputCube("FROM"); p.SetOutputCube("TO"); Pvl pvl = Pvl(ui.GetFilename("PVL")); cube.Open(ui.GetFilename("FROM")); try { // Get info from the operator group // Set the pvlkeywords that need to be set to zero PvlGroup &op = pvl.FindGroup("Operator",Pvl::Traverse); boxcarSamples = op["Samples"]; boxcarLines = op["Lines"]; op["DeltaLine"]=0; op["DeltaSamp"]=0; op["MinimumInterest"]=0.0; Application::Log(op); } catch (iException &e) { std::string msg = "Improper format for InterestOperator PVL ["+pvl.Filename()+"]"; throw iException::Message(iException::User,msg,_FILEINFO_); } iop = InterestOperatorFactory::Create(pvl); // Start the processing p.StartProcess(Operate); p.EndProcess(); }
/** * @brief File name based constructor for HiRISE image cleaner */ HiImageClean::HiImageClean(const std::string &fname) { Cube cube; cube.Open(fname); _filename = fname; _lines = _samples = 0; _totalMaskNulled = _totalDarkNulled = 0; init(cube); }
int main () { Isis::Preference::Preferences(true); try { PvlGroup alg("Algorithm"); alg += PvlKeyword("Name","MinimumDifference"); alg += PvlKeyword("Tolerance",5.0); alg += PvlKeyword("SubpixelAccuracy", "True"); PvlGroup pchip("PatternChip"); pchip += PvlKeyword("Samples",15); pchip += PvlKeyword("Lines",15); pchip += PvlKeyword("Sampling",25); pchip += PvlKeyword("ValidPercent", 10); PvlGroup schip("SearchChip"); schip += PvlKeyword("Samples",35); schip += PvlKeyword("Lines",35); schip += PvlKeyword("Sampling", 50); PvlObject o("AutoRegistration"); o.AddGroup(alg); o.AddGroup(pchip); o.AddGroup(schip); Pvl pvl; pvl.AddObject(o); std::cout << pvl << std::endl; AutoReg *ar = AutoRegFactory::Create(pvl); Cube c; c.Open("$mgs/testData/ab102401.cub"); ar->SearchChip()->TackCube(125.0,50.0); ar->SearchChip()->Load(c); ar->PatternChip()->TackCube(120.0,45.0); ar->PatternChip()->Load(c); std::cout << "Register = " << ar->Register() << std::endl; std::cout << "Position = " << ar->CubeSample() << " " << ar->CubeLine() << std::endl; } catch (iException &e) { e.Report(); } return 0; }
void IsisMain() { //Get user parameters UserInterface &ui = Application::GetUserInterface(); Filename inFile = ui.GetFilename("FROM"); int numberOfLines = ui.GetInteger("NL"); int lineOverlap = ui.GetInteger("OVERLAP"); //Throws exception if user is dumb if ( lineOverlap >= numberOfLines ) { throw iException::Message( iException::User, "The Line Overlap (OVERLAP) must be less than the Number of Lines (LN).", _FILEINFO_ ); } //Opens the cube Cube cube; cube.Open( inFile.Expanded() ); //Loops through, cropping as desired int cropNum = 1; int startLine = 1; bool hasReachedEndOfCube = false; while ( startLine <= cube.Lines() && not hasReachedEndOfCube ) { //! Sets up the proper paramaters for running the crop program string parameters = "FROM=" + inFile.Expanded() + " TO=" + inFile.Path() + "/" + inFile.Basename() + ".segment" + iString(cropNum) + ".cub" + " LINE=" + iString(startLine) + " NLINES="; if ( startLine + numberOfLines > cube.Lines() ) { parameters += iString( cube.Lines() - ( startLine - 1 ) ); hasReachedEndOfCube = true; } else { parameters += iString(numberOfLines); } Isis::iApp ->Exec("crop",parameters); //The starting line for next crop startLine = 1 + cropNum * ( numberOfLines - lineOverlap ); cropNum++; } }
/** * @brief Loads the contents of a BLOB from a cube file * * Provides the I/O interface for ISIS cube files. * * @param [in] filename (string&) Name of ISIS cube file to read */ void Blobber::load(const std::string &filename) { Cube cube; cube.Open(filename); load(cube); return; }
int main () { Isis::Preference::Preferences(true); /** * @brief Test ImagePolygon object for accuracy and correct behavior. * * @author 2005-11-22 Tracie Sucharski * * @history 2007-01-19 Tracie Sucharski, Removed ToGround method (for now) * because of round off problems going back and forth between * lat/lon,line/samp. * @history 2007-01-31 Tracie Sucharski, Added WKT method to return polygon * in string as WKT. * @history 2007-11-09 Tracie Sucharski, Remove WKT method, geos now has * a method to return a WKT string. * @history 2007-11-20 Tracie Sucharski, Added test for sub-polys */ // simple MOC image string inFile = "/usgs/cpkgs/isis3/data/mgs/testData/ab102401.cub"; //string inFile = "/work1/tsucharski/poly/I17621017RDR_lev2.cub"; // same MOC image, but sinusoidal projection //string inFile = "/farm/prog1/tsucharski/isis3/ab102401.lev2.cub"; // same MOC image, but sinusoidal projection , doctored left edge //string inFile = "/farm/prog1/tsucharski/isis3/ab102401.lev2.leftTrim.cub"; // MOC north pole image //string inFile = "/work1/tsucharski/isis3/poly/e0202226.lev1.cub"; // MOC image with 0/360 boundary // orkin //string inFile = "/farm/prog1/tsucharski/isis3/cubes/m0101631.lev1.cub"; // blackflag //string inFile = "/work1/tsucharski/isis3/poly/m0101631.lev1.cub"; // galileo ssi image //string inFile = "/farm/prog1/tsucharski/isis3/6700r.cub"; // Open the cube Cube cube; Cube cube1; cube.Open(inFile,"r"); ImagePolygon poly; try { poly.Create(cube); } catch (iException &e) { std::string msg = "Cannot create polygon for [" + cube.Filename() + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // write poly as WKT std::cout<< poly.Polys()->toString()<<std::endl; // Test sub-poly option try { poly.Create(cube,12,1,384,640,385); } catch (iException &e) { std::string msg = "Cannot create sub-polygon for [" + cube.Filename() + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // write poly as WKT std::cout<< poly.Polys()->toString()<<std::endl; // Test lower quality option try { poly.Create(cube,10,12,1,384,640,385); } catch (iException &e) { std::string msg = "Cannot create lower quality polygon for [" + cube.Filename() + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // write poly as WKT std::cout<< poly.Polys()->toString()<<std::endl; cube.Close(); }
int main() { Preference::Preferences(true); Chip chip(51, 50); cout << "Test basics" << endl; cout << chip.Samples() << endl; cout << chip.Lines() << endl; chip.TackCube(453.5, 568.5); cout << chip.TackSample() << endl; cout << chip.TackLine() << endl; cout << "Test chip-to-cube and cube-to-chip mapping" << endl; chip.SetChipPosition(chip.TackSample(), chip.TackLine()); cout << chip.CubeSample() << endl; cout << chip.CubeLine() << endl; chip.SetChipPosition(1.0, 1.0); cout << chip.CubeSample() << endl; cout << chip.CubeLine() << endl; chip.SetCubePosition(chip.CubeSample(), chip.CubeLine()); cout << chip.ChipSample() << endl; cout << chip.ChipLine() << endl; cout << "Test assignment of chip data to constant" << endl; chip.SetAllValues(10.0); for(int i = 1; i <= chip.Lines(); i++) { for(int j = 1; j <= chip.Samples(); j++) { double value = chip.GetValue(j, i); if(value != 10.0) { cout << "bad constant (!= 10) at " << j << ", " << i << endl; } } } cout << "Test loading chip data" << endl; for(int i = 1; i <= chip.Lines(); i++) { for(int j = 1; j <= chip.Samples(); j++) { chip.SetValue(j, i, (double)(i * 100 + j)); } } for(int i = 1; i <= chip.Lines(); i++) { for(int j = 1; j <= chip.Samples(); j++) { double value = chip.GetValue(j, i); if(value != (double)(i * 100 + j)) { cout << "bad at " << j << ", " << i << endl; } } } chip.SetValidRange(0.0, 5050.0); cout << "Valid tests" << endl; // is chip valid at 51, 50? cout << chip.IsValid(chip.Samples(), chip.Lines()) << endl; // is chip valid at 50, 50? cout << chip.IsValid(chip.Samples() - 1, chip.Lines()) << endl; // is at least 95% of chip values valid? cout << chip.IsValid(95.0) << endl; // is at least 99.99% of chip values valid? cout << chip.IsValid(99.99) << endl; cout << "Extract test" << endl; // Extract 4 by 3 subchip at 26, 25 Chip sub = chip.Extract(4, 3, chip.TackSample(), chip.TackLine()); for(int i = 1; i <= sub.Lines(); i++) { for(int j = 1; j <= sub.Samples(); j++) { cout << sub.GetValue(j, i) << " "; } cout << endl; } cout << "Test writing chip" << endl; chip.Write("junk.cub"); Cube junk; junk.open("junk.cub"); LineManager line(junk); for(int i = 1; i <= chip.Lines(); i++) { line.SetLine(i); junk.read(line); for(int j = 1; j <= chip.Samples(); j++) { double value = chip.GetValue(j, i); if(value != line[j-1]) { cout << "bad at " << j << ", " << i << endl; } } } cout << "Test load chip from cube with rotation" << endl; chip.TackCube(26.0, 25.0); chip.Load(junk, 45.0); for(int i = 1; i <= chip.Lines(); i++) { for(int j = 1; j <= chip.Samples(); j++) { cout << std::setw(14) << chip.GetValue(j, i) << " "; } cout << endl; } cout << "Test load chip from cube with rotation and clipping polygon " << endl; chip.TackCube(26.0, 25.0); geos::geom::CoordinateSequence *pts = new geos::geom::CoordinateArraySequence(); pts->add(geos::geom::Coordinate(23.0, 22.0)); pts->add(geos::geom::Coordinate(28.0, 22.0)); pts->add(geos::geom::Coordinate(28.0, 27.0)); pts->add(geos::geom::Coordinate(25.0, 28.0)); pts->add(geos::geom::Coordinate(23.0, 22.0)); vector<geos::geom::Geometry *> polys; geos::geom::GeometryFactory gf; polys.push_back(gf.createPolygon(gf.createLinearRing(pts), NULL)); geos::geom::MultiPolygon *mPolygon = gf.createMultiPolygon(polys); chip.SetClipPolygon(*mPolygon); chip.Load(junk, 45.0); for(int i = 1; i <= chip.Lines(); i++) { for(int j = 1; j <= chip.Samples(); j++) { cout << std::setw(14) << chip.GetValue(j, i) << " "; } cout << endl; } // Test affine transformation cout << "\nTesting Affine transformation extraction (-1, -1)...\n"; Affine affine; affine.Translate(-1.0, -1.0); Chip mychip(51, 50); // Needed because chip has poly clipping mychip.TackCube(26.0, 25.0); mychip.Load(junk); mychip.SetChipPosition(mychip.TackSample(), mychip.TackLine()); cout << "Cube Sample, Line = " << mychip.CubeSample() << ", " << mychip.CubeLine() << endl; Chip shift(25, 25); mychip.Extract(shift, affine); // shift.SetChipPosition(shift.TackSample(), shift.TackLine()); cout << "Shift Cube Sample, Line = " << shift.CubeSample() << ", " << shift.CubeLine() << endl; Chip io = shift; io.TackCube(25.0, 24.0); io.Load(junk); io.SetChipPosition(io.TackSample(), io.TackLine()); cout << "New Cube Sample, Line = " << io.CubeSample() << ", " << io.CubeLine() << endl; int ioNull(0), shiftNull(0); double sumDiff(0.0); for(int il = 1 ; il <= io.Lines() ; il++) { for(int is = 1 ; is <= io.Samples() ; is++) { if(IsSpecial(io.GetValue(is, il))) { ioNull++; } else if(IsSpecial(shift.GetValue(is, il))) { shiftNull++; } else { sumDiff += io.GetValue(is, il) - shift.GetValue(is, il); } } } cout << "I/O Nulls: " << ioNull << endl; cout << "Shift Nulls: " << shiftNull << endl; cout << "Sum Diff: " << sumDiff << endl; cout << "\nTesting direct Affine Application...\n"; Chip affchip(25, 25); affchip.TackCube(25.0, 24.0); affchip.SetTransform(io.GetTransform()); affchip.SetChipPosition(affchip.TackSample(), affchip.TackLine()); cout << "Affine Cube Sample, Line = " << affchip.CubeSample() << ", " << affchip.CubeLine() << endl; cout << "\nTest reading with new Affine transform...\n"; affchip.Load(junk, io.GetTransform()); ioNull = shiftNull = 0; sumDiff = 0.0; for(int il = 1 ; il <= io.Lines() ; il++) { for(int is = 1 ; is <= io.Samples() ; is++) { if(IsSpecial(io.GetValue(is, il))) { ioNull++; } else if(IsSpecial(affchip.GetValue(is, il))) { shiftNull++; } else { sumDiff += io.GetValue(is, il) - affchip.GetValue(is, il); } } } cout << "I/O Nulls: " << ioNull << endl; cout << "Shift Nulls: " << shiftNull << endl; cout << "Sum Diff: " << sumDiff << endl; affchip.SetChipPosition(affchip.TackSample(), affchip.TackLine()); cout << "Affine Cube loaded at Sample, Line = " << affchip.CubeSample() << ", " << affchip.CubeLine() << endl; // Test Load using match chip method cout << "\nTest reading with match chip and cube...\n"; Cube junkCube; junkCube.open("$base/testData/ab102401_ideal.cub"); // 4 by 4 chip at samle 1000 line 500 Chip matchChip(4, 4); matchChip.TackCube(1000, 500); matchChip.Load(junkCube); cout << "\nMatch chip values..." << endl; for(int i = 1; i <= matchChip.Lines(); i++) { for(int j = 1; j <= matchChip.Samples(); j++) { cout << std::setw(14) << matchChip.GetValue(j, i) << " "; } cout << endl; } // make sure that if we create a new chip from the same cube that is matched // to the match chip, the chips should be almost identical Chip newChip(4, 4); newChip.TackCube(1000, 500); newChip.Load(junkCube, matchChip, junkCube); cout << "\nLoading new chip values from match chip..." << endl; cout << "Passes if difference is less than EPSILON = " << 2E-6 << endl; for(int i = 1; i <= newChip.Lines(); i++) { for(int j = 1; j <= newChip.Samples(); j++) { double difference = newChip.GetValue(j, i) - matchChip.GetValue(j, i); if(fabs(difference) > 2E-6) { cout << "bad at " << j << ", " << i << endl; cout << "difference at " << j << ", " << i << " is " << difference << endl; } else{ cout << "\tPASS\t\t"; // the following comment prints actual difference. // cout << std::setw(14) << difference << "\t"; } } cout << endl; } cout << endl; cout << endl; cout << "Test interpolator set/get methods" << endl; cout << "default: " << chip.GetReadInterpolator() << endl; chip.SetReadInterpolator(Isis::Interpolator::NearestNeighborType); cout << "nearest neighbor: " << chip.GetReadInterpolator() << endl; chip.SetReadInterpolator(Isis::Interpolator::BiLinearType); cout << "bilinear: " << chip.GetReadInterpolator() << endl; chip.SetReadInterpolator(Isis::Interpolator::CubicConvolutionType); cout << "cubic convolution: " << chip.GetReadInterpolator() << endl; cout << endl; cout << endl; cout << "Generate Errors:" << endl; Cube junkCube2; junkCube2.open("$base/testData/f319b18_ideal.cub"); // 4 by 4 chip at samle 1000 line 500 matchChip.TackCube(1, 1); matchChip.Load(junkCube2); cout << "Try to set interpolator to type 0 (Interpolator::None):" << endl; try { chip.SetReadInterpolator(Isis::Interpolator::None); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to set interpolator to type 3 (enum value not assigned):" << endl; try { chip.SetReadInterpolator((Isis::Interpolator::interpType) 3); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to set chip size with input parameter equal to 0:" << endl; try { newChip.SetSize(0, 1); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to load a cube that is not camera or map projection:" << endl; try { newChip.Load(junk, matchChip, junkCube); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to load a cube with a match cube that is not camera or map projection:" << endl; try { newChip.Load(junkCube, matchChip, junk); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to load a cube with match chip and cube that can not find at least 3 points for Affine Transformation:" << endl; try { newChip.Load(junkCube, matchChip, junkCube2); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to set valid range with larger number passed in as first parameter:" << endl; try { newChip.SetValidRange(4, 3); } catch(IException &e) { ReportError(e.toString()); } cout << "Try to extract a sub-chip with samples or lines greater than original chip:" << endl; try { newChip.Extract(2, 5, 1, 1); } catch(IException &e) { ReportError(e.toString()); } junk.close(true);// the "true" flag removes junk.cub from the /tmp/ directory junkCube.close(); // these cubes are kept in test data area, do not delete junkCube2.close(); #if 0 try { junk.Open("/work2/janderso/moc/ab102401.lev1.cub"); chip.TackCube(453.0, 567.0); chip.Load(junk); Cube junk2; junk2.Open("/work2/janderso/moc/ab102402.lev0.cub"); Chip chip2(75, 70); chip2.TackCube(166.0, 567.0); chip2.Load(junk2, chip); chip.Write("junk3.cub"); chip2.Write("junk4.cub"); } catch(IException &e) { e.print(); } #endif return 0; }
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(); }
/** * This is the main method. Makeflat runs in three steps: * * 1) Calculate statistics * - For all cameras, this checks for one band and matching * sample counts. * - For framing cameras, this checks the standard deviation of * the images and records the averages of each image * - For push frame cameras, this calls CheckFramelets for each * image. * * 2) Create the temporary file, collect more detailed statistics * - For all cameras, this generates the temporary file and calculates * the final exclusion list * - For framing/push frame cameras, the temporary file is * 2 bands, where the first is a sum of DNs from each image/framelet * and the second band is a count of valid DNs that went into each sum * * 3) Create the final flat field file * - For all cameras, this processes the temporary file to create the final flat * field file. */ void IsisMain() { // Initialize variables ResetGlobals(); UserInterface &ui = Application::GetUserInterface(); maxStdev = ui.GetDouble("STDEVTOL"); if(ui.GetString("IMAGETYPE") == "FRAMING") { cameraType = Framing; // framing cameras need to figure this out automatically // during step 1 numFrameLines = -1; } else if(ui.GetString("IMAGETYPE") == "LINESCAN") { cameraType = LineScan; numFrameLines = ui.GetInteger("NUMLINES"); } else { cameraType = PushFrame; numFrameLines = ui.GetInteger("FRAMELETHEIGHT"); } FileList inList(ui.GetFilename("FROMLIST")); Progress progress; tempFileLength = 0; numOutputSamples = 0; /** * Line scan progress is based on the input list, whereas * the other cameras take much longer and are based on the * images themselves. Prepare the progress if we're doing * line scan. */ if(cameraType == LineScan) { progress.SetText("Calculating Number of Image Lines"); progress.SetMaximumSteps(inList.size()); progress.CheckStatus(); } /** * For a push frame camera, the temp file is one framelet. * Technically this is the same for the framing, but we * don't know the height of a framelet yet. */ if(cameraType == PushFrame) { tempFileLength = numFrameLines; } /** * Start pass 1, use global currImage so that methods called * know the image we're processing. */ for(currImage = 0; currImage < inList.size(); currImage++) { /** * Read the current cube into memory */ Cube tmp; tmp.Open(Filename(inList[currImage]).Expanded()); /** * If we haven't determined how many samples the output * should have, we can do so now */ if(numOutputSamples == 0 && tmp.Bands() == 1) { numOutputSamples = tmp.Samples(); } /** * Try and validate the image, quick tests first! * * (imageValid &= means imageValid = imageValid && ...) */ bool imageValid = true; // Only single band images are acceptable imageValid &= (tmp.Bands() == 1); // Sample sizes must always match imageValid &= (numOutputSamples == tmp.Samples()); // For push frame cameras, there must be valid all framelets if(cameraType == PushFrame) { imageValid &= (tmp.Lines() % numFrameLines == 0); } // For framing cameras, we need to figure out the size... // setTempFileLength is used to revert if the file // is decided to be invalid bool setTempFileLength = false; if(cameraType == Framing) { if(tempFileLength == 0 && imageValid) { tempFileLength = tmp.Lines(); numFrameLines = tempFileLength; setTempFileLength = true; } imageValid &= (tempFileLength == tmp.Lines()); } // Statistics are necessary at this point for push frame and framing cameras // because the framing camera standard deviation tolerance is based on // entire images, and push frame framelet exclusion stats can not be collected // during pass 2 cleanly if((cameraType == Framing || cameraType == PushFrame) && imageValid) { string prog = "Calculating Standard Deviation " + iString((int)currImage+1) + "/"; prog += iString((int)inList.size()) + " (" + Filename(inList[currImage]).Name() + ")"; if(cameraType == Framing) { Statistics *stats = tmp.Statistics(1, prog); imageValid &= !IsSpecial(stats->StandardDeviation()); imageValid &= !IsSpecial(stats->Average()); imageValid &= stats->StandardDeviation() <= maxStdev; vector<double> fileStats; fileStats.push_back(stats->Average()); inputFrameletAverages.push_back(fileStats); delete stats; } else if(cameraType == PushFrame) { imageValid &= CheckFramelets(prog, tmp); } if(setTempFileLength && !imageValid) { tempFileLength = 0; } } // The line scan camera needs to actually count the number of lines in each image to know // how many total frames there are before beginning pass 2. if(imageValid && (cameraType == LineScan)) { int lines = (tmp.Lines() / numFrameLines); // partial frame? if(tmp.Lines() % numFrameLines != 0) { lines ++; } tempFileLength += lines; } else if(!imageValid) { excludedFiles.insert(pair<int, bool>(currImage, true)); } tmp.Close(); if(cameraType == LineScan) { progress.CheckStatus(); } } /** * If the number of output samples could not be determined, we never * found a legitimate cube. */ if(numOutputSamples <= 0) { string msg = "No valid input cubes were found"; throw iException::Message(iException::User,msg,_FILEINFO_); } /** * If theres no temp file length, which is based off of valid data in * the input cubes, then we havent found any valid data. */ if(tempFileLength <= 0) { string msg = "No valid input data was found"; throw iException::Message(iException::User,msg,_FILEINFO_); } /** * ocube is now the temporary file (for pass 2). */ ocube = new Cube(); ocube->SetDimensions(numOutputSamples, tempFileLength, 2); PvlGroup &prefs = Preference::Preferences().FindGroup("DataDirectory", Pvl::Traverse); iString outTmpName = (string)prefs["Temporary"][0] + "/"; outTmpName += Filename(ui.GetFilename("TO")).Basename() + ".tmp.cub"; ocube->Create(outTmpName); oLineMgr = new LineManager(*ocube); oLineMgr->SetLine(1); ProcessByBrick p; int excludedCnt = 0; if(cameraType == LineScan) { outputTmpAverages.resize(numOutputSamples); outputTmpCounts.resize(numOutputSamples); numInputDns.resize(numOutputSamples); } cubeInitialized = false; for(currImage = 0; currImage < inList.size(); currImage++) { if(Excluded(currImage)) { excludedCnt ++; continue; } PvlObject currFile("Exclusions"); currFile += PvlKeyword("Filename", inList[currImage]); currFile += PvlKeyword("Tolerance", maxStdev); if(cameraType == LineScan) { currFile += PvlKeyword("FrameLines", numFrameLines); } else if(cameraType == PushFrame) { currFile += PvlKeyword("FrameletLines", numFrameLines); } excludedDetails.push_back(currFile); CubeAttributeInput inAtt; // This needs to be set constantly because ClearInputCubes // seems to be removing the input brick size. if(cameraType == LineScan) { p.SetBrickSize(1, numFrameLines, 1); } else if(cameraType == Framing || cameraType == PushFrame) { p.SetBrickSize(numOutputSamples, 1, 1); } p.SetInputCube(inList[currImage], inAtt); iString progText = "Calculating Averages " + iString((int)currImage+1); progText += "/" + iString((int)inList.size()); progText += " (" + Filename(inList[currImage]).Name() + ")"; p.Progress()->SetText(progText); p.StartProcess(CreateTemporaryData); p.EndProcess(); p.ClearInputCubes(); if(excludedDetails[excludedDetails.size()-1].Groups() == 0) { excludedDetails.resize(excludedDetails.size()-1); } } /** * Pass 2 completed. The processing methods were responsible for writing * the entire temporary cube. */ if(oLineMgr) { delete oLineMgr; oLineMgr = NULL; } if(ocube) { ocube->Close(); delete ocube; } /** * ocube is now the final output */ ocube = new Cube(); if(cameraType == LineScan) { ocube->SetDimensions(numOutputSamples, 1, 1); } else if(cameraType == Framing || cameraType == PushFrame) { ocube->SetDimensions(numOutputSamples, tempFileLength, 1); } ocube->Create(Filename(ui.GetFilename("TO")).Expanded()); oLineMgr = new LineManager(*ocube); oLineMgr->SetLine(1); // We now have the necessary temp file, let's go ahead and combine it into // the final output! p.SetInputBrickSize(numOutputSamples, 1, 2); p.SetOutputBrickSize(numOutputSamples, 1, 1); cubeInitialized = false; CubeAttributeInput inAtt; p.Progress()->SetText("Calculating Final Flat Field"); p.SetInputCube(outTmpName, inAtt); p.StartProcess(ProcessTemporaryData); p.EndProcess(); if(cameraType == LineScan) { ocube->Write(*oLineMgr); } if(oLineMgr) { delete oLineMgr; oLineMgr = NULL; } if(ocube) { ocube->Close(); delete ocube; ocube = NULL; } /** * Build a list of excluded files */ PvlGroup excludedFiles("ExcludedFiles"); for(currImage = 0; currImage < inList.size(); currImage++) { if(Excluded(currImage)) { excludedFiles += PvlKeyword("File", inList[currImage]); } } // log the results Application::Log(excludedFiles); if(ui.WasEntered("EXCLUDE")) { Pvl excludeFile; // Find excluded files excludeFile.AddGroup(excludedFiles); for(unsigned int i = 0; i < excludedDetails.size(); i++) { excludeFile.AddObject(excludedDetails[i]); } excludeFile.Write(Filename(ui.GetFilename("EXCLUDE")).Expanded()); } remove(outTmpName.c_str()); // Clean up settings ResetGlobals(); }
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(); /*Processing steps 1. Open and read the jitter table, convert the pixel offsets to angles, and create the polynomials (solve for the coefficients) to use to do the high pass filter putting the results into a rotation matrix in the jitter class. 2. Apply the jitter correction in the LineScanCameraRotation object of the master cube. 3. Loop through FROMLIST correcting the pointing and writing out the updated camera pointing from the master cube */ int degree = ui.GetInteger("DEGREE"); // Get the input file list to make sure it is not empty and the master cube is included FileList list; list.Read(ui.GetFilename("FROMLIST")); if (list.size() < 1) { string msg = "The input list file [" + ui.GetFilename("FROMLIST") + "is empty"; throw iException::Message(iException::User,msg,_FILEINFO_); } int ifile = 0; // Make sure the master file is included in the input file list while (ifile < (int) list.size() && Filename(list[ifile]).Expanded() != Filename(ui.GetFilename("MASTER")).Expanded()) { ifile++; } if (ifile >= (int) list.size()) { string msg = "The master file, [" + Filename(ui.GetFilename("MASTER")).Expanded() + " is not included in " + "the input list file " + ui.GetFilename("FROMLIST") + "]"; throw iException::Message(iException::User,msg,_FILEINFO_); } bool step2 = false; PvlGroup gp("AppjitResults"); //Step 1: Create the jitter rotation try { // Open the master cube Cube cube; cube.Open(ui.GetFilename("MASTER"),"rw"); //check for existing polygon, if exists delete it if (cube.Label()->HasObject("Polygon")){ cube.Label()->DeleteObject("Polygon"); } // Get the camera Camera *cam = cube.Camera(); if (cam->DetectorMap()->LineRate() == 0.0) { string msg = "[" + ui.GetFilename("MASTER") + "] is not a line scan camera image"; throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } // Create the master rotation to be corrected int frameCode = cam->InstrumentRotation()->Frame(); cam->SetImage(int(cube.Samples()/2), int(cube.Lines()/2) ); double tol = cam->PixelResolution(); if (tol < 0.) { // Alternative calculation of .01*ground resolution of a pixel tol = cam->PixelPitch()*cam->SpacecraftAltitude()*1000./cam->FocalLength()/100.; } LineScanCameraRotation crot(frameCode, *(cube.Label()), cam->InstrumentRotation()->GetFullCacheTime(), tol ); crot.SetPolynomialDegree(ui.GetInteger("DEGREE")); crot.SetAxes(1, 2, 3); if (ui.WasEntered("PITCHRATE")) crot.ResetPitchRate(ui.GetDouble("PITCHRATE")); if (ui.WasEntered("YAW")) crot.ResetYaw(ui.GetDouble("YAW")); crot.SetPolynomial(); double baseTime = crot.GetBaseTime(); double timeScale = crot.GetTimeScale(); double fl = cam->FocalLength(); double pixpitch = cam->PixelPitch(); std::vector<double> cacheTime = cam->InstrumentRotation()->GetFullCacheTime(); // Get the jitter in pixels, compute jitter angles, and fit a polynomial to each angle PixelOffset jitter(ui.GetFilename("JITTERFILE"), fl, pixpitch, baseTime, timeScale, degree); jitter.LoadAngles(cacheTime); jitter.SetPolynomial(); // Set the jitter and apply to the instrument rotation crot.SetJitter( &jitter ); crot.ReloadCache(); // Pull out the pointing cache as a table and write it Table cmatrix = crot.Cache("InstrumentPointing"); cmatrix.Label().AddComment("Corrected using appjit and" + ui.GetFilename("JITTERFILE")); cube.Write(cmatrix); // Write out the instrument position table Isis::PvlGroup kernels = cube.Label()->FindGroup("Kernels",Isis::Pvl::Traverse); // Write out the "Table" label to the tabled kernels in the kernels group kernels["InstrumentPointing"] = "Table"; // kernels["InstrumentPosition"] = "Table"; cube.PutGroup(kernels); cube.Close(); gp += PvlKeyword("StatusMaster",ui.GetFilename("MASTER") + ": camera pointing updated"); // Apply the dejittered pointing to the rest of the files step2 = true; for (int ifile = 0; ifile < (int) list.size(); ifile++) { if (list[ifile] != ui.GetFilename("MASTER")) { // Open the cube cube.Open(list[ifile],"rw"); //check for existing polygon, if exists delete it if (cube.Label()->HasObject("Polygon")){ cube.Label()->DeleteObject("Polygon"); } // Get the camera and make sure it is a line scan camera Camera *cam = cube.Camera(); if (cam->DetectorMap()->LineRate() == 0.0) { string msg = "[" + ui.GetFilename("FROM") + "] is not a line scan camera"; throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } // Pull out the pointing cache as a table and write it cube.Write(cmatrix); cube.PutGroup(kernels); cube.Close(); gp += PvlKeyword("Status" + iString(ifile), list[ifile] + ": camera pointing updated"); } } Application::Log( gp ); } catch (iException &e) { string msg; if (!step2) { msg = "Unable to fit pointing for [" + ui.GetFilename("MASTER") + "]"; } else { msg = "Unable to update pointing for nonMaster file(s)"; } throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } }
void IsisMain() { // Get the list of cubes to mosaic UserInterface &ui = Application::GetUserInterface(); FileList flist(ui.GetFilename("FROMLIST")); vector<Cube *> clist; try { if (flist.size() < 1) { string msg = "the list file [" +ui.GetFilename("FROMLIST") + "does not contain any data"; throw iException::Message(iException::User,msg,_FILEINFO_); } // open all the cube and place in vector clist for (int i=0; i<(int)flist.size(); i++) { Cube *c = new Cube(); clist.push_back(c); c->Open(flist[i]); } // run the compair function here. This will conpair the // labels of the first cube to the labels of each following cube. PvlKeyword sourceProductId("SourceProductId"); string ProdId; for (int i=0; i<(int)clist.size(); i++) { Pvl *pmatch = clist[0]->Label(); Pvl *pcomp = clist[i]->Label(); CompareLabels(*pmatch, *pcomp); PvlGroup g = pcomp->FindGroup("Instrument",Pvl::Traverse); if (g.HasKeyword("StitchedProductIds")) { PvlKeyword k = g["StitchedProductIds"]; for (int j=0; j<(int)k.Size(); j++) { sourceProductId += g["stitchedProductIds"][j]; } } ProdId = (string)pmatch->FindGroup("Archive",Pvl::Traverse)["ObservationId"]; iString bandname = (string)pmatch->FindGroup("BandBin",Pvl::Traverse)["Name"]; bandname = bandname.UpCase(); ProdId = ProdId + "_" + bandname; } bool runXY=true; //calculate the min and max lon double minLat = DBL_MAX; double maxLat = -DBL_MAX; double minLon = DBL_MAX; double maxLon = -DBL_MAX; double avgLat; double avgLon; for (int i=0; i<(int)clist.size(); i++) { Projection *proj = clist[i]->Projection(); if (proj->MinimumLatitude() < minLat) minLat = proj->MinimumLatitude(); if (proj->MaximumLatitude() > maxLat) maxLat = proj->MaximumLatitude(); if (proj->MinimumLongitude() < minLon) minLon = proj->MinimumLongitude(); if (proj->MaximumLongitude() > maxLon) maxLon = proj->MaximumLongitude(); } avgLat = (minLat + maxLat) / 2; avgLon = (minLon + maxLon) / 2; Projection *proj = clist[0]->Projection(); proj->SetGround(avgLat,avgLon); avgLat = proj->UniversalLatitude(); avgLon = proj->UniversalLongitude(); // Use camera class to get Inc., emi., phase, and other values double Cemiss; double Cphase; double Cincid; double ClocalSolTime; double CsolarLong; double CsunAzimuth; double CnorthAzimuth; for (int i=0; i<(int)clist.size(); i++) { Camera *cam = clist[i]->Camera(); if (cam->SetUniversalGround(avgLat,avgLon)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->SolarLongitude(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } //The code within the if runXY was added in 10/07 to find an intersect with //pole images that would fail when using projection set universal ground. // This is run if no intersect is found when using lat and lon in // projection space. if (runXY) { double startX = DBL_MAX; double endX = DBL_MIN; double startY = DBL_MAX; double endY = DBL_MIN; for (int i=0; i<(int)clist.size(); i++) { Projection *proj = clist[i]->Projection(); proj->SetWorld(0.5,0.5); if (i==0) { startX = proj->XCoord(); endY = proj->YCoord(); } else { if (proj->XCoord() < startX) startX = proj->XCoord(); if (proj->YCoord() > endY) endY = proj->YCoord(); } Pvl *p = clist[i]->Label(); double nlines = p->FindGroup("Dimensions",Pvl::Traverse)["Lines"]; double nsamps = p->FindGroup("Dimensions",Pvl::Traverse)["Samples"]; proj->SetWorld((nsamps+0.5),(nlines+0.5)); if (i==0) { endX = proj->XCoord(); startY = proj->YCoord(); } else { if (proj->XCoord() > endX) endX = proj->XCoord(); if (proj->YCoord() < startY) startY = proj->YCoord(); } } double avgX = (startX + endX) / 2; double avgY = (startY + endY) / 2; double sample = proj->ToWorldX(avgX); double line = proj->ToWorldY(avgY); for (int i=0; i<(int)clist.size(); i++) { Camera *cam = clist[i]->Camera(); if (cam->SetImage(sample,line)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->SolarLongitude(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } } if (runXY) { string msg = "Camera did not intersect images to gather stats"; throw iException::Message(iException::User,msg,_FILEINFO_); } // get the min and max SCLK values ( do this with string comp.) // get the value from the original label blob string startClock; string stopClock; string startTime; string stopTime; for (int i=0; i<(int)clist.size(); i++) { OriginalLabel origLab; clist[i]->Read(origLab); PvlGroup timegrp = origLab.ReturnLabels().FindGroup("TIME_PARAMETERS",Pvl::Traverse); if (i==0) { startClock = (string)timegrp["SpacecraftClockStartCount"]; stopClock = (string)timegrp["SpacecraftClockStopCount"]; startTime = (string)timegrp["StartTime"]; stopTime = (string)timegrp["StopTime"]; } else { string testStartTime = (string)timegrp["StartTime"]; string testStopTime = (string)timegrp["StopTime"]; if (testStartTime < startTime) { startTime = testStartTime; startClock = (string)timegrp["SpacecraftClockStartCount"]; } if (testStopTime > stopTime) { stopTime = testStopTime; stopClock = (string)timegrp["spacecraftClockStopCount"]; } } } // Concatenate all TDI's and summing and specialProcessingFlat into one keyword PvlKeyword cpmmTdiFlag("cpmmTdiFlag"); PvlKeyword cpmmSummingFlag("cpmmSummingFlag"); PvlKeyword specialProcessingFlag("SpecialProcessingFlag"); for (int i=0; i<14; i++) { cpmmTdiFlag +=(string)""; cpmmSummingFlag +=(string)""; specialProcessingFlag +=(string)""; } for (int i=0; i<(int)clist.size(); i++) { Pvl *clab = clist[i]->Label(); PvlGroup cInst = clab->FindGroup("Instrument",Pvl::Traverse); OriginalLabel cOrgLab; clist[i]->Read(cOrgLab); PvlGroup cGrp = cOrgLab.ReturnLabels().FindGroup("INSTRUMENT_SETTING_PARAMETERS",Pvl::Traverse); cpmmTdiFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:TDI"]; cpmmSummingFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:BINNING"]; if (cInst.HasKeyword("Special_Processing_Flag")) { specialProcessingFlag[cInst["CpmmNumber"]] = (string) cInst["Special_Processing_Flag"]; } else { // there may not be the keyword Special_Processing_Flag if no //keyword then set the output to NOMINAL specialProcessingFlag[cInst["CpmmNumber"]] = "NOMINAL"; } } // Get the blob of original labels from first image in list OriginalLabel org; clist[0]->Read(org); //close all cubes for (int i=0; i<(int)clist.size(); i++) { clist[i]->Close(); delete clist[i]; } clist.clear(); // automos step string list = ui.GetFilename("FROMLIST"); string toMosaic = ui.GetFilename("TO"); string MosaicPriority = ui.GetString("PRIORITY"); string parameters = "FROMLIST=" + list + " MOSAIC=" + toMosaic + " PRIORITY=" + MosaicPriority; Isis::iApp ->Exec("automos",parameters); // write out new information to new group mosaic PvlGroup mos("Mosaic"); mos += PvlKeyword("ProductId ", ProdId); mos += PvlKeyword(sourceProductId); mos += PvlKeyword("StartTime ", startTime); mos += PvlKeyword("SpacecraftClockStartCount ", startClock); mos += PvlKeyword("StopTime ", stopTime); mos += PvlKeyword("SpacecraftClockStopCount ", stopClock); mos += PvlKeyword("IncidenceAngle ", Cincid, "DEG"); mos += PvlKeyword("EmissionAngle ", Cemiss, "DEG"); mos += PvlKeyword("PhaseAngle ", Cphase, "DEG"); mos += PvlKeyword("LocalTime ", ClocalSolTime, "LOCALDAY/24"); mos += PvlKeyword("SolarLongitude ", CsolarLong, "DEG"); mos += PvlKeyword("SubSolarAzimuth ", CsunAzimuth, "DEG"); mos += PvlKeyword("NorthAzimuth ", CnorthAzimuth, "DEG"); mos += cpmmTdiFlag; mos += cpmmSummingFlag; mos += specialProcessingFlag; Cube mosCube; mosCube.Open(ui.GetFilename("TO"), "rw"); PvlObject &lab=mosCube.Label()->FindObject("IsisCube"); lab.AddGroup(mos); //add orginal label blob to the output cube mosCube.Write(org); mosCube.Close(); } catch (iException &e) { for (int i=0; i<(int)clist.size(); i++) { clist[i]->Close(); delete clist[i]; } string msg = "The mosaic [" + ui.GetFilename("TO") + "] was NOT created"; throw iException::Message(iException::User,msg,_FILEINFO_); } } // end of isis main