@@ -371,7 +371,7 @@ class CharmHadronSelection : public baseselection::BaseSelection<float, o2::anal
371371 }
372372
373373 this ->template fillFilterSummary <FilterHistName>(pass);
374- return this ->isPassThrough () || pass;ż
374+ return this ->isPassThrough () || pass;
375375 }
376376
377377 [[nodiscard]] float getMassMin () const
@@ -405,6 +405,9 @@ struct CharmHadronBuilderProducts : o2::framework::ProducesGroup {
405405 o2::framework::Produces<o2::aod::FD0s> producedD0s;
406406 o2::framework::Produces<o2::aod::FD0Masks> producedD0Masks;
407407 o2::framework::Produces<o2::aod::FD0Extras> producedD0Extras;
408+ o2::framework::Produces<o2::aod::FLcs> producedLcs;
409+ o2::framework::Produces<o2::aod::FLcMasks> producedLcMasks;
410+ o2::framework::Produces<o2::aod::FLcExtras> producedLcExtras;
408411};
409412
410413// per-table produce switches (-1: auto = produce only if a downstream device subscribes; 0 off; 1 on)
@@ -413,6 +416,9 @@ struct ConfCharmHadronTables : o2::framework::ConfigurableGroup {
413416 o2::framework::Configurable<int > produceD0s{" produceD0s" , -1 , " Produce D0s (-1: auto; 0 off; 1 on)" };
414417 o2::framework::Configurable<int > produceD0Masks{" produceD0Masks" , -1 , " Produce D0Masks (-1: auto; 0 off; 1 on)" };
415418 o2::framework::Configurable<int > produceD0Extras{" produceD0Extras" , -1 , " Produce D0Extras (-1: auto; 0 off; 1 on)" };
419+ o2::framework::Configurable<int > produceLcs{" produceLcs" , -1 , " Produce Lcs (-1: auto; 0 off; 1 on)" };
420+ o2::framework::Configurable<int > produceLcMasks{" produceLcMasks" , -1 , " Produce LcMasks (-1: auto; 0 off; 1 on)" };
421+ o2::framework::Configurable<int > produceLcExtras{" produceLcExtras" , -1 , " Produce LcExtras (-1: auto; 0 off; 1 on)" };
416422};
417423
418424template <modes::CharmHadron hadronType, auto & SelectionHistName, auto & FilterHistName>
@@ -425,24 +431,43 @@ class CharmHadronBuilder
425431 template <typename T1 , typename T2 , typename T3 , typename T4 >
426432 void init (o2::framework::HistogramRegistry* registry, T1 & config, T2 & filter, T3 & table, T4 & initContext)
427433 {
428- LOG (info) << " Initialize femto charm hadron builder..." ;
429- mProduceD0s = utils::enableTable (" FD0s_001" , table.produceD0s .value , initContext);
430- mProduceD0Masks = utils::enableTable (" FD0Masks_001" , table.produceD0Masks .value , initContext);
431- mProduceD0Extras = utils::enableTable (" FD0Extras_001" , table.produceD0Extras .value , initContext);
432-
433- if (mProduceD0s || mProduceD0Masks || mProduceD0Extras ) {
434+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 ) || modes::isEqual (hadronType, modes::CharmHadron::kD0Bar )) {
435+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 )) {
436+ LOG (info) << " Initialize femto D0 builder..." ;
437+ }
438+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0Bar )) {
439+ LOG (info) << " Initialize femto D0bar builder..." ;
440+ }
441+ mProduceD0s = utils::enableTable (" FD0s_001" , table.produceD0s .value , initContext);
442+ mProduceD0Masks = utils::enableTable (" FD0Masks_001" , table.produceD0Masks .value , initContext);
443+ mProduceD0Extras = utils::enableTable (" FD0Extras_001" , table.produceD0Extras .value , initContext);
444+ }
445+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kLc ) || modes::isEqual (hadronType, modes::CharmHadron::kLcBar )) {
446+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kLc )) {
447+ LOG (info) << " Initialize femto Lc builder..." ;
448+ }
449+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kLcBar )) {
450+ LOG (info) << " Initialize femto Lcbar builder..." ;
451+ }
452+ mProduceLcs = utils::enableTable (" FLcs_001" , table.produceLcs .value , initContext);
453+ mProduceLcMasks = utils::enableTable (" FLcMasks_001" , table.produceLcMasks .value , initContext);
454+ mProduceLcExtras = utils::enableTable (" FLcExtras_001" , table.produceLcExtras .value , initContext);
455+ }
456+ if (mProduceD0s || mProduceD0Masks || mProduceD0Extras ||
457+ mProduceLcs || mProduceLcMasks || mProduceLcExtras ) {
434458 mFillAnyTable = true ;
435459 } else {
436- LOG (info) << " No charm hadron tables configured, selection object will not be configured..." ;
460+ LOG (info) << " No tables configured, Selection object will not be configured..." ;
461+ LOG (info) << " Initialization done..." ;
437462 return ;
438463 }
439-
440464 mCharmHadronSelection .configure (registry, config, filter);
441465 mCharmHadronSelection .printSelections (CharmHadronSelsName);
466+ LOG (info) << " Initialization done..." ;
442467 }
443468
444469 template <typename T1 , typename T2 , typename T3 >
445- void fillTables (T1 & collisionProducts, T2 & charmHadronProducts, T3 const & candidate,
470+ void fillD0Tables (T1 & collisionProducts, T2 & charmHadronProducts, T3 const & candidate,
446471 float signedPt, float mass, int64_t posDauIndex, int64_t negDauIndex)
447472 {
448473 if (mProduceD0s ) {
@@ -476,15 +501,54 @@ class CharmHadronBuilder
476501 }
477502 }
478503
504+ template <typename T1 , typename T2 , typename T3 >
505+ void fillLcTables (T1 & collisionProducts, T2 & charmHadronProducts, T3 const & candidate,
506+ float signedPt, float mass, float massCompeting,
507+ int64_t protonDauIndex, int64_t kaonDauIndex, int64_t pionDauIndex)
508+ {
509+ if (mProduceLcs ) {
510+ charmHadronProducts.producedLcs (collisionProducts.producedCollision .lastIndex (),
511+ signedPt,
512+ candidate.eta (),
513+ candidate.phi (),
514+ mass,
515+ protonDauIndex,
516+ kaonDauIndex,
517+ pionDauIndex);
518+ }
519+ if (mProduceLcMasks ) {
520+ charmHadronProducts.producedLcMasks (mCharmHadronSelection .getBitmask ());
521+ }
522+ if (mProduceLcExtras ) {
523+ charmHadronProducts.producedLcExtras (
524+ candidate.cpa (),
525+ candidate.cpaXY (),
526+ candidate.decayLength (),
527+ candidate.decayLengthXY (),
528+ candidate.chi2PCA (),
529+ candidate.impactParameterProngSqSum (),
530+ candidate.impactParameter0 (),
531+ candidate.impactParameter1 (),
532+ candidate.impactParameter2 (),
533+ massCompeting,
534+ candidate.mlProbLcToPKPi ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPKPi ()[0 ],
535+ candidate.mlProbLcToPKPi ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPKPi ()[1 ],
536+ candidate.mlProbLcToPKPi ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPKPi ()[2 ],
537+ candidate.mlProbLcToPiKP ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPiKP ()[0 ],
538+ candidate.mlProbLcToPiKP ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPiKP ()[1 ],
539+ candidate.mlProbLcToPiKP ().size () < NSizeMLScore ? -1 .f : candidate.mlProbLcToPiKP ()[2 ],
540+ static_cast <int8_t >(candidate.isSelLcToPKPi ()),
541+ static_cast <int8_t >(candidate.isSelLcToPiKP ()));
542+ }
543+ }
544+
479545 template <modes::System system, typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 >
480546 void fillCharmHadrons (T1 const & col, T2 & collisionBuilder, T3 & collisionProducts, T4 & trackProducts,
481547 T5 & charmHadronProducts, T6 const & candidates, T7 const & /* tracks*/ , T8 & trackBuilder)
482548 {
483549 if (!mFillAnyTable ) {
484550 return ;
485551 }
486- int64_t posDauIndex = 0 ;
487- int64_t negDauIndex = 0 ;
488552 for (const auto & candidate : candidates) {
489553 if (!mCharmHadronSelection .checkFilters (candidate)) {
490554 continue ;
@@ -494,17 +558,46 @@ class CharmHadronBuilder
494558 continue ;
495559 }
496560
497- collisionBuilder.template fillCollision <system>(collisionProducts, col);
498-
499- auto prong0 = candidate.template prong0_as <T7 >();
500- auto prong1 = candidate.template prong1_as <T7 >();
501- posDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(prong0, trackProducts, collisionBuilder);
502- negDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(prong1, trackProducts, collisionBuilder);
561+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 ) || modes::isEqual (hadronType, modes::CharmHadron::kD0Bar )) {
562+ auto prong0 = candidate.template prong0_as <T7 >();
563+ auto prong1 = candidate.template prong1_as <T7 >();
564+
565+ collisionBuilder.template fillCollision <system>(collisionProducts, col);
566+
567+ int64_t posDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(prong0, trackProducts, collisionBuilder);
568+ int64_t negDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(prong1, trackProducts, collisionBuilder);
569+
570+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 )) {
571+ this ->fillD0Tables (collisionProducts, charmHadronProducts, candidate, candidate.pt (), mHfHelper .invMassD0ToPiK (candidate), posDauIndex, negDauIndex);
572+ } else {
573+ this ->fillD0Tables (collisionProducts, charmHadronProducts, candidate, -candidate.pt (), mHfHelper .invMassD0barToKPi (candidate), posDauIndex, negDauIndex);
574+ }
575+ }
503576
504- if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 )) {
505- this ->fillTables (collisionProducts, charmHadronProducts, candidate, candidate.pt (), mHfHelper .invMassD0ToPiK (candidate), posDauIndex, negDauIndex);
506- } else {
507- this ->fillTables (collisionProducts, charmHadronProducts, candidate, -candidate.pt (), mHfHelper .invMassD0barToKPi (candidate), posDauIndex, negDauIndex);
577+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kLc ) || modes::isEqual (hadronType, modes::CharmHadron::kLcBar )) {
578+ auto prong0 = candidate.template prong0_as <T7 >();
579+ auto prong1 = candidate.template prong1_as <T7 >();
580+ auto prong2 = candidate.template prong2_as <T7 >();
581+
582+ // the charge of prong 0 is the charge of the Lc, so the species is decided here
583+ if ((prong0.sign () > 0 ) != isParticle<hadronType>()) {
584+ continue ;
585+ }
586+
587+ // remap the prong onto the accepted hypothesis so that the proton is always first
588+ bool const isPKPi = candidate.isSelLcToPKPi ();
589+ auto const & protonProng = isPKPi ? prong0 : prong2;
590+ auto const & pionProng = isPKPi ? prong2 : prong0;
591+ float const mass = isPKPi ? mHfHelper .invMassLcToPKPi (candidate) : mHfHelper .invMassLcToPiKP (candidate);
592+ float const massCompeting = isPKPi ? mHfHelper .invMassLcToPiKP (candidate) : mHfHelper .invMassLcToPKPi (candidate);
593+
594+ collisionBuilder.template fillCollision <system>(collisionProducts, col);
595+ int64_t const protonDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(protonProng, trackProducts, collisionBuilder);
596+ int64_t const kaonDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(prong1, trackProducts, collisionBuilder);
597+ int64_t const pionDauIndex = trackBuilder.template getDaughterIndex <modes::Track::kCharmDaughter >(pionProng, trackProducts, collisionBuilder);
598+
599+ float const signedPt = isParticle<hadronType>() ? candidate.pt () : -candidate.pt ();
600+ this ->fillLcTables (collisionProducts, charmHadronProducts, candidate, signedPt, mass, massCompeting, protonDauIndex, kaonDauIndex, pionDauIndex);
508601 }
509602 }
510603 }
@@ -516,31 +609,62 @@ class CharmHadronBuilder
516609 if (!mFillAnyTable ) {
517610 return ;
518611 }
519- int64_t posDauIndex = 0 ;
520- int64_t negDauIndex = 0 ;
521612 for (const auto & candidate : candidates) {
522613 if (!mCharmHadronSelection .checkFilters (candidate)) {
523614 continue ;
524615 }
525-
616+
526617 mCharmHadronSelection .applySelections (candidate);
527618 if (!mCharmHadronSelection .passesAllRequiredSelections ()) {
528619 continue ;
529620 }
621+
622+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 ) || modes::isEqual (hadronType, modes::CharmHadron::kD0Bar )) {
623+ auto prong0 = candidate.template prong0_as <T8 >();
624+ auto prong1 = candidate.template prong1_as <T8 >();
625+
626+ collisionBuilder.template fillMcCollision <system>(collisionProducts, col, mcCols, mcProducts, mcBuilder);
627+
628+ int64_t posDauIndex = trackBuilder.template getDaughterIndex <system, modes::Track::kCharmDaughter >(prong0, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
629+ int64_t negDauIndex = trackBuilder.template getDaughterIndex <system, modes::Track::kCharmDaughter >(prong1, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
630+
631+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 )) {
632+ this ->fillD0Tables (collisionProducts, charmHadronProducts, candidate, candidate.pt (), mHfHelper .invMassD0ToPiK (candidate), posDauIndex, negDauIndex);
633+ } else {
634+ this ->fillD0Tables (collisionProducts, charmHadronProducts, candidate, -candidate.pt (), mHfHelper .invMassD0barToKPi (candidate), posDauIndex, negDauIndex);
635+ }
636+ mcBuilder.template fillMcD0WithLabel <system>(candidate, tracks, mcParticles, mcCols, mcProducts);
637+ }
530638
531- collisionBuilder.template fillMcCollision <system>(collisionProducts, col, mcCols, mcProducts, mcBuilder);
639+ if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kLc ) || modes::isEqual (hadronType, modes::CharmHadron::kLcBar )) {
640+ auto prong0 = candidate.template prong0_as <T8 >();
641+ auto prong1 = candidate.template prong1_as <T8 >();
642+ auto prong2 = candidate.template prong2_as <T8 >();
532643
533- auto prong0 = candidate. template prong0_as < T8 >();
534- auto prong1 = candidate. template prong1_as < T8 >();
535- posDauIndex = trackBuilder. template getDaughterIndex <system, modes::Track:: kCharmDaughter >(prong0, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts) ;
536- negDauIndex = trackBuilder. template getDaughterIndex <system, modes::Track:: kCharmDaughter >(prong1, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
644+ // the charge of prong 0 is the charge of the Lc, so the species is decided here
645+ if ((prong0. sign () > 0 ) != isParticle<hadronType >()) {
646+ continue ;
647+ }
537648
538- if constexpr (modes::isEqual (hadronType, modes::CharmHadron::kD0 )) {
539- this ->fillTables (collisionProducts, charmHadronProducts, candidate, candidate.pt (), mHfHelper .invMassD0ToPiK (candidate), posDauIndex, negDauIndex);
540- } else {
541- this ->fillTables (collisionProducts, charmHadronProducts, candidate, -candidate.pt (), mHfHelper .invMassD0barToKPi (candidate), posDauIndex, negDauIndex);
649+ // remap the prongs onto the accepted hypothesis so that the proton is always first
650+ bool const isPKPi = candidate.isSelLcToPKPi ();
651+ auto const & protonProng = isPKPi ? prong0 : prong2;
652+ auto const & pionProng = isPKPi ? prong2 : prong0;
653+ float const mass = isPKPi ? mHfHelper .invMassLcToPKPi (candidate) : mHfHelper .invMassLcToPiKP (candidate);
654+ float const massCompeting = isPKPi ? mHfHelper .invMassLcToPiKP (candidate) : mHfHelper .invMassLcToPKPi (candidate);
655+
656+ collisionBuilder.template fillMcCollision <system>(collisionProducts, col, mcCols, mcProducts, mcBuilder);
657+
658+ int64_t const protonDauIndex = trackBuilder.template getDaughterIndex <system, modes::Track::kCharmDaughter >(protonProng, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
659+ int64_t const kaonDauIndex = trackBuilder.template getDaughterIndex <system, modes::Track::kCharmDaughter >(prong1, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
660+ int64_t const pionDauIndex = trackBuilder.template getDaughterIndex <system, modes::Track::kCharmDaughter >(pionProng, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts);
661+
662+ float const signedPt = isParticle<hadronType>() ? candidate.pt () : -candidate.pt ();
663+ this ->fillLcTables (collisionProducts, charmHadronProducts, candidate, signedPt, mass, massCompeting, protonDauIndex, kaonDauIndex, pionDauIndex);
664+ mcBuilder.template fillMcLcWithLabel <system>(candidate, tracks, mcParticles, mcCols, mcProducts);
542665 }
543- mcBuilder.template fillMcD0WithLabel <system>(candidate, tracks, mcParticles, mcCols, mcProducts);
666+
667+
544668 }
545669 }
546670
@@ -554,6 +678,9 @@ class CharmHadronBuilder
554678 bool mProduceD0s = false ;
555679 bool mProduceD0Masks = false ;
556680 bool mProduceD0Extras = false ;
681+ bool mProduceLcs = false ;
682+ bool mProduceLcMasks = false ;
683+ bool mProduceLcExtras = false ;
557684 bool mFillAnyTable = false ;
558685};
559686} // namespace o2::analysis::femto::charmhadronbuilder
0 commit comments