00001 #include "DQMServices/Core/interface/QTest.h"
00002 #include "DQMServices/Core/interface/DQMStore.h"
00003 #include "DQMServices/Core/src/QStatisticalTests.h"
00004 #include "DQMServices/Core/src/DQMError.h"
00005 #include "TMath.h"
00006 #include <iostream>
00007 #include <sstream>
00008 #include <math.h>
00009
00010 using namespace std;
00011
00012 const float QCriterion::ERROR_PROB_THRESHOLD = 0.50;
00013 const float QCriterion::WARNING_PROB_THRESHOLD = 0.90;
00014
00015
00016 void
00017 QCriterion::init(void)
00018 {
00019 errorProb_ = ERROR_PROB_THRESHOLD;
00020 warningProb_ = WARNING_PROB_THRESHOLD;
00021 setAlgoName("NO_ALGORITHM");
00022 status_ = dqm::qstatus::DID_NOT_RUN;
00023 message_ = "NO_MESSAGE";
00024 verbose_ = 0;
00025 }
00026
00027 float QCriterion::runTest(const MonitorElement * )
00028 {
00029 raiseDQMError("QCriterion", "virtual runTest method called" );
00030 return 0.;
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040 float Comp2RefEqualH::runTest(const MonitorElement*me)
00041 {
00042 badChannels_.clear();
00043
00044 if (!me)
00045 return -1;
00046 if (!me->getRootObject() || !me->getRefRootObject())
00047 return -1;
00048 TH1* h=0;
00049 TH1* ref_=0;
00050
00051 if (verbose_>1)
00052 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00053 << me-> getFullname() << "\n";
00054
00055 int nbins=0;
00056 int nbinsref=0;
00057
00058 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00059 {
00060 nbins = me->getTH1F()->GetXaxis()->GetNbins();
00061 nbinsref = me->getRefTH1F()->GetXaxis()->GetNbins();
00062 h = me->getTH1F();
00063 ref_ = me->getRefTH1F();
00064 if (nbins != nbinsref) return -1;
00065 }
00066
00067 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00068 {
00069 nbins = me->getTH1S()->GetXaxis()->GetNbins();
00070 nbinsref = me->getRefTH1S()->GetXaxis()->GetNbins();
00071 h = me->getTH1S();
00072 ref_ = me->getRefTH1S();
00073 if (nbins != nbinsref) return -1;
00074 }
00075
00076 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00077 {
00078 nbins = me->getTH1D()->GetXaxis()->GetNbins();
00079 nbinsref = me->getRefTH1D()->GetXaxis()->GetNbins();
00080 h = me->getTH1D();
00081 ref_ = me->getRefTH1D();
00082 if (nbins != nbinsref) return -1;
00083 }
00084
00085 else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
00086 {
00087 nbins = me->getTH2F()->GetXaxis()->GetNbins() *
00088 me->getTH2F()->GetYaxis()->GetNbins();
00089 nbinsref = me->getRefTH2F()->GetXaxis()->GetNbins() *
00090 me->getRefTH2F()->GetYaxis()->GetNbins();
00091 h = me->getTH2F();
00092 ref_ = me->getRefTH2F();
00093 if (nbins != nbinsref) return -1;
00094 }
00095
00096
00097 else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
00098 {
00099 nbins = me->getTH2S()->GetXaxis()->GetNbins() *
00100 me->getTH2S()->GetYaxis()->GetNbins();
00101 nbinsref = me->getRefTH2S()->GetXaxis()->GetNbins() *
00102 me->getRefTH2S()->GetYaxis()->GetNbins();
00103 h = me->getTH2S();
00104 ref_ = me->getRefTH2S();
00105 if (nbins != nbinsref) return -1;
00106 }
00107
00108
00109 else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
00110 {
00111 nbins = me->getTH2D()->GetXaxis()->GetNbins() *
00112 me->getTH2D()->GetYaxis()->GetNbins();
00113 nbinsref = me->getRefTH2D()->GetXaxis()->GetNbins() *
00114 me->getRefTH2D()->GetYaxis()->GetNbins();
00115 h = me->getTH2D();
00116 ref_ = me->getRefTH2D();
00117 if (nbins != nbinsref) return -1;
00118 }
00119
00120
00121 else if (me->kind()==MonitorElement::DQM_KIND_TH3F)
00122 {
00123 nbins = me->getTH3F()->GetXaxis()->GetNbins() *
00124 me->getTH3F()->GetYaxis()->GetNbins() *
00125 me->getTH3F()->GetZaxis()->GetNbins();
00126 nbinsref = me->getRefTH3F()->GetXaxis()->GetNbins() *
00127 me->getRefTH3F()->GetYaxis()->GetNbins() *
00128 me->getRefTH3F()->GetZaxis()->GetNbins();
00129 h = me->getTH3F();
00130 ref_ = me->getRefTH3F();
00131 if (nbins != nbinsref) return -1;
00132 }
00133
00134 else
00135 {
00136 if (verbose_>0)
00137 std::cout << "QTest:Comp2RefEqualH"
00138 << " ME does not contain TH1F/TH1S/TH1D/TH2F/TH2S/TH2D/TH3F, exiting\n";
00139 return -1;
00140 }
00141
00142
00143 int first = 0;
00144 int last = nbins+1;
00145 bool failure = false;
00146 for (int bin=first;bin<=last;bin++)
00147 {
00148 double contents = h->GetBinContent(bin);
00149 if (contents != ref_->GetBinContent(bin))
00150 {
00151 failure = true;
00152 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
00153 badChannels_.push_back(chan);
00154 }
00155 }
00156 if (failure) return 0;
00157 return 1;
00158 }
00159
00160
00161
00162
00163 float Comp2RefChi2::runTest(const MonitorElement *me)
00164 {
00165 if (!me)
00166 return -1;
00167 if (!me->getRootObject() || !me->getRefRootObject())
00168 return -1;
00169 TH1* h=0;
00170 TH1* ref_=0;
00171
00172 if (verbose_>1)
00173 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00174 << me-> getFullname() << "\n";
00175
00176 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00177 {
00178 h = me->getTH1F();
00179 ref_ = me->getRefTH1F();
00180 }
00181
00182 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00183 {
00184 h = me->getTH1S();
00185 ref_ = me->getRefTH1S();
00186 }
00187
00188 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00189 {
00190 h = me->getTH1D();
00191 ref_ = me->getRefTH1D();
00192 }
00193
00194 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
00195 {
00196 h = me->getTProfile();
00197 ref_ = me->getRefTProfile();
00198 }
00199 else
00200 {
00201 if (verbose_>0)
00202 std::cout << "QTest::Comp2RefChi2"
00203 << " ME does not contain TH1F/TH1S/TH1D/TProfile, exiting\n";
00204 return -1;
00205 }
00206
00207
00208 int ncx1 = h->GetXaxis()->GetNbins();
00209 int ncx2 = ref_->GetXaxis()->GetNbins();
00210 if ( ncx1 != ncx2)
00211 {
00212 if (verbose_>0)
00213 std::cout << "QTest:Comp2RefChi2"
00214 << " different number of channels! ("
00215 << ncx1 << ", " << ncx2 << "), exiting\n";
00216 return -1;
00217 }
00218
00219
00220
00221 Ndof_ = 0; chi2_ = -1.; ncx1 = ncx2 = -1;
00222
00223 int i, i_start, i_end;
00224 double chi2 = 0.; int ndof = 0; int constraint = 0;
00225
00226 i_start = 1;
00227 i_end = ncx1;
00228
00229 i_start = h->GetXaxis()->GetFirst();
00230 i_end = h->GetXaxis()->GetLast();
00231
00232 ndof = i_end-i_start+1-constraint;
00233
00234
00235 double sum1=0, sum2=0;
00236 for (i=i_start; i<=i_end; i++)
00237 {
00238 sum1 += h->GetBinContent(i);
00239 sum2 += ref_->GetBinContent(i);
00240 }
00241
00242
00243 if (sum1 == 0)
00244 {
00245 if (verbose_>0)
00246 std::cout << "QTest:Comp2RefChi2"
00247 << " Test Histogram " << h->GetName()
00248 << " is empty, exiting\n";
00249 return -1;
00250 }
00251 if (sum2 == 0)
00252 {
00253 if (verbose_>0)
00254 std::cout << "QTest:Comp2RefChi2"
00255 << " Ref Histogram " << ref_->GetName()
00256 << " is empty, exiting\n";
00257 return -1;
00258 }
00259
00260 double bin1, bin2, err1, err2, temp;
00261 for (i=i_start; i<=i_end; i++)
00262 {
00263 bin1 = h->GetBinContent(i)/sum1;
00264 bin2 = ref_->GetBinContent(i)/sum2;
00265 if (bin1 ==0 && bin2==0)
00266 {
00267 --ndof;
00268 }
00269 else
00270 {
00271 temp = bin1-bin2;
00272 err1=h->GetBinError(i); err2=ref_->GetBinError(i);
00273 if (err1 == 0 && err2 == 0)
00274 {
00275 if (verbose_>0)
00276 std::cout << "QTest:Comp2RefChi2"
00277 << " bins with non-zero content and zero error, exiting\n";
00278 return -1;
00279 }
00280 err1*=err1 ; err2*=err2;
00281 err1/=sum1*sum1 ; err2/=sum2*sum2;
00282 chi2 +=temp*temp/(err1+err2);
00283 }
00284 }
00285 chi2_ = chi2; Ndof_ = ndof;
00286 return TMath::Prob(0.5*chi2, int(0.5*ndof));
00287 }
00288
00289
00290
00291
00292
00293 float Comp2RefKolmogorov::runTest(const MonitorElement *me)
00294 {
00295 const double difprec = 1e-5;
00296
00297 if (!me)
00298 return -1;
00299 if (!me->getRootObject() || !me->getRefRootObject())
00300 return -1;
00301 TH1* h=0;
00302 TH1* ref_=0;
00303
00304 if (verbose_>1)
00305 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00306 << me-> getFullname() << "\n";
00307
00308 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00309 {
00310 h = me->getTH1F();
00311 ref_ = me->getRefTH1F();
00312 }
00313
00314 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00315 {
00316 h = me->getTH1S();
00317 ref_ = me->getRefTH1S();
00318 }
00319
00320 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00321 {
00322 h = me->getTH1D();
00323 ref_ = me->getRefTH1D();
00324 }
00325
00326 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
00327 {
00328 h = me->getTProfile();
00329 ref_ = me->getRefTProfile();
00330 }
00331 else
00332 {
00333 if (verbose_>0)
00334 std::cout << "QTest:Comp2RefKolmogorov"
00335 << " ME does not contain TH1F/TH1S/TH1D/TProfile, exiting\n";
00336 return -1;
00337 }
00338
00339
00340 int ncx1 = h->GetXaxis()->GetNbins();
00341 int ncx2 = ref_->GetXaxis()->GetNbins();
00342 if ( ncx1 != ncx2)
00343 {
00344 if (verbose_>0)
00345 std::cout << "QTest:Comp2RefKolmogorov"
00346 << " different number of channels! ("
00347 << ncx1 << ", " << ncx2 << "), exiting\n";
00348 return -1;
00349 }
00350
00351 double diff1 = TMath::Abs(h->GetXaxis()->GetXmin() - ref_->GetXaxis()->GetXmin());
00352 double diff2 = TMath::Abs(h->GetXaxis()->GetXmax() - ref_->GetXaxis()->GetXmax());
00353 if (diff1 > difprec || diff2 > difprec)
00354 {
00355 if (verbose_>0)
00356 std::cout << "QTest:Comp2RefKolmogorov"
00357 << " histograms with different binning, exiting\n";
00358 return -1;
00359 }
00360
00361
00362 Bool_t afunc1 = kFALSE; Bool_t afunc2 = kFALSE;
00363 double sum1 = 0, sum2 = 0;
00364 double ew1, ew2, w1 = 0, w2 = 0;
00365 int bin;
00366 for (bin=1;bin<=ncx1;bin++)
00367 {
00368 sum1 += h->GetBinContent(bin);
00369 sum2 += ref_->GetBinContent(bin);
00370 ew1 = h->GetBinError(bin);
00371 ew2 = ref_->GetBinError(bin);
00372 w1 += ew1*ew1;
00373 w2 += ew2*ew2;
00374 }
00375
00376 if (sum1 == 0)
00377 {
00378 if (verbose_>0)
00379 std::cout << "QTest:Comp2RefKolmogorov"
00380 << " Test Histogram: " << h->GetName()
00381 << ": integral is zero, exiting\n";
00382 return -1;
00383 }
00384 if (sum2 == 0)
00385 {
00386 if (verbose_>0)
00387 std::cout << "QTest:Comp2RefKolmogorov"
00388 << " Ref Histogram: " << ref_->GetName()
00389 << ": integral is zero, exiting\n";
00390 return -1;
00391 }
00392
00393 double tsum1 = sum1; double tsum2 = sum2;
00394 tsum1 += h->GetBinContent(0);
00395 tsum2 += ref_->GetBinContent(0);
00396 tsum1 += h->GetBinContent(ncx1+1);
00397 tsum2 += ref_->GetBinContent(ncx1+1);
00398
00399
00400
00401
00402 double ne1 = h->GetEntries();
00403 double ne2 = ref_->GetEntries();
00404
00405 double difsum1 = (ne1-tsum1)/tsum1;
00406 double esum1 = sum1;
00407 if (difsum1 > difprec && int(ne1) != ncx1)
00408 {
00409 if (h->GetSumw2N() == 0)
00410 {
00411 if (verbose_>0)
00412 std::cout << "QTest:Comp2RefKolmogorov"
00413 << " Weighted events and no Sumw2 for "
00414 << h->GetName() << "\n";
00415 }
00416 else
00417 {
00418 esum1 = sum1*sum1/w1;
00419 }
00420 }
00421
00422 double difsum2 = (ne2-tsum2)/tsum2;
00423 double esum2 = sum2;
00424 if (difsum2 > difprec && int(ne2) != ncx1)
00425 {
00426 if (ref_->GetSumw2N() == 0)
00427 {
00428 if (verbose_>0)
00429 std::cout << "QTest:Comp2RefKolmogorov"
00430 << " Weighted events and no Sumw2 for "
00431 << ref_->GetName() << "\n";
00432 }
00433 else
00434 {
00435 esum2 = sum2*sum2/w2;
00436 }
00437 }
00438
00439 double s1 = 1/tsum1; double s2 = 1/tsum2;
00440
00441 double dfmax =0, rsum1 = 0, rsum2 = 0;
00442
00443 int first = 0;
00444
00445 int last = ncx1+1;
00446 for ( bin=first; bin<=last; bin++)
00447 {
00448 rsum1 += s1*h->GetBinContent(bin);
00449 rsum2 += s2*ref_->GetBinContent(bin);
00450 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
00451 }
00452
00453
00454 double z = 0;
00455 if (afunc1) z = dfmax*TMath::Sqrt(esum2);
00456 else if (afunc2) z = dfmax*TMath::Sqrt(esum1);
00457 else z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
00458
00459
00460 if (TMath::Abs(rsum1-1) > 0.002)
00461 if (verbose_>0)
00462 std::cout << "QTest:Comp2RefKolmogorov"
00463 << " Numerical problems with histogram "
00464 << h->GetName() << "\n";
00465 if (TMath::Abs(rsum2-1) > 0.002)
00466 if (verbose_>0)
00467 std::cout << "QTest:Comp2RefKolmogorov"
00468 << " Numerical problems with histogram "
00469 << ref_->GetName() << "\n";
00470
00471 return TMath::KolmogorovProb(z);
00472 }
00473
00474
00475
00476
00477 float ContentsXRange::runTest(const MonitorElement*me)
00478 {
00479 badChannels_.clear();
00480
00481 if (!me)
00482 return -1;
00483 if (!me->getRootObject())
00484 return -1;
00485 TH1* h=0;
00486
00487 if (verbose_>1)
00488 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00489 << me-> getFullname() << "\n";
00490
00491 if (me->kind()==MonitorElement::DQM_KIND_TH1F )
00492 {
00493 h = me->getTH1F();
00494 }
00495
00496 else if ( me->kind()==MonitorElement::DQM_KIND_TH1S )
00497 {
00498 h = me->getTH1S();
00499 }
00500
00501 else if ( me->kind()==MonitorElement::DQM_KIND_TH1D )
00502 {
00503 h = me->getTH1D();
00504 }
00505 else
00506 {
00507 if (verbose_>0) std::cout << "QTest:ContentsXRange"
00508 << " ME " << me->getFullname()
00509 << " does not contain TH1F/TH1S/TH1D, exiting\n";
00510 return -1;
00511 }
00512
00513 if (!rangeInitialized_)
00514 {
00515 if ( h->GetXaxis() )
00516 setAllowedXRange(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
00517 else
00518 return -1;
00519 }
00520 int ncx = h->GetXaxis()->GetNbins();
00521
00522 int first = 0;
00523
00524 int last = ncx+1;
00525
00526 double sum = 0;
00527
00528 double fail = 0;
00529 int bin;
00530 for (bin = first; bin <= last; ++bin)
00531 {
00532 double contents = h->GetBinContent(bin);
00533 double x = h->GetBinCenter(bin);
00534 sum += contents;
00535 if (x < xmin_ || x > xmax_)fail += contents;
00536 }
00537
00538 if (sum==0) return 1;
00539
00540 return (sum - fail)/sum;
00541
00542 }
00543
00544
00545
00546
00547 float ContentsYRange::runTest(const MonitorElement*me)
00548 {
00549 badChannels_.clear();
00550
00551 if (!me)
00552 return -1;
00553 if (!me->getRootObject())
00554 return -1;
00555 TH1* h=0;
00556
00557 if (verbose_>1)
00558 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00559 << me-> getFullname() << "\n";
00560
00561 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00562 {
00563 h = me->getTH1F();
00564 }
00565 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00566 {
00567 h = me->getTH1S();
00568 }
00569 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00570 {
00571 h = me->getTH1D();
00572 }
00573 else
00574 {
00575 if (verbose_>0)
00576 std::cout << "QTest:ContentsYRange"
00577 << " ME " << me->getFullname()
00578 << " does not contain TH1F/TH1S/TH1D, exiting\n";
00579 return -1;
00580 }
00581
00582 if (!rangeInitialized_ || !h->GetXaxis()) return 1;
00583 int ncx = h->GetXaxis()->GetNbins();
00584
00585 int first = 1;
00586
00587 int last = ncx;
00588
00589 int fail = 0;
00590 int bin;
00591
00592 if (useEmptyBins_)
00593 {
00594 for (bin = first; bin <= last; ++bin)
00595 {
00596 double contents = h->GetBinContent(bin);
00597 bool failure = false;
00598 failure = (contents < ymin_ || contents > ymax_);
00599 if (failure)
00600 {
00601 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
00602 badChannels_.push_back(chan);
00603 ++fail;
00604 }
00605 }
00606
00607 return 1.*(ncx - fail)/ncx;
00608 }
00609 else
00610 {
00611 for (bin = first; bin <= last; ++bin)
00612 {
00613 double contents = h->GetBinContent(bin);
00614 bool failure = false;
00615 if (contents) failure = (contents < ymin_ || contents > ymax_);
00616 if (failure) ++fail;
00617 }
00618
00619 return 1.*(ncx - fail)/ncx;
00620 }
00621 }
00622
00623
00624
00625
00626 float DeadChannel::runTest(const MonitorElement*me)
00627 {
00628 badChannels_.clear();
00629 if (!me)
00630 return -1;
00631 if (!me->getRootObject())
00632 return -1;
00633 TH1* h1=0;
00634 TH2* h2=0;
00635
00636 if (verbose_>1)
00637 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00638 << me-> getFullname() << "\n";
00639
00640 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00641 {
00642 h1 = me->getTH1F();
00643 }
00644
00645 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00646 {
00647 h1 = me->getTH1S();
00648 }
00649
00650 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00651 {
00652 h1 = me->getTH1D();
00653 }
00654
00655 else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
00656 {
00657 h2 = me->getTH2F();
00658 }
00659
00660 else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
00661 {
00662 h2 = me->getTH2S();
00663 }
00664
00665 else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
00666 {
00667 h2 = me->getTH2D();
00668 }
00669 else
00670 {
00671 if (verbose_>0)
00672 std::cout << "QTest:DeadChannel"
00673 << " ME " << me->getFullname()
00674 << " does not contain TH1F/TH1S/TH1D/TH2F/TH2S/TH2D, exiting\n";
00675 return -1;
00676 }
00677
00678 int fail = 0;
00679
00680
00681 if (h1 != NULL)
00682 {
00683 if (!rangeInitialized_ || !h1->GetXaxis() )
00684 return 1;
00685 int ncx = h1->GetXaxis()->GetNbins();
00686 int first = 1;
00687 int last = ncx;
00688 int bin;
00689
00691 for (bin = first; bin <= last; ++bin)
00692 {
00693 double contents = h1->GetBinContent(bin);
00694 bool failure = false;
00695 failure = contents <= ymin_;
00696 if (failure)
00697 {
00698 DQMChannel chan(bin, 0, 0, contents, h1->GetBinError(bin));
00699 badChannels_.push_back(chan);
00700 ++fail;
00701 }
00702 }
00703
00704 return 1.*(ncx - fail)/ncx;
00705 }
00706
00707
00708
00709 else if (h2 !=NULL )
00710 {
00711 int ncx = h2->GetXaxis()->GetNbins();
00712 int ncy = h2->GetYaxis()->GetNbins();
00713
00715 for (int cx = 1; cx <= ncx; ++cx)
00716 {
00717 for (int cy = 1; cy <= ncy; ++cy)
00718 {
00719 double contents = h2->GetBinContent(h2->GetBin(cx, cy));
00720 bool failure = false;
00721 failure = contents <= ymin_;
00722 if (failure)
00723 {
00724 DQMChannel chan(cx, cy, 0, contents, h2->GetBinError(h2->GetBin(cx, cy)));
00725 badChannels_.push_back(chan);
00726 ++fail;
00727 }
00728 }
00729 }
00730
00731 return 1.*(ncx*ncy - fail) / (ncx*ncy);
00732 }
00733 else
00734 {
00735 if (verbose_>0)
00736 std::cout << "QTest:DeadChannel"
00737 << " TH1/TH2F are NULL, exiting\n";
00738 return -1;
00739 }
00740 }
00741
00742
00743
00744
00745
00746
00747 float NoisyChannel::runTest(const MonitorElement *me)
00748 {
00749 badChannels_.clear();
00750 if (!me)
00751 return -1;
00752 if (!me->getRootObject())
00753 return -1;
00754 TH1* h=0;
00755
00756 if (verbose_>1)
00757 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00758 << me-> getFullname() << "\n";
00759
00760 int nbins=0;
00761
00762 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
00763 {
00764 nbins = me->getTH1F()->GetXaxis()->GetNbins();
00765 h = me->getTH1F();
00766 }
00767
00768 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
00769 {
00770 nbins = me->getTH1S()->GetXaxis()->GetNbins();
00771 h = me->getTH1S();
00772 }
00773
00774 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
00775 {
00776 nbins = me->getTH1D()->GetXaxis()->GetNbins();
00777 h = me->getTH1D();
00778 }
00779
00780 else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
00781 {
00782 nbins = me->getTH2F()->GetXaxis()->GetNbins() *
00783 me->getTH2F()->GetYaxis()->GetNbins();
00784 h = me->getTH2F();
00785 }
00786
00787 else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
00788 {
00789 nbins = me->getTH2S()->GetXaxis()->GetNbins() *
00790 me->getTH2S()->GetYaxis()->GetNbins();
00791 h = me->getTH2S();
00792 }
00793
00794 else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
00795 {
00796 nbins = me->getTH2D()->GetXaxis()->GetNbins() *
00797 me->getTH2D()->GetYaxis()->GetNbins();
00798 h = me->getTH2D();
00799 }
00800 else
00801 {
00802 if (verbose_>0)
00803 std::cout << "QTest:NoisyChannel"
00804 << " ME " << me->getFullname()
00805 << " does not contain TH1F/TH1S/TH1D or TH2F/TH2S/TH2D, exiting\n";
00806 return -1;
00807 }
00808
00809
00810
00811 if ( !rangeInitialized_ || !h->GetXaxis() )
00812 return 1;
00813
00814
00815 int first = 1;
00816
00817 int last = nbins;
00818
00819 int fail = 0;
00820 int bin;
00821 for (bin = first; bin <= last; ++bin)
00822 {
00823 double contents = h->GetBinContent(bin);
00824 double average = getAverage(bin, h);
00825 bool failure = false;
00826 if (average != 0)
00827 failure = (((contents-average)/TMath::Abs(average)) > tolerance_);
00828
00829 if (failure)
00830 {
00831 ++fail;
00832 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
00833 badChannels_.push_back(chan);
00834 }
00835 }
00836
00837
00838 return 1.*(nbins - fail)/nbins;
00839 }
00840
00841
00842
00843 double NoisyChannel::getAverage(int bin, const TH1 *h) const
00844 {
00846 int first = 1;
00848 int ncx = h->GetXaxis()->GetNbins();
00849 double sum = 0; int bin_low, bin_hi;
00850 for (unsigned i = 1; i <= numNeighbors_; ++i)
00851 {
00853 bin_low = bin-i; bin_hi = bin+i;
00856 while (bin_low < first)
00857 bin_low = ncx + bin_low;
00858 while (bin_hi > ncx)
00859 bin_hi = bin_hi - ncx;
00860 sum += h->GetBinContent(bin_low) + h->GetBinContent(bin_hi);
00861 }
00863 return sum/(numNeighbors_ * 2);
00864 }
00865
00866
00867
00868
00869
00870
00871
00872 float ContentsWithinExpected::runTest(const MonitorElement*me)
00873 {
00874 badChannels_.clear();
00875 if (!me)
00876 return -1;
00877 if (!me->getRootObject())
00878 return -1;
00879 TH1* h=0;
00880
00881 if (verbose_>1)
00882 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
00883 << me-> getFullname() << "\n";
00884
00885 int ncx;
00886 int ncy;
00887
00888 if (useEmptyBins_)
00889 {
00890
00891 if (me->kind()==MonitorElement::DQM_KIND_TH2F)
00892 {
00893 ncx = me->getTH2F()->GetXaxis()->GetNbins();
00894 ncy = me->getTH2F()->GetYaxis()->GetNbins();
00895 h = me->getTH2F();
00896 }
00897
00898 else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
00899 {
00900 ncx = me->getTH2S()->GetXaxis()->GetNbins();
00901 ncy = me->getTH2S()->GetYaxis()->GetNbins();
00902 h = me->getTH2S();
00903 }
00904
00905 else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
00906 {
00907 ncx = me->getTH2D()->GetXaxis()->GetNbins();
00908 ncy = me->getTH2D()->GetYaxis()->GetNbins();
00909 h = me->getTH2D();
00910 }
00911
00912 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
00913 {
00914 ncx = me->getTProfile()->GetXaxis()->GetNbins();
00915 ncy = 1;
00916 h = me->getTProfile();
00917 }
00918
00919 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE2D)
00920 {
00921 ncx = me->getTProfile2D()->GetXaxis()->GetNbins();
00922 ncy = me->getTProfile2D()->GetYaxis()->GetNbins();
00923 h = me->getTProfile2D();
00924 }
00925 else
00926 {
00927 if (verbose_>0)
00928 std::cout << "QTest:ContentsWithinExpected"
00929 << " ME does not contain TH2F/TH2S/TH2D/TPROFILE/TPROFILE2D, exiting\n";
00930 return -1;
00931 }
00932
00933 int nsum = 0;
00934 double sum = 0.0;
00935 double average = 0.0;
00936
00937 if (checkMeanTolerance_)
00938 {
00939
00940 for (int cx = 1; cx <= ncx; ++cx)
00941 {
00942 for (int cy = 1; cy <= ncy; ++cy)
00943 {
00944 if (me->kind() == MonitorElement::DQM_KIND_TH2F)
00945 {
00946 sum += h->GetBinContent(h->GetBin(cx, cy));
00947 ++nsum;
00948 }
00949 else if (me->kind() == MonitorElement::DQM_KIND_TH2S)
00950 {
00951 sum += h->GetBinContent(h->GetBin(cx, cy));
00952 ++nsum;
00953 }
00954 else if (me->kind() == MonitorElement::DQM_KIND_TH2D)
00955 {
00956 sum += h->GetBinContent(h->GetBin(cx, cy));
00957 ++nsum;
00958 }
00959 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE)
00960 {
00961 if (me->getTProfile()->GetBinEntries(h->GetBin(cx)) >= minEntries_/(ncx))
00962 {
00963 sum += h->GetBinContent(h->GetBin(cx));
00964 ++nsum;
00965 }
00966 }
00967 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D)
00968 {
00969 if (me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) >= minEntries_/(ncx*ncy))
00970 {
00971 sum += h->GetBinContent(h->GetBin(cx, cy));
00972 ++nsum;
00973 }
00974 }
00975 }
00976 }
00977
00978 if (nsum > 0)
00979 average = sum/nsum;
00980
00981 }
00982
00983 int fail = 0;
00984
00985 for (int cx = 1; cx <= ncx; ++cx)
00986 {
00987 for (int cy = 1; cy <= ncy; ++cy)
00988 {
00989 bool failMean = false;
00990 bool failRMS = false;
00991 bool failMeanTolerance = false;
00992
00993 if (me->kind() == MonitorElement::DQM_KIND_TPROFILE &&
00994 me->getTProfile()->GetBinEntries(h->GetBin(cx)) < minEntries_/(ncx))
00995 continue;
00996
00997 if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D &&
00998 me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) < minEntries_/(ncx*ncy))
00999 continue;
01000
01001 if (checkMean_)
01002 {
01003 double mean = h->GetBinContent(h->GetBin(cx, cy));
01004 failMean = (mean < minMean_ || mean > maxMean_);
01005 }
01006
01007 if (checkRMS_)
01008 {
01009 double rms = h->GetBinError(h->GetBin(cx, cy));
01010 failRMS = (rms < minRMS_ || rms > maxRMS_);
01011 }
01012
01013 if (checkMeanTolerance_)
01014 {
01015 double mean = h->GetBinContent(h->GetBin(cx, cy));
01016 failMeanTolerance = (TMath::Abs(mean - average) > toleranceMean_*TMath::Abs(average));
01017 }
01018
01019 if (failMean || failRMS || failMeanTolerance)
01020 {
01021
01022 if (me->kind() == MonitorElement::DQM_KIND_TH2F)
01023 {
01024 DQMChannel chan(cx, cy, 0,
01025 h->GetBinContent(h->GetBin(cx, cy)),
01026 h->GetBinError(h->GetBin(cx, cy)));
01027 badChannels_.push_back(chan);
01028 }
01029 else if (me->kind() == MonitorElement::DQM_KIND_TH2S)
01030 {
01031 DQMChannel chan(cx, cy, 0,
01032 h->GetBinContent(h->GetBin(cx, cy)),
01033 h->GetBinError(h->GetBin(cx, cy)));
01034 badChannels_.push_back(chan);
01035 }
01036 else if (me->kind() == MonitorElement::DQM_KIND_TH2D)
01037 {
01038 DQMChannel chan(cx, cy, 0,
01039 h->GetBinContent(h->GetBin(cx, cy)),
01040 h->GetBinError(h->GetBin(cx, cy)));
01041 badChannels_.push_back(chan);
01042 }
01043 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE)
01044 {
01045 DQMChannel chan(cx, cy, int(me->getTProfile()->GetBinEntries(h->GetBin(cx))),
01046 0,
01047 h->GetBinError(h->GetBin(cx)));
01048 badChannels_.push_back(chan);
01049 }
01050 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D)
01051 {
01052 DQMChannel chan(cx, cy, int(me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy))),
01053 h->GetBinContent(h->GetBin(cx, cy)),
01054 h->GetBinError(h->GetBin(cx, cy)));
01055 badChannels_.push_back(chan);
01056 }
01057 ++fail;
01058 }
01059 }
01060 }
01061 return 1.*(ncx*ncy - fail)/(ncx*ncy);
01062 }
01063
01064 else
01065 {
01066 if (me->kind()==MonitorElement::DQM_KIND_TH2F)
01067 {
01068 ncx = me->getTH2F()->GetXaxis()->GetNbins();
01069 ncy = me->getTH2F()->GetYaxis()->GetNbins();
01070 h = me->getTH2F();
01071 }
01072 else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
01073 {
01074 ncx = me->getTH2S()->GetXaxis()->GetNbins();
01075 ncy = me->getTH2S()->GetYaxis()->GetNbins();
01076 h = me->getTH2S();
01077 }
01078 else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
01079 {
01080 ncx = me->getTH2D()->GetXaxis()->GetNbins();
01081 ncy = me->getTH2D()->GetYaxis()->GetNbins();
01082 h = me->getTH2D();
01083 }
01084 else
01085 {
01086 if (verbose_>0)
01087 std::cout << "QTest:ContentsWithinExpected AS"
01088 << " ME does not contain TH2F/TH2S/TH2D, exiting\n";
01089 return -1;
01090 }
01091
01092
01093 int fail = 0;
01094 for (int cx = 1; cx <= ncx; ++cx)
01095 {
01096 for (int cy = 1; cy <= ncy; ++cy)
01097 {
01098 bool failure = false;
01099 double Content = h->GetBinContent(h->GetBin(cx, cy));
01100 if (Content)
01101 failure = (Content < minMean_ || Content > maxMean_);
01102 if (failure)
01103 ++fail;
01104 }
01105 }
01106 return 1.*(ncx*ncy-fail)/(ncx*ncy);
01107 }
01108
01109 }
01111 void ContentsWithinExpected::setMeanRange(double xmin, double xmax)
01112 {
01113 if (xmax < xmin)
01114 if (verbose_>0)
01115 std::cout << "QTest:ContentsWitinExpected"
01116 << " Illogical range: (" << xmin << ", " << xmax << "\n";
01117 minMean_ = xmin;
01118 maxMean_ = xmax;
01119 checkMean_ = true;
01120 }
01121
01123 void ContentsWithinExpected::setRMSRange(double xmin, double xmax)
01124 {
01125 if (xmax < xmin)
01126 if (verbose_>0)
01127 std::cout << "QTest:ContentsWitinExpected"
01128 << " Illogical range: (" << xmin << ", " << xmax << "\n";
01129 minRMS_ = xmin;
01130 maxRMS_ = xmax;
01131 checkRMS_ = true;
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 float MeanWithinExpected::runTest(const MonitorElement *me )
01148 {
01149 if (!me)
01150 return -1;
01151 if (!me->getRootObject())
01152 return -1;
01153 TH1* h=0;
01154
01155 if (verbose_>1)
01156 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
01157 << me-> getFullname() << "\n";
01158
01159 if (minEntries_ != 0 && me->getEntries() < minEntries_) return -1;
01160
01161 if (me->kind()==MonitorElement::DQM_KIND_TH1F)
01162 {
01163 h = me->getTH1F();
01164 }
01165 else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
01166 {
01167 h = me->getTH1S();
01168 }
01169 else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
01170 {
01171 h = me->getTH1D();
01172 }
01173 else {
01174 if (verbose_>0)
01175 std::cout << "QTest:MeanWithinExpected"
01176 << " ME " << me->getFullname()
01177 << " does not contain TH1F/TH1S/TH1D, exiting\n";
01178 return -1;
01179 }
01180
01181
01182 if (useRange_) {
01183 double mean = h->GetMean();
01184 if (mean <= xmax_ && mean >= xmin_)
01185 return 1;
01186 else
01187 return 0;
01188 }
01189 else if (useSigma_)
01190 {
01191 if (sigma_ != 0.)
01192 {
01193 double chi = (h->GetMean() - expMean_)/sigma_;
01194 return TMath::Prob(chi*chi, 1);
01195 }
01196 else
01197 {
01198 if (verbose_>0)
01199 std::cout << "QTest:MeanWithinExpected"
01200 << " Error, sigma_ is zero, exiting\n";
01201 return 0;
01202 }
01203 }
01204 else if (useRMS_)
01205 {
01206 if (h->GetRMS() != 0.)
01207 {
01208 double chi = (h->GetMean() - expMean_)/h->GetRMS();
01209 return TMath::Prob(chi*chi, 1);
01210 }
01211 else
01212 {
01213 if (verbose_>0)
01214 std::cout << "QTest:MeanWithinExpected"
01215 << " Error, RMS is zero, exiting\n";
01216 return 0;
01217 }
01218 }
01219 else
01220 if (verbose_>0)
01221 std::cout << "QTest:MeanWithinExpected"
01222 << " Error, neither Range, nor Sigma, nor RMS, exiting\n";
01223 return -1;
01224 }
01225
01226 void MeanWithinExpected::useRange(double xmin, double xmax)
01227 {
01228 useRange_ = true;
01229 useSigma_ = useRMS_ = false;
01230 xmin_ = xmin; xmax_ = xmax;
01231 if (xmin_ > xmax_)
01232 if (verbose_>0)
01233 std::cout << "QTest:MeanWithinExpected"
01234 << " Illogical range: (" << xmin_ << ", " << xmax_ << "\n";
01235 }
01236 void MeanWithinExpected::useSigma(double expectedSigma)
01237 {
01238 useSigma_ = true;
01239 useRMS_ = useRange_ = false;
01240 sigma_ = expectedSigma;
01241 if (sigma_ == 0)
01242 if (verbose_>0)
01243 std::cout << "QTest:MeanWithinExpected"
01244 << " Expected sigma = " << sigma_ << "\n";
01245 }
01246
01247 void MeanWithinExpected::useRMS()
01248 {
01249 useRMS_ = true;
01250 useSigma_ = useRange_ = false;
01251 }
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264 float CompareToMedian::runTest(const MonitorElement *me){
01265 int32_t nbins=0, failed=0;
01266 badChannels_.clear();
01267
01268 if (!me)
01269 return -1;
01270 if (!me->getRootObject())
01271 return -1;
01272 TH1* h=0;
01273
01274 if (verbose_>1){
01275 std::cout << "QTest:" << getAlgoName() << "::runTest called on "
01276 << me-> getFullname() << "\n";
01277 std::cout << "\tMin = " << _min << "; Max = " << _max << "\n";
01278 std::cout << "\tMinMedian = " << _minMed << "; MaxMedian = " << _maxMed << "\n";
01279 std::cout << "\tUseEmptyBins = " << (_emptyBins?"Yes":"No" )<< "\n";
01280 }
01281
01282 if (me->kind()==MonitorElement::DQM_KIND_TPROFILE2D)
01283 {
01284 h = me->getTProfile2D();
01285 }
01286 else
01287 {
01288 if (verbose_>0)
01289 std::cout << "QTest:ContentsWithinExpected"
01290 << " ME does not contain TPROFILE2D, exiting\n";
01291 return -1;
01292 }
01293
01294 nBinsX = h->GetNbinsX();
01295 nBinsY = h->GetNbinsY();
01296 int entries = 0;
01297 float median = 0.0;
01298
01299
01300 for (int binX = 1; binX <= nBinsX; binX++ ){
01301 reset();
01302
01303 for (int binY = 1; binY <= nBinsY; binY++){
01304 int bin = h->GetBin(binX, binY);
01305 double content = (double)h->GetBinContent(bin);
01306 if ( content == 0 && !_emptyBins)
01307 continue;
01308 binValues.push_back(content);
01309 entries = me->getTProfile2D()->GetBinEntries(bin);
01310 }
01311 if (binValues.empty())
01312 continue;
01313 nbins+=binValues.size();
01314
01315
01316 if(binValues.size()>0){
01317 int medPos = (int)binValues.size()/2;
01318 nth_element(binValues.begin(),binValues.begin()+medPos,binValues.end());
01319 median = *(binValues.begin()+medPos);
01320 }
01321
01322
01323 if(median == 0){
01324 if (verbose_ > 0){
01325 std::cout << "QTest: Median is 0; the fixed cuts: [" << _minMed << "; " << _maxMed << "] are used\n";
01326 }
01327 for(int binY = 1; binY <= nBinsY; binY++){
01328 int bin = h->GetBin(binX, binY);
01329 double content = (double)h->GetBinContent(bin);
01330 entries = me->getTProfile2D()->GetBinEntries(bin);
01331 if ( entries == 0 )
01332 continue;
01333 if (content > _maxMed || content < _minMed){
01334 DQMChannel chan(binX,binY, 0, content, h->GetBinError(bin));
01335 badChannels_.push_back(chan);
01336 failed++;
01337 }
01338 }
01339 continue;
01340 }
01341
01342
01343 if (median*entries < _statCut )
01344 continue;
01345
01346
01347 if(median > _maxMed || median < _minMed){
01348 for(int binY = 1; binY <= nBinsY; binY++){
01349 int bin = h->GetBin(binX, binY);
01350 double content = (double)h->GetBinContent(bin);
01351 entries = me->getTProfile2D()->GetBinEntries(bin);
01352 if ( entries == 0 )
01353 continue;
01354 DQMChannel chan(binX,binY, 0, content/median, h->GetBinError(bin));
01355 badChannels_.push_back(chan);
01356 failed++;
01357 }
01358 continue;
01359 }
01360
01361
01362 float minCut = median*_min;
01363 float maxCut = median*_max;
01364 for(int binY = 1; binY <= nBinsY; binY++){
01365 int bin = h->GetBin(binX, binY);
01366 double content = (double)h->GetBinContent(bin);
01367 entries = me->getTProfile2D()->GetBinEntries(bin);
01368 if ( entries == 0 )
01369 continue;
01370 if (content > maxCut || content < minCut){
01371 DQMChannel chan(binX,binY, 0, content/median, h->GetBinError(bin));
01372 badChannels_.push_back(chan);
01373 failed++;
01374 }
01375 }
01376 }
01377
01378 if (nbins==0){
01379 if (verbose_ > 0)
01380 std::cout << "QTest:CompareToMedian: Histogram is empty" << std::endl;
01381 return 1.;
01382 }
01383 return 1 - (float)failed/nbins;
01384 }
01385
01386