Bug in beam type comparing in AliZDCDigitizer that prevented PMT gains to be set...
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALQAChecker.cxx
CommitLineData
94594e5d 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/*
17 Checks the quality assurance.
18 By comparing with reference data
19
20 Based on PHOS code written by
21 Y. Schutz CERN July 2007
9e47432c 22
a2655076 23 For the moment we only implement the checking of raw data QA.
24 The checked for ESD and RecPoints will be implemented later.
9e47432c 25
26
9e47432c 27 */
28
94594e5d 29
30// --- ROOT system ---
31#include <TClass.h>
9e47432c 32#include <TH1.h>
33#include <TF1.h>
94594e5d 34#include <TH1I.h>
38986b78 35#include <TH2F.h>
94594e5d 36#include <TIterator.h>
37#include <TKey.h>
38#include <TFile.h>
9e47432c 39#include <TLine.h>
38986b78 40#include <TText.h>
9e47432c 41#include <TPaveText.h>
42#include <TMath.h>
94594e5d 43
44// --- Standard library ---
45
46// --- AliRoot header files ---
47#include "AliLog.h"
a57708c8 48#include "AliCDBManager.h"
49#include "AliCDBEntry.h"
4e25ac79 50#include "AliQAv1.h"
94594e5d 51#include "AliQAChecker.h"
a57708c8 52#include "AliQAThresholds.h"
94594e5d 53#include "AliEMCALQAChecker.h"
54
55ClassImp(AliEMCALQAChecker)
56
9e47432c 57//__________________________________________________________________
58AliEMCALQAChecker::AliEMCALQAChecker() :
59AliQACheckerBase("EMCAL","EMCAL Quality Assurance Data Maker"),
afae9650 60fTextSM(new TText*[fgknSM]),
8a38cd34 61fLineCol(new TLine(47.5,-0.5,47.5,119.5)),
00957c37 62fText(new TPaveText(0.2,0.7,0.8,0.9,"NDC"))
9e47432c 63{
38986b78 64 // ctor
65 fLineCol->SetLineColor(1);
66 fLineCol->SetLineWidth(2);
38986b78 67
68 fTextSM[0]= new TText(20, 12, "SM A0");
8a38cd34 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");
b8769ad2 73 fTextSM[5]= new TText(20, 132,"SM A5");
8a38cd34 74
b8769ad2 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");
8a38cd34 81
b8769ad2 82 for(int i = 0; i < 5; i++) {
8a38cd34 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);
86 }
87
a2e583d8 88 for(int i = 0; i < 3; i++) {
a57708c8 89 fTextL1[i] = new TPaveText(0.2,0.8,0.8,0.9,"NDC");
a2e583d8 90 }
91
8a38cd34 92
9e47432c 93}
94
95//__________________________________________________________________
96AliEMCALQAChecker::~AliEMCALQAChecker()
97{
98 /// dtor
38986b78 99 delete [] fTextSM ;
a42ceb0e 100 delete fLineCol ;
b8769ad2 101 for (Int_t i=0; i<5; ++i) delete fLineRow[i] ;
a42ceb0e 102 delete fText ;
9e47432c 103}
104
9e47432c 105//______________________________________________________________________________
a42ceb0e 106void AliEMCALQAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
9e47432c 107{
108 /// Check objects in list
109
110 if ( index == AliQAv1::kRAW )
111 {
a42ceb0e 112 CheckRaws(test, list);
9e47432c 113 printf ("checkers for task %d \n", index) ;
114 }
115
116 if ( index == AliQAv1::kREC)
117 {
a42ceb0e 118 CheckRecPoints(test, list);
9e47432c 119 }
120
121 if ( index == AliQAv1::kESD )
122 {
a42ceb0e 123 CheckESD(test, list);
9e47432c 124 }
125 AliWarning(Form("Checker for task %d not implement for the moment",index));
9e47432c 126}
127
128//______________________________________________________________________________
129TH1*
130AliEMCALQAChecker::GetHisto(TObjArray* list, const char* hname, Int_t specie) const
131{
132 /// Get a given histo from the list
133 TH1* h = static_cast<TH1*>(list->FindObject(Form("%s_%s",AliRecoParam::GetEventSpecieName(specie),hname)));
134 if (!h)
135 {
136 AliError(Form("Did not find expected histo %s",hname));
137 }
138 return h;
139}
140
141//______________________________________________________________________________
142Double_t
143AliEMCALQAChecker::MarkHisto(TH1& histo, Double_t value) const
144{
145 /// Mark histo as originator of some QA error/warning
146
147 if ( value != 1.0 )
148 {
149 histo.SetBit(AliQAv1::GetQABit());
150 }
151
152 return value;
153}
154
155
156//______________________________________________________________________________
a42ceb0e 157void AliEMCALQAChecker::CheckRaws(Double_t * test, TObjArray ** list)
9e47432c 158{
f05c8877 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.
a57708c8 164
165
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)
171
172 AliCDBManager* man = AliCDBManager::Instance();
173 if(man){
174 AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
175 if(entry){
176 TObjArray* branch = (TObjArray*) entry->GetObject();
177 if(branch){
178 AliQAThresholds* thresholds = (AliQAThresholds*) branch->FindObject("EMC");
179 if(thresholds){
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);
184 if(ParamR)
185 ratioThresh = ParamR->GetVal();
186 if(ParamG)
187 ThreshG = ParamG->GetVal();
188 if(ParamJ)
189 ThreshJ = ParamJ->GetVal();
190 if(ParamL)
191 badLinkThresh = ParamL->GetVal();
192 }
193 }
194 }
195 }
196
38986b78 197 Int_t nTowersPerSM = 24*48; // number of towers in a SuperModule; 24x48
afae9650 198 Double_t nTot = fgknSM * nTowersPerSM ;
180c431b 199 TList *lstF = 0;
de96ebc9 200 Int_t calibSpecieId = (Int_t)TMath::Log2( AliRecoParam::kCalib );
a2655076 201 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
a42ceb0e 202 test[specie] = 0.0 ;
a2e583d8 203 if ( !AliQAv1::Instance()->IsEventSpecieSet(specie)) continue ;
204 if (list[specie]->GetEntries() == 0) test[specie] = 0. ; // nothing to check
a2655076 205 else {
a2e583d8 206 //get calib histos
207 TH2F * hdata = (TH2F*)list[specie]->At(k2DRatioAmp) ;
208 TH1F * ratio = (TH1F*)list[specie]->At(kRatioDist) ;
209
210 //get L1 histos
211 TH2F *hL1GammaPatch = (TH2F*)list[specie]->At(kGL1);
212 TH2F *hL1JetPatch = (TH2F*)list[specie]->At(kJL1);
213 TH1I *hFrameR = (TH1I*)list[specie]->At(kSTUTRU);
214
215 //calib histo checker first:
216
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());
224 }
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());
228 }
229 //
230 lstF = ratio->GetListOfFunctions();
231 CleanListOfFunctions(lstF);
232 //
233 //now check the ratio histogram
234 Double_t binContent = 0. ;
edd592b8 235 Int_t nGoodTower = 0 ;
a2e583d8 236 Double_t rv = 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) ;
edd592b8 240 if (binContent < 1.2 && binContent > 0.8) nGoodTower++ ;
a2e583d8 241 }
242 }
edd592b8 243 rv = nGoodTower/nTot ;
a2e583d8 244 printf("%2.2f %% towers out of range [0.8, 1.2]\n", (1-rv)*100);
245 if(fText){
246 lstF->Add(fText->Clone()) ;
247 fText->Clear() ;
7e1d9a9b 248
a2e583d8 249 fText->AddText(Form("%2.2f %% towers out of range [0.8, 1.2]", (1-rv)*100));
a57708c8 250 if (rv < ratioThresh) {
251 test[specie] = ratioThresh;
a2e583d8 252 // 2 lines text info for quality
253 fText->SetFillColor(2) ;
254 fText->AddText(Form("EMCAL = NOK, CALL EXPERTS!!!"));
255 }
256 else {
a57708c8 257 test[specie] = 1 - ratioThresh;
a2e583d8 258 fText->SetFillColor(3) ;
259 fText->AddText(Form("EMCAL = OK, ENJOY..."));
260 }
261 }//fText
262 } // calib histo checking done
263
264 //now L1 checks:
de96ebc9 265 if (specie != calibSpecieId) {
266 if(hL1GammaPatch->GetEntries() !=0 ) {
a2e583d8 267 lstF = hL1GammaPatch->GetListOfFunctions();
268 CleanListOfFunctions(lstF);
269
270
a57708c8 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
edd592b8 276 Double_t dL1GEntries = hL1GammaPatch->GetEntries();
a57708c8 277 Int_t badL1G[48][64] = {{0}} ;
278 Int_t badL1GTRU[2][16] = {{0}} ;
279 Int_t nBadL1G = 0;
280 Int_t nBadL1GTRU = 0;
281 Double_t binContentTRU[2][16] = {{0.}};
a2e583d8 282 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
a57708c8 283 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
284 Double_t binContent = hL1GammaPatch->GetBinContent(ix, iy) ;
285 if (binContent != 0) {
286
287 // fill counter for TRUs
288 binContentTRU[(Int_t)((ix-1)/24)][(Int_t)((iy-1)/4)] += binContent;
289
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;
293 // nBadL1G += 1;
294 // }
295
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;
301 nBadL1G += 1;
302 }
303 }
304 }
a2e583d8 305 }
306
a57708c8 307 // check TRUs
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;
312 nBadL1GTRU += 1;
313 }
314 }
315 }
316
a2e583d8 317 if(fTextL1[0]){
318 lstF->Add(fTextL1[0]->Clone()) ;
319 fTextL1[0]->Clear() ;
320
a57708c8 321 if (nBadL1G == 0 && nBadL1GTRU == 0 ) {
a2e583d8 322 fTextL1[0]->SetFillColor(3) ;
323 fTextL1[0]->AddText(Form("L1 GAMMA TRIGGER = OK, ENJOY..."));
324 }
a57708c8 325 else if (nBadL1G == 0){
a2e583d8 326 fTextL1[0]->SetFillColor(2) ;
a57708c8 327 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER (TRU) = CALL EXPERT!!"));
328
329 }
330 else{
331 fTextL1[0]->SetFillColor(2) ;
332 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER = CALL EXPERT!!"));
333 /*
334 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
335 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
edd592b8 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);
a57708c8 337 }
338 }
339 */
a2e583d8 340 }
341 }//fTextL1[0]
342 }// L1 gamma patch checking done
343
344 if(hL1JetPatch->GetEntries() !=0) {
345 lstF = hL1JetPatch->GetListOfFunctions();
346 CleanListOfFunctions(lstF);
347
a57708c8 348 // Checker for L1JetPatch
349 //Double_t dL1JmeanTrig = 1/126.;
350 //Int_t sigmaJ = 5; // deviation from mean value
edd592b8 351 Double_t dL1JEntries = hL1JetPatch->GetEntries();
352 Int_t badL1J[12][16] = {{0}} ;
353 Int_t nBadL1J = 0;
a2e583d8 354 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
a57708c8 355 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
356 Double_t binContent = hL1JetPatch->GetBinContent(ix, iy) ;
357 if (binContent != 0) {
358
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 ;
362 // nBadL1J += 1;
363 // }
364
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 ;
369 nBadL1J += 1;
370 }
371 }
372 }
a2e583d8 373 }
a57708c8 374
a2e583d8 375 if(fTextL1[1]){
376 lstF->Add(fTextL1[1]->Clone()) ;
377 fTextL1[1]->Clear() ;
378
edd592b8 379 if (nBadL1J == 0) {
a2e583d8 380 fTextL1[1]->SetFillColor(3) ;
381 fTextL1[1]->AddText(Form("L1 JET TRIGGER = OK, ENJOY..."));
382 }
383 else {
384 fTextL1[1]->SetFillColor(2) ;
385 fTextL1[1]->AddText(Form("HOT SPOT IN L1 JET TRIGGER = CALL EXPERT!!"));
386/*
387 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
388 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
edd592b8 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));
a2e583d8 390 }
391 }
392*/
393
394 }
395 }//fTextL1[1]
396 } // L1 Jet patch checking done
de96ebc9 397 } // if (specie != calibSpecieId) ..
a2e583d8 398
399 if(hFrameR->GetEntries() !=0) {
400 lstF = hFrameR->GetListOfFunctions();
401 CleanListOfFunctions(lstF);
402
edd592b8 403 Int_t badLink[32] = {0};
404 Int_t nBadLink = 0;
bb5d026f 405 for(Int_t ix = 1; ix <= hFrameR->GetNbinsX(); ix++) {
a2e583d8 406 Double_t binContent = hFrameR->GetBinContent(ix) ;
407 if (binContent == 0) {
bb5d026f 408 badLink[ix-1] += 1;
edd592b8 409 nBadLink += 1;
a2e583d8 410 }
411 }
412 if(fTextL1[2]){
413 lstF->Add(fTextL1[2]->Clone()) ;
414 fTextL1[2]->Clear() ;
415
a57708c8 416 if (nBadLink < badLinkThresh) {
a2e583d8 417 fTextL1[2]->SetFillColor(3) ;
418 fTextL1[2]->AddText(Form("LINK TRU-STU = OK, ENJOY..."));
419 }
420 else {
421 fTextL1[2]->SetFillColor(2) ;
422 fTextL1[2]->AddText(Form("PROBLEM WITH TRU-STU LINK = CALL EXPERT!!"));
423/*
424 for(Int_t ix = 0; ix <= hFrameR->GetNbinsX(); ix++) {
edd592b8 425 if(badLink[ix] != 0) printf("STU link with TRU %d is out\n",ix);
a2e583d8 426 }
427*/
428 }
429 }//fTextL1[2]
430 } // Checker for link TRU-STU done
de96ebc9 431 }
9e47432c 432
de96ebc9 433 } // specie
a2e583d8 434}
9e47432c 435//______________________________________________________________________________
a2e583d8 436
9e47432c 437void AliEMCALQAChecker::Init(const AliQAv1::DETECTORINDEX_t det)
438{
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 ;
9e47432c 445 lowValue[AliQAv1::kWARNING] = 0.1 ;
6a754398 446 hiValue[AliQAv1::kWARNING] = 0.5 ;
9e47432c 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]) ;
452}
94594e5d 453
a2e583d8 454//______________________________________________________________________________
455
456void AliEMCALQAChecker::CleanListOfFunctions(TList *list)
edd592b8 457{ // clean up
a2e583d8 458
459 if (list) {
460 TObject *stats = list->FindObject("stats"); list->Remove(stats);
461 TObject *obj;
462 while ((obj = list->First())) { while(list->Remove(obj)) { } delete obj; }
463 if (stats) list->Add(stats);
464 }
465 else {
466 AliWarning(Form("Checker : empty list of data functions; returning"));
467 return;
468 }
469
470}
471
472