Movin AliQA from STEER to STEERBase
[u/mrichter/AliRoot.git] / STEER / AliQA.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$ */
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      (SIM)
24 // bit 4-7  : QA raised during reconstruction  (REC)
25 // bit 8-11 : QA raised during ESD checking    (ESD)
26 // bit 12-15: QA raised during analysis        (ANA)
27 // Each of the 4 bits corresponds to a severity level of increasing importance
28 // from lower to higher bit (INFO, WARNING, ERROR, FATAL)
29 //
30 //*-- Yves Schutz CERN, July 2007 
31 //////////////////////////////////////////////////////////////////////////////
32
33
34 // --- ROOT system ---
35 #include <TFile.h>
36 #include <TSystem.h>
37 #include <TROOT.h>
38
39 // --- Standard library ---
40
41 // --- AliRoot header files ---
42 #include "AliLog.h"
43 #include "AliQA.h"
44 #include "AliQAChecker.h"
45
46
47 ClassImp(AliQA)
48 AliQA    * AliQA::fgQA                   = 0x0 ;
49 TFile    * AliQA::fgQADataFile           = 0x0 ;   
50 TString    AliQA::fgQADataFileName       = "QA" ;  // will transform into Det.QA.run.cycle.root  
51 TFile    * AliQA::fgQARefFile            = 0x0 ;   
52 TString    AliQA::fgQARefDirName             = "" ; 
53 TString    AliQA::fgQARefFileName        = "QA.root" ;
54 TFile    * AliQA::fgQAResultFile         = 0x0 ;  
55 TString    AliQA::fgQAResultDirName      = "" ;  
56 TString    AliQA::fgQAResultFileName     = "QA.root" ; 
57 TString    AliQA::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
58                                                                                     "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"} ;   
59 TString       AliQA::fgTaskNames[]       = {"Raws", "Hits", "SDigits", "Digits", "RecPoints", "TrackSegments", "RecParticles", "ESDs"} ;   
60 const TString AliQA::fkgLabLocalFile     = "file://"  ; 
61 const TString AliQA::fkgLabLocalOCDB     = "local://" ;  
62 const TString AliQA::fkgLabAliEnOCDB     = "alien://" ;  
63 const TString AliQA::fkgRefFileName      = "QA.root" ; 
64 const TString AliQA::fkgQAOCDBDirName    = "QA"  ; 
65 const TString AliQA::fkgRefOCDBDirName   = "Ref"  ; 
66 const TString AliQA::fkgQARefOCDBDefault = "local://$ALICE_ROOT"  ; 
67 //____________________________________________________________________________
68 AliQA::AliQA() : 
69   TNamed("", ""), 
70   fNdet(kNDET), 
71   fQA(new ULong_t[fNdet]), 
72   fDet(kNULLDET),
73   fTask(kNULLTASK)
74         
75 {
76   // default constructor
77   // beware singleton: not to be used
78   
79   for (Int_t index = 0 ; index < fNdet ; index++) 
80         fQA[index] = 0 ; 
81 }
82
83 //____________________________________________________________________________
84 AliQA::AliQA(const AliQA& qa) :
85   TNamed(qa),
86   fNdet(qa.fNdet), 
87   fQA(qa.fQA), 
88   fDet(qa.fDet),
89   fTask(qa.fTask)
90
91   // cpy ctor
92 }
93
94 //_____________________________________________________________________________
95 AliQA& AliQA::operator = (const AliQA& qa)
96 {
97 // assignment operator
98
99   this->~AliQA();
100   new(this) AliQA(qa);
101   return *this;
102 }
103
104 //_______________________________________________________________
105 AliQA::AliQA(const DETECTORINDEX det) :
106   TNamed("QA", "Quality Assurance status"),
107   fNdet(kNDET),  
108   fQA(new ULong_t[fNdet]), 
109   fDet(det),
110   fTask(kNULLTASK) 
111 {
112   // constructor to be used
113   if (! CheckRange(det) ) {
114     fDet = kNULLDET ; 
115     return ;
116   } 
117   Int_t index ; 
118   for (index = 0; index < fNdet; index++) 
119     fQA[index] = 0 ; 
120 }
121   
122 //_______________________________________________________________
123 AliQA::AliQA(const ALITASK tsk) :
124   TNamed("QA", "Quality Assurance status"), 
125   fNdet(kNDET),
126   fQA(new ULong_t[fNdet]), 
127   fDet(kNULLDET),
128   fTask(tsk)
129 {
130   // constructor to be used in the AliRoot module (SIM, REC, ESD or ANA)
131   if (! CheckRange(tsk) ) {
132     fTask = kNULLTASK ; 
133     return ;
134   } 
135   Int_t index ; 
136   for (index = 0; index < fNdet; index++) 
137     fQA[index] = 0 ; 
138 }
139
140 //____________________________________________________________________________
141 AliQA::~AliQA() 
142 {
143   // dtor  
144   delete[] fQA ;
145 }
146
147 //_______________________________________________________________
148 void AliQA::Close() 
149 {
150         // close the open files
151         if (fgQADataFile) 
152                 if (fgQADataFile->IsOpen())
153                         fgQADataFile->Close() ; 
154         if (fgQAResultFile) 
155                 if (fgQAResultFile->IsOpen()) 
156                         fgQAResultFile->Close() ;
157         if (fgQARefFile)
158                 if (fgQARefFile->IsOpen())
159                         fgQARefFile->Close() ; 
160
161
162 //_______________________________________________________________
163 const Bool_t AliQA::CheckFatal() const
164 {
165   // check if any FATAL status is set
166   Bool_t rv = kFALSE ;
167   Int_t index ;
168   for (index = 0; index < kNDET ; index++)
169     rv = rv || IsSet(DETECTORINDEX(index), fTask, kFATAL) ;
170   return rv ;
171 }
172
173 //_______________________________________________________________
174 const Bool_t AliQA::CheckRange(DETECTORINDEX det) const
175
176   // check if detector is in given detector range: 0-kNDET
177
178   Bool_t rv = ( det < 0 || det > kNDET )  ? kFALSE : kTRUE ;
179   if (!rv)
180     AliFatal(Form("Detector index %d is out of range: 0 <= index <= %d", det, kNDET)) ;
181   return rv ;
182 }
183
184 //_______________________________________________________________
185 const Bool_t AliQA::CheckRange(ALITASK task) const
186
187   // check if task is given taskk range: 0:kNTASK
188   Bool_t rv = ( task < kRAW || task > kNTASK )  ? kFALSE : kTRUE ;
189   if (!rv)
190     AliFatal(Form("Module index %d is out of range: 0 <= index <= %d", task, kNTASK)) ;
191   return rv ;
192 }
193
194 //_______________________________________________________________
195 const Bool_t AliQA::CheckRange(QABIT bit) const
196
197   // check if bit is in given bit range: 0-kNBit
198
199   Bool_t rv = ( bit < 0 || bit > kNBIT )  ? kFALSE : kTRUE ;
200   if (!rv)
201     AliFatal(Form("Status bit %d is out of range: 0 <= bit <= %d", bit, kNBIT)) ;
202   return rv ;
203 }
204
205
206
207 //_______________________________________________________________
208 const char * AliQA::GetAliTaskName(ALITASK tsk)
209 {
210   // returns the char name corresponding to module index
211   TString tskName ;
212   switch (tsk) {
213   case kNULLTASK:
214     break ; 
215   case kRAW:
216     tskName = "RAW" ;
217     break ;  
218   case kSIM:
219     tskName = "SIM" ;
220     break ;
221   case kREC:
222     tskName = "REC" ;
223     break ;
224   case kESD:
225     tskName = "ESD" ;
226     break ;
227   case kANA:
228     tskName = "ANA" ;
229     break ;
230   default:
231     tsk = kNULLTASK ; 
232     break ;
233   }
234   return tskName.Data() ;
235 }
236
237 //_______________________________________________________________
238 const char * AliQA::GetDetName(Int_t det) 
239 {
240         // returns the detector name corresponding to a given index (needed in a loop)
241
242         if ( det >= 0 &&  det < kNDET) 
243                 return (fgDetNames[det]).Data() ; 
244         else 
245                 return NULL ; 
246 }
247
248 //_______________________________________________________________
249 TFile * AliQA::GetQADataFile(const char * name, const Int_t run, const Int_t cycle) 
250 {
251   // opens the file to store the detectors Quality Assurance Data Maker results
252   char temp[20] ; 
253   sprintf(temp, "%s.%s.%d.%d.root", name, fgQADataFileName.Data(), run, cycle) ; 
254   TString opt ; 
255   if (! fgQADataFile ) {     
256     if  (gSystem->AccessPathName(temp))
257       opt = "NEW" ;
258     else 
259       opt = "UPDATE" ; 
260     fgQADataFile = TFile::Open(temp, opt.Data()) ;
261   } else {
262           if ( strcmp(temp, fgQADataFile->GetName()) != 0 ) {
263                   fgQADataFile = dynamic_cast<TFile *>(gROOT->FindObject(temp)) ; 
264                   if ( !fgQADataFile ) {
265                           if  (gSystem->AccessPathName(temp))
266                                   opt = "NEW" ;
267                           else 
268                                   opt = "UPDATE" ; 
269                           fgQADataFile = TFile::Open(temp, opt.Data()) ;
270                   }
271           }
272   }
273   return fgQADataFile ; 
274
275
276 //_____________________________________________________________________________
277 TFile * AliQA::GetQADataFile(const char * fileName)
278 {
279   // Open if necessary the Data file and return its pointer
280
281   if (!fgQADataFile) 
282         if (!fileName) 
283                 fileName = AliQA::GetQADataFileName() ; 
284         if  (!gSystem->AccessPathName(fileName)) {
285                 fgQADataFile =  TFile::Open(fileName) ;
286         } else {
287                 printf("File %s not found", fileName) ;
288                 exit(1) ;  
289         }
290   return fgQADataFile ; 
291 }
292
293 //_______________________________________________________________
294 TFile * AliQA::GetQAResultFile() 
295 {
296   // opens the file to store the  Quality Assurance Data Checker results
297    
298         if (!fgQAResultFile) { 
299                 TString dirName(fgQAResultDirName) ; 
300                 if ( dirName.Contains(fkgLabLocalFile)) 
301                         dirName.ReplaceAll(fkgLabLocalFile, "") ;
302                 TString fileName(dirName + fgQAResultFileName) ; 
303                 TString opt("") ; 
304                 if ( !gSystem->AccessPathName(fileName) )
305                         opt = "UPDATE" ; 
306                 else { 
307                         if ( gSystem->AccessPathName(dirName) )
308                                 gSystem->mkdir(dirName) ; 
309                         opt = "NEW" ; 
310                 }
311                 fgQAResultFile = TFile::Open(fileName, opt) ;   
312         }
313         
314         return fgQAResultFile ;
315 }
316
317 //_______________________________________________________________
318 const Bool_t AliQA::IsSet(DETECTORINDEX det, ALITASK tsk, QABIT bit) const
319 {
320   // Checks is the requested bit is set
321
322   CheckRange(det) ; 
323   CheckRange(tsk) ;
324   CheckRange(bit) ;
325
326   ULong_t offset = Offset(tsk) ;
327   ULong_t status = GetStatus(det) ;
328   offset+= bit ;
329   status = (status & 1 << offset) != 0 ;
330   return status ;
331 }
332
333 //_______________________________________________________________
334 AliQA * AliQA::Instance()
335 {
336   // Get an instance of the singleton.
337   // Object must have been instantiated with Instance(ALITASK) first
338
339   return fgQA ;
340 }
341
342 //_______________________________________________________________
343 AliQA * AliQA::Instance(const DETECTORINDEX det)
344 {
345   // Get an instance of the singleton. The only authorized way to call the ctor
346   
347   if ( ! fgQA) {
348     TFile * f = GetQAResultFile() ; 
349         fgQA = dynamic_cast<AliQA *>(f->Get("QA")) ; 
350     if ( ! fgQA ) 
351                 fgQA = new AliQA(det) ;
352   }             
353   fgQA->Set(det) ;
354   return fgQA ;
355 }
356
357 //_______________________________________________________________
358 AliQA * AliQA::Instance(const ALITASK tsk)
359 {
360   // get an instance of the singleton.
361
362   if ( ! fgQA)
363     switch (tsk) {
364     case kNULLTASK:
365       break ;
366         case kRAW:
367       fgQA = new AliQA(tsk) ;
368       break ;
369         case kSIM:
370       fgQA = new AliQA(tsk) ;
371       break ;
372     case kREC:
373       printf("fgQA = gAlice->GetQA()") ;
374       break ;
375     case kESD:
376       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
377       break ;
378     case kANA:
379       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
380       break ;
381     case kNTASK:
382       break ;
383     }
384   if (fgQA) 
385     fgQA->Set(tsk) ;
386   return fgQA ;
387 }
388
389 //_______________________________________________________________
390 const ULong_t AliQA::Offset(ALITASK tsk) const
391 {
392   // Calculates the bit offset for a given module (SIM, REC, ESD, ANA)
393
394   CheckRange(tsk) ; 
395
396   ULong_t offset = 0 ;
397   switch (tsk) {
398   case kNULLTASK:
399     break ;
400   case kRAW:
401     offset+= 0 ;
402     break ;
403   case kSIM:
404     offset+= 4 ;
405     break ;
406   case kREC:
407     offset+= 8 ;
408     break ;
409   case kESD:
410     offset+= 12 ;
411     break ;
412   case kANA:
413     offset+= 16 ;
414     break ;
415   case kNTASK:
416     break ;
417   }
418
419   return offset ;
420 }
421
422 //_______________________________________________________________
423 void AliQA::Set(QABIT bit)
424 {
425   // Set the status bit of the current detector in the current module
426   
427   SetStatusBit(fDet, fTask, bit) ;
428 }
429
430 //_____________________________________________________________________________
431 void AliQA::SetQARefStorage(const char * name)
432 {
433   // Set the root directory where the QA reference data are stored
434
435   fgQARefDirName = name ; 
436   if (  fgQARefDirName.Contains(fkgLabLocalFile) )
437          fgQARefFileName =  fkgRefFileName ; 
438   else if (     fgQARefDirName.Contains(fkgLabLocalOCDB) )
439           fgQARefFileName =  fkgQAOCDBDirName ; 
440   else {
441           printf("ERROR: %s is an invalid storage definition\n", name) ; 
442           fgQARefDirName  = "" ; 
443           fgQARefFileName = "" ; 
444   }     
445         TString tmp(fgQARefDirName + fgQARefFileName) ;
446         printf("AliQA::SetQARefDir: QA references are in  %s\n", tmp.Data() ) ;
447 }
448
449 //_____________________________________________________________________________
450 void AliQA::SetQAResultDirName(const char * name)
451 {
452   // Set the root directory where to store the QA status object
453
454   fgQAResultDirName.Prepend(name) ; 
455   printf("AliQA::SetQAResultDirName: QA results are in  %s\n", fgQAResultDirName.Data()) ;
456   if ( fgQAResultDirName.Contains(fkgLabLocalFile)) 
457     fgQAResultDirName.ReplaceAll(fkgLabLocalFile, "") ;
458   fgQAResultFileName.Prepend(fgQAResultDirName) ;
459 }
460
461 //_______________________________________________________________
462 void AliQA::SetStatusBit(DETECTORINDEX det, ALITASK tsk, QABIT bit)
463 {
464  // Set the status bit for a given detector and a given task
465
466   CheckRange(det) ;
467   CheckRange(tsk) ;
468   CheckRange(bit) ;
469
470   ULong_t offset = Offset(tsk) ;
471   ULong_t status = GetStatus(det) ;
472   offset+= bit ;
473   status = status | 1 << offset ;
474   SetStatus(det, status) ;
475 }
476
477 //_______________________________________________________________
478 void AliQA::ShowAll() const
479 {
480   // dispplay the QA status word
481   Int_t index ;
482   for (index = 0 ; index < kNDET ; index++)
483     ShowStatus(DETECTORINDEX(index)) ;
484 }
485
486 //_______________________________________________________________
487 void AliQA::ShowStatus(DETECTORINDEX det) const
488 {
489   // Prints the full QA status of a given detector
490   CheckRange(det) ;
491   ULong_t status = GetStatus(det) ;
492   ULong_t rawStatus = status & 0x0000f ;
493   ULong_t simStatus = status & 0x000f0 ;
494   ULong_t recStatus = status & 0x00f00 ;
495   ULong_t esdStatus = status & 0x0f000 ;
496   ULong_t anaStatus = status & 0xf0000 ;
497
498   AliInfo(Form("QA Status for %s raw =0x%x, sim=0x%x, rec=0x%x, esd=0x%x, ana=0x%x\n", GetDetName(det).Data(), rawStatus, simStatus, recStatus, esdStatus, anaStatus )) ;
499 }
500