Python API overview

The PDG Python API provides a high-level tool for programmatically accessing PDG data. For most users, this is the recommended way to access PDG data in machine-readable format. The Python API provides straightforward navigation from particles to their properties and the corresponding information included in the Review of Particle Physics. After installation the Python API does not require an Internet connection.

The Python API is implemented in Python package pdg and uses a PDG database file as its default data repository. The database file corresponding to the current edition of the Review of Particle Physics at the time of releasing a given version of the package is installed together with the package. When the Review of Particle Physics is updated, a new version of the pdg package with the latest data is released.

To access the data from other editions, additional database files can be downloaded from the PDG website and used with the Python API. Since SQLAlchemy is used for all database access, the necessary database tables could be copied from the SQLite database file into an existing database system (as long as it is supported by SQLAlchemy), and the Python API could then be used with that database system.

The pdg package is released as open source software and can be found at github.com/particledatagroup/api.

Requirements

The current version of the PDG Python API requires at least Python 3.10 and SQLAlchemy 1.4.

Earlier versions of the PDG API also supported Python 2.7, which has now been deprecated for several years. API version 0.2.2 with data from the 2025 update of the Review of Particle Physics was the last version that still supported Python 2.7 as well as Python 3 versions below 3.10. API versions since 0.2.3 require at least Python 3.10 in order to support type annotations, resulting in greatly improved documentation.

Starting with the 2026 edition of the Review of Particle Physics, versioning of the API has switched from semantic versioning to an edition-based versioning scheme where the first number indicates the edition of the Review of Particle Physics and the second number increments for each update for the same edition. Thus the initial release of the API for the 2026 edition has version 2026.0 while the first update will be version 2026.1.

Tutorial

A Jupyter notebook with a comprehensive tutorial on how to use the PDG Python API is available on github.

Installation

The PDG Python API can be installed like any other Python package available from PyPI.

For example, the following commands will first create and activate a Python 3 virtual environment using venv and then download and install package pdg and its dependencies:

python3 -m venv pdg.venv
source pdg.venv/bin/activate
python -m pip install pdg 

(Use virtualenv instead of venv for Python versions below 3.3.)

If a Python virtual environment was already activated, only the following command is needed:

python -m pip install pdg

Alternatively, to add the pdg package to one’s system Python installation if the system Python installation is not marked as being externally managed (if it is, there will be an error message error: externally-managed-environment), one can use

python -m pip install --user pdg

Usage

Any use of the PDG Python API starts with importing the package and connecting the API to a database file:

import pdg
api = pdg.connect()

As discussed in the API reference, connect() takes two optional arguments:

  1. The URL of the database to use. The default is to use the SQLite database file installed with the pdg package.

  2. Whether the API should operate in pedantic mode or not. Pedantic mode is disabled by default.

Connecting to a different database

To connect e.g. to a SQLite database file pdgall-2023-v0.1.sqlite, which was downloaded from the PDG website into the current directory, one would use

api = pdg.connect('sqlite:///pdgall-2023-v0.1.sqlite')

Pedantic mode

Given the nature of the PDG dataset, there are many special cases and sometimes additional knowledge is needed to determine the correct answer. For example, when asking for the mass of the top quark, in most cases the mass resulting from direct measurements is expected, but sometimes the user may want the mass determined from cross-section measurements. By default, if the user asks for a single value (rather than an iterable over all values), the API will either make an assumption that is expected to be correct in most cases, or simply return the value listed first in the Summary Tables or Particle Listings. If this default behaviour is not desirable, the API can connect in pedantic mode to the database:

api = pdg.connect(pedantic=True)

Then, rather than making assumptions in cases where the answer is ambiguous, a PdgAmbiguousValueError will be raised. Thus, taking the example above of the top quark mass,

pdg.connect().get_particle_by_name('t').mass

will return a value of about 173 GeV (2024 edition), while

pdg.connect(pedantic=True).get_particle_by_name('t').mass

will raise pdg.errors.PdgAmbiguousValueError: Ambiguous best property for t mass (Q007/2024).

Getting information about the database being used

After connecting to a database, the API object can be printed for a summary of edition, citation, versions and license information. These and more quantities (see api.info_keys()) can be accessed as properties of the API object or by using api.info(key). For example

api.edition

provides the edition (publication year) of the Review of Particle Physics from which the data is taken.

Examples

After retrieving the desired particle, one can then either directly get the desired quantity such as particle mass or quantum numbers, or obtain an iterator over the desired information such as all exclusive branching fractions for which PDG has data. A few examples with complete code snippets are given below.

Particle Monte Carlo number, mass and quantum numbers

Note: The Monte Carlo particle numbering scheme was substantially updated and extended in 2012. The Python API follows the particle numbering used in the current version of the PDG table of particle information where certain excited baryons follow the pre-2012 scheme. A further revision and/or extension of the numbering scheme is anticipated in the near future.

The following code snippet could be used to print the Monte Carlo particle number, mass (without rounding or errors), and spin of the negative pion:

import pdg
api = pdg.connect()
pi_minus = api.get_particle_by_name('pi-')
print('MC ID  = ', pi_minus.mcid)
print('mass   = ', pi_minus.mass, 'GeV')
print('spin J = ', pi_minus.quantum_J)

Properties and measurements

The following code snippet iterates over the mass properties of the top quark. For each property, the best summary value is printed, followed by all individual measurements included in PDG fits or averages:

import pdg
api = pdg.connect()
for mass in api.get_particle_by_name('t').masses():
    print('Best summary value for %s (%s): %s = %s'
          % (mass.pdgid, mass.description, mass.best_summary().value_type,
             mass.best_summary().value_text))
    for msmt in mass.get_measurements():
        if msmt.get_value().used_in_average or msmt.get_value().used_in_fit:
            print('%s (%s): %s'
                  % (msmt.reference.doi, msmt.reference.title,
                     msmt.get_value().value_text))
    print()

For a more extensive example, see examples/print_datablock.py in the API repository.

Branching fractions

The following code snippet prints all exclusive branching fractions of the charged B meson with their description, ‘True’ if the value denotes a limit, and the raw value (as an unrounded floating point number or None).

import pdg
api = pdg.connect()
for bf in api.get_particle_by_name('B+').exclusive_branching_fractions():
    print('%-60s    %4s    %s' % (bf.description, bf.is_limit, bf.value))

Decays

For branching fractions one can access the particles in the corresponding decay as a list of decay products (PdgDecayProduct). Each PdgDecayProduct specifies the item (PdgItem) that appears, a multiplier, and whether the item needs to decay in a specific way. PdgItems can represent a particle of a specific charge (e.g. a pi+), a generic particle such as a kaon without specifying its charge, a lepton (which could be either an electron or a muon), or a textual description such as “>= 0 neutrals”. These cases can be distinguished using the PdgItem's item_type property; one can call the PdgApi object’s doc_item_type_keys method to view an up-to-date table of the possible item types.

The name property of a PdgItem corresponds to the way that the decay product is expressed in the Review of Particle Physics. For a concrete particle, this is usually, but not always, the particle’s “canonical name”, i.e., the name property of the corresponding PdgParticle. In some cases (e.g. for historical reasons), the decay product’s PdgItem may contain a non-canonical name. When matching and comparing decays, the canonical name should be used (and should generally be regarded as the machine-readable name for the particle). The canonical_name property of a PdgItem will give its canonical name. For items that don’t represent a unique concrete particle, the canonical_name is the same as the name.

As implied above, a PdgParticle object can be retrieved from PdgItem using the particle property. This will raise an exception if the item does not refer to a single unique particle. Similarly, the particles property can be used to retrieve multiple particles for, e.g., a “generic” item that represents a multiplet. This can also raise an exception, such as in the case of an item that represents a purely textual description. The has_particle and has_particles properties can be used to check whether the particle and particles properties can be safely accessed.

In a simple case, all decay products appear with multiplicity 1 and are particles with specified charge. For example:

pion_decay = api.get('S008.1')
pion_decay.description                            # 'pi+ --> mu+ nu_mu'
len(pion_decay.decay_products)                    # 2
pion_decay.decay_products[0].multiplier           # 1
pion_decay.decay_products[0].item.name            # 'mu+'
pion_decay.decay_products[0].item.particle.mcid   # -13 

By querying the decay products one can easily filter out specific decay modes. For example, the following code snippet prints all exclusively measured B0 decays that produce a J/psi:

import pdg
api = pdg.connect()

for decay in api.get_particle_by_name('B0').exclusive_branching_fractions():
    # Note the use of p.item.canonical_name, instead of p.item.name
    decay_products = [p.item.canonical_name for p in decay.decay_products]
    if 'J/psi(1S)' in decay_products:
        print(format(decay.description,'40s'), decay.display_value_text)

Retrieving the particle properties of decay products requires some care:

import pdg
api = pdg.connect()

for decay in api.get_particle_by_name('B0').exclusive_branching_fractions():
    print(f'Masses of decay products for {decay.description}')
    for product in decay.decay_products:
        item = product.item
        if item.has_particle:
            p = item.particle
            mass = p.mass if p.has_mass_entry else None
            print(f'{item.name} (concrete): {mass} GeV')
        elif item.has_particles:
            masses = [p.mass if p.has_mass_entry else None
                      for p in item.particles]
            if all(m == masses[0] for m in masses):
                print(f'{item.name} (generic): {masses[0]} GeV')
            else:
                print(f'{item.name} (generic): No unique mass!')
    print()

A given decay may be associated with one or more subdecays, which may in turn have their own subdecays. In the following snippet, we print all of the direct subdecays of the Lambda_b()0:

import pdg
api = pdg.connect()

for decay in api.get_particle_by_name('Lambda_b()0').exclusive_branching_fractions():
    subdecays = list(decay.subdecays())
    if subdecays:
        print(f'Subdecays of {decay.description}:')
        for subdecay in subdecays:
            print(f'    {subdecay.description}')
        print()

The subdecay data is returned as-is from the Particle Listings. For its interpretation, please refer to the relevant section of the Review of Particle Physics.

Particle properties (except branching fractions)

The following code snippet prints all properties other than branching fractions of the charged pion (retrieved this time via Monte Carlo number rather than name). For each property, the PDG Identifier, the description, and the rounded value with error is shown.

import pdg
api = pdg.connect()
for p in api.get_particle_by_mcid(211).properties():
    print('%16s:  %-60s    %s' % (p.pdgid, p.description, p.display_value_text))

Detailed software documentation

Detailed information on all public classes, methods and utility functions provided by the PDG Python API is given in the API reference, based on the inline code documentation.

License

The data obtained from the PDG Python API is subject to the license used by the corresponding edition of the Review of Particle Physics. Starting with the 2024 edition, the Review of Particle Physics is published under a CC BY 4.0 license.