@@ -121,6 +121,7 @@ struct HfTaskFlowCharmHadrons {
121121 Configurable<bool > storeResoOccu{" storeResoOccu" , false , " Flag to store Occupancy in resolution ThnSparse" };
122122 Configurable<bool > storeEpCosSin{" storeEpCosSin" , false , " Flag to store cos and sin of EP angle in ThnSparse" };
123123 Configurable<bool > storeCandEta{" storeCandEta" , false , " Flag to store candidates eta" };
124+ Configurable<bool > storeCandSign{" storeCandSign" , false , " Flag to store candidates sign" };
124125 Configurable<int > occEstimator{" occEstimator" , 0 , " Occupancy estimation (0: None, 1: ITS, 2: FT0C)" };
125126 Configurable<bool > saveEpResoHisto{" saveEpResoHisto" , false , " Flag to save event plane resolution histogram" };
126127 Configurable<std::string> ccdbUrl{" ccdbUrl" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
@@ -144,6 +145,7 @@ struct HfTaskFlowCharmHadrons {
144145 using CandD0DataWMl = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0, aod::HfMlD0>>;
145146 using CandD0Data = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0>>;
146147 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>;
148+ using TracksWithExtra = soa::Join<aod::Tracks, aod::TracksExtra>;
147149
148150 Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag;
149151 Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag;
@@ -191,6 +193,7 @@ struct HfTaskFlowCharmHadrons {
191193 ConfigurableAxis thnConfigAxisResoFT0cTPCtot{" thnConfigAxisResoFT0cTPCtot" , {160 , -8 , 8 }, " " };
192194 ConfigurableAxis thnConfigAxisResoFV0aTPCtot{" thnConfigAxisResoFV0aTPCtot" , {160 , -8 , 8 }, " " };
193195 ConfigurableAxis thnConfigAxisCandidateEta{" thnConfigAxisCandidateEta" , {100 , -5 , 5 }, " " };
196+ ConfigurableAxis thnConfigAxisSign{" thnConfigAxisSign" , {6 , -3.0 , 3.0 }, " " };
194197
195198 HistogramRegistry registry{" registry" , {}};
196199
@@ -212,6 +215,7 @@ struct HfTaskFlowCharmHadrons {
212215 const AxisSpec thnAxisOccupancyITS{thnConfigAxisOccupancyITS, " OccupancyITS" };
213216 const AxisSpec thnAxisOccupancyFT0C{thnConfigAxisOccupancyFT0C, " OccupancyFT0C" };
214217 const AxisSpec thnAxisCandEta{thnConfigAxisCandidateEta, " #eta" };
218+ const AxisSpec thnAxisSign{thnConfigAxisSign, " Sign" };
215219 const AxisSpec thnAxisNoSameBunchPileup{thnConfigAxisNoSameBunchPileup, " NoSameBunchPileup" };
216220 const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, " Occupancy" };
217221 const AxisSpec thnAxisNoCollInTimeRangeNarrow{thnConfigAxisNoCollInTimeRangeNarrow, " NoCollInTimeRangeNarrow" };
@@ -232,6 +236,9 @@ struct HfTaskFlowCharmHadrons {
232236 if (storeCandEta) {
233237 axes.insert (axes.end (), {thnAxisCandEta});
234238 }
239+ if (storeCandSign) {
240+ axes.insert (axes.end (), {thnAxisSign});
241+ }
235242 if (occEstimator != 0 ) {
236243 if (occEstimator == 1 ) {
237244 axes.insert (axes.end (), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy,
@@ -403,6 +410,7 @@ struct HfTaskFlowCharmHadrons {
403410 // / \param mass is the invariant mass of the candidate
404411 // / \param pt is the transverse momentum of the candidate
405412 // / \param eta is the pseudorapidityof the candidate
413+ // / \param sign is the particle charge sign of the candidate
406414 // / \param cent is the centrality of the collision
407415 // / \param cosNPhi is the cosine of the n*phi angle
408416 // / \param sinNPhi is the sine of the n*phi angle
@@ -414,6 +422,7 @@ struct HfTaskFlowCharmHadrons {
414422 void fillThn (const float mass,
415423 const float pt,
416424 const float eta,
425+ const float sign,
417426 const float cent,
418427 const float cosNPhi,
419428 const float sinNPhi,
@@ -448,7 +457,9 @@ struct HfTaskFlowCharmHadrons {
448457 if (storeCandEta) {
449458 values.push_back (eta);
450459 }
451-
460+ if (storeCandSign) {
461+ values.push_back (sign);
462+ }
452463 if (occEstimator != 0 ) {
453464 auto evtSelFlags = getEventSelectionFlags (hfevselflag);
454465 values.push_back (occupancy);
@@ -492,9 +503,10 @@ struct HfTaskFlowCharmHadrons {
492503 // / Compute the scalar product
493504 // / \param collision is the collision with the Q vector information and event plane
494505 // / \param candidates are the selected candidates
495- template <DecayChannel Channel, typename T1>
506+ template <DecayChannel Channel, typename T1, typename Trk >
496507 void runFlowAnalysis (CollsWithQvecs::iterator const & collision,
497- T1 const & candidates)
508+ T1 const & candidates,
509+ Trk const & /* tracks*/ )
498510 {
499511 float cent = o2::hf_centrality::getCentralityColl (collision, centEstimator);
500512 if (cent < centralityMin || cent > centralityMax) {
@@ -513,12 +525,13 @@ struct HfTaskFlowCharmHadrons {
513525 float yQVec = qVecs[1 ];
514526 float const amplQVec = qVecs[2 ];
515527 float const evtPl = epHelper.GetEventPlane (xQVec, yQVec, harmonic);
516-
517528 for (const auto & candidate : candidates) {
518529 float massCand = 0 .;
530+ float signCand = 0 .;
519531 std::vector<float > outputMl = {-999 ., -999 .};
520-
521532 if constexpr (std::is_same_v<T1, CandDsData> || std::is_same_v<T1, CandDsDataWMl>) {
533+ auto trackprong0 = candidate.template prong0_as <Trk>();
534+ signCand = trackprong0.sign ();
522535 switch (Channel) {
523536 case DecayChannel::DsToKKPi:
524537 massCand = HfHelper::invMassDsToKKPi (candidate);
@@ -541,6 +554,8 @@ struct HfTaskFlowCharmHadrons {
541554 }
542555 } else if constexpr (std::is_same_v<T1, CandDplusData> || std::is_same_v<T1, CandDplusDataWMl>) {
543556 massCand = HfHelper::invMassDplusToPiKPi (candidate);
557+ auto trackprong0 = candidate.template prong0_as <Trk>();
558+ signCand = trackprong0.sign ();
544559 if constexpr (std::is_same_v<T1, CandDplusDataWMl>) {
545560 for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++) {
546561 outputMl[iclass] = candidate.mlProbDplusToPiKPi ()[classMl->at (iclass)];
@@ -549,6 +564,7 @@ struct HfTaskFlowCharmHadrons {
549564 } else if constexpr (std::is_same_v<T1, CandD0Data> || std::is_same_v<T1, CandD0DataWMl>) {
550565 switch (Channel) {
551566 case DecayChannel::D0ToPiK:
567+ signCand = candidate.isSelD0bar () ? 3 : 1 ; // 3: reflected D0bar, 1: pure D0 excluding reflected D0bar
552568 massCand = HfHelper::invMassD0ToPiK (candidate);
553569 if constexpr (std::is_same_v<T1, CandD0DataWMl>) {
554570 for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++) {
@@ -558,6 +574,7 @@ struct HfTaskFlowCharmHadrons {
558574 break ;
559575 case DecayChannel::D0ToKPi:
560576 massCand = HfHelper::invMassD0barToKPi (candidate);
577+ signCand = candidate.isSelD0 () ? 3 : 2 ; // 3: reflected D0, 2: pure D0bar excluding reflected D0
561578 if constexpr (std::is_same_v<T1, CandD0DataWMl>) {
562579 for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++) {
563580 outputMl[iclass] = candidate.mlProbD0bar ()[classMl->at (iclass)];
@@ -568,6 +585,8 @@ struct HfTaskFlowCharmHadrons {
568585 break ;
569586 }
570587 } else if constexpr (std::is_same_v<T1, CandLcData> || std::is_same_v<T1, CandLcDataWMl>) {
588+ auto trackprong0 = candidate.template prong0_as <Trk>();
589+ signCand = trackprong0.sign ();
571590 switch (Channel) {
572591 case DecayChannel::LcToPKPi:
573592 massCand = HfHelper::invMassLcToPKPi (candidate);
@@ -589,6 +608,8 @@ struct HfTaskFlowCharmHadrons {
589608 break ;
590609 }
591610 } else if constexpr (std::is_same_v<T1, CandXicData> || std::is_same_v<T1, CandXicDataWMl>) {
611+ auto trackprong0 = candidate.template prong0_as <Trk>();
612+ signCand = trackprong0.sign ();
592613 switch (Channel) {
593614 case DecayChannel::XicToPKPi:
594615 massCand = HfHelper::invMassXicToPKPi (candidate);
@@ -611,6 +632,7 @@ struct HfTaskFlowCharmHadrons {
611632 }
612633 } else if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
613634 massCand = candidate.invMassCharmBaryon ();
635+ signCand = static_cast <float >(candidate.signDecay ());
614636 if constexpr (std::is_same_v<T1, CandXic0DataWMl>) {
615637 for (unsigned int iclass = 0 ; iclass < classMl->size (); iclass++) {
616638 outputMl[iclass] = candidate.mlProbToXiPi ()[classMl->at (iclass)];
@@ -674,130 +696,142 @@ struct HfTaskFlowCharmHadrons {
674696 }
675697 }
676698 if (fillSparse) {
677- fillThn (massCand, ptCand, etaCand, cent, cosNPhi, sinNPhi, cosDeltaPhi, scalprodCand, outputMl, occupancy, hfevflag);
699+ fillThn (massCand, ptCand, etaCand, signCand, cent, cosNPhi, sinNPhi, cosDeltaPhi, scalprodCand, outputMl, occupancy, hfevflag);
678700 }
679701 }
680702 }
681703
682704 // Ds with ML
683705 void processDsMl (CollsWithQvecs::iterator const & collision,
684- CandDsDataWMl const &)
706+ CandDsDataWMl const &,
707+ TracksWithExtra const & tracks)
685708 {
686709 auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
687710 auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
688- runFlowAnalysis<DecayChannel::DsToKKPi>(collision, candsDsToKKPiWMl);
689- runFlowAnalysis<DecayChannel::DsToPiKK>(collision, candsDsToPiKKWMl);
711+ runFlowAnalysis<DecayChannel::DsToKKPi>(collision, candsDsToKKPiWMl, tracks );
712+ runFlowAnalysis<DecayChannel::DsToPiKK>(collision, candsDsToPiKKWMl, tracks );
690713 }
691714 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDsMl, " Process Ds candidates with ML" , false );
692715
693716 // Ds with rectangular cuts
694717 void processDs (CollsWithQvecs::iterator const & collision,
695- CandDsData const &)
718+ CandDsData const & /* candidatesDs*/ ,
719+ TracksWithExtra const & tracks)
696720 {
697721 auto candsDsToKKPi = selectedDsToKKPi->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
698722 auto candsDsToPiKK = selectedDsToPiKK->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
699- runFlowAnalysis<DecayChannel::DsToKKPi>(collision, candsDsToKKPi);
700- runFlowAnalysis<DecayChannel::DsToPiKK>(collision, candsDsToPiKK);
723+ runFlowAnalysis<DecayChannel::DsToKKPi>(collision, candsDsToKKPi, tracks );
724+ runFlowAnalysis<DecayChannel::DsToPiKK>(collision, candsDsToPiKK, tracks );
701725 }
702726 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDs, " Process Ds candidates" , false );
703727
704728 // Dplus with ML
705729 void processDplusMl (CollsWithQvecs::iterator const & collision,
706- CandDplusDataWMl const & candidatesDplus)
730+ CandDplusDataWMl const & candidatesDplus,
731+ TracksWithExtra const & tracks)
707732 {
708- runFlowAnalysis<DecayChannel::DplusToPiKPi>(collision, candidatesDplus);
733+ runFlowAnalysis<DecayChannel::DplusToPiKPi>(collision, candidatesDplus, tracks );
709734 }
710735 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDplusMl, " Process Dplus candidates with ML" , false );
711736
712737 // Dplus with rectangular cuts
713738 void processDplus (CollsWithQvecs::iterator const & collision,
714- CandDplusData const & candidatesDplus)
739+ CandDplusData const & candidatesDplus,
740+ TracksWithExtra const & tracks)
715741 {
716- runFlowAnalysis<DecayChannel::DplusToPiKPi>(collision, candidatesDplus);
742+ runFlowAnalysis<DecayChannel::DplusToPiKPi>(collision, candidatesDplus, tracks );
717743 }
718744 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processDplus, " Process Dplus candidates" , true );
719745
720746 // D0 with ML
721747 void processD0Ml (CollsWithQvecs::iterator const & collision,
722- CandD0DataWMl const &)
748+ CandD0DataWMl const & /* candidatesD0*/ ,
749+ TracksWithExtra const & tracks)
723750 {
724751 auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
725752 auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
726- runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiKWMl);
727- runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPiWMl);
753+ runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiKWMl, tracks );
754+ runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPiWMl, tracks );
728755 }
729756 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processD0Ml, " Process D0 candidates with ML" , false );
730757
731758 // D0 with rectangular cuts
732759 void processD0 (CollsWithQvecs::iterator const & collision,
733- CandD0Data const &)
760+ CandD0Data const & /* candidatesD0*/ ,
761+ TracksWithExtra const & tracks)
734762 {
735763 auto candsD0ToPiK = selectedD0ToPiK->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
736764 auto candsD0ToKPi = selectedD0ToKPi->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
737- runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiK);
738- runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPi);
765+ runFlowAnalysis<DecayChannel::D0ToPiK>(collision, candsD0ToPiK, tracks );
766+ runFlowAnalysis<DecayChannel::D0ToKPi>(collision, candsD0ToKPi, tracks );
739767 }
740768 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processD0, " Process D0 candidates" , false );
741769
742770 // Lc with ML
743771 void processLcMl (CollsWithQvecs::iterator const & collision,
744- CandLcDataWMl const &)
772+ CandLcDataWMl const & /* candidatesLc*/ ,
773+ TracksWithExtra const & tracks)
745774 {
746775 auto candsLcToPKPiWMl = selectedLcToPKPiWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
747776 auto candsLcToPiKPWMl = selectedLcToPiKPWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
748- runFlowAnalysis<DecayChannel::LcToPKPi>(collision, candsLcToPKPiWMl);
749- runFlowAnalysis<DecayChannel::LcToPiKP>(collision, candsLcToPiKPWMl);
777+ runFlowAnalysis<DecayChannel::LcToPKPi>(collision, candsLcToPKPiWMl, tracks );
778+ runFlowAnalysis<DecayChannel::LcToPiKP>(collision, candsLcToPiKPWMl, tracks );
750779 }
751780 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processLcMl, " Process Lc candidates with ML" , false );
752781
753782 // Lc with rectangular cuts
754783 void processLc (CollsWithQvecs::iterator const & collision,
755- CandLcData const &)
784+ CandLcData const & /* candidatesLc*/ ,
785+ TracksWithExtra const & tracks)
756786 {
757787 auto candsLcToPKPi = selectedLcToPKPi->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
758788 auto candsLcToPiKP = selectedLcToPiKP->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
759- runFlowAnalysis<DecayChannel::LcToPKPi>(collision, candsLcToPKPi);
760- runFlowAnalysis<DecayChannel::LcToPiKP>(collision, candsLcToPiKP);
789+ runFlowAnalysis<DecayChannel::LcToPKPi>(collision, candsLcToPKPi, tracks );
790+ runFlowAnalysis<DecayChannel::LcToPiKP>(collision, candsLcToPiKP, tracks );
761791 }
762792 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processLc, " Process Lc candidates" , false );
763793
764794 // Xic with ML
765795 void processXicMl (CollsWithQvecs::iterator const & collision,
766- CandXicDataWMl const &)
796+ CandXicDataWMl const & /* candidatesXic*/ ,
797+ TracksWithExtra const & tracks)
767798 {
768799 auto candsXicToPKPiWMl = selectedXicToPKPiWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
769800 auto candsXicToPiKPWMl = selectedXicToPiKPWMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
770- runFlowAnalysis<DecayChannel::XicToPKPi>(collision, candsXicToPKPiWMl);
771- runFlowAnalysis<DecayChannel::XicToPiKP>(collision, candsXicToPiKPWMl);
801+ runFlowAnalysis<DecayChannel::XicToPKPi>(collision, candsXicToPKPiWMl, tracks );
802+ runFlowAnalysis<DecayChannel::XicToPiKP>(collision, candsXicToPiKPWMl, tracks );
772803 }
773804 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXicMl, " Process Xic candidates with ML" , false );
774805
775806 // Xic with rectangular cuts
776807 void processXic (CollsWithQvecs::iterator const & collision,
777- CandXicData const &)
808+ CandXicData const & /* candidatesXic*/ ,
809+ TracksWithExtra const & tracks)
778810 {
779811 auto candsXicToPKPi = selectedXicToPKPi->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
780812 auto candsXicToPiKP = selectedXicToPiKP->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
781- runFlowAnalysis<DecayChannel::XicToPKPi>(collision, candsXicToPKPi);
782- runFlowAnalysis<DecayChannel::XicToPiKP>(collision, candsXicToPiKP);
813+ runFlowAnalysis<DecayChannel::XicToPKPi>(collision, candsXicToPKPi, tracks );
814+ runFlowAnalysis<DecayChannel::XicToPiKP>(collision, candsXicToPiKP, tracks );
783815 }
784816 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic, " Process Xic candidates" , false );
785817
786818 // Xic0 with ML
787819 void processXic0Ml (CollsWithQvecs::iterator const & collision,
788- CandXic0DataWMl const &)
820+ CandXic0DataWMl const & /* candidatesXic0*/ ,
821+ TracksWithExtra const & tracks)
789822 {
790823 auto candsXic0WMl = selectedXic0WMl->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
791- runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0WMl);
824+ runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0WMl, tracks );
792825 }
793826 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic0Ml, " Process Xic0 candidates with ML" , false );
794827
795828 // Xic0
796829 void processXic0 (CollsWithQvecs::iterator const & collision,
797- CandXic0Data const &)
830+ CandXic0Data const & /* candidatesXic0*/ ,
831+ TracksWithExtra const & tracks)
798832 {
799833 auto candsXic0 = selectedXic0->sliceByCached (aod::hf_cand::collisionId, collision.globalIndex (), cache);
800- runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0);
834+ runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0, tracks );
801835 }
802836 PROCESS_SWITCH (HfTaskFlowCharmHadrons, processXic0, " Process Xic0 candidates" , false );
803837
0 commit comments