]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCcalibDButil.cxx
fix for event mixing
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibDButil.cxx
index 0c68c6b4707ee91866d9341afc8f506fca5d3022..f762174d3217677878cbb6eb1b49180a5132fe91 100644 (file)
 #include <TGraph.h>
 #include <TFile.h>
 #include <TDirectory.h>
+#include <TMap.h>
+#include <TGraphErrors.h>
 #include <AliCDBStorage.h>
 #include <AliDCSSensorArray.h>
 #include <AliTPCSensorTempArray.h>
 #include <AliDCSSensor.h>
+#include <AliLog.h>
+#include <AliCDBEntry.h>
+#include <AliCDBManager.h>
+#include <AliCDBId.h>
+#include <AliSplineFit.h>
 #include "AliTPCcalibDB.h"
 #include "AliTPCCalPad.h"
 #include "AliTPCCalROC.h"
 #include "AliTPCmapper.h"
 #include "AliTPCParam.h"
 #include "AliTPCCalibRaw.h"
-#include "TGraphErrors.h"
+#include "AliTPCPreprocessorOnline.h"
+#include "AliTPCdataQA.h"
 #include "AliLog.h"
 #include "AliTPCcalibDButil.h"
-#include "AliTPCPreprocessorOnline.h"
 #include "AliTPCCalibVdrift.h"
+#include "AliMathBase.h"
+#include "AliRelAlignerKalman.h"
+
+const Float_t kAlmost0=1.e-30;
 
 ClassImp(AliTPCcalibDButil)
 AliTPCcalibDButil::AliTPCcalibDButil() :
@@ -62,17 +73,29 @@ AliTPCcalibDButil::AliTPCcalibDButil() :
   fCEQmean(0x0),
   fALTROMasked(0x0),
   fCalibRaw(0x0),
+  fDataQA(0x0),
+  fRefMap(0x0),
+  fCurrentRefMap(0x0),
+  fRefValidity(""),
   fRefPadNoise(0x0),
   fRefPedestals(0x0),
+  fRefPedestalMasked(0x0),
   fRefPulserTmean(0x0),
   fRefPulserTrms(0x0),
   fRefPulserQmean(0x0),
   fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
+  fRefPulserMasked(0x0),
   fRefCETmean(0x0),
   fRefCETrms(0x0),
   fRefCEQmean(0x0),
+  fRefCEMasked(0x0),
+  fRefALTROFPED(0x0),
+  fRefALTROZsThr(0x0),
+  fRefALTROAcqStart(0x0),
+  fRefALTROAcqStop(0x0),
   fRefALTROMasked(0x0),
   fRefCalibRaw(0x0),
+  fRefDataQA(0x0),
   fGoofieArray(0x0),
   fMapper(new AliTPCmapper(0x0)),
   fNpulserOutliers(-1),
@@ -100,15 +123,22 @@ AliTPCcalibDButil::~AliTPCcalibDButil()
   delete fMapper;
   if (fRefPadNoise) delete fRefPadNoise;
   if (fRefPedestals) delete fRefPedestals;
+  if (fRefPedestalMasked) delete fRefPedestalMasked;
   if (fRefPulserTmean) delete fRefPulserTmean;
   if (fRefPulserTrms) delete fRefPulserTrms;
   if (fRefPulserQmean) delete fRefPulserQmean;
+  if (fRefPulserMasked) delete fRefPulserMasked;
   if (fRefCETmean) delete fRefCETmean;
   if (fRefCETrms) delete fRefCETrms;
   if (fRefCEQmean) delete fRefCEQmean;
+  if (fRefCEMasked) delete fRefCEMasked;
+  if (fRefALTROFPED) delete fRefALTROFPED;
+  if (fRefALTROZsThr) delete fRefALTROZsThr;
+  if (fRefALTROAcqStart) delete fRefALTROAcqStart;
+  if (fRefALTROAcqStop) delete fRefALTROAcqStop;
   if (fRefALTROMasked) delete fRefALTROMasked;
   if (fRefCalibRaw) delete fRefCalibRaw;
-    
+  if (fCurrentRefMap) delete fCurrentRefMap;    
 }
 //_____________________________________________________________________________________
 void AliTPCcalibDButil::UpdateFromCalibDB()
@@ -117,6 +147,7 @@ void AliTPCcalibDButil::UpdateFromCalibDB()
   // Update pointers from calibDB
   //
   if (!fCalibDB) fCalibDB=AliTPCcalibDB::Instance();
+  fCalibDB->UpdateNonRec();  // load all infromation now
   fPadNoise=fCalibDB->GetPadNoise();
   fPedestals=fCalibDB->GetPedestals();
   fPulserTmean=fCalibDB->GetPulserTmean();
@@ -128,11 +159,14 @@ void AliTPCcalibDButil::UpdateFromCalibDB()
   fALTROMasked=fCalibDB->GetALTROMasked();
   fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
   fCalibRaw=fCalibDB->GetCalibRaw();
+  fDataQA=fCalibDB->GetDataQA();
   UpdatePulserOutlierMap();
+//   SetReferenceRun();
+//   UpdateRefDataFromOCDB();
 }
 //_____________________________________________________________________________________
 void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
-                                      Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad *outCE)
+                                      Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad * const outCE)
 {
   //
   // Process the CE data for this run
@@ -193,7 +227,7 @@ void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResul
         if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
         Float_t valTmean=rocData->GetValue(irow,ipad);
         //exclude values that are exactly 0
-        if (valTmean==0) {
+        if ( !(TMath::Abs(valTmean)>kAlmost0) ) {
           rocOut->SetValue(irow,ipad,1);
           ++noutliersCE;
         }
@@ -301,7 +335,7 @@ void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMea
 //_____________________________________________________________________________________
 void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
                       TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
-                      Int_t &nonMaskedZero)
+                      Int_t &nonMaskedZero, Int_t &nNaN)
 {
   //
   // process noise data
@@ -322,6 +356,7 @@ void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseM
   vNoiseRMS.Zero();
   vNoiseRMSSenRegions.Zero();
   nonMaskedZero=0;
+  nNaN=0;
   //counters
   TVectorD c(infoSize);
   TVectorD cs(infoSize);
@@ -343,13 +378,14 @@ void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseM
         if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
         Float_t noiseVal=noiseROC->GetValue(irow,ipad);
         //check if noise==0
-        if (noiseVal==0) {
+        if (noiseVal<kAlmost0) {
           ++nonMaskedZero;
           continue;
         }
         //check for nan
         if ( !(noiseVal<10000000) ){
-          printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
+         AliInfo(Form("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal));
+          ++nNaN;
           continue;
         }
         Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
@@ -424,7 +460,7 @@ void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseM
     Double_t rmsSen=0;
     
     if (c[i]>verySmall){
-//       printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
+      AliInfo(Form("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]));
       mean=vNoiseMean[i]/c[i];
       rms=vNoiseRMS[i];
       rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
@@ -442,6 +478,89 @@ void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseM
   }
 }
 
+//_____________________________________________________________________________________
+void AliTPCcalibDButil::ProcessQAData(TVectorD &vQaOcc, TVectorD &vQaQtot, 
+                                     TVectorD &vQaQmax)
+{
+  //
+  // process QA data
+  //
+  // vQaOcc/Qtot/Qmax contains the Mean occupancy/Qtot/Qmax for each sector
+  //
+
+
+  const UInt_t infoSize = 72;
+  //reset counters to error number
+  vQaOcc.ResizeTo(infoSize);
+  vQaOcc.Zero();
+  vQaQtot.ResizeTo(infoSize);
+  vQaQtot.Zero();
+  vQaQmax.ResizeTo(infoSize);
+  vQaQmax.Zero();
+  //counter
+  //retrieve pulser and ALTRO data
+  
+  if (!fDataQA) {
+    
+    AliInfo("No QA data");
+    return;
+  }
+  if (fDataQA->GetEventCounter()<=0) {
+
+    AliInfo("No QA data");
+    return; // no data processed
+  }
+  //
+  fDataQA->Analyse();
+
+  TVectorD normOcc(infoSize);
+  TVectorD normQ(infoSize);
+
+  for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
+
+    AliInfo(Form("Sector %d\n", isec));
+    AliTPCCalROC* occupancyROC = fDataQA->GetNoThreshold()->GetCalROC(isec); 
+    AliTPCCalROC* nclusterROC = fDataQA->GetNLocalMaxima()->GetCalROC(isec); 
+    AliTPCCalROC* qROC = fDataQA->GetMeanCharge()->GetCalROC(isec); 
+    AliTPCCalROC* qmaxROC = fDataQA->GetMaxCharge()->GetCalROC(isec); 
+    if (!occupancyROC) continue;
+    if (!nclusterROC) continue;
+    if (!qROC) continue;
+    if (!qmaxROC) continue;
+    
+    const UInt_t nchannels=occupancyROC->GetNchannels();
+
+    AliInfo(Form("Nchannels %d\n", nchannels));
+
+    for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
+
+      vQaOcc[isec] += occupancyROC->GetValue(ichannel);
+      ++normOcc[isec];
+
+      Float_t nClusters = nclusterROC->GetValue(ichannel);
+      normQ[isec] += nClusters;
+      vQaQtot[isec]+=nClusters*qROC->GetValue(ichannel);
+      vQaQmax[isec]+=nClusters*qmaxROC->GetValue(ichannel);
+    }
+  }
+
+  //calculate mean values
+  for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
+    
+    if (normOcc[isec]>0) vQaOcc[isec] /= normOcc[isec];
+    else vQaOcc[isec] = 0;
+
+    if (normQ[isec]>0) {
+      vQaQtot[isec] /= normQ[isec];
+      vQaQmax[isec] /= normQ[isec];
+    }else {
+
+      vQaQtot[isec] = 0;
+      vQaQmax[isec] = 0;
+    }
+  }
+}
+
 //_____________________________________________________________________________________
 void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
 {
@@ -645,6 +764,7 @@ void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
         //don't use masked channels;
         if (mROC   ->GetValue(irow,ipad)) continue;
         if (mRefROC->GetValue(irow,ipad)) continue;
+        if (nRefROC->GetValue(irow,ipad)==0) continue;
         Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
         for (Int_t i=0;i<npar;++i){
           if (deviation>vThres[i])
@@ -698,7 +818,7 @@ void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Flo
     AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
     AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
     AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
-    Float_t pt_mean=ptROC->GetMean(oROC);
+    Float_t ptmean=ptROC->GetMean(oROC);
     UInt_t nrows=mROC->GetNrows();
     for (UInt_t irow=0;irow<nrows;++irow){
       UInt_t npads=mROC->GetNPads(irow);
@@ -714,7 +834,7 @@ void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Flo
         Float_t pt=ptROC->GetValue(irow,ipad);
 //         Float_t ptRef=ptRefROC->GetValue(irow,ipad);
         //comparisons q
-        Float_t deviation=TMath::Abs(pq/pqRef-1);
+       Float_t deviation=TMath::Abs(pqRef)>1e-20?TMath::Abs(pq/pqRef-1):-999; 
         for (Int_t i=0;i<npar;++i){
           if (deviation>vThres[i])
             ++pulserQdeviations.GetMatrixArray()[i];
@@ -722,7 +842,7 @@ void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Flo
         if (pqRef>11&&pq<11) ++npadsOffAdd;
         varQMean+=pq-pqRef;
         //comparisons t
-        if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB;
+        if (TMath::Abs(pt-ptmean)>1) ++npadsOutOneTB;
         ++nActive;
       }//end ipad
     }//ind irow
@@ -738,7 +858,7 @@ void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Flo
 void AliTPCcalibDButil::UpdatePulserOutlierMap()
 {
   //
-  //
+  // Update the outlier map of the pulser data
   //
   PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
 }
@@ -746,7 +866,7 @@ void AliTPCcalibDButil::UpdatePulserOutlierMap()
 void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
 {
   //
-  //
+  // Update the outlier map of the pulser reference data
   //
   PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
 }
@@ -830,7 +950,7 @@ AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Doub
       AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
       Float_t mean=rocPulTmean->GetMean(rocOut);
       //treat case where a whole partition is masked
-      if (mean==0) mean=rocPulTmean->GetMean();
+      if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
       if (model==1) {
         Int_t type=isec/18;
         mean=vMean[type];
@@ -844,7 +964,7 @@ AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Doub
           //This should be the most precise guess in that case.
           if (rocOut->GetValue(irow,ipad)) {
             time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
-            if (time==0) time=mean;
+            if ( TMath::Abs(time)<kAlmost0 ) time=mean;
           }
           Float_t val=time-mean;
           rocTime0->SetValue(irow,ipad,val);
@@ -879,7 +999,7 @@ AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Doub
       rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
       AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
       Float_t mean=rocPulTmean->GetMean(rocOutPul);
-      if (mean==0) mean=rocPulTmean->GetMean();
+      if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
       UInt_t nrows=rocTime0->GetNrows();
       for (UInt_t irow=0;irow<nrows;++irow){
         UInt_t npads=rocTime0->GetNPads(irow);
@@ -901,8 +1021,11 @@ AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Doub
   return padTime0;
 }
 //_____________________________________________________________________________________
-Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
+Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *const rocOut)
 {
+  //
+  // GetMeanAlto information
+  //
   if (roc==0) return 0.;
   const Int_t sector=roc->GetSector();
   AliTPCROC *tpcRoc=AliTPCROC::Instance();
@@ -953,11 +1076,297 @@ void AliTPCcalibDButil::SetRefFile(const char* filename)
   f.Close();
   currDir->cd();
 }
+//_____________________________________________________________________________________
+void AliTPCcalibDButil::UpdateRefDataFromOCDB()
+{
+  //
+  // set reference data from OCDB Reference map
+  //
+  if (!fRefMap) {
+    AliWarning("Referenc map not set!");
+    return;
+  }
+  
+  TString cdbPath;
+  AliCDBEntry* entry = 0x0;
+  Bool_t hasAnyChanged=kFALSE;
+
+  //pedestals
+  cdbPath="TPC/Calib/Pedestals";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entries
+    if (fRefPedestals) delete fRefPedestals;
+    if (fRefPedestalMasked) delete fRefPedestalMasked;
+    fRefPedestals=fRefPedestalMasked=0x0;
+    //get new entries
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefPedestals=GetRefCalPad(entry);
+      delete entry;
+      fRefPedestalMasked=GetAltroMasked(cdbPath, "MaskedPedestals");
+    }
+  }
 
+  //noise
+  cdbPath="TPC/Calib/PadNoise";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entry
+    if (fRefPadNoise) delete fRefPadNoise;
+    fRefPadNoise=0x0;
+    //get new entry
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefPadNoise=GetRefCalPad(entry);
+      delete entry;
+    }
+  }
+  
+  //pulser
+  cdbPath="TPC/Calib/Pulser";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entries
+    if (fRefPulserTmean) delete fRefPulserTmean;
+    if (fRefPulserTrms) delete fRefPulserTrms;
+    if (fRefPulserQmean) delete fRefPulserQmean;
+    if (fRefPulserMasked) delete fRefPulserMasked;
+    fRefPulserTmean=fRefPulserTrms=fRefPulserQmean=fRefPulserMasked=0x0;
+    //get new entries
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefPulserTmean=GetRefCalPad(entry,"PulserTmean");
+      fRefPulserTrms=GetRefCalPad(entry,"PulserTrms");
+      fRefPulserQmean=GetRefCalPad(entry,"PulserQmean");
+      delete entry;
+      fRefPulserMasked=GetAltroMasked(cdbPath, "MaskedPulser");
+    }
+  }
 
+  //ce
+  cdbPath="TPC/Calib/CE";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entries
+    if (fRefCETmean) delete fRefCETmean;
+    if (fRefCETrms) delete fRefCETrms;
+    if (fRefCEQmean) delete fRefCEQmean;
+    if (fRefCEMasked) delete fRefCEMasked;
+    fRefCETmean=fRefCETrms=fRefCEQmean=fRefCEMasked=0x0;
+    //get new entries
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefCETmean=GetRefCalPad(entry,"CETmean");
+      fRefCETrms=GetRefCalPad(entry,"CETrms");
+      fRefCEQmean=GetRefCalPad(entry,"CEQmean");
+      delete entry;
+      fRefCEMasked=GetAltroMasked(cdbPath, "MaskedCE");
+    }
+  }
+  
+  //altro data
+  cdbPath="TPC/Calib/AltroConfig";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entries
+    if (fRefALTROFPED) delete fRefALTROFPED;
+    if (fRefALTROZsThr) delete fRefALTROZsThr;
+    if (fRefALTROAcqStart) delete fRefALTROAcqStart;
+    if (fRefALTROAcqStop) delete fRefALTROAcqStop;
+    if (fRefALTROMasked) delete fRefALTROMasked;
+    fRefALTROFPED=fRefALTROZsThr=fRefALTROAcqStart=fRefALTROAcqStop=fRefALTROMasked=0x0;
+    //get new entries
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefALTROFPED=GetRefCalPad(entry,"FPED");
+      fRefALTROZsThr=GetRefCalPad(entry,"ZsThr");
+      fRefALTROAcqStart=GetRefCalPad(entry,"AcqStart");
+      fRefALTROAcqStop=GetRefCalPad(entry,"AcqStop");
+      fRefALTROMasked=GetRefCalPad(entry,"Masked");
+      delete entry;
+    }
+  }
+  
+  //raw data
+  /*
+  cdbPath="TPC/Calib/Raw";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entry
+    if (fRefCalibRaw) delete fRefCalibRaw;
+    //get new entry
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      TObjArray *arr=(TObjArray*)entry->GetObject();
+      if (!arr){
+        AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
+      } else {
+        fRefCalibRaw=(AliTPCCalibRaw*)arr->At(0)->Clone();
+      }
+    }
+  }
+  */
 
-
-AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad *ceOut, Float_t minSignal, Float_t cutTrmsMin,  Float_t cutTrmsMax, Float_t cutMaxDistT){
+  //data qa
+  cdbPath="TPC/Calib/QA";
+  if (HasRefChanged(cdbPath.Data())){
+    hasAnyChanged=kTRUE;
+    //delete old entry
+    if (fRefDataQA) delete fRefDataQA;
+    //get new entry
+    entry=GetRefEntry(cdbPath.Data());
+    if (entry){
+      entry->SetOwner(kTRUE);
+      fRefDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
+      if (!fRefDataQA){
+        AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
+      } else {
+        fRefDataQA=(AliTPCdataQA*)fRefDataQA->Clone();
+      }
+      delete entry;
+    }
+  }
+  
+  
+//update current reference maps
+  if (hasAnyChanged){
+    if (fCurrentRefMap) delete fCurrentRefMap;
+    fCurrentRefMap=(TMap*)fRefMap->Clone();
+  }
+}
+//_____________________________________________________________________________________
+AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry, const char* objName)
+{
+  //
+  // TObjArray object type case
+  // find 'objName' in 'arr' cast is to a calPad and store it in 'pad'
+  //
+  AliTPCCalPad *pad=0x0;
+  TObjArray *arr=(TObjArray*)entry->GetObject();
+  if (!arr){
+    AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
+    return pad;
+  }
+  pad=(AliTPCCalPad*)arr->FindObject(objName);
+  if (!pad) {
+    AliError(Form("Could not get '%s' from TObjArray in entry '%s'\nPlease check!!!",objName,entry->GetId().GetPath().Data()));
+    return pad;
+  }
+  return (AliTPCCalPad*)pad->Clone();
+}
+//_____________________________________________________________________________________
+AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry)
+{
+  //
+  // AliTPCCalPad object type case
+  // cast object to a calPad and store it in 'pad'
+  //
+  AliTPCCalPad *pad=(AliTPCCalPad*)entry->GetObject();
+  if (!pad) {
+    AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
+    return 0x0;
+  }
+  pad=(AliTPCCalPad*)pad->Clone();
+  return pad;
+}
+//_____________________________________________________________________________________
+AliTPCCalPad* AliTPCcalibDButil::GetAltroMasked(const char* cdbPath, const char* name)
+{
+  //
+  // set altro masked channel map for 'cdbPath'
+  //
+  AliTPCCalPad* pad=0x0;
+  const Int_t run=GetReferenceRun(cdbPath);
+  if (run<0) {
+    AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
+    return pad;
+  }
+  AliCDBEntry *entry=AliCDBManager::Instance()->Get("TPC/Calib/AltroConfig", run);
+  if (!entry) {
+    AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
+    return pad;
+  }
+  pad=GetRefCalPad(entry,"Masked");
+  if (pad) pad->SetNameTitle(name,name);
+  entry->SetOwner(kTRUE);
+  delete entry;
+  return pad;
+}
+//_____________________________________________________________________________________
+void AliTPCcalibDButil::SetReferenceRun(Int_t run){
+  //
+  // Get Reference map
+  //
+  if (run<0) run=fCalibDB->GetRun();
+  TString cdbPath="TPC/Calib/Ref";
+  AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath.Data(), run);
+  if (!entry) {
+    AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath.Data()));
+    fRefMap=0;
+    return;
+  }  
+  entry->SetOwner(kTRUE);
+  fRefMap=(TMap*)(entry->GetObject());
+  AliCDBId &id=entry->GetId();
+  fRefValidity.Form("%d_%d_v%d_s%d",id.GetFirstRun(),id.GetLastRun(),id.GetVersion(),id.GetSubVersion());
+}
+//_____________________________________________________________________________________
+Bool_t AliTPCcalibDButil::HasRefChanged(const char *cdbPath)
+{
+  //
+  // check whether a reference cdb entry has changed
+  //
+  if (!fCurrentRefMap) return kTRUE;
+  if (GetReferenceRun(cdbPath)!=GetCurrentReferenceRun(cdbPath)) return kTRUE;
+  return kFALSE;
+}
+//_____________________________________________________________________________________
+AliCDBEntry* AliTPCcalibDButil::GetRefEntry(const char* cdbPath)
+{
+  //
+  // get the reference AliCDBEntry for 'cdbPath'
+  //
+  const Int_t run=GetReferenceRun(cdbPath);
+  if (run<0) {
+    AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
+    return 0;
+  }
+  AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath, run);
+  if (!entry) {
+    AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
+    return 0;
+  }
+  return entry;
+}
+//_____________________________________________________________________________________
+Int_t AliTPCcalibDButil::GetCurrentReferenceRun(const char* type) const {
+  //
+  // Get reference run number for the specified OCDB path
+  //
+  if (!fCurrentRefMap) return -2;
+  TObjString *str=dynamic_cast<TObjString*>(fCurrentRefMap->GetValue(type));
+  if (!str) return -2;
+  return (Int_t)str->GetString().Atoi();
+}
+//_____________________________________________________________________________________
+Int_t AliTPCcalibDButil::GetReferenceRun(const char* type) const{
+  //
+  // Get reference run number for the specified OCDB path
+  //
+  if (!fRefMap) return -1;
+  TObjString *str=dynamic_cast<TObjString*>(fRefMap->GetValue(type));
+  if (!str) return -1;
+  return (Int_t)str->GetString().Atoi();
+}
+//_____________________________________________________________________________________
+AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad * const ceOut, Float_t minSignal, Float_t cutTrmsMin,  Float_t cutTrmsMax, Float_t cutMaxDistT){
   //
   // Author:  marian.ivanov@cern.ch
   //
@@ -992,13 +1401,14 @@ AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPC
   Double_t rmsMedian         = fCETrms->GetMedian();
   for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
     AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
+    if (!rocData) continue;
     if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
     AliTPCCalROC *rocOut       = out->GetCalROC(iroc);
     AliTPCCalROC *rocCEQ       = fCEQmean->GetCalROC(iroc);
     AliTPCCalROC *rocCETrms    = fCETrms->GetCalROC(iroc);
     Double_t trocMedian        = rocData->GetMedian();
     //
-    if (!rocData) {
+    if (!rocData || !rocCEQ || !rocCETrms || !rocData) {
       noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
       rocOut->Add(1.);
       continue;
@@ -1027,7 +1437,7 @@ AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPC
         //2. exclude edge pads
         if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
         //exclude values that are exactly 0
-        if (valTmean==0) {
+        if ( TMath::Abs(valTmean)<kAlmost0) {
           rocOut->SetValue(irow,ipad,1);
           ++noutliersCE;
         }
@@ -1062,7 +1472,7 @@ AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPC
 }
 
 
-AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad *pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
+AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad * const pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
   //
   // Author: marian.ivanov@cern.ch
   //
@@ -1105,7 +1515,10 @@ AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser,
       Float_t valTmean=rocData->GetValue(ichannel);
       Float_t valQmean=rocPulserQ->GetValue(ichannel);
       Float_t valTrms =rocPulserTrms->GetValue(ichannel);
+      Float_t valMasked =0;
+      if (rocMasked) valMasked = rocMasked->GetValue(ichannel);
       Int_t isOut=0;
+      if (valMasked>0.5) isOut=1;
       if (TMath::Abs(valTmean-rocMedianT)>cutTime) isOut=1;
       if (TMath::Abs(valQmean-rocMedianQ)>cutnRMSQ*rocRMSQ) isOut=1;
       if (TMath::Abs(valTrms-rocMedianTrms)>cutnRMSrms*rocRMSTrms) isOut=1;
@@ -1282,17 +1695,27 @@ Int_t AliTPCcalibDButil::GetNearest(TGraph *graph, Double_t xref, Double_t &dx,
   //
   // find the closest point to xref  in x  direction
   // return dx and value 
+  dx = 0;
+  y = 0;
+
+  if(!graph) return 0;
+  if(graph->GetN() < 1) return 0;
+
   Int_t index=0;
   index = TMath::BinarySearch(graph->GetN(), graph->GetX(),xref);
   if (index<0) index=0;
-  if (index>=graph->GetN()-1) index=graph->GetN()-2;
-  if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
-  dx = xref-graph->GetX()[index];
+  if(graph->GetN()==1) {
+    dx = xref-graph->GetX()[index];
+  }
+  else {
+    if (index>=graph->GetN()-1) index=graph->GetN()-2;
+    if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
+    dx = xref-graph->GetX()[index];
+  }
   y  = graph->GetY()[index];
   return index;
 }
 
-
 Double_t  AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
   //
   // Get the correction of the trigger offset
@@ -1311,7 +1734,7 @@ Double_t  AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Dou
   //
   //
   const Float_t kLaserCut=0.0005;
-  const Int_t   kMaxPeriod=3600*24*30*3; // 3 month max
+  const Int_t   kMaxPeriod=3600*24*30*12; // one year max
   const Int_t   kMinPoints=20;
   //
   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
@@ -1353,10 +1776,18 @@ Double_t  AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Dou
     tdelta[nused]=ccosmic-claser;
     nused++;
   }
-  if (nused<kMinPoints &&deltaT<kMaxPeriod) return  AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
+  if (nused<kMinPoints &&deltaT<kMaxPeriod) {
+    delete [] tdelta;
+    return  AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
+  }
+  if (nused<kMinPoints) {
+    delete [] tdelta;
+    //AliWarning("AliFatal: No time offset calibration available\n");
+    return 0;
+  }
   Double_t median = TMath::Median(nused,tdelta);
   Double_t mean  = TMath::Mean(nused,tdelta);
-  delete tdelta;
+  delete [] tdelta;
   return (valType==0) ? median:mean;
 }
 
@@ -1392,10 +1823,10 @@ Double_t  AliTPCcalibDButil::GetVDriftTPC(Double_t &dist, Int_t run, Int_t timeS
   AliTPCcalibDButil::GetNearest(cosmicAll,timeStamp,dist,grY);
 
   Double_t t0= AliTPCcalibDButil::GetTriggerOffsetTPC(run,timeStamp, deltaT, deltaTLaser,valType);
-  Double_t vcosmic=  AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
+  Double_t vcosmic =  AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
   if (timeStamp>cosmicAll->GetX()[cosmicAll->GetN()-1])  vcosmic=cosmicAll->GetY()[cosmicAll->GetN()-1];
   if (timeStamp<cosmicAll->GetX()[0])  vcosmic=cosmicAll->GetY()[0];
-  return  vcosmic+t0;
+  return  vcosmic-t0;
 
   /*
     Example usage:
@@ -1417,9 +1848,77 @@ Double_t  AliTPCcalibDButil::GetVDriftTPC(Double_t &dist, Int_t run, Int_t timeS
   
 }
 
+const char* AliTPCcalibDButil::GetGUIRefTreeDefaultName()
+{
+  //
+  // Create a default name for the gui file
+  //
+  
+  return Form("guiRefTreeRun%s.root",GetRefValidity());
+}
+
+Bool_t AliTPCcalibDButil::CreateGUIRefTree(const char* filename)
+{
+  //
+  // Create a gui reference tree
+  // if dirname and filename are empty default values will be used
+  // this is the recommended way of using this function
+  // it allows to check whether a file with the given run validity alredy exists
+  //
+  if (!AliCDBManager::Instance()->GetDefaultStorage()){
+    AliError("Default Storage not set. Cannot create reference calibration Tree!");
+    return kFALSE;
+  }
+  
+  TString file=filename;
+  if (file.IsNull()) file=GetGUIRefTreeDefaultName();
+  
+  AliTPCPreprocessorOnline prep;
+  //noise and pedestals
+  if (fRefPedestals) prep.AddComponent(new AliTPCCalPad(*(fRefPedestals)));
+  if (fRefPadNoise ) prep.AddComponent(new AliTPCCalPad(*(fRefPadNoise)));
+  if (fRefPedestalMasked) prep.AddComponent(new AliTPCCalPad(*fRefPedestalMasked));
+  //pulser data
+  if (fRefPulserTmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTmean)));
+  if (fRefPulserTrms ) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTrms)));
+  if (fRefPulserQmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserQmean)));
+  if (fRefPulserMasked) prep.AddComponent(new AliTPCCalPad(*fRefPulserMasked));
+  //CE data
+  if (fRefCETmean) prep.AddComponent(new AliTPCCalPad(*(fRefCETmean)));
+  if (fRefCETrms ) prep.AddComponent(new AliTPCCalPad(*(fRefCETrms)));
+  if (fRefCEQmean) prep.AddComponent(new AliTPCCalPad(*(fRefCEQmean)));
+  if (fRefCEMasked) prep.AddComponent(new AliTPCCalPad(*fRefCEMasked));
+  //Altro data
+  if (fRefALTROAcqStart ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStart )));
+  if (fRefALTROZsThr    ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROZsThr    )));
+  if (fRefALTROFPED     ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROFPED     )));
+  if (fRefALTROAcqStop  ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStop  )));
+  if (fRefALTROMasked   ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROMasked   )));
+  //QA
+  AliTPCdataQA *dataQA=fRefDataQA;
+  if (dataQA) {
+    if (dataQA->GetNLocalMaxima())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
+    if (dataQA->GetMaxCharge())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
+    if (dataQA->GetMeanCharge())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
+    if (dataQA->GetNoThreshold())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
+    if (dataQA->GetNTimeBins())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
+    if (dataQA->GetNPads())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
+    if (dataQA->GetTimePosition())
+      prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
+  }
+  prep.DumpToFile(file.Data());
+  return kTRUE;
+}
+
 Double_t  AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
   //
-  // Get the correction of the drift velocity using the laser tracks calbration
+  // Get the correction of the drift velocity using the offline laser tracks calbration
   //
   // run       - run number
   // timeStamp - tim stamp in seconds
@@ -1427,6 +1926,56 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run,
   // side      - 0 - A side,  1 - C side, 2 - mean from both sides
   // Note in case no data form both A and C side - the value from active side used
   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+
+  return GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
+}
+
+Double_t  AliTPCcalibDButil::GetVDriftTPCLaserTracksOnline(Double_t &dist, Int_t /*run*/, Int_t timeStamp, Double_t deltaT, Int_t side){
+  //
+  // Get the correction of the drift velocity using the online laser tracks calbration
+  //
+  // run       - run number
+  // timeStamp - tim stamp in seconds
+  // deltaT    - integration period to calculate time0 offset
+  // side      - 0 - A side,  1 - C side, 2 - mean from both sides
+  // Note in case no data form both A and C side - the value from active side used
+  TObjArray *array =AliTPCcalibDB::Instance()->GetCEfitsDrift();
+
+  Double_t dv = GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
+  AliTPCParam *param  =AliTPCcalibDB::Instance()->GetParameters();
+  if (!param) return 0;
+
+  //the drift velocity is hard wired in the AliTPCCalibCE class, since online there is no access to OCDB
+  dv*=param->GetDriftV()/2.61301900000000000e+06;
+  if (dv>1e-20) dv=1/dv-1;
+  else return 0;
+  // T/P correction
+  TObjArray*  cearray =AliTPCcalibDB::Instance()->GetCEData();
+  
+  AliTPCSensorTempArray *temp = (AliTPCSensorTempArray*)cearray->FindObject("TempMap");
+  AliDCSSensor *press         = (AliDCSSensor*)cearray->FindObject("CavernAtmosPressure");
+  
+  Double_t corrPTA=0;
+  Double_t corrPTC=0;
+  
+  if (temp&&press) {
+    AliTPCCalibVdrift corr(temp,press,0);
+    corrPTA=corr.GetPTRelative(timeStamp,0);
+    corrPTC=corr.GetPTRelative(timeStamp,1);
+  }
+  
+  if (side==0) dv -=  corrPTA;
+  if (side==1) dv -=  corrPTC;
+  if (side==2) dv -=  (corrPTA+corrPTC)/2;
+  
+  return dv;
+}
+
+Double_t  AliTPCcalibDButil::GetVDriftTPCLaserTracksCommon(Double_t &dist, Int_t timeStamp, Double_t deltaT,
+  Int_t side, TObjArray * const array){
+  //
+  // common drift velocity retrieval for online and offline method
+  //
   TGraphErrors *grlaserA=0;
   TGraphErrors *grlaserC=0;
   Double_t vlaserA=0, vlaserC=0;
@@ -1434,12 +1983,12 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run,
   grlaserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
   grlaserC=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
   Double_t deltaY;
-  if (grlaserA) {
+  if (grlaserA && grlaserA->GetN()>0) {
     AliTPCcalibDButil::GetNearest(grlaserA,timeStamp,dist,deltaY);
     if (TMath::Abs(dist)>deltaT)  vlaserA= deltaY;
     else  vlaserA = AliTPCcalibDButil::EvalGraphConst(grlaserA,timeStamp);
   }
-  if (grlaserC) {
+  if (grlaserC && grlaserC->GetN()>0) {
     AliTPCcalibDButil::GetNearest(grlaserC,timeStamp,dist,deltaY);
     if (TMath::Abs(dist)>deltaT)  vlaserC= deltaY;
     else  vlaserC = AliTPCcalibDButil::EvalGraphConst(grlaserC,timeStamp);
@@ -1464,6 +2013,7 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t time
   // deltaT    - integration period to calculate time0 offset 
   // side      - 0 - A side,  1 - C side, 2 - mean from both sides
   TObjArray *arrT     =AliTPCcalibDB::Instance()->GetCErocTtime();
+  if (!arrT) return 0;
   AliTPCParam *param  =AliTPCcalibDB::Instance()->GetParameters();
   TObjArray*  cearray =AliTPCcalibDB::Instance()->GetCEData(); 
   AliTPCCalibVdrift * driftCalib = (AliTPCCalibVdrift *)cearray->FindObject("driftPTCE");
@@ -1474,6 +2024,7 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t time
   Double_t gry=0;
   Double_t corrA=0, corrC=0;
   Double_t timeA=0, timeC=0;
+  const Double_t kEpsilon = 0.00001;
   TGraph *graphA = (TGraph*)arrT->At(72);
   TGraph *graphC = (TGraph*)arrT->At(73);
   if (!graphA && !graphC) return 0.;
@@ -1482,6 +2033,7 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t time
     timeA   = AliTPCcalibDButil::EvalGraphConst(graphA,timeStamp);
     Int_t mtime   =TMath::Nint((graphA->GetX()[0]+graphA->GetX()[graphA->GetN()-1])*0.5);
     ltime0A       = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
+    if(ltime0A < kEpsilon) return 0;
     if (driftCalib) corrPTA =  driftCalib->GetPTRelative(timeStamp,0);
     corrA = (param->GetZLength(36)/(timeA*param->GetTSample()*(1.-ltime0A)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
     corrA-=corrPTA;
@@ -1491,7 +2043,8 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t time
     timeC=AliTPCcalibDButil::EvalGraphConst(graphC,timeStamp);
     Int_t mtime=TMath::Nint((graphC->GetX()[0]+graphC->GetX()[graphC->GetN()-1])*0.5);
     ltime0C       = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
-    if (driftCalib) corrPTC =  driftCalib->GetPTRelative(timeStamp,0);
+    if(ltime0C < kEpsilon) return 0;   
+if (driftCalib) corrPTC =  driftCalib->GetPTRelative(timeStamp,0);
     corrC = (param->GetZLength(54)/(timeC*param->GetTSample()*(1.-ltime0C)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
     corrC-=corrPTC;
   }
@@ -1504,6 +2057,46 @@ Double_t  AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t time
   return corrM;
 }
 
+Double_t  AliTPCcalibDButil::GetVDriftTPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
+  //
+  // return drift velocity using the TPC-ITS matchin method
+  // return also distance to the closest point
+  //
+  TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+  TGraphErrors *graph=0;
+  dist=0;
+  if (!array) return 0;
+  //array->ls();
+  graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
+  if (!graph) return 0;
+  Double_t deltaY;
+  AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY); 
+  Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
+  return value;
+}
+
+Double_t AliTPCcalibDButil::GetTime0TPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
+  //
+  // Get time dependent time 0 (trigger delay in cm) correction
+  // Arguments:
+  // timestamp - timestamp
+  // run       - run number
+  //
+  // Notice - Extrapolation outside of calibration range  - using constant function
+  //
+  TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+  TGraphErrors *graph=0;
+  dist=0;
+  if (!array) return 0;
+  graph = (TGraphErrors*)array->FindObject("ALIGN_ITSM_TPC_T0");
+  if (!graph) return 0;
+  Double_t deltaY;
+  AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY); 
+  Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
+  return value;
+}
+
+
 
 
 
@@ -1555,7 +2148,7 @@ Int_t  AliTPCcalibDButil::MakeRunList(Int_t startRun, Int_t stopRun){
       if (!tmpRun) continue;
       fRunsStart[irun]=tmpRun->GetStartTime().GetSec();
       fRunsStop[irun]=tmpRun->GetEndTime().GetSec();
-      //      printf("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec());
+      //AliInfo(Form("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec()));
     }}
   return fRuns.fN;
 }
@@ -1571,7 +2164,7 @@ Int_t AliTPCcalibDButil::FindRunTPC(Int_t    itime, Bool_t debug){
   for (Int_t index=index0; index<=index1; index++){
     if (fRunsStart[index]<=itime && fRunsStop[index]>=itime) cindex=index;
     if (debug) {
-      printf("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime);
+      AliInfo(Form("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime));
     }
   }
   if (cindex<0) cindex =(index0+index1)/2;
@@ -1594,11 +2187,12 @@ TGraph* AliTPCcalibDButil::FilterGraphMedian(TGraph * graph, Float_t sigmaCut,Do
   Int_t npoints0 = graph->GetN();
   Int_t npoints=0;
   Float_t  rmsY=0;
-  Double_t *outx=new Double_t[npoints0];
-  Double_t *outy=new Double_t[npoints0];
   //
   //
   if (npoints0<kMinPoints) return 0;
+
+  Double_t *outx=new Double_t[npoints0];
+  Double_t *outy=new Double_t[npoints0];
   for (Int_t iter=0; iter<3; iter++){
     npoints=0;
     for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
@@ -1614,6 +2208,8 @@ TGraph* AliTPCcalibDButil::FilterGraphMedian(TGraph * graph, Float_t sigmaCut,Do
   }
   TGraph *graphOut=0;
   if (npoints>1) graphOut= new TGraph(npoints,outx,outy); 
+  delete [] outx;
+  delete [] outy;
   return graphOut;
 }
 
@@ -1627,11 +2223,12 @@ TGraph* AliTPCcalibDButil::FilterGraphMedianAbs(TGraph * graph, Float_t cut,Doub
   Int_t npoints0 = graph->GetN();
   Int_t npoints=0;
   Float_t  rmsY=0;
-  Double_t *outx=new Double_t[npoints0];
-  Double_t *outy=new Double_t[npoints0];
   //
   //
   if (npoints0<kMinPoints) return 0;
+
+  Double_t *outx=new Double_t[npoints0];
+  Double_t *outy=new Double_t[npoints0];
   for (Int_t iter=0; iter<3; iter++){
     npoints=0;
     for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
@@ -1647,12 +2244,14 @@ TGraph* AliTPCcalibDButil::FilterGraphMedianAbs(TGraph * graph, Float_t cut,Doub
   }
   TGraph *graphOut=0;
   if (npoints>1) graphOut= new TGraph(npoints,outx,outy); 
+  delete [] outx;
+  delete [] outy;
   return graphOut;
 }
 
 
 
-TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * graph, Float_t sigmaCut,Double_t &medianY){
+TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * const graph, Float_t sigmaCut,Double_t &medianY){
   //
   // filter outlyer measurement
   // Only points with normalized errors median +- sigmaCut filtered
@@ -1661,14 +2260,16 @@ TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * graph, Floa
   Int_t npoints0 = graph->GetN();
   Int_t npoints=0;
   Float_t  medianErr=0, rmsErr=0;
+  //
+  //
+  if (npoints0<kMinPoints) return 0;
+
   Double_t *outx=new Double_t[npoints0];
   Double_t *outy=new Double_t[npoints0];
   Double_t *erry=new Double_t[npoints0];
   Double_t *nerry=new Double_t[npoints0];
   Double_t *errx=new Double_t[npoints0];
-  //
-  //
-  if (npoints0<kMinPoints) return 0;
+
   for (Int_t iter=0; iter<3; iter++){
     npoints=0;
     for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
@@ -1689,8 +2290,9 @@ TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * graph, Floa
   if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry); 
   delete []outx;
   delete []outy;
-  delete []errx;
   delete []erry;
+  delete []nerry;
+  delete []errx;
   return graphOut;
 }
 
@@ -1709,6 +2311,9 @@ void AliTPCcalibDButil::Sort(TGraph *graph){
   for (Int_t i=0;i<npoints;i++) graph->GetX()[i]=outx[i];
   for (Int_t i=0;i<npoints;i++) graph->GetY()[i]=outy[i];
  
+  delete [] indexes;
+  delete [] outx;
+  delete [] outy;
 }
 void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
   //
@@ -1717,6 +2322,7 @@ void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
   Sort(graph);
   Int_t npoints = graph->GetN();
   Double_t *outy=new Double_t[npoints];
+  
   for (Int_t ipoint=0; ipoint<npoints; ipoint++){
     Double_t lx=graph->GetX()[ipoint];
     Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
@@ -1729,26 +2335,71 @@ void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
       outy[ipoint]=graph->GetY()[ipoint];
     }
   }
+ //  TLinearFitter  fitter(3,"pol2");
+//   for (Int_t ipoint=0; ipoint<npoints; ipoint++){
+//     Double_t lx=graph->GetX()[ipoint];
+//     Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
+//     Int_t index1=TMath::BinarySearch(npoints, graph->GetX(),lx+delta);
+//     if (index0<0) index0=0;
+//     if (index1>=npoints-1) index1=npoints-1;
+//     fitter.ClearPoints();
+//     for (Int_t jpoint=0;jpoint<index1-index0; jpoint++)
+//     if ((index1-index0)>1){
+//       outy[ipoint]  = TMath::Mean(index1-index0, &(graph->GetY()[index0]));
+//     }else{
+//       outy[ipoint]=graph->GetY()[ipoint];
+//     }
+//   }
+
+
+
   for (Int_t ipoint=0; ipoint<npoints; ipoint++){
     graph->GetY()[ipoint] = outy[ipoint];
   }
   delete[] outy;
 }
 
-Double_t AliTPCcalibDButil::EvalGraphConst(TGraph *graph, Double_t xref){
+Double_t AliTPCcalibDButil::EvalGraphConst(TGraph * const graph, Double_t xref){
   //
   // Use constant interpolation outside of range 
   //
   if (!graph) {
-    printf("AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
+    AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
     return 0;
   }
+
   if (graph->GetN()<1){
-    printf("AliTPCcalibDButil::EvalGraphConst: Empty graph");
+    AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph \n");
     return 0;
   }
+
   if (xref<graph->GetX()[0]) return graph->GetY()[0];
   if (xref>graph->GetX()[graph->GetN()-1]) return graph->GetY()[graph->GetN()-1]; 
+
+  //  AliInfo(Form("graph->Eval(graph->GetX()[0]) %f, graph->Eval(xref) %f \n",graph->Eval(graph->GetX()[0]), graph->Eval(xref)));
+
+  if(graph->GetN()==1)
+    return graph->Eval(graph->GetX()[0]);
+
+
+  return graph->Eval(xref);
+}
+
+Double_t AliTPCcalibDButil::EvalGraphConst(AliSplineFit *graph, Double_t xref){
+  //
+  // Use constant interpolation outside of range also for spline fits
+  //
+  if (!graph) {
+    AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
+    return 0;
+  }
+  if (graph->GetKnots()<1){
+    AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph");
+    return 0;
+  }
+  if (xref<graph->GetX()[0]) return graph->GetY0()[0];
+  if (xref>graph->GetX()[graph->GetKnots()-1]) return graph->GetY0()[graph->GetKnots()-1]; 
   return graph->Eval( xref);
 }
 
@@ -1791,8 +2442,11 @@ Float_t AliTPCcalibDButil::FilterSensor(AliDCSSensor * sensor, Double_t ymin, Do
   if (naccept<1) {
     delete fit;
     sensor->SetFit(0);
+    delete [] yin0;
+    delete [] yin1;
     return 0.;
   }
+
   Double_t medianY0=0, medianY1=0;
   Double_t rmsY0   =0, rmsY1=0;
   medianY0 = TMath::Median(naccept, yin0);
@@ -1838,10 +2492,9 @@ Float_t  AliTPCcalibDButil::FilterTemperature(AliTPCSensorTempArray *tempArray,
   for (Int_t isensor=0; isensor<nsensors; isensor++){
     AliDCSSensor *sensor = tempArray->GetSensorNum(isensor);
     if (!sensor) continue;
-    //printf("%d\n",isensor);
     FilterSensor(sensor,ymin,ymax,kMaxDy, sigmaCut);
     if (sensor->GetFit()==0){
-      delete sensor;
+      //delete sensor;
       tempArray->RemoveSensorNum(isensor);
     }else{
       naccept++;
@@ -1851,7 +2504,7 @@ Float_t  AliTPCcalibDButil::FilterTemperature(AliTPCSensorTempArray *tempArray,
 }
 
 
-void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector *pcstream){
+void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector * const pcstream){
   //
   // Filter CE data
   // Input parameters:
@@ -1882,12 +2535,13 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
   //
   //
   AliTPCSensorTempArray *tempMapCE = (AliTPCSensorTempArray *)cearray->FindObject("TempMap");
-  AliDCSSensor * cavernPressureCE  = (AliDCSSensor *) cearray->FindObject("CavernPressure");
+  AliDCSSensor * cavernPressureCE  = (AliDCSSensor *) cearray->FindObject("CavernAtmosPressure");
   if ( tempMapCE && cavernPressureCE){
     //
-    Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
-    FilterSensor(cavernPressureCE,960,1050,10, 5.);
-    if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
+    //     Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
+    //     FilterSensor(cavernPressureCE,960,1050,10, 5.);
+    //     if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
+    Bool_t isOK=kTRUE;
     if (isOK)  {      
       // recalculate P/T correction map for time of the CE
       AliTPCCalibVdrift * driftCalib = new AliTPCCalibVdrift(tempMapCE,cavernPressureCE ,0);
@@ -1902,7 +2556,8 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
 
   for (Int_t i=0; i<72;i++){
     TGraph *graph= (TGraph*)arrT->At(i);
-    if (!graph) continue;
+    if (!graph) continue; 
+    graph->Sort();
     if (graph->GetN()<kMinPoints){
       arrT->AddAt(0,i);
       delete graph;  // delete empty graph
@@ -1950,7 +2605,8 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
     Double_t median = (isec%36<18) ? medianA: medianC;
     Double_t rms    = (isec%36<18) ? rmsA:    rmsC;
     Int_t naccept=0;
-    for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){
+    //    for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){ //not neccessary to remove first points
+    for (Int_t ipoint=0; ipoint<graph->GetN();ipoint++){
       if (TMath::Abs(graph->GetY()[ipoint]-median)>cutAbs) continue;
       if (TMath::Abs(graph->GetY()[ipoint]-median)>cutSigma*rms) continue;
       vecX[naccept]= graph->GetX()[ipoint];
@@ -1984,6 +2640,7 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
       continue;
     }
     TGraph* graphTS= FilterGraphMedian(graphTS0,cutSigma,medianY);    
+    if (!graphTS) continue;
     graphTS->Sort();
     AliTPCcalibDButil::SmoothGraph(graphTS,deltaT);      
     if (pcstream){
@@ -1998,7 +2655,6 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
        "\n";
     }
     delete graphTS0;
-    if (!graphTS) continue;
     arrT->AddAt(graphTS,i);
     delete graph;
   }
@@ -2053,7 +2709,7 @@ void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutS
 }
 
 
-void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector *pcstream){
+void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector * const pcstream){
   //
   // Filter Drift velocity measurement using the tracks
   // 0.  remove outlyers - error based
@@ -2065,16 +2721,25 @@ void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirec
   Double_t medianY=0;
   if (!arrT) return;
   for (Int_t i=0; i<arrT->GetEntries();i++){
-    TGraphErrors *graph= (TGraphErrors*)arrT->At(i);
+    TGraphErrors *graph= dynamic_cast<TGraphErrors*>(arrT->At(i));
     if (!graph) continue;
     if (graph->GetN()<kMinPoints){
       delete graph;
       arrT->AddAt(0,i);
       continue;
     }
-    TGraphErrors *graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
-    if (!graph2) {
-      delete graph; arrT->AddAt(0,i); continue;
+    TGraphErrors *graph2 = NULL;
+    if(graph->GetN()<10) {
+      graph2 = new TGraphErrors(graph->GetN(),graph->GetX(),graph->GetY(),graph->GetEX(),graph->GetEY()); 
+      if (!graph2) {
+        delete graph; arrT->AddAt(0,i); continue;
+      }
+    } 
+    else {
+      graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
+      if (!graph2) {
+        delete graph; arrT->AddAt(0,i); continue;
+      }
     }
     if (graph2->GetN()<1) {
       delete graph; arrT->AddAt(0,i); continue;
@@ -2096,47 +2761,6 @@ void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirec
 }
 
 
-void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, TTreeSRedirector *pcstream){
-  //
-  // Filter Goofie data
-  // 0.  remove outlyers      - cutSigma around median
-  // 1.  smooth the graphs    - deltaT - smoothing window
-  //  
-  for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
-    //
-    //
-    AliDCSSensor *sensor = goofieArray->GetSensor(isensor);       
-    Double_t medianY;    
-    if (sensor &&  sensor->GetGraph()){
-      TGraph * graph = sensor->GetGraph();
-      if (isensor==3 && graph->GetN()>1){ // drift velocity
-       TGraph * graphv = FilterGraphMedianAbs(graph,0.2,medianY);
-       delete graph;
-       graph=graphv;
-      }
-      TGraph * graph2 = FilterGraphMedian(graph,cutSigma,medianY);
-      if (!graph2) continue;
-      AliTPCcalibDButil::SmoothGraph(graph2,deltaT);
-      if (pcstream){
-       Int_t run = AliTPCcalibDB::Instance()->GetRun();
-       (*pcstream)<<"filterG"<<
-         "run="<<run<<
-         "isensor="<<isensor<<
-         "mY="<<medianY<<
-         "graph.="<<graph<<
-         "graph2.="<<graph2<<
-         "\n";
-      }      
-      if (graph2->GetN()<2) {delete graph2; continue;}
-      delete graph;
-      sensor->SetGraph(graph2);      
-    }
-  }
-}
-
-
-
-
 
 
 
@@ -2180,7 +2804,11 @@ Double_t AliTPCcalibDButil::GetLaserTime0(Int_t run, Int_t timeStamp, Int_t delt
   //if (index1-index0 <kMinPoints) { index1+=kMinPoints; index0-=kMinPoints;}
   if (index0<0) index0=0;
   if (index1>=npoints-1) index1=npoints-1;
-  if (index1-index0<kMinPoints) return 0;
+  if (index1-index0<kMinPoints) {
+    delete [] ylaser;
+    delete [] xlaser;
+    return 0;
+  }
   //
   //Double_t median = TMath::Median(index1-index0, &(ylaser[index0]));
     Double_t mean = TMath::Mean(index1-index0, &(ylaser[index0]));
@@ -2188,3 +2816,320 @@ Double_t AliTPCcalibDButil::GetLaserTime0(Int_t run, Int_t timeStamp, Int_t delt
   delete [] xlaser;
   return mean;
 }
+
+
+
+
+void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, Double_t minVd, Double_t maxVd, TTreeSRedirector * const pcstream){
+  //
+  // Filter Goofie data
+  // goofieArray - points will be filtered
+  // deltaT      - smmothing time window 
+  // cutSigma    - outler sigma cut in rms
+  // minVn, maxVd- range absolute cut for variable vd/pt
+  //             - to be tuned
+  //
+  // Ignore goofie if not enough points
+  //
+  const Int_t kMinPoints = 3;
+  //
+
+  TGraph *graphvd = goofieArray->GetSensorNum(2)->GetGraph();
+  TGraph *graphan = goofieArray->GetSensorNum(8)->GetGraph();
+  TGraph *graphaf = goofieArray->GetSensorNum(9)->GetGraph();
+  TGraph *graphpt = goofieArray->GetSensorNum(15)->GetGraph();
+  if (!graphvd) return;
+  if (graphvd->GetN()<kMinPoints){
+    delete graphvd;
+    goofieArray->GetSensorNum(2)->SetGraph(0);
+    return;
+  }
+  //
+  // 1. Caluclate medians of critical variables
+  //    drift velcocity
+  //    P/T
+  //    area near peak
+  //    area far  peak
+  //
+  Double_t medianpt=0;
+  Double_t medianvd=0, sigmavd=0;
+  Double_t medianan=0;
+  Double_t medianaf=0;
+  Int_t    entries=graphvd->GetN();
+  Double_t yvdn[10000];
+  Int_t nvd=0;
+  //
+  for (Int_t ipoint=0; ipoint<entries; ipoint++){
+    if (graphpt->GetY()[ipoint]<=0.0000001) continue;
+    if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]<minVd) continue;
+    if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]>maxVd) continue;
+    yvdn[nvd++]=graphvd->GetY()[ipoint];
+  }
+  if (nvd<kMinPoints){
+    delete graphvd;
+    goofieArray->GetSensorNum(2)->SetGraph(0);
+    return;
+  }
+  //
+  Int_t nuni = TMath::Min(TMath::Nint(nvd*0.4+2), nvd-1);
+  if (nuni>=kMinPoints){
+    AliMathBase::EvaluateUni(nvd, yvdn, medianvd,sigmavd,nuni); 
+  }else{
+    medianvd = TMath::Median(nvd, yvdn);
+  }
+  
+  TGraph * graphpt0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphpt,10,medianpt);
+  TGraph * graphpt1 = AliTPCcalibDButil::FilterGraphMedian(graphpt0,2,medianpt);
+  TGraph * graphan0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphan,10,medianan);
+  TGraph * graphan1 = AliTPCcalibDButil::FilterGraphMedian(graphan0,2,medianan);
+  TGraph * graphaf0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphaf,10,medianaf);
+  TGraph * graphaf1 = AliTPCcalibDButil::FilterGraphMedian(graphaf0,2,medianaf);
+  delete graphpt0;
+  delete graphpt1;
+  delete graphan0;
+  delete graphan1;
+  delete graphaf0;
+  delete graphaf1;
+  //
+  // 2. Make outlyer graph
+  //
+  Int_t nOK=0;
+  TGraph graphOut(*graphvd);
+  for (Int_t i=0; i<entries;i++){
+    //
+    Bool_t isOut=kFALSE;
+    if (graphpt->GetY()[i]<=0.0000001) {  graphOut.GetY()[i]=1; continue;}
+    if (graphvd->GetY()[i]/graphpt->GetY()[i]<minVd || graphvd->GetY()[i]/graphpt->GetY()[i]>maxVd) {  graphOut.GetY()[i]=1; continue;}
+    if (TMath::Abs((graphvd->GetY()[i]/graphpt->GetY()[i])/medianvd-1.)<0.05) 
+      isOut|=kTRUE;
+    if (TMath::Abs(graphpt->GetY()[i]/medianpt-1.)>0.02) isOut|=kTRUE;
+    if (TMath::Abs(graphan->GetY()[i]/medianan-1.)>0.2) isOut|=kTRUE;
+    if (TMath::Abs(graphaf->GetY()[i]/medianaf-1.)>0.2) isOut|=kTRUE;
+    graphOut.GetY()[i]= (isOut)?1:0;
+    if (!isOut) nOK++;
+  }
+  if (nOK<kMinPoints) {
+    delete graphvd;
+    goofieArray->GetSensorNum(2)->SetGraph(0);
+    return;
+  } 
+  //
+  // 3. Filter out outlyers - and smooth 
+  //
+  TVectorF vmedianArray(goofieArray->NumSensors());
+  TVectorF vrmsArray(goofieArray->NumSensors());
+  Double_t xnew[10000];
+  Double_t ynew[10000]; 
+  TObjArray junk;
+  junk.SetOwner(kTRUE);
+  Bool_t isOK=kTRUE;
+  //
+  //
+  for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
+    isOK=kTRUE;
+    AliDCSSensor *sensor = goofieArray->GetSensorNum(isensor); 
+    TGraph *graphOld=0, *graphNew=0, * graphNew0=0,*graphNew1=0,*graphNew2=0;
+    //
+    if (!sensor) continue;
+    graphOld = sensor->GetGraph();
+    if (graphOld) {
+      sensor->SetGraph(0);
+      Int_t nused=0;
+      for (Int_t i=0;i<entries;i++){
+       if (graphOut.GetY()[i]>0.5) continue;
+       xnew[nused]=graphOld->GetX()[i];
+       ynew[nused]=graphOld->GetY()[i];
+       nused++;
+      }
+      graphNew = new TGraph(nused,xnew,ynew);
+      junk.AddLast(graphNew);
+      junk.AddLast(graphOld);      
+      Double_t median=0;
+      graphNew0  = AliTPCcalibDButil::FilterGraphMedian(graphNew,cutSigma,median);
+      if (graphNew0!=0){
+       junk.AddLast(graphNew0);
+       graphNew1  = AliTPCcalibDButil::FilterGraphMedian(graphNew0,cutSigma,median);
+       if (graphNew1!=0){
+         junk.AddLast(graphNew1);        
+         graphNew2  = AliTPCcalibDButil::FilterGraphMedian(graphNew1,cutSigma,median);
+         if (graphNew2!=0) {
+           vrmsArray[isensor]   =TMath::RMS(graphNew2->GetN(),graphNew2->GetY());
+           AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
+           AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
+           AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
+           //      AliInfo(Form("%d\t%f\t%f\n",isensor, median,vrmsArray[isensor]));
+           vmedianArray[isensor]=median;
+           //
+         }
+       }
+      }
+    }
+    if (!graphOld) {  isOK=kFALSE; graphOld =&graphOut;}
+    if (!graphNew0) { isOK=kFALSE; graphNew0=graphOld;}
+    if (!graphNew1) { isOK=kFALSE; graphNew1=graphOld;}
+    if (!graphNew2) { isOK=kFALSE; graphNew2=graphOld;}
+    (*pcstream)<<"goofieA"<<
+      Form("isOK_%d.=",isensor)<<isOK<<      
+      Form("s_%d.=",isensor)<<sensor<<
+      Form("gr_%d.=",isensor)<<graphOld<<
+      Form("gr0_%d.=",isensor)<<graphNew0<<
+      Form("gr1_%d.=",isensor)<<graphNew1<<
+      Form("gr2_%d.=",isensor)<<graphNew2;
+    if (isOK) sensor->SetGraph(graphNew2);
+  }
+  (*pcstream)<<"goofieA"<<
+    "vmed.="<<&vmedianArray<<
+    "vrms.="<<&vrmsArray<<
+    "\n";
+  junk.Delete();   // delete temoprary graphs
+  
+}
+
+
+
+
+
+TMatrixD* AliTPCcalibDButil::MakeStatRelKalman(TObjArray * const array, Float_t minFraction, Int_t minStat, Float_t maxvd){
+  //
+  // Make a statistic matrix
+  // Input parameters:
+  //   array        - TObjArray of AliRelKalmanAlign 
+  //   minFraction  - minimal ration of accepted tracks
+  //   minStat      - minimal statistic (number of accepted tracks)
+  //   maxvd        - maximal deviation for the 1
+  // Output matrix:
+  //    columns    - Mean, Median, RMS
+  //    row        - parameter type (rotation[3], translation[3], drift[3])
+  if (!array) return 0;
+  if (array->GetEntries()<=0) return 0;
+  //  Int_t entries = array->GetEntries();
+  Int_t entriesFast = array->GetEntriesFast();
+  TVectorD state(9);
+  TVectorD *valArray[9];
+  for (Int_t i=0; i<9; i++){
+    valArray[i] = new TVectorD(entriesFast);
+  }
+  Int_t naccept=0;
+  for (Int_t ikalman=0; ikalman<entriesFast; ikalman++){
+    AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(ikalman);
+    if (!kalman) continue;
+    if (TMath::Abs(kalman->GetTPCvdCorr()-1)>maxvd) continue;
+    if (kalman->GetNUpdates()<minStat) continue;
+    if (Float_t(kalman->GetNUpdates())/Float_t(kalman->GetNTracks())<minFraction) continue;
+    kalman->GetState(state);
+    for (Int_t ipar=0; ipar<9; ipar++)
+      (*valArray[ipar])[naccept]=state[ipar];
+    naccept++;
+  }
+  //if (naccept<2) return 0;
+  if (naccept<1) return 0;
+  TMatrixD *pstat=new TMatrixD(9,3);
+  TMatrixD &stat=*pstat;
+  for (Int_t ipar=0; ipar<9; ipar++){
+    stat(ipar,0)=TMath::Mean(naccept, valArray[ipar]->GetMatrixArray());
+    stat(ipar,1)=TMath::Median(naccept, valArray[ipar]->GetMatrixArray());
+    stat(ipar,2)=TMath::RMS(naccept, valArray[ipar]->GetMatrixArray());
+  }
+  return pstat;
+}
+
+
+TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const array, const TMatrixD & stat, Bool_t direction, Float_t sigmaCut){
+  //
+  // Smooth the array of AliRelKalmanAlign - detector alignment and drift calibration)
+  // Input:
+  //   array     - input array
+  //   stat      - mean parameters statistic
+  //   direction - 
+  //   sigmaCut  - maximal allowed deviation from mean in terms of RMS 
+  if (!array) return 0;
+  if (array->GetEntries()<=0) return 0;
+  if (!(&stat)) return 0;
+  // error increase in 1 hour
+  const Double_t kerrsTime[9]={
+    0.00001,  0.00001, 0.00001,
+    0.001,    0.001,   0.001,
+    0.002,  0.01,   0.001};
+  //
+  //
+  Int_t entries = array->GetEntriesFast();
+  TObjArray *sArray= new TObjArray(entries);
+  AliRelAlignerKalman * sKalman =0;
+  TVectorD state(9);
+  for (Int_t i=0; i<entries; i++){
+    Int_t index=(direction)? entries-i-1:i;
+    AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(index);
+    if (!kalman) continue;
+    Bool_t isOK=kTRUE;
+    kalman->GetState(state);
+    for (Int_t ipar=0; ipar<9; ipar++){
+      if (TMath::Abs(state[ipar]-stat(ipar,1))>sigmaCut*stat(ipar,2)) isOK=kFALSE;
+    }
+    if (!sKalman &&isOK) {
+      sKalman=new AliRelAlignerKalman(*kalman);
+      sKalman->SetRejectOutliers(kFALSE);
+      sKalman->SetRunNumber(kalman->GetRunNumber());
+      sKalman->SetTimeStamp(kalman->GetTimeStamp());      
+    }
+    if (!sKalman) continue;
+    Double_t deltaT=TMath::Abs(Int_t(kalman->GetTimeStamp())-Int_t(sKalman->GetTimeStamp()))/3600.;
+    for (Int_t ipar=0; ipar<9; ipar++){
+//       (*(sKalman->GetStateCov()))(6,6)+=deltaT*errvd*errvd;
+//       (*(sKalman->GetStateCov()))(7,7)+=deltaT*errt0*errt0;
+//       (*(sKalman->GetStateCov()))(8,8)+=deltaT*errvy*errvy; 
+      (*(sKalman->GetStateCov()))(ipar,ipar)+=deltaT*kerrsTime[ipar]*kerrsTime[ipar];
+    }
+    sKalman->SetRunNumber(kalman->GetRunNumber());
+    if (!isOK) sKalman->SetRunNumber(0);
+    sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
+    if (!isOK) continue;
+    sKalman->SetRejectOutliers(kFALSE);
+    sKalman->SetRunNumber(kalman->GetRunNumber());
+    sKalman->SetTimeStamp(kalman->GetTimeStamp()); 
+    sKalman->Merge(kalman);
+    sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
+    //sKalman->Print();
+  }
+  return sArray;
+}
+
+TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const arrayP, TObjArray * const arrayM){
+  //
+  // Merge 2 RelKalman arrays
+  // Input:
+  //   arrayP    - rel kalman in direction plus
+  //   arrayM    - rel kalman in direction minus
+  if (!arrayP) return 0;
+  if (arrayP->GetEntries()<=0) return 0;
+  if (!arrayM) return 0;
+  if (arrayM->GetEntries()<=0) return 0;
+
+  Int_t entries = arrayP->GetEntriesFast();
+  TObjArray *array = new TObjArray(arrayP->GetEntriesFast()); 
+
+  for (Int_t i=0; i<entries; i++){
+     AliRelAlignerKalman * kalmanP = (AliRelAlignerKalman *) arrayP->UncheckedAt(i);
+     AliRelAlignerKalman * kalmanM = (AliRelAlignerKalman *) arrayM->UncheckedAt(i);
+     if (!kalmanP) continue;
+     if (!kalmanM) continue;
+  
+     AliRelAlignerKalman *kalman = NULL;
+     if(kalmanP->GetRunNumber() != 0 && kalmanM->GetRunNumber() != 0) {
+       kalman = new AliRelAlignerKalman(*kalmanP);
+       kalman->Merge(kalmanM);
+     }
+     else if (kalmanP->GetRunNumber() == 0) {
+       kalman = new AliRelAlignerKalman(*kalmanM);
+     }
+     else if (kalmanM->GetRunNumber() == 0) {
+       kalman = new AliRelAlignerKalman(*kalmanP);
+     }
+     else 
+       continue;
+
+     array->AddAt(kalman,i);
+  }
+
+  return array;
+}