Multi-Echo Denoising with tedana

Multi-Echo Denoising with tedana#

In this analysis tutorial, we will use tedana [DuPre et al., 2021] to perform multi-echo denoising.

Specifically, we will use tedana.workflows.tedana_workflow().

import json
import os
from glob import glob
from pprint import pprint

import nibabel as nb
import pandas as pd
from IPython.display import HTML, display
from tedana import workflows

data_path = os.path.abspath('../DATA')
/opt/hostedtoolcache/Python/3.12.11/x64/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
func_dir = os.path.join(data_path, "ds006185/sub-24053/ses-1/func/")
data_files = sorted(
    glob(
        os.path.join(
            func_dir,
            "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_echo-*_part-mag_desc-preproc_bold.nii.gz",
        ),
    ),
)
echo_times = []
for f in data_files:
    json_file = f.replace('.nii.gz', '.json')
    with open(json_file, 'r') as fo:
        metadata = json.load(fo)
    echo_times.append(metadata['EchoTime'] * 1000)
mask_file = os.path.join(
    func_dir,
    "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_part-mag_desc-brain_mask.nii.gz"
)
confounds_file = os.path.join(
    func_dir,
    "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_part-mag_desc-confounds_timeseries.tsv",
)

out_dir = os.path.join(data_path, "tedana")
workflows.tedana_workflow(
    data_files,
    echo_times,
    out_dir=out_dir,
    mask=mask_file,
    prefix="sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01",
    fittype="loglin",
    tedpca="mdl",
    verbose=True,
    gscontrol=["mir"],
)

Hide code cell output

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[3], line 1
----> 1 workflows.tedana_workflow(
      2     data_files,
      3     echo_times,
      4     out_dir=out_dir,
      5     mask=mask_file,
      6     prefix="sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01",
      7     fittype="loglin",
      8     tedpca="mdl",
      9     verbose=True,
     10     gscontrol=["mir"],
     11 )

File /opt/hostedtoolcache/Python/3.12.11/x64/lib/python3.12/site-packages/tedana/workflows/tedana.py:572, in tedana_workflow(data, tes, out_dir, mask, convention, prefix, dummy_scans, masktype, fittype, combmode, n_independent_echos, tree, external_regressors, ica_method, n_robust_runs, tedpca, fixed_seed, maxit, maxrestart, tedort, gscontrol, no_reports, png_cmap, verbose, low_mem, debug, quiet, overwrite, t2smap, mixing_file, tedana_command)
    570 out_dir = op.abspath(out_dir)
    571 if not op.isdir(out_dir):
--> 572     os.mkdir(out_dir)
    574 # boilerplate
    575 prefix = io._infer_prefix(prefix)

FileNotFoundError: [Errno 2] No such file or directory: '/home/runner/work/multi-echo-data-analysis/multi-echo-data-analysis/DATA/tedana'

The tedana workflow writes out a number of files.

out_files = sorted(glob(os.path.join(out_dir, "*")))
out_files = [os.path.basename(f) for f in out_files]
print("\n".join(out_files))
metrics = pd.read_table(
    os.path.join(out_dir, "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_desc-tedana_metrics.tsv")
)

Hide code cell source

def color_rejected_red(series):
    """Color rejected components red."""
    return [
        "color: red" if series["classification"] == "rejected" else "" for v in series
    ]


metrics.style.apply(color_rejected_red, axis=1)
with open(
    os.path.join(out_dir, "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_desc-tedana_metrics.json"),
    "r",
) as fo:
    data = json.load(fo)

first_five_keys = list(data.keys())[:5]
reduced_data = {k: data[k] for k in first_five_keys}
pprint(reduced_data)
df = pd.DataFrame.from_dict(data, orient="index")
df = df.fillna("n/a")
display(HTML(df.to_html()))
report = os.path.join(out_dir, "sub-24053_ses-1_task-rat_rec-nordic_dir-PA_run-01_tedana_report.html")
with open(report, "r") as fo:
    report_data = fo.read()

figures_dir = os.path.relpath(os.path.join(out_dir, "figures"), os.getcwd())
report_data = report_data.replace("./figures", figures_dir)

display(HTML(report_data))