@@ -55,6 +55,7 @@ DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse
5555DECLARE_SOA_COLUMN (Y, y, float ); // ! Rapidity of candidate
5656DECLARE_SOA_COLUMN (Phi, phi, float ); // ! Azimuth angle of candidate
5757DECLARE_SOA_COLUMN (ImpactParameterXY, impactParameterXY, float ); // ! Dca XY of candidate
58+ DECLARE_SOA_COLUMN (ImpactParameterZ, impactParameterZ, float ); // ! Dca Z of candidate
5859DECLARE_SOA_COLUMN (MlScoreBkg, mlScoreBkg, float ); // ! ML score for background class
5960DECLARE_SOA_COLUMN (MlScorePrompt, mlScorePrompt, float ); // ! ML Prompt score for prompt class
6061DECLARE_SOA_COLUMN (MlScoreNonPrompt, mlScoreNonPrompt, float ); // ! ML Non Prompt score for non prompt class
@@ -67,6 +68,7 @@ DECLARE_SOA_COLUMN(PhiProng2, phiProng2, float); //! Phi of the
6768DECLARE_SOA_COLUMN (EtaProng0, etaProng0, float ); // ! Eta of the 1st daughter
6869DECLARE_SOA_COLUMN (EtaProng1, etaProng1, float ); // ! Eta of the 2nd daughter
6970DECLARE_SOA_COLUMN (EtaProng2, etaProng2, float ); // ! Eta of the 3rd daughter (if present)
71+ DECLARE_SOA_COLUMN (FlagMcMatchRec, flagMcMatchRec, int8_t ); // ! Flag for reconstruction level matching
7072} // namespace hf_charm_cand_lite
7173
7274DECLARE_SOA_TABLE (HfCharmCandLites, " AOD" , " HFCHARMCANDLITE" , // ! Table with some charm hadron properties
@@ -84,6 +86,7 @@ DECLARE_SOA_TABLE(HfCharmCandLites, "AOD", "HFCHARMCANDLITE", //! Table with som
8486 hf_charm_cand_lite::Y,
8587 hf_charm_cand_lite::Phi,
8688 hf_charm_cand_lite::ImpactParameterXY,
89+ hf_charm_cand_lite::ImpactParameterZ,
8790 hf_charm_cand_lite::MlScoreBkg,
8891 hf_charm_cand_lite::MlScorePrompt,
8992 hf_charm_cand_lite::MlScoreNonPrompt,
@@ -95,7 +98,8 @@ DECLARE_SOA_TABLE(HfCharmCandLites, "AOD", "HFCHARMCANDLITE", //! Table with som
9598 hf_charm_cand_lite::PhiProng2,
9699 hf_charm_cand_lite::EtaProng0,
97100 hf_charm_cand_lite::EtaProng1,
98- hf_charm_cand_lite::EtaProng2);
101+ hf_charm_cand_lite::EtaProng2,
102+ hf_charm_cand_lite::FlagMcMatchRec);
99103} // namespace o2::aod
100104
101105struct HfTaskCharmHadImpactPar {
@@ -105,15 +109,20 @@ struct HfTaskCharmHadImpactPar {
105109 Configurable<int > fillLightTreeCandidate{" fillLightTreeCandidate" , 0 , " Flag to store charm hadron features" };
106110 Configurable<int > centEstimator{" centEstimator" , 0 , " Centrality estimation (None: 0, FT0C: 2, FT0M: 3)" };
107111 Configurable<int > occEstimator{" occEstimator" , 0 , " Occupancy estimation (None: 0, ITS: 1, FT0C: 2)" };
112+ Configurable<bool > fillOnlySignal{" fillOnlySignal" , false , " Flag to store only matched candidates" };
108113
109114 HfHelper hfHelper;
110115
111116 using Collisions = soa::Join<aod::Collisions, aod::EvSels>;
112117 using CollisionsCent = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Ms, aod::CentFT0Cs>;
113118 using CandDplusData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi>>;
114119 using CandDplusDataWithMl = soa::Filtered<soa::Join<CandDplusData, aod::HfMlDplusToPiKPi>>;
120+ using CandDplusMC = soa::Filtered<soa::Join<CandDplusData, aod::HfCand3ProngMcRec>>;
121+ using CandDplusMCWithMl = soa::Filtered<soa::Join<CandDplusMC, aod::HfMlDplusToPiKPi>>;
115122 using CandDzeroData = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0>>;
116123 using CandDzeroDataWithMl = soa::Filtered<soa::Join<CandDzeroData, aod::HfMlD0>>;
124+ using CandDzeroMc = soa::Filtered<soa::Join<CandDzeroData, aod::HfCand2ProngMcRec>>;
125+ using CandDzeroMcWithMl = soa::Filtered<soa::Join<CandDzeroMc, aod::HfMlD0>>;
117126
118127 Filter filterDplusFlag = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag;
119128 Filter filterDzeroFlag = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
@@ -131,26 +140,33 @@ struct HfTaskCharmHadImpactPar {
131140
132141 void init (InitContext&)
133142 {
134- std::array<bool , 4 > doprocess{doprocessDplus, doprocessDplusWithMl, doprocessDzero, doprocessDzeroWithMl };
143+ std::array<bool , 8 > doprocess{doprocessDataDplus, doprocessDataDplusWithMl, doprocessMCDplus, doprocessMCDplusWithMl, doprocessDataDzero, doprocessDataDzeroWithMl, doprocessMCDzero, doprocessMCDzeroWithMl };
135144 if ((std::accumulate (doprocess.begin (), doprocess.end (), 0 )) != 1 ) {
136145 LOGP (fatal, " Only one process function should be enabled! Please check your configuration!" );
137146 }
138- if (doprocessDplus || doprocessDzero ) {
147+ if (doprocessDataDplus || doprocessDataDzero || doprocessMCDplus || doprocessMCDzero ) {
139148 registry.add (" hMassPtImpParPhiY" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c});dca XY (#mum); phi; y;" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar, axisPhi, axisY});
140- } else if (doprocessDplusWithMl || doprocessDzeroWithMl ) {
149+ } else if (doprocessDataDplusWithMl || doprocessDataDzeroWithMl || doprocessMCDplusWithMl || doprocessMCDzeroWithMl ) {
141150 registry.add (" hMassPtImpParPhiY" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c});dca XY (#mum); phi; y; ML score 0;ML score 1; ML score 2;" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar, axisPhi, axisY, axisMlScore0, axisMlScore1, axisMlScore2});
142151 }
143152 }
144153
145154 // Fill THnSparses for the ML analysis
146155 // / \param candidate is a particle candidate
147- template <Channel channel, bool withMl, typename CCands>
156+ template <Channel channel, bool doMc, bool withMl, typename CCands>
148157 void fillSparse (const CCands& candidate)
149158 {
150159 std::vector<float > outputMl = {-999 ., -999 ., -999 .};
151160 float invMass{-1 .f };
152161 float yCand{-999 .f };
153162 if constexpr (channel == Channel::DplusToKPiPi) { // D+ -> Kpipi
163+ if constexpr (doMc) {
164+ if (fillOnlySignal) {
165+ if (std::abs (candidate.flagMcMatchRec ()) != 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) {
166+ return ;
167+ }
168+ }
169+ }
154170 invMass = hfHelper.invMassDplusToPiKPi (candidate);
155171 yCand = hfHelper.yDplus (candidate);
156172 if constexpr (withMl) {
@@ -163,6 +179,13 @@ struct HfTaskCharmHadImpactPar {
163179 }
164180 } else if constexpr (channel == Channel::DzeroToKPi) {
165181 if (candidate.isSelD0 ()) { // D0 -> Kpi
182+ if constexpr (doMc) {
183+ if (fillOnlySignal) {
184+ if (std::abs (candidate.flagMcMatchRec ()) != 1 << aod::hf_cand_2prong::DecayType::D0ToPiK) {
185+ return ;
186+ }
187+ }
188+ }
166189 invMass = hfHelper.invMassD0ToPiK (candidate);
167190 yCand = hfHelper.yD0 (candidate);
168191 if constexpr (withMl) {
@@ -192,7 +215,7 @@ struct HfTaskCharmHadImpactPar {
192215 // Fill the TTree with both event and candidate properties
193216 // / \param candidate is a particle candidate
194217 // / \param collision is the respective collision
195- template <Channel channel, bool withMl, typename CCands, typename CollType>
218+ template <Channel channel, bool doMc, bool withMl, typename CCands, typename CollType>
196219 void fillTree (const CCands& candidate, const CollType& collision)
197220 {
198221 std::vector<float > outputMl = {-999 ., -999 ., -999 .};
@@ -241,6 +264,12 @@ struct HfTaskCharmHadImpactPar {
241264 occupancy = getOccupancyColl (collision, occEstimator);
242265 }
243266
267+ int8_t flagMcMatchRec = 0 ;
268+ if constexpr (doMc) {
269+ flagMcMatchRec = candidate.flagMcMatchRec ();
270+ }
271+ double impParZ = candidate.impactParameterXY () * (-1 ) * candidate.pz () / candidate.pt ();
272+
244273 hfCharmCandLite (
245274 // Event features
246275 collision.numContrib (),
@@ -258,6 +287,7 @@ struct HfTaskCharmHadImpactPar {
258287 yCand,
259288 candidate.phi (),
260289 candidate.impactParameterXY (),
290+ impParZ,
261291 outputMl[0 ],
262292 outputMl[1 ],
263293 outputMl[2 ],
@@ -270,46 +300,71 @@ struct HfTaskCharmHadImpactPar {
270300 phiProngs[2 ],
271301 etaProngs[0 ],
272302 etaProngs[1 ],
273- etaProngs[2 ]);
303+ etaProngs[2 ],
304+ flagMcMatchRec);
274305 }
275306
276307 // / \param candidates are reconstructed candidates
277- template <Channel channel, bool withMl, typename CCands>
308+ template <Channel channel, bool doMc, bool withMl, typename CCands>
278309 void runAnalysis (const CCands& candidates, CollisionsCent const &)
279310 {
280311 for (auto const & candidate : candidates) {
281312 auto collision = candidate.template collision_as <CollisionsCent>();
282- fillSparse<channel, withMl>(candidate);
313+ fillSparse<channel, doMc, withMl>(candidate);
283314 if (fillLightTreeCandidate) {
284- fillTree<channel, withMl>(candidate, collision);
315+ fillTree<channel, doMc, withMl>(candidate, collision);
285316 }
286317 }
287318 }
288319
289320 // process functions
290- void processDplus (CandDplusData const & candidates, CollisionsCent const & collisions)
321+ void processDataDplus (CandDplusData const & candidates, CollisionsCent const & collisions)
322+ {
323+ runAnalysis<Channel::DplusToKPiPi, false , false >(candidates, collisions);
324+ }
325+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDataDplus, " Process Data D+ w/o ML" , false );
326+
327+ void processDataDplusWithMl (CandDplusDataWithMl const & candidates, CollisionsCent const & collisions)
328+ {
329+ runAnalysis<Channel::DplusToKPiPi, false , true >(candidates, collisions);
330+ }
331+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDataDplusWithMl, " Process Data D+ with ML" , true );
332+
333+ void processMCDplus (CandDplusMC const & candidates, CollisionsCent const & collisions)
334+ {
335+ runAnalysis<Channel::DplusToKPiPi, true , false >(candidates, collisions);
336+ }
337+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processMCDplus, " Process MC D+ w/o ML" , false );
338+
339+ void processMCDplusWithMl (CandDplusMCWithMl const & candidates, CollisionsCent const & collisions)
340+ {
341+ runAnalysis<Channel::DplusToKPiPi, true , true >(candidates, collisions);
342+ }
343+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processMCDplusWithMl, " Process MC D+ with ML" , false );
344+
345+ void processDataDzero (CandDzeroData const & candidates, CollisionsCent const & collisions)
291346 {
292- runAnalysis<Channel::DplusToKPiPi , false >(candidates, collisions);
347+ runAnalysis<Channel::DzeroToKPi, false , false >(candidates, collisions);
293348 }
294- PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDplus , " Process D+ w/o ML" , false );
349+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDataDzero , " Process Data D0 w/o ML" , false );
295350
296- void processDplusWithMl (CandDplusDataWithMl const & candidates, CollisionsCent const & collisions)
351+ void processDataDzeroWithMl (CandDzeroDataWithMl const & candidates, CollisionsCent const & collisions)
297352 {
298- runAnalysis<Channel::DplusToKPiPi , true >(candidates, collisions);
353+ runAnalysis<Channel::DzeroToKPi, false , true >(candidates, collisions);
299354 }
300- PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDplusWithMl , " Process D+ with ML" , true );
355+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDataDzeroWithMl , " Process Data D0 with ML" , false );
301356
302- void processDzero (CandDzeroData const & candidates, CollisionsCent const & collisions)
357+ void processMCDzero (CandDzeroMc const & candidates, CollisionsCent const & collisions)
303358 {
304- runAnalysis<Channel::DzeroToKPi, false >(candidates, collisions);
359+ runAnalysis<Channel::DzeroToKPi, true , false >(candidates, collisions);
305360 }
306- PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDzero , " Process D0 w/o ML" , false );
361+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processMCDzero , " Process MC D0 w/o ML" , false );
307362
308- void processDzeroWithMl (CandDzeroDataWithMl const & candidates, CollisionsCent const & collisions)
363+ void processMCDzeroWithMl (CandDzeroMcWithMl const & candidates, CollisionsCent const & collisions)
309364 {
310- runAnalysis<Channel::DzeroToKPi, true >(candidates, collisions);
365+ runAnalysis<Channel::DzeroToKPi, true , true >(candidates, collisions);
311366 }
312- PROCESS_SWITCH (HfTaskCharmHadImpactPar, processDzeroWithMl , " Process D0 with ML" , false );
367+ PROCESS_SWITCH (HfTaskCharmHadImpactPar, processMCDzeroWithMl , " Process MC D0 with ML" , false );
313368};
314369
315370WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments