kinematics
kinematics#
import ampform.kinematics
Classes and functions for relativistic four-momentum kinematics.
- class HelicityAdapter(transitions: ReactionInfo | Iterable[Topology | StateTransition])[source]#
Bases:
object
Converter for four-momenta to kinematic variable data.
The
create_expressions
method forms the bridge between four-momentum data for the decay you are studying and the kinematic variables that are in theHelicityModel
. These are invariant mass (seeget_invariant_mass_symbol()
) and the \(\theta\) and \(\phi\) helicity angles (seeget_helicity_angle_symbols()
).- register_transition(transition: StateTransition) None [source]#
- permutate_registered_topologies() None [source]#
Register outgoing edge permutations of all
registered_topologies
.
- create_four_momentum_symbols(topology: Topology) FourMomenta [source]#
Create a set of array-symbols for a
Topology
.>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(3) >>> create_four_momentum_symbols(topologies[0]) {0: p0, 1: p1, 2: p2}
- FourMomenta#
A mapping of state IDs to their corresponding
FourMomentumSymbol
.Itβs best to create a
dict
ofFourMomenta
withcreate_four_momentum_symbols()
.alias of
Dict
[int
,FourMomentumSymbol
]
- FourMomentumSymbol#
Array-
Symbol
that represents an array of four-momenta.The array is assumed to be of shape \(n\times 4\) with \(n\) the number of events. The four-momenta are assumed to be in the order \(\left(E,\vec{p}\right)\). See also
Energy
,FourMomentumX
,FourMomentumY
, andFourMomentumZ
.
- class Energy(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Represents the energy-component of a
FourMomentumSymbol
.\(E\left(p\right)=p\left[:, 0\right]\)
- class FourMomentumX(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Component \(x\) of a
FourMomentumSymbol
.\({p}_x=p\left[:, 1\right]\)
- class FourMomentumY(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Component \(y\) of a
FourMomentumSymbol
.\({p}_y=p\left[:, 2\right]\)
- class FourMomentumZ(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Component \(z\) of a
FourMomentumSymbol
.\({p}_z=p\left[:, 3\right]\)
- class ThreeMomentum(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
,NumPyPrintable
Spatial components of a
FourMomentumSymbol
.\(\vec{p}=p\left[:, 1:\right]\)
p[:, 1:]
- class EuclideanNorm(vector: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
,NumPyPrintable
Take the euclidean norm of an array over axis 1.
\(\left|v\right|=\sqrt{\left|v\right|^{2}}\)
from numpy import sqrt, sum numpy.sqrt(sum(v**2, axis=1))
- class EuclideanNormSquared(vector: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Take the squared euclidean norm of an array over axis 1.
- three_momentum_norm(momentum: Basic) EuclideanNorm [source]#
- class InvariantMass(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Invariant mass of a
FourMomentumSymbol
.(1)#\[\begin{split} \begin{array}{rcl} m_{p} &=& \sqrt[\mathrm{c}]{E\left(p\right)^{2} - \left|\vec{p}\right|^{2}} \\ \end{array}\end{split}\]
- class Phi(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Azimuthal angle \(\phi\) of a
FourMomentumSymbol
.(2)#\[\begin{split} \begin{array}{rcl} \phi\left(p\right) &=& \operatorname{atan}_{2}{\left({p}_y,{p}_x \right)} \\ \end{array}\end{split}\]
- class Theta(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Polar (elevation) angle \(\theta\) of a
FourMomentumSymbol
.(3)#\[\begin{split} \begin{array}{rcl} \theta\left(p\right) &=& \operatorname{acos}{\left(\frac{{p}_z}{\left|\vec{p}\right|} \right)} \\ \end{array}\end{split}\]
- class NegativeMomentum(momentum: Basic, **hints)[source]#
Bases:
UnevaluatedExpression
Invert the spatial components of a
FourMomentumSymbol
.
- class MinkowskiMetric(momentum: Basic, **hints)[source]#
Bases:
NumPyPrintable
Minkowski metric \(\eta = (1, -1, -1, -1)\).
- class BoostZMatrix(beta: Basic, n_events: Expr | None = None, **kwargs)[source]#
Bases:
UnevaluatedExpression
Represents a Lorentz boost matrix in the \(z\)-direction.
- Parameters
beta β Velocity in the \(z\)-direction, \(\beta=p_z/E\).
n_events β Number of events \(n\) for this matrix array of shape \(n\times4\times4\). Defaults to the
len
ofbeta
.
This boost operates on a
FourMomentumSymbol
and looks like:(4)#\[\begin{split}\boldsymbol{B_z}\left(\beta\right) = \left[\begin{matrix}\frac{1}{\sqrt[\mathrm{c}]{1 - \beta^{2}}} & 0 & 0 & - \frac{\beta}{\sqrt[\mathrm{c}]{1 - \beta^{2}}}\\0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\- \frac{\beta}{\sqrt[\mathrm{c}]{1 - \beta^{2}}} & 0 & 0 & \frac{1}{\sqrt[\mathrm{c}]{1 - \beta^{2}}}\end{matrix}\right]\end{split}\]In TensorWaves, this class is expressed in a computational backend and it should operate on four-momentum arrays of rank-2. As such, this boost matrix becomes a rank-3 matrix. When using NumPy as backend, the computation looks as follows:
from numpy import array, ones, sqrt, zeros def _lambdifygenerated(b): x0 = 1/numpy.sqrt(1 - b**2) x1 = len(b) return (array( [ [x0, zeros(x1), zeros(x1), -b*x0], [zeros(x1), ones(x1), zeros(x1), zeros(x1)], [zeros(x1), zeros(x1), ones(x1), zeros(x1)], [-b*x0, zeros(x1), zeros(x1), x0], ] ).transpose((2, 0, 1)))
Note that this code was generated with
sympy.lambdify
withcse=True
. The repetition ofnumpy.ones()
is still bothersome, but these sub-nodes is also extracted bysympy.cse
if the expression is nested further down in an expression tree, for instance when boosting aFourMomentumSymbol
\(p\) in the \(z\)-direction:(5)#\[\boldsymbol{B_z}\left(\beta\right) \boldsymbol{R_y}\left(\theta\right) \boldsymbol{R_z}\left(\phi\right) p\]which in
numpy
code becomes:from numpy import array, cos, einsum, ones, sin, sqrt, zeros def _lambdifygenerated(beta, p, phi, theta): x0 = 1/numpy.sqrt(1 - beta**2) x1 = len(p) x2 = ones(x1) x3 = zeros(x1) return (einsum("...ij,...jk,...kl,...l->...i", array( [ [x0, x3, x3, -beta*x0], [x3, x2, x3, x3], [x3, x3, x2, x3], [-beta*x0, x3, x3, x0], ] ).transpose((2, 0, 1)), array( [ [x2, x3, x3, x3], [x3, numpy.cos(theta), x3, numpy.sin(theta)], [x3, x3, x2, x3], [x3, -numpy.sin(theta), x3, numpy.cos(theta)], ] ).transpose((2, 0, 1)), array( [ [x2, x3, x3, x3], [x3, numpy.cos(phi), -numpy.sin(phi), x3], [x3, numpy.sin(phi), numpy.cos(phi), x3], [x3, x3, x3, x2], ] ).transpose((2, 0, 1)), p))
- class BoostMatrix(momentum: Basic, **kwargs)[source]#
Bases:
UnevaluatedExpression
Compute a rank-3 Lorentz boost matrix from a
FourMomentumSymbol
.This boost operates on a
FourMomentumSymbol
and looks like:(6)#\[\begin{split}\boldsymbol{B}\left(p\right) = \left[\begin{matrix}\frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}} & - \frac{{p}_x}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)} & - \frac{{p}_y}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)} & - \frac{{p}_z}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)}\\- \frac{{p}_x}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_x^{2}}{\left|\vec{p}\right|^{2}} + 1 & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_x {p}_y}{\left|\vec{p}\right|^{2}} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_x {p}_z}{\left|\vec{p}\right|^{2}}\\- \frac{{p}_y}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_x {p}_y}{\left|\vec{p}\right|^{2}} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_y^{2}}{\left|\vec{p}\right|^{2}} + 1 & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_y {p}_z}{\left|\vec{p}\right|^{2}}\\- \frac{{p}_z}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}} E\left(p\right)} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_x {p}_z}{\left|\vec{p}\right|^{2}} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_y {p}_z}{\left|\vec{p}\right|^{2}} & \frac{\left(-1 + \frac{1}{\sqrt{1 - \frac{\left|\vec{p}\right|^{2}}{E\left(p\right)^{2}}}}\right) {p}_z^{2}}{\left|\vec{p}\right|^{2}} + 1\end{matrix}\right]\end{split}\]In TensorWaves, this class is expressed in a computational backend and it should operate on four-momentum arrays of rank-2. As such, this boost matrix becomes a rank-3 matrix. When using NumPy as backend, the computation looks as follows:
from numpy import sqrt, sum def _lambdifygenerated(p): x0 = p x1 = x0[:, 0] x2 = sum(x0[:, 1:]**2, axis=1) x3 = 1/numpy.sqrt(1 - x2/x1**2) x4 = x0[:, 1] x5 = x3/x1 x6 = x0[:, 2] x7 = x0[:, 3] x8 = (x3 - 1)/x2 x9 = x4*x8 return (array( [ [x3, -x4*x5, -x5*x6, -x5*x7], [-x4*x5, x4**2*x8 + 1, x6*x9, x7*x9], [-x5*x6, x6*x9, x6**2*x8 + 1, x6*x7*x8], [-x5*x7, x7*x9, x6*x7*x8, x7**2*x8 + 1], ] ).transpose((2, 0, 1)))
- class RotationYMatrix(angle: Basic, n_events: Expr | None = None, **hints)[source]#
Bases:
UnevaluatedExpression
Rotation matrix around the \(y\)-axis for a
FourMomentumSymbol
.- Parameters
The matrix for a rotation over angle \(\alpha\) around the \(y\)-axis operating on
FourMomentumSymbol
looks like:(7)#\[\begin{split}\boldsymbol{R_y}\left(\alpha\right) = \left[\begin{matrix}1 & 0 & 0 & 0\\0 & \cos{\left(\alpha \right)} & 0 & \sin{\left(\alpha \right)}\\0 & 0 & 1 & 0\\0 & - \sin{\left(\alpha \right)} & 0 & \cos{\left(\alpha \right)}\end{matrix}\right]\end{split}\]See
RotationZMatrix
for the computational code.
- class RotationZMatrix(angle: Basic, n_events: Expr | None = None, **hints)[source]#
Bases:
UnevaluatedExpression
Rotation matrix around the \(z\)-axis for a
FourMomentumSymbol
.- Parameters
The matrix for a rotation over angle \(\alpha\) around the \(z\)-axis operating on
FourMomentumSymbol
looks like:(8)#\[\begin{split}\boldsymbol{R_z}\left(\alpha\right) = \left[\begin{matrix}1 & 0 & 0 & 0\\0 & \cos{\left(\alpha \right)} & - \sin{\left(\alpha \right)} & 0\\0 & \sin{\left(\alpha \right)} & \cos{\left(\alpha \right)} & 0\\0 & 0 & 0 & 1\end{matrix}\right]\end{split}\]In TensorWaves, this class is expressed in a computational backend and it should operate on four-momentum arrays of rank-2. As such, this boost matrix becomes a rank-3 matrix. When using NumPy as backend, the computation looks as follows:
from numpy import array, cos, ones, sin, zeros def _lambdifygenerated(a): x0 = len(a) return (array( [ [ones(x0), zeros(x0), zeros(x0), zeros(x0)], [zeros(x0), numpy.cos(a), -numpy.sin(a), zeros(x0)], [zeros(x0), numpy.sin(a), numpy.cos(a), zeros(x0)], [zeros(x0), zeros(x0), zeros(x0), ones(x0)], ] ).transpose((2, 0, 1)))
See also the note that comes with Equation (5).
- compute_helicity_angles(four_momenta: Mapping[int, Expr], topology: Topology) dict[Symbol, Expr] [source]#
Formulate expressions for all helicity angles in a topology.
Formulate expressions (
Expr
) for all helicity angles appearing in a givenTopology
. The expressions are given in terms ofFourMomenta
The expressions returned as values in adict
, where the keys are defined byget_helicity_angle_symbols()
.Example
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(3) >>> topology = topologies[0] >>> four_momenta = create_four_momentum_symbols(topology) >>> angles = compute_helicity_angles(four_momenta, topology) >>> theta_symbol = sp.Symbol("theta_0", real=True) >>> angles[theta_symbol] Theta(p1 + p2)
- compute_invariant_masses(four_momenta: FourMomenta, topology: Topology) dict[Symbol, Expr] [source]#
Compute the invariant masses for all final state combinations.
- compute_wigner_angles(topology: Topology, momenta: FourMomenta, state_id: int) dict[Symbol, Expr] [source]#
Create an
Expr
for each angle in a Wigner rotation.Implementation of (B.2-4) in [1], with \(x'_z\) etc. taken from the result of
compute_wigner_rotation_matrix()
.
- compute_wigner_rotation_matrix(topology: Topology, momenta: FourMomenta, state_id: int) MatrixMultiplication [source]#
Compute a Wigner rotation matrix.
Implementation of Eq. (36) in [1].
- compute_boost_chain(topology: Topology, momenta: FourMomenta, state_id: int) list[BoostMatrix] [source]#
- get_four_momentum_sum(topology: Topology, momenta: FourMomenta, state_id: int) ArraySum | FourMomentumSymbol [source]#
Get the
FourMomentumSymbol
or sum of momenta for any edge ID.If the edge ID is a final state ID, return its
FourMomentumSymbol
. If itβs an intermediate edge ID, return the sum of the momenta of the final states to which it decays.>>> from qrules.topology import create_isobar_topologies >>> topology = create_isobar_topologies(3)[0] >>> momenta = create_four_momentum_symbols(topology) >>> get_four_momentum_sum(topology, momenta, state_id=0) p0 >>> get_four_momentum_sum(topology, momenta, state_id=3) p1 + p2
- get_invariant_mass_symbol(topology: Topology, state_id: int) Symbol [source]#
Generate an invariant mass label for a state (edge on a topology).
Example
In the case shown in Figure topologies[0], the invariant mass of state \(5\) is \(m_{034}\), because \(p_5=p_0+p_3+p_4\):
>>> from qrules.topology import create_isobar_topologies >>> topologies = create_isobar_topologies(5) >>> get_invariant_mass_symbol(topologies[0], state_id=5) m_034
Naturally, the βinvariantβ mass label for a final state is just the mass of the state itself:
>>> get_invariant_mass_symbol(topologies[0], state_id=1) m_1
Submodules and Subpackages