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