ATLAS Offline Software
Loading...
Searching...
No Matches
Epos4.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ----------------------------------------------------------------------
6// Generators/Epos4.cxx
7//
8//
9// AuthorList:
10// Andrii Verbytskyi
11// Paulina Majchrzak
12// ----------------------------------------------------------------------
13#include "Epos4.h"
15#include "CLHEP/Random/RandFlat.h"
16#include "GaudiKernel/MsgStream.h"
18
19#include "AtlasHepMC/GenEvent.h"
20#include "AtlasHepMC/HeavyIon.h"
22
23#include "HepMC3/GenEvent.h"
24#include "HepMC3/Print.h"
25#include "HepMC3/Writer.h"
26
27
28#include <cstdlib> //for std::getenv
29#include <cstring> //for strlen, memcpy
30#include <filesystem>
31#include <fstream> //for ofstream, ifstream
32#include <iostream>
33#include <memory> //for shared_ptr, dynamic_pointer_cast
34
35
36// Match the Fortran COMMON block layout
37
39 char fnjob[1000]; // Fortran CHARACTER*1000
40 int nfnjob; // Fortran INTEGER
41};
42
43// Declare the Fortran COMMON block symbol
44extern struct jobfnametype jobfname_;
45// C function to set values in the COMMON block
46void set_job_common(const char *filename) {
47 size_t len = std::strlen(filename);
48 if (len > 1000)
49 len = 1000;
50 // Copy filename and pad with spaces
51 std::memcpy(jobfname_.fnjob, filename, len);
52 for (size_t i = len; i < 1000; ++i) {
53 jobfname_.fnjob[i] = ' ';
54 }
55 jobfname_.nfnjob = (int)len;
56}
57
58namespace {
59static std::string epos_rndm_stream = "EPOS4_INIT";
60static CLHEP::HepRandomEngine *p_rndmEngine{};
61} // namespace
62
63extern std::shared_ptr<HepMC3::Writer> writer;
64namespace HepMC3 {
65class WriterEPOS : public Writer {
66public:
67 WriterEPOS([[maybe_unused]] const std::string &filename,
68 std::shared_ptr<GenRunInfo> run = std::shared_ptr<GenRunInfo>()) {
69 set_run_info(std::move(run));
70 }
71 WriterEPOS([[maybe_unused]] std::ostream &stream,
72 std::shared_ptr<GenRunInfo> run = std::shared_ptr<GenRunInfo>()) {
73 set_run_info(std::move(run));
74 }
75 WriterEPOS([[maybe_unused]] std::shared_ptr<std::ostream> s_stream,
76 std::shared_ptr<GenRunInfo> run = std::shared_ptr<GenRunInfo>()) {
77 set_run_info(std::move(run));
78 }
80 void write_event(const GenEvent &evt) override { m_event = evt; };
81 const GenEvent &current_event() const { return m_event; }
82 bool failed() override { return false; };
83 void close() override {}
84
85private:
86 GenEvent m_event;
87};
88} // namespace HepMC3
89
90void checkTime();
93void eposEnd();
94void eposStart();
97void listParticles(int &);
105int setEnergyIndex(int &);
109
110// ----------------------------------------------------------------------
111Epos4::Epos4(const std::string &name, ISvcLocator *pSvcLocator)
112 : GenModule(name, pSvcLocator) {
113
114 epos_rndm_stream = "EPOS4_INIT";
115 declareProperty("InputCard", m_inputcard = "foo.optns");
116 declareProperty("ArgsRandomSeed", m_argsRandomSeed = 0);
117 m_events = 0; // current event number (counted by interface)
118}
119
120namespace fs = std::filesystem;
121std::string Epos4::create_file(const std::string &filein) {
122 if (filein.size() < 6 || filein.compare(filein.size() - 6, 6, ".optns") != 0) {
123 ATH_MSG_ERROR(" Input file name: " << filein
124 << " does not end with \".optns\"\n");
125 return "";
126 }
127
128 fs::path source = filein;
129 fs::path destination =
130 fs::current_path() /
131 fs::path(std::string("z-") + source.filename().string());
132
133 std::ifstream src(source); // Open in text mode
134 std::ofstream dst(destination); // Open in text mode
135
136 if (!src) {
137 ATH_MSG_ERROR(" Cannot open source file: " << source << "\n");
138 return "";
139 }
140
141 if (!dst) {
142 ATH_MSG_ERROR(" Cannot create destination file: " << destination << "\n");
143 return "";
144 }
145
146 std::string line;
147 while (std::getline(src, line)) {
148 dst << line << '\n';
149 }
150 dst << "set ihepmc 1" << '\n';
151
152 std::string file = source.filename().string().size() > 6
153 ? source.filename().string().substr(
154 0, source.filename().string().size() - 6)
155 : "";
156
157 std::string num = "0";
158 std::string one = file;
159 if (num != "0") {
160 one = file + "-" + num;
161 }
162
163 std::string clinput = "z-" + one + ".clinput";
164 std::ofstream ofile(clinput);
165
166 std::string CHK = std::getenv("CHK")
167 ? std::getenv("CHK")
168 : (ATH_MSG_WARNING(" CHK not set\n"), "");
169 if (m_seeds.size() < 2)
170 ATH_MSG_WARNING(" m_seeds should contain at least 2 elements\n");
171 std::string seedj;
172 if (m_argsRandomSeed != 0) {
173 seedj = std::to_string(m_argsRandomSeed);
174 } else if (!m_seeds.empty()) {
175 seedj = std::to_string(m_seeds.at(0));
176 } else {
177 seedj = "111111111";
178 };
179 std::string seedi = m_seeds.size() < 2
180 ? "222222222"
181 : std::to_string(m_seeds.at(
182 1)); // Should be something like "111111111";
183 // for initialisation only
184
185 std::string rootcproot = "nono";
186 std::string system = "i";
187 std::string ext1 = "-";
188 std::string ext3 = "-";
189 std::string ext4 = "-";
190 std::string gefac = "1";
191 auto safeGetenv = [this](const char *envName) -> std::string {
192 const char *env = std::getenv(envName);
193 if (env)
194 return env;
195 ATH_MSG_WARNING(envName << " not set.");
196 return {};
197 };
198 std::string EPO = safeGetenv("EPO");
199 std::string SRCEXT = safeGetenv("SRCEXT");
200 std::string HTO = safeGetenv("HTO");
201 std::string SRC = safeGetenv("SRC");
202 std::string CONF = safeGetenv("CONF");
203 std::string OPT = safeGetenv("OPT");
204 std::string OPX = "";
205 if (std::string(OPT) == "./") {
206 OPX = std::filesystem::current_path().string() + "/";
207 } else {
208 OPX = std::move(OPT);
209 }
210
211 ATH_MSG_DEBUG("EPOS files: \n"
212 << "EPO: " << EPO << "\n"
213 << "SRCEXT: " << SRCEXT << "\n"
214 << " HTO: " << HTO << "\n"
215 << " SRC: " << SRC << "\n"
216 << " OPX: " << OPX <<"\n"
217 << " CHK: " << CHK << "\n"
218 );
219
220
221 ofile << "!fname mtr " << CHK << "z-" << one << ".mtr\n";
222 ofile << "set seedj " << seedj << " set seedi " << seedi << "\n";
223 ofile << "echo off\n";
224 ofile << "rootcproot " << rootcproot << "\n";
225 ofile << "system " << system << "\n";
226 ofile << "ext1 " << ext1 << "\n";
227 ofile << "ext3 " << ext3 << "\n";
228 ofile << "ext4 " << ext4 << "\n";
229 ofile << "set gefac " << gefac << "\n";
230 ofile << "!!!beginoptns spherio !No longer used.\n";
231 ofile << "!!!... !See version < 3118 \n";
232 ofile << "!!!endoptns spherio !if needed again \n";
233 ofile << "fname pathep " << EPO << "\n";
234 ofile << "!-------HQ--------\n";
235 ofile << "fname user1 " << SRCEXT << "/HQt/\n";
236 ofile << "fname user2 " << HTO << "z-" << one << ".hq\n";
237 ofile << "fname user3 " << SRCEXT << "/URt/\n";
238 ofile << "!-------HQ END--------\n";
239 ofile << "fname pathpdf " << SRC << "/TPt/\n";
240 ofile << "fname histo " << HTO << "z-" << one << ".histo\n";
241 ofile << "fname check " << CHK << "z-" << one << ".check\n";
242 ofile << "fname copy " << CHK << "z-" << one << ".copy\n";
243 ofile << "fname log " << CHK << "z-" << one << ".log\n";
244 ofile << "fname data " << CHK << "z-" << one << ".data\n";
245 ofile << "fname initl " << SRC << "/KWt/aa.i\n";
246 ofile << "fname inidi " << SRC << "/TPt/di.i\n";
247 ofile << "fname inidr " << SRC << "/KWt/dr.i\n";
248 ofile << "fname iniev " << SRC << "/KWt/ev.i\n";
249 ofile << "fname inirj " << SRC << "/KWt/rj.i\n";
250 ofile << "fname inics " << SRC << "/TPt/cs.i\n";
251 ofile << "fname inigrv " << SRC << "/grv.i\n";
252 ofile << "fname partab " << SRCEXT << "/YK/ptl6.data\n";
253 ofile << "fname dectab " << SRCEXT << "/YK/dky6.data\n";
254 ofile << "fname hpf " << SRCEXT << "/UR/tables.dat \n";
255 ofile << "!fqgsjet dat " << EPO << SRC
256 << "qgsjet/qgsjet.dat !No longer used.\n";
257 ofile << "!fqgsjet ncs " << EPO << SRC
258 << "qgsjet/qgsjet.ncs !No longer used.\n";
259 ofile << "!fqgsjetII dat " << EPO << SRC
260 << "qgsjetII/qgsdat-II-03 !No longer used.\n";
261 ofile << "!fqgsjetII ncs " << EPO << SRC
262 << "qgsjetII/sectnu-II-03 !No longer used.\n";
263 ofile << "nodecay 1220\n";
264 ofile << "nodecay -1220\n";
265 ofile << "nodecay 120\n";
266 ofile << "nodecay -120\n";
267 ofile << "nodecay 130\n";
268 ofile << "nodecay -130\n";
269 ofile << "nodecay -20\n";
270 ofile << "nodecay 14\n";
271 ofile << "nodecay -14\n";
272 ofile << "nodecay 16\n";
273 ofile << "nodecay -16\n";
274 ofile << "echo on\n";
275 ofile << "input " << CONF << "/parbf.i\n";
276 ofile << "input " << OPX << "z-" << one << ".optns\n";
277 ofile << "input " << SRC << "/KWn/paraf.i\n";
278 ofile << "input " << CONF << "/partx.i\n";
279 ofile << "runprogram\n";
280 ofile << "stopprogram\n";
281
282 ofile.close();
283 return clinput;
284}
285
286// ----------------------------------------------------------------------
288 p_rndmEngine = getRandomEngineDuringInitialize(epos_rndm_stream, m_randomSeed,
289 m_dsid); // NOT THREAD-SAFE
290 epos_rndm_stream = "EPOS4";
291 m_events = 0;
292
293 writer = std::make_shared<HepMC3::WriterEPOS>("foo");
294 const std::string &x = this->create_file(m_inputcard);
295 set_job_common(x.c_str());
297 checkTime();
298 eposStart();
302 int currentnumberOfEnergyValues = numberOfEnergyValues();
304 for (int k = 1; k <= currentnumberOfEnergyValues; k++) {
309 }
310 ATH_MSG_DEBUG( "EPOS initialization finalized.");
311 return StatusCode::SUCCESS;
312}
313
314// ----------------------------------------------------------------------
316 // Re-seed the random number stream
317 ATH_MSG_DEBUG("Generating event #" << m_events);
318 long seeds[7];
319 const EventContext &ctx = Gaudi::Hive::currentContext();
320 ATHRNG::calculateSeedsMC21(seeds, epos_rndm_stream,
321 ctx.eventID().event_number(), m_dsid,
323 p_rndmEngine->setSeeds(seeds, 0); // NOT THREAD-SAFE
324 // save the random number seeds in the event
325 const long *s = p_rndmEngine->getSeeds();
326 m_seeds.assign({s[0], s[1]});
327 ++m_events;
330 ATH_MSG_DEBUG("Generated event #" << m_events);
331
332 return StatusCode::SUCCESS;
333}
334
335// ----------------------------------------------------------------------
336StatusCode Epos4::genFinalize() {
337 ATH_MSG_INFO("EPOS4 finalizing.");
338 ATH_MSG_INFO("MetaData: generator = Epos4 .");
343 eposEnd();
345 ATH_MSG_DEBUG("Total generated events: " << m_events);
346 return StatusCode::SUCCESS;
347}
348
349// ----------------------------------------------------------------------
350StatusCode Epos4::fillEvt(HepMC::GenEvent *evt) {
351 auto e =
352 std::dynamic_pointer_cast<HepMC3::WriterEPOS>(writer)->current_event();
354
355 e.set_units(HepMC3::Units::MEV, HepMC3::Units::MM);
356 ATH_MSG_DEBUG("Event #" << m_events
357 << " | particles: " << e.particles().size()
358 << " | vertices: " << e.vertices().size());
359
360 *evt = e;
361 return StatusCode::SUCCESS;
362}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
void checkTime()
void eposEnd()
int numberOfEnergyValues()
void finalizeSimulation()
std::shared_ptr< HepMC3::Writer > writer
int numberOfEvents()
void initializeElectronProtonPart()
void showMemoryAtStart()
int setEnergyIndex(int &)
void set_job_common(const char *filename)
Definition Epos4.cxx:46
void readInputFile()
void listParticles(int &)
void initializeEventCounters()
struct jobfnametype jobfname_
void generateEposEvent(int &)
void defineStorageSettings()
void initializeEpos()
void initializeHeavyQuarkPart()
void showMemoryAtEnd()
void rewindInputFile()
void eposStart()
void writeStatistics()
static Double_t fs
#define x
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
virtual StatusCode genFinalize() override
For finalising the generator, if required.
Definition Epos4.cxx:336
virtual StatusCode genInitialize() override
For initializing the generator, if required.
Definition Epos4.cxx:287
virtual StatusCode callGenerator() override
For calling the generator on each iteration of the event loop.
Definition Epos4.cxx:315
std::string m_inputcard
Definition Epos4.h:33
std::string create_file(const std::string &filein)
Definition Epos4.cxx:121
IntegerProperty m_dsid
Definition Epos4.h:46
Epos4(const std::string &name, ISvcLocator *pSvcLocator)
Definition Epos4.cxx:111
int m_events
Definition Epos4.h:36
std::vector< long int > m_seeds
Definition Epos4.h:48
int m_argsRandomSeed
Definition Epos4.h:43
virtual StatusCode fillEvt(HepMC::GenEvent *evt) override
For filling the HepMC event object.
Definition Epos4.cxx:350
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
WriterEPOS(std::shared_ptr< std::ostream > s_stream, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Definition Epos4.cxx:75
const GenEvent & current_event() const
Definition Epos4.cxx:81
void write_event(const GenEvent &evt) override
Definition Epos4.cxx:80
void close() override
Definition Epos4.cxx:83
WriterEPOS(std::ostream &stream, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Definition Epos4.cxx:71
WriterEPOS(const std::string &filename, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Definition Epos4.cxx:67
bool failed() override
Definition Epos4.cxx:82
GenEvent m_event
Definition Epos4.cxx:86
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.
char fnjob[1000]
Definition Epos4.cxx:39
TFile * file
int run(int argc, char *argv[])