ATLAS Offline Software
Epos.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 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 
31 namespace {
32 static std::string epos_rndm_stream = "EPOS_INIT";
33 static CLHEP::HepRandomEngine* p_rndmEngine{};
34 }
35 
36 extern "C" double atl_epos_rndm_( int* )
37 {
38  return CLHEP::RandFlat::shoot(p_rndmEngine);
39 }
40 // ----------------------------------------------------------------------
41 // Epos Fortran bindings.
42 // ----------------------------------------------------------------------
43 extern "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 // ----------------------------------------------------------------------
60 Epos::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);
88  m_partEnergy.resize (kMaxParticles);
89  m_partMass.resize (kMaxParticles);
90  m_partStat.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],
148  m_partEnergy[0], m_partMass[0], m_partStat[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 // ----------------------------------------------------------------------
183 StatusCode 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
198  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(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(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(xsec);
289 
290  return StatusCode::SUCCESS;
291 }
292 
Epos::m_partPy
std::vector< double > m_partPy
Definition: Epos.h:68
Epos::m_beamMomentum
double m_beamMomentum
Definition: Epos.h:47
GenEvent.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Epos::Epos
Epos(const std::string &name, ISvcLocator *pSvcLocator)
Definition: Epos.cxx:60
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Epos::m_partID
std::vector< int > m_partID
Definition: Epos.h:66
Epos::m_seeds
std::vector< long int > m_seeds
Definition: Epos.h:74
GenBase::GeVToMeV
void GeVToMeV(HepMC::GenEvent *evt)
Scale event energies/momenta by x 1000.
Definition: GenBase.cxx:58
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
HeavyIon.h
Epos::m_events
int m_events
Definition: Epos.h:42
Epos::m_partMass
std::vector< double > m_partMass
Definition: Epos.h:71
jobOptions.paramFile
string paramFile
Definition: jobOptions.crmc.py:12
Epos::m_interface
CRMCinterface * m_interface
Definition: Epos.h:40
Epos::m_iout
int m_iout
Definition: Epos.h:44
MM
@ MM
Definition: RegSelEnums.h:38
Epos::m_dsid
IntegerProperty m_dsid
Definition: Epos.h:60
Epos::m_paramFile
std::string m_paramFile
Definition: Epos.h:52
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
crmc_set_f_
void crmc_set_f_(int &nEvents, double &beamMomentum, double &targetMomentum, int &primaryParticle, int &targetParticle)
HepMC::fillBarcodesAttribute
void fillBarcodesAttribute(GenEvent *)
Definition: GenEvent.h:626
crmc_f_
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)
Epos::kMaxParticles
static const size_t kMaxParticles
Definition: Epos.h:65
Epos::m_partPx
std::vector< double > m_partPx
Definition: Epos.h:67
GenModule
Base class for common behaviour of generator interfaces.
Definition: GenModule.h:39
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
SimpleVector.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Epos::m_targetParticle
int m_targetParticle
Definition: Epos.h:51
python.subdetectors.mmg.names
names
Definition: mmg.py:8
Epos.h
Epos::fillEvt
virtual StatusCode fillEvt(HepMC::GenEvent *evt)
For filling the HepMC event object.
Definition: Epos.cxx:183
Epos::genInitialize
virtual StatusCode genInitialize()
For initializing the generator, if required.
Definition: Epos.cxx:100
Epos::m_ilheout
int m_ilheout
Definition: Epos.h:55
nEvents
int nEvents
Definition: fbtTestBasics.cxx:79
Epos::m_ievent
int m_ievent
Definition: Epos.h:43
Epos::m_model
int m_model
Definition: Epos.h:49
crmc_xsection_f_
void crmc_xsection_f_(double &xsigtot, double &xsigine, double &xsigela, double &xsigdd, double &xsigsd, double &xsloela, double &xsigtotaa, double &xsigineaa, double &xsigelaaa)
merge.output
output
Definition: merge.py:17
Epos::m_nEvents
int m_nEvents
Definition: Epos.h:56
Epos::m_targetMomentum
double m_targetMomentum
Definition: Epos.h:48
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
Epos::m_degymx
double m_degymx
Definition: Epos.h:57
Epos::m_itab
int m_itab
Definition: Epos.h:54
updateDocumentation.lout
string lout
Definition: updateDocumentation.py:37
RNGWrapper.h
python.PyAthena.v
v
Definition: PyAthena.py:154
Epos::m_lheout
std::string m_lheout
Definition: Epos.h:53
GenModule::m_randomSeed
IntegerProperty m_randomSeed
Seed for random number engine.
Definition: GenModule.h:84
correlationModel::model
model
Definition: AsgElectronEfficiencyCorrectionTool.cxx:46
GetAllXsec.xsec
xsec
Definition: GetAllXsec.py:85
Epos::genFinalize
virtual StatusCode genFinalize()
For finalising the generator, if required.
Definition: Epos.cxx:154
crmc_init_f_
void crmc_init_f_(double &m_degymx, int &iSeed, int &model, int &itab, int &itypout, const char *paramFile, const char *output, int &lout)
Epos::callGenerator
virtual StatusCode callGenerator()
For calling the generator on each iteration of the event loop.
Definition: Epos.cxx:124
ATHRNG::calculateSeedsMC21
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.
Definition: RNGWrapper.cxx:37
Epos::m_partEnergy
std::vector< double > m_partEnergy
Definition: Epos.h:70
Epos::m_partPz
std::vector< double > m_partPz
Definition: Epos.h:69
Epos::m_partStat
std::vector< int > m_partStat
Definition: Epos.h:72
atl_epos_rndm_
double atl_epos_rndm_(int *)
Definition: Epos.cxx:36
HepMC::set_signal_process_id
void set_signal_process_id(GenEvent *e, const int i)
Definition: GenEvent.h:641
Epos::m_primaryParticle
int m_primaryParticle
Definition: Epos.h:50
GenModule::getRandomEngineDuringInitialize
CLHEP::HepRandomEngine * getRandomEngineDuringInitialize(const std::string &streamName, unsigned long int randomSeedOffset, unsigned int conditionsRun=1, unsigned int lbn=1) const
Definition: GenModule.cxx:53
HepMC::set_random_states
void set_random_states(GenEvent *e, std::vector< T > a)
Definition: GenEvent.h:647