Spaces:
Sleeping
Sleeping
Delete preprocessing.py
Browse files- preprocessing.py +0 -101
preprocessing.py
DELETED
|
@@ -1,101 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import mne
|
| 3 |
-
import numpy as np
|
| 4 |
-
import pandas as pd
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
def standardize_dataframe(df):
|
| 8 |
-
# Make a copy to avoid modifying the original dataframe
|
| 9 |
-
df_standardized = df.copy()
|
| 10 |
-
|
| 11 |
-
# Only standardize numeric columns
|
| 12 |
-
numeric_columns = df.select_dtypes(include=np.number).columns
|
| 13 |
-
|
| 14 |
-
for column in numeric_columns:
|
| 15 |
-
mean = df[column].mean()
|
| 16 |
-
std = df[column].std()
|
| 17 |
-
|
| 18 |
-
df_standardized[column] = (df[column] - mean) / std
|
| 19 |
-
|
| 20 |
-
return df_standardized
|
| 21 |
-
|
| 22 |
-
desired = ["EEG FP1-REF", "EEG FP2-REF",
|
| 23 |
-
"EEG F3-REF", "EEG F4-REF",
|
| 24 |
-
"EEG C3-REF"]
|
| 25 |
-
|
| 26 |
-
def select_relevant_channels(raw, desired = desired):
|
| 27 |
-
|
| 28 |
-
# For relevant channel criteria check documentation
|
| 29 |
-
'''“EEG FP1-REF” for the left frontal pole
|
| 30 |
-
|
| 31 |
-
“EEG FP2-REF” for the right frontal pole
|
| 32 |
-
|
| 33 |
-
“EEG F3-REF” for the left frontal region
|
| 34 |
-
|
| 35 |
-
“EEG F4-REF” for the right frontal region
|
| 36 |
-
|
| 37 |
-
“EEG C3-REF” for the left central region'''
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
#check if all desired channels are present; if not, skip this file
|
| 41 |
-
if not all(ch in raw.ch_names for ch in desired):
|
| 42 |
-
print("Skipping file because it doesn't have the full set of desired channels.")
|
| 43 |
-
return None
|
| 44 |
-
raw.pick_channels(desired, verbose=False)
|
| 45 |
-
return raw
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
def collapse_epoch_df_by_channel(epoch_df):
|
| 49 |
-
# Identify channel columns (exclude time, epoch, condition)
|
| 50 |
-
channel_cols = [col for col in epoch_df.columns if col not in ['time', 'epoch']]
|
| 51 |
-
# Group by epoch
|
| 52 |
-
grouped = epoch_df.groupby('epoch')
|
| 53 |
-
rows = []
|
| 54 |
-
for epoch_num, group in grouped:
|
| 55 |
-
group_sorted = group.sort_values('time')
|
| 56 |
-
# For each channel, extract the 1D array for this epoch
|
| 57 |
-
row = {'epoch': epoch_num}
|
| 58 |
-
for ch in channel_cols:
|
| 59 |
-
row[ch] = group_sorted[ch].values # 1D array of length = number of time samples in the epoch
|
| 60 |
-
rows.append(row)
|
| 61 |
-
return pd.DataFrame(rows)
|
| 62 |
-
|
| 63 |
-
def preprocess_eeg_file(edf_path, fmin=1.0, fmax=45.0, segment_lenght=5, overlap=2,desired=desired):
|
| 64 |
-
|
| 65 |
-
# 1. Charger le fichier EDF avec MNE
|
| 66 |
-
raw = mne.io.read_raw_edf(edf_path, preload=True, verbose=False)
|
| 67 |
-
|
| 68 |
-
# Resample (to 250 because it's the lowest sampling rate )
|
| 69 |
-
raw.resample(250, verbose=False)
|
| 70 |
-
|
| 71 |
-
# Filtrage passe-bande (1-45 Hz)
|
| 72 |
-
raw.filter(fmin, fmax, fir_design='firwin', verbose=False)
|
| 73 |
-
|
| 74 |
-
# Skip EEGs less than 5s
|
| 75 |
-
if raw.times[-1] < 5:
|
| 76 |
-
print(f"Skipping {edf_path}: duration ({raw.times[-1]:.2f} s) is less than required 5s.")
|
| 77 |
-
return None
|
| 78 |
-
|
| 79 |
-
# Suppression des canaux non EEG
|
| 80 |
-
eeg_channels = mne.pick_types(raw.info, eeg=True, exclude=[])
|
| 81 |
-
raw.pick(eeg_channels, verbose=False)
|
| 82 |
-
|
| 83 |
-
# Selectionner les channels pertinents (channel selection from EDA ?)
|
| 84 |
-
print(raw.ch_names)
|
| 85 |
-
raw = select_relevant_channels(raw,desired=desired)
|
| 86 |
-
if raw is None:
|
| 87 |
-
return None
|
| 88 |
-
|
| 89 |
-
# Segmentation
|
| 90 |
-
epochs = mne.make_fixed_length_epochs(raw, duration=segment_lenght, preload=False, overlap=overlap, verbose=False)
|
| 91 |
-
|
| 92 |
-
# Transform to dataframe and standadize
|
| 93 |
-
|
| 94 |
-
df = epochs.to_data_frame() # epochs is returned by preprocess_eeg_file()
|
| 95 |
-
df_std = standardize_dataframe(df.drop(['time','epoch', 'condition'], axis=1))
|
| 96 |
-
result = pd.concat([df[['time','epoch']], df_std], axis=1)
|
| 97 |
-
|
| 98 |
-
return collapse_epoch_df_by_channel(result)
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|