]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - T0/AliT0QAChecker.cxx
DQM shifter histos based only on physics data
[u/mrichter/AliRoot.git] / T0 / AliT0QAChecker.cxx
index 5a4b80911a1fd8b7f0399f4590e9fdedc1c3cba8..4e9a01dc572e52adf988ce11dad64825cffcc868 100644 (file)
@@ -1,5 +1,5 @@
 /**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * Coyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  *                                                                        *
  * Author: The ALICE Off-line Project.                                    *
  * Contributors are mentioned in the code where appropriate.              *
@@ -42,6 +42,7 @@
 #include <TMath.h>
 #include <TString.h>
 #include <TPaveText.h>
+#include <TLegend.h>
 
 // --- Standard library ---
 
 #include "AliCDBEntry.h"
 #include "AliQAManager.h"
 #include "AliT0QAChecker.h"
+#include "AliQAThresholds.h"
+#include "AliDAQ.h"
 
 ClassImp(AliT0QAChecker)
 //____________________________________________________________________________
 AliT0QAChecker::AliT0QAChecker() :
-AliQACheckerBase("T0","T0 Quality Assurance Checker")
-
+  AliQACheckerBase("T0","T0 Quality Assurance Checker"),
+  fCFDErrorThreshold(0),
+  fLEDErrorThreshold(0),
+  fQTCErrorThreshold(0),
+  fRatioCFDEffLEDEffErrorThreshold(1),
+  fQTCEfficiencyErrorThreshold(0),
+  fBCIDPeriodParam(3564),
+  fBCIDOffsetParam(37),
+  fBCIDBandWidthParam(10),
+  fTZeroAPlusCErrorThreshold(2000.0),
+  fTZeroAMinusCErrorThreshold(2000.0)
 {
   // Standard constructor
+  for(Int_t i=0; i<24; i++){ 
+    fMeanCFDFromGoodRunParam[i]=0; 
+    fMeanLEDFromGoodRunParam[i]=0; 
+    fMeanQTCFromGoodRunParam[i]=0; 
+  }
 
 }
 
 //____________________________________________________________________________
 AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
-  AliQACheckerBase(qac.GetName(), qac.GetTitle()) 
+  AliQACheckerBase(qac.GetName(), qac.GetTitle()),
+  fCFDErrorThreshold(qac.fCFDErrorThreshold),
+  fLEDErrorThreshold(qac.fLEDErrorThreshold),
+  fQTCErrorThreshold(qac.fQTCErrorThreshold),
+  fRatioCFDEffLEDEffErrorThreshold(qac.fRatioCFDEffLEDEffErrorThreshold),
+  fQTCEfficiencyErrorThreshold(qac.fQTCEfficiencyErrorThreshold),
+  fBCIDPeriodParam(qac.fBCIDPeriodParam),
+  fBCIDOffsetParam(qac.fBCIDOffsetParam),
+  fBCIDBandWidthParam(qac.fBCIDBandWidthParam),
+  fTZeroAPlusCErrorThreshold(qac.fTZeroAPlusCErrorThreshold),
+  fTZeroAMinusCErrorThreshold(qac.fTZeroAMinusCErrorThreshold)
 {
   // copy constructor
   AliError("Copy should not be used with this class\n");
+  for(Int_t i=0; i<24; i++){ 
+    fMeanCFDFromGoodRunParam[i]=qac.fMeanCFDFromGoodRunParam[i]; 
+    fMeanLEDFromGoodRunParam[i]=qac.fMeanLEDFromGoodRunParam[i]; 
+    fMeanQTCFromGoodRunParam[i]=qac.fMeanQTCFromGoodRunParam[i]; 
+  }
+
 }
 //____________________________________________________________________________
 AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
@@ -88,10 +121,91 @@ AliT0QAChecker::~AliT0QAChecker(){
 //__________________________________________________________________
 void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
 {
+
+  AliCDBManager* man = AliCDBManager::Instance();
+  //man->SetDefaultStorage(gSystem->Getenv("AMORE_CDB_URI"));
+  if(!man) return; 
+  AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
+  TObjArray* t0branch = (TObjArray*) entry->GetObject();
+  if(!list) return;
+  AliQAThresholds*  thresholds = (AliQAThresholds*) t0branch->FindObject("T00");
+  // here you should test that you got a non-null pointer
+
+  if(!thresholds) return;
+  cout << "******************* thresholds : " << thresholds << endl;
+  if(AliDAQ::DetectorID("T0")!= thresholds->GetDetectorId()){
+    AliInfo(Form("DETECTOR ID %d DOES NOT MATCH TO TZERO",thresholds->GetDetectorId()));
+    return;
+  }
+
+  int iparam; 
+  for(int ipmt=0; ipmt<24;ipmt++){ 
+    iparam = ipmt + 1; //current consecutive number of parameter
+    if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean CFD from a good run 
+      fMeanCFDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+    }
+
+    iparam = ipmt + 25;
+    if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean LED from a good run 
+      fMeanLEDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+    } 
+    iparam = ipmt + 49;
+    if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean QTC from a good run 
+      fMeanQTCFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+    } 
+  }
+  iparam = 73; //CFD threshold
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fCFDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+  iparam = 74; //LED threshold
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fLEDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+  iparam = 75; //QTC threshold
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fQTCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+  iparam = 82; //Error level threshold on CFD efficiency/LED efficiency ratio
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fRatioCFDEffLEDEffErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
   // 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()) ; 
+
+  iparam = 83; //Error level threshold on QTC efficiency 
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fQTCEfficiencyErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+  iparam = 84; 
+  if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
+    fBCIDPeriodParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+  iparam = 85; 
+  if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
+    fBCIDOffsetParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+  iparam = 86; 
+  if((TParameter<int>*) thresholds->GetThreshold(iparam)){ 
+    fBCIDBandWidthParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+  iparam = 87; 
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fTZeroAPlusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+  iparam = 88; 
+  if((TParameter<float>*) thresholds->GetThreshold(iparam)){ 
+    fTZeroAMinusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
+  }
+
+
+  char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ; 
 
   AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
   //  QARefRec->Dump();
@@ -112,21 +226,21 @@ void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray
 
     if(index == AliQAv1::kRAW){
 
-      if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){//      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;
-      }
+      //  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){ 
+      //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;
-      }
+      //  Double_t qaFlag = CheckBCID(list[specie]);
+      //  if(qaFlag < test[specie]) test[specie] = qaFlag;
+      //}
 
       if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
         AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){ 
@@ -144,162 +258,149 @@ void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray
 }
 
 //--------------------------------------------------------------------------
-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++){
+//Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
+//   
+//  return 1.0; 
+//}
 
-    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 {
+Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
    
-  Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram; 
+  //Fk Set drawing options for LED and CFD efficiencies from the raw data
+  TH1F *hCFDEffData = (TH1F*) listrec->UncheckedAt(207);//hRawTrigger 
+  TH1F *hLEDEffData = (TH1F*) listrec->UncheckedAt(208);//hRawTrigger 
 
-  TH2F *hBCID = (TH2F*) listrec->UncheckedAt(224); //BCID versus TRM  BCID
+  //clean objects added at previous checks
+  EraseOldMessages((TH1*) hCFDEffData); 
+  hCFDEffData->GetListOfFunctions()->Add((TH1D*) hLEDEffData->Clone());              
 
-     
-  // clean objects added at previous checks
-  EraseOldMessages((TH1*)hBCID);
+  TLegend leg(0.12,0.76,0.9,0.92," ","brNDC");
+  leg.SetFillStyle(0); leg.SetBorderSize(0); leg.SetTextSize(0.04); leg.SetNColumns(2);
+  leg.AddEntry((TH1D*) hCFDEffData,"CFD","p");
+  leg.AddEntry((TH1D*) hLEDEffData,"LED","p");
+  hCFDEffData->GetListOfFunctions()->Add((TLegend*) leg.Clone());            
 
-  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; 
+  //Fk Draw CFD-mean for each PMT
+  TH2F* fhCFD = (TH2F*) listrec->UncheckedAt(210);
+  TH1F* fhCFDSubtrMean = (TH1F*) listrec->UncheckedAt(231);
 
-    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() ));
+  EraseOldMessages((TH1*) fhCFDSubtrMean); 
+  for(int ipmt=0; ipmt<24;ipmt++){ 
+    TH1F*  hProjDummy = (TH1F*) fhCFD->ProjectionY("dummy",ipmt+1,ipmt+1);
+    Float_t mean=0.0, rms=0.0;
+    GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,0);
 
-      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
+    Float_t deviation = mean - fMeanCFDFromGoodRunParam[ipmt]; 
 
-    qualityFlagBCID = kT0Error;
-    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 :  %s has NO entries", hBCID->GetName() ));
+    fhCFDSubtrMean->SetBinContent(ipmt+1,deviation);
+    fhCFDSubtrMean->SetBinError(ipmt+1,rms);
+      
+    delete hProjDummy;
+  }
+  TLine linelowredCFD(0, fCFDErrorThreshold, 24, fCFDErrorThreshold);    
+  linelowredCFD.SetLineColor(2);
+  linelowredCFD.SetLineStyle(3);
+  linelowredCFD.SetLineWidth(4);
+  TLine linehighredCFD(0, -fCFDErrorThreshold, 24, -fCFDErrorThreshold);    
+  linehighredCFD.SetLineColor(2);
+  linehighredCFD.SetLineStyle(3);
+  linehighredCFD.SetLineWidth(4);
+  fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredCFD.Clone());         
+  fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredCFD.Clone());        
 
-    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());              
+  //Fk Draw LED-mean for each PMT
+  TH2F* fhLED = (TH2F*) listrec->UncheckedAt(211);
+  TH1F* fhLEDSubtrMean = (TH1F*) listrec->UncheckedAt(232);
+  EraseOldMessages((TH1*) fhLEDSubtrMean); 
+  for(int ipmt=0; ipmt<24;ipmt++){ 
+    TH1F*  hProjDummy = (TH1F*) fhLED->ProjectionY("dummy",ipmt+1,ipmt+1);
+    Float_t mean=0.0, rms=0.0;
+    GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,1);
+    Float_t deviation = mean - fMeanLEDFromGoodRunParam[ipmt]; 
+
+    fhLEDSubtrMean->SetBinContent(ipmt+1,deviation);
+    fhLEDSubtrMean->SetBinError(ipmt+1,rms);
+      
+    delete hProjDummy;
   }
+  TLine linelowredLED(0, fLEDErrorThreshold, 24, fLEDErrorThreshold);    
+  linelowredLED.SetLineColor(2);
+  linelowredLED.SetLineStyle(3);
+  linelowredLED.SetLineWidth(4);
+  TLine linehighredLED(0, -fLEDErrorThreshold, 24, -fLEDErrorThreshold);    
+  linehighredLED.SetLineColor(2);
+  linehighredLED.SetLineStyle(3);
+  linehighredLED.SetLineWidth(4);
+  fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredLED.Clone());         
+  fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredLED.Clone());        
 
-  //executive summary
-  int lowestQualityFlag = (int) qualityFlagBCID;
+     
+  //Fk Draw QTC-mean for each PMT
+  TH2F* fhQTC = (TH2F*) listrec->UncheckedAt(212);
+  TH1F* fhQTCSubtrMean = (TH1F*) listrec->UncheckedAt(233);
+   
+  EraseOldMessages((TH1*) fhQTCSubtrMean); 
+  for(int ipmt=0; ipmt<24;ipmt++){ 
+    TH1F*  hProjDummy = (TH1F*) fhQTC->ProjectionY("dummy",ipmt+1,ipmt+1);
+    Float_t mean=0.0, rms=0.0;
+    GetMeanAndRmsAroundMainMaximum(mean, rms,  hProjDummy,2);
+    Float_t deviation = mean - fMeanQTCFromGoodRunParam[ipmt]; 
+
+    fhQTCSubtrMean->SetBinContent(ipmt+1,deviation);
+    fhQTCSubtrMean->SetBinError(ipmt+1,rms);
+      
+    delete hProjDummy;
+  }
+  TLine linelowredQTC(0, fQTCErrorThreshold, 24, fQTCErrorThreshold);    
+  linelowredQTC.SetLineColor(2);
+  linelowredQTC.SetLineStyle(3);
+  linelowredQTC.SetLineWidth(4);
+  TLine linehighredQTC(0, -fQTCErrorThreshold, 24, -fQTCErrorThreshold);    
+  linehighredQTC.SetLineColor(2);
+  linehighredQTC.SetLineStyle(3);
+  linehighredQTC.SetLineWidth(4);
+  fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredQTC.Clone());         
+  fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredQTC.Clone());        
+
+  //CFD and LED efficiency in range ~2000- ~3000 
+  TH1F* hCFDeffSubRange = (TH1F*) listrec->UncheckedAt(237);
+  TH1F* hEffLEDSubRange = (TH1F*) listrec->UncheckedAt(238);
+  // ratio CDF eff /LEF eff in subragne 
+  TH1F* hRatioCFDLEDeff = (TH1F*) listrec->UncheckedAt(239);//FK   
+  EraseOldMessages((TH1*) hRatioCFDLEDeff); 
+  int npmt = hRatioCFDLEDeff->GetNbinsX();
+  for(int ipmt=1;ipmt<=npmt;ipmt++){
+    Float_t c0 = hCFDeffSubRange->GetBinContent(ipmt); 
+    Float_t c1 = hEffLEDSubRange->GetBinContent(ipmt);
+    if(c1){
+      hRatioCFDLEDeff->SetBinContent(ipmt,c0/c1);  
+    }else{
+      hRatioCFDLEDeff->SetBinContent(ipmt,0);  
+    }  
+  }
 
-  return ConvertQualityFlagToDouble(lowestQualityFlag); 
-  
-}
+  TLine linelowredRatioCFDLEDeff(0, 1+fRatioCFDEffLEDEffErrorThreshold, 24, 1+fRatioCFDEffLEDEffErrorThreshold);    
+  linelowredRatioCFDLEDeff.SetLineColor(2);
+  linelowredRatioCFDLEDeff.SetLineStyle(3);
+  linelowredRatioCFDLEDeff.SetLineWidth(4);
+  TLine linehighredRatioCFDLEDeff(0, 1-fRatioCFDEffLEDEffErrorThreshold, 24, 1-fRatioCFDEffLEDEffErrorThreshold);    
+  linehighredRatioCFDLEDeff.SetLineColor(2);
+  linehighredRatioCFDLEDeff.SetLineStyle(3);
+  linehighredRatioCFDLEDeff.SetLineWidth(4);
+  hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linelowredRatioCFDLEDeff.Clone());             
+  hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linehighredRatioCFDLEDeff.Clone());            
 
-//--------------------------------------------------------------------------
-Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
-   
+  //        PERFROM CHECKS on HISTOGRAMS
 
+  //-------- triggers -----------
   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); 
 
@@ -332,73 +433,134 @@ Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
     hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());           
 
   }
+  //---------- CFD eff/LED eff within subrange  -----------
+  Int_t qualityFlagRatioCFDeffLEDeff = kT0Info; //init quality flag for a given histogram;
+  int nPMTs = hRatioCFDLEDeff->GetNbinsX(); 
 
-  //--------- 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() ));
-
+  for(int ipmt=1; ipmt<=nPMTs; ipmt++){
+    if(TMath::Abs( hRatioCFDLEDeff->GetBinContent(ipmt) -1) > fRatioCFDEffLEDEffErrorThreshold){ //mean is expected to be around 1
+      qualityFlagRatioCFDeffLEDeff = kT0Error;
+    }
+  }
+  if(qualityFlagRatioCFDeffLEDeff == kT0Error){
     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
-    text.AddText(Form("NO ENTRIES!!!")); 
+    text.AddText(Form("Problem with efficiency ratio CFD/LED !!!")); 
     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());          
+    hRatioCFDLEDeff->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
   }
+  
 
+  //---------- CFD -  mean CFD  -----------
+  Int_t qualityFlagCFDSubtr = kT0Info; //init quality flag for a given histogram;
+  nPMTs = fhCFDSubtrMean->GetNbinsX(); 
 
+  for(int ipmt=1; ipmt<=nPMTs; ipmt++){
+    if(TMath::Abs( fhCFDSubtrMean->GetBinContent(ipmt)) > fCFDErrorThreshold){
+      qualityFlagCFDSubtr = kT0Error;
 
+   }
+  }
+  if(qualityFlagCFDSubtr == kT0Error){
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("Problem with CFD timing  !!!")); 
+    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);
+    fhCFDSubtrMean->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
+  }
+  //--------- QTC efficiency ---------------
 
-  //----------- vetext plots ---------
+  Int_t qualityFlagEffQTC = kT0Info; //init quality flag for a given histogram;
+  TH1F *hEffQTC = (TH1F*) listrec->UncheckedAt(209);//hRawTrigger 
+  
+  EraseOldMessages((TH1*) hEffQTC); // clean objects added at previous checks
 
-  Int_t qualityFlagVetrexFirst = kT0Info; //init quality flag for a given histogram;
-  Int_t qualityFlagVetrexBest  = kT0Info; //init quality flag for a given histogram;
+  nPMTs = hEffQTC->GetNbinsX(); 
+  for(int ipmt=1; ipmt<=nPMTs; ipmt++){
+    if(TMath::Abs( hEffQTC->GetBinContent(ipmt)) < fQTCEfficiencyErrorThreshold){
+      qualityFlagEffQTC = kT0Error;
+    }
+  }
+  if( qualityFlagEffQTC == kT0Error){
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("Problem with QTC efficiency !!!")); 
+    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);
+    hEffQTC->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
+  }
+  TLine linehighredQTCeff(0, fQTCEfficiencyErrorThreshold, 24, fQTCEfficiencyErrorThreshold);    
+  linehighredQTCeff.SetLineColor(2);
+  linehighredQTCeff.SetLineStyle(3);
+  linehighredQTCeff.SetLineWidth(4);
+  hEffQTC->GetListOfFunctions()->Add((TLine*) linehighredQTCeff.Clone());            
  
-  TH1F *hVertexFirst     = (TH1F*) listrec->UncheckedAt(225);//fhVertex1st
-  TH1F *hVertexBest      = (TH1F*) listrec->UncheckedAt(226);//fhVertexBest
-  TH1F *hOrCminOrATvdcOn = (TH1F*) listrec->UncheckedAt(217);//vertex with TVDC on
-
+  //---------- BCID --------------------
+  Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram; 
+  TH2F *hBCID = (TH2F*) listrec->UncheckedAt(236); //BCID versus TRM  BCID
+     
   // clean objects added at previous checks
-  EraseOldMessages((TH1*) hVertexFirst); 
-  EraseOldMessages((TH1*) hVertexBest); 
-  float errorLevelDifference   = 400; 
-  float warningLevelDifference = 200; 
+  EraseOldMessages((TH1*)hBCID);
 
-  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;
+  if(hBCID->Integral()>0){
+    //BCID does have some counts in it
 
-      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());             
+    Int_t nbinsX = hBCID->GetNbinsX();
+    Int_t startX = hBCID->GetXaxis()->FindBin(100); //skip region close to orbit period
+    Int_t nbinsY = hBCID->GetNbinsY();
+    Int_t binWidthX = (Int_t) hBCID->GetXaxis()->GetBinWidth(1);
+    Int_t binWidthY = (Int_t) hBCID->GetYaxis()->GetBinWidth(1);
+    double entriesOnDiagonal  = 0; //count diagonal and off diagonal entries
+    double entriesOffDiagonal = 0;
 
-    }else if(diff > warningLevelDifference){
-      qualityFlagVetrexFirst = kT0Warning; //init quality flag for a given histogram;
+    for(Int_t itrm=startX; itrm<=nbinsX; itrm++){ //BCID TRM
+      for(Int_t ibcid=1; ibcid<=nbinsY; ibcid++){ //BCID
+        if(TMath::Abs( (itrm*binWidthX - fBCIDOffsetParam) % fBCIDPeriodParam - binWidthY*ibcid) < fBCIDBandWidthParam ){ 
+          entriesOnDiagonal  += hBCID->GetBinContent(itrm,ibcid); //On  Diagonal
+          //hBCID->Fill(itrm*binWidthX,ibcid*binWidthY,0.001); // visualize the diagonal belt
+        }else{
+          entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
+        }
+      }
+    }
+    if(entriesOnDiagonal<1 || entriesOffDiagonal>20){
+      qualityFlagBCID = kT0Error; //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("large diff. between TVDC vertex")); 
-      text.AddText(Form("and the first vertex."));
+      text.AddText(Form("Check if entries are on diagonal")); 
+      text.AddText(Form("Report readout problem to the T0 on-call expert")); 
       text.SetBorderSize(0);
       text.SetFillStyle(0);
-      hVertexFirst->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
-
+      hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
     }
-  }else{
-    qualityFlagVetrexFirst = kT0Error;
-    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertexFirst->GetName() ));
+  }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());              
+  }
+
+  //--------- mean versus vertex 1st ---------
+  Int_t qualityFlagMeanVersusVertex1st = kT0Info; //init quality flag for a given histogram;
+  TH2F *hMeanVersusVertex1st  = (TH2F*) listrec->UncheckedAt(220);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hMeanVersusVertex1st); 
+  if(hMeanVersusVertex1st->Integral()<1){
+    qualityFlagMeanVersusVertex1st = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMeanVersusVertex1st->GetName() ));
 
     TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
     text.AddText(Form("NO ENTRIES!!!")); 
@@ -406,54 +568,120 @@ Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
     text.AddText(Form("the problem to the T0 on-call expert"));
     text.SetBorderSize(0);
     text.SetFillStyle(0);
-    hVertexFirst->GetListOfFunctions()->Add((TPaveText*)text.Clone());       
+    hMeanVersusVertex1st->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;
+  //--------- vertex TVDC on ---------
+  Int_t qualityFlagVertex1stTVDCon = kT0Info; //init quality flag for a given histogram;
+  TH1F *hVertex1stTVDCon  = (TH1F*) listrec->UncheckedAt(223);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hVertex1stTVDCon); 
+  if(hVertex1stTVDCon->Integral()<1){
+    qualityFlagVertex1stTVDCon = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertex1stTVDCon->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);
+    hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());           
+  }else{
+    if(TMath::Abs(hVertex1stTVDCon->GetMean()) > fTZeroAMinusCErrorThreshold){ 
+      qualityFlagVertex1stTVDCon = kT0Error;
 
       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.AddText(Form("Displaced vertex")); 
+      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());              
+      hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());         
+    }
+  }
+
+  //--------- vertex TVDC off ---------
+  Int_t qualityFlagVertex1stTVDCoff = kT0Info; //init quality flag for a given histogram;
+  TH1F *hVertex1stTVDCoff  = (TH1F*) listrec->UncheckedAt(225);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hVertex1stTVDCoff); 
+  if(hVertex1stTVDCoff->Integral()<1){
+    qualityFlagVertex1stTVDCoff = kT0Warning;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertex1stTVDCoff->GetName() ));
+
+    TPaveText text(0.20,0.50,0.99,0.99,"NDC");   
+    text.AddText(Form("Warning: NO ENTRIES")); 
+    text.SetBorderSize(0);
+    text.SetFillStyle(0);
+    hVertex1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());          
+  }
+
 
-    }else if(diff > warningLevelDifference){
-      qualityFlagVetrexBest = kT0Warning; //init quality flag for a given histogram;
+
+  //----------- time TVDC on ---------
+    
+  Int_t qualityFlagMean1stTVDCon = kT0Info; //init quality flag for a given histogram;
+  TH1F *hMean1stTVDCon  = (TH1F*) listrec->UncheckedAt(226);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hMean1stTVDCon); 
+  if(hMean1stTVDCon->Integral()<1){
+    qualityFlagMean1stTVDCon = kT0Error;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMean1stTVDCon->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);
+    hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());             
+  }else{
+    //cout<<"Mean: "<<TMath::Abs(hMean1stTVDCon->GetMean())<<" threshold "<<fTZeroAPlusCErrorThreshold<<endl;
+    if(TMath::Abs(hMean1stTVDCon->GetMean()) > fTZeroAPlusCErrorThreshold){ 
+      qualityFlagMean1stTVDCon = kT0Error;
 
       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.AddText(Form("Shift of mean time")); 
+      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());              
+      hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());           
     }
-  }else{
-    qualityFlagVetrexBest = kT0Error;
-    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hVertexBest->GetName() ));
+  }
+
+  //----------- time TVDC off ---------
+    
+  Int_t qualityFlagMean1stTVDCoff = kT0Info; //init quality flag for a given histogram;
+  TH1F *hMean1stTVDCoff  = (TH1F*) listrec->UncheckedAt(227);  //fhMeanBest  time
+  EraseOldMessages((TH1*) hMean1stTVDCoff); 
+  if(hMean1stTVDCoff->Integral()<1){
+    qualityFlagMean1stTVDCoff = kT0Warning;
+    AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram  %s has NO entries", hMean1stTVDCoff->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.AddText(Form("Warning: NO ENTRIES")); 
     text.SetBorderSize(0);
     text.SetFillStyle(0);
-    hVertexBest->GetListOfFunctions()->Add((TPaveText*)text.Clone());        
+    hMean1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());            
   }
 
 
-  //executive summary
+  //----------------------- executive summary ---------------------
   int lowestQualityFlag = (int) qualityFlagTrigger;
-  if(qualityFlagVetrexBest<lowestQualityFlag)  lowestQualityFlag = qualityFlagVetrexBest;
-  if(qualityFlagVetrexFirst<lowestQualityFlag) lowestQualityFlag = qualityFlagVetrexFirst;
-  if(qualityFlagMeanBest <lowestQualityFlag)   lowestQualityFlag = qualityFlagMeanBest; 
+  if(qualityFlagRatioCFDeffLEDeff   < lowestQualityFlag)  lowestQualityFlag = qualityFlagRatioCFDeffLEDeff;
+  if(qualityFlagCFDSubtr            < lowestQualityFlag)  lowestQualityFlag = qualityFlagCFDSubtr;
+  if(qualityFlagEffQTC              < lowestQualityFlag)  lowestQualityFlag = qualityFlagEffQTC;
+  if(qualityFlagMeanVersusVertex1st < lowestQualityFlag)  lowestQualityFlag = qualityFlagMeanVersusVertex1st;
+  if(qualityFlagBCID                < lowestQualityFlag)  lowestQualityFlag = qualityFlagBCID;
+  if(qualityFlagVertex1stTVDCon     < lowestQualityFlag)  lowestQualityFlag = qualityFlagVertex1stTVDCon;
+  if(qualityFlagVertex1stTVDCoff    < lowestQualityFlag)  lowestQualityFlag = qualityFlagVertex1stTVDCoff;
+  if(qualityFlagMean1stTVDCon       < lowestQualityFlag)  lowestQualityFlag = qualityFlagMean1stTVDCon;
+  if(qualityFlagMean1stTVDCoff      < lowestQualityFlag)  lowestQualityFlag = qualityFlagMean1stTVDCoff;
   
 
   return ConvertQualityFlagToDouble(lowestQualityFlag); 
@@ -584,3 +812,72 @@ Float_t AliT0QAChecker::GetMeanAboveThreshold(TH1F* hV, Float_t thr) const{
   if(nBinsAboveThr>0) return sum/nBinsAboveThr;
   else return hV->GetMean();
 }
+    
+//--------------------------------------------------------------------------
+void AliT0QAChecker::GetMeanAndRmsAroundMainMaximum(Float_t &meanHisto,Float_t &rmsHisto, TH1F *histo, int type) const{
+
+  if(!histo){
+    meanHisto=0.0;
+    rmsHisto=0.0;
+    return;
+  }
+  if(histo->Integral()<0.00001){
+    meanHisto=0.0;
+    rmsHisto=0.0;
+    return;
+  }
+
+  double nSigma      = 3.0; //n sigma window around mean and main maximum 
+  double expectedRMS = 13.0; // expected rms of the main peak in case of CFD
+  if(type == 1) expectedRMS = 34.0; //LED
+  if(type == 2) expectedRMS = 34.0; //QTC
+
+  //0) approx of mean is global maximum
+  Int_t   nb     =  histo->GetNbinsX();
+  Int_t   bmax   =  histo->GetMaximumBin();
+  Float_t xmax   =  histo->GetBinCenter(bmax);
+
+  double window = expectedRMS * nSigma;
+  //1) estimate a mean in the nSigma window around main max
+  int nlow = histo->FindBin( xmax - window);
+  int nhigh = histo->FindBin( xmax + window);
+  if(nlow<1)   nlow = 1; 
+  if(nhigh>nb) nhigh = nb;
+
+  Float_t sum=0.0, sumWeight=0.0, sumWeightSqr=0.0;
+  for(int ii=nlow;ii<=nhigh;ii++){
+    sum          += histo->GetBinContent(ii);  
+    sumWeight    += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
+  }  
+  if(sum>0.0){
+    meanHisto = sumWeight/sum; //mean in 1st itteration
+  }else{
+    meanHisto = 0.0;
+    rmsHisto=0.0;
+    return;
+  }
+  
+  //2) recalculte mean and rms in the nSigma window around mean 1)
+  nlow  = histo->FindBin( meanHisto - window);
+  nhigh = histo->FindBin( meanHisto + window);
+  if(nlow<1)   nlow = 1; 
+  if(nhigh>nb) nhigh = nb;
+
+  sum=0.0; sumWeight=0.0; sumWeightSqr=0.0;
+  for(int ii=nlow;ii<=nhigh;ii++){
+    sum          += histo->GetBinContent(ii);  
+    sumWeight    += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
+    sumWeightSqr += histo->GetBinContent(ii)*histo->GetBinCenter(ii)*histo->GetBinCenter(ii);
+  }
+  if(sum>0.0){
+    meanHisto = sumWeight/sum; //mean in 2nd itteration
+    rmsHisto  = sumWeightSqr/sum - meanHisto*meanHisto;//rms square
+    if(rmsHisto > 0.0) rmsHisto = sqrt(rmsHisto); //rms
+    else  rmsHisto = 0.0;
+    return;
+  }else{
+    meanHisto = 0.0;
+    rmsHisto  = 0.0;
+    return;
+  }
+}