|
Isis 3.0 Application Source Code Reference |
Home |
00001 #include "Isis.h" 00002 00003 #include <set> 00004 #include <stack> 00005 #include <sstream> 00006 00007 #include "UserInterface.h" 00008 #include "ControlNet.h" 00009 #include "Filename.h" 00010 #include "FileList.h" 00011 #include "SerialNumber.h" 00012 #include "CameraFactory.h" 00013 #include "ProjectionFactory.h" 00014 #include "PvlGroup.h" 00015 #include "PvlKeyword.h" 00016 #include "iString.h" 00017 00018 using namespace std; 00019 using namespace Isis; 00020 00021 map< string, set<string> > constructPointSets(set<string> &index, 00022 ControlNet &innet); 00023 vector< set<string> > findIslands(set<string> &index, map< string, 00024 set<string> > &adjCubes); 00025 void WriteOutput( map<string,string> num2cube, string suffix, 00026 set<string> &sns, map< string, set<string> > &cps ); 00027 00028 // Main program 00029 void IsisMain() { 00030 Progress progress; 00031 UserInterface &ui = Application::GetUserInterface(); 00032 ControlNet innet( ui.GetFilename("CNET"), NULL, true ); 00033 iString prefix(ui.GetString("PREFIX")); 00034 bool ignore = ui.GetBoolean("IGNORE"); 00035 00036 // Sets up the list of serial numbers for 00037 FileList inlist(ui.GetFilename("FROMLIST")); 00038 set<iString> inListNums; 00039 map<iString,int> netSerialNumCount; 00040 vector<iString> listedSerialNumbers; 00041 map< string, string > num2cube; 00042 00043 if (inlist.size() > 0) { 00044 progress.SetText("Initializing"); 00045 progress.SetMaximumSteps(inlist.size()); 00046 progress.CheckStatus(); 00047 } 00048 00049 for(int index = 0; index < (int)inlist.size(); index ++) { 00050 iString st = SerialNumber::Compose(inlist[index]); 00051 inListNums.insert(st); 00052 listedSerialNumbers.push_back(st); // Used with nonListedSerialNumbers 00053 num2cube[st] = inlist[index]; // Used as a SerialNumber to Cube index 00054 progress.CheckStatus(); 00055 } 00056 00057 vector<iString> nonListedSerialNumbers; 00058 00059 set<string> singleMeasureSerialNumbers; 00060 map< string, set<string> > singleMeasureControlPoints; 00061 00062 set<string> duplicateSerialNumbers; 00063 map< string, set<string> > duplicateControlPoints; 00064 00065 set<string> noLatLonSerialNumbers; 00066 map< string, set<string> > noLatLonControlPoints; 00067 set<string> latlonchecked; 00068 00069 if (innet.Size() > 0) { 00070 progress.SetText("Calculating"); 00071 progress.SetMaximumSteps(innet.Size()); 00072 progress.CheckStatus(); 00073 } 00074 00075 for(int cp = 0; cp < innet.Size(); cp ++) { 00076 if(ignore && innet[cp].Ignore()) continue; 00077 00078 ControlPoint controlpt(innet[cp]); 00079 00080 // Checks for lat/Lon production 00081 if( ui.GetBoolean("NOLATLON") ) { 00082 for (int cm = 0; cm < controlpt.Size(); cm ++) { 00083 ControlMeasure controlms= controlpt[cm]; 00084 00085 // Make sure a cube is not checked twice 00086 if ( !num2cube[controlms.CubeSerialNumber()].empty() && 00087 latlonchecked.find(controlms.CubeSerialNumber()) == latlonchecked.end() ) { 00088 latlonchecked.insert( controlms.CubeSerialNumber() ); 00089 00090 Pvl pvl( num2cube[controlms.CubeSerialNumber()] ); 00091 Camera *camera( CameraFactory::Create( pvl ) ); 00092 if (camera == NULL) { 00093 try { 00094 // Checking if the Projection can be made 00095 delete ProjectionFactory::Create( pvl ); 00096 } catch ( iException &e ) { 00097 noLatLonSerialNumbers.insert(controlms.CubeSerialNumber()); 00098 noLatLonControlPoints[controlms.CubeSerialNumber()].insert( controlpt.Id() ); 00099 e.Clear(); 00100 } 00101 } 00102 else if(!camera->SetImage(controlms.Sample(), controlms.Line())) { 00103 noLatLonSerialNumbers.insert(controlms.CubeSerialNumber()); 00104 noLatLonControlPoints[controlms.CubeSerialNumber()].insert( controlpt.Id() ); 00105 } 00106 delete camera; 00107 } 00108 } 00109 } 00110 00111 // Checks of the ControlPoint has only 1 Measure 00112 if(controlpt.NumValidMeasures() == 1) { 00113 string sn = controlpt[0].CubeSerialNumber(); 00114 singleMeasureSerialNumbers.insert(sn); 00115 singleMeasureControlPoints[sn].insert( controlpt.Id() ); 00116 } 00117 else { 00118 // Checks for duplicate Measures for the same SerialNumber 00119 vector<ControlMeasure> controlMeasures; 00120 for(int cm = 0; cm < controlpt.Size(); cm ++) { 00121 if( ignore && controlpt[cm].Ignore() ) continue; 00122 00123 controlMeasures.push_back(controlpt[cm]); 00124 iString currentsn = controlpt[cm].CubeSerialNumber(); 00125 00126 // Compares previous ControlMeasure SerialNumbers with the current 00127 for(int pre_cm = controlMeasures.size()-1-1; pre_cm >= 0; pre_cm --) { 00128 if( controlMeasures[pre_cm].CubeSerialNumber() == currentsn ) { 00129 duplicateSerialNumbers.insert(currentsn); //serial number duplication 00130 duplicateControlPoints[currentsn].insert( controlpt.Id() ); 00131 } 00132 } 00133 00134 // Removes from the serial number list, cubes that are included in the cnet 00135 inListNums.erase( currentsn ); 00136 netSerialNumCount[currentsn] ++; 00137 00138 // Records if the currentsnum is not in the input cube list 00139 bool contains = false; 00140 for(int sn = 0; sn < (int)listedSerialNumbers.size() && !contains; sn ++) { 00141 if(currentsn == listedSerialNumbers[sn]) { 00142 contains = true; 00143 } 00144 } 00145 // Check if already added 00146 for(int sn = 0; sn < (int)nonListedSerialNumbers.size() && !contains; sn ++) { 00147 if(currentsn == nonListedSerialNumbers[sn]) { 00148 contains = true; 00149 } 00150 } 00151 00152 if(!contains) { 00153 nonListedSerialNumbers.push_back(currentsn); 00154 } 00155 } 00156 } 00157 00158 progress.CheckStatus(); 00159 00160 } 00161 00162 00163 // Checks/detects islands 00164 set<string> index; 00165 map< string, set<string> > adjCubes = constructPointSets(index, innet); 00166 vector< set<string> > islands = findIslands(index, adjCubes); 00167 00168 // Output islands in the file-by-file format 00169 // Islands that have no cubes listed in the input list will 00170 // not be shown. 00171 for(int i=0; i < (int)islands.size(); i++) { 00172 string name(Filename(prefix + "Island." + iString(i+1)).Expanded()); 00173 ofstream out_stream; 00174 out_stream.open(name.c_str(), std::ios::out); 00175 out_stream.seekp(0,std::ios::beg); //Start writing from beginning of file 00176 00177 bool hasList = false; 00178 for(set<string>::iterator island = islands[i].begin(); 00179 island != islands[i].end(); island++) { 00180 if (((string)num2cube[*island]).compare("") != 0) { 00181 out_stream << Filename(num2cube[*island]).Name() << " " << *island; 00182 out_stream << "\n"; 00183 00184 hasList = true; 00185 } 00186 } 00187 00188 out_stream.close(); 00189 00190 if (!hasList) { 00191 remove(name.c_str()); 00192 } 00193 } 00194 00195 00196 // Output the results to screen and files accordingly 00197 00198 PvlGroup results("Results"); 00199 00200 stringstream ss (stringstream::in | stringstream::out); 00201 00202 results.AddKeyword( PvlKeyword("Islands",iString((BigInt)islands.size())) ); 00203 ss << endl << "----------------------------------------" \ 00204 "----------------------------------------" << endl; 00205 if(islands.size() == 1) { 00206 ss << "The cubes are fully connected by the Control Network." << endl; 00207 } 00208 else if(islands.size() == 0) { 00209 ss << "There are no control points in the provided Control Network ["; 00210 ss << Filename(ui.GetFilename("CNET")).Name() << "]" << endl; 00211 } 00212 else { 00213 ss << "The cubes are NOT fully connected by the Control Network." << endl; 00214 ss << "There are " << islands.size() << " disjoint sets of cubes." << endl; 00215 } 00216 00217 if(ui.GetBoolean("SINGLE") && singleMeasureSerialNumbers.size() > 0) { 00218 results.AddKeyword( 00219 PvlKeyword("SingleMeasure",iString((BigInt)singleMeasureSerialNumbers.size())) ); 00220 00221 string name(Filename(prefix + "SinglePointCubes.txt").Expanded()); 00222 WriteOutput( num2cube, name, 00223 singleMeasureSerialNumbers, singleMeasureControlPoints ); 00224 00225 ss << "----------------------------------------" \ 00226 "----------------------------------------" << endl; 00227 ss << "There are " << singleMeasureSerialNumbers.size(); 00228 ss << " cubes in Control Points with only a single"; 00229 ss << " Control Measure." << endl; 00230 ss << "The serial numbers of these measures are listed in ["; 00231 ss << Filename(name).Name() + "]" << endl; 00232 } 00233 00234 if(ui.GetBoolean("DUPLICATE") && duplicateSerialNumbers.size() > 0) { 00235 results.AddKeyword( 00236 PvlKeyword("DuplicateMeasures",iString((BigInt)duplicateSerialNumbers.size())) ); 00237 00238 string name(Filename(prefix + "DuplicateMeasures.txt").Expanded()); 00239 WriteOutput( num2cube, name, 00240 duplicateSerialNumbers, duplicateControlPoints ); 00241 00242 ss << "----------------------------------------" \ 00243 "----------------------------------------" << endl; 00244 ss << "There are " << duplicateSerialNumbers.size(); 00245 ss << " duplicate Control Measures in the"; 00246 ss << " Control Net." << endl; 00247 ss << "The serial numbers of these duplicate Control Measures"; 00248 ss << " are listed in [" + Filename(name).Name() + "]" << endl; 00249 } 00250 00251 if(ui.GetBoolean("NOLATLON") && noLatLonSerialNumbers.size() > 0) { 00252 results.AddKeyword( 00253 PvlKeyword("NoLatLonCubes",iString((BigInt)noLatLonSerialNumbers.size())) ); 00254 00255 string name(Filename(prefix + "NoLatLon.txt").Expanded()); 00256 WriteOutput( num2cube, name, 00257 noLatLonSerialNumbers, noLatLonControlPoints ); 00258 00259 ss << "----------------------------------------" \ 00260 "----------------------------------------" << endl; 00261 ss << "There are " << noLatLonSerialNumbers.size(); 00262 ss << " serial numbers in the Control Network which are listed in the"; 00263 ss << " input list and cannot compute latitude and longitudes." << endl; 00264 ss << "These serial numbers, filenames, and control points are listed in ["; 00265 ss << Filename(name).Name() + "]" << endl; 00266 } 00267 00268 // At this point, inListNums is the list of cubes NOT included in the 00269 // ControlNet, and inListNums are their those cube's serial numbers. 00270 if(ui.GetBoolean("NOCONTROL") && !inListNums.empty() ) { 00271 results.AddKeyword( PvlKeyword("NoControl",iString((BigInt)inListNums.size())) ); 00272 00273 string name(Filename(prefix + "NoControl.txt").Expanded()); 00274 ofstream out_stream; 00275 out_stream.open(name.c_str(), std::ios::out); 00276 out_stream.seekp(0,std::ios::beg); //Start writing from beginning of file 00277 00278 for( set<iString>::iterator sn = inListNums.begin(); 00279 sn != inListNums.end(); 00280 sn ++) { 00281 out_stream << (*sn); 00282 out_stream << "\t" << Filename(num2cube[(*sn)]).Name(); 00283 out_stream << "\n"; 00284 } 00285 00286 out_stream.close(); 00287 00288 ss << "----------------------------------------" \ 00289 "----------------------------------------" << endl; 00290 ss << "There are " << inListNums.size(); 00291 ss << " cubes in the input list [" << Filename(ui.GetFilename("FROMLIST")).Name(); 00292 ss << "] which do not exist or are ignored in the Control Network ["; 00293 ss << Filename(ui.GetFilename("CNET")).Name() << "]" << endl; 00294 ss << "These cubes are listed in [" + Filename(name).Name() + "]" << endl; 00295 } 00296 00297 // In addition, nonListedSerialNumbers should be the SerialNumbers of 00298 // ControlMeasures in the ControlNet that do not have a correlating 00299 // cube in the input list. 00300 if(ui.GetBoolean("NOCUBE") && nonListedSerialNumbers.size() > 0) { 00301 results.AddKeyword( 00302 PvlKeyword("NoCube",iString((BigInt)nonListedSerialNumbers.size())) ); 00303 00304 string name(Filename(prefix + "NoCube.txt").Expanded()); 00305 ofstream out_stream; 00306 out_stream.open(name.c_str(), std::ios::out); 00307 out_stream.seekp(0,std::ios::beg); //Start writing from beginning of file 00308 00309 for(int sn=0; sn < (int)nonListedSerialNumbers.size(); sn++) { 00310 out_stream << nonListedSerialNumbers[sn]; 00311 out_stream << "\n"; 00312 } 00313 00314 out_stream.close(); 00315 00316 ss << "----------------------------------------" \ 00317 "----------------------------------------" << endl; 00318 ss << "There are " << nonListedSerialNumbers.size(); 00319 ss << " serial numbers in the Control Net ["; 00320 ss << Filename(ui.GetFilename("CNET")).Basename(); 00321 ss << "] which do not exist in the input list ["; 00322 ss << Filename(ui.GetFilename("FROMLIST")).Name() << "]" << endl; 00323 ss << "These serial numbers are listed in ["; 00324 ss << Filename(name).Name() + "]" << endl; 00325 } 00326 00327 00328 ss << "----------------------------------------" \ 00329 "----------------------------------------" << endl << endl; 00330 std::string log = ss.str(); 00331 00332 Application::Log(results); 00333 00334 if (ui.IsInteractive()) { 00335 Application::GuiLog(log); 00336 } 00337 else { 00338 cout << ss.str(); 00339 } 00340 00341 } 00342 00343 00344 // Links cubes to other cubes it shares control points with 00345 map< string, set<string> > constructPointSets(set<string> &index, 00346 ControlNet &innet) { 00347 map< string, set<string > > adjPoints; 00348 00349 bool ignore = Application::GetUserInterface().GetBoolean("IGNORE"); 00350 for(int cp=0; cp < innet.Size(); cp++) { 00351 00352 if(ignore && innet[cp].Ignore()) continue; 00353 00354 if(innet[cp].NumValidMeasures() < 2) continue; 00355 00356 ControlPoint controlpt = innet[cp]; 00357 // Map SerialNumbers together based on ControlMeasures 00358 for(int cm1=0; cm1 < controlpt.Size(); cm1++) { 00359 if(ignore && controlpt.Ignore()) continue; 00360 00361 std::string sn = controlpt[cm1].CubeSerialNumber(); 00362 index.insert(sn); 00363 for(int cm2=0; cm2 < controlpt.Size(); cm2++) { 00364 if(ignore && controlpt[cm2].Ignore()) continue; 00365 00366 if(cm1 != cm2) { 00367 adjPoints[ sn ].insert( controlpt[cm2].CubeSerialNumber() ); 00368 } 00369 } 00370 } 00371 00372 } 00373 00374 return adjPoints; 00375 } 00376 00377 00378 // Uses a depth-first search to construct the islands 00379 vector< set<string> > findIslands(set<string> &index, 00380 map< string, set<string> > &adjCubes) { 00381 vector< set<string> > islands; 00382 00383 while(index.size() != 0) { 00384 set<string> connectedSet; 00385 00386 stack<string> str_stack; 00387 set<string>::iterator first = index.begin(); 00388 str_stack.push(*first); 00389 00390 // Depth search 00391 while(true) { 00392 index.erase(str_stack.top()); 00393 connectedSet.insert(str_stack.top()); 00394 00395 // Find the first connected unvisited node 00396 std::string nextNode = ""; 00397 set<string> neighbors = adjCubes[str_stack.top()]; 00398 for (set<string>::iterator i = neighbors.begin(); i != neighbors.end(); i++) { 00399 if (index.count(*i) == 1) { 00400 nextNode = *i; 00401 break; 00402 } 00403 } 00404 00405 if (nextNode != "") { 00406 // Push the unvisited node 00407 str_stack.push(nextNode); 00408 } 00409 else { 00410 // Pop the visited node 00411 str_stack.pop(); 00412 00413 if (str_stack.size() == 0) break; 00414 } 00415 } 00416 00417 islands.push_back(connectedSet); 00418 } 00419 00420 return islands; 00421 } 00422 00423 00424 // Writes the list of cubes [ SerialNumber, Filename, ControlPoints ] to the output file 00425 void WriteOutput( map<string,string> num2cube, string filename, 00426 set<string> &sns, map< string, set<string> > &cps ) { 00427 00428 // Set up the output file for writing 00429 ofstream out_stream; 00430 out_stream.open(filename.c_str(), std::ios::out); 00431 out_stream.seekp(0,std::ios::beg); //Start writing from beginning of file 00432 00433 for( set<string>::iterator sn = sns.begin(); 00434 sn != sns.end(); sn++ ) { 00435 // Serial Number of cube 00436 out_stream << *sn; 00437 00438 // Filename of cube if given 00439 if( !num2cube[*sn].empty() ) { 00440 out_stream << "\t" << Filename(num2cube[*sn]).Name(); 00441 } 00442 else { 00443 out_stream << "\tUnknownFilename"; 00444 } 00445 00446 // Control Points where the cube was found to have the issue 00447 for( set<string>::iterator cp = cps[*sn].begin(); 00448 cp != cps[*sn].end(); cp++ ) { 00449 out_stream << "\t" << *cp; 00450 } 00451 00452 out_stream << "\n"; 00453 } 00454 00455 out_stream.close(); 00456 }