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");
130 TObjArray* t0branch = (TObjArray*) entry->GetObject();
132 AliQAThresholds* thresholds = (AliQAThresholds*) t0branch->FindObject("T00");
133 // here you should test that you got a non-null pointer
135 if(!thresholds) return;
136 if(AliDAQ::DetectorID("T0")!= thresholds->GetDetectorId()){
137 AliInfo(Form("DETECTOR ID %d DOES NOT MATCH TO TZERO",thresholds->GetDetectorId()));
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();
149 if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean LED from a good run
150 fMeanLEDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
153 if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean QTC from a good run
154 fMeanQTCFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
157 iparam = 73; //CFD threshold
158 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
159 fCFDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
161 iparam = 74; //LED threshold
162 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
163 fLEDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
165 iparam = 75; //QTC threshold
166 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
167 fQTCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
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();
174 // Super-basic check on the QA histograms on the input list:
175 // look whether they are empty!
177 iparam = 83; //Error level threshold on QTC efficiency
178 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
179 fQTCEfficiencyErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
183 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
184 fBCIDPeriodParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
188 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
189 fBCIDOffsetParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
193 if((TParameter<int>*) thresholds->GetThreshold(iparam)){
194 fBCIDBandWidthParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
198 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
199 fTZeroAPlusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
203 if((TParameter<float>*) thresholds->GetThreshold(iparam)){
204 fTZeroAMinusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
208 char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ;
210 AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
213 AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
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
222 for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
223 if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
227 if(index == AliQAv1::kRAW){
229 //if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){// if (index == AliQAv1::kRAW )
230 //check laser data efficiencies
231 // Double_t qaFlag = CheckLaser(list[specie]);
232 // if(qaFlag < test[specie]) test[specie] = qaFlag;
235 //if(//AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib ||
236 // AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
237 // AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){
238 //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
241 // Double_t qaFlag = CheckBCID(list[specie]);
242 // if(qaFlag < test[specie]) test[specie] = qaFlag;
245 if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
246 AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){
247 //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
249 Double_t qaFlag = CheckRaw(list[specie]);
250 if(qaFlag < test[specie]) test[specie] = qaFlag;
254 if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){
255 test[specie] = CheckESD(list[specie]);
260 //--------------------------------------------------------------------------
261 //Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
266 //--------------------------------------------------------------------------
267 Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
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
273 //clean objects added at previous checks
274 EraseOldMessages((TH1*) hCFDEffData);
275 hCFDEffData->GetListOfFunctions()->Add((TH1D*) hLEDEffData->Clone());
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());
284 //Fk Draw CFD-mean for each PMT
285 TH2F* fhCFD = (TH2F*) listrec->UncheckedAt(210);
286 TH1F* fhCFDSubtrMean = (TH1F*) listrec->UncheckedAt(231);
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);
294 Float_t deviation = mean - fMeanCFDFromGoodRunParam[ipmt];
296 fhCFDSubtrMean->SetBinContent(ipmt+1,deviation);
297 fhCFDSubtrMean->SetBinError(ipmt+1,rms);
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());
314 //Fk Draw LED-mean for each PMT
315 TH2F* fhLED = (TH2F*) listrec->UncheckedAt(211);
316 TH1F* fhLEDSubtrMean = (TH1F*) listrec->UncheckedAt(232);
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];
325 fhLEDSubtrMean->SetBinContent(ipmt+1,deviation);
326 fhLEDSubtrMean->SetBinError(ipmt+1,rms);
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());
342 //Fk Draw QTC-mean for each PMT
343 TH2F* fhQTC = (TH2F*) listrec->UncheckedAt(212);
344 TH1F* fhQTCSubtrMean = (TH1F*) listrec->UncheckedAt(233);
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];
353 fhQTCSubtrMean->SetBinContent(ipmt+1,deviation);
354 fhQTCSubtrMean->SetBinError(ipmt+1,rms);
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());
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);
380 hRatioCFDLEDeff->SetBinContent(ipmt,c0/c1);
382 hRatioCFDLEDeff->SetBinContent(ipmt,0);
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());
397 // PERFROM CHECKS on HISTOGRAMS
399 //-------- triggers -----------
400 Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram;
402 TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger
404 // clean objects added at previous checks
405 EraseOldMessages((TH1*) hTrigger);
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() ));
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"));
417 text.SetBorderSize(0);
418 text.SetFillStyle(0);
419 hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());
422 }else{ //Trigger histo empty
424 qualityFlagTrigger = kT0Error;
425 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hTrigger->GetName() ));
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"));
431 text.SetBorderSize(0);
432 text.SetFillStyle(0);
433 hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());
436 //---------- CFD eff/LED eff within subrange -----------
437 Int_t qualityFlagRatioCFDeffLEDeff = kT0Info; //init quality flag for a given histogram;
438 int nPMTs = hRatioCFDLEDeff->GetNbinsX();
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;
445 if(qualityFlagRatioCFDeffLEDeff == kT0Error){
446 TPaveText text(0.20,0.50,0.99,0.99,"NDC");
447 text.AddText(Form("Problem with efficiency ratio CFD/LED !!!"));
448 text.AddText(Form("If T0 is READY and beam is on report"));
449 text.AddText(Form("the problem to the T0 on-call expert"));
450 text.SetBorderSize(0);
451 text.SetFillStyle(0);
452 hRatioCFDLEDeff->GetListOfFunctions()->Add((TPaveText*)text.Clone());
456 //---------- CFD - mean CFD -----------
457 Int_t qualityFlagCFDSubtr = kT0Info; //init quality flag for a given histogram;
458 nPMTs = fhCFDSubtrMean->GetNbinsX();
460 for(int ipmt=1; ipmt<=nPMTs; ipmt++){
461 if(TMath::Abs( fhCFDSubtrMean->GetBinContent(ipmt)) > fCFDErrorThreshold){
462 qualityFlagCFDSubtr = kT0Error;
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());
475 //--------- QTC efficiency ---------------
477 Int_t qualityFlagEffQTC = kT0Info; //init quality flag for a given histogram;
478 TH1F *hEffQTC = (TH1F*) listrec->UncheckedAt(209);//hRawTrigger
480 EraseOldMessages((TH1*) hEffQTC); // clean objects added at previous checks
482 nPMTs = hEffQTC->GetNbinsX();
483 for(int ipmt=1; ipmt<=nPMTs; ipmt++){
484 if(TMath::Abs( hEffQTC->GetBinContent(ipmt)) < fQTCEfficiencyErrorThreshold){
485 qualityFlagEffQTC = kT0Error;
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());
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());
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
507 // clean objects added at previous checks
508 EraseOldMessages((TH1*)hBCID);
510 if(hBCID->Integral()>0){
511 //BCID does have some counts in it
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;
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
527 entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
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() ));
535 TPaveText text(0.20,0.50,0.99,0.99,"NDC");
536 text.AddText(Form("Check if entries are on diagonal"));
537 text.AddText(Form("Report readout problem to the T0 on-call expert"));
538 text.SetBorderSize(0);
539 text.SetFillStyle(0);
540 hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());
544 qualityFlagBCID = kT0Error;
545 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 : %s has NO entries", hBCID->GetName() ));
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());
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);
561 if(hMeanVersusVertex1st->Integral()<1){
562 qualityFlagMeanVersusVertex1st = kT0Error;
563 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMeanVersusVertex1st->GetName() ));
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"));
568 text.AddText(Form("the problem to the T0 on-call expert"));
569 text.SetBorderSize(0);
570 text.SetFillStyle(0);
571 hMeanVersusVertex1st->GetListOfFunctions()->Add((TPaveText*)text.Clone());
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);
580 if(hVertex1stTVDCon->Integral()<1){
581 qualityFlagVertex1stTVDCon = kT0Error;
582 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCon->GetName() ));
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());
592 if(TMath::Abs(hVertex1stTVDCon->GetMean()) > fTZeroAMinusCErrorThreshold){
593 qualityFlagVertex1stTVDCon = kT0Error;
595 TPaveText text(0.20,0.50,0.99,0.99,"NDC");
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"));
599 text.SetBorderSize(0);
600 text.SetFillStyle(0);
601 hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
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);
610 if(hVertex1stTVDCoff->Integral()<1){
611 qualityFlagVertex1stTVDCoff = kT0Warning;
612 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCoff->GetName() ));
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());
623 //----------- time TVDC on ---------
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);
629 if(hMean1stTVDCon->Integral()<1){
630 qualityFlagMean1stTVDCon = kT0Error;
631 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCon->GetName() ));
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());
641 //cout<<"Mean: "<<TMath::Abs(hMean1stTVDCon->GetMean())<<" threshold "<<fTZeroAPlusCErrorThreshold<<endl;
642 if(TMath::Abs(hMean1stTVDCon->GetMean()) > fTZeroAPlusCErrorThreshold){
643 qualityFlagMean1stTVDCon = kT0Error;
645 TPaveText text(0.20,0.50,0.99,0.99,"NDC");
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"));
649 text.SetBorderSize(0);
650 text.SetFillStyle(0);
651 hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
655 //----------- time TVDC off ---------
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);
661 if(hMean1stTVDCoff->Integral()<1){
662 qualityFlagMean1stTVDCoff = kT0Warning;
663 AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCoff->GetName() ));
665 TPaveText text(0.20,0.50,0.99,0.99,"NDC");
666 text.AddText(Form("Warning: NO ENTRIES"));
667 text.SetBorderSize(0);
668 text.SetFillStyle(0);
669 hMean1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());
674 //----------------------- executive summary ---------------------
675 int lowestQualityFlag = (int) qualityFlagTrigger;
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;
687 return ConvertQualityFlagToDouble(lowestQualityFlag);
691 //--------------------------------------------------------------------------
692 Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
697 fhESD = (TH1*) listrec->UncheckedAt(2);
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);
703 f1->GetParameters(&par[0]);
705 TPaveText text(0.30,0.50,0.99,0.99,"NDC");
707 text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
709 AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));
712 if (par[2] > 0.07 && par[2] < 1.) {
714 text.AddText(Form("not good resolution :\n %f ns\n", par[2] ));
715 text.SetFillColor(5);
716 printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
718 if(TMath::Abs(par[1])>0.05) {
720 text.AddText(Form(" Check clock shift on %f ns", par[1]));
721 text.SetFillColor(5);
723 if (par[2] > 1. || TMath::Abs(par[1])>0.1) {
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();
730 TObject *stats = lstF->FindObject("stats");
733 while ((obj = lstF->First())) {
734 while(lstF->Remove(obj)) { }
737 if (stats) lstF->Add(stats);
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) ) ;
748 AliDebug(AliQAv1::GetQADebugLevel(),
749 Form("No ESD QA histogram found, nothing to check"));
758 //--------------------------------------------------------------------------
759 void AliT0QAChecker::EraseOldMessages(TH1* h) const
761 //erase the old captions
762 TList* lstF = h->GetListOfFunctions();
764 TObject *stats = lstF->FindObject("stats");
767 while ((obj = lstF->First())) {
768 while(lstF->Remove(obj)) { }
771 if (stats) lstF->Add(stats);
774 //--------------------------------------------------------------------------
775 Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const
777 //covert quality flag to double
780 switch ( qualityFlag ){
784 checkr = 0.75; break;
786 checkr = 0.25; break;
788 checkr = -1.0; break;
790 AliError("Invalid ecc value. FIXME !");
791 checkr = 0.25; break;
797 //--------------------------------------------------------------------------
798 Float_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;
804 for(Int_t ib=1;ib<=nBins;ib++){
805 Float_t val = hV->GetBinContent(ib);
812 if(nBinsAboveThr>0) return sum/nBinsAboveThr;
813 else return hV->GetMean();
816 //--------------------------------------------------------------------------
817 void AliT0QAChecker::GetMeanAndRmsAroundMainMaximum(Float_t &meanHisto,Float_t &rmsHisto, TH1F *histo, int type) const{
824 if(histo->Integral()<0.00001){
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
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);
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);
845 if(nhigh>nb) nhigh = nb;
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);
853 meanHisto = sumWeight/sum; //mean in 1st itteration
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);
864 if(nhigh>nb) nhigh = nb;
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);
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