12pdg - access particle definitions 
   13--------------------------------- 
   15This module helps to access particle definitions. When the software is loaded a 
   16list of known particles is read from the EvtGen particle definition file 
   17:file:`framework/particledb/data/evt.pdl`. This file contains all well-known 
   18standard-model particles and their properties: mass, width or lifetime, charge, 
   22This module allows to easily access this information (see `get`) or if necessary 
   23add new particles using `add_particle` and even replace the whole particle 
   24definition list using `load`. 
   26It also provides simple getters to convert `PDG codes`_ into particle names and 
   27vice versa for use with modules which require a list of PDG codes for the 
   28particles 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 
   35from 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()
 
   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()
 
   98def to_names(pdg_codes):
 
  100    for a list/tuple of pdg codes, return list of particle 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()
 
  134def 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}'")
 
  180def 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.