USGS

Isis 3.0 Application Source Code Reference

Home

mvstats.cpp

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