Skip to content

Commit 1ae6842

Browse files
committed
First working implementation of json configuration file in hybrid generator
1 parent 6ce5b8e commit 1ae6842

File tree

4 files changed

+100
-52
lines changed

4 files changed

+100
-52
lines changed

Generators/include/Generators/GeneratorHybrid.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#include "FairGenerator.h"
3232
#include <DetectorsBase/Stack.h>
3333
#include <SimConfig/SimConfig.h>
34+
#include <rapidjson/document.h>
35+
#include <rapidjson/error/en.h>
36+
#include <rapidjson/istreamwrapper.h>
3437

3538
namespace o2
3639
{
@@ -42,17 +45,20 @@ class GeneratorHybrid : public Generator
4245

4346
public:
4447
GeneratorHybrid() = default;
45-
GeneratorHybrid(const std::vector<std::string>& gens);
48+
GeneratorHybrid(const std::string& inputgens);
4649
~GeneratorHybrid() = default;
4750

4851
Bool_t Init() override;
4952
Bool_t generateEvent() override;
5053
Bool_t importParticles() override;
54+
55+
Bool_t parseJSON(const std::string& path);
5156

5257
private:
5358
o2::eventgen::Generator* currentgen = nullptr;
5459
std::vector<std::unique_ptr<o2::eventgen::Generator>> gens;
5560
const std::vector<std::string> generatorNames = {"extkinO2", "boxgen", "external", "hepmc", "pythia8", "pythia8pp", "pythia8hi", "pythia8hf", "pythia8powheg"};
61+
std::vector<std::string> mInputGens;
5662
std::vector<std::string> mGens;
5763
std::vector<std::string> mConfigs;
5864
std::vector<std::string> mConfsPythia8;

Generators/include/Generators/GeneratorHybridParam.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ namespace eventgen
2929
**/
3030

3131
struct GeneratorHybridParam : public o2::conf::ConfigurableParamHelper<GeneratorHybridParam> {
32-
std::string generators = ""; // generators to be used in the cocktail, each divided by a comma
33-
std::string configs = ""; // configurations for the generators, each divided by a colon
32+
std::string configFile = ""; // JSON configuration file for the generators
3433
bool randomize = false; // randomize the order of the generators, if not generator using fractions
35-
std::string fractions = ""; // events fractions for each generator, works only for sequence
3634
O2ParamDef(GeneratorHybridParam, "GeneratorHybrid");
3735
};
3836

Generators/src/GeneratorFactory.cxx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,18 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair
245245
} else if (genconfig.compare("hybrid") == 0) { // hybrid using multiple generators
246246
LOG(info) << "Init hybrid generator";
247247
auto& hybridparam = GeneratorHybridParam::Instance();
248-
std::string genslist = hybridparam.generators;
249-
LOG(info) << "Generators list: " << genslist;
250-
std::vector<std::string> generators;
251-
std::stringstream ss(genslist);
252-
std::string item;
253-
while (std::getline(ss, item, ',')) {
254-
generators.push_back(item);
248+
std::string config = hybridparam.configFile;
249+
//check if config string points to an existing file and not empty
250+
if (config.empty()) {
251+
LOG(fatal) << "No configuration file provided for hybrid generator";
252+
return;
253+
}
254+
// check if file named config exists and it's not empty
255+
else if (gSystem->AccessPathName(config.c_str())) {
256+
LOG(fatal) << "Configuration file for hybrid generator does not exist";
257+
return;
255258
}
256-
auto hybrid = new o2::eventgen::GeneratorHybrid(generators);
259+
auto hybrid = new o2::eventgen::GeneratorHybrid(config);
257260
primGen->AddGenerator(hybrid);
258261
} else {
259262
LOG(fatal) << "Invalid generator";

Generators/src/GeneratorHybrid.cxx

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,40 @@
1212
#include "Generators/GeneratorHybrid.h"
1313
#include <fairlogger/Logger.h>
1414
#include <algorithm>
15-
#include <FairPrimaryGenerator.h>
1615

1716
namespace o2
1817
{
1918
namespace eventgen
2019
{
21-
GeneratorHybrid::GeneratorHybrid(const std::vector<std::string>& inputgens)
20+
GeneratorHybrid::GeneratorHybrid(const std::string& inputgens)
2221
{
23-
auto configs = GeneratorHybridParam::Instance().configs;
24-
mRandomize = GeneratorHybridParam::Instance().randomize;
25-
std::stringstream ss(configs);
26-
std::string conf;
27-
while (std::getline(ss, conf, ':')) {
28-
mConfigs.push_back(conf);
22+
if (!parseJSON(inputgens)) {
23+
LOG(fatal) << "Failed to parse JSON configuration from input generators";
24+
exit(1);
2925
}
30-
if(mConfigs.size() != inputgens.size()){
26+
mRandomize = GeneratorHybridParam::Instance().randomize;
27+
if (mConfigs.size() != mInputGens.size()) {
3128
LOG(fatal) << "Number of configurations does not match the number of generators";
29+
exit(1);
3230
}
33-
if(mConfigs.size() == 0){
34-
for(auto gen : inputgens){
31+
if (mConfigs.size() == 0){
32+
for(auto gen : mInputGens){
3533
mConfigs.push_back("");
3634
}
3735
}
3836
int index = 0;
3937
if (!mRandomize) {
40-
std::string fractions = GeneratorHybridParam::Instance().fractions;
41-
if(fractions.compare("") == 0){
42-
for (auto gen : inputgens) {
43-
mFractions.push_back(1);
44-
}
38+
if (mFractions.size() != mInputGens.size()) {
39+
LOG(fatal) << "Number of fractions does not match the number of generators";
40+
return;
41+
}
42+
// Check if all elements of mFractions are 0
43+
if (std::all_of(mFractions.begin(), mFractions.end(), [](int i){ return i == 0; })) {
44+
LOG(fatal) << "All fractions provided are 0, no simulation will be performed";
45+
return;
4546
}
46-
else{
47-
std::stringstream streamfrac(fractions);
48-
std::string frac;
49-
while (std::getline(streamfrac, frac, ',')) {
50-
if(frac.compare("") == 0)
51-
mFractions.push_back(1);
52-
else
53-
mFractions.push_back(std::stoi(frac));
54-
}
55-
if(mFractions.size() != inputgens.size()){
56-
LOG(fatal) << "Number of fractions does not match the number of generators";
57-
return;
58-
}
59-
// Check if all elements of mFractions are 0
60-
if (std::all_of(mFractions.begin(), mFractions.end(), [](int i){ return i == 0; })) {
61-
LOG(fatal) << "All fractions provided are 0, no simulation will be performed";
62-
return;
63-
}
64-
65-
}
6647
}
67-
for(auto gen : inputgens)
68-
{
48+
for (auto gen : mInputGens) {
6949
// Search if the generator name is inside generatorNames (which is a vector of strings)
7050
LOG(info) << "Checking if generator " << gen << " is in the list of available generators \n";
7151
if (std::find(generatorNames.begin(), generatorNames.end(), gen) != generatorNames.end())
@@ -133,7 +113,7 @@ namespace o2
133113
}
134114
}
135115
index++;
136-
}
116+
}
137117
}
138118

139119
Bool_t GeneratorHybrid::Init()
@@ -208,7 +188,68 @@ namespace o2
208188
}
209189

210190
return true;
211-
}
191+
}
192+
193+
Bool_t GeneratorHybrid::parseJSON(const std::string& path)
194+
{
195+
// Parse JSON file to build map
196+
std::ifstream fileStream(path, std::ios::in);
197+
if (!fileStream.is_open()) {
198+
LOG(error) << "Cannot open " << path;
199+
return false;
200+
}
201+
rapidjson::IStreamWrapper isw(fileStream);
202+
rapidjson::Document doc;
203+
doc.ParseStream(isw);
204+
if (doc.HasParseError()) {
205+
LOG(error) << "Error parsing provided json file " << path;
206+
LOG(error) << " - Error -> " << rapidjson::GetParseError_En(doc.GetParseError());
207+
LOG(error) << " - Offset -> " << doc.GetErrorOffset();
208+
return false;
209+
}
210+
211+
// Put the generator names in mInputGens
212+
if (doc.HasMember("generators")) {
213+
const auto& gens = doc["generators"];
214+
for (const auto& gen : gens.GetArray()) {
215+
// push in mInputGens the "name" of the generator
216+
mInputGens.push_back(gen["name"].GetString());
217+
if (gen.HasMember("config")) {
218+
//Check if config is an array
219+
if (gen["config"].IsArray()) {
220+
std::string config = "";
221+
for (const auto& conf : gen["config"].GetArray()) {
222+
config += conf.GetString();
223+
config += ",";
224+
}
225+
mConfigs.push_back(config);
226+
} else {
227+
mConfigs.push_back(gen["config"].GetString());
228+
}
229+
}
230+
else {
231+
mConfigs.push_back("");
232+
}
233+
}
234+
}
235+
236+
// Get fractions and put them in mFractions
237+
if (doc.HasMember("fractions")) {
238+
const auto& fractions = doc["fractions"];
239+
for (const auto& frac : fractions.GetArray()) {
240+
mFractions.push_back(frac.GetInt());
241+
}
242+
}
243+
else {
244+
// Set fractions to unity for all generators in case they are not provided
245+
const auto& gens = doc["generators"];
246+
for (const auto& gen : gens.GetArray()) {
247+
mFractions.push_back(1);
248+
}
249+
}
250+
251+
return true;
252+
}
212253

213254
} // namespace eventgen
214255
} // namespace o2

0 commit comments

Comments
 (0)