Composite Models#

Models can be created by using functors like SumPDF, ProdPDF.

There are two ways to create such models, either with the class API or with simple Python syntax.

Sum PDF#

Lets compose a sum of two gaussians by first creating each gaussian and a fraction parameter.

import numpy as np
import zfit
/home/docs/checkouts/readthedocs.org/user_builds/zfit/envs/latest/lib/python3.8/site-packages/zfit/__init__.py:62: UserWarning: TensorFlow warnings are by default suppressed by zfit. In order to show them, set the environment variable ZFIT_DISABLE_TF_WARNINGS=0. In order to suppress the TensorFlow warnings AND this warning, set ZFIT_DISABLE_TF_WARNINGS=1.
  warnings.warn(
/home/docs/checkouts/readthedocs.org/user_builds/zfit/envs/latest/lib/python3.8/site-packages/tensorflow_addons/utils/ensure_tf_install.py:53: UserWarning: Tensorflow Addons supports using Python ops for all Tensorflow versions above or equal to 2.8.0 and strictly below 2.11.0 (nightly versions are not supported). 
 The versions of TensorFlow you are currently using is 2.11.0 and is not supported. 
Some things might work, some things might not.
If you were to encounter a bug, do not file an issue.
If you want to make sure you're using a tested and supported configuration, either change the TensorFlow version or the TensorFlow Addons's version. 
You can find the compatibility matrix in TensorFlow Addon's readme:
https://github.com/tensorflow/addons
  warnings.warn(
frac = zfit.Parameter("frac_gauss", 0.5, 0, 1)

obs1 = zfit.Space('obs1', limits=(-5, 5))

mu1 = zfit.Parameter("mu1", 1.)
sigma1 = zfit.Parameter("sigma1", 1.)
gauss1 = zfit.pdf.Gauss(obs=obs1, mu=mu1, sigma=sigma1)

mu2 = zfit.Parameter("mu2", 1.)
sigma2 = zfit.Parameter("sigma2", 1.)
gauss2 = zfit.pdf.Gauss(obs=obs1, mu=mu2, sigma=sigma2)

The sum can be created like this:

sum_gauss = zfit.pdf.SumPDF(pdfs=[gauss1, gauss2], fracs=frac)
print(sum_gauss.obs)
('obs1',)

Hereby, the new pdf has the same observables as the daughter pdfs, as they coincide. If they do not, then they are combined (if there is no conflict with the limits). This can be useful to create higher dimensional pdfs.

Product PDF#

Let’s now create a 2D product of two gaussians. Again, we can choose between the Python syntax and the class API.

obs2 = zfit.Space('obs2', limits=(-3, 7))
mu3 = zfit.Parameter("mu3", 1.)
sigma3 = zfit.Parameter("sigma3", 1.)
gauss3 = zfit.pdf.Gauss(obs=obs2, mu=mu3, sigma=sigma3)  # different obs then above!
prod_gauss = zfit.pdf.ProductPDF(pdfs=[gauss1, gauss3])
prod_gauss_inverted_order = zfit.pdf.ProductPDF(pdfs=[gauss3, gauss1])  # notice the different order of the pdfS!

it is also possible to use the following code, but it should only be used for simple cases and is not recommended for more then two pdfs, since this leads to inefficinet, tree like product structures: prod_gauss = gauss1 * gauss3 # NOT RECOMMENDED FOR MORE THAN 2 PDFs!

The new pdf is now in two dimensions. The order of the observables follows the order of the pdfs given.

print("python syntax product obs", prod_gauss.obs)
print("class API product obs", prod_gauss_inverted_order.obs)
python syntax product obs
 
('obs1', 'obs2')

class API product obs
 
('obs2', 'obs1')

creating an extended PDF#

An extended PDF can either be created with the create_extended(yield_param) method or with the simple Python syntax of multiplying a PDF with the parameter.

yield1 = zfit.Parameter("yield_gauss1", 100, 0, 1000)
extended_gauss_method = gauss3.create_extended(yield1)