Skip to content

Commit 7938d99

Browse files
authored
Merge pull request #27 from mfaggin/mfaggin_pythiaGun
First commit of Pythia8 gun event generator
2 parents 52692fd + de6b301 commit 7938d99

File tree

3 files changed

+296
-0
lines changed

3 files changed

+296
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[GeneratorExternal]
2+
fileName=${O2DPG_ROOT}/MC/config/PWGHF/pythia8_gun/generator_pythia8_gun.C
3+
funcName=generateOmegaAndPions_RandomCharge(20)
4+
5+
[GeneratorPythia8]
6+
config=${O2DPG_ROOT}/MC/config/PWGHF/pythia8_gun/config_custom_OmegaC.cfg
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
### Omega_c
2+
#4332:all = Omega_c0 Omega_cbar0 2 0 0 2.69520 0. 0. 0. 10
3+
4+
ProcessLevel:all = off
5+
6+
### changing the ctau value in mm/c
7+
4332:tau0=0.08000000000
8+
9+
### add OmegaC decay absent in PYTHIA8 decay table
10+
4332:addChannel = 1 0.0001 0 3334 211
11+
12+
### force the OmegaC to decay in the Omega_c -> Omega pi channel
13+
4332:onMode = off
14+
4332:onIfMatch = 3334 211
15+
16+
### switch off Omega and Lambda decay channel (treated in GEANT)
17+
3334:onMode = off
18+
3122:onMode = off
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#include "Pythia8/Pythia.h"
2+
#include "FairGenerator.h"
3+
#include "FairPrimaryGenerator.h"
4+
#include "Generators/GeneratorPythia8.h"
5+
#include "TRandom3.h"
6+
#include "TParticlePDG.h"
7+
#include "TDatabasePDG.h"
8+
9+
#include <map>
10+
#include <unordered_set>
11+
//#include <utility> // for std::pair
12+
13+
using namespace Pythia8;
14+
15+
class GeneratorPythia8Gun : public o2::eventgen::GeneratorPythia8{
16+
public:
17+
/// default constructor
18+
GeneratorPythia8Gun() = default;
19+
20+
/// constructor
21+
GeneratorPythia8Gun(int input_pdg){
22+
genMinP=1.;
23+
genMaxP=16.;
24+
genMinEta=-0.1;
25+
genMaxEta=0.1;
26+
27+
pdg = input_pdg;
28+
E=0;
29+
px=0;
30+
py=0;
31+
pz=0;
32+
p=0;
33+
y=0;
34+
eta=0;
35+
xProd=0;
36+
yProd=0;
37+
zProd=0;
38+
xProd=0.; yProd=0.; zProd=0.;
39+
//addFurtherPion=false;
40+
41+
randomizePDGsign=false;
42+
43+
m = getMass(input_pdg);
44+
furtherPrim={};
45+
keys_furtherPrim={};
46+
}
47+
48+
/// Destructor
49+
~GeneratorPythia8Gun() = default;
50+
51+
/// set PDG code
52+
void setPDG(int input_pdg){pdg=input_pdg;}
53+
54+
/// randomize the PDG code sign of core particle
55+
void setRandomizePDGsign(){randomizePDGsign=true;}
56+
57+
/// set mass
58+
void setMass(int input_m){m=input_m;}
59+
60+
/// set 4-momentum
61+
void set4momentum(double input_px, double input_py, double input_pz){
62+
px = input_px;
63+
py = input_py;
64+
pz = input_pz;
65+
E = sqrt( m*m+px*px+py*py+pz*pz );
66+
fourMomentum.px(px);
67+
fourMomentum.py(py);
68+
fourMomentum.pz(pz);
69+
fourMomentum.e(E);
70+
p = sqrt( px*px+py*py+pz*pz );
71+
y = 0.5*log( (E+pz)/(E-pz) );
72+
eta = 0.5*log( (p+pz)/(p-pz) );
73+
74+
////std::cout << "##### Particle #####" << std::endl;
75+
////std::cout << " - PDG code: " << pdg << std::endl;
76+
////std::cout << " - mass: " << m << std::endl;
77+
////std::cout << " - (px,py,pz): (" << px << "," << py << "," << pz << ")" << std::endl;
78+
////std::cout << " - momentum: " << p << std::endl;
79+
////std::cout << " - energy: " << E << std::endl;
80+
////std::cout << " - rapidity: " << y << std::endl;
81+
////std::cout << " - pseudorapidity: " << eta << std::endl;
82+
////std::cout << " - production vertex: (" << xProd << "," << yProd << "," << zProd << ")" << std::endl;
83+
}
84+
85+
/// set 3-momentum
86+
void setMomentum(double input_p){p=input_p;}
87+
88+
/// set x,y,z of production vertex
89+
void setProdVtx(double input_xProd, double input_yProd, double input_zProd){xProd=input_xProd; yProd=input_xProd; zProd=input_zProd;}
90+
91+
/// setter to add further primary particles to the event
92+
void setAddFurtherPrimaries(const int pdgCode, const int howMany){
93+
/// check if this species has been already added
94+
const int map_counts = furtherPrim.count(pdgCode);
95+
if(map_counts==1){ // species already present
96+
const int howMany_already = furtherPrim[pdgCode];
97+
std::cout << "BEWARE: " << howMany_already << " particles of species " << pdgCode << " already required.";
98+
std::cout << " Ignoring the command setAddFurtherPrimaries(" << pdgCode << "," << howMany << ")" << std::endl;
99+
return;
100+
}
101+
/// add particles, if not yet present
102+
furtherPrim[pdgCode] = howMany;
103+
keys_furtherPrim.insert(pdgCode);
104+
}
105+
106+
/// set add a further primary pion
107+
//void setAddFurtherPion(){addFurtherPion=true;}
108+
109+
/// get mass from TParticlePDG
110+
double getMass(int input_pdg){
111+
double mass = 0;
112+
if(TDatabasePDG::Instance()){
113+
TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg);
114+
if(particle) mass = particle->Mass();
115+
else std::cout << "===> particle mass equal to 0" << std::endl;
116+
}
117+
return mass;
118+
}
119+
120+
//_________________________________________________________________________________
121+
/// generate uniform eta and uniform momentum
122+
void genUniformMomentumEta(double minP, double maxP, double minEta, double maxEta){
123+
// random generator
124+
std::unique_ptr<TRandom3> ranGenerator { new TRandom3() };
125+
ranGenerator->SetSeed(0);
126+
127+
// momentum
128+
const double gen_p = ranGenerator->Uniform(minP,maxP);
129+
// eta
130+
const double gen_eta = ranGenerator->Uniform(minEta,maxEta);
131+
// z-component momentum from eta
132+
const double cosTheta = ( exp(2*gen_eta)-1 ) / ( exp(2*gen_eta)+1 ); // starting from eta = -ln(tan(theta/2)) = 1/2*ln( (1+cos(theta))/(1-cos(theta)) ) ---> NB: valid for cos(theta)!=1
133+
const double gen_pz = gen_p*cosTheta;
134+
// y-component: random uniform
135+
const double maxVal = sqrt( gen_p*gen_p-gen_pz*gen_pz );
136+
double sign_py = ranGenerator->Uniform(0,1);
137+
sign_py = (sign_py>0.5)?1.:-1.;
138+
const double gen_py = ranGenerator->Uniform(0.,maxVal)*sign_py;
139+
// x-component momentum
140+
double sign_px = ranGenerator->Uniform(0,1);
141+
sign_px = (sign_px>0.5)?1.:-1.;
142+
const double gen_px = sqrt( gen_p*gen_p-gen_pz*gen_pz-gen_py*gen_py )*sign_px;
143+
144+
set4momentum(gen_px,gen_py,gen_pz);
145+
}
146+
147+
protected:
148+
149+
//__________________________________________________________________
150+
Particle createParticle(){
151+
std::cout << "createParticle() mass " << m << " pdgCode " << pdg << std::endl;
152+
Particle myparticle;
153+
myparticle.id(pdg);
154+
myparticle.status(11);
155+
myparticle.px(px);
156+
myparticle.py(py);
157+
myparticle.pz(pz);
158+
myparticle.e(E);
159+
myparticle.m(m);
160+
myparticle.xProd(xProd);
161+
myparticle.yProd(yProd);
162+
myparticle.zProd(zProd);
163+
164+
return myparticle;
165+
}
166+
167+
//__________________________________________________________________
168+
int randomizeSign(){
169+
170+
std::unique_ptr<TRandom3> gen_random {new TRandom3(0)};
171+
const float n = gen_random->Uniform(-1,1);
172+
173+
return n/abs(n);
174+
}
175+
176+
//__________________________________________________________________
177+
Bool_t generateEvent() override {
178+
179+
const double original_m = m;
180+
const int original_pdg = pdg;
181+
182+
/// reset event
183+
mPythia.event.reset();
184+
185+
/// create and append the desired particle
186+
//genUniformMomentumEta(1.,16.,-0.1,0.1);
187+
genUniformMomentumEta(genMinP,genMaxP,genMinEta,genMaxEta);
188+
if(randomizePDGsign) pdg *= randomizeSign();
189+
Particle particle = createParticle();
190+
//
191+
mPythia.event.append(particle);
192+
//
193+
194+
/// add further particles, if required
195+
if(furtherPrim.size()>0){
196+
if(keys_furtherPrim.size()<1){ /// protection
197+
std::cout << "Something wrong with the insertion of further particles" << std::endl;
198+
return false;
199+
}
200+
/// loop in the map
201+
for(const int addPDG: keys_furtherPrim){
202+
const int numAddPrim = furtherPrim[addPDG]; // we will add "numAddPrim" particles of type "addPDG"
203+
//
204+
// Modify the mass before calling genUniformMomentumEta (required inside set4momentum function)
205+
m = getMass(addPDG);
206+
pdg = addPDG;
207+
//
208+
for(int iAdd=0; iAdd<numAddPrim; iAdd++){ // generated and append the desired particle
209+
genUniformMomentumEta(genMinP,genMaxP,genMinEta,genMaxEta);
210+
Particle further_particle = createParticle();
211+
mPythia.event.append(further_particle);
212+
}
213+
} // end loop map
214+
215+
// restore the values for the desired injected particle (mandatory for next iteration)
216+
m = original_m;
217+
pdg = original_pdg;
218+
}
219+
220+
/// go to next Pythia event
221+
mPythia.next();
222+
223+
return true;
224+
}
225+
226+
private:
227+
228+
double genMinP; /// minimum 3-momentum for generated particles
229+
double genMaxP; /// maximum 3-momentum for generated particles
230+
double genMinEta; /// minimum pseudorapidity for generated particles
231+
double genMaxEta; /// maximum pseudorapidity for generated particles
232+
233+
Vec4 fourMomentum; /// four-momentum (px,py,pz,E)
234+
double E; /// energy: sqrt( m*m+px*px+py*py+pz*pz ) [GeV/c]
235+
double m; /// particle mass [GeV/c^2]
236+
int pdg; /// particle pdg code
237+
double px; /// x-component momentum [GeV/c]
238+
double py; /// y-component momentum [GeV/c]
239+
double pz; /// z-component momentum [GeV/c]
240+
double p; /// momentum
241+
double y; /// rapidity
242+
double eta; /// pseudorapidity
243+
double xProd; /// x-coordinate position production vertex [cm]
244+
double yProd; /// y-coordinate position production vertex [cm]
245+
double zProd; /// z-coordinate position production vertex [cm]
246+
247+
bool randomizePDGsign; /// bool to randomize the PDG code of the core particle
248+
249+
//bool addFurtherPion; /// bool to attach an additional primary pion
250+
std::map<int,int> furtherPrim; /// key: PDG code; value: how many further primaries of this species to be added
251+
std::unordered_set<int> keys_furtherPrim; /// keys of the above map (NB: only unique elements allowed!)
252+
};
253+
254+
///___________________________________________________________
255+
FairGenerator* generateOmegaC(){
256+
auto myGen = new GeneratorPythia8Gun(4332);
257+
myGen->setRandomizePDGsign(); // randomization of OmegaC PDG switched on
258+
return myGen;
259+
}
260+
261+
///___________________________________________________________
262+
FairGenerator* generateOmegaAndPions_RandomCharge(const int nPions){
263+
264+
auto myGen = new GeneratorPythia8Gun(3334);
265+
myGen->setRandomizePDGsign(); // randomization of Omega PDG switched on
266+
267+
/// add further pions
268+
myGen->setAddFurtherPrimaries( 211,nPions/2); // pi+
269+
myGen->setAddFurtherPrimaries(-211,nPions/2); // pi-
270+
271+
return myGen;
272+
}

0 commit comments

Comments
 (0)