diff --git a/doc/source/overview/tutorials/output.ipynb b/doc/source/overview/tutorials/output.ipynb index 79bddaec3..13c10b68e 100644 --- a/doc/source/overview/tutorials/output.ipynb +++ b/doc/source/overview/tutorials/output.ipynb @@ -55,7 +55,7 @@ "id": "f26bf77f-9999-42d0-8ebf-2c1607214ea7", "metadata": {}, "source": [ - "Now that we have it, we can actually use one of the available formats to dump it." + "The computed operator is now it's own type (that no longer inherits from dictionary as in previous eko versions):" ] }, { @@ -63,39 +63,20 @@ "execution_count": 3, "id": "daae3811-e7a6-4a7c-9f55-eef8ea1564b8", "metadata": {}, - "outputs": [], - "source": [ - "evolution_operator.dump_tar(\"myeko.tar\")" - ] - }, - { - "cell_type": "markdown", - "id": "a0d115e4-43cd-4f83-bcb5-922dcbfc56d4", - "metadata": {}, - "source": [ - "Once dumped, we can always use the paired method to load it, at any later time." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b62dc52e-ff36-4621-a772-502ff495456f", - "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "eko.output.Output" + "eko.output.struct.EKO" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "myeko = eko.output.Output.load_tar(\"myeko.tar\")\n", - "type(myeko)" + "type(evolution_operator)" ] }, { @@ -103,12 +84,12 @@ "id": "91b17b27-e423-43fe-87f2-a1eaff027c7a", "metadata": {}, "source": [ - "Now, let's inspect the content of the operator." + "Now, let's inspect the content of the operator: e.g. you can extract the theory and operator card" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "e5c5b8af-d478-48ca-bb61-9a0de680252a", "metadata": {}, "outputs": [ @@ -116,113 +97,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "Q2grid\n", - "eko_version\n", - "inputgrid\n", - "inputpids\n", - "interpolation_is_log\n", - "interpolation_polynomial_degree\n", - "interpolation_xgrid\n", - "q2_ref\n", - "targetgrid\n", - "targetpids\n" + "{'CKM': '0.97428 0.22530 0.003470 0.22520 0.97345 0.041000 0.00862 0.04030 0.999152', 'Comments': 'LO baseline for small-x res', 'DAMP': 0, 'EScaleVar': 1, 'FNS': 'FFNS', 'GF': 1.1663787e-05, 'HQ': 'POLE', 'IB': 0, 'IC': 0, 'ID': 0, 'MP': 0.938, 'MW': 80.398, 'MZ': 91.1876, 'MaxNfAs': 6, 'MaxNfPdf': 6, 'ModEv': 'EXA', 'ModSV': None, 'NfFF': 3, 'PTO': 0, 'Q0': 1.0, 'QED': 0, 'Qedref': 1.777, 'Qmb': 4.5, 'Qmc': 2.0, 'Qmt': 173.07, 'Qref': 91.2, 'SIN2TW': 0.23126, 'SxOrd': 'LL', 'SxRes': 0, 'TMC': 0, 'XIF': 1.0, 'XIR': 1.0, 'alphaqed': 0.007496251999999999, 'alphas': 0.11800000000000001, 'fact_to_ren_scale_ratio': 1.0, 'global_nx': 0, 'kDISbThr': 1.0, 'kDIScThr': 1.0, 'kDIStThr': 1.0, 'kbThr': 1.0, 'kcThr': 1.0, 'ktThr': 1.0, 'mb': 4.5, 'mc': 2.0, 'mt': 173.07, 'nf0': None, 'nfref': None}\n", + "{'Q0': 1.0, 'Q2grid': [100], 'backward_inversion': 'expanded', 'configs': {'backward_inversion': 'expanded', 'ev_op_iterations': 10, 'ev_op_max_order': [10, 0], 'interpolation_is_log': True, 'interpolation_polynomial_degree': 4, 'n_integration_cores': 0}, 'debug': {'skip_non_singlet': False, 'skip_singlet': False}, 'debug_skip_non_singlet': False, 'debug_skip_singlet': False, 'ev_op_iterations': 10, 'ev_op_max_order': 10, 'inputgrid': None, 'inputpids': None, 'interpolation_is_log': True, 'interpolation_polynomial_degree': 4, 'interpolation_xgrid': [0.001, 0.01, 0.1, 0.5, 1.0], 'n_integration_cores': 0, 'rotations': {'inputgrid': None, 'inputpids': None, 'targetgrid': None, 'targetpids': None, 'xgrid': [0.001, 0.01, 0.1, 0.5, 1.0]}, 'targetgrid': None, 'targetpids': None}\n" ] - }, - { - "data": { - "text/plain": [ - "'0.0.0'" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "print(*myeko.keys(), sep=\"\\n\")\n", - "myeko[\"eko_version\"]" - ] - }, - { - "cell_type": "markdown", - "id": "3d610d9f-b2cb-4ddf-ab02-a47d9c9638c3", - "metadata": {}, - "source": [ - "In the last step, we proved that an `eko.output.Output` object essentially behaves like a dictionary. Indeed, it is a dictionary." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "fcca9db4-a266-4abb-8aea-2390fc3aaa72", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "isinstance(myeko, dict)" - ] - }, - { - "cell_type": "markdown", - "id": "7b1baedd-8a95-4b5c-a1a0-03716534ecf3", - "metadata": {}, - "source": [ - "At the moment we have only seen one attribute in action: an `Output` object records the version of `eko` that has generated.\n", - "Let's have a look at some other ones." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "593038bf-d8db-46ce-8a19-fbb2ae1908b6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INTERNAL\n", - "log? True, degree? 4\n", - "[0.001 0.01 0.1 0.5 1. ]\n", - "\n", - "INPUT\n", - "grid: (5,) float64\n", - "pids: 14 \n", - "Q0^2: 1.0 GeV^2\n", - "TARGET\n", - "grid: (5,) float64\n", - "pids: 14 \n", - "\n", - "All grid the same? True\n" - ] - } - ], - "source": [ - "interpl = myeko[\"interpolation_is_log\"]\n", - "interpd = myeko[\"interpolation_polynomial_degree\"]\n", - "interpg = myeko[\"interpolation_xgrid\"]\n", - "print(f\"INTERNAL\\nlog? {interpl}, degree? {interpd}\\n{interpg}\\n\")\n", - "\n", - "ig = myeko[\"inputgrid\"]\n", - "ip = myeko[\"inputpids\"]\n", - "q0 = myeko[\"q2_ref\"]\n", - "print(f\"INPUT\\ngrid: {ig.shape} {ig.dtype}\\npids: {len(ip)} {type(ip[0])}\\nQ0^2: {q0} GeV^2\")\n", - "tg = myeko[\"targetgrid\"]\n", - "tp = myeko[\"targetpids\"]\n", - "print(f\"TARGET\\ngrid: {tg.shape} {tg.dtype}\\npids: {len(tp)} {type(tp[0])}\")\n", - "\n", - "print(\"\\nAll grid the same?\", (interpg == ig).all() and (interpg == tg).all())" + "# obtain theory card\n", + "print(evolution_operator.theory_card)\n", + "# or operator card\n", + "print(evolution_operator.operator_card)" ] }, { @@ -231,29 +115,28 @@ "metadata": {}, "source": [ "So an `Output` object has some internal parameters, related to the interpolation used for the calculation, and then some external attributes, related to the final operator delivered.\n", - "But actually, we have not accessed yet the actual operator." + "But actually, we have not accessed yet the actual operator - let's first find out again which final scales we computed:" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "id": "c82e6733-946f-4210-a6fa-95f995ee5be5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "dict_keys([100.0])" + "array([100])" ] }, - "execution_count": 8, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "opgrid = myeko[\"Q2grid\"]\n", - "opgrid.keys()" + "evolution_operator.Q2grid" ] }, { @@ -261,13 +144,13 @@ "id": "075734fa-8108-44ff-9070-cb4e5baab072", "metadata": {}, "source": [ - "Even the operator grid is a dictionary, mapping $Q^2$ values to the operator evolving to that scale (from the unique starting scale $Q_0^2$).\n", - "In the present case there is a unique final scale, but in the general one there might be many." + "Remember that the unique starting scale is $Q_0^2$. In the present case there is a unique final scale, but in the general one there might be many.\n", + "Now, let's use this operator! The recommended way to load an operator is by using a context manager:" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "id": "15262aee-1cfa-40f3-b072-b53ec5517784", "metadata": {}, "outputs": [ @@ -275,23 +158,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "dict_keys(['operators', 'errors'])\n", - "\n", - "OPERATOR\n", - "(14, 5, 14, 5) float64\n", - "\n", - "ERROR\n", - "(14, 5, 14, 5) float64\n" + "operator: (14, 5, 14, 5)\n", + "error: (14, 5, 14, 5)\n" ] } ], "source": [ - "print(opgrid[100.].keys())\n", - "op = opgrid[100.][\"operators\"]\n", - "operr = opgrid[100.][\"errors\"]\n", - "\n", - "print(f\"\\nOPERATOR\\n{op.shape} {op.dtype}\")\n", - "print(f\"\\nERROR\\n{operr.shape} {operr.dtype}\")" + "with evolution_operator.operator(100) as op:\n", + " print(f\"operator: {op.operator.shape}\")\n", + " print(f\"error: {op.error.shape}\")" ] }, { @@ -300,7 +175,7 @@ "metadata": {}, "source": [ "This is the final product we expected from the beginning: the evolution operator, delivered as a numerical array.\n", - "It is actually composed by 3 elements:\n", + "It is actually composed by two elements:\n", "\n", "- the **operator** itself, whose dimensions are `(flavor_out, x_out, flavor_in, x_in)`\n", "- the *error* on each operator element, propagated from the integration error on the numerical Mellin inversion (no other source is taken into account)" @@ -313,7 +188,7 @@ "source": [ "How to use this object is now completely up to the user, but a few helpers are included in another package: `ekobox`!\n", "\n", - "This package will be explored in a separate tutorial." + "This package will be explored in [a separate tutorial](./pdf.ipynb)." ] } ], @@ -333,7 +208,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.10.6" } }, "nbformat": 4,