Skip to content

Commit cb55054

Browse files
Update rereference.py
Removed the assumption that channels 1-N are always provided for a given contact. Now, any channel numbers on a contact can be provided, and local average referencing will be robust to this. This is useful in cases where depth electrodes are inserted through the brain, e.g. some electrodes are in the CSF beyond the brain, some electrodes are in the brain, and some are in the skull/scalp, since only electrodes in the brain should be used for re-referencing. It now also notifies the user if channels cannot properly be re-referenced because `extent` is too small due to a lack of spatially local sites.
1 parent fae2e2e commit cb55054

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

naplib/preprocessing/rereference.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def make_contact_rereference_arr(channelnames, extent=None, grid_sizes={}):
134134
from each other (inclusive) are still grouped together. For example, if ``extent=1``, only the
135135
nearest electrode on either side of a given electrode on the same contact is still grouped with it.
136136
This ``extent=1`` produces the traditional local average reference scheme.
137+
The default ``extent=None`` produces the traditional common average reference scheme.
137138
grid_sizes : dict, optional, default={}
138139
If provided, contains {'contact_name': (nrow, ncol)} values for any known ECoG grid sizes.
139140
E.g. {'GridA': (8, 16)} indicates that electrodes on contact 'GridA' are arranged in an 8 x 16 grid,
@@ -172,15 +173,21 @@ def _find_adjacent_numbers(a, b, number, extent):
172173
adjacent_numbers.append(adjacent_num)
173174

174175
return np.array(adjacent_numbers, dtype=int)
176+
175177
connections = np.zeros((len(channelnames),) * 2, dtype=float)
176178
channelnames = np.array(channelnames)
177179
contact_arrays = np.array([x.rstrip('0123456789') for x in channelnames])
178-
contacts, ch_per_contact = np.unique([x.rstrip('0123456789') for x in channelnames], return_counts=True)
180+
contacts = np.unique(contact_arrays)
181+
# Determine the channel numbers on each contact
182+
ch_per_contact = {contact:[int(x.replace(contact,'')) for x in channelnames
183+
if x.rstrip('0123456789')==contact]
184+
for contact in contacts}
185+
179186
if extent is None:
180187
# Common average referencing per electrode array (ECoG grid or sEEG shank)
181188
# CAR will end up subtracting parts of channel ch from itself
182-
for contact, num_ch in zip(contacts, ch_per_contact):
183-
for ch in range(1,num_ch+1):
189+
for contact in contacts:
190+
for ch in ch_per_contact[contact]:
184191
curr = np.where(channelnames==f'{contact}{ch}')[0]
185192
inds = np.where(contact_arrays==contact)[0]
186193
connections[curr,inds] = 1
@@ -189,10 +196,11 @@ def _find_adjacent_numbers(a, b, number, extent):
189196
else:
190197
# Local average referencing within each electrode array
191198
# LAR will NOT subtract parts of channel ch from itself
192-
for contact, num_ch in zip(contacts, ch_per_contact):
193-
for ch in range(1,num_ch+1):
199+
for contact in contacts:
200+
for ch in ch_per_contact[contact]:
194201
# Local referencing for ECoG grids
195202
if 'grid' in contact.lower():
203+
num_ch = len(ch_per_contact[contact])
196204
side = np.sqrt(num_ch)
197205
half_side = np.sqrt(num_ch/2)
198206
# Check grid_sizes dict
@@ -221,6 +229,9 @@ def _find_adjacent_numbers(a, b, number, extent):
221229
inds.append(np.where(channelnames==f'{contact}{cc}')[0])
222230

223231
inds = np.concatenate(inds)
224-
connections[curr,inds] = 1
232+
if len(inds) < 1:
233+
print(f'{contact}{cc} has no re-references.')
234+
else:
235+
connections[curr,inds] = 1
225236

226237
return connections

0 commit comments

Comments
 (0)