Refactor CANveyor dashboard architecture
- Replace `stats.utils.extractor` with dedicated `loader` and `converter` modules to improve code organization. - Implement explicit pipeline stages for ingestion, decoding, and precomputation with caching. - Standardize data loading and J1939 parsing logic across sub-modules. - Enhance dashboard responsiveness by pre-calculating figures and downsampling ID-grouped data. - Enforce strict typing and add docstrings to public components.
This commit is contained in:
+9
-10
@@ -1,25 +1,23 @@
|
||||
# File: correlation.py
|
||||
# File: stats/correlation.py
|
||||
# Copyright (C) 2026 Erick Ahmed
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
"""CAN bus inter-byte correlation analyzer and plotter."""
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import plotly.graph_objects as go
|
||||
|
||||
from stats.utils.extractor import load_data
|
||||
from stats.utils.extractor import to_int
|
||||
from stats.utils.converter import format_can_id_vec as _format_can_id_vec, to_int
|
||||
from stats.utils.loader import load_data
|
||||
|
||||
def _format_can_id_vec(s: pd.Series) -> pd.Series:
|
||||
s = s.astype('string').str.strip()
|
||||
s = s.str.replace(r'^0x', '', case=False, regex=True)
|
||||
s = s.str.upper()
|
||||
return s.fillna('UNKNOWN').replace('', 'UNKNOWN')
|
||||
|
||||
def _ensure_int_bytes(df: pd.DataFrame, cols: list) -> pd.DataFrame:
|
||||
def _ensure_int_bytes(df: pd.DataFrame, cols: List[str]) -> pd.DataFrame:
|
||||
needs = [c for c in cols if not pd.api.types.is_numeric_dtype(df[c])]
|
||||
if needs:
|
||||
df = df.copy()
|
||||
@@ -27,6 +25,7 @@ def _ensure_int_bytes(df: pd.DataFrame, cols: list) -> pd.DataFrame:
|
||||
df[c] = df[c].apply(to_int)
|
||||
return df
|
||||
|
||||
|
||||
def calculate_correlation(df: pd.DataFrame, method: str, target_id: str | None = None) -> pd.DataFrame:
|
||||
available_cols = [f"b{i}" for i in range(8) if f"b{i}" in df.columns]
|
||||
|
||||
@@ -70,7 +69,7 @@ def calculate_correlation(df: pd.DataFrame, method: str, target_id: str | None =
|
||||
else:
|
||||
groups = []
|
||||
|
||||
def _process_group(sub):
|
||||
def _process_group(sub: np.ndarray) -> np.ndarray:
|
||||
mask = ~np.isnan(sub).any(axis=1)
|
||||
sub = sub[mask]
|
||||
if len(sub) > 1:
|
||||
|
||||
Reference in New Issue
Block a user