# Reading and processing NIRS data with MNE-Python This tutorial demonstrates how to read and process NIRS data using MNE-Python and `almirah`. ## Setup First, we'll import the necessary libraries and set up the logging and warning configurations. ```python import mne import warnings import numpy as np import matplotlib.pyplot as plt from itertools import compress from almirah import Layout mne.set_log_level(False) warnings.filterwarnings('ignore') ``` ## Loading the Data Next, we'll set up the layout to access the NIRS data. ```python lay = Layout(root="/path/to/data", specification_name="bids") print(lay) ``` This should output: We can query the layout to find all NIRS files with the `.snirf` extension: ```python files = lay.query(datatype="nirs", extension=".snirf") len(files) ``` This gives the total number of NIRS files: 1315 ## Querying a Specific File To query a specific file, we can filter by subject, task, datatype, and extension: ```python file = lay.query(subject="D0019", task="rest", datatype="nirs", extension=".snirf")[0] print(file.rel_path) ``` This should output the relative path of the file: sub-D0019/ses-111/nirs/sub-D0019_ses-111_task-rest_run-01_nirs.snirf We can then download the NIRS file: ```python file.download() ``` ## Reading Raw Data Next, we read the raw NIRS data: ```python raw = mne.io.read_raw_snirf(file.path) raw.load_data() ```
General
Measurement date November 12, 1917 00:00:00 GMT
Experimenter Unknown
Participant mne_anonymize
Channels
Digitized points 21 points
Good channels 36 fNIRS (CW amplitude)
Bad channels None
EOG channels Not available
ECG channels Not available
Data
Sampling frequency 15.62 Hz
Highpass 0.00 Hz
Lowpass 7.81 Hz
Filenames sub-D0019_ses-111_task-rest_run-01_nirs.snirf
Duration 00:10:03 (HH:MM:SS)
```python print(raw.info) ``` ## Preprocessing We pick the NIRS channels, compute the source-detector distances, and filter out channels with a distance greater than 0.01: ```python picks = mne.pick_types(raw.info, meg=False, fnirs=True) dists = mne.preprocessing.nirs.source_detector_distances(raw.info, picks=picks) raw.pick(picks[dists > 0.01]) raw.plot(n_channels=len(raw.ch_names), duration=500, show_scrollbars=False) plt.show() ``` ![png](../images/nirs/raw-plot.png) We convert the raw data to optical density: ```python raw_od = mne.preprocessing.nirs.optical_density(raw) raw_od.plot(n_channels=len(raw_od.ch_names), duration=500, show_scrollbars=False) plt.show() ``` ![png](../images/nirs/optical-density-plot.png) Next, we compute the Scalp Coupling Index (SCI) and plot the distribution: ```python sci = mne.preprocessing.nirs.scalp_coupling_index(raw_od) fig, ax = plt.subplots() ax.hist(sci) ax.set(xlabel="Scalp Coupling Index", ylabel="Count", xlim=[0, 1]) plt.show() ``` ![png](../images/nirs/scalp-coupling-index-plot.png) We mark channels with a low SCI as bad: ```python raw_od.info["bads"] = list(compress(raw_od.ch_names, sci < 0.5)) ``` We convert the optical density data to hemoglobin concentration: ```python raw_haemo = mne.preprocessing.nirs.beer_lambert_law(raw_od, ppf=0.1) raw_haemo.plot(n_channels=len(raw_haemo.ch_names), duration=500, show_scrollbars=False) plt.show() ``` ![png](../images/nirs/raw-haemo-plot.png) ## Power Spectral Analysis We compute and plot the Power Spectral Density (PSD) before and after filtering: ```python fig = raw_haemo.compute_psd().plot(average=True, amplitude=False) fig.suptitle("Before filtering", weight="bold", size="x-large") raw_haemo = raw_haemo.filter(0.05, 0.7, h_trans_bandwidth=0.2, l_trans_bandwidth=0.02) fig = raw_haemo.compute_psd().plot(average=True) fig.suptitle("After filtering", weight="bold", size="x-large") plt.show() ``` ![png](../images/nirs/raw-haemo-psd-before-filtering.png) ![png](../images/nirs/raw-haemo-psd-after-filtering.png) ## Epoching We create epochs from the continuous data: ```python epochs = mne.make_fixed_length_epochs(raw_haemo, duration=30, preload=False) ``` Finally, we plot the epochs: ```python epochs.plot_image(combine="mean", vmin=-30, vmax=30, ts_args=dict(ylim=dict(hbo=[-15, 15], hbr=[-15, 15]))) plt.show() ``` ![png](../images/nirs/deoxyhemoglobin-plot.png) ![png](../images/nirs/oxyhemoglobin-plot.png) This concludes the tutorial. You've learned how to read, and process near-infrared spectroscopy data using MNE-Python and `almirah`.