Spaces:
Runtime error
Runtime error
Download format_detector.py from happynickamazon/zenvolt-api: direct link, hf CLI and curl.
- Browser
- Download file 6.8 kB
-
https://huggingface.co/spaces/happynickamazon/zenvolt-api/resolve/main/format_detector.py
- Command line
-
hf download hf://spaces/happynickamazon/zenvolt-api/format_detector.py
-
curl -L -o format_detector.py https://huggingface.co/spaces/happynickamazon/zenvolt-api/resolve/main/format_detector.py
6.8 kB
| """ | |
| Battery Data Format Detector | |
| Auto-detects NASA vs Stanford format with validation. | |
| MIT/Stanford Quality: Robust format detection with confidence scoring. | |
| """ | |
| import pandas as pd | |
| import numpy as np | |
| from typing import Literal, Dict | |
| def detect_battery_format( | |
| data: pd.DataFrame, | |
| confidence_threshold: float = 0.8 | |
| ) -> Dict[str, any]: | |
| """ | |
| Automatically detect battery data format (NASA vs Stanford). | |
| NASA format: cycle_index, voltage, current, temperature, capacity | |
| Stanford format: 99 columns of voltage discharge curve values | |
| Parameters: | |
| ----------- | |
| data : DataFrame | |
| Battery data to detect format | |
| confidence_threshold : float | |
| Minimum confidence required (default 0.8) | |
| Returns: | |
| -------- | |
| dict: { | |
| 'format': 'nasa' | 'stanford' | 'unknown', | |
| 'confidence': float, | |
| 'reason': str, | |
| 'details': dict | |
| } | |
| """ | |
| detection_scores = { | |
| 'nasa': 0.0, | |
| 'stanford': 0.0 | |
| } | |
| details = { | |
| 'columns': list(data.columns), | |
| 'shape': data.shape, | |
| 'column_count': len(data.columns) | |
| } | |
| # Check 1: Column names | |
| nasa_required_cols = {'cycle_index', 'voltage', 'current', 'temperature', 'capacity'} | |
| nasa_cols_present = sum(1 for col in nasa_required_cols if col in data.columns) | |
| if nasa_cols_present == 5: | |
| detection_scores['nasa'] += 0.5 # Strong indicator | |
| elif nasa_cols_present >= 3: | |
| detection_scores['nasa'] += 0.3 # Moderate indicator | |
| # Check 2: Column count | |
| # Stanford has exactly 99 columns (voltage measurements) | |
| if len(data.columns) == 99: | |
| detection_scores['stanford'] += 0.4 | |
| elif len(data.columns) > 50: # Likely voltage array | |
| detection_scores['stanford'] += 0.2 | |
| if len(data.columns) == 5: | |
| detection_scores['nasa'] += 0.3 | |
| # Check 3: Data patterns | |
| # Stanford values are small (voltage deltas, typically < 0.01) | |
| # NASA values are absolute (voltage 3-4V, current 0-2A, etc.) | |
| if len(data.columns) > 0: | |
| first_col_values = data.iloc[:, 0].dropna() | |
| if len(first_col_values) > 0: | |
| first_col_mean = abs(first_col_values.mean()) | |
| first_col_max = abs(first_col_values.max()) | |
| # Stanford: small values (voltage deltas) | |
| if first_col_max < 0.01: | |
| detection_scores['stanford'] += 0.3 | |
| # NASA: larger values (cycle indices or voltages) | |
| if first_col_max > 1.0: | |
| detection_scores['nasa'] += 0.2 | |
| # Check 4: Row count | |
| # Stanford typically has ~1000 cycles per cell | |
| # NASA typically has ~168 cycles | |
| if len(data) > 500: | |
| detection_scores['stanford'] += 0.1 | |
| elif len(data) < 300: | |
| detection_scores['nasa'] += 0.1 | |
| # Determine format | |
| max_score = max(detection_scores['nasa'], detection_scores['stanford']) | |
| if detection_scores['nasa'] > detection_scores['stanford'] and detection_scores['nasa'] >= confidence_threshold: | |
| format_type = 'nasa' | |
| confidence = detection_scores['nasa'] | |
| reason = f"NASA format detected: {nasa_cols_present}/5 required columns present" | |
| elif detection_scores['stanford'] > detection_scores['nasa'] and detection_scores['stanford'] >= confidence_threshold: | |
| format_type = 'stanford' | |
| confidence = detection_scores['stanford'] | |
| reason = f"Stanford format detected: {len(data.columns)} columns (matrix format)" | |
| else: | |
| format_type = 'unknown' | |
| confidence = max_score | |
| reason = f"Format uncertain: NASA score={detection_scores['nasa']:.2f}, Stanford score={detection_scores['stanford']:.2f}" | |
| details['detection_scores'] = detection_scores | |
| return { | |
| 'format': format_type, | |
| 'confidence': confidence, | |
| 'reason': reason, | |
| 'details': details | |
| } | |
| def validate_format(data: pd.DataFrame, expected_format: str) -> Dict: | |
| """ | |
| Validate that data matches expected format. | |
| Parameters: | |
| ----------- | |
| data : DataFrame | |
| Battery data | |
| expected_format : str | |
| 'nasa' or 'stanford' | |
| Returns: | |
| -------- | |
| dict: Validation results | |
| """ | |
| errors = [] | |
| warnings = [] | |
| if expected_format == 'nasa': | |
| # Check required columns | |
| required = ['cycle_index', 'voltage', 'current', 'temperature', 'capacity'] | |
| missing = [col for col in required if col not in data.columns] | |
| if missing: | |
| errors.append(f"Missing required columns: {missing}") | |
| # Check value ranges | |
| if 'voltage' in data.columns: | |
| v_min, v_max = data['voltage'].min(), data['voltage'].max() | |
| if v_min < 0 or v_max > 5: | |
| warnings.append(f"Unusual voltage range: {v_min:.2f}-{v_max:.2f}V") | |
| if 'capacity' in data.columns: | |
| if data['capacity'].min() < 0: | |
| errors.append("Negative capacity values found") | |
| elif expected_format == 'stanford': | |
| # Check column count | |
| if len(data.columns) != 99: | |
| warnings.append(f"Expected 99 columns, got {len(data.columns)}") | |
| # Check value ranges (should be small voltage deltas) | |
| max_abs_value = abs(data.values).max() | |
| if max_abs_value > 0.1: | |
| warnings.append(f"Values seem large for Stanford format: max={max_abs_value:.4f}") | |
| is_valid = len(errors) == 0 | |
| return { | |
| 'is_valid': is_valid, | |
| 'errors': errors, | |
| 'warnings': warnings | |
| } | |
| if __name__ == "__main__": | |
| # Test format detection | |
| print("Testing format detector...") | |
| # Test NASA format | |
| print("\n1. NASA B0005:") | |
| nasa_data = pd.read_csv('./data/nasa_converted/B0005.csv') | |
| result = detect_battery_format(nasa_data) | |
| print(f" Format: {result['format']}") | |
| print(f" Confidence: {result['confidence']:.2f}") | |
| print(f" Reason: {result['reason']}") | |
| # Test Stanford format | |
| print("\n2. Stanford cell1 (original):") | |
| stanford_data = pd.read_csv('./data/stanford/cell1.csv', header=None) | |
| result = detect_battery_format(stanford_data) | |
| print(f" Format: {result['format']}") | |
| print(f" Confidence: {result['confidence']:.2f}") | |
| print(f" Reason: {result['reason']}") | |
| # Test Stanford converted | |
| print("\n3. Stanford cell1 (converted):") | |
| stanford_converted = pd.read_csv('./data/stanford_converted/cell1.csv') | |
| result = detect_battery_format(stanford_converted) | |
| print(f" Format: {result['format']}") | |
| print(f" Confidence: {result['confidence']:.2f}") | |
| print(f" Reason: {result['reason']}") | |
| print("\n✅ Format detector test complete!") | |