bool FinishSave(String tmpfile, String outfile) { if(IsDeactivationSave()) { FileMove(tmpfile, outfile); return true; } Progress progress; int time = GetTickCount(); for(;;) { progress.SetTotal(10000); progress.SetText("Saving '" + GetFileName(outfile) + "'"); if(!FileExists(tmpfile)) return false; FileDelete(outfile); if(FileMove(tmpfile, outfile)) return true; IdeConsoleFlush(); Sleep(200); if(progress.SetPosCanceled((GetTickCount() - time) % progress.GetTotal())) { int art = Prompt(Ctrl::GetAppName(), CtrlImg::exclamation(), "Unable to save current file.&" "Retry save, ignore it or save file to another location?", "Save as...", "Retry", "Ignore"); if(art < 0) return false; if(art && AnySourceFs().ExecuteSaveAs()) outfile = AnySourceFs(); progress.SetPos(0); } } }
void Ide::Licenses() { Progress pi; const Workspace& wspc = IdeWorkspace(); pi.SetTotal(wspc.GetCount()); VectorMap<String, String> license_package; for(int i = 0; i < wspc.GetCount(); i++) { String n = wspc[i]; pi.SetText(n); if(pi.StepCanceled()) return; String l = LoadFile(SourcePath(n, "Copying")); if(l.GetCount()) MergeWith(license_package.GetAdd(l), ", ", n); } if(license_package.GetCount() == 0) { Exclamation("No license files ('Copying') have been found."); return; } String qtf; for(int i = 0; i < license_package.GetCount(); i++) { bool m = license_package[i].Find(',') >= 0; qtf << (m ? "Packages [* \1" : "Package [* \1") << license_package[i] << (m ? "\1] have" : "\1] has") << " following licence notice:&" << "{{@Y [C1 " << DeQtf(license_package.GetKey(i)) << "]}}&&"; } ShowQTF(qtf, "Licenses"); }
bool PostgreSQLTest::OpenDB() { if(!m_session.Open("host=localhost dbname=test user=test password=test")) { Exclamation(Format("Error in open: %s", DeQtf(m_session.GetLastError()))); return false; } m_array.SetSession(m_session); #ifdef _DEBUG m_session.SetTrace(); #endif SQL = m_session; //schema Progress p; p.SetText(t_("Creating _DEBUG database")); SqlSchema sch(PGSQL); All_Tables(sch); if(sch.ScriptChanged(SqlSchema::UPGRADE)) SqlPerformScript(sch.Upgrade(), p); if(sch.ScriptChanged(SqlSchema::ATTRIBUTES)) { SqlPerformScript(sch.Attributes(), p); } if(sch.ScriptChanged(SqlSchema::CONFIG)) { SqlPerformScript(sch.ConfigDrop(), p); SqlPerformScript(sch.Config(), p); } sch.SaveNormal(); return true; }
void SyncRefsDir(const char *dir, const String& rel, Progress& pi) { SyncRefsRunning++; for(FindFile pff(AppendFileName(dir, "*.*")); pff && !IdeExit; pff.Next()) { if(pff.IsFolder() && *pff.GetName() != '.') { if(SyncRefsShowProgress) pi.Step(); TopicLink tl; tl.package = rel + pff.GetName(); String pdir = AppendFileName(dir, pff.GetName()); for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff && !IdeExit; ff.Next()) { if(ff.IsFolder()) { String group = GetFileTitle(ff.GetName()); tl.group = group; String dir = AppendFileName(pdir, ff.GetName()); LSLOW(); for(FindFile ft(AppendFileName(dir, "*.tpp")); ft && !IdeExit; ft.Next()) { if(ft.IsFile()) { String path = AppendFileName(dir, ft.GetName()); tl.topic = GetFileTitle(ft.GetName()); String link = TopicLinkString(tl); if(SyncRefsShowProgress) pi.SetText("Indexing topic " + tl.topic); SyncTopicFile(link); } if(!SyncRefsFinished && !SyncRefsShowProgress && !IdeExit) Ctrl::ProcessEvents(); } } } SyncRefsDir(pdir, tl.package + '/', pi); } } SyncRefsRunning--; }
/** * Calculates the lat/lon of the ControlNet. * * @param incubes The filename of the list of cubes in the ControlNet * @param cnet The filename of the ControlNet */ void setControlPointLatLon(SerialNumberList &snl, ControlNet &cnet) { CubeManager manager; manager.SetNumOpenCubes(50); //Should keep memory usage to around 1GB Progress progress; progress.SetText("Calculating Lat/Lon"); progress.SetMaximumSteps(cnet.GetNumPoints()); progress.CheckStatus(); for (int cp = 0; cp < cnet.GetNumPoints(); cp++) { ControlPoint *point = cnet.GetPoint(cp); ControlMeasure *cm = point->GetRefMeasure(); Cube *cube = manager.OpenCube(snl.FileName(cm->GetCubeSerialNumber())); try { cube->camera()->SetImage(cm->GetSample(), cm->GetLine()); g_surfacePoints[point->GetId()] = cube->camera()->GetSurfacePoint(); } catch (IException &e) { QString msg = "Unable to create camera for cube file ["; msg += snl.FileName(cm->GetCubeSerialNumber()) + "]"; throw IException(e, IException::Unknown, msg, _FILEINFO_); } cube = NULL; //Do not delete, manager still has ownership progress.CheckStatus(); } manager.CleanCubes(); }
bool PostgreSQLTest::OpenDB() { if(!m_session.Open("host=localhost dbname=test user=postgres password=pepicek12A")) { Exclamation(Format("Error in open: %s", DeQtf(m_session.GetLastError()))); return false; } m_array.SetSession(m_session); SQLCommander(m_session); return false; #ifdef _DEBUG m_session.SetTrace(); #endif SQL = m_session; //schema Progress p; p.SetText(t_("Creating _DEBUG database")); SqlSchema sch(PGSQL); StdStatementExecutor se(m_session); All_Tables(sch); PostgreSQLPerformScript(sch.Upgrade(),se, p); PostgreSQLPerformScript(sch.Attributes(),se, p); sch.SaveNormal(); return true; }
/** * This method performs pass1 on one image. It analyzes each framelet's * statistics and populates the necessary global variable. * * @param progress Progress message * @param theCube Current cube that needs processing * * @return bool True if the file contains a valid framelet */ bool CheckFramelets(string progress, Cube &theCube) { bool foundValidFramelet = false; LineManager mgr(theCube); Progress prog; prog.SetText(progress); prog.SetMaximumSteps(theCube.Lines()); prog.CheckStatus(); vector<double> frameletAvgs; // We need to store off the framelet information, because if no good // framelets were found then no data should be added to the // global variable for framelets, just files. vector< pair<int,double> > excludedFrameletsTmp; Statistics frameletStats; for(int line = 1; line <= theCube.Lines(); line++) { if((line-1) % numFrameLines == 0) { frameletStats.Reset(); } mgr.SetLine(line); theCube.Read(mgr); frameletStats.AddData(mgr.DoubleBuffer(), mgr.size()); if((line-1) % numFrameLines == numFrameLines-1) { if(IsSpecial(frameletStats.StandardDeviation()) || frameletStats.StandardDeviation() > maxStdev) { excludedFrameletsTmp.push_back( pair<int,double>((line-1)/numFrameLines, frameletStats.StandardDeviation()) ); } else { foundValidFramelet = true; } frameletAvgs.push_back(frameletStats.Average()); } prog.CheckStatus(); } inputFrameletAverages.push_back(frameletAvgs); if(foundValidFramelet) { for(unsigned int i = 0; i < excludedFrameletsTmp.size(); i++) { excludedFramelets.insert(pair< pair<int,int>, double>( pair<int,int>(currImage, excludedFrameletsTmp[i].first), excludedFrameletsTmp[i].second ) ); } } return foundValidFramelet; }
void IsisMain() { latLonGrid = NULL; // We will be processing by line ProcessByLine p; Cube *icube = p.SetInputCube("FROM"); UserInterface &ui = Application::GetUserInterface(); string mode = ui.GetString("MODE"); outline = ui.GetBoolean("OUTLINE"); inputSamples = icube->Samples(); inputLines = icube->Lines(); // Line & sample based grid if(mode == "IMAGE") { p.SetOutputCube ("TO"); baseLine = ui.GetInteger("BASELINE"); baseSample = ui.GetInteger("BASESAMPLE"); lineInc = ui.GetInteger("LINC"); sampleInc = ui.GetInteger("SINC"); p.StartProcess(imageGrid); p.EndProcess(); } // Lat/Lon based grid else { CubeAttributeOutput oatt("+32bit"); p.SetOutputCube (ui.GetFilename("TO"), oatt, icube->Samples(), icube->Lines(), icube->Bands()); baseLat = ui.GetDouble("BASELAT"); baseLon = ui.GetDouble("BASELON"); latInc = ui.GetDouble("LATINC"); lonInc = ui.GetDouble("LONINC"); UniversalGroundMap *gmap = new UniversalGroundMap(*icube); latLonGrid = new GroundGrid(gmap, icube->Samples(), icube->Lines()); Progress progress; progress.SetText("Calculating Grid"); latLonGrid->CreateGrid(baseLat, baseLon, latInc, lonInc, &progress); p.StartProcess(groundGrid); p.EndProcess(); delete latLonGrid; latLonGrid = NULL; delete gmap; gmap = NULL; } }
void Ide::Statistics() { Vector< ArrayMap<String, FileStat> > stat; Progress pi; const Workspace& wspc = IdeWorkspace(); pi.SetTotal(wspc.GetCount()); Date now = GetSysDate(); for(int i = 0; i < wspc.GetCount(); i++) { const Package& pk = wspc.GetPackage(i); String n = wspc[i]; pi.SetText(n); if(pi.StepCanceled()) return; ArrayMap<String, FileStat>& pfs = stat.Add(); for(int i = 0; i < pk.GetCount(); i++) if(!pk[i].separator) { String file = SourcePath(n, pk[i]); if(FileExists(file)) { FileStat& fs = pfs.GetAdd(GetFileExt(file)); int d = minmax(now - FileGetTime(file), 0, 9999); fs.oldest = max(d, fs.oldest); fs.newest = min(d, fs.newest); String data = LoadFile(file); for(const char *s = data; *s; s++) if(*s == '\n') fs.lines++; fs.len += data.GetCount(); fs.days += d; fs.count++; } } } String qtf = "[1 "; ArrayMap<String, FileStat> all; String tab = "{{45:20:25:20:35:30:30:30:30@L [* "; String hdr = "]:: [= Files:: Lines:: - avg.:: Length:: - avg.:: Oldest:: Newest:: Avg. age]"; for(int i = 0; i < wspc.GetCount(); i++) { qtf << tab << DeQtf(wspc[i]) << hdr; sPut(qtf, stat[i], all); } qtf << tab << "All packages" << hdr; sPut(qtf, all, all); WithStatLayout<TopWindow> dlg; CtrlLayoutOK(dlg, "Statistics"); dlg.stat = qtf; dlg.Sizeable().Zoomable(); dlg.Run(); }
void LoadTree(int parent, const String& path, Progress& pi) { pi.SetText(DeFormat(path)); for(FindFile ff(AppendFileName(path, "*.*")); ff; ff.Next()) { if(pi.StepCanceled()) return; String n = ff.GetName(); if(n != "." && n != "..") { edit.Add(); edit.Top() <<= n; int q; static int x; if(++x & 1) q = tree2.Add(parent, ff.IsFolder() ? CtrlImg::Dir() : CtrlImg::File(), edit.Top(), 150); else q = tree2.Add(parent, ff.IsFolder() ? CtrlImg::Dir() : CtrlImg::File(), n); if(ff.IsFolder()) LoadTree(q, AppendFileName(path, n), pi); } } }
/** * Finds and writes all input cubes contained within the given Control Network * to the output file list * * @param cnet The Control Network to list the filenames contained within * @param sn2file The map for converting the Control Network's serial numbers * to filenames */ void WriteCubeOutList( ControlNet cnet, map<iString,iString> sn2file ) { UserInterface &ui = Application::GetUserInterface(); if( ui.WasEntered("TOLIST") ) { Progress p; p.SetText("Writing Cube List"); try { p.SetMaximumSteps(cnet.Size()); p.CheckStatus(); } catch( iException &e ) { e.Clear(); string msg = "The provided filters have resulted in an empty Control Network."; throw Isis::iException::Message(Isis::iException::User,msg, _FILEINFO_); } set<iString> outputsn; for( int cp = 0; cp < cnet.Size(); cp ++ ) { for( int cm = 0; cm < cnet[cp].Size(); cm ++ ) { outputsn.insert( cnet[cp][cm].CubeSerialNumber() ); } p.CheckStatus(); } std::string toList = ui.GetFilename("TOLIST"); ofstream out_stream; out_stream.open(toList.c_str(), std::ios::out); out_stream.seekp(0,std::ios::beg); //Start writing from beginning of file for( set<iString>::iterator sn = outputsn.begin(); sn != outputsn.end(); sn ++ ) { if( !sn2file[(*sn)].empty() ) { out_stream << sn2file[(*sn)] << endl; } } out_stream.close(); } }
void bigmailer::onSend() { const String enter = "\r\n" ; if (messagePage.editor.IsModified()) messagePage.Save() ; // mapa de los campos VectorMap<String, int> fldMap ; for (int i = 0; i < theDefList.fields.GetCount(); i++) fldMap.Add(theDefList.fields[i], i) ; String outHTML ; Index<String> css ; VectorMap<String, String> links ; String path = "./" ; String html = EncodeHtml(messagePage.editor.Get(), css, links, path ) ; outHTML << "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n" "<html>\r\n" "<head>\r\n" "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\r\n" "<style>\r\n" << AsCss( css ) << "\r\n" << "</style>\r\n" "</head>\r\n" "<body>\r\n" << html << "\r\n" << "</body>\r\n" "</html>\r\n" ; Progress prog ; prog.Set(0, theDefList.data.GetCount()) ; prog.Show() ; theDefList.errors.Clear() ; String theHtml ; for (int row = 0; row < theDefList.data.GetCount(); row++) { String addrTo = theDefList.data[row][1] ; if (addrTo.IsEmpty()) { theDefList.errors.Add(t_("dirección incorrecta")) ; continue ; } if (prog.Canceled()) break ; theHtml = outHTML ; String s = AsString(row+1) + " / " + AsString( theDefList.data.GetCount() ) ; prog.SetText(s) ; for (int i = 0; i < theDefList.fields.GetCount(); i++) { String toFind = "[%" + theDefList.fields[i] + "%]" ; int from = 0 ; while( (from = theHtml.Find(toFind, from )) != -1) { theHtml.Remove( from, toFind.GetCount() ) ; theHtml.Insert( from, theDefList.data[row][ fldMap.Get(theDefList.fields[i])] ) ; } } prog.SetPos(row+1) ; SmtpMailEx mail ; mail.Host( theCfg.smtpServer ) .User( theCfg.user ) .Password( theCfg.pass ) .From( theMsg.from ) .ReplyTo( theMsg.from ) .To( addrTo ) .Subject( theMsg.subject ) .Text( "" ) .Attach("MENSAJE", theHtml, "text/html; charset=utf-8") ; if ( ! mail.Send() ) theDefList.errors.Add(mail.GetError()) ; else theDefList.errors.Add("OK") ; } theDefList.Save() ; }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); FileList addList(ui.GetFileName("ADDLIST")); bool log = false; FileName logFile; if (ui.WasEntered("LOG")) { log = true; logFile = ui.GetFileName("LOG"); } Pvl results; results.setName("cnetadd_Results"); PvlKeyword added("FilesAdded"); PvlKeyword omitted("FilesOmitted"); PvlKeyword pointsModified("PointsModified"); bool checkMeasureValidity = ui.WasEntered("DEFFILE"); ControlNetValidMeasure validator; if (checkMeasureValidity) { Pvl deffile(ui.GetFileName("DEFFILE")); validator = ControlNetValidMeasure(deffile); } SerialNumberList *fromSerials = ui.WasEntered("FROMLIST") ? new SerialNumberList(ui.GetFileName("FROMLIST")) : new SerialNumberList(); ControlNet inNet = ControlNet(ui.GetFileName("CNET")); inNet.SetUserName(Application::UserName()); inNet.SetModifiedDate(iTime::CurrentLocalTime()); //This should be done in ControlNet's Write fn QString retrievalOpt = ui.GetString("RETRIEVAL"); PvlKeyword duplicates("DupSerialNumbers"); if (retrievalOpt == "REFERENCE") { FileList list1(ui.GetFileName("FROMLIST")); SerialNumberList addSerials(ui.GetFileName("ADDLIST")); //Check for duplicate files in the lists by serial number for (int i = 0; i < addSerials.Size(); i++) { // Check for duplicate SNs accross the lists if (fromSerials->HasSerialNumber(addSerials.SerialNumber(i))) { duplicates.addValue(addSerials.FileName(i)); } // Check for duplicate SNs within the addlist for (int j = i + 1; j < addSerials.Size(); j++) { if (addSerials.SerialNumber(i) == addSerials.SerialNumber(j)) { QString msg = "Add list files [" + addSerials.FileName(i) + "] and ["; msg += addSerials.FileName(j) + "] share the same serial number."; throw IException(IException::User, msg, _FILEINFO_); } } } // Get the lat/long coords from the existing reference measure setControlPointLatLon(*fromSerials, inNet); } else { for (int cp = 0; cp < inNet.GetNumPoints(); cp++) { // Get the surface point from the current control point ControlPoint *point = inNet.GetPoint(cp); SurfacePoint surfacePoint = point->GetBestSurfacePoint(); if (!surfacePoint.Valid()) { QString msg = "Unable to retreive lat/lon from Control Point ["; msg += point->GetId() + "]. RETREIVAL=POINT cannot be used unless "; msg += "all Control Points have Latitude/Longitude keywords."; throw IException(IException::User, msg, _FILEINFO_); } g_surfacePoints[point->GetId()] = surfacePoint; } } FileName outNetFile(ui.GetFileName("ONET")); Progress progress; progress.SetText("Adding Images"); progress.SetMaximumSteps(addList.size()); progress.CheckStatus(); STRtree coordTree; QList<ControlPoint *> pointList; bool usePolygon = ui.GetBoolean("POLYGON"); if (usePolygon) { for (int cp = 0; cp < inNet.GetNumPoints(); cp++) { ControlPoint *point = inNet.GetPoint(cp); SurfacePoint surfacePoint = g_surfacePoints[point->GetId()]; Longitude lon = surfacePoint.GetLongitude(); Latitude lat = surfacePoint.GetLatitude(); Coordinate *coord = new Coordinate(lon.degrees(), lat.degrees()); Envelope *envelope = new Envelope(*coord); coordTree.insert(envelope, point); } } else { for (int cp = 0; cp < inNet.GetNumPoints(); cp++) { pointList.append(inNet.GetPoint(cp)); } } // Loop through all the images for (int img = 0; img < addList.size(); img++) { Cube cube; cube.open(addList[img].toString()); Pvl *cubepvl = cube.label(); QString sn = SerialNumber::Compose(*cubepvl); Camera *cam = cube.camera(); // Loop through all the control points QList<ControlPoint *> validPoints = usePolygon ? getValidPoints(cube, coordTree) : pointList; bool imageAdded = false; for (int cp = 0; cp < validPoints.size(); cp++) { ControlPoint *point = validPoints[cp]; // If the point is locked and Apriori source is "AverageOfMeasures" // then do not add the measures. if (point->IsEditLocked() && point->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::AverageOfMeasures) { continue; } if (point->HasSerialNumber(sn)) continue; // Only use the surface point's latitude and longitude, rely on the DEM // for computing the radius. We do this because otherwise we will receive // inconsistent results from successive runs of this program if the // different DEMs are used, or the point X, Y, Z was generated from the // ellipsoid. SurfacePoint surfacePoint = g_surfacePoints[point->GetId()]; if (cam->SetGround( surfacePoint.GetLatitude(), surfacePoint.GetLongitude())) { // Make sure the samp & line are inside the image if (cam->InCube()) { ControlMeasure *newCm = new ControlMeasure(); newCm->SetCoordinate(cam->Sample(), cam->Line(), ControlMeasure::Candidate); newCm->SetAprioriSample(cam->Sample()); newCm->SetAprioriLine(cam->Line()); newCm->SetCubeSerialNumber(sn); newCm->SetDateTime(); newCm->SetChooserName("Application cnetadd"); // Check the measure for DEFFILE validity if (checkMeasureValidity) { if (!validator.ValidEmissionAngle(cam->EmissionAngle())) { //TODO: log that it was Emission Angle that failed the check newCm->SetIgnored(true); } else if (!validator.ValidIncidenceAngle(cam->IncidenceAngle())) { //TODO: log that it was Incidence Angle that failed the check newCm->SetIgnored(true); } else if (!validator.ValidResolution(cam->resolution())) { //TODO: log that it was Resolution that failed the check newCm->SetIgnored(true); } else if (!validator.PixelsFromEdge((int)cam->Sample(), (int)cam->Line(), &cube)) { //TODO: log that it was Pixels from Edge that failed the check newCm->SetIgnored(true); } else { Portal portal(1, 1, cube.pixelType()); portal.SetPosition(cam->Sample(), cam->Line(), 1); cube.read(portal); if (!validator.ValidDnValue(portal[0])) { //TODO: log that it was DN that failed the check newCm->SetIgnored(true); } } } point->Add(newCm); // Point takes ownership // Record the modified Point and Measure g_modifications[point->GetId()].insert(newCm->GetCubeSerialNumber()); newCm = NULL; // Do not delete because the point has ownership if (retrievalOpt == "POINT" && point->GetNumMeasures() == 1) point->SetIgnored(false); imageAdded = true; } } } cubepvl = NULL; cam = NULL; if (log) { PvlKeyword &logKeyword = (imageAdded) ? added : omitted; logKeyword.addValue(addList[img].baseName()); } progress.CheckStatus(); } if (log) { // Add the list of modified points to the output log file QList<QString> modifiedPointsList = g_modifications.keys(); for (int i = 0; i < modifiedPointsList.size(); i++) pointsModified += modifiedPointsList[i]; results.addKeyword(added); results.addKeyword(omitted); results.addKeyword(pointsModified); if (duplicates.size() > 0) { results.addKeyword(duplicates); } results.write(logFile.expanded()); } // List the modified points if (ui.WasEntered("MODIFIEDPOINTS")) { FileName pointList(ui.GetFileName("MODIFIEDPOINTS")); // Set up the output file for writing std::ofstream out_stream; out_stream.open(pointList.expanded().toAscii().data(), std::ios::out); out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file QList<QString> modifiedPointsList = g_modifications.keys(); for (int i = 0; i < modifiedPointsList.size(); i++) out_stream << modifiedPointsList[i].toStdString() << std::endl; out_stream.close(); } // Modify the inNet to only have modified points/measures if (ui.GetString("EXTRACT") == "MODIFIED") { for (int cp = inNet.GetNumPoints() - 1; cp >= 0; cp--) { ControlPoint *point = inNet.GetPoint(cp); // If the point was not modified, delete // Even get rid of edit locked points in this case if (!g_modifications.contains(point->GetId())) { point->SetEditLock(false); inNet.DeletePoint(cp); } // Else, remove the unwanted measures from the modified point else { for (int cm = point->GetNumMeasures() - 1; cm >= 0; cm--) { ControlMeasure *measure = point->GetMeasure(cm); // Even get rid of edit locked measures in this case if (point->GetRefMeasure() != measure && !g_modifications[point->GetId()].contains( measure->GetCubeSerialNumber())) { measure->SetEditLock(false); point->Delete(cm); } } } } } // Generate the TOLIST if wanted if (ui.WasEntered("TOLIST")) { SerialNumberList toList; SerialNumberList addSerials(ui.GetFileName("ADDLIST")); const QList<QString> snList = inNet.GetCubeSerials(); for (int i = 0; i < snList.size(); i++) { QString sn = snList[i]; if (addSerials.HasSerialNumber(sn)) toList.Add(addSerials.FileName(sn)); else if (fromSerials->HasSerialNumber(sn)) toList.Add(fromSerials->FileName(sn)); } IString name(ui.GetFileName("TOLIST")); std::fstream out_stream; out_stream.open(name.c_str(), std::ios::out); out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file for (int f = 0; f < (int) toList.Size(); f++) out_stream << toList.FileName(f) << std::endl; out_stream.close(); } inNet.Write(outNetFile.expanded()); delete fromSerials; }
void IsisMain() { UserInterface &ui = Application::GetUserInterface(); double time0,//start time time1,//end time alti, //altitude of the spacecraftmore fmc, //forward motion compensation rad/sec horV, //horizontal velocity km/sec radV, //radial velocity km/sec rollV,//roll speed in rad/sec led; //line exposure duration in seconds Cube panCube; iTime isisTime; QString iStrTEMP; int i,j,k,scFrameCode,insCode; QString mission; SpicePosition *spPos; SpiceRotation *spRot; //int nlines,nsamples,nbands; double deg2rad = acos(-1.0)/180.0; ProcessImport jp; FileName transFile("$apollo15/translations/apollopantranstable.trn"); PvlTranslationTable transTable(transFile); PvlGroup kernels_pvlG; //scFrameCode and insCode from user input mission = ui.GetString("MISSION"); if (mission == "APOLLO12") scFrameCode = -912000; if (mission == "APOLLO14") scFrameCode = -914000; if (mission == "APOLLO15") scFrameCode = -915000; if (mission == "APOLLO16") scFrameCode = -916000; if (mission == "APOLLO17") scFrameCode = -917000; insCode = scFrameCode - 230; try { panCube.open(ui.GetFileName("FROM"),"rw"); } catch (IException &e) { throw IException(IException::User, "Unable to open the file [" + ui.GetFileName("FROM") + "] as a cube.", _FILEINFO_); } ////////////////////////////////////////////build the cube header instrament group PvlGroup inst_pvlG("Instrument"); PvlKeyword keyword; //four that are the same for every panaramic mission keyword.setName("SpacecraftName"); keyword.setValue(mission); inst_pvlG.addKeyword(keyword); keyword.setName("InstrumentName"); keyword.setValue(transTable.Translate("InstrumentName","whatever")); inst_pvlG.addKeyword(keyword); keyword.setName("InstrumentId"); keyword.setValue(transTable.Translate("InstrumentId","whatever")); inst_pvlG.addKeyword(keyword); keyword.setName("TargetName"); keyword.setValue(transTable.Translate("TargetName","whatever")); inst_pvlG.addKeyword(keyword); //three that need to be calculated from input values horV = ui.GetDouble("VEL_HORIZ"); radV = ui.GetDouble("VEL_RADIAL"); alti = ui.GetDouble("CRAFT_ALTITUDE"); //caculate the LineExposureDuration (led) if( ui.WasEntered("V/H_OVERRIDE") ) fmc = ui.GetDouble("V/H_OVERRIDE")/1000.0; else //forward motion compensation is directly equivalent to V/H fmc = sqrt(horV*horV + radV*radV)/alti; rollV = fmc*ROLLC; //roll angular velcoity is equal to V/H * constant (units rad/sec) //led = rad/mm * sec/rad = radians(2.5)/FIDL / rollV (final units: sec/mm) led = (2.5*acos(-1.0)/180.0)/rollV/FIDL; //use led and the number of mm to determine the start and stop times isisTime = ui.GetString("GMT"); //calculate starting and stoping times time0 = isisTime.Et() - led*FIDL*21.5; time1 = time0 + led*FIDL*43; isisTime = time0; keyword.setName("StartTime"); keyword.setValue(iStrTEMP=isisTime.UTC()); inst_pvlG.addKeyword(keyword); isisTime = time1; keyword.setName("StopTime"); keyword.setValue(iStrTEMP=isisTime.UTC()); inst_pvlG.addKeyword(keyword); keyword.setName("LineExposureDuration"); //converted led to msec/mm--negative sign to account for the anti-parallel time and line axes keyword.setValue(iStrTEMP=toString(-led),"sec/mm"); inst_pvlG.addKeyword(keyword); panCube.putGroup(inst_pvlG); ///////////////////////////////////The kernals group kernels_pvlG.setName("Kernels"); kernels_pvlG.clear(); keyword.setName("NaifFrameCode"); keyword.setValue(toString(insCode)); kernels_pvlG.addKeyword(keyword); keyword.setName("LeapSecond"); keyword.setValue( transTable.Translate("LeapSecond","File1") ); kernels_pvlG.addKeyword(keyword); keyword.setName("TargetAttitudeShape"); keyword.setValue( transTable.Translate("TargetAttitudeShape", "File1") ); keyword.addValue( transTable.Translate("TargetAttitudeShape", "File2") ); keyword.addValue( transTable.Translate("TargetAttitudeShape", "File3") ); kernels_pvlG.addKeyword(keyword); keyword.setName("TargetPosition"); keyword.setValue("Table"); keyword.addValue( transTable.Translate("TargetPosition", "File1") ); keyword.addValue( transTable.Translate("TargetPosition", "File2") ); kernels_pvlG.addKeyword(keyword); keyword.setName("ShapeModel"); keyword.setValue( transTable.Translate("ShapeModel", "File1") ); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentPointing"); keyword.setValue("Table"); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentPosition"); keyword.setValue("Table"); kernels_pvlG.addKeyword(keyword); keyword.setName("InstrumentAddendum"); keyword.setValue( transTable.Translate("InstrumentAddendum",mission)); kernels_pvlG.addKeyword(keyword); panCube.putGroup(kernels_pvlG); //Load all the kernals Load_Kernel(kernels_pvlG["TargetPosition"]); Load_Kernel(kernels_pvlG["TargetAttitudeShape"]); Load_Kernel(kernels_pvlG["LeapSecond"]); //////////////////////////////////////////attach a target rotation table char frameName[32]; SpiceInt frameCode; SpiceBoolean found; //get the framecode from the body code (301=MOON) cidfrm_c(301, sizeof(frameName), &frameCode, frameName, &found); if(!found) { QString naifTarget = QString("IAU_MOOM"); namfrm_c(naifTarget.toAscii().data(), &frameCode); if(frameCode == 0) { QString msg = "Can not find NAIF code for [" + naifTarget + "]"; throw IException(IException::Io, msg, _FILEINFO_); } } spRot = new SpiceRotation(frameCode); //create a table from starttime to endtime (streched by 3%) with NODES entries spRot->LoadCache(time0-0.015*(time1-time0), time1+0.015*(time1-time0), NODES); Table tableTargetRot = spRot->Cache("BodyRotation"); tableTargetRot.Label() += PvlKeyword("Description", "Created by apollopaninit"); panCube.write(tableTargetRot); //////////////////////////////////////////////////attach a sun position table spPos = new SpicePosition(10,301); //Position of the sun (10) WRT to the MOON (301) //create a table from starttime to endtime (stretched by 3%) with NODES entries spPos->LoadCache(time0-0.015*(time1-time0), time1+0.015*(time1-time0), NODES); Table tableSunPos = spPos->Cache("SunPosition"); tableSunPos.Label() += PvlKeyword("SpkTableStartTime", toString(time0-0.015*(time1-time0))); tableSunPos.Label() += PvlKeyword("SpkTablleEndTime", toString(time1+0.015*(time1-time0))); tableSunPos.Label() += PvlKeyword("Description", "Created by apollopaninit"); panCube.write(tableSunPos); //attach the table to the cube /////////////Finding the principal scan line position and orientation //get the radii of the MOON SpiceInt tempRadii = 0; bodvcd_c(301,"RADII",3,&tempRadii,R_MOON); //units are km double omega,phi,kappa; std::vector<double> posSel; //Seleno centric position std::vector<double> sunPos; //sunPosition used to transform to J2000 std::vector<double> posJ20; //camera position in J2000 posSel.resize(3); sunPos.resize(3); posJ20.resize(3); double temp, vel[3] = { 0.0, 0.0, 0.0 }, //the total velocity vector (combined Horizonatal and normal components) // in km/sec M[3][3] = { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } }, //rotation matrix zDir[] = { 0.0, 0.0, 1.0 }, //selenographic Z axis northPN[3] = { 0.0, 0.0, 0.0 }, //normal to the plane containing all the north/south directions, // that is plane containing // the origin, the z axis, and the primary point of intersection northL[3] = { 0.0, 0.0, 0.0 }, //north direction vector in local horizontal plane azm[3] = { 0.0, 0.0, 0.0 }, //azm direction of the veclocity vector in selenographic coordinates azmP[3] = { 0.0, 0.0, 0.0 }, //azm rotated (partially) and projected into the image plane norm[3] = { 0.0, 0.0, 0.0 }, //normal to the local horizontal plane look[3] = { 0.0, 0.0, 0.0 }; //unit direction vector in the pincipal cameral look direction, // parallel to the vector from the center of the moon through the spacecraft double pos0[3] = { 0.0, 0.0, 0.0 }, //coordinate of the camera position pInt[3] = { 0.0, 0.0, 0.0 }; //coordinate of the principle intersection point /////////////////calculating the camera position for the center (principal scan line) pos0[1] = ui.GetDouble("LON_NADIR")*deg2rad; pos0[0] = ui.GetDouble("LAT_NADIR")*deg2rad; pos0[2] = ui.GetDouble("CRAFT_ALTITUDE"); //units are km Geographic2GeocentricLunar(pos0,pos0); //function is written so the input can also be the // output /////////////////////calculating the camera orientation for the center (principal) scan line pInt[1] = ui.GetDouble("LON_INT")*deg2rad; pInt[0] = ui.GetDouble("LAT_INT")*deg2rad; pInt[2] = 0.0; Geographic2GeocentricLunar(pInt,pInt); //function is written so the input can also be the output //calculate the unit look direction vector in object space look[0] = -pos0[0] + pInt[0]; look[1] = -pos0[1] + pInt[1]; look[2] = -pos0[2] + pInt[2]; temp = sqrt(look[0]*look[0] + look[1]*look[1] + look[2]*look[2]); look[0] /= temp; look[1] /= temp; look[2] /= temp; //the local normal vector is equal to pInt0/|pInt0| temp = sqrt(pInt[0]*pInt[0] + pInt[1]*pInt[1] + pInt[2]*pInt[2]); norm[0] = pInt[0]/temp; norm[1] = pInt[1]/temp; norm[2] = pInt[2]/temp; //omega and phi are defined so that M(phi)M(omega)look = [0 0 -1] leaving only the roation // around z axis to be found omega = -atan2(look[1], look[2]); //omega rotation to zero look[1] phi = atan2(-look[0], sin(omega)*look[1] - cos(omega)*look[2]); //phi rotation to zero look[0] //use the horizontal velocity vector direction to solve for the last rotation; we will make the // image x axis parallel to the in-image-plane projection of the horizontal direction of flight. // The local normal cross the selenogrpahic z gives northPN (normal to the plane containing all // the north/south directions), that is, the plane containing the origin, the z axis, and the // primary point of intersection. crossp(northPN,norm,northL); //The normal to the plane containing all the north/south directions cross the local normal // direction gives the local north/south direction in the local normal plane crossp(norm, zDir, northPN); if (northL[2] < 0) { //if by chance we got the south direction change the signs northL[0] = -northL[0]; northL[1] = -northL[1]; northL[2] = -northL[2]; } //define the rotation matrix to convert northL to the azimuth of flight. // A left handed rotation of "VEL_AZM" around the positive normal direction will convert northL // to azm MfromVecLeftAngle(M,norm,ui.GetDouble("VEL_AZM")*deg2rad); azm[0] = M[0][0]*northL[0] + M[0][1]*northL[1] + M[0][2]*northL[2]; azm[1] = M[1][0]*northL[0] + M[1][1]*northL[1] + M[1][2]*northL[2]; azm[2] = M[2][0]*northL[0] + M[2][1]*northL[1] + M[2][2]*northL[2]; //apply the two rotations we already know MfromLeftEulers(M,omega,phi,0.0); azmP[0] = M[0][0]*azm[0] + M[0][1]*azm[1] + M[0][2]*azm[2]; azmP[1] = M[1][0]*azm[1] + M[1][1]*azm[1] + M[1][2]*azm[2]; azmP[2] = M[2][0]*azm[2] + M[2][1]*azm[1] + M[2][2]*azm[2]; //subtract that portion of the azm that is perpindicular to the image plane (also the portion // which is parallel to look) making azm a vector parrallel to the image plane // Further, since we're now rotated into some coordinate system that differs from // the image coordinate system by only a kappa rotation making the vector parrallel to the // image plan is as simple as zeroing the z component (and as pointless to further calculations // as a nat's fart in hurricane) nevertheless it completes the logical transition azmP[2] = 0.0; //finally the kappa rotation that will make azmP parallel (including sign) to the camera x axis kappa = -atan2(-azmP[1], azmP[0]); ////////////////////Add an instrument position table //Define the table records TableRecord recordPos; // reacord to be added to table // add x,y,z position labels and ephemeris time et to record TableField x("J2000X", TableField::Double); TableField y("J2000Y", TableField::Double); TableField z("J2000Z", TableField::Double); TableField t("ET", TableField::Double); recordPos += x; recordPos += y; recordPos += z; recordPos += t; Table tablePos("InstrumentPosition", recordPos); //now that the azm and norm vectors are defined // the total velocity vector can be calcualted (km/sec) vel[0] = horV*azm[0] + radV * norm[0]; vel[1] = horV*azm[1] + radV * norm[1]; vel[2] = horV*azm[2] + radV * norm[2]; //we'll provide a two ellement table (more is redundant because the motion is modeled as linear // at this point) we'll extend the nodes 3% beyond the edges of the images to be sure // rounding errors don't cause problems temp = 0.515*(time1-time0); //3% extension posSel[0] = pos0[0] - temp*vel[0]; //selenocentric coordinate calculation posSel[1] = pos0[1] - temp*vel[1]; posSel[2] = pos0[2] - temp*vel[2]; //converting to J2000 temp = time0 - 0.005*(time1-time0); //et just before the first scan line spPos->SetEphemerisTime(temp); spRot->SetEphemerisTime(temp); //Despite being labeled as J2000, the coordinates for the instrument position are in fact in // target centric coordinated rotated to a system centered at the target with aces parallel // to J2000, whatever that means posJ20 = spRot->J2000Vector(posSel); //J2000Vector calls rotates the position vector into J2000, // completing the transformation recordPos[0] = posJ20[0]; recordPos[1] = posJ20[1]; recordPos[2] = posJ20[2]; recordPos[3] = temp; //temp = et (right now anyway) tablePos += recordPos; tablePos.Label() += PvlKeyword("SpkTableStartTime",toString(temp)); //now the other node temp = 0.515*(time1-time0); //3% extension posSel[0] = pos0[0] + temp*vel[0]; //selenocentric coordinate calculation posSel[1] = pos0[1] + temp*vel[1]; posSel[2] = pos0[2] + temp*vel[2]; //converting to J2000 temp = time1 + 0.015*(time1-time0); //et just after the last scan line spPos->SetEphemerisTime(temp); spRot->SetEphemerisTime(temp); //Despite being labeled as J2000, the coordinates for the instrument position are in fact // in target centric coordinated rotated to a system centered at the target with aces // parallel to J2000, whatever that means posJ20 = spRot->J2000Vector(posSel); //J2000Vector calls rotates the position vector into J2000, // completing the transformation recordPos[0] = posJ20[0]; recordPos[1] = posJ20[1]; recordPos[2] = posJ20[2]; recordPos[3] = temp; //temp = et (right now anyway) tablePos += recordPos; tablePos.Label() += PvlKeyword("SpkTableEndTime",toString(temp)); tablePos.Label() += PvlKeyword("CacheType","Linear"); tablePos.Label() += PvlKeyword("Description","Created by apollopaninit"); panCube.write(tablePos); //now attach it to the table /////////////////////////////attach a camera pointing table double cacheSlope, //time between epoches in the table rollComb, //magnitude of roll relative to the center in the middle of the epoch relT, //relative time at the center of each epoch Q[NODES][5], //NODES four ellement unit quarternions and et (to be calculated). gimVec[3], //the direction of the gimbal rotation vector (to the cameras persepective // this is always changing because the camera is mounted to the roll frame // assembly which is mounted to the gimbal) M0[3][3], //rotation matrix of the previous epoch Mtemp1[3][3], //intermediate step in the multiplication of rotation matricies Mtemp2[3][3], //intermediate step in the multiplication of rotation matricies Mdg[3][3], //incremental rotation due the the gimbal motion in the camera frame Mdr[3][3]; //the contribution of the roll motion in the camera frame during time // cacheSlope std::vector <double> M_J2toT; //rotation matrix from J2000 to the target frame M_J2toT.resize(9); //Table Definition TableField q0("J2000Q0", TableField::Double); TableField q1("J2000Q1", TableField::Double); TableField q2("J2000Q2", TableField::Double); TableField q3("J2000Q3", TableField::Double); TableField et("ET", TableField::Double); TableRecord recordRot; recordRot += q0; recordRot += q1; recordRot += q2; recordRot += q3; recordRot += et; Table tableRot("InstrumentPointing",recordRot); //From the cameras perspective the gimbal motion is around a constantly changing axis, // this is handled by combining a series of incremental rotations MfromLeftEulers(M0, omega, phi, kappa); //rotation matrix in the center Q[(NOPDES-1)/2] spRot->SetEphemerisTime(isisTime.Et()); M_J2toT = spRot->Matrix(); //this actually gives the rotation from J2000 to target centric for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[(NODES-1)/2]); //save the middle scan line quarternion Q[(NODES-1)/2][4] = (time1 + time0)/2.0; //time in the center of the image //the total time is scaled up slightly so that nodes will extend just beyond the edge of the image cacheSlope = 1.03*(time1 - time0)/(NODES-1); //Mdr is constant for all the forward time computations MfromLeftEulers(Mdr,cacheSlope*rollV,0.0,0.0); for (i=(NODES-1)/2+1; i<NODES; i++) { //moving foward in time first Q[i][4] = Q[i-1][4] + cacheSlope; //new time epoch //epoch center time relative to the center line relT = double(i - (NODES-1)/2 - 0.5)*cacheSlope; rollComb = relT*rollV; gimVec[0] = 0.0; //gimbal rotation vector direction in the middle of the epoch gimVec[1] = cos(rollComb); gimVec[2] = -sin(rollComb); //incremental rotation due to the gimbal (forward motion compensation) MfromVecLeftAngle(Mdg, gimVec, fmc*cacheSlope); //the new rotation matrix is Transpose(Mdr)*Transpose(Mdg)*M0--NOTE the order swap and // transposes are needed because both Mdr and Mdg were caculated in image space and need to be // transposed to apply to object space mtxm_c(Mdg, M0, Mtemp1); //M0 is now what would typically be considered the rotation matrix of an image. It rotates a // vector from the target centric space into camera space. However, what is standard to // include in the cube labels is a rotation from camera space to J2000. M0 is therefore the // transpose of the first part of this rotation. Transpose(M0) is the rotation from camera // space to target centric space mtxm_c(Mdr, Mtemp1, M0); //now adding the rotation from the target frame to J2000 spRot->SetEphemerisTime(Q[i][4]); //this actually gives the rotation from J2000 to target centric--hence the mxmt_c function being // used later M_J2toT = spRot->Matrix(); for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[i]); //convert to a quarterion } MfromLeftEulers(M0, omega, phi, kappa); //rotation matrix in the center Q[(NOPDES-1)/2] //Mdr is constant for all the backward time computations MfromLeftEulers(Mdr, -cacheSlope*rollV, 0.0, 0.0); for (i=(NODES-1)/2-1; i>=0; i--) { //moving backward in time Q[i][4] = Q[i+1][4] - cacheSlope; //new time epoch //epoch center time relative to the center line relT = double(i - (NODES-1)/2 + 0.5)*cacheSlope; rollComb = relT*rollV; gimVec[0] = 0.0; //gimbal rotation vector direction in the middle of the epoch gimVec[1] = cos(rollComb); gimVec[2] = -sin(rollComb); //incremental rotation due to the gimbal (forward motion compensation) MfromVecLeftAngle(Mdg, gimVec, -fmc*cacheSlope); //the new rotation matrix is Transpose(Mdr)*Transpose(Mdg)*M0 NOTE the order swap and // transposes are needed because both Mdr and Mdg were caculated in image space and need to be // transposed to apply to object space mtxm_c(Mdg, M0, Mtemp1); //M0 is now what would typically be considered the rotation matrix of an image. It rotates a // vector from the target centric space into camera space. However, what is standard to // include in the cube labels is a rotation from camera space to J2000. M0 is therefore the // transpose of the first part of this rotation. Transpose(M0) is the rotation from camera // space to target centric space mtxm_c(Mdr, Mtemp1, M0); //now adding the rotation from the target frame to J2000 spRot->SetEphemerisTime(Q[i][4]); M_J2toT = spRot->Matrix(); for(j=0; j<3; j++) //reformating M_J2toT to a 3x3 for(k=0; k<3; k++) Mtemp1[j][k] = M_J2toT[3*j+k]; mxm_c(M0, Mtemp1, Mtemp2); M2Q(Mtemp2, Q[i]); //convert to a quarterion } //fill in the table for (i=0; i<NODES; i++) { recordRot[0] = Q[i][0]; recordRot[1] = Q[i][1]; recordRot[2] = Q[i][2]; recordRot[3] = Q[i][3]; recordRot[4] = Q[i][4]; tableRot += recordRot; } tableRot.Label() += PvlKeyword("CkTableStartTime", toString(Q[0][4])); tableRot.Label() += PvlKeyword("CkTableEndTime", toString(Q[NODES-1][4])); tableRot.Label() += PvlKeyword("Description", "Created by appollopan2isis"); keyword.setName("TimeDependentFrames"); keyword.setValue(toString(scFrameCode)); keyword.addValue("1"); tableRot.Label() += keyword; keyword.setName("ConstantFrames"); keyword.setValue(toString(insCode)); keyword.addValue(toString(scFrameCode)); tableRot.Label() += keyword; keyword.setName("ConstantRotation"); keyword.setValue("1"); for (i=1;i<9;i++) if (i%4 == 0) keyword.addValue("1"); else keyword.addValue("0"); tableRot.Label() += keyword; panCube.write(tableRot); /////////////////////////Attach a table with all the measurements of the fiducial mark locations. Chip patternS,searchS; //scaled pattern and search chips Cube fidC; //Fiducial image //line and sample coordinates for looping through the panCube double l=1,s=1,sample,line,sampleInitial=1,lineInitial=1,play; int regStatus, fidn, panS, refL, //number of lines in the patternS refS; //number of samples in the patternS Pvl pvl; bool foundFirst=false; QString fileName; panS = panCube.sampleCount(); //Table definition TableRecord recordFid; TableField indexFid("FID_INEX",TableField::Integer); TableField xFid("X_COORD",TableField::Double); TableField yFid("Y_COORD",TableField::Double); recordFid += indexFid; recordFid += xFid; recordFid += yFid; Table tableFid("Fiducial Measurement",recordFid); //read the image resolutions and scale the constants acordingly double resolution = ui.GetDouble("MICRONS"), //pixel size in microns scale = SCALE *5.0/resolution, //reduction scale for fast autoregistrations searchHeight = SEARCHh*5.0/resolution, //number of lines (in 5-micron-pixels) in // search space for the first fiducial searchCellSize = SEARCHc*5.0/resolution, //height/width of search chips block averageSamples = AVERs *5.0/resolution, //scaled smaples between fiducials averageLines = AVERl *5.0/resolution; //scaled average distance between the top and //bottom fiducials if( 15.0/resolution < 1.5) play=1.5; else play = 15.0/resolution; //copy the patternS chip (the entire ApolloPanFiducialMark.cub) FileName fiducialFileName("$apollo15/calibration/ApolloPanFiducialMark.cub"); fidC.open(fiducialFileName.expanded(),"r"); if( !fidC.isOpen() ) { QString msg = "Unable to open the fiducial patternS cube: ApolloPanFiducialMark.cub\n"; throw IException(IException::User, msg, _FILEINFO_); } refL = fidC.lineCount(); refS = fidC.sampleCount(); //scaled pattern chip for fast matching patternS.SetSize(int((refS-2)/SCALE), int((refL-2)/SCALE)); patternS.TackCube((refS-1)/2, (refL-1)/2); patternS.Load(fidC, 0, SCALE); //parameters for maximum correlation autoregestration // see: file:///usgs/pkgs/isis3nightly2011-09-21/isis/doc/documents/patternSMatch/patternSMatch.html#DistanceTolerance FileName fiducialPvl("$apollo15/templates/apolloPanFiducialFinder.pvl"); pvl.read(fiducialPvl.expanded()); //read in the autoreg parameters AutoReg *arS = AutoRegFactory::Create(pvl); *arS->PatternChip() = patternS; //patternS chip is constant //set up a centroid measurer CentroidApolloPan centroid(resolution); Chip inputChip,selectionChip; inputChip.SetSize(int(ceil(200*5.0/resolution)), int(ceil(200*5.0/resolution))); fileName = ui.GetFileName("FROM"); if( panCube.pixelType() == 1) //UnsignedByte centroid.setDNRange(12, 1e99); //8 bit bright target else centroid.setDNRange(3500, 1e99); //16 bit bright target Progress progress; progress.SetText("Locating Fiducials"); progress.SetMaximumSteps(91); //Search for the first fiducial, search sizes are constanst searchS.SetSize(int(searchCellSize/scale),int(searchCellSize/scale)); //now start searching along a horizontal line for the first fiducial mark for(l = searchCellSize/2; l<searchHeight+searchCellSize/2.0 && !foundFirst; l+=searchCellSize-125*5.0/resolution) { for (s = searchCellSize/2; s < averageSamples + searchCellSize/2.0 && !foundFirst; s += searchCellSize-125*5.0/resolution) { searchS.TackCube(s, l); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); //continuous dynamic range selection centroid.selectAdaptive(&inputChip, &selectionChip); //elliptical trimming/smoothing if (centroid.elipticalReduction(&selectionChip, 95, play, 2000)) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); sampleInitial = inputChip.CubeSample(); lineInitial = inputChip.CubeLine(); foundFirst = true; //once the first fiducial is found stop } } } } if(s>=averageLines+searchCellSize/2.0) { QString msg = "Unable to locate a fiducial mark in the input cube [" + fileName + "]. Check FROM and MICRONS parameters."; throw IException(IException::Io, msg, _FILEINFO_); return; } progress.CheckStatus(); //record first fiducial measurement in the table recordFid[0] = 0; recordFid[1] = sampleInitial; recordFid[2] = lineInitial; tableFid += recordFid; for (s= sampleInitial, l=lineInitial, fidn=0; s<panS; s+=averageSamples, fidn++) { //corrections for half spacing of center fiducials if (fidn == 22) s -= averageSamples/2.0; if (fidn == 23) s -= averageSamples/2.0; //look for the bottom fiducial searchS.TackCube(s,l+averageLines); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube,0,1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); } else { //if autoreg is unsuccessful, a larger window will be used inputChip.TackCube(s, l+averageLines); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(s, l+averageLines); } centroid.selectAdaptive(&inputChip, &selectionChip); //continuous dynamic range selection //elliptical trimming/smoothing... if this fails move on if (centroid.elipticalReduction(&selectionChip, 95, play, 2000) != 0 ) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); sample = inputChip.CubeSample(); line = inputChip.CubeLine(); recordFid[0] = fidn*2+1; recordFid[1] = sample; recordFid[2] = line; tableFid += recordFid; } progress.CheckStatus(); //look for the top fiducial if (s == sampleInitial) //first time through the loop? continue; //then the top fiducial was already found searchS.TackCube(s, l); searchS.Load(panCube, 0, scale); *arS->SearchChip() = searchS; regStatus = arS->Register(); if (regStatus == AutoReg::SuccessPixel) { inputChip.TackCube(arS->CubeSample(), arS->CubeLine()); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(arS->CubeSample(), arS->CubeLine()); } else { //if autoreg is unsuccessful, a larger window will be used inputChip.TackCube(s, l); inputChip.Load(panCube, 0, 1); inputChip.SetCubePosition(s, l); } centroid.selectAdaptive(&inputChip, &selectionChip);//continuous dynamic range selection //inputChip.Write("inputTemp.cub");//debug //selectionChip.Write("selectionTemp.cub");//debug //elliptical trimming/smoothing... if this fails move on if (centroid.elipticalReduction(&selectionChip, 95, play, 2000) !=0) { //center of mass to reduce selection to a single measure centroid.centerOfMass(&selectionChip, &sample, &line); inputChip.SetChipPosition(sample, line); //when finding the top fiducial both s and l are refined for a successful measurement, // this will help follow trends in the scaned image s = inputChip.CubeSample(); l = inputChip.CubeLine(); recordFid[0] = fidn*2; recordFid[1] = s; recordFid[2] = l; tableFid += recordFid; } progress.CheckStatus(); } panCube.write(tableFid); //close the new cube panCube.close(false); panCube.open(ui.GetFileName("FROM"),"rw"); delete spPos; delete spRot; //now instantiate a camera to make sure all of this is working ApolloPanoramicCamera* cam = (ApolloPanoramicCamera*)(panCube.camera()); //log the residual report from interior orientation PvlGroup residualStats("InteriorOrientationStats"); residualStats += PvlKeyword("FiducialsFound", toString(tableFid.Records())); residualStats += PvlKeyword("ResidualMax", toString(cam->intOriResidualMax()),"pixels"); residualStats += PvlKeyword("ResidualMean", toString(cam->intOriResidualMean()),"pixels"); residualStats += PvlKeyword("ResidualStdev", toString(cam->intOriResidualStdev()),"pixels"); Application::Log( residualStats ); return; }
/** The ISIS smtk main application */ void IsisMain() { UserInterface &ui = Application::GetUserInterface(); // Open the first cube. It is the left hand image. Cube lhImage; CubeAttributeInput &attLeft = ui.GetInputAttribute("FROM"); vector<QString> bandLeft = attLeft.bands(); lhImage.setVirtualBands(bandLeft); lhImage.open(ui.GetFileName("FROM"),"r"); // Open the second cube, it is geomertricallty altered. We will be matching the // first to this one by attempting to compute a sample/line offsets Cube rhImage; CubeAttributeInput &attRight = ui.GetInputAttribute("MATCH"); vector<QString> bandRight = attRight.bands(); rhImage.setVirtualBands(bandRight); rhImage.open(ui.GetFileName("MATCH"),"r"); // Ensure only single bands if (lhImage.bandCount() != 1 || rhImage.bandCount() != 1) { QString msg = "Input Cubes must have only one band!"; throw IException(IException::User,msg,_FILEINFO_); } // Both images must have a Camera and can also have a Projection. We will // only deal with a Camera, however as a projected, non-mosaicked image // uses a Projection internal to the Camera object. Camera *lhCamera = NULL; Camera *rhCamera = NULL; try { lhCamera = lhImage.camera(); rhCamera = rhImage.camera(); } catch (IException &ie) { QString msg = "Both input images must have a camera"; throw IException(ie, IException::User, msg, _FILEINFO_); } // Since we are generating a DEM, we must turn off any existing // DEM that may have been initialized with spiceinit. lhCamera->IgnoreElevationModel(true); rhCamera->IgnoreElevationModel(true); // Get serial number QString serialLeft = SerialNumber::Compose(lhImage, true); QString serialRight = SerialNumber::Compose(rhImage, true); // This still precludes band to band registrations. if (serialLeft == serialRight) { QString sLeft = FileName(lhImage.fileName()).name(); QString sRight = FileName(rhImage.fileName()).name(); if (sLeft == sRight) { QString msg = "Cube Serial Numbers must be unique - FROM=" + serialLeft + ", MATCH=" + serialRight; throw IException(IException::User,msg,_FILEINFO_); } serialLeft = sLeft; serialRight = sRight; } Progress prog; prog.SetText("Finding Initial Seeds"); int nl = lhImage.lineCount(); int ns = lhImage.sampleCount(); BigInt numAttemptedInitialPoints = 0; // Declare Gruen matcher SmtkMatcher matcher(ui.GetFileName("REGDEF"), &lhImage, &rhImage); // Get line/sample linc/sinc parameters int space = ui.GetInteger("SPACE"); int linc (space), sinc(space); // Do we have a seed points from a control net file? bool useseed = ui.WasEntered("CNET"); // Base points on an input cnet SmtkQStack gstack; double lastEigen(0.0); if (useseed) { ControlNet cnet(ui.GetFileName("CNET")); prog.SetMaximumSteps(cnet.GetNumPoints()); prog.CheckStatus(); gstack.reserve(cnet.GetNumPoints()); for (int cpIndex = 0; cpIndex < cnet.GetNumPoints(); cpIndex ++) { ControlPoint *cp = cnet.GetPoint(cpIndex); if (!cp->IsIgnored()) { ControlMeasure *cmLeft(0), *cmRight(0); for(int cmIndex = 0; cmIndex < cp->GetNumMeasures(); cmIndex ++) { ControlMeasure *cm = cp->GetMeasure(cmIndex); if (!cm->IsIgnored()) { if (cm->GetCubeSerialNumber() == serialLeft) cmLeft = cp->GetMeasure(cmIndex); if (cm->GetCubeSerialNumber() == serialRight) cmRight = cp->GetMeasure(cmIndex); } } // If we have both left and right images in the control point, save it if ( (cmLeft != 0) && (cmRight != 0) ) { Coordinate left = Coordinate(cmLeft->GetLine(), cmLeft->GetSample()); Coordinate right = Coordinate(cmRight->GetLine(), cmRight->GetSample()); SmtkPoint spnt = matcher.Create(left, right); // Insert the point (unregistered) if ( spnt.isValid() ) { int line = (int) cmLeft->GetLine(); int samp = (int) cmLeft->GetSample(); matcher.isValid(spnt); gstack.insert(qMakePair(line, samp), spnt); lastEigen = spnt.GoodnessOfFit(); } } } prog.CheckStatus(); } } else { // We want to create a grid of control points that is N rows by M columns. int rows = (lhImage.lineCount() + linc - 1)/linc; int cols = (lhImage.sampleCount() + sinc - 1)/sinc; prog.SetMaximumSteps(rows * cols); prog.CheckStatus(); // First pass stack and eigen value statistics SmtkQStack fpass; fpass.reserve(rows * cols); Statistics temp_mev; // Loop through grid of points and get statistics to compute // initial set of points for (int line = linc / 2 + 1; line < nl; line += linc) { for (int samp = sinc / 2 + 1 ; samp < ns; samp += sinc) { numAttemptedInitialPoints ++; SmtkPoint spnt = matcher.Register(Coordinate(line,samp)); if ( spnt.isValid() ) { matcher.isValid(spnt); fpass.insert(qMakePair(line, samp), spnt); temp_mev.AddData(spnt.GoodnessOfFit()); } prog.CheckStatus(); } } // Now select a subset of fpass points as the seed points cout << "Number of Potential Seed Points: " << fpass.size() << "\n"; cout << "Min / Max Eigenvalues Matched: " << temp_mev.Minimum() << ", " << temp_mev.Maximum() << "\n"; // How many seed points are requested double nseed = ui.GetDouble("NSEED"); int inseed; if (nseed >= 1.0) inseed = (int) nseed; else if (nseed > 0.0) inseed = (int) (nseed * (double) (fpass.size())); else inseed = (int) ((double) (fpass.size()) * 0.05); double seedsample = ui.GetDouble("SEEDSAMPLE"); // Generate a new stack gstack.reserve(inseed); while ((gstack.size() < inseed) && (!fpass.isEmpty() )) { SmtkQStack::iterator bestm; if (seedsample <= 0.0) { bestm = matcher.FindSmallestEV(fpass); } else { bestm = matcher.FindExpDistEV(fpass, seedsample, temp_mev.Minimum(), temp_mev.Maximum()); } // Add point to stack if (bestm != fpass.end()) { Coordinate right = bestm.value().getRight(); matcher.isValid(bestm.value()); gstack.insert(bestm.key(), bestm.value()); lastEigen = bestm.value().GoodnessOfFit(); fpass.erase(bestm); } } // If a user wants to see the seed network, write it out here if (ui.WasEntered("OSEEDNET")) { WriteCnet(ui.GetFileName("OSEEDNET"), gstack, lhCamera->target()->name(), serialLeft, serialRight); } } /////////////////////////////////////////////////////////////////////// // All done with seed points. Sanity check ensures we actually found // some. /////////////////////////////////////////////////////////////////////// if (gstack.size() <= 0) { QString msg = "No seed points found - may need to check Gruen parameters."; throw IException(IException::User, msg, _FILEINFO_); } // Report seed point status if (!useseed) { cout << "Number of Seed Points used: " << gstack.size() << "\n"; cout << "EV of last Seed Point: " << lastEigen << "\n"; } else { cout << "Number of Manual Seed Points: " << gstack.size() << "\n"; } // Use seed points (in stack) to grow SmtkQStack bmf; bmf.reserve(gstack.size()); // Probably need much more but for starters... BigInt numOrigPoints = gstack.size(); BigInt passpix2 = 0; int subcbox = ui.GetInteger("SUBCBOX"); int halfBox((subcbox-1)/2); while (!gstack.isEmpty()) { SmtkQStackIter cstack = matcher.FindSmallestEV(gstack); // Print number on stack if ((gstack.size() % 1000) == 0) { cout << "Number on Stack: " << gstack.size() << ". " << cstack.value().GoodnessOfFit() << "\n"; } // Test to see if already determined SmtkQStackIter bmfPt = bmf.find(cstack.key()); if (bmfPt == bmf.end()) { // Its not in the final stack, process it // Retrieve the point SmtkPoint spnt = cstack.value(); // Register if its not already registered if (!spnt.isRegistered()) { spnt = matcher.Register(spnt, spnt.getAffine()); } // Still must check for validity if the point was just registered, // otherwise should be good if ( spnt.isValid() ) { passpix2++; bmf.insert(cstack.key(), spnt); // inserts (0,0) offset excluded below int line = cstack.key().first; int sample = cstack.key().second; // Determine match points double eigen(spnt.GoodnessOfFit()); for (int sampBox = -halfBox ; sampBox <= halfBox ; sampBox++ ) { int csamp = sample + sampBox; for (int lineBox = -halfBox ; lineBox <= halfBox ; lineBox++) { int cline = line + lineBox; if ( !( (sampBox == 0) && (lineBox == 0)) ) {// Already added above SmtkQPair dupPair(cline, csamp); SmtkQStackIter temp = bmf.find(dupPair); SmtkPoint bmfpnt; if (temp != bmf.end()) { if (temp.value().GoodnessOfFit() > eigen) { // Create cloned point with better fit bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } } else { // ISIS2 is BMF(SAMP,LINE,7) .EQ VALID_MAX4) // Clone new point for insert bmfpnt = matcher.Clone(spnt, Coordinate(cline,csamp)); } // Add if good point if (bmfpnt.isValid()) { bmf.insert(dupPair, bmfpnt); } } } } // Grow stack with spacing adding info to stack for (int i = -1 ; i <= 1 ; i ++) { // Sample for (int j = -1 ; j <= 1 ; j ++) { // Line // Don't re-add the original sample, line if ( !((i == 0) && (j == 0)) ) { // Grow based upon spacing double ssamp = sample + (i * space); double sline = line + (j * space); Coordinate pnt = Coordinate(sline, ssamp); SmtkPoint gpnt = matcher.Clone(spnt, pnt); if ( gpnt.isValid() ) { SmtkQPair growpt((int) sline, (int) ssamp); // double check we don't have a finalized result at this position SmtkQStackIter temp = bmf.find(growpt); if(temp == bmf.end()) { gstack.insert(growpt, gpnt); } } } } } } } // Remove the current point from the grow stack (hole) gstack.erase(cstack); } ///////////////////////////////////////////////////////////////////////// // All done with creating points. Perform output options. ///////////////////////////////////////////////////////////////////////// // If a TO parameter was specified, create DEM with errors if (ui.WasEntered("TO")) { // Create the output DEM cout << "\nCreating output DEM from " << bmf.size() << " points.\n"; Process p; Cube *icube = p.SetInputCube("FROM"); Cube *ocube = p.SetOutputCube("TO", icube->sampleCount(), icube->lineCount(), 3); p.ClearInputCubes(); int boxsize = ui.GetInteger("BOXSIZE"); double plotdist = ui.GetDouble("PLOTDIST"); TileManager dem(*ocube), eigen(*ocube), stErr(*ocube); dem.SetTile(1, 1); // DEM Data/elevation stErr.SetTile(1, 2); // Error in stereo computation eigen.SetTile(1, 3); // Eigenvalue of the solution int nBTiles(eigen.Tiles()/3); // Total tiles / 3 bands prog.SetText("Creating DEM"); prog.SetMaximumSteps(nBTiles); prog.CheckStatus(); Statistics stAng; while ( !eigen.end() ) { // Must use the last band for this!! PointPlot tm = for_each(bmf.begin(), bmf.end(), PointPlot(dem, plotdist)); tm.FillPoints(*lhCamera, *rhCamera, boxsize, dem, stErr, eigen, &stAng); ocube->write(dem); ocube->write(stErr); ocube->write(eigen); dem.next(); stErr.next(); eigen.next(); prog.CheckStatus(); } // Report Stereo separation angles PvlGroup stresultsPvl("StereoSeparationAngle"); stresultsPvl += PvlKeyword("Minimum", toString(stAng.Minimum()), "deg"); stresultsPvl += PvlKeyword("Average", toString(stAng.Average()), "deg"); stresultsPvl += PvlKeyword("Maximum", toString(stAng.Maximum()), "deg"); stresultsPvl += PvlKeyword("StandardDeviation", toString(stAng.StandardDeviation()), "deg"); Application::Log(stresultsPvl); // Update the label with BandBin keywords PvlKeyword filter("FilterName", "Elevation", "meters"); filter.addValue("ElevationError", "meters"); filter.addValue("GoodnessOfFit", "unitless"); PvlKeyword center("Center", "1.0"); center.addValue("1.0"); center.addValue("1.0"); PvlGroup &bandbin = ocube->label()->findGroup("BandBin", PvlObject::Traverse); bandbin.addKeyword(filter, PvlContainer::Replace); bandbin.addKeyword(center, PvlContainer::Replace); center.setName("Width"); bandbin.addKeyword(center, PvlContainer::Replace); p.EndProcess(); } // If a cnet file was entered, write the ControlNet pvl to the file if (ui.WasEntered("ONET")) { WriteCnet(ui.GetFileName("ONET"), bmf, lhCamera->target()->name(), serialLeft, serialRight); } // Create output data PvlGroup totalPointsPvl("Totals"); totalPointsPvl += PvlKeyword("AttemptedPoints", toString(numAttemptedInitialPoints)); totalPointsPvl += PvlKeyword("InitialSuccesses", toString(numOrigPoints)); totalPointsPvl += PvlKeyword("GrowSuccesses", toString(passpix2)); totalPointsPvl += PvlKeyword("ResultingPoints", toString(bmf.size())); Application::Log(totalPointsPvl); Pvl arPvl = matcher.RegistrationStatistics(); PvlGroup smtkresultsPvl("SmtkResults"); smtkresultsPvl += PvlKeyword("SpiceOffImage", toString(matcher.OffImageErrorCount())); smtkresultsPvl += PvlKeyword("SpiceDistanceError", toString(matcher.SpiceErrorCount())); arPvl.addGroup(smtkresultsPvl); for(int i = 0; i < arPvl.groups(); i++) { Application::Log(arPvl.group(i)); } // add the auto registration information to print.prt PvlGroup autoRegTemplate = matcher.RegTemplate(); Application::Log(autoRegTemplate); // Don't need the cubes opened anymore lhImage.close(); rhImage.close(); }
// Main program void IsisMain() { UserInterface &ui = Application::GetUserInterface(); if( !ui.WasEntered("FROMLIST") && ui.WasEntered("TOLIST") ) { std::string msg = "To create a [TOLIST] the [FROMLIST] parameter must be provided."; throw iException::Message(iException::User,msg,_FILEINFO_); } // Gets the input parameters ControlNet outNet( ui.GetFilename("CNET") ); FileList inList; if( ui.WasEntered("FROMLIST") ) { inList = ui.GetFilename("FROMLIST"); } bool noIgnore = ui.GetBoolean("NOIGNORE"); bool noHeld = ui.GetBoolean("NOHELD"); bool noSingleMeasure = ui.GetBoolean("NOSINGLEMEASURES"); bool noMeasureless = ui.GetBoolean("NOMEASURELESS"); bool noTolerancePoints = ui.GetBoolean("TOLERANCE"); bool reference = ui.GetBoolean("REFERENCE"); bool ground = ui.GetBoolean("GROUND"); bool cubePoints = ui.WasEntered("CUBEPOINTS"); bool cubeMeasures = ui.GetBoolean("CUBEMEASURES"); bool pointsEntered = ui.WasEntered("POINTLIST"); bool latLon = ui.GetBoolean("LATLON"); if( !(noIgnore || noHeld || noSingleMeasure || noMeasureless || noTolerancePoints || reference || ground || cubePoints || pointsEntered || latLon) ) { std::string msg = "At least one filter must be selected ["; msg += "NOIGNORE,NOHELD,NOSINGLEMEASURE,TOLERANCE,REFERENCE,GROUND,CUBEPOINTS,"; msg += "CUBEMEASURES,POINTLIST,LATLON]"; throw iException::Message(iException::User,msg,_FILEINFO_); } else if( cubeMeasures && !cubePoints ) { std::string msg = "When CUBEMEASURES is selected, CUBEPOINTS must be given"; msg += " a list of cubes."; throw iException::Message(iException::User,msg,_FILEINFO_); } // Set up the Serial Number to Filename mapping map<iString,iString> sn2filename; for( int cubeIndex=0; cubeIndex < (int)inList.size(); cubeIndex ++ ) { iString sn = SerialNumber::Compose( inList[cubeIndex] ); sn2filename[sn] = inList[cubeIndex]; } Progress progress; progress.SetMaximumSteps(outNet.Size()); progress.CheckStatus(); // Set up verctor records of how points/measures are removed PvlKeyword ignoredPoints( "IgnoredPoints" ); PvlKeyword ignoredMeasures( "IgnoredMeasures" ); PvlKeyword heldPoints( "HeldPoints" ); PvlKeyword singleMeasurePoints( "SingleMeasurePoints" ); PvlKeyword measurelessPoints( "MeasurelessPoints" ); PvlKeyword tolerancePoints( "TolerancePoints" ); PvlKeyword nonReferenceMeasures( "NonReferenseMeasures" ); PvlKeyword nonGroundPoints( "NonGroundPoints" ); PvlKeyword nonCubePoints( "NonCubePoints" ); PvlKeyword nonCubeMeasures( "NonCubeMeasures" ); PvlKeyword noMeasurePoints( "NoMeasurePoints" ); PvlKeyword nonListedPoints( "NonListedPoints" ); PvlKeyword nonLatLonPoints( "LatLonOutOfRangePoints" ); PvlKeyword cannotGenerateLatLonPoints( "NoLatLonPoints" ); // Set up comparison data vector<iString> serialNumbers; if( cubePoints ) { FileList cubeList( ui.GetFilename("CUBEPOINTS") ); for( int cubeIndex=0; cubeIndex < (int)cubeList.size(); cubeIndex ++ ) { iString sn = SerialNumber::Compose( cubeList[cubeIndex] ); serialNumbers.push_back( sn ); } } double tolerance = 0.0; if( noTolerancePoints ) { tolerance = ui.GetDouble("PIXELTOLERANCE"); } // Set up extracted network values if( ui.WasEntered("NETWORKID") ) outNet.SetNetworkId( ui.GetString("NETWORKID") ); outNet.SetUserName( Isis::Application::UserName() ); outNet.SetDescription( ui.GetString("DESCRIPTION") ); for(int cp=outNet.Size()-1; cp >= 0; cp --) { progress.CheckStatus(); // Do preliminary exclusion checks if( noIgnore && outNet[cp].Ignore() ) { ignoredPoints += outNet[cp].Id(); outNet.Delete(cp); continue; } if( noHeld && outNet[cp].Held() ) { heldPoints += outNet[cp].Id(); outNet.Delete(cp); continue; } if( ground && !(outNet[cp].Type() == ControlPoint::Ground) ) { nonGroundPoints += outNet[cp].Id(); outNet.Delete(cp); continue; } if( noSingleMeasure ) { bool invalidPoint = false; invalidPoint |= noIgnore && (outNet[cp].NumValidMeasures() < 2); invalidPoint |= outNet[cp].Size() < 2 && (outNet[cp].Type() != ControlPoint::Ground); if( invalidPoint ) { singleMeasurePoints += outNet[cp].Id(); outNet.Delete(cp); continue; } } // Change the current point into a new point by manipulation of its control measures ControlPoint & newPoint = outNet[cp]; for( int cm = newPoint.Size()-1; cm >= 0; cm --) { if(noIgnore && newPoint[cm].Ignore()) { ignoredMeasures += "(" + newPoint.Id() + "," + newPoint[cm].CubeSerialNumber() + ")"; newPoint.Delete( cm ); } else if( reference && !newPoint[cm].IsReference() ) { nonReferenceMeasures += "(" + newPoint.Id() + "," + newPoint[cm].CubeSerialNumber() + ")"; newPoint.Delete( cm ); } else if( cubeMeasures ) { bool hasSerialNumber = false; for( unsigned int sn = 0; sn < serialNumbers.size() && !hasSerialNumber; sn ++) { if(serialNumbers[sn] == newPoint[cm].CubeSerialNumber()) hasSerialNumber = true; } if( !hasSerialNumber ) { nonCubeMeasures += "(" + newPoint.Id() + "," + newPoint[cm].CubeSerialNumber() + ")"; newPoint.Delete( cm ); } } } // Check for line/sample errors above provided tolerance if( noTolerancePoints ) { bool hasLowTolerance = true; for( int cm = 0; cm < newPoint.Size() && hasLowTolerance; cm ++ ) { if( newPoint[cm].SampleError() >= tolerance || newPoint[cm].LineError() >= tolerance ) { hasLowTolerance = false; } } if( hasLowTolerance ) { tolerancePoints += newPoint.Id(); outNet.Delete(cp); continue; } } // Do not add outPoint if it has too few measures if( noSingleMeasure ) { bool invalidPoint = false; invalidPoint |= noIgnore && (newPoint.NumValidMeasures() < 2); invalidPoint |= newPoint.Size() < 2 && newPoint.Type() != ControlPoint::Ground; if( invalidPoint ) { singleMeasurePoints += outNet[cp].Id(); outNet.Delete(cp); continue; } } // Do not add outPoint if it does not have a cube in CUBEPOINTS as asked if( cubePoints && !cubeMeasures ) { bool hasSerialNumber = false; for( int cm = 0; cm < newPoint.Size() && !hasSerialNumber; cm ++) { for( unsigned int sn = 0; sn < serialNumbers.size() && !hasSerialNumber; sn ++) { if(serialNumbers[sn] == newPoint[cm].CubeSerialNumber()) hasSerialNumber = true; } } if( !hasSerialNumber ) { nonCubePoints += newPoint.Id(); outNet.Delete(cp); continue; } } if( noMeasureless && newPoint.Size() == 0 ) { noMeasurePoints += newPoint.Id(); outNet.Delete(cp); continue; } } //! Finished with simple comparisons /** * Use another pass to check for Ids */ if( pointsEntered ) { ExtractPointList( outNet, nonListedPoints ); } /** * Use another pass on outNet, because this is by far the most time consuming * process, and time could be saved by using the reduced size of outNet */ if( latLon ) { ExtractLatLonRange( outNet, nonLatLonPoints, cannotGenerateLatLonPoints, sn2filename ); } // Write the filenames associated with outNet WriteCubeOutList( outNet, sn2filename ); Progress outProgress; outProgress.SetText("Writing Control Network"); outProgress.SetMaximumSteps( 5 ); outProgress.CheckStatus(); // Create the points included file PvlGroup included("NewControlNet"); included.AddKeyword( PvlKeyword( "Size", outNet.Size() ) ); PvlKeyword newPoints( "Points" ); for( int cp = 0; cp < outNet.Size(); cp ++ ) { newPoints.AddValue( outNet[cp].Id() ); } included.AddKeyword( newPoints ); outProgress.CheckStatus(); // Write the extracted Control Network outNet.Write( ui.GetFilename("OUTNET") ); outProgress.CheckStatus(); // Adds the remove history to the summary and results group PvlGroup summary("ResultSummary"); PvlGroup results("Results"); if( noIgnore ) { summary.AddKeyword( PvlKeyword( "IgnoredPoints", ignoredPoints.Size() ) ); results.AddKeyword( ignoredPoints ); summary.AddKeyword( PvlKeyword( "IgnoredMeasures", ignoredMeasures.Size() ) ); results.AddKeyword( ignoredMeasures ); } if( noHeld ) { summary.AddKeyword( PvlKeyword( "HeldPoints", heldPoints.Size() ) ); results.AddKeyword( heldPoints ); } if( noSingleMeasure ) { summary.AddKeyword( PvlKeyword( "SingleMeasurePoints", singleMeasurePoints.Size() ) ); results.AddKeyword( singleMeasurePoints ); } if( noMeasureless ) { summary.AddKeyword( PvlKeyword( "MeasurelessPoints", measurelessPoints.Size() ) ); results.AddKeyword( measurelessPoints ); } if( noTolerancePoints ) { summary.AddKeyword( PvlKeyword( "TolerancePoints", tolerancePoints.Size() ) ); results.AddKeyword( tolerancePoints ); } if( reference ) { summary.AddKeyword( PvlKeyword( "NonReferenceMeasures", nonReferenceMeasures.Size() ) ); results.AddKeyword( nonReferenceMeasures ); } if( ground ) { summary.AddKeyword( PvlKeyword( "NonGroundPoints", nonGroundPoints.Size() ) ); results.AddKeyword( nonGroundPoints ); } if( cubePoints ) { summary.AddKeyword( PvlKeyword( "NonCubePoints", nonCubePoints.Size() ) ); results.AddKeyword( nonCubePoints ); } if( noMeasurePoints.Size() != 0 ) { summary.AddKeyword( PvlKeyword( "NonCubeMeasure", noMeasurePoints.Size() ) ); results.AddKeyword( noMeasurePoints ); } if( cubeMeasures ) { summary.AddKeyword( PvlKeyword( "NoMeasurePoints", nonCubeMeasures.Size() ) ); results.AddKeyword( nonCubeMeasures ); } if( pointsEntered ) { summary.AddKeyword( PvlKeyword( "NonListedPoints", nonListedPoints.Size() ) ); results.AddKeyword( nonListedPoints ); } if( latLon ) { summary.AddKeyword( PvlKeyword( "LatLonOutOfRange", nonLatLonPoints.Size() ) ); results.AddKeyword( nonLatLonPoints ); summary.AddKeyword( PvlKeyword( "NoLatLonPoints", cannotGenerateLatLonPoints.Size() ) ); results.AddKeyword( cannotGenerateLatLonPoints ); } outProgress.CheckStatus(); // Log Control Net results Application::Log(included); Application::Log(summary); results.AddComment( "Each keyword represents a filter parameter used." \ " Check the documentation for specific keyword descriptions." ); Application::Log(results); outProgress.CheckStatus(); }
/** * 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() { const QString caminfo_program = "caminfo"; UserInterface &ui = Application::GetUserInterface(); QList< QPair<QString, QString> > *general = NULL, *camstats = NULL, *statistics = NULL; BandGeometry *bandGeom = NULL; // Get input filename FileName in = ui.GetFileName("FROM"); // Get the format QString sFormat = ui.GetAsString("FORMAT"); // if true then run spiceinit, xml default is FALSE // spiceinit will use system kernels if(ui.GetBoolean("SPICE")) { QString parameters = "FROM=" + in.expanded(); ProgramLauncher::RunIsisProgram("spiceinit", parameters); } Process p; Cube *incube = p.SetInputCube("FROM"); // General data gathering general = new QList< QPair<QString, QString> >; general->append(MakePair("Program", caminfo_program)); general->append(MakePair("IsisVersion", Application::Version())); general->append(MakePair("RunDate", iTime::CurrentGMT())); general->append(MakePair("IsisId", SerialNumber::Compose(*incube))); general->append(MakePair("From", in.baseName() + ".cub")); general->append(MakePair("Lines", toString(incube->lineCount()))); general->append(MakePair("Samples", toString(incube->sampleCount()))); general->append(MakePair("Bands", toString(incube->bandCount()))); // Run camstats on the entire image (all bands) // another camstats will be run for each band and output // for each band. if(ui.GetBoolean("CAMSTATS")) { camstats = new QList< QPair<QString, QString> >; QString filename = ui.GetAsString("FROM"); int sinc = ui.GetInteger("SINC"); int linc = ui.GetInteger("LINC"); CameraStatistics stats(filename, sinc, linc); Pvl camPvl = stats.toPvl(); PvlGroup cg = camPvl.findGroup("Latitude", Pvl::Traverse); camstats->append(MakePair("MinimumLatitude", cg["latitudeminimum"][0])); camstats->append(MakePair("MaximumLatitude", cg["latitudemaximum"][0])); cg = camPvl.findGroup("Longitude", Pvl::Traverse); camstats->append(MakePair("MinimumLongitude", cg["longitudeminimum"][0])); camstats->append(MakePair("MaximumLongitude", cg["longitudemaximum"][0])); cg = camPvl.findGroup("Resolution", Pvl::Traverse); camstats->append(MakePair("MinimumResolution", cg["resolutionminimum"][0])); camstats->append(MakePair("MaximumResolution", cg["resolutionmaximum"][0])); cg = camPvl.findGroup("PhaseAngle", Pvl::Traverse); camstats->append(MakePair("MinimumPhase", cg["phaseminimum"][0])); camstats->append(MakePair("MaximumPhase", cg["phasemaximum"][0])); cg = camPvl.findGroup("EmissionAngle", Pvl::Traverse); camstats->append(MakePair("MinimumEmission", cg["emissionminimum"][0])); camstats->append(MakePair("MaximumEmission", cg["emissionmaximum"][0])); cg = camPvl.findGroup("IncidenceAngle", Pvl::Traverse); camstats->append(MakePair("MinimumIncidence", cg["incidenceminimum"][0])); camstats->append(MakePair("MaximumIncidence", cg["incidencemaximum"][0])); cg = camPvl.findGroup("LocalSolarTime", Pvl::Traverse); camstats->append(MakePair("LocalTimeMinimum", cg["localsolartimeMinimum"][0])); camstats->append(MakePair("LocalTimeMaximum", cg["localsolartimeMaximum"][0])); } // Compute statistics for entire cube if(ui.GetBoolean("STATISTICS")) { statistics = new QList< QPair<QString, QString> >; LineManager iline(*incube); Statistics stats; Progress progress; progress.SetText("Statistics..."); progress.SetMaximumSteps(incube->lineCount()*incube->bandCount()); progress.CheckStatus(); iline.SetLine(1); for(; !iline.end() ; iline.next()) { incube->read(iline); stats.AddData(iline.DoubleBuffer(), iline.size()); progress.CheckStatus(); } // Compute stats of entire cube double nPixels = stats.TotalPixels(); double nullpercent = (stats.NullPixels() / (nPixels)) * 100; double hispercent = (stats.HisPixels() / (nPixels)) * 100; double hrspercent = (stats.HrsPixels() / (nPixels)) * 100; double lispercent = (stats.LisPixels() / (nPixels)) * 100; double lrspercent = (stats.LrsPixels() / (nPixels)) * 100; // Statitics output for band statistics->append(MakePair("MeanValue", toString(stats.Average()))); statistics->append(MakePair("StandardDeviation", toString(stats.StandardDeviation()))); statistics->append(MakePair("MinimumValue", toString(stats.Minimum()))); statistics->append(MakePair("MaximumValue", toString(stats.Maximum()))); statistics->append(MakePair("PercentHIS", toString(hispercent))); statistics->append(MakePair("PercentHRS", toString(hrspercent))); statistics->append(MakePair("PercentLIS", toString(lispercent))); statistics->append(MakePair("PercentLRS", toString(lrspercent))); statistics->append(MakePair("PercentNull", toString(nullpercent))); statistics->append(MakePair("TotalPixels", toString(stats.TotalPixels()))); } bool getFootBlob = ui.GetBoolean("USELABEL"); bool doGeometry = ui.GetBoolean("GEOMETRY"); bool doPolygon = ui.GetBoolean("POLYGON"); if(doGeometry || doPolygon || getFootBlob) { Camera *cam = incube->camera(); QString incType = ui.GetString("INCTYPE"); int polySinc, polyLinc; if(doPolygon && incType.toUpper() == "VERTICES") { ImagePolygon poly; poly.initCube(*incube); polySinc = polyLinc = (int)(0.5 + (((poly.validSampleDim() * 2) + (poly.validLineDim() * 2) - 3.0) / ui.GetInteger("NUMVERTICES"))); } else if (incType.toUpper() == "LINCSINC"){ if(ui.WasEntered("POLYSINC")) { polySinc = ui.GetInteger("POLYSINC"); } else { polySinc = (int)(0.5 + 0.10 * incube->sampleCount()); if(polySinc == 0) polySinc = 1; } if(ui.WasEntered("POLYLINC")) { polyLinc = ui.GetInteger("POLYLINC"); } else { polyLinc = (int)(0.5 + 0.10 * incube->lineCount()); if(polyLinc == 0) polyLinc = 1; } } else { QString msg = "Invalid INCTYPE option[" + incType + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } bandGeom = new BandGeometry(); bandGeom->setSampleInc(polySinc); bandGeom->setLineInc(polyLinc); bandGeom->setMaxIncidence(ui.GetDouble("MAXINCIDENCE")); bandGeom->setMaxEmission(ui.GetDouble("MAXEMISSION")); bool precision = ui.GetBoolean("INCREASEPRECISION"); if (getFootBlob) { // Need to read history to obtain parameters that were used to // create the footprint History hist("IsisCube", in.expanded()); Pvl pvl = hist.ReturnHist(); PvlObject::PvlObjectIterator objIter; bool found = false; PvlGroup fpgrp; for (objIter=pvl.endObject()-1; objIter>=pvl.beginObject(); objIter--) { if (objIter->name().toUpper() == "FOOTPRINTINIT") { found = true; fpgrp = objIter->findGroup("UserParameters"); break; } } if (!found) { QString msg = "Footprint blob was not found in input image history"; throw IException(IException::User, msg, _FILEINFO_); } QString prec = (QString)fpgrp.findKeyword("INCREASEPRECISION"); prec = prec.toUpper(); if (prec == "TRUE") { precision = true; } else { precision = false; } QString inctype = (QString)fpgrp.findKeyword("INCTYPE"); inctype = inctype.toUpper(); if (inctype == "LINCSINC") { int linc = fpgrp.findKeyword("LINC"); int sinc = fpgrp.findKeyword("SINC"); bandGeom->setSampleInc(sinc); bandGeom->setLineInc(linc); } else { int vertices = fpgrp.findKeyword("NUMVERTICES"); int lincsinc = (int)(0.5 + (((incube->sampleCount() * 2) + (incube->lineCount() * 2) - 3.0) / vertices)); bandGeom->setSampleInc(lincsinc); bandGeom->setLineInc(lincsinc); } if (fpgrp.hasKeyword("MAXINCIDENCE")) { double maxinc = fpgrp.findKeyword("MAXINCIDENCE"); bandGeom->setMaxIncidence(maxinc); } if (fpgrp.hasKeyword("MAXEMISSION")) { double maxema = fpgrp.findKeyword("MAXEMISSION"); bandGeom->setMaxEmission(maxema); } } bandGeom->collect(*cam, *incube, doGeometry, doPolygon, getFootBlob, precision); // Check if the user requires valid image center geometry if(ui.GetBoolean("VCAMERA") && (!bandGeom->hasCenterGeometry())) { QString msg = "Image center does not project in camera model"; throw IException(IException::Unknown, msg, _FILEINFO_); } } if(sFormat.toUpper() == "PVL") GeneratePVLOutput(incube, general, camstats, statistics, bandGeom); else GenerateCSVOutput(incube, general, camstats, statistics, bandGeom); // Clean the data delete general; general = NULL; if(camstats) { delete camstats; camstats = NULL; } if(statistics) { delete statistics; statistics = NULL; } if(bandGeom) { delete bandGeom; bandGeom = NULL; } }
void IsisMain() { latLonGrid = NULL; // We will be processing by line ProcessByLine p; Cube *icube = p.SetInputCube("FROM"); UserInterface &ui = Application::GetUserInterface(); QString mode = ui.GetString("MODE"); outline = ui.GetBoolean("OUTLINE"); ticks = ui.GetBoolean("TICKS"); if (ticks) { tickSize = ui.GetInteger("TICKSIZE") / 2; diagonalTicks = ui.GetBoolean("DIAGONALTICKS"); } lineWidth = ui.GetInteger("LINEWIDTH") / 2; QString bval = ui.GetString("BKGNDVALUE").toUpper(); image = (bval == "IMAGE"); bkgndValue = Null; if (bval == "HRS") { bkgndValue = Hrs; } else if (bval == "LRS") { bkgndValue = Lrs; } else if (bval == "DN") { bkgndValue = ui.GetDouble("BKGNDDNVALUE"); } QString lval = ui.GetString("LINEVALUE").toUpper(); if (lval == "HRS") { lineValue = Hrs; } else if (lval == "LRS") { lineValue = Lrs; } else if (lval == "NULL") { lineValue = Null; } else if (lval == "DN") { if (ui.WasEntered("DNVALUE")) { lineValue = ui.GetDouble("DNVALUE"); } else { throw IException(IException::User, "Must enter value in DNVALUE", _FILEINFO_); } } else { IString msg = "Invalid LINEVALUE string [" + ui.GetString("LINEVALUE"); msg += "], must be one of HRS, LRS, NULL, or DN."; throw IException(IException::User, msg, _FILEINFO_); } inputSamples = icube->sampleCount(); inputLines = icube->lineCount(); // Line & sample based grid if (mode == "IMAGE") { p.SetOutputCube("TO"); baseLine = ui.GetInteger("BASELINE"); baseSample = ui.GetInteger("BASESAMPLE"); lineInc = ui.GetInteger("LINC"); sampleInc = ui.GetInteger("SINC"); p.StartProcess(imageGrid); p.EndProcess(); } // Lat/Lon based grid else { CubeAttributeOutput oatt("+32bit"); p.SetOutputCube(ui.GetFileName("TO"), oatt, icube->sampleCount(), icube->lineCount(), icube->bandCount()); UniversalGroundMap *gmap = new UniversalGroundMap(*icube, UniversalGroundMap::ProjectionFirst); latLonGrid = new GroundGrid(gmap, ticks, icube->sampleCount(), icube->lineCount()); baseLat = Latitude(ui.GetDouble("BASELAT"), *latLonGrid->GetMappingGroup(), Angle::Degrees); baseLon = Longitude(ui.GetDouble("BASELON"), *latLonGrid->GetMappingGroup(), Angle::Degrees); latInc = Angle(ui.GetDouble("LATINC"), Angle::Degrees); lonInc = Angle(ui.GetDouble("LONINC"), Angle::Degrees); Progress progress; progress.SetText("Calculating Grid"); Latitude minLat, maxLat; if (ui.WasEntered("MINLAT")) minLat = Latitude(ui.GetDouble("MINLAT"), *latLonGrid->GetMappingGroup(), Angle::Degrees); if (ui.WasEntered("MAXLAT")) maxLat = Latitude(ui.GetDouble("MAXLAT"), *latLonGrid->GetMappingGroup(), Angle::Degrees); Longitude minLon, maxLon; if (ui.WasEntered("MINLON")) minLon = Longitude(ui.GetDouble("MINLON"), *latLonGrid->GetMappingGroup(), Angle::Degrees); if (ui.WasEntered("MAXLON")) maxLon = Longitude(ui.GetDouble("MAXLON"), *latLonGrid->GetMappingGroup(), Angle::Degrees); latLonGrid->SetGroundLimits(minLat, minLon, maxLat, maxLon); latLonGrid->CreateGrid(baseLat, baseLon, latInc, lonInc, &progress); if (ui.GetBoolean("BOUNDARY")) latLonGrid->WalkBoundary(); p.StartProcess(groundGrid); p.EndProcess(); delete latLonGrid; latLonGrid = NULL; delete gmap; gmap = NULL; } }
/** * Constructs an OverlapStatistics object. Compares the two input cubes and * finds where they overlap. * * @param x The first input cube * @param y The second input cube * @param progressMsg (Default value of "Gathering Overlap Statistics") Text * for indicating progress during statistic gathering * @param sampPercent (Default value of 100.0) Sampling percent, or the percentage * of lines to consider during the statistic gathering procedure * * @throws Isis::iException::User - All images must have the same number of * bands */ OverlapStatistics::OverlapStatistics(Isis::Cube &x, Isis::Cube &y, std::string progressMsg, double sampPercent) { // Test to ensure sampling percent in bound if (sampPercent <= 0.0 || sampPercent > 100.0) { string msg = "The sampling percent must be a decimal (0.0, 100.0]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } p_sampPercent = sampPercent; // Extract filenames and band number from cubes p_xFile = x.Filename(); p_yFile = y.Filename(); // Make sure number of bands match if (x.Bands() != y.Bands()) { string msg = "Number of bands do not match between cubes [" + p_xFile.Name() + "] and [" + p_yFile.Name() + "]"; throw iException::Message(iException::User,msg,_FILEINFO_); } p_bands = x.Bands(); p_stats.resize(p_bands); //Create projection from each cube Projection *projX = x.Projection(); Projection *projY = y.Projection(); // Test to make sure projection parameters match if (*projX != *projY) { string msg = "Mapping groups do not match between cubes [" + p_xFile.Name() + "] and [" + p_yFile.Name() + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // Figure out the x/y range for both images to find the overlap double Xmin1 = projX->ToProjectionX(0.5); double Ymax1 = projX->ToProjectionY(0.5); double Xmax1 = projX->ToProjectionX(x.Samples()+0.5); double Ymin1 = projX->ToProjectionY(x.Lines()+0.5); double Xmin2 = projY->ToProjectionX(0.5); double Ymax2 = projY->ToProjectionY(0.5); double Xmax2 = projY->ToProjectionX(y.Samples()+0.5); double Ymin2 = projY->ToProjectionY(y.Lines()+0.5); // Find overlap if ((Xmin1<Xmax2) && (Xmax1>Xmin2) && (Ymin1<Ymax2) && (Ymax1>Ymin2)) { double minX = Xmin1 > Xmin2 ? Xmin1 : Xmin2; double minY = Ymin1 > Ymin2 ? Ymin1 : Ymin2; double maxX = Xmax1 < Xmax2 ? Xmax1 : Xmax2; double maxY = Ymax1 < Ymax2 ? Ymax1 : Ymax2; // Find Sample range of the overlap p_minSampX = (int)(projX->ToWorldX(minX) + 0.5); p_maxSampX = (int)(projX->ToWorldX(maxX) + 0.5); p_minSampY = (int)(projY->ToWorldX(minX) + 0.5); p_maxSampY = (int)(projY->ToWorldX(maxX) + 0.5); p_sampRange = p_maxSampX - p_minSampX + 1; // Test to see if there was only sub-pixel overlap if (p_sampRange <= 0) return; // Find Line range of overlap p_minLineX = (int)(projX->ToWorldY(maxY) + 0.5); p_maxLineX = (int)(projX->ToWorldY(minY) + 0.5); p_minLineY = (int)(projY->ToWorldY(maxY) + 0.5); p_maxLineY = (int)(projY->ToWorldY(minY) + 0.5); p_lineRange = p_maxLineX - p_minLineX + 1; // Print percent processed Progress progress; progress.SetText(progressMsg); int linc = (int)(100.0 / sampPercent + 0.5); // Calculate our line increment // Define the maximum number of steps to be our line range divided by the // line increment, but if they do not divide evenly, then because of // rounding, we need to do an additional step for each band int maxSteps = (int)(p_lineRange / linc + 0.5); if (p_lineRange % linc != 0) maxSteps += 1; maxSteps *= p_bands; progress.SetMaximumSteps(maxSteps); progress.CheckStatus(); // Collect and store off the overlap statistics for (int band=1; band<=p_bands; band++) { Brick b1(p_sampRange,1,1,x.PixelType()); Brick b2(p_sampRange,1,1,y.PixelType()); int i=0; while (i<p_lineRange) { b1.SetBasePosition(p_minSampX,(i+p_minLineX),band); b2.SetBasePosition(p_minSampY,(i+p_minLineY),band); x.Read(b1); y.Read(b2); p_stats[band-1].AddData(b1.DoubleBuffer(), b2.DoubleBuffer(), p_sampRange); // Make sure we consider the last line if (i+linc > p_lineRange-1 && i != p_lineRange-1) { i = p_lineRange-1; progress.AddSteps(1); } else i+=linc; // Increment the current line by our incrementer progress.CheckStatus(); } } } }
/** * 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() { const QString mdisddr_program = "mdisddr"; const QString mdisddr_version = "1.0"; const QString mdisddr_revision = "$Revision: 5086 $"; const QString mdisddr_runtime = Application::DateTime(); const QString dataSetID = "MESS-E/V/H-MDIS-6-DDR-GEOMDATA-V1.0"; UserInterface &ui = Application::GetUserInterface(); FileName input(ui.GetFileName("FROM")); QString to(""); bool toEntered = ui.WasEntered("TO"); if(toEntered) { to = ui.GetAsString("TO"); } QString opath("."); // Set default to local directory if(ui.WasEntered("OPATH")) { opath = ui.GetString("OPATH"); } else { ui.PutAsString("OPATH", opath); } // Generate the image cube that phocube produces for the DDR data FileName phoFile = FileName::createTempFile("$TEMPORARY/" + input.baseName() + "_phocube.cub"); QString pfile = phoFile.expanded(); QString parameters = "FROM=" + input.expanded() + " TO=" + pfile + " LATITUDE=TRUE LONGITUDE=TRUE PHASE=TRUE EMISSION=TRUE INCIDENCE=TRUE"; ProgramLauncher::RunIsisProgram("phocube", parameters); // Wrap a try clause so that if anything goes wrong below, we can remove // the phocube file. try { Pvl phoLabel(pfile); BandMap bandmap; PvlKeyword bn = phoLabel.findGroup("BandBin", Pvl::Traverse)["Name"]; for(int i = 0 ; i < bn.size() ; i++) { bandmap.add(bn[i], i + 1); } // Set up the export. Note that the attributes selects 5 bands from the // output of the phocube run. It doesn't matter at this time which 5 // bands it is, just so that we have this established so the right labels // and file size is created. ProcessExportPds processPds; (void) processPds.SetInputCube(pfile, CubeAttributeInput("+1-5")); // Due to the nature of the phocube file, we cannot compute a histogram // of the data (it includes lots of data we don't need). So we will // fix the range to the expected well defined angle ranges. double minmin = 0.0; double maxmax = 0.0; if(ui.GetString("TYPE").compare("AUTOMATIC") == 0) { minmin = -360.0; maxmax = 360.0; } else { minmin = ui.GetDouble("MIN"); maxmax = ui.GetDouble("MAX"); } processPds.SetOutputEndian(Isis::Msb); processPds.SetExportType(ProcessExportPds::Fixed); processPds.SetInputRange(minmin, maxmax); // Set the output pixel type and the special pixel values processPds.SetOutputType(Real); processPds.SetOutputRange(minmin, maxmax); processPds.SetOutputNull(NULL4); processPds.SetOutputLrs(LOW_REPR_SAT4); processPds.SetOutputLis(LOW_INSTR_SAT4); processPds.SetOutputHrs(HIGH_REPR_SAT4); processPds.SetOutputHis(HIGH_INSTR_SAT4); Progress p; p.SetText("Modifying Keywords"); p.SetMaximumSteps(6); p.CheckStatus(); // Get the PDS label from the process Pvl &pdsLabel = processPds.StandardPdsLabel(ProcessExportPds::Image); // Translate the keywords from the original EDR PDS label that go in // this DDR PDS label. Note that we have to open the original (FROM) // cube as the phocube output goes into the specification of the // output PDS file (required for 5 band IMAGE object). Cube from; from.open(input.expanded()); OriginalLabel origBlob; from.read(origBlob); Pvl origLabel; PvlObject origLabelObj = origBlob.ReturnLabels(); origLabelObj.setName("OriginalLabelObject"); origLabel.addObject(origLabelObj); p.CheckStatus(); // Translates the ISIS labels along with the original EDR labels origLabel.addObject(*from.label()); PvlTranslationManager labels(origLabel, "$messenger/translations/mdisDDRLabel.trn"); labels.Auto(pdsLabel); p.CheckStatus(); // Add any new keywords QString lnote = "2007-12-20, S. Murchie (JHU/APL); " "2008-01-02, S. Murchie (JHU/APL); " "2008-01-11, J. Ward (GEO)"; pdsLabel += PvlKeyword("LABEL_REVISION_NOTE", lnote); pdsLabel += PvlKeyword("SPACECRAFT_NAME", Quote("MESSENGER")); // Fixes bad keywords PvlKeyword &data_set_id = pdsLabel.findKeyword("DATA_SET_ID", Pvl::Traverse); data_set_id.setValue(dataSetID); QString prodid(input.baseName()); PvlKeyword &product_id = pdsLabel.findKeyword("PRODUCT_ID", Pvl::Traverse); if((product_id.size() == 0) || ((product_id.size() > 0) && (product_id[0] == "N/A"))) { product_id.setValue(prodid); } else { QString pid = product_id[0]; pid[0] = 'D'; pid.remove(QRegExp("_.*")); pid.append("_DE_0"); product_id.setValue(pid); prodid = pid; } // Now we have enough to establish output file name if(!toEntered) to = opath + "/" + prodid; FileName output(to); output = output.addExtension("IMG"); if(!toEntered) ui.PutFileName("TO", output.expanded()); PvlKeyword &product_creation_time = pdsLabel.findKeyword("PRODUCT_CREATION_TIME", Pvl::Traverse); product_creation_time.setValue(mdisddr_runtime); PvlKeyword &software_name = pdsLabel.findKeyword("SOFTWARE_NAME", Pvl::Traverse); software_name.setValue(mdisddr_program); PvlKeyword &software_version_id = pdsLabel.findKeyword("SOFTWARE_VERSION_ID", Pvl::Traverse); software_version_id.setValue(Quote(mdisddr_version)); PvlKeyword &filter_number = pdsLabel.findKeyword("FILTER_NUMBER", Pvl::Traverse); if((filter_number.size() > 0)) { filter_number.setValue(Quote(filter_number[0])); } // Add quotes PvlKeyword &data_quality_id = pdsLabel.findKeyword("DATA_QUALITY_ID", Pvl::Traverse); data_quality_id.setValue(Quote(data_quality_id)); PvlKeyword &sequence_name = pdsLabel.findKeyword("SEQUENCE_NAME", Pvl::Traverse); sequence_name.setValue(Quote(sequence_name)); PvlKeyword &start_count = pdsLabel.findKeyword("SPACECRAFT_CLOCK_START_COUNT", Pvl::Traverse); start_count.setValue(Quote(start_count)); PvlKeyword &stop_count = pdsLabel.findKeyword("SPACECRAFT_CLOCK_STOP_COUNT", Pvl::Traverse); stop_count.setValue(Quote(stop_count)); // For DDRs, the SOURCE_PRODUCT_ID is made up of SPICE kernels. I need to // go get em. Kernels kernels(from); QStringList kfiles = kernels.getKernelList(); PvlKeyword &source_product_id = pdsLabel.findKeyword("SOURCE_PRODUCT_ID", Pvl::Traverse); source_product_id.clear(); for(int i = 0; i < kfiles.size(); i++) { FileName kfile(kfiles[i]); source_product_id.addValue(Quote(kfile.name())); } // Enforce parentheses for scalars if(source_product_id.size() == 1) source_product_id.setValue('(' + source_product_id[0] + ')'); // Removes keywords PvlObject imageObject(pdsLabel.findObject("IMAGE")); if(imageObject.hasKeyword("CENTER_FILTER_WAVELENGTH")) imageObject.deleteKeyword("CENTER_FILTER_WAVELENGTH"); if(imageObject.hasKeyword("BANDWIDTH")) imageObject.deleteKeyword("BANDWIDTH"); if(imageObject.hasKeyword("UNIT")) imageObject.deleteKeyword("UNIT"); if(imageObject.hasKeyword("DARK_STRIP_MEAN")) imageObject.deleteKeyword("DARK_STRIP_MEAN"); if(imageObject.hasKeyword("OFFSET")) imageObject.deleteKeyword("OFFSET"); if(imageObject.hasKeyword("SCALING_FACTOR")) imageObject.deleteKeyword("SCALING_FACTOR"); if(imageObject.hasKeyword("SAMPLE_BIT_MASK")) imageObject.deleteKeyword("SAMPLE_BIT_MASK"); // Add band names to image object PvlKeyword &bandNames = imageObject.findKeyword("FILTER_NAME"); bandNames.setName("BAND_NAME"); bandNames.clear(); bandNames.addValue("Latitude, planetocentric, deg N"); bandNames.addValue("Longitude, planetocentric, deg E"); bandNames.addValue("Incidence angle at equipotential surface, deg"); bandNames.addValue("Emission angle at equipotential surface, deg"); bandNames.addValue("Phase angle at equipotential surface, deg"); pdsLabel.deleteObject("IMAGE"); pdsLabel.addObject(imageObject); p.CheckStatus(); // Fix all the hosed units upon ingest. They are illformed. FixUnit(pdsLabel, "RETICLE_POINT_RA", "DEG"); FixUnit(pdsLabel, "RETICLE_POINT_DECLINATION", "DEG"); FixUnit(pdsLabel, "RETICLE_POINT_LATITUDE", "DEG"); FixUnit(pdsLabel, "RETICLE_POINT_LONGITUDE", "DEG"); // Now address nested keywords in SUBFRAME groups for(int i = 1 ; i <= 5 ; i++) { QString n(toString(i)); QString group = "SUBFRAME" + n + "_PARAMETERS"; if(pdsLabel.hasGroup(group)) { PvlGroup &grp = pdsLabel.findGroup(group); ValidateUnit(grp.findKeyword("RETICLE_POINT_LATITUDE"), "DEG"); ValidateUnit(grp.findKeyword("RETICLE_POINT_LONGITUDE"), "DEG"); } } p.CheckStatus(); // Finally, fix keywords by Quoting missing N/A values FixLabels(pdsLabel); p.CheckStatus(); // All done...write result. pdsLabel.setFormatTemplate("$messenger/templates/labels/mdisPdsDDR.pft"); QString ofile(output.expanded()); ofstream outstream(ofile.toAscii().data()); processPds.OutputLabel(outstream); // Writing out the 5 bands is a bit tricky for this product. The bands // must be ordered in a specific order, but phocube orders them in a // different order. To make this approach work, determine the proper band // as ordered in the phocube output and select the desired bands one at a // time setting the input cube to the desired band and writing it out by // stream. // Write latitude, longitude, incidence, emission, phase bands WriteBand(processPds, outstream, pfile, bandmap.get("Latitude")); WriteBand(processPds, outstream, pfile, bandmap.get("Longitude")); WriteBand(processPds, outstream, pfile, bandmap.get("Incidence Angle")); WriteBand(processPds, outstream, pfile, bandmap.get("Emission Angle")); WriteBand(processPds, outstream, pfile, bandmap.get("Phase Angle")); outstream.close(); processPds.EndProcess(); remove(pfile.toAscii().data()); } catch(IException &) { remove(pfile.toAscii().data()); throw; } catch(...) { remove(pfile.toAscii().data()); throw IException(IException::Unknown, "Unexpected exception caught!", _FILEINFO_); } }
// Construct a BLOb to contain the Hirise main line suffix and prefix data void SaveHiriseAncillaryData (ProcessImportPds &process, Cube *ocube) { vector<int> ConvertCalibrationPixels (int samples, Isis::PixelType pixelType, unsigned char *data); // Setup a Table to hold the main image prefix/suffix data TableField gap("GapFlag", TableField::Integer); TableField line("LineNumber", TableField::Integer); TableField buffer("BufferPixels", TableField::Integer, 12); TableField dark("DarkPixels", TableField::Integer, 16); TableRecord rec; rec += gap; rec += line; rec += buffer; rec += dark; Table table("HiRISE Ancillary", rec); table.SetAssociation (Table::Lines); // Loop through all the prefix and suffix data and construct the table records // In the case of HiRISE there is only one band so the outside vector // only contains one entry. The inside vector contains nl entries. vector<vector<char *> > pre = process.DataPrefix(); vector<vector<char *> > suf = process.DataSuffix(); vector<char *> prefix = pre.at(0); vector<char *> suffix = suf.at(0); Progress progress; progress.SetText("Saving ancillary data"); progress.SetMaximumSteps(prefix.size()); progress.CheckStatus(); for (unsigned int l=0; l<prefix.size(); l++) { unsigned char *linePrefix = (unsigned char *)(prefix[l]); // Pull out the gap byte (in byte 0) rec[0] = (int)(linePrefix[0]); // Pull out the line number (bytes 3-5 3=MSB, 5=LSB) int lineCounter = 0; lineCounter += ((int)(linePrefix[3])) << 16; lineCounter += ((int)(linePrefix[4])) << 8; lineCounter += ((int)(linePrefix[5])); rec[1] = lineCounter; // Pull the 12 buffer pixels (same type as image data) // from the image prefix area linePrefix += 6; section = 3; rec[2] = ConvertCalibrationPixels (12, process.PixelType(),linePrefix); linePrefix += 12 * SizeOf(process.PixelType()); // Pull the 16 dark pixels (same type as image data) // from the image suffix area unsigned char *lineSuffix = (unsigned char *)(suffix[l]); section = 5; rec[3] = ConvertCalibrationPixels (16, process.PixelType(),lineSuffix); lineSuffix += 16 * SizeOf(process.PixelType()); // Add this record to the table table += rec; // Report the progress progress.CheckStatus(); } // Add the table to the output cube ocube->Write(table); }
void IsisMain() { // Get the list of cubes to stack Process p; UserInterface &ui = Application::GetUserInterface(); FileList cubeList(ui.GetFileName("FROMLIST")); // Loop through the list int nsamps(0), nlines(0), nbands(0); PvlGroup outBandBin("BandBin"); try { for(int i = 0; i < cubeList.size(); i++) { Cube cube; CubeAttributeInput inatt(cubeList[i].original()); vector<QString> bands = inatt.bands(); cube.setVirtualBands(bands); cube.open(cubeList[i].toString()); if(i == 0) { nsamps = cube.sampleCount(); nlines = cube.lineCount(); nbands = cube.bandCount(); } else { // Make sure they are all the same size if((nsamps != cube.sampleCount()) || (nlines != cube.lineCount())) { QString msg = "Spatial dimensions of cube [" + cubeList[i].toString() + "] does not match other cubes in list"; throw IException(IException::User, msg, _FILEINFO_); } // Get the total number of bands nbands += cube.bandCount(); } // Build up the band bin group PvlObject &isiscube = cube.label()->findObject("IsisCube"); if(isiscube.hasGroup("BandBin")) { PvlGroup &inBandBin = isiscube.findGroup("BandBin"); for(int key = 0; key < inBandBin.keywords(); key++) { PvlKeyword &inKey = inBandBin[key]; if(!outBandBin.hasKeyword(inKey.name())) { outBandBin += inKey; } else { PvlKeyword &outKey = outBandBin[inKey.name()]; for(int index = 0; index < (int)inKey.size(); index++) { outKey.addValue(inKey[index], inKey.unit(index)); } } } } cube.close(); } } catch(IException &e) { QString msg = "Invalid cube in list file [" + ui.GetFileName("FROMLIST") + "]"; throw IException(e, IException::User, msg, _FILEINFO_); } // Setup to propagate from the first input cube ProcessByLine p2; CubeAttributeInput inatt; int index = 0; if(ui.WasEntered("PROPLAB")) { bool match = false; QString fname = ui.GetFileName("PROPLAB"); for(int i = 0; i < cubeList.size(); i++) { if(fname == cubeList[i].toString()) { index = i; match = true; break; } } if(!match) { QString msg = "FileName [" + ui.GetFileName("PROPLAB") + "] to propagate labels from is not in the list file [" + ui.GetFileName("FROMLIST") + "]"; throw IException(IException::User, msg, _FILEINFO_); } } p2.SetInputCube(cubeList[index].toString(), inatt); // Create the output cube Cube *ocube = p2.SetOutputCube("TO", nsamps, nlines, nbands); p2.ClearInputCubes(); p2.Progress()->SetText("Allocating cube"); p2.StartProcess(NullBand); // Add the band bin group if necessary if(outBandBin.keywords() > 0) { ocube->putGroup(outBandBin); } p2.EndProcess(); // Now loop and mosaic in each cube int sband = 1; for(int i = 0; i < cubeList.size(); i++) { ProcessMosaic m; m.SetBandBinMatch(false); Progress *prog = m.Progress(); prog->SetText("Adding band " + toString((int)i + 1) + " of " + toString(nbands)); m.SetOutputCube("TO"); CubeAttributeInput attrib(cubeList[i].toString()); Cube *icube = m.SetInputCube(cubeList[i].toString(), attrib); m.SetImageOverlay(ProcessMosaic::PlaceImagesOnTop); m.StartProcess(1, 1, sband); sband += icube->bandCount(); m.EndProcess(); } }