LCOV - code coverage report
Current view: top level - ITSMFT/MFT/MFTsim - AliMFT.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 353 0.3 %
Date: 2016-06-14 17:26:59 Functions: 1 23 4.3 %

          Line data    Source code
       1             : // **************************************************************************
       2             : // * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             : // *                                                                        *
       4             : // * Author: The ALICE Off-line Project.                                    *
       5             : // * Contributors are mentioned in the code where appropriate.              *
       6             : // *                                                                        *
       7             : // * Permission to use, copy, modify and distribute this software and its   *
       8             : // * documentation strictly for non-commercial purposes is hereby granted   *
       9             : // * without fee, provided that the above copyright notice appears in all   *
      10             : // * copies and that both the copyright notice and this permission notice   *
      11             : // * appear in the supporting documentation. The authors make no claims     *
      12             : // * about the suitability of this software for any purpose. It is          *
      13             : // * provided "as is" without express or implied warranty.                  *
      14             : // **************************************************************************
      15             : 
      16             : //====================================================================================================================================================
      17             : //
      18             : //      Main class of the ALICE Muon Forward Tracker
      19             : //
      20             : //      Contact author: antonio.uras@cern.ch
      21             : //
      22             : //====================================================================================================================================================
      23             : 
      24             : #include "AliLog.h"
      25             : #include "AliCodeTimer.h"
      26             : #include "TFile.h"
      27             : #include "TGeoManager.h"
      28             : #include "TGeoVolume.h"
      29             : #include "TGeoMatrix.h"
      30             : #include "TVirtualMC.h"
      31             : #include "TClonesArray.h"
      32             : #include "TGeoGlobalMagField.h"
      33             : #include "AliRun.h"
      34             : #include "AliLoader.h"
      35             : #include "AliDetector.h"
      36             : #include "AliMC.h"
      37             : #include "AliMagF.h"
      38             : #include "AliMFT.h"
      39             : #include "AliMFTHit.h"
      40             : #include "AliMFTDigit.h"
      41             : #include "AliMFTCluster.h"
      42             : #include "AliTrackReference.h"
      43             : #include "AliMFTSegmentation.h"
      44             : #include "AliMFTDigitizer.h"
      45             : #include "AliMFTPlane.h"
      46             : #include "AliMFTConstants.h"
      47             : #include "TString.h"
      48             : #include "TObjArray.h"
      49             : #include "AliMFTGeometry.h"
      50             : 
      51          12 : ClassImp(AliMFT)
      52             : 
      53             : //====================================================================================================================================================
      54             : 
      55             : AliMFT::AliMFT():
      56           0 : AliDetector(),
      57           0 : fVersion(1),
      58           0 : fNPlanes(0),
      59           0 : fSDigitsPerPlane(0),
      60           0 : fDigitsPerPlane(0),
      61           0 : fRecPointsPerPlane(0),
      62           0 : fSideDigits(0),
      63           0 : fSegmentation(0),
      64           0 : fNameGeomFile(0),
      65           0 : fChargeDispersion(25.e-4),
      66           0 : fSingleStepForChargeDispersion(0),
      67           0 : fNStepForChargeDispersion(4),
      68           0 : fDensitySupportOverSi(0.036),
      69           0 : fFileNameForUnderyingEvent(0),
      70           0 : fFileNameForPileUpEvents(0),
      71           0 : fNPileUpEvents(0),
      72           0 : fUnderlyingEventID(-1)
      73           0 : {
      74             :   
      75             :   // default constructor
      76             :   
      77           0 :   for (Int_t iPileUp=0; iPileUp<AliMFTConstants::fNMaxPileUpEvents; iPileUp++) fPileUpEventsIDs[iPileUp] = -1;
      78             :   
      79             :   
      80           0 : }
      81             : 
      82             : //====================================================================================================================================================
      83             : 
      84             : AliMFT::AliMFT(const Char_t *name, const Char_t *title):
      85           0 : AliDetector(name, title),
      86           0 : fVersion(1),
      87           0 : fNPlanes(0),
      88           0 : fSDigitsPerPlane(0),
      89           0 : fDigitsPerPlane(0),
      90           0 : fRecPointsPerPlane(0),
      91           0 : fSideDigits(0),
      92           0 : fSegmentation(0),
      93           0 : fNameGeomFile(0),
      94           0 : fChargeDispersion(25.e-4),
      95           0 : fSingleStepForChargeDispersion(0),
      96           0 : fNStepForChargeDispersion(4),
      97           0 : fDensitySupportOverSi(0.036),
      98           0 : fFileNameForUnderyingEvent(0),
      99           0 : fFileNameForPileUpEvents(0),
     100           0 : fNPileUpEvents(0),
     101           0 : fUnderlyingEventID(-1)
     102           0 : {
     103             :   
     104           0 :   for (Int_t iPileUp=0; iPileUp<AliMFTConstants::fNMaxPileUpEvents; iPileUp++) fPileUpEventsIDs[iPileUp] = -1;
     105             :   
     106           0 :   fNameGeomFile = "AliMFTGeometry.root";
     107             :   
     108           0 :   SetGeometry();
     109             :   
     110           0 :   Init();
     111             :   
     112           0 : }
     113             : 
     114             : //====================================================================================================================================================
     115             : 
     116             : AliMFT::AliMFT(const Char_t *name, const Char_t *title, Char_t *nameGeomFile):
     117           0 : AliDetector(name, title),
     118           0 : fVersion(1),
     119           0 : fNPlanes(0),
     120           0 : fSDigitsPerPlane(0),
     121           0 : fDigitsPerPlane(0),
     122           0 : fRecPointsPerPlane(0),
     123           0 : fSideDigits(0),
     124           0 : fSegmentation(0),
     125           0 : fNameGeomFile(0),
     126           0 : fChargeDispersion(25.e-4),
     127           0 : fSingleStepForChargeDispersion(0),
     128           0 : fNStepForChargeDispersion(4),
     129           0 : fDensitySupportOverSi(0.036),
     130           0 : fFileNameForUnderyingEvent(0),
     131           0 : fFileNameForPileUpEvents(0),
     132           0 : fNPileUpEvents(0),
     133           0 : fUnderlyingEventID(-1)
     134           0 : {
     135             :   
     136           0 :   for (Int_t iPileUp=0; iPileUp<AliMFTConstants::fNMaxPileUpEvents; iPileUp++) fPileUpEventsIDs[iPileUp] = -1;
     137             :   
     138           0 :   fNameGeomFile = nameGeomFile;
     139             :   
     140           0 :   SetGeometry();
     141             :   
     142           0 :   Init();
     143             :   
     144           0 : }
     145             : 
     146             : //====================================================================================================================================================
     147             : 
     148           0 : AliMFT::~AliMFT() {
     149             :   
     150           0 :   if (fSDigitsPerPlane)   { fSDigitsPerPlane->Delete();    delete fSDigitsPerPlane;   }
     151           0 :   if (fDigitsPerPlane)    { fDigitsPerPlane->Delete();     delete fDigitsPerPlane;    }
     152           0 :   if (fRecPointsPerPlane) { fRecPointsPerPlane->Delete();  delete fRecPointsPerPlane; }
     153             :   
     154           0 : }
     155             : 
     156             : //====================================================================================================================================================
     157             : 
     158             : void AliMFT::CreateMaterials() {
     159             :   
     160             :   /// \todo Check all materials Remove the one unneeded
     161             :   
     162             :   
     163             :   // Definition of MFT materials  - to be updated to the most recent values
     164             :   
     165           0 :   AliDebug(1,"Start MFT materials");
     166             :   
     167             :     
     168             :   // data from PDG booklet 2002                 density [gr/cm^3]     rad len [cm]           abs len [cm]
     169           0 :   Float_t   aSi = 28.085 ,    zSi   = 14. ,     dSi      =  2.329 ,   radSi   =  21.82/dSi , absSi   = 108.4/dSi  ;    // Silicon
     170             :   Float_t   aCarb = 12.01 ,   zCarb =  6. ,     dCarb    =  2.265 ,   radCarb =  18.8 ,      absCarb = 49.9       ;    // Carbon
     171             :   Float_t   aAlu = 26.98 ,    zAlu  = 13. ,     dAlu     =  2.70  ,   radAlu  =  8.897 ,     absAlu  = 39.70      ;    // Aluminum
     172           0 :   Float_t   aBe = 9.012182 ,  zBe   = 4. ,      dBe      =  1.85 ,    radBe   =  65.19/dBe , absBe   = 77.8/dBe  ;     // Beryllium
     173             :   Float_t   aCu = 63.546 ,    zCu  = 29.  ,     dCu      =  8.96  ,   radCu   =  1.436 ,     absCu   = 15.32      ;    // Copper
     174             : 
     175             :   // Air mixture
     176             :   const Int_t nAir = 4;
     177           0 :   Float_t   aAir[nAir] = {12, 14, 16, 36} ,  zAir[nAir] = {6, 7, 8, 18} ,   wAir[nAir]={0.000124, 0.755267, 0.231781, 0.012827} , dAir=0.00120479, dAirVacuum=0.00120479e-4;
     178             : 
     179             :   // Water mixture
     180             :   const Int_t nWater = 2;
     181           0 :   Float_t   aWater[nWater] = {1.00794, 15.9994} ,  zWater[nWater] = {1, 8} ,   wWater[nWater] = {0.111894, 0.888106} , dWater=1.;
     182             :   
     183             :   // SiO2 mixture
     184             :   const Int_t nSiO2 = 2;
     185           0 :   Float_t   aSiO2[nSiO2] = {15.9994, 28.0855} ,   zSiO2[nSiO2] = {8., 14.} ,   wSiO2[nSiO2] = {0.532565, 0.467435} , dSiO2 = 2.20;
     186             :   
     187             :   // Inox mixture
     188             :   const Int_t nInox = 9;
     189           0 :   Float_t   aInox[nInox] = {12.0107, 54.9380, 28.0855, 30.9738, 32.0660, 58.6928, 51.9961, 95.9400, 55.8450} ;
     190           0 :   Float_t   zInox[nInox] = { 6,      25,      14,      15,      16,      28,      24,      42,      26     } ;
     191           0 :   Float_t   wInox[nInox] = {0.0003,  0.02,    0.01,    0.00045, 0.0003,  0.12,    0.17,    0.025,   0.65395} ;
     192             :   Float_t   dInox = 8.03;
     193             :   
     194             :   // Kapton polyimide film (from SPD AliITSv11.cxx)  and http://physics.nist.gov/cgi-bin/Star/compos.pl?matno=179
     195           0 :   Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
     196           0 :   Float_t zKapton[4]={1.,6.,7.,8.};
     197           0 :   Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
     198             :   Float_t dKapton   = 1.42;
     199             :   
     200             :   //--- EPOXY  --- C18 H19 O3 from ITS AliITSv11.cxx
     201           0 :   Float_t aEpoxy[3] = {15.9994, 1.00794, 12.0107} ;
     202           0 :   Float_t zEpoxy[3] = {     8.,      1.,      6.} ;
     203           0 :   Float_t wEpoxy[3] = {     3.,     19.,     18.} ;
     204             :   Float_t dEpoxy = 1.8 ;
     205             :   
     206             :   //--- CARBON FIBER CM55J --- from ITS AliITSv11.cxx
     207           0 :   Float_t aCM55J[4]={12.0107,14.0067,15.9994,1.00794};
     208           0 :   Float_t zCM55J[4]={6.,7.,8.,1.};
     209           0 :   Float_t wCM55J[4]={0.908508078,0.010387573,0.055957585,0.025146765};
     210             :   Float_t dCM55J = 1.8;  // 1.63 from AliITSv11Geometry.cxx !?
     211             : 
     212             :   // Rohacell mixture
     213             :   const Int_t nRohacell = 3;
     214           0 :   Float_t aRohacell[nRohacell] = {1.00794, 12.0107, 15.9994};
     215           0 :   Float_t zRohacell[nRohacell] = {1., 6., 8.};
     216           0 :   Float_t wRohacell[nRohacell] = {0.0858, 0.5964, 0.3178};
     217             :   Float_t dRohacell = 0.075;
     218             :   
     219             :   // Polyimide pipe mixture
     220             :   const Int_t nPolyimide = 4;
     221           0 :   Float_t aPolyimide[nPolyimide] = {1.00794, 12.0107, 14.0067, 15.9994};
     222           0 :   Float_t zPolyimide[nPolyimide] = {1, 6, 7, 8};
     223           0 :   Float_t wPolyimide[nPolyimide] = {0.00942, 0.56089, 0.13082, 0.29887};
     224             :   Float_t dPolyimide = 1.4;   
     225             : 
     226             :         // PEEK mixture (Polyether Ether Ketone)
     227             :         const Int_t nPEEK = 3;
     228           0 :         Float_t   aPEEK[nPEEK] = {1.00794, 12.0107, 15.9994} ;
     229           0 :         Float_t   zPEEK[nPEEK] = {1,       6,        8} ;
     230           0 :         Float_t   wPEEK[nPEEK] = {0.06713, 0.40001,  0.53285} ;
     231             :         Float_t   dPEEK = 1.32;
     232             : 
     233             :   // (Printed Circuit Board), material type FR4
     234             :   const Int_t nFR4 = 5;
     235           0 :   Float_t   aFR4[nFR4] = {1.00794,    12.0107, 15.9994, 28.0855,   79.904} ;
     236           0 :   Float_t   zFR4[nFR4] = {1,          6,       8,       14,   35} ;
     237           0 :   Float_t   wFR4[nFR4] = {0.0684428,  0.278042,0.405633, 0.180774,    0.0671091} ;
     238             :   Float_t   dFR4 = 1.7; //Density FR4= 1.7 Cu=8.96
     239             : 
     240             :   
     241             :   Int_t   matId  = 0;                        // tmp material id number
     242             :   Int_t   unsens = 0, sens=1;                // sensitive or unsensitive medium
     243             :   Int_t   itgfld = 3;                        // type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z
     244             :   Float_t maxfld = 5.;                       // max field value
     245             :   
     246             :   Float_t tmaxfd = -10.0;                    // max deflection angle due to magnetic field in one step
     247             :   Float_t stemax =  0.001;                   // max step allowed [cm]
     248             :   Float_t deemax = -0.2;                     // maximum fractional energy loss in one step 0<deemax<=1
     249             :   Float_t epsil  =  0.001;                   // tracking precision [cm]
     250             :   Float_t stmin  = -0.001;                   // minimum step due to continuous processes [cm] (negative value: choose it automatically)
     251             :   
     252             :   Float_t tmaxfdSi =  0.1;                   // max deflection angle due to magnetic field in one step
     253             :   Float_t stemaxSi =  5.0e-4;                // maximum step allowed [cm]
     254             :   Float_t deemaxSi =  0.1;                   // maximum fractional energy loss in one step 0<deemax<=1
     255             :   Float_t epsilSi  =  0.5e-4;                // tracking precision [cm]
     256             :   Float_t stminSi  = -0.001;                 // minimum step due to continuous processes [cm] (negative value: choose it automatically)
     257             :   
     258           0 :   Int_t    fieldType        = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();     // Field type
     259           0 :   Double_t maxField         = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();     // Field max.
     260             :   
     261           0 :   AliMixture(kAir,"Air$", aAir, zAir, dAir, nAir, wAir);
     262           0 :   AliMedium(kAir,    "Air$", kAir, unsens, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
     263             :   //
     264             :   //     Vacuum
     265           0 :   AliMixture(kVacuum, "Vacuum$", aAir, zAir, dAirVacuum, nAir, wAir);
     266           0 :   AliMedium(kVacuum,  "Vacuum$", kVacuum, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     267             : 
     268           0 :   AliMaterial(++matId, "Si$", aSi, zSi, dSi, radSi, absSi);
     269           0 :   AliMedium(kSi,       "Si$", matId, sens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
     270             :   
     271           0 :   AliMaterial(++matId, "Readout$", aSi, zSi, dSi, radSi, absSi);
     272           0 :   AliMedium(kReadout,  "Readout$", matId, unsens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
     273             :   
     274           0 :   AliMaterial(++matId, "Support$", aSi, zSi, dSi*fDensitySupportOverSi, radSi/fDensitySupportOverSi, absSi/fDensitySupportOverSi);
     275           0 :   AliMedium(kSupport,  "Support$", matId, unsens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
     276             :   
     277             :   Double_t maxBending       = 0;     // Max Angle
     278             :   Double_t maxStepSize      = 0.001; // Max step size
     279             :   Double_t maxEnergyLoss    = 1;     // Max Delta E
     280             :   Double_t precision        = 0.001; // Precision
     281             :   Double_t minStepSize      = 0.001; // Minimum step size
     282             :  // Carbon
     283             :   aCarb                = 12.011;
     284             :   zCarb                = 6.;
     285             :   dCarb          = 2.265;
     286             :   radCarb  = 18.8;
     287             :   absCarb = 999;
     288             :   maxBending       = 10;
     289             :   maxStepSize      = .01;
     290             :   precision        = .003;
     291             :   minStepSize      = .003;
     292           0 :   AliMaterial(matId, "Carbon$", aCarb, zCarb, dCarb, radCarb, absCarb);
     293           0 :   AliMedium(kCarbon, "Carbon$", matId,0,fieldType,maxField,maxBending,
     294             :             maxStepSize,maxEnergyLoss,precision,minStepSize);
     295             : 
     296             :   //  AliMaterial(++matId, "Carbon$", aCarb, zCarb, dCarb, radCarb, absCarb );
     297             : //  AliMedium(kCarbon,   "Carbon$", matId, unsens, fieldType,  maxField, tmaxfd, stemax, deemax, epsil, stmin);
     298             :   
     299           0 :   AliMaterial(++matId, "Be$", aBe, zBe, dBe, radBe, absBe );
     300           0 :   AliMedium(kBe,   "Be$", matId, unsens, fieldType,  maxField, tmaxfd, stemax, deemax, epsil, stmin);
     301             :   
     302           0 :   AliMaterial(++matId, "Alu$", aAlu, zAlu, dAlu, radAlu, absAlu);
     303           0 :   AliMedium(kAlu,      "Alu$", matId, unsens, fieldType,  maxField, tmaxfd, stemax, deemax, epsil, stmin);
     304             :   
     305             :   
     306           0 :   AliMixture(++matId, "Water$", aWater, zWater, dWater, nWater, wWater);
     307           0 :   AliMedium(kWater,   "Water$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     308             :   
     309           0 :   AliMixture(++matId, "SiO2$", aSiO2, zSiO2, dSiO2, nSiO2, wSiO2);
     310           0 :   AliMedium(kSiO2,    "SiO2$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     311             :   
     312           0 :   AliMixture(++matId, "Inox$", aInox, zInox, dInox, nInox, wInox);
     313           0 :   AliMedium(kInox,    "Inox$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     314             :   
     315           0 :   AliMixture(++matId, "Kapton$", aKapton, zKapton, dKapton, 4, wKapton);
     316           0 :   AliMedium(kKapton,"Kapton$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     317             :   
     318           0 :   AliMixture(++matId, "Epoxy$", aEpoxy, zEpoxy, dEpoxy, -3, wEpoxy);
     319           0 :   AliMedium(kEpoxy,"Epoxy$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     320             :   
     321           0 :   AliMixture(++matId,"C (M55J)$",aCM55J,zCM55J,dCM55J,4,wCM55J);
     322           0 :   AliMedium(kCarbonEpoxy,"CarbonFiber$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     323             :   
     324           0 :   AliMixture(++matId,  "Rohacell", aRohacell, zRohacell, dRohacell, nRohacell, wRohacell);
     325           0 :   AliMedium(kRohacell, "Rohacell", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     326             :   
     327           0 :   AliMixture(++matId,  "Polyimide", aPolyimide, zPolyimide, dPolyimide, nPolyimide, wPolyimide);
     328           0 :   AliMedium(kPolyimide, "Polyimide", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     329             :         
     330           0 :         AliMixture(++matId, "PEEK$", aPEEK, zPEEK, dPEEK, nPEEK, wPEEK);
     331           0 :         AliMedium(kPEEK,    "PEEK$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     332             :   
     333           0 :   AliMixture(++matId, "FR4$", aFR4, zFR4, dFR4, nFR4, wFR4);
     334           0 :   AliMedium(kFR4,    "FR4$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     335             :   
     336           0 :   AliMaterial(++matId, "Cu$", aCu, zCu, dCu, radCu, absCu);
     337           0 :   AliMedium(kCu,       "Cu$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
     338             : 
     339           0 :   AliDebug(1,"End MFT materials");
     340             :   
     341           0 : }
     342             : 
     343             : //====================================================================================================================================================
     344             : 
     345             : void AliMFT::CreateGeometry() {
     346             :   
     347             :   // Creates detailed geometry simulation (currently GEANT volumes tree)
     348             :   
     349           0 :   if(!TVirtualMC::GetMC()->IsRootGeometrySupported()) return;
     350             :   
     351           0 :   AliMFTGeometry* mftGeom =   AliMFTGeometry::Instance();
     352             :   
     353           0 :   mftGeom->Build();
     354             :   
     355           0 :   if (fNStepForChargeDispersion) fSingleStepForChargeDispersion = fChargeDispersion/Double_t(fNStepForChargeDispersion);
     356             :   
     357           0 : }
     358             : 
     359             : //====================================================================================================================================================
     360             : 
     361             : void AliMFT::AddAlignableVolumes() {
     362             :   
     363             :   // Create entries for alignable volumes associating the symbolic volume
     364             :   // name with the corresponding volume path. Needs to be syncronized with
     365             :   // eventual changes in the geometry.
     366             :   
     367           0 :   TString sysName = "MFT";
     368           0 :   TString volPath = "/ALIC_1/MFT_0";
     369             :   
     370           0 :   if (!gGeoManager->SetAlignableEntry(sysName.Data(),volPath.Data())) {
     371           0 :     AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", sysName.Data(), volPath.Data()));
     372             :   }
     373             :   
     374           0 : }
     375             : 
     376             : //====================================================================================================================================================
     377             : 
     378             : void AliMFT::StepManager() {
     379             :   
     380             :   // If MFT is not active do nothing
     381           0 :   if (!(this->IsActive())) return;
     382             :   
     383           0 :   AliMFTGeometry *mftGeo = AliMFTGeometry::Instance();
     384           0 :   AliMFTSegmentation * seg = mftGeo->GetSegmentation();
     385           0 :   if (!seg) AliFatal("No segmentation available");
     386             : 
     387           0 :   TVirtualMC* mc = TVirtualMC::GetMC();
     388             :   
     389           0 :   Double_t absQ = TMath::Abs(mc->TrackCharge());
     390           0 :   if (absQ <= 0) return;
     391             : 
     392           0 :   Int_t copy;
     393             :   // Check if hit is into a MFT sensor volume
     394           0 :   if(mc->CurrentVolID(copy) != mftGeo->GetSensorVolumeID() ) return;
     395             :   // Get The Sensor Unique ID
     396           0 :   int chipId=-1,ladderId=-1,diskId=-1,halfId=-1,level=0;
     397           0 :   mc->CurrentVolOffID(++level,chipId);
     398           0 :   mc->CurrentVolOffID(++level,ladderId);
     399           0 :   mc->CurrentVolOffID(++level,diskId);
     400           0 :   mc->CurrentVolOffID(++level,halfId);
     401           0 :   Int_t detElemID = mftGeo->GetObjectID(AliMFTGeometry::kSensorType,halfId,diskId,ladderId,chipId);
     402           0 :   AliDebug(1,Form("Found hit into half = %d; disk = %d; ladder = %d; chip = %d",halfId,diskId,ladderId,chipId));
     403             : 
     404           0 :   if (mc->IsTrackExiting()) {
     405           0 :     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kMFT);
     406           0 :   }
     407             :   
     408           0 :   static TLorentzVector position, momentum;
     409           0 :   static AliMFTHit hit;
     410             :   
     411             :   Int_t  status = 0;
     412             :   
     413             :   // Track status
     414           0 :   if (mc->IsTrackInside())      status += 0x1<<0;
     415           0 :   if (mc->IsTrackEntering())    status += 0x1<<1;
     416           0 :   if (mc->IsTrackExiting())     status += 0x1<<2;
     417           0 :   if (mc->IsTrackOut())         status += 0x1<<3;
     418           0 :   if (mc->IsTrackDisappeared()) status += 0x1<<4;
     419           0 :   if (mc->IsTrackStop())        status += 0x1<<5;
     420           0 :   if (mc->IsTrackAlive())       status += 0x1<<6;
     421             :   
     422             :   // ---------- Fill hit structure
     423             :   
     424           0 :   hit.SetDetElemID(detElemID);
     425           0 :   hit.SetPlane(diskId);
     426           0 :   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
     427             :   
     428           0 :   mc->TrackPosition(position);
     429           0 :   mc->TrackMomentum(momentum);
     430             :   
     431           0 :   AliDebug(1, Form(" %s Hit #%06d (x=%f, y=%f, z=%f) belongs to track %02d",
     432             :                    mc->CurrentVolName(), fNhits, position.X(), position.Y(), position.Z(), gAlice->GetMCApp()->GetCurrentTrackNumber()));
     433             :   
     434           0 :   hit.SetPosition(position);
     435           0 :   hit.SetTOF(mc->TrackTime());
     436           0 :   hit.SetMomentum(momentum);
     437           0 :   hit.SetStatus(status);
     438           0 :   hit.SetEloss(mc->Edep());
     439             :   //  hit.SetShunt(GetIshunt());
     440             :   //   if (mc->IsTrackEntering()) {
     441             :   //     hit.SetStartPosition(position);
     442             :   //     hit.SetStartTime(mc->TrackTime());
     443             :   //     hit.SetStartStatus(status);
     444             :   //     return; // don't save entering hit.
     445             :   //   }
     446             :   
     447             :   // Fill hit structure with this new hit.
     448           0 :   new ((*fHits)[fNhits++]) AliMFTHit(hit);
     449             :   
     450             :   // Save old position... for next hit.
     451             :   //   hit.SetStartPosition(position);
     452             :   //   hit.SetStartTime(mc->TrackTime());
     453             :   //   hit.SetStartStatus(status);
     454             :   
     455             :   return;
     456             :   
     457           0 : }
     458             : 
     459             : 
     460             : //====================================================================================================================================================
     461             : 
     462             : void AliMFT::Hits2SDigits(){
     463             :   
     464             :   // Interface method invoked from AliSimulation to create a list of sdigits corresponding to list of hits. Every hit generates one sdigit.
     465           0 :   AliCodeTimerAuto("",0);
     466             : 
     467           0 :   AliDebug(1, "Start Hits2SDigits.");
     468             :   
     469           0 :   AliMFTGeometry *mftGeo = AliMFTGeometry::Instance();
     470           0 :   AliMFTSegmentation * seg = mftGeo->GetSegmentation();
     471           0 :   if (!seg) AliFatal("No segmentation available");
     472             :   
     473           0 :   if (!fLoader->TreeH()) fLoader->LoadHits();
     474             :   
     475           0 :   if (!fLoader->TreeS()) {
     476             :     
     477           0 :     for (Int_t iEvt=0;iEvt<fLoader->GetRunLoader()->GetNumberOfEvents(); iEvt++) {
     478             :       
     479           0 :       fLoader->GetRunLoader()->GetEvent(iEvt);
     480           0 :       fLoader->MakeTree("S");
     481           0 :       MakeBranch("S");
     482           0 :       SetTreeAddress();
     483             :       
     484           0 :       AliDebug(1, Form("Event %03d: fLoader->TreeH()->GetEntries() = %2d", iEvt, Int_t(fLoader->TreeH()->GetEntries())));
     485             : 
     486           0 :       for (Int_t iTrack=0; iTrack<fLoader->TreeH()->GetEntries(); iTrack++) {
     487           0 :         fLoader->TreeH()->GetEntry(iTrack);
     488           0 :         Hits2SDigitsLocal(Hits(), GetSDigitsList(), iTrack);    // convert these hits to a list of sdigits
     489             :       }
     490             :       
     491           0 :       fLoader->TreeS()->Fill();
     492           0 :       fLoader->WriteSDigits("OVERWRITE");
     493           0 :       ResetSDigits();
     494             :       
     495             :     }
     496           0 :   }
     497             :   
     498           0 :   fLoader->UnloadHits();
     499           0 :   fLoader->UnloadSDigits();
     500             :   
     501           0 :   AliDebug(1,"Stop Hits2SDigits.");
     502             :   
     503           0 : }
     504             : 
     505             : //====================================================================================================================================================
     506             : 
     507             : void AliMFT::Hits2SDigitsLocal(TClonesArray *hits, const TObjArray *pSDig, Int_t track) {
     508             :   
     509             :   //  Add sdigits of these hits to the list
     510             :   
     511           0 :   AliDebug(1, "Entering Hits2SDigitsLocal");
     512             :   
     513           0 :   TClonesArray *pSDigList[AliMFTConstants::kNDisks];
     514           0 :   for (Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) pSDigList[iPlane] = NULL;
     515           0 :   for (Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks;    iPlane++) {
     516           0 :     pSDigList[iPlane] = (TClonesArray*) (*pSDig)[iPlane];
     517           0 :     AliDebug(1,Form("Entries of pSDigList %3d; plane: %02d,",pSDigList[iPlane]->GetEntries(),iPlane));
     518           0 :     if (!track && pSDigList[iPlane]->GetEntries()!=0) AliErrorClass("Some of sdigits lists is not empty");
     519             :   }
     520             :   
     521           0 :   for (Int_t iHit=0; iHit<hits->GetEntries(); iHit++) {
     522             : 
     523           0 :     AliMFTHit *hit = (AliMFTHit*) hits->At(iHit);
     524             : 
     525             : //    AliDebug(1,Form("\n--- New hit x,y,z %f %f %f  ",hit->X(), hit->Y(), hit->Z()));
     526             : 
     527             :     // Creating "main digit"
     528             :     
     529           0 :     AliMFTDigit *mainSDigit = new AliMFTDigit();
     530           0 :     mainSDigit->SetEloss(hit->GetEloss());
     531           0 :     mainSDigit->SetDetElemID(hit->GetDetElemID());
     532           0 :     mainSDigit->SetPlane(hit->GetPlane());
     533           0 :     mainSDigit->AddMCLabel(hit->GetTrack());
     534           0 :     Int_t xPixel = -1;
     535           0 :     Int_t yPixel = -1;
     536           0 :     AliMFTGeometry * mftGeom = AliMFTGeometry::Instance();
     537             : 
     538           0 :     AliDebug(2,Form("Hit at x,y,z = %f %f %f ",hit->X(), hit->Y(), hit->Z()));
     539           0 :     if(mftGeom->Hit2PixelID(hit->X(), hit->Y(), hit->Z(), mainSDigit->GetDetElemID(), xPixel, yPixel)){
     540           0 :       mainSDigit->SetPixID(xPixel, yPixel, 0);
     541           0 :       mainSDigit->SetPixWidth(AliMFTConstants::kXPixelPitch, AliMFTConstants::kYPixelPitch,AliMFTConstants::kSensorThickness);
     542           0 :       Double_t xCenter,  yCenter, zCenter;
     543           0 :       mftGeom->GetPixelCenter( xPixel,  yPixel, mainSDigit->GetDetElemID(),  xCenter,  yCenter, zCenter );
     544           0 :       mainSDigit->SetPixCenter(xCenter,  yCenter, zCenter );
     545           0 :       new ((*fSideDigits)[fSideDigits->GetEntries()]) AliMFTDigit(*mainSDigit);
     546           0 :       AliDebug(2, Form("Created new sdigit (%f, %f, %f) from hit (%f, %f, %f)",
     547             :                        mainSDigit->GetPixelCenterX(), mainSDigit->GetPixelCenterY(), mainSDigit->GetPixelCenterZ(), hit->X(), hit->Y(), hit->Z()));
     548           0 :     } else
     549           0 :       AliDebug(1,Form("Hit outside active area : hit x,y,z = %f ; %f ; %f --> Pixel %d ; %d ",hit->X(), hit->Y(), hit->Z(),xPixel,yPixel));
     550             :     
     551             :     
     552             :     
     553             : 
     554             :     // creating "side digits" to simulate the effect of charge dispersion
     555             :     
     556           0 :     Double_t pi4 = TMath::Pi()/4.;
     557           0 :     for (Int_t iStep=0; iStep<fNStepForChargeDispersion; iStep++) {
     558           0 :       Double_t shift = (iStep+1) * fSingleStepForChargeDispersion;
     559           0 :       for (Int_t iAngle=0; iAngle<8; iAngle++) {
     560           0 :         Double_t shiftX = shift*TMath::Cos(iAngle*pi4);
     561           0 :         Double_t shiftY = shift*TMath::Sin(iAngle*pi4);
     562           0 :         if (mftGeom->Hit2PixelID(hit->X()+shiftX, hit->Y()+shiftY, hit->Z(), mainSDigit->GetDetElemID(), xPixel, yPixel) ){
     563             :           Bool_t digitExists = kFALSE;
     564           0 :           for (Int_t iSideDigit=0; iSideDigit<fSideDigits->GetEntries(); iSideDigit++) {
     565           0 :             if (xPixel==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelX() &&
     566           0 :                 yPixel==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelY() &&
     567           0 :                 mainSDigit->GetDetElemID() == ((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetDetElemID()) {
     568             :               digitExists = kTRUE;
     569           0 :               break;
     570             :             }
     571             :           }
     572           0 :           if (!digitExists) {
     573           0 :             AliMFTDigit *sideSDigit = new AliMFTDigit();
     574           0 :             sideSDigit->SetEloss(0.);
     575           0 :             sideSDigit->SetDetElemID(hit->GetDetElemID());
     576           0 :             sideSDigit->SetPlane(hit->GetPlane());
     577           0 :             sideSDigit->AddMCLabel(hit->GetTrack());
     578           0 :             sideSDigit->SetPixID(xPixel, yPixel, 0);
     579           0 :             mainSDigit->SetPixWidth(AliMFTConstants::kXPixelPitch, AliMFTConstants::kYPixelPitch,AliMFTConstants::kSensorThickness);
     580           0 :             Double_t xCenter,  yCenter, zCenter;
     581           0 :             mftGeom->GetPixelCenter( xPixel,  yPixel, mainSDigit->GetDetElemID(),  xCenter,  yCenter, zCenter );
     582           0 :             mainSDigit->SetPixCenter(xCenter,  yCenter, zCenter );
     583           0 :             new ((*fSideDigits)[fSideDigits->GetEntries()]) AliMFTDigit(*sideSDigit);
     584           0 :           }
     585           0 :         }
     586             :       }
     587             :     }
     588             : 
     589             : 
     590             :     // -------- checking which pixels switched on have their diode actually within the charge dispersion radius
     591             :     
     592           0 :     for (Int_t iSDigit=0; iSDigit<fSideDigits->GetEntries(); iSDigit++) {
     593           0 :       AliMFTDigit *mySDig = (AliMFTDigit*) (fSideDigits->At(iSDigit));
     594           0 :       Double_t distance = TMath::Sqrt(TMath::Power(mySDig->GetPixelCenterX()-hit->X(),2) + TMath::Power(mySDig->GetPixelCenterY()-hit->Y(),2));
     595           0 :         if (distance<fChargeDispersion) {
     596           0 :           AliDebug(1,Form("Created new side sdigit (%f, %f, %f) from hit (%f, %f, %f)",
     597             :                            mySDig->GetPixelCenterX(), mySDig->GetPixelCenterY(), mySDig->GetPixelCenterZ(), hit->X(), hit->Y(), hit->Z()));
     598           0 :           new ((*pSDigList[mySDig->GetPlane()])[pSDigList[mySDig->GetPlane()]->GetEntries()]) AliMFTDigit(*mySDig);
     599             :         }
     600             :     }
     601             :     
     602           0 :     fSideDigits->Delete();
     603             :     
     604           0 :   }
     605             :   
     606           0 :   AliDebug(1,"Exiting Hits2SDigitsLocal");
     607             :   
     608           0 : }
     609             : 
     610             : //====================================================================================================================================================
     611             : 
     612             : void AliMFT::MakeBranch(Option_t *option) {
     613             :   
     614             :   // Create Tree branches
     615           0 :   AliDebug(1, Form("Start with option= %s.",option));
     616             :   
     617             :   const Int_t kBufSize = 4000;
     618             :   
     619           0 :   const Char_t *cH = strstr(option,"H");
     620           0 :   const Char_t *cD = strstr(option,"D");
     621           0 :   const Char_t *cS = strstr(option,"S");
     622             :   
     623           0 :   if (cH && fLoader->TreeH()) {
     624           0 :     CreateHits();
     625           0 :     MakeBranchInTree(fLoader->TreeH(), "MFT", &fHits, kBufSize, 0);
     626           0 :   }
     627             :   
     628           0 :   if (cS && fLoader->TreeS()) {
     629           0 :     CreateSDigits();
     630           0 :     for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) MakeBranchInTree(fLoader->TreeS(),
     631           0 :                                                                     Form("Plane_%02d",iPlane),
     632           0 :                                                                     &((*fSDigitsPerPlane)[iPlane]),
     633             :                                                                     kBufSize, 0);
     634           0 :   }
     635             :   
     636           0 :   if (cD && fLoader->TreeD()) {
     637           0 :     CreateDigits();
     638           0 :     for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) MakeBranchInTree(fLoader->TreeD(),
     639           0 :                                                                     Form("Plane_%02d",iPlane),
     640           0 :                                                                     &((*fDigitsPerPlane)[iPlane]),
     641             :                                                                     kBufSize, 0);
     642           0 :   }
     643             :   
     644           0 :   AliDebug(1,"Stop.");
     645             :   
     646           0 : }
     647             : 
     648             : //====================================================================================================================================================
     649             : 
     650             : void AliMFT::SetTreeAddress() {
     651             :   
     652             :   
     653             :   //Set branch address for the Hits and Digits Tree.
     654           0 :   AliDebug(1, "Start.");
     655             :   
     656           0 :   AliDebug(1, Form("AliMFT::SetTreeAddress Hits  fLoader->TreeH() = %p\n", fLoader->TreeH()));
     657           0 :   if (fLoader->TreeH() && fLoader->TreeH()->GetBranch("MFT")) {
     658           0 :     CreateHits();
     659           0 :     fLoader->TreeH()->SetBranchAddress("MFT", &fHits);
     660           0 :   }
     661             :   
     662           0 :   AliDebug(1, Form("AliMFT::SetTreeAddress SDigits  fLoader->TreeS() = %p\n", fLoader->TreeS()));
     663           0 :   if (fLoader->TreeS() && fLoader->TreeS()->GetBranch("Plane_00")) {
     664           0 :     CreateSDigits();
     665           0 :     for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) {
     666           0 :       fLoader->TreeS()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fSDigitsPerPlane)[iPlane]));
     667             :     }
     668           0 :   }
     669             :   
     670           0 :   AliDebug(1, Form("AliMFT::SetTreeAddress Digits  fLoader->TreeD() = %p\n", fLoader->TreeD()));
     671           0 :   if (fLoader->TreeD() && fLoader->TreeD()->GetBranch("Plane_00")) {
     672           0 :     CreateDigits();
     673           0 :     for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) {
     674           0 :       fLoader->TreeD()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fDigitsPerPlane)[iPlane]));
     675             :     }
     676           0 :   }
     677             :   
     678           0 :   AliDebug(1, Form("AliMFT::SetTreeAddress RecPoints  fLoader->TreeR() = %p\n", fLoader->TreeR()));
     679           0 :   if (fLoader->TreeR() && fLoader->TreeR()->GetBranch("Plane_00")) {
     680           0 :     CreateRecPoints();
     681           0 :     for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) {
     682           0 :       fLoader->TreeR()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fRecPointsPerPlane)[iPlane]));
     683             :     }
     684           0 :   }
     685             :   
     686           0 :   AliDebug(1,"Stop.");
     687             :   
     688           0 : }
     689             : 
     690             : //====================================================================================================================================================
     691             : 
     692             : void AliMFT::SetGeometry() {
     693             :   
     694             :   //  AliInfo("AliMFT::SetGeometry\n");
     695             :   //
     696             :   //  fSegmentation = new AliMFTSegmentation(fNameGeomFile.Data());
     697             :   //
     698             :   //  fNPlanes = fSegmentation->GetNPlanes();
     699             :   
     700           0 :   fNPlanes = AliMFTConstants::kNDisks;
     701             : 
     702           0 : }
     703             : 
     704             : //====================================================================================================================================================
     705             : 
     706             : void AliMFT::CreateHits() { 
     707             :   
     708             :   // create array of hits
     709             :   
     710           0 :   AliDebug(1, "AliMFT::CreateHits()");
     711             :   
     712           0 :   if (fHits) return;    
     713           0 :   fHits = new TClonesArray("AliMFTHit");  
     714             :   
     715           0 : }
     716             : 
     717             : //====================================================================================================================================================
     718             : 
     719             : void AliMFT::CreateSDigits() { 
     720             :   
     721             :   // create sdigits list
     722             :   
     723           0 :   AliDebug(1, "AliMFT::CreateSDigits()");
     724             :   
     725           0 :   if (fSDigitsPerPlane) return; 
     726           0 :   fSDigitsPerPlane = new TObjArray(AliMFTConstants::kNDisks);
     727           0 :   for (Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) fSDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
     728             :   
     729           0 :   fSideDigits = new TClonesArray("AliMFTDigit");
     730             :   
     731           0 : }
     732             : 
     733             : //====================================================================================================================================================
     734             : 
     735             : void AliMFT::CreateDigits() {
     736             :   
     737             :   // create digits list
     738             :   
     739           0 :   AliDebug(1, "AliMFT::CreateDigits()");
     740             :   
     741           0 :   if (fDigitsPerPlane) return; 
     742           0 :   fDigitsPerPlane = new TObjArray(AliMFTConstants::kNDisks);
     743           0 :   for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) fDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
     744             :   
     745           0 : }
     746             : 
     747             : //====================================================================================================================================================
     748             : 
     749             : void AliMFT::CreateRecPoints() {
     750             :   
     751             :   // create recPoints list
     752             :   
     753           0 :   AliDebug(1, "AliMFT::CreateRecPoints()");
     754             :   
     755           0 :   if (fRecPointsPerPlane) return; 
     756           0 :   fRecPointsPerPlane = new TObjArray(AliMFTConstants::kNDisks);
     757           0 :   for(Int_t iPlane=0; iPlane<AliMFTConstants::kNDisks; iPlane++) fRecPointsPerPlane->AddAt(new TClonesArray("AliMFTCluster"), iPlane);
     758             :   
     759           0 : }
     760             : 
     761             : //====================================================================================================================================================

Generated by: LCOV version 1.11