|
Isis 3.0 Application Source Code Reference |
Home |
00001 #include "Isis.h" 00002 00003 // system include files go first 00004 #include <string> 00005 #include <iostream> 00006 #include <iomanip> 00007 #include <vector> 00008 #include <algorithm> 00009 00010 // Isis specific include files go next 00011 #include "ProcessByLine.h" 00012 #include "SpecialPixel.h" 00013 #include "iException.h" 00014 #include "Pvl.h" 00015 #include "TextFile.h" 00016 #include "Statistics.h" 00017 00018 using namespace std; 00019 using namespace Isis; 00020 00021 static vector<int> band; 00022 static vector<double> average; 00023 static vector<double> normalizer; 00024 00025 // function prototypes 00026 void getStats(Buffer &in); 00027 void normalize(Buffer &in, Buffer &out); 00028 void Tokenize( const string& str, 00029 vector<string> & tokens, 00030 const string& delimiters = " " ); 00031 00032 void IsisMain() { 00033 // We will be processing by line 00034 ProcessByLine p; 00035 00036 // Setup the input cube 00037 UserInterface &ui = Application::GetUserInterface(); 00038 Cube *icube = p.SetInputCube("FROM"); 00039 00040 // Now get the statistics for each band or the entire cube 00041 string avg = ui.GetString("AVERAGE"); 00042 p.StartProcess(getStats); 00043 if (avg == "BAND") { 00044 int b = 0; 00045 Statistics stats; 00046 for (int i=0; i<(int)average.size(); i++) { 00047 if (b == band[i]) { 00048 stats.AddData(&average[i],(unsigned int)1); 00049 } 00050 else { 00051 normalizer.push_back(stats.Average()); 00052 b++; 00053 stats.Reset(); 00054 } 00055 } 00056 normalizer.push_back(stats.Average()); 00057 } 00058 else if( avg == "PENCIL" ) { 00059 TextFile pencil; 00060 pencil.Open( ui.GetFilename("SPECTRUM") ); 00061 if( pencil.LineCount()-1 < icube->Bands()) { 00062 string msg = "The spectral pencil file [" + ui.GetAsString("SPECTRUM") + 00063 "] does not contain enough data for all bands."; 00064 throw iException::Message(iException::User,msg,_FILEINFO_); 00065 } 00066 string st; 00067 int column=-1; 00068 vector<string> tokens; 00069 pencil.GetLine( st ); //Takes care of title line 00070 Tokenize( st, tokens, ", \"-+" ); 00071 if( ui.GetAsString("METHOD") == "number" ) { 00072 column = ui.GetInteger("NUMBER"); 00073 } 00074 else { 00075 for( unsigned i=0; i<tokens.size(); i++ ) { 00076 if( tokens[i] == ui.GetString("NAME") ) { 00077 column = i; 00078 break; 00079 } 00080 } 00081 } 00082 if( column < 0 || (unsigned)column > tokens.size() ) { 00083 string msg = "The column specified in file ["+ ui.GetFilename("SPECTRUM") 00084 + "] was not found."; 00085 throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_); 00086 } 00087 // Add the correct column of data to normalizer 00088 for( int i=0; i<icube->Bands(); i++ ) { 00089 tokens.clear(); 00090 pencil.GetLine( st ); 00091 Tokenize( st, tokens, ", \"" ); 00092 normalizer.push_back( Isis::iString(tokens[column]).ToDouble() ); 00093 } 00094 } 00095 else { // avg == "CUBE" 00096 Statistics stats; 00097 for (int i=0; i<(int)average.size(); i++) { 00098 stats.AddData(&average[i],(unsigned int)1); 00099 } 00100 for (int b=0; b<icube->Bands(); b++) { 00101 normalizer.push_back(stats.Average()); 00102 } 00103 } 00104 00105 // Setup the output file and apply the correction 00106 p.SetOutputCube("TO"); 00107 p.StartProcess(normalize); 00108 00109 // Cleanup 00110 p.EndProcess(); 00111 normalizer.clear(); 00112 band.clear(); 00113 } 00114 00115 //********************************************************** 00116 // Get statistics on a band or entire cube 00117 //********************************************************** 00118 void getStats(Buffer &in) { 00119 Statistics stats; 00120 stats.AddData(in.DoubleBuffer(),in.size()); 00121 average.push_back(stats.Average()); 00122 band.push_back(in.Band()-1); 00123 } 00124 00125 // Apply coefficients 00126 void normalize(Buffer &in, Buffer &out) { 00127 int index = in.Band()-1; 00128 double coeff = normalizer[index]; 00129 00130 // Now loop and apply the coefficents 00131 for (int i=0; i<in.size(); i++) { 00132 if (IsSpecial(in[i])) { 00133 out[i] = in[i]; 00134 } 00135 else { 00136 out[i] = Null; 00137 if (coeff != 0.0 && IsValidPixel(coeff)) { 00138 out[i] = in[i]/coeff; 00139 } 00140 } 00141 } 00142 } 00143 00144 // Tokenizer 00145 void Tokenize( const string& str, 00146 vector<string> & tokens, 00147 const string& delimiters ) 00148 { 00149 //Skip delimiters at the beginning 00150 string::size_type lastPos = str.find_first_not_of(delimiters, 0); 00151 // Find first "non-delimiter". 00152 string::size_type pos = str.find_first_of(delimiters, lastPos); 00153 00154 while( string::npos != pos || string::npos != lastPos ) { 00155 // Found a token, add it to the vector 00156 tokens.push_back( str.substr( lastPos, pos - lastPos ) ); 00157 // Skip delimiters 00158 lastPos = str.find_first_not_of( delimiters, pos); 00159 // Find next "non-delimiter" 00160 pos = str.find_first_of(delimiters, lastPos); 00161 } 00162 }