Created
January 15, 2014 10:43
-
-
Save maedoc/8434195 to your computer and use it in GitHub Desktop.
sEEG bipolar w/ MNE-Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| import glob | |
| import numpy as np | |
| from mne import fiff, event, epochs | |
| from iidc import detect, stat, util, cluster | |
| #### Data | |
| # Load the data, then eliminate all but the sEEG channels | |
| # In[4]: | |
| pdfname = glob.glob(u'/data/nasmeg/DATA/Protocoles_epilepsie/simultane/MEG_SEEG/seeg_006_gou_mi/s_Gou_Mi/*/3/c,rfDC')[0] | |
| data = fiff.bti.read_raw_bti(pdfname) | |
| util.bti_import_fix_channel_names(data, pdfname) | |
| picks = fiff.pick_types(data.info, eeg=True, meg=False, exclude=['VEOG', 'E90', 'E91', 'E92', 'E93', 'E94', 'ECG']) | |
| data.save('goumi-run3-seeg.fif', picks=picks, overwrite=True, verbose=False) | |
| del data | |
| # Out[4]: | |
| # Reading 4D PDF file /data/nasmeg/DATA/Protocoles_epilepsie/simultane/MEG_SEEG/seeg_006_gou_mi/s_Gou_Mi/02%21%13@1030/3/c,rfDC... | |
| # Creating Neuromag info structure ... | |
| # ... Setting channel info structure. | |
| # ... putting coil transforms in Neuromag coordinates | |
| # ... Reading digitization points from /data/nasmeg/DATA/Protocoles_epilepsie/simultane/MEG_SEEG/seeg_006_gou_mi/s_Gou_Mi/02%21%13@1030/3/hs_file | |
| # ... putting digitization points in Neuromag coordinates | |
| # ... Computing new device to head transform. | |
| # Done. | |
| # Warning. Currently direct inclusion of 4D weight tables is not supported. For critical use cases | |
| # please take into account the MNE command 'mne_create_comp_data' to include weights as printed out | |
| # by the 4D 'print_table' routine. | |
| # Reading raw data from /data/nasmeg/DATA/Protocoles_epilepsie/simultane/MEG_SEEG/seeg_006_gou_mi/s_Gou_Mi/02%21%13@1030/3/c,rfDC... | |
| # Range : 0 ... 1453885 = 0.000 ... 714.612 secs | |
| # Ready. | |
| # | |
| # In[4]: | |
| seeg = fiff.Raw('goumi-run3-seeg.fif', preload=True) | |
| # Out[4]: | |
| # Opening raw data file /home/duke/tools/iidc/work/goumi-run3-seeg.fif... | |
| # Current compensation grade : 0 | |
| # Range : 0 ... 1453885 = 0.000 ... 714.612 secs | |
| # Ready. | |
| # Adding average EEG reference projection. | |
| # Reading 0 ... 1453885 = 0.000 ... 714.612 secs... | |
| # [done] | |
| # | |
| # Now, knock off a few that survived the pick, | |
| # In[12]: | |
| picks = array([i for i, c in enumerate(seeg.info['chs']) if c['kind']==2]) | |
| seeg.save('goumi-run3-seeg.fif', picks=picks, overwrite=True, verbose=False) | |
| # In[65]: | |
| seeg = fiff.Raw('goumi-run3-seeg.fif', preload=True) | |
| # Out[65]: | |
| # Opening raw data file /home/duke/tools/iidc/work/goumi-run3-seeg.fif... | |
| # Read a total of 1 projection items: | |
| # Average EEG reference (1 x 97) idle | |
| # Range : 0 ... 1453885 = 0.000 ... 714.612 secs | |
| # Ready. | |
| # Reading 0 ... 1453885 = 0.000 ... 714.612 secs... | |
| # [done] | |
| # | |
| # Reorganize for sEEG, | |
| # In[87]: | |
| import re | |
| def seeg_ch_name_split(nm): | |
| elec, idx = re.match(r'([A-Za-z]+)(\d+)', nm).groups() | |
| return elec, int(idx) | |
| # Sort with a custom key so 'A10' (=> 'A10') is after 'A2' (=> 'A02') | |
| # In[67]: | |
| chix = array([seeg.ch_names.index(nm) for nm in sorted(seeg.ch_names, key=lambda s: '%s%02d' % seeg_ch_name_split(nm))]) | |
| seeg.info['chs'] = [seeg.info['chs'][i] for i in chix] | |
| seeg.info['ch_names'] = [seeg.info['ch_names'][i] for i in chix] | |
| seeg._data = seeg._data[chix] | |
| # In[70]: | |
| seeg.save('goumi-run3-seeg.fif', overwrite=True, verbose=False) | |
| # In[80]: | |
| seeg = fiff.Raw('goumi-run3-seeg.fif', preload=True) | |
| # Out[80]: | |
| # Opening raw data file /home/duke/tools/iidc/work/goumi-run3-seeg.fif... | |
| # Read a total of 1 projection items: | |
| # Average EEG reference (1 x 97) idle | |
| # Range : 0 ... 1453885 = 0.000 ... 714.612 secs | |
| # Ready. | |
| # Reading 0 ... 1453885 = 0.000 ... 714.612 secs... | |
| # [done] | |
| # | |
| # Check we've correctly sorted & don't have duplicate A channels: | |
| # In[81]: | |
| print seeg.ch_names[:12:3], [n for n in seeg.ch_names if n=='A1'] | |
| # Out[81]: | |
| # ['A1', 'A4', 'A7', 'A10'] ['A1'] | |
| # | |
| # I'm not sure how to go about setting up a bipolar montage. Maybe I should ask the question. | |
| # | |
| # The direct way is just to rewrite channel names and info and form the data from the diff of `_data`, removing non-contiguous channels. | |
| # In[88]: | |
| def find_bip_idx(seeg): | |
| bip_idx = [] | |
| for i in xrange(len(seeg.ch_names)-1): | |
| (e1, i1), (e2, i2) = map(seeg_ch_name_split, seeg.ch_names[i:i+2]) | |
| if e1==e2: | |
| bip_idx.append((i, i+1, e1, i1, i2)) | |
| return bip_idx | |
| bip_data = [] | |
| bip_chan = [] | |
| # 16, 17, 'OF', 2, 3 results in 'OF2-3', _data[16] = _data[16] - _data[17] | |
| for i1, i2, elec, ei1, ei2 in find_bip_idx(seeg): | |
| ch_info = seeg.info['chs'][i1].copy() | |
| ch_info['ch_name'] = '%s%d-%d' % (elec, ei1, ei2) | |
| bip_chan.append(ch_info) | |
| bip_data.append(seeg._data[i1] - seeg._data[i2]) | |
| seeg.info['chs'] = bip_chan | |
| seeg._data = array(bip_data) | |
| seeg.info['ch_names'] = [c['ch_name'] for c in seeg.info['chs']] | |
| seeg.info['nchan'] = seeg._data.shape[0] | |
| # check | |
| seeg.ch_names[:12] | |
| # Out[88]: | |
| ['A1-2', | |
| 'A2-3', | |
| 'A3-4', | |
| 'A4-5', | |
| 'A5-6', | |
| 'A6-7', | |
| 'A7-8', | |
| 'A8-9', | |
| 'A9-10', | |
| 'A10-11', | |
| 'B1-2', | |
| 'B2-3'] |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
util.fix_bti_import_channel_namesis defined in aiidc.utilmodule.