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"
42 ClassImp(AliMCAnalysisUtils)
44 //________________________________________
45 AliMCAnalysisUtils::AliMCAnalysisUtils() :
50 fMCGenerator(kPythia),
51 fMCGeneratorString("PYTHIA"),
52 fDaughMom(), fDaughMom2(),
53 fMotherMom(), fGMotherMom()
58 //_______________________________________
59 AliMCAnalysisUtils::~AliMCAnalysisUtils()
61 // Remove all pointers.
70 //_____________________________________________________________________________________________
71 Int_t AliMCAnalysisUtils::CheckCommonAncestor(Int_t index1, Int_t index2,
72 const AliCaloTrackReader* reader,
73 Int_t & ancPDG, Int_t & ancStatus,
74 TLorentzVector & momentum, TVector3 & prodVertex)
76 // Check the first common ancestor of 2 clusters, given the most likely labels of the primaries generating such clusters.
85 if(label1[0]==label2[0])
87 //printf("AliMCAnalysisUtils::CheckCommonAncestor() - Already the same label: %d\n",label1[0]);
93 if(reader->ReadAODMCParticles())
95 TClonesArray * mcparticles = reader->GetAODMCParticles();
97 Int_t label=label1[0];
98 if(label < 0) return -1;
100 while(label > -1 && counter1 < 99)
103 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
106 label = mom->GetMother() ;
107 label1[counter1]=label;
109 //printf("\t counter %d, label %d\n", counter1,label);
112 //printf("Org label2=%d,\n",label2[0]);
114 if(label < 0) return -1;
116 while(label > -1 && counter2 < 99)
119 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
122 label = mom->GetMother() ;
123 label2[counter2]=label;
125 //printf("\t counter %d, label %d\n", counter2,label);
129 { //Kine stack from ESDs
130 AliStack * stack = reader->GetStack();
132 Int_t label=label1[0];
133 while(label > -1 && counter1 < 99)
136 TParticle * mom = stack->Particle(label);
139 label = mom->GetFirstMother() ;
140 label1[counter1]=label;
142 //printf("\t counter %d, label %d\n", counter1,label);
145 //printf("Org label2=%d,\n",label2[0]);
148 while(label > -1 && counter2 < 99)
151 TParticle * mom = stack->Particle(label);
154 label = mom->GetFirstMother() ;
155 label2[counter2]=label;
157 //printf("\t counter %d, label %d\n", counter2,label);
159 }// Kine stack from ESDs
160 }//First labels not the same
162 // if((counter1==99 || counter2==99) && fDebug >=0)
163 // printf("AliMCAnalysisUtils::CheckCommonAncestor() - Genealogy too large c1: %d, c2= %d\n", counter1, counter2);
164 //printf("CheckAncestor:\n");
166 Int_t commonparents = 0;
168 //printf("counters %d %d \n",counter1, counter2);
169 for (Int_t c1 = 0; c1 < counter1; c1++)
171 for (Int_t c2 = 0; c2 < counter2; c2++)
173 if(label1[c1]==label2[c2] && label1[c1]>-1)
175 ancLabel = label1[c1];
178 if(reader->ReadAODMCParticles())
180 AliAODMCParticle * mom = (AliAODMCParticle *) reader->GetAODMCParticles()->At(label1[c1]);
184 ancPDG = mom->GetPdgCode();
185 ancStatus = mom->GetStatus();
186 momentum.SetPxPyPzE(mom->Px(),mom->Py(),mom->Pz(),mom->E());
187 prodVertex.SetXYZ(mom->Xv(),mom->Yv(),mom->Zv());
192 TParticle * mom = (reader->GetStack())->Particle(label1[c1]);
196 ancPDG = mom->GetPdgCode();
197 ancStatus = mom->GetStatusCode();
198 mom->Momentum(momentum);
199 prodVertex.SetXYZ(mom->Vx(),mom->Vy(),mom->Vz());
203 //First ancestor found, end the loops
207 }//second cluster loop
208 }//first cluster loop
214 momentum.SetXYZT(0,0,0,0);
215 prodVertex.SetXYZ(-10,-10,-10);
221 //________________________________________________________________________________________
222 Int_t AliMCAnalysisUtils::CheckOrigin(const Int_t * label, Int_t nlabels,
223 const AliCaloTrackReader* reader, Int_t calorimeter)
225 // Play with the montecarlo particles if available.
231 AliWarning("No MC labels available, please check!!!");
235 TObjArray* arrayCluster = 0;
236 if ( calorimeter == AliCaloTrackReader::kEMCAL ) arrayCluster = reader->GetEMCALClusters();
237 else if ( calorimeter == AliCaloTrackReader::kPHOS ) arrayCluster = reader->GetPHOSClusters ();
239 //Select where the information is, ESD-galice stack or AOD mcparticles branch
240 if(reader->ReadStack()){
241 tag = CheckOriginInStack(label, nlabels, reader->GetStack(), arrayCluster);
243 else if(reader->ReadAODMCParticles()){
244 tag = CheckOriginInAOD(label, nlabels, reader->GetAODMCParticles(),arrayCluster);
250 //____________________________________________________________________________________________________
251 Int_t AliMCAnalysisUtils::CheckOrigin(Int_t label, const AliCaloTrackReader* reader, Int_t calorimeter)
253 // Play with the montecarlo particles if available.
259 AliWarning("No MC labels available, please check!!!");
263 TObjArray* arrayCluster = 0;
264 if ( calorimeter == AliCaloTrackReader::kEMCAL ) arrayCluster = reader->GetEMCALClusters();
265 else if ( calorimeter == AliCaloTrackReader::kPHOS ) arrayCluster = reader->GetPHOSClusters();
267 Int_t labels[]={label};
269 //Select where the information is, ESD-galice stack or AOD mcparticles branch
270 if(reader->ReadStack()){
271 tag = CheckOriginInStack(labels, 1,reader->GetStack(),arrayCluster);
273 else if(reader->ReadAODMCParticles()){
274 tag = CheckOriginInAOD(labels, 1,reader->GetAODMCParticles(),arrayCluster);
280 //__________________________________________________________________________________________
281 Int_t AliMCAnalysisUtils::CheckOriginInStack(const Int_t *labels, Int_t nlabels,
282 AliStack* stack, const TObjArray* arrayCluster)
284 // Play with the MC stack if available. Tag particles depending on their origin.
285 // Do same things as in CheckOriginInAOD but different input.
287 //generally speaking, label is the MC label of a reconstructed
288 //entity (track, cluster, etc) for which we want to know something
289 //about its heritage, but one can also use it directly with stack
290 //particles not connected to reconstructed entities
294 AliDebug(1,"Stack is not available, check analysis settings in configuration file, STOP!!");
299 Int_t label=labels[0];//Most significant particle contributing to the cluster
301 if(label >= 0 && label < stack->GetNtrack())
303 //MC particle of interest is the "mom" of the entity
304 TParticle * mom = stack->Particle(label);
306 Int_t mPdgSign = mom->GetPdgCode();
307 Int_t mPdg = TMath::Abs(mPdgSign);
308 Int_t mStatus = mom->GetStatusCode() ;
309 Int_t iParent = mom->GetFirstMother() ;
311 //if( label < 8 && fMCGenerator != kBoxLike ) AliDebug(1,Form("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d",iParent));
313 //GrandParent of the entity
314 TParticle * parent = NULL;
319 parent = stack->Particle(iParent);
323 pPdg = TMath::Abs(parent->GetPdgCode());
324 pStatus = parent->GetStatusCode();
327 else AliDebug(1,Form("Parent with label %d",iParent));
329 AliDebug(2,"Cluster most contributing mother and its parent:");
330 AliDebug(2,Form("\t Mother label %d, pdg %d, status %d",iMom, mPdg, mStatus));
331 AliDebug(2,Form("\t Parent label %d, pdg %d, status %d",iParent, pPdg, pStatus));
333 //Check if "mother" of entity is converted, if not, get the first non converted mother
334 if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && mStatus == 0)
336 SetTagBit(tag,kMCConversion);
338 //Check if the mother is photon or electron with status not stable
339 while ((pPdg == 22 || pPdg == 11) && mStatus != 1)
342 iMom = mom->GetFirstMother();
343 mom = stack->Particle(iMom);
344 mPdgSign = mom->GetPdgCode();
345 mPdg = TMath::Abs(mPdgSign);
346 mStatus = mom->GetStatusCode() ;
347 iParent = mom->GetFirstMother() ;
349 //if(label < 8 ) AliDebug(1,Form("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent));
354 parent = stack->Particle(iParent);
357 pPdg = TMath::Abs(parent->GetPdgCode());
358 pStatus = parent->GetStatusCode();
361 else {// in case of gun/box simulations
368 AliDebug(2,"Converted photon/electron:");
369 AliDebug(2,Form("\t Mother label %d, pdg %d, status %d",iMom, mPdg, mStatus));
370 AliDebug(2,Form("\t Parent label %d, pdg %d, status %d",iParent, pPdg, pStatus));
372 }//mother and parent are electron or photon and have status 0
373 else if((mPdg == 22 || mPdg == 11) && mStatus == 0)
375 //Still a conversion but only one electron/photon generated. Just from hadrons but not decays.
376 if(pPdg == 2112 || pPdg == 211 || pPdg == 321 ||
377 pPdg == 2212 || pPdg == 130 || pPdg == 13 )
379 SetTagBit(tag,kMCConversion);
380 iMom = mom->GetFirstMother();
381 mom = stack->Particle(iMom);
382 mPdgSign = mom->GetPdgCode();
383 mPdg = TMath::Abs(mPdgSign);
385 AliDebug(2,"Converted hadron:");
386 AliDebug(2,Form("\t Mother label %d, pdg %d, status %d",iMom, mPdg, mStatus));
390 //Comment for the next lines, we do not check the parent of the hadron for the moment.
391 //iParent = mom->GetFirstMother() ;
392 //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInStack() - Mother is parton %d\n",iParent);
396 // parent = stack->Particle(iParent);
397 // pPdg = TMath::Abs(parent->GetPdgCode());
400 // conversion into electrons/photons checked
402 //first check for typical charged particles
403 if (mPdg == 13) SetTagBit(tag,kMCMuon);
404 else if(mPdg == 211) SetTagBit(tag,kMCPion);
405 else if(mPdg == 321) SetTagBit(tag,kMCKaon);
406 else if(mPdgSign == 2212) SetTagBit(tag,kMCProton);
407 else if(mPdgSign == -2212) SetTagBit(tag,kMCAntiProton);
408 else if(mPdgSign == 2112) SetTagBit(tag,kMCNeutron);
409 else if(mPdgSign == -2112) SetTagBit(tag,kMCAntiNeutron);
411 //check for pi0 and eta (shouldn't happen unless their decays were turned off)
415 SetTagBit(tag,kMCPi0Decay);
417 AliDebug(2,"First mother is directly pi0, not decayed by generator");
419 CheckOverlapped2GammaDecay(labels,nlabels, iMom, stack, tag); //set to kMCPi0 if 2 gammas in same cluster
424 SetTagBit(tag,kMCEtaDecay);
426 AliDebug(2,"First mother is directly eta, not decayed by generator");
428 CheckOverlapped2GammaDecay(labels,nlabels, iMom, stack, tag); //set to kMCEta if 2 gammas in same cluster
433 SetTagBit(tag,kMCPhoton);
437 SetTagBit(tag,kMCPi0Decay);
439 AliDebug(2,"PYTHIA pi0 decay photon, parent pi0 with status 11");
441 CheckOverlapped2GammaDecay(labels,nlabels, iParent, stack, tag); //set to kMCPi0 if 2 gammas in same cluster
442 // In case it did not merge, check if the decay companion is lost
443 if(!CheckTagBit(tag, kMCPi0) && !CheckTagBit(tag,kMCDecayPairInCalo))
444 CheckLostDecayPair(arrayCluster,iMom, iParent, stack, tag);
446 //printf("Bit set is Merged %d, Pair in calo %d, Lost %d\n",CheckTagBit(tag, kMCPi0),CheckTagBit(tag,kMCDecayPairInCalo),CheckTagBit(tag,kMCDecayPairLost));
448 else if (pPdg == 221)
450 SetTagBit(tag, kMCEtaDecay);
452 AliDebug(2,"PYTHIA eta decay photon, parent pi0 with status 11");
454 CheckOverlapped2GammaDecay(labels,nlabels, iParent, stack, tag);//set to kMCEta if 2 gammas in same cluster
455 // In case it did not merge, check if the decay companion is lost
456 if(!CheckTagBit(tag, kMCEta) && !CheckTagBit(tag,kMCDecayPairInCalo))
457 CheckLostDecayPair(arrayCluster,iMom, iParent, stack, tag);
459 else if(mStatus == 1)
460 { //undecayed particle
461 if(fMCGenerator == kPythia)
463 if(iParent < 8 && iParent > 5)
465 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
466 else SetTagBit(tag,kMCFragmentation);
468 else if(iParent <= 5)
470 SetTagBit(tag, kMCISR); //Initial state radiation
472 else SetTagBit(tag,kMCUnknown);
475 else if(fMCGenerator == kHerwig)
483 if(parent->GetFirstMother()<=5) break;
484 iParent = parent->GetFirstMother();
485 parent=stack->Particle(iParent);
486 pStatus= parent->GetStatusCode();
487 pPdg = TMath::Abs(parent->GetPdgCode());
489 }//Look for the parton
491 if(iParent < 8 && iParent > 5)
493 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
494 else SetTagBit(tag,kMCFragmentation);
496 else SetTagBit(tag,kMCISR);//Initial state radiation
498 else SetTagBit(tag,kMCUnknown);
501 else SetTagBit(tag,kMCOtherDecay);
505 //Electron check. Where did that electron come from?
506 else if(mPdg == 11){ //electron
507 if(pPdg == 11 && parent)
509 Int_t iGrandma = parent->GetFirstMother();
512 TParticle* gma = (TParticle*)stack->Particle(iGrandma); //get mother
513 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
515 if (gPdg == 23) { SetTagBit(tag,kMCZDecay); } //parent is Z-boson
516 else if (gPdg == 24) { SetTagBit(tag,kMCWDecay); } //parent is W-boson
520 SetTagBit(tag,kMCElectron);
522 AliDebug(1,"Checking ancestors of electrons");
524 if (pPdg == 111) { SetTagBit(tag,kMCPi0Decay); SetTagBit(tag, kMCDecayDalitz) ; } //Pi0 Dalitz decay
525 else if (pPdg == 221) { SetTagBit(tag,kMCEtaDecay); SetTagBit(tag, kMCDecayDalitz) ; } //Eta Dalitz decay
526 else if((499 < pPdg && pPdg < 600)||(4999 < pPdg && pPdg < 6000)) { SetTagBit(tag,kMCEFromB); } //b-->e decay
527 else if((399 < pPdg && pPdg < 500)||(3999 < pPdg && pPdg < 5000))
528 { //check charm decay
531 Int_t iGrandma = parent->GetFirstMother();
534 TParticle* gma = (TParticle*)stack->Particle(iGrandma); //get mother of charm
535 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
536 if((499 < gPdg && gPdg < 600)||(4999 < gPdg && gPdg < 6000)) SetTagBit(tag,kMCEFromCFromB); //b-->c-->e
537 else SetTagBit(tag,kMCEFromC); //c-->e
539 else SetTagBit(tag,kMCEFromC); //c-->e
544 //if it is not from any of the above, where is it from?
545 if(pPdg > 10000) SetTagBit(tag,kMCUnknown);
547 else SetTagBit(tag,kMCOtherDecay);
549 //if(parent) AliDebug(1,Form("Status %d Electron from other origin: %s (pPdg = %d) %s (mpdg = %d)",mStatus,parent->GetName(),pPdg,mom->GetName(),mPdg));
552 //Cluster was made by something else
555 AliDebug(2,Form("\t Setting kMCUnknown for cluster from %s (pdg = %d, Parent pdg = %d)",
556 mom->GetName(),mPdg,pPdg));
558 SetTagBit(tag,kMCUnknown);
564 AliWarning(Form("*** bad label or no stack ***: label %d ", label));
566 if(label >= stack->GetNtrack())
567 AliWarning(Form("*** large label ***: label %d, n tracks %d", label, stack->GetNtrack()));
569 SetTagBit(tag,kMCUnknown);
577 //________________________________________________________________________________________________________
578 Int_t AliMCAnalysisUtils::CheckOriginInAOD(const Int_t *labels, Int_t nlabels,
579 const TClonesArray *mcparticles, const TObjArray* arrayCluster)
581 // Play with the MCParticles in AOD if available. Tag particles depending on their origin.
582 // Do same things as in CheckOriginInStack but different input.
586 AliDebug(1,"AODMCParticles is not available, check analysis settings in configuration file!!");
591 Int_t label=labels[0];//Most significant particle contributing to the cluster
593 Int_t nprimaries = mcparticles->GetEntriesFast();
594 if(label >= 0 && label < nprimaries)
597 AliAODMCParticle * mom = (AliAODMCParticle *) mcparticles->At(label);
599 Int_t mPdgSign = mom->GetPdgCode();
600 Int_t mPdg = TMath::Abs(mPdgSign);
601 Int_t iParent = mom->GetMother() ;
603 //if(label < 8 && fMCGenerator != kBoxLike) AliDebug(1,Form("Mother is parton %d\n",iParent));
606 AliAODMCParticle * parent = NULL ;
610 parent = (AliAODMCParticle *) mcparticles->At(iParent);
611 pPdg = TMath::Abs(parent->GetPdgCode());
613 else AliDebug(1,Form("Parent with label %d",iParent));
615 AliDebug(2,"Cluster most contributing mother and its parent:");
616 AliDebug(2,Form("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary()));
617 AliDebug(2,Form("\t Parent label %d, pdg %d, Primary? %d, Physical Primary? %d",iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary()));
619 //Check if mother is converted, if not, get the first non converted mother
620 if((mPdg == 22 || mPdg == 11) && (pPdg == 22 || pPdg == 11) && !mom->IsPrimary())
622 SetTagBit(tag,kMCConversion);
624 //Check if the mother is photon or electron with status not stable
625 while ((pPdg == 22 || pPdg == 11) && !mom->IsPhysicalPrimary())
628 iMom = mom->GetMother();
629 mom = (AliAODMCParticle *) mcparticles->At(iMom);
630 mPdgSign = mom->GetPdgCode();
631 mPdg = TMath::Abs(mPdgSign);
632 iParent = mom->GetMother() ;
633 //if(label < 8 ) AliDebug(1, Form("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent));
636 if(iParent >= 0 && parent)
638 parent = (AliAODMCParticle *) mcparticles->At(iParent);
639 pPdg = TMath::Abs(parent->GetPdgCode());
641 // printf("\t While Mother label %d, pdg %d, Primary? %d, Physical Primary? %d\n",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary());
642 // printf("\t While Parent label %d, pdg %d, Primary? %d, Physical Primary? %d\n",iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary());
646 AliDebug(2,"AliMCAnalysisUtils::CheckOriginInAOD() - Converted photon/electron:");
647 AliDebug(2,Form("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary()));
648 AliDebug(2,Form("\t Parent label %d, pdg %d, Primary? %d, Physical Primary? %d",iParent, pPdg, parent->IsPrimary(), parent->IsPhysicalPrimary()));
650 }//mother and parent are electron or photon and have status 0 and parent is photon or electron
651 else if((mPdg == 22 || mPdg == 11) && !mom->IsPrimary())
653 //Still a conversion but only one electron/photon generated. Just from hadrons
654 if(pPdg == 2112 || pPdg == 211 || pPdg == 321 ||
655 pPdg == 2212 || pPdg == 130 || pPdg == 13 )
657 SetTagBit(tag,kMCConversion);
658 iMom = mom->GetMother();
659 mom = (AliAODMCParticle *) mcparticles->At(iMom);
660 mPdgSign = mom->GetPdgCode();
661 mPdg = TMath::Abs(mPdgSign);
663 AliDebug(2,"AliMCAnalysisUtils::CheckOriginInAOD() - Converted hadron:");
664 AliDebug(2,Form("\t Mother label %d, pdg %d, Primary? %d, Physical Primary? %d",iMom, mPdg, mom->IsPrimary(), mom->IsPhysicalPrimary()));
668 //Comment for next lines, we do not check the parent of the hadron for the moment.
669 //iParent = mom->GetMother() ;
670 //if(fDebug > 0 && label < 8 ) printf("AliMCAnalysisUtils::CheckOriginInAOD() - Mother is parton %d\n",iParent);
674 // parent = (AliAODMCParticle *) mcparticles->At(iParent);
675 // pPdg = TMath::Abs(parent->GetPdgCode());
679 //printf("Final mother mPDG %d\n",mPdg);
681 // conversion into electrons/photons checked
683 //first check for typical charged particles
684 if (mPdg == 13) SetTagBit(tag,kMCMuon);
685 else if(mPdg == 211) SetTagBit(tag,kMCPion);
686 else if(mPdg == 321) SetTagBit(tag,kMCKaon);
687 else if(mPdgSign == 2212) SetTagBit(tag,kMCProton);
688 else if(mPdgSign == 2112) SetTagBit(tag,kMCNeutron);
689 else if(mPdgSign == -2212) SetTagBit(tag,kMCAntiProton);
690 else if(mPdgSign == -2112) SetTagBit(tag,kMCAntiNeutron);
692 //check for pi0 and eta (shouldn't happen unless their decays were turned off)
695 SetTagBit(tag,kMCPi0Decay);
697 AliDebug(2,"First mother is directly pi0, not decayed by generator");
699 CheckOverlapped2GammaDecay(labels,nlabels, iMom, mcparticles, tag); //set to kMCPi0 if 2 gammas in same cluster
703 SetTagBit(tag,kMCEtaDecay);
705 AliDebug(2,"First mother is directly eta, not decayed by generator");
707 CheckOverlapped2GammaDecay(labels,nlabels, iMom, mcparticles, tag); //set to kMCEta if 2 gammas in same cluster
712 SetTagBit(tag,kMCPhoton);
716 SetTagBit(tag,kMCPi0Decay);
718 AliDebug(2,"Generator pi0 decay photon");
720 CheckOverlapped2GammaDecay(labels,nlabels, iParent, mcparticles, tag); //set to kMCPi0 if 2 gammas in same cluster
721 // In case it did not merge, check if the decay companion is lost
722 if(!CheckTagBit(tag, kMCPi0) && !CheckTagBit(tag,kMCDecayPairInCalo) && !CheckTagBit(tag,kMCDecayPairLost))
724 CheckLostDecayPair(arrayCluster,iMom, iParent, mcparticles, tag);
727 //printf("Bit set is Merged %d, Pair in calo %d, Lost %d\n",CheckTagBit(tag, kMCPi0),CheckTagBit(tag,kMCDecayPairInCalo),CheckTagBit(tag,kMCDecayPairLost));
729 else if (pPdg == 221)
731 SetTagBit(tag, kMCEtaDecay);
733 AliDebug(2,"Generator eta decay photon");
735 CheckOverlapped2GammaDecay(labels,nlabels, iParent, mcparticles, tag); //set to kMCEta if 2 gammas in same cluster
736 // In case it did not merge, check if the decay companion is lost
737 if(!CheckTagBit(tag, kMCEta) && !CheckTagBit(tag,kMCDecayPairInCalo))
738 CheckLostDecayPair(arrayCluster,iMom, iParent, mcparticles, tag);
740 else if( mom->IsPhysicalPrimary() && ( fMCGenerator == kPythia || fMCGenerator == kHerwig ) ) //undecayed particle
742 if(iParent < 8 && iParent > 5 )
744 if(pPdg == 22) SetTagBit(tag,kMCPrompt);
745 else SetTagBit(tag,kMCFragmentation);
747 else if( iParent <= 5 && ( fMCGenerator == kPythia || fMCGenerator == kHerwig ) )
749 SetTagBit(tag, kMCISR); //Initial state radiation
751 else SetTagBit(tag,kMCUnknown);
753 else SetTagBit(tag,kMCOtherDecay);
757 //Electron check. Where did that electron come from?
760 if(pPdg == 11 && parent)
762 Int_t iGrandma = parent->GetMother();
765 AliAODMCParticle* gma = (AliAODMCParticle*)mcparticles->At(iGrandma);
766 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
768 if (gPdg == 23) { SetTagBit(tag,kMCZDecay); } //parent is Z-boson
769 else if (gPdg == 24) { SetTagBit(tag,kMCWDecay); } //parent is W-boson
773 SetTagBit(tag,kMCElectron);
775 AliDebug(1,"Checking ancestors of electrons");
777 if (pPdg == 111) { SetTagBit(tag,kMCPi0Decay); SetTagBit(tag,kMCDecayDalitz);} //Pi0 Dalitz decay
778 else if (pPdg == 221) { SetTagBit(tag,kMCEtaDecay); SetTagBit(tag,kMCDecayDalitz);} //Eta Dalitz decay
779 else if((499 < pPdg && pPdg < 600)||(4999 < pPdg && pPdg < 6000)) { SetTagBit(tag,kMCEFromB);} //b-hadron decay
780 else if((399 < pPdg && pPdg < 500)||(3999 < pPdg && pPdg < 5000))
781 { //c-hadron decay check
784 Int_t iGrandma = parent->GetMother();
787 AliAODMCParticle* gma = (AliAODMCParticle*)mcparticles->At(iGrandma); //charm's mother
788 Int_t gPdg = TMath::Abs(gma->GetPdgCode());
789 if((499 < gPdg && gPdg < 600)||(4999 < gPdg && gPdg < 6000)) SetTagBit(tag,kMCEFromCFromB); //b-->c-->e decay
790 else SetTagBit(tag,kMCEFromC); //c-hadron decay
792 else SetTagBit(tag,kMCEFromC); //c-hadron decay
795 { //prompt or other decay
796 TParticlePDG* foo = TDatabasePDG::Instance()->GetParticle(pPdg);
797 TParticlePDG* foo1 = TDatabasePDG::Instance()->GetParticle(mPdg);
799 AliDebug(1,Form("Electron from other origin: %s (pPdg = %d) %s (mPdg = %d)",foo->GetName(), pPdg,foo1->GetName(),mPdg));
801 if(pPdg > 10000) SetTagBit(tag,kMCUnknown);
802 else SetTagBit(tag,kMCOtherDecay);
805 //cluster was made by something else
808 AliDebug(1,Form("\t Setting kMCUnknown for cluster with pdg = %d, Parent pdg = %d",mPdg,pPdg));
809 SetTagBit(tag,kMCUnknown);
815 AliWarning(Form("*** bad label or no mcparticles ***: label %d", label));
817 if(label >= mcparticles->GetEntriesFast())
818 AliWarning(Form("*** large label ***: label %d, n tracks %d", label, mcparticles->GetEntriesFast()));
820 SetTagBit(tag,kMCUnknown);
828 //_________________________________________________________________________________________
829 void AliMCAnalysisUtils::CheckOverlapped2GammaDecay(const Int_t *labels, Int_t nlabels,
830 Int_t mesonIndex, AliStack *stack,
833 // Check if cluster is formed from the contribution of 2 decay photons from pi0 or eta. Input in stack.
835 if(labels[0] < 0 || labels[0] > stack->GetNtrack() || nlabels <= 1)
837 AliDebug(2,Form("Exit : label[0] %d, n primaries %d, nlabels %d",labels[0],stack->GetNtrack(), nlabels));
841 TParticle * meson = stack->Particle(mesonIndex);
842 Int_t mesonPdg = meson->GetPdgCode();
843 if(mesonPdg!=111 && mesonPdg!=221)
845 AliWarning(Form("Wrong pi0/eta PDG : %d",mesonPdg));
849 AliDebug(2,Form("%s, label %d",meson->GetName(), mesonIndex));
851 //Check if meson decayed into 2 daughters or if both were kept.
852 if(meson->GetNDaughters() != 2)
854 AliDebug(2,Form("Not overalapped. Number of daughters is %d, not 2",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)
867 AliDebug(2,Form("Not overalapped. PDG: daughter 1 = %d, of daughter 2 = %d",photon0->GetPdgCode(),photon1->GetPdgCode()));
871 AliDebug(2,Form("Daughter labels : photon0 = %d, photon1 = %d",iPhoton0,iPhoton1));
873 //Check if both photons contribute to the cluster
874 Bool_t okPhoton0 = kFALSE;
875 Bool_t okPhoton1 = kFALSE;
877 AliDebug(3,"Labels loop:");
879 Bool_t conversion = kFALSE;
881 for(Int_t i = 0; i < nlabels; i++)
883 AliDebug(3,Form("\t at begin:label %d/%d: %d, ok? photon1 %d, photon2 %d", i+1, nlabels, labels[i], okPhoton0, okPhoton1));
885 //If we already found both, break the loop
886 if(okPhoton0 && okPhoton1) break;
888 Int_t index = labels[i];
889 if (iPhoton0 == index)
894 else if (iPhoton1 == index)
900 //Trace back the mother in case it was a conversion
902 if(index >= stack->GetNtrack())
904 AliWarning(Form("Particle index %d larger than size of list %d!!",index,stack->GetNtrack()));
908 TParticle * daught = stack->Particle(index);
909 Int_t tmpindex = daught->GetFirstMother();
911 AliDebug(3,Form("\t Conversion? : mother %d",tmpindex));
915 //MC particle of interest is the mother
916 AliDebug(3,Form("\t \t parent index %d",tmpindex));
917 daught = stack->Particle(tmpindex);
918 if (iPhoton0 == tmpindex)
924 else if (iPhoton1 == tmpindex)
931 tmpindex = daught->GetFirstMother();
933 }//While to check if pi0/eta daughter was one of these contributors to the cluster
935 //if(i == 0 && (!okPhoton0 && !okPhoton1))
936 // AliDebug(1,Form("Something happens, first label should be from a photon decay!"));
938 }//loop on list of labels
940 //If both photons contribute tag as the corresponding meson.
941 if(okPhoton0 && okPhoton1)
943 AliDebug(2,Form("%s OVERLAPPED DECAY", meson->GetName()));
945 if(!CheckTagBit(tag,kMCConversion) && conversion) SetTagBit(tag,kMCConversion) ;
947 if(mesonPdg == 111) SetTagBit(tag,kMCPi0);
948 else SetTagBit(tag,kMCEta);
953 //________________________________________________________________________________________________________
954 void AliMCAnalysisUtils::CheckOverlapped2GammaDecay(const Int_t *labels, Int_t nlabels, Int_t mesonIndex,
955 const TClonesArray *mcparticles, Int_t & tag )
957 // Check if cluster is formed from the contribution of 2 decay photons from pi0 or eta. Input in AODMCParticles.
959 if(labels[0] < 0 || labels[0] > mcparticles->GetEntriesFast() || nlabels <= 1)
961 AliDebug(2,Form("Exit : label[0] %d, n primaries %d, nlabels %d",labels[0],mcparticles->GetEntriesFast(), nlabels));
965 AliAODMCParticle * meson = (AliAODMCParticle *) mcparticles->At(mesonIndex);
966 Int_t mesonPdg = meson->GetPdgCode();
967 if(mesonPdg != 111 && mesonPdg != 221)
969 AliWarning(Form("Wrong pi0/eta PDG : %d",mesonPdg));
973 AliDebug(2,Form("pdg %d, label %d, ndaughters %d", mesonPdg, mesonIndex, meson->GetNDaughters()));
976 if(meson->GetNDaughters() != 2)
978 AliDebug(2,Form("Not overalapped. Number of daughters is %d, not 2",meson->GetNDaughters()));
982 Int_t iPhoton0 = meson->GetDaughter(0);
983 Int_t iPhoton1 = meson->GetDaughter(1);
984 //if((iPhoton0 == -1) || (iPhoton1 == -1)){
986 // printf("AliMCAnalysisUtils::CheckOverlapped2GammaDecay(AOD) - Exit : Not overlapped. At least a daughter do not exists : d1 %d, d2 %d \n", iPhoton0, iPhoton1);
989 AliAODMCParticle *photon0 = (AliAODMCParticle *) mcparticles->At(iPhoton0);
990 AliAODMCParticle *photon1 = (AliAODMCParticle *) mcparticles->At(iPhoton1);
992 //Check if both daughters are photons
993 if(photon0->GetPdgCode() != 22 && photon1->GetPdgCode()!=22)
995 AliWarning(Form("Not overlapped. PDG: daughter 1 = %d, of daughter 2 = %d",photon0->GetPdgCode(),photon1->GetPdgCode()));
999 AliDebug(2,Form("Daughter labels : photon0 = %d, photon1 = %d",iPhoton0,iPhoton1));
1001 //Check if both photons contribute to the cluster
1002 Bool_t okPhoton0 = kFALSE;
1003 Bool_t okPhoton1 = kFALSE;
1005 AliDebug(3,"Labels loop:");
1007 Bool_t conversion = kFALSE;
1009 for(Int_t i = 0; i < nlabels; i++)
1011 AliDebug(3, Form("\t label %d/%d: %d, ok? %d, %d", i, nlabels, labels[i], okPhoton0, okPhoton1));
1013 if(labels[i]<0) continue;
1015 //If we already found both, break the loop
1016 if(okPhoton0 && okPhoton1) break;
1018 Int_t index = labels[i];
1019 if (iPhoton0 == index)
1024 else if (iPhoton1 == index)
1030 //Trace back the mother in case it was a conversion
1032 if(index >= mcparticles->GetEntriesFast())
1034 AliWarning(Form("Particle index %d larger than size of list %d!!",index,mcparticles->GetEntriesFast()));
1038 AliAODMCParticle * daught = (AliAODMCParticle*) mcparticles->At(index);
1039 Int_t tmpindex = daught->GetMother();
1040 AliDebug(3,Form("Conversion? : mother %d",tmpindex));
1044 //MC particle of interest is the mother
1045 AliDebug(3,Form("\t parent index %d",tmpindex));
1046 daught = (AliAODMCParticle*) mcparticles->At(tmpindex);
1047 //printf("tmpindex %d\n",tmpindex);
1048 if (iPhoton0 == tmpindex)
1054 else if (iPhoton1 == tmpindex)
1061 tmpindex = daught->GetMother();
1063 }//While to check if pi0/eta daughter was one of these contributors to the cluster
1065 //if(i == 0 && (!okPhoton0 && !okPhoton1)) AliDebug(1,"Something happens, first label should be from a photon decay!");
1067 }//loop on list of labels
1069 //If both photons contribute tag as the corresponding meson.
1070 if(okPhoton0 && okPhoton1)
1072 AliDebug(2,Form("%s OVERLAPPED DECAY",(TDatabasePDG::Instance()->GetParticle(mesonPdg))->GetName()));
1074 if(!CheckTagBit(tag,kMCConversion) && conversion)
1076 AliDebug(2,"Second decay photon produced a conversion");
1077 SetTagBit(tag,kMCConversion) ;
1080 if(mesonPdg == 111) SetTagBit(tag,kMCPi0);
1081 else SetTagBit(tag,kMCEta);
1086 //______________________________________________________________________________________________________
1087 void AliMCAnalysisUtils::CheckLostDecayPair(const TObjArray* arrayCluster, Int_t iMom, Int_t iParent,
1088 AliStack * stack, Int_t & tag)
1090 // Check on ESDs if the current decay photon has the second photon companion lost.
1092 if(!arrayCluster || iMom < 0 || iParent < 0|| !stack) return;
1094 TParticle * parent= stack->Particle(iParent);
1096 if(parent->GetNDaughters()!=2)
1098 SetTagBit(tag, kMCDecayPairLost);
1102 Int_t pairLabel = -1;
1103 if ( iMom != parent->GetDaughter(0) ) pairLabel = parent->GetDaughter(0);
1104 else if( iMom != parent->GetDaughter(1) ) pairLabel = parent->GetDaughter(1);
1108 SetTagBit(tag, kMCDecayPairLost);
1112 for(Int_t iclus = 0; iclus < arrayCluster->GetEntriesFast(); iclus++)
1114 AliVCluster * cluster = (AliVCluster*) arrayCluster->At(iclus);
1115 for(UInt_t ilab = 0; ilab< cluster->GetNLabels(); ilab++)
1117 Int_t label = cluster->GetLabels()[ilab];
1118 if(label==pairLabel)
1120 SetTagBit(tag, kMCDecayPairInCalo);
1123 else if(label== iParent || label== iMom)
1127 else // check the ancestry
1129 TParticle * mother = stack->Particle(label);
1130 Int_t momPDG = TMath::Abs(mother->GetPdgCode());
1131 if(momPDG!=11 && momPDG!=22) continue;
1133 //Check if "mother" of entity is converted, if not, get the first non converted mother
1134 Int_t iParentClus = mother->GetFirstMother();
1135 if(iParentClus < 0) continue;
1137 TParticle * parentClus = stack->Particle(iParentClus);
1138 if(!parentClus) continue;
1140 Int_t parentClusPDG = TMath::Abs(parentClus->GetPdgCode());
1141 Int_t parentClusStatus = parentClus->GetStatusCode();
1143 if( parentClusPDG != 22 && parentClusPDG != 11 && parentClusStatus != 0) continue;
1145 //printf("Conversion\n");
1147 //Check if the mother is photon or electron with status not stable
1148 while ((parentClusPDG == 22 || parentClusPDG == 11) && parentClusStatus != 1)
1151 label = iParentClus;
1152 momPDG = parentClusPDG;
1154 iParentClus = parentClus->GetFirstMother();
1155 if(iParentClus < 0) break;
1157 parentClus = stack->Particle(iParentClus);
1158 if(!parentClus) break;
1160 parentClusPDG = TMath::Abs(parentClus->GetPdgCode());
1161 parentClusStatus = parentClus->GetStatusCode() ;
1164 if((momPDG == 22 || parentClusPDG ==22) && (label==pairLabel || iParentClus == pairLabel))
1166 SetTagBit(tag, kMCDecayPairInCalo);
1167 //printf("Conversion is paired\n");
1176 SetTagBit(tag, kMCDecayPairLost);
1180 //______________________________________________________________________________________________________
1181 void AliMCAnalysisUtils::CheckLostDecayPair(const TObjArray * arrayCluster,Int_t iMom, Int_t iParent,
1182 const TClonesArray* mcparticles, Int_t & tag)
1184 // Check on AODs if the current decay photon has the second photon companion lost.
1186 if(!arrayCluster || iMom < 0 || iParent < 0|| !mcparticles) return;
1188 AliAODMCParticle * parent = (AliAODMCParticle*) mcparticles->At(iParent);
1190 //printf("*** Check label %d with parent %d\n",iMom, iParent);
1192 if(parent->GetNDaughters()!=2)
1194 SetTagBit(tag, kMCDecayPairLost);
1195 //printf("\t ndaugh = %d\n",parent->GetNDaughters());
1199 Int_t pairLabel = -1;
1200 if ( iMom != parent->GetDaughter(0) ) pairLabel = parent->GetDaughter(0);
1201 else if( iMom != parent->GetDaughter(1) ) pairLabel = parent->GetDaughter(1);
1205 //printf("\t pair Label not found = %d\n",pairLabel);
1206 SetTagBit(tag, kMCDecayPairLost);
1210 //printf("\t *** find pair %d\n",pairLabel);
1212 for(Int_t iclus = 0; iclus < arrayCluster->GetEntriesFast(); iclus++)
1214 AliVCluster * cluster = (AliVCluster*) arrayCluster->At(iclus);
1215 //printf("\t \t ** Cluster %d, nlabels %d\n",iclus,cluster->GetNLabels());
1216 for(UInt_t ilab = 0; ilab< cluster->GetNLabels(); ilab++)
1218 Int_t label = cluster->GetLabels()[ilab];
1220 //printf("\t \t label %d\n",label);
1222 if(label==pairLabel)
1224 //printf("\t \t Pair found\n");
1225 SetTagBit(tag, kMCDecayPairInCalo);
1228 else if(label== iParent || label== iMom)
1230 //printf("\t \t skip\n");
1233 else // check the ancestry
1235 AliAODMCParticle * mother = (AliAODMCParticle*) mcparticles->At(label);
1236 Int_t momPDG = TMath::Abs(mother->GetPdgCode());
1237 if(momPDG!=11 && momPDG!=22)
1239 //printf("\t \t skip, pdg %d\n",momPDG);
1243 //Check if "mother" of entity is converted, if not, get the first non converted mother
1244 Int_t iParentClus = mother->GetMother();
1245 if(iParentClus < 0) continue;
1247 AliAODMCParticle * parentClus = (AliAODMCParticle*) mcparticles->At(iParentClus);
1248 if(!parentClus) continue;
1250 Int_t parentClusPDG = TMath::Abs(parentClus->GetPdgCode());
1251 Int_t parentClusStatus = parentClus->GetStatus();
1253 if( parentClusPDG != 22 && parentClusPDG != 11 && parentClusStatus != 0)
1255 //printf("\t \t skip, not a conversion, parent: pdg %d, status %d\n",parentClusPDG,parentClusStatus);
1259 //printf("\t \t Conversion\n");
1261 //Check if the mother is photon or electron with status not stable
1262 while ((parentClusPDG == 22 || parentClusPDG == 11) && parentClusStatus != 1)
1265 label = iParentClus;
1266 momPDG = parentClusPDG;
1268 iParentClus = parentClus->GetMother();
1269 if(iParentClus < 0) break;
1271 parentClus = (AliAODMCParticle*) mcparticles->At(iParentClus);
1272 if(!parentClus) break;
1274 parentClusPDG = TMath::Abs(parentClus->GetPdgCode());
1275 parentClusStatus = parentClus->GetStatus() ;
1278 if((momPDG == 22 || parentClusPDG ==22) && (label==pairLabel || iParentClus == pairLabel))
1280 SetTagBit(tag, kMCDecayPairInCalo);
1281 //printf("\t \t Conversion is paired: mom %d, parent %d\n",label,iParentClus);
1286 //printf("\t \t Skip, finally label %d, pdg %d, parent label %d, pdg %d, status %d\n",label,momPDG,iParentClus,parentClusPDG,parentClusStatus);
1295 SetTagBit(tag, kMCDecayPairLost);
1299 //_____________________________________________________________________
1300 TList * AliMCAnalysisUtils::GetJets(const AliCaloTrackReader * reader)
1302 // Return list of jets (TParticles) and index of most likely parton that originated it.
1304 AliStack * stack = reader->GetStack();
1305 Int_t iEvent = reader->GetEventNumber();
1306 AliGenEventHeader * geh = reader->GetGenEventHeader();
1307 if(fCurrentEvent!=iEvent){
1308 fCurrentEvent = iEvent;
1309 fJetsList = new TList;
1310 Int_t nTriggerJets = 0;
1311 Float_t tmpjet[]={0,0,0,0};
1313 //printf("Event %d %d\n",fCurrentEvent,iEvent);
1314 //Get outgoing partons
1315 if(stack->GetNtrack() < 8) return fJetsList;
1316 TParticle * parton1 = stack->Particle(6);
1317 TParticle * parton2 = stack->Particle(7);
1319 AliDebug(2,Form("Parton 6 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f",
1320 parton1->GetName(),parton1->Pt(),parton1->Energy(),parton1->Phi()*TMath::RadToDeg(),parton1->Eta()));
1321 AliDebug(2,Form("Parton 7 : %s, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f",
1322 parton2->GetName(),parton2->Pt(),parton2->Energy(),parton2->Phi()*TMath::RadToDeg(),parton2->Eta()));
1324 // //Trace the jet from the mother parton
1331 // TParticle * tmptmp = new TParticle;
1332 // for(Int_t i = 0; i< stack->GetNprimary(); i++){
1333 // tmptmp = stack->Particle(i);
1335 // if(tmptmp->GetStatusCode() == 1){
1336 // pt = tmptmp->Pt();
1337 // e = tmptmp->Energy();
1338 // Int_t imom = tmptmp->GetFirstMother();
1340 // //printf("1st imom %d\n",imom);
1343 // tmptmp = stack->Particle(imom);
1344 // imom = tmptmp->GetFirstMother();
1345 // //printf("imom %d \n",imom);
1347 // //printf("Last imom %d %d\n",imom1, imom);
1352 // else if (imom1 == 7){
1359 // printf("JET 1, pt %2.2f, e %2.2f; JET 2, pt %2.2f, e %2.2f \n",pt1,e1,pt2,e2);
1361 //Get the jet, different way for different generator
1363 if(fMCGenerator == kPythia)
1365 TParticle * jet = 0x0;
1366 AliGenPythiaEventHeader* pygeh= (AliGenPythiaEventHeader*) geh;
1367 nTriggerJets = pygeh->NTriggerJets();
1368 AliDebug(2,Form("PythiaEventHeader: Njets: %d",nTriggerJets));
1370 for(Int_t i = 0; i< nTriggerJets; i++)
1372 pygeh->TriggerJet(i, tmpjet);
1373 jet = new TParticle(94, 21, -1, -1, -1, -1, tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3], 0,0,0,0);
1374 //Assign an outgoing parton as mother
1375 Float_t phidiff1 = TMath::Abs(jet->Phi()-parton1->Phi());
1376 Float_t phidiff2 = TMath::Abs(jet->Phi()-parton2->Phi());
1377 if(phidiff1 > phidiff2) jet->SetFirstMother(7);
1378 else jet->SetFirstMother(6);
1380 AliDebug(1,Form("PYTHIA Jet %d: mother %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f",
1381 i, jet->GetFirstMother(),jet->Pt(),jet->Energy(),jet->Phi()*TMath::RadToDeg(),jet->Eta()));
1382 fJetsList->Add(jet);
1384 }//Pythia triggered jets
1386 else if (fMCGenerator == kHerwig)
1390 TParticle * tmp = parton1;
1391 if(parton1->GetPdgCode()!=22)
1394 if(tmp->GetFirstDaughter()==-1) return fJetsList;
1395 tmp = stack->Particle(tmp->GetFirstDaughter());
1396 pdg = tmp->GetPdgCode();
1399 //Add found jet to list
1400 TParticle *jet1 = new TParticle(*tmp);
1401 jet1->SetFirstMother(6);
1402 fJetsList->Add(jet1);
1403 //printf("jet 1: first daughter %d, last daughter %d\n", tmp->GetFirstDaughter(), tmp->GetLastDaughter());
1404 //tmp = stack->Particle(tmp->GetFirstDaughter());
1407 AliDebug(1,Form("HERWIG Jet 1: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f",
1408 jet1->GetFirstMother(),jet1->GetStatusCode(),jet1->Pt(),jet1->Energy(),jet1->Phi()*TMath::RadToDeg(),jet1->Eta()));
1414 if(parton2->GetPdgCode()!=22)
1418 if(tmp->GetFirstDaughter()==-1) return fJetsList;
1419 tmp = stack->Particle(tmp->GetFirstDaughter());
1420 pdg = tmp->GetPdgCode();
1423 //Add found jet to list
1424 TParticle *jet2 = new TParticle(*tmp);
1425 jet2->SetFirstMother(7);
1426 fJetsList->Add(jet2);
1428 AliDebug(2,Form("HERWIG Jet 2: mother %d, status %d, pt %2.2f,E %2.2f, phi %2.2f, eta %2.2f",
1429 jet2->GetFirstMother(),jet2->GetStatusCode(),jet2->Pt(),jet2->Energy(),jet2->Phi()*TMath::RadToDeg(),jet2->Eta()));
1430 //Int_t first = tmp->GetFirstDaughter();
1431 //Int_t last = tmp->GetLastDaughter();
1432 //printf("jet 2: first daughter %d, last daughter %d, pdg %d\n",first, last, tmp->GetPdgCode());
1433 // for(Int_t d = first ; d < last+1; d++){
1434 // tmp = stack->Particle(d);
1435 // if(i == tmp->GetFirstMother())
1436 // printf("Daughter n %d, Mother %d, name %s, status %d, pT %2.2f,E %2.2f, phi %2.2f, eta %2.2f \n",
1437 // d,tmp->GetFirstMother(), tmp->GetName(), tmp->GetStatusCode(),tmp->Pt(),tmp->Energy(),tmp->Phi()*TMath::RadToDeg(),tmp->Eta());
1441 }//Herwig generated jets
1448 //__________________________________________________________________________________________________________
1449 TLorentzVector AliMCAnalysisUtils::GetDaughter(Int_t idaugh, Int_t label,
1450 const AliCaloTrackReader* reader,
1451 Int_t & pdg, Int_t & status, Bool_t & ok, Int_t & daughlabel)
1453 // Return the kinematics of the particle that generated the signal, its pdg and its status and its label mother.
1454 fDaughMom.SetPxPyPzE(0,0,0,0);
1456 if(reader->ReadStack())
1458 if(!reader->GetStack())
1460 AliWarning("Stack is not available, check analysis settings in configuration file!!");
1466 Int_t nprimaries = reader->GetStack()->GetNtrack();
1467 if(label >= 0 && label < nprimaries)
1469 TParticle * momP = reader->GetStack()->Particle(label);
1470 daughlabel = momP->GetDaughter(idaugh);
1472 if(daughlabel < 0 || daughlabel >= nprimaries)
1478 TParticle * daughP = reader->GetStack()->Particle(daughlabel);
1479 daughP->Momentum(fDaughMom);
1480 pdg = daughP->GetPdgCode();
1481 status = daughP->GetStatusCode();
1489 else if(reader->ReadAODMCParticles())
1491 TClonesArray* mcparticles = reader->GetAODMCParticles();
1494 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1500 Int_t nprimaries = mcparticles->GetEntriesFast();
1501 if(label >= 0 && label < nprimaries)
1503 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1504 daughlabel = momP->GetDaughter(idaugh);
1506 if(daughlabel < 0 || daughlabel >= nprimaries)
1512 AliAODMCParticle * daughP = (AliAODMCParticle *) mcparticles->At(daughlabel);
1513 fDaughMom.SetPxPyPzE(daughP->Px(),daughP->Py(),daughP->Pz(),daughP->E());
1514 pdg = daughP->GetPdgCode();
1515 status = daughP->GetStatus();
1529 //______________________________________________________________________________________________________
1530 TLorentzVector AliMCAnalysisUtils::GetMother(Int_t label, const AliCaloTrackReader* reader, Bool_t & ok)
1532 // Return the kinematics of the particle that generated the signal.
1534 Int_t pdg = -1; Int_t status = -1; Int_t momlabel = -1;
1535 return GetMother(label,reader,pdg,status, ok,momlabel);
1538 //_________________________________________________________________________________________
1539 TLorentzVector AliMCAnalysisUtils::GetMother(Int_t label, const AliCaloTrackReader* reader,
1540 Int_t & pdg, Int_t & status, Bool_t & ok)
1542 // Return the kinematics of the particle that generated the signal.
1544 Int_t momlabel = -1;
1545 return GetMother(label,reader,pdg,status, ok,momlabel);
1548 //______________________________________________________________________________________________________
1549 TLorentzVector AliMCAnalysisUtils::GetMother(Int_t label, const AliCaloTrackReader* reader,
1550 Int_t & pdg, Int_t & status, Bool_t & ok, Int_t & momlabel)
1552 // Return the kinematics of the particle that generated the signal, its pdg and its status and its label mother.
1554 fMotherMom.SetPxPyPzE(0,0,0,0);
1556 if(reader->ReadStack())
1558 if(!reader->GetStack())
1560 AliWarning("Stack is not available, check analysis settings in configuration file, STOP!!");
1565 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1567 TParticle * momP = reader->GetStack()->Particle(label);
1568 momP->Momentum(fMotherMom);
1569 pdg = momP->GetPdgCode();
1570 status = momP->GetStatusCode();
1571 momlabel = momP->GetFirstMother();
1579 else if(reader->ReadAODMCParticles())
1581 TClonesArray* mcparticles = reader->GetAODMCParticles();
1584 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1590 Int_t nprimaries = mcparticles->GetEntriesFast();
1591 if(label >= 0 && label < nprimaries)
1593 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1594 fMotherMom.SetPxPyPzE(momP->Px(),momP->Py(),momP->Pz(),momP->E());
1595 pdg = momP->GetPdgCode();
1596 status = momP->GetStatus();
1597 momlabel = momP->GetMother();
1611 //___________________________________________________________________________________
1612 TLorentzVector AliMCAnalysisUtils::GetMotherWithPDG(Int_t label, Int_t pdg,
1613 const AliCaloTrackReader* reader,
1614 Bool_t & ok, Int_t & momlabel)
1616 // Return the kinematics of the particle that generated the signal.
1618 fGMotherMom.SetPxPyPzE(0,0,0,0);
1620 if(reader->ReadStack())
1622 if(!reader->GetStack())
1624 AliWarning("Stack is not available, check analysis settings in configuration file!!");
1630 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1632 TParticle * momP = reader->GetStack()->Particle(label);
1634 Int_t grandmomLabel = momP->GetFirstMother();
1635 Int_t grandmomPDG = -1;
1636 TParticle * grandmomP = 0x0;
1637 while (grandmomLabel >=0 )
1639 grandmomP = reader->GetStack()->Particle(grandmomLabel);
1640 grandmomPDG = grandmomP->GetPdgCode();
1641 if(grandmomPDG==pdg)
1643 momlabel = grandmomLabel;
1644 fGMotherMom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->Energy());
1648 grandmomLabel = grandmomP->GetFirstMother();
1652 if(grandmomPDG!=pdg) AliInfo(Form("Mother with PDG %d, not found! \n",pdg));
1655 else if(reader->ReadAODMCParticles())
1657 TClonesArray* mcparticles = reader->GetAODMCParticles();
1660 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1666 Int_t nprimaries = mcparticles->GetEntriesFast();
1667 if(label >= 0 && label < nprimaries)
1669 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1671 Int_t grandmomLabel = momP->GetMother();
1672 Int_t grandmomPDG = -1;
1673 AliAODMCParticle * grandmomP = 0x0;
1674 while (grandmomLabel >=0 )
1676 grandmomP = (AliAODMCParticle *) mcparticles->At(grandmomLabel);
1677 grandmomPDG = grandmomP->GetPdgCode();
1678 if(grandmomPDG==pdg)
1680 //printf("AliMCAnalysisUtils::GetMotherWithPDG(AOD) - mother with PDG %d FOUND! \n",pdg);
1681 momlabel = grandmomLabel;
1682 fGMotherMom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->E());
1686 grandmomLabel = grandmomP->GetMother();
1690 if(grandmomPDG!=pdg) AliInfo(Form("Mother with PDG %d, NOT found!",pdg));
1700 //______________________________________________________________________________________________
1701 TLorentzVector AliMCAnalysisUtils::GetGrandMother(Int_t label, const AliCaloTrackReader* reader,
1702 Int_t & pdg, Int_t & status, Bool_t & ok,
1703 Int_t & grandMomLabel, Int_t & greatMomLabel)
1705 // Return the kinematics of the particle that generated the signal.
1707 fGMotherMom.SetPxPyPzE(0,0,0,0);
1709 if(reader->ReadStack())
1711 if(!reader->GetStack())
1713 AliWarning("Stack is not available, check analysis settings in configuration file, STOP!!");
1719 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1721 TParticle * momP = reader->GetStack()->Particle(label);
1723 grandMomLabel = momP->GetFirstMother();
1725 TParticle * grandmomP = 0x0;
1727 if (grandMomLabel >=0 )
1729 grandmomP = reader->GetStack()->Particle(grandMomLabel);
1730 pdg = grandmomP->GetPdgCode();
1731 status = grandmomP->GetStatusCode();
1733 fGMotherMom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->Energy());
1734 greatMomLabel = grandmomP->GetFirstMother();
1739 else if(reader->ReadAODMCParticles())
1741 TClonesArray* mcparticles = reader->GetAODMCParticles();
1744 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1750 Int_t nprimaries = mcparticles->GetEntriesFast();
1751 if(label >= 0 && label < nprimaries)
1753 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1755 grandMomLabel = momP->GetMother();
1757 AliAODMCParticle * grandmomP = 0x0;
1759 if(grandMomLabel >=0 )
1761 grandmomP = (AliAODMCParticle *) mcparticles->At(grandMomLabel);
1762 pdg = grandmomP->GetPdgCode();
1763 status = grandmomP->GetStatus();
1765 fGMotherMom.SetPxPyPzE(grandmomP->Px(),grandmomP->Py(),grandmomP->Pz(),grandmomP->E());
1766 greatMomLabel = grandmomP->GetMother();
1777 //_______________________________________________________________________________________________________________
1778 void AliMCAnalysisUtils::GetMCDecayAsymmetryAngleForPDG(Int_t label, Int_t pdg, const AliCaloTrackReader* reader,
1779 Float_t & asym, Float_t & angle, Bool_t & ok)
1781 // In case of an eta or pi0 decay into 2 photons, get the asymmetry in the energy of the photons.
1783 if(reader->ReadStack())
1785 if(!reader->GetStack())
1787 AliWarning("Stack is not available, check analysis settings in configuration file, STOP!!");
1791 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1793 TParticle * momP = reader->GetStack()->Particle(label);
1795 Int_t grandmomLabel = momP->GetFirstMother();
1796 Int_t grandmomPDG = -1;
1797 TParticle * grandmomP = 0x0;
1798 while (grandmomLabel >=0 )
1800 grandmomP = reader->GetStack()->Particle(grandmomLabel);
1801 grandmomPDG = grandmomP->GetPdgCode();
1803 if(grandmomPDG==pdg) break;
1805 grandmomLabel = grandmomP->GetFirstMother();
1809 if(grandmomPDG==pdg && grandmomP->GetNDaughters()==2)
1811 TParticle * d1 = reader->GetStack()->Particle(grandmomP->GetDaughter(0));
1812 TParticle * d2 = reader->GetStack()->Particle(grandmomP->GetDaughter(1));
1813 if(d1->GetPdgCode() == 22 && d1->GetPdgCode() == 22)
1815 asym = (d1->Energy()-d2->Energy())/grandmomP->Energy();
1816 d1->Momentum(fDaughMom );
1817 d2->Momentum(fDaughMom2);
1818 angle = fDaughMom.Angle(fDaughMom2.Vect());
1824 AliInfo(Form("Mother with PDG %d, not found!",pdg));
1829 else if(reader->ReadAODMCParticles())
1831 TClonesArray* mcparticles = reader->GetAODMCParticles();
1834 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1840 Int_t nprimaries = mcparticles->GetEntriesFast();
1841 if(label >= 0 && label < nprimaries)
1843 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1845 Int_t grandmomLabel = momP->GetMother();
1846 Int_t grandmomPDG = -1;
1847 AliAODMCParticle * grandmomP = 0x0;
1848 while (grandmomLabel >=0 )
1850 grandmomP = (AliAODMCParticle *) mcparticles->At(grandmomLabel);
1851 grandmomPDG = grandmomP->GetPdgCode();
1853 if(grandmomPDG==pdg) break;
1855 grandmomLabel = grandmomP->GetMother();
1859 if(grandmomPDG==pdg && grandmomP->GetNDaughters()==2)
1861 AliAODMCParticle * d1 = (AliAODMCParticle *) mcparticles->At(grandmomP->GetDaughter(0));
1862 AliAODMCParticle * d2 = (AliAODMCParticle *) mcparticles->At(grandmomP->GetDaughter(1));
1863 if(d1->GetPdgCode() == 22 && d1->GetPdgCode() == 22)
1865 asym = (d1->E()-d2->E())/grandmomP->E();
1866 fDaughMom .SetPxPyPzE(d1->Px(),d1->Py(),d1->Pz(),d1->E());
1867 fDaughMom2.SetPxPyPzE(d2->Px(),d2->Py(),d2->Pz(),d2->E());
1868 angle = fDaughMom.Angle(fDaughMom2.Vect());
1874 AliInfo(Form("Mother with PDG %d, not found! \n",pdg));
1884 //_________________________________________________________________________________________________
1885 Int_t AliMCAnalysisUtils::GetNDaughters(Int_t label, const AliCaloTrackReader* reader, Bool_t & ok)
1887 // Return the the number of daughters of a given MC particle.
1889 if(reader->ReadStack())
1891 if(!reader->GetStack())
1893 AliWarning("Stack is not available, check analysis settings in configuration file, STOP!!");
1898 if(label >= 0 && label < reader->GetStack()->GetNtrack())
1900 TParticle * momP = reader->GetStack()->Particle(label);
1902 return momP->GetNDaughters();
1910 else if(reader->ReadAODMCParticles())
1912 TClonesArray* mcparticles = reader->GetAODMCParticles();
1915 AliWarning("AODMCParticles is not available, check analysis settings in configuration file!!");
1921 Int_t nprimaries = mcparticles->GetEntriesFast();
1922 if(label >= 0 && label < nprimaries)
1924 AliAODMCParticle * momP = (AliAODMCParticle *) mcparticles->At(label);
1926 return momP->GetNDaughters();
1940 //_________________________________________________________________________________
1941 Int_t AliMCAnalysisUtils::GetNOverlaps(const Int_t * label, UInt_t nlabels,
1942 Int_t mctag, Int_t mesonLabel,
1943 AliCaloTrackReader * reader, Int_t *overpdg)
1945 // Compare the primary depositing more energy with the rest,
1946 // if no photon/electron (conversion) or neutral meson as comon ancestor, consider it as other particle contributing.
1947 // Give as input the meson label in case it was a pi0 or eta merged cluster.
1948 // Init overpdg with nlabels.
1950 Int_t ancPDG = 0, ancStatus = -1;
1951 TVector3 prodVertex;
1953 Int_t noverlaps = 0;
1956 for (UInt_t ilab = 1; ilab < nlabels; ilab++ )
1958 ancLabel = CheckCommonAncestor(label[0],label[ilab],reader,ancPDG,ancStatus,fMotherMom,prodVertex);
1960 //printf("Overlaps, i %d: Main Label %d, second label %d, ancestor: Label %d, pdg %d - tag %d \n",
1961 // ilab,label[0],label[ilab],ancLabel,ancPDG, mctag);
1963 Bool_t overlap = kFALSE;
1968 //printf("\t \t \t No Label = %d\n",ancLabel);
1970 else if( ( ancPDG==111 || ancPDG==221 ) && ( CheckTagBit(mctag,kMCPi0) || CheckTagBit(mctag,kMCEta)) && mesonLabel != ancLabel)
1972 //printf("\t \t meson Label %d, ancestor Label %d\n",mesonLabel,ancLabel);
1975 else if( ancPDG!=22 && TMath::Abs(ancPDG)!=11 && ancPDG != 111 && ancPDG != 221 )
1977 //printf("\t \t \t Non EM PDG = %d\n",ancPDG);
1981 if( !overlap ) continue ;
1983 // We have at least one overlap
1985 //printf("Overlap!!!!!!!!!!!!!!\n");
1989 // What is the origin of the overlap?
1990 Bool_t mOK = 0, gOK = 0;
1991 Int_t mpdg = -999999, gpdg = -1;
1992 Int_t mstatus = -1, gstatus = -1;
1993 Int_t gLabel = -1, ggLabel = -1;
1995 GetMother (label[ilab],reader,mpdg,mstatus,mOK);
1997 GetGrandMother(label[ilab],reader,gpdg,gstatus,gOK, gLabel,ggLabel);
1999 //printf("\t Overlap!, mother pdg %d; grand mother pdg %d",mpdg,gpdg);
2001 if( ( mpdg == 22 || TMath::Abs(mpdg==11) ) &&
2002 ( gpdg == 22 || TMath::Abs(gpdg==11) ) &&
2005 Int_t labeltmp = gLabel;
2006 while( ( gpdg == 22 || TMath::Abs(gpdg==11) ) && gLabel >=0 )
2009 fGMotherMom = GetGrandMother(labeltmp,reader,gpdg,gstatus,ok, gLabel,ggLabel);
2013 overpdg[noverlaps-1] = mpdg;
2020 //________________________________________________________
2021 void AliMCAnalysisUtils::Print(const Option_t * opt) const
2023 // Print some relevant parameters set for the analysis.
2028 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
2030 printf("Debug level = %d\n",fDebug);
2031 printf("MC Generator = %s\n",fMCGeneratorString.Data());
2036 //__________________________________________________
2037 void AliMCAnalysisUtils::PrintMCTag(Int_t tag) const
2039 // Print the assigned origins to this particle.
2041 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, unk %d, bad %d\n",
2043 CheckTagBit(tag,kMCPhoton),
2044 CheckTagBit(tag,kMCConversion),
2045 CheckTagBit(tag,kMCPrompt),
2046 CheckTagBit(tag,kMCFragmentation),
2047 CheckTagBit(tag,kMCISR),
2048 CheckTagBit(tag,kMCPi0Decay),
2049 CheckTagBit(tag,kMCEtaDecay),
2050 CheckTagBit(tag,kMCOtherDecay),
2051 CheckTagBit(tag,kMCPi0),
2052 CheckTagBit(tag,kMCEta),
2053 CheckTagBit(tag,kMCElectron),
2054 CheckTagBit(tag,kMCMuon),
2055 CheckTagBit(tag,kMCPion),
2056 CheckTagBit(tag,kMCProton),
2057 CheckTagBit(tag,kMCAntiNeutron),
2058 CheckTagBit(tag,kMCKaon),
2059 CheckTagBit(tag,kMCAntiProton),
2060 CheckTagBit(tag,kMCAntiNeutron),
2061 CheckTagBit(tag,kMCUnknown),
2062 CheckTagBit(tag,kMCBadLabel)
2066 //__________________________________________________
2067 void AliMCAnalysisUtils::SetMCGenerator(Int_t mcgen)
2069 // Set the generator type.
2071 fMCGenerator = mcgen ;
2072 if (mcgen == kPythia) fMCGeneratorString = "PYTHIA";
2073 else if(mcgen == kHerwig) fMCGeneratorString = "HERWIG";
2074 else if(mcgen == kHijing) fMCGeneratorString = "HIJING";
2077 fMCGeneratorString = "";
2078 fMCGenerator = kBoxLike ;
2083 //__________________________________________________
2084 void AliMCAnalysisUtils::SetMCGenerator(TString mcgen)
2086 // Set the generator type.
2088 fMCGeneratorString = mcgen ;
2090 if (mcgen == "PYTHIA") fMCGenerator = kPythia;
2091 else if(mcgen == "HERWIG") fMCGenerator = kHerwig;
2092 else if(mcgen == "HIJING") fMCGenerator = kHijing;
2095 fMCGenerator = kBoxLike;
2096 fMCGeneratorString = "" ;