5 pdg - access particle definitions
6 ---------------------------------
8 This module helps to access particle definitions. When the software is loaded a
9 list of known particles is read from the EvtGen particle definition file
10 :file:`framework/particledb/data/evt.pdl`. This file contains all well-known
11 standard-model particles and their properties: mass, width or lifetime, charge,
15 This module allows to easily access this information (see `get`) or if necessary
16 add new particles using `add_particle` and even replace the whole particle
17 definition list using `load`.
19 It also provides simple getters to convert `PDG codes`_ into particle names and
20 vice versa for use with modules which require a list of PDG codes for the
21 particles to generate. See `from_name`, `from_names`, `to_name` and `to_names`
23 .. _PDG codes: http://pdg.lbl.gov/2020/reviews/rpp2020-rev-monte-carlo-numbering.pdf
29 from ROOT.Belle2
import EvtGenDatabasePDG
32 _database = EvtGenDatabasePDG.Instance()
37 Function to return particle information (TParticlePDG) from ROOT Database.
39 'name' can be either the name of the particle, or a pdg code.
40 Will throw an LookupError of no such particle exists.
43 p = _database.GetParticle(name)
45 raise LookupError(
"No particle with name '%s'" % name)
52 Function to return pdg code for the given particle name.
54 >>> pdg.from_name("pi+")
58 return get(name).PdgCode()
61 def from_names(names):
63 for a list/tuple of particle names, return list of pdg codes.
65 >>> pdg.from_names(["e+","e-","gamma"])
69 assert not isinstance(names, str),
'Argument is not a list!'
71 return [from_name(n)
for n
in names]
76 Return particle name for given pdg code.
82 return get(pdg).GetName()
85 def to_names(pdg_codes):
87 for a list/tuple of pdg codes, return list of paricle names.
89 >>> pdg.to_names([11, -11, -211, 3212])
90 ['e-', 'e+', 'pi-', 'Sigma0']
93 assert not isinstance(pdg_codes, int),
'Argument is not a list!'
95 return [to_name(pdg)
for pdg
in pdg_codes]
100 Function to return name of conjugated particle
104 return to_name(-from_name(name))
105 except LookupError
as e:
111 Read particle database from given evtgen pdl file
113 _database.ReadEvtGenTable(filename)
117 """Read default evt.pdl file"""
118 _database.ReadEvtGenTable()
121 def add_particle(name, pdgCode, mass, width, charge, spin, max_width=None, lifetime=0, pythiaID=0):
123 Add a new particle to the list of known particles.
125 The name cannot contain any whitespace character.
128 name (str): name of the particle
129 pdgCode (int): pdg code identifiert for the particle
130 mass (float): mass of the particle in GeV
131 width (float): width of the particle in GeV
132 charge (float): charge of the particle in e
133 sping (float): spin of the particle
134 max_width (float): max width, if omitted 3*width will be used
135 lifetime (float): lifetime in ns, should be 0 as geant4 cannot handle it correctly otherwise
136 pythiaID (int): pythiaID of the particle (if any), if omitted 0 will be used
139 basf2.B2WARNING(
"Userdefined particle with non-zero lifetime will not be simulated correctly")
141 if max_width
is None:
143 max_width = width * 3
145 particle = _database.AddParticle(name, name, mass,
False, width, charge * 3,
"userdefined",
146 pdgCode, 0, 0, lifetime, spin, max_width, pythiaID)
148 basf2.B2INFO(
"Adding new particle '%s' (pdg=%d, mass=%.3g GeV, width=%.3g GeV, charge=%d, spin=%d)" %
149 (name, pdgCode, mass, width, charge, spin))
155 def search(name=None, min_mass=None, max_mass=None, name_regex=False, include_width=False):
157 Search for a particles by name or mass or both.
159 This function allows to search for particle by name or mass and will return
160 a list of all particles which match the given criteria.
162 By default all searches for the name are case insensitive but if ``name``
163 starts with "~" the search will be case sensitive. The "~" will not be part
166 If ``name_regex=True`` the name will be interpreted as a python
167 :py:mod:`regular expression <re>` and the function will return all particles
168 whose names match the expression. If ``name_regex=False`` the function will
169 return a list of all particles containing the given pattern as substring
170 ignoring case with two special cases:
172 - if ``name`` begins with "^", only particles beginning with the pattern
173 will be searched. The "^" will not be part of the search.
174 - if ``name`` ends with "$" the pattern will only be matched to the end
175 of the particle name. The "$" will not be part of the search.
177 If ``include_width=True`` the search will include all particles if their
178 (mass ± width) is within the given limit. If ``include_width`` is a positive
179 number then the particle will be returned if :math:`m ± n*\Gamma` is within the
180 required range where n is the value of ``include_width`` and :math:`\Gamma` the
181 width of the particle.
184 Return a list of all particles
188 Search for all particles containing a "pi" somewhere in the name and ignore the case
192 Search for all particles beginning with K or k
196 Search for all particles ending with "+" and having a maximal mass of 3 GeV:
198 >>> search("+$", max_mass=3.0)
200 Search for all particles which contain a capital D and have a minimal mass of 1 GeV
202 >>> search("~D", min_mass=1.0)
204 Search for all partiles which contain a set of parenthesis containing a number
206 >>> search(".*\(\d*\).*", name_regex=True)
208 Search all particles whose mass ± width covers 1 to 1.2 GeV
210 >>> search(min_mass=1.0, max_mass=1.2, include_width=True)
212 Search all particles whose mass ± 3*width touches 1 GeV
214 >>> search(min_mass=1.0, max_mass=1.0, include_width=3)
218 name (str): Search pattern which will either be matched as a substring
219 or as regular expression if ``name_regex=True``
220 min_mass (float): minimal mass for all returned particles or None for no limit
221 max_mass (float): maximal mass for all returned particles or None for no limit
222 name_regex (bool): if True then ``name`` will be treated as a regular expression
223 include_width (float or bool): if True or >0 include the particles if
224 (mass ± include_width*width) falls within the mass limits
229 options = re.IGNORECASE
235 if name[0] ==
"^" and name[-1] ==
"$":
236 name =
"^{}$".format(re.escape(name[1:-1]))
238 name =
"^{}.*".format(re.escape(name[1:]))
239 elif name[-1] ==
"$":
240 name =
".*{}$".format(re.escape(name[:-1]))
242 name =
".*{}.*".format(re.escape(name))
244 pattern = re.compile(name, options)
246 if include_width
is True:
249 if include_width < 0:
253 for p
in _database.ParticleList():
254 if pattern
is not None and not pattern.match(p.GetName()):
257 w = p.Width() * include_width
258 if min_mass
is not None and min_mass > (m+w):
260 if max_mass
is not None and max_mass < (m-w):