AliRoot Core  3dc7879 (3dc7879)
AliTPCCalibQAChecker.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
17 // //
18 // Class to process a tree and create alarms based on thresholds //
19 // origin: jens wiechula: jens.wiechula@cern.ch //
20 // //
22 
23 #include <iostream>
24 #include <TObjArray.h>
25 #include <TString.h>
26 #include <TObjString.h>
27 #include <TStyle.h>
28 #include <TMarker.h>
29 #include <TAxis.h>
30 #include <TLine.h>
31 #include <TList.h>
32 #include <TTree.h>
33 #include <TMath.h>
34 #include <TGraph.h>
35 #include <TFrame.h>
36 #include <TIterator.h>
37 #include <TPad.h>
38 #include <TCanvas.h>
39 #include <TH1.h>
40 #include <TH2.h>
41 #include <TStopwatch.h>
42 
43 #include <AliLog.h>
44 
45 #include "AliTPCCalibQAChecker.h"
46 
47 using namespace std;
48 
50  TNamed("AliTPCCalibQAChecker","AliTPCCalibQAChecker"),
51  fTreePtr(0x0),
52  fHistPtr(0x0),
53  fGraphPtr(0x0),
54  fNumberPtr(0x0),
55  fHist(0x0),
56  fIterSubCheckers(0x0),
57  fArrSubCheckers(0x0),
58  fArrAlarmDescriptions(0x0),
59  fStrDrawRep(""),
60  fStrDrawRepOpt(""),
61  fStrDraw(""),
62  fStrDrawOpt(""),
63  fStrCuts(""),
64  fAlarmType(kMean),
65  fQualityLevel(kINFO),
66  fHistRep(0x0)
67 {
68  //
69  // Default ctor
70  //
72 }
73 //_________________________________________________________________________
74 AliTPCCalibQAChecker::AliTPCCalibQAChecker(const char* name, const char *title) :
75  TNamed(name,title),
76  fTreePtr(0x0),
77  fHistPtr(0x0),
78  fGraphPtr(0x0),
79  fNumberPtr(0x0),
80  fHist(0x0),
81  fIterSubCheckers(0x0),
82  fArrSubCheckers(0x0),
84  fStrDrawRep(""),
85  fStrDrawRepOpt(""),
86  fStrDraw(""),
87  fStrDrawOpt(""),
88  fStrCuts(""),
91  fHistRep(0x0)
92 {
93  //
94  // TNamed ctor
95  //
97 }
98 //_________________________________________________________________________
100 {
101  //
102  // Default ctor
103  //
104  if (fHistRep) delete fHistRep;
107  if (fArrSubCheckers) delete fArrSubCheckers;
108 }
109 //_________________________________________________________________________
111 {
112  //
113  // add a sub checker to this checker
114  //
115  if (!alarm) return;
116  if (!fArrSubCheckers) {
118  fArrSubCheckers->SetOwner();
119  }
120  fArrSubCheckers->Add(alarm);
121 }
122 //_________________________________________________________________________
124 {
125  //
126  // Process the alarm thresholds, decide the alarm level, create the representation histogram
127  //
128 
129  //reset quality level
131 
132  TStopwatch s;
133  s.Start();
134  //decide which type of checker to use
135  if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0) ProcessSub();
136  else if (fTreePtr && *fTreePtr) ProcessTree();
137  else if (fHistPtr && *fHistPtr) ProcessHist();
138  else if (fGraphPtr && *fGraphPtr) ProcessGraph();
139  else if (fNumberPtr) ProcessNumber();
140  s.Stop();
141  AliInfo(Form("Processing Time (%s): %fs",GetName(),s.RealTime()));
142 }
143 //_________________________________________________________________________
145 {
146  //
147  // sub checker type checker
148  //
149  QualityFlag_t quality=kINFO;
150  if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
151  TIter next(fArrSubCheckers);
152  TObject *o=0x0;
153  while ( (o=next()) ) {
155  al->Process();
156  QualityFlag_t subQuality=al->GetQuality();
157  if (subQuality>quality) quality=subQuality;
158  }
159  }
160  fQualityLevel=quality;
161 }
162 //_________________________________________________________________________
164 {
165  //
166  // process tree type checker
167  //
168 
169  //Create Representation Histogram
171  //
172 // if (!fTree) return;
173  //chek for the quality
174 
175  switch (fAlarmType){
176  case kNentries:
177  ProcessEntries();
178  break;
179  case kMean:
180  case kBinAny:
181  case kBinAll:
182  CreateAlarmHist();
183  ProcessHist();
184  ResetAlarmHist();
185  break;
186  }
187 
188 }
189 //_________________________________________________________________________
191 {
192  //
193  // process histogram type checker
194  //
195 
196  if (!(fHistPtr && *fHistPtr)) return;
197 
198  switch (fAlarmType){
199  case kNentries:
200  case kMean:
201  ProcessMean();
202  break;
203  case kBinAny:
204  case kBinAll:
205  ProcessBin();
206  break;
207  }
208 
209  //create representation histogram if we are not in tree mode
210  if (!fTreePtr){
211  if (!fHistRep) {
212  fHistRep=(*fHistPtr)->Clone();
213  TH1* h=(TH1*)fHistRep;
214  h->SetDirectory(0);
215  h->SetNameTitle(Form("h%s",GetName()),GetTitle());
216  }
217  TH1* h=(TH1*)fHistRep;
218  h->Reset();
219  h->Add(*fHistPtr);
220  if (!fHistRep->InheritsFrom(TH2::Class())) AddQualityLines(h);
221  }
222 }
223 //_________________________________________________________________________
225 {
226  //
227  // process graph type checker
228  //
229  if (!(fGraphPtr && *fGraphPtr)) return;
230  Int_t npoints=(*fGraphPtr)->GetN();
231  fQualityLevel=GetQuality(npoints,(*fGraphPtr)->GetY());
232 }
233 //_________________________________________________________________________
235 {
236  //
237  // process number type checker
238  //
239  if (!fNumberPtr) return;
241  //create representation histogram
242  if (!fHistRep){
243  TH1* h=new TH1F(Form("h%s",GetName()),GetTitle(),1,0,1);
244  h->GetXaxis()->SetBinLabel(1,"Value");
245  AddQualityLines(h);
246  h->SetDirectory(0);
247  fHistRep=h;
248  }
249  TH1 *h=(TH1*)fHistRep;
250  TMarker *marker=(TMarker*)h->GetListOfFunctions()->FindObject("TMarker");
251  if (!marker) {
252  marker=new TMarker(.5,0,20);
253  h->GetListOfFunctions()->Add(marker);
254  }
255  marker->SetMarkerColor(GetQualityColor());
256  marker->SetY(*fNumberPtr);
257 }
258 //_________________________________________________________________________
260 {
261  //
262  // Processing function which analyses the number of affected rows of a tree draw
263  //
264  TString draw=fStrDraw;
265  if (draw.IsNull()) return;
266 
267  TString cuts=fStrCuts;
268 
269  TString opt=fStrDrawOpt;
270  opt+="goff";
271 
272  //draw and get the histogram
273  Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
275 }
276 //_________________________________________________________________________
278 {
279  //
280  // Processing function which analyses the mean of the resulting histogram
281  //
282 
283  TH1* h=(*fHistPtr);
284  Double_t value=h->GetMean();
285  if (fAlarmType==kNentries) value=h->GetEntries();
286  fQualityLevel=GetQuality(value);
287 }
288 //_________________________________________________________________________
290 {
291  //
292  // Process a histogram bin by bin and check for thresholds
293  //
294 
295  //bin quality counters
296  Int_t nquality[kNQualityFlags];
297  for (Int_t iquality=(Int_t)kINFO; iquality<kNQualityFlags; ++iquality) nquality[iquality]=0;
298 
299  TH1 *h=(*fHistPtr);
300 
301  Int_t nbinsX=h->GetNbinsX();
302  Int_t nbinsY=h->GetNbinsY();
303  Int_t nbinsZ=h->GetNbinsZ();
304  Int_t nbinsTotal=nbinsX*nbinsY*nbinsZ;
305 
306  //loop over all bins
307  for (Int_t ibinZ=1;ibinZ<nbinsZ+1;++ibinZ){
308  for (Int_t ibinY=1;ibinY<nbinsY+1;++ibinY){
309  for (Int_t ibinX=1;ibinX<nbinsX+1;++ibinX){
310  Double_t value = (*fHistPtr)->GetBinContent(ibinX, ibinY, ibinZ);
311  QualityFlag_t quality=GetQuality(value);
312  nquality[quality]++;
313  }
314  }
315  }
316 
317  //loop over Quality levels and set quality
318  for (Int_t iquality=(Int_t)kINFO; iquality<kNQualityFlags; ++iquality){
319  if (fAlarmType==kBinAny){
320  if (nquality[iquality]) fQualityLevel=(QualityFlag_t)iquality;
321  } else if (fAlarmType==kBinAll){
322  if (nquality[iquality]==nbinsTotal) fQualityLevel=(QualityFlag_t)iquality;
323  }
324  }
325 }
326 //_________________________________________________________________________
328 {
329  //
330  // Create the representation histogram which will be shown in the draw function
331  //
333 
334  TString draw=fStrDrawRep;
335  if (draw.IsNull()) {
336  draw=fStrDraw;
338  } else {
339  draw.ReplaceAll("%alarm%",fStrDraw.Data());
340  }
341  if (draw.IsNull()) return;
342 
343  TString cuts=fStrCuts;
344 
345  TString opt=fStrDrawRepOpt;
346  opt+="goff";
347 
348  Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
349  TH1 *hist=(*fTreePtr)->GetHistogram();
350  if (res<0 || !hist){
351  AliError(Form("Could not create representation histogram of alarm '%s'",GetName()));
352  return;
353  }
354  fHistRep=hist->Clone();
355  TH1 *h=(TH1*)fHistRep;
356  h->SetDirectory(0);
357  h->SetNameTitle(Form("h%s",GetName()),GetTitle());
358 }
359 //_________________________________________________________________________
361 {
362  //
363  // create alarm histogram from the tree
364  //
365 
366  TString draw=fStrDraw;
367  if (draw.IsNull()) return;
368 
369  TString cuts=fStrCuts;
370 
371  TString opt=fStrDrawOpt;
372  opt+="goff";
373 
374  //draw and get the histogram
375  Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
376  fHist=(*fTreePtr)->GetHistogram();
377  if (res<0 || !fHist){
378  AliError(Form("Could not create alarm histogram of alarm '%s'",GetName()));
379  return;
380  }
381  fHist->SetDirectory(0);
382  fHistPtr=&fHist;
383 }
384 //_________________________________________________________________________
386 {
387  //
388  // delete the alarm histogram and reset the pointer
389  //
390  if (fHistPtr){
391  if (*fHistPtr) delete *fHistPtr;
392  fHistPtr=0x0;
393  }
394 }
395 //_________________________________________________________________________
396 void AliTPCCalibQAChecker::Draw(Option_t *option)
397 {
398  //
399  // object draw function
400  // by default the pad backgound color is set to the quality level color
401  // use 'nobc' to change this
402  //
403 
404  //case of a node with subcheckers and no specific representation histogram
405  if (HasSubCheckers()&&!fHistRep) {DrawSubNodes(option); return;}
406  if (fHistRep) {DrawRepresentationHist(option); return;}
407 }
408 //_________________________________________________________________________
409 void AliTPCCalibQAChecker::Print(Option_t * const option) const
410 {
411  //
412  // print the quality status. If we have sub checkers print recursively
413  //
414  TString sOpt(option);
415  cout << sOpt << GetName() << ": " << GetQualityName() << endl;
416  if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
417  sOpt.ReplaceAll("+-"," ");
418  sOpt+="+-";
419  TIter next(fArrSubCheckers);
420  TObject *o=0x0;
421  while ( (o=next()) ) o->Print(sOpt.Data());
422  }
423 }
424 //_________________________________________________________________________
425 void AliTPCCalibQAChecker::SetAlarmThreshold(Double_t min, Double_t max, QualityFlag_t quality)
426 {
427  //
428  //set the alarm thresholds for a specific quality level
429  //
430  if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
431  fThresMin[quality]=min;
432  fThresMax[quality]=max;
433 }
434 //_________________________________________________________________________
436 {
437  //
438  //set the alarm thresholds for a specific quality level
439  //
440  if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
441  fThresMin[quality]=0;
442  fThresMax[quality]=0;
443 }
444 //_________________________________________________________________________
446 {
447  //
448  //reset all the alarm thresholds
449  //
450  for (Int_t i=0;i<kNQualityFlags;++i){
451  fThresMin[i]=0;
452  fThresMax[i]=0;
453  }
454 }
455 //_________________________________________________________________________
457 {
458  //
459  // set an description for the quality level
460  // %min and %max will be replaced by the min and max values of the alarm, when the quality
461  // description is queried (see QualityDescription)
462  //
463 
464  if (quality<kINFO||quality>kFATAL) return;
466  TObjString *s=(TObjString*)fArrAlarmDescriptions->At(quality);
467  if (!s) fArrAlarmDescriptions->AddAt(s=new TObjString,quality);
468  s->SetString(text);
469 }
470 
471 //_________________________________________________________________________
472 const AliTPCCalibQAChecker* AliTPCCalibQAChecker::GetSubChecker(const char* name, Bool_t recursive) const
473 {
474  //
475  // Return subnode with 'name'
476  //
477  TString sname(name);
478  if (sname==GetName()) return this;
479  if (!fArrSubCheckers || !fArrSubCheckers->GetEntries()) return 0x0;
480  const AliTPCCalibQAChecker *al=0x0;
481  if (recursive){
482  TIter next(fArrSubCheckers);
483  TObject *o=0x0;
484  while ( (o=next()) ){
486  al=sal->GetSubChecker(name);
487  if (al) break;
488  }
489  }else{
490  al=dynamic_cast<AliTPCCalibQAChecker*>(fArrSubCheckers->FindObject(name));
491  }
492  return al;
493 }
494 //_________________________________________________________________________
495 Int_t AliTPCCalibQAChecker::GetNumberOfSubCheckers(Bool_t recursive) const
496 {
497  //
498  // get the number of sub checkers
499  // if recursive get total number of non subchecker type sub checkers
500  //
501  Int_t nsub=0;
502  if (recursive){
503  if (!fArrSubCheckers) return 1;
504  if (!fArrSubCheckers->GetEntries()) return 0;
505  TIter next(fArrSubCheckers);
506  TObject *o=0x0;
507  while ( (o=next()) ){
509  nsub+=al->GetNumberOfSubCheckers();
510  }
511  } else {
512  if (fArrSubCheckers) nsub=fArrSubCheckers->GetEntries();
513  }
514  return nsub;
515 }
516 //_________________________________________________________________________
518 {
519  //
520  // loop over sub checkers
521  // if recursive, recursively return the pointers of non subchecker type sub checkers
522  //
523  if (!fArrSubCheckers || !fArrSubCheckers->GetEntries()) return 0;
524  if (!fIterSubCheckers) fIterSubCheckers=fArrSubCheckers->MakeIterator();
526  if (!al){
527  delete fIterSubCheckers;
528  fIterSubCheckers=0x0;
529  }
530 // if (recursive && al->GetNumberOfSubCheckers(kFALSE)) al=al->NextSubChecker();
531  return al;
532 }
533 //_________________________________________________________________________
535 {
536  //
537  // get quality name for quality
538  //
539  switch (quality){
540  case kINFO:
541  return "Info";
542  break;
543  case kWARNING:
544  return "Warning";
545  break;
546  case kERROR:
547  return "Error";
548  break;
549  case kFATAL:
550  return "Fatal";
551  break;
552  default:
553  return "";
554  }
555 }
556 //_________________________________________________________________________
558 {
559  //
560  // get quality color for quality
561  //
562  Color_t info = kSpring-8;
563  Color_t warning = kOrange;
564  Color_t error = kRed;
565  Color_t fatal = kRed+2;
566  Color_t none = kWhite;
567 
568  switch(quality) {
569  case kINFO :
570  return info;
571  break;
572  case kWARNING :
573  return warning;
574  break;
575  case kERROR :
576  return error;
577  break;
578  case kFATAL :
579  return fatal;
580  break;
581  default:
582  return none;
583  }
584  return none;
585 
586 }
587 //_________________________________________________________________________
589 {
590  //
591  // return description for quality
592  //
593  if (!fArrAlarmDescriptions || !fArrAlarmDescriptions->At(quality)) return "";
594  TString s(fArrAlarmDescriptions->At(quality)->GetName());
595  TString min, max;
596  min+=fThresMin[quality];
597  max+=fThresMax[quality];
598  s.ReplaceAll("%min",min);
599  s.ReplaceAll("%max",max);
600  return s.Data();
601 }
602 //_________________________________________________________________________
603 Int_t AliTPCCalibQAChecker::DrawInPad(TVirtualPad *pad, Int_t sub)
604 {
605  //
606  // Draw recursively in 'pad'
607  //
608 
609  if (fArrSubCheckers){
610  if (fArrSubCheckers->GetEntries()>0){
611  TIter next(fArrSubCheckers);
612  TObject *o=0x0;
613  while ( (o=next()) ) {
615  sub=al->DrawInPad(pad,sub);
616  }
617  }
618  } else {
619  pad->cd(sub);
620  ++sub;
621  Draw();
622  }
623  return sub;
624 }
625 //_________________________________________________________________________
626 void AliTPCCalibQAChecker::DrawSubNodes(Option_t */*option*/)
627 {
628  //
629  // divide the current pad in sub pads and draw all sub nodes
630  //
631  if (!gPad) new TCanvas;
632  TPad *mother=(TPad*)gPad;
633  mother->Clear();
634  //find number of sub pads needed
635  Int_t nPads = GetNumberOfSubCheckers();
636  Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
637  Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
638  gPad->Divide(nCols,nRows);
639 
640  DrawInPad(gPad);
641  mother->Update();
642  TPad *pad=0;
643  Int_t ipad=1;
644  while ( (pad=(TPad*)mother->GetPad(ipad)) ){
645  TFrame* frame=(TFrame*)pad->GetPrimitive("TFrame");
646  if (frame) frame->SetFillColor(kWhite);
647  else {printf("no frame\n");}
648  pad->Modified();
649  ++ipad;
650  }
651  mother->Update();
652 }
653 //_________________________________________________________________________
655 {
656  //
657  // Draw the representation histogram
658  //
659  if (!fHistRep) return;
660  if (!gPad) new TCanvas;
661  Bool_t withBackColor=kTRUE;
662 
663  TString opt=option;
664  opt.ToLower();
665 
666  if (opt.Contains("nobc")) withBackColor=kFALSE;
667  opt.ReplaceAll("nobc","");
668 
669  if (opt.IsNull()) opt=fStrDrawRepOpt;
670  opt.ToLower();
671 
672  opt.ReplaceAll("prof","");
673 
674  fHistRep->Draw(opt.Data());
675  if (withBackColor) {
676  gPad->SetFillColor(GetQualityColor());
677  }
678 
679  gPad->Modified();
680 }
681 //_________________________________________________________________________
683 {
684  //
685  // add lines indicating the quality level to hist
686  //
687 
688  Double_t xmin=hist->GetXaxis()->GetXmin();
689  Double_t xmax=hist->GetXaxis()->GetXmax();
690  Double_t min=0;
691  Double_t max=0;
692 
693  for (Int_t i=(Int_t)kINFO; i<kNQualityFlags; ++i){
694  if (fThresMin[i]>=fThresMax[i]) continue;
695  min=fThresMin[i];
696  max=fThresMax[i];
697  TLine *lmin=new TLine(xmin,min,xmax,min);
698  lmin->SetLineWidth(2);
699  lmin->SetLineColor(QualityColor((QualityFlag_t)i));
700  TLine *lmax=new TLine(xmin,max,xmax,max);
701  lmax->SetLineWidth(2);
702  lmax->SetLineColor(QualityColor((QualityFlag_t)i));
703  hist->GetListOfFunctions()->Add(lmin);
704  hist->GetListOfFunctions()->Add(lmax);
705  }
706  hist->SetAxisRange(min,max,"Y");
707 }
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
void DrawRepresentationHist(const Option_t *option)
void SetQualityDescription(const char *text, QualityFlag_t quality=kERROR)
#define TObjArray
Int_t DrawInPad(TVirtualPad *pad, Int_t sub=1)
Double_t * fNumberPtr
Pointer to the graph pointer.
Int_t GetNumberOfSubCheckers(Bool_t recursive=kTRUE) const
Color_t GetQualityColor() const
virtual void Print(Option_t *option="") const
npoints
Definition: driftITSTPC.C:85
const AliTPCCalibQAChecker * GetSubChecker(const char *name, Bool_t recursive=kTRUE) const
static const char * QualityName(AliTPCCalibQAChecker::QualityFlag_t quality)
const char * QualityDescription(QualityFlag_t quality) const
AliExternalInfo info
AliTPCCalibQAChecker * NextSubChecker()
TH1 ** fHistPtr
Pointer to the Tree pointer.
QualityFlag_t GetQuality() const
TH1 * fHist
Pointer to number.
Double_t fThresMax[kNQualityFlags]
TObjArray * fArrSubCheckers
iterator over sub checkers
void DrawSubNodes(Option_t *option)
#define AliInfo(message)
Definition: AliLog.h:484
void SetAlarmThreshold(Double_t min, Double_t max, QualityFlag_t quality=kERROR)
TGraph ** fGraphPtr
Pointer to the hist pointer.
Double_t fThresMin[kNQualityFlags]
const char * GetQualityName() const
void AddSubChecker(AliTPCCalibQAChecker *alarm)
void ResetAlarmThreshold(QualityFlag_t quality)
#define AliError(message)
Definition: AliLog.h:591
Bool_t HasSubCheckers() const
void res(Char_t i)
Definition: Resolution.C:2
virtual void Draw(Option_t *option="")
static Color_t QualityColor(AliTPCCalibQAChecker::QualityFlag_t quality)
TIterator * fIterSubCheckers
Hist pointer for tree processing.