Adding alarms and graphical representation of alarms
[u/mrichter/AliRoot.git] / TPC / AliTPCCalibQAChecker.cxx
CommitLineData
949d8707 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
40using namespace std;
41
42AliTPCCalibQAChecker::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//_________________________________________________________________________
67AliTPCCalibQAChecker::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//_________________________________________________________________________
92AliTPCCalibQAChecker::~AliTPCCalibQAChecker()
93{
94 //
95 // Default ctor
96 //
97 if (fHistRep) delete fHistRep;
98 if (fIterSubCheckers) delete fIterSubCheckers;
99 if (fArrAlarmDescriptions) delete fArrAlarmDescriptions;
100}
101//_________________________________________________________________________
102void 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//_________________________________________________________________________
115void 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//_________________________________________________________________________
136void 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//_________________________________________________________________________
155void 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//_________________________________________________________________________
182void 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//_________________________________________________________________________
202void 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//_________________________________________________________________________
212void AliTPCCalibQAChecker::ProcessNumber()
213{
214 //
215 // process number type checker
216 //
217 if (!fNumberPtr) return;
218 fQualityLevel=GetQuality(*fNumberPtr);
219}
220//_________________________________________________________________________
221void 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//_________________________________________________________________________
239void 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//_________________________________________________________________________
251void 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//_________________________________________________________________________
289void 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//_________________________________________________________________________
320void 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//_________________________________________________________________________
345void 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//_________________________________________________________________________
356void 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//_________________________________________________________________________
391void 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//_________________________________________________________________________
407void 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//_________________________________________________________________________
417void 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//_________________________________________________________________________
427void 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//_________________________________________________________________________
438void 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//_________________________________________________________________________
454const 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//_________________________________________________________________________
477Int_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//_________________________________________________________________________
499AliTPCCalibQAChecker* 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//_________________________________________________________________________
516const 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//_________________________________________________________________________
539Color_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//_________________________________________________________________________
570const 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//_________________________________________________________________________
585Int_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}