Skip to content

Commit e373309

Browse files
fgrosachiarazampolli
authored andcommitted
PWGHF: add config for Pb-Pb MCs without pt hard bins for signal (#1743)
* PWGHF: add config for Pb-Pb MCs without pt hard bins for signal * Add missing config (cherry picked from commit c0c21b2)
1 parent eccab30 commit e373309

File tree

3 files changed

+163
-18
lines changed

3 files changed

+163
-18
lines changed

MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ public:
4545

4646
/// @brief setup the event generator for HF signals
4747
/// \param gentype generator type (only ccbar, only bbbar, both)
48+
/// \param usePtHardBins flag to enable/disable pt-hard bins
4849
/// \param yQuarkMin minimum quark rapidity
4950
/// \param yQuarkMax maximum quark rapidity
5051
/// \param yHadronMin minimum hadron rapidity
5152
/// \param yHadronMax maximum hadron rapidity
5253
/// \param hadronPdgList list of PDG codes for hadrons to be used in trigger
53-
void setupGeneratorEvHF(int genType, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector<int> hadronPdgList = {}) {
54+
void setupGeneratorEvHF(int genType, bool usePtHardBins, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector<int> hadronPdgList = {}) {
5455
mGeneratorEvHF = nullptr;
5556
switch (genType)
5657
{
@@ -80,18 +81,20 @@ public:
8081
}
8182

8283
// we set pT hard bins
83-
auto seed = dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->getUsedSeed();
84-
float ptHardBins[4] = {2.76, 20., 50., 1000.};
85-
int iPt{0};
86-
if (seed % 10 < 7) {
87-
iPt = 0;
88-
} else if (seed % 10 < 9) {
89-
iPt = 1;
90-
} else {
91-
iPt = 2;
84+
if (usePtHardBins) {
85+
auto seed = dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->getUsedSeed();
86+
float ptHardBins[4] = {2.76, 20., 50., 1000.};
87+
int iPt{0};
88+
if (seed % 10 < 7) {
89+
iPt = 0;
90+
} else if (seed % 10 < 9) {
91+
iPt = 1;
92+
} else {
93+
iPt = 2;
94+
}
95+
dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->readString(Form("PhaseSpace:pTHatMin = %f", ptHardBins[iPt]));
96+
dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->readString(Form("PhaseSpace:pTHatMax = %f", ptHardBins[iPt+1]));
9297
}
93-
dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->readString(Form("PhaseSpace:pTHatMin = %f", ptHardBins[iPt]));
94-
dynamic_cast<GeneratorPythia8GapTriggeredHF*>(mGeneratorEvHF)->readString(Form("PhaseSpace:pTHatMax = %f", ptHardBins[iPt+1]));
9598
mGeneratorEvHF->Init();
9699
}
97100

@@ -377,34 +380,34 @@ private:
377380
};
378381

379382
// Charm enriched
380-
FairGenerator * GeneratorPythia8EmbedHFCharm(float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
383+
FairGenerator * GeneratorPythia8EmbedHFCharm(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
381384
{
382385
auto myGen = new GeneratorPythia8EmbedHF();
383386

384387
/// setup the internal generator for HF events
385-
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
388+
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
386389

387390
return myGen;
388391
}
389392

390393
// Beauty enriched
391-
FairGenerator * GeneratorPythia8EmbedHFBeauty(float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
394+
FairGenerator * GeneratorPythia8EmbedHFBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
392395
{
393396
auto myGen = new GeneratorPythia8EmbedHF();
394397

395398
/// setup the internal generator for HF events
396-
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
399+
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
397400

398401
return myGen;
399402
}
400403

401404
// Charm and beauty enriched (with same ratio)
402-
FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
405+
FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector<int> hadronPdgList = {})
403406
{
404407
auto myGen = new GeneratorPythia8EmbedHF();
405408

406409
/// setup the internal generator for HF events
407-
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
410+
myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList);
408411

409412
return myGen;
410413
}
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_embed_hf.C
4+
funcName=GeneratorPythia8EmbedHFCharmAndBeauty(true)
5+
6+
[GeneratorPythia8]
7+
config=${O2DPG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV.cfg
8+
includePartonEvent=true
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
int External() {
2+
std::string path{"o2sim_Kine.root"};
3+
//std::string path{"tf1/sgn_1_Kine.root"};
4+
5+
int checkPdgQuarkOne{4};
6+
int checkPdgQuarkTwo{5};
7+
float ratioTrigger = 1.; // one event triggered out of 1
8+
float averagePt = 0.;
9+
10+
std::vector<int> checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332};
11+
std::map<int, std::vector<std::vector<int>>> checkHadronDecays{ // sorted pdg of daughters
12+
{411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+
13+
{421, {{-321, 211}, {-321, 111, 211}}}, // D0
14+
{431, {{211, 333}, {-313, 321}}}, // Ds+
15+
{4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+
16+
{4132, {{211, 3312}}}, // Xic0
17+
{4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+
18+
{4332, {{211, 3334}}} // Omegac+
19+
};
20+
21+
TFile file(path.c_str(), "READ");
22+
if (file.IsZombie()) {
23+
std::cerr << "Cannot open ROOT file " << path << "\n";
24+
return 1;
25+
}
26+
27+
auto tree = (TTree *)file.Get("o2sim");
28+
std::vector<o2::MCTrack> *tracks{};
29+
tree->SetBranchAddress("MCTrack", &tracks);
30+
o2::dataformats::MCEventHeader *eventHeader = nullptr;
31+
tree->SetBranchAddress("MCEventHeader.", &eventHeader);
32+
33+
int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{};
34+
int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{};
35+
auto nEvents = tree->GetEntries();
36+
37+
for (int i = 0; i < nEvents; i++) {
38+
tree->GetEntry(i);
39+
40+
// check subgenerator information
41+
//if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) {
42+
// bool isValid = false;
43+
// int subGeneratorId = eventHeader->getInfo<int>(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid);
44+
// if (subGeneratorId == 0) {
45+
// nEventsMB++;
46+
// } else if (subGeneratorId == checkPdgQuarkOne) {
47+
// nEventsInjOne++;
48+
// } else if (subGeneratorId == checkPdgQuarkTwo) {
49+
// nEventsInjTwo++;
50+
// }
51+
//}
52+
53+
for (auto &track : *tracks) {
54+
auto pdg = track.GetPdgCode();
55+
if (std::abs(pdg) == checkPdgQuarkOne) {
56+
nQuarksOne++;
57+
continue;
58+
}
59+
if (std::abs(pdg) == checkPdgQuarkTwo) {
60+
nQuarksTwo++;
61+
continue;
62+
}
63+
if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal
64+
nSignals++; // count signal PDG
65+
averagePt += track.GetPt();
66+
67+
std::vector<int> pdgsDecay{};
68+
std::vector<int> pdgsDecayAntiPart{};
69+
for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) {
70+
auto pdgDau = tracks->at(j).GetPdgCode();
71+
pdgsDecay.push_back(pdgDau);
72+
if (pdgDau != 333) { // phi is antiparticle of itself
73+
pdgsDecayAntiPart.push_back(-pdgDau);
74+
} else {
75+
pdgsDecayAntiPart.push_back(pdgDau);
76+
}
77+
}
78+
79+
std::sort(pdgsDecay.begin(), pdgsDecay.end());
80+
std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end());
81+
82+
for (auto &decay : checkHadronDecays[std::abs(pdg)]) {
83+
if (pdgsDecay == decay || pdgsDecayAntiPart == decay) {
84+
nSignalGoodDecay++;
85+
break;
86+
}
87+
}
88+
}
89+
}
90+
}
91+
92+
averagePt /= nSignals;
93+
94+
std::cout << "--------------------------------\n";
95+
std::cout << "# Events: " << nEvents << "\n";
96+
//std::cout << "# MB events: " << nEventsMB << "\n";
97+
//std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n";
98+
//std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n";
99+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n";
100+
std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n";
101+
std::cout <<"# signal hadrons: " << nSignals << "\n";
102+
std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n";
103+
std::cout <<"average pT of signal hadrons: " << averagePt << "\n";
104+
105+
//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
106+
// std::cerr << "Number of generated MB events different than expected\n";
107+
// return 1;
108+
//}
109+
//if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) {
110+
// std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n";
111+
// return 1;
112+
//}
113+
//if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) {
114+
// std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n";
115+
// return 1;
116+
//}
117+
118+
if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation
119+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n";
120+
return 1;
121+
}
122+
if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation
123+
std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n";
124+
return 1;
125+
}
126+
127+
float fracForcedDecays = float(nSignalGoodDecay) / nSignals;
128+
if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state)
129+
std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n";
130+
return 1;
131+
}
132+
133+
return 0;
134+
}

0 commit comments

Comments
 (0)