diff --git a/config.py b/config.py index 212f0ec45..e5e39c43b 100644 --- a/config.py +++ b/config.py @@ -158,7 +158,7 @@ automatically. """ -ch_types: Iterable[Literal['meg', 'mag', 'grad', 'eeg']] = [] +ch_types: Iterable[Literal['meg', 'mag', 'grad', 'eeg', 'nirs']] = [] """ The channel types to consider. @@ -178,7 +178,7 @@ ``` """ -data_type: Optional[Literal['meg', 'eeg']] = None +data_type: Optional[Literal['meg', 'eeg', 'nirs']] = None """ The BIDS data type. @@ -362,6 +362,32 @@ ``` """ +############################################################################### +# NIRS PROCESSING +# --------------- + +nirs_only_long_channels: Optional[bool] = True +""" +Specifies if only long NIRS channels should be retained for processing. + +???+ example "Example" + ```python + nirs_only_long_channels = True # processes only long channels + nirs_only_long_channels = False # process both long and short channels + ``` +""" + +nirs_short_channel_correction: Optional[bool] = True +""" +Specifies if short channel correction should be applied to fNIRS data. + +???+ example "Example" + ```python + nirs_short_channel_correction = True # use short correction + nirs_short_channel_correction = False # do not use short correction + ``` +""" + ############################################################################### # MAXWELL FILTER PARAMETERS # ------------------------- @@ -1341,7 +1367,7 @@ def get_t1_from_meeg(bids_path): msg = ('EEG data can only be analyzed separately from other channel ' 'types. Please adjust `ch_types` in your configuration.') raise ValueError(msg) -elif any([ch_type not in ('meg', 'mag', 'grad') for ch_type in ch_types]): +elif any([ch_type not in ('meg', 'mag', 'grad', 'nirs') for ch_type in ch_types]): msg = ('Invalid channel type passed. Please adjust `ch_types` in your ' 'configuration.') raise ValueError(msg) @@ -1649,13 +1675,15 @@ def get_task() -> Optional[str]: return task -def get_datatype() -> Literal['meg', 'eeg']: +def get_datatype() -> Literal['meg', 'eeg', 'nirs']: # Content of ch_types should be sanitized already, so we don't need any # extra sanity checks here. if data_type is not None: return data_type elif data_type is None and ch_types == ['eeg']: return 'eeg' + elif data_type is None and ch_types == ['nirs']: + return 'nirs' elif data_type is None and any([t in ['meg', 'mag', 'grad'] for t in ch_types]): return 'meg' @@ -1824,6 +1852,9 @@ def get_channels_to_analyze(info) -> List[str]: elif ch_types == ['eeg']: pick_idx = mne.pick_types(info, meg=False, eeg=True, eog=True, ecg=True, exclude=[]) + elif ch_types == ['nirs']: + pick_idx = mne.pick_types(info, meg=False, eeg=False, eog=False, + ecg=False, fnirs=True, exclude=[]) else: raise RuntimeError('Something unexpected happened. Please contact ' 'the mne-bids-pipeline developers. Thank you.') diff --git a/scripts/preprocessing/01-import_and_maxfilter.py b/scripts/preprocessing/01-import_and_maxfilter.py index f4da2382b..dbb1a3e1c 100644 --- a/scripts/preprocessing/01-import_and_maxfilter.py +++ b/scripts/preprocessing/01-import_and_maxfilter.py @@ -39,9 +39,13 @@ import mne from mne.preprocessing import find_bad_channels_maxwell +from mne.preprocessing.nirs import optical_density, beer_lambert_law from mne.parallel import parallel_func from mne_bids import BIDSPath, read_raw_bids +from mne_nirs.signal_enhancement import short_channel_regression +from mne_nirs.channels import get_long_channels + import config from config import gen_log_message, on_error, failsafe_run @@ -238,6 +242,16 @@ def load_data(bids_path): if hasattr(raw, 'fix_mag_coil_types'): raw.fix_mag_coil_types() + if config.get_datatype() == 'nirs': + if 'fnirs_cw_amplitude' in raw: + raw = optical_density(raw) + if 'fnirs_od' in raw: + if config.nirs_short_channel_correction: + raw = short_channel_regression(raw) + raw = beer_lambert_law(raw) + if config.nirs_only_long_channels: + raw = get_long_channels(raw, min_dist=0.01) + montage_name = config.eeg_template_montage if config.get_datatype() == 'eeg' and montage_name: msg = (f'Setting EEG channel locations to template montage: ' diff --git a/tests/requirements.txt b/tests/requirements.txt index 942b13302..083c1ca92 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -24,3 +24,5 @@ coloredlogs openneuro-py https://api.github.com/repos/mne-tools/mne-python/zipball/main https://api.github.com/repos/mne-tools/mne-bids/zipball/main +mne-nirs +nilearn