1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
18 // Class to process a tree and create alarms based on thresholds //
19 // origin: jens wiechula: jens.wiechula@cern.ch //
21 ///////////////////////////////////////////////////////////////////////////////
24 #include <TObjArray.h>
26 #include <TObjString.h>
36 #include <TIterator.h>
41 #include <TStopwatch.h>
45 #include "AliTPCCalibQAChecker.h"
49 AliTPCCalibQAChecker::AliTPCCalibQAChecker() :
50 TNamed("AliTPCCalibQAChecker","AliTPCCalibQAChecker"),
56 fIterSubCheckers(0x0),
58 fArrAlarmDescriptions(0x0),
71 ResetAlarmThresholds();
73 //_________________________________________________________________________
74 AliTPCCalibQAChecker::AliTPCCalibQAChecker(const char* name, const char *title) :
81 fIterSubCheckers(0x0),
83 fArrAlarmDescriptions(0x0),
96 ResetAlarmThresholds();
98 //_________________________________________________________________________
99 AliTPCCalibQAChecker::~AliTPCCalibQAChecker()
104 if (fHistRep) delete fHistRep;
105 if (fIterSubCheckers) delete fIterSubCheckers;
106 if (fArrAlarmDescriptions) delete fArrAlarmDescriptions;
107 if (fArrSubCheckers) delete fArrSubCheckers;
109 //_________________________________________________________________________
110 void AliTPCCalibQAChecker::AddSubChecker(AliTPCCalibQAChecker *alarm)
113 // add a sub checker to this checker
116 if (!fArrSubCheckers) {
117 fArrSubCheckers=new TObjArray;
118 fArrSubCheckers->SetOwner();
120 fArrSubCheckers->Add(alarm);
122 //_________________________________________________________________________
123 void AliTPCCalibQAChecker::Process()
126 // Process the alarm thresholds, decide the alarm level, create the representation histogram
129 //reset quality level
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();
141 AliInfo(Form("Processing Time (%s): %fs",GetName(),s.RealTime()));
143 //_________________________________________________________________________
144 void AliTPCCalibQAChecker::ProcessSub()
147 // sub checker type checker
149 QualityFlag_t quality=kINFO;
150 if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
151 TIter next(fArrSubCheckers);
153 while ( (o=next()) ) {
154 AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
156 QualityFlag_t subQuality=al->GetQuality();
157 if (subQuality>quality) quality=subQuality;
160 fQualityLevel=quality;
162 //_________________________________________________________________________
163 void AliTPCCalibQAChecker::ProcessTree()
166 // process tree type checker
169 //Create Representation Histogram
170 CreateRepresentationHist();
172 // if (!fTree) return;
173 //chek for the quality
189 //_________________________________________________________________________
190 void AliTPCCalibQAChecker::ProcessHist()
193 // process histogram type checker
196 if (!(fHistPtr && *fHistPtr)) return;
209 //create representation histogram if we are not in tree mode
212 fHistRep=(*fHistPtr)->Clone();
213 TH1* h=(TH1*)fHistRep;
215 h->SetNameTitle(Form("h%s",GetName()),GetTitle());
217 TH1* h=(TH1*)fHistRep;
220 if (!fHistRep->InheritsFrom(TH2::Class())) AddQualityLines(h);
223 //_________________________________________________________________________
224 void AliTPCCalibQAChecker::ProcessGraph()
227 // process graph type checker
229 if (!(fGraphPtr && *fGraphPtr)) return;
230 Int_t npoints=(*fGraphPtr)->GetN();
231 fQualityLevel=GetQuality(npoints,(*fGraphPtr)->GetY());
233 //_________________________________________________________________________
234 void AliTPCCalibQAChecker::ProcessNumber()
237 // process number type checker
239 if (!fNumberPtr) return;
240 fQualityLevel=GetQuality(*fNumberPtr);
241 //create representation histogram
243 TH1* h=new TH1F(Form("h%s",GetName()),GetTitle(),1,0,1);
244 h->GetXaxis()->SetBinLabel(1,"Value");
249 TH1 *h=(TH1*)fHistRep;
250 TMarker *marker=(TMarker*)h->GetListOfFunctions()->FindObject("TMarker");
252 marker=new TMarker(.5,0,20);
253 h->GetListOfFunctions()->Add(marker);
255 marker->SetMarkerColor(GetQualityColor());
256 marker->SetY(*fNumberPtr);
258 //_________________________________________________________________________
259 void AliTPCCalibQAChecker::ProcessEntries()
262 // Processing function which analyses the number of affected rows of a tree draw
264 TString draw=fStrDraw;
265 if (draw.IsNull()) return;
267 TString cuts=fStrCuts;
269 TString opt=fStrDrawOpt;
272 //draw and get the histogram
273 Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
274 fQualityLevel=GetQuality(res);
276 //_________________________________________________________________________
277 void AliTPCCalibQAChecker::ProcessMean()
280 // Processing function which analyses the mean of the resulting histogram
284 Double_t value=h->GetMean();
285 if (fAlarmType==kNentries) value=h->GetEntries();
286 fQualityLevel=GetQuality(value);
288 //_________________________________________________________________________
289 void AliTPCCalibQAChecker::ProcessBin()
292 // Process a histogram bin by bin and check for thresholds
295 //bin quality counters
296 Int_t nquality[kNQualityFlags];
297 for (Int_t iquality=(Int_t)kINFO; iquality<kNQualityFlags; ++iquality) nquality[iquality]=0;
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;
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);
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;
326 //_________________________________________________________________________
327 void AliTPCCalibQAChecker::CreateRepresentationHist()
330 // Create the representation histogram which will be shown in the draw function
332 ResetRepresentationHist();
334 TString draw=fStrDrawRep;
337 fStrDrawRepOpt=fStrDrawOpt;
339 draw.ReplaceAll("%alarm%",fStrDraw.Data());
341 if (draw.IsNull()) return;
343 TString cuts=fStrCuts;
345 TString opt=fStrDrawRepOpt;
348 Int_t res=(*fTreePtr)->Draw(draw.Data(),cuts.Data(),opt.Data());
349 TH1 *hist=(*fTreePtr)->GetHistogram();
351 AliError(Form("Could not create representation histogram of alarm '%s'",GetName()));
354 fHistRep=hist->Clone();
355 TH1 *h=(TH1*)fHistRep;
357 h->SetNameTitle(Form("h%s",GetName()),GetTitle());
359 //_________________________________________________________________________
360 void AliTPCCalibQAChecker::CreateAlarmHist()
363 // create alarm histogram from the tree
366 TString draw=fStrDraw;
367 if (draw.IsNull()) return;
369 TString cuts=fStrCuts;
371 TString opt=fStrDrawOpt;
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()));
381 fHist->SetDirectory(0);
384 //_________________________________________________________________________
385 void AliTPCCalibQAChecker::ResetAlarmHist()
388 // delete the alarm histogram and reset the pointer
391 if (*fHistPtr) delete *fHistPtr;
395 //_________________________________________________________________________
396 void AliTPCCalibQAChecker::Draw(Option_t *option)
399 // object draw function
400 // by default the pad backgound color is set to the quality level color
401 // use 'nobc' to change this
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;}
408 //_________________________________________________________________________
409 void AliTPCCalibQAChecker::Print(Option_t * const option) const
412 // print the quality status. If we have sub checkers print recursively
414 TString sOpt(option);
415 cout << sOpt << GetName() << ": " << GetQualityName() << endl;
416 if (fArrSubCheckers && fArrSubCheckers->GetEntries()>0){
417 sOpt.ReplaceAll("+-"," ");
419 TIter next(fArrSubCheckers);
421 while ( (o=next()) ) o->Print(sOpt.Data());
424 //_________________________________________________________________________
425 void AliTPCCalibQAChecker::SetAlarmThreshold(const Double_t min, const Double_t max, const QualityFlag_t quality)
428 //set the alarm thresholds for a specific quality level
430 if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
431 fThresMin[quality]=min;
432 fThresMax[quality]=max;
434 //_________________________________________________________________________
435 void AliTPCCalibQAChecker::ResetAlarmThreshold(const QualityFlag_t quality)
438 //set the alarm thresholds for a specific quality level
440 if ((Int_t)quality<(Int_t)kINFO||(Int_t)quality>=kNQualityFlags) return;
441 fThresMin[quality]=0;
442 fThresMax[quality]=0;
444 //_________________________________________________________________________
445 void AliTPCCalibQAChecker::ResetAlarmThresholds()
448 //reset all the alarm thresholds
450 for (Int_t i=0;i<kNQualityFlags;++i){
455 //_________________________________________________________________________
456 void AliTPCCalibQAChecker::SetQualityDescription(const char* text, const QualityFlag_t quality)
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)
464 if (quality<kINFO||quality>kFATAL) return;
465 if (! fArrAlarmDescriptions ) fArrAlarmDescriptions=new TObjArray(kNQualityFlags);
466 TObjString *s=(TObjString*)fArrAlarmDescriptions->At(quality);
467 if (!s) fArrAlarmDescriptions->AddAt(s=new TObjString,quality);
471 //_________________________________________________________________________
472 const AliTPCCalibQAChecker* AliTPCCalibQAChecker::GetSubChecker(const char* name, Bool_t recursive) const
475 // Return subnode with 'name'
478 if (sname==GetName()) return this;
479 if (!fArrSubCheckers || !fArrSubCheckers->GetEntries()) return 0x0;
480 const AliTPCCalibQAChecker *al=0x0;
482 TIter next(fArrSubCheckers);
484 while ( (o=next()) ){
485 AliTPCCalibQAChecker *sal=(AliTPCCalibQAChecker*)o;
486 al=sal->GetSubChecker(name);
490 al=dynamic_cast<AliTPCCalibQAChecker*>(fArrSubCheckers->FindObject(name));
494 //_________________________________________________________________________
495 Int_t AliTPCCalibQAChecker::GetNumberOfSubCheckers(Bool_t recursive) const
498 // get the number of sub checkers
499 // if recursive get total number of non subchecker type sub checkers
503 if (!fArrSubCheckers) return 1;
504 if (!fArrSubCheckers->GetEntries()) return 0;
505 TIter next(fArrSubCheckers);
507 while ( (o=next()) ){
508 AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
509 nsub+=al->GetNumberOfSubCheckers();
512 if (fArrSubCheckers) nsub=fArrSubCheckers->GetEntries();
516 //_________________________________________________________________________
517 AliTPCCalibQAChecker* AliTPCCalibQAChecker::NextSubChecker()
520 // loop over sub checkers
521 // if recursive, recursively return the pointers of non subchecker type sub checkers
523 if (!fArrSubCheckers && !fArrSubCheckers->GetEntries()) return 0;
524 if (!fIterSubCheckers) fIterSubCheckers=fArrSubCheckers->MakeIterator();
525 AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)fIterSubCheckers->Next();
527 delete fIterSubCheckers;
528 fIterSubCheckers=0x0;
530 // if (recursive && al->GetNumberOfSubCheckers(kFALSE)) al=al->NextSubChecker();
533 //_________________________________________________________________________
534 const char* AliTPCCalibQAChecker::QualityName(const AliTPCCalibQAChecker::QualityFlag_t quality)
537 // get quality name for quality
556 //_________________________________________________________________________
557 Color_t AliTPCCalibQAChecker::QualityColor(const AliTPCCalibQAChecker::QualityFlag_t quality)
560 // get quality color for quality
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;
587 //_________________________________________________________________________
588 const char* AliTPCCalibQAChecker::QualityDescription(const QualityFlag_t quality) const
591 // return description for quality
593 if (!fArrAlarmDescriptions || !fArrAlarmDescriptions->At(quality)) return "";
594 TString s(fArrAlarmDescriptions->At(quality)->GetName());
596 min+=fThresMin[quality];
597 max+=fThresMax[quality];
598 s.ReplaceAll("%min",min);
599 s.ReplaceAll("%max",max);
602 //_________________________________________________________________________
603 Int_t AliTPCCalibQAChecker::DrawInPad(TVirtualPad *pad, Int_t sub)
606 // Draw recursively in 'pad'
609 if (fArrSubCheckers){
610 if (fArrSubCheckers->GetEntries()>0){
611 TIter next(fArrSubCheckers);
613 while ( (o=next()) ) {
614 AliTPCCalibQAChecker *al=(AliTPCCalibQAChecker*)o;
615 sub=al->DrawInPad(pad,sub);
625 //_________________________________________________________________________
626 void AliTPCCalibQAChecker::DrawSubNodes(Option_t */*option*/)
629 // divide the current pad in sub pads and draw all sub nodes
631 if (!gPad) new TCanvas;
632 TPad *mother=(TPad*)gPad;
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);
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");}
653 //_________________________________________________________________________
654 void AliTPCCalibQAChecker::DrawRepresentationHist(const Option_t *option)
657 // Draw the representation histogram
659 if (!fHistRep) return;
660 if (!gPad) new TCanvas;
661 Bool_t withBackColor=kTRUE;
666 if (opt.Contains("nobc")) withBackColor=kFALSE;
667 opt.ReplaceAll("nobc","");
669 if (opt.IsNull()) opt=fStrDrawRepOpt;
672 opt.ReplaceAll("prof","");
674 fHistRep->Draw(opt.Data());
676 gPad->SetFillColor(GetQualityColor());
681 //_________________________________________________________________________
682 void AliTPCCalibQAChecker::AddQualityLines(TH1 *hist)
685 // add lines indicating the quality level to hist
688 Double_t xmin=hist->GetXaxis()->GetXmin();
689 Double_t xmax=hist->GetXaxis()->GetXmax();
693 for (Int_t i=(Int_t)kINFO; i<kNQualityFlags; ++i){
694 if (fThresMin[i]>=fThresMax[i]) continue;
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);
706 hist->SetAxisRange(min,max,"Y");