Custom models#
All elements of zfit are built to be easily customized. Especially models offer many possibilities to be implemented by the user; in the end, regardless of how many models are provided by a library and of how many things are though, there is always a use-case that was not thought of. High flexibility is therefore a crucial aspect.
This has disadvantages: the more freedom a model takes for itself, the less optimizations are potentially available. But this is usually not noticeable.
Creating a model#
Following the philosophy of zfit, there are different levels of customization. For the most simple use-case, all we need to do is to provide a function describing the shape and the name of the parameters. This can be done by overriding _unnormalized_pdf
.
To implement a mathematical function in zfit, znp, a numpy-like interface or z, the backend, should be used. This ensures that the function can be traced and the gradient can be calculated. If a function is not available, tf
can also be used.
(There are other ways to use arbitrary Python functions, they will be discussed later on).
import matplotlib.pyplot as plt
import mplhep
import numpy as np
import tensorflow as tf
import zfit
import zfit.z.numpy as znp
from zfit import z
2025-01-16 14:48:40.915034: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1737038920.929828 2195 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
E0000 00:00:1737038920.933982 2195 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
/home/docs/checkouts/readthedocs.org/user_builds/zfit/checkouts/latest/.venv/lib/python3.12/site-packages/zfit/__init__.py:60: 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(
We can start with a simple model and implement a custom second order polynomial. Therefore we need to inherit from the right base class, the simpler one is ZPDF
.
For a minimal example, we need to override only _unnormalized_pdf
and specify a list of parameters.
_unnormalized_pdf
gets (currently) one argument, x. This is a zfit Data
object and should first be unstacked. If it is one dimensional - such as here - it will return a single Tensor, otherwise a list of Tensors that can directly be unpacked.
class SecondOrderPoly(zfit.pdf.ZPDF):
"""Second order polynomial `a + b * x + c * x^2`"""
_PARAMS = ['b', 'c'] # specify which parameters to take
@zfit.supports(norm=False)
def _pdf(self, x, norm, params): # implement function, unnormalized
del norm # not needed
data = x[0] # axis 0
b = params['b']
c = params['c']
return 1 + b * data + c * data ** 2
Note that we omitted consciously any attempt to normalize the function, as this is usually done over a specific range. Also, no analytic sampling or integration has to be provided. The model handles all of this internally automatically and we have the full functionality available.
First, we can instantiate the model:
obs = zfit.Space("obs1", -4, 4)
b = zfit.Parameter('b', 0.2, 0.1, 10)
custom_poly = SecondOrderPoly(obs=obs, b=b, c=1.4)
2025-01-16 14:48:44.072586: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:152] failed call to cuInit: INTERNAL: CUDA error: Failed call to cuInit: UNKNOWN ERROR (303)
which lets us now fully access all the main methods of a model:
integral = custom_poly.integrate(limits=(-1, 2))
sample = custom_poly.sample(n=1000)
prob = custom_poly.pdf(sample)
print(f"integral={integral}, sample={sample}, prob={prob[:10]}")
integral=[0.11072835], sample=zfit.Data: Data obs=('obs1',) array=[[ 0.2902287 ]
[ 0.92783911]
[-3.78498173]
[-2.17733846]
[-3.30813341]
[-2.62299165]
[-2.86884693]
[-2.08553978]
[ 2.71597623]
[-2.67959492]
[ 3.4041738 ]
[-3.44355429]
[-1.90675081]
[-3.81551084]
[-2.40357873]
[ 3.9718459 ]
[ 3.63393827]
[ 2.99206899]
[ 3.0533638 ]
[-1.73041024]
[-3.64113638]
[-1.54710588]
[ 2.368732 ]
[ 3.35079368]
[ 3.08567091]
[-3.41519775]
[-3.73038062]
[ 3.36856728]
[ 3.75752284]
[-3.72900747]
[-3.7043799 ]
[ 1.71180608]
[-2.59155591]
[-3.77023251]
[-3.22115126]
[-1.67489746]
[-3.41503699]
[ 0.09764168]
[ 1.65523631]
[ 3.86550263]
[ 1.21508545]
[-3.39813062]
[-2.18786885]
[ 3.12508141]
[-0.4873718 ]
[ 3.39364943]
[-3.83510107]
[-3.74963708]
[-3.54554754]
[ 3.16849372]
[-3.86775913]
[-3.12795791]
[-1.7298153 ]
[-0.43956365]
[ 3.33031513]
[ 2.33950339]
[-2.56030326]
[ 3.97588471]
[ 2.60610161]
[ 3.77256403]
[ 2.31479227]
[ 3.54672269]
[-0.64004226]
[ 2.05196408]
[-1.39018685]
[-3.73489213]
[ 2.7517563 ]
[-1.73155924]
[-3.09949162]
[ 3.60962874]
[-2.08359084]
[-2.71751467]
[-1.44043076]
[-2.79343971]
[-1.84863735]
[-3.78848273]
[-3.70181003]
[-2.99584605]
[-2.97905971]
[ 3.1309332 ]
[ 3.95082153]
[ 3.99543417]
[-3.32584243]
[-3.7137821 ]
[ 3.64728667]
[-3.84423182]
[ 3.07981937]
[ 1.1812504 ]
[ 3.65768652]
[ 3.61352599]
[-3.89436015]
[ 3.73051226]
[ 1.91186137]
[ 3.80798252]
[ 2.95949535]
[ 3.19489029]
[ 3.87129397]
[ 1.86922951]
[-3.36781686]
[-2.29080877]
[-1.35436335]
[ 0.84217288]
[-3.87879589]
[ 2.312888 ]
[ 3.83932236]
[-1.88112206]
[ 3.43648888]
[-2.05319243]
[-3.18804824]
[ 2.08999296]
[-3.84155697]
[-2.34450196]
[ 3.29459262]
[ 1.9950945 ]
[ 2.40583432]
[-1.84976401]
[-3.40662685]
[ 3.47315846]
[-0.68771269]
[ 3.93692817]
[ 3.50635811]
[-3.23444733]
[-3.90708144]
[-2.98465191]
[-3.47371395]
[ 0.71416639]
[ 2.95223631]
[-2.5384727 ]
[-2.98466387]
[-1.508968 ]
[-3.75561783]
[ 3.60291475]
[ 3.85498931]
[ 3.11638811]
[-3.53835917]
[-2.38682796]
[-3.82575475]
[-1.27596717]
[-3.34857578]
[ 3.49871548]
[-1.24828765]
[ 3.82406274]
[-2.01381344]
[-1.44136024]
[-3.46587746]
[ 1.72148415]
[-2.72530691]
[ 2.27713435]
[-3.93463279]
[ 2.23601057]
[ 3.40499819]
[ 2.68680866]
[-2.04088481]
[-1.95648595]
[ 3.23544812]
[-3.05716534]
[-3.36031224]
[ 3.76393881]
[ 3.53829082]
[-3.87246987]
[-3.57212196]
[ 3.99418835]
[ 3.87107726]
[-3.81249692]
[-1.74271476]
[-2.22641653]
[-3.11995146]
[-2.74493121]
[-2.91147989]
[ 2.99384726]
[-3.96150562]
[ 3.83872566]
[-3.53206469]
[-1.96343225]
[-3.56295602]
[-3.98940266]
[ 3.51964708]
[ 1.96815186]
[-2.55879992]
[-2.86369065]
[-3.11847123]
[-2.71278919]
[ 3.45300684]
[-2.93749042]
[ 3.98338381]
[ 2.18026994]
[-2.57805924]
[-3.36758751]
[ 2.99544807]
[ 3.55379871]
[ 3.66134334]
[ 3.35830978]
[-2.02445472]
[ 3.40792462]
[-3.50405556]
[ 3.78073583]
[ 3.18722499]
[-3.45023445]
[-2.68567567]
[-3.2939925 ]
[ 1.94021924]
[-2.11096785]
[ 3.54663844]
[ 2.34771451]
[-2.10953837]
[ 1.68037787]
[ 3.70645851]
[-3.82621055]
[-3.65005657]
[ 2.09393387]
[-3.0922944 ]
[ 2.11941784]
[ 3.35485642]
[-1.92686728]
[ 0.98682579]
[-3.09189413]
[-3.50921088]
[-2.87331466]
[ 2.96508606]
[-3.29861425]
[ 3.27365109]
[ 1.70546917]
[-3.03574131]
[-2.51156628]
[-3.61186472]
[ 3.2160837 ]
[-2.61445858]
[ 2.71539447]
[-2.62228411]
[-3.41555611]
[ 2.80593082]
[-1.62394784]
[ 2.73553344]
[-3.04652272]
[ 3.81689862]
[ 3.20833105]
[ 3.7318863 ]
[ 3.83151323]
[-2.45253498]
[-3.85768056]
[-1.37288683]
[ 3.72632079]
[-2.06105355]
[ 3.79111681]
[-1.7852292 ]
[-3.93867802]
[ 2.14084874]
[ 3.65289759]
[-3.66197996]
[-2.31721954]
[ 2.36701387]
[ 2.09517203]
[ 1.63897832]
[-2.61434578]
[-3.12081085]
[ 3.15847474]
[-2.69415818]
[-1.08654302]
[ 3.95957 ]
[-1.57721898]
[ 3.4158447 ]
[ 3.15380465]
[ 3.90948821]
[ 0.26568762]
[ 3.43312643]
[ 3.18310868]
[ 2.94203142]
[-2.86346057]
[ 3.08049309]
[ 0.17028459]
[ 3.34766176]
[-3.46036874]
[ 2.55954863]
[-3.64082905]
[-1.32795321]
[ 2.00257543]
[ 3.98390483]
[ 2.02026091]
[ 1.40523482]
[-1.60052052]
[-3.27845757]
[ 2.23099198]
[ 0.53953566]
[-3.03477847]
[-3.60281832]
[-3.9020702 ]
[-1.68774598]
[-3.38734662]
[ 3.94994243]
[-2.84440172]
[ 0.701879 ]
[-3.06646552]
[-3.63898259]
[-3.71005301]
[ 3.82890093]
[-2.71182951]
[-3.09651475]
[ 3.79042763]
[-3.28967577]
[ 3.0816557 ]
[-3.31710266]
[-1.83583945]
[-2.88210493]
[-3.77773945]
[ 3.39799591]
[-2.30459564]
[ 3.33734368]
[-2.84678405]
[-3.20738092]
[ 3.17337926]
[ 3.12906193]
[ 3.13872005]
[ 2.95516695]
[ 2.81413484]
[-3.60051834]
[-2.34810302]
[-2.02841255]
[-2.80487582]
[-3.2305479 ]
[ 3.50997873]
[-2.96453254]
[ 3.29644201]
[ 2.27905104]
[ 2.69522317]
[ 3.27836465]
[ 0.5137699 ]
[-0.70899991]
[-2.47233131]
[-3.79824141]
[-2.26373951]
[-1.73366436]
[-2.40002652]
[-1.72274577]
[ 3.28037928]
[-3.296833 ]
[ 3.53357016]
[-3.55643693]
[ 2.87848329]
[-3.55165469]
[ 3.93258575]
[-3.77455949]
[ 3.0307125 ]
[-3.78404438]
[ 3.6016176 ]
[-3.7549292 ]
[-3.03098912]
[ 3.85281869]
[-3.58128367]
[-3.80717359]
[-2.68343807]
[ 1.75882425]
[ 3.95689891]
[-2.76377784]
[-1.83531872]
[ 3.20321083]
[ 3.65206033]
[-3.70808604]
[-3.07247903]
[-2.30103502]
[ 3.60499765]
[ 3.05238728]
[ 2.15391762]
[ 3.77194888]
[-3.3580862 ]
[-1.44634272]
[-3.08241572]
[ 2.82986753]
[ 3.17898891]
[ 2.66349069]
[ 3.46590552]
[-3.05915883]
[ 3.78827692]
[-3.12144731]
[ 2.41769027]
[ 3.26830923]
[-3.99476857]
[ 2.892029 ]
[ 2.841038 ]
[ 3.4613818 ]
[ 3.08918791]
[-3.58515972]
[ 2.24695933]
[ 3.93785939]
[ 2.50069979]
[-3.76467495]
[ 0.85847956]
[-3.97908005]
[-2.02160628]
[ 3.21451515]
[ 1.07226023]
[ 3.77988009]
[ 3.95972191]
[ 3.94229251]
[-3.8220715 ]
[-2.64495731]
[-3.13855189]
[-3.5505762 ]
[-3.22620341]
[ 3.72560374]
[-3.84313011]
[-3.64325361]
[ 2.66108448]
[ 2.3945589 ]
[ 1.53738684]
[ 3.72738543]
[-2.96206224]
[ 3.94843919]
[ 0.91411731]
[-1.67368261]
[-2.93763736]
[-3.12514667]
[ 2.49374584]
[-2.12594186]
[ 2.77430261]
[-3.26171387]
[-3.8890595 ]
[-1.70674329]
[-0.1353075 ]
[-2.59018829]
[-3.76642992]
[ 2.73483064]
[-2.17611849]
[ 2.64191047]
[-3.32430314]
[ 3.99364432]
[-2.36837469]
[ 2.57152175]
[-3.33874231]
[-3.65383026]
[-2.07483198]
[ 3.48864371]
[ 0.98503687]
[ 3.09370278]
[ 3.86128867]
[ 1.90896687]
[ 1.56120343]
[-2.28082522]
[-3.89921449]
[-3.55073616]
[-1.87368658]
[ 3.7629989 ]
[ 3.41474092]
[-1.7038673 ]
[ 3.93399335]
[ 3.02480305]
[ 3.97790436]
[ 2.55884124]
[-2.13757695]
[ 2.12665615]
[-0.69718124]
[-3.49366425]
[-2.06449408]
[-1.50309541]
[ 2.35272174]
[ 3.82712607]
[-3.61376883]
[ 3.07876995]
[ 3.69786644]
[-3.60552521]
[-3.31493409]
[-2.73868679]
[ 2.44704863]
[ 3.70428123]
[-3.66636812]
[-2.73938548]
[-3.17616142]
[-1.91626686]
[-3.05657647]
[-1.82513349]
[ 3.78369718]
[ 2.02333607]
[ 3.67235832]
[ 3.59660132]
[ 2.68657632]
[ 3.10006409]
[ 3.93858054]
[ 3.89785357]
[ 3.31832373]
[ 2.65060051]
[-2.23414089]
[-1.92003245]
[-3.71919146]
[ 3.72594123]
[ 3.49349684]
[-1.69084937]
[-3.71606194]
[-3.64689064]
[-1.78851819]
[-3.79678649]
[-2.1891321 ]
[-1.99292749]
[-2.70423664]
[ 2.57511498]
[-1.79201257]
[-1.02546074]
[-3.33913368]
[ 1.5021094 ]
[-3.3932026 ]
[ 3.05550787]
[ 3.74146353]
[-3.10166151]
[ 3.90883355]
[ 2.13101911]
[-1.73531844]
[ 1.25128962]
[ 0.89932587]
[ 2.46491386]
[-2.68620294]
[ 3.34976062]
[-0.96515614]
[ 3.17727807]
[ 3.69266476]
[ 2.6407639 ]
[-2.40414807]
[ 3.45779629]
[-3.23766767]
[ 3.87106979]
[-3.0108386 ]
[ 0.08974066]
[ 1.10450638]
[-3.14897635]
[-3.19373544]
[ 2.51401062]
[ 3.19488109]
[-3.65062869]
[ 2.9870247 ]
[-3.87026334]
[-2.94247516]
[-2.81502943]
[-3.78517908]
[-2.27291037]
[ 3.65023902]
[ 2.08751602]
[-1.41795564]
[ 3.26417075]
[ 2.34852067]
[-3.0074238 ]
[ 3.02594967]
[ 3.50055263]
[-3.89349549]
[ 3.44933498]
[ 3.64890424]
[ 2.2510119 ]
[-1.35316754]
[-3.89076154]
[ 3.4764683 ]
[ 3.83171636]
[-3.88313938]
[ 2.79163355]
[-3.88714359]
[-2.9608264 ]
[ 2.18795299]
[-3.65899131]
[ 3.23030614]
[ 3.48864061]
[ 3.88487955]
[ 2.16534974]
[-3.63234584]
[ 3.76192448]
[-2.17277708]
[-2.52520877]
[ 2.8902527 ]
[ 1.81243301]
[ 3.79253265]
[ 3.00955809]
[-3.64189304]
[ 2.23265211]
[ 1.47834286]
[ 3.24964233]
[-3.54471327]
[-2.92787545]
[-2.72425728]
[ 3.1229248 ]
[-3.8832964 ]
[-3.9276988 ]
[-3.92874189]
[-2.48933323]
[ 3.8380831 ]
[ 1.20064329]
[-2.4742986 ]
[-2.77810339]
[-3.27030963]
[-3.17063304]
[-3.76748858]
[ 3.72571144]
[-2.81611798]
[-3.50675379]
[-3.82119645]
[-3.13465728]
[ 3.92852853]
[ 3.88987807]
[ 2.85560601]
[ 3.92268346]
[-1.82173295]
[-3.18313776]
[-3.7872505 ]
[-1.87407996]
[ 3.58053483]
[ 3.36572005]
[ 3.65630333]
[ 2.76286364]
[ 1.93647302]
[ 1.51518244]
[-1.70773987]
[ 3.39046757]
[-3.65928773]
[ 2.90150857]
[ 3.96056684]
[ 3.53130708]
[-1.6419411 ]
[ 2.52592051]
[ 3.88003087]
[-3.38225671]
[ 3.30819644]
[-3.00714385]
[-3.54117978]
[ 1.66697974]
[-1.37593998]
[ 3.40395274]
[-3.74164969]
[ 2.95938775]
[-1.05213193]
[ 2.53182314]
[ 3.20536374]
[ 3.54211485]
[ 2.60497424]
[ 3.74321939]
[ 2.28070487]
[ 0.34942966]
[-2.9209154 ]
[-3.40593327]
[ 3.90876783]
[-2.84659991]
[-3.42957469]
[ 3.74623349]
[-3.30568287]
[ 2.96711967]
[-3.85780514]
[-1.665025 ]
[ 3.01989604]
[-2.66927403]
[-2.99335244]
[ 3.05975077]
[-1.47651924]
[ 2.80305564]
[-3.57607666]
[-1.17400975]
[-1.37412731]
[-2.6467979 ]
[-3.78444135]
[ 1.98501266]
[-3.15651328]
[-2.50219241]
[-3.92885883]
[ 3.78055436]
[ 3.72993644]
[-3.06243365]
[-2.3357996 ]
[-0.36760311]
[ 1.91413084]
[ 3.09870761]
[ 2.11686011]
[-2.7150142 ]
[-3.73705935]
[-3.19423801]
[ 3.7293523 ]
[ 0.86612334]
[ 3.23159864]
[-1.23768165]
[ 3.15965748]
[ 1.79462735]
[ 2.6349164 ]
[ 3.52538608]
[-2.80097246]
[-3.18837841]
[-3.01251422]
[ 1.3634209 ]
[ 3.15961053]
[-2.18604428]
[ 3.61574367]
[-3.49266076]
[ 3.54110528]
[ 3.62814684]
[ 2.778105 ]
[-3.51428661]
[-3.22126659]
[ 1.59163246]
[ 3.03124823]
[ 1.58379248]
[-1.97170764]
[ 3.7121137 ]
[ 2.96348849]
[-3.71392923]
[ 3.59310336]
[ 3.86482941]
[-2.5313821 ]
[-3.64385258]
[-3.57304929]
[-2.46889612]
[-2.33697192]
[-2.94299376]
[ 3.30410946]
[-0.66976925]
[ 2.28060043]
[-1.84638032]
[ 1.40058399]
[ 3.30888417]
[ 2.98353937]
[ 3.11546236]
[-1.57469429]
[-2.55038316]
[-2.00785426]
[ 3.21430703]
[-0.87591916]
[ 3.5299973 ]
[-3.78666693]
[ 2.69723215]
[ 3.94893 ]
[ 2.50720008]
[ 3.24704619]
[ 2.75417265]
[-3.62671056]
[ 3.16739253]
[ 3.84222812]
[-3.87475493]
[-3.60960656]
[ 2.14511071]
[-3.08855041]
[ 2.62649101]
[-3.38812615]
[ 3.20469586]
[ 3.6967388 ]
[ 3.27799986]
[ 2.59792397]
[ 1.63990957]
[-3.91985739]
[-3.8905586 ]
[-2.06695354]
[-1.31980926]
[ 3.91376203]
[ 2.68524415]
[ 1.9586603 ]
[-3.51282609]
[-3.39562333]
[-3.13475014]
[ 2.53236676]
[-3.09228996]
[-3.89900636]
[ 3.46436367]
[-3.66426762]
[ 3.20894051]
[ 3.92405054]
[-1.47282499]
[ 3.99658359]
[ 1.81711671]
[ 1.07420926]
[-3.60318303]
[-3.51607059]
[-3.31143345]
[-0.29476452]
[-1.41146043]
[ 2.54043421]
[ 2.41461824]
[-3.67905116]
[-3.90171819]
[-3.71319059]
[-2.86087332]
[ 0.70845157]
[ 1.92657144]
[ 2.29584968]
[-3.01666656]
[ 3.68638681]
[ 3.4023489 ]
[ 2.79893553]
[ 3.8647191 ]
[ 2.32615048]
[ 2.55002942]
[ 2.78373716]
[-2.62548147]
[ 3.07680044]
[ 3.9330364 ]
[ 3.07709553]
[-3.75215629]
[ 3.08986014]
[ 3.13696031]
[-2.86777188]
[ 2.99852877]
[-3.42147655]
[-3.55416101]
[ 2.47078551]
[-3.32392799]
[ 3.61266181]
[ 1.99891493]
[ 3.38783854]
[-2.81011 ]
[ 1.47189274]
[ 3.50205564]
[ 3.5268949 ]
[-3.69401713]
[ 1.68789114]
[ 1.32177554]
[-3.45176511]
[ 3.86717205]
[ 3.92152931]
[ 2.99797289]
[ 0.38693695]
[-3.90047337]
[-2.68892094]
[-2.19883717]
[ 3.47060909]
[ 3.06787487]
[-3.65275068]
[ 3.52063307]
[-3.3829859 ]
[-3.13614805]
[ 1.55288276]
[ 3.75032082]
[ 1.94488645]
[-1.92442167]
[ 1.49337155]
[ 2.40236342]
[-3.62428688]
[ 1.7014032 ]
[ 1.21343795]
[ 3.99984477]
[-3.29753232]
[-2.73075716]
[ 3.00492053]
[ 3.1600194 ]
[-3.30753553]
[-3.59132272]
[ 2.79896268]
[-3.69572478]
[ 3.74295055]
[ 3.24162788]
[-3.97057408]
[-2.75174189]
[ 3.48972665]
[-3.39401967]
[-3.41317685]
[ 3.52383019]
[ 2.71203984]
[ 3.93774052]
[-3.33611255]
[ 2.87117651]
[-1.33134417]
[ 3.39766676]
[-3.89154922]
[ 3.00838393]
[ 3.97419486]
[ 3.4329082 ]
[ 2.42385994]
[ 2.09948722]
[-3.88579058]
[ 2.76090584]
[-2.99450264]
[ 3.91670334]
[ 2.53128236]
[-3.64278286]
[ 3.9699256 ]
[ 3.64093446]
[ 3.75052928]
[ 1.39137557]
[ 3.15117867]
[-2.5686478 ]
[ 3.876156 ]
[-1.59630233]
[ 2.47035412]
[ 2.07708393]
[-3.05381633]
[-2.10861346]
[ 3.4595495 ]
[ 3.25000692]
[ 3.80741237]
[ 3.71338262]
[-3.38799786]
[ 2.46274207]
[ 1.99194366]
[-3.19497987]
[ 2.71484755]
[ 3.88650273]
[ 2.91413241]
[ 2.96368015]
[ 3.58595992]
[-3.59752112]
[ 3.27842263]
[ 3.75397132]
[-3.23633057]
[ 1.24407576]
[-2.73172888]
[-3.19582472]
[ 3.28196994]
[-3.11513202]
[-1.8792819 ]
[ 3.92149514]
[ 2.92947678]
[-1.25277394]
[-2.89755893]
[-2.67798286]
[-3.65989219]
[ 0.89715105]
[-3.03758919]
[-3.53525891]
[-3.81689868]
[ 3.62738803]
[ 3.83182762]
[-3.45628894]
[-2.06695347]
[-3.89932935]
[-1.64056029]
[-3.52059919]
[ 2.59446619]
[ 3.62588124]
[ 3.86912796]
[-1.50374061]
[ 3.73728317]
[ 2.58799998]
[-3.93641135]
[ 3.90433453]
[ 2.16980216]
[ 1.04647297]
[-3.86849497]
[ 1.77857504]
[ 3.13680478]
[-2.0362385 ]
[-3.67932131]
[ 2.06807083]
[ 2.91261107]
[ 2.93461171]
[-1.45146722]
[-2.6433062 ]
[-3.40625229]
[ 2.62109543]
[-2.68870228]
[-0.89088973]
[ 3.11890873]
[ 2.86466943]
[ 2.19137559]
[ 3.42299362]
[ 1.21932459]
[ 3.92414694]
[ 3.23099712]
[-3.72321482]
[ 3.943895 ]
[ 2.05759837]
[ 3.36738108]
[ 2.73782558]
[ 3.08836262]
[ 3.92693383]
[ 3.76314834]
[-3.44350034]
[ 1.3903824 ]
[ 2.34520965]
[ 2.44096943]
[ 3.88602965]
[-3.45329487]
[-3.05569475]
[-2.00479557]
[ 0.28594864]
[ 2.90566518]
[ 2.35937781]
[-0.89158632]
[-2.44568401]
[-2.0143462 ]
[-2.48179923]
[-1.30617335]
[ 3.54420617]
[-3.26836216]
[ 3.44844816]
[ 3.86536761]
[-2.46863741]
[ 0.1557167 ]
[-2.7495754 ]
[-1.1095885 ]
[-3.70195026]
[-3.91622372]
[ 2.23517573]
[-3.49465822]
[ 2.45129871]
[-3.94423649]
[-0.95832452]
[ 3.64891727]
[ 3.08546736]
[ 2.35986669]
[ 1.98644505]
[-2.77880927]
[-2.99734765]
[-3.43161641]
[ 2.10012556]
[-2.80217012]
[ 1.65720827]
[ 2.28998175]
[-3.77952767]
[ 1.07364408]
[-3.15529608]
[-1.43008647]
[-1.30075962]
[ 1.75266302]
[ 2.01391857]
[-2.65658665]], prob=[0.01736178 0.03529735 0.29969771 0.10632366 0.23119516 0.14922521
0.17640689 0.09850628 0.17525098 0.15526183]
What happened?#
The model tries to use analytical functions for integration and sampling if available, otherwise (as happened above), it falls back to the numerical methods. To improve our model, we can add an analytic integral, a common use case. This has to be the integral over the _unnormalized_pdf
.
# define the integral function
def cdf_poly(limit, b, c):
return limit + 0.5 * b * limit ** 2 + 1 / 3 * c * limit ** 3
def integral_func(limits, norm, params, model):
del norm, model # not needed
b = params['b']
c = params['c']
lower, upper = limits.v1.limits
# calculate the integral
integral = cdf_poly(upper, b, c) - cdf_poly(lower, b, c)
print("Integral called")
return integral
# define the space over which it is defined. Here, we use the axes
integral_limits = zfit.Space(axes=(0,), limits=(zfit.Space.ANY, zfit.Space.ANY))
SecondOrderPoly.register_analytic_integral(func=integral_func, limits=integral_limits)
poly2 = SecondOrderPoly(obs=obs, b=b, c=1.2)
integral_analytic = custom_poly.integrate(limits=(-1, 2))
sample = custom_poly.sample(n=1000)
prob_analytic = custom_poly.pdf(sample)
print(f"integral={integral}, sample={sample}, prob={prob[:10]}")
Integral called
Integral called
Integral called
integral=[0.11072835], sample=zfit.Data: Data obs=('obs1',) array=[[-2.68770473]
[-0.31764066]
[-3.12792264]
[ 3.79304801]
[-3.38407529]
[-2.93535652]
[-3.05556305]
[-3.6942316 ]
[ 3.58647761]
[ 1.17089273]
[-2.3927393 ]
[ 2.43757406]
[-3.84422545]
[-3.93033904]
[-2.39579633]
[ 3.89210121]
[ 2.14976432]
[ 2.68373363]
[-3.64518816]
[ 2.49960645]
[ 2.99364456]
[-2.20841194]
[-3.0842424 ]
[-3.18511171]
[ 0.97028181]
[ 3.64905712]
[-1.44165202]
[ 3.67034743]
[ 3.64254516]
[-2.50306698]
[-3.93164684]
[-3.76191421]
[ 3.98975123]
[-1.10652203]
[ 2.26051182]
[ 3.913581 ]
[ 2.94105008]
[-3.48582353]
[ 1.79296619]
[-2.41801312]
[ 3.68998328]
[ 3.81962705]
[ 3.15753546]
[ 1.34345976]
[ 3.81120969]
[-2.43382023]
[ 3.54421545]
[-2.13184229]
[ 3.53285911]
[ 3.89625832]
[ 3.81226562]
[ 1.0728869 ]
[-3.99809066]
[-3.72651794]
[ 1.77634945]
[-2.4140185 ]
[ 3.06865658]
[ 3.12507005]
[ 3.61481363]
[ 2.0769006 ]
[-3.07619099]
[ 3.33434304]
[-3.65771102]
[-3.45768011]
[ 1.31791383]
[-2.75088626]
[-2.13844198]
[ 0.07618319]
[-3.44936462]
[ 3.88055799]
[ 3.24738157]
[ 0.46279556]
[ 2.11896954]
[ 3.85285303]
[ 3.99931429]
[-3.50559462]
[-3.3394492 ]
[ 2.28072442]
[ 1.74415414]
[ 2.42541643]
[-3.05979422]
[-2.54746372]
[ 2.60101723]
[-3.63208189]
[-3.51231102]
[ 2.71578453]
[ 3.61538056]
[ 3.01364198]
[ 3.04282608]
[-3.4419828 ]
[-1.30930159]
[ 3.57146033]
[ 3.45023266]
[ 3.12650025]
[ 3.55745923]
[-3.20332594]
[ 3.21447428]
[-3.49153512]
[ 1.96027955]
[-2.85106429]
[-3.30958885]
[ 3.34213205]
[ 2.50366416]
[ 3.83467184]
[-3.09791082]
[-0.72472408]
[-1.61075556]
[-3.23624762]
[ 3.06371731]
[ 2.51953039]
[ 3.47515024]
[ 3.48186595]
[-3.90656081]
[-3.02352938]
[ 3.27933776]
[-2.90648105]
[-2.54254738]
[-3.52460066]
[-3.90423275]
[ 2.31101527]
[ 3.6943701 ]
[ 2.39206529]
[-3.91296743]
[-1.85780656]
[ 3.26024184]
[ 2.00879245]
[-1.85439795]
[-3.45773652]
[-1.07391161]
[ 1.33809141]
[-2.51042656]
[ 2.61602668]
[-3.31845051]
[-1.54145079]
[-0.15177936]
[ 3.12904138]
[-3.7333433 ]
[ 2.41469514]
[ 2.77269396]
[ 1.13494371]
[-2.54414079]
[ 2.73356114]
[-2.740599 ]
[ 1.53673652]
[-0.6801799 ]
[-2.7397664 ]
[ 2.78785954]
[ 3.22105966]
[-2.8872163 ]
[ 3.58703104]
[-2.22364191]
[-2.8208712 ]
[-3.28912614]
[-2.56166489]
[-3.63186916]
[-3.84030036]
[-3.98758835]
[ 1.89395514]
[-2.9257087 ]
[-2.75970689]
[ 3.57886532]
[-3.61202488]
[ 2.97719107]
[ 1.80502609]
[-3.84441643]
[ 2.73532902]
[-3.46128905]
[ 2.96826176]
[-2.90781664]
[-3.13176726]
[ 3.79750184]
[ 1.5354838 ]
[-0.19391918]
[-2.50791234]
[ 3.44050874]
[ 3.98294098]
[ 3.17074435]
[ 2.40431656]
[-3.85444912]
[-3.967601 ]
[ 1.27906302]
[-3.84373995]
[ 3.6116763 ]
[ 2.86075158]
[-2.79605002]
[ 2.8105561 ]
[-1.83441007]
[-1.0495188 ]
[ 3.84720983]
[ 2.42994578]
[ 3.22215096]
[-3.272496 ]
[ 3.79000355]
[-2.36624998]
[-2.86436299]
[ 0.26186357]
[-2.27823901]
[ 3.09167274]
[ 3.89272685]
[ 3.60494738]
[ 3.2411596 ]
[ 3.6863526 ]
[ 2.13817982]
[-2.09459615]
[ 2.97735722]
[ 1.44574881]
[ 2.83902676]
[ 2.06503027]
[ 2.19822322]
[-3.40447846]
[ 3.06773854]
[-2.51427945]
[ 3.47967318]
[-1.82446788]
[ 3.85035056]
[ 3.1997919 ]
[ 1.84119186]
[-3.43965763]
[-2.81256297]
[-3.61485039]
[ 2.87662957]
[-1.25897447]
[ 2.25214176]
[-3.83315553]
[-0.99904768]
[-2.7367858 ]
[-1.6312409 ]
[-3.48675813]
[ 3.40777054]
[-3.25792405]
[ 2.2289688 ]
[ 1.30339551]
[-2.10579795]
[-2.55051805]
[-3.52357735]
[ 3.82158065]
[-3.02475097]
[ 2.80752741]
[-2.6884258 ]
[ 3.99133583]
[-2.51961863]
[ 2.96564143]
[ 2.24226623]
[ 0.25212759]
[-3.23121906]
[ 2.50188719]
[-3.61909688]
[ 2.05276799]
[ 2.83226689]
[-2.60084314]
[-2.56254738]
[ 2.89665283]
[ 2.70890964]
[ 3.97891129]
[ 3.51127238]
[-3.63694263]
[ 3.46847226]
[-3.89906662]
[ 3.3943512 ]
[-3.29534346]
[ 3.30581766]
[-3.87964006]
[ 0.6579303 ]
[-1.52114095]
[-1.20938318]
[ 3.22540623]
[-3.87833651]
[ 3.58266293]
[-3.44720414]
[ 0.13396731]
[ 3.45783641]
[-2.77500359]
[-2.83502957]
[-3.89045805]
[ 2.91213743]
[-2.06993765]
[-3.60481069]
[-3.95850069]
[-3.87640972]
[-3.91494602]
[ 3.56786654]
[-3.11474199]
[ 3.7955938 ]
[ 3.21941314]
[-2.73026665]
[-1.44913779]
[-3.50493084]
[ 3.62916835]
[ 3.56808194]
[-2.65850959]
[ 2.75221465]
[-3.72712866]
[-2.36946275]
[ 2.66318681]
[-2.2041618 ]
[-2.2654701 ]
[ 3.74492275]
[-3.43063535]
[-2.81663842]
[-3.10632542]
[-0.48542829]
[-1.64008723]
[-2.91543254]
[ 2.96970813]
[ 1.93624861]
[ 2.13194114]
[ 1.61798176]
[ 3.51751065]
[ 1.84509688]
[ 0.67557623]
[ 3.93018384]
[ 3.19026311]
[ 1.93160026]
[ 2.02830715]
[-2.80119921]
[ 3.80992719]
[ 3.86917943]
[-3.73847765]
[-0.61524368]
[-2.19004306]
[ 3.98986009]
[-3.24717615]
[ 3.42632389]
[ 2.46313014]
[-2.66189447]
[-2.80387122]
[-3.78150632]
[ 2.65739154]
[ 3.36326995]
[-2.63986046]
[ 1.67929217]
[ 2.34891639]
[-2.46072344]
[ 3.67513067]
[-1.9435059 ]
[-3.80273816]
[ 0.62185134]
[-3.95202644]
[-3.83717279]
[-3.6723084 ]
[-3.07838167]
[ 3.62894762]
[-1.25836753]
[ 2.91801473]
[-3.10351231]
[ 2.54661651]
[ 2.22568492]
[-2.69350722]
[ 3.97817256]
[ 3.09179642]
[-3.31818293]
[-1.58189526]
[ 3.96420862]
[-3.81886307]
[-3.53864955]
[ 3.28738378]
[-1.07780783]
[ 1.40170636]
[ 2.54321919]
[ 2.07967836]
[ 3.17972798]
[-2.18457713]
[-3.16017476]
[-3.60736914]
[ 2.53075226]
[ 3.95443679]
[-3.92953473]
[ 2.32687719]
[ 3.16654248]
[-3.87003448]
[ 2.37129471]
[ 2.27454755]
[ 3.71285996]
[-3.11974493]
[ 3.65491685]
[ 2.69484901]
[-2.87733641]
[ 2.44395421]
[-3.51518783]
[ 1.51405008]
[ 3.0938574 ]
[ 1.72306206]
[ 3.1302625 ]
[-3.50926159]
[-3.5310379 ]
[-3.05053857]
[ 3.82195991]
[ 3.12365583]
[-3.6152529 ]
[ 0.71622162]
[ 2.04565408]
[ 3.6559483 ]
[-3.46220601]
[-2.68204474]
[-3.04408016]
[-2.27012028]
[ 3.76307353]
[ 3.5503385 ]
[-1.79855723]
[ 2.45507867]
[-2.96396139]
[ 3.68387846]
[-1.92329418]
[-3.73287462]
[-2.08223039]
[-3.07008103]
[ 3.97588815]
[-2.84056811]
[ 3.87811154]
[-2.25144262]
[-2.51067605]
[ 3.60072378]
[-2.32960144]
[ 3.75095079]
[ 3.42289428]
[ 3.00711098]
[-2.92612709]
[-3.09716466]
[ 3.45235074]
[ 3.94903641]
[-2.31059605]
[ 2.44067458]
[-3.69252447]
[-3.98506504]
[-3.98298176]
[ 3.69412262]
[ 1.78298809]
[-3.43910478]
[-2.94580471]
[-3.36406985]
[ 3.12810051]
[-2.0821018 ]
[-2.48401769]
[ 1.65513998]
[ 2.76321078]
[-3.95006711]
[ 2.40347504]
[ 3.06828779]
[ 1.30020479]
[-3.34282413]
[-3.77911866]
[ 2.39788309]
[-2.98062649]
[-3.13865037]
[-1.70948816]
[ 2.45780767]
[ 3.6978577 ]
[ 3.4400073 ]
[-3.79133886]
[-2.86184819]
[ 3.01251973]
[ 3.38102933]
[ 0.66762738]
[-3.97467118]
[ 3.46656969]
[ 0.32278329]
[-3.48854372]
[-2.6361567 ]
[ 3.84869272]
[-1.08815039]
[-2.75087555]
[-3.61353639]
[ 3.57236928]
[-2.94699395]
[-1.15567554]
[ 3.05780142]
[-3.06872659]
[ 2.04365257]
[-3.51537875]
[-3.62110939]
[-3.26332135]
[-2.69984525]
[ 3.78059489]
[-3.36516624]
[ 3.29763013]
[-3.44097658]
[-3.94234083]
[ 2.31893584]
[ 3.52234227]
[ 1.97541475]
[ 3.47076166]
[ 3.26462437]
[-3.61893081]
[ 3.17766927]
[-3.97293565]
[ 2.18460264]
[-1.90800693]
[ 2.66836227]
[ 1.0268203 ]
[-3.17177033]
[-2.13571259]
[ 2.69662808]
[ 3.40171899]
[ 3.05946608]
[ 3.42032008]
[ 3.64193653]
[ 2.41596379]
[ 1.88406419]
[ 3.29602373]
[ 2.9621831 ]
[-3.49550757]
[-1.28989255]
[ 3.15914627]
[ 3.19694281]
[ 3.433889 ]
[ 3.43918392]
[ 0.09078738]
[ 3.06840352]
[-2.90305483]
[-2.90801897]
[-1.67030492]
[ 3.03663785]
[-0.22745691]
[-3.92593415]
[ 1.14830899]
[-1.33373871]
[-3.91812868]
[ 3.71895827]
[-3.13700297]
[-3.39970237]
[-1.98528241]
[ 3.47325279]
[-2.51118387]
[ 1.46544572]
[-3.22965651]
[ 3.43736096]
[ 3.63109118]
[-3.34073791]
[-2.21722471]
[ 3.83605066]
[ 0.83580095]
[ 3.79849297]
[ 3.0834046 ]
[ 3.71635253]
[ 3.69919084]
[ 3.12720145]
[-2.73899334]
[ 3.68736615]
[-1.4630947 ]
[-2.8183496 ]
[ 3.81241772]
[ 3.86131581]
[ 1.86974262]
[ 2.31880442]
[-2.12182428]
[ 3.63483919]
[ 2.97356038]
[ 3.76789097]
[ 3.51980597]
[ 0.68720608]
[ 3.56670025]
[-2.86906154]
[-3.76735344]
[ 2.20020953]
[-0.18822119]
[-1.5181038 ]
[ 3.39187575]
[-1.76287772]
[-2.00847882]
[-3.65041726]
[ 2.78079518]
[ 2.79601962]
[-3.69132457]
[-3.13071553]
[-2.88704569]
[ 3.6227754 ]
[-3.36020017]
[-1.93149601]
[-2.69505551]
[ 2.07875227]
[ 0.78979715]
[ 3.03585575]
[-0.60447039]
[ 3.87540827]
[-3.36657733]
[-2.63031978]
[ 3.9930064 ]
[ 3.61156751]
[-3.71941084]
[ 3.60995572]
[ 2.1195835 ]
[-2.74809702]
[-3.37687887]
[ 2.83972493]
[ 2.52043951]
[ 2.8133975 ]
[-3.71554785]
[ 2.15162908]
[ 3.01535562]
[-2.8371543 ]
[ 2.48454298]
[-1.08859087]
[-2.52146663]
[-3.48202468]
[ 2.5779959 ]
[ 2.86097686]
[ 2.77667645]
[-3.26387702]
[ 3.11122419]
[-2.96403111]
[-3.56895938]
[ 2.77096206]
[ 3.85382964]
[-3.59390123]
[-3.99588735]
[-2.7083496 ]
[-3.40065387]
[ 3.94840513]
[ 0.14502762]
[-2.45325287]
[ 3.84503736]
[ 3.79286865]
[ 3.63615903]
[ 3.96115902]
[-3.95697786]
[ 2.24289965]
[-1.99209032]
[ 3.31837755]
[-2.94850382]
[-3.90096577]
[ 2.38465896]
[-3.30220763]
[-2.18257149]
[ 1.16049377]
[ 2.74484245]
[ 1.7964795 ]
[ 3.89087595]
[-3.1349635 ]
[ 2.90971883]
[ 2.98936479]
[ 3.66174562]
[-3.62440563]
[ 1.74038528]
[-3.0679416 ]
[-2.71434287]
[-3.87777196]
[ 2.9625249 ]
[-3.83590967]
[-2.0859476 ]
[-2.58222967]
[-2.77203509]
[-2.38024489]
[ 1.33496011]
[ 2.31689927]
[-1.20334183]
[-2.91309598]
[ 2.63639417]
[ 3.62057032]
[-1.49939132]
[ 2.62612523]
[ 3.69098953]
[-0.04987054]
[-2.13527157]
[-2.8938234 ]
[ 3.38569686]
[ 2.09462644]
[ 3.19000094]
[-3.80594537]
[-3.88367873]
[-3.94392634]
[ 3.86968663]
[-3.7167528 ]
[-3.45018428]
[-3.80568883]
[ 3.6983224 ]
[ 2.2417824 ]
[-2.83517011]
[ 2.02862974]
[-1.92639817]
[ 3.181351 ]
[-3.18363483]
[-3.85927904]
[ 2.38678796]
[-1.2949296 ]
[ 3.97782743]
[ 2.85218436]
[ 3.76205089]
[ 3.86026937]
[-3.46931277]
[ 3.26603799]
[ 1.83226441]
[ 3.55516419]
[-2.95446623]
[-3.65060992]
[-3.90497812]
[ 2.26850225]
[ 3.46484436]
[ 3.86900936]
[-3.00388735]
[-3.46353209]
[ 2.45824584]
[ 1.63847191]
[ 3.04648941]
[ 2.98482996]
[ 3.76971372]
[ 1.33275282]
[ 3.61265763]
[ 3.15015454]
[-3.39861311]
[ 3.6698583 ]
[ 3.63182536]
[-3.81436079]
[ 2.18736158]
[ 2.06661118]
[ 3.42970928]
[ 3.49493262]
[-3.36125682]
[ 2.60758501]
[-3.71534938]
[ 2.12584086]
[ 3.23921844]
[ 3.3086602 ]
[ 1.99634731]
[ 3.95179205]
[-0.73398251]
[ 3.31573054]
[ 3.47499605]
[ 1.59667714]
[ 2.07593451]
[-3.80798879]
[-2.68220372]
[ 3.76300481]
[ 3.2745929 ]
[-3.702792 ]
[ 2.51994326]
[ 3.84782217]
[-2.51339647]
[ 3.33531988]
[ 3.48697948]
[ 3.94030343]
[ 1.31450598]
[-1.7286161 ]
[-1.15245927]
[ 2.44210156]
[ 3.68176371]
[ 3.88904561]
[ 2.75192811]
[-2.97905582]
[-3.95876041]
[-3.24819083]
[-3.96910248]
[-3.20271359]
[-2.31894518]
[-3.39137385]
[-3.81547561]
[-1.52268109]
[ 3.40865452]
[-3.83576839]
[-1.45376477]
[-3.50623091]
[-3.66790172]
[ 2.44502552]
[ 1.97489861]
[ 2.69355924]
[ 3.3352064 ]
[ 3.92636999]
[-3.52389689]
[ 3.22547662]
[-1.36271311]
[ 2.5176171 ]
[-3.01159717]
[ 2.9693513 ]
[ 3.30685885]
[-3.08540362]
[-3.08970216]
[-3.95146284]
[-2.07258138]
[ 3.06214421]
[ 3.30823366]
[ 3.455569 ]
[ 2.65200398]
[ 2.61685378]
[ 1.55543481]
[-3.12241235]
[ 3.64800522]
[ 3.66611363]
[-2.08909106]
[ 2.91730939]
[-3.56898744]
[ 3.86277789]
[ 1.27923989]
[ 3.73847674]
[ 3.10018963]
[ 3.71328406]
[ 1.55650673]
[ 3.36743677]
[ 1.46892616]
[ 3.3826244 ]
[-3.94491749]
[ 3.80997001]
[-3.87895627]
[ 2.38881328]
[ 3.0455609 ]
[-1.4686604 ]
[ 3.93407597]
[-3.63401519]
[ 1.83446624]
[ 2.5721078 ]
[ 0.73172487]
[ 2.79678879]
[ 2.03807639]
[-1.89810115]
[-3.44530608]
[ 3.40949595]
[ 2.73214502]
[ 3.66964866]
[ 3.49780244]
[-2.73034 ]
[ 3.33745868]
[ 3.12407532]
[ 3.69672576]
[-3.25986104]
[ 2.87810885]
[ 3.22713211]
[ 3.0267872 ]
[ 3.28112764]
[ 3.51977344]
[-3.6852307 ]
[ 1.48646132]
[ 2.89527631]
[-2.44745806]
[ 3.65780157]
[-3.09815929]
[ 3.50197419]
[-3.79090531]
[-3.4845325 ]
[-2.96125512]
[-3.9747714 ]
[-3.40361421]
[-3.21295139]
[ 2.02604349]
[ 1.69184163]
[ 3.80862137]
[-1.51778383]
[ 3.76628047]
[-0.42844058]
[ 3.45282546]
[-3.87320819]
[-2.13227064]
[-1.45427786]
[ 2.95163046]
[-3.37255574]
[-2.96204203]
[ 0.96555729]
[ 2.42143569]
[ 3.56715485]
[-3.77789428]
[ 3.81122829]
[ 2.49673455]
[ 3.92679724]
[-2.03098782]
[-3.75309384]
[ 3.82064023]
[-3.88487598]
[ 1.58680824]
[ 1.19575641]
[ 3.42180329]
[ 3.31196557]
[ 2.70131222]
[-2.79088948]
[-3.54402065]
[ 2.97356906]
[ 3.88596844]
[ 3.93593341]
[ 3.62093106]
[ 3.2776548 ]
[-3.00401387]
[-3.09846211]
[ 3.05136018]
[ 2.40268964]
[-3.44922043]
[ 0.79279443]
[-0.86167102]
[-2.70188228]
[-3.68309818]
[ 3.65831426]
[ 3.60283872]
[ 1.98573258]
[-2.91608825]
[-2.70549324]
[-3.31791744]
[ 1.59209715]
[ 1.39854545]
[ 1.9997012 ]
[ 3.8977289 ]
[ 1.11853891]
[ 3.28066978]
[-3.5263748 ]
[-3.9945486 ]
[-3.22474575]
[ 0.52186538]
[-3.51329106]
[ 3.48666925]
[ 3.69458705]
[-3.05267088]
[-3.37415234]
[ 2.91662451]
[ 0.26086374]
[-3.35720142]
[-3.6883677 ]
[-3.46956508]
[-1.32894789]
[-2.03204539]
[ 3.46729046]
[-2.83335979]
[-3.14572254]
[-1.39218946]
[ 3.46840692]
[-3.32669576]
[ 0.92146128]
[-2.65662831]
[ 3.68437281]
[ 3.83929773]
[-3.49635542]
[ 3.50992867]
[ 3.3380844 ]
[-3.13957623]
[ 2.87463289]
[-2.12771563]
[-3.34500635]
[-3.26953542]
[-0.98083001]
[ 3.81398489]
[ 1.94397058]
[-2.45787845]
[ 2.01236516]
[-2.01627387]
[-3.1495951 ]
[-1.63700821]
[-3.95678653]
[ 1.14853499]
[-0.6118012 ]
[ 2.86152889]
[-3.36880007]
[ 3.27051526]
[-0.87821786]
[ 3.54950604]
[-2.39095573]
[-2.80228352]
[ 3.41293129]
[ 2.81528648]
[ 3.27577756]
[-3.98277845]
[ 3.07427414]
[-3.80227415]
[ 2.98530102]
[-3.74880149]
[ 3.53147814]
[-2.12346816]
[ 2.52462897]
[-3.50606759]
[ 3.40872899]
[ 3.22701458]
[ 3.49447019]
[-0.68636307]
[ 3.10671636]
[-2.92143146]
[-3.1277851 ]
[ 2.56736525]
[-3.14178828]
[ 3.13874544]
[-2.61286819]
[-3.21303894]
[ 0.47226442]
[-2.04496222]
[-2.3808212 ]
[ 2.14792668]
[-2.57262519]
[ 2.39687657]
[-3.56353662]
[-3.75792393]
[ 3.03085224]
[ 3.89565213]
[-3.80783325]
[-3.21187811]
[ 2.65178469]
[-3.12642095]
[-3.07393252]
[ 3.68257259]
[ 3.7877556 ]
[-3.41375523]
[ 3.0279346 ]
[ 2.44472089]
[ 2.54905004]
[ 2.83855548]
[ 2.86173861]
[-2.53634601]
[ 3.42934146]
[-1.58961844]
[ 1.42795587]
[ 3.79139701]
[ 1.89703636]
[ 3.10056909]
[-1.40524386]
[-1.61604439]
[ 1.66930568]
[ 2.51548795]
[ 2.86216652]
[-0.12909924]
[-3.62880723]], prob=[0.01736178 0.03529735 0.29969771 0.10632366 0.23119516 0.14922521
0.17640689 0.09850628 0.17525098 0.15526183]
Multiple dimensions and parameters with angular observables#
So far, we used rather simple examples and many basic shapes, such as polynomials, already have an efficient implementation within zfit. Therefore, we will now create a three dimensional PDF measuring the angular observables of a \(B^+ \rightarrow K^* l l\) decay.
The implementation is not “special” or complicated at all, it rather shows how to deal with multiple dimensions and how to manage several parameters. It was created using the equation of the angular observables (taken from a paper).
Many thanks to Rafael Silva Coutinho for the implementation!
class AngularPDF(zfit.pdf.ZPDF):
"""Full d4Gamma/dq2dOmega for Bd -> Kst ll (l=e,mu)
Angular distribution obtained in the total PDF (using LHCb convention JHEP 02 (2016) 104)
i.e. the valid of the angles is given for
- phi: [-pi, pi]
- theta_K: [0, pi]
- theta_l: [0, pi]
The function is normalized over a finite range and therefore a PDF.
Args:
FL (`zfit.Parameter`): Fraction of longitudinal polarisation of the Kst
S3 (`zfit.Parameter`): A_perp^2 - A_para^2 / A_zero^2 + A_para^2 + A_perp^2 (L, R)
S4 (`zfit.Parameter`): RE(A_zero*^2 * A_para^2) / A_zero^2 + A_para^2 + A_perp^2 (L, R)
S5 (`zfit.Parameter`): RE(A_zero*^2 * A_perp^2) / A_zero^2 + A_para^2 + A_perp^2 (L, R)
AFB (`zfit.Parameter`): Forward-backward asymmetry of the di-lepton system (also i.e. 3/4 * S6s)
S7 (`zfit.Parameter`): IM(A_zero*^2 * A_para^2) / A_zero^2 + A_para^2 + A_perp^2 (L, R)
S8 (`zfit.Parameter`): IM(A_zero*^2 * A_perp^2) / A_zero^2 + A_para^2 + A_perp^2 (L, R)
S9 (`zfit.Parameter`): IM(A_perp*^2 * A_para^2) / A_zero^2 + A_para^2 + A_perp^2 (L, R)
obs (`zfit.Space`):
name (str):
dtype (tf.DType):
"""
_PARAMS = ['FL', 'S3', 'S4', 'S5', 'AFB', 'S7', 'S8', 'S9']
_N_OBS = 3
@zfit.supports(norm=False)
def _pdf(self, x, norm, params): # or _unnormalized_pdf
del norm
FL = params['FL']
S3 = params['S3']
S4 = params['S4']
S5 = params['S5']
AFB = params['AFB']
S7 = params['S7']
S8 = params['S8']
S9 = params['S9']
costheta_l = x[0]
costheta_k = x[1]
phi = x[2]
sintheta_k = tf.sqrt(1.0 - costheta_k * costheta_k)
sintheta_l = tf.sqrt(1.0 - costheta_l * costheta_l)
sintheta_2k = (1.0 - costheta_k * costheta_k)
sintheta_2l = (1.0 - costheta_l * costheta_l)
sin2theta_k = (2.0 * sintheta_k * costheta_k)
cos2theta_l = (2.0 * costheta_l * costheta_l - 1.0)
sin2theta_l = (2.0 * sintheta_l * costheta_l)
pdf = ((3.0 / 4.0) * (1.0 - FL) * sintheta_2k +
FL * costheta_k * costheta_k +
(1.0 / 4.0) * (1.0 - FL) * sintheta_2k * cos2theta_l +
-1.0 * FL * costheta_k * costheta_k * cos2theta_l +
S3 * sintheta_2k * sintheta_2l * znp.cos(2.0 * phi) +
S4 * sin2theta_k * sin2theta_l * znp.cos(phi) +
S5 * sin2theta_k * sintheta_l * znp.cos(phi) +
(4.0 / 3.0) * AFB * sintheta_2k * costheta_l +
S7 * sin2theta_k * sintheta_l * znp.sin(phi) +
S8 * sin2theta_k * sin2theta_l * znp.sin(phi) +
S9 * sintheta_2k * sintheta_2l * znp.sin(2.0 * phi))
return pdf
Multidimensional Spaces#
This PDF now expects multidimensional data. Therefore, we need to provide a Space in multiple dimensions. The preferred way is to use the product operations to build this space from one dimensional Space
s
costhetha_k = zfit.Space('costheta_k', -1, 1)
costhetha_l = zfit.Space('costheta_l', lower=-1, upper=1)
phi = zfit.Space('phi', -np.pi, np.pi)
angular_obs = costhetha_k * costhetha_l * phi
Managing parameters#
Luckily, we’re in Python, which provides many tools out-of-the-box. Handling parameters in a dict
can make things very easy, even for several parameters as here.
params_init = {'FL': 0.43, 'S3': -0.1, 'S4': -0.2, 'S5': -0.4, 'AFB': 0.343, 'S7': 0.001, 'S8': 0.003, 'S9': 0.002}
params = {name: zfit.Parameter(name, val, -1, 1) for name, val in params_init.items()}
angular_pdf = AngularPDF(obs=angular_obs, **params)
integral_analytic = angular_pdf.integrate(limits=angular_obs) # this should be one
sample = angular_pdf.sample(n=1000)
prob_analytic = angular_pdf.pdf(sample)
print(f"integral={integral}, sample={sample}, prob={prob[:10]}")
Estimated integral error ( 2.4615430566483435e-05 ) larger than tolerance ( 3e-06 ), which is maybe not enough (but maybe it's also fine). You can (best solution) implement an anatytical integral (see examples in repo) or manually set a higher number on the PDF with 'update_integration_options' and increase the 'max_draws' (or adjust 'tol'). If partial integration is chosen, this can lead to large memory consumption.This is a new warning checking the integral accuracy. It may warns too often as it is Work In Progress. If you have any observation on it, please tell us about it: https://github.com/zfit/zfit/issues/new/chooseTo suppress this warning, use zfit.settings.set_verbosity(-1).
Estimated integral error ( 2.4615430566483435e-05 ) larger than tolerance ( 3e-06 ), which is maybe not enough (but maybe it's also fine). You can (best solution) implement an anatytical integral (see examples in repo) or manually set a higher number on the PDF with 'update_integration_options' and increase the 'max_draws' (or adjust 'tol'). If partial integration is chosen, this can lead to large memory consumption.This is a new warning checking the integral accuracy. It may warns too often as it is Work In Progress. If you have any observation on it, please tell us about it: https://github.com/zfit/zfit/issues/new/chooseTo suppress this warning, use zfit.settings.set_verbosity(-1).
Estimated integral error ( 2.4615430566483435e-05 ) larger than tolerance ( 3e-06 ), which is maybe not enough (but maybe it's also fine). You can (best solution) implement an anatytical integral (see examples in repo) or manually set a higher number on the PDF with 'update_integration_options' and increase the 'max_draws' (or adjust 'tol'). If partial integration is chosen, this can lead to large memory consumption.This is a new warning checking the integral accuracy. It may warns too often as it is Work In Progress. If you have any observation on it, please tell us about it: https://github.com/zfit/zfit/issues/new/chooseTo suppress this warning, use zfit.settings.set_verbosity(-1).
integral=[0.11072835], sample=zfit.Data: Data obs=('costheta_k', 'costheta_l', 'phi') array=[[-0.89847382 -0.93463893 -0.83796326]
[ 0.61399051 -0.32774226 -2.66704722]
[ 0.81180708 0.21393368 -1.53533653]
...
[-0.0846831 0.88969922 -1.4789297 ]
[ 0.50820253 -0.76849609 -0.3093756 ]
[ 0.70769685 -0.68831327 -1.76864611]], prob=[0.01736178 0.03529735 0.29969771 0.10632366 0.23119516 0.14922521
0.17640689 0.09850628 0.17525098 0.15526183]
Including another observable#
We built our angular PDF successfully and can use this 3 dimensional PDF now. If we want, we could also include another observable. For example, the polynomial that we created above and make it 4 dimensional. Because it’s so simple, let’s do that!
full_pdf = angular_pdf * poly2
# equivalently
# full_pdf = zfit.pdf.ProductPDF([angular_pdf, poly2])
Done! This PDF is now 4 dimensional, which had to be, given that the observable of poly2
is different from the observable of angular_pdf
. If they would coincide, e.g. if poly2
had the observable phi
, this would now be a 3 dimensional PDF.
print(f"obs angular: {angular_pdf.obs} obs poly:{poly2.obs} obs product: {full_pdf.obs})")
obs angular: ('costheta_k', 'costheta_l', 'phi') obs poly:('obs1',) obs product: ('costheta_k', 'costheta_l', 'phi', 'obs1'))
What happened exactly ?#
The model tries to be as smart as possible and calls the most explicit function. Then it starts falling back to alternatives and uses, whenever possible, the analytic version (if available), otherwise a numerical.
The rule simplified: public (sanitizes input and) calls […] private. So e.g. pdf
calls _pdf
and if this is not provided, it uses the fallback that may not be optimized, but general enough to work.
The rule extended (in its current implementation): public calls a series of well defined methods and hooks before it calls the private method. These intermediate can be used, they mostly automatically catch certain cases and handle them for us.
To remember: in order to have full control over a public function such as integrate
, pdf
, sample
or normalization
, the private method, e.g. _integrate
can be overriden and is guaranteed to be called before other possibilities.
In the case above, pdf
called first _pdf
(which is not implemented), so it calls _unnormalized_pdf
and divides this by the normalization
. The latter also does not have an explicit implementation (_implementation
), so it uses the fallback and calls integrate
over the norm
. Since _integrate
is not provided, the fallback tries to perform an analytic integral, which is not available. Therefore, it integrates the _unnormalized_prob
numerically. In all of this calls, we can hook in by overriding the mentioned, specified methods.
What we did not mention: ZPDF
is just a wrapper around the actual BasePDF
that should be preferred in general; it simply provides a convenient __init__
. For the next example, we will implement a multidimensional PDF and use the custom __init__
Overriding pdf
#
Before, we used _unnormalized_pdf
, which is the common use-case. Even if we want to add an analytic integral, we can register it. Or do more fancy stuff like overriding the _normalization
. We can however also get the full control of what our model output by directly overriding _pdf
. The signature does not contain only x
but additionally norm
. This can have no limits (norm.has_limits
is False), in which case the “unnormalized pdf” is requested. Otherwise, norm
can have different limits and we have to take care of the proper normalization.
This is usually not needed and inside zfit, all PDFs are implemented using the _unnormalized_pdf
.
Therefore, it provides mostly a possibility to implement whatever is wanted, any unforeseen use-case, any kind of hack to “just try out something”.
class CustomPDF(zfit.pdf.BasePDF):
"""My custom pdf with three parameters.
"""
def __init__(self, param1, param2, param3, obs, name="CustomPDF", ):
# we can now do complicated stuff here if needed
# only thing: we have to specify explicitly here what is which parameter
params = {'super_param': param1, # we can change/compose etc parameters
'param2': param2, 'param3': param3}
super().__init__(obs, params, name=name)
@zfit.supports(norm=True)
def _pdf(self, x, norm, params):
# we should now normalize in here!
data = x[0]
param1 = params['super_param']
param2 = params['param2']
param3 = params['param3']
# just an arbitrary function
probs = 42 * param1 + (data * param3) ** param2
return probs
In a similar manner, other methods can be overriden as well. We won’t go into further details here, as this provides a quite advanced task. Furthermore, if stability is a large concern or such special cases need to be implemented, it is recommended to get in contact with the developers and share the idea.
Binned PDFs#
Binned models have two more methods, a counts
and a rel_counts
(relative counts) method: the latter is normalized to one.
Counts are the expected counts in each bin; comparing with a probability density function, the integral over a bin gives the expected counts in that bin.
These methods work differently than the PDF
: they return a histogram, i.e. the whole model, and allows for easy manipulation of whole histograms using scaling etc.
Note that you could also override _pdf
and return unbinned values, however, it is as efficient as creating an unbinned PDF and then binning it using to_binned
.
import uhi
class MixtureTwoHists(zfit.pdf.BaseBinnedPDF):
def __init__(self,
hist1,
hist2,
frac,
extended = None,
norm = None,
name = None,
label = None,
) -> None:
self.hist1 = hist1
self.hist2 = hist2
params = {'frac': frac}
space = hist1.space
super().__init__(obs=space, params=params,extended=extended, norm=norm, name=name, label=label)
@zfit.supports(norm=False)
def _rel_counts(self, x, params):
frac = params['frac']
counts = frac * self.hist1.counts() + (1 - frac) * self.hist2.counts()
return counts
# create two histograms
binned_space = zfit.Space('obs1', limits=(-5, 5), binning=100)
hist1 = zfit.data.from_numpy(obs=binned_space, array=np.random.normal(-1, 0.5, 1000))
hist2 = zfit.data.from_numpy(obs=binned_space, array=np.random.normal(1, 0.5, 1000))
frac = zfit.Parameter('frac_binned', 0.5, 0, 1, label="Mixture fraction")
mixture = MixtureTwoHists(hist1=hist1, hist2=hist2, frac=frac)
rel_counts = mixture.rel_counts()
mplhep.histplot(mixture.to_hist())
[StairsArtists(stairs=<matplotlib.patches.StepPatch object at 0x7f1f511a3c50>, errorbar=<ErrorbarContainer object of 3 artists>, legend_artist=<ErrorbarContainer object of 3 artists>)]
mplhep.histplot(mixture.sample(n=1000, params={'frac_binned': 0.3}))
[StairsArtists(stairs=<matplotlib.patches.StepPatch object at 0x7f1eef7ea150>, errorbar=None, legend_artist=None)]
Composed PDFs#
So far, we only looked at creating a model that depends on parameters and data but did not include other models. This is crucial to create for example sums or products of PDFs. Instead of inheriting from BasePDF
, we can use the BaseFunctor
that contains a mixin which handles daughter PDFs correctly.
The main difference is that we can now provide a list of PDFs that our model depends on. There can still be parameters (as for example the fracs
for the sum) that describe the behavior of the models but they can also be omitted (e.g. for the product). _Sidenote: technically, a normal BasePDF
can of course also have no parameters, however, since this is a constant function without dependencies, this will rarely be used in practice.
class SquarePDF(zfit.pdf.BaseFunctor):
"""Example of a functor pdf that takes the log of a single PDF.
DEMONSTRATION PURPOSE ONLY, DO **NOT** USE IN REAL CASE.
"""
def __init__(self, pdf1, name="SumOf3"):
pdfs = [pdf1] # we could have more of course, e.g. for sums
# no need for parameters here, so we can omit it
obs = pdf1.space
super().__init__(pdfs=pdfs, obs=obs, name=name)
@zfit.supports(norm=False)
def _pdf(self, x, norm, params):
del norm
# we do not need to unstack x here as we want to feed it directly to the pdf1
pdf1 = self.pdfs[0]
return pdf1.pdf(x) ** 2
squarepdf = SquarePDF(pdf1=poly2)
squarepdf.integrate(limits=(-2, 3.2))
Integral called
Integral called
<tf.Tensor: shape=(1,), dtype=float64, numpy=array([0.22241748])>
sample_square = squarepdf.sample(n=1000)
sample_square
Integral called
<zfit.Data: Data obs=('obs1',) shape=(1000, 1)>
squarepdf.pdf(sample_square)[:10]
Integral called
Integral called
<tf.Tensor: shape=(10,), dtype=float64, numpy=
array([0.37287906, 0.04281526, 0.11633849, 0.58964246, 0.33238053,
0.52370688, 0.04037297, 0.44352111, 0.1120725 , 0.60147006])>
…and now?#
We’ve implemented a custom PDF. Maybe spent quite some time fine tuning it, debugging it. Adding an integral. And now? Time to make it available to others: zfit-physics. This repository is meant for community contributions. It has less requirements to contribute than to zfit core and has a low threshold. Core devs can provide you with help and you can provide the community with a PDF.
Make an issue or a PR, everything is welcome!
Mixing with pure Python#
Whenever possible, it is preferrable to write anything in TensorFlow. But there is the possibility to mix with pure Python, however losing many of the benefits that TensorFlow provides. To do so:
try to use
z.py_function
ortf.py_function
to wrap pure Python codeif you write something and want to make sure it is run in eager mode, use
zfit.run.assert_executing_eagerly()
. This way, your function won’t be compiled and an error would be raised.set the graph mode and numerical gradient accordingly
x_tf = z.constant(42.)
def sqrt(x):
return np.sqrt(x)
y = z.py_function(func=sqrt, inp=[x_tf], Tout=tf.float64)
/home/docs/checkouts/readthedocs.org/user_builds/zfit/checkouts/latest/.venv/lib/python3.12/site-packages/zfit/z/zextension.py:384: AdvancedFeatureWarning: Either you're using an advanced feature OR causing unwanted behavior. To turn this warning off, use `zfit.settings.advanced_warnings['py_func_autograd'] = False` or 'all' (use with care) with `zfit.settings.advanced_warnings['all'] = False
Using py_function without numerical gradients. If the Python code does not contain any parametrization by `zfit.Parameter` or similar, this can work out. Otherwise, in case it depends on those, you may want to set `zfit.run.set_autograd_mode(=False)`.
warn_advanced_feature(
This raises a warning: since we do not use pure TensorFlow anymore, it means that the automatic gradient (potentially) fails, as it cannot be traced through Python operations. Depending on the use-case, this is not a problem. That’s why the warning is an AdvancedFeatureWarning
: it doesn’t say what we’re doing is wrong, it simply warns that we should know what we’re doing; it can also be switched off as explained in the warning.
It is technically not always required: if we e.g. use the internal, numerical gradient of a minimizer such as Minuit, the global setting does not really matter anyway.
This follows strongly the zfit philosophy that there must not be any bounds in terms of flexibility and even hackability of the framework, this should be an inherent part of it. However, the user should be made aware when leaving “the safe path”.
To do what the above warning told us to do, we can use zfit.run.set_autograd_mode(False)
.
This is needed whenever we want to use non-traceable Python calls in the dynamic calculations, be it by using py_function
or be it by switching off the gradient mode as shown below.
Sidestep: What is ‘z’?#
This is a subset of TensorFlow, wrapped to improve dtype handling and sometimes even provide additional functionality, such as z.function
decorator.
Full Python compatibility#
To operate in a full Python compatible, yet (way) less efficient mode, we can switch off the automatic gradient, as discussed before, and the graph compilation, leaving us with a Numpy-like TensorFlow
zfit.run.set_graph_mode(False)
zfit.run.set_autograd_mode(False)
<zfit.util.temporary.TemporarilySet at 0x7f1eed560b90>
We can now build a Gaussian purely based on Numpy. As we have seen when building graphs with TensorFlow: anything Python-like will be converted to a static value in the graph. So we have to make sure that our code is never run in graph mode but only executed eagerly.
This can be done by calling zfit.run.assert_executing_eagerly()
, which raises an error if this code is run in graph mode.
Note that omitting the graph mode means to loose many optimizations: Not only do we loose the whole TensorFlow speedup from the graph, we also perform redundant tasks that are not cached, since zfit itself is optimized to be run in the graph mode. However, practially, this mode should anyway be used rather rarely and compares still in the same order of magnitude as alternatives.
class NumpyGauss(zfit.pdf.ZPDF):
_PARAMS = ['mu', 'sigma']
@zfit.supports()
def _unnormalized_pdf(self, x, params):
zfit.run.assert_executing_eagerly() # make sure we're eager
data = x[0]
mu = params['mu']
sigma = params['sigma']
return np.exp( - 0.5 * (data - mu) ** 2 / sigma ** 2) # note that we use numpy here
This can be tested and compared.
obs = zfit.Space('obs1', (-3, 3))
mu = zfit.Parameter('mu', 0., -1, 1)
sigma = zfit.Parameter('sigma', 1., 0.1, 10)
gauss_np = NumpyGauss(obs=obs, mu=mu, sigma=sigma)
gauss = zfit.pdf.Gauss(obs=obs, mu=mu, sigma=sigma)
integral_np = gauss_np.integrate((-1, 0))
integral = gauss.integrate((-1, 0))
print(integral_np, integral)
tf.Tensor([0.3422688], shape=(1,), dtype=float64)
tf.Tensor([0.3422688], shape=(1,), dtype=float64)