def analyze(I, U_b, i): B = (ureg.mu_0 * (8 / 125**.5) * (N / R) * I).to('µT') D = list(range(len(I))) # „Linien-Index“ auf dem Leuchtschirm D *= ureg.inch / 4 # …umgerechnet in die Ablenkung ding = D / (L**2 + D**2) a, b = tools.linregress(B, ding) print(f"a = {a.to('1/m/T'):.1f}") e_div_m = 8 * U_b * a**2 print( tools.fmt_compare_to_ref(e_div_m, e_div_m_theo, unit='C/kg', name='e/m')) plt_vals, = plt.plot(B, ding.to('1/m'), 'x', color=f"C{i}") plt_regress, = plt.plot(B, (tools.nominal_value(a) * B + tools.nominal_value(b)).to('1/m'), '-', color=f"C{i}") return ((plt_vals, plt_regress), (U_b, a, e_div_m))
ureg = pint.UnitRegistry() ureg.setup_matplotlib() import tools α1, α2 = np.genfromtxt(f'data/Reflexionsgesetz.csv', comments='#', unpack=True, delimiter=',') α1 *= ureg.deg # Einfallswinkel α2 *= ureg.deg # Reflexionswinkel Δα = abs(α1 - α2) print(f"Δα = {Δα}") print(f"Mittelwert Δα: {np.mean(Δα):.3f}") a, b = tools.linregress(α1, α2) print(f"{a, b=}") print(tools.fmt_compare_to_ref(a, 1, name='Geradensteigung a')) plt.plot(α1, α2, 'x', zorder=5, label='Messwerte') plt.plot(α1, tools.nominal_values(a * α1 + b), label='Regressionsgerade') plt.plot(α1, α1, color='black', label=r'$\alpha_1 = \alpha_2$') plt.xlabel(r'$\alpha_1 \mathbin{/} \si{\degree}$') plt.ylabel(r'$\alpha_2 \mathbin{/} \si{\degree}$') plt.xticks(α1) plt.yticks(α2) plt.grid() plt.legend() # plt.gca().set_aspect('equal') plt.tight_layout() plt.savefig('build/plt/reflexionsgesetz.pdf') # plt.show()
def I_totzeitkorrektur(N): return N / (1 - τ * N) # Gl. 4 in der Versuchsanleitung def calc_λ(θ): d = ureg('201.4 pm') # Gitterkonstante; laut Versuchsanleitung return 2 * d * np.sin(θ) # nach Bragg; n=1 λ = calc_λ(θ) I_0 = I_totzeitkorrektur(N_0) I_Al = I_totzeitkorrektur(N_Al) transmission = I_Al / I_0 transmission_no_TZK = N_Al / N_0 a, b = tools.linregress(λ, tools.nominal_values(transmission)) print(f"{a, b=}") tools.errorbar(plt, λ, transmission, fmt='.', zorder=5, label='Messwerte') # tools.errorbar(plt, λ, transmission_no_TZK, fmt='.', zorder=5, label='Messwerte ohne Totzeitkorrektur') plt.plot(λ, tools.nominal_values(a * λ + b), label='Regressionsgerade') plt.xlabel('$\lambda \mathbin{/} \si{\pico\meter}$') plt.ylabel('$T$') plt.legend() plt.tight_layout() plt.savefig('build/plt/transmission.pdf') # plt.show() print('\n' * 2 + '### Bestimmung der Compton-Wellenlänge' '\n') # Keine eigene Datei, weil wir gleich die Steigung der zuvor bestimmten Regerssionsgeraden nutzen werden
def fit_fn(t, U_0, RC): return U_0 * np.exp(-t / RC) t, U = np.genfromtxt('mess_1.dat', unpack=True) t *= ureg('ms') U *= ureg('V') U -= U[-1] # Das Minimum von U soll 0 sein. # Das macht aber Probleme beim Logarithmieren, # weshalb im Folgenden häufig mit `[:-1]` das letzte Wertepaar ignoriert wird. # Besser misst man U_0 vernünftig, um stets Werte >0 für U zu bekommen. ln_U = np.log(U.m[:-1]) a, b = tools.linregress(t[:-1], ln_U * ureg('dimensionless')) # Das Logarithmieren macht meine Pint-Zaubereien wertlos… :/ # Diese Einheiten müssen manuell überprüft werden. RC = (-1 / a).m * ureg('ms') print(f"{a=}, {b=}") print(f"{RC=}") plt.plot(t, U, 'x', label='Messwerte') plt.plot(t[:-1], np.exp(unp.nominal_values(a * t[:-1] + b)), label='Regressionsgerade') plt.yscale('log') plt.xlabel(r'$t \;/\; ms$') plt.ylabel(r'$\ln(U)$') plt.legend()
a *= ureg('mm') b *= ureg('mm') c *= ureg('mm') nr, t_a, t_b, A_a, A_b = np.genfromtxt('messwerte_ultraschall.dat', unpack=True) t_a *= ureg('µs') t_b *= ureg('µs') A_a *= ureg('V') A_b *= ureg('V') d = tools.pint_concat(a, b) * 2 # hin und zurück t = tools.pint_concat(t_a, t_b) d, t = tools.remove_nans(d, t) speed, achse = tools.linregress(t, d) print(f"{speed=}") print(f"{achse=}") print( tools.fmt_compare_to_ref(speed, ureg('2730 m/s'), 'Schallgeschwindigkeit in Acryl', unit=ureg('m/s'))) t_bounds = tools.bounds(t) plt.plot(t, d, '+', label='Messwerte') plt.plot(t_bounds, (achse.nominal_value * ureg('mm') + speed.nominal_value * ureg('mm/µs') * t_bounds).to('mm'), label='Fit')
print(f"→ {d['colorName']} ({d['λ']})") range = d['range'] # Daten einlesen U, I = np.genfromtxt(f"{d['color']}.dat", unpack=True) # Die Datendateien sind nicht sortiert, sondern geben unsere Messreihenfolge wieder. Das würde sonst stören. U, I = zip(*sorted(zip(U, I))) U = list(U) * ureg('V') I = list(I) * ureg('nA') # Wir betrachten nur den linearen Abschnitt. Und aus negativen Zahlen mag Python keine Wurzel ziehen. U_ranged = U[range[0]:range[1]] sqrt_I_ranged = I[range[0]:range[1]]**.5 a, b = tools.linregress(U_ranged, sqrt_I_ranged) print(f"a={a}") print(f"b={b}") d['a'] = a d['b'] = b #Grenzspannungen U_g = (-b / a).to('V') print("Nullstelle", U_g) d['U_g'] = U_g # Die Ausgleichgerade bzw. der Plot soll die Nullstelle immer einschließen # U_fit_point_upper = U_ranged[-1] if U_ranged[-1] > U_g else U_g U_fit_point_upper = max(U_g, U_ranged[-1]) U_fit_points = np.array( [U_ranged[0].to('V').m,
## Linearer Zusammenhang zwischen der Leuchtpunktverschiebung und Ablenkspannung plt.figure() a_list = [] actor_tuple_list = [] U_B_list = [200, 275, 350, 420, 500] * ureg.V for i, U_B in enumerate(U_B_list): D, U_d = np.genfromtxt(f'V501/data/{U_B.m}V.dat', unpack=True) U_d *= ureg.V D *= ureg.inch / 4 D, U_d = tools.remove_nans(D, U_d) a, b = tools.linregress(U_d, D) a_list.append(a.to('mm/V')) print(f"{a.to('mm/V')=}") plt_vals, = plt.plot(U_d, D.to('cm'), 'x', label='Messwerte', color=f"C{i}") plt_regress, = plt.plot(U_d, tools.nominal_value(a)*U_d+tools.nominal_value(b), '-', label='Regressionsgerade', color=f"C{i}") actor_tuple_list.append((plt_vals, plt_regress)) a_list = tools.pintify(a_list) plt.grid() plt.xlabel(r'$U_d \mathbin{/} \si{\volt}$') plt.ylabel(r'$D \mathbin{/} \si{\centi\meter}$') plt.yticks(list(range(0, 9)) * ureg.inch / 4) plt.legend(actor_tuple_list, [r'$U_\text{B} = \SI{' f'{U_B.m}' r'}{\volt}$' for U_B in U_B_list]) plt.tight_layout() plt.savefig('build/plt/V501_1.pdf')
N /= ureg('15 s') N -= NU_mean # Nulleffekt abziehen ln_N = unp.log(N.to('1/s').m) def fit_fn(t, N0, λ): return N0 * np.exp(-λ * t) t_end_fastdecay = ureg('240 s') t_bounds_slowdecay = (t_end_fastdecay, t[-1]) slope, intercept = tools.linregress( t[15:], unp.nominal_values(ln_N)[15:] * ureg.dimensionless) # keine Einheiten für y-Achse – ist ja logarithmisch! ln_N_lang_fit = slope * t + intercept N_lang_fit = np.exp(tools.nominal_values(ln_N_lang_fit)) * ureg('1/s') N_kurz = N - N_lang_fit ln_N_kurz = np.log( tools.nominal_values(N_kurz).m ) # TODO: Hier sollte sich – wie oben – mit unp der Fehler mitnehmen lassen slope2, intercept2 = tools.linregress( t[:15], unp.nominal_values(ln_N_kurz)[:15] * ureg.dimensionless) ln_N_kurz_fit = slope2 * t + intercept2
r'}} = \num{' + f"{d['σ_K'].m:.2f}" + '}$.', )) with open('build/auswertung_absorptionsspektren.tex', 'w') as f: f.write('\n\n'.join([fmt_single(name, d) for name, d in data.items()])) ## Bestimmung der Rydbergenergie ↓ E_list = tools.pintify([s['E'] for s in data.values()]) σ_K_list = tools.pintify([s['σ_K'] for s in data.values()]) σ_K_lit_list = np.array([s['σ_K_lit'] for s in data.values()]) z = np.array([s['Z'] for s in data.values()]) * ureg('dimensionless') sqrt_E_list = (E_list**.5).to('eV**0.5') a, b = tools.linregress(z, sqrt_E_list) plt.figure() plt.plot(z, sqrt_E_list, 'x', label='Daten') plt.plot(z, tools.nominal_values(a * z + b), label='Regressionsgerade') plt.grid() plt.xlabel(r'$Z$') plt.ylabel(r'$\sqrt{E_K} \mathbin{/} \si{\sqrt{\electronvolt}}$') print(f'Regressionsparameter a = {a}') print(f'Regressionsparameter b = {b}') R_energie = a**2 R = R_energie / ureg.h print(