""" Base parser class for oscilloscope data parsers. """ from abc import ABC, abstractmethod from typing import Dict, List, Optional import numpy as np from .data import ScopeData, ChannelData class BaseOscilloscopeParser(ABC): """Base class for oscilloscope data parsers.""" @abstractmethod def parse(self, file_path: str) -> ScopeData: """Parse oscilloscope data from file.""" pass @abstractmethod def can_parse(self, file_path: str) -> bool: """Check if this parser can handle the given file.""" pass def _extract_time_interval(self, metadata: Dict[str, str]) -> float: """Extract time interval between samples in seconds.""" # Default implementation - can be overridden by subclasses interval_str = metadata.get("Time interval", "") if interval_str: if "uS" in interval_str: return float(interval_str.replace("uS", "")) * 1e-6 elif "nS" in interval_str: return float(interval_str.replace("nS", "")) * 1e-9 elif "mS" in interval_str: return float(interval_str.replace("mS", "")) * 1e-3 elif "S" in interval_str: return float(interval_str.replace("S", "")) return 1e-6 # Default to 1 µs def _extract_frequency(self, metadata: Dict[str, str]) -> Optional[float]: """Extract frequency from metadata if available.""" freq_str = metadata.get("Frequency", "") if freq_str.startswith("F="): # Extract frequency value and convert units freq_value = freq_str[2:] if "kHz" in freq_value: return float(freq_value.replace("kHz", "")) * 1000 elif "Hz" in freq_value: return float(freq_value.replace("Hz", "")) return None def _extract_vpp(self, metadata: Dict[str, str]) -> Optional[float]: """Extract peak-to-peak voltage from metadata.""" pp_str = metadata.get("PK-PK", "") if pp_str.startswith("Vpp="): value = float(pp_str[4:].replace("mV", "").replace("V", "")) # Convert mV to V if needed if "mV" in pp_str: return value / 1000.0 return value return None def _extract_average(self, metadata: Dict[str, str]) -> Optional[float]: """Extract average voltage from metadata.""" avg_str = metadata.get("Average", "") if avg_str.startswith("V="): value = float(avg_str[2:].replace("mV", "").replace("V", "")) # Convert mV to V if needed if "mV" in avg_str: return value / 1000.0 return value return None