Skip to content

Commit d24bae5

Browse files
committed
A full PWGHF simulation example for embedding
1 parent 36bfd05 commit d24bae5

File tree

19 files changed

+459
-0
lines changed

19 files changed

+459
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/// \author R+Preghenella - July 2020
2+
3+
// Example of an implementation of an event generator
4+
// that provides HF signals for embedding in background
5+
6+
#include "Pythia8/Pythia.h"
7+
8+
namespace o2 {
9+
namespace eventgen {
10+
11+
class GeneratorHF : public GeneratorPythia8
12+
{
13+
14+
public:
15+
16+
GeneratorHF() : GeneratorPythia8() { };
17+
~GeneratorHF() = default;
18+
19+
// We initialise the local Pythia8 event where we store the particles
20+
// of the signal event that is the sum of multiple Pythia8 events
21+
// generated according to the generateEvent() function below.
22+
Bool_t Init() override {
23+
mOutputEvent.init("(GeneratorHF output event)", &mPythia.particleData);
24+
return GeneratorPythia8::Init();
25+
}
26+
27+
// This function is called by the primary generator
28+
// for each event in case we are in embedding mode.
29+
// We use it to setup the number of signal events
30+
// to be generated and to be embedded on the background.
31+
void notifyEmbedding(const FairMCEventHeader *bkgHeader) override {
32+
mEvents = mFormula.Eval(bkgHeader->GetB());
33+
std::cout << " --- notify embedding: impact parameter is " << bkgHeader->GetB() << ", generating " << mEvents << " signal events " << std::endl;
34+
};
35+
36+
// We override this function to be able to generate multiple
37+
// events and build an output event that is the sum of them
38+
// where we have stripped out only the sub-event starting from
39+
// the c-cbar ancestor particle
40+
Bool_t generateEvent() override {
41+
42+
// reset counter and event
43+
mOutputEvent.reset();
44+
45+
// loop over number of events to be generated
46+
int nEvents = 0;
47+
while (nEvents < mEvents) {
48+
49+
// generate event
50+
if (!GeneratorPythia8::generateEvent()) return false;
51+
52+
// find the c-cbar ancestor
53+
auto ancestor = findAncestor(mPythia.event);
54+
if (ancestor < 0) continue;
55+
56+
// append ancestor and its daughters to the output event
57+
selectFromAncestor(ancestor, mPythia.event, mOutputEvent);
58+
nEvents++;
59+
}
60+
61+
if (mVerbose) mOutputEvent.list();
62+
63+
return true;
64+
};
65+
66+
// We override this event to import the particles from the
67+
// output event that we have constructed as the sum of multiple
68+
// Pythia8 sub-events as generated above
69+
Bool_t importParticles() override {
70+
return GeneratorPythia8::importParticles(mOutputEvent);
71+
}
72+
73+
// search for c-cbar mother with at least one c at midrapidity
74+
int findAncestor(Pythia8::Event& event) {
75+
for (int ipa = 0; ipa < event.size(); ++ipa) {
76+
auto daughterList = event[ipa].daughterList();
77+
bool hasc = false, hascbar = false, atmidy = false;
78+
for (auto ida : daughterList) {
79+
if (event[ida].id() == 4) hasc = true;
80+
if (event[ida].id() == -4) hascbar = true;
81+
if (fabs(event[ida].y()) < mRapidity) atmidy = true;
82+
}
83+
if (hasc && hascbar && atmidy)
84+
return ipa;
85+
}
86+
return -1;
87+
};
88+
89+
void setRapidity(double val) { mRapidity = val; };
90+
void setVerbose(bool val) { mVerbose = val; };
91+
void setFormula(std::string val) { mFormula.Compile(val.c_str()); };
92+
93+
private:
94+
95+
TFormula mFormula;
96+
int mEvents = 1;
97+
Pythia8::Event mOutputEvent;
98+
double mRapidity = 1.5;
99+
bool mVerbose = false;
100+
101+
};
102+
103+
}}
104+
105+
/** generator instance and settings **/
106+
107+
FairGenerator*
108+
GeneratorHF(double rapidity = 1.5, bool verbose = false)
109+
{
110+
auto gen = new o2::eventgen::GeneratorHF();
111+
gen->setRapidity(rapidity);
112+
gen->setVerbose(verbose);
113+
gen->setFormula("max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.))");
114+
115+
return gen;
116+
}
117+
118+

MC/config/PWGHF/external/trigger/.gitkeep

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
### The external generator derives from GeneratorPythia8.
2+
### This part configures the bits of the interface: configuration and user hooks
3+
4+
[Pythia8]
5+
config = ${O2DPG_ROOT}/MC/config/common/pythia8/generator/pythia8.cfg
6+
hooksFileName = ${O2DPG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_ccbar.C
7+
hooksFuncName = pythia8_userhooks_ccbar(1.5)
8+
9+
### The setup uses the base configuration of the decayer which is loaded from the file specified by config[0].
10+
### On top of the base configuration, two more sets of settings are loaded sequentially from config[1] and [2].
11+
12+
[DecayerPythia8]
13+
config[0] = ${O2DPG_ROOT}/MC/config/common/pythia8/decayer/base.cfg
14+
config[1] = ${O2DPG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D.cfg
15+
config[2] = ${O2DPG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D_use4bodies.cfg
16+
17+
### The setup forces some particles to be decayed by the external decayer instead of Geant.
18+
### The PDG list of the particles is specified below.
19+
20+
[SimUserDecay]
21+
pdglist = 411 421 431 4112 4122 4232 4132
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
### author: Roberto Preghenella (preghenella@bo.infn.it)
2+
### since: July 2020
3+
4+
### Force golden D decay modes
5+
### the origin is from AliRoot AliDecayerPythia8::ForceHadronicD (Latest commit c509466 on May 17)
6+
###
7+
### This file reproduces the configuration achieved with ForceHadronicD(0,0,0)
8+
9+
### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other
10+
411:oneChannel = 1 0.0752 0 -321 211 211
11+
411:addChannel = 1 0.0104 0 -313 211
12+
411:addChannel = 1 0.0156 0 311 211
13+
411:addChannel = 1 0.00276 0 333 211
14+
## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other
15+
4122:oneChannel = 1 0.0196 100 2212 -313
16+
4122:addChannel = 1 0.0108 100 2224 -321
17+
4122:addChannel = 1 0.022 100 3124 211
18+
4122:addChannel = 1 0.035 0 2212 -321 211
19+
4122:addChannel = 1 0.0159 0 2212 311
20+
4122:addChannel = 1 0.0130 0 3122 211
21+
### add Xic+ decays absent in PYTHIA8 decay table
22+
4232:addChannel = 1 0.2 0 2212 -313
23+
4232:addChannel = 1 0.2 0 2212 -321 211
24+
4232:addChannel = 1 0.2 0 3324 211
25+
4232:addChannel = 1 0.2 0 3312 211 211
26+
### add Xic0 decays absent in PYTHIA8 decay table
27+
4132:addChannel = 1 0.2 0 3312 211
28+
29+
### K* -> K pi
30+
313:onMode = off
31+
313:onIfAll = 321 211
32+
### for Ds -> Phi pi+
33+
333:onMode = off
34+
333:onIfAll = 321 321
35+
### for D0 -> rho0 pi+ k-
36+
113:onMode = off
37+
113:onIfAll = 211 211
38+
### for Lambda_c -> Delta++ K-
39+
2224:onMode = off
40+
2224:onIfAll = 2212 211
41+
### for Lambda_c -> Lambda(1520) K-
42+
3124:onMode = off
43+
3124:onIfAll = 2212 321
44+
45+
### Omega_c -> Omega pi
46+
4332:onMode = off
47+
4332:onIfMatch = 3334 211
48+
49+
### switch off all decay channels
50+
411:onMode = off
51+
421:onMode = off
52+
431:onMode = off
53+
4112:onMode = off
54+
4122:onMode = off
55+
4232:onMode = off
56+
4132:onMode = off
57+
58+
### D+/- -> K pi pi
59+
411:onIfMatch = 321 211 211
60+
### D+/- -> K* pi
61+
411:onIfMatch = 313 211
62+
### D+/- -> phi pi
63+
411:onIfMatch = 333 211
64+
65+
### D0 -> K pi
66+
421:onIfMatch = 321 211
67+
68+
### D_s -> K K*
69+
431:onIfMatch = 321 313
70+
### D_s -> Phi pi
71+
431:onIfMatch = 333 211
72+
73+
### Lambda_c -> p K*
74+
4122:onIfMatch = 2212 313
75+
### Lambda_c -> Delta K
76+
4122:onIfMatch = 2224 321
77+
### Lambda_c -> Lambda(1520) pi
78+
4122:onIfMatch = 3124 211
79+
### Lambda_c -> p K pi
80+
4122:onIfMatch = 2212 321 211
81+
### Lambda_c -> Lambda pi
82+
4122:onIfMatch = 3122 211
83+
### Lambda_c -> p K0
84+
4122:onIfMatch = 2212 311
85+
86+
### Xic+ -> pK*0
87+
4232:onIfMatch = 2212 313
88+
### Xic+ -> p K- pi+
89+
4232:onIfMatch = 2212 321 211
90+
### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+
91+
4232:onIfMatch = 3324 211
92+
### Xic+ -> Xi- pi+ pi+
93+
4232:onIfMatch = 3312 211 211
94+
95+
### Xic0 -> Xi- pi+
96+
4132:onIfMatch = 3312 211
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
### author: Roberto Preghenella (preghenella@bo.infn.it)
2+
### since: July 2020
3+
4+
### Force golden D decay modes (force Lc channel 1)
5+
### the origin is from AliRoot AliDecayerPythia8::ForceHadronicD (Latest commit c509466 on May 17)
6+
###
7+
### This file has to be used in conjunction with force_hadronic_D.cfg and loaded
8+
### afterwards to reproduce the configuration achieved with ForceHadronicD(0,0,1)
9+
10+
### force Lc -> p K pi
11+
4122:onMode = off
12+
4122:onIfMatch = 2212 321 211
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
### author: Roberto Preghenella (preghenella@bo.infn.it)
2+
### since: July 2020
3+
4+
### Force golden D decay modes (force Lc channel 2)
5+
### the origin is from AliRoot AliDecayerPythia8::ForceHadronicD (Latest commit c509466 on May 17)
6+
###
7+
### This file has to be used in conjunction with force_hadronic_D.cfg and loaded
8+
### afterwards to reproduce the configuration achieved with ForceHadronicD(0,0,2)
9+
10+
### force Lc -> p K0s
11+
4122:onMode = off
12+
4122:onIfMatch = 2212 311
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
### author: Roberto Preghenella (preghenella@bo.infn.it)
2+
### since: July 2020
3+
4+
### Force golden D decay modes (use 4 bodies option)
5+
### the origin is from AliRoot AliDecayerPythia8::ForceHadronicD (Latest commit c509466 on May 17)
6+
###
7+
### This file has to be used in conjunction with force_hadronic_D.cfg and loaded
8+
### afterwards to reproduce the configuration achieved with ForceHadronicD(1,0,0)
9+
10+
### D0 -> K pi pi pi
11+
421:onIfMatch = 321 211 211 211
12+
### D0 -> K pi rho
13+
421:onIfMatch = 321 211 113
14+
### D0 -> K*0 pi pi
15+
421:onIfMatch = 313 211 211
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### author: Roberto Preghenella (preghenella@bo.infn.it)
2+
### since: July 2020
3+
4+
### Force golden D decay modes (use D to V0 option)
5+
### the origin is from AliRoot AliDecayerPythia8::ForceHadronicD (Latest commit c509466 on May 17)
6+
###
7+
### This file has to be used in conjunction with force_hadronic_D.cfg and loaded
8+
### afterwards to reproduce the configuration achieved with ForceHadronicD(0,1,0)
9+
10+
### Ds -> K0K
11+
431:onIfMatch = 311 321
12+
### Ds -> K0pi
13+
411:onIfMatch = 311 211

MC/config/PWGHF/pythia8/generator/.gitkeep

Whitespace-only changes.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/// \author R+Preghenella - July 2020
2+
3+
/// This Pythia8 UserHooks can veto the processing at parton level.
4+
/// The partonic event is scanned searching for a c-cbar mother
5+
/// with at least one of the c quarks produced withing a fiducial
6+
/// window around midrapidity that can be specified by the user.
7+
8+
#include "Pythia8/Pythia.h"
9+
10+
class UserHooks_ccbar : public Pythia8::UserHooks
11+
{
12+
13+
public:
14+
UserHooks_ccbar() = default;
15+
~UserHooks_ccbar() = default;
16+
bool canVetoPartonLevel() override { return true; };
17+
bool doVetoPartonLevel(const Pythia8::Event& event) override {
18+
// search for c-cbar mother with at least one c at midrapidity
19+
for (int ipa = 0; ipa < event.size(); ++ipa) {
20+
auto daughterList = event[ipa].daughterList();
21+
bool hasc = false, hascbar = false, atmidy = false;
22+
for (auto ida : daughterList) {
23+
if (event[ida].id() == 4) hasc = true;
24+
if (event[ida].id() == -4) hascbar = true;
25+
if (fabs(event[ida].y()) < mRapidity) atmidy = true;
26+
}
27+
if (hasc && hascbar && atmidy)
28+
return false; // found it, do not veto event
29+
}
30+
return true; // did not find it, veto event
31+
};
32+
33+
void setRapidity(double val) { mRapidity = val; };
34+
35+
private:
36+
37+
double mRapidity = 1.5;
38+
39+
};
40+
41+
Pythia8::UserHooks*
42+
pythia8_userhooks_ccbar(double rapidity = 1.5)
43+
{
44+
auto hooks = new UserHooks_ccbar();
45+
hooks->setRapidity(rapidity);
46+
return hooks;
47+
}

0 commit comments

Comments
 (0)