Skip to content

Commit a8b8cfb

Browse files
fgrosaBenedikt Volkel
authored andcommitted
PWGHF: Add configuration for sim with pT-hard bins (no gap) (#1553)
(cherry picked from commit 9ef1e81)
1 parent 9a196d1 commit a8b8cfb

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-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_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C
4+
funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(1, -1.5, 1.5)
5+
6+
[GeneratorPythia8]
7+
config=${O2DPG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_ptHardBins.cfg
8+
includePartonEvent=true
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
int External() {
2+
std::string path{"o2sim_Kine.root"};
3+
4+
int checkPdgQuarkOne{4};
5+
int checkPdgQuarkTwo{5};
6+
float ratioTrigger = 1.; // each event triggered
7+
float averagePt = 0.;
8+
9+
std::vector<int> checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332};
10+
std::map<int, std::vector<std::vector<int>>> checkHadronDecays{ // sorted pdg of daughters
11+
{411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+
12+
{421, {{-321, 211}, {-321, 111, 211}}}, // D0
13+
{431, {{211, 333}, {-313, 321}}}, // Ds+
14+
{4122, {{-313, 2212}, {-321, 2224}, {211, 3124}, {-321, 211, 2212}, {311, 2212}}}, // Lc+
15+
{4132, {{211, 3312}}}, // Xic0
16+
{4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+
17+
{4332, {{211, 3334}}} // Omegac+
18+
};
19+
20+
TFile file(path.c_str(), "READ");
21+
if (file.IsZombie()) {
22+
std::cerr << "Cannot open ROOT file " << path << "\n";
23+
return 1;
24+
}
25+
26+
auto tree = (TTree *)file.Get("o2sim");
27+
std::vector<o2::MCTrack> *tracks{};
28+
tree->SetBranchAddress("MCTrack", &tracks);
29+
o2::dataformats::MCEventHeader *eventHeader = nullptr;
30+
tree->SetBranchAddress("MCEventHeader.", &eventHeader);
31+
32+
int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{};
33+
int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{};
34+
auto nEvents = tree->GetEntries();
35+
36+
for (int i = 0; i < nEvents; i++) {
37+
tree->GetEntry(i);
38+
39+
// check subgenerator information
40+
if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) {
41+
bool isValid = false;
42+
int subGeneratorId = eventHeader->getInfo<int>(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid);
43+
if (subGeneratorId == 0) {
44+
nEventsMB++;
45+
} else if (subGeneratorId == checkPdgQuarkOne) {
46+
nEventsInjOne++;
47+
} else if (subGeneratorId == checkPdgQuarkTwo) {
48+
nEventsInjTwo++;
49+
}
50+
}
51+
52+
for (auto &track : *tracks) {
53+
auto pdg = track.GetPdgCode();
54+
if (std::abs(pdg) == checkPdgQuarkOne) {
55+
nQuarksOne++;
56+
continue;
57+
}
58+
if (std::abs(pdg) == checkPdgQuarkTwo) {
59+
nQuarksTwo++;
60+
continue;
61+
}
62+
if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal
63+
nSignals++; // count signal PDG
64+
averagePt += track.GetPt();
65+
66+
std::vector<int> pdgsDecay{};
67+
std::vector<int> pdgsDecayAntiPart{};
68+
for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) {
69+
auto pdgDau = tracks->at(j).GetPdgCode();
70+
pdgsDecay.push_back(pdgDau);
71+
if (pdgDau != 333) { // phi is antiparticle of itself
72+
pdgsDecayAntiPart.push_back(-pdgDau);
73+
} else {
74+
pdgsDecayAntiPart.push_back(pdgDau);
75+
}
76+
}
77+
78+
std::sort(pdgsDecay.begin(), pdgsDecay.end());
79+
std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end());
80+
81+
for (auto &decay : checkHadronDecays[std::abs(pdg)]) {
82+
if (pdgsDecay == decay || pdgsDecayAntiPart == decay) {
83+
nSignalGoodDecay++;
84+
break;
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
averagePt /= nSignals;
92+
93+
std::cout << "--------------------------------\n";
94+
std::cout << "# Events: " << nEvents << "\n";
95+
std::cout << "# MB events: " << nEventsMB << "\n";
96+
std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n";
97+
std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n";
98+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n";
99+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n";
100+
std::cout <<"# signal hadrons: " << nSignals << "\n";
101+
std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n";
102+
std::cout <<"average pT of signal hadrons: " << averagePt << "\n";
103+
104+
if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small
105+
std::cerr << "Number of generated MB events different than expected\n";
106+
return 1;
107+
}
108+
if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) {
109+
std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n";
110+
return 1;
111+
}
112+
if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) {
113+
std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n";
114+
return 1;
115+
}
116+
117+
if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation
118+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n";
119+
return 1;
120+
}
121+
if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation
122+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n";
123+
return 1;
124+
}
125+
126+
float fracForcedDecays = float(nSignalGoodDecay) / nSignals;
127+
if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state)
128+
std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n";
129+
return 1;
130+
}
131+
132+
if (averagePt < 8.) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD)
133+
std::cerr << "Average pT of charmed hadrons " << averagePt << " lower than expected\n";
134+
return 1;
135+
}
136+
137+
return 0;
138+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch)
2+
### Cristina Terrevoli (cristina.terrevoli@cern.ch)
3+
### Fabio Catalano (fabio.catalano@cern.ch)
4+
### last update: March 2024
5+
6+
### beams
7+
Beams:idA 2212 # proton
8+
Beams:idB 2212 # proton
9+
Beams:eCM 13600. # GeV
10+
11+
### processes: c-cbar and b-bbar processes
12+
HardQCD:hardccbar on
13+
HardQCD:hardbbbar on
14+
HardQCD:gg2ccbar on
15+
HardQCD:qqbar2ccbar on
16+
HardQCD:gg2bbbar on
17+
HardQCD:qqbar2bbbar on
18+
19+
### decays
20+
ParticleDecays:limitTau0 on
21+
ParticleDecays:tau0Max 10.
22+
23+
### switching on Pythia Mode2
24+
ColourReconnection:mode 1
25+
ColourReconnection:allowDoubleJunRem off
26+
ColourReconnection:m0 0.3
27+
ColourReconnection:allowJunctions on
28+
ColourReconnection:junctionCorrection 1.20
29+
ColourReconnection:timeDilationMode 2
30+
ColourReconnection:timeDilationPar 0.18
31+
StringPT:sigma 0.335
32+
StringZ:aLund 0.36
33+
StringZ:bLund 0.56
34+
StringFlav:probQQtoQ 0.078
35+
StringFlav:ProbStoUD 0.2
36+
StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275
37+
MultiPartonInteractions:pT0Ref 2.15
38+
BeamRemnants:remnantMode 1
39+
BeamRemnants:saturation 5
40+
41+
### pT-hard bins
42+
PhaseSpace:pTHatMin = 20
43+
PhaseSpace:pTHatMax = 200
44+
45+
# Correct decay lengths (wrong in PYTHIA8 decay table)
46+
# Lb
47+
5122:tau0 = 0.4390
48+
# Xic0
49+
4132:tau0 = 0.0455
50+
# OmegaC
51+
4332:tau0 = 0.0803
52+
53+
### Force golden charm hadrons decay modes for D2H studies
54+
### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other
55+
411:oneChannel = 1 0.0752 0 -321 211 211
56+
411:addChannel = 1 0.0104 0 -313 211
57+
411:addChannel = 1 0.0156 0 311 211
58+
411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi
59+
## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other
60+
4122:oneChannel = 1 0.0196 100 2212 -313
61+
4122:addChannel = 1 0.0108 100 2224 -321
62+
4122:addChannel = 1 0.022 100 3124 211
63+
4122:addChannel = 1 0.035 0 2212 -321 211
64+
4122:addChannel = 1 0.0159 0 2212 311
65+
### add Xic+ decays absent in PYTHIA8 decay table
66+
4232:addChannel = 1 0.2 0 2212 -313
67+
4232:addChannel = 1 0.2 0 2212 -321 211
68+
4232:addChannel = 1 0.2 0 3324 211
69+
4232:addChannel = 1 0.2 0 3312 211 211
70+
### add Xic0 decays absent in PYTHIA8 decay table
71+
4132:addChannel = 1 0.0143 0 3312 211
72+
### add OmegaC decays absent in PYTHIA8 decay table
73+
4332:addChannel = 1 0.5 0 3334 211
74+
4332:addChannel = 1 0.5 0 3312 211
75+
76+
### K* -> K pi
77+
313:onMode = off
78+
313:onIfAll = 321 211
79+
### for Ds -> Phi pi+
80+
333:onMode = off
81+
333:onIfAll = 321 321
82+
### for D0 -> rho0 pi+ k-
83+
113:onMode = off
84+
113:onIfAll = 211 211
85+
### for Lambda_c -> Delta++ K-
86+
2224:onMode = off
87+
2224:onIfAll = 2212 211
88+
### for Lambda_c -> Lambda(1520) K-
89+
102134:onMode = off
90+
102134:onIfAll = 2212 321
91+
### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p
92+
### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p
93+
3312:onMode = off
94+
3312:onIfAll = 3122 -211
95+
3122:onMode = off
96+
3122:onIfAll = 2212 -211
97+
### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p
98+
3334:onMode = off
99+
3334:onIfAll = 3122 -321
100+
101+
### switch off all decay channels
102+
411:onMode = off
103+
421:onMode = off
104+
431:onMode = off
105+
4112:onMode = off
106+
4122:onMode = off
107+
4232:onMode = off
108+
4132:onMode = off
109+
443:onMode = off
110+
4332:onMode = off
111+
112+
### D0 -> K pi
113+
421:onIfMatch = 321 211
114+
115+
### D+/- -> K pi pi
116+
411:onIfMatch = 321 211 211
117+
### D+/- -> K* pi
118+
411:onIfMatch = 313 211
119+
### D+/- -> phi pi
120+
411:onIfMatch = 333 211
121+
122+
### D_s -> K K*
123+
431:onIfMatch = 321 313
124+
### D_s -> Phi pi
125+
431:onIfMatch = 333 211
126+
127+
### Lambda_c -> p K*
128+
4122:onIfMatch = 2212 313
129+
### Lambda_c -> Delta K
130+
4122:onIfMatch = 2224 321
131+
### Lambda_c -> Lambda(1520) pi
132+
4122:onIfMatch = 3124 211
133+
### Lambda_c -> p K pi
134+
4122:onIfMatch = 2212 321 211
135+
### Lambda_c -> pK0s
136+
4122:onIfMatch = 2212 311
137+
138+
### Xic+ -> pK*0
139+
4232:onIfMatch = 2212 313
140+
### Xic+ -> p K- pi+
141+
4232:onIfMatch = 2212 321 211
142+
### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+
143+
4232:onIfMatch = 3324 211
144+
### Xic+ -> Xi- pi+ pi+
145+
4232:onIfMatch = 3312 211 211
146+
147+
### Xic0 -> Xi- pi+
148+
4132:onIfMatch = 3312 211
149+
150+
### Omega_c -> Omega pi
151+
4332:onIfMatch = 3334 211
152+
### Omega_c -> Xi pi
153+
4332:onIfMatch = 3312 211

0 commit comments

Comments
 (0)