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