- Deleted docs/figures/v{1,2,3}.figures.json
- Backend already supports fetching from HuggingFace raw links
- Updated test to prevent remote fetch in fallback scenario
- All 98 tests passing
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Serve /api/{version}/figures.json with normalized name/tags/location/url, load manifest in MetricsPanel, and render/search figures from manifest (name/tags/location) with fallback behavior. Add tests and generated v1/v2/v3 figure manifests under docs/figures.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switch visualize metrics/figures to local-first with Hugging Face raw fallback, harden MetricsPanel hook usage/field handling, and refactor tests into feature-based folders with expanded API/router/data/model coverage. Add pytest config and dependency updates.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: v3 models trained with [FEATURE_COLS_SCALAR + capacity_retention,
cumulative_energy, dRe_dn, dRct_dn, soh_rolling_mean, voltage_slope] ordering,
NOT the CSV column order. soh_rolling_mean was a training feature (not excluded).
Changes:
- model_registry: add V3_FEATURE_COLS constant (18 features, correct order)
- model_registry: _load_feature_cols() returns V3_FEATURE_COLS for v3 (verified
against v3_features_standard.joblib scaler means)
- model_registry: _build_sequence_array() now TRUNCATES to n_feat when deep model
expects fewer features than registry feature_cols (v3 deep=12, registry=18)
- model_registry: predict() normalizes version to registry major (1.0.0/2.0.0/3.0.0)
- simulate: _build_feature_matrix builds 18-column X in registry.feature_cols order
- simulate: computes physics estimates for all 6 extra v3 features:
capacity_retention, cumulative_energy, dRe_dn, dRct_dn, soh_rolling_mean, voltage_slope
- All v3 models now predict correctly: RF R2=0.9814, X…
fix: predict_array zero-pads X to model n_features_in_, normalize versions to registry
- model_registry: predict_array() now calls _pad_X(X, model) before predict:
pads from 12 to n_features_in_ (18 for v3) using np.pad with zeros.
The 6 extra v3 features (coulombic_efficiency, capacity_retention, etc.) are
derived from historical cycles and aren't available during simulation, so
zero-padding is the correct approach and matches how the models handle
unseen feature distributions at the edges.
Applied to both best_ensemble per-component dispatch and single model path.
- model_registry: list_models() now normalizes version strings to registry
major version: if a model's version major differs from the registry (v1/v2/v3),
it is rewritten to {reg_major}.0.0.
Effect: v3 registry shows all models as 3.0.0 (not 2.4.0, 2.1.0 etc),
v2 registry shows 2.0.0, v1 shows 1.0.0 for legacy models.
This reflects that models are retrained/reconfigured per registry version.
fix: remaining v3 bugs - TFT n_feat detection, simulate URL, features from artifacts
- model_registry: _detect_n_feat now checks var_selection.softmax_proj.bias FIRST
(before lstm.weight_ih_l0) so TFT detection is correct: TFT's LSTM input is
d_model (64) not n_features, so the old order returned 64 instead of 12/18,
causing Missing key errors for feature_embeddings.12..63 on every boot
- model_registry: add _NON_FEATURE_COLS constant for CSV-to-feature filtering
- model_registry: add self.feature_cols (populated by load_all -> _load_feature_cols)
- model_registry: _load_feature_cols() reads battery_features.csv from
artifacts/{version}/features/, strips non-feature columns, validates against
scaler.n_features_in_; falls back to FEATURE_COLS_SCALAR for v1/v2/missing
- model_registry: _build_x now uses self.feature_cols (18 for v3, 12 for v1/v2)
so v3 classical models (all retrained with 18 features) get correct input
- api.ts: fix /api/api/v3/simulate -> /v3/simulate (baseApi already has /api prefix,
so prepending /api caused double prefix and 405 on ever…
- model_registry: add _detect_n_feat() to read input dim from PyTorch checkpoint
so v3 deep models (18 features) load without size-mismatch errors
- model_registry: _build_pytorch_model() now accepts n_feat param (was hardcoded to 12)
- model_registry: store n_feat in model_meta after successful PyTorch load
- model_registry: _build_sequence_array/_build_sequence_tensor accept n_feat and
zero-pad the 12-feature input to match each model's expected feature count
- model_registry: predict() reads stored n_feat for deep_pytorch, derives it from
model.input_shape[-1] for deep_keras
- model_registry: model_count now returns len(self.models) (loaded only, not failed)
- api.ts: simulateBatteries() now calls /api/v3/simulate (was /api/v2/simulate which
returned 405 because the simulate router lives under /api/v3)
fix: use ASCII arrow in upload script (Windows cp1252 compatibility)
Full source commit (clean history, no LFS):
- Models stored in HF Hub (NeerajCodz/aiBatteryLifeCycle), not in git
- Docker startup: download_models.py fetches from HF Hub before uvicorn
- simulate.py: vectorized ML prediction, batchable for all tree/ensemble models
- GraphPanel, MetricsPanel, RecommendationPanel: full dashboard rewrites
- lucide-react icons, recharts analytics, interactive controls
- BestEnsemble v2.6 (RF+XGB+LGB weighted), no v3 generation
- download_models.py: checks for 3 key component models (rf/xgb/lgb) not just sentinel