1 /**************************************************************************
2 * Coyright(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 // Checks the quality assurance.
17 // By comparing with reference data
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
29 // Alla.Maevskaya@cern.ch
32 // --- ROOT system ---
33 #include <Riostream.h>
37 #include <TFitResultPtr.h>
39 #include <TIterator.h>
44 #include <TPaveText.h>
47 // --- Standard library ---
49 // --- AliRoot header files ---
52 #include "AliQAChecker.h"
53 #include "AliCDBEntry.h"
54 #include "AliQAManager.h"
55 #include "AliT0QAChecker.h"
56 #include "AliQAThresholds.h"
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),
70 fBCIDBandWidthParam(10),
71 fTZeroAPlusCErrorThreshold(2000.0),
72 fTZeroAMinusCErrorThreshold(2000.0)
74 // Standard constructor
75 for(Int_t i=0; i<24; i++){
76 fMeanCFDFromGoodRunParam[i]=0;
77 fMeanLEDFromGoodRunParam[i]=0;
78 fMeanQTCFromGoodRunParam[i]=0;
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)
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];
106 //____________________________________________________________________________
107 AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
108 // assignment operator
109 this->~AliT0QAChecker();
110 new(this)AliT0QAChecker(qac);
115 //____________________________________________________________________________
116 AliT0QAChecker::~AliT0QAChecker(){
121 //__________________________________________________________________
122 void AliT0QAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
125 AliCDBManager* man = AliCDBManager::Instance();
126 //man->SetDefaultStorage(gSystem->Getenv("AMORE_CDB_URI"));
128 AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
129 TObjArray* t0branch = (TObjArray*) entry->GetObject();
131 AliQAThresholds* thresholds = (AliQAThresholds*) t0branch->FindObject("T00");
132 // here you should test that you got a non-null pointer
134 if(!thresholds) return;
135 if(AliDAQ::DetectorID("T0")!= thresholds->GetDetectorId()){
136 AliInfo(Form("DETECTOR ID %d DOES NOT MATCH TO TZERO",thresholds->GetDetectorId()));
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();
148 if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean LED from a good run
149 fMeanLEDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
152 if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean QTC from a good run
153 fMeanQTCFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
156 iparam = 73; //CFD threshold
157 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
158 fCFDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
160 iparam = 74; //LED threshold
161 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
162 fLEDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
164 iparam = 75; //QTC threshold
165 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
166 fQTCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
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();
173 // Super-basic check on the QA histograms on the input list:
174 // look whether they are empty!
176 iparam = 83; //Error level threshold on QTC efficiency
177 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
178 fQTCEfficiencyErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
182 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
183 fBCIDPeriodParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
187 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
188 fBCIDOffsetParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
192 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
193 fBCIDBandWidthParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
197 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
198 fTZeroAPlusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
202 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
203 fTZeroAMinusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
207 char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ;
209 AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
212 AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
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
221 for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
222 if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
226 if(index == AliQAv1::kRAW){
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;
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 ||
240 // Double_t qaFlag = CheckBCID(list[specie]);
241 // if(qaFlag < test[specie]) test[specie] = qaFlag;
244 if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
245 AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){
246 //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
248 Double_t qaFlag = CheckRaw(list[specie]);
249 if(qaFlag < test[specie]) test[specie] = qaFlag;
253 if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){
254 test[specie] = CheckESD(list[specie]);
259 //--------------------------------------------------------------------------
260 //Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
265 //--------------------------------------------------------------------------
266 Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
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
272 //clean objects added at previous checks
273 EraseOldMessages((TH1*) hCFDEffData);
274 hCFDEffData->GetListOfFunctions()->Add((TH1D*) hLEDEffData->Clone());
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());
283 //Fk Draw CFD-mean for each PMT
284 TH2F* fhCFD = (TH2F*) listrec->UncheckedAt(210);
285 TH1F* fhCFDSubtrMean = (TH1F*) listrec->UncheckedAt(231);
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);
293 Float_t deviation = mean - fMeanCFDFromGoodRunParam[ipmt];
295 fhCFDSubtrMean->SetBinContent(ipmt+1,deviation);
296 fhCFDSubtrMean->SetBinError(ipmt+1,rms);
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());
313 //Fk Draw LED-mean for each PMT
314 TH2F* fhLED = (TH2F*) listrec->UncheckedAt(211);
315 TH1F* fhLEDSubtrMean = (TH1F*) listrec->UncheckedAt(232);
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];
324 fhLEDSubtrMean->SetBinContent(ipmt+1,deviation);
325 fhLEDSubtrMean->SetBinError(ipmt+1,rms);
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());
341 //Fk Draw QTC-mean for each PMT
342 TH2F* fhQTC = (TH2F*) listrec->UncheckedAt(212);
343 TH1F* fhQTCSubtrMean = (TH1F*) listrec->UncheckedAt(233);
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];
352 fhQTCSubtrMean->SetBinContent(ipmt+1,deviation);
353 fhQTCSubtrMean->SetBinError(ipmt+1,rms);
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());
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);
379 hRatioCFDLEDeff->SetBinContent(ipmt,c0/c1);
381 hRatioCFDLEDeff->SetBinContent(ipmt,0);
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());
396 // PERFROM CHECKS on HISTOGRAMS
398 //-------- triggers -----------
399 Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram;
401 TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger
403 // clean objects added at previous checks
404 EraseOldMessages((TH1*) hTrigger);
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() ));
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());
421 }else{ //Trigger histo empty
423 qualityFlagTrigger = kT0Error;
424 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hTrigger->GetName() ));
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());
435 //---------- CFD eff/LED eff within subrange -----------
436 Int_t qualityFlagRatioCFDeffLEDeff = kT0Info; //init quality flag for a given histogram;
437 int nPMTs = hRatioCFDLEDeff->GetNbinsX();
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;
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());
455 //---------- CFD - mean CFD -----------
456 Int_t qualityFlagCFDSubtr = kT0Info; //init quality flag for a given histogram;
457 nPMTs = fhCFDSubtrMean->GetNbinsX();
459 for(int ipmt=1; ipmt<=nPMTs; ipmt++){
460 if(TMath::Abs( fhCFDSubtrMean->GetBinContent(ipmt)) > fCFDErrorThreshold){
461 qualityFlagCFDSubtr = kT0Error;
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());
474 //--------- QTC efficiency ---------------
476 Int_t qualityFlagEffQTC = kT0Info; //init quality flag for a given histogram;
477 TH1F *hEffQTC = (TH1F*) listrec->UncheckedAt(209);//hRawTrigger
479 EraseOldMessages((TH1*) hEffQTC); // clean objects added at previous checks
481 nPMTs = hEffQTC->GetNbinsX();
482 for(int ipmt=1; ipmt<=nPMTs; ipmt++){
483 if(TMath::Abs( hEffQTC->GetBinContent(ipmt)) < fQTCEfficiencyErrorThreshold){
484 qualityFlagEffQTC = kT0Error;
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());
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());
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
506 // clean objects added at previous checks
507 EraseOldMessages((TH1*)hBCID);
509 if(hBCID->Integral()>0){
510 //BCID does have some counts in it
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;
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
526 entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
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() ));
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());
543 qualityFlagBCID = kT0Error;
544 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 : %s has NO entries", hBCID->GetName() ));
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());
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);
560 if(hMeanVersusVertex1st->Integral()<1){
561 qualityFlagMeanVersusVertex1st = kT0Error;
562 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMeanVersusVertex1st->GetName() ));
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());
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);
579 if(hVertex1stTVDCon->Integral()<1){
580 qualityFlagVertex1stTVDCon = kT0Error;
581 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCon->GetName() ));
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());
591 if(TMath::Abs(hVertex1stTVDCon->GetMean()) > fTZeroAMinusCErrorThreshold){
592 qualityFlagVertex1stTVDCon = kT0Error;
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());
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);
609 if(hVertex1stTVDCoff->Integral()<1){
610 qualityFlagVertex1stTVDCoff = kT0Warning;
611 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCoff->GetName() ));
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());
622 //----------- time TVDC on ---------
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);
628 if(hMean1stTVDCon->Integral()<1){
629 qualityFlagMean1stTVDCon = kT0Error;
630 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCon->GetName() ));
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());
640 //cout<<"Mean: "<<TMath::Abs(hMean1stTVDCon->GetMean())<<" threshold "<<fTZeroAPlusCErrorThreshold<<endl;
641 if(TMath::Abs(hMean1stTVDCon->GetMean()) > fTZeroAPlusCErrorThreshold){
642 qualityFlagMean1stTVDCon = kT0Error;
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());
654 //----------- time TVDC off ---------
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);
660 if(hMean1stTVDCoff->Integral()<1){
661 qualityFlagMean1stTVDCoff = kT0Warning;
662 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCoff->GetName() ));
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());
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;
686 return ConvertQualityFlagToDouble(lowestQualityFlag);
690 //--------------------------------------------------------------------------
691 Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
696 fhESD = (TH1*) listrec->UncheckedAt(2);
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);
702 f1->GetParameters(&par[0]);
704 TPaveText text(0.30,0.50,0.99,0.99,"NDC");
706 text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
708 AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));
711 if (par[2] > 0.07 && par[2] < 1.) {
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] );
717 if(TMath::Abs(par[1])>0.05) {
719 text.AddText(Form(" Check clock shift on %f ns", par[1]));
720 text.SetFillColor(5);
722 if (par[2] > 1. || TMath::Abs(par[1])>0.1) {
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();
729 TObject *stats = lstF->FindObject("stats");
732 while ((obj = lstF->First())) {
733 while(lstF->Remove(obj)) { }
736 if (stats) lstF->Add(stats);
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) ) ;
747 AliDebug(AliQAv1::GetQADebugLevel(),
748 Form("No ESD QA histogram found, nothing to check"));
757 //--------------------------------------------------------------------------
758 void AliT0QAChecker::EraseOldMessages(TH1* h) const
760 //erase the old captions
761 TList* lstF = h->GetListOfFunctions();
763 TObject *stats = lstF->FindObject("stats");
766 while ((obj = lstF->First())) {
767 while(lstF->Remove(obj)) { }
770 if (stats) lstF->Add(stats);
773 //--------------------------------------------------------------------------
774 Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const
776 //covert quality flag to double
779 switch ( qualityFlag ){
783 checkr = 0.75; break;
785 checkr = 0.25; break;
787 checkr = -1.0; break;
789 AliError("Invalid ecc value. FIXME !");
790 checkr = 0.25; break;
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;
803 for(Int_t ib=1;ib<=nBins;ib++){
804 Float_t val = hV->GetBinContent(ib);
811 if(nBinsAboveThr>0) return sum/nBinsAboveThr;
812 else return hV->GetMean();
815 //--------------------------------------------------------------------------
816 void AliT0QAChecker::GetMeanAndRmsAroundMainMaximum(Float_t &meanHisto,Float_t &rmsHisto, TH1F *histo, int type) const{
823 if(histo->Integral()<0.00001){
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
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);
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);
844 if(nhigh>nb) nhigh = nb;
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);
852 meanHisto = sumWeight/sum; //mean in 1st itteration
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);
863 if(nhigh>nb) nhigh = nb;
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);
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