]>
Commit | Line | Data |
---|---|---|
7cd4e982 | 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 | /* $Id: AliMCAnalysisUtils.cxx 21839 2007-10-29 13:49:42Z gustavo $ */ | |
16 | ||
17 | //_________________________________________________________________________ | |
18 | // Class for analysis utils for MC data | |
19 | // stored in stack or event header. | |
20 | // Contains: | |
21 | // - method to check the origin of a given track/cluster | |
22 | // - method to obtain the generated jets | |
23 | // | |
24 | //*-- Author: Gustavo Conesa (LNF-INFN) | |
25 | ////////////////////////////////////////////////////////////////////////////// | |
26 | ||
27 | ||
28 | // --- ROOT system --- | |
29 | #include <TMath.h> | |
30 | #include <TList.h> | |
31 | #include "TParticle.h" | |
32 | ||
33 | //---- ANALYSIS system ---- | |
34 | #include "AliMCAnalysisUtils.h" | |
35 | #include "AliCaloTrackReader.h" | |
36 | #include "AliStack.h" | |
37 | #include "AliGenPythiaEventHeader.h" | |
38 | #include "AliAODMCParticle.h" | |
39 | ||
40 | ClassImp(AliMCAnalysisUtils) | |
41 | ||
42 | //________________________________________________ | |
43 | AliMCAnalysisUtils::AliMCAnalysisUtils() : | |
44 | TObject(), fCurrentEvent(-1), fDebug(-1), | |
45 | fJetsList(new TList), fMCGenerator("PYTHIA") | |
46 | { | |
47 | //Ctor | |
48 | } | |
49 | ||
50 | //____________________________________________________________________________ | |
51 | AliMCAnalysisUtils::AliMCAnalysisUtils(const AliMCAnalysisUtils & mcutils) : | |
52 | TObject(mcutils), fCurrentEvent(mcutils.fCurrentEvent), fDebug(mcutils.fDebug), | |
53 | fJetsList(mcutils.fJetsList), fMCGenerator(mcutils.fMCGenerator) | |
54 | { | |
55 | // cpy ctor | |
56 | ||
57 | } | |
58 | ||
59 | //_________________________________________________________________________ | |
60 | AliMCAnalysisUtils & AliMCAnalysisUtils::operator = (const AliMCAnalysisUtils & mcutils) | |
61 | { | |
62 | // assignment operator | |
63 | ||
64 | if(&mcutils == this) return *this; | |
65 | fCurrentEvent = mcutils.fCurrentEvent ; | |
66 | fDebug = mcutils.fDebug; | |
67 | fJetsList = mcutils.fJetsList; | |
68 | fMCGenerator = mcutils.fMCGenerator; | |
69 | ||
70 | return *this; | |
71 | } | |
72 | ||
73 | //____________________________________________________________________________ | |
74 | AliMCAnalysisUtils::~AliMCAnalysisUtils() | |
75 | { | |
76 | // Remove all pointers. | |
77 | ||
78 | if (fJetsList) { | |
79 | fJetsList->Clear(); | |
80 | delete fJetsList ; | |
81 | } | |
82 | } | |
83 | ||
84 | ||
85 | //_________________________________________________________________________ | |
86 | Int_t AliMCAnalysisUtils::CheckOrigin(const Int_t label, AliCaloTrackReader* reader, const Int_t input = 0) { | |
87 | //Play with the montecarlo particles if available | |
88 | Int_t tag = 0; | |
89 | ||
90 | //Select where the information is, ESD-galice stack or AOD mcparticles branch | |
91 | if(reader->ReadStack()){ | |
92 | tag = CheckOriginInStack(label, reader->GetStack()); | |
93 | } | |
94 | else if(reader->ReadAODMCParticles()){ | |
95 | tag = CheckOriginInAOD(label, reader->GetAODMCParticles(input)); | |
96 | } | |
97 | ||
98 | return tag ; | |
99 | } | |
100 | ||
101 | //_________________________________________________________________________ | |
102 | Int_t AliMCAnalysisUtils::CheckOriginInStack(const Int_t label, AliStack* stack) { | |
103 | // Play with the MC stack if available. Tag particles depending on their origin. | |
104 | // Do same things as in CheckOriginInAOD but different input. | |
105 | ||
106 | if(!stack) { | |
107 | printf("AliMCAnalysisUtils::CheckOriginInStack() - Stack is not available, check analysis settings in configuration file, STOP!!\n"); | |
108 | abort(); | |
109 | } | |
110 | // printf("label %d, ntrack %d, nprim %d\n",label, stack->GetNtrack(), stack->GetNprimary()); | |
111 | // for(Int_t i = 0; i< stack->GetNprimary(); i++){ | |
112 | // TParticle *particle = stack->Particle(i); | |
113 | // //particle->Print(); | |
114 | // } | |
115 | ||
116 | ||
117 | Int_t tag = 0; | |
118 | if(label >= 0 && label < stack->GetNtrack()){ | |
119 | //Mother | |
120 | TParticle * mom = stack->Particle(label); | |
121 | Int_t mPdg = TMath::Abs(mom->GetPdgCode()); | |
122 | Int_t mStatus = mom->GetStatusCode() ; | |
123 | Int_t iParent = mom->GetFirstMother() ; | |
124 | if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent); | |
125 | ||
126 | //GrandParent | |
127 | TParticle * parent = new TParticle ; | |
128 | Int_t pPdg = -1; | |
129 | Int_t pStatus =-1; | |
130 | if(iParent > 0){ | |
131 | parent = stack->Particle(iParent); | |
132 | pPdg = TMath::Abs(parent->GetPdgCode()); | |
133 | pStatus = parent->GetStatusCode(); | |
134 | } | |
135 | else if(fDebug > 0 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Parent with label %d\n",iParent); | |
136 | ||
137 | //Check if mother is converted, if not, get the first non converted mother | |
138 | if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && mStatus == 0){ | |
139 | SetTagBit(tag,kMCConversion); | |
140 | //Check if the mother is photon or electron with status not stable | |
141 | while ((pPdg == 22 || pPdg == 11) && mStatus != 1) { | |
142 | //Mother | |
143 | mom = stack->Particle(mom->GetFirstMother()); | |
144 | mPdg = TMath::Abs(mom->GetPdgCode()); | |
145 | mStatus = mom->GetStatusCode() ; | |
146 | iParent = mom->GetFirstMother() ; | |
147 | if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent); | |
148 | ||
149 | //GrandParent | |
150 | if(iParent > 0){ | |
151 | parent = stack->Particle(iParent); | |
152 | pPdg = TMath::Abs(parent->GetPdgCode()); | |
153 | pStatus = parent->GetStatusCode(); | |
154 | } | |
155 | }//while | |
156 | }//mother and parent are electron or photon and have status 0 | |
157 | else if(mStatus == 0){ | |
158 | //Still a conversion but only one electron/photon generated. Just from hadrons | |
159 | if(pPdg == 2112 || pPdg == 211 || | |
160 | pPdg == 321 || pPdg == 2212 || pPdg == 130 || pPdg == 13 ) | |
161 | SetTagBit(tag,kMCConversion); | |
162 | mom = stack->Particle(mom->GetFirstMother()); | |
163 | mPdg = TMath::Abs(mom->GetPdgCode()); | |
164 | //Comment for the next lines, we do not check the parent of the hadron for the moment. | |
165 | //iParent = mom->GetFirstMother() ; | |
166 | //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent); | |
167 | ||
168 | //GrandParent | |
169 | //if(iParent >= 0){ | |
170 | // parent = stack->Particle(iParent); | |
171 | // pPdg = TMath::Abs(parent->GetPdgCode()); | |
172 | //} | |
173 | } | |
174 | // conversion fo electrons/photons checked | |
175 | ||
176 | //first check for typical charged particles | |
177 | if(mPdg == 13) SetTagBit(tag,kMCMuon); | |
178 | else if(mPdg == 211) SetTagBit(tag,kMCPion); | |
179 | else if(mPdg == 321) SetTagBit(tag,kMCKaon); | |
180 | else if(mPdg == 2212) SetTagBit(tag,kMCProton); | |
181 | //check for pi0 and eta (shouldn't happen unless their decays were | |
182 | //turned off) | |
183 | else if(mPdg == 111) SetTagBit(tag,kMCPi0); | |
184 | else if(mPdg == 221) SetTagBit(tag,kMCEta); | |
185 | //Photons | |
186 | else if(mPdg == 22){ | |
187 | SetTagBit(tag,kMCPhoton); | |
188 | if(mStatus == 1){ //undecayed particle | |
189 | if(fMCGenerator == "PYTHIA"){ | |
190 | if(iParent < 8 && iParent > 5) {//outgoing partons | |
191 | if(pPdg == 22) SetTagBit(tag,kMCPrompt); | |
192 | else SetTagBit(tag,kMCFragmentation); | |
193 | }//Outgoing partons | |
194 | else if(iParent <= 5) { | |
195 | SetTagBit(tag, kMCISR); //Initial state radiation | |
196 | } | |
197 | else if(pStatus == 11){//Decay | |
198 | if(pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
199 | else if (pPdg == 221) SetTagBit(tag, kMCEtaDecay); | |
200 | else SetTagBit(tag,kMCOtherDecay); | |
201 | }//Decay | |
202 | else { | |
203 | printf("AliMCAnalysisUtils::ChecOrigingInAOD() - what is it? Mother mPdg %d, status %d \n Parent iParent %d, pPdg %d %s, status %d\n", | |
204 | mPdg, mStatus,iParent, pPdg, parent->GetName(),pStatus); | |
205 | SetTagBit(tag,kMCOtherDecay);//Check | |
206 | } | |
207 | }//PYTHIA | |
208 | ||
209 | else if(fMCGenerator == "HERWIG"){ | |
210 | if(pStatus < 197){//Not decay | |
211 | while(1){ | |
212 | if(parent->GetFirstMother()<=5) break; | |
213 | iParent = parent->GetFirstMother(); | |
214 | parent=stack->Particle(iParent); | |
215 | pStatus= parent->GetStatusCode(); | |
216 | pPdg = parent->GetPdgCode(); | |
217 | }//Look for the parton | |
218 | ||
219 | if(iParent < 8 && iParent > 5) { | |
220 | if(pPdg == 22) SetTagBit(tag,kMCPrompt); | |
221 | else SetTagBit(tag,kMCFragmentation); | |
222 | } | |
223 | else SetTagBit(tag,kMCISR);//Initial state radiation | |
224 | }//Not decay | |
225 | else{//Decay | |
226 | if(pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
227 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); | |
228 | else SetTagBit(tag,kMCOtherDecay); | |
229 | }//Decay | |
230 | }//HERWIG | |
231 | ||
232 | else SetTagBit(tag,kMCUnknown); | |
233 | ||
234 | }//Status 1 : created by event generator | |
235 | ||
236 | else if(mStatus == 0){ // geant | |
237 | if(pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
238 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); | |
239 | else SetTagBit(tag,kMCOtherDecay); | |
240 | }//status 0 : geant generated | |
241 | ||
242 | }//Mother Photon | |
243 | ||
244 | //Electron check. Where did that electron come from? | |
245 | else if(mPdg == 11){ //electron | |
246 | SetTagBit(tag,kMCElectron); | |
247 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInStack() - Checking ancestors of electrons"); | |
248 | ||
249 | //check first for B and C ancestry, then other possibilities. | |
250 | //An electron from a photon parent could have other particles in | |
251 | //its history and we would want to know that, right? | |
252 | ||
253 | if(mStatus == 1) { //electron from event generator | |
254 | if (pPdg == 23) SetTagBit(tag,kMCZDecay); //parent is Z-boson | |
255 | else if (pPdg == 24) SetTagBit(tag,kMCWDecay); //parent is W-boson | |
256 | else if (pPdg == 111) SetTagBit(tag,kMCPi0Decay); //Pi0 Dalitz decay | |
257 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); //Eta Dalitz decay | |
258 | else { //check the electron's ancestors for B/C contribution | |
259 | Bool_t bAncestor = kFALSE; | |
260 | Bool_t cAncestor = kFALSE; | |
261 | TParticle * ancestors = stack->Particle(label); //start from electron | |
262 | Int_t iAncestors = ancestors->GetFirstMother(); //get its mother index | |
263 | if(iAncestors < 0) return tag; //no ancestor, shouldn't happen | |
264 | ancestors = stack->Particle(iAncestors); //get electron mother | |
265 | Int_t aPdg = TMath::Abs(ancestors->GetPdgCode()); //get electron mother pdg | |
266 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOrigin: Scaning the decay chain for bottom/charm generated electron"); | |
267 | while(1){//check electron's mother's pdg and its mother(s) | |
268 | //pdgs | |
269 | if((499 < aPdg && aPdg < 600)||(4999 < aPdg && aPdg < 6000)) bAncestor = kTRUE; | |
270 | if((399 < aPdg && aPdg < 500)||(3999 < aPdg && aPdg < 5000)) cAncestor = kTRUE; | |
271 | if(bAncestor && cAncestor) break; | |
272 | iAncestors = ancestors->GetFirstMother(); | |
273 | if(iAncestors < 0) break; | |
274 | ancestors = stack->Particle(iAncestors); | |
275 | aPdg = ancestors->GetPdgCode(); | |
276 | }//searching for ancestors | |
277 | if(bAncestor && cAncestor) SetTagBit(tag,kMCEFromCFromB);//Decay chain has both B and C | |
278 | else if(bAncestor && !cAncestor) SetTagBit(tag,kMCEFromB);//Decay chain has only B | |
279 | else if(!bAncestor && cAncestor) SetTagBit(tag,kMCEFromC);//Decay chain has only C | |
280 | } | |
281 | //if it is not from any of the above, where is it from? | |
282 | if(fDebug > 0) printf("Electron from other origin: %s (pdg = %d)\n",parent->GetName(),pPdg); | |
283 | SetTagBit(tag,kMCOtherDecay); | |
284 | } | |
285 | else if (mStatus == 0) { //electron from GEANT | |
286 | ||
287 | //Rewind ancestry and check for electron with status == 1 | |
288 | //if we find one, we'll assume that this object is from an | |
289 | //electron but that it may have gone through some showering in | |
290 | //material before the detector | |
291 | ||
292 | //Not a double-counting problem because we are only accessing | |
293 | //these histories for MC labels connected to a reco object. | |
294 | //If you wanted to use this to sort through the kine stack | |
295 | //directly, might it be a problem? | |
296 | Bool_t eleFromEvGen = kFALSE; | |
297 | Bool_t bAncestor = kFALSE; | |
298 | Bool_t cAncestor = kFALSE; | |
299 | ||
300 | TParticle * ancestors = stack->Particle(label); //start from electron | |
301 | Int_t iAncestors = ancestors->GetFirstMother(); //get its mother index | |
302 | if(iAncestors < 0) return tag; //no ancestor, shouldn't happen | |
303 | ancestors = stack->Particle(iAncestors); //get electron mother | |
304 | Int_t aStatus = ancestors->GetStatusCode(); //get electron mother's status | |
305 | Int_t aPdg = TMath::Abs(ancestors->GetPdgCode()); //get electron mother pdg | |
306 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOrigin: Scanning the decay chain for bottom/charm generated electron"); | |
307 | while(1){//check electron's mother's pdg and its mother(s) pdgs | |
308 | if(aStatus == 1 && aPdg == 11) eleFromEvGen = kTRUE; | |
309 | if(eleFromEvGen && aPdg == 23) SetTagBit(tag,kMCZDecay); | |
310 | if(eleFromEvGen && aPdg == 24) SetTagBit(tag,kMCWDecay); | |
311 | if(eleFromEvGen && ((499 < aPdg && aPdg < 600)||(4999 < aPdg && aPdg < 6000))) bAncestor = kTRUE; | |
312 | if(eleFromEvGen && ((399 < aPdg && aPdg < 500)||(3999 < aPdg && aPdg < 5000))) cAncestor = kTRUE; | |
313 | if(bAncestor && cAncestor) break; | |
314 | iAncestors = ancestors->GetFirstMother(); | |
315 | if(iAncestors <= 5) break; | |
316 | ancestors = stack->Particle(iAncestors); | |
317 | aPdg = ancestors->GetPdgCode(); | |
318 | }//searching for ancestors | |
319 | if(bAncestor && cAncestor) SetTagBit(tag,kMCEFromCFromB);//Decay chain has both B and C | |
320 | else if(bAncestor && !cAncestor) SetTagBit(tag,kMCEFromB);//Decay chain has only B | |
321 | else if(!bAncestor && cAncestor) SetTagBit(tag,kMCEFromC);//Decay chain has only C | |
322 | if(pPdg == 22 || pPdg == 11 || pPdg == 2112 || pPdg == 211 || | |
323 | pPdg == 321 || pPdg == 2212 || pPdg == 130 || pPdg == 13) | |
324 | SetTagBit(tag,kMCConversion); | |
325 | else if (pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
326 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); | |
327 | else { | |
328 | //if it is not from any of the above, where is it from? | |
329 | if(pPdg > 10000) SetTagBit(tag,kMCUnknown); | |
330 | if(fDebug > 0) printf("Electron from other origin: %s (pdg = %d)\n",parent->GetName(),pPdg); | |
331 | SetTagBit(tag,kMCOtherDecay); | |
332 | } | |
333 | } //GEANT check | |
334 | }//electron check | |
335 | //Cluster was made by something else | |
336 | else { | |
337 | if(fDebug > 0) printf("\tSetting kMCUnknown for cluster from %s (pdg = %d, Parent pdg = %d)\n",mom->GetName(),mPdg,pPdg); | |
338 | SetTagBit(tag,kMCUnknown); | |
339 | } | |
340 | }//Good label value | |
341 | else{ | |
342 | if(label < 0 ) printf("AliMCAnalysisUtils::CheckOriginInStack() *** bad label or no stack ***: label %d \n", label); | |
343 | if(label >= stack->GetNtrack()) printf("AliMCAnalysisUtils::CheckOriginInStack() *** large label ***: label %d, n tracks %d \n", label, stack->GetNtrack()); | |
344 | SetTagBit(tag,kMCUnknown); | |
345 | }//Bad label | |
346 | ||
347 | return tag; | |
348 | ||
349 | } | |
350 | ||
351 | ||
352 | //_________________________________________________________________________ | |
353 | Int_t AliMCAnalysisUtils::CheckOriginInAOD(const Int_t label, TClonesArray *mcparticles) { | |
354 | // Play with the MCParticles in AOD if available. Tag particles depending on their origin. | |
355 | // Do same things as in CheckOriginInStack but different input. | |
356 | if(!mcparticles) { | |
357 | printf("AliMCAnalysisUtils::CheckOriginInAOD() - AODMCParticles is not available, check analysis settings in configuration file!!\n"); | |
358 | ||
359 | } | |
360 | ||
361 | // printf(">>>>>>>>> Second Event, AODMCParticles, nMC %d\n", (GetAODMCParticles(1))->GetEntriesFast()); | |
362 | // for(Int_t i = 0; i< (GetAODMCParticles(1))->GetEntriesFast(); i++){ | |
363 | // AliAODMCParticle *particle = (AliAODMCParticle*) (GetAODMCParticles(1))->At(i); | |
364 | // printf("** index %d, PDG %d, Flag %d, Mother %d, Daughter %d and %d, E %2.3f, pT %2.3f, phi %2.3f, eta %2.3f\n", | |
365 | // i, particle->GetPdgCode(), particle->GetFlag(), particle->GetMother(), particle->GetDaughter(0),particle->GetDaughter(1), | |
366 | // particle->E(),particle->Pt(), particle->Phi()*TMath::RadToDeg(), particle->Eta()); | |
367 | // if(particle->IsPhysicalPrimary()) printf("Is Physical Primary !\n"); | |
368 | // if(!particle->IsPrimary()) printf("Not Primary !\n"); | |
369 | // } | |
370 | ||
371 | ||
372 | Int_t tag = 0; | |
373 | Int_t nprimaries = mcparticles->GetEntriesFast(); | |
374 | if(label >= 0 && label < nprimaries){ | |
375 | //Mother | |
376 | AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label); | |
377 | Int_t mPdg = TMath::Abs(mom->GetPdgCode()); | |
378 | Int_t iParent = mom->GetMother() ; | |
379 | if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent); | |
380 | ||
381 | //GrandParent | |
382 | AliAODMCParticle * parent = new AliAODMCParticle ; | |
383 | Int_t pPdg = -1; | |
384 | if(iParent >= 0){ | |
385 | parent = (AliAODMCParticle *) mcparticles->At(iParent); | |
386 | pPdg = TMath::Abs(parent->GetPdgCode()); | |
387 | } | |
388 | else if(fDebug > 0 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Parent with label %d\n",iParent); | |
389 | ||
390 | //Check if mother is converted, if not, get the first non converted mother | |
391 | if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && !mom->IsPrimary()){ | |
392 | SetTagBit(tag,kMCConversion); | |
393 | //Check if the mother is photon or electron with status not stable | |
394 | while ((pPdg == 22 || pPdg == 11) && !mom->IsPhysicalPrimary()) { | |
395 | //Mother | |
396 | mom = (AliAODMCParticle *) mcparticles->At(mom->GetMother()); | |
397 | mPdg = TMath::Abs(mom->GetPdgCode()); | |
398 | iParent = mom->GetMother() ; | |
399 | if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent); | |
400 | ||
401 | //GrandParent | |
402 | if(iParent >= 0){ | |
403 | parent = (AliAODMCParticle *) mcparticles->At(iParent); | |
404 | pPdg = TMath::Abs(parent->GetPdgCode()); | |
405 | } | |
406 | }//while | |
407 | }//mother and parent are electron or photon and have status 0 and parent is photon or electron | |
408 | else if(!mom->IsPrimary()){ | |
409 | //Still a conversion but only one electron/photon generated. Just from hadrons | |
410 | if(pPdg == 2112 || pPdg == 211 || | |
411 | pPdg == 321 || pPdg == 2212 || pPdg == 130 || pPdg == 13 ) | |
412 | SetTagBit(tag,kMCConversion); | |
413 | mom = (AliAODMCParticle *) mcparticles->At(mom->GetMother()); | |
414 | mPdg = TMath::Abs(mom->GetPdgCode()); | |
415 | //Comment for next lines, we do not check the parent of the hadron for the moment. | |
416 | //iParent = mom->GetMother() ; | |
417 | //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent); | |
418 | ||
419 | //GrandParent | |
420 | //if(iParent >= 0){ | |
421 | // parent = (AliAODMCParticle *) mcparticles->At(iParent); | |
422 | // pPdg = TMath::Abs(parent->GetPdgCode()); | |
423 | //} | |
424 | } | |
425 | ||
426 | // conversion into electrons/photons checked | |
427 | ||
428 | //first check for typical charged particles | |
429 | if(mPdg == 13) SetTagBit(tag,kMCMuon); | |
430 | else if(mPdg == 211) SetTagBit(tag,kMCPion); | |
431 | else if(mPdg == 321) SetTagBit(tag,kMCKaon); | |
432 | else if(mPdg == 2212) SetTagBit(tag,kMCProton); | |
433 | //check for pi0 and eta (shouldn't happen unless their decays were | |
434 | //turned off) | |
435 | else if(mPdg == 111) SetTagBit(tag,kMCPi0); | |
436 | else if(mPdg == 221) SetTagBit(tag,kMCEta); | |
437 | //Photons | |
438 | else if(mPdg == 22){ | |
439 | SetTagBit(tag,kMCPhoton); | |
440 | if(mom->IsPhysicalPrimary()){ //undecayed particle | |
441 | if(iParent < 8 && iParent > 5) {//outgoing partons | |
442 | if(pPdg == 22) SetTagBit(tag,kMCPrompt); | |
443 | else SetTagBit(tag,kMCFragmentation); | |
444 | }//Outgoing partons | |
445 | else if(iParent <= 5) { | |
446 | SetTagBit(tag, kMCISR); //Initial state radiation | |
447 | } | |
448 | else if(parent->IsPrimary() && !parent->IsPhysicalPrimary()){//Decay | |
449 | if(pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
450 | else if (pPdg == 221) SetTagBit(tag, kMCEtaDecay); | |
451 | else SetTagBit(tag,kMCOtherDecay); | |
452 | }//Decay | |
453 | else { | |
454 | printf("AliMCAnalysisUtils::ChecOrigingInAOD() - what is it? Mother mPdg %d, is primary? %d, is physical %d \n Parent iParent %d, pPdg %d, is primary? %d, is physical? %d\n", | |
455 | mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary(),iParent, pPdg,parent->IsPrimary(), parent->IsPhysicalPrimary()); | |
456 | SetTagBit(tag,kMCOtherDecay);//Check | |
457 | } | |
458 | }// Pythia generated | |
459 | else if(!mom->IsPrimary()){ //Decays | |
460 | if(pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
461 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); | |
462 | else SetTagBit(tag,kMCOtherDecay); | |
463 | }//not primary : geant generated, decays | |
464 | else { | |
465 | //printf("UNKNOWN 1, mom pdg %d, primary %d, physical primary %d; parent %d, pdg %d, primary %d, physical primary %d \n", | |
466 | //mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary(), iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary()); | |
467 | SetTagBit(tag,kMCUnknown); | |
468 | } | |
469 | }//Mother Photon | |
470 | ||
471 | //Electron check. Where did that electron come from? | |
472 | else if(mPdg == 11){ //electron | |
473 | SetTagBit(tag,kMCElectron); | |
474 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Checking ancestors of electrons"); | |
475 | ||
476 | //check first for B and C ancestry, then other possibilities. | |
477 | //An electron from a photon parent could have other particles in | |
478 | //its history and we would want to know that, right? | |
479 | Bool_t eleFromEvGen = kFALSE; | |
480 | Bool_t bAncestor = kFALSE; | |
481 | Bool_t cAncestor = kFALSE; | |
482 | ||
483 | if(mom->IsPhysicalPrimary()) { //electron from event generator | |
484 | if (pPdg == 23) SetTagBit(tag,kMCZDecay); //parent is Z-boson | |
485 | else if (pPdg == 24) SetTagBit(tag,kMCWDecay); //parent is W-boson | |
486 | else if (pPdg == 111) SetTagBit(tag,kMCPi0Decay); //Pi0 Dalitz decay | |
487 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); //Eta Dalitz decay | |
488 | else { //check the electron's ancestors for B/C contribution | |
489 | bAncestor = kFALSE; | |
490 | cAncestor = kFALSE; | |
491 | AliAODMCParticle * ancestors = (AliAODMCParticle*)mcparticles->At(label); //start from electron | |
492 | Int_t iAncestors = ancestors->GetMother(); //get its mother index | |
493 | if(iAncestors < 0) return tag; //no ancestor, shouldn't happen | |
494 | ancestors = (AliAODMCParticle *) mcparticles->At(iAncestors); | |
495 | Int_t aPdg = TMath::Abs(ancestors->GetPdgCode()); | |
496 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOrigin: Scanning the decay chain for bottom/charm generated electron"); | |
497 | while(1){//check electron's mother's pdg and its mother(s) pdgs | |
498 | if((499 < aPdg && aPdg < 600)||(4999 < aPdg && aPdg < 6000)) bAncestor = kTRUE; | |
499 | if((399 < aPdg && aPdg < 500)||(3999 < aPdg && aPdg < 5000)) cAncestor = kTRUE; | |
500 | if(bAncestor && cAncestor) break; | |
501 | iAncestors = ancestors->GetMother(); | |
502 | if(iAncestors < 0) break; | |
503 | ancestors = (AliAODMCParticle *) mcparticles->At(iAncestors); | |
504 | aPdg = ancestors->GetPdgCode(); | |
505 | }//searching for ancestors | |
506 | if(bAncestor && cAncestor) SetTagBit(tag,kMCEFromCFromB);//Decay chain has both B and C | |
507 | else if(bAncestor && !cAncestor) SetTagBit(tag,kMCEFromB);//Decay chain has only B | |
508 | else if(!bAncestor && cAncestor) SetTagBit(tag,kMCEFromC);//Decay chain has only C | |
509 | } | |
510 | //if it is not from any of the above, where is it from? | |
511 | if(fDebug > 0) printf("Electron from other origin: %s (pdg = %d)\n",parent->GetName(),pPdg); | |
512 | SetTagBit(tag,kMCOtherDecay); | |
513 | } | |
514 | else if (!mom->IsPrimary()) { //electron from GEANT | |
515 | ||
516 | //Rewind ancestry and check for electron with status == 1 | |
517 | //if we find one, we'll assume that this object is from an | |
518 | //electron but that it may have gone through some showering in | |
519 | //material before the detector | |
520 | ||
521 | //Not a double-counting problem because we are only accessing | |
522 | //these histories for MC labels connected to a reco object. | |
523 | //If you wanted to use this to sort through the kine stack | |
524 | //directly, might it be a problem? | |
525 | eleFromEvGen = kFALSE; | |
526 | bAncestor = kFALSE; | |
527 | cAncestor = kFALSE; | |
528 | ||
529 | AliAODMCParticle * ancestors = (AliAODMCParticle *) mcparticles->At(label); | |
530 | Int_t iAncestors = ancestors->GetMother(); | |
531 | if(iAncestors < 0) return tag; //no ancestor, shouldn't happen | |
532 | ancestors = (AliAODMCParticle *) mcparticles->At(iAncestors); //get electron mother | |
533 | Int_t aPdg = TMath::Abs(ancestors->GetPdgCode()); //get electron mother pdg | |
534 | if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Scanning the decay chain for bottom/charm electrons"); | |
535 | ||
536 | while(1){//check electron's mother's pdg and its mother(s) pdgs | |
537 | if(ancestors->IsPhysicalPrimary() && aPdg == 11) eleFromEvGen = kTRUE; | |
538 | if(eleFromEvGen && aPdg == 23) SetTagBit(tag,kMCZDecay); | |
539 | if(eleFromEvGen && aPdg == 24) SetTagBit(tag,kMCWDecay); | |
540 | if(eleFromEvGen && ((499 < aPdg && aPdg < 600)||(4999 < aPdg && aPdg < 6000))) bAncestor = kTRUE; | |
541 | if(eleFromEvGen && ((399 < aPdg && aPdg < 500)||(3999 < aPdg && aPdg < 5000))) cAncestor = kTRUE; | |
542 | if(bAncestor && cAncestor) break; | |
543 | iAncestors = ancestors->GetMother(); | |
544 | if(iAncestors <= 5) break; //don't go all the way back | |
545 | ancestors = (AliAODMCParticle *) mcparticles->At(iAncestors); | |
546 | aPdg = ancestors->GetPdgCode(); | |
547 | }//searching for ancestors | |
548 | if(bAncestor && cAncestor) SetTagBit(tag,kMCEFromCFromB);//Decay chain has both B and C | |
549 | else if(bAncestor && !cAncestor) SetTagBit(tag,kMCEFromB);//Decay chain has only B | |
550 | else if(!bAncestor && cAncestor) SetTagBit(tag,kMCEFromC);//Decay chain has only C | |
551 | if(pPdg == 22 || pPdg == 11 || pPdg == 2112 || pPdg == 211 || | |
552 | pPdg == 321 || pPdg == 2212 || pPdg == 130 || pPdg == 13) | |
553 | SetTagBit(tag,kMCConversion); | |
554 | else if (pPdg == 111) SetTagBit(tag,kMCPi0Decay); | |
555 | else if (pPdg == 221) SetTagBit(tag,kMCEtaDecay); | |
556 | else { | |
557 | //if it is not from any of the above, where is it from? | |
558 | if(pPdg > 10000) SetTagBit(tag,kMCUnknown); | |
559 | if(fDebug > 0) printf("Electron from other origin: %s (pdg = %d)\n",parent->GetName(),pPdg); | |
560 | SetTagBit(tag,kMCOtherDecay); | |
561 | } | |
562 | } //GEANT check | |
563 | }//electron check | |
564 | //cluster was made by something else | |
565 | else { | |
566 | if(fDebug > 0) printf("\tSetting kMCUnknown for cluster from %s (pdg = %d, Parent pdg = %d)\n",mom->GetName(),mPdg,pPdg); | |
567 | SetTagBit(tag,kMCUnknown); | |
568 | } | |
569 | }//Good label value | |
570 | else{ | |
571 | if(label < 0 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() *** bad label or no stack ***: label %d \n", label); | |
572 | if(label >= mcparticles->GetEntriesFast()) printf("AliMCAnalysisUtils::CheckOriginInAOD() *** large label ***: label %d, n tracks %d \n", label, mcparticles->GetEntriesFast()); | |
573 | SetTagBit(tag,kMCUnknown); | |
574 | }//Bad label | |
575 | ||
576 | return tag; | |
577 | ||
578 | } | |
579 | ||
580 | ||
581 | ||
582 | //_________________________________________________________________________ | |
583 | TList * AliMCAnalysisUtils::GetJets(AliCaloTrackReader * reader){ | |
584 | //Return list of jets (TParticles) and index of most likely parton that originated it. | |
585 | AliStack * stack = reader->GetStack(); | |
586 | Int_t iEvent = reader->GetEventNumber(); | |
587 | AliGenEventHeader * geh = reader->GetGenEventHeader(); | |
588 | if(fCurrentEvent!=iEvent){ | |
589 | fCurrentEvent = iEvent; | |
590 | fJetsList = new TList; | |
591 | Int_t nTriggerJets = 0; | |
592 | Float_t tmpjet[]={0,0,0,0}; | |
593 | ||
594 | //printf("Event %d %d\n",fCurrentEvent,iEvent); | |
595 | //Get outgoing partons | |
596 | if(stack->GetNtrack() < 8) return fJetsList; | |
597 | TParticle * parton1 = stack->Particle(6); | |
598 | TParticle * parton2 = stack->Particle(7); | |
599 | if(fDebug > 2){ | |
600 | printf("AliMCAnalysisUtils::GetJets() - parton 6 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
601 | parton1->GetName(),parton1->Pt(),parton1->Energy(),parton1->Phi()*TMath::RadToDeg(),parton1->Eta()); | |
602 | printf("AliMCAnalysisUtils::GetJets() - parton 7 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
603 | parton2->GetName(),parton2->Pt(),parton2->Energy(),parton2->Phi()*TMath::RadToDeg(),parton2->Eta()); | |
604 | } | |
605 | // //Trace the jet from the mother parton | |
606 | // Float_t pt = 0; | |
607 | // Float_t pt1 = 0; | |
608 | // Float_t pt2 = 0; | |
609 | // Float_t e = 0; | |
610 | // Float_t e1 = 0; | |
611 | // Float_t e2 = 0; | |
612 | // TParticle * tmptmp = new TParticle; | |
613 | // for(Int_t i = 0; i< stack->GetNprimary(); i++){ | |
614 | // tmptmp = stack->Particle(i); | |
615 | ||
616 | // if(tmptmp->GetStatusCode() == 1){ | |
617 | // pt = tmptmp->Pt(); | |
618 | // e = tmptmp->Energy(); | |
619 | // Int_t imom = tmptmp->GetFirstMother(); | |
620 | // Int_t imom1 = 0; | |
621 | // //printf("1st imom %d\n",imom); | |
622 | // while(imom > 5){ | |
623 | // imom1=imom; | |
624 | // tmptmp = stack->Particle(imom); | |
625 | // imom = tmptmp->GetFirstMother(); | |
626 | // //printf("imom %d \n",imom); | |
627 | // } | |
628 | // //printf("Last imom %d %d\n",imom1, imom); | |
629 | // if(imom1 == 6) { | |
630 | // pt1+=pt; | |
631 | // e1+=e; | |
632 | // } | |
633 | // else if (imom1 == 7){ | |
634 | // pt2+=pt; | |
635 | // e2+=e; } | |
636 | // }// status 1 | |
637 | ||
638 | // }// for | |
639 | ||
640 | // printf("JET 1, pt %2.2f, e %2.2f; JET 2, pt %2.2f, e %2.2f \n",pt1,e1,pt2,e2); | |
641 | ||
642 | //Get the jet, different way for different generator | |
643 | //PYTHIA | |
644 | if(fMCGenerator == "PYTHIA"){ | |
645 | TParticle * jet = new TParticle; | |
646 | AliGenPythiaEventHeader* pygeh= (AliGenPythiaEventHeader*) geh; | |
647 | nTriggerJets = pygeh->NTriggerJets(); | |
648 | if(fDebug > 1) | |
649 | printf("AliMCAnalysisUtils::GetJets() - PythiaEventHeader: Njets: %d\n",nTriggerJets); | |
650 | ||
651 | Int_t iparton = -1; | |
652 | for(Int_t i = 0; i< nTriggerJets; i++){ | |
653 | iparton=-1; | |
654 | pygeh->TriggerJet(i, tmpjet); | |
655 | jet = new TParticle(94, 21, -1, -1, -1, -1, tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3], 0,0,0,0); | |
656 | //Assign an outgoing parton as mother | |
657 | Float_t phidiff1 = TMath::Abs(jet->Phi()-parton1->Phi()); | |
658 | Float_t phidiff2 = TMath::Abs(jet->Phi()-parton2->Phi()); | |
659 | if(phidiff1 > phidiff2) jet->SetFirstMother(7); | |
660 | else jet->SetFirstMother(6); | |
661 | //jet->Print(); | |
662 | if(fDebug > 1) | |
663 | printf("AliMCAnalysisUtils::GetJets() - PYTHIA Jet %d: mother %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
664 | i, jet->GetFirstMother(),jet->Pt(),jet->Energy(),jet->Phi()*TMath::RadToDeg(),jet->Eta()); | |
665 | fJetsList->Add(jet); | |
666 | } | |
667 | }//Pythia triggered jets | |
668 | //HERWIG | |
669 | else if (fMCGenerator=="HERWIG"){ | |
670 | Int_t pdg = -1; | |
671 | //Check parton 1 | |
672 | TParticle * tmp = parton1; | |
673 | if(parton1->GetPdgCode()!=22){ | |
674 | while(pdg != 94){ | |
675 | if(tmp->GetFirstDaughter()==-1) return fJetsList; | |
676 | tmp = stack->Particle(tmp->GetFirstDaughter()); | |
677 | pdg = tmp->GetPdgCode(); | |
678 | }//while | |
679 | ||
680 | //Add found jet to list | |
681 | TParticle *jet1 = new TParticle(*tmp); | |
682 | jet1->SetFirstMother(6); | |
683 | fJetsList->Add(jet1); | |
684 | //printf("jet 1: first daughter %d, last daughter %d\n", tmp->GetFirstDaughter(), tmp->GetLastDaughter()); | |
685 | //tmp = stack->Particle(tmp->GetFirstDaughter()); | |
686 | //tmp->Print(); | |
687 | //jet1->Print(); | |
688 | if(fDebug > 1) | |
689 | printf("AliMCAnalysisUtils::GetJets() - HERWIG Jet 1: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
690 | jet1->GetFirstMother(),jet1->GetStatusCode(),jet1->Pt(),jet1->Energy(),jet1->Phi()*TMath::RadToDeg(),jet1->Eta()); | |
691 | }//not photon | |
692 | ||
693 | //Check parton 2 | |
694 | pdg = -1; | |
695 | tmp = parton2; | |
696 | Int_t i = -1; | |
697 | if(parton2->GetPdgCode()!=22){ | |
698 | while(pdg != 94){ | |
699 | if(tmp->GetFirstDaughter()==-1) return fJetsList; | |
700 | i = tmp->GetFirstDaughter(); | |
701 | tmp = stack->Particle(tmp->GetFirstDaughter()); | |
702 | pdg = tmp->GetPdgCode(); | |
703 | }//while | |
704 | //Add found jet to list | |
705 | TParticle *jet2 = new TParticle(*tmp); | |
706 | jet2->SetFirstMother(7); | |
707 | fJetsList->Add(jet2); | |
708 | //jet2->Print(); | |
709 | if(fDebug > 1) | |
710 | printf("AliMCAnalysisUtils::GetJets() - HERWIG Jet 2: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
711 | jet2->GetFirstMother(),jet2->GetStatusCode(),jet2->Pt(),jet2->Energy(),jet2->Phi()*TMath::RadToDeg(),jet2->Eta()); | |
712 | //Int_t first = tmp->GetFirstDaughter(); | |
713 | //Int_t last = tmp->GetLastDaughter(); | |
714 | //printf("jet 2: first daughter %d, last daughter %d, pdg %d\n",first, last, tmp->GetPdgCode()); | |
715 | // for(Int_t d = first ; d < last+1; d++){ | |
716 | // tmp = stack->Particle(d); | |
717 | // if(i == tmp->GetFirstMother()) | |
718 | // printf("Daughter n %d, Mother %d, name %s, status %d, pT %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n", | |
719 | // d,tmp->GetFirstMother(), tmp->GetName(), tmp->GetStatusCode(),tmp->Pt(),tmp->Energy(),tmp->Phi()*TMath::RadToDeg(),tmp->Eta()); | |
720 | // } | |
721 | //tmp->Print(); | |
722 | }//not photon | |
723 | }//Herwig generated jets | |
724 | } | |
725 | ||
726 | return fJetsList; | |
727 | } | |
728 | ||
729 | ||
730 | //________________________________________________________________ | |
731 | void AliMCAnalysisUtils::Print(const Option_t * opt) const | |
732 | { | |
733 | //Print some relevant parameters set for the analysis | |
734 | ||
735 | if(! opt) | |
736 | return; | |
737 | ||
738 | printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ; | |
739 | ||
740 | printf("Debug level = %d\n",fDebug); | |
741 | printf("MC Generator = %s\n",fMCGenerator.Data()); | |
742 | printf(" \n"); | |
743 | ||
744 | } | |
745 | ||
746 |