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