Closed rb643 closed 5 years ago
I actually think you need to either pass each of the epoch objects to Ssvep successively, or to pass them with all epochs in one Epoch object. I think you can always split later, since data arrays (e.g. ssvep.stimulation.power
) have epoch as a dimension!
e.g. if I do:
file = Path('debug/EG-CTR-0115-Face-Categorisation.bdf')
raw = mne.io.read_raw_edf(
file, montage=mne.channels.read_montage('biosemi64'),
eog=[f'EXG{n}' for n in range(1, 9)]
)
raw.info['subject_info'] = {'pid': file.name[7:11], 'group': file.name[3:6]}
events = mne.find_events(raw)
epochs = mne.Epochs(
raw, events,
tmin=0, tmax=30, preload=True
).set_eeg_reference().load_data().apply_proj()
ssvep = ssvepy.Ssvep(epochs, [1.2, 6])
then I can access the individual epoch type data in the arrays:
ssvep.stimulation.power.shape
#> (31, 64, 2)
Where the dimensions are Epochs, Electrodes, Stimulation Frequencies.
Yep get that same dimensions! How do you next loop though these to average across and append?
I'm not familiair with the xarray package so I assume this is no longer correct when looping through files (when they are printed to csv the means looks a bit oddly formatted):
# which channels to use
occipital_elecs = mne.pick_channels(raw.ch_names, ['Oz', 'O1', 'O2', 'Iz'])
datadicts.append(
{'pid': raw.info['subject_info']['pid'],
'group': raw.info['subject_info']['group'],
'occipital_snr_social': ssvep.stimulation.snr[:, occipital_elecs,0].mean(),
'occipital_snr_nonsocial': ssvep.stimulation.snr[:, occipital_elecs,1].mean()}
)
pd.DataFrame(datadicts).to_csv('occipital_snrs.csv');
Yeah, good question! You can treat the xarray data like a normal numpy array, so what you posted will still work.
But you can also use strings to index in the electrode dimension and seconds / Hz to index in the time / frequency domain:
occipital_elecs = mne.pick_channels(raw.ch_names, ['Oz', 'O1', 'O2', 'Iz'])
datadicts.append(
{'pid': raw.info['subject_info']['pid'],
'group': raw.info['subject_info']['group'],
# you can index using the electrode strings, and the raw frequency value:
'occipital_snr_social': ssvep.stimulation.snr.loc[:, ['Oz', 'O1', 'O2', 'Iz'], 1.2].mean(),
'occipital_snr_nonsocial': ssvep.stimulation.snr[:, ['Oz', 'O1', 'O2', 'Iz'] , 6].mean()}
)
not quite:
TypeError: invalid indexer array, does not have integer dtype: array(['Oz', 'O1', 'O2', 'Iz'], dtype='<U2')
Sorry, forgot adding loc
to the second line:
occipital_elecs = mne.pick_channels(raw.ch_names, ['Oz', 'O1', 'O2', 'Iz'])
datadicts.append(
{'pid': raw.info['subject_info']['pid'],
'group': raw.info['subject_info']['group'],
# you can index using the electrode strings, and the raw frequency value:
'occipital_snr_social': ssvep.stimulation.snr.loc[:, ['Oz', 'O1', 'O2', 'Iz'], 1.2].mean(),
'occipital_snr_nonsocial': ssvep.stimulation.snr.loc[:, ['Oz', 'O1', 'O2', 'Iz'] , 6].mean()}
)
Without .loc
, indexing works with integers just like numpy, with .loc
it works more like pandas, so you can specify bands of frequencies by doing:
ssvep.stimulation.snr.loc[:, :, 1.2:2.4]
In the csv files either option is listed like this though:
Which does contain the relevant information, but perhaps not in the most straightforward format :)
Haha, fair enough. You probably need to call .values on it (which gets the raw numpy values) before passing it to pandas.
Excellent!
When looping over 'conditions' in the epochs reconstruction it seems to not maintain the info attribute for epochs...
e.g. when I do:
epochs = [mne.Epochs(raw, events[events[:, 2] % 2 == a, :], tmin=0, tmax=4, preload=True).set_eeg_reference().load_data().apply_proj() for a in [1, 0]]
I get: --> 92 self.info = deepcopy(epochs.info) 93 94 self.noisebandwidth = noisebandwidth
AttributeError: 'list' object has no attribute 'info'
But when I do: mne.Epochs(raw, events[events[:, 2] % 2 == 1, :], tmin=0, tmax=4, preload=True).set_eeg_reference().load_data().apply_proj()
Its fine (but I obviously want to split beforehand..)