]> git.uio.no Git - u/mrichter/AliRoot.git/blob - T0/AliT0QAChecker.cxx
modified Multi BF drawing macros (AliTHn::FillParent only once)
[u/mrichter/AliRoot.git] / T0 / AliT0QAChecker.cxx
1 /**************************************************************************
2  * Coyright(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 //  Checks the quality assurance. 
17 //  By comparing with reference data
18 //  Skeleton for T0
19 //---------------------------------------------
20 //checkig without reference data:
21 //for RAW QA all histograms should have approximatly the same 
22 //number of entries as RefPoint
23 //for Rec Points checks 
24 //  - amplitude measured by 2 methos
25 //  - online and offline T0 measurements
26 // for ESD quality of reconstruction ( and measurements):
27 // RMS of vertex and T0 less than 75ps
28 //
29 // Alla.Maevskaya@cern.ch   
30 //...
31
32 // --- ROOT system ---
33 #include <Riostream.h>
34 #include <TClass.h>
35 #include <TH1F.h> 
36 #include <TF1.h> 
37 #include <TFitResultPtr.h>
38 #include <TH2.h> 
39 #include <TIterator.h> 
40 #include <TKey.h> 
41 #include <TFile.h> 
42 #include <TMath.h>
43 #include <TString.h>
44 #include <TPaveText.h>
45 #include <TLegend.h>
46
47 // --- Standard library ---
48
49 // --- AliRoot header files ---
50 #include "AliLog.h"
51 #include "AliQAv1.h"
52 #include "AliQAChecker.h"
53 #include "AliCDBEntry.h"
54 #include "AliQAManager.h"
55 #include "AliT0QAChecker.h"
56 #include "AliQAThresholds.h"
57 #include "AliDAQ.h"
58
59 ClassImp(AliT0QAChecker)
60 //____________________________________________________________________________
61 AliT0QAChecker::AliT0QAChecker() :
62   AliQACheckerBase("T0","T0 Quality Assurance Checker"),
63   fCFDErrorThreshold(0),
64   fLEDErrorThreshold(0),
65   fQTCErrorThreshold(0),
66   fRatioCFDEffLEDEffErrorThreshold(1),
67   fQTCEfficiencyErrorThreshold(0),
68   fBCIDPeriodParam(3564),
69   fBCIDOffsetParam(37),
70   fBCIDBandWidthParam(10),
71   fTZeroAPlusCErrorThreshold(2000.0),
72   fTZeroAMinusCErrorThreshold(2000.0)
73 {
74   // Standard constructor
75   for(Int_t i=0; i<24; i++){ 
76     fMeanCFDFromGoodRunParam[i]=0; 
77     fMeanLEDFromGoodRunParam[i]=0; 
78     fMeanQTCFromGoodRunParam[i]=0; 
79   }
80
81 }
82
83 //____________________________________________________________________________
84 AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
85   AliQACheckerBase(qac.GetName(), qac.GetTitle()),
86   fCFDErrorThreshold(qac.fCFDErrorThreshold),
87   fLEDErrorThreshold(qac.fLEDErrorThreshold),
88   fQTCErrorThreshold(qac.fQTCErrorThreshold),
89   fRatioCFDEffLEDEffErrorThreshold(qac.fRatioCFDEffLEDEffErrorThreshold),
90   fQTCEfficiencyErrorThreshold(qac.fQTCEfficiencyErrorThreshold),
91   fBCIDPeriodParam(qac.fBCIDPeriodParam),
92   fBCIDOffsetParam(qac.fBCIDOffsetParam),
93   fBCIDBandWidthParam(qac.fBCIDBandWidthParam),
94   fTZeroAPlusCErrorThreshold(qac.fTZeroAPlusCErrorThreshold),
95   fTZeroAMinusCErrorThreshold(qac.fTZeroAMinusCErrorThreshold)
96 {
97   // copy constructor
98   AliError("Copy should not be used with this class\n");
99   for(Int_t i=0; i<24; i++){ 
100     fMeanCFDFromGoodRunParam[i]=qac.fMeanCFDFromGoodRunParam[i]; 
101     fMeanLEDFromGoodRunParam[i]=qac.fMeanLEDFromGoodRunParam[i]; 
102     fMeanQTCFromGoodRunParam[i]=qac.fMeanQTCFromGoodRunParam[i]; 
103   }
104
105 }
106 //____________________________________________________________________________
107 AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
108   // assignment operator
109   this->~AliT0QAChecker();
110   new(this)AliT0QAChecker(qac);
111   return *this;
112 }
113
114
115 //____________________________________________________________________________
116 AliT0QAChecker::~AliT0QAChecker(){
117   // destructor
118
119 }
120
121 //__________________________________________________________________
122 void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
123 {
124
125   AliCDBManager* man = AliCDBManager::Instance();
126   //man->SetDefaultStorage(gSystem->Getenv("AMORE_CDB_URI"));
127   if(!man) return; 
128   AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
129   TObjArray* t0branch = (TObjArray*) entry->GetObject();
130   if(!list) return;
131   AliQAThresholds*  thresholds = (AliQAThresholds*) t0branch->FindObject("T00");
132   // here you should test that you got a non-null pointer
133
134   if(!thresholds) return;
135   if(AliDAQ::DetectorID("T0")!= thresholds->GetDetectorId()){
136     AliInfo(Form("DETECTOR ID %d DOES NOT MATCH TO TZERO",thresholds->GetDetectorId()));
137     return;
138   }
139
140   int iparam; 
141   for(int ipmt=0; ipmt<24;ipmt++){ 
142     iparam = ipmt + 1; //current consecutive number of parameter
143     if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean CFD from a good run 
144       fMeanCFDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
145     }
146
147     iparam = ipmt + 25;
148     if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean LED from a good run 
149       fMeanLEDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
150     } 
151     iparam = ipmt + 49;
152     if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean QTC from a good run 
153       fMeanQTCFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
154     } 
155   }
156   iparam = 73; //CFD threshold
157   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
158     fCFDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
159   }
160   iparam = 74; //LED threshold
161   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
162     fLEDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
163   }
164   iparam = 75; //QTC threshold
165   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
166     fQTCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
167   }
168  
169   iparam = 82; //Error level threshold on CFD efficiency/LED efficiency ratio
170   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
171     fRatioCFDEffLEDEffErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
172   }
173   // Super-basic check on the QA histograms on the input list:
174   // look whether they are empty!
175
176   iparam = 83; //Error level threshold on QTC efficiency 
177   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
178     fQTCEfficiencyErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
179   }
180
181   iparam = 84; 
182   if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
183     fBCIDPeriodParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
184   }
185
186   iparam = 85; 
187   if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
188     fBCIDOffsetParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
189   }
190
191   iparam = 86; 
192   if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
193     fBCIDBandWidthParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
194   }
195
196   iparam = 87; 
197   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
198     fTZeroAPlusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
199   }
200
201   iparam = 88; 
202   if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
203     fTZeroAMinusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
204   }
205
206
207   char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ; 
208
209   AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
210   //  QARefRec->Dump();
211   if( !QARefRec){
212     AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
213   }
214
215     
216   for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++){ 
217     test[specie]    = 1.0; //FK//  initiate qa flag for the whole set of histograms as good 
218   }
219
220
221   for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
222     if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
223       continue;
224     }
225
226     if(index == AliQAv1::kRAW){
227
228       //if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){//      if (index == AliQAv1::kRAW )
229         //check laser data efficiencies   
230       //  Double_t qaFlag = CheckLaser(list[specie]);
231       //  if(qaFlag < test[specie]) test[specie] = qaFlag;
232       //}
233
234       //if(//AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib   ||
235        //  AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
236       //   AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){ 
237          //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
238          
239         //check BCID   
240       //  Double_t qaFlag = CheckBCID(list[specie]);
241       //  if(qaFlag < test[specie]) test[specie] = qaFlag;
242       //}
243
244       if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
245         AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){ 
246         //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
247         //check physics 
248         Double_t qaFlag = CheckRaw(list[specie]);
249         if(qaFlag < test[specie]) test[specie] = qaFlag;
250       }
251     }
252
253     if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){
254       test[specie] = CheckESD(list[specie]);
255     } 
256   }
257 }
258
259 //--------------------------------------------------------------------------
260 //Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
261 //   
262 //  return 1.0; 
263 //}
264
265 //--------------------------------------------------------------------------
266 Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
267    
268   //Fk Set drawing options for LED and CFD efficiencies from the raw data
269   TH1F *hCFDEffData = (TH1F*) listrec->UncheckedAt(207);//hRawTrigger 
270   TH1F *hLEDEffData = (TH1F*) listrec->UncheckedAt(208);//hRawTrigger 
271
272   //clean objects added at previous checks
273   EraseOldMessages((TH1*) hCFDEffData); 
274   hCFDEffData->GetListOfFunctions()->Add((TH1D*) hLEDEffData->Clone());       
275
276   TLegend leg(0.12,0.76,0.9,0.92," ","brNDC");
277   leg.SetFillStyle(0); leg.SetBorderSize(0); leg.SetTextSize(0.04); leg.SetNColumns(2);
278   leg.AddEntry((TH1D*) hCFDEffData,"CFD","p");
279   leg.AddEntry((TH1D*) hLEDEffData,"LED","p");
280   hCFDEffData->GetListOfFunctions()->Add((TLegend*) leg.Clone());             
281
282
283   //Fk Draw CFD-mean for each PMT
284   TH2F* fhCFD = (TH2F*) listrec->UncheckedAt(210);
285   TH1F* fhCFDSubtrMean = (TH1F*) listrec->UncheckedAt(231);
286
287   EraseOldMessages((TH1*) fhCFDSubtrMean); 
288   for(int ipmt=0; ipmt<24;ipmt++){ 
289     TH1F*  hProjDummy = (TH1F*) fhCFD->ProjectionY("dummy",ipmt+1,ipmt+1);
290     Float_t mean=0.0, rms=0.0;
291     GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,0);
292
293     Float_t deviation = mean - fMeanCFDFromGoodRunParam[ipmt]; 
294
295     fhCFDSubtrMean->SetBinContent(ipmt+1,deviation);
296     fhCFDSubtrMean->SetBinError(ipmt+1,rms);
297       
298     delete hProjDummy;
299   }
300   TLine linelowredCFD(0, fCFDErrorThreshold, 24, fCFDErrorThreshold);    
301   linelowredCFD.SetLineColor(2);
302   linelowredCFD.SetLineStyle(3);
303   linelowredCFD.SetLineWidth(4);
304   TLine linehighredCFD(0, -fCFDErrorThreshold, 24, -fCFDErrorThreshold);    
305   linehighredCFD.SetLineColor(2);
306   linehighredCFD.SetLineStyle(3);
307   linehighredCFD.SetLineWidth(4);
308   fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredCFD.Clone());          
309   fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredCFD.Clone());         
310
311  
312  
313   //Fk Draw LED-mean for each PMT
314   TH2F* fhLED = (TH2F*) listrec->UncheckedAt(211);
315   TH1F* fhLEDSubtrMean = (TH1F*) listrec->UncheckedAt(232);
316  
317   EraseOldMessages((TH1*) fhLEDSubtrMean); 
318   for(int ipmt=0; ipmt<24;ipmt++){ 
319     TH1F*  hProjDummy = (TH1F*) fhLED->ProjectionY("dummy",ipmt+1,ipmt+1);
320     Float_t mean=0.0, rms=0.0;
321     GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,1);
322     Float_t deviation = mean - fMeanLEDFromGoodRunParam[ipmt]; 
323
324     fhLEDSubtrMean->SetBinContent(ipmt+1,deviation);
325     fhLEDSubtrMean->SetBinError(ipmt+1,rms);
326       
327     delete hProjDummy;
328   }
329   TLine linelowredLED(0, fLEDErrorThreshold, 24, fLEDErrorThreshold);    
330   linelowredLED.SetLineColor(2);
331   linelowredLED.SetLineStyle(3);
332   linelowredLED.SetLineWidth(4);
333   TLine linehighredLED(0, -fLEDErrorThreshold, 24, -fLEDErrorThreshold);    
334   linehighredLED.SetLineColor(2);
335   linehighredLED.SetLineStyle(3);
336   linehighredLED.SetLineWidth(4);
337   fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredLED.Clone());          
338   fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredLED.Clone());         
339
340      
341   //Fk Draw QTC-mean for each PMT
342   TH2F* fhQTC = (TH2F*) listrec->UncheckedAt(212);
343   TH1F* fhQTCSubtrMean = (TH1F*) listrec->UncheckedAt(233);
344    
345   EraseOldMessages((TH1*) fhQTCSubtrMean); 
346   for(int ipmt=0; ipmt<24;ipmt++){ 
347     TH1F*  hProjDummy = (TH1F*) fhQTC->ProjectionY("dummy",ipmt+1,ipmt+1);
348     Float_t mean=0.0, rms=0.0;
349     GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,2);
350     Float_t deviation = mean - fMeanQTCFromGoodRunParam[ipmt]; 
351
352     fhQTCSubtrMean->SetBinContent(ipmt+1,deviation);
353     fhQTCSubtrMean->SetBinError(ipmt+1,rms);
354       
355     delete hProjDummy;
356   }
357   TLine linelowredQTC(0, fQTCErrorThreshold, 24, fQTCErrorThreshold);    
358   linelowredQTC.SetLineColor(2);
359   linelowredQTC.SetLineStyle(3);
360   linelowredQTC.SetLineWidth(4);
361   TLine linehighredQTC(0, -fQTCErrorThreshold, 24, -fQTCErrorThreshold);    
362   linehighredQTC.SetLineColor(2);
363   linehighredQTC.SetLineStyle(3);
364   linehighredQTC.SetLineWidth(4);
365   fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredQTC.Clone());          
366   fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredQTC.Clone());         
367
368   //CFD and LED efficiency in range ~2000- ~3000 
369   TH1F* hCFDeffSubRange = (TH1F*) listrec->UncheckedAt(237);
370   TH1F* hEffLEDSubRange = (TH1F*) listrec->UncheckedAt(238);
371   // ratio CDF eff /LEF eff in subragne 
372   TH1F* hRatioCFDLEDeff = (TH1F*) listrec->UncheckedAt(239);//FK   
373   EraseOldMessages((TH1*) hRatioCFDLEDeff); 
374   int npmt = hRatioCFDLEDeff->GetNbinsX();
375   for(int ipmt=1;ipmt<=npmt;ipmt++){
376     Float_t c0 = hCFDeffSubRange->GetBinContent(ipmt); 
377     Float_t c1 = hEffLEDSubRange->GetBinContent(ipmt);
378     if(c1){
379       hRatioCFDLEDeff->SetBinContent(ipmt,c0/c1);  
380     }else{
381       hRatioCFDLEDeff->SetBinContent(ipmt,0);  
382     }  
383   }
384
385   TLine linelowredRatioCFDLEDeff(0, 1+fRatioCFDEffLEDEffErrorThreshold, 24, 1+fRatioCFDEffLEDEffErrorThreshold);    
386   linelowredRatioCFDLEDeff.SetLineColor(2);
387   linelowredRatioCFDLEDeff.SetLineStyle(3);
388   linelowredRatioCFDLEDeff.SetLineWidth(4);
389   TLine linehighredRatioCFDLEDeff(0, 1-fRatioCFDEffLEDEffErrorThreshold, 24, 1-fRatioCFDEffLEDEffErrorThreshold);    
390   linehighredRatioCFDLEDeff.SetLineColor(2);
391   linehighredRatioCFDLEDeff.SetLineStyle(3);
392   linehighredRatioCFDLEDeff.SetLineWidth(4);
393   hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linelowredRatioCFDLEDeff.Clone());              
394   hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linehighredRatioCFDLEDeff.Clone());             
395
396   //        PERFROM CHECKS on HISTOGRAMS
397
398   //-------- triggers -----------
399   Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram; 
400
401   TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger 
402
403   // clean objects added at previous checks
404   EraseOldMessages((TH1*) hTrigger); 
405
406   if(hTrigger->Integral()>0){
407     //trigger plot does have some counts in it
408     //are Mean, ORA and ORC not empty?  
409     if( hTrigger->GetBinContent(1)<0.001 || hTrigger->GetBinContent(3)<0.001 || hTrigger->GetBinContent(4)<0.001){
410       qualityFlagTrigger = kT0Error; //no entries on diagonal
411       AliDebug(AliQAv1::GetQADebugLevel(), Form("T0: too little ORA and ORC in  %s", hTrigger->GetName() ));
412
413       TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
414       text.AddText(Form("Check ORA and ORC")); 
415       text.AddText(Form("Report problem to the T0 on-call expert")); 
416       text.SetBorderSize(0);
417       text.SetFillStyle(0);
418       hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());          
419     }
420
421   }else{ //Trigger histo empty
422
423     qualityFlagTrigger = kT0Error;
424     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hTrigger->GetName() ));
425
426     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
427     text.AddText(Form("NO ENTRIES!!!")); 
428     text.AddText(Form("If T0 is READY report")); 
429     text.AddText(Form("readout problem to the T0 on-call expert")); 
430     text.SetBorderSize(0);
431     text.SetFillStyle(0);
432     hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
433
434   }
435   //---------- CFD eff/LED eff within subrange  -----------
436   Int_t qualityFlagRatioCFDeffLEDeff = kT0Info; //init quality flag for a given histogram;
437   int nPMTs = hRatioCFDLEDeff->GetNbinsX(); 
438
439   for(int ipmt=1; ipmt<=nPMTs; ipmt++){
440     if(TMath::Abs( hRatioCFDLEDeff->GetBinContent(ipmt) -1) > fRatioCFDEffLEDEffErrorThreshold){ //mean is expected to be around 1
441       qualityFlagRatioCFDeffLEDeff = kT0Error;
442     }
443   }
444   if(qualityFlagRatioCFDeffLEDeff == kT0Error){
445     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
446     text.AddText(Form("Problem with efficiency ratio CFD/LED !!!")); 
447     text.AddText(Form("If T0 is READY and beam is on report")); 
448     text.AddText(Form("the problem to the T0 on-call expert"));
449     text.SetBorderSize(0);
450     text.SetFillStyle(0);
451     hRatioCFDLEDeff->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
452   }
453   
454
455   //---------- CFD -  mean CFD  -----------
456   Int_t qualityFlagCFDSubtr = kT0Info; //init quality flag for a given histogram;
457   nPMTs = fhCFDSubtrMean->GetNbinsX(); 
458
459   for(int ipmt=1; ipmt<=nPMTs; ipmt++){
460     if(TMath::Abs( fhCFDSubtrMean->GetBinContent(ipmt)) > fCFDErrorThreshold){
461       qualityFlagCFDSubtr = kT0Error;
462
463    }
464   }
465   if(qualityFlagCFDSubtr == kT0Error){
466     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
467     text.AddText(Form("Problem with CFD timing  !!!")); 
468     text.AddText(Form("If T0 is READY and beam is on report")); 
469     text.AddText(Form("the problem to the T0 on-call expert"));
470     text.SetBorderSize(0);
471     text.SetFillStyle(0);
472     fhCFDSubtrMean->GetListOfFunctions()->Add((TPaveText*)text.Clone());              
473   }
474   //--------- QTC efficiency ---------------
475
476   Int_t qualityFlagEffQTC = kT0Info; //init quality flag for a given histogram;
477   TH1F *hEffQTC = (TH1F*) listrec->UncheckedAt(209);//hRawTrigger 
478   
479   EraseOldMessages((TH1*) hEffQTC); // clean objects added at previous checks
480
481   nPMTs = hEffQTC->GetNbinsX(); 
482   for(int ipmt=1; ipmt<=nPMTs; ipmt++){
483     if(TMath::Abs( hEffQTC->GetBinContent(ipmt)) < fQTCEfficiencyErrorThreshold){
484       qualityFlagEffQTC = kT0Error;
485     }
486   }
487   if( qualityFlagEffQTC == kT0Error){
488     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
489     text.AddText(Form("Problem with QTC efficiency !!!")); 
490     text.AddText(Form("If T0 is READY and beam is on report")); 
491     text.AddText(Form("the problem to the T0 on-call expert"));
492     text.SetBorderSize(0);
493     text.SetFillStyle(0);
494     hEffQTC->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
495   }
496   TLine linehighredQTCeff(0, fQTCEfficiencyErrorThreshold, 24, fQTCEfficiencyErrorThreshold);    
497   linehighredQTCeff.SetLineColor(2);
498   linehighredQTCeff.SetLineStyle(3);
499   linehighredQTCeff.SetLineWidth(4);
500   hEffQTC->GetListOfFunctions()->Add((TLine*) linehighredQTCeff.Clone());             
501  
502   //---------- BCID --------------------
503   Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram; 
504   TH2F *hBCID = (TH2F*) listrec->UncheckedAt(236); //BCID versus TRM  BCID
505      
506   // clean objects added at previous checks
507   EraseOldMessages((TH1*)hBCID);
508
509   if(hBCID->Integral()>0){
510     //BCID does have some counts in it
511
512     Int_t nbinsX = hBCID->GetNbinsX();
513     Int_t startX = hBCID->GetXaxis()->FindBin(100); //skip region close to orbit period
514     Int_t nbinsY = hBCID->GetNbinsY();
515     Int_t binWidthX = (Int_t) hBCID->GetXaxis()->GetBinWidth(1);
516     Int_t binWidthY = (Int_t) hBCID->GetYaxis()->GetBinWidth(1);
517     double entriesOnDiagonal  = 0; //count diagonal and off diagonal entries
518     double entriesOffDiagonal = 0;
519
520     for(Int_t itrm=startX; itrm<=nbinsX; itrm++){ //BCID TRM
521       for(Int_t ibcid=1; ibcid<=nbinsY; ibcid++){ //BCID
522         if(TMath::Abs( (itrm*binWidthX - fBCIDOffsetParam) % fBCIDPeriodParam - binWidthY*ibcid) < fBCIDBandWidthParam ){ 
523           entriesOnDiagonal  += hBCID->GetBinContent(itrm,ibcid); //On  Diagonal
524           //hBCID->Fill(itrm*binWidthX,ibcid*binWidthY,0.001); // visualize the diagonal belt
525         }else{
526           entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
527         }
528       }
529     }
530     if(entriesOnDiagonal<1 || entriesOffDiagonal>20){
531       qualityFlagBCID = kT0Error; //no entries on diagonal
532       AliDebug(AliQAv1::GetQADebugLevel(), Form("T0   %s is not diagonal", hBCID->GetName() ));
533
534       TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
535       text.AddText(Form("Check if entries are on diagonal")); 
536       text.AddText(Form("Report readout problem to the T0 on-call expert")); 
537       text.SetBorderSize(0);
538       text.SetFillStyle(0);
539       hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
540     }
541   }else{ //BCID empty
542
543     qualityFlagBCID = kT0Error;
544     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 :  %s has NO entries", hBCID->GetName() ));
545
546     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
547     text.AddText(Form("NO ENTRIES!!!")); 
548     text.AddText(Form("If T0 is READY report")); 
549     text.AddText(Form("readout problem to the T0 on-call expert"));
550     text.SetBorderSize(0);
551     text.SetFillStyle(0);
552     hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());       
553   }
554
555   //--------- mean versus vertex 1st ---------
556   Int_t qualityFlagMeanVersusVertex1st = kT0Info; //init quality flag for a given histogram;
557   TH2F *hMeanVersusVertex1st  = (TH2F*) listrec->UncheckedAt(220);  //fhMeanBest  time
558   EraseOldMessages((TH1*) hMeanVersusVertex1st); 
559  
560   if(hMeanVersusVertex1st->Integral()<1){
561     qualityFlagMeanVersusVertex1st = kT0Error;
562     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMeanVersusVertex1st->GetName() ));
563
564     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
565     text.AddText(Form("NO ENTRIES!!!")); 
566     text.AddText(Form("If T0 is READY and beam is on report")); 
567     text.AddText(Form("the problem to the T0 on-call expert"));
568     text.SetBorderSize(0);
569     text.SetFillStyle(0);
570     hMeanVersusVertex1st->GetListOfFunctions()->Add((TPaveText*)text.Clone());        
571   }
572
573
574   //--------- vertex TVDC on ---------
575   Int_t qualityFlagVertex1stTVDCon = kT0Info; //init quality flag for a given histogram;
576   TH1F *hVertex1stTVDCon  = (TH1F*) listrec->UncheckedAt(223);  //fhMeanBest  time
577   EraseOldMessages((TH1*) hVertex1stTVDCon); 
578  
579   if(hVertex1stTVDCon->Integral()<1){
580     qualityFlagVertex1stTVDCon = kT0Error;
581     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertex1stTVDCon->GetName() ));
582
583     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
584     text.AddText(Form("NO ENTRIES!!!")); 
585     text.AddText(Form("If T0 is READY and beam is on report")); 
586     text.AddText(Form("the problem to the T0 on-call expert"));
587     text.SetBorderSize(0);
588     text.SetFillStyle(0);
589     hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
590   }else{
591     if(TMath::Abs(hVertex1stTVDCon->GetMean()) > fTZeroAMinusCErrorThreshold){ 
592       qualityFlagVertex1stTVDCon = kT0Error;
593
594       TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
595       text.AddText(Form("Displaced vertex")); 
596       text.AddText(Form("If T0 is READY and beam is on report")); 
597       text.AddText(Form("the problem to the T0 on-call expert"));
598       text.SetBorderSize(0);
599       text.SetFillStyle(0);
600       hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());          
601     }
602   }
603
604   //--------- vertex TVDC off ---------
605   Int_t qualityFlagVertex1stTVDCoff = kT0Info; //init quality flag for a given histogram;
606   TH1F *hVertex1stTVDCoff  = (TH1F*) listrec->UncheckedAt(225);  //fhMeanBest  time
607   EraseOldMessages((TH1*) hVertex1stTVDCoff); 
608  
609   if(hVertex1stTVDCoff->Integral()<1){
610     qualityFlagVertex1stTVDCoff = kT0Warning;
611     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertex1stTVDCoff->GetName() ));
612
613     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
614     text.AddText(Form("Warning: NO ENTRIES")); 
615     text.SetBorderSize(0);
616     text.SetFillStyle(0);
617     hVertex1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());           
618   }
619
620
621
622   //----------- time TVDC on ---------
623     
624   Int_t qualityFlagMean1stTVDCon = kT0Info; //init quality flag for a given histogram;
625   TH1F *hMean1stTVDCon  = (TH1F*) listrec->UncheckedAt(226);  //fhMeanBest  time
626   EraseOldMessages((TH1*) hMean1stTVDCon); 
627  
628   if(hMean1stTVDCon->Integral()<1){
629     qualityFlagMean1stTVDCon = kT0Error;
630     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMean1stTVDCon->GetName() ));
631
632     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
633     text.AddText(Form("NO ENTRIES!!!")); 
634     text.AddText(Form("If T0 is READY and beam is on report")); 
635     text.AddText(Form("the problem to the T0 on-call expert"));
636     text.SetBorderSize(0);
637     text.SetFillStyle(0);
638     hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());              
639   }else{
640     //cout<<"Mean: "<<TMath::Abs(hMean1stTVDCon->GetMean())<<" threshold "<<fTZeroAPlusCErrorThreshold<<endl;
641     if(TMath::Abs(hMean1stTVDCon->GetMean()) > fTZeroAPlusCErrorThreshold){ 
642       qualityFlagMean1stTVDCon = kT0Error;
643
644       TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
645       text.AddText(Form("Shift of mean time")); 
646       text.AddText(Form("If T0 is READY and beam is on report")); 
647       text.AddText(Form("the problem to the T0 on-call expert"));
648       text.SetBorderSize(0);
649       text.SetFillStyle(0);
650       hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
651     }
652   }
653
654   //----------- time TVDC off ---------
655     
656   Int_t qualityFlagMean1stTVDCoff = kT0Info; //init quality flag for a given histogram;
657   TH1F *hMean1stTVDCoff  = (TH1F*) listrec->UncheckedAt(227);  //fhMeanBest  time
658   EraseOldMessages((TH1*) hMean1stTVDCoff); 
659  
660   if(hMean1stTVDCoff->Integral()<1){
661     qualityFlagMean1stTVDCoff = kT0Warning;
662     AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMean1stTVDCoff->GetName() ));
663
664     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
665     text.AddText(Form("Warning: NO ENTRIES")); 
666     text.SetBorderSize(0);
667     text.SetFillStyle(0);
668     hMean1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
669   }
670  
671
672
673   //----------------------- executive summary ---------------------
674   int lowestQualityFlag = (int) qualityFlagTrigger;
675   if(qualityFlagRatioCFDeffLEDeff   < lowestQualityFlag)  lowestQualityFlag = qualityFlagRatioCFDeffLEDeff;
676   if(qualityFlagCFDSubtr            < lowestQualityFlag)  lowestQualityFlag = qualityFlagCFDSubtr;
677   if(qualityFlagEffQTC              < lowestQualityFlag)  lowestQualityFlag = qualityFlagEffQTC;
678   if(qualityFlagMeanVersusVertex1st < lowestQualityFlag)  lowestQualityFlag = qualityFlagMeanVersusVertex1st;
679   if(qualityFlagBCID                < lowestQualityFlag)  lowestQualityFlag = qualityFlagBCID;
680   if(qualityFlagVertex1stTVDCon     < lowestQualityFlag)  lowestQualityFlag = qualityFlagVertex1stTVDCon;
681   if(qualityFlagVertex1stTVDCoff    < lowestQualityFlag)  lowestQualityFlag = qualityFlagVertex1stTVDCoff;
682   if(qualityFlagMean1stTVDCon       < lowestQualityFlag)  lowestQualityFlag = qualityFlagMean1stTVDCon;
683   if(qualityFlagMean1stTVDCoff      < lowestQualityFlag)  lowestQualityFlag = qualityFlagMean1stTVDCoff;
684   
685
686   return ConvertQualityFlagToDouble(lowestQualityFlag); 
687   
688 }
689
690 //--------------------------------------------------------------------------
691 Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
692 {
693   Float_t checkr = 0;
694   TH1 *fhESD;
695  
696   fhESD  = (TH1*) listrec->UncheckedAt(2);
697   if(fhESD){
698     AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) );
699      TF1 *f1 = new TF1("f1","gaus",-1,1);
700     fhESD->Fit("f1","R","Q", -1,1);
701     Double_t par[3];
702     f1->GetParameters(&par[0]);
703     
704     TPaveText text(0.30,0.50,0.99,0.99,"NDC");
705     
706     text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
707     
708     AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f  #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));
709     
710     
711     if (par[2] > 0.07 && par[2] < 1.) {
712       checkr=0.5;
713        text.AddText(Form("not good resolution :\n %f ns\n", par[2] ));
714        text.SetFillColor(5);
715        printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
716     }
717     if(TMath::Abs(par[1])>0.05) {
718       checkr = 0.5;
719       text.AddText(Form(" Check clock shift on %f ns", par[1]));
720       text.SetFillColor(5);
721     }
722     if (par[2] >  1. || TMath::Abs(par[1])>0.1) {
723       checkr = 0.25;
724       text.AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2]));
725       text.SetFillColor(2);
726       { // RS Clean previous additions
727         TList* lstF = fhESD->GetListOfFunctions();
728         if (lstF) {
729           TObject *stats = lstF->FindObject("stats");
730           lstF->Remove(stats);
731           TObject *obj;
732           while ((obj = lstF->First())) {
733             while(lstF->Remove(obj)) { }
734             delete obj;
735           }
736           if (stats) lstF->Add(stats);
737         } 
738       }
739       fhESD->GetListOfFunctions()->Add((TPaveText*)text.Clone());       
740       AliDebug(AliQAv1::GetQADebugLevel(),
741                Form("Please, check calibration: shift= %f resolution %f test=%f\n",
742                     par[1], par[2], checkr) ) ; 
743     }
744   }
745   else
746     {
747       AliDebug(AliQAv1::GetQADebugLevel(),
748                Form("No ESD QA histogram found, nothing to check"));
749         checkr=0;
750     }
751   
752   
753   return checkr;
754 }
755
756
757 //--------------------------------------------------------------------------
758 void AliT0QAChecker::EraseOldMessages(TH1* h) const 
759 {
760   //erase the old captions 
761   TList* lstF = h->GetListOfFunctions();
762   if(lstF){  
763      TObject *stats = lstF->FindObject("stats");
764      lstF->Remove(stats);
765      TObject *obj;
766      while ((obj = lstF->First())) {
767        while(lstF->Remove(obj)) { }
768          delete obj;
769     }
770     if (stats) lstF->Add(stats);
771   }
772 }
773 //--------------------------------------------------------------------------
774 Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const 
775 {
776   //covert quality flag to double
777   Double_t checkr=1.0;
778
779   switch ( qualityFlag ){
780     case kT0Info:
781         checkr = 1.0; break;
782     case kT0Warning:
783         checkr = 0.75; break;
784     case kT0Error:
785           checkr = 0.25; break;
786     case kT0Fatal:
787         checkr = -1.0; break;
788     default:
789          AliError("Invalid ecc value. FIXME !");
790          checkr = 0.25; break;
791   };
792
793   return checkr; 
794 }
795  
796 //--------------------------------------------------------------------------
797 Float_t AliT0QAChecker::GetMeanAboveThreshold(TH1F* hV, Float_t thr) const{
798   //caculate mean value of histo bins above threshold
799   Int_t nBins = hV->GetNbinsX();
800   Int_t nBinsAboveThr = 0; 
801   Float_t sum = 0;
802
803   for(Int_t ib=1;ib<=nBins;ib++){
804     Float_t val = hV->GetBinContent(ib);
805     if(val<thr){
806       sum+=val;
807       nBinsAboveThr++; 
808     }
809   }
810
811   if(nBinsAboveThr>0) return sum/nBinsAboveThr;
812   else return hV->GetMean();
813 }
814     
815 //--------------------------------------------------------------------------
816 void AliT0QAChecker::GetMeanAndRmsAroundMainMaximum(Float_t &meanHisto,Float_t &rmsHisto, TH1F *histo, int type) const{
817
818   if(!histo){
819     meanHisto=0.0;
820     rmsHisto=0.0;
821     return;
822   }
823   if(histo->Integral()<0.00001){
824     meanHisto=0.0;
825     rmsHisto=0.0;
826     return;
827   }
828
829   double nSigma      = 3.0; //n sigma window around mean and main maximum 
830   double expectedRMS = 13.0; // expected rms of the main peak in case of CFD
831   if(type == 1) expectedRMS = 34.0; //LED
832   if(type == 2) expectedRMS = 34.0; //QTC
833
834   //0) approx of mean is global maximum
835   Int_t   nb     =  histo->GetNbinsX();
836   Int_t   bmax   =  histo->GetMaximumBin();
837   Float_t xmax   =  histo->GetBinCenter(bmax);
838
839   double window = expectedRMS * nSigma;
840   //1) estimate a mean in the nSigma window around main max
841   int nlow = histo->FindBin( xmax - window);
842   int nhigh = histo->FindBin( xmax + window);
843   if(nlow<1)   nlow = 1; 
844   if(nhigh>nb) nhigh = nb;
845
846   Float_t sum=0.0, sumWeight=0.0, sumWeightSqr=0.0;
847   for(int ii=nlow;ii<=nhigh;ii++){
848     sum          += histo->GetBinContent(ii);  
849     sumWeight    += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
850   }  
851   if(sum>0.0){
852     meanHisto = sumWeight/sum; //mean in 1st itteration
853   }else{
854     meanHisto = 0.0;
855     rmsHisto=0.0;
856     return;
857   }
858   
859   //2) recalculte mean and rms in the nSigma window around mean 1)
860   nlow  = histo->FindBin( meanHisto - window);
861   nhigh = histo->FindBin( meanHisto + window);
862   if(nlow<1)   nlow = 1; 
863   if(nhigh>nb) nhigh = nb;
864
865   sum=0.0; sumWeight=0.0; sumWeightSqr=0.0;
866   for(int ii=nlow;ii<=nhigh;ii++){
867     sum          += histo->GetBinContent(ii);  
868     sumWeight    += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
869     sumWeightSqr += histo->GetBinContent(ii)*histo->GetBinCenter(ii)*histo->GetBinCenter(ii);
870   }
871   if(sum>0.0){
872     meanHisto = sumWeight/sum; //mean in 2nd itteration
873     rmsHisto  = sumWeightSqr/sum - meanHisto*meanHisto;//rms square
874     if(rmsHisto > 0.0) rmsHisto = sqrt(rmsHisto); //rms
875     else  rmsHisto = 0.0;
876     return;
877   }else{
878     meanHisto = 0.0;
879     rmsHisto  = 0.0;
880     return;
881   }
882 }