2121#include " PWGHF/Core/CentralityEstimation.h"
2222#include " PWGHF/Core/DecayChannels.h"
2323#include " PWGHF/Core/HfHelper.h"
24+ #include " PWGHF/Core/HfMlResponseDplusToPiKPi.h"
2425#include " PWGHF/Core/HfMlResponseLcToPKPi.h"
2526#include " PWGHF/Core/SelectorCuts.h"
2627#include " PWGHF/DataModel/CandidateReconstructionTables.h"
@@ -87,6 +88,11 @@ enum MlMode : uint8_t {
8788 FillMlFromNewBDT
8889};
8990
91+ // decay channels
92+ enum DecayChannel { DplusToPiKPi = 0 ,
93+ LcToPKPi
94+ };
95+
9096struct HfFemtoDreamProducer {
9197
9298 Produces<aod::FDCollisions> outputCollision;
@@ -119,9 +125,9 @@ struct HfFemtoDreamProducer {
119125 Configurable<bool > isDebug{" isDebug" , true , " Enable Debug tables" };
120126 Configurable<bool > isRun3{" isRun3" , true , " Running on Run3 or pilot" };
121127
122- // / Lc table
123- Configurable<int > selectionFlagLc{ " selectionFlagLc " , 1 , " Selection Flag for Lc " };
124- Configurable<bool > useCent{" useCent" , false , " Enable centrality for lc " };
128+ // / Charm hadron table
129+ Configurable<int > selectionFlagHadron{ " selectionFlagHadron " , 1 , " Selection Flag for Charm Hadron " };
130+ Configurable<bool > useCent{" useCent" , false , " Enable centrality for Charm Hadron " };
125131
126132 Configurable<int > trkPDGCode{" trkPDGCode" , 2212 , " PDG code of the selected track for Monte Carlo truth" };
127133 Configurable<std::vector<float >> trkCharge{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kSign , " trk" ), std::vector<float >{-1 , 1 }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kSign , " Track selection: " )};
@@ -141,7 +147,7 @@ struct HfFemtoDreamProducer {
141147 Configurable<std::vector<float >> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kITSnClsIbMin , " trk" ), std::vector<float >{-1 .f , 1 .f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kITSnClsIbMin , " Track selection: " )};
142148 Configurable<std::vector<float >> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kITSnClsMin , " trk" ), std::vector<float >{-1 .f , 2 .f , 4 .f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kITSnClsMin , " Track selection: " )};
143149 // ML inference
144- Configurable<int > applyMlMode{" applyMlMode" , 1 , " None: 0, BDT model from Lc selector: 1, New BDT model on Top of Lc selector: 2" };
150+ Configurable<int > applyMlMode{" applyMlMode" , 1 , " None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2" };
145151 Configurable<std::vector<double >> binsPtMl{" binsPtMl" , std::vector<double >{hf_cuts_ml::vecBinsPt}, " pT bin limits for ML application" };
146152 Configurable<std::vector<int >> cutDirMl{" cutDirMl" , std::vector<int >{hf_cuts_ml::vecCutDir}, " Whether to reject score values greater or smaller than the threshold" };
147153 Configurable<LabeledArray<double >> cutsMl{" cutsMl" , {hf_cuts_ml::Cuts[0 ], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, " ML selections per pT bin" };
@@ -152,6 +158,8 @@ struct HfFemtoDreamProducer {
152158
153159 HfHelper hfHelper;
154160 o2::analysis::HfMlResponseLcToPKPi<float > hfMlResponse;
161+ o2::analysis::HfMlResponseDplusToPiKPi<float > hfMlResponseDplus;
162+ std::vector<float > outputMlDplus = {};
155163 std::vector<float > outputMlPKPi = {};
156164 std::vector<float > outputMlPiKP = {};
157165 o2::ccdb::CcdbApi ccdbApi;
@@ -162,6 +170,8 @@ struct HfFemtoDreamProducer {
162170
163171 float magField;
164172 int runNumber;
173+ using CandidateDplus = soa::Join<aod::HfCand3ProngWPidPiKa, aod::HfSelDplusToPiKPi>;
174+ using CandidateDplusMc = soa::Join<aod::HfCand3ProngWPidPiKa, aod::HfSelDplusToPiKPi, aod::HfCand3ProngMcRec>;
165175 using CandidateLc = soa::Join<aod::HfCand3ProngWPidPiKaPr, aod::HfSelLc>;
166176 using CandidateLcMc = soa::Join<aod::HfCand3ProngWPidPiKaPr, aod::HfSelLc, aod::HfCand3ProngMcRec>;
167177
@@ -176,14 +186,16 @@ struct HfFemtoDreamProducer {
176186
177187 using GeneratedMc = soa::Filtered<soa::Join<aod::McParticles, aod::HfCand3ProngMcGen>>;
178188
179- Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc);
189+ Filter filterSelectCandidateDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron || aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron);
190+ Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron);
180191
181192 HistogramRegistry qaRegistry{" QAHistos" , {}, OutputObjHandlingPolicy::AnalysisObject};
182193 HistogramRegistry trackRegistry{" Tracks" , {}, OutputObjHandlingPolicy::AnalysisObject};
183194
184195 void init (InitContext&)
185196 {
186- std::array<bool , 5 > processes = {doprocessDataCharmHad, doprocessMcCharmHad, doprocessDataCharmHadWithML, doprocessMcCharmHadWithML, doprocessMcCharmHadGen};
197+ std::array<bool , 10 > processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen,
198+ doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen};
187199 if (std::accumulate (processes.begin (), processes.end (), 0 ) != 1 ) {
188200 LOGP (fatal, " One and only one process function must be enabled at a time." );
189201 }
@@ -404,7 +416,7 @@ struct HfFemtoDreamProducer {
404416 return fIsTrackFilled ;
405417 }
406418
407- template <bool isMc, bool useCharmMl, typename TrackType, typename CollisionType, typename CandType>
419+ template <DecayChannel channel, bool isMc, bool useCharmMl, typename TrackType, typename CollisionType, typename CandType>
408420 void fillCharmHadronTable (CollisionType const & col, TrackType const & tracks, CandType const & candidates)
409421 {
410422 const auto vtxZ = col.posZ ();
@@ -451,44 +463,15 @@ struct HfFemtoDreamProducer {
451463 bool isTrackFilled = false ;
452464 bool isSelectedMlLcToPKPi = true ;
453465 bool isSelectedMlLcToPiKP = true ;
466+ bool isSelectedMlDplusToPiKPi = true ;
454467 for (const auto & candidate : candidates) {
468+ outputMlDplus = {-1 .0f , -1 .0f , -1 .0f };
455469 outputMlPKPi = {-1 .0f , -1 .0f , -1 .0f };
456470 outputMlPiKP = {-1 .0f , -1 .0f , -1 .0f };
457471 auto trackPos1 = candidate.template prong0_as <TrackType>(); // positive daughter (negative for the antiparticles)
458472 auto trackNeg = candidate.template prong1_as <TrackType>(); // negative daughter (positive for the antiparticles)
459473 auto trackPos2 = candidate.template prong2_as <TrackType>(); // positive daughter (negative for the antiparticles)
460-
461- if constexpr (useCharmMl) {
462- // / fill with ML information
463- // / BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score
464- if (applyMlMode == FillMlFromSelector) {
465- if (candidate.mlProbLcToPKPi ().size () > 0 ) {
466- outputMlPKPi.at (0 ) = candidate.mlProbLcToPKPi ()[0 ]; // / bkg score
467- outputMlPKPi.at (1 ) = candidate.mlProbLcToPKPi ()[1 ]; // / prompt score
468- outputMlPKPi.at (2 ) = candidate.mlProbLcToPKPi ()[2 ]; // / non-prompt score
469- }
470- if (candidate.mlProbLcToPiKP ().size () > 0 ) {
471- outputMlPiKP.at (0 ) = candidate.mlProbLcToPiKP ()[0 ]; // / bkg score
472- outputMlPiKP.at (1 ) = candidate.mlProbLcToPiKP ()[1 ]; // / prompt score
473- outputMlPiKP.at (2 ) = candidate.mlProbLcToPiKP ()[2 ]; // / non-prompt score
474- }
475- } else if (applyMlMode == FillMlFromNewBDT) {
476- isSelectedMlLcToPKPi = false ;
477- isSelectedMlLcToPiKP = false ;
478- if (candidate.mlProbLcToPKPi ().size () > 0 ) {
479- std::vector<float > inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures (candidate, true );
480- isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl (inputFeaturesLcToPKPi, candidate.pt (), outputMlPKPi);
481- }
482- if (candidate.mlProbLcToPiKP ().size () > 0 ) {
483- std::vector<float > inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures (candidate, false );
484- isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl (inputFeaturesLcToPiKP, candidate.pt (), outputMlPKPi);
485- }
486- if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP)
487- continue ;
488- } else {
489- LOGF (fatal, " Please check your Ml configuration!!" );
490- }
491- }
474+
492475 auto bc = col.template bc_as <aod::BCsWithTimestamps>();
493476 int64_t timeStamp = bc.timestamp ();
494477 auto fillTable = [&](int CandFlag,
@@ -526,8 +509,65 @@ struct HfFemtoDreamProducer {
526509 }
527510 } };
528511
529- fillTable (0 , candidate.isSelLcToPKPi (), outputMlPKPi.at (0 ), outputMlPKPi.at (1 ), outputMlPKPi.at (2 ));
530- fillTable (1 , candidate.isSelLcToPiKP (), outputMlPiKP.at (0 ), outputMlPiKP.at (1 ), outputMlPiKP.at (2 ));
512+ if constexpr (channel == DecayChannel::DplusToPiKPi) {
513+ if constexpr (useCharmMl) {
514+ // / fill with ML information
515+ // / BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score
516+ if (applyMlMode == FillMlFromSelector) {
517+ if (candidate.mlProbDplusToPiKPi ().size () > 0 ) {
518+ outputMlDplus.at (0 ) = candidate.mlProbDplusToPiKPi ()[0 ]; // / bkg score
519+ outputMlDplus.at (1 ) = candidate.mlProbDplusToPiKPi ()[1 ]; // / prompt score
520+ outputMlDplus.at (2 ) = candidate.mlProbDplusToPiKPi ()[2 ]; // / non-prompt score
521+ }
522+ } else if (applyMlMode == FillMlFromNewBDT) {
523+ isSelectedMlDplusToPiKPi = false ;
524+ if (candidate.mlProbDplusToPiKPi ().size () > 0 ) {
525+ std::vector<float > inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures (candidate);
526+ isSelectedMlDplusToPiKPi = hfMlResponseDplus.isSelectedMl (inputFeaturesDplusToPiKPi, candidate.pt (), outputMlDplus);
527+ }
528+ if (!isSelectedMlDplusToPiKPi)
529+ continue ;
530+ } else {
531+ LOGF (fatal, " Please check your Ml configuration!!" );
532+ }
533+ }
534+ fillTable (0 , candidate.isSelDplusToPiKPi (), outputMlDplus.at (0 ), outputMlDplus.at (1 ), outputMlDplus.at (2 ));
535+
536+ } else if constexpr (channel == DecayChannel::LcToPKPi) {
537+ if constexpr (useCharmMl) {
538+ // / fill with ML information
539+ // / BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score
540+ if (applyMlMode == FillMlFromSelector) {
541+ if (candidate.mlProbLcToPKPi ().size () > 0 ) {
542+ outputMlPKPi.at (0 ) = candidate.mlProbLcToPKPi ()[0 ]; // / bkg score
543+ outputMlPKPi.at (1 ) = candidate.mlProbLcToPKPi ()[1 ]; // / prompt score
544+ outputMlPKPi.at (2 ) = candidate.mlProbLcToPKPi ()[2 ]; // / non-prompt score
545+ }
546+ if (candidate.mlProbLcToPiKP ().size () > 0 ) {
547+ outputMlPiKP.at (0 ) = candidate.mlProbLcToPiKP ()[0 ]; // / bkg score
548+ outputMlPiKP.at (1 ) = candidate.mlProbLcToPiKP ()[1 ]; // / prompt score
549+ outputMlPiKP.at (2 ) = candidate.mlProbLcToPiKP ()[2 ]; // / non-prompt score
550+ }
551+ } else if (applyMlMode == FillMlFromNewBDT) {
552+ isSelectedMlLcToPKPi = false ;
553+ isSelectedMlLcToPiKP = false ;
554+ if (candidate.mlProbLcToPKPi ().size () > 0 ) {
555+ std::vector<float > inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures (candidate, true );
556+ isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl (inputFeaturesLcToPKPi, candidate.pt (), outputMlPKPi);
557+ }
558+ if (candidate.mlProbLcToPiKP ().size () > 0 ) {
559+ std::vector<float > inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures (candidate, false );
560+ isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl (inputFeaturesLcToPiKP, candidate.pt (), outputMlPKPi);
561+ }
562+ if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP)
563+ continue ;
564+ } else {
565+ LOGF (fatal, " Please check your Ml configuration!!" );
566+ }
567+ }
568+ fillTable (0 , candidate.isSelLcToPKPi (), outputMlPKPi.at (0 ), outputMlPKPi.at (1 ), outputMlPKPi.at (2 ));
569+ fillTable (1 , candidate.isSelLcToPiKP (), outputMlPiKP.at (0 ), outputMlPiKP.at (1 ), outputMlPiKP.at (2 ));
570+ }
531571 }
532572
533573 if (!isTrackFilled) {
@@ -586,20 +626,84 @@ struct HfFemtoDreamProducer {
586626 }
587627 }
588628
589- void processDataCharmHad (FemtoFullCollision const & col,
629+ // / DplusToPiKPi
630+ void processDataDplusToPiKPi (FemtoFullCollision const & col,
631+ aod::BCsWithTimestamps const &,
632+ FemtoHFTracks const & tracks,
633+ soa::Filtered<CandidateDplus> const & candidates)
634+ {
635+ // get magnetic field for run
636+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
637+
638+ fillCharmHadronTable<DecayChannel::DplusToPiKPi, false , false >(col, tracks, candidates);
639+ }
640+ PROCESS_SWITCH (HfFemtoDreamProducer, processDataDplusToPiKPi,
641+ " Provide experimental data for DplusToPiKPi femto" , false );
642+
643+ void processDataDplusToPiKPiWithML (FemtoFullCollision const & col,
644+ aod::BCsWithTimestamps const &,
645+ FemtoHFTracks const & tracks,
646+ soa::Filtered<soa::Join<CandidateDplus,
647+ aod::HfMlDplusToPiKPi>> const & candidates)
648+ {
649+
650+ // get magnetic field for run
651+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
652+
653+ fillCharmHadronTable<DecayChannel::DplusToPiKPi, false , true >(col, tracks, candidates);
654+ }
655+ PROCESS_SWITCH (HfFemtoDreamProducer, processDataDplusToPiKPiWithML,
656+ " Provide experimental data for DplusToPiKPi with ml" , false );
657+
658+ void processMcDplusToPiKPi (FemtoFullCollisionMc const & col,
659+ aod::BCsWithTimestamps const &,
660+ FemtoHFMcTracks const & tracks,
661+ aod::McParticles const &,
662+ CandidateDplusMc const & candidates)
663+ {
664+ // get magnetic field for run
665+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
666+
667+ fillCharmHadronTable<DecayChannel::DplusToPiKPi, true , false >(col, tracks, candidates);
668+ }
669+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcDplusToPiKPi, " Provide Mc for DplusToPiKPi" , false );
670+
671+ void processMcDplusToPiKPiWithML (FemtoFullCollisionMc const & col,
672+ aod::BCsWithTimestamps const &,
673+ FemtoHFMcTracks const & tracks,
674+ aod::McParticles const &,
675+ soa::Join<CandidateDplusMc,
676+ aod::HfMlDplusToPiKPi> const & candidates)
677+ {
678+ // get magnetic field for run
679+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
680+
681+ fillCharmHadronTable<DecayChannel::DplusToPiKPi, true , true >(col, tracks, candidates);
682+ }
683+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcDplusToPiKPiWithML, " Provide Mc for DplusToPiKPi with ml" , false );
684+
685+ void processMcDplusToPiKPiGen (GeneratedMc const & particles)
686+ {
687+
688+ fillCharmHadMcGen (particles);
689+ }
690+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcDplusToPiKPiGen, " Provide Mc Generated DplusToPiKPi" , false );
691+
692+ // / LcToPKPi
693+ void processDataLcToPKPi (FemtoFullCollision const & col,
590694 aod::BCsWithTimestamps const &,
591695 FemtoHFTracks const & tracks,
592696 soa::Filtered<CandidateLc> const & candidates)
593697 {
594698 // get magnetic field for run
595699 getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
596700
597- fillCharmHadronTable<false , false >(col, tracks, candidates);
701+ fillCharmHadronTable<DecayChannel::LcToPKPi, false , false >(col, tracks, candidates);
598702 }
599- PROCESS_SWITCH (HfFemtoDreamProducer, processDataCharmHad ,
600- " Provide experimental data for charm hadron femto" , false );
703+ PROCESS_SWITCH (HfFemtoDreamProducer, processDataLcToPKPi ,
704+ " Provide experimental data for lctopkpi femto" , false );
601705
602- void processDataCharmHadWithML (FemtoFullCollision const & col,
706+ void processDataLcToPKPiWithML (FemtoFullCollision const & col,
603707 aod::BCsWithTimestamps const &,
604708 FemtoHFTracks const & tracks,
605709 soa::Filtered<soa::Join<CandidateLc,
@@ -609,12 +713,12 @@ struct HfFemtoDreamProducer {
609713 // get magnetic field for run
610714 getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
611715
612- fillCharmHadronTable<false , true >(col, tracks, candidates);
716+ fillCharmHadronTable<DecayChannel::LcToPKPi, false , true >(col, tracks, candidates);
613717 }
614- PROCESS_SWITCH (HfFemtoDreamProducer, processDataCharmHadWithML ,
615- " Provide experimental data for charm hadron femto with ml" , false );
718+ PROCESS_SWITCH (HfFemtoDreamProducer, processDataLcToPKPiWithML ,
719+ " Provide experimental data for lctopkpi femto with ml" , false );
616720
617- void processMcCharmHad (FemtoFullCollisionMc const & col,
721+ void processMcLcToPKPi (FemtoFullCollisionMc const & col,
618722 aod::BCsWithTimestamps const &,
619723 FemtoHFMcTracks const & tracks,
620724 aod::McParticles const &,
@@ -623,11 +727,11 @@ struct HfFemtoDreamProducer {
623727 // get magnetic field for run
624728 getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
625729
626- fillCharmHadronTable<true , false >(col, tracks, candidates);
730+ fillCharmHadronTable<DecayChannel::LcToPKPi, true , false >(col, tracks, candidates);
627731 }
628- PROCESS_SWITCH (HfFemtoDreamProducer, processMcCharmHad , " Provide Mc for charm hadron " , false );
732+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcLcToPKPi , " Provide Mc for lctopkpi " , false );
629733
630- void processMcCharmHadWithML (FemtoFullCollisionMc const & col,
734+ void processMcLcToPKPiWithML (FemtoFullCollisionMc const & col,
631735 aod::BCsWithTimestamps const &,
632736 FemtoHFMcTracks const & tracks,
633737 aod::McParticles const &,
@@ -637,16 +741,16 @@ struct HfFemtoDreamProducer {
637741 // get magnetic field for run
638742 getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
639743
640- fillCharmHadronTable<true , true >(col, tracks, candidates);
744+ fillCharmHadronTable<DecayChannel::LcToPKPi, true , true >(col, tracks, candidates);
641745 }
642- PROCESS_SWITCH (HfFemtoDreamProducer, processMcCharmHadWithML , " Provide Mc for charm hadron with ml" , false );
746+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcLcToPKPiWithML , " Provide Mc for lctopkpi with ml" , false );
643747
644- void processMcCharmHadGen (GeneratedMc const & particles)
748+ void processMcLcToPKPiGen (GeneratedMc const & particles)
645749 {
646750
647751 fillCharmHadMcGen (particles);
648752 }
649- PROCESS_SWITCH (HfFemtoDreamProducer, processMcCharmHadGen , " Provide Mc Generated charm hadron " , false );
753+ PROCESS_SWITCH (HfFemtoDreamProducer, processMcLcToPKPiGen , " Provide Mc Generated lctopkpi " , false );
650754};
651755
652756WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments