Skip to content
Draft
55 changes: 41 additions & 14 deletions docs/_extend_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ def extend_BreakupMomentumSquared() -> None:
_append_latex_doit_definition(expr, deep=True)


def extend_BreitWigner() -> None:
from ampform.dynamics import BreitWigner

s, m0, w0, m1, m2, d = sp.symbols("s m0 Gamma0 m1 m2 d", nonnegative=True)
L = sp.Symbol("L", integer=True, nonnegative=True)
expr = BreitWigner(s, m0, w0, m1, m2, angular_momentum=L, meson_radius=d)
_append_latex_doit_definition(expr)


def extend_ComplexSqrt() -> None:
from ampform.sympy.math import ComplexSqrt

Expand Down Expand Up @@ -358,6 +367,30 @@ def extend_is_within_phasespace() -> None:
)


def extend_MultichannelBreitWigner() -> None:
from ampform.dynamics import (
ChannelArguments,
MultichannelBreitWigner,
SimpleBreitWigner,
)

s, m0, w0 = sp.symbols("s m0 Gamma0", nonnegative=True)
channels = [
ChannelArguments(*sp.symbols("Gamma1 m_a1 m_b1 L1 d", nonnegative=True)),
ChannelArguments(*sp.symbols("Gamma2 m_a2 m_b2 L2 d", nonnegative=True)),
]
expr = MultichannelBreitWigner(s, m0, channels=channels)
_append_latex_doit_definition(expr)
bw = SimpleBreitWigner(s, m0, w0)
_append_to_docstring(
MultichannelBreitWigner,
Rf"""
with :math:`{sp.latex(bw)}` defined by Equation :eq:`SimpleBreitWigner`, a
`SimpleBreitWigner`.
""",
)


def extend_PhaseSpaceFactor() -> None:
from ampform.dynamics.phasespace import PhaseSpaceFactor

Expand Down Expand Up @@ -473,6 +506,14 @@ def extend_RotationZMatrix() -> None:
)


def extend_SimpleBreitWigner() -> None:
from ampform.dynamics import SimpleBreitWigner

s, m0, w0 = sp.symbols("s m0 Gamma0", nonnegative=True)
expr = SimpleBreitWigner(s, m0, w0)
_append_latex_doit_definition(expr)


def extend_SphericalHankel1() -> None:
from ampform.dynamics.form_factor import SphericalHankel1

Expand Down Expand Up @@ -604,20 +645,6 @@ def extend_get_boost_chain_suffix() -> None:
)


def extend_relativistic_breit_wigner() -> None:
from ampform.dynamics import relativistic_breit_wigner

s, m0, w0 = sp.symbols("s m0 Gamma0")
rel_bw = relativistic_breit_wigner(s, m0, w0)
_append_to_docstring(
relativistic_breit_wigner,
f"""
.. math:: {sp.latex(rel_bw)}
:label: relativistic_breit_wigner
""",
)


def extend_relativistic_breit_wigner_with_ff() -> None:
from ampform.dynamics import relativistic_breit_wigner_with_ff

Expand Down
6 changes: 4 additions & 2 deletions docs/usage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,12 @@
"source": [
"import sympy as sp\n",
"\n",
"from ampform.dynamics import relativistic_breit_wigner\n",
"from ampform.dynamics import SimpleBreitWigner\n",
"from ampform.io import aslatex\n",
"\n",
"m, m0, w0 = sp.symbols(\"m m0 Gamma0\")\n",
"relativistic_breit_wigner(s=m**2, mass0=m0, gamma0=w0)"
"bw = SimpleBreitWigner(s=m**2, mass=m0, width=w0)\n",
"Math(aslatex({bw: bw.doit(deep=False)}))"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/amplitude.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@
"source": [
"To set dynamics for specific resonances, use {meth}`.DynamicsSelector.assign` on the same {attr}`.HelicityAmplitudeBuilder.dynamics` attribute. You can set the dynamics to be any kind of {class}`~sympy.core.expr.Expr`, as long as you keep track of which {class}`~sympy.core.symbol.Symbol` names you use (see {doc}`/usage/dynamics/custom`).\n",
"\n",
"AmpForm does provide a few common {mod}`.dynamics` functions, which can be constructed as {class}`~sympy.core.expr.Expr` with the correct {class}`~sympy.core.symbol.Symbol` names using {meth}`.DynamicsSelector.assign`. This function takes specific {mod}`.dynamics.builder` functions and classes, such as {class}`.RelativisticBreitWignerBuilder`, which can create {func}`.relativistic_breit_wigner` functions for specific resonances. Here's an example for a relativistic Breit-Wigner _with form factor_ for the intermediate resonances and use a Blatt-Weisskopf barrier factor for the production decay:"
"AmpForm does provide a few common {mod}`.dynamics` functions, which can be constructed as {class}`~sympy.core.expr.Expr` with the correct {class}`~sympy.core.symbol.Symbol` names using {meth}`.DynamicsSelector.assign`. This function takes specific {mod}`.dynamics.builder` functions and classes, such as {class}`.RelativisticBreitWignerBuilder`, which can create {class}`.SimpleBreitWigner` functions for specific resonances. Here's an example for a relativistic Breit-Wigner _with form factor_ for the intermediate resonances and use a Blatt-Weisskopf barrier factor for the production decay:"
]
},
{
Expand Down
172 changes: 154 additions & 18 deletions docs/usage/dynamics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Relativistic Breit-Wigner"
"## Relativistic BreitWigner"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"AmpForm has two types of relativistic Breit-Wigner functions. Both are compared below ― for more info, see the links to the API."
"AmpForm has two types of relativistic BreitWigner functions. Both are compared below ― for more info, see the links to the API."
]
},
{
Expand All @@ -391,7 +391,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The 'normal' {func}`.relativistic_breit_wigner` looks as follows:"
"The {class}`.SimpleBreitWigner` looks as follows:"
]
},
{
Expand All @@ -402,11 +402,11 @@
},
"outputs": [],
"source": [
"from ampform.dynamics import relativistic_breit_wigner\n",
"from ampform.dynamics import SimpleBreitWigner\n",
"\n",
"m, m0, w0 = sp.symbols(\"m, m0, Gamma0\", nonnegative=True)\n",
"rel_bw = relativistic_breit_wigner(s=m**2, mass0=m0, gamma0=w0)\n",
"rel_bw"
"bw = SimpleBreitWigner(m**2, m0, w0)\n",
"Math(aslatex({bw: bw.doit(deep=False)}))"
]
},
{
Expand All @@ -420,7 +420,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The relativistic Breit-Wigner can be adapted slightly, so that its amplitude goes to zero at threshold ($m_0 = m1 + m2$) and that it becomes normalizable. This is done with {ref}`form factors <usage/dynamics:Form factor>` and can be obtained with the function {func}`.relativistic_breit_wigner_with_ff`:"
"The relativistic BreitWigner can be adapted slightly, so that its amplitude goes to zero at threshold, $s = \\left(m_1 + m_2\\right)^2$, and that it becomes normalizable. This is done with {ref}`form factors <usage/dynamics:Form factor>` and can be obtained with the function {func}`.relativistic_breit_wigner_with_ff`:"
]
},
{
Expand All @@ -433,7 +433,7 @@
"source": [
"from ampform.dynamics import PhaseSpaceFactorSWave, relativistic_breit_wigner_with_ff\n",
"\n",
"rel_bw_with_ff = relativistic_breit_wigner_with_ff(\n",
"bw_with_ff = relativistic_breit_wigner_with_ff(\n",
" s=s,\n",
" mass0=m0,\n",
" gamma0=w0,\n",
Expand All @@ -443,7 +443,7 @@
" meson_radius=1,\n",
" phsp_factor=PhaseSpaceFactorSWave,\n",
")\n",
"rel_bw_with_ff"
"bw_with_ff"
]
},
{
Expand All @@ -457,16 +457,12 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": []
},
"outputs": [],
"source": [
"from ampform.dynamics import EnergyDependentWidth\n",
"\n",
"L = sp.Symbol(\"L\", integer=True)\n",
"width = EnergyDependentWidth(\n",
" s=s,\n",
" mass0=m0,\n",
Expand All @@ -476,8 +472,34 @@
" angular_momentum=L,\n",
" meson_radius=1,\n",
" phsp_factor=PhaseSpaceFactorSWave,\n",
")\n",
"Math(aslatex({width: width.evaluate()}))"
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"editable": true,
"jupyter": {
"source_hidden": true
},
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"from ampform.dynamics import BreitWigner\n",
"\n",
"exprs = [\n",
" BreitWigner(s, m0, w0, m1, m2, angular_momentum=L, meson_radius=d),\n",
" SimpleBreitWigner(s, m0, w0),\n",
" width,\n",
"]\n",
"Math(aslatex({e: e.doit(deep=False) for e in exprs}))"
]
},
{
Expand All @@ -490,6 +512,110 @@
{
"cell_type": "markdown",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"### Multi-channel Breit–Wigner"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"from ampform.dynamics import ChannelArguments, MultichannelBreitWigner\n",
"\n",
"channels = [\n",
" ChannelArguments(\n",
" width=sp.Symbol(f\"Gamma{i}\"),\n",
" m1=sp.Symbol(f\"m_{{a,{i}}}\"),\n",
" m2=sp.Symbol(f\"m_{{b,{i}}}\"),\n",
" angular_momentum=sp.Symbol(f\"L{i}\"),\n",
" meson_radius=d,\n",
" )\n",
" for i in [1, 2]\n",
"]\n",
"multi_bw = MultichannelBreitWigner(s, m0, channels)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"editable": true,
"jupyter": {
"source_hidden": true
},
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"exprs = [\n",
" multi_bw,\n",
" SimpleBreitWigner(s, m0, w0),\n",
" EnergyDependentWidth(s, m0, w0, m1, m2, L, d),\n",
"]\n",
"Math(aslatex({e: e.doit(deep=False) for e in exprs}))"
]
},
{
"cell_type": "markdown",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Note that {class}`.MultichannelBreitWigner` simplifies to a Flatté function. This is especially clear for $L=0$:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"editable": true,
"jupyter": {
"source_hidden": true
},
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"channels = [ChannelArguments(sp.Symbol(f\"Gamma{i}\")) for i in [1, 2]]\n",
"expr = MultichannelBreitWigner(s, m0, channels)\n",
"Math(aslatex({expr: expr.doit().simplify()}))"
]
},
{
"cell_type": "markdown",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
Expand All @@ -498,18 +624,28 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"The following shows the effect of {doc}`/usage/dynamics/analytic-continuation` a on relativistic Breit-Wigner:"
"The following shows the effect of {doc}`/usage/dynamics/analytic-continuation` a on relativistic BreitWigner:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"editable": true,
"jupyter": {
"source_hidden": true
},
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-cell",
"remove-output"
Expand Down Expand Up @@ -552,7 +688,7 @@
")\n",
"np_rel_bw = sp.lambdify(\n",
" args=(m, w0, L, d, m0, m1, m2),\n",
" expr=rel_bw.doit(),\n",
" expr=bw.doit(),\n",
")\n",
"\n",
"# Set sliders\n",
Expand Down
Loading