Source code for polarimetry
from __future__ import annotations
import sys
import sympy as sp
from ampform.sympy import PoolSum
from sympy.physics.matrices import msigma
from polarimetry.spin import create_spin_range
from .amplitude import DalitzPlotDecompositionBuilder
if sys.version_info < (3, 8):
from typing_extensions import Literal
else:
from typing import Literal
[docs]def formulate_polarimetry(
builder: DalitzPlotDecompositionBuilder, reference_subsystem: Literal[1, 2, 3] = 1
) -> tuple[PoolSum, PoolSum, PoolSum]:
half = sp.Rational(1, 2)
if builder.decay.initial_state.spin != half:
raise ValueError(
"Can only formulate polarimetry for an initial state with spin 1/2, but"
f" got {builder.decay.initial_state.spin}"
)
model = builder.formulate(reference_subsystem)
λ0, λ0_prime = sp.symbols(R"lambda \lambda^{\prime}", rational=True)
λ = {
sp.Symbol(f"lambda{i}", rational=True): create_spin_range(state.spin)
for i, state in builder.decay.final_state.items()
}
ref = reference_subsystem
return tuple(
PoolSum(
builder.formulate_aligned_amplitude(λ0, *λ, ref)[0].conjugate()
* pauli_matrix[_to_index(λ0), _to_index(λ0_prime)]
* builder.formulate_aligned_amplitude(λ0_prime, *λ, ref)[0],
(λ0, [-half, +half]),
(λ0_prime, [-half, +half]),
*λ.items(),
).cleanup()
/ model.intensity
for pauli_matrix in map(msigma, [1, 2, 3])
)
def _to_index(helicity):
"""Symbolic conversion of half-value helicities to Pauli matrix indices."""
return sp.Piecewise(
(1, sp.LessThan(helicity, 0)),
(0, True),
)