1313// / \brief Analysis task for charm hadron directed flow
1414// /
1515// / \author Prottay Das, prottay.das@cern.ch
16+ // / \author Biao Zhang, biao.zhanng@cern.ch
1617
1718#include < string>
1819#include < vector>
@@ -40,7 +41,9 @@ using namespace o2::framework::expressions;
4041using namespace o2 ::hf_centrality;
4142using namespace o2 ::hf_evsel;
4243
43- enum DecayChannel { DplusToPiKPi = 0 };
44+ enum DecayChannel { DplusToPiKPi = 0 ,
45+ D0ToPiK,
46+ D0ToKPi };
4447
4548struct HfTaskDirectedFlowCharmHadrons {
4649 Configurable<int > centEstimator{" centEstimator" , 2 , " Centrality estimation (FT0A: 1, FT0C: 2, FT0M: 3, FV0A: 4)" };
@@ -63,10 +66,18 @@ struct HfTaskDirectedFlowCharmHadrons {
6366
6467 using CandDplusDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi, aod::HfMlDplusToPiKPi>>;
6568 using CandDplusData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi>>;
69+ using CandD0DataWMl = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0, aod::HfMlD0>>;
70+ using CandD0Data = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0>>;
6671 using CollsWithQvecs = soa::Join<aod::Collisions, aod::EvSels, aod::CentFV0As, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::SPCalibrationTables>;
6772 using TracksWithExtra = soa::Join<aod::Tracks, aod::TracksExtra>;
6873
6974 Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag;
75+ Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
76+
77+ Partition<CandD0Data> selectedD0ToPiK = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag;
78+ Partition<CandD0Data> selectedD0ToKPi = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
79+ Partition<CandD0DataWMl> selectedD0ToPiKWMl = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag;
80+ Partition<CandD0DataWMl> selectedD0ToKPiWMl = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
7081
7182 SliceCache cache;
7283 HfHelper hfHelper;
@@ -80,7 +91,7 @@ struct HfTaskDirectedFlowCharmHadrons {
8091 {
8192
8293 // / check process functions
83- std::array<int , 2 > processes = {doprocessDplusStd, doprocessDplusMl};
94+ std::array<int , 4 > processes = {doprocessDplusStd, doprocessDplusMl, doprocessD0Std, doprocessD0Ml };
8495 const int nProcesses = std::accumulate (processes.begin (), processes.end (), 0 );
8596 if (nProcesses > 1 ) {
8697 LOGP (fatal, " Only one process function should be enabled at a time, please check your configuration" );
@@ -197,10 +208,29 @@ struct HfTaskDirectedFlowCharmHadrons {
197208 for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++)
198209 outputMl[iclass] = candidate.mlProbDplusToPiKPi ()[classMl->at (iclass)];
199210 }
211+ } else if constexpr (std::is_same_v<T1, CandD0Data> || std::is_same_v<T1, CandD0DataWMl>) {
212+ switch (channel) {
213+ case DecayChannel::D0ToPiK:
214+ massCand = hfHelper.invMassD0ToPiK (candidate);
215+ if constexpr (std::is_same_v<T1, CandD0DataWMl>) {
216+ for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++)
217+ outputMl[iclass] = candidate.mlProbD0 ()[classMl->at (iclass)];
218+ }
219+ break ;
220+ case DecayChannel::D0ToKPi:
221+ massCand = hfHelper.invMassD0barToKPi (candidate);
222+ if constexpr (std::is_same_v<T1, CandD0DataWMl>) {
223+ for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++)
224+ outputMl[iclass] = candidate.mlProbD0bar ()[classMl->at (iclass)];
225+ }
226+ break ;
227+ default :
228+ break ;
229+ }
200230 }
201231
202232 auto trackprong0 = candidate.template prong0_as <Trk>();
203- double sign = trackprong0.sign (); // to differentiate between D+ and D-
233+ double sign = trackprong0.sign (); // electric charge of the first daughter track to differentiate particle and antiparticle
204234
205235 double ptCand = candidate.pt ();
206236 double etaCand = candidate.eta ();
@@ -246,6 +276,28 @@ struct HfTaskDirectedFlowCharmHadrons {
246276 }
247277 }
248278 }
279+ // D0 with ML
280+ void processD0Ml (CollsWithQvecs::iterator const & collision,
281+ TracksWithExtra const & tracks)
282+ {
283+ auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
284+ auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
285+ runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiKWMl, tracks);
286+ runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPiWMl, tracks);
287+ }
288+ PROCESS_SWITCH (HfTaskDirectedFlowCharmHadrons, processD0Ml, " Process D0 candidates with ML" , false );
289+
290+ // D0 with rectangular cuts
291+ void processD0Std (CollsWithQvecs::iterator const & collision,
292+ TracksWithExtra const & tracks)
293+ {
294+ auto candsD0ToPiK = selectedD0ToPiK->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
295+ auto candsD0ToKPi = selectedD0ToKPi->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
296+ runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiK, tracks);
297+ runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPi, tracks);
298+ }
299+ PROCESS_SWITCH (HfTaskDirectedFlowCharmHadrons, processD0Std, " Process D0 candidates with rectangular cuts" , false );
300+
249301 // Dplus with ML
250302 void processDplusMl (CollsWithQvecs::iterator const & collision,
251303 CandDplusDataWMl const & candidatesDplus,
0 commit comments