Push 03.02.2026

This commit is contained in:
2026-02-03 18:31:48 +01:00
parent 4e7c55500b
commit 5842255a6a
4 changed files with 17997 additions and 76246 deletions

File diff suppressed because one or more lines are too long

View File

@@ -710,6 +710,25 @@ class Datenbankzugriff:
liste_instrumente = f"Kein Instrument vom Typ {typ} gefunden. Folgende Typen stehen aktuell zur Auswahl: {liste_typen}" liste_instrumente = f"Kein Instrument vom Typ {typ} gefunden. Folgende Typen stehen aktuell zur Auswahl: {liste_typen}"
return liste_instrumente return liste_instrumente
def get_alle_instrumente_liste(self: str) -> list:
"""Liest alle Instrumente aus der Tabelle Instrumente.
Gibt eine Liste der gefundenen Instrumente zurück. Falls keine Instrumente vorhanden sind,
wird eine Textausgabe mit verfügbaren Typen zurückgegeben.
:return: Liste der Instrumente oder Hinweistext, falls keine Instrumente gefunden wurden.
:rtype: list | str
"""
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
liste_instrumente = cursor.execute("SELECT * FROM Instrumente").fetchall()
liste_typen = cursor.execute("SELECT DISTINCT typ FROM Instrumente").fetchall()
cursor.close()
con.close()
if liste_instrumente == []:
liste_instrumente = f"Kein Instrumente gefunden. Bitte in der Folgenden Zelle anlegen."
return liste_instrumente
def get_genauigkeiten_dict(self) -> dict[Any, Any]: def get_genauigkeiten_dict(self) -> dict[Any, Any]:
"""Liest alle Genauigkeiten aus der Tabelle Genauigkeiten und gibt diese als Dictionary zurück. """Liest alle Genauigkeiten aus der Tabelle Genauigkeiten und gibt diese als Dictionary zurück.

View File

@@ -3,6 +3,20 @@ from Netzqualität_Genauigkeit import Genauigkeitsmaße
from Datumsfestlegung import Datumsfestlegung from Datumsfestlegung import Datumsfestlegung
import numpy as np import numpy as np
import Export import Export
import importlib
import Datenbank
import importlib
import Export
from Export import Export as Exporter
import Stochastisches_Modell
import Funktionales_Modell
import Koordinatentransformationen
import Parameterschaetzung
import Netzqualität_Genauigkeit
import Datumsfestlegung
import numpy as np
import sympy as sp
import pandas as pd
def ausgleichung_global(A, dl, Q_ext, P): def ausgleichung_global(A, dl, Q_ext, P):
@@ -265,3 +279,286 @@ def ausgleichung_spurminimierung(A, dl, Q_ll, *, datumfestlegung, x0, unbekannte
} }
return dict_ausgleichung, dx return dict_ausgleichung, dx
class Iterationen:
"""Iterative Ausgleichung auf Basis des funktionalen und stochastischen Modells.
Die Klasse führt eine iterative Parameterschätzung nach dem Gauss-Markov-Modell durch. Zudem stellt Sie eine Methode zur Verfügung für:
- einmaligen Aufbau der symbolischen Matrizen/Vektoren (Jacobi-Matrix, Näherungs-Beobachtungsvektor, Qll, QAA, Unbekanntenvektor),
- numerische Auswertung je Iteration (A(x_k), l0(x_k), dl_k) und Berechnung des Vektors dx,
- Fortschreibung des Unbekanntenvektors x_{k+1} = x_k + dx,
- Abbruchprüfung über Konvergenzkriterium (max|dx_xyz|) und Stagnation,
- optionaler Export von Zwischenergebnisse als CSV in den Ordner Zwischenergebnisse.
Die Iteration verwendet bei weicher Lagerung eine erweiterte Kovarianzmatrix (Q_ext) inklusive Anschlusspunkten (lA_*),
aus der die Gewichtsmatrix P abgeleitet wird.
"""
def __init__(self, pfad_datenbank: str, pfad_tif_quasigeoidundolation: str, a: float, b: float) -> None:
"""Initialisiert die Iterationssteuerung.
Speichert Datenbankpfade und Ellipsoidparameter, initialisiert das funktionale Modell sowie das stochastische Modell
und legt den Datenbankzugriff an.
:param pfad_datenbank: Pfad zur SQLite-Datenbank.
:type pfad_datenbank: str
:param pfad_tif_quasigeoidundolation: Pfad zum GeoTIFF der Quasigeoidundulation (BKG), benötigt für UTM/Normalhöhen in Transformationen.
:type pfad_tif_quasigeoidundolation: str
:param a: Große Halbachse a des Referenzellipsoids in Meter.
:type a: float
:param b: Kleine Halbachse b des Referenzellipsoids in Meter.
:type b: float
:return: None
:rtype: None
"""
self.pfad_datenbank = pfad_datenbank
self.pfad_tif_quasigeoidundolation = pfad_tif_quasigeoidundolation
self.a = a
self.b = b
self.stoch_modell = Stochastisches_Modell.StochastischesModell(pfad_datenbank)
self.db_zugriff = Datenbank.Datenbankzugriff(pfad_datenbank)
self.fm = Funktionales_Modell.FunktionalesModell(self.pfad_datenbank, self.a, self.b, self.pfad_tif_quasigeoidundolation)
def iterationen(self, datumfestlegung: str, speichern_in_csv: bool) -> tuple[np.ndarray, list, list, np.ndarray, np.ndarray, np.ndarray, dict]:
"""Führt die iterative Ausgleichung (Parameterschätzung) aus und gibt die Ergebnisse zurück.
Ablauf (vereinfacht):
1) Symbolische Initialisierung (einmalig):
- Jacobi-Matrix_symbolisch inkl. Unbekanntenliste und Beobachtungskennungen,
- l0_symbolisch (Näherungs-Beobachtungsvektor),
- Qll_symbolisch (Beobachtungen) und ggf. QAA_symbolisch (Anschlusspunkte lA_*),
- Unbekanntenvektor_symbolisch.
2) Numerische Initialisierung (einmalig):
- numerischer Beobachtungsvektor l aus Datenbank/Substitutionen,
- Qll_numerisch (und ggf. QAA_numerisch) sowie Aufbau von Q_ext und P bei weicher Lagerung.
3) Iterationsschleife (k = 0..max_iter-1):
- Jacobi-Matrix(x_k) numerisch aus Jacobi-Matrix_symbolisch,
- l0(x_k) numerisch aus l0_symbolisch,
- dl_k = l l0(x_k) (inkl. Normierung der Richtungen),
- Parameterschätzung -> dx_k,
- Fortschreibung x_{k+1} = x_k + dx_k,
- Abbruch bei Konvergenz (max|dx_xyz| < tol) oder Stagnation.
Optional werden ausgewählte Matrizen/Vektoren als CSV-Datei exportiert.
:param datumfestlegung: Art der Datumsfestlegung. In der aktuellen Implementierung wird "weiche Lagerung" erwartet,
da Q_ext und P sonst nicht aufgebaut werden.
:type datumfestlegung: str
:param speichern_in_csv: Steuert den Export von Zwischenergebnissen als CSV-Datei in den Ordner Zwischenergebnisse.
:type speichern_in_csv: bool
:return: Tupel mit (Jacobi-Matrix_matrix_numerisch, liste_unbekannte, liste_beobachtungen, x, dx, dl, ausgabe_parameterschaetzung).
Dabei ist x der numerische Unbekanntenvektor der letzten Iteration, dx die letzte Korrektur, dl der letzte
Verbesserungsvektor und ausgabe_parameterschaetzung ein Dictionary der globalen Ausgleichungs-Ausgabe.
:rtype: tuple[np.ndarray, list, list, np.ndarray, np.ndarray, np.ndarray, dict]
"""
# Symbolische Matrizen vor Ausführung der ersten Iteration aufstellen
# Symbolische Jacobimatrix aufstellen
Jacobimatrix_symbolisch, Jacobimatrix_symbolisch_liste_unbekannte, Jacobimatrix_symbolisch_liste_beobachtungsvektor = self.fm.jacobi_matrix_symbolisch(
datumfestlegung, self.db_zugriff.get_datumskoordinate())
# Symbolischen Beobachtungsvektor aus Näherungskoordinaten (l0) aufstellen
beobachtungsvektor_naeherung_symbolisch = self.fm.beobachtungsvektor_naeherung_symbolisch(
Jacobimatrix_symbolisch_liste_beobachtungsvektor)
# Symbolische Qll-Matrix aufstellen
Qll_matrix_symbolisch = self.stoch_modell.Qll_symbolisch(Jacobimatrix_symbolisch_liste_beobachtungsvektor)
# Symbolische QAA-Matrix mit den Anschlusspunkten für die weiche Lagerung aufstellen, wenn datumsfestlegung = weiche Lagerung ist
if datumfestlegung == "weiche Lagerung":
QAA_matrix_symbolisch = self.stoch_modell.QAA_symbolisch(Jacobimatrix_symbolisch_liste_beobachtungsvektor)
# Symbolische Unbekanntenvektor aufstellen
unbekanntenvektor_symbolisch = (self.fm.unbekanntenvektor_symbolisch(Jacobimatrix_symbolisch_liste_unbekannte))
# Überprüfung, ob bereits eine Varianzkomponentenschätzung erfolgt ist
liste_varianzkomponentenschaetzung = self.db_zugriff.get_varianzkomponentenschaetzung()
for varianzkomponente in liste_varianzkomponentenschaetzung:
if varianzkomponente[3] != 1:
varianzkomponentenschaetzung_erfolgt = True
else:
varianzkomponentenschaetzung_erfolgt = False
dict_indizes_beobachtungsgruppen = Datumsfestlegung.Datumsfestlegung.indizes_beobachtungsvektor_nach_beobachtungsgruppe(
Jacobimatrix_symbolisch_liste_beobachtungsvektor)
# Klasse FunktionalesModell zurücksetzen
self.fm.substitutionen_dict = self.fm.dict_substitutionen_uebergeordnetes_system()
self.fm.liste_symbole_lambdify = sorted(self.fm.substitutionen_dict.keys(), key=lambda s: str(s))
self.fm.func_A0 = None
self.fm.func_beob0 = None
self.fm.func_u0 = None
# Numerischen Unbekanntenvektor aufstellen
x = self.fm.unbekanntenvektor_numerisch(
Jacobimatrix_symbolisch_liste_unbekannte,
unbekanntenvektor_symbolisch
)
# sp.Symbol in Strings konvertieren
labels_str = [str(s).strip() for s in Jacobimatrix_symbolisch_liste_beobachtungsvektor]
unk_str = [str(s).strip() for s in Jacobimatrix_symbolisch_liste_unbekannte]
# Beschriftungen für CSV-Dateien vorbereiten
mask_lA = np.array([l.startswith("lA_") for l in labels_str])
idx_ll = np.where(~mask_lA)[0]
idx_AA = np.where(mask_lA)[0]
perm = np.concatenate([idx_ll, idx_AA])
labels_perm = [labels_str[i] for i in perm]
idx_xyz = [i for i, s in enumerate(unk_str) if s.startswith(("X", "Y", "Z"))]
# Numerischen Beobachtungsvektor einmalig aufstellen
beobachtungsvektor_numerisch = np.asarray(
self.fm.beobachtungsvektor_numerisch(Jacobimatrix_symbolisch_liste_beobachtungsvektor),
float
).reshape(-1, 1)
# Beobachtungsvektor mit den Anschlusspunkten für die weiche Lagerung aufstellen
lA_prior = beobachtungsvektor_numerisch[mask_lA].copy() if datumfestlegung == "weiche Lagerung" else None
if datumfestlegung == "weiche Lagerung":
beobachtungsvektor_numerisch[mask_lA] = lA_prior
# Numerische QLL-MAtrix einmalig aufstellen
Qll_matrix_numerisch = self.stoch_modell.Qll_numerisch(
Qll_matrix_symbolisch,
Jacobimatrix_symbolisch_liste_beobachtungsvektor
)
# Einmalig die numerischen Qll- und QAA-Matrizen zu einer gemeinsamen Matrix verbinden und P-Matrix aufbauen
if datumfestlegung == "weiche Lagerung":
QAA_matrix_numerisch = self.stoch_modell.QAA_numerisch(
QAA_matrix_symbolisch,
Jacobimatrix_symbolisch_liste_beobachtungsvektor
)
Q_ext, P = Datumsfestlegung.Datumsfestlegung.weiches_datum(Qll_matrix_numerisch, QAA_matrix_numerisch,
varianzkomponentenschaetzung_erfolgt,
dict_indizes_beobachtungsgruppen)
# Abbruchbedingungen für die Iteration definieren
tol_dx_abs = 1e-3 # 1.0 mm
tol_stag = 1e-10 # Änderung in max|dx_xyz|
stag_max = 3
prev_max_dx_xyz = None
stag_count = 0
max_iter = 20 # Maximale Anzahl Iterationen
# Iterationen ausführen
for iteration in range(max_iter):
print("\n" + "=" * 60)
print(f"ITERATION {iteration}")
print(f" -> berechne A(x_{iteration})")
# Numerische Jacobi-Matrix bei Iteration 0 mit den Datensätzen aus der Datenbank aufbauen. In jeder weiteren Iteration aus den Ergebnissen der vorherigen Iteration.
A_matrix_numerisch = self.fm.jacobi_matrix_numerisch(
Jacobimatrix_symbolisch,
"naeherung_us",
Jacobimatrix_symbolisch_liste_unbekannte,
Jacobimatrix_symbolisch_liste_beobachtungsvektor,
iteration
)
A_matrix_numerisch = np.asarray(A_matrix_numerisch, float)
if datumfestlegung == "weiche Lagerung":
beobachtungsvektor_numerisch[mask_lA] = lA_prior
# Numerischen Beobachtungsvektor aus Näherungswerten (l0) aufbauen.
print(f" -> berechne l0(x_{iteration})")
beobachtungsvektor_naeherung_numerisch_iteration0 = self.fm.beobachtungsvektor_naeherung_numerisch(
Jacobimatrix_symbolisch_liste_beobachtungsvektor,
beobachtungsvektor_naeherung_symbolisch,
iteration
)
# Exportieren von Matrizen und Vektoren in CSV-Dateien
if iteration == 0:
if speichern_in_csv == True:
Exporter.matrix_to_csv(
fr"Zwischenergebnisse\_l.csv",
[""],
labels_str,
beobachtungsvektor_numerisch,
"l"
)
if datumfestlegung == "weiche Lagerung":
Exporter.matrix_to_csv(
fr"Zwischenergebnisse\{iteration}_Q_ext.csv",
labels_perm,
labels_perm,
Q_ext,
"Q_ext"
)
Exporter.matrix_to_csv(
fr"Zwischenergebnisse\{iteration}_P.csv",
labels_perm,
labels_perm,
P,
"P"
)
# Q-Matrix für weitere Berechnung auswählen
if datumfestlegung == "weiche Lagerung":
Q_k = Q_ext
else:
Q_k = Qll_matrix_numerisch
# dl = l - l0 Vektor berechnen
dl_k = self.fm.berechnung_dl(
beobachtungsvektor_numerisch,
beobachtungsvektor_naeherung_numerisch_iteration0,
Jacobimatrix_symbolisch_liste_beobachtungsvektor,
iteration
)
dl_k = np.asarray(dl_k, float)
# Parameterschätzung für die aktuelle Iteration berechnen
ausgabe_parameterschaetzung, dx = Parameterschaetzung.ausgleichung_global(A_matrix_numerisch, dl_k, Q_k, P)
dx = np.asarray(dx, float).reshape(-1, 1)
# Matrizen je Iteration als CSV-Datei speichern
if speichern_in_csv == True:
Exporter.matrix_to_csv(fr"Zwischenergebnisse\{iteration}_Qxx.csv",
[""], Jacobimatrix_symbolisch_liste_unbekannte, ausgabe_parameterschaetzung["Q_xx"], "Qxx")
Exporter.matrix_to_csv(fr"Zwischenergebnisse\{iteration}_dl.csv",
[""], labels_str, dl_k, "dl")
Exporter.matrix_to_csv(fr"Zwischenergebnisse\{iteration}_dx.csv",
[""], Jacobimatrix_symbolisch_liste_unbekannte, dx, "dx")
# Unbekanntenvektor als Ergebnis der aktuellen Iteration berechnen
x = self.fm.unbekanntenvektor_numerisch(
Jacobimatrix_symbolisch_liste_unbekannte,
unbekanntenvektor_symbolisch,
dX_Vektor=dx,
unbekanntenvektor_numerisch_vorherige_Iteration=x,
iterationsnummer=iteration
)
# Abbruchbedingungen überprüfen und ausgeben
max_dx_xyz = float(np.max(np.abs(dx[idx_xyz])))
print(" -> max|dx_xyz| [m] =", max_dx_xyz)
tol_dx = tol_dx_abs
if prev_max_dx_xyz is not None and abs(prev_max_dx_xyz - max_dx_xyz) < tol_stag:
stag_count += 1
else:
stag_count = 0
prev_max_dx_xyz = max_dx_xyz
if max_dx_xyz < tol_dx:
print("\nKONVERGENZ ERREICHT (XYZ)")
break
if stag_count >= stag_max:
print("\nABBRUCH: STAGNATION (XYZ)")
break
return A_matrix_numerisch, Jacobimatrix_symbolisch_liste_unbekannte, Jacobimatrix_symbolisch_liste_beobachtungsvektor, x, dx, dl_k, ausgabe_parameterschaetzung

View File

@@ -0,0 +1,229 @@
import ipywidgets as widgets
from IPython.display import display, clear_output
import numpy as np
import pandas as pd
import Datenbank
import Datumsfestlegung
from Netzqualität_Genauigkeit import Genauigkeitsmaße
class VKS:
"""Varianzkomponentenschätzung (VKS) mit Anpassung durch Benutzereingaben.
Die Klasse stellt Methoden zur Verfügung für:
- Berechnung der a-posteriori Standardabweichungen je Beobachtungsgruppe anhand von v, P und R,
- Anzeige und Anpassung der Varianzkomponenten (Multiplikationsfaktoren),
- Rückschreiben geänderter Faktoren in die Datenbank und Sperren weiterer Eingaben nach dem Speichern.
Die interaktive Tabelle stellt die in der Datenbank gespeicherten Varianzkomponenten dar und ergänzt
je Zeile einen frei wählbaren Varianzmultiplikator (Standard: 1.0).
"""
def __init__(self,pfad_datenbank: str) -> None:
"""Initialisiert die VKS-Klasse.
Legt den Datenbankpfad fest, initialisiert den Datenbankzugriff und bereitet Instanzvariablen
für DataFrame, Widgets, Button und Log-Ausgabe vor.
:param pfad_datenbank: Pfad zur SQLite-Datenbank.
:type pfad_datenbank: str
:return: None
:rtype: None
"""
self.pfad_datenbank = pfad_datenbank
self.df = None
self.neue_werte_widgets = []
self.btn_save = None
self.log_output = None
self.columns = ['ID', 'InstrumentenID', 'Beobachtungsgruppe', 'Varianzfaktor_aktuelle_iteration']
self.db_zugriff = Datenbank.Datenbankzugriff(self.pfad_datenbank)
def varianzkomponten_berechnen(self, Jacobimatrix_symbolisch_liste_beobachtungsvektor: list, res: dict, R: np.ndarray) -> None:
"""Berechnet a-posteriori Varianzen und a-posteriori Standardabweichungen je Beobachtungsgruppe.
Teilt die Residuen v, die Gewichtsmatrix P sowie die Redundanzmatrix R gemäß der in
Jacobimatrix_symbolisch_liste_beobachtungsvektor enthaltenen Gruppenindizes auf. Für jede
Beobachtungsgruppe wird die Redundanz ri = Spur(R_i) gebildet und daraus s0_aposteriori
berechnet.
Unterstützte Gruppenkennungen: "SD", "R", "ZW", "gnss", "niv", "lA".
:param Jacobimatrix_symbolisch_liste_beobachtungsvektor: Liste der Zeilenbeschriftungen/Beobachtungskennungen (Strings).
:type Jacobimatrix_symbolisch_liste_beobachtungsvektor: list
:param res: Ergebnis-Dictionary der Ausgleichung, erwartet mindestens res["v"] (Residuen) und res["P"] (Gewichte).
:type res: dict
:param R: Redundanzmatrix (z. B. aus R = Q_vv @ P oder äquivalent), passend zu v/P dimensioniert.
:type R: np.ndarray
:return: None
:rtype: None
"""
# Zeilen- und Spaltennummern der jeweiligen Beobachtungsgruppe, z.B. SD für Schrägdistanz ermitteln
dict_indizes_beobachtungsgruppen = Datumsfestlegung.Datumsfestlegung.indizes_beobachtungsvektor_nach_beobachtungsgruppe(
Jacobimatrix_symbolisch_liste_beobachtungsvektor)
# Matrizen, bzw. Vektoren V, P und R aufteilen und die Redundanz und Standardabweichung aposteriori der jeweiligen Beobachtungsgruppe berechnen
for beobachtungsgruppe, indizes in dict_indizes_beobachtungsgruppen.items():
z_start, z_ende = indizes[0], indizes[1]
s_start, s_ende = indizes[0], indizes[1]
# SD = Tachymeter Schrägstrecke
if beobachtungsgruppe == "SD":
aufgeteilt_v_SD = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_SD = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_SD = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_SD = sum(np.diag(aufgeteilt_R_SD))
s0_aposteriori_SD = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_SD, aufgeteilt_P_SD, ri_SD)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_SD:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_SD ** 2:.4f}")
# R = Tachymeter Richtungsbeobachtungen
if beobachtungsgruppe == "R":
aufgeteilt_v_R = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_R = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_R = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_R = sum(np.diag(aufgeteilt_R_R))
s0_aposteriori_R = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_R, aufgeteilt_P_R, ri_R)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_R:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_R ** 2:.4f}")
# ZW = Tachymeter Zenitwinkelbeobachtung
if beobachtungsgruppe == "ZW":
aufgeteilt_v_ZW = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_ZW = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_ZW = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_ZW = sum(np.diag(aufgeteilt_R_ZW))
s0_aposteriori_ZW = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_ZW, aufgeteilt_P_ZW, ri_ZW)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_ZW:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_ZW ** 2:.4f}")
# GNSS = GNSS-Basisilinien
if beobachtungsgruppe == "gnss":
aufgeteilt_v_gnss = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_gnss = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_gnss = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_gnss = sum(np.diag(aufgeteilt_R_gnss))
s0_aposteriori_gnss = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_gnss, aufgeteilt_P_gnss, ri_gnss)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_gnss:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_gnss ** 2:.4f}")
# niv = geometrisches Nivellement
if beobachtungsgruppe == "niv":
aufgeteilt_v_niv = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_niv = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_niv = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_niv = sum(np.diag(aufgeteilt_R_niv))
s0_aposteriori_niv = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_niv, aufgeteilt_P_niv, ri_niv)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_niv:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_niv ** 2:.4f}")
# lA = Anschlusspunkte für die weiche Lagerung
if beobachtungsgruppe == "lA":
aufgeteilt_v_lA = res["v"][z_start: z_ende + 1, :]
aufgeteilt_P_lA = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_lA = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_lA = sum(np.diag(aufgeteilt_R_lA))
s0_aposteriori_lA = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_lA, aufgeteilt_P_lA, ri_lA)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_lA:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_lA ** 2:.4f}")
def vks_ausfuehren(self) -> None:
"""Initialisiert die interaktive VKS-Eingabetabelle.
Liest die aktuell gespeicherten Varianzkomponenten aus der Datenbank, erstellt daraus einen
pandas DataFrame und erzeugt je Zeile ein FloatText-Tupel (Standardwert 1.0) zur Eingabe eines
Multiplikationsfaktors. Zusätzlich wird ein Button zum Speichern der Änderungen erstellt.
:return: None
:rtype: None
"""
# In der aktuellen Iteration verwendete Varianzkomponenten aus der Datenbank abfragen und zur Tabelle hinzufügen
rohdaten = self.db_zugriff.get_varianzkomponentenschaetzung()
self.df = pd.DataFrame(rohdaten, columns=self.columns)
# Festlegen der Tupel für die Eintragung des Multiplikationsfaktors auf die Varianzkomponente der aktuellen Iteration
self.neue_werte_widgets = [
widgets.FloatText(value=1.0, step=0.1, layout=widgets.Layout(width='150px'))
for _ in range(len(self.df))
]
# Output speichern
self.log_output = widgets.Output()
# Button zum speichern der Benutzereingaben definieren
self.btn_save = widgets.Button(
description="Varianzkomponten anpassen",
icon="check",
layout=widgets.Layout(width='300px', height='40px')
)
self.btn_save.style.button_color = '#3c3f41'
self.btn_save.style.text_color = '#afb1b3'
# Button verbinden
self.btn_save.on_click(self.buttondefinition)
def buttondefinition(self, b: any) -> None:
"""Definieren der durch den Button auszuführenden Aktionen.
Liest alle Varianzmultiplikatoren aus den Eingabewidgets aus und schreibt in die Datenbank. Nach erfolgreichem
Speichern wird der Button deaktiviert und Benutzereingaben werden gesperrt.
:param b: Button-Event-Objekt von ipywidgets (wird beim ausführen übergeben).
:type b: Any
:return: None
:rtype: None
"""
with self.log_output:
clear_output()
# Benutzereingaben abfragen
liste_varianzkomponten_anpassen = [
(int(self.df.iat[i, 1]), str(self.df.iat[i, 2]), w.value)
for i, w in enumerate(self.neue_werte_widgets)
if w.value != 1.0
]
# Benutzereingabe in Datenbank übernehmen
if liste_varianzkomponten_anpassen:
self.db_zugriff.set_varianzkomponente(liste_varianzkomponten_anpassen)
# Button zum speichern deaktivieren
self.btn_save.disabled = True
for w in self.neue_werte_widgets:
# Eingabe neuer Faktoren für die Varianzkomponenten verhindern
w.disabled = True
def zeige_vks_tabelle(self) -> None:
"""Erzeugt und zeigt die interaktive VKS-Tabelle im Notebook an.
Baut eine tabellarische Darstellung auf.
Ergänzt die Ausgabe um einen Speichern-Button.
:return: None
:rtype: None
"""
# Header erstellen
header = widgets.HBox([
widgets.Label(col, layout=widgets.Layout(width='250px', font_weight='bold', align='center'))
for col in self.columns
] + [widgets.Label('Varianzmultiplikator',
layout=widgets.Layout(width='150px', font_weight='bold', align='center'))])
zeilen = []
# Iterieren über df und widgets gleichzeitig
for i, row in enumerate(self.df.itertuples(index=False)):
zellen = [widgets.Label(str(val), layout=widgets.Layout(width='250px', align='center')) for val in row]
zellen.append(self.neue_werte_widgets[i])
zeilen.append(widgets.HBox(zellen))
# Darstellen der Tabelle
display(widgets.VBox([header] + zeilen + [widgets.HTML("<br>"), self.btn_save, self.log_output]))