From 7f3a794bebd33e9fce3d93cde4054516c96a8345 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Tue, 31 May 2022 10:20:32 +0200 Subject: [PATCH] refactor: deactivate default spin alignment (#295) `HelicityModelBuilder.align_spin` needs to be set explicitly to activate spin alignment for multiple topologies. --- docs/usage/helicity/spin-alignment.ipynb | 22 +++++++++++++++++++--- src/ampform/helicity/__init__.py | 14 +++----------- src/ampform/helicity/decay.py | 7 ------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/docs/usage/helicity/spin-alignment.ipynb b/docs/usage/helicity/spin-alignment.ipynb index 399c8d9fb..0bc6b3bcd 100644 --- a/docs/usage/helicity/spin-alignment.ipynb +++ b/docs/usage/helicity/spin-alignment.ipynb @@ -98,7 +98,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As described in {doc}`compwa-org:report/015`, the {doc}`'standard' helicity formalism ` is not suited for state transitions that have different decay topologies. For this reason, the {class}`.HelicityAmplitudeBuilder` insert a number of Wigner-$D$ function into the amplitude model in case there is more than one underlying {class}`~qrules.topology.Topology`. It is easiest to see this by inspecting the resulting {attr}`.HelicityModel.intensity` and its {attr}`~.HelicityModel.amplitudes`:" + "As described in {doc}`compwa-org:report/015`, the {doc}`'standard' helicity formalism ` is not suited for state transitions that have different decay topologies. For this reason, the {class}`.HelicityAmplitudeBuilder` can insert a number of Wigner-$D$ function into the amplitude model in case there is more than one underlying {class}`~qrules.topology.Topology`. It is easiest to see this by inspecting the resulting {attr}`.HelicityModel.intensity` and its {attr}`~.HelicityModel.amplitudes`:" ] }, { @@ -135,6 +135,13 @@ "graphviz.Source(dot)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "'Spin alignment' can be now switched off or on by setting {attr}`.HelicityAmplitudeBuilder.align_spin`:" + ] + }, { "cell_type": "code", "execution_count": null, @@ -146,6 +153,7 @@ "outputs": [], "source": [ "builder = ampform.get_builder(reaction)\n", + "builder.align_spin = True\n", "model = builder.formulate()\n", "model.intensity" ] @@ -195,7 +203,7 @@ "source": [ "For more information about these angles, see {ref}`compwa-org:report/015:Compute Wigner rotation angles` in TR-015.\n", "\n", - "Spin alignment can be switched off or on by setting {attr}`.HelicityAmplitudeBuilder.align_spin`:" + "By default, {attr}`~.HelicityAmplitudeBuilder.align_spin` is set to {obj}`False` and the total {attr}`.HelicityModel.intensity` does not contain alignment Wigner-$D$ functions:" ] }, { @@ -219,8 +227,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.8.12" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" } }, "nbformat": 4, diff --git a/src/ampform/helicity/__init__.py b/src/ampform/helicity/__init__.py index 4b2115744..a8f362cde 100644 --- a/src/ampform/helicity/__init__.py +++ b/src/ampform/helicity/__init__.py @@ -52,7 +52,6 @@ from .decay import ( TwoBodyDecay, - collect_topologies, get_parent_id, get_prefactor, get_sibling_state_id, @@ -518,7 +517,7 @@ def __init__( self.__ingredients = _HelicityModelIngredients() self.__dynamics_choices = DynamicsSelector(reaction) self.__adapter = HelicityAdapter(reaction) - self.align_spin: bool | None = None + self.align_spin: bool = False """(De)activate :doc:`spin alignment `.""" self.use_helicity_couplings: bool = False """Use helicity couplings instead of amplitude coefficients. @@ -587,7 +586,7 @@ def formulate(self) -> HelicityModel: self.__ingredients.reset() main_intensity = self.__formulate_top_expression() kinematic_variables = self.__adapter.create_expressions( - generate_wigner_angles=self.__is_align_spin + generate_wigner_angles=self.align_spin ) if self.stable_final_state_ids is not None: for state_id in self.stable_final_state_ids: @@ -628,7 +627,7 @@ def __formulate_top_expression(self) -> PoolSum: spin_projections[symbol].add(value) topology_groups = group_by_topology(self.__reaction.transitions) - if self.__is_align_spin: + if self.align_spin: amplitude = self.__formulate_aligned_amplitude(topology_groups) else: indices = list(spin_projections) @@ -659,13 +658,6 @@ def __formulate_aligned_amplitude( ) return amplitude - @property - def __is_align_spin(self) -> bool: - if self.align_spin is None: - topologies = collect_topologies(self.__reaction.transitions) - return len(topologies) > 1 - return self.align_spin - def __register_amplitudes( self, transition_group: list[StateTransition] ) -> None: diff --git a/src/ampform/helicity/decay.py b/src/ampform/helicity/decay.py index 84591b7f4..d580672fa 100644 --- a/src/ampform/helicity/decay.py +++ b/src/ampform/helicity/decay.py @@ -147,13 +147,6 @@ def is_opposite_helicity_state(topology: Topology, state_id: int) -> bool: return tuple(state_fs_ids) > tuple(sibling_fs_ids) -@lru_cache(maxsize=None) -def collect_topologies( - transitions: tuple[StateTransition, ...] -) -> list[Topology]: - return sorted({t.topology for t in transitions}) - - def get_sibling_state_id(topology: Topology, state_id: int) -> int: r"""Get the sibling state ID for a state in an isobar decay.