12 pdg - access particle definitions
13 ---------------------------------
15 This module helps to access particle definitions. When the software is loaded a
16 list of known particles is read from the EvtGen particle definition file
17 :file:`framework/particledb/data/evt.pdl`. This file contains all well-known
18 standard-model particles and their properties: mass, width or lifetime, charge,
22 This module allows to easily access this information (see `get`) or if necessary
23 add new particles using `add_particle` and even replace the whole particle
24 definition list using `load`.
26 It also provides simple getters to convert `PDG codes`_ into particle names and
27 vice versa for use with modules which require a list of PDG codes for the
28 particles to generate. See `from_name`, `from_names`, `to_name` and `to_names`
30 .. _PDG codes: http://pdg.lbl.gov/2020/reviews/rpp2020-rev-monte-carlo-numbering.pdf
35 from fractions
import Fraction
40 Function to return an instance of the EvtGenDatabasePDG class.
43 from ROOT
import Belle2
50 Function to return particle information (TParticlePDG) from ROOT Database.
52 'name' can be either the name of the particle, or a pdg code.
53 Will throw an LookupError of no such particle exists.
56 p = _get_instance().GetParticle(name)
58 raise LookupError(f
"No particle with name '{name}'")
65 Function to return pdg code for the given particle name.
67 >>> pdg.from_name("pi+")
71 return get(name).PdgCode()
74 def from_names(names):
76 for a list/tuple of particle names, return list of pdg codes.
78 >>> pdg.from_names(["e+","e-","gamma"])
82 assert not isinstance(names, str),
'Argument is not a list!'
84 return [from_name(n)
for n
in names]
89 Return particle name for given pdg code.
95 return get(pdg).GetName()
98 def to_names(pdg_codes):
100 for a list/tuple of pdg codes, return list of paricle names.
102 >>> pdg.to_names([11, -11, -211, 3212])
103 ['e-', 'e+', 'pi-', 'Sigma0']
106 assert not isinstance(pdg_codes, int),
'Argument is not a list!'
108 return [to_name(pdg)
for pdg
in pdg_codes]
113 Function to return name of conjugated particle
117 return to_name(-from_name(name))
124 Read particle database from given evtgen pdl file
126 _get_instance().ReadEvtGenTable(filename)
130 """Read default evt.pdl file"""
131 _get_instance().ReadEvtGenTable()
134 def add_particle(name, pdgCode, mass, width, charge, spin, max_width=None, lifetime=0, pythiaID=0,
135 define_anti_particle=False):
137 Add a new particle to the list of known particles.
139 The name cannot contain any whitespace character.
142 name (str): name of the particle
143 pdgCode (int): pdg code identifiert for the particle
144 mass (float): mass of the particle in GeV
145 width (float): width of the particle in GeV
146 charge (float): charge of the particle in e
147 spin (float): spin of the particle
148 max_width (float): max width, if omitted 3*width will be used
149 lifetime (float): lifetime in ns, should be 0 as geant4 cannot handle it correctly otherwise
150 pythiaID (int): pythiaID of the particle (if any), if omitted 0 will be used
151 define_anti_particle (bool): if True, an anti-particle with the default name anti-{name} is defined and added.
154 basf2.B2WARNING(
"Userdefined particle with non-zero lifetime will not be simulated correctly")
156 if max_width
is None:
158 max_width = width * 3
160 particle = _get_instance().AddParticle(name, name, mass,
False, width, charge * 3,
"userdefined",
161 pdgCode, 0, 0, lifetime, spin, max_width, pythiaID)
164 f
"Adding new particle '{name}' (pdg={int(pdgCode)}, mass={mass:.3g} GeV, width={width:.3g} GeV, " +
165 f
"charge={int(charge)}, spin={Fraction(spin)})")
167 if define_anti_particle:
168 anti_particle = _get_instance().AddParticle(
169 f
'anti-{name}', f
'anti-{name}', mass,
False, width, -charge * 3,
"userdefined", -pdgCode, 0, 0,
170 lifetime, spin, max_width, pythiaID
172 particle.SetAntiParticle(anti_particle)
173 basf2.B2INFO(f
"Adding new particle 'anti-{name}' as anti-particle of '{name}'")
180 def search(name=None, min_mass=None, max_mass=None, name_regex=False, include_width=False):
182 Search for a particles by name or mass or both.
184 This function allows to search for particle by name or mass and will return
185 a list of all particles which match the given criteria.
187 By default all searches for the name are case insensitive but if ``name``
188 starts with "~" the search will be case sensitive. The "~" will not be part
191 If ``name_regex=True`` the name will be interpreted as a python
192 :py:mod:`regular expression <re>` and the function will return all particles
193 whose names match the expression. If ``name_regex=False`` the function will
194 return a list of all particles containing the given pattern as substring
195 ignoring case with two special cases:
197 - if ``name`` begins with "^", only particles beginning with the pattern
198 will be searched. The "^" will not be part of the search.
199 - if ``name`` ends with "$" the pattern will only be matched to the end
200 of the particle name. The "$" will not be part of the search.
202 If ``include_width=True`` the search will include all particles if their
203 (mass ± width) is within the given limit. If ``include_width`` is a positive
204 number then the particle will be returned if :math:`m ± n*\Gamma` is within the
205 required range where n is the value of ``include_width`` and :math:`\Gamma` the
206 width of the particle.
209 Return a list of all particles
213 Search for all particles containing a "pi" somewhere in the name and ignore the case
217 Search for all particles beginning with K or k
221 Search for all particles ending with "+" and having a maximal mass of 3 GeV:
223 >>> search("+$", max_mass=3.0)
225 Search for all particles which contain a capital D and have a minimal mass of 1 GeV
227 >>> search("~D", min_mass=1.0)
229 Search for all partiles which contain a set of parenthesis containing a number
231 >>> search(r".*\(\d*\).*", name_regex=True)
233 Search all particles whose mass ± width covers 1 to 1.2 GeV
235 >>> search(min_mass=1.0, max_mass=1.2, include_width=True)
237 Search all particles whose mass ± 3*width touches 1 GeV
239 >>> search(min_mass=1.0, max_mass=1.0, include_width=3)
243 name (str): Search pattern which will either be matched as a substring
244 or as regular expression if ``name_regex=True``
245 min_mass (float): minimal mass for all returned particles or None for no limit
246 max_mass (float): maximal mass for all returned particles or None for no limit
247 name_regex (bool): if True then ``name`` will be treated as a regular expression
248 include_width (float or bool): if True or >0 include the particles if
249 (mass ± include_width*width) falls within the mass limits
254 options = re.IGNORECASE
260 if name[0] ==
"^" and name[-1] ==
"$":
261 name = f
"^{re.escape(name[1:-1])}$"
263 name = f
"^{re.escape(name[1:])}.*"
264 elif name[-1] ==
"$":
265 name = f
".*{re.escape(name[:-1])}$"
267 name = f
".*{re.escape(name)}.*"
269 pattern = re.compile(name, options)
271 if include_width
is True:
274 if include_width < 0:
278 for p
in _get_instance().ParticleList():
279 if pattern
is not None and not pattern.match(p.GetName()):
282 w = p.Width() * include_width
283 if min_mass
is not None and min_mass > (m + w):
285 if max_mass
is not None and max_mass < (m - w):
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.