1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 Checks the quality assurance.
18 By comparing with reference data
20 Based on PHOS code written by
21 Y. Schutz CERN July 2007
23 For the moment we only implement the checking of raw data QA.
24 The checked for ESD and RecPoints will be implemented later.
30 // --- ROOT system ---
36 #include <TIterator.h>
41 #include <TPaveText.h>
44 // --- Standard library ---
46 // --- AliRoot header files ---
48 #include "AliCDBManager.h"
49 #include "AliCDBEntry.h"
51 #include "AliQAChecker.h"
52 #include "AliQAThresholds.h"
53 #include "AliEMCALQAChecker.h"
55 ClassImp(AliEMCALQAChecker)
57 //__________________________________________________________________
58 AliEMCALQAChecker::AliEMCALQAChecker() :
59 AliQACheckerBase("EMCAL","EMCAL Quality Assurance Data Maker"),
60 fTextSM(new TText*[fgknSM]),
61 fLineCol(new TLine(47.5,-0.5,47.5,119.5)),
62 fText(new TPaveText(0.2,0.7,0.8,0.9,"NDC"))
65 fLineCol->SetLineColor(1);
66 fLineCol->SetLineWidth(2);
68 fTextSM[0]= new TText(20, 12, "SM A0");
69 fTextSM[1]= new TText(20, 36, "SM A1");
70 fTextSM[2]= new TText(20, 60, "SM A2");
71 fTextSM[3]= new TText(20, 84, "SM A3");
72 fTextSM[4]= new TText(20, 108,"SM A4");
73 fTextSM[5]= new TText(20, 132,"SM A5");
75 fTextSM[6]= new TText(64, 12, "SM C0");
76 fTextSM[7]= new TText(64, 36, "SM C1");
77 fTextSM[8]= new TText(64, 60, "SM C2");
78 fTextSM[9]= new TText(64, 84, "SM C3");
79 fTextSM[10]= new TText(64, 108,"SM C4");
80 fTextSM[11]= new TText(64, 132,"SM C5");
82 for(int i = 0; i < 5; i++) {
83 fLineRow[i] = new TLine(-0.5,23.5+(24*i),95.5,23.5+(24*i));
84 fLineRow[i]->SetLineColor(1);
85 fLineRow[i]->SetLineWidth(2);
88 for(int i = 0; i < 3; i++) {
89 fTextL1[i] = new TPaveText(0.2,0.8,0.8,0.9,"NDC");
95 //__________________________________________________________________
96 AliEMCALQAChecker::~AliEMCALQAChecker()
101 for (Int_t i=0; i<5; ++i) delete fLineRow[i] ;
105 //______________________________________________________________________________
106 void AliEMCALQAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
108 /// Check objects in list
110 if ( index == AliQAv1::kRAW )
112 CheckRaws(test, list);
113 printf ("checkers for task %d \n", index) ;
116 if ( index == AliQAv1::kREC)
118 CheckRecPoints(test, list);
121 if ( index == AliQAv1::kESD )
123 CheckESD(test, list);
125 AliWarning(Form("Checker for task %d not implement for the moment",index));
128 //______________________________________________________________________________
130 AliEMCALQAChecker::GetHisto(TObjArray* list, const char* hname, Int_t specie) const
132 /// Get a given histo from the list
133 TH1* h = static_cast<TH1*>(list->FindObject(Form("%s_%s",AliRecoParam::GetEventSpecieName(specie),hname)));
136 AliError(Form("Did not find expected histo %s",hname));
141 //______________________________________________________________________________
143 AliEMCALQAChecker::MarkHisto(TH1& histo, Double_t value) const
145 /// Mark histo as originator of some QA error/warning
149 histo.SetBit(AliQAv1::GetQABit());
156 //______________________________________________________________________________
157 void AliEMCALQAChecker::CheckRaws(Double_t * test, TObjArray ** list)
159 // Check RAW QA histograms
160 // -- Yaxian Mao, CCNU/CERN/LPSC
161 //adding new checking method: 25/04/2010, Yaxian Mao
162 //Comparing the amplitude from current run to the reference run, if the ratio in the range [0.8, .12], count as a good tower.
163 //If more than 90% towers are good, EMCAL works fine, otherwise experts should be contacted.
166 // Retrieve the thresholds
167 Float_t ratioThresh = 0.9; // threshold for calibration ratio = good towers/all towers (default 0.9)
168 Float_t ThreshG = 0.5; // threshold for L1 Gamma triggers (default 0.5)
169 Float_t ThreshJ = 0.5; // threshold for L1 Jet triggers (default 0.5)
170 Int_t badLinkThresh = 1; // threshold for bad links (default 1)
172 AliCDBManager* man = AliCDBManager::Instance();
174 AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
176 TObjArray* branch = (TObjArray*) entry->GetObject();
178 AliQAThresholds* thresholds = (AliQAThresholds*) branch->FindObject("EMC");
180 TParameter<float>* ParamR = (TParameter<float>*) thresholds->GetThreshold(0);
181 TParameter<float>* ParamG = (TParameter<float>*) thresholds->GetThreshold(1);
182 TParameter<float>* ParamJ = (TParameter<float>*) thresholds->GetThreshold(2);
183 TParameter<int>* ParamL = (TParameter<int>*) thresholds->GetThreshold(3);
185 ratioThresh = ParamR->GetVal();
187 ThreshG = ParamG->GetVal();
189 ThreshJ = ParamJ->GetVal();
191 badLinkThresh = ParamL->GetVal();
197 Int_t nTowersPerSM = 24*48; // number of towers in a SuperModule; 24x48
198 Double_t nTot = fgknSM * nTowersPerSM ;
200 Int_t calibSpecieId = (Int_t)TMath::Log2( AliRecoParam::kCalib );
201 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
203 if ( !AliQAv1::Instance()->IsEventSpecieSet(specie)) continue ;
204 if (list[specie]->GetEntries() == 0) test[specie] = 0. ; // nothing to check
207 TH2F * hdata = (TH2F*)list[specie]->At(k2DRatioAmp) ;
208 TH1F * ratio = (TH1F*)list[specie]->At(kRatioDist) ;
211 TH2F *hL1GammaPatch = (TH2F*)list[specie]->At(kGL1);
212 TH2F *hL1JetPatch = (TH2F*)list[specie]->At(kJL1);
213 TH1I *hFrameR = (TH1I*)list[specie]->At(kSTUTRU);
215 //calib histo checker first:
217 if(hdata->GetEntries()!=0 && ratio->GetEntries()!=0) {
218 //adding the lines to distinguish different SMs
219 lstF = hdata->GetListOfFunctions();
220 CleanListOfFunctions(lstF);
221 lstF->Add(fLineCol->Clone());
222 for(Int_t iLine = 0; iLine < 4; iLine++) {
223 lstF->Add(fLineRow[iLine]->Clone());
225 //Now adding the text to for each SM
226 for(Int_t iSM = 0 ; iSM < fgknSM ; iSM++){ //number of SMs loop start
227 lstF->Add(fTextSM[iSM]->Clone());
230 lstF = ratio->GetListOfFunctions();
231 CleanListOfFunctions(lstF);
233 //now check the ratio histogram
234 Double_t binContent = 0. ;
235 Int_t nGoodTower = 0 ;
237 for(Int_t ix = 1; ix <= hdata->GetNbinsX(); ix++) {
238 for(Int_t iy = 1; iy <= hdata->GetNbinsY(); iy++) {
239 binContent = hdata->GetBinContent(ix, iy) ;
240 if (binContent < 1.2 && binContent > 0.8) nGoodTower++ ;
243 rv = nGoodTower/nTot ;
244 printf("%2.2f %% towers out of range [0.8, 1.2]\n", (1-rv)*100);
246 lstF->Add(fText->Clone()) ;
249 fText->AddText(Form("%2.2f %% towers out of range [0.8, 1.2]", (1-rv)*100));
250 if (rv < ratioThresh) {
251 test[specie] = ratioThresh;
252 // 2 lines text info for quality
253 fText->SetFillColor(2) ;
254 fText->AddText(Form("EMCAL = NOK, CALL EXPERTS!!!"));
257 test[specie] = 1 - ratioThresh;
258 fText->SetFillColor(3) ;
259 fText->AddText(Form("EMCAL = OK, ENJOY..."));
262 } // calib histo checking done
265 if (specie != calibSpecieId) {
266 if(hL1GammaPatch->GetEntries() !=0 ) {
267 lstF = hL1GammaPatch->GetListOfFunctions();
268 CleanListOfFunctions(lstF);
271 // Checker for L1GammaPatch
272 //Double_t dL1GmeanTrig = 1./2961.;
273 //Double_t dL1GmeanTrigTRU = 1./32.;
274 //Int_t sigmaG = 100; // deviation from mean value (increased to 100)
275 //Int_t sigmaGTRU = 5; // deviation from mean value for TRUs
276 Double_t dL1GEntries = hL1GammaPatch->GetEntries();
277 Int_t badL1G[48][64] = {{0}} ;
278 Int_t badL1GTRU[2][16] = {{0}} ;
280 Int_t nBadL1GTRU = 0;
281 Double_t binContentTRU[2][16] = {{0.}};
282 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
283 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
284 Double_t binContent = hL1GammaPatch->GetBinContent(ix, iy) ;
285 if (binContent != 0) {
287 // fill counter for TRUs
288 binContentTRU[(Int_t)((ix-1)/24)][(Int_t)((iy-1)/4)] += binContent;
290 // OLD METHOD (if a patch triggers > sigmaG * mean value (1/#patch positions total) says "hot spot !")
291 // if ((double)binContent/(double)dL1GEntries > sigmaG*dL1GmeanTrig) {
292 // badL1G[ix-1][iy-1] += 1;
296 // NEW METHOD (if Rate > Threshold * ( (Number of towers or TRUs * Average rate) - Rate ) --> "hot spot !")
297 // Thresold = how much does the noisy tower/TRU contribute to the rate
298 // 1.0 --> Rate of noisy tower/TRU = Rate of all other towers/TRUs
299 if (binContent/dL1GEntries > ThreshG / ( 1 + ThreshG )) {
300 badL1G[ix-1][iy-1] += 1;
308 for(Int_t ix = 1; ix <= 2; ix++) {
309 for(Int_t iy = 1; iy <= 16; iy++) {
310 if(binContentTRU[ix-1][iy-1]/dL1GEntries > ThreshG / ( 1 + ThreshG )) {
311 badL1GTRU[ix-1][iy-1] += 1;
318 lstF->Add(fTextL1[0]->Clone()) ;
319 fTextL1[0]->Clear() ;
321 if (nBadL1G == 0 && nBadL1GTRU == 0 ) {
322 fTextL1[0]->SetFillColor(3) ;
323 fTextL1[0]->AddText(Form("L1 GAMMA TRIGGER = OK, ENJOY..."));
325 else if (nBadL1G == 0){
326 fTextL1[0]->SetFillColor(2) ;
327 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER (TRU) = CALL EXPERT!!"));
331 fTextL1[0]->SetFillColor(2) ;
332 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER = CALL EXPERT!!"));
334 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
335 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
336 if(badL1G[ix-1][iy-1] != 0) printf("L1 Gamma patch with position x = %d, y = %d is out of range\n",ix,iy);
342 }// L1 gamma patch checking done
344 if(hL1JetPatch->GetEntries() !=0) {
345 lstF = hL1JetPatch->GetListOfFunctions();
346 CleanListOfFunctions(lstF);
348 // Checker for L1JetPatch
349 //Double_t dL1JmeanTrig = 1/126.;
350 //Int_t sigmaJ = 5; // deviation from mean value
351 Double_t dL1JEntries = hL1JetPatch->GetEntries();
352 Int_t badL1J[12][16] = {{0}} ;
354 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
355 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
356 Double_t binContent = hL1JetPatch->GetBinContent(ix, iy) ;
357 if (binContent != 0) {
359 // OLD METHOD (if a patch triggers > sigmaJ * mean value (1/#patch positions total) says "hot spot !")
360 // if ((double)binContent/(double)dL1JEntries > sigmaJ*dL1JmeanTrig) {
361 // badL1J[ix-1][iy-1] += 1 ;
365 // NEW METHOD (if Rate > Threshold * ( (Number of towers or TRUs * Average rate) - Rate ) --> "hot spot !")
366 // Threshold: same definitionas for Gamma
367 if ((double)binContent/(double)dL1JEntries > ThreshJ / ( 1 + ThreshJ )) {
368 badL1J[ix-1][iy-1] += 1 ;
376 lstF->Add(fTextL1[1]->Clone()) ;
377 fTextL1[1]->Clear() ;
380 fTextL1[1]->SetFillColor(3) ;
381 fTextL1[1]->AddText(Form("L1 JET TRIGGER = OK, ENJOY..."));
384 fTextL1[1]->SetFillColor(2) ;
385 fTextL1[1]->AddText(Form("HOT SPOT IN L1 JET TRIGGER = CALL EXPERT!!"));
387 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
388 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
389 if(badL1J[ix-1][iy-1] != 0) printf("L1 Jet patch with position x = %d, y = %d is out of range\n",(4*ix-4),(4*iy-4));
396 } // L1 Jet patch checking done
397 } // if (specie != calibSpecieId) ..
399 if(hFrameR->GetEntries() !=0) {
400 lstF = hFrameR->GetListOfFunctions();
401 CleanListOfFunctions(lstF);
403 Int_t badLink[32] = {0};
405 for(Int_t ix = 1; ix <= hFrameR->GetNbinsX(); ix++) {
406 Double_t binContent = hFrameR->GetBinContent(ix) ;
407 if (binContent == 0) {
413 lstF->Add(fTextL1[2]->Clone()) ;
414 fTextL1[2]->Clear() ;
416 if (nBadLink < badLinkThresh) {
417 fTextL1[2]->SetFillColor(3) ;
418 fTextL1[2]->AddText(Form("LINK TRU-STU = OK, ENJOY..."));
421 fTextL1[2]->SetFillColor(2) ;
422 fTextL1[2]->AddText(Form("PROBLEM WITH TRU-STU LINK = CALL EXPERT!!"));
424 for(Int_t ix = 0; ix <= hFrameR->GetNbinsX(); ix++) {
425 if(badLink[ix] != 0) printf("STU link with TRU %d is out\n",ix);
430 } // Checker for link TRU-STU done
435 //______________________________________________________________________________
437 void AliEMCALQAChecker::Init(const AliQAv1::DETECTORINDEX_t det)
439 /// intialises QA and QA checker settings
440 AliQAv1::Instance(det) ;
441 Float_t hiValue[AliQAv1::kNBIT] ;
442 Float_t lowValue[AliQAv1::kNBIT] ;
443 lowValue[AliQAv1::kINFO] = 0.0 ;
444 hiValue[AliQAv1::kINFO] = 0.1 ;
445 lowValue[AliQAv1::kWARNING] = 0.1 ;
446 hiValue[AliQAv1::kWARNING] = 0.5 ;
447 lowValue[AliQAv1::kERROR] = 0.5 ;
448 hiValue[AliQAv1::kERROR] = 0.8 ;
449 lowValue[AliQAv1::kFATAL] = 0.8 ;
450 hiValue[AliQAv1::kFATAL] = 1.0 ;
451 SetHiLo(&hiValue[0], &lowValue[0]) ;
454 //______________________________________________________________________________
456 void AliEMCALQAChecker::CleanListOfFunctions(TList *list)
460 TObject *stats = list->FindObject("stats"); list->Remove(stats);
462 while ((obj = list->First())) { while(list->Remove(obj)) { } delete obj; }
463 if (stats) list->Add(stats);
466 AliWarning(Form("Checker : empty list of data functions; returning"));