zfit - 从 zFit 中的玩具中提取情节
问题描述
首先我想说我在这个话题上确实有概念上的困难,所以如果我的意图没有意义,请纠正我。
我正在尝试验证用于从分布中提取信号产量的模型。为简单起见,假设只有信号分布而没有背景。该模型是标准高斯模型,我创建了扩展 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.
解决方案
这看起来是一件合理的事情。问题是您是否真的只想改变信号和只改变 bkg,但这当然是免费的。
那么你需要的是更复杂的东西。
首先要做的事情是:该resample
方法实际上再次从 PDF 中采样。但是,来自整个 PDF,而不是部分。
您需要的是一个 for 循环,在这个 for 循环中,您可以使用sample
from 方法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
也许您想在循环的开头添加 a ,否则内存会不断增长,或者在脚本的开头zfit.run.clear_graph_cache()
使用 a 以急切模式运行所有内容。zfit.run.set_graph_mode(False)
这可能更快或更慢,具体取决于复杂性。对于简单、快速的拟合,预计将图形模式设置为 False 会更快,对于更复杂的情况,第一种方法 - 清除缓存 - 应该会执行得更好。
推荐阅读
- javascript - JQuery小册子添加搜索栏
- visual-studio - 代码无法访问 - Visual Studio 中的 React Native
- unity3d - 为什么我的测试视频广告无法在 Android 上运行,但在编辑器上运行?
- python - 按索引名称调用数据框值
- google-bigquery - BigQuery 的 DBT 无效快照时间错误
- firebase - Flutter - 如何在从 firebase 实时数据库中获取数据时检查多个条件?
- python - 。文本。返回一个空字符串
- xpath - google sheet importxml 返回错误:导入的内容为空
- visual-studio-code - 删除 vscode 中的默认(自动检测)任务(launch.json 和 task.json)
- bison - 野牛:我的语法中的移位减少冲突