From 642eae8ab39bce8246a239eb6badc5ebc06fefda Mon Sep 17 00:00:00 2001 From: AleCandido Date: Fri, 22 May 2020 17:47:58 +0200 Subject: [PATCH 1/5] Start TMC abstract class docs --- docs/sphinx/source/theory/TMC.rst | 65 +++++++++++++++ src/yadism/structure_functions/TMC.py | 110 ++++++++++++-------------- 2 files changed, 117 insertions(+), 58 deletions(-) diff --git a/docs/sphinx/source/theory/TMC.rst b/docs/sphinx/source/theory/TMC.rst index 36319e83d..ea89329f8 100644 --- a/docs/sphinx/source/theory/TMC.rst +++ b/docs/sphinx/source/theory/TMC.rst @@ -1,4 +1,69 @@ +.. _tmc-page: + Target Mass Corrections ======================= :cite:`tmc-review`, :cite:`tmc-iranian` + + + + +----- + + +Work in Progress notes +====================== + + +Runner: holds a list of structure functions instances, that will act as our +"soft singletons" +StructureFunction: holds a reference to his parent runner, in this way its also +able to access its StructureFunctions siblings (like F2 from FL, in order to +compute TMCs, e.g.) + +Caching: it is managed at the level of StructureFunction, while the values are +kept at the level of ESF (so the StructureFunction is just routing the caller to +the correct instance of ESF to ask for values) + +Note 1 +------ +Here is the third time that we are proliferating the SF classes to all the +flavours and kinds (SF/ESFTMC/ESF x 2/L x light/c/b/t), but at the bottom level +they are needed (ESF implementation are actually different for every option, so +it makes sense to have different classes). +The classes one level above (SF/ESFTMC) are simply shadowing the ones below in +order to route to the correct one. The same business can be done with a `switch` +pattern (actually `if...elif...elif...` in python), but the only difference is +how many lines of code you are saving. +**Proposal** for a better layout in which we don't need to explicitly shadow +from level to level (and we don't need to route with `if` as well) are liked and +likeòy to be accepted. + +Note 2 (caching) +---------------- +Since the responsibility of caching is of SF as written above we decided the +following layout: + +- SF instantiate ESF or ESFTMC according to TMC flag in theory dictionary, + and append it to `self.__ESFs` at load time, i.e. in `self.load()` (these + are the observables to be computed) +- when asked for output if noTMC a ESF is called and the instance is + registered + + - `self.get_ouput()` is used for getting the result passing through: + - `self.get_ESF()` is used for getting the instance and register to the + cache + +- if TMC a ESFTMC is called, and whenever he needs an ESF instance to + compute a point it will ask its parent SF with `SF.get_ESF()` method, in + this way passing through the cache + +Note 3 (physics) +---------------- +There 3 schemes in the reference: + +- **exact**: is the full and involves integration +- **approximate**: is stemming from the exact, but the strcture functions in + the integrand are evaluated at the bottom end +- **APFEL**: the one used in APFEL, similar to the exact but with g2 in + the review (Schienbein et al.) set to 0 diff --git a/src/yadism/structure_functions/TMC.py b/src/yadism/structure_functions/TMC.py index 70c63bf6b..e8147ad54 100644 --- a/src/yadism/structure_functions/TMC.py +++ b/src/yadism/structure_functions/TMC.py @@ -1,60 +1,28 @@ # -*- coding: utf-8 -*- """ -Runner: holds a list of structure functions instances, that will act as our -"soft singletons" -StructureFunction: holds a reference to his parent runner, in this way its also -able to access its StructureFunctions siblings (like F2 from FL, in order to -compute TMCs, e.g.) - -Caching: it is managed at the level of StructureFunction, while the values are -kept at the level of ESF (so the StructureFunction is just routing the caller to -the correct instance of ESF to ask for values) - -Note 1 ------- -Here is the third time that we are proliferating the SF classes to all the -flavours and kinds (SF/ESFTMC/ESF x 2/L x light/c/b/t), but at the bottom level -they are needed (ESF implementation are actually different for every option, so -it makes sense to have different classes). -The classes one level above (SF/ESFTMC) are simply shadowing the ones below in -order to route to the correct one. The same business can be done with a `switch` -pattern (actually `if...elif...elif...` in python), but the only difference is -how many lines of code you are saving. -**Proposal** for a better layout in which we don't need to explicitly shadow -from level to level (and we don't need to route with `if` as well) are liked and -likeòy to be accepted. - -Note 2 (caching) ----------------- -Since the responsibility of caching is of SF as written above we decided the -following layout: - -- SF instantiate ESF or ESFTMC according to TMC flag in theory dictionary, - and append it to `self.__ESFs` at load time, i.e. in `self.load()` (these - are the observables to be computed) -- when asked for output if noTMC a ESF is called and the instance is - registered - - - `self.get_ouput()` is used for getting the result passing through: - - `self.get_ESF()` is used for getting the instance and register to the - cache - -- if TMC a ESFTMC is called, and whenever he needs an ESF instance to - compute a point it will ask its parent SF with `SF.get_ESF()` method, in - this way passing through the cache - -Note 3 (physics) ----------------- -There 3 schemes in the reference: - -- **exact**: is the full and involves integration -- **approximate**: is stemming from the exact, but the strcture functions in - the integrand are evaluated at the bottom end -- **APFEL**: the one used in APFEL, similar to the exact but with g2 in - the review (Schienbein et al.) set to 0 - -.. todo:: - docs +This module contain the implementation of target mass corrections (TMC). For an +introduction about TMC and also implementation details see :ref:`tmc-page`. + +Three classes are here defined: + + - :py:class:`EvaluatedStructureFunctionTMC` is the abstract class defining + the machinery for TMC calculation + - :py:class:`ESFTMC_F2` and :py:class:`ESFTMC_FL` implements the previous + one, making use of its machinery as building blocks for the actual + expressions for TMC + +The three structures presented play together the role of an intermediate block +between the :py:class:`StructureFunction` interface (used to manage user request +for DIS observables) the actual calculator +:py:class:`EvaluatedStructureFunction`, or even better they can be seen as a +replacement for the latter, that makes use of that one under the hood. + +Indeed TMC corrected structure functions are defined on top of the "bare" ones, +and one of their main features is that their expression is a functione of the +"bare" themselves, but evaluated to a shifted kinematics (w.r.t. to the one +asked by the user, that is the physical kinematic point at which one would like +to evaluate the physical structure function). + """ import abc import warnings @@ -68,12 +36,38 @@ class EvaluatedStructureFunctionTMC(abc.ABC): - """ - .. todo: - docs + r""" + This is an abstract class, made to serve the machinery to the inheriting + classes. In particular here are defined: + + - shifted kinematics :math:`\xi` and other aux variables + (:math:`\mu` and :math:`\rho`, see :cite:`tmc-iranian`) + - integration layout and two common integrals of structure + functions, :math:`h_2` and :math:`g_2` (see :cite:`tmc-review`) + - an interface for picking up the chosen formulas between: + + - *APFEL* + - *approximate* + - *exact* + + (see :cite:`tmc-iranian`) + + Parameters + ---------- + SF : StructureFunction + the interface object representing the structure function kind he + belongs to + kinematics : dict + requested kinematic point + """ def __init__(self, SF, kinematics): + """ + Just store the input and compute some auxiliary variables, no + integration performed here. + + """ self._SF = SF self._flavour = SF._name[2:] self._x = kinematics["x"] From 578f7cbfa6b73018971ceba456089cd9a849cfa8 Mon Sep 17 00:00:00 2001 From: AleCandido Date: Mon, 1 Jun 2020 11:42:09 +0200 Subject: [PATCH 2/5] Add .github/codecov.yml --- .github/codecov.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/codecov.yml diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 000000000..309a8c0bb --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,34 @@ +# Reference docs at: +# https://docs.codecov.io/docs/codecovyml-reference + +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "70...100" + status: + project: + default: + branches: + - master + - "feature/*" + - "release/*" + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "reach,diff,flags,tree" + behavior: default + require_changes: no + branches: + - master + - "feature/*" + - "release/*" From 2342ac0879461f0b2a750351891c6988a8270cff Mon Sep 17 00:00:00 2001 From: AleCandido Date: Mon, 1 Jun 2020 11:48:18 +0200 Subject: [PATCH 3/5] Update codecov.yml --- .github/codecov.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index 309a8c0bb..a504b1534 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -11,6 +11,8 @@ coverage: status: project: default: + # check only master and branches that should be merged directly into + # master branches: - master - "feature/*" @@ -28,7 +30,10 @@ comment: layout: "reach,diff,flags,tree" behavior: default require_changes: no - branches: - - master - - "feature/*" - - "release/*" + # comments in the pull request are not preventing the merge, and can be + # useful to detect dropping in unit and regression tests since they are + # individually reported [so keep the following option commented] + #branches: + #- master + #- "feature/*" + #- "release/*" From 7309ca5a73b2a926e707eab6adb6a72aa7ca90af Mon Sep 17 00:00:00 2001 From: AleCandido Date: Mon, 1 Jun 2020 12:47:32 +0200 Subject: [PATCH 4/5] Add docstrings to the TMC parent class getters --- docs/sphinx/source/refs.bib | 10 ++++ src/yadism/structure_functions/tmc.py | 74 +++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/docs/sphinx/source/refs.bib b/docs/sphinx/source/refs.bib index 1412d63f0..a2ae7ba50 100644 --- a/docs/sphinx/source/refs.bib +++ b/docs/sphinx/source/refs.bib @@ -89,3 +89,13 @@ @article{tmc-iranian volume = "101", year = "2020" } +@article{tmc-georgi, + author = "Georgi, Howard and Politzer, H.David", + title = "{Freedom at Moderate Energies: Masses in Color Dynamics}", + reportNumber = "Print-76-0479 (HARVARD)", + doi = "10.1103/PhysRevD.14.1829", + journal = "Phys. Rev. D", + volume = "14", + pages = "1829", + year = "1976" +} diff --git a/src/yadism/structure_functions/tmc.py b/src/yadism/structure_functions/tmc.py index 083213b04..d123aa647 100644 --- a/src/yadism/structure_functions/tmc.py +++ b/src/yadism/structure_functions/tmc.py @@ -81,28 +81,70 @@ def __init__(self, SF, kinematics): @abc.abstractmethod def _get_result_APFEL(self): """ - .. todo: - docs + This method is defined by subclasses to provide the implementation + of TMC calculation according to the same formula used by APFEL, see + :cite:`???` + + .. todo:: + + - APFEL TMC reference missing + """ @abc.abstractmethod def _get_result_approx(self): """ - .. todo: - docs + This method is defined by subclasses to provide the implementation + of TMC calculation according to the approximate formula defined in + :eqref:`4` in :cite:`tmc-iranian`, and already presented in + :cite:`tmc-review`. + + The convenience of this formula is that the integration is + approximate by a simple evaluation of the integrand in a suitable + point, so the evaluation of the full expression is much faster + (because integration yields an array of evaluations, ranging from 1 + to the `xgrid` length). + Despite the approximation the formula is quite in a good agreement + with the exact one (for comparison see :cite:`tmc-review`). + """ @abc.abstractmethod def _get_result_exact(self): """ - .. todo: - docs + This method is defined by subclasses to provide the implementation + of TMC calculation according to the exact formula defined in + :eqref:`2` in :cite:`tmc-iranian`, and already presented in + :cite:`tmc-review` and older literature like :cite:`tmc-georgi`. + + Note + ---- + This method will always involve an integration (and more than one + according to the structure function). If this is to expensive check + :py:meth:`_get_result_approx`. + """ def get_result(self): """ - .. todo: - docs + This is the interfaces provided to get the evaluation of the TMC + corrected structure function. + + The kinematics is set to be the requested one, as it should (and not + the shifted one used in evaluation of expression terms). + + Returns + ------- + out : ESFResult + an object that stores the details and result of the calculation + + Note + ---- + Another interfaces is provided, :py:meth:`get_output`, that makes + use of this one, so results of the two are consistent, but simply + output in a different format (see :py:class:`ESFResult`, and its + :py:meth:`ESFResult.get_raw` method). + """ if self._SF.TMC == 0: # no TMC raise RuntimeError( @@ -125,8 +167,20 @@ def get_result(self): def get_output(self): """ - .. todo:: - docs + This is the interfaces provided to get the evaluation of the TMC + corrected structure function. + + The kinematics is set to be the requested one, as it should (and not + the shifted one used in evaluation of expression terms). + + This method is the sibling of :py:meth:`get_result`, providing a + :py:class:`dict` as output, instead of an object. + + Returns + ------- + out : dict + an dictionary that stores the details and result of the calculation + """ return self.get_result().get_raw() From 1f56c51e7292e1a5cc287729657554f89a59d622 Mon Sep 17 00:00:00 2001 From: AleCandido Date: Thu, 11 Jun 2020 17:32:10 +0200 Subject: [PATCH 5/5] Complete missing TMC docstrings --- docs/sphinx/source/conf.py | 1 + docs/sphinx/source/index.rst | 4 +- docs/sphinx/source/shared/abbreviations.rst | 3 + docs/sphinx/source/yadism.rst | 4 +- src/yadism/structure_functions/tmc.py | 105 ++++++++++++++++---- 5 files changed, 95 insertions(+), 22 deletions(-) diff --git a/docs/sphinx/source/conf.py b/docs/sphinx/source/conf.py index 36e6a48bb..4015fbfc7 100644 --- a/docs/sphinx/source/conf.py +++ b/docs/sphinx/source/conf.py @@ -253,6 +253,7 @@ # "members": "var1, var2", # "member-order": "bysource", "special-members": True, + "private-members": True, # "inherited-members": True, # "undoc-members": True, "exclude-members": "__weakref__, __init__, __dict__, __module__" diff --git a/docs/sphinx/source/index.rst b/docs/sphinx/source/index.rst index 86a16a7ca..d07a94778 100644 --- a/docs/sphinx/source/index.rst +++ b/docs/sphinx/source/index.rst @@ -30,8 +30,8 @@ Features ~~~~~~~~ Current features: -- |LO| structure functions (|NC|) -- |NLO| structure functions (|NC|) +- |LO| structure functions (|EM|) +- |NLO| structure functions (|EM|) - |NLO| scale variations diff --git a/docs/sphinx/source/shared/abbreviations.rst b/docs/sphinx/source/shared/abbreviations.rst index e2f3d989f..0af8060e8 100644 --- a/docs/sphinx/source/shared/abbreviations.rst +++ b/docs/sphinx/source/shared/abbreviations.rst @@ -10,6 +10,9 @@ .. |NC| replace:: :abbr:`NC (Neutral Current)` +.. |EM| replace:: + :abbr:`EM (Electromagnetic Current)` + .. ------------------- perturbative orders ------------------- diff --git a/docs/sphinx/source/yadism.rst b/docs/sphinx/source/yadism.rst index e3647c08b..89f7adac2 100644 --- a/docs/sphinx/source/yadism.rst +++ b/docs/sphinx/source/yadism.rst @@ -15,8 +15,8 @@ The :eqref:`2.3`. |DIS| .. toctree:: :maxdepth: 2 - Structure - API + Structure + API .. todo:: diff --git a/src/yadism/structure_functions/tmc.py b/src/yadism/structure_functions/tmc.py index d123aa647..25b624f7c 100644 --- a/src/yadism/structure_functions/tmc.py +++ b/src/yadism/structure_functions/tmc.py @@ -45,9 +45,9 @@ class EvaluatedStructureFunctionTMC(abc.ABC): functions, :math:`h_2` and :math:`g_2` (see :cite:`tmc-review`) - an interface for picking up the chosen formulas between: - - *APFEL* - - *approximate* - - *exact* + 1. *APFEL* + 2. *approximate* + 3. *exact* (see :cite:`tmc-iranian`) @@ -185,11 +185,39 @@ def get_output(self): return self.get_result().get_raw() def _convolute_F2(self, ker): - """ - Convolute F2 and ker. + r""" + Implement generic structure to convolute any function `ker` with `F2`. + + This method is provided for internal use, in order to factorize the + machinery for TMC integrals. + The implementation is flavor transparent, in the sense that takes + any flavor from up and it's passing it down in the call for a + proper F2 instance (done by using :py:meth:`self._SF.get_ESF`). + + The integration is made over the interpolation basis, postponing the + once more the the contraction with the PDF. + + .. math:: + :nowrap: + + \begin{align*} + \tilde{F}_X \otimes f &= \sum_i (\tilde{F}_X \otimes w_i) f_i = + \left[ a + \sum_{i} ((F_2 \otimes k) \otimes w_i) + \right] f_i \\ + & = \left[ a + \sum_{i,j} \underbrace{{F_2}_j ((w_j \otimes + k)}_{\texttt{_convolute_F2}} \otimes w_i) \right] f_i + \end{align*} + + where :math:`\tilde{F}_X` is the target mass corrected structure + function, :math:`F_2` is the bare structure function, :math:`k` is + the kernel function `ker`, and :math:`a` is representing all the + other terms not described here. + + Parameters + ---------- + ker : callable + the kernel function to be convoluted with `F2` - .. todo:: - docs """ # check domain if self._xi < min(self._SF.interpolator.xgrid_raw): @@ -216,12 +244,17 @@ def _convolute_F2(self, ker): def _h2(self): r""" - Compute raw integral over F2. + Compute raw integral over `F2`, making use of :py:meth:`_convolute_F2`. .. math:: - h_2(\xi,Q^2) &= \int_\xi^1 du \frac{F_2^(u,Q^2)}{u^2} - &= \int_\xi^1 \frac{du}{u} \frac{1}{\xi} \frac{\xi}{u} F_2^(u,Q^2) + :nowrap: + + \begin{align*} + h_2(\xi,Q^2) &= \int_\xi^1 du \frac{F_2(u,Q^2)}{u^2}\\ + &= \int_\xi^1 \frac{du}{u} \frac{1}{\xi} + \frac{\xi}{u} F_2(u,Q^2)\\ &= ((z\to z/\xi) \otimes F_2(z))(\xi) + \end{align*} Returns ------- @@ -236,12 +269,18 @@ def _h2(self): def _g2(self): r""" - Compute nested integral over F2. + Compute nested integral over `F2`, making use of :py:meth:`_convolute_F2`. .. math:: - g_2(\xi,Q^2) &= \int_\xi^1 du (u-\xi) \frac{F_2^(u,Q^2)}{u^2} - &= \int_\xi^1 \frac{du}{u} \left(1 - \frac{\xi}{u}\right) F_2^(u,Q^2) - &= ((z\to 1-z) \otimes F_2(z))(\xi) + :nowrap: + + \begin{align*} + g_2(\xi,Q^2) &= \int_\xi^1 du (u-\xi) + \frac{F_2(u,Q^2)}{u^2}\\ + &= \int_\xi^1 \frac{du}{u} \left(1 - + \frac{\xi}{u}\right) F_2(u,Q^2)\\ + &= ((z\to 1-z) \otimes F_2(z))(\xi) + \end{align*} Returns ------- @@ -257,8 +296,18 @@ def _g2(self): class ESFTMC_F2(EvaluatedStructureFunctionTMC): """ - .. todo:: - docs + This function implements the actual formula for target mass corrections + of F2, for all the three (+1) kinds described in the parent class + :py:class:`EvaluatedStructureFunctionTMC`. + + Parameters + ---------- + SF : StructureFunction + the interface object representing the structure function kind he + belongs to + kinematics : dict + requested kinematic point + """ def __init__(self, SF, kinematics): @@ -310,7 +359,7 @@ def _get_result_exact(self): self._factor_shifted * F2out + self._factor_h2 * h2out + factor_g2 * g2out ) - ### ----- APFEL crap + ### ----- APFEL stuffs def _get_result_APFEL_strict(self): # interpolate F2(xi) F2list = [] @@ -344,10 +393,25 @@ def _get_result_APFEL_strict(self): # join return res - ### ----- /APFEL crap + ### ----- /APFEL stuffs class ESFTMC_FL(EvaluatedStructureFunctionTMC): + """ + This function implements the actual formula for target mass corrections + of FL, for all the three (+1) kinds described in the parent class + :py:class:`EvaluatedStructureFunctionTMC`. + + Parameters + ---------- + SF : StructureFunction + the interface object representing the structure function kind he + belongs to + kinematics : dict + requested kinematic point + + """ + def __init__(self, SF, kinematics): super(ESFTMC_FL, self).__init__(SF, kinematics) # shifted prefactor is common @@ -404,3 +468,8 @@ def _get_result_exact(self): ESFTMCmap = {"F2": ESFTMC_F2, "FL": ESFTMC_FL} +"""dict: mapping of ESF TMC classes + +This dictionary is used to redirect to the correct class from a string +indicating the kind of the required structure function. +"""