void MiCalibration::ReadLabels(Cube &image){ PvlGroup labelgrp = image.Label()->FindGroup("Instrument",Pvl::Traverse); p_exposureDuration = labelgrp["ExposureDuration"]; p_instrumentSerialNumber = labelgrp["InstrumentSerialNumber"]; p_CCDTemperature = labelgrp["InstrumentTemperature"][6]; p_PCBTemperature = labelgrp["InstrumentTemperature"][7]; p_OffsetModeId = labelgrp["OffsetModeID"]; p_shuttereffectcorrectionflag = (string)labelgrp["ShutterEffectCorrectionFlag"]; p_filterName = (string)labelgrp["FilterName"]; p_startTime = (string)labelgrp["StartTime"]; }
/** * Removes control points not in the lat/lon range provided in the unput * parameters. * * @param outNet The output control net being removed from * @param noLanLonPoint The keyword recording all of the control points removed * due to the provided lat/lon range * @param noLanLonPoint The keyword recording all of the control points removed * due to the inability to calculate the lat/lon for that * point */ void ExtractLatLonRange( ControlNet & outNet, PvlKeyword & nonLatLonPoints, PvlKeyword & cannotGenerateLatLonPoints, map<iString,iString> sn2filename ) { if( outNet.Size() == 0 ) { return; } UserInterface &ui = Application::GetUserInterface(); // Get the lat/lon and fix the range for the internal 0/360 double minlat = ui.GetDouble("MINLAT"); double maxlat = ui.GetDouble("MAXLAT"); double minlon = ui.GetDouble("MINLON"); if( minlon < 0.0 ) { minlon += 360; } double maxlon = ui.GetDouble("MAXLON"); if( maxlon < 0.0 ) { minlon += 360; } bool useNetwork = ui.GetBoolean("USENETWORK"); Progress progress; progress.SetText("Calculating lat/lon"); progress.SetMaximumSteps(outNet.Size()); progress.CheckStatus(); CubeManager manager; manager.SetNumOpenCubes( 50 ); //Should keep memory usage to around 1GB for( int cp = outNet.Size()-1; cp >= 0; cp --) { progress.CheckStatus(); // If the Contorl Network takes priority, use it double pointLat = outNet[cp].UniversalLatitude(); double pointLon = outNet[cp].UniversalLongitude(); bool useControlNet = useNetwork && pointLat > -1000 && pointLon > -1000; if( outNet[cp].Type() == Isis::ControlPoint::Ground || useControlNet ) { if( NotInLatLonRange( outNet[cp].UniversalLatitude(), outNet[cp].UniversalLongitude(), minlat, maxlat, minlon, maxlon ) ) { nonLatLonPoints += outNet[cp].Id(); outNet.Delete( cp ); } } /** * If the lat/lon cannot be determined from the point, then we need to calculate * lat/lon on our own */ else if( ui.WasEntered("FROMLIST") ) { // Find a cube in the Control Point to get the lat/lon from int cm = 0; iString sn = ""; double lat = 0.0; double lon = 0.0; double radius = 0.0; // First check the reference Measure if( outNet[cp].HasReference() ) { cm = outNet[cp].ReferenceIndex(); if( !sn2filename[outNet[cp][cm].CubeSerialNumber()].empty() ) { sn = outNet[cp][cm].CubeSerialNumber(); } } // Search for other Control Measures if needed if( sn.empty() ) { // Find the Serial Number if it exists for( int cm = 0; (cm < outNet[cp].Size()) && sn.empty(); cm ++ ) { if( !sn2filename[outNet[cp][cm].CubeSerialNumber()].empty() ) { sn = outNet[cp][cm].CubeSerialNumber(); } } } // Connot fine a cube to get the lat/lon from if( sn.empty() ) { cannotGenerateLatLonPoints += outNet[cp].Id(); outNet.Delete( cp ); } // Calculate the lat/lon and check for validity else { bool remove = false; Cube *cube = manager.OpenCube( sn2filename[sn] ); Camera *camera = cube->Camera(); if (camera == NULL) { try { Projection *projection = ProjectionFactory::Create( (*(cube->Label())) ); if(!projection->SetCoordinate(outNet[cp][cm].Sample(),outNet[cp][cm].Line())) { nonLatLonPoints += outNet[cp].Id(); remove = true; } lat = projection->Latitude(); lon = projection->Longitude(); radius = projection->LocalRadius(); delete projection; projection = NULL; } catch ( iException &e ) { remove = true; e.Clear(); } } else { if(!camera->SetImage(outNet[cp][cm].Sample(),outNet[cp][cm].Line())) { nonLatLonPoints += outNet[cp].Id(); remove = true; } lat = camera->UniversalLatitude(); lon = camera->UniversalLongitude(); radius = camera->LocalRadius(); camera = NULL; } cube = NULL; if( remove || NotInLatLonRange( lat, lon, minlat, maxlat, minlon, maxlon ) ) { nonLatLonPoints += outNet[cp].Id(); outNet.Delete( cp ); } else { // Add the reference lat/lon/radius to the Control Point outNet[cp].SetUniversalGround( lat, lon, radius ); } } } else { cannotGenerateLatLonPoints += outNet[cp].Id(); outNet.Delete( cp ); } } manager.CleanCubes(); }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); string from = ui.GetFilename("FROM"); // Setup to read headers/labels ifstream input; input.open(from.c_str(), ios::in | ios::binary); // Check stream open status if (!input.is_open()) { string msg = "Cannot open input file [" + from + "]"; throw Isis::iException::Message(Isis::iException::Io, msg, _FILEINFO_); } char reading[81]; iString line = ""; unsigned int place = 0; PvlGroup labels("OriginalLabels"); // Load first line input.seekg(0); input.read(reading, 80); reading[80] = '\0'; line = reading; place += 80; // Read in and place in PvlKeywords and a PvlGroup while (line.substr(0,3) != "END") { // Check for blank lines if (line.substr(0,1) != " " && line.substr(0,1) != "/") { // Name of keyword PvlKeyword label(line.Token(" =")); // Remove up to beginning of data line.TrimHead(" ='"); line.TrimTail(" "); if (label.Name() == "COMMENT" || label.Name() == "HISTORY") { label += line; } else { // Access the data without the comment if there is one iString value = line.Token("/"); // Clear to end of data, including single quotes value.TrimTail(" '"); label += value; line.TrimHead(" "); // If the remaining line string has anything, it is comments. if (line.size() > 0) { label.AddComment(line); // A possible format for units, other possiblites exist. if (line != line.Token("[")) { label.SetUnits(line.Token("[").Token("]")); } } } labels += label; } // Load next line input.seekg(place); input.read(reading, 80); reading[80] = '\0'; place += 80; line = reading; } // Done with stream input.close(); // Its possible they could have this instead of T, in which case we won't even try if (labels["SIMPLE"][0] == "F") { string msg = "The file [" + ui.GetFilename("FROM") + "] does not conform to the FITS standards"; throw iException::Message(iException::User, msg, _FILEINFO_); } ProcessImport pfits; pfits.SetInputFile(ui.GetFilename("FROM")); // Header size will be a multiple of 2880 int multiple = (int)((place + 2881)/2880); pfits.SetFileHeaderBytes(multiple * 2880); pfits.SaveFileHeader(); // Find pixel type, there are several unsupported possiblites Isis::PixelType type; string msg = ""; switch (labels["BITPIX"][0].ToInteger()) { case 8: type = Isis::UnsignedByte; break; case 16: type = Isis::SignedWord; break; case 32: msg = "Signed 32 bit integer (int) pixel type is not supported at this time"; throw iException::Message(iException::User, msg, _FILEINFO_); break; case 64: msg = "Signed 64 bit integer (long) pixel type is not supported at this time"; throw iException::Message(iException::User, msg, _FILEINFO_); break; case -32: type = Isis::Real; break; case -64: msg = "64 bit floating point (double) pixel type is not supported at this time"; throw iException::Message(iException::User, msg, _FILEINFO_); break; default: msg = "Unknown pixel type [" + labels["BITPIX"][0] + "] cannot be imported"; throw iException::Message(iException::User, msg, _FILEINFO_); break; } pfits.SetPixelType(type); // It is possible to have a NAXIS value of 0 meaning no data, the file could include // xtensions with data, however, those aren't supported as of Oct '09 if (labels["NAXIS"][0].ToInteger() == 2) { pfits.SetDimensions(labels["NAXIS1"][0], labels["NAXIS2"][0], 1); } else if (labels["NAXIS"][0].ToInteger() == 3) { pfits.SetDimensions(labels["NAXIS1"][0], labels["NAXIS2"][0], labels["NAXIS3"][0]); } else { string msg = "NAXIS count of [" + labels["NAXIS"][0] + "] is not supported at this time"; throw iException::Message(iException::User, msg, _FILEINFO_); } // Base and multiplier if (labels.HasKeyword("BZERO")) { pfits.SetBase(labels["BZERO"][0]); } if (labels.HasKeyword("BSCALE")) { pfits.SetMultiplier(labels["BSCALE"][0]); } // Byte order pfits.SetByteOrder(Isis::Msb); // Limited section of standardized keywords that could exist bool instGrp = false; PvlGroup inst("Instrument"); if (labels.HasKeyword("DATE-OBS")) { instGrp = true; inst += PvlKeyword("StartTime", labels["DATE-OBS"][0]); } if (labels.HasKeyword("OBJECT")) { instGrp = true; inst += PvlKeyword("Target", labels["OBJECT"][0]); } if (labels.HasKeyword("INSTRUME")) { instGrp = true; inst += PvlKeyword("InstrumentId", labels["INSTRUME"][0]); } if (labels.HasKeyword("OBSERVER")) { instGrp = true; inst += PvlKeyword("SpacecraftName", labels["OBSERVER"][0]); } Cube * output = pfits.SetOutputCube("TO"); // Add instrument group if any relevant data exists Pvl * lbls = output->Label(); if (instGrp) { lbls->FindObject("IsisCube") += inst; } // Save original labels Pvl pvl; pvl += labels; OriginalLabel originals(pvl); output->Write(originals); // Process... pfits.StartProcess(); pfits.EndProcess(); }
// Main program void IsisMain(){ // Create an object for exporting Isis data ProcessExport p; // Open the input cube Cube *icube = p.SetInputCube("FROM"); // Conform to the Big-Endian format for FITS if(IsLsb()) p.SetOutputEndian(Isis::Msb); // Generate the name of the fits file and open it UserInterface &ui = Application::GetUserInterface(); // specify the bits per pixel string bitpix; if (ui.GetString ("BITTYPE") == "8BIT") bitpix = "8"; else if (ui.GetString ("BITTYPE") == "16BIT") bitpix = "16"; else if (ui.GetString ("BITTYPE") == "32BIT") bitpix = "-32"; else { string msg = "Pixel type of [" + ui.GetString("BITTYPE") + "] is unsupported"; throw iException::Message(iException::User, msg, _FILEINFO_); } // Determine bit size and calculate number of bytes to write // for each line. if (bitpix == "8") p.SetOutputType(Isis::UnsignedByte); if (bitpix == "16") p.SetOutputType(Isis::SignedWord); if (bitpix == "-32") p.SetOutputType(Isis::Real); // determine core base and multiplier, set up the stretch PvlGroup pix = icube->Label()->FindObject("IsisCube").FindObject("Core").FindGroup("Pixels"); double scale = pix["Multiplier"][0].ToDouble(); double base = pix["Base"][0].ToDouble(); if (ui.GetString("STRETCH") != "NONE" && bitpix != "-32") { if (ui.GetString("STRETCH") == "LINEAR") { p.SetInputRange(); } else if (ui.GetString("STRETCH") == "MANUAL") { p.SetInputRange(ui.GetDouble("MINIMUM"), ui.GetDouble("MAXIMUM")); } // create a proper scale so pixels look like 32bit data. scale = ((p.GetInputMaximum() - p.GetInputMinimum()) * (p.GetOutputMaximum() - p.GetOutputMinimum())); // round off after 14 decimals to avoid system architecture differences scale = ((floor(scale * 1e14)) / 1e14); // create a proper zero point so pixels look like 32bit data. base = -1.0 * (scale * p.GetOutputMinimum()) + p.GetInputMinimum(); // round off after 14 decimals to avoid system architecture differences base = ((floor(base * 1e14)) / 1e14); } ////////////////////////////////////////// // Write the minimal fits header // ////////////////////////////////////////// string header; // specify that this file conforms to simple fits standard header += FitsKeyword("SIMPLE", true, "T"); // specify the bits per pixel header += FitsKeyword("BITPIX", true, bitpix); // specify the number of data axes (2: samples by lines) int axes = 2; if (icube->Bands() > 1) { axes = 3; } header += FitsKeyword("NAXIS", true, iString(axes)); // specify the limit on data axis 1 (number of samples) header += FitsKeyword("NAXIS1", true, iString(icube->Samples())); // specify the limit on data axis 2 (number of lines) header += FitsKeyword("NAXIS2", true, iString(icube->Lines())); if (axes == 3){ header += FitsKeyword("NAXIS3", true, iString(icube->Bands())); } header += FitsKeyword("BZERO", true, base); header += FitsKeyword("BSCALE", true, scale); // Sky and All cases if (ui.GetString("INFO") == "SKY" || ui.GetString("INFO") == "ALL") { iString msg = "cube has not been skymapped"; PvlGroup map; if (icube->HasGroup("mapping")) { map = icube->GetGroup("mapping"); msg = (string)map["targetname"]; } // If we have sky we want it if (msg == "Sky") { double midRa = 0, midDec = 0; midRa = ((double)map["MaximumLongitude"] + (double)map["MinimumLongitude"])/2; midDec = ((double)map["MaximumLatitude"] + (double)map["MinimumLatitude"])/2; header += FitsKeyword("OBJCTRA", true, iString(midRa)); // Specify the Declination header += FitsKeyword("OBJCTDEC", true, iString(midDec)); } if (ui.GetString("INFO") == "ALL") { header += WritePvl("INSTRUME","Instrument","InstrumentId", icube, true); header += WritePvl("OBSERVER","Instrument","SpacecraftName", icube, true); header += WritePvl("OBJECT ","Instrument","TargetName", icube, true); // StartTime is sometimes middle of the exposure and somtimes beginning, // so StopTime can't be calculated off of exposure reliably. header += WritePvl("DATE-OBS","Instrument","StartTime", icube, true); // Some cameras don't have StopTime if (icube->HasGroup("Instrument")) { PvlGroup inst = icube->GetGroup("Instrument"); if (inst.HasKeyword("StopTime")) { header += WritePvl("TIME_END","Instrument","StopTime", icube, true); } if (inst.HasKeyword("ExposureDuration")) { header += WritePvl("EXPTIME","Instrument","ExposureDuration", icube, false); } } } // If we were set on SKY and Sky doesn't exist else if (msg != "Sky") { throw iException::Message(iException::User,msg,_FILEINFO_); } } // signal the end of the header header += FitsKeyword("END", false, ""); // fill the rest of the fits header with space so to conform with the fits header // size of 2880 bytes for (int i = header.length() % 2880 ; i < 2880 ; i++) header += " "; // open the cube for writing string to = ui.GetFilename("TO","fits"); ofstream fout; fout.open (to.c_str (), ios::out|ios::binary); if (!fout.is_open ()) { string msg = "Cannot open fits output file"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } fout.seekp(0); fout.write(header.c_str(),header.length()); // write the raw cube data p.StartProcess (fout); // Finish off data area to a number n % 2880 == 0 is true // 2880 is the size of the data blocks int count = 2880 - (fout.tellp() % 2880); for (int i = 0; i < count; i++) { // Write nul characters as needed. ascii 0, hex 00... fout.write("\0", 1); } fout.close(); p.EndProcess(); }
void IsisMain() { // Open the input cube Process p; UserInterface &ui = Application::GetUserInterface(); CubeAttributeInput cai; Cube *icube = p.SetInputCube(ui.GetFilename("FROM"), cai, ReadWrite); // Make sure at least one CK & SPK quality was selected if (!ui.GetBoolean("CKPREDICTED") && !ui.GetBoolean("CKRECON") && !ui.GetBoolean("CKSMITHED") && !ui.GetBoolean("CKNADIR")) { string msg = "At least one CK quality must be selected"; throw iException::Message(iException::User,msg,_FILEINFO_); } if (!ui.GetBoolean("SPKPREDICTED") && !ui.GetBoolean("SPKRECON") && !ui.GetBoolean("SPKSMITHED")) { string msg = "At least one SPK quality must be selected"; throw iException::Message(iException::User,msg,_FILEINFO_); } // Make sure it is not projected Projection *proj = NULL; try { proj = icube->Projection(); } catch (iException &e) { proj = NULL; e.Clear(); } if (proj != NULL) { string msg = "Can not initialize SPICE for a map projected cube"; throw iException::Message(iException::User,msg,_FILEINFO_); } Pvl lab = *icube->Label(); // if cube has existing polygon delete it if (icube->Label()->HasObject("Polygon")) { icube->Label()->DeleteObject("Polygon"); } // Set up for getting the mission name // Get the directory where the system missions translation table is. string transFile = p.MissionData("base", "translations/MissionName2DataDir.trn"); // Get the mission translation manager ready PvlTranslationManager missionXlater (lab, transFile); // Get the mission name so we can search the correct DB's for kernels string mission = missionXlater.Translate ("MissionName"); // Get system base kernels unsigned int allowed = 0; unsigned int allowedCK = 0; unsigned int allowedSPK = 0; if (ui.GetBoolean("CKPREDICTED")) allowedCK |= spiceInit::kernelTypeEnum("PREDICTED"); if (ui.GetBoolean("CKRECON")) allowedCK |= spiceInit::kernelTypeEnum("RECONSTRUCTED"); if (ui.GetBoolean("CKSMITHED")) allowedCK |= spiceInit::kernelTypeEnum("SMITHED"); if (ui.GetBoolean("CKNADIR")) allowedCK |= spiceInit::kernelTypeEnum("NADIR"); if (ui.GetBoolean("SPKPREDICTED")) allowedSPK |= spiceInit::kernelTypeEnum("PREDICTED"); if (ui.GetBoolean("SPKRECON")) allowedSPK |= spiceInit::kernelTypeEnum("RECONSTRUCTED"); if (ui.GetBoolean("SPKSMITHED")) allowedSPK |= spiceInit::kernelTypeEnum("SMITHED"); KernelDb baseKernels (allowed); KernelDb ckKernels (allowedCK); KernelDb spkKernels (allowedSPK); baseKernels.LoadSystemDb(mission); ckKernels.LoadSystemDb(mission); spkKernels.LoadSystemDb(mission); Kernel lk, pck, targetSpk, fk, ik, sclk, spk, iak, dem, exk; std::priority_queue< Kernel > ck; lk = baseKernels.LeapSecond(lab); pck = baseKernels.TargetAttitudeShape(lab); targetSpk = baseKernels.TargetPosition(lab); ik = baseKernels.Instrument(lab); sclk = baseKernels.SpacecraftClock(lab); iak = baseKernels.InstrumentAddendum(lab); fk = ckKernels.Frame(lab); ck = ckKernels.SpacecraftPointing(lab); spk = spkKernels.SpacecraftPosition(lab); if (ui.GetBoolean("CKNADIR")) { // Only add nadir if no spacecraft pointing found std::vector<std::string> kernels; kernels.push_back("Nadir"); ck.push(Kernel((spiceInit::kernelTypes)0, kernels)); } // Get user defined kernels and override ones already found GetUserEnteredKernel("LS", lk); GetUserEnteredKernel("PCK", pck); GetUserEnteredKernel("TSPK", targetSpk); GetUserEnteredKernel("FK", fk); GetUserEnteredKernel("IK", ik); GetUserEnteredKernel("SCLK", sclk); GetUserEnteredKernel("SPK", spk); GetUserEnteredKernel("IAK", iak); GetUserEnteredKernel("EXTRA", exk); // Get shape kernel if (ui.GetString ("SHAPE") == "USER") { GetUserEnteredKernel("MODEL", dem); } else if (ui.GetString("SHAPE") == "SYSTEM") { dem = baseKernels.Dem(lab); } bool kernelSuccess = false; if (ck.size() == 0 && !ui.WasEntered("CK")) { throw iException::Message(iException::Camera, "No Camera Kernel found for the image ["+ui.GetFilename("FROM") +"]", _FILEINFO_); } else if(ui.WasEntered("CK")) { // ck needs to be array size 1 and empty kernel objects while(ck.size()) ck.pop(); ck.push(Kernel()); } while(ck.size() != 0 && !kernelSuccess) { Kernel realCkKernel = ck.top(); ck.pop(); if (ui.WasEntered("CK")) { ui.GetAsString("CK", realCkKernel.kernels); } // Merge SpacecraftPointing and Frame into ck for (int i = 0; i < fk.size(); i++) { realCkKernel.push_back(fk[i]); } kernelSuccess = TryKernels(icube, p, lk, pck, targetSpk, realCkKernel, fk, ik, sclk, spk, iak, dem, exk); } if(!kernelSuccess) { throw iException::Message(iException::Camera, "Unable to initialize camera model", _FILEINFO_); } p.EndProcess(); }
void IsisMain(){ const std::string hical_program = "hicalbeta"; const std::string hical_version = "3.5"; const std::string hical_revision = "$Revision: 1.14 $"; const std::string hical_runtime = Application::DateTime(); UserInterface &ui = Application::GetUserInterface(); string 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->Samples(); int nlines = hifrom->Lines(); // Initialize the configuration file string 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 string 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); //////////////////////////////////////////////////////////////////////////// // FixGaps (Z_f) Get buffer pixels and compute coefficients for equation // y = a[0] + a[1]*x + a[2] * exp(a[3] * x) // where y is the average of the buffer pixel region, // and x is the time at each line in electrons/sec/pixel procStep = "Zf module"; hiconf.selectProfile("Zf"); hiprof = hiconf.getMatrixProfile(); HiHistory ZfHist; ZfHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { DriftBuffer driftB(caldata, hiconf); calVars->add("Zf", driftB.ref()); ZfHist = driftB.History(); if ( hiprof.exists("DumpModuleFile") ) { driftB.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { // NOT RECOMMENDED! This is required for the next step! // SURELY must be skipped with Z_d step as well! calVars->add("Zf", HiVector(nlines, 0.0)); ZfHist.add("Debug::SkipModule invoked!"); } ///////////////////////////////////////////////////////////////////// // DriftCorrect (Z_d) // Now compute the equation of fit // procStep = "Zd module"; HiHistory ZdHist; hiconf.selectProfile("Zd"); hiprof = hiconf.getMatrixProfile(); ZdHist.add("Profile["+ hiprof.Name()+"]"); if (!SkipModule(hiconf.getMatrixProfile("Zd")) ) { DriftCorrect driftC(hiconf); calVars->add("Zd", driftC.Normalize(driftC.Solve(calVars->get("Zf")))); ZdHist = driftC.History(); if ( hiprof.exists("DumpModuleFile") ) { driftC.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zd", HiVector(nlines, 0.0)); ZdHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // ZeroCorrect (Z_z) Get reverse clock procStep = "Zz module"; hiconf.selectProfile("Zz"); hiprof = hiconf.getMatrixProfile(); HiHistory ZzHist; ZzHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { OffsetCorrect zoff(caldata, hiconf); calVars->add("Zz", zoff.ref()); ZzHist = zoff.History(); if ( hiprof.exists("DumpModuleFile") ) { zoff.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zz", HiVector(nsamps, 0.0)); ZzHist.add("Debug::SkipModule invoked!"); } ///////////////////////////////////////////////////////////////// // DarkSubtract (Z_b) Remove dark current // procStep = "Zb module"; hiconf.selectProfile("Zb"); hiprof = hiconf.getMatrixProfile(); HiHistory ZbHist; ZbHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { DarkSubtractComp dark(hiconf); calVars->add("Zb", dark.ref()); ZbHist = dark.History(); if ( hiprof.exists("DumpModuleFile") ) { dark.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zb", HiVector(nsamps, 0.0)); ZbHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainVLineCorrect (Z_g) Correct for gain-based drift // procStep = "Zg module"; hiconf.selectProfile("Zg"); hiprof = hiconf.getMatrixProfile(); HiHistory ZgHist; ZgHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { GainVLineComp gainV(hiconf); calVars->add("Zg", gainV.ref()); ZgHist = gainV.History(); if ( hiprof.exists("DumpModuleFile") ) { gainV.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zg", HiVector(nlines, 1.0)); ZgHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // GainCorrect (Z_gg) Correct for gain with the G matrix procStep = "Zgg module"; hiconf.selectProfile("Zgg"); hiprof = hiconf.getMatrixProfile(); HiHistory ZggHist; ZggHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { double bin = ToDouble(hiprof("Summing")); double tdi = ToDouble(hiprof("Tdi")); double factor = 128.0 / tdi / (bin*bin); HiVector zgg = hiconf.getMatrix("G", hiprof); for ( int i = 0 ; i < zgg.dim() ; i++ ) { zgg[i] *= factor; } calVars->add("Zgg", zgg);; ZggHist.add("LoadMatrix(G[" + hiconf.getMatrixSource("G",hiprof) + "],Band[" + ToString(hiconf.getMatrixBand(hiprof)) + "],Factor[" + ToString(factor) + "])"); if ( hiprof.exists("DumpModuleFile") ) { Component zg("GMatrix", ZggHist); zg.Process(zgg); zg.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zgg", HiVector(nsamps, 1.0)); ZggHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // FlatField (Z_a) Flat field correction with A matrix procStep = "Za module"; hiconf.selectProfile("Za"); hiprof = hiconf.getMatrixProfile(); HiHistory ZaHist; ZaHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { FlatFieldComp flat(hiconf); calVars->add("Za", flat.ref()); ZaHist = flat.History(); if ( hiprof.exists("DumpModuleFile") ) { flat.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Za", HiVector(nsamps, 1.0)); ZaHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // FlatField (Z_t) Temperature-dependant gain correction procStep = "Zt module"; hiconf.selectProfile("Zt"); hiprof = hiconf.getMatrixProfile(); HiHistory ZtHist; ZtHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { TempGainCorrect tcorr(hiconf); calVars->add("Zt", tcorr.ref()); ZtHist = tcorr.History(); if ( hiprof.exists("DumpModuleFile") ) { tcorr.Dump(hiconf.getMatrixSource("DumpModuleFile",hiprof)); } } else { calVars->add("Zt", HiVector(nsamps, 1.0)); ZtHist.add("Debug::SkipModule invoked!"); } //////////////////////////////////////////////////////////////////// // I/FCorrect (Z_iof) Conversion to I/F // procStep = "Ziof module"; hiconf.selectProfile("Ziof"); hiprof = hiconf.getMatrixProfile(); HiHistory ZiofHist; ZiofHist.add("Profile["+ hiprof.Name()+"]"); if ( !SkipModule(hiprof) ) { double sed = ToDouble(hiprof("ScanExposureDuration")); // units = us if ( IsEqual(units, "IOF") ) { // Add solar I/F correction parameters double au = hiconf.sunDistanceAU(); ZiofHist.add("SunDist[" + ToString(au) + " (AU)]"); double suncorr = 1.5 / au; suncorr *= suncorr; double zbin = ToDouble(hiprof("ZiofBinFactor")); ZiofHist.add("ZiofBinFactor[" + ToString(zbin) + "]"); double zgain = ToDouble(hiprof("FilterGainCorrection")); ZiofHist.add("FilterGainCorrection[" + ToString(zgain) + "]"); ZiofHist.add("ScanExposureDuration[" + ToString(sed) + "]"); double ziof = (zbin * zgain) * (sed * 1.0e-6) * suncorr; calVars->add("Ziof", HiVector(1, ziof)); ZiofHist.add("I/F_Factor[" + ToString(ziof) + "]"); ZiofHist.add("Units[I/F Reflectance]"); } else if ( IsEqual(units, "DN/US") ) { // Ziof is a divisor in calibration equation double ziof = sed; calVars->add("Ziof", HiVector(1, ziof)); ZiofHist.add("ScanExposureDuration[" + ToString(sed) + "]"); ZiofHist.add("DN/US_Factor[" + ToString(ziof) + "]"); ZiofHist.add("Units[DNs/microsecond]"); } else { // Units are already in DN double ziof = 1.0; calVars->add("Ziof", HiVector(1, ziof)); ZiofHist.add("DN_Factor[" + ToString(ziof) + "]"); ZiofHist.add("Units[DN]"); } } else { calVars->add("Ziof", HiVector(1,1.0)); ZiofHist.add("Debug::SkipModule invoked!"); ZiofHist.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 std::string 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)); string hdumpFile = hdump.Expanded(); ofstream ofile(hdumpFile.c_str(), ios::out); if (!ofile) { string mess = "Unable to open/create history dump file " + hdump.Expanded(); iException::Message(iException::User, mess, _FILEINFO_).Report(); } 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 */" << endl << "/* hdn = (idn - Zd(Zf) - Zz - Zb) */" << endl << "/* odn = hdn / Zg * Zgg * Za * Zt / Ziof */" << endl << endl; ofile << "****** PARAMETER GENERATION HISTORY *******" << endl; ofile << "\nZf = " << ZfHist << endl; ofile << "\nZd = " << ZdHist << endl; ofile << "\nZz = " << ZzHist << endl; ofile << "\nZb = " << ZbHist << endl; ofile << "\nZg = " << ZgHist << endl; ofile << "\nZgg = " << ZggHist << endl; ofile << "\nZa = " << ZaHist << endl; ofile << "\nZt = " << ZtHist << endl; ofile << "\nZiof = " << ZiofHist << endl; ofile.close(); } } // Ensure the RadiometricCalibration group is out there const std::string rcalGroup("RadiometricCalibration"); if (!ocube->HasGroup(rcalGroup)) { PvlGroup temp(rcalGroup); ocube->PutGroup(temp); } PvlGroup &rcal = ocube->GetGroup(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 - Zd(Zf) - Zz - Zb) */"); key.AddComment("/* odn = hdn / Zg * Zgg * Za * Zt / Ziof */"); 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",string("TRUE")),"TRUE")) { rcal += ZfHist.makekey("Zf"); rcal += ZdHist.makekey("Zd"); rcal += ZzHist.makekey("Zz"); rcal += ZbHist.makekey("Zb"); rcal += ZgHist.makekey("Zg"); rcal += ZggHist.makekey("Zgg"); rcal += ZaHist.makekey("Za"); rcal += ZiofHist.makekey("Ziof"); } p.EndProcess(); } catch (iException &ie) { delete calVars; calVars = 0; string mess = "Failed in " + procStep; ie.Message(iException::User, mess.c_str(), _FILEINFO_); throw; } // Clean up parameters delete calVars; calVars = 0; }
void IsisMain() { // Open the input cube ProcessByLine p; Cube *input = p.SetInputCube("FROM"); // Check for filter type of A-D Pvl *label = input->Label(); iString wave = (string)label->FindGroup("BandBin", Pvl::Traverse)["FilterName"]; if ((wave != "A") && (wave != "B") && (wave != "C") && (wave != "D")) { string message = "Invalid FilterName [" + wave + "], can only handle A-D filters"; throw iException::Message(Isis::iException::None, message, _FILEINFO_); } // Determine and load calibration flat field file wave.DownCase(); iString flatFile("$Clementine1/calibration/hires/lh" + wave + "_flat.cub"); CubeAttributeInput cubeAtt; p.SetInputCube(flatFile, cubeAtt); // Check the offset mode for validity int index = label->FindGroup("Instrument", Pvl::Traverse)["OffsetModeID"]; if (index < 0 || index > 5) { string message = "Invalid OffsetModeID, can only handle offests 0-5"; throw iException::Message(Isis::iException::None, message, _FILEINFO_); } // Set the offset (b0) value based on mode double dataOffset[] = {-49.172, -41.0799, -32.8988, -24.718, -16.98, -8.0}; offset = dataOffset[index]; // Computer the K value to convert to I/F. The K value per MCP and wavelength // were obtained from JGR publication Vol 108, A radiometric calibration for the // Clementine HIRES camera: Robinson, Malart, White, page 17 UserInterface &ui = Application::GetUserInterface(); if (ui.GetString("KFROM").compare("COMPUTED") == 0) { wave.UpCase(); int MCP = label->FindGroup("Instrument", Pvl::Traverse)["MCPGainModeID"]; // Two possible MCP gains for filter A if (wave == "A") { if (MCP == 156) { abscoef = 0.00105; } else if (MCP == 159) { abscoef = 0.00089; } else { string message = "Image is not one of supported MCP Gain Mode IDs, enter your own K value"; throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); } } // Three possiblities for filter D else if (wave == "D") { if (MCP == 151) { abscoef = 0.001655; } else if (MCP == 154) { abscoef = 0.001375; } else if (MCP == 158) { abscoef = 0.00097; } else { string message = "Image is not one of supported MCP Gain Mode IDs, enter your own K value"; throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); } } // Other filters not supported for preset K value else { string message = "Image is of filter [" + wave + "], not supported type A or D, enter your own K value"; throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); } } // Otherwise get K value from user else { abscoef = ui.GetDouble("KVALUE"); } // K, Offset, and flat file are defined. Create output cube and process // each line p.SetOutputCube("TO"); p.StartProcess(clemhirescal); p.EndProcess(); }
/** * Constructs a UniversalGroundMap object from a cube * * @param cube The Cube to create the UniversalGroundMap from */ UniversalGroundMap::UniversalGroundMap(Cube &cube) { Init(*cube.Label()); }
/** * @brief Construct using an ISIS Cube object * * @param cube Cube object of ISIS file */ Kernels::Kernels(Cube &cube) { Load(*cube.Label()); }
void IsisMain () { UserInterface &ui = Application::GetUserInterface(); Filename inFile = ui.GetFilename("FROM"); // Set the processing object ProcessExportMiniRFLroPds cProcess; // Setup the input cube Cube *cInCube = cProcess.SetInputCube("FROM"); Pvl * cInLabel = cInCube->Label(); // Get the output label file Filename outFile(ui.GetFilename("TO", "lbl")); string outFilename(outFile.Expanded()); cProcess.SetDetached (true, outFilename); cProcess.SetExportType ( ProcessExportPds::Fixed ); //Set the resolution to Kilometers cProcess.SetPdsResolution( ProcessExportPds::Kilometer ); // 32bit cProcess.SetOutputType(Isis::Real); cProcess.SetOutputNull(Isis::NULL4); cProcess.SetOutputLrs(Isis::LOW_REPR_SAT4); cProcess.SetOutputLis(Isis::LOW_INSTR_SAT4); cProcess.SetOutputHrs(Isis::HIGH_REPR_SAT4); cProcess.SetOutputHis(Isis::HIGH_INSTR_SAT4); cProcess.SetOutputRange(-DBL_MAX, DBL_MAX); cProcess.SetOutputEndian(Isis::Msb); // Turn off Keywords cProcess.ForceScalingFactor(false); cProcess.ForceSampleBitMask(false); cProcess.ForceCoreNull (false); cProcess.ForceCoreLrs (false); cProcess.ForceCoreLis (false); cProcess.ForceCoreHrs (false); cProcess.ForceCoreHis (false); // Standard label Translation Pvl &pdsLabel = cProcess.StandardPdsLabel( ProcessExportPds::Image); // bLevel => Level 2 = True, Level 3 = False bool bLevel2 = cInCube->HasGroup("Instrument"); // Translate the keywords from the original EDR PDS label that go in // this RDR PDS label for Level2 images only if (bLevel2) { OriginalLabel cOriginalBlob; cInCube->Read(cOriginalBlob); Pvl cOrigLabel; PvlObject cOrigLabelObj = cOriginalBlob.ReturnLabels(); cOrigLabelObj.SetName("OriginalLabelObject"); cOrigLabel.AddObject(cOrigLabelObj); // Translates the ISIS labels along with the original EDR labels cOrigLabel.AddObject( *(cInCube->Label()) ); PvlTranslationManager cCubeLabel2(cOrigLabel, "$lro/translations/mrfExportOrigLabel.trn"); cCubeLabel2.Auto(pdsLabel); if (cInLabel->FindObject("IsisCube").FindGroup("Instrument").HasKeyword("MissionName")) { PvlKeyword & cKeyMissionName = cInLabel->FindObject("IsisCube").FindGroup("Instrument").FindKeyword("MissionName"); size_t sFound = cKeyMissionName[0].find("CHANDRAYAAN"); if (sFound != string::npos ) { cCubeLabel2 = PvlTranslationManager(cOrigLabel, "$lro/translations/mrfExportOrigLabelCH1.trn"); cCubeLabel2.Auto(pdsLabel); } else { cCubeLabel2 = PvlTranslationManager(cOrigLabel, "$lro/translations/mrfExportOrigLabelLRO.trn"); cCubeLabel2.Auto(pdsLabel); } } } else { //Level3 - add Band_Name keyword PvlGroup & cBandBinGrp = cInCube->GetGroup("BandBin"); PvlKeyword cKeyBandBin = PvlKeyword("BAND_NAME"); PvlKeyword cKeyInBandBin; if (cBandBinGrp.HasKeyword("OriginalBand")){ cKeyInBandBin = cBandBinGrp.FindKeyword("OriginalBand"); } else if (cBandBinGrp.HasKeyword("FilterName")){ cKeyInBandBin = cBandBinGrp.FindKeyword("FilterName"); } for (int i=0; i<cKeyInBandBin.Size(); i++) { cKeyBandBin += cKeyInBandBin[i]; } PvlObject &cImageObject( pdsLabel.FindObject("IMAGE") ); cImageObject += cKeyBandBin; } // Get the Sources Product ID if entered for Level2 only as per example if (ui.WasEntered("SRC") && bLevel2) { std::string sSrcFile = ui.GetFilename("SRC"); std::string sSrcType = ui.GetString("TYPE"); GetSourceProductID(sSrcFile, sSrcType, pdsLabel); } // Get the User defined Labels if (ui.WasEntered("USERLBL")) { std::string sUserLbl = ui.GetFilename("USERLBL"); GetUserLabel(sUserLbl, pdsLabel, bLevel2); } // Calculate CheckSum Statistics * cStats = cInCube->Statistics(); iCheckSum = (unsigned int )cStats->Sum(); FixLabel(pdsLabel, bLevel2); // Add an output format template to the PDS PVL // Distinguish betweeen Level 2 and 3 images by calling the camera() // function as only non mosaic images(Level2) have a camera if (bLevel2) { pdsLabel.SetFormatTemplate ("$lro/translations/mrfPdsLevel2.pft"); } else { pdsLabel.SetFormatTemplate ("$lro/translations/mrfPdsLevel3.pft"); } size_t iFound = outFilename.find(".lbl"); outFilename.replace(iFound, 4, ".img"); ofstream oCube(outFilename.c_str()); cProcess.OutputDetatchedLabel(); //cProcess.OutputLabel(oCube); cProcess.StartProcess(oCube); oCube.close(); cProcess.EndProcess(); }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); /*Processing steps 1. Open and read the jitter table, convert the pixel offsets to angles, and create the polynomials (solve for the coefficients) to use to do the high pass filter putting the results into a rotation matrix in the jitter class. 2. Apply the jitter correction in the LineScanCameraRotation object of the master cube. 3. Loop through FROMLIST correcting the pointing and writing out the updated camera pointing from the master cube */ int degree = ui.GetInteger("DEGREE"); // Get the input file list to make sure it is not empty and the master cube is included FileList list; list.Read(ui.GetFilename("FROMLIST")); if (list.size() < 1) { string msg = "The input list file [" + ui.GetFilename("FROMLIST") + "is empty"; throw iException::Message(iException::User,msg,_FILEINFO_); } int ifile = 0; // Make sure the master file is included in the input file list while (ifile < (int) list.size() && Filename(list[ifile]).Expanded() != Filename(ui.GetFilename("MASTER")).Expanded()) { ifile++; } if (ifile >= (int) list.size()) { string msg = "The master file, [" + Filename(ui.GetFilename("MASTER")).Expanded() + " is not included in " + "the input list file " + ui.GetFilename("FROMLIST") + "]"; throw iException::Message(iException::User,msg,_FILEINFO_); } bool step2 = false; PvlGroup gp("AppjitResults"); //Step 1: Create the jitter rotation try { // Open the master cube Cube cube; cube.Open(ui.GetFilename("MASTER"),"rw"); //check for existing polygon, if exists delete it if (cube.Label()->HasObject("Polygon")){ cube.Label()->DeleteObject("Polygon"); } // Get the camera Camera *cam = cube.Camera(); if (cam->DetectorMap()->LineRate() == 0.0) { string msg = "[" + ui.GetFilename("MASTER") + "] is not a line scan camera image"; throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } // Create the master rotation to be corrected int frameCode = cam->InstrumentRotation()->Frame(); cam->SetImage(int(cube.Samples()/2), int(cube.Lines()/2) ); double tol = cam->PixelResolution(); if (tol < 0.) { // Alternative calculation of .01*ground resolution of a pixel tol = cam->PixelPitch()*cam->SpacecraftAltitude()*1000./cam->FocalLength()/100.; } LineScanCameraRotation crot(frameCode, *(cube.Label()), cam->InstrumentRotation()->GetFullCacheTime(), tol ); crot.SetPolynomialDegree(ui.GetInteger("DEGREE")); crot.SetAxes(1, 2, 3); if (ui.WasEntered("PITCHRATE")) crot.ResetPitchRate(ui.GetDouble("PITCHRATE")); if (ui.WasEntered("YAW")) crot.ResetYaw(ui.GetDouble("YAW")); crot.SetPolynomial(); double baseTime = crot.GetBaseTime(); double timeScale = crot.GetTimeScale(); double fl = cam->FocalLength(); double pixpitch = cam->PixelPitch(); std::vector<double> cacheTime = cam->InstrumentRotation()->GetFullCacheTime(); // Get the jitter in pixels, compute jitter angles, and fit a polynomial to each angle PixelOffset jitter(ui.GetFilename("JITTERFILE"), fl, pixpitch, baseTime, timeScale, degree); jitter.LoadAngles(cacheTime); jitter.SetPolynomial(); // Set the jitter and apply to the instrument rotation crot.SetJitter( &jitter ); crot.ReloadCache(); // Pull out the pointing cache as a table and write it Table cmatrix = crot.Cache("InstrumentPointing"); cmatrix.Label().AddComment("Corrected using appjit and" + ui.GetFilename("JITTERFILE")); cube.Write(cmatrix); // Write out the instrument position table Isis::PvlGroup kernels = cube.Label()->FindGroup("Kernels",Isis::Pvl::Traverse); // Write out the "Table" label to the tabled kernels in the kernels group kernels["InstrumentPointing"] = "Table"; // kernels["InstrumentPosition"] = "Table"; cube.PutGroup(kernels); cube.Close(); gp += PvlKeyword("StatusMaster",ui.GetFilename("MASTER") + ": camera pointing updated"); // Apply the dejittered pointing to the rest of the files step2 = true; for (int ifile = 0; ifile < (int) list.size(); ifile++) { if (list[ifile] != ui.GetFilename("MASTER")) { // Open the cube cube.Open(list[ifile],"rw"); //check for existing polygon, if exists delete it if (cube.Label()->HasObject("Polygon")){ cube.Label()->DeleteObject("Polygon"); } // Get the camera and make sure it is a line scan camera Camera *cam = cube.Camera(); if (cam->DetectorMap()->LineRate() == 0.0) { string msg = "[" + ui.GetFilename("FROM") + "] is not a line scan camera"; throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } // Pull out the pointing cache as a table and write it cube.Write(cmatrix); cube.PutGroup(kernels); cube.Close(); gp += PvlKeyword("Status" + iString(ifile), list[ifile] + ": camera pointing updated"); } } Application::Log( gp ); } catch (iException &e) { string msg; if (!step2) { msg = "Unable to fit pointing for [" + ui.GetFilename("MASTER") + "]"; } else { msg = "Unable to update pointing for nonMaster file(s)"; } throw iException::Message(Isis::iException::User,msg,_FILEINFO_); } }
void IsisMain() { // Get the list of cubes to mosaic UserInterface &ui = Application::GetUserInterface(); FileList flist(ui.GetFilename("FROMLIST")); vector<Cube *> clist; try { if (flist.size() < 1) { string msg = "the list file [" +ui.GetFilename("FROMLIST") + "does not contain any data"; throw iException::Message(iException::User,msg,_FILEINFO_); } // open all the cube and place in vector clist for (int i=0; i<(int)flist.size(); i++) { Cube *c = new Cube(); clist.push_back(c); c->Open(flist[i]); } // run the compair function here. This will conpair the // labels of the first cube to the labels of each following cube. PvlKeyword sourceProductId("SourceProductId"); string ProdId; for (int i=0; i<(int)clist.size(); i++) { Pvl *pmatch = clist[0]->Label(); Pvl *pcomp = clist[i]->Label(); CompareLabels(*pmatch, *pcomp); PvlGroup g = pcomp->FindGroup("Instrument",Pvl::Traverse); if (g.HasKeyword("StitchedProductIds")) { PvlKeyword k = g["StitchedProductIds"]; for (int j=0; j<(int)k.Size(); j++) { sourceProductId += g["stitchedProductIds"][j]; } } ProdId = (string)pmatch->FindGroup("Archive",Pvl::Traverse)["ObservationId"]; iString bandname = (string)pmatch->FindGroup("BandBin",Pvl::Traverse)["Name"]; bandname = bandname.UpCase(); ProdId = ProdId + "_" + bandname; } bool runXY=true; //calculate the min and max lon double minLat = DBL_MAX; double maxLat = -DBL_MAX; double minLon = DBL_MAX; double maxLon = -DBL_MAX; double avgLat; double avgLon; for (int i=0; i<(int)clist.size(); i++) { Projection *proj = clist[i]->Projection(); if (proj->MinimumLatitude() < minLat) minLat = proj->MinimumLatitude(); if (proj->MaximumLatitude() > maxLat) maxLat = proj->MaximumLatitude(); if (proj->MinimumLongitude() < minLon) minLon = proj->MinimumLongitude(); if (proj->MaximumLongitude() > maxLon) maxLon = proj->MaximumLongitude(); } avgLat = (minLat + maxLat) / 2; avgLon = (minLon + maxLon) / 2; Projection *proj = clist[0]->Projection(); proj->SetGround(avgLat,avgLon); avgLat = proj->UniversalLatitude(); avgLon = proj->UniversalLongitude(); // Use camera class to get Inc., emi., phase, and other values double Cemiss; double Cphase; double Cincid; double ClocalSolTime; double CsolarLong; double CsunAzimuth; double CnorthAzimuth; for (int i=0; i<(int)clist.size(); i++) { Camera *cam = clist[i]->Camera(); if (cam->SetUniversalGround(avgLat,avgLon)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->SolarLongitude(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } //The code within the if runXY was added in 10/07 to find an intersect with //pole images that would fail when using projection set universal ground. // This is run if no intersect is found when using lat and lon in // projection space. if (runXY) { double startX = DBL_MAX; double endX = DBL_MIN; double startY = DBL_MAX; double endY = DBL_MIN; for (int i=0; i<(int)clist.size(); i++) { Projection *proj = clist[i]->Projection(); proj->SetWorld(0.5,0.5); if (i==0) { startX = proj->XCoord(); endY = proj->YCoord(); } else { if (proj->XCoord() < startX) startX = proj->XCoord(); if (proj->YCoord() > endY) endY = proj->YCoord(); } Pvl *p = clist[i]->Label(); double nlines = p->FindGroup("Dimensions",Pvl::Traverse)["Lines"]; double nsamps = p->FindGroup("Dimensions",Pvl::Traverse)["Samples"]; proj->SetWorld((nsamps+0.5),(nlines+0.5)); if (i==0) { endX = proj->XCoord(); startY = proj->YCoord(); } else { if (proj->XCoord() > endX) endX = proj->XCoord(); if (proj->YCoord() < startY) startY = proj->YCoord(); } } double avgX = (startX + endX) / 2; double avgY = (startY + endY) / 2; double sample = proj->ToWorldX(avgX); double line = proj->ToWorldY(avgY); for (int i=0; i<(int)clist.size(); i++) { Camera *cam = clist[i]->Camera(); if (cam->SetImage(sample,line)) { Cemiss = cam->EmissionAngle(); Cphase = cam->PhaseAngle(); Cincid = cam->IncidenceAngle(); ClocalSolTime = cam->LocalSolarTime(); CsolarLong = cam->SolarLongitude(); CsunAzimuth = cam->SunAzimuth(); CnorthAzimuth = cam->NorthAzimuth(); runXY = false; break; } } } if (runXY) { string msg = "Camera did not intersect images to gather stats"; throw iException::Message(iException::User,msg,_FILEINFO_); } // get the min and max SCLK values ( do this with string comp.) // get the value from the original label blob string startClock; string stopClock; string startTime; string stopTime; for (int i=0; i<(int)clist.size(); i++) { OriginalLabel origLab; clist[i]->Read(origLab); PvlGroup timegrp = origLab.ReturnLabels().FindGroup("TIME_PARAMETERS",Pvl::Traverse); if (i==0) { startClock = (string)timegrp["SpacecraftClockStartCount"]; stopClock = (string)timegrp["SpacecraftClockStopCount"]; startTime = (string)timegrp["StartTime"]; stopTime = (string)timegrp["StopTime"]; } else { string testStartTime = (string)timegrp["StartTime"]; string testStopTime = (string)timegrp["StopTime"]; if (testStartTime < startTime) { startTime = testStartTime; startClock = (string)timegrp["SpacecraftClockStartCount"]; } if (testStopTime > stopTime) { stopTime = testStopTime; stopClock = (string)timegrp["spacecraftClockStopCount"]; } } } // Concatenate all TDI's and summing and specialProcessingFlat into one keyword PvlKeyword cpmmTdiFlag("cpmmTdiFlag"); PvlKeyword cpmmSummingFlag("cpmmSummingFlag"); PvlKeyword specialProcessingFlag("SpecialProcessingFlag"); for (int i=0; i<14; i++) { cpmmTdiFlag +=(string)""; cpmmSummingFlag +=(string)""; specialProcessingFlag +=(string)""; } for (int i=0; i<(int)clist.size(); i++) { Pvl *clab = clist[i]->Label(); PvlGroup cInst = clab->FindGroup("Instrument",Pvl::Traverse); OriginalLabel cOrgLab; clist[i]->Read(cOrgLab); PvlGroup cGrp = cOrgLab.ReturnLabels().FindGroup("INSTRUMENT_SETTING_PARAMETERS",Pvl::Traverse); cpmmTdiFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:TDI"]; cpmmSummingFlag[(int)cInst["CpmmNumber"]] = (string) cGrp["MRO:BINNING"]; if (cInst.HasKeyword("Special_Processing_Flag")) { specialProcessingFlag[cInst["CpmmNumber"]] = (string) cInst["Special_Processing_Flag"]; } else { // there may not be the keyword Special_Processing_Flag if no //keyword then set the output to NOMINAL specialProcessingFlag[cInst["CpmmNumber"]] = "NOMINAL"; } } // Get the blob of original labels from first image in list OriginalLabel org; clist[0]->Read(org); //close all cubes for (int i=0; i<(int)clist.size(); i++) { clist[i]->Close(); delete clist[i]; } clist.clear(); // automos step string list = ui.GetFilename("FROMLIST"); string toMosaic = ui.GetFilename("TO"); string MosaicPriority = ui.GetString("PRIORITY"); string parameters = "FROMLIST=" + list + " MOSAIC=" + toMosaic + " PRIORITY=" + MosaicPriority; Isis::iApp ->Exec("automos",parameters); // write out new information to new group mosaic PvlGroup mos("Mosaic"); mos += PvlKeyword("ProductId ", ProdId); mos += PvlKeyword(sourceProductId); mos += PvlKeyword("StartTime ", startTime); mos += PvlKeyword("SpacecraftClockStartCount ", startClock); mos += PvlKeyword("StopTime ", stopTime); mos += PvlKeyword("SpacecraftClockStopCount ", stopClock); mos += PvlKeyword("IncidenceAngle ", Cincid, "DEG"); mos += PvlKeyword("EmissionAngle ", Cemiss, "DEG"); mos += PvlKeyword("PhaseAngle ", Cphase, "DEG"); mos += PvlKeyword("LocalTime ", ClocalSolTime, "LOCALDAY/24"); mos += PvlKeyword("SolarLongitude ", CsolarLong, "DEG"); mos += PvlKeyword("SubSolarAzimuth ", CsunAzimuth, "DEG"); mos += PvlKeyword("NorthAzimuth ", CnorthAzimuth, "DEG"); mos += cpmmTdiFlag; mos += cpmmSummingFlag; mos += specialProcessingFlag; Cube mosCube; mosCube.Open(ui.GetFilename("TO"), "rw"); PvlObject &lab=mosCube.Label()->FindObject("IsisCube"); lab.AddGroup(mos); //add orginal label blob to the output cube mosCube.Write(org); mosCube.Close(); } catch (iException &e) { for (int i=0; i<(int)clist.size(); i++) { clist[i]->Close(); delete clist[i]; } string msg = "The mosaic [" + ui.GetFilename("TO") + "] was NOT created"; throw iException::Message(iException::User,msg,_FILEINFO_); } } // end of isis main
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(); }