Beispiel #1
0
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))
Beispiel #2
0
    print(f"- T_plus_rechts={tools.ufloat_from_list(T_plus_rechts)}")
    # print(f"- T_std_rechts={np.std(T_plus_rechts)}")

    T_diff_lr = abs(
        tools.ufloat_from_list(T_plus_links) -
        tools.ufloat_from_list(T_plus_rechts))
    T_diff_lr_tolerance = min(np.std(T_plus_links), np.std(T_plus_rechts))
    print(f"Differenz der Schwingungsdauern links/rechts: {T_diff_lr}")
    # „Überprüfen Sie, daß die Schwingungsdauern T₁ und T₂ im Rahmen der Meßgenauigkeit übereinstimmen.“
    print(
        f"Toleranzgrenze dieser Differenz: {T_diff_lr_tolerance} (→ {'PASS' if T_diff_lr < T_diff_lr_tolerance else 'FAIL'})"
    )

    ω_plus_theo = ((ureg.gravity / l)**.5).to('rad/s')
    ω_plus_avg = (2 * np.pi * ureg.rad) / T_plus_avg
    print(tools.fmt_compare_to_ref(ω_plus_avg, ω_plus_theo, name='ω_plus'))

    print("\n→ Gegensinnige Schwingung")
    T_minus = get_T(i, 'gegensinnig') / 5  # 5 Perioden gemessen… Unschön…
    T_minus_avg = tools.ufloat_from_list(T_minus) * ureg('s')
    print(f"{T_minus_avg=}")

    # Kopplungskonstante
    K = (T_plus_avg**2 - T_minus_avg**2) / (T_plus_avg**2 + T_minus_avg**2)
    K *= ureg('m/s²')  # !?
    print(f"{K=}")

    ω_minus_theo = ((ureg.gravity / l + 2 * K / l)**.5).to('rad/s')
    ω_minus_avg = (2 * np.pi * ureg.rad) / T_minus_avg
    print(tools.fmt_compare_to_ref(ω_minus_avg, ω_minus_theo, name='ω_minus'))
Beispiel #3
0
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()
Beispiel #4
0
I_0 = u_I(2731)  # ohne Al-Absorper
I_1 = u_I(1180)  # mit Al-Absorber zwischen Röntgenröhre und Streuer
I_2 = u_I(1024)  # mit Al-Absorber zwischen Streuer und Geiger-Müller-Zählrohr
t = ureg('300 s')  # Integrationszeit

N_0 = I_0 / t  # ohne Al-Absorper
N_1 = I_1 / t  # mit Al-Absorber zwischen Röntgenröhre und Streuer
N_2 = I_2 / t  # mit Al-Absorber zwischen Streuer und Geiger-Müller-Zählrohr
print(f'{N_0=}', f'{N_1=}', f'{N_2=}', sep='\n')

max_N_possible = (1 / τ).to('Imp/s')
max_N_measured = max(N_0, N_1, N_2)
assert max_N_possible > max_N_measured * 1e3
print(
    '\n'
    f'größtmögliche Zählrate = 1/τ = {max_N_possible:.2f} ≫ {max_N_measured:.2f} = größte gemessene Zählrate'
)
print(f'→ um den Faktor {(max_N_possible / max_N_measured).m.n:.0f} größer!')

T_1 = N_1 / N_0  # Transmission der ungestreuten Röntgenstrahlung
T_2 = N_2 / N_0  # Transmission der gestreuten Röntgenstrahlung
print(f'T_1 = {T_1}', f'T_2 = {T_2}', sep='\n')
λ_1 = (T_1 - b) / a
λ_2 = (T_2 - b) / a
print(f'λ_1 = {λ_1:.2f}')
print(f'λ_2 = {λ_2:.2f}')
λ_C = λ_2 - λ_1  # Compton-Wellenlänge
λ_C_theo = 1 * ureg.h / (ureg.electron_mass * ureg.c)
print(tools.fmt_compare_to_ref(λ_C, λ_C_theo, 'λ_C', unit='pm'))
Beispiel #5
0
import uncertainties.unumpy as unp

import tools

θ, N = np.genfromtxt('data/EmissionCu.dat', unpack=True)
θ *= ureg.deg

peak_indices = find_peaks(N, height=1000)[0]
assert len(peak_indices) == 2

θ_Kβ, θ_Kα = θ[peak_indices]

θ_Kα_lit = ureg('22.323 °')
θ_Kβ_lit = ureg('20.217 °')

print(tools.fmt_compare_to_ref(θ_Kα, θ_Kα_lit, name='θ_Kα'))
print(tools.fmt_compare_to_ref(θ_Kβ, θ_Kβ_lit, name='θ_Kβ'))


def energie(θ):
    d = ureg('201.4 pm')  # Gitterebenenabstand
    return (ureg.h * ureg.c / (2 * d * np.sin(θ))).to('keV')


E_Kα, E_Kβ = energie(θ_Kα), energie(θ_Kβ)
assert E_Kα < E_Kβ

print(tools.fmt_compare_to_ref(E_Kα, energie(θ_Kα_lit), name='E_Kα'))
print(tools.fmt_compare_to_ref(E_Kβ, energie(θ_Kβ_lit), name='E_Kβ'))

plt.plot(θ, N, '-o', zorder=5, label='Messwerte')
Beispiel #6
0
I_list = []

for i, U_b in enumerate(U_b_list):
    print(f"→ U_b = {U_b}")
    I = np.genfromtxt(f'V502/data/{U_b.m}V.dat', unpack=True) * ureg.A
    I_list.append(I)
    result = analyze(I, U_b, i)
    actor_tuple_list.append(result[0])
    data_list.append(result[1])
    print()

e_div_m_list = tools.pintify([d[2] for d in data_list])
e_div_m_mean = np.mean(e_div_m_list)
print(
    tools.fmt_compare_to_ref(e_div_m_mean,
                             e_div_m_theo,
                             unit='C/kg',
                             name='e/m mean'))

plt.legend(actor_tuple_list, [f"$U_b = {U_b.m} V$" for U_b in U_b_list])
plt.xlabel(r"$B \mathbin{/} \si{\micro\tesla}$")
plt.ylabel(r"$\frac{D}{L²+D²} \mathbin{/} \si{\per\meter}$")
plt.grid()
# plt.show()
plt.tight_layout()
plt.savefig('build/plt/V502_1.pdf')

D_list = list(range(max([len(I) for I in I_list
                         ])))  # „Linien-Index“ auf dem Leuchtschirm
D_list *= ureg.inch / 4  # …umgerechnet in die Ablenkung

# generate_table('tab/V502_tab_a', [(U_b, a.to('1/m/T'), e_div_m.to('C/kg') / 1e11) for U_b, a, e_div_m in data_list], col_fmt=[{'d': 0}, {'d': 1}, {'d': 2}], headers=['U_b', 'a', 'e/m / 1e11'])
Beispiel #7
0
def analyze(T, manual_max_indices):
    print(f"→ {T=}")
    U_B, I_A = np.genfromtxt(
        f'build/dat/franck_hertz_{str(T).replace(".", "_")}.csv',
        comments='#',
        unpack=True,
        delimiter=',')
    U_B *= ureg.V  # Beschleunigungsspannung
    I_A *= ureg.nA

    # Achtung: distance/width werden in *samples* angegeben!
    # Damit ist keine weitere Generalisierung möglich.
    max_indices = find_peaks(I_A.m, height=1.5, width=1)[0]
    # max_indices = find_peaks(I_A.m, height=1.5, distance=15)[0]

    if manual_max_indices:
        max_indices = np.sort(
            np.unique(np.concatenate([max_indices, manual_max_indices])))

    print(f'{max_indices=}')
    print(
        f'Peaks: \n-U_B: {U_B[max_indices]:.3f}\n-I_A: {I_A[max_indices]:.3f}')

    # Abstand der relativen Maxima
    dif = np.diff(U_B[max_indices].to('V').m) * ureg.V
    dif_avg = tools.ufloat_from_list(dif.m) * ureg.V
    print(f'Abstände: {dif:.3f}', )
    print('mittlerer Abstand:', dif_avg)
    print(
        tools.fmt_compare_to_ref(dif_avg * ureg.e,
                                 ureg('4.9 eV'),
                                 unit='eV',
                                 name='→ Anregungsenergie'))
    λ = ureg.c * ureg.h / (dif_avg * ureg.e)
    print('λ =', λ.to('nm'))

    # Ohne Berücksichtigung des Kontaktpotentials würde man erwarten,
    # dass der mittlere Abstand gleich dem Abstand des ersten Maximums von der 0 ist –
    # schließlich müssten die Elektronen bei dif_avg gerade zum ersten Mal
    # eine ausreichende Beschleunigung erfahren haben, um ein Hg-Atom zu ionisieren.
    # Das tatsächliche Beschleunigungspotential (und somit die Energie des Elektrons)
    # ist wegen des Kontaktpotentials aber geringer.
    # Das verschiebt die Franck-Hertz-Kurve nach rechts,
    # was wir uns folgendermaßen zu Nutze machen können:
    print('1. Maximum: ', U_B[max_indices[0]])
    print('Kontaktpotential: ', U_B[max_indices[0]] - dif_avg)
    print(
        'Kontaktpotential (Modulo): ', U_B[max_indices[0]] % dif_avg
    )  # sinnvoll, wenn das wirklich erste Maximum (bei 4.9 V) nicht bestimmt werden konnte

    plt.figure(f'{T=}')
    plt.plot(U_B, I_A, 'x-', label='Messwerte')
    plt.plot(U_B[max_indices], I_A[max_indices], 'xr', label='Maxima')

    for i in max_indices:
        plt.axvline(U_B[i], color='grey', linestyle='--', alpha=0.5)
    for k in range(len(max_indices) - 1):
        i1 = max_indices[k]
        i2 = max_indices[k + 1]
        plt.arrow(*(U_B[i1], I_A[i2]), *(U_B[i2] - U_B[i1], 0))
        plt.annotate(f'{(U_B[i2] - U_B[i1]).to("V").m:.1f} V',
                     (U_B[i1], I_A[i2] + ureg('0.15 nA')))

    # plt.grid()
    plt.xlabel(r'$U_\text{A} \mathbin{/} \si{\volt}$')
    plt.ylabel(r'$I_\text{A}$')
    plt.yticks([])
    plt.legend()
    plt.tight_layout()
    plt.savefig(f'build/plt/franck_hertz_{str(T).replace(".", "_")}.pdf')
Beispiel #8
0
ureg.setup_matplotlib()
from scipy.signal import find_peaks, peak_widths
from uncertainties import ufloat
import uncertainties.unumpy as unp

import tools

θ, N = np.genfromtxt('data/Emissionsspektrum.dat', unpack=True)
θ *= ureg.deg

peak_indices, _ = find_peaks(N, height=1000)
assert len(peak_indices) == 2

peaks = θ[peak_indices]

print(tools.fmt_compare_to_ref(peaks[1], ureg('22.323 °'), name="θ_Kα"))
print(tools.fmt_compare_to_ref(peaks[0], ureg('20.217 °'), name="θ_Kβ"))
results_half = peak_widths(N, peak_indices, rel_height=0.5)

w_h, l, r = results_half[1:]
# TODO hard-coden ist doof :/
l = (l / 10 + 8) * ureg.deg
r = (r / 10 + 8) * ureg.deg

print(f"Halbwertsbreiten: {(r-l):.3f}°")


def energie(θ):
    d = ureg('201.4 pm')  # Gitterebenenabstand
    return (ureg.h * ureg.c / (2 * d * np.sin(θ.to('rad')))).to('keV')
Beispiel #9
0
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')
#TODO Theoriewert dazu plotten

plt.xlabel(r'$t \mathbin{/} \si{\micro\second}$')
plt.ylabel(r'$d \mathbin{/} \si{\milli\meter}$')
plt.legend()
plt.tight_layout()
plt.savefig('build/plt/schallgeschwindigkeit.pdf')
Beispiel #10
0
plt.tight_layout()
plt.savefig('build/plt/V501_1.pdf')

# generate_table('c_dings', list(zip(U_B_list.m, tools.pintify(a_list))))


print("\n\nApparaturkonstante:")
a_list_nominal = tools.nominal_values(tools.pintify(a_list))
m, n = tools.linregress(1 / U_B_list, a_list_nominal)

d = ureg('0.38 cm') # Abstand der Y-Ablenkplatten zueinander
p = ureg('1.9 cm') # Länge der Y-Ablenkplatten
L = ureg('1.03 cm') + ureg('14.3 cm') # Abstand *Beginn* der Y-Ablenkplatten → Leuchtschirm
m_theo = (p*L)/(2*d)

print(tools.fmt_compare_to_ref(m, m_theo, unit='mm', name='Apparaturkonstante'))

plt.figure()
plt.plot(1 / U_B_list.to('kV'), a_list_nominal, 'x', label='Werte') #label-Name lol
plt.plot(1 / U_B_list.to('kV'), tools.nominal_value(m)*(1 / U_B_list)+tools.nominal_value(n), '-', label='Regressionsgerade')
plt.grid()
plt.xlabel(r'$\sfrac{1}{U_\text{b}} \mathbin{/} \si{\per\kilo\volt}$')
plt.ylabel(r'$\sfrac{D}{U_\text{d}} \mathbin{/} \si{\centi\meter\per\volt}$')
# plt.legend() # hier vllt. wirklich keine Legende…
plt.tight_layout()
plt.savefig('build/plt/V501_2.pdf')

print("\n\nAmplitude:")
a = a_list[np.argwhere(U_B_list == ureg('420 V'))[0][0]]
print(f"{a=}")
D = 1/2 * ureg('1/4 inch') # Amplitude: eine halbe Skaleneinheit
Beispiel #11
0
import numpy as np
import pint
ureg = pint.UnitRegistry()
ureg.setup_matplotlib()
import tools

α, β = np.genfromtxt(f'data/Brechungsgesetz.csv',
                     comments='#',
                     delimiter=',',
                     unpack=True)
α *= ureg.deg  # Einfallswinkel
β *= ureg.deg  # Brechungswinkel

n = np.sin(α) / np.sin(β)
# n1 = 1.000292 # Brechungsindex Luft
# n2 = n1 * np.sin(α) / np.sin(β)
n_avg = tools.ufloat_from_list(n.m)
# print(f"Mittelwert n: {n_avg:.3f}")

n_lit = 1.489 * ureg.dimensionless
print(tools.fmt_compare_to_ref(n_avg, n_lit), 'Brechungsindex')

v = (ureg.c / n_avg).to('m/s')
# v = (ureg.c * np.sin(β) / np.sin(α)).to('m/s')
print(f"Lichtgeschwindigkeit in Plexiglas: {v}")
Beispiel #12
0
        θ_middle = θ[i_exact[0]]
    else:
        for i in range(len(N)):
            if N[i] < I_K and N[i + 1] > I_K:
                Δθ = θ[i + 1] - θ[i]
                ΔN = N[i + 1] - N[i]
                N_gerade = N[i] + ΔN * (θ - θ[i]) / Δθ
                θ_middle = (I_K - N[i]) * Δθ / ΔN + θ[i]
                break
    print(f"θ_middle = {θ_middle}")

    E = (ureg.h * ureg.c / (2 * d * np.sin(θ_middle.to('rad')))).to('keV')
    σ_K = calc_σ_K(E, Z)

    print(f"E = {E}")
    print(tools.fmt_compare_to_ref(σ_K, s_data['σ_K_lit'], name="σ_K"))

    ## Plots
    plt.figure()
    plt.plot(θ, N, 'x')
    plt.plot(θ[I_K_argmin],
             N[I_K_argmin],
             'xr',
             label=('rel. Minima' if len(I_K_argmin) > 1 else 'rel. Minimum'))
    plt.plot(θ[I_K_argmax],
             N[I_K_argmax],
             'xr',
             label=('rel. Maxima' if len(I_K_argmax) > 1 else 'rel. Maximum'))
    # plt.axvspan(*θ_bounds, alpha=0.25, label='Absorptionskante')
    if not i_exact:
        plt.plot(θ[i:i + 2], N[i:i + 2], color='gray')
Beispiel #13
0
        ax.set_ylim([-0.5, 0.5])

        # Für k=0 lässt sich keine Wellenlänge berechnen, daher `[k!=0]`.
        λ = d * np.sin(φ[k != 0]) / k[k != 0]
        λ_all[color] += list(λ)

        λ_mean = tools.ufloat_from_list(λ)

    ax.axvline(0, color='grey', zorder=0)
    ax.set_xlabel(r'$\varphi \mathbin{/} \si{\degree}$')
    ax.set_yticks([])
    # krasser One-Liner, um 0° im Plot zu zentrieren :P
    ax.set_xlim(*(np.array([-1, 1]) * abs(max(ax.get_xlim(), key=abs))))

plt.tight_layout()
plt.savefig(f'build/plt/beugung.pdf')
# plt.show()

λ_lit = {
    'red': ureg('635 nm'),
    'green': ureg('532 nm')
}  # siehe Versuchsanleitung und Versuchsaufbau

for color, λ in λ_all.items():
    λ = tools.pintify(λ)
    λ_all_mean = tools.ufloat_from_list(λ).to('nm')
    print(f"{color}:",
          tools.fmt_compare_to_ref(λ_all_mean, λ_lit[color]),
          '',
          sep='\n')