]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliQA.cxx
Include cstdlib (gcc 4.3.0)
[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 #include <cstdlib>
35 // --- ROOT system ---
36 #include <TFile.h>
37 #include <TSystem.h>
38 #include <TROOT.h>
39
40 // --- Standard library ---
41
42 // --- AliRoot header files ---
43 #include "AliLog.h"
44 #include "AliQA.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", "Global"} ;   
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::fkgQAName           = "QA"  ; 
65 const TString AliQA::fkgRefOCDBDirName   = "Ref"  ; 
66 TString AliQA::fkgRefDataDirName   = "Data"  ; 
67 const TString AliQA::fkgQARefOCDBDefault = "alien://folder=/alice/QA/20"  ; 
68 //____________________________________________________________________________
69 AliQA::AliQA() : 
70   TNamed("", ""), 
71   fNdet(kNDET), 
72   fQA(new ULong_t[fNdet]), 
73   fDet(kNULLDET),
74   fTask(kNULLTASK)
75         
76 {
77   // default constructor
78   // beware singleton: not to be used
79   
80   for (Int_t index = 0 ; index < fNdet ; index++) 
81         fQA[index] = 0 ; 
82 }
83
84 //____________________________________________________________________________
85 AliQA::AliQA(const AliQA& qa) :
86   TNamed(qa),
87   fNdet(qa.fNdet), 
88   fQA(qa.fQA), 
89   fDet(qa.fDet),
90   fTask(qa.fTask)
91
92   // cpy ctor
93 }
94
95 //_____________________________________________________________________________
96 AliQA& AliQA::operator = (const AliQA& qa)
97 {
98 // assignment operator
99
100   this->~AliQA();
101   new(this) AliQA(qa);
102   return *this;
103 }
104
105 //_______________________________________________________________
106 AliQA::AliQA(const DETECTORINDEX_t det) :
107   TNamed("QA", "Quality Assurance status"),
108   fNdet(kNDET),  
109   fQA(new ULong_t[fNdet]), 
110   fDet(det),
111   fTask(kNULLTASK) 
112 {
113   // constructor to be used
114   if (! CheckRange(det) ) {
115     fDet = kNULLDET ; 
116     return ;
117   } 
118   Int_t index ; 
119   for (index = 0; index < fNdet; index++) 
120     fQA[index] = 0 ; 
121 }
122   
123 //_______________________________________________________________
124 AliQA::AliQA(const ALITASK_t tsk) :
125   TNamed("QA", "Quality Assurance status"), 
126   fNdet(kNDET),
127   fQA(new ULong_t[fNdet]), 
128   fDet(kNULLDET),
129   fTask(tsk)
130 {
131   // constructor to be used in the AliRoot module (SIM, REC, ESD or ANA)
132   if (! CheckRange(tsk) ) {
133     fTask = kNULLTASK ; 
134     return ;
135   } 
136   Int_t index ; 
137   for (index = 0; index < fNdet; index++) 
138     fQA[index] = 0 ; 
139 }
140
141 //____________________________________________________________________________
142 AliQA::~AliQA() 
143 {
144   // dtor  
145   delete[] fQA ;
146 }
147
148 //_______________________________________________________________
149 void AliQA::Close() 
150 {
151         // close the open files
152         if (fgQADataFile) 
153                 if (fgQADataFile->IsOpen())
154                         fgQADataFile->Close() ; 
155         if (fgQAResultFile) 
156                 if (fgQAResultFile->IsOpen()) 
157                         fgQAResultFile->Close() ;
158         if (fgQARefFile)
159                 if (fgQARefFile->IsOpen())
160                         fgQARefFile->Close() ; 
161
162
163 //_______________________________________________________________
164 const Bool_t AliQA::CheckFatal() const
165 {
166   // check if any FATAL status is set
167   Bool_t rv = kFALSE ;
168   Int_t index ;
169   for (index = 0; index < kNDET ; index++)
170     rv = rv || IsSet(DETECTORINDEX_t(index), fTask, kFATAL) ;
171   return rv ;
172 }
173
174 //_______________________________________________________________
175 const Bool_t AliQA::CheckRange(DETECTORINDEX_t det) const
176
177   // check if detector is in given detector range: 0-kNDET
178
179   Bool_t rv = ( det < 0 || det > kNDET )  ? kFALSE : kTRUE ;
180   if (!rv)
181     AliFatal(Form("Detector index %d is out of range: 0 <= index <= %d", det, kNDET)) ;
182   return rv ;
183 }
184
185 //_______________________________________________________________
186 const Bool_t AliQA::CheckRange(ALITASK_t task) const
187
188   // check if task is given taskk range: 0:kNTASK
189   Bool_t rv = ( task < kRAW || task > kNTASK )  ? kFALSE : kTRUE ;
190   if (!rv)
191     AliFatal(Form("Module index %d is out of range: 0 <= index <= %d", task, kNTASK)) ;
192   return rv ;
193 }
194
195 //_______________________________________________________________
196 const Bool_t AliQA::CheckRange(QABIT_t bit) const
197
198   // check if bit is in given bit range: 0-kNBit
199
200   Bool_t rv = ( bit < 0 || bit > kNBIT )  ? kFALSE : kTRUE ;
201   if (!rv)
202     AliFatal(Form("Status bit %d is out of range: 0 <= bit <= %d", bit, kNBIT)) ;
203   return rv ;
204 }
205
206
207
208 //_______________________________________________________________
209 const char * AliQA::GetAliTaskName(ALITASK_t tsk)
210 {
211         // returns the char name corresponding to module index
212         TString tskName ;
213         switch (tsk) {
214                 case kNULLTASK:
215                         break ; 
216                 case kRAW:
217                         tskName = "RAW" ;
218                         break ;  
219                 case kSIM:
220                         tskName = "SIM" ;
221                         break ;
222                 case kREC:
223                         tskName = "REC" ;
224                         break ;
225                 case kESD:
226                         tskName = "ESD" ;
227                         break ;
228                 case kANA:
229                         tskName = "ANA" ;
230                         break ;
231                 default:
232                         tsk = kNULLTASK ; 
233                         break ;
234         }
235         return tskName.Data() ;
236 }
237 //_______________________________________________________________
238 const char * AliQA::GetBitName(QABIT_t bit) const
239 {
240         // returns the char name corresponding to bit 
241         TString bitName ;
242         switch (bit) {
243                 case kNULLBit:
244                         break ; 
245                 case kINFO:
246                         bitName = "INFO" ;
247                         break ;  
248                 case kWARNING:
249                         bitName = "WARNING" ;
250                         break ;
251                 case kERROR:
252                         bitName = "ERROR" ;
253                         break ;
254                 case kFATAL:
255                         bitName = "FATAL" ;
256                         break ;
257                 default:
258                         bit = kNULLBit ; 
259                         break ;
260         }
261         return bitName.Data() ;
262 }
263
264 //_______________________________________________________________
265 const AliQA::DETECTORINDEX_t AliQA::GetDetIndex(const char * name) 
266 {
267         // returns the detector index corresponding to a given name
268         TString sname(name) ; 
269         DETECTORINDEX_t rv = kNULLDET ; 
270         for (Int_t det = 0; det < kNDET ; det++) {
271                 if ( GetDetName(det) == sname ) {
272                         rv = DETECTORINDEX_t(det) ; 
273                         break ; 
274                 }
275         }
276         return rv ;             
277 }
278
279 //_______________________________________________________________
280 const char * AliQA::GetDetName(Int_t det) 
281 {
282         // returns the detector name corresponding to a given index (needed in a loop)
283         
284         if ( det >= 0 &&  det < kNDET) 
285                 return (fgDetNames[det]).Data() ; 
286         else 
287                 return NULL ; 
288 }
289
290 //_______________________________________________________________
291 TFile * AliQA::GetQADataFile(const char * name, const Int_t run, const Int_t cycle) 
292 {
293   // opens the file to store the detectors Quality Assurance Data Maker results
294         const char * temp = Form("%s.%s.%d.%d.root", name, fgQADataFileName.Data(), run, cycle) ; 
295         TString opt ; 
296         if (! fgQADataFile ) {     
297                 if  (gSystem->AccessPathName(temp))
298                         opt = "NEW" ;
299                 else 
300                         opt = "UPDATE" ; 
301                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
302         } else {
303                 if ( strcmp(temp, fgQADataFile->GetName()) != 0 ) {
304                         fgQADataFile = dynamic_cast<TFile *>(gROOT->FindObject(temp)) ; 
305                         if ( !fgQADataFile ) {
306                                 if  (gSystem->AccessPathName(temp))
307                                         opt = "NEW" ;
308                                 else 
309                                         opt = "UPDATE" ; 
310                                 fgQADataFile = TFile::Open(temp, opt.Data()) ;
311                         }
312                 }
313   }
314         return fgQADataFile ;
315
316
317 //_____________________________________________________________________________
318 TFile * AliQA::GetQADataFile(const char * fileName)
319 {
320   // Open if necessary the Data file and return its pointer
321
322   if (!fgQADataFile) 
323         if (!fileName) 
324                 fileName = AliQA::GetQADataFileName() ; 
325         if  (!gSystem->AccessPathName(fileName)) {
326                 fgQADataFile =  TFile::Open(fileName) ;
327         } else {
328                 printf("File %s not found", fileName) ;
329                 exit(1) ;  
330         }
331   return fgQADataFile ; 
332 }
333
334 //_______________________________________________________________
335 TFile * AliQA::GetQAResultFile() 
336 {
337   // opens the file to store the  Quality Assurance Data Checker results
338         if (fgQAResultFile) 
339                 fgQAResultFile->Close() ; 
340         fgQAResultFile = 0x0 ; 
341 //      if (!fgQAResultFile) { 
342                 TString dirName(fgQAResultDirName) ; 
343                 if ( dirName.Contains(fkgLabLocalFile)) 
344                         dirName.ReplaceAll(fkgLabLocalFile, "") ;
345                 TString fileName(dirName + fgQAResultFileName) ; 
346                 TString opt("") ; 
347                 if ( !gSystem->AccessPathName(fileName) )
348                         opt = "UPDATE" ; 
349                 else { 
350                         if ( gSystem->AccessPathName(dirName) )
351                                 gSystem->mkdir(dirName) ; 
352                         opt = "NEW" ; 
353                 }
354                 fgQAResultFile = TFile::Open(fileName, opt) ;   
355 //      }
356         
357         return fgQAResultFile ;
358 }
359
360 //_______________________________________________________________
361 const Bool_t AliQA::IsSet(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit) const
362 {
363   // Checks is the requested bit is set
364
365   CheckRange(det) ; 
366   CheckRange(tsk) ;
367   CheckRange(bit) ;
368
369   ULong_t offset = Offset(tsk) ;
370   ULong_t status = GetStatus(det) ;
371   offset+= bit ;
372   status = (status & 1 << offset) != 0 ;
373   return status ;
374 }
375
376 //_______________________________________________________________
377 AliQA * AliQA::Instance()
378 {
379   // Get an instance of the singleton.
380   // Object must have been instantiated with Instance(ALITASK) first
381
382   return fgQA ;
383 }
384
385 //_______________________________________________________________
386 AliQA * AliQA::Instance(const DETECTORINDEX_t det)
387 {
388   // Get an instance of the singleton. The only authorized way to call the ctor
389   
390   if ( ! fgQA) {
391     TFile * f = GetQAResultFile() ; 
392         fgQA = dynamic_cast<AliQA *>(f->Get("QA")) ; 
393     if ( ! fgQA ) 
394                 fgQA = new AliQA(det) ;
395   }             
396   fgQA->Set(det) ;
397   return fgQA ;
398 }
399
400 //_______________________________________________________________
401 AliQA * AliQA::Instance(const ALITASK_t tsk)
402 {
403   // get an instance of the singleton.
404
405   if ( ! fgQA)
406     switch (tsk) {
407     case kNULLTASK:
408       break ;
409         case kRAW:
410       fgQA = new AliQA(tsk) ;
411       break ;
412         case kSIM:
413       fgQA = new AliQA(tsk) ;
414       break ;
415     case kREC:
416       printf("fgQA = gAlice->GetQA()") ;
417       break ;
418     case kESD:
419       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
420       break ;
421     case kANA:
422       printf("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
423       break ;
424     case kNTASK:
425       break ;
426     }
427   if (fgQA) 
428     fgQA->Set(tsk) ;
429   return fgQA ;
430 }
431
432 //_______________________________________________________________
433 AliQA *  AliQA::Instance(const TASKINDEX_t tsk) 
434 {
435         // get an instance of the singleton.
436         
437         ALITASK_t index = kNULLTASK ; 
438
439         if ( tsk == kRAWS )
440                 index = kRAW ;
441         else if (tsk < kDIGITS)
442                 index = kSIM ;
443         else if (tsk < kRECPARTICLES)
444                 index = kREC ; 
445         else if (tsk == kESDS) 
446                 index = kESD ; 
447
448         return Instance(index) ; 
449 }
450
451 //_______________________________________________________________
452 const ULong_t AliQA::Offset(ALITASK_t tsk) const
453 {
454   // Calculates the bit offset for a given module (SIM, REC, ESD, ANA)
455
456   CheckRange(tsk) ; 
457
458   ULong_t offset = 0 ;
459   switch (tsk) {
460   case kNULLTASK:
461     break ;
462   case kRAW:
463     offset+= 0 ;
464     break ;
465   case kSIM:
466     offset+= 4 ;
467     break ;
468   case kREC:
469     offset+= 8 ;
470     break ;
471   case kESD:
472     offset+= 12 ;
473     break ;
474   case kANA:
475     offset+= 16 ;
476     break ;
477   case kNTASK:
478     break ;
479   }
480
481   return offset ;
482 }
483
484 //_______________________________________________________________
485 void AliQA::Set(QABIT_t bit)
486 {
487   // Set the status bit of the current detector in the current module
488   
489   SetStatusBit(fDet, fTask, bit) ;
490 }
491
492 //_____________________________________________________________________________
493 void AliQA::SetQARefStorage(const char * name)
494 {
495         // Set the root directory where the QA reference data are stored
496
497         fgQARefDirName = name ; 
498         if ( fgQARefDirName.Contains(fkgLabLocalFile) )
499                 fgQARefFileName =  fkgRefFileName ; 
500         else if ( fgQARefDirName.Contains(fkgLabLocalOCDB) )
501                 fgQARefFileName =  fkgQAName ; 
502         else if ( fgQARefDirName.Contains(fkgLabAliEnOCDB) )
503                 fgQARefFileName =  fkgQAName ; 
504
505   else {
506           printf("ERROR: %s is an invalid storage definition\n", name) ; 
507           fgQARefDirName  = "" ; 
508           fgQARefFileName = "" ; 
509   }     
510         TString tmp(fgQARefDirName) ; // + fgQARefFileName) ;
511         printf("AliQA::SetQARefDir: QA references are in  %s\n", tmp.Data() ) ;
512 }
513
514 //_____________________________________________________________________________
515 void AliQA::SetQAResultDirName(const char * name)
516 {
517   // Set the root directory where to store the QA status object
518
519   fgQAResultDirName.Prepend(name) ; 
520   printf("AliQA::SetQAResultDirName: QA results are in  %s\n", fgQAResultDirName.Data()) ;
521   if ( fgQAResultDirName.Contains(fkgLabLocalFile)) 
522     fgQAResultDirName.ReplaceAll(fkgLabLocalFile, "") ;
523   fgQAResultFileName.Prepend(fgQAResultDirName) ;
524 }
525
526 //_______________________________________________________________
527 void AliQA::SetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
528 {
529  // Set the status bit for a given detector and a given task
530
531   CheckRange(det) ;
532   CheckRange(tsk) ;
533   CheckRange(bit) ;
534
535   ULong_t offset = Offset(tsk) ;
536   ULong_t status = GetStatus(det) ;
537   offset+= bit ;
538   status = status | 1 << offset ;
539   SetStatus(det, status) ;
540 }
541
542 //_______________________________________________________________
543 void AliQA::ShowAll() const
544 {
545   // dispplay the QA status word
546   Int_t index ;
547   for (index = 0 ; index < kNDET ; index++)
548     ShowStatus(DETECTORINDEX_t(index)) ;
549 }
550
551 //_______________________________________________________________
552 void AliQA::ShowStatus(DETECTORINDEX_t det) const
553 {
554         // Prints the full QA status of a given detector
555         CheckRange(det) ;
556         ULong_t status = GetStatus(det) ;
557         ULong_t tskStatus[kNTASK] ; 
558         tskStatus[kRAW] = status & 0x0000f ;
559         tskStatus[kSIM] = status & 0x000f0 ;
560         tskStatus[kREC] = status & 0x00f00 ;
561         tskStatus[kESD] = status & 0x0f000 ;
562         tskStatus[kANA] = status & 0xf0000 ;
563
564         AliInfo(Form("====> QA Status for %8s raw =0x%x, sim=0x%x, rec=0x%x, esd=0x%x, ana=0x%x", GetDetName(det).Data(), 
565                                  tskStatus[kRAW], tskStatus[kSIM], tskStatus[kREC], tskStatus[kESD], tskStatus[kANA] )) ;
566         for (Int_t tsk = kRAW ; tsk < kNTASK ; tsk++) {
567                 ShowASCIIStatus(det, ALITASK_t(tsk), tskStatus[tsk]) ; 
568         }
569 }
570
571 //_______________________________________________________________
572 void AliQA::ShowASCIIStatus(DETECTORINDEX_t det, ALITASK_t tsk, const ULong_t status) const 
573 {
574         // print the QA status in human readable format
575         TString text; 
576         for (Int_t bit = kINFO ; bit < kNBIT ; bit++) {
577                 if (IsSet(det, tsk, QABIT_t(bit))) {
578                         text = GetBitName(QABIT_t(bit)) ; 
579                         text += " " ; 
580                 }
581         }
582         if (! text.IsNull())
583                 printf("           %8s %4s 0x%4x, Problem signalled: %8s \n", GetDetName(det).Data(), GetAliTaskName(tsk), status, text.Data()) ; 
584 }
585
586 //_______________________________________________________________
587 void AliQA::UnSet(QABIT_t bit)
588 {
589         // UnSet the status bit of the current detector in the current module
590         
591         UnSetStatusBit(fDet, fTask, bit) ;
592 }
593
594 //_______________________________________________________________
595 void AliQA::UnSetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
596 {
597         // UnSet the status bit for a given detector and a given task
598         
599         CheckRange(det) ;
600         CheckRange(tsk) ;
601         CheckRange(bit) ;
602         
603         ULong_t offset = Offset(tsk) ;
604         ULong_t status = GetStatus(det) ;
605         offset+= bit ;
606         status = status & 0 << offset ;
607         SetStatus(det, status) ;
608 }