zfit binned#

There are two main ways of looking at “binned fits”

  • Either an analytic shape that could be fit unbinned but is fit to binned data because of the datasize (typical LHCb, Belle II,…)

  • stacking template histograms from simulation to provide the shape and fit to binned data (typical done in CMS, ATLAS, some LHCb,…)

Some templated fits with uniform binning, no analytic components and specific morphing and constraints fit into the HistFactory model, implemented in pyhf. These fits make a large portion of CMS and ATLAS analyses.

zfit can, in principle, reproduce them too. However, it’s comparably inefficient, a lot of code and slow. The main purpose is to support anything that is beyond HistFactory.

import matplotlib.pyplot as plt
import mplhep
import numpy as np
import zfit
import zfit.z.numpy as znp  # numpy-like backend interface
from zfit import z  # backend, special functions

zfit.settings.set_seed(43)
{'zfit': 1678410587, 'numpy': 1085174816, 'backend': 685015468, 'seed': 43}

Binned parts#

zfit introduces binned equivalents to unbinned components and transformations from one to the other. For example:

  • SumPDF -> BinnedSumPDF

  • Data -> BinnedData

  • UnbinnedNLL -> BinnedNLL

There are converters and new, histogram specific PDFs and methods.

From unbinned to binned#

Let’s start with an example, namely a simple, unbinned fit that we want to perform binned.

normal_np = np.random.normal(loc=2., scale=1.3, size=10000)

obs = zfit.Space("x", -10, 10)

mu = zfit.Parameter("mu", 1., -4, 6)
sigma = zfit.Parameter("sigma", 1., 0.1, 10)
model_nobin = zfit.pdf.Gauss(mu, sigma, obs)

data_nobin = zfit.Data.from_numpy(obs, normal_np)

loss_nobin = zfit.loss.UnbinnedNLL(model_nobin, data_nobin)
minimizer = zfit.minimize.Minuit()
# make binned
nbins = 50
data = data_nobin.to_binned(nbins)
model = model_nobin.to_binned(data.space)
loss = zfit.loss.BinnedNLL(model, data)
result = minimizer.minimize(loss)
print(result)
FitResult
 of
<BinnedNLL model=[<zfit.models.tobinned.BinnedFromUnbinnedPDF object at 0x7f4d404bf3d0>] data=[<zfit._data.binneddatav1.BinnedData object at 0x7f4d404dc290>] constraints=[]> 
with
<Minuit Minuit tol=0.001>

╒═════════╤═════════════╤══════════════════╤═══════╤══════════════════════════════╕
│  valid  │  converged  │  param at limit  │  edm  │   approx. fmin (full | opt.) │
╞═════════╪═════════════╪══════════════════╪═══════╪══════════════════════════════╡
│  
True
   │    True
     │      False
       │ 3e-05 │        -56085.38 | -55783.96 │
╘═════════╧═════════════╧══════════════════╧═══════╧══════════════════════════════╛
Parameters
name      value  (rounded)    at limit
------  ------------------  ----------
mu                 2.00582       False
sigma              1.30038       False

result.hesse(name="hesse")
{<zfit.Parameter 'mu' floating=True value=2.006>: {'error': 0.013055034990214433,
  'cl': 0.68268949},
 <zfit.Parameter 'sigma' floating=True value=1.3>: {'error': 0.009267627993316109,
  'cl': 0.68268949}}
result.errors(name="errors")
({<zfit.Parameter 'mu' floating=True value=2.006>: {'lower': -0.013153331959172017,
   'upper': 0.012957752403914837,
   'is_valid': True,
   'upper_valid': True,
   'lower_valid': True,
   'at_lower_limit': False,
   'at_upper_limit': False,
   'nfcn': 26,
   'original': ┌──────────┬───────────────────────┐
│          │          mu           │
├──────────┼───────────┬───────────┤
│  Error   │  -0.013   │   0.013   │
│  Valid   │   True    │   True    │
│ At Limit │   False   │   False   │
│ Max FCN  │   False   │   False   │
│ New Min  │   False   │   False   │
└──────────┴───────────┴───────────┘,
   'cl': 0.68268949},
  <zfit.Parameter 'sigma' floating=True value=1.3>: {'lower': -0.009231682967702513,
   'upper': 0.009303539528788134,
   'is_valid': True,
   'upper_valid': True,
   'lower_valid': True,
   'at_lower_limit': False,
   'at_upper_limit': False,
   'nfcn': 12,
   'original': ┌──────────┬───────────────────────┐
│          │         sigma         │
├──────────┼───────────┬───────────┤
│  Error   │  -0.009   │   0.009   │
│  Valid   │   True    │   True    │
│ At Limit │   False   │   False   │
│ Max FCN  │   False   │   False   │
│ New Min  │   False   │   False   │
└──────────┴───────────┴───────────┘,
   'cl': 0.68268949}},
 None)
print(result)
FitResult
 of
<BinnedNLL model=[<zfit.models.tobinned.BinnedFromUnbinnedPDF object at 0x7f4d404bf3d0>] data=[<zfit._data.binneddatav1.BinnedData object at 0x7f4d404dc290>] constraints=[]> 
with
<Minuit Minuit tol=0.001>

╒═════════╤═════════════╤══════════════════╤═══════╤══════════════════════════════╕
│  valid  │  converged  │  param at limit  │  edm  │   approx. fmin (full | opt.) │
╞═════════╪═════════════╪══════════════════╪═══════╪══════════════════════════════╡
│  
True
   │    True
     │      False
       │ 3e-05 │        -56085.38 | -55783.96 │
╘═════════╧═════════════╧══════════════════╧═══════╧══════════════════════════════╛
Parameters
name      value  (rounded)        hesse               errors    at limit
------  ------------------  -----------  -------------------  ----------
mu                 2.00582  +/-   0.013  -  0.013   +  0.013       False
sigma              1.30038  +/-  0.0093  - 0.0092   + 0.0093       False

Binned parts in detail#

to_binned creates a binned (and to_unbinned an unbinned) version of objects. It takes a binned Space, a binning or (as above), an integer (in which case a uniform binning is created).

This creates implicitly a new, binned space.

obs_binned_auto = data.space
print(obs_binned_auto)
<zfit Space obs=('x',), axes=(0,), limits=(array([[-10.]]), array([[10.]])), binned=True>

print(f"is_binned: {obs_binned_auto.is_binned}, binned obs binning: {obs_binned_auto.binning}")
print(f"is_binned: {obs.is_binned}, unbinned obs binning:{obs.binning}")
is_binned: True, binned obs binning: (RegularBinning(50, -10, 10, underflow=False, overflow=False, name='x'),)

is_binned: False, unbinned obs binning:None

Explicit conversion#

We can explicitly convert spaces, data and models to binned parts.

Either number of bins for uniform binning or explicit binning.

obs_binned = obs.with_binning(nbins)
print(obs_binned)

# or we can create binnings
binning_regular = zfit.binned.RegularBinning(nbins, -10, 10, name='x')
binning_variable = zfit.binned.VariableBinning([-10, -6, -1, -0.1, 0.4, 3, 10], name='x')
<zfit Space obs=('x',), axes=None, limits=(array([[-10.]]), array([[10.]])), binned=True>

Since a binning contains all the information needed to create a Space, a binning can be used to define a space directly.

obs_binned_variable = zfit.Space(binning=binning_variable)
print(obs_binned_variable, obs_binned_variable.binning)
<zfit Space obs=('x',), axes=None, limits=(array([[-10.]]), array([[10.]])), binned=True>
 
(VariableBinning([-10, -6, -1, -0.1, 0.4, 3, 10], underflow=False, overflow=False, name='x'),)

Converting data, models#

data_nobin.to_binned(obs_binned_variable)
-10 10 x
Variable([-10, -6, -1, -0.1, 0.4, 3, 10], underflow=False, overflow=False, name='x')

Weight() Σ=WeightedSum(value=10000, variance=10000)
model_nobin.to_binned(obs_binned_variable)
<zfit.models.tobinned.BinnedFromUnbinnedPDF at 0x7f4d4032e050>

Compatibility with UHI#

zfit keeps compatibility with Universal Histogram Interface (UHI) and libraries that implement it (boost-histogram, hist).

  • BinnedData directly adheres to UHI (and has a to_hist attribute)

  • BinnedPDF has a to_binneddata and to_hist attribute

Where a BinnedData object is expected, a (named) UHI object is also possible. Same goes for the binning axes.

h = model.to_hist()
h_scaled = h * [10_000]

Binneddata#

Binned data has counts, values and variances attributes, it has a binning (aliased with axes).

data.values()
<tf.Tensor: shape=(50,), dtype=float64, numpy=
array([0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
       0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
       0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 1.000e+00, 1.000e+00,
       3.000e+00, 8.000e+00, 1.300e+01, 3.100e+01, 9.700e+01, 1.460e+02,
       3.140e+02, 4.770e+02, 6.900e+02, 9.190e+02, 1.105e+03, 1.192e+03,
       1.204e+03, 1.053e+03, 9.410e+02, 6.810e+02, 4.950e+02, 2.960e+02,
       1.750e+02, 8.700e+01, 5.000e+01, 1.800e+01, 3.000e+00, 0.000e+00,
       0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
       0.000e+00, 0.000e+00])>

BinnedPDF#

A binned PDF has the same methods as the unbinned counterparts, namely pdf, integrate (and their ext_* parts) and sample that can respond to binned as well as unbinned data.

Additionally, there are two more methods, namely

  • counts returns the absolute counts as for a histogram. Equivalent to ext_pdf, ext_integrate, this only works if the PDF is extended.

  • rel_counts relative counts, like a histogram, but the sum is normalized to 1

Note on Counts vs Density#

Counts are the integrated density, i.e. they differ by a factor bin_width. For regular binning, this is “just” a constant factor, as it’s the same for all bins, but for Variable binning, this changes “the shape” of the histogram.

binned_sample = model.sample(n=1_000)

Plotting made easy#

This allows plotting to become a lot easier using mplhep, also for unbinned models.

plt.title("Counts plot")
mplhep.histplot(data, label="data")
mplhep.histplot(model.to_hist() * [data.nevents],
                label="model")  # scaling up since model is not extended, i.e. has no yield
plt.legend()
<matplotlib.legend.Legend at 0x7f4d40551c50>
../../_images/854cc9b880d292cf825ea7ebd1108e9a2ac706edab1f6775c2f96a709470cce9.png
plt.title("Counts plot")
mplhep.histplot(binned_sample, label="sampled data")
mplhep.histplot(model.to_hist() * [binned_sample.nevents],
                label="model")  # scaling up since model is not extended, i.e. has no yield
plt.legend()
<matplotlib.legend.Legend at 0x7f4d3af66010>
../../_images/acd893b5d47c51b0aa64c8996ba64e8e59d17f49ecc31668fcb6fe2d7cce8fa6.png
# or using unbinned data points, we can do a density plot
plt.title("Density plot")
mplhep.histplot(data.to_hist(), density=True, label="data")
x = znp.linspace(-10, 10, 200)
plt.plot(x, model.pdf(x), label="model")
plt.legend()
<matplotlib.legend.Legend at 0x7f4d38eb18d0>
../../_images/1998d190676051d4cd2e817428269ddb5308810b8b69d8d623bd08a08d883017.png

Binned loss functions#

We used above the BinnedNLL, but zfit offers more, namely an extended version and a BinnedChi2 (or least-square).

print(zfit.loss.__all__)
['ExtendedUnbinnedNLL', 'UnbinnedNLL', 'BinnedNLL', 'ExtendedBinnedNLL', 'BaseLoss', 'SimpleLoss', 'ExtendedBinnedNLL', 'BinnedChi2', 'ExtendedBinnedChi2']

Fitting using histograms#

There are a few new PDFs that are specific to histogram-like shapes, such as morphing interpolation and shape variations.

Most simple a HistogramPDF wraps a histogram and acts as a PDF.

By default, these histograms are extended automatically (which can be overruled using the extended argument)

histpdf = zfit.pdf.HistogramPDF(h_scaled)  # fixed yield
print(np.sum(histpdf.counts()))
10000.0

sig_yield = zfit.Parameter('sig_yield', 4_000, 0, 100_000)
histpdf = zfit.pdf.HistogramPDF(h, extended=sig_yield)
print(np.sum(histpdf.counts()))
4000.0

Modifiers#

We may want to add modifiers, i.e. scale each bin by a value. BinwiseScaleModifier offers this functionality.

Note however that these are just free parameters and not in any way constraint. This needs to be done manually.

histpdf.space.binning.size
(50,)
sig_pdf = zfit.pdf.BinwiseScaleModifier(histpdf,
                                        modifiers=True)  # or we could give a list of parameters matching each bin
modifiers = sig_pdf.params
# modifiers = {f'modifier_{i}': zfit.Parameter(f'modifier_{i}', 1, 0, 10) for i in range(histpdf.space.binning.size[0])}
# histpdf_scaled = zfit.pdf.BinwiseScaleModifier(histpdf, modifiers=modifiers)
modifiers
{'sysshape_0': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_0' floating=True value=1>,
 'sysshape_1': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_1' floating=True value=1>,
 'sysshape_2': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_2' floating=True value=1>,
 'sysshape_3': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_3' floating=True value=1>,
 'sysshape_4': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_4' floating=True value=1>,
 'sysshape_5': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_5' floating=True value=1>,
 'sysshape_6': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_6' floating=True value=1>,
 'sysshape_7': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_7' floating=True value=1>,
 'sysshape_8': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_8' floating=True value=1>,
 'sysshape_9': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_9' floating=True value=1>,
 'sysshape_10': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_10' floating=True value=1>,
 'sysshape_11': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_11' floating=True value=1>,
 'sysshape_12': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_12' floating=True value=1>,
 'sysshape_13': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_13' floating=True value=1>,
 'sysshape_14': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_14' floating=True value=1>,
 'sysshape_15': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_15' floating=True value=1>,
 'sysshape_16': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_16' floating=True value=1>,
 'sysshape_17': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_17' floating=True value=1>,
 'sysshape_18': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_18' floating=True value=1>,
 'sysshape_19': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_19' floating=True value=1>,
 'sysshape_20': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_20' floating=True value=1>,
 'sysshape_21': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_21' floating=True value=1>,
 'sysshape_22': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_22' floating=True value=1>,
 'sysshape_23': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_23' floating=True value=1>,
 'sysshape_24': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_24' floating=True value=1>,
 'sysshape_25': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_25' floating=True value=1>,
 'sysshape_26': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_26' floating=True value=1>,
 'sysshape_27': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_27' floating=True value=1>,
 'sysshape_28': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_28' floating=True value=1>,
 'sysshape_29': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_29' floating=True value=1>,
 'sysshape_30': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_30' floating=True value=1>,
 'sysshape_31': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_31' floating=True value=1>,
 'sysshape_32': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_32' floating=True value=1>,
 'sysshape_33': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_33' floating=True value=1>,
 'sysshape_34': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_34' floating=True value=1>,
 'sysshape_35': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_35' floating=True value=1>,
 'sysshape_36': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_36' floating=True value=1>,
 'sysshape_37': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_37' floating=True value=1>,
 'sysshape_38': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_38' floating=True value=1>,
 'sysshape_39': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_39' floating=True value=1>,
 'sysshape_40': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_40' floating=True value=1>,
 'sysshape_41': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_41' floating=True value=1>,
 'sysshape_42': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_42' floating=True value=1>,
 'sysshape_43': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_43' floating=True value=1>,
 'sysshape_44': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_44' floating=True value=1>,
 'sysshape_45': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_45' floating=True value=1>,
 'sysshape_46': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_46' floating=True value=1>,
 'sysshape_47': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_47' floating=True value=1>,
 'sysshape_48': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_48' floating=True value=1>,
 'sysshape_49': <zfit.Parameter 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_49' floating=True value=1>}
sig_pdf.get_yield()
<zfit.ComposedParameter 'AUTO_binwise_modifier_2' params=[('sysshape_0', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_0'), ('sysshape_1', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_1'), ('sysshape_2', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_2'), ('sysshape_3', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_3'), ('sysshape_4', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_4'), ('sysshape_5', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_5'), ('sysshape_6', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_6'), ('sysshape_7', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_7'), ('sysshape_8', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_8'), ('sysshape_9', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_9'), ('sysshape_10', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_10'), ('sysshape_11', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_11'), ('sysshape_12', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_12'), ('sysshape_13', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_13'), ('sysshape_14', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_14'), ('sysshape_15', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_15'), ('sysshape_16', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_16'), ('sysshape_17', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_17'), ('sysshape_18', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_18'), ('sysshape_19', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_19'), ('sysshape_20', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_20'), ('sysshape_21', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_21'), ('sysshape_22', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_22'), ('sysshape_23', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_23'), ('sysshape_24', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_24'), ('sysshape_25', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_25'), ('sysshape_26', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_26'), ('sysshape_27', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_27'), ('sysshape_28', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_28'), ('sysshape_29', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_29'), ('sysshape_30', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_30'), ('sysshape_31', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_31'), ('sysshape_32', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_32'), ('sysshape_33', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_33'), ('sysshape_34', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_34'), ('sysshape_35', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_35'), ('sysshape_36', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_36'), ('sysshape_37', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_37'), ('sysshape_38', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_38'), ('sysshape_39', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_39'), ('sysshape_40', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_40'), ('sysshape_41', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_41'), ('sysshape_42', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_42'), ('sysshape_43', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_43'), ('sysshape_44', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_44'), ('sysshape_45', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_45'), ('sysshape_46', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_46'), ('sysshape_47', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_47'), ('sysshape_48', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_48'), ('sysshape_49', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_49'), ('DUMMPY_PARAM_1', 'sig_yield')] value=4000>

Morphing#

Let’s create a background from simulation. Let’s assume, we have a parameter in the simulation that we’re unsure about.

A common used technique is to use “morphing”: creating multiple templates and interpolating between them. Typically, they are created at +1 and -1 sigma of the nuisance parameter (however, zfit allows arbitrary values and as many as wanted)

bkg_hist = zfit.Data(np.random.exponential(scale=20, size=100_000) - 10, obs=obs_binned)
bkg_hist_m1 = zfit.Data.from_numpy(obs=obs,
                                   array=np.random.exponential(scale=35, size=100_000) - 10).to_binned(
    obs_binned)
bkg_hist_m05 = zfit.Data.from_numpy(obs=obs,
                                    array=np.random.exponential(scale=26, size=100_000) - 10).to_binned(
    obs_binned)
bkg_hist_p1 = zfit.Data.from_numpy(obs=obs,
                                   array=np.random.exponential(scale=17, size=100_000) - 10).to_binned(
    obs_binned)
bkg_hists = {-1: bkg_hist_m1, -0.5: bkg_hist_m05, 0: bkg_hist, 1: bkg_hist_p1}
bkg_histpdfs = {k: zfit.pdf.HistogramPDF(v) for k, v in bkg_hists.items()}
mplhep.histplot(list(bkg_hists.values()), label=list(bkg_hists.keys()))
plt.legend();
../../_images/c5eabe8b463a33ded2c8d626a7fcc1596ccff5d7b84df8a1236b2a226dd98511.png
alpha = zfit.Parameter("alpha", 0, -3, 3)
bkg_yield = zfit.Parameter("bkg_yield", 15_000)
bkg_pdf = zfit.pdf.SplineMorphingPDF(alpha, bkg_histpdfs, extended=bkg_yield)
with alpha.set_value(-0.6):  # we can change this value to play around
    mplhep.histplot(bkg_pdf.to_hist())
../../_images/abd1b4c1081e2a6f5b9b95523d8036520ad3b86343036cda132d22140e7bfff1.png
bkg_pdf = zfit.pdf.HistogramPDF(bkg_hist, extended=bkg_yield)  # we don't use the spline for simplicity
model = zfit.pdf.BinnedSumPDF([sig_pdf, bkg_pdf])
model.to_hist()
-10 10 x
Regular(50, -10, 10, underflow=False, overflow=False, name='x')

Weight() Σ=WeightedSum(value=19000, variance=nan) (WeightedSum(value=19000, variance=nan) with flow)
with zfit.param.set_values([alpha] + list(modifiers.values()),
                           [0.] + list(np.random.normal(1.0, scale=0.14, size=len(modifiers)))):
    data = bkg_pdf.sample(n=10_000).to_hist() + sig_pdf.sample(1000).to_hist()
data
-10 10 x
Regular(50, -10, 10, underflow=False, overflow=False, name='x')

Weight() Σ=WeightedSum(value=11000, variance=nan) (WeightedSum(value=11000, variance=nan) with flow)
modifier_constraints = zfit.constraint.GaussianConstraint(params=list(modifiers.values()), observation=np.ones(len(modifiers)),
                                   uncertainty=0.1 * np.ones(len(modifiers)))
alpha_constraint = zfit.constraint.GaussianConstraint(alpha, 0, sigma=1)
loss_binned = zfit.loss.ExtendedBinnedNLL(model, data, constraints=[modifier_constraints, alpha_constraint])
result = minimizer.minimize(loss_binned)
print(result)
FitResult
 of
<ExtendedBinnedNLL model=[<zfit.models.binned_functor.BinnedSumPDF object at 0x7f4d38a9dd50>] data=[<zfit._data.binneddatav1.BinnedData object at 0x7f4d38dca5d0>] constraints=[<zfit.core.constraint.GaussianConstraint object at 0x7f4d38ad0c10>, <zfit.core.constraint.GaussianConstraint object at 0x7f4d404e2e50>]> 
with
<Minuit Minuit tol=0.001>

╒═════════╤═════════════╤══════════════════╤═════════╤══════════════════════════════╕
│  valid  │  converged  │  param at limit  │   edm   │   approx. fmin (full | opt.) │
╞═════════╪═════════════╪══════════════════╪═════════╪══════════════════════════════╡
│  
True
   │    True
     │      False
       │ 0.00071 │        -48785.63 | -48790.77 │
╘═════════╧═════════════╧══════════════════╧═════════╧══════════════════════════════╛
Parameters
name                                                                                         value  (rounded)    at limit
-----------------------------------------------------------------------------------------  ------------------  ----------
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_0                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_1                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_2                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_3                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_4                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_5                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_6                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_7                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_8                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_9                    1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_10                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_11                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_12                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_13                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_14            0.999999       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_15                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_16             1.00001       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_17            0.999959       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_18             1.00011       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_19            0.999505       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_20            0.999279       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_21             1.00515       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_22             1.00718       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_23            0.961558       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_24               1.017       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_25             1.05217       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_26             1.01427       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_27             1.01991       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_28             1.01051       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_29             1.04267       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_30            0.941107       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_31            0.930384       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_32             0.95839       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_33              1.0505       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_34            0.991157       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_35            0.984894       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_36             0.99943       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_37            0.996243       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_38             1.00404       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_39             1.00078       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_40             1.00063       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_41             1.00004       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_42             1.00004       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_43             1.00001       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_44            0.999992       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_45            0.999999       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_46                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_47                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_48                   1       False
auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_49                   1       False
sig_yield                                                                                             911.441       False
bkg_yield                                                                                             10094.1       False
alpha                                                                                                       0       False

mplhep.histplot(model.to_hist(), label='model')
mplhep.histplot(data, label='data')
plt.legend()
<matplotlib.legend.Legend at 0x7f4d3874b650>
../../_images/248c27981d1e8686e44945ed4db7295b015cf0b37225516185b0e046165d0744.png
print(sig_pdf.get_yield())
<zfit.ComposedParameter 'AUTO_binwise_modifier_2' params=[('sysshape_0', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_0'), ('sysshape_1', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_1'), ('sysshape_2', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_2'), ('sysshape_3', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_3'), ('sysshape_4', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_4'), ('sysshape_5', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_5'), ('sysshape_6', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_6'), ('sysshape_7', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_7'), ('sysshape_8', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_8'), ('sysshape_9', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_9'), ('sysshape_10', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_10'), ('sysshape_11', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_11'), ('sysshape_12', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_12'), ('sysshape_13', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_13'), ('sysshape_14', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_14'), ('sysshape_15', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_15'), ('sysshape_16', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_16'), ('sysshape_17', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_17'), ('sysshape_18', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_18'), ('sysshape_19', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_19'), ('sysshape_20', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_20'), ('sysshape_21', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_21'), ('sysshape_22', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_22'), ('sysshape_23', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_23'), ('sysshape_24', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_24'), ('sysshape_25', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_25'), ('sysshape_26', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_26'), ('sysshape_27', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_27'), ('sysshape_28', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_28'), ('sysshape_29', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_29'), ('sysshape_30', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_30'), ('sysshape_31', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_31'), ('sysshape_32', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_32'), ('sysshape_33', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_33'), ('sysshape_34', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_34'), ('sysshape_35', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_35'), ('sysshape_36', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_36'), ('sysshape_37', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_37'), ('sysshape_38', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_38'), ('sysshape_39', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_39'), ('sysshape_40', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_40'), ('sysshape_41', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_41'), ('sysshape_42', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_42'), ('sysshape_43', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_43'), ('sysshape_44', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_44'), ('sysshape_45', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_45'), ('sysshape_46', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_46'), ('sysshape_47', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_47'), ('sysshape_48', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_48'), ('sysshape_49', 'auto_sysshape_<zfit.models.histmodifier.BinwiseScaleModifier object at 0x7f4d402e1750>_49'), ('DUMMPY_PARAM_1', 'sig_yield')] value=907.3>

Binned to unbinned#

We can convert a histogram directly to an unbinned PDF with to_unbinned or smooth it out by interpolating with splines.

unbinned_spline = zfit.pdf.SplinePDF(sig_pdf)
plt.plot(x, unbinned_spline.pdf(x))
mplhep.histplot(sig_pdf.to_hist(), density=True)
[StairsArtists(stairs=<matplotlib.patches.StepPatch object at 0x7f4d3847d950>, errorbar=<ErrorbarContainer object of 3 artists>, legend_artist=<ErrorbarContainer object of 3 artists>)]
../../_images/82fd24ec47fde7b286fb34c542171da66af7c15b6570f08088d7903a1f5c70bb.png

hepstats#

As before, we can now use hepstats to do further statistical treatment (supports binned PDFs).

More tutorials on hepstats can be found in the zfit guides or in the hepstats tutorials