1919#include " PWGHF/Core/SelectorCuts.h"
2020#include " PWGHF/DataModel/CandidateReconstructionTables.h"
2121#include " PWGHF/DataModel/CandidateSelectionTables.h"
22- #include " PWGHF/Utils/utilsAnalysis.h" // findBin function
22+ #include " PWGHF/Utils/utilsAnalysis.h"
2323
2424#include " Common/Core/TrackSelectorPID.h"
2525
@@ -55,6 +55,15 @@ struct HfCandidateSelectorXicToXiPiPi {
5555 Configurable<float > ptPidTofMax{" ptPidTofMax" , 20 ., " Upper bound of track pT for TOF PID" };
5656 Configurable<float > nSigmaTofMax{" nSigmaTofMax" , 5 ., " Nsigma cut on TOF only" };
5757 Configurable<float > nSigmaTofCombinedMax{" nSigmaTofCombinedMax" , 5 ., " Nsigma cut on TOF combined with TPC" };
58+ // TrackQualitySelection
59+ Configurable<bool > doTrackQualitySelection{" doTrackQualitySelection" , true , " Switch to apply track quality selections on final state daughter particles" };
60+ Configurable<int > nClustersTpcMin{" nClustersTpcMin" , 70 , " Minimum number of TPC clusters requirement" };
61+ Configurable<int > nTpcCrossedRowsMin{" nTpcCrossedRowsMin" , 70 , " Minimum number of TPC crossed rows requirement" };
62+ Configurable<double > tpcCrossedRowsOverFindableClustersRatioMin{" tpcCrossedRowsOverFindableClustersRatioMin" , 0.8 , " Minimum ratio TPC crossed rows over findable clusters requirement" };
63+ Configurable<float > tpcChi2PerClusterMax{" tpcChi2PerClusterMax" , 4 , " Maximum value of chi2 fit over TPC clusters" };
64+ Configurable<int > nClustersItsMin{" nClustersItsMin" , 3 , " Minimum number of ITS clusters requirement for pi <- charm baryon" };
65+ Configurable<int > nClustersItsInnBarrMin{" nClustersItsInnBarrMin" , 1 , " Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon" };
66+ Configurable<float > itsChi2PerClusterMax{" itsChi2PerClusterMax" , 36 , " Maximum value of chi2 fit over ITS clusters for pi <- charm baryon" };
5867 // ML inference
5968 Configurable<bool > applyMl{" applyMl" , false , " Flag to apply ML selections" };
6069 Configurable<std::vector<double >> binsPtMl{" binsPtMl" , std::vector<double >{hf_cuts_ml::vecBinsPt}, " pT bin limits for ML application" };
@@ -84,10 +93,13 @@ struct HfCandidateSelectorXicToXiPiPi {
8493 Chi2SV,
8594 MinDecayLength,
8695 MaxInvMassXiPiPairs,
96+ TpcTrackQualityXiDaughters,
97+ TpcTrackQualityPiFromCharm,
98+ ItsTrackQualityPiFromCharm,
8799 PidSelected,
88100 BdtSelected };
89101
90- using TracksPidWithSel = soa::Join<aod::TracksWExtra, aod::TracksPidPi, aod::TracksPidPr, aod::TrackSelection >;
102+ using TracksExtraWPid = soa::Join<aod::TracksWExtra, aod::TracksPidPi, aod::TracksPidPr>;
91103
92104 HistogramRegistry registry{" registry" };
93105
@@ -111,7 +123,7 @@ struct HfCandidateSelectorXicToXiPiPi {
111123 }
112124
113125 if (fillHistogram) {
114- registry.add (" hSelCandidates" , " ;;entries" , {HistType::kTH1F , {{11 , -0.5 , 10 .5 }}});
126+ registry.add (" hSelCandidates" , " ;;entries" , {HistType::kTH1F , {{15 , -0.5 , 14 .5 }}});
115127 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + All, " All" );
116128 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + Pt, " #it{p}_{T}" );
117129 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + Mass, " #Delta M" );
@@ -122,6 +134,9 @@ struct HfCandidateSelectorXicToXiPiPi {
122134 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + Chi2SV, " #chi^{2}_{SV}" );
123135 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + MinDecayLength, " Decay length" );
124136 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + MaxInvMassXiPiPairs, " M_{#Xi #pi}" );
137+ registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + TpcTrackQualityXiDaughters, " TPC track quality selection on #Xi daughters" );
138+ registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + TpcTrackQualityPiFromCharm, " TPC track quality selection on #pi #leftarrow #Xi_{c}^{+}" );
139+ registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + ItsTrackQualityPiFromCharm, " ITS track quality selection on #pi #leftarrow #Xi_{c}^{+}" );
125140 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + PidSelected, " PID selection" );
126141 registry.get <TH1>(HIST (" hSelCandidates" ))->GetXaxis ()->SetBinLabel (1 + BdtSelected, " BDT selection" );
127142 }
@@ -143,7 +158,12 @@ struct HfCandidateSelectorXicToXiPiPi {
143158 // / \param candidate is candidate
144159 // / \return true if candidate passes all cuts
145160 template <typename T1>
146- bool isSelectedXic (const T1& hfCandXic)
161+ bool isSelectedXic (const T1& hfCandXic,
162+ const float & etaPi0,
163+ const float & etaPi1,
164+ const float & etaPiFromXi,
165+ const float & etaV0PosDau,
166+ const float & etaV0NegDau)
147167 {
148168 auto candpT = hfCandXic.pt ();
149169 int pTBin = findBin (binsPt, candpT);
@@ -178,6 +198,14 @@ struct HfCandidateSelectorXicToXiPiPi {
178198 registry.fill (HIST (" hSelCandidates" ), Eta);
179199 }
180200
201+ // cut on rapidity of final state daughters
202+ if (std::abs (etaPi0) > cuts->get (pTBin, " eta Daughters" ) || std::abs (etaPi1) > cuts->get (pTBin, " eta Daughters" ) || std::abs (etaPiFromXi) > cuts->get (pTBin, " eta Daughters" ) || std::abs (etaV0PosDau) > cuts->get (pTBin, " eta Daughters" ) || std::abs (etaV0NegDau) > cuts->get (pTBin, " eta Daughters" )) {
203+ return false ;
204+ }
205+ if (fillHistogram) {
206+ registry.fill (HIST (" hSelCandidates" ), EtaDaughters);
207+ }
208+
181209 // cut on pion pT
182210 if (hfCandXic.ptProng1 () < cuts->get (pTBin, " pT Pi0" ) || hfCandXic.ptProng2 () < cuts->get (pTBin, " pT Pi1" )) {
183211 return false ;
@@ -241,22 +269,26 @@ struct HfCandidateSelectorXicToXiPiPi {
241269 }
242270
243271 void process (aod::HfCandXic const & hfCandsXic,
244- TracksPidWithSel const &)
272+ TracksExtraWPid const &)
245273 {
246274 for (const auto & hfCandXic : hfCandsXic) {
247275 int statusXicToXiPiPi = 0 ;
248276 if (applyMl) {
249277 outputMlXicToXiPiPi.clear ();
250278 }
251279
252- // get candidate pT
253280 float ptCandXic = hfCandXic.pt ();
281+ auto trackPi0 = hfCandXic.pi0_as <TracksExtraWPid>();
282+ auto trackPi1 = hfCandXic.pi1_as <TracksExtraWPid>();
283+ auto trackPiFromXi = hfCandXic.bachelor_as <TracksExtraWPid>();
284+ auto trackV0PosDau = hfCandXic.posTrack_as <TracksExtraWPid>();
285+ auto trackV0NegDau = hfCandXic.negTrack_as <TracksExtraWPid>();
254286
255287 // No hfflag -> by default skim selected
256288 SETBIT (statusXicToXiPiPi, SelectionStep::RecoSkims); // RecoSkims = 0 --> statusXicToXiPiPi = 1
257289
258290 // kinematic and topological selection
259- if (!isSelectedXic (hfCandXic)) {
291+ if (!isSelectedXic (hfCandXic, trackPi0. eta (), trackPi1. eta (), trackPiFromXi. eta (), trackV0PosDau. eta (), trackV0NegDau. eta () )) {
260292 hfSelXicToXiPiPiCandidate (statusXicToXiPiPi);
261293 if (applyMl) {
262294 hfMlXicToXiPiPiCandidate (outputMlXicToXiPiPi);
@@ -265,6 +297,51 @@ struct HfCandidateSelectorXicToXiPiPi {
265297 }
266298 SETBIT (statusXicToXiPiPi, SelectionStep::RecoTopol); // RecoTopol = 1 --> statusXicToXiPiPi = 3
267299
300+ // track quality selection
301+ if (doTrackQualitySelection) {
302+ if (!isSelectedTrackTpcQuality (trackPiFromXi, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) ||
303+ !isSelectedTrackTpcQuality (trackV0PosDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) ||
304+ !isSelectedTrackTpcQuality (trackV0NegDau, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) {
305+ hfSelXicToXiPiPiCandidate (statusXicToXiPiPi);
306+ if (applyMl) {
307+ hfMlXicToXiPiPiCandidate (outputMlXicToXiPiPi);
308+ }
309+ continue ;
310+ }
311+ if (fillHistogram) {
312+ registry.fill (HIST (" hSelCandidates" ), TpcTrackQualityXiDaughters);
313+ }
314+
315+ if (!isSelectedTrackTpcQuality (trackPi0, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax) ||
316+ !isSelectedTrackTpcQuality (trackPi1, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) {
317+ hfSelXicToXiPiPiCandidate (statusXicToXiPiPi);
318+ if (applyMl) {
319+ hfMlXicToXiPiPiCandidate (outputMlXicToXiPiPi);
320+ }
321+ continue ;
322+ }
323+ if (fillHistogram) {
324+ registry.fill (HIST (" hSelCandidates" ), TpcTrackQualityPiFromCharm);
325+ }
326+
327+ if ((!isSelectedTrackItsQuality (trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel () < nClustersItsInnBarrMin) ||
328+ (!isSelectedTrackItsQuality (trackPi0, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel () < nClustersItsInnBarrMin)) {
329+ hfSelXicToXiPiPiCandidate (statusXicToXiPiPi);
330+ if (applyMl) {
331+ hfMlXicToXiPiPiCandidate (outputMlXicToXiPiPi);
332+ }
333+ continue ;
334+ }
335+ if (fillHistogram) {
336+ registry.fill (HIST (" hSelCandidates" ), ItsTrackQualityPiFromCharm);
337+ }
338+ }
339+ if (!doTrackQualitySelection && fillHistogram) {
340+ registry.fill (HIST (" hSelCandidates" ), TpcTrackQualityXiDaughters);
341+ registry.fill (HIST (" hSelCandidates" ), TpcTrackQualityPiFromCharm);
342+ registry.fill (HIST (" hSelCandidates" ), ItsTrackQualityPiFromCharm);
343+ }
344+
268345 // track-level PID selection
269346 if (usePid) {
270347 TrackSelectorPID::Status statusPidPi0 = TrackSelectorPID::NotApplicable;
@@ -273,11 +350,6 @@ struct HfCandidateSelectorXicToXiPiPi {
273350 TrackSelectorPID::Status statusPidPrLam = TrackSelectorPID::NotApplicable;
274351 TrackSelectorPID::Status statusPidPiLam = TrackSelectorPID::NotApplicable;
275352
276- auto trackPi0 = hfCandXic.pi0_as <TracksPidWithSel>();
277- auto trackPi1 = hfCandXic.pi1_as <TracksPidWithSel>();
278- auto trackV0PosDau = hfCandXic.posTrack_as <TracksPidWithSel>();
279- auto trackV0NegDau = hfCandXic.negTrack_as <TracksPidWithSel>();
280- auto trackPiFromXi = hfCandXic.bachelor_as <TracksPidWithSel>();
281353 // assign proton and pion hypothesis to V0 daughters
282354 auto trackPr = trackV0PosDau;
283355 auto trackPiFromLam = trackV0NegDau;
0 commit comments