Removing mirroring in case of private alien storage.
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALQAChecker.cxx
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
22
23  For the moment we only implement the checking of raw data QA.
24  The checked for ESD and RecPoints will be implemented later.
25  
26
27  */
28
29
30 // --- ROOT system ---
31 #include <TClass.h>
32 #include <TH1.h> 
33 #include <TF1.h> 
34 #include <TH1I.h> 
35 #include <TH2F.h>
36 #include <TIterator.h> 
37 #include <TKey.h> 
38 #include <TFile.h> 
39 #include <TLine.h>
40 #include <TText.h>
41 #include <TPaveText.h>
42 #include <TMath.h>
43
44 // --- Standard library ---
45
46 // --- AliRoot header files ---
47 #include "AliLog.h"
48 #include "AliQAv1.h"
49 #include "AliQAChecker.h"
50 #include "AliEMCALQAChecker.h"
51
52 ClassImp(AliEMCALQAChecker)
53
54 //__________________________________________________________________
55 AliEMCALQAChecker::AliEMCALQAChecker() : 
56 AliQACheckerBase("EMCAL","EMCAL Quality Assurance Data Maker"),
57 fTextSM(new TText*[fgknSM]),
58 fLineCol(new TLine(47.5,-0.5,47.5,119.5)),
59 fText(new TPaveText(0.2,0.7,0.8,0.9,"NDC"))
60 {
61   // ctor
62   fLineCol->SetLineColor(1);
63   fLineCol->SetLineWidth(2);
64
65   fTextSM[0]= new TText(20, 12, "SM A0");
66   fTextSM[1]= new TText(20, 36, "SM A1");
67   fTextSM[2]= new TText(20, 60, "SM A2");
68   fTextSM[3]= new TText(20, 84, "SM A3");
69   fTextSM[4]= new TText(20, 108,"SM A4");
70   fTextSM[5]= new TText(20, 132,"SM A5");
71
72   fTextSM[6]= new TText(64, 12, "SM C0");
73   fTextSM[7]= new TText(64, 36, "SM C1");
74   fTextSM[8]= new TText(64, 60, "SM C2");
75   fTextSM[9]= new TText(64, 84, "SM C3");
76   fTextSM[10]= new TText(64, 108,"SM C4");
77   fTextSM[11]= new TText(64, 132,"SM C5");
78
79         for(int i = 0; i < 5; i++) {
80                 fLineRow[i] = new TLine(-0.5,23.5+(24*i),95.5,23.5+(24*i));
81                 fLineRow[i]->SetLineColor(1);
82                 fLineRow[i]->SetLineWidth(2);
83         }
84
85         for(int i = 0; i < 3; i++) {
86                 fTextL1[i] = new TPaveText(0.2,0.7,0.8,0.9,"NDC");
87         }
88
89
90 }          
91
92 //__________________________________________________________________
93 AliEMCALQAChecker::~AliEMCALQAChecker() 
94 {
95         /// dtor
96   delete [] fTextSM ;
97   delete fLineCol ;
98   for (Int_t i=0; i<5; ++i) delete fLineRow[i] ;
99   delete fText  ; 
100 }
101
102 //______________________________________________________________________________
103 void AliEMCALQAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
104 {
105         /// Check objects in list
106         
107         if ( index == AliQAv1::kRAW ) 
108         {
109     CheckRaws(test, list);
110                 printf ("checkers for task %d \n", index) ;             
111         }
112         
113         if ( index == AliQAv1::kREC)
114         {
115     CheckRecPoints(test, list);
116         }
117         
118         if ( index == AliQAv1::kESD )
119         {
120     CheckESD(test, list);
121         }
122         AliWarning(Form("Checker for task %d not implement for the moment",index));
123 }
124
125 //______________________________________________________________________________
126 TH1* 
127 AliEMCALQAChecker::GetHisto(TObjArray* list, const char* hname, Int_t specie) const
128 {
129         /// Get a given histo from the list
130         TH1* h = static_cast<TH1*>(list->FindObject(Form("%s_%s",AliRecoParam::GetEventSpecieName(specie),hname)));
131         if (!h)
132         {
133                 AliError(Form("Did not find expected histo %s",hname));
134         }
135         return h;
136 }
137
138 //______________________________________________________________________________
139 Double_t 
140 AliEMCALQAChecker::MarkHisto(TH1& histo, Double_t value) const
141 {
142         /// Mark histo as originator of some QA error/warning
143         
144         if ( value != 1.0 )
145         {
146                 histo.SetBit(AliQAv1::GetQABit());
147         }
148         
149         return value;
150 }
151
152
153 //______________________________________________________________________________
154 void AliEMCALQAChecker::CheckRaws(Double_t * test, TObjArray ** list)
155 {
156   //  Check RAW QA histograms   
157   //  -- Yaxian Mao, CCNU/CERN/LPSC
158   //adding new checking method: 25/04/2010, Yaxian Mao
159   //Comparing the amplitude from current run to the reference run, if the ratio in the range [0.8, .12], count as a good tower.
160   //If more than 90% towers are good, EMCAL works fine, otherwise experts should be contacted. 
161                                 
162   Int_t nTowersPerSM = 24*48; // number of towers in a SuperModule; 24x48
163   Double_t nTot = fgknSM * nTowersPerSM ;
164   TList *lstF = 0;
165   Int_t calibSpecieId = (Int_t)TMath::Log2( AliRecoParam::kCalib );
166   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
167     test[specie] = 0.0 ; 
168     if ( !AliQAv1::Instance()->IsEventSpecieSet(specie)) continue ; 
169     if (list[specie]->GetEntries() == 0) test[specie] = 0. ; // nothing to check
170     else {
171                         //get calib histos
172                         TH2F * hdata  = (TH2F*)list[specie]->At(k2DRatioAmp) ; 
173                         TH1F * ratio = (TH1F*)list[specie]->At(kRatioDist) ;
174                         
175                         //get L1 histos
176                         TH2F *hL1GammaPatch = (TH2F*)list[specie]->At(kGL1);
177                         TH2F *hL1JetPatch = (TH2F*)list[specie]->At(kJL1);
178                         TH1I *hFrameR = (TH1I*)list[specie]->At(kSTUTRU);
179
180                         //calib histo checker first:
181
182       if(hdata->GetEntries()!=0 && ratio->GetEntries()!=0) {
183                                 //adding the lines to distinguish different SMs
184                                 lstF = hdata->GetListOfFunctions();
185                                 CleanListOfFunctions(lstF);
186                                 lstF->Add(fLineCol->Clone()); 
187                                 for(Int_t iLine = 0; iLine < 4; iLine++) {
188                                         lstF->Add(fLineRow[iLine]->Clone());
189                                 } 
190                                 //Now adding the text to for each SM
191                                 for(Int_t iSM = 0 ; iSM < fgknSM ; iSM++){  //number of SMs loop start
192                                         lstF->Add(fTextSM[iSM]->Clone()); 
193                                 }
194                                 //
195                                 lstF = ratio->GetListOfFunctions();
196                                 CleanListOfFunctions(lstF);
197                                 //
198                                 //now check the ratio histogram
199                                 Double_t binContent = 0. ;  
200                                 Int_t nGoodTower = 0 ;
201                                 Double_t rv = 0. ;
202                                 for(Int_t ix = 1; ix <= hdata->GetNbinsX(); ix++) {
203                                         for(Int_t iy = 1; iy <= hdata->GetNbinsY(); iy++) {
204                                                 binContent = hdata->GetBinContent(ix, iy) ; 
205                                                 if (binContent < 1.2 && binContent > 0.8) nGoodTower++ ;
206                                         }
207                                 }
208                                 rv = nGoodTower/nTot ; 
209                                 printf("%2.2f %% towers out of range [0.8, 1.2]\n", (1-rv)*100);
210                                 if(fText){
211                                         lstF->Add(fText->Clone()) ;
212                                         fText->Clear() ; 
213         
214                                         fText->AddText(Form("%2.2f %% towers out of range [0.8, 1.2]", (1-rv)*100));     
215                                         if (rv < 0.9) {
216                                                 test[specie] = 0.9 ;
217                                                 // 2 lines text info for quality         
218                                                 fText->SetFillColor(2) ;
219                                                 fText->AddText(Form("EMCAL = NOK, CALL EXPERTS!!!")); 
220                                         }
221                                         else {
222                                                 test[specie] = 0.1 ;
223                                                 fText->SetFillColor(3) ;
224                                                 fText->AddText(Form("EMCAL = OK, ENJOY...")); 
225                                         }
226                                 }//fText
227                         } // calib histo checking done
228
229                         //now L1 checks:
230       if (specie != calibSpecieId) {
231                         if(hL1GammaPatch->GetEntries() !=0 ) {
232                                 lstF = hL1GammaPatch->GetListOfFunctions();
233                                 CleanListOfFunctions(lstF);
234
235
236                                 //Checker for L1GammaPatch (if a patch triggers > sigmaG * mean value (1/#patch positions total) says "hot spot !")
237                                 Double_t dL1GmeanTrig = 1/2961.; 
238                                 Int_t sigmaG = 100; // deviation from mean value (increased to 100)
239                                 Double_t dL1GEntries = hL1GammaPatch->GetEntries();
240                                 Int_t badL1G[48][64] = {{0}} ;
241                                 Int_t nBadL1G = 0;
242                                 for(Int_t ix = 1; ix <=  hL1GammaPatch->GetNbinsX(); ix++) {
243                                         for(Int_t iy = 1; iy <=  hL1GammaPatch->GetNbinsY(); iy++) {
244                                                 Double_t binContent = hL1GammaPatch->GetBinContent(ix, iy) ; 
245                                                 if (binContent != 0) {
246                                                         if ((double)binContent/(double)dL1GEntries > sigmaG*dL1GmeanTrig) {
247                                                                 badL1G[ix-1][iy-1] += 1;
248                                                                 nBadL1G += 1;
249                                                         }
250                                                 }
251                                         }
252                                 }
253
254                                 if(fTextL1[0]){
255                                         lstF->Add(fTextL1[0]->Clone()) ;
256                                         fTextL1[0]->Clear() ; 
257
258                                         if (nBadL1G == 0) {
259                                                 fTextL1[0]->SetFillColor(3) ;
260                                                 fTextL1[0]->AddText(Form("L1 GAMMA TRIGGER = OK, ENJOY...")); 
261                                         }
262                                         else {
263                                                 fTextL1[0]->SetFillColor(2) ;
264                                                 fTextL1[0]->AddText(Form("HOT SPOT IN L1 GAMMA TRIGGER = CALL EXPERT!!"));
265 /*
266                                                 for(Int_t ix = 1; ix <=  hL1GammaPatch->GetNbinsX(); ix++) {
267                                                         for(Int_t iy = 1; iy <=  hL1GammaPatch->GetNbinsY(); iy++) {
268                                                                 if(badL1G[ix-1][iy-1] != 0) printf("L1 Gamma patch with position x = %d, y = %d is out of range\n",ix,iy);
269                                                         }
270                                                 }
271 */
272                                         }
273                                 }//fTextL1[0]
274                         }// L1 gamma patch checking done
275
276                         if(hL1JetPatch->GetEntries() !=0) {
277                                 lstF = hL1JetPatch->GetListOfFunctions();
278                                 CleanListOfFunctions(lstF);
279                         
280                                 //Checker for L1JetPatch (if a patch triggers > sigmaJ * mean value (1/#patch positions total) says "hot spot !")
281                                 Double_t dL1JmeanTrig = 1/126.;
282                                 Int_t sigmaJ = 5; // deviation from  mean value
283                                 Double_t dL1JEntries = hL1JetPatch->GetEntries();
284                                 Int_t badL1J[12][16] = {{0}} ;
285                                 Int_t nBadL1J = 0;
286                                 for(Int_t ix = 1; ix <=  hL1JetPatch->GetNbinsX(); ix++) {
287                                         for(Int_t iy = 1; iy <=  hL1JetPatch->GetNbinsY(); iy++) {
288                                                 Double_t binContent = hL1JetPatch->GetBinContent(ix, iy) ; 
289                                                 if (binContent != 0) {
290                                                         if ((double)binContent/(double)dL1JEntries > sigmaJ*dL1JmeanTrig) {
291                                                                 badL1J[ix-1][iy-1] += 1 ;
292                                                                 nBadL1J += 1;
293                                                         }
294                                                 }
295                                         }
296                                 }
297
298                                 if(fTextL1[1]){
299                                         lstF->Add(fTextL1[1]->Clone()) ;
300                                         fTextL1[1]->Clear() ; 
301
302                                         if (nBadL1J == 0) {
303                                                 fTextL1[1]->SetFillColor(3) ;
304                                                 fTextL1[1]->AddText(Form("L1 JET TRIGGER = OK, ENJOY...")); 
305                                         }
306                                         else {
307                                                 fTextL1[1]->SetFillColor(2) ;
308                                                 fTextL1[1]->AddText(Form("HOT SPOT IN L1 JET TRIGGER = CALL EXPERT!!")); 
309 /*
310                                                 for(Int_t ix = 1; ix <=  hL1JetPatch->GetNbinsX(); ix++) {
311                                                         for(Int_t iy = 1; iy <=  hL1JetPatch->GetNbinsY(); iy++) {
312                                                                 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));
313                                                         }
314                                                 }
315 */
316
317                                         }
318                                 }//fTextL1[1]
319                         } // L1 Jet patch checking done
320       } // if (specie != calibSpecieId) ..
321
322                         if(hFrameR->GetEntries() !=0) {
323                                 lstF = hFrameR->GetListOfFunctions();
324                                 CleanListOfFunctions(lstF);
325
326                                 Int_t badLink[32] = {0};
327                                 Int_t nBadLink = 0;
328                                 for(Int_t ix = 1; ix <= hFrameR->GetNbinsX(); ix++) {
329                                         Double_t binContent = hFrameR->GetBinContent(ix) ; 
330                                         if (binContent == 0) {
331                                                 badLink[ix-1] += 1;
332                                                 nBadLink += 1;
333                                         }
334                                 }
335                                 if(fTextL1[2]){
336                                         lstF->Add(fTextL1[2]->Clone()) ;
337                                         fTextL1[2]->Clear() ; 
338         
339                                 if (nBadLink == 0) {
340                                                 fTextL1[2]->SetFillColor(3) ;
341                                                 fTextL1[2]->AddText(Form("LINK TRU-STU = OK, ENJOY...")); 
342                                         }
343                                         else {
344                                                 fTextL1[2]->SetFillColor(2) ;
345                                                 fTextL1[2]->AddText(Form("PROBLEM WITH TRU-STU LINK = CALL EXPERT!!"));
346 /*
347                                                 for(Int_t ix = 0; ix <= hFrameR->GetNbinsX(); ix++) {
348                                                         if(badLink[ix] != 0) printf("STU link with TRU %d is out\n",ix);
349                                                 }
350 */
351                                         }   
352                                 }//fTextL1[2]
353                         } // Checker for link TRU-STU done
354     }
355
356   } // specie
357 }
358 //______________________________________________________________________________
359
360 void AliEMCALQAChecker::Init(const AliQAv1::DETECTORINDEX_t det) 
361 {
362         /// intialises QA and QA checker settings
363         AliQAv1::Instance(det) ; 
364         Float_t hiValue[AliQAv1::kNBIT] ; 
365         Float_t lowValue[AliQAv1::kNBIT] ;
366         lowValue[AliQAv1::kINFO]      = 0.0   ; 
367         hiValue[AliQAv1::kINFO]       = 0.1 ; 
368         lowValue[AliQAv1::kWARNING]   = 0.1 ; 
369   hiValue[AliQAv1::kWARNING]    = 0.5 ; 
370         lowValue[AliQAv1::kERROR]     = 0.5   ; 
371         hiValue[AliQAv1::kERROR]      = 0.8 ; 
372         lowValue[AliQAv1::kFATAL]     = 0.8   ; 
373         hiValue[AliQAv1::kFATAL]      = 1.0 ; 
374         SetHiLo(&hiValue[0], &lowValue[0]) ; 
375 }
376
377 //______________________________________________________________________________
378
379 void AliEMCALQAChecker::CleanListOfFunctions(TList *list)
380 { // clean up
381
382         if (list) {
383                 TObject *stats = list->FindObject("stats"); list->Remove(stats);
384                 TObject *obj;
385                 while ((obj = list->First())) { while(list->Remove(obj)) { } delete obj; }
386                         if (stats) list->Add(stats);
387                 }
388         else {
389                 AliWarning(Form("Checker : empty list of data functions; returning"));
390                 return;
391         }
392
393 }
394
395