]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Corrections for Lorentz drift - Savannah bug 74658
authormasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 2 Nov 2010 15:09:03 +0000 (15:09 +0000)
committermasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 2 Nov 2010 15:09:03 +0000 (15:09 +0000)
ITS/AliITSClusterFinderV2SPD.cxx
ITS/AliITSClusterFinderV2SSD.cxx
ITS/AliITSClusterFinderV2SSD.h
ITS/AliITSRecoParam.cxx
ITS/AliITSRecoParam.h
ITS/AliITSSimuParam.cxx
ITS/AliITSSimuParam.h
ITS/AliITSsimulationSSD.cxx
ITS/AliITSsimulationSSD.h

index 75e1dac79628d09b0a23128996a6159526f68d62..2f193c04755057894bf207dd93162f5857388105 100644 (file)
@@ -21,6 +21,7 @@
 ////////////////////////////////////////////////////////////////////////////
 
 
+#include <TGeoGlobalMagField.h>
 #include "AliITSCalibrationSPD.h"
 #include "AliITSClusterFinderV2SPD.h"
 #include "AliITSRecPoint.h"
@@ -33,6 +34,8 @@
 #include "AliITSdigitSPD.h"
 #include "AliITSFOSignalsSPD.h"
 #include "AliITSRecPointContainer.h"
+#include "AliMagF.h"
+#include "AliITSsegmentationSPD.h"
 
 ClassImp(AliITSClusterFinderV2SPD)
 
@@ -87,6 +90,8 @@ void AliITSClusterFinderV2SPD::RawdataToClusters(AliRawReader* rawReader){
 Int_t AliITSClusterFinderV2SPD::ClustersSPD(AliBin* bins, TClonesArray* digits,TClonesArray* clusters,Int_t maxBins,Int_t nzbins,Int_t iModule,Bool_t rawdata){
   
   //Cluster finder for SPD (from digits and from rawdata)
+  const Double_t kmictocm = 1.0e-4; // convert microns to cm.
+  const Double_t defaultField = 5.0; // default Bz value at which Tan(theta_Lorentz) is given in RecoParam
 
   static AliITSRecoParam *repa = NULL;
   if(!repa){
@@ -98,6 +103,20 @@ Int_t AliITSClusterFinderV2SPD::ClustersSPD(AliBin* bins, TClonesArray* digits,T
   }
   const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(iModule);
 
+  // Lorentz angle correction
+  Double_t tanLorentzAngle=0; 
+  AliITSsegmentationSPD *seg = (AliITSsegmentationSPD*)(GetDetTypeRec()->GetSegmentationModel(0));
+  Double_t thick = 0.5*kmictocm*seg->Dy();  // Half Thickness in cm
+  if(repa->GetCorrectLorentzAngleSPD()) { // only if CorrectLorentzAngleSPD required
+    // here retrieve the value of the field
+    AliMagF* field = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
+    if (field == 0)
+      AliError("Cannot get magnetic field from TGeoGlobalMagField");
+    Float_t magField = field->SolenoidField();
+    tanLorentzAngle=repa->GetTanLorentzAngleHolesSPD() * magField / defaultField ;
+  }
+  //
+
    if (repa->GetSPDRemoveNoisyFlag()) {
     // Loop on noisy pixels and reset them
     AliITSCalibrationSPD *cal =  
@@ -241,6 +260,10 @@ Int_t AliITSClusterFinderV2SPD::ClustersSPD(AliBin* bins, TClonesArray* digits,T
        y -= fHwSPD;
        z -= fHlSPD;
 
+        // Lorentz drift effect in local y
+        y -= tanLorentzAngle*thick;
+        //
+
        Float_t hit[5]; //y,z,sigma(y)^2, sigma(z)^2, charge
         {
         Double_t loc[3]={y,0.,z},trk[3]={0.,0.,0.};
index 7f7427a27c38ec870af121196edab19898af7bef..0d622498c82ee27fd2bd4cb998f80b563e2f8f37 100644 (file)
 //                                                                        //
 ///////////////////////////////////////////////////////////////////////////
 
+#include "AliITSClusterFinderV2SSD.h"
+
 #include <Riostream.h>
-#include "AliLog.h"
+#include <TGeoGlobalMagField.h>
 
-#include "AliITSClusterFinderV2SSD.h"
+#include "AliLog.h"
+#include "AliMagF.h"
 #include "AliITSRecPoint.h"
 #include "AliITSRecPointContainer.h"
 #include "AliITSgeomTGeo.h"
@@ -66,15 +69,34 @@ const Float_t AliITSClusterFinderV2SSD::fgkCosmic2008StripShifts[16][9] =
 ClassImp(AliITSClusterFinderV2SSD)
 
 
-AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),
-                                                                            fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1)
+  AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1), fLorentzShiftP(0), fLorentzShiftN(0)
 {
 //Default constructor
+  static AliITSRecoParam *repa = NULL;  
+  if(!repa){
+    repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
+    if(!repa){
+      repa = AliITSRecoParam::GetHighFluxParam();
+      AliWarning("Using default AliITSRecoParam class");
+    }
+  }
 
+  if (repa->GetCorrectLorentzAngleSSD()) {
+    AliMagF* field = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField()); 
+    if (field == 0)
+      AliError("Cannot get magnetic field from TGeoGlobalMagField");
+    Float_t Bfield = field->SolenoidField();
+    // NB: spatial shift has opposite sign for lay 5 and 6, but strip numbering also changes direction, so no sign-change 
+    // Shift due to ExB on drift N-side, units: strip width 
+    fLorentzShiftP = -repa->GetTanLorentzAngleElectronsSSD() * 150.e-4/95.e-4 * Bfield / 5.0;
+    // Shift due to ExB on drift P-side, units: strip width 
+    fLorentzShiftN = -repa->GetTanLorentzAngleHolesSSD() * 150.e-4/95.e-4 * Bfield / 5.0;
+    AliDebug(1,Form("Bfield %f Lorentz Shift P-side %f N-side %f",Bfield,fLorentzShiftN,fLorentzShiftP));
+  }
 }
  
 //______________________________________________________________________
-AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinder(cf),                                              fLastSSD1(cf.fLastSSD1)
+AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinder(cf), fLastSSD1(cf.fLastSSD1), fLorentzShiftP(cf.fLorentzShiftP), fLorentzShiftN(cf.fLorentzShiftN)
 {
   // Copy constructor
 }
@@ -162,6 +184,9 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
   cout<<endl;
   cout<<endl;
   */
+  Int_t layer = 4;
+  if (fModule>fLastSSD1) 
+    layer = 5;
 
   //--------------------------------------------------------
   // start 1D-clustering from the first digit in the digits array
@@ -221,7 +246,14 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
 
        if(flag5) {
          //cout<<"here1"<<endl;
-         c[*n].SetY(y/q);
+         Float_t dLorentz = 0;
+         if (!flag) { // P-side is neg clust
+           dLorentz = fLorentzShiftN;
+         }
+         else { // N-side is p clust
+           dLorentz = fLorentzShiftP;
+         }
+         c[*n].SetY(y/q+dLorentz);
          c[*n].SetQ(q);
          c[*n].SetNd(nd);
         CheckLabels2(milab);
@@ -232,14 +264,14 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
 
           //Split suspiciously big cluster
           if (nd>4&&nd<25) {
-            c[*n].SetY(y/q-0.25*nd);
+            c[*n].SetY(y/q-0.25*nd+dLorentz);
             c[*n].SetQ(0.5*q);
             (*n)++;
             if (*n==kMax) {
               Error("FindClustersSSD","Too many 1D clusters !");
               return;
             }
-            c[*n].SetY(y/q+0.25*nd);
+            c[*n].SetY(y/q+0.25*nd+dLorentz);
             c[*n].SetQ(0.5*q);
             c[*n].SetNd(nd);
             c[*n].SetLabels(milab);
@@ -311,8 +343,15 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
   if(flag5) {
 
     // cout<<"here2"<<endl;
-
-    c[*n].SetY(y/q);
+    Float_t dLorentz = 0;
+    if (!flag) { // P-side is neg clust
+      dLorentz = fLorentzShiftN;
+    }
+    else { // N-side is p clust
+      dLorentz = fLorentzShiftP;
+    }
+    
+    c[*n].SetY(y/q + dLorentz);
     c[*n].SetQ(q);
     c[*n].SetNd(nd);
     c[*n].SetLabels(lab);
@@ -321,14 +360,14 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
       
       //Split suspiciously big cluster
       if (nd>4 && nd<25) {
-       c[*n].SetY(y/q-0.25*nd);
+       c[*n].SetY(y/q-0.25*nd + dLorentz);
        c[*n].SetQ(0.5*q);
        (*n)++;
        if (*n==kMax) {
          Error("FindClustersSSD","Too many 1D clusters !");
          return;
        }
-       c[*n].SetY(y/q+0.25*nd);
+       c[*n].SetY(y/q+0.25*nd + dLorentz);
        c[*n].SetQ(0.5*q);
        c[*n].SetNd(nd);
        c[*n].SetLabels(lab);
@@ -367,7 +406,7 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
 
 void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader){
 
-    //------------------------------------------------------------
+  //------------------------------------------------------------
   // This function creates ITS clusters from raw data
   //------------------------------------------------------------
   rawReader->Reset();
@@ -461,6 +500,10 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
 //CM channels are always present even everything is suppressed 
          continue;
        }
+       
+       Int_t layer = 4;
+       if (fModule>fLastSSD1) 
+         layer = 5;
 
        AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)fDetTypeRec->GetCalibrationModel(fModule);
        if( !cal ){
@@ -486,6 +529,14 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
          Int_t nDigits = 0;
          Int_t ostrip = -2;
          Bool_t snFlag = 0;
+
+         Float_t dLorentz = 0;
+         if (side==0) { // P-side is neg clust
+           dLorentz = fLorentzShiftN;
+         }
+         else { // N-side is pos clust
+           dLorentz = fLorentzShiftP;
+         }
          
          Int_t n = nStrips[adc][side];
          for( int istr = 0; istr<n+1; istr++ ){
@@ -522,7 +573,7 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
                }else {
                  
                  Ali1Dcluster &cluster = clusters1D[side][nClusters1D[side]++];
-                 cluster.SetY( y / q + dStrip);
+                 cluster.SetY( y / q + dStrip + dLorentz);
                  cluster.SetQ(q);
                  cluster.SetNd(nDigits);
                  cluster.SetLabels(lab);
@@ -532,10 +583,10 @@ void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
                  if( repa->GetUseUnfoldingInClusterFinderSSD()
                      && nDigits > 4 && nDigits < 25 
                      ){
-                   cluster.SetY(y/q + dStrip - 0.25*nDigits);      
+                   cluster.SetY(y/q + dStrip - 0.25*nDigits + dLorentz);           
                    cluster.SetQ(0.5*q);          
                    Ali1Dcluster& cluster2 = clusters1D[side][nClusters1D[side]++];
-                   cluster2.SetY(y/q + dStrip + 0.25*nDigits);     
+                   cluster2.SetY(y/q + dStrip + 0.25*nDigits + dLorentz);          
                    cluster2.SetQ(0.5*q);
                    cluster2.SetNd(nDigits);
                    cluster2.SetLabels(lab);      
index ab9a39f8d7f78192ca50130aabab252f7ed994e0..8051f2edff9fe1891e262a185a17d606ca406567 100644 (file)
@@ -42,6 +42,8 @@ public:
     return (AliITSCalibrationSSD*) fDetTypeRec->GetCalibrationModel(mod);}
 
   Int_t fLastSSD1;        //index of the last SSD1 detector   
+  Float_t  fLorentzShiftP; // Shift due to ExB on drift N-side @ actual B field, layer 5, units: strip width 
+  Float_t  fLorentzShiftN; // Shift due to ExB on drift P-side @ actual B field, layer 5, units: strip width
   static Short_t* fgPairs;       //array used to build positive-negative pairs
   static Int_t    fgPairsSize;    //actual size of pairs array
   static const Float_t fgkCosmic2008StripShifts[16][9]; // Shifts for 2007/2008 Cosmic data (timing problem)
index b17f0c84d97e92703fb58eabebe43b9c5d65b43c..55bedd66ec638274cda9f9b341db023a47ef7ca4 100644 (file)
@@ -213,10 +213,10 @@ fMultCutK0SFromDecay(-10.),
 fMultCutMaxDCA(1.),
 //
 fCorrectLorentzAngleSPD(kFALSE),
-fLorentzAngleHolesSPD(0.),
+fTanLorentzAngleHolesSPD(0.017455), // tan(1 degree)
 fCorrectLorentzAngleSSD(kFALSE),
-fLorentzAngleHolesSSD(0.),
-fLorentzAngleElectronsSSD(0.),
+fTanLorentzAngleHolesSSD(0.016),  // tan(0.94 degrees)
+fTanLorentzAngleElectronsSSD(0.068), // tan(3.98 degrees)
 //
 fESDV0Params(NULL)
 {
index ae43d5e433cb658e06b6a4883b9e5244da4146f6..0a86fac2c575601f125561e890d338e9178c915e 100644 (file)
@@ -436,16 +436,16 @@ class AliITSRecoParam : public AliDetectorRecoParam
   //
   // Lorentz angle
   Bool_t  GetCorrectLorentzAngleSPD() const {return fCorrectLorentzAngleSPD;}
-  Float_t GetLorentzAngleHolesSPD() const {return fLorentzAngleHolesSPD;}
+  Float_t GetTanLorentzAngleHolesSPD() const {return fTanLorentzAngleHolesSPD;}
   Bool_t  GetCorrectLorentzAngleSSD() const {return fCorrectLorentzAngleSSD;}
-  Float_t GetLorentzAngleHolesSSD() const {return fLorentzAngleHolesSSD;}
-  Float_t GetLorentzAngleElectronsSSD() const {return fLorentzAngleElectronsSSD;}
+  Float_t GetTanLorentzAngleHolesSSD() const {return fTanLorentzAngleHolesSSD;}
+  Float_t GetTanLorentzAngleElectronsSSD() const {return fTanLorentzAngleElectronsSSD;}
 
   void SetCorrectLorentzAngleSPD(Bool_t flag) {fCorrectLorentzAngleSPD=flag;}
-  void SetLorentzAngleHolesSPD(Float_t la) {fLorentzAngleHolesSPD=la;}
+  void SetTanLorentzAngleHolesSPD(Float_t la) {fTanLorentzAngleHolesSPD=la;}
   void SetCorrectLorentzAngleSSD(Bool_t flag) {fCorrectLorentzAngleSSD=flag;}
-  void SetLorentzAngleHolesSSD(Float_t la) {fLorentzAngleHolesSSD=la;}
-  void SetLorentzAngleElectronsSSD(Float_t la) {fLorentzAngleElectronsSSD=la;}
+  void SetTanLorentzAngleHolesSSD(Float_t la) {fTanLorentzAngleHolesSSD=la;}
+  void SetTanLorentzAngleElectronsSSD(Float_t la) {fTanLorentzAngleElectronsSSD=la;}
 
   //
   enum {fgkMaxClusterPerLayer=70000}; //7000*10;   // max clusters per layer
@@ -705,10 +705,10 @@ class AliITSRecoParam : public AliDetectorRecoParam
   //
   // Lorentz angle
   Bool_t fCorrectLorentzAngleSPD;         // flag to enable correction
-  Float_t fLorentzAngleHolesSPD;          // angle for holes in SPD
+  Float_t fTanLorentzAngleHolesSPD;       // angle for holes in SPD
   Bool_t fCorrectLorentzAngleSSD;         // flag to enable correction
-  Float_t fLorentzAngleHolesSSD;          // angle for holes in SSD
-  Float_t fLorentzAngleElectronsSSD;          // angle for electrons in SSD
+  Float_t fTanLorentzAngleHolesSSD;       // tan(angle) for holes in SSD @ B = 0.5 T
+  Float_t fTanLorentzAngleElectronsSSD;   // tan(angle) for electrons in SSD @ B = 0.5 T
 
  private:
   AliESDV0Params * fESDV0Params;  // declare the AliESDV0Params to be able to used in AliITSV0Finder
@@ -716,7 +716,7 @@ class AliITSRecoParam : public AliDetectorRecoParam
   AliITSRecoParam(const AliITSRecoParam & param);
   AliITSRecoParam & operator=(const AliITSRecoParam &param);
 
-  ClassDef(AliITSRecoParam,33) // ITS reco parameters
+  ClassDef(AliITSRecoParam,34) // ITS reco parameters
 };
 
 #endif
index a92cee2513e65d4ae61ea87e9c14f8beb2c19d6e..6548c62e34d5571731c965b4b909ac0f04505de6 100644 (file)
@@ -77,6 +77,7 @@ fSDDMaxAdc(0.),
 fSDDChargeLoss(fgkSDDChargeLossDefault),
 fSDDTrigDelay(fgkSDDTrigDelayDefault),
 fSDDRawFormat(7),
+fSSDLorentzDrift(kTRUE),
 fSSDCouplingPR(0),
 fSSDCouplingPL(0),
 fSSDCouplingNR(0),
@@ -126,6 +127,7 @@ fSDDMaxAdc(simpar.fSDDMaxAdc),
 fSDDChargeLoss(simpar.fSDDChargeLoss),
 fSDDTrigDelay(simpar.fSDDTrigDelay),
 fSDDRawFormat(simpar.fSDDRawFormat),
+fSSDLorentzDrift(simpar.fSSDLorentzDrift),
 fSSDCouplingPR(simpar.fSSDCouplingPR),
 fSSDCouplingPL(simpar.fSSDCouplingPL),
 fSSDCouplingNR(simpar.fSSDCouplingNR),
@@ -200,6 +202,7 @@ void AliITSSimuParam::PrintParameters() const{
   printf("Raw Data Format           = %d\n",fSDDRawFormat);  
   printf("\n");
   printf("=====  SSD parameters  =====\n");
+  printf("Flag to add Lorentz Drift = %d\n",fSSDLorentzDrift);
   printf("Coupling PR               = %f\n",fSSDCouplingPR);
   printf("Coupling PL               = %f\n",fSSDCouplingPL);
   printf("Coupling NR               = %f\n",fSSDCouplingNR);
index 0163e93134037a4d59044dadcd447a131380daf7..0d0c091cf7f7a6989db93b3acf302239e11156ce 100644 (file)
@@ -103,6 +103,11 @@ class AliITSSimuParam : public TObject {
   void    SetSDDRawDataFormatCarlos() {fSDDRawFormat=7;}
   void    SetSDDRawDataFormatFixLen8bitEncoded() {fSDDRawFormat=0;}
   Char_t  GetSDDRawDataFormat() const {return fSDDRawFormat;}
+
+  // Use Lorentz's angle
+  void    SetSSDLorentzDrift(Bool_t ison) {fSSDLorentzDrift=ison;}
+  Bool_t  GetSSDLorentzDrift() const {return fSSDLorentzDrift;}
+
   Int_t GetSSDZSThreshold() const { // ZS threshold
     return fSSDZSThreshold; }
   virtual void SetSSDZSThreshold(Int_t zsth) { fSSDZSThreshold = zsth; }
@@ -240,6 +245,8 @@ class AliITSSimuParam : public TObject {
   Float_t  fSDDTrigDelay;    // SDD time-zero
   Char_t   fSDDRawFormat;    // Index for SDD RawFormat
   
+  Bool_t   fSSDLorentzDrift;     // Flag to decide whether to simulate the Lorentz Drift or not in SSD
+
   Double_t fSSDCouplingPR;  // SSD couplings
   Double_t fSSDCouplingPL;  // SSD couplings
   Double_t fSSDCouplingNR;  // SSD couplings
index ae473468b46aa202dde3bc4f231e472ff77d7b88..fc4d5ca2d41a06e07dcf61f0d8b524e08db15df3 100644 (file)
@@ -21,6 +21,7 @@
 #include <TObjArray.h>
 #include <TRandom.h>
 
+#include <TGeoGlobalMagField.h>
 #include "AliITSmodule.h"
 #include "AliITSMapA2.h"
 #include "AliITSpList.h"
@@ -31,6 +32,7 @@
 #include "AliITShit.h"
 #include "AliITSdigitSSD.h"
 #include "AliRun.h"
+#include "AliMagF.h"
 #include "AliITSgeom.h"
 #include "AliITSsimulationSSD.h"
 #include "AliITSTableSSD.h"
@@ -54,7 +56,11 @@ fMapA2(0),
 fIonE(0.0),
 fDifConst(),
 fDriftVel(),
-fTimeResponse(NULL){
+fTimeResponse(NULL),
+fLorentz(kFALSE),
+fTanLorAngP(0),
+fTanLorAngN(0)
+{
     //default Constructor
     //Inputs:
     // none.
@@ -71,7 +77,11 @@ fMapA2(0),
 fIonE(0.0),
 fDifConst(),
 fDriftVel(),
-fTimeResponse(NULL){
+fTimeResponse(NULL),
+fLorentz(kFALSE),
+fTanLorAngP(0),
+fTanLorAngN(0)
+{
     // Constructor 
     // Input:
     //   AliITSDetTypeSim    Pointer to the SSD dettype to be used
@@ -94,13 +104,38 @@ void AliITSsimulationSSD::Init(){
   // Return
   //   none.
   AliITSsegmentationSSD* seg = (AliITSsegmentationSSD*)GetSegmentationModel(2);
+  AliITSSimuParam* simpar = fDetType->GetSimuParam();
   
   SetDriftVelocity(); // use default values in .h file
   SetIonizeE();       // use default values in .h file
   SetDiffConst();     // use default values in .h file
   fpList           = new AliITSpList(2,GetNStrips());
   fMapA2           = new AliITSMapA2(seg);
+  SetLorentzDrift(simpar->GetSSDLorentzDrift());
+  if (fLorentz) SetTanLorAngle();
 }
+
+//______________________________________________________________________
+Bool_t AliITSsimulationSSD::SetTanLorAngle() {
+    // This function set the Tangent of the Lorentz angles. 
+    // output: Bool_t : kTRUE in case of success
+    //
+
+    if(!fDetType) {
+      AliError("AliITSsimulationSPD::SetTanLorAngle: AliITSDetTypeSim* fDetType not set ");
+      return kFALSE;}
+
+    AliITSSimuParam* simpar = fDetType->GetSimuParam();
+    AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+    if (!fld) AliFatal("The field is not initialized");
+    Double_t bz = fld->SolenoidField();
+
+    fTanLorAngN = TMath::Tan( simpar->LorentzAngleElectron(bz) );
+    fTanLorAngP = TMath::Tan( simpar->LorentzAngleHole(bz) );
+
+    return kTRUE;
+}
+
 //______________________________________________________________________
 AliITSsimulationSSD& AliITSsimulationSSD::operator=(
                                          const AliITSsimulationSSD &s){
@@ -116,6 +151,9 @@ AliITSsimulationSSD& AliITSsimulationSSD::operator=(
   this->fDriftVel[0] = s.fDriftVel[0];
   this->fDriftVel[1] = s.fDriftVel[1];
   this->fTimeResponse = s.fTimeResponse;
+  this->fLorentz   = s.fLorentz;
+  this->fTanLorAngP = s.fTanLorAngP;
+  this->fTanLorAngN = s.fTanLorAngN;
   return *this;
 }
 /*
@@ -138,7 +176,11 @@ fMapA2(source.fMapA2),
 fIonE(source.fIonE),
 fDifConst(),
 fDriftVel(),
-fTimeResponse(source.fTimeResponse){
+fTimeResponse(source.fTimeResponse),
+fLorentz(source.fLorentz),
+fTanLorAngP(source.fTanLorAngP),
+fTanLorAngN(source.fTanLorAngN)
+{
   // copy constructor
   fDifConst[0] = source.fDifConst[0];
   fDifConst[1] = source.fDifConst[1];
@@ -238,6 +280,7 @@ void AliITSsimulationSSD::HitsToAnalogDigits(AliITSmodule *mod,
   module = mod->GetIndex();
   if ( mod->GetLayer() == 6 ) seg->SetLayer(6);
   if ( mod->GetLayer() == 5 ) seg->SetLayer(5);
+
   for(Int_t i=0; i<nhits; i++) {    
     // LineSegmentL returns 0 if the hit is entering
     // If hits is exiting returns positions of entering and exiting hits
@@ -288,7 +331,15 @@ void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0,
   Double_t tdrift[2] = {0.,0.}; // time of drift
   Double_t w;
   Double_t inf[2], sup[2], par0[2];                 
-  
+  // Set up corrections for Lorentz drift (ExB)
+  Double_t TanLorAngP = fTanLorAngP;
+  Double_t TanLorAngN = fTanLorAngN;
+  if(seg->GetLayer()==6) {
+    TanLorAngP = -1.*fTanLorAngP;
+    TanLorAngN = -1.*fTanLorAngN;
+  }
+
   // Steps in the module are determined "manually" (i.e. No Geant)
   // NumOfSteps divide path between entering and exiting hits in steps 
   Int_t numOfSteps = NumOfSteps(x1, y1, z1, dex, dey, dez);
@@ -319,16 +370,23 @@ void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0,
       y=-y; // Lay6 module has sensor up-side-down!!!
     }
     
-    // w is the coord. perpendicular to the strips
-    //    Float_t xp=x*1.e+4,zp=z*1.e+4; // microns    
-    Float_t xp=x,zp=z; 
-    seg->GetPadTxz(xp,zp);
-
     Int_t k;
     //---------------------------------------------------------
     // Pside
     //------------------------------------------------------------
     k=0;
+
+    // w is the coord. perpendicular to the strips
+    //    Float_t xp=x*1.e+4,zp=z*1.e+4; // microns    
+    Float_t xp=x,zp=z; 
+
+    // correction for the Lorentz's angle
+    if(fLorentz) {
+      Float_t deltaxp = (y+(seg->Dy()*1.0E-4)/2)*TanLorAngP;
+      xp+=deltaxp;  
+    }
+
+    seg->GetPadTxz(xp,zp);
     
     // calculate drift time
     // y is the minimum path
@@ -342,8 +400,7 @@ void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0,
       if(GetDebug(4)) cout << "Dead SSD region, x,z="<<x<<","<<z<<endl;
       return; // There are dead region on the SSD sensitive volume!!!
     } // end if
-    
-      // sigma is the standard deviation of the diffusion gaussian
+    // sigma is the standard deviation of the diffusion gaussian
     if(tdrift[k]<0) return;
     
     sigma[k] = TMath::Sqrt(2*GetDiffConst(k)*tdrift[k]);
@@ -370,6 +427,18 @@ void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0,
     // Nside
     //-------------------------------------------------------
     k=1;
+
+    xp=x; zp=z; 
+
+    // correction for the Lorentz's angle
+    if(fLorentz) {
+      Float_t deltaxn = ((seg->Dy()*1.0E-4)/2-y)*TanLorAngN;
+      xp+=deltaxn;
+    }
+    
+
+    seg->GetPadTxz(xp,zp);
+
     tdrift[1] = ((seg->Dy()*1.0E-4)/2-y)/GetDriftVelocity(1);
     
     //tang[k]=TMath::Tan(tang[k]);
index 73a7177430545c1a1f6acb30147a1ddce413e527..9d014139e02d173bf294da5feac4f2172a0bb6ab 100644 (file)
@@ -72,6 +72,19 @@ class AliITSsimulationSSD: public AliITSsimulation {
     //Sets the Drift velocity for the P and N sides
     void SetDriftVelocity(Double_t v0=0.86E+06,Double_t v1=2.28E+06)
        {fDriftVel[0] = v0;fDriftVel[1] = v1;}
+
+
+    //  Decide whether to use or not the Lorentz drift 
+    void SetLorentzDrift(Bool_t b=kFALSE)
+      {fLorentz=b; if(fLorentz) SetTanLorAngle();};
+    // Set the Lorentz angles
+    Bool_t SetTanLorAngle();
+    // Getter for the Lorentz angles
+    Double_t GetTanLorAngleP() const {return fTanLorAngP;};
+    Double_t GetTanLorAngleN() const {return fTanLorAngN;};
+    //
+
+
     // Standard ascii class print function
     void Print(ostream *os);
     // Standard ascii class read function
@@ -128,6 +141,11 @@ class AliITSsimulationSSD: public AliITSsimulation {
 
     TF1         *fTimeResponse; // signal time response function
 
+   Bool_t        fLorentz;      // kTRUE if Lorentz drift has been allowed 
+   Double_t      fTanLorAngP;    //! Tangent of the Lorentz Angle for holes 
+   Double_t      fTanLorAngN;    //! Tangent of the Lorentz Angle for electrons
+
+
     ClassDef(AliITSsimulationSSD,3) // SSD signal simulation class
 
 };