diff --git a/docs/usage.ipynb b/docs/usage.ipynb index 3278bd42e..3d65ee2cd 100644 --- a/docs/usage.ipynb +++ b/docs/usage.ipynb @@ -60,7 +60,6 @@ "import graphviz\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", - "from expertsystem.amplitude.dynamics import set_resonance_dynamics\n", "from expertsystem.amplitude.dynamics.builder import (\n", " create_relativistic_breit_wigner_with_ff,\n", ")\n", @@ -100,20 +99,10 @@ "metadata": {}, "outputs": [], "source": [ - "model = es.generate_amplitudes(result)\n", - "model.expression.top" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ + "model_builder = es.amplitude.get_builder(result)\n", "for name in result.get_intermediate_particles().names:\n", - " set_resonance_dynamics(\n", - " model, name, create_relativistic_breit_wigner_with_ff\n", - " )" + " model_builder.set_dynamics(name, create_relativistic_breit_wigner_with_ff)\n", + "model = model_builder.generate()" ] }, { @@ -126,7 +115,7 @@ }, "outputs": [], "source": [ - "display(*model.expression.dynamics)" + "next(iter(model.components.values())).doit()" ] }, { @@ -139,16 +128,7 @@ }, "outputs": [], "source": [ - "display(*sorted(model.parameters, key=lambda s: s.name))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(model.expression.dynamics.values())[1]" + "sorted(model.parameters, key=lambda s: s.name)" ] }, { @@ -176,7 +156,7 @@ "outputs": [], "source": [ "sympy_model = SympyModel(\n", - " expression=model.expression.full_expression,\n", + " expression=model.expression,\n", " parameters={k: v.value for k, v in model.parameters.items()},\n", " variables={},\n", ")\n", @@ -199,20 +179,7 @@ "metadata": {}, "outputs": [], "source": [ - "kin = HelicityKinematics(\n", - " ParticleReactionKinematicsInfo(\n", - " initial_state_names=[\n", - " x.name for x in model.kinematics.initial_state.values()\n", - " ],\n", - " final_state_names=[\n", - " x.name for x in model.kinematics.final_state.values()\n", - " ],\n", - " particles=model.particles,\n", - " fs_id_event_pos_mapping=dict(\n", - " {k: i for i, k in enumerate(model.kinematics.final_state.keys())}\n", - " ),\n", - " )\n", - ")\n", + "kin = HelicityKinematics.from_model(model)\n", "kin.register_subsystem(SubSystem([[3, 4], [2]], [], []))\n", "kin.register_subsystem(SubSystem([[3], [4]], [2], []))\n", "kin.register_invariant_mass([2, 4]);" @@ -289,7 +256,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Optimize the amplitude model" + "## Optimize the amplitude model" ] }, { diff --git a/docs/usage/1_create_model.ipynb b/docs/usage/1_create_model.ipynb index fd902827f..84cf27cf5 100644 --- a/docs/usage/1_create_model.ipynb +++ b/docs/usage/1_create_model.ipynb @@ -31,7 +31,7 @@ "---\n", "class: dropdown\n", "---\n", - "As {doc}`3_perform_fit` serves to illustrate usage only, we make the amplitude model here a bit simpler by not allowing $\\omega$ resonances (which are narrow and therefore hard to fit). For this reason, we can also limit the {class}`~expertsystem.reaction.default_settings.InteractionTypes` to {attr}`~expertsystem.reaction.default_settings.InteractionTypes.Strong`.\n", + "As {doc}`3_perform_fit` serves to illustrate usage only, we make the amplitude model here a bit simpler by not allowing $\\omega$ resonances (which are narrow and therefore hard to fit). For this reason, we can also limit the {class}`~expertsystem.reaction.default_settings.InteractionTypes` to {attr}`~expertsystem.reaction.default_settings.InteractionTypes.STRONG`.\n", "```" ] }, @@ -75,7 +75,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Next we convert the {attr}`~expertsystem.reaction.Result.transitions` into an {class}`~expertsystem.amplitude.helicity.HelicityModel`. This can be done with the {func}`~expertsystem.generate_amplitudes` method." + "Next we convert the {attr}`~expertsystem.reaction.Result.transitions` into an {class}`~expertsystem.amplitude.helicity.HelicityModel`. This can be done with `expertsystem.amplitude.get_builder` and `~expertsystem.amplitude.SympyHelicityAmplitudeGenerator.generate`." ] }, { @@ -84,7 +84,8 @@ "metadata": {}, "outputs": [], "source": [ - "model = es.generate_amplitudes(result)\n", + "model_builder = es.amplitude.get_builder(result)\n", + "model = model_builder.generate()\n", "list(model.parameters)" ] }, @@ -96,7 +97,7 @@ "1. The coefficients for the different amplitudes are **complex** valued.\n", "2. By default there is no dynamics in the model and it still has to be specified.\n", "\n", - "We choose to use {func}`~expertsystem.amplitude.dynamics.lineshape.relativistic_breit_wigner_with_ff` for all resonances. The {func}`~expertsystem.amplitude.dynamics.set_resonance_dynamics` is an convenience interface for replacing the dynamics for intermediate states." + "We choose to use {func}`~expertsystem.amplitude.dynamics.lineshape.relativistic_breit_wigner_with_ff` for all resonances. The {meth}`~expertsystem.amplitude.helicity.SympyHelicityAmplitudeGenerator.set_dynamics` is a convenience interface for replacing the dynamics for intermediate states." ] }, { @@ -105,15 +106,13 @@ "metadata": {}, "outputs": [], "source": [ - "from expertsystem.amplitude.dynamics import set_resonance_dynamics\n", "from expertsystem.amplitude.dynamics.builder import (\n", " create_relativistic_breit_wigner_with_ff,\n", ")\n", "\n", "for name in result.get_intermediate_particles().names:\n", - " set_resonance_dynamics(\n", - " model, name, create_relativistic_breit_wigner_with_ff\n", - " )" + " model_builder.set_dynamics(name, create_relativistic_breit_wigner_with_ff)\n", + "model = model_builder.generate()" ] }, { @@ -129,7 +128,7 @@ "metadata": {}, "outputs": [], "source": [ - "list(model.parameters)" + "sorted(model.parameters, key=lambda s: s.name)" ] }, { diff --git a/src/tensorwaves/physics/amplitude.py b/src/tensorwaves/physics/amplitude.py index 8aec5d5dd..2307a4aa4 100644 --- a/src/tensorwaves/physics/amplitude.py +++ b/src/tensorwaves/physics/amplitude.py @@ -91,8 +91,7 @@ class Intensity(Function): evaluation backends available. Args: - model: A `~expertsystem.amplitude.helicity.SympyModel` instance - created via the `expertsystem`. + model: A `.SympyModel` instance. backend: A string, tuple or mapping passed to the `~sympy.utilities.lambdify.lambdify` call as the :code:`modules` argument. diff --git a/src/tensorwaves/physics/helicity_formalism/kinematics.py b/src/tensorwaves/physics/helicity_formalism/kinematics.py index 25115472a..71f94a620 100644 --- a/src/tensorwaves/physics/helicity_formalism/kinematics.py +++ b/src/tensorwaves/physics/helicity_formalism/kinematics.py @@ -17,6 +17,7 @@ import amplitf.kinematics as tfa_kin import numpy as np +from expertsystem.amplitude.helicity import HelicityModel from expertsystem.particle import ParticleCollection from tensorwaves.interfaces import Kinematics @@ -73,13 +74,33 @@ def __init__( self._fs_id_event_pos_mapping = fs_id_event_pos_mapping + @staticmethod + def from_model( + model: HelicityModel, + ) -> "ParticleReactionKinematicsInfo": + return ParticleReactionKinematicsInfo( + initial_state_names=[ + p.name for p in model.kinematics.initial_state.values() + ], + final_state_names=[ + p.name for p in model.kinematics.final_state.values() + ], + particles=model.particles, + fs_id_event_pos_mapping=dict( + zip( + model.kinematics.final_state, + range(len(model.kinematics.final_state)), + ) + ), + ) + @property - def initial_state_masses(self) -> List[float]: - return [p.mass for p in self._initial_state_particles] + def initial_state_masses(self) -> Tuple[float, ...]: + return tuple(p.mass for p in self._initial_state_particles) @property - def final_state_masses(self) -> List[float]: - return [p.mass for p in self._final_state_particles] + def final_state_masses(self) -> Tuple[float, ...]: + return tuple(p.mass for p in self._final_state_particles) @property def total_invariant_mass(self) -> float: @@ -182,6 +203,11 @@ def __init__(self, reaction_info: ParticleReactionKinematicsInfo): self._registered_inv_masses: Dict[Tuple, str] = dict() self._registered_subsystems: Dict[SubSystem, Tuple[str, str]] = dict() + @staticmethod + def from_model(model: HelicityModel) -> "HelicityKinematics": + reaction_info = ParticleReactionKinematicsInfo.from_model(model) + return HelicityKinematics(reaction_info) + @property def reaction_kinematics_info(self) -> ParticleReactionKinematicsInfo: return self._reaction_info diff --git a/tests/conftest.py b/tests/conftest.py index dabc5d78b..b7131dfbe 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,6 @@ import expertsystem as es import numpy as np import pytest -from expertsystem.amplitude.dynamics import set_resonance_dynamics from expertsystem.amplitude.dynamics.builder import ( create_relativistic_breit_wigner_with_ff, ) @@ -153,13 +152,14 @@ def __create_model(formalism: str) -> SympyModel: allowed_interaction_types=["EM", "strong"], number_of_threads=1, ) - model = es.generate_amplitudes(result) + model_builder = es.amplitude.get_builder(result) for name in result.get_intermediate_particles().names: - set_resonance_dynamics( - model, name, create_relativistic_breit_wigner_with_ff + model_builder.set_dynamics( + name, create_relativistic_breit_wigner_with_ff ) + model = model_builder.generate() return SympyModel( - expression=model.expression.full_expression, + expression=model.expression, parameters={ k: v.value if isinstance(v, ParameterProperties) else v for k, v in model.parameters.items()