Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e135fd6
Making the photon a downloadable resource
achiefa Oct 30, 2025
83d6662
Add photon resource to nnprofile
achiefa Oct 30, 2025
dbf92e3
Utility script to run FiatLux
achiefa Oct 30, 2025
5fe1213
Remove debugger
achiefa Oct 30, 2025
2fd90aa
Allow force computation
achiefa Oct 30, 2025
d191408
Apply suggestions + download
achiefa Nov 4, 2025
72d419a
Restore check for photon [skip ci]
achiefa Nov 4, 2025
bdc7042
Fix compute + index photon
achiefa Nov 4, 2025
a731ac6
Change name when photon is computed
achiefa Nov 4, 2025
3a0c209
Addtional errors added in fiatlux exec
achiefa Nov 5, 2025
541bbd1
Fixing names for photon resource
achiefa Nov 6, 2025
1dc141a
Make photon downloadable from vp-setupfit only
achiefa Nov 6, 2025
5eaa668
Moving photon computation into vp-setupfit
achiefa Nov 12, 2025
9efa4e2
force_compute only if specified by the user
achiefa Nov 12, 2025
b5e5180
Correct path to photon
achiefa Nov 12, 2025
5b59615
Add photon path to profile utils
achiefa Nov 12, 2025
169f6c4
Move joblib outside the Photon class
achiefa Nov 13, 2025
9464d0b
Fix shape in photon computation
achiefa Nov 13, 2025
32ec19e
Fixing self.lux -> lux
achiefa Nov 13, 2025
ff13285
Remove unused imports
achiefa Nov 13, 2025
1fb51c8
Avoid pickling issues with joblib
achiefa Nov 13, 2025
38dfd1b
Remove fiatlux-exec from pyproject
achiefa Nov 18, 2025
d969ca7
Move loader initialization inside function calls
achiefa Nov 18, 2025
4860d8e
Add check for non-photon resources
achiefa Nov 18, 2025
fe7330a
Use maxcores + rename function that computes the photon
achiefa Nov 18, 2025
1f628b7
Change log message depending on flag
achiefa Nov 18, 2025
0a8508b
Refactoring Photon + one EKO for all replicas
achiefa Nov 25, 2025
d0a21cf
Pre-commit
achiefa Nov 25, 2025
b6770f4
Storing photon replicas in a dictionary
achiefa Nov 26, 2025
fab60cd
Upload documentation
achiefa Dec 18, 2025
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
234 changes: 217 additions & 17 deletions doc/sphinx/source/tutorials/run-qed-fit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,232 @@
==========================
How to run a QED fit
==========================
This tutorial describes how to run a QED fit using the LuxQED approach, as
described in `arXiv:1607.04266 <https://arxiv.org/abs/1607.04266>`_ and
`arXiv:1708.01256 <https://arxiv.org/abs/1708.01256>`_.

It is possible to perform a QED fit adding the key ``fiatlux`` to the runcard. In this way
a photon PDF will be generated using the FiatLux public library that implements the LuxQED
(see :cite:p:`Manohar:2016nzj` and :cite:p:`Manohar:2017eqh`) approach.
The parameters to be added are the following:
Setting up the runcard
----------------------

It is possible to perform a QED fit by adding a ``fiatlux`` block to the
runcard. The following code snippet shows an example of a QED fit configuration:

.. code-block:: yaml
fiatlux:
luxset: NNPDF40_nnlo_as_01180
luxset: 251127-jcm-lh-qed-001
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
luxset: 251127-jcm-lh-qed-001
luxset: NNPDF40_nnlo_as_01180_qcd

I only added that for testing.

additional_errors: true
luxseed: 1234567890
``luxset`` is the PDF set used to generate the photon PDF with `FiatLux <https://github.com/scarrazza/fiatlux/>`.
The code will generate as many photon replicas as the number of replicas contained in the ``luxset``. Therefore, if the user
tries to generate a replica with ID higher than the maximum ID of the ``luxset``, the code will
raise an error. Moreover, being the LuxQED approach an iterated prcedure, and given that some replicas
do not pass the ``postfit`` selection criteria, the user should make sure that the number of replicas in
the ``luxset`` is high enough such that in the final iteration there will be a number of replicas
higher than the final replicas desired.
``additional_errors`` is a parameter that switches on and off the additional errors of the LuxQED approach,
while ``luxseed`` is the seed used to generate such errors.
This errors should be switched on only in the very last iteration of the procedure.
The parameters contained in the ``fiatlux`` block are:

* ``luxset``
The name of the PDF set used to generate the photon PDF with `FiatLux
<https://github.com/scarrazza/fiatlux/>`_. The code will use as many
photon replicas as the number of replicas contained in the ``luxset``. If
the user tries to generate a replica with ID higher than the maximum ID of
the ``luxset``, the code will start reusing photon replica from the first.
Being the LuxQED approach an iterated procedure, and given that some
replicas do not pass the ``postfit`` selection criteria, the user should
make sure that the number of replicas in the ``luxset`` is high enough
such that in the final iteration there will be a number of replicas higher
than the final replicas desired.

* ``additional_errors``
Boolean flag to switch on and off the additional errors of the LuxQED approach.

.. note::

The ``additional_errors`` flag should be switched on only in the very last
iteration of the procedure.

* ``luxseed``
The seed used to generate the additional errors of the LuxQED as in ``additional_errors``.

The code uses both the ``fiatlux`` block and the ``theoryid`` specified in the
runcard to identify the photon PDF set. As explained below, the code searches
for precomputed photon PDF sets using the pair of ``luxset`` and ``theoryid``
parameters, first locally and then on the NNPDF server (see
:ref:`photon-resources` for details). The photon PDF set will be named
``photon_theoryID_<theoryid>_fit_<luxset>``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the compute in setupfit flag also feature here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, maybe. This part focuses only on the creation of the runcard. The compute_in_setupfit flag is needed if the user wants to compute the photon from scratch. But this is required only if the photon is not already stored in the remote. That's why I opted for the following reasoning order:

Setting up the runcard --> check and collect available resources --> Compute missing resources.

Maybe the wording is a bit misleading at this stage of the tutorial because the user is not yet aware of the possibility of either downloading/storing available resources or computing resources from scratch. Maybe something like that, which introduces the two possibilities, sounds better:

The code uses both the ``fiatlux`` block and the ``theoryid`` specified in the
runcard to identify the photon PDF set, which will be assigned the name
``photon_theoryID_<theoryid>_fit_<luxset>``. This name will be used to either
look for existing photon PDF sets or to store newly generated ones, as explained
below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it is a flag for the dictionary fiatlux.


.. _photon-resources:

Running with Photon PDF sets
-----------------------------

The generation of a photon PDF set can add significant overhead to the fitting
procedure. Moreover, the same photon PDF set might be used in different fits. To
minimize the overhead due to the generation of photon PDF sets and avoid
redundant computations, the code looks for precomputed photon resources either
locally or on the NNPDF server. If a desired photon PDF set does not exist in
either of the two locations, it will be computed on the fly and stored locally.
The following sections describe how to use existing photon PDF sets or generate
new ones.

Using available Photon PDF sets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before running a QED fit, it is strongly advised to prepare the fit using
``vp-setupfit``, as explained in :ref:`this tutorial <run-n3fit-fit>`. This will
ensure that all the required resources are available, including the photon PDF.
The desired photon PDF is specified by the ``luxset`` parameter in the
``fiatlux`` block and the ``theoryid``, as explained above. The code will first
look for the photon PDF set in the local directory specified in the
:ref:`profile file <nnprofile>`. If the set is not found locally, it will try to
download it from the NNPDF server. The following is an example of running
``vp-setupfit`` using the ``fiatlux`` block shown above:

.. code-block:: bash
$ vp-setupfit qed_example_runcard.yml
[INFO]: Could not find a resource (photonQED): Could not find Photon QED set /user/envs/nnpdf/share/NNPDF/photons_qed/photon_theoryID_702_fit_251127-jcm-lh-qed-001 in theory: 702. Attempting to download it.
[INFO]: Downloading https://data.nnpdf.science/photons/photon_theoryID_702_fit_251127-jcm-lh-qed-001.tar.
[==================================================] (100%)
[INFO]: Extracting archive to /opt/homebrew/Caskroom/miniconda/base/envs/nnpdf/share/NNPDF/photons_qed
[INFO]: Photon QED set found for 702 with luxset 251127-jcm-lh-qed-001.
[WARNING]: Using q2min from runcard
[WARNING]: Using w2min from runcard
Using Keras backend
[INFO]: All requirements processed and checked successfully. Executing actions.
...
This will download and extract the photon PDF set in the local
``photons_qed_path`` specified in the :ref:`profile file <nnprofile>`.

The ``vp-list`` utility tool can be used to list all the available photon PDF
sets locally and on the NNPDF server. To list the available photon PDF sets,
just run:

.. code-block:: bash
$ vp-list photons
[INFO]: The following photons are available locally:
- theoryID_702_fit_251127-jcm-lh-qed-001
[INFO]: The following photons are downloadable:
- theoryID_702_fit_251127-jcm-lh-qed-002
In this example, there is one photon PDF set available locally, and one photon
resource available on the NNPDF server precomputed with theory ID 702 and
``251127-jcm-lh-qed-002`` as input PDF. The user can manually download a photon
PDF set using the ``vp-get`` tool as explained :ref:`here <download>`. For
example:

.. code-block:: bash
$ vp-get photonQED 702 251127-jcm-lh-qed-002
[INFO]: Could not find a resource (photonQED): Could not find Photon QED set /user/envs/nnpdf/share/NNPDF/photons_qed/photon_theoryID_702_fit_251127-jcm-lh-qed-002 in theory: 702. Attempting to download it.
[INFO]: Downloading https://data.nnpdf.science/photons/photon_theoryID_702_fit_251127-jcm-lh-qed-002.tar.
[==================================================] (100%)
[INFO]: Extracting archive to /user/envs/nnpdf/share/NNPDF/photons_qed
PosixPath('/user/envs/nnpdf/share/NNPDF/photons_qed/photon_theoryID_702_fit_251127-jcm-lh-qed-002')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to be this specific, create a photon for NNPDF40_nnlo_as_01180_qed and theoryid 40000100

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the context of a tutorial, I find this level of detail quite suited. If I were an external user, I'd appreciate this one-to-one approach. I agree that if we want to keep this approach, we need existing sets. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with the level of detail. I am less happy about having to be the one creating the sets for the level of detail to apply 🤷‍♂️

Whenever the photon PDF is generated, it will remain constant during the fit and will be considered in the momentum sum rule.
As in the case of ``vp-setupfit``, this will download and extract the photon PDF
set in the local ``photons_qed_path`` specified in the :ref:`profile file <nnprofile>`.
Once the photon PDF set is available locally, the user can proceed to run the
fit with ``n3fit`` as usual.

.. warning::

At the moment it is not possible to run QED fits in parallel, as the FiatLux library cannot run in parallel.
If ``vp-setupfit`` is not run before ``n3fit``, and the photon PDF set is not
available locally, the code will **not** attempt to download it from the server,
but will directly proceed to compute it on the fly. See the :ref:`next section <generating-photon-sets>` for
more details.

.. _generating-photon-sets:
Generating new Photon PDF sets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the desired photon PDF set is not available locally nor on the NNPDF server, the
code will generate the required photon PDF set replicas on the fly using `FiatLux <https://github.com/scarrazza/fiatlux/>`_.
This can be done either during the ``vp-setupfit`` step, which precomputes all photon
replicas before starting the fit, or during the fitting step with ``n3fit``, which
generates the photon replica as needed for each replica being fitted.

.. note::

Generating photon PDF sets on the fly can add significant overhead to the
fitting procedure. It is therefore strongly advised to precompute the photon
PDF set using ``vp-setupfit`` before running the fit with ``n3fit``.

In either case, the generated photon PDF set will be stored locally in the
``photons_qed_path`` specified in the :ref:`profile file <nnprofile>`, so that
it can be reused in future fits. The folder containing the photon replicas will
be named as ``photon_theoryID_<theoryid>_fit_<luxset>`` where ``<theoryid>`` and
``<luxset>`` are the values specified in the runcard. The folder contains a ``npz``
file for each photon replica, named as ``replica_<replica_id>.npz``. Each replica
file contains the photon PDF grid computed with FiatLux at :math:`Q_{\rm init} = 100` GeV,
prior to the evolution through EKO.

.. important::

Automatic upload to the NNPDF server through ``vp-upload`` is **not**
supported at the moment. The user should manually create a ``tar`` archive
file containing the photon replicas and upload it to server. Refer to the
:ref:`profile file <nnprofile>` to find the remote URL where photon PDF sets are stored.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments here

  1. you should mention explicitly the command to run for the .tar because it is not the same to do
tar -cf my_photon.tar my_photon_folder

or

cd my_photon_folder
tar -cf my_photon.tar *.npz

or even

cd my_photon_folder
tar -czf my_photon.tgz *.npz
  1. In the profile you have the URL but you didn't add a photon_target_dir so it is impossible to know where in the server the photon lives!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, why is it not supported? You already have all the infrastructure so it should be easy.

We probably already talked about this but you can think about me like an LLM with about 30 words of memory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, why is it not supported? You already have all the infrastructure, so it should be easy.

We probably already talked about this, but you can think about me like an LLM with about 30 words of memory.

I don't remember the reason, but I'm pretty sure that at some point we agreed on leaving this completely manual because it wasn't a priority :/ But with hindsight, I think at this stage we might want to allow for uploading photon resources using vp-upload, which eases the process by quite a lot.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that at some point we agreed on leaving this completely manual because it wasn't a priority

I agree with my past self and you it isn't, we can do it at a later stage.



Using ``vp-setupfit`` (preferred)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In order to trigger the computation of the photon PDF set during ``vp-setupfit``,
the user needs to add the flag ``compute_in_setupfit: true`` in the ``fiatlux`` block
discussed above. The following is an example of running ``vp-setupfit`` with
this flag enabled:

.. code-block:: bash
$ vp-setupfit qed_example_runcard.yml
[INFO]: Could not find a resource (photonQED): Could not find Photon QED set /user/envs/nnpdf/share/NNPDF/photons_qed/photon_theoryID_703_fit_251127-jcm-lh-qed-001 in theory: 703. Attempting to download it.
[ERROR]: Resource not in the remote repository: Photon QED set for TheoryID 703 and luxset 251127-jcm-lh-qed-001 is not available in the remote server.
[WARNING]: Photon QED set for theory 703 with luxset 251127-jcm-lh-qed-001 not found. It will be computed in vp-setupfit.
[INFO]: Forcing photon computation with FiatLux during setupfit.
[WARNING]: Using q2min from runcard
[WARNING]: Using w2min from runcard
Using Keras backend
[INFO]: All requirements processed and checked successfully. Executing actions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as before.

...
In addition, the user can also specify the optional parameter ``eps_base`` to
the ``fiatlux`` block to set the base precision of the FiatLux computation,
which controls the precision on final integration of double integral. By
default, it is set to ``1e-5``. If the ``compute_in_setupfit`` flag is set to
``true`` despite the photon PDF being available locally, the code will
recompute and overwrite the existing photon PDF set
.. tip::
During ``vp-setupfit``, the code tries to distribute the computation of the
photon replicas among the available CPU cores as specified in the
``maxcores`` key of the runcard. This can significantly speed up the
computation of the photon PDF set. Make sure to set ``maxcores`` to a value
compatible with the available hardware. For example, using ``maxcores: 64``
will try to compute up to 64 photon replicas in parallel using 64 GB of RAM.
Once the preparation step is completed, and the photon PDF set is generated and stored
locally, the user can proceed to run the fit with ``n3fit`` as usual.
Using ``n3fit`` (discouraged)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the user prefers to compute the photon PDF set during the fitting step with
``n3fit``, no additional flag is needed in the runcard and ``vp-setupfit`` is
not required beforehand (unless other resources are needed such as the
:ref:`theory covariance matrix <vptheorycov-index>`). The code will check for
the presence of the photon PDF set locally before starting the fit for each
replica. If it is not found, it will proceed to compute the photon replica as
needed for each replica being fitted. The following is an example of running
``n3fit`` where the photon PDF set is computed during the fitting step:
.. code-block:: bash
$ n3fit qed_example_runcard.yml 1
[INFO]: Creating replica output folder in /user/runcards/qed_example_runcard/nnfit/replica_1
[WARNING]: Using q2min from runcard
[WARNING]: Using w2min from runcard
Using Keras backend
[WARNING]: No Photon QED set found for Theory 703 with luxset 251127-jcm-lh-qed-001. It will be computed using FiatLux. This may impact performance. It is recommended to precompute the photon set before running the fit. Refer to https://docs.nnpdf.science/tutorials/run-qed-fit.html for more details on precomputing photon PDF sets.
[INFO]: All requirements processed and checked successfully. Executing actions.
.. warning::
Computing the photon PDF set during `n3fit` with multiple replicas or using GPUs
has not been tested and may lead to unexpected behaviour. It is strongly advised to
precompute the photon PDF set using ``vp-setupfit`` before running the fit with ``n3fit``.
44 changes: 35 additions & 9 deletions doc/sphinx/source/vp/download.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ Downloading resources
``validphys`` is designed so that, by default, resources stored in known remote
locations are downloaded automatically and seamlessly used where necessary.
Available resources include PDF sets, completed fits, theories, and results of
past ``validphys`` runs that have been :ref:`uploaded to the server <upload>`.
The ``vp-get`` tool, :ref:`described below <vp-get>`,
past ``validphys`` runs that have been :ref:`uploaded to the server <upload>`.
The ``vp-get`` tool, :ref:`described below <vp-get>`,
can be used to download the same items manually.

Automatic operation
-------------------

By default when some resource such as a PDF is required by ``validphys`` (or
derived tools such as ``vp-setupfit``), the code will first look for it in some
local directory specified in the [profile file](nnprofile). If it is not found
local directory specified in the :ref:`profile file <nnprofile>`. If it is not found
there, it will try to download it from some remote repository (also specified in
the profile).

Expand Down Expand Up @@ -70,6 +70,21 @@ Theories
Theories (specified by the ``theoryid`` key) are downloaded and
uncompressed.

Photon PDF sets
Photon PDF sets can be downloaded if they have been previously generated
using `FiatLux <https://github.com/scarrazza/fiatlux/>`_. A photon PDF set
is uniquely identified by the input PDF set used to generate the photon replicas
and the theory ID. See :ref:`this tutorial <run-qed-fit>` for more details on
how to set up a QED fit.

EKOs
Evolution kernels (EKOs) can be downloaded if they have been previously
generated using EKO.

Hyperparameter scans
Results of the hyperparameter scans generated in the hyperoptimization
procedure.

``validphys`` output files
Files produced by ``validphys`` can be used as input to subsequent validphys
analyses (for example χ² tables are used for αs fits). The user needs to
Expand All @@ -80,7 +95,7 @@ Theories

.. _vp-get:

The `vp-get` tool
The ``vp-get`` tool
-----------------

The ``vp-get`` tool can be used to download resources manually, in the same way
Expand All @@ -99,8 +114,11 @@ They correspond to the resources described :ref:`above <what-can-be-downloaded>`

$ vp-get --list
Available resource types:
- eko
- fit
- hyperscan
- pdf
- photonQED
- theoryID
- vp_output_file

Expand All @@ -118,6 +136,15 @@ information on it and bail out:
$ vp-get fit NNPDF31_nlo_as_0118_1000
FitSpec(name='NNPDF31_nlo_as_0118_1000', path=PosixPath('/home/zah/anaconda3/envs/nnpdf-dev/share/NNPDF/results/NNPDF31_nlo_as_0118_1000'))

.. note::

In order to download photon PDF sets, the user needs to specify both the input PDF
set and the theory ID. For example:

.. code:: bash

$ vp-get photonQED 40000000 NNPDF40_nnlo_as_01180

Downloading resources in code (``validphys.loader``)
----------------------------------------------------

Expand Down Expand Up @@ -164,18 +191,18 @@ Conversely the ``Loader`` class will only search locally.
----> 1 l.check_dataset('NMC', theoryid=151)

~/nngit/nnpdf/validphys2/src/validphys/loader.py in check_dataset(self, name, rules, sysnum, theoryid, cfac, frac, cuts, use_fitcommondata, fit, weight)
416
416
417 if not isinstance(theoryid, TheoryIDSpec):
--> 418 theoryid = self.check_theoryID(theoryid)
419
419
420 theoryno, _ = theoryid

~/nngit/nnpdf/validphys2/src/validphys/loader.py in check_theoryID(self, theoryID)
288 if not theopath.exists():
289 raise TheoryNotFound(("Could not find theory %s. "
--> 290 "Folder '%s' not found") % (theoryID, theopath) )
291 return TheoryIDSpec(theoryID, theopath)
292
292

TheoryNotFound: Could not find theory 151. Folder '/home/zah/anaconda3/share/NNPDF/data/theory_151' not found

Expand All @@ -184,10 +211,9 @@ Output files uploaded to the ``validphys`` can be retrieved specifying their pat
(starting from the report ID). They will be either downloaded (when using
``FallbackLoader``) or retrieved from the cache:

.. code:: python
.. code:: python

from validphys.loader import FallbackLoader as Loader
l = Loader()
l.check_vp_output_file('qTpvLZLwS924oAsmpMzhFw==/figures/f_ns0_fitunderlyinglaw_plot_closure_pdf_histograms_0.pdf')
PosixPath('/home/zah/anaconda3/share/NNPDF/vp-cache/qTpvLZLwS924oAsmpMzhFw==/figures/f_ns0_fitunderlyinglaw_plot_closure_pdf_histograms_0.pdf')

Loading
Loading