Skip to content

Commit 50f1b3a

Browse files
author
Prottay Das
committed
updated task accordingly
1 parent 8181b34 commit 50f1b3a

1 file changed

Lines changed: 87 additions & 179 deletions

File tree

PWGLF/Tasks/Resonances/phiflowder.cxx

Lines changed: 87 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -37,52 +37,46 @@ using namespace o2::framework::expressions;
3737

3838
struct phiflowder {
3939

40-
// Event selection
4140
Configurable<float> centMin{"centMin", 0.f, "Minimum centrality"};
4241
Configurable<float> centMax{"centMax", 80.f, "Maximum centrality"};
4342

44-
// PID selection from stored bitmask
45-
Configurable<bool> usePID{"usePID", false, "Enable PID selection using stored bitmask"};
46-
Configurable<int> pidChoice{"pidChoice", 2, "PID choice: 1, 2, 3, 4"};
47-
Configurable<bool> pidExclusive{"pidExclusive", false, "If true require only the chosen PID bit"};
43+
Configurable<bool> useStoredPID{"useStoredPID", false, "Apply PID-bit selection using stored kaon PID mask"};
44+
Configurable<int> pidChoice{"pidChoice", 2, "PID choice: 1, 2, 3, or 4"};
45+
Configurable<bool> pidExclusive{"pidExclusive", false, "Require exactly the selected PID bit"};
4846

49-
// Event mixing
50-
Configurable<int> nEvtMixing{"nEvtMixing", 5, "Number of events to mix"};
51-
ConfigurableAxis cfgVtxBins{"cfgVtxBins", {5, -10.0, 10.0}, "Mixing bins in z vertex"};
52-
ConfigurableAxis cfgMultBins{"cfgMultBins", {8, 0.0, 80.0}, "Mixing bins in centrality"};
47+
Configurable<bool> applyDeepAngle{"applyDeepAngle", false, "Apply minimum opening-angle cut for K+K- pairs"};
48+
Configurable<float> deepAngleCut{"deepAngleCut", 0.04f, "Minimum K+K- opening angle"};
5349

54-
// Histogram axes
55-
ConfigurableAxis configAxisInvMass{"configAxisInvMass", {120, 0.9, 1.2}, "#it{M}_{K^{+}K^{-}} (GeV/#it{c}^{2})"};
56-
ConfigurableAxis configAxisPt{"configAxisPt", {100, 0.0, 10.0}, "#it{p}_{T} (GeV/#it{c})"};
57-
ConfigurableAxis configAxisCentrality{"configAxisCentrality", {8, 0.0, 80.0}, "Centrality (%)"};
50+
Configurable<float> massMin{"massMin", 0.9f, "Minimum K+K- mass to fill"};
51+
Configurable<float> massMax{"massMax", 1.2f, "Maximum K+K- mass to fill"};
52+
53+
ConfigurableAxis axisInvMass{"axisInvMass", {120, 0.9f, 1.2f}, "#it{M}_{K^{+}K^{-}} (GeV/#it{c}^{2})"};
54+
ConfigurableAxis axisPhiPt{"axisPhiPt", {100, 0.f, 10.f}, "#it{p}_{T}^{K^{+}K^{-}} (GeV/#it{c})"};
55+
ConfigurableAxis axisCent{"axisCent", {80, 0.f, 80.f}, "Centrality (%)"};
56+
ConfigurableAxis axisNKaons{"axisNKaons", {300, 0.f, 300.f}, "Number of stored kaons per event"};
57+
ConfigurableAxis axisNPairs{"axisNPairs", {500, 0.f, 5000.f}, "Number of K^{+}K^{-} pairs per event"};
5858

5959
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
6060

61-
// PID bits: same convention as producer
6261
static constexpr uint8_t kPID1 = 1u << 0;
6362
static constexpr uint8_t kPID2 = 1u << 1;
6463
static constexpr uint8_t kPID3 = 1u << 2;
6564
static constexpr uint8_t kPID4 = 1u << 3;
6665

67-
struct KaonDaughter {
68-
float px;
69-
float py;
70-
float pz;
71-
uint8_t pidMask;
72-
};
66+
SliceCache cache;
7367

74-
void init(o2::framework::InitContext&)
68+
void init(InitContext const&)
7569
{
76-
77-
histos.add("hCentrality", "Centrality distribution", kTH1F, {configAxisCentrality});
78-
79-
histos.add("hSparseSame", "Same-event sparse", kTHnSparseF,
80-
{configAxisInvMass, configAxisPt, configAxisCentrality});
81-
histos.add("hSparseMixed", "Mixed-event sparse", kTHnSparseF,
82-
{configAxisInvMass, configAxisPt, configAxisCentrality});
70+
histos.add("hCentrality", "Centrality distribution", kTH1F, {axisCent});
71+
histos.add("hPhiMassSame", "Same-event K^{+}K^{-} invariant mass", kTH1F, {axisInvMass});
72+
histos.add("hPhiPtSame", "Same-event K^{+}K^{-} pT", kTH1F, {axisPhiPt});
73+
histos.add("hNplusPerEvent", "Number of stored K^{+} per event", kTH1F, {axisNKaons});
74+
histos.add("hNminusPerEvent", "Number of stored K^{-} per event", kTH1F, {axisNKaons});
75+
histos.add("hNphiSamePerEvent", "Number of same-event K^{+}K^{-} pairs per event", kTH1F, {axisNPairs});
76+
histos.add("hSparseSame", "Same-event K^{+}K^{-};M;pT;centrality", kTHnSparseF, {axisInvMass, axisPhiPt, axisCent});
8377
}
8478

85-
uint8_t requiredPidBit() const
79+
uint8_t getRequiredPidBit() const
8680
{
8781
switch (pidChoice.value) {
8882
case 1:
@@ -94,207 +88,121 @@ struct phiflowder {
9488
case 4:
9589
return kPID4;
9690
default:
97-
LOGF(warn, "pidChoice=%d is invalid. Using PID2.", pidChoice.value);
91+
LOGF(warn, "Invalid pidChoice=%d. PID2 will be used.", pidChoice.value);
9892
return kPID2;
9993
}
10094
}
10195

102-
bool passDaughterPID(uint8_t mask) const
96+
template <typename T>
97+
bool passStoredPID(const T& kaon) const
10398
{
104-
if (!usePID.value) {
99+
if (!useStoredPID.value) {
105100
return true;
106101
}
107102

108-
const uint8_t bit = requiredPidBit();
103+
const uint16_t mask = kaon.kaonPidMask();
104+
const uint8_t requiredBit = getRequiredPidBit();
109105

110106
if (pidExclusive.value) {
111-
return mask == bit;
107+
return mask == requiredBit;
112108
}
113109

114-
return (mask & bit) != 0;
110+
return (mask & requiredBit) != 0;
115111
}
116112

117-
template <typename TPhi>
118-
bool passPairPID(const TPhi& phiCand) const
113+
bool passDeepAngle(float px1, float py1, float pz1, float px2, float py2, float pz2) const
119114
{
120-
if (!usePID.value) {
115+
if (!applyDeepAngle.value) {
121116
return true;
122117
}
123118

124-
const uint16_t pairMask = phiCand.kaonPidMask();
125-
126-
const uint8_t kPlusMask = pairMask & 0xFF;
127-
const uint8_t kMinusMask = (pairMask >> 8) & 0xFF;
128-
129-
return passDaughterPID(kPlusMask) && passDaughterPID(kMinusMask);
130-
}
131-
132-
void collectUniqueKPlusForEvent(const aod::KaonTracks& kaontracks,
133-
int64_t eventId,
134-
std::map<int64_t, KaonDaughter>& uniqueKPlus)
135-
{
136-
uniqueKPlus.clear();
137-
138-
for (const auto& phiCand : kaontracks) {
139-
if (phiCand.kaonkaoneventId() != eventId) {
140-
continue;
141-
}
119+
const double p1 = std::sqrt(px1 * px1 + py1 * py1 + pz1 * pz1);
120+
const double p2 = std::sqrt(px2 * px2 + py2 * py2 + pz2 * pz2);
142121

143-
const uint16_t pairMask = phiCand.kaonPidMask();
144-
const uint8_t kPlusMask = pairMask & 0xFF;
145-
146-
if (!passDaughterPID(kPlusMask)) {
147-
continue;
148-
}
149-
150-
const int64_t kPlusId = phiCand.kaonIndex1();
151-
152-
if (uniqueKPlus.find(kPlusId) == uniqueKPlus.end()) {
153-
uniqueKPlus[kPlusId] = {
154-
phiCand.d1Px(),
155-
phiCand.d1Py(),
156-
phiCand.d1Pz(),
157-
kPlusMask};
158-
}
122+
if (p1 <= 0.0 || p2 <= 0.0) {
123+
return false;
159124
}
160-
}
161125

162-
void collectUniqueKMinusForEvent(const aod::KaonTracks& kaontracks,
163-
int64_t eventId,
164-
std::map<int64_t, KaonDaughter>& uniqueKMinus)
165-
{
166-
uniqueKMinus.clear();
126+
const double cosAngle = std::clamp((px1 * px2 + py1 * py2 + pz1 * pz2) / (p1 * p2), -1.0, 1.0);
127+
const double angle = std::acos(cosAngle);
167128

168-
for (const auto& phiCand : kaontracks) {
169-
if (phiCand.kaonkaoneventId() != eventId) {
170-
continue;
171-
}
129+
return angle >= deepAngleCut.value;
130+
}
172131

173-
const uint16_t pairMask = phiCand.kaonPidMask();
174-
const uint8_t kMinusMask = (pairMask >> 8) & 0xFF;
132+
Filter centralityFilter = (aod::kaonevent::cent >= centMin) && (aod::kaonevent::cent < centMax);
175133

176-
if (!passDaughterPID(kMinusMask)) {
177-
continue;
178-
}
134+
using EventCandidates = soa::Filtered<aod::KaonEvents>;
179135

180-
const int64_t kMinusId = phiCand.kaonIndex2();
136+
Partition<aod::KaonTracks> posKaons = aod::kaonpair::charge > int8_t{0};
137+
Partition<aod::KaonTracks> negKaons = aod::kaonpair::charge < int8_t{0};
181138

182-
if (uniqueKMinus.find(kMinusId) == uniqueKMinus.end()) {
183-
uniqueKMinus[kMinusId] = {
184-
phiCand.d2Px(),
185-
phiCand.d2Py(),
186-
phiCand.d2Pz(),
187-
kMinusMask};
188-
}
189-
}
190-
}
191-
192-
// Filter reduced events
193-
Filter centralityFilter = (aod::kaonkaonevent::cent >= centMin &&
194-
aod::kaonkaonevent::cent < centMax);
195-
using EventCandidates = soa::Filtered<aod::KaonkaonEvents>;
196-
197-
void processSameData(EventCandidates::iterator const& collision,
198-
aod::KaonTracks const& kaontracks)
139+
void processSameData(EventCandidates::iterator const& collision, aod::KaonTracks const& /*kaontracks*/)
199140
{
200141
const float centrality = collision.cent();
201-
const int64_t eventId = collision.globalIndex();
202142

203143
histos.fill(HIST("hCentrality"), centrality);
204144

205-
for (const auto& phiCand : kaontracks) {
206-
if (phiCand.kaonkaoneventId() != eventId) {
207-
continue;
208-
}
209-
210-
if (!passPairPID(phiCand)) {
211-
continue;
212-
}
145+
auto posThisColl = posKaons->sliceByCached(aod::kaonpair::kaoneventId, collision.globalIndex(), cache);
146+
auto negThisColl = negKaons->sliceByCached(aod::kaonpair::kaoneventId, collision.globalIndex(), cache);
213147

214-
ROOT::Math::PxPyPzMVector kPlus(
215-
phiCand.d1Px(),
216-
phiCand.d1Py(),
217-
phiCand.d1Pz(),
218-
o2::constants::physics::MassKPlus);
148+
int nPlus = 0;
149+
int nMinus = 0;
150+
int nPhiSame = 0;
219151

220-
ROOT::Math::PxPyPzMVector kMinus(
221-
phiCand.d2Px(),
222-
phiCand.d2Py(),
223-
phiCand.d2Pz(),
224-
o2::constants::physics::MassKPlus);
225-
226-
auto phi = kPlus + kMinus;
227-
228-
const float phiMass = phi.M();
229-
const float phiPt = phi.Pt();
230-
231-
histos.fill(HIST("hSparseSame"), phiMass, phiPt, centrality);
152+
for (const auto& kPlus : posThisColl) {
153+
if (passStoredPID(kPlus)) {
154+
nPlus++;
155+
}
232156
}
233-
}
234-
235-
PROCESS_SWITCH(phiflowder, processSameData, "Process same-event phi candidates", true);
236157

237-
using BinningType = ColumnBinningPolicy<aod::kaonkaonevent::Posz,
238-
aod::kaonkaonevent::Cent>;
239-
240-
void processMixedData(EventCandidates const& collisions,
241-
aod::KaonTracks const& kaontracks)
242-
{
243-
244-
BinningType colBinning{{cfgVtxBins, cfgMultBins}, false};
245-
246-
std::map<int64_t, KaonDaughter> kPlusEvent1;
247-
std::map<int64_t, KaonDaughter> kMinusEvent2;
248-
// int nMixedEventPairs = 0;
158+
for (const auto& kMinus : negThisColl) {
159+
if (passStoredPID(kMinus)) {
160+
nMinus++;
161+
}
162+
}
249163

250-
for (const auto& [collision1, collision2] :
251-
selfCombinations(colBinning, nEvtMixing.value, -1, collisions, collisions)) {
164+
histos.fill(HIST("hNplusPerEvent"), nPlus);
165+
histos.fill(HIST("hNminusPerEvent"), nMinus);
252166

253-
if (collision1.globalIndex() == collision2.globalIndex()) {
167+
for (const auto& kPlus : posThisColl) {
168+
if (!passStoredPID(kPlus)) {
254169
continue;
255170
}
256-
// nMixedEventPairs++;
257-
258-
const float centrality = collision1.cent();
259171

260-
collectUniqueKPlusForEvent(kaontracks,
261-
collision1.globalIndex(),
262-
kPlusEvent1);
172+
ROOT::Math::PxPyPzMVector plusVec(kPlus.px(), kPlus.py(), kPlus.pz(), o2::constants::physics::MassKPlus);
263173

264-
collectUniqueKMinusForEvent(kaontracks,
265-
collision2.globalIndex(),
266-
kMinusEvent2);
174+
for (const auto& kMinus : negThisColl) {
175+
if (!passStoredPID(kMinus)) {
176+
continue;
177+
}
267178

268-
// histos.fill(HIST("hNplusUnique"), kPlusEvent1.size());
269-
// histos.fill(HIST("hNminusUnique"), kMinusEvent2.size());
179+
if (!passDeepAngle(kPlus.px(), kPlus.py(), kPlus.pz(), kMinus.px(), kMinus.py(), kMinus.pz())) {
180+
continue;
181+
}
270182

271-
// const int nMixedKPairs = static_cast<int>(kPlusEvent1.size() * kMinusEvent2.size());
183+
ROOT::Math::PxPyPzMVector minusVec(kMinus.px(), kMinus.py(), kMinus.pz(), o2::constants::physics::MassKPlus);
272184

273-
// histos.fill(HIST("hNmixedKPairsPerEventPair"), nMixedKPairs);
185+
const auto phiCandidate = plusVec + minusVec;
274186

275-
for (const auto& [kPlusId, kPlus] : kPlusEvent1) {
276-
ROOT::Math::PxPyPzMVector kPlusVec(
277-
kPlus.px,
278-
kPlus.py,
279-
kPlus.pz,
280-
o2::constants::physics::MassKPlus);
187+
const float phiMass = phiCandidate.M();
188+
const float phiPt = phiCandidate.Pt();
281189

282-
for (const auto& [kMinusId, kMinus] : kMinusEvent2) {
283-
ROOT::Math::PxPyPzMVector kMinusVec(
284-
kMinus.px,
285-
kMinus.py,
286-
kMinus.pz,
287-
o2::constants::physics::MassKPlus);
190+
if (phiMass < massMin || phiMass > massMax) {
191+
continue;
192+
}
288193

289-
auto phiMix = kPlusVec + kMinusVec;
194+
histos.fill(HIST("hPhiMassSame"), phiMass);
195+
histos.fill(HIST("hPhiPtSame"), phiPt);
196+
histos.fill(HIST("hSparseSame"), phiMass, phiPt, centrality);
290197

291-
histos.fill(HIST("hSparseMixed"), phiMix.M(), phiMix.Pt(), centrality);
292-
}
198+
nPhiSame++;
293199
}
294200
}
295-
// histos.fill(HIST("hNMixEventPairs"), nMixedEventPairs);
201+
202+
histos.fill(HIST("hNphiSamePerEvent"), nPhiSame);
296203
}
297-
PROCESS_SWITCH(phiflowder, processMixedData, "Process mixed-event phi candidates", false);
204+
205+
PROCESS_SWITCH(phiflowder, processSameData, "Process same-event K+K- pairs", true);
298206
};
299207

300208
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)