]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCCalibQAChecker.cxx
Adding alarms and graphical representation of alarms
[u/mrichter/AliRoot.git] / TPC / AliTPCCalibQAChecker.cxx
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
16 ///////////////////////////////////////////////////////////////////////////////
17 //                                                                           //
18 //  Class to process a tree and create alarms based on thresholds            //
19 //  origin: jens wiechula: jens.wiechula@cern.ch                             //
20 //                                                                           //
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include <iostream>
24 #include <TObjArray.h>
25 #include <TString.h>
26 #include <TObjString.h>
27 #include <TTree.h>
28 #include <TGraph.h>
29 #include <TFrame.h>
30 #include <TIterator.h>
31 #include <TPad.h>
32 #include <TH1.h>
33 #include <TH2.h>
34 #include <TStopwatch.h>
35
36 #include <AliLog.h>
37
38 #include "AliTPCCalibQAChecker.h"
39
40 using namespace std;
41
42 AliTPCCalibQAChecker::AliTPCCalibQAChecker() :
43   TNamed("AliTPCCalibQAChecker","AliTPCCalibQAChecker"),
44   fTreePtr(0x0),
45   fHistPtr(0x0),
46   fGraphPtr(0x0),
47   fNumberPtr(0x0),
48   fHist(0x0),
49   fIterSubCheckers(0x0),
50   fArrSubCheckers(0x0),
51   fArrAlarmDescriptions(0x0),
52   fStrDrawRep(""),
53   fStrDrawRepOpt(""),
54   fStrDraw(""),
55   fStrDrawOpt(""),
56   fStrCuts(""),
57   fAlarmType(kMean),
58   fQualityLevel(kINFO),
59   fHistRep(0x0)
60 {
61   //
62   // Default ctor
63   //
64   ResetAlarmThresholds();
65 }
66 //_________________________________________________________________________
67 AliTPCCalibQAChecker::AliTPCCalibQAChecker(const char* name, const char *title) :
68   TNamed(name,title),
69   fTreePtr(0x0),
70   fHistPtr(0x0),
71   fGraphPtr(0x0),
72   fNumberPtr(0x0),
73   fHist(0x0),
74   fIterSubCheckers(0x0),
75   fArrSubCheckers(0x0),
76   fArrAlarmDescriptions(0x0),
77   fStrDrawRep(""),
78   fStrDrawRepOpt(""),
79   fStrDraw(""),
80   fStrDrawOpt(""),
81   fStrCuts(""),
82   fAlarmType(kMean),
83   fQualityLevel(kINFO),
84   fHistRep(0x0)
85 {
86   //
87   // TNamed ctor
88   //
89   ResetAlarmThresholds();
90 }
91 //_________________________________________________________________________
92 AliTPCCalibQAChecker::~AliTPCCalibQAChecker()
93 {
94   //
95   // Default ctor
96   //
97   if (fHistRep) delete fHistRep;
98   if (fIterSubCheckers) delete fIterSubCheckers;
99   if (fArrAlarmDescriptions) delete fArrAlarmDescriptions;
100 }
101 //_________________________________________________________________________
102 void AliTPCCalibQAChecker::AddSubChecker(AliTPCCalibQAChecker *alarm)
103 {
104   //
105   // add a sub checker to this checker
106   //
107   if (!alarm) return;
108   if (!fArrSubCheckers) {
109     fArrSubCheckers=new TObjArray;
110     fArrSubCheckers->SetOwner();
111   }
112   fArrSubCheckers->Add(alarm);
113 }
114 //_________________________________________________________________________
115 void AliTPCCalibQAChecker::Process()
116 {
117   //
118   // Process the alarm thresholds, decide the alarm level, create the representation histogram
119   //
120
121   //reset quality level
122   fQualityLevel=kINFO;
123
124   TStopwatch s;
125   s.Start();
126   //decide which type of checker to use
127   if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0) ProcessSub();
128   else if (fTreePtr && *fTreePtr) ProcessTree();
129   else if (fHistPtr && *fHistPtr) ProcessHist();
130   else if (fGraphPtr && *fGraphPtr) ProcessGraph();
131   else if (fNumberPtr) ProcessNumber();
132   s.Stop();
133   AliInfo(Form("Processing Time (%s): %fs",GetName(),s.RealTime()));
134 }
135 //_________________________________________________________________________
136 void AliTPCCalibQAChecker::ProcessSub()
137 {
138   //
139   // sub checker type checker
140   //
141   QualityFlag_t quality=kINFO;
142   if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
143     TIter next(fArrSubCheckers);
144     TObject *o=0x0;
145     while ( (o=next()) ) {
146       AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
147       al->Process();
148       QualityFlag_t subQuality=al->GetQuality();
149       if (subQuality>quality) quality=subQuality;
150     }
151   }
152   fQualityLevel=quality;
153 }
154 //_________________________________________________________________________
155 void AliTPCCalibQAChecker::ProcessTree()
156 {
157   //
158   // process tree type checker
159   //
160
161   //Create Representation Histogram
162   CreateRepresentationHist();
163   //
164 //   if (!fTree) return;
165   //chek for the quality
166
167   switch (fAlarmType){
168   case kNentries:
169     ProcessEntries();
170     break;
171   case kMean:
172   case kBinAny:
173   case kBinAll:
174     CreateAlarmHist();
175     ProcessHist();
176     ResetAlarmHist();
177     break;
178   }
179   
180 }
181 //_________________________________________________________________________
182 void AliTPCCalibQAChecker::ProcessHist()
183 {
184   //
185   // process histogram type checker
186   //
187   
188   if (!(fHistPtr && *fHistPtr)) return;
189     
190   switch (fAlarmType){
191   case kNentries:
192   case kMean:
193     ProcessMean();
194     break;
195   case kBinAny:
196   case kBinAll:
197     ProcessBin();
198     break;
199   }
200 }
201 //_________________________________________________________________________
202 void AliTPCCalibQAChecker::ProcessGraph()
203 {
204   //
205   // process graph type checker
206   //
207   if (!(fGraphPtr && *fGraphPtr)) return;
208   Int_t npoints=(*fGraphPtr)->GetN();
209   fQualityLevel=GetQuality(npoints,(*fGraphPtr)->GetY());
210 }
211 //_________________________________________________________________________
212 void AliTPCCalibQAChecker::ProcessNumber()
213 {
214   //
215   // process number type checker
216   //
217   if (!fNumberPtr) return;
218   fQualityLevel=GetQuality(*fNumberPtr);
219 }
220 //_________________________________________________________________________
221 void AliTPCCalibQAChecker::ProcessEntries()
222 {
223   //
224   // Processing function which analyses the number of affected rows of a tree draw
225   //
226   TString draw=fStrDraw;
227   if (draw.IsNull()) return;
228   
229   TString cuts=fStrCuts;
230   
231   TString opt=fStrDrawOpt;
232   opt+="goff";
233   
234   //draw and get the histogram
235   Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
236   fQualityLevel=GetQuality(res);
237 }
238 //_________________________________________________________________________
239 void AliTPCCalibQAChecker::ProcessMean()
240 {
241   //
242   // Processing function which analyses the mean of the resulting histogram
243   //
244
245   TH1* h=(*fHistPtr);
246   Double_t value=h->GetMean();
247   if (fAlarmType==kNentries) value=h->GetEntries();
248   fQualityLevel=GetQuality(value);
249 }
250 //_________________________________________________________________________
251 void AliTPCCalibQAChecker::ProcessBin()
252 {
253   //
254   // Process a histogram bin by bin and check for thresholds
255   //
256
257   //bin quality counters
258   Int_t nquality[kNQualityFlags];
259   for (Int_t iquality=(Int_t)kINFO; iquality<kNQualityFlags; ++iquality) nquality[iquality]=0;
260     
261   TH1 *h=(*fHistPtr);
262   
263   Int_t nbinsX=h->GetNbinsX();
264   Int_t nbinsY=h->GetNbinsY();
265   Int_t nbinsZ=h->GetNbinsZ();
266   Int_t nbinsTotal=nbinsX*nbinsY*nbinsZ;
267
268   //loop over all bins
269   for (Int_t ibinZ=1;ibinZ<nbinsZ+1;++ibinZ){
270     for (Int_t ibinY=1;ibinY<nbinsY+1;++ibinY){
271       for (Int_t ibinX=1;ibinX<nbinsX+1;++ibinX){
272         Double_t value = (*fHistPtr)->GetBinContent(ibinX, ibinY, ibinZ);
273         QualityFlag_t quality=GetQuality(value);
274         nquality[quality]++;
275       }
276     }
277   }
278
279   //loop over Quality levels and set quality
280   for (Int_t iquality=(Int_t)kINFO; iquality<kNQualityFlags; ++iquality){
281     if (fAlarmType==kBinAny){
282       if (nquality[iquality]) fQualityLevel=(QualityFlag_t)iquality;
283     } else if (fAlarmType==kBinAll){
284       if (nquality[iquality]==nbinsTotal) fQualityLevel=(QualityFlag_t)iquality;
285     }
286   }
287 }
288 //_________________________________________________________________________
289 void AliTPCCalibQAChecker::CreateRepresentationHist()
290 {
291   //
292   // Create the representation histogram which will be shown in the draw function
293   //
294   ResetRepresentationHist();
295
296   TString draw=fStrDrawRep;
297   if (draw.IsNull()) {
298     draw=fStrDraw;
299     fStrDrawRepOpt=fStrDrawOpt;
300   } else {
301     draw.ReplaceAll("%alarm%",fStrDraw.Data());
302   }
303   if (draw.IsNull()) return;
304   
305   TString cuts=fStrCuts;
306   
307   TString opt=fStrDrawRepOpt;
308   opt+="goff";
309   
310   Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
311   TH1 *hist=(*fTreePtr)->GetHistogram();
312   if (res<0 || !hist){
313     AliError(Form("Could not create representation histogram of alarm '%s'",GetName()));
314     return;
315   }
316   fHistRep=(TH1*)hist->Clone();
317   fHistRep->SetDirectory(0);
318 }
319 //_________________________________________________________________________
320 void AliTPCCalibQAChecker::CreateAlarmHist()
321 {
322   //
323   // create alarm histogram from the tree
324   //
325     
326   TString draw=fStrDraw;
327   if (draw.IsNull()) return;
328   
329   TString cuts=fStrCuts;
330   
331   TString opt=fStrDrawOpt;
332   opt+="goff";
333   
334   //draw and get the histogram
335   Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
336   fHist=(*fTreePtr)->GetHistogram();
337   if (res<0 || !fHist){
338     AliError(Form("Could not create alarm histogram of alarm '%s'",GetName()));
339     return;
340   }
341   fHist->SetDirectory(0);
342   fHistPtr=&fHist;
343 }
344 //_________________________________________________________________________
345 void AliTPCCalibQAChecker::ResetAlarmHist()
346 {
347   //
348   // delete the alarm histogram and reset the pointer
349   //
350   if (fHistPtr){
351     if (*fHistPtr) delete *fHistPtr;
352     fHistPtr=0x0;
353   }
354 }
355 //_________________________________________________________________________
356 void AliTPCCalibQAChecker::Draw(Option_t *option)
357 {
358   //
359   // object draw function
360   // by default the pad backgound color is set to the quality level color
361   // use 'nobc' to change this
362   //
363
364   if (!fHistRep) return;
365   
366   Bool_t withBackColor=kTRUE;
367   
368   TString opt=option;
369   opt.ToLower();
370   
371   if (opt.Contains("nobc")) withBackColor=kFALSE;
372   opt.ReplaceAll("nobc","");
373   
374   if (opt.IsNull()) opt=fStrDrawRepOpt;
375   opt.ToLower();
376   
377   opt.ReplaceAll("prof","");
378   
379   fHistRep->Draw(opt.Data());
380   
381   if (gPad){
382     gPad->Modified();
383     if (withBackColor) gPad->SetFillColor(GetQualityColor());
384     TFrame* frame=(TFrame*)gPad->GetPrimitive("TFrame");
385     if (frame) frame->SetFillColor(kWhite);
386   }
387   
388   gPad->Modified();
389 }
390 //_________________________________________________________________________
391 void AliTPCCalibQAChecker::Print(Option_t *option) const
392 {
393   //
394   // print the quality status. If we have sub checkers print recursively
395   //
396   TString sOpt(option);
397   cout << sOpt << GetName() << ": " << GetQualityName() << endl;
398   if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
399     sOpt.ReplaceAll("+-","  ");
400     sOpt+="+-";
401     TIter next(fArrSubCheckers);
402     TObject *o=0x0;
403     while ( (o=next()) ) o->Print(sOpt.Data());
404   }
405 }
406 //_________________________________________________________________________
407 void AliTPCCalibQAChecker::SetAlarmThreshold(const Double_t min, const Double_t max, const QualityFlag_t quality)
408 {
409   //
410   //set the alarm thresholds for a specific quality level
411   //
412   if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
413   fThresMin[quality]=min;
414   fThresMax[quality]=max;
415 }
416 //_________________________________________________________________________
417 void AliTPCCalibQAChecker::ResetAlarmThreshold(const QualityFlag_t quality)
418 {
419   //
420   //set the alarm thresholds for a specific quality level
421   //
422   if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
423   fThresMin[quality]=0;
424   fThresMax[quality]=0;
425 }
426 //_________________________________________________________________________
427 void AliTPCCalibQAChecker::ResetAlarmThresholds()
428 {
429   //
430   //reset all the alarm thresholds
431   //
432   for (Int_t i=0;i<kNQualityFlags;++i){
433     fThresMin[i]=0;
434     fThresMax[i]=0;
435   }
436 }
437 //_________________________________________________________________________
438 void AliTPCCalibQAChecker::SetQualityDescription(const char* text, const QualityFlag_t quality)
439 {
440   //
441   // set an description for the quality level
442   // %min and %max will be replaced by the min and max values of the alarm, when the quality
443   // description is queried (see QualityDescription)
444   //
445
446   if (quality<kINFO||quality>kFATAL) return;
447   if (! fArrAlarmDescriptions ) fArrAlarmDescriptions=new TObjArray(kNQualityFlags);
448   TObjString *s=(TObjString*)fArrAlarmDescriptions->At(quality);
449   if (!s) fArrAlarmDescriptions->AddAt(s=new TObjString,quality);
450   s->SetString(text);
451 }
452
453 //_________________________________________________________________________
454 const AliTPCCalibQAChecker* AliTPCCalibQAChecker::GetSubChecker(const char* name, Bool_t recursive) const
455 {
456   //
457   //
458   //
459   TString sname(name);
460   if (sname==GetName()) return this;
461   if (!fArrSubCheckers || !fArrSubCheckers->GetEntries()) return 0x0;
462   const AliTPCCalibQAChecker *al=0x0;
463   if (recursive){
464     TIter next(fArrSubCheckers);
465     TObject *o=0x0;
466     while ( (o=next()) ){
467       AliTPCCalibQAChecker *sal=(AliTPCCalibQAChecker*)o;
468       al=sal->GetSubChecker(name);
469       if (al) break;
470     }
471   }else{
472     al=dynamic_cast<AliTPCCalibQAChecker*>(fArrSubCheckers->FindObject(name));
473   }
474   return al;
475 }
476 //_________________________________________________________________________
477 Int_t AliTPCCalibQAChecker::GetNumberOfSubCheckers(Bool_t recursive) const
478 {
479   //
480   // get the number of sub checkers
481   // if recursive get total number of non subchecker type sub checkers
482   //
483   Int_t nsub=0;
484   if (recursive){
485     if (!fArrSubCheckers) return 1;
486     if (!fArrSubCheckers->GetEntries()) return 0;
487     TIter next(fArrSubCheckers);
488     TObject *o=0x0;
489     while ( (o=next()) ){
490       AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
491       nsub+=al->GetNumberOfSubCheckers();
492     }
493   } else {
494     if (fArrSubCheckers) nsub=fArrSubCheckers->GetEntries();
495   }
496   return nsub;
497 }
498 //_________________________________________________________________________
499 AliTPCCalibQAChecker* AliTPCCalibQAChecker::NextSubChecker()
500 {
501   //
502   // loop over sub checkers
503   // if recursive, recursively return the pointers of non subchecker type sub checkers
504   //
505   if (!fArrSubCheckers && !fArrSubCheckers->GetEntries()) return 0;
506   if (!fIterSubCheckers) fIterSubCheckers=fArrSubCheckers->MakeIterator();
507   AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)fIterSubCheckers->Next();
508   if (!al){
509     delete fIterSubCheckers;
510     fIterSubCheckers=0x0;
511   }
512 //   if (recursive && al->GetNumberOfSubCheckers(kFALSE)) al=al->NextSubChecker();
513   return al;
514 }
515 //_________________________________________________________________________
516 const char* AliTPCCalibQAChecker::QualityName(const AliTPCCalibQAChecker::QualityFlag_t quality)
517 {
518   //
519   // get quality name for quality
520   //
521   switch (quality){
522   case kINFO:
523     return "Info";
524     break;
525   case kWARNING:
526     return "Warning";
527     break;
528   case kERROR:
529     return "Error";
530     break;
531   case kFATAL:
532     return "Fatal";
533     break;
534   default:
535     return "";
536   }
537 }
538 //_________________________________________________________________________
539 Color_t AliTPCCalibQAChecker::QualityColor(const AliTPCCalibQAChecker::QualityFlag_t quality)
540 {
541   //
542   // get quality color for quality
543   //
544   Color_t info = kSpring-8;
545   Color_t warning = kOrange;
546   Color_t error = kRed;
547   Color_t fatal = kRed+2;
548   Color_t none = kWhite;
549   
550   switch(quality) {
551   case kINFO :
552     return info;
553     break;
554   case kWARNING :
555     return warning;
556     break;
557   case kERROR :
558     return error;
559     break;
560   case kFATAL :
561     return fatal;
562     break;
563   default:
564     return none;
565   }
566   return none;
567   
568 }
569 //_________________________________________________________________________
570 const char* AliTPCCalibQAChecker::QualityDescription(const QualityFlag_t quality) const
571 {
572   //
573   // return description for quality
574   //
575   if (!fArrAlarmDescriptions || !fArrAlarmDescriptions->At(quality)) return "";
576   TString s(fArrAlarmDescriptions->At(quality)->GetName());
577   TString min, max;
578   min+=fThresMin[quality];
579   max+=fThresMax[quality];
580   s.ReplaceAll("%min",min);
581   s.ReplaceAll("%max",max);
582   return s.Data();
583 }
584 //_________________________________________________________________________
585 Int_t AliTPCCalibQAChecker::DrawInPad(TPad *pad, Int_t sub)
586 {
587   //
588   //
589   //
590   
591   if (fArrSubCheckers){
592     if (fArrSubCheckers->GetEntries()>0){
593       TIter next(fArrSubCheckers);
594       TObject *o=0x0;
595       while ( (o=next()) ) {
596         AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
597         sub=al->DrawInPad(pad,sub);
598       }
599     }
600   } else {
601     pad->cd(sub);
602     ++sub;
603     Draw();
604   }
605   return sub;
606 }