@@ -143,6 +143,7 @@ struct HfCandidateCreator3Prong {
143143 // KF
144144 Configurable<bool > applyTopoConstraint{" applyTopoConstraint" , false , " apply origin from PV hypothesis for created candidate, works only in KF mode" };
145145 Configurable<bool > applyInvMassConstraint{" applyInvMassConstraint" , false , " apply particle type hypothesis to recalculate created candidate's momentum, works only in KF mode" };
146+ Configurable<bool > kfConstructWithEnergyFitMc{" kfConstructWithEnergyFitMc" , true , " for details see https://github.com/alisw/KFParticle/blob/a00323cd7b022430abcb3c43f18188b291b0c803/KFParticle/KFParticleBase.cxx#L625" };
146147
147148 Configurable<LabeledArray<float >> tpcPidBBParamsLightNuclei{" tpcPidBBParamsLightNuclei" , {hf_presel_lightnuclei::BetheBlochParams[0 ], hf_presel_lightnuclei::NParticleRows, hf_presel_lightnuclei::NBetheBlochParams, hf_presel_lightnuclei::labelsRowsNucleiType, hf_presel_lightnuclei::labelsBetheBlochParams}, " TPC PID Bethe–Bloch parameter configurations for light nuclei (deuteron, triton, helium-3, alpha)" };
148149
@@ -169,19 +170,22 @@ struct HfCandidateCreator3Prong {
169170
170171 void init (InitContext const &)
171172 {
172- std::array<bool , 8 > doprocessDF{doprocessPvRefitWithDCAFitterN, doprocessNoPvRefitWithDCAFitterN,
173- doprocessPvRefitWithDCAFitterNCentFT0C, doprocessNoPvRefitWithDCAFitterNCentFT0C,
174- doprocessPvRefitWithDCAFitterNCentFT0M, doprocessNoPvRefitWithDCAFitterNCentFT0M, doprocessPvRefitWithDCAFitterNUpc, doprocessNoPvRefitWithDCAFitterNUpc};
175- std::array<bool , 8 > doprocessKF{doprocessPvRefitWithKFParticle, doprocessNoPvRefitWithKFParticle,
176- doprocessPvRefitWithKFParticleCentFT0C, doprocessNoPvRefitWithKFParticleCentFT0C,
177- doprocessPvRefitWithKFParticleCentFT0M, doprocessNoPvRefitWithKFParticleCentFT0M, doprocessPvRefitWithKFParticleUpc, doprocessNoPvRefitWithKFParticleUpc};
173+ const std::array<bool , 8 > doprocessDF{doprocessPvRefitWithDCAFitterN, doprocessNoPvRefitWithDCAFitterN,
174+ doprocessPvRefitWithDCAFitterNCentFT0C, doprocessNoPvRefitWithDCAFitterNCentFT0C,
175+ doprocessPvRefitWithDCAFitterNCentFT0M, doprocessNoPvRefitWithDCAFitterNCentFT0M, doprocessPvRefitWithDCAFitterNUpc, doprocessNoPvRefitWithDCAFitterNUpc};
176+ const std::array<bool , 8 > doprocessKF{doprocessPvRefitWithKFParticle, doprocessNoPvRefitWithKFParticle,
177+ doprocessPvRefitWithKFParticleCentFT0C, doprocessNoPvRefitWithKFParticleCentFT0C,
178+ doprocessPvRefitWithKFParticleCentFT0M, doprocessNoPvRefitWithKFParticleCentFT0M, doprocessPvRefitWithKFParticleUpc, doprocessNoPvRefitWithKFParticleUpc};
178179 if ((std::accumulate (doprocessDF.begin (), doprocessDF.end (), 0 ) + std::accumulate (doprocessKF.begin (), doprocessKF.end (), 0 )) != 1 ) {
179180 LOGP (fatal, " One and only one process function must be enabled at a time." );
180181 }
181- std::array<bool , 4 > processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M, doprocessCollisionsUpc};
182+ if (std::accumulate (doprocessKF.begin (), doprocessKF.end (), 0 ) == 1 && createCharmNuclei == true ) {
183+ LOGP (fatal, " KF based reconstruction of charm nuclei is not impemented yet." );
184+ }
185+ const std::array<bool , 4 > processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M, doprocessCollisionsUpc};
182186 const int nProcessesCollisions = std::accumulate (processesCollisions.begin (), processesCollisions.end (), 0 );
183187
184- std::array<bool , 5 > processesUpc = {doprocessPvRefitWithDCAFitterNUpc, doprocessNoPvRefitWithDCAFitterNUpc, doprocessPvRefitWithKFParticleUpc, doprocessNoPvRefitWithKFParticleUpc, doprocessCollisionsUpc};
188+ const std::array<bool , 5 > processesUpc = {doprocessPvRefitWithDCAFitterNUpc, doprocessNoPvRefitWithDCAFitterNUpc, doprocessPvRefitWithKFParticleUpc, doprocessNoPvRefitWithKFParticleUpc, doprocessCollisionsUpc};
185189 const int nProcessesUpc = std::accumulate (processesUpc.begin (), processesUpc.end (), 0 );
186190
187191 if (nProcessesCollisions > 1 ) {
@@ -204,13 +208,13 @@ struct HfCandidateCreator3Prong {
204208 if (nProcessesUpc > 0 && isRun2) {
205209 LOGP (fatal, " Process function for UPC is only available in Run 3!" );
206210 }
207- std::array<bool , 5 > creationFlags = {createDplus, createDs, createLc, createXic, createCharmNuclei};
208- if (std::accumulate (creationFlags.begin (), creationFlags.end (), 0 ) == 0 ) {
211+ const std::array<bool , 5 > creationFlags = {createDplus, createDs, createLc, createXic, createCharmNuclei};
212+ const int nParticlesToCreate = std::accumulate (creationFlags.begin (), creationFlags.end (), 0 );
213+ if (nParticlesToCreate == 0 ) {
209214 LOGP (fatal, " At least one particle specie should be enabled for the creation." );
210215 }
211-
212- if (createLc && createXic && applyInvMassConstraint) {
213- LOGP (fatal, " Unable to apply invariant mass constraint due to ambiguity of mass hypothesis: only one of Lc and Xic and Cd can be reconstructed." );
216+ if (nParticlesToCreate > 1 && applyInvMassConstraint) {
217+ LOGP (fatal, " Invariant mass constraint can be applied only when one particle specie is requested for creation." );
214218 }
215219
216220 // histograms
@@ -472,9 +476,11 @@ struct HfCandidateCreator3Prong {
472476 TracksWCovExtraPidPiKaPrLightNuclei const &,
473477 BCsType const & bcs)
474478 {
479+ const int kfConstructMethod = kfConstructWithEnergyFitMc ? 2 : 0 ;
480+
475481 for (const auto & rowTrackIndexProng3 : rowsTrackIndexProng3) {
476482 // / reject candidates in collisions not satisfying the event selections
477- auto collision = rowTrackIndexProng3.template collision_as <Coll>();
483+ const auto collision = rowTrackIndexProng3.template collision_as <Coll>();
478484 float centrality{-1 .f };
479485 o2::hf_evsel::HfCollisionRejectionMask rejectionMask{};
480486 if constexpr (ApplyUpcSel) {
@@ -487,14 +493,14 @@ struct HfCandidateCreator3Prong {
487493 continue ;
488494 }
489495
490- auto track0 = rowTrackIndexProng3.template prong0_as <TracksWCovExtraPidPiKaPrLightNuclei>();
491- auto track1 = rowTrackIndexProng3.template prong1_as <TracksWCovExtraPidPiKaPrLightNuclei>();
492- auto track2 = rowTrackIndexProng3.template prong2_as <TracksWCovExtraPidPiKaPrLightNuclei>();
496+ const auto track0 = rowTrackIndexProng3.template prong0_as <TracksWCovExtraPidPiKaPrLightNuclei>();
497+ const auto track1 = rowTrackIndexProng3.template prong1_as <TracksWCovExtraPidPiKaPrLightNuclei>();
498+ const auto track2 = rowTrackIndexProng3.template prong2_as <TracksWCovExtraPidPiKaPrLightNuclei>();
493499
494500 // / Set the magnetic field from ccdb.
495501 // / The static instance of the propagator was already modified in the HFTrackIndexSkimCreator,
496502 // / but this is not true when running on Run2 data/MC already converted into AO2Ds.
497- auto bc = collision.template bc_as <aod::BCsWithTimestamps>();
503+ const auto bc = collision.template bc_as <aod::BCsWithTimestamps>();
498504 if (runNumber != bc.runNumber ()) {
499505 LOG (info) << " >>>>>>>>>>>> Current run number: " << runNumber;
500506 initCCDB (bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, nullptr , isRun2);
@@ -517,7 +523,7 @@ struct HfCandidateCreator3Prong {
517523 kfpVertex.SetCovarianceMatrix (rowTrackIndexProng3.pvRefitSigmaX2 (), rowTrackIndexProng3.pvRefitSigmaXY (), rowTrackIndexProng3.pvRefitSigmaY2 (), rowTrackIndexProng3.pvRefitSigmaXZ (), rowTrackIndexProng3.pvRefitSigmaYZ (), rowTrackIndexProng3.pvRefitSigmaZ2 ());
518524 }
519525 kfpVertex.GetCovarianceMatrix (covMatrixPV);
520- KFParticle kfpV (kfpVertex);
526+ const KFParticle kfpV (kfpVertex);
521527 registry.fill (HIST (" hCovPVXX" ), covMatrixPV[0 ]);
522528 registry.fill (HIST (" hCovPVYY" ), covMatrixPV[2 ]);
523529 registry.fill (HIST (" hCovPVXZ" ), covMatrixPV[3 ]);
@@ -558,9 +564,9 @@ struct HfCandidateCreator3Prong {
558564 registry.fill (HIST (" hDcaZProngs" ), track2.pt (), UndefValueFloat);
559565 }
560566
561- auto [impactParameter0Z, errImpactParameter0Z] = kfCalculateImpactParameterZ (kfFirstProton, kfpV);
562- auto [impactParameter1Z, errImpactParameter1Z] = kfCalculateImpactParameterZ (kfSecondKaon, kfpV);
563- auto [impactParameter2Z, errImpactParameter2Z] = kfCalculateImpactParameterZ (kfThirdProton, kfpV);
567+ const auto [impactParameter0Z, errImpactParameter0Z] = kfCalculateImpactParameterZ (kfFirstProton, kfpV);
568+ const auto [impactParameter1Z, errImpactParameter1Z] = kfCalculateImpactParameterZ (kfSecondKaon, kfpV);
569+ const auto [impactParameter2Z, errImpactParameter2Z] = kfCalculateImpactParameterZ (kfThirdProton, kfpV);
564570
565571 const float chi2primFirst = kfCalculateChi2ToPrimaryVertex (kfFirstProton, kfpV);
566572 const float chi2primSecond = kfCalculateChi2ToPrimaryVertex (kfSecondKaon, kfpV);
@@ -574,33 +580,53 @@ struct HfCandidateCreator3Prong {
574580 const float chi2geoFirstThird = kfCalculateChi2geoBetweenParticles (kfFirstProton, kfThirdPion);
575581 const float chi2geoFirstSecond = kfCalculateChi2geoBetweenParticles (kfFirstProton, kfSecondKaon);
576582
583+ KFParticle* kfCandGeneric{nullptr };
584+
577585 // Λc± → p± K∓ π±, Ξc± → p± K∓ π±
578586 KFParticle kfCandPKPi;
579587 const KFParticle* kfDaughtersPKPi[3 ] = {&kfFirstProton, &kfSecondKaon, &kfThirdPion};
580- kfCandPKPi.SetConstructMethod (2 );
581- kfCandPKPi.Construct (kfDaughtersPKPi, 3 );
588+ kfCandPKPi.SetConstructMethod (kfConstructMethod);
582589 KFParticle kfCandPiKP;
583590 const KFParticle* kfDaughtersPiKP[3 ] = {&kfFirstPion, &kfSecondKaon, &kfThirdProton};
584- kfCandPiKP.SetConstructMethod (2 );
585- kfCandPiKP.Construct (kfDaughtersPiKP, 3 );
591+ kfCandPiKP.SetConstructMethod (kfConstructMethod);
592+ if (createLc || createXic) {
593+ kfCandPKPi.Construct (kfDaughtersPKPi, 3 );
594+ kfCandPiKP.Construct (kfDaughtersPiKP, 3 );
595+ kfCandGeneric = &kfCandPKPi;
596+ }
586597
587598 // D± → π± K∓ π±
588599 KFParticle kfCandPiKPi;
589600 const KFParticle* kfDaughtersPiKPi[3 ] = {&kfFirstPion, &kfSecondKaon, &kfThirdPion};
590- kfCandPiKPi.SetConstructMethod (2 );
591- kfCandPiKPi.Construct (kfDaughtersPiKPi, 3 );
601+ kfCandPiKPi.SetConstructMethod (kfConstructMethod);
602+ if (createDplus) {
603+ kfCandPiKPi.Construct (kfDaughtersPiKPi, 3 );
604+ if (kfCandGeneric == nullptr ) {
605+ kfCandGeneric = &kfCandPiKPi;
606+ }
607+ }
592608
593609 // Ds± → K± K∓ π±
594610 KFParticle kfCandKKPi;
595611 const KFParticle* kfDaughtersKKPi[3 ] = {&kfFirstKaon, &kfSecondKaon, &kfThirdPion};
596- kfCandKKPi.SetConstructMethod (2 );
597- kfCandKKPi.Construct (kfDaughtersKKPi, 3 );
612+ kfCandKKPi.SetConstructMethod (kfConstructMethod);
598613 KFParticle kfCandPiKK;
599614 const KFParticle* kfDaughtersPiKK[3 ] = {&kfFirstPion, &kfSecondKaon, &kfThirdKaon};
600- kfCandPiKK.SetConstructMethod (2 );
601- kfCandPiKK.Construct (kfDaughtersPiKK, 3 );
615+ kfCandPiKK.SetConstructMethod (kfConstructMethod);
616+ if (createDs) {
617+ kfCandKKPi.Construct (kfDaughtersKKPi, 3 );
618+ kfCandPiKK.Construct (kfDaughtersPiKK, 3 );
619+ if (kfCandGeneric == nullptr ) {
620+ kfCandGeneric = &kfCandKKPi;
621+ }
622+ }
602623
603- const float chi2topo = kfCalculateChi2ToPrimaryVertex (kfCandPKPi, kfpV);
624+ if (kfCandGeneric == nullptr ) {
625+ // should never happen, but for redundant safety
626+ LOGP (fatal, " kfCandGeneric was not assigned with address of any candidate hypothesis. Check the create<...> configurables" );
627+ }
628+
629+ const float chi2topo = kfCalculateChi2ToPrimaryVertex (*kfCandGeneric, kfpV);
604630
605631 if (applyTopoConstraint) { // constraints applied after chi2topo getter - to preserve unbiased value of chi2topo
606632 for (const auto & kfCand : std::array<KFParticle*, 5 >{&kfCandPKPi, &kfCandPiKP, &kfCandPiKPi, &kfCandKKPi, &kfCandPiKK}) {
@@ -610,13 +636,13 @@ struct HfCandidateCreator3Prong {
610636 }
611637
612638 KFParticle kfPairKPi;
613- const KFParticle* kfDaughtersKPi[3 ] = {&kfSecondKaon, &kfThirdPion};
614- kfPairKPi.SetConstructMethod (2 );
639+ const KFParticle* kfDaughtersKPi[2 ] = {&kfSecondKaon, &kfThirdPion};
640+ kfPairKPi.SetConstructMethod (kfConstructMethod );
615641 kfPairKPi.Construct (kfDaughtersKPi, 2 );
616642
617643 KFParticle kfPairPiK;
618- const KFParticle* kfDaughtersPiK[3 ] = {&kfFirstPion, &kfSecondKaon};
619- kfPairPiK.SetConstructMethod (2 );
644+ const KFParticle* kfDaughtersPiK[2 ] = {&kfFirstPion, &kfSecondKaon};
645+ kfPairPiK.SetConstructMethod (kfConstructMethod );
620646 kfPairPiK.Construct (kfDaughtersPiK, 2 );
621647
622648 const float massPKPi = kfCandPKPi.GetMass ();
@@ -628,32 +654,36 @@ struct HfCandidateCreator3Prong {
628654 const float massPiK = kfPairPiK.GetMass ();
629655
630656 if (applyInvMassConstraint) { // constraints applied after minv getters - to preserve unbiased values of minv
631- kfCandPKPi.SetNonlinearMassConstraint (createLc ? static_cast <float >(MassLambdaCPlus) : static_cast <float >(MassXiCPlus));
632- kfCandPiKP.SetNonlinearMassConstraint (createLc ? static_cast <float >(MassLambdaCPlus) : static_cast <float >(MassXiCPlus));
633- kfCandPiKPi.SetNonlinearMassConstraint (static_cast <float >(MassDPlus));
634- kfCandKKPi.SetNonlinearMassConstraint (static_cast <float >(MassDS));
635- kfCandPiKK.SetNonlinearMassConstraint (static_cast <float >(MassDS));
657+ if (createLc) {
658+ kfCandGeneric->SetNonlinearMassConstraint (MassLambdaCPlus);
659+ } else if (createXic) {
660+ kfCandGeneric->SetNonlinearMassConstraint (MassXiCPlus);
661+ } else if (createDplus) {
662+ kfCandGeneric->SetNonlinearMassConstraint (MassDPlus);
663+ } else if (createDs) {
664+ kfCandGeneric->SetNonlinearMassConstraint (MassDS);
665+ }
636666 }
637667
638- const float chi2geo = kfCandPKPi. Chi2 () / static_cast <float >(kfCandPKPi. NDF ());
639- const std::pair<float , float > ldl = kfCalculateLdL (kfCandPKPi , kfpV);
668+ const float chi2geo = kfCandGeneric-> Chi2 () / static_cast <float >(kfCandGeneric-> NDF ());
669+ const std::pair<float , float > ldl = kfCalculateLdL (*kfCandGeneric , kfpV);
640670
641- std::array<float , 3 > pProng0 = kfCalculateProngMomentumInSecondaryVertex (kfFirstProton, kfCandPiKP );
642- std::array<float , 3 > pProng1 = kfCalculateProngMomentumInSecondaryVertex (kfSecondKaon, kfCandPiKP );
643- std::array<float , 3 > pProng2 = kfCalculateProngMomentumInSecondaryVertex (kfThirdPion, kfCandPiKP );
671+ const std::array<float , 3 > pProng0 = kfCalculateProngMomentumInSecondaryVertex (kfFirstProton, *kfCandGeneric );
672+ const std::array<float , 3 > pProng1 = kfCalculateProngMomentumInSecondaryVertex (kfSecondKaon, *kfCandGeneric );
673+ const std::array<float , 3 > pProng2 = kfCalculateProngMomentumInSecondaryVertex (kfThirdPion, *kfCandGeneric );
644674
645- registry.fill (HIST (" hCovSVXX" ), kfCandPKPi. Covariance (0 , 0 ));
646- registry.fill (HIST (" hCovSVYY" ), kfCandPKPi. Covariance (1 , 1 ));
647- registry.fill (HIST (" hCovSVXZ" ), kfCandPKPi. Covariance (2 , 0 ));
648- registry.fill (HIST (" hCovSVZZ" ), kfCandPKPi. Covariance (2 , 2 ));
675+ registry.fill (HIST (" hCovSVXX" ), kfCandGeneric-> GetCovariance (0 , 0 ));
676+ registry.fill (HIST (" hCovSVYY" ), kfCandGeneric-> GetCovariance (1 , 1 ));
677+ registry.fill (HIST (" hCovSVXZ" ), kfCandGeneric-> GetCovariance (2 , 0 ));
678+ registry.fill (HIST (" hCovSVZZ" ), kfCandGeneric-> GetCovariance (2 , 2 ));
649679
650- auto * covMatrixSV = kfCandPKPi. CovarianceMatrix ();
680+ const auto * const covMatrixSV = kfCandGeneric-> CovarianceMatrix ();
651681 double phi{}, theta{};
652- getPointDirection (std::array{kfpV.GetX (), kfpV.GetY (), kfpV.GetZ ()}, std::array{kfCandPKPi. GetX (), kfCandPKPi. GetY (), kfCandPKPi. GetZ ()}, phi, theta);
653- auto errorDecayLength = std::sqrt (getRotatedCovMatrixXX (covMatrixPV, phi, theta) + getRotatedCovMatrixXX (covMatrixSV, phi, theta));
654- auto errorDecayLengthXY = std::sqrt (getRotatedCovMatrixXX (covMatrixPV, phi, 0 .) + getRotatedCovMatrixXX (covMatrixSV, phi, 0 .));
682+ getPointDirection (std::array{kfpV.GetX (), kfpV.GetY (), kfpV.GetZ ()}, std::array{kfCandGeneric-> GetX (), kfCandGeneric-> GetY (), kfCandGeneric-> GetZ ()}, phi, theta);
683+ const auto errorDecayLength = std::sqrt (getRotatedCovMatrixXX (covMatrixPV, phi, theta) + getRotatedCovMatrixXX (covMatrixSV, phi, theta));
684+ const auto errorDecayLengthXY = std::sqrt (getRotatedCovMatrixXX (covMatrixPV, phi, 0 .) + getRotatedCovMatrixXX (covMatrixSV, phi, 0 .));
655685
656- auto indexCollision = collision.globalIndex ();
686+ const auto indexCollision = collision.globalIndex ();
657687 uint8_t bitmapProngsContributorsPV = 0 ;
658688 if (indexCollision == track0.collisionId () && track0.isPVContributor ()) {
659689 SETBIT (bitmapProngsContributorsPV, 0 );
@@ -669,9 +699,9 @@ struct HfCandidateCreator3Prong {
669699 // fill candidate table rows
670700 rowCandidateBase (indexCollision,
671701 kfpV.GetX (), kfpV.GetY (), kfpV.GetZ (),
672- kfCandPKPi. GetX (), kfCandPKPi. GetY (), kfCandPKPi. GetZ (),
702+ kfCandGeneric-> GetX (), kfCandGeneric-> GetY (), kfCandGeneric-> GetZ (),
673703 errorDecayLength, errorDecayLengthXY,
674- kfCandPKPi. GetChi2 () / static_cast <float >(kfCandPKPi. GetNDF ()),
704+ kfCandGeneric-> GetChi2 () / static_cast <float >(kfCandGeneric-> GetNDF ()),
675705 pProng0.at (0 ), pProng0.at (1 ), pProng0.at (2 ),
676706 pProng1.at (0 ), pProng1.at (1 ), pProng1.at (2 ),
677707 pProng2.at (0 ), pProng2.at (1 ), pProng2.at (2 ),
@@ -683,11 +713,11 @@ struct HfCandidateCreator3Prong {
683713 rowTrackIndexProng3.hfflag ());
684714
685715 // fill KF info
686- rowCandidateKF (kfCandPKPi. GetErrX (), kfCandPKPi. GetErrY (), kfCandPKPi. GetErrZ (),
687- std::sqrt (kfpV.Covariance (0 , 0 )), std::sqrt (kfpV.Covariance (1 , 1 )), std::sqrt (kfpV.Covariance (2 , 2 )),
716+ rowCandidateKF (kfCandGeneric-> GetErrX (), kfCandGeneric-> GetErrY (), kfCandGeneric-> GetErrZ (),
717+ std::sqrt (kfpV.GetCovariance (0 , 0 )), std::sqrt (kfpV.GetCovariance (1 , 1 )), std::sqrt (kfpV.GetCovariance (2 , 2 )),
688718 massPKPi, massPiKP, massPiKPi, massKKPi, massPiKK, massKPi, massPiK,
689- kfCandPKPi. GetPx (), kfCandPKPi. GetPy (), kfCandPKPi. GetPz (),
690- kfCandPKPi. GetErrPx (), kfCandPKPi. GetErrPy (), kfCandPKPi. GetErrPz (),
719+ kfCandGeneric-> GetPx (), kfCandGeneric-> GetPy (), kfCandGeneric-> GetPz (),
720+ kfCandGeneric-> GetErrPx (), kfCandGeneric-> GetErrPy (), kfCandGeneric-> GetErrPz (),
691721 chi2primFirst, chi2primSecond, chi2primThird,
692722 dcaSecondThird, dcaFirstThird, dcaFirstSecond,
693723 chi2geoSecondThird, chi2geoFirstThird, chi2geoFirstSecond,
0 commit comments