Skip to content

Commit 8585daa

Browse files
authored
Created EPOS4 external example generator (#1789)
* Created EPOS4 external example generator * Updated center-of-mass energy of EPOS4 example * Implemented GeneratorEPOS4 test * Testing fix for EPOS4 external * Revert "Implemented GeneratorEPOS4 test" This reverts commit e0b88b1. * Reapply "Implemented GeneratorEPOS4 test" This reverts commit 53671e8. * Revert "Testing fix for EPOS4 external" This reverts commit 920cf42. * Check for LIBDIR * Added EPO4 as env variable in external script * Explicit definition of EPOS4 version * Reorganised and improved fix for CI
1 parent 6d28427 commit 8585daa

File tree

5 files changed

+208
-0
lines changed

5 files changed

+208
-0
lines changed

MC/config/examples/epos4/epos.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/sh
2+
# Script based on CRMC example
3+
# EPOS4 option files must contain ihepmc set to 2 to print HepMC
4+
# data on stdout. -hepmc flag is not needed anymore, but -hepstd is fundamental
5+
# in order not to print useless information on stdout (a z-*optns*.mtr file will be created)
6+
7+
optns="example"
8+
seed=$RANDOM
9+
10+
while test $# -gt 0 ; do
11+
case $1 in
12+
-i|--input) optns=$2 ; shift ;;
13+
-s|--seed) seed=$2 ; shift ;;
14+
-h|--help) usage; exit 0 ;;
15+
esac
16+
shift
17+
done
18+
19+
if [ ! -f $optns.optns ]; then
20+
echo "Error: Options file $optns.optns not found"
21+
exit 1
22+
fi
23+
24+
if [ $seed -eq 0 ]; then
25+
echo "Seed can't be 0, random number will be used"
26+
seed=$RANDOM
27+
fi
28+
29+
# Check if the environment variable EPO4 is set (mandatory with o2dpg-sim-tests on CI machines)
30+
# If not, set all the EPOS4 related variables, most likely they are unset as well.
31+
if [ -z "${EPO4}" ]; then
32+
export EPO4=$EPOS4_ROOT/epos4/
33+
export LIBDIR=$EPOS4_ROOT/epos4/bin
34+
export EPO4VSN=4.0.0
35+
export OPT=./
36+
export HTO=./
37+
export CHK=./
38+
fi
39+
40+
# Or filters the stdout with only HepMC2 useful data
41+
$EPOS4_ROOT/epos4/scripts/epos -hepstd -s $seed $optns | sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p'
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
!--------------------------------------------------------------------
2+
! proton-proton collision no hydro no hadronic cascade
3+
!--------------------------------------------------------------------
4+
5+
!---------------------------------------
6+
! Define run
7+
!---------------------------------------
8+
9+
application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus
10+
set laproj 1 !projectile atomic number
11+
set maproj 1 !projectile mass number
12+
set latarg 1 !target atomic number
13+
set matarg 1 !target mass number
14+
set ecms 13600 !sqrt(s)_pp
15+
set istmax 25 !max status considered for storage
16+
17+
ftime on !string formation time non-zero
18+
!suppressed decays:
19+
nodecays
20+
110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331
21+
end
22+
23+
set ninicon 1 !number of initial conditions used for hydro evolution
24+
core off !core/corona not activated
25+
hydro off !hydro not activated
26+
eos off !eos not activated
27+
hacas off !hadronic cascade not activated
28+
set nfreeze 1 !number of freeze out events per hydro event
29+
set modsho 1 !printout every modsho events
30+
set centrality 0 !0=min bias
31+
set ihepmc 2 !HepMC output enabled on stdout
32+
set nfull 10
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <filesystem>
4+
#include <fairlogger/Logger.h>
5+
6+
class GeneratorEPOS4 : public o2::eventgen::GeneratorHepMC
7+
{
8+
public:
9+
GeneratorEPOS4() = default;
10+
~GeneratorEPOS4() = default;
11+
12+
};
13+
14+
// Next function takes the optns file as argument and edits the maximum number of events to be generated.
15+
// When used as an external generator it is important that the events passed with the -n flag are the same
16+
// or lower of the events set in the optns file, otherwise the generation will crash. That is why the .ini
17+
// example file contains the maximum integer available, assuming less events than that are generated in a real
18+
// life scenario. Unfortunately a larger number cannot be used at the moment since EPOS4 has a signed integer
19+
// type for the nfull parameter. Might be changed in the future.
20+
// When running locally, or on the GRID (not in hyperloop), the default parameters provided in the .ini file of the
21+
// external generation can be overwritten using the confKeyValues option (or similar depending on the tool used).
22+
FairGenerator* generateEPOS4(const std::string &name, const int& nEvents)
23+
{
24+
// check if the file exists
25+
auto filename = gSystem->ExpandPathName(name.c_str());
26+
if (!std::filesystem::exists(filename))
27+
{
28+
LOG(fatal) << "Options file " << filename << " does not exist!";
29+
exit(1);
30+
}
31+
// cache all the lines of the optns file and replace the number of events
32+
std::ifstream file(filename);
33+
std::string line;
34+
bool found = false;
35+
std::stringstream buffer;
36+
while (std::getline(file, line))
37+
{
38+
if (line.find("nfull") != std::string::npos){
39+
// replace the number of events
40+
found = true;
41+
line = "set nfull " + std::to_string(nEvents);
42+
}
43+
buffer << line << "\n";
44+
}
45+
file.close();
46+
// Write the updated content back to a file in the current directory
47+
std::ofstream outFile("cfg.optns");
48+
outFile << buffer.str();
49+
if (!found)
50+
{
51+
outFile << "set nfull " + std::to_string(nEvents);
52+
}
53+
outFile.close();
54+
auto gen = new GeneratorEPOS4();
55+
auto& param0 = o2::eventgen::GeneratorFileOrCmdParam::Instance();
56+
auto& param = o2::eventgen::GeneratorHepMCParam::Instance();
57+
auto& conf = o2::conf::SimConfig::Instance();
58+
// setup the HepMC generator to run with automatic FIFOs
59+
gen->setup(param0, param, conf);
60+
return gen;
61+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[GeneratorExternal]
2+
fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C
3+
funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/example.optns", 2147483647)
4+
5+
[GeneratorFileOrCmd]
6+
cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh -i cfg
7+
bMaxSwitch=none
8+
9+
[HepMC]
10+
version=2
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
int External()
2+
{
3+
std::string path{"o2sim_Kine.root"};
4+
// Check that file exists, can be opened and has the correct tree
5+
TFile file(path.c_str(), "READ");
6+
if (file.IsZombie())
7+
{
8+
std::cerr << "Cannot open ROOT file " << path << "\n";
9+
return 1;
10+
}
11+
auto tree = (TTree *)file.Get("o2sim");
12+
if (!tree)
13+
{
14+
std::cerr << "Cannot find tree o2sim in file " << path << "\n";
15+
return 1;
16+
}
17+
std::vector<o2::MCTrack> *tracks{};
18+
tree->SetBranchAddress("MCTrack", &tracks);
19+
20+
// Check if all events are filled
21+
auto nEvents = tree->GetEntries();
22+
for (Long64_t i = 0; i < nEvents; ++i)
23+
{
24+
tree->GetEntry(i);
25+
if (tracks->empty())
26+
{
27+
std::cerr << "Empty entry found at event " << i << "\n";
28+
return 1;
29+
}
30+
}
31+
// Check if there are 100 events, as simulated in the o2dpg-test
32+
if (nEvents != 100)
33+
{
34+
std::cerr << "Expected 100 events, got " << nEvents << "\n";
35+
return 1;
36+
}
37+
// check if each event has two protons with 6800 GeV of energy
38+
// exits if the particle is not a proton
39+
for (int i = 0; i < nEvents; i++)
40+
{
41+
auto check = tree->GetEntry(i);
42+
int count = 0;
43+
for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack)
44+
{
45+
auto track = tracks->at(idxMCTrack);
46+
double energy = track.GetEnergy();
47+
// Check if track energy is approximately equal to 6800 GeV (a tolerance of 65 keV is considered, straight equality does not work due to floating point precision)
48+
if (std::abs(energy - 6800) < 1e-4)
49+
{
50+
if (track.GetPdgCode() != 2212){
51+
std::cerr << "Found 6800 GeV particle with pdgID " << track.GetPdgCode() << "\n";
52+
return 1;
53+
}
54+
count++;
55+
}
56+
}
57+
if (count < 2)
58+
{
59+
std::cerr << "Event " << i << " has less than 2 protons at 6800 GeV\n";
60+
return 1;
61+
}
62+
}
63+
return 0;
64+
}

0 commit comments

Comments
 (0)