-
Notifications
You must be signed in to change notification settings - Fork 14
Add an lhapdf_compatibility module for LHAPDF
#1799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0ec7ec3
add a lhapdf_compatibility class to avoid having to use lhapdf
scarlehoff 6a674c9
rebase this branch on top of the pyproject.toml
scarlehoff ff1cf95
isort
scarlehoff d23b302
Update validphys2/src/validphys/lhapdf_compatibility.py
scarlehoff 3de9b27
Apply suggestions from code review
scarlehoff 37812ac
remove lha_paths
scarlehoff File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| """ | ||
| Module for LHAPDF compatibility backends | ||
|
|
||
| If LHAPDF is installed, the module will transparently hand over everything to LHAPDF | ||
| if LHAPDF is not available, it will try to use a combination of the packages | ||
| `lhapdf-management` and `pdfflow` | ||
| which cover all the features of LHAPDF used during the fit (and likely most of validphys) | ||
| """ | ||
| from functools import cached_property | ||
|
|
||
| import numpy as np | ||
|
|
||
| try: | ||
| import lhapdf | ||
|
|
||
| USING_LHAPDF = True | ||
| except ModuleNotFoundError: | ||
| import logging | ||
|
|
||
| import lhapdf_management as lhapdf | ||
|
|
||
| log = logging.getLogger(__name__) | ||
| log.warning("LHAPDF was not found, using an alternative backend") | ||
|
|
||
| USING_LHAPDF = False | ||
|
|
||
|
|
||
| class _PDFFlowPDF: | ||
| """Wrapper around the PDFFlow PDF so that it can be used as an LHAPDF | ||
| set by validphys | ||
| Takes as input a pdf_meta object (which is a PDFset from lhapdf_management | ||
| and which knows where the PDF needs to be loaded from) and a single member | ||
|
|
||
| Loading the PDF is done in a lazy manner since most of the time only a few members are needed. | ||
|
|
||
| Since PDFFlow is only utilized to load the PDF for interpolation, the import is delayed until | ||
| the first call to `mkPDF`. This allows the usage of most of validphys without tensorflow. | ||
| """ | ||
|
|
||
| def __init__(self, pdf_meta, member): | ||
| if USING_LHAPDF: | ||
| raise ValueError("PDFFlow should not be instantiated when using LHAPDF") | ||
|
|
||
| self._pdf_meta = pdf_meta | ||
| self._m = member | ||
| self._pdf = None | ||
| self._flavors = self._pdf_meta.info["Flavors"] | ||
|
|
||
| @cached_property | ||
| def pdf(self): | ||
| # Don't import PDF Flow until you really needed it | ||
| import pdfflow | ||
|
|
||
| if self._pdf is None: | ||
| pdf_def = f"{self._pdf_meta.name}/{self._m}" | ||
| self._pdf = pdfflow.mkPDF(pdf_def, self._pdf_meta.path.parent) | ||
| return self._pdf | ||
|
|
||
| def flavors(self): | ||
| return self._flavors | ||
|
|
||
| def _xfxQ_all_pid(self, x, q): | ||
| x = np.atleast_1d(x) | ||
| q = np.atleast_1d(q) | ||
|
|
||
| res = self.pdf.py_xfxQ2_allpid(x, q**2).numpy() | ||
| return dict(zip(self._flavors, res.T)) | ||
|
|
||
| def xfxQ(self, a, b, c=None): | ||
| """Wrapper for the LHAPDF xfxQ function | ||
| This is an overloaded function in LHAPDF so depending | ||
| on the number of arguments we will do: | ||
| xfxQ(flavours, x, Q) | ||
| or | ||
| xfxQ(x, q) | ||
|
|
||
| All of x/q/flavours can be either a scalar or an array | ||
| """ | ||
| if c is None: | ||
| return self._xfxQ_all_pid(a, b) | ||
|
|
||
| # PDFFlow doesn't allow to ask for flavours that do not exist | ||
| # so let us retrieve all and return 0s for non existing flavs | ||
| ret_dict = self.xfxQ(b, c) | ||
| zeros = np.zeros_like(b) | ||
|
|
||
| if isinstance(a, int): | ||
| return ret_dict.get(a, zeros) | ||
| return [ret_dict.get(i, zeros) for i in a] | ||
|
|
||
| def xfxQ2(self, a, b, c=None): | ||
| """Wrapper for LHAPDF xfxQ2 function, like xfxQ for Q2""" | ||
| if c is None: | ||
| return self.xfxQ(a, np.sqrt(b)) | ||
| return self.xfxQ(a, b, np.sqrt(c)) | ||
|
|
||
|
|
||
| def make_pdf(pdf_name, member=None): | ||
| """Load a PDF | ||
| if member is given, load the single member otherwise, load the entire set as a list | ||
|
|
||
| if LHAPDF is provided, it returns LHAPDF PDF instances | ||
| otherwise it returns and object which is _compatible_ with LHAPDF | ||
| for lhapdf functions for the selected backend | ||
|
|
||
| Parameters: | ||
| ---------- | ||
| pdf_name: str | ||
| name of the PDF to load | ||
| member: int | ||
| index of the member of the PDF to load | ||
|
|
||
| Returns: | ||
| ------- | ||
| list(pdf_sets) | ||
| """ | ||
| if USING_LHAPDF: | ||
| if member is None: | ||
| return lhapdf.mkPDFs(pdf_name) | ||
| return [lhapdf.mkPDF(pdf_name, member)] | ||
|
|
||
| pdf_meta = lhapdf.load_pdf_meta(pdf_name) | ||
| if member is None: | ||
| return [_PDFFlowPDF(pdf_meta, m) for m in range(len(pdf_meta))] | ||
| return [_PDFFlowPDF(pdf_meta, member)] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.