From e08bc70f75020e8ec45ed3ddc604a1ac44e12d02 Mon Sep 17 00:00:00 2001 From: alessandratrapani Date: Tue, 19 Nov 2024 15:38:25 +0100 Subject: [PATCH] handle multi edf file --- .../interfaces/zaki_2024_edf_interface.py | 15 ++++-- .../zaki_2024_convert_week_session.py | 53 ++++++------------- 2 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/cai_lab_to_nwb/zaki_2024/interfaces/zaki_2024_edf_interface.py b/src/cai_lab_to_nwb/zaki_2024/interfaces/zaki_2024_edf_interface.py index 9bff7cf..c123cfe 100644 --- a/src/cai_lab_to_nwb/zaki_2024/interfaces/zaki_2024_edf_interface.py +++ b/src/cai_lab_to_nwb/zaki_2024/interfaces/zaki_2024_edf_interface.py @@ -1,8 +1,12 @@ from typing import Union from pathlib import Path -from neuroconv.basedatainterface import BaseDataInterface + from pynwb import NWBFile, TimeSeries from pynwb.device import Device + +from neuroconv.basedatainterface import BaseDataInterface +from neuroconv.utils import DeepDict + from mne.io import read_raw_edf from datetime import datetime, timedelta import numpy as np @@ -179,18 +183,23 @@ def add_to_nwbfile( "unit": "n.a.", }, } - concatenated_data = [] + concatenated_data = None concatenated_times = [] # Loop over each EDF file and concatenate data and timestamps for file_path in self.file_paths: edf_reader = read_raw_edf(input_fname=file_path, verbose=self.verbose) data, times = edf_reader.get_data(picks=list(channels_dict.keys()), return_times=True) + data = data.astype(np.float32) # Slice the data and timestamps within the time range if stub_test: concatenated_data = data[:, :stub_frames] break - concatenated_data.append(data.astype("float32")) + # Concatenate along the time axis + if concatenated_data is None: + concatenated_data = data + else: + concatenated_data = np.concatenate((concatenated_data, data), axis=1) concatenated_times.extend(times) for channel_index, channel_name in enumerate(channels_dict.keys()): diff --git a/src/cai_lab_to_nwb/zaki_2024/zaki_2024_convert_week_session.py b/src/cai_lab_to_nwb/zaki_2024/zaki_2024_convert_week_session.py index c8131bb..690c16c 100644 --- a/src/cai_lab_to_nwb/zaki_2024/zaki_2024_convert_week_session.py +++ b/src/cai_lab_to_nwb/zaki_2024/zaki_2024_convert_week_session.py @@ -1,7 +1,7 @@ """Primary script to run to convert an entire session for of data using the NWBConverter.""" import time - +from natsort import natsorted from pathlib import Path from typing import Union from datetime import datetime, timedelta @@ -11,10 +11,6 @@ from zaki_2024_nwbconverter import Zaki2024NWBConverter -# TODO: -# 1. aggiungere sessions start time da edf.info["meas_date"] -# 2. creare un interfaccia per multi edf files - def session_to_nwb( data_dir_path: Union[str, Path], @@ -22,9 +18,8 @@ def session_to_nwb( subject_id: str, stub_test: bool = False, verbose: bool = True, - include_eeg_emg_signals: bool = True, ): - print(f"Converting session {session_id}") + print(f"Converting week-long session") if verbose: start = time.time() @@ -40,34 +35,30 @@ def session_to_nwb( conversion_options = dict() # Add EEG, EMG, Temperature and Activity signals - datetime_obj = datetime.strptime(date_str, "%Y_%m_%d") - reformatted_date_str = datetime_obj.strftime("_%m%d%y") - edf_file_path = data_dir_path / "Ca_EEG_EDF" / (subject_id + "_EDF") / (subject_id + reformatted_date_str + ".edf") - - if edf_file_path.is_file() and include_eeg_emg_signals: - + edf_folder_path = data_dir_path / "Ca_EEG_EDF" / (subject_id + "_EDF") + edf_file_paths = natsorted(edf_folder_path.glob("*.edf")) + if len(edf_file_paths) > 0: source_data.update( dict( - EDFSignals=dict( - file_path=edf_file_path, + MultiEDFSignals=dict( + file_paths=edf_file_paths, ) ) ) - conversion_options.update(dict(EDFSignals=dict(stub_test=stub_test))) - elif verbose and not include_eeg_emg_signals: - print(f"The EEG, EMG, Temperature and Activity signals will not be included for session {session_id}") - elif verbose and not edf_file_path.is_file(): - print(f"No .edf file found at {edf_file_path}") + conversion_options.update(dict(MultiEDFSignals=dict(stub_test=stub_test))) + else: + print(f"No .edf file found in {edf_folder_path}") converter = Zaki2024NWBConverter(source_data=source_data) # Add datetime to conversion metadata = converter.get_metadata() - # if session_start_time has been already set from other interfaces do not override - if not metadata["NWBFile"]["session_start_time"]: - datetime_str = date_str + " " + time_str - session_start_time = datetime.strptime(datetime_str, "%Y_%m_%d %H_%M_%S") - metadata["NWBFile"]["session_start_time"] = session_start_time + + from mne.io import read_raw_edf + + edf_reader = read_raw_edf(input_fname=edf_file_paths[0], verbose=verbose) + session_start_time = edf_reader.info["meas_date"] + metadata["NWBFile"]["session_start_time"] = session_start_time # Update default metadata with the editable in the corresponding yaml file editable_metadata_path = Path(__file__).parent / "zaki_2024_metadata.yaml" @@ -96,22 +87,12 @@ def session_to_nwb( # Parameters for conversion data_dir_path = Path("D:/") - subject_id = "Ca_EEG3-4" - task = "OfflineDay1Session1" - session_id = subject_id + "_" + task output_dir_path = Path("D:/cai_lab_conversion_nwb/") + subject_id = "Ca_EEG3-4" stub_test = False - session_times_file_path = data_dir_path / "Ca_EEG_Experiment" / subject_id / (subject_id + "_SessionTimes.csv") - df = pd.read_csv(session_times_file_path) - session_row = df[df["Session"] == task].iloc[0] - date_str = session_row["Date"] - time_str = session_row["Time"] session_to_nwb( data_dir_path=data_dir_path, output_dir_path=output_dir_path, stub_test=stub_test, subject_id=subject_id, - session_id=session_id, - date_str=date_str, - time_str=time_str, )