예제 #1
0
def test_html_params_with_limits():
    m = Minuit(f1, x=3, y=5)
    m.fixed["x"] = True
    m.errors = (0.2, 0.1)
    m.limits = ((0, None), (0, 10))
    # fmt: off
    assert m.init_params._repr_html_() == r"""<table>
예제 #2
0
def test_params():
    m = Minuit(func0, x=1, y=2)
    m.errordef = Minuit.LEAST_SQUARES
    m.errors = (3, 4)
    m.fixed["x"] = True
    m.limits["y"] = (None, 10)

    # these are the initial param states
    expected = (
        Param(0, "x", 1.0, 3.0, None, False, True, False, False, False, None, None),
        Param(1, "y", 2.0, 4.0, None, False, False, True, False, True, None, 10),
    )
    assert m.params == expected

    m.migrad()
    m.minos()
    assert m.init_params == expected

    expected = [
        Namespace(number=0, name="x", value=1.0, error=3.0, merror=(-3.0, 3.0)),
        Namespace(number=1, name="y", value=5.0, error=1.0, merror=(-1.0, 1.0)),
    ]

    params = m.params
    for i, exp in enumerate(expected):
        p = params[i]
        assert p.number == exp.number
        assert p.name == exp.name
        assert p.value == approx(exp.value, rel=1e-2)
        assert p.error == approx(exp.error, rel=1e-2)
        assert p.error == approx(exp.error, rel=1e-2)
예제 #3
0
def MinForReplica():
    global totalN,setDY,initialValues,initialErrors,searchLimits,parametersToMinimize
        
    def repchi_2(x):        
        global totalN
        startT=time.time()
        harpy.setNPparameters(x)
        print('np set =',["{:8.3f}".format(i) for i in x], end =" ")    
        
        ccDY2,cc2=DataProcessor.harpyInterface.ComputeChi2(repDataDY)
        if(usePenaltyTerm): ccDY2+=totalN*PenaltyTerm(x)
        
        cc=(ccDY2)/totalN
        endT=time.time()
        print(':->',cc,'       t=',endT-startT)
        return ccDY2
    
    repDataDY=setDY.GenerateReplica()
    
    localM = Minuit(repchi_2, initialValues)
    
    localM.errors=initialErrors
    localM.limits=searchLimits
    localM.fixed=parametersToMinimize
    localM.errordef=1    
    localM.tol=0.0001*totalN*10000 ### the last 0.0001 is to compensate MINUIT def
    localM.strategy=1

    localM.migrad()
    
    ### [chi^2, NP-parameters]
    return [localM.fval,list(localM.values)]
예제 #4
0
def test_text_params_with_limits():
    m = Minuit(
        f1,
        x=3,
        y=5,
    )
    m.fixed["x"] = True
    m.errors = (0.2, 0.1)
    m.limits = ((0, None), (0, 10))
    assert _repr_text.params(m.params) == ref("params_with_limits")
예제 #5
0
def test_array_func_1():
    m = Minuit(func_np, (2, 1))
    m.errors = (1, 1)
    assert m.parameters == ("x0", "x1")
    assert m.values == (2, 1)
    assert m.errors == (1, 1)
    m.migrad()
    assert_allclose(m.values, (1, 1), rtol=1e-2)
    c = m.covariance
    assert_allclose(np.diag(c), (1, 1), rtol=1e-2)
예제 #6
0
    def minimize(
        self,
        initial_param_values: np.ndarray,
        verbose: bool = False,
        error_def: float = 0.5,
        additional_args: Optional[Tuple[Any, ...]] = None,
        get_hesse: bool = True,
        check_success: bool = True,
    ) -> MinimizeResult:

        m = Minuit(
            self._fcn,
            initial_param_values,
            name=self.params.names,
        )

        m.errors = 0.05 * initial_param_values
        m.errordef = error_def
        m.limits = self._param_bounds

        for i in range(len(m.params)):
            m.fixed[i] = self._get_fixed_params()[i]

        m.print_level = 1 if verbose else 0

        # perform minimization twice!
        fmin = m.migrad(ncall=100000, iterate=2).fmin

        self._fcn_min_val = m.fval
        self._params.values = np.array(m.values)
        self._params.errors = np.array(m.errors)

        fixed_params = tuple(
            ~np.array(self._get_fixed_params()))  # type: Tuple[bool, ...]
        self._params.covariance = np.array(
            m.covariance)[fixed_params, :][:, fixed_params]
        self._params.correlation = np.array(
            m.covariance.correlation())[fixed_params, :][:, fixed_params]

        self._success = fmin.is_valid and fmin.has_valid_parameters and fmin.has_covariance

        if check_success and not self._success:
            raise RuntimeError(f"Minimization was not successful.\n"
                               f"{fmin}\n")

        assert self._success is not None
        return MinimizeResult(fcn_min_val=m.fval,
                              params=self._params,
                              success=self._success)
예제 #7
0
def test_array_func_2():
    m = Minuit(func_np, (2, 1), grad=func_np_grad, name=("a", "b"))
    m.fixed = (False, True)
    m.errors = (0.5, 0.5)
    m.limits = ((0, 2), (-np.inf, np.inf))
    assert m.values == (2, 1)
    assert m.errors == (0.5, 0.5)
    assert m.fixed == (False, True)
    assert m.limits["a"] == (0, 2)
    m.migrad()
    assert_allclose(m.values, (1, 1), rtol=1e-2)
    c = m.covariance
    assert_allclose(c, ((1, 0), (0, 0)), rtol=1e-2)
    m.minos()
    assert len(m.merrors) == 1
    assert m.merrors[0].lower == approx(-1, abs=1e-2)
    assert m.merrors[0].name == "a"
예제 #8
0
def test_use_array_call():
    inf = float("infinity")
    m = Minuit(
        func_np,
        (1, 1),
        name=("a", "b"),
    )
    m.fixed = False
    m.errors = 1
    m.limits = (0, inf)
    m.migrad()
    assert m.parameters == ("a", "b")
    assert_allclose(m.values, (1, 1))
    m.hesse()
    c = m.covariance
    assert_allclose((c[("a", "a")], c[("b", "b")]), (1, 1))
    with pytest.raises(RuntimeError):
        Minuit(lambda *args: 0, [1, 2], name=["a", "b", "c"])
예제 #9
0
def func_test_helper(f, grad=None, errordef=None):
    m = Minuit(f, x=0, y=0, grad=grad)
    if errordef:
        m.errordef = errordef
    m.migrad()
    val = m.values
    assert_allclose(val["x"], 2.0, rtol=2e-3)
    assert_allclose(val["y"], 5.0, rtol=2e-3)
    assert_allclose(m.fval, 11.0 * m.errordef, rtol=1e-3)
    assert m.valid
    assert m.accurate
    m.hesse()
    err = m.errors
    assert_allclose(err["x"], 2.0, rtol=1e-3)
    assert_allclose(err["y"], 1.0, rtol=1e-3)
    m.errors = (1, 2)
    assert_allclose(err["x"], 1.0, rtol=1e-3)
    assert_allclose(err["y"], 2.0, rtol=1e-3)
    return m
예제 #10
0
    def get_minuit(self, event, guess):
        def fcn(x, y, angle, length, t0):
            pars = {'x': x, 'y': y, 'angle': angle, 'length': length, 't0': t0}
            neg_log = -1. * self.ln_likelihood(event, pars)
            #print(pars,neg_log)
            return neg_log

        fcn.errordef = Minuit.LIKELIHOOD

        #print(guess)
        m = Minuit(fcn,
                   x=guess['x'],
                   y=guess['y'],
                   angle=guess['angle'],
                   length=guess['length'],
                   t0=guess['t0'])
        m.limits = [(-5000., 0.), (0., 5000.), (None, None), (0.1, 3000.),
                    (-100., 100.)]
        m.errors = (10., 10., 0.01, 10., 0.5)

        return m
initialErrors = (0.1, 10., 10., 0.1, 0.1, 0.3, 0.5, 1., 1., 1., 1., 1., 1.,
                 0.1)
# searchLimits=((0.0001,2.),(0.01,80), (0.0,400), None,None,
#               (-2.,2.),(-0.99,2.5), (-10.,10.),
#               (-20.,20.),(-0.99,6.), (-15.,15.),
#               (-5.,5.),(-0.99,8), None)
searchLimits = ((0, None), (0, None), (0, None), None, None, (-5., 5.),
                (-0.99, 30), (-30., 30.), (-5., 5.), (-0.99, 60.), (-30., 30.),
                (-5., 15.), (-0.99, 30.), (-5, 5))

parametersToMinimize = (False, False, False, True, True, False, False, False,
                        False, False, False, False, False, False)

m = Minuit(chi_2, initialValues)

m.errors = initialErrors
m.limits = searchLimits
m.fixed = parametersToMinimize
m.errordef = 1

print(m.params)

m.tol = 0.0001 * totalN * 10000  ### the last 0.0001 is to compensate MINUIT def
m.strategy = 1

#%%

# m.tol=0.0001*totalN*10000 ### the last 0.0001 is to compensate MINUIT def
# m.strategy=1

m.migrad()  #ncall=150)
예제 #12
0
# Initialize the fit; parameter starting values and limits
if iminuit_version_f < 2.0:
    m = Minuit(getL,
               CV=1,
               limit_CV=(0, 3),
               CF=1,
               limit_CF=(0, 3),
               print_level=0,
               errordef=1,
               error_CV=0.2,
               error_CF=0.2)
else:
    m = Minuit(getL, CV=1, CF=1)
    m.limits = [(0, 3), (0, 3)]
    m.errordef = 1  # 1 for -2LogL (or least square), 0.5 for -LogL
    m.errors = [0.2, 0.2]
    m.print_level = 0

# Minimization and error estimation
m.migrad()
m.hesse()  # run covariance estimator
m.minos()

print("\nbest-fit point:", m.values)
print("\nHesse errors:", m.errors)
print("\nMinos errors:")
for key, value in list(m.merrors.items()):
    print(key, value)

if iminuit_version_f < 2.0:
    print("\nCorrelation matrix:\n", m.matrix(correlation=True))
예제 #13
0
# Initialize the fit; parameter starting values and limits
if iminuit_version_f < 2.0:
    m = Minuit(getL_CGaCg,
               CGa=0.9,
               limit_CGa=(0, 3),
               Cg=0.9,
               limit_Cg=(0, 3),
               print_level=0,
               errordef=1,
               error_CGa=1,
               error_Cg=1)
else:
    m = Minuit(getL_CGaCg, CGa=0.9, Cg=0.9)
    m.limits = [(0, 3), (0, 3)]
    m.errordef = 1  # 1 for -2LogL (or least square), 0.5 for -LogL
    m.errors = [1, 1]
    m.print_level = 0

# Fit the model
m.migrad()
# Display parameter values at the best-fit point
print("Best-fit point: ")
print("Cgamma =", m.values["CGa"])
print("Cgluon =", m.values["Cg"])

bestfit_CGa_Cg_minus2logL = m.fval

print("-2LogL =", bestfit_CGa_Cg_minus2logL)

print("\n***** model comparison *****")
예제 #14
0
    def laplace_approximate(self, num_global_samples=400, verbose=True):
        """ Find maximum and derive a Laplace approximation there.
        
        Parameters
        ----------
        num_global_samples: int
            Number of samples to draw from the prior to find a good
            starting point (see `init_globally`).
        verbose: bool
            If true, print out maximum likelihood value and point

         """

        if not hasattr(self, 'optu'):
            self.init_globally(num_global_samples=num_global_samples)

        # starting point is:
        startu = np.copy(self.optu)
        ndim = len(startu)

        # this part is not parallelised.
        if self.mpi_rank == 0:

            # choose a jump distance that does not go over the space border
            # because Minuit does not support that.
            deltau = 0.9999 * np.min(
                [np.abs(startu - 1), np.abs(startu)], axis=0)
            deltau[deltau > 0.04] = 0.04
            assert deltau.shape == startu.shape

            def negloglike(u):
                """ negative log-likelihood to minimize """
                p = self.transform(u)
                return -self.loglike(p)

            if self.log:
                self.logger.debug("    starting optimization...")
                self.logger.info("    from: %s" % startu)
                self.logger.info("    error: %s" % deltau)
            if hasattr(Minuit, 'from_array_func'):
                m = Minuit.from_array_func(negloglike,
                                           startu,
                                           errordef=0.5,
                                           error=deltau,
                                           limit=[(0, 1)] * ndim)
            else:
                m = Minuit(negloglike, startu)
                m.errordef = Minuit.LIKELIHOOD
                m.errors = deltau
                m.limits = np.array([(0, 1)] * ndim)
            m.migrad()

            if hasattr(m, 'fval'):
                optL = -m.fval
            else:
                optL = -m.get_fmin().val
            if verbose:
                print("Maximum likelihood: L = %.1f at:" % optL)
            optu = [
                max(1e-10, min(1 - 1e-10, m.values[i])) for i in range(ndim)
            ]
            optp = self.transform(np.asarray(optu))
            umax = [
                max(1e-6, min(1 - 1e-6, m.values[i] + m.errors[i]))
                for i in range(ndim)
            ]
            umin = [
                max(1e-6, min(1 - 1e-6, m.values[i] - m.errors[i]))
                for i in range(ndim)
            ]
            pmax = self.transform(np.asarray(umax))
            pmin = self.transform(np.asarray(umin))
            perr = (pmax - pmin) / 2

            for name, med, sigma in zip(self.paramnames, optp, perr):
                if sigma > 0:
                    i = max(0, int(-np.floor(np.log10(sigma))) + 1)
                else:
                    i = 3
                fmt = '%%.%df' % i
                fmts = '\t'.join(['    %-20s' + fmt + " +- " + fmt])
                if verbose:
                    print(fmts % (name, med, sigma))

            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                try:
                    m.hesse()
                    hesse_failed = getattr(m, 'hesse_failed', False)
                except:
                    hesse_failed = True
                if not hesse_failed:
                    hesse_failed = any((issubclass(warning.category,
                                                   HesseFailedWarning)
                                        for warning in w))
                if not hesse_failed:
                    hesse_failed = not getattr(m, 'has_covariance', True)
                # check if full rank matrix:
                if not hesse_failed:
                    if hasattr(m, 'np_matrix'):
                        cov = m.np_matrix()
                    else:
                        cov = np.asarray(m.covariance)
                    if cov.shape != (ndim, ndim):
                        self.logger.debug("    hesse failed, not full rank")
                        del cov
                        hesse_failed = True
                else:
                    self.logger.debug("    hesse failed")

            if not hesse_failed:
                self.logger.info("    using correlated errors ...")
                invcov = np.linalg.inv(cov)

            if hesse_failed:
                self.logger.info("    using uncorrelated errors ...")
                cov = np.diag(np.clip(perr, a_min=1e-10, a_max=1)**2)
                invcov = np.linalg.inv(cov)
            assert cov.shape == (ndim, ndim), (cov.shape, ndim)
            assert invcov.shape == (ndim, ndim), (invcov.shape, ndim)

            if hasattr(m, 'nfcn'):
                self.ncall += m.nfcn
            elif hasattr(m, 'ncalls_total'):
                self.ncall += m.ncalls_total
            else:
                self.ncall += m.ncalls
        else:
            cov = np.empty((ndim, ndim))
            invcov = np.empty((ndim, ndim))
            optu = np.empty(ndim)
            optp = np.empty(ndim)
            optL = np.empty(1)

        if self.use_mpi:
            # inform other processes about the results.
            cov = self.comm.bcast(cov)
            invcov = self.comm.bcast(invcov)
            optu = self.comm.bcast(optu)
            optp = self.comm.bcast(optp)
            optL = self.comm.bcast(optL)
            self.ncall += self.comm.bcast(self.ncall)

        self.invcov, self.cov = invcov, cov
        self.optu, self.optp, self.optL = optu, optp, optL
예제 #15
0
def run_minuit(nll,
               pars,
               use_gradient=True,
               use_hesse=False,
               use_minos=False,
               get_covariance=False):
    """
    Run IMinuit to minimise NLL function

    nll  : python callable representing the negative log likelihood to be minimised
    pars : list of FitParameters
    use_gradient : if True, use analytic gradient
    use_hesse : if True, uses HESSE for error estimation
    use_minos : if True, use MINOS for asymmetric error estimation
    get_covariance: if True, get the covariance matrix from the fit

    returns the dictionary with the values and errors of the fit parameters
    """

    float_pars = [p for p in pars if p.floating()]
    fixed_pars = [p for p in pars if not p.floating()]

    def func(par):
        for i, p in enumerate(float_pars):
            p.update(par[i])
        kwargs = {p.name: p() for p in float_pars + fixed_pars}
        func.n += 1
        nll_val = nll(kwargs).numpy()
        if func.n % 10 == 0:
            print(func.n, nll_val, par)
        return nll_val

    def gradient(par):
        for i, p in enumerate(float_pars):
            p.update(par[i])
        kwargs = {p.name: p() for p in float_pars + fixed_pars}
        float_vars = [i() for i in float_pars]
        gradient.n += 1
        with tf.GradientTape() as gt:
            gt.watch(float_vars)
            nll_val = nll(kwargs)
        g = gt.gradient(nll_val,
                        float_vars,
                        unconnected_gradients=tf.UnconnectedGradients.ZERO)
        g_val = [i.numpy() for i in g]
        return g_val

    func.n = 0
    gradient.n = 0

    start = [p.init_value for p in float_pars]
    error = [p.step_size for p in float_pars]
    limit = [(p.lower_limit, p.upper_limit) for p in float_pars]
    name = [p.name for p in float_pars]

    if use_gradient:
        minuit = Minuit(func, start, grad=gradient, name=name)
    else:
        minuit = Minuit(func, start, name=name)

    minuit.errordef = Minuit.LIKELIHOOD
    minuit.errors = error
    minuit.limits = limit

    initlh = func(start)
    starttime = timer()
    minuit.migrad()
    if use_hesse:
        minuit.hesse()

    if use_minos:
        minuit.minos()

    endtime = timer()

    par_states = minuit.params
    f_min = minuit.fmin
    #print the nice tables of fit results
    print(f_min)
    print(par_states)
    print(minuit.covariance.correlation())

    results = {"params": {}}  # Get fit results and update parameters
    for n, p in enumerate(float_pars):
        p.update(par_states[n].value)
        p.fitted_value = par_states[n].value
        p.error = par_states[n].error
        results["params"][p.name] = (p.fitted_value, p.error)
    for p in fixed_pars:
        results["params"][p.name] = (p.numpy(), 0.0)

    # return fit results
    results["initlh"] = initlh
    results["loglh"] = f_min.fval
    results["iterations"] = f_min.nfcn
    results["func_calls"] = func.n
    results["grad_calls"] = gradient.n
    results["time"] = endtime - starttime
    #results["covariance"] = [(k, v) for k, v in minuit.covariance.items()]
    #is_valid == (has_valid_parameters & !has_reached_call_limit & !is_above_max_edm)
    results["is_valid"] = int(f_min.is_valid)
    results["has_parameters_at_limit"] = int(f_min.has_parameters_at_limit)
    results["has_accurate_covar"] = int(f_min.has_accurate_covar)
    results["has_posdef_covar"] = int(f_min.has_posdef_covar)
    results["has_made_posdef_covar"] = int(f_min.has_made_posdef_covar)
    results["has_reached_call_limit"] = int(f_min.has_reached_call_limit)

    #store covariance matrix of parameters
    if get_covariance:
        covarmatrix = {}
        for p1 in float_pars:
            covarmatrix[p1.name] = {}
            for p2 in float_pars:
                covarmatrix[p1.name][p2.name] = minuit.covariance[p1.name,
                                                                  p2.name]

        results["covmatrix"] = covarmatrix

    return results
예제 #16
0
    def _fitdidv(freq, didv, poles, priors, invpriorscov, p0, yerr=None):
        """
        Function to directly fit the small signal TES parameters with
        the knowledge of prior known values any number of the
        parameters. In order for the degeneracy of the parameters to be
        broken, at least 2 fit parameters should have priors knowledge.
        This is usually rsh, rp, and r0, as these can be known from IV
        data.

        """
        def _residual(params):
            """
            Define a residual for the nonlinear least squares algorithm
            for the priors fit.

            """

            if poles == 1:
                rsh, rp, L, dt = params
                ci = DIDVPriors._onepolescaledadmittance(
                    freq,
                    rsh,
                    rp,
                    L,
                ) * np.exp(-2.0j * pi * freq * dt)
            elif poles == 2:
                rsh, rp, r0, beta, l, L, tau0, dt = params
                ci = DIDVPriors._twopolescaledadmittance(
                    freq,
                    rsh,
                    rp,
                    r0,
                    beta,
                    l,
                    L,
                    tau0,
                ) * np.exp(-2.0j * pi * freq * dt)
            elif poles == 3:
                rsh, rp, r0, beta, l, L, tau0, gratio, tau3, dt = params
                ci = DIDVPriors._threepolescaledadmittance(
                    freq,
                    rsh,
                    rp,
                    r0,
                    beta,
                    l,
                    L,
                    tau0,
                    gratio,
                    tau3,
                ) * np.exp(-2.0j * pi * freq * dt)

            # the difference between the data and the fit
            diff = didv - ci
            # get the weights from yerr, these should be
            # 1/(standard deviation) for real and imaginary parts
            if (yerr is None):
                weights = 1.0 + 1.0j
            else:
                weights = 1.0 / yerr.real + 1.0j / yerr.imag

            # create the residual vector, splitting up real and
            # imaginary parts of the residual separately
            z1d = np.zeros(freq.size * 2, dtype=np.float64)
            z1d[0:z1d.size:2] = diff.real * weights.real
            z1d[1:z1d.size:2] = diff.imag * weights.imag
            return z1d

        def _residualpriors(params):
            """Helper function to incude the priors in the residual."""

            z1dpriors = np.sqrt(
                (priors - params).dot(invpriorscov).dot(priors - params))
            return z1dpriors

        def _neg_log_likelihood(params):
            """Negative log likelihood with priors included."""

            return np.sum(
                (_residual(params))**2 / 2) + _residualpriors(params)**2 / 2

        m = Minuit(
            _neg_log_likelihood,
            p0,
        )
        m.limits = (len(p0) - 1) * ((0, None), ) + ((None, None), )
        m.errors = np.abs(p0)
        m.errordef = 0.5

        m.migrad()

        popt = np.asarray(m.values)
        pcov = np.asarray(m.covariance)
        cost = m.fval

        return popt, pcov, cost
예제 #17
0
    def fit_data_minuit(self, spectrum_only=False, minimizer_args={}):
        from iminuit import Minuit

        def chi2(deltaE, xmax_shift, *norms):
            norms = np.array(norms)
            # norms = np.array(norms)
            if spectrum_only == True:
                result = self.get_chi2_spectrum(norms=norms, deltaE=deltaE)
            elif spectrum_only == 'xmax':
                result = self.get_chi2_spectrum(
                    norms=norms, deltaE=deltaE) + self.get_chi2_Xmax(
                        norms=norms, deltaE=deltaE, xmax_shift=xmax_shift)
            else:
                result = self.get_chi2_total(norms=norms,
                                             deltaE=deltaE,
                                             xmax_shift=xmax_shift)
            return result

        init_norm = self.spectrum['spectrum'][14] / self.res_spectrum[
            14] / len(self.ncoids)
        # trick if spectrum is zero, will iMinuit will give nan anyway
        init_norm = init_norm if np.isfinite(init_norm) else 1.
        m_best = None

        if 'fix_deltaE' in minimizer_args and not minimizer_args['fix_deltaE']:
            delta_tries = [-0.13, -0.8, 0., 0.8, 0.13]
            #delta_tries = [-0.12, 0., 0.12]
            fix_deltaE = False

        else:
            delta_tries = [0.]
            fix_deltaE = True

        if 'fix_xmax_shift' in minimizer_args and not minimizer_args[
                'fix_xmax_shift']:
            pass
            shift_tries = [-0.9, -0.5, 0., 0.5, 0.9]
            #shift_tries = [-0.9, 0., 0.9]
            fix_xmax_shift = False
        else:
            shift_tries = [0.]
            fix_xmax_shift = True

        for delta_start in delta_tries:
            for shift_start in shift_tries:

                arg_names = ['deltaE'] + ['xmax_shift'] + [
                    'norm{:}'.format(pid) for pid in self.ncoids
                ]
                start = [delta_start] + [shift_start
                                         ] + [init_norm] * len(self.ncoids)
                error = [0.1] + [0.2] + [init_norm / 100] * len(self.ncoids)
                limit = [(-0.14, 0.14)] + [
                    (-1., 1.)
                ] + [(init_norm / 1e6, init_norm * 1e6)] * len(self.ncoids)
                fixed = [fix_deltaE] + [fix_xmax_shift
                                        ] + [False] * len(self.ncoids)

                params = {name: val for name, val in zip(arg_names, start)}

                m = Minuit(chi2, name=arg_names, **params)
                m.errordef = Minuit.LEAST_SQUARES
                m.limits = limit
                m.errors = error
                m.fixed = fixed
                # m.print_param()
                m.migrad(ncall=100000)

                if m_best == None:
                    m_best = m
                if m.fval < m_best.fval:
                    m_best = m

        return m_best
예제 #18
0
    m = Minuit(getL,
               CGa=1,
               limit_CGa=(0, 3),
               Cg=1,
               limit_Cg=(0, 3),
               BRinv=0.2,
               limit_BRinv=(0, 0.9),
               errordef=1,
               error_CGa=0.1,
               error_Cg=0.1,
               error_BRinv=0.1)
else:
    m = Minuit(getL, CGa=1, Cg=1, BRinv=0.2)
    m.limits = [(0, 3), (0, 3), (0, 0.9)]
    m.errordef = 1  # 1 for -2LogL (or least square), 0.5 for -LogL
    m.errors = [0.1, 0.1, 0.1]

print("\n***** performing model fit with iminuit *****")

# Minimization and error estimation
m.migrad()
m.minos()

print("\n***** fit summary *****")

print("\nbest-fit point:", m.values)
print("\nHesse errors:", m.errors)
print("\nMinos errors:")
for key, value in list(m.merrors.items()):
    print(key, value)
예제 #19
0
파일: musuite.py 프로젝트: RDeRenzi/mujpy
    def promptfit(self,mplot, mprint = False):
        '''
        launches t0 prompts fit::

            fits peak positions 
            prints migrad results
            plots prompts and their fit (if plot checked, mprint not implemented)
            stores bins for background and t0

        refactored for run addition and
        suite of runs

        WARNING: this module is for PSI only        
        '''
        from numpy import array, where, arange, zeros, mean, ones, sqrt, linspace
        from iminuit import Minuit, cost
        
        import matplotlib.pyplot as P
        from mujpy.mucomponents.muprompt import muprompt
        from mujpy.mucomponents.muedge import muedge
        from mujpy.aux.aux import TauMu_mus, scanms, step, set_fig 
    
        if mplot:  # setup figure window
            font = {'family' : 'Ubuntu','size'   : 8}
            P.rc('font', **font)
            dpi = 100. # conventional screen dpi
            num = 0 # unique window number
            if self.datafile[-3:] == 'bin': 
                nrow, ncol = 2,3
                kwargs = {'figsize':(7.5,5),'dpi':dpi}
                title = 'Prompts t0 fit'
                prompt_fit_text = [None]*self._the_runs_[0][0].get_numberHisto_int()
            elif self.datafile[-3:] =='mdu': # PSI HIFI        
                nrow, ncol = 3,3
                ###################
                #  set figure, axes (8  real counters, python number 1 2 3 4 5 6 7 8
                ###################
                # fig_counters,ax_counters = P.subplots(3,3,figsize=(9.5,9.5),dpi=dpi)
                kwargs = {'figsize':(9.5,9.5),'dpi':dpi}
                title = 'HIFI start histo guess'
            elif self.filespecs[1].value=='nxs': # ISIS
                nrow, ncol = 3,3
                ###################
                #  set figure, axes 
                ###################
                kwargs = {'figsize':(5,4),'dpi':dpi}
                title = 'Edge t0 fit'
            fig_counters,ax_counters = set_fig(num,nrow,ncol,title,**kwargs)
            fig_counters.canvas.set_window_title(title)
                
        if self.datafile[-3:] == 'bin':  # PSI gps, flame, dolly, gpd
            second_plateau = 100
            peakheight = 100000.
            peakwidth = 1.
            ###################################################
            # fit a peak with different left and right plateaus
            ###################################################

            #############################
            # guess prompt peak positions
            ############################# 
            npeaks = []
            for counter in range(self._the_runs_[0][0].get_numberHisto_int()):
                histo = zeros(self._the_runs_[0][0].get_histoLength_bin())
                for k in range(len(self._the_runs_[0])): # may add runs
                    histo += array(self._the_runs_[0][k].get_histo_vector(counter,1))
                binpeak = where(histo==histo.max())[0][0]
                npeaks.append(binpeak)
            npeaks = array(npeaks)

            ###############
            # right plateau
            ###############
            nbin =  int(max(npeaks) + second_plateau) # this sets a counter dependent second plateau bin interval
            x = arange(0,nbin,dtype=int) # nbin bins from 0 to nbin-1
            self.lastbin, np3s = npeaks.min() - self.prepostpk[0], int(npeaks.max() + self.prepostpk[1])
            # final bin for background average, first bin for right plateau estimate (last is nbin)

            x0 = zeros(self._the_runs_[0][0].get_numberHisto_int()) # for center of peaks

            if mplot:
                for counter in range(self._the_runs_[0][0].get_numberHisto_int(),sum(ax_counters.shape)):
                    ax_counters[divmod(counter,3)].cla()
                    ax_counters[divmod(counter,3)].axis('off')

            for counter in range(self._the_runs_[0][0].get_numberHisto_int()):
                # prepare for muprompt fit
                histo = zeros(self._the_runs_[0][0].get_histoLength_bin())
                for k in range(len(self._the_runs_[0])): # may add runs
                    histo += self._the_runs_[0][k].get_histo_vector(counter,1)
                p = [ peakheight, float(npeaks[counter]), peakwidth, 
                      mean(histo[self.firstbin:self.lastbin]), 
                      mean(histo[np3s:nbin])]
                y = histo[:nbin]
                ##############
                # guess values
                ##############
                mm = muprompt()
                mm._init_(x,y)
                mm.errordef = Minuit.LEAST_SQUARES
                m = Minuit(mm,a=p[0],x0=p[1],dx=p[2],ak1=p[3],ak2=p[4])
                # m.values = p
                m.errors = (p[0]/100,p[1]/100,0.01,p[3]/100,p[4]/100)
                m.migrad()
                A,X0,Dx,Ak1,Ak2 = m.values
                x0[counter] = X0 # store float peak bin position (fractional)  

                if mplot:    # do plot
                    n1 = npeaks[counter]-50
                    n2 = npeaks[counter]+50
                    x3 = arange(n1,n2,1./10.)
                    ax_counters[divmod(counter,3)].cla()
                    ax_counters[divmod(counter,3)].plot(x[n1:n2],y[n1:n2],'.')
                    ax_counters[divmod(counter,3)].plot(x3,mm.f(x3,A,X0,Dx,Ak1,Ak2))
                    x_text,y_text = npeaks[counter]+10,0.8*max(y)
                    prompt_fit_text[counter] = ax_counters[
                                                  divmod(counter,3)].text(x_text,y_text,
                     'Det #{}\nt0={}bin\n$\delta$t0={:.2f}'.format(counter+1,
                     x0.round().astype(int)[counter],x0[counter]-x0.round().astype(int)[counter]))

                ##############################################################################
                # Simple cases:                                                              #
                # 1) Assume the prompt is entirely in bin nt0.                               #
                #   (python convention, the bin index is 0,...,n,...                         #
                # The content of bin nt0 will be the t=0 value for this case and dt0 = 0.    #
                # The center of bin nt0 will correspond to time t = 0,                       #
                #         time = (n-nt0 + mufit.offset + mufit.dt0)*mufit.binWidth_ns/1000.  #
                # 2) Assume the prompt is equally distributed between n and n+1.             #
                #    Then nt0 = n and dt0 = 0.5, the same formula applies                    #
                # 3) Assume the prompt is 0.45 in n and 0.55 in n+1.                         #
                #    Then nt0 = n+1 and dt0 = -0.45, the same formula applies.               #
                ##############################################################################

                # these three are the sets of parameters used by other methods
            self.nt0 = x0.round().astype(int) # bin of peak, nd.array of shape run.get_numberHisto_int() 
            self.dt0 = x0-self.nt0 # fraction of bin, nd.array of shape run.get_numberHisto_int() 
            self.lastbin = self.nt0.min() - self.prepostpk[0] # nd.array of shape run.get_numberHisto_int() 

        elif self.datafile[-3:] =='mdu': # PSI HIFI
            first_plateau = - 500
            second_plateau = 1500
            #############################
            # very rough guess of histo start bin
            # then 
            # fit a step
            ############################# 
            ncounters = self._the_runs_[0][0].get_numberHisto_int()
            npeaks = []
            a = 0.5*ones(ncounters)
            b = 30*ones(ncounters)
            dn = 5*ones(ncounters)
            for counter in range(ncounters):
                histo = zeros(self._the_runs_[0][0].get_histoLength_bin())
                for k in range(len(self._the_runs_[0])): # may add runs
                    histo += self._the_runs_[0][k].get_histo_vector(counter,1)
                npeakguess = scanms(histo,100) # simple search for a step pattern
                if npeakguess>0:
                    npeaks.append(npeakguess)
                elif counter != 0:
                    self.console('**** WARNING: step in hifi detector {} not found'.format(counter))
                    self.console('     set to arbitrary bin 20000')
                    npeaks.append(20000)
                else:
                    npeaks.append(where(histo==histo.max())[0][0])
                ###############
                # now fit it
                ###############
                if counter != 0:
                    n2 = npeaks[counter] + second_plateau # counter dependent bin interval
                    n1 = npeaks[counter] + first_plateau
                    x = arange(n1,n2+1,dtype=int) # n2-n1+1 bins from n1 to n2 included for plotting
                    y = histo[n1:n2+1]
                    # next will try likelihood
                    c = cost.LeastSquares(x,y,1,step)
                    m = Minuit(c,a=a[counter],n=npeaks[counter],dn=dn[counter],b=b[counter])
                    # m.errors(1.,10.,1.)
                    m.migrad()
                    a[counter],n,dn[counter],b[counter] = m.values
                    if m.valid:                               
                        npeaks.pop()
                        npeaks.append(n)
                    else:
                        self.console('****   step fit not converged for detector {}'.format(counter))
            x0 = array(npeaks).astype(int)
            self.lastbin = x0.min() - self.prepostpk[0].value # final bin for background average 

            ############################
            # just show where this is and save parameters
            ############################
            if mplot:     # do plot
                prompt_fit_text = [None]*ncounters   
                n2 = x0.max() + second_plateau # counter independent bin interval
                n1 = x0.min() + first_plateau
                for counter in range(ncounters):
                    ax_counters[divmod(counter,3)].cla()
                    # ax_counters[divmod(counter,3)].axis('off')
                    histo = zeros(self._the_runs_[0][0].get_histoLength_bin())
                    for k in range(len(self._the_runs_[0])): # may add runs
                        histo += self._the_runs_[0][k].get_histo_vector(counter,1)
                    x = arange(n1,n2+1,dtype=int) # n2-n1+1 bins from n1 to n2 included for plotting
                    y = histo[n1:n2+1]
                    x3 = arange(n1,n2)
                    ax_counters[divmod(counter,3)].plot(x,y,'.')
                    ax_counters[divmod(counter3)].plot(x,
                                step(x,a[counter],npeaks[counter],dn[counter],b[counter]),'r-')
                    x_text,y_text = npeaks[counter]+10,0.8*histo.max()
                    prompt_fit_text[counter] = ax_counters[divmod(counter,3)].text(x_text,
                                  y_text,'Det #{}\nt0={}bin'.format(counter+1,x0[counter]))
            self.nt0 = x0 # bin of peak, nd.array of shape run.get_numberHisto_int() 
            self.dt0 = zeros(x0.shape) # fraction of bin, nd.array of shape run.get_numberHisto_int()

        elif self.filespecs[1].value=='nxs': # ISIS
            histo = zeros(self._the_runs_[0][0].get_histoLength_bin())
            for counter in range(self._the_runs_[0][0].get_numberHisto_int()):
                for k in range(len(self._the_runs_[0])): # may add runs
                    histo += self._the_runs_[0][k].get_histo_vector(counter,1)
            error = sqrt(histo)
            error[where(error==0)]=1
            dh = histo[1:]-histo[:-1]
            kt0 = where(dh==dh.max())[0] # [0]
            musbin = float(self.nsbin.value)/1e3
            t0 = kt0*musbin
            N = histo[int(kt0)+10]*TauMu_mus()
            D = 0.080
            n1 = 0
            n2 = 101
            t = musbin*linspace(n1,n2-1,n2)
            mm = muedge()
            mm._init_(t,histo[n1:n2])
            m = Minuit(mm,t00=t0,N=N,D=D)
            m.errors=(t0/100,N/100,0.8)
            m.print_level = 1 if mprint else 0                   
            m.migrad()
            t0,N,D = m.values
            
            
            if mplot:    # do plot
                ax_counters.plot(t,histo[n1:n2],'.')
                ax_counters.plot(t,mm.f(t,t0,N,D))
                x_text,y_text = t[int(2*n2/3)],0.2*max(histo[n1:n2])
                ax_counters.text(x_text,y_text,'t0 = {:.1f} mus'.format(t0))
            self.nt0 = array([t0/float(self.nsbin.value)]).round().astype(int) # bin of peak, 
                                             # nd.array of shape run.get_numberHisto_int() 
            self.dt0 = array(t0-self.nt0) # fraction of bin, in ns


        if mplot:   # show results                  
            fig_counters.canvas.manager.window.tkraise()
            P.draw()
            self.console('Succesfully completed prompt Minuit fit, check plots')
        else:
            self.console('Succesfully completed prompt Minuit fit, check nt0, dt0 ')
        self.console('****************END OF SUITE*****************')