void IsisMain() { // Create a process by line object ProcessByLine p; // Get the size of the cube Cube *icube = p.SetInputCube("FROM"); // Open output text file UserInterface &ui = Application::GetUserInterface(); QString to = ui.GetFileName("TO", "txt"); fout.open(to.toAscii().data()); // Print header if needed if(ui.GetBoolean("HEADER")) { fout << "Input Cube: " << icube->fileName() << endl; fout << "Samples:Lines:Bands: " << icube->sampleCount() << ":" << icube->lineCount() << ":" << icube->bandCount() << endl; } // List the cube p.StartProcess(isis2ascii); p.EndProcess(); fout.close(); }
/** * Constructs a UniversalGroundMap object from a cube * * @param cube The Cube to create the UniversalGroundMap from * @param priority Try to make a camera or projection first */ UniversalGroundMap::UniversalGroundMap(Cube &cube, CameraPriority priority) { p_camera = NULL; p_projection = NULL; Pvl &pvl = *cube.label(); try { if(priority == CameraFirst) p_camera = CameraFactory::Create(cube); else p_projection = Isis::ProjectionFactory::CreateFromCube(pvl); } catch (IException &firstError) { p_camera = NULL; p_projection = NULL; try { if(priority == CameraFirst) p_projection = Isis::ProjectionFactory::CreateFromCube(pvl); else p_camera = CameraFactory::Create(cube); } catch (IException &secondError) { p_projection = NULL; QString msg = "Could not create camera or projection for [" + cube.fileName() + "]"; IException realError(IException::Unknown, msg, _FILEINFO_); realError.append(firstError); realError.append(secondError); throw realError; } } }
QList<ControlPoint *> getValidPoints(Cube &cube, STRtree &coordTree) { ImagePolygon poly; try { cube.read(poly); } catch (IException &e) { QString msg = "Footprintinit must be run prior to running cnetadd"; msg += " with POLYGON=TRUE for cube [" + cube.fileName() + "]"; throw IException(e, IException::User, msg, _FILEINFO_); } std::vector<void *> matches; MultiPolygon *polys = poly.Polys(); for (unsigned int i = 0; i < polys->getNumGeometries(); i++) { const Geometry *geometry = polys->getGeometryN(i); const Envelope *boundingBox = geometry->getEnvelopeInternal(); coordTree.query(boundingBox, matches); } QList<ControlPoint *> results; for (unsigned int i = 0; i < matches.size(); i++) { results.append((ControlPoint *) matches[i]); } return results; }
/** * @brief Initializes an ISIS cube converting it into a SPICE segment * * This method is called to extract the perinent contents of an ISIS cube file * and accumulate generic information that is used to create the output SPICE * kernel segment. Other specific kernel types can use this class as its base * class and add to it additional elements to complete the needed content for * the NAIF kernel. * * @param cube ISIS cube file to accumulate information from */ void SpiceSegment::init(Cube &cube) { _kernels.UnLoad(); // Unload all active, owned kernels init(); // Init local variables _fname = cube.fileName(); // Extract ISIS CK blob and transform to CK 3 content NaifStatus::CheckErrors(); try { // Order is somewhat important here. The call to initialize Kernels // object checks the NAIF pool for existance. It logs their NAIF // status as loaded which may cause trouble from here on... Pvl *label = cube.label(); _kernels.Init(*label); Camera *camera = cube.camera(); // Determine segment ID from product ID if it exists, otherwise basename if ( _name.isEmpty() ) { _name = getKeyValue(*label, "ProductId"); if (_name.isEmpty() ) { _name = FileName(_fname).baseName(); } } // Get instrument and target ids QString value(""); value = getKeyValue(*label, "InstrumentId"); if (!value.isEmpty()) { _instId = value; } value = getKeyValue(*label, "TargetName"); if (!value.isEmpty()) { _target = value; } // Get default times for sorting purposes setStartTime(camera->cacheStartTime().Et()); setEndTime(camera->cacheEndTime().Et()); } catch ( IException &ie ) { ostringstream mess; mess << "Failed to construct Spice Segment basics from ISIS file " << _fname; throw IException(ie, IException::User, mess.str(), _FILEINFO_); } return; }
void IsisMain(){ const QString hical_program = "hicalbeta"; const QString hical_version = "5.0"; const QString hical_revision = "$Revision: 1.15 $"; const QString hical_runtime = Application::DateTime(); UserInterface &ui = Application::GetUserInterface(); QString procStep("prepping phase"); try { // The output from the last processing is the input into subsequent processing ProcessByLine p; Cube *hifrom = p.SetInputCube("FROM"); int nsamps = hifrom->sampleCount(); int nlines = hifrom->lineCount(); // Initialize the configuration file QString conf(ui.GetAsString("CONF")); HiCalConf hiconf(*(hifrom->label()), conf); DbProfile hiprof = hiconf.getMatrixProfile(); // Check for label propagation and set the output cube Cube *ocube = p.SetOutputCube("TO"); if ( !IsTrueValue(hiprof,"PropagateTables", "TRUE") ) { RemoveHiBlobs(*(ocube->label())); } // Set specified profile if entered by user if (ui.WasEntered("PROFILE")) { hiconf.selectProfile(ui.GetAsString("PROFILE")); } // Add OPATH parameter to profiles if (ui.WasEntered("OPATH")) { hiconf.add("OPATH",ui.GetAsString("OPATH")); } else { // Set default to output directory hiconf.add("OPATH", FileName(ocube->fileName()).path()); } // Do I/F output DN conversions QString units = ui.GetString("UNITS"); // Allocate the calibration list calVars = new MatrixList; // Set up access to HiRISE ancillary data (tables, blobs) here. Note it they // are gone, this will error out. See PropagateTables in conf file. HiCalData caldata(*hifrom); //////////////////////////////////////////////////////////////////////////// // Drift Correction (Zf) using buffer pixels // Extracts specified regions of the calibration buffer pixels and runs // series of lowpass filters. Apply spline fit if any missing data // remains. Config file contains parameters for this operation. procStep = "ZeroBufferSmooth module"; hiconf.selectProfile("ZeroBufferSmooth"); hiprof = hiconf.getMatrixProfile(); HiHistory ZbsHist; ZbsHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { ZeroBufferSmooth zbs(caldata, hiconf); calVars->add("ZeroBufferSmooth", zbs.ref()); ZbsHist = zbs.History(); if ( hiprof.exists("DumpModuleFile") ) { zbs.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { // NOT RECOMMENDED! This is required for the next step! // SURELY must be skipped with ZeroBufferSmooth step as well! calVars->add("ZeroBufferSmooth", HiVector(nlines, 0.0)); ZbsHist.add("Debug::SkipModule invoked!"); } ///////////////////////////////////////////////////////////////////// // ZeroBufferFit // Compute second level of drift correction. The high level noise // is removed from a modeled non-linear fit. // procStep = "ZeroBufferFit module"; HiHistory ZbfHist; hiconf.selectProfile("ZeroBufferFit"); hiprof = hiconf.getMatrixProfile(); ZbfHist.add("Profile["+ hiprof.Name()+"]"); if (!SkipModule(hiprof) ) { ZeroBufferFit zbf(hiconf); calVars->add(hiconf.getProfileName(), zbf.Normalize(zbf.Solve(calVars->get("ZeroBufferSmooth")))); ZbfHist = zbf.History(); if ( hiprof.exists("DumpModuleFile") ) { zbf.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nlines, 0.0)); ZbfHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // ZeroReverse procStep = "ZeroReverse module"; hiconf.selectProfile("ZeroReverse"); hiprof = hiconf.getMatrixProfile(); HiHistory ZrHist; ZrHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { ZeroReverse zr(caldata, hiconf); calVars->add(hiconf.getProfileName(), zr.ref()); ZrHist = zr.History(); if ( hiprof.exists("DumpModuleFile") ) { zr.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nsamps, 0.0)); ZrHist.add("Debug::SkipModule invoked!"); } ///////////////////////////////////////////////////////////////// // ZeroDark removes dark current // procStep = "ZeroDark module"; hiconf.selectProfile("ZeroDark"); hiprof = hiconf.getMatrixProfile(); HiHistory ZdHist; ZdHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { ZeroDark zd(hiconf); calVars->add(hiconf.getProfileName(), zd.ref()); ZdHist = zd.History(); if ( hiprof.exists("DumpModuleFile") ) { zd.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nsamps, 0.0)); ZdHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainLineDrift correct for gain-based drift // procStep = "GainLineDrift module"; hiconf.selectProfile("GainLineDrift"); hiprof = hiconf.getMatrixProfile(); HiHistory GldHist; GldHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainLineDrift gld(hiconf); calVars->add(hiconf.getProfileName(), gld.ref()); GldHist = gld.History(); if ( hiprof.exists("DumpModuleFile") ) { gld.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nlines, 1.0)); GldHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainNonLinearity Correct for non-linear gain procStep = "GainNonLinearity module"; hiconf.selectProfile("GainNonLinearity"); hiprof = hiconf.getMatrixProfile(); HiHistory GnlHist; GnlHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainNonLinearity gnl(hiconf); calVars->add(hiconf.getProfileName(), gnl.ref()); GnlHist = gnl.History(); if ( hiprof.exists("DumpModuleFile") ) { gnl.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(1, 0.0)); GnlHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainChannelNormalize Correct for sample gain with the G matrix procStep = "GainChannelNormalize module"; hiconf.selectProfile("GainChannelNormalize"); hiprof = hiconf.getMatrixProfile(); HiHistory GcnHist; GcnHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainChannelNormalize gcn(hiconf); calVars->add(hiconf.getProfileName(), gcn.ref()); GcnHist = gcn.History(); if ( hiprof.exists("DumpModuleFile") ) { gcn.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0)); GcnHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainFlatField Flat field correction with A matrix procStep = "GainFlatField module"; hiconf.selectProfile("GainFlatField"); hiprof = hiconf.getMatrixProfile(); HiHistory GffHist; GffHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainFlatField gff(hiconf); calVars->add(hiconf.getProfileName(), gff.ref()); GffHist = gff.History(); if ( hiprof.exists("DumpModuleFile") ) { gff.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0)); GffHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainTemperature - Temperature-dependant gain correction procStep = "GainTemperature module"; hiconf.selectProfile("GainTemperature"); hiprof = hiconf.getMatrixProfile(); HiHistory GtHist; GtHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainTemperature gt(hiconf); calVars->add(hiconf.getProfileName(), gt.ref()); GtHist = gt.History(); if ( hiprof.exists("DumpModuleFile") ) { gt.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(nsamps, 1.0)); GtHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainUnitConversion converts to requested units // procStep = "GainUnitConversion module"; hiconf.selectProfile("GainUnitConversion"); hiprof = hiconf.getMatrixProfile(); HiHistory GucHist; GucHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainUnitConversion guc(hiconf, units); calVars->add(hiconf.getProfileName(), guc.ref()); GucHist = guc.History(); if ( hiprof.exists("DumpModuleFile") ) { guc.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add(hiconf.getProfileName(), HiVector(1,1.0)); GucHist.add("Debug::SkipModule invoked!"); GucHist.add("Units[Unknown]"); } // Reset the profile selection to default hiconf.selectProfile(); //---------------------------------------------------------------------- // ///////////////////////////////////////////////////////////////////////// // Call the processing function procStep = "calibration phase"; p.StartProcess(calibrate); // Get the default profile for logging purposes hiprof = hiconf.getMatrixProfile(); const QString conf_file = hiconf.filepath(conf); // Quitely dumps parameter history to alternative format file. This // is completely controlled by the configuration file if ( hiprof.exists("DumpHistoryFile") ) { procStep = "logging/reporting phase"; FileName hdump(hiconf.getMatrixSource("DumpHistoryFile",hiprof)); QString hdumpFile = hdump.expanded(); ofstream ofile(hdumpFile.toAscii().data(), ios::out); if (!ofile) { QString mess = "Unable to open/create history dump file " + hdump.expanded(); IException(IException::User, mess, _FILEINFO_).print(); } else { ofile << "Program: " << hical_program << endl; ofile << "RunTime: " << hical_runtime << endl; ofile << "Version: " << hical_version << endl; ofile << "Revision: " << hical_revision << endl << endl; ofile << "FROM: " << hifrom->fileName() << endl; ofile << "TO: " << ocube->fileName() << endl; ofile << "CONF: " << conf_file << endl << endl; ofile << "/* " << hical_program << " application equation */\n" << "/* hdn = (idn - ZeroBufferFit(ZeroBufferSmooth) - ZeroReverse - ZeroDark) */\n" << "/* odn = hdn / GainLineDrift * GainNonLinearity * GainChannelNormalize */\n" << "/* * GainFlatField * GainTemperature / GainUnitConversion */\n\n"; ofile << "****** PARAMETER GENERATION HISTORY *******" << endl; ofile << "\nZeroBufferSmooth = " << ZbsHist << endl; ofile << "\nZeroBufferFit = " << ZbfHist << endl; ofile << "\nZeroReverse = " << ZrHist << endl; ofile << "\nZeroDark = " << ZdHist << endl; ofile << "\nGainLineDrift = " << GldHist << endl; ofile << "\nGainNonLinearity = " << GnlHist << endl; ofile << "\nGainChannelNormalize = " << GcnHist << endl; ofile << "\nGainFlatField = " << GffHist << endl; ofile << "\nGainTemperature = " << GtHist << endl; ofile << "\nGainUnitConversion = " << GucHist << endl; ofile.close(); } } // Ensure the RadiometricCalibration group is out there const QString rcalGroup("RadiometricCalibration"); if (!ocube->hasGroup(rcalGroup)) { PvlGroup temp(rcalGroup); ocube->putGroup(temp); } PvlGroup &rcal = ocube->group(rcalGroup); rcal += PvlKeyword("Program", hical_program); rcal += PvlKeyword("RunTime", hical_runtime); rcal += PvlKeyword("Version",hical_version); rcal += PvlKeyword("Revision",hical_revision); PvlKeyword key("Conf", conf_file); key.addCommentWrapped("/* " + hical_program + " application equation */"); key.addComment("/* hdn = idn - ZeroBufferFit(ZeroBufferSmooth) */"); key.addComment("/* - ZeroReverse - ZeroDark */"); key.addComment("/* odn = hdn / GainLineDrift * GainNonLinearity */"); key.addComment("/* * GainChannelNormalize * GainFlatField */"); key.addComment("/* * GainTemperature / GainUnitConversion */"); rcal += key; // Record parameter generation history. Controllable in configuration // file. Note this is optional because of a BUG!! in the ISIS label // writer as this application was initially developed if ( IsEqual(ConfKey(hiprof,"LogParameterHistory",QString("TRUE")),"TRUE")) { rcal += ZbsHist.makekey("ZeroBufferSmooth"); rcal += ZbfHist.makekey("ZeroBufferFit"); rcal += ZrHist.makekey("ZeroReverse"); rcal += ZdHist.makekey("ZeroDark"); rcal += GldHist.makekey("GainLineDrift"); rcal += GnlHist.makekey("GainNonLinearity"); rcal += GcnHist.makekey("GainChannelNormalize"); rcal += GffHist.makekey("GainFlatField"); rcal += GtHist.makekey("GainTemperature"); rcal += GucHist.makekey("GainUnitConversion"); } p.EndProcess(); } catch (IException &ie) { delete calVars; calVars = 0; QString mess = "Failed in " + procStep; throw IException(ie, IException::User, mess, _FILEINFO_); } // Clean up parameters delete calVars; calVars = 0; }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); Process p; // Get the histogram Cube *icube = p.SetInputCube("FROM"); double validMin = Isis::ValidMinimum; double validMax = Isis::ValidMaximum; if(ui.WasEntered("VALIDMIN")) { validMin = ui.GetDouble("VALIDMIN"); } if(ui.WasEntered("VALIDMAX")) { validMax = ui.GetDouble("VALIDMAX"); } // Set a global Pvl for storing results Pvl mainpvl; // Get the number of bands to process int bandcount = icube->bandCount(); for (int i = 1; i <= bandcount; i++) { Histogram *stats = icube->histogram(i, validMin, validMax); // Construct a label with the results PvlGroup results("Results"); results += PvlKeyword("From", icube->fileName()); results += PvlKeyword("Band", toString(icube->physicalBand(i))); if(stats->ValidPixels() != 0) { results += PvlKeyword("Average", toString(stats->Average())); results += PvlKeyword("StandardDeviation", toString(stats->StandardDeviation())); results += PvlKeyword("Variance", toString(stats->Variance())); // These statistics only worked on a histogram results += PvlKeyword("Median", toString(stats->Median())); results += PvlKeyword("Mode", toString(stats->Mode())); results += PvlKeyword("Skew", toString(stats->Skew())); results += PvlKeyword("Minimum", toString(stats->Minimum())); results += PvlKeyword("Maximum", toString(stats->Maximum())); results += PvlKeyword("Sum", toString(stats->Sum())); } results += PvlKeyword("TotalPixels", toString(stats->TotalPixels())); results += PvlKeyword("ValidPixels", toString(stats->ValidPixels())); results += PvlKeyword("OverValidMaximumPixels", toString(stats->OverRangePixels())); results += PvlKeyword("UnderValidMinimumPixels", toString(stats->UnderRangePixels())); results += PvlKeyword("NullPixels", toString(stats->NullPixels())); results += PvlKeyword("LisPixels", toString(stats->LisPixels())); results += PvlKeyword("LrsPixels", toString(stats->LrsPixels())); results += PvlKeyword("HisPixels", toString(stats->HisPixels())); results += PvlKeyword("HrsPixels", toString(stats->HrsPixels())); mainpvl.addGroup(results); delete stats; // Write the results to the log Application::Log(results); } // Write the results to the output file if the user specified one if(ui.WasEntered("TO")) { QString outFile = FileName(ui.GetFileName("TO")).expanded(); bool exists = FileName(outFile).fileExists(); bool append = ui.GetBoolean("APPEND"); ofstream os; bool writeHeader = false; //write the results in the requested format. if(ui.GetString("FORMAT") == "PVL") { if(append) { mainpvl.append(outFile); } else { mainpvl.write(outFile); } } else { //if the format was not PVL, write out a flat file. if(append) { os.open(outFile.toAscii().data(), ios::app); if(!exists) { writeHeader = true; } } else { os.open(outFile.toAscii().data(), ios::out); writeHeader = true; } if(writeHeader) { for(int i = 0; i < mainpvl.group(0).keywords(); i++) { os << mainpvl.group(0)[i].name(); if( i < mainpvl.group(0).keywords() - 1 ) { os << ","; } } os << endl; } for(int i = 0; i < mainpvl.groups(); i++) { for (int j = 0; j < mainpvl.group(i).keywords(); j++) { os << (QString)mainpvl.group(i)[j]; if(j < mainpvl.group(i).keywords() - 1) { os << ","; } } os << endl; } } } }
void IsisMain() { // We will be processing by line ProcessByBrick p; UserInterface &ui = Application::GetUserInterface(); // Use the def file for filter constants Pvl uvvisDef("$clementine1/calibration/uvvis/uvvis.def"); // Setup the input and output cubes Cube *icube = p.SetInputCube("FROM"); Cube *dccube; if(ui.WasEntered("DCFILE")) { dccube = p.SetInputCube("DCFILE"); } else { QString dcfileloc = "$clementine1/calibration/uvvis/"; dcfileloc += "dark_5_15_96.cub"; CubeAttributeInput cubeAtt; dccube = p.SetInputCube(dcfileloc, cubeAtt); } QString filter = (QString)(icube->group("BandBin"))["FilterName"]; filter = filter.toLower(); Cube *ffcube; if(ui.WasEntered("FFFILE")) { ffcube = p.SetInputCube("FFFILE"); } else { // compute default fffile double compressRatio = (icube->group("Instrument"))["EncodingCompressionRatio"]; // check to see if cube is compressed or uncompressed if(compressRatio == 1.0) { QString fffileLoc = "$clementine1/calibration/uvvis/"; fffileLoc += "lu" + filter + "_uncomp_flat_long.cub"; CubeAttributeInput cubeAtt; ffcube = p.SetInputCube(fffileLoc, cubeAtt); } else { QString fffileLoc = "$clementine1/calibration/uvvis/"; fffileLoc += "lu" + filter + "_comp_flat_long.cub"; CubeAttributeInput cubeAtt; ffcube = p.SetInputCube(fffileLoc, cubeAtt); } } Cube *ocube = p.SetOutputCube("TO"); avgFF = uvvisDef.findGroup("Filter" + filter.toUpper())["AVGFF"]; cr = uvvisDef.findGroup("Filter" + filter.toUpper())["CO"]; gain = uvvisDef.findGroup(QString("GainModeID") + QString(icube->group("Instrument")["GainModeID"][0]))["GAIN"]; useDcconst = ui.WasEntered("DCCONST"); if(useDcconst) { dcconst = ui.GetDouble("DCCONST"); } else { dcconst = 0.0; } conv = ui.GetBoolean("CONV"); exposureDuration = icube->group("Instrument")["ExposureDuration"]; offsetModeID = icube->group("Instrument")["OffsetModeID"]; if(((QString)icube->group("Instrument")["FocalPlaneTemperature"]).compare("UNK") == 0) { //if FocalPlaneTemp is unknown set it to zero focalPlaneTemp = 0.0; } else { focalPlaneTemp = icube->group("Instrument")["FocalPlaneTemperature"]; } Camera *cam = icube->camera(); bool camSuccess = cam->SetImage(icube->sampleCount() / 2, icube->lineCount() / 2); if(!camSuccess) { throw IException(IException::Unknown, "Unable to calculate the Solar Distance for this cube.", _FILEINFO_); } dist = cam->SolarDistance(); // If temp. correction set to true, or focal plane temp is zero then use temperature correction if(ui.GetBoolean("TCOR") || abs(focalPlaneTemp) <= DBL_EPSILON) { // Temperature correction requires the use of the mission phase // (PRELAUNCH, EARTH, LUNAR) and the product ID. QString productID = (QString)(icube->group("Archive")["ProductID"]); QChar missionPhase = ((QString)((icube->group("Archive"))["MissionPhase"])).at(0); QString n1subQString(productID.mid(productID.indexOf('.') + 1, productID.length() - 1)); QString n2subQString(productID.mid(4, productID.indexOf('.') - 5)); int n1 = toInt(n1subQString); int n2 = toInt(n2subQString); int phase = 0; if(missionPhase == 'L') { phase = 0; } else if(missionPhase == 'E') { phase = 1; } else if(missionPhase == 'P') { phase = 2; } else { throw IException(IException::Unknown, "Invalid Mission Phase", _FILEINFO_); } // This formula makes the primary search critera the original product ID's extension, // the secondary search criteria the mission phase and finally the numerical part of the // original product ID. int imageID = (100000 * n1) + (10000 * phase) + n2; FixTemp(imageID); } if(focalPlaneTemp <= 0.0) { focalPlaneTemp = 272.5; } // Start the processing p.SetBrickSize(icube->sampleCount(), icube->lineCount(), 1); p.StartProcess(UvVisCal); // Add the radiometry group PvlGroup calgrp("Radiometry"); calgrp += PvlKeyword("FlatFieldFile", ffcube->fileName()); if(ui.GetString("DARKCURRENT").compare("DCFILE") == 0) { calgrp += PvlKeyword("DarkCurrentFile", dccube->fileName()); } else { calgrp += PvlKeyword("DarkCurrentConstant", toString(dcconst)); } calgrp += PvlKeyword("CorrectedFocalPlaneTemp", toString(focalPlaneTemp)); calgrp += PvlKeyword("C1", toString(avgFF)); calgrp += PvlKeyword("C2", toString(C2)); calgrp += PvlKeyword("C3", toString(C3)); calgrp += PvlKeyword("C4", toString(C4)); calgrp += PvlKeyword("C5", toString(C5)); calgrp += PvlKeyword("CR", toString(cr)); calgrp += PvlKeyword("FrameTransferTimePerRow", toString(cr)); calgrp += PvlKeyword("Gain", toString(gain)); calgrp += PvlKeyword("CorrectedExposureDuration", toString(correctedExposureDuration)); calgrp += PvlKeyword("ConvertToRadiance", toString(conv)); calgrp += PvlKeyword("ACO", toString(ACO)); calgrp += PvlKeyword("BCO", toString(BCO)); calgrp += PvlKeyword("CCO", toString(CCO)); calgrp += PvlKeyword("DCO", toString(DCO)); ocube->putGroup(calgrp); p.EndProcess(); }
void IsisMain() { // We will be processing by line ProcessByLine p; // Setup the input and make sure it is a mariner10 file UserInterface & ui = Application::GetUserInterface(); Isis::Pvl lab(ui.GetFileName("FROM")); Isis::PvlGroup & inst = lab.findGroup("Instrument", Pvl::Traverse); QString mission = inst["SpacecraftName"]; if (mission != "Mariner_10") { string msg = "This is not a Mariner 10 image. Mar10cal requires a Mariner 10 image."; throw IException(IException::User, msg, _FILEINFO_); } Cube * icube = p.SetInputCube("FROM", OneBand); // If it is already calibrated then complain if (icube->hasGroup("Radiometry")) { QString msg = "This Mariner 10 image [" + icube->fileName() + "] has " "already been radiometrically calibrated"; throw IException(IException::User, msg, _FILEINFO_); } // Get label parameters we will need for calibration equation QString instId = inst["InstrumentId"]; QString camera = instId.mid(instId.size()-1); QString filter = (QString)(icube->group("BandBin"))["FilterName"]; filter = filter.toUpper().mid(0,3); QString target = inst["TargetName"]; iTime startTime((QString) inst["StartTime"]); double exposure = inst["ExposureDuration"]; double exposureOffset = 0.0; if (ui.WasEntered("EXPOFF")) { exposureOffset = ui.GetDouble("EXPOFF"); } else { if (camera == "A") { exposureOffset = 0.316; } else if (camera == "B") { exposureOffset = 3.060; } else { QString msg = "Camera [" + camera + "] is not supported."; throw IException(IException::User, msg, _FILEINFO_); } } correctedExp = exposure + exposureOffset; Cube * dcCube; if (ui.WasEntered ("DCCUBE") ) { dcCube = p.SetInputCube("DCCUBE"); } else { // Mercury Dark current // ??? NOTE: Need to find Mark's dc for venus and moon ???? QString dcFile("$mariner10/calibration/mariner_10_" + camera + "_dc.cub"); CubeAttributeInput cubeAtt; dcCube = p.SetInputCube(dcFile, cubeAtt); } // Open blemish removal file Cube * blemCube = 0; useBlem = (ui.GetBoolean("BLEMMASK")) ? true : false; if (useBlem) { QString blemFile("$mariner10/calibration/mariner_10_blem_" + camera + ".cub"); CubeAttributeInput cubeAtt; blemCube = p.SetInputCube(blemFile, cubeAtt); } if (filter == "FAB" || filter == "WAF") { QString msg = "Filter type [" + filter + "] is not supported at this time."; throw IException(IException::User, msg, _FILEINFO_); } if (ui.WasEntered ("COEFCUBE")) { coCube.open(ui.GetFileName("COEFCUBE")); } else { FileName coFile("$mariner10/calibration/mariner_10_" + filter + "_" + camera + "_coef.cub"); coCube.open(coFile.expanded()); } coef = new Brick(icube->sampleCount(), 1, 6, coCube.pixelType()); if (ui.WasEntered("ABSCOEF")) { absCoef = ui.GetDouble("ABSCOEF"); } else { if (camera == "A") { absCoef = 16.0; } else if (camera == "B") { absCoef = 750.0; } else { QString msg = "Camera [" + camera + "] is not supported."; throw IException(IException::User, msg, _FILEINFO_); } } mask = ui.GetBoolean("MASK"); xparm = ui.GetDouble("XPARM"); // Get the distance between Mars and the Sun at the given time in // Astronomical Units (AU) Camera * cam = icube->camera(); bool camSuccess = cam->SetImage(icube->sampleCount()/2,icube->lineCount()/2); if (!camSuccess) { throw IException(IException::Unknown, "Unable to calculate the Solar Distance on [" + icube->fileName() + "]", _FILEINFO_); } sunDist = cam->SolarDistance(); // Setup the output cube Cube *ocube = p.SetOutputCube("TO"); // Add the radiometry group PvlGroup calgrp("Radiometry"); calgrp += PvlKeyword("DarkCurrentCube", dcCube->fileName()); if (useBlem) { calgrp += PvlKeyword("BlemishRemovalCube", blemCube->fileName()); } calgrp += PvlKeyword("CoefficientCube", coCube.fileName()); calgrp += PvlKeyword("AbsoluteCoefficient", toString(absCoef)); ocube->putGroup(calgrp); // Start the line-by-line calibration sequence p.StartProcess(Mar10Cal); p.EndProcess(); }
// Main moccal routine void IsisMain() { // We will be processing by line ProcessByLine p; // Setup the input and make sure it is a ctx file UserInterface &ui = Application::GetUserInterface(); Isis::Pvl lab(ui.GetFileName("FROM")); Isis::PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse); QString instId = inst["InstrumentId"]; if(instId != "CTX") { QString msg = "This is not a CTX image. Ctxcal requires a CTX image."; throw IException(IException::User, msg, _FILEINFO_); } Cube *icube = p.SetInputCube("FROM", OneBand); Cube flatFile; if(ui.WasEntered("FLATFILE")) { flatFile.open(ui.GetFileName("FLATFILE")); } else { FileName flat = FileName("$mro/calibration/ctxFlat_????.cub").highestVersion(); flatFile.open(flat.expanded()); } flat = new Brick(5000, 1, 1, flatFile.pixelType()); flat->SetBasePosition(1, 1, 1); flatFile.read(*flat); // If it is already calibrated then complain if(icube->hasGroup("Radiometry")) { QString msg = "The CTX image [" + icube->fileName() + "] has already " "been radiometrically calibrated"; throw IException(IException::User, msg, _FILEINFO_); } // Get label parameters we will need for calibration equation iTime startTime((QString) inst["StartTime"]); double etStart = startTime.Et(); // Read exposure and convert to milliseconds exposure = inst["LineExposureDuration"]; //exposure *= 1000.; sum = inst["SpatialSumming"]; // If firstSamp > 0, adjust by 38 to account for prefix pixels. firstSamp = inst["SampleFirstPixel"]; if(firstSamp > 0) firstSamp -= 38; // Read dark current info, if no dc exit? Table dcTable("Ctx Prefix Dark Pixels"); icube->read(dcTable); // TODO:: make sure dc records match cube nlines. // If summing mode = 1 , average odd & even dc pixels separately for // a & b channels. // If summing mode != 1, average all dc pixels and use for both for(int rec = 0; rec < dcTable.Records(); rec++) { vector<int> darks = dcTable[rec]["DarkPixels"]; bool aChannel = true; double dcASum = 0.; double dcBSum = 0.; int dcACount = 0; int dcBCount = 0; double dcSum = 0; int dcCount = 0; for(int i = 0; i < (int)darks.size(); i++) { if(sum == 1) { if(aChannel == true) { dcASum += (double)darks.at(i); dcACount++; } else { dcBSum += (double)darks.at(i); dcBCount++; } aChannel = !aChannel; } else if(sum > 1) { dcSum += (double)darks.at(i); dcCount ++; } } if(sum == 1) { dcA.push_back(dcASum / (double)dcACount); dcB.push_back(dcBSum / (double)dcBCount); } else { dc.push_back(dcSum / (double)dcCount); } } // See if the user wants counts/ms or i/f // iof = conversion factor from counts/ms to i/f bool convertIOF = ui.GetBoolean("IOF"); if(convertIOF) { // Get the distance between Mars and the Sun at the given time in // Astronomical Units (AU) QString bspKernel = p.MissionData("base", "/kernels/spk/de???.bsp", true); furnsh_c(bspKernel.toAscii().data()); QString pckKernel = p.MissionData("base", "/kernels/pck/pck?????.tpc", true); furnsh_c(pckKernel.toAscii().data()); double sunpos[6], lt; spkezr_c("sun", etStart, "iau_mars", "LT+S", "mars", sunpos, <); double dist1 = vnorm_c(sunpos); unload_c(bspKernel.toAscii().data()); unload_c(pckKernel.toAscii().data()); double dist = 2.07E8; double w0 = 3660.5; double w1 = w0 * ((dist * dist) / (dist1 * dist1)); if(exposure *w1 == 0.0) { QString msg = icube->fileName() + ": exposure or w1 has value of 0.0 "; throw IException(IException::User, msg, _FILEINFO_); } iof = 1.0 / (exposure * w1); } else { iof = 1.0; } // Setup the output cube Cube *ocube = p.SetOutputCube("TO"); // Add the radiometry group PvlGroup calgrp("Radiometry"); calgrp += PvlKeyword("FlatFile", flatFile.fileName()); calgrp += PvlKeyword("iof", toString(iof)); ocube->putGroup(calgrp); // Start the line-by-line calibration sequence p.StartProcess(Calibrate); p.EndProcess(); }
void IsisMain () { ResetGlobals(); UserInterface &ui = Application::GetUserInterface(); ProcessByBrick p; Cube *icube = p.SetInputCube("FROM"); // Make sure it is a WAC cube Isis::PvlGroup &inst = icube->label()->findGroup("Instrument", Pvl::Traverse); QString instId = (QString) inst["InstrumentId"]; instId = instId.toUpper(); if (instId != "WAC-VIS" && instId != "WAC-UV") { QString msg = "This program is intended for use on LROC WAC images only. ["; msg += icube->fileName() + "] does not appear to be a WAC image."; throw IException(IException::User, msg, _FILEINFO_); } // And check if it has already run through calibration if (icube->label()->findObject("IsisCube").hasGroup("Radiometry")) { QString msg = "This image has already been calibrated"; throw IException(IException::User, msg, _FILEINFO_); } if (icube->label()->findObject("IsisCube").hasGroup("AlphaCube")) { QString msg = "This application can not be run on any image that has been geometrically transformed (i.e. scaled, rotated, sheared, or reflected) or cropped."; throw IException(IException::User, msg, _FILEINFO_); } g_dark = ui.GetBoolean("DARK"); g_flatfield = ui.GetBoolean("FLATFIELD"); g_radiometric = ui.GetBoolean("RADIOMETRIC"); g_iof = (ui.GetString("RADIOMETRICTYPE") == "IOF"); g_specpix = ui.GetBoolean("SPECIALPIXELS"); g_temprature = ui.GetBoolean("TEMPERATURE"); // Determine the dark/flat files to use QString offset = (QString) inst["BackgroundOffset"]; QString mode = (QString) inst["Mode"]; QString instModeId = (QString) inst["InstrumentModeId"]; instModeId = instModeId.toUpper(); if (instModeId == "COLOR" && (QString) inst["InstrumentId"] == "WAC-UV") instModeId = "UV"; else if (instModeId == "VIS") instModeId = "COLOR"; g_startTemperature = (double) inst["BeginTemperatureFpa"]; g_endTemperature = (double) inst["EndTemperatureFpa"]; g_numFrames = (int) inst["NumFramelets"]; vector<QString> darkFiles; ui.GetAsString("DARKFILE", darkFiles); QString flatFile = ui.GetAsString("FLATFIELDFILE"); QString radFile = ui.GetAsString("RADIOMETRICFILE"); QString specpixFile = ui.GetAsString("SPECIALPIXELSFILE"); QString tempFile = ui.GetAsString("TEMPERATUREFILE"); // Figure out which bands are input for (int i = 1; i <= icube->bandCount(); i++) { g_bands.push_back(icube->physicalBand(i)); } Isis::PvlGroup &bandBin = icube->label()->findGroup("BandBin", Pvl::Traverse); QString filter = (QString) bandBin["Center"][0]; QString filterNum = (QString) bandBin["FilterNumber"][0]; //We have to pay special attention incase we are passed a //single band image that has been "exploded" from a multiband wac if (instModeId == "COLOR" && g_bands.size() == 1) g_bands[0] = (toInt(filterNum) -2); else if (instModeId == "UV" && g_bands.size() == 1) g_bands[0] = (toInt(filterNum)); if (g_dark) { if (darkFiles.size() == 0 || darkFiles[0] =="Default" || darkFiles[0].length() == 0) { darkFiles.resize(2); double temp = (double) inst["MiddleTemperatureFpa"]; double time = iTime(inst["StartTime"][0]).Et(); QString darkFile = "$lro/calibration/wac_darks/WAC_" + instModeId; if (instModeId == "BW") darkFile += "_" + filter + "_Mode" + mode; darkFile += "_Offset" + offset + "_*C_*T_Dark.????.cub"; GetDark (darkFile, temp, time, g_darkCube1, g_darkCube2, g_temp1, g_temp2, darkFiles[0], darkFiles[1]); } else if (darkFiles.size() == 1) { CopyCubeIntoBuffer(darkFiles[0], g_darkCube1); g_temp1 = 0.0; g_darkCube2 = new Buffer(*g_darkCube1); g_temp2 = g_temp1; } else { CopyCubeIntoBuffer(darkFiles[0], g_darkCube1); int index = darkFiles[0].lastIndexOf("_"); g_temp1 = IString(darkFiles[0].mid( darkFiles[0].lastIndexOf("_", index-1), index)).ToDouble(); CopyCubeIntoBuffer(darkFiles[1], g_darkCube2); index = darkFiles[1].lastIndexOf("_"); g_temp2 = IString(darkFiles[1].mid( darkFiles[1].lastIndexOf("_", index-1), index)).ToDouble(); } } if (g_flatfield) { if (flatFile.toLower() == "default" || flatFile.length() == 0) { flatFile = "$lro/calibration/wac_flats/WAC_" + instModeId; if (instModeId == "BW") flatFile += "_" + filter + "_Mode" + mode; flatFile += "_Flatfield.????.cub"; } CopyCubeIntoBuffer(flatFile, g_flatCube); // invert the flat-field data here so we don't have to divide for every pixel of the wac for (int i = 0; i < g_flatCube->size(); i++) { (*g_flatCube)[i] = 1.0 / (*g_flatCube)[i]; } } PvlKeyword responsivity; if (g_radiometric) { Isis::PvlKeyword &bands = icube->label()->findGroup("BandBin", Pvl::Traverse).findKeyword("FilterNumber"); if (radFile.toLower() == "default" || radFile.length() == 0) radFile = "$lro/calibration/WAC_RadiometricResponsivity.????.pvl"; FileName radFileName(radFile); if (radFileName.isVersioned()) radFileName = radFileName.highestVersion(); if (!radFileName.fileExists()) { QString msg = radFile + " does not exist."; throw IException(IException::User, msg, _FILEINFO_); } Pvl radPvl(radFileName.expanded()); if (g_iof) { responsivity = radPvl["IOF"]; for (int i = 0; i < bands.size(); i++) g_iofResponsivity.push_back(toDouble(responsivity[toInt(bands[i]) - 1])); try { iTime startTime((QString) inst["StartTime"]); double etStart = startTime.Et(); // Get the distance between the Moon and the Sun at the given time in // Astronomical Units (AU) QString bspKernel1 = p.MissionData("lro", "/kernels/tspk/moon_pa_de421_1900-2050.bpc", false); QString bspKernel2 = p.MissionData("lro", "/kernels/tspk/de421.bsp", false); furnsh_c(bspKernel1.toAscii().data()); furnsh_c(bspKernel2.toAscii().data()); QString pckKernel1 = p.MissionData("base", "/kernels/pck/pck?????.tpc", true); QString pckKernel2 = p.MissionData("lro", "/kernels/pck/moon_080317.tf", false); QString pckKernel3 = p.MissionData("lro", "/kernels/pck/moon_assoc_me.tf", false); furnsh_c(pckKernel1.toAscii().data()); furnsh_c(pckKernel2.toAscii().data()); furnsh_c(pckKernel3.toAscii().data()); double sunpos[6], lt; spkezr_c("sun", etStart, "MOON_ME", "LT+S", "MOON", sunpos, <); g_solarDistance = vnorm_c(sunpos) / KM_PER_AU; unload_c(bspKernel1.toAscii().data()); unload_c(bspKernel2.toAscii().data()); unload_c(pckKernel1.toAscii().data()); unload_c(pckKernel2.toAscii().data()); unload_c(pckKernel3.toAscii().data()); } catch (IException &e) { QString msg = "Can not find necessary SPICE kernels for converting to IOF"; throw IException(e, IException::User, msg, _FILEINFO_); } } else { responsivity = radPvl["Radiance"]; for (int i = 0; i < bands.size(); i++) g_radianceResponsivity.push_back(toDouble(responsivity[toInt(bands[i]) - 1])); } } if (g_specpix) { if (specpixFile.toLower() == "default" || specpixFile.length() == 0) { specpixFile = "$lro/calibration/wac_masks/WAC_" + instModeId; double temp = (double) inst["MiddleTemperatureFpa"]; if (instModeId == "BW") specpixFile += "_" + filter + "_Mode" + mode; specpixFile += "_*C_SpecialPixels.????.cub"; GetMask(specpixFile, temp, g_specpixCube); } else CopyCubeIntoBuffer(specpixFile, g_specpixCube); } if (g_temprature) { if (tempFile.toLower() == "default" || tempFile.length() == 0) tempFile = "$lro/calibration/WAC_TempratureConstants.????.pvl"; FileName tempFileName(tempFile); if (tempFileName.isVersioned()) tempFileName = tempFileName.highestVersion(); if (!tempFileName.fileExists()) { QString msg = tempFile + " does not exist."; throw IException(IException::User, msg, _FILEINFO_); } Isis::PvlKeyword &bands = icube->label()->findGroup("BandBin", Pvl::Traverse).findKeyword("FilterNumber"); Pvl tempPvl(tempFileName.expanded()); for (int b = 0; b < bands.size(); b++){ g_TempratureConstants[g_bands[b]][0]=toDouble(tempPvl[bands[b]][0]); g_TempratureConstants[g_bands[b]][1]=toDouble(tempPvl[bands[b]][1]); } } if (instModeId == "BW") { if (mode == "1" || mode == "0") p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size())); else p.SetBrickSize(POLAR_MODE_SAMPLES, VIS_LINES, (int)min(BW_BANDS, g_bands.size())); } else if (instModeId == "COLOR") { p.SetBrickSize(NO_POLAR_MODE_SAMPLES, VIS_LINES, (int)min(COLOR_BANDS, g_bands.size())); } else if (instModeId == "UV") { p.SetBrickSize(UV_SAMPLES, UV_LINES, (int)min(UV_BANDS, g_bands.size())); } g_exposure = inst["ExposureDuration"]; Cube *ocube = p.SetOutputCube("TO"); p.ProcessCube(Calibrate, false); // Add an output group with the appropriate information PvlGroup calgrp("Radiometry"); if (g_dark) { PvlKeyword darks("DarkFiles"); darks.addValue(darkFiles[0]); if (darkFiles.size() > 1) darks.addValue(darkFiles[1]); calgrp += darks; } if (g_flatfield) calgrp += PvlKeyword("FlatFile", flatFile); if (g_radiometric) { PvlKeyword vals("ResponsivityValues"); if (g_iof) { calgrp += PvlKeyword("RadiometricType", "IOF"); for (unsigned int i=0; i< g_iofResponsivity.size(); i++) vals.addValue(toString(g_iofResponsivity[i])); } else { calgrp += PvlKeyword("RadiometricType", "AbsoluteRadiance"); for (unsigned int i=0; i< g_radianceResponsivity.size(); i++) vals.addValue(toString(g_radianceResponsivity[i])); } calgrp += vals; calgrp += PvlKeyword("SolarDistance", toString(g_solarDistance)); } if (g_specpix) calgrp += PvlKeyword("SpecialPixelsFile", specpixFile); ocube->putGroup(calgrp); }
// Main moccal routine void IsisMain() { // We will be processing by line ProcessByLine p; // Setup the input and make sure it is a moc file UserInterface &ui = Application::GetUserInterface(); Cube *icube = p.SetInputCube("FROM", OneBand); gbl::moc = new MocLabels(ui.GetFileName("FROM")); // If it is already calibrated then complain if(icube->hasGroup("Radiometry")) { QString msg = "The MOC image [" + icube->fileName() + "] has already " "been radiometrically calibrated"; throw IException(IException::User, msg, _FILEINFO_); } // Get label parameters we will need for calibration equation gbl::a = gbl::moc->Gain(); gbl::off = gbl::moc->Offset(); gbl::ex = gbl::moc->ExposureDuration(); // Get the starting, ending, and activation et's. For now, the // activation et is set to the largest double precision value. If // The narrow angle B detectors ever get activated then the value // will need to be changed to the appropriate et iTime startTime(gbl::moc->StartTime()); double etStart = startTime.Et(); double etNABActivation = DBL_MAX; // Open the calibration kernel that contains constants for each camera // and internalize it in a pvl object QString calKernelFile; if(ui.WasEntered("CALKERNEL")) { calKernelFile = ui.GetFileName("CALKERNEL"); } else { calKernelFile = p.MissionData("mgs", "/calibration/moccal.ker.???", true); } Pvl calKernel(calKernelFile); // Point to the right group of camera parameters QString camera; if(gbl::moc->WideAngleRed()) { camera = "WideAngleRed"; } else if(gbl::moc->WideAngleBlue()) { camera = "WideAngleBlue"; } else if(etStart > etNABActivation) { camera = "NarrowAngleB"; } else { camera = "NarrowAngleA"; } PvlGroup &calCamera = calKernel.findGroup(camera); // Get the camera specific calibration parameters from the kernel file // and load detector coefficients (gain/offsets at each pixel) gbl::z = calCamera["Z"]; gbl::dc = calCamera["DC"]; gbl::g = calCamera["G"]; gbl::w0 = calCamera["W0"]; QString coefFile = calCamera["CoefFile"]; gbl::LoadCoefficients(coefFile, icube->sampleCount()); #if 0 // Override with these with any user selected parameters if(ui.WasEntered("Z")) gbl::z = ui.GetDouble("Z"); if(ui.WasEntered("DC")) gbl::dc = ui.GetDouble("DC"); if(ui.WasEntered("G")) gbl::g = ui.GetDouble("G"); if(ui.WasEntered("W0")) gbl::w0 = ui.GetDouble("W0"); #endif gbl::nullWago = ui.GetBoolean("NULLWAGO"); // Get the distance between Mars and the Sun at the given time in // Astronomical Units (AU) QString bspKernel = p.MissionData("base", "/kernels/spk/de???.bsp", true); furnsh_c(bspKernel.toAscii().data()); QString pckKernel = p.MissionData("base", "/kernels/pck/pck?????.tpc", true); furnsh_c(pckKernel.toAscii().data()); double sunpos[6], lt; spkezr_c("sun", etStart, "iau_mars", "LT+S", "mars", sunpos, <); double dist = vnorm_c(sunpos); double kmPerAU = 1.4959787066E8; double sunAU = dist / kmPerAU; unload_c(bspKernel.toAscii().data()); unload_c(pckKernel.toAscii().data()); // See if the user wants counts/ms or i/f but if w0 is 0 then // we must go to counts/ms // iof = conversion factor from counts/ms to i/f bool convertIOF = ui.GetBoolean("IOF") && (gbl::w0 > 0.0); if(convertIOF) { gbl::iof = sunAU * sunAU / gbl::w0; } else { gbl::iof = 1.0; } // Setup the output cube Cube *ocube = p.SetOutputCube("TO"); // Add the radiometry group PvlGroup calgrp("Radiometry"); calgrp += PvlKeyword("CalibrationKernel", calKernelFile); calgrp += PvlKeyword("CoefficientFile", coefFile); calgrp += PvlKeyword("a", toString(gbl::a)); calgrp["a"].addComment("Radiometric equation in moccal"); calgrp["a"].addComment("r = (pixel - z + off) / a - g / ex - dc"); calgrp += PvlKeyword("off", toString(gbl::off)); calgrp += PvlKeyword("ex", toString(gbl::ex)); calgrp += PvlKeyword("z", toString(gbl::z)); calgrp += PvlKeyword("dc", toString(gbl::dc)); calgrp += PvlKeyword("g", toString(gbl::g)); calgrp += PvlKeyword("w0", toString(gbl::w0)); calgrp["w0"].addComment("Reflectance = r * iof, where iof = (s * s) / w0"); calgrp += PvlKeyword("s", toString(sunAU)); calgrp += PvlKeyword("iof", toString(gbl::iof)); ocube->putGroup(calgrp); // Start the line-by-line calibration sequence p.StartProcess(gbl::Calibrate); p.EndProcess(); // Now go fix errors around the wago changes gbl::FixWagoLines(ui.GetFileName("TO")); // Cleanup gbl::pixelGain.clear(); gbl::pixelOffset.clear(); gbl::inLineAvg.clear(); gbl::outLineAvg.clear(); }
/** The ISIS smtk main application */ void IsisMain() { UserInterface &ui = Application::GetUserInterface(); // Open the first cube. It is the left hand image. Cube lhImage; CubeAttributeInput &attLeft = ui.GetInputAttribute("FROM"); vector<QString> bandLeft = attLeft.bands(); lhImage.setVirtualBands(bandLeft); lhImage.open(ui.GetFileName("FROM"),"r"); // Open the second cube, it is geomertricallty altered. We will be matching the // first to this one by attempting to compute a sample/line offsets Cube rhImage; CubeAttributeInput &attRight = ui.GetInputAttribute("MATCH"); vector<QString> bandRight = attRight.bands(); rhImage.setVirtualBands(bandRight); rhImage.open(ui.GetFileName("MATCH"),"r"); // Ensure only single bands if (lhImage.bandCount() != 1 || rhImage.bandCount() != 1) { QString msg = "Input Cubes must have only one band!"; throw IException(IException::User,msg,_FILEINFO_); } // Both images must have a Camera and can also have a Projection. We will // only deal with a Camera, however as a projected, non-mosaicked image // uses a Projection internal to the Camera object. Camera *lhCamera = NULL; Camera *rhCamera = NULL; try { lhCamera = lhImage.camera(); rhCamera = rhImage.camera(); } catch (IException &ie) { QString msg = "Both input images must have a camera"; throw IException(ie, IException::User, msg, _FILEINFO_); } // Since we are generating a DEM, we must turn off any existing // DEM that may have been initialized with spiceinit. lhCamera->IgnoreElevationModel(true); rhCamera->IgnoreElevationModel(true); // Get serial number QString serialLeft = SerialNumber::Compose(lhImage, true); QString serialRight = SerialNumber::Compose(rhImage, true); // This still precludes band to band registrations. if (serialLeft == serialRight) { QString sLeft = FileName(lhImage.fileName()).name(); QString sRight = FileName(rhImage.fileName()).name(); if (sLeft == sRight) { QString msg = "Cube Serial Numbers must be unique - FROM=" + serialLeft + ", MATCH=" + serialRight; throw IException(IException::User,msg,_FILEINFO_); } serialLeft = sLeft; serialRight = sRight; } Progress prog; prog.SetText("Finding Initial Seeds"); int nl = lhImage.lineCount(); int ns = lhImage.sampleCount(); BigInt numAttemptedInitialPoints = 0; // Declare Gruen matcher SmtkMatcher matcher(ui.GetFileName("REGDEF"), &lhImage, &rhImage); // Get line/sample linc/sinc parameters int space = ui.GetInteger("SPACE"); int linc (space), sinc(space); // Do we have a seed points from a control net file? bool useseed = ui.WasEntered("CNET"); // Base points on an input cnet SmtkQStack gstack; double lastEigen(0.0); if (useseed) { ControlNet cnet(ui.GetFileName("CNET")); prog.SetMaximumSteps(cnet.GetNumPoints()); prog.CheckStatus(); gstack.reserve(cnet.GetNumPoints()); for (int cpIndex = 0; cpIndex < cnet.GetNumPoints(); cpIndex ++) { ControlPoint *cp = cnet.GetPoint(cpIndex); if (!cp->IsIgnored()) { ControlMeasure *cmLeft(0), *cmRight(0); for(int cmIndex = 0; cmIndex < cp->GetNumMeasures(); cmIndex ++) { ControlMeasure *cm = cp->GetMeasure(cmIndex); if (!cm->IsIgnored()) { if (cm->GetCubeSerialNumber() == serialLeft) cmLeft = cp->GetMeasure(cmIndex); if (cm->GetCubeSerialNumber() == serialRight) cmRight = cp->GetMeasure(cmIndex); } } // If we have both left and right images in the control point, save it if ( (cmLeft != 0) && (cmRight != 0) ) { Coordinate left = Coordinate(cmLeft->GetLine(), cmLeft->GetSample()); Coordinate right = Coordinate(cmRight->GetLine(), cmRight->GetSample()); SmtkPoint spnt = matcher.Create(left, right); // Insert the point (unregistered) if ( spnt.isValid() ) { int line = (int) cmLeft->GetLine(); int samp = (int) cmLeft->GetSample(); matcher.isValid(spnt); gstack.insert(qMakePair(line, samp), spnt); lastEigen = spnt.GoodnessOfFit(); } } } prog.CheckStatus(); } } else { // We want to create a grid of control points that is N rows by M columns. int rows = (lhImage.lineCount() + linc - 1)/linc; int cols = (lhImage.sampleCount() + sinc - 1)/sinc; prog.SetMaximumSteps(rows * cols); prog.CheckStatus(); // First pass stack and eigen value statistics SmtkQStack fpass; fpass.reserve(rows * cols); Statistics temp_mev; // Loop through grid of points and get statistics to compute // initial set of points for (int line = linc / 2 + 1; line < nl; line += linc) { for (int samp = sinc / 2 + 1 ; samp < ns; samp += sinc) { numAttemptedInitialPoints ++; SmtkPoint spnt = matcher.Register(Coordinate(line,samp)); if ( spnt.isValid() ) { matcher.isValid(spnt); fpass.insert(qMakePair(line, samp), spnt); temp_mev.AddData(spnt.GoodnessOfFit()); } prog.CheckStatus(); } } // Now select a subset of fpass points as the seed points cout << "Number of Potential Seed Points: " << fpass.size() << "\n"; cout << "Min / Max Eigenvalues Matched: " << temp_mev.Minimum() << ", " << temp_mev.Maximum() << "\n"; // How many seed points are requested double nseed = ui.GetDouble("NSEED"); int inseed; if (nseed >= 1.0) inseed = (int) nseed; else if (nseed > 0.0) inseed = (int) (nseed * (double) (fpass.size())); else inseed = (int) ((double) (fpass.size()) * 0.05); double seedsample = ui.GetDouble("SEEDSAMPLE"); // Generate a new stack gstack.reserve(inseed); while ((gstack.size() < inseed) && (!fpass.isEmpty() )) { SmtkQStack::iterator bestm; if (seedsample <= 0.0) { bestm = matcher.FindSmallestEV(fpass); } else { bestm = matcher.FindExpDistEV(fpass, seedsample, temp_mev.Minimum(), temp_mev.Maximum()); } // Add point to stack if (bestm != fpass.end()) { Coordinate right = bestm.value().getRight(); matcher.isValid(bestm.value()); gstack.insert(bestm.key(), bestm.value()); lastEigen = bestm.value().GoodnessOfFit(); fpass.erase(bestm); } } // If a user wants to see the seed network, write it out here if (ui.WasEntered("OSEEDNET")) { WriteCnet(ui.GetFileName("OSEEDNET"), gstack, lhCamera->target()->name(), serialLeft, serialRight); } } /////////////////////////////////////////////////////////////////////// // All done with seed points. Sanity check ensures we actually found // some. /////////////////////////////////////////////////////////////////////// if (gstack.size() <= 0) { QString msg = "No seed points found - may need to check Gruen parameters."; throw IException(IException::User, msg, _FILEINFO_); } // Report seed point status if (!useseed) { cout << "Number of Seed Points used: " << gstack.size() << "\n"; cout << "EV of last Seed Point: " << lastEigen << "\n"; } else { cout << "Number of Manual Seed Points: " << gstack.size() << "\n"; } // Use seed points (in stack) to grow SmtkQStack bmf; bmf.reserve(gstack.size()); // Probably need much more but for starters... BigInt numOrigPoints = gstack.size(); BigInt passpix2 = 0; int subcbox = ui.GetInteger("SUBCBOX"); int halfBox((subcbox-1)/2); while (!gstack.isEmpty()) { SmtkQStackIter cstack = matcher.FindSmallestEV(gstack); // Print number on stack if ((gstack.size() % 1000) == 0) { cout << "Number on Stack: " << gstack.size() << ". " << cstack.value().GoodnessOfFit() << "\n"; } // Test to see if already determined SmtkQStackIter bmfPt = bmf.find(cstack.key()); if (bmfPt == bmf.end()) { // Its not in the final stack, process it // Retrieve the point SmtkPoint spnt = cstack.value(); // Register if its not already registered if (!spnt.isRegistered()) { spnt = matcher.Register(spnt, spnt.getAffine()); } // Still must check for validity if the point was just registered, // otherwise should be good if ( spnt.isValid() ) { passpix2++; bmf.insert(cstack.key(), spnt); // inserts (0,0) offset excluded below int line = cstack.key().first; int sample = cstack.key().second; // Determine match points double eigen(spnt.GoodnessOfFit()); for (int sampBox = -halfBox ; sampBox <= halfBox ; sampBox++ ) { int csamp = sample + sampBox; for (int lineBox = -halfBox ; lineBox <= halfBox ; lineBox++) { int cline = line + lineBox; if ( !( (sampBox == 0) && (lineBox == 0)) ) {// Already added above SmtkQPair dupPair(cline, csamp); SmtkQStackIter temp = bmf.find(dupPair); SmtkPoint bmfpnt; if (temp != bmf.end()) { if (temp.value().GoodnessOfFit() > eigen) { // Create cloned point with better fit bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } } else { // ISIS2 is BMF(SAMP,LINE,7) .EQ VALID_MAX4) // Clone new point for insert bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } // Add if good point if (bmfpnt.isValid()) { bmf.insert(dupPair, bmfpnt); } } } } // Grow stack with spacing adding info to stack for (int i = -1 ; i <= 1 ; i ++) { // Sample for (int j = -1 ; j <= 1 ; j ++) { // Line // Don't re-add the original sample, line if ( !((i == 0) && (j == 0)) ) { // Grow based upon spacing double ssamp = sample + (i * space); double sline = line + (j * space); Coordinate pnt = Coordinate(sline, ssamp); SmtkPoint gpnt = matcher.Clone(spnt, pnt); if ( gpnt.isValid() ) { SmtkQPair growpt((int) sline, (int) ssamp); // double check we don't have a finalized result at this position SmtkQStackIter temp = bmf.find(growpt); if(temp == bmf.end()) { gstack.insert(growpt, gpnt); } } } } } } } // Remove the current point from the grow stack (hole) gstack.erase(cstack); } ///////////////////////////////////////////////////////////////////////// // All done with creating points. Perform output options. ///////////////////////////////////////////////////////////////////////// // If a TO parameter was specified, create DEM with errors if (ui.WasEntered("TO")) { // Create the output DEM cout << "\nCreating output DEM from " << bmf.size() << " points.\n"; Process p; Cube *icube = p.SetInputCube("FROM"); Cube *ocube = p.SetOutputCube("TO", icube->sampleCount(), icube->lineCount(), 3); p.ClearInputCubes(); int boxsize = ui.GetInteger("BOXSIZE"); double plotdist = ui.GetDouble("PLOTDIST"); TileManager dem(*ocube), eigen(*ocube), stErr(*ocube); dem.SetTile(1, 1); // DEM Data/elevation stErr.SetTile(1, 2); // Error in stereo computation eigen.SetTile(1, 3); // Eigenvalue of the solution int nBTiles(eigen.Tiles()/3); // Total tiles / 3 bands prog.SetText("Creating DEM"); prog.SetMaximumSteps(nBTiles); prog.CheckStatus(); Statistics stAng; while ( !eigen.end() ) { // Must use the last band for this!! PointPlot tm = for_each(bmf.begin(), bmf.end(), PointPlot(dem, plotdist)); tm.FillPoints(*lhCamera, *rhCamera, boxsize, dem, stErr, eigen, &stAng); ocube->write(dem); ocube->write(stErr); ocube->write(eigen); dem.next(); stErr.next(); eigen.next(); prog.CheckStatus(); } // Report Stereo separation angles PvlGroup stresultsPvl("StereoSeparationAngle"); stresultsPvl += PvlKeyword("Minimum", toString(stAng.Minimum()), "deg"); stresultsPvl += PvlKeyword("Average", toString(stAng.Average()), "deg"); stresultsPvl += PvlKeyword("Maximum", toString(stAng.Maximum()), "deg"); stresultsPvl += PvlKeyword("StandardDeviation", toString(stAng.StandardDeviation()), "deg"); Application::Log(stresultsPvl); // Update the label with BandBin keywords PvlKeyword filter("FilterName", "Elevation", "meters"); filter.addValue("ElevationError", "meters"); filter.addValue("GoodnessOfFit", "unitless"); PvlKeyword center("Center", "1.0"); center.addValue("1.0"); center.addValue("1.0"); PvlGroup &bandbin = ocube->label()->findGroup("BandBin", PvlObject::Traverse); bandbin.addKeyword(filter, PvlContainer::Replace); bandbin.addKeyword(center, PvlContainer::Replace); center.setName("Width"); bandbin.addKeyword(center, PvlContainer::Replace); p.EndProcess(); } // If a cnet file was entered, write the ControlNet pvl to the file if (ui.WasEntered("ONET")) { WriteCnet(ui.GetFileName("ONET"), bmf, lhCamera->target()->name(), serialLeft, serialRight); } // Create output data PvlGroup totalPointsPvl("Totals"); totalPointsPvl += PvlKeyword("AttemptedPoints", toString(numAttemptedInitialPoints)); totalPointsPvl += PvlKeyword("InitialSuccesses", toString(numOrigPoints)); totalPointsPvl += PvlKeyword("GrowSuccesses", toString(passpix2)); totalPointsPvl += PvlKeyword("ResultingPoints", toString(bmf.size())); Application::Log(totalPointsPvl); Pvl arPvl = matcher.RegistrationStatistics(); PvlGroup smtkresultsPvl("SmtkResults"); smtkresultsPvl += PvlKeyword("SpiceOffImage", toString(matcher.OffImageErrorCount())); smtkresultsPvl += PvlKeyword("SpiceDistanceError", toString(matcher.SpiceErrorCount())); arPvl.addGroup(smtkresultsPvl); for(int i = 0; i < arPvl.groups(); i++) { Application::Log(arPvl.group(i)); } // add the auto registration information to print.prt PvlGroup autoRegTemplate = matcher.RegTemplate(); Application::Log(autoRegTemplate); // Don't need the cubes opened anymore lhImage.close(); rhImage.close(); }