Skip to content

Commit 8912261

Browse files
committed
Appended the injected event in MB correctly
1 parent 2cc0f9a commit 8912261

1 file changed

Lines changed: 57 additions & 75 deletions

File tree

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

Lines changed: 57 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "Pythia8/Pythia.h"
77
#include "TRandom3.h"
88
#include "TMath.h"
9-
// #include "TF1.h"
109
#include "TParticle.h"
1110
#include "TSystem.h"
1211
#if __has_include("SimulationDataFormat/MCGenStatus.h")
@@ -19,15 +18,9 @@
1918
#endif
2019
#include <cmath>
2120
#include <string>
21+
#include <vector>
2222
#endif
2323

24-
// Double_t FuncLavy(Double_t *x, Double_t *par)
25-
// {
26-
27-
// Double_t p = (par[0] - 1) * (par[0] - 2) * par[1] * x[0] / (((pow((1 + (((sqrt((par[2] * par[2]) + (x[0] * x[0]))) - par[2]) / (par[0] * par[3]))), par[0]) * (par[0] * par[3] * ((par[0] * par[3]) + (par[2] * (par[0] - 2)))))));
28-
// return (p);
29-
// }
30-
3124
class GeneratorPhiResonance : public o2::eventgen::GeneratorPythia8
3225
{
3326
public:
@@ -38,21 +31,30 @@ public:
3831
int signalInterval = 3)
3932
: GeneratorPythia8(), mResoPDG(resoPDG), mPtMin(ptMin), mPtMaxPhiPhi(ptMax), mYMin(yMin), mYMax(yMax), mSignalInterval(signalInterval)
4033
{
41-
// 1. Initialize Gun Pythia object & define custom resonance
42-
// # id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0
34+
35+
// 1. Define Custom Signal Resonance (PDG: 999999) decay into standard Phis (333 333)
4336
std::string createReso = std::to_string(mResoPDG) + ":new = f2_Custom void 5 0 0 2.714 0.012 2.05 3.50 0.0";
44-
mPythiaGun.readString(createReso);
45-
mPythiaGun.readString(std::to_string(mResoPDG) + ":mayDecay = on");
46-
// id:addChannel = onMode bRatio meMode product1 product2, (onMode = 1: allow decay, bRatio = branching ratio, meMode = matrix element mode where 0 is isotropic decay)
47-
std::string addDecay = std::to_string(mResoPDG) + ":addChannel = 1 1.0 0 333 333";
48-
mPythiaGun.readString(addDecay);
37+
std::string resoMayDecay = std::to_string(mResoPDG) + ":mayDecay = on";
38+
std::string addResoDecay = std::to_string(mResoPDG) + ":addChannel = 1 1.0 0 333 333";
39+
40+
// Helper lambda to load custom particle definitions across ALL Pythia engines
41+
auto applyCustomParticles = [&](Pythia8::Pythia &pythiaInst)
42+
{
43+
pythiaInst.readString(createReso);
44+
pythiaInst.readString(resoMayDecay);
45+
pythiaInst.readString(addResoDecay);
46+
};
47+
48+
// 1: Apply particle definitions to mPythia, mPythiaGun, and pythiaObjectMinimumBias
49+
applyCustomParticles(mPythia);
50+
applyCustomParticles(mPythiaGun);
4951

5052
mPythiaGun.readString("ProcessLevel:all off");
5153
mPythiaGun.readString("Random:setSeed = on");
5254
mPythiaGun.readString("Random:seed = " + std::to_string(1 + gRandom->Integer(900000000)));
5355
mPythiaGun.init();
5456

55-
// 2. Initialize Minimum Bias Pythia Engine
57+
// 3. Initialize Minimum Bias Pythia Engine
5658
if (pythiaCfgMb.empty())
5759
{
5860
auto &param = o2::eventgen::GeneratorPythia8Param::Instance();
@@ -67,25 +69,8 @@ public:
6769
pythiaObjectMinimumBias.readString("Random:setSeed = on");
6870
pythiaObjectMinimumBias.readString("Random:seed = " + std::to_string(1 + gRandom->Integer(900000000)));
6971

70-
// Add custom particle definition to MB instance so particle table matches
71-
pythiaObjectMinimumBias.readString(createReso);
72-
pythiaObjectMinimumBias.readString(std::to_string(mResoPDG) + ":mayDecay = on");
73-
pythiaObjectMinimumBias.readString(addDecay);
74-
72+
applyCustomParticles(pythiaObjectMinimumBias);
7573
pythiaObjectMinimumBias.init();
76-
77-
// // Thermal pT distribution for phi-phi resonance
78-
// mThermal = new TF1("mThermal", "x*sqrt(x*x+[0]*[0])*exp(-sqrt(x*x+[0]*[0])/[1])", mPtMin, mPtMaxPhiPhi);
79-
80-
// // Lévy-Tsallis pT distribution for direct phi
81-
// mLevyTsallis = new TF1("mLevyTsallis", FuncLavy, mPtMin, 100.0, 4);
82-
83-
// mLevyTsallis->SetParameters(
84-
// 7.60279, // n
85-
// 0.0374237, // dN/dy
86-
// 1.01946, // mass
87-
// 0.338379 // T
88-
// );
8974
}
9075

9176
Bool_t generateEvent() override
@@ -99,69 +84,77 @@ public:
9984
mbOK = pythiaObjectMinimumBias.next();
10085
}
10186

102-
// Copy MB event into mPythia
103-
mPythia.event = pythiaObjectMinimumBias.event;
87+
// 2: Copy MB event using exact pointer binding from generator_pythia8_LF_rapidity_width.C
88+
copyMinimumBiasEventForInjection();
10489

10590
// 2. Clear Gun event container
10691
mPythiaGun.event.reset();
10792

10893
// 3. Inject Signal Gun Particles into mPythiaGun
10994
if (mEventCounter % mSignalInterval == 0)
11095
{
111-
// Theramal distribution
96+
// Resonant signal -> Decays into 333 333 (Standard Phis)
11297
injectParticle(mResoPDG, 1, true);
11398
}
11499
else
115100
{
116-
// From published
101+
// Directly injected uncorrelated Phi
117102
injectParticle(333, 2, false);
118103
}
119104

120105
// 4. Force Decay of injected particles using Pythia's Decayer
121-
for (int i = 1; i < mPythiaGun.event.size(); ++i)
122-
{
123-
if (mPythiaGun.event[i].status() > 0)
124-
{ // Active injected particles
125-
mPythiaGun.particleData.mayDecay(mPythiaGun.event[i].id(), true);
126-
mPythiaGun.moreDecays();
127-
}
128-
}
106+
mPythiaGun.moreDecays();
107+
mPythiaGun.next();
129108

130-
// 5. Merge mPythiaGun event into mPythia.event
109+
// 3: Index Mapping during Event Merging
131110
int offset = mPythia.event.size();
111+
std::vector<int> indexMap(mPythiaGun.event.size(), 0);
132112

133113
for (int i = 1; i < mPythiaGun.event.size(); ++i)
134-
{ // Skip system particle 0
114+
{
115+
indexMap[i] = mPythia.event.size();
135116
Pythia8::Particle p = mPythiaGun.event[i];
117+
mPythia.event.append(p);
118+
}
119+
120+
// Re-link mother and daughter index relationships accurately
121+
for (int i = 1; i < mPythiaGun.event.size(); ++i)
122+
{
123+
int newIdx = indexMap[i];
124+
Pythia8::Particle &p = mPythia.event[newIdx];
136125

137-
// Adjust history indices accurately
138-
int mother1 = (p.mother1() > 0) ? p.mother1() + offset - 1 : p.mother1();
139-
int mother2 = (p.mother2() > 0) ? p.mother2() + offset - 1 : p.mother2();
140-
int daughter1 = (p.daughter1() > 0) ? p.daughter1() + offset - 1 : p.daughter1();
141-
int daughter2 = (p.daughter2() > 0) ? p.daughter2() + offset - 1 : p.daughter2();
126+
int m1 = p.mother1();
127+
int m2 = p.mother2();
128+
int d1 = p.daughter1();
129+
int d2 = p.daughter2();
142130

143-
p.mothers(mother1, mother2);
144-
p.daughters(daughter1, daughter2);
131+
p.mothers((m1 > 0 && m1 < (int)indexMap.size()) ? indexMap[m1] : 0,
132+
(m2 > 0 && m2 < (int)indexMap.size()) ? indexMap[m2] : 0);
145133

146-
mPythia.event.append(p);
134+
p.daughters((d1 > 0 && d1 < (int)indexMap.size()) ? indexMap[d1] : 0,
135+
(d2 > 0 && d2 < (int)indexMap.size()) ? indexMap[d2] : 0);
147136
}
148137

149-
// 6. CRITICAL: Restore Pythia particleData pointers for O2 exporter
138+
// 4: Restore Pythia particleData pointers for O2 exporter
150139
mPythia.event.restorePtrs();
151140

152-
// 7. Invoke base generator hooks to sync O2 event record
153-
// return GeneratorPythia8::generateEvent();
154-
return true; // Skip base generator processing to avoid overwriting injected particles
141+
return true;
155142
}
156143

157144
private:
145+
void copyMinimumBiasEventForInjection()
146+
{
147+
mPythia.event = pythiaObjectMinimumBias.event;
148+
mPythia.event.init("Minimum-bias event with injected particles", &mPythia.particleData);
149+
mPythia.event.restorePtrs();
150+
}
151+
158152
void injectParticle(int pdg, int nParticles, bool thermalPt)
159153
{
160154
const double phiMass = 1.019461;
161155

162156
for (int i = 0; i < nParticles; ++i)
163157
{
164-
// const double pt = gRandom->Uniform(mPtMin, mPtMaxPhiPhi);
165158
const double y = gRandom->Uniform(mYMin, mYMax);
166159
const double phi = gRandom->Uniform(0, TMath::TwoPi());
167160

@@ -179,22 +172,13 @@ private:
179172
}
180173

181174
double pt;
182-
183175
if (thermalPt)
184176
{
185-
// const double T = 0.160;
186-
187-
// mThermal->SetParameter(0, mass);
188-
// mThermal->SetParameter(1, T);
189-
190-
// pt = mThermal->GetRandom();
191-
192-
pt = gRandom->Uniform(mPtMin, mPtMaxPhiPhi); // Falling back to flat pT due to low statistics in high pT
177+
pt = gRandom->Uniform(mPtMin, mPtMaxPhiPhi);
193178
}
194179
else
195180
{
196-
// pt = mLevyTsallis->GetRandom();
197-
pt = gRandom->Uniform(mPtMin, 100.0); // Falling back to flat pT due to low statistics in high pT
181+
pt = gRandom->Uniform(mPtMin, 100.0);
198182
}
199183

200184
const double px = pt * std::cos(phi);
@@ -215,6 +199,7 @@ private:
215199
particle.yProd(0.);
216200
particle.zProd(0.);
217201

202+
mPythiaGun.particleData.mayDecay(pdg, true);
218203
mPythiaGun.event.append(particle);
219204
}
220205
}
@@ -226,9 +211,6 @@ private:
226211

227212
Pythia8::Pythia mPythiaGun;
228213
Pythia8::Pythia pythiaObjectMinimumBias;
229-
230-
// TF1 *mThermal;
231-
// TF1 *mLevyTsallis;
232214
};
233215

234216
/// Entry point for o2-sim

0 commit comments

Comments
 (0)