1 /*************************************************************************
2 * Copyright(c) 1998-2009, 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 //#####################################################
18 //# Class AliDielectronMC #
19 //# Cut Class for Jpsi->e+e- analysis #
21 //# by WooJin J. Park, GSI / W.J.Park@gsi.de #
23 //#####################################################
25 #include <AliAnalysisManager.h>
26 #include <AliAODHandler.h>
27 #include <AliESDInputHandler.h>
28 #include <AliAODInputHandler.h>
29 #include <AliMCEventHandler.h>
30 #include <AliMCEvent.h>
31 #include <AliMCParticle.h>
32 #include <AliAODMCParticle.h>
33 #include <AliAODMCHeader.h>
35 #include <AliESDEvent.h>
36 #include <AliAODEvent.h>
37 #include <AliESDtrack.h>
38 #include <AliAODTrack.h>
41 #include <TClonesArray.h>
42 #include <TParticle.h>
43 #include <TMCProcess.h>
45 #include "AliDielectronSignalMC.h"
46 #include "AliDielectronMC.h"
49 ClassImp(AliDielectronMC)
51 AliDielectronMC* AliDielectronMC::fgInstance=0x0;
53 //____________________________________________________________
54 AliDielectronMC* AliDielectronMC::Instance()
57 // return pointer to singleton implementation
59 if (fgInstance) return fgInstance;
61 AnalysisType type=kUNSET;
63 if (AliAnalysisManager::GetAnalysisManager()){
64 if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()) type=kESD;
65 else if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()) type=kAOD;
67 AliMCEventHandler* mcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
68 if(type == kESD) hasMC=mcHandler!=0x0;
71 fgInstance=new AliDielectronMC(type);
73 fgInstance->SetHasMC(hasMC);
78 //____________________________________________________________
79 AliDielectronMC::AliDielectronMC(AnalysisType type):
87 // default constructor
92 //____________________________________________________________
93 AliDielectronMC::~AliDielectronMC()
101 //____________________________________________________________
102 void AliDielectronMC::Initialize()
105 // initialize MC class
107 if (!ConnectMCEvent()) AliError("Initialization of MC object failed!");
110 //____________________________________________________________
111 Int_t AliDielectronMC::GetNMCTracks()
114 // return the number of generated tracks from MC event
116 if(fAnaType == kESD){
117 if (!fMCEvent){ AliError("No fMCEvent"); return 0; }
118 return fMCEvent->GetNumberOfTracks();}
119 else if(fAnaType == kAOD){
120 if(!fMcArray) { AliError("No fMcArray"); return 0; }
121 return fMcArray->GetEntriesFast();
126 //____________________________________________________________
127 Int_t AliDielectronMC::GetNMCTracksFromStack()
130 // return the number of generated tracks from stack
132 if (!fStack){ AliError("No fStack"); return -999; }
133 return fStack->GetNtrack();
136 //____________________________________________________________
137 Int_t AliDielectronMC::GetNPrimary() const
140 // return the number of primary track from MC event
142 if (!fMCEvent){ AliError("No fMCEvent"); return 0; }
143 return fMCEvent->GetNumberOfPrimaries();
146 //____________________________________________________________
147 Int_t AliDielectronMC::GetNPrimaryFromStack()
150 // return the number of primary track from stack
152 if (!fStack){ AliError("No fStack"); return -999; }
153 return fStack->GetNprimary();
156 //____________________________________________________________
157 AliVParticle* AliDielectronMC::GetMCTrackFromMCEvent(Int_t label) const
160 // return MC track directly from MC event
161 // used not only for tracks but for mothers as well, therefore do not use abs(label)
163 if (label<0) return NULL;
164 AliVParticle * track=0x0;
165 if(fAnaType == kESD){
166 if (!fMCEvent){ AliError("No fMCEvent"); return NULL;}
167 track = fMCEvent->GetTrack(label); // tracks from MC event (ESD)
168 } else if(fAnaType == kAOD) {
169 if (!fMcArray){ AliError("No fMcArray"); return NULL;}
170 if (label>fMcArray->GetEntriesFast()) { AliDebug(10,Form("track %d out of array size %d",label,fMcArray->GetEntriesFast())); return NULL;}
171 track = (AliVParticle*)fMcArray->At(label); // tracks from MC event (AOD)
176 //____________________________________________________________
177 Bool_t AliDielectronMC::ConnectMCEvent()
180 // connect stack object from the mc handler
186 if(fAnaType == kESD){
187 AliMCEventHandler* mcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
188 if (!mcHandler){ /*AliError("Could not retrive MC event handler!");*/ return kFALSE; }
189 if (!mcHandler->InitOk() ) return kFALSE;
190 if (!mcHandler->TreeK() ) return kFALSE;
191 if (!mcHandler->TreeTR() ) return kFALSE;
193 AliMCEvent* mcEvent = mcHandler->MCEvent();
194 if (!mcEvent){ /*AliError("Could not retrieve MC event!");*/ return kFALSE; }
197 if (!UpdateStack()) return kFALSE;
199 else if(fAnaType == kAOD)
201 AliAODInputHandler* aodHandler=(AliAODInputHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
202 if (!aodHandler) return kFALSE;
203 AliAODEvent *aod=aodHandler->GetEvent();
204 if (!aod) return kFALSE;
206 fMcArray = dynamic_cast<TClonesArray*>(aod->FindListObject(AliAODMCParticle::StdBranchName()));
207 if (!fMcArray){ /*AliError("Could not retrieve MC array!");*/ return kFALSE; }
213 //____________________________________________________________
214 Bool_t AliDielectronMC::UpdateStack()
217 // update stack with new event
219 if (!fMCEvent){ AliError("No fMCEvent"); return kFALSE;}
220 AliStack* stack = fMCEvent->Stack();
221 if (!stack){ AliError("Could not retrive stack!"); return kFALSE; }
226 //____________________________________________________________
227 AliMCParticle* AliDielectronMC::GetMCTrack( const AliESDtrack* _track)
232 if (!fMCEvent){ AliError("No fMCEvent"); return NULL;}
233 Int_t nStack = fMCEvent->GetNumberOfTracks();
234 Int_t label = TMath::Abs(_track->GetLabel()); // negative label indicate poor matching quality
235 if(label>nStack)return NULL;
236 AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(label));
241 //____________________________________________________________
242 AliAODMCParticle* AliDielectronMC::GetMCTrack( const AliAODTrack* _track)
247 if(!fMcArray) { AliError("No fMcArray"); return NULL;}
248 Int_t nStack = fMcArray->GetEntriesFast();
249 Int_t label = TMath::Abs(_track->GetLabel()); // negative label indicate poor matching quality
250 if(label > nStack) return NULL;
251 AliAODMCParticle *mctrack = (AliAODMCParticle*)fMcArray->At(label);
255 //____________________________________________________________
256 TParticle* AliDielectronMC::GetMCTrackFromStack(const AliESDtrack* _track)
259 // return MC track from stack
261 Int_t label = TMath::Abs(_track->GetLabel());
262 if (!fStack) AliWarning("fStack is not available. Update stack first.");
263 TParticle* mcpart = fStack->Particle(label);
264 if (!mcpart) return NULL;
268 //____________________________________________________________
269 AliMCParticle* AliDielectronMC::GetMCTrackMother(const AliESDtrack* _track)
272 // return MC track mother
274 AliMCParticle* mcpart = GetMCTrack(_track);
275 if (!mcpart) return NULL;
276 if(mcpart->GetMother()<0) return NULL;
277 AliMCParticle* mcmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(mcpart->GetMother()));
278 if (!mcmother) return NULL;
282 //______________________________________________________________
283 AliAODMCParticle* AliDielectronMC::GetMCTrackMother(const AliAODTrack* _track)
286 // return MC track mother
288 AliAODMCParticle* mcpart = GetMCTrack(_track);
289 if (!mcpart) return NULL;
290 if(mcpart->GetMother() < 0) return NULL;
291 AliAODMCParticle* mcmother = dynamic_cast<AliAODMCParticle *>(fMcArray->At(mcpart->GetMother()));
292 if (!mcmother) return NULL;
295 //____________________________________________________________
296 AliMCParticle* AliDielectronMC::GetMCTrackMother(const AliMCParticle* _particle){
298 // return MC track mother
300 if(_particle->GetMother() < 0) return NULL;
301 AliMCParticle* mcmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(_particle->GetMother()));
305 //____________________________________________________________
306 AliAODMCParticle* AliDielectronMC::GetMCTrackMother(const AliAODMCParticle* _particle){
308 // return MC track mother
310 if( _particle->GetMother() < 0) return NULL;
311 AliAODMCParticle* mcmother = dynamic_cast<AliAODMCParticle *>(fMcArray->At(_particle->GetMother()));
315 //____________________________________________________________
316 TParticle* AliDielectronMC::GetMCTrackMotherFromStack(const AliESDtrack* _track)
319 // return MC track mother from stack
321 TParticle* mcpart = GetMCTrackFromStack(_track);
322 if ( !mcpart || mcpart->GetFirstMother()<=0 ) return NULL;
323 TParticle* mcmother = fStack->Particle(mcpart->GetFirstMother());
324 if (!mcmother) return NULL;
328 //____________________________________________________________
329 Int_t AliDielectronMC::GetMCPID(const AliESDtrack* _track)
332 // return PDG code of the track from the MC truth info
334 AliMCParticle* mcpart = GetMCTrack(_track);
335 if (!mcpart) return -999;
336 return mcpart->PdgCode();
339 //__________________________________________________________
340 Int_t AliDielectronMC::GetMCPID(const AliAODTrack* _track)
343 // return PDG code of the track from the MC truth info
345 AliAODMCParticle* mcpart = GetMCTrack(_track);
346 if (!mcpart) return -999;
347 return mcpart->PdgCode();
350 //____________________________________________________________
351 Int_t AliDielectronMC::GetMCPIDFromStack(const AliESDtrack* _track)
354 // return MC PDG code from stack
356 TParticle* mcpart = GetMCTrackFromStack(_track);
357 if (!mcpart) return -999;
358 return mcpart->GetPdgCode();
361 //____________________________________________________________
362 Int_t AliDielectronMC::GetMotherPDG( const AliESDtrack* _track)
365 // return PDG code of the mother track from the MC truth info
367 AliMCParticle* mcmother = GetMCTrackMother(_track);
368 if (!mcmother) return -999;
369 return mcmother->PdgCode();
372 //________________________________________________________
373 Int_t AliDielectronMC::GetMotherPDG( const AliAODTrack* _track)
376 // return PDG code of the mother track from the MC truth info
378 AliAODMCParticle* mcmother = GetMCTrackMother(_track);
379 if (!mcmother) return -999;
380 return mcmother->PdgCode();
383 //________________________________________________________
384 Int_t AliDielectronMC::GetMotherPDG( const AliMCParticle* _track)
387 // return PDG code of the mother track from the MC truth info
389 AliMCParticle* mcmother = GetMCTrackMother(_track);
390 if (!mcmother) return -999;
391 return mcmother->PdgCode();
394 //________________________________________________________
395 Int_t AliDielectronMC::GetMotherPDG( const AliAODMCParticle* _track)
398 // return PDG code of the mother track from the MC truth info
400 AliAODMCParticle* mcmother = GetMCTrackMother(_track);
401 if (!mcmother) return -999;
402 return mcmother->PdgCode();
405 //____________________________________________________________
406 Int_t AliDielectronMC::GetMotherPDGFromStack(const AliESDtrack* _track)
409 // return PDG code of the mother track from stack
411 TParticle* mcmother = GetMCTrackMotherFromStack(_track);
412 if (!mcmother) return -999;
413 return mcmother->GetPdgCode();
416 //____________________________________________________________
417 Int_t AliDielectronMC::GetMCProcess(const AliESDtrack* _track)
420 // return process number of the track
422 AliMCParticle* mcpart = GetMCTrack(_track);
423 if (!mcpart) return -999;
427 //____________________________________________________________
428 Int_t AliDielectronMC::GetMCProcessFromStack(const AliESDtrack* _track)
431 // return process number of the track
433 TParticle* mcpart = GetMCTrackFromStack(_track);
434 if (!mcpart) return -999;
435 return mcpart->GetUniqueID();
438 //____________________________________________________________
439 Int_t AliDielectronMC::NumberOfDaughters(const AliESDtrack* track)
442 // returns the number of daughters
444 AliMCParticle *mcmother=GetMCTrackMother(track);
445 if(!mcmother||!mcmother->Particle()) return -999;
446 // return mcmother->GetFirstDaughter()>0?mcmother->GetLastDaughter()-mcmother->GetFirstDaughter()+1:0;
447 return mcmother->Particle()->GetNDaughters();
450 //_________________________________________________________
451 Int_t AliDielectronMC::NumberOfDaughters(const AliAODTrack* track)
454 // returns the number of daughters
456 AliAODMCParticle *mcmother=GetMCTrackMother(track);
457 if(!mcmother) return -999;
458 return NumberOfDaughters(mcmother);
462 //____________________________________________________________
463 Int_t AliDielectronMC::NumberOfDaughters(const AliMCParticle* particle)
466 // returns the number of daughters
468 AliMCParticle *mcmother=GetMCTrackMother(particle);
469 if(!mcmother||!mcmother->Particle()) return -999;
470 //return mcmother->GetFirstDaughter()>0?mcmother->GetLastDaughter()-mcmother->GetFirstDaughter()+1:0;
471 return mcmother->Particle()->GetNDaughters();
474 //____________________________________________________________
475 Int_t AliDielectronMC::NumberOfDaughters(const AliAODMCParticle* particle)
478 // returns the number of daughters
480 AliAODMCParticle *mcmother=GetMCTrackMother(particle);
481 if(!mcmother) return -999;
482 return mcmother->GetNDaughters();
485 //____________________________________________________________
486 Int_t AliDielectronMC::GetMCProcessMother(const AliESDtrack* _track)
489 // return process number of the mother of the track
491 AliMCParticle* mcmother = GetMCTrackMother(_track);
492 if (!mcmother) return -999;
496 //____________________________________________________________
497 Int_t AliDielectronMC::GetMCProcessMotherFromStack(const AliESDtrack* _track)
500 // return process number of the mother of the track
502 TParticle* mcmother = GetMCTrackMotherFromStack(_track);
503 if (!mcmother) return -999;
504 return mcmother->GetUniqueID();
507 //____________________________________________________________
508 Bool_t AliDielectronMC::IsMCMotherToEE(const AliVParticle *particle, Int_t pdgMother)
511 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
513 if (fAnaType==kESD && !fMCEvent) return kFALSE;
514 if (fAnaType==kAOD && !fMcArray) return kFALSE;
515 if (!particle) return kFALSE;
517 if (particle->IsA()==AliMCParticle::Class()){
518 return IsMCMotherToEEesd(static_cast<const AliMCParticle*>(particle),pdgMother);
519 } else if (particle->IsA()==AliAODMCParticle::Class()){
520 return IsMCMotherToEEaod(static_cast<const AliAODMCParticle*>(particle),pdgMother);
522 AliError("Unknown particle type");
527 //____________________________________________________________
528 Bool_t AliDielectronMC::IsMCMotherToEEesd(const AliMCParticle *particle, Int_t pdgMother)
531 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
536 if (particle->PdgCode()!=pdgMother) return kFALSE;
537 Int_t ifirst = particle->GetFirstDaughter();
538 Int_t ilast = particle->GetLastDaughter();
540 //check number of daughters
541 if ((ilast-ifirst)!=1) return kFALSE;
542 AliMCParticle *firstD=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(ifirst));
543 AliMCParticle *secondD=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(ilast));
545 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
546 if (firstD->Charge()>0){
547 if (firstD->PdgCode()!=-11) return kFALSE;
548 if (secondD->PdgCode()!=11) return kFALSE;
550 if (firstD->PdgCode()!=11) return kFALSE;
551 if (secondD->PdgCode()!=-11) return kFALSE;
557 //____________________________________________________________
558 Bool_t AliDielectronMC::IsMCMotherToEEaod(const AliAODMCParticle *particle, Int_t pdgMother)
561 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
565 if (particle->GetPdgCode()!=pdgMother) return kFALSE;
566 if (particle->GetNDaughters()!=2) return kFALSE;
568 Int_t ifirst = particle->GetDaughter(0);
569 Int_t ilast = particle->GetDaughter(1);
571 //check number of daughters
572 if ((ilast-ifirst)!=1) return kFALSE;
574 AliAODMCParticle *firstD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ifirst));
575 AliAODMCParticle *secondD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ilast));
577 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
579 if (firstD->Charge()>0){
580 if (firstD->GetPdgCode()!=-11) return kFALSE;
581 if (secondD->GetPdgCode()!=11) return kFALSE;
583 if (firstD->GetPdgCode()!=11) return kFALSE;
584 if (secondD->GetPdgCode()!=-11) return kFALSE;
589 //____________________________________________________________
590 Int_t AliDielectronMC::GetLabelMotherWithPdg(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
593 // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
596 if (!fMCEvent) return -1;
597 return GetLabelMotherWithPdgESD(particle1, particle2, pdgMother);
599 else if (fAnaType==kAOD)
601 if (!fMcArray) return -1;
602 return GetLabelMotherWithPdgAOD(particle1, particle2, pdgMother);
608 //____________________________________________________________
609 Int_t AliDielectronMC::GetLabelMotherWithPdgESD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
612 // test if mother of particle 1 and 2 has pdgCode +-11 (electron),
613 // have the same mother and the mother had pdg code pdgMother
615 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
617 // negative label indicate poor matching quality
618 Int_t lblPart1 = TMath::Abs(particle1->GetLabel());
619 Int_t lblPart2 = TMath::Abs(particle2->GetLabel());
620 AliMCParticle *mcPart1=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(lblPart1));
621 AliMCParticle *mcPart2=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(lblPart2));
623 if (!mcPart1||!mcPart2) return -1;
625 Int_t lblMother1=mcPart1->GetMother();
626 Int_t lblMother2=mcPart2->GetMother();
627 AliMCParticle *mcMother1=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
629 if (!mcMother1) return -1;
630 if (lblMother1!=lblMother2) return -1;
631 if (TMath::Abs(mcPart1->PdgCode())!=11) return -1;
632 if (mcPart1->PdgCode()!=-mcPart2->PdgCode()) return -1;
633 if (mcMother1->PdgCode()!=pdgMother) return -1;
638 //____________________________________________________________
639 Int_t AliDielectronMC::GetLabelMotherWithPdgAOD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
642 // test if mother of particle 1 and 2 has pdgCode +-11 (electron),
643 // have the same mother and the mother had pdg code pdgMother
645 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
647 // negative label indicate poor matching quality
648 Int_t lblPart1 = TMath::Abs(particle1->GetLabel());
649 Int_t lblPart2 = TMath::Abs(particle2->GetLabel());
650 AliAODMCParticle *mcPart1=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(lblPart1));
651 AliAODMCParticle *mcPart2=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(lblPart2));
653 if (!mcPart1||!mcPart2) return -1;
655 Int_t lblMother1=mcPart1->GetMother();
656 Int_t lblMother2=mcPart2->GetMother();
657 AliAODMCParticle *mcMother1=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
659 if (!mcMother1) return -1;
660 if (lblMother1!=lblMother2) return -1;
661 if (TMath::Abs(mcPart1->GetPdgCode())!=11) return -1;
662 if (mcPart1->GetPdgCode()!=-mcPart2->GetPdgCode()) return -1;
663 if (mcMother1->GetPdgCode()!=pdgMother) return -1;
668 //____________________________________________________________
669 void AliDielectronMC::GetDaughters(const TObject *mother, AliVParticle* &d1, AliVParticle* &d2)
672 // Get First two daughters of the mother
679 if(!fMcArray) return;
680 const AliAODMCParticle *aodMother=static_cast<const AliAODMCParticle*>(mother);
681 lblD1=aodMother->GetDaughter(0);
682 lblD2=aodMother->GetDaughter(1);
683 d1 = (AliVParticle*)fMcArray->At(lblD1);
684 d2 = (AliVParticle*)fMcArray->At(lblD2);
685 } else if (fAnaType==kESD){
686 if (!fMCEvent) return;
687 const AliMCParticle *aodMother=static_cast<const AliMCParticle*>(mother);
688 lblD1=aodMother->GetFirstDaughter();
689 lblD2=aodMother->GetLastDaughter();
690 d1=fMCEvent->GetTrack(lblD1);
691 d2=fMCEvent->GetTrack(lblD2);
696 //________________________________________________________________________________
697 Int_t AliDielectronMC::GetMothersLabel(Int_t daughterLabel) const {
699 // Get the label of the mother for particle with label daughterLabel
700 // NOTE: for tracks, the absolute label should be passed
702 if(daughterLabel<0) return -1;
703 if (fAnaType==kAOD) {
704 if(!fMcArray) return -1;
705 if(GetMCTrackFromMCEvent(daughterLabel))
706 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(daughterLabel)))->GetMother();
707 } else if(fAnaType==kESD) {
708 if (!fMCEvent) return -1;
709 if(GetMCTrackFromMCEvent(daughterLabel))
710 return (static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(daughterLabel)))->GetMother();
716 //________________________________________________________________________________
717 Int_t AliDielectronMC::GetPdgFromLabel(Int_t label) const {
719 // Get particle code using the label from stack
720 // NOTE: for tracks, the absolute label should be passed
722 if(label<0) return 0;
724 if(!fMcArray) return 0;
725 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label)))->PdgCode();
726 } else if(fAnaType==kESD) {
727 if (!fMCEvent) return 0;
728 return (static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(label)))->PdgCode();
734 //________________________________________________________________________________
735 Bool_t AliDielectronMC::ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion, Bool_t checkBothCharges) const {
737 // Test the PDG codes of particles with the required ones
739 Bool_t result = kTRUE;
740 Int_t absRequiredPDG = TMath::Abs(requiredPDG);
742 switch(absRequiredPDG) {
744 result = kTRUE; // PDG not required (any code will do fine)
746 case 100: // light flavoured mesons
748 result = TMath::Abs(particlePDG)>=100 && TMath::Abs(particlePDG)<=199;
750 if(requiredPDG>0) result = particlePDG>=100 && particlePDG<=199;
751 if(requiredPDG<0) result = particlePDG>=-199 && particlePDG<=-100;
754 case 1000: // light flavoured baryons
756 result = TMath::Abs(particlePDG)>=1000 && TMath::Abs(particlePDG)<=1999;
758 if(requiredPDG>0) result = particlePDG>=1000 && particlePDG<=1999;
759 if(requiredPDG<0) result = particlePDG>=-1999 && particlePDG<=-1000;
762 case 200: // light flavoured mesons
764 result = TMath::Abs(particlePDG)>=200 && TMath::Abs(particlePDG)<=299;
766 if(requiredPDG>0)result = particlePDG>=200 && particlePDG<=299;
767 if(requiredPDG<0)result = particlePDG>=-299 && particlePDG<=-200;
770 case 2000: // light flavoured baryons
772 result = TMath::Abs(particlePDG)>=2000 && TMath::Abs(particlePDG)<=2999;
774 if(requiredPDG>0) result = particlePDG>=2000 && particlePDG<=2999;
775 if(requiredPDG<0) result = particlePDG>=-2999 && particlePDG<=-2000;
778 case 300: // all strange mesons
780 result = TMath::Abs(particlePDG)>=300 && TMath::Abs(particlePDG)<=399;
782 if(requiredPDG>0) result = particlePDG>=300 && particlePDG<=399;
783 if(requiredPDG<0) result = particlePDG>=-399 && particlePDG<=-300;
786 case 3000: // all strange baryons
788 result = TMath::Abs(particlePDG)>=3000 && TMath::Abs(particlePDG)<=3999;
790 if(requiredPDG>0) result = particlePDG>=3000 && particlePDG<=3999;
791 if(requiredPDG<0) result = particlePDG>=-3999 && particlePDG<=-3000;
794 case 400: // all charmed mesons
796 result = TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=499;
798 if(requiredPDG>0) result = particlePDG>=400 && particlePDG<=499;
799 if(requiredPDG<0) result = particlePDG>=-499 && particlePDG<=-400;
802 case 401: // open charm mesons
804 result = TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439;
806 if(requiredPDG>0) result = particlePDG>=400 && particlePDG<=439;
807 if(requiredPDG<0) result = particlePDG>=-439 && particlePDG<=-400;
810 case 402: // open charm mesons and baryons together
812 result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439) ||
813 (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399);
815 if(requiredPDG>0) result = (particlePDG>=400 && particlePDG<=439) ||
816 (particlePDG>=4000 && particlePDG<=4399);
817 if(requiredPDG<0) result = (particlePDG>=-439 && particlePDG<=-400) ||
818 (particlePDG>=-4399 && particlePDG<=-4000);
821 case 403: // all charm hadrons
823 result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=499) ||
824 (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999);
826 if(requiredPDG>0) result = (particlePDG>=400 && particlePDG<=499) ||
827 (particlePDG>=4000 && particlePDG<=4999);
828 if(requiredPDG<0) result = (particlePDG>=-499 && particlePDG<=-400) ||
829 (particlePDG>=-4999 && particlePDG<=-4000);
832 case 4000: // all charmed baryons
834 result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999;
836 if(requiredPDG>0) result = particlePDG>=4000 && particlePDG<=4999;
837 if(requiredPDG<0) result = particlePDG>=-4999 && particlePDG<=-4000;
840 case 4001: // open charm baryons
842 result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399;
844 if(requiredPDG>0) result = particlePDG>=4000 && particlePDG<=4399;
845 if(requiredPDG<0) result = particlePDG>=-4399 && particlePDG<=-4000;
848 case 500: // all beauty mesons
850 result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599;
852 if(requiredPDG>0) result = particlePDG>=500 && particlePDG<=599;
853 if(requiredPDG<0) result = particlePDG>=-599 && particlePDG<=-500;
856 case 501: // open beauty mesons
858 result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549;
860 if(requiredPDG>0) result = particlePDG>=500 && particlePDG<=549;
861 if(requiredPDG<0) result = particlePDG>=-549 && particlePDG<=-500;
864 case 502: // open beauty mesons and baryons
866 result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549) ||
867 (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499);
869 if(requiredPDG>0) result = (particlePDG>=500 && particlePDG<=549) ||
870 (particlePDG>=5000 && particlePDG<=5499);
871 if(requiredPDG<0) result = (particlePDG>=-549 && particlePDG<=-500) ||
872 (particlePDG>=-5499 && particlePDG<=-5000);
875 case 503: // all beauty hadrons
877 result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599) ||
878 (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999);
880 if(requiredPDG>0) result = (particlePDG>=500 && particlePDG<=599) ||
881 (particlePDG>=5000 && particlePDG<=5999);
882 if(requiredPDG<0) result = (particlePDG>=-599 && particlePDG<=-500) ||
883 (particlePDG>=-5999 && particlePDG<=-5000);
886 case 5000: // all beauty baryons
888 result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999;
890 if(requiredPDG>0) result = particlePDG>=5000 && particlePDG<=5999;
891 if(requiredPDG<0) result = particlePDG>=-5999 && particlePDG<=-5000;
894 case 5001: // open beauty baryons
896 result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499;
898 if(requiredPDG>0) result = particlePDG>=5000 && particlePDG<=5499;
899 if(requiredPDG<0) result = particlePDG>=-5499 && particlePDG<=-5000;
902 case 902: // // open charm,beauty mesons and baryons together
904 result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439) ||
905 (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399) ||
906 (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549) ||
907 (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499);
909 if(requiredPDG>0) result = (particlePDG>=400 && particlePDG<=439) ||
910 (particlePDG>=4000 && particlePDG<=4399) ||
911 (particlePDG>=500 && particlePDG<=549) ||
912 (particlePDG>=5000 && particlePDG<=5499);
913 if(requiredPDG<0) result = (particlePDG>=-439 && particlePDG<=-400) ||
914 (particlePDG>=-4399 && particlePDG<=-4000) ||
915 (particlePDG>=-549 && particlePDG<=-500) ||
916 (particlePDG>=-5499 && particlePDG<=-5000);
919 default: // all specific cases
921 result = (absRequiredPDG==TMath::Abs(particlePDG));
923 result = (requiredPDG==particlePDG);
926 if(absRequiredPDG!=0 && pdgExclusion) result = !result;
930 //________________________________________________________________________________
931 Bool_t AliDielectronMC::IsPhysicalPrimary(Int_t label) const {
933 // Check if the particle with label "label" is a physical primary according to the
934 // definition in AliStack::IsPhysicalPrimary(Int_t label)
935 // Convention for being physical primary:
936 // 1.) particles produced in the collision
937 // 2.) stable particles with respect to strong and electromagnetic interactions
938 // 3.) excludes initial state particles
939 // 4.) includes products of directly produced Sigma0 hyperon decay
940 // 5.) includes products of directly produced pi0 decays
941 // 6.) includes products of directly produced beauty hadron decays
943 if(label<0) return kFALSE;
945 if(!fMcArray) return kFALSE;
946 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label)))->IsPhysicalPrimary();
947 } else if(fAnaType==kESD) {
948 if (!fMCEvent) return kFALSE;
949 return fStack->IsPhysicalPrimary(label);
954 //________________________________________________________________________________
955 Bool_t AliDielectronMC::IsSecondaryFromWeakDecay(Int_t label) const {
957 // Check if the particle with label "label" is a physical secondary from weak decay according to the
958 // definition in AliStack::IsSecondaryFromWeakDecay(Int_t label)
960 if(label<0) return kFALSE;
962 if(!fMcArray) return kFALSE;
963 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label)))->IsSecondaryFromWeakDecay();
964 } else if(fAnaType==kESD) {
965 if (!fMCEvent) return kFALSE;
966 return fStack->IsSecondaryFromWeakDecay(label);
971 //________________________________________________________________________________
972 Bool_t AliDielectronMC::IsSecondaryFromMaterial(Int_t label) const {
974 // Check if the particle with label "label" is a physical secondary from weak decay according to the
975 // definition in AliStack::IsSecondaryFromMaterial(Int_t label)
977 if(label<0) return kFALSE;
979 if(!fMcArray) return kFALSE;
980 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label)))->IsSecondaryFromMaterial();
981 } else if(fAnaType==kESD) {
982 if (!fMCEvent) return kFALSE;
983 return fStack->IsSecondaryFromMaterial(label);
989 //________________________________________________________________________________
990 Bool_t AliDielectronMC::CheckGEANTProcess(Int_t label, TMCProcess process) const {
992 // Check the GEANT process for the particle
993 // NOTE: for tracks the absolute label should be passed
995 if(label<0) return kFALSE;
997 if(!fMcArray) return kFALSE;
998 UInt_t processID = static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label))->GetMCProcessCode();
999 // printf("process: id %d --> %s \n",processID,TMCProcessName[processID]);
1000 return (process==processID);
1001 } else if(fAnaType==kESD) {
1002 if (!fMCEvent) return kFALSE;
1003 AliError(Form("return of GEANT process not implemented for ESD "));
1010 //________________________________________________________________________________
1011 Bool_t AliDielectronMC::CheckParticleSource(Int_t label, AliDielectronSignalMC::ESource source) const {
1013 // Check the source for the particle
1014 // NOTE: for tracks the absolute label should be passed
1018 case AliDielectronSignalMC::kDontCare :
1021 case AliDielectronSignalMC::kPrimary :
1022 // true if label is in the list of particles from physics generator
1023 // NOTE: This includes all physics event history (initial state particles,
1024 // exchange bosons, quarks, di-quarks, strings, un-stable particles, final state particles)
1025 // Only the final state particles make it to the detector!!
1026 return (label>=0 && label<=GetNPrimary());
1028 case AliDielectronSignalMC::kFinalState :
1029 // primary particles created in the collision which reach the detectors
1031 // 1.) particles produced in the collision
1032 // 2.) stable particles with respect to strong and electromagnetic interactions
1033 // 3.) excludes initial state particles
1034 // 4.) includes products of directly produced Sigma0 hyperon decay
1035 // 5.) includes products of directly produced pi0 decays
1036 // 6.) includes products of directly produced beauty hadron decays
1037 return IsPhysicalPrimary(label);
1039 case AliDielectronSignalMC::kDirect :
1040 // Primary particles which do not have any mother
1041 // This is the case for:
1042 // 1.) Initial state particles (the 2 protons in Pythia pp collisions)
1043 // 2.) In some codes, with sudden freeze-out, all particles generated from the fireball are direct.
1044 // There is no history for these particles.
1045 // 3.) Certain particles added via MC generator cocktails (e.g. J/psi added to pythia MB events)
1046 return (label>=0 && GetMothersLabel(label)<0);
1048 case AliDielectronSignalMC::kNoCocktail :
1049 // Particles from the HIJING event and NOT from the AliGenCocktail
1050 return (label>=0 && GetMothersLabel(label)>=0);
1052 case AliDielectronSignalMC::kSecondary :
1053 // particles which are created by the interaction of final state primaries with the detector
1054 // or particles from strange weakly decaying particles (e.g. lambda, kaons, etc.)
1055 return (label>=GetNPrimary() && !IsPhysicalPrimary(label));
1057 case AliDielectronSignalMC::kSecondaryFromWeakDecay :
1058 // secondary particle from weak decay
1059 // or particles from strange weakly decaying particles (e.g. lambda, kaons, etc.)
1060 return (IsSecondaryFromWeakDecay(label));
1062 case AliDielectronSignalMC::kSecondaryFromMaterial :
1063 // secondary particle from material
1064 return (IsSecondaryFromMaterial(label));
1072 //________________________________________________________________________________
1073 Bool_t AliDielectronMC::CheckIsRadiative(Int_t label) const
1076 // Check if the particle has a three body decay, one being a photon
1078 if(label<0) return kFALSE;
1081 if(fAnaType==kAOD) {
1082 if(!fMcArray) return kFALSE;
1083 AliAODMCParticle *mother=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label));
1084 if (!mother) return kFALSE;
1085 const Int_t nd=mother->GetNDaughters();
1086 if (nd==2) return kFALSE;
1087 for (Int_t i=2; i<nd; ++i)
1088 if (GetMCTrackFromMCEvent(mother->GetDaughter(0)+i)->PdgCode()!=22) return kFALSE; //last daughter is photon
1089 } else if(fAnaType==kESD) {
1090 if (!fMCEvent) return kFALSE;
1091 AliMCParticle *mother=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(label));
1092 if (!mother) return kFALSE;
1093 const Int_t nd=(mother->GetLastDaughter()-mother->GetFirstDaughter()+1);
1094 if (nd==2) return kFALSE;
1095 for (Int_t i=2; i<nd; ++i)
1096 if (GetMCTrackFromMCEvent(mother->GetFirstDaughter()+i)->PdgCode()!=22) return kFALSE; //last daughters are photons
1101 //________________________________________________________________________________
1102 Bool_t AliDielectronMC::CheckRadiativeDecision(Int_t mLabel, const AliDielectronSignalMC * const signalMC) const
1105 // Check for the decision of the radiative type request
1108 if (!signalMC) return kFALSE;
1110 if (signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kAll) return kTRUE;
1112 Bool_t isRadiative=CheckIsRadiative(mLabel);
1113 if ((signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kIsRadiative) && !isRadiative) return kFALSE;
1114 if ((signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kIsNotRadiative) && isRadiative) return kFALSE;
1119 //________________________________________________________________________________
1120 Bool_t AliDielectronMC::IsMCTruth(Int_t label, AliDielectronSignalMC* signalMC, Int_t branch) const {
1122 // Check if the particle corresponds to the MC truth in signalMC in the branch specified
1125 // NOTE: Some particles have the sign of the label flipped. It is related to the quality of matching
1126 // between the ESD and the MC track. The negative labels indicate a poor matching quality
1127 //if(label<0) return kFALSE;
1128 if(label<0) label *= -1;
1130 AliVParticle* part = GetMCTrackFromMCEvent(label);
1132 AliError(Form("Could not find MC particle with label %d",label));
1136 // check geant process if set
1137 if(signalMC->GetCheckGEANTProcess() && !CheckGEANTProcess(label,signalMC->GetGEANTProcess())) return kFALSE;
1140 if(!ComparePDG(part->PdgCode(),signalMC->GetLegPDG(branch),signalMC->GetLegPDGexclude(branch),signalMC->GetCheckBothChargesLegs(branch))) return kFALSE;
1141 if(!CheckParticleSource(label, signalMC->GetLegSource(branch))) return kFALSE;
1144 AliVParticle* mcMother=0x0;
1146 if(signalMC->GetMotherPDG(branch)!=0 || signalMC->GetMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
1148 mLabel = GetMothersLabel(label);
1149 mcMother = GetMCTrackFromMCEvent(mLabel);
1151 if(!mcMother && !signalMC->GetMotherPDGexclude(branch)) return kFALSE;
1153 if(!ComparePDG((mcMother ? mcMother->PdgCode() : 0),signalMC->GetMotherPDG(branch),signalMC->GetMotherPDGexclude(branch),signalMC->GetCheckBothChargesMothers(branch))) return kFALSE;
1154 if(!CheckParticleSource(mLabel, signalMC->GetMotherSource(branch))) return kFALSE;
1156 //check for radiative deday
1157 if (!CheckRadiativeDecision(mLabel, signalMC)) return kFALSE;
1160 // check the grandmother
1161 AliVParticle* mcGrandMother=0x0;
1162 if(signalMC->GetGrandMotherPDG(branch)!=0 || signalMC->GetGrandMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
1165 gmLabel = GetMothersLabel(mLabel);
1166 mcGrandMother = static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(gmLabel));
1168 if(!mcGrandMother && !signalMC->GetGrandMotherPDGexclude(branch)) return kFALSE;
1170 if(!ComparePDG((mcGrandMother ? mcGrandMother->PdgCode() : 0),signalMC->GetGrandMotherPDG(branch),signalMC->GetGrandMotherPDGexclude(branch),signalMC->GetCheckBothChargesGrandMothers(branch))) return kFALSE;
1171 if(!CheckParticleSource(gmLabel, signalMC->GetGrandMotherSource(branch))) return kFALSE;
1179 //________________________________________________________________________________
1180 Bool_t AliDielectronMC::IsMCTruth(const AliDielectronPair* pair, const AliDielectronSignalMC* signalMC) const {
1182 // Check if the pair corresponds to the MC truth in signalMC
1186 const AliVParticle * mcD1 = pair->GetFirstDaughterP();
1187 const AliVParticle * mcD2 = pair->GetSecondDaughterP();
1188 Int_t labelD1 = (mcD1 ? TMath::Abs(mcD1->GetLabel()) : -1);
1189 Int_t labelD2 = (mcD2 ? TMath::Abs(mcD2->GetLabel()) : -1);
1190 Int_t d1Pdg = GetPdgFromLabel(labelD1);
1191 Int_t d2Pdg = GetPdgFromLabel(labelD2);
1194 AliVParticle* mcM1=0x0;
1195 AliVParticle* mcM2=0x0;
1198 AliVParticle* mcG1 = 0x0;
1199 AliVParticle* mcG2 = 0x0;
1201 // make direct(1-1 and 2-2) and cross(1-2 and 2-1) comparisons for the whole branch
1202 Bool_t directTerm = kTRUE;
1204 directTerm = directTerm && mcD1 && ComparePDG(d1Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
1205 && CheckParticleSource(labelD1, signalMC->GetLegSource(1));
1207 directTerm = directTerm && mcD2 && ComparePDG(d2Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
1208 && CheckParticleSource(labelD2, signalMC->GetLegSource(2));
1212 if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1213 labelM1 = GetMothersLabel(labelD1);
1214 if(labelD1>-1 && labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
1215 directTerm = directTerm && (mcM1 || signalMC->GetMotherPDGexclude(1))
1216 && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
1217 && CheckParticleSource(labelM1, signalMC->GetMotherSource(1))
1218 && CheckRadiativeDecision(labelM1,signalMC);
1222 if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1223 labelM2 = GetMothersLabel(labelD2);
1224 if(labelD2>-1 && labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
1225 directTerm = directTerm && (mcM2 || signalMC->GetMotherPDGexclude(2))
1226 && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
1227 && CheckParticleSource(labelM2, signalMC->GetMotherSource(2))
1228 && CheckRadiativeDecision(labelM2,signalMC);
1233 if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1234 labelG1 = GetMothersLabel(labelM1);
1235 if(mcM1 && labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
1236 directTerm = directTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(1))
1237 && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
1238 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(1));
1242 if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1243 labelG2 = GetMothersLabel(labelM2);
1244 if(mcM2 && labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
1245 directTerm = directTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(2))
1246 && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
1247 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(2));
1251 Bool_t crossTerm = kTRUE;
1253 crossTerm = crossTerm && mcD2
1254 && ComparePDG(d2Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
1255 && CheckParticleSource(labelD2, signalMC->GetLegSource(1));
1257 crossTerm = crossTerm && mcD1
1258 && ComparePDG(d1Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
1259 && CheckParticleSource(labelD1, signalMC->GetLegSource(2));
1262 if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1263 if(!mcM2 && labelD2>-1) {
1264 labelM2 = GetMothersLabel(labelD2);
1265 if(labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
1267 crossTerm = crossTerm && (mcM2 || signalMC->GetMotherPDGexclude(1))
1268 && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
1269 && CheckParticleSource(labelM2, signalMC->GetMotherSource(1))
1270 && CheckRadiativeDecision(labelM2,signalMC);
1273 if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1274 if(!mcM1 && labelD1>-1) {
1275 labelM1 = GetMothersLabel(labelD1);
1276 if(labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
1278 crossTerm = crossTerm && (mcM1 || signalMC->GetMotherPDGexclude(2))
1279 && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
1280 && CheckParticleSource(labelM1, signalMC->GetMotherSource(2))
1281 && CheckRadiativeDecision(labelM1,signalMC);
1285 if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1287 labelG2 = GetMothersLabel(labelM2);
1288 if(labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
1290 crossTerm = crossTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(1))
1291 && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
1292 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(1));
1295 if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1297 labelG1 = GetMothersLabel(labelM1);
1298 if(labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
1300 crossTerm = crossTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(2))
1301 && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
1302 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(2));
1305 Bool_t motherRelation = kTRUE;
1306 if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kSame) {
1307 motherRelation = motherRelation && HaveSameMother(pair);
1309 if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent) {
1310 motherRelation = motherRelation && !HaveSameMother(pair);
1313 // check geant process if set
1314 Bool_t processGEANT = kTRUE;
1315 if(signalMC->GetCheckGEANTProcess()) {
1316 if(!CheckGEANTProcess(labelD1,signalMC->GetGEANTProcess()) &&
1317 !CheckGEANTProcess(labelD2,signalMC->GetGEANTProcess()) ) processGEANT= kFALSE;
1320 return ((directTerm || crossTerm) && motherRelation && processGEANT);
1325 //____________________________________________________________
1326 Bool_t AliDielectronMC::HaveSameMother(const AliDielectronPair * pair) const
1329 // Check whether two particles have the same mother
1332 const AliVParticle * daughter1 = pair->GetFirstDaughterP();
1333 const AliVParticle * daughter2 = pair->GetSecondDaughterP();
1334 if (!daughter1 || !daughter2) return 0;
1336 AliVParticle *mcDaughter1=GetMCTrackFromMCEvent(daughter1->GetLabel());
1337 AliVParticle *mcDaughter2=GetMCTrackFromMCEvent(daughter2->GetLabel());
1338 if (!mcDaughter1 || !mcDaughter2) return 0;
1340 Int_t labelMother1=-1;
1341 Int_t labelMother2=-1;
1343 if (mcDaughter1->IsA()==AliMCParticle::Class()){
1344 labelMother1=(static_cast<AliMCParticle*>(mcDaughter1))->GetMother();
1345 labelMother2=(static_cast<AliMCParticle*>(mcDaughter2))->GetMother();
1346 } else if (mcDaughter1->IsA()==AliAODMCParticle::Class()) {
1347 labelMother1=(static_cast<AliAODMCParticle*>(mcDaughter1))->GetMother();
1348 labelMother2=(static_cast<AliAODMCParticle*>(mcDaughter2))->GetMother();
1351 Bool_t sameMother=(labelMother1>-1)&&(labelMother2>-1)&&(labelMother1==labelMother2);
1356 //________________________________________________________________
1357 Int_t AliDielectronMC::IsJpsiPrimary(const AliDielectronPair * pair)
1359 // return: "0" for primary jpsi
1360 // "1" for secondary jpsi (from beauty)
1361 // "2" for background
1362 if(!HaveSameMother(pair)) return 2;
1363 AliVParticle *mcDaughter1=GetMCTrackFromMCEvent((pair->GetFirstDaughterP())->GetLabel());
1364 Int_t labelMother=-1;
1366 if (mcDaughter1->IsA()==AliMCParticle::Class()){
1367 labelMother=(static_cast<AliMCParticle*>(mcDaughter1))->GetMother();
1368 } else if (mcDaughter1->IsA()==AliAODMCParticle::Class()) {
1369 labelMother=(static_cast<AliAODMCParticle*>(mcDaughter1))->GetMother();
1372 AliVParticle* mcMother=GetMCTrackFromMCEvent(labelMother);
1373 if(!IsMCMotherToEE(mcMother,443)) return 2;
1374 return IsJpsiPrimary(mcMother);
1377 //______________________________________________________________
1378 Int_t AliDielectronMC::IsJpsiPrimary(const AliVParticle * particle)
1380 // return: "0" for primary jpsi
1381 // "1" for secondary jpsi (come from B decay)
1385 if (particle->IsA()==AliMCParticle::Class()){
1386 labelMoth = (static_cast<const AliMCParticle*>(particle))->GetMother();
1388 particle = GetMCTrackFromMCEvent(labelMoth);
1389 pdgCode = TMath::Abs((static_cast<const AliMCParticle*>(particle))->PdgCode());
1390 if((pdgCode>500 && pdgCode<600) || (pdgCode>5000 && pdgCode<6000)) return 1;
1391 labelMoth = (static_cast<const AliMCParticle*>(particle))->GetMother();
1394 else if (particle->IsA()==AliAODMCParticle::Class()){
1395 labelMoth = (static_cast<const AliAODMCParticle*>(particle))->GetMother();
1397 particle = GetMCTrackFromMCEvent(labelMoth);
1398 pdgCode = TMath::Abs((static_cast<const AliAODMCParticle*>(particle))->PdgCode());
1399 if((pdgCode>500 && pdgCode<600) || (pdgCode>5000 && pdgCode<6000)) return 1;
1400 labelMoth = (static_cast<const AliAODMCParticle*>(particle))->GetMother();
1407 Bool_t AliDielectronMC::GetPrimaryVertex(Double_t &primVtxX, Double_t &primVtxY, Double_t &primVtxZ){
1409 if(fAnaType == kESD){
1410 const AliVVertex* mcVtx = fMCEvent->GetPrimaryVertex();
1411 if(!mcVtx) return kFALSE;
1412 primVtxX = mcVtx->GetX();
1413 primVtxY = mcVtx->GetY();
1414 primVtxZ = mcVtx->GetZ();
1415 }else if(fAnaType == kAOD){
1416 AliAODEvent *aod=((AliAODInputHandler*)((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler()))->GetEvent();
1417 if(!aod) return kFALSE;
1418 AliAODMCHeader *mcHead = dynamic_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
1419 if(!mcHead) return kFALSE;
1420 primVtxX = mcHead->GetVtxX();
1421 primVtxY = mcHead->GetVtxY();
1422 primVtxZ = mcHead->GetVtxZ();