Search code examples
pythonzfit

PDF from a histogram in zfit?


I looking in the documentation how to obtain a PDF from a histogram, but I couldn't find anything, so how can I obtain PDF from a histogram ?, for example to use it in a sum_pdf = zfit.pdf.SumPDF([model1, model2], fracs=frac) in order to perfome a fit, or maybe generate some toys.

Thanks in advance.

PS. I'm looking something similar to RooHistPdf Class from Roofit.


Solution

  • Updated answer

    zfit now allows to do binned fits (to be installed currently with pip install zfit --pre) as described in the tutorial

    Basically, starting from the unbinned data or model, you can do:

    # make binned
    binning = zfit.binned.RegularBinning(50, -8, 10, name="x")
    obs_bin = zfit.Space("x", binning=binning)
    
    data = data_nobin.to_binned(obs_bin)
    model = zfit.pdf.BinnedFromUnbinnedPDF(model_nobin, obs_bin)
    

    Old answer

    There is currently no out-of-the-box solution for this but work-in-progress.

    However, you can simply construct something on your own like:

    import zfit
    from zfit import z
    import numpy as np
    import tensorflow as tf
    
    zfit.settings.options['numerical_grad'] = True
    
    
    class BinnedEfficiencyPDF(zfit.pdf.BasePDF):
    
        def __init__(self, efficiency, eff_bins, obs, name='BinnedEfficiencyPDF'):
            self.efficiency = efficiency
            self.eff_bins = eff_bins
            super().__init__(obs=obs, name=name)
    
        def _binContent(self, x):
            eff_bin = np.digitize(x, self.eff_bins)
            return self.efficiency[eff_bin]
    
        def _unnormalized_pdf(self, x):  # or even try with PDF
            x = z.unstack_x(x)
            probs =  z.py_function(func=self._binContent, inp=[x], Tout=tf.float64)
            probs.set_shape(x.shape)
            return prob