Plotting non-trivial combinations of PDFs

Suppose we are interested in plotting some (in general non-linear) function of PDFs as a function of \(x\), for example the strangeness fraction defined as

\[R_s = \frac{s + \bar{s}}{\bar{u} + \bar{d}}.\]

To achieve this we can make use of a PDF basis (the implementation within validphys can be found in validphys.pdfbases).

We need to begin by assigning each parton a numerical index. This convention is laid out by the PDG as follows:

































We see that for our quantity of interest, \(R_s\), we are interested in indices \(-3\), \(3\), \(-2\), and \(-1\). To achieve the desired plot, we must tell validphys what manipulation it must make on the interpolation grids. The logic for grid manipulation is handled by validphys.pdfbases.Basis.apply_grid_values() which is an abstract base class method and thus must be implemented manually each time the user inherits from this class. We shall define a function strange_fraction which will do exactly this.

The function should take in as arguments: func a callable which will return grid_values, a list of \(x\) values xmat, and a list of \(Q\) values in GeV qmat. The object grid_values will be indexed as grid_values[replica_number][flavour][x][Q].

def strange_fraction(func, xmat, qmat):
    gv = func([-3, 3, -2, -1], xmat, qmat)
    sbar, s, ubar, dbar = (gv[:, [i], ...] for i in range(4))
    return (sbar + s) / (ubar + dbar)

We then use this transformation to produce a Basis with the required functionality to integrate with the rest of the framework (such as labels for plotting). To do so, we decorate the function with validphys.pdfbases.scalar_function_transformation() which will instantiate a new validphys.pdfbases.ScalarFunctionTransformation object, with the apply_grid_values method constructed based on the strange_fraction function we above.

The scalar_function_transformation function takes as an argument label, which it will use to label the plot title and axes. For our particular example, it will be sensible to use Rs as the value for this argument.

In addition, it is good practice to define this particular combination of PDFs as an element of a particular basis. As such, we must give this particular element a label, which we will do by adding element_representations={"Rs": "R_{s}"} to the decorator arguments.

The final function is thus:

@scalar_function_transformation(label="Rs", element_representations={"Rs": "R_{s}"})
def strange_fraction(func, xmat, qmat):
    gv = func([-3, 3, -2, -1], xmat, qmat)
    sbar, s, ubar, dbar = (gv[:, [i], ...] for i in range(4))
    return (sbar + s) / (ubar + dbar)

All that remains now is to construct the appropriate runcard, makes use of our newly defined basis. One such example would be:

    - NNPDF31_nlo_as_0118

Q: 10

  - basis: strange_fraction

template_text: |
    {@bases plot_pdfs@}

    - report(main=True)

Note that the name of the basis exposed to validphys is the name of the function.