21#include "FairPrimaryGenerator.h"
22#include <fairlogger/Logger.h>
24#include "TClonesArray.h"
32#ifdef GENERATORS_WITH_TPCLOOPERS
36#ifdef GENERATORS_WITH_PYTHIA8
47unsigned int Generator::gTotalNEvents = 0;
51 static const bool isHY = std::getenv(
"IS_HYPERLOOP") && std::atoi(std::getenv(
"IS_HYPERLOOP"));
63#ifdef GENERATORS_WITH_TPCLOOPERS
66 if (!loopersParam.loopersVeto) {
67 bool transport = (simConfig.getMCEngine() !=
"O2TrivialMCEngine");
69 bool tpcActive = (std::find(simConfig.getReadoutDetectors().begin(), simConfig.getReadoutDetectors().end(),
"TPC") != simConfig.getReadoutDetectors().end());
71 if (initTPCLoopersGen()) {
72 mAddTPCLoopers = kTRUE;
75 LOG(info) <<
"TPC not active in readout detectors: loopers fast generator disabled.";
79 LOG(info) <<
"Loopers fast generator turned OFF with veto flag.";
92#ifdef GENERATORS_WITH_TPCLOOPERS
95 if (!loopersParam.loopersVeto) {
96 bool transport = (simConfig.getMCEngine() !=
"O2TrivialMCEngine");
98 bool tpcActive = (std::find(simConfig.getReadoutDetectors().begin(), simConfig.getReadoutDetectors().end(),
"TPC") != simConfig.getReadoutDetectors().end());
100 if (initTPCLoopersGen()) {
101 mAddTPCLoopers = kTRUE;
104 LOG(info) <<
"TPC not active in readout detectors: loopers fast generator disabled.";
108 LOG(info) <<
"Loopers fast generator turned OFF with veto flag.";
118#ifdef GENERATORS_WITH_TPCLOOPERS
119 if (mTPCLoopersGen) {
120 delete mTPCLoopersGen;
121 mTPCLoopersGen =
nullptr;
124#ifdef GENERATORS_WITH_PYTHIA8
125 if (mEventDecayerReport) {
126 LOG(info) <<
"EventDecayer summary of generator " << GetName();
127 mEventDecayerReport->
print();
129 delete mEventDecayer;
130 delete mEventDecayerReport;
135#ifdef GENERATORS_WITH_TPCLOOPERS
136bool Generator::initTPCLoopersGen()
140 auto expandPathName = [](
const std::string&
path) {
141 TString expandedPath =
path;
142 gSystem->ExpandPathName(expandedPath);
143 return std::string(expandedPath.Data());
145 std::string model_pairs = expandPathName(loopersParam.model_pairs);
146 std::string model_compton = expandPathName(loopersParam.model_compton);
147 std::string nclxrate = expandPathName(loopersParam.nclxrate);
148 const std::string scaler_pair = expandPathName(loopersParam.scaler_pair);
149 const std::string scaler_compton = expandPathName(loopersParam.scaler_compton);
150 const std::string poisson = expandPathName(loopersParam.poisson);
151 const std::string gauss = expandPathName(loopersParam.gauss);
152 const auto& flat_gas = loopersParam.flat_gas;
153 const auto& colsys = loopersParam.colsys;
155 if (colsys !=
"PbPb" && colsys !=
"pp") {
156 LOG(warning) <<
"Automatic background loopers configuration supports only 'pp' and 'PbPb' systems.";
157 LOG(warning) <<
"Fast loopers generator will remain OFF.";
160 bool isContext = std::filesystem::exists(
"collisioncontext.root");
162 LOG(warning) <<
"Warning: No collisioncontext.root file found!";
163 LOG(warning) <<
"Loopers will be kept OFF.";
167 std::array<float, 2> multiplier = {loopersParam.multiplier[0], loopersParam.multiplier[1]};
168 unsigned int nLoopersPairs = loopersParam.fixedNLoopers[0];
169 unsigned int nLoopersCompton = loopersParam.fixedNLoopers[1];
170 const std::array<std::string, 3> models = {model_pairs, model_compton, nclxrate};
171 const std::array<std::string, 3> local_names = {
"WGANpair.onnx",
"WGANcompton.onnx",
"nclxrate.root"};
172 const std::array<bool, 3> isAlien = {models[0].starts_with(
"alien://"), models[1].starts_with(
"alien://"), models[2].starts_with(
"alien://")};
173 const std::array<bool, 3> isCCDB = {models[0].starts_with(
"ccdb://"), models[1].starts_with(
"ccdb://"), models[2].starts_with(
"ccdb://")};
174 if (std::any_of(isAlien.begin(), isAlien.end(), [](
bool v) { return v; })) {
176 TGrid::Connect(
"alien://");
178 LOG(fatal) <<
"AliEn connection failed, check token.";
182 for (
size_t i = 0;
i < models.size(); ++
i) {
183 if (isAlien[
i] && !TFile::Cp(models[
i].c_str(), local_names[
i].c_str())) {
184 LOG(fatal) <<
"Error: Model file " << models[
i] <<
" does not exist!";
189 if (std::any_of(isCCDB.begin(), isCCDB.end(), [](
bool v) { return v; })) {
191 ccdb.setURL(
"http://alice-ccdb.cern.ch");
193 auto& ccdb_api = ccdb.getCCDBAccessor();
194 for (
size_t i = 0;
i < models.size(); ++
i) {
196 auto model_path = models[
i].substr(7);
198 auto extension = model_path.find(
".onnx");
199 if (extension != std::string::npos) {
200 auto last_slash = model_path.find_last_of(
'/');
201 model_path = model_path.substr(0, last_slash);
203 std::map<std::string, std::string>
filter;
205 LOG(fatal) <<
"Error: issues in retrieving " << model_path <<
" from CCDB!";
211 model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs;
212 model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton;
213 nclxrate = isAlien[2] || isCCDB[2] ? local_names[2] : nclxrate;
216 mTPCLoopersGen =
new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton);
217 mTPCLoopersGen->setGeomProtection(loopersParam.geomProtection);
218 const auto& intrate = loopersParam.intrate;
222 mTPCLoopersGen->SetRate(nclxrate, (colsys ==
"PbPb") ?
true : false, intrate);
223 mTPCLoopersGen->SetAdjust(loopersParam.adjust_flatgas);
228 mTPCLoopersGen->SetNLoopers(nLoopersPairs, nLoopersCompton);
229 mTPCLoopersGen->SetMultiplier(multiplier);
231 LOG(info) <<
"TPC Loopers generator initialized successfully";
232 }
catch (
const std::exception& e) {
233 LOG(error) <<
"Failed to initialize TPC Loopers generator: " << e.what();
234 delete mTPCLoopersGen;
235 mTPCLoopersGen =
nullptr;
258#ifdef GENERATORS_WITH_TPCLOOPERS
259 if (mAddTPCLoopers) {
260 if (!mTPCLoopersGen) {
261 LOG(error) <<
"Loopers generator not initialized";
266 if (!mTPCLoopersGen->generateEvent()) {
267 LOG(error) <<
"Failed to generate loopers event";
270 const auto nCandidates = mTPCLoopersGen->getNLoopers();
271 if (nCandidates == 0) {
272 LOG(warning) <<
"No loopers generated for this event";
275 const auto& looperParticles = mTPCLoopersGen->importParticles();
276 const auto skippedLoopers = mTPCLoopersGen->getNSkipped();
277 if (looperParticles.empty()) {
278 if (skippedLoopers == nCandidates) {
280 LOG(
debug) <<
"All " << skippedLoopers <<
" candidate loopers were outside the TPC active volume; none added for this event";
283 LOG(error) <<
"Failed to import loopers particles";
289 LOG(
debug) <<
"Added " << looperParticles.size() <<
" looper particles";
290 if (skippedLoopers > 0) {
291 LOG(
debug) <<
"Geometrical protection skipped " << skippedLoopers <<
" loopers outside the TPC active volume";
313 mSubGeneratorId = -1;
317 LOG(error) <<
"ReadEvent failed in generateEvent";
323 LOG(error) <<
"ReadEvent failed in importParticles";
329 LOG(error) <<
"ReadEvent failed in finalizeEvent";
333 if (mSubGeneratorsIdToDesc.empty() && mSubGeneratorId > -1) {
334 LOG(fatal) <<
"ReadEvent failed because no SubGenerator description given";
337 if (!mSubGeneratorsIdToDesc.empty() && mSubGeneratorId < 0) {
338 LOG(fatal) <<
"ReadEvent failed because SubGenerator description given but sub-generator not set";
350 auto header = primGen->GetEvent();
353 LOG(fatal) <<
"MC event header is not a 'o2::dataformats::MCEventHeader' object";
358 if (!decayParticles(o2header)) {
359 LOG(error) <<
"ReadEvent failed in decayParticles";
365 LOG(error) <<
"ReadEvent failed in addTracks";
371 updateSubGeneratorInformation(o2header);
382#ifdef GENERATORS_WITH_PYTHIA8
386 if (!mEventDecayer) {
387 mEventDecayer =
new EventDecayer();
388 if (!mEventDecayer->
init()) {
389 LOG(fatal) <<
"Could not initialise the EventDecayer of generator " << GetName();
392 mEventDecayerReport =
new EventDecayerReport();
398 header->putInfo<
int>(
"eventDecayerSeed", mEventDecayer->
seed());
413 LOG(fatal) <<
"PrimaryGenerator is not a o2::eventgen::PrimaryGenerator";
419 o2primGen->
AddTrack(particle.GetPdgCode(),
426 particle.GetMother(0),
427 particle.GetMother(1),
428 particle.GetDaughter(0),
429 particle.GetDaughter(1),
433 particle.GetWeight(),
434 (TMCProcess)particle.GetUniqueID(),
435 particle.GetStatusCode());
507 if (subGeneratorId < 0) {
508 LOG(fatal) <<
"Sub-generator IDs must be >= 0, instead, passed value is " << subGeneratorId;
510 mSubGeneratorsIdToDesc.insert({subGeneratorId, subGeneratorDescription});
517 if (mSubGeneratorId < 0) {
std::vector< std::string > header
ClassImp(o2::eventgen::Generator)
static BasicCCDBManager & instance()
static const GenTPCLoopersParam & Instance()
static SimConfig & Instance()
void setUnits(double positionUnit, double timeUnit, double momentumUnit=1., double energyUnit=1.)
Sets the caller's units in cm, s, GeV/c and GeV, as the unit setters of Generator (default cm,...
EventDecayerReport decay(std::vector< TParticle > &particles)
std::string configSummary() const
virtual void updateHeader(o2::dataformats::MCEventHeader *eventHeader)
std::string mInterfaceName
Bool_t ReadEvent(FairPrimaryGenerator *primGen) final
static std::atomic< int > InstanceCounter
std::vector< Trigger > mTriggers
std::function< void(std::vector< TParticle > const &p, int eventCount)> mTriggerOkHook
virtual Bool_t generateEvent()=0
std::vector< DeepTrigger > mDeepTriggers
std::function< void(std::vector< TParticle > const &p, int eventCount)> mTriggerFalseHook
void addSubGenerator(int subGeneratorId, std::string const &subGeneratorDescription)
ETriggerMode_t mTriggerMode
static bool isHyperloop()
Bool_t addTracks(FairPrimaryGenerator *primGen)
std::vector< TParticle > mParticles
virtual Bool_t importParticles()=0
void AddTrack(Int_t pdgid, Double_t px, Double_t py, Double_t pz, Double_t vx, Double_t vy, Double_t vz, Int_t mother1=-1, Int_t mother2=-1, Int_t daughter1=-1, Int_t daughter2=-1, Bool_t wanttracking=true, Double_t e=-9e9, Double_t tof=0., Double_t weight=0., TMCProcess proc=kPPrimary, Int_t generatorStatus=0)
static constexpr Property SUBGENERATORID
static constexpr Property SUBGENERATORDESCRIPTIONMAP
GLuint const GLchar * name
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void merge(EventDecayerReport const &other)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"