Skip to content

Commit 4cc3902

Browse files
authored
[PWGHF] Add Xic0 flow task and fix previous O2 linter issues (AliceO2Group#11533)
1 parent b7c799e commit 4cc3902

File tree

1 file changed

+117
-41
lines changed

1 file changed

+117
-41
lines changed

PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx

Lines changed: 117 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
///
1515
/// \author S. Politanò, INFN Torino, Italy
1616
/// \author Wu Chuntai, CUG, China
17+
/// \author Ran Tu, Fudan University, China
1718

1819
#include <string>
1920
#include <vector>
@@ -48,7 +49,8 @@ enum DecayChannel { DplusToPiKPi = 0,
4849
LcToPKPi,
4950
LcToPiKP,
5051
XicToPKPi,
51-
XicToPiKP
52+
XicToPiKP,
53+
Xic0ToXiPi
5254
};
5355

5456
enum QvecEstimator { FV0A = 0,
@@ -75,25 +77,11 @@ struct HfTaskFlowCharmHadrons {
7577
Configurable<std::string> ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
7678
Configurable<std::vector<int>> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."};
7779

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}, ""};
80+
HfHelper hfHelper;
81+
EventPlaneHelper epHelper;
82+
HfEventSelection hfEvSel; // event selection and monitoring
83+
o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
84+
SliceCache cache;
9785

9886
using CandDsDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi, aod::HfMlDsToKKPi>>;
9987
using CandDsData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi>>;
@@ -103,6 +91,8 @@ struct HfTaskFlowCharmHadrons {
10391
using CandLcDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelLc, aod::HfMlLcToPKPi>>;
10492
using CandXicData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelXicToPKPi>>;
10593
using CandXicDataWMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelXicToPKPi, aod::HfMlXicToPKPi>>;
94+
using CandXic0Data = soa::Filtered<soa::Join<aod::HfCandToXiPiKf, aod::HfSelToXiPiKf>>;
95+
using CandXic0DataWMl = soa::Filtered<soa::Join<aod::HfCandToXiPiKf, aod::HfSelToXiPiKf, aod::HfMlToXiPiKf>>;
10696
using CandD0DataWMl = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0, aod::HfMlD0>>;
10797
using CandD0Data = soa::Filtered<soa::Join<aod::HfCand2Prong, aod::HfSelD0>>;
10898
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 +102,7 @@ struct HfTaskFlowCharmHadrons {
112102
Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag;
113103
Filter filterSelectLcCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag;
114104
Filter filterSelectXicCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
105+
Filter filterSelectXic0Candidates = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
115106

116107
Partition<CandDsData> selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag;
117108
Partition<CandDsData> selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag;
@@ -129,12 +120,28 @@ struct HfTaskFlowCharmHadrons {
129120
Partition<CandXicData> selectedXicToPiKP = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
130121
Partition<CandXicDataWMl> selectedXicToPKPiWMl = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag;
131122
Partition<CandXicDataWMl> selectedXicToPiKPWMl = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag;
123+
Partition<CandXic0Data> selectedXic0 = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
124+
Partition<CandXic0DataWMl> selectedXic0WMl = aod::hf_sel_toxipi::resultSelections >= selectionFlag;
132125

133-
SliceCache cache;
134-
HfHelper hfHelper;
135-
EventPlaneHelper epHelper;
136-
HfEventSelection hfEvSel; // event selection and monitoring
137-
o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
126+
ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""};
127+
ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""};
128+
ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""};
129+
ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""};
130+
ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 0, constants::math::TwoPI}, ""};
131+
ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""};
132+
ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""};
133+
ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""};
134+
ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""};
135+
ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""};
136+
ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""};
137+
ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""};
138+
ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""};
139+
ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""};
140+
ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""};
141+
ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""};
142+
ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""};
143+
ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""};
144+
ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""};
138145

139146
HistogramRegistry registry{"registry", {}};
140147

@@ -231,15 +238,15 @@ struct HfTaskFlowCharmHadrons {
231238
}
232239

233240
if (storeResoOccu) {
234-
std::vector<AxisSpec> axes_reso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot};
241+
std::vector<AxisSpec> axesReso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot};
235242
if (occEstimator == 1) {
236-
axes_reso.insert(axes_reso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy,
237-
thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
243+
axesReso.insert(axesReso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy,
244+
thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
238245
} else {
239-
axes_reso.insert(axes_reso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy,
240-
thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
246+
axesReso.insert(axesReso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy,
247+
thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard});
241248
}
242-
registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axes_reso);
249+
registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axesReso);
243250
}
244251

245252
hfEvSel.addHistograms(registry); // collision monitoring
@@ -285,19 +292,52 @@ struct HfTaskFlowCharmHadrons {
285292
}
286293
}
287294

295+
/// Compute the Q vector for the candidate's tracks
296+
/// \param cand is the candidate
297+
/// \param tracksQx is the X component of the Q vector for the tracks
298+
/// \param tracksQy is the Y component of the Q vector for the tracks
299+
/// \param channel is the decay channel
300+
template <typename T1>
301+
void getQvecXic0Tracks(const T1& cand,
302+
std::vector<float>& tracksQx,
303+
std::vector<float>& tracksQy,
304+
float ampl)
305+
{
306+
// add possibility to consider different weights for the tracks, at the moment only pT is considered;
307+
float pXTrack0 = cand.pxPosV0Dau();
308+
float pYTrack0 = cand.pyPosV0Dau();
309+
float pTTrack0 = std::hypot(pXTrack0, pYTrack0);
310+
float phiTrack0 = std::atan2(pXTrack0, pYTrack0);
311+
float pXTrack1 = cand.pxNegV0Dau();
312+
float pYTrack1 = cand.pyNegV0Dau();
313+
float pTTrack1 = std::hypot(pXTrack1, pYTrack1);
314+
float phiTrack1 = std::atan2(pXTrack1, pYTrack1);
315+
float pYTrack2 = cand.pxBachFromCasc();
316+
float pXTrack2 = cand.pyBachFromCasc();
317+
float pTTrack2 = std::hypot(pXTrack2, pYTrack2);
318+
float phiTrack2 = std::atan2(pXTrack2, pYTrack2);
319+
float pXTrack3 = cand.pxBachFromCharmBaryon();
320+
float pYTrack3 = cand.pyBachFromCharmBaryon();
321+
float pTTrack3 = std::hypot(pXTrack3, pYTrack3);
322+
float phiTrack3 = std::atan2(pXTrack3, pYTrack3);
323+
324+
tracksQx.push_back(std::cos(harmonic * phiTrack0) * pTTrack0 / ampl);
325+
tracksQy.push_back(std::sin(harmonic * phiTrack0) * pTTrack0 / ampl);
326+
tracksQx.push_back(std::cos(harmonic * phiTrack1) * pTTrack1 / ampl);
327+
tracksQy.push_back(std::sin(harmonic * phiTrack1) * pTTrack1 / ampl);
328+
tracksQx.push_back(std::cos(harmonic * phiTrack2) * pTTrack2 / ampl);
329+
tracksQy.push_back(std::sin(harmonic * phiTrack2) * pTTrack2 / ampl);
330+
tracksQx.push_back(std::cos(harmonic * phiTrack3) * pTTrack3 / ampl);
331+
tracksQy.push_back(std::sin(harmonic * phiTrack3) * pTTrack3 / ampl);
332+
}
288333
/// Compute the delta psi in the range [0, pi/harmonic]
289334
/// \param psi1 is the first angle
290335
/// \param psi2 is the second angle
291336
/// \note Ported from AliAnalysisTaskSECharmHadronvn::GetDeltaPsiSubInRange
292337
float getDeltaPsiInRange(float psi1, float psi2)
293338
{
294339
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-
}
340+
deltaPsi = RecoDecay::constrainAngle(deltaPsi, -o2::constants::math::PI / harmonic, harmonic);
301341
return deltaPsi;
302342
}
303343

@@ -552,18 +592,36 @@ struct HfTaskFlowCharmHadrons {
552592
default:
553593
break;
554594
}
595+
} else if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
596+
massCand = candidate.invMassCharmBaryon();
597+
if constexpr (std::is_same_v<T1, CandXic0DataWMl>) {
598+
for (unsigned int iclass = 0; iclass < classMl->size(); iclass++)
599+
outputMl[iclass] = candidate.mlProbToXiPi()[classMl->at(iclass)];
600+
}
555601
}
556602

557-
float ptCand = candidate.pt();
558-
float phiCand = candidate.phi();
603+
float ptCand = 0.;
604+
float phiCand = 0.;
605+
606+
if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
607+
ptCand = candidate.kfptXic();
608+
phiCand = std::atan2(candidate.pxCharmBaryon(), candidate.pyCharmBaryon());
609+
} else {
610+
ptCand = candidate.pt();
611+
phiCand = candidate.phi();
612+
}
559613

560614
// 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
561615
if (qvecDetector == QvecEstimator::TPCNeg || qvecDetector == QvecEstimator::TPCPos) {
562616
float ampl = amplQVec - static_cast<float>(nProngs);
563617
std::vector<float> tracksQx = {};
564618
std::vector<float> tracksQy = {};
565-
566-
getQvecDtracks<channel>(candidate, tracksQx, tracksQy, ampl);
619+
if constexpr (std::is_same_v<T1, CandXic0Data> || std::is_same_v<T1, CandXic0DataWMl>) {
620+
// std::cout<<candidate.pxProng0()<<std::endl;
621+
getQvecXic0Tracks(candidate, tracksQx, tracksQy, ampl);
622+
} else {
623+
getQvecDtracks<channel>(candidate, tracksQx, tracksQy, ampl);
624+
}
567625
for (auto iTrack{0u}; iTrack < tracksQx.size(); ++iTrack) {
568626
xQVec -= tracksQx[iTrack];
569627
yQVec -= tracksQy[iTrack];
@@ -683,6 +741,24 @@ struct HfTaskFlowCharmHadrons {
683741
}
684742
PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false);
685743

744+
// Xic0 with ML
745+
void processXic0Ml(CollsWithQvecs::iterator const& collision,
746+
CandXic0DataWMl const&)
747+
{
748+
auto candsXic0WMl = selectedXic0WMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache);
749+
runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0WMl);
750+
}
751+
PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0Ml, "Process Xic0 candidates with ML", false);
752+
753+
// Xic0
754+
void processXic0(CollsWithQvecs::iterator const& collision,
755+
CandXic0Data const&)
756+
{
757+
auto candsXic0 = selectedXic0->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache);
758+
runFlowAnalysis<DecayChannel::Xic0ToXiPi>(collision, candsXic0);
759+
}
760+
PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0, "Process Xic0 candidates", false);
761+
686762
// Resolution
687763
void processResolution(CollsWithQvecs::iterator const& collision,
688764
aod::BCsWithTimestamps const& bcs)

0 commit comments

Comments
 (0)