Update master to aliroot
[u/mrichter/AliRoot.git] / TPC / TPCbase / AliTPCQAChecker.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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 /// \class AliTPCQAChecker
18 /// \brief Checks implemented a la AliMUONQAChecker.
19 ///
20 /// Checks the quality assurance by realzed checks on histogram content.
21 ///
22 /// Based on AliPHOSQAChecker.
23 /// Checks the quality assurance by comparing with reference data.
24 ///
25 /// \author P. Christiansen, Lund
26 /// \date January 2008 - September 2009.
27
28 // --- ROOT header files ---
29 #include <TH1.h>
30
31 // --- AliRoot header files ---
32 #include "AliTPCQAChecker.h"
33 #include "AliTPCQADataMakerRec.h"
34
35 /// \cond CLASSIMP
36 ClassImp(AliTPCQAChecker)
37 /// \endcond
38
39
40 //__________________________________________________________________
41 AliTPCQAChecker& AliTPCQAChecker::operator = (const AliTPCQAChecker &checker)
42 {
43   /// Equal operator.
44
45   this->~AliTPCQAChecker();
46   new(this) AliTPCQAChecker(checker);
47   return *this;
48 }
49
50 //__________________________________________________________________
51 void
52 AliTPCQAChecker::Check(Double_t * rv, AliQAv1::ALITASK_t index, TObjArray ** list,
53                        const AliDetectorRecoParam * /*recoParam*/)
54 {
55   /// It is important to understand the destinction between indexed tasks (AliQAv1::TASKINDEX_t) which are used in the DataMaker classes and indexed tasks (AliQAv1::ALITASK_t) whihc are used in the checker class.
56   ///
57   ///     From the AliQAChecker::Run() methods we have:
58   ///     AliQAv1::kRAW
59   ///     - AliQAv1::kRAWS
60   ///
61   ///     AliQAv1::kSIM
62   ///     - AliQAv1::kHITS
63   ///     - AliQAv1::kSDIGITS
64   ///     - AliQAv1::kDIGITS
65   ///
66   ///     AliQAv1::kREC
67   ///     - AliQAv1::kDIGITSR
68   ///     - AliQAv1::kRECPOINTS
69   ///     - AliQAv1::kTRACKSEGMENTS
70   ///     - AliQAv1::kRECPARTICLES
71   ///
72   ///     AliQAv1::kESD ;
73   ///     -AliQAv1::kESDS
74   ///
75   ///     This means that for each group of tasks the Check will be called
76   ///     one or more times.  This also mean that we cannot know what
77   ///     histograms will be or not be there in a single call... And we
78   ///     also do not know the position in the list of the histogram.
79
80   /// Check objects in list
81   if(fDebug>0)
82     AliInfo("In AliTPCQAChecker::Check");
83
84   if (index!=AliQAv1::kRAW&&index!=AliQAv1::kSIM&&index!=AliQAv1::kREC&&index!=AliQAv1::kESD) {
85
86     AliWarning(Form("Checker for task %d not implement for the moment",index));
87     return;
88   }
89
90   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
91     rv[specie] = 1.0; // All is fine
92
93   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
94
95     if ( !AliQAv1::Instance()->IsEventSpecieSet(specie) )
96       continue ;
97
98     if (index == AliQAv1::kRAW)
99       rv[specie] = CheckRAW(specie, list[specie]);
100     if (index == AliQAv1::kSIM)
101       rv[specie] = CheckSIM(specie, list[specie]);
102     if (index == AliQAv1::kREC)
103       rv[specie] = CheckREC(specie, list[specie]);
104     if (index == AliQAv1::kESD)
105       rv[specie] = CheckESD(specie, list[specie]);
106
107     if(fDebug>3)
108       AliInfo(Form("Specie: %s. Task: %s. Value: %f",
109                    AliRecoParam::GetEventSpecieName(specie),
110                    AliQAv1::GetAliTaskName(index),
111                    rv[specie]));
112   }
113 }
114
115 //______________________________________________________________________________
116 Double_t AliTPCQAChecker::CheckRAW(Int_t specie, TObjArray* list)
117 {
118   /// Check ESD
119
120   if(fDebug>0)
121     AliInfo("In AliTPCQAChecker::CheckRAW");
122
123   if(fDebug>2)
124     list->Print();
125
126   TH1* hRawsOccupancyVsSector = static_cast<TH1*>
127     (list->FindObject(Form("%s_hRawsOccupancyVsSector",AliRecoParam::GetEventSpecieName(specie))));
128   TH1* hRawsQmaxVsSector = static_cast<TH1*>
129     (list->FindObject(Form("%s_hRawsQmaxVsSector",AliRecoParam::GetEventSpecieName(specie))));
130
131   if (!hRawsOccupancyVsSector || !hRawsQmaxVsSector)
132     return -0.5; // fatal
133
134   if(hRawsOccupancyVsSector->GetEntries()==0) {
135     return 0.25; // error - No TPC data!
136   }
137
138   Int_t nBinsX = hRawsOccupancyVsSector->GetNbinsX();
139   for(Int_t i = 1; i <= nBinsX; i++) {
140
141     if(hRawsOccupancyVsSector->GetBinContent(i)==0)
142       return 0.75; // warning - no TPC data for at least one sector
143   }
144
145   return 1.0; // ok
146 }
147
148 //______________________________________________________________________________
149 Double_t AliTPCQAChecker::CheckSIM(Int_t specie, TObjArray* list)
150 {
151   /// This method checks the QA histograms associated with simulation
152   ///
153   /// For TPC this is:
154   /// Digits :
155   /// The digit histogram gives the ADC distribution for all sigbnals
156   /// above threshold. The check is just that there are digits.
157   /// Hits : The hit histograms are checked to see that they are not
158   /// empty. They contain a lot of detailed information on the
159   /// energyloss model (they were used to debug the AliRoot TPC use of
160   /// FLUKA).
161   ///
162   /// The check methods are simple:
163   /// We do not know if it is bad that histograms are missing because
164   /// this will always be the case for summable digits. So this check
165   /// is not possible here.
166   /// If digit histogram is empty (set error)
167   /// If one of the hit histograms are empty (set error)
168
169   if(fDebug>0)
170     AliInfo("In AliTPCQAChecker::CheckSIM");
171
172   if(fDebug>2)
173     list->Print();
174
175   TH1* hDigits = static_cast<TH1*>
176     (list->FindObject(Form("%s_hDigitsADC",AliRecoParam::GetEventSpecieName(specie))));
177   TH1* hHitsNhits = static_cast<TH1*>
178     (list->FindObject(Form("%s_hHitsNhits",AliRecoParam::GetEventSpecieName(specie))));
179   TH1* hHitsElectrons         = static_cast<TH1*>
180     (list->FindObject(Form("%s_hHitsElectrons",AliRecoParam::GetEventSpecieName(specie))));
181   TH1* hHitsRadius        = static_cast<TH1*>
182     (list->FindObject(Form("%s_hHitsRadius",AliRecoParam::GetEventSpecieName(specie))));
183   TH1* histHitsPrimPerCm          = static_cast<TH1*>
184     (list->FindObject(Form("%s_histHitsPrimPerCm",AliRecoParam::GetEventSpecieName(specie))));
185   TH1* histHitsElectronsPerCm          = static_cast<TH1*>
186     (list->FindObject(Form("%s_histHitsElectronsPerCm",AliRecoParam::GetEventSpecieName(specie))));
187
188 //   if (!(hDigits) ||                                             // digit hists
189 //       !(hHitsNhits && hHitsElectrons && hHitsRadius && histHitsPrimPerCm && histHitsElectronsPerCm)) // hit hists
190 //     return -0.5; // fatal
191
192   if (hDigits) {
193     if(hDigits->GetEntries()==0)
194       return 0.25; // error
195   }
196
197   if (hHitsNhits && hHitsElectrons && hHitsRadius &&
198       histHitsPrimPerCm && histHitsElectronsPerCm) {
199     if (hHitsNhits->GetEntries()==0 || hHitsElectrons->GetEntries()==0 ||
200         hHitsRadius->GetEntries()==0 || histHitsPrimPerCm->GetEntries()==0 ||
201         histHitsElectronsPerCm->GetEntries()==0)
202       return 0.25; // error
203   }
204
205   return 1; // ok
206 }
207
208 //______________________________________________________________________________
209 Double_t AliTPCQAChecker::CheckREC(Int_t specie, TObjArray* list)
210 {
211   /// This method checks the QA histograms associated with reconstruction
212   ///
213   /// For TPC this is:
214   /// DigitsR :
215   /// The digit histogram gives the ADC distribution for all sigbnals
216   /// above threshold. The check is just that there are digits.
217   /// RecPoints :
218   /// The cluster histograms are meant to give an idea about the gain
219   /// from the cluster charge and to indicate iof there are rows with
220   /// noise clusters, i.e., they are very visual.
221   ///
222   /// The check methods are simple:
223   /// If there are no histogram at all (set fatal)
224   /// If digit histogram is there, but there are no digits (set error)
225   /// If cluster histogram is there but there are less than 1000
226   ///    clusters (set warning)
227   /// If there are more than 1000 clusters but no clusters for either short,
228   /// medium, or long pads (set error)
229
230   if(fDebug>0)
231     AliInfo("In AliTPCQAChecker::CheckREC");
232
233   if(fDebug>2)
234     list->Print();
235
236   TH1* hDigits = static_cast<TH1*>
237     (list->FindObject(Form("%s_hDigitsADC",AliRecoParam::GetEventSpecieName(specie))));
238   TH1* hNclustersVsRow = static_cast<TH1*>
239     (list->FindObject(Form("%s_hRecPointsRow",AliRecoParam::GetEventSpecieName(specie))));
240   TH1* hQshort         = static_cast<TH1*>
241     (list->FindObject(Form("%s_hRecPointsQShort",AliRecoParam::GetEventSpecieName(specie))));
242   TH1* hQmedium        = static_cast<TH1*>
243     (list->FindObject(Form("%s_hRecPointsQMedium",AliRecoParam::GetEventSpecieName(specie))));
244   TH1* hQlong          = static_cast<TH1*>
245     (list->FindObject(Form("%s_hRecPointsQLong",AliRecoParam::GetEventSpecieName(specie))));
246   // The Qmax histograms are for now ignored
247
248   if (!hDigits &&                                             // digits missing
249       (!hNclustersVsRow || !hQshort || !hQmedium || !hQlong)) // 1 recpoint hist missing
250     return -0.5; // fatal
251
252   if (hDigits && hDigits->GetEntries()==0)
253     return 0.25; // error
254
255   if (hNclustersVsRow && hNclustersVsRow->GetEntries() < 1000) {
256     return 0.75; // warning
257   } else {
258     if (!hQshort || !hQlong || !hQlong)
259       return -0.5;// fatal - they should be there if the cluster vs row hist is there
260     if (hQshort->GetEntries()==0 || hQmedium->GetEntries()==0 ||
261         hQlong->GetEntries()==0)
262       return 0.25; // error
263   }
264   return 1; // ok
265 }
266
267 //______________________________________________________________________________
268 Double_t AliTPCQAChecker::CheckESD(Int_t specie, TObjArray* list)
269 {
270   /// This method checks the QA histograms associated with ESDs
271   /// (Note that there is aslo a globalQA which is running on all
272   ///  the ESD information so for now this is just a few basic
273   ///  histograms)
274   ///
275   /// The check methods are simple:
276   /// If there are no histogram at all (set fatal)
277
278   if(fDebug>0)
279     AliInfo("In AliTPCQAChecker::CheckESD");
280
281   if(fDebug>2)
282     list->Print();
283
284   TH1* hESDclusters = static_cast<TH1*>
285     (list->FindObject(Form("%s_hESDclusters",AliRecoParam::GetEventSpecieName(specie))));
286   TH1* hESDratio = static_cast<TH1*>
287     (list->FindObject(Form("%s_hESDratio",AliRecoParam::GetEventSpecieName(specie))));
288   TH1* hESDpt = static_cast<TH1*>
289     (list->FindObject(Form("%s_hESDpt",AliRecoParam::GetEventSpecieName(specie))));
290
291   if (!hESDclusters || !hESDratio || !hESDpt)
292     return -0.5; // fatal
293
294   return 1.0; // ok
295 }
296
297 //______________________________________________________________________________
298 void AliTPCQAChecker::Init(const AliQAv1::DETECTORINDEX_t det)
299 {
300   /// intialises QA and QA checker settings
301
302   if(fDebug>0)
303     AliInfo("In AliTPCQAChecker::Init");
304   AliQAv1::Instance(det) ;
305   Float_t hiValue[AliQAv1::kNBIT] ;
306   Float_t lowValue[AliQAv1::kNBIT] ;
307   hiValue[AliQAv1::kINFO]       = 1.00;
308   lowValue[AliQAv1::kINFO]      = 0.99;
309   hiValue[AliQAv1::kWARNING]    = 0.99;
310   lowValue[AliQAv1::kWARNING]   = 0.50;
311   hiValue[AliQAv1::kERROR]      = 0.50;
312   lowValue[AliQAv1::kERROR]     = 0.00;
313   hiValue[AliQAv1::kFATAL]      = 0.00;
314   lowValue[AliQAv1::kFATAL]     =-1.00;
315   //  SetHiLo(&hiValue[0], &lowValue[0]) ;
316   SetHiLo(hiValue, lowValue) ;
317 }
318
319 //______________________________________________________________________________
320 void
321 AliTPCQAChecker::SetQA(AliQAv1::ALITASK_t index, Double_t * value) const
322 {
323   /// sets the QA according the return value of the Check
324
325   if(fDebug>0)
326     AliInfo("In AliTPCQAChecker::SetQA");
327
328   AliQAv1 * qa = AliQAv1::Instance(index);
329
330   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
331
332     if (value==NULL) { // No checker is implemented, set all QA to Fatal
333
334       if(fDebug>1)
335         AliInfo(Form("Fatal QA. Task: %s. Specie: %s",
336                      AliQAv1::GetAliTaskName(index),
337                      AliRecoParam::GetEventSpecieName(specie)));
338       qa->Set(AliQAv1::kFATAL, specie) ;
339     } else {
340
341       if ( value[specie] >= fLowTestValue[AliQAv1::kFATAL] &&
342            value[specie] < fUpTestValue[AliQAv1::kFATAL] ) {
343
344         if(fDebug>1)
345           AliInfo(Form("QA-Fatal. Task: %s. Specie: %s",
346                        AliQAv1::GetAliTaskName(index),
347                        AliRecoParam::GetEventSpecieName(specie)));
348         qa->Set(AliQAv1::kFATAL, specie) ;
349       } else if ( value[specie] > fLowTestValue[AliQAv1::kERROR] &&
350                   value[specie] <= fUpTestValue[AliQAv1::kERROR]  ) {
351
352         if(fDebug>1)
353           AliInfo(Form("QA-Error. Task: %s. Specie: %s",
354                        AliQAv1::GetAliTaskName(index),
355                        AliRecoParam::GetEventSpecieName(specie)));
356         qa->Set(AliQAv1::kERROR, specie) ;
357       } else if (value[specie] > fLowTestValue[AliQAv1::kWARNING] &&
358                  value[specie] <= fUpTestValue[AliQAv1::kWARNING]) {
359
360         if(fDebug>1)
361           AliInfo(Form("QA-Warning. Task: %s. Specie: %s",
362                        AliQAv1::GetAliTaskName(index),
363                        AliRecoParam::GetEventSpecieName(specie)));
364         qa->Set(AliQAv1::kWARNING, specie) ;
365       } else if (value[specie] > fLowTestValue[AliQAv1::kINFO] &&
366                  value[specie] <= fUpTestValue[AliQAv1::kINFO] ) {
367
368         if(fDebug>1)
369           AliInfo(Form("QA-Info. Task: %s. Specie: %s",
370                        AliQAv1::GetAliTaskName(index),
371                        AliRecoParam::GetEventSpecieName(specie)));
372         qa->Set(AliQAv1::kINFO, specie) ;
373       }
374     }
375   }
376 }