@@ -40,6 +40,7 @@ namespace mcbuilder
4040struct ConfMc : o2::framework::ConfigurableGroup {
4141 std::string prefix = std::string(" MonteCarlo" );
4242 o2::framework::Configurable<bool > passThrough{" passThrough" , false , " Passthrough all MC collisions and particles" };
43+ o2::framework::Configurable<bool > findLastPartonicMother{" findLastPartonicMother" , true , " If true, the partonic mother will be the first parton directly after the initial collision. If false, the partonic mother will be the last parton before hadronization" };
4344};
4445
4546struct McBuilderProducts : o2::framework::ProducesGroup {
@@ -113,6 +114,7 @@ class McBuilder
113114 return ;
114115 }
115116 mPassThrough = config.passThrough .value ;
117+ mFindLastPartonicMother = config.findLastPartonicMother .value ;
116118 LOG (info) << " Initialization done..." ;
117119 }
118120
@@ -340,7 +342,12 @@ class McBuilder
340342
341343 // Partonic mother
342344 int64_t mcPartonicMotherRow = -1 ;
343- auto mcPartonicMotherIndex = this ->findFirstPartonicMother (mcParticle, mcParticles);
345+ int64_t mcPartonicMotherIndex = -1 ;
346+ if (mFindLastPartonicMother ) {
347+ mcPartonicMotherIndex = this ->findLastPartonicMother (mcParticle, mcParticles);
348+ } else {
349+ mcPartonicMotherIndex = this ->findFirstPartonicMother (mcParticle, mcParticles);
350+ }
344351 if (mcPartonicMotherIndex >= 0 ) {
345352 auto itPM = mMcPartonicMotherMap .find (mcPartonicMotherIndex);
346353 if (itPM != mMcPartonicMotherMap .end ()) {
@@ -357,14 +364,12 @@ class McBuilder
357364 }
358365
359366 template <typename T1, typename T2>
360- int findFirstPartonicMother (const T1& mcParticle, const T2& mcParticles)
367+ int64_t findFirstPartonicMother (const T1& mcParticle, const T2& mcParticles)
361368 {
362369 if (!mcParticle.has_mothers ()) {
363370 return -1 ;
364371 }
365-
366372 auto motherIds = mcParticle.mothersIds ();
367-
368373 // adapted these checks from MCUtils in PWGEM
369374 const int defaultMotherSize = 2 ;
370375 std::vector<int > allMotherIds;
@@ -379,32 +384,69 @@ class McBuilder
379384 for (const int & id : motherIds)
380385 allMotherIds.push_back (id);
381386 }
382-
383387 // Loop over all mothers
384388 for (const int & i : allMotherIds) {
385389
386390 if (i < 0 || i >= mcParticles.size ())
387391 continue ;
388-
389392 const auto & mother = mcParticles.iteratorAt (i);
390393 int pdgAbs = std::abs (mother.pdgCode ());
391-
392394 // Is it a parton? (quark or gluon)
393395 if (pdgAbs <= PDG_t::kTop || pdgAbs == PDG_t::kGluon ) {
394396 return i; // Found a parton → return index
395397 }
396-
397398 // Recurse upward
398- int found = this ->findFirstPartonicMother (mother, mcParticles);
399+ int64_t found = this ->findFirstPartonicMother (mother, mcParticles);
399400 if (found != -1 )
400401 return found;
401402 }
402-
403403 // No partonic ancestor found
404404 return -1 ;
405405 }
406406
407+ template <typename T1, typename T2>
408+ int64_t findLastPartonicMother (const T1& mcParticle, const T2& mcParticles)
409+ {
410+ int64_t lastPartonIndex = -1 ;
411+ int64_t currentIndex = mcParticle.globalIndex ();
412+ while (currentIndex >= 0 && currentIndex < mcParticles.size ()) {
413+ const auto & current = mcParticles.iteratorAt (currentIndex);
414+ if (!current.has_mothers ())
415+ break ;
416+ auto motherIds = current.mothersIds ();
417+ int nextIndex = -1 ;
418+ const int defaultMotherSize = 2 ;
419+ if (motherIds.size () == defaultMotherSize && motherIds[1 ] > motherIds[0 ]) {
420+ nextIndex = motherIds[0 ];
421+ } else {
422+ for (const int & id : motherIds) {
423+ if (id >= 0 && id < mcParticles.size ()) {
424+ nextIndex = id;
425+ break ;
426+ }
427+ }
428+ }
429+ if (nextIndex < 0 || nextIndex >= mcParticles.size ())
430+ break ;
431+ const auto & mother = mcParticles.iteratorAt (nextIndex);
432+ int pdgAbs = std::abs (mother.pdgCode ());
433+ int status = std::abs (o2::mcgenstatus::getGenStatusCode (mother.statusCode ()));
434+ bool isParton = (pdgAbs <= PDG_t::kTop || pdgAbs == PDG_t::kGluon );
435+ const int isBeamParticleLowerLimit = 11 ;
436+ const int isBeamParticleUpperLimit = 19 ;
437+ bool isBeam = (status >= isBeamParticleLowerLimit && status <= isBeamParticleUpperLimit);
438+ if (isBeam)
439+ return lastPartonIndex;
440+ if (isParton)
441+ lastPartonIndex = nextIndex;
442+
443+ currentIndex = nextIndex;
444+ }
445+ return -1 ;
446+ }
447+
407448 bool mPassThrough = false ;
449+ bool mFindLastPartonicMother = false ;
408450 bool mFillAnyTable = false ;
409451 bool mProduceMcCollisions = false ;
410452 bool mProduceMcParticles = false ;
0 commit comments