首先我想说我在这个话题上确实有概念上的困难,所以如果我的意图没有意义,请纠正我。
我正在尝试验证用于从分布中提取信号产量的模型。为简单起见,假设只有信号分布而没有背景。该模型是标准高斯模型,我创建了扩展 PDF。
在我的想法中,我会从该 PDF 创建示例数据,并且只更改事件的数量,即仅缩放。比我适合这个玩具样本并通过计算将生成的事件数量与拟合的信号产量进行比较
pull = (N_generated - N_fit) / sigma_Nfit
我不明白的是我如何设置和获取生成的数字。在这一代中,我想随机设置事件的数量(我猜是泊松分布?)并保持所有其他模型参数固定。
最后我有信号+背景分布并且想要:
- 改变信号数量+保持背景数量固定
- 修复信号+改变背景
- 改变 n_total 中的分数 = n_signal + fraction * n_background
以下代码取自 zfit-tutorials 并更新为具有扩展模型(也可在此处找到:https ://github.com/holyschmoly/zfit_toymc ):
mu = zfit.Parameter('mu', 0, -1, 1)
sigma = zfit.Parameter('sigma', 1, 0.5, 1.5)
model = zfit.pdf.Gauss(obs=obs, mu=mu, sigma=sigma)
# do i need this range here?
nsig_toy = 1e4
nsig_range = 0.1
n_sig = zfit.Parameter('n_sig', nsig_toy, nsig_toy*(1-nsig_range), nsig_toy*(1+nsig_range))
model = model.create_extended(n_sig)
# vary only n_sig
sampler = model.create_sampler(fixed_params=[mu, sigma])
nll = zfit.loss.ExtendedUnbinnedNLL(model, sampler)
minimizer = zfit.minimize.Minuit(
strategy=zfit.minimize.DefaultToyStrategy(),
verbosity=0,
tolerance=1e-3,
use_minuit_grad=True)
params = nll.get_params()
fit_results = []
ntoys = 10
while len(fit_results) < ntoys:
# What does really happen here?
sampler.resample()
# I think this is probably not what I want but I don't understand why
# this is needed in the first place.
# I want something like: vary n_sig randomly, keep mu and sigma fixed
for param in params:
param.randomize()
result = minimizer.minimize(nll)
if result.converged:
result.hesse()
fit_results.append(result)
# Now I want something like this:
# pull = (N_generated - N_fit ) / sigma_fit
# for each fit_result.