Adding include path to allow compilation of CleanGeom task
[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);
b4776d2d 113 //printf ("checkers for task %d \n", index) ;
9e47432c 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 }
b4776d2d 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++) {
5fb50596 202
a42ceb0e 203 test[specie] = 0.0 ;
a2e583d8 204 if ( !AliQAv1::Instance()->IsEventSpecieSet(specie)) continue ;
205 if (list[specie]->GetEntries() == 0) test[specie] = 0. ; // nothing to check
a2655076 206 else {
5fb50596 207 //get calib histos
208 TH2F * hdata = (TH2F*)list[specie]->At(k2DRatioAmp) ;
209 TH1F * ratio = (TH1F*)list[specie]->At(kRatioDist) ;
210
211 //get L1 histos
212 TH2F *hL1GammaPatch = (TH2F*)list[specie]->At(kGL1);
213 TH2F *hL1JetPatch = (TH2F*)list[specie]->At(kJL1);
214 TH1I *hFrameR = (TH1I*)list[specie]->At(kSTUTRU);
215
216
217 // =======================================================================================
218 //calib histo checker first:
219 if( hdata && ratio ){
a2e583d8 220
5fb50596 221 // first clean lines, text (functions)
222 lstF = hdata->GetListOfFunctions();
223 CleanListOfFunctions(lstF);
224 lstF = ratio->GetListOfFunctions();
225 CleanListOfFunctions(lstF);
226
227 if(hdata->GetEntries()!=0 && ratio->GetEntries()!=0) {
228
229 lstF = hdata->GetListOfFunctions();
230
231 //adding the lines to distinguish different SMs
232 lstF->Add(fLineCol->Clone());
233 for(Int_t iLine = 0; iLine < 5; iLine++) {
234 lstF->Add(fLineRow[iLine]->Clone());
235 }
236 //Now adding the text to for each SM
237 for(Int_t iSM = 0 ; iSM < fgknSM ; iSM++){ //number of SMs loop start
238 lstF->Add(fTextSM[iSM]->Clone());
239 }
240
241
242 //now check the ratio histogram
243 lstF = ratio->GetListOfFunctions();
244
245 Double_t binContent = 0. ;
246 Int_t nGoodTower = 0 ;
247 Double_t rv = 0. ;
248 for(Int_t ix = 1; ix <= hdata->GetNbinsX(); ix++) {
249 for(Int_t iy = 1; iy <= hdata->GetNbinsY(); iy++) {
250 binContent = hdata->GetBinContent(ix, iy) ;
251 if (binContent < 1.2 && binContent > 0.8) nGoodTower++ ;
252 }
253 }
254 rv = nGoodTower/nTot ;
255 //printf("%2.2f %% towers out of range [0.8, 1.2]\n", (1-rv)*100);
256 if(fText){
257 lstF->Add(fText->Clone()) ;
258 fText->Clear() ;
259
260 fText->AddText(Form("%2.2f %% towers out of range [0.8, 1.2]", (1-rv)*100));
261 if (rv < ratioThresh) {
262 test[specie] = ratioThresh;
263 // 2 lines text info for quality
264 fText->SetFillColor(2) ;
265 fText->AddText(Form("EMCAL = NOK, CALL EXPERTS!!!"));
266 }
267 else {
268 test[specie] = 1 - ratioThresh;
269 fText->SetFillColor(3) ;
270 fText->AddText(Form("EMCAL = OK, ENJOY..."));
271 }
272 }//fText
273 }//calib histo checking done
274 }//histograms NOT NULL
275
276 // ========================================================================================
277 // now L1 checks:
278
279 if( hL1GammaPatch ){
280
281 // first clean lines, text (functions)
282 lstF = hL1GammaPatch->GetListOfFunctions();
283 CleanListOfFunctions(lstF);
284
285 if (specie != calibSpecieId) {
286 //if(hL1GammaPatch->GetEntries() !=0 ) {
287 if(hL1GammaPatch->GetEntries() > 10) { // need some statistics for hot spot calculation
288 lstF = hL1GammaPatch->GetListOfFunctions();
289
290 // Checker for L1GammaPatch
291 //Double_t dL1GmeanTrig = 1./2961.;
292 //Double_t dL1GmeanTrigTRU = 1./32.;
293 //Int_t sigmaG = 100; // deviation from mean value (increased to 100)
294 //Int_t sigmaGTRU = 5; // deviation from mean value for TRUs
295 Double_t dL1GEntries = hL1GammaPatch->GetEntries();
296 Int_t badL1G[48][64] = {{0}} ;
297 Int_t badL1GTRU[2][16] = {{0}} ;
298 Int_t nBadL1G = 0;
299 Int_t nBadL1GTRU = 0;
300 Double_t binContentTRU[2][16] = {{0.}};
301 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
302 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
303 Double_t binContent = hL1GammaPatch->GetBinContent(ix, iy) ;
304 if (binContent != 0) {
305
306 // fill counter for TRUs
307 binContentTRU[(Int_t)((ix-1)/24)][(Int_t)((iy-1)/4)] += binContent;
308
309 // OLD METHOD (if a patch triggers > sigmaG * mean value (1/#patch positions total) says "hot spot !")
310 // if ((double)binContent/(double)dL1GEntries > sigmaG*dL1GmeanTrig) {
311 // badL1G[ix-1][iy-1] += 1;
312 // nBadL1G += 1;
313 // }
314
315 // NEW METHOD (if Rate > Threshold * ( (Number of towers or TRUs * Average rate) - Rate ) --> "hot spot !")
316 // Thresold = how much does the noisy tower/TRU contribute to the rate
317 // 1.0 --> Rate of noisy tower/TRU = Rate of all other towers/TRUs
318 if (binContent/dL1GEntries > ThreshG / ( 1 + ThreshG )) {
319 badL1G[ix-1][iy-1] += 1;
320 nBadL1G += 1;
321 }
322 }
323 }
324 }
325
326 // check TRUs
327 for(Int_t ix = 1; ix <= 2; ix++) {
328 for(Int_t iy = 1; iy <= 16; iy++) {
329 if(binContentTRU[ix-1][iy-1]/dL1GEntries > ThreshG / ( 1 + ThreshG )) {
330 badL1GTRU[ix-1][iy-1] += 1;
331 nBadL1GTRU += 1;
332 }
333 }
334 }
335
336 if(fTextL1[0]){
337 lstF->Add(fTextL1[0]->Clone()) ;
338 fTextL1[0]->Clear() ;
339
340 if (nBadL1G == 0 && nBadL1GTRU == 0 ) {
341 fTextL1[0]->SetFillColor(3) ;
342 fTextL1[0]->AddText(Form("L1 GAMMA TRIGGER = OK, ENJOY..."));
343 }
344 else if (nBadL1G == 0){
345 fTextL1[0]->SetFillColor(2) ;
346 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER (TRU) = CALL EXPERT!!"));
347
348 }
349 else{
350 fTextL1[0]->SetFillColor(2) ;
351 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER = CALL EXPERT!!"));
352 /*
353 for(Int_t ix = 1; ix <= hL1GammaPatch->GetNbinsX(); ix++) {
354 for(Int_t iy = 1; iy <= hL1GammaPatch->GetNbinsY(); iy++) {
355 if(badL1G[ix-1][iy-1] != 0) printf("L1 Gamma patch with position x = %d, y = %d is out of range\n",ix,iy);
356 }
357 }
358 */
359 }
360 }//fTextL1[0]
361 }// L1 gamma patch checking done
362 }// if (specie != calibSpecieId) ..
363 }//hL1GammaPatch NOT NULL
364
365 if( hL1JetPatch ){
366
367 lstF = hL1JetPatch->GetListOfFunctions();
368 CleanListOfFunctions(lstF);
369
370 if (specie != calibSpecieId) {
371
372 //if(hL1JetPatch->GetEntries() !=0) {
373 if(hL1JetPatch->GetEntries() > 10) { // need some statistics for hot spot calculation
374
375 lstF = hL1JetPatch->GetListOfFunctions();
376
377 // Checker for L1JetPatch
378 //Double_t dL1JmeanTrig = 1/126.;
379 //Int_t sigmaJ = 5; // deviation from mean value
380 Double_t dL1JEntries = hL1JetPatch->GetEntries();
381 Int_t badL1J[12][16] = {{0}} ;
382 Int_t nBadL1J = 0;
383 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
384 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
385 Double_t binContent = hL1JetPatch->GetBinContent(ix, iy) ;
386 if (binContent != 0) {
387
388 // OLD METHOD (if a patch triggers > sigmaJ * mean value (1/#patch positions total) says "hot spot !")
389 // if ((double)binContent/(double)dL1JEntries > sigmaJ*dL1JmeanTrig) {
390 // badL1J[ix-1][iy-1] += 1 ;
391 // nBadL1J += 1;
392 // }
393
394 // NEW METHOD (if Rate > Threshold * ( (Number of towers or TRUs * Average rate) - Rate ) --> "hot spot !")
395 // Threshold: same definitionas for Gamma
396 if ((double)binContent/(double)dL1JEntries > ThreshJ / ( 1 + ThreshJ )) {
397 badL1J[ix-1][iy-1] += 1 ;
398 nBadL1J += 1;
399 }
400 }
401 }
402 }
403
404 if(fTextL1[1]){
405 lstF->Add(fTextL1[1]->Clone()) ;
406 fTextL1[1]->Clear() ;
407
408 if (nBadL1J == 0) {
409 fTextL1[1]->SetFillColor(3) ;
410 fTextL1[1]->AddText(Form("L1 JET TRIGGER = OK, ENJOY..."));
411 }
412 else {
413 fTextL1[1]->SetFillColor(2) ;
414 fTextL1[1]->AddText(Form("HOT SPOT IN L1 JET TRIGGER = CALL EXPERT!!"));
415 /*
416 for(Int_t ix = 1; ix <= hL1JetPatch->GetNbinsX(); ix++) {
417 for(Int_t iy = 1; iy <= hL1JetPatch->GetNbinsY(); iy++) {
418 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));
419 }
420 }
421 */
422
423 }
424 }//fTextL1[1]
425 } // L1 Jet patch checking done
426 } // if (specie != calibSpecieId) ..
427 }// hL1JetPatch NOT NULL
428
429 if(hFrameR){
430
431 lstF = hFrameR->GetListOfFunctions();
432 CleanListOfFunctions(lstF);
433
434 if(hFrameR->GetEntries() !=0) {
435 lstF = hFrameR->GetListOfFunctions();
436
437 Int_t badLink[32] = {0};
438 Int_t nBadLink = 0;
439 for(Int_t ix = 1; ix <= hFrameR->GetNbinsX(); ix++) {
440 Double_t binContent = hFrameR->GetBinContent(ix) ;
441 if (binContent == 0) {
442 badLink[ix-1] += 1;
443 nBadLink += 1;
444 }
445 }
446 if(fTextL1[2]){
447 lstF->Add(fTextL1[2]->Clone()) ;
448 fTextL1[2]->Clear() ;
449
450 if (nBadLink < badLinkThresh) {
451 fTextL1[2]->SetFillColor(3) ;
452 fTextL1[2]->AddText(Form("LINK TRU-STU = OK, ENJOY..."));
453 }
454 else {
455 fTextL1[2]->SetFillColor(2) ;
456 fTextL1[2]->AddText(Form("PROBLEM WITH TRU-STU LINK = CALL EXPERT!!"));
457 /*
458 for(Int_t ix = 0; ix <= hFrameR->GetNbinsX(); ix++) {
459 if(badLink[ix] != 0) printf("STU link with TRU %d is out\n",ix);
460 }
461 */
462 }
463 }//fTextL1[2]
464 } // Checker for link TRU-STU done
465 }//hFrameR NOT NULL
466 } // species processed
de96ebc9 467 } // specie
a2e583d8 468}
9e47432c 469//______________________________________________________________________________
a2e583d8 470
9e47432c 471void AliEMCALQAChecker::Init(const AliQAv1::DETECTORINDEX_t det)
472{
473 /// intialises QA and QA checker settings
474 AliQAv1::Instance(det) ;
475 Float_t hiValue[AliQAv1::kNBIT] ;
476 Float_t lowValue[AliQAv1::kNBIT] ;
477 lowValue[AliQAv1::kINFO] = 0.0 ;
478 hiValue[AliQAv1::kINFO] = 0.1 ;
9e47432c 479 lowValue[AliQAv1::kWARNING] = 0.1 ;
6a754398 480 hiValue[AliQAv1::kWARNING] = 0.5 ;
9e47432c 481 lowValue[AliQAv1::kERROR] = 0.5 ;
482 hiValue[AliQAv1::kERROR] = 0.8 ;
483 lowValue[AliQAv1::kFATAL] = 0.8 ;
484 hiValue[AliQAv1::kFATAL] = 1.0 ;
485 SetHiLo(&hiValue[0], &lowValue[0]) ;
486}
94594e5d 487
a2e583d8 488//______________________________________________________________________________
489
490void AliEMCALQAChecker::CleanListOfFunctions(TList *list)
edd592b8 491{ // clean up
a2e583d8 492
493 if (list) {
494 TObject *stats = list->FindObject("stats"); list->Remove(stats);
495 TObject *obj;
496 while ((obj = list->First())) { while(list->Remove(obj)) { } delete obj; }
497 if (stats) list->Add(stats);
498 }
499 else {
500 AliWarning(Form("Checker : empty list of data functions; returning"));
501 return;
502 }
503
504}
505
506