Add artifact.1/src/artifact_1/core.py
This commit is contained in:
commit
25a5c9f1fb
1 changed files with 83 additions and 0 deletions
83
artifact.1/src/artifact_1/core.py
Normal file
83
artifact.1/src/artifact_1/core.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class SignalData:
|
||||
"""Repräsentiert eine Zeile der FM-Signaldaten."""
|
||||
|
||||
timestamp: str
|
||||
frequency_MHz: float
|
||||
signal_dB: float
|
||||
noise_dB: float
|
||||
lat: float
|
||||
lon: float
|
||||
|
||||
@staticmethod
|
||||
def validate(row: pd.Series) -> bool:
|
||||
required_columns = [
|
||||
'timestamp', 'frequency_MHz', 'signal_dB', 'noise_dB', 'lat', 'lon'
|
||||
]
|
||||
for col in required_columns:
|
||||
if col not in row or pd.isna(row[col]):
|
||||
logger.warning("Fehlender oder ungültiger Wert in Spalte '%s'", col)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def generate_signal_plot(csv_file: str) -> Figure:
|
||||
"""Liest ein CSV mit FM-Signaldaten und erzeugt einen Frequenz-vs-Signal-Plot.
|
||||
|
||||
Args:
|
||||
csv_file (str): Pfad zur CSV-Datei mit Spalten 'frequency_MHz' und 'signal_dB'.
|
||||
|
||||
Returns:
|
||||
matplotlib.figure.Figure: Eine Figure mit dem visualisierten Frequenzspektrum.
|
||||
"""
|
||||
csv_path = Path(csv_file)
|
||||
if not csv_path.exists() or not csv_path.is_file():
|
||||
raise FileNotFoundError(f"Eingabedatei nicht gefunden: {csv_file}")
|
||||
|
||||
logger.debug("Lese CSV-Datei: %s", csv_path)
|
||||
df = pd.read_csv(csv_path)
|
||||
|
||||
required_cols = {'frequency_MHz', 'signal_dB'}
|
||||
if not required_cols.issubset(df.columns):
|
||||
raise ValueError(
|
||||
f"CSV-Datei muss Spalten {required_cols} enthalten, gefunden: {set(df.columns)}"
|
||||
)
|
||||
|
||||
# Input validation pro Row, falls Spalten vorhanden sind
|
||||
valid_mask = df.apply(SignalData.validate, axis=1)
|
||||
df_valid = df[valid_mask]
|
||||
|
||||
if df_valid.empty:
|
||||
raise ValueError("Keine gültigen Datenzeilen gefunden nach Validierung.")
|
||||
|
||||
# Sortieren nach Frequenz, um sauberen Plot zu gewährleisten
|
||||
df_sorted = df_valid.sort_values(by='frequency_MHz')
|
||||
|
||||
logger.debug("Erstelle Plot (%d Werte)...", len(df_sorted))
|
||||
fig, ax = plt.subplots(figsize=(10, 5))
|
||||
ax.plot(df_sorted['frequency_MHz'], df_sorted['signal_dB'], label='Signal (dB)', color='tab:blue')
|
||||
ax.set_xlabel('Frequency [MHz]')
|
||||
ax.set_ylabel('Signal Strength [dB]')
|
||||
ax.set_title('FM Spectrum Analysis')
|
||||
ax.grid(True, linestyle='--', alpha=0.7)
|
||||
ax.legend()
|
||||
|
||||
fig.tight_layout()
|
||||
logger.info("Plot erfolgreich erzeugt für Datei: %s", csv_file)
|
||||
|
||||
return fig
|
||||
Loading…
Reference in a new issue