|
Isis 3.0 Application Source Code Reference |
Home |
00001 #include "Isis.h" 00002 00003 #include <QString> 00004 #include <vector> 00005 00006 #include "ProcessByLine.h" 00007 00008 #include "Pvl.h" 00009 #include "MultivariateStatistics.h" 00010 00011 using namespace std; 00012 using namespace Isis; 00013 00014 std::vector< vector<double> > covariance; 00015 std::vector< vector<double> > correlation; 00016 MultivariateStatistics stats; 00017 00018 void MakeStats(vector<Buffer *> &in, vector<Buffer *> &out); 00019 void WriteText(int size, QString filename); 00020 void WriteCube(Buffer &inout); 00021 00022 void IsisMain() { 00023 00024 //Check to see if an output file was specified 00025 UserInterface &ui = Application::GetUserInterface(); 00026 if(!ui.WasEntered("CUBE") && !ui.WasEntered("FLATFILE")) { 00027 QString message = "At least one output file must be entered"; 00028 throw IException(IException::User, message, _FILEINFO_); 00029 } 00030 00031 QString file = ui.GetFileName("FROM"); 00032 00033 //Use a Process to get the number of bands in the input cube 00034 Process q; 00035 Cube *icube = q.SetInputCube("FROM"); 00036 int bands = icube->bandCount(); 00037 00038 //Check to see if the input cube has enough bands 00039 if(bands < 2) { 00040 QString message = "Input band must have at least two bands!"; 00041 throw IException(IException::User, message, _FILEINFO_); 00042 } 00043 00044 //Set the matrices according to the number of bands in the input cube 00045 covariance.resize(bands); 00046 correlation.resize(bands); 00047 for(int i = 0; i < bands ; ++i) { 00048 covariance[i].resize(bands); 00049 correlation[i].resize(bands); 00050 } 00051 00052 //Loop through the bands, systematically ensuring that 00053 //each band is compared against each other band. 00054 for(int i = 1 ; i <= bands ; ++i) { 00055 for(int j = i ; j <= bands ; j++) { 00056 //Reset Stat accumulators and set the Progress Display Text 00057 stats.Reset(); 00058 QString progText = "Band " + toString(i) + 00059 " vs. " + 00060 "Band " + toString(j); 00061 00062 //Cube will be processed by line 00063 ProcessByLine p; 00064 00065 //Set CubeAttributeInputs to tell the ProcessByLine which 00066 //bands to compare 00067 CubeAttributeInput band_a("d+" + toString(icube->physicalBand(i))); 00068 CubeAttributeInput band_b("d+" + toString(icube->physicalBand(j))); 00069 00070 //Set Input files and process, to accumulate the statistics 00071 p.SetInputCube(file, band_a); 00072 p.SetInputCube(file, band_b); 00073 Progress *progress = p.Progress(); 00074 progress->SetText(progText); 00075 p.StartProcess(MakeStats); 00076 p.EndProcess(); 00077 00078 //If the bands are the same, use the Variance of one, and a Correlation 00079 //of 1, for speed and simplicity 00080 if(i == j) { 00081 covariance[i-1][j-1] = stats.X().Variance(); 00082 correlation[i-1][j-1] = 1.0; 00083 } 00084 //Otherwise, set the matrix to the appropriate value 00085 else { 00086 covariance[i-1][j-1] = stats.Covariance(); 00087 correlation[i-1][j-1] = stats.Correlation(); 00088 } 00089 } 00090 } 00091 //Mirror the matrices to create a full representation, instead 00092 //of half-matrices 00093 for(int i = 0; i < bands; ++i) { 00094 for(int j = 0; j < bands; ++j) { 00095 covariance[j][i] = covariance[i][j]; 00096 correlation[j][i] = correlation[i][j]; 00097 } 00098 } 00099 //Write the output file(s) 00100 if(ui.WasEntered("FLATFILE")) { 00101 WriteText(bands, ui.GetFileName("FLATFILE")); 00102 } 00103 if(ui.WasEntered("CUBE")) { 00104 //Set the Band Names 00105 PvlKeyword name("Name"); 00106 name += "Correlation"; 00107 name += "Covariance"; 00108 PvlGroup bandBin("BandBin"); 00109 bandBin += name; 00110 00111 //Set up the Process and the OutputCube, and Process 00112 ProcessByLine p; 00113 CubeAttributeOutput set; 00114 set.setPixelType(Real); 00115 Cube *ocube = p.SetOutputCube(ui.GetFileName("CUBE"), 00116 set, bands, bands, 2); 00117 p.StartProcess(WriteCube); 00118 ocube->putGroup(bandBin); 00119 p.EndProcess(); 00120 } 00121 } 00122 00123 //Function to gather the data and feed them to a 00124 //MultivariateStatistics container 00125 void MakeStats(vector<Buffer *> &in, vector<Buffer *> &out) { 00126 double *x = in[0]->DoubleBuffer(); 00127 double *y = in[1]->DoubleBuffer(); 00128 00129 stats.AddData(x, y, in[0]->size()); 00130 } 00131 00132 //Function to generate a flatfile to represent the matrices 00133 void WriteText(int size, QString filename) { 00134 ofstream outputFile; 00135 outputFile.open(filename.toAscii().data()); 00136 QString line = " "; 00137 outputFile << "Correlation:" << endl << endl; 00138 for(int i = 0; i < size; ++i) { 00139 for(int j = 0; j < size; ++j) { 00140 line += " " + toString(correlation[i][j]) + " "; 00141 } 00142 outputFile << line << endl; 00143 line = " "; 00144 } 00145 00146 outputFile << endl << endl << "Covariance:" << endl << endl; 00147 for(int i = 0; i < size; ++i) { 00148 for(int j = 0; j < size; ++j) { 00149 line += " " + toString(covariance[i][j]) + " "; 00150 } 00151 outputFile << line << endl; 00152 line = " "; 00153 } 00154 outputFile.close(); 00155 } 00156 00157 //Function to write the 2 band cube containing representions 00158 //of the two matrices 00159 void WriteCube(Buffer &inout) { 00160 if(inout.Band() == 1) { 00161 for(int i = 0; i < inout.size(); ++i) { 00162 inout[i] = correlation[inout.Line()-1][i]; 00163 } 00164 } 00165 else if(inout.Band() == 2) { 00166 for(int i = 0; i < inout.size(); ++i) { 00167 inout[i] = covariance[inout.Line()-1][i]; 00168 } 00169 } 00170 } 00171