Skip to content

Commit 3e5efc8

Browse files
committed
[PWGLF] Add hybrid PYTHIA8 generator for antideuteron coalescence in jets
1 parent 6f4f32d commit 3e5efc8

4 files changed

Lines changed: 169 additions & 16 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
{
3+
"mode": "sequential",
4+
"generators": [
5+
{
6+
"name": "pythia8",
7+
"config": {
8+
"config": "${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg",
9+
"hooksFileName": "",
10+
"hooksFuncName": "",
11+
"includePartonEvent": false,
12+
"particleFilter": "",
13+
"verbose": 0
14+
}
15+
},
16+
{
17+
"name": "external",
18+
"config": {
19+
"iniFile": "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/ini/GeneratorAntideuteronCoalescenceJet.ini"
20+
}
21+
}
22+
],
23+
"fractions": [4, 1]
24+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[GeneratorExternal]
2+
fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C
3+
funcName = generateCoalescence({-1000010020}, 1, 0.4)
4+
5+
[GeneratorPythia8]
6+
config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
#if !defined(__CLING__) || defined(__ROOTCLING__)
3+
#include "SimulationDataFormat/MCTrack.h"
4+
#include "TFile.h"
5+
#include "TTree.h"
6+
7+
#include <algorithm>
8+
#include <iostream>
9+
#include <string>
10+
#include <vector>
11+
#endif
12+
13+
int External()
14+
{
15+
std::string path{"o2sim_Kine.root"};
16+
17+
std::vector<int> injectedPDGs = {
18+
-1000010020 // anti-deuteron
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+
if (!tree) {
29+
std::cerr << "Cannot find tree o2sim in file " << path << "\n";
30+
return 1;
31+
}
32+
33+
std::vector<o2::MCTrack>* tracks = nullptr;
34+
tree->SetBranchAddress("MCTrack", &tracks);
35+
36+
std::vector<int> nSignal(injectedPDGs.size(), 0);
37+
std::vector<int> nEventsWithSignal(injectedPDGs.size(), 0);
38+
39+
const auto nEvents = tree->GetEntries();
40+
41+
for (Long64_t i = 0; i < nEvents; ++i) {
42+
tree->GetEntry(i);
43+
44+
std::vector<bool> found(injectedPDGs.size(), false);
45+
46+
for (const auto& track : *tracks) {
47+
const int pdg = track.GetPdgCode();
48+
49+
auto it = std::find(
50+
injectedPDGs.begin(),
51+
injectedPDGs.end(),
52+
pdg);
53+
54+
if (it != injectedPDGs.end()) {
55+
const auto index = std::distance(injectedPDGs.begin(), it);
56+
++nSignal[index];
57+
found[index] = true;
58+
}
59+
}
60+
61+
for (size_t j = 0; j < injectedPDGs.size(); ++j) {
62+
if (found[j]) {
63+
++nEventsWithSignal[j];
64+
}
65+
}
66+
}
67+
68+
std::cout << "--------------------------------\n";
69+
std::cout << "# Events: " << nEvents << "\n";
70+
71+
for (size_t i = 0; i < injectedPDGs.size(); ++i) {
72+
std::cout << "PDG: " << injectedPDGs[i] << "\n";
73+
std::cout << "# Generated particles: " << nSignal[i] << "\n";
74+
std::cout << "# Events containing particle: "
75+
<< nEventsWithSignal[i] << "\n";
76+
77+
if (nSignal[i] == 0) {
78+
std::cerr << "No generated particles with PDG "
79+
<< injectedPDGs[i] << "\n";
80+
return 1;
81+
}
82+
}
83+
84+
return 0;
85+
}

‎MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C‎

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "TDatabasePDG.h"
1010
#include "TSystem.h"
1111
#include "TMath.h"
12+
#include <algorithm>
1213
#include <cmath>
1314
#include <vector>
1415
#include <fstream>
@@ -18,20 +19,26 @@ using namespace Pythia8;
1819

1920
R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT)
2021
#include "MC/config/common/external/generator/CoalescencePythia8.h"
21-
/// First version of the simple coalescence generator based PYTHIA8
2222

23+
/// First version of the simple coalescence generator based on PYTHIA8
2324
class GeneratorPythia8Coalescence : public o2::eventgen::GeneratorPythia8
2425
{
2526
public:
2627
/// Constructor
27-
GeneratorPythia8Coalescence(std::vector<unsigned int> pdgList, int input_trigger_ratio = 1, double coal_momentum = 0.4)
28+
GeneratorPythia8Coalescence(std::vector<int> pdgList, int input_trigger_ratio = 1, double coal_momentum = 0.4)
2829
: o2::eventgen::GeneratorPythia8()
2930
{
3031
fmt::printf(">> Coalescence generator %d\n", input_trigger_ratio);
3132
mInverseTriggerRatio = input_trigger_ratio;
3233
mCoalMomentum = coal_momentum;
3334
mPdgList = pdgList;
35+
36+
// CoalescencePythia8 accepts unsigned PDG codes
37+
for (auto pdg : mPdgList) {
38+
mAbsPdgList.push_back(static_cast<unsigned int>(std::abs(pdg)));
39+
}
3440
}
41+
3542
/// Destructor
3643
~GeneratorPythia8Coalescence() = default;
3744

@@ -45,55 +52,86 @@ public:
4552
protected:
4653
bool generateEvent() override
4754
{
48-
fmt::printf(">> Generating event %d\n", mGeneratedEvents);
55+
fmt::printf(">> Generating event %llu\n",
56+
static_cast<unsigned long long>(mGeneratedEvents));
57+
4958
// Simple straightforward check to alternate generators
5059
if (mGeneratedEvents % mInverseTriggerRatio == 0)
5160
{
52-
fmt::printf(">> Generating coalescence event %d\n", mGeneratedEvents);
61+
fmt::printf(">> Generating coalescence event %llu\n",
62+
static_cast<unsigned long long>(mGeneratedEvents));
63+
5364
bool genOk = false;
5465
int localCounter{0};
66+
5567
while (!genOk)
5668
{
5769
if (GeneratorPythia8::generateEvent())
5870
{
59-
genOk = CoalescencePythia8(mPythia.event, mPdgList, mCoalMomentum);
71+
// Store the event size before coalescence
72+
const int originalSize = mPythia.event.size();
73+
74+
// Run coalescence with absolute PDG codes
75+
bool coalOk = CoalescencePythia8(
76+
mPythia.event, mAbsPdgList, false, mCoalMomentum);
77+
78+
if (coalOk && mPythia.event.size() > originalSize) {
79+
for (int i = originalSize; i < mPythia.event.size(); ++i) {
80+
const int producedPdg = mPythia.event[i].id();
81+
if (std::find(mPdgList.begin(), mPdgList.end(), producedPdg) != mPdgList.end()) {
82+
genOk = true;
83+
break;
84+
}
85+
}
86+
}
6087
}
88+
6189
localCounter++;
6290
}
63-
fmt::printf(">> Coalescence successful after %i generations\n", localCounter);
91+
92+
fmt::printf(">> Coalescence successful after %i generations\n",
93+
localCounter);
6494
std::cout << std::endl << std::endl;
6595
notifySubGenerator(1);
6696
}
6797
else
6898
{
69-
fmt::printf(">> Generating minimum-bias event %d\n", mGeneratedEvents);
99+
fmt::printf(">> Generating minimum-bias event %llu\n",
100+
static_cast<unsigned long long>(mGeneratedEvents));
101+
70102
// Generate minimum-bias event
71103
bool genOk = false;
72104
while (!genOk)
73105
{
74106
genOk = GeneratorPythia8::generateEvent();
75107
}
108+
76109
notifySubGenerator(0);
77110
}
111+
78112
mGeneratedEvents++;
79113
return true;
80114
}
81115

82-
83116
private:
84-
std::vector<unsigned int> mPdgList; /// list of pdg codes to be generated
85-
float mCoalMomentum = 0.4; /// coalescence momentum
86-
uint64_t mGeneratedEvents = 0; /// number of events generated so far
87-
int mInverseTriggerRatio = 1; /// injection gap
117+
std::vector<int> mPdgList; /// Signed PDG codes
118+
std::vector<unsigned int> mAbsPdgList; /// Absolute PDG codes for coalescence
119+
float mCoalMomentum = 0.4; /// Coalescence momentum
120+
uint64_t mGeneratedEvents = 0; /// Number of generated events
121+
int mInverseTriggerRatio = 1; /// Injection gap
88122
};
89123

90-
///___________________________________________________________
91-
FairGenerator *generateCoalescence(std::vector<unsigned int> pdgList, int input_trigger_ratio, double coal_momentum = 0.4)
124+
/// Factory function
125+
FairGenerator* generateCoalescence(std::vector<int> pdgList,
126+
int input_trigger_ratio,
127+
double coal_momentum = 0.4)
92128
{
93-
auto myGen = new GeneratorPythia8Coalescence(pdgList, input_trigger_ratio, coal_momentum);
129+
auto myGen = new GeneratorPythia8Coalescence(
130+
pdgList, input_trigger_ratio, coal_momentum);
131+
94132
auto seed = (gRandom->TRandom::GetSeed() % 900000000);
95133
myGen->readString("Random:setSeed on");
96134
myGen->readString("Random:seed " + std::to_string(seed));
135+
97136
return myGen;
98137
}
99-
///___________________________________________________________

0 commit comments

Comments
 (0)