00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "AIDADynHist1D.h"
00011 #include <assert.h>
00012 #include "Interfaces/IHistogramFactory.h"
00013 #include "Interfaces/IAnnotation.h"
00014 #include "Interfaces/IAnnotationFactory.h"
00015 #include "HepUtilities/SimpleTokenizer.h"
00016 #include "CHBook/CHBookHisto.h"
00017 #include "AIDAAxis.h"
00018
00019
00020
00021 using Anaphe::IAnnotation;
00022 using Anaphe::IAxis;
00023 using Anaphe::IHistogramFactory;
00024 using Anaphe::AIDA_HBook::AIDAAxis;
00025 using Anaphe::AIDA_HBook::AIDADynHist1D;
00026 using Anaphe::CHBookHisto;
00027
00028
00029
00031
00032
00033
00035
00036 const double AIDADynHist1D::BIG_DOUBLE = 1e30;
00037 const int AIDADynHist1D::DEFAULT_MAX_CACHE_SIZE = 100000;
00038 const int AIDADynHist1D::CACHE_SAFETY_LIMIT = 10000000;
00039
00040
00041
00042
00044
00045
00046
00048
00049 AIDADynHist1D::AIDADynHist1D(const char* nm,
00050 const int& nb,
00051 IAnnotation* a,
00052 IHistogramFactory* f)
00053
00054 : histo (0),
00055 axis (0),
00056 ann (0),
00057 maxCacheSize (DEFAULT_MAX_CACHE_SIZE),
00058 nbins (nb),
00059 name (nm),
00060 factory (f)
00061 {
00062 reset();
00063 IAnnotationFactory* af = createIAnnotationFactory();
00064 assert(af);
00065 if (a) ann = af->create(a);
00066 else ann = af->create();
00067 assert(ann);
00068 delete af;
00069 }
00070
00071
00072
00073
00074 AIDADynHist1D::~AIDADynHist1D(void)
00075 {
00076
00077
00078
00079
00080
00081
00082 delete axis;
00083 delete ann;
00084 delete histo;
00085 }
00086
00087
00089
00090
00091
00093
00095
00096 {
00097 return name;
00098 }
00099
00100
00101
00103 void AIDADynHist1D::setTitle(const AIDA_STD::string& newTitle)
00104 {
00105 name = newTitle;
00106 histo->setTitle(const_cast<char*>(name.c_str()));
00107 }
00108
00109
00110
00111
00113 IAnnotation* AIDADynHist1D::annotation(void)
00114 {
00115 return ann;
00116 }
00117
00118
00119
00120
00122 int AIDADynHist1D::dimensions(void) const
00123 {
00124 return 1;
00125 }
00126
00127
00128
00129
00131 void AIDADynHist1D::reset(void)
00132 {
00133 delete axis; axis = 0;
00134 delete histo; histo = 0;
00135 weightedCache.clear();
00136 unweightedCache.clear();
00137 synchronised = false;
00138 frozen = false;
00139 needsRebook = true;
00140 loVal = BIG_DOUBLE;
00141 hiVal = -BIG_DOUBLE;
00142 }
00143
00144
00145
00146
00148 int AIDADynHist1D::entries(void) const
00149 {
00150 if (frozen) return (allEntries() - extraEntries());
00151 else return (weightedCache.size() + unweightedCache.size());
00152 }
00153
00154
00155
00156
00159 int AIDADynHist1D::allEntries(void) const
00160 {
00161 if (frozen) return histo->entries();
00162 else return (unweightedCache.size() + weightedCache.size());
00163 }
00164
00165
00166
00167
00169 int AIDADynHist1D::extraEntries(void) const
00170 {
00171 if (frozen) return static_cast<int>((histo->outOfRangeContent()));
00172 else return 0;
00173 }
00174
00175
00176
00177
00179 double AIDADynHist1D::equivalentBinEntries(void) const
00180 {
00181 sync();
00182 return histo->equivalentEntries();
00183 }
00184
00185
00186
00187
00189 double AIDADynHist1D::sumBinHeights(void) const
00190 {
00191 sync();
00192 return histo->sum();
00193 }
00194
00195
00196
00197
00199 double AIDADynHist1D::sumAllBinHeights(void) const
00200 {
00201 return (sumBinHeights() + sumExtraBinHeights());
00202 }
00203
00204
00205
00206
00208 double AIDADynHist1D::sumExtraBinHeights(void) const
00209 {
00210 sync();
00211 return histo->outOfRangeContent();
00212 }
00213
00214
00215
00216
00218 int AIDADynHist1D::binEntries(int index) const
00219 {
00220 return static_cast<int>(binHeight(index));
00221 }
00222
00223
00224
00225
00227 double AIDADynHist1D::binHeight(int index) const
00228 {
00229 sync();
00230 int i = index;
00231 if (i == UNDERFLOW_BIN) i = -1;
00232 else if (i == OVERFLOW_BIN) i = histo->bins();
00233 return histo->binContent(i);
00234 }
00235
00236
00237
00238
00240 double AIDADynHist1D::binError(int index) const
00241 {
00242 sync();
00243 int i = index;
00244 if (i == UNDERFLOW_BIN) i = -1;
00245 else if (i == OVERFLOW_BIN) i = histo->bins();
00246 return histo->binError(i);
00247 }
00248
00249
00250
00251
00254 double AIDADynHist1D::mean(void) const
00255 {
00256 sync();
00257 return histo->mean();
00258 }
00259
00260
00261
00262
00265 double AIDADynHist1D::rms(void) const
00266 {
00267 sync();
00268 return histo->sigma();
00269 }
00270
00271
00272
00273
00275 double AIDADynHist1D::minBinHeight(void) const
00276 {
00277 sync();
00278 return histo->min();
00279 }
00280
00281
00282
00283
00285 int AIDADynHist1D::minBin(void) const
00286 {
00287 sync();
00288 return histo->minBin();
00289 }
00290
00291
00292
00293
00295 double AIDADynHist1D::maxBinHeight(void) const
00296 {
00297 sync();
00298 return histo->max();
00299 }
00300
00301
00302
00303
00305 int AIDADynHist1D::maxBin(void) const
00306 {
00307 sync();
00308 return histo->maxBin();
00309 }
00310
00311
00312
00313
00315 IAxis* AIDADynHist1D::xAxis(void) const
00316 {
00317 sync();
00318 return axis;
00319 }
00320
00321
00322
00323
00325 int AIDADynHist1D::coordToIndex(double coord) const
00326 {
00327 sync();
00328 return xAxis()->coordToIndex(coord);
00329 }
00330
00331
00332
00333
00335 AIDA_STD::ostream& AIDADynHist1D::print(AIDA_STD::ostream& s) const
00336 {
00337 sync();
00338 histo->print();
00339 return s;
00340 }
00341
00342
00343
00344
00346 AIDA_STD::ostream& AIDADynHist1D::write(AIDA_STD::ostream& s) const
00347 {
00348
00349 notYetMessage("write");
00350 return s;
00351 }
00352
00353
00354
00355
00357 int AIDADynHist1D::write(const char* filename) const
00358 {
00359
00360 notYetMessage("write");
00361 return -1;
00362 }
00363
00364
00365
00366
00369 int AIDADynHist1D::checkIndex(int index) const
00370 {
00371 sync();
00372 return axis->checkIndex(index);
00373 }
00374
00375
00376
00377
00378 void AIDADynHist1D::fill(double x, double weight)
00379 {
00380 if (frozen) histo->fill(static_cast<float>(x),
00381 static_cast<float>(weight));
00382 else {
00383 if (weight == 1.0) unweightedCache.push_back(x);
00384 else weightedCache.push_back(AIDA_STD::pair<double,double>(x,weight));
00385 synchronised = false;
00386 if (x < loVal) { needsRebook = true; loVal = x; }
00387 if (x > hiVal) { needsRebook = true; hiVal = x; }
00388 if (static_cast<int>(unweightedCache.size()+weightedCache.size())
00389 == maxCacheSize) {
00390 freeze();
00391 frozenMessage();
00392 }
00393 }
00394 }
00395
00396
00397
00398
00399 bool AIDADynHist1D::sync(void) const
00400 {
00401 if (synchronised) return true;
00402 else {
00403 if (needsRebook) {
00404 AIDA_STD::pair<double,double> newLimits = chooseLimits();
00405 delete histo;
00406 histo = new CHBookHisto(myID(), name.c_str(), nbins,
00407 static_cast<float>(newLimits.first),
00408 static_cast<float>(newLimits.second));
00409 delete axis;
00410 axis = new AIDAAxis(histo,0,nbins,newLimits.first,newLimits.second);
00411 assert(histo && axis);
00412 uwcIt = unweightedCache.begin();
00413 wcIt = weightedCache.begin();
00414 needsRebook = false;
00415 }
00416 UwcIt endOfUwc = unweightedCache.end();
00417 WcIt endOfWc = weightedCache.end();
00418 for (UwcIt i = uwcIt; i != endOfUwc; ++i)
00419 histo->fill(static_cast<float>(*i),1.0);
00420 for (WcIt i = wcIt; i != endOfWc; ++i)
00421 histo->fill(static_cast<float>(i->first),static_cast<float>(i->second));
00422 synchronised = true;
00423 return true;
00424 }
00425 }
00426
00427
00428
00429
00430 const CHBookHisto* AIDADynHist1D::representation() const
00431 {
00432 sync();
00433 return histo;
00434 }
00435
00436
00437
00438
00439 int AIDADynHist1D::cacheSize(void) const
00440 {
00441 return maxCacheSize;
00442 }
00443
00444
00445
00446
00447 bool AIDADynHist1D::setCacheSize(int newSize)
00448 {
00449 if (
00450 frozen ||
00451 newSize <= static_cast<int>(weightedCache.size() +
00452 unweightedCache.size()) ||
00453 newSize > CACHE_SAFETY_LIMIT
00454 )
00455 return false;
00456 else {
00457 maxCacheSize = newSize;
00458 return true;
00459 }
00460 }
00461
00462
00463
00464
00465 void AIDADynHist1D::freeze(void) const
00466 {
00467 sync();
00468 weightedCache.clear();
00469 unweightedCache.clear();
00470 needsRebook = false;
00471 frozen = true;
00472 }
00473
00474
00475
00476
00477 AIDA_STD::pair<double,double> AIDADynHist1D::chooseLimits(void) const
00478 {
00479 double lowerLimit = loVal;
00480 double upperLimit = hiVal;
00481 if (loVal == BIG_DOUBLE || hiVal == -BIG_DOUBLE) {
00482 lowerLimit = -1.0;
00483 upperLimit = 1.0;
00484 }
00485 else if (loVal == hiVal) {
00486 if (loVal == 0.0) {
00487 lowerLimit = -1.0;
00488 upperLimit = 1.0;
00489 }
00490 else {
00491 if (loVal > 0.0) {
00492 lowerLimit = 0.0;
00493 upperLimit = 2.0*loVal;
00494 }
00495 else {
00496 lowerLimit = 2.0*loVal;
00497 upperLimit = 0.0;
00498 }
00499 }
00500 }
00501 assert(upperLimit > lowerLimit);
00502
00503 return AIDA_STD::pair<double,double>(lowerLimit,upperLimit);
00504 }
00505
00506
00507
00508
00509 void AIDADynHist1D::notYetMessage(const AIDA_STD::string& featureName) const
00510 {
00511 AIDA_STD::cerr << "AIDADynHist1D::" << featureName
00512 << "(...) not yet implemented, sorry ..."
00513 << AIDA_STD::endl;
00514 }
00515
00516
00517
00518
00519 void AIDADynHist1D::frozenMessage(void) const
00520 {
00521 AIDA_STD::cerr << "AIDADynHist1D::fill: WARNING - cache limit of "
00522 << maxCacheSize
00523 << "entries reached; converting to static histogram!"
00524 << AIDA_STD::endl;
00525 }
00526
00527
00528
00529
00530 int AIDADynHist1D::getIntFromString(const AIDA_STD::string& str) const
00531 {
00532 int ans = 0;
00533 if (str.length() < 1) return false;
00534 AIDA_STD::string s = str;
00535 for (unsigned int i = 0; i < s.length(); ++i) {
00536 if (s[i] == '0') s.erase(0,1);
00537 else break;
00538 }
00539 if (s.length() < 1) return false;
00540 for (unsigned int i = 0; i < s.length(); ++i) {
00541 if (!isdigit(s[i])) return false;
00542 }
00543 ans = atoi(s.c_str());
00544 return (ans > 0) ? ans : 0;
00545 }
00546
00547
00548
00549
00550 int AIDADynHist1D::myID(void) const
00551 {
00552 AIDA_STD::string idstr;
00553 if (ann) idstr = ann->find("ID");
00554 if (idstr == "") idstr = "0";
00555 return getIntFromString(idstr);
00556 }