]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - T0/AliT0QAChecker.cxx
Upadte from Taku
[u/mrichter/AliRoot.git] / T0 / AliT0QAChecker.cxx
index 777277914c24b377d53d80cb7a30d2b7bc9e64dd..5a4b80911a1fd8b7f0399f4590e9fdedc1c3cba8 100644 (file)
  * about the suitability of this software for any purpose. It is          *
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
-
-
-
-
 //...
 //  Checks the quality assurance. 
 //  By comparing with reference data
 //  Skeleton for T0
+//---------------------------------------------
+//checkig without reference data:
+//for RAW QA all histograms should have approximatly the same 
+//number of entries as RefPoint
+//for Rec Points checks 
+//  - amplitude measured by 2 methos
+//  - online and offline T0 measurements
+// for ESD quality of reconstruction ( and measurements):
+// RMS of vertex and T0 less than 75ps
+//
+// Alla.Maevskaya@cern.ch   
 //...
 
 // --- ROOT system ---
 #include <Riostream.h>
 #include <TClass.h>
 #include <TH1F.h> 
-#include <TH1I.h> 
+#include <TF1.h> 
+#include <TFitResultPtr.h>
+#include <TH2.h> 
 #include <TIterator.h> 
 #include <TKey.h> 
 #include <TFile.h> 
 #include <TMath.h>
+#include <TString.h>
+#include <TPaveText.h>
 
 // --- Standard library ---
 
 // --- AliRoot header files ---
 #include "AliLog.h"
-#include "AliQA.h"
+#include "AliQAv1.h"
 #include "AliQAChecker.h"
+#include "AliCDBEntry.h"
+#include "AliQAManager.h"
 #include "AliT0QAChecker.h"
 
 ClassImp(AliT0QAChecker)
+//____________________________________________________________________________
+AliT0QAChecker::AliT0QAChecker() :
+AliQACheckerBase("T0","T0 Quality Assurance Checker")
 
+{
+  // Standard constructor
 
-//__________________________________________________________________
-const Double_t AliT0QAChecker::Check(AliQA::ALITASK_t index,TObjArray * list)
+}
+
+//____________________________________________________________________________
+AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
+  AliQACheckerBase(qac.GetName(), qac.GetTitle()) 
 {
+  // copy constructor
+  AliError("Copy should not be used with this class\n");
+}
+//____________________________________________________________________________
+AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
+  // assignment operator
+  this->~AliT0QAChecker();
+  new(this)AliT0QAChecker(qac);
+  return *this;
+}
+
+
+//____________________________________________________________________________
+AliT0QAChecker::~AliT0QAChecker(){
+  // destructor
+
+}
 
+//__________________________________________________________________
+void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
+{
   // Super-basic check on the QA histograms on the input list:
   // look whether they are empty!
+    
+ char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ; 
+
+  AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
+  //  QARefRec->Dump();
+  if( !QARefRec){
+    AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
+  }
 
-  cout<<" GetAliTaskName "<<AliQA::GetAliTaskName(index)<<" index "<<index<<endl;
+    
+  for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++){ 
+    test[specie]    = 1.0; //FK//  initiate qa flag for the whole set of histograms as good 
+  }
 
 
-  Double_t test = 10.0  ;
-  
-  Int_t count = 0 ;
-  Double_t nent[200], nentraw[200];
-  TString hname[200];
-  const char *cname;
-  memset(nent,0,200*sizeof(Double_t));
-  Double_t w[200];
-  memset(w,1,200*sizeof(Double_t));
-  TH1 *fhRecLEDAmp[24];  TH1 * fhRecQTC[24];
-  TH1 *fhOnlineMean = 0x0;  
-  TH1 * fhRecMean = 0x0;
-  TH1 *fhESDMean = 0x0;
-  TH1 *fhESDVertex = 0x0;
-  TString dataType = AliQA::GetAliTaskName(index);
-
-  if (list->GetEntries() == 0){
-    test = 1. ; // nothing to check
+  for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
+    if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
+      continue;
+    }
+
+    if(index == AliQAv1::kRAW){
+
+      if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){//      if (index == AliQAv1::kRAW )
+        //check laser data efficiencies   
+        Double_t qaFlag = CheckLaser(list[specie]);
+        if(qaFlag < test[specie]) test[specie] = qaFlag;
+      }
+
+      if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib   ||
+         AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
+         AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){ 
+         //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
+         
+        //check BCID   
+        Double_t qaFlag = CheckBCID(list[specie]);
+        if(qaFlag < test[specie]) test[specie] = qaFlag;
+      }
+
+      if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
+        AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){ 
+        //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
+        //check physics 
+        Double_t qaFlag = CheckRaw(list[specie]);
+        if(qaFlag < test[specie]) test[specie] = qaFlag;
+      }
+    }
+
+    if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){
+      test[specie] = CheckESD(list[specie]);
+    } 
   }
-  else {
-    
-    TIter next(list) ;
-    TH1 * hdata ;
-    
-    count = 0 ;
-    while ( (hdata = dynamic_cast<TH1 *>(next())) ) {
-      if (hdata) {
-       nent[count] = hdata->GetEntries();
-       cname = hdata->GetName();
-       hname[count] = cname;
-       AliDebug(10,Form("count %i %s -> %f",count, hname[count].Data(),nent[count])) ;
-                       
-       if(index==2){
-         if(count>23 && count<48)fhRecLEDAmp[count-24] = hdata;
-         if(count>47 && count<72)fhRecQTC[count-48] = hdata;
-         if(count == 72)  fhOnlineMean = hdata; 
-         if(count == 73)  fhRecMean = hdata; 
-       }
-       
-
-       if(index==3){
-         printf(" check ESD count %i \n",count);
-         if(count==0) fhESDMean = hdata;
-         if(count==1) fhESDVertex = hdata;
-         if(count>1){
-           AliWarning("Unknowm ESD QA histograms");
-           return 0;
-         }
-       }
-       count++ ;
-       
-        Double_t rv = 0.;
-        if(hdata->GetEntries()>0) rv = 1;
-       //   AliInfo(Form("%s -> %f", hdata->GetName(), rv)) ;
-        test += rv ;
-       
-     }
-      else{
-        AliError("Data type cannot be processed") ;
+}
+
+//--------------------------------------------------------------------------
+Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
+   
+  TH1 *hdata; 
+  TH1 *fhRawEff[10];
+  Int_t nEffHistos=0;
+
+  //thresholds for warning and error on efficiencies
+  Float_t thrWarning = 0.5; //FK//  warning level
+  Float_t thrError   = 0.2; //FK//  error level
+
+  const int kNumberOfHistos = 3; 
+  Int_t consecutiveHistoNumber[kNumberOfHistos] = { 207, 208, 209};  //Checked histos   fhCDFeff, hEffLED, hEffQTC
+  Int_t qualityFlag[kNumberOfHistos]; //quality flag for a given histogram
+
+  for(Int_t ir=0; ir<kNumberOfHistos; ir++){
+    qualityFlag[ir] = kT0Info; //init quality flag for a given histogram
+
+    hdata = (TH1*) listrec->UncheckedAt(consecutiveHistoNumber[ir]);
+    if(hdata){
+      fhRawEff[nEffHistos] = hdata;
+      nEffHistos++;
+    }
+  }
+     
+  TLine linelowyellow(0, thrWarning, 24, thrWarning);    
+  linelowyellow.SetLineColor(5);
+  linelowyellow.SetLineStyle(3);
+  linelowyellow.SetLineWidth(4);
+  TLine linelowred(0, thrError, 24, thrError);    
+  linelowred.SetLineColor(2);
+  linelowred.SetLineStyle(3);
+  linelowred.SetLineWidth(4);
+
+  Bool_t bEffHistosNotEmpty = kFALSE; //check if all histograms have some counts
+  for(Int_t ih = 0; ih < nEffHistos; ih++){
+     
+    EraseOldMessages((TH1*) fhRawEff[ih]);// clean objects added at previous checks
+    fhRawEff[ih]->SetLineWidth(2);
+    fhRawEff[ih]->SetMaximum(2.);
+    fhRawEff[ih]->SetMinimum(0.);
+    fhRawEff[ih]->GetListOfFunctions()->Add((TLine*)linelowyellow.Clone());
+    fhRawEff[ih]->GetListOfFunctions()->Add((TLine*)linelowred.Clone());
+
+    if(fhRawEff[ih]->Integral()>0) bEffHistosNotEmpty = kTRUE; //this histo does have some counts in it
+
+    Int_t nbins= fhRawEff[ih]->GetNbinsX();
+    for(Int_t ib=1; ib<=nbins; ib++){ //loop over bins and check if the efficiency is above level
+        
+      Float_t chcont = fhRawEff[ih]->GetBinContent(ib);
+      if(chcont < thrWarning && qualityFlag[ih] > kT0Error  ) qualityFlag[ih] = kT0Warning;//Warning level
+      if(chcont < thrError)  qualityFlag[ih] = kT0Error;//Error level
+    }
+   
+    if(qualityFlag[ih] == kT0Info ){
+      AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency  %s  is good", fhRawEff[ih]->GetName() ));
+    }else if(qualityFlag[ih] == kT0Warning){ 
+      AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency  %s  is not so good", fhRawEff[ih]->GetName() ));
+    }else if(qualityFlag[ih] == kT0Error){
+      AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency  %s  is not good", fhRawEff[ih]->GetName() ));
+    }
+  }
+
+  //executive summary
+  int lowestQualityFlag = (int) kT0Info;
+  for(Int_t ih = 0; ih < nEffHistos; ih++){
+
+    if(!bEffHistosNotEmpty){ //all laser efficiency plots are empty
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("1) T0 is in BEAMTUNIG: empty plots are ok")); 
+      text.AddText(Form("2) T0 is in READY: check calibriation trigger")); 
+      text.AddText(Form("if also physics data are empty report"));
+      text.AddText(Form("readout problem to the T0 on-call expert")); 
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      fhRawEff[ih]->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
+    }
+    if( qualityFlag[ih] <lowestQualityFlag )  lowestQualityFlag = qualityFlag[ih];
+  }
+   
+  return ConvertQualityFlagToDouble(lowestQualityFlag); 
+}
+//--------------------------------------------------------------------------
+Double_t AliT0QAChecker::CheckBCID(TObjArray *listrec) const {
+   
+  Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram; 
+
+  TH2F *hBCID = (TH2F*) listrec->UncheckedAt(224); //BCID versus TRM  BCID
+
+     
+  // clean objects added at previous checks
+  EraseOldMessages((TH1*)hBCID);
+
+  if(hBCID->Integral()>0){
+    //BCID does have some counts in it
+
+    Int_t nbinsX = hBCID->GetNbinsX();
+    Int_t nbinsY = hBCID->GetNbinsY();
+    double entriesOnDiagonal  = 0; //count diagonal and off diagonal entries
+    double entriesOffDiagonal = 0;
+    Int_t offset = 37; 
+    Int_t period = 3564; 
+
+    for(Int_t itrm=1; itrm<=nbinsX; itrm++){ //BCID TRM
+      for(Int_t ibcid=1; ibcid<=nbinsY; ibcid++){ //BCID
+        if(TMath::Abs(itrm-ibcid)<6 || TMath::Abs( (itrm+offset)%period - ibcid)<2 ){ 
+           entriesOnDiagonal  += hBCID->GetBinContent(itrm,ibcid); //On  Diagonal
+        }else{
+         entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
+        }
       }
+    }
+    if(entriesOnDiagonal<1 || entriesOffDiagonal>20){
+      qualityFlagBCID = kT0Warning; //no entries on diagonal
+      AliDebug(AliQAv1::GetQADebugLevel(), Form("T0   %s is not diagonal", hBCID->GetName() ));
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("Check if entries are on a diagonal.")); 
+      text.AddText(Form("Report readout problem to the T0 on-call expert")); 
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
+    }
+  }else{ //BCID empty
+
+    qualityFlagBCID = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 :  %s has NO entries", hBCID->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("If T0 is READY report")); 
+    text.AddText(Form("readout problem to the T0 on-call expert"));
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());              
+  }
+
+  //executive summary
+  int lowestQualityFlag = (int) qualityFlagBCID;
+
+  return ConvertQualityFlagToDouble(lowestQualityFlag); 
+  
+}
+
+//--------------------------------------------------------------------------
+Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
+   
+
+  Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram; 
+
+  TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger 
+
+     
+  // clean objects added at previous checks
+  EraseOldMessages((TH1*) hTrigger); 
+
+  if(hTrigger->Integral()>0){
+    //trigger plot does have some counts in it
+    //are Mean, ORA and ORC not empty?  
+    if( hTrigger->GetBinContent(1)<0.001 || hTrigger->GetBinContent(3)<0.001 || hTrigger->GetBinContent(4)<0.001){
+      qualityFlagTrigger = kT0Error; //no entries on diagonal
+      AliDebug(AliQAv1::GetQADebugLevel(), Form("T0: too little ORA and ORC in  %s", hTrigger->GetName() ));
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("Check ORA and ORC")); 
+      text.AddText(Form("Report problem to the T0 on-call expert")); 
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());         
+    }
+
+  }else{ //Trigger histo empty
+
+    qualityFlagTrigger = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hTrigger->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("If T0 is READY report")); 
+    text.AddText(Form("readout problem to the T0 on-call expert")); 
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());           
+
+  }
+
+  //--------- timing plots ---------
+  Int_t qualityFlagMeanBest = kT0Info; //init quality flag for a given histogram;
+  TH1F *hMeanBest    = (TH1F*) listrec->UncheckedAt(223);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hMeanBest); 
+
+  if(hMeanBest->Integral()<1){
+    qualityFlagMeanBest = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMeanBest->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("If T0 is READY and beam is on report")); 
+    text.AddText(Form("the problem to the T0 on-call expert"));
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hMeanBest->GetListOfFunctions()->Add((TPaveText*)text.Clone());          
+  }
+
+
+
+
+  //----------- vetext plots ---------
+
+  Int_t qualityFlagVetrexFirst = kT0Info; //init quality flag for a given histogram;
+  Int_t qualityFlagVetrexBest  = kT0Info; //init quality flag for a given histogram;
+  TH1F *hVertexFirst     = (TH1F*) listrec->UncheckedAt(225);//fhVertex1st
+  TH1F *hVertexBest      = (TH1F*) listrec->UncheckedAt(226);//fhVertexBest
+  TH1F *hOrCminOrATvdcOn = (TH1F*) listrec->UncheckedAt(217);//vertex with TVDC on
+
+  // clean objects added at previous checks
+  EraseOldMessages((TH1*) hVertexFirst); 
+  EraseOldMessages((TH1*) hVertexBest); 
+  float errorLevelDifference   = 400; 
+  float warningLevelDifference = 200; 
+
+  if(hVertexFirst->Integral()>0 && hOrCminOrATvdcOn->Integral()>0){
+    Float_t thr = 0.05 * hVertexFirst->GetBinContent(hVertexFirst->GetMaximumBin());
+     
+    float meanVertexFirst = GetMeanAboveThreshold( hVertexFirst, thr);
+    float meanVertexTVDC  = GetMeanAboveThreshold( hOrCminOrATvdcOn,thr);
+    float diff = TMath::Abs(meanVertexFirst - meanVertexTVDC);
+    if(diff > errorLevelDifference){
+      qualityFlagVetrexFirst = kT0Warning; //init quality flag for a given histogram;
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("large diff. between TVDC vertex")); 
+      text.AddText(Form("and the first vertex."));
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hVertexFirst->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
+
+    }else if(diff > warningLevelDifference){
+      qualityFlagVetrexFirst = kT0Warning; //init quality flag for a given histogram;
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("large diff. between TVDC vertex")); 
+      text.AddText(Form("and the first vertex."));
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hVertexFirst->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
+
+    }
+  }else{
+    qualityFlagVetrexFirst = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertexFirst->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("If T0 is READY and beam is on report")); 
+    text.AddText(Form("the problem to the T0 on-call expert"));
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hVertexFirst->GetListOfFunctions()->Add((TPaveText*)text.Clone());       
+  }
+
+  if(hVertexBest->Integral()>0 && hOrCminOrATvdcOn->Integral()>0){
+
+    Float_t thr = 0.05 * hVertexBest->GetBinContent(hVertexBest->GetMaximumBin());
+    float meanVertexBest  = GetMeanAboveThreshold(hVertexBest,thr);
+    float meanVertexTVDC =  GetMeanAboveThreshold(hOrCminOrATvdcOn,thr);
+    float diff = TMath::Abs(meanVertexBest - meanVertexTVDC);
+    if(diff > errorLevelDifference){
+      qualityFlagVetrexBest = kT0Warning; //init quality flag for a given histogram;
+
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("Large. diff. between TVDC vertex")); 
+      text.AddText(Form("and the best vertex."));
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hVertexBest->GetListOfFunctions()->Add((TPaveText*)text.Clone());              
+
+    }else if(diff > warningLevelDifference){
+      qualityFlagVetrexBest = kT0Warning; //init quality flag for a given histogram;
 
+      TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+      text.AddText(Form("Large. diff. between TVDC vertex")); 
+      text.AddText(Form("and the best vertex."));
+      text.SetBorderSize(0);
+      text.SetFillStyle(0);
+      hVertexBest->GetListOfFunctions()->Add((TPaveText*)text.Clone());              
     }
+  }else{
+    qualityFlagVetrexBest = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertexBest->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("If T0 is READY and beam is on report")); 
+    text.AddText(Form("the problem to the T0 on-call expert"));
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hVertexBest->GetListOfFunctions()->Add((TPaveText*)text.Clone());        
+  }
+
+
+  //executive summary
+  int lowestQualityFlag = (int) qualityFlagTrigger;
+  if(qualityFlagVetrexBest<lowestQualityFlag)  lowestQualityFlag = qualityFlagVetrexBest;
+  if(qualityFlagVetrexFirst<lowestQualityFlag) lowestQualityFlag = qualityFlagVetrexFirst;
+  if(qualityFlagMeanBest <lowestQualityFlag)   lowestQualityFlag = qualityFlagMeanBest; 
+  
+
+  return ConvertQualityFlagToDouble(lowestQualityFlag); 
+  
+}
+
+//--------------------------------------------------------------------------
+Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
+{
+  Float_t checkr = 0;
+  TH1 *fhESD;
+  fhESD  = (TH1*) listrec->UncheckedAt(2);
+  if(fhESD){
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) );
+     TF1 *f1 = new TF1("f1","gaus",-1,1);
+    fhESD->Fit("f1","R","Q", -1,1);
+    Double_t par[3];
+    f1->GetParameters(&par[0]);
     
-    if (count != 0) {
-      if (test==0) {
-        AliWarning("Histograms are there, but they are all empty: setting flag to kWARNING");
-        test = 0.5;  //upper limit value to set kWARNING flag for a task
-      }
-      else {
-
-       if(index == 2){
-         if ( TMath::Abs(fhRecMean->GetMean() - fhOnlineMean->GetMean()) > 5) 
-           AliWarning(Form("rec mean %f -> online mean %f",fhRecMean->GetMean(), fhOnlineMean->GetMean())) ;
-         Double_t meanLED, meanQTC;
-         for (Int_t idet=0; idet<24; idet++) {
-           meanLED = fhRecLEDAmp[idet]->GetMean();
-           meanQTC = fhRecQTC[idet]->GetMean();
-           if (TMath::Abs(meanLED-meanQTC)> 1.) 
-             AliWarning(Form("Amplitude measurements are different in channel %i : Amp LED %f -> Amp QTC %f",idet,meanLED, meanQTC)) ;
+    TPaveText text(0.30,0.50,0.99,0.99,"NDC");
+    
+    text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
+    
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f  #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));
+    
+    
+    if (par[2] > 0.07 && par[2] < 1.) {
+      checkr=0.5;
+       text.AddText(Form("not good resolution :\n %f ns\n", par[2] ));
+       text.SetFillColor(5);
+       printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
+    }
+    if(TMath::Abs(par[1])>0.05) {
+      checkr = 0.5;
+      text.AddText(Form(" Check clock shift on %f ns", par[1]));
+      text.SetFillColor(5);
+    }
+    if (par[2] >  1. || TMath::Abs(par[1])>0.1) {
+      checkr = 0.25;
+      text.AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2]));
+      text.SetFillColor(2);
+      { // RS Clean previous additions
+       TList* lstF = fhESD->GetListOfFunctions();
+       if (lstF) {
+         TObject *stats = lstF->FindObject("stats");
+         lstF->Remove(stats);
+         TObject *obj;
+         while ((obj = lstF->First())) {
+           while(lstF->Remove(obj)) { }
+           delete obj;
          }
-       }       
-        
-       
-       if (index == 0) {
-         Int_t realNumber = Int_t(nent[0]);
-         for (Int_t i=77; i<count; i++) 
-           {
-             Double_t diff = TMath::Abs(nent[i]-realNumber);
-             if (diff > 0.1*realNumber )
-               AliWarning(Form("Problem in Number of entried in hist %s  is %f\n",hname[i].Data() , nent[i])) ; 
-           }
-       }
-       if (index == 3) {
-         Double_t rmsMeanTime = fhESDMean->GetRMS();
-         if (rmsMeanTime>3)            
-           AliWarning(Form("Mean time with bad resolution, RMS= %f",rmsMeanTime)) ; 
-         Double_t rmsVertex = fhESDVertex->GetRMS();
-         if (rmsVertex>3)              
-           AliWarning(Form("Vertex with bad resolution, RMS= %f",rmsVertex)) ; 
-       }
+         if (stats) lstF->Add(stats);
+       } 
       }
-      
+      fhESD->GetListOfFunctions()->Add((TPaveText*)text.Clone());      
+      AliDebug(AliQAv1::GetQADebugLevel(),
+              Form("Please, check calibration: shift= %f resolution %f test=%f\n",
+                   par[1], par[2], checkr) ) ; 
+    }
+  }
+  else
+    {
+      AliDebug(AliQAv1::GetQADebugLevel(),
+              Form("No ESD QA histogram found, nothing to check"));
+       checkr=0;
     }
+  
+  
+  return checkr;
+}
 
 
-  } //  if (list->GetEntries() != 0
-  
-  AliInfo(Form("Test Result = %f", test)) ;
+//--------------------------------------------------------------------------
+void AliT0QAChecker::EraseOldMessages(TH1* h) const 
+{
+  //erase the old captions 
+  TList* lstF = h->GetListOfFunctions();
+  if(lstF){  
+     TObject *stats = lstF->FindObject("stats");
+     lstF->Remove(stats);
+     TObject *obj;
+     while ((obj = lstF->First())) {
+       while(lstF->Remove(obj)) { }
+         delete obj;
+    }
+    if (stats) lstF->Add(stats);
+  }
+}
+//--------------------------------------------------------------------------
+Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const 
+{
+  //covert quality flag to double
+  Double_t checkr=1.0;
 
-  return test ;
+  switch ( qualityFlag ){
+    case kT0Info:
+        checkr = 1.0; break;
+    case kT0Warning:
+        checkr = 0.75; break;
+    case kT0Error:
+          checkr = 0.25; break;
+    case kT0Fatal:
+        checkr = -1.0; break;
+    default:
+         AliError("Invalid ecc value. FIXME !");
+         checkr = 0.25; break;
+  };
+
+  return checkr; 
 }
+//--------------------------------------------------------------------------
+Float_t AliT0QAChecker::GetMeanAboveThreshold(TH1F* hV, Float_t thr) const{
+  //caculate mean value of histo bins above threshold
+  Int_t nBins = hV->GetNbinsX();
+  Int_t nBinsAboveThr = 0; 
+  Float_t sum = 0;
 
+  for(Int_t ib=1;ib<=nBins;ib++){
+    Float_t val = hV->GetBinContent(ib);
+    if(val<thr){
+      sum+=val;
+      nBinsAboveThr++; 
+    }
+  }
+
+  if(nBinsAboveThr>0) return sum/nBinsAboveThr;
+  else return hV->GetMean();
+}