EvtGen
2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Toggle main menu visibility
Loading...
Searching...
No Matches
src
EvtGenExternal
EvtPHOTOS.cpp
Go to the documentation of this file.
1
2
/***********************************************************************
3
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4
* *
5
* This file is part of EvtGen. *
6
* *
7
* EvtGen is free software: you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation, either version 3 of the License, or *
10
* (at your option) any later version. *
11
* *
12
* EvtGen is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
16
* *
17
* You should have received a copy of the GNU General Public License *
18
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19
***********************************************************************/
20
21
#ifdef EVTGEN_PHOTOS
22
23
#include "
EvtGenExternal/EvtPHOTOS.hh
"
24
25
#include "
EvtGenBase/EvtPDL.hh
"
26
#include "
EvtGenBase/EvtPhotonParticle.hh
"
27
#include "
EvtGenBase/EvtRandom.hh
"
28
#include "
EvtGenBase/EvtReport.hh
"
29
#include "
EvtGenBase/EvtVector4R.hh
"
30
31
#include <iostream>
32
#include <sstream>
33
#include <vector>
34
35
using
std::endl;
36
37
// Mutex PHOTOS as it is not thread safe.
38
bool
EvtPHOTOS::m_initialised
=
false
;
39
std::mutex
EvtPHOTOS::m_photos_mutex
;
40
41
EvtPHOTOS::EvtPHOTOS
(
const
std::string& photonType,
const
bool
useEvtGenRandom,
42
const
double
infraredCutOff,
43
const
double
maxWtInterference ) :
44
m_useEvtGenRandom
{ useEvtGenRandom },
45
m_infraredCutOff
{ infraredCutOff },
46
m_maxWtInterference
{ maxWtInterference },
47
m_photonType
{ photonType }
48
{
49
}
50
51
void
EvtPHOTOS::initialise
()
52
{
53
const
std::lock_guard<std::mutex> lock(
m_photos_mutex
);
54
55
m_gammaId
=
EvtPDL::getId
(
m_photonType
);
56
if
(
m_gammaId
==
EvtId
( -1, -1 ) ) {
57
EvtGenReport
(
EVTGEN_INFO
,
"EvtGen"
)
58
<<
"Error in EvtPHOTOS. Do not recognise the photon type "
59
<<
m_photonType
<<
". Setting this to \"gamma\". "
<< endl;
60
m_gammaId
=
EvtPDL::getId
(
"gamma"
);
61
}
62
m_gammaPDG
=
EvtPDL::getStdHep
(
m_gammaId
);
63
64
if
(
m_initialised
) {
65
return
;
66
}
67
68
EvtGenReport
(
EVTGEN_INFO
,
"EvtGen"
) <<
"Setting up PHOTOS."
<< endl;
69
70
if
(
m_useEvtGenRandom
) {
71
EvtGenReport
(
EVTGEN_INFO
,
"EvtGen"
)
72
<<
"Using EvtGen random number engine also for Photos++"
<< endl;
73
74
Photospp::Photos::setRandomGenerator(
EvtRandom::Flat
);
75
}
76
77
Photospp::Photos::initialize();
78
79
Photospp::Photos::setExponentiation(
true
);
80
81
/* Sets the infrared cutoff (default at 1e-7)
82
* Reset the minimum photon energy, if required, in units of half of the decaying particle mass.
83
* This must be done after exponentiation! Keep the cut at 1e-7, i.e. 0.1 keV at the 1 GeV scale,
84
* which is appropriate for B decays
85
*/
86
Photospp::Photos::setInfraredCutOff(
m_infraredCutOff
);
87
88
Photospp::Photos::setInterference(
true
);
89
90
/* Increase the maximum possible value of the interference weight
91
* corresponding to 2^n, where n = number of charges (+,-).
92
*/
93
Photospp::Photos::maxWtInterference(
m_maxWtInterference
);
94
95
#ifdef EVTGEN_PHOTOS_NEWLIBS
96
// This turns off/on virtual photons splitting into l+l-
97
// It is false by default, but just to keep track of it here.
98
Photospp::Photos::setPairEmission(
false
);
99
#endif
100
101
m_initialised
=
true
;
102
}
103
104
void
EvtPHOTOS::doRadCorr
(
EvtParticle
* theParticle )
105
{
106
if
( !theParticle ) {
107
return
;
108
}
109
110
/* Skip running Photos if the particle has no daughters, since we can't add FSR.
111
* Also skip Photos if the particle has too many daughters (>= 10) to avoid a problem
112
* with a hard coded upper limit in the PHOENE subroutine.
113
*/
114
const
int
nDaughters( theParticle->
getNDaug
() );
115
if
( nDaughters == 0 || nDaughters >= 10 ) {
116
return
;
117
}
118
119
/* Create a dummy HepMC GenEvent containing a single vertex, with the mother
120
* assigned as the incoming particle and its daughters as outgoing particles.
121
* We then pass this event to Photos for processing.
122
* It will return a modified version of the event, updating the momentum of
123
* the original particles and will contain any new photon particles.
124
* We add these extra photons to the mother particle daughter list.
125
* First, Create the dummy event.
126
*/
127
auto
theEvent = std::make_unique<GenEvent>( Units::GEV, Units::MM );
128
129
// Create the decay "vertex".
130
GenVertexPtr
theVertex =
newGenVertexPtr
();
131
theEvent->add_vertex( theVertex );
132
133
// Add the mother particle as the incoming particle to the vertex.
134
const
GenParticlePtr
hepMCMother = this->
createGenParticle
( *theParticle,
135
true
);
136
theVertex->add_particle_in( hepMCMother );
137
138
/* Find all daughter particles and assign them as outgoing particles to the vertex.
139
* Keep track of the number of photons already in the decay (e.g. we may have B -> K* gamma)
140
*/
141
int
iDaug( 0 ), nGamma( 0 );
142
for
( iDaug = 0; iDaug < nDaughters; iDaug++ ) {
143
const
EvtParticle
& theDaughter = *theParticle->
getDaug
( iDaug );
144
const
GenParticlePtr
hepMCDaughter =
145
this->
createGenParticle
( theDaughter,
false
);
146
theVertex->add_particle_out( hepMCDaughter );
147
148
if
( theDaughter.
getPDGId
() ==
m_gammaPDG
) {
149
nGamma++;
150
}
151
}
152
153
{
154
const
std::lock_guard<std::mutex> lock(
m_photos_mutex
);
155
/* Now pass the event to Photos for processing
156
* Create a Photos event object */
157
#ifdef EVTGEN_HEPMC3
158
Photospp::PhotosHepMC3Event photosEvent( theEvent.get() );
159
#else
160
Photospp::PhotosHepMCEvent photosEvent( theEvent.get() );
161
#endif
162
163
// Run the Photos algorithm
164
photosEvent.process();
165
}
166
167
// Find the number of (outgoing) photons in the event
168
const
int
nPhotons = this->
getNumberOfPhotons
( theVertex );
169
170
int
iLoop( 0 );
171
// See whether Photos has created additional photons. If not, do nothing extra.
172
if
( nPhotons > nGamma ) {
173
// We have extra particles from Photos; these would have been appended
174
// to the outgoing particle list
175
176
// Get the iterator of outgoing particles for this vertex
177
#ifdef EVTGEN_HEPMC3
178
for
(
const
auto
& outParticle : theVertex->particles_out() ) {
179
#else
180
HepMC::GenVertex::particles_out_const_iterator outIter;
181
for
( outIter = theVertex->particles_out_const_begin();
182
outIter != theVertex->particles_out_const_end(); ++outIter ) {
183
// Get the next HepMC GenParticle
184
const
HepMC::GenParticle* outParticle = *outIter;
185
#endif
186
// Get the three-momentum Photos result for this particle, and the PDG id
187
if
( outParticle ) {
188
const
FourVector
HepMCP4 = outParticle->momentum();
189
const
double
px = HepMCP4.px();
190
const
double
py = HepMCP4.py();
191
const
double
pz = HepMCP4.pz();
192
const
double
energy = HepMCP4.e();
193
const
int
pdgId = outParticle->pdg_id();
194
const
EvtVector4R
newP4( energy, px, py, pz );
195
196
if
( iLoop < nDaughters ) {
197
/* Original daughters: keep the original particle mass,
198
* but set the three-momentum according to what Photos
199
* has modified.
200
*/
201
EvtParticle
* daugParticle = theParticle->
getDaug
( iLoop );
202
if
( daugParticle ) {
203
daugParticle->
setP4WithFSR
( newP4 );
204
}
205
206
}
else
if
( pdgId ==
m_gammaPDG
) {
207
// Extra photon particle. Setup the four-momentum object
208
209
// Create a new photon particle and add it to the list of daughters
210
EvtPhotonParticle
* gamma =
new
EvtPhotonParticle
();
211
gamma->
init
(
m_gammaId
, newP4 );
212
// Set the pre-FSR photon momentum to zero
213
gamma->
setFSRP4toZero
();
214
// Set its particle attribute to specify it is a FSR photon
215
gamma->
setAttribute
(
"FSR"
, 1 );
// it is a FSR photon
216
// Let the mother know about this new photon
217
gamma->
addDaug
( theParticle );
218
}
219
220
// Increment the loop counter for detecting additional photon particles
221
iLoop++;
222
}
223
}
224
}
225
226
// Cleanup
227
theEvent->clear();
228
229
return
;
230
}
231
232
GenParticlePtr
EvtPHOTOS::createGenParticle
(
const
EvtParticle
& theParticle,
233
bool
incoming )
const
234
{
235
/* Method to create an HepMC::GenParticle version of the given EvtParticle.
236
*/
237
238
// Get the 4-momentum (E, px, py, pz) for the EvtParticle
239
const
EvtVector4R
p4 = incoming ? theParticle.
getP4Restframe
()
240
: theParticle.
getP4
();
241
242
// Convert this to the HepMC 4-momentum
243
const
double
E = p4.
get
( 0 );
244
const
double
px = p4.
get
( 1 );
245
const
double
py = p4.
get
( 2 );
246
const
double
pz = p4.
get
( 3 );
247
248
const
FourVector
hepMC_p4( px, py, pz, E );
249
250
const
int
PDGInt =
EvtPDL::getStdHep
( theParticle.
getId
() );
251
252
// Set the status flag for the particle. This is required, otherwise Photos++
253
// will crash from out-of-bounds array index problems.
254
const
int
status = incoming ? Photospp::PhotosParticle::HISTORY
255
: Photospp::PhotosParticle::STABLE;
256
257
const
GenParticlePtr
genParticle =
newGenParticlePtr
( hepMC_p4, PDGInt,
258
status );
259
260
return
genParticle;
261
}
262
263
int
EvtPHOTOS::getNumberOfPhotons
(
const
GenVertexPtr
theVertex )
const
264
{
265
/* Find the number of photons from the outgoing particle list
266
*/
267
268
if
( !theVertex ) {
269
return
0;
270
}
271
272
int
nPhotons( 0 );
273
274
// Get the iterator of outgoing particles for this vertex
275
#ifdef EVTGEN_HEPMC3
276
for
(
const
auto
& outParticle : theVertex->particles_out() ) {
277
#else
278
HepMC::GenVertex::particles_out_const_iterator outIter;
279
for
( outIter = theVertex->particles_out_const_begin();
280
outIter != theVertex->particles_out_const_end(); ++outIter ) {
281
// Get the next HepMC GenParticle
282
const
HepMC::GenParticle* outParticle = *outIter;
283
#endif
284
285
// Get the PDG id
286
int
pdgId( 0 );
287
if
( outParticle !=
nullptr
) {
288
pdgId = outParticle->pdg_id();
289
}
290
291
// Keep track of how many photons there are
292
if
( pdgId ==
m_gammaPDG
) {
293
nPhotons++;
294
}
295
}
296
297
return
nPhotons;
298
}
299
300
#endif
GenVertexPtr
HepMC3::GenVertexPtr GenVertexPtr
Definition
EvtHepMCEvent.hh:33
newGenVertexPtr
GenVertexPtr newGenVertexPtr(const FourVector &pos=FourVector::ZERO_VECTOR())
Definition
EvtHepMCEvent.hh:43
newGenParticlePtr
GenParticlePtr newGenParticlePtr(const FourVector &mom=FourVector::ZERO_VECTOR(), int pid=0, int status=0)
Definition
EvtHepMCEvent.hh:37
GenParticlePtr
HepMC3::GenParticlePtr GenParticlePtr
Definition
EvtHepMCEvent.hh:32
FourVector
HepMC3::FourVector FourVector
Definition
EvtHepMCEvent.hh:35
EvtPDL.hh
EvtPHOTOS.hh
EvtPhotonParticle.hh
EvtRandom.hh
EvtReport.hh
EvtGenReport
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition
EvtReport.cpp:32
EVTGEN_INFO
@ EVTGEN_INFO
Definition
EvtReport.hh:52
EvtVector4R.hh
EvtId
Definition
EvtId.hh:27
EvtPDL::getStdHep
static int getStdHep(EvtId id)
Definition
EvtPDL.cpp:356
EvtPDL::getId
static EvtId getId(const std::string &name)
Definition
EvtPDL.cpp:283
EvtPHOTOS::m_useEvtGenRandom
bool m_useEvtGenRandom
Definition
EvtPHOTOS.hh:71
EvtPHOTOS::m_photos_mutex
static std::mutex m_photos_mutex
Definition
EvtPHOTOS.hh:85
EvtPHOTOS::createGenParticle
GenParticlePtr createGenParticle(const EvtParticle &theParticle, bool incoming) const
Definition
EvtPHOTOS.cpp:232
EvtPHOTOS::m_maxWtInterference
double m_maxWtInterference
Definition
EvtPHOTOS.hh:77
EvtPHOTOS::m_initialised
static bool m_initialised
Definition
EvtPHOTOS.hh:84
EvtPHOTOS::m_infraredCutOff
double m_infraredCutOff
Definition
EvtPHOTOS.hh:75
EvtPHOTOS::getNumberOfPhotons
int getNumberOfPhotons(const GenVertexPtr theVertex) const
Definition
EvtPHOTOS.cpp:263
EvtPHOTOS::m_gammaPDG
long int m_gammaPDG
Definition
EvtPHOTOS.hh:82
EvtPHOTOS::doRadCorr
void doRadCorr(EvtParticle *theParticle) override
Definition
EvtPHOTOS.cpp:104
EvtPHOTOS::m_photonType
std::string m_photonType
Definition
EvtPHOTOS.hh:80
EvtPHOTOS::initialise
void initialise() override
Definition
EvtPHOTOS.cpp:51
EvtPHOTOS::EvtPHOTOS
EvtPHOTOS(const std::string &photonType="gamma", const bool useEvtGenRandom=true, const double infraredCutOff=1.0e-7, const double maxWtInterference=64.0)
Definition
EvtPHOTOS.cpp:41
EvtPHOTOS::m_gammaId
EvtId m_gammaId
Definition
EvtPHOTOS.hh:81
EvtParticle
Definition
EvtParticle.hh:45
EvtParticle::getId
EvtId getId() const
Definition
EvtParticle.cpp:124
EvtParticle::getP4Restframe
EvtVector4R getP4Restframe() const
Definition
EvtParticle.cpp:788
EvtParticle::setAttribute
void setAttribute(std::string attName, int attValue)
Definition
EvtParticle.hh:423
EvtParticle::getPDGId
int getPDGId() const
Definition
EvtParticle.cpp:129
EvtParticle::getP4
const EvtVector4R & getP4() const
Definition
EvtParticle.cpp:144
EvtParticle::getDaug
EvtParticle * getDaug(const int i)
Definition
EvtParticle.hh:173
EvtParticle::setP4WithFSR
void setP4WithFSR(const EvtVector4R &p4)
Definition
EvtParticle.hh:277
EvtParticle::getNDaug
size_t getNDaug() const
Definition
EvtParticle.cpp:154
EvtParticle::addDaug
void addDaug(EvtParticle *node)
Definition
EvtParticle.cpp:112
EvtParticle::setFSRP4toZero
void setFSRP4toZero()
Definition
EvtParticle.hh:279
EvtPhotonParticle
Definition
EvtPhotonParticle.hh:30
EvtPhotonParticle::init
void init(EvtId part_n, double e, double px, double py, double pz)
Definition
EvtPhotonParticle.cpp:37
EvtRandom::Flat
static double Flat()
Definition
EvtRandom.cpp:95
EvtVector4R
Definition
EvtVector4R.hh:29
EvtVector4R::get
double get(int i) const
Definition
EvtVector4R.hh:163
Generated by
1.17.0