Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"allowCompoundWords": true,
"allowCompoundWords": false,
"enableFiletypes": [
"git-commit",
"github-actions-workflow",
Expand Down Expand Up @@ -43,15 +43,19 @@
"allclose",
"ampform",
"arange",
"argnames",
"argvalues",
"aslatex",
"asmermaid",
"atfi",
"automethod",
"autoupdate",
"axhline",
"axvline",
"bdist",
"bgcolor",
"cano",
"caplog",
"capsys",
"celltoolbar",
"classmethod",
Expand All @@ -72,14 +76,17 @@
"dphi",
"dtype",
"eqnarray",
"errordef",
"eval",
"evalf",
"figsize",
"filterwarnings",
"fmin",
"fontsize",
"forceobj",
"fval",
"genindex",
"getfixturevalue",
"getsource",
"gridspec",
"heli",
Expand All @@ -88,6 +95,7 @@
"iloc",
"imag",
"iminuit",
"indentless",
"indeterministic",
"ioff",
"ipykernel",
Expand All @@ -109,10 +117,14 @@
"logdir",
"macos",
"mathbf",
"mathcal",
"mathrm",
"maxdepth",
"maxval",
"meshgrid",
"migrad",
"mimetype",
"minval",
"modindex",
"mprime",
"nbconvert",
Expand All @@ -129,17 +141,20 @@
"noreply",
"nrows",
"numba",
"numpycode",
"outfile",
"pandoc",
"pcolormesh",
"phasespace",
"phsp",
"poethepoet",
"prange",
"precommit",
"prefactor",
"prek",
"preorder",
"prereleased",
"printmethod",
"pwa's",
"py's",
"pygments",
Expand All @@ -149,13 +164,16 @@
"pytestconfig",
"qrules",
"rightarrow",
"rowdict",
"rtfd",
"rtol",
"scimath",
"scipy",
"sdist",
"seealso",
"sharex",
"sharey",
"sphinxcontrib",
"startswith",
"staticmethod",
"subsys",
Expand All @@ -167,6 +185,7 @@
"unflattened",
"unnormalized",
"unsubscriptable",
"usefixtures",
"vstack",
"waves's",
"wspace",
Expand Down
17 changes: 5 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,11 @@
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty)

TensorWaves is a fitter package that optimizes mathematical models to data samples. The
models can be any _symbolic_ mathematical expression that is then converted to any
computational backend. In addition, TensorWaves provides functionality to generate toy
Monte Carlo data samples. The package is developed in parallel with
[AmpForm](https://github.com/ComPWA/ampform), which implements physics models, but its
'lambdifying' mechanisms can in principle be used independently.

All documentation can be found on
[tensorwaves.rtfd.io](https://tensorwaves.readthedocs.io).

For an overview of **upcoming releases and planned functionality**, see
[here](https://github.com/ComPWA/tensorwaves/milestones?direction=asc&sort=title&state=open).
TensorWaves is a fitter package that optimizes mathematical models to data samples. The models can be any _symbolic_ mathematical expression that is then converted to any computational backend. In addition, TensorWaves provides functionality to generate toy Monte Carlo data samples. The package is developed in parallel with [AmpForm](https://github.com/ComPWA/ampform), which implements physics models, but its 'lambdifying' mechanisms can in principle be used independently.

All documentation can be found on [tensorwaves.rtfd.io](https://tensorwaves.readthedocs.io).

For an overview of **upcoming releases and planned functionality**, see [here](https://github.com/ComPWA/tensorwaves/milestones?direction=asc&sort=title&state=open).

## Contribute

Expand Down
28 changes: 14 additions & 14 deletions docs/amplitude-analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Optionally, we can backup the {class}`~ampform.helicity.HelicityModel` to disk via {mod}`pickle`. The {class}`~qrules.transition.ReactionInfo` object (which takes longest to generate) can also be pickled, or it can also be serialized to JSON:"
"Optionally, we can back up the {class}`~ampform.helicity.HelicityModel` to disk via {mod}`pickle`. The {class}`~qrules.transition.ReactionInfo` object (which takes longest to generate) can also be pickled, or it can also be serialized to JSON:"
]
},
{
Expand Down Expand Up @@ -422,7 +422,7 @@
":::\n",
"\n",
":::{warning}\n",
"When using the helicity formalism, the sum of the four-momenta should be in the rest frame, that is $\\sum_i p_i = \\left(m_A, 0, 0, 0\\right)$ with $m_A$ the mass of the decaying particle&nbsp;$A$. This is because the helicity formalisms boosts through the decay chain starting from particle&nbsp;$A$. **Take care to boost your experimental data into the rest frame**, optionally following the {doc}`kinematics classes provided by AmpForm <ampform:kinematics>`.\n",
"When using the helicity formalism, the sum of the four-momenta should be in the rest frame, that is $\\sum_i p_i = \\left(m_A, 0, 0, 0\\right)$ with $m_A$ the mass of the decaying particle&nbsp;$A$. This is because the helicity formalism boosts through the decay chain starting from particle&nbsp;$A$. **Take care to boost your experimental data into the rest frame**, optionally following the {doc}`kinematics classes provided by AmpForm <ampform:kinematics>`.\n",
":::"
]
},
Expand Down Expand Up @@ -624,7 +624,7 @@
"Check the remark about four-momentum format and rest frame of the decaying particle [here](compwa-step-2.1).\n",
"::::\n",
"\n",
"The {obj}`.DataSample` is a mapping of kinematic variables names to a 1-dimensional array of values. The numbers you see here are final state IDs as defined in the {class}`~ampform.helicity.HelicityModel` member of the {class}`~ampform.helicity.HelicityModel`:"
"The {obj}`.DataSample` is a mapping of kinematic variable names to a 1-dimensional array of values. The numbers you see here are final state IDs as defined in the {class}`~ampform.helicity.HelicityModel` member of the {class}`~ampform.helicity.HelicityModel`:"
]
},
{
Expand Down Expand Up @@ -817,7 +817,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"In principle, we can use the same {class}`.ParametrizedFunction` as the one that we created in [](compwa-step-2.2). However, when fitting such a function to a data distribution, an {class}`.Optimizer` will evaluate this function numerous times, so it is smart to apply some optimizations to the underlying expression tree before-hand.\n",
"In principle, we can use the same {class}`.ParametrizedFunction` as the one that we created in [](compwa-step-2.2). However, when fitting such a function to a data distribution, an {class}`.Optimizer` will evaluate this function numerous times, so it is smart to apply some optimizations to the underlying expression tree beforehand.\n",
"\n",
":::{tip}\n",
"\n",
Expand Down Expand Up @@ -1028,7 +1028,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Since the final state particles $\\gamma, \\pi^0, \\pi^0$ are **stable**, we can substitute their invariant masses $m_0, m_1, m_2$ with scalar values. SymPy will then further simply the expression, so that the computation is less complex."
"Since the final state particles $\\gamma, \\pi^0, \\pi^0$ are **stable**, we can substitute their invariant masses $m_0, m_1, m_2$ with scalar values. SymPy will then further simplify the expression, so that the computation is less complex."
]
},
{
Expand Down Expand Up @@ -1074,7 +1074,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that some of the computed kinematic variable arrays are complex-valued. This can be useful in come cases, but in this decay channel, all kinematic variable values lie on the real axis. The fit can therefore be further optimized by casting the data arrays to real values:"
"Note that some of the computed kinematic variable arrays are complex-valued. This can be useful in some cases, but in this decay channel, all kinematic variable values lie on the real axis. The fit can therefore be further optimized by casting the data arrays to real values:"
]
},
{
Expand Down Expand Up @@ -1236,7 +1236,7 @@
"\n",
"As noted under [](compwa-step-3.1), most of what is described in this section can be achieved with the function {func}`.create_cached_function`. The idea is described on {doc}`/usage/caching`, but in this section, we show how this translates to amplitude analysis.\n",
"\n",
"First, note that {func}`.create_cached_function` works with mappings and iterable of {class}`sympy.Symbol <sympy.core.symbol.Symbol>` and not with the {obj}`str` mappings that we defined in [](#determine-free-parameters). We can convert the parameter names back to {class}`~sympy.core.symbol.Symbol`s as follows:"
"First, note that {func}`.create_cached_function` works with mappings and iterables of {class}`sympy.Symbol <sympy.core.symbol.Symbol>` and not with the {obj}`str` mappings that we defined in [](#determine-free-parameters). We can convert the parameter names back to {class}`~sympy.core.symbol.Symbol`s as follows:"
]
},
{
Expand Down Expand Up @@ -1354,7 +1354,7 @@
"source": [
"To perform a fit, you need to define an {class}`.Estimator`. This is a measure for the discrepancy between the {class}`.ParametrizedFunction` and the data distribution to which you fit it. In PWA, we usually use an **unbinned negative log likelihood estimator** ({class}`.UnbinnedNLL`).\n",
"\n",
"Generally, the {class}`.ParametrizedFunction` is not normalized with regards to the data sample, while a log likelihood estimator requires a normalized function. This is where the [phase space data](compwa-step-2.1) comes into play again: the {class}`.ParametrizedFunction` is evaluated over the phase space data, so that its output can be used as a normalization factor.\n",
"Generally, the {class}`.ParametrizedFunction` is not normalized with regard to the data sample, while a log likelihood estimator requires a normalized function. This is where the [phase space data](compwa-step-2.1) comes into play again: the {class}`.ParametrizedFunction` is evaluated over the phase space data, so that its output can be used as a normalization factor.\n",
"\n",
"```{margin}\n",
"If you want to correct for the efficiency of the detector, you should use a *detector-reconstructed* phase space sample.\n",
Expand Down Expand Up @@ -1487,7 +1487,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we are ready to create an {class}`.Optimizer` that can {meth}`~.Minuit2.optimize` the parameters in the {class}`.ParametrizedFunction` (which is embedded in the {class}`.Estimator`). Here, we choose the {class}`.Minuit2` optimizer, which is the most common optimizer in high-energy physics (see also {ref}`usage/basics:Perform fit with different optimizers`). Since we constructed the {class}`.UnbinnedNLL` with {obj}`jax <jax.jit>`, can an optimize the model with analytic gradient over the {class}`.ParametrizedBackendFunction`:\n",
"Finally, we are ready to create an {class}`.Optimizer` that can {meth}`~.Minuit2.optimize` the parameters in the {class}`.ParametrizedFunction` (which is embedded in the {class}`.Estimator`). Here, we choose the {class}`.Minuit2` optimizer, which is the most common optimizer in high-energy physics (see also {ref}`usage/basics:Perform fit with different optimizers`). Since we constructed the {class}`.UnbinnedNLL` with {obj}`jax <jax.jit>`, we can optimize the model with an analytic gradient over the {class}`.ParametrizedBackendFunction`:\n",
"\n",
":::{note}\n",
"\n",
Expand Down Expand Up @@ -1582,7 +1582,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"In [](compwa-step-3.3), we initialized {obj}`.Minuit2` with a {class}`.Loadable` callback. Such callback classes offer the possibility to {meth}`~.Loadable.load_latest_parameters`, so you can pick up the optimize process in case it crashes or if you pause it. Loading the latest parameters goes as follows:"
"In [](compwa-step-3.3), we initialized {obj}`.Minuit2` with a {class}`.Loadable` callback. Such callback classes offer the possibility to {meth}`~.Loadable.load_latest_parameters`, so you can pick up the optimization process in case it crashes or if you pause it. Loading the latest parameters goes as follows:"
]
},
{
Expand Down Expand Up @@ -1652,7 +1652,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Each of the {mod}`.optimizer`s offer more specific information about the fit result. This information can be accessed with {attr}`.FitResult.specifics`. A common example would be to get the {attr}`~iminuit.Minuit.covariance` matrix and {attr}`~iminuit.util.Matrix.correlation` matrix:"
"Each of the {mod}`.optimizer`s offers more specific information about the fit result. This information can be accessed with {attr}`.FitResult.specifics`. A common example would be to get the {attr}`~iminuit.Minuit.covariance` matrix and {attr}`~iminuit.util.Matrix.correlation` matrix:"
]
},
{
Expand Down Expand Up @@ -1736,7 +1736,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"As we have seen [when formulating the amplitude model](#build-amplitude-model), the helicity model is built up of an incoherent sum of real-valued intensities (one for each spin combination), which are each built up of a coherent sum of complex-valued amplitudes (one for each resonance). If we want to compute what each of these amplitudes contribute to the main intensity, we should use the optimized intensity and set coefficients or helicity couplings of amplitudes that were are not interested in to zero."
"As we have seen [when formulating the amplitude model](#build-amplitude-model), the helicity model is built up of an incoherent sum of real-valued intensities (one for each spin combination), which are each built up of a coherent sum of complex-valued amplitudes (one for each resonance). If we want to compute what each of these amplitudes contributes to the main intensity, we should use the optimized intensity and set coefficients or helicity couplings of amplitudes that we are not interested in to zero."
]
},
{
Expand Down Expand Up @@ -1868,7 +1868,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also use these functions to compute the decay rates for each resonance. Notice how the sum of the decay rates does not add up to a 100%. This is because of the strong constructive interference between the resonances in this model."
"We can also use these functions to compute the decay rates for each resonance. Notice how the sum of the decay rates does not add up to 100%. This is because of the strong constructive interference between the resonances in this model."
]
},
{
Expand Down Expand Up @@ -1919,7 +1919,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.15"
"version": "3.13.16"
}
},
"nbformat": 4,
Expand Down
8 changes: 4 additions & 4 deletions docs/amplitude-analysis/analytic-continuation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Of the two resonances, $a_0(980)$ lies just below threshold ― it's mass is smaller than the the masses of the two decay products combined:"
"Of the two resonances, $a_0(980)$ lies just below threshold ― its mass is smaller than the masses of the two decay products combined:"
]
},
{
Expand Down Expand Up @@ -107,7 +107,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"To correctly describe the dynamics for this resonance, we should use make use of {doc}`analytic continuation <ampform:analyticity>`. As opposed to {ref}`compwa-step-1`, we now construct a {class}`~ampform.dynamics.builder.RelativisticBreitWignerBuilder` where we set its phase space factor to {class}`~ampform.dynamics.phasespace.PhaseSpaceFactorSWave`:"
"To correctly describe the dynamics for this resonance, we should make use of {doc}`analytic continuation <ampform:analyticity>`. As opposed to {ref}`compwa-step-1`, we now construct a {class}`~ampform.dynamics.builder.RelativisticBreitWignerBuilder` where we set its phase space factor to {class}`~ampform.dynamics.phasespace.PhaseSpaceFactorSWave`:"
]
},
{
Expand Down Expand Up @@ -141,7 +141,7 @@
"source": [
":::{margin}\n",
"\n",
"Note that we have reduced the coupling for the sub-threshold resonance $a_0(980)^0$, so that it doesn't dominate over $a_2(1320)^0$ resonance.\n",
"Note that we have reduced the coupling for the sub-threshold resonance $a_0(980)^0$, so that it doesn't dominate over the $a_2(1320)^0$ resonance.\n",
"\n",
":::\n",
"\n",
Expand Down Expand Up @@ -232,7 +232,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.15"
"version": "3.13.16"
}
},
"nbformat": 4,
Expand Down
11 changes: 3 additions & 8 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,9 @@ TensorWaves originates from [`pycompwa`](https://github.com/ComPWA/pycompwa), wh

:::

TensorWaves is an optimizer package that can 'fit' mathematical models (expressed with
{mod}`sympy`) to data distributions using a variety of computational back-ends,
optimizers, and estimator functions. In addition, the {mod}`tensorwaves.data` module
helps one to generate data distributions for those mathematical expressions.

The package is developed in parallel with {doc}`AmpForm <ampform:index>`, which
implements physics models for amplitude analysis, but its mechanisms for creating
computational backend functions can in principle be used independently.
TensorWaves is an optimizer package that can 'fit' mathematical models (expressed with {mod}`sympy`) to data distributions using a variety of computational back-ends, optimizers, and estimator functions. In addition, the {mod}`tensorwaves.data` module helps one to generate data distributions for those mathematical expressions.

The package is developed in parallel with {doc}`AmpForm <ampform:index>`, which implements physics models for amplitude analysis, but its mechanisms for creating computational backend functions can in principle be used independently.

<!-- prettier-ignore -->
::::{grid} 1 2 2 2
Expand Down
Loading
Loading