Added QA for digits during reconstruction (Yves)
[u/mrichter/AliRoot.git] / STEER / AliQAv1.cxx
1
2 /**************************************************************************
3  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4  *                                                                        *
5  * Author: The ALICE Off-line Project.                                    *
6  * Contributors are mentioned in the code where appropriate.              *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16 /* $Id: AliQAv1.cxx 31503 2009-03-16 11:01:16Z schutz $ */
17
18 //////////////////////////////////////////////////////////////////////////////
19 //
20 // Quality Assurance Object//_________________________________________________________________________
21 // Quality Assurance object. The QA status is held in one word per detector,
22 // each bit corresponds to a different status.
23 // bit 0-3   : QA raised during simulation      (RAW)
24 // bit 4-7   : QA raised during simulation      (SIM)
25 // bit 8-11  : QA raised during reconstruction  (REC)
26 // bit 12-15 : QA raised during ESD checking    (ESD)
27 // bit 16-19 : QA raised during analysis        (ANA)
28 // Each of the 4 bits corresponds to a severity level of increasing importance
29 // from lower to higher bit (INFO, WARNING, ERROR, FATAL)
30 //
31 //*-- Yves Schutz CERN, July 2007 
32 //////////////////////////////////////////////////////////////////////////////
33
34
35 #include <cstdlib>
36 // --- ROOT system ---
37 #include <TClass.h>
38 #include <TFile.h>
39 #include <TSystem.h>
40 #include <TROOT.h>
41
42 // --- Standard library ---
43
44 // --- AliRoot header files ---
45 #include "AliLog.h"
46 #include "AliQAv1.h"
47
48
49 ClassImp(AliQAv1)
50 AliQAv1  * AliQAv1::fgQA                   = 0x0 ;
51 TFile    * AliQAv1::fgQADataFile           = 0x0 ;   
52 TString    AliQAv1::fgQADataFileName       = "QA" ;  // will transform into Det.QA.run.root  
53 TFile    * AliQAv1::fgQARefFile            = 0x0 ;   
54 TString    AliQAv1::fgQARefDirName             = "" ; 
55 TString    AliQAv1::fgQARefFileName        = "QA.root" ;
56 TFile    * AliQAv1::fgQAResultFile         = 0x0 ;  
57 TString    AliQAv1::fgQAResultDirName      = "" ;  
58 TString    AliQAv1::fgQAResultFileName     = "QA.root" ; 
59 TString    AliQAv1::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
60                                             "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR"} ;   
61 TString    AliQAv1::fgGRPPath              = "GRP/GRP/Data" ; 
62 TString       AliQAv1::fgTaskNames[]       = {"Raws", "Hits", "SDigits", "Digits", "DigitsR", "RecPoints", "TrackSegments", "RecParticles", "ESDs"} ;   
63 const TString AliQAv1::fgkLabLocalFile     = "file://"  ; 
64 const TString AliQAv1::fgkLabLocalOCDB     = "local://" ;  
65 const TString AliQAv1::fgkLabAliEnOCDB     = "alien://" ;  
66 const TString AliQAv1::fgkRefFileName      = "QA.root" ; 
67 const TString AliQAv1::fgkQAName           = "QA"  ; 
68 const TString AliQAv1::fgkQACorrNtName     = "CorrQA" ;  
69 const TString AliQAv1::fgkRefOCDBDirName   = "QA"  ; 
70 TString AliQAv1::fgRefDataDirName                = ""  ; 
71 const TString AliQAv1::fgkQARefOCDBDefault = "alien://folder=/alice/QA/20"  ; 
72 const TString AliQAv1::fgkExpert           = "Expert" ; 
73 const UInt_t  AliQAv1::fgkExpertBit        = 0x40000 ; 
74 const UInt_t  AliQAv1::fgkQABit            = 0x80000 ; 
75 const UInt_t  AliQAv1::fgkImageBit         = 0x100000 ; 
76 const Int_t  AliQAv1::fgkQADebugLevel      = 99 ; 
77 //____________________________________________________________________________
78 AliQAv1::AliQAv1() : 
79   TNamed("", ""), 
80   fNdet(kNDET), 
81   fNEventSpecies(AliRecoParam::kNSpecies), 
82   fLengthQA(fNdet*fNEventSpecies),
83   fQA(new ULong_t[fLengthQA]), 
84   fDet(kNULLDET),
85   fTask(kNULLTASK), 
86   fEventSpecie(AliRecoParam::kDefault), 
87   fEventSpecies(new Bool_t[fNEventSpecies])
88 {
89   // default constructor
90   memset(fQA,0,fLengthQA*sizeof(ULong_t));
91   memset(fEventSpecies,kFALSE,fNEventSpecies*sizeof(Bool_t));
92 }
93
94 //____________________________________________________________________________
95 AliQAv1::AliQAv1(const AliQAv1& qa) :
96   TNamed(qa),
97   fNdet(qa.fNdet), 
98   fNEventSpecies(qa.fNEventSpecies), 
99   fLengthQA(qa.fLengthQA),
100   fQA(new ULong_t[fLengthQA]), 
101   fDet(qa.fDet),
102   fTask(qa.fTask), 
103   fEventSpecie(qa.fEventSpecie), 
104   fEventSpecies(new Bool_t[fNEventSpecies])
105
106   // cpy ctor
107   memcpy(fQA,qa.fQA,fLengthQA*sizeof(ULong_t));
108   memcpy(fEventSpecies,qa.fEventSpecies,fNEventSpecies*sizeof(Bool_t));
109 }
110
111 //_____________________________________________________________________________
112 AliQAv1& AliQAv1::operator = (const AliQAv1& qa)
113 {
114   // assignment operator
115   if(&qa != this) {
116     TNamed::operator=(qa);
117     fNdet          = qa.fNdet;
118     fNEventSpecies = qa.fNEventSpecies; 
119     fLengthQA      = qa.fLengthQA;
120
121     if(fQA) delete [] fQA;
122     fQA = new ULong_t[fLengthQA];
123     memcpy(fQA,qa.fQA,fLengthQA*sizeof(ULong_t));
124
125     fDet = qa.fDet;
126     fTask = qa.fTask;
127     fEventSpecie = qa.fEventSpecie; 
128     if(fEventSpecies) delete [] fEventSpecies;
129     fEventSpecies = new Bool_t[fNEventSpecies];
130     memcpy(fEventSpecies,qa.fEventSpecies,fNEventSpecies*sizeof(Bool_t));
131   }  
132   return *this;
133 }
134
135 //_______________________________________________________________
136 AliQAv1::AliQAv1(const Int_t qalength, ULong_t * qa, const Int_t eslength, Bool_t * es) :
137 TNamed("QA", "Quality Assurance status"),
138 fNdet(kNDET), 
139 fNEventSpecies(eslength), 
140 fLengthQA(qalength),
141 fQA(new ULong_t[fLengthQA]), 
142 fDet(kNULLDET),
143 fTask(kNULLTASK), 
144 fEventSpecie(AliRecoParam::kDefault), 
145 fEventSpecies(new Bool_t[fNEventSpecies])
146 {
147   // constructor to be used
148   memcpy(fQA, qa, fLengthQA*sizeof(ULong_t));
149   memcpy(fEventSpecies, es, fNEventSpecies*sizeof(Bool_t));
150 }
151
152 //_______________________________________________________________
153 AliQAv1::AliQAv1(const DETECTORINDEX_t det) :
154   TNamed("QA", "Quality Assurance status"),
155   fNdet(kNDET), 
156   fNEventSpecies(AliRecoParam::kNSpecies), 
157   fLengthQA(fNdet*fNEventSpecies),
158   fQA(new ULong_t[fLengthQA]), 
159   fDet(det),
160   fTask(kNULLTASK), 
161   fEventSpecie(AliRecoParam::kDefault), 
162   fEventSpecies(new Bool_t[fNEventSpecies])
163 {
164   // constructor to be used
165   if (! CheckRange(det) ) fDet = kNULLDET ; 
166   memset(fQA,0,fLengthQA*sizeof(ULong_t));
167   memset(fEventSpecies,kFALSE,fNEventSpecies*sizeof(Bool_t));
168 }
169   
170 //_______________________________________________________________
171 AliQAv1::AliQAv1(const ALITASK_t tsk) :
172   TNamed("QA", "Quality Assurance status"),
173   fNdet(kNDET), 
174   fNEventSpecies(AliRecoParam::kNSpecies), 
175   fLengthQA(fNdet*fNEventSpecies),
176   fQA(new ULong_t[fLengthQA]), 
177   fDet(kNULLDET),
178   fTask(tsk), 
179   fEventSpecie(AliRecoParam::kDefault), 
180   fEventSpecies(new Bool_t[fNEventSpecies])
181 {
182   // constructor to be used in the AliRoot module (SIM, REC, ESD or ANA)
183   if (! CheckRange(tsk) ) fTask = kNULLTASK ; 
184   memset(fQA,0,fLengthQA*sizeof(ULong_t));
185   memset(fEventSpecies,kFALSE,fNEventSpecies*sizeof(Bool_t));
186 }
187
188 //____________________________________________________________________________
189 AliQAv1::~AliQAv1() 
190 {
191   // dtor  
192   delete [] fQA;
193   delete [] fEventSpecies;
194 }
195
196 //_______________________________________________________________
197 void AliQAv1::Close() 
198 {
199         // close the open files
200         if (fgQADataFile) 
201                 if (fgQADataFile->IsOpen())
202                         fgQADataFile->Close() ; 
203         if (fgQAResultFile) 
204                 if (fgQAResultFile->IsOpen()) 
205                         fgQAResultFile->Close() ;
206         if (fgQARefFile)
207                 if (fgQARefFile->IsOpen())
208                         fgQARefFile->Close() ; 
209
210
211 //_______________________________________________________________
212 Bool_t AliQAv1::CheckFatal() const
213 {
214   // check if any FATAL status is set
215   Bool_t rv = kFALSE ;
216   Int_t index ;
217   for (index = 0; index < kNDET ; index++)
218     rv = rv || IsSet(DETECTORINDEX_t(index), fTask, fEventSpecie, kFATAL) ;
219   return rv ;
220 }
221
222 //_______________________________________________________________
223 Bool_t AliQAv1::CheckRange(DETECTORINDEX_t det) const
224
225   // check if detector is in given detector range: 0-kNDET
226
227   Bool_t rv = ( det < 0 || det > kNDET )  ? kFALSE : kTRUE ;
228   if (!rv)
229     AliFatal(Form("Detector index %d is out of range: 0 <= index <= %d", det, kNDET)) ;
230   return rv ;
231 }
232
233 //_______________________________________________________________
234 Bool_t AliQAv1::CheckRange(ALITASK_t task) const
235
236   // check if task is given taskk range: 0:kNTASK
237   Bool_t rv = ( task < kRAW || task > kNTASK )  ? kFALSE : kTRUE ;
238   if (!rv)
239     AliFatal(Form("Module index %d is out of range: 0 <= index <= %d", task, kNTASK)) ;
240   return rv ;
241 }
242
243 //_______________________________________________________________
244 Bool_t AliQAv1::CheckRange(QABIT_t bit) const
245
246   // check if bit is in given bit range: 0-kNBit
247
248   Bool_t rv = ( bit < 0 || bit > kNBIT )  ? kFALSE : kTRUE ;
249   if (!rv)
250     AliFatal(Form("Status bit %d is out of range: 0 <= bit <= %d", bit, kNBIT)) ;
251   return rv ;
252 }
253
254 //_______________________________________________________________
255 Bool_t AliQAv1::CheckRange(AliRecoParam::EventSpecie_t es) const
256
257   // check if bit is in given bit range: 0-kNBit
258   Bool_t rv = kFALSE ; 
259   switch (es) {
260     case AliRecoParam::kDefault: 
261       rv = kTRUE ; 
262       break ; 
263     case AliRecoParam::kLowMult: 
264       rv = kTRUE ; 
265       break ; 
266     case AliRecoParam::kHighMult: 
267       rv = kTRUE ; 
268       break ; 
269     case AliRecoParam::kCosmic: 
270       rv = kTRUE ; 
271       break ; 
272     case AliRecoParam::kCalib: 
273       rv = kTRUE ; 
274       break ; 
275   }
276   if (!rv)
277     AliFatal(Form("Event Specie %d is not valid", es)) ;
278   return rv ;
279 }
280
281 //_______________________________________________________________
282 const char * AliQAv1::GetAliTaskName(ALITASK_t tsk)
283 {
284         // returns the char name corresponding to module index
285         TString tskName ;
286         switch (tsk) {
287                 case kNULLTASK:
288                         break ; 
289                 case kRAW:
290                         tskName = "RAW" ;
291                         break ;  
292                 case kSIM:
293                         tskName = "SIM" ;
294                         break ;
295                 case kREC:
296                         tskName = "REC" ;
297                         break ;
298                 case kESD:
299                         tskName = "ESD" ;
300                         break ;
301                 case kANA:
302                         tskName = "ANA" ;
303                         break ;
304                 default:
305                         tsk = kNULLTASK ; 
306                         break ;
307         }
308         return tskName.Data() ;
309 }
310
311 //_______________________________________________________________
312 const char * AliQAv1::GetBitName(QABIT_t bit) const
313 {
314         // returns the char name corresponding to bit 
315         TString bitName ;
316         switch (bit) {
317                 case kNULLBit:
318                         break ; 
319                 case kINFO:
320                         bitName = "INFO" ;
321                         break ;  
322                 case kWARNING:
323                         bitName = "WARNING" ;
324                         break ;
325                 case kERROR:
326                         bitName = "ERROR" ;
327                         break ;
328                 case kFATAL:
329                         bitName = "FATAL" ;
330                         break ;
331                 default:
332                         bit = kNULLBit ; 
333                         break ;
334         }
335         return bitName.Data() ;
336 }
337
338 //_______________________________________________________________
339 AliQAv1::DETECTORINDEX_t AliQAv1::GetDetIndex(const char * name) 
340 {
341         // returns the detector index corresponding to a given name
342         TString sname(name) ; 
343         DETECTORINDEX_t rv = kNULLDET ; 
344         for (Int_t det = 0; det < kNDET ; det++) {
345                 if ( GetDetName(det) == sname ) {
346                         rv = DETECTORINDEX_t(det) ; 
347                         break ; 
348                 }
349         }
350         return rv ;             
351 }
352
353 //_______________________________________________________________
354 const char * AliQAv1::GetDetName(Int_t det) 
355 {
356         // returns the detector name corresponding to a given index (needed in a loop)
357         
358         if ( det >= 0 &&  det < kNDET) 
359                 return (fgDetNames[det]).Data() ; 
360         else 
361                 return NULL ; 
362 }
363
364 //_______________________________________________________________
365 TFile * AliQAv1::GetQADataFile(const char * name, Int_t run) 
366 {
367   // opens the file to store the detectors Quality Assurance Data Maker results
368         const char * temp = Form("%s.%s.%d.root", name, fgQADataFileName.Data(), run) ; 
369         TString opt ; 
370         if (! fgQADataFile ) {     
371                 if  (gSystem->AccessPathName(temp))
372                         opt = "NEW" ;
373                 else 
374                         opt = "UPDATE" ; 
375                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
376         } else {
377                 if ( strcmp(temp, fgQADataFile->GetName()) != 0 ) {
378                         fgQADataFile = dynamic_cast<TFile *>(gROOT->FindObject(temp)) ; 
379                         if ( !fgQADataFile ) {
380                                 if  (gSystem->AccessPathName(temp))
381                                         opt = "NEW" ;
382                                 else 
383                                         opt = "UPDATE" ; 
384                                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
385                         }
386                 }
387   }
388         return fgQADataFile ;
389
390
391 //_____________________________________________________________________________
392 TFile * AliQAv1::GetQADataFile(const char * fileName)
393 {
394   // Open if necessary the Data file and return its pointer
395
396   if (!fgQADataFile) 
397         if (!fileName) 
398                 fileName = AliQAv1::GetQADataFileName() ; 
399         if  (!gSystem->AccessPathName(fileName)) {
400                 fgQADataFile =  TFile::Open(fileName) ;
401         } else {
402                 AliFatalClass(Form("File %s not found", fileName)) ;
403         }
404   return fgQADataFile ; 
405 }
406
407 //_______________________________________________________________
408 TFile * AliQAv1::GetQAResultFile() 
409 {
410   // opens the file to store the  Quality Assurance Data Checker results
411         if (fgQAResultFile) 
412                 fgQAResultFile->Close() ; 
413         fgQAResultFile = 0x0 ; 
414 //      if (!fgQAResultFile) { 
415                 TString dirName(fgQAResultDirName) ; 
416                 if ( dirName.Contains(fgkLabLocalFile)) 
417                         dirName.ReplaceAll(fgkLabLocalFile, "") ;
418                 TString fileName(dirName + fgQAResultFileName) ; 
419                 TString opt("") ; 
420                 if ( !gSystem->AccessPathName(fileName) )
421                         opt = "UPDATE" ; 
422                 else { 
423                         if ( gSystem->AccessPathName(dirName) )
424                                 gSystem->mkdir(dirName) ; 
425                         opt = "NEW" ; 
426                 }
427                 fgQAResultFile = TFile::Open(fileName, opt) ;   
428 //      }
429         
430         return fgQAResultFile ;
431 }
432
433 //_______________________________________________________________
434 AliQAv1::TASKINDEX_t AliQAv1::GetTaskIndex(const char * name) 
435 {
436         // returns the detector index corresponding to a given name
437         TString sname(name) ; 
438         TASKINDEX_t rv = kNULLTASKINDEX ; 
439         for (Int_t tsk = 0; tsk < kNTASKINDEX ; tsk++) {
440                 if ( GetTaskName(tsk) == sname ) {
441                         rv = TASKINDEX_t(tsk) ; 
442                         break ; 
443                 }
444         }
445         return rv ;             
446 }
447
448 //_______________________________________________________________
449 Bool_t AliQAv1::IsSet(DETECTORINDEX_t det, ALITASK_t tsk, Int_t ies, QABIT_t bit) const 
450 {
451   // Checks is the requested bit is set
452    
453   const AliRecoParam::EventSpecie_t es = AliRecoParam::Convert(ies) ; 
454   return IsSet(det, tsk, es, bit) ; 
455   
456 }  
457
458 //_______________________________________________________________
459 Bool_t AliQAv1::IsSet(DETECTORINDEX_t det, ALITASK_t tsk, AliRecoParam::EventSpecie_t es, QABIT_t bit) const
460 {
461   // Checks is the requested bit is set
462         
463   CheckRange(det) ; 
464   CheckRange(tsk) ;
465   CheckRange(bit) ;
466   CheckRange(es) ;
467         
468   ULong_t offset = Offset(tsk) ;
469   ULong_t status = GetStatus(det, es) ;
470   offset+= bit ;
471   status = (status & 1 << offset) != 0 ;
472   return status ;
473 }
474
475 //_______________________________________________________________
476 Bool_t AliQAv1::IsSetAny(DETECTORINDEX_t det, ALITASK_t tsk, AliRecoParam::EventSpecie_t es) const
477 {
478   // Checks is the requested bit is set
479         
480   CheckRange(det) ; 
481   CheckRange(tsk) ;
482   CheckRange(es) ;
483         
484   ULong_t offset = Offset(tsk) ;
485   ULong_t status = GetStatus(det, es) ;
486         ULong_t st = 0 ; 
487         for ( Int_t bit = 0 ; bit < kNBIT ; bit++) {
488                 offset+= bit ;
489                 st += (status & 1 << offset) != 0 ;             
490         }
491         if ( st == 0 ) 
492                 return kFALSE ; 
493         else 
494                 return kTRUE ;
495 }
496 //_______________________________________________________________
497 Bool_t AliQAv1::IsSetAny(DETECTORINDEX_t det, AliRecoParam::EventSpecie_t es) const
498 {
499   // Checks is the requested bit is set
500         
501   CheckRange(det) ; 
502   CheckRange(es) ; 
503         
504         ULong_t status = GetStatus(det, es) ;
505         ULong_t st = 0 ; 
506         for ( Int_t tsk = 0 ; tsk < kNTASK ; tsk++) {
507                 ULong_t offset = Offset(ALITASK_t(tsk)) ;
508                 for ( Int_t bit = 0 ; bit < kNBIT ; bit++) {
509                         offset+= bit ;
510                         st += (status & 1 << offset) != 0 ;             
511                 }
512         }
513         if ( st == 0 ) 
514                 return kFALSE ; 
515         else 
516                 return kTRUE ;
517 }
518
519 //_______________________________________________________________
520 AliQAv1 * AliQAv1::Instance()
521 {
522   // Get an instance of the singleton. The only authorized way to call the ctor
523
524   if ( ! fgQA) {
525     TFile * f = GetQAResultFile() ; 
526     fgQA = dynamic_cast<AliQAv1 *>(f->Get("QA")) ; 
527     if ( ! fgQA ) 
528       fgQA = new AliQAv1() ;
529   }     
530   return fgQA ;
531 }
532
533 //_______________________________________________________________
534 AliQAv1 * AliQAv1::Instance(const Int_t qalength, ULong_t * qa, const Int_t eslength, Bool_t * es)
535 {
536   // Get an instance of the singleton. The only authorized way to call the ctor
537   
538   if ( ! fgQA) 
539     fgQA = new AliQAv1(qalength, qa, eslength, es) ;
540   return fgQA ;
541 }
542
543 //_______________________________________________________________
544 AliQAv1 * AliQAv1::Instance(const DETECTORINDEX_t det)
545 {
546   // Get an instance of the singleton. The only authorized way to call the ctor
547   
548   if ( ! fgQA) {
549     TFile * f = GetQAResultFile() ; 
550         fgQA = dynamic_cast<AliQAv1 *>(f->Get("QA")) ; 
551     if ( ! fgQA ) 
552                 fgQA = new AliQAv1(det) ;
553   }             
554   fgQA->Set(det) ;
555   return fgQA ;
556 }
557
558 //_______________________________________________________________
559 AliQAv1 * AliQAv1::Instance(const ALITASK_t tsk)
560 {
561   // Get an instance of the singleton. The only authorized way to call the ctor
562
563   if ( ! fgQA)
564     switch (tsk) {
565     case kNULLTASK:
566       break ;
567         case kRAW:
568       fgQA = new AliQAv1(tsk) ;
569       break ;
570         case kSIM:
571       fgQA = new AliQAv1(tsk) ;
572       break ;
573     case kREC:
574       AliInfoClass("fgQA = gAlice->GetQA()") ;
575       break ;
576     case kESD:
577       AliInfoClass("fgQA = dynamic_cast<AliQAv1 *> (esdFile->Get(\"QA\")") ;
578       break ;
579     case kANA:
580       AliInfoClass("fgQA = dynamic_cast<AliQAv1 *> (esdFile->Get(\"QA\")") ;
581       break ;
582     case kNTASK:
583       break ;
584     }
585   if (fgQA) 
586     fgQA->Set(tsk) ;
587   return fgQA ;
588 }
589
590 //_______________________________________________________________
591 AliQAv1 *  AliQAv1::Instance(const TASKINDEX_t tsk) 
592 {
593         // get an instance of the singleton.
594         
595         ALITASK_t index = kNULLTASK ; 
596
597         if ( tsk == kRAWS )
598                 index = kRAW ;
599         else if (tsk < kDIGITS)
600                 index = kSIM ;
601         else if (tsk < kRECPARTICLES)
602                 index = kREC ; 
603         else if (tsk == kESDS) 
604                 index = kESD ; 
605
606         return Instance(index) ; 
607 }
608
609 //_______________________________________________________________
610 void AliQAv1::Merge(TCollection * list) {
611         // Merge the QA resuls in the list into this single AliQAv1 object
612         
613         for (Int_t det = 0 ; det < kNDET ; det++) {
614                 Set(DETECTORINDEX_t(det)) ; 
615                 for (Int_t task = 0 ; task < kNTASK ; task++) {
616                         Set(ALITASK_t(task)) ; 
617                         for (Int_t bit = 0 ; bit < kNBIT ; bit++) {
618                                 TIter next(list) ;
619                                 AliQAv1 * qa ; 
620                                 while ( (qa = (AliQAv1*)next() ) ) {
621           for (Int_t es = 0 ; es < fNEventSpecies ; es++) {
622             if (qa->IsSet(DETECTORINDEX_t(det), ALITASK_t(task), es, QABIT_t(bit)))
623               Set(QABIT_t(bit), es) ; 
624           }
625                                 } // qa list
626                         } // bit
627                 } // task
628         } // detector
629 }
630
631 //_______________________________________________________________
632 ULong_t AliQAv1::Offset(ALITASK_t tsk) const
633 {
634   // Calculates the bit offset for a given module (SIM, REC, ESD, ANA)
635
636   CheckRange(tsk) ; 
637
638   ULong_t offset = 0 ;
639   switch (tsk) {
640   case kNULLTASK:
641     break ;
642   case kRAW:
643     offset+= 0 ;
644     break ;
645   case kSIM:
646     offset+= 4 ;
647     break ;
648   case kREC:
649     offset+= 8 ;
650     break ;
651   case kESD:
652     offset+= 12 ;
653     break ;
654   case kANA:
655     offset+= 16 ;
656     break ;
657   case kNTASK:
658     break ;
659   }
660
661   return offset ;
662 }
663
664 //_______________________________________________________________
665 void AliQAv1::ResetStatus(DETECTORINDEX_t det) 
666
667   // reset the status of det for all event specie
668   for (Int_t es = 0 ; es < fNEventSpecies ; es++)
669     fQA[det*fNdet+es] = 0 ; 
670 }
671
672 //_______________________________________________________________
673 void AliQAv1::Set(QABIT_t bit, Int_t ies)
674 {
675   // Set the status bit of the current detector in the current module and for the current event specie 
676    Set(bit, AliRecoParam::Convert(ies)) ;
677 }
678
679 //_______________________________________________________________
680 void AliQAv1::Set(QABIT_t bit, AliRecoParam::EventSpecie_t es)
681 {
682   // Set the status bit of the current detector in the current module and for the current event specie 
683   
684   SetStatusBit(fDet, fTask, es, bit) ;
685 }
686
687 //_____________________________________________________________________________
688 void AliQAv1::SetQARefStorage(const char * name)
689 {
690         // Set the root directory where the QA reference data are stored
691
692         fgQARefDirName = name ; 
693         if ( fgQARefDirName.Contains(fgkLabLocalFile) )
694                 fgQARefFileName =  fgkRefFileName ; 
695         else if ( fgQARefDirName.Contains(fgkLabLocalOCDB) )
696                 fgQARefFileName =  fgkQAName ; 
697         else if ( fgQARefDirName.Contains(fgkLabAliEnOCDB) )
698                 fgQARefFileName =  fgkQAName ; 
699
700   else {
701           AliErrorClass(Form("ERROR: %s is an invalid storage definition\n", name)) ; 
702           fgQARefDirName  = "" ; 
703           fgQARefFileName = "" ; 
704   }     
705         TString tmp(fgQARefDirName) ; // + fgQARefFileName) ;
706         AliInfoClass(Form("AliQAv1::SetQARefDir: QA references are in  %s\n", tmp.Data() )) ;
707 }
708
709 //_____________________________________________________________________________
710 void AliQAv1::SetQAResultDirName(const char * name)
711 {
712   // Set the root directory where to store the QA status object
713
714   fgQAResultDirName.Prepend(name) ; 
715   AliInfoClass(Form("AliQAv1::SetQAResultDirName: QA results are in  %s\n", fgQAResultDirName.Data())) ;
716   if ( fgQAResultDirName.Contains(fgkLabLocalFile)) 
717     fgQAResultDirName.ReplaceAll(fgkLabLocalFile, "") ;
718   fgQAResultFileName.Prepend(fgQAResultDirName) ;
719 }
720
721 //_______________________________________________________________
722 void AliQAv1::SetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, AliRecoParam::EventSpecie_t es, QABIT_t bit)
723 {
724  // Set the status bit for a given detector and a given task
725
726   CheckRange(det) ;
727   CheckRange(tsk) ;
728   CheckRange(bit) ;
729   CheckRange(es) ;
730
731   ULong_t offset = Offset(tsk) ;
732   ULong_t status = GetStatus(det, es) ;
733   offset+= bit ;
734   status = status | 1 << offset ;
735   SetStatus(det, es, status) ;
736 }
737
738 //_______________________________________________________________
739 void AliQAv1::Show(DETECTORINDEX_t det) const 
740
741   // dispplay the QA status word
742   if ( det == kNULLDET) 
743     det = fDet ;  
744   for (Int_t ies = 0 ; ies < fNEventSpecies ; ies++) {
745     const Bool_t what = IsEventSpecieSet(ies) ;
746     if ( what )
747       ShowStatus(det, kNULLTASK, AliRecoParam::Convert(ies)) ; 
748   }
749 }
750
751 //_______________________________________________________________
752 void AliQAv1::ShowAll() const 
753 {
754   // dispplay the QA status word
755   Int_t index ;
756   for (index = 0 ; index < kNDET ; index++) {
757                 for (Int_t tsk = kRAW ; tsk < kNTASK ; tsk++) {
758       for (Int_t ies = 0 ; ies < fNEventSpecies ; ies++) {
759         const Bool_t what = IsEventSpecieSet(ies) ;
760         if ( what )
761           ShowStatus(DETECTORINDEX_t(index), ALITASK_t(tsk), AliRecoParam::Convert(ies)) ;
762       }
763     }
764         }
765 }
766
767 //_______________________________________________________________
768 void AliQAv1::ShowStatus(DETECTORINDEX_t det, ALITASK_t tsk, AliRecoParam::EventSpecie_t es) const
769 {
770         // Prints the full QA status of a given detector
771         CheckRange(det) ;
772         CheckRange(es) ;
773         ULong_t status = GetStatus(det, es) ;
774         ULong_t tskStatus[kNTASK] ; 
775         tskStatus[kRAW] = status & 0x0000f ;
776         tskStatus[kSIM] = status & 0x000f0 ;
777         tskStatus[kREC] = status & 0x00f00 ;
778         tskStatus[kESD] = status & 0x0f000 ;
779         tskStatus[kANA] = status & 0xf0000 ;
780
781         AliInfo(Form("====> QA Status for %8s %8s raw =0x%x, sim=0x%x, rec=0x%x, esd=0x%x, ana=0x%x", GetDetName(det).Data(), AliRecoParam::GetEventSpecieName(es), 
782                                  tskStatus[kRAW], tskStatus[kSIM], tskStatus[kREC], tskStatus[kESD], tskStatus[kANA] )) ;
783         if (tsk == kNULLTASK) {
784                 for (Int_t itsk = kRAW ; itsk < kNTASK ; itsk++) {
785                         ShowASCIIStatus(es, det, ALITASK_t(itsk), tskStatus[itsk]) ; 
786                 } 
787         } else {
788                         ShowASCIIStatus(es, det, tsk, tskStatus[tsk]) ; 
789         }
790 }
791
792 //_______________________________________________________________
793 void AliQAv1::ShowASCIIStatus(AliRecoParam::EventSpecie_t es, DETECTORINDEX_t det, ALITASK_t tsk, const ULong_t status) const 
794 {
795         // print the QA status in human readable format
796         TString text; 
797         for (Int_t bit = kINFO ; bit < kNBIT ; bit++) {
798                 if (IsSet(det, tsk, es, QABIT_t(bit))) {
799                         text = GetBitName(QABIT_t(bit)) ; 
800                         text += " " ; 
801                 }
802         }
803         if (! text.IsNull())
804                 AliInfoClass(Form("           %8s %8s %4s 0x%4lx, Problem signalled: %8s \n", AliRecoParam::GetEventSpecieName(es), GetDetName(det).Data(), GetAliTaskName(tsk), status, text.Data())) ; 
805 }
806
807 //_______________________________________________________________
808 void AliQAv1::UnSet(QABIT_t bit, Int_t ies)
809 {
810         // UnSet the status bit of the current detector in the current module
811                 UnSet(bit, AliRecoParam::Convert(ies)) ;
812 }
813
814 //_______________________________________________________________
815 void AliQAv1::UnSet(QABIT_t bit, AliRecoParam::EventSpecie_t es)
816 {
817         // UnSet the status bit of the current detector in the current module
818         
819         UnSetStatusBit(fDet, fTask, es, bit) ;
820 }
821
822 //_______________________________________________________________
823 void AliQAv1::UnSetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, AliRecoParam::EventSpecie_t es, QABIT_t bit)
824 {
825         // UnSet the status bit for a given detector and a given task
826         
827         CheckRange(det) ;
828         CheckRange(tsk) ;
829         CheckRange(bit) ;
830         CheckRange(es) ;
831         
832         ULong_t offset = Offset(tsk) ;
833         ULong_t status = GetStatus(det, es) ;
834         offset+= bit ;
835         status = status & 0 << offset ;
836         SetStatus(det, es, status) ;
837 }