CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
QTest.cc
Go to the documentation of this file.
5 #include "TMath.h"
6 #include <iostream>
7 #include <sstream>
8 #include <math.h>
9 
10 using namespace std;
11 
12 const float QCriterion::ERROR_PROB_THRESHOLD = 0.50;
13 const float QCriterion::WARNING_PROB_THRESHOLD = 0.90;
14 
15 // initialize values
16 void
18 {
19  errorProb_ = ERROR_PROB_THRESHOLD;
20  warningProb_ = WARNING_PROB_THRESHOLD;
21  setAlgoName("NO_ALGORITHM");
22  status_ = dqm::qstatus::DID_NOT_RUN;
23  message_ = "NO_MESSAGE";
24  verbose_ = 0; // 0 = silent, 1 = algorithmic failures, 2 = info
25 }
26 
27 float QCriterion::runTest(const MonitorElement * /* me */)
28 {
29  raiseDQMError("QCriterion", "virtual runTest method called" );
30  return 0.;
31 }
32 //===================================================//
33 //================ QUALITY TESTS ====================//
34 //==================================================//
35 
36 //-------------------------------------------------------//
37 //----------------- Comp2RefEqualH base -----------------//
38 //-------------------------------------------------------//
39 // run the test (result: [0, 1] or <0 for failure)
41 {
42  badChannels_.clear();
43 
44  if (!me)
45  return -1;
46  if (!me->getRootObject() || !me->getRefRootObject())
47  return -1;
48  TH1* h=0; //initialize histogram pointer
49  TH1* ref_=0;
50 
51  if (verbose_>1)
52  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
53  << me-> getFullname() << "\n";
54 
55  int nbins=0;
56  int nbinsref=0;
57  //-- TH1F
59  {
60  nbins = me->getTH1F()->GetXaxis()->GetNbins();
61  nbinsref = me->getRefTH1F()->GetXaxis()->GetNbins();
62  h = me->getTH1F(); // access Test histo
63  ref_ = me->getRefTH1F(); //access Ref hiso
64  if (nbins != nbinsref) return -1;
65  }
66  //-- TH1S
67  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
68  {
69  nbins = me->getTH1S()->GetXaxis()->GetNbins();
70  nbinsref = me->getRefTH1S()->GetXaxis()->GetNbins();
71  h = me->getTH1S(); // access Test histo
72  ref_ = me->getRefTH1S(); //access Ref hiso
73  if (nbins != nbinsref) return -1;
74  }
75  //-- TH1D
76  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
77  {
78  nbins = me->getTH1D()->GetXaxis()->GetNbins();
79  nbinsref = me->getRefTH1D()->GetXaxis()->GetNbins();
80  h = me->getTH1D(); // access Test histo
81  ref_ = me->getRefTH1D(); //access Ref hiso
82  if (nbins != nbinsref) return -1;
83  }
84  //-- TH2
85  else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
86  {
87  nbins = me->getTH2F()->GetXaxis()->GetNbins() *
88  me->getTH2F()->GetYaxis()->GetNbins();
89  nbinsref = me->getRefTH2F()->GetXaxis()->GetNbins() *
90  me->getRefTH2F()->GetYaxis()->GetNbins();
91  h = me->getTH2F(); // access Test histo
92  ref_ = me->getRefTH2F(); //access Ref hiso
93  if (nbins != nbinsref) return -1;
94  }
95 
96  //-- TH2
97  else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
98  {
99  nbins = me->getTH2S()->GetXaxis()->GetNbins() *
100  me->getTH2S()->GetYaxis()->GetNbins();
101  nbinsref = me->getRefTH2S()->GetXaxis()->GetNbins() *
102  me->getRefTH2S()->GetYaxis()->GetNbins();
103  h = me->getTH2S(); // access Test histo
104  ref_ = me->getRefTH2S(); //access Ref hiso
105  if (nbins != nbinsref) return -1;
106  }
107 
108  //-- TH2
109  else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
110  {
111  nbins = me->getTH2D()->GetXaxis()->GetNbins() *
112  me->getTH2D()->GetYaxis()->GetNbins();
113  nbinsref = me->getRefTH2D()->GetXaxis()->GetNbins() *
114  me->getRefTH2D()->GetYaxis()->GetNbins();
115  h = me->getTH2D(); // access Test histo
116  ref_ = me->getRefTH2D(); //access Ref hiso
117  if (nbins != nbinsref) return -1;
118  }
119 
120  //-- TH3
121  else if (me->kind()==MonitorElement::DQM_KIND_TH3F)
122  {
123  nbins = me->getTH3F()->GetXaxis()->GetNbins() *
124  me->getTH3F()->GetYaxis()->GetNbins() *
125  me->getTH3F()->GetZaxis()->GetNbins();
126  nbinsref = me->getRefTH3F()->GetXaxis()->GetNbins() *
127  me->getRefTH3F()->GetYaxis()->GetNbins() *
128  me->getRefTH3F()->GetZaxis()->GetNbins();
129  h = me->getTH3F(); // access Test histo
130  ref_ = me->getRefTH3F(); //access Ref hiso
131  if (nbins != nbinsref) return -1;
132  }
133 
134  else
135  {
136  if (verbose_>0)
137  std::cout << "QTest:Comp2RefEqualH"
138  << " ME does not contain TH1F/TH1S/TH1D/TH2F/TH2S/TH2D/TH3F, exiting\n";
139  return -1;
140  }
141 
142  //-- QUALITY TEST itself
143  int first = 0; // 1 //(use underflow bin)
144  int last = nbins+1; //(use overflow bin)
145  bool failure = false;
146  for (int bin=first;bin<=last;bin++)
147  {
148  double contents = h->GetBinContent(bin);
149  if (contents != ref_->GetBinContent(bin))
150  {
151  failure = true;
152  DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
153  badChannels_.push_back(chan);
154  }
155  }
156  if (failure) return 0;
157  return 1;
158 }
159 
160 //-------------------------------------------------------//
161 //----------------- Comp2RefChi2 --------------------//
162 //-------------------------------------------------------//
164 {
165  if (!me)
166  return -1;
167  if (!me->getRootObject() || !me->getRefRootObject())
168  return -1;
169  TH1* h=0;
170  TH1* ref_=0;
171 
172  if (verbose_>1)
173  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
174  << me-> getFullname() << "\n";
175  //-- TH1F
177  {
178  h = me->getTH1F(); // access Test histo
179  ref_ = me->getRefTH1F(); //access Ref histo
180  }
181  //-- TH1S
182  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
183  {
184  h = me->getTH1S(); // access Test histo
185  ref_ = me->getRefTH1S(); //access Ref histo
186  }
187  //-- TH1D
188  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
189  {
190  h = me->getTH1D(); // access Test histo
191  ref_ = me->getRefTH1D(); //access Ref histo
192  }
193  //-- TProfile
194  else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
195  {
196  h = me->getTProfile(); // access Test histo
197  ref_ = me->getRefTProfile(); //access Ref histo
198  }
199  else
200  {
201  if (verbose_>0)
202  std::cout << "QTest::Comp2RefChi2"
203  << " ME does not contain TH1F/TH1S/TH1D/TProfile, exiting\n";
204  return -1;
205  }
206 
207  //-- isInvalid ? - Check consistency in number of channels
208  int ncx1 = h->GetXaxis()->GetNbins();
209  int ncx2 = ref_->GetXaxis()->GetNbins();
210  if ( ncx1 != ncx2)
211  {
212  if (verbose_>0)
213  std::cout << "QTest:Comp2RefChi2"
214  << " different number of channels! ("
215  << ncx1 << ", " << ncx2 << "), exiting\n";
216  return -1;
217  }
218 
219  //-- QUALITY TEST itself
220  //reset Results
221  Ndof_ = 0; chi2_ = -1.; ncx1 = ncx2 = -1;
222 
223  int i, i_start, i_end;
224  double chi2 = 0.; int ndof = 0; int constraint = 0;
225 
226  i_start = 1;
227  i_end = ncx1;
228  // if (fXaxis.TestBit(TAxis::kAxisRange)) {
229  i_start = h->GetXaxis()->GetFirst();
230  i_end = h->GetXaxis()->GetLast();
231  // }
232  ndof = i_end-i_start+1-constraint;
233 
234  //Compute the normalisation factor
235  double sum1=0, sum2=0;
236  for (i=i_start; i<=i_end; i++)
237  {
238  sum1 += h->GetBinContent(i);
239  sum2 += ref_->GetBinContent(i);
240  }
241 
242  //check that the histograms are not empty
243  if (sum1 == 0)
244  {
245  if (verbose_>0)
246  std::cout << "QTest:Comp2RefChi2"
247  << " Test Histogram " << h->GetName()
248  << " is empty, exiting\n";
249  return -1;
250  }
251  if (sum2 == 0)
252  {
253  if (verbose_>0)
254  std::cout << "QTest:Comp2RefChi2"
255  << " Ref Histogram " << ref_->GetName()
256  << " is empty, exiting\n";
257  return -1;
258  }
259 
260  double bin1, bin2, err1, err2, temp;
261  for (i=i_start; i<=i_end; i++)
262  {
263  bin1 = h->GetBinContent(i)/sum1;
264  bin2 = ref_->GetBinContent(i)/sum2;
265  if (bin1 ==0 && bin2==0)
266  {
267  --ndof; //no data means one less degree of freedom
268  }
269  else
270  {
271  temp = bin1-bin2;
272  err1=h->GetBinError(i); err2=ref_->GetBinError(i);
273  if (err1 == 0 && err2 == 0)
274  {
275  if (verbose_>0)
276  std::cout << "QTest:Comp2RefChi2"
277  << " bins with non-zero content and zero error, exiting\n";
278  return -1;
279  }
280  err1*=err1 ; err2*=err2;
281  err1/=sum1*sum1 ; err2/=sum2*sum2;
282  chi2 +=temp*temp/(err1+err2);
283  }
284  }
285  chi2_ = chi2; Ndof_ = ndof;
286  return TMath::Prob(0.5*chi2, int(0.5*ndof));
287 }
288 
289 //-------------------------------------------------------//
290 //----------------- Comp2RefKolmogorov --------------//
291 //-------------------------------------------------------//
292 
294 {
295  const double difprec = 1e-5;
296 
297  if (!me)
298  return -1;
299  if (!me->getRootObject() || !me->getRefRootObject())
300  return -1;
301  TH1* h=0;
302  TH1* ref_=0;
303 
304  if (verbose_>1)
305  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
306  << me-> getFullname() << "\n";
307  //-- TH1F
309  {
310  h = me->getTH1F(); // access Test histo
311  ref_ = me->getRefTH1F(); //access Ref histo
312  }
313  //-- TH1S
314  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
315  {
316  h = me->getTH1S(); // access Test histo
317  ref_ = me->getRefTH1S(); //access Ref histo
318  }
319  //-- TH1D
320  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
321  {
322  h = me->getTH1D(); // access Test histo
323  ref_ = me->getRefTH1D(); //access Ref histo
324  }
325  //-- TProfile
326  else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
327  {
328  h = me->getTProfile(); // access Test histo
329  ref_ = me->getRefTProfile(); //access Ref histo
330  }
331  else
332  {
333  if (verbose_>0)
334  std::cout << "QTest:Comp2RefKolmogorov"
335  << " ME does not contain TH1F/TH1S/TH1D/TProfile, exiting\n";
336  return -1;
337  }
338 
339  //-- isInvalid ? - Check consistency in number of channels
340  int ncx1 = h->GetXaxis()->GetNbins();
341  int ncx2 = ref_->GetXaxis()->GetNbins();
342  if ( ncx1 != ncx2)
343  {
344  if (verbose_>0)
345  std::cout << "QTest:Comp2RefKolmogorov"
346  << " different number of channels! ("
347  << ncx1 << ", " << ncx2 << "), exiting\n";
348  return -1;
349  }
350  //-- isInvalid ? - Check consistency in channel edges
351  double diff1 = TMath::Abs(h->GetXaxis()->GetXmin() - ref_->GetXaxis()->GetXmin());
352  double diff2 = TMath::Abs(h->GetXaxis()->GetXmax() - ref_->GetXaxis()->GetXmax());
353  if (diff1 > difprec || diff2 > difprec)
354  {
355  if (verbose_>0)
356  std::cout << "QTest:Comp2RefKolmogorov"
357  << " histograms with different binning, exiting\n";
358  return -1;
359  }
360 
361  //-- QUALITY TEST itself
362  Bool_t afunc1 = kFALSE; Bool_t afunc2 = kFALSE;
363  double sum1 = 0, sum2 = 0;
364  double ew1, ew2, w1 = 0, w2 = 0;
365  int bin;
366  for (bin=1;bin<=ncx1;bin++)
367  {
368  sum1 += h->GetBinContent(bin);
369  sum2 += ref_->GetBinContent(bin);
370  ew1 = h->GetBinError(bin);
371  ew2 = ref_->GetBinError(bin);
372  w1 += ew1*ew1;
373  w2 += ew2*ew2;
374  }
375 
376  if (sum1 == 0)
377  {
378  if (verbose_>0)
379  std::cout << "QTest:Comp2RefKolmogorov"
380  << " Test Histogram: " << h->GetName()
381  << ": integral is zero, exiting\n";
382  return -1;
383  }
384  if (sum2 == 0)
385  {
386  if (verbose_>0)
387  std::cout << "QTest:Comp2RefKolmogorov"
388  << " Ref Histogram: " << ref_->GetName()
389  << ": integral is zero, exiting\n";
390  return -1;
391  }
392 
393  double tsum1 = sum1; double tsum2 = sum2;
394  tsum1 += h->GetBinContent(0);
395  tsum2 += ref_->GetBinContent(0);
396  tsum1 += h->GetBinContent(ncx1+1);
397  tsum2 += ref_->GetBinContent(ncx1+1);
398 
399  // Check if histograms are weighted.
400  // If number of entries = number of channels, probably histograms were
401  // not filled via Fill(), but via SetBinContent()
402  double ne1 = h->GetEntries();
403  double ne2 = ref_->GetEntries();
404  // look at first histogram
405  double difsum1 = (ne1-tsum1)/tsum1;
406  double esum1 = sum1;
407  if (difsum1 > difprec && int(ne1) != ncx1)
408  {
409  if (h->GetSumw2N() == 0)
410  {
411  if (verbose_>0)
412  std::cout << "QTest:Comp2RefKolmogorov"
413  << " Weighted events and no Sumw2 for "
414  << h->GetName() << "\n";
415  }
416  else
417  {
418  esum1 = sum1*sum1/w1; //number of equivalent entries
419  }
420  }
421  // look at second histogram
422  double difsum2 = (ne2-tsum2)/tsum2;
423  double esum2 = sum2;
424  if (difsum2 > difprec && int(ne2) != ncx1)
425  {
426  if (ref_->GetSumw2N() == 0)
427  {
428  if (verbose_>0)
429  std::cout << "QTest:Comp2RefKolmogorov"
430  << " Weighted events and no Sumw2 for "
431  << ref_->GetName() << "\n";
432  }
433  else
434  {
435  esum2 = sum2*sum2/w2; //number of equivalent entries
436  }
437  }
438 
439  double s1 = 1/tsum1; double s2 = 1/tsum2;
440  // Find largest difference for Kolmogorov Test
441  double dfmax =0, rsum1 = 0, rsum2 = 0;
442  // use underflow bin
443  int first = 0; // 1
444  // use overflow bin
445  int last = ncx1+1; // ncx1
446  for ( bin=first; bin<=last; bin++)
447  {
448  rsum1 += s1*h->GetBinContent(bin);
449  rsum2 += s2*ref_->GetBinContent(bin);
450  dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
451  }
452 
453  // Get Kolmogorov probability
454  double z = 0;
455  if (afunc1) z = dfmax*TMath::Sqrt(esum2);
456  else if (afunc2) z = dfmax*TMath::Sqrt(esum1);
457  else z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
458 
459  // This numerical error condition should never occur:
460  if (TMath::Abs(rsum1-1) > 0.002)
461  if (verbose_>0)
462  std::cout << "QTest:Comp2RefKolmogorov"
463  << " Numerical problems with histogram "
464  << h->GetName() << "\n";
465  if (TMath::Abs(rsum2-1) > 0.002)
466  if (verbose_>0)
467  std::cout << "QTest:Comp2RefKolmogorov"
468  << " Numerical problems with histogram "
469  << ref_->GetName() << "\n";
470 
471  return TMath::KolmogorovProb(z);
472 }
473 
474 //----------------------------------------------------//
475 //--------------- ContentsXRange ---------------------//
476 //----------------------------------------------------//
478 {
479  badChannels_.clear();
480 
481  if (!me)
482  return -1;
483  if (!me->getRootObject())
484  return -1;
485  TH1* h=0;
486 
487  if (verbose_>1)
488  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
489  << me-> getFullname() << "\n";
490  // -- TH1F
491  if (me->kind()==MonitorElement::DQM_KIND_TH1F )
492  {
493  h = me->getTH1F();
494  }
495  // -- TH1S
496  else if ( me->kind()==MonitorElement::DQM_KIND_TH1S )
497  {
498  h = me->getTH1S();
499  }
500  // -- TH1D
501  else if ( me->kind()==MonitorElement::DQM_KIND_TH1D )
502  {
503  h = me->getTH1D();
504  }
505  else
506  {
507  if (verbose_>0) std::cout << "QTest:ContentsXRange"
508  << " ME " << me->getFullname()
509  << " does not contain TH1F/TH1S/TH1D, exiting\n";
510  return -1;
511  }
512 
513  if (!rangeInitialized_)
514  {
515  if ( h->GetXaxis() )
516  setAllowedXRange(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
517  else
518  return -1;
519  }
520  int ncx = h->GetXaxis()->GetNbins();
521  // use underflow bin
522  int first = 0; // 1
523  // use overflow bin
524  int last = ncx+1; // ncx
525  // all entries
526  double sum = 0;
527  // entries outside X-range
528  double fail = 0;
529  int bin;
530  for (bin = first; bin <= last; ++bin)
531  {
532  double contents = h->GetBinContent(bin);
533  double x = h->GetBinCenter(bin);
534  sum += contents;
535  if (x < xmin_ || x > xmax_)fail += contents;
536  }
537 
538  if (sum==0) return 1;
539  // return fraction of entries within allowed X-range
540  return (sum - fail)/sum;
541 
542 }
543 
544 //-----------------------------------------------------//
545 //--------------- ContentsYRange ---------------------//
546 //----------------------------------------------------//
548 {
549  badChannels_.clear();
550 
551  if (!me)
552  return -1;
553  if (!me->getRootObject())
554  return -1;
555  TH1* h=0;
556 
557  if (verbose_>1)
558  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
559  << me-> getFullname() << "\n";
560 
562  {
563  h = me->getTH1F(); //access Test histo
564  }
565  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
566  {
567  h = me->getTH1S(); //access Test histo
568  }
569  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
570  {
571  h = me->getTH1D(); //access Test histo
572  }
573  else
574  {
575  if (verbose_>0)
576  std::cout << "QTest:ContentsYRange"
577  << " ME " << me->getFullname()
578  << " does not contain TH1F/TH1S/TH1D, exiting\n";
579  return -1;
580  }
581 
582  if (!rangeInitialized_ || !h->GetXaxis()) return 1; // all bins are accepted if no initialization
583  int ncx = h->GetXaxis()->GetNbins();
584  // do NOT use underflow bin
585  int first = 1;
586  // do NOT use overflow bin
587  int last = ncx;
588  // bins outside Y-range
589  int fail = 0;
590  int bin;
591 
592  if (useEmptyBins_)
593  {
594  for (bin = first; bin <= last; ++bin)
595  {
596  double contents = h->GetBinContent(bin);
597  bool failure = false;
598  failure = (contents < ymin_ || contents > ymax_); // allowed y-range: [ymin_, ymax_]
599  if (failure)
600  {
601  DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
602  badChannels_.push_back(chan);
603  ++fail;
604  }
605  }
606  // return fraction of bins that passed test
607  return 1.*(ncx - fail)/ncx;
608  }
609  else
610  {
611  for (bin = first; bin <= last; ++bin)
612  {
613  double contents = h->GetBinContent(bin);
614  bool failure = false;
615  if (contents) failure = (contents < ymin_ || contents > ymax_); // allowed y-range: [ymin_, ymax_]
616  if (failure) ++fail;
617  }
618  // return fraction of bins that passed test
619  return 1.*(ncx - fail)/ncx;
620  }
621 }
622 
623 //-----------------------------------------------------//
624 //------------------ DeadChannel ---------------------//
625 //----------------------------------------------------//
627 {
628  badChannels_.clear();
629  if (!me)
630  return -1;
631  if (!me->getRootObject())
632  return -1;
633  TH1* h1=0;
634  TH2* h2=0;//initialize histogram pointers
635 
636  if (verbose_>1)
637  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
638  << me-> getFullname() << "\n";
639  //TH1F
641  {
642  h1 = me->getTH1F(); //access Test histo
643  }
644  //TH1S
645  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
646  {
647  h1 = me->getTH1S(); //access Test histo
648  }
649  //TH1D
650  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
651  {
652  h1 = me->getTH1D(); //access Test histo
653  }
654  //-- TH2F
655  else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
656  {
657  h2 = me->getTH2F(); // access Test histo
658  }
659  //-- TH2S
660  else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
661  {
662  h2 = me->getTH2S(); // access Test histo
663  }
664  //-- TH2D
665  else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
666  {
667  h2 = me->getTH2D(); // access Test histo
668  }
669  else
670  {
671  if (verbose_>0)
672  std::cout << "QTest:DeadChannel"
673  << " ME " << me->getFullname()
674  << " does not contain TH1F/TH1S/TH1D/TH2F/TH2S/TH2D, exiting\n";
675  return -1;
676  }
677 
678  int fail = 0; // number of failed channels
679 
680  //--------- do the quality test for 1D histo ---------------//
681  if (h1 != NULL)
682  {
683  if (!rangeInitialized_ || !h1->GetXaxis() )
684  return 1; // all bins are accepted if no initialization
685  int ncx = h1->GetXaxis()->GetNbins();
686  int first = 1;
687  int last = ncx;
688  int bin;
689 
691  for (bin = first; bin <= last; ++bin)
692  {
693  double contents = h1->GetBinContent(bin);
694  bool failure = false;
695  failure = contents <= ymin_; // dead channel: equal to or less than ymin_
696  if (failure)
697  {
698  DQMChannel chan(bin, 0, 0, contents, h1->GetBinError(bin));
699  badChannels_.push_back(chan);
700  ++fail;
701  }
702  }
703  //return fraction of alive channels
704  return 1.*(ncx - fail)/ncx;
705  }
706  //----------------------------------------------------------//
707 
708  //--------- do the quality test for 2D -------------------//
709  else if (h2 !=NULL )
710  {
711  int ncx = h2->GetXaxis()->GetNbins(); // get X bins
712  int ncy = h2->GetYaxis()->GetNbins(); // get Y bins
713 
715  for (int cx = 1; cx <= ncx; ++cx)
716  {
717  for (int cy = 1; cy <= ncy; ++cy)
718  {
719  double contents = h2->GetBinContent(h2->GetBin(cx, cy));
720  bool failure = false;
721  failure = contents <= ymin_; // dead channel: equal to or less than ymin_
722  if (failure)
723  {
724  DQMChannel chan(cx, cy, 0, contents, h2->GetBinError(h2->GetBin(cx, cy)));
725  badChannels_.push_back(chan);
726  ++fail;
727  }
728  }
729  }
730  //return fraction of alive channels
731  return 1.*(ncx*ncy - fail) / (ncx*ncy);
732  }
733  else
734  {
735  if (verbose_>0)
736  std::cout << "QTest:DeadChannel"
737  << " TH1/TH2F are NULL, exiting\n";
738  return -1;
739  }
740 }
741 
742 //-----------------------------------------------------//
743 //---------------- NoisyChannel ---------------------//
744 //----------------------------------------------------//
745 // run the test (result: fraction of channels not appearing noisy or "hot")
746 // [0, 1] or <0 for failure
748 {
749  badChannels_.clear();
750  if (!me)
751  return -1;
752  if (!me->getRootObject())
753  return -1;
754  TH1* h=0;//initialize histogram pointer
755 
756  if (verbose_>1)
757  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
758  << me-> getFullname() << "\n";
759 
760  int nbins=0;
761  //-- TH1F
763  {
764  nbins = me->getTH1F()->GetXaxis()->GetNbins();
765  h = me->getTH1F(); // access Test histo
766  }
767  //-- TH1S
768  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
769  {
770  nbins = me->getTH1S()->GetXaxis()->GetNbins();
771  h = me->getTH1S(); // access Test histo
772  }
773  //-- TH1D
774  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
775  {
776  nbins = me->getTH1D()->GetXaxis()->GetNbins();
777  h = me->getTH1D(); // access Test histo
778  }
779  //-- TH2
780  else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
781  {
782  nbins = me->getTH2F()->GetXaxis()->GetNbins() *
783  me->getTH2F()->GetYaxis()->GetNbins();
784  h = me->getTH2F(); // access Test histo
785  }
786  //-- TH2
787  else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
788  {
789  nbins = me->getTH2S()->GetXaxis()->GetNbins() *
790  me->getTH2S()->GetYaxis()->GetNbins();
791  h = me->getTH2S(); // access Test histo
792  }
793  //-- TH2
794  else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
795  {
796  nbins = me->getTH2D()->GetXaxis()->GetNbins() *
797  me->getTH2D()->GetYaxis()->GetNbins();
798  h = me->getTH2D(); // access Test histo
799  }
800  else
801  {
802  if (verbose_>0)
803  std::cout << "QTest:NoisyChannel"
804  << " ME " << me->getFullname()
805  << " does not contain TH1F/TH1S/TH1D or TH2F/TH2S/TH2D, exiting\n";
806  return -1;
807  }
808 
809  //-- QUALITY TEST itself
810 
811  if ( !rangeInitialized_ || !h->GetXaxis() )
812  return 1; // all channels are accepted if tolerance has not been set
813 
814  // do NOT use underflow bin
815  int first = 1;
816  // do NOT use overflow bin
817  int last = nbins;
818  // bins outside Y-range
819  int fail = 0;
820  int bin;
821  for (bin = first; bin <= last; ++bin)
822  {
823  double contents = h->GetBinContent(bin);
824  double average = getAverage(bin, h);
825  bool failure = false;
826  if (average != 0)
827  failure = (((contents-average)/TMath::Abs(average)) > tolerance_);
828 
829  if (failure)
830  {
831  ++fail;
832  DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
833  badChannels_.push_back(chan);
834  }
835  }
836 
837  // return fraction of bins that passed test
838  return 1.*(nbins - fail)/nbins;
839 }
840 
841 // get average for bin under consideration
842 // (see description of method setNumNeighbors)
843 double NoisyChannel::getAverage(int bin, const TH1 *h) const
844 {
846  int first = 1;
848  int ncx = h->GetXaxis()->GetNbins();
849  double sum = 0; int bin_low, bin_hi;
850  for (unsigned i = 1; i <= numNeighbors_; ++i)
851  {
853  bin_low = bin-i; bin_hi = bin+i;
856  while (bin_low < first) // shift bin by +ncx
857  bin_low = ncx + bin_low;
858  while (bin_hi > ncx) // shift bin by -ncx
859  bin_hi = bin_hi - ncx;
860  sum += h->GetBinContent(bin_low) + h->GetBinContent(bin_hi);
861  }
863  return sum/(numNeighbors_ * 2);
864 }
865 
866 
867 //-----------------------------------------------------------//
868 //---------------- ContentsWithinExpected ---------------------//
869 //-----------------------------------------------------------//
870 // run the test (result: fraction of channels that passed test);
871 // [0, 1] or <0 for failure
873 {
874  badChannels_.clear();
875  if (!me)
876  return -1;
877  if (!me->getRootObject())
878  return -1;
879  TH1* h=0; //initialize histogram pointer
880 
881  if (verbose_>1)
882  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
883  << me-> getFullname() << "\n";
884 
885  int ncx;
886  int ncy;
887 
888  if (useEmptyBins_)
889  {
890  //-- TH2
892  {
893  ncx = me->getTH2F()->GetXaxis()->GetNbins();
894  ncy = me->getTH2F()->GetYaxis()->GetNbins();
895  h = me->getTH2F(); // access Test histo
896  }
897  //-- TH2S
898  else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
899  {
900  ncx = me->getTH2S()->GetXaxis()->GetNbins();
901  ncy = me->getTH2S()->GetYaxis()->GetNbins();
902  h = me->getTH2S(); // access Test histo
903  }
904  //-- TH2D
905  else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
906  {
907  ncx = me->getTH2D()->GetXaxis()->GetNbins();
908  ncy = me->getTH2D()->GetYaxis()->GetNbins();
909  h = me->getTH2D(); // access Test histo
910  }
911  //-- TProfile
912  else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
913  {
914  ncx = me->getTProfile()->GetXaxis()->GetNbins();
915  ncy = 1;
916  h = me->getTProfile(); // access Test histo
917  }
918  //-- TProfile2D
920  {
921  ncx = me->getTProfile2D()->GetXaxis()->GetNbins();
922  ncy = me->getTProfile2D()->GetYaxis()->GetNbins();
923  h = me->getTProfile2D(); // access Test histo
924  }
925  else
926  {
927  if (verbose_>0)
928  std::cout << "QTest:ContentsWithinExpected"
929  << " ME does not contain TH2F/TH2S/TH2D/TPROFILE/TPROFILE2D, exiting\n";
930  return -1;
931  }
932 
933  int nsum = 0;
934  double sum = 0.0;
935  double average = 0.0;
936 
937  if (checkMeanTolerance_)
938  { // calculate average value of all bin contents
939 
940  for (int cx = 1; cx <= ncx; ++cx)
941  {
942  for (int cy = 1; cy <= ncy; ++cy)
943  {
944  if (me->kind() == MonitorElement::DQM_KIND_TH2F)
945  {
946  sum += h->GetBinContent(h->GetBin(cx, cy));
947  ++nsum;
948  }
949  else if (me->kind() == MonitorElement::DQM_KIND_TH2S)
950  {
951  sum += h->GetBinContent(h->GetBin(cx, cy));
952  ++nsum;
953  }
954  else if (me->kind() == MonitorElement::DQM_KIND_TH2D)
955  {
956  sum += h->GetBinContent(h->GetBin(cx, cy));
957  ++nsum;
958  }
959  else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE)
960  {
961  if (me->getTProfile()->GetBinEntries(h->GetBin(cx)) >= minEntries_/(ncx))
962  {
963  sum += h->GetBinContent(h->GetBin(cx));
964  ++nsum;
965  }
966  }
967  else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D)
968  {
969  if (me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) >= minEntries_/(ncx*ncy))
970  {
971  sum += h->GetBinContent(h->GetBin(cx, cy));
972  ++nsum;
973  }
974  }
975  }
976  }
977 
978  if (nsum > 0)
979  average = sum/nsum;
980 
981  } // calculate average value of all bin contents
982 
983  int fail = 0;
984 
985  for (int cx = 1; cx <= ncx; ++cx)
986  {
987  for (int cy = 1; cy <= ncy; ++cy)
988  {
989  bool failMean = false;
990  bool failRMS = false;
991  bool failMeanTolerance = false;
992 
993  if (me->kind() == MonitorElement::DQM_KIND_TPROFILE &&
994  me->getTProfile()->GetBinEntries(h->GetBin(cx)) < minEntries_/(ncx))
995  continue;
996 
998  me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) < minEntries_/(ncx*ncy))
999  continue;
1000 
1001  if (checkMean_)
1002  {
1003  double mean = h->GetBinContent(h->GetBin(cx, cy));
1004  failMean = (mean < minMean_ || mean > maxMean_);
1005  }
1006 
1007  if (checkRMS_)
1008  {
1009  double rms = h->GetBinError(h->GetBin(cx, cy));
1010  failRMS = (rms < minRMS_ || rms > maxRMS_);
1011  }
1012 
1013  if (checkMeanTolerance_)
1014  {
1015  double mean = h->GetBinContent(h->GetBin(cx, cy));
1016  failMeanTolerance = (TMath::Abs(mean - average) > toleranceMean_*TMath::Abs(average));
1017  }
1018 
1019  if (failMean || failRMS || failMeanTolerance)
1020  {
1021 
1022  if (me->kind() == MonitorElement::DQM_KIND_TH2F)
1023  {
1024  DQMChannel chan(cx, cy, 0,
1025  h->GetBinContent(h->GetBin(cx, cy)),
1026  h->GetBinError(h->GetBin(cx, cy)));
1027  badChannels_.push_back(chan);
1028  }
1029  else if (me->kind() == MonitorElement::DQM_KIND_TH2S)
1030  {
1031  DQMChannel chan(cx, cy, 0,
1032  h->GetBinContent(h->GetBin(cx, cy)),
1033  h->GetBinError(h->GetBin(cx, cy)));
1034  badChannels_.push_back(chan);
1035  }
1036  else if (me->kind() == MonitorElement::DQM_KIND_TH2D)
1037  {
1038  DQMChannel chan(cx, cy, 0,
1039  h->GetBinContent(h->GetBin(cx, cy)),
1040  h->GetBinError(h->GetBin(cx, cy)));
1041  badChannels_.push_back(chan);
1042  }
1043  else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE)
1044  {
1045  DQMChannel chan(cx, cy, int(me->getTProfile()->GetBinEntries(h->GetBin(cx))),
1046  0,
1047  h->GetBinError(h->GetBin(cx)));
1048  badChannels_.push_back(chan);
1049  }
1050  else if (me->kind() == MonitorElement::DQM_KIND_TPROFILE2D)
1051  {
1052  DQMChannel chan(cx, cy, int(me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy))),
1053  h->GetBinContent(h->GetBin(cx, cy)),
1054  h->GetBinError(h->GetBin(cx, cy)));
1055  badChannels_.push_back(chan);
1056  }
1057  ++fail;
1058  }
1059  }
1060  }
1061  return 1.*(ncx*ncy - fail)/(ncx*ncy);
1062  }
1063 
1064  else
1065  {
1067  {
1068  ncx = me->getTH2F()->GetXaxis()->GetNbins();
1069  ncy = me->getTH2F()->GetYaxis()->GetNbins();
1070  h = me->getTH2F(); // access Test histo
1071  }
1072  else if (me->kind()==MonitorElement::DQM_KIND_TH2S)
1073  {
1074  ncx = me->getTH2S()->GetXaxis()->GetNbins();
1075  ncy = me->getTH2S()->GetYaxis()->GetNbins();
1076  h = me->getTH2S(); // access Test histo
1077  }
1078  else if (me->kind()==MonitorElement::DQM_KIND_TH2D)
1079  {
1080  ncx = me->getTH2D()->GetXaxis()->GetNbins();
1081  ncy = me->getTH2D()->GetYaxis()->GetNbins();
1082  h = me->getTH2D(); // access Test histo
1083  }
1084  else
1085  {
1086  if (verbose_>0)
1087  std::cout << "QTest:ContentsWithinExpected AS"
1088  << " ME does not contain TH2F/TH2S/TH2D, exiting\n";
1089  return -1;
1090  }
1091 
1092  // if (!rangeInitialized_) return 0; // all accepted if no initialization
1093  int fail = 0;
1094  for (int cx = 1; cx <= ncx; ++cx)
1095  {
1096  for (int cy = 1; cy <= ncy; ++cy)
1097  {
1098  bool failure = false;
1099  double Content = h->GetBinContent(h->GetBin(cx, cy));
1100  if (Content)
1101  failure = (Content < minMean_ || Content > maxMean_);
1102  if (failure)
1103  ++fail;
1104  }
1105  }
1106  return 1.*(ncx*ncy-fail)/(ncx*ncy);
1107  }
1108 
1109 }
1112 {
1113  if (xmax < xmin)
1114  if (verbose_>0)
1115  std::cout << "QTest:ContentsWitinExpected"
1116  << " Illogical range: (" << xmin << ", " << xmax << "\n";
1117  minMean_ = xmin;
1118  maxMean_ = xmax;
1119  checkMean_ = true;
1120 }
1121 
1124 {
1125  if (xmax < xmin)
1126  if (verbose_>0)
1127  std::cout << "QTest:ContentsWitinExpected"
1128  << " Illogical range: (" << xmin << ", " << xmax << "\n";
1129  minRMS_ = xmin;
1130  maxRMS_ = xmax;
1131  checkRMS_ = true;
1132 }
1133 
1134 //----------------------------------------------------------------//
1135 //-------------------- MeanWithinExpected ---------------------//
1136 //---------------------------------------------------------------//
1137 // run the test;
1138 // (a) if useRange is called: 1 if mean within allowed range, 0 otherwise
1139 // (b) is useRMS or useSigma is called: result is the probability
1140 // Prob(chi^2, ndof=1) that the mean of histogram will be deviated by more than
1141 // +/- delta from <expected_mean>, where delta = mean - <expected_mean>, and
1142 // chi^2 = (delta/sigma)^2. sigma is the RMS of the histogram ("useRMS") or
1143 // <expected_sigma> ("useSigma")
1144 // e.g. for delta = 1, Prob = 31.7%
1145 // for delta = 2, Prob = 4.55%
1146 // (returns result in [0, 1] or <0 for failure)
1148 {
1149  if (!me)
1150  return -1;
1151  if (!me->getRootObject())
1152  return -1;
1153  TH1* h=0;
1154 
1155  if (verbose_>1)
1156  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
1157  << me-> getFullname() << "\n";
1158 
1159  if (minEntries_ != 0 && me->getEntries() < minEntries_) return -1;
1160 
1161  if (me->kind()==MonitorElement::DQM_KIND_TH1F)
1162  {
1163  h = me->getTH1F(); //access Test histo
1164  }
1165  else if (me->kind()==MonitorElement::DQM_KIND_TH1S)
1166  {
1167  h = me->getTH1S(); //access Test histo
1168  }
1169  else if (me->kind()==MonitorElement::DQM_KIND_TH1D)
1170  {
1171  h = me->getTH1D(); //access Test histo
1172  }
1173  else {
1174  if (verbose_>0)
1175  std::cout << "QTest:MeanWithinExpected"
1176  << " ME " << me->getFullname()
1177  << " does not contain TH1F/TH1S/TH1D, exiting\n";
1178  return -1;
1179  }
1180 
1181 
1182  if (useRange_) {
1183  double mean = h->GetMean();
1184  if (mean <= xmax_ && mean >= xmin_)
1185  return 1;
1186  else
1187  return 0;
1188  }
1189  else if (useSigma_)
1190  {
1191  if (sigma_ != 0.)
1192  {
1193  double chi = (h->GetMean() - expMean_)/sigma_;
1194  return TMath::Prob(chi*chi, 1);
1195  }
1196  else
1197  {
1198  if (verbose_>0)
1199  std::cout << "QTest:MeanWithinExpected"
1200  << " Error, sigma_ is zero, exiting\n";
1201  return 0;
1202  }
1203  }
1204  else if (useRMS_)
1205  {
1206  if (h->GetRMS() != 0.)
1207  {
1208  double chi = (h->GetMean() - expMean_)/h->GetRMS();
1209  return TMath::Prob(chi*chi, 1);
1210  }
1211  else
1212  {
1213  if (verbose_>0)
1214  std::cout << "QTest:MeanWithinExpected"
1215  << " Error, RMS is zero, exiting\n";
1216  return 0;
1217  }
1218  }
1219  else
1220  if (verbose_>0)
1221  std::cout << "QTest:MeanWithinExpected"
1222  << " Error, neither Range, nor Sigma, nor RMS, exiting\n";
1223  return -1;
1224 }
1225 
1227 {
1228  useRange_ = true;
1229  useSigma_ = useRMS_ = false;
1230  xmin_ = xmin; xmax_ = xmax;
1231  if (xmin_ > xmax_)
1232  if (verbose_>0)
1233  std::cout << "QTest:MeanWithinExpected"
1234  << " Illogical range: (" << xmin_ << ", " << xmax_ << "\n";
1235 }
1236 void MeanWithinExpected::useSigma(double expectedSigma)
1237 {
1238  useSigma_ = true;
1239  useRMS_ = useRange_ = false;
1240  sigma_ = expectedSigma;
1241  if (sigma_ == 0)
1242  if (verbose_>0)
1243  std::cout << "QTest:MeanWithinExpected"
1244  << " Expected sigma = " << sigma_ << "\n";
1245 }
1246 
1248 {
1249  useRMS_ = true;
1250  useSigma_ = useRange_ = false;
1251 }
1252 
1253 //----------------------------------------------------------------//
1254 //------------------------ CompareToMedian ---------------------------//
1255 //----------------------------------------------------------------//
1256 /*
1257 Test for TProfile2D
1258 For each x bin, the median value is calculated and then each value is compared with the median.
1259 This procedure is repeated for each x-bin of the 2D profile
1260 The parameters used for this comparison are:
1261 MinRel and MaxRel to identify outliers wrt the median value
1262 An absolute value (MinAbs, MaxAbs) on the median is used to identify a full region out of specification
1263 */
1265  int32_t nbins=0, failed=0;
1266  badChannels_.clear();
1267 
1268  if (!me)
1269  return -1;
1270  if (!me->getRootObject())
1271  return -1;
1272  TH1* h=0;
1273 
1274  if (verbose_>1){
1275  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
1276  << me-> getFullname() << "\n";
1277  std::cout << "\tMin = " << _min << "; Max = " << _max << "\n";
1278  std::cout << "\tMinMedian = " << _minMed << "; MaxMedian = " << _maxMed << "\n";
1279  std::cout << "\tUseEmptyBins = " << (_emptyBins?"Yes":"No" )<< "\n";
1280  }
1281 
1283  {
1284  h = me->getTProfile2D(); // access Test histo
1285  }
1286  else
1287  {
1288  if (verbose_>0)
1289  std::cout << "QTest:ContentsWithinExpected"
1290  << " ME does not contain TPROFILE2D, exiting\n";
1291  return -1;
1292  }
1293 
1294  nBinsX = h->GetNbinsX();
1295  nBinsY = h->GetNbinsY();
1296  int entries = 0;
1297  float median = 0.0;
1298 
1299  //Median calculated with partially sorted vector
1300  for (int binX = 1; binX <= nBinsX; binX++ ){
1301  reset();
1302  // Fill vector
1303  for (int binY = 1; binY <= nBinsY; binY++){
1304  int bin = h->GetBin(binX, binY);
1305  double content = (double)h->GetBinContent(bin);
1306  if ( content == 0 && !_emptyBins)
1307  continue;
1308  binValues.push_back(content);
1309  entries = me->getTProfile2D()->GetBinEntries(bin);
1310  }
1311  if (binValues.empty())
1312  continue;
1313  nbins+=binValues.size();
1314 
1315  //calculate median
1316  if(binValues.size()>0){
1317  int medPos = (int)binValues.size()/2;
1318  nth_element(binValues.begin(),binValues.begin()+medPos,binValues.end());
1319  median = *(binValues.begin()+medPos);
1320  }
1321 
1322  // if median == 0, use the absolute cut
1323  if(median == 0){
1324  if (verbose_ > 0){
1325  std::cout << "QTest: Median is 0; the fixed cuts: [" << _minMed << "; " << _maxMed << "] are used\n";
1326  }
1327  for(int binY = 1; binY <= nBinsY; binY++){
1328  int bin = h->GetBin(binX, binY);
1329  double content = (double)h->GetBinContent(bin);
1330  entries = me->getTProfile2D()->GetBinEntries(bin);
1331  if ( entries == 0 )
1332  continue;
1333  if (content > _maxMed || content < _minMed){
1334  DQMChannel chan(binX,binY, 0, content, h->GetBinError(bin));
1335  badChannels_.push_back(chan);
1336  failed++;
1337  }
1338  }
1339  continue;
1340  }
1341 
1342  //Cut on stat: will mask rings with no enought of statistics
1343  if (median*entries < _statCut )
1344  continue;
1345 
1346  // If median is off the absolute cuts, declare everything bad (if bin has non zero entries)
1347  if(median > _maxMed || median < _minMed){
1348  for(int binY = 1; binY <= nBinsY; binY++){
1349  int bin = h->GetBin(binX, binY);
1350  double content = (double)h->GetBinContent(bin);
1351  entries = me->getTProfile2D()->GetBinEntries(bin);
1352  if ( entries == 0 )
1353  continue;
1354  DQMChannel chan(binX,binY, 0, content/median, h->GetBinError(bin));
1355  badChannels_.push_back(chan);
1356  failed++;
1357  }
1358  continue;
1359  }
1360 
1361  // Test itself
1362  float minCut = median*_min;
1363  float maxCut = median*_max;
1364  for(int binY = 1; binY <= nBinsY; binY++){
1365  int bin = h->GetBin(binX, binY);
1366  double content = (double)h->GetBinContent(bin);
1367  entries = me->getTProfile2D()->GetBinEntries(bin);
1368  if ( entries == 0 )
1369  continue;
1370  if (content > maxCut || content < minCut){
1371  DQMChannel chan(binX,binY, 0, content/median, h->GetBinError(bin));
1372  badChannels_.push_back(chan);
1373  failed++;
1374  }
1375  }
1376  }
1377 
1378  if (nbins==0){
1379  if (verbose_ > 0)
1380  std::cout << "QTest:CompareToMedian: Histogram is empty" << std::endl;
1381  return 1.;
1382  }
1383  return 1 - (float)failed/nbins;
1384 }
1385 //----------------------------------------------------------------//
1386 //------------------------ CompareLastFilledBin -----------------//
1387 //----------------------------------------------------------------//
1388 /*
1389 Test for TH1F and TH2F
1390 For the last filled bin the value is compared with specified upper and lower limits. If
1391 it is outside the limit the test failed test result is returned
1392 The parameters used for this comparison are:
1393 MinRel and MaxRel to check identify outliers wrt the median value
1394 */
1396  if (!me)
1397  return -1;
1398  if (!me->getRootObject())
1399  return -1;
1400  TH1* h1=0;
1401  TH2* h2=0;
1402  if (verbose_>1){
1403  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
1404  << me-> getFullname() << "\n";
1405  std::cout << "\tMin = " << _min << "; Max = " << _max << "\n";
1406  }
1408  {
1409  h1 = me->getTH1F(); // access Test histo
1410  }
1411  else if (me->kind()==MonitorElement::DQM_KIND_TH2F)
1412  {
1413  h2 = me->getTH2F(); // access Test histo
1414  }
1415  else
1416  {
1417  if (verbose_>0)
1418  std::cout << "QTest:ContentsWithinExpected"
1419  << " ME does not contain TH1F or TH2F, exiting\n";
1420  return -1;
1421  }
1422  int lastBinX = 0;
1423  int lastBinY = 0;
1424  float lastBinVal;
1425 
1426  //--------- do the quality test for 1D histo ---------------//
1427  if (h1 != NULL)
1428  {
1429  lastBinX = h1->FindLastBinAbove(_average,1);
1430  lastBinVal = h1->GetBinContent(lastBinX);
1431  if (h1->GetEntries() == 0 || lastBinVal < 0) return 1;
1432  }
1433  else if (h2 != NULL)
1434  {
1435 
1436  lastBinX = h2->FindLastBinAbove(_average,1);
1437  lastBinY = h2->FindLastBinAbove(_average,2);
1438  if ( h2->GetEntries() == 0 || lastBinX < 0 || lastBinY < 0 ) return 1;
1439  lastBinVal = h2->GetBinContent(h2->GetBin(lastBinX,lastBinY));
1440  } else {
1441  if (verbose_ > 0) std::cout << "QTest:"<< getAlgoName() << " Histogram does not exist" << std::endl;
1442  return 1;
1443  }
1444  if (verbose_ > 0) std::cout << "Min and Max values " << _min << " " << _max << " Av value " << _average << " lastBinX " << lastBinX<< " lastBinY " << lastBinY << " lastBinVal " << lastBinVal << std::endl;
1445  if (lastBinVal > _min && lastBinVal <= _max)
1446  return 1;
1447  else
1448  return 0;
1449 }
1450 //----------------------------------------------------//
1451 //--------------- CheckVariance ---------------------//
1452 //----------------------------------------------------//
1454 {
1455  badChannels_.clear();
1456 
1457  if (!me)
1458  return -1;
1459  if (!me->getRootObject())
1460  return -1;
1461  TH1* h=0;
1462 
1463  if (verbose_>1)
1464  std::cout << "QTest:" << getAlgoName() << "::runTest called on "
1465  << me-> getFullname() << "\n";
1466  // -- TH1F
1467  if (me->kind()==MonitorElement::DQM_KIND_TH1F )
1468  {
1469  h = me->getTH1F();
1470  }
1471  // -- TH1D
1472  else if ( me->kind()==MonitorElement::DQM_KIND_TH1D )
1473  {
1474  h = me->getTH1D();
1475  }
1476  else if (me->kind()==MonitorElement::DQM_KIND_TPROFILE)
1477  {
1478  h = me->getTProfile(); // access Test histo
1479  }
1480  else
1481  {
1482  if (verbose_>0) std::cout << "QTest:CheckVariance"
1483  << " ME " << me->getFullname()
1484  << " does not contain TH1F/TH1D/TPROFILE, exiting\n";
1485  return -1;
1486  }
1487 
1488  int ncx = h->GetXaxis()->GetNbins();
1489 
1490  double sum = 0;
1491  double sum2 = 0;
1492  for (int bin = 1; bin <= ncx; ++bin)
1493  {
1494  double contents = h->GetBinContent(bin);
1495  sum += contents;
1496  }
1497  if (sum==0) return -1;
1498  double avg = sum/ncx;
1499 
1500  for (int bin = 1; bin <= ncx; ++bin)
1501  {
1502  double contents = h->GetBinContent(bin);
1503  sum2 += (contents - avg)*(contents - avg);
1504  }
1505 
1506  double Variance = TMath::Sqrt(sum2/ncx);
1507  return Variance;
1508 }
TH1F * getRefTH1F(void) const
TH2S * getTH2S(void) const
TH1S * getTH1S(void) const
int i
Definition: DBlmapReader.cc:9
double getAverage(int bin, const TH1 *h) const
Definition: QTest.cc:843
void useRMS(void)
Definition: QTest.cc:1247
float runTest(const MonitorElement *me)
Definition: QTest.cc:547
float runTest(const MonitorElement *me)
Definition: QTest.cc:872
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
TProfile2D * getTProfile2D(void) const
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
float runTest(const MonitorElement *me)
Definition: QTest.cc:626
TH3F * getTH3F(void) const
TH1D * getTH1D(void) const
#define NULL
Definition: scimark2.h:8
void setRMSRange(double xmin, double xmax)
set expected value for mean
Definition: QTest.cc:1123
void useSigma(double expectedSigma)
Definition: QTest.cc:1236
TH2D * getTH2D(void) const
double getEntries(void) const
get # of entries
tuple s2
Definition: indexGen.py:106
TH3F * getRefTH3F(void) const
float runTest(const MonitorElement *me)
Definition: QTest.cc:293
float runTest(const MonitorElement *me)
Definition: QTest.cc:1395
T x() const
Cartesian x coordinate.
TH2F * getRefTH2F(void) const
T Abs(T a)
Definition: MathUtil.h:49
static const int DID_NOT_RUN
static const float ERROR_PROB_THRESHOLD
Definition: QTest.h:122
Kind kind(void) const
Get the type of the monitor element.
float runTest(const MonitorElement *me)
Definition: QTest.cc:747
const std::string getFullname(void) const
get full name of ME including Pathname
TH2D * getRefTH2D(void) const
void useRange(double xmin, double xmax)
Definition: QTest.cc:1226
T Max(T a, T b)
Definition: MathUtil.h:44
TObject * getRootObject(void) const
float runTest(const MonitorElement *me)
Definition: QTest.cc:163
virtual float runTest(const MonitorElement *me)
Definition: QTest.cc:27
TH1F * getTH1F(void) const
int average
Definition: PDRates.py:137
TProfile * getRefTProfile(void) const
void init(void)
initialize values
Definition: QTest.cc:17
void setMeanRange(double xmin, double xmax)
set expected value for mean
Definition: QTest.cc:1111
float runTest(const MonitorElement *me)
Definition: QTest.cc:1147
TProfile * getTProfile(void) const
TH2S * getRefTH2S(void) const
tuple cout
Definition: gather_cfg.py:145
float runTest(const MonitorElement *me)
Definition: QTest.cc:40
float runTest(const MonitorElement *me)
Definition: QTest.cc:1264
TH2F * getTH2F(void) const
void reset(double vett[256])
Definition: TPedValues.cc:11
TObject * getRefRootObject(void) const
TH1S * getRefTH1S(void) const
float runTest(const MonitorElement *me)
Definition: QTest.cc:1453
float runTest(const MonitorElement *me)
Definition: QTest.cc:477
static const float WARNING_PROB_THRESHOLD
default &quot;probability&quot; values for setting warnings &amp; errors when running tests
Definition: QTest.h:121
TH1D * getRefTH1D(void) const
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11