fertig
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -124,7 +124,7 @@ class Datumsfestlegung:
|
||||
return Q_ext, P
|
||||
|
||||
@staticmethod
|
||||
def indizes_beobachtungsvektor_nach_beobachtungsgruppe(Jacobimatrix_symbolisch_liste_beobachtungsvektor):
|
||||
def indizes_beobachtungsvektor_nach_beobachtungsgruppe(Jacobimatrix_symbolisch_liste_beobachtungsvektor: list[str]) -> dict[str, tuple[int, int]]:
|
||||
"""
|
||||
Ermittelt Indexbereiche des Beobachtungsvektors getrennt nach Beobachtungsgruppen.
|
||||
|
||||
@@ -189,113 +189,4 @@ class Datumsfestlegung:
|
||||
dict_beobachtungsgruppen_indizes["niv"] = min(liste_nivellement_indizes), max(liste_nivellement_indizes)
|
||||
dict_beobachtungsgruppen_indizes["lA"] = min(liste_anschlusspunkte_indizes), max(liste_anschlusspunkte_indizes)
|
||||
|
||||
return dict_beobachtungsgruppen_indizes
|
||||
|
||||
|
||||
@staticmethod
|
||||
def make_index(unbekannten_liste):
|
||||
names = [str(s).strip() for s in unbekannten_liste]
|
||||
return names, {n: i for i, n in enumerate(names)}
|
||||
|
||||
@staticmethod
|
||||
def erstelle_G(x0, unbekannten_liste, liste_punktnummern=None, mit_massstab=True):
|
||||
"""
|
||||
Baut G (u x d) in den vollen Unbekanntenraum.
|
||||
Wenn liste_punktnummern=None, werden alle Punkt-IDs aus unbekannten_liste
|
||||
über X*/Y*/Z* automatisch bestimmt.
|
||||
"""
|
||||
x0 = np.asarray(x0, float).reshape(-1)
|
||||
names, idx = Datumsfestlegung.make_index(unbekannten_liste)
|
||||
|
||||
u = len(names)
|
||||
d = 7 if mit_massstab else 6
|
||||
G = np.zeros((u, d), dtype=float)
|
||||
|
||||
# --- Punktliste automatisch, falls nicht gegeben ---
|
||||
if liste_punktnummern is None:
|
||||
pids = set()
|
||||
for n in names:
|
||||
if len(n) >= 2 and n[0].upper() in ("X", "Y", "Z"):
|
||||
pids.add(n[1:]) # alles nach X/Y/Z
|
||||
liste_punktnummern = sorted(pids)
|
||||
|
||||
for pid in liste_punktnummern:
|
||||
sx, sy, sz = f"X{pid}", f"Y{pid}", f"Z{pid}"
|
||||
if sx not in idx or sy not in idx or sz not in idx:
|
||||
continue # Punkt nicht vollständig als XYZ-Unbekannte vorhanden
|
||||
|
||||
ix, iy, iz = idx[sx], idx[sy], idx[sz]
|
||||
xi, yi, zi = x0[ix], x0[iy], x0[iz]
|
||||
|
||||
# Translationen
|
||||
G[ix, 0] = 1.0
|
||||
G[iy, 1] = 1.0
|
||||
G[iz, 2] = 1.0
|
||||
|
||||
# Rotationen (δr = ω × r)
|
||||
# Rx: δY=-Z, δZ=+Y
|
||||
G[iy, 3] = -zi
|
||||
G[iz, 3] = yi
|
||||
# Ry: δX=+Z, δZ=-X
|
||||
G[ix, 4] = zi
|
||||
G[iz, 4] = -xi
|
||||
# Rz: δX=-Y, δY=+X
|
||||
G[ix, 5] = -yi
|
||||
G[iy, 5] = xi
|
||||
|
||||
# Maßstab
|
||||
if mit_massstab:
|
||||
G[ix, 6] = xi
|
||||
G[iy, 6] = yi
|
||||
G[iz, 6] = zi
|
||||
|
||||
return G
|
||||
|
||||
|
||||
def aktive_indices_from_selection(auswahl, unbekannten_liste):
|
||||
names, idx = Datumsfestlegung.make_index(unbekannten_liste)
|
||||
aktive = []
|
||||
for pid, comp in auswahl:
|
||||
key = f"{comp.upper()}{str(pid)}"
|
||||
if key not in idx:
|
||||
raise KeyError(f"{key} nicht im Unbekanntenvektor.")
|
||||
aktive.append(idx[key])
|
||||
# unique
|
||||
out = []
|
||||
seen = set()
|
||||
for i in aktive:
|
||||
if i not in seen:
|
||||
seen.add(i)
|
||||
out.append(i)
|
||||
return out
|
||||
|
||||
|
||||
def auswahlmatrix_E(u, aktive_indices):
|
||||
E = np.zeros((u, u), dtype=float)
|
||||
for i in aktive_indices:
|
||||
E[int(i), int(i)] = 1.0
|
||||
return E
|
||||
|
||||
|
||||
def berechne_dx(N, n, G):
|
||||
|
||||
N = np.asarray(N, float)
|
||||
n = np.asarray(n, float).reshape(-1, 1)
|
||||
G = np.asarray(G, float)
|
||||
|
||||
u = N.shape[0]
|
||||
d = G.shape[1]
|
||||
|
||||
K = np.block([
|
||||
[N, G],
|
||||
[G.T, np.zeros((d, d))]
|
||||
])
|
||||
rhs = np.vstack([n, np.zeros((d, 1))])
|
||||
|
||||
K_inv = np.linalg.inv(K)
|
||||
sol = K_inv @ rhs
|
||||
|
||||
dx = sol[:u]
|
||||
k = sol[u:]
|
||||
Q_xx = K_inv[:u, :u]
|
||||
return dx, k, Q_xx
|
||||
return dict_beobachtungsgruppen_indizes
|
||||
@@ -65,11 +65,7 @@ class Export:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def erzeuge_ergebnis_datenframes(
|
||||
pfad_datenbank: str,
|
||||
pfad_tif_quasigeoidundulation: str,
|
||||
dict_koordinaten_ausgleichungsergebnis: dict
|
||||
):
|
||||
def erzeuge_ergebnis_datenframes(pfad_datenbank: str, pfad_tif_quasigeoidundulation: str, dict_koordinaten_ausgleichungsergebnis: dict) -> tuple[pd.DataFrame, pd.DataFrame]:
|
||||
"""
|
||||
Erzeugt Ergebnis-DataFrames für ausgeglichene Koordinaten in ECEF (XYZ) und UTM.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class FunktionalesModell:
|
||||
Die grundlegende Funktionsweise der Matrixdefinition lautet:
|
||||
|
||||
1) Einmaligen Aufbauen der Symbolischen Matrix einmalig
|
||||
2) In jeder Iteration Substituieren der Symbolischen Matrizen in Numerische np.asarrays
|
||||
2) In jeder Iteration Substituieren der Symbolischen Matrizen in Numerische np.ndarray
|
||||
"""
|
||||
|
||||
def __init__(self, pfad_datenbank: str, a: float, b: float, pfad_tif_quasigeoidundulation: str = None) -> None:
|
||||
@@ -703,8 +703,8 @@ class FunktionalesModell:
|
||||
|
||||
def unbekanntenvektor_numerisch(self, liste_unbekanntenvektor_symbolisch: list,
|
||||
unbekanntenvektor_symbolisch: sp.Matrix,
|
||||
dX_Vektor: np.asarray = None,
|
||||
unbekanntenvektor_numerisch_vorherige_Iteration: np.asarray = None,
|
||||
dX_Vektor: np.ndarray = None,
|
||||
unbekanntenvektor_numerisch_vorherige_Iteration: np.ndarray = None,
|
||||
iterationsnummer: int = 0) -> ndarray[tuple[int, int], Any] | ndarray[tuple[Any, ...], dtype[Any]]:
|
||||
"""Erstellt den numerischen Unbekanntenvektor jeder Iteration.
|
||||
|
||||
@@ -722,9 +722,9 @@ class FunktionalesModell:
|
||||
:param unbekanntenvektor_symbolisch: Symbolischer Unbekanntenvektor.
|
||||
:type unbekanntenvektor_symbolisch: sp.Matrix
|
||||
:param dX_Vektor: Verbesserungsvektor der aktuellen Iteration (optional).
|
||||
:type dX_Vektor: np.asarray | None
|
||||
:type dX_Vektor: np.ndarray | None
|
||||
:param unbekanntenvektor_numerisch_vorherige_Iteration: Numerischer Unbekanntenvektor der vorherigen Iteration (optional).
|
||||
:type unbekanntenvektor_numerisch_vorherige_Iteration: np.asarray | None
|
||||
:type unbekanntenvektor_numerisch_vorherige_Iteration: np.ndarray | None
|
||||
:param iterationsnummer: Iterationsnummer für Dateinamen der Zwischenergebnisse.
|
||||
:type iterationsnummer: int
|
||||
:return: Numerischer Unbekanntenvektor als Numpy-Array
|
||||
@@ -754,7 +754,7 @@ class FunktionalesModell:
|
||||
"Unbekanntenvektor")
|
||||
return unbekanntenvektor_numerisch
|
||||
|
||||
def unbekanntenvektor_numerisch_to_dict_unbekanntenvektor(self, liste_unbekanntenvektor_symbolisch: list, unbekanntenvektor_numerisch: np.asarray) -> dict:
|
||||
def unbekanntenvektor_numerisch_to_dict_unbekanntenvektor(self, liste_unbekanntenvektor_symbolisch: list, unbekanntenvektor_numerisch: np.ndarray) -> dict:
|
||||
"""Wandelt einen numerischen Unbekanntenvektor in ein Koordinatendictionary um.
|
||||
|
||||
Aus dem numerischen Unbekanntenvektor werden für alle Punkte die Koordinaten (X, Y, Z) extrahiert
|
||||
@@ -763,7 +763,7 @@ class FunktionalesModell:
|
||||
:param liste_unbekanntenvektor_symbolisch: Liste der Unbekannten (Symbole) in der Reihenfolge des numerischen Vektors.
|
||||
:type liste_unbekanntenvektor_symbolisch: list
|
||||
:param unbekanntenvektor_numerisch: Numerischer Unbekanntenvektor.
|
||||
:type unbekanntenvektor_numerisch: np.asarray
|
||||
:type unbekanntenvektor_numerisch: np.ndarray
|
||||
:return: Dictionary {punktnummer: sp.Matrix([X, Y, Z])}.
|
||||
:rtype: dict
|
||||
"""
|
||||
@@ -796,8 +796,8 @@ class FunktionalesModell:
|
||||
|
||||
return dict_koordinaten
|
||||
|
||||
def berechnung_dl(self, beobachtungsvektor_numerisch: np.asarray, beobachtungsvektor_naeherung_numerisch: sp.Matrix,
|
||||
liste_beobachtungsvektor_symbolisch: list = None, iterationsnummer: int = 0) -> np.asarray:
|
||||
def berechnung_dl(self, beobachtungsvektor_numerisch: np.ndarray, beobachtungsvektor_naeherung_numerisch: sp.Matrix,
|
||||
liste_beobachtungsvektor_symbolisch: list = None, iterationsnummer: int = 0) -> np.ndarray:
|
||||
"""Berechnet den Verbesserungsvektor dl = l − f(x0).
|
||||
|
||||
Der Vektor wird als Differenz aus numerischem Beobachtungsvektor und numerischem Näherungs-Beobachtungsvektor gebildet.
|
||||
@@ -806,7 +806,7 @@ class FunktionalesModell:
|
||||
Der Vektor dl wird als CSV-Datei in den Ordner Zwischenergebnisse exportiert.
|
||||
|
||||
:param beobachtungsvektor_numerisch: Numerischer Beobachtungsvektor l.
|
||||
:type beobachtungsvektor_numerisch: np.asarray
|
||||
:type beobachtungsvektor_numerisch: np.ndarray
|
||||
:param beobachtungsvektor_naeherung_numerisch: Numerischer Näherungs-Beobachtungsvektor f(x0).
|
||||
:type beobachtungsvektor_naeherung_numerisch: sp.Matrix
|
||||
:param liste_beobachtungsvektor_symbolisch: Optional: Liste der Beobachtungskennungen.
|
||||
@@ -814,7 +814,7 @@ class FunktionalesModell:
|
||||
:param iterationsnummer: Iterationsnummer für Dateinamen der Zwischenergebnisse.
|
||||
:type iterationsnummer: int
|
||||
:return: Verbesserungsvektor dl.
|
||||
:rtype: np.asarray
|
||||
:rtype: np.ndarray
|
||||
"""
|
||||
dl = beobachtungsvektor_numerisch - beobachtungsvektor_naeherung_numerisch
|
||||
# Umwandeln in einen Numpy-Array, um Rechenzeit im Vergleich zu einer sympy.MAtrix zu sparen
|
||||
@@ -839,7 +839,7 @@ class FunktionalesModell:
|
||||
return dl
|
||||
|
||||
def dict_substitutionen_uebergeordnetes_system(self,
|
||||
unbekanntenvektor_aus_iteration: np.asarray = None) -> dict[Any, Any]:
|
||||
unbekanntenvektor_aus_iteration: np.ndarray = None) -> dict[Any, Any]:
|
||||
"""Erstellt das Substitutions-Dictionary für das geozentrisch-kartesische System.
|
||||
|
||||
Es werden (abhängig davon, ob ein Unbekanntenvektor aus einer Iteration übergeben wurde) die aktuellen
|
||||
@@ -852,7 +852,7 @@ class FunktionalesModell:
|
||||
- Orientierungsunbekannte O.
|
||||
|
||||
:param unbekanntenvektor_aus_iteration: Optionaler numerischer Unbekanntenvektor einer Iteration zur Aktualisierung der Substitutionen.
|
||||
:type unbekanntenvektor_aus_iteration: np.asarray | None
|
||||
:type unbekanntenvektor_aus_iteration: np.ndarray | None
|
||||
:return: Dictionary mit SymPy-Symbolen als Key und numerischen Werten als Value.
|
||||
:rtype: dict[Any, Any]
|
||||
"""
|
||||
@@ -976,7 +976,7 @@ class FunktionalesModell:
|
||||
return substitutionen
|
||||
|
||||
def unbekanntenvektor_numerisch_to_dict_orientierungen(self, liste_unbekanntenvektor_symbolisch: list,
|
||||
unbekanntenvektor_numerisch: np.asarray) -> dict[Any, Any]:
|
||||
unbekanntenvektor_numerisch: np.ndarray) -> dict[Any, Any]:
|
||||
"""Extrahiert Orientierungsparameter aus einem numerischen Unbekanntenvektor in ein Dictionary.
|
||||
|
||||
Alle Unbekannten, deren Symbolname mit "O" beginnt, werden als als Dictionary in der Form {orientierungs_id: wert} zurückgegeben.
|
||||
@@ -984,7 +984,7 @@ class FunktionalesModell:
|
||||
:param liste_unbekanntenvektor_symbolisch: Liste der Unbekannten (Symbole) in der Reihenfolge des numerischen Vektors.
|
||||
:type liste_unbekanntenvektor_symbolisch: list
|
||||
:param unbekanntenvektor_numerisch: Numerischer Unbekanntenvektor.
|
||||
:type unbekanntenvektor_numerisch: np.asarray
|
||||
:type unbekanntenvektor_numerisch: np.ndarray
|
||||
:return: Dictionary der Orientierungen je Beobachtungsgruppe.
|
||||
:rtype: dict[Any, Any]
|
||||
"""
|
||||
|
||||
@@ -401,7 +401,7 @@ class Transformationen:
|
||||
def ecef_to_utm(
|
||||
self,
|
||||
dict_koordinaten: dict,
|
||||
pfad_gcg_tif: str | Path | None = None):
|
||||
pfad_gcg_tif: str | Path | None = None) -> dict:
|
||||
"""Rechnet ECEF-Koordinaten (ETRS89 geozentrisch-kartesisch) nach nach UTM (+ DHHN2016 Normalhöhe).
|
||||
|
||||
Es wird ein PROJ-Transformer von:
|
||||
|
||||
@@ -13,7 +13,7 @@ class Genauigkeitsmaße:
|
||||
|
||||
Die Klasse stellt Methoden zur Verfügung für:
|
||||
|
||||
- Berechnung der a-posteriori Standardabweichung der Gewichtseinheit s₀
|
||||
- Berechnung der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀
|
||||
- Berechnung des Helmertschen Punktfehlers (2D/3D),
|
||||
- Berechnung der Standardellipse (Helmertschen Fehlerellipse),
|
||||
- Berechnung der Konfidenzellipse auf Basis eines Konfidenzniveaus (alpha) mit Skalierung über die F-Verteilung,
|
||||
@@ -25,19 +25,19 @@ class Genauigkeitsmaße:
|
||||
@staticmethod
|
||||
def berechne_sigma0apost(v: np.ndarray, P: np.ndarray, r: int, print_ausgabe = True) -> float:
|
||||
"""
|
||||
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
|
||||
Die a-posteriori Standardabweichung dient als Qualitätsmaß für die
|
||||
Ausgleichung nach der Methode der kleinsten Quadrate. Dabei beschreibt
|
||||
r die Redundanz (Freiheitsgrade).
|
||||
|
||||
:param v: Residuenvektor der Beobachtungen.
|
||||
:type v: numpy.ndarray
|
||||
:type v: np.ndarray
|
||||
:param P: Gewichtsmatrix der Beobachtungen.
|
||||
:type P: numpy.ndarray
|
||||
:type P: np.ndarray
|
||||
:param r: Redundanz bzw. Anzahl der Freiheitsgrade der Ausgleichung.
|
||||
:type r: int
|
||||
:return: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:return: a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:rtype: float
|
||||
"""
|
||||
|
||||
@@ -50,12 +50,12 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def helmert_punktfehler(Qxx, s0_apost, unbekannten_liste):
|
||||
def helmert_punktfehler(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
||||
"""
|
||||
Berechnet den Helmertschen Punktfehler (2D/3D) anhand der Standardabweichungen der Koordinaten der Punkte.
|
||||
|
||||
Aus der Kofaktor-Matrix der Unbekannten Qxx werden die Kofaktoren punktweise ausgelesen. Durch Multiplikation
|
||||
mit der a-posteriori Standardabweichung der Gewichtseinheit s₀ werden die Standardabweichungen je Koordinate
|
||||
mit der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀ werden die Standardabweichungen je Koordinate
|
||||
(σx, σy, σz) sowie der Helmert'sche Punktfehler σP berechnet:
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||
@@ -63,14 +63,13 @@ class Genauigkeitsmaße:
|
||||
Ergebnisse als Tabelle ausgegeben und in eine Excel-Datei exportiert.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:return: Tabelle mit Standardabweichungen und Helmertschem Punktfehler je Punkt.
|
||||
:rtype: pandas.DataFrame
|
||||
:raises ValueError: Wenn eine ungültige Dimension (nicht 2 oder 3) eingegeben wird.
|
||||
"""
|
||||
dim = int(input("Helmertscher Punktfehler (2 = 2D, 3 = 3D): "))
|
||||
diagQ = np.diag(Qxx)
|
||||
@@ -98,17 +97,17 @@ class Genauigkeitsmaße:
|
||||
except StopIteration:
|
||||
qz = 0.0
|
||||
|
||||
sx = s0_apost * np.sqrt(qx)
|
||||
sy = s0_apost * np.sqrt(qy)
|
||||
sz = s0_apost * np.sqrt(qz) if dim == 3 else 0
|
||||
sx = sigma0_apost * np.sqrt(qx)
|
||||
sy = sigma0_apost * np.sqrt(qy)
|
||||
sz = sigma0_apost * np.sqrt(qz) if dim == 3 else 0
|
||||
|
||||
sP = s0_apost * np.sqrt(qx + qy + qz)
|
||||
sP = sigma0_apost * np.sqrt(qx + qy + qz)
|
||||
|
||||
daten.append([pid, float(sx), float(sy), float(sz), float(sP)])
|
||||
except:
|
||||
continue
|
||||
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σx", "σy", "σz", f"σP_{dim}D"])
|
||||
mittel_sP = helmert_punktfehler[f"σP_{dim}D"].mean()
|
||||
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σ̂x", "σ̂y", "σ̂z", f"σ̂P_{dim}D"])
|
||||
mittel_sP = helmert_punktfehler[f"σ̂P_{dim}D"].mean()
|
||||
print(f"Mittlerer Helmert-Punktfehler über alle Punkte: {mittel_sP:.4f} [m]")
|
||||
display(HTML(helmert_punktfehler.to_html(index=False)))
|
||||
helmert_punktfehler.to_excel(r"Netzqualitaet\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
|
||||
@@ -117,9 +116,9 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def standardellipsoid(Qxx, s0_apost, unbekannten_liste):
|
||||
def standardellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
||||
"""
|
||||
Berechnet Achsenlängen des Fehlerellipsoids (a, b, c) sowie den 2D-Richtungswinkel θ aus Qxx und s₀ a posteriori.
|
||||
Berechnet Achsenlängen des Fehlerellipsoids (a, b, c) sowie den 2D-Richtungswinkel θ aus Qxx und σ̂₀ a posteriori.
|
||||
|
||||
Für jeden Punkt wird aus der Kofaktor-Matrix der Unbekannten Qxx die 3×3-Submatrix
|
||||
der Koordinaten (X, Y, Z) gebildet. Daraus werden zunächst die Standardabweichungen
|
||||
@@ -137,9 +136,9 @@ class Genauigkeitsmaße:
|
||||
Die Ergebnisse werden tabellarisch ausgegeben und in eine Excel-Datei exportiert.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: A-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: A-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:return: Tabelle mit Standardabweichungen (σx, σy, σz), Ellipsoid-Halbachsen (a, b, c) und Richtungswinkel θ je Punkt.
|
||||
@@ -165,18 +164,18 @@ class Genauigkeitsmaße:
|
||||
Q_sub = Qxx[np.ix_(indices, indices)]
|
||||
|
||||
# Standardabweichungen
|
||||
sx = s0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = s0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = s0_apost * np.sqrt(Q_sub[2, 2])
|
||||
sx = sigma0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = sigma0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = sigma0_apost * np.sqrt(Q_sub[2, 2])
|
||||
|
||||
# Eigenwertzerlegung
|
||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
||||
|
||||
# Halbachsen
|
||||
s_a = s0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
||||
s_b = s0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
||||
s_c = s0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
||||
s_a = sigma0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
||||
s_b = sigma0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
||||
s_c = sigma0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
||||
|
||||
# Richtungswinkel theta in gon:
|
||||
qyx = Q_sub[1, 0]
|
||||
@@ -192,10 +191,10 @@ class Genauigkeitsmaße:
|
||||
])
|
||||
except:
|
||||
continue
|
||||
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σx [m]", "σy [m]", "σz [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "θ [gon]"])
|
||||
standardellipsoid["σx [m]"] = standardellipsoid["σx [m]"].astype(float).round(4)
|
||||
standardellipsoid["σy [m]"] = standardellipsoid["σy [m]"].astype(float).round(4)
|
||||
standardellipsoid["σz [m]"] = standardellipsoid["σz [m]"].astype(float).round(4)
|
||||
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "θ [gon]"])
|
||||
standardellipsoid["σ̂x [m]"] = standardellipsoid["σ̂x [m]"].astype(float).round(4)
|
||||
standardellipsoid["σ̂y [m]"] = standardellipsoid["σ̂y [m]"].astype(float).round(4)
|
||||
standardellipsoid["σ̂z [m]"] = standardellipsoid["σ̂z [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse a [m]"] = standardellipsoid["Halbachse a [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse b [m]"] = standardellipsoid["Halbachse b [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse c [m]"] = standardellipsoid["Halbachse c [m]"].astype(float).round(4)
|
||||
@@ -207,23 +206,34 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def konfidenzellipsoid(Qxx, s0_apost, unbekannten_liste, R, ausgabe_erfolgt):
|
||||
def konfidenzellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list, R: int, ausgabe_erfolgt: bool) -> tuple[pd.DataFrame, float]:
|
||||
"""
|
||||
Berechnet die Konfidenzellipse für Punkte aus Qxx und einem Konfidenzniveau.
|
||||
Berechnet die Konfidenzellipsoid für Punkte aus Qxx und einem Konfidenzniveau.
|
||||
|
||||
Auf Basis der Kovarianz-Matrix der Unbekannten Qxx und der a-posteriori
|
||||
Standardabweichung der Gewichtseinheit s₀ werden für jeden Punkt die Parameter
|
||||
der Konfidenzellipse berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
||||
über alpha gewählt (Standard: 0.05 für 95%).
|
||||
Standardabweichung der Gewichtseinheit σ̂₀ werden für jeden Punkt die Parameter
|
||||
des Konfidenzellipsoids berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
||||
über alpha festgelegt (Standard: 0.05 für 95%).
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste (z.B. X1, Y1).
|
||||
Für jeden Punkt wird die 3×3-Submatrix der Koordinaten (X, Y, Z) aus Qxx gebildet.
|
||||
Über eine Eigenwertzerlegung dieser Submatrix werden die drei Hauptachsen des
|
||||
Fehlerellipsoids bestimmt. Die Halbachsen des Konfidenzellipsoids ergeben sich aus:
|
||||
|
||||
- Aₖ: große Halbachse des Konfidenzellipsoids,
|
||||
- Bₖ: mittlere Halbachse des Konfidenzellipsoids,
|
||||
- Cₖ: kleine Halbachse des Konfidenzellipsoids,
|
||||
|
||||
unter Verwendung eines Faktors aus der F-Verteilung in Abhängigkeit vom
|
||||
Konfidenzniveau und den Freiheitsgraden.
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||
Optional wird die Tabelle ausgegeben und als Excel-Datei exportiert, abhängig von
|
||||
ausgabe_erfolgt.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der geschätzten Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:param R: Redundanz (Freiheitsgrade) für die F-Verteilung.
|
||||
@@ -232,7 +242,6 @@ class Genauigkeitsmaße:
|
||||
:type ausgabe_erfolgt: bool
|
||||
:return: Tabelle der Konfidenzellipse je Punkt, verwendetes alpha.
|
||||
:rtype: tuple[pandas.DataFrame, float]
|
||||
:raises ValueError: Wenn alpha nicht in (0, 1) liegt oder nicht in float umgewandelt werden kann.
|
||||
"""
|
||||
alpha_input = input("Irrtumswahrscheinlichkeit α wählen (z.B. 0.05, 0.01) [Standard=0.05]: ")
|
||||
if alpha_input.strip() == "":
|
||||
@@ -259,18 +268,18 @@ class Genauigkeitsmaße:
|
||||
Q_sub = Qxx[np.ix_(indices, indices)]
|
||||
|
||||
# Standardabweichungen
|
||||
sx = s0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = s0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = s0_apost * np.sqrt(Q_sub[2, 2])
|
||||
sx = sigma0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = sigma0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = sigma0_apost * np.sqrt(Q_sub[2, 2])
|
||||
|
||||
# Eigenwertzerlegung
|
||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
||||
|
||||
# Halbachsen des Konfidenzellipoid
|
||||
A_K = k * s0_apost * np.sqrt(eigenwerte[0])
|
||||
B_K = k * s0_apost * np.sqrt(eigenwerte[1])
|
||||
C_K = k * s0_apost * np.sqrt(eigenwerte[2])
|
||||
A_K = k * sigma0_apost * np.sqrt(eigenwerte[0])
|
||||
B_K = k * sigma0_apost * np.sqrt(eigenwerte[1])
|
||||
C_K = k * sigma0_apost * np.sqrt(eigenwerte[2])
|
||||
|
||||
# Richtungswinkel theta in gon:
|
||||
qyx = Q_sub[1, 0]
|
||||
@@ -288,7 +297,7 @@ class Genauigkeitsmaße:
|
||||
except:
|
||||
continue
|
||||
|
||||
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σx [m]", "σy [m]", "σz [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "θ [gon]"])
|
||||
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "θ [gon]"])
|
||||
if ausgabe_erfolgt == False:
|
||||
display(HTML(konfidenzellipoid.to_html(index=False)))
|
||||
konfidenzellipoid.to_excel(r"Netzqualitaet\Konfidenzellipoid.xlsx", index=False)
|
||||
@@ -296,7 +305,7 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def konfidenzellipsen_enu(a, b, ausgabe_parameterschaetzung, liste_unbekannte, ausgleichungsergebnis, s0apost, r_gesamt):
|
||||
def konfidenzellipsen_enu(a: float, b: float, ausgabe_parameterschaetzung: dict, liste_unbekannte: list, ausgleichungsergebnis: dict, sigma0apost: float, r_gesamt: int) -> tuple[pd.DataFrame, np.ndarray]:
|
||||
"""
|
||||
Berechnet Konfidenzellipsen im lokalen ENU-System aus einer ins ENU-System transformierten Qxx-Matrix.
|
||||
|
||||
@@ -317,13 +326,12 @@ class Genauigkeitsmaße:
|
||||
:type liste_unbekannte: list
|
||||
:param ausgleichungsergebnis: Dictionary der geschätzten Punktkoordinaten (XYZ) zur ENU-Referenzbildung.
|
||||
:type ausgleichungsergebnis: dict
|
||||
:param s0apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0apost: float
|
||||
:param sigma0apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0apost: float
|
||||
:param r_gesamt: Redundanz (Freiheitsgrade) für die Konfidenzberechnung.
|
||||
:type r_gesamt: int
|
||||
:return: Tabelle der Konfidenzellipse im ENU-System, Rotationsmatrix R0 der ENU-Transformation.
|
||||
:rtype: tuple[pandas.DataFrame, numpy.ndarray]
|
||||
:raises KeyError: Wenn ``ausgabe_parameterschaetzung`` keinen Eintrag ``"Q_xx"`` enthält.
|
||||
"""
|
||||
|
||||
berechnungen = Berechnungen.Berechnungen(a, b)
|
||||
@@ -342,7 +350,7 @@ class Genauigkeitsmaße:
|
||||
# 2) Konfidenzellipoid im ENU-System
|
||||
Konfidenzellipse_ENU, alpha = Genauigkeitsmaße.konfidenzellipsoid(
|
||||
Qxx_enu,
|
||||
s0apost,
|
||||
sigma0apost,
|
||||
liste_unbekannte,
|
||||
r_gesamt,
|
||||
ausgabe_erfolgt = True
|
||||
@@ -350,16 +358,16 @@ class Genauigkeitsmaße:
|
||||
|
||||
# 3) Spaltennamen anpassen
|
||||
Konfidenzellipse_ENU = Konfidenzellipse_ENU.rename(columns={
|
||||
"σx [m]": "σE [m]",
|
||||
"σy [m]": "σN [m]",
|
||||
"σz [m]": "σU [m]",
|
||||
"σ̂x [m]": "σ̂E [m]",
|
||||
"σ̂y [m]": "σ̂N [m]",
|
||||
"σ̂z [m]": "σ̂U [m]",
|
||||
"θ [gon]": "θ_EN [gon]"
|
||||
})
|
||||
|
||||
# 4) Runden und Anzeigen
|
||||
Konfidenzellipse_ENU["σE [m]"] = Konfidenzellipse_ENU["σE [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σN [m]"] = Konfidenzellipse_ENU["σN [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σU [m]"] = Konfidenzellipse_ENU["σU [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂E [m]"] = Konfidenzellipse_ENU["σ̂E [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂N [m]"] = Konfidenzellipse_ENU["σ̂N [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂U [m]"] = Konfidenzellipse_ENU["σ̂U [m]"].round(6)
|
||||
Konfidenzellipse_ENU["Halbachse a_k [m]"] = Konfidenzellipse_ENU["Halbachse a_k [m]"].round(4)
|
||||
Konfidenzellipse_ENU["Halbachse b_k [m]"] = Konfidenzellipse_ENU["Halbachse b_k [m]"].round(4)
|
||||
Konfidenzellipse_ENU["Halbachse c_k [m]"] = Konfidenzellipse_ENU["Halbachse c_k [m]"].round(4)
|
||||
@@ -390,15 +398,7 @@ class Plot:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def netzplot_ellipsen(
|
||||
Koord_ENU,
|
||||
unbekannten_labels,
|
||||
beobachtungs_labels,
|
||||
df_konf_ellipsen_enu,
|
||||
skalierung,
|
||||
n_ellipse_pts=60,
|
||||
titel="Netzplot im ENU-System mit Konfidenzellipsen"
|
||||
):
|
||||
def netzplot_ellipsen(Koord_ENU: dict[str, tuple[float, float, float]], unbekannten_labels: list, beobachtungs_labels: list, df_konf_ellipsen_enu: pd.DataFrame, skalierung: float, n_ellipse_pts: int = 60, titel: str = "Netzplot im ENU-System mit Konfidenzellipsen") -> go.Figure:
|
||||
|
||||
"""
|
||||
Erstellt einen Netzplot im ENU-System inklusive Konfidenzellipsen, Netzpunkten und Beobachtungslinien.
|
||||
@@ -430,7 +430,6 @@ class Plot:
|
||||
:type titel: str
|
||||
:return: Plotly-Figure-Objekt mit Netz, Beobachtungen und Ellipsen.
|
||||
:rtype: plotly.graph_objects.Figure
|
||||
:raises ValueError: Wenn weder "θ_EN [gon]" noch "θ [gon]" im DataFrame vorhanden ist.
|
||||
"""
|
||||
|
||||
namen = [str(s).strip() for s in unbekannten_labels]
|
||||
@@ -546,7 +545,7 @@ class Plot:
|
||||
return plot
|
||||
|
||||
|
||||
def plot_speichere_aktuelle_ansicht(plot, dateiname=r"Netzqualitaet\netzplot_ellipsen_zoom_ansicht.png"):
|
||||
def plot_speichere_aktuelle_ansicht(plot: go.Figure, dateiname: str = r"Netzqualitaet\netzplot_ellipsen_zoom_ansicht.png") -> None:
|
||||
"""
|
||||
Speichert die aktuell dargestellte Plot-Ansicht als Bilddatei.
|
||||
|
||||
@@ -564,7 +563,6 @@ class Plot:
|
||||
:type dateiname: str
|
||||
:return: None
|
||||
:rtype: None
|
||||
:raises OSError: Wenn die Bilddatei nicht geschrieben werden kann (z.B. fehlender Pfad oder fehlendes Kaleido).
|
||||
"""
|
||||
|
||||
aktuelles_layout = plot.layout
|
||||
|
||||
@@ -12,9 +12,20 @@ from itables.widget import ITable
|
||||
|
||||
@dataclass
|
||||
class Zuverlaessigkeit:
|
||||
"""Berechnung von Zuverlässigkeitsmaße zur Bewertung der erreichten Netzqualität.
|
||||
|
||||
Die Klasse stellt Methoden zur Verfügung für:
|
||||
|
||||
- Berechnung der Gesamtredundanz
|
||||
- Aufbau der Redundanzmatrix
|
||||
- Ableitung und Klassifikation der Redundanzanteile
|
||||
- Durchführung des Globaltests zur Modellprüfung
|
||||
- Lokaltest und Maße der inneren Zuverlässigkeit
|
||||
- Berechnung von Kenngrößen der äußeren Zuverlässigkeit
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def gesamtredundanz(n, u):
|
||||
def gesamtredundanz(n: int, u: int) -> int:
|
||||
"""
|
||||
Berechnet die Gesamtredundanz des Netzes.
|
||||
|
||||
@@ -35,7 +46,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def berechne_R(Q_vv, P):
|
||||
def berechne_R(Q_vv: np.ndarray, P: np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Berechnet die Redundanzmatrix R aus Qvv und der Gewichtsmatrix P.
|
||||
|
||||
@@ -54,7 +65,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def berechne_ri(R):
|
||||
def berechne_ri(R: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Berechnet die Redundanzanteile einzelner Beobachtungen.
|
||||
|
||||
@@ -74,7 +85,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def klassifiziere_ri(ri):
|
||||
def klassifiziere_ri(ri: float) -> str:
|
||||
"""
|
||||
Klassifiziert einen Redundanzanteil rᵢ nach seiner Kontrollierbarkeit.
|
||||
|
||||
@@ -99,7 +110,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def redundanzanteile_ri(Qvv, P, liste_beob):
|
||||
def redundanzanteile_ri(Qvv: np.ndarray, P: np.ndarray, liste_beob: list[str]) -> tuple[np.ndarray, np.ndarray, np.ndarray, pd.DataFrame]:
|
||||
"""
|
||||
Berechnet und dokumentiert Redundanzanteile rᵢ und EVᵢ für alle Beobachtungen.
|
||||
|
||||
@@ -129,7 +140,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def globaltest(r_gesamt, sigma0_apost, sigma0_apriori=1):
|
||||
def globaltest(r_gesamt: int, sigma0_apost: float, sigma0_apriori: float = 1.0) -> dict[str, int | float | bool | str]:
|
||||
"""
|
||||
Führt den Globaltest zur Prüfung des Ausgleichungsmodells durch.
|
||||
|
||||
@@ -148,10 +159,8 @@ class Zuverlaessigkeit:
|
||||
:param sigma0_apriori: a-priori Standardabweichung der Gewichtseinheit σ₀ (Standard=1).
|
||||
:type sigma0_apriori: float
|
||||
:return: Dictionary mit Testparametern, Testergebnis (H₀ angenommen/verworfen) und Interpretation.
|
||||
:rtype: dict[str, Any]
|
||||
:raises ValueError: Wenn alpha nicht in (0, 1) liegt oder nicht in float umgewandelt werden kann.
|
||||
:rtype: dict[str, int | float | bool | str]
|
||||
"""
|
||||
|
||||
alpha_input = input("Irrtumswahrscheinlichkeit α wählen (z.B. 0.05, 0.01) [Standard=0.001]: ").strip()
|
||||
alpha = 0.001 if alpha_input == "" else float(alpha_input)
|
||||
T_G = (sigma0_apost ** 2) / (sigma0_apriori ** 2)
|
||||
@@ -193,40 +202,38 @@ class Zuverlaessigkeit:
|
||||
}
|
||||
|
||||
|
||||
def lokaltest_innere_Zuverlaessigkeit(v, Q_vv, ri, labels, s0_apost, alpha, beta):
|
||||
def lokaltest_innere_Zuverlaessigkeit(v: np.ndarray, Q_vv: np.ndarray, ri: np.ndarray, labels: list, sigma0_apost: float, alpha: float, beta: float) -> pd.DataFrame:
|
||||
"""
|
||||
Führt den Lokaltest zur Grobfehlerdetektion je Beobachtung durch.
|
||||
|
||||
Auf Basis der Residuen v, der Kofaktor-Matrix der Residuen Qvv und der Redundanzanteile rᵢ
|
||||
werden für jede Beobachtung statistische Kennwerte zur Detektion grober Fehler berechnet. Dazu zählen:
|
||||
|
||||
- Grobfehlerabschätzung: GFᵢ = − vᵢ / rᵢ
|
||||
- Standardabweichung der Residuen: s_vᵢ = s₀ · √q_vᵢ (mit q_vᵢ = diag(Qvv))
|
||||
- Normierte Verbesserung: NVᵢ = |vᵢ| / s_vᵢ
|
||||
- Nichtzentralitätsparameter: δ₀ = k + k_A
|
||||
mit k aus dem zweiseitigen Normalquantil (α) und k_A aus der Testmacht (1−β)
|
||||
- Grenzwert der Aufdeckbarkeit (Minimal detektierbarer Grobfehler): GRZWᵢ = (s_vᵢ / rᵢ) · δ₀
|
||||
- Grobfehlerabschätzung GFᵢ
|
||||
- Standardabweichung der Residuen s_vᵢ
|
||||
- Normierte Verbesserung NVᵢ
|
||||
- Nichtzentralitätsparameter δ₀ mit k aus dem zweiseitigen Normalquantil (α) und k_A aus der Testmacht (1−β)
|
||||
- Grenzwert der Aufdeckbarkeit (Minimal detektierbarer Grobfehler) GRZWᵢ
|
||||
|
||||
Beobachtungen werden als auffällig markiert, wenn NVᵢ > δ₀. Für rᵢ = 0 wird die Grobfehlerabschätzung
|
||||
und der Grenzwert als NaN gesetzt.
|
||||
|
||||
:param v: Residuenvektor der Beobachtungen.
|
||||
:type v: np.asarray
|
||||
:type v: np.ndarray
|
||||
:param Q_vv: Kofaktor-Matrix der Residuen.
|
||||
:type Q_vv: np.asarray
|
||||
:type Q_vv: np.ndarray
|
||||
:param ri: Redundanzanteile der Beobachtungen.
|
||||
:type ri: np.asarray
|
||||
:type ri: np.ndarray
|
||||
:param labels: Liste der Beobachtungen zur Zuordnung in der Ergebnistabelle.
|
||||
:type labels: list
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0_apost: float
|
||||
:param alpha: Irrtumswahrscheinlichkeit α (Signifikanzniveau, zweiseitiger Test).
|
||||
:type alpha: float
|
||||
:param beta: Wahrscheinlichkeit β für einen Fehler 2. Art (Testmacht = 1−β).
|
||||
:type beta: float
|
||||
:return: DataFrame mit NVᵢ, Auffälligkeit, Grobfehlerabschätzung GFᵢ und Grenzwert GRZWᵢ je Beobachtung.
|
||||
:rtype: pandas.DataFrame
|
||||
:raises ValueError: Wenn alpha oder beta nicht im Intervall (0, 1) liegen.
|
||||
"""
|
||||
v = np.asarray(v, float).reshape(-1)
|
||||
Q_vv = np.asarray(Q_vv, float)
|
||||
@@ -239,7 +246,7 @@ class Zuverlaessigkeit:
|
||||
|
||||
# Standardabweichungen der Residuen
|
||||
qv = np.diag(Q_vv).astype(float)
|
||||
s_vi = float(s0_apost) * np.sqrt(qv)
|
||||
s_vi = float(sigma0_apost) * np.sqrt(qv)
|
||||
|
||||
# Normierte Verbesserung NV
|
||||
NV = np.abs(v) / s_vi
|
||||
@@ -274,7 +281,7 @@ class Zuverlaessigkeit:
|
||||
return Lokaltest_innere_Zuv
|
||||
|
||||
|
||||
def aufruf_lokaltest(liste_beob, alpha, ausgabe_parameterschaetzung, ri, s0_aposteriori):
|
||||
def aufruf_lokaltest(liste_beob: list[str], alpha: float, ausgabe_parameterschaetzung: dict, ri: np.ndarray, sigma0_aposteriori: float) -> tuple[dict[str, bool], float]:
|
||||
"""Startet den Lokaltest und erzeugt die interaktive Tabelle.
|
||||
|
||||
:param liste_beob: Liste der Beobachtungslabels.
|
||||
@@ -284,9 +291,9 @@ class Zuverlaessigkeit:
|
||||
:param ausgabe_parameterschaetzung: Dictionary mit den Ergebnissen der letzten Iteration der Parameterschätzung.
|
||||
:type ausgabe_parameterschaetzung: dict
|
||||
:param ri: Redundanz.
|
||||
:type ri: Any
|
||||
:param s0_aposteriori: a-posteriori Standardabweichung.
|
||||
:type s0_aposteriori: float
|
||||
:type ri: np.ndarray
|
||||
:param sigma0_aposteriori: a-posteriori Standardabweichung.
|
||||
:type sigma0_aposteriori: float
|
||||
:return: ausschalten_dict
|
||||
:rtype: dict
|
||||
"""
|
||||
@@ -305,7 +312,7 @@ class Zuverlaessigkeit:
|
||||
Q_vv=ausgabe_parameterschaetzung["Q_vv"],
|
||||
ri=ri,
|
||||
labels=labels,
|
||||
s0_apost=s0_aposteriori,
|
||||
sigma0_apost=sigma0_aposteriori,
|
||||
alpha=alpha,
|
||||
beta=beta
|
||||
)
|
||||
@@ -345,36 +352,23 @@ class Zuverlaessigkeit:
|
||||
|
||||
|
||||
|
||||
def aeussere_zuverlaessigkeit(
|
||||
Lokaltest, bezeichnung, Qxx, A, P, s0_apost, unbekannten_liste, x,
|
||||
ausschliessen=("lA_",),
|
||||
):
|
||||
def aeussere_zuverlaessigkeit(Lokaltest: pd.DataFrame, bezeichnung: list, Qxx: np.ndarray, A: np.ndarray, P: np.ndarray, sigma0_apost: float, unbekannten_liste: list, x: np.ndarray, ausschliessen: tuple[str, ...] = ("lA_",)) -> pd.DataFrame:
|
||||
"""
|
||||
Berechnet Parameter der äußeren Zuverlässigkeit (EP/EF) je Beobachtung.
|
||||
|
||||
Auf Basis der Ergebnisse des Lokaltests werden für jede Beobachtung Maße der äußeren
|
||||
Zuverlässigkeit bestimmt. Dazu zählen:
|
||||
Auf Basis der Ergebnisse des Lokaltests werden für jede Beobachtung Maße der äußeren Zuverlässigkeit bestimmt. Dazu zählen:
|
||||
|
||||
- Einfluss auf die (relative) Punktlage EP:
|
||||
- aus geschätzter Modellstörung: EP_GF,i = |(1 - r_i) · GF_i|
|
||||
- aus Grenzwert der nicht mehr aufdeckbaren Modellstörung: EP_GRZW,i = |(1 - r_i) · GRZW_i|
|
||||
Für Winkelbeobachtungen (R/ZW) wird EP in eine äquivalente Querabweichung (in m) umgerechnet: q = EP · s
|
||||
wobei EP als Winkelstörung im Bogenmaß (rad) und s als räumliche Strecke zwischen Stand- und
|
||||
Zielpunkt verwendet wird.
|
||||
- Einflussfaktor / Netzverzerrung EF (Worst-Case-Einfluss einer nicht detektierten Störung):
|
||||
Es wird eine Einzelstörung Δl_i = GRZW_i angesetzt (alle anderen Δl_j = 0) und in den
|
||||
Unbekanntenraum übertragen: Δx = Q_xx · A^T · P · Δl
|
||||
Der Einflussfaktor wird lokal (nur für die von der Beobachtung berührten Punktkoordinaten,
|
||||
i.d.R. Stand- und Zielpunkt) über die gewichtete Norm berechnet: EF_i^2 = (Δx_loc^T · Q_loc^{-1} · Δx_loc) / s0^2
|
||||
mit s0 = a posteriori Standardabweichung der Gewichtseinheit.
|
||||
- Punktstreuungsmaß SP_3D und maximale Verfälschung EF·SP:
|
||||
Für die berührten Punkte wird je Punkt der 3×3-Block aus Q_xx betrachtet: als Maß wird die maximale Spur
|
||||
verwendet: SP_3D,loc = s0 · sqrt( max( tr(Q_P) ) )
|
||||
und daraus: (EF·SP)_i = EF_i · SP_3D,loc
|
||||
- Einfluss auf die Punktlage EP
|
||||
- aus geschätzter Modellstörung EP_GF,i
|
||||
- aus Grenzwert der nicht mehr aufdeckbaren Modellstörung EP_GRZW,i
|
||||
- Für Richtungs- und Winkelbeobachtungen erfolgt eine Umrechnung
|
||||
- Einflussfaktor EF
|
||||
- Es wird eine Einzelstörung Δl_i = GRZW_i angesetzt und in den Unbekanntenraum übertragen
|
||||
- Der Einflussfaktor wird lokal berechnet
|
||||
- Punktstreuungsmaß SP_3D und maximale Verfälschung EF·SP
|
||||
|
||||
Pseudobeobachtungen (z.B. Lagerungs-/Anschlussgleichungen) können über Präfixe in
|
||||
"ausschliessen" aus der Auswertung entfernt werden. Es wird geprüft, ob die Anzahl
|
||||
der Bezeichnungen und die Zeilenanzahl des Lokaltests zur Beobachtungsanzahl von A passen.
|
||||
"ausschliessen" aus der Auswertung entfernt werden.
|
||||
|
||||
:param Lokaltest: DataFrame des Lokaltests`.
|
||||
:type Lokaltest: pandas.DataFrame
|
||||
@@ -386,8 +380,8 @@ class Zuverlaessigkeit:
|
||||
:type A: numpy.ndarray
|
||||
:param P: Gewichtsmatrix der Beobachtungen.
|
||||
:type P: numpy.ndarray
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:param x: Unbekanntenvektor.
|
||||
@@ -395,7 +389,7 @@ class Zuverlaessigkeit:
|
||||
:param ausschliessen: Präfixe von Beobachtungsbezeichnungen, die aus der Auswertung entfernt werden sollen
|
||||
(Standard: ("lA_",) für Lagerungs-/Pseudobeobachtungen).
|
||||
:type ausschliessen: tuple
|
||||
:return: DataFrame mit Stand/Zielpunkt, Redundanzanteil rᵢ, EP (aus GF und GRZW), EF sowie SP_3D und EF·SP_3D.
|
||||
:return: DataFrame mit Stand/Zielpunkt, Redundanzanteil rᵢ, EP (aus GF und GRZW), EF, SP_3D und EF·SP_3D.
|
||||
:rtype: pandas.DataFrame
|
||||
:raises ValueError: Wenn die Anzahl der Bezeichnungen oder die Zeilenanzahl des Lokaltests nicht zu A passt.
|
||||
"""
|
||||
@@ -434,7 +428,7 @@ class Zuverlaessigkeit:
|
||||
ri = lokaltest_daten["r_i"].astype(float).to_numpy()
|
||||
GF = lokaltest_daten["GF_i"].astype(float).to_numpy()
|
||||
GRZW = lokaltest_daten["GRZW_i"].astype(float).to_numpy()
|
||||
s0 = float(s0_apost)
|
||||
s0 = float(sigma0_apost)
|
||||
|
||||
# Punktkoordinaten
|
||||
koordinaten = {}
|
||||
@@ -576,7 +570,7 @@ class LokaltestInnereZuverlaessigkeitGUI:
|
||||
einer Komponente (bx/by/bz) automatisch das gesamte Trio gewählt bzw. abgewählt wird.
|
||||
"""
|
||||
|
||||
def __init__(self, df):
|
||||
def __init__(self, df: pd.DataFrame) -> None:
|
||||
"""Initialisiert die GUI-Objekte.
|
||||
|
||||
:param df: DataFrame des Lokaltests (inkl. Spalte "Beobachtung").
|
||||
@@ -606,7 +600,7 @@ class LokaltestInnereZuverlaessigkeitGUI:
|
||||
self.btn_auswahl_zuruecksetzen = widgets.Button(description="Rückgängig", icon="refresh")
|
||||
|
||||
@staticmethod
|
||||
def gnss_komponenten_extrahieren(beobachtung: str):
|
||||
def gnss_komponenten_extrahieren(beobachtung: str) -> tuple[str | None, str | None]:
|
||||
"""Extrahiert GNSS-Komponente und einen eindeutigen Key für bx/by/bz-Trio.
|
||||
|
||||
:param beobachtung: Text aus Spalte "Beobachtung".
|
||||
|
||||
@@ -53,7 +53,8 @@ class Iterationen:
|
||||
self.fm = Funktionales_Modell.FunktionalesModell(self.pfad_datenbank, self.a, self.b, self.pfad_tif_quasigeoidundulation)
|
||||
|
||||
|
||||
def ausgleichung_global(self, A, dl, Q_ext, P):
|
||||
|
||||
def ausgleichung_global(self, A: np.ndarray, dl: np.ndarray, Q_ext: np.ndarray, P: np.ndarray) -> tuple[dict[str, np.ndarray], np.ndarray]:
|
||||
"""
|
||||
Führt eine Ausgleichung nach kleinsten Quadraten durch.
|
||||
|
||||
@@ -62,24 +63,23 @@ class Iterationen:
|
||||
|
||||
Es werden folgende Berechnungsschitte durchgeführt:
|
||||
|
||||
1) Normalgleichungsmatrix N = Aᵀ · P · A und Absolutglied n = Aᵀ · P · dl
|
||||
2) Lösung dx = N⁻¹ · n
|
||||
3) Residuen v = A · dx − dl
|
||||
4) Kofaktormatrix der Unbekannten Q_xx
|
||||
5) Kofaktormatrix der ausgeglichenen Beobachtungen Q_ll_dach
|
||||
6) Kofaktormatrix der Verbesserungen Q_vv
|
||||
- Normalgleichungsmatrix N und Absolutgliedvektor n
|
||||
- Zuschlagsvektor dx
|
||||
- Residuenvektor v
|
||||
- Kofaktormatrix der Unbekannten Q_xx
|
||||
- Kofaktormatrix der ausgeglichenen Beobachtungen Q_ll_dach
|
||||
- Kofaktormatrix der Verbesserungen Q_vv
|
||||
|
||||
:param A: Jacobi-Matrix (A-Matrix).
|
||||
:type A: array_like
|
||||
:type A: np.ndarray
|
||||
:param dl: Verbesserungsvektor bzw. Beobachtungsabweichungen.
|
||||
:type dl: array_like
|
||||
:type dl: np.ndarray
|
||||
:param Q_ext: a-priori Kofaktormatrix der Beobachtungen.
|
||||
:type Q_ext: array_like
|
||||
:type Q_ext: np.ndarray
|
||||
:param P: Gewichtsmatrix der Beobachtungen.
|
||||
:type P: array_like
|
||||
:type P: np.ndarray
|
||||
:return: Dictionary mit Ausgleichungsergebnissen, Zuschlagsvektor dx.
|
||||
:rtype: tuple[dict[str, Any], numpy.ndarray]
|
||||
:raises numpy.linalg.LinAlgError: Wenn das Normalgleichungssystem singulär ist und nicht gelöst werden kann.
|
||||
:rtype: tuple[dict[str, numpy.ndarray], np.ndarray]
|
||||
"""
|
||||
A = np.asarray(A, float)
|
||||
dl = np.asarray(dl, float).reshape(-1, 1)
|
||||
|
||||
18
Proben.py
18
Proben.py
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
|
||||
def atpv_probe(A, P, v, tol=1e-7):
|
||||
def atpv_probe(A: np.ndarray, P: np.ndarray, v: np.ndarray, tol: float = 1e-7) -> None:
|
||||
"""
|
||||
Führt die ATPv-Probe zur Kontrolle der Lösung des Normalgleichungssystems durch.
|
||||
|
||||
@@ -8,11 +8,11 @@ def atpv_probe(A, P, v, tol=1e-7):
|
||||
Die Prüfung erfolgt unter Verwendung einer vorgegebenen Toleranz.
|
||||
|
||||
:param A: Jacobi-Matrix (A-Matrix).
|
||||
:type A: np.asarray
|
||||
:type A: np.ndarray
|
||||
:param P: Gewichtsmatrix der Beobachtungen.
|
||||
:type P: np.asarray
|
||||
:type P: np.ndarray
|
||||
:param v: Residuenvektor der Beobachtungen.
|
||||
:type v: np.asarray
|
||||
:type v: np.ndarray
|
||||
:param tol: Absolute Toleranz für den Vergleich mit Null.
|
||||
:type tol: float
|
||||
:return: None
|
||||
@@ -30,7 +30,7 @@ def atpv_probe(A, P, v, tol=1e-7):
|
||||
print("❌ ATPv-Probe nicht erfolgreich. Fehler bei der Lösung des Normalgleichungssystems")
|
||||
|
||||
|
||||
def hauptprobe(A, x, l, v, tol=1e-7):
|
||||
def hauptprobe(A: np.ndarray, x: np.ndarray, l: np.ndarray, v: np.ndarray, tol: float = 1e-7) -> None:
|
||||
"""
|
||||
Führt die Hauptprobe zur Überprüfung der berechneten Residuen durch.
|
||||
|
||||
@@ -40,13 +40,13 @@ def hauptprobe(A, x, l, v, tol=1e-7):
|
||||
innerhalb der Toleranz überein, gilt die Ausgleichung als konsistent.
|
||||
|
||||
:param A: Jacobi-Matrix (A-Matrix).
|
||||
:type A: np.asarray
|
||||
:type A: np.ndarray
|
||||
:param x: Lösungsvektor der Unbekannten.
|
||||
:type x: np.asarray
|
||||
:type x: np.ndarray
|
||||
:param l: Beobachtungsvektor.
|
||||
:type l: np.asarray
|
||||
:type l: np.ndarray
|
||||
:param v: Residuenvektor aus der Ausgleichung.
|
||||
:type v: np.asarray
|
||||
:type v: np.ndarray
|
||||
:param tol: Absolute Toleranz für den Vergleich der Residuen.
|
||||
:type tol: float
|
||||
:return: None
|
||||
|
||||
@@ -205,7 +205,7 @@ class StochastischesModell:
|
||||
Export.matrix_to_csv(r"Zwischenergebnisse\Qll_Symbolisch.csv", liste_beobachtungen_symbolisch, liste_beobachtungen_symbolisch, Qll, "Qll")
|
||||
return Qll
|
||||
|
||||
def Qll_numerisch(self, Qll_Matrix_Symbolisch: sp.Matrix, liste_beobachtungen_symbolisch: list) -> np.asarray:
|
||||
def Qll_numerisch(self, Qll_Matrix_Symbolisch: sp.Matrix, liste_beobachtungen_symbolisch: list) -> np.ndarray:
|
||||
"""Erstellt eine numerische Kofaktormatrix der Beobachtungen aus einer symbolischen Qll-Matrix.
|
||||
|
||||
Es werden die zur Substitution benötigten Werte aus der Datenbank abgefragt und den in Qll vorkommenden Symbolen zugeordnet,
|
||||
@@ -228,7 +228,7 @@ class StochastischesModell:
|
||||
:param liste_beobachtungen_symbolisch: Liste der symbolischen Beobachtungskennungen.
|
||||
:type liste_beobachtungen_symbolisch: list
|
||||
:return: Numerische Kofaktormatrix Qll als Numpy-Array.
|
||||
:rtype: np.asarray
|
||||
:rtype: np.ndarray
|
||||
:raises ValueError: Falls Symbole in Qll_Matrix_Symbolisch enthalten sind, für die keine Substitutionen vorhanden sind.
|
||||
"""
|
||||
liste_beobachtungen_symbolisch = [str(b).strip() for b in liste_beobachtungen_symbolisch]
|
||||
@@ -381,7 +381,7 @@ class StochastischesModell:
|
||||
|
||||
return Qll_numerisch
|
||||
|
||||
def QAA_symbolisch(self, liste_beobachtungen_symbolisch: list) -> np.asarray:
|
||||
def QAA_symbolisch(self, liste_beobachtungen_symbolisch: list) -> np.ndarray:
|
||||
"""Erstellt die symbolische Kofaktormatrix der Anschlusspunkte (weiche Lagerung).
|
||||
|
||||
Es werden ausschließlich Beobachtungen berücksichtigt, deren Kennung mit "lA_" beginnt. Für jede Anschlussbedingung
|
||||
@@ -421,7 +421,7 @@ class StochastischesModell:
|
||||
Export.matrix_to_csv(r"Zwischenergebnisse\QAA_Symbolisch.csv", liste_beobachtungen_symbolisch, liste_beobachtungen_symbolisch, Qll, "Qll")
|
||||
return Qll
|
||||
|
||||
def QAA_numerisch(self, QAA_Matrix_Symbolisch: sp.Matrix, liste_beobachtungen_symbolisch: list) -> np.asarray:
|
||||
def QAA_numerisch(self, QAA_Matrix_Symbolisch: sp.Matrix, liste_beobachtungen_symbolisch: list) -> np.ndarray:
|
||||
"""Erstellt eine numerische Matrix aus einer symbolischen QAA-Matrix.
|
||||
|
||||
Es werden die numerischen Standardabweichungen der Anschlussbedingungen sowie die Varianzkomponente der Gruppe
|
||||
@@ -435,7 +435,7 @@ class StochastischesModell:
|
||||
:param liste_beobachtungen_symbolisch: Liste der symbolischen Beobachtungskennungen.
|
||||
:type liste_beobachtungen_symbolisch: list
|
||||
:return: Numerische VKofaktormatrix QAA als Numpy-Array.
|
||||
:rtype: np.asarray
|
||||
:rtype: np.ndarray
|
||||
"""
|
||||
# Symbolische Listen
|
||||
liste_beobachtungen_symbolisch = [str(b).strip() for b in liste_beobachtungen_symbolisch]
|
||||
|
||||
@@ -42,12 +42,12 @@ class VKS:
|
||||
|
||||
self.db_zugriff = Datenbank.Datenbankzugriff(self.pfad_datenbank)
|
||||
|
||||
def varianzkomponten_berechnen(self, Jacobimatrix_symbolisch_liste_beobachtungsvektor: list, res: dict, R: np.asarray) -> pd.DataFrame:
|
||||
def varianzkomponten_berechnen(self, Jacobimatrix_symbolisch_liste_beobachtungsvektor: list, res: dict, R: np.ndarray) -> pd.DataFrame:
|
||||
"""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
|
||||
Beobachtungsgruppe wird die Redundanz ri = Spur(R_i) gebildet und daraus sigma0_aposteriori
|
||||
berechnet.
|
||||
|
||||
Unterstützte Gruppenkennungen: "SD", "R", "ZW", "gnss", "niv", "lA".
|
||||
@@ -57,7 +57,7 @@ class VKS:
|
||||
: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.asarray
|
||||
:type R: np.ndarray
|
||||
:return: DataFrame mit den Spalten 'Beobachtungsgruppe', 'Standardabweichung', 'Varianz'
|
||||
:rtype: pd.DataFrame
|
||||
"""
|
||||
@@ -80,10 +80,10 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_SD, aufgeteilt_P_SD, ri_SD, False)
|
||||
sigma0_aposteriori_SD = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_SD, aufgeteilt_P_SD, ri_SD, False)
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_SD,
|
||||
"Varianz a posteriori": s0_aposteriori_SD ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_SD,
|
||||
"Varianz a posteriori": sigma0_aposteriori_SD ** 2})
|
||||
|
||||
# R = Tachymeter Richtungsbeobachtungen
|
||||
if beobachtungsgruppe == "R":
|
||||
@@ -92,10 +92,10 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_R, aufgeteilt_P_R, ri_R, False)
|
||||
sigma0_aposteriori_R = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_R, aufgeteilt_P_R, ri_R, False)
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_R,
|
||||
"Varianz a posteriori": s0_aposteriori_R ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_R,
|
||||
"Varianz a posteriori": sigma0_aposteriori_R ** 2})
|
||||
|
||||
# ZW = Tachymeter Zenitwinkelbeobachtung
|
||||
if beobachtungsgruppe == "ZW":
|
||||
@@ -104,10 +104,10 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_ZW, aufgeteilt_P_ZW, ri_ZW, False)
|
||||
sigma0_aposteriori_ZW = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_ZW, aufgeteilt_P_ZW, ri_ZW, False)
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_ZW,
|
||||
"Varianz a posteriori": s0_aposteriori_ZW ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_ZW,
|
||||
"Varianz a posteriori": sigma0_aposteriori_ZW ** 2})
|
||||
|
||||
# GNSS = GNSS-Basisilinien
|
||||
if beobachtungsgruppe == "gnss":
|
||||
@@ -116,10 +116,10 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_gnss, aufgeteilt_P_gnss, ri_gnss, False)
|
||||
sigma0_aposteriori_gnss = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_gnss, aufgeteilt_P_gnss, ri_gnss, False)
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_gnss,
|
||||
"Varianz a posteriori": s0_aposteriori_gnss ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_gnss,
|
||||
"Varianz a posteriori": sigma0_aposteriori_gnss ** 2})
|
||||
|
||||
# niv = geometrisches Nivellement
|
||||
if beobachtungsgruppe == "niv":
|
||||
@@ -128,10 +128,10 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_niv, aufgeteilt_P_niv, ri_niv, False)
|
||||
sigma0_aposteriori_niv = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_niv, aufgeteilt_P_niv, ri_niv, False)
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_niv,
|
||||
"Varianz a posteriori": s0_aposteriori_niv ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_niv,
|
||||
"Varianz a posteriori": sigma0_aposteriori_niv ** 2})
|
||||
|
||||
# lA = Anschlusspunkte für die weiche Lagerung
|
||||
if beobachtungsgruppe == "lA":
|
||||
@@ -140,11 +140,11 @@ class VKS:
|
||||
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_sigma0apost(aufgeteilt_v_lA, aufgeteilt_P_lA, ri_lA, False)
|
||||
sigma0_aposteriori_lA = Genauigkeitsmaße.berechne_sigma0apost(aufgeteilt_v_lA, aufgeteilt_P_lA, ri_lA, False)
|
||||
# Speichern in Instanzvariable
|
||||
liste_ergebnisse.append(
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": s0_aposteriori_lA,
|
||||
"Varianz a posteriori": s0_aposteriori_lA ** 2})
|
||||
{"Beobachtungsgruppe": beobachtungsgruppe_lang, "Standardabweichung a posteriori": sigma0_aposteriori_lA,
|
||||
"Varianz a posteriori": sigma0_aposteriori_lA ** 2})
|
||||
|
||||
self.liste_ergebnisse = liste_ergebnisse
|
||||
df_varianzkomponenten = pd.DataFrame(self.liste_ergebnisse)
|
||||
|
||||
Reference in New Issue
Block a user