Skip to content

Commit b43e45c

Browse files
authored
[PWGHF] Add a method for electron source selection (#12541)
1 parent 26354ff commit b43e45c

File tree

1 file changed

+325
-9
lines changed

1 file changed

+325
-9
lines changed

PWGHF/HFL/Tasks/taskSingleElectron.cxx

Lines changed: 325 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,44 @@ using namespace o2::constants::math;
2727
using namespace o2::framework;
2828
using namespace o2::framework::expressions;
2929

30+
enum PdgCode {
31+
kEta = 221,
32+
kOmega = 223,
33+
kPhi = 333,
34+
kEtaPrime = 331
35+
};
36+
37+
enum SourceType {
38+
NotElec = 0, // not electron
39+
DirectCharm = 1, // electrons from prompt charm hadrons
40+
DirectBeauty = 2, // electrons from primary beauty hadrons
41+
BeautyCharm = 3, // electrons from non-prompt charm hadrons
42+
DirectGamma = 4, // electrons from direct photon
43+
GammaPi0 = 5,
44+
GammaEta = 6,
45+
GammaOmega = 7,
46+
GammaPhi = 8,
47+
GammaEtaPrime = 9,
48+
GammaRho0 = 10,
49+
GammaK0s = 11,
50+
GammaK0l = 12,
51+
GammaKe3 = 13,
52+
GammaLambda0 = 14,
53+
GammaSigma = 15,
54+
Pi0 = 16,
55+
Eta = 17,
56+
Omega = 18,
57+
Phi = 19,
58+
EtaPrime = 20,
59+
Rho0 = 21,
60+
K0s = 22,
61+
K0l = 23,
62+
Ke3 = 24,
63+
Lambda0 = 25,
64+
Sigma = 26,
65+
Else = 27
66+
};
67+
3068
struct HfTaskSingleElectron {
3169

3270
// Produces
@@ -55,6 +93,7 @@ struct HfTaskSingleElectron {
5593
// using declarations
5694
using MyCollisions = soa::Join<aod::Collisions, aod::EvSels>;
5795
using TracksEl = soa::Join<aod::Tracks, aod::TrackExtra, aod::TracksDCA, aod::pidTOFFullEl, aod::pidTPCFullEl>;
96+
using McTracksEl = soa::Join<aod::Tracks, aod::TrackExtra, aod::TracksDCA, aod::pidTOFFullEl, aod::pidTPCFullEl, aod::McTrackLabels>;
5897

5998
// Filter
6099
Filter collZFilter = nabs(aod::collision::posZ) < posZMax;
@@ -79,7 +118,6 @@ struct HfTaskSingleElectron {
79118
void init(InitContext const&)
80119
{
81120
// create histograms
82-
histos.add("hEventCounter", "hEventCounter", kTH1F, {axisEvt});
83121
histos.add("nEvents", "Number of events", kTH1F, {{1, 0., 1.}});
84122
histos.add("VtxZ", "VtxZ; cm; entries", kTH1F, {axisPosZ});
85123
histos.add("etaTrack", "etaTrack; #eta; entries", kTH1F, {axisEta});
@@ -102,6 +140,16 @@ struct HfTaskSingleElectron {
102140

103141
// track impact parameter
104142
histos.add("dcaTrack", "", kTH2F, {{axisPtEl}, {axisTrackIp}});
143+
histos.add("dcaBeauty", "", kTH2F, {{axisPtEl}, {axisTrackIp}});
144+
histos.add("dcaCharm", "", kTH2F, {{axisPtEl}, {axisTrackIp}});
145+
histos.add("dcaDalitz", "", kTH2F, {{axisPtEl}, {axisTrackIp}});
146+
histos.add("dcaConv", "", kTH2F, {{axisPtEl}, {axisTrackIp}});
147+
148+
// QA plots for MC
149+
histos.add("hPdgC", "", kTH1F, {{10001, -0.5, 10000.5}});
150+
histos.add("hPdgB", "", kTH1F, {{10001, -0.5, 10000.5}});
151+
histos.add("hPdgDa", "", kTH1F, {{10001, -0.5, 10000.5}});
152+
histos.add("hPdgCo", "", kTH1F, {{10001, -0.5, 10000.5}});
105153
}
106154

107155
template <typename TrackType>
@@ -138,24 +186,267 @@ struct HfTaskSingleElectron {
138186
return true;
139187
}
140188

141-
void process(soa::Filtered<MyCollisions>::iterator const& collision,
142-
TracksEl const& tracks)
189+
template <typename TrackType>
190+
int getElecSource(const TrackType& track, double& mpt, int& mpdg)
191+
{
192+
auto mcpart = track.mcParticle();
193+
if (std::abs(mcpart.pdgCode()) != kElectron) {
194+
return NotElec;
195+
}
196+
197+
int motherPdg = -999;
198+
int grmotherPdg = -999;
199+
int ggrmotherPdg = -999; // mother, grand mother, grand grand mother pdg
200+
int motherPt = -999.;
201+
int grmotherPt = -999;
202+
int ggrmotherPt = -999.; // mother, grand mother, grand grand mother pt
203+
204+
auto partMother = mcpart.template mothers_as<aod::McParticles>(); // first mother particle of electron
205+
auto partMotherCopy = partMother; // copy of the first mother
206+
auto mctrack = partMother; // will change all the time
207+
208+
motherPt = partMother.front().pt(); // first mother pt
209+
motherPdg = std::abs(partMother.front().pdgCode()); // first mother pdg
210+
mpt = motherPt; // copy of first mother pt
211+
mpdg = motherPdg; // copy of first mother pdg
212+
213+
// check if electron from charm hadrons
214+
if ((static_cast<int>(motherPdg / 100.) % 10) == kCharm || (static_cast<int>(motherPdg / 1000.) % 10) == kCharm) {
215+
216+
// iterate until B hadron is found as an ancestor
217+
while (partMother.size()) {
218+
mctrack = partMother.front().template mothers_as<aod::McParticles>();
219+
if (mctrack.size()) {
220+
auto const& grmothersIdsVec = mctrack.front().mothersIds();
221+
222+
if (grmothersIdsVec.empty()) {
223+
return DirectCharm;
224+
} else {
225+
grmotherPt = mctrack.front().pt();
226+
grmotherPdg = std::abs(mctrack.front().pdgCode());
227+
if ((static_cast<int>(grmotherPdg / 100.) % 10) == kBottom || (static_cast<int>(grmotherPdg / 1000.) % 10) == kBottom) {
228+
mpt = grmotherPt;
229+
mpdg = grmotherPdg;
230+
return BeautyCharm;
231+
}
232+
}
233+
}
234+
partMother = mctrack;
235+
}
236+
} else if ((static_cast<int>(motherPdg / 100.) % 10) == kBottom || (static_cast<int>(motherPdg / 1000.) % 10) == kBottom) { // check if electron from beauty hadrons
237+
return DirectBeauty;
238+
} else if (motherPdg == kGamma) { // check if electron from photon conversion
239+
mctrack = partMother.front().template mothers_as<aod::McParticles>();
240+
if (mctrack.size()) {
241+
auto const& grmothersIdsVec = mctrack.front().mothersIds();
242+
if (grmothersIdsVec.empty()) {
243+
return DirectGamma;
244+
} else {
245+
grmotherPdg = std::abs(mctrack.front().pdgCode());
246+
mpdg = grmotherPdg;
247+
mpt = mctrack.front().pt();
248+
249+
partMother = mctrack;
250+
mctrack = partMother.front().template mothers_as<aod::McParticles>();
251+
if (mctrack.size()) {
252+
auto const& ggrmothersIdsVec = mctrack.front().mothersIds();
253+
if (ggrmothersIdsVec.empty()) {
254+
if (grmotherPdg == kPi0) {
255+
return GammaPi0;
256+
} else if (grmotherPdg == kEta) {
257+
return GammaEta;
258+
} else if (grmotherPdg == kOmega) {
259+
return GammaOmega;
260+
} else if (grmotherPdg == kPhi) {
261+
return GammaPhi;
262+
} else if (grmotherPdg == kEtaPrime) {
263+
return GammaEtaPrime;
264+
} else if (grmotherPdg == kRho770_0) {
265+
return GammaRho0;
266+
} else {
267+
return Else;
268+
}
269+
} else {
270+
ggrmotherPdg = mctrack.front().pdgCode();
271+
ggrmotherPt = mctrack.front().pt();
272+
mpdg = ggrmotherPdg;
273+
mpt = ggrmotherPt;
274+
if (grmotherPdg == kPi0) {
275+
if (ggrmotherPdg == kK0Short) {
276+
return GammaK0s;
277+
} else if (ggrmotherPdg == kK0Long) {
278+
return GammaK0l;
279+
} else if (ggrmotherPdg == kKPlus) {
280+
return GammaKe3;
281+
} else if (ggrmotherPdg == kLambda0) {
282+
return GammaLambda0;
283+
} else if (ggrmotherPdg == kSigmaPlus) {
284+
return GammaSigma;
285+
} else {
286+
mpdg = grmotherPdg;
287+
mpt = grmotherPt;
288+
return GammaPi0;
289+
}
290+
} else if (grmotherPdg == kEta) {
291+
mpdg = grmotherPdg;
292+
mpt = grmotherPt;
293+
return GammaEta;
294+
} else if (grmotherPdg == kOmega) {
295+
mpdg = grmotherPdg;
296+
mpt = grmotherPt;
297+
return GammaOmega;
298+
} else if (grmotherPdg == kPhi) {
299+
mpdg = grmotherPdg;
300+
mpt = grmotherPt;
301+
return GammaPhi;
302+
} else if (grmotherPdg == kEtaPrime) {
303+
mpdg = grmotherPdg;
304+
mpt = grmotherPt;
305+
return GammaEtaPrime;
306+
} else if (grmotherPdg == kRho770_0) {
307+
mpdg = grmotherPdg;
308+
mpt = grmotherPt;
309+
return GammaRho0;
310+
} else {
311+
return Else;
312+
}
313+
}
314+
}
315+
}
316+
}
317+
} else { // check if electron from Dalitz decays
318+
mctrack = partMother.front().template mothers_as<aod::McParticles>();
319+
if (mctrack.size()) {
320+
auto const& grmothersIdsVec = mctrack.front().mothersIds();
321+
if (grmothersIdsVec.empty()) {
322+
if (motherPdg == kPi0) {
323+
return Pi0;
324+
} else if (motherPdg == kEta) {
325+
return Eta;
326+
} else if (motherPdg == kOmega) {
327+
return Omega;
328+
} else if (motherPdg == kPhi) {
329+
return Phi;
330+
} else if (motherPdg == kEtaPrime) {
331+
return EtaPrime;
332+
} else if (motherPdg == kRho770_0) {
333+
return Rho0;
334+
} else if (motherPdg == kKPlus) {
335+
return Ke3;
336+
} else if (motherPdg == kK0Long) {
337+
return K0l;
338+
} else {
339+
return Else;
340+
}
341+
} else {
342+
if (motherPdg == kPi0) {
343+
grmotherPt = mctrack.front().pt();
344+
grmotherPdg = mctrack.front().pdgCode();
345+
mpt = grmotherPt;
346+
mpdg = grmotherPdg;
347+
if (grmotherPdg == kK0Short) {
348+
return K0s;
349+
} else if (grmotherPdg == kK0Long) {
350+
return K0l;
351+
} else if (grmotherPdg == kKPlus) {
352+
return Ke3;
353+
} else if (grmotherPdg == kLambda0) {
354+
return Lambda0;
355+
} else if (grmotherPdg == kSigmaPlus) {
356+
return Sigma;
357+
} else {
358+
mpt = motherPt;
359+
mpdg = motherPdg;
360+
return Pi0;
361+
}
362+
} else if (motherPdg == kEta) {
363+
return Eta;
364+
} else if (motherPdg == kOmega) {
365+
return Omega;
366+
} else if (motherPdg == kPhi) {
367+
return Phi;
368+
} else if (motherPdg == kEtaPrime) {
369+
return EtaPrime;
370+
} else if (motherPdg == kRho770_0) {
371+
return Rho0;
372+
} else if (motherPdg == kKPlus) {
373+
return Ke3;
374+
} else if (motherPdg == kK0Long) {
375+
return K0l;
376+
} else {
377+
return Else;
378+
}
379+
}
380+
}
381+
}
382+
383+
return Else;
384+
}
385+
386+
void processData(soa::Filtered<MyCollisions>::iterator const& collision,
387+
TracksEl const& tracks)
388+
{
389+
float flagAnalysedEvt = 0.5;
390+
391+
if (!collision.sel8()) {
392+
return;
393+
}
394+
395+
if (collision.numContrib() < nContribMin) {
396+
return;
397+
}
398+
399+
histos.fill(HIST("VtxZ"), collision.posZ());
400+
histos.fill(HIST("nEvents"), flagAnalysedEvt);
401+
402+
for (const auto& track : tracks) {
403+
404+
if (!trackSel(track)) {
405+
continue;
406+
}
407+
408+
histos.fill(HIST("etaTrack"), track.eta());
409+
histos.fill(HIST("ptTrack"), track.pt());
410+
411+
histos.fill(HIST("tpcNClsTrack"), track.tpcNClsCrossedRows());
412+
histos.fill(HIST("tpcFoundFindableTrack"), track.tpcCrossedRowsOverFindableCls());
413+
histos.fill(HIST("tpcChi2Track"), track.tpcChi2NCl());
414+
histos.fill(HIST("itsIBClsTrack"), track.itsNClsInnerBarrel());
415+
histos.fill(HIST("dcaXYTrack"), track.dcaXY());
416+
histos.fill(HIST("dcaZTrack"), track.dcaZ());
417+
418+
histos.fill(HIST("tofNSigPt"), track.pt(), track.tofNSigmaEl());
419+
histos.fill(HIST("tpcNSigPt"), track.pt(), track.tpcNSigmaEl());
420+
421+
if (std::abs(track.tofNSigmaEl()) > tofNSigmaMax) {
422+
continue;
423+
}
424+
histos.fill(HIST("tofNSigPtQA"), track.pt(), track.tofNSigmaEl());
425+
histos.fill(HIST("tpcNSigPtAfterTofCut"), track.pt(), track.tpcNSigmaEl());
426+
427+
if (track.tpcNSigmaEl() < tpcNSigmaMin || track.tpcNSigmaEl() > tpcNSigmaMax) {
428+
continue;
429+
}
430+
histos.fill(HIST("tpcNSigPtQA"), track.pt(), track.tpcNSigmaEl());
431+
432+
histos.fill(HIST("dcaTrack"), track.pt(), track.dcaXY());
433+
}
434+
}
435+
PROCESS_SWITCH(HfTaskSingleElectron, processData, "For real data", true);
436+
437+
void processMc(soa::Filtered<MyCollisions>::iterator const& collision,
438+
McTracksEl const& tracks,
439+
aod::McParticles const&)
143440
{
144-
float flagEventFill = 0.5;
145441
float flagAnalysedEvt = 0.5;
146-
histos.fill(HIST("hEventCounter"), flagEventFill);
147442

148443
if (!collision.sel8()) {
149444
return;
150445
}
151-
flagEventFill += 1.;
152-
histos.fill(HIST("hEventCounter"), flagEventFill);
153446

154447
if (collision.numContrib() < nContribMin) {
155448
return;
156449
}
157-
flagEventFill += 1.;
158-
histos.fill(HIST("hEventCounter"), flagEventFill);
159450

160451
histos.fill(HIST("VtxZ"), collision.posZ());
161452
histos.fill(HIST("nEvents"), flagAnalysedEvt);
@@ -179,6 +470,30 @@ struct HfTaskSingleElectron {
179470
histos.fill(HIST("tofNSigPt"), track.pt(), track.tofNSigmaEl());
180471
histos.fill(HIST("tpcNSigPt"), track.pt(), track.tpcNSigmaEl());
181472

473+
int mpdg; // electron source pdg code
474+
double mpt; // electron source pt
475+
int source = getElecSource(track, mpt, mpdg);
476+
477+
if (source == DirectBeauty || source == BeautyCharm) {
478+
histos.fill(HIST("hPdgB"), mpdg);
479+
histos.fill(HIST("dcaBeauty"), track.pt(), track.dcaXY());
480+
}
481+
482+
if (source == DirectCharm) {
483+
histos.fill(HIST("hPdgC"), mpdg);
484+
histos.fill(HIST("dcaCharm"), track.pt(), track.dcaXY());
485+
}
486+
487+
if (source >= GammaPi0 && source <= GammaSigma) {
488+
histos.fill(HIST("hPdgCo"), mpdg);
489+
histos.fill(HIST("dcaConv"), track.pt(), track.dcaXY());
490+
}
491+
492+
if (source >= Pi0 && source <= Sigma) {
493+
histos.fill(HIST("hPdgDa"), mpdg);
494+
histos.fill(HIST("dcaDalitz"), track.pt(), track.dcaXY());
495+
}
496+
182497
if (std::abs(track.tofNSigmaEl()) > tofNSigmaMax) {
183498
continue;
184499
}
@@ -193,6 +508,7 @@ struct HfTaskSingleElectron {
193508
histos.fill(HIST("dcaTrack"), track.pt(), track.dcaXY());
194509
}
195510
}
511+
PROCESS_SWITCH(HfTaskSingleElectron, processMc, "For real data", false);
196512
};
197513

198514
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)