def test_NormalConstraint_2(): lsq1 = NormalConstraint(("a", "b"), (1, 2), (2, 2)) lsq2 = lsq1 + NormalConstraint("b", 2, 0.1) + NormalConstraint("a", 1, 0.01) sa = 0.1 sb = 0.02 rho = 0.5 cov = ((sa ** 2, rho * sa * sb), (rho * sa * sb, sb ** 2)) lsq3 = lsq1 + NormalConstraint(("a", "b"), (1, 2), cov) assert lsq1.func_code.co_varnames == ("a", "b") assert lsq2.func_code.co_varnames == ("a", "b") assert lsq3.func_code.co_varnames == ("a", "b") m = Minuit(lsq1, 0, 0) m.migrad() assert_allclose(m.values, (1, 2), atol=1e-3) assert_allclose(m.errors, (2, 2), rtol=1e-3) m = Minuit(lsq2, 0, 0) m.migrad() assert_allclose(m.values, (1, 2), atol=1e-3) assert_allclose(m.errors, (0.01, 0.1), rtol=1e-2) m = Minuit(lsq3, 0, 0) m.migrad() assert_allclose(m.values, (1, 2), atol=1e-3) assert_allclose(m.errors, (sa, sb), rtol=1e-2) assert_allclose(m.covariance, cov, rtol=1e-2)
def fitter(data, fit_range, params, mc=False): params = params.copy() xmin, xmax = fit_range width = xmax - xmin data = data[(data >= xmin) & (data <= xmax)] # print(len(data)) if mc: cost_function0 = ExtendedUnbinnedNLL( data, lambda x, n_sig, m, sL, sR, aL, aR: (n_sig, n_sig * sig_pdf(x, m, sL, sR, aL, aR, fit_range))) cost_function = cost_function0 del params['y0'], params['dy'], else: cost_function0 = ExtendedUnbinnedNLL( data, lambda x, n_sig, m, sL, sR, aL, aR, y0, dy: (n_sig + width * (2 * y0 + dy) / 2, pdf(x, n_sig, m, sL, sR, aL, aR, y0, dy, fit_range))) cost_function = cost_function0 + NormalConstraint('sL', params['sL'][0], params['sL'][1]) + NormalConstraint('sR', params['sR'][0], params['sR'][1]) + \ NormalConstraint('aL', params['aL'][0], params['aL'][1]) + NormalConstraint('aR', params['aR'][0], params['aR'][1]) + NormalConstraint('m', params['m'][0], params['m'][1]) parameters = {k: params[k][0] for k in params} m = Minuit(cost_function, **parameters) for par in m.parameters: m.limits[par] = params[par][1] # m.errordef= Minuit.LIKELIHOOD return (m, cost_function0)
def test_NormalConstraint_properties(): nc = NormalConstraint(("a", "b"), (1, 2), (3, 4)) assert_equal(nc.value, (1, 2)) assert_equal(nc.covariance, (9, 16)) nc.value = (2, 3) nc.covariance = (1, 2) assert_equal(nc.value, (2, 3)) assert_equal(nc.covariance, (1, 2))
def test_addable_cost_2(): ref = NormalConstraint("a", 1, 2), NormalConstraint(("b", "a"), (1, 1), (2, 2)) cs = ref[0] + ref[1] assert isinstance(cs, Sequence) assert len(cs) == 2 assert cs[0] is ref[0] assert cs[1] is ref[1] for c, r in zip(cs, ref): assert c is r assert cs.index(ref[0]) == 0 assert cs.index(ref[1]) == 1 assert cs.count(ref[0]) == 1
def __init__(self, data, fit_func, pars: dict, lims: dict, fit_range: tuple, sigmas={}): """ data - данные для фита fit_func:callable - функция фита (зависит x и фитируемых параметров) из классов ниже pars - словарь с начальными значениями параметров lims - словарь с ограничениями на параметры fit_range - кортеж (xmin, xmax) с областью фитирования sigmas - словарь с отклонением параметров для регуляризации (может использоваться в эксперименте, чтоб мягко ограничить параметры) """ xmin, xmax = fit_range self.fit_range = fit_range self.fit_func = fit_func self.data = data self.cost = ExtendedUnbinnedNLL(data[(data > xmin) & (data < xmax)], self.fit_func) parnames = iminuit.util.describe(self.cost) clear_dict = lambda dic: { p: dic[p] for p in set(parnames) & set(dic.keys()) } #вытащить только необходимое из словаря self.pars, self.lims = clear_dict(pars), clear_dict(lims) cost0 = self.cost for s in clear_dict(sigmas): cost0 += NormalConstraint(s, self.pars[s], sigmas[s]) self.m = Minuit(cost0, **self.pars) for par in self.m.parameters: if par in self.lims: self.m.limits[par] = self.lims[par]
def test_addable_cost_3(): def line_np(x, par): return par[0] + par[1] * x lsq = LeastSquares([1, 2, 3], [3, 4, 5], 1, line_np) con = NormalConstraint("par", (1, 1), (1, 1)) cs = sum([lsq, con]) assert cs((1, 1)) == pytest.approx(3) cs = 1.5 + lsq + con assert cs((1, 1)) == pytest.approx(4.5)
def test_NormalConstraint_1(): def model(x, a): return a lsq1 = LeastSquares(0, 1, 1, model) lsq2 = lsq1 + NormalConstraint("a", 1, 0.1) assert lsq1.func_code.co_varnames == ("a",) assert lsq2.func_code.co_varnames == ("a",) m = Minuit(lsq1, 0) m.migrad() assert_allclose(m.values, (1,), atol=1e-2) assert_allclose(m.errors, (1,), rtol=1e-2) m = Minuit(lsq2, 0) m.migrad() assert_allclose(m.values, (1,), atol=1e-2) assert_allclose(m.errors, (0.1,), rtol=1e-2)