simple-scope-parser/scope_parser/base_parser.py

73 lines
2.7 KiB
Python

"""
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