ATLAS Offline Software
Loading...
Searching...
No Matches
Epos.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ----------------------------------------------------------------------
6// Generators/Epos.cxx
7//
8// Description: Allows the user to generate epos events and store the result
9// in the Transient Store.
10//
11// AuthorList:
12// Sami Kama: Initial code.
13// Sebastian Piec: Adaptation for Epos 1.99.crmc.r2790.
14// Andrii Verbytskyi: 2.0.1+
15// ----------------------------------------------------------------------
16
17#include "GaudiKernel/MsgStream.h"
18#include "CLHEP/Random/RandFlat.h"
20
21#include "AtlasHepMC/GenEvent.h"
22#include "AtlasHepMC/HeavyIon.h"
24
25#include "Epos_i/Epos.h"
26#include "CRMChepevt.h"
27#define CRMC_STATIC
28#include "CRMCinterface.h"
29
30
31namespace {
32static std::string epos_rndm_stream = "EPOS_INIT";
33static CLHEP::HepRandomEngine* p_rndmEngine{};
34}
35
36extern "C" double atl_epos_rndm_( int* )
37{
38 return CLHEP::RandFlat::shoot(p_rndmEngine);
39}
40// ----------------------------------------------------------------------
41// Epos Fortran bindings.
42// ----------------------------------------------------------------------
43extern "C"
44{
45 // generator initialization
46 void crmc_init_f_( double &m_degymx, int &iSeed, int &model, int &itab, int &itypout, const char *paramFile, const char *output, int &lout);
47
48 void crmc_set_f_( int &nEvents,double &beamMomentum, double &targetMomentum, int &primaryParticle, int &targetParticle);
49
50 // event generation
51 void crmc_f_( int &iout, int &ievent, int &nParticles, double &impactParam, int &partPdg,
52 double &partPx, double &partPy, double &partPz, double &partEnergy, double &partMass, int &outstat );
53
54 // cross section info
55 void crmc_xsection_f_(double &xsigtot, double &xsigine, double &xsigela, double &xsigdd,
56 double &xsigsd, double &xsloela, double &xsigtotaa, double &xsigineaa, double &xsigelaaa);
57
58}
59// ----------------------------------------------------------------------
60Epos::Epos( const std::string &name, ISvcLocator *pSvcLocator ):
61 GenModule( name, pSvcLocator )
62{
63 m_interface = nullptr;
64 epos_rndm_stream = "EPOS_INIT";
65
66 declareProperty( "BeamMomentum", m_beamMomentum = -6500.0 ); // GeV
67 declareProperty( "TargetMomentum", m_targetMomentum = 6500.0 );
68 declareProperty( "Model", m_model = 7 ); // 0=EPOS 1.99 LHC, 1=EPOS 1.99
69 declareProperty( "PrimaryParticle", m_primaryParticle = 1 ); // 1=p, 12=C, 120=pi+, 207=Pb
70 declareProperty( "TargetParticle", m_targetParticle = 1 );
71 declareProperty( "ParamFile", m_paramFile = "crmc.param" );
72 declareProperty( "LheOutput", m_ilheout = 0 );
73 declareProperty( "LheFile", m_lheout = "epos.lhe" );
74 declareProperty( "TabCreate", m_itab = 0 );
75 declareProperty( "nEvents", m_nEvents = 5500 );
76 declareProperty( "maxCMEnergy", m_degymx = 13000.0 ); // maximum center-of-mass energy which will be call in the run [GeV]
77
78 m_events = 0; // current event number (counted by interface)
79 m_ievent = 0; // current event number counted by Epos
80 m_iout = 0; // output type (output)
81
82 // initialize internally used arrays
83 ATH_MSG_INFO( "max number of Particles " << kMaxParticles );
84 m_partID.resize (kMaxParticles);
85 m_partPx.resize (kMaxParticles);
86 m_partPy.resize (kMaxParticles);
87 m_partPz.resize (kMaxParticles);
91 for (size_t i = 0; i < kMaxParticles; ++i) {
92 m_partID[i] = 0;
93 m_partPx[i] = m_partPy[i] = m_partPz[i] = m_partEnergy[i] = m_partMass[i] = 0.0;
94 m_partStat[i] = 0;
95 }
96
97}
98
99// ----------------------------------------------------------------------
101{
102 ATH_MSG_INFO( " CRMC INITIALISING.\n" );
103 ATH_MSG_INFO( "signal_rocess_id 101-ND, 105-DD, 102-CD, 103 AB->XB, 104 AB->AX \n");
104
105 p_rndmEngine = getRandomEngineDuringInitialize(epos_rndm_stream, m_randomSeed, m_dsid); // NOT THREAD-SAFE
106 const long *sip = p_rndmEngine->getSeeds();
107 long int si1 = sip[0];
108
109 int iSeed = si1%1000000000; // FIXME ?
110 int lout = 50; //lenght of the output string (useful only for LHE output)
111 // initialise Epos and set up initial values
112
113 crmc_init_f_( m_degymx, iSeed, m_model, m_itab, m_ilheout, (m_paramFile + " ").c_str(), m_lheout.c_str(), lout);
115
116 epos_rndm_stream = "EPOS";
117
118 m_events = 0;
119
120 return StatusCode::SUCCESS;
121}
122
123// ----------------------------------------------------------------------
125{
126 // ATH_MSG_INFO( " EPOS Generating." );
127
128 //Re-seed the random number stream
129 long seeds[7];
130 const EventContext& ctx = Gaudi::Hive::currentContext();
131 ATHRNG::calculateSeedsMC21(seeds, epos_rndm_stream, ctx.eventID().event_number(), m_dsid, m_randomSeed);
132 p_rndmEngine->setSeeds(seeds, 0); // NOT THREAD-SAFE
133
134 // save the random number seeds in the event
135 const long *s = p_rndmEngine->getSeeds();
136 m_seeds.clear();
137 m_seeds.push_back(s[0]);
138 m_seeds.push_back(s[1]);
139
140 ++m_events;
141
142 // as in crmchep.h
143 int nParticles = 0;
144 double impactParameter = -1.0;
145
146 // generate event
147 crmc_f_( m_iout, m_ievent,nParticles, impactParameter, m_partID[0], m_partPx[0], m_partPy[0], m_partPz[0],
149
150 return StatusCode::SUCCESS;
151}
152
153// ----------------------------------------------------------------------
155{
156 ATH_MSG_INFO("EPOS finalizing.");
157
158 std::cout << "MetaData: generator = Epos " << std::endl;
159
160 // retrieve information about the total cross-section from Epos
161 double xsigtot, xsigine, xsigela, xsigdd, xsigsd, xsloela, xsigtotaa, xsigineaa, xsigelaaa;
162 xsigtot = xsigine = xsigela = xsigdd = xsigsd = xsloela = xsigtotaa = xsigineaa = xsigelaaa = 0.0;
163
164 crmc_xsection_f_(xsigtot, xsigine, xsigela, xsigdd, xsigsd, xsloela, xsigtotaa, xsigineaa, xsigelaaa);
165
166 xsigtot *= 1000000; // [mb] to [nb] conversion
167 std::cout << "MetaData: cross-section (nb) = " << xsigtot << std::endl;
168 xsigine *= 1000000; //[mb] to [nb] conversion
169 std::cout << "MetaData: cross-section inelastic (cut + projectile diffraction)[nb] = " << xsigine << std::endl;
170 xsigela *= 1000000; // [mb] to [nb] conversion
171 std::cout << "MetaData: cross-section elastic (includes target diffraction)[nb] = " << xsigela << std::endl;
172 xsigdd *= 1000000; // [mb] to [nb] conversion
173 std::cout << "MetaData: cross-section dd (nb) = " << xsigdd << std::endl;
174 xsigsd *= 1000000; // [mb] to [nb] conversion
175 std::cout << "MetaData: cross-section sd (nb) = " << xsigsd << std::endl;
176
177 // m_eposEventInfo.close();
178
179 return StatusCode::SUCCESS;
180}
181
182// ----------------------------------------------------------------------
183StatusCode Epos::fillEvt( HepMC::GenEvent* evt )
184{
185 CRMChepevt<HepMC::GenParticlePtr, HepMC::GenVertexPtr, HepMC::FourVector, HepMC::GenEvent> hepevtconverter;
186#ifdef HEPMC3
187 hepevtconverter.convert(*evt);
188 evt->set_event_number(m_events);
191 evt->weights().push_back(1.0);
192 m_runinfo = std::make_shared<HepMC3::GenRunInfo>();
193 std::vector<std::string> names = {"Default"};
194 m_runinfo->set_weight_names(names);
195 evt->set_run_info(m_runinfo);
196 evt->set_units(HepMC3::Units::MEV, HepMC3::Units::MM);
197#else
200 hepevtconverter.convert();
201 for (auto& v: hepevtconverter.vertices()) evt->add_vertex(v);
202 if (hepevtconverter.beams().size() == 2) evt->set_beam_particles(hepevtconverter.beams()[0],hepevtconverter.beams()[1]);
203 if (hepevtconverter.beams().size() == 1) evt->set_beam_particles(hepevtconverter.beams()[0],nullptr);
204 evt->set_event_number(m_events);
206 evt->weights().push_back(1.0);
207 GeVToMeV(evt);
208#endif
209
210 std::vector<HepMC::GenParticlePtr> beams;
211
212 for (auto p: *evt) {
213 if (p->status() == 4) {
214 beams.push_back(std::move(p));
215 }
216 }
217
218 if (beams.size() >= 2) {
219 evt->set_beam_particles(beams[0], beams[1]);
220 } else {
221 ATH_MSG_INFO( "EPOS event has only " << beams.size() << " beam particles" );
222 }
223
224 // Heavy Ion and Signal ID from Epos to HepMC
225
226#ifdef HEPMC3
227 HepMC::GenHeavyIonPtr ion= std::make_shared<HepMC::GenHeavyIon>();
228 ion->Ncoll_hard=cevt_.kohevt;
229 ion->Npart_proj=cevt_.npjevt;
230 ion->Npart_targ=cevt_.ntgevt;
231 ion->Ncoll=cevt_.kolevt;
232 ion->spectator_neutrons=cevt_.npnevt + cevt_.ntnevt;
233 ion->spectator_protons=cevt_.nppevt + cevt_.ntpevt;
234 ion->N_Nwounded_collisions=-1;
235 ion->Nwounded_N_collisions=-1;
236 ion->Nwounded_Nwounded_collisions=-1;
237 ion->impact_parameter= cevt_.bimevt;
238 ion->event_plane_angle=cevt_.phievt;
239 ion->eccentricity=-1; //c2evt_.fglevt, //correct name but not defined
240 ion->sigma_inel_NN=1e9*hadr5_.sigine;
241#else
242 HepMC::HeavyIon ion(cevt_.kohevt,
243 cevt_.npjevt,
244 cevt_.ntgevt,
245 cevt_.kolevt,
246 cevt_.npnevt + cevt_.ntnevt,
247 cevt_.nppevt + cevt_.ntpevt,
248 -1,
249 -1,
250 -1,
251 cevt_.bimevt,
252 cevt_.phievt,
253 -1, //c2evt_.fglevt, //correct name but not defined
254 1e9*hadr5_.sigine);
255#endif
256
257 evt->set_heavy_ion(std::move(ion));
258
259 //an integer ID uniquely specifying the signal process (i.e. MSUB in Pythia)
260 // Epos 1-ND, 2-DD, 3-CD, 4 AB->XB, -4 AB->AX translated into signal_proces_id 101-ND, 105 - DD, 102 - CD, 103 -AB->XB, 104 AB->AX
261 int sig_id = -1;
262 switch (int(c2evt_.typevt))
263 {
264 case 1: sig_id = 101; break;
265 case -1: sig_id = 101; break;
266 case 2: sig_id = 105; break;
267 case -2: sig_id = 105; break;
268 case 3: sig_id = 102; break;
269 case -3: sig_id = 102; break;
270 case 4: sig_id = 103; break;
271 case -4: sig_id = 104; break;
272 default: ATH_MSG_INFO( "Signal ID not recognised for setting HEPEVT \n");
273 }
274
276
277 double xsigtot, xsigine, xsigela, xsigdd, xsigsd, xsloela, xsigtotaa, xsigineaa, xsigelaaa;
278 xsigtot = xsigine = xsigela = xsigdd = xsigsd = xsloela = xsigtotaa = xsigineaa = xsigelaaa = 0.0;
279 crmc_xsection_f_(xsigtot, xsigine, xsigela, xsigdd, xsigsd, xsloela, xsigtotaa, xsigineaa, xsigelaaa);
280 xsigtot *= 1000000; // [mb] to [nb] conversion
281#ifdef HEPMC3
282 std::shared_ptr<HepMC3::GenCrossSection> xsec = std::make_shared<HepMC3::GenCrossSection>();
283 xsec->set_cross_section(xsigine, 0.0);
284#else
285 HepMC::GenCrossSection xsec;
286 xsec.set_cross_section(xsigine, 0.0);
287#endif
288 evt->set_cross_section(std::move(xsec));
289
290 return StatusCode::SUCCESS;
291}
292
#define ATH_MSG_INFO(x)
void crmc_f_(int &iout, int &ievent, int &nParticles, double &impactParam, int &partPdg, double &partPx, double &partPy, double &partPz, double &partEnergy, double &partMass, int &outstat)
double atl_epos_rndm_(int *)
Definition Epos.cxx:36
void crmc_set_f_(int &nEvents, double &beamMomentum, double &targetMomentum, int &primaryParticle, int &targetParticle)
void crmc_init_f_(double &m_degymx, int &iSeed, int &model, int &itab, int &itypout, const char *paramFile, const char *output, int &lout)
void crmc_xsection_f_(double &xsigtot, double &xsigine, double &xsigela, double &xsigdd, double &xsigsd, double &xsloela, double &xsigtotaa, double &xsigineaa, double &xsigelaaa)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
int m_primaryParticle
Definition Epos.h:50
std::vector< double > m_partPy
Definition Epos.h:68
int m_nEvents
Definition Epos.h:56
std::string m_paramFile
Definition Epos.h:52
int m_itab
Definition Epos.h:54
int m_ilheout
Definition Epos.h:55
IntegerProperty m_dsid
Definition Epos.h:60
std::vector< int > m_partStat
Definition Epos.h:72
std::string m_lheout
Definition Epos.h:53
static const size_t kMaxParticles
Definition Epos.h:65
std::vector< double > m_partPx
Definition Epos.h:67
std::vector< double > m_partPz
Definition Epos.h:69
virtual StatusCode genInitialize()
For initializing the generator, if required.
Definition Epos.cxx:100
int m_model
Definition Epos.h:49
Epos(const std::string &name, ISvcLocator *pSvcLocator)
Definition Epos.cxx:60
int m_events
Definition Epos.h:42
double m_targetMomentum
Definition Epos.h:48
std::vector< long int > m_seeds
Definition Epos.h:74
double m_beamMomentum
Definition Epos.h:47
int m_ievent
Definition Epos.h:43
int m_targetParticle
Definition Epos.h:51
std::vector< int > m_partID
Definition Epos.h:66
virtual StatusCode genFinalize()
For finalising the generator, if required.
Definition Epos.cxx:154
CRMCinterface * m_interface
Definition Epos.h:40
virtual StatusCode fillEvt(HepMC::GenEvent *evt)
For filling the HepMC event object.
Definition Epos.cxx:183
virtual StatusCode callGenerator()
For calling the generator on each iteration of the event loop.
Definition Epos.cxx:124
std::vector< double > m_partEnergy
Definition Epos.h:70
double m_degymx
Definition Epos.h:57
std::vector< double > m_partMass
Definition Epos.h:71
int m_iout
Definition Epos.h:44
void GeVToMeV(HepMC::GenEvent *evt)
Scale event energies/momenta by x 1000.
Definition GenBase.cxx:58
GenModule(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition GenModule.cxx:14
CLHEP::HepRandomEngine * getRandomEngineDuringInitialize(const std::string &streamName, unsigned long int randomSeedOffset, unsigned int conditionsRun=1, unsigned int lbn=1) const
Definition GenModule.cxx:53
IntegerProperty m_randomSeed
Seed for random number engine.
Definition GenModule.h:84
const int nEvents
void calculateSeedsMC21(long *seeds, const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
Set the random seed using a string (e.g.
void set_random_states(GenEvent *e, std::vector< T > a)
Definition GenEvent.h:648
void set_signal_process_id(GenEvent *e, const int i)
Definition GenEvent.h:642
void fillBarcodesAttribute(GenEvent *)
Definition GenEvent.h:627