Skip to content

Commit

Permalink
Merge pull request #1979 from NNPDF/nnpdfpol
Browse files Browse the repository at this point in the history
Polarised proton fits
  • Loading branch information
Radonirinaunimi authored Apr 22, 2024
2 parents 6c63d8c + abe5d46 commit 546bb90
Show file tree
Hide file tree
Showing 62 changed files with 3,614 additions and 273 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/fitbot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
env:
N3FIT_MAXNREP: 20 # total number of replicas to fit
POSTFIT_NREP: 16 # requested replicas for postfit
REFERENCE_SET: NNBOT-9fded1f04-2024-03-29 # reference set for exact results
REFERENCE_SET: NNBOT-489c196ac-2024-04-18 # reference set for exact results
STABLE_REFERENCE_SET: NNBOT-c0f99b7b3-2024-02-28 # reference set for last tag
CONDA_PY: 312
PYTHONHASHSEED: "0"
Expand Down
1 change: 1 addition & 0 deletions doc/sphinx/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Running fits
./run-fit.md
./run-iterated-fit.rst
./run-qed-fit.rst
./polarized_fits.rst
./general_th_covmat.rst
./thcov_tutorial.rst

Expand Down
123 changes: 123 additions & 0 deletions doc/sphinx/source/tutorials/polarized_fits.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
.. _polarized:

How to run a Polarized fit
==========================

The user should first refer to the :ref:`detailed guide <n3fit-usage>` on how to run
a standard unpolarized PDF fit. Most of the steps in that guide still apply here and
in the following section we only highlight the differences.


Preparing a runcard and running a fit
-------------------------------------

The writing of a polarized fit runcard follows exactly the guideline described
in :ref:`Preparing a fit runcard <prepare-fits>`. The user only needs to modify
and adjusts various entries.

In polarized fits, the positivity of the polarized PDFs are enforced using as
a boundary condition an unpolarized PDF set. The information on how such a
constraint is enforced is defined under the key ``positivity_bound`` as follows:

.. code-block:: yaml
# Define the unpolarized PDF set to be used as BC for positivity
...
positivity_bound:
unpolarized_bc: NNPDF40_nnlo_pch_as_01180
n_std: 1.00 # Standard Deviation to be added as Shift
...
where ``unpolarized_bc`` specifies the name of the unpolarized PDF set to be used
as a boundary condition while ``n_std`` specifies the shift in terms of the standard
deviation to be applied to the PDF central values. If ``n_std=0.0`` then the
PDF central values will be used to constrain their polarized counterparts.

Given that polarized fits require different fitting bases and different theory
constraints, the fields under the ``fitting`` key require some adjustments.
Specifically:

.. code-block:: yaml
...
fitting:
fitbasis: POLARIZED_EVOL
sum_rules: TSR
basis:
- {fl: sng, trainable: false, smallx: [1.094, 1.118], largex: [1.46, 3.003]}
- {fl: g, trainable: false, smallx: [0.8189, 1.844], largex: [2.591, 5.697]}
- {fl: t3, trainable: false, smallx: [-0.4401, 0.9163], largex: [1.773, 3.333]}
- {fl: t8, trainable: false, smallx: [0.5852, 0.8537], largex: [1.533, 3.436]}
...
where ``TSR`` specifies that only sum rules on the :math:`T_3` and :math:`T_8`
distributions are applied. If any of these values are specified differently the program will
raise an error. Note that for polarized fits, the basis name has to start with ``POLARIZED_``
and then followed by the basis type (for example ``EVOL`` or ``FLAVOUR``).

.. note::

While the treatment of integrability follows exactly the same concept as in the
default unpolarized fits, the treatment of positivity in the polarized case
requires specific treatment. Similar to the unpolarized fits, the cost function
used to enforce the positivity is defined by the following quantity:

.. math::
\chi_{\mathrm{tot}}^2 \rightarrow \chi_{\mathrm{tot}}^2+ \Lambda_{\rm POS} \sum_{k=1}^8 \sum_{i=1}^{n_x} \operatorname{ReLU}\left(-\mathcal{C}_k\left(x_i, Q^2\right)\right)
where:

.. math::
\mathrm{ReLU}(t)= \begin{cases}t & \text { if } t>0 \\ 0 & \text { if } t \leq 0\end{cases}
with :math:`n_i=20` and :math:`Q^2=5~\mathrm{GeV}^2` chosen to be the same as in the unpolarized
case. In the polarized case, omitting the :math:`Q^2`-dependence, the expression of :math:`\mathcal{C}_k`
is rather given by:

.. math::
\mathcal{C}_k(x_i) = \mathcal{F}_k(x_i) + \Sigma_k(x_i) - | \Delta \mathcal{F}_k(x_i) |
where :math:`\Sigma_k(x_i)` represents the one standard deviation error computed at
:math:`x_i` for the flavour :math:`k`. :math:`(\Delta) \mathcal{F}_k` can be a (p)PDF of
flavour :math:`k` or the longitudinally (polarized) structure functions :math:`(k=1)`.
The way in which the unpolarized prediction uncertainties are accounted for during
the fit is by sampling according to a normal distribution and ought to enforce the
following inequality:

.. math::
\mathcal{N}_r \left( \mathcal{F}_k, \Sigma_k^2 \right) - | \Delta \mathcal{F}_k | \geq 0
where the subscript :math:`r` indicates that the random seed per replica is always
different. In practice, when imposing the positivity at the level of PDFs, we enforce
the constraints on the flavor combination :math:`\left( \Delta f_i + \Delta \bar{f}_i \right)`,
that is :math:`(\Delta) \mathcal{F}_k \equiv (\Delta) f_k + (\Delta) \bar{f}_k`.

Once the runcard is ready, the user can follow the guidelines :ref:`here <run-n3fit-fits>`
to set up and run fits.


Evolving the fit
----------------

In order to evolve the fitted replicas, we have to use the polarized DGLAP evolution. This
can simply be done by supplementing a flag to the ``evolven3fit``:

.. code-block:: bash
evolven3fit evolve $runcard_folder --use_polarized
Alternatively, the user can explicitly specify the path to the EKO using the flag ``--load``.


Comparing polarized fits
------------------------

Additionally, a specific report template should be used when comparing two polarized
fits. This can be done by simply using the ``--use_polarized`` when calling ``vp-comparefits``:

.. code-block:: bash
vp-comparefits -i --use_polarized
To read in details on how to compare two fits, head to the :ref:`following <compare-fits>`
documentation.
4 changes: 4 additions & 0 deletions doc/sphinx/source/tutorials/run-fit.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ The fitting methodology is detailed in the [Methodology](methodology) page.
- [Upload and analyse the fit](#upload-and-analyse-the-fit)


```eval_rst
.. _prepare-fits:
```

Preparing a fit runcard
-----------------------

Expand Down
1 change: 1 addition & 0 deletions extra_tests/regression_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"trainable_prepro": 61,
"no_lagrange": 27,
"no_csr": 613,
"polarized_evol": 34,
"single_dense": 316,
}

Expand Down
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/central_16.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@
],
"timing": {
"walltime": {
"Total": 29.638298988342285,
"Total": 32.32825946807861,
"start": 0.0,
"replica_set": 0.2522115707397461,
"replica_fitted": 29.6381618976593,
"replica_set_to_replica_fitted": 29.385950326919556
"replica_set": 0.23800349235534668,
"replica_fitted": 32.32805871963501,
"replica_set_to_replica_fitted": 32.09005522727966
},
"cputime": {
"Total": 31.201514887000002,
"Total": 33.586156003,
"start": 0.0,
"replica_set": 0.5735468639999999,
"replica_fitted": 31.201376138,
"replica_set_to_replica_fitted": 30.627829274
"replica_set": 0.23583456399999925,
"replica_fitted": 33.585950811000004,
"replica_set_to_replica_fitted": 33.350116247
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/diagonal_45.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@
],
"timing": {
"walltime": {
"Total": 29.0417582988739,
"Total": 31.026511907577515,
"start": 0.0,
"replica_set": 0.24686527252197266,
"replica_fitted": 29.04159164428711,
"replica_set_to_replica_fitted": 28.794726371765137
"replica_set": 0.22557783126831055,
"replica_fitted": 31.026363611221313,
"replica_set_to_replica_fitted": 30.800785779953003
},
"cputime": {
"Total": 30.396234212999996,
"Total": 32.27932530699999,
"start": 0.0,
"replica_set": 0.5666455580000003,
"replica_fitted": 30.396064907,
"replica_set_to_replica_fitted": 29.829419349
"replica_set": 0.2244609740000003,
"replica_fitted": 32.279174556,
"replica_set_to_replica_fitted": 32.054713582
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/feature_scaling_81.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@
],
"timing": {
"walltime": {
"Total": 29.385473251342773,
"Total": 33.15795373916626,
"start": 0.0,
"replica_set": 0.2618255615234375,
"replica_fitted": 29.38529133796692,
"replica_set_to_replica_fitted": 29.12346577644348
"replica_set": 0.24506402015686035,
"replica_fitted": 33.15779399871826,
"replica_set_to_replica_fitted": 32.9127299785614
},
"cputime": {
"Total": 30.624417034000004,
"Total": 32.71397760399999,
"start": 0.0,
"replica_set": 0.5652710770000002,
"replica_fitted": 30.62423277,
"replica_set_to_replica_fitted": 30.058961692999997
"replica_set": 0.2428332590000002,
"replica_fitted": 32.71381593300001,
"replica_set_to_replica_fitted": 32.470982674000005
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/flavour_29.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@
],
"timing": {
"walltime": {
"Total": 7.07843017578125,
"Total": 7.731718301773071,
"start": 0.0,
"replica_set": 0.2522542476654053,
"replica_fitted": 7.078283309936523,
"replica_set_to_replica_fitted": 6.826029062271118
"replica_set": 0.2266373634338379,
"replica_fitted": 7.731366872787476,
"replica_set_to_replica_fitted": 7.504729509353638
},
"cputime": {
"Total": 7.514604531,
"Total": 7.901237213,
"start": 0.0,
"replica_set": 0.5747256410000006,
"replica_fitted": 7.514455934000001,
"replica_set_to_replica_fitted": 6.939730293
"replica_set": 0.22565210800000024,
"replica_fitted": 7.900883664,
"replica_set_to_replica_fitted": 7.675231556
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/no_csr_613.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,24 @@
],
"timing": {
"walltime": {
"Total": 27.847703218460083,
"Total": 31.898317337036133,
"start": 0.0,
"replica_set": 0.2785060405731201,
"replica_fitted": 27.847578287124634,
"replica_set_to_replica_fitted": 27.569072246551514
"replica_set": 0.2562828063964844,
"replica_fitted": 31.898224592208862,
"replica_set_to_replica_fitted": 31.641941785812378
},
"cputime": {
"Total": 28.899172986,
"Total": 32.496953049,
"start": 0.0,
"replica_set": 0.5995310260000002,
"replica_fitted": 28.899045308,
"replica_set_to_replica_fitted": 28.299514282
"replica_set": 0.25330967699999984,
"replica_fitted": 32.496857621,
"replica_set_to_replica_fitted": 32.243547944
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
20 changes: 10 additions & 10 deletions extra_tests/regression_fits/no_lagrange_27.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@
],
"timing": {
"walltime": {
"Total": 33.39091753959656,
"Total": 37.980634450912476,
"start": 0.0,
"replica_set": 0.2545652389526367,
"replica_fitted": 33.390822649002075,
"replica_set_to_replica_fitted": 33.13625741004944
"replica_set": 0.22922587394714355,
"replica_fitted": 37.98039174079895,
"replica_set_to_replica_fitted": 37.75116586685181
},
"cputime": {
"Total": 34.736605786000005,
"Total": 39.138274702000004,
"start": 0.0,
"replica_set": 0.566752718,
"replica_fitted": 34.736509046,
"replica_set_to_replica_fitted": 34.169756328
"replica_set": 0.22799105100000006,
"replica_fitted": 39.138029595,
"replica_set_to_replica_fitted": 38.910038543999995
}
},
"version": {
"tensorflow": "2.16.1, mkl=??",
"numpy": "1.26.4",
"nnpdf": "4.0.9.post446.dev0+264ada234",
"validphys": "4.0.9.post446.dev0+264ada234"
"nnpdf": "4.0.9.post576.dev0+47a077fe1",
"validphys": "4.0.9.post576.dev0+47a077fe1"
}
}
Loading

0 comments on commit 546bb90

Please sign in to comment.