USGS

Isis 3.0 Application Source Code Reference

Home

bandnorm.cpp

Go to the documentation of this file.
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 }