Download this notebook here.

Particle database

In PWA, you usually want to search for special resonances, possibly even some not listed in the PDG. In this notebook, we go through a few ways to add or overwrite Particle instances in the database with your own particle definitions.

Loading the default database

In the usual workflow, you start by calling the StateTransitionManager. Upon construction, the the StateTransitionManager calls the function load_default_particles, which fills the expertsystem.state.particle.DATABASE (simply a ParticleCollection instance) with Particle definitions from the PDG. Here, we call this method directly to illustrate what happens:

[1]:
from expertsystem.ui import load_default_particles

particle_db = load_default_particles()
print("Number of loaded particles:", len(particle_db))
Number of loaded particles: 533

In the following, we illustrate how to use the methods of the ParticleCollection class and the particle module to modify or add particle definitions in the particle database.

Finding particles

The ParticleCollection class offers some methods to search for particles, either by name or by PID (see ParticleCollection.find):

[2]:
particle_db.find(333)
[2]:
Particle('phi(1020)', 333, QuantumState(spin=1.0, charge=0, isospin=Spin(0.0, 0.0), strangeness=0, charmness=0, bottomness=0, topness=0, baryon_number=0, electron_lepton_number=0, muon_lepton_number=0, tau_lepton_number=0, parity=Parity(-1), c_parity=Parity(-1), g_parity=Parity(-1)), 1.019461, 0.004248999999999999)

ParticleCollection.find_subset returns a ParticleCollection subset instead of one Particle instance.

[3]:
subset = particle_db.find_subset("f(2)")
list(subset)
[3]:
['f(2)(1270)',
 "f(2)'(1525)",
 'f(2)(1950)',
 'f(2)(2010)',
 'f(2)(2300)',
 'f(2)(2340)']

More complicated searches can be done with list comprehensions. This is especially useful when searching for specific quantum numbers.

[4]:
{
    item.name
    for item in particle_db.values()
    if item.state.strangeness == 1
    and item.state.spin >= 1
    and item.mass > 1.8
    and item.mass < 1.9
}
[4]:
{'K(2)(1820)+',
 'K(2)(1820)0',
 'Lambda(1820)~',
 'Lambda(1830)~',
 'Lambda(1890)~'}

Adding custom particle definitions through Python

A quick way to modify or overwrite particles, is through your Python script of notebook. Notice that the instances in the database are Particle instances:

[5]:
N1650_plus = particle_db["N(1650)+"]
N1650_plus
[5]:
Particle('N(1650)+', 32212, QuantumState(spin=0.5, charge=1, isospin=Spin(0.5, 0.5), strangeness=0, charmness=0, bottomness=0, topness=0, baryon_number=1, electron_lepton_number=0, muon_lepton_number=0, tau_lepton_number=0, parity=Parity(-1), c_parity=None, g_parity=None), 1.65, 0.125)

The instances in the database are immutable. Therefore, if you want to modify, say, the width, you have to create a new Particle instance from the particle you want to modify and add it back to the database. You can do this with create_particle:

[6]:
from expertsystem.data import create_particle

new_N1650_plus = create_particle(
    template_particle=N1650_plus, name="Modified N(1650)+", width=0.2
)

particle_db.add(new_N1650_plus)
particle_db["Modified N(1650)+"].width
[6]:
0.2

You often also want to add the antiparticle of the particle you modified to the database. Using create_antiparticle, it is easy to create the corresponding antiparticle object.

[7]:
from expertsystem.data import create_antiparticle

new_N1650_minus = create_antiparticle(new_N1650_plus, new_name="Modified N(1650)-")

particle_db.add(new_N1650_minus)
particle_db["Modified N(1650)-"]
[7]:
Particle('Modified N(1650)-', -32212, QuantumState(spin=0.5, charge=-1, isospin=Spin(0.5, -0.5), strangeness=0, charmness=0, bottomness=0, topness=0, baryon_number=-1, electron_lepton_number=0, muon_lepton_number=0, tau_lepton_number=0, parity=Parity(+1), c_parity=None, g_parity=None), 1.65, 0.2)

When adding additional particles you may need for your research, it is easiest to work with an existing particle as template. Let’s say we want to study \(e^+e^-\) collisions of several energies:

[8]:
energies_mev = {4180, 4220, 4420, 4600}
template_particle = particle_db["J/psi(1S)"]
for energy_mev in energies_mev:
    energy_gev = energy_mev / 1e3
    new_particle = create_particle(
        template_particle, name=f"EpEm ({energy_mev} MeV)", mass=energy_gev
    )
    particle_db.add(new_particle)
len(particle_db)
[8]:
539
[9]:
set(particle_db.find_subset("EpEm"))
[9]:
{'EpEm (4180 MeV)', 'EpEm (4220 MeV)', 'EpEm (4420 MeV)', 'EpEm (4600 MeV)'}

Note

By convention, the expertsystem uses GeV as energy unit.

Loading custom definitions from a YAML file

It’s also possible to add particles from a config file, with load_particle_collection. Existing entries remain and if the imported file of particle definitions contains a particle with the same name, it is overwritten in the database.

It’s easiest to work with YAML. Here, we use the provided additional_particles.yml example file:

[10]:
from expertsystem.io import load_particle_collection

particle_db += load_particle_collection("additional_particles.yml")
WARNING:root:ParticleCollection: Overwriting particle Sigma(1385)+
WARNING:root:ParticleCollection: Overwriting particle Sigma(1660)+
WARNING:root:ParticleCollection: Overwriting particle Sigma(1750)+

Writing to XML or YAML

You can also dump the existing particle lists to either YAML or XML. You do this with the expertsystem.io.write function.

[11]:
from expertsystem import io

io.write(instance=particle_db, filename="dumped_particle_list.xml")
io.write(instance=particle_db, filename="dumped_particle_list.yaml")

Note that the function write can dump any ParticleCollection to an output file, also a specific subset.

[12]:
from expertsystem.data import ParticleCollection

output = ParticleCollection()
output += particle_db["J/psi(1S)"]
output += particle_db.find(22)  # gamma
output += particle_db.find_subset("f(0)")
output += particle_db["pi0"]
output += particle_db["pi+"]
output += particle_db["pi-"]
io.write(output, "particle_list_selection.yml")
set(output)
[12]:
{'J/psi(1S)',
 'f(0)(1370)',
 'f(0)(1500)',
 'f(0)(1710)',
 'f(0)(500)',
 'f(0)(980)',
 'gamma',
 'pi+',
 'pi-',
 'pi0'}

As a side note, the expertsystem provides JSON schemas (e.g. yaml/particle-list.json) to validate your particle list files (see also jsonschema.validate):

[13]:
import yaml

from expertsystem import io

with open("dumped_particle_list.yaml") as stream:
    definition = yaml.load(stream, Loader=yaml.SafeLoader)
io.yaml.validation.particle_list(definition)

In addition, if you have installed the expertsystem in Development mode and use VSCode, your YAML particle list are checked automatically in the GUI.