MorganBrizon commited on
Commit
69d12c6
·
verified ·
1 Parent(s): 5b8ed74

Delete preprocessing_epilepsynet.py

Browse files
Files changed (1) hide show
  1. preprocessing_epilepsynet.py +0 -260
preprocessing_epilepsynet.py DELETED
@@ -1,260 +0,0 @@
1
- import mne
2
- import numpy as np
3
-
4
- from typing import List, Optional
5
- import random
6
-
7
-
8
- def extract_random_segment(raw: mne.io.Raw, duration: float = 60.0,
9
- random_state: Optional[int] = None) -> mne.io.Raw:
10
- """
11
- Extract a random segment of specified duration from a raw MNE file.
12
-
13
- Parameters:
14
- -----------
15
- raw : mne.io.Raw
16
- The raw MNE object
17
- duration : float
18
- Duration of the segment to extract in seconds
19
- random_state : int, optional
20
- Random seed for reproducibility
21
-
22
- Returns:
23
- --------
24
- mne.io.Raw
25
- A cropped raw object containing only the random segment
26
- """
27
- if random_state is not None:
28
- np.random.seed(random_state)
29
-
30
- # Get the total duration of the raw file
31
- total_duration = raw.times[-1]
32
-
33
- # Ensure the raw file is long enough
34
- if total_duration <= duration:
35
- raise ValueError(f"Raw file duration ({total_duration:.2f}s) is shorter than requested segment duration ({duration:.2f}s)")
36
-
37
- # Generate a random start time
38
- max_start = total_duration - duration
39
- start_time = np.random.uniform(0, max_start)
40
- end_time = start_time + duration
41
-
42
- # Create a copy and crop to the random segment
43
- raw_segment = raw.copy().crop(tmin=start_time, tmax=end_time)
44
-
45
- return raw_segment
46
-
47
-
48
- def segment_to_epochs(raw_segment: mne.io.Raw, n_segments: int = 12) -> mne.Epochs:
49
- """
50
- Convert a raw segment into fixed-length epochs.
51
-
52
- Parameters:
53
- -----------
54
- raw_segment : mne.io.Raw
55
- The raw segment to convert to epochs
56
- n_segments : int
57
- Number of segments to create
58
-
59
- Returns:
60
- --------
61
- mne.Epochs
62
- Epoch object containing the segmented data
63
- """
64
- # Calculate duration of each epoch based on total duration and number of segments
65
- total_duration = raw_segment.times[-1]
66
- epoch_duration = total_duration / n_segments
67
-
68
- # Create fixed-length epochs
69
- epochs = mne.make_fixed_length_epochs(
70
- raw_segment,
71
- duration=epoch_duration,
72
- preload=True,
73
- reject_by_annotation=True
74
- )
75
-
76
- return epochs
77
-
78
-
79
- def process_raw_files(raw_file: mne.io.Raw,
80
- eeg_cols: List[str],
81
- segment_duration: float = 60.0,
82
- n_segments_per_file: int = 12,
83
- samples_per_segment: int = 1250,
84
- random_state: Optional[int] = None) -> np.ndarray:
85
- """
86
- Process a list of raw MNE files into a batch of epochs with specific EEG channels.
87
-
88
- Parameters:
89
- -----------
90
- raw_files : mne.io.Raw
91
- The raw MNE object to make preds on
92
- eeg_cols : List[str]
93
- List of EEG channel names to keep
94
- segment_duration : float
95
- Duration of random segment to extract from each file in seconds
96
- n_segments_per_file : int
97
- Number of segments to create per file
98
- samples_per_segment : int
99
- Number of time samples per segment
100
- random_state : int, optional
101
- Random seed for reproducibility
102
-
103
- Returns:
104
- --------
105
- np.ndarray
106
- Array of shape (len(raw_files), n_segments_per_file, len(eeg_cols), samples_per_segment)
107
- """
108
- # Initialize the output array
109
- X = np.zeros((n_segments_per_file, len(eeg_cols), samples_per_segment))
110
-
111
- # Define duration of each epoch based on number of segment and total duration
112
- epoch_duration = segment_duration / n_segments_per_file
113
-
114
-
115
- try:
116
- # Set different random seed for each file if random_state is provided
117
- file_random_state = None if random_state is None else random_state
118
-
119
- # Pick only the specified EEG channels
120
- available_channels = raw_file.ch_names
121
- print('Num of availbable ch :', len(available_channels))
122
- channels_to_use = [ch for ch in available_channels if ch.replace('-REF','').replace('-LE','') in eeg_cols]
123
- if not channels_to_use:
124
- raise ValueError(f"None of the specified EEG channels found in file")
125
-
126
- if len(channels_to_use) < len(eeg_cols):
127
- print(f"Warning: Only {len(channels_to_use)}/{len(eeg_cols)} EEG channels found in file")
128
-
129
- # Select only the required channels
130
- raw_eeg = raw_file.copy().pick_channels(channels_to_use)
131
-
132
- # Resample to 250Hz
133
- current_sfreq = int(raw_eeg.info['sfreq'])
134
- if current_sfreq != 250:
135
- print(f"🔁 Resample : {current_sfreq} Hz → {250} Hz")
136
- raw_eeg.resample(250)
137
-
138
- # Extract random segment
139
- raw_segment = extract_random_segment(
140
- raw_eeg,
141
- duration=segment_duration,
142
- random_state=file_random_state
143
- )
144
-
145
- # Convert to epochs
146
- epochs = segment_to_epochs(raw_segment, n_segments=n_segments_per_file)
147
-
148
- # Get the data as array
149
- epoch_data = epochs.get_data()
150
-
151
- # Ensure the data has the correct number of time samples
152
- if epoch_data.shape[2] != samples_per_segment:
153
- # Resample if necessary
154
- resampling_freq = samples_per_segment / (epoch_duration / n_segments_per_file)
155
- raw_segment.resample(resampling_freq)
156
- epochs = segment_to_epochs(raw_segment, n_segments=n_segments_per_file)
157
- epoch_data = epochs.get_data()
158
-
159
- # Store in the output array
160
- X[:, :len(channels_to_use), :] = epoch_data
161
-
162
- except Exception as e:
163
- print(f"Error processing file {str(e)}")
164
- # Keep zeros in the output array for this file
165
-
166
- return X
167
-
168
- # Standardize the data per channel :
169
- def standardize_data(X: np.ndarray) -> np.ndarray:
170
- """
171
- Standardize the data along the last axis (time samples).
172
-
173
- Parameters:
174
- -----------
175
- X : np.ndarray
176
- Input data of shape (n_samples, n_segments, n_channels, n_time_samples)
177
-
178
- Returns:
179
- --------
180
- np.ndarray
181
- Standardized data
182
- """
183
- # Compute mean and std for each channel across all segments and samples
184
- mean = np.mean(X, axis=(1), keepdims=True)
185
- std = np.std(X, axis=(1), keepdims=True)
186
- print(X.shape)
187
-
188
- # Standardize the data
189
- X_standardized = (X - mean) / std
190
-
191
- return X_standardized
192
-
193
-
194
- # Compute Correlation Matrix
195
- def compute_correlation_matrix(X: np.ndarray) -> np.ndarray:
196
- """
197
- Compute the correlation matrix for the data.
198
-
199
- Parameters:
200
- -----------
201
- X : np.ndarray
202
- Input data of shape (n_samples, n_segments, n_channels, n_time_samples)
203
-
204
- Returns:
205
- --------
206
- np.ndarray
207
- Correlation matrices of shape (n_samples, n_segments, n_channels, n_channels)
208
- """
209
- # Declare corr_matrix np array of shape (n_samples, n_segments,n_channels, n_channels)
210
- corr_matrix = np.zeros((X.shape[0], X.shape[1], X.shape[1]))
211
- for j in range(X.shape[0]): # for each segment 5 secs
212
- # Compute the correlation matrix
213
- temp = np.corrcoef(X[j])
214
- corr_matrix[j] = np.nan_to_num(temp)
215
-
216
- return corr_matrix
217
-
218
-
219
-
220
- # Discard bottom triangle from the matrix:
221
- def discard_bottom_triangle(matrix):
222
- """
223
- Discard the bottom triangle of a square matrix.
224
-
225
- Parameters:
226
- - matrix (numpy.ndarray): The input square matrix.
227
-
228
- Returns:
229
- - numpy.ndarray: The matrix with the bottom triangle discarded.
230
- """
231
- # Create a mask for the upper triangle
232
- mask = np.triu(np.ones_like(matrix, dtype=bool), k=1)
233
-
234
- # Apply the mask to the matrix
235
- upper_triangle = np.where(mask, matrix, 0)
236
-
237
- return upper_triangle
238
-
239
- def extract_upper_triangle(corr_matrices):
240
- """
241
- Extract upper triangles from correlation matrices
242
-
243
- Args:
244
- corr_matrices: numpy array of shape (n_sample, n_segments, n_channels, n_channels)
245
-
246
- Returns:
247
- numpy array of shape (n_segments, n_features) where n_features = n_channels*(n_channels-1)/2
248
- """
249
- n_segments, n_channels, = corr_matrices.shape[0], corr_matrices.shape[1]
250
- n_features = n_channels * (n_channels - 1) // 2
251
-
252
- flattened = np.zeros((n_segments, n_features))
253
-
254
- for j in range(n_segments):
255
- # Get upper triangle indices (excluding diagonal)
256
- upper_indices = np.triu_indices(n_channels, k=1)
257
- # Extract values
258
- flattened[j] = corr_matrices[j][upper_indices]
259
-
260
- return flattened