Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First step for trigger inclusion with hybrid #13868

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Generators/include/Generators/Generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ class Generator : public FairGenerator

/** getters **/
const std::vector<TParticle>& getParticles() const { return mParticles; }; //!
void* getInterface() { return mInterface; };
std::string getInterfaceName() { return mInterfaceName; };
ETriggerMode_t getTriggerMode() { return mTriggerMode; };
std::vector<Trigger> getTriggers() { return mTriggers; };
std::vector<DeepTrigger> getDeepTriggers() { return mDeepTriggers; };

/** other **/
void clearParticles() { mParticles.clear(); };
Expand All @@ -106,7 +111,7 @@ class Generator : public FairGenerator
/** internal methods **/
Bool_t addTracks(FairPrimaryGenerator* primGen);
Bool_t boostEvent();
Bool_t triggerEvent();
virtual Bool_t triggerEvent();

/** to handle cocktail constituents **/
void addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription);
Expand Down
3 changes: 3 additions & 0 deletions Generators/include/Generators/GeneratorHybrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class GeneratorHybrid : public Generator
Bool_t Init() override;
Bool_t generateEvent() override;
Bool_t importParticles() override;
Bool_t triggerEvent() override;
void updateHeader(o2::dataformats::MCEventHeader* eventHeader) override;

void setNEvents(int n) { mNEvents = n; }
Expand Down Expand Up @@ -103,6 +104,8 @@ class GeneratorHybrid : public Generator
bool mCocktailMode = false;
std::vector<std::vector<int>> mGroups;

bool mTriggerFlag = true; // Checks if trigger was provided by JSON

// Create a task arena with a specified number of threads
std::thread mTBBTaskPoolRunner;
tbb::concurrent_bounded_queue<int> mInputTaskQueue;
Expand Down
87 changes: 85 additions & 2 deletions Generators/src/GeneratorHybrid.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ Bool_t GeneratorHybrid::Init()
}
gens[count]->Init(); // TODO: move this to multi-threaded
addSubGenerator(count, gen);
// If trigger mode is an unknown value or empty string in the JSON file, it will be set to kTriggerOR
// when at least one generator has trigger mode enabled. If the trigger field is not set then trigger is forced OFF
if (!mTriggerFlag && gens[count]->getTriggerMode()) {
LOG(info) << "Generator " << gen << " has trigger mode enabled to " << gens[count]->getTriggerMode();
LOG(info) << "Setting Hybrid trigger mode to OR";
setTriggerMode(o2::eventgen::Generator::kTriggerOR);
mTriggerFlag = true;
}
count++;
}
if (mRandomize) {
Expand Down Expand Up @@ -349,6 +357,13 @@ bool GeneratorHybrid::importParticles()
// Clear particles and event header
mParticles.clear();
mMCEventHeader.clearInfo();

// Clear trigger information of previous generator
mInterface = nullptr;
mInterfaceName = "";
mDeepTriggers.clear();
mTriggers.clear();

if (mCocktailMode) {
// in cocktail mode we need to merge the particles from the different generators
for (auto subIndex : subGenIndex) {
Expand All @@ -357,6 +372,23 @@ bool GeneratorHybrid::importParticles()
mParticles.insert(mParticles.end(), subParticles.begin(), subParticles.end());
// fetch the event Header information from the underlying generator
gens[subIndex]->updateHeader(&mMCEventHeader);
// Trigger forwarding to hybrid gen for the event
// For cocktail mode only the first generator in the list is used for triggers
// TODO: implement trigger merging for cocktail mode
if (strcmp(mInterfaceName.c_str(), "") == 0) {
if (gens[subIndex]->getTriggers().size() > 0) {
for (auto& Trigger : gens[subIndex]->getTriggers()) {
addTrigger(Trigger);
}
}
if (gens[subIndex]->getDeepTriggers().size() > 0) {
for (auto& deepTrigger : gens[subIndex]->getDeepTriggers()) {
addDeepTrigger(deepTrigger);
}
}
mInterface = gens[subIndex]->getInterface();
mInterfaceName = gens[subIndex]->getInterfaceName();
}
mInputTaskQueue.push(subIndex);
mTasksStarted++;
}
Expand All @@ -366,18 +398,43 @@ bool GeneratorHybrid::importParticles()
mParticles = gens[genIndex]->getParticles();
// fetch the event Header information from the underlying generator
gens[genIndex]->updateHeader(&mMCEventHeader);
// Trigger forwarding to hybrid gen for the event
if (gens[genIndex]->getTriggers().size() > 0) {
for (auto& Trigger : gens[genIndex]->getTriggers()) {
addTrigger(Trigger);
}
}
if (gens[genIndex]->getDeepTriggers().size() > 0) {
for (auto& deepTrigger : gens[genIndex]->getDeepTriggers()) {
addDeepTrigger(deepTrigger);
}
}
mInterface = gens[genIndex]->getInterface();
mInterfaceName = gens[genIndex]->getInterfaceName();
mInputTaskQueue.push(genIndex);
mTasksStarted++;
}

mseqCounter++;
mEventCounter++;

return true;
}

bool GeneratorHybrid::triggerEvent()
{
bool triggered = Generator::triggerEvent();
if (!triggered) {
// counter is decreased when event is rejected, otherwise simulation hangs
// when using trigger mechanism. If no trigger is used all events are
// automatically accepted
mEventCounter--;
}
if (mEventCounter == mNEvents) {
LOG(info) << "HybridGen: Stopping TBB task pool";
mStopFlag = true;
}

return true;
return triggered;
}

void GeneratorHybrid::updateHeader(o2::dataformats::MCEventHeader* eventHeader)
Expand Down Expand Up @@ -485,6 +542,32 @@ Bool_t GeneratorHybrid::parseJSON(const std::string& path)
}
}

// check if there is a trigger field, if not the trigger mode is set to OFF
// unless a generator has a trigger mode specified, in this case it will be forced to OR during the initialization
// TODO: make the triggering options more versatile
if (doc.HasMember("trigger")) {
const auto& trigger = doc["trigger"].GetString();
if (strcmp(trigger, "or") == 0) {
// OR
LOG(info) << "Setting trigger mode to OR";
setTriggerMode(o2::eventgen::Generator::kTriggerOR);
} else if (strcmp(trigger, "and") == 0) {
// AND
LOG(info) << "Setting trigger mode to AND";
setTriggerMode(o2::eventgen::Generator::kTriggerAND);
} else if (strcmp(trigger, "off") == 0) {
LOG(warn) << "Trigger OFF";
} else if (strlen(trigger) == 0) {
// OFF by default
LOG(warn) << "Trigger mode not specified, turning to OR if gen list has a trigger mode specified";
mTriggerFlag = false;
} else {
// OFF by default
LOG(warn) << "Unknown trigger mode, turning to OR if gen list has a trigger mode specified (otherwise OFF)";
mTriggerFlag = false;
}
}

// Put the generator names in mInputGens
if (doc.HasMember("generators")) {
const auto& gens = doc["generators"];
Expand Down
Loading