PDFxTMDLib provides a powerful and easy-to-use Python interface for high-performance Parton Distribution Function (PDF) calculations. It offers unified access to collinear PDFs (cPDFs), Transverse Momentum-Dependent PDFs (TMDs), double parton distributions (DPDs), uncertainty analysis, and QCD coupling calculations.
This guide covers the installation and usage of the Python bindings.
Installation
You can install the package directly from PyPI:
High-Level API: <tt>PDFSet</tt>
The PDFSet interface is the recommended way to work with PDF sets. It handles the entire collection of PDF members (central value and error sets) and provides a simple API for calculating uncertainties and correlations.
1\. Collinear PDF (cPDF) Uncertainty
import pdfxtmd
cpdf_set = pdfxtmd.CPDFSet("CT18NLO")
print(f"Loaded CPDF Set: CT18NLO with {len(cpdf_set)} members.")
x = 0.01
mu2 = 100
central_cpdf = cpdf_set[0]
up_pdf_central = central_cpdf.pdf(pdfxtmd.PartonFlavor.u, x, mu2)
print(f"Central Up Quark PDF: {up_pdf_central:.6f}")
uncertainty = cpdf_set.Uncertainty(pdfxtmd.PartonFlavor.u, x, mu2)
print(f"Uncertainty: central={uncertainty.central:.6f}, +{uncertainty.errplus:.6f}, -{uncertainty.errminus:.6f}")
correlation = cpdf_set.Correlation(
pdfxtmd.PartonFlavor.u, x, mu2,
pdfxtmd.PartonFlavor.d, x, mu2
)
print(f"Correlation between u and d quarks: {correlation:.4f}")
2\. TMD Uncertainty
The interface for TMDs is analogous. Just use TMDSet and include the transverse momentum kt2.
import pdfxtmd
tmd_set = pdfxtmd.TMDSet("PB-NLO-HERAI+II-2018-set2")
print(f"\nLoaded TMD Set: {tmd_set.info().get_string('SetDesc')} with {len(tmd_set)} members.")
x = 0.01
mu2 = 100
kt2 = 10
uncertainty_tmd = tmd_set.Uncertainty(pdfxtmd.PartonFlavor.g, x, kt2, mu2)
print(f"Gluon TMD Uncertainty: central={uncertainty_tmd.central:.6f}, +{uncertainty_tmd.errplus:.6f}, -{uncertainty_tmd.errminus:.6f}")
Low-Level API: Factories
For applications where you only need to evaluate a single PDF member and do not require uncertainty analysis, the factory interface offers a more direct approach.
import pdfxtmd
x = 0.01
mu2 = 100
kt2 = 10
cpdf_factory = pdfxtmd.GenericCPDFFactory()
cpdf = cpdf_factory.mkCPDF("CT18NLO", 0)
up_pdf = cpdf.pdf(pdfxtmd.PartonFlavor.u, x, mu2)
print(f"CPDF (Up Quark) from Factory: {up_pdf:.6f}")
all_flavors_cpdf = cpdf.pdf(x, mu2)
print(f"All CPDF Flavors from Factory: {all_flavors_cpdf}")
tmd_factory = pdfxtmd.GenericTMDFactory()
tmd = tmd_factory.mkTMD("PB-NLO-HERAI+II-2018-set2", 0)
gluon_tmd = tmd.tmd(pdfxtmd.PartonFlavor.g, x, kt2, mu2)
print(f"\nTMD (Gluon) from Factory: {gluon_tmd:.6f}")
all_flavors_tmd = tmd.tmd(x, kt2, mu2)
print(f"All TMD Flavors from Factory: {all_flavors_tmd}")
Double Parton Distributions (DPDs)
DPDs are available when the package is built with DPD support. The same Python API handles dense PDFxTMD-DPDB1 and hybrid PDFxTMD-DPDH1 sets.
import numpy as np
import pdfxtmd
print("DPD support:", pdfxtmd.__has_dpd__)
dpd = pdfxtmd.GenericCDPDFactory().mkCDPD(
"MSTW2008lo68cl_GSDPDF_PDFxTMD", 0
)
value = dpd.dpd(
pdfxtmd.PartonFlavor.g,
pdfxtmd.PartonFlavor.g,
1e-2, 100.0,
2e-2, 400.0,
)
print("g-g DPD:", value)
x1 = np.array([1e-3, 1e-2, 5e-2])
x2 = np.array([2e-3, 2e-2, 1e-1])
mu1_2 = np.full_like(x1, 100.0)
mu2_2 = np.full_like(x2, 400.0)
values = dpd.dpd_batch(
pdfxtmd.PartonFlavor.g,
pdfxtmd.PartonFlavor.g,
x1, mu1_2, x2, mu2_2,
)
print(values)
The NumPy batch overload accepts arrays with matching shapes and releases the Python GIL during native evaluation.
QCD Coupling ($\alpha_s$) Calculations
You can calculate the strong coupling constant $\alpha_s$ in two ways.
import pdfxtmd
cpdf_set = pdfxtmd.CPDFSet("CT18NLO")
print("--- Method A: From PDFSet ---")
alpha_s_from_set = cpdf_set.alphasQ2(10000)
print(f"Alpha_s at mu2=10000: {alpha_s_from_set:.5f}")
print("\n--- Method B: From CouplingFactory ---")
coupling_factory = pdfxtmd.CouplingFactory()
coupling = coupling_factory.mkCoupling("CT18NLO")
alpha_s_from_factory = coupling.AlphaQCDMu2(10000)
print(f"Alpha_s at mu2=10000: {alpha_s_from_factory:.5f}")
Complete Example: Plotting PDFs with Uncertainties
This example demonstrates a complete workflow: loading PDF/TMD sets, calculating values and uncertainties over a range of x, and plotting the results using matplotlib.
import pdfxtmd
import numpy as np
import matplotlib.pyplot as plt
cpdf_set = pdfxtmd.CPDFSet("CT18NLO")
print(f"Loaded cPDF set: {cpdf_set.info().get_string('SetDesc')}")
x_values = np.logspace(-4, -1, 100)
mu2 = 1000
uncertainties = [cpdf_set.Uncertainty(pdfxtmd.PartonFlavor.g, x, mu2) for x in x_values]
central_pdfs = [u.central for u in uncertainties]
upper_band = [u.central + u.errplus for u in uncertainties]
lower_band = [u.central - u.errminus for u in uncertainties]
plt.figure(figsize=(10, 6))
plt.plot(x_values, central_pdfs, label='Gluon PDF (CT18NLO)', color='blue')
plt.fill_between(x_values, lower_band, upper_band, color='blue', alpha=0.2, label='68% CL Uncertainty')
plt.xscale('log')
plt.xlabel('$x$')
plt.ylabel('$xg(x, \mu^2)$')
plt.title(f'Gluon PDF with Uncertainty at $\mu^2 = {mu2} \ GeV^2$')
plt.legend()
plt.grid(True, which="both", ls="--")
plt.savefig('gluon_pdf_plot.png')
print("Saved plot to gluon_pdf_plot.png")
plt.close()
tmd_set = pdfxtmd.TMDSet("PB-LO-HERAI+II-2020-set2")
print(f"Loaded TMD set: {tmd_set.info().get_string('SetDesc')}")
kt2 = 1
tmd_uncertainties = [tmd_set.Uncertainty(pdfxtmd.PartonFlavor.g, x, kt2, mu2) for x in x_values]
central_tmds = [u.central for u in tmd_uncertainties]
tmd_upper_band = [u.central + u.errplus for u in tmd_uncertainties]
tmd_lower_band = [u.central - u.errminus for u in tmd_uncertainties]
plt.figure(figsize=(10, 6))
plt.plot(x_values, central_tmds, label='Gluon TMD (PB-LO-2020)', color='green')
plt.fill_between(x_values, tmd_lower_band, tmd_upper_band, color='green', alpha=0.2, label='68% CL Uncertainty')
plt.xscale('log')
plt.xlabel('$x$')
plt.ylabel('$xg(x, k_t^2, \mu^2)$')
plt.title(f'Gluon TMD with Uncertainty at $k_t^2 = {kt2} \ GeV^2, \mu^2 = {mu2} \ GeV^2$')
plt.legend()
plt.grid(True, which="both", ls="--")
plt.savefig('gluon_tmd_plot.png')
print("Saved plot to gluon_tmd_plot.png")
plt.close()
Additional Information
Error Handling
The API raises a RuntimeError for invalid kinematic inputs.
try:
cpdf.pdf(pdfxtmd.PartonFlavor.u, -0.1, mu2)
except RuntimeError as e:
print(f"Caught expected error for invalid x: {e}")
Enumerating Parton Flavors
You can inspect all available parton flavors and their integer codes.
print("\n--- All PartonFlavor enum values ---")
for name, flavor in pdfxtmd.PartonFlavor.__members__.items():
print(f" {name}: {flavor.value}")
Full Code Examples
For more detailed examples, see the full tutorials in the project repository:
License
This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.
Contact
For questions or contributions, please contact raminkord92@gmail.com.