]>
Commit | Line | Data |
---|---|---|
70da6c5a | 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 | // Class for electrons from beauty study | |
17 | // Counting electrons from beauty | |
18 | // by DCA cuts, background subtraction | |
19 | // | |
20 | // Authors: | |
21 | // Hongyan Yang <hongyan@physi.uni-heidelberg.de> | |
22 | // | |
23 | ||
24 | #include "TMath.h" | |
25 | #include "TList.h" | |
26 | #include "AliLog.h" | |
27 | ||
28 | #include <TParticle.h> | |
29 | #include <TDatabasePDG.h> | |
30 | ||
31 | #include "THnSparse.h" | |
32 | #include "AliMCEvent.h" | |
33 | #include "AliESDEvent.h" | |
34 | #include "AliMCParticle.h" | |
35 | #include "AliESDtrack.h" | |
36 | ||
37 | #include "AliStack.h" | |
38 | ||
39 | #include "AliHFEdisplacedElectrons.h" | |
40 | ||
41 | ClassImp(AliHFEdisplacedElectrons) | |
42 | ||
43 | //__________________________________________________________ | |
44 | const Float_t AliHFEdisplacedElectrons::fgkDcaMinPtIntv[13] = { | |
45 | // | |
46 | // define DCA low limits for single electrons cut in each Pt bin | |
47 | // preliminary numbers | |
48 | // these numbers should be replaced by the best numbers determined by | |
49 | // cut efficiency study: signal/background (not used right now) | |
50 | // | |
51 | 450, // 0.0 - 0.5 | |
52 | 450, // 0.5 - 1.0 | |
53 | 450, // 1.0 - 1.5 | |
54 | 500, // 1.5 - 2.0 | |
55 | 400, // 2.0 - 2.5 | |
56 | 300, // 2.5 - 3.0 | |
57 | 300, // 3.0 - 4.0 | |
58 | 300, // 4.0 - 5.0 | |
59 | 200, // 5.0 - 7.0 | |
60 | 150, // 7.0 - 9.0 | |
61 | 150, // 9.0 - 12.0 | |
62 | 100, //12.0 - 16.0 | |
63 | 50}; //16.0 - 20.0 | |
64 | //__________________________________________________________ | |
65 | const Float_t AliHFEdisplacedElectrons::fgkPtIntv[14] = { | |
66 | // | |
67 | // define pT bins for spectra of single electrons | |
68 | // | |
69 | 0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0}; | |
70 | ||
71 | //__________________________________________________________ | |
72 | const Char_t *AliHFEdisplacedElectrons::fgkKineVar[3] = { | |
73 | "y", "phi", "pt"}; | |
74 | ||
75 | //__________________________________________________________ | |
76 | const Char_t *AliHFEdisplacedElectrons::fgkKineVarTitle[3] ={ | |
77 | "rapidity;y;dN/dy", "azimuthal;#phi;dN/d#phi", "transverse momentum;p_{T};dN/dp_{T}", | |
78 | }; | |
79 | ||
80 | //__________________________________________________________ | |
81 | AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(): | |
82 | fDebugLevel(0) | |
70da6c5a | 83 | , fTHnSparseDcaMcPionInfo(NULL) |
84 | , fTHnSparseDcaMcEleInfo(NULL) | |
85 | , fTHnSparseDcaDataEleInfo(NULL) | |
86 | , fOutputList(0x0) | |
87 | { | |
88 | // | |
89 | // default constructor | |
90 | // | |
91 | ||
92 | } | |
93 | ||
94 | //__________________________________________________________ | |
91c7e1ec | 95 | AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(const AliHFEdisplacedElectrons &ref): |
96 | TObject(ref) | |
97 | , fDebugLevel(ref.fDebugLevel) | |
98 | , fTHnSparseDcaMcPionInfo(ref.fTHnSparseDcaMcPionInfo) | |
99 | , fTHnSparseDcaMcEleInfo(ref.fTHnSparseDcaMcEleInfo) | |
100 | , fTHnSparseDcaDataEleInfo(ref.fTHnSparseDcaDataEleInfo) | |
101 | , fOutputList(ref.fOutputList) | |
70da6c5a | 102 | |
103 | { | |
104 | // | |
105 | // copy constructor | |
106 | // | |
107 | } | |
108 | ||
109 | ||
110 | //__________________________________________________________ | |
91c7e1ec | 111 | AliHFEdisplacedElectrons&AliHFEdisplacedElectrons::operator=(const AliHFEdisplacedElectrons &ref) |
70da6c5a | 112 | { |
113 | // | |
114 | // Assignment operator | |
115 | // | |
91c7e1ec | 116 | |
117 | if(this == &ref) return *this; | |
118 | AliHFEdisplacedElectrons::operator=(ref); | |
119 | ||
120 | fDebugLevel = ref.fDebugLevel; | |
121 | ||
122 | fTHnSparseDcaMcPionInfo = ref.fTHnSparseDcaMcPionInfo; | |
123 | fTHnSparseDcaMcEleInfo = ref.fTHnSparseDcaMcEleInfo; | |
124 | fTHnSparseDcaDataEleInfo = ref.fTHnSparseDcaDataEleInfo; | |
125 | fOutputList = ref.fOutputList; | |
126 | ||
70da6c5a | 127 | return *this; |
128 | } | |
129 | ||
130 | //__________________________________________________________ | |
131 | AliHFEdisplacedElectrons::~AliHFEdisplacedElectrons() | |
132 | { | |
133 | // | |
134 | // default constructor | |
135 | // | |
136 | ||
137 | if(fTHnSparseDcaMcPionInfo) | |
138 | delete fTHnSparseDcaMcPionInfo; | |
139 | if(fTHnSparseDcaMcEleInfo) | |
140 | delete fTHnSparseDcaMcEleInfo; | |
141 | if(fTHnSparseDcaDataEleInfo) | |
142 | delete fTHnSparseDcaDataEleInfo; | |
143 | ||
144 | if(fOutputList){ | |
145 | fOutputList->Clear(); | |
146 | delete fOutputList; | |
147 | ||
148 | } | |
149 | ||
150 | Printf("analysis done\n"); | |
151 | } | |
152 | ||
153 | //__________________________________________________________ | |
154 | void AliHFEdisplacedElectrons::InitAnalysis(){ | |
155 | // | |
156 | // init analysis (no intialization yet) | |
157 | // | |
158 | ||
159 | ||
160 | Printf("initialize analysis\n"); | |
161 | ||
162 | } | |
163 | ||
164 | ||
165 | //__________________________________________________________ | |
166 | void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){ | |
167 | ||
168 | // | |
169 | // create output fOutputList | |
170 | // | |
171 | ||
172 | // THnSparseF | |
173 | // 8 interested electron sources: others, photon conv, direct photon, pi0, eta, b, b->c, c | |
174 | // 21 possible DCA cuts XY | |
175 | // 21 possible DCA cuts Z | |
176 | // 13 pT bins | |
177 | // 10 rapidity bins | |
178 | // 10 azimuthal angle phi bins | |
179 | ||
180 | ||
181 | if(!displacedList) return; | |
182 | ||
183 | fOutputList = displacedList; | |
184 | fOutputList -> SetName("information"); | |
185 | ||
186 | ||
187 | // electron source | |
188 | Int_t nBinsEleSource = 8; | |
189 | Double_t minEleSource = -1.5; | |
190 | Double_t maxEleSource = 6.5; | |
191 | Double_t *binLimEleSource = new Double_t[nBinsEleSource+1]; | |
192 | for(Int_t i=0; i<=nBinsEleSource; i++) | |
193 | binLimEleSource[i] = minEleSource + i*(maxEleSource-minEleSource)/nBinsEleSource; | |
194 | ||
195 | // dca bins: the same as XY and Z | |
196 | // these should be variable bins as well | |
197 | Int_t nBinsDca = kNDcaMin-1; // 12 bins | |
198 | Double_t minDca = -0.5; | |
199 | Double_t maxDca = 20.5; | |
200 | Double_t dcaBinWidth = (maxDca-minDca)/nBinsDca; | |
201 | Double_t *binLimDca = new Double_t[nBinsDca+1]; | |
202 | for(Int_t i=0; i<=nBinsDca; i++) | |
203 | binLimDca[i] = minDca + i*dcaBinWidth; | |
204 | ||
205 | ||
206 | // pt bins | |
207 | Int_t nBinsPt = kNPtIntv-1; | |
208 | Double_t *binLimPt = new Double_t[nBinsPt+1]; | |
209 | for(Int_t i=0; i<=nBinsPt; i++) | |
210 | binLimPt[i] = fgkPtIntv[i]; // variable bins | |
211 | ||
212 | // rapidity bins | |
213 | Int_t nBinsRap = 10; | |
214 | Double_t minRap = -1.0; | |
215 | Double_t maxRap = 1.0; | |
216 | Double_t *binLimRap = new Double_t[nBinsRap+1]; | |
217 | for(Int_t i=0; i<=nBinsRap; i++) | |
218 | binLimRap[i] = minRap + i*(maxRap-minRap)/nBinsRap; | |
219 | ||
220 | // azumuthal phi angle | |
221 | Int_t nBinsPhi = 10; | |
222 | Double_t minPhi = 0; | |
223 | Double_t maxPhi = 2*TMath::Pi(); | |
224 | Double_t *binLimPhi = new Double_t[nBinsPhi+1]; | |
225 | for(Int_t i=0; i<=nBinsPhi; i++) | |
226 | binLimPhi[i] = minPhi + i*(maxPhi-minPhi)/nBinsPhi; | |
227 | ||
228 | ||
229 | ||
230 | //for MC pionss | |
231 | const Int_t nVarPion = 5; | |
232 | Int_t iBinPion[nVarPion] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; | |
233 | ||
91c7e1ec | 234 | // THnSparseF *fTHnSparseDcaMcPionInfo = NULL; // empty for the moment |
70da6c5a | 235 | if(HasMCData()){ |
236 | fTHnSparseDcaMcPionInfo = new THnSparseF("dcaMcPionInfo", | |
237 | "MC info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", | |
238 | nVarPion, iBinPion); | |
239 | fTHnSparseDcaMcPionInfo->SetBinEdges(0, binLimDca); // dca xy cut | |
240 | fTHnSparseDcaMcPionInfo->SetBinEdges(1, binLimDca); // dca z cut | |
241 | fTHnSparseDcaMcPionInfo->SetBinEdges(2, binLimPt); // pt | |
242 | fTHnSparseDcaMcPionInfo->SetBinEdges(3, binLimRap); // rapidity | |
243 | fTHnSparseDcaMcPionInfo->SetBinEdges(4, binLimPhi); // phi | |
244 | fTHnSparseDcaMcPionInfo->Sumw2(); | |
245 | ||
246 | fOutputList -> AddAt(fTHnSparseDcaMcPionInfo, kMCpion); | |
247 | } | |
248 | ||
249 | // for MC electrons | |
250 | const Int_t nVar = 6; | |
251 | Int_t iBin[nVar] = {nBinsEleSource,nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; | |
252 | ||
91c7e1ec | 253 | // THnSparseF *fTHnSparseDcaMcEleInfo = NULL; // empty for the moment |
70da6c5a | 254 | if(HasMCData()){ |
255 | fTHnSparseDcaMcEleInfo = new THnSparseF("dcaMcElectronInfo", | |
256 | "MC info:;ID [electron source id];dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", | |
257 | nVar, iBin); | |
258 | fTHnSparseDcaMcEleInfo->SetBinEdges(0, binLimEleSource); // electron source | |
259 | fTHnSparseDcaMcEleInfo->SetBinEdges(1, binLimDca); // dca xy cut | |
260 | fTHnSparseDcaMcEleInfo->SetBinEdges(2, binLimDca); // dca z cut | |
261 | fTHnSparseDcaMcEleInfo->SetBinEdges(3, binLimPt); // pt | |
262 | fTHnSparseDcaMcEleInfo->SetBinEdges(4, binLimRap); // rapidity | |
263 | fTHnSparseDcaMcEleInfo->SetBinEdges(5, binLimPhi); // phi | |
264 | fTHnSparseDcaMcEleInfo->Sumw2(); | |
265 | fOutputList -> AddAt(fTHnSparseDcaMcEleInfo, kMCelectron); | |
266 | } | |
267 | ||
268 | ||
269 | // for ESD: HFE pid | |
270 | ||
91c7e1ec | 271 | // THnSparseF *fTHnSparseDcaDataEleInfo = NULL; // empty for the moment |
70da6c5a | 272 | const Int_t nVarData = 5; |
273 | Int_t iBinData[nVarData] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; | |
274 | ||
275 | fTHnSparseDcaDataEleInfo = new THnSparseF("dcaDataElectronInfo", | |
276 | "Data info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", | |
277 | nVarData, iBinData); | |
278 | fTHnSparseDcaDataEleInfo->SetBinEdges(0, binLimDca); // dca xy cut | |
279 | fTHnSparseDcaDataEleInfo->SetBinEdges(1, binLimDca); // dca z cut | |
280 | fTHnSparseDcaDataEleInfo->SetBinEdges(2, binLimPt); // pt | |
281 | fTHnSparseDcaDataEleInfo->SetBinEdges(3, binLimRap); // rapidity | |
282 | fTHnSparseDcaDataEleInfo->SetBinEdges(4, binLimPhi); // phi | |
283 | fTHnSparseDcaDataEleInfo->Sumw2(); | |
284 | ||
285 | fOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kData); | |
286 | ||
287 | AliInfo("THnSparse histograms are created\n"); | |
288 | fOutputList->Print(); | |
289 | ||
290 | } | |
291 | ||
292 | ||
293 | //__________________________________________________________ | |
294 | void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack) | |
295 | { | |
296 | ||
297 | // fill output | |
298 | if(!esdTrack) return; | |
299 | AliESDtrack *track = esdTrack; | |
300 | Double_t pt = track->Pt(); | |
301 | Double_t eta = track->Eta(); | |
302 | Double_t phi = track->Phi(); | |
303 | ||
304 | Int_t label = track->GetLabel(); | |
305 | if(label<0 || label>stack->GetNtrack()) return; | |
306 | ||
307 | TParticle *particle = stack->Particle(label); | |
308 | if(!particle) return; | |
309 | ||
310 | ||
311 | // obtain impact parameters in xy and y | |
312 | const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex(); | |
313 | ||
314 | Float_t magneticField = 5; // initialized as 5kG | |
315 | magneticField = fESDEvent->GetMagneticField(); // in kG | |
316 | ||
317 | ||
318 | Double_t dz[2]; // error of dca in cm | |
319 | Double_t covardz[3]; | |
320 | track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); | |
321 | ||
322 | ||
323 | Double_t dcaXY = TMath::Abs(dz[0])*1.0e4; // conv dca in cm to dca in micron | |
324 | Double_t dcaZ = TMath::Abs(dz[1])*1.0e4; | |
325 | ||
326 | // do PID with MC | |
327 | ||
328 | if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGelectron){ | |
329 | ||
330 | Int_t eleLabel = label; | |
331 | ||
332 | const Int_t nvarMC=6; | |
333 | Double_t var[nvarMC]; | |
334 | var[0] = -1; | |
335 | Int_t sourcePdg = ElectronFromSource(stack, eleLabel); | |
336 | ||
337 | if(sourcePdg==kPDGgamma){ // check direct photon or not // fixme | |
338 | if(ElePhotonDirect(stack, eleLabel)!=-1) | |
339 | var[0] = kEleDirectPhotonConv; | |
340 | else | |
341 | var[0] = kElePhotonConv; | |
342 | if(fDebugLevel>=10) | |
343 | printf("photonconv=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); | |
344 | } // photon or direct photon -> e | |
345 | ||
346 | if(sourcePdg==kPDGpi0){ | |
347 | var[0] = kElePi0; | |
348 | if(fDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); | |
349 | } | |
350 | ||
351 | if(sourcePdg==kPDGeta){ | |
352 | var[0] = kEleEta; | |
353 | if(fDebugLevel>=10) | |
354 | printf("eta=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); | |
355 | } // from eta -> e | |
356 | ||
357 | if(TMath::Abs(sourcePdg%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 | |
358 | TMath::Abs(sourcePdg)/1000==kPDGbeauty || | |
359 | TMath::Abs(sourcePdg)/100==kPDGbeauty || | |
360 | TMath::Abs(sourcePdg)==kPDGbeauty){ | |
361 | var[0]=kEleB; | |
362 | if(fDebugLevel>=10) | |
363 | printf("beauty======electron %d is from %d with id %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); | |
364 | } // direct beauty -> e | |
365 | if(TMath::Abs(sourcePdg%10000)/100==kPDGcharm || // for special intermediate meson states: like 1004** | |
366 | TMath::Abs(sourcePdg)/1000==kPDGcharm || | |
367 | TMath::Abs(sourcePdg)/100==kPDGcharm || | |
368 | TMath::Abs(sourcePdg)==kPDGcharm){ | |
369 | // two cases: | |
370 | // electron from b->c->e | |
371 | // electron from c->e | |
372 | if(ElectronFromCharm(stack, eleLabel)!=-1){ | |
373 | var[0] = ElectronFromCharm(stack, eleLabel); | |
374 | if(fDebugLevel>=10) | |
375 | printf("charm----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); | |
376 | } | |
377 | } // charm electrons: b->c->e or c->e | |
378 | ||
379 | if(fDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); | |
380 | ||
381 | if(dcaXY<1000) var[1] = Int_t(dcaXY)/50; // larger than 1mm should go to the last bin | |
382 | else | |
383 | var[1] = 20; | |
384 | if(dcaZ<1000) var[2] = Int_t(dcaZ)/50; | |
385 | else | |
386 | var[2] = 20; | |
387 | ||
388 | var[3] = pt; // pt | |
389 | var[4] = eta; // eta | |
390 | var[5] = phi; // phi | |
391 | ||
392 | (dynamic_cast<THnSparseF *>(fOutputList->At(kMCelectron)))->Fill(var); | |
393 | } | |
394 | ||
395 | if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGpion){ | |
396 | ||
397 | const Int_t nvarPionMC=5; | |
398 | Double_t varPion[nvarPionMC]; | |
399 | if(dcaXY<1000) | |
400 | varPion[0] = Int_t(dcaXY)/50; // dca xy | |
401 | else | |
402 | varPion[0] = 20; | |
403 | if(dcaZ<1000) | |
404 | varPion[1] = Int_t(dcaZ)/50; // dca Z | |
405 | else | |
406 | varPion[1] = 20; | |
407 | ||
408 | // varPion[0] = TMath::Abs(dcaXY); // dca xy | |
409 | // varPion[1] = TMath::Abs(dcaZ); // dca z | |
410 | varPion[2] = pt; // pt | |
411 | varPion[3] = eta; //eta | |
412 | varPion[4] = phi; // phi | |
413 | ||
414 | (dynamic_cast<THnSparseF *>(fOutputList->At(kMCpion)))->Fill(varPion); | |
415 | } | |
416 | ||
417 | } | |
418 | ||
419 | ||
420 | ||
421 | //__________________________________________________________ | |
91c7e1ec | 422 | void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack) |
70da6c5a | 423 | { |
424 | ||
425 | // fill output | |
426 | if(!esdTrack) return; | |
427 | AliESDtrack *track = esdTrack; | |
428 | ||
429 | Double_t pt = track->Pt(); | |
430 | Double_t eta = track->Eta(); | |
431 | Double_t phi = track->Phi(); | |
432 | ||
433 | // obtain impact parameters in xy and y | |
91c7e1ec | 434 | const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex(); |
70da6c5a | 435 | |
436 | Float_t magneticField = 5; // initialized as 5kG | |
91c7e1ec | 437 | magneticField = fESDEvent->GetMagneticField(); // in kG |
70da6c5a | 438 | Double_t dz[2]; // error of dca in cm |
439 | Double_t covardz[3]; | |
440 | track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); | |
441 | Double_t dcaXY = TMath::Abs(dz[0]*1.0e4); // conv dca in cm to dca in micron | |
442 | Double_t dcaZ = TMath::Abs(dz[1]*1.0e4); | |
443 | ||
444 | ||
445 | const Int_t nvarData = 5; | |
446 | Double_t varData[nvarData]; | |
447 | // fixme | |
448 | if(dcaXY<1000) | |
449 | varData[0] = Int_t(dcaXY)/50; // dca xy | |
450 | else | |
451 | varData[0] = 20; | |
452 | if(dcaZ<1000) | |
453 | varData[1] = Int_t(dcaZ)/50; // dca Z | |
454 | else | |
455 | varData[1] = 20; | |
456 | ||
457 | varData[2] = pt; // pt | |
458 | varData[3] = eta; //eta | |
459 | varData[4] = phi; // phi | |
460 | ||
461 | (dynamic_cast<THnSparseF *>(fOutputList->At(kData)))->Fill(varData); | |
462 | ||
463 | } | |
464 | ||
465 | //__________________________________________________________ | |
466 | Int_t AliHFEdisplacedElectrons::ElectronFromSource(AliStack * const stack, Int_t label) const | |
467 | { | |
468 | ||
469 | // | |
470 | // return electron source label via electron label | |
471 | // | |
472 | ||
473 | // kEleSource is supposed to be either photon conv, direct photon conv, pi0, eta, beauty --> 0, 1, 2, 3, 4 | |
474 | ||
475 | Int_t eleLabel = label; | |
476 | ||
477 | if(eleLabel<0 || eleLabel>stack->GetNtrack()) return -1; | |
478 | ||
479 | TParticle *particle = stack->Particle(eleLabel); | |
480 | if(!particle) return -1; | |
481 | ||
482 | Int_t motherLabel = particle->GetFirstMother(); | |
483 | if(motherLabel<0 || motherLabel>stack->GetNtrack()) return -1; | |
484 | TParticle *motherPart = stack->Particle(motherLabel); | |
485 | if(!motherPart) return -1; | |
486 | ||
487 | Int_t pdgCode = TMath::Abs(motherPart->GetPdgCode()); | |
488 | ||
489 | if(pdgCode==kPDGelectron) { | |
490 | if(fDebugLevel>=10) printf("particle label: %d...(motherLabel=%d : motherPdg=%d) grandmother's pdg code was returned...%d \n", | |
491 | label, motherLabel, pdgCode, ElectronFromSource(stack, motherLabel)); | |
492 | return ElectronFromSource(stack, motherLabel); | |
493 | } | |
494 | ||
495 | return pdgCode; | |
496 | ||
497 | } | |
498 | ||
499 | //__________________________________________________________ | |
500 | Int_t AliHFEdisplacedElectrons::ElectronFromCharm(AliStack * const stack, Int_t label) const | |
501 | { | |
502 | // | |
503 | // separate electron: kEleC from c->eX, kEleBC from b->c->eX | |
504 | // | |
505 | ||
506 | Int_t motherLabel = label; | |
507 | TParticle *motherParticle = stack->Particle(motherLabel); // mother part | |
508 | if(!motherParticle) return -1; | |
509 | Int_t gMotherLabel = motherParticle->GetFirstMother(); // grand mother | |
510 | if(gMotherLabel<0 || gMotherLabel>stack->GetNtrack()) return -1; | |
511 | ||
512 | TParticle *gMotherPart = stack->Particle(gMotherLabel); | |
513 | if(!gMotherPart) return -1; | |
514 | ||
515 | Int_t pdgCode = gMotherPart->GetPdgCode(); | |
516 | if(TMath::Abs(pdgCode%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 | |
517 | TMath::Abs(pdgCode)/1000==kPDGbeauty || TMath::Abs(pdgCode)/100==kPDGbeauty || TMath::Abs(pdgCode)==kPDGbeauty) { | |
518 | if(fDebugLevel>=10) printf("this electron label %d is from mother %d, and finally from %d\n", label, ElectronFromSource(stack, label), pdgCode); | |
519 | return kEleBC; | |
520 | } // for sure it is from BC | |
521 | ||
522 | else | |
523 | if(TMath::Abs(pdgCode%10000)/100==kPDGcharm || // for special intermediate meson states: like 100443, 10443, 204*3 (*=1, 2, 3, 4) | |
524 | TMath::Abs(pdgCode)/1000==kPDGcharm || | |
525 | TMath::Abs(pdgCode)/100==kPDGcharm || | |
526 | TMath::Abs(pdgCode)==kPDGcharm){ | |
527 | ||
528 | if(CharmFromBeauty(stack, gMotherLabel)!=-1) | |
529 | return kEleBC; | |
530 | else | |
531 | return kEleC; | |
532 | ||
533 | } | |
534 | ||
535 | else | |
536 | return -1; | |
537 | ||
538 | } | |
539 | ||
540 | //__________________________________________________________ | |
541 | Int_t AliHFEdisplacedElectrons::CharmFromBeauty(AliStack * const stack, Int_t hfLabel) const | |
542 | { | |
543 | ||
544 | // | |
545 | // check if charm meson/hadron is from beauty decay | |
546 | // -1, not from beauty | |
547 | // return the label of the mother of this charm hadron | |
548 | // | |
549 | ||
550 | Int_t charmLabel = hfLabel; | |
551 | ||
552 | // AliStack *stack = fMC->Stack(); | |
553 | if(charmLabel<0 || charmLabel>stack->GetNtrack()) return -1; | |
554 | TParticle *particle = stack->Particle(charmLabel); | |
555 | if(!particle) return -1; | |
556 | ||
557 | Int_t motherCharmLabel = particle->GetFirstMother(); | |
558 | if(motherCharmLabel<0 || motherCharmLabel>stack->GetNtrack()) return -1; | |
559 | ||
560 | TParticle *motherCharmPart = stack->Particle(motherCharmLabel); | |
561 | if(!motherCharmPart) return -1; | |
562 | ||
563 | Int_t pdgCode = motherCharmPart->GetPdgCode(); | |
564 | ||
565 | if(TMath::Abs(pdgCode%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 | |
566 | TMath::Abs(pdgCode)/1000==kPDGbeauty || | |
567 | TMath::Abs(pdgCode)/100==kPDGbeauty || | |
568 | TMath::Abs(pdgCode)==kPDGbeauty) | |
569 | return motherCharmLabel; | |
570 | else | |
571 | if(TMath::Abs(pdgCode%10000)/100==kPDGcharm || // for special intermediate meson states: like 100443, 10443, 204*3 (*=1, 2, 3, 4) | |
572 | TMath::Abs(pdgCode)/1000==kPDGcharm || | |
573 | TMath::Abs(pdgCode)/100==kPDGcharm) | |
574 | return CharmFromBeauty(stack, motherCharmLabel); // loop over to see if charm is from beauty -- if yes, return the label of mother of the charm | |
575 | ||
576 | else | |
577 | return -1; | |
578 | } | |
579 | ||
580 | //__________________________________________________________ | |
581 | Int_t AliHFEdisplacedElectrons::ElePhotonDirect(AliStack * const stack, Int_t label) const | |
582 | { | |
583 | // | |
584 | // electron is from photon, and check if this photon is direct | |
585 | // | |
586 | ||
587 | Int_t eleLabel = label; | |
588 | ||
589 | TParticle *particle = stack->Particle(eleLabel); | |
590 | if(particle->GetFirstMother()<0 || particle->GetFirstMother()>stack->GetNtrack()) | |
591 | return -1; | |
592 | ||
593 | TParticle *photonPart = stack->Particle(particle->GetFirstMother()); | |
594 | if(!photonPart) | |
595 | return -1; | |
596 | Int_t motherPhotonLabel = photonPart->GetFirstMother(); | |
597 | if(motherPhotonLabel<0 || motherPhotonLabel>stack->GetNtrack()) | |
598 | return -1; | |
599 | ||
600 | TParticle *motherPhotonPart = stack->Particle(motherPhotonLabel); | |
601 | if(!motherPhotonPart) | |
602 | return -1; | |
603 | ||
604 | Int_t pdgMotherPhoton = motherPhotonPart->GetPdgCode(); | |
605 | if(TMath::Abs(pdgMotherPhoton)<=10 || TMath::Abs(pdgMotherPhoton)==21) | |
606 | return 1; | |
607 | ||
608 | else | |
609 | return -1; | |
610 | ||
611 | ||
612 | } | |
613 | ||
614 | //__________________________________________________________ | |
615 | Int_t AliHFEdisplacedElectrons::GetMCpid(AliStack* const stack, Int_t partLabel) const | |
616 | { | |
617 | ||
618 | // | |
619 | // Simply pdg code | |
620 | // | |
621 | ||
622 | Int_t label = partLabel; | |
623 | // AliStack* stack = fMC->Stack(); | |
624 | if((label < 0) || (label >= stack->GetNtrack())) return -1; | |
625 | ||
626 | // MC Information | |
627 | TParticle * particle = stack->Particle(label); | |
628 | if(!particle) return -1; | |
629 | Int_t pdg = particle->GetPdgCode(); | |
630 | ||
631 | return pdg; | |
632 | ||
633 | } | |
634 | ||
635 | //__________________________________________________________ | |
636 | Int_t AliHFEdisplacedElectrons::GetMotherLabel(AliStack *const stack, Int_t eleLabel) const | |
637 | { | |
638 | // | |
639 | // Simply label of mother | |
640 | // | |
641 | ||
642 | ||
643 | Int_t label = eleLabel; | |
644 | // AliStack* stack = fMC->Stack(); | |
645 | if((label < 0) || (label >= stack->GetNtrack())) return -1; | |
646 | ||
647 | // MC Information | |
648 | TParticle * particle = stack->Particle(label); | |
649 | if(!particle) return -1; | |
650 | ||
651 | return particle->GetFirstMother(); | |
652 | ||
653 | } | |
654 | ||
655 | ||
656 | //__________________________________________________________ | |
657 | Float_t AliHFEdisplacedElectrons::GetRapidity(TParticle *part) const | |
658 | { | |
659 | // return rapidity | |
660 | ||
661 | Float_t rapidity = -999; | |
662 | if((part->Energy() - part->Pz())*(part->Energy() + part->Pz())>0) | |
663 | rapidity = 0.5*(TMath::Log((part->Energy()+part->Pz()) / (part->Energy()-part->Pz()))); | |
664 | ||
665 | return rapidity; | |
666 | } | |
667 | ||
668 | ||
669 | //__________________________________________________________ | |
670 | Float_t AliHFEdisplacedElectrons::GetTrackRapidity(AliESDtrack * const track) const | |
671 | { | |
672 | // return rapidity of electron | |
673 | ||
674 | Float_t px = track->Px(); | |
675 | Float_t py = track->Py(); | |
676 | Float_t pz = track->Pz(); | |
677 | ||
678 | // electron mass 0.00051099906 GeV/c2 | |
679 | TParticlePDG* electron = TDatabasePDG::Instance()->GetParticle(kPDGelectron); | |
680 | Double_t mass = electron->Mass(); | |
681 | ||
682 | Float_t en = TMath::Sqrt(px*px + py*py + pz*pz + mass*mass); | |
683 | ||
684 | Float_t rapidity = -999; | |
685 | if((en - pz)*(en + pz)>0) | |
686 | rapidity = 0.5*(TMath::Log((en - pz)*(en + pz))); | |
687 | ||
688 | return rapidity; | |
689 | } |