1-
21#include "Pythia8/Pythia.h"
32#include "Pythia8/HeavyIons.h"
43#include "FairGenerator.h"
@@ -19,14 +18,25 @@ public:
1918 GeneratorPythia8ExtraStrangeness() = default;
2019
2120 /// Constructor
22- GeneratorPythia8ExtraStrangeness(int input_pdg)
21+ GeneratorPythia8ExtraStrangeness(int input_pdg, int inputTriggerRatio)
2322 {
23+
24+ if (inputTriggerRatio <= 0) {
25+ throw std::invalid_argument("inputTriggerRatio must be positive");
26+ }
27+
28+ LOG(info) << "Gap trigger ratio N = " << inputTriggerRatio << " events";
29+
30+
31+ mGeneratedEvents = 0;
32+ mTriggerRatio = inputTriggerRatio;
33+
2434 genMinPt=0.0;
25- genMaxPt=12 .0;
26- genminY=-1.5 ;
27- genmaxY=1.5 ;
28- genminEta=-1 .5;
29- genmaxEta=1 .5;
35+ genMaxPt=10 .0;
36+ genminY=-1.0 ;
37+ genmaxY=1.0 ;
38+ genminEta=-2 .5;
39+ genmaxEta=2 .5;
3040
3141 pdg=input_pdg;
3242 m = 0;
@@ -40,14 +50,8 @@ public:
4050 xProd=0.; yProd=0.; zProd=0.;
4151
4252 fLVHelper = std::make_unique<TLorentzVector>();
43-
44- randomizePDGsign = false;
45-
46- fSpectra = makeLevySpectrum("fSpectra", genMinPt, genMaxPt, mPythia.particleData.m0(input_pdg), 0.30, 7.);
4753 }
4854
49- /// randomize the PDG code sign of core particle
50- void setRandomizePDGsign() { randomizePDGsign = true; }
5155
5256 Double_t y2eta(Double_t pt, Double_t mass, Double_t y){
5357 Double_t mt = TMath::Sqrt(mass * mass + pt * pt);
@@ -108,22 +112,19 @@ TF1* makeLevySpectrum(const char* name, double ptMin, double ptMax, double mass,
108112 //_________________________________________________________________________________
109113 /// generate uniform eta and uniform momentum
110114 void genSpectraMomentumEta(double minPt, double maxPt, double minY, double maxY){
111- // random generator
112- std::unique_ptr<TRandom3> ranGenerator { new TRandom3() };
113- ranGenerator->SetSeed(0);
114-
115+
115116 // generate transverse momentum
116117 //const double gen_pT = ranGenerator->Uniform(minPt, maxPt);
117- const double gen_pT = fSpectra->GetRandom(minPt,maxPt);
118+ const double gen_pT = fSpectra->GetRandom(minPt, maxPt, &mRandom );
118119
119120 //Actually could be something else without loss of generality but okay
120- const double gen_phi = ranGenerator-> Uniform(0,2*TMath::Pi());
121+ const double gen_phi = mRandom. Uniform(0,2*TMath::Pi());
121122
122123 // sample flat in rapidity, calculate eta
123124 Double_t gen_Y=10, gen_eta=10;
124125
125126 while( gen_eta>genmaxEta || gen_eta<genminEta ){
126- gen_Y = ranGenerator-> Uniform(minY,maxY);
127+ gen_Y = mRandom. Uniform(minY,maxY);
127128 gen_eta = y2eta(gen_pT, m, gen_Y);
128129 }
129130
@@ -132,10 +133,10 @@ TF1* makeLevySpectrum(const char* name, double ptMin, double ptMax, double mass,
132133 }
133134
134135 //__________________________________________________________________
135- Pythia8::Particle createParticle(){
136+ Pythia8::Particle createParticle(int id ){
136137 //std::cout << "createParticle() mass " << m << " pdgCode " << pdg << std::endl;
137138 Pythia8::Particle myparticle;
138- myparticle.id(pdg );
139+ myparticle.id(id );
139140 myparticle.status(11);
140141 myparticle.px(px);
141142 myparticle.py(py);
@@ -149,46 +150,92 @@ TF1* makeLevySpectrum(const char* name, double ptMin, double ptMax, double mass,
149150 return myparticle;
150151 }
151152
153+
152154 //__________________________________________________________________
153- int randomizeSign()
155+ // look for final-state (anti)Lambdas in the event; if there are any, remove one
156+ // (chosen at random) from the event record and return the Lambda id, otherwise return 0
157+ int removeLambda()
154158 {
155- std::unique_ptr<TRandom3> gen_random{new TRandom3(0)} ;
156- const float n = gen_random->Uniform(-1, 1) ;
159+ int kLambdaPdg = 3122 ;
160+ auto& event = mPythia.event ;
157161
158- return n / abs(n);
162+ std::vector<int> candidates;
163+ for (int i = 0; i < event.size(); ++i) {
164+ bool isFromDecay = event[i].status() >= 91 && event[i].status() <= 99;
165+ bool isAcc = std::abs(event[i].y()) < genmaxY;
166+
167+ if (event[i].idAbs() == kLambdaPdg && event[i].isFinal() && isAcc && !isFromDecay) {
168+ // not considering lambdas that are the first daughter in the event record.
169+ bool isEdge = false;
170+ for (int mom : event[i].motherList()) {
171+ if (i == event[mom].daughter1() || i == event[mom].daughter2()) isEdge = true;
172+ }
173+
174+ if (!isEdge) {
175+ candidates.push_back(i);
176+ }
177+ }
178+ }
179+ if (candidates.empty()) {
180+ return 0;
181+ }
182+
183+ const int idx = candidates[static_cast<int>(mRandom.Uniform(0,candidates.size()))];
184+ const int lambdaId = event[idx].id();
185+
186+ // remove the entry and shift the indices of the others
187+ event.remove(idx, idx, true);
188+
189+ return lambdaId;
159190 }
160-
191+
161192 //__________________________________________________________________
162193 Bool_t generateEvent() override {
163194 // Generate PYTHIA event
164195
165- mPythia.event.reset();
196+ if (!fSpectra) {
197+ fSpectra = makeLevySpectrum("fSpectra", genMinPt, genMaxPt, mPythia.particleData.m0(pdg), 0.3942, 9.943);
198+ }
166199
167- /// go to next Pythia event
200+ mPythia. event.reset();
168201 Bool_t lPythiaOK = kFALSE;
169- while (!lPythiaOK){
170- lPythiaOK = mPythia.next();
171- }
172202
173- /// reset event
174- //mPythia.event.reset();
203+ mGeneratedEvents++;
204+ if (mGeneratedEvents % mTriggerRatio == 0) {
205+ int lambdaId = 0;
175206
176- /// create and append the desired particle
177- m = sampleMass(pdg);
178- genSpectraMomentumEta(genMinPt, genMaxPt, genminY, genmaxY);
207+ // regenerate until the event contains a Lambda or an anti-Lambda, which is removed
208+ while (lambdaId == 0)
209+ {
210+ lPythiaOK = mPythia.next();
211+ if (lPythiaOK) {
212+ lambdaId = removeLambda();
213+ }
214+ }
179215
180- if (randomizePDGsign)
181- pdg *= randomizeSign( );
216+ m = sampleMass(pdg);
217+ genSpectraMomentumEta(genMinPt, genMaxPt, genminY, genmaxY );
182218
183- Pythia8::Particle particle = createParticle();
184- mPythia.event.append(particle);
185- mPythia.moreDecays();
219+ // Lambda -> Lambda*, anti-Lambda -> anti-Lambda*
220+ const int sign = lambdaId > 0 ? 1 : -1;
186221
222+ Pythia8::Particle particle = createParticle(sign*pdg);
223+ int idxL = mPythia.event.append(particle);
224+ mPythia.moreDecays(idxL);
225+ } else {
226+ while (!lPythiaOK){
227+ lPythiaOK = mPythia.next();
228+ }
229+ }
187230 return true;
188231 }
232+
189233
190234private:
191-
235+
236+ unsigned long long mGeneratedEvents;
237+ int mTriggerRatio;
238+
192239 double genMinPt; /// minimum 3-momentum for generated particles
193240 double genMaxPt; /// maximum 3-momentum for generated particles
194241 double genminY; /// minimum pseudorapidity for generated particles
@@ -211,16 +258,14 @@ private:
211258 double xProd; /// x-coordinate position production vertex [cm]
212259 double yProd; /// y-coordinate position production vertex [cm]
213260 double zProd; /// z-coordinate position production vertex [cm]
214-
215- bool randomizePDGsign; /// bool to randomize the PDG code of the core particle
216261
217262 TF1 *fSpectra = nullptr; /// TF1 to store more realistic shape of spectrum
218263 std::unique_ptr<TLorentzVector> fLVHelper;
264+ TRandom3 mRandom{0};
219265};
220266
221- FairGenerator *generator_Lstar()
267+ FairGenerator *generator_Lstar(int inputTriggerRatio = 3 )
222268 {
223- auto myGen = new GeneratorPythia8ExtraStrangeness(3124);
224- myGen->setRandomizePDGsign(); // randomization of PDG switched on
269+ auto myGen = new GeneratorPythia8ExtraStrangeness(3124, inputTriggerRatio);
225270 return myGen;
226271 }
0 commit comments