From 273d6e02846222f2a24394a72c408a57d54976fd Mon Sep 17 00:00:00 2001 From: Sage Date: Mon, 24 Mar 2025 17:07:25 -0700 Subject: [PATCH 1/2] Support new channel mapping header --- synapse/cli/offline_plot.py | 23 ++++++++++++++++++++++- synapse/nodes/__init__.py | 0 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 synapse/nodes/__init__.py diff --git a/synapse/cli/offline_plot.py b/synapse/cli/offline_plot.py index cf4ae693..1827af31 100644 --- a/synapse/cli/offline_plot.py +++ b/synapse/cli/offline_plot.py @@ -1,4 +1,5 @@ import sys +import struct import os import json import numpy as np @@ -54,7 +55,7 @@ def setup_logging(): def process_data(file_path, num_channels, logger): _, file_extension = os.path.splitext(file_path) - if file_extension in [".bin", ".dat"]: + if file_extension in [".bin"]: with open(file_path, "rb") as f: data = np.fromfile(f, dtype=np.int16) @@ -65,6 +66,20 @@ def process_data(file_path, num_channels, logger): return pd.DataFrame(df) + if file_extension in [".dat"]: + with open(file_path, "rb") as f: + data = np.fromfile(f, dtype=np.int16) + + df = pd.DataFrame(data) + new_len = (len(df)) // num_channels + df = df.tail( + -num_channels + ) # Remove the header info containing the channel mapping + df = df.head(new_len * num_channels) + df = df.values.reshape(-1, num_channels) + + return pd.DataFrame(df) + if file_extension in [".jsonl"]: channel_data = {} @@ -188,6 +203,12 @@ def plot(args): data = process_data(data_file, num_channels, logger) logger.info(f"Loaded data with {data.shape[1]} channels") + # Extract channel ids from data file header + if data_file.endswith(".dat"): + with open(data_file, "rb") as f: + header = f.read(num_channels * 2) + channel_ids = struct.unpack("h" * num_channels, header) + # Setup the window for the plot pg.setConfigOption("background", BACKGROUND_COLOR) diff --git a/synapse/nodes/__init__.py b/synapse/nodes/__init__.py new file mode 100644 index 00000000..e69de29b From 0a86ae79dfc5b6676f2478bd2c63601b37dc3382 Mon Sep 17 00:00:00 2001 From: Sage Date: Tue, 1 Apr 2025 16:10:22 -0700 Subject: [PATCH 2/2] validate file size before reading channel header --- synapse/cli/offline_plot.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/synapse/cli/offline_plot.py b/synapse/cli/offline_plot.py index 1827af31..4d554292 100644 --- a/synapse/cli/offline_plot.py +++ b/synapse/cli/offline_plot.py @@ -205,9 +205,16 @@ def plot(args): # Extract channel ids from data file header if data_file.endswith(".dat"): - with open(data_file, "rb") as f: - header = f.read(num_channels * 2) - channel_ids = struct.unpack("h" * num_channels, header) + size = os.path.getsize(data_file) + if size > num_channels * 2: + with open(data_file, "rb") as f: + header = f.read(num_channels * 2) + channel_ids = struct.unpack("h" * num_channels, header) + else: + logger.error( + f"Data file is too small to contain channel ids. Expected {num_channels} channels." + ) + return # Setup the window for the plot pg.setConfigOption("background", BACKGROUND_COLOR)