Calc done

This commit is contained in:
Sally Marcher 2025-11-19 18:10:49 +01:00
parent bfc29d426d
commit aa025c38b4
5 changed files with 406 additions and 11 deletions

BIN
res/graphs/3D_4.1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
res/graphs/3D_4.4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

94
res/graphs/3d.py Normal file
View file

@ -0,0 +1,94 @@
from saplotlib import match_t, eval_uncert, symbolize, plot_dataset_v2, format_uncert, latex_table_from_lists
import numpy as np
from sympy import *
import sympy as sp
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import pyperclip
clip = ""
# Versuch 1
# 1. Polarisator auf 0°
# RS pro RS-12 DMM - range 200mV
# maximum: ~138 => 185.5mV
def calc_dphi(phi):
return 1 # +- kleinste einheit / 2
def calc_dU(U):
return 0.1 * U + 0.2 # 200mV Range [Res 0.1mV] +- 0.5% (10%!) + 2 digits
# (winkel, spannung [mV])
data_1 = [(0, 46.7), (10, 22.9), (20, 4.8), (30, 1), (40, 8.9), (50, 30.5), (60, 57.5), (70, 85.9), (80, 132.4), (90, 160), (100, 176.1), (110, 192), (120, 193.4), (130, 173.1), (140, 190.3), (150, 146), (160, 118.8), (170, 80), (180, 51), (190, 22.5), (200, 6.6), (210, 0.8), (220, 7.9), (230, 29.8), (240, 63.5), (250, 98.8), (260, 128.8), (270, 161.7), (280, 171.2), (290, 182.3), (300, 199.5), (310, 191.6), (320, 169.4), (330, 158.3), (340, 119.7), (350, 73.9)]
clip += "% Versuch 4.1 Werte Tabelle:\n"
clip += latex_table_from_lists([[i[0] for i in data_1], [i[1] for i in data_1]], ["Winkel $\\phi$ / °", "Spannung $U$ / mV"], [calc_dphi, calc_dU]) + "\n\n"
def I(_tex_phi, I_0, _tex_Delta_tex_phi):
return I_0 * cos(_tex_phi + _tex_Delta_tex_phi) ** 2
p = np.array([i[0] * (np.pi / 180) for i in data_1])
U = np.array([i[1] * (np.pi / 180) for i in data_1])
plt.polar()
popt, perr = plot_dataset_v2(p, U, calc_dphi(p) * (np.pi / 180), calc_dU(U), I, "Messdaten", normalize=1)
d_p = (popt[1] % np.pi) * (180/np.pi)
dd_p = perr[1] * (180/np.pi)
print(f"Verkippungswinkel der beiden Polarisatoren zueinander (delta phi): {format_uncert(d_p, dd_p)}°")
plt.xlabel("$\\phi$ / °")
plt.yticks([0.25, 0.5, 0.75, 1])
plt.legend()
plt.savefig('3D_4.1.png')
plt.cla()
# Versuch 2
# -> Polarisatoren sind normal zueinander
# Pol1: 0°; Pol2: 218°
# Spannung 1.4mV
# => Zucker Lösung in den Weg stellen, dann
# > 47mV
# Nomral stellen: 240°; 0.6mV
pol_o = np.array([210, 209, 209, 209, 210]) # Ohne Zucker
pol_m = np.array([238, 240, 238, 239, 239]) # Mit Zucker
clip += "% Versuch 4.2 Werte Tabelle:\n"
clip += latex_table_from_lists([pol_o, pol_m], ["Winkel $\\phi_o$ / °", "Winkel $\\phi_m$ / °"], [calc_dphi, calc_dphi]) + "\n\n"
phi = np.mean(pol_m) - np.mean(pol_o)
d_phi = 1
phi_0 = 6.65
l = 18.5 # [cm] +- 0.1cm
dl = 0.1
c = (phi / (phi_0 * l)) * 100
dc = (1 / (phi_0 * l) * d_phi + dl * phi / (phi_0 * (l ** 2))) * 100
print(f"Länge l {format_uncert(l, dl)}cm")
print(f"Konzentration: {format_uncert(c, dc)}%")
# Versuch 4
# Polarisator 1: 0°
# Polarisator 2: 28° => dann 0 transmission
# (winkel, spannung [mV])
data_2 = [(0, 0.5), (10, 3.6), (20, 16.1), (30, 37.7), (40, 66.8), (50, 97.2), (60, 128.9), (70, 152), (80, 152.6), (90, 151.7), (100, 139.9), (110, 137.9), (120, 128.8), (130, 109.2), (140, 81.1), (150, 52.1), (160, 25.9), (170, 8.4), (180, 0.8), (190, 3.2), (200, 14.9), (210, 34.5), (220, 65.4), (230, 97.2), (240, 119.1), (250, 153.6), (260, 162.4), (270, 153.2), (280, 154.2), (290, 154.2), (300, 140.8), (310, 123.5), (320, 92.6), (330, 57.3), (340, 28.2), (350, 7.7)]
clip += "% Versuch 4.4 Werte Tabelle:\n"
clip += latex_table_from_lists([[i[0] for i in data_2], [i[1] for i in data_2]], ["Winkel $\\phi$ / °", "Spannung $U$ / mV"], [calc_dphi, calc_dU]) + "\n\n"
p = np.array([i[0] * (np.pi / 180) for i in data_2])
U = np.array([i[1] for i in data_2])
plt.polar()
popt, perr = plot_dataset_v2(p, U, calc_dphi(p) * (np.pi / 180), calc_dU(U), I, "Messdaten", normalize=1)
plt.xlabel("$\\phi$ / °")
plt.gca().set_theta_zero_location("N")
plt.yticks([0.25, 0.5, 0.75, 1])
plt.legend()
plt.savefig('3D_4.4.png')
plt.cla()
d_p = (popt[1] % np.pi) * (180/np.pi)
dd_p = perr[1] * (180/np.pi)
print(f"delta phi Brille: {format_uncert(d_p, dd_p)}°")
pyperclip.copy(clip)

180
res/graphs/out.txt Normal file
View file

@ -0,0 +1,180 @@
% Versuch 4.1 Werte Tabelle:
\begin{tabular}{|c||c|}
\hline
Winkel $\phi$ / ° ($\pm 1.0$) & Spannung $U$ / mV \\
\hline
$0.0$ & $47\pm5$ \\
\hline
$10.0$ & $23\pm3$ \\
\hline
$20.0$ & $4.8\pm0.7$ \\
\hline
$30.0$ & $1.0\pm0.4$ \\
\hline
$40.0$ & $8.9\pm1.1$ \\
\hline
$50.0$ & $30\pm4$ \\
\hline
$60.0$ & $58\pm6$ \\
\hline
$70.0$ & $86\pm9$ \\
\hline
$80.0$ & $132\pm14$ \\
\hline
$90.0$ & $160\pm17$ \\
\hline
$100.0$ & $176\pm18$ \\
\hline
$110.0$ & $192\pm20$ \\
\hline
$120.0$ & $193\pm20$ \\
\hline
$130.0$ & $173\pm18$ \\
\hline
$140.0$ & $190\pm20$ \\
\hline
$150.0$ & $146\pm15$ \\
\hline
$160.0$ & $119\pm13$ \\
\hline
$170.0$ & $80\pm9$ \\
\hline
$180.0$ & $51\pm6$ \\
\hline
$190.0$ & $22\pm3$ \\
\hline
$200.0$ & $6.6\pm0.9$ \\
\hline
$210.0$ & $0.8\pm0.3$ \\
\hline
$220.0$ & $7.9\pm1.0$ \\
\hline
$230.0$ & $30\pm4$ \\
\hline
$240.0$ & $64\pm7$ \\
\hline
$250.0$ & $99\pm11$ \\
\hline
$260.0$ & $129\pm14$ \\
\hline
$270.0$ & $162\pm17$ \\
\hline
$280.0$ & $171\pm18$ \\
\hline
$290.0$ & $182\pm19$ \\
\hline
$300.0$ & $200\pm30$ \\
\hline
$310.0$ & $192\pm20$ \\
\hline
$320.0$ & $169\pm18$ \\
\hline
$330.0$ & $158\pm17$ \\
\hline
$340.0$ & $120\pm13$ \\
\hline
$350.0$ & $74\pm8$ \\
\hline
\end{tabular}
% Versuch 4.2 Werte Tabelle:
\begin{tabular}{|c||c|}
\hline
Winkel $\phi_o$ / ° ($\pm 1.0$) & Winkel $\phi_m$ / ° ($\pm 1.0$) \\
\hline
$210.0$ & $238.0$ \\
\hline
$209.0$ & $240.0$ \\
\hline
$209.0$ & $238.0$ \\
\hline
$209.0$ & $239.0$ \\
\hline
$210.0$ & $239.0$ \\
\hline
\end{tabular}
% Versuch 4.4 Werte Tabelle:
\begin{tabular}{|c||c|}
\hline
Winkel $\phi$ / ° ($\pm 1.0$) & Spannung $U$ / mV \\
\hline
$0.0$ & $0.5\pm0.3$ \\
\hline
$10.0$ & $3.6\pm0.6$ \\
\hline
$20.0$ & $16.1\pm1.9$ \\
\hline
$30.0$ & $38\pm4$ \\
\hline
$40.0$ & $67\pm7$ \\
\hline
$50.0$ & $97\pm10$ \\
\hline
$60.0$ & $129\pm14$ \\
\hline
$70.0$ & $152\pm16$ \\
\hline
$80.0$ & $153\pm16$ \\
\hline
$90.0$ & $152\pm16$ \\
\hline
$100.0$ & $140\pm15$ \\
\hline
$110.0$ & $138\pm14$ \\
\hline
$120.0$ & $129\pm14$ \\
\hline
$130.0$ & $109\pm12$ \\
\hline
$140.0$ & $81\pm9$ \\
\hline
$150.0$ & $52\pm6$ \\
\hline
$160.0$ & $26\pm3$ \\
\hline
$170.0$ & $8.4\pm1.1$ \\
\hline
$180.0$ & $0.8\pm0.3$ \\
\hline
$190.0$ & $3.2\pm0.6$ \\
\hline
$200.0$ & $14.9\pm1.7$ \\
\hline
$210.0$ & $34\pm4$ \\
\hline
$220.0$ & $65\pm7$ \\
\hline
$230.0$ & $97\pm10$ \\
\hline
$240.0$ & $119\pm13$ \\
\hline
$250.0$ & $154\pm16$ \\
\hline
$260.0$ & $162\pm17$ \\
\hline
$270.0$ & $153\pm16$ \\
\hline
$280.0$ & $154\pm16$ \\
\hline
$290.0$ & $154\pm16$ \\
\hline
$300.0$ & $141\pm15$ \\
\hline
$310.0$ & $124\pm13$ \\
\hline
$320.0$ & $93\pm10$ \\
\hline
$330.0$ & $57\pm6$ \\
\hline
$340.0$ & $28\pm4$ \\
\hline
$350.0$ & $7.7\pm1.0$ \\
\hline
\end{tabular}
Verkippungswinkel der beiden Polarisatoren zueinander (delta phi): (61.5 ± 0.5)°
Länge l (18.50 ± 0.10)cm
Konzentration: (23.9 ± 1.0)%
delta phi Brille: (87.4 ± 0.8)°

View file

@ -2,6 +2,7 @@ import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from sympy import *
import math
plt.rcParams['text.usetex'] = True
@ -30,6 +31,30 @@ def match_t(arr, sigma_mult):
print(f"Matched Student t multiplier: {t}! Using {sigma_mult} Sigma width!")
return t
def format_uncert(val, err, p=False):
if err == 0:
return f"{val}"
exponent = math.floor(math.log10(abs(err)))
first_digit = int(abs(err) / (10**exponent))
sig = 2 if first_digit == 1 else 1
factor = 10**(exponent - sig + 1)
rounded_err = math.ceil(abs(err) / factor) * factor
rounded_val = round(val, -(exponent - sig + 1))
decimals = max(0, -(exponent - sig + 1))
val_str = f"{rounded_val:.{decimals}f}"
err_str = f"{rounded_err:.{decimals}f}"
if p:
return f"{val_str};{err_str}"
return f"({val_str} ± {err_str})"
def symbolize(func):
"""
Arguments:
@ -39,6 +64,9 @@ def symbolize(func):
"""
return func(*[Symbol(label) for label in func.__code__.co_varnames])
def symbolize_tex(func):
return func(*[Symbol(label.replace("_tex_", "\\")) for label in func.__code__.co_varnames])
def conv_to_f_args(args):
f_args = {}
for key in args.keys():
@ -68,18 +96,111 @@ def eval_uncert(f, args, typ="B"):
result = symf.evalf(subs=f_args)
return result, uncert
def plot_dataset(x, y, xerr, yerr, func, label, n=100, log=0):
symfunc = symbolize(func)
def plot_dataset(x, y, xerr, yerr, func, label, n=100, log=0, fit_range=(0, None), plot_fit_range=None):
if str(type(func)) != "<class 'NoneType'>":
symfunc = symbolize(func)
plt.errorbar(x, y, yerr=yerr, xerr=xerr, marker="o", ls="", capsize=5, label=label)
if log:
fitx = np.logspace(min(x), max(x), n)
else:
fitx = np.linspace(min(x), max(x), n)
symbols = func.__code__.co_varnames
npfunc = lambdify(symbols, symfunc, "numpy")
popt, pcov = curve_fit(npfunc, x, y)
plt.plot(fitx, npfunc(fitx, *popt), label="Fit: $"+latex(symfunc)+"$")
print(f"Optimized {symbols[1:]} with values {popt}")
if str(type(func)) != "<class 'NoneType'>":
if log:
if plot_fit_range:
fitx = np.logspace(plot_fit_range[0], plot_fit_range[1], n)
else:
fitx = np.logspace(min(x[fit_range[0]:fit_range[1]]), max(x[fit_range[0]:fit_range[1]]), n)
else:
if plot_fit_range:
fitx = np.linspace(plot_fit_range[0], plot_fit_range[1], n)
else:
fitx = np.linspace(min(x[fit_range[0]:fit_range[1]]), max(x[fit_range[0]:fit_range[1]]), n)
symbols = func.__code__.co_varnames
npfunc = lambdify(symbols, symfunc, "numpy")
popt, pcov = curve_fit(npfunc, x[fit_range[0]:fit_range[1]], y[fit_range[0]:fit_range[1]])
plt.plot(fitx, npfunc(fitx, *popt), label="Fit: $"+latex(symfunc)+"$")
print(f"Optimized {symbols[1:]} with values {popt}")
return popt
def plot_dataset_v2(x, y, xerr, yerr, func, label, *, n: int = 100, log: int = 0, fit_range: tuple = (0, None), plot_fit_range=None, normalize: int = 0):
if str(type(func)) != "<class 'NoneType'>":
symfunc = symbolize(func)
if normalize == 0:
plt.errorbar(x, y, yerr=yerr, xerr=xerr, marker="o", ls="", capsize=5, label=label)
if str(type(func)) != "<class 'NoneType'>":
if log:
if plot_fit_range:
fitx = np.logspace(plot_fit_range[0], plot_fit_range[1], n)
else:
fitx = np.logspace(min(x[fit_range[0]:fit_range[1]]), max(x[fit_range[0]:fit_range[1]]), n)
else:
if plot_fit_range:
fitx = np.linspace(plot_fit_range[0], plot_fit_range[1], n)
else:
fitx = np.linspace(min(x[fit_range[0]:fit_range[1]]), max(x[fit_range[0]:fit_range[1]]), n)
symbols = func.__code__.co_varnames
npfunc = lambdify(symbols, symfunc, "numpy")
popt, pcov = curve_fit(npfunc, x[fit_range[0]:fit_range[1]], y[fit_range[0]:fit_range[1]])
I_0 = 1
if normalize:
try:
I_0 = popt[func.__code__.co_varnames.index("I_0")-1]
plt.errorbar(x, [i/I_0 for i in y], yerr=[i/I_0 for i in yerr], xerr=xerr, marker="o", ls="", capsize=5, label=label)
except ValueError:
plt.errorbar(x, y, yerr=yerr, xerr=xerr, marker="o", ls="", capsize=5, label=label)
symfunc = symbolize_tex(func)
plt.plot(fitx, [i/I_0 for i in npfunc(fitx, *popt)], label="Fit: $"+latex(symfunc)+"$")
#print(f"Optimized {symbols[1:]} with values {popt}")
perr = np.sqrt(np.diag(pcov))
return popt, perr
def latex_table_from_lists(
data_lists,
column_names=None,
uncertainty_func=None,
):
n_cols = len(data_lists)
n_rows = len(data_lists[0])
common_uncertainties=[]
for i in range(0, n_cols):
uncertainties = [format_uncert(v, uncertainty_func[i](v), True).split(";")[1] for v in data_lists[i]]
if all(u == uncertainties[0] for u in uncertainties):
common_uncertainties.append(uncertainties[0])
else:
common_uncertainties.append(None)
header = []
for i in range(n_cols):
if common_uncertainties and common_uncertainties[i] is not None:
header.append(f"{column_names[i]} ($\\pm {common_uncertainties[i]}$)")
else:
header.append(column_names[i])
rows = []
for row_idx in range(n_rows):
row_entries = []
for col_idx in range(n_cols):
value = data_lists[col_idx][row_idx]
u = uncertainty_func[col_idx](value)
if common_uncertainties[col_idx]:
entry = "$"+format_uncert(value, u, True).split(";")[0]+"$"
else:
entry = "$"+format_uncert(value, u, True).replace(";", "\\pm")+"$"
row_entries.append(entry)
rows.append(" & ".join(row_entries) + " \\\\")
latex = "\\begin{tabular}{" + "|c|" * n_cols + "}\n"
latex += "\\hline\n"
latex += " & ".join(header) + " \\\\\n"
latex += "\\hline\n"
latex += "\n\\hline\n".join(rows) + "\n"
latex += "\\hline\n"
latex += "\\end{tabular}"
return latex
"""
Sources: