]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONTrackExtrap.cxx
Implemented a new version of cluster (with its store and iterator):
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackExtrap.cxx
index 41a7b1833ff277451ea3466e188704881418f889..08930b7727069cea4d97d1a5dc3133bf9055ac5e 100644 (file)
 
 /* $Id$ */
 
-///////////////////////////////////////////////////
-//
-// Tools
-// for
-// track
-// extrapolation
-// in
-// ALICE
-// dimuon
-// spectrometer
-//
-///////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
+// Class AliMUONTrackExtrap
+// ------------------------
+// Tools for track extrapolation in ALICE dimuon spectrometer
+// Author: Philippe Pillot
+//-----------------------------------------------------------------------------
 
 #include "AliMUONTrackExtrap.h" 
 #include "AliMUONTrackParam.h"
 
 #include "AliMagF.h" 
 
-#include <Riostream.h>
 #include <TMath.h>
 #include <TMatrixD.h>
 #include <TGeoManager.h>
 
+#include <Riostream.h>
+
 /// \cond CLASSIMP
 ClassImp(AliMUONTrackExtrap) // Class implementation in ROOT context
 /// \endcond
@@ -93,6 +88,34 @@ Double_t AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(Double_t impactPa
   Double_t simpleBValue = (Double_t) b[0];
   
   return (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / impactParam);
+}
+
+  //__________________________________________________________________________
+void AliMUONTrackExtrap::LinearExtrapToZ(AliMUONTrackParam* trackParam, Double_t zEnd)
+{
+  /// Track parameters (and their covariances if any) linearly extrapolated to the plane at "zEnd".
+  /// On return, results from the extrapolation are updated in trackParam.
+  
+  if (trackParam->GetZ() == zEnd) return; // nothing to be done if same z
+  
+  // Compute track parameters
+  Double_t dZ = zEnd - trackParam->GetZ();
+  trackParam->SetNonBendingCoor(trackParam->GetNonBendingCoor() + trackParam->GetNonBendingSlope() * dZ);
+  trackParam->SetBendingCoor(trackParam->GetBendingCoor() + trackParam->GetBendingSlope() * dZ);
+  trackParam->SetZ(zEnd);
+  
+  // Update track parameters covariances if any
+  if (trackParam->CovariancesExist()) {
+    TMatrixD paramCov(trackParam->GetCovariances());
+    paramCov(0,0) += dZ * dZ * paramCov(1,1) + 2. * dZ * paramCov(0,1);
+    paramCov(0,1) += dZ * paramCov(1,1);
+    paramCov(1,0) = paramCov(0,1);
+    paramCov(2,2) += dZ * dZ * paramCov(3,3) + 2. * dZ * paramCov(2,3);
+    paramCov(2,3) += dZ * paramCov(3,3);
+    paramCov(3,2) = paramCov(2,3);
+    trackParam->SetCovariances(paramCov);
+  }
+  
 }
 
   //__________________________________________________________________________
@@ -234,72 +257,72 @@ void AliMUONTrackExtrap::RecoverTrackParam(Double_t *v3, Double_t charge, AliMUO
 }
 
   //__________________________________________________________________________
-void AliMUONTrackExtrap::ExtrapToZCov(AliMUONTrackParam* trackParam, Double_t zEnd)
+void AliMUONTrackExtrap::ExtrapToZCov(AliMUONTrackParam* trackParam, Double_t zEnd, Bool_t updatePropagator)
 {
   /// Track parameters and their covariances extrapolated to the plane at "zEnd".
   /// On return, results from the extrapolation are updated in trackParam.
   
   if (trackParam->GetZ() == zEnd) return; // nothing to be done if same z
   
+  // No need to propagate the covariance matrix if it does not exist
+  if (!trackParam->CovariancesExist()) {
+    cout<<"W-AliMUONTrackExtrap::ExtrapToZCov: Covariance matrix does not exist"<<endl;
+    // Extrapolate track parameters to "zEnd"
+    ExtrapToZ(trackParam,zEnd);
+    return;
+  }
+  
   // Save the actual track parameters
   AliMUONTrackParam trackParamSave(*trackParam);
-  Double_t nonBendingCoor        = trackParamSave.GetNonBendingCoor();
-  Double_t nonBendingSlope       = trackParamSave.GetNonBendingSlope();
-  Double_t bendingCoor                   = trackParamSave.GetBendingCoor();
-  Double_t bendingSlope          = trackParamSave.GetBendingSlope();
-  Double_t inverseBendingMomentum = trackParamSave.GetInverseBendingMomentum();
-  Double_t zBegin                = trackParamSave.GetZ();
+  TMatrixD paramSave(trackParamSave.GetParameters());
+  Double_t zBegin = trackParamSave.GetZ();
+  
+  // Get reference to the parameter covariance matrix
+  const TMatrixD& kParamCov = trackParam->GetCovariances();
   
   // Extrapolate track parameters to "zEnd"
   ExtrapToZ(trackParam,zEnd);
-  Double_t extrapNonBendingCoor        = trackParam->GetNonBendingCoor();
-  Double_t extrapNonBendingSlope       = trackParam->GetNonBendingSlope();
-  Double_t extrapBendingCoor           = trackParam->GetBendingCoor();
-  Double_t extrapBendingSlope          = trackParam->GetBendingSlope();
-  Double_t extrapInverseBendingMomentum = trackParam->GetInverseBendingMomentum();
   
-  // Get the pointer to the parameter covariance matrix
-  if (!trackParam->CovariancesExist()) {
-    //cout<<"W-AliMUONTrackExtrap::ExtrapToZCov: track parameter covariance matrix does not exist"<<endl;
-    //cout<<"                                    -> nothing to extrapolate !!"<<endl;
-    return;
-  }
-  TMatrixD* paramCov = trackParam->GetCovariances();
+  // Get reference to the extrapolated parameters
+  const TMatrixD& extrapParam = trackParam->GetParameters();
   
   // Calculate the jacobian related to the track parameters extrapolation to "zEnd"
   TMatrixD jacob(5,5);
-  jacob = 0.;
-  Double_t dParam[5];
+  jacob.Zero();
+  TMatrixD dParam(5,1);
   for (Int_t i=0; i<5; i++) {
     // Skip jacobian calculation for parameters with no associated error
-    if ((*paramCov)(i,i) == 0.) continue;
+    if (kParamCov(i,i) == 0.) continue;
+    
     // Small variation of parameter i only
     for (Int_t j=0; j<5; j++) {
       if (j==i) {
-        dParam[j] = TMath::Sqrt((*paramCov)(i,i));
-       if (j == 4) dParam[j] *= TMath::Sign(1.,-inverseBendingMomentum); // variation always in the same direction
-      } else dParam[j] = 0.;
+        dParam(j,0) = TMath::Sqrt(kParamCov(i,i));
+       if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramSave(4,0)); // variation always in the same direction
+      } else dParam(j,0) = 0.;
     }
+    
     // Set new parameters
-    trackParamSave.SetNonBendingCoor       (nonBendingCoor         + dParam[0]);
-    trackParamSave.SetNonBendingSlope      (nonBendingSlope        + dParam[1]);
-    trackParamSave.SetBendingCoor          (bendingCoor            + dParam[2]);
-    trackParamSave.SetBendingSlope         (bendingSlope           + dParam[3]);
-    trackParamSave.SetInverseBendingMomentum(inverseBendingMomentum + dParam[4]);
-    trackParamSave.SetZ                            (zBegin);
+    trackParamSave.SetParameters(paramSave);
+    trackParamSave.AddParameters(dParam);
+    trackParamSave.SetZ(zBegin);
+    
     // Extrapolate new track parameters to "zEnd"
     ExtrapToZ(&trackParamSave,zEnd);
+    
     // Calculate the jacobian
-    jacob(0,i) = (trackParamSave.GetNonBendingCoor()        - extrapNonBendingCoor        ) / dParam[i];
-    jacob(1,i) = (trackParamSave.GetNonBendingSlope()       - extrapNonBendingSlope       ) / dParam[i];
-    jacob(2,i) = (trackParamSave.GetBendingCoor()           - extrapBendingCoor           ) / dParam[i];
-    jacob(3,i) = (trackParamSave.GetBendingSlope()          - extrapBendingSlope          ) / dParam[i];
-    jacob(4,i) = (trackParamSave.GetInverseBendingMomentum() - extrapInverseBendingMomentum) / dParam[i];
+    TMatrixD jacobji(trackParamSave.GetParameters(),TMatrixD::kMinus,extrapParam);
+    jacobji *= 1. / dParam(i,0);
+    jacob.SetSub(0,i,jacobji);
   }
   
   // Extrapolate track parameter covariances to "zEnd"
-  TMatrixD tmp((*paramCov),TMatrixD::kMultTranspose,jacob);
-  (*paramCov) = TMatrixD(jacob,TMatrixD::kMult,tmp);
+  TMatrixD tmp(kParamCov,TMatrixD::kMultTranspose,jacob);
+  TMatrixD tmp2(jacob,TMatrixD::kMult,tmp);
+  trackParam->SetCovariances(tmp2);
+  
+  // Update the propagator if required
+  if (updatePropagator) trackParam->UpdatePropagator(jacob);
   
 }
 
@@ -349,49 +372,36 @@ void AliMUONTrackExtrap::ExtrapToVertexUncorrected(AliMUONTrackParam* trackParam
     exit(-1);
   }
   
-  // Check whether the geometry is available and get absorber boundaries
-  if (!gGeoManager) {
-    cout<<"E-AliMUONTrackExtrap::ExtrapToVertexUncorrected: no TGeo"<<endl;
-    return;
-  }
-  TGeoNode *absNode = gGeoManager->GetVolume("ALIC")->GetNode("ABSM_1");
-  if (!absNode) {
-    cout<<"E-AliMUONTrackExtrap::ExtrapToVertexUncorrected: failed to get absorber node"<<endl;
-    return;
-  }
-  Double_t zAbsBeg, zAbsEnd;
-  absNode->GetVolume()->GetShape()->GetAxisRange(3,zAbsBeg,zAbsEnd);
-  const Double_t *absPos = absNode->GetMatrix()->GetTranslation();
-  zAbsBeg = absPos[2] - zAbsBeg; // spectro. (z<0)
-  zAbsEnd = absPos[2] - zAbsEnd; // spectro. (z<0)
-  
   // Check the vertex position relatively to the absorber
-  if (zVtx < zAbsBeg && zVtx > zAbsEnd) { // spectro. (z<0)
+  if (zVtx < AliMUONConstants::AbsZBeg() && zVtx > AliMUONConstants::AbsZEnd()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Ending Z ("<<zVtx
-       <<") inside the front absorber ("<<zAbsBeg<<","<<zAbsEnd<<")"<<endl;
-  } else if (zVtx < zAbsEnd ) { // spectro. (z<0)
+       <<") inside the front absorber ("<<AliMUONConstants::AbsZBeg()<<","<<AliMUONConstants::AbsZEnd()<<")"<<endl;
+  } else if (zVtx < AliMUONConstants::AbsZEnd() ) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Ending Z ("<<zVtx
-       <<") downstream the front absorber (zAbsorberEnd = "<<zAbsEnd<<")"<<endl;
-    ExtrapToZCov(trackParam,zVtx);
+       <<") downstream the front absorber (zAbsorberEnd = "<<AliMUONConstants::AbsZEnd()<<")"<<endl;
+    if (trackParam->CovariancesExist()) ExtrapToZCov(trackParam,zVtx);
+    else ExtrapToZ(trackParam,zVtx);
     return;
   }
   
   // Check the track position relatively to the absorber and extrapolate track parameters to the end of the absorber if needed
-  if (trackParam->GetZ() > zAbsBeg) { // spectro. (z<0)
+  if (trackParam->GetZ() > AliMUONConstants::AbsZBeg()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Starting Z ("<<trackParam->GetZ()
-       <<") upstream the front absorber (zAbsorberBegin = "<<zAbsBeg<<")"<<endl;
-    ExtrapToZCov(trackParam,zVtx);
+       <<") upstream the front absorber (zAbsorberBegin = "<<AliMUONConstants::AbsZBeg()<<")"<<endl;
+    if (trackParam->CovariancesExist()) ExtrapToZCov(trackParam,zVtx);
+    else ExtrapToZ(trackParam,zVtx);
     return;
-  } else if (trackParam->GetZ() > zAbsEnd) { // spectro. (z<0)
+  } else if (trackParam->GetZ() > AliMUONConstants::AbsZEnd()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Starting Z ("<<trackParam->GetZ()
-       <<") inside the front absorber ("<<zAbsBeg<<","<<zAbsEnd<<")"<<endl;
+       <<") inside the front absorber ("<<AliMUONConstants::AbsZBeg()<<","<<AliMUONConstants::AbsZEnd()<<")"<<endl;
   } else {
-    ExtrapToZCov(trackParam,zAbsEnd);
+    if (trackParam->CovariancesExist()) ExtrapToZCov(trackParam,AliMUONConstants::AbsZEnd());
+    else ExtrapToZ(trackParam,AliMUONConstants::AbsZEnd());
   }
   
   // Then add MCS effect in absorber to the parameters covariances
   AliMUONTrackParam trackParamIn(*trackParam);
-  ExtrapToZ(&trackParamIn, TMath::Min(zVtx, zAbsBeg));
+  ExtrapToZ(&trackParamIn, TMath::Min(zVtx, AliMUONConstants::AbsZBeg()));
   Double_t trackXYZIn[3];
   trackXYZIn[0] = trackParamIn.GetNonBendingCoor();
   trackXYZIn[1] = trackParamIn.GetBendingCoor();
@@ -405,7 +415,8 @@ void AliMUONTrackExtrap::ExtrapToVertexUncorrected(AliMUONTrackParam* trackParam
   Double_t f1 = 0.;
   Double_t f2 = 0.;
   Double_t meanRho = 0.;
-  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,pathLength,f0,f1,f2,meanRho);
+  Double_t totalELoss = 0.;
+  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,trackParam->P(),pathLength,f0,f1,f2,meanRho,totalELoss);
   AddMCSEffectInAbsorber(trackParam,pathLength,f0,f1,f2);
   
   // finally go to the vertex
@@ -429,19 +440,22 @@ void AliMUONTrackExtrap::AddMCSEffectInAbsorber(AliMUONTrackParam* param, Double
   Double_t covCorrSlope = alpha2 * (pathLength * f0 - f1);
   Double_t varSlop = alpha2 * f0;
   
-  TMatrixD* paramCov = param->GetCovariances();
+  TMatrixD newParamCov(param->GetCovariances());
   // Non bending plane
-  (*paramCov)(0,0) += varCoor;         (*paramCov)(0,1) += covCorrSlope;
-  (*paramCov)(1,0) += covCorrSlope;    (*paramCov)(1,1) += varSlop;
+  newParamCov(0,0) += varCoor;       newParamCov(0,1) += covCorrSlope;
+  newParamCov(1,0) += covCorrSlope;  newParamCov(1,1) += varSlop;
   // Bending plane
-  (*paramCov)(2,2) += varCoor;         (*paramCov)(2,3) += covCorrSlope;
-  (*paramCov)(3,2) += covCorrSlope;    (*paramCov)(3,3) += varSlop;
+  newParamCov(2,2) += varCoor;       newParamCov(2,3) += covCorrSlope;
+  newParamCov(3,2) += covCorrSlope;  newParamCov(3,3) += varSlop;
+  
+  // Set new covariances
+  param->SetCovariances(newParamCov);
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Double_t trackXYZOut[3], Double_t &pathLength,
-                                                   Double_t &f0, Double_t &f1, Double_t &f2, Double_t &meanRho)
+void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Double_t trackXYZOut[3], Double_t pTotal, Double_t &pathLength,
+                                                   Double_t &f0, Double_t &f1, Double_t &f2, Double_t &meanRho, Double_t &totalELoss)
 {
   /// Parameters used to correct for Multiple Coulomb Scattering and energy loss in absorber
   /// Calculated assuming a linear propagation between track positions trackXYZIn and trackXYZOut
@@ -450,6 +464,7 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
   // f1:         1st moment of z calculated with the inverse radiation-length distribution
   // f2:         2nd moment of z calculated with the inverse radiation-length distribution
   // meanRho:    average density of crossed material (g/cm3)
+  // totalELoss: total energy loss in absorber
   
   // Reset absorber's parameters
   pathLength = 0.;
@@ -457,6 +472,7 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
   f1 = 0.;
   f2 = 0.;
   meanRho = 0.;
+  totalELoss = 0.;
   
   // Check whether the geometry is available
   if (!gGeoManager) {
@@ -482,6 +498,8 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
   // loop over absorber slices and calculate absorber's parameters
   Double_t rho = 0.; // material density (g/cm3)
   Double_t x0 = 0.;  // radiation-length (cm-1)
+  Double_t atomicA = 0.; // A of material
+  Double_t atomicZ = 0.; // Z of material
   Double_t localPathLength = 0;
   Double_t remainingPathLength = pathLength;
   Double_t zB = trackXYZIn[2];
@@ -492,6 +510,8 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
     rho = material->GetDensity();
     x0 = material->GetRadLen();
     if (!material->IsMixture()) x0 /= rho; // different normalization in the modeler for mixture
+    atomicA = material->GetA();
+    atomicZ = material->GetZ();
     
     // Get path length within this material
     gGeoManager->FindNextBoundary(remainingPathLength);
@@ -526,6 +546,7 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
     f1 += (dzE*dzE - dzB*dzB) / b[2] / b[2] / x0 / 2.;
     f2 += (dzE*dzE*dzE - dzB*dzB*dzB) / b[2] / b[2] / b[2] / x0 / 3.;
     meanRho += localPathLength * rho;
+    totalELoss += BetheBloch(pTotal, localPathLength, rho, atomicA, atomicZ);
     
     // prepare next step
     zB = zE;
@@ -535,6 +556,28 @@ void AliMUONTrackExtrap::GetAbsorberCorrectionParam(Double_t trackXYZIn[3], Doub
   meanRho /= pathLength;
 }
 
+  //__________________________________________________________________________
+Double_t AliMUONTrackExtrap::GetMCSAngle2(const AliMUONTrackParam& param, Double_t dZ, Double_t x0)
+{
+  /// Return the angular dispersion square due to multiple Coulomb scattering
+  /// through a material of thickness "dZ" and of radiation length "x0"
+  /// assuming linear propagation and using the small angle approximation.
+  
+  Double_t bendingSlope = param.GetBendingSlope();
+  Double_t nonBendingSlope = param.GetNonBendingSlope();
+  Double_t inverseTotalMomentum2 = param.GetInverseBendingMomentum() * param.GetInverseBendingMomentum() *
+                                  (1.0 + bendingSlope * bendingSlope) /
+                                  (1.0 + bendingSlope *bendingSlope + nonBendingSlope * nonBendingSlope); 
+  // Path length in the material
+  Double_t pathLength = TMath::Abs(dZ) * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
+  // relativistic velocity
+  Double_t velo = 1.;
+  // Angular dispersion square of the track (variance) in a plane perpendicular to the trajectory
+  Double_t theta02 = 0.0136 / velo * (1 + 0.038 * TMath::Log(pathLength/x0));
+  
+  return theta02 * theta02 * inverseTotalMomentum2 * pathLength / x0;
+}
+
   //__________________________________________________________________________
 void AliMUONTrackExtrap::AddMCSEffect(AliMUONTrackParam *param, Double_t dZ, Double_t x0)
 {
@@ -556,18 +599,21 @@ void AliMUONTrackExtrap::AddMCSEffect(AliMUONTrackParam *param, Double_t dZ, Dou
   Double_t theta02 = 0.0136 / velo * (1 + 0.038 * TMath::Log(pathLength/x0));
   theta02 *= theta02 * inverseTotalMomentum2 * pathLength / x0;
   
-  // Add effects of multiple Coulomb scattering in track parameter covariances
-  TMatrixD* paramCov = param->GetCovariances();
   Double_t varCoor     = pathLength2 * theta02 / 3.;
   Double_t varSlop     = theta02;
   Double_t covCorrSlope = pathLength * theta02 / 2.;
+  
+  // Add effects of multiple Coulomb scattering in track parameter covariances
+  TMatrixD newParamCov(param->GetCovariances());
   // Non bending plane
-  (*paramCov)(0,0) += varCoor;         (*paramCov)(0,1) += covCorrSlope;
-  (*paramCov)(1,0) += covCorrSlope;    (*paramCov)(1,1) += varSlop;
+  newParamCov(0,0) += varCoor;       newParamCov(0,1) += covCorrSlope;
+  newParamCov(1,0) += covCorrSlope;  newParamCov(1,1) += varSlop;
   // Bending plane
-  (*paramCov)(2,2) += varCoor;         (*paramCov)(2,3) += covCorrSlope;
-  (*paramCov)(3,2) += covCorrSlope;    (*paramCov)(3,3) += varSlop;
+  newParamCov(2,2) += varCoor;       newParamCov(2,3) += covCorrSlope;
+  newParamCov(3,2) += covCorrSlope;  newParamCov(3,3) += varSlop;
   
+  // Set new covariances
+  param->SetCovariances(newParamCov);
 }
 
   //__________________________________________________________________________
@@ -592,44 +638,28 @@ void AliMUONTrackExtrap::ExtrapToVertex(AliMUONTrackParam* trackParam, Double_t
     return;
   }
   
-  // Check whether the geometry is available and get absorber boundaries
-  if (!gGeoManager) {
-    cout<<"E-AliMUONTrackExtrap::ExtrapToVertex: no TGeo"<<endl;
-    return;
-  }
-  TGeoNode *absNode = gGeoManager->GetVolume("ALIC")->GetNode("ABSM_1");
-  if (!absNode) {
-    cout<<"E-AliMUONTrackExtrap::ExtrapToVertex: failed to get absorber node"<<endl;
-    return;
-  }
-  Double_t zAbsBeg, zAbsEnd;
-  absNode->GetVolume()->GetShape()->GetAxisRange(3,zAbsBeg,zAbsEnd);
-  const Double_t *absPos = absNode->GetMatrix()->GetTranslation();
-  zAbsBeg = absPos[2] - zAbsBeg; // spectro. (z<0)
-  zAbsEnd = absPos[2] - zAbsEnd; // spectro. (z<0)
-  
   // Check the vertex position relatively to the absorber
-  if (zVtx < zAbsBeg && zVtx > zAbsEnd) { // spectro. (z<0)
+  if (zVtx < AliMUONConstants::AbsZBeg() && zVtx > AliMUONConstants::AbsZEnd()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Ending Z ("<<zVtx
-       <<") inside the front absorber ("<<zAbsBeg<<","<<zAbsEnd<<")"<<endl;
-  } else if (zVtx < zAbsEnd ) { // spectro. (z<0)
+       <<") inside the front absorber ("<<AliMUONConstants::AbsZBeg()<<","<<AliMUONConstants::AbsZEnd()<<")"<<endl;
+  } else if (zVtx < AliMUONConstants::AbsZEnd() ) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Ending Z ("<<zVtx
-       <<") downstream the front absorber (zAbsorberEnd = "<<zAbsEnd<<")"<<endl;
+       <<") downstream the front absorber (zAbsorberEnd = "<<AliMUONConstants::AbsZEnd()<<")"<<endl;
     ExtrapToZ(trackParam,zVtx);
     return;
   }
   
   // Check the track position relatively to the absorber and extrapolate track parameters to the end of the absorber if needed
-  if (trackParam->GetZ() > zAbsBeg) { // spectro. (z<0)
+  if (trackParam->GetZ() > AliMUONConstants::AbsZBeg()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Starting Z ("<<trackParam->GetZ()
-       <<") upstream the front absorber (zAbsorberBegin = "<<zAbsBeg<<")"<<endl;
+       <<") upstream the front absorber (zAbsorberBegin = "<<AliMUONConstants::AbsZBeg()<<")"<<endl;
     ExtrapToZ(trackParam,zVtx);
     return;
-  } else if (trackParam->GetZ() > zAbsEnd) { // spectro. (z<0)
+  } else if (trackParam->GetZ() > AliMUONConstants::AbsZEnd()) { // spectro. (z<0)
     cout<<"W-AliMUONTrackExtrap::ExtrapToVertex: Starting Z ("<<trackParam->GetZ()
-       <<") inside the front absorber ("<<zAbsBeg<<","<<zAbsEnd<<")"<<endl;
+       <<") inside the front absorber ("<<AliMUONConstants::AbsZBeg()<<","<<AliMUONConstants::AbsZEnd()<<")"<<endl;
   } else {
-    ExtrapToZ(trackParam,zAbsEnd);
+    ExtrapToZ(trackParam,AliMUONConstants::AbsZEnd());
   }
   
   // Get absorber correction parameters assuming linear propagation from vertex to the track position
@@ -638,23 +668,21 @@ void AliMUONTrackExtrap::ExtrapToVertex(AliMUONTrackParam* trackParam, Double_t
   trackXYZOut[1] = trackParam->GetBendingCoor();
   trackXYZOut[2] = trackParam->GetZ();
   Double_t trackXYZIn[3];
-  trackXYZIn[2] = TMath::Min(zVtx, zAbsBeg); // spectro. (z<0)
+  trackXYZIn[2] = TMath::Min(zVtx, AliMUONConstants::AbsZBeg()); // spectro. (z<0)
   trackXYZIn[0] = trackXYZOut[0] + (xVtx - trackXYZOut[0]) / (zVtx - trackXYZOut[2]) * (trackXYZIn[2] - trackXYZOut[2]);
   trackXYZIn[1] = trackXYZOut[1] + (yVtx - trackXYZOut[1]) / (zVtx - trackXYZOut[2]) * (trackXYZIn[2] - trackXYZOut[2]);
+  Double_t pTot = trackParam->P();
   Double_t pathLength = 0.;
   Double_t f0 = 0.;
   Double_t f1 = 0.;
   Double_t f2 = 0.;
   Double_t meanRho = 0.;
-  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,pathLength,f0,f1,f2,meanRho);
-  
-  // Calculate energy loss
-  Double_t pTot = trackParam->P();
-  Double_t charge = TMath::Sign(Double_t(1.0), trackParam->GetInverseBendingMomentum());      
-  Double_t deltaP = TotalMomentumEnergyLoss(pTot,pathLength,meanRho);
+  Double_t deltaP = 0.;
+  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,pTot,pathLength,f0,f1,f2,meanRho,deltaP);
   
   // Correct for half of energy loss
   Double_t nonBendingSlope, bendingSlope;
+  Double_t charge = TMath::Sign(Double_t(1.0), trackParam->GetInverseBendingMomentum());      
   if (CorrectForEnergyLoss) {
     pTot += 0.5 * deltaP;
     nonBendingSlope = trackParam->GetNonBendingSlope();
@@ -721,46 +749,42 @@ Double_t AliMUONTrackExtrap::TotalMomentumEnergyLoss(AliMUONTrackParam* trackPar
   trackXYZIn[0] = xVtx;
   trackXYZIn[1] = yVtx;
   trackXYZIn[2] = zVtx;
+  Double_t pTot = trackParam->P();
   Double_t pathLength = 0.;
   Double_t f0 = 0.;
   Double_t f1 = 0.;
   Double_t f2 = 0.;
   Double_t meanRho = 0.;
-  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,pathLength,f0,f1,f2,meanRho);
+  Double_t totalELoss = 0.;
+  GetAbsorberCorrectionParam(trackXYZIn,trackXYZOut,pTot,pathLength,f0,f1,f2,meanRho,totalELoss);
   
-  // Calculate energy loss
-  Double_t pTot = trackParam->P();
-  return TotalMomentumEnergyLoss(pTot,pathLength,meanRho);
+  return totalELoss;
 }
 
   //__________________________________________________________________________
-Double_t AliMUONTrackExtrap::TotalMomentumEnergyLoss(Double_t pTotal, Double_t pathLength, Double_t rho)
+Double_t AliMUONTrackExtrap::BetheBloch(Double_t pTotal, Double_t pathLength, Double_t rho, Double_t atomicA, Double_t atomicZ)
 {
-  /// Returns the total momentum energy loss in the front absorber
-  Double_t muMass = 0.105658369;
+  /// Returns the mean total momentum energy loss of muon with total momentum='pTotal'
+  /// in the absorber layer of lenght='pathLength', density='rho', A='atomicA' and Z='atomicZ'
+  Double_t muMass = 0.105658369; // GeV
+  Double_t eMass = 0.510998918e-3; // GeV
+  Double_t k = 0.307075e-3; // GeV.g^-1.cm^2
+  Double_t i = 9.5e-9; // mean exitation energy per atomic Z (GeV)
   Double_t p2=pTotal*pTotal;
   Double_t beta2=p2/(p2 + muMass*muMass);
-  Double_t dE=ApproximateBetheBloch(beta2)*pathLength*rho;
   
-  return dE;
-}
-
-  //__________________________________________________________________________
-Double_t AliMUONTrackExtrap::ApproximateBetheBloch(Double_t beta2) {
-  //------------------------------------------------------------------
-  // This is an approximation of the Bethe-Bloch formula with 
-  // the density effect taken into account at beta*gamma > 3.5
-  // (the approximation is reasonable only for solid materials) 
-  //------------------------------------------------------------------
+  Double_t w = k * rho * pathLength * atomicZ / atomicA / beta2;
+  
   if (beta2/(1-beta2)>3.5*3.5)
-     return 0.153e-3/beta2*(log(3.5*5940)+0.5*log(beta2/(1-beta2)) - beta2);
+     return w * (log(2.*eMass*3.5/(i*atomicZ)) + 0.5*log(beta2/(1-beta2)) - beta2);
 
-  return 0.153e-3/beta2*(log(5940*beta2/(1-beta2)) - beta2);
+  return w * (log(2.*eMass*beta2/(1-beta2)/(i*atomicZ)) - beta2);
 }
 
  //__________________________________________________________________________
 void AliMUONTrackExtrap::ExtrapOneStepHelix(Double_t charge, Double_t step, Double_t *vect, Double_t *vout)
 {
+/// <pre>
 ///    ******************************************************************
 ///    *                                                                *
 ///    *  Performs the tracking of one step in a magnetic field         *
@@ -774,12 +798,13 @@ void AliMUONTrackExtrap::ExtrapOneStepHelix(Double_t charge, Double_t step, Doub
 ///    *   output                                                       *
 ///    *     VOUT = same as VECT after completion of the step           *
 ///    *                                                                *
-///    *    ==>Called by : <USER>, GUSWIM                               *
+///    *    ==>Called by : USER, GUSWIM                               *
 ///    *       Author    m.hansroul  *********                          *
 ///    *       modified  s.egli, s.v.levonian                           *
 ///    *       modified  v.perevoztchikov
 ///    *                                                                *
 ///    ******************************************************************
+/// </pre>
 
 // modif: everything in double precision
 
@@ -878,6 +903,7 @@ void AliMUONTrackExtrap::ExtrapOneStepHelix(Double_t charge, Double_t step, Doub
  //__________________________________________________________________________
 void AliMUONTrackExtrap::ExtrapOneStepHelix3(Double_t field, Double_t step, Double_t *vect, Double_t *vout)
 {
+/// <pre>
 ///    ******************************************************************
 ///    *                                                                *
 ///    *       Tracking routine in a constant field oriented            *
@@ -885,11 +911,12 @@ void AliMUONTrackExtrap::ExtrapOneStepHelix3(Double_t field, Double_t step, Doub
 ///    *       Tracking is performed with a conventional                *
 ///    *       helix step method                                        *
 ///    *                                                                *
-///    *    ==>Called by : <USER>, GUSWIM                               *
+///    *    ==>Called by : USER, GUSWIM                                 *
 ///    *       Authors    R.Brun, M.Hansroul  *********                 *
 ///    *       Rewritten  V.Perevoztchikov
 ///    *                                                                *
 ///    ******************************************************************
+/// </pre>
 
     Double_t hxp[3];
     Double_t h4, hp, rho, tet;
@@ -954,6 +981,7 @@ void AliMUONTrackExtrap::ExtrapOneStepHelix3(Double_t field, Double_t step, Doub
  //__________________________________________________________________________
 void AliMUONTrackExtrap::ExtrapOneStepRungekutta(Double_t charge, Double_t step, Double_t* vect, Double_t* vout)
 {
+/// <pre>
 ///    ******************************************************************
 ///    *                                                                *
 ///    *  Runge-Kutta method for tracking a particle through a magnetic *
@@ -969,12 +997,13 @@ void AliMUONTrackExtrap::ExtrapOneStepRungekutta(Double_t charge, Double_t step,
 ///    *  User routine called                                           *
 ///    *       CALL GUFLD(X,F)                                          *
 ///    *                                                                *
-///    *    ==>Called by : <USER>, GUSWIM                               *
+///    *    ==>Called by : USER, GUSWIM                                 *
 ///    *       Authors    R.Brun, M.Hansroul  *********                 *
 ///    *                  V.Perevoztchikov (CUT STEP implementation)    *
 ///    *                                                                *
 ///    *                                                                *
 ///    ******************************************************************
+/// </pre>
 
     Double_t h2, h4, f[4];
     Double_t xyzt[3], a, b, c, ph,ph2;