00001 #include "DQMServices/Core/interface/QTest.h" 00002 #include "DQMServices/Core/src/QStatisticalTests.h" 00003 #include "FWCore/ServiceRegistry/interface/Service.h" 00004 #include "TMath.h" 00005 #include "TH1F.h" 00006 #include "TH1S.h" 00007 #include <iostream> 00008 #include <sstream> 00009 #include <math.h> 00010 00011 #include "DQMServices/Core/interface/DQMStore.h" 00012 00013 using namespace std; 00014 00015 const float QCriterion::ERROR_PROB_THRESHOLD = 0.50; 00016 const float QCriterion::WARNING_PROB_THRESHOLD = 0.90; 00017 00018 // initialize values 00019 void 00020 QCriterion::init(void) 00021 { 00022 wasModified_ = true; 00023 errorProb_ = ERROR_PROB_THRESHOLD; 00024 warningProb_ = WARNING_PROB_THRESHOLD; 00025 setAlgoName("NO_ALGORITHM"); 00026 status_ = dqm::qstatus::DID_NOT_RUN; 00027 message_ = "NO_MESSAGE"; 00028 } 00029 00030 // set status & message for disabled tests 00031 void 00032 QCriterion::setDisabled(void) 00033 { 00034 status_ = dqm::qstatus::DISABLED; 00035 std::ostringstream message; 00036 message << " Test " << qtname_ << " (" << algoName() 00037 << ") has been disabled "; 00038 message_ = message.str(); 00039 } 00040 00041 // set status & message for invalid tests 00042 void 00043 QCriterion::setInvalid(void) 00044 { 00045 status_ = dqm::qstatus::INVALID; 00046 std::ostringstream message; 00047 message << " Test " << qtname_ << " (" << algoName() 00048 << ") cannot run due to problems "; 00049 message_ = message.str(); 00050 } 00051 00052 float QCriterion::runTest(const MonitorElement *me) 00053 { 00054 cout << " QCriterion:: virtual runTest method called " << endl; 00055 return -1; 00056 } 00057 //===================================================// 00058 //================ QUALITY TESTS ====================// 00059 //==================================================// 00060 00061 //-------------------------------------------------------// 00062 //----------------- Comp2RefEqualH base -----------------// 00063 //-------------------------------------------------------// 00064 // run the test (result: [0, 1] or <0 for failure) 00065 float Comp2RefEqualH::runTest(const MonitorElement*me) 00066 { 00067 00068 badChannels_.clear(); 00069 00070 if (!me) return -1; 00071 if (!me->getRootObject() || !me->getRefRootObject()) return -1; 00072 h=0;//initialize histogram pointer 00073 ref_=0; 00074 00075 int nbins=0; 00076 int nbinsref=0; 00077 //-- TH1F 00078 if (me->kind()==MonitorElement::DQM_KIND_TH1F){ 00079 nbins = me->getTH1F()->GetXaxis()->GetNbins(); 00080 nbinsref = me->getRefTH1F()->GetXaxis()->GetNbins(); 00081 h = me->getTH1F(); // access Test histo 00082 ref_ = me->getRefTH1F(); //access Ref hiso 00083 if (nbins != nbinsref) return -1; 00084 } 00085 00086 //-- TH1S 00087 else if (me->kind()==MonitorElement::DQM_KIND_TH1S){ 00088 nbins = me->getTH1S()->GetXaxis()->GetNbins(); 00089 nbinsref = me->getRefTH1S()->GetXaxis()->GetNbins(); 00090 h = me->getTH1S(); // access Test histo 00091 ref_ = me->getRefTH1S(); //access Ref hiso 00092 if (nbins != nbinsref) return -1; 00093 } 00094 00095 //-- TH2 00096 else if (me->kind()==MonitorElement::DQM_KIND_TH2F){ 00097 nbins = me->getTH2F()->GetXaxis()->GetNbins() * 00098 me->getTH2F()->GetYaxis()->GetNbins(); 00099 nbinsref = me->getRefTH2F()->GetXaxis()->GetNbins() * 00100 me->getRefTH2F()->GetYaxis()->GetNbins(); 00101 h = me->getTH2F(); // access Test histo 00102 ref_ = me->getRefTH2F(); //access Ref hiso 00103 if (nbins != nbinsref) return -1; 00104 } 00105 00106 //-- TH2 00107 else if (me->kind()==MonitorElement::DQM_KIND_TH2S){ 00108 nbins = me->getTH2S()->GetXaxis()->GetNbins() * 00109 me->getTH2S()->GetYaxis()->GetNbins(); 00110 nbinsref = me->getRefTH2S()->GetXaxis()->GetNbins() * 00111 me->getRefTH2S()->GetYaxis()->GetNbins(); 00112 h = me->getTH2S(); // access Test histo 00113 ref_ = me->getRefTH2S(); //access Ref hiso 00114 if (nbins != nbinsref) return -1; 00115 } 00116 00117 //-- TH3 00118 else if (me->kind()==MonitorElement::DQM_KIND_TH3F){ 00119 nbins = me->getTH3F()->GetXaxis()->GetNbins() * 00120 me->getTH3F()->GetYaxis()->GetNbins() * 00121 me->getTH3F()->GetZaxis()->GetNbins(); 00122 nbinsref = me->getRefTH3F()->GetXaxis()->GetNbins() * 00123 me->getRefTH3F()->GetYaxis()->GetNbins() * 00124 me->getRefTH3F()->GetZaxis()->GetNbins(); 00125 h = me->getTH3F(); // access Test histo 00126 ref_ = me->getRefTH3F(); //access Ref hiso 00127 if (nbins != nbinsref) return -1; 00128 } 00129 00130 else{ 00131 std::cout<< "Comp2RefEqualH ERROR: ME does not contain TH1F/TH1S/TH2F/TH2S/TH3F" << std::endl; 00132 return -1; 00133 } 00134 00135 //-- QUALITY TEST itself 00136 Int_t first = 0; // 1 //(use underflow bin) 00137 Int_t last = nbins+1; //(use overflow bin) 00138 bool failure = false; 00139 for (Int_t bin=first;bin<=last;bin++) { 00140 float contents = h->GetBinContent(bin); 00141 if (contents != ref_->GetBinContent(bin)) { 00142 failure = true; 00143 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin)); 00144 badChannels_.push_back(chan); 00145 } 00146 } 00147 if (failure) return 0; 00148 return 1; 00149 } 00150 00151 //-------------------------------------------------------// 00152 //----------------- Comp2RefChi2 --------------------// 00153 //-------------------------------------------------------// 00154 float Comp2RefChi2::runTest(const MonitorElement *me) 00155 { 00156 if (!me) return -1; 00157 if (!me->getRootObject() || !me->getRefRootObject()) return -1; 00158 h=0; 00159 ref_=0; 00160 00161 //-- TH1F 00162 if (me->kind()==MonitorElement::DQM_KIND_TH1F){ 00163 h = me->getTH1F(); // access Test histo 00164 ref_ = me->getRefTH1F(); //access Ref histo 00165 } 00166 //-- TH1S 00167 else if (me->kind()==MonitorElement::DQM_KIND_TH1S){ 00168 h = me->getTH1S(); // access Test histo 00169 ref_ = me->getRefTH1S(); //access Ref histo 00170 } 00171 //-- TProfile 00172 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE){ 00173 h = me->getTProfile(); // access Test histo 00174 ref_ = me->getRefTProfile(); //access Ref histo 00175 } 00176 00177 else{ 00178 std::cout<< "Comp2RefChi2 ERROR: ME does not contain TH1F/TH1S/TProfile" << std::endl; 00179 return -1; 00180 } 00181 00182 //-- isInvalid ? - Check consistency in number of channels 00183 ncx1 = h->GetXaxis()->GetNbins(); 00184 ncx2 = ref_->GetXaxis()->GetNbins(); 00185 if ( ncx1 != ncx2){ 00186 std::cout<<"Comp2RefChi2 ERROR: different number of channels! (" 00187 << ncx1 << ", " << ncx2 << ") " << std::endl; 00188 return -1; 00189 } 00190 00191 //-- QUALITY TEST itself 00192 //reset Results 00193 Ndof_ = 0; chi2_ = -1.; ncx1 = ncx2 = -1; 00194 00195 Int_t i, i_start, i_end; 00196 float chi2 = 0.; int ndof = 0; int constraint = 0; 00197 00198 i_start = 1; 00199 i_end = ncx1; 00200 // if (fXaxis.TestBit(TAxis::kAxisRange)) { 00201 i_start = h->GetXaxis()->GetFirst(); 00202 i_end = h->GetXaxis()->GetLast(); 00203 // } 00204 ndof = i_end-i_start+1-constraint; 00205 00206 //Compute the normalisation factor 00207 Double_t sum1=0, sum2=0; 00208 for (i=i_start; i<=i_end; i++){ 00209 sum1 += h->GetBinContent(i); 00210 sum2 += ref_->GetBinContent(i); 00211 } 00212 00213 //check that the histograms are not empty 00214 if (sum1 == 0){ 00215 std::cout << "Comp2RefChi2 ERROR : Test Histogram " << h->GetName() << " is empty " << std::endl; 00216 return -1; 00217 } 00218 if (sum2 == 0){ 00219 std::cout << "Comp2RefChi2 ERROR: Ref Histogram " << ref_->GetName() << " is empty " << std::endl; 00220 return -1; 00221 } 00222 00223 00224 Double_t bin1, bin2, err1, err2, temp; 00225 for (i=i_start; i<=i_end; i++){ 00226 bin1 = h->GetBinContent(i)/sum1; 00227 bin2 = ref_->GetBinContent(i)/sum2; 00228 if (bin1 ==0 && bin2==0){ 00229 --ndof; //no data means one less degree of freedom 00230 } else { 00231 temp = bin1-bin2; 00232 err1=h->GetBinError(i); err2=ref_->GetBinError(i); 00233 if (err1 == 0 && err2 == 0) 00234 { 00235 std::cout << " Comp2RefChi2 ERROR: bins with non-zero content and zero error" 00236 << std::endl; 00237 return -1; 00238 } 00239 err1*=err1 ; err2*=err2; 00240 err1/=sum1*sum1 ; err2/=sum2*sum2; 00241 chi2 +=temp*temp/(err1+err2); 00242 } 00243 } 00244 chi2_ = chi2; Ndof_ = ndof; 00245 return TMath::Prob(0.5*chi2, Int_t(0.5*ndof)); 00246 } 00247 00248 //-------------------------------------------------------// 00249 //----------------- Comp2RefKolmogorov --------------// 00250 //-------------------------------------------------------// 00251 00252 const Double_t Comp2RefKolmogorov::difprec = 1e-5; 00253 00254 float Comp2RefKolmogorov::runTest(const MonitorElement *me) 00255 { 00256 if (!me) return -1; 00257 if (!me->getRootObject() || !me->getRefRootObject()) return -1; 00258 h=0; 00259 ref_=0; 00260 00261 //-- TH1F 00262 if (me->kind()==MonitorElement::DQM_KIND_TH1F){ 00263 h = me->getTH1F(); // access Test histo 00264 ref_ = me->getRefTH1F(); //access Ref histo 00265 } 00266 //-- TH1S 00267 else if (me->kind()==MonitorElement::DQM_KIND_TH1S){ 00268 h = me->getTH1S(); // access Test histo 00269 ref_ = me->getRefTH1S(); //access Ref histo 00270 } 00271 //-- TProfile 00272 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE){ 00273 h = me->getTProfile(); // access Test histo 00274 ref_ = me->getRefTProfile(); //access Ref histo 00275 } 00276 else{ 00277 std::cout<< "Comp2RefKolmogorov ERROR: ME does not contain TH1F/TH1S/TProfile" << std::endl; 00278 return -1; 00279 } 00280 00281 //-- isInvalid ? - Check consistency in number of channels 00282 ncx1 = h->GetXaxis()->GetNbins(); 00283 ncx2 = ref_->GetXaxis()->GetNbins(); 00284 if ( ncx1 != ncx2){ 00285 std::cout<<"Comp2RefKolmogorov ERROR: different number of channels! (" 00286 << ncx1 << ", " << ncx2 << ") " << std::endl; 00287 return -1; 00288 } 00289 //-- isInvalid ? - Check consistency in channel edges 00290 Double_t diff1 = TMath::Abs(h->GetXaxis()->GetXmin() - ref_->GetXaxis()->GetXmin()); 00291 Double_t diff2 = TMath::Abs(h->GetXaxis()->GetXmax() - ref_->GetXaxis()->GetXmax()); 00292 if (diff1 > difprec || diff2 > difprec){ 00293 std::cout << "Comp2RefKolmogorov ERROR: histograms with different binning" << std::endl; 00294 return -1; 00295 } 00296 00297 //-- QUALITY TEST itself 00298 Bool_t afunc1 = kFALSE; Bool_t afunc2 = kFALSE; 00299 Double_t sum1 = 0, sum2 = 0; 00300 Double_t ew1, ew2, w1 = 0, w2 = 0; 00301 Int_t bin; 00302 for (bin=1;bin<=ncx1;bin++){ 00303 sum1 += h->GetBinContent(bin); 00304 sum2 += ref_->GetBinContent(bin); 00305 ew1 = h->GetBinError(bin); 00306 ew2 = ref_->GetBinError(bin); 00307 w1 += ew1*ew1; 00308 w2 += ew2*ew2; 00309 } 00310 if (sum1 == 0){ 00311 std::cout << "Comp2RefKolmogorov ERROR: Test Histogram " << h->GetName() << " integral is zero" << std::endl; 00312 return -1; 00313 } 00314 if (sum2 == 0){ 00315 std::cout << "Comp2RefKolmogorov ERROR: Ref Histogram " << ref_->GetName() << " integral is zero" << std::endl; 00316 return -1; 00317 } 00318 00319 Double_t tsum1 = sum1; Double_t tsum2 = sum2; 00320 tsum1 += h->GetBinContent(0); 00321 tsum2 += ref_->GetBinContent(0); 00322 tsum1 += h->GetBinContent(ncx1+1); 00323 tsum2 += ref_->GetBinContent(ncx1+1); 00324 00325 // Check if histograms are weighted. 00326 // If number of entries = number of channels, probably histograms were 00327 // not filled via Fill(), but via SetBinContent() 00328 Double_t ne1 = h->GetEntries(); 00329 Double_t ne2 = ref_->GetEntries(); 00330 // look at first histogram 00331 Double_t difsum1 = (ne1-tsum1)/tsum1; 00332 Double_t esum1 = sum1; 00333 if (difsum1 > difprec && Int_t(ne1) != ncx1) 00334 { 00335 if (h->GetSumw2N() == 0) 00336 std::cout << " Comp2RefKolmogorov WARNING: Weighted events and no Sumw2 for " 00337 << h->GetName() << std::endl; 00338 else 00339 esum1 = sum1*sum1/w1; //number of equivalent entries 00340 } 00341 // look at second histogram 00342 Double_t difsum2 = (ne2-tsum2)/tsum2; 00343 Double_t esum2 = sum2; 00344 if (difsum2 > difprec && Int_t(ne2) != ncx1) 00345 { 00346 if (ref_->GetSumw2N() == 0) 00347 std::cout << " Comp2RefKolmogorov WARNING: Weighted events and no Sumw2 for " 00348 << ref_->GetName() << std::endl; 00349 else 00350 esum2 = sum2*sum2/w2; //number of equivalent entries 00351 } 00352 00353 Double_t s1 = 1/tsum1; Double_t s2 = 1/tsum2; 00354 00355 // Find largest difference for Kolmogorov Test 00356 Double_t dfmax =0, rsum1 = 0, rsum2 = 0; 00357 00358 // use underflow bin 00359 Int_t first = 0; // 1 00360 // use overflow bin 00361 Int_t last = ncx1+1; // ncx1 00362 for (bin=first;bin<=last;bin++) 00363 { 00364 rsum1 += s1*h->GetBinContent(bin); 00365 rsum2 += s2*ref_->GetBinContent(bin); 00366 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2)); 00367 } 00368 00369 // Get Kolmogorov probability 00370 Double_t z = 0; 00371 if (afunc1) z = dfmax*TMath::Sqrt(esum2); 00372 else if (afunc2) z = dfmax*TMath::Sqrt(esum1); 00373 else z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2)); 00374 00375 // This numerical error condition should never occur: 00376 if (TMath::Abs(rsum1-1) > 0.002) 00377 std::cout << " Comp2RefKolmogorov WARNING: Numerical problems with histogram " 00378 << h->GetName() << std::endl; 00379 if (TMath::Abs(rsum2-1) > 0.002) 00380 std::cout << " Comp2RefKolmogorov WARNING: Numerical problems with histogram " 00381 << ref_->GetName() << std::endl; 00382 00383 return TMath::KolmogorovProb(z); 00384 } 00385 00386 00387 00388 //----------------------------------------------------// 00389 //--------------- ContentsXRange ---------------------// 00390 //----------------------------------------------------// 00391 float ContentsXRange::runTest(const MonitorElement*me) 00392 { 00393 00394 badChannels_.clear(); 00395 00396 if (!me) return -1; 00397 if (!me->getRootObject()) return -1; 00398 TH1* h=0; 00399 00400 if (me->kind()==MonitorElement::DQM_KIND_TH1F ) { 00401 h = me->getTH1F(); 00402 } 00403 else if ( me->kind()==MonitorElement::DQM_KIND_TH1S ) { 00404 h = me->getTH1S(); 00405 } 00406 else { 00407 std::cout<< "ContentsXRange ERROR: ME " << me->getFullname() << " does not contain TH1F/TH1S" << std::endl; 00408 return -1; 00409 } 00410 00411 if (!rangeInitialized_) 00412 { 00413 if ( h->GetXaxis() ) setAllowedXRange(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax()); 00414 else return -1; 00415 } 00416 Int_t ncx = h->GetXaxis()->GetNbins(); 00417 // use underflow bin 00418 Int_t first = 0; // 1 00419 // use overflow bin 00420 Int_t last = ncx+1; // ncx 00421 // all entries 00422 Double_t sum = 0; 00423 // entries outside X-range 00424 Double_t fail = 0; 00425 Int_t bin; 00426 for (bin = first; bin <= last; ++bin) 00427 { 00428 Double_t contents = h->GetBinContent(bin); 00429 float x = h->GetBinCenter(bin); 00430 sum += contents; 00431 if (x < xmin_ || x > xmax_)fail += contents; 00432 } 00433 00434 if(sum==0) return 1; 00435 // return fraction of entries within allowed X-range 00436 return (sum - fail)/sum; 00437 00438 } 00439 00440 //-----------------------------------------------------// 00441 //--------------- ContentsYRange ---------------------// 00442 //----------------------------------------------------// 00443 float ContentsYRange::runTest(const MonitorElement*me) 00444 { 00445 00446 badChannels_.clear(); 00447 00448 if (!me) return -1; 00449 if (!me->getRootObject()) return -1; 00450 TH1* h=0; 00451 00452 if (me->kind()==MonitorElement::DQM_KIND_TH1F) { 00453 h = me->getTH1F(); //access Test histo 00454 } 00455 else if (me->kind()==MonitorElement::DQM_KIND_TH1S) { 00456 h = me->getTH1S(); //access Test histo 00457 } 00458 else { 00459 std::cout<< "ContentsYRange ERROR: ME " << me->getFullname() << " does not contain TH1F/TH1S" << std::endl; 00460 return -1; 00461 } 00462 00463 if (!rangeInitialized_ || !h->GetXaxis()) return 1; // all bins are accepted if no initialization 00464 Int_t ncx = h->GetXaxis()->GetNbins(); 00465 // do NOT use underflow bin 00466 Int_t first = 1; 00467 // do NOT use overflow bin 00468 Int_t last = ncx; 00469 // bins outside Y-range 00470 Int_t fail = 0; 00471 Int_t bin; 00472 00473 if(useEmptyBins_) 00474 { 00475 for (bin = first; bin <= last; ++bin){ 00476 Double_t contents = h->GetBinContent(bin); 00477 bool failure = false; 00478 failure = (contents < ymin_ || contents > ymax_); // allowed y-range: [ymin_, ymax_] 00479 if (failure) { 00480 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin)); 00481 badChannels_.push_back(chan); 00482 ++fail; 00483 } 00484 } 00485 // return fraction of bins that passed test 00486 return 1.*(ncx - fail)/ncx; 00487 } 00488 00489 else 00490 { 00491 for (bin = first; bin <= last; ++bin){ 00492 Double_t contents = h->GetBinContent(bin); 00493 bool failure = false; 00494 if(contents) failure = (contents < ymin_ || contents > ymax_); // allowed y-range: [ymin_, ymax_] 00495 if (failure) ++fail; 00496 } 00497 // return fraction of bins that passed test 00498 return 1.*(ncx - fail)/ncx; 00499 } 00500 //=================== end of ContentsYRange =========// 00501 } 00502 00503 00504 //-----------------------------------------------------// 00505 //------------------ DeadChannel ---------------------// 00506 //----------------------------------------------------// 00507 float DeadChannel::runTest(const MonitorElement*me) 00508 { 00509 badChannels_.clear(); 00510 if (!me) return -1; 00511 if (!me->getRootObject()) return -1; 00512 h1=0; 00513 h2=0;//initialize histogram pointers 00514 00515 //TH1F 00516 if (me->kind()==MonitorElement::DQM_KIND_TH1F) { 00517 h1 = me->getTH1F(); //access Test histo 00518 } 00519 00520 //TH1S 00521 else if (me->kind()==MonitorElement::DQM_KIND_TH1S) { 00522 h1 = me->getTH1S(); //access Test histo 00523 } 00524 00525 //-- TH2F 00526 else if (me->kind()==MonitorElement::DQM_KIND_TH2F){ 00527 h2 = me->getTH2F(); // access Test histo 00528 } 00529 00530 //-- TH2S 00531 else if (me->kind()==MonitorElement::DQM_KIND_TH2S){ 00532 h2 = me->getTH2S(); // access Test histo 00533 } 00534 00535 else { 00536 std::cout<< "DeadChannel ERROR: ME " << me->getFullname() << " does not contain TH1F/TH1S/TH2F/TH1S" << std::endl; 00537 return -1; 00538 } 00539 00540 Int_t fail = 0; // number of failed channels 00541 00542 //--------- do the quality test for 1D histo ---------------// 00543 if(h1 != NULL) 00544 { 00545 if (!rangeInitialized_ || !h1->GetXaxis() ) return 1; // all bins are accepted if no initialization 00546 Int_t ncx = h1->GetXaxis()->GetNbins(); 00547 Int_t first = 1; 00548 Int_t last = ncx; 00549 Int_t bin; 00550 00552 for (bin = first; bin <= last; ++bin) 00553 { 00554 Double_t contents = h1->GetBinContent(bin); 00555 bool failure = false; 00556 failure = contents <= ymin_; // dead channel: equal to or less than ymin_ 00557 if (failure){ 00558 DQMChannel chan(bin, 0, 0, contents, h1->GetBinError(bin)); 00559 badChannels_.push_back(chan); 00560 ++fail; 00561 } 00562 } 00563 //return fraction of alive channels 00564 return 1.*(ncx - fail)/ncx; 00565 } 00566 //----------------------------------------------------------// 00567 00568 //--------- do the quality test for 2D -------------------// 00569 else if (h2 !=NULL ) 00570 { 00571 int ncx = h2->GetXaxis()->GetNbins(); // get X bins 00572 int ncy = h2->GetYaxis()->GetNbins(); // get Y bins 00573 00575 for (int cx = 1; cx <= ncx; ++cx) 00576 { 00577 for (int cy = 1; cy <= ncy; ++cy) 00578 { 00579 Double_t contents = h2->GetBinContent(h2->GetBin(cx, cy)); 00580 bool failure = false; 00581 failure = contents <= ymin_; // dead channel: equal to or less than ymin_ 00582 if (failure){ 00583 DQMChannel chan(cx, cy, 0, contents, h2->GetBinError(h2->GetBin(cx, cy))); 00584 badChannels_.push_back(chan); 00585 ++fail; 00586 } 00587 } 00588 } 00589 //return fraction of alive channels 00590 00591 return 1.*(ncx*ncy - fail) / (ncx*ncy); 00592 } 00593 00594 else {std::cout<< "DeadChannel ERROR: TH1/TH2F are NULL !" << std::endl; return -1;} 00595 } 00596 00597 00598 //-----------------------------------------------------// 00599 //---------------- NoisyChannel ---------------------// 00600 //----------------------------------------------------// 00601 // run the test (result: fraction of channels not appearing noisy or "hot") 00602 // [0, 1] or <0 for failure 00603 float NoisyChannel::runTest(const MonitorElement *me) 00604 { 00605 00606 badChannels_.clear(); 00607 if (!me) return -1; 00608 if (!me->getRootObject()) return -1; 00609 h=0;//initialize histogram pointer 00610 00611 int nbins=0; 00612 //-- TH1F 00613 if (me->kind()==MonitorElement::DQM_KIND_TH1F){ 00614 nbins = me->getTH1F()->GetXaxis()->GetNbins(); 00615 h = me->getTH1F(); // access Test histo 00616 } 00617 //-- TH1S 00618 else if (me->kind()==MonitorElement::DQM_KIND_TH1S){ 00619 nbins = me->getTH1S()->GetXaxis()->GetNbins(); 00620 h = me->getTH1S(); // access Test histo 00621 } 00622 //-- TH2 00623 else if (me->kind()==MonitorElement::DQM_KIND_TH2F){ 00624 nbins = me->getTH2F()->GetXaxis()->GetNbins() * 00625 me->getTH2F()->GetYaxis()->GetNbins(); 00626 h = me->getTH2F(); // access Test histo 00627 } 00628 //-- TH2 00629 else if (me->kind()==MonitorElement::DQM_KIND_TH2S){ 00630 nbins = me->getTH2S()->GetXaxis()->GetNbins() * 00631 me->getTH2S()->GetYaxis()->GetNbins(); 00632 h = me->getTH2S(); // access Test histo 00633 } 00634 else { 00635 std::cout<< "NoisyChannel ERROR: ME " << me->getFullname() << 00636 " does not contain TH1F/TH1S or TH2F/TH2S" << std::endl; 00637 return -1; 00638 } 00639 00640 //-- QUALITY TEST itself 00641 00642 if ( !rangeInitialized_ || !h->GetXaxis() ) return 1; // all channels are accepted if tolerance has not been set 00643 00644 // do NOT use underflow bin 00645 Int_t first = 1; 00646 // do NOT use overflow bin 00647 Int_t last = nbins; 00648 // bins outside Y-range 00649 Int_t fail = 0; 00650 Int_t bin; 00651 for (bin = first; bin <= last; ++bin) 00652 { 00653 Double_t contents = h->GetBinContent(bin); 00654 Double_t average = getAverage(bin, h); 00655 bool failure = false; 00656 if (average != 0) 00657 failure = (((contents-average)/TMath::Abs(average)) > tolerance_); 00658 00659 if (failure) 00660 { 00661 ++fail; 00662 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin)); 00663 badChannels_.push_back(chan); 00664 } 00665 } 00666 00667 // return fraction of bins that passed test 00668 return 1.*(nbins - fail)/nbins; 00669 } 00670 00671 // get average for bin under consideration 00672 // (see description of method setNumNeighbors) 00673 Double_t NoisyChannel::getAverage(int bin, const TH1 *h) const 00674 { 00676 Int_t first = 1; 00678 Int_t ncx = h->GetXaxis()->GetNbins(); 00679 00680 Double_t sum = 0; int bin_low, bin_hi; 00681 for (unsigned i = 1; i <= numNeighbors_; ++i) 00682 { 00684 bin_low = bin-i; bin_hi = bin+i; 00687 00688 while (bin_low < first) // shift bin by +ncx 00689 bin_low = ncx + bin_low; 00690 while (bin_hi > ncx) // shift bin by -ncx 00691 bin_hi = bin_hi - ncx; 00692 00693 sum += h->GetBinContent(bin_low) + h->GetBinContent(bin_hi); 00694 } 00695 00697 return sum/(numNeighbors_ * 2); 00698 } 00699 00700 00701 //-----------------------------------------------------------// 00702 //---------------- ContentsWithinExpected ---------------------// 00703 //-----------------------------------------------------------// 00704 // run the test (result: fraction of channels that passed test); 00705 // [0, 1] or <0 for failure 00706 float ContentsWithinExpected::runTest(const MonitorElement*me) 00707 { 00708 badChannels_.clear(); 00709 if (!me) return -1; 00710 if (!me->getRootObject()) return -1; 00711 h=0;//initialize histogram pointer 00712 00713 int ncx; 00714 int ncy; 00715 00716 if(useEmptyBins_) 00717 { 00718 //-- TH2 00719 if (me->kind()==MonitorElement::DQM_KIND_TH2F){ 00720 ncx = me->getTH2F()->GetXaxis()->GetNbins(); 00721 ncy = me->getTH2F()->GetYaxis()->GetNbins(); 00722 h = me->getTH2F(); // access Test histo 00723 } 00724 00725 //-- TH2S 00726 else if (me->kind()==MonitorElement::DQM_KIND_TH2S){ 00727 ncx = me->getTH2S()->GetXaxis()->GetNbins(); 00728 ncy = me->getTH2S()->GetYaxis()->GetNbins(); 00729 h = me->getTH2S(); // access Test histo 00730 } 00731 00732 //-- TProfile 00733 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE){ 00734 ncx = me->getTProfile()->GetXaxis()->GetNbins(); 00735 ncy = 1; 00736 h = me->getTProfile(); // access Test histo 00737 } 00738 00739 //-- TProfile2D 00740 else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE2D){ 00741 ncx = me->getTProfile2D()->GetXaxis()->GetNbins(); 00742 ncy = me->getTProfile2D()->GetYaxis()->GetNbins(); 00743 h = me->getTProfile2D(); // access Test histo 00744 } 00745 00746 else{ 00747 std::cout<< " ContentsWithinExpected ERROR: ME does not contain TH2F/TH2S/TPROFILE/TPROFILE2D" << std::endl; 00748 return -1; 00749 } 00750 00751 int nsum = 0; 00752 float sum = 0.0; 00753 float average = 0.0; 00754 00755 if (checkMeanTolerance_){ // calculate average value of all bin contents 00756 00757 for (int cx = 1; cx <= ncx; ++cx) 00758 { 00759 for (int cy = 1; cy <= ncy; ++cy) 00760 { 00761 if (me->kind() == MonitorElement::DQM_KIND_TH2F) 00762 { 00763 sum += h->GetBinContent(h->GetBin(cx, cy)); 00764 ++nsum; 00765 } 00766 else if (me->kind() == MonitorElement::DQM_KIND_TH2S) 00767 { 00768 sum += h->GetBinContent(h->GetBin(cx, cy)); 00769 ++nsum; 00770 } 00771 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE) 00772 { 00773 if (me->getTProfile()->GetBinEntries(h->GetBin(cx)) >= minEntries_/(ncx)) 00774 { 00775 sum += h->GetBinContent(h->GetBin(cx)); 00776 ++nsum; 00777 } 00778 } 00779 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D) 00780 { 00781 if (me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) >= minEntries_/(ncx*ncy)) 00782 { 00783 sum += h->GetBinContent(h->GetBin(cx, cy)); 00784 ++nsum; 00785 } 00786 } 00787 } 00788 } 00789 00790 if (nsum > 0) average = sum/nsum; 00791 00792 } // calculate average value of all bin contents 00793 00794 int fail = 0; 00795 00796 for (int cx = 1; cx <= ncx; ++cx) 00797 { 00798 for (int cy = 1; cy <= ncy; ++cy) 00799 { 00800 bool failMean = false; 00801 bool failRMS = false; 00802 bool failMeanTolerance = false; 00803 00804 if (me->kind() == MonitorElement::DQM_KIND_TPROFILE && me->getTProfile()->GetBinEntries(h->GetBin(cx)) < minEntries_/(ncx)) continue; 00805 00806 if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D && me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) < minEntries_/(ncx*ncy)) continue; 00807 00808 if (checkMean_) 00809 { 00810 float mean = h->GetBinContent(h->GetBin(cx, cy)); 00811 failMean = (mean < minMean_ || mean > maxMean_); 00812 } 00813 00814 if (checkRMS_) 00815 { 00816 float rms = h->GetBinError(h->GetBin(cx, cy)); 00817 failRMS = (rms < minRMS_ || rms > maxRMS_); 00818 } 00819 00820 if (checkMeanTolerance_) 00821 { 00822 float mean = h->GetBinContent(h->GetBin(cx, cy)); 00823 failMeanTolerance = (TMath::Abs(mean - average) > toleranceMean_*TMath::Abs(average)); 00824 } 00825 00826 if (failMean || failRMS || failMeanTolerance) 00827 { 00828 00829 if (me->kind() == MonitorElement::DQM_KIND_TH2F) { 00830 DQMChannel chan(cx, cy, 0, 00831 h->GetBinContent(h->GetBin(cx, cy)), 00832 h->GetBinError(h->GetBin(cx, cy))); 00833 badChannels_.push_back(chan); 00834 } 00835 else if (me->kind() == MonitorElement::DQM_KIND_TH2S) { 00836 DQMChannel chan(cx, cy, 0, 00837 h->GetBinContent(h->GetBin(cx, cy)), 00838 h->GetBinError(h->GetBin(cx, cy))); 00839 badChannels_.push_back(chan); 00840 } 00841 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE) { 00842 DQMChannel chan(cx, cy, int(me->getTProfile()->GetBinEntries(h->GetBin(cx))), 00843 0, 00844 h->GetBinError(h->GetBin(cx))); 00845 badChannels_.push_back(chan); 00846 } 00847 else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D) { 00848 DQMChannel chan(cx, cy, int(me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy))), 00849 h->GetBinContent(h->GetBin(cx, cy)), 00850 h->GetBinError(h->GetBin(cx, cy))); 00851 badChannels_.push_back(chan); 00852 } 00853 ++fail; 00854 } 00855 } 00856 } 00857 00858 return 1.*(ncx*ncy - fail)/(ncx*ncy); 00859 } 00860 00861 else 00862 { 00863 if (me->kind()==MonitorElement::DQM_KIND_TH2F){ 00864 ncx = me->getTH2F()->GetXaxis()->GetNbins(); 00865 ncy = me->getTH2F()->GetYaxis()->GetNbins(); 00866 h = me->getTH2F(); // access Test histo 00867 } 00868 else if (me->kind()==MonitorElement::DQM_KIND_TH2S){ 00869 ncx = me->getTH2S()->GetXaxis()->GetNbins(); 00870 ncy = me->getTH2S()->GetYaxis()->GetNbins(); 00871 h = me->getTH2S(); // access Test histo 00872 } 00873 else { 00874 std::cout<< " ContentsWithinExpected AS! ERROR: ME does not contain TH2F/TH2S" << std::endl; 00875 return -1; 00876 } 00877 00878 // if (!rangeInitialized_) return 0; // all accepted if no initialization 00879 int fail = 0; 00880 for (int cx = 1; cx <= ncx; ++cx) 00881 { 00882 for (int cy = 1; cy <= ncy; ++cy) 00883 { 00884 bool failure = false; 00885 float Content = h->GetBinContent(h->GetBin(cx, cy)); 00886 if(Content) failure = (Content < minMean_ || Content > maxMean_); 00887 if (failure) ++fail; 00888 } 00889 } 00890 00891 return 1.*(ncx*ncy-fail)/(ncx*ncy); 00892 } 00893 00894 00895 } 00896 00897 // check that allowed range is logical 00898 void 00899 ContentsWithinExpected::checkRange(const float xmin, const float xmax) 00900 { 00901 if (xmin < xmax) 00902 validMethod_ = true; 00903 else 00904 { 00905 std::cerr << " *** Error! Illogical range: (" << xmin << ", " << xmax 00906 << ") in algorithm " << getAlgoName() << std::endl; 00907 validMethod_ = false; 00908 } 00909 } 00910 00911 //----------------------------------------------------------------// 00912 //-------------------- MeanWithinExpected ---------------------// 00913 //---------------------------------------------------------------// 00914 // run the test; 00915 // (a) if useRange is called: 1 if mean within allowed range, 0 otherwise 00916 // (b) is useRMS or useSigma is called: result is the probability 00917 // Prob(chi^2, ndof=1) that the mean of histogram will be deviated by more than 00918 // +/- delta from <expected_mean>, where delta = mean - <expected_mean>, and 00919 // chi^2 = (delta/sigma)^2. sigma is the RMS of the histogram ("useRMS") or 00920 // <expected_sigma> ("useSigma") 00921 // e.g. for delta = 1, Prob = 31.7% 00922 // for delta = 2, Prob = 4.55% 00923 // (returns result in [0, 1] or <0 for failure) 00924 float MeanWithinExpected::runTest(const MonitorElement *me ) 00925 { 00926 if (!me) return -1; 00927 if (!me->getRootObject()) return -1; 00928 TH1* h=0; 00929 00930 if (me->kind()==MonitorElement::DQM_KIND_TH1F) { 00931 h = me->getTH1F(); //access Test histo 00932 } 00933 else if (me->kind()==MonitorElement::DQM_KIND_TH1S) { 00934 h = me->getTH1S(); //access Test histo 00935 } 00936 else { 00937 std::cout<< " MeanWithinExpected ERROR: ME " << me->getFullname() << " does not contain TH1F/TH1S" << std::endl; 00938 return -1; 00939 } 00940 00941 if (isInvalid()) return -1; 00942 00943 if (useRange_) return doRangeTest(h); 00944 00945 if (useSigma_) return doGaussTest(h, sigma_); 00946 00947 if (useRMS_) return doGaussTest(h, h->GetRMS()); 00948 00949 // we should never reach this point; 00950 return -99; 00951 } 00952 00953 // test assuming mean value is quantity with gaussian errors 00954 float MeanWithinExpected::doGaussTest(const TH1 *h, float sigma) 00955 { 00956 float chi = (h->GetMean() - expMean_)/sigma; 00957 return TMath::Prob(chi*chi, 1); 00958 } 00959 00960 // test for useRange_ = true case 00961 float MeanWithinExpected::doRangeTest(const TH1 *h) 00962 { 00963 float mean = h->GetMean(); 00964 if (mean <= xmax_ && mean >= xmin_) return 1; 00965 else return 0; 00966 } 00967 00968 // check that exp_sigma_ is non-zero 00969 void 00970 MeanWithinExpected::checkSigma(void) 00971 { 00972 if (sigma_ != 0) validMethod_ = true; 00973 else 00974 { 00975 std::cout << " *** Error! Expected sigma = " << sigma_ << " in algorithm " << getAlgoName() << std::endl; 00976 validMethod_ = false; 00977 } 00978 } 00979 00980 // check that allowed range is logical 00981 void MeanWithinExpected::checkRange(void) 00982 { 00983 if (xmin_ < xmax_) validMethod_ = true; 00984 else 00985 { 00986 std::cout << " *** Error! Illogical range: (" << xmin_ << ", " << xmax_ 00987 << ") in algorithm " << getAlgoName() << std::endl; 00988 validMethod_ = false; 00989 } 00990 } 00991 00992 // true if test cannot run 00993 bool MeanWithinExpected::isInvalid(void) 00994 { 00995 // if useRange_ = true, test does not need a "expected mean value" 00996 if (useRange_) return !validMethod_; // set by checkRange() 00997 00998 // otherwise (useSigma_ or useRMS_ case), we also need to check 00999 // if "expected mean value" has been set 01000 return !validMethod_ // set by useRMS() or checkSigma() 01001 || !validExpMean_; // set by setExpectedMean() 01002 01003 } 01004 01005 01006 01007 // 01008 // @brief 01009 // Rational approximation for erfc(rdX) (Abramowitz & Stegun, Sec. 7.1.26) 01010 // Fifth order approximation. | error| <= 1.5e-7 for all rdX 01011 // 01012 // @param rdX 01013 // Significance value 01014 // 01015 // @return 01016 // Probability 01017 // 01018 // double edm::qtests::fits::erfc(const double &rdX) 01019 // { 01020 // const double dP = 0.3275911; 01021 // const double dA1 = 0.254829592; 01022 // const double dA2 = -0.284496736; 01023 // const double dA3 = 1.421413741; 01024 // const double dA4 = -1.453152027; 01025 // const double dA5 = 1.061405429; 01026 // const double dT = 1.0 / (1.0 + dP * rdX); 01027 // return (dA1 + (dA2 + (dA3 + (dA4 + dA5 * dT) * dT) * dT) * dT) * exp(-rdX * rdX); 01028 // } 01029 // 01030 01031 // //----------------------------------------------------------------// 01032 // //-------------------- MostProbableBase ------------------------// 01033 // //---------------------------------------------------------------// 01034 // // --[ Fit: Base - MostProbableBase ] 01035 // MostProbableBase::MostProbableBase(const std::string &name) 01036 // : SimpleTest(name), 01037 // dMostProbable_(0), 01038 // dSigma_(0), 01039 // dXMin_(0), 01040 // dXMax_(0) 01041 // {} 01042 // 01043 // // 01044 // // @brief 01045 // // Run QTest 01046 // // 01047 // // @param poPLOT 01048 // // See Interface 01049 // // 01050 // // @return 01051 // // See Interface 01052 // // 01053 // float MostProbableBase::runTest(const MonitorElement *me) 01054 // { 01055 // float dResult = -1; 01056 // 01057 // if (me->kind()!=MonitorElement::DQM_KIND_TH1F) { 01058 // std::cout<< " MostProbableBase ERROR: ME does not contain TH1F" << std::endl; 01059 // return -1;} 01060 // 01061 // poPLOT = me->getTH1F(); //access Test histo 01062 // if (!poPLOT) return -1; 01063 // 01064 // 01065 // if (poPLOT && !isInvalid()) 01066 // { 01067 // // It is childrens responsibility to implement and actually fit Histogram. 01068 // // Constness should be removed since TH1::Fit(...) method is declared as 01069 // // non const. 01070 // if (TH1F *const poPlot = const_cast<TH1F *const>(poPLOT)) 01071 // dResult = fit(poPlot); 01072 // } 01073 // 01074 // return dResult; 01075 // } 01076 // 01077 // // 01078 // // @brief 01079 // // Check if given QTest is Invalid 01080 // // 01081 // // @return 01082 // // See Interface 01083 // // 01084 // bool MostProbableBase::isInvalid(void) 01085 // { 01086 // return !(dMostProbable_ > dXMin_ 01087 // && dMostProbable_ < dXMax_ 01088 // && dSigma_ > 0); 01089 // } 01090 // 01091 // double MostProbableBase::compareMostProbables(const double &rdMP_FIT, const double &rdSIGMA_FIT) const 01092 // { 01093 // double dDeltaMP = rdMP_FIT - dMostProbable_; 01094 // if (dDeltaMP < 0) 01095 // dDeltaMP = -dDeltaMP; 01096 // 01097 // return (dDeltaMP / dSigma_ < 2 // Check Deviation 01098 // ? edm::qtests::fits::erfc((dDeltaMP / sqrt(rdSIGMA_FIT * rdSIGMA_FIT + dSigma_ * dSigma_))) / sqrt(2.0) 01099 // : 0); 01100 // } 01101 // 01102 // 01103 // // --[ Fit: Landau ]----------------------------------------------------------- 01104 // MostProbableLandau::MostProbableLandau(const std::string &name) 01105 // : MostProbableBase(name), 01106 // dNormalization_(0) 01107 // { 01108 // setMinimumEntries(50); 01109 // setAlgoName(getAlgoName()); 01110 // } 01111 // 01112 // // 01113 // // @brief 01114 // // Perform Landau Fit 01115 // // 01116 // // @param poPlot 01117 // // See Interface 01118 // // 01119 // // @return 01120 // // See Interface 01121 // // 01122 // float MostProbableLandau::fit(TH1F *const poPlot) 01123 // { 01124 // double dResult = -1; 01125 // 01126 // // Create Fit Function 01127 // TF1 *poFFit = new TF1("Landau", "landau", getXMin(), getXMax()); 01128 // 01129 // // Fit Parameters: 01130 // // [0] Normalisation coefficient. 01131 // // [1] Most probable value. 01132 // // [2] Lambda in most books (the width of the distribution) 01133 // poFFit->SetParameters(dNormalization_, getMostProbable(), getSigma()); 01134 // 01135 // // Fit 01136 // if (!poPlot->Fit(poFFit, "RB0")) 01137 // { 01138 // // Obtain Fit Parameters: We are interested in Most Probable and Sigma so far. 01139 // const double dMP_FIT = poFFit->GetParameter(1); 01140 // const double dSIGMA_FIT = poFFit->GetParameter(2); 01141 // 01142 // // Compare gotten values with expected ones. 01143 // dResult = compareMostProbables(dMP_FIT, dSIGMA_FIT); 01144 // } 01145 // 01146 // return dResult; 01147 // } 01148 // 01149 // 01150 // 01151 // 01152 // 01153 // 01154 // 01155 // //----------------------------------------------------------------// 01156 // //-------------------- AllContentWithinFixedRange -------------// 01157 // //---------------------------------------------------------------// 01158 // 01159 // float AllContentWithinFixedRange::runTest(const MonitorElement*me) 01160 // { 01161 // if (!me) return -1; 01162 // 01163 // if (me->kind()!=MonitorElement::DQM_KIND_TH1F) { 01164 // std::cout<< " AllContentWithinFixedRange ERROR: ME " << me->getFullname() << " does not contain TH1F" << std::endl; 01165 // return -1;} 01166 // 01167 // histogram = me->getTH1F(); //access Test histo 01168 // if (!histogram) return -1; 01169 // 01170 // //double x, y, z; 01171 // set_x_min( 6.0 ); 01172 // set_x_max( 9.0 ); 01173 // set_epsilon_max( 0.1 ); 01174 // set_S_fail( 5.0 ); 01175 // set_S_pass( 5.0 ); 01176 // 01177 // /*--------------------------------------------------------------------------+ 01178 // | Input to this function | 01179 // +--------------------------------------------------------------------------+ 01180 // |TH1F* histogram, : histogram to be compared with Rule | 01181 // |double x_min, : x range (low). Note low edge <= bin < high edge | 01182 // |double x_max, : x range (high). Note low edge <= bin < high edge | 01183 // |double epsilon_max, : maximum allowed failure rate fraction | 01184 // |double S_fail, : required Statistical Significance to fail rule | 01185 // |double S_pass, : required Significance to pass rule | 01186 // |double* epsilon_obs : uninitialised observed failure rate fraction | 01187 // |double* S_fail_obs : uninitialised Significance of failure | 01188 // |double* S_pass_obs : uninitialised Significance of Success | 01189 // +--------------------------------------------------------------------------+ 01190 // | Result values for this function | 01191 // +--------------------------------------------------------------------------+ 01192 // |int result : "0" = "Passed Rule & is statistically significant"| 01193 // | "1" = "Failed Rule & is statistically significant"| 01194 // | "2" = "Passed Rule & not stat. significant" | 01195 // | "3" = "Failed Rule & not stat. significant" | 01196 // | "4" = "zero histo entries, can not evaluate Rule" | 01197 // | "5" = "Input invalid, can not evaluate Rule" | 01198 // |double* epsilon_obs : the observed failure rate frac. from the histogram| 01199 // |double* S_fail_obs : the observed Significance of failure | 01200 // |double* S_pass_obs : the observed Significance of Success | 01201 // +--------------------------------------------------------------------------+ 01202 // | Author: Richard Cavanaugh, University of Florida | 01203 // | email: Richard.Cavanaugh@cern.ch | 01204 // | Creation Date: 08.July.2005 | 01205 // | Last Modified: 16.Jan.2006 | 01206 // | Comments: | 01207 // | 11.July.2005 - moved the part which calculates the statistical | 01208 // | significance of the result into a separate function | 01209 // +--------------------------------------------------------------------------*/ 01210 // epsilon_obs = 0.0; 01211 // S_fail_obs = 0.0; 01212 // S_pass_obs = 0.0; 01213 // 01214 // //-----------Perform Quality Checks on Input------------- 01215 // if (!histogram) {result = 5; return 0.0;}//exit if histo does not exist 01216 // TAxis *xAxis = histogram -> GetXaxis(); //retrieve x-axis information 01217 // if (x_min < xAxis -> GetXmin() || xAxis -> GetXmax() < x_max) 01218 // {result = 5; return 0.0;}//exit if x range not in hist range 01219 // if (epsilon_max <= 0.0 || epsilon_max >= 1.0) 01220 // {result = 5; return 0.0;}//exit if epsilon_max not in (0,1) 01221 // if (S_fail < 0) {result = 5; return 0.0;}//exit if Significance < 0 01222 // if (S_pass < 0) {result = 5; return 0.0;}//exit if Significance < 0 01223 // S_fail_obs = 0.0; S_pass_obs = 0.0; //initialise Sig return values 01224 // int Nentries = (int) histogram -> GetEntries(); 01225 // if (Nentries < 1){result = 4; return 0.0;}//exit if histo has 0 entries 01226 // 01227 // //-----------Find number of successes and failures------------- 01228 // int low_bin, high_bin; //convert x range to bin range 01229 // if (x_min != x_max) //Note: x in [low_bin, high_bin) 01230 // { //Or: x in [0,high_bin) && 01231 // // [low_bin, max_bin] 01232 // low_bin = (int)(histogram -> GetNbinsX() / 01233 // (xAxis -> GetXmax() - xAxis -> GetXmin()) * 01234 // (x_min - xAxis -> GetXmin())) + 1; 01235 // high_bin = (int)(histogram -> GetNbinsX() / 01236 // (xAxis -> GetXmax() - xAxis -> GetXmin()) * 01237 // (x_max - xAxis -> GetXmin())) + 1; 01238 // } 01239 // else //convert x point to particular bin 01240 // { 01241 // low_bin = high_bin = (int)(histogram -> GetNbinsX() / 01242 // (xAxis -> GetXmax() - xAxis -> GetXmin()) * 01243 // (x_min - xAxis -> GetXmin())) + 1; 01244 // } 01245 // int Nsuccesses = 0; 01246 // if (low_bin <= high_bin) //count number of entries 01247 // for (int i = low_bin; i <= high_bin; i++) //in bin range 01248 // Nsuccesses += (int) histogram -> GetBinContent(i); 01249 // else //include wrap-around case 01250 // { 01251 // for (int i = 0; i <= high_bin; i++) 01252 // Nsuccesses += (int) histogram -> GetBinContent(i); 01253 // for (int i = low_bin; i <= histogram -> GetNbinsX(); i++) 01254 // Nsuccesses += (int) histogram -> GetBinContent(i); 01255 // } 01256 // int Nfailures = Nentries - Nsuccesses; 01257 // double Nepsilon_max = (double)Nentries * epsilon_max; 01258 // epsilon_obs = (double)Nfailures / (double)Nentries; 01259 // 01260 // //-----------Calculate Statistical Significance------------- 01261 // BinLogLikelihoodRatio(Nentries,Nfailures,epsilon_max,&S_fail_obs,&S_pass_obs); 01262 // if (Nfailures > Nepsilon_max) 01263 // { 01264 // if (S_fail_obs > S_fail) 01265 // {result = 1; return 0.0;} //exit if statistically fails rule 01266 // else 01267 // {result = 3; return 0.0;} //exit if non-stat significant result 01268 // } 01269 // else 01270 // { 01271 // if (S_pass_obs > S_pass) 01272 // {result = 0; return 1.0;} //exit if statistically passes rule 01273 // else 01274 // {result = 2; return 0.0;} //exit if non-stat significant result 01275 // } 01276 // } 01277 // 01278 // 01279 // //----------------------------------------------------------------// 01280 // //-------------------- AllContentWithinFixedRange -------------// 01281 // //---------------------------------------------------------------// 01282 // float AllContentWithinFloatingRange::runTest(const MonitorElement*me) 01283 // { 01284 // if (!me) return -1; 01285 // 01286 // if (me->kind()!=MonitorElement::DQM_KIND_TH1F) { 01287 // std::cout<< " AllContentWithinFloatingRange ERROR: ME " << me->getFullname() << " does not contain TH1F" << std::endl; 01288 // return -1;} 01289 // 01290 // histogram = me->getTH1F(); //access Test histo 01291 // if (!histogram) return -1; 01292 // 01293 // //double x, y, z; 01294 // set_Nrange( 1 ); 01295 // set_epsilon_max( 0.1 ); 01296 // set_S_fail( 5.0 ); 01297 // set_S_pass( 5.0 ); 01298 // 01299 // /*--------------------------------------------------------------------------+ 01300 // | Input to this function | 01301 // +--------------------------------------------------------------------------+ 01302 // |TH1F* histogram, : histogram to be compared with Rule | 01303 // |int Nrange, : number of contiguous bins holding entries | 01304 // |double epsilon_max, : maximum allowed failure rate fraction | 01305 // |double S_fail, : required Statistical Significance to fail rule | 01306 // |double S_pass, : required Significance to pass rule | 01307 // |double* epsilon_obs : uninitialised observed failure rate fraction | 01308 // |double* S_fail_obs : uninitialised Significance of failure | 01309 // |double* S_pass_obs : uninitialised Significance of Success | 01310 // +--------------------------------------------------------------------------+ 01311 // | Result values for this function | 01312 // +--------------------------------------------------------------------------+ 01313 // |int result : "0" = "Passed Rule & is statistically significant"| 01314 // | "1" = "Failed Rule & is statistically significant"| 01315 // | "2" = "Passed Rule & not stat. significant" | 01316 // | "3" = "Failed Rule & not stat. significant" | 01317 // | "4" = "zero histo entries, can not evaluate Rule" | 01318 // | "5" = "Input invalid, can not evaluate Rule" | 01319 // |double* epsilon_obs : the observed failure rate frac. from the histogram| 01320 // |double* S_fail_obs : the observed Significance of failure | 01321 // |double* S_pass_obs : the observed Significance of Success | 01322 // +--------------------------------------------------------------------------+ 01323 // | Author: Richard Cavanaugh, University of Florida | 01324 // | email: Richard.Cavanaugh@cern.ch | 01325 // | Creation Date: 07.Jan.2006 | 01326 // | Last Modified: 16.Jan.2006 | 01327 // | Comments: | 01328 // +--------------------------------------------------------------------------*/ 01329 // epsilon_obs = 0.0; 01330 // S_fail_obs = 0.0; 01331 // S_pass_obs = 0.0; 01332 // 01333 // //-----------Perform Quality Checks on Input------------- 01334 // if (!histogram) {result = 5; return 0.0;}//exit if histo does not exist 01335 // int Nbins = histogram -> GetNbinsX(); 01336 // if (Nrange > Nbins){result = 5; return 0.0;}//exit if Nrange > # bins in histo 01337 // if (epsilon_max <= 0.0 || epsilon_max >= 1.0) 01338 // {result = 5; return 0.0;}//exit if epsilon_max not in (0,1) 01339 // if (S_fail < 0) {result = 5; return 0.0;}//exit if Significance < 0 01340 // if (S_pass < 0) {result = 5; return 0.0;}//exit if Significance < 0 01341 // S_fail_obs = 0.0; S_pass_obs = 0.0; //initialise Sig return values 01342 // int Nentries = (int) histogram -> GetEntries(); 01343 // if (Nentries < 1) {result = 4; return 0.0;}//exit if histo has 0 entries 01344 // 01345 // //-----------Find number of successes and failures------------- 01346 // int Nsuccesses = 0, EntriesInCurrentRange = 0; 01347 // for (int i = 1; i <= Nrange; i++) //initialise Nsuccesses 01348 // { //histos start with bin index 1 (not 0) 01349 // Nsuccesses += (int) histogram -> GetBinContent(i); 01350 // } 01351 // EntriesInCurrentRange = Nsuccesses; 01352 // for (int i = Nrange + 1; i <= Nbins; i++) //optimise floating bin range 01353 // { //slide range by adding new high side bin & subtracting old low side bin 01354 // EntriesInCurrentRange += 01355 // (int) (histogram -> GetBinContent(i) - 01356 // histogram -> GetBinContent(i - Nrange)); 01357 // if (EntriesInCurrentRange > Nsuccesses) 01358 // Nsuccesses = EntriesInCurrentRange; 01359 // } 01360 // for (int i = 1; i < Nrange; i++) //include possiblity of wrap-around 01361 // { //slide range by adding new low side bin & subtracting old high side bin 01362 // EntriesInCurrentRange += 01363 // (int) (histogram -> GetBinContent(i) - 01364 // histogram -> GetBinContent(Nbins - (Nrange - i))); 01365 // if (EntriesInCurrentRange > Nsuccesses) 01366 // Nsuccesses = EntriesInCurrentRange; 01367 // } 01368 // int Nfailures = Nentries - Nsuccesses; 01369 // double Nepsilon_max = (double)Nentries * epsilon_max; 01370 // epsilon_obs = (double)Nfailures / (double)Nentries; 01371 // 01372 // //-----------Calculate Statistical Significance------------- 01373 // BinLogLikelihoodRatio(Nentries,Nfailures,epsilon_max,&S_fail_obs,&S_pass_obs); 01374 // if (Nfailures > Nepsilon_max) 01375 // { 01376 // if (S_fail_obs > S_fail) 01377 // {result = 1; return 0.0;} //exit if statistically fails rule 01378 // else 01379 // {result = 3; return 0.0;} //exit if non-stat significant result 01380 // } 01381 // else 01382 // { 01383 // if (S_pass_obs > S_pass) 01384 // {result = 0; return 1.0;} //exit if statistically passes rule 01385 // else 01386 // {result = 2; return 0.0;} //exit if non-stat significant result 01387 // } 01388 // } 01389 // 01390 // 01391 // 01392 // 01393 // 01394 // //----------------------------------------------------------------// 01395 // //-------------------- FlatOccupancy1d ------------------------// 01396 // //---------------------------------------------------------------// 01397 // 01398 // #if 0 01399 // float FlatOccupancy1d::runTest(const MonitorElement*me) 01400 // { 01401 // 01402 // if (!me) return -1; 01403 // 01404 // if (me->kind()!=MonitorElement::DQM_KIND_TH1F) { 01405 // std::cout<< " FlatOccupancy1d ERROR: ME " << me->getFullname() << " does not contain TH1F" << std::endl; 01406 // return -1;} 01407 // 01408 // histogram = me->getTH1F(); //access Test histo 01409 // if (!histogram) return -1; 01410 // 01411 // 01412 // /*--------------------------------------------------------------------------+ 01413 // | Input to this function | 01414 // +--------------------------------------------------------------------------+ 01415 // |TH1F* histogram, : histogram to be compared with Rule | 01416 // |int* mask : bit mask which excludes bins from consideration | 01417 // |double epsilon_min, : minimum tolerance (fraction of line) | 01418 // |double epsilon_max, : maximum tolerance (fraction of line) | 01419 // |double S_fail, : required Statistical Significance to fail rule | 01420 // |double S_pass, : required Significance to pass rule | 01421 // |double[2][] FailedBins: uninit. vector of bins out of tolerance | 01422 // +--------------------------------------------------------------------------+ 01423 // | Result values for this function | 01424 // +--------------------------------------------------------------------------+ 01425 // |int result : "0" = "Passed Rule & is statistically significant"| 01426 // | "1" = "Failed Rule & is statistically significant"| 01427 // | "2" = "Passed Rule & not stat. significant" | 01428 // | "3" = "Failed Rule & not stat. significant" | 01429 // | "4" = "zero histo entries, can not evaluate Rule" | 01430 // | "5" = "Input invalid, can not evaluate Rule" | 01431 // |double[2][] FailedBins: the obs. vector of bins out of tolerance | 01432 // +--------------------------------------------------------------------------+ 01433 // | Author: Richard Cavanaugh, University of Florida | 01434 // | email: Richard.Cavanaugh@cern.ch | 01435 // | Creation Date: 07.Jan.2006 | 01436 // | Last Modified: 16.Jan.2006 | 01437 // | Comments: | 01438 // +--------------------------------------------------------------------------*/ 01439 // double *S_fail_obs; 01440 // double *S_pass_obs; 01441 // double dummy1, dummy2; 01442 // S_fail_obs = &dummy1; 01443 // S_pass_obs = &dummy2; 01444 // *S_fail_obs = 0.0; 01445 // *S_pass_obs = 0.0; 01446 // Nbins = histogram -> GetNbinsX(); 01447 // 01448 // //-----------Perform Quality Checks on Input------------- 01449 // if (!histogram) {result = 5; return 0.0;}//exit if histo does not exist 01450 // if (epsilon_min <= 0.0 || epsilon_min >= 1.0) 01451 // {result = 5; return 0.0;}//exit if epsilon_min not in (0,1) 01452 // if (epsilon_max <= 0.0 || epsilon_max >= 1.0) 01453 // {result = 5; return 0.0;}//exit if epsilon_max not in (0,1) 01454 // if (epsilon_max < epsilon_min) 01455 // {result = 5; return 0.0;}//exit if max < min 01456 // if (S_fail < 0) {result = 5; return 0.0;}//exit if Significance < 0 01457 // if (S_pass < 0) {result = 5; return 0.0;}//exit if Significance < 0 01458 // int Nentries = (int) histogram -> GetEntries(); 01459 // if (Nentries < 1){result = 4; return 0.0;}//exit if histo has 0 entries 01460 // 01461 // //-----------Find best value for occupancy b---------------- 01462 // double b = 0.0; 01463 // int NusedBins = 0; 01464 // for (int i = 1; i <= Nbins; i++) //loop over all bins 01465 // { 01466 // if (ExclusionMask[i-1] != 1) //do not check if bin excluded (=1) 01467 // { 01468 // b += histogram -> GetBinContent(i); 01469 // NusedBins += 1; //keep track of # checked bins 01470 // } 01471 // } 01472 // b *= 1.0 / (double) NusedBins; //average for poisson stats 01473 // 01474 // //-----------Calculate Statistical Significance------------- 01475 // double S_pass_obs_min = 0.0, S_fail_obs_max = 0.0; 01476 // // allocate Nbins of memory for FailedBins 01477 // for (int i = 0; i <= 1; i++) FailedBins[i] = new double [Nbins]; 01478 // // remember to delete[] FailedBins[0] and delete[] FailedBins[1] 01479 // for (int i = 1; i <= Nbins; i++) //loop (again) over all bins 01480 // { 01481 // FailedBins[0][i-1] = 0.0; //initialise obs fraction 01482 // FailedBins[1][i-1] = 0.0; //initialise obs significance 01483 // if (ExclusionMask[i-1] != 1) //do not check if bin excluded (=1) 01484 // { 01485 // //determine significance for bin to fail or pass, given occupancy 01486 // //hypothesis b with tolerance epsilon_min < b < epsilon_max 01487 // PoissionLogLikelihoodRatio(histogram->GetBinContent(i), 01488 // b, 01489 // epsilon_min, epsilon_max, 01490 // S_fail_obs, S_pass_obs); 01491 // //set S_fail_obs to maximum over all non-excluded bins 01492 // //set S_pass_obs to non-zero minimum over all non-excluded bins 01493 // if (S_fail_obs_max == 0.0 && *S_pass_obs > 0.0) 01494 // S_pass_obs_min = *S_pass_obs; //init to first non-zero value 01495 // if (*S_fail_obs > S_fail_obs_max) S_fail_obs_max = *S_fail_obs; 01496 // if (*S_pass_obs < S_pass_obs_min) S_pass_obs_min = *S_pass_obs; 01497 // //set FailedBins[0][] to fraction away from fitted line b 01498 // //set to zero if bin is within tolerance (via initialisation) 01499 // if (*S_fail_obs > 0) FailedBins[0][i-1] = 01500 // histogram->GetBinContent(i)/b - 1.0; 01501 // //set FailedBins[1][] to observed significance of failure 01502 // //set to zero if bin is within tolerance (via initialisation) 01503 // if (*S_fail_obs > 0) FailedBins[1][i-1] = *S_fail_obs; 01504 // } 01505 // } 01506 // *S_fail_obs = S_fail_obs_max; 01507 // *S_pass_obs = S_pass_obs_min; 01508 // if (*S_fail_obs > 0.0) 01509 // { 01510 // if (*S_fail_obs > S_fail) 01511 // {result = 1; return 0.0;} //exit if statistically fails rule 01512 // else 01513 // {result = 3; return 0.0;} //exit if non-stat significant result 01514 // } 01515 // else 01516 // { 01517 // if (*S_pass_obs > S_pass) 01518 // {result = 0; return 1.0;} //exit if statistically passes rule 01519 // else 01520 // {result = 2; return 0.0;} //exit if non-stat significant result 01521 // } 01522 // } 01523 // #endif 01524 // 01525 // 01526 // 01527 // 01528 // float FixedFlatOccupancy1d::runTest(const MonitorElement *me) 01529 // { 01530 // if (!me) return -1; 01531 // 01532 // if (me->kind()!=MonitorElement::DQM_KIND_TH1F) { 01533 // std::cout<< " FixedFlatOccupancy1d ERROR: ME " << me->getFullname() << " does not contain TH1F" << std::endl; 01534 // return -1;} 01535 // 01536 // histogram = me->getTH1F(); //access Test histo 01537 // if (!histogram) return -1; 01538 // 01539 // 01540 // set_Occupancy( 1.0 ); 01541 // double mask[10] = {1,0,0,0,1,1,1,1,1,1}; 01542 // set_ExclusionMask( mask ); 01543 // set_epsilon_min( 0.099 ); 01544 // set_epsilon_max( 0.101 ); 01545 // set_S_fail( 5.0 ); 01546 // set_S_pass( 5.0 ); 01547 // 01548 // /*--------------------------------------------------------------------------+ 01549 // | Input to this function | 01550 // +--------------------------------------------------------------------------+ 01551 // |TH1F* histogram, : histogram to be compared with Rule | 01552 // |int* mask : bit mask which excludes bins from consideration | 01553 // |double epsilon_min, : minimum tolerance (fraction of line) | 01554 // |double epsilon_max, : maximum tolerance (fraction of line) | 01555 // |double S_fail, : required Statistical Significance to fail rule | 01556 // |double S_pass, : required Significance to pass rule | 01557 // |double[2][] FailedBins: uninit. vector of bins out of tolerance | 01558 // +--------------------------------------------------------------------------+ 01559 // | Result values for this function | 01560 // +--------------------------------------------------------------------------+ 01561 // |int result : "0" = "Passed Rule & is statistically significant"| 01562 // | "1" = "Failed Rule & is statistically significant"| 01563 // | "2" = "Passed Rule & not stat. significant" | 01564 // | "3" = "Failed Rule & not stat. significant" | 01565 // | "4" = "zero histo entries, can not evaluate Rule" | 01566 // | "5" = "Input invalid, can not evaluate Rule" | 01567 // |double[2][] FailedBins: the obs. vector of bins out of tolerance | 01568 // +--------------------------------------------------------------------------+ 01569 // | Author: Richard Cavanaugh, University of Florida | 01570 // | email: Richard.Cavanaugh@cern.ch | 01571 // | Creation Date: 07.Jan.2006 | 01572 // | Last Modified: 16.Jan.2006 | 01573 // | Comments: | 01574 // +--------------------------------------------------------------------------*/ 01575 // double *S_fail_obs; 01576 // double *S_pass_obs; 01577 // double dummy1, dummy2; 01578 // S_fail_obs = &dummy1; 01579 // S_pass_obs = &dummy2; 01580 // *S_fail_obs = 0.0; 01581 // *S_pass_obs = 0.0; 01582 // Nbins = histogram -> GetNbinsX(); 01583 // 01584 // //-----------Perform Quality Checks on Input------------- 01585 // if (!histogram) {result = 5; return 0.0;} //exit if histo does not exist 01586 // if (epsilon_min <= 0.0 || epsilon_min >= 1.0) 01587 // {result = 5; return 0.0;} //exit if epsilon_min not in (0,1) 01588 // if (epsilon_max <= 0.0 || epsilon_max >= 1.0) 01589 // {result = 5; return 0.0;} //exit if epsilon_max not in (0,1) 01590 // if (epsilon_max < epsilon_min) 01591 // {result = 5; return 0.0;} //exit if max < min 01592 // if (S_fail < 0) {result = 5; return 0.0;} //exit if Significance < 0 01593 // if (S_pass < 0) {result = 5; return 0.0;} //exit if Significance < 0 01594 // int Nentries = (int) histogram -> GetEntries(); 01595 // if (Nentries < 1){result = 4; return 0.0;} //exit if histo has 0 entries 01596 // 01597 // //-----------Calculate Statistical Significance------------- 01598 // double S_pass_obs_min = 0.0, S_fail_obs_max = 0.0; 01599 // // allocate Nbins of memory for FailedBins 01600 // for (int i = 0; i <= 1; i++) FailedBins[i] = new double [Nbins]; 01601 // // remember to delete[] FailedBins[0] and delete[] FailedBins[1]; 01602 // for (int i = 1; i <= Nbins; i++) //loop over all bins 01603 // { 01604 // FailedBins[0][i-1] = 0.0; //initialise obs fraction 01605 // FailedBins[1][i-1] = 0.0; //initialise obs significance 01606 // if (ExclusionMask[i-1] != 1) //do not check if bin excluded 01607 // { 01608 // //determine significance for bin to fail or pass, given occupancy 01609 // //hypothesis b with tolerance epsilon_min < b < epsilon_max 01610 // PoissionLogLikelihoodRatio(histogram->GetBinContent(i), 01611 // b, 01612 // epsilon_min, epsilon_max, 01613 // S_fail_obs, S_pass_obs); 01614 // //set S_fail_obs to maximum over all non-excluded bins 01615 // //set S_pass_obs to non-zero minimum over all non-excluded bins 01616 // if (S_fail_obs_max == 0.0 && *S_pass_obs > 0.0) 01617 // S_pass_obs_min = *S_pass_obs; //init to first non-zero value 01618 // if (*S_fail_obs > S_fail_obs_max) S_fail_obs_max = *S_fail_obs; 01619 // if (*S_pass_obs < S_pass_obs_min) S_pass_obs_min = *S_pass_obs; 01620 // //set FailedBins[0][] to fraction away from fitted line b 01621 // //set to zero if bin is within tolerance (via initialisation) 01622 // if (*S_fail_obs > 0) FailedBins[0][i-1] = 01623 // histogram->GetBinContent(i)/b - 1.0; 01624 // //set FailedBins[1][] to observed significance of failure 01625 // //set to zero if bin is within tolerance (via initialisation) 01626 // if (*S_fail_obs > 0) FailedBins[1][i-1] = *S_fail_obs; 01627 // } 01628 // } 01629 // *S_fail_obs = S_fail_obs_max; 01630 // *S_pass_obs = S_pass_obs_min; 01631 // if (*S_fail_obs > 0.0) 01632 // { 01633 // if (*S_fail_obs > S_fail) 01634 // {result = 1; return 0.0;} //exit if statistically fails rule 01635 // else 01636 // {result = 3; return 0.0;} //exit if non-stat significant result 01637 // } 01638 // else 01639 // { 01640 // if (*S_pass_obs > S_pass) 01641 // {result = 0; return 1.0;} //exit if statistically passes rule 01642 // else 01643 // {result = 2; return 0.0;} //exit if non-stat significant result 01644 // } 01645 // } 01646 // 01647 // 01648 // 01649 // #if 0 01650 // float AllContentAlongDiagonal::runTest(const TH2F *histogram) 01651 // { 01652 // 01653 // if (!me) return -1; 01654 // 01655 // if (me->kind()!=MonitorElement::DQM_KIND_TH2F) { 01656 // std::cout<< " AllContentAlongDiagonal ERROR: ME " << me->getFullname() << " does not contain TH2F" << std::endl; 01657 // return -1;} 01658 // 01659 // histogram = me->getTH2F(); //access Test histo 01660 // if (!histogram) return -1; 01661 // 01662 // /* 01663 // +--------------------------------------------------------------------------+ 01664 // | Input to this function | 01665 // +--------------------------------------------------------------------------+ 01666 // |TH2* histogram, : histogram to be compared with Rule | 01667 // |double epsilon_max, : maximum allowed failure rate fraction | 01668 // |double S_fail, : required Significance to fail rule | 01669 // |double S_pass, : required Significance to pass rule | 01670 // |double* epsilon_obs : uninitialised actual failure rate fraction | 01671 // |double* S_fail_obs : uninitialised Statistical Significance of failure | 01672 // |double* S_pass_obs : uninitialised Significance of Success | 01673 // +--------------------------------------------------------------------------+ 01674 // | Result values for this function | 01675 // +--------------------------------------------------------------------------+ 01676 // |int result : "0" = "Passed Rule & is statistically significant"| 01677 // | "1" = "Failed Rule & is statistically significant"| 01678 // | "2" = "Passed Rule & not stat. significant" | 01679 // | "3" = "Failed Rule & not stat. significant" | 01680 // | "4" = "zero histo entries, can not evaluate Rule" | 01681 // | "5" = "Input invalid, can not evaluate Rule" | 01682 // |double* epsilon_obs : the observed failure rate frac. from the histogram| 01683 // |double* S_fail_obs : the observed Significance of failure | 01684 // |double* S_pass_obs : the observed Significance of Success | 01685 // +--------------------------------------------------------------------------+ 01686 // | Author: Richard Cavanaugh, University of Florida | 01687 // | email: Richard.Cavanaugh@cern.ch | 01688 // | Creation Date: 11.July.2005 | 01689 // | Last Modified: 16.Jan.2006 | 01690 // | Comments: | 01691 // +--------------------------------------------------------------------------+ 01692 // */ 01693 // //-----------Perform Quality Checks on Input------------- 01694 // if (!histogram) {result = 5; return 0.0;}//exit if histo does not exist 01695 // if (histogram -> GetNbinsX() != histogram -> GetNbinsY()) 01696 // {result = 5; return 0.0;}//exit if histogram not square 01697 // if (epsilon_max <= 0.0 || epsilon_max >= 1.0) 01698 // {result = 5; return 0.0;}//exit if epsilon_max not in (0,1) 01699 // if (S_fail < 0) {result = 5; return 0.0;}//exit if Significance < 0 01700 // if (S_pass < 0) {result = 5; return 0.0;}//exit if Significance < 0 01701 // S_fail_obs = 0.0; S_pass_obs = 0.0; //initialise Sig return values 01702 // int Nentries = (int) histogram -> GetEntries(); 01703 // if (Nentries < 1){result = 4; return 0.0;}//exit if histo has 0 entries 01704 // 01705 // //-----------Find number of successes and failures------------- 01706 // int Nsuccesses = 0; 01707 // for (int i = 0; i <= histogram -> GetNbinsX() + 1; i++)//count the number of 01708 // { //entries contained along diag. 01709 // Nsuccesses += (int) histogram -> GetBinContent(i,i); 01710 // } 01711 // int Nfailures = Nentries - Nsuccesses; 01712 // double Nepsilon_max = (double)Nentries * epsilon_max; 01713 // epsilon_obs = (double)Nfailures / (double)Nentries; 01714 // 01715 // //-----------Calculate Statistical Significance------------- 01716 // BinLogLikelihoodRatio(Nentries,Nfailures,epsilon_max,&S_fail_obs,&S_pass_obs); 01717 // if (Nfailures > Nepsilon_max) 01718 // { 01719 // if (S_fail_obs > S_fail) 01720 // {result = 1; return 0.0;} //exit if statistically fails rule 01721 // else 01722 // {result = 3; return 0.0;} //exit if non-stat significant result 01723 // } 01724 // else 01725 // { 01726 // if (S_pass_obs > S_pass) 01727 // {result = 0; return 1.0;} //exit if statistically passes rule 01728 // else 01729 // {result = 2; return 0.0;} //exit if non-stat significant result 01730 // } 01731 // } 01732 // #endif