Added methods for finding a given module in the DDL map (F. Prino)
[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
45
46 ClassImp(AliQA)
47 AliQA    * AliQA::fgQA                   = 0x0 ;
48 TFile    * AliQA::fgQADataFile           = 0x0 ;   
49 TString    AliQA::fgQADataFileName       = "QA" ;  // will transform into Det.QA.run.cycle.root  
50 TFile    * AliQA::fgQARefFile            = 0x0 ;   
51 TString    AliQA::fgQARefDirName             = "" ; 
52 TString    AliQA::fgQARefFileName        = "QA.root" ;
53 TFile    * AliQA::fgQAResultFile         = 0x0 ;  
54 TString    AliQA::fgQAResultDirName      = "" ;  
55 TString    AliQA::fgQAResultFileName     = "QA.root" ; 
56 TString    AliQA::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
57                                                                                     "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global"} ;   
58 TString       AliQA::fgTaskNames[]       = {"Raws", "Hits", "SDigits", "Digits", "RecPoints", "TrackSegments", "RecParticles", "ESDs"} ;   
59 const TString AliQA::fkgLabLocalFile     = "file://"  ; 
60 const TString AliQA::fkgLabLocalOCDB     = "local://" ;  
61 const TString AliQA::fkgLabAliEnOCDB     = "alien://" ;  
62 const TString AliQA::fkgRefFileName      = "QA.root" ; 
63 const TString AliQA::fkgQAName           = "QA"  ; 
64 const TString AliQA::fkgRefOCDBDirName   = "Ref"  ; 
65 TString AliQA::fkgRefDataDirName   = "Data"  ; 
66 const TString AliQA::fkgQARefOCDBDefault = "alien://folder=/alice/QA/20"  ; 
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_t 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_t 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_t(index), fTask, kFATAL) ;
170   return rv ;
171 }
172
173 //_______________________________________________________________
174 const Bool_t AliQA::CheckRange(DETECTORINDEX_t 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_t 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_t 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_t 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 AliQA::DETECTORINDEX_t AliQA::GetDetIndex(const char * name) 
239 {
240         // returns the detector index corresponding to a given name
241         TString sname(name) ; 
242         DETECTORINDEX_t rv = kNULLDET ; 
243         for (Int_t det = 0; det < kNDET ; det++) {
244                 if ( GetDetName(det) == sname ) {
245                         rv = DETECTORINDEX_t(det) ; 
246                         break ; 
247                 }
248         }
249         return rv ;             
250 }
251
252 //_______________________________________________________________
253 const char * AliQA::GetDetName(Int_t det) 
254 {
255         // returns the detector name corresponding to a given index (needed in a loop)
256         
257         if ( det >= 0 &&  det < kNDET) 
258                 return (fgDetNames[det]).Data() ; 
259         else 
260                 return NULL ; 
261 }
262
263 //_______________________________________________________________
264 TFile * AliQA::GetQADataFile(const char * name, const Int_t run, const Int_t cycle) 
265 {
266   // opens the file to store the detectors Quality Assurance Data Maker results
267         const char * temp = Form("%s.%s.%d.%d.root", name, fgQADataFileName.Data(), run, cycle) ; 
268         TString opt ; 
269         if (! fgQADataFile ) {     
270                 if  (gSystem->AccessPathName(temp))
271                         opt = "NEW" ;
272                 else 
273                         opt = "UPDATE" ; 
274                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
275         } else {
276                 if ( strcmp(temp, fgQADataFile->GetName()) != 0 ) {
277                         fgQADataFile = dynamic_cast<TFile *>(gROOT->FindObject(temp)) ; 
278                         if ( !fgQADataFile ) {
279                                 if  (gSystem->AccessPathName(temp))
280                                         opt = "NEW" ;
281                                 else 
282                                         opt = "UPDATE" ; 
283                                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
284                         }
285                 }
286   }
287         return fgQADataFile ;
288
289
290 //_____________________________________________________________________________
291 TFile * AliQA::GetQADataFile(const char * fileName)
292 {
293   // Open if necessary the Data file and return its pointer
294
295   if (!fgQADataFile) 
296         if (!fileName) 
297                 fileName = AliQA::GetQADataFileName() ; 
298         if  (!gSystem->AccessPathName(fileName)) {
299                 fgQADataFile =  TFile::Open(fileName) ;
300         } else {
301                 printf("File %s not found", fileName) ;
302                 exit(1) ;  
303         }
304   return fgQADataFile ; 
305 }
306
307 //_______________________________________________________________
308 TFile * AliQA::GetQAResultFile() 
309 {
310   // opens the file to store the  Quality Assurance Data Checker results
311         if (fgQAResultFile) 
312                 fgQAResultFile->Close() ; 
313         fgQAResultFile = 0x0 ; 
314 //      if (!fgQAResultFile) { 
315                 TString dirName(fgQAResultDirName) ; 
316                 if ( dirName.Contains(fkgLabLocalFile)) 
317                         dirName.ReplaceAll(fkgLabLocalFile, "") ;
318                 TString fileName(dirName + fgQAResultFileName) ; 
319                 TString opt("") ; 
320                 if ( !gSystem->AccessPathName(fileName) )
321                         opt = "UPDATE" ; 
322                 else { 
323                         if ( gSystem->AccessPathName(dirName) )
324                                 gSystem->mkdir(dirName) ; 
325                         opt = "NEW" ; 
326                 }
327                 fgQAResultFile = TFile::Open(fileName, opt) ;   
328 //      }
329         
330         return fgQAResultFile ;
331 }
332
333 //_______________________________________________________________
334 const Bool_t AliQA::IsSet(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit) const
335 {
336   // Checks is the requested bit is set
337
338   CheckRange(det) ; 
339   CheckRange(tsk) ;
340   CheckRange(bit) ;
341
342   ULong_t offset = Offset(tsk) ;
343   ULong_t status = GetStatus(det) ;
344   offset+= bit ;
345   status = (status & 1 << offset) != 0 ;
346   return status ;
347 }
348
349 //_______________________________________________________________
350 AliQA * AliQA::Instance()
351 {
352   // Get an instance of the singleton.
353   // Object must have been instantiated with Instance(ALITASK) first
354
355   return fgQA ;
356 }
357
358 //_______________________________________________________________
359 AliQA * AliQA::Instance(const DETECTORINDEX_t det)
360 {
361   // Get an instance of the singleton. The only authorized way to call the ctor
362   
363   if ( ! fgQA) {
364     TFile * f = GetQAResultFile() ; 
365         fgQA = dynamic_cast<AliQA *>(f->Get("QA")) ; 
366     if ( ! fgQA ) 
367                 fgQA = new AliQA(det) ;
368   }             
369   fgQA->Set(det) ;
370   return fgQA ;
371 }
372
373 //_______________________________________________________________
374 AliQA * AliQA::Instance(const ALITASK_t tsk)
375 {
376   // get an instance of the singleton.
377
378   if ( ! fgQA)
379     switch (tsk) {
380     case kNULLTASK:
381       break ;
382         case kRAW:
383       fgQA = new AliQA(tsk) ;
384       break ;
385         case kSIM:
386       fgQA = new AliQA(tsk) ;
387       break ;
388     case kREC:
389       printf("fgQA = gAlice->GetQA()") ;
390       break ;
391     case kESD:
392       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
393       break ;
394     case kANA:
395       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
396       break ;
397     case kNTASK:
398       break ;
399     }
400   if (fgQA) 
401     fgQA->Set(tsk) ;
402   return fgQA ;
403 }
404
405 //_______________________________________________________________
406 AliQA *  AliQA::Instance(const TASKINDEX_t tsk) 
407 {
408         // get an instance of the singleton.
409         
410         ALITASK_t index = kNULLTASK ; 
411
412         if ( tsk == kRAWS )
413                 index = kRAW ;
414         else if (tsk < kDIGITS)
415                 index = kSIM ;
416         else if (tsk < kRECPARTICLES)
417                 index = kREC ; 
418         else if (tsk == kESDS) 
419                 index = kESD ; 
420
421         return Instance(index) ; 
422 }
423
424 //_______________________________________________________________
425 const ULong_t AliQA::Offset(ALITASK_t tsk) const
426 {
427   // Calculates the bit offset for a given module (SIM, REC, ESD, ANA)
428
429   CheckRange(tsk) ; 
430
431   ULong_t offset = 0 ;
432   switch (tsk) {
433   case kNULLTASK:
434     break ;
435   case kRAW:
436     offset+= 0 ;
437     break ;
438   case kSIM:
439     offset+= 4 ;
440     break ;
441   case kREC:
442     offset+= 8 ;
443     break ;
444   case kESD:
445     offset+= 12 ;
446     break ;
447   case kANA:
448     offset+= 16 ;
449     break ;
450   case kNTASK:
451     break ;
452   }
453
454   return offset ;
455 }
456
457 //_______________________________________________________________
458 void AliQA::Set(QABIT_t bit)
459 {
460   // Set the status bit of the current detector in the current module
461   
462   SetStatusBit(fDet, fTask, bit) ;
463 }
464
465 //_____________________________________________________________________________
466 void AliQA::SetQARefStorage(const char * name)
467 {
468         // Set the root directory where the QA reference data are stored
469
470         fgQARefDirName = name ; 
471         if ( fgQARefDirName.Contains(fkgLabLocalFile) )
472                 fgQARefFileName =  fkgRefFileName ; 
473         else if ( fgQARefDirName.Contains(fkgLabLocalOCDB) )
474                 fgQARefFileName =  fkgQAName ; 
475         else if ( fgQARefDirName.Contains(fkgLabAliEnOCDB) )
476                 fgQARefFileName =  fkgQAName ; 
477
478   else {
479           printf("ERROR: %s is an invalid storage definition\n", name) ; 
480           fgQARefDirName  = "" ; 
481           fgQARefFileName = "" ; 
482   }     
483         TString tmp(fgQARefDirName) ; // + fgQARefFileName) ;
484         printf("AliQA::SetQARefDir: QA references are in  %s\n", tmp.Data() ) ;
485 }
486
487 //_____________________________________________________________________________
488 void AliQA::SetQAResultDirName(const char * name)
489 {
490   // Set the root directory where to store the QA status object
491
492   fgQAResultDirName.Prepend(name) ; 
493   printf("AliQA::SetQAResultDirName: QA results are in  %s\n", fgQAResultDirName.Data()) ;
494   if ( fgQAResultDirName.Contains(fkgLabLocalFile)) 
495     fgQAResultDirName.ReplaceAll(fkgLabLocalFile, "") ;
496   fgQAResultFileName.Prepend(fgQAResultDirName) ;
497 }
498
499 //_______________________________________________________________
500 void AliQA::SetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
501 {
502  // Set the status bit for a given detector and a given task
503
504   CheckRange(det) ;
505   CheckRange(tsk) ;
506   CheckRange(bit) ;
507
508   ULong_t offset = Offset(tsk) ;
509   ULong_t status = GetStatus(det) ;
510   offset+= bit ;
511   status = status | 1 << offset ;
512   SetStatus(det, status) ;
513 }
514
515 //_______________________________________________________________
516 void AliQA::ShowAll() const
517 {
518   // dispplay the QA status word
519   Int_t index ;
520   for (index = 0 ; index < kNDET ; index++)
521     ShowStatus(DETECTORINDEX_t(index)) ;
522 }
523
524 //_______________________________________________________________
525 void AliQA::ShowStatus(DETECTORINDEX_t det) const
526 {
527   // Prints the full QA status of a given detector
528   CheckRange(det) ;
529   ULong_t status = GetStatus(det) ;
530   ULong_t rawStatus = status & 0x0000f ;
531   ULong_t simStatus = status & 0x000f0 ;
532   ULong_t recStatus = status & 0x00f00 ;
533   ULong_t esdStatus = status & 0x0f000 ;
534   ULong_t anaStatus = status & 0xf0000 ;
535
536   AliInfo(Form("QA Status for %8s raw =0x%x, sim=0x%x, rec=0x%x, esd=0x%x, ana=0x%x\n", GetDetName(det).Data(), rawStatus, simStatus, recStatus, esdStatus, anaStatus )) ;
537 }
538
539 //_______________________________________________________________
540 void AliQA::UnSet(QABIT_t bit)
541 {
542         // UnSet the status bit of the current detector in the current module
543         
544         UnSetStatusBit(fDet, fTask, bit) ;
545 }
546
547 //_______________________________________________________________
548 void AliQA::UnSetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
549 {
550         // UnSet the status bit for a given detector and a given task
551         
552         CheckRange(det) ;
553         CheckRange(tsk) ;
554         CheckRange(bit) ;
555         
556         ULong_t offset = Offset(tsk) ;
557         ULong_t status = GetStatus(det) ;
558         offset+= bit ;
559         status = status & 0 << offset ;
560         SetStatus(det, status) ;
561 }