@@ -48,7 +48,8 @@ enum DecayChannel { DplusToPiKPi = 0,
4848 LcToPKPi,
4949 LcToPiKP,
5050 XicToPKPi,
51- XicToPiKP
51+ XicToPiKP,
52+ Xic0ToXiPi
5253};
5354
5455enum QvecEstimator { FV0A = 0 ,
@@ -75,25 +76,11 @@ struct HfTaskFlowCharmHadrons {
7576 Configurable<std::string> ccdbUrl{" ccdbUrl" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
7677 Configurable<std::vector<int >> classMl{" classMl" , {0 , 2 }, " Indexes of BDT scores to be stored. Two indexes max." };
7778
78- ConfigurableAxis thnConfigAxisInvMass{" thnConfigAxisInvMass" , {100 , 1.78 , 2.05 }, " " };
79- ConfigurableAxis thnConfigAxisPt{" thnConfigAxisPt" , {10 , 0 ., 10 .}, " " };
80- ConfigurableAxis thnConfigAxisCent{" thnConfigAxisCent" , {10000 , 0 ., 100 .}, " " };
81- ConfigurableAxis thnConfigAxisCosNPhi{" thnConfigAxisCosNPhi" , {100 , -1 ., 1 .}, " " };
82- ConfigurableAxis thnConfigAxisPsi{" thnConfigAxisPsi" , {6000 , 2 . * TMath::Pi (), 2 . * TMath::Pi ()}, " " };
83- ConfigurableAxis thnConfigAxisCosDeltaPhi{" thnConfigAxisCosDeltaPhi" , {100 , -1 ., 1 .}, " " };
84- ConfigurableAxis thnConfigAxisScalarProd{" thnConfigAxisScalarProd" , {100 , 0 ., 1 .}, " " };
85- ConfigurableAxis thnConfigAxisMlOne{" thnConfigAxisMlOne" , {1000 , 0 ., 1 .}, " " };
86- ConfigurableAxis thnConfigAxisMlTwo{" thnConfigAxisMlTwo" , {1000 , 0 ., 1 .}, " " };
87- ConfigurableAxis thnConfigAxisOccupancyITS{" thnConfigAxisOccupancyITS" , {14 , 0 , 14000 }, " " };
88- ConfigurableAxis thnConfigAxisOccupancyFT0C{" thnConfigAxisOccupancyFT0C" , {14 , 0 , 140000 }, " " };
89- ConfigurableAxis thnConfigAxisNoSameBunchPileup{" thnConfigAxisNoSameBunchPileup" , {2 , 0 , 2 }, " " };
90- ConfigurableAxis thnConfigAxisOccupancy{" thnConfigAxisOccupancy" , {2 , 0 , 2 }, " " };
91- ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{" thnConfigAxisNoCollInTimeRangeNarrow" , {2 , 0 , 2 }, " " };
92- ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{" thnConfigAxisNoCollInTimeRangeStandard" , {2 , 0 , 2 }, " " };
93- ConfigurableAxis thnConfigAxisNoCollInRofStandard{" thnConfigAxisNoCollInRofStandard" , {2 , 0 , 2 }, " " };
94- ConfigurableAxis thnConfigAxisResoFT0cFV0a{" thnConfigAxisResoFT0cFV0a" , {160 , -8 , 8 }, " " };
95- ConfigurableAxis thnConfigAxisResoFT0cTPCtot{" thnConfigAxisResoFT0cTPCtot" , {160 , -8 , 8 }, " " };
96- ConfigurableAxis thnConfigAxisResoFV0aTPCtot{" thnConfigAxisResoFV0aTPCtot" , {160 , -8 , 8 }, " " };
79+ HfHelper hfHelper;
80+ EventPlaneHelper epHelper;
81+ HfEventSelection hfEvSel; // event selection and monitoring
82+ o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
83+ SliceCache cache;
9784
9885 using CandDsDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi, aod::HfMlDsToKKPi>>;
9986 using CandDsData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi>>;
@@ -103,6 +90,8 @@ struct HfTaskFlowCharmHadrons {
10390 using CandLcDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelLc, aod::HfMlLcToPKPi>>;
10491 using CandXicData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelXicToPKPi>>;
10592 using CandXicDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelXicToPKPi, aod::HfMlXicToPKPi>>;
93+ using CandXic0Data = soa::Filtered<soa::Join<aod::HfCandToXiPiKf, aod::HfSelToXiPiKf>>;
94+ using CandXic0DataWMl = soa::Filtered<soa::Join<aod::HfCandToXiPiKf, aod::HfSelToXiPiKf, aod::HfMlToXiPiKf>>;
10695 using CandD0DataWMl = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0, aod::HfMlD0>>;
10796 using CandD0Data = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0>>;
10897 using CollsWithQvecs = soa::Join<aod::Collisions, aod::EvSels, aod::QvectorFT0Cs, aod::QvectorFT0As, aod::QvectorFT0Ms, aod::QvectorFV0As, aod::QvectorBPoss, aod::QvectorBNegs, aod::QvectorBTots, aod::CentFV0As, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs>;
@@ -112,6 +101,7 @@ struct HfTaskFlowCharmHadrons {
112101 Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
113102 Filter filterSelectLcCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag;
114103 Filter filterSelectXicCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
104+ Filter filterSelectXic0Candidates = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
115105
116106 Partition<CandDsData> selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag;
117107 Partition<CandDsData> selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag;
@@ -129,12 +119,28 @@ struct HfTaskFlowCharmHadrons {
129119 Partition<CandXicData> selectedXicToPiKP = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
130120 Partition<CandXicDataWMl> selectedXicToPKPiWMl = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag;
131121 Partition<CandXicDataWMl> selectedXicToPiKPWMl = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
122+ Partition<CandXic0Data> selectedXic0 = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
123+ Partition<CandXic0DataWMl> selectedXic0WMl = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
132124
133- SliceCache cache;
134- HfHelper hfHelper;
135- EventPlaneHelper epHelper;
136- HfEventSelection hfEvSel; // event selection and monitoring
137- o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
125+ ConfigurableAxis thnConfigAxisInvMass{" thnConfigAxisInvMass" , {100 , 1.78 , 2.05 }, " " };
126+ ConfigurableAxis thnConfigAxisPt{" thnConfigAxisPt" , {10 , 0 ., 10 .}, " " };
127+ ConfigurableAxis thnConfigAxisCent{" thnConfigAxisCent" , {10000 , 0 ., 100 .}, " " };
128+ ConfigurableAxis thnConfigAxisCosNPhi{" thnConfigAxisCosNPhi" , {100 , -1 ., 1 .}, " " };
129+ ConfigurableAxis thnConfigAxisPsi{" thnConfigAxisPsi" , {6000 , 0 , constants::math::TwoPI}, " " };
130+ ConfigurableAxis thnConfigAxisCosDeltaPhi{" thnConfigAxisCosDeltaPhi" , {100 , -1 ., 1 .}, " " };
131+ ConfigurableAxis thnConfigAxisScalarProd{" thnConfigAxisScalarProd" , {100 , 0 ., 1 .}, " " };
132+ ConfigurableAxis thnConfigAxisMlOne{" thnConfigAxisMlOne" , {1000 , 0 ., 1 .}, " " };
133+ ConfigurableAxis thnConfigAxisMlTwo{" thnConfigAxisMlTwo" , {1000 , 0 ., 1 .}, " " };
134+ ConfigurableAxis thnConfigAxisOccupancyITS{" thnConfigAxisOccupancyITS" , {14 , 0 , 14000 }, " " };
135+ ConfigurableAxis thnConfigAxisOccupancyFT0C{" thnConfigAxisOccupancyFT0C" , {14 , 0 , 140000 }, " " };
136+ ConfigurableAxis thnConfigAxisNoSameBunchPileup{" thnConfigAxisNoSameBunchPileup" , {2 , 0 , 2 }, " " };
137+ ConfigurableAxis thnConfigAxisOccupancy{" thnConfigAxisOccupancy" , {2 , 0 , 2 }, " " };
138+ ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{" thnConfigAxisNoCollInTimeRangeNarrow" , {2 , 0 , 2 }, " " };
139+ ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{" thnConfigAxisNoCollInTimeRangeStandard" , {2 , 0 , 2 }, " " };
140+ ConfigurableAxis thnConfigAxisNoCollInRofStandard{" thnConfigAxisNoCollInRofStandard" , {2 , 0 , 2 }, " " };
141+ ConfigurableAxis thnConfigAxisResoFT0cFV0a{" thnConfigAxisResoFT0cFV0a" , {160 , -8 , 8 }, " " };
142+ ConfigurableAxis thnConfigAxisResoFT0cTPCtot{" thnConfigAxisResoFT0cTPCtot" , {160 , -8 , 8 }, " " };
143+ ConfigurableAxis thnConfigAxisResoFV0aTPCtot{" thnConfigAxisResoFV0aTPCtot" , {160 , -8 , 8 }, " " };
138144
139145 HistogramRegistry registry{" registry" , {}};
140146
@@ -231,15 +237,15 @@ struct HfTaskFlowCharmHadrons {
231237 }
232238
233239 if (storeResoOccu) {
234- std::vector<AxisSpec> axes_reso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot};
240+ std::vector<AxisSpec> axesReso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot};
235241 if (occEstimator == 1 ) {
236- axes_reso .insert (axes_reso .end (), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy,
237- thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
242+ axesReso .insert (axesReso .end (), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy,
243+ thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
238244 } else {
239- axes_reso .insert (axes_reso .end (), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy,
240- thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
245+ axesReso .insert (axesReso .end (), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy,
246+ thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
241247 }
242- registry.add (" spReso/hSparseReso" , " THn for resolution with occupancy" , HistType::kTHnSparseF , axes_reso );
248+ registry.add (" spReso/hSparseReso" , " THn for resolution with occupancy" , HistType::kTHnSparseF , axesReso );
243249 }
244250
245251 hfEvSel.addHistograms (registry); // collision monitoring
@@ -285,19 +291,52 @@ struct HfTaskFlowCharmHadrons {
285291 }
286292 }
287293
294+ // / Compute the Q vector for the candidate's tracks
295+ // / \param cand is the candidate
296+ // / \param tracksQx is the X component of the Q vector for the tracks
297+ // / \param tracksQy is the Y component of the Q vector for the tracks
298+ // / \param channel is the decay channel
299+ template <typename T1>
300+ void getQvecXic0Tracks (const T1& cand,
301+ std::vector<float >& tracksQx,
302+ std::vector<float >& tracksQy,
303+ float & ampl)
304+ {
305+ // add possibility to consider different weights for the tracks, at the moment only pT is considered;
306+ float pXTrack0 = cand.pxPosV0Dau ();
307+ float pYTrack0 = cand.pyPosV0Dau ();
308+ float pTTrack0 = std::hypot (pXTrack0, pYTrack0);
309+ float phiTrack0 = std::atan2 (pXTrack0, pYTrack0);
310+ float pXTrack1 = cand.pxNegV0Dau ();
311+ float pYTrack1 = cand.pyNegV0Dau ();
312+ float pTTrack1 = std::hypot (pXTrack1, pYTrack1);
313+ float phiTrack1 = std::atan2 (pXTrack1, pYTrack1);
314+ float pYTrack2 = cand.pxBachFromCasc ();
315+ float pXTrack2 = cand.pyBachFromCasc ();
316+ float pTTrack2 = std::hypot (pXTrack2, pYTrack2);
317+ float phiTrack2 = std::atan2 (pXTrack2, pYTrack2);
318+ float pXTrack3 = cand.pxBachFromCharmBaryon ();
319+ float pYTrack3 = cand.pyBachFromCharmBaryon ();
320+ float pTTrack3 = std::hypot (pXTrack3, pYTrack3);
321+ float phiTrack3 = std::atan2 (pXTrack3, pYTrack3);
322+
323+ tracksQx.push_back (std::cos (harmonic * phiTrack0) * pTTrack0 / ampl);
324+ tracksQy.push_back (std::sin (harmonic * phiTrack0) * pTTrack0 / ampl);
325+ tracksQx.push_back (std::cos (harmonic * phiTrack1) * pTTrack1 / ampl);
326+ tracksQy.push_back (std::sin (harmonic * phiTrack1) * pTTrack1 / ampl);
327+ tracksQx.push_back (std::cos (harmonic * phiTrack2) * pTTrack2 / ampl);
328+ tracksQy.push_back (std::sin (harmonic * phiTrack2) * pTTrack2 / ampl);
329+ tracksQx.push_back (std::cos (harmonic * phiTrack3) * pTTrack3 / ampl);
330+ tracksQy.push_back (std::sin (harmonic * phiTrack3) * pTTrack3 / ampl);
331+ }
288332 // / Compute the delta psi in the range [0, pi/harmonic]
289333 // / \param psi1 is the first angle
290334 // / \param psi2 is the second angle
291335 // / \note Ported from AliAnalysisTaskSECharmHadronvn::GetDeltaPsiSubInRange
292336 float getDeltaPsiInRange (float psi1, float psi2)
293337 {
294338 float deltaPsi = psi1 - psi2;
295- if (std::abs (deltaPsi) > constants::math::PI / harmonic) {
296- if (deltaPsi > 0 .)
297- deltaPsi -= constants::math::TwoPI / harmonic;
298- else
299- deltaPsi += constants::math::TwoPI / harmonic;
300- }
339+ deltaPsi = RecoDecay::constrainAngle (deltaPsi, -o2::constants::math::PI / harmonic, harmonic);
301340 return deltaPsi;
302341 }
303342
@@ -552,18 +591,35 @@ struct HfTaskFlowCharmHadrons {
552591 default :
553592 break ;
554593 }
594+ } else if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
595+ massCand = candidate.invMassCharmBaryon ();
596+ if constexpr (std::is_same_v<T1, CandXic0DataWMl>) {
597+ for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++)
598+ outputMl[iclass] = candidate.mlProbToXiPi ()[classMl->at (iclass)];
599+ }
555600 }
556601
557- float ptCand = candidate.pt ();
558- float phiCand = candidate.phi ();
602+ float ptCand = 0 .;
603+ float phiCand = 0 .;
604+
605+ if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
606+ ptCand = candidate.kfptXic ();
607+ phiCand = std::atan2 (candidate.pxCharmBaryon (), candidate.pyCharmBaryon ());
608+ } else {
609+ ptCand = candidate.pt ();
610+ phiCand = candidate.phi ();
611+ }
559612
560613 // If TPC is used for the SP estimation, the tracks of the hadron candidate must be removed from the TPC Q vector to avoid double counting
561614 if (qvecDetector == QvecEstimator::TPCNeg || qvecDetector == QvecEstimator::TPCPos) {
562615 float ampl = amplQVec - static_cast <float >(nProngs);
563616 std::vector<float > tracksQx = {};
564617 std::vector<float > tracksQy = {};
565-
566- getQvecDtracks<channel>(candidate, tracksQx, tracksQy, ampl);
618+ if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
619+ // std::cout<<candidate.pxProng0()<<std::endl;
620+ getQvecXic0Tracks (candidate, tracksQx, tracksQy, ampl);
621+ } else
622+ getQvecDtracks<channel>(candidate, tracksQx, tracksQy, ampl);
567623 for (auto iTrack{0u }; iTrack < tracksQx.size (); ++iTrack) {
568624 xQVec -= tracksQx[iTrack];
569625 yQVec -= tracksQy[iTrack];
@@ -615,7 +671,7 @@ struct HfTaskFlowCharmHadrons {
615671 {
616672 runFlowAnalysis<DecayChannel::DplusToPiKPi>(collision, candidatesDplus);
617673 }
618- PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDplus, " Process Dplus candidates" , true );
674+ PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDplus, " Process Dplus candidates" , false );
619675
620676 // D0 with ML
621677 void processD0Ml (CollsWithQvecs::iterator const & collision,
@@ -670,7 +726,7 @@ struct HfTaskFlowCharmHadrons {
670726 runFlowAnalysis<DecayChannel::XicToPKPi>(collision, candsXicToPKPiWMl);
671727 runFlowAnalysis<DecayChannel::XicToPiKP>(collision, candsXicToPiKPWMl);
672728 }
673- PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXicMl, " Process Xic candidates with ML" , false );
729+ PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXicMl, " Process Xic candidates with ML" , true );
674730
675731 // Xic with rectangular cuts
676732 void processXic (CollsWithQvecs::iterator const & collision,
@@ -683,6 +739,24 @@ struct HfTaskFlowCharmHadrons {
683739 }
684740 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic, " Process Xic candidates" , false );
685741
742+ // Xic0 with ML
743+ void processXic0Ml (CollsWithQvecs::iterator const & collision,
744+ CandXic0DataWMl const &)
745+ {
746+ auto candsXic0WMl = selectedXic0WMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
747+ runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0WMl);
748+ }
749+ PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic0Ml, " Process Xic0 candidates with ML" , false );
750+
751+ // Xic0
752+ void processXic0 (CollsWithQvecs::iterator const & collision,
753+ CandXic0Data const &)
754+ {
755+ auto candsXic0 = selectedXic0->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
756+ runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0);
757+ }
758+ PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic0, " Process Xic0 candidates" , false );
759+
686760 // Resolution
687761 void processResolution (CollsWithQvecs::iterator const & collision,
688762 aod::BCsWithTimestamps const & bcs)
0 commit comments