From ee7372ea7f097297738dae22f34f0b5558e4bfe9 Mon Sep 17 00:00:00 2001 From: Alberto Caliva Date: Thu, 29 Jan 2026 16:22:22 +0100 Subject: [PATCH] Add generators for light-ion systems based on EPOS4 --- .../epos4/generator/NeNe_536TeV_EPOS4.optns | 32 ++++++++ .../epos4/generator/OO_536TeV_EPOS4.optns | 32 ++++++++ .../examples/ini/GeneratorEPOS4NeNe536TeV.ini | 12 +++ .../examples/ini/GeneratorEPOS4OO536TeV.ini | 12 +++ .../ini/tests/GeneratorEPOS4NeNe536TeV.C | 78 +++++++++++++++++++ .../ini/tests/GeneratorEPOS4OO536TeV.C | 78 +++++++++++++++++++ 6 files changed, 244 insertions(+) create mode 100644 MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns create mode 100644 MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns create mode 100644 MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini create mode 100644 MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C create mode 100644 MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns new file mode 100644 index 000000000..9c7df71a3 --- /dev/null +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! Neon-Neon collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 10 !projectile atomic number +set maproj 20 !projectile mass number +set latarg 10 !target atomic number +set matarg 20 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns new file mode 100644 index 000000000..254a1e4a4 --- /dev/null +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! Oxygen-Oxygen collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 8 !projectile atomic number +set maproj 16 !projectile mass number +set latarg 8 !target atomic number +set matarg 16 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini new file mode 100644 index 000000000..9da491aae --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini new file mode 100644 index 000000000..c05718ff0 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C new file mode 100644 index 000000000..c3f845e3e --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is exactly 1 event, as set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + + // ---- Neon-Neon parameters ---- + constexpr int kNeonPDG = 1000100200; // Ne-20 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 20; // Neon mass number + constexpr double kNeonEnergy = kA * kEnucleon; // 107200 GeV + + // Check if each event has two neon ions at the expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance to account for floating point precision + if (std::abs(energy - kNeonEnergy) < 5e-2 && + track.GetPdgCode() == kNeonPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 neon ions at " + << kNeonEnergy << " GeV\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C new file mode 100644 index 000000000..b5af3b3ad --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is 1 event, as customly set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + + // ---- Oxygen-Oxygen parameters ---- + constexpr int kOxygenPDG = 1000080160; // O-16 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 16; // Oxygen mass number + constexpr double kOxygenEnergy = kA * kEnucleon; // 85760 GeV + + // Check if each event has two oxygen ions at expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance (floating point safety) + if (std::abs(energy - kOxygenEnergy) < 5e-2 && + track.GetPdgCode() == kOxygenPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 oxygen ions at " + << kOxygenEnergy << " GeV\n"; + return 1; + } + } + + return 0; +}