decay
decay¶
import ampform.helicity.decay
Extract two-body decay info from a StateTransition
.
- class StateWithID(particle: Particle, spin_projection: SupportsFloat, id: int)[source]¶
Bases:
State
Extension of
State
that embeds the state ID.- classmethod from_transition(transition: StateTransition, state_id: int) StateWithID [source]¶
- class TwoBodyDecay(parent: StateWithID, children: tuple[StateWithID, StateWithID], interaction: InteractionProperties)[source]¶
Bases:
object
Two-body sub-decay in a
StateTransition
.This container class ensures that:
a selected node in a
StateTransition
is indeed a 1-to-2 body decayits two
children
are sorted by whether they decay further or not (seeget_helicity_angle_label
,formulate_wigner_d
, andformulate_clebsch_gordan_coefficients
).the
TwoBodyDecay
is hashable, so that it can be used as a key (seeset_dynamics
.)
- parent: StateWithID¶
- children: tuple[StateWithID, StateWithID]¶
- interaction: InteractionProperties¶
- static create(obj) TwoBodyDecay [source]¶
Create a
TwoBodyDecay
instance from an arbitrary object.More implementations of
create()
can be implemented with@ampform.helicity.decay._create_two_body_decay.register(TYPE)
.
- classmethod from_transition(transition: StateTransition, node_id: int) TwoBodyDecay [source]¶
- is_opposite_helicity_state(topology: Topology, state_id: int) bool [source]¶
Determine if an edge is an “opposite helicity” state.
This function provides a deterministic way of identifying states in a
Topology
as “opposite helicity” vs “helicity” state. It enforces that:state
0
is never an opposite helicity statethe sibling of an opposite helicity state is a helicity state.
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(5) >>> for topology in topologies: ... assert not is_opposite_helicity_state(topology, state_id=0) ... for state_id in set(topology.edges) - topology.incoming_edge_ids: ... sibling_id = get_sibling_state_id(topology, state_id) ... assert is_opposite_helicity_state( ... topology, state_id ... ) != is_opposite_helicity_state( ... topology, sibling_id ... )
The Wigner-\(D\) function for a two-particle state treats one helicity with a negative sign. This sign originates from Eq.(13) in [13] (see also Eq.(6) in [1]). Following [1], we call the state that gets this minus sign the “opposite helicity” state. The other state is called helicity state. The choice of (opposite) helicity state affects not only the sign in the Wigner-\(D\) function, but also the choice of angles: the argument of the Wigner-\(D\) function returned by
formulate_wigner_d()
are the angles of the helicity state.
- get_sibling_state_id(topology: Topology, state_id: int) int [source]¶
Get the sibling state ID for a state in an isobar decay.
Example
-- 3 -- 0 \ 4 -- 1 \ 2
The sibling state of
1
is2
and the sibling state of3
is4
.
- get_helicity_info(transition: StateTransition, node_id: int) tuple[State, tuple[State, State]] [source]¶
Extract in- and outgoing states for a two-body decay node.
- get_parent_id(topology: Topology, state_id: int) int | None [source]¶
Get the edge ID of the edge from which this state decayed.
Warning
This only works on 1-to-\(n\) isobar topologies.
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(3) >>> topology = topologies[0] >>> get_parent_id(topology, state_id=0) -1 >>> get_parent_id(topology, state_id=1) # parent is the resonance 3 >>> get_parent_id(topology, state_id=2) 3 >>> get_parent_id(topology, state_id=3) -1 >>> get_parent_id(topology, state_id=-1) # already the top particle
- list_decay_chain_ids(topology: Topology, state_id: int) list[int] [source]¶
Get the edge ID of the edge from which this state decayed.
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(3) >>> topology = topologies[0] >>> list_decay_chain_ids(topology, state_id=0) [0, -1] >>> list_decay_chain_ids(topology, state_id=1) [1, 3, -1] >>> list_decay_chain_ids(topology, state_id=2) [2, 3, -1] >>> list_decay_chain_ids(topology, state_id=-1) [-1]
- get_sorted_states(transition: StateTransition, state_ids: Iterable[int]) list[State] [source]¶
Get a sorted list of
State
instances.In order to ensure correct naming of amplitude coefficients the list has to be sorted by name. The same coefficient names have to be created for two transitions that only differ from a kinematic standpoint (swapped external edges).
- determine_attached_final_state(topology: Topology, state_id: int) list[int] [source]¶
Determine all final state particles of a transition.
These are attached downward (forward in time) for a given edge (resembling the root).
Example
For edge 5 in Figure topologies[0], we get:
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(5) >>> determine_attached_final_state(topologies[0], state_id=5) [0, 3, 4]
- get_prefactor(transition: StateTransition) float [source]¶
Calculate the product of all prefactors defined in this transition.
- group_by_spin_projection(transitions: Iterable[StateTransition]) list[list[StateTransition]] [source]¶
Match final and initial states in groups.
Each
StateTransition
corresponds to a specific state transition amplitude. This function groups together transitions, which have the same initial and final state (including spin). This is needed to determine the coherency of the individual amplitude parts.
- group_by_topology(transitions: Iterable[StateTransition]) dict[Topology, list[StateTransition]] [source]¶
Group state transitions by different
Topology
.