Exemplo n.º 1
0
 def plot_model_full(self,
                     model,
                     data,
                     labels=True,
                     paramvalues=None,
                     offset=0,
                     **kw):
     if self.no_fits:
         return
     if paramvalues is None:
         paramvalues = prepare_params(model.params, data.meta)[3]
     nsamples = self._get_samples(model, data)
     imin, imax = data.x_plot.argmin(), data.x_plot.argmax()
     xx = multi_linspace(data.x[imin], data.x[imax], nsamples)
     xxp = linspace(data.x_plot[imin], data.x_plot[imax], nsamples)
     yy = model.fcn(paramvalues, xx)
     if 'label' not in kw:
         kw['label'] = labels and 'fit' or ''
     self.axes.plot(xxp, yy + offset, 'g', lw=kw.pop('kw', 2), **kw)
     for comp in model.get_components():
         if comp is model:
             continue
         yy = comp.fcn(paramvalues, xx)
         kw['label'] = labels and comp.name or ''
         self.axes.plot(xxp, yy + offset, '-.', **kw)
Exemplo n.º 2
0
 def simulate(self, data):
     varying, varynames, dependent, _ = prepare_params(
         self.params, data.meta)
     pd = dict((p.name, p.value) for p in self.params)
     update_params(dependent, data.meta, pd)
     yy = self.fcn(pd, data.x)
     new = data.copy()
     new.y = yy
     new.dy = zeros(len(yy))
     return new
Exemplo n.º 3
0
 def export_fits(self, filename):
     xx = linspace(self.data.x.min(), self.data.x.max(), 1000)
     paramvalues = prepare_params(self.model.params, self.data.meta)[3]
     yy = self.model.fcn(paramvalues, xx)
     yys = []
     for comp in self.model.get_components():
         if comp is self.model:
             continue
         yys.append(comp.fcn(paramvalues, xx))
     savetxt(filename, array([xx, yy] + yys).T)
Exemplo n.º 4
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def leastsqfcn(params, data):
        pd = dict(zip(varynames, params))
        update_params(dependent, meta, pd)
        return (fcn(pd, x) - y) / dy

    initpars = []
    warned = False
    for p in varying:
        initpars.append(p.value)
        if (p.pmin is not None or p.pmax is not None) and not warned:
            print('Sorry, scipy backend cannot handle parameter bounds.')
            warned = True

    try:
        res = leastsq(leastsqfcn,
                      initpars,
                      args=(data, ),
                      full_output=1,
                      **add_kw)
    except Exception as e:
        return False, str(e), 0

    popt, pcov, infodict, errmsg, ier = res
    success = (ier in [1, 2, 3, 4])

    nfree = len(y) - len(varying)
    if nfree > 0 and pcov is not None:
        s_sq = (leastsqfcn(popt, data)**2).sum() / nfree
        pcov = pcov * s_sq
    else:
        pcov = inf

    pd = {}
    for i, p in enumerate(varying):
        pd[p.name] = popt[i]
        if pcov is not inf:
            p.error = sqrt(pcov[i, i])
        else:
            p.error = 0
        p.correl = {}  # XXX
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]

    return success, errmsg, get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 5
0
def do_fit(data, fcn, params, add_kw):

    # lmfit can handle expression-based parameters itself, but that is
    # a) buggy (cannot pass custom items into namespace without subclass)
    # and b) it is better to use the same mechanism in all backends

    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    lmfparams = Parameters()
    for p in varying:
        lmfparams.add(p.name, p.value, min=p.pmin, max=p.pmax)

    def lmfitfcn(lmfparams, data):
        pd = dict((pn, lmfparams[pn].value) for pn in varynames)
        update_params(dependent, meta, pd)
        return (fcn(pd, x) - y) / dy

    printReport = add_kw.pop('printReport', False)

    try:
        out = minimize(lmfitfcn, lmfparams, args=(data,), **add_kw)
    except Exception as e:
        print(str(e))
        return False, str(e), 0

    if printReport:
        report_fit(out.params)

    pd = dict((pn, out.params[pn].value) for pn in varynames)
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]
        if p.name in lmfparams:
            p.error = out.params[p.name].stderr
            p.correl = out.params[p.name].correl
        else:
            p.error = 0
            p.correl = {}

    # sadly, out.message is a bit buggy
    message = ''
    if not out.success:
        message = out.lmdif_message
    if not out.errorbars:
        message += ' Could not estimate error bars.'
    return out.success, message, out.redchi
Exemplo n.º 6
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def minuitfcn(*args):
        pd = dict(zip(varynames, args))
        update_params(dependent, meta, pd)
        return ((fcn(pd, x) - y)**2 / dy**2).sum()

    printReport = add_kw.pop('printReport', False)

    marg = dict(
        print_level=int(printReport),
        forced_parameters=varynames,
    )
    marg.update(add_kw)
    if 'errordef' not in marg:
        marg['errordef'] = 1
    for p in varying:
        marg[p.name] = p.value
        marg['error_' + p.name] = 100*p.delta or p.value/100. or 0.01
        if p.pmin is not None or p.pmax is not None:
            marg['limit_' + p.name] = (p.pmin is None and -1e8 or p.pmin,
                                       p.pmax is None and +1e8 or p.pmax)

    m = Minuit(minuitfcn, **marg)
    try:
        m.migrad()
        m.hesse()
    except Exception as e:
        return False, str(e), 0
    # m.minos()  -> would calculate more exact and asymmetric errors

    pd = dict((pn, m.values[pn]) for pn in varynames)
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]
        if p.name in varynames:
            p.error = m.errors[p.name]
            p.correl = {}  # XXX
        else:
            p.error = 0
            p.correl = {}

    return True, '', get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 7
0
 def plot_model_components(self,
                           model,
                           data,
                           labels=True,
                           paramvalues=None,
                           offset=0,
                           **kw):
     if self.no_fits:
         return
     if paramvalues is None:
         paramvalues = prepare_params(model.params, data.meta)[3]
     nsamples = self._get_samples(model, data)
     imin, imax = data.x_plot.argmin(), data.x_plot.argmax()
     xx = multi_linspace(data.x[imin], data.x[imax], nsamples)
     xxp = linspace(data.x_plot[imin], data.x_plot[imax], nsamples)
     for comp in model.get_components():
         yy = comp.fcn(paramvalues, xx)
         kw['label'] = labels and comp.name or ''
         self.axes.plot(xxp, yy + offset, kw.pop('fmt', '-.'), **kw)
Exemplo n.º 8
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def leastsqfcn(x, params):
        pd = dict(zip(varynames, params))
        update_params(dependent, meta, pd)
        return fcn(pd, x)

    initpars = []
    initdp = []
    warned = False
    for p in varying:
        initpars.append(p.value)
        initdp.append(p.delta or p.value / 10. or 0.01)
        if (p.pmin is not None or p.pmax is not None) and not warned:
            print('Sorry, unifit backend cannot handle parameter bounds.')
            warned = True
    try:
        res = __leastsq((x, y, dy), leastsqfcn, initpars, initdp, **add_kw)
    except Exception as e:
        raise
        return False, str(e), 0

    success = res['converged']
    errmsg = res['errmsg']

    pd = {}
    for i, p in enumerate(varying):
        pd[p.name] = res['values'][i]
        p.error = res['errors'][i]
        p.correl = {}  # XXX
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]

    return success, errmsg, get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 9
0
 def plot_model(self,
                model,
                data,
                labels=True,
                paramvalues=None,
                offset=0,
                **kw):
     if self.no_fits:
         return
     if paramvalues is None:
         paramvalues = prepare_params(model.params, data.meta)[3]
     nsamples = self._get_samples(model, data)
     imin, imax = data.x_plot.argmin(), data.x_plot.argmax()
     xx = multi_linspace(data.x[imin], data.x[imax], nsamples)
     xxp = linspace(data.x_plot[imin], data.x_plot[imax], nsamples)
     yy = model.fcn(paramvalues, xx)
     if 'label' not in kw:
         kw['label'] = labels and 'fit' or ''
     self.axes.plot(xxp,
                    yy + offset,
                    kw.pop('fmt', 'g'),
                    lw=kw.pop('lw', 2),
                    **kw)