def make_bids_folder_struct(datadir, subject, kind, session_id="one"): """ Create the empty folder structure for a new subject according to the BIDS format. Session is assumed to be 'one' for now. Parameters ---------- datadir : subject : kind : session_id : """ if type(datadir) is not str: datadir = str(datadir) # create bids folders for this subject make_bids_folders( subject=subject, kind=kind, session=session_id, output_path=datadir, make_dir=True, )
def test_make_folders(): """Test that folders are created and named properly.""" # Make sure folders are created properly bids_root = _TempDir() make_bids_folders(subject='hi', session='foo', kind='ba', bids_root=bids_root) assert op.isdir(op.join(bids_root, 'sub-hi', 'ses-foo', 'ba')) # If we remove a kwarg the folder shouldn't be created bids_root = _TempDir() make_bids_folders(subject='hi', kind='ba', bids_root=bids_root) assert op.isdir(op.join(bids_root, 'sub-hi', 'ba')) # check overwriting of folders make_bids_folders(subject='hi', kind='ba', bids_root=bids_root, overwrite=True, verbose=True) # Check if a pathlib.Path bids_root works. bids_root = Path(_TempDir()) make_bids_folders(subject='hi', session='foo', kind='ba', bids_root=bids_root) assert op.isdir(op.join(bids_root, 'sub-hi', 'ses-foo', 'ba')) # Check if bids_root=None creates folders in the current working directory bids_root = _TempDir() curr_dir = os.getcwd() os.chdir(bids_root) make_bids_folders(subject='hi', session='foo', kind='ba', bids_root=None) assert op.isdir(op.join(os.getcwd(), 'sub-hi', 'ses-foo', 'ba')) os.chdir(curr_dir)
def test_bids_setup(self, tmp_bids_root, edf_fpath): """ Integration test for setting up a bids directory from scratch. Should test: 1. Initial setup 2. loading runs 3. loading patients Parameters ---------- bids_root : Returns ------- """ # create the BIDS dirctory structure test_subjectid = "0002" modality = "eeg" test_sessionid = "seizure" test_runid = "01" task = "monitor" line_freq = 60 # create the BIDS directory structure if not os.path.exists(tmp_bids_root): print("Making bids root directory.") make_bids_folders( output_path=tmp_bids_root, session=test_sessionid, subject=test_subjectid, kind=modality, ) # add a bids run bids_basename = make_bids_basename( subject=test_subjectid, acquisition=modality, session=test_sessionid, run=test_runid, task=task, ) # call bidsbuilder pipeline tmp_bids_root = BidsConverter.convert_to_bids( edf_fpath=edf_fpath, bids_root=tmp_bids_root, bids_basename=bids_basename, line_freq=line_freq, overwrite=True, ) # load it in using mne_bids again bids_fname = bids_basename + f"_{modality}.fif" raw = mne_bids.read_raw_bids(bids_fname, tmp_bids_root)
def test_get_matched_emptyroom_no_meas_date(): """Test that we warn if measurement date can be read or inferred.""" bids_root = _TempDir() er_session = 'mysession' er_meas_date = None er_dir = make_bids_folders(subject='emptyroom', session=er_session, kind='meg', bids_root=bids_root) er_bids_path = BIDSPath(subject='emptyroom', session=er_session, task='noise') er_basename = str(er_bids_path) raw = mne.io.read_raw_fif(raw_fname) er_raw_fname = op.join(data_path, 'MEG', 'sample', 'ernoise_raw.fif') raw.copy().crop(0, 10).save(er_raw_fname, overwrite=True) er_raw = mne.io.read_raw_fif(er_raw_fname) er_raw.set_meas_date(er_meas_date) er_raw.save(op.join(er_dir, f'{er_basename}_meg.fif'), overwrite=True) # Write raw file data using mne-bids, and remove participants.tsv # as it's incomplete (doesn't contain the emptyroom subject we wrote # manually using MNE's Raw.save() above) raw = mne.io.read_raw_fif(raw_fname) write_raw_bids(raw, bids_basename, bids_root, overwrite=True) os.remove(op.join(bids_root, 'participants.tsv')) with pytest.warns(RuntimeWarning, match='Could not retrieve .* date'): get_matched_empty_room(bids_basename=bids_basename, bids_root=bids_root)
def test_vhdr(): """Test raw_to_bids conversion for BrainVision data.""" output_path = _TempDir() data_path = op.join(base_path, 'brainvision', 'tests', 'data') raw_fname = op.join(data_path, 'test.vhdr') raw_to_bids(subject_id=subject_id, session_id=session_id, run=run, task=task, acquisition=acq, raw_file=raw_fname, output_path=output_path, overwrite=False, kind='eeg') cmd = ['bids-validator', '--bep006', output_path] run_subprocess(cmd, shell=shell) # create another bids folder with the overwrite command and check # no files are in the folder data_path = make_bids_folders(subject=subject_id, session=session_id, kind='eeg', root=output_path, overwrite=True) assert len([f for f in os.listdir(data_path) if op.isfile(f)]) == 0
def test_vhdr(_bids_validate): """Test write_raw_bids conversion for BrainVision data.""" output_path = _TempDir() data_path = op.join(base_path, 'brainvision', 'tests', 'data') raw_fname = op.join(data_path, 'test.vhdr') raw = mne.io.read_raw_brainvision(raw_fname) # inject a bad channel assert not raw.info['bads'] injected_bad = ['FP1'] raw.info['bads'] = injected_bad # write with injected bad channels write_raw_bids(raw, bids_basename_minimal, output_path, overwrite=False) _bids_validate(output_path) # read and also get the bad channels raw = read_raw_bids(bids_basename_minimal + '_eeg.vhdr', output_path) with pytest.raises(TypeError, match="unexpected keyword argument 'foo'"): read_raw_bids(bids_basename_minimal + '_eeg.vhdr', output_path, extra_params=dict(foo='bar')) # Check that injected bad channel shows up in raw after reading np.testing.assert_array_equal(np.asarray(raw.info['bads']), np.asarray(injected_bad)) # Test that correct channel units are written ... and that bad channel # is in channels.tsv channels_tsv_name = op.join(output_path, 'sub-{}'.format(subject_id), 'eeg', bids_basename_minimal + '_channels.tsv') data = _from_tsv(channels_tsv_name) assert data['units'][data['name'].index('FP1')] == 'µV' assert data['units'][data['name'].index('CP5')] == 'n/a' assert data['status'][data['name'].index(injected_bad[0])] == 'bad' # check events.tsv is written events_tsv_fname = channels_tsv_name.replace('channels', 'events') assert op.exists(events_tsv_fname) # create another bids folder with the overwrite command and check # no files are in the folder data_path = make_bids_folders(subject=subject_id, kind='eeg', output_path=output_path, overwrite=True) assert len([f for f in os.listdir(data_path) if op.isfile(f)]) == 0 # test anonymize and convert raw = mne.io.read_raw_brainvision(raw_fname) _test_anonymize(raw, bids_basename) # Also cover iEEG # We use the same data and pretend that eeg channels are ecog raw = mne.io.read_raw_brainvision(raw_fname) raw.set_channel_types({raw.ch_names[i]: 'ecog' for i in mne.pick_types(raw.info, eeg=True)}) output_path = _TempDir() write_raw_bids(raw, bids_basename, output_path, overwrite=False) _bids_validate(output_path)
def convert_to_bids(filename, subject, bids_folder): subject = subject.replace('sub-', '') data = read_file(filename) session = data['SessionDate'][:-1].replace('-', '').replace(':', '') bpath = pathlib.Path( bids_folder, make_bids_folders(subject=subject, session=session, make_dir=False)) sourcename = make_bids_basename(subject=subject, session=session) sourcefolder = pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata') tb.mkdir(sourcefolder) shutil.copyfile(filename, pathlib.Path(sourcefolder, sourcename + '.json')) plot_LfpFrequencySnapshotEvents( pathlib.Path(sourcefolder, sourcename + '.json')) LfpMontageTimeDomain_to_bids(filename, subject, bids_folder) BrainSenseTimeDomain_to_bids(filename, subject, bids_folder) IndefiniteStreaming_to_bids(filename, subject, bids_folder) plt.close('all')
def BrainSenseTimeDomain_to_bids(filename, subject, bids_folder='/bids', task='BrainSenseTimeDomain'): data = read_file(filename) opath, fname, ext = tb.fileparts(filename) if subject.find('-') > 0: subject = subject[subject.find('-') + 1:] session = data['SessionDate'][:-1].replace('-', '').replace(':', '') basename = make_bids_basename(subject=subject, task=task, session=session) bpath = make_bids_folders(subject=subject, session=session, make_dir=False) sourcename = make_bids_basename(subject=subject, session=session) raw = import_BrainSenseTimeDomain(filename) if raw is not None: rfig = raw.plot(color='k') rfig.savefig( pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', 'figures', basename + '.png')) if os.path.exists('tmp.edf'): os.remove('tmp.edf') ephys.mne_write_edf(raw, 'tmp.edf') raw = mne.io.read_raw_edf('tmp.edf') write_raw_bids(raw, bids_basename=basename, output_path=bids_folder, overwrite=True) if not os.path.isdir( pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata')): os.makedirs(pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata')) shutil.copyfile( filename, pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', basename + ext)) plot_wavelet_spectra(pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', basename + ext), typefield=task) plot_BrainSenseLfp( pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', basename + ext)) os.remove('tmp.edf') shutil.move( pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', basename + ext), pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', sourcename + ext))
def test_make_folders(): """Test that folders are created and named properly.""" # Make sure folders are created properly output_path = _TempDir() make_bids_folders(subject='hi', session='foo', kind='ba', output_path=output_path) assert op.isdir(op.join(output_path, 'sub-hi', 'ses-foo', 'ba')) # If we remove a kwarg the folder shouldn't be created output_path = _TempDir() make_bids_folders(subject='hi', kind='ba', output_path=output_path) assert op.isdir(op.join(output_path, 'sub-hi', 'ba')) # check overwriting of folders make_bids_folders(subject='hi', kind='ba', output_path=output_path, overwrite=True, verbose=True)
def test_vhdr(): """Test write_raw_bids conversion for BrainVision data.""" output_path = _TempDir() data_path = op.join(base_path, 'brainvision', 'tests', 'data') raw_fname = op.join(data_path, 'test.vhdr') raw = mne.io.read_raw_brainvision(raw_fname) write_raw_bids(raw, bids_basename, output_path, overwrite=False) cmd = ['bids-validator', '--bep006', output_path] run_subprocess(cmd, shell=shell) # Test that correct channel units are written channels_tsv_name = op.join(output_path, 'sub-' + subject_id, 'ses-' + session_id, 'eeg', bids_basename + '_channels.tsv') df = pd.read_csv(channels_tsv_name, sep='\t', keep_default_na=False) assert df.loc[df['name'] == 'FP1', 'units'].all() == 'µV' assert df.loc[df['name'] == 'CP5', 'units'].all() == 'n/a' # create another bids folder with the overwrite command and check # no files are in the folder data_path = make_bids_folders(subject=subject_id, session=session_id, kind='eeg', output_path=output_path, overwrite=True) assert len([f for f in os.listdir(data_path) if op.isfile(f)]) == 0 # Also cover iEEG # We use the same data and pretend that eeg channels are ecog raw.set_channel_types( {raw.ch_names[i]: 'ecog' for i in mne.pick_types(raw.info, eeg=True)}) output_path = _TempDir() write_raw_bids(raw, bids_basename, output_path, overwrite=False) cmd = ['bids-validator', '--bep010', output_path] run_subprocess(cmd, shell=shell)
def test_get_matched_emptyroom_ties(): """Test that we receive a warning on a date tie.""" bids_root = _TempDir() session = '20010101' er_dir = make_bids_folders(subject='emptyroom', session=session, kind='meg', bids_root=bids_root) meas_date = (datetime.strptime(session, '%Y%m%d').replace(tzinfo=timezone.utc)) raw = mne.io.read_raw_fif(raw_fname) er_raw_fname = op.join(data_path, 'MEG', 'sample', 'ernoise_raw.fif') raw.copy().crop(0, 10).save(er_raw_fname, overwrite=True) er_raw = mne.io.read_raw_fif(er_raw_fname) if check_version('mne', '0.20'): raw.set_meas_date(meas_date) er_raw.set_meas_date(meas_date) else: raw.info['meas_date'] = (meas_date.timestamp(), 0) er_raw.info['meas_date'] = (meas_date.timestamp(), 0) write_raw_bids(raw, bids_basename, bids_root, overwrite=True) er_bids_path = BIDSPath(subject='emptyroom', session=session) er_basename_1 = str(er_bids_path) er_basename_2 = make_bids_basename(subject='emptyroom', session=session, task='noise') er_raw.save(op.join(er_dir, f'{er_basename_1}_meg.fif')) er_raw.save(op.join(er_dir, f'{er_basename_2}_meg.fif')) with pytest.warns(RuntimeWarning, match='Found more than one'): get_matched_empty_room(bids_basename=bids_basename, bids_root=bids_root)
def convert_to_bids( edf_fpath, bids_root, bids_basename, coords_fpath=None, excluded_contacts=None, eog_contacts=None, misc_contacts=None, overwrite=False, line_freq=60.0, ): """ Convert the passed edf file into the Bids format. # TODO: - Clean up how write_raw_bids is called - eliminate redundant writing/reading using temporaryDirectory Parameters ---------- edf_fpath : Union[str, os.PathLike] The location the edf file. bids_root : Union[str, os.PathLike] The base directory for newly created bids files. bids_basename : str The base name of the new data files excluded_contacts : list Contacts to be excluded from conversion eog_contacts : list Contacts to be annotated as EOG. misc_contacts : list Contacts to be annotated as Misc. overwrite : bool Whether to overwrite an existing converted file. Returns ------- The path to the new data file. """ if excluded_contacts is None: excluded_contacts = ["-", ""] raw = mne.io.read_raw_edf( edf_fpath, preload=False, verbose="ERROR", exclude=excluded_contacts, eog=eog_contacts, misc=misc_contacts, ) if line_freq is not None: raw.info["line_freq"] = line_freq annonymize_dict = None # { # "daysback": 10000, # "keep_his": True, # } # extract parameters from bids_basenmae params = _parse_bids_filename(bids_basename, True) subject, session = params["sub"], params["ses"] acquisition, kind = params["acq"], params["kind"] task = params["task"] # read in the events from the EDF file events_data, events_id = mne.events_from_annotations(raw) print(events_data, events_id) channel_scrub = ChannelScrub # convert the channel types based on acquisition if necessary if acquisition is not None: ch_modality_map = {ch: acquisition for ch in raw.ch_names} raw.set_channel_types(ch_modality_map) ch_type_mapping = channel_scrub.label_channel_types(raw.ch_names) raw.set_channel_types((ch_type_mapping)) # reformat channel text if necessary channel_scrub.channel_text_scrub(raw) # look for bad channels that are obvious channel_names = raw.ch_names bad_channels = channel_scrub.look_for_bad_channels(channel_names) bad_channels_dict = {} for bad in bad_channels: bad_channels_dict[ bad] = f"Scrubbed channels containing markers {', '.join(BAD_MARKERS)}" raw.info["bads"] = bad_channels if coords_fpath: ch_pos = dict() with open(coords_fpath, "r") as fp: # strip of newline character lines = [line.rstrip("\n") for line in fp] for line in lines: ch_name = line.split(" ")[0] coord = line.split(" ")[1:] ch_pos[ch_name] = [float(x) for x in coord] unit = "mm" if unit != "m": ch_pos = { ch_name: np.divide(coord, 1000) for ch_name, coord in ch_pos.items() } montage = mne.channels.make_dig_montage(ch_pos=ch_pos, coord_frame="head") # TODO: remove. purely for testing scenario # ch_names = raw.ch_names # elec = np.random.random_sample((len(ch_names), 3)) # assume in mm # elec = elec / 1000 # convert to meters # montage = mne.channels.make_dig_montage(ch_pos=dict(zip(ch_names, elec)), # coord_frame='head') else: montage = None if montage is not None: if not isinstance(montage, mne.channels.DigMontage): raise TypeError("Montage passed in should be of type: " "`mne.channels.DigMontage`.") raw.set_montage(montage) print("Set montage: ") print(len(raw.info["ch_names"])) print(raw.info["dig"]) print(raw) # actually perform write_raw bids bids_root = write_raw_bids( raw, bids_basename, bids_root, events_data=events_data, event_id=events_id, overwrite=overwrite, # anonymize=annonymize_dict, verbose=False, ) # save a fif copy and reload it kind = _handle_kind(raw) fif_data_path = make_bids_folders( subject=subject, session=session, kind=kind, output_path=bids_root, overwrite=False, verbose=True, ) bids_fname = bids_basename + f"_{kind}.fif" deriv_bids_root = os.path.join(bids_root, "derivatives") print("Should be saving for: ", bids_fname) with tempfile.TemporaryDirectory() as tmp_bids_root: raw.save(os.path.join(tmp_bids_root, bids_fname), overwrite=overwrite) raw = mne.io.read_raw_fif(os.path.join(tmp_bids_root, bids_fname)) print(raw, bids_basename) print(raw.filenames) _, ext = _parse_ext(raw.filenames[0]) print(ext) # actually perform write_raw bids bids_root = write_raw_bids( raw, bids_basename, deriv_bids_root, events_data=events_data, event_id=events_id, overwrite=overwrite, # anonymize=annonymize_dict, verbose=False, ) return bids_root
sys.stderr.write('No _HS.txt file found in raw directory') sys.exit(3) stim_dir = os.path.join(bids_path, 'stimuli') raws = mne_read_raw_kit(sqd_files, mrk_files[0], elp_file, hsp_file, subject=sub) for ii in range(len(raws)): bname = os.path.split(raws[ii].filenames[0])[1]; bname = '.'.join(bname.split('.')[:-1]) bdata = {kk[0]:kk[1] for pp in bname.split('_') for kk in [pp.split('-')] if len(kk) == 2} mne_bids.write_raw_bids(raws[ii], bname, bids_path, events_data=None, overwrite=True, verbose=False) # since mne_bids doesn't correctly write out our events data... pnm = mne_bids.make_bids_folders(subject=bdata['sub'], kind='meg', session=bdata['ses'], make_dir=False, output_path=bids_path) edata_in = os.path.join(meta_path, bname + '.tsv') edata_out = os.path.join(pnm, bname + '_events.tsv') edata = pandas.read_csv(edata_in, sep='\t') ts = triggers(raws[ii]) wh = np.where(ts > 0)[0] edata['onset'] = wh / 1000.0 edata.to_csv(edata_out, sep='\t', index=False) # we need to make the stimulus directory also... if not os.path.isdir(stim_dir): os.makedirs(stim_dir) mdata_in = os.path.join(meta_path, bname + '.mat') mdata_out = os.path.join(stim_dir, bname + '.mat') shutil.copyfile(mdata_in, mdata_out) # Done!
# final file path. Omitted keys will not be included in the file path. bids_basename = make_bids_basename(subject='test', session='two', task='mytask', suffix='data.csv') print(bids_basename) ############################################################################### # You may also omit the suffix, which will result in *only* a prefix for a # file name. This could then prepended to many more files. bids_basename = make_bids_basename(subject='test', task='mytask') print(bids_basename) ############################################################################### # Creating folders # ---------------- # # You can also use MNE-BIDS to create folder hierarchies. path_folder = make_bids_folders('sub_01', session='mysession', kind='meg', output_path='path/to/project', make_dir=False) print(path_folder) # Note that passing `make_dir=True` will create the folder hierarchy, ignoring # errors if the folder already exists.
def convert(container, settings, parent=None): """ Main function to take all the data from some container (IC or fif file currently) and call the bids conversion function (from mne_bids). parent is the main GUI object """ # first, make sure that the container obejct is ready for conversion container.prepare() # Construct a name for storing 2 weeks worth of BIDS formatted data. # We chunk into 2 week blocks for ease of uploading to the MEG_RAW archive. chunk_length = settings.get('CHUNK_FREQ', 14) if chunk_length == 0: subfolder_name = '' else: curr_date = date.today() subfolder_name = 'BIDS-{0}-{1}'.format( get_year(curr_date), get_chunk_num(curr_date, chunk_length)) # Find the SID of the BIDS folder. bids_root_folder_path = op.join(settings['DATA_PATH'], 'BIDS') bids_folder_path = op.join(bids_root_folder_path, subfolder_name) # Determine if the BIDS-YYYY-FF folder exists already: bidstree_folder_exists = op.exists(bids_folder_path) # Create variables for the dynamic displaying of the process. # We unfortunately cannot get particularly granular or precise progress # tracking due to the fact that the conversion is done externally. progress = StreamedVar(['Writing', 'Conversion done'], {'Writing': _shorten_path}) job_name = StringVar() has_error = False p = ProgressPopup(parent, progress, job_name) target_folder = op.join(bids_folder_path, container.proj_name.get()) # redict the stout to the StreamedVar as a way of capturing progress with redirect_stdout(progress): for job in container.jobs: if job.is_junk.get(): continue extra_data = job.extra_data emptyroom_path = '' rec_date = None if 'Measurement date' in job.info: date_vals = job.info['Measurement date'].split('/') date_vals.reverse() rec_date = ''.join(date_vals) # also check to see if the file is meant to have an associated # empty room file if job.has_empty_room.get() is True: # we will auto-construct a file path based on the date of # creation of the con file # TODO: make this more robust? emptyroom_path = ('sub-emptyroom/ses-{0}/meg/' 'sub-emptyroom_ses-{0}_task-' 'noise_meg.con'.format(rec_date)) # get the variables for the raw_to_bids conversion function: if job.is_empty_room.get(): if rec_date is None: warn('Recording date is not known. Emptry room cannot be ' 'exported.') continue subject_id = 'emptyroom' sess_id = rec_date subject_group = 'n/a' task = 'noise' run = None job.raw.info['subject_info'] = None else: subject_id = container.subject_ID.get() sess_id = container.session_ID.get() if sess_id == '': sess_id = None subject_group = container.subject_group.get() task = job.task.get() if task == 'None': task = None run = job.run.get() if run == '': run = None if emptyroom_path != '': extra_data['AssociatedEmptyRoom'] = emptyroom_path # TODO: change this to just use the event_info property trigger_channels, descriptions = job.get_event_data() # assume there is only one for now?? event_ids = dict( zip(descriptions, [int(i) for i in trigger_channels])) job_name.set("Task: {0}, Run: {1}".format(task, run)) try: bids_name = make_bids_basename(subject=subject_id, session=sess_id, task=task, run=run) write_raw_bids(raw=job.raw, bids_basename=bids_name, output_path=target_folder, event_id=event_ids, overwrite=True, verbose=True) bids_path = make_bids_folders(subject=subject_id, session=sess_id, kind='meg', output_path=target_folder, make_dir=False) update_sidecar( op.join(bids_path, '{0}_meg.json'.format(bids_name)), extra_data) update_participants( op.join(target_folder, 'participants.tsv'), ('sub-{0}'.format(subject_id), subject_group)) write_readme(op.join(target_folder, 'README.txt'), container.readme) modify_dataset_description( op.join(target_folder, 'dataset_description.json'), container.proj_name.get()) update_markers(job, bids_path, bids_name) if subject_id == 'emptyroom': clean_emptyroom(bids_path) except: # noqa # We want to actually just catch any error and print a # message. progress.curr_value.set("An error occurred during the " "conversion process.\nPlease check " "the python console to see the error.") has_error = True raise new_sids = parent.file_treeview.refresh() if not bidstree_folder_exists: assign_bids_folder(bids_folder_path, parent.file_treeview, parent.preloaded_data) else: # assign any new BIDS data assign_bids_data(new_sids, parent.file_treeview, parent.preloaded_data) # find the first instance from the newly added folders that is a # bidshandler.Session object and set this is the focus of the treeview. for sid in new_sids: if isinstance(parent.preloaded_data.get(sid, None), Session): parent.file_treeview.see(sid) parent.file_treeview.focus(item=sid) # sid added as a tuple for pre-3.6 compatibilty parent.file_treeview.selection_set((sid, )) break if not has_error: # copy over any extra files: for file in container.extra_files: ext = op.splitext(file)[1] if ext in ['.m', '.py']: dst = op.join(target_folder, 'code') else: dst = op.join(target_folder, 'sub-{0}'.format(subject_id), 'ses-{0}'.format(sess_id), 'extras') if not op.exists(dst): os.makedirs(dst) shutil.copy(file, dst) progress.curr_value.set("Conversion done! Closing window in 3...") sleep(1) progress.curr_value.set("Conversion done! Closing window in 2...") sleep(1) progress.curr_value.set("Conversion done! Closing window in 1...") sleep(1) p._exit() # This is essentially useless but it suppresses pylint:E1111 return True
ct_fpath = Path(deriv_dir / "CT" / "CT.nii") # get the post -> pre T1 affine post_to_pre_affine = np.loadtxt( Path(postsurg_dir / "fsl_postt1-to-t1_omat.txt")) pre_to_post_affine = np.linalg.inv(post_to_pre_affine) # print(surgmask_arr.shape, t1w_img.shape) # print(surgmask_hdr) # print(aff2axcodes(t1w_img.affine)) # print(aff2axcodes(post_to_pre_affine)) # print(nb.io_orientation(t1w_img.affine)) # read in electrodes subj_dir = make_bids_folders(bids_root=bids_root.as_posix(), subject=subject, session="veeg", make_dir=False) # get electrodes electrodes_fpath = make_bids_basename( subject=subject, session="veeg", processing="manual", acquisition="seeg", prefix=subj_dir, suffix="electrodes.tsv", ) electrodes_tsv = _from_tsv(electrodes_fpath) ch_names = electrodes_tsv["name"] ch_coords = np.vstack((electrodes_tsv["x"], electrodes_tsv["y"], electrodes_tsv["z"])).T.astype(float)
def _setup_main_eeg(): """ We copy some explicit example from MNE-BIDS and modify small details. Specifically, we will follow these steps: 1. Download repository, and use the data in example directory: data/ bids_layout/ sourcedata/ derivatives/ sub-XXX/ sub-XXY/ ... 2. Load the source raw data, extract information, preprocess certain things and save in a new BIDS directory 3. Check the result and compare it with the standard """ ############################################################################### # Step 1: Prepare the data # ------------------------- # # First, we need some data to work with. We will use some sample simulated scalp and # iEEG data. For each subject, there are "seizure" events. For the present example, we will # show how to format the data for two modalities to comply with the Brain Imaging Data Structure # (`BIDS <http://bids.neuroimaging.io/>`_). # # The data are in the `European Data Format <https://www.edfplus.info/>`_ # '.edf', which is good for us because next to the BrainVision format, EDF is # one of the recommended file formats for EEG BIDS. However, apart from the # data format, we need to build a directory structure and supply meta data # files to properly *bidsify* this data. # # Conveniently, there is already a data loading function available with # MNE-Python: DATADIR = os.getcwd() bids_root = os.path.join(DATADIR, "./data/bids_layout/") RUN_IEEG = False # either run scalp, or iEEG line_freq = ( 60 # user should set the line frequency, since MNE-BIDS defaults to 50 Hz ) test_subjectid = "0001" test_sessionid = "seizure" test_task = "monitor" authors = ["Adam Li", "Patrick Myers"] if RUN_IEEG: edf_fpaths = [ os.path.join(bids_root, "sourcedata", "ieeg_ecog_test.edf") ] modality = "ecog" else: edf_fpath1 = os.path.join(bids_root, "sourcedata", "scalp_test.edf") edf_fpath2 = os.path.join(bids_root, "sourcedata", "scalp_test_2.edf") edf_fpaths = [edf_fpath1, edf_fpath2] modality = "eeg" ############################################################################### # Let's see whether the data has been downloaded using a quick visualization # of the directory tree. data_dir = os.path.join(bids_root, "sourcedata") print_dir_tree(data_dir) ############################################################################### # Step 2: Formatting as BIDS # -------------------------- # # Let's start by formatting a single subject. We are reading the data using # MNE-Python's io module and the :func:`read_raw_edf` function. Note that we # must use `preload=False`, the default in MNE-Python. It prevents the data # from being loaded and modified when converting to BIDS. # # Note that kind and acquisition currently almost stand for the same thing. # Please read the BIDS docs to get acquainted. # create the BIDS directory structure if not os.path.exists(bids_root): print("Making bids root directory.") make_bids_folders( output_path=bids_root, session=test_sessionid, subject=test_subjectid, kind=modality, ) for i, edf_fpath in enumerate(edf_fpaths): """ Write data file into BIDS format """ test_runid = i # add a bids run bids_basename = make_bids_basename( subject=test_subjectid, session=test_sessionid, task=test_task, run=test_runid, acquisition=modality, ) print("Loading filepath: ", edf_fpath) print("Writing to bidsroot: ", bids_root) print("Bids basenmae; ", bids_basename) # call bidsbuilder pipeline bids_deriv_root = BidsConverter.convert_to_bids( edf_fpath=edf_fpath, bids_root=bids_root, bids_basename=bids_basename, line_freq=line_freq, overwrite=True, ) # currently write_raw_bids overwrites make_dataset_description # TODO: put this on the top when PR gets merged. make_dataset_description(os.path.join(bids_root), name="test_bids_dataset", authors=authors) ############################################################################### # What does our fresh BIDS directory look like? print_dir_tree(bids_root) ############################################################################### # Step 3: Check and compare and read in the data # ------------------------------------------------------------ # Now we have written our BIDS directory. if modality in ["ecog", "seeg"]: kind = "ieeg" elif modality == "eeg": kind = "eeg" bids_fname = bids_basename + f"_{kind}.edf" print("Trying to read from: ", bids_fname) # use MNE-BIDS function to read in the data raw = read_raw_bids(bids_fname, bids_root) print("Read successfully using MNE-BIDS") # use BidsRun object, which just simply adds additional functionality # bidsrun = BidsRun(tmp_bids_root, bids_fname) # raw = bidsrun.load_data() print(raw) ############################################################################### # Step 4: Run BIDS-Validate # ------------------------------------------------------------ # Now we have written our BIDS directory. # save a fif copy and reload it # TODO: re-check when pybids is updated. # currently, use the https://bids-standard.github.io/bids-validator/ and see that it is verified params = _parse_bids_filename(bids_basename, True) print(raw.info) fif_data_path = make_bids_folders( subject=params["sub"], session=params["ses"], kind=kind, output_path=bids_root, overwrite=False, verbose=True, ) rel_bids_root = f"/sub-0001/ses-seizure/{kind}/" path = os.path.join(rel_bids_root, bids_fname) is_valid = BIDSValidator().is_bids(path) print(BIDSValidator().is_top_level(path)) print(BIDSValidator().is_associated_data(path)) print(BIDSValidator().is_session_level(path)) print(BIDSValidator().is_subject_level(path)) print(BIDSValidator().is_phenotypic(path)) print(BIDSValidator().is_file(path)) print("checked filepath: ", os.path.join(rel_bids_root, bids_fname)) print(is_valid)
# -------------------------- # # Let's start by formatting a single subject. We are reading the data using # MNE-Python's io module and the :func:`read_raw_edf` function. Note that we # must use `preload=False`, the default in MNE-Python. It prevents the data # from being loaded and modified when converting to BIDS. # # Note that kind and acquisition currently almost stand for the same thing. # Please read the BIDS docs to get acquainted. # create the BIDS directory structure if not os.path.exists(bids_root): print("Making bids root directory.") make_bids_folders( session=test_sessionid, subject=test_subjectid, kind=modality, output_path=bids_root, ) for i, edf_fpath in enumerate(edf_fpaths): """ Write data file into BIDS format """ test_runid = i # add a bids run bids_basename = make_bids_basename( subject=test_subjectid, session=test_sessionid, task=test_task, run=test_runid, acquisition=modality, )
# -------------------------- # # Let's start by formatting a single subject. We are reading the data using # MNE-Python's io module and the :func:`read_raw_edf` function. Note that we # must use `preload=False`, the default in MNE-Python. It prevents the data # from being loaded and modified when converting to BIDS. # # Note that kind and acquisition currently almost stand for the same thing. # Please read the BIDS docs to get acquainted. # create the BIDS directory structure if not os.path.exists(bids_root): print("Making bids root directory.") make_bids_folders( output_path=bids_root, session=test_sessionid, subject=test_subjectid, kind=modality, ) coords_fpath = os.path.join(bids_root, "sourcedata", "ieeg_ecog_coords.txt") for i, edf_fpath in enumerate(edf_fpaths): """ Write data file into BIDS format """ test_runid = i # add a bids run bids_basename = make_bids_basename( subject=test_subjectid, session=test_sessionid, task=test_task, run=test_runid,
raws = mne_read_raw_kit(sqd_files, mrk_files[0], elp_file, hsp_file, subject=sub) for ii in range(len(raws)): bname = os.path.split(raws[ii].filenames[0])[1]; bname = '.'.join(bname.split('.')[:-1]) bdata = {kk[0]:kk[1] for pp in bname.split('_') for kk in [pp.split('-')] if len(kk) == 2} # Mark the bad channels as bad... bad_chs = find_bad_channels(raws[ii]) raws[ii].info['bads'] = bad_chs # Write out the raw bids via MNE mne_bids.write_raw_bids(raws[ii], bname, bids_path, events_data=None, overwrite=True, verbose=False) # since mne_bids doesn't correctly write out our events data... pnm = mne_bids.make_bids_folders(subject=bdata['sub'], kind='meg', session=bdata['ses'], make_dir=False, output_path=bids_path) edata_in = os.path.join(meta_path, bname + '.tsv') edata_out = os.path.join(pnm, bname + '_events.tsv') edata = pandas.read_csv(edata_in, sep='\t') ts = triggers(raws[ii]) wh = np.where(ts > 0)[0] if len(wh) != len(edata['onset']): # this is probably because of near-0 duration items edata = edata.loc[edata['duration'] > 0.05] print(len(edata), len(wh)) print(wh) print(edata) edata['onset'] = wh / 1000.0 edata.to_csv(edata_out, sep='\t', index=False) # we need to make the stimulus directory also...
# eyetrack. note, the BEP for eyetracking isn't merged # but this is likely the naming convention for it for subject, experiments in config.exp_list.items(): subname = 'sub-{}'.format(subject) for ii, exp in enumerate(experiments, 1): if exp != 'n/a': bids_basename = make_bids_basename(subject=subject, run='{:02d}'.format(ii), task=project_name) bids_eyetrack = op.join(output_path, subname, 'eyetrack', bids_basename + '_eyetrack.edf') input_fname = op.join(input_path, subject, 'edf', '{}_{}.edf'.format(subject, exp)) make_bids_folders(subject=subject, kind='eyetrack', output_path=output_path) sh.copyfile(input_fname, bids_eyetrack) # make a dataset description make_dataset_description( path=output_path, data_license='CC-BY', name=project_name, authors=[ 'Teon L Brooks', 'Laura Gwilliams', 'Alexandre Gramfort', 'Alec Marantz' ], how_to_acknowledge='', funding=['NSF DGE-1342536 (TB)', 'Abu Dhabi Institute Grant G1001 (AM)'], references_and_links='',
# pieces of metadata, ensuring that they are in the correct order in the # final file path. Omitted keys will not be included in the file path. bids_basename = make_bids_basename(subject='test', session='two', task='mytask', suffix='events.tsv') print(bids_basename) ############################################################################### # You may also omit the suffix, which will result in *only* a prefix for a # file name. This could then prepended to many more files. bids_basename = make_bids_basename(subject='test', task='mytask') print(bids_basename) ############################################################################### # Creating folders # ---------------- # # You can also use MNE-BIDS to create folder hierarchies. path_folder = make_bids_folders(subject='01', session='mysession', kind='meg', bids_root='path/to/project', make_dir=False) print(path_folder) # Note that passing `make_dir=True` will create the folder hierarchy. If that # path already exists, you can make use of the `overwrite` parameter. # If `overwrite=False` then no existing folders will be removed, however # if `overwrite=True` then any existing folders at the session level # or lower will be removed, including any contained data.