def fit_radium_calib(): energies = [3.953, 5.332, 7.02] # MeV error_energies = np.array([0.001, 0.001, 0.01]) / math.sqrt(12) channels = [240, 815, 1495] error_channels = [10, 10, 8] fit = Fit(LINEAR) fit.set_data(xdata=channels, xerrors=error_channels, ydata=energies, yerrors=error_energies) fit.set_labels(xlabel="Kanal", ylabel="Energie / MeV") fit.iterative_fit(5) plt.clf() plt.minorticks_on() fit.plot(box="tl", units={ "slope": "keV/Kanal", "offset": "MeV" }, factors={"slope": 1000}) plt.savefig("out/radium_calib_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="bl") plt.savefig("out/radium_calib_residual." + SAVETYPE)
def plot_caesium_absorber(): depth, events, slabs = np.loadtxt("data/caesium_bleiabschirmung.txt", unpack=True) error_depth = np.sqrt(slabs) * 0.1 error_events = np.sqrt(events + 1) plt.clf() plt.minorticks_on() plt.errorbar(depth, events, xerr=error_depth, yerr=error_events, fmt=',') plt.xlabel("Tiefe / mm") plt.ylabel("ln(Anzahl)") plt.savefig("out/caesium_absorber_nolog." + SAVETYPE) ln_events = np.log(events) error_ln_events = np.abs(1 / events) * error_events depth /= 10 # mm=>cm error_depth /= 10 plt.clf() plt.minorticks_on() func = lambda x, mu, lnI0: -x * mu + lnI0 fit = Fit(func) fit.set_data(xdata=depth, ydata=ln_events, xerrors=error_depth, yerrors=error_ln_events) fit.set_labels(xlabel="Tiefe / cm", ylabel="ln(Anzahl)") fit.iterative_fit(5) fit.plot(box="tr", units={"mu": "1/cm"}) plt.savefig("out/caesium_absorber_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/caesium_absorber_residual." + SAVETYPE) plt.clf() plt.minorticks_on() fit = fit.filtered(depth <= 2) fit.iterative_fit(5) fit.plot(box="tr", units={"mu": "1/cm"}) plt.savefig("out/caesium_absorber_fit2." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/caesium_absorber_residual2." + SAVETYPE) mu = fit.uvalue("mu") print("Absorptionskoeffizient:", mu, "1/cm") mu1 = mu / ufloat(11.342, 0.001) print("Massenabsorptionskoeffizient:", mu1, "cm^2/g")
def plot_yag_lifetime(): time, voltage = _load_oscilloscope_csv("data/ALL0010/F0010CH2.CSV") time *= 1E6 # us voltage *= 1000 # mV error_voltage = voltage[time < 0].std() print("Fehler:", error_voltage, "mV") fit = Fit(EXPONENTIAL_DECAY) fit.set_data(xdata=time, ydata=voltage, yerrors=error_voltage) fit.set_labels(xlabel="Zeit / us", ylabel="Spannung / mV") fit = fit.filtered(np.logical_and(time > 0, time < 1500)) fit.set_params(A=0.1, offset=0.20, T=250) fit.iterative_fit(1) print("Lebensdauer:", formatUFloat(fit.uvalue("T"), "us"), "- Chi^2:", fit.chi2, "- ndf:", fit.ndf, "- Chi^2/ndf:", fit.chi2ndf) plt.clf() fit.plot(box="tr", units={"T": "us", "A": "mV", "offset": "mV"}) plt.savefig("out/yag_lifetime." + SAVETYPE)
def plot_strontium(): m = { 0: 0, 5: 0.03, 6: 0.04, 7: 0.05, 8: 0.08, 9: 0.10, 10: 0.17, 11: 0.25, 12: 0.37, 13: 0.50, 14: 0.64, 15: 0.83, 16: 1.01, 17: 1.23, 18: 1.39, 19: 1.57, 20: 1.88, 21: 2.29, 22: 2.79, 23: 3.46, } nr, count = np.loadtxt("data/strontium_alu.txt", unpack=True) absorb = np.zeros_like(nr) for i, x in enumerate(nr): absorb[i] = m[x] / 10 scale = 1 / count[0] error_count = np.sqrt(count + 1) error_absorb = 0.01 / 10 count *= scale error_count *= scale func = lambda x, A, mu, offset: A * np.exp(-x * mu) + offset fit = Fit(func) fit.set_data(xdata=absorb, ydata=count, xerrors=error_absorb, yerrors=error_count) fit.set_params(A=1, mu=1, offset=0) fit.set_labels(xlabel="Dicke / cm", ylabel="Anteil") fit.iterative_fit(5) plt.clf() plt.minorticks_on() plt.xlim(0, .35) fit.plot(box="tr", units={"mu": "1/cm"}) plt.savefig("out/strontium_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/strontium_residual." + SAVETYPE) rho = ufloat(2.7, 0.1) mu = fit.uvalue("mu") print("Absorptionskoeffizient:", mu, "1/cm") mu1 = mu / rho print("Massenabsorptionskoeffizient:", mu1, "cm^2/g") E = umath.pow(17 / mu1, 1 / 1.14) print("Maximalenergie:", E, "MeV") R1 = 0.412 * umath.pow(E, 1.265 - 0.0954 * umath.log(E)) R = R1 / rho print("Reichweite:", R1, "g/cm^2") print("Reichweite:", R, "cm")
def plot_ionisation_raw(): distances, voltages, error_voltages = np.loadtxt( "data/radium_ionisationskammer.txt", unpack=True) # discard 38.80cm distances = distances[:-1] voltages = voltages[:-1] error_voltages = error_voltages[:-1] for distance, voltage, error_voltage in zip(distances, voltages, error_voltages): distance = ufloat(distance, 0.05) voltage = ufloat(voltage, error_voltage) print("$({:L}) \\unit{{cm}}$ & $({:L}) \\unit{{mV}}$ \\\\".format( distance, voltage)) plt.clf() plt.minorticks_on() plt.errorbar(distances, voltages, xerr=0.05, yerr=error_voltages, fmt=',') plt.xlabel("Distanz / cm") plt.ylabel("Spannung / mV") plt.savefig("out/radium_ionisation_raw." + SAVETYPE) plt.clf() plt.minorticks_on() currents = [] error_currents = [] for voltage, error_voltage in zip(voltages, error_voltages): current = ufloat(voltage, error_voltage) #+ ufloat(5, 3) currents.append(current.n) error_currents.append(current.s) currents = np.array(currents) error_currents = np.array(error_currents) distances -= 39 plt.clf() plt.minorticks_on() plt.errorbar(distances, currents, xerr=0.05, yerr=error_currents, fmt=',') plt.xlabel("Distanz / cm") plt.ylabel("Strom / nA") plt.savefig("out/radium_ionisation." + SAVETYPE) plt.clf() plt.minorticks_on() x = distances[1:] + np.abs(np.diff(distances) / 2) y = -np.diff(currents) / np.diff(distances) plt.plot(x, y, 's-') plt.xlabel("Distanz / cm") plt.ylabel("- Änderung des Stromes / nA / cm") plt.savefig("out/radium_ionisation_diff." + SAVETYPE) plt.clf() plt.minorticks_on() fit = Fit(LINEAR) fit.set_data(xdata=(7.42, 6.92, 6.42), ydata=currents[9:12], xerrors=0.25, yerrors=error_currents[9:12]) fit.set_labels(xlabel="Distanz / cm", ylabel="Strom / nA") fit.iterative_fit(5) fit.plot(box="tr", units={"slope": "nA/cm", "offset": "nA"}) plt.savefig("out/radium_ionisation_po_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tl") plt.savefig("out/radium_ionisation_po_residual." + SAVETYPE) middle = (ufloat(currents[9], error_currents[9]) + ufloat(currents[11], error_currents[11])) / 2 print("Middle:", middle, "nA") r = (middle - fit.uvalue("offset")) / fit.uvalue("slope") print("Range:", r, "cm")
def calc_radium_range(): peak = { 35: (1100, 1800), 35.5: (1000, 1700), 36: (900, 1600), 36.5: (800, 1500), 37: (600, 1400), 37.5: (500, 1200), 38: (300, 1000), 38.5: (100, 700) } distances = [] error_distances = [] integrals = [] error_integrals = [] for distanceStr in ("35_0", "35_5", "36_0", "36_5", "37_0", "37_5", "38_0", "38_5"): filename = "data/Radium%s.TKA" % distanceStr distance = ufloat(float(distanceStr.replace("_", ".")), 0.05) tka = TkaFile(filename) lower, upper = peak[distance.n] data = tka.data[lower:upper] distance = distance - 35 + ufloat(3.17, 0.17) integral = ufloat(data.sum(), math.sqrt((data + 1).sum())) integral_fixed = integral * distance**2 print( "$({:L}) \\unit{{cm}}$ & {:d} & {:d} & ${:dL}$ & ${:dL} \\unit{{cm^2}}$ \\\\" .format(distance, lower, upper, integral, integral_fixed)) distances.append(distance.n) error_distances.append(distance.s) integrals.append(integral_fixed.n) error_integrals.append(integral_fixed.s) distances = np.array(distances) integrals = np.array(integrals) error_distances = np.array(error_distances) error_integrals = np.array(error_integrals) plt.clf() plt.minorticks_on() plt.errorbar(distances, integrals, xerr=error_distances, yerr=error_integrals, fmt="s") #plt.plot(distances, integrals, 's') plt.xlabel("Distanz / cm") plt.ylabel("korrigierte Summe / cm^2") plt.ylim(0, plt.ylim()[1]) plt.savefig("out/radium_range." + SAVETYPE) #plt.show() plt.clf() plt.minorticks_on() scale = 1 / integrals[0:3].mean() fit = Fit(LINEAR) fit.set_params(offset=1, slope=-0.5) fit.set_data(xdata=distances[1:], ydata=integrals[1:] * scale, xerrors=error_distances[1:], yerrors=error_integrals[1:] * scale) fit.set_labels(xlabel="Distanz / cm", ylabel="Intensität") fit.iterative_fit(5) fit.plot(plot_data=True, plot_fit=True, box="bl", units={"slope": "1/cm"}) plt.ylim(0, plt.ylim()[1]) plt.savefig("out/radium_range_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/radium_range_residual." + SAVETYPE) r = (0.5 - fit.uvalue("offset")) / fit.uvalue("slope") print("Range:", r, "cm")
def radium_calib_2(): E, proj_range = np.loadtxt("ranges.txt", unpack=True) real_range = proj_range / 1.184e-3 energy_from_range = interp1d(real_range, E, kind='cubic') energies = [] error_energies = [] for distance in (0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5): distance = ufloat(35 + distance, 0.05) total_distance = (distance - 35) + ufloat(3.17, 0.17) for peak in (3.52, 4.99, 7.18): peak = ufloat(peak, 0.01) rest = peak - total_distance try: upper = energy_from_range(rest.n + rest.s) lower = energy_from_range(rest.n - rest.s) value = energy_from_range(rest.n) except ValueError as e: #print(e) #print("orig distance:", peak, "cm ", "rest distance:", rest, "cm ") pass else: error = max(upper - value, value - lower) energy = ufloat(value, error) #print("orig distance:", peak, "cm ", "total distance:", total_distance, "cm ", "rest distance:", rest, "cm ", "rest energy:", energy, "MeV") print( "$({:L}) \\unit{{cm}}$ & $({:L}) \\unit{{cm}}$ & $({:L}) \\unit{{cm}}$ & $({:L}) \\unit{{cm}}$ & $({:L}) \\unit{{MeV}}$ \\\\" .format(peak, distance, total_distance, rest, energy)) energies.append(value) error_energies.append(error) # PART2 !!! channels = [ 220, 780, 1460, 620, 1340, 450, 1260, 150, 1170, 990, 820, 620, 390 ] error_channels = [20, 20, 20, 20, 20, 20, 20, 100, 20, 20, 20, 20, 30] energies = energies[:len(channels)] error_energies = error_energies[:len(channels)] for energy, error_energy, channel, error_channel in zip( energies, error_energies, channels, error_channels): e = ufloat(energy, error_energy) c = ufloat(channel, error_channel) print("$({:L}) \\unit{{MeV}}$ & ${:L}$ \\\\".format(e, c)) fit = Fit(LINEAR) fit.set_data(xdata=channels, xerrors=error_channels, ydata=energies, yerrors=error_energies) fit.set_labels(xlabel="Kanal", ylabel="Energie / MeV") fit.iterative_fit(5) plt.clf() plt.minorticks_on() fit.plot(box="tl", units={ "slope": "keV/Kanal", "offset": "MeV" }, factors={"slope": 1000}) plt.savefig("out/radium_calib2_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/radium_calib2_residual." + SAVETYPE)
def plot_diode_kennlinie(): current, power = np.loadtxt("data/kennlinie_diode.txt", unpack=True) error_current = 1 / math.sqrt(12) error_power = 1 / math.sqrt(12) plt.clf() plt.errorbar(current, power, xerr=error_current, yerr=error_power, fmt=',', color="black") plt.xlabel("Strom / mA") plt.ylabel("Leistung / mW") plt.savefig("out/kennlinie_diode_raw." + SAVETYPE) fit_indices_list = [] fit_indices_list.append(current > 200) valid = current > 200 valid[current > 410] = False fit_indices_list.append(valid) valid = current > 410 fit_indices_list.append(valid) zero_power = power[current < 150] background = zero_power.mean() print("Background:", background, "mW") power -= background func = lambda x, slope, threshold: (x - threshold) * slope fit = Fit(func) fit.set_params(slope=0.85, threshold=190) fit.set_data(xdata=current, ydata=power, xerrors=error_current, yerrors=error_power) fit.set_labels(xlabel="Strom / mA", ylabel="Leistung / mW") for i, fit_indices in enumerate(fit_indices_list): subfit = fit.filtered(fit_indices) plt.clf() plt.errorbar(current, power, xerr=error_current, yerr=error_power, fmt=',', color="black") subfit.iterative_fit(5) #plt.axhline(background, color="blue") #plt.axvline(subfit.value("threshold"), color="blue") print("Threshold:", formatUFloat(subfit.uvalue("threshold"), unit="mA")) print("Slope:", formatUFloat(subfit.uvalue("slope"), unit="W/A")) print("Chi^2/ndf:", subfit.chi2ndf) print("===") subfit.plot(range=(subfit.value("threshold"), current.max()), color="black", plot_fit=False, plot_data=True, fmt="s") subfit.plot(range=(subfit.value("threshold"), current.max()), box="tl", color="red", plot_data=False, units={ "threshold": "mA", "slope": "W/A" }) plt.savefig("out/kennlinie_diode_%d_fit." % i + SAVETYPE) plt.clf() subfit.plot_residual(box="br", color="black", fmt="s") plt.savefig("out/kennlinie_diode_%d_residual." % i + SAVETYPE)
def plot_qswitch(): frequency, error_frequency, power = np.loadtxt("data/frequenz_qswitch.txt", unpack=True) error_power = 1 / math.sqrt(12) power /= 1000 error_power /= 1000 plt.clf() plt.errorbar(frequency, power, xerr=error_frequency, yerr=error_power, fmt=',', color="black") plt.xlabel("Frequenz / Hz") plt.ylabel("Leistung / mW") plt.savefig("out/qswitch_raw." + SAVETYPE) #power -= power[0] fit = Fit(POLY3) fit.set_data(xdata=frequency, ydata=power, xerrors=error_frequency, yerrors=error_power) fit.set_params(a0=380, a1=0.005, a2=-7e-8) fit.set_labels(xlabel="Frequenz / Hz", ylabel="Leistung / mW") subfit = fit.filtered(np.logical_and(frequency < 20e3, frequency > 1e3)) subfit.iterative_fit(5) plt.clf() subfit.plot(box="br", units={ "a3": "mW/Hz^3", "a2": "mW/Hz^2", "a1": "mW/Hz", "a0": "mW" }) plt.savefig("out/qswitch_power_fit." + SAVETYPE) plt.clf() subfit.plot_residual(box="tr") plt.savefig("out/qswitch_power_residual." + SAVETYPE) plt.clf() time, voltage = _load_oscilloscope_csv("data/ALL0023/F0023CH2.CSV") time *= 1E6 time -= -935 plt.plot(time, voltage, ".", color="black") pause = np.logical_and(time > 300, time < 900) one_period = np.logical_and(time > 0, time < 1000) print(one_period, one_period.sum()) mean_voltage = ufloat(voltage[one_period].mean(), voltage[pause].std() / math.sqrt(one_period.sum())) peak_voltage = ufloat(voltage[one_period].max(), voltage[pause].std()) print("ErrorL:", voltage[pause].std()) print("Mean voltage:", mean_voltage, "V") print("Peak voltage:", peak_voltage, "V") frequency = 1.01798e3 # Hz mean_power = subfit.ueval(frequency) print("Mean power:", mean_power * 1000, "uW") peak_power = mean_power * peak_voltage / mean_voltage print("Peak power:", peak_power * 1000, "uW") plt.axhline(mean_voltage.n, color="red", linewidth=2) plt.axhline(peak_voltage.n, color="red", linewidth=2) plt.xlabel("Zeit / us") plt.ylabel("Spannung / V") plt.savefig("out/qswitch_osci." + SAVETYPE)
def plot_ktp(): current, power, error_power = np.loadtxt("data/ktp_kristall.txt", unpack=True) error_current = 1 / math.sqrt(12) # uW -> mW power /= 1000 error_power /= 1000 plt.clf() plt.errorbar(current, power, xerr=error_current, yerr=error_power, fmt=',', color="black") plt.xlabel("Strom / mA") plt.ylabel("Leistung mit KTP / mW") plt.xlim(0, 700) plt.savefig("out/ktp_raw." + SAVETYPE) lower = np.logical_and(current > 182.10, current < 410) upper = current >= 410 diode_power, error_diode_power = current2diode_power( current, error_current) plt.clf() plt.errorbar(diode_power, power, xerr=error_diode_power, yerr=error_power, fmt=',', color="black") plt.xlabel("Diodenleistung / mW") plt.ylabel("Laserleistung mit KTP / mW") plt.savefig("out/ktp_raw2." + SAVETYPE) yag_power, error_yag_power = diode_power2yag_power(diode_power, error_diode_power) plt.clf() plt.errorbar(yag_power, power, xerr=error_yag_power, yerr=error_power, fmt=',', color="black") plt.xlabel("Laserleistung ohne KTP / mW") plt.ylabel("Laserleistung mit KTP / mW") plt.xlim(0, 10) plt.savefig("out/ktp_raw3." + SAVETYPE) plt.clf() fit = Fit(POLY2) fit.set_data(xdata=yag_power, ydata=power, xerrors=error_yag_power, yerrors=error_power) fit.set_labels(xlabel="Laserleistung ohne KTP / mW", ylabel="Laserleistung mit KTP / mW") fit = fit.filtered(yag_power > 2) fit.iterative_fit(5) fit.plot(box="tl", units={"a2": "1/mW", "a0": "mW"}) plt.savefig("out/ktp_fit." + SAVETYPE) plt.clf() fit.plot_residual(box="tl") plt.savefig("out/ktp_residual." + SAVETYPE)
def plot_yag_kennlinie(): current, power, error_power = np.loadtxt("data/kennlinie_yag2.txt", unpack=True) error_current = 1 / math.sqrt(12) plt.clf() plt.errorbar(current, power, xerr=error_current, yerr=error_power, fmt=',', color="black") plt.xlabel("Strom / mA") plt.ylabel("Leistung / mW") plt.xlim(0, 700) plt.savefig("out/kennlinie_yag_raw." + SAVETYPE) lower = np.logical_and(current > 182.10, current < 410) upper = current >= 410 fit_indices_list = [] fit_indices_list.append(power > 0.10) #fit_indices_list.append(np.logical_and(power > 0.10, lower)) #fit_indices_list.append(np.logical_and(power > 0.10, upper)) diode_power, error_diode_power = current2diode_power( current, error_current) zero_power = power[current < 150] background = zero_power.mean() print("Background:", background, "mW") power -= background plt.clf() plt.errorbar(diode_power, power, xerr=error_diode_power, yerr=error_power, fmt=',', color="black") plt.xlabel("Diodenleistung / mW") plt.ylabel("Laserleistung / mW") plt.savefig("out/kennlinie_yag_raw2." + SAVETYPE) func = lambda x, slope, threshold: (x - threshold) * slope fit = Fit(func) fit.set_params(slope=0.016, threshold=16) fit.set_data(xdata=diode_power, ydata=power, xerrors=error_diode_power, yerrors=error_power) fit.set_labels(xlabel="Diodenleistung / mW", ylabel="Laserleistung / mW") fit.iterative_fit(1) plt.clf() fit.plot(plot_data=True, plot_fit=True, box="tr") plt.savefig("out/kennlinie_yag_linear_fit." + SAVETYPE) plt.clf() fit.plot_residual(box="br", fmt="s") plt.savefig("out/kennlinie_yag_linear_residual." + SAVETYPE) fit = Fit(POLY2) fit.set_data(xdata=diode_power, ydata=power, xerrors=error_diode_power, yerrors=error_power) fit.set_labels(xlabel="Diodenleistung / mW", ylabel="Laserleistung / mW") fit.iterative_fit(5) for i, fit_indices in enumerate(fit_indices_list): plt.clf() fit.plot(plot_fit=False) subfit = fit[fit_indices] subfit.iterative_fit(5) #zero_power = power[power < 0.03] #zero = umean(zero_power) #plt.axhline(zero.n, color="blue") print(subfit) x = 200 try: i_threshold = solve_quadratic(subfit.uvalue("a0"), subfit.uvalue("a1"), subfit.uvalue("a2")) i_slope = 2 * x * subfit.uvalue("a2") + subfit.uvalue("a1") except ValueError: print("no solution", i) else: print("Threshold:", formatUFloat(i_threshold, unit="mW")) print("Efficiency:", formatUFloat(i_slope * 100, unit="%")) lines = "threshold = " + formatUFloat( i_threshold, unit="mW" ) + "\n" + "efficiency at %d mW = " % x + formatUFloat( i_slope * 100, unit="%") info_box(lines, location="tl") subfit.plot(plot_data=False) plt.savefig("out/kennlinie_yag_%d_fit." % i + SAVETYPE) plt.clf() subfit.plot_residual(box="br", color="black", fmt="s") plt.savefig("out/kennlinie_yag_%d_residual." % i + SAVETYPE) plt.clf() x = diode_power[diode_power > i_threshold.n] plt.plot(x, 100 * (2 * x * subfit.value("a2") + subfit.value("a1")), color="black") #x_new = diode_power - i_threshold.n #plt.plot(diode_power, 100*(x_new*subfit.value("a2") + subfit.value("a1") + subfit.value("a0")/x_new), color="red") plt.xlabel("Diodenleistung / mW") plt.ylabel("Effizienz / %") plt.savefig("out/kennlinie_yag_%d_efficiency." % i + SAVETYPE)