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 book_utils import load_pafin
from tedana import workflows

data_path = os.path.abspath('../data')
/Users/eurunuela/GitHub/multi-echo-data-analysis/.venv/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
data = load_pafin(data_path)
out_dir = os.path.join(data_path, "tedana")
workflows.tedana_workflow(
    data['echo_files'],
    data['echo_times'],
    out_dir=out_dir,
    mask=data['mask'],
    prefix="sub-24053_ses-1_task-rat_dir-PA_run-01",
    fittype="loglin",
    tedpca="mdl",
    verbose=True,
    gscontrol=["mir"],
    overwrite=True,
)

Hide code cell output

INFO     tedana:tedana_workflow:636 Using output directory: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana
INFO     utils:check_te_values:792 TE values appear to be in seconds. Converting to milliseconds for internal use.
INFO     tedana:tedana_workflow:655 Initializing and validating component selection tree
WARNING  component_selector:validate_tree:146 Decision tree includes fields that are not used or logged ['_comment']
INFO     component_selector:__init__:345 Performing component selection with tedana_orig_decision_tree
INFO     component_selector:__init__:346 Very similar to the decision tree designed by Prantik Kundu
INFO     utils:load_mask:916 Using user-defined mask
INFO     tedana:tedana_workflow:690 Loading input data: ['/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_part-mag_desc-preproc_bold.nii.gz']
INFO     utils:make_adaptive_mask:167 Echo-wise intensity thresholds for adaptive mask: [5427.905   3060.0125  1939.6979   923.65643  479.0348 ]
WARNING  utils:make_adaptive_mask:195 11350 voxels in user-defined mask do not have good signal. Removing voxels from mask.
INFO     tedana:tedana_workflow:780 Computing T2* map
INFO     combine:make_optcom:202 Optimally combining data with voxel-wise T2* estimates
INFO     tedana:tedana_workflow:859 Writing optimally combined data set: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcom_bold.nii.gz
INFO     pca:tedpca:212 Computing PCA of optimally combined multi-echo data with selection criteria: mdl
INFO     pca:tedpca:254 Optimal number of components based on different criteria:
INFO     pca:tedpca:255 AIC: 46 | KIC: 41 | MDL: 27 | 90% varexp: 293 | 95% varexp: 327
INFO     pca:tedpca:260 Explained variance based on different criteria:
INFO     pca:tedpca:261 AIC: 48.4% | KIC: 47.2% | MDL: 43.4% | 90% varexp: 90.1% | 95% varexp: 95.1%
INFO     pca:tedpca:281 Plotting maPCA optimization curves
INFO     collect:generate_metrics:153 Calculating standardized parameter estimate maps for optimally combined data
INFO     collect:generate_metrics:171 Calculating unstandardized parameter estimate maps for optimally combined data
INFO     collect:generate_metrics:203 Calculating F-statistic maps
INFO     collect:generate_metrics:229 Thresholding standardized parameter estimate maps
INFO     collect:generate_metrics:237 Thresholding T2* F-statistic maps
INFO     collect:generate_metrics:245 Thresholding S0 F-statistic maps
INFO     collect:generate_metrics:254 Counting significant voxels in T2* F-statistic maps
INFO     collect:generate_metrics:260 Counting significant voxels in S0 F-statistic maps
INFO     collect:generate_metrics:267 Thresholding optimal combination beta maps to match T2* F-statistic maps
INFO     collect:generate_metrics:275 Thresholding optimal combination beta maps to match S0 F-statistic maps
INFO     collect:generate_metrics:284 Calculating kappa and rho
INFO     collect:generate_metrics:293 Calculating variance explained
INFO     collect:generate_metrics:299 Calculating normalized variance explained
INFO     collect:generate_metrics:328 Calculating DSI between thresholded T2* F-statistic and optimal combination beta maps
INFO     collect:generate_metrics:338 Calculating DSI between thresholded S0 F-statistic and optimal combination beta maps
INFO     collect:generate_metrics:349 Calculating signal-noise t-statistics
/Users/eurunuela/GitHub/multi-echo-data-analysis/.venv/lib/python3.12/site-packages/tedana/metrics/dependence.py:779: SmallSampleWarning: One or more sample arguments is too small; all returned values will be NaN. See documentation for sample size requirements.
  signal_minus_noise_t[i_comp], signal_minus_noise_p[i_comp] = stats.ttest_ind(
INFO     collect:generate_metrics:385 Counting significant noise voxels from z-statistic maps
INFO     collect:generate_metrics:398 Calculating decision table score
INFO     pca:tedpca:425 Selected 27 components with 43.39% normalized variance explained using mdl dimensionality estimate
INFO     ica:f_ica:360 ICA with random seed 42 converged in 43 iterations
INFO     collect:generate_metrics:153 Calculating standardized parameter estimate maps for optimally combined data
INFO     collect:generate_metrics:171 Calculating unstandardized parameter estimate maps for optimally combined data
INFO     collect:generate_metrics:203 Calculating F-statistic maps
INFO     collect:generate_metrics:229 Thresholding standardized parameter estimate maps
INFO     collect:generate_metrics:237 Thresholding T2* F-statistic maps
INFO     collect:generate_metrics:245 Thresholding S0 F-statistic maps
INFO     collect:generate_metrics:254 Counting significant voxels in T2* F-statistic maps
INFO     collect:generate_metrics:260 Counting significant voxels in S0 F-statistic maps
INFO     collect:generate_metrics:267 Thresholding optimal combination beta maps to match T2* F-statistic maps
INFO     collect:generate_metrics:275 Thresholding optimal combination beta maps to match S0 F-statistic maps
INFO     collect:generate_metrics:284 Calculating kappa and rho
INFO     collect:generate_metrics:293 Calculating variance explained
INFO     collect:generate_metrics:299 Calculating normalized variance explained
INFO     collect:generate_metrics:328 Calculating DSI between thresholded T2* F-statistic and optimal combination beta maps
INFO     collect:generate_metrics:338 Calculating DSI between thresholded S0 F-statistic and optimal combination beta maps
INFO     collect:generate_metrics:349 Calculating signal-noise t-statistics
/Users/eurunuela/GitHub/multi-echo-data-analysis/.venv/lib/python3.12/site-packages/tedana/metrics/dependence.py:779: SmallSampleWarning: One or more sample arguments is too small; all returned values will be NaN. See documentation for sample size requirements.
  signal_minus_noise_t[i_comp], signal_minus_noise_p[i_comp] = stats.ttest_ind(
INFO     collect:generate_metrics:385 Counting significant noise voxels from z-statistic maps
INFO     collect:generate_metrics:398 Calculating decision table score
INFO     tedana:tedana_workflow:933 Selecting components from ICA results
INFO     tedica:automatic_selection:54 Performing ICA component selection with tree: tedana_orig
INFO     selection_nodes:manual_classify:104 Step 0: manual_classify: Set all to unclassified 
INFO     selection_utils:comptable_classification_changer:293 Step 0: No components fit criterion False to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 0: manual_classify applied to 27 components. 27 True -> unclassified. 0 False -> nochange.
INFO     selection_nodes:manual_classify:136 Step 0: manual_classify component classification tags are cleared
INFO     selection_utils:log_classification_counts:492 Step 0: Total component classifications: 27 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 1: left_op_right: rejected if rho>kappa, else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 1: left_op_right applied to 27 components. 7 True -> rejected. 20 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 1: Total component classifications: 7 rejected, 20 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 2: left_op_right: rejected if ['countsigFS0>countsigFT2 & countsigFT2>0'], else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 2: left_op_right applied to 27 components. 2 True -> rejected. 25 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 2: Total component classifications: 7 rejected, 20 unclassified
INFO     selection_nodes:calc_median:653 Step 3: calc_median: Median(median_varex)
INFO     selection_utils:log_decision_tree_step:459 Step 3: calc_median calculated: median_varex=1.3544642655629533
INFO     selection_utils:log_classification_counts:492 Step 3: Total component classifications: 7 rejected, 20 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 4: left_op_right: rejected if ['dice_FS0>dice_FT2 & variance explained>1.35'], else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 4: left_op_right applied to 27 components. 3 True -> rejected. 24 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 4: Total component classifications: 7 rejected, 20 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 5: left_op_right: rejected if ['0>signal-noise_t & variance explained>1.35'], else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 5: left_op_right applied to 27 components. 1 True -> rejected. 26 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 5: Total component classifications: 8 rejected, 19 unclassified
INFO     selection_nodes:calc_kappa_elbow:767 Step 6: calc_kappa_elbow: Calc Kappa Elbow
INFO     selection_utils:kappa_elbow_kundu:664 Calculating kappa elbow based on min of all and nonsig components.
INFO     selection_utils:log_decision_tree_step:459 Step 6: calc_kappa_elbow calculated: kappa_elbow_kundu=16.897483347993777, kappa_allcomps_elbow=37.532572252736514, kappa_nonsig_elbow=16.897483347993777, varex_upper_p=1.2879407613250256
INFO     selection_utils:log_classification_counts:492 Step 6: Total component classifications: 8 rejected, 19 unclassified
INFO     selection_nodes:dec_reclassify_high_var_comps:1140 Step 7: reclassify_high_var_comps: Change unclassified to unclass_highvar for the top couple of components with the highest jumps in variance
INFO     selection_utils:log_decision_tree_step:447 Step 7: reclassify_high_var_comps applied to 19 components. 3 True -> unclass_highvar. 16 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 7: Total component classifications: 8 rejected, 3 unclass_highvar, 16 unclassified
INFO     selection_nodes:calc_rho_elbow:902 Step 8: calc_rho_elbow: Calc Rho Elbow
INFO     selection_utils:log_decision_tree_step:459 Step 8: calc_rho_elbow calculated: rho_elbow_kundu=10.93046089207899, rho_allcomps_elbow=13.236574169202648, rho_unclassified_elbow=11.846161084857535, elbow_f05=7.708647422176786
INFO     selection_utils:log_classification_counts:492 Step 8: Total component classifications: 8 rejected, 3 unclass_highvar, 16 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 9: left_op_right: provisionalaccept if kappa>=16.9, else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 9: left_op_right applied to 16 components. 15 True -> provisionalaccept. 1 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 9: Total component classifications: 15 provisionalaccept, 8 rejected, 3 unclass_highvar, 1 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 10: left_op_right: unclassified if rho>10.93, else nochange
INFO     selection_utils:log_decision_tree_step:447 Step 10: left_op_right applied to 15 components. 6 True -> unclassified. 9 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 10: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_nodes:dec_classification_doesnt_exist:1029 Step 11: classification_doesnt_exist: Change ['provisionalaccept', 'unclassified', 'unclass_highvar'] to accepted if less than 2 components with provisionalaccept exist
INFO     selection_nodes:dec_classification_doesnt_exist:1031 Step 11: classification_doesnt_exist If nothing is provisionally accepted by this point, then rerun ICA & selection. If max iterations of rerunning done, then accept everything not already rejected
INFO     selection_utils:log_decision_tree_step:447 Step 11: classification_doesnt_exist applied to 19 components. None True -> 0. None False -> 19.
INFO     selection_utils:log_classification_counts:492 Step 11: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_nodes:calc_varex_thresh:1328 Step 12: calc_varex_thresh: Calc varex_upper_thresh, 90th percentile threshold
INFO     selection_utils:log_decision_tree_step:459 Step 12: calc_varex_thresh calculated: varex_upper_thresh=1.4986459297236918, upper_perc=90
INFO     selection_utils:log_classification_counts:492 Step 12: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_nodes:calc_varex_thresh:1328 Step 13: calc_varex_thresh: Calc varex_lower_thresh, 25th percentile threshold
INFO     selection_utils:log_decision_tree_step:459 Step 13: calc_varex_thresh calculated: varex_lower_thresh=0.933376555850726, lower_perc=25
INFO     selection_utils:log_classification_counts:492 Step 13: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_utils:get_extend_factor:846 extend_factor=2.0, based on number of fMRI volumes
INFO     selection_utils:log_decision_tree_step:459 Step 14: calc_extend_factor calculated: extend_factor=2.0
INFO     selection_utils:log_classification_counts:492 Step 14: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_utils:log_decision_tree_step:459 Step 15: calc_max_good_meanmetricrank calculated: max_good_meanmetricrank=18.0
INFO     selection_utils:log_classification_counts:492 Step 15: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_utils:log_decision_tree_step:459 Step 16: calc_varex_kappa_ratio calculated: kappa_rate=30.94839546895041
INFO     selection_utils:log_classification_counts:492 Step 16: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 17: left_op_right: rejected if ['d_table_score>18.0 & variance explained>2.0*1.5'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 17: left_op_right If variance and d_table_scores are high, then reject
INFO     selection_utils:comptable_classification_changer:293 Step 17: No components fit criterion True to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 17: left_op_right applied to 19 components. 0 True -> rejected. 19 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 17: Total component classifications: 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 7 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 18: left_op_right: accepted if ['d_table_score>18.0 & variance explained<=0.93 & kappa<=16.9'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 18: left_op_right If low variance, accept even if bad kappa & d_table_scores
INFO     selection_utils:log_decision_tree_step:447 Step 18: left_op_right applied to 19 components. 1 True -> accepted. 18 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 18: Total component classifications: 1 accepted, 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 6 unclassified
INFO     selection_nodes:dec_classification_doesnt_exist:1029 Step 19: classification_doesnt_exist: Change ['provisionalaccept', 'unclassified', 'unclass_highvar'] to accepted if ['unclassified', 'unclass_highvar'] doesn't exist
INFO     selection_nodes:dec_classification_doesnt_exist:1031 Step 19: classification_doesnt_exist If nothing left is unclassified, then accept all
INFO     selection_utils:log_decision_tree_step:447 Step 19: classification_doesnt_exist applied to 18 components. None True -> 0. None False -> 18.
INFO     selection_utils:log_classification_counts:492 Step 19: Total component classifications: 1 accepted, 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 6 unclassified
INFO     selection_nodes:calc_revised_meanmetricrank_guesses:1788 Step 20: calc_revised_meanmetricrank_guesses: Calc revised d_table_score & num accepted component guesses
INFO     selection_utils:log_decision_tree_step:459 Step 20: calc_revised_meanmetricrank_guesses calculated: num_acc_guess=13, conservative_guess=6.5, restrict_factor=2
INFO     selection_utils:log_classification_counts:492 Step 20: Total component classifications: 1 accepted, 9 provisionalaccept, 8 rejected, 3 unclass_highvar, 6 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 21: left_op_right: rejected if ['d_table_score_node20>6.5 & varex kappa ratio>2*2.0 & variance explained>2.0*1.5'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 21: left_op_right Reject if a combination of kappa, variance, and other factors are ranked worse than others
INFO     selection_utils:log_decision_tree_step:447 Step 21: left_op_right applied to 18 components. 3 True -> rejected. 15 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 21: Total component classifications: 1 accepted, 9 provisionalaccept, 11 rejected, 6 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 22: left_op_right: rejected if ['d_table_score_node20>0.9*13 & variance explained>2.0*0.93'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 22: left_op_right Reject if a combination of variance and ranks of other metrics are worse than others
INFO     selection_utils:comptable_classification_changer:293 Step 22: No components fit criterion True to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 22: left_op_right applied to 15 components. 0 True -> rejected. 15 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 22: Total component classifications: 1 accepted, 9 provisionalaccept, 11 rejected, 6 unclassified
INFO     selection_nodes:calc_varex_thresh:1328 Step 23: calc_varex_thresh: Calc varex_new_lower_thresh, 25th percentile threshold
INFO     selection_utils:log_decision_tree_step:459 Step 23: calc_varex_thresh calculated: varex_new_lower_thresh=1.0166694833002672, new_lower_perc=25
INFO     selection_utils:log_classification_counts:492 Step 23: Total component classifications: 1 accepted, 9 provisionalaccept, 11 rejected, 6 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 24: left_op_right: accepted if ['d_table_score_node20>13 & variance explained>1.02'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 24: left_op_right Accept components with a bad d_table_score, but are at the higher end of the remaining variance so more cautious to not remove
INFO     selection_utils:comptable_classification_changer:293 Step 24: No components fit criterion True to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 24: left_op_right applied to 15 components. 0 True -> accepted. 15 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 24: Total component classifications: 1 accepted, 9 provisionalaccept, 11 rejected, 6 unclassified
INFO     selection_nodes:dec_left_op_right:389 Step 25: left_op_right: accepted if ['kappa<=16.9 & variance explained>1.02'], else nochange
INFO     selection_nodes:dec_left_op_right:391 Step 25: left_op_right For not already rejected components, accept ones below the kappa elbow, but at the higher end of the remaining variance so more cautious to not remove
INFO     selection_utils:comptable_classification_changer:293 Step 25: No components fit criterion True to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 25: left_op_right applied to 15 components. 0 True -> accepted. 15 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 25: Total component classifications: 1 accepted, 9 provisionalaccept, 11 rejected, 6 unclassified
INFO     selection_nodes:manual_classify:104 Step 26: manual_classify: Set ['provisionalaccept', 'unclassified', 'unclass_highvar'] to accepted 
INFO     selection_nodes:manual_classify:106 Step 26: manual_classify Anything still provisional (accepted or rejected) or unclassified should be accepted
INFO     selection_utils:comptable_classification_changer:293 Step 26: No components fit criterion False to change classification
INFO     selection_utils:log_decision_tree_step:447 Step 26: manual_classify applied to 15 components. 15 True -> accepted. 0 False -> nochange.
INFO     selection_utils:log_classification_counts:492 Step 26: Total component classifications: 16 accepted, 11 rejected
INFO     io:denoise_ts:682 Variance explained by decomposition: 55.99%
INFO     io:write_split_ts:754 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomAccepted_bold.nii.gz
INFO     io:write_split_ts:762 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomRejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-denoised_bold.nii.gz
INFO     io:writeresults:817 Writing full ICA coefficient feature set: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_components.nii.gz
INFO     io:writeresults:824 Writing Z-normalized spatial component maps: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_stat-z_components.nii.gz
INFO     io:writeresults:828 Writing denoised ICA coefficient feature set: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAccepted_components.nii.gz
INFO     io:writeresults:835 Writing Z-normalized spatial component maps: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAccepted_stat-z_components.nii.gz
INFO     gscontrol:minimum_image_regression:214 Performing minimum image regression to remove spatially-diffuse noise
INFO     gscontrol:minimum_image_regression:274 Variance in optimally combined data explained by T1-like global signal: 2.32%
INFO     io:writeresults_echoes:875 Writing Kappa-filtered echo #1 timeseries
INFO     io:denoise_ts:682 Variance explained by decomposition: 35.68%
INFO     io:write_split_ts:751 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Accepted_bold.nii.gz
INFO     io:write_split_ts:759 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Rejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Denoised_bold.nii.gz
INFO     io:writeresults_echoes:875 Writing Kappa-filtered echo #2 timeseries
INFO     io:denoise_ts:682 Variance explained by decomposition: 39.92%
INFO     io:write_split_ts:751 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Accepted_bold.nii.gz
INFO     io:write_split_ts:759 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Rejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Denoised_bold.nii.gz
INFO     io:writeresults_echoes:875 Writing Kappa-filtered echo #3 timeseries
INFO     io:denoise_ts:682 Variance explained by decomposition: 41.84%
INFO     io:write_split_ts:751 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Accepted_bold.nii.gz
INFO     io:write_split_ts:759 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Rejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Denoised_bold.nii.gz
INFO     io:writeresults_echoes:875 Writing Kappa-filtered echo #4 timeseries
INFO     io:denoise_ts:682 Variance explained by decomposition: 42.80%
INFO     io:write_split_ts:751 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Accepted_bold.nii.gz
INFO     io:write_split_ts:759 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Rejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Denoised_bold.nii.gz
INFO     io:writeresults_echoes:875 Writing Kappa-filtered echo #5 timeseries
INFO     io:denoise_ts:682 Variance explained by decomposition: 42.76%
INFO     io:write_split_ts:751 Writing high-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Accepted_bold.nii.gz
INFO     io:write_split_ts:759 Writing low-Kappa time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Rejected_bold.nii.gz
INFO     io:write_split_ts:769 Writing denoised time series: /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Denoised_bold.nii.gz
INFO     tedana:tedana_workflow:1153 Making figures folder with static component maps and timecourse plots.
INFO     io:denoise_ts:682 Variance explained by decomposition: 55.99%
/Users/eurunuela/GitHub/multi-echo-data-analysis/.venv/lib/python3.12/site-packages/tedana/reporting/static_figures.py:734: UserWarning: Non-finite values detected. These values will be replaced with zeros.
  plotting.plot_stat_map(
INFO     tedana:tedana_workflow:1236 Generating dynamic report
INFO     html_report:_update_template_bokeh:164 Checking for adaptive mask: sub-24053_ses-1_task-rat_dir-PA_run-01_adaptive_mask.svg, exists: True
INFO     html_report:_update_template_bokeh:208 T2* files exist: True
INFO     html_report:_update_template_bokeh:209 S0 files exist: True
INFO     html_report:_update_template_bokeh:210 RMSE files exist: True
INFO     html_report:_update_template_bokeh:217 Variance files exist: False
INFO     html_report:_update_template_bokeh:223 External regressors exist: False
INFO     rica:setup_rica_report:787 Rica launcher created. Run 'python /Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana/open_rica_report.py' to visualize results.
INFO     tedana:tedana_workflow:1242 Workflow completed
INFO     utils:log_newsletter_info:812 Don't forget to subscribe to the tedana newsletter for updates! This is a very low volume email list.
INFO     utils:log_newsletter_info:816 https://groups.google.com/g/tedana-newsletter

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))
figures
open_rica_report.py
sub-24053_ses-1_task-rat_dir-PA_run-01_S0map.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_T2starmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_dataset_description.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAcceptedMIRDenoised_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAccepted_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAccepted_stat-z_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAAveragingWeights_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICACrossComponent_metrics.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAMIRDenoised_mixing.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAS0_stat-F_statmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICAT2_stat-F_statmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_decision_tree.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_decomposition.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_mixing.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_stat-z_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-ICA_status_table.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCAAveragingWeights_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCACrossComponent_metrics.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCAS0_stat-F_statmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCAT2_stat-F_statmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCA_decomposition.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCA_metrics.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCA_metrics.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCA_mixing.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-PCA_stat-z_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-T1likeEffect_min.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-adaptiveGoodSignal_mask.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-confounds_timeseries.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-limited_S0map.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-limited_T2starmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomAcceptedMIRDenoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomAccepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomMIRDenoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcomRejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcom_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-optcom_whitened_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-rmse_statmap.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-tedana_metrics.json
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-tedana_metrics.tsv
sub-24053_ses-1_task-rat_dir-PA_run-01_desc-tedana_registry.json
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Accepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-ICAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-ICAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-PCAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-PCAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-PCA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_desc-Rejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Accepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-ICAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-ICAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-PCAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-PCAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-PCA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_desc-Rejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Accepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-ICAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-ICAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-PCAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-PCAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-PCA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_desc-Rejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Accepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-ICAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-ICAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-PCAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-PCAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-PCA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_desc-Rejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Accepted_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Denoised_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-ICAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-ICAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-ICA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-PCAS0ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-PCAT2ModelPredictions_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-PCA_components.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_desc-Rejected_bold.nii.gz
sub-24053_ses-1_task-rat_dir-PA_run-01_references.bib
sub-24053_ses-1_task-rat_dir-PA_run-01_report.txt
sub-24053_ses-1_task-rat_dir-PA_run-01_report_old.txt
sub-24053_ses-1_task-rat_dir-PA_run-01_report_old_old.txt
sub-24053_ses-1_task-rat_dir-PA_run-01_tedana_report.html
tedana_2026-06-09T100122.tsv
tedana_2026-06-09T112355.tsv
tedana_2026-06-14T094100.tsv
metrics = pd.read_table(
    os.path.join(out_dir, "sub-24053_ses-1_task-rat_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)
  Component kappa rho variance explained normalized variance explained countsigFT2 countsigFS0 dice_FT2 dice_FS0 countnoise signal-noise_t signal-noise_p d_table_score optimal sign varex kappa ratio d_table_score_node20 Var Exp of rejected to accepted classification classification_tags
0 ICA_00 35.897960 24.369720 3.116226 3.414322 14318 6516 0.327031 0.255773 9695 0.000000 0.000000 15.200000 1 2.686565 10.600000 9.007952 accepted Likely BOLD
1 ICA_01 50.519734 9.190112 1.221417 1.916619 15554 1657 0.514943 0.085532 3377 9.253946 0.000000 5.000000 -1 0.748240 3.800000 2.737397 accepted Likely BOLD
2 ICA_02 10.215109 14.267127 0.977362 0.844075 1306 1858 0.438356 0.283060 9695 0.000000 0.000000 20.800000 -1 2.961082 nan nan rejected Unlikely BOLD
3 ICA_03 15.197244 11.833206 0.529667 1.017728 3749 1483 0.077435 0.207296 9695 0.000000 0.000000 22.400000 -1 1.078639 nan 2.285886 accepted Low variance
4 ICA_04 11.026574 13.236574 0.928514 1.729676 2102 1036 0.159515 0.000000 8892 2.765219 0.005800 19.000000 1 2.606070 nan nan rejected Unlikely BOLD
5 ICA_05 32.387547 16.585226 3.354734 4.342934 16485 4247 0.375685 0.207155 9695 0.000000 0.000000 15.200000 1 3.205665 10.600000 9.477309 accepted Likely BOLD
6 ICA_06 19.044382 24.212826 1.040440 1.244479 10270 11086 0.349373 0.338378 8219 7.423686 0.000000 13.400000 -1 1.690784 nan nan rejected Unlikely BOLD
7 ICA_07 23.441985 12.159223 12.591377 17.403808 19015 1876 0.302657 0.000000 9695 0.000000 0.000000 16.000000 -1 16.623290 11.400000 nan rejected Less likely BOLD
8 ICA_08 17.369177 23.078242 9.626538 2.754779 2909 2164 0.448067 0.577694 8960 9.398605 0.000000 14.200000 1 17.152564 nan nan rejected Unlikely BOLD
9 ICA_09 25.693861 9.887890 0.577836 1.042674 9986 1082 0.301456 0.000000 7930 16.783757 0.000000 11.200000 1 0.696007 9.200000 4.812046 accepted Likely BOLD
10 ICA_10 35.372025 28.980431 3.194135 3.421235 16674 7398 0.359196 0.267412 9695 0.000000 0.000000 14.400000 -1 2.794677 10.000000 4.628745 accepted Likely BOLD
11 ICA_11 16.897483 11.846161 0.902715 1.240939 6162 1470 0.218074 0.318677 9161 8.172738 0.000000 16.600000 -1 1.653357 12.200000 4.730222 accepted Likely BOLD
12 ICA_12 26.979825 8.603518 1.971129 3.451624 10171 668 0.423559 0.000000 9695 0.000000 0.000000 15.800000 -1 2.261070 11.200000 25.568251 accepted Likely BOLD
13 ICA_13 35.692289 9.455334 0.707355 1.224384 11858 1039 0.419808 0.000000 6228 18.629724 0.000000 7.200000 -1 0.613340 6.000000 5.687572 accepted Likely BOLD
14 ICA_14 34.224276 12.655300 9.143560 15.730556 29863 3328 0.456240 0.000000 9695 0.000000 0.000000 11.600000 -1 8.268356 7.800000 nan rejected Less likely BOLD
15 ICA_15 51.110821 9.545650 1.380525 2.414741 20436 1945 0.511941 0.210992 4076 11.485841 0.000000 2.600000 -1 0.835929 2.200000 9.523861 accepted Likely BOLD
16 ICA_16 24.851919 21.402390 1.016669 1.640386 7042 3750 0.189515 0.126102 9590 -1.607447 0.110933 18.800000 1 1.266071 13.800000 9.556839 accepted Likely BOLD
17 ICA_17 19.341875 20.602514 10.130169 2.800861 3473 2112 0.508682 0.477256 9357 11.086674 0.000000 12.600000 1 16.209001 nan nan rejected Unlikely BOLD
18 ICA_18 18.890735 23.545769 10.472541 2.711862 2902 2633 0.532468 0.541172 8921 10.998363 0.000000 11.800000 1 17.157000 nan nan rejected Unlikely BOLD
19 ICA_19 60.807142 8.626295 1.354464 2.534241 19343 1337 0.581412 0.157915 2734 11.306640 0.000000 1.600000 -1 0.689368 1.600000 6.058723 accepted Likely BOLD
20 ICA_20 18.867494 21.103902 10.056883 2.679880 2345 2118 0.521163 0.525106 9339 7.000427 0.000000 14.400000 1 16.496328 nan nan rejected Unlikely BOLD
21 ICA_21 27.944134 10.782014 10.459819 14.514896 22480 1786 0.400965 0.000000 9695 0.000000 0.000000 13.400000 -1 11.584350 9.200000 nan rejected Less likely BOLD
22 ICA_22 34.880040 17.732879 1.528777 3.581298 18103 4629 0.389720 0.000000 9236 -3.280487 0.001109 13.400000 -1 1.356455 nan nan rejected Unlikely BOLD
23 ICA_23 20.419441 16.820935 0.667994 1.149756 5523 2770 0.110410 0.151093 9562 2.028319 0.044526 17.600000 -1 1.012434 12.800000 9.438866 accepted Likely BOLD
24 ICA_24 37.532572 9.555547 1.072563 1.790168 16535 648 0.478983 0.000000 5765 13.506946 0.000000 5.000000 1 0.884408 4.200000 12.357488 accepted Likely BOLD
25 ICA_25 39.669322 9.283617 1.043214 1.692097 18786 776 0.453157 0.360698 4936 8.597489 0.000000 5.800000 1 0.813874 4.600000 4.828391 accepted Likely BOLD
26 ICA_26 17.686976 9.832943 0.933377 1.709982 4185 402 0.081677 0.000000 9695 0.000000 0.000000 21.400000 -1 1.633208 15.400000 4.625396 accepted Likely BOLD
with open(
    os.path.join(out_dir, "sub-24053_ses-1_task-rat_dir-PA_run-01_desc-tedana_metrics.json"),
    "r",
) as fo:
    metrics = json.load(fo)

first_five_keys = list(metrics.keys())[:5]
reduced_metrics = {k: metrics[k] for k in first_five_keys}
pprint(reduced_metrics)
{'Component': {'Description': 'The unique identifier of each component. This '
                              'identifier matches column names in the mixing '
                              'matrix TSV file.',
               'LongName': 'Component identifier'},
 'classification_tags': {'Description': 'A single tag or a comma separated '
                                        'list of tags to describe why a '
                                        'component received its classification',
                         'LongName': 'Component classification tags'},
 'countnoise': {'Description': "Number of 'noise' voxels (voxels highly "
                               'weighted for component, but not from clusters) '
                               'from each component.',
                'LongName': 'Noise voxel count',
                'Units': 'voxel'},
 'countsigFS0': {'Description': 'Number of significant voxels from the '
                                'cluster-extent thresholded S0 model '
                                'F-statistic map for each component.',
                 'LongName': 'S0 model F-statistic map significant voxel count',
                 'Units': 'voxel'},
 'countsigFT2': {'Description': 'Number of significant voxels from the '
                                'cluster-extent thresholded T2 model '
                                'F-statistic map for each component.',
                 'LongName': 'T2 model F-statistic map significant voxel count',
                 'Units': 'voxel'}}
df = pd.DataFrame.from_dict(metrics, orient="index")
df = df.fillna("n/a")
display(HTML(df.to_html()))
Description LongName Units Levels
Component The unique identifier of each component. This identifier matches column names in the mixing matrix TSV file. Component identifier n/a n/a
classification_tags A single tag or a comma separated list of tags to describe why a component received its classification Component classification tags n/a n/a
countnoise Number of 'noise' voxels (voxels highly weighted for component, but not from clusters) from each component. Noise voxel count voxel n/a
countsigFS0 Number of significant voxels from the cluster-extent thresholded S0 model F-statistic map for each component. S0 model F-statistic map significant voxel count voxel n/a
countsigFT2 Number of significant voxels from the cluster-extent thresholded T2 model F-statistic map for each component. T2 model F-statistic map significant voxel count voxel n/a
d_table_score Summary score compiled from five metrics, with smaller values (i.e., higher ranks) indicating more BOLD dependence and less noise. Decision table score arbitrary n/a
dice_FS0 Dice value of cluster-extent thresholded maps of S0-model betas and F-statistics. S0 model beta map-F-statistic map Dice similarity index arbitrary n/a
dice_FT2 Dice value of cluster-extent thresholded maps of T2-model betas and F-statistics. T2 model beta map-F-statistic map Dice similarity index arbitrary n/a
kappa A pseudo-F-statistic indicating TE-dependence of the component. This metric is calculated by computing fit to the TE-dependence model at each voxel, and then performing a weighted average based on the voxel-wise weights of the component. Kappa arbitrary n/a
normalized variance explained 'Normalized' variance explained by each component in the ICA weights maps. This is calculated by z-scoring the mixing matrix and optimally combined data over time, then fitting a GLM to calculate voxel-wise parameter estimates for each component. These parameter estimates are then cropped to values between -0.999 and 0.999, and then the Fisher's z-transform is applied to the parameter estimates. This is then used to calculate the variance explained for each component. On a scale from 0 to 100. Normalized variance explained percent n/a
optimal sign Optimal sign determined based on skew direction of component parameter estimates across the brain. In cases where components were left-skewed (-1), the component time series and map weights are flipped prior to metric calculation. This sign applies to the original mixing matrix and map weights. The outputs produced by tedana are already flipped. Optimal component sign n/a {'-1': 'Component is flipped prior to metric calculation.', '1': 'Component is not flipped prior to metric calculation.'}
rho A pseudo-F-statistic indicating TE-independence of the component. This metric is calculated by computing fit to the TE-independence model at each voxel, and then performing a weighted average based on the voxel-wise weights of the component. Rho arbitrary n/a
signal-noise_p P-value for two-sample t-test of F-statistics from 'signal' voxels (voxels in clusters) against 'noise' voxels (voxels not in clusters) for T2 model. Signal > noise p-value arbitrary n/a
signal-noise_t T-statistic for two-sample t-test of F-statistics from 'signal' voxels (voxels in clusters) against 'noise' voxels (voxels not in clusters) for T2 model. Signal > noise t-statistic arbitrary n/a
variance explained The square of the parameter estimates from the regression of the mean-centered, but not z-scored, optimally combined data against the component time series, divided by the sum of the squares of the parameter estimates. This metric reflects relative participation in the fitted model, not unique or marginal explanatory power. On a scale from 0 to 100. Variance explained percent n/a
report = os.path.join(out_dir, "sub-24053_ses-1_task-rat_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))
tedana report

ICA components

Carpet plots

Adaptive mask

T2*

S0

T2* and S0 model fit (RMSE). (Scaled between 2nd and 98th percentiles)

Global Signal Control

Minimum Image Regression

Info

Tedana command used:

      
        tedana_workflow(data=['/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-1_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-2_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-3_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-4_part-mag_desc-preproc_bold.nii.gz', '/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_echo-5_part-mag_desc-preproc_bold.nii.gz'], tes=[0.0142, 0.03893, 0.06366, 0.08839, 0.11312], out_dir=/Users/eurunuela/GitHub/multi-echo-data-analysis/data/tedana, mask=/Users/eurunuela/GitHub/multi-echo-data-analysis/data/ds006185/sub-24053/ses-1/func/sub-24053_ses-1_task-rat_dir-PA_run-01_part-mag_desc-brain_mask.nii.gz, convention=bids, prefix=sub-24053_ses-1_task-rat_dir-PA_run-01_, dummy_scans=0, masktype=['dropout'], fittype=loglin, combmode=t2s, n_independent_echos=None, tree=tedana_orig, external_regressors=None, ica_method=fastica, n_robust_runs=30, tedpca=mdl, fixed_seed=42, maxit=500, maxrestart=10, tedort=False, gscontrol=['mir'], no_reports=False, png_cmap=coolwarm, verbose=True, low_mem=False, debug=False, quiet=False, overwrite=True, t2smap=None, mixing_file=None, n_threads=1)
      
    

System: Darwin
Node: Enekos-MacBook-Pro.local
Release: 25.5.0
System version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:38:56 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6000
Machine: arm64
Processor: arm
Python: 3.12.8 (main, Jan 14 2025, 23:36:58) [Clang 19.1.6 ]
Tedana version: 26.0.3
Other library versions: {'bokeh': '3.9.0', 'mapca': '0.0.7', 'matplotlib': '3.10.8', 'nibabel': '5.4.2', 'nilearn': '0.12.1', 'numpy': '2.4.4', 'pandas': '3.0.2', 'robustica': '0.1.4', 'scikit-learn': '1.8.0', 'scipy': '1.17.1', 'threadpoolctl': '3.6.0', 'tqdm': '4.67.3'}

About tedana

This is the tedana_orig tree (tedana community et al. 2024), which is very similar to the criteria of the MEICA v2.5 decision tree (Kundu et al. 2013). For a description of the decision tree steps, with the rationale for each step, see (Olafsson et al. 2015). TE-dependence analysis was performed on input data using the tedana workflow (DuPre et al. 2021). A user-defined mask was applied to the data. An adaptive mask was then generated using the dropout method(s), in which each voxel's value reflects the number of echoes with 'good' data. An adaptive mask was then generated using the dropout method(s), in which each voxel's value reflects the number of echoes with 'good' data. A two-stage masking procedure was applied, in which a liberal mask (including voxels with good data in at least the first echo) was used for optimal combination, T2*/S0 estimation, and denoising, while a more conservative mask (restricted to voxels with good data in at least the first three echoes) was used for the component classification procedure. A monoexponential model was fit to the data at each voxel using log-linear regression in order to estimate T2* and S0 maps. For each voxel, the value from the adaptive mask was used to determine which echoes would be used to estimate T2* and S0. Multi-echo data were then optimally combined using the T2* combination method (Posse et al. 1999). Principal component analysis based on the PCA component estimation with a Moving Average(stationary Gaussian) process (Li et al. 2007) was applied to the optimally combined data for dimensionality reduction. The following metrics were calculated: kappa, rho, countnoise, countsigFT2, countsigFS0, dice_FT2, dice_FS0, signal-noise_t, variance explained, normalized variance explained, d_table_score. Kappa (kappa) and Rho (rho) were calculated as measures of TE-dependence and TE-independence, respectively. A t-test was performed between the distributions of T2*-model F-statistics associated with clusters (i.e., signal) and non-cluster voxels (i.e., noise) to generate a t-statistic (metric signal-noise_z) and p-value (metric signal-noise_p) measuring relative association of the component to signal over noise. The number of significant voxels not from clusters was calculated for each component. Independent component analysis was then used to decompose the dimensionally reduced dataset. The following metrics were calculated: countnoise, countsigFS0, countsigFT2, d_table_score, dice_FS0, dice_FT2, kappa, normalized variance explained, rho, signal-noise_t, variance explained. Kappa (kappa) and Rho (rho) were calculated as measures of TE-dependence and TE-independence, respectively. A t-test was performed between the distributions of T2*-model F-statistics associated with clusters (i.e., signal) and non-cluster voxels (i.e., noise) to generate a t-statistic (metric signal-noise_z) and p-value (metric signal-noise_p) measuring relative association of the component to signal over noise. The number of significant voxels not from clusters was calculated for each component. Next, component selection was performed to identify BOLD (TE-dependent) and non-BOLD (TE-independent) components using a decision tree. Minimum image regression was then applied to the data in order to remove spatially diffuse noise (Kundu et al. 2013). This workflow used numpy (Van Der Walt et al. 2011), scipy (Virtanen et al. 2020), pandas (McKinney et al. 2010, pandas development team et al. 2020), scikit-learn (Pedregosa et al. 2011), nilearn, bokeh (Team et al. 2018), matplotlib (Hunter et al. 2007), and nibabel (Brett et al. 2019). This workflow also used the Dice similarity index (Dice et al. 1945, Sorensen et al. 1948).

References