def test_edf(_bids_validate): """Test write_raw_bids conversion for European Data Format data.""" output_path = _TempDir() data_path = op.join(testing.data_path(), 'EDF') raw_fname = op.join(data_path, 'test_reduced.edf') raw = mne.io.read_raw_edf(raw_fname, preload=True) # XXX: hack that should be fixed later. Annotation reading is # broken for this file with preload=False and read_annotations_edf raw.preload = False raw.rename_channels({raw.info['ch_names'][0]: 'EOG'}) raw.info['chs'][0]['coil_type'] = FIFF.FIFFV_COIL_EEG_BIPOLAR raw.rename_channels({raw.info['ch_names'][1]: 'EMG'}) raw.set_channel_types({'EMG': 'emg'}) write_raw_bids(raw, bids_basename, output_path) # Reading the file back should raise an error, because we renamed channels # in `raw` and used that information to write a channels.tsv. Yet, we # saved the unchanged `raw` in the BIDS folder, so channels in the TSV and # in raw clash with pytest.raises(RuntimeError, match='Channels do not correspond'): read_raw_bids(bids_basename + '_eeg.edf', output_path) bids_fname = bids_basename.replace('run-01', 'run-%s' % run2) write_raw_bids(raw, bids_fname, output_path, overwrite=True) _bids_validate(output_path) # ensure there is an EMG channel in the channels.tsv: channels_tsv = make_bids_basename(subject=subject_id, session=session_id, task=task, run=run, suffix='channels.tsv', acquisition=acq, prefix=op.join(output_path, 'sub-01', 'ses-01', 'eeg')) data = _from_tsv(channels_tsv) assert 'ElectroMyoGram' in data['description'] # check that the scans list contains two scans scans_tsv = make_bids_basename(subject=subject_id, session=session_id, suffix='scans.tsv', prefix=op.join(output_path, 'sub-01', 'ses-01')) data = _from_tsv(scans_tsv) assert len(list(data.values())[0]) == 2 # 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) _bids_validate(output_path)
def test_copyfile_kit(): """Test copying and renaming KIT files to a new location.""" output_path = _TempDir() data_path = op.join(base_path, 'kit', 'tests', 'data') raw_fname = op.join(data_path, 'test.sqd') hpi_fname = op.join(data_path, 'test_mrk.sqd') electrode_fname = op.join(data_path, 'test.elp') headshape_fname = op.join(data_path, 'test.hsp') subject_id = '01' session_id = '01' run = '01' acq = '01' task = 'testing' bids_basename = make_bids_basename( subject=subject_id, session=session_id, run=run, acquisition=acq, task=task) kit_bids_basename = bids_basename.copy().update(acquisition=None, prefix=output_path) raw = mne.io.read_raw_kit( raw_fname, mrk=hpi_fname, elp=electrode_fname, hsp=headshape_fname) _, ext = _parse_ext(raw_fname, verbose=True) kind = _handle_kind(raw) bids_fname = str(bids_basename.copy().update(suffix=f'{kind}{ext}', prefix=output_path)) copyfile_kit(raw_fname, bids_fname, subject_id, session_id, task, run, raw._init_kwargs) assert op.exists(bids_fname) _, ext = _parse_ext(hpi_fname, verbose=True) if ext == '.sqd': kit_bids_basename.suffix = 'markers.sqd' assert op.exists(kit_bids_basename) elif ext == '.mrk': kit_bids_basename.suffix = 'markers.mrk' assert op.exists(kit_bids_basename) if op.exists(electrode_fname): task, run, key = None, None, 'ELP' elp_ext = '.pos' elp_fname = make_bids_basename( subject=subject_id, session=session_id, task=task, run=run, acquisition=key, suffix='headshape%s' % elp_ext, prefix=output_path) assert op.exists(elp_fname) if op.exists(headshape_fname): task, run, key = None, None, 'HSP' hsp_ext = '.pos' hsp_fname = make_bids_basename( subject=subject_id, session=session_id, task=task, run=run, acquisition=key, suffix='headshape%s' % hsp_ext, prefix=output_path) assert op.exists(hsp_fname)
def run_ssp(subject, session=None): print("Processing subject: %s" % subject) print(" Loading one run to compute SSPs") # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) # compute SSP on first run of raw run = config.runs[0] bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=run, processing=config.proc, recording=config.rec, space=config.space) # Prepare a name to save the data fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) raw_fname_in = \ op.join(fpath_deriv, bids_basename + '_filt_raw.fif') # when saving proj, use bids_basename=None bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) proj_fname_out = op.join(fpath_deriv, bids_basename + '_ssp-proj.fif') print("Input: ", raw_fname_in) print("Output: ", proj_fname_out) raw = mne.io.read_raw_fif(raw_fname_in) # XXX : n_xxx should be options in config print(" Computing SSPs for ECG") ecg_projs, ecg_events = \ compute_proj_ecg(raw, n_grad=1, n_mag=1, n_eeg=0, average=True) print(" Computing SSPs for EOG") eog_projs, eog_events = \ compute_proj_eog(raw, n_grad=1, n_mag=1, n_eeg=1, average=True) mne.write_proj(proj_fname_out, eog_projs + ecg_projs)
def test_bids_path(return_bids_test_dir): """Test usage of BIDSPath object.""" bids_root = return_bids_test_dir bids_basename = make_bids_basename( subject=subject_id, session=session_id, run=run, acquisition=acq, task=task) # get_bids_fname should fire warning with pytest.raises(ValueError, match='No filename extension was provided'): bids_fname = bids_basename.get_bids_fname() # should find the correct filename if bids_root was passed bids_fname = bids_basename.get_bids_fname(bids_root=bids_root) assert bids_fname == bids_basename.update(suffix='meg.fif') # confirm BIDSPath assigns properties correctly bids_basename = make_bids_basename(subject=subject_id, session=session_id) assert bids_basename.subject == subject_id assert bids_basename.session == session_id assert 'subject' in bids_basename.entities assert 'session' in bids_basename.entities print(bids_basename.entities) assert all(bids_basename.entities.get(entity) is None for entity in ['task', 'run', 'recording', 'acquisition', 'space', 'processing', 'prefix', 'suffix']) # test updating functionality bids_basename.update(acquisition='03', run='2', session='02', task=None) assert bids_basename.subject == subject_id assert bids_basename.session == '02' assert bids_basename.acquisition == '03' assert bids_basename.run == '2' assert bids_basename.task is None new_bids_basename = bids_basename.copy().update(task='02', acquisition=None) assert new_bids_basename.task == '02' assert new_bids_basename.acquisition is None # equality of bids basename assert new_bids_basename != bids_basename assert new_bids_basename == bids_basename.copy().update(task='02', acquisition=None) # error check with pytest.raises(ValueError, match='Key must be one of*'): bids_basename.update(sub=subject_id, session=session_id) # test repr bids_path = make_bids_basename(subject='01', session='02', task='03', suffix='ieeg.edf') assert repr(bids_path) == 'BIDSPath(sub-01_ses-02_task-03_ieeg.edf)'
def run_forward(subject, session=None): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) fname_evoked = op.join(deriv_path, bids_basename + '-ave.fif') fname_trans = op.join(deriv_path, 'sub-{}'.format(subject) + '-trans.fif') fname_fwd = op.join(deriv_path, bids_basename + '-fwd.fif') msg = f'Input: {fname_evoked}, Output: {fname_fwd}' logger.info(gen_log_message(message=msg, step=10, subject=subject, session=session)) # Find the raw data file # XXX : maybe simplify bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=config.get_runs()[0], processing=config.proc, recording=config.rec, space=config.space) trans = get_head_mri_trans(bids_basename=bids_basename, bids_root=config.bids_root) mne.write_trans(fname_trans, trans) src = mne.setup_source_space(subject, spacing=config.spacing, subjects_dir=config.get_fs_subjects_dir(), add_dist=False) evoked = mne.read_evokeds(fname_evoked, condition=0) # Here we only use 3-layers BEM only if EEG is available. if 'eeg' in config.ch_types: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3, 0.006, 0.3), subjects_dir=config.get_fs_subjects_dir()) else: model = mne.make_bem_model(subject, ico=4, conductivity=(0.3,), subjects_dir=config.get_fs_subjects_dir()) bem = mne.make_bem_solution(model) fwd = mne.make_forward_solution(evoked.info, trans, src, bem, mindist=config.mindist) mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def test_kit(): """Test functionality of the write_raw_bids conversion for KIT data.""" output_path = _TempDir() data_path = op.join(base_path, 'kit', 'tests', 'data') raw_fname = op.join(data_path, 'test.sqd') events_fname = op.join(data_path, 'test-eve.txt') hpi_fname = op.join(data_path, 'test_mrk.sqd') electrode_fname = op.join(data_path, 'test_elp.txt') headshape_fname = op.join(data_path, 'test_hsp.txt') event_id = dict(cond=1) raw = mne.io.read_raw_kit(raw_fname, mrk=hpi_fname, elp=electrode_fname, hsp=headshape_fname) write_raw_bids(raw, bids_basename, output_path, events_data=events_fname, event_id=event_id, overwrite=False) cmd = ['bids-validator', output_path] run_subprocess(cmd, shell=shell) assert op.exists(op.join(output_path, 'participants.tsv')) # ensure the channels file has no STI 014 channel: channels_tsv = make_bids_basename(subject=subject_id, session=session_id, task=task, run=run, suffix='channels.tsv', acquisition=acq, prefix=op.join(output_path, 'sub-01/ses-01/meg')) df = pd.read_csv(channels_tsv, sep='\t') assert not ('STI 014' in df['name'].values) # ensure the marker file is produced in the right place raw_folder = make_bids_basename(subject=subject_id, session=session_id, task=task, run=run, acquisition=acq, suffix='%s' % 'meg') marker_fname = make_bids_basename(subject=subject_id, session=session_id, task=task, run=run, acquisition=acq, suffix='markers.sqd', prefix=os.path.join( output_path, 'sub-01/ses-01/meg', raw_folder)) assert op.exists(marker_fname)
def test_edf(): """Test write_raw_bids conversion for European Data Format data.""" output_path = _TempDir() data_path = op.join(testing.data_path(), 'EDF') raw_fname = op.join(data_path, 'test_reduced.edf') raw = mne.io.read_raw_edf(raw_fname, preload=True) # XXX: hack that should be fixed later. Annotation reading is # broken for this file with preload=False and read_annotations_edf raw.preload = False raw.rename_channels({raw.info['ch_names'][0]: 'EOG'}) raw.info['chs'][0]['coil_type'] = FIFF.FIFFV_COIL_EEG_BIPOLAR raw.rename_channels({raw.info['ch_names'][1]: 'EMG'}) raw.set_channel_types({'EMG': 'emg'}) write_raw_bids(raw, bids_basename, output_path) bids_fname = bids_basename.replace('run-01', 'run-%s' % run2) write_raw_bids(raw, bids_fname, output_path, overwrite=True) cmd = ['bids-validator', '--bep006', output_path] run_subprocess(cmd, shell=shell) # ensure there is an EMG channel in the channels.tsv: channels_tsv = make_bids_basename(subject=subject_id, session=session_id, task=task, run=run, suffix='channels.tsv', acquisition=acq, prefix=op.join(output_path, 'sub-01/ses-01/eeg')) df = pd.read_csv(channels_tsv, sep='\t') assert 'ElectroMyoGram' in df['description'].values # check that the scans list contains two scans scans_tsv = make_bids_basename(subject=subject_id, session=session_id, suffix='scans.tsv', prefix=op.join(output_path, 'sub-01/ses-01')) df = pd.read_csv(scans_tsv, sep='\t') assert df.shape[0] == 2 # 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) cmd = ['bids-validator', '--bep010', output_path] run_subprocess(cmd, shell=shell)
def run_ssp(subject, session=None): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) # compute SSP on first run of raw run = config.get_runs()[0] bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=run, processing=config.proc, recording=config.rec, space=config.space) # Prepare a name to save the data raw_fname_in = op.join(deriv_path, bids_basename + '_filt_raw.fif') # when saving proj, use bids_basename=None bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) proj_fname_out = op.join(deriv_path, bids_basename + '_ssp-proj.fif') msg = f'Input: {raw_fname_in}, Output: {proj_fname_out}' logger.info( gen_log_message(message=msg, step=4, subject=subject, session=session)) raw = mne.io.read_raw_fif(raw_fname_in) # XXX : n_xxx should be options in config msg = 'Computing SSPs for ECG' logger.debug( gen_log_message(message=msg, step=4, subject=subject, session=session)) ecg_projs, ecg_events = \ compute_proj_ecg(raw, n_grad=1, n_mag=1, n_eeg=0, average=True) msg = 'Computing SSPs for EOG' logger.debug( gen_log_message(message=msg, step=4, subject=subject, session=session)) eog_projs, eog_events = \ compute_proj_eog(raw, n_grad=1, n_mag=1, n_eeg=1, average=True) mne.write_proj(proj_fname_out, eog_projs + ecg_projs)
def rel_chanstsv_fpath(self): """ Get the path of the channel tsv file. Returns ------- Channel tsv path """ return os.path.join( make_bids_basename(subject=self.subject_id), make_bids_basename(session=self.session_id), self.kind, self._make_bids_basename(suffix="channels.tsv",), )
def rel_sidecarjson_fpath(self): """ Get the path of the sidecar json file. Returns ------- Sidecar json path """ return os.path.join( make_bids_basename(subject=self.subject_id), make_bids_basename(session=self.session_id), self.kind, self._make_bids_basename(suffix=f"{self.kind}.json",), )
def rel_datafile_fpath(self): """ Get the path of the data file. Returns ------- Data file path """ return os.path.join( make_bids_basename(subject=self.subject_id), make_bids_basename(session=self.session_id), self.kind, self._make_bids_basename(suffix=f"{self.kind}.{self.ext}",), )
def _get_bids_basename(subject, session, imgtype, ext="nii.gz", **bids_kwargs): """Wildcard function to get bids_basename.""" bids_fname = make_bids_basename(subject, session=session, **bids_kwargs, suffix=f"{imgtype}.{ext}") return bids_fname
def compute_cov_from_empty_room(subject, session): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) raw_er_fname = op.join(deriv_path, bids_basename + '_emptyroom_filt_raw.fif') cov_fname = op.join(deriv_path, bids_basename + '-cov.fif') extra_params = dict() if not config.use_maxwell_filter and config.allow_maxshield: extra_params['allow_maxshield'] = config.allow_maxshield msg = (f'Computing regularized covariance based on empty-room recording. ' f'Input: {raw_er_fname}, Output: {cov_fname}') logger.info( gen_log_message(message=msg, step=11, subject=subject, session=session)) raw_er = mne.io.read_raw_fif(raw_er_fname, preload=True, **extra_params) cov = mne.compute_raw_covariance(raw_er, method='shrunk', rank='info') cov.save(cov_fname)
def rel_scanstsv_fpath(self): """ Get the path of the scans tsv file. Returns ------- Scans tsv path """ return os.path.join( make_bids_basename(subject=self.subject_id), make_bids_basename(session=self.session_id), make_bids_basename( subject=self.subject_id, session=self.session_id, suffix="scans.tsv" ), )
def make_preprocessed_folder(datadir, subject_id, session="one", preprocess_name="preprocessed"): """ Create the preproceesed data folder in the correct location if it does not already exist. Assumes session is 'one'. Parameters ---------- datadir : Union[str, os.PathLike] The base directory for bids data subject_id : str The unique identifier for the BidsPatient session : str The identifier for this BidsPatient session preprocess_name : str The name of the preprocessed folder """ basedir = os.path.join( datadir, make_bids_basename(subject=subject_id, session=session)) preprocessed_dir = os.path.join(basedir, preprocess_name) if os.path.exists(preprocessed_dir): return 1 else: os.mkdir(preprocessed_dir)
def test_baseio(self): test_subjectid = "0001" session_id = "seizure" kind = "eeg" run_id = "01" task = "monitor" bids_basename = make_bids_basename( subject=test_subjectid, session=session_id, acquisition=kind, run=run_id, task=task, # suffix=kind + ".fif", ) ext = "fif" bids_root = os.path.join(os.getcwd(), "./data/bids_layout/") # instantiate a loader/writer loader = BidsLoader( bids_root=bids_root, bids_basename=bids_basename, kind=kind, datatype=ext, ) participant_dict = loader.load_participants_json() participant_df = loader.load_participants_tsv() scans_df = loader.load_scans_tsv() sidecar = loader.load_sidecar_json() chans_df = loader.load_channels_tsv() # check basic funcs print(loader.chanstsv_fpath) print(loader.datafile_fpath) print(loader.eventstsv_fpath) print(loader.rel_chanstsv_fpath) print(loader.rel_datafile_fpath) print(loader.rel_eventstsv_fpath) print(loader.rel_participantsjson_fpath) print(loader.rel_participantstsv_fpath) print(loader.rel_scanstsv_fpath) print(loader.rel_sidecarjson_fpath) with tempfile.TemporaryDirectory() as bids_root: writer = BidsWriter( bids_root=bids_root, bids_basename=bids_basename, kind=kind, datatype=ext, ) with pytest.raises(Exception): writer.write_channels_tsv(chans_df) with pytest.raises(Exception): writer.write_electrode_coords() with pytest.raises(Exception): writer.write_scans_tsv(scans_df) with pytest.raises(Exception): writer.write_sidecar_json(sidecar) writer.write_participants_json(participant_dict) writer.write_participants_tsv(participant_df)
def modify_participants_file(self, column_id: str, new_value: str): """ Modify the BIDS dataset participants tsv file to include a new value. Parameters ---------- column_id : str The name of the column to which data should be modified. Must exist in the tsv file new_value : str The new value of the column_id for this BidsPatient """ # load in the data and do error check and set index participants_df = self.loader.load_participants_tsv() participants_df = participants_df.set_index("participant_id") colnames = participants_df.columns if column_id not in colnames: raise ValueError( f"{column_id} not in the existing participants file. Add it first." ) # modify at the TSV level and reset_index participants_df.at[ make_bids_basename(subject=self.subject_id), column_id ] = new_value self._write_to_participants_tsv(participants_df) # recreate metadata metadata = self._create_metadata() self._load_metadata(metadata)
def compute_cov_from_epochs(subject, session, tmin, tmax): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) if config.use_ica or config.use_ssp: extension = '_cleaned-epo' else: extension = '-epo' epo_fname = op.join(deriv_path, bids_basename + '%s.fif' % extension) cov_fname = op.join(deriv_path, bids_basename + '-cov.fif') msg = (f"Computing regularized covariance based on epochs' baseline " f"periods. Input: {epo_fname}, Output: {cov_fname}") logger.info( gen_log_message(message=msg, step=11, subject=subject, session=session)) epochs = mne.read_epochs(epo_fname, preload=True) cov = mne.compute_covariance(epochs, tmin=tmin, tmax=tmax, method='shrunk', rank='info') cov.save(cov_fname)
def find_bids_run_file( subject_id, session_id, task_id, acquisition_id, run_id, kind, datadir, ext, center=None, ): """ Get the path of the data file of interest. TODO: Allow searching through other folders for preprocessed and results files for this run. TODO: Should this be done on BidsRun side? Parameters ---------- subject_id : str The unique identifier for the subject. We may need to have some mapping functions. session_id : str The identifier for the session of the subject. Again, mapping may be necessary for anonymity. task_id : str or None Identifier for the task acquisition_id: str or None Identifier for the acquisition run_id : str The identifier for the run of the subject. kind : str The type of recording datadir : Union[str, os.PathLike] Base directory containing the bids data. ext : str (fif or edf) either fif or edf center : str or None The name of the center that the patient belongs to Returns ------- bids_run_fpath: os.PathLike The location of the desired file. """ if task_id is None: task_id = DEFAULT_TASK if acquisition_id is None: acquisition_id = DEFAULT_ACQUISITION bids_root = datadir bids_fname = make_bids_basename( subject=subject_id, session=session_id, task=task_id, acquisition=acquisition_id, run=run_id, suffix=f"{kind}.{ext}", ) bids_run = BidsRun(bids_root, bids_fname) return bids_root, bids_fname, bids_run.fpath
def run_inverse(subject, session=None): print("Processing subject: %s" % subject) # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) fname_ave = \ op.join(fpath_deriv, bids_basename + '-ave.fif') fname_fwd = \ op.join(fpath_deriv, bids_basename + '-fwd.fif') fname_cov = \ op.join(fpath_deriv, bids_basename + '-cov.fif') fname_inv = \ op.join(fpath_deriv, bids_basename + '-inv.fif') evokeds = mne.read_evokeds(fname_ave) cov = mne.read_cov(fname_cov) forward = mne.read_forward_solution(fname_fwd) info = evokeds[0].info inverse_operator = make_inverse_operator(info, forward, cov, loose=0.2, depth=0.8) write_inverse_operator(fname_inv, inverse_operator) # Apply inverse snr = 3.0 lambda2 = 1.0 / snr**2 for condition, evoked in zip(config.conditions, evokeds): stc = apply_inverse(evoked, inverse_operator, lambda2, "dSPM", pick_ori=None) stc.save( op.join( fpath_deriv, '%s_%s_mne_dSPM_inverse-%s' % (config.study_name, subject, condition.replace(op.sep, ''))))
def update_markers(confile, fpath, bids_name): # TODO: shouldn't be needed once PR goes through on github """Update the markers provided and ensure that the BIDS output contains all the markers.""" bids_params = _get_bids_params(bids_name) folder = None for f in os.listdir(fpath): if op.isdir(op.join(fpath, f)): if _bids_params_are_subsets(_get_bids_params(f), bids_params): # this is the folder containing the BIDS data we want. folder = op.join(fpath, f) break if folder is None: # In this case it is broken. Do nothing I guess... return fnames = list(os.listdir(folder)) # cache for safety # do a check for any existing marker files with acq in their title for fname in fnames: params = _get_bids_params(fname) if params['file'] == 'markers': if params.get('acq', None) is not None: os.remove(op.join(folder, fname)) continue if len(confile.hpi) != 2: # If there is only one marker for the con file we don't need to do # anything. return # First entry in the list will always be the one that gets converted. converted = confile.hpi[0] not_converted = confile.hpi[1] # determine which marker is pre and which is post confile.hpi.sort(key=get_mrk_meas_date) order = ['pre', 'post'] if confile.hpi.index(converted) != 0: order = ['post', 'pre'] fnames = list(os.listdir(folder)) # recache for safety for fname in fnames: params = _get_bids_params(fname) if params['file'] == 'markers': params['suffix'] = params.pop('file') + params.pop('ext') bname = make_bids_basename(subject=params.get('sub', None), session=params.get('ses', None), run=params.get('run', None), task=params.get('task', None), suffix=params.get('suffix', None), acquisition=order[0]) os.rename(op.join(folder, fname), op.join(folder, bname)) bname = bname.replace('acq-{0}'.format(order[0]), 'acq-{0}'.format(order[1])) shutil.copy(not_converted.file, op.join(folder, op.basename(not_converted.file))) os.rename(op.join(folder, op.basename(not_converted.file)), op.join(folder, bname))
def run_time_decoding(subject, condition1, condition2, session=None): print("Processing subject: %s (%s vs %s)" % (subject, condition1, condition2)) # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space ) fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) fname_in = \ op.join(fpath_deriv, bids_basename + '-epo.fif') epochs = mne.read_epochs(fname_in) # We define the epochs and the labels epochs = mne.concatenate_epochs([epochs[condition1], epochs[condition2]]) epochs.apply_baseline() # Get the data and labels X = epochs.get_data() n_cond1 = len(epochs[condition1]) n_cond2 = len(epochs[condition2]) y = np.r_[np.ones(n_cond1), np.zeros(n_cond2)] # Use AUC because chance level is same regardless of the class balance se = SlidingEstimator( make_pipeline(StandardScaler(), LogisticRegression(solver='liblinear', random_state=config.random_state)), scoring=config.decoding_metric, n_jobs=config.N_JOBS) cv = StratifiedKFold(random_state=config.random_state, n_splits=config.decoding_n_splits) scores = cross_val_multiscore(se, X=X, y=y, cv=cv) # let's save the scores now a_vs_b = '%s_vs_%s' % (condition1, condition2) a_vs_b = a_vs_b.replace(op.sep, '') fname_td = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, '%s_%s_%s_%s.mat' % (subject, config.study_name, a_vs_b, config.decoding_metric)) savemat(fname_td, {'scores': scores, 'times': epochs.times})
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_filenames(): """Test that we create filenames according to the BIDS spec.""" # All keys work prefix_data = dict(subject='one', session='two', task='three', acquisition='four', run='five', processing='six', recording='seven', suffix='suffix.csv') assert make_bids_basename( **prefix_data ) == 'sub-one_ses-two_task-three_acq-four_run-five_proc-six_recording-seven_suffix.csv' # noqa # subsets of keys works assert make_bids_basename(subject='one', task='three', run=4) == 'sub-one_task-three_run-04' # noqa assert make_bids_basename( subject='one', task='three', suffix='hi.csv') == 'sub-one_task-three_hi.csv' # noqa with pytest.raises(ValueError): make_bids_basename(subject='one-two', suffix='there.csv') with pytest.raises(ValueError, match='At least one'): make_bids_basename()
def _make_bids_basename(self, suffix): return make_bids_basename( subject=self.subject_id, session=self.session_id, acquisition=self.acquisition, task=self.task, run=self.run, suffix=suffix, )
def run_evoked(subject, session=None): deriv_path = config.get_subject_deriv_path(subject=subject, session=session, kind=config.get_kind()) bids_basename = make_bids_basename(subject=subject, session=session, task=config.get_task(), acquisition=config.acq, run=None, processing=config.proc, recording=config.rec, space=config.space) if config.use_ica or config.use_ssp: extension = '_cleaned-epo' else: extension = '-epo' fname_in = op.join(deriv_path, bids_basename + '%s.fif' % extension) fname_out = op.join(deriv_path, bids_basename + '-ave.fif') msg = f'Input: {fname_in}, Output: {fname_out}' logger.info( gen_log_message(message=msg, step=6, subject=subject, session=session)) epochs = mne.read_epochs(fname_in, preload=True) msg = 'Creating evoked data based on experimental conditions …' logger.info( gen_log_message(message=msg, step=6, subject=subject, session=session)) evokeds = [] for condition in config.conditions: evoked = epochs[condition].average() evokeds.append(evoked) if config.contrasts: msg = 'Contrasting evoked responses …' logger.info( gen_log_message(message=msg, step=6, subject=subject, session=session)) for contrast in config.contrasts: cond_1, cond_2 = contrast evoked_1 = epochs[cond_1].average() evoked_2 = epochs[cond_2].average() evoked_diff = mne.combine_evoked([evoked_1, evoked_2], weights=[1, -1]) evokeds.append(evoked_diff) mne.evoked.write_evokeds(fname_out, evokeds) if config.interactive: for evoked in evokeds: evoked.plot()
def __init__( self, bids_root, bids_basename, kind=None, datatype="fif", verbose: bool = True ): self.bids_root = bids_root self.bids_basename = bids_basename # extract BIDS parameters from the bids filename to be loaded/modified # gets: subjectid, sessionid, acquisition type, task name, run, file extension params = _parse_bids_filename(self.bids_basename, verbose=verbose) self.subject_id, self.session_id = params["sub"], params["ses"] self.acquisition, self.task, self.run = ( params["acq"], params["task"], params["run"], ) self.ext = datatype.strip(".") if kind: self.kind = kind else: self.kind = self.acquisition if "meg" in self.kind: self.kind = "meg" elif "ieeg" in self.kind or "ecog" in self.kind or "seeg" in self.kind: self.kind = "ieeg" elif "eeg" in self.kind: self.kind = "eeg" self.subjdir = os.path.join( bids_root, make_bids_basename(subject=self.subject_id) ) self.sessiondir = os.path.join( self.subjdir, make_bids_basename(session=self.session_id) ) # 'ses-' + self.session_id) self.runs_datadir = os.path.join(self.sessiondir, self.kind) SUPPORTED_DATATYPES = ["edf", "fif", "nii", "nii.gz", "mgz"] if self.ext.strip(".") not in SUPPORTED_DATATYPES: raise ValueError( f"Supported data file types are: {SUPPORTED_DATATYPES}. " f"You passed {self.ext}" )
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 mne_write_bids(filename, subject, bids_folder='/bids', task='rest'): raw = mne.io.read_raw_brainvision(str(pathlib.Path(filename))) print(raw.annotations) raw.annotations.duration[raw.annotations.description == 'DC Correction/'] = 6 events, event_id = mne.events_from_annotations( raw) # this needs to be checked write_raw_bids(raw, make_bids_basename(subject=subject, task=task), bids_folder, overwrite=True)
def run_maxwell_filter(subject, session=None): print("Processing subject: %s" % subject) # Construct the search path for the data file. `sub` is mandatory subject_path = op.join('sub-{}'.format(subject)) # `session` is optional if session is not None: subject_path = op.join(subject_path, 'ses-{}'.format(session)) subject_path = op.join(subject_path, config.kind) for run_idx, run in enumerate(config.runs): bids_basename = make_bids_basename(subject=subject, session=session, task=config.task, acquisition=config.acq, run=run, processing=config.proc, recording=config.rec, space=config.space) # Prepare a name to save the data fpath_deriv = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME, subject_path) raw_fname_in = op.join(fpath_deriv, bids_basename + '_filt_raw.fif') raw_fname_out = op.join(fpath_deriv, bids_basename + '_sss_raw.fif') print("Input: ", raw_fname_in) print("Output: ", raw_fname_out) raw = mne.io.read_raw_fif(raw_fname_in, allow_maxshield=True) raw.fix_mag_coil_types() if run_idx == 0: destination = raw.info['dev_head_t'] if config.mf_st_duration: print(' st_duration=%d' % (config.mf_st_duration, )) raw_sss = mne.preprocessing.maxwell_filter( raw, calibration=config.mf_cal_fname, cross_talk=config.mf_ctc_fname, st_duration=config.mf_st_duration, origin=config.mf_head_origin, destination=destination) raw_sss.save(raw_fname_out, overwrite=True) if config.plot: # plot maxfiltered data raw_sss.plot(n_channels=50, butterfly=True)