1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 //_________________________________________________________________________
17 // Class for analysis utils for MC data
18 // stored in stack or event header.
20 // - method to check the origin of a given track/cluster
21 // - method to obtain the generated jets
23 //*-- Author: Gustavo Conesa (LNF-INFN)
24 //////////////////////////////////////////////////////////////////////////////
27 // --- ROOT system ---
30 #include "TParticle.h"
31 #include "TDatabasePDG.h"
34 //---- ANALYSIS system ----
35 #include "AliMCAnalysisUtils.h"
36 #include "AliCaloTrackReader.h"
38 #include "AliGenPythiaEventHeader.h"
39 #include "AliAODMCParticle.h"
41 ClassImp(AliMCAnalysisUtils)
43 //________________________________________
44 AliMCAnalysisUtils::AliMCAnalysisUtils() :
49 fMCGenerator("PYTHIA")
54 //_______________________________________
55 AliMCAnalysisUtils::~AliMCAnalysisUtils()
57 // Remove all pointers.
65 //_____________________________________________________________________________________________
66 Int_t AliMCAnalysisUtils::CheckCommonAncestor(const Int_t index1, const Int_t index2,
67 const AliCaloTrackReader* reader,
68 Int_t & ancPDG, Int_t & ancStatus,
69 TLorentzVector & momentum, TVector3 & prodVertex)
71 //Check the first common ancestor of 2 clusters, given the most likely labels of the primaries generating such clusters.
79 if(label1[0]==label2[0])
81 //printf("AliMCAnalysisUtils::CheckCommonAncestor() - Already the same label: %d\n",label1[0]);
87 if(reader->ReadAODMCParticles())
89 TClonesArray * mcparticles = reader->GetAODMCParticles();
91 Int_t label=label1[0];
92 if(label < 0) return -1;
94 while(label > -1 && counter1 < 99)
97 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
100 label = mom->GetMother() ;
101 label1[counter1]=label;
103 //printf("\t counter %d, label %d\n", counter1,label);
106 //printf("Org label2=%d,\n",label2[0]);
108 if(label < 0) return -1;
110 while(label > -1 && counter2 < 99)
113 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
116 label = mom->GetMother() ;
117 label2[counter2]=label;
119 //printf("\t counter %d, label %d\n", counter2,label);
123 { //Kine stack from ESDs
124 AliStack * stack = reader->GetStack();
126 Int_t label=label1[0];
127 while(label > -1 && counter1 < 99)
130 TParticle * mom = stack->Particle(label);
133 label = mom->GetFirstMother() ;
134 label1[counter1]=label;
136 //printf("\t counter %d, label %d\n", counter1,label);
139 //printf("Org label2=%d,\n",label2[0]);
142 while(label > -1 && counter2 < 99)
145 TParticle * mom = stack->Particle(label);
148 label = mom->GetFirstMother() ;
149 label2[counter2]=label;
151 //printf("\t counter %d, label %d\n", counter2,label);
153 }// Kine stack from ESDs
154 }//First labels not the same
156 if((counter1==99 || counter2==99) && fDebug >=0)
157 printf("AliMCAnalysisUtils::CheckCommonAncestor() - Genealogy too large c1: %d, c2= %d\n", counter1, counter2);
158 //printf("CheckAncestor:\n");
160 Int_t commonparents = 0;
162 //printf("counters %d %d \n",counter1, counter2);
163 for (Int_t c1 = 0; c1 < counter1; c1++)
165 for (Int_t c2 = 0; c2 < counter2; c2++)
167 if(label1[c1]==label2[c2] && label1[c1]>-1)
169 ancLabel = label1[c1];
172 if(reader->ReadAODMCParticles())
174 AliAODMCParticle * mom = (AliAODMCParticle *) reader->GetAODMCParticles()->At(label1[c1]);
178 ancPDG = mom->GetPdgCode();
179 ancStatus = mom->GetStatus();
180 momentum.SetPxPyPzE(mom->Px(),mom->Py(),mom->Pz(),mom->E());
181 prodVertex.SetXYZ(mom->Xv(),mom->Yv(),mom->Zv());
186 TParticle * mom = (reader->GetStack())->Particle(label1[c1]);
190 ancPDG = mom->GetPdgCode();
191 ancStatus = mom->GetStatusCode();
192 mom->Momentum(momentum);
193 prodVertex.SetXYZ(mom->Vx(),mom->Vy(),mom->Vz());
197 //First ancestor found, end the loops
201 }//second cluster loop
202 }//first cluster loop
208 momentum.SetXYZT(0,0,0,0);
209 prodVertex.SetXYZ(-10,-10,-10);
215 //_____________________________________________________________________
216 Int_t AliMCAnalysisUtils::CheckOrigin(const Int_t * label,
218 const AliCaloTrackReader* reader)
220 //Play with the montecarlo particles if available
224 printf("AliMCAnalysisUtils::CheckOrigin(nlabel<=0) - No MC labels available, please check!!!\n");
228 //Select where the information is, ESD-galice stack or AOD mcparticles branch
229 if(reader->ReadStack()){
230 tag = CheckOriginInStack(label, nlabels, reader->GetStack());
232 else if(reader->ReadAODMCParticles()){
233 tag = CheckOriginInAOD(label, nlabels, reader->GetAODMCParticles());
239 //_____________________________________________________________________
240 Int_t AliMCAnalysisUtils::CheckOrigin(const Int_t label,
241 const AliCaloTrackReader* reader)
243 //Play with the montecarlo particles if available
247 printf("AliMCAnalysisUtils::CheckOrigin(label<0) - No MC labels available, please check!!!\n");
251 Int_t labels[]={label};
253 //Select where the information is, ESD-galice stack or AOD mcparticles branch
254 if(reader->ReadStack()){
255 tag = CheckOriginInStack(labels, 1,reader->GetStack());
257 else if(reader->ReadAODMCParticles()){
258 tag = CheckOriginInAOD(labels, 1,reader->GetAODMCParticles());
264 //_________________________________________________________________
265 Int_t AliMCAnalysisUtils::CheckOriginInStack(const Int_t *labels,
269 // Play with the MC stack if available. Tag particles depending on their origin.
270 // Do same things as in CheckOriginInAOD but different input.
272 //generally speaking, label is the MC label of a reconstructed
273 //entity (track, cluster, etc) for which we want to know something
274 //about its heritage, but one can also use it directly with stack
275 //particles not connected to reconstructed entities
280 printf("AliMCAnalysisUtils::CheckOriginInStack() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
285 Int_t label=labels[0];//Most significant particle contributing to the cluster
287 if(label >= 0 && label < stack->GetNtrack())
289 //MC particle of interest is the "mom" of the entity
290 TParticle * mom = stack->Particle(label);
292 Int_t mPdgSign = mom->GetPdgCode();
293 Int_t mPdg = TMath::Abs(mPdgSign);
294 Int_t mStatus = mom->GetStatusCode() ;
295 Int_t iParent = mom->GetFirstMother() ;
297 if(fDebug > 0 && label < 8 && fMCGenerator!="") printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent);
299 //GrandParent of the entity
300 TParticle * parent = NULL;
305 parent = stack->Particle(iParent);
309 pPdg = TMath::Abs(parent->GetPdgCode());
310 pStatus = parent->GetStatusCode();
313 else if(fDebug > 0 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Parent with label %d\n",iParent);
317 printf("AliMCAnalysisUtils::CheckOriginInStack() - Cluster most contributing mother and its parent: \n");
318 printf("\t Mother label %d, pdg %d, status %d\n",iMom, mPdg, mStatus);
319 printf("\t Parent label %d, pdg %d, status %d\n",iParent, pPdg, pStatus);
322 //Check if "mother" of entity is converted, if not, get the first non converted mother
323 if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && mStatus == 0)
325 SetTagBit(tag,kMCConversion);
327 //Check if the mother is photon or electron with status not stable
328 while ((pPdg == 22 || pPdg == 11) && mStatus != 1)
331 iMom = mom->GetFirstMother();
332 mom = stack->Particle(iMom);
333 mPdgSign = mom->GetPdgCode();
334 mPdg = TMath::Abs(mPdgSign);
335 mStatus = mom->GetStatusCode() ;
336 iParent = mom->GetFirstMother() ;
338 if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent);
343 parent = stack->Particle(iParent);
346 pPdg = TMath::Abs(parent->GetPdgCode());
347 pStatus = parent->GetStatusCode();
350 else {// in case of gun/box simulations
359 printf("AliMCAnalysisUtils::CheckOriginInStack() - Converted photon/electron: \n");
360 printf("\t Mother label %d, pdg %d, status %d\n",iMom, mPdg, mStatus);
361 printf("\t Parent label %d, pdg %d, status %d\n",iParent, pPdg, pStatus);
364 }//mother and parent are electron or photon and have status 0
365 else if((mPdg == 22 || mPdg == 11) && mStatus == 0)
367 //Still a conversion but only one electron/photon generated. Just from hadrons but not decays.
368 if(pPdg == 2112 || pPdg == 211 || pPdg == 321 ||
369 pPdg == 2212 || pPdg == 130 || pPdg == 13 )
371 SetTagBit(tag,kMCConversion);
372 iMom = mom->GetFirstMother();
373 mom = stack->Particle(iMom);
374 mPdgSign = mom->GetPdgCode();
375 mPdg = TMath::Abs(mPdgSign);
379 printf("AliMCAnalysisUtils::CheckOriginInStack() - Converted hadron: \n");
380 printf("\t Mother label %d, pdg %d, status %d\n",iMom, mPdg, mStatus);
384 //Comment for the next lines, we do not check the parent of the hadron for the moment.
385 //iParent = mom->GetFirstMother() ;
386 //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent);
390 // parent = stack->Particle(iParent);
391 // pPdg = TMath::Abs(parent->GetPdgCode());
394 // conversion into electrons/photons checked
396 //first check for typical charged particles
397 if (mPdg == 13) SetTagBit(tag,kMCMuon);
398 else if(mPdg == 211) SetTagBit(tag,kMCPion);
399 else if(mPdg == 321) SetTagBit(tag,kMCKaon);
400 else if(mPdgSign == 2212) SetTagBit(tag,kMCProton);
401 else if(mPdgSign == -2212) SetTagBit(tag,kMCAntiProton);
402 else if(mPdgSign == 2112) SetTagBit(tag,kMCNeutron);
403 else if(mPdgSign == -2112) SetTagBit(tag,kMCAntiNeutron);
405 //check for pi0 and eta (shouldn't happen unless their decays were turned off)
409 SetTagBit(tag,kMCPi0Decay);
412 printf("AliMCAnalysisUtils::CheckOriginInStack() - First mother is directly pi0, not decayed by generator \n");
414 CheckOverlapped2GammaDecay(labels,nlabels, iMom, stack, tag); //set to kMCPi0 if 2 gammas in same cluster
418 SetTagBit(tag,kMCEtaDecay);
421 printf("AliMCAnalysisUtils::CheckOriginInStack() - First mother is directly eta, not decayed by generator \n");
423 CheckOverlapped2GammaDecay(labels,nlabels, iMom, stack, tag); //set to kMCEta if 2 gammas in same cluster
428 SetTagBit(tag,kMCPhoton);
432 SetTagBit(tag,kMCPi0Decay);
434 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - PYTHIA pi0 decay photon, parent pi0 with status 11 \n");
436 CheckOverlapped2GammaDecay(labels,nlabels, iParent, stack, tag); //set to kMCPi0 if 2 gammas in same cluster
438 else if (pPdg == 221)
440 SetTagBit(tag, kMCEtaDecay);
442 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - PYTHIA eta decay photon, parent pi0 with status 11 \n");
444 CheckOverlapped2GammaDecay(labels,nlabels, iParent, stack, tag);//set to kMCEta if 2 gammas in same cluster
446 else if(mStatus == 1)
447 { //undecayed particle
448 if(fMCGenerator == "PYTHIA")
450 if(iParent < 8 && iParent > 5)
452 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
453 else SetTagBit(tag,kMCFragmentation);
455 else if(iParent <= 5)
457 SetTagBit(tag, kMCISR); //Initial state radiation
459 else SetTagBit(tag,kMCUnknown);
462 else if(fMCGenerator == "HERWIG")
470 if(parent->GetFirstMother()<=5) break;
471 iParent = parent->GetFirstMother();
472 parent=stack->Particle(iParent);
473 pStatus= parent->GetStatusCode();
474 pPdg = TMath::Abs(parent->GetPdgCode());
476 }//Look for the parton
478 if(iParent < 8 && iParent > 5)
480 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
481 else SetTagBit(tag,kMCFragmentation);
483 else SetTagBit(tag,kMCISR);//Initial state radiation
485 else SetTagBit(tag,kMCUnknown);
488 else SetTagBit(tag,kMCOtherDecay);
492 //Electron check. Where did that electron come from?
493 else if(mPdg == 11){ //electron
494 if(pPdg == 11 && parent)
496 Int_t iGrandma = parent->GetFirstMother();
499 TParticle* gma = (TParticle*)stack->Particle(iGrandma); //get mother
500 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
502 if (gPdg == 23) { SetTagBit(tag,kMCZDecay); } //parent is Z-boson
503 else if (gPdg == 24) { SetTagBit(tag,kMCWDecay); } //parent is W-boson
507 SetTagBit(tag,kMCElectron);
509 if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInStack() - Checking ancestors of electrons\n");
511 if (pPdg == 111) { SetTagBit(tag,kMCPi0Decay); } //Pi0 Dalitz decay
512 else if (pPdg == 221) { SetTagBit(tag,kMCEtaDecay); } //Eta Dalitz decay
513 else if((499 < pPdg && pPdg < 600)||(4999 < pPdg && pPdg < 6000)) { SetTagBit(tag,kMCEFromB); } //b-->e decay
514 else if((399 < pPdg && pPdg < 500)||(3999 < pPdg && pPdg < 5000)) { //check charm decay
517 Int_t iGrandma = parent->GetFirstMother();
520 TParticle* gma = (TParticle*)stack->Particle(iGrandma); //get mother of charm
521 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
522 if((499 < gPdg && gPdg < 600)||(4999 < gPdg && gPdg < 6000)) SetTagBit(tag,kMCEFromCFromB); //b-->c-->e
523 else SetTagBit(tag,kMCEFromC); //c-->e
525 else SetTagBit(tag,kMCEFromC); //c-->e
530 //if it is not from any of the above, where is it from?
531 if(pPdg > 10000) SetTagBit(tag,kMCUnknown);
533 else SetTagBit(tag,kMCOtherDecay);
535 if(fDebug > 0 && parent) printf("AliMCAnalysisUtils::CheckOriginInStack() - Status %d Electron from other origin: %s (pPdg = %d) %s (mpdg = %d)\n",mStatus,parent->GetName(),pPdg,mom->GetName(),mPdg);
538 //Cluster was made by something else
542 printf("AliMCAnalysisUtils::CheckOriginInStack() - \tSetting kMCUnknown for cluster from %s (pdg = %d, Parent pdg = %d)\n",
543 mom->GetName(),mPdg,pPdg);
545 SetTagBit(tag,kMCUnknown);
550 if(label < 0 && (fDebug >= 0))
551 printf("AliMCAnalysisUtils::CheckOriginInStack() *** bad label or no stack ***: label %d \n", label);
553 if(label >= stack->GetNtrack() && (fDebug >= 0))
554 printf("AliMCAnalysisUtils::CheckOriginInStack() *** large label ***: label %d, n tracks %d \n", label, stack->GetNtrack());
556 SetTagBit(tag,kMCUnknown);
564 //_________________________________________________________________________
565 Int_t AliMCAnalysisUtils::CheckOriginInAOD(const Int_t *labels,
567 const TClonesArray *mcparticles)
569 // Play with the MCParticles in AOD if available. Tag particles depending on their origin.
570 // Do same things as in CheckOriginInStack but different input.
574 printf("AliMCAnalysisUtils::CheckOriginInAOD() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
579 Int_t label=labels[0];//Most significant particle contributing to the cluster
581 Int_t nprimaries = mcparticles->GetEntriesFast();
582 if(label >= 0 && label < nprimaries)
585 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
587 Int_t mPdgSign = mom->GetPdgCode();
588 Int_t mPdg = TMath::Abs(mPdgSign);
589 Int_t iParent = mom->GetMother() ;
591 if(fDebug > 0 && label < 8 && fMCGenerator!="") printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent);
594 AliAODMCParticle * parent = NULL ;
598 parent = (AliAODMCParticle *) mcparticles->At(iParent);
599 pPdg = TMath::Abs(parent->GetPdgCode());
601 else if(fDebug > 0 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Parent with label %d\n",iParent);
605 printf("AliMCAnalysisUtils::CheckOriginInAOD() - Cluster most contributing mother and its parent: \n");
607 printf("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d\n",
608 iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary());
611 printf("\t Parent label %d, pdg %d, Primary? %d, Physical Primary? %d\n",
612 iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary());
615 //Check if mother is converted, if not, get the first non converted mother
616 if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && !mom->IsPrimary())
618 SetTagBit(tag,kMCConversion);
620 //Check if the mother is photon or electron with status not stable
621 while ((pPdg == 22 || pPdg == 11) && !mom->IsPhysicalPrimary())
624 iMom = mom->GetMother();
625 mom = (AliAODMCParticle *) mcparticles->At(iMom);
626 mPdgSign = mom->GetPdgCode();
627 mPdg = TMath::Abs(mPdgSign);
628 iParent = mom->GetMother() ;
629 if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent);
632 if(iParent >= 0 && parent)
634 parent = (AliAODMCParticle *) mcparticles->At(iParent);
635 pPdg = TMath::Abs(parent->GetPdgCode());
637 // printf("\t While Mother label %d, pdg %d, Primary? %d, Physical Primary? %d\n",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary());
638 // printf("\t While Parent label %d, pdg %d, Primary? %d, Physical Primary? %d\n",iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary());
644 printf("AliMCAnalysisUtils::CheckOriginInAOD() - Converted photon/electron : \n");
646 printf("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d\n",
647 iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary());
650 printf("\t Parent label %d, pdg %d, Primary? %d, Physical Primary? %d\n",
651 iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary());
654 }//mother and parent are electron or photon and have status 0 and parent is photon or electron
655 else if((mPdg == 22 || mPdg == 11) && !mom->IsPrimary())
657 //Still a conversion but only one electron/photon generated. Just from hadrons
658 if(pPdg == 2112 || pPdg == 211 || pPdg == 321 ||
659 pPdg == 2212 || pPdg == 130 || pPdg == 13 )
661 SetTagBit(tag,kMCConversion);
662 iMom = mom->GetMother();
663 mom = (AliAODMCParticle *) mcparticles->At(iMom);
664 mPdgSign = mom->GetPdgCode();
665 mPdg = TMath::Abs(mPdgSign);
669 printf("AliMCAnalysisUtils::CheckOriginInAOD() - Converted hadron : \n");
670 printf("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d\n",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary());
674 //Comment for next lines, we do not check the parent of the hadron for the moment.
675 //iParent = mom->GetMother() ;
676 //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent);
680 // parent = (AliAODMCParticle *) mcparticles->At(iParent);
681 // pPdg = TMath::Abs(parent->GetPdgCode());
685 //printf("Final mother mPDG %d\n",mPdg);
687 // conversion into electrons/photons checked
689 //first check for typical charged particles
690 if (mPdg == 13) SetTagBit(tag,kMCMuon);
691 else if(mPdg == 211) SetTagBit(tag,kMCPion);
692 else if(mPdg == 321) SetTagBit(tag,kMCKaon);
693 else if(mPdgSign == 2212) SetTagBit(tag,kMCProton);
694 else if(mPdgSign == 2112) SetTagBit(tag,kMCNeutron);
695 else if(mPdgSign == -2212) SetTagBit(tag,kMCAntiProton);
696 else if(mPdgSign == -2112) SetTagBit(tag,kMCAntiNeutron);
698 //check for pi0 and eta (shouldn't happen unless their decays were turned off)
701 SetTagBit(tag,kMCPi0Decay);
703 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - First mother is directly pi0, not decayed by generator \n");
705 CheckOverlapped2GammaDecay(labels,nlabels, iMom, mcparticles, tag); //set to kMCPi0 if 2 gammas in same cluster
709 SetTagBit(tag,kMCEtaDecay);
711 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - First mother is directly eta, not decayed by generator \n");
713 CheckOverlapped2GammaDecay(labels,nlabels, iMom, mcparticles, tag); //set to kMCEta if 2 gammas in same cluster
718 SetTagBit(tag,kMCPhoton);
722 SetTagBit(tag,kMCPi0Decay);
724 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Generator pi0 decay photon \n");
726 CheckOverlapped2GammaDecay(labels,nlabels, iParent, mcparticles, tag); //set to kMCPi0 if 2 gammas in same cluster
728 else if (pPdg == 221)
730 SetTagBit(tag, kMCEtaDecay);
732 if(fDebug > 2 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Generator eta decay photon \n");
734 CheckOverlapped2GammaDecay(labels,nlabels, iParent, mcparticles, tag); //set to kMCEta if 2 gammas in same cluster
736 else if(mom->IsPhysicalPrimary() && (fMCGenerator=="PYTHIA" || fMCGenerator=="HERWIG")) //undecayed particle
738 if(iParent < 8 && iParent > 5 )
740 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
741 else SetTagBit(tag,kMCFragmentation);
743 else if(iParent <= 5 && (fMCGenerator=="PYTHIA" || fMCGenerator=="HERWIG"))
745 SetTagBit(tag, kMCISR); //Initial state radiation
747 else SetTagBit(tag,kMCUnknown);
749 else SetTagBit(tag,kMCOtherDecay);
753 //Electron check. Where did that electron come from?
756 if(pPdg == 11 && parent)
758 Int_t iGrandma = parent->GetMother();
761 AliAODMCParticle* gma = (AliAODMCParticle*)mcparticles->At(iGrandma);
762 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
764 if (gPdg == 23) { SetTagBit(tag,kMCZDecay); } //parent is Z-boson
765 else if (gPdg == 24) { SetTagBit(tag,kMCWDecay); } //parent is W-boson
769 SetTagBit(tag,kMCElectron);
771 if (fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Checking ancestors of electrons");
772 if (pPdg == 111) { SetTagBit(tag,kMCPi0Decay); } //Pi0 Dalitz decay
773 else if (pPdg == 221) { SetTagBit(tag,kMCEtaDecay); } //Eta Dalitz decay
774 else if((499 < pPdg && pPdg < 600)||(4999 < pPdg && pPdg < 6000)) { SetTagBit(tag,kMCEFromB);} //b-hadron decay
775 else if((399 < pPdg && pPdg < 500)||(3999 < pPdg && pPdg < 5000))
776 { //c-hadron decay check
779 Int_t iGrandma = parent->GetMother();
782 AliAODMCParticle* gma = (AliAODMCParticle*)mcparticles->At(iGrandma); //charm's mother
783 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
784 if((499 < gPdg && gPdg < 600)||(4999 < gPdg && gPdg < 6000)) SetTagBit(tag,kMCEFromCFromB); //b-->c-->e decay
785 else SetTagBit(tag,kMCEFromC); //c-hadron decay
787 else SetTagBit(tag,kMCEFromC); //c-hadron decay
790 { //prompt or other decay
791 TParticlePDG* foo = TDatabasePDG::Instance()->GetParticle(pPdg);
792 TParticlePDG* foo1 = TDatabasePDG::Instance()->GetParticle(mPdg);
794 if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Electron from other origin: %s (pPdg = %d) %s (mPdg = %d)\n",
795 foo->GetName(), pPdg,foo1->GetName(),mPdg);
797 if(pPdg > 10000) SetTagBit(tag,kMCUnknown);
798 else SetTagBit(tag,kMCOtherDecay);
801 //cluster was made by something else
804 if(fDebug > 0) printf("AliMCAnalysisUtils::CheckOriginInAOD() - \tSetting kMCUnknown for cluster with pdg = %d, Parent pdg = %d\n",
806 SetTagBit(tag,kMCUnknown);
811 if(label < 0 && (fDebug >= 0) )
812 printf("AliMCAnalysisUtils::CheckOriginInAOD() *** bad label or no mcparticles ***: label %d \n", label);
814 if(label >= mcparticles->GetEntriesFast() && (fDebug >= 0) )
815 printf("AliMCAnalysisUtils::CheckOriginInAOD() *** large label ***: label %d, n tracks %d \n", label, mcparticles->GetEntriesFast());
817 SetTagBit(tag,kMCUnknown);
825 //_________________________________________________________________________
826 void AliMCAnalysisUtils::CheckOverlapped2GammaDecay(const Int_t *labels,
828 const Int_t mesonIndex,
832 //Check if cluster is formed from the contribution of 2 decay photons from pi0 or eta. Input in stack
834 if(labels[0] < 0 || labels[0] > stack->GetNtrack() || nlabels <= 1) {
835 if(fDebug > 2) printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Exit : label[0] %d, n primaries %d, nlabels %d \n",
836 labels[0],stack->GetNtrack(), nlabels);
840 TParticle * meson = stack->Particle(mesonIndex);
841 Int_t mesonPdg = meson->GetPdgCode();
842 if(mesonPdg!=111 && mesonPdg!=221)
844 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Wrong pi0/eta PDG : %d \n",mesonPdg);
848 if(fDebug > 2) printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - %s, label %d\n",meson->GetName(), mesonIndex);
850 //Check if meson decayed into 2 daughters or if both were kept.
851 if(meson->GetNDaughters() != 2)
854 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Not overalapped. Number of daughters is %d, not 2 \n",meson->GetNDaughters());
859 Int_t iPhoton0 = meson->GetDaughter(0);
860 Int_t iPhoton1 = meson->GetDaughter(1);
861 TParticle *photon0 = stack->Particle(iPhoton0);
862 TParticle *photon1 = stack->Particle(iPhoton1);
864 //Check if both daughters are photons
865 if(photon0->GetPdgCode() != 22 || photon1->GetPdgCode()!=22)
868 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Not overalapped. PDG: daughter 1 = %d, of daughter 2 = %d \n",photon0->GetPdgCode(),photon1->GetPdgCode());
873 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Daughter labels : photon0 = %d, photon1 = %d \n",iPhoton0,iPhoton1);
875 //Check if both photons contribute to the cluster
876 Bool_t okPhoton0 = kFALSE;
877 Bool_t okPhoton1 = kFALSE;
879 if(fDebug > 3) printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Labels loop:\n");
881 Bool_t conversion = kFALSE;
883 for(Int_t i = 0; i < nlabels; i++)
885 if(fDebug > 3) printf("\t at begin:label %d/%d: %d, ok? photon1 %d, photon2 %d\n", i+1, nlabels, labels[i], okPhoton0, okPhoton1);
887 //If we already found both, break the loop
888 if(okPhoton0 && okPhoton1) break;
890 Int_t index = labels[i];
891 if (iPhoton0 == index)
896 else if (iPhoton1 == index)
902 //Trace back the mother in case it was a conversion
904 if(index >= stack->GetNtrack())
906 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) Particle index %d larger than size of list %d !!\n",
907 index,stack->GetNtrack());
911 TParticle * daught = stack->Particle(index);
912 Int_t tmpindex = daught->GetFirstMother();
913 if(fDebug > 3) printf("\t Conversion? : mother %d\n",tmpindex);
916 //MC particle of interest is the mother
917 if(fDebug > 3) printf("\t \t parent index %d\n",tmpindex);
918 daught = stack->Particle(tmpindex);
919 if (iPhoton0 == tmpindex)
925 else if (iPhoton1 == tmpindex)
932 tmpindex = daught->GetFirstMother();
934 }//While to check if pi0/eta daughter was one of these contributors to the cluster
936 if(i == 0 && (!okPhoton0 && !okPhoton1) && fDebug>=0)
937 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Something happens, first label should be from a photon decay!\n");
939 }//loop on list of labels
941 //If both photons contribute tag as the corresponding meson.
942 if(okPhoton0 && okPhoton1)
945 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - %s OVERLAPPED DECAY \n", meson->GetName());
947 if(!CheckTagBit(tag,kMCConversion) && conversion) SetTagBit(tag,kMCConversion) ;
949 if(mesonPdg == 111) SetTagBit(tag,kMCPi0);
950 else SetTagBit(tag,kMCEta);
955 //__________________________________________________________________________________
956 void AliMCAnalysisUtils::CheckOverlapped2GammaDecay(const Int_t *labels,
958 const Int_t mesonIndex,
959 const TClonesArray *mcparticles,
962 //Check if cluster is formed from the contribution of 2 decay photons from pi0 or eta. Input in AODMCParticles
964 if(labels[0] < 0 || labels[0] > mcparticles->GetEntriesFast() || nlabels <= 1)
967 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Exit : label[0] %d, n primaries %d, nlabels %d \n",
968 labels[0],mcparticles->GetEntriesFast(), nlabels);
972 AliAODMCParticle * meson = (AliAODMCParticle *) mcparticles->At(mesonIndex);
973 Int_t mesonPdg = meson->GetPdgCode();
974 if(mesonPdg != 111 && mesonPdg != 221)
976 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Wrong pi0/eta PDG : %d \n",mesonPdg);
980 if(fDebug > 2) printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - pdg %d, label %d, ndaughters %d\n", mesonPdg, mesonIndex, meson->GetNDaughters());
984 if(meson->GetNDaughters() != 2)
987 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(ESD) - Not overalapped. Number of daughters is %d, not 2 \n",meson->GetNDaughters());
991 Int_t iPhoton0 = meson->GetDaughter(0);
992 Int_t iPhoton1 = meson->GetDaughter(1);
993 //if((iPhoton0 == -1) || (iPhoton1 == -1)){
995 // printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Exit : Not overlapped. At least a daughter do not exists : d1 %d, d2 %d \n", iPhoton0, iPhoton1);
998 AliAODMCParticle *photon0 = (AliAODMCParticle *) mcparticles->At(iPhoton0);
999 AliAODMCParticle *photon1 = (AliAODMCParticle *) mcparticles->At(iPhoton1);
1001 //Check if both daughters are photons
1002 if(photon0->GetPdgCode() != 22 && photon1->GetPdgCode()!=22)
1004 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Not overlapped. PDG: daughter 1 = %d, of daughter 2 = %d \n",photon0->GetPdgCode(),photon1->GetPdgCode());
1009 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Daughter labels : photon0 = %d, photon1 = %d \n",iPhoton0,iPhoton1);
1011 //Check if both photons contribute to the cluster
1012 Bool_t okPhoton0 = kFALSE;
1013 Bool_t okPhoton1 = kFALSE;
1016 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Labels loop:\n");
1018 Bool_t conversion = kFALSE;
1020 for(Int_t i = 0; i < nlabels; i++)
1023 printf("\t label %d/%d: %d, ok? %d, %d\n", i, nlabels, labels[i], okPhoton0, okPhoton1);
1025 if(labels[i]<0) continue;
1027 //If we already found both, break the loop
1028 if(okPhoton0 && okPhoton1) break;
1030 Int_t index = labels[i];
1031 if (iPhoton0 == index)
1036 else if (iPhoton1 == index)
1042 //Trace back the mother in case it was a conversion
1044 if(index >= mcparticles->GetEntriesFast())
1046 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) Particle index %d larger than size of list %d !!\n",index,mcparticles->GetEntriesFast());
1050 AliAODMCParticle * daught = (AliAODMCParticle*) mcparticles->At(index);
1051 Int_t tmpindex = daught->GetMother();
1053 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Conversion? : mother %d\n",tmpindex);
1057 //MC particle of interest is the mother
1059 printf("\t parent index %d\n",tmpindex);
1060 daught = (AliAODMCParticle*) mcparticles->At(tmpindex);
1061 //printf("tmpindex %d\n",tmpindex);
1062 if (iPhoton0 == tmpindex)
1068 else if (iPhoton1 == tmpindex)
1075 tmpindex = daught->GetMother();
1077 }//While to check if pi0/eta daughter was one of these contributors to the cluster
1079 if(i == 0 && (!okPhoton0 && !okPhoton1) && fDebug>=0 )
1080 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Something happens, first label should be from a photon decay!\n");
1082 }//loop on list of labels
1084 //If both photons contribute tag as the corresponding meson.
1085 if(okPhoton0 && okPhoton1)
1088 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - %s OVERLAPPED DECAY \n",
1089 (TDatabasePDG::Instance()->GetParticle(mesonPdg))->GetName());
1091 if(!CheckTagBit(tag,kMCConversion) && conversion)
1094 printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) Second decay photon produced a conversion \n");
1095 SetTagBit(tag,kMCConversion) ;
1098 if(mesonPdg == 111) SetTagBit(tag,kMCPi0);
1099 else SetTagBit(tag,kMCEta);
1104 //_________________________________________________________________________
1105 TList * AliMCAnalysisUtils::GetJets(const AliCaloTrackReader * reader)
1107 //Return list of jets (TParticles) and index of most likely parton that originated it.
1108 AliStack * stack = reader->GetStack();
1109 Int_t iEvent = reader->GetEventNumber();
1110 AliGenEventHeader * geh = reader->GetGenEventHeader();
1111 if(fCurrentEvent!=iEvent){
1112 fCurrentEvent = iEvent;
1113 fJetsList = new TList;
1114 Int_t nTriggerJets = 0;
1115 Float_t tmpjet[]={0,0,0,0};
1117 //printf("Event %d %d\n",fCurrentEvent,iEvent);
1118 //Get outgoing partons
1119 if(stack->GetNtrack() < 8) return fJetsList;
1120 TParticle * parton1 = stack->Particle(6);
1121 TParticle * parton2 = stack->Particle(7);
1123 printf("AliMCAnalysisUtils::GetJets() - parton 6 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1124 parton1->GetName(),parton1->Pt(),parton1->Energy(),parton1->Phi()*TMath::RadToDeg(),parton1->Eta());
1125 printf("AliMCAnalysisUtils::GetJets() - parton 7 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1126 parton2->GetName(),parton2->Pt(),parton2->Energy(),parton2->Phi()*TMath::RadToDeg(),parton2->Eta());
1128 // //Trace the jet from the mother parton
1135 // TParticle * tmptmp = new TParticle;
1136 // for(Int_t i = 0; i< stack->GetNprimary(); i++){
1137 // tmptmp = stack->Particle(i);
1139 // if(tmptmp->GetStatusCode() == 1){
1140 // pt = tmptmp->Pt();
1141 // e = tmptmp->Energy();
1142 // Int_t imom = tmptmp->GetFirstMother();
1144 // //printf("1st imom %d\n",imom);
1147 // tmptmp = stack->Particle(imom);
1148 // imom = tmptmp->GetFirstMother();
1149 // //printf("imom %d \n",imom);
1151 // //printf("Last imom %d %d\n",imom1, imom);
1156 // else if (imom1 == 7){
1163 // printf("JET 1, pt %2.2f, e %2.2f; JET 2, pt %2.2f, e %2.2f \n",pt1,e1,pt2,e2);
1165 //Get the jet, different way for different generator
1167 if(fMCGenerator == "PYTHIA")
1169 TParticle * jet = 0x0;
1170 AliGenPythiaEventHeader* pygeh= (AliGenPythiaEventHeader*) geh;
1171 nTriggerJets = pygeh->NTriggerJets();
1173 printf("AliMCAnalysisUtils::GetJets() - PythiaEventHeader: Njets: %d\n",nTriggerJets);
1176 for(Int_t i = 0; i< nTriggerJets; i++){
1178 pygeh->TriggerJet(i, tmpjet);
1179 jet = new TParticle(94, 21, -1, -1, -1, -1, tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3], 0,0,0,0);
1180 //Assign an outgoing parton as mother
1181 Float_t phidiff1 = TMath::Abs(jet->Phi()-parton1->Phi());
1182 Float_t phidiff2 = TMath::Abs(jet->Phi()-parton2->Phi());
1183 if(phidiff1 > phidiff2) jet->SetFirstMother(7);
1184 else jet->SetFirstMother(6);
1187 printf("AliMCAnalysisUtils::GetJets() - PYTHIA Jet %d: mother %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1188 i, jet->GetFirstMother(),jet->Pt(),jet->Energy(),jet->Phi()*TMath::RadToDeg(),jet->Eta());
1189 fJetsList->Add(jet);
1191 }//Pythia triggered jets
1193 else if (fMCGenerator=="HERWIG"){
1196 TParticle * tmp = parton1;
1197 if(parton1->GetPdgCode()!=22){
1199 if(tmp->GetFirstDaughter()==-1) return fJetsList;
1200 tmp = stack->Particle(tmp->GetFirstDaughter());
1201 pdg = tmp->GetPdgCode();
1204 //Add found jet to list
1205 TParticle *jet1 = new TParticle(*tmp);
1206 jet1->SetFirstMother(6);
1207 fJetsList->Add(jet1);
1208 //printf("jet 1: first daughter %d, last daughter %d\n", tmp->GetFirstDaughter(), tmp->GetLastDaughter());
1209 //tmp = stack->Particle(tmp->GetFirstDaughter());
1213 printf("AliMCAnalysisUtils::GetJets() - HERWIG Jet 1: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1214 jet1->GetFirstMother(),jet1->GetStatusCode(),jet1->Pt(),jet1->Energy(),jet1->Phi()*TMath::RadToDeg(),jet1->Eta());
1221 if(parton2->GetPdgCode()!=22){
1223 if(tmp->GetFirstDaughter()==-1) return fJetsList;
1224 i = tmp->GetFirstDaughter();
1225 tmp = stack->Particle(tmp->GetFirstDaughter());
1226 pdg = tmp->GetPdgCode();
1228 //Add found jet to list
1229 TParticle *jet2 = new TParticle(*tmp);
1230 jet2->SetFirstMother(7);
1231 fJetsList->Add(jet2);
1234 printf("AliMCAnalysisUtils::GetJets() - HERWIG Jet 2: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1235 jet2->GetFirstMother(),jet2->GetStatusCode(),jet2->Pt(),jet2->Energy(),jet2->Phi()*TMath::RadToDeg(),jet2->Eta());
1236 //Int_t first = tmp->GetFirstDaughter();
1237 //Int_t last = tmp->GetLastDaughter();
1238 //printf("jet 2: first daughter %d, last daughter %d, pdg %d\n",first, last, tmp->GetPdgCode());
1239 // for(Int_t d = first ; d < last+1; d++){
1240 // tmp = stack->Particle(d);
1241 // if(i == tmp->GetFirstMother())
1242 // printf("Daughter n %d, Mother %d, name %s, status %d, pT %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1243 // d,tmp->GetFirstMother(), tmp->GetName(), tmp->GetStatusCode(),tmp->Pt(),tmp->Energy(),tmp->Phi()*TMath::RadToDeg(),tmp->Eta());
1247 }//Herwig generated jets
1254 //________________________________________________________________________________________________________
1255 TLorentzVector AliMCAnalysisUtils::GetDaughter(const Int_t idaugh, const Int_t label,
1256 const AliCaloTrackReader* reader,
1257 Int_t & pdg, Int_t & status, Bool_t & ok, Int_t & daughlabel)
1259 //Return the kinematics of the particle that generated the signal, its pdg and its status and its label mother
1261 TLorentzVector daughter(0,0,0,0);
1263 if(reader->ReadStack())
1265 if(!reader->GetStack())
1268 printf("AliMCAnalysisUtils::GetDaughter() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1273 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1275 TParticle * momP = reader->GetStack()->Particle(label);
1276 daughlabel = momP->GetDaughter(idaugh);
1278 TParticle * daughP = reader->GetStack()->Particle(daughlabel);
1279 daughP->Momentum(daughter);
1280 pdg = daughP->GetPdgCode();
1281 status = daughP->GetStatusCode();
1289 else if(reader->ReadAODMCParticles())
1291 TClonesArray* mcparticles = reader->GetAODMCParticles();
1295 printf("AliMCAnalysisUtils::GetDaughter() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1301 Int_t nprimaries = mcparticles->GetEntriesFast();
1302 if(label >= 0 && label < nprimaries)
1304 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1305 daughlabel = momP->GetDaughter(idaugh);
1307 AliAODMCParticle * daughP = (AliAODMCParticle *) mcparticles->At(daughlabel);
1308 daughter.SetPxPyPzE(daughP->Px(),daughP->Py(),daughP->Pz(),daughP->E());
1309 pdg = daughP->GetPdgCode();
1310 status = daughP->GetStatus();
1324 //_______________________________________________________________________________________________
1325 TLorentzVector AliMCAnalysisUtils::GetMother(const Int_t label, const AliCaloTrackReader* reader,
1328 //Return the kinematics of the particle that generated the signal
1330 Int_t pdg = -1; Int_t status = -1; Int_t momlabel = -1;
1331 return GetMother(label,reader,pdg,status, ok,momlabel);
1334 //_______________________________________________________________________________________________
1335 TLorentzVector AliMCAnalysisUtils::GetMother(const Int_t label, const AliCaloTrackReader* reader,
1336 Int_t & pdg, Int_t & status, Bool_t & ok)
1338 //Return the kinematics of the particle that generated the signal
1340 Int_t momlabel = -1;
1341 return GetMother(label,reader,pdg,status, ok,momlabel);
1344 //_______________________________________________________________________________________________
1345 TLorentzVector AliMCAnalysisUtils::GetMother(const Int_t label, const AliCaloTrackReader* reader,
1346 Int_t & pdg, Int_t & status, Bool_t & ok, Int_t & momlabel)
1348 //Return the kinematics of the particle that generated the signal, its pdg and its status and its label mother
1350 TLorentzVector mom(0,0,0,0);
1352 if(reader->ReadStack())
1354 if(!reader->GetStack())
1357 printf("AliMCAnalysisUtils::GetMother() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1362 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1364 TParticle * momP = reader->GetStack()->Particle(label);
1365 momP->Momentum(mom);
1366 pdg = momP->GetPdgCode();
1367 status = momP->GetStatusCode();
1368 momlabel = momP->GetFirstMother();
1376 else if(reader->ReadAODMCParticles())
1378 TClonesArray* mcparticles = reader->GetAODMCParticles();
1382 printf("AliMCAnalysisUtils::GetMother() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1388 Int_t nprimaries = mcparticles->GetEntriesFast();
1389 if(label >= 0 && label < nprimaries)
1391 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1392 mom.SetPxPyPzE(momP->Px(),momP->Py(),momP->Pz(),momP->E());
1393 pdg = momP->GetPdgCode();
1394 status = momP->GetStatus();
1395 momlabel = momP->GetMother();
1409 //_____________________________________________________________________________________
1410 TLorentzVector AliMCAnalysisUtils::GetMotherWithPDG(const Int_t label, const Int_t pdg, const AliCaloTrackReader* reader,
1411 Bool_t & ok, Int_t & momlabel)
1413 //Return the kinematics of the particle that generated the signal
1415 TLorentzVector grandmom(0,0,0,0);
1418 if(reader->ReadStack())
1420 if(!reader->GetStack())
1423 printf("AliMCAnalysisUtils::GetMotherWithPDG() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1429 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1431 TParticle * momP = reader->GetStack()->Particle(label);
1433 Int_t grandmomLabel = momP->GetFirstMother();
1434 Int_t grandmomPDG = -1;
1435 TParticle * grandmomP = 0x0;
1436 while (grandmomLabel >=0 )
1438 grandmomP = reader->GetStack()->Particle(grandmomLabel);
1439 grandmomPDG = grandmomP->GetPdgCode();
1440 if(grandmomPDG==pdg)
1442 momlabel = grandmomLabel;
1443 grandmom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->Energy());
1447 grandmomLabel = grandmomP->GetFirstMother();
1451 if(grandmomPDG!=pdg) printf("AliMCAnalysisUtils::GetMotherWithPDG(ESD) - mother with PDG %d, not found! \n",pdg);
1454 else if(reader->ReadAODMCParticles())
1456 TClonesArray* mcparticles = reader->GetAODMCParticles();
1460 printf("AliMCAnalysisUtils::GetMotherWithPDG() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1466 Int_t nprimaries = mcparticles->GetEntriesFast();
1467 if(label >= 0 && label < nprimaries)
1469 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1471 Int_t grandmomLabel = momP->GetMother();
1472 Int_t grandmomPDG = -1;
1473 AliAODMCParticle * grandmomP = 0x0;
1474 while (grandmomLabel >=0 )
1476 grandmomP = (AliAODMCParticle *) mcparticles->At(grandmomLabel);
1477 grandmomPDG = grandmomP->GetPdgCode();
1478 if(grandmomPDG==pdg)
1480 //printf("AliMCAnalysisUtils::GetMotherWithPDG(AOD) - mother with PDG %d FOUND! \n",pdg);
1481 momlabel = grandmomLabel;
1482 grandmom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->E());
1486 grandmomLabel = grandmomP->GetMother();
1490 if(grandmomPDG!=pdg) printf("AliMCAnalysisUtils::GetMotherWithPDG(AOD) - mother with PDG %d, NOT found! \n",pdg);
1500 //____________________________________________________________________________________________________
1501 TLorentzVector AliMCAnalysisUtils::GetGrandMother(const Int_t label, const AliCaloTrackReader* reader,
1502 Int_t & pdg, Int_t & status, Bool_t & ok,
1503 Int_t & grandMomLabel, Int_t & greatMomLabel)
1505 //Return the kinematics of the particle that generated the signal
1507 TLorentzVector grandmom(0,0,0,0);
1509 if(reader->ReadStack())
1511 if(!reader->GetStack())
1514 printf("AliMCAnalysisUtils::GetGrandMother() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1520 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1522 TParticle * momP = reader->GetStack()->Particle(label);
1524 grandMomLabel = momP->GetFirstMother();
1526 TParticle * grandmomP = 0x0;
1528 if (grandMomLabel >=0 )
1530 grandmomP = reader->GetStack()->Particle(grandMomLabel);
1531 pdg = grandmomP->GetPdgCode();
1532 status = grandmomP->GetStatusCode();
1534 grandmom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->Energy());
1535 greatMomLabel = grandmomP->GetFirstMother();
1540 else if(reader->ReadAODMCParticles())
1542 TClonesArray* mcparticles = reader->GetAODMCParticles();
1546 printf("AliMCAnalysisUtils::GetGrandMother() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1552 Int_t nprimaries = mcparticles->GetEntriesFast();
1553 if(label >= 0 && label < nprimaries)
1555 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1557 grandMomLabel = momP->GetMother();
1559 AliAODMCParticle * grandmomP = 0x0;
1561 if(grandMomLabel >=0 )
1563 grandmomP = (AliAODMCParticle *) mcparticles->At(grandMomLabel);
1564 pdg = grandmomP->GetPdgCode();
1565 status = grandmomP->GetStatus();
1567 grandmom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->E());
1568 greatMomLabel = grandmomP->GetMother();
1579 //___________________________________________________________________________________________________________________________
1580 void AliMCAnalysisUtils::GetMCDecayAsymmetryAngleForPDG(const Int_t label, const Int_t pdg, const AliCaloTrackReader* reader,
1581 Float_t & asym, Float_t & angle, Bool_t & ok)
1583 //In case of an eta or pi0 decay into 2 photons, get the asymmetry in the energy of the photons
1586 if(reader->ReadStack())
1588 if(!reader->GetStack())
1591 printf("AliMCAnalysisUtils::GetMCDecayAsymmetryForPDG() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1595 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1597 TParticle * momP = reader->GetStack()->Particle(label);
1599 Int_t grandmomLabel = momP->GetFirstMother();
1600 Int_t grandmomPDG = -1;
1601 TParticle * grandmomP = 0x0;
1602 while (grandmomLabel >=0 )
1604 grandmomP = reader->GetStack()->Particle(grandmomLabel);
1605 grandmomPDG = grandmomP->GetPdgCode();
1607 if(grandmomPDG==pdg) break;
1609 grandmomLabel = grandmomP->GetFirstMother();
1613 if(grandmomPDG==pdg && grandmomP->GetNDaughters()==2)
1615 TParticle * d1 = reader->GetStack()->Particle(grandmomP->GetDaughter(0));
1616 TParticle * d2 = reader->GetStack()->Particle(grandmomP->GetDaughter(1));
1617 if(d1->GetPdgCode() == 22 && d1->GetPdgCode() == 22)
1619 asym = (d1->Energy()-d2->Energy())/grandmomP->Energy();
1620 TLorentzVector lvd1, lvd2;
1623 angle = lvd1.Angle(lvd2.Vect());
1629 printf("AliMCAnalysisUtils::GetMCDecayAsymmetryForPDG(ESD) - mother with PDG %d, not found! \n",pdg);
1634 else if(reader->ReadAODMCParticles())
1636 TClonesArray* mcparticles = reader->GetAODMCParticles();
1640 printf("AliMCAnalysisUtils::GetMCDecayAsymmetryForPDG() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1646 Int_t nprimaries = mcparticles->GetEntriesFast();
1647 if(label >= 0 && label < nprimaries)
1649 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1651 Int_t grandmomLabel = momP->GetMother();
1652 Int_t grandmomPDG = -1;
1653 AliAODMCParticle * grandmomP = 0x0;
1654 while (grandmomLabel >=0 )
1656 grandmomP = (AliAODMCParticle *) mcparticles->At(grandmomLabel);
1657 grandmomPDG = grandmomP->GetPdgCode();
1659 if(grandmomPDG==pdg) break;
1661 grandmomLabel = grandmomP->GetMother();
1665 if(grandmomPDG==pdg && grandmomP->GetNDaughters()==2)
1667 AliAODMCParticle * d1 = (AliAODMCParticle *) mcparticles->At(grandmomP->GetDaughter(0));
1668 AliAODMCParticle * d2 = (AliAODMCParticle *) mcparticles->At(grandmomP->GetDaughter(1));
1669 if(d1->GetPdgCode() == 22 && d1->GetPdgCode() == 22)
1671 asym = (d1->E()-d2->E())/grandmomP->E();
1672 TLorentzVector lvd1, lvd2;
1673 lvd1.SetPxPyPzE(d1->Px(),d1->Py(),d1->Pz(),d1->E());
1674 lvd2.SetPxPyPzE(d2->Px(),d2->Py(),d2->Pz(),d2->E());
1675 angle = lvd1.Angle(lvd2.Vect());
1681 printf("AliMCAnalysisUtils::GetMCDecayAsymmetryForPDG(AOD) - mother with PDG %d, not found! \n",pdg);
1692 //_______________________________________________________________________________________________________
1693 Int_t AliMCAnalysisUtils::GetNDaughters(const Int_t label, const AliCaloTrackReader* reader, Bool_t & ok)
1695 // Return the the number of daughters of a given MC particle
1698 if(reader->ReadStack())
1700 if(!reader->GetStack())
1703 printf("AliMCAnalysisUtils::GetNDaughters() - Stack is not available, check analysis settings in configuration file, STOP!!\n");
1708 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1710 TParticle * momP = reader->GetStack()->Particle(label);
1712 return momP->GetNDaughters();
1720 else if(reader->ReadAODMCParticles())
1722 TClonesArray* mcparticles = reader->GetAODMCParticles();
1726 printf("AliMCAnalysisUtils::GetNDaughters() - AODMCParticles is not available, check analysis settings in configuration file!!\n");
1732 Int_t nprimaries = mcparticles->GetEntriesFast();
1733 if(label >= 0 && label < nprimaries)
1735 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1737 return momP->GetNDaughters();
1751 //_______________________________________________________________________________
1752 Int_t AliMCAnalysisUtils::GetNOverlaps(const Int_t * label, const UInt_t nlabels,
1753 const Int_t mctag, const Int_t mesonLabel,
1754 AliCaloTrackReader * reader, Int_t *overpdg)
1756 // Compare the primary depositing more energy with the rest,
1757 // if no photon/electron (conversion) or neutral meson as comon ancestor, consider it as other particle contributing
1758 // Give as input the meson label in case it was a pi0 or eta merged cluster
1759 // Init overpdg with nlabels
1761 Int_t ancPDG = 0, ancStatus = -1;
1762 TLorentzVector momentum; TVector3 prodVertex;
1764 Int_t noverlaps = 0;
1767 for (UInt_t ilab = 1; ilab < nlabels; ilab++ )
1769 ancLabel = CheckCommonAncestor(label[0],label[ilab],reader,ancPDG,ancStatus,momentum,prodVertex);
1771 //printf("Overlaps, i %d: Main Label %d, second label %d, ancestor: Label %d, pdg %d - tag %d \n",
1772 // ilab,label[0],label[ilab],ancLabel,ancPDG, mctag);
1774 Bool_t overlap = kFALSE;
1779 //printf("\t \t \t No Label = %d\n",ancLabel);
1781 else if( ( ancPDG==111 || ancPDG==221 ) && ( CheckTagBit(mctag,kMCPi0) || CheckTagBit(mctag,kMCEta)) && mesonLabel != ancLabel)
1783 //printf("\t \t meson Label %d, ancestor Label %d\n",mesonLabel,ancLabel);
1786 else if( ancPDG!=22 && TMath::Abs(ancPDG)!=11 && ancPDG != 111 && ancPDG != 221 )
1788 //printf("\t \t \t Non EM PDG = %d\n",ancPDG);
1792 if( !overlap ) continue ;
1794 // We have at least one overlap
1796 //printf("Overlap!!!!!!!!!!!!!!\n");
1800 // What is the origin of the overlap?
1801 Bool_t mOK = 0, gOK = 0;
1802 Int_t mpdg = -999999, gpdg = -1;
1803 Int_t mstatus = -1, gstatus = -1;
1804 Int_t gLabel = -1, ggLabel = -1;
1805 TLorentzVector mother = GetMother (label[ilab],reader,mpdg,mstatus,mOK);
1806 TLorentzVector grandmother = GetGrandMother(label[ilab],reader,gpdg,gstatus,gOK, gLabel,ggLabel);
1808 //printf("\t Overlap!, mother pdg %d; grand mother pdg %d",mpdg,gpdg);
1810 if( ( mpdg == 22 || TMath::Abs(mpdg==11) ) &&
1811 ( gpdg == 22 || TMath::Abs(gpdg==11) ) &&
1814 Int_t labeltmp = gLabel;
1815 while( ( gpdg == 22 || TMath::Abs(gpdg==11) ) && gLabel >=0 )
1818 grandmother = GetGrandMother(labeltmp,reader,gpdg,gstatus,ok, gLabel,ggLabel);
1822 overpdg[noverlaps-1] = mpdg;
1829 //________________________________________________________
1830 void AliMCAnalysisUtils::Print(const Option_t * opt) const
1832 //Print some relevant parameters set for the analysis
1837 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1839 printf("Debug level = %d\n",fDebug);
1840 printf("MC Generator = %s\n",fMCGenerator.Data());
1845 //________________________________________________________
1846 void AliMCAnalysisUtils::PrintMCTag(const Int_t tag) const
1848 // print the assigned origins to this particle
1850 printf("AliMCAnalysisUtils::PrintMCTag() - tag %d \n photon %d, conv %d, prompt %d, frag %d, isr %d, \n pi0 decay %d, eta decay %d, other decay %d pi0 %d, eta %d \n electron %d, muon %d,pion %d, proton %d, neutron %d, \n kaon %d, a-proton %d, a-neutron %d, other %d, unk %d, bad %d\n",
1852 CheckTagBit(tag,kMCPhoton),
1853 CheckTagBit(tag,kMCConversion),
1854 CheckTagBit(tag,kMCPrompt),
1855 CheckTagBit(tag,kMCFragmentation),
1856 CheckTagBit(tag,kMCISR),
1857 CheckTagBit(tag,kMCPi0Decay),
1858 CheckTagBit(tag,kMCEtaDecay),
1859 CheckTagBit(tag,kMCOtherDecay),
1860 CheckTagBit(tag,kMCPi0),
1861 CheckTagBit(tag,kMCEta),
1862 CheckTagBit(tag,kMCElectron),
1863 CheckTagBit(tag,kMCMuon),
1864 CheckTagBit(tag,kMCPion),
1865 CheckTagBit(tag,kMCProton),
1866 CheckTagBit(tag,kMCAntiNeutron),
1867 CheckTagBit(tag,kMCKaon),
1868 CheckTagBit(tag,kMCAntiProton),
1869 CheckTagBit(tag,kMCAntiNeutron),
1870 CheckTagBit(tag,kMCOther),
1871 CheckTagBit(tag,kMCUnknown),
1872 CheckTagBit(tag,kMCBadLabel)