CbmRoot
Loading...
Searching...
No Matches
PairAnalysisMC.cxx
Go to the documentation of this file.
1
2// //
3// //
4// Authors: //
5// * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
6// Julian Book <Julian.Book@cern.ch>
7/*
8
9 Finds signal in the MC stack that are defined via PairAnalysisSignalMC
10
11 */
12// //
14
15
16#include "PairAnalysisMC.h"
17
18#include "CbmMCTrack.h"
19
20#include "FairRootManager.h"
21
22#include <TClonesArray.h>
23#include <TMCProcess.h>
24#include <TPDGCode.h>
25#include <TParticle.h>
26
28#include "PairAnalysisTrack.h"
29
30
32
34
35//____________________________________________________________
37{
38 //
39 // return pointer to singleton implementation
40 //
41 if (fgInstance) return fgInstance;
42
44 // fgInstance->SetHasMC(kTRUE);
45
46 return fgInstance;
47}
48
49//____________________________________________________________
50PairAnalysisMC::PairAnalysisMC() : fMCEvent(0x0), fHasMC(kFALSE), fMCArray(0x0)
51{
52 //
53 // default constructor
54 //
55}
56
57
58//____________________________________________________________
60{
61 //
62 // default destructor
63 //
64}
65
66//____________________________________________________________
68{
69 //
70 // return the number of generated tracks from MC event
71 //
72 if (!fMCArray) {
73 Error("PairAnalysisMC::", "No fMCArray");
74 return 0;
75 }
76 return fMCArray->GetEntriesFast();
77}
78
79//____________________________________________________________
81{
82 //
83 // return MC track directly from MC event
84 // used not only for tracks but for mothers as well, therefore do not use abs(label)
85 //
86 if (label < 0) return NULL;
87 if (!fMCArray) {
88 Error("PairAnalysisMC::", "No fMCArray");
89 return NULL;
90 }
91
92 if (label > fMCArray->GetEntriesFast()) {
93 Info("PairAnalysisMC::", "track %d out of array size %d", label, fMCArray->GetEntriesFast());
94 return NULL;
95 }
96
97 CbmMCTrack* track = static_cast<CbmMCTrack*>(fMCArray->UncheckedAt(label)); // tracks from MC event
98 // CbmMCTrack *track = static_cast<CbmMCTrack*>( fMCArray->At(label) ); // tracks from MC event
99 return track;
100}
101
102//____________________________________________________________
104{
105 //
106 // connect MC array of tracks
107 //
108
109 fMCArray = 0x0;
110 fMCEvent = 0x0;
111
112 FairRootManager* man = FairRootManager::Instance();
113 if (!man) { Fatal("PairAnalysisMC::Instance", "No FairRootManager!"); }
114
115 fMCArray = dynamic_cast<TClonesArray*>(man->GetObject("MCTrack"));
116 if (!fMCArray) {
117 Error("PairAnalysisMC::Instance", "Initialization of MC object failed!");
118 return kFALSE;
119 }
120 else
121 fHasMC = kTRUE;
122 // printf("PairAnalysisMC::ConnectMCEvent: size of mc array: %04d \n",fMCArray->GetSize());
123 return kTRUE;
124}
125
126
127//____________________________________________________________
129{
130 //
131 // return MC track
132 //
133 return (_track->GetMCTrack());
134}
135
136//______________________________________________________________
138{
139 //
140 // return MC track mother
141 //
142 CbmMCTrack* mcpart = GetMCTrack(_track);
143 if (!mcpart) return NULL;
144 return (GetMCTrackMother(mcpart));
145}
146
147//____________________________________________________________
149{
150 //
151 // return MC track mother
152 //
153 if (_particle->GetMotherId() < 0) return NULL;
154 CbmMCTrack* mcmother = dynamic_cast<CbmMCTrack*>(fMCArray->At(_particle->GetMotherId()));
155 return mcmother;
156}
157
158
159//________________________________________________________
161{
162 //
163 // return PDG code of the mother track from the MC truth info
164 //
165 CbmMCTrack* mcmother = GetMCTrackMother(_track);
166 if (!mcmother) return -99999;
167 return mcmother->GetPdgCode();
168}
169
170//________________________________________________________
172{
173 //
174 // return PDG code of the mother track from the MC truth info
175 //
176 if (!_track) return -99999;
177 CbmMCTrack* mcmother = GetMCTrackMother(_track);
178 if (!mcmother) return -99999;
179 return mcmother->GetPdgCode();
180}
181
182//____________________________________________________________
184{
185 //
186 // returns the number of daughters
187 //
188 CbmMCTrack* mcmother = GetMCTrackMother(particle);
189 if (!mcmother) return -9999;
190 return 0; //TODO: maybe request number of daughters or remove function
191 //mcmother->GetNDaughters();
192}
193
194//____________________________________________________________
196 Int_t pdgMother)
197{
198 //
199 // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
200 //
201 if (!fMCArray) return -1;
202 CbmMCTrack* mcPart1 = particle1->GetMCTrack();
203 CbmMCTrack* mcPart2 = particle2->GetMCTrack();
204 if (!mcPart1 || !mcPart2) return -1;
205
206 // get mother
207 Int_t lblMother1 = mcPart1->GetMotherId();
208 Int_t lblMother2 = mcPart2->GetMotherId();
209 if (lblMother1 != lblMother2) return -1;
210 CbmMCTrack* mcMother1 = GetMCTrackFromMCEvent(lblMother1);
211 if (!mcMother1) return -1;
212
213 // compare mc truth with expectation
214 if (TMath::Abs(mcPart1->GetPdgCode()) != particle1->PdgCode()) return -1;
215 if (TMath::Abs(mcPart2->GetPdgCode()) != particle2->PdgCode()) return -1;
216 // if (mcPart1->GetPdgCode()!=-mcPart2->GetPdgCode()) return -1;
217 if (mcMother1->GetPdgCode() != pdgMother) return -1;
218
219 return lblMother1;
220}
221
222//____________________________________________________________
223void PairAnalysisMC::GetDaughters(const TObject* /*mother*/, CbmMCTrack*& d1, CbmMCTrack*& d2)
224{
225 //
226 // Get First two daughters of the mother
227 // TODO: theres NO connection from mother to daughters
228 // Int_t lblD1=-1;
229 // Int_t lblD2=-1;
230 d1 = 0;
231 d2 = 0;
232 if (!fMCArray) return;
233 return; // TOBEDONE
234 /*
235 const CbmMCTrack *mom=static_cast<const CbmMCTrack*>(mother);
236 lblD1=mom->GetDaughter(0);
237 lblD2=mom->GetDaughter(1);
238 d1 = (CbmMCTrack*)fMCArray->At(lblD1);
239 d2 = (CbmMCTrack*)fMCArray->At(lblD2);
240 */
241}
242
243
244//________________________________________________________________________________
245Int_t PairAnalysisMC::GetMothersLabel(Int_t daughterLabel) const
246{
247 //
248 // Get the label of the mother for particle with label daughterLabel
249 // NOTE: for tracks, the absolute label should be passed
250 //
251 if (daughterLabel < 0) return -1;
252 if (!fMCArray) return -1;
253 if (GetMCTrackFromMCEvent(daughterLabel)) return (GetMCTrackFromMCEvent(daughterLabel))->GetMotherId();
254 return -1;
255}
256
257
258//________________________________________________________________________________
259Int_t PairAnalysisMC::GetPdgFromLabel(Int_t label) const
260{
261 //
262 // Get particle code using the label from stack
263 // NOTE: for tracks, the absolute label should be passed
264 //
265 if (label < 0) return 0;
266 if (!fMCArray) return 0;
267 return (GetMCTrackFromMCEvent(label)->GetPdgCode());
268 return 0;
269}
270
271
272//________________________________________________________________________________
273Bool_t PairAnalysisMC::ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion,
274 Bool_t checkBothCharges) const
275{
276 //
277 // Test the PDG codes of particles with the required ones
278 //
279 Bool_t result = kTRUE;
280 Int_t absRequiredPDG = TMath::Abs(requiredPDG);
281
282 switch (absRequiredPDG) {
283 case 0:
284 result = kTRUE; // PDG not required (any code will do fine)
285 break;
286 case 100: // light flavoured mesons
287 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 100 && TMath::Abs(particlePDG) <= 199;
288 else {
289 if (requiredPDG > 0) result = particlePDG >= 100 && particlePDG <= 199;
290 if (requiredPDG < 0) result = particlePDG >= -199 && particlePDG <= -100;
291 }
292 break;
293 case 1000: // light flavoured baryons
294 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 1000 && TMath::Abs(particlePDG) <= 1999;
295 else {
296 if (requiredPDG > 0) result = particlePDG >= 1000 && particlePDG <= 1999;
297 if (requiredPDG < 0) result = particlePDG >= -1999 && particlePDG <= -1000;
298 }
299 break;
300 case 200: // light flavoured mesons
301 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 200 && TMath::Abs(particlePDG) <= 299;
302 else {
303 if (requiredPDG > 0) result = particlePDG >= 200 && particlePDG <= 299;
304 if (requiredPDG < 0) result = particlePDG >= -299 && particlePDG <= -200;
305 }
306 break;
307 case 2000: // light flavoured baryons
308 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 2000 && TMath::Abs(particlePDG) <= 2999;
309 else {
310 if (requiredPDG > 0) result = particlePDG >= 2000 && particlePDG <= 2999;
311 if (requiredPDG < 0) result = particlePDG >= -2999 && particlePDG <= -2000;
312 }
313 break;
314 case 300: // all strange mesons
315 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 300 && TMath::Abs(particlePDG) <= 399;
316 else {
317 if (requiredPDG > 0) result = particlePDG >= 300 && particlePDG <= 399;
318 if (requiredPDG < 0) result = particlePDG >= -399 && particlePDG <= -300;
319 }
320 break;
321 case 3000: // all strange baryons
322 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 3000 && TMath::Abs(particlePDG) <= 3999;
323 else {
324 if (requiredPDG > 0) result = particlePDG >= 3000 && particlePDG <= 3999;
325 if (requiredPDG < 0) result = particlePDG >= -3999 && particlePDG <= -3000;
326 }
327 break;
328 case 400: // all charmed mesons
329 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 400 && TMath::Abs(particlePDG) <= 499;
330 else {
331 if (requiredPDG > 0) result = particlePDG >= 400 && particlePDG <= 499;
332 if (requiredPDG < 0) result = particlePDG >= -499 && particlePDG <= -400;
333 }
334 break;
335 case 401: // open charm mesons
336 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 400 && TMath::Abs(particlePDG) <= 439;
337 else {
338 if (requiredPDG > 0) result = particlePDG >= 400 && particlePDG <= 439;
339 if (requiredPDG < 0) result = particlePDG >= -439 && particlePDG <= -400;
340 }
341 break;
342 case 402: // open charm mesons and baryons together
343 if (checkBothCharges)
344 result = (TMath::Abs(particlePDG) >= 400 && TMath::Abs(particlePDG) <= 439)
345 || (TMath::Abs(particlePDG) >= 4000 && TMath::Abs(particlePDG) <= 4399);
346 else {
347 if (requiredPDG > 0)
348 result = (particlePDG >= 400 && particlePDG <= 439) || (particlePDG >= 4000 && particlePDG <= 4399);
349 if (requiredPDG < 0)
350 result = (particlePDG >= -439 && particlePDG <= -400) || (particlePDG >= -4399 && particlePDG <= -4000);
351 }
352 break;
353 case 403: // all charm hadrons
354 if (checkBothCharges)
355 result = (TMath::Abs(particlePDG) >= 400 && TMath::Abs(particlePDG) <= 499)
356 || (TMath::Abs(particlePDG) >= 4000 && TMath::Abs(particlePDG) <= 4999);
357 else {
358 if (requiredPDG > 0)
359 result = (particlePDG >= 400 && particlePDG <= 499) || (particlePDG >= 4000 && particlePDG <= 4999);
360 if (requiredPDG < 0)
361 result = (particlePDG >= -499 && particlePDG <= -400) || (particlePDG >= -4999 && particlePDG <= -4000);
362 }
363 break;
364 case 4000: // all charmed baryons
365 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 4000 && TMath::Abs(particlePDG) <= 4999;
366 else {
367 if (requiredPDG > 0) result = particlePDG >= 4000 && particlePDG <= 4999;
368 if (requiredPDG < 0) result = particlePDG >= -4999 && particlePDG <= -4000;
369 }
370 break;
371 case 4001: // open charm baryons
372 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 4000 && TMath::Abs(particlePDG) <= 4399;
373 else {
374 if (requiredPDG > 0) result = particlePDG >= 4000 && particlePDG <= 4399;
375 if (requiredPDG < 0) result = particlePDG >= -4399 && particlePDG <= -4000;
376 }
377 break;
378 case 500: // all beauty mesons
379 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 500 && TMath::Abs(particlePDG) <= 599;
380 else {
381 if (requiredPDG > 0) result = particlePDG >= 500 && particlePDG <= 599;
382 if (requiredPDG < 0) result = particlePDG >= -599 && particlePDG <= -500;
383 }
384 break;
385 case 501: // open beauty mesons
386 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 500 && TMath::Abs(particlePDG) <= 549;
387 else {
388 if (requiredPDG > 0) result = particlePDG >= 500 && particlePDG <= 549;
389 if (requiredPDG < 0) result = particlePDG >= -549 && particlePDG <= -500;
390 }
391 break;
392 case 502: // open beauty mesons and baryons
393 if (checkBothCharges)
394 result = (TMath::Abs(particlePDG) >= 500 && TMath::Abs(particlePDG) <= 549)
395 || (TMath::Abs(particlePDG) >= 5000 && TMath::Abs(particlePDG) <= 5499);
396 else {
397 if (requiredPDG > 0)
398 result = (particlePDG >= 500 && particlePDG <= 549) || (particlePDG >= 5000 && particlePDG <= 5499);
399 if (requiredPDG < 0)
400 result = (particlePDG >= -549 && particlePDG <= -500) || (particlePDG >= -5499 && particlePDG <= -5000);
401 }
402 break;
403 case 503: // all beauty hadrons
404 if (checkBothCharges)
405 result = (TMath::Abs(particlePDG) >= 500 && TMath::Abs(particlePDG) <= 599)
406 || (TMath::Abs(particlePDG) >= 5000 && TMath::Abs(particlePDG) <= 5999);
407 else {
408 if (requiredPDG > 0)
409 result = (particlePDG >= 500 && particlePDG <= 599) || (particlePDG >= 5000 && particlePDG <= 5999);
410 if (requiredPDG < 0)
411 result = (particlePDG >= -599 && particlePDG <= -500) || (particlePDG >= -5999 && particlePDG <= -5000);
412 }
413 break;
414 case 5000: // all beauty baryons
415 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 5000 && TMath::Abs(particlePDG) <= 5999;
416 else {
417 if (requiredPDG > 0) result = particlePDG >= 5000 && particlePDG <= 5999;
418 if (requiredPDG < 0) result = particlePDG >= -5999 && particlePDG <= -5000;
419 }
420 break;
421 case 5001: // open beauty baryons
422 if (checkBothCharges) result = TMath::Abs(particlePDG) >= 5000 && TMath::Abs(particlePDG) <= 5499;
423 else {
424 if (requiredPDG > 0) result = particlePDG >= 5000 && particlePDG <= 5499;
425 if (requiredPDG < 0) result = particlePDG >= -5499 && particlePDG <= -5000;
426 }
427 break;
428 case 902: // // open charm,beauty mesons and baryons together
429 if (checkBothCharges)
430 result = (TMath::Abs(particlePDG) >= 400 && TMath::Abs(particlePDG) <= 439)
431 || (TMath::Abs(particlePDG) >= 4000 && TMath::Abs(particlePDG) <= 4399)
432 || (TMath::Abs(particlePDG) >= 500 && TMath::Abs(particlePDG) <= 549)
433 || (TMath::Abs(particlePDG) >= 5000 && TMath::Abs(particlePDG) <= 5499);
434 else {
435 if (requiredPDG > 0)
436 result = (particlePDG >= 400 && particlePDG <= 439) || (particlePDG >= 4000 && particlePDG <= 4399)
437 || (particlePDG >= 500 && particlePDG <= 549) || (particlePDG >= 5000 && particlePDG <= 5499);
438 if (requiredPDG < 0)
439 result = (particlePDG >= -439 && particlePDG <= -400) || (particlePDG >= -4399 && particlePDG <= -4000)
440 || (particlePDG >= -549 && particlePDG <= -500) || (particlePDG >= -5499 && particlePDG <= -5000);
441 }
442 break;
443 default: // all specific cases
444 if (checkBothCharges) result = (absRequiredPDG == TMath::Abs(particlePDG));
445 else
446 result = (requiredPDG == particlePDG);
447 }
448
449 if (absRequiredPDG != 0 && pdgExclusion) result = !result;
450 return result;
451}
452
453//________________________________________________________________________________
454Bool_t PairAnalysisMC::CheckGEANTProcess(Int_t label, TMCProcess process) const
455{
456 //
457 // Check the GEANT process for the particle
458 //
459 if (label < 0) return kFALSE;
460
461 if (!fMCArray) return kFALSE;
462 UInt_t processID = static_cast<CbmMCTrack*>(GetMCTrackFromMCEvent(label))->GetGeantProcessId();
463 // printf("process: id %d --> %s \n",processID,TMCProcessName[processID]);
464 return (process == processID);
465}
466
467//________________________________________________________________________________
469{
470 //
471 // Check the source for the particle
472 // NOTE: TODO: check and clarify different sources, UPDATE!
473 //
474
475 UInt_t processID = 9999999;
476 if (label > 0) processID = static_cast<CbmMCTrack*>(GetMCTrackFromMCEvent(label))->GetGeantProcessId();
477 // printf("process: id %d --> %s \n",processID,TMCProcessName[processID]);
478
479 switch (source) {
480 case PairAnalysisSignalMC::ESource::kDontCare: return kTRUE; break;
482 // NOTE: This includes all physics event history (initial state particles,
483 // exchange bosons, quarks, di-quarks, strings, un-stable particles, final state particles)
484 // Only the final state particles make it to the detector!!
485 return (processID == kPPrimary);
486 break;
488 // particles which are created by the interaction of final state primaries with the detector
489 // or particles from strange weakly decaying particles (e.g. lambda, kaons, etc.)
490 return (!IsPhysicalPrimary(label, processID));
491 break;
493 // primary particles created in the collision which reach the detectors
494 // These would be:
495 // 1.) particles produced in the collision
496 // 2.) stable particles with respect to strong and electromagnetic interactions
497 // 3.) excludes initial state particles
498 // 4.) includes products of directly produced Sigma0 hyperon decay
499 // 5.) includes products of directly produced pi0 decays
500 // 6.) includes products of directly produced beauty hadron decays
501 return IsPhysicalPrimary(label, processID);
502 break;
504 // Primary particles which do not have any mother
505 // This is the case for:
506 // 1.) Initial state particles (the 2 protons in Pythia pp collisions)
507 // 2.) In some codes, with sudden freeze-out, all particles generated from the fireball are direct.
508 // There is no history for these particles.
509 // 3.) Certain particles added via MC generator cocktails (e.g. J/psi added to pythia MB events)
510 return (label >= 0 && GetMothersLabel(label) < 0);
511 break;
513 // secondary particle from weak decay
514 // or particles from strange weakly decaying particles (e.g. lambda, kaons, etc.)
515 return (IsSecondaryFromWeakDecay(label, processID));
516 break;
518 // secondary particle from material
519 return (IsSecondaryFromMaterial(label, processID));
520 break;
521 default: return kFALSE;
522 }
523 return kFALSE;
524}
525
526//________________________________________________________________________________
527Bool_t PairAnalysisMC::CheckIsDalitz(Int_t label, const PairAnalysisSignalMC* const signalMC) const
528{
529 //
530 // Check if the particle has a three body decay, one being a dalitz pdg
531 // NOTE: no information on # of daugthers available in CbmMCTrack
532
533 // loop over the MC tracks
534 // for(Int_t ipart=0; ipart<fMCArray->GetEntriesFast(); ++ipart) { // super slow
535 for (Int_t ipart = label; ipart < label + 5; ++ipart) { // embedded particles are sorted
536 CbmMCTrack* daughter = static_cast<CbmMCTrack*>(GetMCTrackFromMCEvent(ipart));
537 if (!daughter) continue;
538 if (daughter->GetPdgCode() != signalMC->GetDalitzPdg()) continue;
539 if (daughter->GetMotherId() == label) return kTRUE;
540 }
541 return kFALSE;
542}
543
544//________________________________________________________________________________
545Bool_t PairAnalysisMC::CheckDalitzDecision(Int_t mLabel, const PairAnalysisSignalMC* const signalMC) const
546{
547 //
548 // Check for the decision of the dalitz type request
549 //
550
551 if (!signalMC) return kFALSE;
552
553 if (signalMC->GetDalitz() == PairAnalysisSignalMC::EDalitz::kWhoCares) return kTRUE;
554
555 Bool_t isDalitz = CheckIsDalitz(mLabel, signalMC);
556 if ((signalMC->GetDalitz() == PairAnalysisSignalMC::EDalitz::kIsDalitz) && !isDalitz) return kFALSE;
557 if ((signalMC->GetDalitz() == PairAnalysisSignalMC::EDalitz::kIsNotDalitz) && isDalitz) return kFALSE;
558
559 return kTRUE;
560}
561
562//________________________________________________________________________________
563Bool_t PairAnalysisMC::IsMCTruth(Int_t label, PairAnalysisSignalMC* signalMC, Int_t branch) const
564{
565 //
566 // Check if the particle corresponds to the MC truth in signalMC in the branch specified
567 //
568
569 if (label < 0) return kFALSE; // to be checked
570 // if(label<0) label *= -1;
571
573 if (signalMC->IsSingleParticle() && branch > 1) return kFALSE;
574
575 CbmMCTrack* part = GetMCTrackFromMCEvent(label);
576 if (!part) {
577 Error("PairAnalysisMC::", "Could not find MC particle with label %d", label);
578 return kFALSE;
579 }
580
581 // check geant process if set
582 if (signalMC->GetCheckGEANTProcess() && !CheckGEANTProcess(label, signalMC->GetGEANTProcess())) return kFALSE;
583
584
585 // check the LEG
586 if (!ComparePDG(part->GetPdgCode(), signalMC->GetLegPDG(branch), signalMC->GetLegPDGexclude(branch),
587 signalMC->GetCheckBothChargesLegs(branch)))
588 return kFALSE;
589
590
591 // Check the source (primary, secondary, embedded) for the particle
592 if (!CheckParticleSource(label, signalMC->GetLegSource(branch))) return kFALSE;
593
594 // check the MOTHER
595 CbmMCTrack* mcMother = 0x0;
596 Int_t mLabel = -1;
597 if (signalMC->GetMotherPDG(branch) != 0
599 mLabel = GetMothersLabel(label);
600 mcMother = GetMCTrackFromMCEvent(mLabel);
601
602 if (!mcMother && !signalMC->GetMotherPDGexclude(branch)) return kFALSE;
603
604 if (!ComparePDG((mcMother ? mcMother->GetPdgCode() : -99999), signalMC->GetMotherPDG(branch),
605 signalMC->GetMotherPDGexclude(branch), signalMC->GetCheckBothChargesMothers(branch)))
606 return kFALSE;
607 if (!CheckParticleSource(mLabel, signalMC->GetMotherSource(branch))) return kFALSE;
608
609 //check for dalitz decay
610 if (!CheckDalitzDecision(mLabel, signalMC)) return kFALSE;
611 }
612
613 // check the GRANDMOTHER
614 CbmMCTrack* mcGrandMother = 0x0;
615 Int_t gmLabel = -1;
616 if (signalMC->GetGrandMotherPDG(branch) != 0
618 if (mcMother) {
619 gmLabel = GetMothersLabel(mLabel);
620 mcGrandMother = GetMCTrackFromMCEvent(gmLabel);
621 }
622 if (!mcGrandMother && !signalMC->GetGrandMotherPDGexclude(branch)) return kFALSE;
623
624 if (!ComparePDG((mcGrandMother ? mcGrandMother->GetPdgCode() : 0), signalMC->GetGrandMotherPDG(branch),
625 signalMC->GetGrandMotherPDGexclude(branch), signalMC->GetCheckBothChargesGrandMothers(branch)))
626 return kFALSE;
627 if (!CheckParticleSource(gmLabel, signalMC->GetGrandMotherSource(branch))) return kFALSE;
628 }
629
630 // check the GREAT GRANDMOTHER
631 CbmMCTrack* mcGreatGrandMother = 0x0;
632 Int_t ggmLabel = -1;
633 if(signalMC->GetGreatGrandMotherPDG(branch) !=0/* ||
634 signalMC->GetGreatGrandMotherSource(branch)!=PairAnalysisSignalMC::ESource::kDontCare
635 */) {
636 if (mcGrandMother) {
637 ggmLabel = GetMothersLabel(gmLabel);
638 mcGreatGrandMother = GetMCTrackFromMCEvent(ggmLabel);
639 }
640 if (!mcGreatGrandMother && !signalMC->GetGreatGrandMotherPDGexclude(branch)) return kFALSE;
641
642 if (!ComparePDG((mcGreatGrandMother ? mcGreatGrandMother->GetPdgCode() : 0),
643 signalMC->GetGreatGrandMotherPDG(branch), signalMC->GetGreatGrandMotherPDGexclude(branch),
644 signalMC->GetCheckBothChargesGreatGrandMothers(branch)))
645 return kFALSE;
646 // if( !CheckParticleSource(gmLabel, signalMC->GetGreatGrandMotherSource(branch))) return kFALSE;
647 }
648
649 return kTRUE;
650}
651
652//________________________________________________________________________________
653Bool_t PairAnalysisMC::IsMCTruth(const PairAnalysisTrack* trk, PairAnalysisSignalMC* signalMC, Int_t branch) const
654{
655 //
656 // Check if the particle corresponds to the MC truth in signalMC in the branch specified
657 //
658 return IsMCTruth(trk->GetLabel(), signalMC, branch);
659}
660
661//________________________________________________________________________________
662Bool_t PairAnalysisMC::IsMCTruth(const PairAnalysisPair* pair, const PairAnalysisSignalMC* signalMC) const
663{
664 //
665 // Check if the pair corresponds to the MC truth in signalMC
666 //
667
668 // legs (daughters)
669 const PairAnalysisTrack* mcD1 = pair->GetFirstDaughter();
670 const PairAnalysisTrack* mcD2 = pair->GetSecondDaughter();
671 Int_t labelD1 = (mcD1 ? mcD1->GetLabel() : -1);
672 Int_t labelD2 = (mcD2 ? mcD2->GetLabel() : -1);
673 Int_t d1Pdg = GetPdgFromLabel(labelD1);
674 Int_t d2Pdg = GetPdgFromLabel(labelD2);
675
676 // check geant process if set
677 Bool_t processGEANT = kTRUE;
678 if (signalMC->GetCheckGEANTProcess()) {
679 if (!CheckGEANTProcess(labelD1, signalMC->GetGEANTProcess())
680 && !CheckGEANTProcess(labelD2, signalMC->GetGEANTProcess()))
681 return kFALSE;
682 }
683
684 // mothers
685 CbmMCTrack* mcM1 = 0x0;
686 CbmMCTrack* mcM2 = 0x0;
687
688 // grand-mothers
689 CbmMCTrack* mcG1 = 0x0;
690 CbmMCTrack* mcG2 = 0x0;
691
692 // great grand-mothers
693 CbmMCTrack* mcGG1 = 0x0;
694 CbmMCTrack* mcGG2 = 0x0;
695
696 // make direct(1-1 and 2-2) and cross(1-2 and 2-1) comparisons for the whole branch
697 Bool_t directTerm = kTRUE;
698 // daughters
699 directTerm =
700 directTerm && mcD1
701 && ComparePDG(d1Pdg, signalMC->GetLegPDG(1), signalMC->GetLegPDGexclude(1), signalMC->GetCheckBothChargesLegs(1))
702 && CheckParticleSource(labelD1, signalMC->GetLegSource(1));
703
704 directTerm =
705 directTerm && mcD2
706 && ComparePDG(d2Pdg, signalMC->GetLegPDG(2), signalMC->GetLegPDGexclude(2), signalMC->GetCheckBothChargesLegs(2))
707 && CheckParticleSource(labelD2, signalMC->GetLegSource(2));
708
709 // mothers
710 Int_t labelM1 = -1;
711 if (signalMC->GetMotherPDG(1) != 0 || signalMC->GetMotherSource(1) != PairAnalysisSignalMC::ESource::kDontCare) {
712 labelM1 = GetMothersLabel(labelD1);
713 if (labelD1 > -1 && labelM1 > -1) mcM1 = GetMCTrackFromMCEvent(labelM1);
714 directTerm = directTerm && (mcM1 || signalMC->GetMotherPDGexclude(1))
715 && ComparePDG((mcM1 ? mcM1->GetPdgCode() : -99999), signalMC->GetMotherPDG(1),
716 signalMC->GetMotherPDGexclude(1), signalMC->GetCheckBothChargesMothers(1))
717 && CheckParticleSource(labelM1, signalMC->GetMotherSource(1))
718 && CheckDalitzDecision(labelM1, signalMC);
719 }
720
721 Int_t labelM2 = -1;
722 if (signalMC->GetMotherPDG(2) != 0 || signalMC->GetMotherSource(2) != PairAnalysisSignalMC::ESource::kDontCare) {
723 labelM2 = GetMothersLabel(labelD2);
724 if (labelD2 > -1 && labelM2 > -1) mcM2 = GetMCTrackFromMCEvent(labelM2);
725 directTerm = directTerm && (mcM2 || signalMC->GetMotherPDGexclude(2))
726 && ComparePDG((mcM2 ? mcM2->GetPdgCode() : -99999), signalMC->GetMotherPDG(2),
727 signalMC->GetMotherPDGexclude(2), signalMC->GetCheckBothChargesMothers(2))
728 && CheckParticleSource(labelM2, signalMC->GetMotherSource(2))
729 && CheckDalitzDecision(labelM2, signalMC);
730 }
731
732 // grand-mothers
733 Int_t labelG1 = -1;
734 if (signalMC->GetGrandMotherPDG(1) != 0
736 labelG1 = GetMothersLabel(labelM1);
737 if (mcM1 && labelG1 > -1) mcG1 = GetMCTrackFromMCEvent(labelG1);
738 directTerm = directTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(1))
739 && ComparePDG((mcG1 ? mcG1->GetPdgCode() : 0), signalMC->GetGrandMotherPDG(1),
741 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(1));
742 }
743
744 Int_t labelG2 = -1;
745 if (signalMC->GetGrandMotherPDG(2) != 0
747 labelG2 = GetMothersLabel(labelM2);
748 if (mcM2 && labelG2 > -1) mcG2 = GetMCTrackFromMCEvent(labelG2);
749 directTerm = directTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(2))
750 && ComparePDG((mcG2 ? mcG2->GetPdgCode() : 0), signalMC->GetGrandMotherPDG(2),
752 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(2));
753 }
754
755 // great grand-mothers
756 Int_t labelGG1 = -1;
757 if (signalMC->GetGreatGrandMotherPDG(1) != 0
758 /* || signalMC->GetGreatGrandMotherSource(1)!=PairAnalysisSignalMC::ESource::kDontCare*/) {
759 labelGG1 = GetMothersLabel(labelG1);
760 if (mcG1 && labelGG1 > -1) mcGG1 = GetMCTrackFromMCEvent(labelGG1);
761 directTerm =
762 directTerm && (mcGG1 || signalMC->GetGreatGrandMotherPDGexclude(1))
763 && ComparePDG((mcGG1 ? mcGG1->GetPdgCode() : 0), signalMC->GetGreatGrandMotherPDG(1),
765 // && CheckParticleSource(labelGG1, signalMC->GetGreatGrandMotherSource(1));
766 }
767
768 Int_t labelGG2 = -1;
769 if (signalMC->GetGreatGrandMotherPDG(2) != 0
770 /* || signalMC->GetGreatGrandMotherSource(2)!=PairAnalysisSignalMC::ESource::kDontCare*/) {
771 labelGG2 = GetMothersLabel(labelG2);
772 if (mcG2 && labelGG2 > -1) mcGG2 = GetMCTrackFromMCEvent(labelGG2);
773 directTerm =
774 directTerm && (mcGG2 || signalMC->GetGreatGrandMotherPDGexclude(2))
775 && ComparePDG((mcGG2 ? mcGG2->GetPdgCode() : 0), signalMC->GetGreatGrandMotherPDG(2),
777 // && CheckParticleSource(labelG2, signalMC->GetGreatGrandMotherSource(2));
778 }
779
780 // Cross term
781 Bool_t crossTerm = kTRUE;
782 // daughters
783 crossTerm =
784 crossTerm && mcD2
785 && ComparePDG(d2Pdg, signalMC->GetLegPDG(1), signalMC->GetLegPDGexclude(1), signalMC->GetCheckBothChargesLegs(1))
786 && CheckParticleSource(labelD2, signalMC->GetLegSource(1));
787
788 crossTerm =
789 crossTerm && mcD1
790 && ComparePDG(d1Pdg, signalMC->GetLegPDG(2), signalMC->GetLegPDGexclude(2), signalMC->GetCheckBothChargesLegs(2))
791 && CheckParticleSource(labelD1, signalMC->GetLegSource(2));
792
793 // mothers
794 if (signalMC->GetMotherPDG(1) != 0 || signalMC->GetMotherSource(1) != PairAnalysisSignalMC::ESource::kDontCare) {
795 if (!mcM2 && labelD2 > -1) {
796 labelM2 = GetMothersLabel(labelD2);
797 if (labelM2 > -1) mcM2 = GetMCTrackFromMCEvent(labelM2);
798 }
799 crossTerm = crossTerm && (mcM2 || signalMC->GetMotherPDGexclude(1))
800 && ComparePDG((mcM2 ? mcM2->GetPdgCode() : -99999), signalMC->GetMotherPDG(1),
801 signalMC->GetMotherPDGexclude(1), signalMC->GetCheckBothChargesMothers(1))
802 && CheckParticleSource(labelM2, signalMC->GetMotherSource(1)) && CheckDalitzDecision(labelM2, signalMC);
803 }
804
805 if (signalMC->GetMotherPDG(2) != 0 || signalMC->GetMotherSource(2) != PairAnalysisSignalMC::ESource::kDontCare) {
806 if (!mcM1 && labelD1 > -1) {
807 labelM1 = GetMothersLabel(labelD1);
808 if (labelM1 > -1) mcM1 = GetMCTrackFromMCEvent(labelM1);
809 }
810 crossTerm = crossTerm && (mcM1 || signalMC->GetMotherPDGexclude(2))
811 && ComparePDG((mcM1 ? mcM1->GetPdgCode() : -99999), signalMC->GetMotherPDG(2),
812 signalMC->GetMotherPDGexclude(2), signalMC->GetCheckBothChargesMothers(2))
813 && CheckParticleSource(labelM1, signalMC->GetMotherSource(2)) && CheckDalitzDecision(labelM1, signalMC);
814 }
815
816 // grand-mothers
817 if (signalMC->GetGrandMotherPDG(1) != 0
819 if (!mcG2 && mcM2) {
820 labelG2 = GetMothersLabel(labelM2);
821 if (labelG2 > -1) mcG2 = GetMCTrackFromMCEvent(labelG2);
822 }
823 crossTerm = crossTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(1))
824 && ComparePDG((mcG2 ? mcG2->GetPdgCode() : 0), signalMC->GetGrandMotherPDG(1),
826 && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(1));
827 }
828
829 if (signalMC->GetGrandMotherPDG(2) != 0
831 if (!mcG1 && mcM1) {
832 labelG1 = GetMothersLabel(labelM1);
833 if (labelG1 > -1) mcG1 = GetMCTrackFromMCEvent(labelG1);
834 }
835 crossTerm = crossTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(2))
836 && ComparePDG((mcG1 ? mcG1->GetPdgCode() : 0), signalMC->GetGrandMotherPDG(2),
838 && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(2));
839 }
840
841 // great grand-mothers
842 if (signalMC->GetGreatGrandMotherPDG(1) != 0
843 /*|| signalMC->GetGreatGrandMotherSource(1)!=PairAnalysisSignalMC::ESource::kDontCare*/) {
844 if (!mcGG2 && mcG2) {
845 labelGG2 = GetMothersLabel(labelG2);
846 if (labelGG2 > -1) mcGG2 = GetMCTrackFromMCEvent(labelGG2);
847 }
848 crossTerm =
849 crossTerm && (mcGG2 || signalMC->GetGreatGrandMotherPDGexclude(1))
850 && ComparePDG((mcGG2 ? mcGG2->GetPdgCode() : 0), signalMC->GetGreatGrandMotherPDG(1),
852 // && CheckParticleSource(labelG2, signalMC->GetGreatGrandMotherSource(1));
853 }
854
855 if (signalMC->GetGreatGrandMotherPDG(2) != 0
856 /* || signalMC->GetGreatGrandMotherSource(2)!=PairAnalysisSignalMC::ESource::kDontCare*/) {
857 if (!mcGG1 && mcG1) {
858 labelGG1 = GetMothersLabel(labelG1);
859 if (labelGG1 > -1) mcGG1 = GetMCTrackFromMCEvent(labelGG1);
860 }
861 crossTerm =
862 crossTerm && (mcGG1 || signalMC->GetGreatGrandMotherPDGexclude(2))
863 && ComparePDG((mcGG1 ? mcGG1->GetPdgCode() : 0), signalMC->GetGreatGrandMotherPDG(2),
865 // && CheckParticleSource(labelG1, signalMC->GetGreatGrandMotherSource(2));
866 }
867
868 Bool_t motherRelation = kTRUE;
870 motherRelation = motherRelation && HaveSameMother(pair);
871 }
873 motherRelation = motherRelation && !HaveSameMother(pair);
874 }
875
876
877 return ((directTerm || crossTerm) && motherRelation && processGEANT);
878}
879
880//____________________________________________________________
882{
883 //
884 // Check whether two particles have the same mother
885 //
886
887 const PairAnalysisTrack* daughter1 = pair->GetFirstDaughter();
888 const PairAnalysisTrack* daughter2 = pair->GetSecondDaughter();
889 if (!daughter1 || !daughter2) return 0;
890
891 CbmMCTrack* mcDaughter1 = GetMCTrackFromMCEvent(daughter1->GetLabel());
892 CbmMCTrack* mcDaughter2 = GetMCTrackFromMCEvent(daughter2->GetLabel());
893 if (!mcDaughter1 || !mcDaughter2) return 0;
894
895 Int_t labelMother1 = mcDaughter1->GetMotherId();
896 Int_t labelMother2 = mcDaughter2->GetMotherId();
897 Bool_t sameMother = (labelMother1 > -1) && (labelMother2 > -1) && (labelMother1 == labelMother2);
898
899 return sameMother;
900}
901
902//____________________________________________________________
903Bool_t PairAnalysisMC::IsPhysicalPrimary(Int_t label, UInt_t processID) const
904{
905
906 // initial state particle
907 if (processID != kPPrimary) return kFALSE;
908
909 // stable (anti-)particles
910 Double_t isStable = kFALSE;
911 Int_t pdg = TMath::Abs(GetPdgFromLabel(label));
912
913 // All ions/nucleons are considered as stable
914 // Nuclear code is 10LZZZAAAI
915 if (pdg > 1000000000) isStable = kTRUE;
916
917 switch (pdg) {
918 case kGamma: // Photon
919 case kElectron: // Electron
920 case kMuonMinus: // Muon
921 case kPiPlus: // Pion
922 case kKPlus: // kaon
923 case kK0Short: // k0s
924 case kK0Long: // k0l
925 case kProton: // Proton
926 case kNeutron: // Neutron
927 case kLambda0: // Lambda_0
928 case kSigmaMinus: // Sigma Minus
929 case kSigmaPlus: // Sigma Plus
930 case kXiMinus: // Xsi Minus
931 case kOmegaMinus: // Omega
932 case kNuE: // Electron Neutrino
933 case kNuMu: // Muon Neutrino
934 case kNuTau: // Tau Neutrino
935 case 3322: // Xsi
936 isStable = kTRUE;
937 break;
938 default:
939 isStable = kFALSE;
940 return isStable;
941 break;
942 }
943
944 // particle produced during transport
946 if (!mother) return kTRUE;
947 Int_t pdgMother = TMath::Abs(mother->GetPdgCode());
948 UInt_t processMother = mother->GetGeantProcessId();
949
950 // Check for Sigma0
951 if ((pdgMother == kSigma0) && (processMother == kPPrimary)) return kTRUE;
952 // Check if it comes from a pi0 decay
953 if ((pdgMother == kPi0) && (processMother == kPPrimary)) return kTRUE;
954 // Check if it this is a heavy flavor decay product
955 Int_t mfl = Int_t(pdgMother / TMath::Power(10, Int_t(TMath::Log10(pdgMother))));
956 if (mfl < 4) return kFALSE; // Light hadron
957 // Heavy flavor hadron produced by generator
958 if (processMother == kPPrimary) return kTRUE;
959 // Check for secondary interaction producing the heavy flavour
960 Int_t mLabel = -1;
961 while ((mLabel = mother->GetMotherId() && mLabel >= 0)) {
962 mother = GetMCTrackFromMCEvent(mLabel);
963 }
964 pdgMother = TMath::Abs(mother->GetPdgCode());
965 mfl = Int_t(pdgMother / TMath::Power(10, Int_t(TMath::Log10(pdgMother))));
966 return (mfl < 4 ? kFALSE : kTRUE);
967}
968
969//____________________________________________________________
970Bool_t PairAnalysisMC::IsSecondaryFromWeakDecay(Int_t label, UInt_t processID) const
971{
972 if (IsPhysicalPrimary(label, processID)) return kFALSE;
973 if (processID != kPDecay) return kFALSE;
974
975 Float_t pdgMother = (Float_t) TMath::Abs(GetPdgFromLabel(GetMothersLabel(label)));
976 // mass fo the flavour
977 Int_t mfl = Int_t(pdgMother / TMath::Power(10, Int_t(TMath::Log10(pdgMother))));
978 // mother has strangeness, pion+- or muon decay
979 if (mfl == 3 || pdgMother == 211 || pdgMother == 13) return kTRUE;
980 else
981 return kFALSE;
982}
983//____________________________________________________________
984Bool_t PairAnalysisMC::IsSecondaryFromMaterial(Int_t label, UInt_t processID) const
985{
986 if (IsPhysicalPrimary(label, processID)) return kFALSE;
987 if (IsSecondaryFromWeakDecay(label, processID)) return kFALSE;
988
989 // Check if it is a non-stable product or one of the beams
991 if (!mother) return kFALSE;
992 else
993 return kTRUE;
994}
ClassImp(CbmConverterManager)
uint32_t GetGeantProcessId() const
Definition CbmMCTrack.h:67
int32_t GetMotherId() const
Definition CbmMCTrack.h:69
int32_t GetPdgCode() const
Definition CbmMCTrack.h:68
Int_t NumberOfDaughters(const CbmMCTrack *particle)
virtual ~PairAnalysisMC()
void GetDaughters(const TObject *mother, CbmMCTrack *&d1, CbmMCTrack *&d2)
Int_t GetLabelMotherWithPdg(const PairAnalysisPair *pair, Int_t pdgMother)
Bool_t IsSecondaryFromMaterial(Int_t label, UInt_t processID) const
CbmMCTrack * GetMCTrack(const PairAnalysisTrack *_track)
Bool_t IsPhysicalPrimary(Int_t label, UInt_t processID) const
Bool_t HaveSameMother(const PairAnalysisPair *pair) const
static PairAnalysisMC * Instance()
Bool_t CheckParticleSource(Int_t label, PairAnalysisSignalMC::ESource source) const
TClonesArray * fMCArray
Int_t GetPdgFromLabel(Int_t label) const
TObject * fMCEvent
Bool_t ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion, Bool_t checkBothCharges) const
Int_t GetMothersLabel(Int_t daughterLabel) const
Bool_t CheckDalitzDecision(Int_t mLabel, const PairAnalysisSignalMC *const signalMC) const
Bool_t CheckGEANTProcess(Int_t label, TMCProcess process) const
Bool_t IsSecondaryFromWeakDecay(Int_t label, UInt_t processID) const
CbmMCTrack * GetMCTrackMother(const PairAnalysisTrack *_track)
static PairAnalysisMC * fgInstance
Bool_t CheckIsDalitz(Int_t label, const PairAnalysisSignalMC *const signalMC) const
CbmMCTrack * GetMCTrackFromMCEvent(Int_t label) const
Int_t GetMotherPDG(const PairAnalysisTrack *_track)
Bool_t IsMCTruth(const PairAnalysisPair *pair, const PairAnalysisSignalMC *signalMC) const
Bool_t GetMotherPDGexclude(Int_t branch) const
Bool_t GetCheckBothChargesGrandMothers(Int_t branch) const
Bool_t GetLegPDGexclude(Int_t branch) const
EBranchRelation GetMothersRelation() const
Bool_t GetCheckBothChargesGreatGrandMothers(Int_t branch) const
Bool_t GetCheckBothChargesLegs(Int_t branch) const
Bool_t GetCheckBothChargesMothers(Int_t branch) const
Bool_t GetCheckGEANTProcess() const
Int_t GetGrandMotherPDG(Int_t branch) const
Bool_t GetGrandMotherPDGexclude(Int_t branch) const
Int_t GetGreatGrandMotherPDG(Int_t branch) const
Int_t GetMotherPDG(Int_t branch) const
ESource GetGrandMotherSource(Int_t branch) const
ESource GetLegSource(Int_t branch) const
Int_t GetLegPDG(Int_t branch) const
Bool_t GetGreatGrandMotherPDGexclude(Int_t branch) const
TMCProcess GetGEANTProcess() const
ESource GetMotherSource(Int_t branch) const
CbmMCTrack * GetMCTrack() const