Skip to content

Commit a33b2cf

Browse files
committed
[PWGHF] new files for production of electrons from heavy-flavour hadron decays
1 parent fef755c commit a33b2cf

File tree

3 files changed

+238
-0
lines changed

3 files changed

+238
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### The external generator derives from GeneratorPythia8.
2+
[GeneratorExternal]
3+
fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C
4+
funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5)
5+
6+
[GeneratorPythia8]
7+
config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg
8+
includePartonEvent=true
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
int External() {
2+
std::string path{"o2sim_Kine.root"};
3+
4+
int checkPdgDecayElectron = 11;
5+
int checkPdgQuarkOne = 4;
6+
int checkPdgQuarkTwo = 5;
7+
float ratioTrigger = 1. / 5; // one event triggered out of 5
8+
9+
TFile file(path.c_str(), "READ");
10+
if (file.IsZombie()) {
11+
std::cerr << "Cannot open ROOT file" << path << "\n";
12+
return 1;
13+
}
14+
15+
auto tree = (TTree *)file.Get("o2sim");
16+
if (!tree) {
17+
std::cerr << "Cannot find tree o2sim in file" << path << "\n";
18+
return 1;
19+
}
20+
21+
std::vector<o2::MCTrack> *tracks{};
22+
tree->SetBranchAddress("MCTrack", &tracks);
23+
o2::dataformats::MCEventHeader *eventHeader = nullptr;
24+
tree->SetBranchAddress("MCEventHeader.", &eventHeader);
25+
26+
int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{};
27+
int nQuarksOne{}, nQuarksTwo{};
28+
int nElectrons{};
29+
auto nEvents = tree->GetEntries();
30+
31+
for (int i = 0; i < nEvents; i++) {
32+
tree->GetEntry(i);
33+
34+
// check subgenerator information
35+
if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) {
36+
bool isValid = false;
37+
int subGeneratorId = eventHeader->getInfo<int>(
38+
o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid);
39+
if (subGeneratorId == 0) {
40+
nEventsMB++;
41+
} else if (subGeneratorId == checkPdgQuarkOne) {
42+
nEventsInjOne++;
43+
} else if (subGeneratorId == checkPdgQuarkTwo) {
44+
nEventsInjTwo++;
45+
}
46+
} // if event header
47+
48+
int nelectronsev = 0;
49+
50+
for (auto &track : *tracks) {
51+
auto pdg = track.GetPdgCode();
52+
if (std::abs(pdg) == checkPdgQuarkOne) {
53+
nQuarksOne++;
54+
continue;
55+
}
56+
if (std::abs(pdg) == checkPdgQuarkTwo) {
57+
nQuarksTwo++;
58+
continue;
59+
}
60+
61+
auto y = track.GetRapidity();
62+
if (std::abs(pdg) == checkPdgDecayElectron) {
63+
int igmother = track.getMotherTrackId();
64+
auto gmTrack = (*tracks)[igmother];
65+
int gmpdg = gmTrack.GetPdgCode();
66+
if (int(std::abs(gmpdg) / 100.) == 4 ||
67+
int(std::abs(gmpdg) / 1000.) == 4 ||
68+
int(std::abs(gmpdg) / 100.) == 5 ||
69+
int(std::abs(gmpdg) / 1000.) == 5) {
70+
nElectrons++;
71+
nelectronsev++;
72+
} // gmpdg
73+
} // pdgdecay
74+
} // loop track
75+
// std::cout << "#electrons per event: " << nelectronsev << "\n";
76+
}
77+
78+
std::cout << "--------------------------------\n";
79+
std::cout << "# Events: " << nEvents << "\n";
80+
std::cout << "# MB events: " << nEventsMB << "\n";
81+
std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne)
82+
<< nEventsInjOne << "\n";
83+
std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo)
84+
<< nEventsInjTwo << "\n";
85+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne
86+
<< "\n";
87+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo
88+
<< "\n";
89+
90+
if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 ||
91+
nEventsMB > nEvents * (1 - ratioTrigger) *
92+
1.05) { // we put some tolerance since the number of
93+
// generated events is small
94+
std::cerr << "Number of generated MB events different than expected\n";
95+
return 1;
96+
}
97+
if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 ||
98+
nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) {
99+
std::cerr << "Number of generated events injected with " << checkPdgQuarkOne
100+
<< " different than expected\n";
101+
return 1;
102+
}
103+
if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 ||
104+
nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) {
105+
std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo
106+
<< " different than expected\n";
107+
return 1;
108+
}
109+
if (nQuarksOne <
110+
nEvents *
111+
ratioTrigger) { // we expect anyway more because the same quark is
112+
// repeated several time, after each gluon radiation
113+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne
114+
<< " lower than expected\n";
115+
return 1;
116+
}
117+
if (nQuarksTwo <
118+
nEvents *
119+
ratioTrigger) { // we expect anyway more because the same quark is
120+
// repeated several time, after each gluon radiation
121+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo
122+
<< " lower than expected\n";
123+
return 1;
124+
}
125+
std::cout << "#electrons: " << nElectrons << "\n";
126+
127+
return 0;
128+
} // external
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch)
2+
### Grazia Luparello (Grazia.Luparello@cern.ch)
3+
### Antonio Palasciano (antonio.palasciano@cern.ch)
4+
### Jonghan Park (jonghan@cern.ch)
5+
### electrons from heavy-flavour hadrons and from light neutral mesons
6+
### last update: August 2025
7+
8+
### beams
9+
Beams:idA 2212 # proton
10+
Beams:idB 2212 # proton
11+
Beams:eCM 13600. # GeV
12+
13+
### processes
14+
SoftQCD:inelastic on # all inelastic processes
15+
16+
### decays
17+
ParticleDecays:limitTau0 on
18+
ParticleDecays:tau0Max 10.
19+
20+
### switching on Pythia Mode2
21+
ColourReconnection:mode 1
22+
ColourReconnection:allowDoubleJunRem off
23+
ColourReconnection:m0 0.3
24+
ColourReconnection:allowJunctions on
25+
ColourReconnection:junctionCorrection 1.20
26+
ColourReconnection:timeDilationMode 2
27+
ColourReconnection:timeDilationPar 0.18
28+
StringPT:sigma 0.335
29+
StringZ:aLund 0.36
30+
StringZ:bLund 0.56
31+
StringFlav:probQQtoQ 0.078
32+
StringFlav:ProbStoUD 0.2
33+
StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275
34+
MultiPartonInteractions:pT0Ref 2.15
35+
BeamRemnants:remnantMode 1
36+
BeamRemnants:saturation 5
37+
38+
# Correct decay lengths (wrong in PYTHIA8 decay table)
39+
# Lb
40+
5122:tau0 = 0.4390
41+
# Xic0
42+
4132:tau0 = 0.0455
43+
# OmegaC
44+
4332:tau0 = 0.0803
45+
46+
47+
### switch off all decay channels
48+
111:onMode = off
49+
221:onMode = off
50+
51+
411:onMode = off
52+
421:onMode = off
53+
431:onMode = off
54+
4122:onMode = off
55+
4132:onMode = off
56+
4232:onMode = off
57+
4332:onMode = off
58+
59+
511:onMode = off
60+
521:onMode = off
61+
531:onMode = off
62+
5122:onMode = off
63+
5132:onMode = off
64+
5232:onMode = off
65+
5332:onMode = off
66+
67+
###Semimuonic decays of charm
68+
69+
### pi0 -> e
70+
111:onIfAny = 11 -11
71+
### eta -> e
72+
221:onIfAny = 11 -11
73+
74+
### D+/- -> e + X
75+
411:onIfAny = 11 -11
76+
### D0 -> e + X
77+
421:onIfAny = 11 -11
78+
### D_s -> e + X
79+
431:onIfAny = 11 -11
80+
### Lambda_c -> e + X
81+
4122:onIfAny = 11 -11
82+
### Xsi0_c -> e + X
83+
4132:onIfAny = 11 -11
84+
### Xsi+_c -> e + X
85+
4232:onIfAny = 11 -11
86+
### Omega_c -> e + X
87+
4332:onIfAny = 11 -11
88+
89+
### B0 -> e + X
90+
511:onIfAny = 11 -11
91+
### B+/- -> e + X
92+
521:onIfAny = 11 -11
93+
### B_s -> e + X
94+
531:onIfAny = 11 -11
95+
### Lambda_b -> e + X
96+
5122:onIfAny = 11 -11
97+
### Xsi_b -> e + X
98+
5132:onIfAny = 11 -11
99+
### Xsi0_b -> e + X
100+
5232:onIfAny = 11 -11
101+
### Omega_b -> e + X
102+
5332:onIfAny = 11 -11

0 commit comments

Comments
 (0)