Skip to content

Commit 88725a7

Browse files
committed
Cleaned and improved generator
Header files folders are now directly included in the ROOT_INCLUDE_PATHs via the recipes
1 parent edd991d commit 88725a7

1 file changed

Lines changed: 85 additions & 163 deletions

File tree

Lines changed: 85 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,48 @@
1-
// Set include paths for ThePEG headers
2-
R__ADD_INCLUDE_PATH($THEPEG_ROOT/include/)
3-
R__ADD_INCLUDE_PATH($THEPEG_ROOT/../../GSL/latest/include/)
4-
R__ADD_INCLUDE_PATH($HEPMC3_ROOT/include/)
5-
R__ADD_INCLUDE_PATH($HERWIG_ROOT/include/)
61
#define SKIP_HEPMC_CONVERSION 1
72
#define HAVE_HEPMC3 1
8-
#define ThePEG_DEBUG_LEVEL 1
93

104
// O2DPG and ROOT includes
115
#include "FairGenerator.h"
126
#include "FairPrimaryGenerator.h"
137
#include "fairlogger/Logger.h"
14-
#include "TRandom3.h"
158
#include "TParticle.h"
16-
#include "TParticlePDG.h"
17-
#include "TDatabasePDG.h"
189
#include "TLorentzVector.h"
19-
#include "TMath.h"
20-
#include <fstream>
2110
#include <iostream>
2211
#include <vector>
2312
#include <string>
24-
#include <memory>
25-
26-
// Undefine conflicting macros before including ThePEG headers
27-
#ifdef B0
28-
#undef B0
29-
#endif
30-
#ifdef B50
31-
#undef B50
32-
#endif
33-
#ifdef B75
34-
#undef B75
35-
#endif
36-
#ifdef B110
37-
#undef B110
38-
#endif
39-
#ifdef B134
40-
#undef B134
41-
#endif
42-
#ifdef B150
43-
#undef B150
44-
#endif
45-
#ifdef B200
46-
#undef B200
47-
#endif
48-
#ifdef B300
49-
#undef B300
50-
#endif
51-
#ifdef B600
52-
#undef B600
53-
#endif
54-
#ifdef B1200
55-
#undef B1200
56-
#endif
57-
#ifdef B1800
58-
#undef B1800
59-
#endif
60-
#ifdef B2400
61-
#undef B2400
62-
#endif
63-
#ifdef B4800
64-
#undef B4800
65-
#endif
66-
#ifdef B9600
67-
#undef B9600
68-
#endif
69-
#ifdef B19200
70-
#undef B19200
71-
#endif
72-
#ifdef B38400
73-
#undef B38400
74-
#endif
75-
76-
// ThePEG and Herwig includes
13+
14+
// ThePEG
7715
#include "ThePEG/Repository/EventGenerator.h"
7816
#include "ThePEG/EventRecord/Event.h"
7917
#include "ThePEG/EventRecord/Particle.h"
8018
#include "ThePEG/EventRecord/Step.h"
8119
#include "ThePEG/Config/ThePEG.h"
8220
#include "ThePEG/PDT/ParticleData.h"
83-
#include "ThePEG/Vectors/HepMCConverter.h"
8421
#include "ThePEG/Repository/Repository.h"
85-
#include "ThePEG/Repository/BaseRepository.h"
86-
#include "ThePEG/Utilities/DynamicLoader.h"
87-
#include "ThePEG/Persistency/PersistentIStream.h"
8822

89-
// Herwig specific includes
23+
// Herwig
9024
#include "Herwig/API/HerwigAPI.h"
9125
#include "Herwig/API/HerwigUI.h"
9226

93-
// Subclass of HerwigUI to provide minimal implementation for our use case
27+
// Subclass of HerwigUI to provide minimal implementation of the abstract class
9428
class SimpleHerwigUI : public Herwig::HerwigUI
9529
{
9630
public:
9731
SimpleHerwigUI(const std::string &inFile,
98-
Herwig::RunMode::Mode mode = Herwig::RunMode::READ)
32+
Herwig::RunMode::Mode mode = Herwig::RunMode::READ, int seed = 0)
9933
: m_inFile(inFile), m_mode(mode),
100-
m_in(inFile), m_out(std::cout), m_err(std::cerr)
34+
m_in(inFile), m_out(std::cout), m_err(std::cerr), mSeed(seed)
10135
{
10236
if (!m_in)
103-
throw std::runtime_error("Cannot open Herwig input file: " + inFile);
104-
Dirs.reserve(5);
37+
{
38+
LOG(fatal) << "Cannot open Herwig input file: " << inFile;
39+
exit(1);
40+
}
10541
std::string hDir = std::getenv("HERWIG_ROOT");
10642
if (!hDir.empty())
43+
{
10744
Dirs.push_back(hDir + "/share/Herwig");
45+
}
10846
}
10947

11048
Herwig::RunMode::Mode runMode() const override { return m_mode; }
@@ -132,8 +70,8 @@ public:
13270
return empty;
13371
}
13472

135-
long N() const override { return 10; } // number of events
136-
int seed() const override { return 1234; }
73+
long N() const override { return 1; } // number of events
74+
int seed() const override { return mSeed; }
13775
int jobs() const override { return 1; }
13876
unsigned int jobSize() const override { return 1; }
13977
unsigned int maxJobs() const override { return 1; }
@@ -152,6 +90,7 @@ private:
15290
std::ostream &m_out;
15391
std::ostream &m_err;
15492
std::vector<std::string> Dirs;
93+
int mSeed = 0;
15594
};
15695

15796
namespace o2
@@ -161,52 +100,51 @@ namespace eventgen
161100

162101
/// HERWIG7 event generator using ThePEG interface
163102
/// Author: Marco Giacalone (marco.giacalone@cern.ch)
164-
/// Based on the O2DPG external generator patterns
103+
/// Based on the O2DPG external generator configurations
165104
class GeneratorHerwig : public Generator
166105
{
167106
public:
168107
/// Default constructor
169-
GeneratorHerwig(const std::string& configFile = "LHC.in")
108+
GeneratorHerwig(const std::string& configFile = "LHC.in", int seed = -1)
170109
: mConfigFile(configFile)
171110
, mEventGenerator(nullptr)
172111
{
173-
LOG(info) << "HERWIG7 Generator initialized";
112+
LOG(info) << "HERWIG7 Generator construction";
174113
LOG(info) << "Config file: " << mConfigFile;
175114
std::string extension = mConfigFile.substr(mConfigFile.find_last_of("."));
176115
if( extension == ".in" ) {
177116
mIsInputFile = true;
178117
LOG(info) << "Using input file for configuration";
179-
} else if(std::find(mConfigFile.end()-4, mConfigFile.end(), '.run') != mConfigFile.end()) {
118+
} else if(extension == ".run") {
180119
mIsInputFile = false;
181120
LOG(info) << "Using run file for configuration";
182121
} else {
183122
LOG(fatal) << "No file extension found in config file: " << mConfigFile;
184123
exit(1);
185124
}
125+
if (seed == -1)
126+
{
127+
auto &conf = o2::conf::SimConfig::Instance();
128+
mSeed = gRandom->Integer(conf.getStartSeed());
129+
} else {
130+
mSeed = seed;
131+
}
132+
LOG(info) << "Using seed: " << mSeed << " for HERWIG simulation";
186133
}
187134

188135
/// Destructor
189-
~GeneratorHerwig(){
190-
delete mEventGenerator;
191-
};
136+
~GeneratorHerwig() = default;
192137

193138
/// Initialize the generator
194139
Bool_t Init() override
195140
{
196141
LOG(info) << "Initializing HERWIG7 Generator";
197-
198-
try {
199-
if (mIsInputFile) {
200-
// Process .in file
201-
return initFromInputFile();
202-
} else {
203-
// Process .run file directly
204-
return initFromRunFile();
205-
}
206-
207-
} catch (const std::exception& e) {
208-
LOG(fatal) << "Exception during HERWIG7 initialization: " << e.what();
209-
return kFALSE;
142+
if (mIsInputFile) {
143+
// Process .in file
144+
return initFromInputFile();
145+
} else {
146+
// Process .run file directly
147+
return initFromRunFile();
210148
}
211149
}
212150

@@ -217,28 +155,23 @@ public:
217155
LOG(error) << "Event generator not initialized";
218156
return kFALSE;
219157
}
220-
try {
221-
// Clear previous event particles
222-
hParticles.clear();
223-
224-
// Generate the event
225-
ThePEG::EventPtr event = mEventGenerator->shoot();
226-
227-
if (!event) {
228-
LOG(error) << "Failed to generate event";
229-
return kFALSE;
230-
}
231-
232-
// Convert ThePEG event to TParticle format
233-
convertEvent(event);
234-
LOG(debug) << "Herwig7 generated " << hParticles.size();
158+
// Clear previous event particles
159+
hParticles.clear();
235160

236-
return kTRUE;
237-
238-
} catch (const std::exception& e) {
239-
LOG(error) << "Exception during event generation: " << e.what();
161+
// Generate the event
162+
mPEGEvent = mEventGenerator->shoot();
163+
164+
if (!mPEGEvent)
165+
{
166+
LOG(error) << "Failed to generate event";
240167
return kFALSE;
241168
}
169+
170+
// Convert ThePEG event to TParticle format
171+
convertEvent(mPEGEvent);
172+
LOG(debug) << "Herwig7 generated " << hParticles.size() << " particles";
173+
174+
return kTRUE;
242175
}
243176

244177
/// Import particles for transport
@@ -259,9 +192,11 @@ public:
259192

260193
private:
261194
std::string mConfigFile; ///< HERWIG config file (.in or .run)
262-
Bool_t mIsInputFile = false; ///< True for .in files, false for .run files
195+
Bool_t mIsInputFile = false; ///< True for .in files, false for .run files
263196
ThePEG::EGPtr mEventGenerator; ///< ThePEG event generator
264197
std::vector<TParticle> hParticles; ///< Generated Herwig particles
198+
ThePEG::EventPtr mPEGEvent; ///< Pointer to Current event
199+
int mSeed = 0; ///< Random seed for Herwig
265200

266201
void printHerwigSearchPaths()
267202
{
@@ -277,61 +212,48 @@ private:
277212
{
278213
LOG(info) << "Initializing from .in file: " << mConfigFile;
279214

280-
try {
281-
using namespace ThePEG;
282-
SimpleHerwigUI ui(mConfigFile, Herwig::RunMode::READ);
283-
284-
Herwig::API::read(ui);
285-
printHerwigSearchPaths();
286-
std::string runFile = mConfigFile;
287-
size_t pos = runFile.find_last_of('.');
288-
runFile.replace(pos, 4, ".run");
289-
mConfigFile = runFile;
290-
LOG(info) << "Generated run file: " << runFile;
291-
auto res = initFromRunFile();
292-
if (!res) {
293-
LOG(error) << "Failed to initialize from generated run file";
294-
return kFALSE;
295-
}
296-
return kTRUE;
297-
}
298-
catch (const std::exception &e)
299-
{
300-
std::cerr << "Exception: " << e.what() << std::endl;
215+
using namespace ThePEG;
216+
SimpleHerwigUI ui(mConfigFile, Herwig::RunMode::READ, mSeed);
217+
Herwig::API::read(ui);
218+
// For debugging, print the search paths
219+
// printHerwigSearchPaths();
220+
std::string runFile = mConfigFile;
221+
size_t pos = runFile.find_last_of('.');
222+
runFile.replace(pos, 4, ".run");
223+
mConfigFile = runFile;
224+
LOG(info) << "Generated run file: " << runFile;
225+
auto res = initFromRunFile();
226+
if (!res) {
227+
LOG(error) << "Failed to initialize from generated run file";
301228
return kFALSE;
302229
}
230+
return kTRUE;
303231
}
304232

305233
/// Initialize from .run file
306234
Bool_t initFromRunFile()
307235
{
308236
LOG(info) << "Initializing from .run file: " << mConfigFile;
309237

310-
try {
311-
using namespace ThePEG;
312-
313-
if (!std::ifstream(mConfigFile))
314-
{
315-
LOG(info) << "Run file does not exist: " << mConfigFile;
316-
return kFALSE;
317-
}
318-
SimpleHerwigUI runui(mConfigFile, Herwig::RunMode::RUN);
319-
// Prepare the generator
320-
mEventGenerator = Herwig::API::prepareRun(runui);
321-
if (!mEventGenerator)
322-
{
323-
std::cerr << "Error: prepareRun() returned null." << std::endl;
324-
return kFALSE;
325-
}
326-
327-
mEventGenerator->initialize();
328-
std::cout << "Herwig generator initialized successfully." << std::endl;
329-
return kTRUE;
238+
using namespace ThePEG;
239+
240+
if (!std::ifstream(mConfigFile))
241+
{
242+
LOG(info) << "Run file does not exist: " << mConfigFile;
243+
return kFALSE;
330244
}
331-
catch (const std::exception &ex) {
332-
LOG(error) << "Standard exception: " << ex.what();
245+
SimpleHerwigUI runui(mConfigFile, Herwig::RunMode::RUN, mSeed);
246+
// Prepare the generator
247+
mEventGenerator = Herwig::API::prepareRun(runui);
248+
if (!mEventGenerator)
249+
{
250+
LOG(fatal) << "Error: prepareRun() returned null.";
333251
return kFALSE;
334252
}
253+
254+
mEventGenerator->initialize();
255+
LOG(info) << "Herwig generator initialized successfully.";
256+
return kTRUE;
335257
}
336258

337259
/// Convert ThePEG event to TParticle format
@@ -396,10 +318,10 @@ private:
396318
} // namespace eventgen
397319
} // namespace o2
398320

399-
/// Factory function to create HERWIG7 generator from .in file
400-
/// @param inputFile HERWIG input/run file (e.g., "LHC.in"/"LHC.run")
401-
FairGenerator* generateHerwig7(const std::string& inputFile = "LHC.in")
321+
/// HERWIG7 generator from .in/.run file. If seed is -1, a random seed is chosen
322+
/// based on the SimConfig starting seed.
323+
FairGenerator* generateHerwig7(const std::string& inputFile = "LHC.in", int seed = -1)
402324
{
403-
auto generator = new o2::eventgen::GeneratorHerwig(inputFile);
325+
auto generator = new o2::eventgen::GeneratorHerwig(inputFile, seed);
404326
return generator;
405327
}

0 commit comments

Comments
 (0)