// Main program void IsisMain() { ProcessImportPds p; Pvl pdsLabel; UserInterface &ui = Application::GetUserInterface(); FileName inFile = ui.GetFileName("FROM"); p.SetPdsFile(inFile.expanded(), "", pdsLabel); QString filename = FileName(ui.GetFileName("FROM")).baseName(); FileName toFile = ui.GetFileName("TO"); apollo = new Apollo(filename); utcTime = (QString)pdsLabel["START_TIME"]; // Setup the output cube attributes for a 16-bit unsigned tiff Isis::CubeAttributeOutput cao; cao.setPixelType(Isis::Real); p.SetOutputCube(toFile.expanded(), cao); // Import image p.StartProcess(); p.EndProcess(); cube.open(toFile.expanded(), "rw"); // Once the image is imported, we need to find and decrypt the code if (apollo->IsMetric() && FindCode()) TranslateCode(); CalculateTransform(); // Once we have decrypted the code, we need to populate the image labels TranslateApolloLabels(filename, &cube); cube.close(); }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); try { // Open the cube Cube cube; cube.open(ui.GetFileName("FROM"), "rw"); //check for existing polygon, if exists delete it if(cube.label()->hasObject("Polygon")) { cube.label()->deleteObject("Polygon"); } // Get the camera, interpolate to a parabola Camera *cam = cube.camera(); if(cam->DetectorMap()->LineRate() == 0.0) { QString msg = "[" + ui.GetFileName("FROM") + "] is not a line scan camera"; throw IException(IException::User, msg, _FILEINFO_); } cam->instrumentRotation()->SetPolynomial(); // Get the instrument pointing keyword from the kernels group and update // its value to table. Isis::PvlGroup kernels = cube.label()->findGroup("Kernels", Isis::Pvl::Traverse); // Save original kernels in keyword before changing to "Table" in the kernels group PvlKeyword origCk = kernels["InstrumentPointing"]; // Write out the "Table" label to the tabled kernels in the kernels group kernels["InstrumentPointing"] = "Table"; // And finally write out the original kernels after Table for (int i = 0; i < origCk.size(); i++) { kernels["InstrumentPointing"].addValue(origCk[i]); } cube.putGroup(kernels); // Pull out the pointing cache as a table and write it Table cmatrix = cam->instrumentRotation()->Cache("InstrumentPointing"); cmatrix.Label().addComment("Smoothed using spicefit"); cube.write(cmatrix); cube.close(); } catch(IException &e) { QString msg = "Unable to fit pointing for [" + ui.GetFileName("FROM") + "]"; throw IException(IException::User, msg, _FILEINFO_); } }
void IsisMain() { // Create a serial number list UserInterface &ui = Application::GetUserInterface(); QString filename = ui.GetFileName("FROM"); SerialNumberList serialNumberList; serialNumberList.Add(filename); // Get the coordinate for updating the camera pointing // We will want to make the camera pointing match the lat/lon at this // line sample double samp1 = ui.GetDouble("SAMP1"); double line1 = ui.GetDouble("LINE1"); Latitude lat1(ui.GetDouble("LAT1"), Angle::Degrees); Longitude lon1(ui.GetDouble("LON1"), Angle::Degrees); Distance rad1; if(ui.WasEntered("RAD1")) { rad1 = Distance(ui.GetDouble("RAD1"), Distance::Meters); } else { rad1 = GetRadius(ui.GetFileName("FROM"), lat1, lon1); } // In order to use the bundle adjustment class we will need a control // network ControlMeasure * m = new ControlMeasure; m->SetCubeSerialNumber(serialNumberList.SerialNumber(0)); m->SetCoordinate(samp1, line1); // m->SetType(ControlMeasure::Manual); m->SetType(ControlMeasure::RegisteredPixel); ControlPoint * p = new ControlPoint; p->SetAprioriSurfacePoint(SurfacePoint(lat1, lon1, rad1)); p->SetId("Point1"); p->SetType(ControlPoint::Fixed); p->Add(m); ControlNet cnet; // cnet.SetType(ControlNet::ImageToGround); cnet.AddPoint(p); // We need the target body Cube c; c.open(filename, "rw"); //check for target name if(c.label()->hasKeyword("TargetName", PvlObject::Traverse)) { // c.Label()->findKeyword("TargetName"); PvlGroup inst = c.label()->findGroup("Instrument", PvlObject::Traverse); QString targetName = inst["TargetName"]; cnet.SetTarget(targetName); } c.close(); // See if they wanted to solve for twist if(ui.GetBoolean("TWIST")) { double samp2 = ui.GetDouble("SAMP2"); double line2 = ui.GetDouble("LINE2"); Latitude lat2(ui.GetDouble("LAT2"), Angle::Degrees); Longitude lon2(ui.GetDouble("LON2"), Angle::Degrees); Distance rad2; if(ui.WasEntered("RAD2")) { rad2 = Distance(ui.GetDouble("RAD2"), Distance::Meters); } else { rad2 = GetRadius(ui.GetFileName("FROM"), lat2, lon2); } ControlMeasure * m = new ControlMeasure; m->SetCubeSerialNumber(serialNumberList.SerialNumber(0)); m->SetCoordinate(samp2, line2); m->SetType(ControlMeasure::Manual); ControlPoint * p = new ControlPoint; p->SetAprioriSurfacePoint(SurfacePoint(lat2, lon2, rad2)); p->SetId("Point2"); p->SetType(ControlPoint::Fixed); p->Add(m); cnet.AddPoint(p); } // Bundle adjust to solve for new pointing try { BundleAdjust b(cnet, serialNumberList); b.SetSolveTwist(ui.GetBoolean("TWIST")); // double tol = ui.GetDouble("TOL"); //int maxIterations = ui.GetInteger("MAXITS"); //b.Solve(tol, maxIterations); b.SetSolveCmatrix(BundleAdjust::AnglesOnly); b.SetSolveSpacecraftPosition(BundleAdjust::Nothing); b.SetErrorPropagation(false); b.SetOutlierRejection(false); b.SetSolutionMethod("SPECIALK"); b.SetStandardOutput(true); b.SetCSVOutput(false); b.SetResidualOutput(true); b.SetConvergenceThreshold(ui.GetDouble("SIGMA0")); b.SetMaxIterations(ui.GetInteger("MAXITS")); b.SetDecompositionMethod(BundleAdjust::SPECIALK); b.SolveCholesky(); Cube c; c.open(filename, "rw"); //check for existing polygon, if exists delete it if(c.label()->hasObject("Polygon")) { c.label()->deleteObject("Polygon"); } Table cmatrix = b.Cmatrix(0); // Write out a description in the spice table QString deltackComment = "deltackAdjusted = " + Isis::iTime::CurrentLocalTime(); cmatrix.Label().addComment(deltackComment); //PvlKeyword description("Description"); //description = "Camera pointing updated via deltack application"; //cmatrix.Label().findObject("Table",Pvl::Traverse).addKeyword(description); // Update the cube history c.write(cmatrix); History h("IsisCube"); c.read(h); h.AddEntry(); c.write(h); c.close(); PvlGroup gp("DeltackResults"); gp += PvlKeyword("Status", "Camera pointing updated"); Application::Log(gp); } catch(IException &e) { QString msg = "Unable to update camera pointing for [" + filename + "]"; throw IException(e, IException::Unknown, 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) { QString msg = "the list file [" + ui.GetFileName("FROMLIST") + "does not contain any data"; throw IException(IException::User, msg, _FILEINFO_); } // open all the cube and place in vector clist for(int i = 0; i < flist.size(); i++) { Cube *c = new Cube(); clist.push_back(c); c->open(flist[i].toString()); } // run the compair function here. This will conpair the // labels of the first cube to the labels of each following cube. PvlKeyword sourceProductId("SourceProductId"); QString ProdId; for(int i = 0; i < (int)clist.size(); i++) { Pvl *pmatch = clist[0]->label(); Pvl *pcomp = clist[i]->label(); CompareLabels(*pmatch, *pcomp); PvlGroup g = pcomp->findGroup("Instrument", Pvl::Traverse); if(g.hasKeyword("StitchedProductIds")) { PvlKeyword k = g["StitchedProductIds"]; for(int j = 0; j < (int)k.size(); j++) { sourceProductId += g["stitchedProductIds"][j]; } } ProdId = (QString)pmatch->findGroup("Archive", Pvl::Traverse)["ObservationId"]; QString bandname = (QString)pmatch->findGroup("BandBin", Pvl::Traverse)["Name"]; bandname = bandname.toUpper(); ProdId = ProdId + "_" + bandname; } bool runXY = true; //calculate the min and max lon double minLat = DBL_MAX; double maxLat = -DBL_MAX; double minLon = DBL_MAX; double maxLon = -DBL_MAX; double avgLat; double avgLon; for(int i = 0; i < (int)clist.size(); i++) { TProjection *proj = (TProjection *) clist[i]->projection(); if(proj->MinimumLatitude() < minLat) minLat = proj->MinimumLatitude(); if(proj->MaximumLatitude() > maxLat) maxLat = proj->MaximumLatitude(); if(proj->MinimumLongitude() < minLon) minLon = proj->MinimumLongitude(); if(proj->MaximumLongitude() > maxLon) maxLon = proj->MaximumLongitude(); } avgLat = (minLat + maxLat) / 2; avgLon = (minLon + maxLon) / 2; TProjection *proj = (TProjection *) clist[0]->projection(); proj->SetGround(avgLat, avgLon); avgLat = proj->UniversalLatitude(); avgLon = proj->UniversalLongitude(); // Use camera class to get Inc., emi., phase, and other values double Cemiss; double Cphase; double Cincid; double ClocalSolTime; double CsolarLong; double CsunAzimuth; double CnorthAzimuth; for(int i = 0; i < (int)clist.size(); i++) { Camera *cam = clist[i]->camera(); if(cam->SetUniversalGround(avgLat, avgLon)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->solarLongitude().degrees(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } //The code within the if runXY was added in 10/07 to find an intersect with //pole images that would fail when using projection set universal ground. // This is run if no intersect is found when using lat and lon in // projection space. if(runXY) { double startX = DBL_MAX; double endX = DBL_MIN; double startY = DBL_MAX; double endY = DBL_MIN; for(int i = 0; i < (int)clist.size(); i++) { TProjection *proj = (TProjection *) clist[i]->projection(); proj->SetWorld(0.5, 0.5); if(i == 0) { startX = proj->XCoord(); endY = proj->YCoord(); } else { if(proj->XCoord() < startX) startX = proj->XCoord(); if(proj->YCoord() > endY) endY = proj->YCoord(); } Pvl *p = clist[i]->label(); double nlines = p->findGroup("Dimensions", Pvl::Traverse)["Lines"]; double nsamps = p->findGroup("Dimensions", Pvl::Traverse)["Samples"]; proj->SetWorld((nsamps + 0.5), (nlines + 0.5)); if(i == 0) { endX = proj->XCoord(); startY = proj->YCoord(); } else { if(proj->XCoord() > endX) endX = proj->XCoord(); if(proj->YCoord() < startY) startY = proj->YCoord(); } } double avgX = (startX + endX) / 2; double avgY = (startY + endY) / 2; double sample = proj->ToWorldX(avgX); double line = proj->ToWorldY(avgY); for(int i = 0; i < (int)clist.size(); i++) { Camera *cam = clist[i]->camera(); if(cam->SetImage(sample, line)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->solarLongitude().degrees(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } } if(runXY) { QString msg = "Camera did not intersect images to gather stats"; throw IException(IException::User, msg, _FILEINFO_); } // get the min and max SCLK values ( do this with QString comp.) // get the value from the original label blob QString startClock; QString stopClock; QString startTime; QString stopTime; for(int i = 0; i < (int)clist.size(); i++) { OriginalLabel origLab; clist[i]->read(origLab); PvlGroup timegrp = origLab.ReturnLabels().findGroup("TIME_PARAMETERS", Pvl::Traverse); if(i == 0) { startClock = (QString)timegrp["SpacecraftClockStartCount"]; stopClock = (QString)timegrp["SpacecraftClockStopCount"]; startTime = (QString)timegrp["StartTime"]; stopTime = (QString)timegrp["StopTime"]; } else { QString testStartTime = (QString)timegrp["StartTime"]; QString testStopTime = (QString)timegrp["StopTime"]; if(testStartTime < startTime) { startTime = testStartTime; startClock = (QString)timegrp["SpacecraftClockStartCount"]; } if(testStopTime > stopTime) { stopTime = testStopTime; stopClock = (QString)timegrp["spacecraftClockStopCount"]; } } } // Concatenate all TDI's and summing and specialProcessingFlat into one keyword PvlKeyword cpmmTdiFlag("cpmmTdiFlag"); PvlKeyword cpmmSummingFlag("cpmmSummingFlag"); PvlKeyword specialProcessingFlag("SpecialProcessingFlag"); for(int i = 0; i < 14; i++) { cpmmTdiFlag += (QString)""; cpmmSummingFlag += (QString)""; specialProcessingFlag += (QString)""; } for(int i = 0; i < (int)clist.size(); i++) { Pvl *clab = clist[i]->label(); PvlGroup cInst = clab->findGroup("Instrument", Pvl::Traverse); OriginalLabel cOrgLab; clist[i]->read(cOrgLab); PvlGroup cGrp = cOrgLab.ReturnLabels().findGroup("INSTRUMENT_SETTING_PARAMETERS", Pvl::Traverse); cpmmTdiFlag[(int)cInst["CpmmNumber"]] = (QString) cGrp["MRO:TDI"]; cpmmSummingFlag[(int)cInst["CpmmNumber"]] = (QString) cGrp["MRO:BINNING"]; if(cInst.hasKeyword("Special_Processing_Flag")) { specialProcessingFlag[cInst["CpmmNumber"]] = (QString) cInst["Special_Processing_Flag"]; } else { // there may not be the keyword Special_Processing_Flag if no //keyword then set the output to NOMINAL specialProcessingFlag[cInst["CpmmNumber"]] = "NOMINAL"; } } // Get the blob of original labels from first image in list OriginalLabel org; clist[0]->read(org); //close all cubes for(int i = 0; i < (int)clist.size(); i++) { clist[i]->close(); delete clist[i]; } clist.clear(); // automos step QString list = ui.GetFileName("FROMLIST"); QString toMosaic = ui.GetFileName("TO"); QString MosaicPriority = ui.GetString("PRIORITY"); QString parameters = "FROMLIST=" + list + " MOSAIC=" + toMosaic + " PRIORITY=" + MosaicPriority; ProgramLauncher::RunIsisProgram("automos", parameters); // write out new information to new group mosaic PvlGroup mos("Mosaic"); mos += PvlKeyword("ProductId ", ProdId); mos += PvlKeyword(sourceProductId); mos += PvlKeyword("StartTime ", startTime); mos += PvlKeyword("SpacecraftClockStartCount ", startClock); mos += PvlKeyword("StopTime ", stopTime); mos += PvlKeyword("SpacecraftClockStopCount ", stopClock); mos += PvlKeyword("IncidenceAngle ", toString(Cincid), "DEG"); mos += PvlKeyword("EmissionAngle ", toString(Cemiss), "DEG"); mos += PvlKeyword("PhaseAngle ", toString(Cphase), "DEG"); mos += PvlKeyword("LocalTime ", toString(ClocalSolTime), "LOCALDAY/24"); mos += PvlKeyword("SolarLongitude ", toString(CsolarLong), "DEG"); mos += PvlKeyword("SubSolarAzimuth ", toString(CsunAzimuth), "DEG"); mos += PvlKeyword("NorthAzimuth ", toString(CnorthAzimuth), "DEG"); mos += cpmmTdiFlag; mos += cpmmSummingFlag; mos += specialProcessingFlag; Cube mosCube; mosCube.open(ui.GetFileName("TO"), "rw"); PvlObject &lab = mosCube.label()->findObject("IsisCube"); lab.addGroup(mos); //add orginal label blob to the output cube mosCube.write(org); mosCube.close(); } catch(IException &e) { for(int i = 0; i < (int)clist.size(); i++) { clist[i]->close(); delete clist[i]; } QString msg = "The mosaic [" + ui.GetFileName("TO") + "] was NOT created"; throw IException(IException::User, msg, _FILEINFO_); } } // end of isis main
void IsisMain() { // Get the list of cubes to stack Process p; UserInterface &ui = Application::GetUserInterface(); FileList cubeList(ui.GetFileName("FROMLIST")); // Loop through the list int nsamps(0), nlines(0), nbands(0); PvlGroup outBandBin("BandBin"); try { for(int i = 0; i < cubeList.size(); i++) { Cube cube; CubeAttributeInput inatt(cubeList[i].original()); vector<QString> bands = inatt.bands(); cube.setVirtualBands(bands); cube.open(cubeList[i].toString()); if(i == 0) { nsamps = cube.sampleCount(); nlines = cube.lineCount(); nbands = cube.bandCount(); } else { // Make sure they are all the same size if((nsamps != cube.sampleCount()) || (nlines != cube.lineCount())) { QString msg = "Spatial dimensions of cube [" + cubeList[i].toString() + "] does not match other cubes in list"; throw IException(IException::User, msg, _FILEINFO_); } // Get the total number of bands nbands += cube.bandCount(); } // Build up the band bin group PvlObject &isiscube = cube.label()->findObject("IsisCube"); if(isiscube.hasGroup("BandBin")) { PvlGroup &inBandBin = isiscube.findGroup("BandBin"); for(int key = 0; key < inBandBin.keywords(); key++) { PvlKeyword &inKey = inBandBin[key]; if(!outBandBin.hasKeyword(inKey.name())) { outBandBin += inKey; } else { PvlKeyword &outKey = outBandBin[inKey.name()]; for(int index = 0; index < (int)inKey.size(); index++) { outKey.addValue(inKey[index], inKey.unit(index)); } } } } cube.close(); } } catch(IException &e) { QString msg = "Invalid cube in list file [" + ui.GetFileName("FROMLIST") + "]"; throw IException(e, IException::User, msg, _FILEINFO_); } // Setup to propagate from the first input cube ProcessByLine p2; CubeAttributeInput inatt; int index = 0; if(ui.WasEntered("PROPLAB")) { bool match = false; QString fname = ui.GetFileName("PROPLAB"); for(int i = 0; i < cubeList.size(); i++) { if(fname == cubeList[i].toString()) { index = i; match = true; break; } } if(!match) { QString msg = "FileName [" + ui.GetFileName("PROPLAB") + "] to propagate labels from is not in the list file [" + ui.GetFileName("FROMLIST") + "]"; throw IException(IException::User, msg, _FILEINFO_); } } p2.SetInputCube(cubeList[index].toString(), inatt); // Create the output cube Cube *ocube = p2.SetOutputCube("TO", nsamps, nlines, nbands); p2.ClearInputCubes(); p2.Progress()->SetText("Allocating cube"); p2.StartProcess(NullBand); // Add the band bin group if necessary if(outBandBin.keywords() > 0) { ocube->putGroup(outBandBin); } p2.EndProcess(); // Now loop and mosaic in each cube int sband = 1; for(int i = 0; i < cubeList.size(); i++) { ProcessMosaic m; m.SetBandBinMatch(false); Progress *prog = m.Progress(); prog->SetText("Adding band " + toString((int)i + 1) + " of " + toString(nbands)); m.SetOutputCube("TO"); CubeAttributeInput attrib(cubeList[i].toString()); Cube *icube = m.SetInputCube(cubeList[i].toString(), attrib); m.SetImageOverlay(ProcessMosaic::PlaceImagesOnTop); m.StartProcess(1, 1, sband); sband += icube->bandCount(); m.EndProcess(); } }
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; }
/** * We created a method to manually skip the suffix and corner * data for this image to avoid implementing it in * ProcessImport and ProcessImportPds. To fully support this * file format, we would have to re-implement the ISIS2 Cube * IO plus add prefix data features to it. This is a shortcut; * because we know these files have one sideplane and four * backplanes, we know how much data to skip when. This should * be fixed if we ever decide to fully support suffix and * corner data, which would require extensive changes to * ProcessImport/ProcessImportPds. Method written by Steven * Lambright. * * @param inFileName FileName of the input file * @param outFile FileName of the output file */ void ReadVimsBIL(QString inFileName, const PvlKeyword &suffixItems, QString outFile) { Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory"); QString transDir = (QString) dataDir["Base"]; Pvl pdsLabel(inFileName); Isis::FileName transFile(transDir + "/" + "translations/pdsQube.trn"); Isis::PvlTranslationManager pdsXlater(pdsLabel, transFile.expanded()); TableField sideplaneLine("Line", Isis::TableField::Integer); TableField sideplaneBand("Band", Isis::TableField::Integer); TableField sideplaneValue("Value", Isis::TableField::Integer); TableRecord record; record += sideplaneLine; record += sideplaneBand; record += sideplaneValue; Table sideplaneVisTable("SideplaneVis", record); Table sideplaneIrTable("SideplaneIr", record); sideplaneVisTable.SetAssociation(Table::Lines); sideplaneIrTable.SetAssociation(Table::Lines); QString str; str = pdsXlater.Translate("CoreBitsPerPixel"); int bitsPerPixel = toInt(str); str = pdsXlater.Translate("CorePixelType"); PixelType pixelType = Isis::Real; if((str == "Real") && (bitsPerPixel == 32)) { pixelType = Isis::Real; } else if((str == "Integer") && (bitsPerPixel == 8)) { pixelType = Isis::UnsignedByte; } else if((str == "Integer") && (bitsPerPixel == 16)) { pixelType = Isis::SignedWord; } else if((str == "Integer") && (bitsPerPixel == 32)) { pixelType = Isis::SignedInteger; } else if((str == "Natural") && (bitsPerPixel == 8)) { pixelType = Isis::UnsignedByte; } else if((str == "Natural") && (bitsPerPixel == 16)) { pixelType = Isis::UnsignedWord; } else if((str == "Natural") && (bitsPerPixel == 16)) { pixelType = Isis::SignedWord; } else if((str == "Natural") && (bitsPerPixel == 32)) { pixelType = Isis::UnsignedInteger; } else { QString msg = "Invalid PixelType and BitsPerPixel combination [" + str + ", " + toString(bitsPerPixel) + "]"; throw IException(IException::Io, msg, _FILEINFO_); } str = pdsXlater.Translate("CoreByteOrder"); Isis::ByteOrder byteOrder = Isis::ByteOrderEnumeration(str); str = pdsXlater.Translate("CoreSamples", 0); int ns = toInt(str); str = pdsXlater.Translate("CoreLines", 2); int nl = toInt(str); str = pdsXlater.Translate("CoreBands", 1); int nb = toInt(str); std::vector<double> baseList; std::vector<double> multList; str = pdsXlater.Translate("CoreBase"); baseList.clear(); baseList.push_back(toDouble(str)); str = pdsXlater.Translate("CoreMultiplier"); multList.clear(); multList.push_back(toDouble(str)); Cube outCube; outCube.setPixelType(Isis::Real); outCube.setDimensions(ns, nl, nb); outCube.create(outFile); // Figure out the number of bytes to read for a single line int readBytes = Isis::SizeOf(pixelType); readBytes = readBytes * ns; char *in = new char [readBytes]; // Set up an Isis::EndianSwapper object QString tok(Isis::ByteOrderName(byteOrder)); tok = tok.toUpper(); Isis::EndianSwapper swapper(tok); ifstream fin; // Open input file Isis::FileName inFile(inFileName); fin.open(inFileName.toAscii().data(), ios::in | ios::binary); if(!fin.is_open()) { QString msg = "Cannot open input file [" + inFileName + "]"; throw IException(IException::Io, msg, _FILEINFO_); } // Handle the file header streampos pos = fin.tellg(); int fileHeaderBytes = (int)(IString)pdsXlater.Translate("DataFileRecordBytes") * ((int)(IString)pdsXlater.Translate("DataStart", 0) - 1); fin.seekg(fileHeaderBytes, ios_base::beg); // Check the last io if(!fin.good()) { QString msg = "Cannot read file [" + inFileName + "]. Position [" + toString((int)pos) + "]. Byte count [" + toString(fileHeaderBytes) + "]" ; throw IException(IException::Io, msg, _FILEINFO_); } // Construct a line buffer manager Isis::Brick out(ns, 1, 1, Isis::Real); // Loop for each line for(int line = 0; line < nl; line++) { // Loop for each band for(int band = 0; band < nb; band++) { // Set the base multiplier double base, mult; if(baseList.size() > 1) { base = baseList[band]; mult = multList[band]; } else { base = baseList[0]; mult = multList[0]; } // Get a line of data from the input file pos = fin.tellg(); fin.read(in, readBytes); if(!fin.good()) { QString msg = "Cannot read file [" + inFileName + "]. Position [" + toString((int)pos) + "]. Byte count [" + toString(readBytes) + "]" ; throw IException(IException::Io, msg, _FILEINFO_); } // Swap the bytes if necessary and convert any out of bounds pixels // to special pixels for(int samp = 0; samp < ns; samp++) { switch(pixelType) { case Isis::UnsignedByte: out[samp] = (double)((unsigned char *)in)[samp]; break; case Isis::UnsignedWord: out[samp] = (double)swapper.UnsignedShortInt((unsigned short int *)in + samp); break; case Isis::SignedWord: out[samp] = (double)swapper.ShortInt((short int *)in + samp); break; case Isis::Real: out[samp] = (double)swapper.Float((float *)in + samp); break; default: break; } // Sets out to isis special pixel or leaves it if valid out[samp] = TestPixel(out[samp]); if(Isis::IsValidPixel(out[samp])) { out[samp] = mult * out[samp] + base; } } // End sample loop //Set the buffer position and write the line to the output file out.SetBasePosition(1, line + 1, band + 1); outCube.write(out); if(toInt(suffixItems[0]) != 0) { pos = fin.tellg(); char *sideplaneData = new char[4*toInt(suffixItems[0])]; fin.read(sideplaneData, 4 * toInt(suffixItems[0])); int suffixData = (int)swapper.Int((int *)sideplaneData); record[0] = line + 1; record[1] = band + 1; record[2] = suffixData; if(band < 96) { sideplaneVisTable += record; // set HIS pixels appropriately for(int samp = 0; samp < ns; samp++) { if(out[samp] >= 4095) { out[samp] = Isis::His; } } } else { record[1] = (band + 1) - 96; sideplaneIrTable += record; // set HIS pixels appropriately for(int samp = 0; samp < ns; samp++) { if(out[samp] + suffixData >= 4095) { out[samp] = Isis::His; } } } delete [] sideplaneData; // Check the last io if(!fin.good()) { QString msg = "Cannot read file [" + inFileName + "]. Position [" + toString((int)pos) + "]. Byte count [" + toString(4) + "]" ; throw IException(IException::Io, msg, _FILEINFO_); } } } // End band loop int backplaneSize = toInt(suffixItems[1]) * (4 * (ns + toInt(suffixItems[0]))); fin.seekg(backplaneSize, ios_base::cur); // Check the last io if(!fin.good()) { QString msg = "Cannot read file [" + inFileName + "]. Position [" + toString((int)pos) + "]. Byte count [" + toString(4 * (4 * ns + 4)) + "]" ; throw IException(IException::Io, msg, _FILEINFO_); } } // End line loop outCube.write(sideplaneVisTable); outCube.write(sideplaneIrTable); // Close the file and clean up fin.close(); outCube.close(); delete [] in; }
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(); }
int main() { Preference::Preferences(true); QString inputFile = "$mgs/testData/ab102401.lev2.cub"; Cube cube; cube.open(inputFile); Camera *c = NULL; c = cube.camera(); Pvl pvl = *cube.label(); MyCamera cam(cube); double line = 453.0; double sample = 534.0; Latitude lat(18.221, Angle::Degrees); Longitude lon(226.671, Angle::Degrees); double ra = 347.016; double dec = -51.2677; cout << endl << "Camera* from: " << inputFile << endl; QList<QPointF> ifovOffsets = c->PixelIfovOffsets(); cout << "Pixel Ifov: " << endl; foreach (QPointF offset, ifovOffsets) { cout << offset.x() << " , " << offset.y() << endl; } cout << "Line: " << line << ", Sample: " << sample << endl; cout << "Lat: " << lat.degrees() << ", Lon: " << lon.degrees() << endl; cout << "RightAscension: " << ra << ", Declination: " << dec << endl << endl; cout << "SetImage (sample, line): " << c->SetImage(sample, line) << endl << endl; cout << "NorthAzimuth: " << c->NorthAzimuth() << endl; cout << "SunAzimuth: " << c->SunAzimuth() << endl; cout << "SpacecraftAzimuth: " << c->SpacecraftAzimuth() << endl; cout << "OffNadirAngle: " << c->OffNadirAngle() << endl << endl; cout << "GroundAzimuth in North: " << c->GroundAzimuth(18.221, 226.671, 20.0, 230.0) << endl; cout << "GroundAzimuth in North: " << c->GroundAzimuth(20.0, 226.671, 20.0, 230.0) << endl; cout << "GroundAzimuth in North: " << c->GroundAzimuth(18.221, 355.0, 20.0, 6.671) << endl; cout << "GroundAzimuth in North: " << c->GroundAzimuth(18.221, 6.671, 20.0, 355.0) << endl; cout << "GroundAzimuth in North: " << c->GroundAzimuth(18.221, 6.671, 20.0, 6.671) << endl; cout << "GroundAzimuth in South: " << c->GroundAzimuth(-18.221, 226.671, -20.0, 230.0) << endl; cout << "GroundAzimuth in South: " << c->GroundAzimuth(-20.0, 226.671, -20.0, 230.0) << endl; cout << "GroundAzimuth in South: " << c->GroundAzimuth(-18.221, 355.0, -20.0, 6.671) << endl; cout << "GroundAzimuth in South: " << c->GroundAzimuth(-18.221, 6.671, -20.0, 355.0) << endl; cout << "GroundAzimuth in South: " << c->GroundAzimuth(-18.221, 6.671, -20.0, 6.671) << endl << endl; cout << "SetUniversalGround(lat, lon): " << c->SetGround(lat, lon) << endl; cout << "SetRightAscensionDeclination(ra, dec): " << c->SetRightAscensionDeclination(ra, dec) << endl; cout << "HasProjection: " << c->HasProjection() << endl; cam.IsBandIndependent(); cout << "ReferenceBand: " << c->ReferenceBand() << endl; cout << "HasReferenceBand: " << c->HasReferenceBand() << endl; cam.SetBand(7); cout << "Sample: " << setprecision(3) << c->Sample() << endl; cout << "Line: " << setprecision(3) << c->Line() << endl; try { double lat = 0, lon = 0; cout << "GroundRange: " << c->GroundRange(lat, lat, lon, lon, pvl) << endl; cout << "IntersectsLongitudeDomain: " << c->IntersectsLongitudeDomain(pvl) << endl; } catch(IException &e) { cout << "No mapping group found, so GroundRange and " << endl << "IntersectsLongitudeDomain cannot run." << endl; } cout << "PixelResolution: " << c->PixelResolution() << endl; cout << "LineResolution: " << c->LineResolution() << endl; cout << "SampleResolution: " << c->SampleResolution() << endl; cout << "DetectorResolution: " << c->DetectorResolution() << endl; cout << "LowestImageResolution: " << setprecision(4) << c->LowestImageResolution() << endl; cout << "HighestImageResolution: " << setprecision(3) << c->HighestImageResolution() << endl; cout << "Calling BasicMapping (pvl)..." << endl; c->BasicMapping(pvl); double pixRes2 = pvl.findGroup("Mapping")["PixelResolution"]; pixRes2 *= 10000000; pixRes2 = round(pixRes2); pixRes2 /= 10000000; pvl.findGroup("Mapping")["PixelResolution"] = toString(pixRes2); cout << "BasicMapping PVL: " << endl << pvl << endl << endl; cout << "FocalLength: " << c->FocalLength() << endl; cout << "PixelPitch: " << c->PixelPitch() << endl; cout << "Samples: " << c->Samples() << endl; cout << "Lines: " << c->Lines() << endl; cout << "Bands: " << c->Bands() << endl; cout << "ParentLines: " << c->ParentLines() << endl; cout << "ParentSamples: " << c->ParentSamples() << endl; try { cout << c->RaDecRange(ra, ra, dec, dec) << endl; } catch(IException &e) { e.print(); } try { cout << c->RaDecResolution() << endl; } catch(IException &e) { e.print(); } cout << "Calling Distortion, FocalPlane, "; cout << "Detector, Ground, and Sky Map functions... "; c->DistortionMap(); c->FocalPlaneMap(); c->DetectorMap(); c->GroundMap(); c->SkyMap(); cout << "Done." << endl; cout << "Calling IgnoreProjection (false)..." << endl; c->IgnoreProjection(false); cout << endl << "Testing SetUniversalGround(lat,lon,radius)..." << endl; lat.setDegrees(18.221); lon.setDegrees(226.671); double radius = 3414033.72108798; c->SetUniversalGround(lat.degrees(), lon.degrees(), radius); c->SetGround(SurfacePoint(lat, lon, Distance(radius, Distance::Meters))); cout << "Has intersection " << c->HasSurfaceIntersection() << endl; cout << "Latitude = " << c->UniversalLatitude() << endl; cout << "Longitude = " << c->UniversalLongitude() << endl; cout << "Radius = " << c->LocalRadius().meters() << endl; double p[3]; c->Coordinate(p); cout << "Point = " << setprecision(4) << p[0] << " " << p[1] << " " << p[2] << endl << endl; cout << "Test Forward/Reverse Camera Calculations At Center Of Image..." << endl; sample = c->Samples() / 2.0; line = c->Lines() / 2.0; cout << "Sample = " << setprecision(3) << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << c->SetImage(sample, line) << endl; cout << "Latitude = " << c->UniversalLatitude() << endl; cout << "Longitude = " << c->UniversalLongitude() << endl; cout << "Radius = " << c->LocalRadius().meters() << endl; c->Coordinate(p); cout << "Point = " << setprecision(4) << p[0] << " " << p[1] << " " << p[2] << endl; cout << "SetUniversalGround (lat, lon, radius): " << c->SetUniversalGround(c->UniversalLatitude(), c->UniversalLongitude(), c->LocalRadius().meters()) << endl; cout << "Sample = " << c->Sample() << endl; cout << "Line = " << c->Line() << endl << endl; cout << endl << "/---------- Test Polar Boundary Conditions" << endl; inputFile = "$clementine1/testData/lub5992r.292.lev1.phot.cub"; cube.close(); cube.open(inputFile); pvl = *cube.label(); Camera *cam2 = CameraFactory::Create(cube); cube.close(); cout << endl; cout << "Camera* from: " << inputFile << endl; ifovOffsets = cam2->PixelIfovOffsets(); cout << "Pixel Ifov: " << endl; foreach (QPointF offset, ifovOffsets) { cout << offset.x() << " , " << offset.y() << endl; } cout << "Basic Mapping: " << endl; Pvl camMap; cam2->BasicMapping(camMap); double minLat = camMap.findGroup("Mapping")["MinimumLatitude"]; minLat *= 100; minLat = round(minLat); minLat /= 100; camMap.findGroup("Mapping")["MinimumLatitude"] = toString(minLat); double pixRes = camMap.findGroup("Mapping")["PixelResolution"]; pixRes *= 100; pixRes = round(pixRes); pixRes /= 100; camMap.findGroup("Mapping")["PixelResolution"] = toString(pixRes); double minLon = camMap.findGroup("Mapping")["MinimumLongitude"]; minLon *= 100000000000.0; minLon = round(minLon); minLon /= 100000000000.0; camMap.findGroup("Mapping")["MinimumLongitude"] = toString(minLon); cout << camMap << endl; cout << endl; cout << "180 Domain Range: " << endl; double minlat, maxlat, minlon, maxlon; camMap.findGroup("Mapping")["LongitudeDomain"][0] = "180"; cam2->GroundRange(minlat, maxlat, minlon, maxlon, camMap); cout << "Latitude Range: " << minlat << " to " << maxlat << endl; cout << "Longitude Range: " << minlon << " to " << maxlon << endl << endl; cout << "Test Forward/Reverse Camera Calculations At Center Of Image..." << endl; sample = cam2->Samples() / 2.0; line = cam2->Lines() / 2.0; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam2->SetImage(sample, line) << endl; cout << "Latitude = " << cam2->UniversalLatitude() << endl; cout << "Longitude = " << cam2->UniversalLongitude() << endl; cout << "Radius = " << cam2->LocalRadius().meters() << endl; cam2->Coordinate(p); cout << "Point = " << p[0] << " " << p[1] << " " << p[2] << endl; cout << "SetUniversalGround (cam2->UniversalLatitude(), " "cam2->UniversalLongitude()): " << cam2->SetUniversalGround(cam2->UniversalLatitude(), cam2->UniversalLongitude()) << endl; cout << "Sample = " << cam2->Sample() << endl; cout << "Line = " << cam2->Line() << endl << endl; cube.close(); delete cam2; cube.close(); cout << endl << "/---------- Test Local Photometric Angles..." << endl << endl; cout << "Flat DEM Surface..." << endl; inputFile = "$base/testData/f319b18_ideal_flat.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam3 = CameraFactory::Create(cube); cube.close(); sample = cam3->Samples() / 2.0; line = cam3->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam3->SetImage(sample, line) << endl; double normal[3]; cam3->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; Angle phase; Angle incidence; Angle emission; bool success; cam3->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam3; cout << endl << "45 Degree DEM Surface Facing Left..." << endl; inputFile = "$base/testData/f319b18_ideal_45left.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam4 = CameraFactory::Create(cube); cube.close(); sample = cam4->Samples() / 2.0; line = cam4->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam4->SetImage(sample, line) << endl; cam4->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam4->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam4; cout << endl << "45 Degree DEM Surface Facing Top..." << endl; inputFile = "$base/testData/f319b18_ideal_45top.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam5 = CameraFactory::Create(cube); cube.close(); sample = cam5->Samples() / 2.0; line = cam5->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam5->SetImage(sample, line) << endl; cam5->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam5->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam5; cout << endl << "45 Degree DEM Surface Facing Right..." << endl; inputFile = "$base/testData/f319b18_ideal_45right.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam6 = CameraFactory::Create(cube); cube.close(); sample = cam6->Samples() / 2.0; line = cam6->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam6->SetImage(sample, line) << endl; cam6->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam6->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam6; cout << endl << "45 Degree DEM Surface Facing Bottom..." << endl; inputFile = "$base/testData/f319b18_ideal_45bottom.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam7 = CameraFactory::Create(cube); cube.close(); sample = cam7->Samples() / 2.0; line = cam7->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam7->SetImage(sample, line) << endl; cam7->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam7->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam7; cout << endl << "80 Degree DEM Surface Facing Left..." << endl; inputFile = "$base/testData/f319b18_ideal_80left.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam8 = CameraFactory::Create(cube); cube.close(); sample = cam8->Samples() / 2.0; line = cam8->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam8->SetImage(sample, line) << endl; cam8->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam8->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam8; cout << endl << "80 Degree DEM Surface Facing Top..." << endl; inputFile = "$base/testData/f319b18_ideal_80top.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam9 = CameraFactory::Create(cube); cube.close(); sample = cam9->Samples() / 2.0; line = cam9->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam9->SetImage(sample, line) << endl; cam9->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam9->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam9; cout << endl << "80 Degree DEM Surface Facing Right..." << endl; inputFile = "$base/testData/f319b18_ideal_80right.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam10 = CameraFactory::Create(cube); cube.close(); sample = cam10->Samples() / 2.0; line = cam10->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam10->SetImage(sample, line) << endl; cam10->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam10->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam10; cout << endl << "80 Degree DEM Surface Facing Bottom..." << endl; inputFile = "$base/testData/f319b18_ideal_80bottom.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam11 = CameraFactory::Create(cube); cube.close(); sample = cam11->Samples() / 2.0; line = cam11->Lines() / 2.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam11->SetImage(sample, line) << endl; cam11->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam11->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam11; cout << endl << "Point Does Not Intersect DEM..." << endl; inputFile = "$base/testData/f319b18_ideal_flat.cub"; cube.open(inputFile); pvl = *cube.label(); Camera *cam12 = CameraFactory::Create(cube); cube.close(); sample = 1.0; line = 1.0; cout << "Camera* from: " << inputFile << endl; cout << "Sample = " << sample << endl; cout << "Line = " << line << endl; cout << "SetImage (sample, line): " << cam12->SetImage(sample, line) << endl; cam12->GetLocalNormal(normal); cout << "Normal = " << normal[0] << ", " << normal[1] << ", " << normal[2] << endl; cam12->LocalPhotometricAngles(phase,emission,incidence,success); if (success) { cout << "Phase = " << phase.degrees() << endl; cout << "Emission = " << emission.degrees() << endl; cout << "Incidence = " << incidence.degrees() << endl; } else { cout << "Angles could not be calculated." << endl; } delete cam12; // Test PixelIfov for Vims which sets the field of view if it in hires mode. The Ifov is // rectangular instead of square. inputFile = "$base/testData/CM_1515945709_1.ir.cub"; cube.open(inputFile); Camera *cam13 = CameraFactory::Create(cube); cube.close(); cout << endl << endl << "Testing non-square pixel Ifov using Hires vims cube" << endl; cout << "Camera* from: " << inputFile << endl; ifovOffsets = cam13->PixelIfovOffsets(); cout << "Pixel Ifov: " << endl; foreach (QPointF offset, ifovOffsets) { cout << offset.x() << " , " << offset.y() << endl; } delete cam13; }
void IsisMain() { Preference::Preferences(true); cout << "Testing Isis::ProcessMapMosaic Class ... " << endl; // Create the temp parent cube FileList cubes; cubes.read("unitTest.lis"); cout << "Testing Mosaic 1" << endl; ProcessMapMosaic m1; CubeAttributeOutput oAtt; ProcessMosaic::ImageOverlay priority = ProcessMapMosaic::PlaceImagesOnTop; m1.SetBandBinMatch(false); m1.SetOutputCube(cubes, oAtt, "./unitTest.cub"); //set priority m1.SetImageOverlay(priority); for(int i = 0; i < cubes.size(); i++) { if(m1.StartProcess(cubes[i].toString())) { cout << cubes[i].toString() << " is inside the mosaic" << endl; } else { cout << cubes[i].toString() << " is outside the mosaic" << endl; } } m1.EndProcess(); cout << "Mosaic label: " << endl; Pvl labels("./unitTest.cub"); cout << labels << endl; remove("./unitTest.cub"); cout << "Testing Mosaic 2" << endl; ProcessMapMosaic m2; m2.SetBandBinMatch(false); m2.SetOutputCube(cubes, -6, -4, 29, 31, oAtt, "./unitTest.cub"); //set priority m2.SetImageOverlay(priority); for(int i = 0; i < cubes.size(); i++) { if(m2.StartProcess(cubes[i].toString())) { cout << cubes[i].toString() << " is inside the mosaic" << endl; } else { cout << cubes[i].toString() << " is outside the mosaic" << endl; } } m2.EndProcess(); cout << "Mosaic label: " << endl; labels.clear(); labels.read("./unitTest.cub"); cout << labels << endl; Cube tmp; tmp.open("./unitTest.cub"); LineManager lm(tmp); lm.SetLine(1, 1); while(!lm.end()) { tmp.read(lm); cout << "Mosaic Data: " << lm[lm.SampleDimension()/4] << '\t' << lm[lm.SampleDimension()/2] << '\t' << lm[(3*lm.SampleDimension())/4] << endl; lm++; } tmp.close(); remove("./unitTest.cub"); // Create the temp parent cube cout << endl << "Testing Mosaic where the input (x, y) is negative," " according to the output cube." << endl; QString inputFile = "./unitTest1.cub"; Cube inCube; inCube.open(inputFile); PvlGroup mapGroup = inCube.label()->findGroup("Mapping", Pvl::Traverse); mapGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(-4.9)), Pvl::Replace); mapGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(-4.7)), Pvl::Replace); mapGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(30.7)), Pvl::Replace); mapGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(31)), Pvl::Replace); inCube.close(); CubeAttributeOutput oAtt2( FileName("./unitTest3.cub") ); ProcessMapMosaic m3; m3.SetBandBinMatch(false); m3.SetOutputCube(inputFile, mapGroup, oAtt2, "./unitTest3.cub"); //set priority m3.SetImageOverlay(priority); m3.SetHighSaturationFlag(false); m3.SetLowSaturationFlag(false); m3.SetNullFlag(false); if(m3.StartProcess(inputFile)) { cout << "The mosaic was successfull." << endl; } else { cout << "The mosaic was not successfull." << endl; } m3.EndProcess(); cout << "Mosaic label: " << endl; Pvl labels2("./unitTest3.cub"); cout << labels2 << endl; remove("./unitTest3.cub"); }
void IsisMain() { Isis::Preference::Preferences(true); UserInterface &ui = Application::GetUserInterface(); ProcessByLine p1; Pvl inlabel; Cube cube; int sl, ss; int el, es; double linc, sinc; int inl, ins; int onl, ons; p1.SetInputCube("FROM1"); QString from1 = ui.GetFileName("FROM1"); Cube inomapcube; inomapcube.open(from1); inl = inomapcube.lineCount(); ins = inomapcube.sampleCount(); sl = 1; ss = 1; el = inl; es = ins; linc = 1.0; sinc = 1.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); Cube *onomapcube = p1.SetOutputCube("TO", ons, onl, 1); PvlGroup results("Results"); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); SubArea s; s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&inomapcube, onomapcube, results); cout << "Input unprojected cube label: " << endl << endl; inlabel = *inomapcube.label(); cout << inlabel.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(inlabel.findObject("IsisCube").hasGroup("Instrument")) { cout << inlabel.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(inlabel.findObject("IsisCube").hasGroup("Mapping")) { cout << inlabel.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(inlabel.findObject("IsisCube").hasGroup("AlphaCube")) { cout << inlabel.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } cout << "Testing no change in image area for unprojected cube..." << endl << endl; Isis::Application::Log(results); cout << endl; p1.EndProcess(); cout << "Output cube label: " << endl << endl; QString file = ui.GetFileName("TO"); Pvl label(file); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } cube.open(file); cube.close(true); results.clear(); ProcessByLine p2; p2.SetInputCube("FROM1"); linc = 2.0; sinc = 2.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); onomapcube = p2.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&inomapcube, onomapcube, results); cout << "Testing full image area with linc=2, sinc=2 "; cout << "for unprojected cube..." << endl; Isis::Application::Log(results); cout << endl; p2.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p3; p3.SetInputCube("FROM1"); linc = 2.0; sinc = 3.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); onomapcube = p3.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&inomapcube, onomapcube, results); cout << "Testing full image area with linc=2, sinc=3 "; cout << "for unprojected cube..." << endl; Isis::Application::Log(results); cout << endl; p3.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p4; p4.SetInputCube("FROM1"); sl = 25; ss = 10; el = inl - 33; es = ins - 18; linc = .5; sinc = .5; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); onomapcube = p4.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&inomapcube, onomapcube, results); cout << "Testing sub image area with linc=.5, sinc=.5 "; cout << "for unprojected cube..." << endl; Isis::Application::Log(results); cout << endl; p4.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p5; p5.SetInputCube("FROM1"); linc = 1.0; sinc = 2.5; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); onomapcube = p5.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&inomapcube, onomapcube, results); cout << "Testing sub image area with linc=1.0, sinc=2.5 "; cout << "for unprojected cube..." << endl; Isis::Application::Log(results); cout << endl; p5.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } inomapcube.close(); results.clear(); ProcessByLine p6; p6.SetInputCube("FROM2"); QString from2 = ui.GetFileName("FROM2"); Cube imapcube; imapcube.open(from2); inl = imapcube.lineCount(); ins = imapcube.sampleCount(); sl = 1; ss = 1; el = inl; es = ins; linc = 1.0; sinc = 1.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); Cube *omapcube = p6.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&imapcube, omapcube, results); cout << "Input projected cube label: " << endl << endl; inlabel = *imapcube.label(); cout << inlabel.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(inlabel.findObject("IsisCube").hasGroup("Instrument")) { cout << inlabel.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(inlabel.findObject("IsisCube").hasGroup("Mapping")) { cout << inlabel.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(inlabel.findObject("IsisCube").hasGroup("AlphaCube")) { cout << inlabel.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } cout << "Testing no change in image area for projected cube..." << endl; Isis::Application::Log(results); cout << endl; p6.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p7; p7.SetInputCube("FROM2"); linc = 2.0; sinc = 2.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); omapcube = p7.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&imapcube, omapcube, results); cout << "Testing full image area with linc=2, sinc=2 "; cout << "for projected cube..." << endl; Isis::Application::Log(results); cout << endl; p7.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p8; p8.SetInputCube("FROM2"); linc = 2.0; sinc = 3.0; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); omapcube = p8.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&imapcube, omapcube, results); cout << "Testing full image area with linc=2, sinc=3 "; cout << "for projected cube..." << endl; Isis::Application::Log(results); cout << endl; p8.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p9; p9.SetInputCube("FROM2"); sl = 25; ss = 10; el = inl - 33; es = ins - 18; linc = .5; sinc = .5; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); omapcube = p9.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&imapcube, omapcube, results); cout << "Testing sub image area with linc=.5, sinc=.5 "; cout << "for projected cube..." << endl; Isis::Application::Log(results); cout << endl; p9.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } results.clear(); ProcessByLine p10; p10.SetInputCube("FROM2"); linc = 1.0; sinc = 2.5; onl = (int)ceil((double)(el - sl + 1) / linc); ons = (int)ceil((double)(es - ss + 1) / sinc); omapcube = p10.SetOutputCube("TO", ons, onl, 1); results += PvlKeyword("InputLines", toString(inl)); results += PvlKeyword("InputSamples", toString(ins)); results += PvlKeyword("StartingLine", toString(sl)); results += PvlKeyword("StartingSample", toString(ss)); results += PvlKeyword("EndingLine", toString(el)); results += PvlKeyword("EndingSample", toString(es)); results += PvlKeyword("LineIncrement", toString(linc)); results += PvlKeyword("SampleIncrement", toString(sinc)); results += PvlKeyword("OutputLines", toString(onl)); results += PvlKeyword("OutputSamples", toString(ons)); s.SetSubArea(inl, ins, sl, ss, el, es, linc, sinc); s.UpdateLabel(&imapcube, omapcube, results); cout << "Testing sub image area with linc=1.0, sinc=2.5 "; cout << "for projected cube..." << endl; Isis::Application::Log(results); cout << endl; p10.EndProcess(); cout << "Output cube label: " << endl << endl; cube.open(file); label = *cube.label(); cube.close(true); cout << label.findObject("IsisCube").findObject("Core").findGroup("Dimensions") << endl << endl; if(label.findObject("IsisCube").hasGroup("Instrument")) { cout << label.findObject("IsisCube").findGroup("Instrument") << endl << endl; } if(label.findObject("IsisCube").hasGroup("Mapping")) { cout << label.findObject("IsisCube").findGroup("Mapping") << endl << endl; } if(label.findObject("IsisCube").hasGroup("AlphaCube")) { cout << label.findObject("IsisCube").findGroup("AlphaCube") << endl << endl; } imapcube.close(); results.clear(); }
int main() { Preference::Preferences(true); QString inputFile = "$mgs/testData/ab102401.cub"; Cube cube; cube.open(inputFile); Camera *c = cube.camera(); std::vector<Distance> radii = c->target()->radii(); Pvl &pvl = *cube.label(); Spice spi(cube); Target targ(&spi, pvl); targ.setRadii(radii); cout << "Begin testing Ellipsoid Shape Model class...." << endl; cout << endl << " Testing constructors..." << endl; EllipsoidShape shape(&targ, pvl); EllipsoidShape shape2(&targ); EllipsoidShape shape3; cout << " Shape1 name is " << shape.name() << endl; cout << " Shape2 name is " << shape2.name() << endl; cout << " Shape3 name is " << shape3.name() << endl; std::vector<double> sB(3); sB[0] = -2399.54; sB[1] = -2374.03; sB[2] = 1277.68; std::vector<double> lookB(3, 1.); lookB[0] = -1.; cout << endl << " Testing method intersectSurface with failure..." << endl; cout << " Do we have an intersection? " << shape.hasIntersection() << endl; shape.intersectSurface(sB, lookB); if (!shape.hasIntersection()) cout << " Intersection failed " << endl; cout << endl << "Testing method intersectSurface..." << endl; cout << " Do we have an intersection? " << shape.hasIntersection() << endl; cout << " Set a pixel in the image and check again." << endl; double line = 453.0; double sample = 534.0; c->SetImage(sample, line); c->instrumentPosition((double *) &sB[0]); std::vector<double> uB(3); c->sunPosition((double *) &uB[0]); c->SpacecraftSurfaceVector((double *) &lookB[0]); /* Sample/Line = 534/453 surface normal = -0.623384, -0.698838, 0.350738 Local normal = -0.581842, -0.703663, 0.407823 Phase = 40.787328112158 Incidence = 85.341094499768 Emission = 46.966269013795 */ if (!shape.intersectSurface(sB, lookB)) { cout << " ... intersectSurface method failed" << endl; return -1; } cout << " Do we have an intersection? " << shape.hasIntersection() << endl; SurfacePoint *sp = shape.surfaceIntersection(); cout << " surface point = (" << sp->GetX().kilometers() << ", " << sp->GetY().kilometers() << ", " << sp->GetZ().kilometers() << endl; cout << endl << " Testing class method calculateLocalNormal..." << endl; QVector<double *> notUsed(4); for (int i = 0; i < notUsed.size(); i ++) notUsed[i] = new double[3]; shape.calculateLocalNormal(notUsed); vector<double> myNormal(3); myNormal = shape.normal(); cout << " local normal = (" << myNormal[0] << ", " << myNormal[1] << ", " << myNormal[2] << endl; cout << endl << " Testing class method calculateSurfaceNormal..." << endl; shape.calculateSurfaceNormal(); myNormal = shape.normal(); cout << " surface normal = (" << myNormal[0] << ", " << myNormal[1] << ", " << myNormal[2] << endl; cout << endl << " Testing class method calculateDefaultNormal..." << endl; shape.calculateDefaultNormal(); myNormal = shape.normal(); cout << " default normal = (" << myNormal[0] << ", " << myNormal[1] << ", " << myNormal[2] << endl; cout << endl << " Testing localRadius method ..." << endl; cout << " Local radius = " << shape.localRadius(Latitude(20.532461495381, Angle::Degrees), Longitude(228.26609149754, Angle::Degrees)).kilometers() << endl; // Mars radii = 3397. 3397. 3375. cout << endl << " Testing setHasIntersection method" << endl; shape.setHasIntersection(false); cout << " Do we have an intersection? " << shape.hasIntersection() << endl; cout << endl << " Testing setSurfacePoint method ..." << endl; shape.setSurfacePoint(*sp); cout << " Do we have an intersection? " << shape.hasIntersection() << endl; cout << " surface point = (" << sp->GetX().kilometers() << ", " << sp->GetY().kilometers() << ", " << sp->GetZ().kilometers() << endl; cube.close(); }
/** The ISIS smtk main application */ void IsisMain() { UserInterface &ui = Application::GetUserInterface(); // Open the first cube. It is the left hand image. Cube lhImage; CubeAttributeInput &attLeft = ui.GetInputAttribute("FROM"); vector<QString> bandLeft = attLeft.bands(); lhImage.setVirtualBands(bandLeft); lhImage.open(ui.GetFileName("FROM"),"r"); // Open the second cube, it is geomertricallty altered. We will be matching the // first to this one by attempting to compute a sample/line offsets Cube rhImage; CubeAttributeInput &attRight = ui.GetInputAttribute("MATCH"); vector<QString> bandRight = attRight.bands(); rhImage.setVirtualBands(bandRight); rhImage.open(ui.GetFileName("MATCH"),"r"); // Ensure only single bands if (lhImage.bandCount() != 1 || rhImage.bandCount() != 1) { QString msg = "Input Cubes must have only one band!"; throw IException(IException::User,msg,_FILEINFO_); } // Both images must have a Camera and can also have a Projection. We will // only deal with a Camera, however as a projected, non-mosaicked image // uses a Projection internal to the Camera object. Camera *lhCamera = NULL; Camera *rhCamera = NULL; try { lhCamera = lhImage.camera(); rhCamera = rhImage.camera(); } catch (IException &ie) { QString msg = "Both input images must have a camera"; throw IException(ie, IException::User, msg, _FILEINFO_); } // Since we are generating a DEM, we must turn off any existing // DEM that may have been initialized with spiceinit. lhCamera->IgnoreElevationModel(true); rhCamera->IgnoreElevationModel(true); // Get serial number QString serialLeft = SerialNumber::Compose(lhImage, true); QString serialRight = SerialNumber::Compose(rhImage, true); // This still precludes band to band registrations. if (serialLeft == serialRight) { QString sLeft = FileName(lhImage.fileName()).name(); QString sRight = FileName(rhImage.fileName()).name(); if (sLeft == sRight) { QString msg = "Cube Serial Numbers must be unique - FROM=" + serialLeft + ", MATCH=" + serialRight; throw IException(IException::User,msg,_FILEINFO_); } serialLeft = sLeft; serialRight = sRight; } Progress prog; prog.SetText("Finding Initial Seeds"); int nl = lhImage.lineCount(); int ns = lhImage.sampleCount(); BigInt numAttemptedInitialPoints = 0; // Declare Gruen matcher SmtkMatcher matcher(ui.GetFileName("REGDEF"), &lhImage, &rhImage); // Get line/sample linc/sinc parameters int space = ui.GetInteger("SPACE"); int linc (space), sinc(space); // Do we have a seed points from a control net file? bool useseed = ui.WasEntered("CNET"); // Base points on an input cnet SmtkQStack gstack; double lastEigen(0.0); if (useseed) { ControlNet cnet(ui.GetFileName("CNET")); prog.SetMaximumSteps(cnet.GetNumPoints()); prog.CheckStatus(); gstack.reserve(cnet.GetNumPoints()); for (int cpIndex = 0; cpIndex < cnet.GetNumPoints(); cpIndex ++) { ControlPoint *cp = cnet.GetPoint(cpIndex); if (!cp->IsIgnored()) { ControlMeasure *cmLeft(0), *cmRight(0); for(int cmIndex = 0; cmIndex < cp->GetNumMeasures(); cmIndex ++) { ControlMeasure *cm = cp->GetMeasure(cmIndex); if (!cm->IsIgnored()) { if (cm->GetCubeSerialNumber() == serialLeft) cmLeft = cp->GetMeasure(cmIndex); if (cm->GetCubeSerialNumber() == serialRight) cmRight = cp->GetMeasure(cmIndex); } } // If we have both left and right images in the control point, save it if ( (cmLeft != 0) && (cmRight != 0) ) { Coordinate left = Coordinate(cmLeft->GetLine(), cmLeft->GetSample()); Coordinate right = Coordinate(cmRight->GetLine(), cmRight->GetSample()); SmtkPoint spnt = matcher.Create(left, right); // Insert the point (unregistered) if ( spnt.isValid() ) { int line = (int) cmLeft->GetLine(); int samp = (int) cmLeft->GetSample(); matcher.isValid(spnt); gstack.insert(qMakePair(line, samp), spnt); lastEigen = spnt.GoodnessOfFit(); } } } prog.CheckStatus(); } } else { // We want to create a grid of control points that is N rows by M columns. int rows = (lhImage.lineCount() + linc - 1)/linc; int cols = (lhImage.sampleCount() + sinc - 1)/sinc; prog.SetMaximumSteps(rows * cols); prog.CheckStatus(); // First pass stack and eigen value statistics SmtkQStack fpass; fpass.reserve(rows * cols); Statistics temp_mev; // Loop through grid of points and get statistics to compute // initial set of points for (int line = linc / 2 + 1; line < nl; line += linc) { for (int samp = sinc / 2 + 1 ; samp < ns; samp += sinc) { numAttemptedInitialPoints ++; SmtkPoint spnt = matcher.Register(Coordinate(line,samp)); if ( spnt.isValid() ) { matcher.isValid(spnt); fpass.insert(qMakePair(line, samp), spnt); temp_mev.AddData(spnt.GoodnessOfFit()); } prog.CheckStatus(); } } // Now select a subset of fpass points as the seed points cout << "Number of Potential Seed Points: " << fpass.size() << "\n"; cout << "Min / Max Eigenvalues Matched: " << temp_mev.Minimum() << ", " << temp_mev.Maximum() << "\n"; // How many seed points are requested double nseed = ui.GetDouble("NSEED"); int inseed; if (nseed >= 1.0) inseed = (int) nseed; else if (nseed > 0.0) inseed = (int) (nseed * (double) (fpass.size())); else inseed = (int) ((double) (fpass.size()) * 0.05); double seedsample = ui.GetDouble("SEEDSAMPLE"); // Generate a new stack gstack.reserve(inseed); while ((gstack.size() < inseed) && (!fpass.isEmpty() )) { SmtkQStack::iterator bestm; if (seedsample <= 0.0) { bestm = matcher.FindSmallestEV(fpass); } else { bestm = matcher.FindExpDistEV(fpass, seedsample, temp_mev.Minimum(), temp_mev.Maximum()); } // Add point to stack if (bestm != fpass.end()) { Coordinate right = bestm.value().getRight(); matcher.isValid(bestm.value()); gstack.insert(bestm.key(), bestm.value()); lastEigen = bestm.value().GoodnessOfFit(); fpass.erase(bestm); } } // If a user wants to see the seed network, write it out here if (ui.WasEntered("OSEEDNET")) { WriteCnet(ui.GetFileName("OSEEDNET"), gstack, lhCamera->target()->name(), serialLeft, serialRight); } } /////////////////////////////////////////////////////////////////////// // All done with seed points. Sanity check ensures we actually found // some. /////////////////////////////////////////////////////////////////////// if (gstack.size() <= 0) { QString msg = "No seed points found - may need to check Gruen parameters."; throw IException(IException::User, msg, _FILEINFO_); } // Report seed point status if (!useseed) { cout << "Number of Seed Points used: " << gstack.size() << "\n"; cout << "EV of last Seed Point: " << lastEigen << "\n"; } else { cout << "Number of Manual Seed Points: " << gstack.size() << "\n"; } // Use seed points (in stack) to grow SmtkQStack bmf; bmf.reserve(gstack.size()); // Probably need much more but for starters... BigInt numOrigPoints = gstack.size(); BigInt passpix2 = 0; int subcbox = ui.GetInteger("SUBCBOX"); int halfBox((subcbox-1)/2); while (!gstack.isEmpty()) { SmtkQStackIter cstack = matcher.FindSmallestEV(gstack); // Print number on stack if ((gstack.size() % 1000) == 0) { cout << "Number on Stack: " << gstack.size() << ". " << cstack.value().GoodnessOfFit() << "\n"; } // Test to see if already determined SmtkQStackIter bmfPt = bmf.find(cstack.key()); if (bmfPt == bmf.end()) { // Its not in the final stack, process it // Retrieve the point SmtkPoint spnt = cstack.value(); // Register if its not already registered if (!spnt.isRegistered()) { spnt = matcher.Register(spnt, spnt.getAffine()); } // Still must check for validity if the point was just registered, // otherwise should be good if ( spnt.isValid() ) { passpix2++; bmf.insert(cstack.key(), spnt); // inserts (0,0) offset excluded below int line = cstack.key().first; int sample = cstack.key().second; // Determine match points double eigen(spnt.GoodnessOfFit()); for (int sampBox = -halfBox ; sampBox <= halfBox ; sampBox++ ) { int csamp = sample + sampBox; for (int lineBox = -halfBox ; lineBox <= halfBox ; lineBox++) { int cline = line + lineBox; if ( !( (sampBox == 0) && (lineBox == 0)) ) {// Already added above SmtkQPair dupPair(cline, csamp); SmtkQStackIter temp = bmf.find(dupPair); SmtkPoint bmfpnt; if (temp != bmf.end()) { if (temp.value().GoodnessOfFit() > eigen) { // Create cloned point with better fit bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } } else { // ISIS2 is BMF(SAMP,LINE,7) .EQ VALID_MAX4) // Clone new point for insert bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } // Add if good point if (bmfpnt.isValid()) { bmf.insert(dupPair, bmfpnt); } } } } // Grow stack with spacing adding info to stack for (int i = -1 ; i <= 1 ; i ++) { // Sample for (int j = -1 ; j <= 1 ; j ++) { // Line // Don't re-add the original sample, line if ( !((i == 0) && (j == 0)) ) { // Grow based upon spacing double ssamp = sample + (i * space); double sline = line + (j * space); Coordinate pnt = Coordinate(sline, ssamp); SmtkPoint gpnt = matcher.Clone(spnt, pnt); if ( gpnt.isValid() ) { SmtkQPair growpt((int) sline, (int) ssamp); // double check we don't have a finalized result at this position SmtkQStackIter temp = bmf.find(growpt); if(temp == bmf.end()) { gstack.insert(growpt, gpnt); } } } } } } } // Remove the current point from the grow stack (hole) gstack.erase(cstack); } ///////////////////////////////////////////////////////////////////////// // All done with creating points. Perform output options. ///////////////////////////////////////////////////////////////////////// // If a TO parameter was specified, create DEM with errors if (ui.WasEntered("TO")) { // Create the output DEM cout << "\nCreating output DEM from " << bmf.size() << " points.\n"; Process p; Cube *icube = p.SetInputCube("FROM"); Cube *ocube = p.SetOutputCube("TO", icube->sampleCount(), icube->lineCount(), 3); p.ClearInputCubes(); int boxsize = ui.GetInteger("BOXSIZE"); double plotdist = ui.GetDouble("PLOTDIST"); TileManager dem(*ocube), eigen(*ocube), stErr(*ocube); dem.SetTile(1, 1); // DEM Data/elevation stErr.SetTile(1, 2); // Error in stereo computation eigen.SetTile(1, 3); // Eigenvalue of the solution int nBTiles(eigen.Tiles()/3); // Total tiles / 3 bands prog.SetText("Creating DEM"); prog.SetMaximumSteps(nBTiles); prog.CheckStatus(); Statistics stAng; while ( !eigen.end() ) { // Must use the last band for this!! PointPlot tm = for_each(bmf.begin(), bmf.end(), PointPlot(dem, plotdist)); tm.FillPoints(*lhCamera, *rhCamera, boxsize, dem, stErr, eigen, &stAng); ocube->write(dem); ocube->write(stErr); ocube->write(eigen); dem.next(); stErr.next(); eigen.next(); prog.CheckStatus(); } // Report Stereo separation angles PvlGroup stresultsPvl("StereoSeparationAngle"); stresultsPvl += PvlKeyword("Minimum", toString(stAng.Minimum()), "deg"); stresultsPvl += PvlKeyword("Average", toString(stAng.Average()), "deg"); stresultsPvl += PvlKeyword("Maximum", toString(stAng.Maximum()), "deg"); stresultsPvl += PvlKeyword("StandardDeviation", toString(stAng.StandardDeviation()), "deg"); Application::Log(stresultsPvl); // Update the label with BandBin keywords PvlKeyword filter("FilterName", "Elevation", "meters"); filter.addValue("ElevationError", "meters"); filter.addValue("GoodnessOfFit", "unitless"); PvlKeyword center("Center", "1.0"); center.addValue("1.0"); center.addValue("1.0"); PvlGroup &bandbin = ocube->label()->findGroup("BandBin", PvlObject::Traverse); bandbin.addKeyword(filter, PvlContainer::Replace); bandbin.addKeyword(center, PvlContainer::Replace); center.setName("Width"); bandbin.addKeyword(center, PvlContainer::Replace); p.EndProcess(); } // If a cnet file was entered, write the ControlNet pvl to the file if (ui.WasEntered("ONET")) { WriteCnet(ui.GetFileName("ONET"), bmf, lhCamera->target()->name(), serialLeft, serialRight); } // Create output data PvlGroup totalPointsPvl("Totals"); totalPointsPvl += PvlKeyword("AttemptedPoints", toString(numAttemptedInitialPoints)); totalPointsPvl += PvlKeyword("InitialSuccesses", toString(numOrigPoints)); totalPointsPvl += PvlKeyword("GrowSuccesses", toString(passpix2)); totalPointsPvl += PvlKeyword("ResultingPoints", toString(bmf.size())); Application::Log(totalPointsPvl); Pvl arPvl = matcher.RegistrationStatistics(); PvlGroup smtkresultsPvl("SmtkResults"); smtkresultsPvl += PvlKeyword("SpiceOffImage", toString(matcher.OffImageErrorCount())); smtkresultsPvl += PvlKeyword("SpiceDistanceError", toString(matcher.SpiceErrorCount())); arPvl.addGroup(smtkresultsPvl); for(int i = 0; i < arPvl.groups(); i++) { Application::Log(arPvl.group(i)); } // add the auto registration information to print.prt PvlGroup autoRegTemplate = matcher.RegTemplate(); Application::Log(autoRegTemplate); // Don't need the cubes opened anymore lhImage.close(); rhImage.close(); }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); double time0,//start time time1,//end time alti, //altitude of the spacecraftmore fmc, //forward motion compensation rad/sec horV, //horizontal velocity km/sec radV, //radial velocity km/sec rollV,//roll speed in rad/sec led; //line exposure duration in seconds Cube panCube; iTime isisTime; QString iStrTEMP; int i,j,k,scFrameCode,insCode; QString mission; SpicePosition *spPos; SpiceRotation *spRot; //int nlines,nsamples,nbands; double deg2rad = acos(-1.0)/180.0; ProcessImport jp; FileName transFile("$apollo15/translations/apollopantranstable.trn"); PvlTranslationTable transTable(transFile); PvlGroup kernels_pvlG; //scFrameCode and insCode from user input mission = ui.GetString("MISSION"); if (mission == "APOLLO12") scFrameCode = -912000; if (mission == "APOLLO14") scFrameCode = -914000; if (mission == "APOLLO15") scFrameCode = -915000; if (mission == "APOLLO16") scFrameCode = -916000; if (mission == "APOLLO17") scFrameCode = -917000; insCode = scFrameCode - 230; try { panCube.open(ui.GetFileName("FROM"),"rw"); } catch (IException &e) { throw IException(IException::User, "Unable to open the file [" + ui.GetFileName("FROM") + "] as a cube.", _FILEINFO_); } ////////////////////////////////////////////build the cube header instrament group PvlGroup inst_pvlG("Instrument"); PvlKeyword keyword; //four that are the same for every panaramic mission keyword.setName("SpacecraftName"); keyword.setValue(mission); inst_pvlG.addKeyword(keyword); keyword.setName("InstrumentName"); keyword.setValue(transTable.Translate("InstrumentName","whatever")); inst_pvlG.addKeyword(keyword); keyword.setName("InstrumentId"); keyword.setValue(transTable.Translate("InstrumentId","whatever")); inst_pvlG.addKeyword(keyword); keyword.setName("TargetName"); keyword.setValue(transTable.Translate("TargetName","whatever")); inst_pvlG.addKeyword(keyword); //three that need to be calculated from input values horV = ui.GetDouble("VEL_HORIZ"); radV = ui.GetDouble("VEL_RADIAL"); alti = ui.GetDouble("CRAFT_ALTITUDE"); //caculate the LineExposureDuration (led) if( ui.WasEntered("V/H_OVERRIDE") ) fmc = ui.GetDouble("V/H_OVERRIDE")/1000.0; else //forward motion compensation is directly equivalent to V/H fmc = sqrt(horV*horV + radV*radV)/alti; rollV = fmc*ROLLC; //roll angular velcoity is equal to V/H * constant (units rad/sec) //led = rad/mm * sec/rad = radians(2.5)/FIDL / rollV (final units: sec/mm) led = (2.5*acos(-1.0)/180.0)/rollV/FIDL; //use led and the number of mm to determine the start and stop times isisTime = ui.GetString("GMT"); //calculate starting and stoping times time0 = isisTime.Et() - led*FIDL*21.5; time1 = time0 + led*FIDL*43; isisTime = time0; keyword.setName("StartTime"); keyword.setValue(iStrTEMP=isisTime.UTC()); inst_pvlG.addKeyword(keyword); isisTime = time1; keyword.setName("StopTime"); keyword.setValue(iStrTEMP=isisTime.UTC()); inst_pvlG.addKeyword(keyword); keyword.setName("LineExposureDuration"); //converted led to msec/mm--negative sign to account for the anti-parallel time and line axes keyword.setValue(iStrTEMP=toString(-led),"sec/mm"); inst_pvlG.addKeyword(keyword); panCube.putGroup(inst_pvlG); ///////////////////////////////////The kernals group kernels_pvlG.setName("Kernels"); kernels_pvlG.clear(); keyword.setName("NaifFrameCode"); keyword.setValue(toString(insCode)); kernels_pvlG.addKeyword(keyword); keyword.setName("LeapSecond"); keyword.setValue( transTable.Translate("LeapSecond","File1") ); kernels_pvlG.addKeyword(keyword); keyword.setName("TargetAttitudeShape"); keyword.setValue( transTable.Translate("TargetAttitudeShape", "File1") ); keyword.addValue( transTable.Translate("TargetAttitudeShape", "File2") ); keyword.addValue( transTable.Translate("TargetAttitudeShape", "File3") ); kernels_pvlG.addKeyword(keyword); keyword.setName("TargetPosition"); keyword.setValue("Table"); keyword.addValue( transTable.Translate("TargetPosition", "File1") ); keyword.addValue( transTable.Translate("TargetPosition", "File2") ); kernels_pvlG.addKeyword(keyword); keyword.setName("ShapeModel"); keyword.setValue( transTable.Translate("ShapeModel", "File1") ); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentPointing"); keyword.setValue("Table"); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentPosition"); keyword.setValue("Table"); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentAddendum"); keyword.setValue( transTable.Translate("InstrumentAddendum",mission)); kernels_pvlG.addKeyword(keyword); panCube.putGroup(kernels_pvlG); //Load all the kernals Load_Kernel(kernels_pvlG["TargetPosition"]); Load_Kernel(kernels_pvlG["TargetAttitudeShape"]); Load_Kernel(kernels_pvlG["LeapSecond"]); //////////////////////////////////////////attach a target rotation table char frameName[32]; SpiceInt frameCode; SpiceBoolean found; //get the framecode from the body code (301=MOON) cidfrm_c(301, sizeof(frameName), &frameCode, frameName, &found); if(!found) { QString naifTarget = QString("IAU_MOOM"); namfrm_c(naifTarget.toAscii().data(), &frameCode); if(frameCode == 0) { QString msg = "Can not find NAIF code for [" + naifTarget + "]"; throw IException(IException::Io, msg, _FILEINFO_); } } spRot = new SpiceRotation(frameCode); //create a table from starttime to endtime (streched by 3%) with NODES entries spRot->LoadCache(time0-0.015*(time1-time0), time1+0.015*(time1-time0), NODES); Table tableTargetRot = spRot->Cache("BodyRotation"); tableTargetRot.Label() += PvlKeyword("Description", "Created by apollopaninit"); panCube.write(tableTargetRot); //////////////////////////////////////////////////attach a sun position table spPos = new SpicePosition(10,301); //Position of the sun (10) WRT to the MOON (301) //create a table from starttime to endtime (stretched by 3%) with NODES entries spPos->LoadCache(time0-0.015*(time1-time0), time1+0.015*(time1-time0), NODES); Table tableSunPos = spPos->Cache("SunPosition"); tableSunPos.Label() += PvlKeyword("SpkTableStartTime", toString(time0-0.015*(time1-time0))); tableSunPos.Label() += PvlKeyword("SpkTablleEndTime", toString(time1+0.015*(time1-time0))); tableSunPos.Label() += PvlKeyword("Description", "Created by apollopaninit"); panCube.write(tableSunPos); //attach the table to the cube /////////////Finding the principal scan line position and orientation //get the radii of the MOON SpiceInt tempRadii = 0; bodvcd_c(301,"RADII",3,&tempRadii,R_MOON); //units are km double omega,phi,kappa; std::vector<double> posSel; //Seleno centric position std::vector<double> sunPos; //sunPosition used to transform to J2000 std::vector<double> posJ20; //camera position in J2000 posSel.resize(3); sunPos.resize(3); posJ20.resize(3); double temp, vel[3] = { 0.0, 0.0, 0.0 }, //the total velocity vector (combined Horizonatal and normal components) // in km/sec M[3][3] = { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } }, //rotation matrix zDir[] = { 0.0, 0.0, 1.0 }, //selenographic Z axis northPN[3] = { 0.0, 0.0, 0.0 }, //normal to the plane containing all the north/south directions, // that is plane containing // the origin, the z axis, and the primary point of intersection northL[3] = { 0.0, 0.0, 0.0 }, //north direction vector in local horizontal plane azm[3] = { 0.0, 0.0, 0.0 }, //azm direction of the veclocity vector in selenographic coordinates azmP[3] = { 0.0, 0.0, 0.0 }, //azm rotated (partially) and projected into the image plane norm[3] = { 0.0, 0.0, 0.0 }, //normal to the local horizontal plane look[3] = { 0.0, 0.0, 0.0 }; //unit direction vector in the pincipal cameral look direction, // parallel to the vector from the center of the moon through the spacecraft double pos0[3] = { 0.0, 0.0, 0.0 }, //coordinate of the camera position pInt[3] = { 0.0, 0.0, 0.0 }; //coordinate of the principle intersection point /////////////////calculating the camera position for the center (principal scan line) pos0[1] = ui.GetDouble("LON_NADIR")*deg2rad; pos0[0] = ui.GetDouble("LAT_NADIR")*deg2rad; pos0[2] = ui.GetDouble("CRAFT_ALTITUDE"); //units are km Geographic2GeocentricLunar(pos0,pos0); //function is written so the input can also be the // output /////////////////////calculating the camera orientation for the center (principal) scan line pInt[1] = ui.GetDouble("LON_INT")*deg2rad; pInt[0] = ui.GetDouble("LAT_INT")*deg2rad; pInt[2] = 0.0; Geographic2GeocentricLunar(pInt,pInt); //function is written so the input can also be the output //calculate the unit look direction vector in object space look[0] = -pos0[0] + pInt[0]; look[1] = -pos0[1] + pInt[1]; look[2] = -pos0[2] + pInt[2]; temp = sqrt(look[0]*look[0] + look[1]*look[1] + look[2]*look[2]); look[0] /= temp; look[1] /= temp; look[2] /= temp; //the local normal vector is equal to pInt0/|pInt0| temp = sqrt(pInt[0]*pInt[0] + pInt[1]*pInt[1] + pInt[2]*pInt[2]); norm[0] = pInt[0]/temp; norm[1] = pInt[1]/temp; norm[2] = pInt[2]/temp; //omega and phi are defined so that M(phi)M(omega)look = [0 0 -1] leaving only the roation // around z axis to be found omega = -atan2(look[1], look[2]); //omega rotation to zero look[1] phi = atan2(-look[0], sin(omega)*look[1] - cos(omega)*look[2]); //phi rotation to zero look[0] //use the horizontal velocity vector direction to solve for the last rotation; we will make the // image x axis parallel to the in-image-plane projection of the horizontal direction of flight. // The local normal cross the selenogrpahic z gives northPN (normal to the plane containing all // the north/south directions), that is, the plane containing the origin, the z axis, and the // primary point of intersection. crossp(northPN,norm,northL); //The normal to the plane containing all the north/south directions cross the local normal // direction gives the local north/south direction in the local normal plane crossp(norm, zDir, northPN); if (northL[2] < 0) { //if by chance we got the south direction change the signs northL[0] = -northL[0]; northL[1] = -northL[1]; northL[2] = -northL[2]; } //define the rotation matrix to convert northL to the azimuth of flight. // A left handed rotation of "VEL_AZM" around the positive normal direction will convert northL // to azm MfromVecLeftAngle(M,norm,ui.GetDouble("VEL_AZM")*deg2rad); azm[0] = M[0][0]*northL[0] + M[0][1]*northL[1] + M[0][2]*northL[2]; azm[1] = M[1][0]*northL[0] + M[1][1]*northL[1] + M[1][2]*northL[2]; azm[2] = M[2][0]*northL[0] + M[2][1]*northL[1] + M[2][2]*northL[2]; //apply the two rotations we already know MfromLeftEulers(M,omega,phi,0.0); azmP[0] = M[0][0]*azm[0] + M[0][1]*azm[1] + M[0][2]*azm[2]; azmP[1] = M[1][0]*azm[1] + M[1][1]*azm[1] + M[1][2]*azm[2]; azmP[2] = M[2][0]*azm[2] + M[2][1]*azm[1] + M[2][2]*azm[2]; //subtract that portion of the azm that is perpindicular to the image plane (also the portion // which is parallel to look) making azm a vector parrallel to the image plane // Further, since we're now rotated into some coordinate system that differs from // the image coordinate system by only a kappa rotation making the vector parrallel to the // image plan is as simple as zeroing the z component (and as pointless to further calculations // as a nat's fart in hurricane) nevertheless it completes the logical transition azmP[2] = 0.0; //finally the kappa rotation that will make azmP parallel (including sign) to the camera x axis kappa = -atan2(-azmP[1], azmP[0]); ////////////////////Add an instrument position table //Define the table records TableRecord recordPos; // reacord to be added to table // add x,y,z position labels and ephemeris time et to record TableField x("J2000X", TableField::Double); TableField y("J2000Y", TableField::Double); TableField z("J2000Z", TableField::Double); TableField t("ET", TableField::Double); recordPos += x; recordPos += y; recordPos += z; recordPos += t; Table tablePos("InstrumentPosition", recordPos); //now that the azm and norm vectors are defined // the total velocity vector can be calcualted (km/sec) vel[0] = horV*azm[0] + radV * norm[0]; vel[1] = horV*azm[1] + radV * norm[1]; vel[2] = horV*azm[2] + radV * norm[2]; //we'll provide a two ellement table (more is redundant because the motion is modeled as linear // at this point) we'll extend the nodes 3% beyond the edges of the images to be sure // rounding errors don't cause problems temp = 0.515*(time1-time0); //3% extension posSel[0] = pos0[0] - temp*vel[0]; //selenocentric coordinate calculation posSel[1] = pos0[1] - temp*vel[1]; posSel[2] = pos0[2] - temp*vel[2]; //converting to J2000 temp = time0 - 0.005*(time1-time0); //et just before the first scan line spPos->SetEphemerisTime(temp); spRot->SetEphemerisTime(temp); //Despite being labeled as J2000, the coordinates for the instrument position are in fact in // target centric coordinated rotated to a system centered at the target with aces parallel // to J2000, whatever that means posJ20 = spRot->J2000Vector(posSel); //J2000Vector calls rotates the position vector into J2000, // completing the transformation recordPos[0] = posJ20[0]; recordPos[1] = posJ20[1]; recordPos[2] = posJ20[2]; recordPos[3] = temp; //temp = et (right now anyway) tablePos += recordPos; tablePos.Label() += PvlKeyword("SpkTableStartTime",toString(temp)); //now the other node temp = 0.515*(time1-time0); //3% extension posSel[0] = pos0[0] + temp*vel[0]; //selenocentric coordinate calculation posSel[1] = pos0[1] + temp*vel[1]; posSel[2] = pos0[2] + temp*vel[2]; //converting to J2000 temp = time1 + 0.015*(time1-time0); //et just after the last scan line spPos->SetEphemerisTime(temp); spRot->SetEphemerisTime(temp); //Despite being labeled as J2000, the coordinates for the instrument position are in fact // in target centric coordinated rotated to a system centered at the target with aces // parallel to J2000, whatever that means posJ20 = spRot->J2000Vector(posSel); //J2000Vector calls rotates the position vector into J2000, // completing the transformation recordPos[0] = posJ20[0]; recordPos[1] = posJ20[1]; recordPos[2] = posJ20[2]; recordPos[3] = temp; //temp = et (right now anyway) tablePos += recordPos; tablePos.Label() += PvlKeyword("SpkTableEndTime",toString(temp)); tablePos.Label() += PvlKeyword("CacheType","Linear"); tablePos.Label() += PvlKeyword("Description","Created by apollopaninit"); panCube.write(tablePos); //now attach it to the table /////////////////////////////attach a camera pointing table double cacheSlope, //time between epoches in the table rollComb, //magnitude of roll relative to the center in the middle of the epoch relT, //relative time at the center of each epoch Q[NODES][5], //NODES four ellement unit quarternions and et (to be calculated). gimVec[3], //the direction of the gimbal rotation vector (to the cameras persepective // this is always changing because the camera is mounted to the roll frame // assembly which is mounted to the gimbal) M0[3][3], //rotation matrix of the previous epoch Mtemp1[3][3], //intermediate step in the multiplication of rotation matricies Mtemp2[3][3], //intermediate step in the multiplication of rotation matricies Mdg[3][3], //incremental rotation due the the gimbal motion in the camera frame Mdr[3][3]; //the contribution of the roll motion in the camera frame during time // cacheSlope std::vector <double> M_J2toT; //rotation matrix from J2000 to the target frame M_J2toT.resize(9); //Table Definition TableField q0("J2000Q0", TableField::Double); TableField q1("J2000Q1", TableField::Double); TableField q2("J2000Q2", TableField::Double); TableField q3("J2000Q3", TableField::Double); TableField et("ET", TableField::Double); TableRecord recordRot; recordRot += q0; recordRot += q1; recordRot += q2; recordRot += q3; recordRot += et; Table tableRot("InstrumentPointing",recordRot); //From the cameras perspective the gimbal motion is around a constantly changing axis, // this is handled by combining a series of incremental rotations MfromLeftEulers(M0, omega, phi, kappa); //rotation matrix in the center Q[(NOPDES-1)/2] spRot->SetEphemerisTime(isisTime.Et()); M_J2toT = spRot->Matrix(); //this actually gives the rotation from J2000 to target centric for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[(NODES-1)/2]); //save the middle scan line quarternion Q[(NODES-1)/2][4] = (time1 + time0)/2.0; //time in the center of the image //the total time is scaled up slightly so that nodes will extend just beyond the edge of the image cacheSlope = 1.03*(time1 - time0)/(NODES-1); //Mdr is constant for all the forward time computations MfromLeftEulers(Mdr,cacheSlope*rollV,0.0,0.0); for (i=(NODES-1)/2+1; i<NODES; i++) { //moving foward in time first Q[i][4] = Q[i-1][4] + cacheSlope; //new time epoch //epoch center time relative to the center line relT = double(i - (NODES-1)/2 - 0.5)*cacheSlope; rollComb = relT*rollV; gimVec[0] = 0.0; //gimbal rotation vector direction in the middle of the epoch gimVec[1] = cos(rollComb); gimVec[2] = -sin(rollComb); //incremental rotation due to the gimbal (forward motion compensation) MfromVecLeftAngle(Mdg, gimVec, fmc*cacheSlope); //the new rotation matrix is Transpose(Mdr)*Transpose(Mdg)*M0--NOTE the order swap and // transposes are needed because both Mdr and Mdg were caculated in image space and need to be // transposed to apply to object space mtxm_c(Mdg, M0, Mtemp1); //M0 is now what would typically be considered the rotation matrix of an image. It rotates a // vector from the target centric space into camera space. However, what is standard to // include in the cube labels is a rotation from camera space to J2000. M0 is therefore the // transpose of the first part of this rotation. Transpose(M0) is the rotation from camera // space to target centric space mtxm_c(Mdr, Mtemp1, M0); //now adding the rotation from the target frame to J2000 spRot->SetEphemerisTime(Q[i][4]); //this actually gives the rotation from J2000 to target centric--hence the mxmt_c function being // used later M_J2toT = spRot->Matrix(); for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[i]); //convert to a quarterion } MfromLeftEulers(M0, omega, phi, kappa); //rotation matrix in the center Q[(NOPDES-1)/2] //Mdr is constant for all the backward time computations MfromLeftEulers(Mdr, -cacheSlope*rollV, 0.0, 0.0); for (i=(NODES-1)/2-1; i>=0; i--) { //moving backward in time Q[i][4] = Q[i+1][4] - cacheSlope; //new time epoch //epoch center time relative to the center line relT = double(i - (NODES-1)/2 + 0.5)*cacheSlope; rollComb = relT*rollV; gimVec[0] = 0.0; //gimbal rotation vector direction in the middle of the epoch gimVec[1] = cos(rollComb); gimVec[2] = -sin(rollComb); //incremental rotation due to the gimbal (forward motion compensation) MfromVecLeftAngle(Mdg, gimVec, -fmc*cacheSlope); //the new rotation matrix is Transpose(Mdr)*Transpose(Mdg)*M0 NOTE the order swap and // transposes are needed because both Mdr and Mdg were caculated in image space and need to be // transposed to apply to object space mtxm_c(Mdg, M0, Mtemp1); //M0 is now what would typically be considered the rotation matrix of an image. It rotates a // vector from the target centric space into camera space. However, what is standard to // include in the cube labels is a rotation from camera space to J2000. M0 is therefore the // transpose of the first part of this rotation. Transpose(M0) is the rotation from camera // space to target centric space mtxm_c(Mdr, Mtemp1, M0); //now adding the rotation from the target frame to J2000 spRot->SetEphemerisTime(Q[i][4]); M_J2toT = spRot->Matrix(); for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[i]); //convert to a quarterion } //fill in the table for (i=0; i<NODES; i++) { recordRot[0] = Q[i][0]; recordRot[1] = Q[i][1]; recordRot[2] = Q[i][2]; recordRot[3] = Q[i][3]; recordRot[4] = Q[i][4]; tableRot += recordRot; } tableRot.Label() += PvlKeyword("CkTableStartTime", toString(Q[0][4])); tableRot.Label() += PvlKeyword("CkTableEndTime", toString(Q[NODES-1][4])); tableRot.Label() += PvlKeyword("Description", "Created by appollopan2isis"); keyword.setName("TimeDependentFrames"); keyword.setValue(toString(scFrameCode)); keyword.addValue("1"); tableRot.Label() += keyword; keyword.setName("ConstantFrames"); keyword.setValue(toString(insCode)); keyword.addValue(toString(scFrameCode)); tableRot.Label() += keyword; keyword.setName("ConstantRotation"); keyword.setValue("1"); for (i=1;i<9;i++) if (i%4 == 0) keyword.addValue("1"); else keyword.addValue("0"); tableRot.Label() += keyword; panCube.write(tableRot); /////////////////////////Attach a table with all the measurements of the fiducial mark locations. Chip patternS,searchS; //scaled pattern and search chips Cube fidC; //Fiducial image //line and sample coordinates for looping through the panCube double l=1,s=1,sample,line,sampleInitial=1,lineInitial=1,play; int regStatus, fidn, panS, refL, //number of lines in the patternS refS; //number of samples in the patternS Pvl pvl; bool foundFirst=false; QString fileName; panS = panCube.sampleCount(); //Table definition TableRecord recordFid; TableField indexFid("FID_INEX",TableField::Integer); TableField xFid("X_COORD",TableField::Double); TableField yFid("Y_COORD",TableField::Double); recordFid += indexFid; recordFid += xFid; recordFid += yFid; Table tableFid("Fiducial Measurement",recordFid); //read the image resolutions and scale the constants acordingly double resolution = ui.GetDouble("MICRONS"), //pixel size in microns scale = SCALE *5.0/resolution, //reduction scale for fast autoregistrations searchHeight = SEARCHh*5.0/resolution, //number of lines (in 5-micron-pixels) in // search space for the first fiducial searchCellSize = SEARCHc*5.0/resolution, //height/width of search chips block averageSamples = AVERs *5.0/resolution, //scaled smaples between fiducials averageLines = AVERl *5.0/resolution; //scaled average distance between the top and //bottom fiducials if( 15.0/resolution < 1.5) play=1.5; else play = 15.0/resolution; //copy the patternS chip (the entire ApolloPanFiducialMark.cub) FileName fiducialFileName("$apollo15/calibration/ApolloPanFiducialMark.cub"); fidC.open(fiducialFileName.expanded(),"r"); if( !fidC.isOpen() ) { QString msg = "Unable to open the fiducial patternS cube: ApolloPanFiducialMark.cub\n"; throw IException(IException::User, msg, _FILEINFO_); } refL = fidC.lineCount(); refS = fidC.sampleCount(); //scaled pattern chip for fast matching patternS.SetSize(int((refS-2)/SCALE), int((refL-2)/SCALE)); patternS.TackCube((refS-1)/2, (refL-1)/2); patternS.Load(fidC, 0, SCALE); //parameters for maximum correlation autoregestration // see: file:///usgs/pkgs/isis3nightly2011-09-21/isis/doc/documents/patternSMatch/patternSMatch.html#DistanceTolerance FileName fiducialPvl("$apollo15/templates/apolloPanFiducialFinder.pvl"); pvl.read(fiducialPvl.expanded()); //read in the autoreg parameters AutoReg *arS = AutoRegFactory::Create(pvl); *arS->PatternChip() = patternS; //patternS chip is constant //set up a centroid measurer CentroidApolloPan centroid(resolution); Chip inputChip,selectionChip; inputChip.SetSize(int(ceil(200*5.0/resolution)), int(ceil(200*5.0/resolution))); fileName = ui.GetFileName("FROM"); if( panCube.pixelType() == 1) //UnsignedByte centroid.setDNRange(12, 1e99); //8 bit bright target else centroid.setDNRange(3500, 1e99); //16 bit bright target Progress progress; progress.SetText("Locating Fiducials"); progress.SetMaximumSteps(91); //Search for the first fiducial, search sizes are constanst searchS.SetSize(int(searchCellSize/scale),int(searchCellSize/scale)); //now start searching along a horizontal line for the first fiducial mark for(l = searchCellSize/2; l<searchHeight+searchCellSize/2.0 && !foundFirst; l+=searchCellSize-125*5.0/resolution) { for (s = searchCellSize/2; s < averageSamples + searchCellSize/2.0 && !foundFirst; s += searchCellSize-125*5.0/resolution) { searchS.TackCube(s, l); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); //continuous dynamic range selection centroid.selectAdaptive(&inputChip, &selectionChip); //elliptical trimming/smoothing if (centroid.elipticalReduction(&selectionChip, 95, play, 2000)) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); sampleInitial = inputChip.CubeSample(); lineInitial = inputChip.CubeLine(); foundFirst = true; //once the first fiducial is found stop } } } } if(s>=averageLines+searchCellSize/2.0) { QString msg = "Unable to locate a fiducial mark in the input cube [" + fileName + "]. Check FROM and MICRONS parameters."; throw IException(IException::Io, msg, _FILEINFO_); return; } progress.CheckStatus(); //record first fiducial measurement in the table recordFid[0] = 0; recordFid[1] = sampleInitial; recordFid[2] = lineInitial; tableFid += recordFid; for (s= sampleInitial, l=lineInitial, fidn=0; s<panS; s+=averageSamples, fidn++) { //corrections for half spacing of center fiducials if (fidn == 22) s -= averageSamples/2.0; if (fidn == 23) s -= averageSamples/2.0; //look for the bottom fiducial searchS.TackCube(s,l+averageLines); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube,0,1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); } else { //if autoreg is unsuccessful, a larger window will be used inputChip.TackCube(s, l+averageLines); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(s, l+averageLines); } centroid.selectAdaptive(&inputChip, &selectionChip); //continuous dynamic range selection //elliptical trimming/smoothing... if this fails move on if (centroid.elipticalReduction(&selectionChip, 95, play, 2000) != 0 ) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); sample = inputChip.CubeSample(); line = inputChip.CubeLine(); recordFid[0] = fidn*2+1; recordFid[1] = sample; recordFid[2] = line; tableFid += recordFid; } progress.CheckStatus(); //look for the top fiducial if (s == sampleInitial) //first time through the loop? continue; //then the top fiducial was already found searchS.TackCube(s, l); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); } else { //if autoreg is unsuccessful, a larger window will be used inputChip.TackCube(s, l); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(s, l); } centroid.selectAdaptive(&inputChip, &selectionChip);//continuous dynamic range selection //inputChip.Write("inputTemp.cub");//debug //selectionChip.Write("selectionTemp.cub");//debug //elliptical trimming/smoothing... if this fails move on if (centroid.elipticalReduction(&selectionChip, 95, play, 2000) !=0) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); //when finding the top fiducial both s and l are refined for a successful measurement, // this will help follow trends in the scaned image s = inputChip.CubeSample(); l = inputChip.CubeLine(); recordFid[0] = fidn*2; recordFid[1] = s; recordFid[2] = l; tableFid += recordFid; } progress.CheckStatus(); } panCube.write(tableFid); //close the new cube panCube.close(false); panCube.open(ui.GetFileName("FROM"),"rw"); delete spPos; delete spRot; //now instantiate a camera to make sure all of this is working ApolloPanoramicCamera* cam = (ApolloPanoramicCamera*)(panCube.camera()); //log the residual report from interior orientation PvlGroup residualStats("InteriorOrientationStats"); residualStats += PvlKeyword("FiducialsFound", toString(tableFid.Records())); residualStats += PvlKeyword("ResidualMax", toString(cam->intOriResidualMax()),"pixels"); residualStats += PvlKeyword("ResidualMean", toString(cam->intOriResidualMean()),"pixels"); residualStats += PvlKeyword("ResidualStdev", toString(cam->intOriResidualStdev()),"pixels"); Application::Log( residualStats ); return; }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); Cube cube; cube.open(ui.GetFileName("FROM"), "rw"); // Make sure cube has been run through spiceinit try { cube.camera(); } catch(IException &e) { string msg = "Spiceinit must be run before initializing the polygon"; throw IException(e, IException::User, msg, _FILEINFO_); } Progress prog; prog.SetMaximumSteps(1); prog.CheckStatus(); QString sn = SerialNumber::Compose(cube); ImagePolygon poly; if(ui.WasEntered("MAXEMISSION")) { poly.Emission(ui.GetDouble("MAXEMISSION")); } if(ui.WasEntered("MAXINCIDENCE")) { poly.Incidence(ui.GetDouble("MAXINCIDENCE")); } if(ui.GetString("LIMBTEST") == "ELLIPSOID") { poly.EllipsoidLimb(true); } int sinc = 1; int linc = 1; IString incType = ui.GetString("INCTYPE"); if(incType.UpCase() == "VERTICES") { poly.initCube(cube); sinc = linc = (int)(0.5 + (((poly.validSampleDim() * 2) + (poly.validLineDim() * 2) - 3.0) / ui.GetInteger("NUMVERTICES"))); if (sinc < 1.0 || linc < 1.0) sinc = linc = 1.0; } else if (incType.UpCase() == "LINCSINC"){ sinc = ui.GetInteger("SINC"); linc = ui.GetInteger("LINC"); } else { string msg = "Invalid INCTYPE option[" + incType + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } bool precision = ui.GetBoolean("INCREASEPRECISION"); try { poly.Create(cube, sinc, linc, 1, 1, 0, 0, 1, precision); } catch (IException &e) { QString msg = "Cannot generate polygon for [" + ui.GetFileName("FROM") + "]"; throw IException(e, IException::User, msg, _FILEINFO_); } if(ui.GetBoolean("TESTXY")) { Pvl cubeLab(ui.GetFileName("FROM")); PvlGroup inst = cubeLab.findGroup("Instrument", Pvl::Traverse); QString target = inst["TargetName"]; PvlGroup radii = Projection::TargetRadii(target); Pvl map(ui.GetFileName("MAP")); PvlGroup &mapping = map.findGroup("MAPPING"); if(!mapping.hasKeyword("TargetName")) mapping += Isis::PvlKeyword("TargetName", target); if(!mapping.hasKeyword("EquatorialRadius")) mapping += Isis::PvlKeyword("EquatorialRadius", (QString)radii["EquatorialRadius"]); if(!mapping.hasKeyword("PolarRadius")) mapping += Isis::PvlKeyword("PolarRadius", (QString)radii["PolarRadius"]); if(!mapping.hasKeyword("LatitudeType")) mapping += Isis::PvlKeyword("LatitudeType", "Planetocentric"); if(!mapping.hasKeyword("LongitudeDirection")) mapping += Isis::PvlKeyword("LongitudeDirection", "PositiveEast"); if(!mapping.hasKeyword("LongitudeDomain")) mapping += Isis::PvlKeyword("LongitudeDomain", "360"); if(!mapping.hasKeyword("CenterLatitude")) mapping += Isis::PvlKeyword("CenterLatitude", "0"); if(!mapping.hasKeyword("CenterLongitude")) mapping += Isis::PvlKeyword("CenterLongitude", "0"); sinc = poly.getSinc(); linc = poly.getLinc(); bool polygonGenerated = false; while (!polygonGenerated) { Projection *proj = NULL; geos::geom::MultiPolygon *xyPoly = NULL; try { proj = ProjectionFactory::Create(map, true); xyPoly = PolygonTools::LatLonToXY(*poly.Polys(), proj); polygonGenerated = true; } catch (IException &e) { if (precision && sinc > 1 && linc > 1) { sinc = sinc * 2 / 3; linc = linc * 2 / 3; poly.Create(cube, sinc, linc); } else { delete proj; delete xyPoly; e.print(); // This should be a NAIF error QString msg = "Cannot calculate XY for ["; msg += ui.GetFileName("FROM") + "]"; throw IException(e, IException::User, msg, _FILEINFO_); } } delete proj; delete xyPoly; } } cube.deleteBlob("Polygon", sn); cube.write(poly); if(precision) { PvlGroup results("Results"); results.addKeyword(PvlKeyword("SINC", toString(sinc))); results.addKeyword(PvlKeyword("LINC", toString(linc))); Application::Log(results); } Process p; p.SetInputCube("FROM"); p.WriteHistory(cube); cube.close(); prog.CheckStatus(); }
/** * Set the output cube to specified file name and specified input images * and output attributes */ Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes, CubeAttributeOutput &oAtt, const QString &mosaicFile) { int bands = 0; double xmin = DBL_MAX; double xmax = -DBL_MAX; double ymin = DBL_MAX; double ymax = -DBL_MAX; double slat = DBL_MAX; double elat = -DBL_MAX; double slon = DBL_MAX; double elon = -DBL_MAX; Projection *proj = NULL; if (propagationCubes.size() < 1) { QString msg = "The list does not contain any data"; throw IException(IException::Programmer, msg, _FILEINFO_); } for (int i = 0; i < propagationCubes.size(); i++) { // Open the cube and get the maximum number of band in all cubes Cube cube; cube.open(propagationCubes[i].toString()); bands = max(bands, cube.bandCount()); // See if the cube has a projection and make sure it matches // previous input cubes Projection *projNew = Isis::ProjectionFactory::CreateFromCube(*(cube.label())); if ((proj != NULL) && (*proj != *projNew)) { QString msg = "Mapping groups do not match between cubes [" + propagationCubes[0].toString() + "] and [" + propagationCubes[i].toString() + "]"; throw IException(IException::User, msg, _FILEINFO_); } // Figure out the x/y range as it may be needed later double x = projNew->ToProjectionX(0.5); double y = projNew->ToProjectionY(0.5); if (x < xmin) xmin = x; if (y < ymin) ymin = y; if (x > xmax) xmax = x; if (y > ymax) ymax = y; x = projNew->ToProjectionX(cube.sampleCount() + 0.5); y = projNew->ToProjectionY(cube.lineCount() + 0.5); if (x < xmin) xmin = x; if (y < ymin) ymin = y; if (x > xmax) xmax = x; if (y > ymax) ymax = y; slat = min(slat, projNew->MinimumLatitude()); elat = max(elat, projNew->MaximumLatitude()); slon = min(slon, projNew->MinimumLongitude()); elon = max(elon, projNew->MaximumLongitude()); // Cleanup cube.close(); if (proj) delete proj; proj = projNew; } if (proj) delete proj; return SetOutputCube(propagationCubes[0].toString(), xmin, xmax, ymin, ymax, slat, elat, slon, elon, bands, oAtt, mosaicFile); }
void gbl::FixWagoLines(QString file) { // Nothing to do for narrow angle if(gbl::moc->NarrowAngle()) return; // Open the cube to repair Cube fix; fix.open(file, "rw"); const int nl = fix.lineCount(); // Create a line manager on the cube for I/O LineManager lbuf(fix); // Determine which lines need to be examined double lastGain = moc->Gain(); double lastOffset = moc->Offset(); vector<int> fixList; for(int line = 2; line <= nl; line++) { double gain = moc->Gain(line); double offset = moc->Offset(line); if((lastGain != gain) || (lastOffset != offset)) fixList.push_back(line); lastGain = gain; lastOffset = offset; } const int nlBefore = 2; const int nlAfter = 2; const int nlavg = 4; const double fixFactor = 1.5; // Loop for each line to fix for(unsigned int i = 0; i < fixList.size(); i++) { // We will examine a window of lines around the wago change int centerLine = fixList[i]; int sl = centerLine - nlBefore - nlavg; int el = centerLine + nlAfter + nlavg; // Don't do anything if the window is outside the image if(sl < 1) continue; if(el < 1) continue; if(sl > nl) continue; if(el > nl) continue; // Find the closest non-zero output line average before the wago line int slBefore = sl; int elBefore = sl + nlavg; int indexBefore = -1; for(int line = elBefore; line >= slBefore; line--) { if(gbl::outLineAvg[line-1] != 0.0) { indexBefore = line - 1; break; } } if(indexBefore < 0) continue; double oavgBefore = gbl::outLineAvg[indexBefore]; // Find the closest non-zero output line average before the wago line int slAfter = el - nlavg; int elAfter = el; int indexAfter = -1; for(int line = slAfter; line <= elAfter; line++) { if(gbl::outLineAvg[line-1] != 0.0) { indexAfter = line - 1; break; } } if(indexAfter < 0) continue; double oavgAfter = gbl::outLineAvg[indexAfter]; // Get the corresponding input averages and compute net WAGO change // Don't do anything if the net change is invalid double iavgBefore = gbl::inLineAvg[indexBefore]; double iavgAfter = gbl::inLineAvg[indexAfter]; double sum = (iavgBefore / iavgAfter) / (oavgBefore / oavgAfter); if(abs(1.0 - sum) < 0.05) continue; // Prep to fix the lines sl = centerLine - nlBefore; el = centerLine + nlAfter; int nlFix = el - sl + 1; double fixinc = (oavgAfter - oavgBefore) / (nlFix + 1); double base = oavgBefore; double avgTol = abs(fixinc * fixFactor); // Loop and fix each one for(int line = sl; line <= el; line++) { base += fixinc; double avg = base - gbl::outLineAvg[line-1]; // Do we need to fix this line? if(abs(avg) <= avgTol) continue; // Read the line lbuf.SetLine(line); fix.read(lbuf); // Null it if(gbl::nullWago) { for(int samp = 0 ; samp < lbuf.size(); samp++) { lbuf[samp] = Null; } outLineAvg[line-1] = 0.0; } // or repair it else { avg = outLineAvg[line-1]; outLineAvg[line-1] = base; for(int samp = 0; samp < lbuf.size(); samp++) { if(IsValidPixel(lbuf[samp])) { lbuf[samp] = lbuf[samp] / avg * base; } } } // Write the line fix.write(lbuf); } } // Cleanup fix.close(); }
void IsisMain() { try { // We will be processing by line ProcessByLine p; double sscale, lscale; int ins, inl, inb; int ons, onl; vector<QString> bands; Cube inCube; // To propogate labels, set input cube, // this cube will be cleared after output cube is set. p.SetInputCube("FROM"); // Setup the input and output cubes UserInterface &ui = Application::GetUserInterface(); QString replaceMode = ui.GetAsString("VPER_REPLACE"); CubeAttributeInput cai(ui.GetAsString("FROM")); bands = cai.bands(); inCube.setVirtualBands(bands); QString from = ui.GetFileName("FROM"); inCube.open(from); ins = inCube.sampleCount(); inl = inCube.lineCount(); inb = inCube.bandCount(); QString alg = ui.GetString("ALGORITHM"); double vper = ui.GetDouble("VALIDPER") / 100.; if(ui.GetString("MODE") == "TOTAL") { ons = ui.GetInteger("ONS"); onl = ui.GetInteger("ONL"); sscale = (double)ins / (double)ons; lscale = (double)inl / (double)onl; } else { sscale = ui.GetDouble("SSCALE"); lscale = ui.GetDouble("LSCALE"); ons = (int)((double)ins / sscale + 0.5); onl = (int)((double)inl / lscale + 0.5); } if(ons > ins || onl > inl) { QString msg = "Number of output samples/lines must be less than or equal"; msg = msg + " to the input samples/lines."; throw IException(IException::User, msg, _FILEINFO_); } // Allocate output file Cube *ocube = p.SetOutputCube("TO", ons, onl, inb); // Our processing routine only needs 1 // the original set was for info about the cube only p.ClearInputCubes(); // Start the processing PvlGroup results; if(alg == "AVERAGE"){ Average average(&inCube, sscale, lscale, vper, replaceMode); p.ProcessCubeInPlace(average, false); results = average.UpdateOutputLabel(ocube); } else if(alg == "NEAREST") { Nearest near(&inCube, sscale, lscale); p.ProcessCubeInPlace(near, false); results = near.UpdateOutputLabel(ocube); } // Cleanup inCube.close(); p.EndProcess(); // Write the results to the log Application::Log(results); } // REFORMAT THESE ERRORS INTO ISIS TYPES AND RETHROW catch (IException &) { throw; } catch (std::exception const &se) { QString message = "std::exception: " + (QString)se.what(); throw IException(IException::User, message, _FILEINFO_); } catch (...) { QString message = "Other Error"; throw IException(IException::User, message, _FILEINFO_); } }
void IsisMain() { // We will be processing by line ProcessByTile p; p.SetTileSize(128, 128); // Setup the input and output cubes Cube* info = p.SetInputCube("FROM"); PvlKeyword &status = info ->group("RESEAUS")["STATUS"]; UserInterface &ui = Application::GetUserInterface(); QString in = ui.GetFileName("FROM"); QString spacecraft = (info->group("Instrument")["SpacecraftName"]); QString instrument = (info->group("Instrument")["InstrumentId"]); Apollo apollo(spacecraft, instrument); if (spacecraft.mid(0,6) != "APOLLO") { QString msg = "This application is for use with Apollo spacecrafts only. "; throw IException(IException::Unknown, msg, _FILEINFO_); } // 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(); dim = apollo.ReseauDimension(); // 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(dim,dim,1,cube.pixelType()); int width = ui.GetInteger("WIDTH"); for (int res=0; res<numres; res++) { if ((resvalid == 0 || toInt(valid[res]) == 1)) { int baseSamp = (int)(toDouble(samps[res])+0.5) - (dim/2); int baseLine = (int)(toDouble(lines[res])+0.5) - (dim/2); brick.SetBasePosition(baseSamp,baseLine,1); cube.read(brick); if (action == "NULL") { // set the three pixels surrounding the reseau to null for (int i=0; i<dim; i++) { for (int j=(width-1)/-2; j<=width/2; j++) { // vertical lines brick[dim*i+dim/2+j] = Isis::Null; // horizontal lines brick[dim*(dim/2+j)+i] = Isis::Null; } } } else if (action == "PATCH") { for (int i = 0; i < dim; i++) { for (int j=(width-1)/-2; j<=width/2; j++) { // vertical lines brick[dim*i+dim/2+j] = (brick[dim*i+dim/2-width+j] + brick[dim*i+dim/2+width+j])/2.0; // horizontal lines brick[dim*(dim/2+j)+i] = (brick[dim*(dim/2-width+j)+i]+brick[dim*(dim/2+width+j)+i])/2.0; } } } } cube.write(brick); } cube.close(); }
void IsisMain() { // Create a process so we can output the noproj'd labels without overwriting Process p; // Open the user interface and get the input file and the ideal specs file UserInterface &ui = Application::GetUserInterface(); Cube *mcube, *icube; // If a MATCH cube is entered, make sure to SetInputCube it first to get the SPICE blobs // from it propagated to the TO labels // Until polygon blobs are detached without "/" don't propagate them p.PropagatePolygons(false); if((ui.WasEntered("MATCH"))) { mcube = p.SetInputCube("MATCH"); icube = p.SetInputCube("FROM"); } else { mcube = icube = p.SetInputCube("FROM"); } Camera *incam = mcube->camera(); // Extract Instrument groups from input labels for the output match and noproj'd cubes PvlGroup inst = mcube->group("Instrument"); PvlGroup fromInst = icube->group("Instrument"); QString groupName = (QString) inst["SpacecraftName"] + "/"; groupName += (QString) inst.findKeyword("InstrumentId"); // Get Ideal camera specifications FileName specs; if((ui.WasEntered("SPECS"))) { specs = ui.GetFileName("SPECS"); } else { specs = "$base/applications/noprojInstruments???.pvl"; specs = specs.highestVersion(); } Pvl idealSpecs(specs.expanded()); PvlObject obSpecs = idealSpecs.findObject("IdealInstrumentsSpecifications"); PvlGroup idealGp = obSpecs.findGroup(groupName); double transx, transy, transl, transs; transx = transy = transl = transs = 0.; if(idealGp.hasKeyword("TransX")) transx = idealGp["TransX"]; if(idealGp.hasKeyword("TransY")) transy = idealGp["TransY"]; if(idealGp.hasKeyword("ItransL")) transl = idealGp["ItransL"]; if(idealGp.hasKeyword("ItransS")) transs = idealGp["ItransS"]; int detectorSamples = mcube->sampleCount(); if(idealGp.hasKeyword("DetectorSamples")) detectorSamples = idealGp["DetectorSamples"]; int numberLines = mcube->lineCount(); int numberBands = mcube->bandCount(); if(idealGp.hasKeyword("DetectorLines")) numberLines = idealGp["DetectorLines"]; int xDepend = incam->FocalPlaneMap()->FocalPlaneXDependency(); // Get output summing mode if(ui.GetString("SOURCE") == "FROMMATCH") { LoadMatchSummingMode(); } else if(ui.GetString("SOURCE") == "FROMINPUT") { LoadInputSummingMode(); } double pixPitch = incam->PixelPitch() * ui.GetDouble("SUMMINGMODE"); detectorSamples /= (int)(ui.GetDouble("SUMMINGMODE")); // Get the user options int sampleExpansion = int((ui.GetDouble("SAMPEXP") / 100.) * detectorSamples + .5); int lineExpansion = int((ui.GetDouble("LINEEXP") / 100.) * numberLines + .5); QString instType; // Adjust translations for summing mode transl /= ui.GetDouble("SUMMINGMODE"); transs /= ui.GetDouble("SUMMINGMODE"); detectorSamples += sampleExpansion; numberLines += lineExpansion; // Determine whether this ideal camera is a line scan or framing camera and // set the instrument id and exposure int detectorLines; int expandFlag; if(incam->DetectorMap()->LineRate() != 0.0) { instType = "LINESCAN"; // Isis3 line rate is always in seconds so convert to milliseconds for the // Ideal instrument detectorLines = 1; expandFlag = 1; } else { instType = "FRAMING"; detectorLines = numberLines; expandFlag = 0; // Framing cameras don't need exposure time } // Adjust focal plane translations with line expansion for scanners since // the CCD is only 1 line if(expandFlag) { transl += lineExpansion / 2; if(xDepend == CameraFocalPlaneMap::Line) { transx -= lineExpansion / 2.*pixPitch * expandFlag; } else { transy -= lineExpansion / 2.*pixPitch * expandFlag; } } // Get the start time for parent line 1 AlphaCube alpha(*icube); double sample = alpha.BetaSample(.5); double line = alpha.BetaLine(.5); incam->SetImage(sample, line); double et = incam->time().Et(); // Get the output file name and set its attributes CubeAttributeOutput cao; // Can we do a regular label? Didn't work on 12-15-2006 cao.setLabelAttachment(Isis::DetachedLabel); // Determine the output image size from // 1) the idealInstrument pvl if there or // 2) the input size expanded by user specified percentage Cube *ocube = p.SetOutputCube("match.cub", cao, 1, 1, 1); // Extract the times and the target from the instrument group QString startTime = inst["StartTime"]; QString stopTime; if(inst.hasKeyword("StopTime")) stopTime = (QString) inst["StopTime"]; QString target = inst["TargetName"]; // rename the instrument groups inst.setName("OriginalInstrument"); fromInst.setName("OriginalInstrument"); // add it back to the IsisCube object under a new group name ocube->putGroup(inst); // and remove the version from the IsisCube Object ocube->deleteGroup("Instrument"); // Now rename the group back to the Instrument group and clear out old keywords inst.setName("Instrument"); inst.clear(); // Add keywords for the "Ideal" instrument Isis::PvlKeyword key("SpacecraftName", "IdealSpacecraft"); inst.addKeyword(key); key.setName("InstrumentId"); key.setValue("IdealCamera"); inst.addKeyword(key); key.setName("TargetName"); key.setValue(target); inst.addKeyword(key); key.setName("SampleDetectors"); key.setValue(Isis::toString(detectorSamples)); inst.addKeyword(key); key.setName("LineDetectors"); key.setValue(Isis::toString(detectorLines)); inst.addKeyword(key); key.setName("InstrumentType"); key.setValue(instType); inst.addKeyword(key); Pvl &ocubeLabel = *ocube->label(); PvlObject *naifKeywordsObject = NULL; if (ocubeLabel.hasObject("NaifKeywords")) { naifKeywordsObject = &ocubeLabel.findObject("NaifKeywords"); // Clean up the naif keywords object... delete everything that isn't a radii for (int keyIndex = naifKeywordsObject->keywords() - 1; keyIndex >= 0; keyIndex--) { QString keyName = (*naifKeywordsObject)[keyIndex].name(); if (!keyName.contains("RADII")) { naifKeywordsObject->deleteKeyword(keyIndex); } } // Clean up the kernels group... delete everything that isn't internalized or the orig frame // code PvlGroup &kernelsGroup = ocube->group("Kernels"); for (int keyIndex = kernelsGroup.keywords() - 1; keyIndex >= 0; keyIndex--) { PvlKeyword &kernelsKeyword = kernelsGroup[keyIndex]; bool isTable = false; bool isFrameCode = kernelsKeyword.isNamed("NaifFrameCode") || kernelsKeyword.isNamed("NaifIkCode"); bool isShapeModel = kernelsKeyword.isNamed("ShapeModel"); for (int keyValueIndex = 0; keyValueIndex < kernelsKeyword.size(); keyValueIndex++) { if (kernelsKeyword[keyValueIndex] == "Table") { isTable = true; } } if (!isTable && !isFrameCode && !isShapeModel) { kernelsGroup.deleteKeyword(keyIndex); } } } if (naifKeywordsObject) { naifKeywordsObject->addKeyword(PvlKeyword("IDEAL_FOCAL_LENGTH", toString(incam->FocalLength())), Pvl::Replace); } else { inst.addKeyword(PvlKeyword("FocalLength", toString(incam->FocalLength()), "millimeters")); } double newPixelPitch = incam->PixelPitch() * ui.GetDouble("SUMMINGMODE"); if (naifKeywordsObject) { naifKeywordsObject->addKeyword(PvlKeyword("IDEAL_PIXEL_PITCH", toString(newPixelPitch)), Pvl::Replace); } else { inst.addKeyword(PvlKeyword("PixelPitch", toString(newPixelPitch), "millimeters")); } key.setName("EphemerisTime"); key.setValue(Isis::toString(et), "seconds"); inst.addKeyword(key); key.setName("StartTime"); key.setValue(startTime); inst.addKeyword(key); if(stopTime != "") { key.setName("StopTime"); key.setValue(stopTime); inst.addKeyword(key); } key.setName("FocalPlaneXDependency"); key.setValue(toString((int)incam->FocalPlaneMap()->FocalPlaneXDependency())); inst.addKeyword(key); int xDependency = incam->FocalPlaneMap()->FocalPlaneXDependency(); double newInstrumentTransX = incam->FocalPlaneMap()->SignMostSigX(); inst.addKeyword(PvlKeyword("TransX", toString(newInstrumentTransX))); double newInstrumentTransY = incam->FocalPlaneMap()->SignMostSigY(); inst.addKeyword(PvlKeyword("TransY", toString(newInstrumentTransY))); storeSpice(&inst, naifKeywordsObject, "TransX0", "IDEAL_TRANSX", transx, newPixelPitch * newInstrumentTransX, (xDependency == CameraFocalPlaneMap::Sample)); storeSpice(&inst, naifKeywordsObject, "TransY0", "IDEAL_TRANSY", transy, newPixelPitch * newInstrumentTransY, (xDependency == CameraFocalPlaneMap::Line)); double transSXCoefficient = 1.0 / newPixelPitch * newInstrumentTransX; double transLXCoefficient = 1.0 / newPixelPitch * newInstrumentTransY; if (xDependency == CameraFocalPlaneMap::Line) { swap(transSXCoefficient, transLXCoefficient); } storeSpice(&inst, naifKeywordsObject, "TransS0", "IDEAL_TRANSS", transs, transSXCoefficient, (xDependency == CameraFocalPlaneMap::Sample)); storeSpice(&inst, naifKeywordsObject, "TransL0", "IDEAL_TRANSL", transl, transLXCoefficient, (xDependency == CameraFocalPlaneMap::Line)); if(instType == "LINESCAN") { key.setName("ExposureDuration"); key.setValue(Isis::toString(incam->DetectorMap()->LineRate() * 1000.), "milliseconds"); inst.addKeyword(key); } key.setName("MatchedCube"); key.setValue(mcube->fileName()); inst.addKeyword(key); ocube->putGroup(inst); p.EndProcess(); // Now adjust the label to fake the true size of the image to match without // taking all the space it would require for the image data Pvl label; label.read("match.lbl"); PvlGroup &dims = label.findGroup("Dimensions", Pvl::Traverse); dims["Lines"] = toString(numberLines); dims["Samples"] = toString(detectorSamples); dims["Bands"] = toString(numberBands); label.write("match.lbl"); // And run cam2cam to apply the transformation QString parameters; parameters += " FROM= " + ui.GetFileName("FROM"); parameters += " MATCH= " + QString("match.cub"); parameters += " TO= " + ui.GetFileName("TO"); parameters += " INTERP=" + ui.GetString("INTERP"); ProgramLauncher::RunIsisProgram("cam2cam", parameters); // Cleanup by deleting the match files remove("match.History.IsisCube"); remove("match.lbl"); remove("match.cub"); remove("match.OriginalLabel.IsisCube"); remove("match.Table.BodyRotation"); remove("match.Table.HiRISE Ancillary"); remove("match.Table.HiRISE Calibration Ancillary"); remove("match.Table.HiRISE Calibration Image"); remove("match.Table.InstrumentPointing"); remove("match.Table.InstrumentPosition"); remove("match.Table.SunPosition"); // Finally finish by adding the OriginalInstrument group to the TO cube Cube toCube; toCube.open(ui.GetFileName("TO"), "rw"); // Extract label and create cube object Pvl *toLabel = toCube.label(); PvlObject &o = toLabel->findObject("IsisCube"); o.deleteGroup("OriginalInstrument"); o.addGroup(fromInst); toCube.close(); }
void IsisMain() { Process p; Cube *icube = p.SetInputCube("FROM"); Camera *cam = icube->camera(); UserInterface &ui = Application::GetUserInterface(); QString from = ui.GetFileName("FROM"); int sinc = ui.GetInteger("SINC"); int linc = ui.GetInteger("LINC"); CameraStatistics camStats(cam, sinc, linc, from); // Send the Output to the log area Pvl statsPvl = camStats.toPvl(); for (int i = 0; i < statsPvl.groups(); i++) { Application::Log(statsPvl.group(i)); } if(ui.WasEntered("TO")) { QString outfile = FileName(ui.GetFileName("TO")).expanded(); bool exists = FileName(outfile).fileExists(); bool append = ui.GetBoolean("APPEND"); // If the user chose a format of PVL, then write to the output file ("TO") if(ui.GetString("FORMAT") == "PVL") { (append) ? statsPvl.append(outfile) : statsPvl.write(outfile); } else { // Create a flatfile of the data with columhn headings the flatfile is // comma-delimited and can be imported in to spreadsheets ofstream os; bool writeHeader = true; if(append) { os.open(outfile.toAscii().data(), ios::app); if(exists) { writeHeader = false; } } else { os.open(outfile.toAscii().data(), ios::out); } // if new file or append and no file exists then write header if(writeHeader) { os << "Filename," << "LatitudeMinimum," << "LatitudeMaximum," << "LatitudeAverage," << "LatitudeStandardDeviation," << "LongitudeMinimum," << "LongitudeMaximum," << "LongitudeAverage," << "LongitudeStandardDeviation," << "SampleResolutionMinimum," << "SampleResolutionMaximum," << "SampleResolutionAverage," << "SampleResolutionStandardDeviation," << "LineResolutionMinimum," << "LineResolutionMaximum," << "LineResolutionAverage," << "LineResolutionStandardDeviation," << "ResolutionMinimum," << "ResolutionMaximum," << "ResolutionAverage," << "ResolutionStandardDeviation," << "AspectRatioMinimum," << "AspectRatioMaximum," << "AspectRatioAverage," << "AspectRatioStandardDeviation," << "PhaseMinimum," << "PhaseMaximum," << "PhaseAverage," << "PhaseStandardDeviation," << "EmissionMinimum," << "EmissionMaximum," << "EmissionAverage," << "EmissionStandardDeviation," << "IncidenceMinimum," << "IncidenceMaximum," << "IncidenceAverage," << "IncidenceStandardDeviation," << "LocalSolarTimeMinimum," << "LocalSolarTimeMaximum," << "LocalSolarTimeAverage," << "LocalSolarTimeStandardDeviation," << "LocalRadiusMaximum," << "LocalRadiusMaximum," << "LocalRadiusAverage," << "LocalRadiusStandardDeviation," << "NorthAzimuthMinimum," << "NorthAzimuthMaximum," << "NorthAzimuthAverage," << "NorthAzimuthStandardDeviation," << endl; } os << FileName(from).expanded() << ","; //call the function to write out the values for each group writeFlat(os, camStats.getLatStat()); writeFlat(os, camStats.getLonStat()); writeFlat(os, camStats.getSampleResStat()); writeFlat(os, camStats.getLineResStat()); writeFlat(os, camStats.getResStat()); writeFlat(os, camStats.getAspectRatioStat()); writeFlat(os, camStats.getPhaseStat()); writeFlat(os, camStats.getEmissionStat()); writeFlat(os, camStats.getIncidenceStat()); writeFlat(os, camStats.getLocalSolarTimeStat()); writeFlat(os, camStats.getLocalRaduisStat()); writeFlat(os, camStats.getNorthAzimuthStat()); os << endl; } } if(ui.GetBoolean("ATTACH")) { QString cam_name = "CameraStatistics"; //Creates new CameraStatistics Table TableField fname("Name", Isis::TableField::Text, 20); TableField fmin("Minimum", Isis::TableField::Double); TableField fmax("Maximum", Isis::TableField::Double); TableField favg("Average", Isis::TableField::Double); TableField fstd("StandardDeviation", Isis::TableField::Double); TableRecord record; record += fname; record += fmin; record += fmax; record += favg; record += fstd; Table table(cam_name, record); // Place all the gathered camera statistics in a table and attach it to the // cube. Skip "User Parameters" group. for (int i = 1; i < statsPvl.groups(); i++) { PvlGroup &group = statsPvl.group(i); int entry = 0; record[entry] = group.name(); entry++; for (int j = 0; j < group.keywords(); j++) { record[entry] = toDouble(group[j][0]); entry++; } table += record; } icube->reopen("rw"); icube->write(table); p.WriteHistory(*icube); icube->close(); } }