@@ -109,8 +109,7 @@ struct HfTaskPtFlucCharmHadrons {
109109
110110 Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag;
111111 Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
112- Filter filterSelectTracks = (nabs(aod::track::eta) < etaTrkMax) && (aod::track::pt > ptTrkMin) && (aod::track::pt < ptTrkMax) && (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (aod::track::itsNCls >= cfgITScluster) && (aod::track::itsNClsInnerBarrel >= cfgITSbarrel) && (aod::track::tpcNClsFound >= cfgTPCcluster);
113-
112+ Filter filterSelectTracks = (nabs(aod::track::eta) < etaTrkMax) && (aod::track::pt > ptTrkMin) && (aod::track::pt < ptTrkMax) && (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz);
114113 Partition<CandD0DataWMl> selectedD0ToPiKWMl = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag;
115114 Partition<CandD0DataWMl> selectedD0ToKPiWMl = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
116115
@@ -156,6 +155,8 @@ struct HfTaskPtFlucCharmHadrons {
156155 const AxisSpec aMPtTrkB{axisMPtTrkB, " Mean pT of tracks in subevent B (GeV/#it{c})" };
157156 const AxisSpec aPtCandProduct{axisPtCandProduct, " #it{p}_{T}^{cand} * <#it{p}_{T}>^{trks} (GeV^{2}/#it{c}^{2})" };
158157 const AxisSpec aPtTrkProduct{axisPtTrkProduct, " #it{p}_{T}^{trks}(A) * #it{p}_{T}^{trks}(B) (GeV^{2}/#it{c}^{2})" };
158+ const AxisSpec aNTrkA{axisNTrkA, " N_{tracks} in subevent A" };
159+ const AxisSpec aNTrkB{axisNTrkB, " N_{tracks} in subevent B" };
159160
160161 // Event-level accumulators (charged hadrons only!)
161162 registry.add (" hEvents" , " events vs cent" , HistType::kTH1F , {aCent}, true );
@@ -180,6 +181,8 @@ struct HfTaskPtFlucCharmHadrons {
180181 registry.add (" hMeanPtTrkAllColls" , " Mean pT of charged hadrons for all collisions" , HistType::kTHnSparseF , {aCent, aMPtTrkA, aMPtTrkB, aPtTrkProduct, aNTrkA, aNTrkB}, true );
181182 }
182183
184+ hfEvSel.addHistograms (registry); // collision monitoring
185+
183186 ccdb->setURL (ccdbUrl);
184187 ccdb->setCaching (true );
185188 ccdb->setLocalObjectValidityChecking ();
@@ -188,43 +191,44 @@ struct HfTaskPtFlucCharmHadrons {
188191 // ---------------------------------------------------------------------------
189192 // Helper functions
190193 // ---------------------------------------------------------------------------
191- // / Get the centrality
192- // / \param collision is the collision with the centrality information
193- double getCentrality (Colls::iterator const & collision)
194+ // / Check event selections for collision and fill event selection histograms, and revalculate centrality
195+ // / \param collision is the collision
196+ template <typename Coll>
197+ bool isSelectedHfCollision (Coll const & collision, float & cent)
194198 {
195- double cent = - 999 . ;
196- switch (centEstimator) {
197- case CentralityEstimator::FV0A:
198- cent = collision. centFV0A ( );
199- break ;
200- case CentralityEstimator::FT0M:
201- cent = collision. centFT0M ( );
202- break ;
203- case CentralityEstimator::FT0A:
204- cent = collision. centFT0A ( );
205- break ;
206- case CentralityEstimator::FT0C:
207- cent = collision. centFT0C ( );
208- break ;
209- default :
210- LOG (warning ) << " Centrality estimator not valid. Possible values are V0A, T0M, T0A, T0C. Fallback to V0A " ;
211- cent = collision. centFV0A ();
212- break ;
213- }
214- return cent ;
199+ o2::hf_evsel::HfCollisionRejectionMask collRejMask{} ;
200+ if (centEstimator == CentralityEstimator::FT0A)
201+ {
202+ collRejMask = hfEvSel. getHfCollisionRejectionMask < true , CentralityEstimator::FT0A, aod::BCsWithTimestamps>(collision, cent, ccdb, registry );
203+ } else if (centEstimator == CentralityEstimator::FT0C)
204+ {
205+ collRejMask = hfEvSel. getHfCollisionRejectionMask < true , CentralityEstimator::FT0C, aod::BCsWithTimestamps>(collision, cent, ccdb, registry );
206+ } else if (centEstimator == CentralityEstimator::FT0M)
207+ {
208+ collRejMask = hfEvSel. getHfCollisionRejectionMask < true , CentralityEstimator::FT0M, aod::BCsWithTimestamps>(collision, cent, ccdb, registry );
209+ } else if (centEstimator == CentralityEstimator::FV0A)
210+ {
211+ collRejMask = hfEvSel. getHfCollisionRejectionMask < true , CentralityEstimator::FV0A, aod::BCsWithTimestamps>(collision, cent, ccdb, registry );
212+ } else
213+ {
214+ LOG (fatal ) << " Centrality estimator not recognized for collision selection " ;
215+ std::abort ();
216+ }
217+ hfEvSel. fillHistograms (collision, collRejMask, cent);
218+ return collRejMask == 0 ;
215219 }
216220
217221 // / Get candidate mass
218222 template <typename CandT, typename Trk>
219223 std::pair<float , float > getCandMassAndSign (const CandT& cand, DecayChannel channel, Trk const & /* tracks*/ )
220224 {
221225 if constexpr (std::is_same_v<CandT, CandDplusDataWMl>) {
222- return {HfHelper::invMassDplusToPiKPi (cand), cand.prong0_as <Trk>().sign ()};
223- } else if constexpr (std::is_same_v<CandT, CandD0DataWMl::value_type >) {
226+ return {HfHelper::invMassDplusToPiKPi (cand), cand.template prong0_as <Trk>().sign ()};
227+ } else if constexpr (std::is_same_v<CandT, CandD0DataWMl>) {
224228 if (channel == DecayChannel::D0ToPiK) {
225- return {HfHelper::invMassD0ToPiK (cand), candidate .isSelD0bar () ? 3 : 1 }; // 3: reflected D0bar, 1: pure D0 excluding reflected D0bar
229+ return {HfHelper::invMassD0ToPiK (cand), cand .isSelD0bar () ? 3 : 1 }; // 3: reflected D0bar, 1: pure D0 excluding reflected D0bar
226230 } else if (channel == DecayChannel::D0ToKPi) {
227- return {HfHelper::invMassD0barToKPi (cand), candidate .isSelD0 () ? 3 : 2 }; // 3: reflected D0, 2: pure D0bar excluding reflected D0
231+ return {HfHelper::invMassD0barToKPi (cand), cand .isSelD0 () ? 3 : 2 }; // 3: reflected D0, 2: pure D0bar excluding reflected D0
228232 }
229233 }
230234 return {0 ., 0 .}; // default return value for unsupported types
@@ -233,30 +237,31 @@ struct HfTaskPtFlucCharmHadrons {
233237 template <typename T>
234238 bool selectionTrack (const T& track) const
235239 {
236- if (!(track.isGlobalTrack () && track.isPVContributor ())) {
240+ if (!(track.isGlobalTrack () && track.isPVContributor () && track. itsNCls () > cfgITScluster. value && track. tpcNClsFound () > cfgTPCcluster. value && track. itsNClsInnerBarrel () >= cfgITSbarrel. value )) {
237241 return false ;
238242 }
239243 return true ;
240244 }
241245
242246 // / remove candidate daughters from the mean pT of tracks in A and B (if they are in the respective subevent)
243- template <DecayChannel Channel, typename TrkType, typename Cand >
244- float removeDaughtersFromMeanPt (const Cand & cand, float & meanPt, int & n, const std::vector<int >& trkIDs)
247+ template <DecayChannel Channel, typename CandT >
248+ float removeDaughtersFromMeanPt (const CandT & cand, const float & rawMeanPt, const int & n, const std::vector<int >& trkIDs)
245249 {
250+ float meanPt{0 .f };
246251 if constexpr (Channel == DecayChannel::DplusToPiKPi) {
252+ std::array<int , 3 > daugIDs = {cand.prong0Id (), cand.prong1Id (), cand.prong2Id ()};
253+ std::array<float , 3 > daugPts = {cand.ptProng0 (), cand.ptProng1 (), cand.ptProng2 ()};
247254 for (int iProng = 0 ; iProng < 3 ; ++iProng) { // for 3-prong
248- int trkID = cand.template prong_as <TrkType>(iProng).globalIndex ();
249- float ptDaughter = cand.template prong_as <TrkType>(iProng).pt ();
250- if (std::find (trkIDs.begin (), trkIDs.end (), trkID) != trkIDs.end ()) {
251- meanPt = (meanPt * n - ptDaughter) / (n - 1 );
255+ if (std::find (trkIDs.begin (), trkIDs.end (), daugIDs[iProng]) != trkIDs.end ()) {
256+ meanPt = (rawMeanPt * n - daugPts[iProng]) / (n - 1 );
252257 }
253258 }
254259 } else if constexpr (Channel == DecayChannel::D0ToPiK || Channel == DecayChannel::D0ToKPi) {
260+ std::array<int , 2 > daugIDs = {cand.prong0Id (), cand.prong1Id ()};
261+ std::array<float , 2 > daugPts = {cand.ptProng0 (), cand.ptProng1 ()};
255262 for (int iProng = 0 ; iProng < 2 ; ++iProng) { // for 2-prong
256- int trkID = cand.template prong_as <TrkType>(iProng).globalIndex ();
257- float ptDaughter = cand.template prong_as <TrkType>(iProng).pt ();
258- if (std::find (trkIDs.begin (), trkIDs.end (), trkID) != trkIDs.end ()) {
259- meanPt = (meanPt * n - ptDaughter) / (n - 1 );
263+ if (std::find (trkIDs.begin (), trkIDs.end (), daugIDs[iProng]) != trkIDs.end ()) {
264+ meanPt = (rawMeanPt * n - daugPts[iProng]) / (n - 1 );
260265 }
261266 }
262267 }
@@ -338,16 +343,17 @@ struct HfTaskPtFlucCharmHadrons {
338343 ml2 >= mlTwoMin.value && ml2 < mlTwoMax.value );
339344 }
340345
341- // / Compute the scalar product
342- // / \param collision is the collision with the Q vector information and event plane
343- // / \param candidates are the selected candidates
346+ // / Compute the mean pT of the event using charged tracks in two eta-separated subevents, and correlate with D candidates
347+ // / \param collision is the collision with centrality and event selection
348+ // / \param candidates are the D candidates to correlate with the mean pT of the event
349+ // / \param tracks are the tracks used to compute the mean pT of the event
344350 template <DecayChannel Channel, typename T1, typename Trk>
345351 void runPtFlucAnalysis (Colls::iterator const & collision,
346352 T1 const & candidates,
347353 Trk const & tracks)
348354 {
349- float cent = getCentrality (collision) ;
350- if (cent < centralityMin || cent > centralityMax ) {
355+ float cent{ 0 . f } ;
356+ if (! isSelectedHfCollision (collision, cent) ) {
351357 return ;
352358 }
353359
@@ -397,24 +403,26 @@ struct HfTaskPtFlucCharmHadrons {
397403
398404 // remove the daughters from the mean pT of tracks and calculate pt product
399405 float eta = cand.eta ();
406+ float pt = cand.pt ();
407+
400408 float candPtProduct{0 .f };
401409 float meanPtA{0 .f };
402410 float meanPtB{0 .f };
403411 if (eta > etaAMin.value && eta < etaAMax.value ) {
404- meanPtB = removeDaughtersFromMeanPt<Channel, Trk >(cand, RawMeanPtB, nB, trkIDB);
412+ meanPtB = removeDaughtersFromMeanPt<Channel, decltype (cand) >(cand, RawMeanPtB, nB, trkIDB);
405413 meanPtA = RawMeanPtA; // no need to remove daughters from A if candidate is in A
406- candPtProduct = cand. pt () * meanPtB;
414+ candPtProduct = pt * meanPtB;
407415 } else if (eta > etaBMin.value && eta < etaBMax.value ) {
408- meanPtA = removeDaughtersFromMeanPt<Channel, Trk >(cand, RawMeanPtA, nA, trkIDA);
416+ meanPtA = removeDaughtersFromMeanPt<Channel, decltype (cand) >(cand, RawMeanPtA, nA, trkIDA);
409417 meanPtB = RawMeanPtB; // no need to remove daughters from B if candidate is in B
410- candPtProduct = cand. pt () * meanPtA;
418+ candPtProduct = pt * meanPtA;
411419 }
412420
413421 // get candidate mass and sign
414422 auto [invMass, sign] = getCandMassAndSign (cand, Channel, tracks);
415423
416424 // fill charm-bulk correlation thnsparse
417- registry.fill (HIST (" hCharmBulkCorrelations" ), invMass, cent, cand. pt () , sign, ml1, ml2, eta, meanPtA, meanPtB, candPtProduct);
425+ registry.fill (HIST (" hCharmBulkCorrelations" ), invMass, cent, pt , sign, ml1, ml2, eta, meanPtA, meanPtB, candPtProduct);
418426 }
419427 } else
420428 {
0 commit comments