@@ -38,13 +38,15 @@ enum Selections : uint8_t {
3838 NoSel = 0 ,
3939 DSel,
4040 V0Sel,
41+ TrackSel,
4142 NSelSteps
4243};
4344enum DecayChannel : uint8_t {
4445 Ds1ToDstarK0s = 0 ,
4546 Ds2StarToDplusK0s,
4647 XcToDplusLambda,
47- LambdaDminus
48+ LambdaDminus,
49+ DstarTrack
4850};
4951enum V0Type : uint8_t {
5052 K0s = 0 ,
@@ -67,6 +69,7 @@ auto vecBinsPt = std::vector<double>{binsPt, binsPt + nBinsPt + 1};
6769struct HfCandidateCreatorCharmResoReduced {
6870 // Produces: Tables with resonance info
6971 Produces<aod::HfCandCharmReso> rowCandidateReso;
72+ Produces<aod::HfCandChaResTr> rowCandidateResoTrack;
7073 // Optional daughter ML scores table
7174 Produces<aod::HfCharmResoMLs> mlScores;
7275
@@ -89,11 +92,13 @@ struct HfCandidateCreatorCharmResoReduced {
8992 Partition<aod::HfRedVzeros> candidatesLambda = aod::hf_reso_v0::v0Type == (uint8_t )2 || aod::hf_reso_v0::v0Type == (uint8_t )4 ;
9093
9194 Preslice<aod::HfRedVzeros> candsV0PerCollision = aod::hf_track_index_reduced::hfRedCollisionId;
95+ Preslice<aod::HfRedTracks> candsTrackPerCollision = aod::hf_track_index_reduced::hfRedCollisionId;
9296 Preslice<aod::HfRed3PrNoTrks> candsDPerCollision = hf_track_index_reduced::hfRedCollisionId;
9397
9498 // Useful constants
9599 double massK0{0 .};
96100 double massLambda{0 .};
101+ double massProton{0 .};
97102 double massDplus{0 .};
98103 double massDstar{0 .};
99104 double massD0{0 .};
@@ -103,7 +108,7 @@ struct HfCandidateCreatorCharmResoReduced {
103108 void init (InitContext const &)
104109 {
105110 // check that only one process function is enabled
106- std::array<bool , 8 > doprocess{doprocessDs2StarToDplusK0s, doprocessDs2StarToDplusK0sWithMl, doprocessDs1ToDstarK0s, doprocessDs1ToDstarK0sWithMl, doprocessXcToDplusLambda, doprocessXcToDplusLambdaWithMl, doprocessLambdaDminus, doprocessLambdaDminusWithMl};
111+ std::array<bool , 10 > doprocess{doprocessDs2StarToDplusK0s, doprocessDs2StarToDplusK0sWithMl, doprocessDs1ToDstarK0s, doprocessDs1ToDstarK0sWithMl, doprocessXcToDplusLambda, doprocessXcToDplusLambdaWithMl, doprocessLambdaDminus, doprocessLambdaDminusWithMl, doprocessDstarTrack, doprocessDstarTrackWithMl };
107112 if ((std::accumulate (doprocess.begin (), doprocess.end (), 0 )) != 1 ) {
108113 LOGP (fatal, " Only one process function should be enabled! Please check your configuration!" );
109114 }
@@ -113,12 +118,15 @@ struct HfCandidateCreatorCharmResoReduced {
113118 registry.add (" hMassDs2Star" , " Ds^{*}2 candidates; m_Ds^{*}2 (GeV/#it{c}^{2}) ;entries" , {HistType::kTH2F , {{100 , 2.4 , 2.7 }, {(std::vector<double >)binsPt, " #it{p}_{T} (GeV/#it{c})" }}});
114119 registry.add (" hMassXcRes" , " XcRes candidates; m_XcRes (GeV/#it{c}^{2}) ;entries" , {HistType::kTH2F , {{100 , 2.9 , 3.3 }, {(std::vector<double >)binsPt, " #it{p}_{T} (GeV/#it{c})" }}});
115120 registry.add (" hMassLambdaDminus" , " LambdaDminus candidates; m_LambdaDminus (GeV/#it{c}^{2}) ;entries" , {HistType::kTH2F , {{100 , 2.9 , 3.3 }, {(std::vector<double >)binsPt, " #it{p}_{T} (GeV/#it{c})" }}});
121+ registry.add (" hMassDstarTrack" , " DstarTrack candidates; m_DstarTrack (GeV/#it{c}^{2}) ;entries" , {HistType::kTH2F , {{100 , 0.9 , 1.4 }, {(std::vector<double >)binsPt, " #it{p}_{T} (GeV/#it{c})" }}});
122+
116123 if (activateQA) {
117124 constexpr int kNBinsSelections = Selections::NSelSteps;
118125 std::string labels[kNBinsSelections ];
119126 labels[Selections::NoSel] = " No selection" ;
120127 labels[Selections::DSel] = " D Candidates Selection" ;
121128 labels[Selections::V0Sel] = " D & V0 candidate Selection" ;
129+ labels[Selections::TrackSel] = " D & Track candidate Selection" ;
122130 static const AxisSpec axisSelections = {kNBinsSelections , 0.5 , kNBinsSelections + 0.5 , " " };
123131 registry.add (" hSelections" , " Selections" , {HistType::kTH1F , {axisSelections}});
124132 for (int iBin = 0 ; iBin < kNBinsSelections ; ++iBin) {
@@ -128,6 +136,7 @@ struct HfCandidateCreatorCharmResoReduced {
128136 // mass constants
129137 massK0 = o2::constants::physics::MassK0Short;
130138 massLambda = o2::constants::physics::MassLambda;
139+ massProton = o2::constants::physics::MassProton;
131140 massDplus = o2::constants::physics::MassDPlus;
132141 massDstar = o2::constants::physics::MassDStar;
133142 massD0 = o2::constants::physics::MassD0;
@@ -147,7 +156,7 @@ struct HfCandidateCreatorCharmResoReduced {
147156 // slection on D candidate mass
148157 if (channel == DecayChannel::Ds2StarToDplusK0s || channel == DecayChannel::XcToDplusLambda || channel == DecayChannel::LambdaDminus) {
149158 invMassD = candD.invMassDplus ();
150- } else if (channel == DecayChannel::Ds1ToDstarK0s) {
159+ } else if (channel == DecayChannel::Ds1ToDstarK0s || channel == DecayChannel::DstarTrack ) {
151160 if (candD.dType () > 0 )
152161 invMassD = candD.invMassDstar ();
153162 else
@@ -169,7 +178,7 @@ struct HfCandidateCreatorCharmResoReduced {
169178 return true ;
170179 }
171180
172- // / Basic selection of V0 candidates
181+ // / Basic selection of V0 and track candidates
173182 // / \param candV0 is the reduced V0 candidate
174183 // / \param candD is the reduced D meson candidate
175184 // / \return true if selections are passed
@@ -215,10 +224,10 @@ struct HfCandidateCreatorCharmResoReduced {
215224 return true ;
216225 }
217226
218- template <bool fillMl, DecayChannel channel, typename Coll, typename DRedTable, typename V0RedTable >
227+ template <bool fillMl, DecayChannel channel, typename Coll, typename DRedTable, typename V0TrRedTable >
219228 void runCandidateCreation (Coll const & collision,
220229 DRedTable const & candsD,
221- V0RedTable const & candsV0 )
230+ V0TrRedTable const & candsV0Tr )
222231 {
223232 // loop on D candidates
224233 for (const auto & candD : candsD) {
@@ -242,71 +251,92 @@ struct HfCandidateCreatorCharmResoReduced {
242251 std::array<float , 3 > pVecD = {candD.px (), candD.py (), candD.pz ()};
243252 std::array<int , 3 > dDaughtersIds = {candD.prong0Id (), candD.prong1Id (), candD.prong2Id ()};
244253
245- // loop on V0 candidates
254+ // loop on V0 or track candidates
246255 bool alreadyCounted{false };
247- for (const auto & candV0 : candsV0 ) {
256+ for (const auto & candV0Tr : candsV0Tr ) {
248257 if (rejectDV0PairsWithCommonDaughter) {
249258 const std::array<int , 3 > dDaughtersIDs = {candD.prong0Id (), candD.prong1Id (), candD.prong2Id ()};
250- if (std::find (dDaughtersIDs.begin (), dDaughtersIDs.end (), candV0.prong0Id ()) != dDaughtersIDs.end () || std::find (dDaughtersIDs.begin (), dDaughtersIDs.end (), candV0.prong1Id ()) != dDaughtersIDs.end ()) {
259+ if constexpr (channel == DecayChannel::DstarTrack) {
260+ if (std::find (dDaughtersIDs.begin (), dDaughtersIDs.end (), candV0Tr.globalIndex ()) != dDaughtersIDs.end ()) {
261+ continue ;
262+ }
263+ } else {
264+ if (std::find (dDaughtersIDs.begin (), dDaughtersIDs.end (), candV0Tr.prong0Id ()) != dDaughtersIDs.end () || std::find (dDaughtersIDs.begin (), dDaughtersIDs.end (), candV0Tr.prong1Id ()) != dDaughtersIDs.end ()) {
265+ continue ;
266+ }
267+ }
268+ }
269+ if constexpr (channel != DecayChannel::DstarTrack) {
270+ if (!isV0Selected<channel>(candV0Tr, candD)) {
251271 continue ;
252272 }
273+ if (activateQA && !alreadyCounted) {
274+ registry.fill (HIST (" hSelections" ), 1 + Selections::V0Sel);
275+ alreadyCounted = true ;
276+ }
253277 }
254278
255- if (!isV0Selected<channel>(candV0, candD)) {
256- continue ;
257- }
258- if (activateQA && !alreadyCounted) {
259- registry.fill (HIST (" hSelections" ), 1 + Selections::V0Sel);
260- alreadyCounted = true ;
261- }
262279 float invMassReso{0 .};
263280 float invMassV0{0 .};
264- std::array<float , 3 > pVecV0 = {candV0.px (), candV0.py (), candV0.pz ()};
265- float ptReso = RecoDecay::pt (RecoDecay::sumOfVec (pVecV0, pVecD));
266- switch (channel) {
267- case DecayChannel::Ds1ToDstarK0s:
268- invMassV0 = candV0.invMassK0s ();
269- invMassReso = RecoDecay::m (std::array{pVecD, pVecV0}, std::array{massDstar, massK0});
270- registry.fill (HIST (" hMassDs1" ), invMassReso, ptReso);
271- break ;
272- case DecayChannel::Ds2StarToDplusK0s:
273- invMassV0 = candV0.invMassK0s ();
274- invMassReso = RecoDecay::m (std::array{pVecD, pVecV0}, std::array{massDplus, massK0});
275- registry.fill (HIST (" hMassDs2Star" ), invMassReso, ptReso);
276- break ;
277- case DecayChannel::XcToDplusLambda:
278- if (candD.dType () > 0 ) {
279- invMassV0 = candV0.invMassLambda ();
280- } else {
281- invMassV0 = candV0.invMassAntiLambda ();
282- }
283- invMassReso = RecoDecay::m (std::array{pVecD, pVecV0}, std::array{massDplus, massLambda});
284- registry.fill (HIST (" hMassXcRes" ), invMassReso, ptReso);
285- break ;
286- case DecayChannel::LambdaDminus:
287- if (candD.dType () < 0 ) {
288- invMassV0 = candV0.invMassLambda ();
289- } else {
290- invMassV0 = candV0.invMassAntiLambda ();
291- }
292- invMassReso = RecoDecay::m (std::array{pVecD, pVecV0}, std::array{massDplus, massLambda});
293- registry.fill (HIST (" hMassLambdaDminus" ), invMassReso, ptReso);
294- break ;
295- default :
296- break ;
281+ std::array<float , 3 > pVecV0Tr = {candV0Tr.px (), candV0Tr.py (), candV0Tr.pz ()};
282+ float ptReso = RecoDecay::pt (RecoDecay::sumOfVec (pVecV0Tr, pVecD));
283+
284+ if constexpr (channel == DecayChannel::DstarTrack) {
285+ invMassReso = RecoDecay::m (std::array{pVecD, pVecV0Tr}, std::array{massDstar, massProton});
286+ registry.fill (HIST (" hMassDstarTrack" ), invMassReso, ptReso);
287+ } else {
288+ switch (channel) {
289+ case DecayChannel::Ds1ToDstarK0s:
290+ invMassV0 = candV0Tr.invMassK0s ();
291+ invMassReso = RecoDecay::m (std::array{pVecD, pVecV0Tr}, std::array{massDstar, massK0});
292+ registry.fill (HIST (" hMassDs1" ), invMassReso, ptReso);
293+ break ;
294+ case DecayChannel::Ds2StarToDplusK0s:
295+ invMassV0 = candV0Tr.invMassK0s ();
296+ invMassReso = RecoDecay::m (std::array{pVecD, pVecV0Tr}, std::array{massDplus, massK0});
297+ registry.fill (HIST (" hMassDs2Star" ), invMassReso, ptReso);
298+ break ;
299+ case DecayChannel::XcToDplusLambda:
300+ if (candD.dType () > 0 ) {
301+ invMassV0 = candV0Tr.invMassLambda ();
302+ } else {
303+ invMassV0 = candV0Tr.invMassAntiLambda ();
304+ }
305+ invMassReso = RecoDecay::m (std::array{pVecD, pVecV0Tr}, std::array{massDplus, massLambda});
306+ registry.fill (HIST (" hMassXcRes" ), invMassReso, ptReso);
307+ break ;
308+ case DecayChannel::LambdaDminus:
309+ if (candD.dType () < 0 ) {
310+ invMassV0 = candV0Tr.invMassLambda ();
311+ } else {
312+ invMassV0 = candV0Tr.invMassAntiLambda ();
313+ }
314+ invMassReso = RecoDecay::m (std::array{pVecD, pVecV0Tr}, std::array{massDplus, massLambda});
315+ registry.fill (HIST (" hMassLambdaDminus" ), invMassReso, ptReso);
316+ break ;
317+ default :
318+ break ;
319+ }
297320 }
298321 // Filling Output table
299- rowCandidateReso (collision.globalIndex (),
300- candD.globalIndex (),
301- candV0.globalIndex (),
302- pVecD[0 ], pVecD[1 ], pVecD[2 ],
303- pVecV0[0 ], pVecV0[1 ], pVecV0[2 ],
304- invMassReso,
305- invMassD,
306- invMassV0,
307- candV0.cpa (),
308- candV0.dca (),
309- candV0.v0Radius ());
322+ if constexpr (channel == DecayChannel::DstarTrack) {
323+ rowCandidateResoTrack (pVecD[0 ], pVecD[1 ], pVecD[2 ],
324+ candV0Tr.px (), candV0Tr.py (), candV0Tr.pz (),
325+ invMassReso,
326+ invMassD);
327+ } else {
328+ rowCandidateReso (collision.globalIndex (),
329+ candD.globalIndex (),
330+ candV0Tr.globalIndex (),
331+ pVecD[0 ], pVecD[1 ], pVecD[2 ],
332+ pVecV0Tr[0 ], pVecV0Tr[1 ], pVecV0Tr[2 ],
333+ invMassReso,
334+ invMassD,
335+ invMassV0,
336+ candV0Tr.cpa (),
337+ candV0Tr.dca (),
338+ candV0Tr.v0Radius ());
339+ }
310340 if constexpr (fillMl) {
311341 mlScores (candD.mlScoreBkgMassHypo0 (), candD.mlScorePromptMassHypo0 (), candD.mlScoreNonpromptMassHypo0 ());
312342 }
@@ -417,6 +447,32 @@ struct HfCandidateCreatorCharmResoReduced {
417447 }
418448 }
419449 PROCESS_SWITCH (HfCandidateCreatorCharmResoReduced, processLambdaDminusWithMl, " Process LambdaDminus candidates with Ml info" , false );
450+ void processDstarTrack (aod::HfRedCollisions const & collisions,
451+ aod::HfRed3PrNoTrks const & candsD,
452+ soa::Join<aod::HfRedTrackBases, aod::HfRedTracksCov> const & candidatesTrack)
453+ {
454+ for (const auto & collision : collisions) {
455+ auto thisCollId = collision.globalIndex ();
456+ auto candsDThisColl = candsD.sliceBy (candsDPerCollision, thisCollId);
457+ auto trackThisColl = candidatesTrack.sliceBy (candsTrackPerCollision, thisCollId);
458+ runCandidateCreation<false , DecayChannel::DstarTrack>(collision, candsDThisColl, trackThisColl);
459+ }
460+ }
461+ PROCESS_SWITCH (HfCandidateCreatorCharmResoReduced, processDstarTrack, " Process DStar candidates without Ml info" , false );
462+
463+ void processDstarTrackWithMl (aod::HfRedCollisions const & collisions,
464+ soa::Join<aod::HfRed3PrNoTrks, aod::HfRed3ProngsMl> const & candsD,
465+ soa::Join<aod::HfRedTrackBases, aod::HfRedTracksCov> const & candidatesTrack)
466+ // aod::HfRedTracks const&)
467+ {
468+ for (const auto & collision : collisions) {
469+ auto thisCollId = collision.globalIndex ();
470+ auto candsDThisColl = candsD.sliceBy (candsDPerCollision, thisCollId);
471+ auto trackThisColl = candidatesTrack.sliceBy (candsTrackPerCollision, thisCollId);
472+ runCandidateCreation<true , DecayChannel::DstarTrack>(collision, candsDThisColl, trackThisColl);
473+ }
474+ }
475+ PROCESS_SWITCH (HfCandidateCreatorCharmResoReduced, processDstarTrackWithMl, " Process DStar candidates with Ml info" , false );
420476
421477}; // struct
422478
0 commit comments