Λc⁺ → p π⁺ K⁻#
Show code cell content
from __future__ import annotations
import graphviz
import qrules
import sympy as sp
from IPython.display import Latex, Markdown
from ampform_dpd import DalitzPlotDecompositionBuilder
from ampform_dpd.adapter.qrules import (
load_particles,
normalize_state_ids,
to_three_body_decay,
)
from ampform_dpd.decay import ThreeBodyDecayChain
from ampform_dpd.dynamics import BreitWignerMinL
from ampform_dpd.dynamics.builder import create_mass_symbol, get_mandelstam_s
from ampform_dpd.io import as_markdown_table, aslatex, simplify_latex_rendering
simplify_latex_rendering()
Decay definition#
Show code cell source
PARTICLES = load_particles()
for name in [
"K*(1410)~0",
"K(2)*(1430)~0",
"K*(1680)~0",
"Delta(1620)++",
"Delta(1900)++",
"Delta(1910)++",
"Delta(1920)++",
"Lambda(1800)",
"Lambda(1810)",
"Lambda(1890)",
]:
PARTICLES.remove(PARTICLES[name])
STM = qrules.StateTransitionManager(
initial_state=["Lambda(c)+"],
final_state=["p", "K-", "pi+"],
mass_conservation_factor=3,
allowed_intermediate_particles=["K", "Delta", "Lambda"],
particle_db=PARTICLES,
max_angular_momentum=2,
formalism="canonical-helicity",
)
STM.set_allowed_interaction_types([qrules.InteractionType.STRONG], node_id=1)
problem_sets = STM.create_problem_sets()
REACTION = STM.find_solutions(problem_sets)
REACTION = normalize_state_ids(REACTION)
dot = qrules.io.asdot(REACTION, collapse_graphs=True)
graphviz.Source(dot)
Show code cell source
DECAY = to_three_body_decay(REACTION.transitions, min_ls=True)
Markdown(as_markdown_table([DECAY.initial_state, *DECAY.final_state.values()]))
Show code cell source
resonances = sorted(
{t.resonance for t in DECAY.chains},
key=lambda p: (p.name[0], p.mass),
)
resonance_names = [p.name for p in resonances]
Markdown(as_markdown_table(resonances))
Lineshapes for dynamics#
Show code cell source
s, m0, Γ0, m1, m2 = sp.symbols("s m0 Gamma0 m1 m2", nonnegative=True)
m_top, m_spec = sp.symbols(R"m_\mathrm{top} m_\mathrm{spectator}", nonnegative=True)
R_dec, R_prod = sp.symbols(R"R_\mathrm{res} R_{\Lambda_c}", nonnegative=True)
l_Λc, l_R = sp.symbols(R"l_{\Lambda_c} l_R", integer=True, nonnegative=True)
bw = BreitWignerMinL(s, m_top, m_spec, m0, Γ0, m1, m2, l_R, l_Λc, R_dec, R_prod)
Latex(aslatex({bw: bw.doit(deep=False)}))
Dynamics builder function
def formulate_breit_wigner(
decay_chain: ThreeBodyDecayChain,
) -> tuple[BreitWignerMinL, dict[sp.Symbol, float]]:
s = get_mandelstam_s(decay_chain.decay_node)
child1_mass, child2_mass = map(create_mass_symbol, decay_chain.decay_products)
l_dec = sp.Rational(decay_chain.outgoing_ls.L)
l_prod = sp.Rational(decay_chain.incoming_ls.L)
parent_mass = sp.Symbol(f"m_{{{decay_chain.parent.latex}}}", nonnegative=True)
spectator_mass = sp.Symbol(f"m_{{{decay_chain.spectator.latex}}}", nonnegative=True)
resonance_mass = sp.Symbol(f"m_{{{decay_chain.resonance.latex}}}", nonnegative=True)
resonance_width = sp.Symbol(
Rf"\Gamma_{{{decay_chain.resonance.latex}}}", nonnegative=True
)
R_dec = sp.Symbol(R"R_\mathrm{res}", nonnegative=True)
R_prod = sp.Symbol(R"R_{\Lambda_c}", nonnegative=True)
parameter_defaults = {
parent_mass: decay_chain.parent.mass,
spectator_mass: decay_chain.spectator.mass,
resonance_mass: decay_chain.resonance.mass,
resonance_width: decay_chain.resonance.width,
child1_mass: decay_chain.decay_products[0].mass,
child2_mass: decay_chain.decay_products[1].mass,
# https://github.com/ComPWA/polarimetry/pull/11#issuecomment-1128784376
R_dec: 1.5,
R_prod: 5,
}
dynamics = BreitWignerMinL(
s,
parent_mass,
spectator_mass,
resonance_mass,
resonance_width,
child1_mass,
child2_mass,
l_dec,
l_prod,
R_dec,
R_prod,
)
return dynamics, parameter_defaults
Model formulation#
model_builder = DalitzPlotDecompositionBuilder(DECAY, min_ls=(False, True))
for chain in model_builder.decay.chains:
model_builder.dynamics_choices.register_builder(chain, formulate_breit_wigner)
model = model_builder.formulate(reference_subsystem=1)
model.intensity