Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improve documentation with plots #142

Merged
merged 2 commits into from
Oct 28, 2020
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
9 changes: 8 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"xml"
],
"flagWords": [
"analyse",
"colour",
"comparision",
"favour",
Expand Down Expand Up @@ -65,6 +66,7 @@
"jsonschema",
"jupyter",
"mathbb",
"matplotlib",
"mypy",
"nishijima",
"numpy",
Expand All @@ -91,6 +93,7 @@
"ignoreWords": [
"amplitf",
"atfi",
"axvline",
"cano",
"celltoolbar",
"codacy",
Expand All @@ -105,12 +108,15 @@
"fval",
"genindex",
"heli",
"histtype",
"iminuit",
"isort",
"jupyterlab",
"keras",
"kernelspec",
"linestyle",
"linkcheck",
"linspace",
"macos",
"markdownlint",
"mathrm",
Expand Down Expand Up @@ -138,6 +144,7 @@
"seealso",
"subsys",
"unnormalized",
"vstack"
"vstack",
"xlabel"
]
}
1 change: 0 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@
nbsphinx_timeout = -1
nbsphinx_execute_arguments = [
"--InlineBackend.figure_formats={'svg', 'pdf'}",
"--InlineBackend.rc={'figure.dpi': 96}",
]

# Settings for myst-parser
Expand Down
1 change: 1 addition & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.json
25 changes: 9 additions & 16 deletions examples/workflow/1_create_model.ipynb
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Download this notebook :download:`here <1_create_model.ipynb>`."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -33,7 +24,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"We first define the boundary conditions of our physics problem, that is, initial state, final state, formalism type, and the intermediate states that we're interested in. All this is handled through the `~expertsystem.reaction.StateTransitionManager` (STM). In this example, we chose to use the helicity formalism, but you can also use :code:`formalism_type=\"canonical-helicity\"`."
"We first define the boundary conditions of our physics problem, that is, initial state, final state, formalism type, and the intermediate states that we're interested in. All this is handled through the `~expertsystem.reaction.StateTransitionManager` (STM). In this example, we chose to use the helicity formalism, but you can also use :code:`formalism_type=\"canonical-helicity\"`. As you can see, we analyze the decay :math:`J/\\psi \\to \\pi^0\\pi^0\\gamma` here."
]
},
{
Expand All @@ -47,7 +38,7 @@
"stm = StateTransitionManager(\n",
" initial_state=[(\"J/psi(1S)\", [-1, +1])],\n",
" final_state=[\"gamma\", \"pi0\", \"pi0\"],\n",
" allowed_intermediate_particles=[\"f(0)(980)\", \"f(0)(1500)\"],\n",
" allowed_intermediate_particles=[\"f(0)\"],\n",
" formalism_type=\"helicity\",\n",
")\n",
"stm.set_allowed_interaction_types([InteractionTypes.Strong])"
Expand All @@ -59,8 +50,10 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
".. note::\n",
" As :doc:`3_perform_fit` serves to illustrate usage only, we make the amplitude model here a bit simpler by not allowing :math:`\\omega` states (which are narrow and therefore hard to fit). For this reason, we can also limit the `~expertsystem.reaction.solving.InteractionTypes` to `~expertsystem.reaction.solving.InteractionTypes.Strong`"
".. admonition:: Simplified model: :math:`J/\\psi \\to f_0\\gamma`\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 :math:`\\omega` resonances (which are narrow and therefore hard to fit). For this reason, we can also limit the `~expertsystem.reaction.solving.InteractionTypes` to `~expertsystem.reaction.solving.InteractionTypes.Strong`."
]
},
{
Expand Down Expand Up @@ -91,7 +84,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Now we're ready to let the STM compute the allowed intermediate states. In this example, we just use the standard interaction types that the `expertsystem` uses."
"Now we're ready to let the STM compute the allowed intermediate states. In this example, we just use the standard interaction type settings that `~expertsystem.reaction.StateTransitionManager` generated."
]
},
{
Expand All @@ -118,7 +111,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Now, this is the part where `tensorwaves` comes in: we want to convert the possible transitions to an `~expertsystem.amplitude.model.AmplitudeModel` that `tensorwaves` can then use as a fit model. This can be done with the `~expertsystem.amplitude.generate_amplitude_model` method."
"Finally, we're ready to create an `~expertsystem.amplitude.model.AmplitudeModel`. This can be done with the `~expertsystem.amplitude.generate_amplitude_model` method."
]
},
{
Expand Down Expand Up @@ -158,7 +151,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Cool, that's it! We now have a recipe for an amplitude model with which to :doc:`generate data <2_generate_data>` and perform a fit!"
"Cool, that's it! We now have a recipe for an amplitude model with which to :doc:`generate data </usage/2_generate_data>` and :doc:`perform a fit </usage/3_perform_fit>`! In the :doc:`next steps </usage/2_generate_data>`, we will use use this `~expertsystem.amplitude.model.AmplitudeModel` as a fit model template for `tensorwaves`."
]
}
],
Expand Down
130 changes: 77 additions & 53 deletions examples/workflow/2_generate_data.ipynb
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Download this notebook :download:`here <2_generate_data.ipynb>`."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -22,7 +13,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"In this section, we will use the amplitude model that we created with the expert system in :doc:`the previous step <1_create_model>` to generate a data sample via hit & miss Monte Carlo. We do this with the `tensorwaves.data.generate` module.\n",
"In this section, we will use the `~expertsystem.amplitude.model.AmplitudeModel` that we created with the expert system in :doc:`the previous step <1_create_model>` to generate a data sample via hit & miss Monte Carlo. We do this with the `tensorwaves.data.generate` module.\n",
"\n",
"First, we load a `~expertsystem.amplitude.model.AmplitudeModel` that was created in the previous step:"
]
Expand Down Expand Up @@ -51,11 +42,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"A recipe file defines the kinematics, the particles involved in the reaction,\n",
"the dynamics used for the model on which to perform the eventual optimization,\n",
"etc. In :doc:`Step 1 <1_create_model>`, we decided to use the helicity\n",
"formalism to analyse the problem, so here we need to use the\n",
"`~tensorwaves.physics.helicity_formalism.kinematics.HelicityKinematics` class."
"An `~expertsystem.amplitude.model.AmplitudeModel` defines the kinematics, the particles involved in the reaction, the dynamics used for the model on which to perform the eventual optimization, etc."
]
},
{
Expand All @@ -78,9 +65,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"A `.Kinematics` object defines the kinematics of the particle reaction we are\n",
"studying. From the final state masses listed here, we can see we are dealing\n",
"with the reaction :math:`J/\\psi \\to \\gamma\\pi^0\\pi^0`."
"A `.Kinematics` object defines the kinematics of the particle reaction we are studying. From the final state masses listed here, we can see we are dealing with the reaction :math:`J/\\psi \\to \\gamma\\pi^0\\pi^0`."
]
},
{
Expand All @@ -96,13 +81,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Kinematics define the constraints of the phase-space. As such, we have enough\n",
"information to generate a **phase-space sample** for this particle reaction.\n",
"We do this with the `.generate_phsp` function. By default, this function uses\n",
"`.TFPhaseSpaceGenerator` as a, well... phase-space generator (using tensorflow\n",
"in the back-end) and generates random numbers with\n",
"`.TFUniformRealNumberGenerator`. You can specify this with the arguments of\n",
"`.generate_phsp` function."
"`.Kinematics` define the constraints of the phase space. As such, we have enough information to generate a **phase-space sample** for this particle reaction. We do this with the `.generate_phsp` function. By default, this function uses `.TFPhaseSpaceGenerator` as a, well... phase-space generator (using tensorflow in the back-end) and generates random numbers with `.TFUniformRealNumberGenerator`. You can specify this with the arguments of `.generate_phsp` function."
]
},
{
Expand All @@ -123,8 +102,7 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"As you can see, the phase-space sample is a three-dimensional array: 300.000\n",
"events of four-momentum tuples for three particles."
"As you can see, the phase-space sample is a three-dimensional array: **300.000 events** of **four**-momentum tuples for **three** particles."
]
},
{
Expand All @@ -140,16 +118,9 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"'Data samples' are more complicated than phase space samples in that they\n",
"represent the intensity profile resulting from a reaction. You therefore need\n",
"an `.IntensityTF` object (or, more generally, a `~.interfaces.Function`\n",
"instance) and a phase space over which to generate that intensity\n",
"distribution. We call such a data sample an **intensity-based sample**.\n",
"'Data samples' are more complicated than phase space samples in that they represent the intensity profile resulting from a reaction. You therefore need an `.IntensityTF` object (or, more generally, a `~.interfaces.Function` instance) and a phase space over which to generate that intensity distribution. We call such a data sample an **intensity-based sample**.\n",
"\n",
"An intensity-based sample is generated with the function `.generate_data`. Its\n",
"usage is similar to `.generate_phsp`, but now you have to give an\n",
"`.IntensityTF` in addition to the `.Kinematics` object. An `.IntensityTF`\n",
"object can be created with the `.IntensityTF` class:"
"An intensity-based sample is generated with the function `.generate_data`. Its usage is similar to `.generate_phsp`, but now you have to give an `.IntensityTF` in addition to the `.Kinematics` object. An `.IntensityTF` object can be created with the `.IntensityTF` class:"
]
},
{
Expand Down Expand Up @@ -189,9 +160,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"That's it, now we have enough info to create an intensity-based data sample.\n",
"Notice how the structure is the sample as the phase-space sample we saw\n",
"before:"
"That's it, now we have enough info to create an intensity-based data sample. Notice how the structure is the sample as the phase-space sample we saw before:"
]
},
{
Expand Down Expand Up @@ -219,13 +188,9 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"We now have a phase space sample and an intensity-based sample. Their data\n",
"structure isn't the most informative though: it's just a collection of\n",
"four-momentum tuples. However, we can use the `.Kinematics` class to convert\n",
"those four-momentum tuples to a data set of kinematic variables.\n",
"We now have a phase space sample and an intensity-based sample. Their data structure isn't the most informative though: it's just a collection of four-momentum tuples. However, we can use the `.Kinematics` class to convert those four-momentum tuples to a data set of kinematic variables.\n",
"\n",
"Now we can use the :meth:`.Kinematics.convert` method to convert the phase\n",
"space and data samples of four-momentum tuples to kinematic variables."
"Now we can use the :meth:`.Kinematics.convert` method to convert the phase space and data samples of four-momentum tuples to kinematic variables."
]
},
{
Expand All @@ -236,7 +201,7 @@
"source": [
"phsp_set = kin.convert(phsp_sample)\n",
"data_set = kin.convert(data_sample)\n",
"list(data_set.keys())"
"list(data_set)"
]
},
{
Expand All @@ -245,12 +210,42 @@
"raw_mimetype": "text/restructuredtext"
},
"source": [
"The data set is just a `dict` of kinematic variables (keys are the names,\n",
"values is a list of computed values for each event). The numbers you see here\n",
"are final state IDs as defined in the YAML recipe file.\n",
"The data set is just a `dict` of kinematic variables (keys are the names, values is a list of computed values for each event). The numbers you see here are final state IDs as defined in the `~expertsystem.amplitude.model.AmplitudeModel.kinematics` member of the `~expertsystem.amplitude.model.AmplitudeModel`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for state_id, particle in model.kinematics.final_state.items():\n",
" print(f\"ID {state_id}:\", particle.name)"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
".. admonition:: Available kinematic variables\n",
" :class: dropdown\n",
"\n",
" By default, `tensorwaves` only generates invariant masses of the `.SubSystem` s that are of relevance to the decay problem. In this case, we only have resonances :math:`f_0 \\to \\pi^0\\pi^0`. If you are interested in more invariant mass combinations, you can do so with the method `.HelicityKinematics.register_invariant_mass`, e.g.:\n",
" \n",
" .. code-block:: python\n",
"\n",
"The format of this data set `dict` allows us to easily convert it to a\n",
"`pandas.DataFrame` and plot its content in the form of a histogram:"
" kin.register_invariant_mass([2, 4])"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"The data set is `dict`, which allows us to easily convert it to a `pandas.DataFrame` and plot its content in the form of a histogram:"
]
},
{
Expand All @@ -266,13 +261,36 @@
"data_frame"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"This also means that we can use all kinds of fancy plotting functionality of for instance `matplotlib.pyplot` to see what's going on. Here's an example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"phsp_frame[\"mSq_3_4\"].hist(bins=100)"
"import numpy as np\n",
"from matplotlib import cm\n",
"\n",
"intermediate_states = sorted(\n",
" (\n",
" p\n",
" for p in model.particles\n",
" if p not in model.kinematics.final_state.values()\n",
" and p not in model.kinematics.initial_state.values()\n",
" ),\n",
" key=lambda p: p.mass,\n",
")\n",
"\n",
"evenly_spaced_interval = np.linspace(0, 1, len(intermediate_states))\n",
"colors = [cm.rainbow(x) for x in evenly_spaced_interval]"
]
},
{
Expand All @@ -281,7 +299,13 @@
"metadata": {},
"outputs": [],
"source": [
"data_frame[\"mSq_3_4\"].hist(bins=100, alpha=0.5, density=True)"
"import matplotlib.pyplot as plt\n",
"\n",
"np.sqrt(data_frame[\"mSq_3_4\"]).hist(bins=100, alpha=0.5, density=True)\n",
"plt.xlabel(\"$m$ [GeV]\")\n",
"for i, p in enumerate(intermediate_states):\n",
" plt.axvline(x=p.mass, linestyle=\"dotted\", label=p.name, color=colors[i])\n",
"plt.legend();"
]
},
{
Expand Down
Loading