Topology and numbering

Short reference for indices and the flat topology used inside CascadeDecays.jl.

Names

NameRangeMeaning
line_ind1:nlinesRow in the incidence matrix: a particle line (final, internal, or root)
vertex_ind1:nverticesColumn in the incidence matrix: a binary decay vertex
address—Bracket key such as (2, 3); resolves via vertex_ind_for / line_ind_for
vertex—Local amplitude model (Vertex): chain.vertices[vertex_ind]
propagator—Lineshape payload, not a line id: entry in chain.propagators

User input uses address => vertex pairs in the vertices keyword; DecayChain stores them in vertex_address / root-first preorder as chain.vertices.

Counts for a tree with n final-state particles:

  • nfinal = n
  • nvertices = n − 1
  • nlines = nfinal + nvertices (finals + internal lines + root)
  • Np = nvertices (one propagator per internal line)

Bracket addresses such as (2, 3) or ((1, (2, 3)), 4) are user-facing keys. They resolve to a line_ind or vertex_ind via line_ind_for and vertex_ind_for.

Bracket child order is physical

The two children in every bracket pair are ordered. DecayTopology(((3, 1), 2)) and DecayTopology(((1, 3), 2)) are different topologies, even though they contain the same final-state labels. The order defines child1 and child2 in vertex_line_inds, and therefore fixes local helicity conventions, particle-2 phases, and Wigner-rotation paths. Do not treat bracket pairs as unordered sets.

Example

\[B^{+} \to \psi\, K^{+}\, K^{-}\, \pi^{+}\]

Decay chain:

B+  →  X0  K+
X0  →  ψ   K*0
K*0 →  K−  π+

Final-state labels 1…4 and bracket tree (right child = spectator at each step):

        B+  (root)
       /  \
     X0    K+        finals: 1=ψ, 2=K−, 3=π+, 4=K+
    /  \
   ψ   K*0
      /  \
     K−   π+
topology = DecayTopology(((1, (2, 3)), 4))
# bracket_notation(topology) == "((1,(2,3)),4)"

Line numbering

line_indRoleParticle / system
1–4finalψ, K−, π+, K+
5internalK*0 (from K− + π+)
6internalX0 (from ψ + K*0)
7rootB+

Internal lines are assigned in postorder; the root line is always nlines.

Vertex indices

Vertex indices are the columns of the incidence matrix, in root-first preorder (same order as DecayChain vertices):

vertex_indBracket addressDecay
1((1, (2, 3)), 4)B+ → X0 + K+
2(1, (2, 3))X0 → ψ + K*0
3(2, 3)K*0 → K− + π+

At each vertex index, vertex_line_inds returns (parent, child1, child2) as line ids. For example index 2: parent line 6 (X0), children lines 1 (ψ) and 5 (K*0).

The child1, child2 order is exactly the left/right order written in the bracket tree. For example:

bracket_notation(DecayTopology(((3, 1), 2))) == "((3,1),2)"
bracket_notation(DecayTopology(((1, 3), 2))) == "((1,3),2)"
DecayTopology(((3, 1), 2)) != DecayTopology(((1, 3), 2))

Incidence matrix

relation[line_ind, vertex_ind] uses this sign convention:

  • −1 — line enters the vertex (incoming parent)
  • +1 — line leaves the vertex (outgoing child)
  • 0 — no incidence

Rows = lines, columns = vertex indices:

          v1  v2  v3
  L1 ψ    0   1   0
  L2 K−   0   0   1
  L3 π+   0   0   1
  L4 K+   1   0   0
  L5 K*0  0   1  −1
  L6 X0   1  −1   0
  L7 B+  −1   0   0

Propagators vs lines

Only internal lines (5 and 6 here) carry propagators. A propagator payload sits in chain.propagators[i]; the corresponding line is propagating_line_inds(chain)[i]:

iline_indResonance
15K*0
26X0

Final lines (1–4) and the root (7) are lines without an attached propagator.

Amplitude axes

line_amplitude_tensor builds a buffer with one axis per line, sized by the spin/helicity multiplicity on that line. external_helicity_amplitude sums over internal line axes (propagating_line_inds); the result has one axis per external line (finals in final_line_inds order, plus the root helicity last).

For the full evaluation pipeline (propagators, vertex couplings, particle-2 phase), see Amplitude computation.