Creating your own pdf¶
A core feature of zfit is the ability to create custom pdfs and functions in an simple and straightforward way.
There are two main possibilities to create a custom pdf, an easier for most use-cases and an advanced way..
The simple way¶
While the same works for functions, an example with a PDF is shown here
import numpy as np
import zfit
from zfit import z
class MyGauss(zfit.pdf.ZPDF):
_N_OBS = 1 # dimension, can be omitted
_PARAMS = ['mean', 'std'] # the name of the parameters
def _unnormalized_pdf(self, x):
x = z.unstack_x(x) # returns a list with the columns: do x, y, z = z.unstack_x(x) for 3D
mean = self.params['mean']
std = self.params['std']
return z.exp(- ((x - mean)/std)**2)
Done. Now we can use our pdf already!
obs = zfit.Space('obs1', limits=(-3, 6))
data_np = np.random.random(size=1000)
data = zfit.data.Data.from_numpy(array=data_np, obs=obs)
Create two parameters and an instance of your own pdf
mean = zfit.Parameter("mean", 1.)
std = zfit.Parameter("std", 1.)
my_gauss = MyGauss(obs='obs1', mean=mean, std=std)
probs = my_gauss.pdf(data, norm_range=(-3, 4))
probs_np = zfit.run(probs)
print(probs_np[:20])
[0.25326084 0.53630835 0.28033435 0.51129527 0.52547282 0.55845964
0.36465913 0.4310475 0.47268722 0.23873094 0.43609205 0.45172849
0.49170268 0.53067981 0.24145915 0.56318064 0.38656897 0.45412051
0.39474896 0.51229143]
We could improve our PDF by registering an integral
def gauss_integral_from_any_to_any(limits, params, model):
lower, upper = limits.limit1d
mean = params['mean']
std = params['std']
# write your integral here
return 42. # dummy integral, must be a scalar!
limits = zfit.Space.from_axes(axes=0, limits=(zfit.Space.ANY_LOWER, zfit.Space.ANY_UPPER))
MyGauss.register_analytic_integral(func=gauss_integral_from_any_to_any, limits=limits)
n-dimensional¶
Advanced Custom PDF¶
Subclass BasePDF. The _unnormalized_pdf
has to be overriden and, in addition, the __init__
.
Any of the public main methods (pdf
, integrate
, partial_integrate
etc.) can always be overriden by implementing the function with a leading underscore, e.g. implement _pdf
to directly controls pdf
, the API is the same as the public function without the name. In case, during execution of your own method, it is found to be a bad idea to have overridden the default methods, throwing a NotImplementedError
will restore the default behavior.
# TOBEDONE