]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCcalibLaser.cxx
more secure string operations
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibLaser.cxx
index 181b7781e43918cbd599c7b18c08df7cb3fcfc9e..e44f72c4f6d7c855687e70e48e49dbaca06817b9 100644 (file)
   //
   // To make laser scan the user interaction neccessary
   //
-  .x ~/UliStyle.C
+  .x ~/NimStyle.C
   gSystem->Load("libANALYSIS");
   gSystem->Load("libTPCcalib");
-  TFile fcalib("CalibObjects.root");
-  TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib");
-  AliTPCcalibLaser * laser = ( AliTPCcalibLaser *)array->FindObject("laserTPC");
-  laser->DumpMeanInfo(-0,0,10)
+  TFile fcalib("CalibObjectsTrain2.root");
+  AliTPCcalibLaser * laser = ( AliTPCcalibLaser *)fcalib->Get("laserTPC");
+  laser->DumpMeanInfo(run)
   TFile fmean("laserMean.root")
   //
   //  laser track clasification;
   //
   TCut cutT("cutT","abs(Tr.fP[3])<0.06");
-  TCut cutPt("cutPt","abs(Tr.fP[4])<0.1");
   TCut cutN("cutN","fTPCncls>70");
   TCut cutP("cutP","abs(atan2(x1,x0)-atan2(lx1,lx0))<0.03")
   TCut cutA = cutT+cutPt+cutP;
   gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
   gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+")
   AliXRDPROOFtoolkit tool;
+  AliXRDPROOFtoolkit::FilterList("laserDebug.list","* driftvN",1) 
+  TChain * chainDrift = tool.MakeChainRandom("laser.txt.Good","driftv",0,50);
+  chainDrift->Lookup();
+  TChain * chainDriftN = tool.MakeChainRandom("laserDebug.list.Good","driftvN",0,300);
+  chainDriftN->Lookup();
+
+
   TChain * chain = tool.MakeChain("laser.txt","Residuals",0,10200);
   chain->Lookup();
   TChain * chainFit = tool.MakeChain("laser.txt","FitModels",0,10200);
   chainFit->Lookup();
+  TChain * chainTrack = tool.MakeChainRandom("laser.txt","Track",0,30);
+  chainTrack->Lookup();
 
 */
 
 #include "TH2F.h"
 #include "TStatToolkit.h"
 #include "TROOT.h"
+#include "TDatabasePDG.h"
 
 
 #include "TTreeStream.h"
 #include "AliTPCLaserTrack.h"
 #include "AliTPCcalibDB.h"
 #include "AliTPCParam.h"
+#include "AliTPCParamSR.h"
+#include "TTimeStamp.h"
+#include "AliDCSSensorArray.h"
+#include "AliDCSSensor.h"
+#include "AliGRPObject.h"
 
 using namespace std;
 
@@ -123,11 +136,13 @@ ClassImp(AliTPCcalibLaser)
 AliTPCcalibLaser::AliTPCcalibLaser():
   AliTPCcalibBase(),
   fESD(0),
-  fESDfriend(),
+  fESDfriend(0),
+  fNtracks(0),
   fTracksMirror(336),
   fTracksEsd(336),
   fTracksEsdParam(336),
   fTracksTPC(336),
+  fFullCalib(kTRUE),
   fDeltaZ(336),
   fDeltaP3(336),
   fDeltaP4(336),
@@ -135,6 +150,7 @@ AliTPCcalibLaser::AliTPCcalibLaser():
   fDeltaPhiP(336),
   fSignals(336),
   //
+  fHisLaser(0),      //  N dim histogram of laser
   fHisNclIn(0),      //->Number of clusters inner
   fHisNclOut(0),     //->Number of clusters outer
   fHisNclIO(0),      //->Number of cluster inner outer
@@ -182,30 +198,58 @@ AliTPCcalibLaser::AliTPCcalibLaser():
   fDeltaZres(336),   //->2D histo fo residuals
   fDeltaYres2(336),   //->2D histo of residuals
   fDeltaZres2(336),   //->2D histo fo residuals
+  fDeltaYresAbs(336), //->2D histo of residuals
+  fHisYAbsErrors(0),  //-> total errors per beam in the abs res y analysis
+  fDeltaZresAbs(336), //->2D histo of residuals
+  fHisZAbsErrors(0),  //-> total errors per beam in the abs res z analysis
   //fDeltaYres3(336),   //->2D histo of residuals
   //fDeltaZres3(336),   //->2D histo fo residuals
-  fFitAside(new TVectorD(3)),
-  fFitCside(new TVectorD(3)),      
-  fFitACside(new TVectorD(4)),      
+  fFitAside(new TVectorD(5)),
+  fFitCside(new TVectorD(5)),      
+  fFitACside(new TVectorD(6)),      
   fEdgeXcuts(3),    
   fEdgeYcuts(3),    
   fNClCuts(5),      
-  fNcuts(0)        
+  fNcuts(0),
+  fBeamSectorOuter(336),
+  fBeamSectorInner(336),
+  fBeamOffsetYOuter(336),
+  fBeamSlopeYOuter(336),
+  fBeamOffsetYInner(336),
+  fBeamSlopeYInner(336),
+  fBeamOffsetZOuter(336),
+  fBeamSlopeZOuter(336),
+  fBeamOffsetZInner(336),
+  fBeamSlopeZInner(336),
+  fInverseSlopeZ(kTRUE),
+  fUseFixedDriftV(0),
+  fFixedFitAside0(0.0),
+  fFixedFitAside1(1.0),
+  fFixedFitCside0(0.0),
+  fFixedFitCside1(1.0)
 {
   //
   // Constructor
   //
   fTracksEsdParam.SetOwner(kTRUE);
+  for (Int_t i=0; i<336; i++) {
+    fFitZ[i]=0;
+    fCounter[i]=0;    //! counter of usage
+    fClusterCounter[i]=0; //!couter of clusters in "sensitive are"
+    fClusterSatur[i]=0;   //!couter of saturated clusters in "sensitive are"
+  }
 }
 
-AliTPCcalibLaser::AliTPCcalibLaser(const Text_t *name, const Text_t *title):
+AliTPCcalibLaser::AliTPCcalibLaser(const Text_t *name, const Text_t *title, Bool_t full):
   AliTPCcalibBase(),
   fESD(0),
   fESDfriend(0),
+  fNtracks(0),
   fTracksMirror(336),
   fTracksEsd(336),
   fTracksEsdParam(336),
   fTracksTPC(336),
+  fFullCalib(full),
   //
   fDeltaZ(336),          // array of histograms of delta z for each track
   fDeltaP3(336),          // array of histograms of delta z for each track
@@ -215,6 +259,7 @@ AliTPCcalibLaser::AliTPCcalibLaser(const Text_t *name, const Text_t *title):
   fSignals(336),           // array of dedx signals
   //
   //
+  fHisLaser(0),      //  N dim histogram of laser
   fHisNclIn(0),      //->Number of clusters inner
   fHisNclOut(0),     //->Number of clusters outer
   fHisNclIO(0),      //->Number of cluster inner outer
@@ -264,15 +309,35 @@ AliTPCcalibLaser::AliTPCcalibLaser(const Text_t *name, const Text_t *title):
   fDeltaZres(336),  
   fDeltaYres2(336),
   fDeltaZres2(336),  
+  fDeltaYresAbs(336),
+  fHisYAbsErrors(0),
+  fDeltaZresAbs(336),
+  fHisZAbsErrors(0),
   //  fDeltaYres3(336),
   //fDeltaZres3(336),  
-  fFitAside(new TVectorD(3)),        // drift fit - A side
-  fFitCside(new TVectorD(3)),        // drift fit - C- side
-  fFitACside(new TVectorD(4)),        // drift fit - AC- side
+  fFitAside(new TVectorD(5)),        // drift fit - A side
+  fFitCside(new TVectorD(5)),        // drift fit - C- side
+  fFitACside(new TVectorD(6)),        // drift fit - AC- side
   fEdgeXcuts(3),       // cuts in local x direction; used in the refit of the laser tracks
   fEdgeYcuts(3),       // cuts in local y direction; used in the refit of the laser tracks
   fNClCuts(5),         // cuts on the number of clusters per tracklet; used in the refit of the laser tracks
-  fNcuts(0)           // number of cuts
+  fNcuts(0),           // number of cuts
+  fBeamSectorOuter(336),
+  fBeamSectorInner(336),
+  fBeamOffsetYOuter(336),
+  fBeamSlopeYOuter(336),
+  fBeamOffsetYInner(336),
+  fBeamSlopeYInner(336),
+  fBeamOffsetZOuter(336),
+  fBeamSlopeZOuter(336),
+  fBeamOffsetZInner(336),
+  fBeamSlopeZInner(336),
+  fInverseSlopeZ(kTRUE),
+  fUseFixedDriftV(0),
+  fFixedFitAside0(0.0),
+  fFixedFitAside1(1.0),
+  fFixedFitCside0(0.0),
+  fFixedFitCside1(1.0)
 {
   SetName(name);
   SetTitle(title);
@@ -280,16 +345,24 @@ AliTPCcalibLaser::AliTPCcalibLaser(const Text_t *name, const Text_t *title):
   // Constructor
   //
   fTracksEsdParam.SetOwner(kTRUE);
+  for (Int_t i=0; i<336; i++) {
+    fFitZ[i]=0;
+    fCounter[i]=0;    //! counter of usage
+    fClusterCounter[i]=0; //!couter of clusters in "sensitive are"
+    fClusterSatur[i]=0;   //!couter of saturated clusters in "sensitive are"
+  }
 }
 
 AliTPCcalibLaser::AliTPCcalibLaser(const AliTPCcalibLaser& calibLaser):
   AliTPCcalibBase(calibLaser), 
   fESD(0),
   fESDfriend(0),
+  fNtracks(0),
   fTracksMirror(336),
   fTracksEsd(336),
   fTracksEsdParam(336),
   fTracksTPC(336),
+  fFullCalib(calibLaser.fFullCalib),
   //
   fDeltaZ(calibLaser.fDeltaZ),          // array of histograms of delta z for each track
   fDeltaP3(((calibLaser.fDeltaP3))),          // array of histograms of delta z for each track
@@ -299,6 +372,7 @@ AliTPCcalibLaser::AliTPCcalibLaser(const AliTPCcalibLaser& calibLaser):
   fSignals(((calibLaser.fSignals))),           // array of dedx signals
   //
   //
+  fHisLaser(0),      //  N dim histogram of laser
   fHisNclIn(new TH2F(*(calibLaser.fHisNclIn))),      //->Number of clusters inner
   fHisNclOut(new TH2F(*(calibLaser.fHisNclOut))),     //->Number of clusters outer
   fHisNclIO(new TH2F(*(calibLaser.fHisNclIO))),      //->Number of cluster inner outer
@@ -347,19 +421,45 @@ AliTPCcalibLaser::AliTPCcalibLaser(const AliTPCcalibLaser& calibLaser):
   fDeltaZres(((calibLaser.fDeltaZres))),  
   fDeltaYres2(((calibLaser.fDeltaYres))),
   fDeltaZres2(((calibLaser.fDeltaZres))),  
+  fDeltaYresAbs(((calibLaser.fDeltaYresAbs))),
+  fHisYAbsErrors(new TH1F(*(calibLaser.fHisYAbsErrors))),
+  fDeltaZresAbs(((calibLaser.fDeltaZresAbs))),
+  fHisZAbsErrors(new TH1F(*(calibLaser.fHisZAbsErrors))),
   //  fDeltaYres3(((calibLaser.fDeltaYres))),
   //fDeltaZres3(((calibLaser.fDeltaZres))),  
-  fFitAside(new TVectorD(3)),        // drift fit - A side
-  fFitCside(new TVectorD(3)),        // drift fit - C- side
-  fFitACside(new TVectorD(4)),        // drift fit - C- side
+  fFitAside(new TVectorD(5)),        // drift fit - A side
+  fFitCside(new TVectorD(5)),        // drift fit - C- side
+  fFitACside(new TVectorD(6)),        // drift fit - C- side
   fEdgeXcuts(3),       // cuts in local x direction; used in the refit of the laser tracks
   fEdgeYcuts(3),       // cuts in local y direction; used in the refit of the laser tracks
   fNClCuts(5),         // cuts on the number of clusters per tracklet; used in the refit of the laser tracks
-  fNcuts(0)           // number of cuts
+  fNcuts(0),           // number of cuts
+  fBeamSectorOuter(336),
+  fBeamSectorInner(336),
+  fBeamOffsetYOuter(336),
+  fBeamSlopeYOuter(336),
+  fBeamOffsetYInner(336),
+  fBeamSlopeYInner(336),
+  fBeamOffsetZOuter(336),
+  fBeamSlopeZOuter(336),
+  fBeamOffsetZInner(336),
+  fBeamSlopeZInner(336),
+  fInverseSlopeZ(calibLaser.fInverseSlopeZ),
+  fUseFixedDriftV(calibLaser.fUseFixedDriftV),
+  fFixedFitAside0(calibLaser.fFixedFitAside0),
+  fFixedFitAside1(calibLaser.fFixedFitAside1),
+  fFixedFitCside0(calibLaser.fFixedFitCside0),
+  fFixedFitCside1(calibLaser.fFixedFitCside1)
 {
   //
   // copy constructor
   //
+  for (Int_t i=0; i<336; i++) {
+    fFitZ[i]=0;
+    fCounter[i]=0;    //! counter of usage
+    fClusterCounter[i]=0; //!couter of clusters in "sensitive are"
+    fClusterSatur[i]=0;   //!couter of saturated clusters in "sensitive are"
+  }
 }
 
 
@@ -383,6 +483,7 @@ AliTPCcalibLaser::~AliTPCcalibLaser() {
   // destructor
   //
   if ( fHisNclIn){
+    delete fHisLaser;      //->
     delete fHisNclIn;      //->Number of clusters inner
     delete fHisNclOut;     //->Number of clusters outer
     delete fHisNclIO;      //->Number of cluster inner outer
@@ -426,6 +527,38 @@ AliTPCcalibLaser::~AliTPCcalibLaser() {
     delete fHisPz2vP2Out;  //-> Curv  P2outer - parabola
     delete fHisPz3vP2IO;   //-> Curv  P2outerinner - common parabola
   }
+  //
+  //
+  //
+  fDeltaZ.SetOwner();          //-> array of histograms of delta z for each track
+  fDeltaP3.SetOwner();         //-> array of histograms of P3      for each track
+  fDeltaP4.SetOwner();         //-> array of histograms of P4      for each track
+  fDeltaPhi.SetOwner();        //-> array of histograms of delta z for each track
+  fDeltaPhiP.SetOwner();       //-> array of histograms of delta z for each track
+  fSignals.SetOwner();         //->Array of dedx signals
+  
+  fDeltaZ.Delete();          //-> array of histograms of delta z for each track
+  fDeltaP3.Delete();         //-> array of histograms of P3      for each track
+  fDeltaP4.Delete();         //-> array of histograms of P4      for each track
+  fDeltaPhi.Delete();        //-> array of histograms of delta z for each track
+  fDeltaPhiP.Delete();       //-> array of histograms of delta z for each track
+  fSignals.Delete();         //->Array of dedx signals
+
+  fDeltaYres.SetOwner();
+  fDeltaYres.Delete();
+  delete fHisYAbsErrors;
+  fDeltaZres.SetOwner();
+  fDeltaZres.Delete();
+  delete fHisZAbsErrors;
+  fDeltaYres2.SetOwner();
+  fDeltaYres2.Delete();
+  fDeltaZres2.SetOwner();
+  fDeltaZres2.Delete();
+  
+  fDeltaYresAbs.SetOwner();
+  fDeltaYresAbs.Delete();
+  fDeltaZresAbs.SetOwner();
+  fDeltaZresAbs.Delete();
 }
 
 
@@ -435,7 +568,9 @@ void AliTPCcalibLaser::Process(AliESDEvent * event) {
   //
   // Loop over tracks and call  Process function
   //
-  Int_t kMinTracks=20;
+  const Int_t  kMinTracks=20;
+  const Int_t  kMinClusters=40;
+
   fESD = event;
   if (!fESD) {
     return;
@@ -446,6 +581,22 @@ void AliTPCcalibLaser::Process(AliESDEvent * event) {
   }
   if (fESD->GetNumberOfTracks()<kMinTracks) return; //not enough tracks
   AliDebug(4,Form("Event number in current file: %d",event->GetEventNumberInFile()));
+  //
+  // find CE background if present
+  //
+  if (AliTPCLaserTrack::GetTracks()==0) AliTPCLaserTrack::LoadTracks();
+  TH1D hisCE("hhisCE","hhisCE",100,-100,100);  
+  for (Int_t i=0;i<fESD->GetNumberOfTracks();++i) {
+    AliESDtrack *track=fESD->GetTrack(i);
+    if (!track) continue;
+    hisCE.Fill(track->GetZ());
+    hisCE.Fill(track->GetZ()+2);
+    hisCE.Fill(track->GetZ()-2);
+  }
+  //
+  //
+
+
   fTracksTPC.Clear();
   fTracksEsd.Clear();
   fTracksEsdParam.Delete();
@@ -454,31 +605,39 @@ void AliTPCcalibLaser::Process(AliESDEvent * event) {
     fClusterCounter[id]=0;
     fClusterSatur[id]=0;
   }
-  static Bool_t init=kFALSE;
-  if (!init){
-    init = kTRUE;  // way around for PROOF - to be investigated
-    MakeFitHistos();
-  }
   //
   Int_t n=fESD->GetNumberOfTracks();
   Int_t counter=0;
   for (Int_t i=0;i<n;++i) {
     AliESDfriendTrack *friendTrack=fESDfriend->GetTrack(i);
+    if (!friendTrack) continue;
     AliESDtrack *track=fESD->GetTrack(i);
+    if (!track) continue;
+    Double_t binC = hisCE.GetBinContent(hisCE.FindBin(track->GetZ()));
+    if (binC>336) continue; //remove CE background
     TObject *calibObject=0;
     AliTPCseed *seed=0;
     for (Int_t j=0;(calibObject=friendTrack->GetCalibObject(j));++j)
       if ((seed=dynamic_cast<AliTPCseed*>(calibObject)))
        break;
-    if (track&&seed) {
+    if (track&&seed&&track->GetTPCNcls()>kMinClusters && seed->GetNumberOfClusters() >kMinClusters) {
+      //filter CE tracks
       Int_t id = FindMirror(track,seed);
-      if (id>0) counter++;
+      if (id>=0) counter++;
     }
     //
-  }  
+  } 
+  fNtracks=counter;
   if (counter<kMinTracks) return;
 
-  FitDriftV();
+  //FitDriftV();
+  FitDriftV(0.2);
+  if (!fFullCalib) return;
+  static Bool_t init=kFALSE;
+  if (!init){
+    init = kTRUE;  // way around for PROOF - to be investigated
+    MakeFitHistos();
+  }
   //
   for (Int_t id=0; id<336; id++){    
     //
@@ -502,6 +661,7 @@ void AliTPCcalibLaser::MakeDistHisto(Int_t id){
     //
     if (!fTracksEsdParam.At(id)) return;
     if (!AcceptLaser(id)) return;
+    Double_t xhis[12]={0,0,0,0,0,0,0,0,0,0,0,0};
     //
     //
     TH1F * hisdz = (TH1F*)fDeltaZ.At(id);
@@ -538,7 +698,21 @@ void AliTPCcalibLaser::MakeDistHisto(Int_t id){
     if (hisdphi) hisdphi->Fill(dphi);
     if (hisdphiP) hisdphiP->Fill(dphiP);
     if (hisSignal) hisSignal->Fill(TMath::Sqrt(TMath::Abs(track->GetTPCsignal())));
+    // fill HisLaser
+    xhis[0] = ltrp->GetId();
+    xhis[1] = ltrp->GetSide();
+    xhis[2] = ltrp->GetRod();
+    xhis[3] = ltrp->GetBundle();
+    xhis[4] = ltrp->GetBeam();
+    xhis[5] = dphi;
+    xhis[6] = fFitZ[id];
+    xhis[7] = param->GetParameter()[2]-ltrp->GetParameter()[2]; //dp2
+    xhis[8] = param->GetParameter()[3]-ltrp->GetParameter()[3]; //dp3
+    xhis[9] = param->GetParameter()[4];
+    xhis[10]= track->GetTPCNcls();
+    xhis[11]= TMath::Sqrt(TMath::Abs(track->GetTPCsignal()));
     // }
+    fHisLaser->Fill(xhis);
 }
 
 void AliTPCcalibLaser::FitDriftV(){
@@ -585,8 +759,7 @@ void AliTPCcalibLaser::FitDriftV(){
   TVectorD fitA(3),fitC(3),fitAC(4);
   
   AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
-  AliTPCParam  * tpcparam    = calib->GetParameters(); 
-   
+  AliTPCParam  * tpcparam    = calib->GetParameters();    
   //
   for (Int_t id=0; id<336; id++) fFitZ[id]=0;
 
@@ -649,7 +822,14 @@ void AliTPCcalibLaser::FitDriftV(){
       fdriftA.GetParameters(fitA);
       npointsA= fdriftA.GetNpoints();
       chi2A = fdriftA.GetChisquare()/fdriftA.GetNpoints();
-      if (chi2A<kChi2Cut ||(*fFitAside)[0]==0 ) (*fFitAside) = fitA;
+      if (chi2A<kChi2Cut ||(*fFitAside)[0]==0 ) {
+       if (fFitAside->GetNoElements()<5) fFitAside->ResizeTo(5);
+       (*fFitAside)[0] = fitA[0];
+       (*fFitAside)[1] = fitA[1];
+       (*fFitAside)[2] = fitA[2];
+       (*fFitAside)[3] = fdriftA.GetNpoints();
+       (*fFitAside)[4] = chi2A;        
+      }
     }
     if (fdriftC.GetNpoints()>10){
       fdriftC.Eval();
@@ -659,7 +839,14 @@ void AliTPCcalibLaser::FitDriftV(){
       fdriftC.GetParameters(fitC);
       npointsC= fdriftC.GetNpoints();
       chi2C = fdriftC.GetChisquare()/fdriftC.GetNpoints();
-      if (chi2C<kChi2Cut||(*fFitCside)[0]==0) (*fFitCside) = fitC;
+      if (chi2C<kChi2Cut||(*fFitCside)[0]==0) {        
+       if (fFitCside->GetNoElements()<5) fFitCside->ResizeTo(5);
+       (*fFitCside)[0] = fitC[0];
+       (*fFitCside)[1] = fitC[1];
+       (*fFitCside)[2] = fitC[2];
+       (*fFitCside)[3] = fdriftC.GetNpoints();
+       (*fFitCside)[4] = chi2C;        
+      }
     }
 
     if (fdriftAC.GetNpoints()>10&&fdriftC.GetNpoints()>10&&fdriftA.GetNpoints()>10){
@@ -703,6 +890,21 @@ void AliTPCcalibLaser::FitDriftV(){
     }
     if (fStreamLevel>0){
       TTreeSRedirector *cstream = GetDebugStreamer();
+      TTimeStamp tstamp(fTime);
+      Float_t valuePressure0  = AliTPCcalibDB::GetPressure(tstamp,fRun,0);
+      Float_t valuePressure1 = AliTPCcalibDB::GetPressure(tstamp,fRun,1);
+      Double_t ptrelative0   = AliTPCcalibDB::GetPTRelative(tstamp,fRun,0);
+      Double_t ptrelative1   = AliTPCcalibDB::GetPTRelative(tstamp,fRun,1);
+      Double_t temp0         = AliTPCcalibDB::GetTemperature(tstamp,fRun,0);
+      Double_t temp1         = AliTPCcalibDB::GetTemperature(tstamp,fRun,1);
+      TVectorD vecGoofie(20);
+      AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(fRun);
+      if (goofieArray) 
+       for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
+         AliDCSSensor *gsensor = goofieArray->GetSensor(isensor);
+         if (gsensor) vecGoofie[isensor]=gsensor->GetValue(tstamp);
+       }
+
       if (cstream){
        (*cstream)<<"driftv"<<
          "run="<<fRun<<              //  run number
@@ -710,6 +912,16 @@ void AliTPCcalibLaser::FitDriftV(){
          "time="<<fTime<<            //  time stamp of event
          "trigger="<<fTrigger<<      //  trigger
          "mag="<<fMagF<<             //  magnetic field
+         // Environment values
+         "press0="<<valuePressure0<<
+         "press1="<<valuePressure1<<
+         "pt0="<<ptrelative0<<
+         "pt1="<<ptrelative1<<
+         "temp0="<<temp0<<
+         "temp1="<<temp1<<
+         "vecGoofie.="<<&vecGoofie<<
+         //
+         //
          "iter="<<iter<<
          "driftA.="<<fFitAside<<
          "driftC.="<<fFitCside<<
@@ -725,6 +937,346 @@ void AliTPCcalibLaser::FitDriftV(){
     }
   }
 }
+Bool_t  AliTPCcalibLaser::FitDriftV(Float_t minFraction){
+  //
+  // Fit corrections to the drift velocity - linear approximation in the z and global y
+  //The transfromatiom from the drift time to the z position done in AliTPCTracnsform class
+  // 
+  // Source of outlyers : 
+  // 0. Track in the saturation - postpeak
+  // 1. gating grid close the part of the signal for first bundle
+
+  // The robust fit is performed in 2 itterations /robust fraction controlled by kFraction/
+  // 1. Robust fit is used in the itteration number 0
+  // only fraction of laser used
+  // 2. Only the tracks close to the fit used in the second itteration
+  /*
+    Formulas:
+    
+    z  = s* (z0 - vd*(t-t0))
+    
+    s  - side -1 and +1 
+    t0 - time 0
+    vd - nominal drift velocity
+    zs - miscalibrated position
+    
+    zs = s*(z0 - vd*(1+vr)*(t-(t0+dt))
+    vr  - relative change of the drift velocity
+    dzt - vd*dt
+    dr  = zz0-s*z
+    ..
+    ==>
+    zs ~ z - s*vr*(z0-s*z)+s*dzt
+    --------------------------------
+    1. Correction function vr constant:
+    
+    
+    dz = zs-z = -s*vr *(z0-s*z)+s*dzt         
+    dzs/dl = dz/dl +s*s*vr*dz/dl 
+    d(dz/dl) = vr*dz/dl     
+  */
+  const Int_t   knLaser      = 336;     //n laser tracks
+  const Float_t kFraction[2] = {0.70,0.95};    // robust fit fraction
+
+  const Float_t kSaturCut    = 0.05;    // remove saturated lasers - cut on fraction of saturated 
+  const Float_t kDistCut     = 3.;      // distance sigma cut - 3 sigma
+  const Float_t kDistCutAbs  = 1.;      // absolute cut 1 cm
+  const Float_t kMinClusters = 40.;      // minimal amount of the clusters
+  const Float_t kMinSignal   = 2.5;      // minimal mean height of the signal
+  const Float_t kChi2Cut     = 1.0;     // chi2 cut to accept drift fit
+  //
+  static TLinearFitter fdriftA(3,"hyp2");
+  static TLinearFitter fdriftC(3,"hyp2");
+  static TLinearFitter fdriftAC(4,"hyp3");
+  TVectorD fitA(3),fitC(3),fitAC(4);
+  
+  AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
+  AliTPCParam  * tpcparam    = calib->GetParameters();    
+  //
+  // reset old data
+  //
+  for (Int_t id=0; id<336; id++) fFitZ[id]=0;
+  if (fFitAside->GetNoElements()<5) fFitAside->ResizeTo(5);
+  if (fFitCside->GetNoElements()<5) fFitCside->ResizeTo(5);
+  for (Int_t i=0;i<5; i++){
+    (*fFitCside)[i]=0;
+    (*fFitAside)[i]=0;
+  }
+  //
+  //
+  Float_t chi2A = 10;
+  Float_t chi2C = 10;
+  Float_t chi2AC = 10;
+  Int_t npointsA=0;
+  Int_t npointsC=0;
+  Int_t npointsAC=0;
+  Int_t nbA[4]={0,0,0,0};
+  Int_t nbC[4]={0,0,0,0};
+  TVectorD vecZM(336);      // measured z potion of laser
+  TVectorD vecA(336);       // accepted laser
+  TVectorD vecZF(336);      // fitted position  
+  TVectorD vecDz(336);      // deltaZ
+  TVectorD vecZS(336);      // surveyed position of laser
+  // additional variable to cut
+  TVectorD vecdEdx(336);    // dEdx
+  TVectorD vecSy(336);      // shape y
+  TVectorD vecSz(336);      // shape z
+  //
+  //
+  for (Int_t id=0; id<336; id++){
+    Int_t reject=0;
+    AliTPCLaserTrack *ltrp =
+      (AliTPCLaserTrack*)AliTPCLaserTrack::GetTracks()->UncheckedAt(id);
+    AliExternalTrackParam *param=(AliExternalTrackParam*)fTracksEsdParam.At(id);
+    AliTPCseed * seed = (AliTPCseed*)fTracksTPC.At(id);
+    vecZM(id)= (param==0) ? 0:param->GetZ();
+    vecZS(id)= ltrp->GetZ();
+    vecDz(id)= 0;
+    vecA(id)=1;
+    vecdEdx(id)=(seed)?seed->GetdEdx():0;
+    vecSy(id) =(seed)?seed->CookShape(1):0;
+    vecSz(id) =(seed)?seed->CookShape(2):0;
+    //
+    fFitZ[id]=0;
+    if (!fTracksEsdParam.At(id)) reject|=1;
+    if (!param) continue; 
+    if (!AcceptLaser(id))        reject|=2;
+    if ( fClusterSatur[id]>kSaturCut)  reject|=4;
+    if ( fClusterCounter[id]<kMinClusters)  reject|=8;
+    vecA(id)=reject;
+    if (reject>0) continue;
+    if (ltrp->GetSide()==0){
+      npointsA++;
+      nbA[ltrp->GetBundle()]++;
+    }
+    if (ltrp->GetSide()==1){
+      npointsC++;
+      nbC[ltrp->GetBundle()]++;
+    }
+  }
+  //
+  // reject  "bad events"
+  //
+  Bool_t isOK=kTRUE;
+  Int_t  naA=0;
+  Int_t  naC=0;
+  if (npointsA<minFraction*0.5*knLaser && npointsC<minFraction*0.5*knLaser)
+    isOK=kFALSE;
+  for (Int_t i=0;i<4;i++){
+    //count accepted for all layers
+    if (nbA[i]>minFraction*0.5*0.25*knLaser) naA++;
+    if (nbC[i]>minFraction*0.5*0.25*knLaser) naC++;
+  }
+  if (naA<3 &&naC<3) isOK=kFALSE;
+  if (isOK==kFALSE) return kFALSE;
+  
+  //
+  //
+  //
+  for (Int_t iter=0; iter<2; iter++){
+    fdriftA.ClearPoints();
+    fdriftC.ClearPoints();
+    fdriftAC.ClearPoints(); 
+    npointsA=0;  npointsC=0;  npointsAC=0;
+    //
+    for (Int_t id=0; id<336; id++){
+      if (!fTracksEsdParam.At(id)) continue;
+      if (!AcceptLaser(id)) continue;
+      if ( fClusterSatur[id]>kSaturCut)  continue;
+      if ( fClusterCounter[id]<kMinClusters)  continue;
+      AliESDtrack   *track    = (AliESDtrack*)fTracksEsd.At(id);
+      if (track->GetTPCsignal()<kMinSignal) continue;
+      AliExternalTrackParam *param=(AliExternalTrackParam*)fTracksEsdParam.At(id);
+      AliTPCLaserTrack *ltrp = ( AliTPCLaserTrack*)fTracksMirror.At(id);
+      Double_t xyz[3];
+      Double_t pxyz[3];
+      Double_t lxyz[3];
+      Double_t lpxyz[3];
+      param->GetXYZ(xyz);
+      param->GetPxPyPz(pxyz);
+      ltrp->GetXYZ(lxyz);
+      ltrp->GetPxPyPz(lpxyz);
+      Float_t sz = (ltrp->GetSide()==0) ? TMath::Sqrt(chi2A): TMath::Sqrt(chi2C);
+      //if (npointsAC>0) sz =TMath::Sqrt(chi2AC); 
+      if (iter>0 && TMath::Abs(fFitZ[id])>sz*kDistCut) continue;
+      if (iter>0 && TMath::Abs(fFitZ[id])>kDistCutAbs) continue;
+
+//       // drift distance
+//       Double_t zlength =  tpcparam->GetZLength(0);
+//       Double_t ldrift  = zlength-TMath::Abs(lxyz[2]);
+//       Double_t mdrift  = zlength-TMath::Abs(xyz[2]);
+      //
+      Double_t zlength = (ltrp->GetSide()==0)? tpcparam->GetZLength(36): tpcparam->GetZLength(71);
+      Double_t ldrift  = (ltrp->GetSide()==0)?zlength-lxyz[2]:lxyz[2]+zlength;
+      Double_t mdrift  = (ltrp->GetSide()==0)?zlength-xyz[2]:xyz[2]+zlength;
+
+
+      Double_t xxx[2] = {ldrift,lxyz[1]*ldrift/(zlength*250.)};
+      if (iter==0 &&ltrp->GetBundle()==0) continue;  
+      // skip bundle 0 - can be wrong in the 0 iteration
+      if (ltrp->GetSide()==0){
+       fdriftA.AddPoint(xxx,mdrift,1);
+      }else{
+       fdriftC.AddPoint(xxx,mdrift,1);
+      }
+      Double_t xxx2[3] = {ltrp->GetSide(), ldrift,lxyz[1]*ldrift/(zlength*250.)};
+      fdriftAC.AddPoint(xxx2,mdrift,1);
+    }
+    //
+    if (fdriftA.GetNpoints()>minFraction*0.5*knLaser){
+      //
+      fdriftA.Eval();
+      //if (iter==0) fdriftA.FixParameter(2,0); //fix global y gradient
+      npointsA= fdriftA.GetNpoints();
+      chi2A = fdriftA.GetChisquare()/fdriftA.GetNpoints();
+      fdriftA.EvalRobust(kFraction[iter]);
+      fdriftA.GetParameters(fitA);
+      if (chi2A<kChi2Cut ||(*fFitAside)[0]==0 ) {
+       if (fFitAside->GetNoElements()<5) fFitAside->ResizeTo(5);
+       (*fFitAside)[0] = fitA[0];
+       (*fFitAside)[1] = fitA[1];
+       (*fFitAside)[2] = fitA[2];
+       (*fFitAside)[3] = fdriftA.GetNpoints();
+       (*fFitAside)[4] = chi2A;        
+      }
+    }
+    if (fdriftC.GetNpoints()>minFraction*0.5*knLaser){
+      fdriftC.Eval();
+      //if (iter==0) fdriftC.FixParameter(2,0); //fix global y gradient
+      npointsC= fdriftC.GetNpoints();
+      chi2C = fdriftC.GetChisquare()/fdriftC.GetNpoints();
+      fdriftC.EvalRobust(kFraction[iter]);
+      fdriftC.GetParameters(fitC);
+      if (chi2C<kChi2Cut||(*fFitCside)[0]==0) {        
+       if (fFitCside->GetNoElements()<5) fFitCside->ResizeTo(5);
+       (*fFitCside)[0] = fitC[0];
+       (*fFitCside)[1] = fitC[1];
+       (*fFitCside)[2] = fitC[2];
+       (*fFitCside)[3] = fdriftC.GetNpoints();
+       (*fFitCside)[4] = chi2C;        
+      }
+    }
+
+    if (fdriftAC.GetNpoints()>minFraction*knLaser &&npointsA>0.5*minFraction*knLaser&&npointsC>0.5*minFraction*knLaser){
+      fdriftAC.Eval();
+      //if (iter==0) fdriftAC.FixParameter(2,0); //fix global y gradient
+      npointsAC= fdriftAC.GetNpoints();
+      chi2AC = fdriftAC.GetChisquare()/fdriftAC.GetNpoints();
+      fdriftAC.EvalRobust(kFraction[iter]);
+      fdriftAC.GetParameters(fitAC);
+      if (chi2AC<kChi2Cut||(*fFitACside)[0]==0) (*fFitACside) = fitAC;
+      (*fFitACside)[0] = fitAC[0];
+      (*fFitACside)[1] = fitAC[1];
+      (*fFitACside)[2] = fitAC[2];
+      (*fFitACside)[3] = fdriftAC.GetNpoints();
+      (*fFitACside)[4] = chi2AC;
+    }
+    
+    for (Int_t id=0; id<336; id++){
+      if (!fTracksEsdParam.At(id)) continue;
+      //
+      AliExternalTrackParam *param=(AliExternalTrackParam*)fTracksEsdParam.At(id);
+      AliTPCLaserTrack *ltrp = ( AliTPCLaserTrack*)fTracksMirror.At(id);
+      Double_t xyz[3];
+      Double_t pxyz[3];
+      Double_t lxyz[3];
+      Double_t lpxyz[3];
+      param->GetXYZ(xyz);
+      param->GetPxPyPz(pxyz);
+      ltrp->GetXYZ(lxyz);
+      ltrp->GetPxPyPz(lpxyz); 
+      //Double_t zlength =  tpcparam->GetZLength(0);
+      //Double_t ldrift = zlength-TMath::Abs(lxyz[2]);
+      //Double_t mdrift = zlength-TMath::Abs(xyz[2]);
+      Double_t zlength = (ltrp->GetSide()==0)? tpcparam->GetZLength(36): tpcparam->GetZLength(71);
+      Double_t ldrift  = (ltrp->GetSide()==0)?zlength-lxyz[2]:lxyz[2]+zlength;
+      Double_t mdrift  = (ltrp->GetSide()==0)?zlength-xyz[2]:xyz[2]+zlength;
+
+
+      Float_t fz =0;
+      if (ltrp->GetSide()==0){
+       fz = (fitA)[0]+(fitA)[1]*ldrift+(fitA)[2]*lxyz[1]*ldrift/(zlength*250.);
+      }else{
+       fz = (fitC)[0]+(fitC)[1]*ldrift+(fitC)[2]*lxyz[1]*ldrift/(zlength*250.);        
+      }
+      if (npointsAC>10){
+       //fz = (fitAC)[0]+(fitAC)[1]*ltrp->GetSide()+(fitAC)[2]*ldrift+(fitAC)[3]*lxyz[1]*ldrift/(zlength*250.);
+      }
+      fFitZ[id]=mdrift-fz;
+      vecZF[id]=fz;
+      vecDz[id]=mdrift-fz;
+    }
+    if (fStreamLevel>0){
+      TTreeSRedirector *cstream = GetDebugStreamer();
+      TTimeStamp tstamp(fTime);
+      Float_t valuePressure0  = AliTPCcalibDB::GetPressure(tstamp,fRun,0);
+      Float_t valuePressure1 = AliTPCcalibDB::GetPressure(tstamp,fRun,1);
+      Double_t ptrelative0   = AliTPCcalibDB::GetPTRelative(tstamp,fRun,0);
+      Double_t ptrelative1   = AliTPCcalibDB::GetPTRelative(tstamp,fRun,1);
+      Double_t temp0         = AliTPCcalibDB::GetTemperature(tstamp,fRun,0);
+      Double_t temp1         = AliTPCcalibDB::GetTemperature(tstamp,fRun,1);
+      TVectorD vecGoofie(20);
+      AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(fRun);
+      if (goofieArray) 
+       for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
+         AliDCSSensor *gsensor = goofieArray->GetSensor(isensor);
+         if (gsensor) vecGoofie[isensor]=gsensor->GetValue(tstamp);
+       }
+
+      if (cstream){
+       (*cstream)<<"driftvN"<<
+         "run="<<fRun<<              //  run number
+         "event="<<fEvent<<          //  event number
+         "time="<<fTime<<            //  time stamp of event
+         "trigger="<<fTrigger<<      //  trigger
+         "mag="<<fMagF<<             //  magnetic field
+         // Environment values
+         "press0="<<valuePressure0<<
+         "press1="<<valuePressure1<<
+         "pt0="<<ptrelative0<<
+         "pt1="<<ptrelative1<<
+         "temp0="<<temp0<<
+         "temp1="<<temp1<<
+         "vecGoofie.="<<&vecGoofie<<
+         //
+         //
+         "vecZM.="<<&vecZM<<   // measured z position
+         "vecZS.="<<&vecZS<<   // surveyed z position
+         "vecZF.="<<&vecZF<<   // fitted   z position
+         "vecDz.="<<&vecDz<<   // fitted   z position
+         "vecA.="<<&vecA<<     // accept laser flag
+         "vecdEdx.="<<&vecdEdx<<   // dEdx  - to cut on
+         "vecSy.="<<&vecSy<<       // shape y - to cut on
+         "vecSz.="<<&vecSz<<       // shape z - to cut on
+         //
+         "iter="<<iter<<
+         "driftA.="<<fFitAside<<
+         "driftC.="<<fFitCside<<
+         "driftAC.="<<fFitACside<<
+         "chi2A="<<chi2A<<
+         "chi2C="<<chi2C<<
+         "chi2AC="<<chi2AC<<
+         "nA="<<npointsA<<
+         "nC="<<npointsC<<
+         "nAC="<<npointsAC<<
+         "\n";
+       /*
+         //
+         variables to check in debug mode:
+         //
+         chainDriftN->SetAlias("driftS","250-abs(vecZS.fElements)");
+         chainDriftN->SetAlias("driftM","250-abs(vecZM.fElements)");
+         chainDriftN->SetAlias("driftF","vecZF.fElements");      
+         chainDriftN->SetAlias("deltaZ","driftF-driftM");  //deltaZ
+         TCut cutA="iter==1&&sqrt(chi2A)<0.1&&vecZS.fElements>0&&vecA.fElements==0";
+         TCut cutC="iter==1&&sqrt(chi2C)<0.1&&vecZS.fElements<0&&vecA.fElements==0";
+         
+        */
+      }
+    }
+  }
+  return kTRUE;
+}
 
 Float_t AliTPCcalibLaser::GetDistance(AliExternalTrackParam *param, AliTPCLaserTrack *ltrp){
   //
@@ -769,7 +1321,6 @@ Bool_t  AliTPCcalibLaser::AcceptLaser(Int_t id){
   TCut cutP1("cutP1","abs(LTr.fP[1]-Tr.fP[1])<30");
   TCut cutP2("cutP2","abs(LTr.fP[2]-Tr.fP[2])<0.03");
   TCut cutP3("cutP3","abs(Tr.fP[3])<0.05");
-  TCut cutP4("cutPt","abs(Tr.fP[4])<0.1");
 
   TCut cutA = cutP0+cutP1+cutP2+cutP3+cutP4;
   */
@@ -784,7 +1335,6 @@ Bool_t  AliTPCcalibLaser::AcceptLaser(Int_t id){
   if (TMath::Abs(param->GetParameter()[1]-ltrp->GetParameter()[1])>30) return kFALSE;    // cutZ -P1
   if (TMath::Abs(param->GetParameter()[2]-ltrp->GetParameter()[2])>0.03) return kFALSE;  // cut -P2
   if (TMath::Abs(param->GetParameter()[3])>0.05) return kFALSE;   // cut Tl -P3
-  if (TMath::Abs(param->GetParameter()[4])>0.1) return kFALSE;   // cut Pt  -P4
   //
   //
 
@@ -796,19 +1346,44 @@ Int_t  AliTPCcalibLaser::FindMirror(AliESDtrack *track, AliTPCseed *seed){
   // Find corresponding mirror
   // add the corresponding tracks
  
+  if (!track->GetOuterParam()) return -1;
 
   Float_t kRadius0  = 252;
-  Float_t kRadius   = 253.4;
+  Float_t kRadius   = 254.2;
+  Int_t countercl=0;
+  Float_t counterSatur=0;
+  Int_t csideA =0;
+  Int_t csideC =0;
+  for (Int_t irow=158;irow>-1;--irow) {
+    AliTPCclusterMI *c=seed->GetClusterPointer(irow);
+    if (!c) continue;
+    Double_t pedgeY = c->GetX()*TMath::DegToRad()*(10)-TMath::Abs(c->GetY());
+    Double_t pedgeX = TMath::Min((irow)*0.75, (159.-irow)*1.5);
+    if (pedgeY<3) continue;
+    if (pedgeX<3) continue;
+    countercl++;
+    if (c->GetDetector()%36<18) csideA++;
+    if (c->GetDetector()%36>=18) csideC++;
+    if (c->GetMax()>900) counterSatur++;
+  }
+  counterSatur/=(countercl+1);
+  //
+  //
+  //
+  if (csideA<0.9*seed->GetNumberOfClusters() && csideC<0.9*seed->GetNumberOfClusters()) return 0;  // cross laser track can not happen
+
+  Int_t side= 0;
+  if (csideC>0.5*seed->GetNumberOfClusters()) side=1;
+
 
-  if (!track->GetOuterParam()) return -1;
   AliExternalTrackParam param(*(track->GetOuterParam()));
-  AliTracker::PropagateTrackTo(&param,kRadius0,0.10566,3,kTRUE);
-  AliTracker::PropagateTrackTo(&param,kRadius,0.10566,0.1,kTRUE);
+  AliTracker::PropagateTrackTo(&param,kRadius0,TDatabasePDG::Instance()->GetParticle("mu+")->Mass(),3,kTRUE);
+  AliTracker::PropagateTrackTo(&param,kRadius,TDatabasePDG::Instance()->GetParticle("mu+")->Mass(),0.1,kTRUE);
   AliTPCLaserTrack ltr;
   AliTPCLaserTrack *ltrp=0x0;
   //  AliTPCLaserTrack *ltrpjw=0x0;
   //
-  Int_t id   = AliTPCLaserTrack::IdentifyTrack(&param);
+  Int_t id   = AliTPCLaserTrack::IdentifyTrack(&param,side);
  // Int_t idjw = AliTPCLaserTrack::IdentifyTrackJW(&param);
   //AliDebug(4,Form("Identified Track: %03d (%03d)",id,idjw));
 
@@ -817,30 +1392,19 @@ Int_t  AliTPCcalibLaser::FindMirror(AliESDtrack *track, AliTPCseed *seed){
   else
     ltrp=&ltr;
 
-  if (id<0) return id;
+  if (id<0) return -1;
+  if (ltrp->GetSide()!=side) return -1;
   fCounter[id]++;
   //
   //
   //
-  Int_t countercl=0;
-  Float_t counterSatur=0;
-  for (Int_t irow=158;irow>-1;--irow) {
-    AliTPCclusterMI *c=seed->GetClusterPointer(irow);
-    if (!c) continue;
-    Double_t pedgeY = c->GetX()*TMath::DegToRad()*(10)-TMath::Abs(c->GetY());
-    Double_t pedgeX = TMath::Min((irow)*0.75, (159.-irow)*1.5);
-    if (pedgeY<3) continue;
-    if (pedgeX<3) continue;
-    countercl++;
-    if (c->GetMax()>900) counterSatur++;
-  }
-  counterSatur/=(countercl+1);
   //
   if (counterSatur>fClusterSatur[id]) fClusterSatur[id]=counterSatur;
   //
   //
   Float_t radius=TMath::Abs(ltrp->GetX());
-  AliTracker::PropagateTrackTo(&param,radius,0.10566,0.01,kTRUE);
+  param.Rotate(ltrp->GetAlpha());
+  AliTracker::PropagateTrackTo(&param,radius,0.10566,0.01,kFALSE);
   //
   if (!fTracksMirror.At(id)) fTracksMirror.AddAt(ltrp,id);
   Bool_t accept=kTRUE;  
@@ -977,11 +1541,13 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
   //=============================================//
   // Linear Fitters for the Different Approaches //
   //=============================================//
-  //linear fit model in y and z; inner - outer sector
+  //linear fit model in y and z; inner - outer sector, combined with offset
   static TLinearFitter fy1I(2,"hyp1");
   static TLinearFitter fy1O(2,"hyp1");
   static TLinearFitter fz1I(2,"hyp1");
   static TLinearFitter fz1O(2,"hyp1");
+  static TLinearFitter fy1IO(3,"hyp2");
+  static TLinearFitter fz1IO(3,"hyp2");
   //quadratic fit model in y and z; inner - sector
   static TLinearFitter fy2I(3,"hyp2");
   static TLinearFitter fy2O(3,"hyp2");
@@ -1026,6 +1592,7 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
       TVectorD vecy1resOuter(2),vecz1resOuter(2); //pol1 fit parameters outer
       TVectorD vecy2resOuter(3),vecz2resOuter(3); //pol2 fit parameters outer
       TVectorD vecy4res(5),vecz4res(5);
+      TVectorD vecy1resIO(3),vecz1resIO(3);
       // cluster and track positions for each row - used for residuals
       TVectorD vecgX(159);        // global X
       TVectorD vecgY(159);        // global Y
@@ -1036,6 +1603,8 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
       TVectorD vecZkalman(159);  // z from kalman fit
       TVectorD vecY1(159);       // y from pol1 fit per ROC
       TVectorD vecZ1(159);       // z from pol1 fit per ROC
+      TVectorD vecY1IO(159);     // y from pol1 fit per ROC
+      TVectorD vecZ1IO(159);     // z from pol1 fit per ROC
       TVectorD vecY2(159);       // y from pol2 fit per ROC
       TVectorD vecZ2(159);       // z from pol2 fit per ROC
       TVectorD vecY4(159);       // y from sector fit
@@ -1049,6 +1618,8 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
       Double_t chi2I1y=0;       // chi2 of pol1 fit in y (inner)
       Double_t chi2O1z=0;       // chi2 of pol1 fit in z (outer)
       Double_t chi2O1y=0;       // chi2 of pol1 fit in y (outer)
+      Double_t chi2IO1z=0;       // chi2 of pol1 fit in z (outer)
+      Double_t chi2IO1y=0;       // chi2 of pol1 fit in y (outer)
       Double_t chi2I2z=0;       // chi2 of pol2 fit in z (inner)
       Double_t chi2I2y=0;       // chi2 of pol2 fit in y (inner)
       Double_t chi2O2z=0;       // chi2 of pol2 fit in z (outer)
@@ -1129,13 +1700,13 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
          for (Int_t drow=-1;drow<=1;drow++) {
            if (irow+drow<0) continue;
            if (irow+drow>158) continue;
-           AliTPCclusterMI *c=track->GetClusterPointer(irow);
-           if (!c) continue;
-           Int_t roc = static_cast<Int_t>(c->GetDetector());
+           AliTPCclusterMI *ccurrent=track->GetClusterPointer(irow);
+           if (!ccurrent) continue;
+           Int_t roc = static_cast<Int_t>(ccurrent->GetDetector());
            if ( roc!=innerSector && roc!=outerSector ) continue;
-           if (c->GetX()<10) continue;
-           if (c->GetY()==0) continue;
-           meanY+=c->GetY();
+           if (ccurrent->GetX()<10) continue;
+           if (ccurrent->GetY()==0) continue;
+           meanY+=ccurrent->GetY();
            sumY++;
          }
          if (sumY>0)  meanY/=sumY; 
@@ -1160,11 +1731,11 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
          vecClY[irow] = c->GetY();
          vecClZ[irow] = c->GetZ();
          //
-         Float_t gxyz[3];
-         c->GetGlobalXYZ(gxyz);
-         vecgX[irow]   = gxyz[0];
-         vecgY[irow]   = gxyz[1];
-         vecgZ[irow]   = gxyz[2];
+//       Float_t gxyz[3];
+//       c->GetGlobalXYZ(gxyz);
+//       vecgX[irow]   = gxyz[0];
+//       vecgY[irow]   = gxyz[1];
+//       vecgZ[irow]   = gxyz[2];
           //
           Double_t x = vecX[irow]-133.4; //reference is between IROC and OROC
           Double_t y = vecClY[irow];
@@ -1172,9 +1743,11 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
           //
          Double_t x2[2]={x,x*x};   //linear and parabolic parameters
          Double_t x4[4]={0,0,0,0}; //hyp4 parameters
+          Double_t xIO[2]={0,x};    //common linear + offset IROC-OROC
          if ( roc == innerSector ) {
              x4[0]=1; //offset inner - outer sector
              x4[1]=x; //slope parameter inner sector
+              xIO[0]=1;
          } else {
              x4[2]=x; //slope parameter outer sector
          }
@@ -1210,6 +1783,8 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
          }
          fy4.AddPoint(x4,y);
          fz4.AddPoint(x4,z);
+          fy1IO.AddPoint(xIO,y);
+          fz1IO.AddPoint(xIO,z);
       }
       if (nclI>0)  {
        msigmaYIn/=nclI;
@@ -1265,6 +1840,16 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              fz4.GetParameters(vecz4res);
              chi2IOz=fz4.GetChisquare()/(fz4.GetNpoints()-5);
          }
+          if (fy1IO.GetNpoints()>0) {
+            fy1IO.Eval();
+            fy1IO.GetParameters(vecy1resIO);
+            chi2IO1y=fy1IO.GetChisquare()/(fy1IO.GetNpoints()-3);
+          }
+          if (fz1IO.GetNpoints()>0) {
+            fz1IO.Eval();
+            fz1IO.GetParameters(vecz1resIO);
+            chi2IO1z=fz1IO.GetChisquare()/(fz1IO.GetNpoints()-3);
+          }
       }
       //clear points
       fy4.ClearPoints();  fz4.ClearPoints();
@@ -1272,6 +1857,7 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
       fz1I.ClearPoints(); fz1O.ClearPoints();
       fy2I.ClearPoints(); fy2O.ClearPoints();
       fz2I.ClearPoints(); fz2O.ClearPoints();
+      fy1IO.ClearPoints(); fz1IO.ClearPoints();
       //==============================//
       // calculate tracklet positions //
       //==============================//
@@ -1308,6 +1894,8 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
           //
           Double_t yoffInner=0;
           Double_t zoffInner=0;
+          Double_t yoffInner1=0;
+          Double_t zoffInner1=0;
           Double_t yslopeInner=0;
           Double_t yslopeOuter=0;
           Double_t zslopeInner=0;
@@ -1328,10 +1916,14 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
               vecY2[irow]=vecy2resInner[0]+vecy2resInner[1]*xref+vecy2resInner[2]*xref*xref;
               vecZ2[irow]=vecz2resInner[0]+vecz2resInner[1]*xref+vecz2resInner[2]*xref*xref;
               yoffInner=vecy4res[1];
-             zoffInner=vecz4res[1];
+              zoffInner=vecz4res[1];
+              yoffInner1=vecy1resIO[1];
+              zoffInner1=vecz1resIO[1];
               yslopeInner=vecy4res[2];
              zslopeInner=vecz4res[2];
          }
+          vecY1IO[irow]=vecy1resIO[0]+yoffInner1+vecy1resIO[2]*xref;
+          vecZ1IO[irow]=vecz1resIO[0]+zoffInner1+vecz1resIO[2]*xref;
          vecY4[irow]=vecy4res[0]+yoffInner+yslopeInner*xref+yslopeOuter*xref+vecy4res[4]*xref*xref;
          vecZ4[irow]=vecz4res[0]+zoffInner+zslopeInner*xref+zslopeOuter*xref+vecz4res[4]*xref*xref;
           //positions of kalman fits
@@ -1375,9 +1967,11 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              "dEdx="       << dedx <<
              "LTr.="       << ltrp <<
              "Tr.="        << extparam <<
-             "yPol1In.="   << &vecy1resInner <<
-             "zPol1In.="   << &vecz1resInner <<
-             "yPol2In.="   << &vecy2resInner <<
+              "yPol1In.="   << &vecy1resInner <<
+              "zPol1In.="   << &vecz1resInner <<
+              "yPol1InOut.="<< &vecy1resIO <<
+              "zPol1InOut.="<< &vecz1resIO <<
+              "yPol2In.="   << &vecy2resInner <<
              "zPol2In.="   << &vecz2resInner <<
              "yPol1Out.="  << &vecy1resOuter <<
              "zPol1Out.="  << &vecz1resOuter <<
@@ -1385,9 +1979,11 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              "zPol2Out.="  << &vecz2resOuter <<
              "yInOut.="    << &vecy4res <<
              "zInOut.="    << &vecz4res <<
-             "chi2y1In="   << chi2I1y <<
-             "chi2z1In="   << chi2I1z <<
-             "chi2y1Out="  << chi2O1y <<
+              "chi2y1In="   << chi2I1y <<
+              "chi2z1In="   << chi2I1z <<
+              "chi2y1InOut="<< chi2IO1y <<
+              "chi2z1InOut="<< chi2IO1z <<
+              "chi2y1Out="  << chi2O1y <<
              "chi2z1Out="  << chi2O1z <<
              "chi2y2In="   << chi2I2y <<
              "chi2z2In="   << chi2I2z <<
@@ -1439,9 +2035,11 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              "TrZpol1.="   << &vecZ1 <<
              "TrYpol2.="   << &vecY2 <<
              "TrZpol2.="   << &vecZ2 <<
-             "TrYInOut.="  << &vecY4 <<
-             "TrZInOut.="  << &vecZ4 <<
-             "ClY.="       << &vecClY <<
+              "TrYpol1InOut.="<< &vecY1IO <<
+              "TrZpol1InOut.="<< &vecZ1IO <<
+              "TrYInOut.="  << &vecY4 <<
+              "TrZInOut.="  << &vecZ4 <<
+              "ClY.="       << &vecClY <<
              "ClZ.="       << &vecClZ <<
              "isReject.="  << &isReject<<
              "sec.="       << &vecSec <<
@@ -1462,7 +2060,9 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              "chi2z1In="   << chi2I1z <<
              "chi2y1Out="  << chi2O1y <<
              "chi2z1Out="  << chi2O1z <<
-             "chi2y2In="   << chi2I2y <<
+              "chi2y1InOut="<< chi2IO1y <<
+              "chi2z1InOut="<< chi2IO1z <<
+              "chi2y2In="   << chi2I2y <<
              "chi2z2In="   << chi2I2z <<
              "chi2y2Out="  << chi2O2y <<
              "chi2z2Out="  << chi2O2z <<
@@ -1475,7 +2075,9 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
              "zPol2In.="   << &vecz2resInner <<
              "yPol1Out.="  << &vecy1resOuter <<
              "zPol1Out.="  << &vecz1resOuter <<
-             "yPol2Out.="  << &vecy2resOuter <<
+              "yPol1InOut.="<< &vecy1resIO <<
+              "zPol1InOut.="<< &vecz1resIO <<
+              "yPol2Out.="  << &vecy2resOuter <<
              "zPol2Out.="  << &vecz2resOuter <<
 
              "\n";
@@ -1491,32 +2093,101 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
       TH2F *profz = (TH2F*)fDeltaZres.UncheckedAt(id);
       TH2F *profy2 = (TH2F*)fDeltaYres2.UncheckedAt(id);
       TH2F *profz2 = (TH2F*)fDeltaZres2.UncheckedAt(id);
+      TH2F *profyabs = (TH2F*)fDeltaYresAbs.UncheckedAt(id);
+      TH2F *profzabs = (TH2F*)fDeltaZresAbs.UncheckedAt(id);
       //      TH2F *profy3 = (TH2F*)fDeltaYres3.UncheckedAt(id);
       //TH2F *profz3 = (TH2F*)fDeltaZres3.UncheckedAt(id);
       //
       for (Int_t irow=158;irow>-1;--irow) {
        if (vecSec[irow]==-1)continue; // no cluster info
        if (isReject[irow]>0.5) continue;  // 
-       //Double_t x    = vecX[irow];
        Double_t ycl  = vecClY[irow];
        Double_t yfit = vecY1[irow];
        Double_t yfit2 = vecY2[irow];
+       Double_t x    = vecX[irow];
+       Double_t yabsbeam = -1000;
+       if(vecSec[irow]==outerSector && outerSector==fBeamSectorOuter[id])
+         yabsbeam = fBeamSlopeYOuter[id]*x + fBeamOffsetYOuter[id];
+       else if(innerSector==fBeamSectorInner[id])
+         yabsbeam = fBeamSlopeYInner[id]*x + fBeamOffsetYInner[id];
+
        //      Double_t yfit3 = vecY2[irow];
        Double_t zcl  = vecClZ[irow];
        Double_t zfit = vecZ1[irow];
        Double_t zfit2 = vecZ2[irow];
        //Double_t zfit3 = vecZ2[irow];
 
+       // dz abs 
+       // The expressions for zcorrected has been obtained by
+       // inverting the fits in the FitDriftV() method (ignoring the
+       // global y dependence for now):
+       // A side:
+       // 250 - zmeasured = [0] + [1]*(250 - zreal) + .... (yglobal)
+       // =>
+       // zreal = (zmeasured + [0] - (1-[1])*250.0)/[1]
+       // 
+       // C side:
+       // 250 + zmeasured  = [0] + [1]*(250+zreal) + .... (yglobal)
+       // =>
+       // zreal = (zmeasured - [0] + (1 - [1])*250.0)/[1]
+
+       Double_t dzabs = -1000;
+       Double_t zcorrected = -1000;
+       if (ltrp->GetSide()==0){
+         if ((*fFitAside)[1]>0. || fUseFixedDriftV) { 
+           // ignore global y dependence for now
+           zcorrected = 0;         
+           if(!fUseFixedDriftV) 
+             zcorrected = (zcl + (*fFitAside)[0] - 
+                           (1.0-(*fFitAside)[1])*250.0)/(*fFitAside)[1];
+           else
+             zcorrected = (zcl + fFixedFitAside0 - 
+                           (1.0-fFixedFitAside1)*250.0)/fFixedFitAside1;
+           //      zcorrected = zcl;
+           if(vecSec[irow]==outerSector && outerSector==fBeamSectorOuter[id])
+             dzabs = zcorrected -fBeamSlopeZOuter[id]*x -fBeamOffsetZOuter[id];
+           else if(innerSector==fBeamSectorInner[id])
+             dzabs = zcorrected -fBeamSlopeZInner[id]*x -fBeamOffsetZInner[id];
+         }
+       } else {
+         if ((*fFitCside)[1]>0. || fUseFixedDriftV) {
+           
+           if(!fUseFixedDriftV) 
+             zcorrected = (zcl - (*fFitCside)[0] + 
+                           (1.0-(*fFitCside)[1])*250.0)/(*fFitCside)[1];
+           else
+             zcorrected = (zcl - fFixedFitCside0 + 
+                           (1.0-fFixedFitCside1)*250.0)/fFixedFitCside1;
+           
+           //      zcorrected = zcl;
+           if(vecSec[irow]==outerSector && outerSector==fBeamSectorOuter[id])
+             dzabs = zcorrected -fBeamSlopeZOuter[id]*x -fBeamOffsetZOuter[id];
+           else if(innerSector==fBeamSectorInner[id])
+             dzabs = zcorrected -fBeamSlopeZInner[id]*x -fBeamOffsetZInner[id];
+         }
+       }
+       
        if (TMath::Abs(yfit-ycl)<2&&TMath::Abs(zfit-zcl)<2){
          if (profy){       
              profy->Fill(irow,ycl-yfit);
              profy2->Fill(irow,ycl-yfit2);
+             if(yabsbeam<-100) {
+               fHisYAbsErrors->Fill(id);
+               //              profyabs->Fill(irow,-0.99);
+             } else
+               profyabs->Fill(irow,ycl-yabsbeam);
+
              //              profy3->Fill(irow,ycl-yfit3);
          }
          if (profz) {
              profz->Fill(irow,zcl-zfit);
              profz2->Fill(irow,zcl-zfit2);
              //profz3->Fill(irow,zcl-zfit3);
+             if(dzabs<-100) {
+
+               fHisZAbsErrors->Fill(id);
+             }else
+               profzabs->Fill(irow,dzabs);
          }
        }
       }
@@ -1585,7 +2256,7 @@ void AliTPCcalibLaser::RefitLaserJW(Int_t id){
 
 
 
-void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries){
+void AliTPCcalibLaser::DumpMeanInfo(Int_t run){
   //
   //  Dump information about laser beams
   //  isOK variable indicates usability of the beam  
@@ -1600,10 +2271,46 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
   const Float_t krmsCut1=0.16;
   const Float_t kmultiCut=2;
   const Float_t kcutP0=0.002;
+  AliMagF* magF=  dynamic_cast<AliMagF*> (TGeoGlobalMagField::Instance()->GetField());
+  Double_t xyz[3]={90,0,10};         // tmp. global position 
+  Double_t bxyz[3]={90,0,10};        // tmp. mag field  integral - cylindrical
+  Double_t bgxyz[3]={90,0,10};       // tmp. mag field  integral - local
   //
   AliTPCcalibLaser *laser = this;
   TTreeSRedirector *pcstream = new TTreeSRedirector("laserMean.root");
   TF1 fg("fg","gaus");
+  AliTPCParam  * tpcparam    = 0;   
+  // start set up for absolute residuals analysis
+  //
+  AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
+  tpcparam    = calib->GetParameters(); 
+  if (!tpcparam) tpcparam    = new AliTPCParamSR;
+  tpcparam->Update();
+  AliGRPObject *grp = AliTPCcalibDB::GetGRP(run);
+  Float_t current=0;
+  Float_t bfield      = 0, bz=0;
+
+  if (grp){
+    Float_t polarity = (grp->GetL3Polarity()>0) ? -1.:1;
+    current = grp->GetL3Current((AliGRPObject::Stats)0);
+    bfield = polarity*5*current/30000.;
+    bz = polarity*5*current/30000.;
+    printf("Run%d\tL3 current%f\tBz\t%f\n",run,current,bz);
+  }
+
+  SetBeamParameters(fBeamOffsetYOuter, fBeamSlopeYOuter, fBeamSectorOuter,0);
+  SetBeamParameters(fBeamOffsetYInner, fBeamSlopeYInner, fBeamSectorInner,1);
+  TLinearFitter lfabsyInner(2);
+  lfabsyInner.SetFormula("1 ++ x");
+  TLinearFitter lfabszInner(2);
+  lfabszInner.SetFormula("1 ++ x");
+
+  TLinearFitter lfabsyOuter(2);
+  lfabsyOuter.SetFormula("1 ++ x");
+  TLinearFitter lfabszOuter(2);
+  lfabszOuter.SetFormula("1 ++ x");
+  // end set up for absolute residuals analysis
+
   //
   //
   for (Int_t id=0; id<336; id++){
@@ -1623,6 +2330,7 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
      AliTPCLaserTrack::LoadTracks();
       ltrp =(AliTPCLaserTrack*)AliTPCLaserTrack::GetTracks()->UncheckedAt(id);
     }
+    ltrp->UpdatePoints();
     pcstream->GetFile()->cd();
     if (hisphi)  hisphi->Write();
     if (hisphiP) hisphiP->Write();
@@ -1637,24 +2345,33 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
     Float_t rmsphiP = hisphiP->GetRMS();
     Float_t meanZ = hisZ->GetMean();
     Float_t rmsZ = hisZ->GetRMS();
-    hisphi->Fit(&fg,"","",hisphi->GetMean()-4*hisphi->GetRMS(),hisphi->GetMean()+4*hisphi->GetRMS());
+    if (hisphi->GetRMS()>hisphi->GetBinWidth(1))
+      hisphi->Fit(&fg,"","",hisphi->GetMean()-4*hisphi->GetRMS(),hisphi->GetMean()+4*hisphi->GetRMS());
     Double_t gphi1 = fg.GetParameter(1);
     Double_t gphi2 = fg.GetParameter(2);
-    hisphiP->Fit(&fg,"","",hisphiP->GetMean()-4*hisphiP->GetRMS(),hisphiP->GetMean()+4*hisphiP->GetRMS());
+    if (hisphiP->GetRMS()>0)
+      hisphiP->Fit(&fg,"","",hisphiP->GetMean()-4*hisphiP->GetRMS(),hisphiP->GetMean()+4*hisphiP->GetRMS());
     Double_t gphiP1 = fg.GetParameter(1);
     Double_t gphiP2 = fg.GetParameter(2);
     //
-    hisZ->Fit(&fg,"","",hisZ->GetMean()-4*hisZ->GetRMS(),hisZ->GetMean()+4*hisZ->GetRMS());
+    if (hisZ->GetRMS()>hisZ->GetBinWidth(1))
+      hisZ->Fit(&fg,"","");
     Double_t gz1 = fg.GetParameter(1);
     Double_t gz2 = fg.GetParameter(2);
     //
-    hisP3->Fit(&fg,"","",hisP3->GetMean()-4*hisP3->GetRMS(),hisP3->GetMean()+4*hisP3->GetRMS());
+    if (hisP3->GetRMS()>hisP3->GetBinWidth(1))
+      hisP3->Fit(&fg,"","",hisP3->GetMean()-4*hisP3->GetRMS(),hisP3->GetMean()+4*hisP3->GetRMS());
     Double_t gp31 = fg.GetParameter(1);
     Double_t gp32 = fg.GetParameter(2);
+    Double_t meanp3 = hisP3->GetMean();
+    Double_t rmsp3  = hisP3->GetRMS();
     //
-    hisP4->Fit(&fg,"","",hisP4->GetMean()-4*hisP4->GetRMS(),hisP4->GetMean()+4*hisP4->GetRMS());
+    if (hisP4->GetRMS()>hisP4->GetBinWidth(1))
+      hisP4->Fit(&fg,"","",hisP4->GetMean()-4*hisP4->GetRMS(),hisP4->GetMean()+4*hisP4->GetRMS());
     Double_t gp41 = fg.GetParameter(1);
     Double_t gp42 = fg.GetParameter(2);
+    Double_t meanp4 = hisP4->GetMean();
+    Double_t rmsp4  = hisP4->GetRMS();
     //
     Float_t meanS=hisS->GetMean();
     //
@@ -1846,10 +2563,282 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
     Float_t  mPz3vP2IO  = his->GetMean();
     Float_t  rPz3vP2IO  = his->GetRMS();
     delete his;
+
+    // Fit absolute laser residuals
+    TH2F* histAbsY = (TH2F*)laser->fDeltaYresAbs[id];
+    TH2F* histAbsZ = (TH2F*)laser->fDeltaZresAbs[id];
+
+    Int_t secInner = TMath::Nint(fBeamSectorInner[id]); 
+    Int_t secOuter = TMath::Nint(fBeamSectorOuter[id]); 
+
+    TVectorD vecX(159);        // X
+    TVectorD vecY(159);        // Y
+    TVectorD vecR(159);        // R
+    TVectorD vecDY(159);       // absolute residuals in Y
+    TVectorD vecDZ(159);       // absolute residuals in Z
+    TVectorD vecN(159);        // number of clusters
+    TVectorD vecEy(159);       //error y
+    TVectorD vecEz(159);       //error z
+    TVectorD vecPhi(159);      // local tangent
+    TVectorD vecPhiR(159);     // local tangent
+    // magnetic field integrals
+    TVectorD vecIBR(159);        // radial
+    TVectorD vecIBRPhi(159);     // r-phi
+    TVectorD vecIBLX(159);       // local x
+    TVectorD vecIBLY(159);       // local y
+    TVectorD vecIBGX(159);       // local x
+    TVectorD vecIBGY(159);       // local y
+    TVectorD vecIBZ(159);        // z
+    //
+    for (Int_t irow=0;irow<159;irow++){
+      vecIBR[irow]=0;
+      vecIBRPhi[irow]=0;
+      vecIBLX[irow]=0;
+      vecIBLY[irow]=0;
+      vecIBGX[irow]=0;
+      vecIBGY[irow]=0;
+      vecIBZ[irow]=0;
+      Double_t gx    =(*(ltrp->fVecGX))[irow];
+      Double_t gy    =(*(ltrp->fVecGY))[irow];
+      Int_t    lsec  =TMath::Nint((*(ltrp->fVecSec))[irow]);
+      Double_t   ca  =TMath::Cos(TMath::Pi()*(lsec+0.5)/9.);
+      Double_t   sa  =TMath::Sin(TMath::Pi()*(lsec+0.5)/9.);
+      xyz[2]=(*(ltrp->fVecGZ))[irow];
+      xyz[0]=TMath::Sqrt(gx*gx+gy*gy);
+      xyz[1]=TMath::ATan2(gy,gx);
+      Double_t gxyz[3]={gx,gy,(*(ltrp->fVecGZ))[irow]};
+      if (magF){
+       magF->GetTPCIntCyl(xyz,bxyz);
+       magF->GetTPCInt(gxyz,bgxyz);
+       vecIBR[irow]=bxyz[0];
+       vecIBRPhi[irow]=bxyz[1];
+       //
+       vecIBGX[irow]=bgxyz[0];
+       vecIBGY[irow]=bgxyz[1];
+       //
+       vecIBLX[irow]=  bgxyz[0]*ca+bgxyz[1]*sa;
+       vecIBLY[irow]= -bgxyz[0]*sa+bgxyz[1]*ca;
+       //
+
+       vecIBZ[irow]=bxyz[2];
+      }
+    }
+
+
+    lfabsyInner.ClearPoints();    
+    lfabszInner.ClearPoints();    
+    lfabsyOuter.ClearPoints();    
+    lfabszOuter.ClearPoints();    
+    // dummy fit values
+    Int_t    nClInY         = 0;
+    Float_t  yAbsInOffset  = -100;
+    Float_t  yAbsInSlope   = -100;
+    Float_t  yAbsInDeltay  = -100;
+    Int_t    nClInZ         = 0;
+    Float_t  zAbsInOffset  = -100;
+    Float_t  zAbsInSlope   = -100;
+    Float_t  zAbsInDeltaz  = -100;
+    Int_t    nClOutY         = 0;
+    Float_t  yAbsOutOffset  = -100;
+    Float_t  yAbsOutSlope   = -100;
+    Float_t  yAbsOutDeltay  = -100;
+    Int_t    nClOutZ         = 0;
+    Float_t  zAbsOutOffset  = -100;
+    Float_t  zAbsOutSlope   = -100;
+    Float_t  zAbsOutDeltaz  = -100;
+
+    Float_t  lasTanPhiLocIn = -100;
+    Float_t  lasTanPhiLocOut = -100;
+
+    if(histAbsY && histAbsY->GetEntries()>0) {
+      
+      Double_t rotAngOut = 10;
+      Double_t rotAngIn = 10;
+      if((secInner%36)!=(secOuter%36))
+       rotAngIn += 20; // 30 degrees
+      
+      // Calculate laser mirror X position in local frame
+      Double_t laserposOut = 
+       TMath::Abs(ltrp->GetX()*TMath::Cos(rotAngOut*TMath::DegToRad()));
+      Double_t laserposIn = 
+       TMath::Abs(ltrp->GetX()*TMath::Cos(rotAngIn*TMath::DegToRad()));
+      
+      // Calculate laser tan phi in local frame
+      lasTanPhiLocOut  = TMath::ASin(ltrp->GetSnp());
+      if(lasTanPhiLocOut<0) {
+       lasTanPhiLocIn  = lasTanPhiLocOut - rotAngIn*TMath::DegToRad();
+       lasTanPhiLocOut -= rotAngOut*TMath::DegToRad();
+      } else {
+       
+       lasTanPhiLocIn  = lasTanPhiLocOut + rotAngIn*TMath::DegToRad();
+       lasTanPhiLocOut += rotAngOut*TMath::DegToRad();
+      }
+      
+      lasTanPhiLocIn = TMath::Tan(lasTanPhiLocIn);
+      lasTanPhiLocOut = TMath::Tan(lasTanPhiLocOut);
+      
+      TProfile* yprof  = histAbsY->ProfileX("yprof");
+      TProfile* zprof  = histAbsZ->ProfileX("zprof");
+      
+      for(Int_t bin = 1; bin<=159; bin++) {
+       
+       if(yprof->GetBinEntries(bin)<10&&
+          zprof->GetBinEntries(bin)<10) {
+         continue;     
+       }
+       
+       // There is a problem in defining inner and outer sectors for
+       // the outer beams (0 and 6) where both sectors are OROCs. To
+       // make sure there is no overlap row 94 to 99 are cutted.
+       if(((ltrp->GetBeam()==0)||(ltrp->GetBeam()==6))&&bin>=95&&bin<=100)
+         continue;
+       
+       Int_t row = (bin-1);
+       if(row>62)
+         row -= 63;
+
+       Bool_t isOuter = kTRUE;
+       Int_t sector = TMath::Nint(fBeamSectorOuter[id]);
+       
+       if(bin<=62 ||                                        
+          (((ltrp->GetBeam()==0)||(ltrp->GetBeam()==6))&&bin<=95)) {
+
+         isOuter = kFALSE;
+         sector = TMath::Nint(fBeamSectorInner[id]);
+       }
+
+
+       Double_t x = tpcparam->GetPadRowRadii(sector, row); // slope
+       vecN[bin-1] =yprof->GetBinEntries(bin);
+       vecEy[bin-1]=yprof->GetBinError(bin);
+       vecEz[bin-1]=zprof->GetBinError(bin);
+       vecX[bin-1] = x;
+       vecDY[bin-1] = yprof->GetBinContent(bin);
+       vecDZ[bin-1] = zprof->GetBinContent(bin);
+       if(!isOuter) { // inner   
+         vecPhi[bin-1]=lasTanPhiLocIn;
+         // Calculate local y from residual and database
+         Double_t y  = fBeamSlopeYInner[id]*x + fBeamOffsetYInner[id]
+           + vecDY[bin-1];
+         vecY[bin-1] = y;
+         Double_t r  = TMath::Sqrt(x*x + y*y);
+         vecR[bin-1] = r;
+         // Find angle between laser vector and R vector
+         // cos angle = (x,y).(1,fBeamSlopeYInner)/R/sqrt(1+fBeamSlopeYInner**2)
+         Double_t cosPhi = x + y*fBeamSlopeYInner[id];
+         cosPhi /= r*TMath::Sqrt(1+fBeamSlopeYInner[id]*fBeamSlopeYInner[id]);
+         vecPhiR[bin-1] = TMath::Tan(TMath::ACos(cosPhi));
+         if(lasTanPhiLocIn<0)
+           vecPhiR[bin-1]*=-1; // to have the same sign
+         
+         if(yprof->GetBinEntries(bin)>=10) {
+           lfabsyInner.AddPoint(&x, yprof->GetBinContent(bin), 
+                                 TMath::Max(yprof->GetBinError(bin), 0.001));
+         } 
+         if(zprof->GetBinEntries(bin)>=10) {
+           lfabszInner.AddPoint(&x, zprof->GetBinContent(bin), 
+                                 TMath::Max(zprof->GetBinError(bin), 0.001));
+         }
+       } else { // outer
+         vecPhi[bin-1]=lasTanPhiLocOut;          
+         // Calculate local y from residual and database
+         Double_t y  = fBeamSlopeYOuter[id]*x + fBeamOffsetYOuter[id]
+           + vecDY[bin-1];
+         vecY[bin-1] = y;
+         Double_t r  = TMath::Sqrt(x*x + y*y);
+         vecR[bin-1] = r;
+
+         Double_t cosPhi = x + y*fBeamSlopeYOuter[id];
+         cosPhi /= r*TMath::Sqrt(1+fBeamSlopeYOuter[id]*fBeamSlopeYOuter[id]);
+         vecPhiR[bin-1] = TMath::Tan(TMath::ACos(cosPhi));
+         if(lasTanPhiLocOut<0)
+           vecPhiR[bin-1]*=-1; // to have the same sign
+
+         if(yprof->GetBinEntries(bin)>=10) {
+           lfabsyOuter.AddPoint(&x, yprof->GetBinContent(bin), 
+                                 TMath::Max(yprof->GetBinError(bin), 0.001));
+         }
+         if(zprof->GetBinEntries(bin)>=10) {
+           lfabszOuter.AddPoint(&x, zprof->GetBinContent(bin), 
+                                 TMath::Max(zprof->GetBinError(bin), 0.001));
+         }
+       }
+       // global position
+       
+      }
+       
+      delete yprof; delete zprof;
+
+      
+      // Fit laser abs residuals with linear robust fit (exclude 5% outliers)
+      nClInY = lfabsyInner.GetNpoints();
+      if(lfabsyInner.GetNpoints()>10) {
+       lfabsyInner.EvalRobust(0.95);
+       
+       TVectorD result(2);
+       lfabsyInner.GetParameters(result);
+       yAbsInOffset = result[0];
+       yAbsInSlope  = result[1];
+       yAbsInDeltay = yAbsInSlope*laserposIn + yAbsInOffset;
+      }
+      nClInZ = lfabszInner.GetNpoints();
+      if(lfabszInner.GetNpoints()>10) {
+       lfabszInner.EvalRobust(0.95);
+       
+       TVectorD result(2);
+       lfabszInner.GetParameters(result);
+       zAbsInOffset = result[0];
+       zAbsInSlope  = result[1];
+       zAbsInDeltaz = zAbsInSlope*laserposIn + zAbsInOffset;
+      } 
+      nClOutY = lfabsyOuter.GetNpoints();
+      if(lfabsyOuter.GetNpoints()>10) {
+       lfabsyOuter.EvalRobust(0.95);
+       
+       TVectorD result(2);
+       lfabsyOuter.GetParameters(result);
+       yAbsOutOffset = result[0];
+       yAbsOutSlope  = result[1];
+       yAbsOutDeltay = yAbsOutSlope*laserposOut + yAbsOutOffset;
+      }
+      nClOutZ = lfabszOuter.GetNpoints();
+      if(lfabszOuter.GetNpoints()>10) {
+       lfabszOuter.EvalRobust(0.95);
+       
+       TVectorD result(2);
+       lfabszOuter.GetParameters(result);
+       zAbsOutOffset = result[0];
+       zAbsOutSlope  = result[1];
+       zAbsOutDeltaz = zAbsOutSlope*laserposOut + zAbsOutOffset;
+      }
+    }
+
     
+    Int_t itime=-1;
+    Float_t  coverIA=AliTPCcalibDB::GetCoverVoltage(run,0,itime);
+    Float_t  coverIC=AliTPCcalibDB::GetCoverVoltage(run,18,itime);
+    Float_t  coverOA=AliTPCcalibDB::GetCoverVoltage(run,36,itime);
+    Float_t  coverOC=AliTPCcalibDB::GetCoverVoltage(run,54,itime);
+    //
+    Float_t  skirtA=AliTPCcalibDB::GetSkirtVoltage(run,0,itime);
+    Float_t  skirtC=AliTPCcalibDB::GetSkirtVoltage(run,18,itime);
+    //
+    Float_t  ggOffA=AliTPCcalibDB::GetGGoffsetVoltage(run,0,itime);
+    Float_t  ggOffC=AliTPCcalibDB::GetGGoffsetVoltage(run,18,itime);
+
     //
     (*pcstream)<<"Mean"<<
       "run="<<run<<               //
+      //voltages
+      "UcIA="<<coverIA<<
+      "UcIC="<<coverIC<<
+      "UcOA="<<coverOA<<
+      "UcOC="<<coverOC<<
+      "UsA="<<skirtA<<
+      "UsC="<<skirtC<<
+      "UggA="<<ggOffA<<
+      "UggC="<<ggOffC<<
+      //
       "isOK="<<isOK<<             //
       "id="<<id<<                 // track id
       "entries="<<entries<<       // number of entries
@@ -1965,9 +2954,56 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
       //
       "gp31="<<gp31<<            //gaus mean - tgl
       "gp32="<<gp32<<            //gaus rms  -tgl
+      "meanp3="<<meanp3<<            //mean - tgl
+      "rmsp3="<<rmsp3<<            //rms  -tgl
       "gp41="<<gp41<<            //gaus mean - P4
       "gp42="<<gp42<<            //gaus rms  - P4
-
+      "meanp4="<<meanp4<<            //mean - P4
+      "rmsp4="<<rmsp4<<            //rms  - P4
+      // Parameters from abs res analysis
+      "SecIn="<<secInner<<              // inner sector
+      "SecOut="<<secOuter<<             // outer sector
+      "lasTanPhiLocIn="<<lasTanPhiLocIn<< // laser tan phi in local frame (inner)
+      "lasTanPhiLocOut="<<lasTanPhiLocOut<<// laser tan phi in local frame (outer)
+      "ibr.="<<&vecIBR<<   // radial filed integral
+      "ibrphi.="<<&vecIBRPhi<<   // r=phifiled integral
+      "ibr.="<<&vecIBR<<   // radial filed integral
+      "ibz.="<<&vecIBZ<<   // z filed integral
+      //
+      "iblx.="<<&vecIBLX<<   // local bx  integral
+      "ibly.="<<&vecIBLY<<   // local by integral
+      "ibgx.="<<&vecIBGX<<   // global bx  integral
+      "ibgy.="<<&vecIBGY<<   // global by integral
+      //
+      "X.="<<&vecX<<       // local x 
+      "Y.="<<&vecY<<       // local y 
+      "R.="<<&vecR<<       // radius 
+      "dY.="<<&vecDY<<     // abs y residuals
+      "dZ.="<<&vecDZ<<     // abs z residuals
+      "eY.="<<&vecEy<<     // error of y residuals
+      "eZ.="<<&vecEz<<     // error of z residuals
+      "kY.="<<&vecPhi<<    // local tangent y (fixed for sector)
+      "kYR.="<<&vecPhiR<<  // tangent between laser and R vector (varies inside sector) 
+      "nCl.="<<&vecN<<     // number of clusters
+      //
+      "nClInY="<<nClInY<<               // Number of clusters for inner y
+      "yAbsInOffset="<<yAbsInOffset<< // fitted offset absres (inner y)
+      "yAbsInSlope="<<yAbsInSlope <<  // fitted slope absres (inner y)
+      "yAbsInDeltay="<<yAbsInDeltay<< // fitted laser offset absres (inner y)
+      "nClInZ="<<nClInZ<<               // Number of clusters for inner z
+      "zAbsInOffset="<<zAbsInOffset<< // fitted offset absres (inner z)
+      "zAbsInSlope="<<zAbsInSlope <<  // fitted slope absres (inner z)
+      "zAbsInDeltaz="<<zAbsInDeltaz<< // fitted laser offset absres (inner z)
+      //
+      "nClOutY="<<nClOutY<<               // Number of clusters for outer y
+      "yAbsOutOffset="<<yAbsOutOffset<< // fitted offset absres (outer y)
+      "yAbsOutSlope="<<yAbsOutSlope <<  // fitted slope absres (outer y)
+      "yAbsOutDeltay="<<yAbsOutDeltay<< // fitted laser offset absres (outer y)
+      "nClOutZ="<<nClOutZ<<               // Number of clusters for outer z
+      "zAbsOutOffset="<<zAbsOutOffset<< // fitted offset absres (outer z)
+      "zAbsOutSlope="<<zAbsOutSlope <<  // fitted slope absres (outer z)
+      "zAbsOutDeltaz="<<zAbsOutDeltaz<< // fitted laser offset absres (outer z)
+      //
       "\n";
   }
   delete pcstream;
@@ -1983,7 +3019,7 @@ void AliTPCcalibLaser::DumpMeanInfo(Float_t bfield, Int_t run, Int_t minEntries)
 
 
 
-void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
+void AliTPCcalibLaser::DumpScanInfo(TTree * chain, const char * cutUser){
   //
   //
   //
@@ -2011,10 +3047,11 @@ void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
   Double_t pphi[3];
   Double_t pphiP[3];
   Double_t pmZ[3];
+  
   //
   for (Int_t id=0; id<336; id++){
     // id =205;
-    sprintf(cut,"isOK&&fId==%d",id);
+    snprintf(cut,1000,"fId==%d&&%s",id,cutUser);
     Int_t entries = chain->Draw("bz",cut,"goff");
     if (entries<3) continue;
     AliTPCLaserTrack *ltrp = 0;
@@ -2032,17 +3069,17 @@ void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
     //
     chain->Draw("gphi1",cut,"goff");
     memcpy(mphi, chain->GetV1(), entries*sizeof(Double_t));
-    chain->Draw("0.05*abs(mphi)+gphi2",cut,"goff");
+    chain->Draw("0.05*abs(mphi)+abs(gphi2)*0.5+0.05",cut,"goff");
     memcpy(smphi, chain->GetV1(), entries*sizeof(Double_t));
     //
     chain->Draw("gphiP1",cut,"goff");
     memcpy(mphiP, chain->GetV1(), entries*sizeof(Double_t));
-    chain->Draw("0.05*abs(mphiP)+gphiP2",cut,"goff");
+    chain->Draw("0.05*abs(mphiP)+abs(gphiP2)*0.5+0.001",cut,"goff");
     memcpy(smphiP, chain->GetV1(), entries*sizeof(Double_t));
     //
     chain->Draw("gz1",cut,"goff");
     memcpy(mZ, chain->GetV1(), entries*sizeof(Double_t));
-    chain->Draw("0.01*abs(meanZ)+gz2",cut,"goff");
+    chain->Draw("0.01*abs(meanZ)+abs(gz2)*0.5+0.1",cut,"goff");
     memcpy(smZ, chain->GetV1(), entries*sizeof(Double_t));
     //
     //
@@ -2051,6 +3088,16 @@ void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
     // store data  
     // phi
     f->cd("dirphi");
+    Float_t phiB0 =0;
+    Float_t phiPB0=0;
+    Float_t zB0=0;
+    for (Int_t ientry=0; ientry<entries; ientry++){
+      if (TMath::Abs(bz[ientry])<0.05){
+       phiB0  = mphi[ientry];
+       phiPB0 = mphiP[ientry];
+       zB0    = mZ[ientry];
+      }
+    }
     TGraphErrors *grphi = new TGraphErrors(entries,bz,mphi,sbz,smphi);
     grphi->Draw("a*");
     grphi->Fit(&fp);
@@ -2100,7 +3147,9 @@ void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
 
     gPad->SaveAs(Form("pic/z/z_%s.gif",grnamefull));
     grmZ->Write();
-    
+    //
+    // P4
+    //
 
     for (Int_t ientry=0; ientry<entries; ientry++){
       (*pcstream)<<"Mean"<<
@@ -2115,19 +3164,23 @@ void AliTPCcalibLaser::DumpScanInfo(TTree * chain){
        "lpx1="<<lpxyz[1]<<          // reference y
        "lpx2="<<lpxyz[2]<<          // refernece z            
        //values
+       "phiB0="<<phiB0<<          // position shift at 0 field
+       "phiPB0="<<phiPB0<<        // angular  shift at 0 field
+       "zB0="<<zB0<<              // z shift for 0 field
+       //
        "gphi1="<<mphi[ientry]<< // mean - from gaus fit
        "pphi0="<<pphi[0]<<   // offset
-       "pphi1="<<pphi[1]<<   // mean
+       "pphi1="<<pphi[1]<<   // slope
        "pphi2="<<pphi[2]<<   // norm chi2
        //
        "gphiP1="<<mphiP[ientry]<< // mean - from gaus fit
        "pphiP0="<<pphiP[0]<< // offset
-       "pphiP1="<<pphiP[1]<< // mean
+       "pphiP1="<<pphiP[1]<< // slope
        "pphiP2="<<pphiP[2]<< // norm chi2
        //
        "gz1="<<mZ[ientry]<<
        "pmZ0="<<pmZ[0]<<     // offset
-       "pmZ1="<<pmZ[1]<<     // mean
+       "pmZ1="<<pmZ[1]<<     // slope
        "pmZ2="<<pmZ[2]<<     // norm chi2
        "\n";
     }
@@ -2152,7 +3205,7 @@ Long64_t AliTPCcalibLaser::Merge(TCollection *li) {
   static Int_t counter0=0;
   while ((cal = (AliTPCcalibLaser*)iter->Next())) {
     if (!cal->InheritsFrom(AliTPCcalibLaser::Class())) {
-      Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
+      //      Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
       return -1;
     }
     printf("Marging number %d\n", counter0);
@@ -2228,19 +3281,28 @@ Long64_t AliTPCcalibLaser::Merge(TCollection *li) {
       // merge ProfileY histograms -0
       h2m = (TH2F*)cal->fDeltaYres.At(id);
       h2  = (TH2F*)fDeltaYres.At(id);
-      if (h2m) h2->Add(h2m);
+      if (h2m&&h2) h2->Add(h2m);
       //
       h2m = (TH2F*)cal->fDeltaZres.At(id);
       h2  = (TH2F*)fDeltaZres.At(id);
-      if (h2m) h->Add(h2m);
+      if (h2m&&h2) h2->Add(h2m);
       // merge ProfileY histograms - 2
       h2m = (TH2F*)cal->fDeltaYres2.At(id);
       h2  = (TH2F*)fDeltaYres2.At(id);
-      if (h2m) h2->Add(h2m);
+      if (h2m&&h2) h2->Add(h2m);
       //
       h2m = (TH2F*)cal->fDeltaZres2.At(id);
       h2  = (TH2F*)fDeltaZres2.At(id);
-      if (h2m) h->Add(h2m);
+      if (h2m&&h2) h2->Add(h2m);
+
+      // merge ProfileY histograms - abs
+      h2m = (TH2F*)cal->fDeltaYresAbs.At(id);
+      h2  = (TH2F*)fDeltaYresAbs.At(id);
+      if (h2m&&h2) h2->Add(h2m);
+
+      h2m = (TH2F*)cal->fDeltaZresAbs.At(id);
+      h2  = (TH2F*)fDeltaZresAbs.At(id);
+      if (h2m&&h2) h2->Add(h2m);
       // merge ProfileY histograms - 3
       //h2m = (TH2F*)cal->fDeltaYres3.At(id);
       //h2  = (TH2F*)fDeltaYres3.At(id);
@@ -2343,6 +3405,9 @@ void   AliTPCcalibLaser::MakeFitHistos(){
   fHisPz2vP2Out= new TH2F("HisPz2vP2Out","HisPz2vP2Out",336,0,336,500,-0.0002,0.0002);
   fHisPz3vP2IO = new TH2F("HisPz3vP2IO", "HisPz3vP2IO",336,0,336,500,-0.0002,0.0002);
   
+  fHisYAbsErrors = new TH1F("HisYabsErrors", "Errors per beam (y)", 336, 0, 336);
+  fHisZAbsErrors = new TH1F("HisZabsErrors", "Errors per beam (z)", 336, 0, 336);
+
   fHisNclIn->SetDirectory(0);      //->Number of clusters inner
   fHisNclOut->SetDirectory(0);     //->Number of clusters outer
   fHisNclIO->SetDirectory(0);      //->Number of cluster inner outer
@@ -2386,6 +3451,10 @@ void   AliTPCcalibLaser::MakeFitHistos(){
   fHisPz2vP2Out->SetDirectory(0);  //-> Curv  P2outer - parabola
   fHisPz3vP2IO->SetDirectory(0);   //-> Curv  P2outerinner - common parabola
 
+  fHisYAbsErrors->SetDirectory(0); //-> total errors per beam in the abs res y analysis
+  fHisZAbsErrors->SetDirectory(0); //-> total errors per beam in the abs res z analysis
+
+  
 
   //
   //
@@ -2393,8 +3462,11 @@ void   AliTPCcalibLaser::MakeFitHistos(){
   for (Int_t id=0; id<336;id++){
     TH2F *profy = (TH2F*)fDeltaYres.UncheckedAt(id);
     TH2F *profz = (TH2F*)fDeltaZres.UncheckedAt(id);
-    TH2F *profy2 = (TH2F*)fDeltaYres2.UncheckedAt(id);
+    //TH2F *profy2 = (TH2F*)fDeltaYres2.UncheckedAt(id);
+    TH2F *profy2 = 0;
     TH2F *profz2 = (TH2F*)fDeltaZres2.UncheckedAt(id);
+    TH2F *profyabs = (TH2F*)fDeltaYresAbs.UncheckedAt(id);
+    TH2F *profzabs = (TH2F*)fDeltaYresAbs.UncheckedAt(id);
     //    TH2F *profy3 = (TH2F*)fDeltaYres3.UncheckedAt(id);
     //TH2F *profz3 = (TH2F*)fDeltaZres3.UncheckedAt(id);
     if (!profy){
@@ -2404,6 +3476,12 @@ void   AliTPCcalibLaser::MakeFitHistos(){
       profy2=new TH2F(Form("pry%03d",id),Form("Y Residuals for Laser Beam %03d -Parabolic",id),160,0,160,50,-0.5,0.5);
       profy2->SetDirectory(0);
       fDeltaYres2.AddAt(profy2,id);
+      if(!fUseFixedDriftV)
+       profyabs=new TH2F(Form("pryabs%03d",id),Form("Y Residuals for Laser Beam %03d -Absolute",id),160,0,160,100,-1.0,1.0); // has to be bigger based on earlier studies
+      else
+       profyabs=new TH2F(Form("pryabs%03d",id),Form("Y Residuals for Laser Beam %03d -Absolute",id),160,0,160,200,-2.0,2.0); // has to be bigger based on earlier studies
+      profyabs->SetDirectory(0);
+      fDeltaYresAbs.AddAt(profyabs,id);
       //profy3=new TH2F(Form("pry%03d",id),Form("Y Residuals for Laser Beam %03d- Parabolic2",id),160,0,160,100,-0.5,0.5);
       //profy3->SetDirectory(0);
       //fDeltaYres3.AddAt(profy3,id);
@@ -2415,6 +3493,12 @@ void   AliTPCcalibLaser::MakeFitHistos(){
       profz2=new TH2F(Form("prz%03d",id),Form("Z Residuals for Laser Beam %03d - Parabolic",id),160,0,160,50,-0.5,0.5);
       profz2->SetDirectory(0);
       fDeltaZres2.AddAt(profz2,id);
+      if(!fUseFixedDriftV)
+       profzabs=new TH2F(Form("przabs%03d",id),Form("Z Residuals for Laser Beam %03d -Absolute",id),160,0,160,100,-1.0,1.0); // has to be bigger based on earlier studies
+      else
+       profzabs=new TH2F(Form("przabs%03d",id),Form("Z Residuals for Laser Beam %03d -Absolute",id),160,0,160,200,-2.0,2.0); // has to be bigger based on earlier studies
+      profzabs->SetDirectory(0);
+      fDeltaZresAbs.AddAt(profzabs,id);
       //profz3=new TH2F(Form("prz%03d",id),Form("Z Residuals for Laser Beam %03d- Parabolic2",id),160,0,160,100,-0.5,0.5);
       //profz3->SetDirectory(0);
       //fDeltaZres3.AddAt(profz3,id);
@@ -2424,7 +3508,8 @@ void   AliTPCcalibLaser::MakeFitHistos(){
   //
   for (Int_t id=0; id<336;id++){
     TH1F * hisdz = (TH1F*)fDeltaZ.At(id);
-    TH1F * hisP3 = (TH1F*)fDeltaP3.At(id);
+    //TH1F * hisP3 = (TH1F*)fDeltaP3.At(id);
+    TH1F * hisP3 = 0;
     TH1F * hisP4 = (TH1F*)fDeltaP4.At(id);
     
     TH1F * hisdphi = (TH1F*)fDeltaPhi.At(id);
@@ -2457,6 +3542,81 @@ void   AliTPCcalibLaser::MakeFitHistos(){
       fSignals.AddAt(hisSignal,id);
     }
   }
+
+  SetBeamParameters(fBeamOffsetZOuter, fBeamSlopeZOuter, fBeamSectorOuter,2);
+  SetBeamParameters(fBeamOffsetZInner, fBeamSlopeZInner, fBeamSectorInner,3);
+  SetBeamParameters(fBeamOffsetYOuter, fBeamSlopeYOuter, fBeamSectorOuter,0);
+  SetBeamParameters(fBeamOffsetYInner, fBeamSlopeYInner, fBeamSectorInner,1);
+  //
+  // Make THnSparse
+  //
+  //                   id   side   rod  bundle  beam  dP0  dP1  dP2  dP3  dP4 ncl dEdx 
+  Int_t binsLaser[12]= {336,  //id
+                       2,    //side
+                       6,    //rod
+                       4,    //bundle
+                       7,    //beam
+                       300,  //dP0
+                       300,  //dP1
+                       300,  //dP2
+                       300,  //dP3
+                       300,  //dP4
+                       80,   //ncl
+                       50};   //dEdx
+  Double_t xminLaser[12]= {0,  //id
+                       0,     //side
+                       0,     //rod
+                       0,     //bundle
+                       0,     //beam
+                       -1,    //dP0
+                       -1,    //dP1
+                       -0.01,   //dP2
+                       -0.01,  //dP3
+                       -0.1,  //dP4
+                       0,   //ncl
+                       0};   //sqrt dEdx
+  Double_t xmaxLaser[12]= {336,  //id
+                       2,    //side
+                       6,    //rod
+                       4,    //bundle
+                       7,    //beam
+                       1,  //dP0
+                       1,  //dP1
+                       0.01,  //dP2
+                       0.01,  //dP3
+                       0.1,  //dP4
+                       160,   //ncl
+                       40};   //sqrt dEdx
+  
+  TString nameLaser[12]= {"id",
+                         "side",
+                         "rod",
+                         "bundle",
+                         "beam",
+                         "dP0",
+                         "dP1",
+                         "dP2",
+                         "dP3",
+                         "dP4",
+                         "ncl",
+                         "sqrt dEdx"};
+  TString titleLaser[12]= {"id",
+                         "side",
+                         "rod",
+                         "bundle",
+                         "beam",
+                         "#Delta_{P0}",
+                         "#Delta_{P1}",
+                         "#Delta_{P2}",
+                         "#Delta_{P3}",
+                         "#Delta_{P4}",
+                         "N_{cl}",
+                         "#sqrt{dEdx}"};
+  fHisLaser = new THnSparseS("dLaser","#Delta_{Laser}", 12, binsLaser,xminLaser, xmaxLaser);
+  for (Int_t iaxis=1; iaxis<12; iaxis++){
+    fHisLaser->GetAxis(iaxis)->SetName(nameLaser[iaxis]);
+    fHisLaser->GetAxis(iaxis)->SetTitle(titleLaser[iaxis]);
+  }
 }
 
 void AliTPCcalibLaser::MergeFitHistos(AliTPCcalibLaser * laser){
@@ -2464,10 +3624,11 @@ void AliTPCcalibLaser::MergeFitHistos(AliTPCcalibLaser * laser){
   // Merge content of histograms 
   //
   // Only first histogram is checked - all other should be the same
+  if (fHisLaser &&laser->fHisLaser) fHisLaser->Add(laser->fHisLaser);
+
   if (!laser->fHisNclIn) return;  // empty histograms
   if (!fHisNclIn) MakeFitHistos();
   //
-  
   fHisNclIn->Add(laser->fHisNclIn  );      //->Number of clusters inner
   fHisNclOut->Add(laser->fHisNclOut  );     //->Number of clusters outer
   fHisNclIO->Add(laser->fHisNclIO  );      //->Number of cluster inner outer
@@ -2510,6 +3671,8 @@ void AliTPCcalibLaser::MergeFitHistos(AliTPCcalibLaser * laser){
   fHisPz2vP2In->Add(laser->fHisPz2vP2In  );   //-> Curv  P2inner - parabola
   fHisPz2vP2Out->Add(laser->fHisPz2vP2Out  );  //-> Curv  P2outer - parabola
   fHisPz3vP2IO->Add(laser->fHisPz3vP2IO  );   //-> Curv  P2outerinner - common parabola
+  fHisYAbsErrors->Add(laser->fHisYAbsErrors); //-> total errors per beam in the abs res y analysis
+  fHisZAbsErrors->Add(laser->fHisZAbsErrors); //-> total errors per beam in the abs res z analysis
   //
   //
   //
@@ -2789,6 +3952,88 @@ void AliTPCcalibLaser::DumpFitInfo(TTree * chainFit,Int_t id){
     
     delete pcstream;
   }
+}
+
+void AliTPCcalibLaser::SetBeamParameters(TVectorD& meanOffset,
+                                        TVectorD& meanSlope,
+                                        TVectorD& sectorArray,
+                                        Int_t option)
+{
+  // This method should ideally go in AliTPCLaser
+  // option == 0 (pads outer - closest to beam)
+  // option == 1 (pads inner)
+  // option == 2 (time outer)
+  // option == 3 (time inner)
+  Int_t nFailures = 0;
+
+  for(Int_t id = 0; id < 336; id++) {
+    
+    if (!AliTPCLaserTrack::GetTracks()) 
+      AliTPCLaserTrack::LoadTracks();
+    AliTPCLaserTrack *ltrp =
+      (AliTPCLaserTrack*)AliTPCLaserTrack::GetTracks()->UncheckedAt(id);
+    
+    AliExternalTrackParam trackParam(*ltrp);
+    
+    Double_t deltaangle = 10.0; // sector is 1/2 a sector away from mirror
+    if((option==1 || option==3)&& (ltrp->GetBeam()<=1 || ltrp->GetBeam()>=5))
+      deltaangle = 30.0; // inner sector is 1 sector further away from mirror
+    
+    Double_t angle = trackParam.GetAlpha();
+    if(angle<0)
+      angle += 2*TMath::Pi();
+    if(trackParam.GetSnp()>0) // track points to sector "before"
+      angle -= deltaangle*TMath::DegToRad();
+    else // track points to sector "after"
+      angle += deltaangle*TMath::DegToRad();
+    
+    Bool_t success = trackParam.Rotate(angle);
+    
+    if(!success) {
+      //      cout << "WARNING: Rotate failed for ID: " << id << endl;
+      nFailures++;
+    }
+    
+    angle *= TMath::RadToDeg();
+    
+    Int_t sector = TMath::Nint((angle-10.0)/20.0);
+    if(sector<0)
+      sector += 18;
+    else if(sector>=18)
+      sector -= 18;
+    if(ltrp->GetSide()==1) // C side
+      sector += 18;
+    if(option==0 || option==2)
+      sector += 36;
+    if((option==1||option==3)&&(ltrp->GetBeam()==0||ltrp->GetBeam()==6)) 
+      sector += 36;
+
+    sectorArray[id] = sector;
+
+    const Double_t x0 = 0;
+    
+    Double_t slopey  = TMath::Tan(TMath::ASin(trackParam.GetSnp()));
+    Double_t slopez  = trackParam.GetTgl();
+    //  One needs a factor sqrt(1+slopey**2) to take into account the
+    //  longer path length
+    slopez *= TMath::Sqrt(1.0 + slopey*slopey);    
+    if(fInverseSlopeZ) // wrong sign in database, should be fixed there
+      slopez *= -1;
+    //    Double_t offsetz = trackParam.GetZ();
+    Double_t offsety = trackParam.GetY() + slopey*(x0-trackParam.GetX());
+    Double_t offsetz = trackParam.GetZ() + slopez*(x0-trackParam.GetX());
+    if(option==2 || option==3) {
+      meanOffset[id] = offsetz; meanSlope[id] = slopez;
+    } else {
+      meanOffset[id] = offsety; meanSlope[id] = slopey;
+    }
+  }
+
+  if(nFailures>0)
+    AliWarning(Form("Rotate method failed %d times", nFailures));
+}
+
+
   /*
     TFile f("vscan.root");
    */  
@@ -2877,8 +4122,6 @@ TH2 * phisPy2In = (TH2*) gROOT->FindObject("hisPy2In0")
 
 */
 
-}  
-