Source code for pinefarm.external.positivity

"""Positivity interface."""

import json

import numpy as np
import pandas as pd
import pineappl
import yaml

from .. import configs
from . import interface


[docs] class Positivity(interface.External): """Interface provider.""" kind = "Positivity" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
[docs] def run(self): """Open configuration.""" with open( configs.configs["paths"]["runcards"] / self.name / "positivity.yaml" ) as o: self.runcard = yaml.safe_load(o)
[docs] def read_kinematics(self): """Read kinematics from runcard.""" if "kinematics" in self.runcard: kinematics = self.runcard["kinematics"] xgrid = np.array([point["x"] for point in kinematics]) q2grid = np.array([point["q2"] for point in kinematics]) else: xgrid = np.array(self.runcard["xgrid"]) q2 = self.runcard["q2"] q2grid = np.full_like(xgrid, q2) return xgrid, q2grid
[docs] def generate_pineappl(self): """Generate grid.""" self.xgrid, self.q2grid = self.read_kinematics() self.pid = self.runcard["pid"] self.hadron_pid = self.runcard["hadron_pid"] self.convolution_type = self.runcard.get("convolution_type", "UnpolPDF") bins_length = len(self.xgrid) bin_limits = [float(i) for i in range(0, bins_length + 1)] polarized = self.convolution_type == "PolPDF" # Instantiate the objecs required to construct a new Grid channels = [pineappl.boc.Channel([([self.pid], 1.0)])] orders = [pineappl.boc.Order(0, 0, 0, 0, 0)] convolution_types = pineappl.convolutions.ConvType( polarized=polarized, time_like=False ) convolutions = [ pineappl.convolutions.Conv( convolution_types=convolution_types, pid=self.hadron_pid ) ] kinematics = [pineappl.boc.Kinematics.Scale(0), pineappl.boc.Kinematics.X(0)] scale_funcs = pineappl.boc.Scales( ren=pineappl.boc.ScaleFuncForm.Scale(0), fac=pineappl.boc.ScaleFuncForm.Scale(0), frg=pineappl.boc.ScaleFuncForm.NoScale(0), ) bin_limits = pineappl.boc.BinsWithFillLimits.from_fill_limits( fill_limits=bin_limits ) interpolations = [ pineappl.interpolation.Interp( min=10, max=1e3, nodes=50, order=3, reweight_meth=pineappl.interpolation.ReweightingMethod.NoReweight, map=pineappl.interpolation.MappingMethod.ApplGridH0, interpolation_meth=pineappl.interpolation.InterpolationMethod.Lagrange, ), # Interpolation on the Scale pineappl.interpolation.Interp( min=1e-5, max=1, nodes=40, order=3, reweight_meth=pineappl.interpolation.ReweightingMethod.ApplGridX, map=pineappl.interpolation.MappingMethod.ApplGridF2, interpolation_meth=pineappl.interpolation.InterpolationMethod.Lagrange, ), # Interpolation on momentum fraction x ] grid = pineappl.grid.Grid( pid_basis=pineappl.pids.PidBasis.Pdg, channels=channels, orders=orders, bins=bin_limits, convolutions=convolutions, interpolations=interpolations, kinematics=kinematics, scale_funcs=scale_funcs, ) limits = [] # add each point as a bin for bin_, (x, q2) in enumerate(zip(self.xgrid, self.q2grid)): # keep DIS bins limits.append([(q2, q2), (x, x)]) # Fill the subgrid with delta functions array_subgrid = np.zeros((1, self.xgrid.size)) array_subgrid[0][bin_] = x # create and set the subgrid subgrid = pineappl.subgrid.ImportSubgridV1( array=array_subgrid, node_values=[[q2], self.xgrid], ) grid.set_subgrid(0, bin_, 0, subgrid.into()) # set the correct observables normalizations = [1.0] * bins_length bin_configs = pineappl.boc.BinsWithFillLimits.from_limits_and_normalizations( limits=limits, normalizations=normalizations, ) grid.set_bwfl(bin_configs) # set the initial state PDF ids for the grid grid.set_metadata("runcard", json.dumps(self.runcard)) # dump file grid.optimize() grid.write(self.grid)
[docs] def results(self): """Apply PDF to grid.""" import lhapdf # pylint: disable=import-error pdf = lhapdf.mkPDF(self.pdf) d = { "result": [ pdf.xfxQ2(self.pid, x, q2) for (x, q2) in zip(self.xgrid, self.q2grid) ], "error": [1e-15] * len(self.xgrid), "sv_min": [ np.amin( [ pdf.xfxQ2(self.pid, x, 0.25 * q2), pdf.xfxQ2(self.pid, x, q2), pdf.xfxQ2(self.pid, x, 4.0 * q2), ] ) for (x, q2) in zip(self.xgrid, self.q2grid) ], "sv_max": [ np.amax( [ pdf.xfxQ2(self.pid, x, 0.25 * q2), pdf.xfxQ2(self.pid, x, q2), pdf.xfxQ2(self.pid, x, 4.0 * q2), ] ) for (x, q2) in zip(self.xgrid, self.q2grid) ], } results = pd.DataFrame(data=d) return results
[docs] def collect_versions(self): """No additional programs involved.""" return {}