Skip to content

Commit ba72480

Browse files
committed
Implemented basic pythia8 generator with deep trigger forwarding
1 parent a77ed47 commit ba72480

File tree

5 files changed

+208
-0
lines changed

5 files changed

+208
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#if !defined(__CLING__) || defined(__ROOTCLING__)
2+
#include "Pythia8/Pythia.h"
3+
#include "FairGenerator.h"
4+
#include "FairPrimaryGenerator.h"
5+
#include "Generators/Trigger.h"
6+
#include <Generators/TriggerExternalParam.h>
7+
#include "Generators/GeneratorPythia8.h"
8+
#include <stdlib.h>
9+
#include "CommonUtils/ConfigurationMacroHelper.h"
10+
11+
using namespace Pythia8;
12+
#endif
13+
14+
// Basic implementation of deep-triggered Pythia8 as external generator
15+
16+
class GeneratorPythia8Deep : public o2::eventgen::GeneratorPythia8
17+
{
18+
// Settings are fed via the configuration file specified in the .ini file
19+
// Triggers need to be handled like this otherwise the simulation with hybrid will
20+
// not be able to recognise the provided triggers.
21+
22+
public :
23+
24+
GeneratorPythia8Deep() : o2::eventgen::GeneratorPythia8()
25+
{
26+
mInterface = reinterpret_cast<void *>(&mPythia);
27+
mInterfaceName = "pythia8";
28+
o2::eventgen::DeepTrigger deeptrigger = nullptr;
29+
30+
// external trigger via ini file
31+
auto &params = o2::eventgen::TriggerExternalParam::Instance();
32+
LOG(info) << "Setting up external trigger for Pythia8 with following parameters";
33+
LOG(info) << params;
34+
auto external_trigger_filename = params.fileName;
35+
auto external_trigger_func = params.funcName;
36+
deeptrigger = o2::conf::GetFromMacro<o2::eventgen::DeepTrigger>(external_trigger_filename, external_trigger_func, "o2::eventgen::DeepTrigger", "deeptrigger");
37+
if (!deeptrigger)
38+
{
39+
LOG(fatal) << "Failed to retrieve \'external trigger\': problem with configuration ";
40+
} else {
41+
LOG(info) << "External trigger for Pythia8 is set";
42+
addDeepTrigger(deeptrigger);
43+
setTriggerMode(o2::eventgen::Generator::kTriggerOR);
44+
}
45+
}
46+
};
47+
48+
FairGenerator *generator_pythia8_deep()
49+
{
50+
return new GeneratorPythia8Deep();
51+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
### The setup uses an external event generator trigger which is
2+
### defined in the following file and it is retrieved and configured
3+
### according to the specified function call
4+
5+
[GeneratorExternal]
6+
fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/external/generator/pythia8_deep.C
7+
funcName=generator_pythia8_deep()
8+
9+
[TriggerExternal]
10+
fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/trigger/trigger_impactb.macro
11+
funcName=trigger_impactb_pythia8(0.,15.)
12+
13+
### This part configures Pythia8
14+
15+
[GeneratorPythia8]
16+
config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/pythia8/generator/pythia8_hi.cfg
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
std::string path{"o2sim_Kine.root"};
3+
// Check that file exists, can be opened and has the correct tree
4+
TFile file(path.c_str(), "READ");
5+
if (file.IsZombie())
6+
{
7+
std::cerr << "Cannot open ROOT file " << path << "\n";
8+
return 1;
9+
}
10+
auto tree = (TTree *)file.Get("o2sim");
11+
if (!tree)
12+
{
13+
std::cerr << "Cannot find tree o2sim in file " << path << "\n";
14+
return 1;
15+
}
16+
std::vector<o2::MCTrack> *tracks{};
17+
tree->SetBranchAddress("MCTrack", &tracks);
18+
19+
o2::dataformats::MCEventHeader *mcheader = nullptr;
20+
tree->SetBranchAddress("MCEventHeader.", &mcheader);
21+
22+
// Check if all events are filled
23+
auto nEvents = tree->GetEntries();
24+
for (Long64_t i = 0; i < nEvents; ++i)
25+
{
26+
tree->GetEntry(i);
27+
if (tracks->empty())
28+
{
29+
std::cerr << "Empty entry found at event " << i << "\n";
30+
return 1;
31+
}
32+
}
33+
// Check if there are 100 events, as simulated in the o2dpg-test
34+
if (nEvents != 100)
35+
{
36+
std::cerr << "Expected 100 events, got " << nEvents << "\n";
37+
return 1;
38+
}
39+
// check if each event has two lead ions with the correct energy (based on Pythia simulation)
40+
// exits if the particle is not lead 208
41+
bool isvalid;
42+
for (int i = 0; i < nEvents; i++)
43+
{
44+
auto check = tree->GetEntry(i);
45+
int count = 0;
46+
for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack)
47+
{
48+
auto track = tracks->at(idxMCTrack);
49+
double energy = track.GetEnergy();
50+
// Check if track energy is right for the lead ions (a tolerance of 100 MeV is considered, straight equality does not work due to floating point precision)
51+
if (std::abs(energy - 547158) < 1e-1) // Lead ion energy is 547158 MeV
52+
{
53+
if (track.GetPdgCode() != 1000822080)
54+
{
55+
std::cerr << "Found 547158 GeV particle with pdgID " << track.GetPdgCode() << "\n";
56+
return 1;
57+
}
58+
count++;
59+
}
60+
}
61+
if (count < 2)
62+
{
63+
std::cerr << "Event " << i << " has less than 2 lead ions at 547158 GeV\n";
64+
return 1;
65+
}
66+
// Check if event impact parameter is < 15 fm
67+
double impactParameter = mcheader->getInfo<double>(o2::dataformats::MCInfoKeys::impactParameter, isvalid);
68+
if (impactParameter > 15)
69+
{
70+
std::cerr << "Event " << i << " has impact parameter " << impactParameter << " fm outside range\n";
71+
return 1;
72+
}
73+
}
74+
return 0;
75+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
### random
2+
Random:setSeed = on
3+
Random:seed = 0
4+
5+
### beams
6+
Beams:idA = 1000822080
7+
Beams:idB = 1000822080
8+
Beams:eCM = 5300.000000
9+
10+
### heavy-ion settings (valid for Pb-Pb 5520 only)
11+
HeavyIon:SigFitNGen = 0
12+
HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0
13+
HeavyIon:bWidth = 14.48
14+
15+
### decays
16+
ParticleDecays:limitTau0 = on
17+
ParticleDecays:tau0Max = 10.
18+
19+
### phase space cuts
20+
PhaseSpace:pTHatMin = 0.000000
21+
PhaseSpace:pTHatMax = -1.000000
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "Generators/Trigger.h"
2+
#include "TParticle.h"
3+
#include <iostream>
4+
5+
// a very simple trigger example, examining generated particles
6+
o2::eventgen::Trigger trigger()
7+
{
8+
//
9+
return [](const std::vector<TParticle>& particles) -> bool {
10+
std::cout << "Running trigger on event with size " << particles.size() << "\n";
11+
if (particles.size() > 10000) {
12+
return true;
13+
}
14+
return false;
15+
};
16+
}
17+
18+
#include "Pythia8/Pythia.h"
19+
#include "Pythia8/HIInfo.h"
20+
#include <fairlogger/Logger.h>
21+
// a deep trigger example, looking into the internal generator state
22+
o2::eventgen::DeepTrigger
23+
trigger_impactb_pythia8(double bmin = 5., double bmax = 10.)
24+
{
25+
return [bmin, bmax](void* interface, std::string name) -> bool {
26+
if (!name.compare("pythia8")) {
27+
auto py8 = reinterpret_cast<Pythia8::Pythia*>(interface);
28+
#if PYTHIA_VERSION_INTEGER < 8300
29+
auto hiinfo = py8->info.hiinfo;
30+
#else
31+
auto hiinfo = py8->info.hiInfo;
32+
#endif
33+
if (!hiinfo) {
34+
LOG(fatal) << "Cannot define impact parameter: is \'pythia8\' running in heavy-ion mode?";
35+
}
36+
auto b = hiinfo->b();
37+
auto selected = (b > bmin && b < bmax);
38+
LOG(info) << "Impact parameter = " << b << " fm: " << (selected ? "selected" : "rejected");
39+
return selected;
40+
} else {
41+
LOG(fatal) << "Cannot define impact parameter for generator interface \'" << name << "\'";
42+
}
43+
return false;
44+
};
45+
}

0 commit comments

Comments
 (0)