ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Simulation
FastSimulation
FastChainPileup
src
MultiParticleGunPileup.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
// MultiPY8Pileup.cxx - extension of GenModule_i to generate multiple pileup
6
// events in one go for fast simulation chain
7
// Richard Hawkings, started 20/2/15, + contributions from Vladimir Lyubushkin
8
9
#include <algorithm>
10
#include <numeric>
11
#include <functional>
12
#include <iterator>
13
14
15
#include "CLHEP/Random/RandPoisson.h"
16
#include "
FastChainPileup/MultiParticleGunPileup.h
"
17
18
MultiParticleGunPileup::MultiParticleGunPileup
(
const
std::string& name, ISvcLocator* pSvcLocator) :
19
GenModule
( name, pSvcLocator ),
20
m_ngen
(0),
21
m_nbad
(0),
22
// m_evnumber(1),
23
m_file
(NULL),
24
m_htgPileupProfile
(NULL),
25
m_htgPileupMu
(NULL),
26
m_htgPileupEvents
(NULL),
27
m_partSampler
(NULL)
28
{
29
declareProperty
(
"NCollPerEvent"
,
m_ncollevent
=20,
"Collisons per event (-1 to use profile)"
);
30
declareProperty
(
"PileupProfile"
,
m_pileupProfile
,
"Pileup profile array"
);
31
declareProperty
(
"MultBCID"
,
m_multbcid
,
"Pileup multiplier per BCID array"
);
32
declareProperty
(
"HistFile"
,
m_filename
=
""
,
"Filename for histograms"
);
33
}
34
35
MultiParticleGunPileup::~MultiParticleGunPileup
() {
36
37
}
38
39
StatusCode
MultiParticleGunPileup::genInitialize
() {
40
ATH_MSG_INFO
(
"In MultiParticleGunPileup::genInitialize"
);
41
42
// should be initialized after Pythia8_i::genInitialize() ???
43
// m_randomEngine = atRndmGenSvc().GetEngine( Pythia8_i::pythia_stream );
44
45
// if filename set, initialise histograms for mu/nevt profiles
46
if
(
m_filename
!=
""
) {
47
m_file
=
new
TFile(
m_filename
.c_str(),
"recreate"
);
48
m_file
->cd();
49
m_htgPileupProfile
=
new
TH1D(
"pileupProfile"
,
"input pileupProfile"
, 100, 0., 100. );
50
m_htgPileupMu
=
new
TH1D(
"generatedMu"
,
"generated pileup mu"
, 100, 0., 100. );
51
m_htgPileupEvents
=
new
TH1D(
"generatedEvents"
,
"generated pileup events"
, 100, 0., 100. );
52
}
53
54
m_pileupProfileIntegral
.clear();
55
m_pileupProfileIntegral
.reserve(
m_pileupProfile
.size() );
56
for
( std::vector< int >::iterator itr =
m_pileupProfile
.begin(); itr !=
m_pileupProfile
.end(); ++itr ) {
57
m_pileupProfileIntegral
.push_back( std::accumulate(
m_pileupProfile
.begin(), itr + 1, 0. ) );
58
if
(
m_file
)
59
m_htgPileupProfile
->SetBinContent( std::distance(
m_pileupProfile
.begin(), itr ) + 1, *itr );
60
}
61
62
if
(
m_ncollevent
> 0 ) {
63
ATH_MSG_INFO
(
"Generate fixed number of "
<<
m_ncollevent
<<
" minbias collisions per bunch crossing"
);
64
}
65
else
{
66
ATH_MSG_INFO
(
"Generate varying minbias collisions per event according to given pileup profile"
);
67
}
68
m_evts
.reserve( 50 );
69
70
ATH_MSG_INFO
(
"Simulate "
<<
m_multbcid
.size() <<
" bunch crossings per event"
);
71
int
ibc=1;
72
for
(std::vector<float>::const_iterator itr=
m_multbcid
.begin();
73
itr!=
m_multbcid
.end();++itr,++ibc) {
74
ATH_MSG_INFO
(
"Bunch crossing BCID "
<< ibc <<
" mu multiplier "
<< *itr);
75
}
76
77
//Initialize the ParticleGun generator
78
m_partSampler
=
new
ParticleSampler
(
new
CyclicSeqSampler
(
"-11,11,"
),
new
PtEtaMPhiSampler
(10000.,10000.,-3,3),1);
79
80
// exit via the base class initialisation
81
return
StatusCode::SUCCESS;
82
}
83
84
StatusCode
MultiParticleGunPileup::callGenerator
() {
85
// initialise random generators the first time - delayed after Pythia init
86
const
EventContext& ctx = Gaudi::Hive::currentContext();
87
CLHEP::HepRandomEngine* rndmEngine = this->
getRandomEngine
(
"ParticleGun"
, ctx);
88
89
// decide how many events to generate
90
91
int
muval = (
m_ncollevent
> 0 ?
m_ncollevent
:
nPileupEvents
(rndmEngine) );
92
if
(
m_file
)
m_htgPileupMu
->Fill(muval+0.1);
93
m_evts
.clear();
94
95
// loop over all BCID - starting from 1 for in-time pileup
96
int
bcid=1;
97
for
(std::vector<float>::const_iterator bcitr=
m_multbcid
.begin();
98
bcitr!=
m_multbcid
.end();++bcitr,++bcid) {
99
// actual number of minbias in this BCID
100
// Poisson around instantaneous_mu * multiplier value
101
const
int
nevtraw=CLHEP::RandPoisson::shoot(muval);
102
if
(
m_file
)
m_htgPileupEvents
->Fill(nevtraw+0.1);
103
const
int
nevt=(float)nevtraw*(*bcitr);
104
105
for
(
int
ievt=0;ievt<nevt;++ievt) {
106
ATH_MSG_DEBUG
(
"Request generation of event "
<< ievt <<
" of "
<< nevt
107
<<
" for BCID "
<< bcid);
108
109
//--------------------------- CALL GUN HERE
110
HepMC::GenEvent
* evt=
new
HepMC::GenEvent
();
111
evt->weights().push_back(1.0);
112
//evt->set_event_number(ievt); //Maybe dangerous to do this since the first event gets stacked last
113
// Make and fill particles
114
std::vector<SampledParticle> particles =
m_partSampler
->shoot();
115
for
(
const
auto
& p : particles){
116
// Debug printout of particle properties
117
std::cout << ievt <<
" DEBUG0,"
<< p.m_pid <<
", "
<< p.m_mom.E()<<
", "
<< p.m_mom.Pt()<<
", "
<< p.m_mom.M() << std::endl;
118
std::cout << ievt <<
" DEBUG1 (px,py,pz,E) = ("
<< p.m_mom.Px()<<
", "
<< p.m_mom.Py()<<
", "
<< p.m_mom.Pz()<<
", "
<< p.m_mom.E() <<
")"
<< std::endl;
119
std::cout << ievt <<
" DEBUG2 (eta,phi,pt,m) = ()"
<< p.m_mom.Eta()<<
", "
<< p.m_mom.Phi()<<
", "
<< p.m_mom.Pt()<<
", "
<< p.m_mom.M() <<
")"
<< std::endl;
120
std::cout << ievt <<
" DEBUG3 (x,y,z,t) = ()"
<< p.m_pos.X()<<
", "
<< p.m_pos.Y()<<
", "
<< p.m_pos.Z()<<
", "
<< p.m_pos.T() <<
")"
<< std::endl;
121
// Make particle-creation vertex
122
// TODO: do something cleverer than one vertex per particle?
123
HepMC::FourVector
pos(p.m_pos.X(), p.m_pos.Y(), p.m_pos.Z(), p.m_pos.T());
124
HepMC::GenVertexPtr
gv =
HepMC::newGenVertexPtr
(pos);
125
evt->add_vertex(gv);
126
// Make particle with status == 1
127
HepMC::FourVector
mom(p.m_mom.Px(), p.m_mom.Py(), p.m_mom.Pz(), p.m_mom.E());
128
HepMC::GenParticlePtr
gp =
HepMC::newGenParticlePtr
();
129
gp->set_status(1);
130
gp->set_pdg_id(p.m_pid);
131
gp->set_momentum(mom);
132
if
(p.m_mass)
133
gp->set_generated_mass(p.m_mass);
134
gv->add_particle_out(std::move(gp));
135
}
136
//-----------------------------------------
137
138
// change the process ID to incorporate the BCID * 10000
139
int
pid=
HepMC::signal_process_id
(evt);
140
HepMC::set_signal_process_id
(evt,pid+10000*bcid);
141
ATH_MSG_DEBUG
(
"Signal process ID "
<< pid <<
" set to "
<<
142
HepMC::signal_process_id
(evt) <<
" for BCID "
<< bcid);
143
HepMC::fillBarcodesAttribute
(evt);
144
m_evts
.push_back(evt);
145
++
m_ngen
;
146
}
147
}
148
ATH_MSG_DEBUG
(
"callGenerator finished with "
<<
m_evts
.size() <<
149
" pileup events in buffer"
);
150
return
StatusCode::SUCCESS;
151
}
152
153
StatusCode
MultiParticleGunPileup::fillEvt
(
HepMC::GenEvent
* evt) {
154
int
nbuf=
m_evts
.size();
155
if
(nbuf>1) {
156
// send extra events into McEventCollection via backdoor
157
for
(
int
i=1;i<nbuf;++i) {
158
events()->push_back(
m_evts
[i]);
159
}
160
}
161
// send first event back via usual method
162
// have to copy it to the passed in GenEvent
163
if
(nbuf>0) {
164
*evt=*
m_evts
[0];
165
delete
m_evts
[0];
166
}
167
return
StatusCode::SUCCESS;
168
}
169
170
StatusCode
MultiParticleGunPileup::genFinalize
() {
171
ATH_MSG_INFO
(
"MultiParticleGunPileup finished with "
<<
m_ngen
<<
" good events and "
<<
m_nbad
<<
" failures"
);
172
173
if
(
m_file
) {
174
m_file
->cd();
175
m_file
->Write();
176
m_file
->Close();
177
}
178
179
return
StatusCode::SUCCESS;
180
}
181
182
183
int
MultiParticleGunPileup::nPileupEvents
(CLHEP::HepRandomEngine* rndmEngine) {
184
// return the instantaneous mu value according to the profile
185
double
threshold
= rndmEngine->flat() *
m_pileupProfileIntegral
.back();
186
std::vector< double >::iterator itr = std::lower_bound(
m_pileupProfileIntegral
.begin(),
m_pileupProfileIntegral
.end(),
threshold
);
187
return
std::distance(
m_pileupProfileIntegral
.begin(), itr );
188
}
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition
AthMsgStreamMacros.h:31
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition
AthMsgStreamMacros.h:29
MultiParticleGunPileup.h
AthCommonAlgorithm< Gaudi::Algorithm >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition
AthCommonDataStore.h:145
CyclicSeqSampler
Definition
Samplers.h:186
GenModule::GenModule
GenModule(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition
GenModule.cxx:14
GenModule::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
Definition
GenModule.cxx:34
MultiParticleGunPileup::genFinalize
virtual StatusCode genFinalize()
For finalising the generator, if required.
Definition
MultiParticleGunPileup.cxx:170
MultiParticleGunPileup::genInitialize
virtual StatusCode genInitialize()
For initializing the generator, if required.
Definition
MultiParticleGunPileup.cxx:39
MultiParticleGunPileup::callGenerator
virtual StatusCode callGenerator()
For calling the generator on each iteration of the event loop.
Definition
MultiParticleGunPileup.cxx:84
MultiParticleGunPileup::m_pileupProfileIntegral
std::vector< double > m_pileupProfileIntegral
Definition
MultiParticleGunPileup.h:49
MultiParticleGunPileup::m_evts
std::vector< HepMC::GenEvent * > m_evts
Definition
MultiParticleGunPileup.h:47
MultiParticleGunPileup::m_multbcid
std::vector< float > m_multbcid
Definition
MultiParticleGunPileup.h:40
MultiParticleGunPileup::m_nbad
int m_nbad
Definition
MultiParticleGunPileup.h:44
MultiParticleGunPileup::nPileupEvents
int nPileupEvents(CLHEP::HepRandomEngine *rndmEngine)
Definition
MultiParticleGunPileup.cxx:183
MultiParticleGunPileup::m_ngen
int m_ngen
Definition
MultiParticleGunPileup.h:43
MultiParticleGunPileup::m_partSampler
ParticleSampler * m_partSampler
Definition
MultiParticleGunPileup.h:54
MultiParticleGunPileup::m_filename
std::string m_filename
Definition
MultiParticleGunPileup.h:41
MultiParticleGunPileup::~MultiParticleGunPileup
~MultiParticleGunPileup()
Definition
MultiParticleGunPileup.cxx:35
MultiParticleGunPileup::m_ncollevent
int m_ncollevent
Definition
MultiParticleGunPileup.h:38
MultiParticleGunPileup::MultiParticleGunPileup
MultiParticleGunPileup(const std::string &name, ISvcLocator *pSvcLocator)
Definition
MultiParticleGunPileup.cxx:18
MultiParticleGunPileup::m_htgPileupProfile
TH1D * m_htgPileupProfile
Definition
MultiParticleGunPileup.h:52
MultiParticleGunPileup::m_htgPileupEvents
TH1D * m_htgPileupEvents
Definition
MultiParticleGunPileup.h:52
MultiParticleGunPileup::fillEvt
virtual StatusCode fillEvt(HepMC::GenEvent *event)
For filling the HepMC event object.
Definition
MultiParticleGunPileup.cxx:153
MultiParticleGunPileup::m_pileupProfile
std::vector< int > m_pileupProfile
Definition
MultiParticleGunPileup.h:39
MultiParticleGunPileup::m_htgPileupMu
TH1D * m_htgPileupMu
Definition
MultiParticleGunPileup.h:52
MultiParticleGunPileup::m_file
TFile * m_file
Definition
MultiParticleGunPileup.h:51
ParticleSampler
Definition
Samplers.h:345
PtEtaMPhiSampler
Definition
Samplers.h:293
HepMC::signal_process_id
int signal_process_id(const GenEvent &evt)
Definition
GenEvent.h:572
HepMC::FourVector
HepMC3::FourVector FourVector
Definition
SimpleVector.h:11
HepMC::set_signal_process_id
void set_signal_process_id(GenEvent *e, const int i=0)
Definition
GenEvent.h:580
HepMC::newGenParticlePtr
GenParticlePtr newGenParticlePtr(const HepMC3::FourVector &mom=HepMC3::FourVector::ZERO_VECTOR(), int pid=0, int status=0)
Definition
GenParticle.h:21
HepMC::fillBarcodesAttribute
void fillBarcodesAttribute(GenEvent *e)
Definition
GenEvent.h:393
HepMC::GenParticlePtr
HepMC3::GenParticlePtr GenParticlePtr
Definition
GenParticle.h:19
HepMC::newGenVertexPtr
GenVertexPtr newGenVertexPtr(const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
Definition
GenVertex.h:25
HepMC::GenVertexPtr
HepMC3::GenVertexPtr GenVertexPtr
Definition
GenVertex.h:23
HepMC::GenEvent
HepMC3::GenEvent GenEvent
Definition
GenEvent.h:39
threshold
Definition
chainparser.cxx:74
Generated on
for ATLAS Offline Software by
1.17.0