]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/AliTRDv1.cxx
Moving to standard names
[u/mrichter/AliRoot.git] / TRD / AliTRDv1.cxx
index 3f13891dbd1180d0b2aca7f52d04a31760be0934..6056c4539565cb0761d48c904416f01a973fa544 100644 (file)
 #include <TVector.h>
 #include <TVirtualMC.h>
 #include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TGeoPhysicalNode.h>
 
 #include "AliConst.h"
 #include "AliLog.h"
+#include "AliTrackReference.h"
 #include "AliMC.h"
 #include "AliRun.h"
+#include "AliGeomManager.h"
 
 #include "AliTRDgeometry.h"
+#include "AliTRDSimParam.h"
 #include "AliTRDhit.h"
-#include "AliTRDsim.h"
+#include "AliTRDsimTR.h"
 #include "AliTRDv1.h"
 
 ClassImp(AliTRDv1)
@@ -50,6 +55,7 @@ AliTRDv1::AliTRDv1()
   ,fTR(NULL)
   ,fTypeOfStepManager(0)
   ,fStepSize(0)
+  ,fWion(0)
   ,fDeltaE(NULL)
   ,fDeltaG(NULL)
   ,fTrackLength0(0)
@@ -68,6 +74,7 @@ AliTRDv1::AliTRDv1(const char *name, const char *title)
   ,fTR(NULL)
   ,fTypeOfStepManager(2)
   ,fStepSize(0.1)
+  ,fWion(0)
   ,fDeltaE(NULL)
   ,fDeltaG(NULL)
   ,fTrackLength0(0)
@@ -79,27 +86,16 @@ AliTRDv1::AliTRDv1(const char *name, const char *title)
 
   SetBufferSize(128000);
 
-}
-
-//_____________________________________________________________________________
-AliTRDv1::AliTRDv1(const AliTRDv1 &trd)
-  :AliTRD(trd)
-  ,fTRon(trd.fTRon)
-  ,fTR(NULL)
-  ,fTypeOfStepManager(trd.fTypeOfStepManager)
-  ,fStepSize(trd.fStepSize)
-  ,fDeltaE(NULL)
-  ,fDeltaG(NULL)
-  ,fTrackLength0(trd.fTrackLength0)
-  ,fPrimaryTrackPid(trd.fPrimaryTrackPid)
-{
-  //
-  // Copy constructor
-  //
-
-  fDeltaE->Copy(*((AliTRDv1 &) trd).fDeltaE);
-  fDeltaG->Copy(*((AliTRDv1 &) trd).fDeltaG);
-  fTR->Copy(*((AliTRDv1 &) trd).fTR);
+  if      (AliTRDSimParam::Instance()->IsXenon()) {
+    fWion = 23.53; // Ionization energy XeCO2 (85/15)
+  }
+  else if (AliTRDSimParam::Instance()->IsArgon()) {
+    fWion = 27.21; // Ionization energy ArCO2 (82/18)
+  }
+  else {
+    AliFatal("Wrong gas mixture");
+    exit(1);
+  }
 
 }
 
@@ -127,38 +123,6 @@ AliTRDv1::~AliTRDv1()
 
 }
  
-//_____________________________________________________________________________
-AliTRDv1 &AliTRDv1::operator=(const AliTRDv1 &trd)
-{
-  //
-  // Assignment operator
-  //
-
-  if (this != &trd) ((AliTRDv1 &) trd).Copy(*this);
-
-  return *this;
-
-}
-//_____________________________________________________________________________
-void AliTRDv1::Copy(TObject &trd) const
-{
-  //
-  // Copy function
-  //
-
-  ((AliTRDv1 &) trd).fTypeOfStepManager = fTypeOfStepManager;
-  ((AliTRDv1 &) trd).fStepSize          = fStepSize;
-  ((AliTRDv1 &) trd).fTRon              = fTRon;
-  ((AliTRDv1 &) trd).fTrackLength0      = fTrackLength0;
-  ((AliTRDv1 &) trd).fPrimaryTrackPid   = fPrimaryTrackPid;
-
-  fDeltaE->Copy(*((AliTRDv1 &) trd).fDeltaE);
-  fDeltaG->Copy(*((AliTRDv1 &) trd).fDeltaG);
-  fTR->Copy(*((AliTRDv1 &) trd).fTR);
-
-}
-
 //_____________________________________________________________________________
 void AliTRDv1::AddAlignableVolumes() const
 {
@@ -171,14 +135,16 @@ void AliTRDv1::AddAlignableVolumes() const
   TString volPath;
   TString symName;
 
-  TString vpStr  = "ALIC_1/B077_1/BSEGMO";
-  TString vpApp1 = "_1/BTRD";
-  TString vpApp2 = "_1";
-  TString vpApp3 = "/UTR1_1/UTS1_1/UTI1_1/UT";
+  TString vpStr   = "ALIC_1/B077_1/BSEGMO";
+  TString vpApp1  = "_1/BTRD";
+  TString vpApp2  = "_1";
+  TString vpApp3a = "/UTR1_1/UTS1_1/UTI1_1/UT";
+  TString vpApp3b = "/UTR2_1/UTS2_1/UTI2_1/UT";
+  TString vpApp3c = "/UTR3_1/UTS3_1/UTI3_1/UT";
 
-  TString snStr  = "TRD/sm";
-  TString snApp1 = "/st";
-  TString snApp2 = "/pl";
+  TString snStr   = "TRD/sm";
+  TString snApp1  = "/st";
+  TString snApp2  = "/pl";
 
   //
   // The super modules
@@ -186,16 +152,16 @@ void AliTRDv1::AddAlignableVolumes() const
   //                           ...
   //                         TRD/sm17
   //
-  for (Int_t isect = 0; isect < AliTRDgeometry::Nsect(); isect++) {
+  for (Int_t isector = 0; isector < AliTRDgeometry::Nsector(); isector++) {
 
     volPath  = vpStr;
-    volPath += isect;
+    volPath += isector;
     volPath += vpApp1;
-    volPath += isect;
+    volPath += isector;
     volPath += vpApp2;
 
     symName  = snStr;
-    symName += Form("%02d",isect);
+    symName += Form("%02d",isector);
 
     gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data());
 
@@ -207,29 +173,68 @@ void AliTRDv1::AddAlignableVolumes() const
   //                           ...
   //                         TRD/sm17/st4/pl5
   //
-  for (Int_t isect = 0; isect < AliTRDgeometry::Nsect(); isect++) {
-    for (Int_t icham = 0; icham < AliTRDgeometry::Ncham(); icham++) {
-      for (Int_t iplan = 0; iplan < AliTRDgeometry::Nplan(); iplan++) {
+  AliGeomManager::ELayerID idTRD1 = AliGeomManager::kTRD1;
+  Int_t layer, modUID;
+  
+  for (Int_t isector = 0; isector < AliTRDgeometry::Nsector(); isector++) {
+
+    if (fGeometry->GetSMstatus(isector) == 0) continue;
+
+    for (Int_t istack = 0; istack < AliTRDgeometry::Nstack(); istack++) {
+      for (Int_t ilayer = 0; ilayer < AliTRDgeometry::Nlayer(); ilayer++) {
 
-        Int_t idet = AliTRDgeometry::GetDetectorSec(iplan,icham);
+       layer = idTRD1 + ilayer;
+       modUID = AliGeomManager::LayerToVolUIDSafe(layer,isector*5+istack);
+
+        Int_t idet = AliTRDgeometry::GetDetectorSec(ilayer,istack);
 
         volPath  = vpStr;
-        volPath += isect;
+        volPath += isector;
         volPath += vpApp1;
-        volPath += isect;
+        volPath += isector;
         volPath += vpApp2;
-        volPath += vpApp3;
+        switch (isector) {
+        case 13:
+        case 14:
+        case 15:
+          if (istack == 2) {
+            continue;
+         }
+          volPath += vpApp3c;
+          break;
+        case 11:
+        case 12:
+          volPath += vpApp3b;
+          break;
+        default:
+          volPath += vpApp3a;
+       };
         volPath += Form("%02d",idet);
         volPath += vpApp2;
 
         symName  = snStr;
-        symName += Form("%02d",isect);
+        symName += Form("%02d",isector);
         symName += snApp1;
-        symName += icham;
+        symName += istack;
         symName += snApp2;
-        symName += iplan;
-
-        gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data());
+        symName += ilayer;
+
+        TGeoPNEntry *alignableEntry = 
+         gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data(),modUID);
+
+       // Add the tracking to local matrix following the TPC example
+       if (alignableEntry) {
+         // Is this correct still????
+         TGeoHMatrix *globMatrix = alignableEntry->GetGlobalOrig();
+         Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
+         TGeoHMatrix *t2lMatrix  = new TGeoHMatrix();
+         t2lMatrix->RotateZ(sectorAngle);
+         t2lMatrix->MultiplyLeft(&(globMatrix->Inverse()));
+         alignableEntry->SetMatrix(t2lMatrix);
+       }
+       else {
+         AliError(Form("Alignable entry %s is not valid!",symName.Data()));
+       }
 
       }
     }
@@ -279,97 +284,89 @@ void AliTRDv1::CreateTRhit(Int_t det)
   // volume.
   //
 
-  // PDG code electron
-  const Int_t   kPdgElectron = 11;
-
-  // Ionization energy
-  const Float_t kWion        = 23.53;
-
   // Maximum number of TR photons per track
   const Int_t   kNTR         = 50;
 
   TLorentzVector mom;
   TLorentzVector pos;
 
-  // Create TR at the entrance of the chamber
-  if (gMC->IsTrackEntering()) {
+  Float_t eTR[kNTR];
+  Int_t   nTR;
 
-    // Create TR only for electrons 
-    Int_t iPdg = gMC->TrackPid();
-    if (TMath::Abs(iPdg) != kPdgElectron) {
-      return;
-    }
+  // Create TR photons
+  gMC->TrackMomentum(mom);
+  Float_t pTot = mom.Rho();
+  fTR->CreatePhotons(11,pTot,nTR,eTR);
+  if (nTR > kNTR) {
+    AliFatal(Form("Boundary error: nTR = %d, kNTR = %d",nTR,kNTR));
+  }
 
-    Float_t eTR[kNTR];
-    Int_t   nTR;
+  // Loop through the TR photons
+  for (Int_t iTR = 0; iTR < nTR; iTR++) {
 
-    // Create TR photons
-    gMC->TrackMomentum(mom);
-    Float_t pTot = mom.Rho();
-    fTR->CreatePhotons(iPdg,pTot,nTR,eTR);
-    if (nTR > kNTR) {
-      AliFatal(Form("Boundary error: nTR = %d, kNTR = %d",nTR,kNTR));
-    }
+    Float_t energyMeV = eTR[iTR] * 0.001;
+    Float_t energyeV  = eTR[iTR] * 1000.0;
+    Float_t absLength = 0.0;
+    Float_t sigma     = 0.0;
 
-    // Loop through the TR photons
-    for (Int_t iTR = 0; iTR < nTR; iTR++) {
-
-      Float_t energyMeV = eTR[iTR] * 0.001;
-      Float_t energyeV  = eTR[iTR] * 1000.0;
-      Float_t absLength = 0.0;
-      Float_t sigma     = 0.0;
-
-      // Take the absorbtion in the entrance window into account
-      Double_t muMy = fTR->GetMuMy(energyMeV);
-      sigma         = muMy * fFoilDensity;
-      if (sigma > 0.0) {
-        absLength = gRandom->Exp(1.0/sigma);
-        if (absLength < AliTRDgeometry::MyThick()) {
-          continue;
-       }
-      }
-      else {
+    // Take the absorbtion in the entrance window into account
+    Double_t muMy = fTR->GetMuMy(energyMeV);
+    sigma         = muMy * fFoilDensity;
+    if (sigma > 0.0) {
+      absLength = gRandom->Exp(1.0/sigma);
+      if (absLength < AliTRDgeometry::MyThick()) {
         continue;
       }
+    }
+    else {
+      continue;
+    }
 
-      // The absorbtion cross sections in the drift gas
-      // Gas-mixture (Xe/CO2)
-      Double_t muXe = fTR->GetMuXe(energyMeV);
-      Double_t muCO = fTR->GetMuCO(energyMeV);
-      sigma = (0.85 * muXe + 0.15 * muCO) * fGasDensity * fTR->GetTemp();
-
-      // The distance after which the energy of the TR photon
-      // is deposited.
-      if (sigma > 0.0) {
-        absLength = gRandom->Exp(1.0/sigma);
-        if (absLength > (AliTRDgeometry::DrThick()
-                       + AliTRDgeometry::AmThick())) {
-          continue;
-       }
-      }
-      else {
+    // The absorbtion cross sections in the drift gas
+    // Gas-mixture (Xe/CO2)
+    Double_t muNo = 0.0;
+    if      (AliTRDSimParam::Instance()->IsXenon()) {
+      muNo = fTR->GetMuXe(energyMeV);
+    }
+    else if (AliTRDSimParam::Instance()->IsArgon()) {
+      muNo = fTR->GetMuAr(energyMeV);
+    }
+    Double_t muCO = fTR->GetMuCO(energyMeV);
+    sigma = (fGasNobleFraction * muNo + (1.0 - fGasNobleFraction) * muCO) 
+          * fGasDensity 
+          * fTR->GetTemp();
+
+    // The distance after which the energy of the TR photon
+    // is deposited.
+    if (sigma > 0.0) {
+      absLength = gRandom->Exp(1.0/sigma);
+      if (absLength > (AliTRDgeometry::DrThick()
+                     + AliTRDgeometry::AmThick())) {
         continue;
       }
-
-      // The position of the absorbtion
-      Float_t posHit[3];
-      gMC->TrackPosition(pos);
-      posHit[0] = pos[0] + mom[0] / pTot * absLength;
-      posHit[1] = pos[1] + mom[1] / pTot * absLength;
-      posHit[2] = pos[2] + mom[2] / pTot * absLength;
-
-      // Create the charge 
-      Int_t q = ((Int_t) (energyeV / kWion));
-
-      // Add the hit to the array. TR photon hits are marked 
-      // by negative charge
-      AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
-            ,det
-            ,posHit
-            ,-q
-            ,kTRUE); 
-
     }
+    else {
+      continue;
+    }
+
+    // The position of the absorbtion
+    Float_t posHit[3];
+    gMC->TrackPosition(pos);
+    posHit[0] = pos[0] + mom[0] / pTot * absLength;
+    posHit[1] = pos[1] + mom[1] / pTot * absLength;
+    posHit[2] = pos[2] + mom[2] / pTot * absLength;
+
+    // Create the charge 
+    Int_t q = ((Int_t) (energyeV / fWion));
+
+    // Add the hit to the array. TR photon hits are marked 
+    // by negative charge
+    AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
+          ,det
+          ,posHit
+          ,-q
+          ,gMC->TrackTime()*1.0e06
+          ,kTRUE);
 
   }
 
@@ -391,10 +388,10 @@ void AliTRDv1::Init()
     AliInfo("TR simulation off");
   }
   else {
-    fTR = new AliTRDsim();
+    fTR = new AliTRDsimTR();
   }
 
-  // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
+  // First ionization potential (eV) for the gas mixture
   const Float_t kPoti = 12.1;
   // Maximum energy (50 keV);
   const Float_t kEend = 50000.0;
@@ -460,13 +457,15 @@ void AliTRDv1::StepManagerGeant()
   // to Bethe-Bloch. The energy distribution of the delta electrons follows
   // a spectrum taken from Geant3.
   //
+  // Works only for Xe/CO2!!
+  //
   // Version by A. Bercuci
   //
 
-  Int_t    pla = 0;
-  Int_t    cha = 0;
-  Int_t    sec = 0;
-  Int_t    det = 0;
+  Int_t    layer  = 0;
+  Int_t    stack  = 0;
+  Int_t    sector = 0;
+  Int_t    det    = 0;
   Int_t    iPdg;
   Int_t    qTot;
 
@@ -483,6 +482,10 @@ void AliTRDv1::StepManagerGeant()
   Bool_t   drRegion = kFALSE;
   Bool_t   amRegion = kFALSE;
 
+  TString  cIdPath;
+  Char_t   cIdSector[3];
+           cIdSector[2]  = 0;
+
   TString  cIdCurrent;
   TString  cIdSensDr = "J";
   TString  cIdSensAm = "K";
@@ -494,12 +497,11 @@ void AliTRDv1::StepManagerGeant()
 
   TArrayI        processes;
 
-  const Int_t    kNplan       = AliTRDgeometry::Nplan();
-  const Int_t    kNcham       = AliTRDgeometry::Ncham();
-  const Int_t    kNdetsec     = kNplan * kNcham;
+  const Int_t    kNlayer      = AliTRDgeometry::Nlayer();
+  const Int_t    kNstack      = AliTRDgeometry::Nstack();
+  const Int_t    kNdetsec     = kNlayer * kNstack;
 
   const Double_t kBig         = 1.0e+12; // Infinitely big
-  const Float_t  kWion        = 23.53;   // Ionization energy
   const Float_t  kPTotMaxEl   = 0.002;   // Maximum momentum for e+ e- g
 
   // Minimum energy for the step size adjustment
@@ -550,164 +552,153 @@ void AliTRDv1::StepManagerGeant()
       hits[1] = pos[1];
       hits[2] = pos[2];
 
-      // The sector number (0 - 17)
-      // The numbering goes clockwise and starts at y = 0
-      Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
-      if (phi < 90.0) {
-        phi = phi + 270.0;
-      }
-      else {
-        phi = phi -  90.0;
-      }
-      sec = ((Int_t) (phi / 20.0));
+      // The sector number (0 - 17), according to standard coordinate system
+      cIdPath      = gGeoManager->GetPath();
+      cIdSector[0] = cIdPath[21];
+      cIdSector[1] = cIdPath[22];
+      sector = atoi(cIdSector);
 
-      // The plane and chamber number
+      // The layer and stack number
       cIdChamber[0]   = cIdCurrent[2];
       cIdChamber[1]   = cIdCurrent[3];
       Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
-      cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
-      pla = ((Int_t) idChamber % kNplan);
-
-      // Check on selected volumes
-      Int_t addthishit = 1;
-
-      // Add this hit
-      if (addthishit) {
-
-       // The detector number
-        det = fGeometry->GetDetector(pla,cha,sec);
-
-       // Special hits only in the drift region
-        if (drRegion) {
+      stack = ((Int_t) idChamber / kNlayer);
+      layer = ((Int_t) idChamber % kNlayer);
+
+      // The detector number
+      det = fGeometry->GetDetector(layer,stack,sector);
+
+      // Special hits only in the drift region
+      if      ((drRegion) &&
+               (gMC->IsTrackEntering())) {
+
+        // Create a track reference at the entrance of each
+        // chamber that contains the momentum components of the particle
+        gMC->TrackMomentum(mom);
+        AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
+
+        // Create the hits from TR photons if electron/positron is
+        // entering the drift volume
+        if ((fTR) && 
+            (TMath::Abs(gMC->TrackPid()) == kPdgElectron)) {
+          CreateTRhit(det);
+        }
 
-          // Create a track reference at the entrance and
-          // exit of each chamber that contain the
-         // momentum components of the particle
-          if (gMC->IsTrackEntering() || 
-              gMC->IsTrackExiting()) {
-            gMC->TrackMomentum(mom);
-            AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
-          }
+      }
+      else if ((amRegion) && 
+               (gMC->IsTrackExiting())) {
 
-         if (gMC->IsTrackEntering() && 
-              !gMC->IsNewTrack()) {
-           // determine if hit belong to primary track 
-           fPrimaryTrackPid = gAlice->GetMCApp()->GetCurrentTrackNumber();
-           // determine track length when entering the detector
-           fTrackLength0    = gMC->TrackLength();
-         }
-                                       
-         // Create the hits from TR photons
-          if (fTR) CreateTRhit(det);
+        // Create a track reference at the exit of each
+        // chamber that contains the momentum components of the particle
+        gMC->TrackMomentum(mom);
+        AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
 
-        }
+      }
 
-       // Calculate the energy of the delta-electrons
-       // modified by Alex Bercuci (A.Bercuci@gsi.de) on 26.01.06
-       // take into account correlation with the underlying GEANT tracking
-       // mechanism. see
-        // http://www-linux.gsi.de/~abercuci/Contributions/TRD/index.html
-       //
-       // determine the most significant process (last on the processes list)
-       // which caused this hit
-        gMC->StepProcesses(processes);
-        Int_t nofprocesses = processes.GetSize();
-        Int_t pid;
-       if (!nofprocesses) {
-          pid = 0;
-       }
-       else {
-          pid =        processes[nofprocesses-1];              
-       }               
+      // Calculate the energy of the delta-electrons
+      // modified by Alex Bercuci (A.Bercuci@gsi.de) on 26.01.06
+      // take into account correlation with the underlying GEANT tracking
+      // mechanism. see
+      // http://www-linux.gsi.de/~abercuci/Contributions/TRD/index.html
+      //
+      // determine the most significant process (last on the processes list)
+      // which caused this hit
+      gMC->StepProcesses(processes);
+      Int_t nofprocesses = processes.GetSize();
+      Int_t pid;
+      if (!nofprocesses) {
+        pid = 0;
+      }
+      else {
+        pid = processes[nofprocesses-1];               
+      }                
                
-       // generate Edep according to GEANT parametrisation
-       eDelta = TMath::Exp(fDeltaG->GetRandom()) - kPoti;
-        eDelta = TMath::Max(eDelta,0.0);
-       Float_t prRange = 0.0;
-       Float_t range   = gMC->TrackLength() - fTrackLength0;
-       // merge GEANT tracker information with locally cooked one
-       if (gAlice->GetMCApp()->GetCurrentTrackNumber() == fPrimaryTrackPid) {
-         if      (pid == 27) { 
-           if (eDelta >= kECut) {                
-             prRange = kRa * eDelta * 0.001
-                      * (1.0 - kRb / (1.0 + kRc * eDelta * 0.001)) / kRho;
-              if (prRange >= (3.7 - range)) {
-                eDelta *= 0.1;
-             }
-           }
-         } 
-          else if (pid ==  1) {        
-           if (eDelta <  kECut) {
+      // Generate Edep according to GEANT parametrisation
+      eDelta = TMath::Exp(fDeltaG->GetRandom()) - kPoti;
+      eDelta = TMath::Max(eDelta,0.0);
+      Float_t prRange = 0.0;
+      Float_t range   = gMC->TrackLength() - fTrackLength0;
+      // merge GEANT tracker information with locally cooked one
+      if (gAlice->GetMCApp()->GetCurrentTrackNumber() == fPrimaryTrackPid) {
+       if      (pid == 27) { 
+          if (eDelta >= kECut) {                
+            prRange = kRa * eDelta * 0.001
+                    * (1.0 - kRb / (1.0 + kRc * eDelta * 0.001)) / kRho;
+            if (prRange >= (3.7 - range)) {
+              eDelta *= 0.1;
+            }
+          }
+        } 
+        else if (pid ==  1) {  
+          if (eDelta <  kECut) {
+            eDelta *= 0.5;
+          }
+          else {                
+            prRange = kRa * eDelta * 0.001
+                    * (1.0 - kRb / (1.0 + kRc * eDelta * 0.001)) / kRho;
+            if (prRange >= ((AliTRDgeometry::DrThick()
+                           + AliTRDgeometry::AmThick()) - range)) {
+              eDelta *= 0.05;
+            }
+            else {
               eDelta *= 0.5;
-           }
-           else {                
-             prRange = kRa * eDelta * 0.001
-                      * (1.0 - kRb / (1.0 + kRc * eDelta * 0.001)) / kRho;
-              if (prRange >= ((AliTRDgeometry::DrThick()
-                             + AliTRDgeometry::AmThick()) - range)) {
-                eDelta *= 0.05;
-             }
-             else {
-                eDelta *= 0.5;
-             }
-           }
-         } 
-          else {
-            eDelta = 0.0;
-         }     
-       } 
+            }
+          }
+        } 
         else {
           eDelta = 0.0;
-       }
+        }      
+      } 
+      else {
+        eDelta = 0.0;
+      }
 
-        // Generate the electron cluster size
-        if (eDelta == 0.0) {
-          qTot = 0;
-       }
-       else {
-          qTot = ((Int_t) (eDelta / kWion) + 1);
-       }
+      // Generate the electron cluster size
+      if (eDelta > 0.0) {
 
-       // Create a new dEdx hit
+        qTot = ((Int_t) (eDelta / fWion) + 1);
+
+        // Create a new dEdx hit
         AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
               ,det
               ,hits
               ,qTot
+              ,gMC->TrackTime()*1.0e06
               ,drRegion);
-                               
-        // Calculate the maximum step size for the next tracking step
-       // Produce only one hit if Ekin is below cutoff
-        aMass = gMC->TrackMass();
-        if ((gMC->Etot() - aMass) > kEkinMinStep) {
-
-          // The energy loss according to Bethe Bloch
-          iPdg = TMath::Abs(gMC->TrackPid());
-          if ((iPdg != kPdgElectron) ||
-             ((iPdg == kPdgElectron) && 
-               (pTot  < kPTotMaxEl))) {
-            gMC->TrackMomentum(mom);
-            pTot      = mom.Rho();
-            betaGamma = pTot / aMass;
-            pp        = BetheBlochGeant(betaGamma);
-           // Take charge > 1 into account
-            charge     = gMC->TrackCharge();
-            if (TMath::Abs(charge) > 1) {
-              pp = pp * charge*charge;
-           }
-          } 
-          else { 
-            // Electrons above 20 Mev/c are at the plateau
-           pp = kPrim * kPlateau;
-          }
 
-         Int_t nsteps = 0;
-         do {
-            nsteps = gRandom->Poisson(pp);
-          } while(!nsteps);
-          stepSize = 1.0 / nsteps;
-         gMC->SetMaxStep(stepSize);
+      }
+                       
+      // Calculate the maximum step size for the next tracking step
+      // Produce only one hit if Ekin is below cutoff
+      aMass = gMC->TrackMass();
+      if ((gMC->Etot() - aMass) > kEkinMinStep) {
+
+        // The energy loss according to Bethe Bloch
+        iPdg = TMath::Abs(gMC->TrackPid());
+        if ((iPdg != kPdgElectron) ||
+           ((iPdg == kPdgElectron) && 
+             (pTot  < kPTotMaxEl))) {
+          gMC->TrackMomentum(mom);
+          pTot      = mom.Rho();
+          betaGamma = pTot / aMass;
+          pp        = BetheBlochGeant(betaGamma);
+         // Take charge > 1 into account
+          charge     = gMC->TrackCharge();
+          if (TMath::Abs(charge) > 1) {
+            pp = pp * charge*charge;
+          }
+        } 
+        else { 
+          // Electrons above 20 Mev/c are at the plateau
+          pp = kPrim * kPlateau;
+        }
 
-       }
+       Int_t nsteps = 0;
+        do {
+          nsteps = gRandom->Poisson(pp);
+        } while(!nsteps);
+        stepSize = 1.0 / nsteps;
+        gMC->SetMaxStep(stepSize);
 
       }
 
@@ -726,11 +717,13 @@ void AliTRDv1::StepManagerErmilova()
   // to Bethe-Bloch. The energy distribution of the delta electrons follows
   // a spectrum taken from Ermilova et al.
   //
+  // Works only for Xe/CO2!!
+  //
 
-  Int_t    pla = 0;
-  Int_t    cha = 0;
-  Int_t    sec = 0;
-  Int_t    det = 0;
+  Int_t    layer  = 0;
+  Int_t    stack  = 0;
+  Int_t    sector = 0;
+  Int_t    det    = 0;
   Int_t    iPdg;
   Int_t    qTot;
 
@@ -748,6 +741,10 @@ void AliTRDv1::StepManagerErmilova()
   Bool_t   drRegion = kFALSE;
   Bool_t   amRegion = kFALSE;
 
+  TString  cIdPath;
+  Char_t   cIdSector[3];
+           cIdSector[2]  = 0;
+
   TString  cIdCurrent;
   TString  cIdSensDr = "J";
   TString  cIdSensAm = "K";
@@ -757,12 +754,11 @@ void AliTRDv1::StepManagerErmilova()
   TLorentzVector pos;
   TLorentzVector mom;
 
-  const Int_t    kNplan       = AliTRDgeometry::Nplan();
-  const Int_t    kNcham       = AliTRDgeometry::Ncham();
-  const Int_t    kNdetsec     = kNplan * kNcham;
+  const Int_t    kNlayer      = AliTRDgeometry::Nlayer();
+  const Int_t    kNstack      = AliTRDgeometry::Nstack();
+  const Int_t    kNdetsec     = kNlayer * kNstack;
 
   const Double_t kBig         = 1.0e+12; // Infinitely big
-  const Float_t  kWion        = 23.53;   // Ionization energy
   const Float_t  kPTotMaxEl   = 0.002;   // Maximum momentum for e+ e- g 
 
   // Minimum energy for the step size adjustment
@@ -804,61 +800,57 @@ void AliTRDv1::StepManagerErmilova()
       hits[1] = pos[1];
       hits[2] = pos[2];
 
-      // The sector number (0 - 17)
-      // The numbering goes clockwise and starts at y = 0
-      Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
-      if (phi < 90.0) { 
-        phi = phi + 270.0;
-      }
-      else {
-        phi = phi -  90.0;
-      }
-      sec = ((Int_t) (phi / 20.0));
+      // The sector number (0 - 17), according to standard coordinate system
+      cIdPath      = gGeoManager->GetPath();
+      cIdSector[0] = cIdPath[21];
+      cIdSector[1] = cIdPath[22];
+      sector = atoi(cIdSector);
 
       // The plane and chamber number
       cIdChamber[0] = cIdCurrent[2];
       cIdChamber[1] = cIdCurrent[3];
       Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
-      cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
-      pla = ((Int_t) idChamber % kNplan);
-
-      // Check on selected volumes
-      Int_t addthishit = 1;
+      stack = ((Int_t) idChamber / kNlayer);
+      layer = ((Int_t) idChamber % kNlayer);
+
+      // The detector number
+      det = fGeometry->GetDetector(layer,stack,sector);
+
+      // Special hits only in the drift region
+      if      ((drRegion) &&
+               (gMC->IsTrackEntering())) {
+
+        // Create a track reference at the entrance of each
+        // chamber that contains the momentum components of the particle
+        gMC->TrackMomentum(mom);
+        AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
+
+        // Create the hits from TR photons if electron/positron is
+        // entering the drift volume
+        if ((fTR) && 
+            (TMath::Abs(gMC->TrackPid()) == kPdgElectron)) {
+          CreateTRhit(det);
+        }
 
-      // Add this hit
-      if (addthishit) {
+      }
+      else if ((amRegion) && 
+               (gMC->IsTrackExiting())) {
 
-       // The detector number
-        det = fGeometry->GetDetector(pla,cha,sec);
+        // Create a track reference at the exit of each
+        // chamber that contains the momentum components of the particle
+        gMC->TrackMomentum(mom);
+        AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
 
-       // Special hits only in the drift region
-        if (drRegion) {
+      }
 
-          // Create a track reference at the entrance and
-          // exit of each chamber that contain the 
-         // momentum components of the particle
-          if (gMC->IsTrackEntering() || 
-              gMC->IsTrackExiting()) {
-            gMC->TrackMomentum(mom);
-            AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
-          }
-          // Create the hits from TR photons
-          if (fTR) {
-            CreateTRhit(det);
-         }
+      // Calculate the energy of the delta-electrons
+      eDelta = TMath::Exp(fDeltaE->GetRandom()) - kPoti;
+      eDelta = TMath::Max(eDelta,0.0);
 
-       }
+      // Generate the electron cluster size
+      if (eDelta > 0.0) {
 
-        // Calculate the energy of the delta-electrons
-        eDelta = TMath::Exp(fDeltaE->GetRandom()) - kPoti;
-        eDelta = TMath::Max(eDelta,0.0);
-        // Generate the electron cluster size
-        if (eDelta == 0.0) {
-          qTot = 0;
-       }
-       else {
-          qTot = ((Int_t) (eDelta / kWion) + 1);
-       }
+        qTot = ((Int_t) (eDelta / fWion) + 1);
 
        // Create a new dEdx hit
         if (drRegion) {
@@ -866,6 +858,7 @@ void AliTRDv1::StepManagerErmilova()
                 ,det
                 ,hits
                 ,qTot
+                ,gMC->TrackTime()*1.0e06
                 ,kTRUE);
        }
         else {
@@ -873,45 +866,46 @@ void AliTRDv1::StepManagerErmilova()
                 ,det
                 ,hits
                 ,qTot
+                ,gMC->TrackTime()*1.0e06
                 ,kFALSE);
        }
 
-        // Calculate the maximum step size for the next tracking step
-       // Produce only one hit if Ekin is below cutoff 
-        aMass = gMC->TrackMass();
-        if ((gMC->Etot() - aMass) > kEkinMinStep) {
-
-          // The energy loss according to Bethe Bloch
-          iPdg  = TMath::Abs(gMC->TrackPid());
-          if ((iPdg != kPdgElectron) ||
-             ((iPdg == kPdgElectron) && 
-               (pTot  < kPTotMaxEl))) {
-            gMC->TrackMomentum(mom);
-            pTot      = mom.Rho();
-            betaGamma = pTot / aMass;
-            pp        = kPrim * BetheBloch(betaGamma);
-           // Take charge > 1 into account
-            charge = gMC->TrackCharge();
-            if (TMath::Abs(charge) > 1) {
-              pp = pp * charge*charge;
-           }
-          } 
-          else { 
-            // Electrons above 20 Mev/c are at the plateau
-           pp = kPrim * kPlateau;
+      }
+
+      // Calculate the maximum step size for the next tracking step
+      // Produce only one hit if Ekin is below cutoff 
+      aMass = gMC->TrackMass();
+      if ((gMC->Etot() - aMass) > kEkinMinStep) {
+
+        // The energy loss according to Bethe Bloch
+        iPdg  = TMath::Abs(gMC->TrackPid());
+        if ((iPdg != kPdgElectron) ||
+           ((iPdg == kPdgElectron) && 
+             (pTot  < kPTotMaxEl))) {
+          gMC->TrackMomentum(mom);
+          pTot      = mom.Rho();
+          betaGamma = pTot / aMass;
+          pp        = kPrim * BetheBloch(betaGamma);
+          // Take charge > 1 into account
+          charge = gMC->TrackCharge();
+          if (TMath::Abs(charge) > 1) {
+            pp = pp * charge*charge;
           }
+        } 
+        else { 
+          // Electrons above 20 Mev/c are at the plateau
+         pp = kPrim * kPlateau;
+        }
       
-          if (pp > 0.0) {
-            do {
-              gMC->GetRandom()->RndmArray(1,random);
-           }
-            while ((random[0] == 1.0) || 
-                   (random[0] == 0.0));
-            stepSize = - TMath::Log(random[0]) / pp; 
-            gMC->SetMaxStep(stepSize);
+        if (pp > 0.0) {
+          do {
+            gMC->GetRandom()->RndmArray(1,random);
          }
-
-       }
+          while ((random[0] == 1.0) || 
+                 (random[0] == 0.0));
+          stepSize = - TMath::Log(random[0]) / pp; 
+          gMC->SetMaxStep(stepSize);
+        }
 
       }
 
@@ -929,11 +923,16 @@ void AliTRDv1::StepManagerFixedStep()
   // along its path across the drift volume. The step size is fixed in
   // this version of the step manager.
   //
+  // Works for Xe/CO2 as well as Ar/CO2
+  //
+
+  // PDG code electron
+  const Int_t   kPdgElectron = 11;
 
-  Int_t    pla = 0;
-  Int_t    cha = 0;
-  Int_t    sec = 0;
-  Int_t    det = 0;
+  Int_t    layer  = 0;
+  Int_t    stack  = 0;
+  Int_t    sector = 0;
+  Int_t    det    = 0;
   Int_t    qTot;
 
   Float_t  hits[3];
@@ -942,22 +941,24 @@ void AliTRDv1::StepManagerFixedStep()
   Bool_t   drRegion = kFALSE;
   Bool_t   amRegion = kFALSE;
 
+  TString  cIdPath;
+  Char_t   cIdSector[3];
+           cIdSector[2]  = 0;
+
   TString  cIdCurrent;
   TString  cIdSensDr = "J";
   TString  cIdSensAm = "K";
   Char_t   cIdChamber[3];
-  cIdChamber[2] = 0;
+           cIdChamber[2] = 0;
 
   TLorentzVector pos;
   TLorentzVector mom;
 
-  const Int_t    kNplan       = AliTRDgeometry::Nplan();
-  const Int_t    kNcham       = AliTRDgeometry::Ncham();
-  const Int_t    kNdetsec     = kNplan * kNcham;
+  const Int_t    kNlayer      = AliTRDgeometry::Nlayer();
+  const Int_t    kNstack      = AliTRDgeometry::Nstack();
+  const Int_t    kNdetsec     = kNlayer * kNstack;
 
   const Double_t kBig         = 1.0e+12;
-
-  const Float_t  kWion        = 23.53;   // Ionization energy
   const Float_t  kEkinMinStep = 1.0e-5;  // Minimum energy for the step size adjustment
 
   // Set the maximum step size to a very large number for all 
@@ -966,13 +967,19 @@ void AliTRDv1::StepManagerFixedStep()
 
   // If not charged track or already stopped or disappeared, just return.
   if ((!gMC->TrackCharge()) || 
-        gMC->IsTrackDisappeared()) return;
+        gMC->IsTrackDisappeared()) {
+    return;
+  }
 
   // Inside a sensitive volume?
   cIdCurrent = gMC->CurrentVolName();
 
-  if (cIdSensDr == cIdCurrent[1]) drRegion = kTRUE;
-  if (cIdSensAm == cIdCurrent[1]) amRegion = kTRUE;
+  if (cIdSensDr == cIdCurrent[1]) {
+    drRegion = kTRUE;
+  }
+  if (cIdSensAm == cIdCurrent[1]) {
+    amRegion = kTRUE;
+  }
 
   if ((!drRegion) && 
       (!amRegion)) {
@@ -985,70 +992,67 @@ void AliTRDv1::StepManagerFixedStep()
   hits[1] = pos[1];
   hits[2] = pos[2];
 
-  // The sector number (0 - 17)
-  // The numbering goes clockwise and starts at y = 0
-  Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
-  if (phi < 90.0) {
-    phi = phi + 270.0;
-  }
-  else {          
-    phi = phi -  90.0;
-  }
-  sec = ((Int_t) (phi / 20.0));
+  // The sector number (0 - 17), according to standard coordinate system
+  cIdPath      = gGeoManager->GetPath();
+  cIdSector[0] = cIdPath[21];
+  cIdSector[1] = cIdPath[22];
+  sector = atoi(cIdSector);
 
   // The plane and chamber number
   cIdChamber[0]   = cIdCurrent[2];
   cIdChamber[1]   = cIdCurrent[3];
   Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
-  cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
-  pla = ((Int_t) idChamber % kNplan);
-
-  // Check on selected volumes
-  Int_t addthishit = 1;
-
-  if (!addthishit) {
-    return;
-  }
+  stack = ((Int_t) idChamber / kNlayer);
+  layer = ((Int_t) idChamber % kNlayer);
 
   // The detector number
-  det = fGeometry->GetDetector(pla,cha,sec);
+  det = fGeometry->GetDetector(layer,stack,sector);
 
   // 0: InFlight 1:Entering 2:Exiting
   Int_t trkStat = 0;
 
   // Special hits only in the drift region
-  if (drRegion) {
-
-    // Create a track reference at the entrance and exit of each
-    // chamber that contain the momentum components of the particle
+  if      ((drRegion) &&
+           (gMC->IsTrackEntering())) {
 
-    if (gMC->IsTrackEntering()) {
-      gMC->TrackMomentum(mom);
-      AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
-      trkStat = 1;
-    }
-    if (gMC->IsTrackExiting()) {
-      gMC->TrackMomentum(mom);
-      AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
-      trkStat = 2;
+    // Create a track reference at the entrance of each
+    // chamber that contains the momentum components of the particle
+    gMC->TrackMomentum(mom);
+    AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
+    trkStat = 1;
+
+    // Create the hits from TR photons if electron/positron is
+    // entering the drift volume
+    if ((fTR) && 
+        (TMath::Abs(gMC->TrackPid()) == kPdgElectron)) {
+      CreateTRhit(det);
     }
 
-    // Create the hits from TR photons
-    if (fTR) {
-      CreateTRhit(det);    
-    }
+  }
+  else if ((amRegion) && 
+           (gMC->IsTrackExiting())) {
+
+    // Create a track reference at the exit of each
+    // chamber that contains the momentum components of the particle
+    gMC->TrackMomentum(mom);
+    AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
+    trkStat = 2;
 
   }
   
   // Calculate the charge according to GEANT Edep
   // Create a new dEdx hit
   eDep = TMath::Max(gMC->Edep(),0.0) * 1.0e+09;
-  qTot = (Int_t) (eDep / kWion);
-  AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
-        ,det
-        ,hits
-        ,qTot
-        ,drRegion);
+  qTot = (Int_t) (eDep / fWion);
+  if ((qTot) ||
+      (trkStat)) {
+    AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
+          ,det
+          ,hits
+          ,qTot
+          ,gMC->TrackTime()*1.0e06
+          ,drRegion);
+  }
 
   // Set Maximum Step Size
   // Produce only one hit if Ekin is below cutoff
@@ -1247,6 +1251,10 @@ Double_t IntSpecGeant(Double_t *x, Double_t *)
   Int_t    i;
   Double_t energy = x[0];
 
+  if (energy >= arre[npts-1]) {
+    return 0.0;
+  }
+
   for (i = 0; i < npts; i++) {
     if (energy < arre[i]) {
       break;