示例#1
0
    # effective length of the pendulum = length of the string + radius of the steel ball
    l_total = l + r
    omega_0 = np.sqrt(g / l_total)  # phase speed of an undamped pendulum
    omega_d = np.sqrt(omega_0**2 - c**2)  # phase speed of a damped pendulum
    return y_0 * np.exp(
        -c * x) * (np.cos(omega_d * x) + c / omega_d * np.sin(omega_d * x))


# Load data from yaml, contains data and errors
data = XYContainer.from_file(filename='data.yml')

# Create fit object from data and model function
fit = Fit(data=data, model_function=damped_harmonic_oscillator)

# Constrain model parameters to measurements
fit.add_parameter_constraint(name='l', value=l, uncertainty=delta_l)
fit.add_parameter_constraint(name='r', value=r, uncertainty=delta_r)
fit.add_parameter_constraint(name='y_0',
                             value=y_0,
                             uncertainty=delta_y_0,
                             relative=True)

# Because the model function is oscillating the fit needs to be initialized with near guesses for
# unconstrained parameters in order to converge
g_initial = 9.81  # initial guess for g
c_initial = 0.01  # initial guess for c
fit.set_parameter_values(g=g_initial, c=c_initial)

# Optional: Set the initial values of the remaining parameters to correspond to their constraint
# values (this may help some minimization algorithms converge)
fit.set_parameter_values(y_0=y_0, l=l, r=r)
xy_d2.add_error('x', e2x)  # independent errors y

# set meaningful names
xy_d1.label = 'Beispieldaten (1)'
xy_d1.axis_labels = ['x', 'y (1)']
xy_d2.label = 'Beispieldaten (2)'
xy_d2.axis_labels = ['x', 'y(2) & f(x)']

# 3. create the Fit objects
xyFit1 = Fit(xy_d1, model1)
xyFit2 = Fit(xy_d2, model2)
# set meaningful names for model
xyFit1.model_label = 'Lineares Modell'
xyFit2.model_label = 'Lineares Modell'
# add the parameter constraints
xyFit1.add_parameter_constraint(name='g1', value=c1, uncertainty=ec1)
xyFit2.add_parameter_constraint(name='g2', value=c2, uncertainty=ec2)

# combine the two fit objects to form a MultiFit
multiFit = MultiFit(fit_list=[xyFit1, xyFit2])

# 4. perform the fit
multiFit.do_fit()

# 5. report fit results
multiFit.report()

# 6. create and draw plots
multiPlot = Plot(multiFit)
##multiPlot = Plot(multiFit, separate_figures=True)
multiPlot.plot(figsize=(13., 7.))
示例#3
0
def k2hFit(fitf,
           data,
           bin_edges,
           p0=None,
           constraints=None,
           fixPars=None,
           limits=None,
           use_GaussApprox=False,
           plot=True,
           plot_cor=False,
           showplots=True,
           plot_band=True,
           plot_residual=False,
           quiet=True,
           axis_labels=['x', 'counts/bin = f(x, *par)'],
           data_legend='Histogram Data',
           model_legend='Model',
           model_expression=None,
           model_name=None,
           model_band=r'$\pm 1 \sigma$',
           fit_info=True,
           asym_parerrs=True):
    """Wrapper function to fit a density distribution f(x, \*par) 
  to binned data (histogram) with class mnFit 
  
  The cost function is two times the negative log-likelihood of the 
  Poisson  distribution, or - optionally - of the Gaussian approximation.

  Uncertainties are determined from the model values in order to avoid biases 
  and to take account of empty bins of an histogram. 

  Args:
    * fitf: model function to fit, arguments (float:x, float: \*args)
    * data: the data to be histogrammed  
    * bin_edges: bin edges 

    fit options

      * p0: array-like, initial guess of parameters
      * constraints: (nested) list(s) [name or id, value, error] 
      * limits: (nested) list(s) [name or id, min, max]
      * use_GaussApprox: Gaussian approximation instead of Poisson 

    output options

      * plot: show data and model if True
      * plot_cor: show profile likelihoods and confidence contours
      * plot_band: plot uncertainty band around model function
      * plot_residual: also plot residuals w.r.t. model
      * showplots: show plots on screen
      * quiet: suppress printout
      * axis_labes: list of tow strings, axis labels
      * data_legend: legend entry for data
      * model_legend: legend entry for model 
      * plot: flag to switch off graphical output
      * axis_labels: list of strings, axis labels x and y
      * model_name: latex name for model function
      * model_expression: latex expression for model function
      * model_band: legend entry for model uncertainty band
      * fit_info: controls display of fit results on figure
      * asym_parerrs: show (asymmetric) errors from profile-likelihood scan

  Returns:
    * list: parameter names
    * np-array of float: parameter values
    * np-array of float: negative and positive parameter errors
    * np-array: cor   correlation matrix 
    * float: goodness-of-fit (equiv. chi2 for large number of entries/bin)

  """

    # for fit with kafe2
    from kafe2 import HistContainer, Fit, Plot, ContoursProfiler
    from kafe2.fit.histogram import HistCostFunction_NegLogLikelihood

    # create a data container from input
    nbins = len(bin_edges) - 1
    bin_range = (bin_edges[0], bin_edges[-1])
    hdat = HistContainer(nbins, bin_range, bin_edges=bin_edges, fill_data=data)

    # set up fit object
    if use_GaussApprox:
        print(
            'Gauss Approx. for histogram data not yet implemented - exiting!')
        exit(1)
        ## hfit = Fit(hdat, fitf,
        ##            cost_function=CostFunction_GaussApproximation)
    else:
        hfit = Fit(hdat,
                   fitf,
                   cost_function=HistCostFunction_NegLogLikelihood(
                       data_point_distribution='poisson'))
    # text for labeling
    hfit.assign_model_function_latex_name(model_name)
    hfit.assign_model_function_latex_expression(model_expression)
    hfit.model_label = model_legend

    # - provide text for labeling ...
    hdat.label = data_legend
    hdat.axis_labels = axis_labels

    # initialize and run fit
    if p0 is not None: hfit.set_all_parameter_values(p0)

    if constraints is not None:
        if not (isinstance(constraints[0], tuple)
                or isinstance(constraints[0], list)):
            constraints = (constraints, )
        for c in constraints:
            hfit.add_parameter_constraint(*c)

    if limits is not None:
        if isinstance(limits[1], list):
            for l in limits:
                hfit.limit_parameter(l[0], l[1], l[2])
        else:
            hfit.limit_parameter(limits[0], limits[1], limits[2])

    hfit.do_fit()

    # harvest results
    #  par, perr, cov, chi2 = fit.get_results() # for kafe vers. > 1.1.0
    parn = np.array(hfit.parameter_names)
    parv = np.array(hfit.parameter_values)
    pare = np.array(hfit.parameter_errors)
    cor = np.array(hfit.parameter_cor_mat)
    gof = hfit.goodness_of_fit
    if asym_parerrs:
        parae = np.array(hfit.asymmetric_parameter_errors)
    else:
        parae = np.array(list(zip(-pare, pare)))

    if not quiet:
        hfit.report(asymmetric_parameter_errors=True)

    if plot:
        # plot data, uncertainties, model line and model uncertainties
        kplot = Plot(hfit)
        # set some 'nice' options
        kplot.customize('data', 'marker', ['o'])
        kplot.customize('data', 'markersize', [6])
        kplot.customize('data', 'color', ['darkblue'])
        ## the following not (yet) defined for kafe2 Histogram Fit
        ##    kplot.customize('model_line', 'color', ['darkorange'])
        ##    kplot.customize('model_line', 'linestyle', ['--'])
        ##    if not plot_band:
        ##      kplot.customize('model_error_band', 'hide', [True])
        ##    else:
        ##      kplot.customize('model_error_band', 'color', ['green'])
        ##      kplot.customize('model_error_band', 'label', [model_band])
        ##      kplot.customize('model_error_band', 'alpha', [0.1])

        # plot with defined options
        kplot.plot(fit_info=fit_info,
                   residual=plot_residual,
                   asymmetric_parameter_errors=True)

        if plot_cor:
            cpf = ContoursProfiler(hfit)
            cpf.plot_profiles_contours_matrix(
            )  # plot profile likelihood and contours

        if showplots: plt.show()

    return parv, parae, cor, gof