00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "AIDAHistogram2D.h"
00011 #if defined __i386__ || defined __sun
00012 # include <strstream>
00013 #else
00014 # include <sstream>
00015 #endif
00016 #include <assert.h>
00017 #include "HepUtilities/SimpleTokenizer.h"
00018 #include "Interfaces/IAnnotationFactory.h"
00019 #include "Interfaces/IAxis.h"
00020 #include "Interfaces/IAnnotation.h"
00021 #include "Interfaces/IHistogramFactory.h"
00022 #include "CHBook/CHBookHisto2.h"
00023 #include "AIDAHistogram1D.h"
00024 #include "AIDAAxis.h"
00025 #include "Builder.h"
00026 #include "HistoParameters/HistoParameters.h"
00027
00028
00029
00030
00031 using Anaphe::IAxis;
00032 using Anaphe::AIDA_HBook::AIDAHistogram2D;
00033 using Anaphe::AIDA_HBook::AIDAAxis;
00034 using Anaphe::HistoParameters2D;
00035 using Anaphe::CHBookHisto2;
00036 using Anaphe::AIDA_HBook::Builder;
00037
00038
00039
00040
00042
00043
00044
00046
00047 AIDAHistogram2D::AIDAHistogram2D(const HistoParameters2D & hp,
00048 const Anaphe::IAnnotation* a,
00049 const Anaphe::IHistogramFactory* f)
00050 : xaxis (0),
00051 yaxis (0),
00052 ann (0),
00053 factory (const_cast<Anaphe::IHistogramFactory*>(f)),
00054 rep (0),
00055 ownsRep (true)
00056 {
00057 Anaphe::IAnnotationFactory* af = createIAnnotationFactory();
00058 assert (af);
00059 if (a) ann = af->create(a);
00060 else ann = af->create();
00061 delete af;
00062 int id = 1;
00063 AIDA_STD::string label = ann->find("ID");
00064 if (label != "") id = getIntFromString(label);
00065 Anaphe::AIDA_HBook::Builder builder;
00066 builder.noWarnings(true);
00067 rep = builder.buildFrom(hp, id);
00068 assert(rep);
00069 if (label == "") ann->add("ID", getStringFromInt(rep->id()));
00070 xaxis = new AIDAAxis(rep, 0, hp.nbX(), hp.lowX(), hp.highX());
00071 yaxis = new AIDAAxis(rep, 1, hp.nbY(), hp.lowY(), hp.highY());
00072 assert(xaxis && yaxis);
00073 }
00074
00075
00076
00077
00078 AIDAHistogram2D::AIDAHistogram2D(const char* name,
00079 const int& nBinsX,
00080 const double& lowX,
00081 const double& highX,
00082 const int& nBinsY,
00083 const double& lowY,
00084 const double& highY,
00085 const Anaphe::IAnnotation* a,
00086 const Anaphe::IHistogramFactory* f)
00087 : xaxis (0),
00088 yaxis (0),
00089 ann (0),
00090 factory (const_cast<Anaphe::IHistogramFactory*>(f)),
00091 rep (0),
00092 ownsRep (true)
00093 {
00094 Anaphe::IAnnotationFactory* af = createIAnnotationFactory();
00095 assert (af);
00096 if (a) ann = af->create(a);
00097 else ann = af->create();
00098 delete af;
00099 int id = 1;
00100 AIDA_STD::string label = ann->find("ID");
00101 if (label != "") id = getIntFromString(label);
00102 rep = new CHBookHisto2(id, name, nBinsX, lowX, highX,
00103 nBinsY, lowY, highY);
00104 assert(rep);
00105 if (label == "") ann->add("ID", getStringFromInt(rep->id()));
00106 xaxis = new AIDAAxis(rep, 0, nBinsX, lowX, highX);
00107 yaxis = new AIDAAxis(rep, 1, nBinsY, lowY, highY);
00108 assert(xaxis && yaxis);
00109 }
00110
00111
00112
00113
00114 AIDAHistogram2D::AIDAHistogram2D(const CHBookHisto2* h,
00115 const Anaphe::IHistogramFactory* f)
00116 : xaxis (0),
00117 yaxis (0),
00118 ann (0),
00119 factory (const_cast<Anaphe::IHistogramFactory*>(f)),
00120 rep (const_cast<CHBookHisto2*>(h)),
00121 ownsRep (true)
00122 {
00123 assert(rep);
00124 Anaphe::IAnnotationFactory* af = createIAnnotationFactory();
00125 assert(af);
00126 ann = af->create();
00127 delete af;
00128 int id = rep->id();
00129 ann->add("ID", getStringFromInt(id));
00130 int nbx = rep->binsX();
00131 int nby = rep->binsY();
00132 double lox = rep->lowerEdgeX();
00133 double hix = rep->upperEdgeX();
00134 double loy = rep->lowerEdgeY();
00135 double hiy = rep->upperEdgeY();
00136 xaxis = new AIDAAxis(rep, 0, nbx, lox, hix);
00137 yaxis = new AIDAAxis(rep, 1, nby, loy, hiy);
00138 assert(xaxis && yaxis);
00139 }
00140
00141
00142
00143
00144 AIDAHistogram2D::~AIDAHistogram2D(void)
00145 {
00146 delete xaxis;
00147 delete yaxis;
00148 delete ann;
00149 if (ownsRep) delete rep;
00150
00151
00152
00153
00154 }
00155
00156
00157
00158
00160
00161
00162
00164
00168
00169 {
00170 if (!rep) { crisisMessage("title"); return ""; }
00171 else return AIDA_STD::string(rep->getTitle());
00172 }
00173
00174
00175
00176
00177 void AIDAHistogram2D::setTitle(const AIDA_STD::string& value)
00178 {
00179 if (!rep) { crisisMessage("setTitle"); return; }
00180 else rep->setTitle(value.c_str());
00181 }
00182
00183
00184
00185
00187 Anaphe::IAnnotation* AIDAHistogram2D::annotation(void)
00188 {
00189 return ann;
00190 }
00191
00192
00193
00194
00196 int AIDAHistogram2D::dimensions(void) const
00197 {
00198 return 2;
00199 }
00200
00201
00202
00203
00205 void AIDAHistogram2D::reset(void)
00206 {
00207 if (!rep) crisisMessage("reset");
00208 else rep->reset();
00209 }
00210
00211
00212
00213
00215 int AIDAHistogram2D::entries(void) const
00216 {
00217 if (!rep) { crisisMessage("entries"); return -1; }
00218 else return (allEntries() - extraEntries());
00219 }
00220
00221
00222
00223
00226 int AIDAHistogram2D::allEntries(void) const
00227 {
00228 if (!rep) { crisisMessage("allEntries"); return -1; }
00229 else return rep->entries();
00230 }
00231
00232
00233
00234
00236 int AIDAHistogram2D::extraEntries(void) const
00237 {
00238 if (!rep) { crisisMessage("extraEntries"); return -1; }
00239 else return static_cast<int>(rep->outOfRangeContent());
00240 }
00241
00242
00243
00244
00247 double AIDAHistogram2D::equivalentBinEntries() const
00248 {
00249
00250 notYetMessage("equivalentBinEntries");
00251 return -1.0;
00252 }
00253
00254
00255
00256
00258 double AIDAHistogram2D::sumBinHeights(void) const
00259 {
00260 if (!rep) { crisisMessage("sumBinHeights"); return -1; }
00261 else return rep->sum();
00262 }
00263
00264
00265
00266
00268 double AIDAHistogram2D::sumAllBinHeights(void) const
00269 {
00270 if (!rep) { crisisMessage("sumAllBinHeights"); return -1; }
00271 return (sumBinHeights() + sumExtraBinHeights());
00272 }
00273
00274
00275
00276
00278 double AIDAHistogram2D::sumExtraBinHeights(void) const
00279 {
00280 if (!rep) { crisisMessage("sumExtraBinHeights"); return -1; }
00281 else return rep->outOfRangeContent();
00282 }
00283
00284
00285
00286
00288 void AIDAHistogram2D::fill(double x, double y, double weight)
00289 {
00290 if (!rep) crisisMessage("fill");
00291 else {
00292
00293 float xx = static_cast<float>(x);
00294 float yy = static_cast<float>(y);
00295 float ww = static_cast<float>(weight);
00296 rep->fill(xx, yy, ww);
00297 }
00298 }
00299
00300
00301
00302
00304 int AIDAHistogram2D::binEntries(int i, int j) const
00305 {
00306 if (!rep) { crisisMessage("binEntries"); return -1; }
00307 return static_cast<int>(binHeight(i,j));
00308 }
00309
00310
00311
00312
00315 int AIDAHistogram2D::binEntriesX(int i) const
00316 {
00317 IHistogram1D* p = projectionX();
00318 assert(p);
00319 int r = p->binEntries(i);
00320 delete p;
00321 return r;
00322 }
00323
00324
00325
00326
00329 int AIDAHistogram2D::binEntriesY(int i) const
00330 {
00331 IHistogram1D* p = projectionY();
00332 assert(p);
00333 int r = p->binEntries(i);
00334 delete p;
00335 return r;
00336 }
00337
00338
00339
00340
00342 double AIDAHistogram2D::binHeight(int indexX, int indexY) const
00343 {
00344 if (!rep) { crisisMessage("binHeight"); return -1; }
00345 else {
00346 int i = indexX, j = indexY;
00347 if (i == UNDERFLOW_BIN) i = -1;
00348 else if (i == OVERFLOW_BIN) i = rep->binsX();
00349 if (j == UNDERFLOW_BIN) j = -1;
00350 else if (j == OVERFLOW_BIN) j = rep->binsY();
00351 return rep->binContent(i,j);
00352 }
00353 }
00354
00355
00356
00357
00360 double AIDAHistogram2D::binHeightX(int i) const
00361 {
00362 IHistogram1D* p = projectionX();
00363 assert(p);
00364 double r = p->binHeight(i);
00365 delete p;
00366 return r;
00367 }
00368
00369
00370
00371
00374 double AIDAHistogram2D::binHeightY(int i) const
00375 {
00376 IHistogram1D* p = projectionY();
00377 assert(p);
00378 double r = p->binHeight(i);
00379 delete p;
00380 return r;
00381 }
00382
00383
00384
00385
00387 double AIDAHistogram2D::binError(int indexX, int indexY) const
00388 {
00389 if (!rep) { crisisMessage("binError"); return -1; }
00390 else {
00391 int i = indexX, j = indexY;
00392 if (i == UNDERFLOW_BIN) i = -1;
00393 else if (i == OVERFLOW_BIN) i = rep->binsX();
00394 if (j == UNDERFLOW_BIN) j = -1;
00395 else if (j == OVERFLOW_BIN) j = rep->binsY();
00396 return rep->binError(i,j);
00397 }
00398 }
00399
00400
00401
00402
00405 double AIDAHistogram2D::meanX(void) const
00406 {
00407 IHistogram1D* p = projectionX();
00408 assert(p);
00409 double r = p->mean();
00410 delete p;
00411 return r;
00412 }
00413
00414
00415
00416
00419 double AIDAHistogram2D::meanY(void) const
00420 {
00421 IHistogram1D* p = projectionY();
00422 assert(p);
00423 double r = p->mean();
00424 delete p;
00425 return r;
00426 }
00427
00428
00429
00430
00433 double AIDAHistogram2D::rmsX(void) const
00434 {
00435 IHistogram1D* p = projectionX();
00436 assert(p);
00437 double r = p->rms();
00438 delete p;
00439 return r;
00440 }
00441
00442
00443
00444
00447 double AIDAHistogram2D::rmsY(void) const
00448 {
00449 IHistogram1D* p = projectionY();
00450 assert(p);
00451 double r = p->rms();
00452 delete p;
00453 return r;
00454 }
00455
00456
00457
00458
00460 double AIDAHistogram2D::minBinHeight(void) const
00461 {
00462 if (!rep) { crisisMessage("minBinHeight"); return -1; }
00463 else return rep->min();
00464 }
00465
00466
00467
00468
00470 int AIDAHistogram2D::minBinX(void) const
00471 {
00472 if (!rep) { crisisMessage("minBinX"); return -1; }
00473 else {
00474 int i = -1, j = -1;
00475 AIDA_STD::pair<int,int> p = AIDA_STD::make_pair(i,j);
00476 p = rep->minBin();
00477 return p.first;
00478 }
00479 }
00480
00481
00482
00483
00485 int AIDAHistogram2D::minBinY(void) const
00486 {
00487 if (!rep) { crisisMessage("minBinY"); return -1; }
00488 else {
00489 int i = -1, j = -1;
00490 AIDA_STD::pair<int,int> p = AIDA_STD::make_pair(i,j);
00491 p = rep->minBin();
00492 return p.second;
00493 }
00494 }
00495
00496
00497
00498
00500 double AIDAHistogram2D::maxBinHeight(void) const
00501 {
00502 if (!rep) { crisisMessage("maxBinHeight"); return -1; }
00503 else return rep->max();
00504 }
00505
00506
00507
00508
00510 int AIDAHistogram2D::maxBinX(void) const
00511 {
00512 if (!rep) { crisisMessage("maxBinX"); return -1; }
00513 else {
00514 int i = -1, j = -1;
00515 AIDA_STD::pair<int,int> p = AIDA_STD::make_pair(i,j);
00516 p = rep->maxBin();
00517 return p.first;
00518 }
00519 }
00520
00521
00522
00523
00525 int AIDAHistogram2D::maxBinY(void) const
00526 {
00527 if (!rep) { crisisMessage("maxBinY"); return -1; }
00528 else {
00529 int i = -1, j = -1;
00530 AIDA_STD::pair<int,int> p = AIDA_STD::make_pair(i,j);
00531 p = rep->maxBin();
00532 return p.second;
00533 }
00534 }
00535
00536
00537
00538
00540 IAxis* AIDAHistogram2D::xAxis(void) const
00541 {
00542 return xaxis;
00543 }
00544
00545
00546
00547
00549 IAxis* AIDAHistogram2D::yAxis(void) const
00550 {
00551 return yaxis;
00552 }
00553
00554
00555
00556
00558 int AIDAHistogram2D::coordToIndexX(double coordX) const
00559 {
00560 return xAxis()->coordToIndex( coordX );
00561 }
00562
00563
00564
00565
00567 int AIDAHistogram2D::coordToIndexY( double coordY ) const
00568 {
00569 return yAxis()->coordToIndex( coordY );
00570 }
00571
00572
00573
00574
00577 Anaphe::IHistogram1D* AIDAHistogram2D::projectionX(void) const
00578 {
00579 return sliceX(UNDERFLOW_BIN, OVERFLOW_BIN);
00580 }
00581
00582
00583
00584
00587 Anaphe::IHistogram1D* AIDAHistogram2D::projectionY(void) const
00588 {
00589 return sliceY(UNDERFLOW_BIN, OVERFLOW_BIN);
00590 }
00591
00592
00593
00594
00597 Anaphe::IHistogram1D* AIDAHistogram2D::sliceX(int i) const
00598 {
00599 return sliceX(i,i);
00600 }
00601
00602
00603
00604
00607 Anaphe::IHistogram1D* AIDAHistogram2D::sliceY(int i) const
00608 {
00609 return sliceY(i,i);
00610 }
00611
00612
00613
00614
00616 Anaphe::IHistogram1D* AIDAHistogram2D::sliceX(int lowBin, int highBin) const
00617 {
00618 return slice(lowBin,highBin,0);
00619 }
00620
00621
00622
00623
00625 Anaphe::IHistogram1D* AIDAHistogram2D::sliceY(int lowBin, int highBin) const
00626 {
00627 return slice(lowBin,highBin,1);
00628 }
00629
00630
00631
00632
00634 AIDA_STD::ostream& AIDAHistogram2D::print(AIDA_STD::ostream& s) const
00635 {
00636 if (!rep) { crisisMessage("print"); return s; }
00637 else rep->print();
00638 return s;
00639 }
00640
00641
00642
00643
00645 AIDA_STD::ostream& AIDAHistogram2D::write(AIDA_STD::ostream& s) const
00646 {
00647
00648 notYetMessage("write-os");
00649 return s;
00650 }
00651
00652
00653
00654
00656 int AIDAHistogram2D::write( const char* file_name ) const
00657 {
00658
00659 notYetMessage("write-file");
00660 return 0;
00661 }
00662
00663
00664
00665
00666 const CHBookHisto2 * AIDAHistogram2D::representation(void) const
00667 {
00668 return rep;
00669 }
00670
00671
00672
00673
00675
00676
00677
00679
00681
00682 {
00683
00684 notYetMessage("calcIndex");
00685 return 0;
00686 }
00687
00688
00689
00690
00693 int AIDAHistogram2D::checkIndexX(int indexX) const
00694 {
00695 AIDAAxis* ax = dynamic_cast<AIDAAxis*>(xaxis);
00696 if (ax) return ax->checkIndex(indexX);
00697 else return -1;
00698 }
00699
00700
00701
00702
00705 int AIDAHistogram2D::checkIndexY(int indexY) const
00706 {
00707 AIDAAxis* ax = dynamic_cast<AIDAAxis*>(yaxis);
00708 if (ax) return ax->checkIndex(indexY);
00709 else return -1;
00710 }
00711
00712
00713
00714
00715 Anaphe::IHistogram1D* AIDAHistogram2D::slice(const int& lowBin, const int& highBin,
00716 const int& axis) const
00717 {
00718
00719
00720 if (axis > 1 || axis < 0) return 0;
00721 if (!goodIndices(lowBin,highBin,axis)) return 0;
00722 AIDA_STD::string axisname = (axis == 0 ? "x" : "y");
00723 AIDA_STD::string orthname = (axis == 0 ? "y" : "x");
00724 IAxis* thisAxis = (axis == 0 ? xAxis() : yAxis());
00725 IAxis* orthAxis = (axis == 0 ? yAxis() : xAxis());
00726 assert(thisAxis && orthAxis);
00727 float lowerEdge = thisAxis->lowerEdge();
00728 float upperEdge = thisAxis->upperEdge();
00729 int nbinsAxis = thisAxis->bins();
00730 int nbinsOrth = orthAxis->bins();
00731
00732 AIDA_STD::string loname = binname(lowBin);
00733 AIDA_STD::string hiname = binname(highBin);
00734
00735 int lo = lowBin;
00736 int hi = highBin;
00737 if (lo == OVERFLOW_BIN) lo = nbinsAxis;
00738 else if (lo == UNDERFLOW_BIN) lo = -1;
00739 if (hi == OVERFLOW_BIN) hi = nbinsAxis;
00740 else if (hi == UNDERFLOW_BIN) hi = -1;
00741
00742 AIDA_STD::string hname = title() + " (" + axisname;
00743 if (lo == -1 && hi == nbinsAxis) hname = hname + " projection)";
00744 else if (lo == hi) hname = hname + " slice at " + orthname +
00745 " bin = " + binname(lo) + ")";
00746 else hname = hname + " slice between " + orthname + " bins " +
00747 loname + " and " + hiname + ")";
00748
00749 AIDAHistogram1D* proj =
00750 new AIDAHistogram1D(hname.c_str(),nbinsAxis,lowerEdge,upperEdge);
00751 assert(proj);
00752
00753 int ibin = 0;
00754 int jbin = 0;
00755 double ival = 0.0;
00756 double binContent = 0.0;
00757 double sum = 0.0;
00758 for (int i = -1; i <= nbinsAxis; ++i) {
00759 if (i == -1) ibin = UNDERFLOW_BIN;
00760 else if (i == nbinsAxis) ibin = OVERFLOW_BIN;
00761 else ibin = i;
00762 ival = thisAxis->binCentre(ibin);
00763 sum = 0.0;
00764 for (int j = lo; j <= hi; ++j) {
00765 if (j == -1) jbin = UNDERFLOW_BIN;
00766 else if (j == nbinsOrth) jbin = OVERFLOW_BIN;
00767 else jbin = j;
00768 if (axis==0) binContent = binHeight(ibin,jbin);
00769 else binContent = binHeight(jbin,ibin);
00770 sum += binContent;
00771 }
00772 if (sum > 0.0) {
00773 proj->fill(ival,sum);
00774 }
00775 }
00776 return proj;
00777 }
00778
00779
00780
00781
00782 bool AIDAHistogram2D::goodIndices(const int& lowBin, const int& highBin,
00783 const int& axis) const
00784 {
00785 IAxis* theAxis = (axis == 0 ? xAxis() : yAxis());
00786 assert(theAxis);
00787 int nb = theAxis->bins();
00788 int lo = lowBin;
00789 int hi = highBin;
00790
00791 if (lo == OVERFLOW_BIN) lo = nb;
00792 else if (lo == UNDERFLOW_BIN) lo = -1;
00793 if (hi == OVERFLOW_BIN) hi = nb;
00794 else if (hi == UNDERFLOW_BIN) hi = -1;
00795
00796 if (lo < -1 || hi > nb || lo > hi) return false;
00797 else return true;
00798 }
00799
00800
00801
00802
00803 AIDA_STD::string AIDAHistogram2D::binname(const int& i) const
00804 {
00805 if (i == UNDERFLOW_BIN) return AIDA_STD::string("UFL");
00806 else if (i == OVERFLOW_BIN) return AIDA_STD::string("OFL");
00807 else return getStringFromInt(i);
00808 }
00809
00810
00811
00812
00813 int AIDAHistogram2D::getIntFromString(const AIDA_STD::string& str) const
00814 {
00815 int ans = 0;
00816 if (str.length() < 1) return false;
00817 AIDA_STD::string s = str;
00818 for (unsigned int i = 0; i < s.length(); ++i) {
00819 if (s[i] == '0') s.erase(0,1);
00820 else break;
00821 }
00822 if (s.length() < 1) return false;
00823 for (unsigned int i = 0; i < s.length(); ++i) {
00824 if (!isdigit(s[i])) return false;
00825 }
00826 ans = atoi(s.c_str());
00827 return (ans > 0) ? ans : 0;
00828 }
00829
00830
00831
00832
00833 AIDA_STD::string AIDAHistogram2D::getStringFromInt(const int& i) const
00834 {
00835 AIDA_STD::ostrstream ostr;
00836 ostr << i << AIDA_STD::ends;
00837 return ostr.str();
00838 }
00839
00840
00841
00842
00843 void AIDAHistogram2D::notYetMessage(const AIDA_STD::string& featureName) const
00844 {
00845 AIDA_STD::cerr << "AIDAHistogram2D::" << featureName
00846 << "is not yet implemented." << AIDA_STD::endl;
00847 AIDA_STD::cerr << " If you really need this feature, please contact "
00848 << " Andreas.Pfeiffer@cern.ch " << AIDA_STD::endl;
00849 }
00850
00851
00852
00853
00854 void AIDAHistogram2D::crisisMessage(const AIDA_STD::string& featureName) const
00855 {
00856 AIDA_STD::cerr << "AIDAHistogram2D::" << featureName
00857 << "(...): ERROR - histo = 0"
00858 << AIDA_STD::endl;
00859 }