// // Programmer: Craig Stuart Sapp // Creation Date: Sat May 12 04:36:30 PDT 2007 (derived from hicor) // Last Modified: Sat May 12 04:36:45 PDT 2007 // Filename: ...sig/examples/all/hicor.cpp // Web Address: http://sig.sapp.org/examples/museinfo/archetype/archetype.cpp // Syntax: C++; museinfo // // Description: Generate a hierarchical correlation plots compared to // input data. // #include "Options.h" #include "PixelColor.h" #include #include #include #include #include #include using namespace std; #define COLOR_BW 0 #define COLOR_HUE 1 #define SHAPE_TRIANGLE 0 #define SHAPE_RECTANGLE 1 // function declarations: void checkOptions (Options& opts, int argc, char** argv); void example (void); void usage (const string& command); void calculateAverage (vector >& correlations, vector& a); void calculateCorrelations (vector >& correlations, vector& a, vector& b); double pearsonCorrelation (int size, double* a, double* b); double getMean (int size, double* a); void printImageTriangle (vector >& correlation); void printImageRectangle (vector >& correlation); void printCorrelationPixel (double value, int style); double average (int size, double* data); void normalizeAverageData (vector >& correlations); double getStandardDeviation (double mean, vector& data); int logScale (int level, int maxlevel, double factor); void calculateAverageDifference(vector >& correlations, vector& a, vector& b); void makeSineArch (vector& arch, int size); void makeRamp (vector& ramp, int size); void calculateArchCorrelations(vector >& correlations, vector& a); void calculateRampCorrelations(vector >& correlations, vector& a); // User interface variables: Options options; int dataq = 0; // debug: display input data only with -d int correlq = 0; // debug: display correlations with -c int colortype = COLOR_BW; // used with various color options int plotshape = SHAPE_TRIANGLE; // used with -r option int averageq = 0; // used with -a option int diffq = 0; // display average differences with -d option int condiffq = 0; // display contoured differences, --cd option int column = 0; // used with -n option (for averaging) int logq = 0; // used with -g option double logfactor = 1500; // used with -f option int flipq = 0; // flip the data from tempo to duration int polyq = 0; // used with -p option int archq = 0; // used with -A option int rampq = 0; // used with -R option int maxheight = -1; // used with --height option int gradientq = 0; // used with -G option ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); double aval; double bval; vector a; vector b; a.reserve(100000); b.reserve(100000); ifstream infile; string filename = ""; if (options.getArgCount() <= 0) { filename = ""; } else { filename = options.getArg(1); #ifndef OLDCPP infile.open(filename, ios::in); #else infile.open(filename, ios::in | ios::nocreate); #endif } if (!infile.is_open()) { cerr << "Cannot open file for reading: " << filename << endl; exit(1); } char templine[4096]; if (averageq) { while (!infile.eof()) { infile.getline(templine, 4096, '\n'); if (infile.eof() && (strcmp(templine, "") == 0)) { break; } else if (sscanf(templine, "%lf\t%lf", &aval, &bval) == 2) { if (flipq) { aval = 60.0 / aval; bval = 60.0 / bval; } a.push_back(aval); b.push_back(bval); } else if (sscanf(templine, "%lf", &aval) == 1) { if (flipq) { aval = 60.0 / aval; } a.push_back(aval); b.push_back(aval); } } } else { while (!infile.eof()) { infile.getline(templine, 4096, '\n'); if (infile.eof() && (strcmp(templine, "") == 0)) { break; } else { if (sscanf(templine, "%lf\t%lf", &aval, &bval) == 2) { if (flipq) { aval = 60.0 / aval; bval = 60.0 / bval; } a.push_back(aval); b.push_back(bval); } } } } int i, j; if (dataq) { for (i=0; i<(int)a.size(); i++) { cout << a[i] << "\t" << b[i] << endl; } exit(0); } vector > correlations; correlations.resize(a.size()); for (i=0; i<(int)a.size(); i++) { correlations[i].resize(i+1); } if (averageq) { if (column == 0) { calculateAverage(correlations, a); } else { calculateAverage(correlations, b); } } else if (archq) { calculateArchCorrelations(correlations, a); } else if (rampq) { calculateRampCorrelations(correlations, a); } else if (condiffq || diffq) { calculateAverageDifference(correlations, a, b); } else { calculateCorrelations(correlations, a, b); } if (correlq) { for (i=0; i<(int)correlations.size(); i++) { for (j=0; j<(int)correlations[i].size(); j++) { cout << correlations[i][j]; if (j < (int)correlations[i].size()-1) { cout << '\t'; } } cout << '\n'; } exit(0); } switch (plotshape) { case SHAPE_RECTANGLE: printImageRectangle(correlations); break; case SHAPE_TRIANGLE: default: printImageTriangle(correlations); } return 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // printImageTriangle -- // void printImageTriangle(vector >& correlation) { string background = options.getString("background"); int maxcolumn = correlation.size() * 2; int maxrow = (correlation.size()) * 2; int startrow = 0; if (maxheight > 0 && maxheight < (int)correlation.size()) { startrow = (int)correlation.size() - maxheight; maxrow = (maxheight) * 2; } cout << "P3\n"; cout << maxcolumn << " " << maxrow << "\n"; cout << "255\n"; int i, j; int ii; int datawidth; int bgwidth; for (i=startrow; i<(int)correlation.size(); i++) { ii = i; if (logq) { ii = logScale(i, correlation.size(), logfactor); } datawidth = correlation[ii].size(); bgwidth = (maxcolumn - datawidth * 2)/2; for (j=0; j >& correlation) { int maxcolumn = correlation.size() * 2; int maxrow = ((int)correlation.size()-1) * 2; if (maxheight > 0 && maxheight < maxrow) { maxrow = maxheight; } cout << "P3\n"; cout << maxcolumn << " " << maxrow << "\n"; cout << "255\n"; int i, j; int datawidth; int jstretch; for (i=0; i<(int)correlation.size()-1; i++) { datawidth = correlation[i].size(); for (j=0; j 0) { pc.setColor(255,0,0); } else if (value < 0) { pc.setColor(0,0,255); } else { pc.setColor(255,255,255); } } else if (condiffq) { if (value > 0.210) { pc.setColor(252,41,41); } // red else if (value > 0.150) { pc.setColor(252,41,210); } // pink else if (value > 0.090) { pc.setColor(255,144,41); } // orange else if (value > 0.030) { pc.setColor(223,250,35); } // yellow else if (value > -0.030) { pc.setColor(239,239,239); } // whiteish else if (value > -0.090) { pc.setColor(148,247,138); } // green else if (value > -0.150) { pc.setColor(82,246,221); } // lt blue else if (value > -0.210) { pc.setColor(36,59,227); } // dk blue else if (value <= -0.210) { pc.setColor(80,4,184); } // violet } cout << " "; pc.writePpm3(cout); cout << " "; // repeat the cell for a square image cout << " "; pc.writePpm3(cout); cout << " "; } ////////////////////////////// // // calculateAverage -- // void calculateAverage(vector >& correlations, vector& a) { int i, j; double *aa; int rowsize; int corelsize; for (i=0; i<(int)correlations.size()-1; i++) { rowsize = correlations[i].size(); corelsize = (int)a.size() - i; for (j=0; j >& correlations) { int i, j; double mean = 0.0; for (i=0; i<(int)correlations[(int)correlations.size()-1].size(); i++) { mean += correlations[(int)correlations.size()-1][i]; } mean = mean / correlations.size(); double sd = getStandardDeviation(mean,correlations[(int)correlations.size()-1]); double& center = mean; double width = 4 * sd; for (i=0; i<(int)correlations.size(); i++) { for (j=0; j<(int)correlations[i].size(); j++) { correlations[i][j] = SIGMOID(correlations[i][j], center, width)*2-1; } } } ////////////////////////////// // // getStandardDeviation -- // double getStandardDeviation(double mean, vector& data) { double sum = 0.0; double value; int i; for (i=0; i<(int)data.size(); i++) { value = data[i] - mean; sum += value * value; } return sqrt(sum / data.size()); } ////////////////////////////// // // calculateAverageDifference -- // void calculateAverageDifference(vector >& correlations, vector& a, vector& b) { int i, j; double *aa; double *bb; double aval = 1.0; double bval = 1.0; int rowsize; int corelsize; for (i=0; i<(int)correlations.size(); i++) { rowsize = correlations[i].size(); corelsize = (int)a.size() - i; for (j=0; j >& correlations, vector& a, vector& b) { int i, j; double *aa; double *bb; int rowsize; int corelsize; for (i=0; i<(int)correlations.size()-1; i++) { rowsize = correlations[i].size(); corelsize = (int)a.size() - i; for (j=0; j 1) { column = 1; } dataq = opts.getBoolean("data"); correlq = opts.getBoolean("correlation"); if (opts.getBoolean("hue")) { colortype = COLOR_HUE; } if (opts.getBoolean("rectangle")) { plotshape = SHAPE_RECTANGLE; } } ////////////////////////////// // // makeSineArch -- generate a sqrt sine half-cycle arch of the // specified length. // void makeSineArch(vector& arch, int size) { arch.resize(size); if (size == 1) { arch[0] = 0; return; } int i; double freq = 2.0 * M_PI / ((size-1) * 2.0); for (i=0; i& ramp, int size) { ramp.resize(size); if (size == 1) { ramp[0] = 0; } double factor = 1.0 / (size - 1.0); int i; for (i=0; i >& correlations, vector& a) { vector arch; int i, j; double *aa; double *bb; int rowsize; int corelsize; for (i=0; i<(int)correlations.size()-1; i++) { makeSineArch(arch, i+1); rowsize = correlations[i].size(); corelsize = (int)a.size() - i; makeSineArch(arch, corelsize); for (j=0; j >& correlations, vector& a) { vector ramp; int i, j; double *aa; double *bb; int rowsize; int corelsize; for (i=0; i<(int)correlations.size()-1; i++) { rowsize = correlations[i].size(); corelsize = (int)a.size() - i; makeRamp(ramp, corelsize); for (j=0; j