Reaction via qrules
#
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
Import Python libraries
import graphviz
import qrules
from ampform.io import improve_latex_rendering
from IPython.display import Math
from qrules import InteractionType, StateTransitionManager, io
from qrules.particle import Particle, Spin, load_pdg
improve_latex_rendering()
particle_db = load_pdg()
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"]
Math(proton.latex)
\(\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)
\(\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)
\(\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)
Virtual particle that represents the state pγ#
Adding custom particle#
We add the virtual particle \(p\gamma\) to represent the state of \(p-\gamma\) system in the photoproduction reaction. See PWA101 (see TR-033), 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
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)
Math(pgamma2.latex)
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.
reaction1_all = qrules.generate_transitions(
initial_state=("pgamma"),
final_state=["eta", "pi0", "p"],
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)
reaction1_strong_em = qrules.generate_transitions(
initial_state=("pgamma"),
final_state=["eta", "pi0", "p"],
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)
reaction1_strong = qrules.generate_transitions(
initial_state=("pgamma"),
final_state=["eta", "pi0", "p"],
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)
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]
some_problem_set = problem_sets[60.0][0]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
some_problem_set = problem_sets[1][0]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
some_problem_set = problem_sets[0.0001][1]
dot = io.asdot(some_problem_set, render_node=True)
graphviz.Source(dot)
reaction = stm.find_solutions(problem_sets)
print("found", len(reaction.transitions), "solutions!")
reaction.get_intermediate_particles().names
found 2304 solutions!
['a(0)(980)0',
'a(1)(1260)0',
'a(0)(1450)0',
'a(1)(1640)0',
'b(1)(1235)0',
'D~0',
'D0',
'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)',
'h(1)(1415)',
'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',
'K(0)*(1950)~0',
'K(0)*(1950)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)(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 80 solutions!
['a(0)(980)0',
'a(0)(1450)0',
'N(1440)+',
'N(1535)+',
'N(1650)+',
'N(1710)+',
'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 152 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)(1600)0']