// Testing tool for FermiLab Physics Class Library // This program is an interactive environment for creating histograms. // Histograms can be created, and most histogram (HepHist*) member // functions can be applied. // If the program crashes, it is more likely that my code has errors, // not the library. The approach this program takes it to verify that // the simple histogram operations - creation and accumulation - work // as intended. // Profile histograms are not yet well-supported because they deserve a // more careul examination than just a bin-by-bin comparison. // History: // 12-Jun-1997 Jason Luther Created // Zoom Histograms #include "TestManager.h" #include "HepTuple/HepFileManager.h" #include "HepTuple/HepHist1D.h" #include "HepTuple/HepHist2D.h" #include "HepTuple/HepHistProf.h" // The only current implementation is the wrapper for CERNLib HBook // #include "HepTuple/HepHBookFileManager.h" // JList is my list class - it is perhaps not well implemented #include "jlist.hh" // Tag Types for the list #include "tag.hh" #include "ZMutility/iostream" USING( namespace std ) ZM_USING_NAMESPACE( zmht ) // This test program provides a way to interact with histograms (and // later, ntuples). It has a main menu where histogram objects can be // created and manipulated. // global varibles HepFileManager* M; JList* HistList = new JList; // histogram list const int BUFFERSIZE(255); const int RANDLIMIT(100); // prototypes void menu(); void makeNew1D(); void makeNew2D(); void makeNewProf(); void displayList(); void fillHistCall(); void fillHist(HepHist1D*); void fillHist(HepHist2D*); void fillHist(HepHistProf*); bool compareHist(HepHist1D* h1, HepHist1D* h2); bool compareHist(HepHist2D* h1, HepHist2D* h2); bool compareHist(HepHistProf* h1, HepHistProf* h2); void clone(); void newEmpty(); void compare(); void deleteHist(); void readHistCall(); void writeCall(); void resetCall(); void printSums(); // main() - the menu interface int main(int argc, char** argv) { const int FILENAMESIZE(255); // get comandline arguments PARSE; // create the file manager char filename[FILENAMESIZE]; cout << "Filename for file manager: "; cin >> filename; HepFileManager* m = OPEN_FILE(filename); if (m == NULL ) { cerr << "Could not open file\n"; ::exit(-1); } cout << "File manager '" << filename << "' was created. \n" << endl; M = m; // set the global file manager // present menu menu(); int response = 0; // get user option while (1) { cout << "Enter your choice. 0 will show the command menu: "; cin >> response; if (response == 99) break; switch (response) { case 0: menu(); break; case 1: makeNew1D(); break; case 2: makeNew2D(); break; case 3: makeNewProf(); break; case 4: displayList(); break; case 5: fillHistCall(); break; case 6: readHistCall(); break; case 7: clone(); break; case 8: newEmpty(); break; case 9: compare(); break; case 10: deleteHist(); break; case 11: // write the histograms writeCall(); break; case 12: resetCall(); break; case 13: printSums(); break; default: menu(); } } // delete the manager and the HistList delete HistList; // histList should NOT delete the HepObj // to work around we delete them BEFORE the manager. delete M; return 0; } void menu() { cout << "\t--- Zoom Test Suite options: ---" << endl; cout << "\t 0.\tShow this menu.\n"; cout << "\t 1.\tCreate a 1D histogram.\n"; cout << "\t 2.\tCreate a 2D histogram.\n"; cout << "\t 3.\tCreate a profile histogram.\n"; cout << "\t 4.\tView histogram list.\n"; cout << "\t 5.\tFill a histogram with random data.\n"; cout << "\t 6.\tRead out the bins of a histogram.\n"; cout << "\t 7.\tClone a histogram.\n"; cout << "\t 8.\tCreate a new empty histogram from an existing histogram.\n"; cout << "\t 9.\tCompare two histograms.\n"; cout << "\t10.\tDelete a histogram.\n"; cout << "\t11.\tWrite the histograms to the data file.\n"; cout << "\t12.\tReset a histogram.\n"; cout << "\t13.\tPrint sums of values.\n"; cout << "\t99.\tExit the test program.\n"; cout << endl; return; } // create a new hist1d and add it to the list void makeNew1D() { char name[BUFFERSIZE]; cout << "Enter the name of the histogram: "; cin >> name; int id = 0; cout << "Enter the id number of the histogram (use 0 for Auto): "; cin >> id; int nBins = 0; cout << "Enter the number of bins: "; cin >> nBins; float low; cout << "Enter the minimum: "; cin >> low; float high; cout << "Enter the maximum: "; cin >> high; // create the histogram HepHist1D* h = & M->hist1D(name, nBins, low, high, id); // add to list HistList->add((HepHist*)h, HEPHIST1D); cout << "Histogram '" << name << "' was created. " << endl; return; } // create a new hist2d and add it to the list void makeNew2D() { char name[BUFFERSIZE]; cout << "Enter the name of the histogram: "; cin >> name; int id = 0; cout << "Enter the id number of the histogram (use 0 for Auto): "; cin >> id; int nBinsX = 0; cout << "Enter the number of X bins: "; cin >> nBinsX; float lowX; cout << "Enter the X minimum: "; cin >> lowX; float highX; cout << "Enter the X maximum: "; cin >> highX; int nBinsY = 0; cout << "Enter the number of Y bins: "; cin >> nBinsY; float lowY; cout << "Enter the Y minimum: "; cin >> lowY; float highY; cout << "Enter the Y maximum: "; cin >> highY; // create the histogram HepHist2D* h = & M->hist2D(name, nBinsX, lowX, highX, nBinsY, lowY, highY, id); // add to list HistList->add((HepHist*)h, HEPHIST2D); cout << "Histogram '" << name << "' was created. " << endl; return; } // create a new histProf and add it to the list void makeNewProf() { char name[BUFFERSIZE]; cout << "Enter the name of the histogram: "; cin >> name; int id = 0; cout << "Enter the id number of the histogram (use 0 for Auto): "; cin >> id; int nBinsX = 0; cout << "Enter the number of X bins: "; cin >> nBinsX; float lowX; cout << "Enter the X minimum: "; cin >> lowX; float highX; cout << "Enter the X maximum: "; cin >> highX; float lowY; cout << "Enter the Y minimum: "; cin >> lowY; float highY; cout << "Enter the Y maximum: "; cin >> highY; // char chopt[BUFFERSIZE]; // cout << "Enter the options: "; // cin >> chopt; // create the histogram // HepHistProf* h = M->newHistProf(name, nBinsX, lowX, highX, // lowY, highY, chopt, id); HepHistProf* h = & M->histProf(name, nBinsX, lowX, highX, lowY, highY, id); // add to list HistList->add((HepHist*)h, HEPHISTPROF); cout << "Histogram '" << name << "' was created. " << endl; return; } void displayList() { cout << endl; HistList->print(); return; } void deleteHist() { displayList(); cout << "Enter the number of the histogram you would like to delete: "; int id; cin >> id; if (id == 0) return; //cancel HistList->del(id); } void fillHistCall() { cout << "Enter the number of the histogram you would like to fill: "; int id; cin >> id; if (HistList->getType(id) == HEPHIST1D) { fillHist((HepHist1D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHIST2D) { fillHist((HepHist2D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHISTPROF) { fillHist((HepHistProf*)(HistList->getPtr(id))); } return; } // fill a HepHist1D void fillHist(HepHist1D* h) { float low, high; int range; // Gather data from histogram low = h->min(); high = h->max(); range = h->nBins(); float inc = (high - low)/(float)range; // iterate through a loop that generates data // the number of loop iterations may not be correct int bob = 0; // temporary counter for (float i = low - inc; i <= high; i += inc/2) { // cout << "\tDatapoint: " << i << " \t"; for (int j = 0; j < ( ::rand() % RANDLIMIT); j++) { h->accumulate(i); // cout << "."; bob++; } // cout << bob << endl; // " from " << r << endl; bob = 0; } return; } // fill a HepHist2D void fillHist(HepHist2D* h) { float lowX, highX, lowY, highY; int rangeX, rangeY; // Gather data from histogram lowX = h->minX(); highX = h->maxX(); rangeX = h->nBinsX(); lowY = h->minY(); highY = h->maxY(); rangeY = h->nBinsY(); float incX = (highX - lowX)/(float)rangeX; float incY = (highY - lowY)/(float)rangeY; // iterate through a loop that generates data // the number of loop iterations may not be correct int bob = 0; // temporary counter float offsetX = incX; // change range of loops float offsetY = incY; for (float i = lowX - offsetX; i <= highX + offsetX; i += incX) { for (float k = lowY - offsetY; k <= highY + offsetY; k += incY) { // cout << "\tDatapoint: " << i << ", " << k << " \t"; for (int j = 0; j < ::rand() % RANDLIMIT; j++) { h->accumulate(i, k); // cout << "."; bob++; } // cout << bob << endl; bob = 0; } } return; } // fill a HepHistProf void fillHist(HepHistProf* h) { float lowX, highX, lowY, highY; int rangeX; // Gather data from histogram lowX = h->minX(); highX = h->maxX(); rangeX = h->nBinsX(); lowY = h->minY(); highY = h->maxY(); float incX = (highX - lowX)/(float)rangeX; float incY = (highY - lowY)/(float)100.0; // iterate through a loop that generates data // the number of loop iterations may not be correct int bob = 0; // temporary counter float offsetX = incX; // change range of loops float offsetY = incY; for (float i = lowX - offsetX; i <= highX + offsetX; i += incX) { for (float k = lowY - offsetY; k <= highY + offsetY; k += incY) { // cout << "\tDatapoint: " << i << ", " << k << " \t"; for (int j = 0; j < ::rand() % RANDLIMIT; j++) { h->accumulate(i, k); // cout << "."; bob++; } // cout << bob << endl; bob = 0; } } return; } // read out the values void readHist(HepHist1D* h) { float low = h->min(); float high = h->max(); long range = h->nBins(); cout << "Title: " << h->title() << endl; cout << "\tValues: low = " << low << ", high = " << high; cout << ", range = " << range << ". " << endl; // float inc = (high - low)/(float)range; for (int i = 0; i <= range + 1; i++) { cout << "\t"; if (i == 0) cout << "Under "; if (i == range + 1) cout << "Over "; cout << "Bin " << i << ": \t"; cout << h->bin(i); cout << endl; } } void readHist(HepHist2D* h) { float lowX = h->minX(); float highX = h->maxX(); long rangeX = h->nBinsX(); float lowY = h->minY(); float highY = h->maxY(); long rangeY = h->nBinsY(); cout << "\tX values: low = " << lowX << ", high = " << highX; cout << ", range = " << rangeX << ". " << endl; cout << "\tY values: low = " << lowY << ", high = " << highY; cout << ", range = " << rangeY << ". " << endl; // float incX = (highX - lowX)/(float)rangeX; // float incY = (highY - lowY)/(float)rangeY; for (int i = 0; i <= rangeX + 1; i++) { for (int j = 0; j <= rangeY + 1; j++) { cout << "\t"; cout << "Bin " << i << ", " << j << ": \t"; cout << h->bin(i, j); cout << endl; } } } void readHist(HepHistProf* h) { float lowX = h->minX(); float highX = h->maxX(); long rangeX = h->nBinsX(); float lowY = h->minY(); float highY = h->maxY(); cout << "\tX values: low = " << lowX << ", high = " << highX; cout << ", range = " << rangeX << ". " << endl; cout << "\tY values: low = " << lowY << ", high = " << highY; cout << ", range = " << "Profile" << ". " << endl; // float incX = (highX - lowX)/(float)rangeX; cout << "Not Finished Yet." << endl; return; } void readHistCall() { cout << "Enter the number of the histogram you would like to read out: "; int id; cin >> id; if (HistList->getType(id) == HEPHIST1D) { readHist((HepHist1D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHIST2D) { readHist((HepHist2D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHISTPROF) { readHist((HepHistProf*)(HistList->getPtr(id))); } return; } void clone() { cout << "Enter the number of the histogram you would like to clone: "; int id; cin >> id; char name[BUFFERSIZE]; cout << "Enter the name of the new histogram: "; cin >> name; HepHist* h = dynamic_cast ( & (HistList->getPtr(id))->makeClone(name) ); // add to list HistList->add(h, HistList->getType(id)); cout << "Histogram '" << name << "' was created. " << endl; return; } void newEmpty() { cout << "Enter the number of the original histogram: "; int id; cin >> id; char name[BUFFERSIZE]; cout << "Enter the name of the new histogram: "; cin >> name; HepHist* h = dynamic_cast (& (HistList->getPtr(id))->makeEmpty(name)); // add to list HistList->add(h, HistList->getType(id)); cout << "Histogram '" << name << "' was created. " << endl; return; } void compare() { cout << "Enter the numbers of the histograms you would like to compare: "; int id1, id2; cin >> id1; cin >> id2; if (HistList->getType(id1) == HEPHIST1D) { compareHist((HepHist1D*)(HistList->getPtr(id1)), (HepHist1D*)(HistList->getPtr(id2))); } if (HistList->getType(id1) == HEPHIST2D) { compareHist((HepHist2D*)(HistList->getPtr(id1)), (HepHist2D*)(HistList->getPtr(id2))); } if (HistList->getType(id1) == HEPHISTPROF) { compareHist((HepHistProf*)(HistList->getPtr(id1)), (HepHistProf*)(HistList->getPtr(id2))); } return; } bool compareHist(HepHist1D* h1, HepHist1D* h2) { if (h1->nBins() != h2->nBins()) { cout << "Histograms have different number of bins!" << endl; return false; } bool anyFalse = false; for (int i = 0; i <= h1->nBins() + 1; i++) { //cout << "Bin " << i << ": "; if (h1->bin(i) == h2->bin(i)) { //cout << "Equal" << endl; } else { //cout << "***Not Equal***" << endl; anyFalse = true; } } if (anyFalse) { cout << "The two histograms are *NOT* equal. " << endl; return false; } else { cout << "The two histograms are equal. " << endl; return true; } } bool compareHist(HepHist2D* h1, HepHist2D* h2) { if ((h1->nBinsX() != h2->nBinsX()) || (h1->nBinsY() != h2->nBinsY())) { cout << "Histograms have different number of bins!" << endl; return false; } bool anyFalse = false; for (int i = 0; i <= h1->nBinsX() + 1; i++) { for (int j = 0; j <= h1->nBinsY() + 1; j++) { //cout << "Bin " << i << ", " << j << ": "; if (h1->bin(i, j) == h2->bin(i, j)) { //cout << "Equal" << endl; } else { //cout << "***Not Equal***" << endl; anyFalse = true; } } } if (anyFalse) { cout << "The two histograms are *NOT* equal. " << endl; return false; } else { cout << "The two histograms are equal. " << endl; return true; } } bool compareHist(HepHistProf* h1, HepHistProf* h2) { cerr << "Not implemented yet." << endl; return false; } void writeCall() { cout << "Writing datafile. "; M->write(); cout << "Done. " << endl; return; } void resetCall() { cout << "Enter the number of the histogram you would like to reset: "; int id; cin >> id; (HistList->getPtr(id))->reset(); return; } // Output the sums for the histogram void sumHist(HepHist1D* h) { cout << "Title: " << h->title() << endl; cout << "Number of entries: \t" << h->entries() << endl; cout << "Sum of weight: \t\t" << h->weight() << endl; cout << "Weighted Sum: \t\t" << h->sum() << endl; cout << "Weighted Sum of Square: " << h->sum2() << endl; cout << "Mean: \t\t\t" << h->mean() << endl; cout << "Sample Variance: \t" << h->variance() << endl; } void sumHist(HepHist2D* h) { cout << "Title: " << h->title() << endl; cout << "Number of entries: \t" << h->entries() << endl; cout << "Sum of weight: \t\t" << h->weight() << endl; cout << "Weighted Sum of X: \t" << h->sumX() << endl; cout << "Weighted Sum of X^2: \t" << h->sumX2() << endl; cout << "Weighted Sum of Y: \t" << h->sumY() << endl; cout << "Weighted Sum of Y^2: \t" << h->sumY2() << endl; cout << "Weighted Sum of X*Y: \t" << h->sumXY() << endl; float w = h->weight(); if ( w != 0 ) { cout << "Mean of X:\t\t" << h->sumX()/w << endl; cout << "Mean of Y:\t\t" << h->sumY()/w << endl; cout << "Sample Variance of X: \t" << (h->sumX2()/w-h->sumX()/w*h->sumX()/w) << endl; cout << "Sample Variance of Y: \t" << (h->sumY2()/w-h->sumY()/w*h->sumY()/w) << endl; cout << "Sample CoVariance: \t" << (h->sumXY()/w-h->sumX()/w*h->sumY()/w) << endl; } } void sumHist(HepHistProf* h) { cout << "Title: " << h->title() << endl; cout << "Number of entries: \t" << h->entries() << endl; cout << "Sum of weight: \t\t" << h->weight() << endl; cout << "Weighted Sum of Y: \t" << h->sumY() << endl; cout << "Weighted Sum of Y^2: \t" << h->sumY2() << endl; // cout << "Mean: \t" << h->meanY() << endl; // cout << "Sample Variance: \t" << h->varianceY() << endl; } void printSums() { cout << "Enter the number of the histogram you would like to read out: "; int id; cin >> id; if (HistList->getType(id) == HEPHIST1D) { sumHist((HepHist1D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHIST2D) { sumHist((HepHist2D*)(HistList->getPtr(id))); } if (HistList->getType(id) == HEPHISTPROF) { sumHist((HepHistProf*)(HistList->getPtr(id))); } return; }