//Function to translate the labels void TranslateLrocNacLabels ( Filename &labelFile, Cube *ocube ) { //Pvl to store the labels Pvl outLabel; //Set up the directory where the translations are PvlGroup dataDir(Preference::Preferences().FindGroup("DataDirectory")); iString transDir = (string) dataDir["Lro"] + "/translations/"; Pvl labelPvl(labelFile.Expanded()); //Translate the Instrument group Filename transFile(transDir + "lronacInstrument.trn"); PvlTranslationManager instrumentXlator(labelPvl, transFile.Expanded()); instrumentXlator.Auto(outLabel); //Translate the Archive group transFile = transDir + "lronacArchive.trn"; PvlTranslationManager archiveXlater(labelPvl, transFile.Expanded()); archiveXlater.Auto(outLabel); // Set up the BandBin groups PvlGroup bbin("BandBin"); bbin += PvlKeyword("FilterName", "BroadBand"); bbin += PvlKeyword("Center", 0.650, "micrometers"); bbin += PvlKeyword("Width", 0.150, "micrometers"); Pvl lab(labelFile.Expanded()); //Set up the Kernels group PvlGroup kern("Kernels"); if (lab.FindKeyword("FRAME_ID")[0] == "LEFT") kern += PvlKeyword("NaifFrameCode", -85600); else kern += PvlKeyword("NaifFrameCode", -85610); PvlGroup inst = outLabel.FindGroup("Instrument", Pvl::Traverse); if (lab.FindKeyword("FRAME_ID")[0] == "LEFT") { inst.FindKeyword("InstrumentId") = "NACL"; inst.FindKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA LEFT"; g_flip = false; } else { inst.FindKeyword("InstrumentId") = "NACR"; inst.FindKeyword("InstrumentName") = "LUNAR RECONNAISSANCE ORBITER NARROW ANGLE CAMERA RIGHT"; } inst += PvlKeyword("SpatialSumming", lab.FindKeyword("CROSSTRACK_SUMMING")[0] ); inst += PvlKeyword("SampleFirstPixel", 0 ); //Add all groups to the output cube ocube->PutGroup(inst); ocube->PutGroup(outLabel.FindGroup("Archive", Pvl::Traverse)); ocube->PutGroup(bbin); ocube->PutGroup(kern); }
// Updates existing BandBin keywords with additional values to ensure // label compilancy (which should support Camera models). It checks for the // existance of the keyword and uses its (assumed) first value to set nvals // values to a constant. If the keyword doesn't exist, it uses the default // value. void UpdateBandKey(const QString &keyname, PvlGroup &bb, const int &nvals, const QString &default_value) { QString defVal(default_value); if ( bb.hasKeyword(keyname) ) { defVal = bb[keyname][0]; } bb.addKeyword(makeKey(keyname, nvals, defVal), PvlContainer::Replace); return; }
void Stretch::Save(Isis::Pvl &pvl, QString &grpName) { PvlGroup *grp = new PvlGroup(grpName); PvlKeyword inputs("Input"); PvlKeyword outputs("Output"); for(int i = 0; i < Pairs(); i++) { inputs.addValue(toString(Input(i))); outputs.addValue(toString(Output(i))); } grp->addKeyword(inputs); grp->addKeyword(outputs); pvl.addGroup(*grp); }
/** * Loads the stretch pairs from the pvl file into the Stretch * object. The pvl should look similar to this: * @code * Group = Pairs * Input = (0,100,255) * Output = (255,100,0) * EndGroup * @endcode * * @param pvl - The pvl containing the stretch pairs * @param grpName - The group name to get the input and output * keywords from */ void Stretch::Load(Isis::Pvl &pvl, QString &grpName) { PvlGroup grp = pvl.findGroup(grpName, Isis::PvlObject::Traverse); PvlKeyword inputs = grp.findKeyword("Input"); PvlKeyword outputs = grp.findKeyword("Output"); if(inputs.size() != outputs.size()) { QString msg = "Invalid Pvl file: The number of Input values must equal the number of Output values"; throw IException(IException::User, msg, _FILEINFO_); } for(int i = 0; i < inputs.size(); i++) { AddPair(toDouble(inputs[i]), toDouble(outputs[i])); } }
/** * Reads the DefFile having info about the different filters to * be used on the Control Network. * * @author Sharmila Prasad (9/7/2010) * * @param pcNetFilter * @param pvlDefFile */ void ReadDefFile(ControlNetFilter & pcNetFilter, Pvl & pvlDefFile) { // prototype to ControlNetFilter member function void (ControlNetFilter::*pt2Filter)(const PvlGroup & pvlGrp, bool pbLastFilter); // Parse the Groups in Point Object PvlObject filtersObj = pvlDefFile.findObject("Filters", Pvl::Traverse); int iNumGroups = filtersObj.groups(); for (int i=0; i<iNumGroups; i++) { PvlGroup pvlGrp = filtersObj.group(i); // Get the pointer to ControlNetFilter member function based on Group name pt2Filter=GetPtr2Filter(pvlGrp.name()); if (pt2Filter != NULL) { (pcNetFilter.*pt2Filter)(pvlGrp, ((i==(iNumGroups-1)) ? true : false)); } } }
//! Constructs a HiLab Object HiLab::HiLab(Cube *cube){ PvlGroup group = cube->GetGroup("Instrument"); p_cpmmNumber = group["CpmmNumber"]; p_channel = group["ChannelNumber"]; if (group.HasKeyword("Summing")) { p_bin = group["Summing"]; } else { std::string msg = "Cannot find required Summing keyword in label"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } if (group.HasKeyword("Tdi")) { p_tdi = group["Tdi"]; } else { std::string msg = "Cannot find required Tdi keyword in label"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } }
/** * @brief Writes data specific to calibration statistics in Pvl Format * * This method is a compartmentalization of the writing of the contents of * a HiImageClean object. * * This method dumps the calibration statistics computed from the HiRISE * cube specifed on construction or through the load methods. */ void HiImageClean::PvlCalStats(PvlGroup &grp) const { grp.SetName("CalibrationStatistics"); grp += PvlKeyword("Binning",_binning); grp += PvlKeyword("TDI",_tdi); grp += PvlKeyword("CPMM",_cpmm); grp += PvlKeyword("Channel",_channelNo); grp += PvlKeyword("FirstImageSample",_firstImageSample); grp += PvlKeyword("FirstImageLine",_firstImageLine); grp += PvlKeyword("FirstBufferSample",_firstBufferSample); grp += PvlKeyword("FirstDarkSample",_firstDarkSample); grp += PvlKeyword("MaskInducedNulls", _totalMaskNulled); grp += PvlKeyword("DarkInducedNulls", _totalDarkNulled); grp += PvlKeyword("LastGoodLine",_lastGoodLine+1); }
/** * Create and initialize a Latitude value using the mapping group's latitude * units and radii. * * @see ErrorChecking * @see CoordinateType * @param latitude The latitude value this instance will represent, * in the mapping group's units * @param mapping A mapping group * @param latitudeUnits The angular units of the latitude value (degs, rads) * @param errors Error checking conditions */ Latitude::Latitude(double latitude, PvlGroup mapping, Angle::Units latitudeUnits, ErrorChecking errors) : Angle(latitude, latitudeUnits) { m_equatorialRadius = NULL; m_polarRadius = NULL; if (mapping.hasKeyword("EquatorialRadius") && mapping.hasKeyword("PolarRadius")) { m_equatorialRadius = new Distance(toDouble(mapping["EquatorialRadius"][0]), Distance::Meters); m_polarRadius = new Distance(toDouble(mapping["PolarRadius"][0]), Distance::Meters); } else { PvlGroup radiiGrp = TProjection::TargetRadii(mapping["TargetName"]); m_equatorialRadius = new Distance(toDouble(radiiGrp["EquatorialRadius"][0]), Distance::Meters); m_polarRadius = new Distance(toDouble(radiiGrp["PolarRadius"][0]), Distance::Meters); } m_errors = errors; if(mapping["LatitudeType"][0] == "Planetographic") { setPlanetographic(latitude, latitudeUnits); } else if(mapping["LatitudeType"][0] == "Planetocentric") { setPlanetocentric(latitude, latitudeUnits); } else { IString msg = "Latitude type [" + IString(mapping["LatitudeType"][0]) + "] is not recognized"; throw IException(IException::Programmer, msg, _FILEINFO_); } }
/** * With the Channel, CCD in the isis label, find the coefficient values * for this image * * @author Sharmila Prasad (11/24/2010) * * @param pCubeLabel */ void GetCCD_Channel_Coefficients(Pvl & pCubeLabel) { int iChannel=-1, iSumming=-1; QString sCcd=""; PvlGroup instrGrp = pCubeLabel.findObject("IsisCube").findGroup("Instrument"); // Summing keyword if (!instrGrp.hasKeyword("Summing")) { QString sMsg = "Summing keyword not found"; throw IException(IException::User, sMsg, _FILEINFO_); } else { PvlKeyword binKey = instrGrp.findKeyword("Summing"); iSumming = toInt(binKey[0]); if (iSumming != 1 && iSumming != 2 && iSumming != 4) { QString sMsg = "Invalid Summing value in input file, must be 1,2,or 4"; throw IException(IException::User, sMsg, _FILEINFO_); } } // CCD Keyword if (!instrGrp.hasKeyword("CcdId")) { QString sMsg = "CcdId keyword not found"; throw IException(IException::User, sMsg, _FILEINFO_); } else { PvlKeyword ccdKey = instrGrp.findKeyword("CcdId"); sCcd = ccdKey[0]; } // Channel Keyword if (!instrGrp.hasKeyword("ChannelNumber")) { QString sMsg = "ChannelNumber keyword not found"; throw IException(IException::User, sMsg, _FILEINFO_); } else { PvlKeyword channelKey = instrGrp.findKeyword("ChannelNumber"); iChannel = toInt(channelKey[0]); } // Get the coefficient file name QString dCoeffFile = "$mro/calibration/HiRISE_Gain_Drift_Correction_Bin" + toString(iSumming) + ".0001.csv"; //QString dCoeffFile = "/home/sprasad/isis3/isis/src/mro/apps/hicalproc/HiRISE_Gain_Drift_Correction_Bin" + toString(iSumming) + ".0001.csv"; #ifdef _DEBUG_ cout << dCoeffFile << endl; #endif // Get the coefficients ReadCoefficientFile(FileName(dCoeffFile).expanded(), sCcd, iChannel); }
/** * @brief Writes data specific to image statistics out in Pvl format * * This method creates a PvlGroup containing the image statistics * acculated during line-by-line processing of raw image data. */ void HiImageClean::PvlImageStats(PvlGroup &grp) const { grp.SetName("ImageStatistics"); grp += PvlKeyword("File",_filename.Name()); grp += PvlKeyword("Lines",_lines); grp += PvlKeyword("Samples",_samples); BigInt nBad = _maskStats.TotalPixels() - _maskStats.ValidPixels(); grp += PvlKeyword("MaskAverage", _maskStats.Average()); grp += PvlKeyword("MaskStdDev", _maskStats.StandardDeviation()); grp += PvlKeyword("BadMaskPixels", nBad); grp += PvlKeyword("MaskInducedNulls", _totalMaskNulled); nBad = _darkStats.TotalPixels() - _darkStats.ValidPixels(); grp += PvlKeyword("DarkAverage", _darkStats.Average()); grp += PvlKeyword("DarkStdDev", _darkStats.StandardDeviation()); grp += PvlKeyword("BadDarkPixels", nBad); grp += PvlKeyword("DarkInducedNulls", _totalDarkNulled); }
void IsisMain() { // We will be processing by brick ProcessByBrick p; Isis::Cube *amatrixCube=NULL; Isis::Cube *bmatrixCube=NULL; // Setup the user input for the input/output files and the option UserInterface &ui = Application::GetUserInterface(); // Setup the input HiRise cube Isis::Cube *icube = p.SetInputCube("FROM"); if (icube->Bands() != 1) { std::string msg = "Only single-band HiRise cubes can be calibrated"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } //Get pertinent label information to determine which band of matrix cube to use HiLab hilab(icube); int ccd = hilab.getCcd(); int channel = hilab.getChannel(); if (channel != 0 && channel != 1) { std::string msg = "Only unstitched cubes can be calibrated"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } int band = 1 + ccd*2 + channel; string option = ui.GetString("OPTION"); // Set attributes (input band number) for the matrix cube(s); CubeAttributeInput att("+" + iString(band)); // Determine the file specification to the matrix file(s) if defaulted // and open if (ui.WasEntered ("MATRIX") ) { if (option == "GAIN") { string matrixFile = ui.GetFilename("MATRIX"); amatrixCube = p.SetInputCube(matrixFile, att); } else if (option == "OFFSET") { string matrixFile = ui.GetFilename("MATRIX"); bmatrixCube = p.SetInputCube(matrixFile, att); } else { //(option == "BOTH") std::string msg = "The BOTH option cannot be used if a MATRIX is entered"; throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); } } else { int tdi = hilab.getTdi(); int bin = hilab.getBin(); if (option == "OFFSET" || option == "BOTH") { std::string bmatrixFile = "$mro/calibration"; bmatrixFile += "/B_matrix_tdi"; bmatrixFile += iString(tdi) + "_bin" + iString(bin); bmatrixCube = p.SetInputCube(bmatrixFile, att); } if (option == "GAIN" || option == "BOTH") { std::string amatrixFile = "$mro/calibration"; amatrixFile += "/A_matrix_tdi"; amatrixFile += iString(tdi) + "_bin" + iString(bin); amatrixCube = p.SetInputCube(amatrixFile, att); } } // Open the output file and set processing parameters Cube *ocube = p.SetOutputCube ("TO"); p.SetWrap (true); p.SetBrickSize ( icube->Samples(), 1, 1); // Add the radiometry group if it is not there yet. Otherwise // read the current value of the keyword CalibrationParameters. // Then delete the keyword and rewrite it after appending the // new value to it. Do it this way to avoid multiple Calibration // Parameter keywords. PvlGroup calgrp; PvlKeyword calKey; if (ocube->HasGroup("Radiometry")) { calgrp = ocube->GetGroup ("Radiometry"); if (calgrp.HasKeyword("CalibrationParameters")) { calKey = calgrp.FindKeyword("CalibrationParameters"); calgrp.DeleteKeyword( "CalibrationParameters" ); } else { calKey.SetName ("CalibrationParameters"); } } else { calgrp.SetName("Radiometry"); calKey.SetName ("CalibrationParameters"); } string keyValue = option; if (option == "GAIN") { keyValue += ":" + amatrixCube->Filename(); } else if (option == "OFFSET") { keyValue += ":" + bmatrixCube->Filename(); } else { // "BOTH" keyValue += ":"+bmatrixCube->Filename()+":"+amatrixCube->Filename(); } calKey += keyValue; calgrp += calKey; ocube->PutGroup(calgrp); // Start the processing based on the option if (option == "GAIN") { p.StartProcess(mult); } else if (option == "OFFSET") { p.StartProcess(sub); } else { //(option == "BOTH") p.StartProcess(multSub); } // Cleanup p.EndProcess(); }
/** * Get Groups by translating from correct Translation table * * @param label A pvl formatted label to be used to generate the serial number */ PvlGroup ObservationNumber::FindObservationTranslation(Pvl &label) { Pvl outLabel; static PvlGroup dataDir(Preference::Preferences().findGroup("DataDirectory")); // Get the mission name static QString missionTransFile = (QString) dataDir["base"] + "/translations/MissionName2DataDir.trn"; static PvlTranslationManager missionXlater(missionTransFile); missionXlater.SetLabel(label); QString mission = missionXlater.Translate("MissionName"); // Get the instrument name static QString instTransFile = (QString) dataDir["base"] + "/translations/Instruments.trn"; static PvlTranslationManager instrumentXlater(instTransFile); instrumentXlater.SetLabel(label); QString instrument = instrumentXlater.Translate("InstrumentName"); // We want to use this instrument's translation manager. It's much faster for // ObservationNumberList if we keep the translation manager in memory, so re-reading // from the disk is not necessary every time. To do this, we'll use a map to store // the translation managers and observation number keys with a string identifier to find them. // This identifier needs to have the mission name and the instrument name. static std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> > missionTranslators; QString key = mission + "_" + instrument; std::map<QString, std::pair<PvlTranslationManager, PvlKeyword> >::iterator translationIterator = missionTranslators.find(key); if(translationIterator == missionTranslators.end()) { // Get the file FileName snFile((QString) dataDir[mission] + "/translations/" + instrument + "SerialNumber????.trn"); snFile = snFile.highestVersion(); // Delets the extra Pvl translation(snFile.expanded()); PvlKeyword observationKeys; if(translation.hasKeyword("ObservationKeys")) { observationKeys = translation["ObservationKeys"]; } // use the translation file to generate keywords missionTranslators.insert( std::pair<QString, std::pair<PvlTranslationManager, PvlKeyword> > (key, std::pair<PvlTranslationManager, PvlKeyword>(PvlTranslationManager(snFile.expanded()), observationKeys)) ); translationIterator = missionTranslators.find(key); } translationIterator->second.first.SetLabel(label); translationIterator->second.first.Auto(outLabel); PvlGroup snGroup = outLabel.findGroup("SerialNumberKeywords"); // Delets the extra if(!translationIterator->second.second.name().isEmpty()) { snGroup += translationIterator->second.second; } else { snGroup += PvlKeyword("ObservationKeys", toString(snGroup.keywords())); } return snGroup; }
/** * Find the lat/lon range of the image. This will use the image footprint, * camera, or projection in order to find a good result. * * @param Cube* This is required for estimation. You can pass in NULL (it will * disable estimation). * @param minLat This is an output: minimum latitude * @param maxLat This is an output: maximum latitude * @param minLon This is an output: minimum longitude * @param maxLon This is an output: maximum longitude * @param allowEstimation If this is true then extra efforts will be made to * guess the ground range of the input. This can still fail. * @return True if a ground range was found, false if no ground range could * be determined. Some lat/lon results may still be populated; their * values are undefined. */ bool UniversalGroundMap::GroundRange(Cube *cube, Latitude &minLat, Latitude &maxLat, Longitude &minLon, Longitude &maxLon, bool allowEstimation) { // Do we need a RingRange method? // For now just return false if (HasCamera()) if (p_camera->target()->shape()->name() == "Plane") return false; if (HasProjection()) if (p_projection->projectionType() == Projection::RingPlane) return false; minLat = Latitude(); maxLat = Latitude(); minLon = Longitude(); maxLon = Longitude(); // If we have a footprint, use it try { if (cube) { ImagePolygon poly; cube->read(poly); geos::geom::MultiPolygon *footprint = PolygonTools::MakeMultiPolygon( poly.Polys()->clone()); geos::geom::Geometry *envelope = footprint->getEnvelope(); geos::geom::CoordinateSequence *coords = envelope->getCoordinates(); for (unsigned int i = 0; i < coords->getSize(); i++) { const geos::geom::Coordinate &coord = coords->getAt(i); Latitude coordLat(coord.y, Angle::Degrees); Longitude coordLon(coord.x, Angle::Degrees); if (!minLat.isValid() || minLat > coordLat) minLat = coordLat; if (!maxLat.isValid() || maxLat < coordLat) maxLat = coordLat; if (!minLon.isValid() || minLon > coordLon) minLon = coordLon; if (!maxLon.isValid() || maxLon < coordLon) maxLon = coordLon; } delete coords; coords = NULL; delete envelope; envelope = NULL; delete footprint; footprint = NULL; } } catch (IException &) { } if (!minLat.isValid() || !maxLat.isValid() || !minLon.isValid() || !maxLon.isValid()) { if (HasCamera()) { // Footprint failed, ask the camera PvlGroup mappingGrp("Mapping"); mappingGrp += PvlKeyword("LatitudeType", "Planetocentric"); mappingGrp += PvlKeyword("LongitudeDomain", "360"); mappingGrp += PvlKeyword("LongitudeDirection", "PositiveEast"); Pvl mappingPvl; mappingPvl += mappingGrp; double minLatDouble; double maxLatDouble; double minLonDouble; double maxLonDouble; p_camera->GroundRange( minLatDouble, maxLatDouble, minLonDouble, maxLonDouble, mappingPvl); minLat = Latitude(minLatDouble, Angle::Degrees); maxLat = Latitude(maxLatDouble, Angle::Degrees); minLon = Longitude(minLonDouble, Angle::Degrees); maxLon = Longitude(maxLonDouble, Angle::Degrees); } else if (HasProjection()) { // Footprint failed, look in the mapping group PvlGroup mappingGrp = p_projection->Mapping(); if (mappingGrp.hasKeyword("MinimumLatitude") && mappingGrp.hasKeyword("MaximumLatitude") && mappingGrp.hasKeyword("MinimumLongitude") && mappingGrp.hasKeyword("MaximumLongitude")) { minLat = Latitude(mappingGrp["MinimumLatitude"], mappingGrp, Angle::Degrees); maxLat = Latitude(mappingGrp["MaximumLatitude"], mappingGrp, Angle::Degrees); minLon = Longitude(mappingGrp["MinimumLongitude"], mappingGrp, Angle::Degrees); maxLon = Longitude(mappingGrp["MaximumLongitude"], mappingGrp, Angle::Degrees); } else if (allowEstimation && cube) { // Footprint and mapping failed... no lat/lon range of any kind is // available. Let's test points in the image to try to make our own // extent. QList<QPointF> imagePoints; // Reset to TProjection TProjection *tproj = (TProjection *) p_projection; /* * This is where we're testing: * * |---------------| * |***************| * |** * **| * |* * * * *| * |* * * * *| * |***************| * |* * * * *| * |* * * * *| * |** * **| * |***************| * |---------------| * * We'll test at the edges, a plus (+) and an (X) to help DEMs work. */ int sampleCount = cube->sampleCount(); int lineCount = cube->lineCount(); int stepsPerLength = 20; //number of steps per length double aspectRatio = (double)lineCount / (double)sampleCount; double xStepSize = sampleCount / stepsPerLength; double yStepSize = xStepSize * aspectRatio; if (lineCount > sampleCount) { aspectRatio = (double)sampleCount / (double)lineCount; yStepSize = lineCount / stepsPerLength; xStepSize = yStepSize * aspectRatio; } double yWalked = 0.5; //3 vertical lines for (int i = 0; i < 3; i++) { double xValue = 0.5 + ( i * (sampleCount / 2) ); while (yWalked <= lineCount) { imagePoints.append( QPointF(xValue, yWalked) ); yWalked += yStepSize; } yWalked = 0.5; } double xWalked = 0.5; //3 horizontal lines for (int i = 0; i < 3; i++) { double yValue = 0.5 + ( i * (lineCount / 2) ); while (xWalked <= sampleCount) { imagePoints.append( QPointF(xWalked, yValue) ); xWalked += xStepSize; } xWalked = 0.5; } double xDiagonalWalked = 0.5; double yDiagonalWalked = 0.5; xStepSize = sampleCount / stepsPerLength; yStepSize = lineCount / stepsPerLength; //Top-Down Diagonal while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked <= lineCount) ) { imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) ); xDiagonalWalked += xStepSize; yDiagonalWalked += yStepSize; } xDiagonalWalked = 0.5; //Bottom-Up Diagonal while ( (xDiagonalWalked <= sampleCount) && (yDiagonalWalked >= 0) ) { imagePoints.append( QPointF(xDiagonalWalked, yDiagonalWalked) ); xDiagonalWalked += xStepSize; yDiagonalWalked -= yStepSize; } foreach (QPointF imagePoint, imagePoints) { if (tproj->SetWorld(imagePoint.x(), imagePoint.y())) { Latitude latResult(tproj->UniversalLatitude(), Angle::Degrees); Longitude lonResult(tproj->UniversalLongitude(), Angle::Degrees); if (minLat.isValid()) minLat = qMin(minLat, latResult); else minLat = latResult; if (maxLat.isValid()) maxLat = qMax(maxLat, latResult); else maxLat = latResult; if (minLon.isValid()) minLon = qMin(minLon, lonResult); else minLon = lonResult; if (maxLon.isValid()) maxLon = qMax(maxLon, lonResult); else maxLon = lonResult; } } } } }
void IsisMain() { // We will be warping a cube ProcessRubberSheet p; // Get the map projection file provided by the user UserInterface &ui = Application::GetUserInterface(); Pvl userPvl(ui.GetFileName("MAP")); PvlGroup &userMappingGrp = userPvl.findGroup("Mapping", Pvl::Traverse); // Open the input cube and get the projection Cube *icube = p.SetInputCube("FROM"); // Get the mapping group PvlGroup fromMappingGrp = icube->group("Mapping"); TProjection *inproj = (TProjection *) icube->projection(); PvlGroup outMappingGrp = fromMappingGrp; // If the default range is FROM, then wipe out any range data in user mapping file if(ui.GetString("DEFAULTRANGE").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { if(userMappingGrp.hasKeyword("MinimumLatitude")) { userMappingGrp.deleteKeyword("MinimumLatitude"); } if(userMappingGrp.hasKeyword("MaximumLatitude")) { userMappingGrp.deleteKeyword("MaximumLatitude"); } if(userMappingGrp.hasKeyword("MinimumLongitude")) { userMappingGrp.deleteKeyword("MinimumLongitude"); } if(userMappingGrp.hasKeyword("MaximumLongitude")) { userMappingGrp.deleteKeyword("MaximumLongitude"); } } // Deal with user overrides entered in the GUI. Do this by changing the user's mapping group, which // will then overlay anything in the output mapping group. if(ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.addKeyword(PvlKeyword("MinimumLatitude", toString(ui.GetDouble("MINLAT"))), Pvl::Replace); } if(ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.addKeyword(PvlKeyword("MaximumLatitude", toString(ui.GetDouble("MAXLAT"))), Pvl::Replace); } if(ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.addKeyword(PvlKeyword("MinimumLongitude", toString(ui.GetDouble("MINLON"))), Pvl::Replace); } if(ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.addKeyword(PvlKeyword("MaximumLongitude", toString(ui.GetDouble("MAXLON"))), Pvl::Replace); } /** * If the user is changing from positive east to positive west, or vice-versa, the output minimum is really * the input maximum. However, the user mapping group must be left unaffected (an input minimum must be the * output minimum). To accomplish this, we swap the minimums/maximums in the output group ahead of time. This * causes the minimums and maximums to correlate to the output minimums and maximums. That way when we copy * the user mapping group into the output group a mimimum overrides a minimum and a maximum overrides a maximum. */ bool sameDirection = true; if(userMappingGrp.hasKeyword("LongitudeDirection")) { if(((QString)userMappingGrp["LongitudeDirection"]).compare(fromMappingGrp["LongitudeDirection"]) != 0) { sameDirection = false; } } // Since the out mapping group came from the from mapping group, which came from a valid cube, // we can assume both min/max lon exists if min longitude exists. if(!sameDirection && outMappingGrp.hasKeyword("MinimumLongitude")) { double minLon = outMappingGrp["MinimumLongitude"]; double maxLon = outMappingGrp["MaximumLongitude"]; outMappingGrp["MaximumLongitude"] = toString(minLon); outMappingGrp["MinimumLongitude"] = toString(maxLon); } if(ui.GetString("PIXRES").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { // Resolution will be in fromMappingGrp and outMappingGrp at this time // delete from user mapping grp if(userMappingGrp.hasKeyword("Scale")) { userMappingGrp.deleteKeyword("Scale"); } if(userMappingGrp.hasKeyword("PixelResolution")) { userMappingGrp.deleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MAP") == 0 || ui.GetBoolean("MATCHMAP")) { // Resolution will be in userMappingGrp - delete all others if(outMappingGrp.hasKeyword("Scale")) { outMappingGrp.deleteKeyword("Scale"); } if(outMappingGrp.hasKeyword("PixelResolution")) { outMappingGrp.deleteKeyword("PixelResolution"); } if(fromMappingGrp.hasKeyword("Scale")); { fromMappingGrp.deleteKeyword("Scale"); } if(fromMappingGrp.hasKeyword("PixelResolution")) { fromMappingGrp.deleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MPP") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.hasKeyword("Scale")) { outMappingGrp.deleteKeyword("Scale"); } if(outMappingGrp.hasKeyword("PixelResolution")) { outMappingGrp.deleteKeyword("PixelResolution"); } if(fromMappingGrp.hasKeyword("Scale")) { fromMappingGrp.deleteKeyword("Scale"); } if(fromMappingGrp.hasKeyword("PixelResolution")) { fromMappingGrp.deleteKeyword("PixelResolution"); } if(userMappingGrp.hasKeyword("Scale")) { userMappingGrp.deleteKeyword("Scale"); } if(userMappingGrp.hasKeyword("PixelResolution")) { userMappingGrp.deleteKeyword("PixelResolution"); } outMappingGrp.addKeyword(PvlKeyword("PixelResolution", toString(ui.GetDouble("RESOLUTION")), "meters/pixel"), Pvl::Replace); } else if(ui.GetString("PIXRES").compare("PPD") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.hasKeyword("Scale")) { outMappingGrp.deleteKeyword("Scale"); } if(outMappingGrp.hasKeyword("PixelResolution")) { outMappingGrp.deleteKeyword("PixelResolution"); } if(fromMappingGrp.hasKeyword("Scale")) { fromMappingGrp.deleteKeyword("Scale"); } if(fromMappingGrp.hasKeyword("PixelResolution")) { fromMappingGrp.deleteKeyword("PixelResolution"); } if(userMappingGrp.hasKeyword("Scale")) { userMappingGrp.deleteKeyword("Scale"); } if(userMappingGrp.hasKeyword("PixelResolution")) { userMappingGrp.deleteKeyword("PixelResolution"); } outMappingGrp.addKeyword(PvlKeyword("Scale", toString(ui.GetDouble("RESOLUTION")), "pixels/degree"), Pvl::Replace); } // Rotation will NOT Propagate if(outMappingGrp.hasKeyword("Rotation")) { outMappingGrp.deleteKeyword("Rotation"); } /** * The user specified map template file overrides what ever is in the * cube's mapping group. */ for(int keyword = 0; keyword < userMappingGrp.keywords(); keyword ++) { outMappingGrp.addKeyword(userMappingGrp[keyword], Pvl::Replace); } /** * Now, we have to deal with unit conversions. We convert only if the following are true: * 1) We used values from the input cube * 2) The values are longitudes or latitudes * 3) The map file or user-specified information uses a different measurement system than * the input cube for said values. * * The data is corrected for: * 1) Positive east/positive west * 2) Longitude domain * 3) planetographic/planetocentric. */ // First, the longitude direction if(!sameDirection) { PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.keywords(); index ++) { if(!userMappingGrp.hasKeyword(longitudes[index].name())) { // use the from domain because that's where our values are coming from if(((QString)userMappingGrp["LongitudeDirection"]).compare("PositiveEast") == 0) { outMappingGrp[longitudes[index].name()] = toString( TProjection::ToPositiveEast(outMappingGrp[longitudes[index].name()], outMappingGrp["LongitudeDomain"])); } else { outMappingGrp[longitudes[index].name()] = toString( TProjection::ToPositiveWest(outMappingGrp[longitudes[index].name()], outMappingGrp["LongitudeDomain"])); } } } } // Second, longitude domain if(userMappingGrp.hasKeyword("LongitudeDomain")) { // user set a new domain? if((int)userMappingGrp["LongitudeDomain"] != (int)fromMappingGrp["LongitudeDomain"]) { // new domain different? PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.keywords(); index ++) { if(!userMappingGrp.hasKeyword(longitudes[index].name())) { if((int)userMappingGrp["LongitudeDomain"] == 180) { outMappingGrp[longitudes[index].name()] = toString( TProjection::To180Domain(outMappingGrp[longitudes[index].name()])); } else { outMappingGrp[longitudes[index].name()] = toString( TProjection::To360Domain(outMappingGrp[longitudes[index].name()])); } } } } } // Third, planetographic/planetocentric if(userMappingGrp.hasKeyword("LatitudeType")) { // user set a new domain? if(((QString)userMappingGrp["LatitudeType"]).compare(fromMappingGrp["LatitudeType"]) != 0) { // new lat type different? PvlGroup latitudes = inproj->MappingLatitudes(); for(int index = 0; index < latitudes.keywords(); index ++) { if(!userMappingGrp.hasKeyword(latitudes[index].name())) { if(((QString)userMappingGrp["LatitudeType"]).compare("Planetographic") == 0) { outMappingGrp[latitudes[index].name()] = toString(TProjection::ToPlanetographic( (double)fromMappingGrp[latitudes[index].name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"])); } else { outMappingGrp[latitudes[index].name()] = toString(TProjection::ToPlanetocentric( (double)fromMappingGrp[latitudes[index].name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"])); } } } } } // Try a couple equivalent longitudes to fix the ordering of min,max for border cases if ((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) { if ((QString)outMappingGrp["MinimumLongitude"] == "180.0" && (int)userMappingGrp["LongitudeDomain"] == 180) outMappingGrp["MinimumLongitude"] = "-180"; if ((QString)outMappingGrp["MaximumLongitude"] == "-180.0" && (int)userMappingGrp["LongitudeDomain"] == 180) outMappingGrp["MaximumLongitude"] = "180"; if ((QString)outMappingGrp["MinimumLongitude"] == "360.0" && (int)userMappingGrp["LongitudeDomain"] == 360) outMappingGrp["MinimumLongitude"] = "0"; if ((QString)outMappingGrp["MaximumLongitude"] == "0.0" && (int)userMappingGrp["LongitudeDomain"] == 360) outMappingGrp["MaximumLongitude"] = "360"; } // If MinLon/MaxLon out of order, we weren't able to calculate the correct values if((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) { if(!ui.WasEntered("MINLON") || !ui.WasEntered("MAXLON")) { QString msg = "Unable to determine the correct [MinimumLongitude,MaximumLongitude]."; msg += " Please specify these values in the [MINLON,MAXLON] parameters"; throw IException(IException::Unknown, msg, _FILEINFO_); } } int samples, lines; Pvl mapData; // Copy to preserve cube labels so we can match cube size if(userPvl.hasObject("IsisCube")) { mapData = userPvl; mapData.findObject("IsisCube").deleteGroup("Mapping"); mapData.findObject("IsisCube").addGroup(outMappingGrp); } else { mapData.addGroup(outMappingGrp); } // *NOTE: The UpperLeftX,UpperLeftY keywords will not be used in the CreateForCube // method, and they will instead be recalculated. This is correct. TProjection *outproj = (TProjection *) ProjectionFactory::CreateForCube(mapData, samples, lines, ui.GetBoolean("MATCHMAP")); // Set up the transform object which will simply map // output line/samps -> output lat/lons -> input line/samps Transform *transform = new map2map(icube->sampleCount(), icube->lineCount(), (TProjection *) icube->projection(), samples, lines, outproj, ui.GetBoolean("TRIM")); // Allocate the output cube and add the mapping labels Cube *ocube = p.SetOutputCube("TO", transform->OutputSamples(), transform->OutputLines(), icube->bandCount()); PvlGroup cleanOutGrp = outproj->Mapping(); // ProjectionFactory::CreateForCube updated mapData to have the correct // upperleftcornerx, upperleftcornery, scale and resolution. Use these // updated numbers. cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["UpperLeftCornerX"], Pvl::Replace); cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["UpperLeftCornerY"], Pvl::Replace); cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["Scale"], Pvl::Replace); cleanOutGrp.addKeyword(mapData.findGroup("Mapping", Pvl::Traverse)["PixelResolution"], Pvl::Replace); ocube->putGroup(cleanOutGrp); // Set up the interpolator Interpolator *interp; if(ui.GetString("INTERP") == "NEARESTNEIGHBOR") { interp = new Interpolator(Interpolator::NearestNeighborType); } else if(ui.GetString("INTERP") == "BILINEAR") { interp = new Interpolator(Interpolator::BiLinearType); } else if(ui.GetString("INTERP") == "CUBICCONVOLUTION") { interp = new Interpolator(Interpolator::CubicConvolutionType); } else { QString msg = "Unknow value for INTERP [" + ui.GetString("INTERP") + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } // Warp the cube p.StartProcess(*transform, *interp); p.EndProcess(); Application::Log(cleanOutGrp); // Cleanup delete transform; delete interp; }
// Populate cube label using filname and film code // Code decrypted as specified in film decoder document (July 23, 1971 Revision) // available at ASU Apollo Resources archive void TranslateApolloLabels (IString filename, Cube *opack) { //Instrument group PvlGroup inst("Instrument"); PvlGroup kern("Kernels"); PvlGroup codeGroup("Code"); inst += PvlKeyword("SpacecraftName", apollo->SpacecraftName()); inst += PvlKeyword("InstrumentId", apollo->InstrumentId()); inst += PvlKeyword("TargetName", apollo->TargetName()); if ( !IsValidCode() ){ PvlGroup error("ERROR"); error.addComment("The decrypted code is invalid."); for (int i=0; i<4; i++) { PvlKeyword keyword("Column"+toString(i+1)); for (int j=0; j<32; j++) { keyword += toString((int)code[i][j]); } error.addKeyword(keyword); codeGroup += keyword; } Application::Log(error); } else { codeGroup += PvlKeyword("StartTime", FrameTime()); codeGroup += PvlKeyword("SpacecraftAltitude", toString(Altitude()),"meters"); if (apollo->IsMetric()){ codeGroup += PvlKeyword("ExposureDuration", toString(ShutterInterval()), "milliseconds"); codeGroup += PvlKeyword("ForwardMotionCompensation", FMC()); } for (int i=0; i<4; i++) { PvlKeyword keyword("Column"+toString(i+1)); for (int j=0; j<32; j++) { keyword += toString((int)code[i][j]); } codeGroup += keyword; } } PvlGroup bandBin("BandBin"); // There are no filters on the camera, so the default is clear with id # of 1 // the BandBin group is only included to work with the spiceinit application bandBin += PvlKeyword("FilterName", "CLEAR"); bandBin += PvlKeyword("FilterId", "1"); kern += PvlKeyword("NaifFrameCode", apollo->NaifFrameCode()); // Set up the nominal reseaus group Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory"); Process p; PvlTranslationTable tTable( (QString)p.MissionData("base", "translations/MissionName2DataDir.trn")); QString missionDir = dataDir[tTable.Translate("MissionName", apollo->SpacecraftName())][0]; Pvl resTemplate(missionDir + "/reseaus/" + apollo->InstrumentId() + "_NOMINAL.pvl"); PvlGroup *reseaus = &resTemplate.findGroup("Reseaus"); // Update reseau locations based on refined code location for (int i=0; i<(reseaus->findKeyword("Type")).size(); i++) { double x = toDouble(reseaus->findKeyword("Sample")[i]) + sampleTranslation + 2278, y = toDouble(reseaus->findKeyword("Line")[i]) + lineTranslation - 20231; if (apollo->IsApollo17()) { x += 50; y += 20; } reseaus->findKeyword("Sample")[i] = toString( cos(rotation)*(x-sampleTranslation) - sin(rotation)*(y-lineTranslation) + sampleTranslation); reseaus->findKeyword("Line")[i] = toString( sin(rotation)*(x-sampleTranslation) + cos(rotation)*(y-lineTranslation) + lineTranslation); } inst += PvlKeyword("StartTime", utcTime); opack->putGroup(inst); opack->putGroup(bandBin); opack->putGroup(kern); opack->putGroup(*reseaus); opack->putGroup(codeGroup); }
/** * Set the output cube to specified file name and specified input images * and output attributes and lat,lons */ Isis::Cube *ProcessMapMosaic::SetOutputCube(FileList &propagationCubes, double slat, double elat, double slon, double elon, CubeAttributeOutput &oAtt, const QString &mosaicFile) { if (propagationCubes.size() < 1) { QString msg = "The list does not contain any data"; throw IException(IException::Programmer, msg, _FILEINFO_); } int samples, lines, bands = 0; Pvl label; label.read(propagationCubes[0].toString()); PvlGroup mGroup = label.findGroup("Mapping", Pvl::Traverse); mGroup.addKeyword(PvlKeyword("MinimumLatitude", toString(slat)), Pvl::Replace); mGroup.addKeyword(PvlKeyword("MaximumLatitude", toString(elat)), Pvl::Replace); mGroup.addKeyword(PvlKeyword("MinimumLongitude", toString(slon)), Pvl::Replace); mGroup.addKeyword(PvlKeyword("MaximumLongitude", toString(elon)), Pvl::Replace); if (mGroup.hasKeyword("UpperLeftCornerX")) mGroup.deleteKeyword("UpperLeftCornerX"); if (mGroup.hasKeyword("UpperLeftCornerY")) mGroup.deleteKeyword("UpperLeftCornerY"); Pvl mapPvl; mapPvl += mGroup; // Use CreateForCube because our range differs from any of the cubes (manually specified) Projection *proj = Isis::ProjectionFactory::CreateForCube(mapPvl, samples, lines, false); double xmin, xmax, ymin, ymax; proj->XYRange(xmin, xmax, ymin, ymax); // The xmin/ymax should be rounded for the labels xmin = mapPvl.findGroup("Mapping")["UpperLeftCornerX"]; ymax = mapPvl.findGroup("Mapping")["UpperLeftCornerY"]; for (int i = 0; i < propagationCubes.size(); i++) { Cube cube; cube.open(propagationCubes[i].toString()); bands = max(cube.bandCount(), bands); // 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) { } else if (*proj != *projNew) { QString msg = "Mapping groups do not match between cube [" + propagationCubes[i].toString() + "] and [" + propagationCubes[0].toString() + "]"; throw IException(IException::User, msg, _FILEINFO_); } 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); }
// Main program void IsisMain(){ // Create an object for exporting Isis data ProcessExport p; // Open the input cube Cube *icube = p.SetInputCube("FROM"); // Conform to the Big-Endian format for FITS if(IsLsb()) p.SetOutputEndian(Isis::Msb); // Generate the name of the fits file and open it UserInterface &ui = Application::GetUserInterface(); // specify the bits per pixel string bitpix; if (ui.GetString ("BITTYPE") == "8BIT") bitpix = "8"; else if (ui.GetString ("BITTYPE") == "16BIT") bitpix = "16"; else if (ui.GetString ("BITTYPE") == "32BIT") bitpix = "-32"; else { string msg = "Pixel type of [" + ui.GetString("BITTYPE") + "] is unsupported"; throw iException::Message(iException::User, msg, _FILEINFO_); } // Determine bit size and calculate number of bytes to write // for each line. if (bitpix == "8") p.SetOutputType(Isis::UnsignedByte); if (bitpix == "16") p.SetOutputType(Isis::SignedWord); if (bitpix == "-32") p.SetOutputType(Isis::Real); // determine core base and multiplier, set up the stretch PvlGroup pix = icube->Label()->FindObject("IsisCube").FindObject("Core").FindGroup("Pixels"); double scale = pix["Multiplier"][0].ToDouble(); double base = pix["Base"][0].ToDouble(); if (ui.GetString("STRETCH") != "NONE" && bitpix != "-32") { if (ui.GetString("STRETCH") == "LINEAR") { p.SetInputRange(); } else if (ui.GetString("STRETCH") == "MANUAL") { p.SetInputRange(ui.GetDouble("MINIMUM"), ui.GetDouble("MAXIMUM")); } // create a proper scale so pixels look like 32bit data. scale = ((p.GetInputMaximum() - p.GetInputMinimum()) * (p.GetOutputMaximum() - p.GetOutputMinimum())); // round off after 14 decimals to avoid system architecture differences scale = ((floor(scale * 1e14)) / 1e14); // create a proper zero point so pixels look like 32bit data. base = -1.0 * (scale * p.GetOutputMinimum()) + p.GetInputMinimum(); // round off after 14 decimals to avoid system architecture differences base = ((floor(base * 1e14)) / 1e14); } ////////////////////////////////////////// // Write the minimal fits header // ////////////////////////////////////////// string header; // specify that this file conforms to simple fits standard header += FitsKeyword("SIMPLE", true, "T"); // specify the bits per pixel header += FitsKeyword("BITPIX", true, bitpix); // specify the number of data axes (2: samples by lines) int axes = 2; if (icube->Bands() > 1) { axes = 3; } header += FitsKeyword("NAXIS", true, iString(axes)); // specify the limit on data axis 1 (number of samples) header += FitsKeyword("NAXIS1", true, iString(icube->Samples())); // specify the limit on data axis 2 (number of lines) header += FitsKeyword("NAXIS2", true, iString(icube->Lines())); if (axes == 3){ header += FitsKeyword("NAXIS3", true, iString(icube->Bands())); } header += FitsKeyword("BZERO", true, base); header += FitsKeyword("BSCALE", true, scale); // Sky and All cases if (ui.GetString("INFO") == "SKY" || ui.GetString("INFO") == "ALL") { iString msg = "cube has not been skymapped"; PvlGroup map; if (icube->HasGroup("mapping")) { map = icube->GetGroup("mapping"); msg = (string)map["targetname"]; } // If we have sky we want it if (msg == "Sky") { double midRa = 0, midDec = 0; midRa = ((double)map["MaximumLongitude"] + (double)map["MinimumLongitude"])/2; midDec = ((double)map["MaximumLatitude"] + (double)map["MinimumLatitude"])/2; header += FitsKeyword("OBJCTRA", true, iString(midRa)); // Specify the Declination header += FitsKeyword("OBJCTDEC", true, iString(midDec)); } if (ui.GetString("INFO") == "ALL") { header += WritePvl("INSTRUME","Instrument","InstrumentId", icube, true); header += WritePvl("OBSERVER","Instrument","SpacecraftName", icube, true); header += WritePvl("OBJECT ","Instrument","TargetName", icube, true); // StartTime is sometimes middle of the exposure and somtimes beginning, // so StopTime can't be calculated off of exposure reliably. header += WritePvl("DATE-OBS","Instrument","StartTime", icube, true); // Some cameras don't have StopTime if (icube->HasGroup("Instrument")) { PvlGroup inst = icube->GetGroup("Instrument"); if (inst.HasKeyword("StopTime")) { header += WritePvl("TIME_END","Instrument","StopTime", icube, true); } if (inst.HasKeyword("ExposureDuration")) { header += WritePvl("EXPTIME","Instrument","ExposureDuration", icube, false); } } } // If we were set on SKY and Sky doesn't exist else if (msg != "Sky") { throw iException::Message(iException::User,msg,_FILEINFO_); } } // signal the end of the header header += FitsKeyword("END", false, ""); // fill the rest of the fits header with space so to conform with the fits header // size of 2880 bytes for (int i = header.length() % 2880 ; i < 2880 ; i++) header += " "; // open the cube for writing string to = ui.GetFilename("TO","fits"); ofstream fout; fout.open (to.c_str (), ios::out|ios::binary); if (!fout.is_open ()) { string msg = "Cannot open fits output file"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } fout.seekp(0); fout.write(header.c_str(),header.length()); // write the raw cube data p.StartProcess (fout); // Finish off data area to a number n % 2880 == 0 is true // 2880 is the size of the data blocks int count = 2880 - (fout.tellp() % 2880); for (int i = 0; i < count; i++) { // Write nul characters as needed. ascii 0, hex 00... fout.write("\0", 1); } fout.close(); p.EndProcess(); }
bool TryKernels(Cube *icube, Process &p, Kernel lk, Kernel pck, Kernel targetSpk, Kernel ck, Kernel fk, Kernel ik, Kernel sclk, Kernel spk, Kernel iak, Kernel dem, Kernel exk) { Pvl lab = *icube->Label(); // Add the new kernel files to the existing kernels group PvlKeyword lkKeyword("LeapSecond"); PvlKeyword pckKeyword("TargetAttitudeShape"); PvlKeyword targetSpkKeyword("TargetPosition"); PvlKeyword ckKeyword("InstrumentPointing"); PvlKeyword ikKeyword("Instrument"); PvlKeyword sclkKeyword("SpacecraftClock"); PvlKeyword spkKeyword("InstrumentPosition"); PvlKeyword iakKeyword("InstrumentAddendum"); PvlKeyword demKeyword("ShapeModel"); PvlKeyword exkKeyword("Extra"); for (int i=0; i<lk.size(); i++) { lkKeyword.AddValue(lk[i]); } for (int i=0; i<pck.size(); i++) { pckKeyword.AddValue(pck[i]); } for (int i=0; i<targetSpk.size(); i++) { targetSpkKeyword.AddValue(targetSpk[i]); } for (int i=0; i<ck.size(); i++) { ckKeyword.AddValue(ck[i]); } for (int i=0; i<ik.size(); i++) { ikKeyword.AddValue(ik[i]); } for (int i=0; i<sclk.size(); i++) { sclkKeyword.AddValue(sclk[i]); } for (int i=0; i<spk.size(); i++) { spkKeyword.AddValue(spk[i]); } for (int i=0; i<iak.size(); i++) { iakKeyword.AddValue(iak[i]); } for (int i=0; i<dem.size(); i++) { demKeyword.AddValue(dem[i]); } for (int i=0; i<exk.size(); i++) { exkKeyword.AddValue(exk[i]); } PvlGroup originalKernels = icube->GetGroup("Kernels"); PvlGroup currentKernels = originalKernels; currentKernels.AddKeyword(lkKeyword, Pvl::Replace); currentKernels.AddKeyword(pckKeyword, Pvl::Replace); currentKernels.AddKeyword(targetSpkKeyword, Pvl::Replace); currentKernels.AddKeyword(ckKeyword, Pvl::Replace); currentKernels.AddKeyword(ikKeyword, Pvl::Replace); currentKernels.AddKeyword(sclkKeyword, Pvl::Replace); currentKernels.AddKeyword(spkKeyword, Pvl::Replace); currentKernels.AddKeyword(iakKeyword, Pvl::Replace); currentKernels.AddKeyword(demKeyword, Pvl::Replace); // report qualities PvlKeyword spkQuality("InstrumentPositionQuality"); spkQuality.AddValue(spiceInit::kernelTypeEnum(spk.kernelType)); currentKernels.AddKeyword(spkQuality, Pvl::Replace); PvlKeyword ckQuality("InstrumentPointingQuality"); ckQuality.AddValue(spiceInit::kernelTypeEnum(ck.kernelType)); currentKernels.AddKeyword(ckQuality, Pvl::Replace); if (!exkKeyword.IsNull()) { currentKernels.AddKeyword(exkKeyword, Pvl::Replace); } else if( currentKernels.HasKeyword("EXTRA") ) { currentKernels.DeleteKeyword( "EXTRA" ); } // Get rid of old keywords from previously inited cubes if (currentKernels.HasKeyword("SpacecraftPointing")) { currentKernels.DeleteKeyword("SpacecraftPointing"); } if (currentKernels.HasKeyword("SpacecraftPosition")) { currentKernels.DeleteKeyword("SpacecraftPosition"); } if (currentKernels.HasKeyword("ElevationModel")) { currentKernels.DeleteKeyword("ElevationModel"); } if (currentKernels.HasKeyword("Frame")) { currentKernels.DeleteKeyword("Frame"); } if (currentKernels.HasKeyword("StartPadding")) { currentKernels.DeleteKeyword("StartPadding"); } if (currentKernels.HasKeyword("EndPadding")) { currentKernels.DeleteKeyword("EndPadding"); } UserInterface &ui = Application::GetUserInterface(); // Add any time padding the user specified to the spice group if(ui.GetDouble("STARTPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("StartPadding", ui.GetDouble("STARTPAD"), "seconds")); } if(ui.GetDouble("ENDPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("EndPadding", ui.GetDouble("ENDPAD"), "seconds")); } currentKernels.AddKeyword(PvlKeyword("CameraVersion",CameraFactory::CameraVersion(lab)), Pvl::Replace); // Add the modified Kernels group to the input cube labels icube->PutGroup(currentKernels); // Create the camera so we can get blobs if necessary try { Camera *cam; try { cam = icube->Camera(); Application::Log(currentKernels); } catch (iException &e) { Pvl errPvl = e.PvlErrors(); if(errPvl.Groups() > 0) { currentKernels += PvlKeyword("Error", errPvl.Group(errPvl.Groups()-1)["Message"][0]); } Application::Log(currentKernels); icube->PutGroup(originalKernels); throw e; } if (ui.GetBoolean("ATTACH")) { Table ckTable = cam->InstrumentRotation()->Cache("InstrumentPointing"); ckTable.Label() += PvlKeyword("Description", "Created by spiceinit"); ckTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<ckKeyword.Size(); i++) { ckTable.Label()["Kernels"].AddValue(ckKeyword[i]); } icube->Write(ckTable); Table spkTable = cam->InstrumentPosition()->Cache("InstrumentPosition"); spkTable.Label() += PvlKeyword("Description", "Created by spiceinit"); spkTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<spkKeyword.Size(); i++) { spkTable.Label()["Kernels"].AddValue(spkKeyword[i]); } icube->Write(spkTable); Table bodyTable = cam->BodyRotation()->Cache("BodyRotation"); bodyTable.Label() += PvlKeyword("Description", "Created by spiceinit"); bodyTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } for (int i=0; i<pckKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(pckKeyword[i]); } bodyTable.Label() += PvlKeyword("SolarLongitude", cam->SolarLongitude()); icube->Write(bodyTable); Table sunTable = cam->SunPosition()->Cache("SunPosition"); sunTable.Label() += PvlKeyword("Description", "Created by spiceinit"); sunTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { sunTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } icube->Write(sunTable); // Save original kernels in keyword before changing to Table PvlKeyword origCk = currentKernels["InstrumentPointing"]; PvlKeyword origSpk = currentKernels["InstrumentPosition"]; PvlKeyword origTargPos = currentKernels["TargetPosition"]; currentKernels["InstrumentPointing"] = "Table"; for (int i=0; i<origCk.Size(); i++) { currentKernels["InstrumentPointing"].AddValue(origCk[i]); } currentKernels["InstrumentPosition"] = "Table"; for (int i=0; i<origSpk.Size(); i++) { currentKernels["InstrumentPosition"].AddValue(origSpk[i]); } currentKernels["TargetPosition"] = "Table"; for (int i=0; i<origTargPos.Size(); i++) { currentKernels["TargetPosition"].AddValue(origTargPos[i]); } icube->PutGroup(currentKernels); } //modify Kernels group only else { Pvl *label = icube->Label(); int i=0; while (i < label->Objects()) { PvlObject currObj = label->Object(i); if (currObj.IsNamed("Table")) { if (currObj["Name"][0] == iString("InstrumentPointing")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("InstrumentPosition")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("BodyRotation")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("SunPosition")) { label->DeleteObject(i); } else { i++; } } else { i++; } } } p.WriteHistory(*icube); } catch (iException &e) { e.Clear(); icube->PutGroup(originalKernels); return false; } return true; }
/** * GetPointInfo builds the PvlGroup containing all the important * information derived from the Camera. * * @return PvlGroup* Data taken directly from the Camera and * drived from Camera information. Ownership passed. */ PvlGroup *CameraPointInfo::GetPointInfo(bool passed, bool allowOutside, bool allowErrors) { PvlGroup *gp = new PvlGroup("GroundPoint"); { gp->addKeyword(PvlKeyword("Filename")); gp->addKeyword(PvlKeyword("Sample")); gp->addKeyword(PvlKeyword("Line")); gp->addKeyword(PvlKeyword("PixelValue")); gp->addKeyword(PvlKeyword("RightAscension")); gp->addKeyword(PvlKeyword("Declination")); gp->addKeyword(PvlKeyword("PlanetocentricLatitude")); gp->addKeyword(PvlKeyword("PlanetographicLatitude")); gp->addKeyword(PvlKeyword("PositiveEast360Longitude")); gp->addKeyword(PvlKeyword("PositiveEast180Longitude")); gp->addKeyword(PvlKeyword("PositiveWest360Longitude")); gp->addKeyword(PvlKeyword("PositiveWest180Longitude")); gp->addKeyword(PvlKeyword("BodyFixedCoordinate")); gp->addKeyword(PvlKeyword("LocalRadius")); gp->addKeyword(PvlKeyword("SampleResolution")); gp->addKeyword(PvlKeyword("LineResolution")); gp->addKeyword(PvlKeyword("SpacecraftPosition")); gp->addKeyword(PvlKeyword("SpacecraftAzimuth")); gp->addKeyword(PvlKeyword("SlantDistance")); gp->addKeyword(PvlKeyword("TargetCenterDistance")); gp->addKeyword(PvlKeyword("SubSpacecraftLatitude")); gp->addKeyword(PvlKeyword("SubSpacecraftLongitude")); gp->addKeyword(PvlKeyword("SpacecraftAltitude")); gp->addKeyword(PvlKeyword("OffNadirAngle")); gp->addKeyword(PvlKeyword("SubSpacecraftGroundAzimuth")); gp->addKeyword(PvlKeyword("SunPosition")); gp->addKeyword(PvlKeyword("SubSolarAzimuth")); gp->addKeyword(PvlKeyword("SolarDistance")); gp->addKeyword(PvlKeyword("SubSolarLatitude")); gp->addKeyword(PvlKeyword("SubSolarLongitude")); gp->addKeyword(PvlKeyword("SubSolarGroundAzimuth")); gp->addKeyword(PvlKeyword("Phase")); gp->addKeyword(PvlKeyword("Incidence")); gp->addKeyword(PvlKeyword("Emission")); gp->addKeyword(PvlKeyword("NorthAzimuth")); gp->addKeyword(PvlKeyword("EphemerisTime")); gp->addKeyword(PvlKeyword("UTC")); gp->addKeyword(PvlKeyword("LocalSolarTime")); gp->addKeyword(PvlKeyword("SolarLongitude")); if (allowErrors) gp->addKeyword(PvlKeyword("Error")); } bool noErrors = passed; QString error = ""; if (!m_camera->HasSurfaceIntersection()) { error = "Requested position does not project in camera model; no surface intersection"; noErrors = false; if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_); } if (!m_camera->InCube() && !allowOutside) { error = "Requested position does not project in camera model; not inside cube"; noErrors = false; if (!allowErrors) throw IException(IException::Unknown, error, _FILEINFO_); } if (!noErrors) { for (int i = 0; i < gp->keywords(); i++) { QString name = (*gp)[i].name(); // These three keywords have 3 values, so they must have 3 N/As if (name == "BodyFixedCoordinate" || name == "SpacecraftPosition" || name == "SunPosition") { (*gp)[i].addValue("N/A"); (*gp)[i].addValue("N/A"); (*gp)[i].addValue("N/A"); } else { (*gp)[i].setValue("N/A"); } } // Set all keywords that still have valid information gp->findKeyword("Error").setValue(error); gp->findKeyword("FileName").setValue(m_currentCube->fileName()); gp->findKeyword("Sample").setValue(toString(m_camera->Sample())); gp->findKeyword("Line").setValue(toString(m_camera->Line())); gp->findKeyword("EphemerisTime").setValue( toString(m_camera->time().Et()), "seconds"); gp->findKeyword("EphemerisTime").addComment("Time"); QString utc = m_camera->time().UTC(); gp->findKeyword("UTC").setValue(utc); gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information"); gp->findKeyword("SunPosition").addComment("Sun Information"); gp->findKeyword("Phase").addComment("Illumination and Other"); } else { Brick b(3, 3, 1, m_currentCube->pixelType()); int intSamp = (int)(m_camera->Sample() + 0.5); int intLine = (int)(m_camera->Line() + 0.5); b.SetBasePosition(intSamp, intLine, 1); m_currentCube->read(b); double pB[3], spB[3], sB[3]; QString utc; double ssplat, ssplon, sslat, sslon, pwlon, oglat; { gp->findKeyword("FileName").setValue(m_currentCube->fileName()); gp->findKeyword("Sample").setValue(toString(m_camera->Sample())); gp->findKeyword("Line").setValue(toString(m_camera->Line())); gp->findKeyword("PixelValue").setValue(PixelToString(b[0])); gp->findKeyword("RightAscension").setValue(toString( m_camera->RightAscension())); gp->findKeyword("Declination").setValue(toString( m_camera->Declination())); gp->findKeyword("PlanetocentricLatitude").setValue(toString( m_camera->UniversalLatitude())); // Convert lat to planetographic Distance radii[3]; m_camera->radii(radii); oglat = TProjection::ToPlanetographic(m_camera->UniversalLatitude(), radii[0].kilometers(), radii[2].kilometers()); gp->findKeyword("PlanetographicLatitude").setValue(toString(oglat)); gp->findKeyword("PositiveEast360Longitude").setValue(toString( m_camera->UniversalLongitude())); //Convert lon to -180 - 180 range gp->findKeyword("PositiveEast180Longitude").setValue(toString( TProjection::To180Domain(m_camera->UniversalLongitude()))); //Convert lon to positive west pwlon = TProjection::ToPositiveWest( m_camera->UniversalLongitude(), 360); gp->findKeyword("PositiveWest360Longitude").setValue(toString(pwlon)); //Convert pwlon to -180 - 180 range gp->findKeyword("PositiveWest180Longitude").setValue(toString( TProjection::To180Domain(pwlon))); m_camera->Coordinate(pB); gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[0]), "km"); gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[1]), "km"); gp->findKeyword("BodyFixedCoordinate").addValue(toString(pB[2]), "km"); gp->findKeyword("LocalRadius").setValue(toString( m_camera->LocalRadius().meters()), "meters"); gp->findKeyword("SampleResolution").setValue(toString( m_camera->SampleResolution()), "meters/pixel"); gp->findKeyword("LineResolution").setValue(toString( m_camera->LineResolution()), "meters/pixel"); //body fixed m_camera->instrumentPosition(spB); gp->findKeyword("SpacecraftPosition").addValue(toString(spB[0]), "km"); gp->findKeyword("SpacecraftPosition").addValue(toString(spB[1]), "km"); gp->findKeyword("SpacecraftPosition").addValue(toString(spB[2]), "km"); gp->findKeyword("SpacecraftPosition").addComment("Spacecraft Information"); gp->findKeyword("SpacecraftAzimuth").setValue(toString( m_camera->SpacecraftAzimuth())); gp->findKeyword("SlantDistance").setValue(toString( m_camera->SlantDistance()), "km"); gp->findKeyword("TargetCenterDistance").setValue(toString( m_camera->targetCenterDistance()), "km"); m_camera->subSpacecraftPoint(ssplat, ssplon); gp->findKeyword("SubSpacecraftLatitude").setValue(toString(ssplat)); gp->findKeyword("SubSpacecraftLongitude").setValue(toString(ssplon)); gp->findKeyword("SpacecraftAltitude").setValue(toString( m_camera->SpacecraftAltitude()), "km"); gp->findKeyword("OffNadirAngle").setValue(toString( m_camera->OffNadirAngle())); double subspcgrdaz; subspcgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), m_camera->UniversalLongitude(), ssplat, ssplon); gp->findKeyword("SubSpacecraftGroundAzimuth").setValue(toString(subspcgrdaz)); m_camera->sunPosition(sB); gp->findKeyword("SunPosition").addValue(toString(sB[0]), "km"); gp->findKeyword("SunPosition").addValue(toString(sB[1]), "km"); gp->findKeyword("SunPosition").addValue(toString(sB[2]), "km"); gp->findKeyword("SunPosition").addComment("Sun Information"); gp->findKeyword("SubSolarAzimuth").setValue(toString(m_camera->SunAzimuth())); gp->findKeyword("SolarDistance").setValue(toString( m_camera->SolarDistance()), "AU"); m_camera->subSolarPoint(sslat, sslon); gp->findKeyword("SubSolarLatitude").setValue(toString(sslat)); gp->findKeyword("SubSolarLongitude").setValue(toString(sslon)); double subsolgrdaz; subsolgrdaz = m_camera->GroundAzimuth(m_camera->UniversalLatitude(), m_camera->UniversalLongitude(), sslat, sslon); gp->findKeyword("SubSolarGroundAzimuth").setValue(toString(subsolgrdaz)); gp->findKeyword("Phase").setValue(toString(m_camera->PhaseAngle())); gp->findKeyword("Phase").addComment("Illumination and Other"); gp->findKeyword("Incidence").setValue(toString( m_camera->IncidenceAngle())); gp->findKeyword("Emission").setValue(toString( m_camera->EmissionAngle())); gp->findKeyword("NorthAzimuth").setValue(toString( m_camera->NorthAzimuth())); gp->findKeyword("EphemerisTime").setValue(toString( m_camera->time().Et()), "seconds"); gp->findKeyword("EphemerisTime").addComment("Time"); utc = m_camera->time().UTC(); gp->findKeyword("UTC").setValue(utc); gp->findKeyword("LocalSolarTime").setValue(toString( m_camera->LocalSolarTime()), "hour"); gp->findKeyword("SolarLongitude").setValue(toString( m_camera->solarLongitude().degrees())); if (allowErrors) gp->findKeyword("Error").setValue("N/A"); } } return gp; }
void TranslateLabels(FileName in, Cube *ocube) { // Get the directory where the Clementine translation tables are. PvlGroup &dataDir = Preference::Preferences().findGroup("DataDirectory"); // Transfer the instrument group to the output cube QString transDir = (QString) dataDir["clementine1"]; FileName transFile(transDir + "/translations/clementine.trn"); Pvl pdsLab(in.expanded()); PvlTranslationManager labelXlater(pdsLab, transFile.expanded()); // Pvl outputLabels; Pvl *outputLabel = ocube->label(); labelXlater.Auto(*(outputLabel)); //Instrument group PvlGroup inst = outputLabel->findGroup("Instrument", Pvl::Traverse); PvlKeyword &startTime = inst.findKeyword("StartTime"); startTime.setValue(startTime[0].mid(0, startTime[0].size() - 1)); // Old PDS labels used keyword INSTRUMENT_COMPRESSION_TYPE & PDS Labels now use ENCODING_TYPE if(pdsLab.findObject("Image").hasKeyword("InstrumentCompressionType")) { inst += PvlKeyword("EncodingFormat", (QString) pdsLab.findObject("Image")["InstrumentCompressionType"]); } else { inst += PvlKeyword("EncodingFormat", (QString) pdsLab.findObject("Image")["EncodingType"]); } if(((QString)inst["InstrumentId"]) == "HIRES") { inst += PvlKeyword("MCPGainModeID", (QString)pdsLab["MCP_Gain_Mode_ID"], ""); } ocube->putGroup(inst); PvlGroup bBin = outputLabel->findGroup("BandBin", Pvl::Traverse); QString filter = pdsLab["FilterName"]; if(filter != "F") { //Band Bin group double center = pdsLab["CenterFilterWavelength"]; center /= 1000.0; bBin.findKeyword("Center").setValue(toString(center), "micrometers"); } double width = pdsLab["Bandwidth"]; width /= 1000.0; bBin.findKeyword("Width").setValue(toString(width), "micrometers"); ocube->putGroup(bBin); //Kernel group PvlGroup kern("Kernels"); if(((QString)inst["InstrumentId"]) == "HIRES") { kern += PvlKeyword("NaifFrameCode", "-40001"); } if(((QString)inst["InstrumentId"]) == "UVVIS") { kern += PvlKeyword("NaifFrameCode", "-40002"); } if(((QString)inst["InstrumentId"]) == "NIR") { kern += PvlKeyword("NaifFrameCode", "-40003"); } if(((QString)inst["InstrumentId"]) == "LWIR") { kern += PvlKeyword("NaifFrameCode", "-40004"); } ocube->putGroup(kern); OriginalLabel org(pdsLab); ocube->write(org); }
/** * GetPointInfo builds the PvlGroup containing all the important * information derived from the Camera. * * @return PvlGroup* Data taken directly from the Camera and * drived from Camera information. Ownership passed. */ PvlGroup * CameraPointInfo::GetPointInfo() { CheckConditions(); Brick b(3,3,1,currentCube->PixelType()); int intSamp = (int)(camera->Sample() + 0.5); int intLine = (int)(camera->Line() + 0.5); b.SetBasePosition(intSamp, intLine, 1); currentCube->Read(b); double pB[3], spB[3], sB[3]; string utc; double ssplat, ssplon, sslat, sslon, pwlon, oglat; // Create group with ground position PvlGroup * gp = new PvlGroup("GroundPoint"); { gp->AddKeyword(PvlKeyword("Filename",currentCube->Filename())); gp->AddKeyword(PvlKeyword("Sample",camera->Sample())); gp->AddKeyword(PvlKeyword("Line",camera->Line())); gp->AddKeyword(PvlKeyword("PixelValue",PixelToString(b[0]))); gp->AddKeyword(PvlKeyword("RightAscension",camera->RightAscension())); gp->AddKeyword(PvlKeyword("Declination",camera->Declination())); gp->AddKeyword(PvlKeyword("PlanetocentricLatitude", camera->UniversalLatitude())); // Convert lat to planetographic double radii[3]; camera->Radii(radii); oglat = Isis::Projection::ToPlanetographic(camera->UniversalLatitude(), radii[0],radii[2]); gp->AddKeyword(PvlKeyword("PlanetographicLatitude",oglat)); gp->AddKeyword(PvlKeyword("PositiveEast360Longitude", camera->UniversalLongitude())); //Convert lon to -180 - 180 range gp->AddKeyword(PvlKeyword("PositiveEast180Longitude", Isis::Projection::To180Domain( camera->UniversalLongitude()))); //Convert lon to positive west pwlon = Isis::Projection::ToPositiveWest(camera->UniversalLongitude(), 360); gp->AddKeyword(PvlKeyword("PositiveWest360Longitude",pwlon)); //Convert pwlon to -180 - 180 range gp->AddKeyword(PvlKeyword("PositiveWest180Longitude", Isis::Projection::To180Domain(pwlon))); camera->Coordinate(pB); PvlKeyword coord("BodyFixedCoordinate"); coord.AddValue(pB[0],"km"); coord.AddValue(pB[1],"km"); coord.AddValue(pB[2],"km"); gp->AddKeyword(coord); gp->AddKeyword(PvlKeyword("LocalRadius",camera->LocalRadius(),"m")); gp->AddKeyword(PvlKeyword("SampleResolution",camera->SampleResolution(),"m")); gp->AddKeyword(PvlKeyword("LineResolution",camera->LineResolution(),"m")); camera->InstrumentPosition(spB); PvlKeyword spcoord("SpacecraftPosition"); spcoord.AddValue(spB[0],"km"); spcoord.AddValue(spB[1],"km"); spcoord.AddValue(spB[2],"km"); spcoord.AddComment("Spacecraft Information"); gp->AddKeyword(spcoord); gp->AddKeyword(PvlKeyword("SpacecraftAzimuth",camera->SpacecraftAzimuth())); gp->AddKeyword(PvlKeyword("SlantDistance",camera->SlantDistance(),"km")); gp->AddKeyword(PvlKeyword("TargetCenterDistance",camera->TargetCenterDistance(),"km")); camera->SubSpacecraftPoint(ssplat,ssplon); gp->AddKeyword(PvlKeyword("SubSpacecraftLatitude",ssplat)); gp->AddKeyword(PvlKeyword("SubSpacecraftLongitude",ssplon)); gp->AddKeyword(PvlKeyword("SpacecraftAltitude",camera->SpacecraftAltitude(),"km")); gp->AddKeyword(PvlKeyword("OffNadirAngle",camera->OffNadirAngle())); double subspcgrdaz; subspcgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(), ssplat,ssplon); gp->AddKeyword(PvlKeyword("SubSpacecraftGroundAzimuth",subspcgrdaz)); camera->SunPosition(sB); PvlKeyword scoord("SunPosition"); scoord.AddValue(sB[0],"km"); scoord.AddValue(sB[1],"km"); scoord.AddValue(sB[2],"km"); scoord.AddComment("Sun Information"); gp->AddKeyword(scoord); gp->AddKeyword(PvlKeyword("SubSolarAzimuth",camera->SunAzimuth())); gp->AddKeyword(PvlKeyword("SolarDistance",camera->SolarDistance(),"AU")); camera->SubSolarPoint(sslat,sslon); gp->AddKeyword(PvlKeyword("SubSolarLatitude",sslat)); gp->AddKeyword(PvlKeyword("SubSolarLongitude",sslon)); double subsolgrdaz; subsolgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(), sslat,sslon); gp->AddKeyword(PvlKeyword("SubSolarGroundAzimuth",subsolgrdaz)); PvlKeyword phase("Phase",camera->PhaseAngle()); phase.AddComment("Illumination and Other"); gp->AddKeyword(phase); gp->AddKeyword(PvlKeyword("Incidence",camera->IncidenceAngle())); gp->AddKeyword(PvlKeyword("Emission",camera->EmissionAngle())); gp->AddKeyword(PvlKeyword("NorthAzimuth",camera->NorthAzimuth())); PvlKeyword et("EphemerisTime",camera->EphemerisTime(),"seconds"); et.AddComment("Time"); gp->AddKeyword(et); iTime t(camera->EphemerisTime()); utc = t.UTC(); gp->AddKeyword(PvlKeyword("UTC",utc)); gp->AddKeyword(PvlKeyword("LocalSolarTime",camera->LocalSolarTime(),"hour")); gp->AddKeyword(PvlKeyword("SolarLongitude",camera->SolarLongitude())); } return gp; }
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() { const QString caminfo_program = "caminfo"; UserInterface &ui = Application::GetUserInterface(); QList< QPair<QString, QString> > *general = NULL, *camstats = NULL, *statistics = NULL; BandGeometry *bandGeom = NULL; // Get input filename FileName in = ui.GetFileName("FROM"); // Get the format QString sFormat = ui.GetAsString("FORMAT"); // if true then run spiceinit, xml default is FALSE // spiceinit will use system kernels if(ui.GetBoolean("SPICE")) { QString parameters = "FROM=" + in.expanded(); ProgramLauncher::RunIsisProgram("spiceinit", parameters); } Process p; Cube *incube = p.SetInputCube("FROM"); // General data gathering general = new QList< QPair<QString, QString> >; general->append(MakePair("Program", caminfo_program)); general->append(MakePair("IsisVersion", Application::Version())); general->append(MakePair("RunDate", iTime::CurrentGMT())); general->append(MakePair("IsisId", SerialNumber::Compose(*incube))); general->append(MakePair("From", in.baseName() + ".cub")); general->append(MakePair("Lines", toString(incube->lineCount()))); general->append(MakePair("Samples", toString(incube->sampleCount()))); general->append(MakePair("Bands", toString(incube->bandCount()))); // Run camstats on the entire image (all bands) // another camstats will be run for each band and output // for each band. if(ui.GetBoolean("CAMSTATS")) { camstats = new QList< QPair<QString, QString> >; QString filename = ui.GetAsString("FROM"); int sinc = ui.GetInteger("SINC"); int linc = ui.GetInteger("LINC"); CameraStatistics stats(filename, sinc, linc); Pvl camPvl = stats.toPvl(); PvlGroup cg = camPvl.findGroup("Latitude", Pvl::Traverse); camstats->append(MakePair("MinimumLatitude", cg["latitudeminimum"][0])); camstats->append(MakePair("MaximumLatitude", cg["latitudemaximum"][0])); cg = camPvl.findGroup("Longitude", Pvl::Traverse); camstats->append(MakePair("MinimumLongitude", cg["longitudeminimum"][0])); camstats->append(MakePair("MaximumLongitude", cg["longitudemaximum"][0])); cg = camPvl.findGroup("Resolution", Pvl::Traverse); camstats->append(MakePair("MinimumResolution", cg["resolutionminimum"][0])); camstats->append(MakePair("MaximumResolution", cg["resolutionmaximum"][0])); cg = camPvl.findGroup("PhaseAngle", Pvl::Traverse); camstats->append(MakePair("MinimumPhase", cg["phaseminimum"][0])); camstats->append(MakePair("MaximumPhase", cg["phasemaximum"][0])); cg = camPvl.findGroup("EmissionAngle", Pvl::Traverse); camstats->append(MakePair("MinimumEmission", cg["emissionminimum"][0])); camstats->append(MakePair("MaximumEmission", cg["emissionmaximum"][0])); cg = camPvl.findGroup("IncidenceAngle", Pvl::Traverse); camstats->append(MakePair("MinimumIncidence", cg["incidenceminimum"][0])); camstats->append(MakePair("MaximumIncidence", cg["incidencemaximum"][0])); cg = camPvl.findGroup("LocalSolarTime", Pvl::Traverse); camstats->append(MakePair("LocalTimeMinimum", cg["localsolartimeMinimum"][0])); camstats->append(MakePair("LocalTimeMaximum", cg["localsolartimeMaximum"][0])); } // Compute statistics for entire cube if(ui.GetBoolean("STATISTICS")) { statistics = new QList< QPair<QString, QString> >; LineManager iline(*incube); Statistics stats; Progress progress; progress.SetText("Statistics..."); progress.SetMaximumSteps(incube->lineCount()*incube->bandCount()); progress.CheckStatus(); iline.SetLine(1); for(; !iline.end() ; iline.next()) { incube->read(iline); stats.AddData(iline.DoubleBuffer(), iline.size()); progress.CheckStatus(); } // Compute stats of entire cube double nPixels = stats.TotalPixels(); double nullpercent = (stats.NullPixels() / (nPixels)) * 100; double hispercent = (stats.HisPixels() / (nPixels)) * 100; double hrspercent = (stats.HrsPixels() / (nPixels)) * 100; double lispercent = (stats.LisPixels() / (nPixels)) * 100; double lrspercent = (stats.LrsPixels() / (nPixels)) * 100; // Statitics output for band statistics->append(MakePair("MeanValue", toString(stats.Average()))); statistics->append(MakePair("StandardDeviation", toString(stats.StandardDeviation()))); statistics->append(MakePair("MinimumValue", toString(stats.Minimum()))); statistics->append(MakePair("MaximumValue", toString(stats.Maximum()))); statistics->append(MakePair("PercentHIS", toString(hispercent))); statistics->append(MakePair("PercentHRS", toString(hrspercent))); statistics->append(MakePair("PercentLIS", toString(lispercent))); statistics->append(MakePair("PercentLRS", toString(lrspercent))); statistics->append(MakePair("PercentNull", toString(nullpercent))); statistics->append(MakePair("TotalPixels", toString(stats.TotalPixels()))); } bool getFootBlob = ui.GetBoolean("USELABEL"); bool doGeometry = ui.GetBoolean("GEOMETRY"); bool doPolygon = ui.GetBoolean("POLYGON"); if(doGeometry || doPolygon || getFootBlob) { Camera *cam = incube->camera(); QString incType = ui.GetString("INCTYPE"); int polySinc, polyLinc; if(doPolygon && incType.toUpper() == "VERTICES") { ImagePolygon poly; poly.initCube(*incube); polySinc = polyLinc = (int)(0.5 + (((poly.validSampleDim() * 2) + (poly.validLineDim() * 2) - 3.0) / ui.GetInteger("NUMVERTICES"))); } else if (incType.toUpper() == "LINCSINC"){ if(ui.WasEntered("POLYSINC")) { polySinc = ui.GetInteger("POLYSINC"); } else { polySinc = (int)(0.5 + 0.10 * incube->sampleCount()); if(polySinc == 0) polySinc = 1; } if(ui.WasEntered("POLYLINC")) { polyLinc = ui.GetInteger("POLYLINC"); } else { polyLinc = (int)(0.5 + 0.10 * incube->lineCount()); if(polyLinc == 0) polyLinc = 1; } } else { QString msg = "Invalid INCTYPE option[" + incType + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } bandGeom = new BandGeometry(); bandGeom->setSampleInc(polySinc); bandGeom->setLineInc(polyLinc); bandGeom->setMaxIncidence(ui.GetDouble("MAXINCIDENCE")); bandGeom->setMaxEmission(ui.GetDouble("MAXEMISSION")); bool precision = ui.GetBoolean("INCREASEPRECISION"); if (getFootBlob) { // Need to read history to obtain parameters that were used to // create the footprint History hist("IsisCube", in.expanded()); Pvl pvl = hist.ReturnHist(); PvlObject::PvlObjectIterator objIter; bool found = false; PvlGroup fpgrp; for (objIter=pvl.endObject()-1; objIter>=pvl.beginObject(); objIter--) { if (objIter->name().toUpper() == "FOOTPRINTINIT") { found = true; fpgrp = objIter->findGroup("UserParameters"); break; } } if (!found) { QString msg = "Footprint blob was not found in input image history"; throw IException(IException::User, msg, _FILEINFO_); } QString prec = (QString)fpgrp.findKeyword("INCREASEPRECISION"); prec = prec.toUpper(); if (prec == "TRUE") { precision = true; } else { precision = false; } QString inctype = (QString)fpgrp.findKeyword("INCTYPE"); inctype = inctype.toUpper(); if (inctype == "LINCSINC") { int linc = fpgrp.findKeyword("LINC"); int sinc = fpgrp.findKeyword("SINC"); bandGeom->setSampleInc(sinc); bandGeom->setLineInc(linc); } else { int vertices = fpgrp.findKeyword("NUMVERTICES"); int lincsinc = (int)(0.5 + (((incube->sampleCount() * 2) + (incube->lineCount() * 2) - 3.0) / vertices)); bandGeom->setSampleInc(lincsinc); bandGeom->setLineInc(lincsinc); } if (fpgrp.hasKeyword("MAXINCIDENCE")) { double maxinc = fpgrp.findKeyword("MAXINCIDENCE"); bandGeom->setMaxIncidence(maxinc); } if (fpgrp.hasKeyword("MAXEMISSION")) { double maxema = fpgrp.findKeyword("MAXEMISSION"); bandGeom->setMaxEmission(maxema); } } bandGeom->collect(*cam, *incube, doGeometry, doPolygon, getFootBlob, precision); // Check if the user requires valid image center geometry if(ui.GetBoolean("VCAMERA") && (!bandGeom->hasCenterGeometry())) { QString msg = "Image center does not project in camera model"; throw IException(IException::Unknown, msg, _FILEINFO_); } } if(sFormat.toUpper() == "PVL") GeneratePVLOutput(incube, general, camstats, statistics, bandGeom); else GenerateCSVOutput(incube, general, camstats, statistics, bandGeom); // Clean the data delete general; general = NULL; if(camstats) { delete camstats; camstats = NULL; } if(statistics) { delete statistics; statistics = NULL; } if(bandGeom) { delete bandGeom; bandGeom = NULL; } }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); SerialNumberList serialNumbers(true); FileList images(ui.GetFileName("FROMLIST")); // list of sns/filenames sorted by serial number vector< pair<QString, QString> > sortedList; // We want to sort the input data by serial number so that the same // results are produced every time this program is run with the same // images. This is a modified insertion sort. for(int image = 0; image < images.size(); image++) { unsigned int insertPos = 0; QString sn = SerialNumber::Compose(images[image].toString()); for(insertPos = 0; insertPos < sortedList.size(); insertPos++) { if(sn.compare(sortedList[insertPos].first) < 0) break; } pair<QString, QString> newPair = pair<QString, QString>(sn, images[image].toString()); sortedList.insert(sortedList.begin() + insertPos, newPair); } // Add the serial numbers in sorted order now for(unsigned int i = 0; i < sortedList.size(); i++) { serialNumbers.Add(sortedList[i].second); } // Now we want the ImageOverlapSet to calculate our overlaps ImageOverlapSet overlaps(true); // Use multi-threading to create the overlaps overlaps.FindImageOverlaps(serialNumbers, FileName(ui.GetFileName( "OVERLAPLIST")).expanded()); // This will only occur when "CONTINUE" was true, so we can assume "ERRORS" was // an entered parameter. if(overlaps.Errors().size() != 0 && ui.WasEntered("ERRORS")) { Pvl outFile; bool filenamesOnly = !ui.GetBoolean("DETAILED"); vector<PvlGroup> errorList = overlaps.Errors(); for(unsigned int err = 0; err < errorList.size(); err++) { if(!filenamesOnly) { outFile += errorList[err]; } else if(errorList[err].hasKeyword("FileNames")) { PvlGroup origError = errorList[err]; PvlGroup err("ImageOverlapError"); for(int keyword = 0; keyword < origError.keywords(); keyword++) { if(origError[keyword].name() == "FileNames") { err += origError[keyword]; } } outFile += err; } } outFile.write(FileName(ui.GetFileName("ERRORS")).expanded()); } PvlGroup results("Results"); results += PvlKeyword("ErrorCount", toString((BigInt)overlaps.Errors().size())); Application::Log(results); }
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() { // 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() { UserInterface &ui = Application::GetUserInterface(); Isis::FileName fromFile = ui.GetFileName("FROM"); Isis::Cube inputCube; inputCube.open(fromFile.expanded()); //Check to make sure we got the cube properly if(!inputCube.isOpen()) { QString msg = "Could not open FROM cube" + fromFile.expanded(); throw IException(IException::User, msg, _FILEINFO_); } Process p; Cube *icube = p.SetInputCube("FROM"); int totalSamples = icube->sampleCount(); int totalLines = icube->lineCount(); Isis::LineManager lineManager(inputCube); lineManager.begin(); int leftFringe, rightFringe; int binningMode = icube->group("Instrument")["Summing"]; //determine the edges between which no statistics should be gathered leftFringe = 48 / binningMode; rightFringe = totalSamples - leftFringe; int numSections = ui.GetInteger("SECTIONS"); if(numSections > 9) { QString msg = "You may have no more than 9 sections per side"; throw IException(IException::User, msg, _FILEINFO_); } int sectionLength = 0; if(!ui.WasEntered("LINESIZE")) { //User didn't enter number of lines if(numSections == 0) { sectionLength = 0; } else { sectionLength = totalLines / numSections; } } else { sectionLength = ui.GetInteger("LINESIZE"); if((sectionLength * numSections > totalLines) || sectionLength < 1) { sectionLength = totalLines / numSections; } } Statistics sections[numSections][2]; Statistics leftTotal, rightTotal; int sectionStarts[numSections]; sectionStarts[0] = 0; for(int i = 1 ; i < numSections - 1 ; i ++) { sectionStarts[i] = (totalLines / numSections) * i; } if(numSections > 0) { sectionStarts[numSections -1] = totalLines - sectionLength; } int currentSection = 0; Buffer leftFringeBuf(leftFringe, 1, 1, lineManager.PixelType()); Buffer rightFringeBuf(leftFringe, 1, 1, lineManager.PixelType()); //Walk down the cube for(int lineCount = 0 ; lineCount < totalLines ; lineCount++) { inputCube.read(lineManager); //Read the edges into the fringe buffers for(int i = 0 ; i < leftFringe ; i++) { leftFringeBuf[i] = lineManager[i]; } for(int i = rightFringe ; i < totalSamples ; i++) { rightFringeBuf[i - rightFringe] = lineManager[i]; } //No matter what, add the fringe buffers to the totals for that side leftTotal.AddData(leftFringeBuf.DoubleBuffer(), leftFringeBuf.size()); rightTotal.AddData(rightFringeBuf.DoubleBuffer(), rightFringeBuf.size()); if(numSections == 0) { continue; } //Index is not too large for this fringe section if(lineCount < sectionStarts[currentSection] + sectionLength) { //Index is not too small for this fringe section if(lineCount >= sectionStarts[currentSection]) { sections[currentSection][0].AddData(leftFringeBuf.DoubleBuffer(), leftFringeBuf.size()); sections[currentSection][1].AddData(rightFringeBuf.DoubleBuffer(), rightFringeBuf.size()); } } else { currentSection++; //Since sections may butt up against each other, it is possible that // we have to add this data to the next section. if(lineCount >= sectionStarts[currentSection]) { sections[currentSection][0].AddData(leftFringeBuf.DoubleBuffer(), leftFringeBuf.size()); sections[currentSection][1].AddData(rightFringeBuf.DoubleBuffer(), rightFringeBuf.size()); } } } // Write the results to the output file if the user specified one PvlObject leftSide("LeftSide"), rightSide("RightSide"); for(int i = 0 ; i < numSections ; i++) { QString sectionName = "Section" + toString(i + 1); pvlOut(sections[i][0], //Stats to add to the left Object sections[i][1], //Stats to add to the right Object sectionName, //Name for the new groups sectionStarts[i], //start line sectionStarts[i] + sectionLength, //end line &leftSide, //Object to add left group to &rightSide //Object to add right group to ); } pvlOut(leftTotal, //Stats to add to the left Object rightTotal, //Stats to add to the right Object "Total", //Name for the new groups 0, //start line totalLines, //end line &leftSide, //Object to add left group to &rightSide //Object to add right group to ); Pvl outputPvl; PvlGroup sourceInfo("SourceInfo"); sourceInfo += PvlKeyword("From", fromFile.expanded()); sourceInfo += icube->group("Archive")["ProductId"]; outputPvl.addGroup(sourceInfo); if(numSections > 0) { outputPvl.addObject(leftSide); outputPvl.addObject(rightSide); } else { PvlGroup leftGroup = leftSide.findGroup("Total"); PvlGroup rightGroup = rightSide.findGroup("Total"); leftGroup.setName("LeftSide"); rightGroup.setName("RightSide"); outputPvl.addGroup(leftGroup); outputPvl.addGroup(rightGroup); } outputPvl.write(ui.GetFileName("TO")); }