void IsisMain() { // We will be processing by line ProcessByBrick p; p.SetBrickSize(1,1,1); p.SetOutputBrickSize(1,1,1); UserInterface &ui = Application::GetUserInterface(); // Basic settings p.SetInputCube("FROM"); p.SetOutputCube("TO"); Pvl pvl = Pvl(ui.GetFilename("PVL")); cube.Open(ui.GetFilename("FROM")); try { // Get info from the operator group // Set the pvlkeywords that need to be set to zero PvlGroup &op = pvl.FindGroup("Operator",Pvl::Traverse); boxcarSamples = op["Samples"]; boxcarLines = op["Lines"]; op["DeltaLine"]=0; op["DeltaSamp"]=0; op["MinimumInterest"]=0.0; Application::Log(op); } catch (iException &e) { std::string msg = "Improper format for InterestOperator PVL ["+pvl.Filename()+"]"; throw iException::Message(iException::User,msg,_FILEINFO_); } iop = InterestOperatorFactory::Create(pvl); // Start the processing p.StartProcess(Operate); p.EndProcess(); }
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(); }
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() { UserInterface &ui = Application::GetUserInterface(); // Get the camera information if this is not a mosaic. Otherwise, get the // projection information Process p1; Cube *icube = p1.SetInputCube("FROM", OneBand); if (ui.GetString("SOURCE") == "CAMERA") { noCamera = false; } else { noCamera = true; } if(noCamera) { try { proj = (TProjection *) icube->projection(); } catch(IException &e) { QString msg = "Mosaic files must contain mapping labels"; throw IException(e, IException::User, msg, _FILEINFO_); } } else { try { cam = icube->camera(); } catch(IException &e) { QString msg = "If " + FileName(ui.GetFileName("FROM")).name() + " is a mosaic, make sure the SOURCE " "option is set to PROJECTION"; throw IException(e, IException::User, msg, _FILEINFO_); } } // We will be processing by brick. ProcessByBrick p; // Find out which bands are to be created nbands = 0; phase = false; emission = false; incidence = false; localEmission = false; localIncidence = false; lineResolution = false; sampleResolution = false; detectorResolution = false; sunAzimuth = false; spacecraftAzimuth = false; offnadirAngle = false; subSpacecraftGroundAzimuth = false; subSolarGroundAzimuth = false; morphology = false; albedo = false; northAzimuth = false; if (!noCamera) { if((phase = ui.GetBoolean("PHASE"))) nbands++; if((emission = ui.GetBoolean("EMISSION"))) nbands++; if((incidence = ui.GetBoolean("INCIDENCE"))) nbands++; if((localEmission = ui.GetBoolean("LOCALEMISSION"))) nbands++; if((localIncidence = ui.GetBoolean("LOCALINCIDENCE"))) nbands++; if((lineResolution = ui.GetBoolean("LINERESOLUTION"))) nbands++; if((sampleResolution = ui.GetBoolean("SAMPLERESOLUTION"))) nbands++; if((detectorResolution = ui.GetBoolean("DETECTORRESOLUTION"))) nbands++; if((sunAzimuth = ui.GetBoolean("SUNAZIMUTH"))) nbands++; if((spacecraftAzimuth = ui.GetBoolean("SPACECRAFTAZIMUTH"))) nbands++; if((offnadirAngle = ui.GetBoolean("OFFNADIRANGLE"))) nbands++; if((subSpacecraftGroundAzimuth = ui.GetBoolean("SUBSPACECRAFTGROUNDAZIMUTH"))) nbands++; if((subSolarGroundAzimuth = ui.GetBoolean("SUBSOLARGROUNDAZIMUTH"))) nbands++; if ((morphology = ui.GetBoolean("MORPHOLOGY"))) nbands++; if ((albedo = ui.GetBoolean("ALBEDO"))) nbands++; if ((northAzimuth = ui.GetBoolean("NORTHAZIMUTH"))) nbands++; } if((dn = ui.GetBoolean("DN"))) nbands++; if((latitude = ui.GetBoolean("LATITUDE"))) nbands++; if((longitude = ui.GetBoolean("LONGITUDE"))) nbands++; if((pixelResolution = ui.GetBoolean("PIXELRESOLUTION"))) nbands++; if(nbands < 1) { QString message = "At least one photometry parameter must be entered" "[PHASE, EMISSION, INCIDENCE, LATITUDE, LONGITUDE...]"; throw IException(IException::User, message, _FILEINFO_); } // If outputting a a dn band, retrieve the orignal values for the filter name from the input cube, // if it exists. Otherwise, the default will be "DN" QString bname = "DN"; if ( dn && icube->hasGroup("BandBin") ) { PvlGroup &mybb = icube->group("BandBin"); if ( mybb.hasKeyword("Name") ) { bname = mybb["Name"][0]; } else if ( mybb.hasKeyword("FilterName") ) { bname = mybb["FilterName"][0]; } } // Create a bandbin group for the output label PvlKeyword name("Name"); if (dn) name += bname; if(phase) name += "Phase Angle"; if(emission) name += "Emission Angle"; if(incidence) name += "Incidence Angle"; if(localEmission) name += "Local Emission Angle"; if(localIncidence) name += "Local Incidence Angle"; if(latitude) name += "Latitude"; if(longitude) name += "Longitude"; if(pixelResolution) name += "Pixel Resolution"; if(lineResolution) name += "Line Resolution"; if(sampleResolution) name += "Sample Resolution"; if(detectorResolution) name += "Detector Resolution"; if(northAzimuth) name += "North Azimuth"; if(sunAzimuth) name += "Sun Azimuth"; if(spacecraftAzimuth) name += "Spacecraft Azimuth"; if(offnadirAngle) name += "OffNadir Angle"; if(subSpacecraftGroundAzimuth) name += "Sub Spacecraft Ground Azimuth"; if(subSolarGroundAzimuth) name += "Sub Solar Ground Azimuth"; if (morphology) name += "Morphology"; if (albedo) name += "Albedo"; // Create the output cube. Note we add the input cube to expedite propagation // of input cube elements (label, blobs, etc...). It will be cleared // prior to systematic processing only if the DN option is not selected. // If DN is chosen by the user, then we propagate the input buffer with a // different function - one that accepts both input and output buffers. (void) p.SetInputCube("FROM", OneBand); Cube *ocube = p.SetOutputCube("TO", icube->sampleCount(), icube->lineCount(), nbands); p.SetBrickSize(64, 64, nbands); if (dn) { // Process with input and output buffers p.StartProcess(phocubeDN); } else { // Toss the input file as stated above p.ClearInputCubes(); // Start the processing p.StartProcess(phocube); } // Add the bandbin group to the output label. If a BandBin group already // exists, remove all existing keywords and add the keywords for this app. // Otherwise, just put the group in. PvlObject &cobj = ocube->label()->findObject("IsisCube"); if(!cobj.hasGroup("BandBin")) { cobj.addGroup(PvlGroup("BandBin")); } PvlGroup &bb = cobj.findGroup("BandBin"); bb.addKeyword(name, PvlContainer::Replace); int nvals = name.size(); UpdateBandKey("Center", bb, nvals, "1.0"); if ( bb.hasKeyword("OriginalBand") ) { UpdateBandKey("OriginalBand", bb, nvals, "1.0"); } if ( bb.hasKeyword("Number") ) { UpdateBandKey("Number", bb, nvals, "1.0"); } UpdateBandKey("Width", bb, nvals, "1.0"); p.EndProcess(); }
void IsisMain() { // Grab the file to import ProcessByBrick p; evenCube = p.SetInputCube("INEVEN"); oddCube = p.SetInputCube("INODD"); outEven = p.SetOutputCube("OUTEVEN"); outOdd = p.SetOutputCube("OUTODD"); UserInterface &ui = Application::GetUserInterface(); // Make sure it is a Themis EDR/RDR try { if(evenCube->group("Instrument")["InstrumentID"][0] != "THEMIS_VIS") { throw IException(IException::User, "", _FILEINFO_); } } catch(IException &) { QString msg = "This program is intended for use on THEMIS VIS images only"; msg += " [" + ui.GetFileName("INEVEN") + "] does not appear to be a "; msg += "THEMIS VIS image."; throw IException(IException::User, msg, _FILEINFO_); } try { if(oddCube->group("Instrument")["InstrumentID"][0] != "THEMIS_VIS") { throw IException(IException::User, "", _FILEINFO_); } } catch(IException &e) { QString msg = "This program is intended for use on THEMIS VIS images only"; msg += " [" + ui.GetFileName("INODD") + "] does not appear to be a "; msg += "THEMIS VIS image."; throw IException(IException::User, msg, _FILEINFO_); } if (evenCube->group("Instrument")["Framelets"][0] != "Even") { QString msg = "The image [" + ui.GetFileName("INEVEN") + "] does not appear " "to contain the EVEN framelets of a Themis VIS cube"; throw IException(IException::User, msg, _FILEINFO_); } if (oddCube->group("Instrument")["Framelets"][0] != "Odd") { QString msg = "The image [" + ui.GetFileName("ODDEVEN") + "] does not appear " "to contain the ODD framelets of a Themis VIS cube"; throw IException(IException::User, msg, _FILEINFO_); } PvlGroup &inputInstrumentGrp = evenCube->group("Instrument"); PvlKeyword &spatialSumming = inputInstrumentGrp["SpatialSumming"]; frameletSize = 192 / toInt(spatialSumming[0]); overlapSize = FrameletOverlapSize(); if(overlapSize == 0) { IString msg = "There must be overlap to remove seams"; throw IException(IException::Unknown, msg, _FILEINFO_); } p.SetBrickSize(evenCube->sampleCount(), frameletSize, 1); p.StartProcess(FixSeams); PvlGroup &evenInst = outEven->group("Instrument"); evenInst["Framelets"] = "Even"; PvlGroup &oddInst = outOdd->group("Instrument"); oddInst["Framelets"] = "Odd"; p.EndProcess(); }
void IsisMain() { ProcessByBrick p; Cube *icube = p.SetInputCube("FROM"); int numDimensions = icube->bandCount(); p.SetBrickSize(128, 128, numDimensions); // The output cube with no attributes and real pixel type Isis::CubeAttributeOutput cao; cao.setPixelType(Isis::Real); p.SetOutputCube(tmpFileName, cao, icube->sampleCount(), icube->lineCount(), icube->bandCount()); // Get the data for the transform matrix pca = Isis::PrincipalComponentAnalysis(numDimensions); ProcessByBrick p2; p2.SetBrickSize(128, 128, numDimensions); p2.SetInputCube("FROM"); p2.Progress()->SetText("Computing Transform"); p2.StartProcess(GetData); p2.EndProcess(); pca.ComputeTransform(); p.Progress()->SetText("Transforming Cube"); p.StartProcess(Transform); p.EndProcess(); Isis::CubeAttributeInput cai; Cube *icube2 = p.SetInputCube(tmpFileName, cai); for(int i = 0; i < numDimensions; i++) { stretches.push_back(new GaussianStretch(*(icube2->histogram(i + 1)))); } p.SetOutputCube("TO"); p.SetBrickSize(128, 128, numDimensions); p.Progress()->SetText("Stretching Cube"); p.StartProcess(NormalizeAndInvert); for(int i = 0; i < numDimensions; i++) delete stretches[i]; stretches.clear(); p.EndProcess(); remove(tmpFileName.toAscii().data()); }
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); }
/** * This is the main method. Makeflat runs in three steps: * * 1) Calculate statistics * - For all cameras, this checks for one band and matching * sample counts. * - For framing cameras, this checks the standard deviation of * the images and records the averages of each image * - For push frame cameras, this calls CheckFramelets for each * image. * * 2) Create the temporary file, collect more detailed statistics * - For all cameras, this generates the temporary file and calculates * the final exclusion list * - For framing/push frame cameras, the temporary file is * 2 bands, where the first is a sum of DNs from each image/framelet * and the second band is a count of valid DNs that went into each sum * * 3) Create the final flat field file * - For all cameras, this processes the temporary file to create the final flat * field file. */ void IsisMain() { // Initialize variables ResetGlobals(); UserInterface &ui = Application::GetUserInterface(); maxStdev = ui.GetDouble("STDEVTOL"); if(ui.GetString("IMAGETYPE") == "FRAMING") { cameraType = Framing; // framing cameras need to figure this out automatically // during step 1 numFrameLines = -1; } else if(ui.GetString("IMAGETYPE") == "LINESCAN") { cameraType = LineScan; numFrameLines = ui.GetInteger("NUMLINES"); } else { cameraType = PushFrame; numFrameLines = ui.GetInteger("FRAMELETHEIGHT"); } FileList inList(ui.GetFilename("FROMLIST")); Progress progress; tempFileLength = 0; numOutputSamples = 0; /** * Line scan progress is based on the input list, whereas * the other cameras take much longer and are based on the * images themselves. Prepare the progress if we're doing * line scan. */ if(cameraType == LineScan) { progress.SetText("Calculating Number of Image Lines"); progress.SetMaximumSteps(inList.size()); progress.CheckStatus(); } /** * For a push frame camera, the temp file is one framelet. * Technically this is the same for the framing, but we * don't know the height of a framelet yet. */ if(cameraType == PushFrame) { tempFileLength = numFrameLines; } /** * Start pass 1, use global currImage so that methods called * know the image we're processing. */ for(currImage = 0; currImage < inList.size(); currImage++) { /** * Read the current cube into memory */ Cube tmp; tmp.Open(Filename(inList[currImage]).Expanded()); /** * If we haven't determined how many samples the output * should have, we can do so now */ if(numOutputSamples == 0 && tmp.Bands() == 1) { numOutputSamples = tmp.Samples(); } /** * Try and validate the image, quick tests first! * * (imageValid &= means imageValid = imageValid && ...) */ bool imageValid = true; // Only single band images are acceptable imageValid &= (tmp.Bands() == 1); // Sample sizes must always match imageValid &= (numOutputSamples == tmp.Samples()); // For push frame cameras, there must be valid all framelets if(cameraType == PushFrame) { imageValid &= (tmp.Lines() % numFrameLines == 0); } // For framing cameras, we need to figure out the size... // setTempFileLength is used to revert if the file // is decided to be invalid bool setTempFileLength = false; if(cameraType == Framing) { if(tempFileLength == 0 && imageValid) { tempFileLength = tmp.Lines(); numFrameLines = tempFileLength; setTempFileLength = true; } imageValid &= (tempFileLength == tmp.Lines()); } // Statistics are necessary at this point for push frame and framing cameras // because the framing camera standard deviation tolerance is based on // entire images, and push frame framelet exclusion stats can not be collected // during pass 2 cleanly if((cameraType == Framing || cameraType == PushFrame) && imageValid) { string prog = "Calculating Standard Deviation " + iString((int)currImage+1) + "/"; prog += iString((int)inList.size()) + " (" + Filename(inList[currImage]).Name() + ")"; if(cameraType == Framing) { Statistics *stats = tmp.Statistics(1, prog); imageValid &= !IsSpecial(stats->StandardDeviation()); imageValid &= !IsSpecial(stats->Average()); imageValid &= stats->StandardDeviation() <= maxStdev; vector<double> fileStats; fileStats.push_back(stats->Average()); inputFrameletAverages.push_back(fileStats); delete stats; } else if(cameraType == PushFrame) { imageValid &= CheckFramelets(prog, tmp); } if(setTempFileLength && !imageValid) { tempFileLength = 0; } } // The line scan camera needs to actually count the number of lines in each image to know // how many total frames there are before beginning pass 2. if(imageValid && (cameraType == LineScan)) { int lines = (tmp.Lines() / numFrameLines); // partial frame? if(tmp.Lines() % numFrameLines != 0) { lines ++; } tempFileLength += lines; } else if(!imageValid) { excludedFiles.insert(pair<int, bool>(currImage, true)); } tmp.Close(); if(cameraType == LineScan) { progress.CheckStatus(); } } /** * If the number of output samples could not be determined, we never * found a legitimate cube. */ if(numOutputSamples <= 0) { string msg = "No valid input cubes were found"; throw iException::Message(iException::User,msg,_FILEINFO_); } /** * If theres no temp file length, which is based off of valid data in * the input cubes, then we havent found any valid data. */ if(tempFileLength <= 0) { string msg = "No valid input data was found"; throw iException::Message(iException::User,msg,_FILEINFO_); } /** * ocube is now the temporary file (for pass 2). */ ocube = new Cube(); ocube->SetDimensions(numOutputSamples, tempFileLength, 2); PvlGroup &prefs = Preference::Preferences().FindGroup("DataDirectory", Pvl::Traverse); iString outTmpName = (string)prefs["Temporary"][0] + "/"; outTmpName += Filename(ui.GetFilename("TO")).Basename() + ".tmp.cub"; ocube->Create(outTmpName); oLineMgr = new LineManager(*ocube); oLineMgr->SetLine(1); ProcessByBrick p; int excludedCnt = 0; if(cameraType == LineScan) { outputTmpAverages.resize(numOutputSamples); outputTmpCounts.resize(numOutputSamples); numInputDns.resize(numOutputSamples); } cubeInitialized = false; for(currImage = 0; currImage < inList.size(); currImage++) { if(Excluded(currImage)) { excludedCnt ++; continue; } PvlObject currFile("Exclusions"); currFile += PvlKeyword("Filename", inList[currImage]); currFile += PvlKeyword("Tolerance", maxStdev); if(cameraType == LineScan) { currFile += PvlKeyword("FrameLines", numFrameLines); } else if(cameraType == PushFrame) { currFile += PvlKeyword("FrameletLines", numFrameLines); } excludedDetails.push_back(currFile); CubeAttributeInput inAtt; // This needs to be set constantly because ClearInputCubes // seems to be removing the input brick size. if(cameraType == LineScan) { p.SetBrickSize(1, numFrameLines, 1); } else if(cameraType == Framing || cameraType == PushFrame) { p.SetBrickSize(numOutputSamples, 1, 1); } p.SetInputCube(inList[currImage], inAtt); iString progText = "Calculating Averages " + iString((int)currImage+1); progText += "/" + iString((int)inList.size()); progText += " (" + Filename(inList[currImage]).Name() + ")"; p.Progress()->SetText(progText); p.StartProcess(CreateTemporaryData); p.EndProcess(); p.ClearInputCubes(); if(excludedDetails[excludedDetails.size()-1].Groups() == 0) { excludedDetails.resize(excludedDetails.size()-1); } } /** * Pass 2 completed. The processing methods were responsible for writing * the entire temporary cube. */ if(oLineMgr) { delete oLineMgr; oLineMgr = NULL; } if(ocube) { ocube->Close(); delete ocube; } /** * ocube is now the final output */ ocube = new Cube(); if(cameraType == LineScan) { ocube->SetDimensions(numOutputSamples, 1, 1); } else if(cameraType == Framing || cameraType == PushFrame) { ocube->SetDimensions(numOutputSamples, tempFileLength, 1); } ocube->Create(Filename(ui.GetFilename("TO")).Expanded()); oLineMgr = new LineManager(*ocube); oLineMgr->SetLine(1); // We now have the necessary temp file, let's go ahead and combine it into // the final output! p.SetInputBrickSize(numOutputSamples, 1, 2); p.SetOutputBrickSize(numOutputSamples, 1, 1); cubeInitialized = false; CubeAttributeInput inAtt; p.Progress()->SetText("Calculating Final Flat Field"); p.SetInputCube(outTmpName, inAtt); p.StartProcess(ProcessTemporaryData); p.EndProcess(); if(cameraType == LineScan) { ocube->Write(*oLineMgr); } if(oLineMgr) { delete oLineMgr; oLineMgr = NULL; } if(ocube) { ocube->Close(); delete ocube; ocube = NULL; } /** * Build a list of excluded files */ PvlGroup excludedFiles("ExcludedFiles"); for(currImage = 0; currImage < inList.size(); currImage++) { if(Excluded(currImage)) { excludedFiles += PvlKeyword("File", inList[currImage]); } } // log the results Application::Log(excludedFiles); if(ui.WasEntered("EXCLUDE")) { Pvl excludeFile; // Find excluded files excludeFile.AddGroup(excludedFiles); for(unsigned int i = 0; i < excludedDetails.size(); i++) { excludeFile.AddObject(excludedDetails[i]); } excludeFile.Write(Filename(ui.GetFilename("EXCLUDE")).Expanded()); } remove(outTmpName.c_str()); // Clean up settings ResetGlobals(); }
void IsisMain() { // Get the camera information Process p1; Cube *icube = p1.SetInputCube("FROM",OneBand); cam = icube->Camera(); // We will be processing by brick. ProcessByBrick p; // Find out which bands are to be created UserInterface &ui = Application::GetUserInterface(); nbands = 0; if ((phase = ui.GetBoolean("PHASE"))) nbands++; if ((emission = ui.GetBoolean("EMISSION"))) nbands++; if ((incidence = ui.GetBoolean("INCIDENCE"))) nbands++; if ((latitude = ui.GetBoolean("LATITUDE"))) nbands++; if ((longitude = ui.GetBoolean("LONGITUDE"))) nbands++; if ((pixelResolution = ui.GetBoolean("PIXELRESOLUTION"))) nbands++; if ((lineResolution = ui.GetBoolean("LINERESOLUTION"))) nbands++; if ((sampleResolution = ui.GetBoolean("SAMPLERESOLUTION"))) nbands++; if ((detectorResolution = ui.GetBoolean("DETECTORRESOLUTION"))) nbands++; if ((northAzimuth = ui.GetBoolean("NORTHAZIMUTH"))) nbands++; if ((sunAzimuth = ui.GetBoolean("SUNAZIMUTH"))) nbands++; if ((spacecraftAzimuth = ui.GetBoolean("SPACECRAFTAZIMUTH"))) nbands++; if ((offnadirAngle = ui.GetBoolean("OFFNADIRANGLE"))) nbands++; if (nbands < 1) { string message = "At least one photometry parameter must be entered" "[PHASE, EMISSION, INCIDENCE, LATITUDE, LONGITUDE]"; throw iException::Message (iException::User, message, _FILEINFO_); } // Create a bandbin group for the output label PvlKeyword name("Name"); if (phase) name += "Phase Angle"; if (emission) name += "Emission Angle"; if (incidence) name += "Incidence Angle"; if (latitude) name += "Latitude"; if (longitude) name += "Longitude"; if (pixelResolution) name += "Pixel Resolution"; if (lineResolution) name += "Line Resolution"; if (sampleResolution) name += "Sample Resolution"; if (detectorResolution) name += "Detector Resolution"; if (northAzimuth) name += "North Azimuth"; if (sunAzimuth) name += "Sun Azimuth"; if (spacecraftAzimuth) name += "Spacecraft Azimuth"; if (offnadirAngle) name += "OffNadir Angle"; PvlGroup bandBin("BandBin"); bandBin += name; // Create the output cube. Note we add the input cube to expedite propagation // of input cube elements (label, blobs, etc...). It *must* be cleared // prior to systematic processing. (void) p.SetInputCube("FROM", OneBand); Cube *ocube = p.SetOutputCube("TO",icube->Samples(), icube->Lines(), nbands); p.SetBrickSize(64,64,nbands); p.ClearInputCubes(); // Toss the input file as stated above // Start the processing p.StartProcess(phocube); // Add the bandbin group to the output label. If a BandBin group already // exists, remove all existing keywords and add the keywords for this app. // Otherwise, just put the group in. PvlObject &cobj = ocube->Label()->FindObject("IsisCube"); if (cobj.HasGroup("BandBin")) { PvlGroup &bb = cobj.FindGroup("BandBin"); bb.Clear(); PvlContainer::PvlKeywordIterator k = bandBin.Begin(); while (k != bandBin.End()) { bb += *k; ++k; } } else { ocube->PutGroup(bandBin); } p.EndProcess(); }