コード例 #1
0
ファイル: part1.py プロジェクト: QuantumDancer/FP2
def evalDiode():
    datalist = loadCSVToList('../data/part1/Kennlinie.txt')
    data = DataErrors()
    U0 = datalist[0][1]
    sU0 = 0.05 + 0.01 * U0
    for I, u in datalist:
        U = u - U0
        su = 5 + 0.01 * u
        sU = sqrt(su**2 + sU0**2)
        data.addPoint(I, U, 0.1, sU)
    xmin, xmax = 53, 71.5

    c = TCanvas('c_diode', '', 1280, 720)
    g = data.makeGraph('g_diode', "Laserstrom I_{L} / mA",
                       "Photodiodenspannung U_{ph} / mV")
    g.GetXaxis().SetRangeUser(-5, 90)
    g.SetMinimum(-50)
    g.SetMaximum(1400)
    g.Draw('APX')

    # y=0 line
    line = TLine(-5, 0, 90, 0)
    line.SetLineColor(OPData.CH2ECOLOR)
    line.Draw()

    data.filterX(xmin, xmax)
    g2 = data.makeGraph('g_diode_2', "Laserstrom I_{L} / mA",
                        "Photodiodenspannung U_{ph} / mV")
    g2.SetMarkerColor(OPData.CH1COLOR)
    g2.SetLineColor(OPData.CH1COLOR)

    fit = Fitter('fit_diode', '[0] * (x-[1])')
    fit.function.SetNpx(1000)
    fit.setParam(0, 'a', 1)
    fit.setParam(1, 'I_{th}', 50)
    fit.fit(g2, 40, 77)
    fit.saveData('../fit/part1/kennlinie.txt')

    l = TLegend(0.15, 0.55, 0.4, 0.85)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Laserdiodenkennlinie', 'p')
    l.AddEntry(g2, 'Ausschnitt zum Fitten', 'p')
    l.AddEntry(fit.function, 'Fit mit U_{ph} = a (I_{ L} - I_{ th} )', 'l')
    fit.addParamsToLegend(l, (('%.1f', '%.1f'), ('%.2f', '%.2f')),
                          chisquareformat='%.2f',
                          units=['mV/mA', 'mA'])
    l.Draw()

    g.Draw('P')
    g2.Draw('P')

    c.Update()
    c.Print('../img/part1/diodenkennlinie.pdf', 'pdf')
コード例 #2
0
ファイル: part1.py プロジェクト: Bigben37/FP2
def evalDiode():
    datalist = loadCSVToList('../data/part1/Kennlinie.txt')
    data = DataErrors()
    U0 = datalist[0][1]
    sU0 = 0.05 + 0.01 * U0
    for I, u in datalist:
        U = u - U0
        su = 5 + 0.01 * u
        sU = sqrt(su ** 2 + sU0 ** 2)
        data.addPoint(I, U, 0.1, sU)
    xmin, xmax = 53, 71.5

    c = TCanvas('c_diode', '', 1280, 720)
    g = data.makeGraph('g_diode', "Laserstrom I_{L} / mA", "Photodiodenspannung U_{ph} / mV")
    g.GetXaxis().SetRangeUser(-5, 90)
    g.SetMinimum(-50)
    g.SetMaximum(1400)
    g.Draw('APX')

    # y=0 line
    line = TLine(-5, 0, 90, 0)
    line.SetLineColor(OPData.CH2ECOLOR)
    line.Draw()

    data.filterX(xmin, xmax)
    g2 = data.makeGraph('g_diode_2', "Laserstrom I_{L} / mA", "Photodiodenspannung U_{ph} / mV")
    g2.SetMarkerColor(OPData.CH1COLOR)
    g2.SetLineColor(OPData.CH1COLOR)

    fit = Fitter('fit_diode', '[0] * (x-[1])')
    fit.function.SetNpx(1000)
    fit.setParam(0, 'a', 1)
    fit.setParam(1, 'I_{th}', 50)
    fit.fit(g2, 40, 77)
    fit.saveData('../fit/part1/kennlinie.txt')

    l = TLegend(0.15, 0.55, 0.4, 0.85)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Laserdiodenkennlinie', 'p')
    l.AddEntry(g2, 'Ausschnitt zum Fitten', 'p')
    l.AddEntry(fit.function, 'Fit mit U_{ph} = a (I_{ L} - I_{ th} )', 'l')
    fit.addParamsToLegend(l, (('%.1f', '%.1f'), ('%.2f', '%.2f')), chisquareformat='%.2f', units=['mV/mA', 'mA'])
    l.Draw()

    g.Draw('P')
    g2.Draw('P')

    c.Update()
    c.Print('../img/part1/diodenkennlinie.pdf', 'pdf')
コード例 #3
0
ファイル: eval_energy_gauge.py プロジェクト: Bigben37/FP1
def energyGauge():
    dataList = readFileToList('../calc/hg_lines.txt')
    elemNames = ['Hg'] * len(dataList)
    dataList += readFileToList('../calc/na_lines.txt')
    elemNames += ['Na'] * (len(dataList) - len(elemNames))
    litVals = readFileToList('../data/hg_litvals.txt')
    litVals += readFileToList('../data/na_litvals.txt')

    data = DataErrors()
    for val, litval in zip(dataList, litVals):
        data.addPoint(val, litval, I2Data.ERRORBIN, 0)
        
    c = TCanvas('c', '', 1280, 720)
    g = data.makeGraph('g', 'measured wavelength #lambda_{exp} / nm', 'literature value #lambda_{lit} / nm')
    g.Draw('AP')
    
    fit = Fitter('f', '[0]+[1]*x')
    fit.setParam(0, 'a', 0)
    fit.setParam(1, 'b', 1)
    fit.fit(g, 420, 600)
    fit.saveData('../calc/fit_energy_gauge.txt', 'w')
    
    l = TLegend(0.15, 0.6, 0.5, 0.85)
    l.AddEntry(fit.function, 'y = a + b*x', 'l')
    fit.addParamsToLegend(l)
    l.SetTextSize(0.03)
    l.Draw()
    
    c.Update()
    c.Print('../img/energy_gauge.pdf', 'pdf')
コード例 #4
0
ファイル: eval_angles.py プロジェクト: Bigben37/FP1
def evalAngles():
    # load data and set errors
    datalist = loadCSVToList('../data/angles.txt')
    l = len(datalist)
    data = DataErrors().fromLists(list(zip(*datalist)[0]), list(zip(*datalist)[1]), ex=[0.5] * l, ey=[0] * l)
    data.setYErrorFunc(lambda x: np.sqrt(x))
    
    #draw graph
    c = TCanvas('c', '', 1280, 720)
    g = data.makeGraph('g', 'Winkel #alpha / #circ', 'Counts N')
    g.SetMarkerStyle(1)
    g.Draw('AP')
    
    #fit function
    fit = Fitter('f', '[0]+gaus(1)')
    fit.function.SetNpx(1000)  # for smoother curve
    fit.setParam(0, 'offset', 35)
    fit.setParam(1, 'ampl', 350)
    fit.setParam(2, 'theta', 180)
    fit.setParam(3, 'sigma', 20)
    fit.fit(g, 80, 280)
    fit.saveData('../calc/angles.txt', 'w')

    fit2 = Fitter('f', '[0]+1/2*[4]*(TMath::Erf(([1]+2*x-2*[2])/(2*sqrt(2)*[3]))+TMath::Erf(([1]-2*x+2*[2])/(2*sqrt(2)*[3])))')
    fit2.function.SetNpx(1000)  # for smoother curve
    fit2.function.SetLineColor(4)
    fit2.setParam(0, 'offset', 20)
    fit2.setParam(1, 'breite', 20)
    fit2.setParam(2, 'theta', 180)
    fit2.setParam(3, 'sigma', 5)
    fit2.setParam(4, 'amplitude', 350)
    fit2.fit(g, 80, 280, '+')
    fit2.saveData('../calc/angles_convolution.txt', 'w')
    
    l = TLegend(0.65, 0.55, 0.85, 0.85)
    l.AddEntry('g', 'Messwerte', 'p')
    l.AddEntry(fit.function, 'Fit mit Gaussverteilung', 'l')
    l.AddEntry(0, '#chi^2 / DoF = %.1f' % fit.getChisquareOverDoF(), '')
    l.AddEntry(0, '#alpha_{0,g} = (%.1f #pm %.1f) #circ' % (fit.params[2]['value'], fit.params[2]['error']), '')
    l.AddEntry(fit2.function, 'Fit mit Faltungsprodukt', 'l')
    l.AddEntry(0, '#chi^2 / DoF = %.1f' % fit2.getChisquareOverDoF(), '')
    l.AddEntry(0, '#alpha_{0,f} = (%.1f #pm %.1f) #circ' % (fit2.params[2]['value'], fit2.params[2]['error']), '')
    l.Draw()
    
    #print to file
    c.Update()
    c.Print('../img/angles.pdf')
コード例 #5
0
def evalTaus(taus, filters):
    data = DataErrors()
    table = []
    for key, (tau, stau) in taus.items():
        invtau = 1 / tau
        sinvtau = stau / (tau**2)
        int, sint = filters[key]
        data.addPoint(int, invtau, sint, sinvtau)
        table.append([int * 100, sint * 100, tau * 1000, stau * 1000])

    table.sort(key=lambda x: x[0], reverse=True)
    # make table
    with TxtFile('../src/tab_part5_taus.tex', 'w') as f:
        f.write2DArrayToLatexTable(
            table, [
                r'$I_\text{mess}$ / \%', r'$s_{I_\text{mess}}$ / \%',
                r'$\tau$ / ms', r'$s_\tau$ / ms'
            ], ['%.2f', '%.2f', '%.3f', '%.3f'],
            r'Orientierungszeiten $\tau$ des Rubidiumensembles bei verschiedenen Pumpintensitäten $I_{\text{mess}}$.',
            'tab:deh:fitres')

    # make fit
    c = TCanvas('c_taus', '', 1280, 720)
    g = data.makeGraph('g_taus', r'relative Intensitaet I_{mess}',
                       'inverse Orientierungszeit #tau^{ -1} / s^{-1}')
    g.Draw('APX')

    fit = Fitter('fit_taus', '[0]*x + 1/[1]')
    fit.setParam(0, '#alpha', 1)
    fit.setParam(1, 'T_{R}', 1)
    fit.fit(g, 0, 1.1)
    fit.saveData('../fit/part5/taufit.txt')

    l = TLegend(0.55, 0.15, 0.85, 0.5)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Inverse Orientierungszeit #tau^{ -1}', 'p')
    l.AddEntry(fit.function,
               'Fit mit #tau^{ -1} (I) = #alpha I + #frac{1}{T_{R}}', 'l')
    fit.addParamsToLegend(l, [('%.0f', '%.0f'), ('%.5f', '%.5f')],
                          chisquareformat='%.2f',
                          units=['s^{-1}', 's'])
    l.Draw()

    g.Draw('P')
    c.Print('../img/part5/taufit.pdf', 'pdf')
コード例 #6
0
ファイル: part5.py プロジェクト: Bigben37/FP2
def evalTaus(taus, filters):
    data = DataErrors()
    table = []
    for key, (tau, stau) in taus.items():
        invtau = 1 / tau
        sinvtau = stau / (tau ** 2)
        int, sint = filters[key]
        data.addPoint(int, invtau, sint, sinvtau)
        table.append([int * 100, sint * 100, tau * 1000, stau * 1000])

    table.sort(key=lambda x: x[0], reverse=True)
    # make table
    with TxtFile('../src/tab_part5_taus.tex', 'w') as f:
        f.write2DArrayToLatexTable(table, [r'$I_\text{mess}$ / \%', r'$s_{I_\text{mess}}$ / \%', r'$\tau$ / ms', r'$s_\tau$ / ms'],
                                   ['%.2f', '%.2f', '%.3f', '%.3f'],
                                   r'Orientierungszeiten $\tau$ des Rubidiumensembles bei verschiedenen Pumpintensitäten $I_{\text{mess}}$.',
                                   'tab:deh:fitres')

    # make fit
    c = TCanvas('c_taus', '', 1280, 720)
    g = data.makeGraph('g_taus', r'relative Intensitaet I_{mess}', 'inverse Orientierungszeit #tau^{ -1} / s^{-1}')
    g.Draw('APX')

    fit = Fitter('fit_taus', '[0]*x + 1/[1]')
    fit.setParam(0, '#alpha', 1)
    fit.setParam(1, 'T_{R}', 1)
    fit.fit(g, 0, 1.1)
    fit.saveData('../fit/part5/taufit.txt')

    l = TLegend(0.55, 0.15, 0.85, 0.5)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Inverse Orientierungszeit #tau^{ -1}', 'p')
    l.AddEntry(fit.function, 'Fit mit #tau^{ -1} (I) = #alpha I + #frac{1}{T_{R}}', 'l')
    fit.addParamsToLegend(l, [('%.0f', '%.0f'), ('%.5f', '%.5f')], chisquareformat='%.2f', units=['s^{-1}', 's'])
    l.Draw()

    g.Draw('P')
    c.Print('../img/part5/taufit.pdf', 'pdf')
コード例 #7
0
ファイル: part4.py プロジェクト: QuantumDancer/FP2
def evalAngleDependency():
    datalist = loadCSVToList(DIR + 'Winkelabh.txt')
    data = DataErrors()
    strel = 0.01
    sI = 1
    for t2, t1, n, phi in datalist:
        f, sf = calcPrecissionFreq(t2, t1, n)
        data.addPoint(phi, f, 0.5, sf)

    c = TCanvas('c_phi', '', 1280, 720)
    g = data.makeGraph('g_phi', 'Rotation des Strahlengangs #varphi / #circ',
                       'Praezessionsfrequenz f / kHz')
    g.GetXaxis().SetRangeUser(-15, 15)
    g.SetMinimum(0)
    g.Draw('APX')

    fit = Fitter('fit_phi', '[0] * abs(sin((x-[1])*pi/180))')
    fit.function.SetNpx(1000)
    fit.setParam(0, '#beta', 1)
    fit.setParam(1, '#phi_{0}', 0)
    fit.fit(g, -15, 15)
    fit.saveData('../fit/part4/winkel.txt')

    g.Draw('P')

    l = TLegend(0.7, 0.15, 0.95, 0.5)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Praezessionsfrequenz', 'p')
    l.AddEntry(fit.function, 'Fit mit f = #beta |sin(#varphi + #varphi_{0})|',
               'l')
    fit.addParamsToLegend(l, (('%.1f', '%.1f'), ('%.2f', '%.2f')),
                          chisquareformat='%.2f',
                          units=['kHz/#muT', '#circ'])
    l.Draw()

    c.Update()
    c.Print('../img/part4/winkel.pdf', 'pdf')
コード例 #8
0
ファイル: eval_sm.py プロジェクト: Bigben37/FP1
def makeAreaFit():
    # calculate ares
    d_s = [1.000, 0.990, 0.990, 1.005, 1.000, 1.005]
    d_m = [1.700, 1.690, 1.695, 1.700, 1.705, 1.705]
    d_l = [2.880, 2.880, 2.875, 2.880, 2.880, 2.880]
    d = map(avgstd, [d_s, d_m, d_l])
    a = map(area, d)
    
    diaarea = DataErrors()
    for i in range(3):
        diaarea.addPoint(d[i][0], a[i][0], d[i][1], a[i][1])
    diaarea.saveDataToLaTeX(['Durchmesser $d$ / cm', '$s_d$ / cm', 'Fl\"ache $F / \\text{cm}^2$', '$s_F / \\text{cm}^2$'], 
                            ['%.4f', '%.4f', '%.4f', '%.4f'], 'Verschiedene Fl\"achen f\"ur die Samariummessung', 
                            'tab:data:samarium:area', '../src/data_samarium_areas.tex', 'w')
    
    with TxtFile('../fit/samarium.txt', 'w') as f:
        f.writeline('areas')
        f.writeline('=====')
        for b in a:
            f.writeline('\t', '%e' % b[0], TxtFile.PM, '%e' % b[1])
        f.writeline()
    
    
    #read data from files
    #file=[area, area error, path, time]
    files = []
    files.append([a[0][0], a[0][1], '../data/31_Sm_kl_1600_t3000.txt', 3000])
    files.append([a[1][0], a[1][1], '../data/34_Sm_m_1600_t2400.txt', 2400])
    files.append([a[2][0], a[2][1], '../data/08_Sm_ggrFl_1600-1600-0.txt', 1200])
    u = readSingleEntryFile('../data/09_Untergrund_1600-1600-0.txt') 
    tu = 3600
    d = DataErrors()
    for file in files:
        n = readSingleEntryFile(file[2])
        d.addPoint(file[0], n - u, file[1], np.sqrt(n / file[3] + u / tu))
        
    d.saveDataToLaTeX(['Fl\"ache $F / \\text{cm}^2$', '$s_F / \\text{cm}^2$', 'Z\"ahlrate $n / (1/\\text{s})$', '$s_n / (1/\\text{s})$'], 
                      ['%.4f', '%.4f', '%.3f', '%.3f'], 'Z\"ahlraten von \\samarium~f\"ur verschiedene Fl\"achen mit Fehlern', 
                      'tab:data:samarium', '../src/data_samarium.tex', 'w')
        
    c = TCanvas('c2', '', 800, 600)
    g = d.makeGraph('g', 'Fl#ddot{a}che F / cm^{2}', 'Z#ddot{a}hlrate n / (1/s)')
    g.Draw('AP')
    
    fit = Fitter('f', '[0]+[1]*x')
    fit.setParam(0, 'a', 0)
    fit.setParam(1, 'b', 0.05)
    fit.fit(g, 0, 30)
    fit.saveData('../fit/samarium.txt', 'a')
    
    a = fit.params[0]['value']
    sa = fit.params[0]['error']
    b = fit.params[1]['value']
    sb = fit.params[1]['error']

    l = TLegend(0.55, 0.15, 0.98, 0.5)
    l.AddEntry('g', '{}^{147} Samarium ohne Untergrund', 'p')  # TODO with error bar? (options +'e')
    l.AddEntry(fit.function, 'Fit mit n(F)=a+b*F', 'l')
    l.AddEntry(0, '#chi^{2} / DoF : %f' % fit.getChisquareOverDoF(), '')
    l.AddEntry(0, 'Paramter:', '') 
    l.AddEntry(0, 'a: %e #pm %e' % (a, sa), '')
    l.AddEntry(0, 'b: %e #pm %e' % (b, sb), '')   
    l.SetTextSize(0.03)
    l.Draw()
    
    c.Update()
    c.Print('../img/Samarium147-Flaechenabhaengigkeit.pdf', 'pdf')
    
    #calculation with fit parameters
    c  = 0.004025
    NA = 6.02214129e23
    m  = 2*150.36 + 3*15.999
    h = 0.1487
    t = (np.log(2) * c * NA * h) / (2 * m * b) / (3600 * 24 * 365.242)
    st = t * (sb / b)
    with TxtFile('../fit/samarium.txt', 'a') as f:
        f.writeline('calculation from fit')
        f.writeline('====================')
        f.writeline('\t', '%e' % t, TxtFile.PM, '%e' % st)
        f.writeline()
    
    # calculation from single data points
    sc = map(lambda p: calculateHalfLife(*p), d.points)
    with TxtFile('../fit/samarium.txt', 'a') as f:
        f.writeline('calculation from single data points')
        f.writeline('===================================')
        for s in sc:
            f.writeline('\t', '%e' % s[0], TxtFile.PM, '%e' % s[1])
        f.writeline()
コード例 #9
0
ファイル: part4.py プロジェクト: QuantumDancer/FP2
def evalSpinPrecission(name):
    datalist = loadCSVToList(DIR + name + '.txt')
    data = DataErrors()
    sI = 1
    for t2, t1, n, I in datalist:
        f, sf = calcPrecissionFreq(t2, t1, n)
        B, sB = inductorIToB(4, I * 1e-3, sI * 1e-3)
        data.addPoint(B * 1e6, f, sB * 1e6, sf)

    if len(name) == 4:
        xmin, xmax = 0, 50
    else:
        xmin, xmax = 0, 80

    c = TCanvas('c_%s' % name, '', 1280, 720)
    g = data.makeGraph('g_%s' % name,
                       'Zusaetzliches Vertikalfeld B_{S, v} / #muT',
                       'Praezessionsfrequenz f / kHz')
    g.GetXaxis().SetRangeUser(xmin, xmax)
    g.Draw('APX')

    fit1 = Fitter('fit1_%s' % name, '[0] * abs([1]-x)')
    fit1.function.SetNpx(1000)
    fit1.setParam(0, '#alpha', 1)
    fit1.setParam(1, 'B_{E, v}', 40)
    fit1.fit(g, xmin, xmax)
    fit1.saveData('../fit/part4/fit1_%s' % name)

    fit2 = Fitter('fit1_%s' % name, '[0] * (abs([1]-x) + [2])')
    fit2.function.SetNpx(1000)
    fit2.function.SetLineColor(3)
    fit2.setParam(0, '#alpha', 1)
    fit2.setParam(1, 'B_{E, v}', 40)
    fit2.setParam(2, 'B_{E,h,s}', 20)
    fit2.setParamLimits(2, 0, 100)
    fit2.fit(g, xmin, xmax, '+')
    fit2.saveData('../fit/part4/fit2_%s' % name)

    g.Draw('P')

    if len(name) == 4:
        l = TLegend(0.6, 0.4, 0.975, 0.95)
    else:
        l = TLegend(0.325, 0.475, 0.725, 0.99)
    l.SetTextSize(0.03)
    l.AddEntry(g, 'Praezessionsfrequenzen', 'p')
    l.AddEntry(fit1.function,
               'Fit mit f_{1}(B_{S, v}) = #alpha |B_{E, v} - B_{S, v}|', 'l')
    fit1.addParamsToLegend(l, (('%.2f', '%.2f'), ('%.2f', '%.2f')),
                           chisquareformat='%.2f',
                           units=['kHz/#muT', '#muT'])
    l.AddEntry(
        fit2.function,
        'Fit mit f_{2}(B_{S, v}) = #alpha (|B_{E, v} - B_{S, v}| + B_{E,h,s})',
        'l')
    fit2.addParamsToLegend(l, (('%.2f', '%.2f'), ('%.2f', '%.2f'),
                               ('%.2f', '%.2f')),
                           chisquareformat='%.2f',
                           units=['kHz/#muT', '#muT', '#muT'])
    l.Draw()

    c.Update()
    c.Print('../img/part4/%s.pdf' % name, 'pdf')
コード例 #10
0
ファイル: eval_k.py プロジェクト: Bigben37/FP1
def makeMassFit():
    # config files
    # file = [mass, path]
    files = []
    files.append([2.0123, "../data/11_K_m9_3200_t420.txt", 420])
    files.append([2.0123, "../data/11b_K_m9_3200_t420.txt", 420])
    files.append([1.9047, "../data/13_K_m8_3200_t420.txt", 420])
    files.append([1.6812, "../data/15_K_m7_3200_t420.txt", 420])
    files.append([1.4827, "../data/17_K_m6_3200_t420.txt", 420])
    files.append([1.2952, "../data/19_K_m5_3200_t480.txt", 480])
    files.append([1.0993, "../data/21_K_m4_3200_t480.txt", 480])
    files.append([0.8086, "../data/23_K_m3_3200_t540.txt", 540])
    files.append([0.6954, "../data/25_K_m2_3200_t540.txt", 540])
    files.append([0.5007, "../data/27_K_m1_3200_t660.txt", 660])
    files.append([0.3030, "../data/29_K_m0_3200_t780.txt", 780])
    u = 0.760
    tu = 50

    d = DataErrors()

    for file in files:
        n = readSingleEntryFile(file[1])
        d.addPoint(file[0], n - u, 0.001, np.sqrt(n / file[2] + u / tu))

    d.saveDataToLaTeX(['Masse $m /$g', '$s_m /$g', 'Z\"ahlrate $n / (1/\\text{s})$', '$s_n / (1/\\text{s})$'],
                      ['%.3f', '%.3f', '%.3f', '%.3f'], 
                      'Z\"ahlraten von \\kalium\,f\"ur verschiedene Massen mit Fehlern', 'tab:data:kalium', '../src/data_kalium.tex', 'w')

    c = TCanvas('c2', '', 800, 600)
    g = d.makeGraph('g', 'Masse m / g', 'Z#ddot{a}hlrate n / (1/s)')
    g.SetMaximum(6)
    g.SetMinimum(2)
    g.Draw('AP')

    fit = Fitter('f', '[0]*(1-exp(-[1]*x))')
    fit.setParam(0, 'a')
    fit.setParam(1, 'b')
    fit.fit(g, 0.1, 2.5)
    fit.saveData('../fit/kalium.txt')
    
    a = fit.params[0]['value']
    sa = fit.params[0]['error']
    b = fit.params[1]['value']
    sb = fit.params[1]['error']

    l = TLegend(0.4, 0.15, 0.85, 0.5)
    l.AddEntry('g', '{}^{40} Kalium ohne Untergrund', 'p')  # TODO with error bar? (options +'e')
    l.AddEntry(fit.function, 'Fit mit n(m)=a(1-exp(-b*m))', 'l')
    l.AddEntry(0, '#chi^{2} / DoF : %f' % fit.getChisquareOverDoF(), '')
    l.AddEntry(0, 'Paramter:', '') 
    l.AddEntry(0, 'a: %e #pm %e' % (a, sa), '')
    l.AddEntry(0, 'b: %e #pm %e' % (b, sb), '')   
    l.SetTextSize(0.03)
    l.Draw()

    NA = 6.02214129e23
    hrel = 0.000118
    mrel = 39.0983 + 35.45
    f = 1.29
    rho = fit.getCorrMatrixElem(1, 0)
    thalf = (np.log(2) * NA * hrel * f) / (1.12 * mrel * 2 * a * b) / (3600 * 24 * 365.242)
    sthalf = thalf * np.sqrt((sa / a) ** 2 + (sb / b) ** 2 + 2 * rho * (sa / a) * (sb / b))

    with TxtFile.fromRelPath('../fit/kalium.txt', 'a') as f:
        f.writeline()
        f.writeline('calculations')
        f.writeline('============')
        f.writeline('\t', 'half-life of Kalium:', '%e' % thalf, TxtFile.PM, '%e' % sthalf)

    c.Update()
    c.Print('../img/Kalium40_Massenabhaengigkeit.pdf')