]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGDQ/dielectron/AliDielectronMC.cxx
add proptections (marcel), add GEANT process for MC
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronMC.cxx
CommitLineData
b2a297fa 1/*************************************************************************
2* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16//#####################################################
17//# #
18//# Class AliDielectronMC #
19//# Cut Class for Jpsi->e+e- analysis #
20//# #
21//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
22//# #
23//#####################################################
24
25#include <AliAnalysisManager.h>
26#include <AliAODHandler.h>
27#include <AliESDInputHandler.h>
fb7d2d99 28#include <AliAODInputHandler.h>
b2a297fa 29#include <AliMCEventHandler.h>
30#include <AliMCEvent.h>
31#include <AliMCParticle.h>
32#include <AliAODMCParticle.h>
4533e78e 33#include <AliAODMCHeader.h>
b2a297fa 34#include <AliStack.h>
35#include <AliESDEvent.h>
fb7d2d99 36#include <AliAODEvent.h>
b2a297fa 37#include <AliESDtrack.h>
fb7d2d99 38#include <AliAODTrack.h>
b2a297fa 39#include <AliLog.h>
40
fb7d2d99 41#include <TClonesArray.h>
5720c765 42#include <TParticle.h>
ffcd7c9e 43#include <TMCProcess.h>
ba15fdfb 44
45#include "AliDielectronSignalMC.h"
b2a297fa 46#include "AliDielectronMC.h"
47
c72d368f 48
c081415a 49ClassImp(AliDielectronMC)
50
b2a297fa 51AliDielectronMC* AliDielectronMC::fgInstance=0x0;
52
53//____________________________________________________________
54AliDielectronMC* AliDielectronMC::Instance()
55{
56 //
57 // return pointer to singleton implementation
58 //
59 if (fgInstance) return fgInstance;
fb7d2d99 60
b2a297fa 61 AnalysisType type=kUNSET;
3505bfad 62 Bool_t hasMC=kFALSE;
63 if (AliAnalysisManager::GetAnalysisManager()){
64 if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()) type=kESD;
fb7d2d99 65 else if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()) type=kAOD;
8df8e382 66
3505bfad 67 AliMCEventHandler* mcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
fb7d2d99 68 if(type == kESD) hasMC=mcHandler!=0x0;
69 }
70
b2a297fa 71 fgInstance=new AliDielectronMC(type);
fb7d2d99 72
3505bfad 73 fgInstance->SetHasMC(hasMC);
fb7d2d99 74
b2a297fa 75 return fgInstance;
76}
77
78//____________________________________________________________
79AliDielectronMC::AliDielectronMC(AnalysisType type):
80 fMCEvent(0x0),
81 fStack(0x0),
572b0139 82 fAnaType(type),
fb7d2d99 83 fHasMC(kTRUE),
84 fMcArray(0x0)
b2a297fa 85{
86 //
87 // default constructor
88 //
89}
90
91
92//____________________________________________________________
93AliDielectronMC::~AliDielectronMC()
94{
95 //
96 // default destructor
97 //
98
99}
100
101//____________________________________________________________
102void AliDielectronMC::Initialize()
103{
104 //
105 // initialize MC class
106 //
107 if (!ConnectMCEvent()) AliError("Initialization of MC object failed!");
108}
109
110//____________________________________________________________
111Int_t AliDielectronMC::GetNMCTracks()
112{
113 //
114 // return the number of generated tracks from MC event
115 //
fb7d2d99 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();
122 }
123 return 0;
b2a297fa 124}
125
126//____________________________________________________________
127Int_t AliDielectronMC::GetNMCTracksFromStack()
128{
129 //
130 // return the number of generated tracks from stack
131 //
132 if (!fStack){ AliError("No fStack"); return -999; }
133 return fStack->GetNtrack();
134}
135
2a14a7b1 136//____________________________________________________________
c8f0f810 137Int_t AliDielectronMC::GetNPrimary() const
2a14a7b1 138{
139 //
140 // return the number of primary track from MC event
141 //
142 if (!fMCEvent){ AliError("No fMCEvent"); return 0; }
143 return fMCEvent->GetNumberOfPrimaries();
144}
145
146//____________________________________________________________
147Int_t AliDielectronMC::GetNPrimaryFromStack()
148{
149 //
150 // return the number of primary track from stack
151 //
152 if (!fStack){ AliError("No fStack"); return -999; }
153 return fStack->GetNprimary();
154}
155
b2a297fa 156//____________________________________________________________
d191916c 157AliVParticle* AliDielectronMC::GetMCTrackFromMCEvent(Int_t label) const
b2a297fa 158{
159 //
160 // return MC track directly from MC event
d191916c 161 // used not only for tracks but for mothers as well, therefore do not use abs(label)
b2a297fa 162 //
d191916c 163 if (label<0) return NULL;
fb7d2d99 164 AliVParticle * track=0x0;
165 if(fAnaType == kESD){
166 if (!fMCEvent){ AliError("No fMCEvent"); return NULL;}
d191916c 167 track = fMCEvent->GetTrack(label); // tracks from MC event (ESD)
fb7d2d99 168 } else if(fAnaType == kAOD) {
40875e45 169 if (!fMcArray){ AliError("No fMcArray"); return NULL;}
b829fbd2 170 if (label>fMcArray->GetEntriesFast()) { AliDebug(10,Form("track %d out of array size %d",label,fMcArray->GetEntriesFast())); return NULL;}
d191916c 171 track = (AliVParticle*)fMcArray->At(label); // tracks from MC event (AOD)
fb7d2d99 172 }
b2a297fa 173 return track;
174}
175
176//____________________________________________________________
177Bool_t AliDielectronMC::ConnectMCEvent()
178{
179 //
180 // connect stack object from the mc handler
181 //
b2ad74d0 182
183 fMcArray = 0x0;
184 fMCEvent = 0x0;
185
fb7d2d99 186 if(fAnaType == kESD){
fb7d2d99 187 AliMCEventHandler* mcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
40875e45 188 if (!mcHandler){ /*AliError("Could not retrive MC event handler!");*/ return kFALSE; }
fb7d2d99 189 if (!mcHandler->InitOk() ) return kFALSE;
190 if (!mcHandler->TreeK() ) return kFALSE;
191 if (!mcHandler->TreeTR() ) return kFALSE;
192
193 AliMCEvent* mcEvent = mcHandler->MCEvent();
40875e45 194 if (!mcEvent){ /*AliError("Could not retrieve MC event!");*/ return kFALSE; }
fb7d2d99 195 fMCEvent = mcEvent;
196
197 if (!UpdateStack()) return kFALSE;
198 }
199 else if(fAnaType == kAOD)
200 {
b2ad74d0 201 AliAODInputHandler* aodHandler=(AliAODInputHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
202 if (!aodHandler) return kFALSE;
203 AliAODEvent *aod=aodHandler->GetEvent();
204 if (!aod) return kFALSE;
4533e78e 205
fb7d2d99 206 fMcArray = dynamic_cast<TClonesArray*>(aod->FindListObject(AliAODMCParticle::StdBranchName()));
40875e45 207 if (!fMcArray){ /*AliError("Could not retrieve MC array!");*/ return kFALSE; }
208 else fHasMC=kTRUE;
fb7d2d99 209 }
b2a297fa 210 return kTRUE;
211}
212
213//____________________________________________________________
214Bool_t AliDielectronMC::UpdateStack()
215{
216 //
217 // update stack with new event
218 //
219 if (!fMCEvent){ AliError("No fMCEvent"); return kFALSE;}
220 AliStack* stack = fMCEvent->Stack();
221 if (!stack){ AliError("Could not retrive stack!"); return kFALSE; }
222 fStack = stack;
223 return kTRUE;
224}
225
226//____________________________________________________________
8df8e382 227AliMCParticle* AliDielectronMC::GetMCTrack( const AliESDtrack* _track)
b2a297fa 228{
229 //
230 // return MC track
231 //
9143d69f 232 if (!fMCEvent){ AliError("No fMCEvent"); return NULL;}
9143d69f 233 Int_t nStack = fMCEvent->GetNumberOfTracks();
d191916c 234 Int_t label = TMath::Abs(_track->GetLabel()); // negative label indicate poor matching quality
9143d69f 235 if(label>nStack)return NULL;
b2a297fa 236 AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(label));
237 return mctrack;
238}
239
fb7d2d99 240
241//____________________________________________________________
242AliAODMCParticle* AliDielectronMC::GetMCTrack( const AliAODTrack* _track)
243{
244 //
245 // return MC track
246 //
40875e45 247 if(!fMcArray) { AliError("No fMcArray"); return NULL;}
d191916c 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;
fb7d2d99 251 AliAODMCParticle *mctrack = (AliAODMCParticle*)fMcArray->At(label);
252 return mctrack;
253}
254
b2a297fa 255//____________________________________________________________
8df8e382 256TParticle* AliDielectronMC::GetMCTrackFromStack(const AliESDtrack* _track)
b2a297fa 257{
258 //
259 // return MC track from stack
260 //
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;
265 return mcpart;
266}
267
268//____________________________________________________________
8df8e382 269AliMCParticle* AliDielectronMC::GetMCTrackMother(const AliESDtrack* _track)
b2a297fa 270{
271 //
272 // return MC track mother
273 //
274 AliMCParticle* mcpart = GetMCTrack(_track);
275 if (!mcpart) return NULL;
7329335b 276 if(mcpart->GetMother()<0) return NULL;
b2a297fa 277 AliMCParticle* mcmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(mcpart->GetMother()));
278 if (!mcmother) return NULL;
279 return mcmother;
280}
281
fb7d2d99 282//______________________________________________________________
283AliAODMCParticle* AliDielectronMC::GetMCTrackMother(const AliAODTrack* _track)
284{
285 //
286 // return MC track mother
287 //
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;
293 return mcmother;
294}
b2a297fa 295//____________________________________________________________
8df8e382 296AliMCParticle* AliDielectronMC::GetMCTrackMother(const AliMCParticle* _particle){
297 //
298 // return MC track mother
299 //
7329335b 300 if(_particle->GetMother() < 0) return NULL;
8df8e382 301 AliMCParticle* mcmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(_particle->GetMother()));
302 return mcmother;
303}
304
305//____________________________________________________________
306AliAODMCParticle* AliDielectronMC::GetMCTrackMother(const AliAODMCParticle* _particle){
307 //
308 // return MC track mother
309 //
fb7d2d99 310 if( _particle->GetMother() < 0) return NULL;
311 AliAODMCParticle* mcmother = dynamic_cast<AliAODMCParticle *>(fMcArray->At(_particle->GetMother()));
8df8e382 312 return mcmother;
313}
314
315//____________________________________________________________
316TParticle* AliDielectronMC::GetMCTrackMotherFromStack(const AliESDtrack* _track)
b2a297fa 317{
318 //
319 // return MC track mother from stack
320 //
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;
325 return mcmother;
326}
327
328//____________________________________________________________
8df8e382 329Int_t AliDielectronMC::GetMCPID(const AliESDtrack* _track)
b2a297fa 330{
331 //
332 // return PDG code of the track from the MC truth info
333 //
334 AliMCParticle* mcpart = GetMCTrack(_track);
335 if (!mcpart) return -999;
336 return mcpart->PdgCode();
337}
338
fb7d2d99 339//__________________________________________________________
340Int_t AliDielectronMC::GetMCPID(const AliAODTrack* _track)
341{
342 //
343 // return PDG code of the track from the MC truth info
344 //
345 AliAODMCParticle* mcpart = GetMCTrack(_track);
346 if (!mcpart) return -999;
347 return mcpart->PdgCode();
348}
349
b2a297fa 350//____________________________________________________________
8df8e382 351Int_t AliDielectronMC::GetMCPIDFromStack(const AliESDtrack* _track)
b2a297fa 352{
353 //
354 // return MC PDG code from stack
355 //
356 TParticle* mcpart = GetMCTrackFromStack(_track);
357 if (!mcpart) return -999;
358 return mcpart->GetPdgCode();
359}
360
361//____________________________________________________________
8df8e382 362Int_t AliDielectronMC::GetMotherPDG( const AliESDtrack* _track)
b2a297fa 363{
364 //
365 // return PDG code of the mother track from the MC truth info
366 //
367 AliMCParticle* mcmother = GetMCTrackMother(_track);
368 if (!mcmother) return -999;
369 return mcmother->PdgCode();
370}
371
fb7d2d99 372//________________________________________________________
373Int_t AliDielectronMC::GetMotherPDG( const AliAODTrack* _track)
374{
375 //
376 // return PDG code of the mother track from the MC truth info
377 //
378 AliAODMCParticle* mcmother = GetMCTrackMother(_track);
379 if (!mcmother) return -999;
380 return mcmother->PdgCode();
381}
382
d191916c 383//________________________________________________________
384Int_t AliDielectronMC::GetMotherPDG( const AliMCParticle* _track)
385{
386 //
387 // return PDG code of the mother track from the MC truth info
388 //
389 AliMCParticle* mcmother = GetMCTrackMother(_track);
390 if (!mcmother) return -999;
391 return mcmother->PdgCode();
392}
393
394//________________________________________________________
395Int_t AliDielectronMC::GetMotherPDG( const AliAODMCParticle* _track)
396{
397 //
398 // return PDG code of the mother track from the MC truth info
399 //
400 AliAODMCParticle* mcmother = GetMCTrackMother(_track);
401 if (!mcmother) return -999;
402 return mcmother->PdgCode();
403}
404
b2a297fa 405//____________________________________________________________
8df8e382 406Int_t AliDielectronMC::GetMotherPDGFromStack(const AliESDtrack* _track)
b2a297fa 407{
408 //
409 // return PDG code of the mother track from stack
410 //
411 TParticle* mcmother = GetMCTrackMotherFromStack(_track);
412 if (!mcmother) return -999;
413 return mcmother->GetPdgCode();
414}
415
416//____________________________________________________________
8df8e382 417Int_t AliDielectronMC::GetMCProcess(const AliESDtrack* _track)
b2a297fa 418{
419 //
420 // return process number of the track
421 //
422 AliMCParticle* mcpart = GetMCTrack(_track);
423 if (!mcpart) return -999;
424 return 0;
425}
426
427//____________________________________________________________
8df8e382 428Int_t AliDielectronMC::GetMCProcessFromStack(const AliESDtrack* _track)
b2a297fa 429{
430 //
431 // return process number of the track
432 //
433 TParticle* mcpart = GetMCTrackFromStack(_track);
434 if (!mcpart) return -999;
435 return mcpart->GetUniqueID();
436}
437
438//____________________________________________________________
8df8e382 439Int_t AliDielectronMC::NumberOfDaughters(const AliESDtrack* track)
440{
441 //
442 // returns the number of daughters
443 //
444 AliMCParticle *mcmother=GetMCTrackMother(track);
445 if(!mcmother||!mcmother->Particle()) return -999;
d191916c 446 // return mcmother->GetFirstDaughter()>0?mcmother->GetLastDaughter()-mcmother->GetFirstDaughter()+1:0;
8df8e382 447 return mcmother->Particle()->GetNDaughters();
448}
449
fb7d2d99 450//_________________________________________________________
451Int_t AliDielectronMC::NumberOfDaughters(const AliAODTrack* track)
452{
453 //
454 // returns the number of daughters
455 //
456 AliAODMCParticle *mcmother=GetMCTrackMother(track);
457 if(!mcmother) return -999;
458 return NumberOfDaughters(mcmother);
459
460}
461
8df8e382 462//____________________________________________________________
463Int_t AliDielectronMC::NumberOfDaughters(const AliMCParticle* particle)
464{
465 //
466 // returns the number of daughters
467 //
468 AliMCParticle *mcmother=GetMCTrackMother(particle);
469 if(!mcmother||!mcmother->Particle()) return -999;
fb7d2d99 470 //return mcmother->GetFirstDaughter()>0?mcmother->GetLastDaughter()-mcmother->GetFirstDaughter()+1:0;
8df8e382 471 return mcmother->Particle()->GetNDaughters();
472}
473
474//____________________________________________________________
475Int_t AliDielectronMC::NumberOfDaughters(const AliAODMCParticle* particle)
476{
477 //
478 // returns the number of daughters
479 //
480 AliAODMCParticle *mcmother=GetMCTrackMother(particle);
481 if(!mcmother) return -999;
482 return mcmother->GetNDaughters();
483}
484
485//____________________________________________________________
486Int_t AliDielectronMC::GetMCProcessMother(const AliESDtrack* _track)
b2a297fa 487{
488 //
489 // return process number of the mother of the track
490 //
491 AliMCParticle* mcmother = GetMCTrackMother(_track);
492 if (!mcmother) return -999;
493 return 0;
494}
495
496//____________________________________________________________
8df8e382 497Int_t AliDielectronMC::GetMCProcessMotherFromStack(const AliESDtrack* _track)
b2a297fa 498{
499 //
500 // return process number of the mother of the track
501 //
502 TParticle* mcmother = GetMCTrackMotherFromStack(_track);
503 if (!mcmother) return -999;
504 return mcmother->GetUniqueID();
505}
506
507//____________________________________________________________
508Bool_t AliDielectronMC::IsMCMotherToEE(const AliVParticle *particle, Int_t pdgMother)
509{
510 //
511 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
512 //
fb7d2d99 513 if (fAnaType==kESD && !fMCEvent) return kFALSE;
514 if (fAnaType==kAOD && !fMcArray) return kFALSE;
8df8e382 515 if (!particle) return kFALSE;
b2a297fa 516
517 if (particle->IsA()==AliMCParticle::Class()){
518 return IsMCMotherToEEesd(static_cast<const AliMCParticle*>(particle),pdgMother);
519 } else if (particle->IsA()==AliAODMCParticle::Class()){
fb7d2d99 520 return IsMCMotherToEEaod(static_cast<const AliAODMCParticle*>(particle),pdgMother);
b2a297fa 521 } else {
522 AliError("Unknown particle type");
523 }
524 return kFALSE;
b2a297fa 525}
526
527//____________________________________________________________
528Bool_t AliDielectronMC::IsMCMotherToEEesd(const AliMCParticle *particle, Int_t pdgMother)
529{
530 //
531 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
532 // ESD case
533 //
534
535 //check pdg code
536 if (particle->PdgCode()!=pdgMother) return kFALSE;
537 Int_t ifirst = particle->GetFirstDaughter();
538 Int_t ilast = particle->GetLastDaughter();
539
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));
8df8e382 544
545 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
b2a297fa 546 if (firstD->Charge()>0){
547 if (firstD->PdgCode()!=-11) return kFALSE;
548 if (secondD->PdgCode()!=11) return kFALSE;
549 }else{
550 if (firstD->PdgCode()!=11) return kFALSE;
551 if (secondD->PdgCode()!=-11) return kFALSE;
552 }
553
554 return kTRUE;
555}
556
557//____________________________________________________________
558Bool_t AliDielectronMC::IsMCMotherToEEaod(const AliAODMCParticle *particle, Int_t pdgMother)
559{
560 //
561 // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
562 // AOD case
563 //
fb7d2d99 564
b2a297fa 565 if (particle->GetPdgCode()!=pdgMother) return kFALSE;
566 if (particle->GetNDaughters()!=2) return kFALSE;
fb7d2d99 567
b2a297fa 568 Int_t ifirst = particle->GetDaughter(0);
569 Int_t ilast = particle->GetDaughter(1);
570
571 //check number of daughters
572 if ((ilast-ifirst)!=1) return kFALSE;
fb7d2d99 573
b2a297fa 574 AliAODMCParticle *firstD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ifirst));
575 AliAODMCParticle *secondD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ilast));
fb7d2d99 576
8df8e382 577 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
fb7d2d99 578
b2a297fa 579 if (firstD->Charge()>0){
b2a297fa 580 if (firstD->GetPdgCode()!=-11) return kFALSE;
581 if (secondD->GetPdgCode()!=11) return kFALSE;
fb7d2d99 582 }else{
583 if (firstD->GetPdgCode()!=11) return kFALSE;
584 if (secondD->GetPdgCode()!=-11) return kFALSE;
b2a297fa 585 }
586 return kTRUE;
587}
588
589//____________________________________________________________
a655b716 590Int_t AliDielectronMC::GetLabelMotherWithPdg(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
b2a297fa 591{
592 //
593 // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
594 //
fb7d2d99 595 if (fAnaType==kESD){
a655b716 596 if (!fMCEvent) return -1;
fb7d2d99 597 return GetLabelMotherWithPdgESD(particle1, particle2, pdgMother);
598 }
599 else if (fAnaType==kAOD)
600 {
601 if (!fMcArray) return -1;
602 return GetLabelMotherWithPdgAOD(particle1, particle2, pdgMother);
603 }
604
a655b716 605 return -1;
b2a297fa 606}
607
608//____________________________________________________________
a655b716 609Int_t AliDielectronMC::GetLabelMotherWithPdgESD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
b2a297fa 610{
611 //
a655b716 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
b2a297fa 614 // ESD case
8df8e382 615 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
b2a297fa 616 //
d191916c 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));
b2a297fa 622
a655b716 623 if (!mcPart1||!mcPart2) return -1;
b2a297fa 624
625 Int_t lblMother1=mcPart1->GetMother();
626 Int_t lblMother2=mcPart2->GetMother();
b2a297fa 627 AliMCParticle *mcMother1=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
d191916c 628
a655b716 629 if (!mcMother1) return -1;
630 if (lblMother1!=lblMother2) return -1;
631 if (TMath::Abs(mcPart1->PdgCode())!=11) return -1;
572b0139 632 if (mcPart1->PdgCode()!=-mcPart2->PdgCode()) return -1;
a655b716 633 if (mcMother1->PdgCode()!=pdgMother) return -1;
b2a297fa 634
a655b716 635 return lblMother1;
b2a297fa 636}
637
638//____________________________________________________________
a655b716 639Int_t AliDielectronMC::GetLabelMotherWithPdgAOD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
b2a297fa 640{
641 //
a655b716 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
b2a297fa 644 // AOD case
8df8e382 645 //TODO: check how you can get rid of the hardcoded numbers. One should make use of the PdgCodes set in AliDielectron!!!
b2a297fa 646 //
d191916c 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));
b2a297fa 652
a655b716 653 if (!mcPart1||!mcPart2) return -1;
b2a297fa 654
655 Int_t lblMother1=mcPart1->GetMother();
656 Int_t lblMother2=mcPart2->GetMother();
b2a297fa 657 AliAODMCParticle *mcMother1=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
658
a655b716 659 if (!mcMother1) return -1;
660 if (lblMother1!=lblMother2) return -1;
661 if (TMath::Abs(mcPart1->GetPdgCode())!=11) return -1;
572b0139 662 if (mcPart1->GetPdgCode()!=-mcPart2->GetPdgCode()) return -1;
a655b716 663 if (mcMother1->GetPdgCode()!=pdgMother) return -1;
b2a297fa 664
a655b716 665 return lblMother1;
b2a297fa 666}
667
6551594b 668//____________________________________________________________
669void AliDielectronMC::GetDaughters(const TObject *mother, AliVParticle* &d1, AliVParticle* &d2)
670{
671 //
672 // Get First two daughters of the mother
673 //
6551594b 674 Int_t lblD1=-1;
675 Int_t lblD2=-1;
676 d1=0;
677 d2=0;
6551594b 678 if (fAnaType==kAOD){
fb7d2d99 679 if(!fMcArray) return;
6551594b 680 const AliAODMCParticle *aodMother=static_cast<const AliAODMCParticle*>(mother);
681 lblD1=aodMother->GetDaughter(0);
682 lblD2=aodMother->GetDaughter(1);
fb7d2d99 683 d1 = (AliVParticle*)fMcArray->At(lblD1);
684 d2 = (AliVParticle*)fMcArray->At(lblD2);
685 } else if (fAnaType==kESD){
686 if (!fMCEvent) return;
6551594b 687 const AliMCParticle *aodMother=static_cast<const AliMCParticle*>(mother);
688 lblD1=aodMother->GetFirstDaughter();
689 lblD2=aodMother->GetLastDaughter();
fb7d2d99 690 d1=fMCEvent->GetTrack(lblD1);
691 d2=fMCEvent->GetTrack(lblD2);
692 }
6551594b 693}
8df8e382 694
ba15fdfb 695
696//________________________________________________________________________________
c8f0f810 697Int_t AliDielectronMC::GetMothersLabel(Int_t daughterLabel) const {
ba15fdfb 698 //
699 // Get the label of the mother for particle with label daughterLabel
d191916c 700 // NOTE: for tracks, the absolute label should be passed
ba15fdfb 701 //
702 if(daughterLabel<0) return -1;
703 if (fAnaType==kAOD) {
704 if(!fMcArray) return -1;
1bb1fef1 705 if(GetMCTrackFromMCEvent(daughterLabel))
706 return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(daughterLabel)))->GetMother();
ba15fdfb 707 } else if(fAnaType==kESD) {
708 if (!fMCEvent) return -1;
1bb1fef1 709 if(GetMCTrackFromMCEvent(daughterLabel))
710 return (static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(daughterLabel)))->GetMother();
ba15fdfb 711 }
712 return -1;
713}
714
715
716//________________________________________________________________________________
c8f0f810 717Int_t AliDielectronMC::GetPdgFromLabel(Int_t label) const {
ba15fdfb 718 //
719 // Get particle code using the label from stack
d191916c 720 // NOTE: for tracks, the absolute label should be passed
ba15fdfb 721 //
722 if(label<0) return 0;
723 if(fAnaType==kAOD) {
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();
729 }
730 return 0;
731}
732
733
734//________________________________________________________________________________
5720c765 735Bool_t AliDielectronMC::ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion, Bool_t checkBothCharges) const {
ba15fdfb 736 //
737 // Test the PDG codes of particles with the required ones
738 //
739 Bool_t result = kTRUE;
740 Int_t absRequiredPDG = TMath::Abs(requiredPDG);
5720c765 741
ba15fdfb 742 switch(absRequiredPDG) {
743 case 0:
744 result = kTRUE; // PDG not required (any code will do fine)
745 break;
5720c765 746 case 100: // light flavoured mesons
ba15fdfb 747 if(checkBothCharges)
5720c765 748 result = TMath::Abs(particlePDG)>=100 && TMath::Abs(particlePDG)<=199;
ba15fdfb 749 else {
5720c765 750 if(requiredPDG>0) result = particlePDG>=100 && particlePDG<=199;
751 if(requiredPDG<0) result = particlePDG>=-199 && particlePDG<=-100;
ba15fdfb 752 }
753 break;
5720c765 754 case 1000: // light flavoured baryons
ba15fdfb 755 if(checkBothCharges)
5720c765 756 result = TMath::Abs(particlePDG)>=1000 && TMath::Abs(particlePDG)<=1999;
ba15fdfb 757 else {
5720c765 758 if(requiredPDG>0) result = particlePDG>=1000 && particlePDG<=1999;
759 if(requiredPDG<0) result = particlePDG>=-1999 && particlePDG<=-1000;
ba15fdfb 760 }
761 break;
5720c765 762 case 200: // light flavoured mesons
ba15fdfb 763 if(checkBothCharges)
5720c765 764 result = TMath::Abs(particlePDG)>=200 && TMath::Abs(particlePDG)<=299;
ba15fdfb 765 else {
5720c765 766 if(requiredPDG>0)result = particlePDG>=200 && particlePDG<=299;
767 if(requiredPDG<0)result = particlePDG>=-299 && particlePDG<=-200;
ba15fdfb 768 }
769 break;
5720c765 770 case 2000: // light flavoured baryons
ba15fdfb 771 if(checkBothCharges)
5720c765 772 result = TMath::Abs(particlePDG)>=2000 && TMath::Abs(particlePDG)<=2999;
ba15fdfb 773 else {
5720c765 774 if(requiredPDG>0) result = particlePDG>=2000 && particlePDG<=2999;
775 if(requiredPDG<0) result = particlePDG>=-2999 && particlePDG<=-2000;
ba15fdfb 776 }
777 break;
778 case 300: // all strange mesons
779 if(checkBothCharges)
780 result = TMath::Abs(particlePDG)>=300 && TMath::Abs(particlePDG)<=399;
781 else {
782 if(requiredPDG>0) result = particlePDG>=300 && particlePDG<=399;
783 if(requiredPDG<0) result = particlePDG>=-399 && particlePDG<=-300;
784 }
785 break;
786 case 3000: // all strange baryons
787 if(checkBothCharges)
788 result = TMath::Abs(particlePDG)>=3000 && TMath::Abs(particlePDG)<=3999;
789 else {
790 if(requiredPDG>0) result = particlePDG>=3000 && particlePDG<=3999;
791 if(requiredPDG<0) result = particlePDG>=-3999 && particlePDG<=-3000;
792 }
793 break;
794 case 400: // all charmed mesons
795 if(checkBothCharges)
796 result = TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=499;
797 else {
798 if(requiredPDG>0) result = particlePDG>=400 && particlePDG<=499;
799 if(requiredPDG<0) result = particlePDG>=-499 && particlePDG<=-400;
800 }
801 break;
5720c765 802 case 401: // open charm mesons
803 if(checkBothCharges)
804 result = TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439;
805 else {
806 if(requiredPDG>0) result = particlePDG>=400 && particlePDG<=439;
807 if(requiredPDG<0) result = particlePDG>=-439 && particlePDG<=-400;
808 }
809 break;
810 case 402: // open charm mesons and baryons together
811 if(checkBothCharges)
812 result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439) ||
813 (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399);
814 else {
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);
819 }
820 break;
821 case 403: // all charm hadrons
822 if(checkBothCharges)
823 result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=499) ||
824 (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999);
825 else {
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);
830 }
831 break;
ba15fdfb 832 case 4000: // all charmed baryons
833 if(checkBothCharges)
834 result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999;
835 else {
836 if(requiredPDG>0) result = particlePDG>=4000 && particlePDG<=4999;
837 if(requiredPDG<0) result = particlePDG>=-4999 && particlePDG<=-4000;
838 }
839 break;
5720c765 840 case 4001: // open charm baryons
841 if(checkBothCharges)
842 result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399;
843 else {
844 if(requiredPDG>0) result = particlePDG>=4000 && particlePDG<=4399;
845 if(requiredPDG<0) result = particlePDG>=-4399 && particlePDG<=-4000;
846 }
847 break;
ba15fdfb 848 case 500: // all beauty mesons
849 if(checkBothCharges)
850 result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599;
851 else {
852 if(requiredPDG>0) result = particlePDG>=500 && particlePDG<=599;
853 if(requiredPDG<0) result = particlePDG>=-599 && particlePDG<=-500;
854 }
855 break;
5720c765 856 case 501: // open beauty mesons
857 if(checkBothCharges)
858 result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549;
859 else {
860 if(requiredPDG>0) result = particlePDG>=500 && particlePDG<=549;
861 if(requiredPDG<0) result = particlePDG>=-549 && particlePDG<=-500;
862 }
863 break;
864 case 502: // open beauty mesons and baryons
865 if(checkBothCharges)
866 result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549) ||
867 (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499);
868 else {
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);
873 }
874 break;
875 case 503: // all beauty hadrons
876 if(checkBothCharges)
877 result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599) ||
878 (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999);
879 else {
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);
884 }
885 break;
ba15fdfb 886 case 5000: // all beauty baryons
887 if(checkBothCharges)
888 result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999;
889 else {
890 if(requiredPDG>0) result = particlePDG>=5000 && particlePDG<=5999;
891 if(requiredPDG<0) result = particlePDG>=-5999 && particlePDG<=-5000;
892 }
893 break;
5720c765 894 case 5001: // open beauty baryons
895 if(checkBothCharges)
896 result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499;
897 else {
898 if(requiredPDG>0) result = particlePDG>=5000 && particlePDG<=5499;
899 if(requiredPDG<0) result = particlePDG>=-5499 && particlePDG<=-5000;
900 }
901 break;
c72d368f 902 case 902: // // open charm,beauty mesons and baryons together
903 if(checkBothCharges)
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);
908 else {
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);
917 }
918 break;
ba15fdfb 919 default: // all specific cases
920 if(checkBothCharges)
921 result = (absRequiredPDG==TMath::Abs(particlePDG));
922 else
923 result = (requiredPDG==particlePDG);
924 }
925
5720c765 926 if(absRequiredPDG!=0 && pdgExclusion) result = !result;
ba15fdfb 927 return result;
928}
929
5720c765 930//________________________________________________________________________________
931Bool_t AliDielectronMC::IsPhysicalPrimary(Int_t label) const {
932 //
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
942 //
943 if(label<0) return kFALSE;
944 if(fAnaType==kAOD) {
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);
950 }
951 return kFALSE;
952}
953
ad4edb42 954//________________________________________________________________________________
955Bool_t AliDielectronMC::IsSecondaryFromWeakDecay(Int_t label) const {
956 //
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)
959 //
960 if(label<0) return kFALSE;
961 if(fAnaType==kAOD) {
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);
967 }
968 return kFALSE;
969}
970
971//________________________________________________________________________________
972Bool_t AliDielectronMC::IsSecondaryFromMaterial(Int_t label) const {
973 //
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)
976 //
977 if(label<0) return kFALSE;
978 if(fAnaType==kAOD) {
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);
984 }
985 return kFALSE;
986}
987
5720c765 988
ffcd7c9e 989//________________________________________________________________________________
990Bool_t AliDielectronMC::CheckGEANTProcess(Int_t label, TMCProcess process) const {
991 //
992 // Check the GEANT process for the particle
993 // NOTE: for tracks the absolute label should be passed
994 //
995 if(label<0) return kFALSE;
996 if(fAnaType==kAOD) {
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 "));
1004 return kFALSE;
1005 }
1006 return kFALSE;
1007
1008}
1009
ba15fdfb 1010//________________________________________________________________________________
c8f0f810 1011Bool_t AliDielectronMC::CheckParticleSource(Int_t label, AliDielectronSignalMC::ESource source) const {
ba15fdfb 1012 //
1013 // Check the source for the particle
d191916c 1014 // NOTE: for tracks the absolute label should be passed
ba15fdfb 1015 //
1016
1017 switch (source) {
1018 case AliDielectronSignalMC::kDontCare :
1019 return kTRUE;
1020 break;
5720c765 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());
ba15fdfb 1027 break;
5720c765 1028 case AliDielectronSignalMC::kFinalState :
1029 // primary particles created in the collision which reach the detectors
1030 // These would be:
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);
ba15fdfb 1038 break;
1039 case AliDielectronSignalMC::kDirect :
5720c765 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);
1047 break;
1ae2dca4 1048 case AliDielectronSignalMC::kNoCocktail :
1049 // Particles from the HIJING event and NOT from the AliGenCocktail
1050 return (label>=0 && GetMothersLabel(label)>=0);
1051 break;
5720c765 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));
ba15fdfb 1056 break;
ad4edb42 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));
1061 break;
1062 case AliDielectronSignalMC::kSecondaryFromMaterial :
1063 // secondary particle from material
1064 return (IsSecondaryFromMaterial(label));
1065 break;
ba15fdfb 1066 default :
1067 return kFALSE;
1068 }
1069 return kFALSE;
1070}
1071
ef37a5a8 1072//________________________________________________________________________________
ee877a49 1073Bool_t AliDielectronMC::CheckIsRadiative(Int_t label) const
ef37a5a8 1074{
1075 //
1076 // Check if the particle has a three body decay, one being a photon
1077 //
1078 if(label<0) return kFALSE;
ee877a49 1079
1080
ef37a5a8 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));
ef37a5a8 1092 if (!mother) return kFALSE;
1ae2dca4 1093 const Int_t nd=(mother->GetLastDaughter()-mother->GetFirstDaughter()+1);
ef37a5a8 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
1097 }
1098 return kTRUE;
1099}
ba15fdfb 1100
1101//________________________________________________________________________________
ee877a49 1102Bool_t AliDielectronMC::CheckRadiativeDecision(Int_t mLabel, const AliDielectronSignalMC * const signalMC) const
1103{
1104 //
1105 // Check for the decision of the radiative type request
1106 //
1107
1108 if (!signalMC) return kFALSE;
1109
1110 if (signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kAll) return kTRUE;
1111
1112 Bool_t isRadiative=CheckIsRadiative(mLabel);
1113 if ((signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kIsRadiative) && !isRadiative) return kFALSE;
1114 if ((signalMC->GetJpsiRadiative()==AliDielectronSignalMC::kIsNotRadiative) && isRadiative) return kFALSE;
1115
1116 return kTRUE;
1117}
1118
1119//________________________________________________________________________________
1120Bool_t AliDielectronMC::IsMCTruth(Int_t label, AliDielectronSignalMC* signalMC, Int_t branch) const {
ba15fdfb 1121 //
1122 // Check if the particle corresponds to the MC truth in signalMC in the branch specified
1123 //
1124
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;
5720c765 1129
ba15fdfb 1130 AliVParticle* part = GetMCTrackFromMCEvent(label);
5cc8c825 1131 if (!part) {
1132 AliError(Form("Could not find MC particle with label %d",label));
1133 return kFALSE;
1134 }
ffcd7c9e 1135
1136 // check geant process if set
1137 if(signalMC->GetCheckGEANTProcess() && !CheckGEANTProcess(label,signalMC->GetGEANTProcess())) return kFALSE;
1138
ba15fdfb 1139 // check the leg
5720c765 1140 if(!ComparePDG(part->PdgCode(),signalMC->GetLegPDG(branch),signalMC->GetLegPDGexclude(branch),signalMC->GetCheckBothChargesLegs(branch))) return kFALSE;
ba15fdfb 1141 if(!CheckParticleSource(label, signalMC->GetLegSource(branch))) return kFALSE;
1142
1143 // check the mother
1144 AliVParticle* mcMother=0x0;
1145 Int_t mLabel = -1;
1146 if(signalMC->GetMotherPDG(branch)!=0 || signalMC->GetMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
1147 if(part) {
1148 mLabel = GetMothersLabel(label);
1149 mcMother = GetMCTrackFromMCEvent(mLabel);
1150 }
5720c765 1151 if(!mcMother && !signalMC->GetMotherPDGexclude(branch)) return kFALSE;
c72d368f 1152
5720c765 1153 if(!ComparePDG((mcMother ? mcMother->PdgCode() : 0),signalMC->GetMotherPDG(branch),signalMC->GetMotherPDGexclude(branch),signalMC->GetCheckBothChargesMothers(branch))) return kFALSE;
ba15fdfb 1154 if(!CheckParticleSource(mLabel, signalMC->GetMotherSource(branch))) return kFALSE;
ef37a5a8 1155
1156 //check for radiative deday
ee877a49 1157 if (!CheckRadiativeDecision(mLabel, signalMC)) return kFALSE;
ba15fdfb 1158 }
5720c765 1159
ba15fdfb 1160 // check the grandmother
5720c765 1161 AliVParticle* mcGrandMother=0x0;
ba15fdfb 1162 if(signalMC->GetGrandMotherPDG(branch)!=0 || signalMC->GetGrandMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
ba15fdfb 1163 Int_t gmLabel = -1;
1164 if(mcMother) {
1165 gmLabel = GetMothersLabel(mLabel);
1166 mcGrandMother = static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(gmLabel));
1167 }
5720c765 1168 if(!mcGrandMother && !signalMC->GetGrandMotherPDGexclude(branch)) return kFALSE;
ba15fdfb 1169
5720c765 1170 if(!ComparePDG((mcGrandMother ? mcGrandMother->PdgCode() : 0),signalMC->GetGrandMotherPDG(branch),signalMC->GetGrandMotherPDGexclude(branch),signalMC->GetCheckBothChargesGrandMothers(branch))) return kFALSE;
ba15fdfb 1171 if(!CheckParticleSource(gmLabel, signalMC->GetGrandMotherSource(branch))) return kFALSE;
1172 }
1173
1174 return kTRUE;
1175}
1176
1177
5720c765 1178
ba15fdfb 1179//________________________________________________________________________________
c8f0f810 1180Bool_t AliDielectronMC::IsMCTruth(const AliDielectronPair* pair, const AliDielectronSignalMC* signalMC) const {
ba15fdfb 1181 //
1182 // Check if the pair corresponds to the MC truth in signalMC
1183 //
1184
1185 // legs (daughters)
54ce9dc4 1186 const AliVParticle * mcD1 = pair->GetFirstDaughterP();
1187 const AliVParticle * mcD2 = pair->GetSecondDaughterP();
d191916c 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);
ba15fdfb 1192
1193 // mothers
1194 AliVParticle* mcM1=0x0;
1195 AliVParticle* mcM2=0x0;
1196
1197 // grand-mothers
1198 AliVParticle* mcG1 = 0x0;
1199 AliVParticle* mcG2 = 0x0;
1200
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;
1203 // daughters
5720c765 1204 directTerm = directTerm && mcD1 && ComparePDG(d1Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
ba15fdfb 1205 && CheckParticleSource(labelD1, signalMC->GetLegSource(1));
1206
5720c765 1207 directTerm = directTerm && mcD2 && ComparePDG(d2Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
ba15fdfb 1208 && CheckParticleSource(labelD2, signalMC->GetLegSource(2));
1209
1210 // mothers
1211 Int_t labelM1 = -1;
1212 if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1213 labelM1 = GetMothersLabel(labelD1);
1214 if(labelD1>-1 && labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
ee877a49 1215 directTerm = directTerm && (mcM1 || signalMC->GetMotherPDGexclude(1))
5720c765 1216 && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
ee877a49 1217 && CheckParticleSource(labelM1, signalMC->GetMotherSource(1))
1218 && CheckRadiativeDecision(labelM1,signalMC);
ba15fdfb 1219 }
1220
1221 Int_t labelM2 = -1;
1222 if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1223 labelM2 = GetMothersLabel(labelD2);
1224 if(labelD2>-1 && labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
5720c765 1225 directTerm = directTerm && (mcM2 || signalMC->GetMotherPDGexclude(2))
1226 && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
ee877a49 1227 && CheckParticleSource(labelM2, signalMC->GetMotherSource(2))
1228 && CheckRadiativeDecision(labelM2,signalMC);
ba15fdfb 1229 }
1230
1231 // grand-mothers
1232 Int_t labelG1 = -1;
1233 if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1234 labelG1 = GetMothersLabel(labelM1);
1235 if(mcM1 && labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
5720c765 1236 directTerm = directTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(1))
1237 && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
ba15fdfb 1238 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(1));
1239 }
1240
1241 Int_t labelG2 = -1;
1242 if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1243 labelG2 = GetMothersLabel(labelM2);
1244 if(mcM2 && labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
5720c765 1245 directTerm = directTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(2))
1246 && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
ba15fdfb 1247 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(2));
1248 }
1249
1250 // Cross term
1251 Bool_t crossTerm = kTRUE;
1252 // daughters
1253 crossTerm = crossTerm && mcD2
5720c765 1254 && ComparePDG(d2Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
ba15fdfb 1255 && CheckParticleSource(labelD2, signalMC->GetLegSource(1));
1256
1257 crossTerm = crossTerm && mcD1
5720c765 1258 && ComparePDG(d1Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
ba15fdfb 1259 && CheckParticleSource(labelD1, signalMC->GetLegSource(2));
1260
1261 // mothers
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);
1266 }
5720c765 1267 crossTerm = crossTerm && (mcM2 || signalMC->GetMotherPDGexclude(1))
1268 && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
ee877a49 1269 && CheckParticleSource(labelM2, signalMC->GetMotherSource(1))
1270 && CheckRadiativeDecision(labelM2,signalMC);
ba15fdfb 1271 }
1272
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);
1277 }
5720c765 1278 crossTerm = crossTerm && (mcM1 || signalMC->GetMotherPDGexclude(2))
1279 && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
ee877a49 1280 && CheckParticleSource(labelM1, signalMC->GetMotherSource(2))
1281 && CheckRadiativeDecision(labelM1,signalMC);
ba15fdfb 1282 }
1283
1284 // grand-mothers
1285 if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
1286 if(!mcG2 && mcM2) {
1287 labelG2 = GetMothersLabel(labelM2);
1288 if(labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
1289 }
5720c765 1290 crossTerm = crossTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(1))
1291 && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
ba15fdfb 1292 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(1));
1293 }
1294
1295 if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
1296 if(!mcG1 && mcM1) {
1297 labelG1 = GetMothersLabel(labelM1);
cff21183 1298 if(labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
ba15fdfb 1299 }
5720c765 1300 crossTerm = crossTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(2))
1301 && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
ba15fdfb 1302 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(2));
1303 }
1304
1305 Bool_t motherRelation = kTRUE;
1306 if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kSame) {
1307 motherRelation = motherRelation && HaveSameMother(pair);
1308 }
1309 if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent) {
1310 motherRelation = motherRelation && !HaveSameMother(pair);
1311 }
ffcd7c9e 1312
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;
1318 }
1319
1320 return ((directTerm || crossTerm) && motherRelation && processGEANT);
ba15fdfb 1321}
1322
1323
1324
8df8e382 1325//____________________________________________________________
c8f0f810 1326Bool_t AliDielectronMC::HaveSameMother(const AliDielectronPair * pair) const
8df8e382 1327{
1328 //
1329 // Check whether two particles have the same mother
1330 //
1331
54ce9dc4 1332 const AliVParticle * daughter1 = pair->GetFirstDaughterP();
1333 const AliVParticle * daughter2 = pair->GetSecondDaughterP();
5720c765 1334 if (!daughter1 || !daughter2) return 0;
8df8e382 1335
83e37742 1336 AliVParticle *mcDaughter1=GetMCTrackFromMCEvent(daughter1->GetLabel());
1337 AliVParticle *mcDaughter2=GetMCTrackFromMCEvent(daughter2->GetLabel());
8df8e382 1338 if (!mcDaughter1 || !mcDaughter2) return 0;
1339
83e37742 1340 Int_t labelMother1=-1;
1341 Int_t labelMother2=-1;
8df8e382 1342
83e37742 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();
1349 }
8df8e382 1350
83e37742 1351 Bool_t sameMother=(labelMother1>-1)&&(labelMother2>-1)&&(labelMother1==labelMother2);
8df8e382 1352
83e37742 1353 return sameMother;
8df8e382 1354}
1355
fb7d2d99 1356//________________________________________________________________
1357Int_t AliDielectronMC::IsJpsiPrimary(const AliDielectronPair * pair)
1358{
1359 // return: "0" for primary jpsi
1360 // "1" for secondary jpsi (from beauty)
1361 // "2" for background
1362 if(!HaveSameMother(pair)) return 2;
54ce9dc4 1363 AliVParticle *mcDaughter1=GetMCTrackFromMCEvent((pair->GetFirstDaughterP())->GetLabel());
fb7d2d99 1364 Int_t labelMother=-1;
8df8e382 1365
fb7d2d99 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();
1370 }
1371
1372 AliVParticle* mcMother=GetMCTrackFromMCEvent(labelMother);
1373 if(!IsMCMotherToEE(mcMother,443)) return 2;
1374 return IsJpsiPrimary(mcMother);
1375}
1376
1377//______________________________________________________________
1378Int_t AliDielectronMC::IsJpsiPrimary(const AliVParticle * particle)
1379{
1380 // return: "0" for primary jpsi
1381 // "1" for secondary jpsi (come from B decay)
1382 Int_t labelMoth=-1;
1383 Int_t pdgCode;
1384
1385 if (particle->IsA()==AliMCParticle::Class()){
1386 labelMoth = (static_cast<const AliMCParticle*>(particle))->GetMother();
1387 while(labelMoth>0){
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();
1392 }
1393 }
1394 else if (particle->IsA()==AliAODMCParticle::Class()){
1395 labelMoth = (static_cast<const AliAODMCParticle*>(particle))->GetMother();
1396 while(labelMoth>0){
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();
1401 }
1402 }
1403 return 0;
1404}
4533e78e 1405
1406
1407Bool_t AliDielectronMC::GetPrimaryVertex(Double_t &primVtxX, Double_t &primVtxY, Double_t &primVtxZ){
1408
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();
5fd52e70 1417 if(!aod) return kFALSE;
4533e78e 1418 AliAODMCHeader *mcHead = dynamic_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
5fd52e70 1419 if(!mcHead) return kFALSE;
4533e78e 1420 primVtxX = mcHead->GetVtxX();
1421 primVtxY = mcHead->GetVtxY();
1422 primVtxZ = mcHead->GetVtxZ();
1423 }
1424
1425return kTRUE;
1426}