""" Parser for OWON oscilloscope CSV files. """ import csv from typing import Dict, List import numpy as np from .base_parser import BaseOscilloscopeParser from .data import ScopeData, ChannelData class OwonParser(BaseOscilloscopeParser): """Parser for OWON oscilloscope CSV files.""" def can_parse(self, file_path: str) -> bool: """Check if file is from OWON scope.""" try: with open(file_path, "r") as f: first_lines = [f.readline().strip() for _ in range(10)] # Look for OWON-specific patterns return any("Channel" in line and "CH" in line for line in first_lines) except: return False def parse(self, file_path: str) -> ScopeData: """Parse OWON oscilloscope CSV file.""" with open(file_path, "r") as f: # Read header metadata metadata_lines = [] data_start_line = 0 for i, line in enumerate(f): line = line.strip() if not line: # Empty line indicates end of metadata data_start_line = i + 1 break metadata_lines.append(line) # Parse metadata metadata = self._parse_metadata(metadata_lines) # Reset file pointer to data section f.seek(0) for _ in range(data_start_line): next(f) # Parse CSV data reader = csv.DictReader(f) # Extract data columns voltage_data = [] time_data = [] for row in reader: # Get voltage data (look for CH*_Voltage column) voltage_col = None for col_name in row.keys(): if "Voltage" in col_name: voltage_col = col_name break if voltage_col is None: raise ValueError("Could not find voltage column in CSV data") # Convert mV to volts voltage_mv = float(row[voltage_col]) voltage_data.append(voltage_mv / 1000.0) # Calculate time values from index and time interval index = int(row["index"]) time_interval = self._extract_time_interval(metadata) time_data.append(index * time_interval) # Create channel data channel_name = metadata.get("Channel", "CH1").replace(":", "").strip() channel_data = ChannelData( channel_name=channel_name, voltage_values=np.array(voltage_data), time_values=np.array(time_data), metadata=metadata, ) return ScopeData(channels={channel_name: channel_data}, metadata=metadata) def _parse_metadata(self, metadata_lines: List[str]) -> Dict[str, str]: """ Parse metadata from header lines. You can access the metadata like this: data = parse_owon_data(".CSV") print(data.frequency) print(data.vpp) """ metadata = {} for line in metadata_lines: if "," in line: parts = line.split(",", 1) if len(parts) == 2: key = parts[0].strip().rstrip(":").strip() value = parts[1].strip() metadata[key] = value return metadata