1+ ///////////////////////////////////////////////////////////////////////////////
2+ /// ///
3+ /// HF MC generator for Pb-Pb ///
4+ /// Option 1: generate N PYTHIA events triggered on ccbar and/or bbbar ///
5+ /// to be embedded with a underlying Pb-Pb event ///
6+ /// ///
7+ ///////////////////////////////////////////////////////////////////////////////
8+
9+ #include "generator_pythia8_gaptriggered_hf.C"
10+
11+ using namespace Pythia8 ;
12+
13+ namespace hf_generators
14+ {
15+ enum GenType : int {
16+ GapTriggeredCharm = 0 , // --> GeneratorPythia8GapTriggeredCharm: charm enriched
17+ GapTriggeredBeauty , // --> GeneratorPythia8GapTriggeredBeauty: beauty enriched
18+ GapTriggeredCharmAndBeauty , // --> GeneratorPythia8GapTriggeredCharmAndBeauty: charm and beauty enriched (with same ratio)
19+ GapHF , // --> GeneratorPythia8GapHF
20+ NGenType
21+ };
22+ }
23+
24+ class GeneratorPythia8EmbedHF : public o2 ::eventgen ::GeneratorPythia8
25+ {
26+ public :
27+
28+ /// default constructor
29+ GeneratorPythia8EmbedHF () = default ;
30+
31+ /// constructor
32+ //GeneratorPythia8EmbedHF(int numSigEvs = 1) {
33+ // mNumSigEvs = numSigEvs;
34+ // //mGeneratedEvents = 0;
35+ //}
36+
37+ /// Destructor
38+ ~GeneratorPythia8EmbedHF () = default ;
39+
40+ /// Init
41+ bool Init () override
42+ {
43+ return o2 ::eventgen ::GeneratorPythia8 ::Init ();
44+ }
45+
46+ /// @brief setup the event generator for HF signals
47+ /// \param gentype generator type (only ccbar, only bbbar, both)
48+ /// \param yQuarkMin minimum quark rapidity
49+ /// \param yQuarkMax maximum quark rapidity
50+ /// \param yHadronMin minimum hadron rapidity
51+ /// \param yHadronMax maximum hadron rapidity
52+ /// \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+ mGeneratorEvHF = nullptr ;
55+ switch (genType )
56+ {
57+ case hf_generators ::GapTriggeredCharm :
58+ LOG (info ) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharm **********" ;
59+ LOG (info ) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs ;
60+ mGeneratorEvHF = dynamic_cast < GeneratorPythia8GapTriggeredHF * > (GeneratorPythia8GapTriggeredCharm (/*no gap trigger*/ 1 , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList ));
61+ break ;
62+ case hf_generators ::GapTriggeredBeauty :
63+ LOG (info ) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredBeauty **********" ;
64+ LOG (info ) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs ;
65+ mGeneratorEvHF = dynamic_cast < GeneratorPythia8GapTriggeredHF * > (GeneratorPythia8GapTriggeredBeauty (/*no gap trigger*/ 1 , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList ));
66+ break ;
67+ case hf_generators ::GapTriggeredCharmAndBeauty :
68+ LOG (info ) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharmAndBeauty **********" ;
69+ LOG (info ) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs ;
70+ mGeneratorEvHF = dynamic_cast < GeneratorPythia8GapTriggeredHF * > (GeneratorPythia8GapTriggeredCharmAndBeauty (/*no gap trigger*/ 1 , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList ));
71+ break ;
72+ case hf_generators ::GapHF :
73+ LOG (info ) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapHF **********" ;
74+ LOG (info ) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs ;
75+ mGeneratorEvHF = dynamic_cast < GeneratorPythia8GapTriggeredHF * > (GeneratorPythia8GapHF (/*no gap trigger*/ 1 , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList ));
76+ break ;
77+ default :
78+ LOG (fatal ) << "********** [GeneratorPythia8EmbedHF] bad configuration, fix it! **********" ;
79+ break ;
80+ }
81+ mGeneratorEvHF -> Init ();
82+ }
83+
84+ // This function is called by the primary generator
85+ // for each event in case we are in embedding mode.
86+ // We use it to setup the number of signal events
87+ // to be generated and to be embedded on the background.
88+ void notifyEmbedding (const o2 ::dataformats ::MCEventHeader * bkgHeader ) override
89+ {
90+ LOG (info ) << "[notifyEmbedding] ----- Function called" ;
91+
92+ /// Impact parameter between the two nuclei
93+ const float x = bkgHeader -> GetB ();
94+ LOG (info ) << "[notifyEmbedding] ----- Collision impact parameter: " << x ;
95+
96+ /// number of events to be embedded in a background event
97+ mNumSigEvs = std ::max (1. ,120. * (x < 5. )+ 80. * (1. - x /20. )* (x > 5. )* (x < 11. )+ 240. * (1. - x /13. )* (x > 11. ));
98+ LOG (info ) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std ::endl ;
99+ };
100+
101+ protected :
102+
103+ /// @brief Main function for event generation
104+ bool generateEvent () override
105+ {
106+ /// Overriding that from GeneratorPythia8, to avoid the simulation of an untriggered event as first
107+ return true;
108+ }
109+
110+ /// @brief Main function to copy the generated particles in mPythia.event into the stack (this.mParticles)
111+ Bool_t importParticles () override
112+ {
113+ /// Import particles from generated event
114+ /// This should not do anything now, since we override generateEvent
115+ GeneratorPythia8 ::importParticles ();
116+
117+ /// Generate mNumSigEvs HF events to be merged in one
118+ int nEvsHF = 0 ;
119+ while (nEvsHF < mNumSigEvs ) {
120+
121+ /// generate the HF event
122+ bool genOk = false;
123+ while (!genOk ) {
124+ genOk = (mGeneratorEvHF -> generateEvent () && mGeneratorEvHF -> importParticles () /*copy particles from mGeneratorEvHF.mPythia.event to mGeneratorEvHF.mParticles*/ );
125+ }
126+
127+ /// copy the particles from the HF event in the particle stack
128+ auto particlesHfEvent = mGeneratorEvHF -> getParticles ();
129+ int originalSize = mParticles .size (); // stack of this event generator
130+ for (int iPart = 0 ; iPart < particlesHfEvent .size (); iPart ++ ) {
131+ auto particle = particlesHfEvent .at (iPart );
132+
133+ /// adjust the particle mother and daughter indices
134+ if (particle .GetFirstMother () >= 0 ) particle .SetFirstMother (particle .GetFirstMother () + originalSize );
135+ if (particle .GetFirstDaughter () >= 0 ) particle .SetFirstDaughter (particle .GetFirstDaughter () + originalSize );
136+ if (particle .GetLastDaughter () >= 0 ) particle .SetLastDaughter (particle .GetLastDaughter () + originalSize );
137+
138+ /// copy inside this.mParticles from mGeneratorEvHF.mParticles, i.e. the particles generated in mGeneratorEvHF
139+ mParticles .push_back (particle );
140+ }
141+
142+ /// one more event generated, let's update the counter and clear it, to allow the next generation
143+ nEvsHF ++ ;
144+ //mGeneratedEvents++;
145+ mGeneratorEvHF -> clearParticles ();
146+ }
147+
148+ return true;
149+ }
150+
151+ private :
152+
153+ Generator * mGeneratorEvHF ; // to generate HF signal events
154+
155+ int mNumSigEvs {1 }; // number of HF signal events to be merged in one Pythia event
156+ //unsigned long long mGeneratedEvents;
157+
158+ };
159+
160+ // Charm enriched
161+ FairGenerator * GeneratorPythia8EmbedHFCharm (float yQuarkMin = -1.5 , float yQuarkMax = 1.5 , float yHadronMin = -1.5 , float yHadronMax = 1.5 , std ::vector < int > hadronPdgList = {})
162+ {
163+ auto myGen = new GeneratorPythia8EmbedHF ();
164+
165+ /// setup the internal generator for HF events
166+ myGen -> setupGeneratorEvHF (hf_generators ::GapTriggeredCharm , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList );
167+
168+ return myGen ;
169+ }
170+
171+ // Beauty enriched
172+ FairGenerator * GeneratorPythia8EmbedHFBeauty (float yQuarkMin = -1.5 , float yQuarkMax = 1.5 , float yHadronMin = -1.5 , float yHadronMax = 1.5 , std ::vector < int > hadronPdgList = {})
173+ {
174+ auto myGen = new GeneratorPythia8EmbedHF ();
175+
176+ /// setup the internal generator for HF events
177+ myGen -> setupGeneratorEvHF (hf_generators ::GapTriggeredBeauty , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList );
178+
179+ return myGen ;
180+ }
181+
182+ // Charm and beauty enriched (with same ratio)
183+ FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty (float yQuarkMin = -1.5 , float yQuarkMax = 1.5 , float yHadronMin = -1.5 , float yHadronMax = 1.5 , std ::vector < int > hadronPdgList = {})
184+ {
185+ auto myGen = new GeneratorPythia8EmbedHF ();
186+
187+ /// setup the internal generator for HF events
188+ myGen -> setupGeneratorEvHF (hf_generators ::GapTriggeredCharmAndBeauty , yQuarkMin , yQuarkMax , yHadronMin , yHadronMax , hadronPdgList );
189+
190+ return myGen ;
191+ }
0 commit comments