Virtual particle that represents the state pγ#

Address to issue ✅ ComPWA/gluex-nstar#5, this section is an investigation of creating a virtual particle that represents the state \(p \gamma\) in QRules

As an example of side note, create a virtual particle that represents state \(e^+ e^-\) can be seen here.

Finding particles#

Our reaction is \(p + \gamma \to \eta + \pi^0 + p\), so we can look for each of the reaction and decay particles

from __future__ import annotations
from IPython.display import Math
from qrules.particle import load_pdg
from ampform.io import aslatex, improve_latex_rendering

improve_latex_rendering()
particle_db = load_pdg()
print("Number of loaded particles:", len(particle_db))
Number of loaded particles: 537

The ParticleCollection class offers some methods to search for particles by name or by PID, name, or other properties.

Proton#

Search by Particle ID (PID) for proton:

particle_db.find(2212)
Particle(
  name='p',
  pid=2212,
  latex='p',
  spin=0.5,
  mass=0.93827208816,
  charge=1,
  isospin=Spin(1/2, +1/2),
  baryon_number=1,
  parity=+1,
)

Search by Particle name for proton:

particle_db.find("p")
proton = particle_db["p"]
from IPython.display import Math

Math(proton.latex)
\[\displaystyle p\]

\(\gamma\)#

similarly for \(\gamma\):

particle_db.find("gamma")
Particle(
  name='gamma',
  pid=22,
  latex='\\gamma',
  spin=1.0,
  mass=0.0,
  parity=-1,
  c_parity=-1,
)
gamma = particle_db["gamma"]
Math(gamma.latex)
\[\displaystyle \gamma\]

\(\eta\)#

particle_db.find("eta")
Particle(
  name='eta',
  pid=221,
  latex='\\eta',
  spin=0.0,
  mass=0.547862,
  width=1.31e-06,
  isospin=Spin(0, 0),
  parity=-1,
  c_parity=+1,
  g_parity=+1,
)
eta = particle_db["eta"]
Math(gamma.latex)
\[\displaystyle \gamma\]

\(\pi^0\)#

particle_db.find("pi0")
Particle(
  name='pi0',
  pid=111,
  latex='\\pi^{0}',
  spin=0.0,
  mass=0.1349768,
  width=7.81e-09,
  isospin=Spin(1, 0),
  parity=-1,
  c_parity=+1,
  g_parity=-1,
)
pi0 = particle_db["pi0"]
Math(pi0.latex)
\[\displaystyle \pi^{0}\]

Adding custom particle#

We add the virtual particle \(p\gamma\) to represent the state of \(p-\gamma\) system in the photoproduction reaction. See PWA101 (temporary here), the value of the mass of the system \(m_{p\gamma}\) in CM frame is about 4.102 GeV in this analysis.

We use Particle from QRules for adding custom particle, so that some quantum numbers we need to determine for the \(p\gamma\) virtual state particle:

  • (Total) Spin

    • \(J_{p\gamma} = \frac{1}{2}\) or \(\frac{3}{2}\)

      because \(J_{p\gamma}\) = from \(|s_p-s_{\gamma}|\) to \(s_p + s_{\gamma}\) = from \(|\frac{1}{2}-1|\) to \(\frac{1}{2} + 1\)

  • Mass

    • \(m_{p\gamma} = E_{p\gamma} \approx 4.102\)

  • Charge

    • \(Q_{p\gamma} = Q_p + Q_{\gamma} = 1 \)

  • Isospin and \(3^{rd}\) component of isospin

    • \(I_{p\gamma} = I_p = \frac{1}{2}\)

    • \(I_{3_{p\gamma}} = I_{3_p} = +\frac{1}{2}\)

  • Baryon Number

    • \(B_{p\gamma} = B_p = 1\)

  • Parity

    • \(P_{p\gamma} = P_p \times P_{\gamma} = +1 \times (-1) = -1\)

These quantum numbers provide a complete and accurate description of the virtual particle representing the p−γ system with a mass of 4.102 GeV. The pγ virtual particle has two possibilities for the total spin, while the other quantum numbers are fixed.

We add the spin-\(\frac{1}{2}\) \(p\gamma\) virtual particle via QRules and named it \(p\gamma\) with a make-up pid number 99990

from qrules.particle import Particle, Spin

pgamma = Particle(
    name="pgamma",
    latex=r"p\gamma (s1/2)",
    spin=0.5,
    mass=4.101931071854584,
    charge=1,
    isospin=Spin(1 / 2, +1 / 2),
    baryon_number=1,
    parity=-1,
    pid=99990,
)
pgamma
Particle(
  name='pgamma',
  pid=99990,
  latex='p\\gamma (s1/2)',
  spin=0.5,
  mass=4.101931071854584,
  charge=1,
  isospin=Spin(1/2, +1/2),
  baryon_number=1,
  parity=-1,
)

We add the spin-\(\frac{3}{2}\) \(p\gamma\) virtual particle via QRules and named it \(p\gamma (s3/2)\) with a make-up pid number 99991

pgamma2 = Particle(
    name="pgamma2",
    latex=R"p\gamma (s3/2)",
    spin=1.5,
    mass=4.101931071854584,
    charge=1,
    isospin=Spin(1 / 2, +1 / 2),
    baryon_number=1,
    parity=-1,
    pid=99991,
)
pgamma2
Particle(
  name='pgamma2',
  pid=99991,
  latex='p\\gamma (s3/2)',
  spin=1.5,
  mass=4.101931071854584,
  charge=1,
  isospin=Spin(1/2, +1/2),
  baryon_number=1,
  parity=-1,
)
Math(pgamma.latex)
\[\displaystyle p\gamma (s1/2)\]
Math(pgamma2.latex)
\[\displaystyle p\gamma (s3/2)\]
particle_db.add(pgamma)
particle_db.add(pgamma2)

The \(`p\gamma`\) virtual states generated via QRules will be used in later stages, both possible spin states \((J= \frac{1}{2}\) and \(\frac{3}{2})\) should be taken into account if possible, otherwise simplified if necessary.

Important

It is possible to add any kind of custom Particle, as long as its quantum numbers comply with the gellmann_nishijima() rule:

Note

Gell-Mann-Nishijima formula: \(Q = I_3 + \frac{1}{2}(B+S+C+B'+T)\)

where Q is charge, \(I_3\) is Spin projection of isospin, B is baryon number, S is strangeness, C is charmness, B’ is bottomness, and T is topness.

import qrules
import graphviz

reaction1_all = qrules.generate_transitions(
    initial_state=("pgamma"),
    final_state=["eta", "pi0", "p"],
    # allowed_intermediate_particles=["a(2)", "Delta", "N"],
    allowed_interaction_types=["strong", "EM", "weak"],
    formalism="canonical-helicity",
    particle_db=particle_db,
)
dot_all = qrules.io.asdot(reaction1_all, collapse_graphs=True)
graphviz.Source(dot_all)
_images/b60c5e06f4dbf5181d4a2c911f4bea8274cffff3cbeedb96542764c3ed9038b3.svg
reaction1_strong_EM = qrules.generate_transitions(
    initial_state=("pgamma"),
    final_state=["eta", "pi0", "p"],
    # allowed_intermediate_particles=["a(2)", "Delta", "N"],
    allowed_interaction_types=["strong", "EM"],
    formalism="canonical-helicity",
    particle_db=particle_db,
)
dot_se = qrules.io.asdot(reaction1_strong_EM, collapse_graphs=True)
graphviz.Source(dot_se)
_images/5adb69458d6c80ae28c6918fef15339321790b9f3fbe8357b020696afed42fbc.svg
reaction1_strong = qrules.generate_transitions(
    initial_state=("pgamma"),
    final_state=["eta", "pi0", "p"],
    # allowed_intermediate_particles=["a(2)", "Delta", "N"],
    allowed_interaction_types=["strong"],
    formalism="canonical-helicity",
    particle_db=particle_db,
)
dot_s = qrules.io.asdot(reaction1_strong, collapse_graphs=True)
graphviz.Source(dot_s)
_images/f57e294e3f7953293286eff6f415f8cdf1a52a38926bc019135cf235d775ce6a.svg
from qrules import InteractionType, StateTransitionManager

stm = StateTransitionManager(
    initial_state=["pgamma"],
    final_state=["eta", "pi0", "p"],
    formalism="canonical-helicity",
    particle_db=particle_db,
)
problem_sets = stm.create_problem_sets()
sorted(problem_sets, reverse=True)
[3600.0, 60.0, 1.0, 0.006, 0.0001, 1e-08]
from qrules import io

some_problem_set = problem_sets[60.0][0]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
_images/67736169dba15beca2e02151153be1917f43ee464f279e32c6790303fd1cece3.svg
some_problem_set = problem_sets[1][0]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
_images/405b5b83859999120b90a646d41577bee0d23d301ab46beb42b00fc89a7abdf6.svg
some_problem_set = problem_sets[0.0001][1]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
_images/1ad2527a9d204644acb8df2d93b17f30146487faeda4d2e1fc8d7c5a72d86e74.svg
reaction = stm.find_solutions(problem_sets)
print("found", len(reaction.transitions), "solutions!")
reaction.get_intermediate_particles().names
found 2288 solutions!
['a(0)(980)0',
 'a(1)(1260)0',
 'a(0)(1450)0',
 'a(1)(1640)0',
 'b(1)(1235)0',
 'D0',
 'D~0',
 'D*(2007)0',
 'D*(2007)~0',
 'D(0)*(2300)~0',
 'D(0)*(2300)0',
 'D(1)(2430)~0',
 'D(1)(2430)0',
 'D(1)(2420)0',
 'D(1)(2420)~0',
 'Delta(1232)+',
 'Delta(1600)+',
 'Delta(1620)+',
 'Delta(1700)+',
 'Delta(1900)+',
 'Delta(1910)+',
 'Delta(1920)+',
 "eta'(958)",
 'eta(1295)',
 'eta(1405)',
 'eta(1475)',
 'eta(c)(1S)',
 'f(0)(500)',
 'f(0)(980)',
 'f(1)(1285)',
 'f(0)(1370)',
 'f(1)(1420)',
 'f(0)(1500)',
 'f(0)(1710)',
 'f(0)(2020)',
 'h(1)(1170)',
 'J/psi(1S)',
 'K(0)*(700)~0',
 'K(0)*(700)0',
 'K*(892)0',
 'K*(892)~0',
 'K(1)(1270)0',
 'K(1)(1270)~0',
 'K(1)(1400)0',
 'K(1)(1400)~0',
 'K*(1410)0',
 'K*(1410)~0',
 'K(0)*(1430)0',
 'K(0)*(1430)~0',
 'K(1)(1650)0',
 'K(1)(1650)~0',
 'K*(1680)~0',
 'K*(1680)0',
 'Lambda(c)+',
 'Lambda(c)(2595)+',
 'Lambda(c)(2625)+',
 'N(1440)+',
 'N(1520)+',
 'N(1535)+',
 'N(1650)+',
 'N(1710)+',
 'N(1700)+',
 'N(1720)+',
 'omega(782)',
 'omega(1420)',
 'omega(1650)',
 'phi(1020)',
 'phi(1680)',
 'pi(1300)0',
 'pi(1)(1400)0',
 'pi(1)(1600)0',
 'pi(1800)0',
 'rho(770)0',
 'rho(1450)0',
 'rho(1700)0',
 'Sigma+',
 'Sigma(1385)+',
 'Sigma(1660)+',
 'Sigma(1670)+',
 'Sigma(1750)+',
 'Sigma(1910)+',
 'Sigma(c)(2455)+',
 'Sigma(c)(2520)+',
 'Xi(c)+',
 "Xi(c)'+",
 'Xi(c)(2645)+',
 'Xi(c)(2790)+',
 'Xi(c)(2815)+']
stm.set_allowed_interaction_types([InteractionType.STRONG])
problem_sets = stm.create_problem_sets()
reaction = stm.find_solutions(problem_sets)

print("found", len(reaction.transitions), "solutions!")
reaction.get_intermediate_particles().names
found 88 solutions!
['a(0)(980)0',
 'a(0)(1450)0',
 'N(1440)+',
 'N(1535)+',
 'N(1650)+',
 'N(1710)+',
 'pi(1)(1400)0',
 'pi(1)(1600)0']
stm.set_allowed_interaction_types([InteractionType.STRONG, InteractionType.EM])
problem_sets = stm.create_problem_sets()
reaction = stm.find_solutions(problem_sets)

print("found", len(reaction.transitions), "solutions!")
reaction.get_intermediate_particles().names
found 160 solutions!
['a(0)(980)0',
 'a(0)(1450)0',
 'Delta(1620)+',
 'Delta(1900)+',
 'Delta(1910)+',
 'f(0)(500)',
 'f(0)(980)',
 'f(0)(1370)',
 'f(0)(1500)',
 'f(0)(1710)',
 'f(0)(2020)',
 'N(1440)+',
 'N(1535)+',
 'N(1650)+',
 'N(1710)+',
 'pi(1)(1400)0',
 'pi(1)(1600)0']