3f76921121119050c0adfc31dabf7fdb3e8da042
[u/mrichter/AliRoot.git] / TRD / AliTRDv2.cxx
1 ///////////////////////////////////////////////////////////////////////////////
2 //                                                                           //
3 //  Transition Radiation Detector version 2 -- detailed simulation           //
4 //                                                                           //
5 //Begin_Html
6 /*
7 <img src="picts/AliTRDv2Class.gif">
8 */
9 //End_Html
10 //                                                                           //
11 //                                                                           //
12 ///////////////////////////////////////////////////////////////////////////////
13
14 #include <TMath.h>
15 #include <TVector.h>
16
17 #include "AliTRDv2.h"
18 #include "AliRun.h"
19 #include "AliMC.h"
20 #include "AliConst.h"
21
22 ClassImp(AliTRDv2)
23
24 //_____________________________________________________________________________
25 AliTRDv2::AliTRDv2(const char *name, const char *title) 
26          :AliTRD(name, title) 
27 {
28   //
29   // Standard constructor for Transition Radiation Detector version 2
30   //
31
32   fIdSens      = 0;
33
34   fIdSpace1    = 0;
35   fIdSpace2    = 0;
36   fIdSpace3    = 0;
37
38   fIdChamber1  = 0;
39   fIdChamber2  = 0;
40   fIdChamber3  = 0;
41
42   fSensSelect  = 0;
43   fSensPlane   = 0;
44   fSensChamber = 0;
45   fSensSector  = 0;
46
47   fDeltaE      = NULL;
48
49   SetBufferSize(128000);
50
51 }
52
53 AliTRDv2::~AliTRDv2()
54 {
55
56   if (fDeltaE)  delete fDeltaE;
57
58 }
59  
60 //_____________________________________________________________________________
61 void AliTRDv2::CreateGeometry()
62 {
63   //
64   // Create the GEANT geometry for the Transition Radiation Detector - Version 2
65   // This version covers the full azimuth. 
66   //
67   // Author:  Christoph Blume (C.Blume@gsi.de) 20/07/99 
68   //
69
70   Float_t xpos, ypos, zpos;
71
72   // Check that FRAME is there otherwise we have no place where to put the TRD
73   AliModule* FRAME = gAlice->GetModule("FRAME");
74   if (!FRAME) return;
75
76   // Define the chambers
77   AliTRD::CreateGeometry();
78
79   // Position the the TRD-sectors in all TRD-volumes in the spaceframe
80   xpos     = 0.;
81   ypos     = 0.;
82   zpos     = 0.;
83   gMC->Gspos("TRD ",1,"BTR1",xpos,ypos,zpos,0,"ONLY");
84   gMC->Gspos("TRD ",2,"BTR2",xpos,ypos,zpos,0,"ONLY");
85   gMC->Gspos("TRD ",3,"BTR3",xpos,ypos,zpos,0,"ONLY");
86
87 }
88
89 //_____________________________________________________________________________
90 void AliTRDv2::CreateMaterials()
91 {
92   //
93   // Create materials for the Transition Radiation Detector version 2
94   //
95
96   AliTRD::CreateMaterials();
97
98 }
99
100 //_____________________________________________________________________________
101 void AliTRDv2::Init() 
102 {
103   //
104   // Initialise Transition Radiation Detector after geometry has been built
105   //
106
107   // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
108   const Float_t kPoti = 12.1;
109   // Maximum energy (50 keV);
110   const Float_t kEend = 50000.0;
111
112   AliTRD::Init();
113
114   if (fSensPlane)
115     printf("          Only plane %d is sensitive\n",fSensPlane);
116   if (fSensChamber)   
117     printf("          Only chamber %d is sensitive\n",fSensChamber);
118   if (fSensSector)
119     printf("          Only sector %d is sensitive\n",fSensSector);
120
121   for(Int_t i = 0; i < 80; i++) printf("*");
122   printf("\n");
123
124   // Ermilova distribution for the delta-ray spectrum
125   Float_t Poti = TMath::Log(kPoti);
126   Float_t Eend = TMath::Log(kEend);
127   fDeltaE  = new TF1("deltae",Ermilova,Poti,Eend,0);
128
129   // Identifier of the sensitive volume (drift region)
130   fIdSens     = gMC->VolId("UL05");
131
132   // Identifier of the TRD-spaceframe volumina
133   fIdSpace1   = gMC->VolId("B028");
134   fIdSpace2   = gMC->VolId("B029");
135   fIdSpace3   = gMC->VolId("B030");
136
137   // Identifier of the TRD-driftchambers
138   fIdChamber1 = gMC->VolId("UCIO");
139   fIdChamber2 = gMC->VolId("UCIM");
140   fIdChamber3 = gMC->VolId("UCII");
141
142 }
143
144 //_____________________________________________________________________________
145 void AliTRDv2::SetSensPlane(Int_t iplane)
146 {
147   //
148   // Defines the hit-sensitive plane (1-6)
149   //
150
151   if ((iplane < 0) || (iplane > 6)) {
152     printf("Wrong input value: %d\n",iplane);
153     printf("Use standard setting\n");
154     fSensPlane  = 0;
155     fSensSelect = 0;
156     return;
157   }
158
159   fSensSelect = 1;
160   fSensPlane  = iplane;
161
162 }
163
164 //_____________________________________________________________________________
165 void AliTRDv2::SetSensChamber(Int_t ichamber)
166 {
167   //
168   // Defines the hit-sensitive chamber (1-5)
169   //
170
171   if ((ichamber < 0) || (ichamber > 5)) {
172     printf("Wrong input value: %d\n",ichamber);
173     printf("Use standard setting\n");
174     fSensChamber = 0;
175     fSensSelect  = 0;
176     return;
177   }
178
179   fSensSelect  = 1;
180   fSensChamber = ichamber;
181
182 }
183
184 //_____________________________________________________________________________
185 void AliTRDv2::SetSensSector(Int_t isector)
186 {
187   //
188   // Defines the hit-sensitive sector (1-18)
189   //
190
191   if ((isector < 0) || (isector > 18)) {
192     printf("Wrong input value: %d\n",isector);
193     printf("Use standard setting\n");
194     fSensSector = 0;
195     fSensSelect = 0;
196     return;
197   }
198
199   fSensSelect = 1;
200   fSensSector = isector;
201
202 }
203
204 //_____________________________________________________________________________
205 void AliTRDv2::StepManager()
206 {
207   //
208   // Called at every step in the Transition Radiation Detector version 2.
209   // Slow simulator. Every charged track produces electron cluster as hits 
210   // along its path across the drift volume. The step size is set acording
211   // to Bethe-Bloch. The energy distribution of the delta electrons follows
212   // a spectrum taken from Ermilova et al.
213   //
214
215   Int_t    iIdSens, icSens;
216   Int_t    iIdSpace, icSpace;
217   Int_t    iIdChamber, icChamber;
218   Int_t    vol[3]; 
219   Int_t    iPid;
220
221   Int_t    secMap1[10] = {  3,  7,  8,  9, 10, 11,  2,  1, 18, 17 };
222   Int_t    secMap2[ 5] = { 16, 15, 14, 13, 12 };
223   Int_t    secMap3[ 3] = {  5,  6,  4 };
224
225   Float_t  hits[4];
226   Float_t  random[1];
227   Float_t  charge;
228   Float_t  aMass;
229
230   Double_t pTot;
231   Double_t qTot;
232   Double_t eDelta;
233   Double_t betaGamma, pp;
234
235   TLorentzVector pos, mom;
236   TClonesArray  &lhits = *fHits;
237
238   const Double_t kBig = 1.0E+12;
239
240   // Ionization energy
241   const Float_t kWion    = 22.04;
242   // Maximum energy for e+ e- g for the step-size calculation
243   const Float_t kPTotMax = 0.002;
244   // Plateau value of the energy-loss for electron in xenon
245   // taken from: Allison + Comb, Ann. Rev. Nucl. Sci. (1980), 30, 253
246   //const Double_t kPlateau = 1.70;
247   // the averaged value (26/3/99)
248   const Float_t kPlateau = 1.55;
249   // dN1/dx|min for the gas mixture (90% Xe + 10% CO2)
250   const Float_t kPrim    = 48.0;
251   // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
252   const Float_t kPoti    = 12.1;
253
254   // Set the maximum step size to a very large number for all 
255   // neutral particles and those outside the driftvolume
256   gMC->SetMaxStep(kBig); 
257
258   // Use only charged tracks 
259   if (( gMC->TrackCharge()       ) &&
260       (!gMC->IsTrackStop()       ) && 
261       (!gMC->IsTrackDisappeared())) {
262
263     // Inside a sensitive volume?
264     iIdSens = gMC->CurrentVolID(icSens);
265     if (iIdSens == fIdSens) { 
266
267       iIdSpace   = gMC->CurrentVolOffID(4,icSpace  );
268       iIdChamber = gMC->CurrentVolOffID(1,icChamber);
269
270       // Calculate the energy of the delta-electrons
271       eDelta = TMath::Exp(fDeltaE->GetRandom()) - kPoti;
272       eDelta = TMath::Max(eDelta,0.0);
273
274       // The number of secondary electrons created
275       qTot = (Double_t) ((Int_t) (eDelta / kWion) + 1);
276
277       // The hit coordinates and charge
278       gMC->TrackPosition(pos);
279       hits[0] = pos[0];
280       hits[1] = pos[1];
281       hits[2] = pos[2];
282       hits[3] = qTot;
283
284       // The sector number
285       if      (iIdSpace == fIdSpace1) 
286         vol[0] = secMap1[icSpace-1];
287       else if (iIdSpace == fIdSpace2) 
288         vol[0] = secMap2[icSpace-1];
289       else if (iIdSpace == fIdSpace3) 
290         vol[0] = secMap3[icSpace-1];
291
292       // The chamber number 
293       //   1: outer left
294       //   2: middle left
295       //   3: inner
296       //   4: middle right
297       //   5: outer right
298       if      (iIdChamber == fIdChamber1)
299         vol[1] = (hits[2] < 0 ? 1 : 5);
300       else if (iIdChamber == fIdChamber2)       
301         vol[1] = (hits[2] < 0 ? 2 : 4);
302       else if (iIdChamber == fIdChamber3)       
303         vol[1] = 3;
304
305       // The plane number
306       vol[2] = icChamber - TMath::Nint((Float_t) (icChamber / 7)) * 6;
307
308       // Check on selected volumes
309       Int_t addthishit = 1;
310       if (fSensSelect) {
311         if ((fSensPlane)   && (vol[2] != fSensPlane  )) addthishit = 0;
312         if ((fSensChamber) && (vol[1] != fSensChamber)) addthishit = 0;
313         if ((fSensSector)  && (vol[0] != fSensSector )) addthishit = 0;
314       }
315
316       // Add this hit
317       if (addthishit) {
318
319         new(lhits[fNhits++]) AliTRDhit(fIshunt,gAlice->CurrentTrack(),vol,hits);
320
321         // The energy loss according to Bethe Bloch
322         gMC->TrackMomentum(mom);
323         pTot = mom.Rho();
324         iPid = gMC->TrackPid();
325         if ( (iPid >  3) ||
326             ((iPid <= 3) && (pTot < kPTotMax))) {
327           aMass     = gMC->TrackMass();
328           betaGamma = pTot / aMass;
329           pp        = kPrim * BetheBloch(betaGamma);
330           // Take charge > 1 into account
331           charge = gMC->TrackCharge();
332           if (TMath::Abs(charge) > 1) pp = pp * charge*charge;
333         }
334         // Electrons above 20 Mev/c are at the plateau
335         else {
336           pp = kPrim * kPlateau;
337         }
338       
339         // Calculate the maximum step size for the next tracking step
340         if (pp > 0) {
341           do 
342             gMC->Rndm(random,1);
343           while ((random[0] == 1.) || (random[0] == 0.));
344           gMC->SetMaxStep( - TMath::Log(random[0]) / pp);
345         }
346
347       }
348       else {
349         // set step size to maximal value
350         gMC->SetMaxStep(kBig); 
351       }
352
353     }
354
355   }
356
357 }
358
359 //_____________________________________________________________________________
360 Double_t AliTRDv2::BetheBloch(Double_t bg) 
361 {
362   //
363   // Parametrization of the Bethe-Bloch-curve
364   // The parametrization is the same as for the TPC and is taken from Lehrhaus.
365   //
366
367   // The parameters have been adjusted to Xe-data found in:
368   // Allison & Cobb, Ann. Rev. Nucl. Sci. (1980), 30, 253
369   //const Double_t kP1 = 0.76176E-1;
370   //const Double_t kP2 = 10.632;
371   //const Double_t kP3 = 3.17983E-6;
372   //const Double_t kP4 = 1.8631;
373   //const Double_t kP5 = 1.9479;
374
375   // This parameters have been adjusted to averaged values from GEANT
376   const Double_t kP1 = 7.17960e-02;
377   const Double_t kP2 = 8.54196;
378   const Double_t kP3 = 1.38065e-06;
379   const Double_t kP4 = 5.30972;
380   const Double_t kP5 = 2.83798;
381
382   if (bg > 0) {
383     Double_t yy = bg / TMath::Sqrt(1. + bg*bg);
384     Double_t aa = TMath::Power(yy,kP4);
385     Double_t bb = TMath::Power((1./bg),kP5);
386              bb = TMath::Log(kP3 + bb);
387     return ((kP2 - aa - bb)*kP1 / aa);
388   }
389   else
390     return 0;
391
392 }
393
394 //_____________________________________________________________________________
395 Double_t Ermilova(Double_t *x, Double_t *)
396 {
397   //
398   // Calculates the delta-ray energy distribution according to Ermilova
399   // Logarithmic scale !
400   //
401
402   Double_t energy;
403   Double_t dpos;
404   Double_t dnde;
405
406   Int_t    pos1, pos2;
407
408   const Int_t nV = 31;
409
410   Float_t vxe[nV] = { 2.3026, 2.9957, 3.4012, 3.6889, 3.9120  
411                     , 4.0943, 4.2485, 4.3820, 4.4998, 4.6052
412                     , 4.7005, 5.0752, 5.2983, 5.7038, 5.9915
413                     , 6.2146, 6.5221, 6.9078, 7.3132, 7.6009
414                     , 8.0064, 8.5172, 8.6995, 8.9872, 9.2103
415                     , 9.4727, 9.9035,10.3735,10.5966,10.8198
416                     ,11.5129 };
417
418   Float_t vye[nV] = { 80.0  , 31.0  , 23.3  , 21.1  , 21.0
419                     , 20.9  , 20.8  , 20.0  , 16.0  , 11.0
420                     ,  8.0  ,  6.0  ,  5.2  ,  4.6  ,  4.0
421                     ,  3.5  ,  3.0  ,  1.4  ,  0.67 ,  0.44
422                     ,  0.3  ,  0.18 ,  0.12 ,  0.08 ,  0.056
423                     ,  0.04 ,  0.023,  0.015,  0.011,  0.01
424                     ,  0.004 };
425
426   energy = x[0];
427
428   // Find the position 
429   pos1 = pos2 = 0;
430   dpos = 0;
431   do {
432     dpos = energy - vxe[pos2++];
433   } 
434   while (dpos > 0);
435   pos2--; 
436   if (pos2 > nV) pos2 = nV;
437   pos1 = pos2 - 1;
438
439   // Differentiate between the sampling points
440   dnde = (vye[pos1] - vye[pos2]) / (vxe[pos2] - vxe[pos1]);
441
442   return dnde;
443
444 }