Skip to content

Commit

Permalink
BREAK: split kinematics module (#384)
Browse files Browse the repository at this point in the history
* FEAT: make `determine_indices()` publicly available
  • Loading branch information
redeboer authored Dec 27, 2023
1 parent 17f383e commit 8b45539
Show file tree
Hide file tree
Showing 17 changed files with 1,200 additions and 1,119 deletions.
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
],
"ignoreWords": [
"Autoupdate",
"Dalitzplot",
"MAINT",
"Minkowski",
"adrs",
Expand Down Expand Up @@ -254,6 +255,7 @@
"lineshapes",
"mathbb",
"matplotlib",
"Mikhasenko",
"mypy",
"nishijima",
"numpy",
Expand Down
39 changes: 22 additions & 17 deletions docs/_extend_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from sympy.printing.numpy import NumPyPrinter

from ampform.io import aslatex
from ampform.kinematics import ArraySize, FourMomentumSymbol
from ampform.kinematics.lorentz import ArraySize, FourMomentumSymbol
from ampform.sympy._array_expressions import ArrayMultiplication

if sys.version_info < (3, 8):
Expand Down Expand Up @@ -72,14 +72,14 @@ def extend_BlattWeisskopfSquared() -> None:


def extend_BoostMatrix() -> None:
from ampform.kinematics import BoostMatrix
from ampform.kinematics.lorentz import BoostMatrix

p = FourMomentumSymbol("p", shape=[])
expr = BoostMatrix(p)
_append_to_docstring(
BoostMatrix,
f"""\n
This boost operates on a `FourMomentumSymbol` and looks like:
This boost operates on a `.FourMomentumSymbol` and looks like:
.. math:: {sp.latex(expr)} = {sp.latex(expr.as_explicit())}
:class: full-width
Expand All @@ -103,14 +103,14 @@ def extend_BoostMatrix() -> None:


def extend_BoostZMatrix() -> None:
from ampform.kinematics import BoostZMatrix
from ampform.kinematics.lorentz import BoostZMatrix

beta, n_events = sp.symbols("beta n")
matrix = BoostZMatrix(beta, n_events)
_append_to_docstring(
BoostZMatrix,
f"""\n
This boost operates on a `FourMomentumSymbol` and looks like:
This boost operates on a `.FourMomentumSymbol` and looks like:
.. math:: {sp.latex(matrix)} = {sp.latex(matrix.as_explicit())}
:label: BoostZMatrix
Expand All @@ -132,7 +132,7 @@ def extend_BoostZMatrix() -> None:
docstring_class=BoostZMatrix,
)

from ampform.kinematics import RotationYMatrix, RotationZMatrix
from ampform.kinematics.lorentz import RotationYMatrix, RotationZMatrix

_append_to_docstring(
BoostZMatrix,
Expand Down Expand Up @@ -259,7 +259,12 @@ def extend_EnergyDependentWidth() -> None:


def extend_Energy_and_FourMomentumXYZ() -> None:
from ampform.kinematics import Energy, FourMomentumX, FourMomentumY, FourMomentumZ
from ampform.kinematics.lorentz import (
Energy,
FourMomentumX,
FourMomentumY,
FourMomentumZ,
)

def _extend(component_class: type[sp.Expr]) -> None:
_append_to_docstring(component_class, "\n\n")
Expand All @@ -274,7 +279,7 @@ def _extend(component_class: type[sp.Expr]) -> None:


def extend_EuclideanNorm() -> None:
from ampform.kinematics import EuclideanNorm
from ampform.kinematics.lorentz import EuclideanNorm

vector = FourMomentumSymbol("v", shape=[])
expr = EuclideanNorm(vector)
Expand Down Expand Up @@ -327,7 +332,7 @@ def extend_Kibble() -> None:


def extend_InvariantMass() -> None:
from ampform.kinematics import InvariantMass
from ampform.kinematics.lorentz import InvariantMass

p = FourMomentumSymbol("p", shape=[])
expr = InvariantMass(p)
Expand Down Expand Up @@ -403,23 +408,23 @@ def extend_PhaseSpaceFactorSWave() -> None:


def extend_Phi() -> None:
from ampform.kinematics import Phi
from ampform.kinematics.angles import Phi

p = FourMomentumSymbol("p", shape=[])
expr = Phi(p)
_append_latex_doit_definition(expr)


def extend_RotationYMatrix() -> None:
from ampform.kinematics import RotationYMatrix
from ampform.kinematics.lorentz import RotationYMatrix

angle, n_events = sp.symbols("alpha n")
expr = RotationYMatrix(angle, n_events)
_append_to_docstring(
RotationYMatrix,
f"""\n
The matrix for a rotation over angle :math:`\\alpha` around the :math:`y`-axis
operating on `FourMomentumSymbol` looks like:
operating on `.FourMomentumSymbol` looks like:
.. math:: {sp.latex(expr)} = {sp.latex(expr.as_explicit())}
:label: RotationYMatrix
Expand All @@ -430,15 +435,15 @@ def extend_RotationYMatrix() -> None:


def extend_RotationZMatrix() -> None:
from ampform.kinematics import RotationZMatrix
from ampform.kinematics.lorentz import RotationZMatrix

angle, n_events = sp.symbols("alpha n")
expr = RotationZMatrix(angle, n_events)
_append_to_docstring(
RotationZMatrix,
f"""\n
The matrix for a rotation over angle :math:`\\alpha` around the :math:`z`-axis
operating on `FourMomentumSymbol` looks like:
The matrix for a rotation over angle :math:`\\alpha` around the
:math:`z`-axis operating on `.FourMomentumSymbol` looks like:
.. math:: {sp.latex(expr)} = {sp.latex(expr.as_explicit())}
:label: RotationZMatrix
Expand Down Expand Up @@ -468,15 +473,15 @@ def extend_RotationZMatrix() -> None:


def extend_Theta() -> None:
from ampform.kinematics import Theta
from ampform.kinematics.angles import Theta

p = FourMomentumSymbol("p", shape=[])
expr = Theta(p)
_append_latex_doit_definition(expr)


def extend_ThreeMomentum() -> None:
from ampform.kinematics import ThreeMomentum
from ampform.kinematics.lorentz import ThreeMomentum

p = FourMomentumSymbol("p", shape=[])
expr = ThreeMomentum(p)
Expand Down
5 changes: 3 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"BuilderReturnType": ("obj", "ampform.dynamics.builder.BuilderReturnType"),
"DecoratedClass": ("obj", "ampform.sympy.deprecated.DecoratedClass"),
"DecoratedExpr": ("obj", "ampform.sympy.deprecated.DecoratedExpr"),
"FourMomenta": ("obj", "ampform.kinematics.FourMomenta"),
"FourMomentumSymbol": ("obj", "ampform.kinematics.FourMomentumSymbol"),
"FourMomenta": ("obj", "ampform.kinematics.lorentz.FourMomenta"),
"FourMomentumSymbol": ("obj", "ampform.kinematics.lorentz.FourMomentumSymbol"),
"InteractionProperties": "qrules.quantum_numbers.InteractionProperties",
"LatexPrinter": "sympy.printing.printer.Printer",
"Literal[(-1, 1)]": "typing.Literal",
Expand Down Expand Up @@ -230,6 +230,7 @@
"show_navbar_depth": 2,
"show_toc_level": 2,
}
html_title = REPO_TITLE
intersphinx_mapping = {
"IPython": (f"https://ipython.readthedocs.io/en/{pin('IPython')}", None),
"attrs": (f"https://www.attrs.org/en/{pin('attrs')}", None),
Expand Down
4 changes: 2 additions & 2 deletions docs/usage/kinematics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
},
"outputs": [],
"source": [
"from ampform.kinematics import (\n",
"from ampform.kinematics.lorentz import (\n",
" ArrayMultiplication,\n",
" ArraySize,\n",
" BoostZMatrix,\n",
Expand Down Expand Up @@ -225,7 +225,7 @@
"metadata": {},
"outputs": [],
"source": [
"from ampform.kinematics import BoostMatrix\n",
"from ampform.kinematics.lorentz import BoostMatrix\n",
"\n",
"B = BoostMatrix(p)\n",
"B_expr = ArrayMultiplication(B, q)\n",
Expand Down
5 changes: 2 additions & 3 deletions src/ampform/dynamics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@
PhaseSpaceFactorComplex, # noqa: F401
PhaseSpaceFactorProtocol,
PhaseSpaceFactorSWave, # noqa: F401
_determine_indices,
_indices_to_subscript,
)
from ampform.sympy import argument, unevaluated
from ampform.sympy import argument, determine_indices, unevaluated

if TYPE_CHECKING:
from sympy.printing.latex import LatexPrinter
Expand Down Expand Up @@ -180,7 +179,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s = printer._print(self.args[0])
gamma0 = self.args[2]
subscript = _indices_to_subscript(_determine_indices(gamma0))
subscript = _indices_to_subscript(determine_indices(gamma0))
name = Rf"\Gamma{subscript}" if self.name is None else self.name
return Rf"{name}\left({s}\right)"

Expand Down
2 changes: 1 addition & 1 deletion src/ampform/dynamics/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class TwoBodyKinematicVariableSet:
"""Data container for the essential variables of a two-body decay.
This data container is inserted into a `.ResonanceDynamicsBuilder`, so that it can
build some lineshape expression from the `.dynamics` module. It also allows to
build some lineshape expression from the :mod:`.dynamics` module. It also allows to
insert :doc:`custom dynamics </usage/dynamics/custom>` into the amplitude model.
"""

Expand Down
46 changes: 7 additions & 39 deletions src/ampform/dynamics/phasespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@

from __future__ import annotations

import re
import sys
from typing import TYPE_CHECKING, Any, Sequence

import sympy as sp
from sympy.printing.conventions import split_super_sub

from ampform.sympy import argument, unevaluated
from ampform.sympy import argument, determine_indices, unevaluated
from ampform.sympy.math import ComplexSqrt

if TYPE_CHECKING:
Expand Down Expand Up @@ -87,7 +85,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s = self.args[0]
s_latex = printer._print(self.args[0])
subscript = _indices_to_subscript(_determine_indices(s))
subscript = _indices_to_subscript(determine_indices(s))
name = "q^2" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand All @@ -113,7 +111,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s_symbol = self.args[0]
s_latex = printer._print(s_symbol)
subscript = _indices_to_subscript(_determine_indices(s_symbol))
subscript = _indices_to_subscript(determine_indices(s_symbol))
name = R"\rho" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand Down Expand Up @@ -144,7 +142,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s_symbol = self.args[0]
s_latex = printer._print(s_symbol)
subscript = _indices_to_subscript(_determine_indices(s_symbol))
subscript = _indices_to_subscript(determine_indices(s_symbol))
name = R"\hat{\rho}" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand All @@ -171,7 +169,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s_symbol = self.args[0]
s_latex = printer._print(s_symbol)
subscript = _indices_to_subscript(_determine_indices(s_symbol))
subscript = _indices_to_subscript(determine_indices(s_symbol))
name = R"\rho^\mathrm{c}" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand All @@ -197,7 +195,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s_symbol = self.args[0]
s_latex = printer._print(s_symbol)
subscript = _indices_to_subscript(_determine_indices(s_symbol))
subscript = _indices_to_subscript(determine_indices(s_symbol))
name = R"\rho^\mathrm{CM}" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand Down Expand Up @@ -245,7 +243,7 @@ def evaluate(self) -> sp.Expr:
def _latex_repr_(self, printer: LatexPrinter, *args) -> str:
s_symbol = self.args[0]
s_latex = printer._print(s_symbol)
subscript = _indices_to_subscript(_determine_indices(s_symbol))
subscript = _indices_to_subscript(determine_indices(s_symbol))
name = R"\rho^\mathrm{eq}" + subscript if self.name is None else self.name
return Rf"{name}\left({s_latex}\right)"

Expand Down Expand Up @@ -285,33 +283,3 @@ def _indices_to_subscript(indices: Sequence[int]) -> str:
return ""
subscript = ",".join(map(str, indices))
return "_{" + subscript + "}"


def _determine_indices(symbol) -> list[int]:
r"""Extract any indices if available from a `~sympy.core.symbol.Symbol`.
>>> _determine_indices(sp.Symbol("m1"))
[1]
>>> _determine_indices(sp.Symbol("m_a2"))
[2]
>>> _determine_indices(sp.Symbol(R"\alpha_{i2, 5}"))
[2, 5]
>>> _determine_indices(sp.Symbol("m"))
[]
`~sympy.tensor.indexed.Indexed` instances can also be handled:
>>> m_a = sp.IndexedBase("m_a")
>>> _determine_indices(m_a[0])
[0]
"""
_, _, subscripts = split_super_sub(sp.latex(symbol))
if not subscripts:
return []
subscript: str = subscripts[-1]
subscript = re.sub(r"[^0-9^\,]", "", subscript)
subscript = f"[{subscript}]"
try:
indices = eval(subscript) # noqa: PGH001, S307
except SyntaxError:
return []
return list(indices)
22 changes: 11 additions & 11 deletions src/ampform/helicity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@
TwoBodyKinematicVariableSet,
create_non_dynamic,
)
from ampform.helicity.decay import (
TwoBodyDecay,
get_parent_id,
get_prefactor,
get_sibling_state_id,
group_by_spin_projection,
group_by_topology,
is_opposite_helicity_state,
)
from ampform.helicity.naming import (
CanonicalAmplitudeNameGenerator,
HelicityAmplitudeNameGenerator,
Expand All @@ -53,19 +62,10 @@
get_topology_identifier,
natural_sorting,
)
from ampform.kinematics import HelicityAdapter, get_invariant_mass_symbol
from ampform.kinematics import HelicityAdapter
from ampform.kinematics.lorentz import get_invariant_mass_symbol
from ampform.sympy import PoolSum

from .decay import (
TwoBodyDecay,
get_parent_id,
get_prefactor,
get_sibling_state_id,
group_by_spin_projection,
group_by_topology,
is_opposite_helicity_state,
)

if sys.version_info >= (3, 8):
from functools import singledispatchmethod
from typing import Literal
Expand Down
Loading

0 comments on commit 8b45539

Please sign in to comment.