From 6e0909f31983c5b3686cf743b0d9b7672abdf32d Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Sat, 8 Jul 2023 22:35:09 +0200 Subject: [PATCH] DOC: illustrate use of `interaction_determinators` (#226) * DOC: add intermediate headings * DX: switch to implicit MyST targets Looks better on JupyterLab-MyST and is easier to write: https://myst-parser.readthedocs.io/en/v2.0.0/syntax/cross-referencing.html#implicit-targets * FEAT: make `system_control` public * MAINT: update notebook kernel --- docs/conf.py | 11 ++-- docs/usage/reaction.ipynb | 57 +++++++++++++++++-- .../{_system_control.py => system_control.py} | 12 ++-- src/qrules/transition.py | 26 +++++---- tests/unit/test_system_control.py | 12 ++-- 5 files changed, 84 insertions(+), 34 deletions(-) rename src/qrules/{_system_control.py => system_control.py} (96%) diff --git a/docs/conf.py b/docs/conf.py index 291d773b..f2386b8f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -363,16 +363,15 @@ def get_version(package_name: str) -> str: "smartquotes", "substitution", ] -BINDER_LINK = ( - f"https://mybinder.org/v2/gh/ComPWA/{REPO_NAME}/{BRANCH}?filepath=docs/usage" -) +myst_heading_anchors = 2 myst_substitutions = { "branch": BRANCH, "run_interactive": f""" ```{{margin}} -Run this notebook [on Binder]({BINDER_LINK}) or -{{ref}}`locally on Jupyter Lab ` to interactively -modify the parameters. +Run this notebook +[on Binder](https://mybinder.org/v2/gh/ComPWA/{REPO_NAME}/{BRANCH}?filepath=docs/usage) +or {{ref}}`locally on Jupyter Lab ` to +interactively modify the parameters. ``` """, } diff --git a/docs/usage/reaction.ipynb b/docs/usage/reaction.ipynb index 14595247..95fdbdd0 100644 --- a/docs/usage/reaction.ipynb +++ b/docs/usage/reaction.ipynb @@ -113,7 +113,7 @@ "source": [ ":::{margin}\n", "\n", - "How does the {class}`.StateTransitionManager` know what a `\"J/psi(1S)\"` is? Upon construction, the {class}`.StateTransitionManager` loads default definitions from the [PDG](https://pdg.lbl.gov). See {doc}`/usage/particle` for how to add custom particle definitions.\n", + "How does the {class}`.StateTransitionManager` know what a `\"J/psi(1S)\"` is? Upon construction, the {class}`.StateTransitionManager` loads default definitions from the [PDG](https://pdg.lbl.gov). See [](particle.ipynb) for how to add custom particle definitions.\n", "\n", ":::" ] @@ -157,7 +157,7 @@ "\n", ":::{tip}\n", "\n", - "{doc}`custom-topology` shows how to provide custom {class}`.Topology` instances to the STM, so that you generate more than just isobar decays.\n", + "[](custom-topology.ipynb) shows how to provide custom {class}`.Topology` instances to the STM, so that you generate more than just isobar decays.\n", "\n", ":::" ] @@ -210,7 +210,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To get an idea of what these {class}`.ProblemSet`s represent, you can use {func}`.asdot` and {doc}`graphviz:index` to visualize one of them (see {doc}`visualize`):" + "To get an idea of what these {class}`.ProblemSet`s represent, you can use {func}`.asdot` and {doc}`graphviz:index` to visualize one of them (see [](visualize.ipynb)):" ] }, { @@ -315,6 +315,13 @@ "Now we have a lot of solutions that are actually heavily suppressed (they involve two weak decays)." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Select interaction types" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -361,7 +368,40 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Be aware, however, that the {attr}`~.InteractionType.EM` interaction is now available globally, for each node in the decay topology. Hence, there now might be solutions in which both nodes are electromagnetic. This is fine for the decay $J/\\psi \\to \\gamma \\pi^0 \\pi^0$, but for decays that require the {attr}`~.InteractionType.WEAK` interaction type, you want to set the interaction type per **specific nodes**. Take for example the decay $\\Lambda_c^+ \\to p K^- \\pi^+$, which has a production node that is mediated by the weak force and a decay node that goes via the strong force. In this case, only limit the decay node to the {attr}`~.InteractionType.STRONG` force:" + "This automatic selection of conservation rules can be switched of the {attr}`.StateTransitionManager.interaction_determinators`. Here's an example where we deselect the check that causes makes detects the existence of a photon in the decay chain. Note, however, that for $J/\\psi \\to \\gamma\\pi^0\\pi^0$, this results in non-executed node rules:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qrules.system_control import GammaCheck\n", + "\n", + "stm_no_check = StateTransitionManager(\n", + " initial_state=[\"J/psi(1S)\"],\n", + " final_state=[\"gamma\", \"pi0\", \"pi0\"],\n", + ")\n", + "stm_no_check.interaction_determinators = [\n", + " check\n", + " for check in stm_no_check.interaction_determinators\n", + " if not isinstance(check, GammaCheck)\n", + "]\n", + "stm_no_check.set_allowed_interaction_types([InteractionType.STRONG])\n", + "problem_sets_no_check = stm_no_check.create_problem_sets()\n", + "try:\n", + " reaction_no_check = stm_no_check.find_solutions(problem_sets_no_check)\n", + "except RuntimeError as e:\n", + " msg, execution_info = e.args\n", + "execution_info" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Be aware that after calling {meth}`.set_allowed_interaction_types`, the {attr}`~.InteractionType.EM` interaction is now selected for all nodes, for each node in the decay topology. Hence, there now might be solutions in which both nodes are electromagnetic. This is fine for the decay $J/\\psi \\to \\gamma \\pi^0 \\pi^0$, but for decays that require the {attr}`~.InteractionType.WEAK` interaction type, you want to set the interaction type per **specific nodes**. Take for example the decay $\\Lambda_c^+ \\to p K^- \\pi^+$, which has a production node that is mediated by the weak force and a decay node that goes via the strong force. In this case, only limit the decay node to the {attr}`~.InteractionType.STRONG` force:" ] }, { @@ -397,6 +437,13 @@ "graphviz.Source(dot)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Select intermediate particles" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -483,7 +530,7 @@ "source": [ ":::{seealso}\n", "\n", - "{doc}`/usage/visualize`\n", + "[](visualize.ipynb)\n", "\n", ":::" ] diff --git a/src/qrules/_system_control.py b/src/qrules/system_control.py similarity index 96% rename from src/qrules/_system_control.py rename to src/qrules/system_control.py index f9329472..fa47261a 100644 --- a/src/qrules/_system_control.py +++ b/src/qrules/system_control.py @@ -90,7 +90,7 @@ def find_particle( # noqa: D417 Args: edge_props: The quantum number dictionary. particle_db: A `.ParticleCollection` which is used to retrieve a - reference `.particle` to lower the memory footprint. + reference :code:`state` to lower the memory footprint. Raises: KeyError: If the edge properties do not contain the pid information or no @@ -328,13 +328,13 @@ def require_interaction_property( nodes. Args: - ingoing_particle_name (str): name of particle, used to find nodes which - have a particle with this name as "ingoing" + ingoing_particle_name: name of particle, used to find nodes which have a + particle with this name as "ingoing" - interaction_qn ([Type[NodeQuantumNumber]]): interaction quantum number + interaction_qn: interaction quantum number - allowed_values (list): list of allowed values, that the interaction - quantum number may take + allowed_values: list of allowed values, that the interaction quantum number may + take Return: Callable[Any, bool]: diff --git a/src/qrules/transition.py b/src/qrules/transition.py index f33f5fc0..f69fbf3b 100644 --- a/src/qrules/transition.py +++ b/src/qrules/transition.py @@ -34,17 +34,6 @@ from qrules._implementers import implement_pretty_repr -from ._system_control import ( - GammaCheck, - InteractionDeterminator, - LeptonCheck, - create_edge_properties, - create_interaction_properties, - create_node_properties, - filter_interaction_types, - find_particle, - remove_duplicate_solutions, -) from .combinatorics import ( InitialFacts, StateDefinition, @@ -83,6 +72,17 @@ QNProblemSet, QNResult, ) +from .system_control import ( + GammaCheck, + InteractionDeterminator, + LeptonCheck, + create_edge_properties, + create_interaction_properties, + create_node_properties, + filter_interaction_types, + find_particle, + remove_duplicate_solutions, +) from .topology import ( FrozenDict, StateTransitionGraph, @@ -287,6 +287,10 @@ def __init__( # noqa: C901, PLR0912 LeptonCheck(), GammaCheck(), ] + """Checks that are executed over selected conservation rules. + + .. seealso:: {ref}`usage/reaction:Select interaction types` + """ self.final_state_groupings: Optional[List[List[List[str]]]] = None self.__allowed_interaction_types: Union[ List[InteractionType], diff --git a/tests/unit/test_system_control.py b/tests/unit/test_system_control.py index 54f94ae6..439916ad 100644 --- a/tests/unit/test_system_control.py +++ b/tests/unit/test_system_control.py @@ -5,12 +5,6 @@ import pytest from qrules import InteractionType, ProblemSet, StateTransitionManager -from qrules._system_control import ( - create_edge_properties, - filter_graphs, - remove_duplicate_solutions, - require_interaction_property, -) from qrules.combinatorics import ( ParticleWithSpin, _create_edge_id_particle_mapping, @@ -23,6 +17,12 @@ InteractionProperties, NodeQuantumNumbers, ) +from qrules.system_control import ( + create_edge_properties, + filter_graphs, + remove_duplicate_solutions, + require_interaction_property, +) from qrules.topology import Edge, StateTransitionGraph, Topology if sys.version_info < (3, 8):