"""
plot.py -- erzeugt aus messwerte.csv:
  * plot.pdf      Bode-Diagramm (Betrag und Phase)
  * tabelle.tex   LaTeX-Tabelle der Messpunkte
  * werte.tex     LaTeX-Makros: \\omegaKtheorie, \\omegaKmess, \\abweichung

Idee: messwerte.csv ist die EINZIGE Quelle der Wahrheit. paper.tex
enthaelt keine Messzahlen mehr. CSV aendern, plot.py laufen lassen,
paper.tex neu kompilieren -- alles bleibt konsistent.
"""

import numpy as np
import matplotlib.pyplot as plt

# 1) CSV einlesen ------------------------------------------------------
# 3 Spalten: omega_rad_s, betrag_dB, phase_grad (erste Zeile = Ueberschrift)
daten = np.loadtxt("messwerte.csv", delimiter=",", skiprows=1)
omega   = daten[:, 0]    # Kreisfrequenz in rad/s
betrag  = daten[:, 1]    # Amplitudengang in dB
phase   = daten[:, 2]    # Phasengang in Grad

# 2) Theoretische Knickfrequenz (aus Identifikation der Strecke) -------
# PT2-Modell der Drehzahl-Strecke: omega_n = 56 rad/s
omega_K_theor = 56                          # Knickfrequenz lt. Modell
K_s_dB = betrag[0]                          # DC-Verstaerkung (tiefste Frequenz)

# 3) Gemessene Knickfrequenz: dort wo der Betrag um 3 dB faellt --------
ziel_dB = K_s_dB - 3
# np.interp braucht aufsteigende x-Werte; betrag faellt mit omega -> umdrehen:
omega_K_mess = np.interp(ziel_dB, np.flip(betrag), np.flip(omega))
abweichung = abs(omega_K_mess - omega_K_theor) / omega_K_theor * 100

# 4) Bode-Diagramm zeichnen (zwei Subplots: Betrag + Phase) ------------
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(5, 4), sharex=True)
ax1.semilogx(omega, betrag, "o-")
ax1.axhline(ziel_dB, linestyle=":", color="gray",
            label=f"$K_s - 3$ dB = {ziel_dB:.2f} dB")
ax1.axvline(omega_K_theor, linestyle="--", color="gray",
            label=f"$\\omega_K$ theor. = {omega_K_theor} rad/s")
ax1.set_ylabel("Betrag in dB")
ax1.legend(loc="lower left", fontsize=8)
ax1.grid(True, which="both", alpha=0.3)

ax2.semilogx(omega, phase, "o-")
ax2.set_xlabel("Kreisfrequenz $\\omega$ in rad/s")
ax2.set_ylabel("Phase in Grad")
ax2.grid(True, which="both", alpha=0.3)

fig.tight_layout()
fig.savefig("plot.pdf")

# 5) Hilfsfunktion: Zahl mit deutschem Komma ---------------------------
def deutsch(zahl, nachkommastellen=2):
    """1.59 -> '1{,}59' (LaTeX-tauglich, deutsches Komma)."""
    text = f"{zahl:.{nachkommastellen}f}"
    return text.replace(".", "{,}")

# 6) Tabelle als LaTeX-Code schreiben ----------------------------------
zeilen = [
    r"\begin{tabular}{rrr}",
    r"\toprule",
    r"$\omega$ (rad/s) & Betrag (dB) & Phase ($^\circ$) \\",
    r"\midrule",
]
for i in range(len(omega)):
    zeilen.append(f"{omega[i]:g} & {deutsch(betrag[i])} & {deutsch(phase[i], 1)} \\\\")
zeilen.append(r"\bottomrule")
zeilen.append(r"\end{tabular}")

with open("tabelle.tex", "w", encoding="utf-8") as datei:
    datei.write("\n".join(zeilen) + "\n")

# 7) Werte als LaTeX-Makros schreiben ----------------------------------
with open("werte.tex", "w", encoding="utf-8") as datei:
    datei.write(r"\newcommand{\omegaKtheorie}{" + deutsch(omega_K_theor, 0) + "}\n")
    datei.write(r"\newcommand{\omegaKmess}{"    + deutsch(omega_K_mess, 1) + "}\n")
    datei.write(r"\newcommand{\abweichung}{"    + deutsch(abweichung, 1)   + "}\n")

print("Fertig: plot.pdf, tabelle.tex, werte.tex")
print(f"  theoretisch: omega_K = {omega_K_theor} rad/s")
print(f"  gemessen:    omega_K = {omega_K_mess:.2f} rad/s")
print(f"  Abweichung:  {abweichung:.1f} %")
