首先,我想说,我在这个问题上确实有概念上的困难,所以如果我的意图没有意义,请纠正我。
我试图验证用于从分布中提取信号产量的模型。为了简单起见,假设只有一个信号分布而没有背景。模型是一个标准的Gauss,我创建了一个扩展的PDF。
在我的想法中,我会从PDF中创建样本数据,并且只改变事件的数量,即只改变缩放。比我更适合这个玩具样本,并通过计算将所产生的事件数与拟合的信号产量进行比较。
pull = (N_generated - N_fit) / sigma_Nfit
我不明白的是我是如何设置并得到生成的数字的。在这一代中,我想随机设置事件数(我猜泊松分布?)并保持所有其他模型参数的固定。
最后,我有了signal+background发行版,并希望:
固定信号+在n_total = n_signal +分数* n_background中的可变n_total分数
以下代码摘自zfit教程并更新为具有扩展模型(也可以在这里找到: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.发布于 2020-12-01 00:35:56
这看起来是一件合理的事。问题是你是否真的想只改变信号和bkg,但它当然是自由的。
那么你需要的是一些更复杂的东西。
首先要做的事情是:resample方法实际上再次从PDF中取样。然而,从整个PDF,而不是部分。
您需要的是一个for-循环,在这个for-循环中,可以使用来自pdf的pdf方法来生成各个部件。然后你把它们缝合在一起,造成损失。然后你把这个损失降到最低限度。让我把它画出来:
for i in ntoys:
# calculate how many background and signal samples you want, e.g. with numpy
sample_bkg = bkg_pdf.sample(n=...)
sample_signal = sig_pdf.sample(n=...)
sample = tf.concat([sample_sig.value(), sample_bkg.value()], axis=0)
data = zfit.Data.from_tensor(tensor=sample, obs=obs)
nll = zfit.loss.ExtendedUnbinnedNLL(model, data)
result = minimizer.minimize(nll)
# use the result to get the param values
nsig = result.param[sig_yield]['value'] # assuming sig_yield is a zfit.Parameter, the yield of the signal
# calculate pull, add it to a list of pulls也许您想在循环的开头添加一个zfit.run.clear_graph_cache(),否则内存就会继续增长,或者在脚本开始时使用zfit.run.set_graph_mode(False)以急切的方式运行所有的东西。这可能是更快或更慢,取决于复杂性。对于简单、快速的匹配,如果将图形模式设置为False,这会更快,对于更复杂的情况,第一种方法--清除缓存--应该会执行得更好。
https://stackoverflow.com/questions/65071895
复制相似问题