Skip to content

Commit ec9bf03

Browse files
committed
Use the ieegprep functionality to load events
1 parent 469887d commit ec9bf03

1 file changed

Lines changed: 26 additions & 62 deletions

File tree

erdetect/_erdetect.py

Lines changed: 26 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import scipy.io as sio
1919
from os.path import exists
2020

21-
from ieegprep.bids import load_channel_info, load_stim_event_info, load_ieeg_sidecar
21+
from ieegprep.bids.sidecars import load_channel_info, load_elec_stim_events, load_ieeg_sidecar
2222
from ieegprep.bids.data_epoch import load_data_epochs_averages
2323
from ieegprep.bids.rereferencing import RerefStruct
2424
from ieegprep.utils.console import multi_line_list, print_progressbar
@@ -303,79 +303,45 @@ def process_subset(bids_subset_data_path, output_dir, preproc_prioritize_speed=F
303303

304304

305305
#
306-
# retrieve trials
306+
# retrieve trials (onsets) and stim-pairs conditions
307307
#
308308

309-
# retrieve the stimulation events (onsets and pairs) from the events.tsv file
309+
# retrieve the electrical stimulation events (onsets and stim-pairs) from the events.tsv file
310+
# only retrieve the stim-pairs for the channels that are included
310311
try:
311-
trial_onsets, trial_pairs, trials_bad_onsets = load_stim_event_info(bids_subset_root + '_events.tsv')
312+
trial_onsets, trial_pairs, stim_pairs_onsets, bad_trial_onsets = load_elec_stim_events(bids_subset_root + '_events.tsv',
313+
exclude_bad_events=True,
314+
concat_bidirectional_stimpairs=cfg('trials', 'concat_bidirectional_pairs'),
315+
only_stimpairs_between_channels=channels_stim_incl)
312316
except (RuntimeError):
313-
logging.error('Could not load the stimulation event metadata (\'' + bids_subset_root + '_events.tsv\'), exiting...')
314-
raise RuntimeError('Could not load the stimulation event metadata')
317+
logging.error('Could not load the electrical stimulation event metadata (\'' + bids_subset_root + '_events.tsv\'), exiting...')
318+
raise RuntimeError('Could not load the electrical stimulation event metadata')
315319

316-
if len(trials_bad_onsets) > 0:
317-
log_indented_line('Number of trials marked as bad (excluded):', str(len(trials_bad_onsets)))
320+
if len(bad_trial_onsets) > 0:
321+
log_indented_line('Number of trials marked as bad (excluded):', str(len(bad_trial_onsets)))
318322

319323
# check if there are trials
320324
if len(trial_onsets) == 0:
321325
logging.error('No trials were found, exiting...')
322326
raise RuntimeError('No trials found')
323327

324-
325-
#
326-
# retrieve stimulus-pairs
327-
#
328-
329-
# determine the stimulation-pairs conditions (and the trial and electrodes that belong to them)
330-
# (note that the 'concat_bidirectional_pairs' configuration setting is taken into account here)
331-
#
332-
stim_pairs_onsets = dict() # for each pair, the onsets of the trials that were involved
333-
stim_pairs_electrode_names = dict() # for each pair, the names of the electrodes that were stimulated
334-
335-
# TODO: there might be a difference in the type of channels included for stimulation and those for recording
336-
337-
# loop over all the combinations of channels
338-
# Note: only the combinations of stim-pairs that actually have events/trials end up in the output
339-
for iChannel0 in range(len(channels_stim_incl)):
340-
for iChannel1 in range(len(channels_stim_incl)):
341-
342-
# retrieve the indices of all the trials that concern this stim-pair
343-
indices = []
344-
if cfg('trials', 'concat_bidirectional_pairs'):
345-
# allow concatenation of bidirectional pairs, pair order does not matter
346-
if not iChannel1 < iChannel0:
347-
# unique pairs while ignoring pair order
348-
indices = [i for i, x in enumerate(trial_pairs) if
349-
(x[0] == channels_stim_incl[iChannel0] and x[1] == channels_stim_incl[iChannel1]) or (x[0] == channels_stim_incl[iChannel1] and x[1] == channels_stim_incl[iChannel0])]
350-
351-
else:
352-
# do not concatenate bidirectional pairs, pair order matters
353-
indices = [i for i, x in enumerate(trial_pairs) if
354-
x[0] == channels_stim_incl[iChannel0] and x[1] == channels_stim_incl[iChannel1]]
355-
356-
# add the pair if there are trials for it
357-
if len(indices) > 0:
358-
stim_pairs_onsets[channels_stim_incl[iChannel0] + '-' + channels_stim_incl[iChannel1]] = [trial_onsets[i] for i in indices]
359-
stim_pairs_electrode_names[channels_stim_incl[iChannel0] + '-' + channels_stim_incl[iChannel1]] = (channels_stim_incl[iChannel0], channels_stim_incl[iChannel1])
360-
361-
# search for stimulus-pairs with too little trials
362-
stimpair_remove_indices = []
328+
# determine the stimulus-pairs conditions that have too little trials
329+
stimpair_remove_keys = []
363330
for stim_pair, onsets in stim_pairs_onsets.items():
364331
if len(onsets) < cfg('trials', 'minimum_stimpair_trials'):
365-
stimpair_remove_indices.append(stim_pair)
332+
stimpair_remove_keys.append(stim_pair)
366333

367334
# remove the stimulus-pairs with too little trials
368-
if len(stimpair_remove_indices) > 0:
335+
if len(stimpair_remove_keys) > 0:
369336

370337
# message
371-
stimpair_print = [stim_pair + ' (' + str(len(stim_pairs_onsets[stim_pair])) + ' trials)' for stim_pair in stimpair_remove_indices]
338+
stimpair_print = [stim_pair + ' (' + str(len(stim_pairs_onsets[stim_pair])) + ' trials)' for stim_pair in stimpair_remove_keys]
372339
stimpair_print = [str_print.ljust(len(max(stimpair_print, key=len)), ' ') for str_print in stimpair_print]
373340
logging.info(multi_line_list(stimpair_print, LOGGING_CAPTION_INDENT_LENGTH, 'Stim-pairs excluded by number of trials:', 3, ' '))
374341

375342
# remove those stimulation-pairs
376-
for stim_pair in stimpair_remove_indices:
343+
for stim_pair in stimpair_remove_keys:
377344
del stim_pairs_onsets[stim_pair]
378-
del stim_pairs_electrode_names[stim_pair]
379345

380346
# display stimulation-pair/trial information
381347
stimpair_print = [stim_pair + ' (' + str(len(onsets)) + ' trials)' for stim_pair, onsets in stim_pairs_onsets.items()]
@@ -391,11 +357,11 @@ def process_subset(bids_subset_data_path, output_dir, preproc_prioritize_speed=F
391357
if early_reref is not None:
392358
early_reref.set_exclude_reref_epochs(stim_pairs_onsets,
393359
(cfg('preprocess', 'early_re_referencing', 'stim_excl_epoch')[0], cfg('preprocess', 'early_re_referencing', 'stim_excl_epoch')[1]),
394-
'-')
360+
channel_key_seperator='-')
395361
if late_reref is not None:
396362
late_reref.set_exclude_reref_epochs(stim_pairs_onsets,
397363
(cfg('preprocess', 'late_re_referencing', 'stim_excl_epoch')[0], cfg('preprocess', 'late_re_referencing', 'stim_excl_epoch')[1]),
398-
'-')
364+
channel_key_seperator='-')
399365
logging.info('')
400366

401367

@@ -421,7 +387,7 @@ def process_subset(bids_subset_data_path, output_dir, preproc_prioritize_speed=F
421387
# TODO: normalize to raw or to Z-values (return both raw and z?)
422388
# z-might be needed for detection
423389
try:
424-
sampling_rate, averages, metrics = load_data_epochs_averages(bids_subset_data_path, channels_measured_incl, list(stim_pairs_onsets.values()),
390+
sampling_rate, averages, metrics = load_data_epochs_averages(bids_subset_data_path, channels_measured_incl, stim_pairs_onsets,
425391
trial_epoch=cfg('trials', 'trial_epoch'),
426392
baseline_norm=cfg('trials', 'baseline_norm'),
427393
baseline_epoch=cfg('trials', 'baseline_epoch'),
@@ -437,24 +403,21 @@ def process_subset(bids_subset_data_path, output_dir, preproc_prioritize_speed=F
437403
raise RuntimeError('Could not load data')
438404

439405
# for each stimulation pair condition, NaN out the values of the measured electrodes that were stimulated
440-
iPair = 0
441-
for stim_pair in stim_pairs_onsets.keys():
406+
for stim_pair_index, stim_pair in enumerate(stim_pairs_onsets):
407+
stim_pair_electrode_names = stim_pair.split('-')
442408

443409
# find and clear the first electrode
444410
try:
445-
averages[channels_measured_incl.index(stim_pairs_electrode_names[stim_pair][0]), iPair, :] = np.nan
411+
averages[channels_measured_incl.index(stim_pair_electrode_names[0]), stim_pair_index, :] = np.nan
446412
except ValueError:
447413
pass
448414

449415
# find and clear the second electrode
450416
try:
451-
averages[channels_measured_incl.index(stim_pairs_electrode_names[stim_pair][1]), iPair, :] = np.nan
417+
averages[channels_measured_incl.index(stim_pair_electrode_names[1]), stim_pair_index, :] = np.nan
452418
except ValueError:
453419
pass
454420

455-
# next stim-pair index
456-
iPair += 1
457-
458421
# determine the sample of stimulus onset (counting from the epoch start)
459422
onset_sample = int(round(abs(cfg('trials', 'trial_epoch')[0] * sampling_rate)))
460423
# todo: handle trial epochs which start after the trial onset, currently disallowed by config
@@ -468,6 +431,7 @@ def process_subset(bids_subset_data_path, output_dir, preproc_prioritize_speed=F
468431
metric_counter += 1
469432
if cfg('metrics', 'waveform', 'enabled'):
470433
waveform_metrics = metrics[:, :, metric_counter]
434+
metric_counter += 1
471435

472436

473437
#

0 commit comments

Comments
 (0)