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