From 3ae285d5363a9e70d56ae1d7c5d94f8c5c7776f3 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 5 Nov 2024 13:59:49 +0100 Subject: [PATCH] Update Python tutorials --- pineappl_py/docs/source/advanced.ipynb | 113 ++++++++++-- pineappl_py/docs/source/introduction.ipynb | 189 ++++++++++++++------- 2 files changed, 231 insertions(+), 71 deletions(-) diff --git a/pineappl_py/docs/source/advanced.ipynb b/pineappl_py/docs/source/advanced.ipynb index b499b128..95e0ccfa 100644 --- a/pineappl_py/docs/source/advanced.ipynb +++ b/pineappl_py/docs/source/advanced.ipynb @@ -295,7 +295,14 @@ " q2 = 90.0 * 90.0\n", " \n", " # fill the interpolation grid\n", - " grid.fill(x1, x2, q2, 0, np.abs(yll), 0, weight)" + " n_tuple = [q2, x1, x2] # Pass kinematics as list; order has to follow `[q2, x1, x2, ..., xn]`\n", + " grid.fill(\n", + " order=0,\n", + " observable=np.abs(yll),\n", + " channel=0,\n", + " ntuple=n_tuple,\n", + " weight=weight,\n", + " )" ] }, { @@ -317,15 +324,85 @@ "metadata": {}, "outputs": [], "source": [ + "from pineappl.boc import Channel, Kinematics, ScaleFuncForm, Scales\n", + "from pineappl.convolutions import Conv, ConvType\n", + "from pineappl.grid import Grid, Order\n", + "from pineappl.interpolation import (\n", + " Interp,\n", + " InterpolationMethod,\n", + " MappingMethod,\n", + " ReweightingMethod,\n", + ")\n", + "from pineappl.pids import PidBasis\n", + "\n", "def generate_grid(calls: int) -> pineappl.grid.Grid:\n", " \"\"\"Generate the grid.\"\"\"\n", " # create a new luminosity function for the $\\gamma\\gamma$ initial state\n", - " lumi_entries = [pineappl.boc.Channel([(22, 22, 1.0)])]\n", - " # only LO $\\alpha_\\mathrm{s}^0 \\alpha^2 \\log^0(\\xi_\\mathrm{R}) \\log^0(\\xi_\\mathrm{F})$\n", - " orders = [pineappl.grid.Order(0, 2, 0, 0)]\n", + " channels = [Channel([([22, 22], 1.0)])]\n", + " # only LO $\\alpha_\\mathrm{s}^0 \\alpha^2 \\log^0(\\xi_\\mathrm{R}) \\log^0(\\xi_\\mathrm{F}) \\log^0(\\xi_\\mathrm{G})$$\n", + " orders = [Order(0, 2, 0, 0, 0)]\n", " bins = np.arange(0, 2.4, 0.1)\n", - " params = pineappl.subgrid.SubgridParams()\n", - " grid = pineappl.grid.Grid(lumi_entries, orders, bins, params)\n", + "\n", + " ### Define the specs that define the Grid ###\n", + " kinematics = [\n", + " Kinematics.Scale(0), # Scale\n", + " Kinematics.X(0), # momentum fraction x1\n", + " Kinematics.X(1), # momentum fraction x2\n", + " ]\n", + " # Define the interpolation specs for each item of the Kinematics\n", + " interpolations = [\n", + " Interp(\n", + " min=1e2,\n", + " max=1e8,\n", + " nodes=40,\n", + " order=3,\n", + " reweight_meth=ReweightingMethod.NoReweight,\n", + " map=MappingMethod.ApplGridH0,\n", + " interpolation_meth=InterpolationMethod.Lagrange,\n", + " ), # Interpolation on the Scale\n", + " Interp(\n", + " min=2e-7,\n", + " max=1,\n", + " nodes=50,\n", + " order=3,\n", + " reweight_meth=ReweightingMethod.ApplGridX,\n", + " map=MappingMethod.ApplGridF2,\n", + " interpolation_meth=InterpolationMethod.Lagrange,\n", + " ), # Interpolation on momentum fraction x1\n", + " Interp(\n", + " min=2e-7,\n", + " max=1,\n", + " nodes=50,\n", + " order=3,\n", + " reweight_meth=ReweightingMethod.ApplGridX,\n", + " map=MappingMethod.ApplGridF2,\n", + " interpolation_meth=InterpolationMethod.Lagrange,\n", + " ), # Interpolation on momentum fraction x2\n", + " ]\n", + "\n", + " # Construct the `Scales` object\n", + " scale_funcs = Scales(\n", + " ren=ScaleFuncForm.Scale(0),\n", + " fac=ScaleFuncForm.Scale(0),\n", + " frg=ScaleFuncForm.NoScale(0),\n", + " )\n", + "\n", + " # Construct the type of convolutions and the convolution object\n", + " # In our case we have symmetrical unpolarized protons in the initial state\n", + " conv_type = ConvType(polarized=False, time_like=False)\n", + " conv_object = Conv(conv_type=conv_type, pid=2212)\n", + " convolutions = [conv_object, conv_object]\n", + "\n", + " grid = Grid(\n", + " pid_basis=PidBasis.Evol,\n", + " channels=channels,\n", + " orders=orders,\n", + " bin_limits=bins,\n", + " convolutions=convolutions,\n", + " interpolations=interpolations,\n", + " kinematics=kinematics,\n", + " scale_funcs=scale_funcs,\n", + " )\n", "\n", " # fill the grid with phase-space points\n", " print(f\"Generating {calls} events, please wait...\")\n", @@ -355,7 +432,7 @@ "text": [ "Generating 1000000 events, please wait...\n", "Done.\n", - "LHAPDF 6.5.0 loading /Users/tanjona/miniconda3/envs/nnpdf/share/LHAPDF/NNPDF31_nnlo_as_0118_luxqed/NNPDF31_nnlo_as_0118_luxqed_0000.dat\n", + "LHAPDF 6.5.4 loading /home/tanjona/miniconda3/envs/nnpdf/share/LHAPDF/NNPDF31_nnlo_as_0118_luxqed/NNPDF31_nnlo_as_0118_luxqed_0000.dat\n", "NNPDF31_nnlo_as_0118_luxqed PDF set, member #0, version 2; LHAPDF ID = 325100\n" ] } @@ -370,7 +447,11 @@ "# of the partonic cross sections with the PDFs as given by our master \n", "# formula\n", "pdf = lhapdf.mkPDF(\"NNPDF31_nnlo_as_0118_luxqed\", 0)\n", - "bins = grid.convolve_with_one(2212, pdf.xfxQ2, pdf.alphasQ2)" + "bins = grid.convolve(\n", + " pdg_convs=[grid.convolutions()[0]],\n", + " xfxs=[pdf.xfxQ2],\n", + " alphas=pdf.alphasQ2,\n", + ")" ] }, { @@ -393,7 +474,7 @@ "outputs": [ { "data": { - "image/png": "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peHDh0uS/vCHP8jj8SgvL8+6CgEAgCVCCv3169cHX5eXl6tv3776xS9+obS0NEnSkSNHVFhY2O0eugMAgBOE/Zn+4sWLVVZWFgx8SUpLS9Njjz2mxYsXW1IcAACwTtih7/P51NDQ0GF/Q0ODjh8/HlFRAADAemGH/s0336zCwkK99tpr2r9/v/bv3681a9aoqKhI3/3ud62sEQAAWCCip+w98MAD+t73vqfW1tbTnfXooaKiIi1cuNCyAgEgbK0npJamyPromSKFsRIpYEdhh35KSoqeeeYZLVy4ULt375YkDRs2TL1797asOACIyFNXRt7HkHyp6B2CHwkh5On9uXPnatOmTcHt3r17a/To0Ro9ejSBDyD+eniljFHW9bd/o9R8xLr+gDgK+Ux///79uu6665SUlKQbbrhB06ZN09/+7d8qKSkpGvUBQGhcLmnaUsnvk0wz/H5OnZRenXH6tWFYUxsQZyGHfkVFhQzD0Icffqj//u//1pw5c3TgwAFdc801uvHGG/Wd73xH/fv3j0atANA1Lpfk7RdZH63N1tQC2EhYV++73W5NnDhRP/vZz7Rz5079/ve/V0FBgZ599lkNGjRI3/72t7Vo0SL96U9/srpeAAAQprBv2WtsbAy+vvzyy/XQQw/pww8/1L59+zRr1iy9//77evXVVy0pEgAARC7sq/f79eunX/3qV7rlllva7b/oootUVFSkoqKiiIsDAADWCftM3zRNPfvss/rmN7+pb33rW5ozZ44++eQTK2sDAAAWCjv0pdNP3RszZoy+9a1vafv27Zo4caIeeOABq2oDAAAWCnt6X5JeeeUVXXPNNcHtrVu36sYbb9TgwYN1//33R1wcAACwTthn+v3791dmZma7faNHj9bSpUu1fPnyiAsDAADWCjv0c3Nz9eKLL3bYn52drdra2oiKAgAA1gt7ev+xxx7T1VdfrS+//FJ33323Ro8eraamJj3++OO69NJLrawRAABYIOzQHzdunD7++GPde++9mjhxoswzy116vV79+te/tqxAAABgjYgu5MvJydF7772ngwcPatOmTTIMQwUFBUpPT7eqPgAAYJGQQr+kpOS8bSorKyVJ5eXl4VUEAACiIqTQ37x5c7vt6upqnTp1SsOHD5ck/eEPf5DH41FeXp51FQIAAEuEFPrr168Pvi4vL1ffvn31i1/8Qmlp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meDy8/PNe+65J7gdCATMQYMGmWVlZZ22/4d/+Afz+uuvb7evoKDA/Od//ueo1pmIQh37F1980ezXr1+MqnMGSebrr79+zjYPPfSQOWrUqHb7pk+fbk6dOjWKlSW2roz7+vXrTUnmkSNHYlKTUxw8eNCUZL733ntnbePk//MJfabf9qjeKVOmBPd15VG9X20vnX5U79nao3PhjL0kNTY26pJLLlFmZqZuvPFGbd++PRblOhq/8/GVm5uriy++WNdcc40+/PDDeJfT7bU9Lr1///5nbePk3/mEDv1zPar3bJ+bhfqoXnQunLEfPny4Kioq9F//9V96+eWXZRiGJkyYoP3798eiZMc62++8z+dTc3NznKpKfBdffLFWrFihNWvWaM2aNcrMzNTkyZNVXV0d79K6LcMwNGfOHH3zm98856qsTv4/b7tleOFc48ePb/egpAkTJujyyy/Xs88+q0cffTSOlQHWGz58uIYPHx7cnjBhgnbv3q0nn3xSL730Uhwr677uuecebdu2TR988EG8S7GthD7Tj8WjetG5cMb+r/Xs2VNXXXWVampqolEizjjb73xqaqp69eoVp6qcKT8/n9/3MBUXF+t//ud/tH79eg0ZMuScbZ38fz6hQ59H9cZPOGP/1wKBgD799FNdfPHF0SoT4nfeTrZs2cLve4hM01RxcbFef/11rVu3Tpdeeul5j3H073y8rySMtlWrVpnJycnmypUrzc8++8z8wQ9+YF5wwQVmXV2daZqmeccdd5gPP/xwsP2HH35o9ujRw1y0aJH5+eefm/PmzTN79uxpfvrpp/F6C91WqGM/f/588+233zZ3795tbtq0yZwxY4bp9XrN7du3x+stdEvHjx83N2/ebG7evNmUZJaXl5ubN2829+7da5qmaT788MPmHXfcEWz/xRdfmCkpKeaDDz5ofv755+ayZctMj8djrl27Nl5voVsKddyffPJJ84033jB37dplfvrpp+Z9991nut1u87e//W283kK3dNddd5n9+vUzq6qqzAMHDgS/Tpw4EWzD//m/SPjQN03TfPrpp82vfe1rZlJSkpmfn29+/PHHwe9NmjTJnDVrVrv2v/rVr8yvf/3rZlJSkjlq1CjzrbfeinHFiSOUsZ8zZ06wbUZGhvn3f//3ZnV1dRyq7t7abgX766+2sZ41a5Y5adKkDsfk5uaaSUlJ5tChQ80XX3wx5nV3d6GO+4IFC8xhw4aZXq/X7N+/vzl58mRz3bp18Sm+G+tszCW1+x3m//xf8GhdAAAcIqE/0wcAAH9B6AMA4BCEPgAADkHoAwDgEIQ+AAAOQegDAOAQhD4AAA5B6AMA4BCEPgAADkHoAwDgEIQ+gLBUVVUpKyvL9n0C+AtCHwAAhyD0AQBwCEIfgCWGDBmiZ555pt2+jz76SCkpKdq7d2+cqgLwVYQ+AEsUFBTok08+CW6bpqk5c+bo/vvv1yWXXBLHygC0IfQBWGLcuHHtQv+ll17Svn37VFpaKkk6fvy47r77bm3durXTbQDRR+gDsMS4ceP0+eefq7GxUU1NTfrRj36kxx57TH369JEkLV++XH6/Xxs3bux0G0D0EfoALJGXlye3263q6motWLBAF110kQoLC4PfX7dunbKyspSbm9vpNoDoI/QBWCIlJUVXXnml1qxZo0WLFunJJ5+U2336X8zJkyfldrv12WefKS8vr8M2gNgg9AFYZty4cXr66ac1depUTZ48Obh/165dampqUl5enlwuV4dtALFB6AOwTE5Ojnr27KmFCxe229/Q0KAvvvhCd911V6fbAGKjR7wLAJA4Vq1apeLiYmVnZ7fbf+DAAd16661qbm6WYRgdtvv27RunigFn4UwfQEQMw1B9fb0ef/xx7dq1S/PmzWv3/UAgoOrqau3bt0/33ntv8GK/tu2ePXvGqXLAeTjTBxCR3/3ud/qbv/kbjRgxQmvWrFFqamq773s8Hi1evLjdvr/eBhAbhD6AsGRlZWnOnDmaPHmyDMOwtE8A0eEyTdOMdxEAACD6+EwfAACHIPQBAHAIQh8AAIcg9AEAcAhCHwAAhyD0AQBwCEIfAACHIPQBAHAIQh8AAIf4/5bmCcvpjkZOAAAAAElFTkSuQmCC", + "image/png": "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peHDh0uS/vCHP8jj8SgvL8+6CgEAgCVCCv3169cHX5eXl6tv3776xS9+obS0NEnSkSNHVFhY2O0eugMAgBOE/Zn+4sWLVVZWFgx8SUpLS9Njjz2mxYsXW1IcAACwTtih7/P51NDQ0GF/Q0ODjh8/HlFRAADAemGH/s0336zCwkK99tpr2r9/v/bv3681a9aoqKhI3/3ud62sEQAAWCCip+w98MAD+t73vqfW1tbTnfXooaKiIi1cuNCyAgEgbK0npJamyPromSKFsRIpYEdhh35KSoqeeeYZLVy4ULt375YkDRs2TL1797asOACIyFNXRt7HkHyp6B2CHwkh5On9uXPnatOmTcHt3r17a/To0Ro9ejSBDyD+eniljFHW9bd/o9R8xLr+gDgK+Ux///79uu6665SUlKQbbrhB06ZN09/+7d8qKSkpGvUBQGhcLmnaUsnvk0wz/H5OnZRenXH6tWFYUxsQZyGHfkVFhQzD0Icffqj//u//1pw5c3TgwAFdc801uvHGG/Wd73xH/fv3j0atANA1Lpfk7RdZH63N1tQC2EhYV++73W5NnDhRP/vZz7Rz5079/ve/V0FBgZ599lkNGjRI3/72t7Vo0SL96U9/srpeAAAQprBv2WtsbAy+vvzyy/XQQw/pww8/1L59+zRr1iy9//77evXVVy0pEgAARC7sq/f79eunX/3qV7rlllva7b/oootUVFSkoqKiiIsDAADWCftM3zRNPfvss/rmN7+pb33rW5ozZ44++eQTK2sDAAAWCjv0pdNP3RszZoy+9a1vafv27Zo4caIeeOABq2oDAAAWCnt6X5JeeeUVXXPNNcHtrVu36sYbb9TgwYN1//33R1wcAACwTthn+v3791dmZma7faNHj9bSpUu1fPnyiAsDAADWCjv0c3Nz9eKLL3bYn52drdra2oiKAgAA1gt7ev+xxx7T1VdfrS+//FJ33323Ro8eraamJj3++OO69NJLrawRAABYIOzQHzdunD7++GPde++9mjhxoswzy116vV79+te/tqxAAABgjYgu5MvJydF7772ngwcPatOmTTIMQwUFBUpPT7eqPgAAYJGQQr+kpOS8bSorKyVJ5eXl4VUEAACiIqTQ37x5c7vt6upqnTp1SsOHD5ck/eEPf5DH41FeXp51FQIAAEuEFPrr168Pvi4vL1ffvn31i1/8Qmlp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meDy8/PNe+65J7gdCATMQYMGmWVlZZ22/4d/+Afz+uuvb7evoKDA/Od//ueo1pmIQh37F1980ezXr1+MqnMGSebrr79+zjYPPfSQOWrUqHb7pk+fbk6dOjWKlSW2roz7+vXrTUnmkSNHYlKTUxw8eNCUZL733ntnbePk//MJfabf9qjeKVOmBPd15VG9X20vnX5U79nao3PhjL0kNTY26pJLLlFmZqZuvPFGbd++PRblOhq/8/GVm5uriy++WNdcc40+/PDDeJfT7bU9Lr1///5nbePk3/mEDv1zPar3bJ+bhfqoXnQunLEfPny4Kioq9F//9V96+eWXZRiGJkyYoP3798eiZMc62++8z+dTc3NznKpKfBdffLFWrFihNWvWaM2aNcrMzNTkyZNVXV0d79K6LcMwNGfOHH3zm98856qsTv4/b7tleOFc48ePb/egpAkTJujyyy/Xs88+q0cffTSOlQHWGz58uIYPHx7cnjBhgnbv3q0nn3xSL730Uhwr677uuecebdu2TR988EG8S7GthD7Tj8WjetG5cMb+r/Xs2VNXXXWVampqolEizjjb73xqaqp69eoVp6qcKT8/n9/3MBUXF+t//ud/tH79eg0ZMuScbZ38fz6hQ59H9cZPOGP/1wKBgD799FNdfPHF0SoT4nfeTrZs2cLve4hM01RxcbFef/11rVu3Tpdeeul5j3H073y8rySMtlWrVpnJycnmypUrzc8++8z8wQ9+YF5wwQVmXV2daZqmeccdd5gPP/xwsP2HH35o9ujRw1y0aJH5+eefm/PmzTN79uxpfvrpp/F6C91WqGM/f/588+233zZ3795tbtq0yZwxY4bp9XrN7du3x+stdEvHjx83N2/ebG7evNmUZJaXl5ubN2829+7da5qmaT788MPmHXfcEWz/xRdfmCkpKeaDDz5ofv755+ayZctMj8djrl27Nl5voVsKddyffPJJ84033jB37dplfvrpp+Z9991nut1u87e//W283kK3dNddd5n9+vUzq6qqzAMHDgS/Tpw4EWzD//m/SPjQN03TfPrpp82vfe1rZlJSkpmfn29+/PHHwe9NmjTJnDVrVrv2v/rVr8yvf/3rZlJSkjlq1CjzrbfeinHFiSOUsZ8zZ06wbUZGhvn3f//3ZnV1dRyq7t7abgX766+2sZ41a5Y5adKkDsfk5uaaSUlJ5tChQ80XX3wx5nV3d6GO+4IFC8xhw4aZXq/X7N+/vzl58mRz3bp18Sm+G+tszCW1+x3m//xf8GhdAAAcIqE/0wcAAH9B6AMA4BCEPgAADkHoAwDgEIQ+AAAOQegDAOAQhD4AAA5B6AMA4BCEPgAADkHoAwDgEIQ+gLBUVVUpKyvL9n0C+AtCHwAAhyD0AQBwCEIfgCWGDBmiZ555pt2+jz76SCkpKdq7d2+cqgLwVYQ+AEsUFBTok08+CW6bpqk5c+bo/vvv1yWXXBLHygC0IfQBWGLcuHHtQv+ll17Svn37VFpaKkk6fvy47r77bm3durXTbQDRR+gDsMS4ceP0+eefq7GxUU1NTfrRj36kxx57TH369JEkLV++XH6/Xxs3bux0G0D0EfoALJGXlye3263q6motWLBAF110kQoLC4PfX7dunbKyspSbm9vpNoDoI/QBWCIlJUVXXnml1qxZo0WLFunJJ5+U2336X8zJkyfldrv12WefKS8vr8M2gNgg9AFYZty4cXr66ac1depUTZ48Obh/165dampqUl5enlwuV4dtALFB6AOwTE5Ojnr27KmFCxe229/Q0KAvvvhCd911V6fbAGKjR7wLAJA4Vq1apeLiYmVnZ7fbf+DAAd16661qbm6WYRgdtvv27RunigFn4UwfQEQMw1B9fb0ef/xx7dq1S/PmzWv3/UAgoOrqau3bt0/33ntv8GK/tu2ePXvGqXLAeTjTBxCR3/3ud/qbv/kbjRgxQmvWrFFqamq773s8Hi1evLjdvr/eBhAbhD6AsGRlZWnOnDmaPHmyDMOwtE8A0eEyTdOMdxEAACD6+EwfAACHIPQBAHAIQh8AAIcg9AEAcAhCHwAAhyD0AQBwCEIfAACHIPQBAHAIQh8AAIf4/5bmCcvpjkZOAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -421,13 +502,21 @@ "\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb155b03-7ad5-41e9-bd21-3d9cd3d17585", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "PineAPPL", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "pineappl" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -439,7 +528,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.6" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/pineappl_py/docs/source/introduction.ipynb b/pineappl_py/docs/source/introduction.ipynb index 63808c6c..8bef76df 100644 --- a/pineappl_py/docs/source/introduction.ipynb +++ b/pineappl_py/docs/source/introduction.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "raw", - "id": "ecb04362-1f02-4d0b-81f6-df1b95134c67", + "id": "e904212d-ee57-4664-8e78-fd0e8f2a665e", "metadata": {}, "source": [ "pip install pineappl" @@ -116,7 +116,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "LHAPDF 6.5.4 loading /home/felix/local/share/LHAPDF/NNPDF40_nnlo_as_01180/NNPDF40_nnlo_as_01180_0000.dat\n", + "LHAPDF 6.5.4 loading /home/tanjona/LHAPDF_PATH/NNPDF40_nnlo_as_01180/NNPDF40_nnlo_as_01180_0000.dat\n", "NNPDF40_nnlo_as_01180 PDF set, member #0, version 1; LHAPDF ID = 331100\n" ] } @@ -139,12 +139,38 @@ "id": "640a1efd-94bb-4c22-a6d7-785e940a0013", "metadata": {}, "source": [ - "Our grid can now be convolved with our PDF set using the `convolve_with_one()` function:" + "In order to convolve a grid, we need to specify the types of convolutions that are required.\n", + "This includes the polarization and the PDG IDs of the involved hadrons, as well as wether or\n", + "not the hadron is in the initial- or final-state.\n", + "\n", + "In our example, the grid involves two initial-state unpolarized protons. We can therefore\n", + "construct the convolution types as follows:" ] }, { "cell_type": "code", "execution_count": 5, + "id": "a10346c8-cda8-4d71-9b10-518cab0ec38b", + "metadata": {}, + "outputs": [], + "source": [ + "from pineappl.convolutions import Conv, ConvType\n", + "\n", + "conv_type = ConvType(polarized=False, time_like=False)\n", + "conv_object = Conv(conv_type=conv_type, pid=2212)" + ] + }, + { + "cell_type": "markdown", + "id": "813d3ba0-df32-4f2d-8364-73c625855bce", + "metadata": {}, + "source": [ + "Our grid can now be convolved with our PDF set using the `convolve()` function." + ] + }, + { + "cell_type": "code", + "execution_count": 6, "id": "d41e391c-affd-49ad-8d70-483bf952d4f3", "metadata": {}, "outputs": [ @@ -181,13 +207,17 @@ "└──────┴─────────────┘" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "predictions = grid.convolve_with_one(2212, pdf.xfxQ2, pdf.alphasQ2)\n", + "predictions = grid.convolve(\n", + " pdg_convs=[conv_object, conv_object], # Similar convolutions for symmetric protons\n", + " xfxs=[pdf.xfxQ2, pdf.xfxQ2], # Similar PDF sets for symmetric protons\n", + " alphas=pdf.alphasQ2,\n", + ")\n", "df_preds = pl.DataFrame({\n", " \"bins\": range(predictions.size),\n", " \"predictions\": predictions,\n", @@ -195,6 +225,34 @@ "df_preds" ] }, + { + "cell_type": "markdown", + "id": "6ad4724b-e303-4200-a212-c24c81cb1d3f", + "metadata": {}, + "source": [ + "We can see that `convolve()` can perform convolutions with an arbitrary number of distributions. This is\n", + "why `pdf_convs` and `xfxs` are lists that respectively take all the types of convolutions and distributions\n", + "corresponding to the involved hadrons.\n", + "\n", + "**NOTE:** If the hadrons have the same type of convolutions and require the convolution to the same distribution,\n", + "then only one single element can be passed to the list:" + ] + }, + { + "cell_type": "markdown", + "id": "1cb9a279-cb32-4817-8d5a-0fde5213085b", + "metadata": {}, + "source": [ + "```python\n", + "# Pass the shared convolution type and distribution to all hadrons\n", + "predictions = grid.convolve(\n", + " pdg_convs=[conv_object],\n", + " xfxs=[pdf.xfxQ2],\n", + " alphas=pdf.alphasQ2,\n", + ")\n", + "```" + ] + }, { "cell_type": "markdown", "id": "231dd694-e068-4e62-8e19-b93c96f4d937", @@ -212,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "fee97bfd-e392-4a78-8850-a4093bbcb330", "metadata": {}, "outputs": [ @@ -269,9 +327,10 @@ "id": "ba2b1e4c-bc60-48dd-9b04-d349b4118707", "metadata": {}, "source": [ - "**NOTE:** If the two initial state hadrons are different (as is the case in\n", - "$pp$ collisions in which one of the protons is polarized), then one can convolve\n", - "the grid with **two** different PDF sets using the `convolve_with_two()` function:" + "**NOTE:** As mentioned before, if the two initial state hadrons are different \n", + "(as is the case in $pp$ collisions in which one of the protons is polarized),\n", + "then one can convolve the grid with **two** different PDF sets using the `convolve()` \n", + "function:" ] }, { @@ -280,8 +339,19 @@ "metadata": {}, "source": [ "```python\n", + "# Define the convolution types for each of the (un)polarized hadrons\n", + "pol_type = ConvType(polarized=True, time_like=False) # `polarized = True`\n", + "pol_object = Conv(conv_type=pol_type, pid=2212)\n", + "\n", + "unpol_type = ConvType(polarized=False, time_like=False)\n", + "unpol_object = Conv(conv_type=conv_type, pid=2212)\n", + "\n", "# Convolve the two initial state hadrons with different PDF sets\n", - "predictions = grid.convolve_with_two(2212, polarized_pdf.xfxQ2, 2212, unpolarized_pdf.xfxQ2, unpolarized_pdf.alphasQ2)\n", + "predictions = predictions = grid.convolve(\n", + " pdg_convs=[pol_object, conv_object],\n", + " xfxs=[polarized_pdf.xfxQ2, 2212, unpolarized_pdf.xfxQ2],\n", + " alphas=pdf.alphasQ2,\n", + ")\n", "```" ] }, @@ -290,7 +360,7 @@ "id": "3d56b36c-b888-4f2d-b3fb-2f8f689ff003", "metadata": {}, "source": [ - "**NOTE:** The same functions `convolve_with_one()` and `convolve_with_two()` also work for convolving FK tables with PDF sets." + "**NOTE:** The same function `convolve` also works for convolving FK tables with PDF sets." ] }, { @@ -314,7 +384,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "b0d1a772-3be5-47df-99e2-96daa5ebf380", "metadata": {}, "outputs": [ @@ -322,24 +392,24 @@ "name": "stdout", "output_type": "stream", "text": [ - "0: [(2, -2, 1.0), (4, -4, 1.0)]\n", - "1: [(0, -4, 1.0), (0, -2, 1.0)]\n", - "2: [(22, -4, 1.0), (22, -2, 1.0)]\n", - "3: [(2, 0, 1.0), (4, 0, 1.0)]\n", - "4: [(2, 22, 1.0), (4, 22, 1.0)]\n", - "5: [(1, -1, 1.0), (3, -3, 1.0)]\n", - "6: [(0, -3, 1.0), (0, -1, 1.0)]\n", - "7: [(22, -3, 1.0), (22, -1, 1.0)]\n", - "8: [(1, 0, 1.0), (3, 0, 1.0)]\n", - "9: [(1, 22, 1.0), (3, 22, 1.0)]\n", - "10: [(5, -5, 1.0)]\n", - "11: [(0, -5, 1.0)]\n", - "12: [(22, -5, 1.0)]\n", - "13: [(5, 0, 1.0)]\n", - "14: [(5, 22, 1.0)]\n", - "15: [(22, 22, 1.0)]\n", - "16: [(-5, 22, 1.0), (-3, 22, 1.0), (-1, 22, 1.0)]\n", - "17: [(1, 22, 1.0), (3, 22, 1.0), (5, 22, 1.0)]\n" + "0: [([2, -2], 1.0), ([4, -4], 1.0)]\n", + "1: [([0, -4], 1.0), ([0, -2], 1.0)]\n", + "2: [([22, -4], 1.0), ([22, -2], 1.0)]\n", + "3: [([2, 0], 1.0), ([4, 0], 1.0)]\n", + "4: [([2, 22], 1.0), ([4, 22], 1.0)]\n", + "5: [([1, -1], 1.0), ([3, -3], 1.0)]\n", + "6: [([0, -3], 1.0), ([0, -1], 1.0)]\n", + "7: [([22, -3], 1.0), ([22, -1], 1.0)]\n", + "8: [([1, 0], 1.0), ([3, 0], 1.0)]\n", + "9: [([1, 22], 1.0), ([3, 22], 1.0)]\n", + "10: [([5, -5], 1.0)]\n", + "11: [([0, -5], 1.0)]\n", + "12: [([22, -5], 1.0)]\n", + "13: [([5, 0], 1.0)]\n", + "14: [([5, 22], 1.0)]\n", + "15: [([22, 22], 1.0)]\n", + "16: [([-5, 22], 1.0), ([-3, 22], 1.0), ([-1, 22], 1.0)]\n", + "17: [([1, 22], 1.0), ([3, 22], 1.0), ([5, 22], 1.0)]\n" ] } ], @@ -373,7 +443,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "6658a6c3-bb88-42fa-a567-9f5b6cebb1ac", "metadata": {}, "outputs": [ @@ -387,26 +457,26 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (7, 5)
indexasalflr
u32i64i64i64i64
00200
11200
21210
31201
40300
50310
60301
" + "shape: (7, 6)
indexasalflrlg
u32i64i64i64i64i64
002000
112000
212100
312010
403000
503100
603010
" ], "text/plain": [ - "shape: (7, 5)\n", - "┌───────┬─────┬─────┬─────┬─────┐\n", - "│ index ┆ as ┆ a ┆ lf ┆ lr │\n", - "│ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", - "│ u32 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │\n", - "╞═══════╪═════╪═════╪═════╪═════╡\n", - "│ 0 ┆ 0 ┆ 2 ┆ 0 ┆ 0 │\n", - "│ 1 ┆ 1 ┆ 2 ┆ 0 ┆ 0 │\n", - "│ 2 ┆ 1 ┆ 2 ┆ 1 ┆ 0 │\n", - "│ 3 ┆ 1 ┆ 2 ┆ 0 ┆ 1 │\n", - "│ 4 ┆ 0 ┆ 3 ┆ 0 ┆ 0 │\n", - "│ 5 ┆ 0 ┆ 3 ┆ 1 ┆ 0 │\n", - "│ 6 ┆ 0 ┆ 3 ┆ 0 ┆ 1 │\n", - "└───────┴─────┴─────┴─────┴─────┘" + "shape: (7, 6)\n", + "┌───────┬─────┬─────┬─────┬─────┬─────┐\n", + "│ index ┆ as ┆ a ┆ lf ┆ lr ┆ lg │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u32 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │\n", + "╞═══════╪═════╪═════╪═════╪═════╪═════╡\n", + "│ 0 ┆ 0 ┆ 2 ┆ 0 ┆ 0 ┆ 0 │\n", + "│ 1 ┆ 1 ┆ 2 ┆ 0 ┆ 0 ┆ 0 │\n", + "│ 2 ┆ 1 ┆ 2 ┆ 1 ┆ 0 ┆ 0 │\n", + "│ 3 ┆ 1 ┆ 2 ┆ 0 ┆ 1 ┆ 0 │\n", + "│ 4 ┆ 0 ┆ 3 ┆ 0 ┆ 0 ┆ 0 │\n", + "│ 5 ┆ 0 ┆ 3 ┆ 1 ┆ 0 ┆ 0 │\n", + "│ 6 ┆ 0 ┆ 3 ┆ 0 ┆ 1 ┆ 0 │\n", + "└───────┴─────┴─────┴─────┴─────┴─────┘" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -419,7 +489,7 @@ "\n", "df_orders = pl.DataFrame(\n", " np.array(orders),\n", - " schema=[\"as\", \"a\", \"lf\", \"lr\"]\n", + " schema=[\"as\", \"a\", \"lf\", \"lr\", \"lg\"]\n", ")\n", "df_orders.with_row_index()" ] @@ -431,7 +501,8 @@ "source": [ "The table above lists the perturbative orders contained in the\n", "grid where the powers of the strong coupling $a_s$, the electroweak\n", - "coupling $a$, the factorization $\\ell_F = \\log(\\mu_F^2/Q^2)$ and renormalization $\\ell_R=\\log(\\mu_R^2/Q^2)$ \n", + "coupling $a$, the factorization $\\ell_F = \\log(\\mu_F^2/Q^2)$, renormalization $\\ell_R=\\log(\\mu_R^2/Q^2)$,\n", + "and fragmentation $\\ell_g=\\log(\\mu_G^2/Q^2)$\n", "logs are shown. For instance, the first index shows that the grid \n", "contains a leading-order (LO) which has the coupling $a_s^2$." ] @@ -456,7 +527,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "4514380c-65e3-4116-a835-238212d68d10", "metadata": {}, "outputs": [ @@ -493,7 +564,7 @@ "└────────────┴─────────────┘" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -531,7 +602,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "16f768ea-4007-4ee9-be97-c862fbb8dfab", "metadata": {}, "outputs": [ @@ -568,7 +639,7 @@ "└───────┴───────────────────┘" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -590,7 +661,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "60745b45-0cb5-413d-8f84-cea84e557998", "metadata": {}, "outputs": [], @@ -626,7 +697,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "82efebec-966b-4a8f-89b1-c78077857752", "metadata": {}, "outputs": [ @@ -663,7 +734,7 @@ "└───────┴───────────────────┘" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -710,9 +781,9 @@ ], "metadata": { "kernelspec": { - "display_name": "PineAPPL", + "display_name": "nnpdf", "language": "python", - "name": "pineappl" + "name": "nnpdf" }, "language_info": { "codemirror_mode": { @@ -724,7 +795,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.6" + "version": "3.11.9" } }, "nbformat": 4,