ROOT logo

/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
/* $Id$ */

//////////////////////////////////////////////////////////////////////////////
//
// Quality Assurance Object//_________________________________________________________________________
// Quality Assurance object. The QA status is held in one word per detector,
// each bit corresponds to a different status.
// bit 0-3   : QA raised during simulation      (RAW)
// bit 4-7   : QA raised during simulation      (SIM)
// bit 8-11  : QA raised during reconstruction  (REC)
// bit 12-15 : QA raised during ESD checking    (ESD)
// bit 16-19 : QA raised during analysis        (ANA)
// Each of the 4 bits corresponds to a severity level of increasing importance
// from lower to higher bit (INFO, WARNING, ERROR, FATAL)
//
//*-- Yves Schutz CERN, July 2007 
//////////////////////////////////////////////////////////////////////////////


#include <cstdlib>
// --- ROOT system ---
#include <TClass.h>
#include <TFile.h>
#include <TSystem.h>
#include <TROOT.h>

// --- Standard library ---

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliQA.h"


ClassImp(AliQA)
AliQA    * AliQA::fgQA                   = 0x0 ;
TFile    * AliQA::fgQADataFile           = 0x0 ;   
TString    AliQA::fgQADataFileName       = "QA" ;  // will transform into Det.QA.run.cycle.root  
TFile    * AliQA::fgQARefFile            = 0x0 ;   
TString    AliQA::fgQARefDirName	       = "" ; 
TString    AliQA::fgQARefFileName        = "QA.root" ;
TFile    * AliQA::fgQAResultFile         = 0x0 ;  
TString    AliQA::fgQAResultDirName      = "" ;  
TString    AliQA::fgQAResultFileName     = "QA.root" ; 
TString    AliQA::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
                                            "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR","MFT"};   
TString    AliQA::fgGRPPath              = "GRP/GRP/Data" ; 
TString    AliQA::fgRTNames[]            = {"UNKNOWN", "AUTO_TEST", "CALIBRATION", "CALIBRATION_PULSER", "CHANNEL_DELAY_TUNING", "COSMIC", 
																						"COSMICS", "DAQ_FO_UNIF_SCAN", "DAQ_GEN_DAC_SCAN", "DAQ_MEAN_TH_SCAN", "DAQ_MIN_TH_SCAN", 
																						"DAQ_NOISY_PIX_SCAN", "DAQ_PIX_DELAY_SCAN", "DAQ_UNIFORMITY_SCAN", "DCS_FO_UNIF_SCAN", 
																						"DCS_MEAN_TH_SCAN", "DCS_MIN_TH_SCAN", "DCS_PIX_DELAY_SCAN", "DCS_UNIFORMITY_SCAN", 
																						"DDL_TEST", "GAIN", "PEDESTAL", "INJECTOR",  "LASER", "MONTECARLO", "NOISE", "NOISY_PIX_SCAN", 
																						"PHYSICS", "PULSER", "STANDALONE", "STANDALONE_BC", "STANDALONE_CENTRAL", "STANDALONE_COSMIC", 
																						"STANDALONE_EMD", "STANDALONE_LASER", "STANDALONE_MB", "STANDALONE_PEDESTAL", 
																						"STANDALONE_SEMICENTRAL", "STANDALONE_PULSER" } ;   
TString       AliQA::fgTaskNames[]       = {"Raws", "Hits", "SDigits", "Digits", "RecPoints", "TrackSegments", "RecParticles", "ESDs"} ;   
const TString AliQA::fgkLabLocalFile     = "file://"  ; 
const TString AliQA::fgkLabLocalOCDB     = "local://" ;  
const TString AliQA::fgkLabAliEnOCDB     = "alien://" ;  
const TString AliQA::fgkRefFileName      = "QA.root" ; 
const TString AliQA::fgkQAName           = "QA"  ; 
const TString AliQA::fgkQACorrNtName     = "CorrQA" ;  
const TString AliQA::fgkRefOCDBDirName   = "Ref"  ; 
TString AliQA::fgkRefDataDirName	       = ""  ; 
const TString AliQA::fgkQARefOCDBDefault = "alien://folder=/alice/QA/20"  ; 
const TString AliQA::fgkExpert           = "Expert" ; 
const UInt_t  AliQA::fgkExpertBit        = 16 ; 
const UInt_t  AliQA::fgkQABit            = 17 ; 

//____________________________________________________________________________
AliQA::AliQA() : 
  TNamed("", ""), 
  fNdet(kNDET), 
  fQA(new ULong_t[fNdet]), 
  fDet(kNULLDET),
  fTask(kNULLTASK)
  	
{
  // default constructor
  // beware singleton: not to be used
  
  for (Int_t index = 0 ; index < fNdet ; index++) 
	fQA[index] = 0 ; 
}

//____________________________________________________________________________
AliQA::AliQA(const AliQA& qa) :
  TNamed(qa),
  fNdet(qa.fNdet), 
  fQA(new ULong_t[qa.fNdet]), 
  fDet(qa.fDet),
  fTask(qa.fTask)
{ 
  // cpy ctor
  memcpy(fQA, qa.fQA, sizeof(ULong_t)*fNdet);
}

//_____________________________________________________________________________
AliQA& AliQA::operator = (const AliQA& qa)
{
  //
  // Assignment operator
  if(this != &qa) {
    TNamed::operator=(qa);
    fNdet = qa.fNdet;
    delete [] fQA;
    fQA = new ULong_t[fNdet];
    memcpy(fQA, qa.fQA, sizeof(ULong_t)*fNdet);
    fDet = qa.fDet;
    fTask = qa.fTask;
  }
  return *this;
}

//_______________________________________________________________
AliQA::AliQA(const DETECTORINDEX_t det) :
  TNamed("QA", "Quality Assurance status"),
  fNdet(kNDET),  
  fQA(new ULong_t[fNdet]), 
  fDet(det),
  fTask(kNULLTASK) 
{
  // constructor to be used
  if (! CheckRange(det) ) {
    fDet = kNULLDET ; 
    return ;
  } 
  Int_t index ; 
  for (index = 0; index < fNdet; index++) 
    fQA[index] = 0 ; 
}
  
//_______________________________________________________________
AliQA::AliQA(const ALITASK_t tsk) :
  TNamed("QA", "Quality Assurance status"), 
  fNdet(kNDET),
  fQA(new ULong_t[fNdet]), 
  fDet(kNULLDET),
  fTask(tsk)
{
  // constructor to be used in the AliRoot module (SIM, REC, ESD or ANA)
  if (! CheckRange(tsk) ) {
    fTask = kNULLTASK ; 
    return ;
  } 
  Int_t index ; 
  for (index = 0; index < fNdet; index++) 
    fQA[index] = 0 ; 
}

//____________________________________________________________________________
AliQA::~AliQA() 
{
  // dtor  
  delete[] fQA ;
}

//_______________________________________________________________
void AliQA::Close() 
{
	// close the open files
	if (fgQADataFile) 
		if (fgQADataFile->IsOpen())
			fgQADataFile->Close() ; 
	if (fgQAResultFile) 
		if (fgQAResultFile->IsOpen()) 
			fgQAResultFile->Close() ;
	if (fgQARefFile)
		if (fgQARefFile->IsOpen())
			fgQARefFile->Close() ; 
} 

//_______________________________________________________________
Bool_t AliQA::CheckFatal() const
{
  // check if any FATAL status is set
  Bool_t rv = kFALSE ;
  Int_t index ;
  for (index = 0; index < kNDET ; index++)
    rv = rv || IsSet(DETECTORINDEX_t(index), fTask, kFATAL) ;
  return rv ;
}

//_______________________________________________________________
Bool_t AliQA::CheckRange(DETECTORINDEX_t det) const
{ 
  // check if detector is in given detector range: 0-kNDET

  Bool_t rv = ( det < 0 || det > kNDET )  ? kFALSE : kTRUE ;
  if (!rv)
    AliFatal(Form("Detector index %d is out of range: 0 <= index <= %d", det, kNDET)) ;
  return rv ;
}

//_______________________________________________________________
Bool_t AliQA::CheckRange(ALITASK_t task) const
{ 
  // check if task is given taskk range: 0:kNTASK
  Bool_t rv = ( task < kRAW || task > kNTASK )  ? kFALSE : kTRUE ;
  if (!rv)
    AliFatal(Form("Module index %d is out of range: 0 <= index <= %d", task, kNTASK)) ;
  return rv ;
}

//_______________________________________________________________
Bool_t AliQA::CheckRange(QABIT_t bit) const
{ 
  // check if bit is in given bit range: 0-kNBit

  Bool_t rv = ( bit < 0 || bit > kNBIT )  ? kFALSE : kTRUE ;
  if (!rv)
    AliFatal(Form("Status bit %d is out of range: 0 <= bit <= %d", bit, kNBIT)) ;
  return rv ;
}



//_______________________________________________________________
char * AliQA::GetAliTaskName(ALITASK_t tsk)
{
	// returns the char name corresponding to module index
	TString tskName ;
	switch (tsk) {
		case kNULLTASK:
			break ; 
		case kRAW:
			tskName = "RAW" ;
			break ;  
		case kSIM:
			tskName = "SIM" ;
			break ;
		case kREC:
			tskName = "REC" ;
			break ;
		case kESD:
			tskName = "ESD" ;
			break ;
		case kANA:
			tskName = "ANA" ;
			break ;
		default:
			tsk = kNULLTASK ; 
			break ;
	}
	return Form("%s", tskName.Data()) ;
}

//_______________________________________________________________
char * AliQA::GetBitName(QABIT_t bit) const
{
	// returns the char name corresponding to bit 
	TString bitName ;
	switch (bit) {
		case kNULLBit:
			break ; 
		case kINFO:
			bitName = "INFO" ;
			break ;  
		case kWARNING:
			bitName = "WARNING" ;
			break ;
		case kERROR:
			bitName = "ERROR" ;
			break ;
		case kFATAL:
			bitName = "FATAL" ;
			break ;
		default:
			bit = kNULLBit ; 
			break ;
	}
	return Form("%s", bitName.Data()) ; 
}

//_______________________________________________________________
AliQA::DETECTORINDEX_t AliQA::GetDetIndex(const char * name) 
{
	// returns the detector index corresponding to a given name
	TString sname(name) ; 
	DETECTORINDEX_t rv = kNULLDET ; 
	for (Int_t det = 0; det < kNDET ; det++) {
		if ( GetDetName(det) == sname ) {
			rv = DETECTORINDEX_t(det) ; 
			break ; 
		}
	}
	return rv ; 		
}

//_______________________________________________________________
const char * AliQA::GetDetName(Int_t det) 
{
	// returns the detector name corresponding to a given index (needed in a loop)
	
	if ( det >= 0 &&  det < kNDET) 
		return (fgDetNames[det]).Data() ; 
	else 
		return NULL ; 
}

//_______________________________________________________________
TFile * AliQA::GetQADataFile(const char * name, const Int_t run) 
{
  // opens the file to store the detectors Quality Assurance Data Maker results
	const char * temp = Form("%s.%s.%d.root", name, fgQADataFileName.Data(), run) ; 
	TString opt ; 
	if (! fgQADataFile ) {     
		if  (gSystem->AccessPathName(temp))
			opt = "NEW" ;
		else 
			opt = "UPDATE" ; 
		fgQADataFile = TFile::Open(temp, opt.Data()) ;
	} else {
		if ( strcmp(temp, fgQADataFile->GetName()) != 0 ) {
			fgQADataFile = dynamic_cast<TFile *>(gROOT->FindObject(temp)) ; 
			if ( !fgQADataFile ) {
				if  (gSystem->AccessPathName(temp))
					opt = "NEW" ;
				else 
					opt = "UPDATE" ; 
				fgQADataFile = TFile::Open(temp, opt.Data()) ;
			}
		}
  }
	return fgQADataFile ;
} 

//_____________________________________________________________________________
TFile * AliQA::GetQADataFile(const char * fileName)
{
  // Open if necessary the Data file and return its pointer

  if (!fgQADataFile) 
	if (!fileName) 
		fileName = AliQA::GetQADataFileName() ; 
	if  (!gSystem->AccessPathName(fileName)) {
		fgQADataFile =  TFile::Open(fileName) ;
	} else {
		AliFatalClass(Form("File %s not found", fileName)) ;
	}
  return fgQADataFile ; 
}

//_______________________________________________________________
TFile * AliQA::GetQAResultFile() 
{
  // opens the file to store the  Quality Assurance Data Checker results
	if (fgQAResultFile) 
		fgQAResultFile->Close() ; 
	fgQAResultFile = 0x0 ; 
//	if (!fgQAResultFile) { 
		TString dirName(fgQAResultDirName) ; 
		if ( dirName.Contains(fgkLabLocalFile)) 
			dirName.ReplaceAll(fgkLabLocalFile, "") ;
		TString fileName(dirName + fgQAResultFileName) ; 
		TString opt("") ; 
		if ( !gSystem->AccessPathName(fileName) )
			opt = "UPDATE" ; 
		else { 
			if ( gSystem->AccessPathName(dirName) )
				gSystem->mkdir(dirName) ; 
			opt = "NEW" ; 
		}
		fgQAResultFile = TFile::Open(fileName, opt) ;   
//	}
	
	return fgQAResultFile ;
}

//_______________________________________________________________
const TString AliQA::GetRunTypeName(RUNTYPE_t rt) 
{ 
  // returns the name of a run type
	TString rv("Invalid Run Type") ; 	
	if ( rt == kNULLTYPE ) {
		rv = "Known RUN_TYPE are: \n" ; 
		for (Int_t index = 0 ; index < kNTYPE; index++) {
			rv += Form("%2d -- %s\n", index, fgRTNames[index].Data()) ;  
		}
		AliErrorClass(Form("%s", rv.Data())) ; 
		return "" ; 
	}
	else {
		if ( rt > kNULLTYPE && rt < kNTYPE )
			rv = fgRTNames[rt] ; 
	}
	return rv ; 
}

//_______________________________________________________________
AliQA::TASKINDEX_t AliQA::GetTaskIndex(const char * name) 
{
	// returns the detector index corresponding to a given name
	TString sname(name) ; 
	TASKINDEX_t rv = kNULLTASKINDEX ; 
	for (Int_t tsk = 0; tsk < kNTASKINDEX ; tsk++) {
		if ( GetTaskName(tsk) == sname ) {
			rv = TASKINDEX_t(tsk) ; 
			break ; 
		}
	}
	return rv ; 		
}

//_______________________________________________________________
Bool_t AliQA::IsSet(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit) const
{
  // Checks is the requested bit is set
	
  CheckRange(det) ; 
  CheckRange(tsk) ;
  CheckRange(bit) ;
	
  ULong_t offset = Offset(tsk) ;
  ULong_t status = GetStatus(det) ;
  offset+= bit ;
  status = (status & 1 << offset) != 0 ;
  return status ;
}

//_______________________________________________________________
Bool_t AliQA::IsSetAny(DETECTORINDEX_t det, ALITASK_t tsk) const
{
  // Checks is the requested bit is set
	
  CheckRange(det) ; 
  CheckRange(tsk) ;
	
  ULong_t offset = Offset(tsk) ;
  ULong_t status = GetStatus(det) ;
	UShort_t st = 0 ; 
	for ( Int_t bit = 0 ; bit < kNBIT ; bit++) {
		offset+= bit ;
		st += (status & 1 << offset) != 0 ;		
	}
	if ( st == 0 ) 
		return kFALSE ; 
	else 
		return kTRUE ;
}
//_______________________________________________________________
Bool_t AliQA::IsSetAny(DETECTORINDEX_t det) const
{
  // Checks is the requested bit is set
	
  CheckRange(det) ; 
	
	ULong_t status = GetStatus(det) ;
	UShort_t st = 0 ; 
	for ( Int_t tsk = 0 ; tsk < kNTASK ; tsk++) {
		ULong_t offset = Offset(ALITASK_t(tsk)) ;
		for ( Int_t bit = 0 ; bit < kNBIT ; bit++) {
			offset+= bit ;
			st += (status & 1 << offset) != 0 ;		
		}
	}
	if ( st == 0 ) 
		return kFALSE ; 
	else 
		return kTRUE ;
}

//_______________________________________________________________
AliQA * AliQA::Instance()
{
  // Get an instance of the singleton.
  // Object must have been instantiated with Instance(ALITASK) first

  return fgQA ;
}

//_______________________________________________________________
AliQA * AliQA::Instance(const DETECTORINDEX_t det)
{
  // Get an instance of the singleton. The only authorized way to call the ctor
  
  if ( ! fgQA) {
    TFile * f = GetQAResultFile() ; 
	fgQA = dynamic_cast<AliQA *>(f->Get("QA")) ; 
    if ( ! fgQA ) 
		fgQA = new AliQA(det) ;
  }		
  fgQA->Set(det) ;
  return fgQA ;
}

//_______________________________________________________________
AliQA * AliQA::Instance(const ALITASK_t tsk)
{
  // get an instance of the singleton.

  if ( ! fgQA)
    switch (tsk) {
    case kNULLTASK:
      break ;
	case kRAW:
      fgQA = new AliQA(tsk) ;
      break ;
	case kSIM:
      fgQA = new AliQA(tsk) ;
      break ;
    case kREC:
      AliInfoClass("fgQA = gAlice->GetQA()") ;
      break ;
    case kESD:
      AliInfoClass("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
      break ;
    case kANA:
      AliInfoClass("fgQA = dynamic_cast<AliQA *> (esdFile->Get(\"QA\")") ;
      break ;
    case kNTASK:
      break ;
    }
  if (fgQA) 
    fgQA->Set(tsk) ;
  return fgQA ;
}

//_______________________________________________________________
AliQA *  AliQA::Instance(const TASKINDEX_t tsk) 
{
	// get an instance of the singleton.
	
	ALITASK_t index = kNULLTASK ; 

	if ( tsk == kRAWS )
		index = kRAW ;
	else if (tsk < kDIGITS)
		index = kSIM ;
	else if (tsk < kRECPARTICLES)
		index = kREC ; 
	else if (tsk == kESDS) 
		index = kESD ; 

	return Instance(index) ; 
}

//_______________________________________________________________
Long64_t AliQA::Merge(const TCollection * list) {
  // Merge the QA resuls in the list into this single AliQA object
  
  Long64_t nmerge=0;
  for (Int_t det = 0 ; det < kNDET ; det++) {
    Set(DETECTORINDEX_t(det)) ; 
    for (Int_t task = 0 ; task < kNTASK ; task++) {
      Set(ALITASK_t(task)) ; 
      for (Int_t bit = 0 ; bit < kNBIT ; bit++) {
	TIter next(list) ;
	AliQA * qa ; 
	while ( (qa = (AliQA*)next() ) ) {
	  ++nmerge;
	  qa->IsSet(DETECTORINDEX_t(det), ALITASK_t(task), QABIT_t(bit)) ;
	  Set(QABIT_t(bit)) ; 
	} // qa list
      } // bit
    } // task
  } // detector
  return nmerge;
}

//_______________________________________________________________
ULong_t AliQA::Offset(ALITASK_t tsk) const
{
  // Calculates the bit offset for a given module (SIM, REC, ESD, ANA)

  CheckRange(tsk) ; 

  ULong_t offset = 0 ;
  switch (tsk) {
  case kNULLTASK:
    break ;
  case kRAW:
    offset+= 0 ;
    break ;
  case kSIM:
    offset+= 4 ;
    break ;
  case kREC:
    offset+= 8 ;
    break ;
  case kESD:
    offset+= 12 ;
    break ;
  case kANA:
    offset+= 16 ;
    break ;
  case kNTASK:
    break ;
  }

  return offset ;
}

//_______________________________________________________________
void AliQA::Set(QABIT_t bit)
{
  // Set the status bit of the current detector in the current module
  
  SetStatusBit(fDet, fTask, bit) ;
}

//_____________________________________________________________________________
void AliQA::SetQARefStorage(const char * name)
{
	// Set the root directory where the QA reference data are stored

	fgQARefDirName = name ; 
	if ( fgQARefDirName.Contains(fgkLabLocalFile) )
		fgQARefFileName =  fgkRefFileName ; 
	else if ( fgQARefDirName.Contains(fgkLabLocalOCDB) )
		fgQARefFileName =  fgkQAName ; 
	else if ( fgQARefDirName.Contains(fgkLabAliEnOCDB) )
		fgQARefFileName =  fgkQAName ; 

  else {
	  AliErrorClass(Form("%s is an invalid storage definition\n", name)) ; 
	  fgQARefDirName  = "" ; 
	  fgQARefFileName = "" ; 
  }	
	TString tmp(fgQARefDirName) ; // + fgQARefFileName) ;
	AliInfoClass(Form("AliQA::SetQARefDir: QA references are in  %s\n", tmp.Data()) ) ;
}

//_____________________________________________________________________________
void AliQA::SetQARefDataDirName(const char * name) 
{
  // Set the lower level directory name where reference data are found
  TString test(name) ; 
  RUNTYPE_t rt = kNULLTYPE ; 
  for (Int_t index = 0; index < kNTYPE; index++) {
    if (test.CompareTo(fgRTNames[index]) == 0) {
      rt = (RUNTYPE_t) index ; 
      break ; 
    } 
	}
	
	if (rt == kNULLTYPE) {
      AliWarningClass(Form("AliQA::SetQARefDataDirName: %s is an unknown RUN TYPE name\n", name)) ; 
      return ; 
	}
 
	SetQARefDataDirName(rt) ; 
}

//_____________________________________________________________________________
void AliQA::SetQAResultDirName(const char * name)
{
  // Set the root directory where to store the QA status object

  fgQAResultDirName.Prepend(name) ; 
  AliInfoClass(Form("AliQA::SetQAResultDirName: QA results are in  %s\n", fgQAResultDirName.Data())) ;
  if ( fgQAResultDirName.Contains(fgkLabLocalFile)) 
    fgQAResultDirName.ReplaceAll(fgkLabLocalFile, "") ;
  fgQAResultFileName.Prepend(fgQAResultDirName) ;
}

//_______________________________________________________________
void AliQA::SetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
{
 // Set the status bit for a given detector and a given task

  CheckRange(det) ;
  CheckRange(tsk) ;
  CheckRange(bit) ;

  ULong_t offset = Offset(tsk) ;
  ULong_t status = GetStatus(det) ;
  offset+= bit ;
  status = status | 1 << offset ;
  SetStatus(det, status) ;
}

//_______________________________________________________________
void AliQA::ShowAll() const
{
  // dispplay the QA status word
  Int_t index ;
  for (index = 0 ; index < kNDET ; index++) {
		for (Int_t tsk = kRAW ; tsk < kNTASK ; tsk++) {
			ShowStatus(DETECTORINDEX_t(index), ALITASK_t(tsk)) ;
		}
	}
}

//_______________________________________________________________
void AliQA::ShowStatus(DETECTORINDEX_t det, ALITASK_t tsk) const
{
	// Prints the full QA status of a given detector
	CheckRange(det) ;
	ULong_t status = GetStatus(det) ;
	ULong_t tskStatus[kNTASK] ; 
	tskStatus[kRAW] = status & 0x0000f ;
	tskStatus[kSIM] = status & 0x000f0 ;
	tskStatus[kREC] = status & 0x00f00 ;
	tskStatus[kESD] = status & 0x0f000 ;
	tskStatus[kANA] = status & 0xf0000 ;

	AliInfo(Form("====> QA Status for %8s raw =0x%lx, sim=0x%lx, rec=0x%lx, esd=0x%lx, ana=0x%lx", GetDetName(det).Data(), 
				 tskStatus[kRAW], tskStatus[kSIM], tskStatus[kREC], tskStatus[kESD], tskStatus[kANA] )) ;
	if (tsk == kNULLTASK) {
		for (Int_t itsk = kRAW ; itsk < kNTASK ; itsk++) {
			ShowASCIIStatus(det, ALITASK_t(itsk), tskStatus[itsk]) ; 
		} 
	} else {
			ShowASCIIStatus(det, tsk, tskStatus[tsk]) ; 
	}
}

//_______________________________________________________________
void AliQA::ShowASCIIStatus(DETECTORINDEX_t det, ALITASK_t tsk, const ULong_t status) const 
{
	// print the QA status in human readable format
	TString text; 
	for (Int_t bit = kINFO ; bit < kNBIT ; bit++) {
		if (IsSet(det, tsk, QABIT_t(bit))) {
			text = GetBitName(QABIT_t(bit)) ; 
			text += " " ; 
		}
	}
	if (! text.IsNull())
		AliWarningClass(Form("           %8s %4s 0x%4lx, Problem signalled: %8s \n", GetDetName(det).Data(), GetAliTaskName(tsk), status, text.Data())) ; 
}

//_______________________________________________________________
void AliQA::UnSet(QABIT_t bit)
{
	// UnSet the status bit of the current detector in the current module
	
	UnSetStatusBit(fDet, fTask, bit) ;
}

//_______________________________________________________________
void AliQA::UnSetStatusBit(DETECTORINDEX_t det, ALITASK_t tsk, QABIT_t bit)
{
	// UnSet the status bit for a given detector and a given task
	
	CheckRange(det) ;
	CheckRange(tsk) ;
	CheckRange(bit) ;
	
	ULong_t offset = Offset(tsk) ;
	ULong_t status = GetStatus(det) ;
	offset+= bit ;
	status = status & 0 << offset ;
	SetStatus(det, status) ;
}
 AliQA.cxx:1
 AliQA.cxx:2
 AliQA.cxx:3
 AliQA.cxx:4
 AliQA.cxx:5
 AliQA.cxx:6
 AliQA.cxx:7
 AliQA.cxx:8
 AliQA.cxx:9
 AliQA.cxx:10
 AliQA.cxx:11
 AliQA.cxx:12
 AliQA.cxx:13
 AliQA.cxx:14
 AliQA.cxx:15
 AliQA.cxx:16
 AliQA.cxx:17
 AliQA.cxx:18
 AliQA.cxx:19
 AliQA.cxx:20
 AliQA.cxx:21
 AliQA.cxx:22
 AliQA.cxx:23
 AliQA.cxx:24
 AliQA.cxx:25
 AliQA.cxx:26
 AliQA.cxx:27
 AliQA.cxx:28
 AliQA.cxx:29
 AliQA.cxx:30
 AliQA.cxx:31
 AliQA.cxx:32
 AliQA.cxx:33
 AliQA.cxx:34
 AliQA.cxx:35
 AliQA.cxx:36
 AliQA.cxx:37
 AliQA.cxx:38
 AliQA.cxx:39
 AliQA.cxx:40
 AliQA.cxx:41
 AliQA.cxx:42
 AliQA.cxx:43
 AliQA.cxx:44
 AliQA.cxx:45
 AliQA.cxx:46
 AliQA.cxx:47
 AliQA.cxx:48
 AliQA.cxx:49
 AliQA.cxx:50
 AliQA.cxx:51
 AliQA.cxx:52
 AliQA.cxx:53
 AliQA.cxx:54
 AliQA.cxx:55
 AliQA.cxx:56
 AliQA.cxx:57
 AliQA.cxx:58
 AliQA.cxx:59
 AliQA.cxx:60
 AliQA.cxx:61
 AliQA.cxx:62
 AliQA.cxx:63
 AliQA.cxx:64
 AliQA.cxx:65
 AliQA.cxx:66
 AliQA.cxx:67
 AliQA.cxx:68
 AliQA.cxx:69
 AliQA.cxx:70
 AliQA.cxx:71
 AliQA.cxx:72
 AliQA.cxx:73
 AliQA.cxx:74
 AliQA.cxx:75
 AliQA.cxx:76
 AliQA.cxx:77
 AliQA.cxx:78
 AliQA.cxx:79
 AliQA.cxx:80
 AliQA.cxx:81
 AliQA.cxx:82
 AliQA.cxx:83
 AliQA.cxx:84
 AliQA.cxx:85
 AliQA.cxx:86
 AliQA.cxx:87
 AliQA.cxx:88
 AliQA.cxx:89
 AliQA.cxx:90
 AliQA.cxx:91
 AliQA.cxx:92
 AliQA.cxx:93
 AliQA.cxx:94
 AliQA.cxx:95
 AliQA.cxx:96
 AliQA.cxx:97
 AliQA.cxx:98
 AliQA.cxx:99
 AliQA.cxx:100
 AliQA.cxx:101
 AliQA.cxx:102
 AliQA.cxx:103
 AliQA.cxx:104
 AliQA.cxx:105
 AliQA.cxx:106
 AliQA.cxx:107
 AliQA.cxx:108
 AliQA.cxx:109
 AliQA.cxx:110
 AliQA.cxx:111
 AliQA.cxx:112
 AliQA.cxx:113
 AliQA.cxx:114
 AliQA.cxx:115
 AliQA.cxx:116
 AliQA.cxx:117
 AliQA.cxx:118
 AliQA.cxx:119
 AliQA.cxx:120
 AliQA.cxx:121
 AliQA.cxx:122
 AliQA.cxx:123
 AliQA.cxx:124
 AliQA.cxx:125
 AliQA.cxx:126
 AliQA.cxx:127
 AliQA.cxx:128
 AliQA.cxx:129
 AliQA.cxx:130
 AliQA.cxx:131
 AliQA.cxx:132
 AliQA.cxx:133
 AliQA.cxx:134
 AliQA.cxx:135
 AliQA.cxx:136
 AliQA.cxx:137
 AliQA.cxx:138
 AliQA.cxx:139
 AliQA.cxx:140
 AliQA.cxx:141
 AliQA.cxx:142
 AliQA.cxx:143
 AliQA.cxx:144
 AliQA.cxx:145
 AliQA.cxx:146
 AliQA.cxx:147
 AliQA.cxx:148
 AliQA.cxx:149
 AliQA.cxx:150
 AliQA.cxx:151
 AliQA.cxx:152
 AliQA.cxx:153
 AliQA.cxx:154
 AliQA.cxx:155
 AliQA.cxx:156
 AliQA.cxx:157
 AliQA.cxx:158
 AliQA.cxx:159
 AliQA.cxx:160
 AliQA.cxx:161
 AliQA.cxx:162
 AliQA.cxx:163
 AliQA.cxx:164
 AliQA.cxx:165
 AliQA.cxx:166
 AliQA.cxx:167
 AliQA.cxx:168
 AliQA.cxx:169
 AliQA.cxx:170
 AliQA.cxx:171
 AliQA.cxx:172
 AliQA.cxx:173
 AliQA.cxx:174
 AliQA.cxx:175
 AliQA.cxx:176
 AliQA.cxx:177
 AliQA.cxx:178
 AliQA.cxx:179
 AliQA.cxx:180
 AliQA.cxx:181
 AliQA.cxx:182
 AliQA.cxx:183
 AliQA.cxx:184
 AliQA.cxx:185
 AliQA.cxx:186
 AliQA.cxx:187
 AliQA.cxx:188
 AliQA.cxx:189
 AliQA.cxx:190
 AliQA.cxx:191
 AliQA.cxx:192
 AliQA.cxx:193
 AliQA.cxx:194
 AliQA.cxx:195
 AliQA.cxx:196
 AliQA.cxx:197
 AliQA.cxx:198
 AliQA.cxx:199
 AliQA.cxx:200
 AliQA.cxx:201
 AliQA.cxx:202
 AliQA.cxx:203
 AliQA.cxx:204
 AliQA.cxx:205
 AliQA.cxx:206
 AliQA.cxx:207
 AliQA.cxx:208
 AliQA.cxx:209
 AliQA.cxx:210
 AliQA.cxx:211
 AliQA.cxx:212
 AliQA.cxx:213
 AliQA.cxx:214
 AliQA.cxx:215
 AliQA.cxx:216
 AliQA.cxx:217
 AliQA.cxx:218
 AliQA.cxx:219
 AliQA.cxx:220
 AliQA.cxx:221
 AliQA.cxx:222
 AliQA.cxx:223
 AliQA.cxx:224
 AliQA.cxx:225
 AliQA.cxx:226
 AliQA.cxx:227
 AliQA.cxx:228
 AliQA.cxx:229
 AliQA.cxx:230
 AliQA.cxx:231
 AliQA.cxx:232
 AliQA.cxx:233
 AliQA.cxx:234
 AliQA.cxx:235
 AliQA.cxx:236
 AliQA.cxx:237
 AliQA.cxx:238
 AliQA.cxx:239
 AliQA.cxx:240
 AliQA.cxx:241
 AliQA.cxx:242
 AliQA.cxx:243
 AliQA.cxx:244
 AliQA.cxx:245
 AliQA.cxx:246
 AliQA.cxx:247
 AliQA.cxx:248
 AliQA.cxx:249
 AliQA.cxx:250
 AliQA.cxx:251
 AliQA.cxx:252
 AliQA.cxx:253
 AliQA.cxx:254
 AliQA.cxx:255
 AliQA.cxx:256
 AliQA.cxx:257
 AliQA.cxx:258
 AliQA.cxx:259
 AliQA.cxx:260
 AliQA.cxx:261
 AliQA.cxx:262
 AliQA.cxx:263
 AliQA.cxx:264
 AliQA.cxx:265
 AliQA.cxx:266
 AliQA.cxx:267
 AliQA.cxx:268
 AliQA.cxx:269
 AliQA.cxx:270
 AliQA.cxx:271
 AliQA.cxx:272
 AliQA.cxx:273
 AliQA.cxx:274
 AliQA.cxx:275
 AliQA.cxx:276
 AliQA.cxx:277
 AliQA.cxx:278
 AliQA.cxx:279
 AliQA.cxx:280
 AliQA.cxx:281
 AliQA.cxx:282
 AliQA.cxx:283
 AliQA.cxx:284
 AliQA.cxx:285
 AliQA.cxx:286
 AliQA.cxx:287
 AliQA.cxx:288
 AliQA.cxx:289
 AliQA.cxx:290
 AliQA.cxx:291
 AliQA.cxx:292
 AliQA.cxx:293
 AliQA.cxx:294
 AliQA.cxx:295
 AliQA.cxx:296
 AliQA.cxx:297
 AliQA.cxx:298
 AliQA.cxx:299
 AliQA.cxx:300
 AliQA.cxx:301
 AliQA.cxx:302
 AliQA.cxx:303
 AliQA.cxx:304
 AliQA.cxx:305
 AliQA.cxx:306
 AliQA.cxx:307
 AliQA.cxx:308
 AliQA.cxx:309
 AliQA.cxx:310
 AliQA.cxx:311
 AliQA.cxx:312
 AliQA.cxx:313
 AliQA.cxx:314
 AliQA.cxx:315
 AliQA.cxx:316
 AliQA.cxx:317
 AliQA.cxx:318
 AliQA.cxx:319
 AliQA.cxx:320
 AliQA.cxx:321
 AliQA.cxx:322
 AliQA.cxx:323
 AliQA.cxx:324
 AliQA.cxx:325
 AliQA.cxx:326
 AliQA.cxx:327
 AliQA.cxx:328
 AliQA.cxx:329
 AliQA.cxx:330
 AliQA.cxx:331
 AliQA.cxx:332
 AliQA.cxx:333
 AliQA.cxx:334
 AliQA.cxx:335
 AliQA.cxx:336
 AliQA.cxx:337
 AliQA.cxx:338
 AliQA.cxx:339
 AliQA.cxx:340
 AliQA.cxx:341
 AliQA.cxx:342
 AliQA.cxx:343
 AliQA.cxx:344
 AliQA.cxx:345
 AliQA.cxx:346
 AliQA.cxx:347
 AliQA.cxx:348
 AliQA.cxx:349
 AliQA.cxx:350
 AliQA.cxx:351
 AliQA.cxx:352
 AliQA.cxx:353
 AliQA.cxx:354
 AliQA.cxx:355
 AliQA.cxx:356
 AliQA.cxx:357
 AliQA.cxx:358
 AliQA.cxx:359
 AliQA.cxx:360
 AliQA.cxx:361
 AliQA.cxx:362
 AliQA.cxx:363
 AliQA.cxx:364
 AliQA.cxx:365
 AliQA.cxx:366
 AliQA.cxx:367
 AliQA.cxx:368
 AliQA.cxx:369
 AliQA.cxx:370
 AliQA.cxx:371
 AliQA.cxx:372
 AliQA.cxx:373
 AliQA.cxx:374
 AliQA.cxx:375
 AliQA.cxx:376
 AliQA.cxx:377
 AliQA.cxx:378
 AliQA.cxx:379
 AliQA.cxx:380
 AliQA.cxx:381
 AliQA.cxx:382
 AliQA.cxx:383
 AliQA.cxx:384
 AliQA.cxx:385
 AliQA.cxx:386
 AliQA.cxx:387
 AliQA.cxx:388
 AliQA.cxx:389
 AliQA.cxx:390
 AliQA.cxx:391
 AliQA.cxx:392
 AliQA.cxx:393
 AliQA.cxx:394
 AliQA.cxx:395
 AliQA.cxx:396
 AliQA.cxx:397
 AliQA.cxx:398
 AliQA.cxx:399
 AliQA.cxx:400
 AliQA.cxx:401
 AliQA.cxx:402
 AliQA.cxx:403
 AliQA.cxx:404
 AliQA.cxx:405
 AliQA.cxx:406
 AliQA.cxx:407
 AliQA.cxx:408
 AliQA.cxx:409
 AliQA.cxx:410
 AliQA.cxx:411
 AliQA.cxx:412
 AliQA.cxx:413
 AliQA.cxx:414
 AliQA.cxx:415
 AliQA.cxx:416
 AliQA.cxx:417
 AliQA.cxx:418
 AliQA.cxx:419
 AliQA.cxx:420
 AliQA.cxx:421
 AliQA.cxx:422
 AliQA.cxx:423
 AliQA.cxx:424
 AliQA.cxx:425
 AliQA.cxx:426
 AliQA.cxx:427
 AliQA.cxx:428
 AliQA.cxx:429
 AliQA.cxx:430
 AliQA.cxx:431
 AliQA.cxx:432
 AliQA.cxx:433
 AliQA.cxx:434
 AliQA.cxx:435
 AliQA.cxx:436
 AliQA.cxx:437
 AliQA.cxx:438
 AliQA.cxx:439
 AliQA.cxx:440
 AliQA.cxx:441
 AliQA.cxx:442
 AliQA.cxx:443
 AliQA.cxx:444
 AliQA.cxx:445
 AliQA.cxx:446
 AliQA.cxx:447
 AliQA.cxx:448
 AliQA.cxx:449
 AliQA.cxx:450
 AliQA.cxx:451
 AliQA.cxx:452
 AliQA.cxx:453
 AliQA.cxx:454
 AliQA.cxx:455
 AliQA.cxx:456
 AliQA.cxx:457
 AliQA.cxx:458
 AliQA.cxx:459
 AliQA.cxx:460
 AliQA.cxx:461
 AliQA.cxx:462
 AliQA.cxx:463
 AliQA.cxx:464
 AliQA.cxx:465
 AliQA.cxx:466
 AliQA.cxx:467
 AliQA.cxx:468
 AliQA.cxx:469
 AliQA.cxx:470
 AliQA.cxx:471
 AliQA.cxx:472
 AliQA.cxx:473
 AliQA.cxx:474
 AliQA.cxx:475
 AliQA.cxx:476
 AliQA.cxx:477
 AliQA.cxx:478
 AliQA.cxx:479
 AliQA.cxx:480
 AliQA.cxx:481
 AliQA.cxx:482
 AliQA.cxx:483
 AliQA.cxx:484
 AliQA.cxx:485
 AliQA.cxx:486
 AliQA.cxx:487
 AliQA.cxx:488
 AliQA.cxx:489
 AliQA.cxx:490
 AliQA.cxx:491
 AliQA.cxx:492
 AliQA.cxx:493
 AliQA.cxx:494
 AliQA.cxx:495
 AliQA.cxx:496
 AliQA.cxx:497
 AliQA.cxx:498
 AliQA.cxx:499
 AliQA.cxx:500
 AliQA.cxx:501
 AliQA.cxx:502
 AliQA.cxx:503
 AliQA.cxx:504
 AliQA.cxx:505
 AliQA.cxx:506
 AliQA.cxx:507
 AliQA.cxx:508
 AliQA.cxx:509
 AliQA.cxx:510
 AliQA.cxx:511
 AliQA.cxx:512
 AliQA.cxx:513
 AliQA.cxx:514
 AliQA.cxx:515
 AliQA.cxx:516
 AliQA.cxx:517
 AliQA.cxx:518
 AliQA.cxx:519
 AliQA.cxx:520
 AliQA.cxx:521
 AliQA.cxx:522
 AliQA.cxx:523
 AliQA.cxx:524
 AliQA.cxx:525
 AliQA.cxx:526
 AliQA.cxx:527
 AliQA.cxx:528
 AliQA.cxx:529
 AliQA.cxx:530
 AliQA.cxx:531
 AliQA.cxx:532
 AliQA.cxx:533
 AliQA.cxx:534
 AliQA.cxx:535
 AliQA.cxx:536
 AliQA.cxx:537
 AliQA.cxx:538
 AliQA.cxx:539
 AliQA.cxx:540
 AliQA.cxx:541
 AliQA.cxx:542
 AliQA.cxx:543
 AliQA.cxx:544
 AliQA.cxx:545
 AliQA.cxx:546
 AliQA.cxx:547
 AliQA.cxx:548
 AliQA.cxx:549
 AliQA.cxx:550
 AliQA.cxx:551
 AliQA.cxx:552
 AliQA.cxx:553
 AliQA.cxx:554
 AliQA.cxx:555
 AliQA.cxx:556
 AliQA.cxx:557
 AliQA.cxx:558
 AliQA.cxx:559
 AliQA.cxx:560
 AliQA.cxx:561
 AliQA.cxx:562
 AliQA.cxx:563
 AliQA.cxx:564
 AliQA.cxx:565
 AliQA.cxx:566
 AliQA.cxx:567
 AliQA.cxx:568
 AliQA.cxx:569
 AliQA.cxx:570
 AliQA.cxx:571
 AliQA.cxx:572
 AliQA.cxx:573
 AliQA.cxx:574
 AliQA.cxx:575
 AliQA.cxx:576
 AliQA.cxx:577
 AliQA.cxx:578
 AliQA.cxx:579
 AliQA.cxx:580
 AliQA.cxx:581
 AliQA.cxx:582
 AliQA.cxx:583
 AliQA.cxx:584
 AliQA.cxx:585
 AliQA.cxx:586
 AliQA.cxx:587
 AliQA.cxx:588
 AliQA.cxx:589
 AliQA.cxx:590
 AliQA.cxx:591
 AliQA.cxx:592
 AliQA.cxx:593
 AliQA.cxx:594
 AliQA.cxx:595
 AliQA.cxx:596
 AliQA.cxx:597
 AliQA.cxx:598
 AliQA.cxx:599
 AliQA.cxx:600
 AliQA.cxx:601
 AliQA.cxx:602
 AliQA.cxx:603
 AliQA.cxx:604
 AliQA.cxx:605
 AliQA.cxx:606
 AliQA.cxx:607
 AliQA.cxx:608
 AliQA.cxx:609
 AliQA.cxx:610
 AliQA.cxx:611
 AliQA.cxx:612
 AliQA.cxx:613
 AliQA.cxx:614
 AliQA.cxx:615
 AliQA.cxx:616
 AliQA.cxx:617
 AliQA.cxx:618
 AliQA.cxx:619
 AliQA.cxx:620
 AliQA.cxx:621
 AliQA.cxx:622
 AliQA.cxx:623
 AliQA.cxx:624
 AliQA.cxx:625
 AliQA.cxx:626
 AliQA.cxx:627
 AliQA.cxx:628
 AliQA.cxx:629
 AliQA.cxx:630
 AliQA.cxx:631
 AliQA.cxx:632
 AliQA.cxx:633
 AliQA.cxx:634
 AliQA.cxx:635
 AliQA.cxx:636
 AliQA.cxx:637
 AliQA.cxx:638
 AliQA.cxx:639
 AliQA.cxx:640
 AliQA.cxx:641
 AliQA.cxx:642
 AliQA.cxx:643
 AliQA.cxx:644
 AliQA.cxx:645
 AliQA.cxx:646
 AliQA.cxx:647
 AliQA.cxx:648
 AliQA.cxx:649
 AliQA.cxx:650
 AliQA.cxx:651
 AliQA.cxx:652
 AliQA.cxx:653
 AliQA.cxx:654
 AliQA.cxx:655
 AliQA.cxx:656
 AliQA.cxx:657
 AliQA.cxx:658
 AliQA.cxx:659
 AliQA.cxx:660
 AliQA.cxx:661
 AliQA.cxx:662
 AliQA.cxx:663
 AliQA.cxx:664
 AliQA.cxx:665
 AliQA.cxx:666
 AliQA.cxx:667
 AliQA.cxx:668
 AliQA.cxx:669
 AliQA.cxx:670
 AliQA.cxx:671
 AliQA.cxx:672
 AliQA.cxx:673
 AliQA.cxx:674
 AliQA.cxx:675
 AliQA.cxx:676
 AliQA.cxx:677
 AliQA.cxx:678
 AliQA.cxx:679
 AliQA.cxx:680
 AliQA.cxx:681
 AliQA.cxx:682
 AliQA.cxx:683
 AliQA.cxx:684
 AliQA.cxx:685
 AliQA.cxx:686
 AliQA.cxx:687
 AliQA.cxx:688
 AliQA.cxx:689
 AliQA.cxx:690
 AliQA.cxx:691
 AliQA.cxx:692
 AliQA.cxx:693
 AliQA.cxx:694
 AliQA.cxx:695
 AliQA.cxx:696
 AliQA.cxx:697
 AliQA.cxx:698
 AliQA.cxx:699
 AliQA.cxx:700
 AliQA.cxx:701
 AliQA.cxx:702
 AliQA.cxx:703
 AliQA.cxx:704
 AliQA.cxx:705
 AliQA.cxx:706
 AliQA.cxx:707
 AliQA.cxx:708
 AliQA.cxx:709
 AliQA.cxx:710
 AliQA.cxx:711
 AliQA.cxx:712
 AliQA.cxx:713
 AliQA.cxx:714
 AliQA.cxx:715
 AliQA.cxx:716
 AliQA.cxx:717
 AliQA.cxx:718
 AliQA.cxx:719
 AliQA.cxx:720
 AliQA.cxx:721
 AliQA.cxx:722
 AliQA.cxx:723
 AliQA.cxx:724
 AliQA.cxx:725
 AliQA.cxx:726
 AliQA.cxx:727
 AliQA.cxx:728
 AliQA.cxx:729
 AliQA.cxx:730
 AliQA.cxx:731
 AliQA.cxx:732
 AliQA.cxx:733
 AliQA.cxx:734
 AliQA.cxx:735
 AliQA.cxx:736
 AliQA.cxx:737
 AliQA.cxx:738
 AliQA.cxx:739
 AliQA.cxx:740
 AliQA.cxx:741
 AliQA.cxx:742
 AliQA.cxx:743
 AliQA.cxx:744
 AliQA.cxx:745
 AliQA.cxx:746
 AliQA.cxx:747
 AliQA.cxx:748
 AliQA.cxx:749
 AliQA.cxx:750
 AliQA.cxx:751
 AliQA.cxx:752
 AliQA.cxx:753
 AliQA.cxx:754
 AliQA.cxx:755
 AliQA.cxx:756
 AliQA.cxx:757
 AliQA.cxx:758
 AliQA.cxx:759
 AliQA.cxx:760