From 3c942bb797e18b445b7438e628a2a4c926c4b01b Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:17:47 -0400 Subject: [PATCH 01/21] Drop accepted and rejected outputs. Also remove the term "optcom" from certain outputs. --- tedana/resources/config/outputs.json | 38 +++------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/tedana/resources/config/outputs.json b/tedana/resources/config/outputs.json index b67bfd8dc..605650dc7 100644 --- a/tedana/resources/config/outputs.json +++ b/tedana/resources/config/outputs.json @@ -27,25 +27,9 @@ "orig": "betas_OC", "bidsv1.5.0": "desc-ICA_stat-z_components" }, - "ICA accepted components img": { - "orig": "betas_hik_OC", - "bidsv1.5.0": "desc-ICAAccepted_components" - }, - "z-scored ICA accepted components img": { - "orig": "feats_OC2", - "bidsv1.5.0": "desc-ICAAccepted_stat-z_components" - }, "denoised ts img": { "orig": "dn_ts_OC", - "bidsv1.5.0": "desc-optcomDenoised_bold" - }, - "high kappa ts img": { - "orig": "hik_ts_OC", - "bidsv1.5.0": "desc-optcomAccepted_bold" - }, - "low kappa ts img": { - "orig": "lowk_ts_OC", - "bidsv1.5.0": "desc-optcomRejected_bold" + "bidsv1.5.0": "desc-denoised_bold" }, "limited t2star img": { "orig": "t2sv", @@ -95,17 +79,9 @@ "orig": "ica_weights", "bidsv1.5.0": "desc-ICAAveragingWeights_components" }, - "high kappa ts split img": { - "orig": "hik_ts_e{echo}", - "bidsv1.5.0": "echo-{echo}_desc-Accepted_bold" - }, - "low kappa ts split img": { - "orig": "lowk_ts_e{echo}", - "bidsv1.5.0": "echo-{echo}_desc-Rejected_bold" - }, "denoised ts split img": { "orig": "dn_ts_e{echo}", - "bidsv1.5.0": "echo-{echo}_desc-Denoised_bold" + "bidsv1.5.0": "echo-{echo}_desc-denoised_bold" }, "gs img": { "orig": "T1gs", @@ -123,17 +99,9 @@ "orig": "sphis_hik", "bidsv1.5.0": "desc-T1likeEffect_min" }, - "ICA accepted mir denoised img": { - "orig": "hik_ts_OC_MIR", - "bidsv1.5.0": "desc-optcomAcceptedMIRDenoised_bold" - }, "mir denoised img": { "orig": "dn_ts_OC_MIR", - "bidsv1.5.0": "desc-optcomMIRDenoised_bold" - }, - "ICA accepted mir component weights img": { - "orig": "betas_hik_OC_MIR", - "bidsv1.5.0": "desc-ICAAcceptedMIRDenoised_components" + "bidsv1.5.0": "desc-MIRDenoised_bold" }, "data description json": { "orig": "dataset_description", From 70daca6b7b9253e26455412eab4a2a0e94a6a989 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:18:04 -0400 Subject: [PATCH 02/21] Stop generating accepted and rejected outputs. --- tedana/io.py | 99 ++++++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 72 deletions(-) diff --git a/tedana/io.py b/tedana/io.py index b9e202e1d..81bace695 100644 --- a/tedana/io.py +++ b/tedana/io.py @@ -17,7 +17,7 @@ from nilearn.image import new_img_like from tedana import utils -from tedana.stats import computefeats2, get_coeffs +from tedana.stats import get_coeffs LGR = logging.getLogger("GENERAL") RepLGR = logging.getLogger("REPORT") @@ -371,7 +371,7 @@ def denoise_ts(data, mmix, mask, comptable): # get variance explained by retained components betas = get_coeffs(dmdata.T, mmix, mask=None) varexpl = (1 - ((dmdata.T - betas.dot(mmix.T)) ** 2.0).sum() / (dmdata ** 2.0).sum()) * 100 - LGR.info("Variance explained by decomposition: {:.02f}%".format(varexpl)) + LGR.info(f"Variance explained by decomposition: {varexpl:.02f}%") # create component-based data hikts = utils.unmask(betas[:, acc].dot(mmix.T[acc, :]), mask) @@ -382,8 +382,7 @@ def denoise_ts(data, mmix, mask, comptable): # File Writing Functions def write_split_ts(data, mmix, mask, comptable, io_generator, echo=0): - """ - Splits `data` into denoised / noise / ignored time series and saves to disk + """Split `data` into denoised / noise / ignored time series and save to disk. Parameters ---------- @@ -394,11 +393,11 @@ def write_split_ts(data, mmix, mask, comptable, io_generator, echo=0): is components and `T` is the same as in `data` mask : (S,) array_like Boolean mask array + comptable : (C x X) :obj:`pandas.DataFrame` + Metric table with one row for each component. One column must be named "classification". io_generator : :obj:`tedana.io.OutputGenerator` Reference image to dictate how outputs are saved to disk - out_dir : :obj:`str`, optional - Output directory. - echo: :obj: `int`, optional + echo : :obj:`int`, optional Echo number to generate filenames, used by some verbose functions. Default 0. @@ -411,44 +410,25 @@ def write_split_ts(data, mmix, mask, comptable, io_generator, echo=0): ----- This function writes out several files: - ============================ ============================================ - Filename Content - ============================ ============================================ - [prefix]Accepted_bold.nii.gz High-Kappa time series. - [prefix]Rejected_bold.nii.gz Low-Kappa time series. - [prefix]Denoised_bold.nii.gz Denoised time series. - ============================ ============================================ + ======================================= =============================================== + Filename Content + ======================================= =============================================== + [echo-(echo)_]desc-denoised_bold.nii.gz Denoised time series. If ``echo`` is not 0, + then the filename will include the echo entity. + ======================================= =============================================== """ - acc = comptable[comptable.classification == "accepted"].index.values - rej = comptable[comptable.classification == "rejected"].index.values - - dnts, hikts, lowkts = denoise_ts(data, mmix, mask, comptable) - - if len(acc) != 0: - if echo != 0: - fout = io_generator.save_file(hikts, "high kappa ts split img", echo=echo) - else: - fout = io_generator.save_file(hikts, "high kappa ts img") - LGR.info("Writing high-Kappa time series: {}".format(fout)) - - if len(rej) != 0: - if echo != 0: - fout = io_generator.save_file(lowkts, "low kappa ts split img", echo=echo) - else: - fout = io_generator.save_file(lowkts, "low kappa ts img") - LGR.info("Writing low-Kappa time series: {}".format(fout)) + dnts, _, _ = denoise_ts(data, mmix, mask, comptable) if echo != 0: fout = io_generator.save_file(dnts, "denoised ts split img", echo=echo) else: fout = io_generator.save_file(dnts, "denoised ts img") - LGR.info("Writing denoised time series: {}".format(fout)) + LGR.info(f"Writing denoised time series: {fout}") -def writeresults(ts, mask, comptable, mmix, n_vols, io_generator): - """ - Denoises `ts` and saves all resulting files to disk +def writeresults(ts, mask, comptable, mmix, io_generator): + """Denoise `ts` and save all resulting files to disk. Parameters ---------- @@ -463,9 +443,7 @@ def writeresults(ts, mask, comptable, mmix, n_vols, io_generator): mmix : (C x T) array_like Mixing matrix for converting input data to component space, where `C` is components and `T` is the same as in `data` - n_vols : :obj:`int` - Number of volumes in original time series - ref_img : :obj:`str` or img_like + io_generator : :obj:`tedana.io.OutputGenerator` Reference image to dictate how outputs are saved to disk Notes @@ -475,42 +453,24 @@ def writeresults(ts, mask, comptable, mmix, n_vols, io_generator): ========================================= ===================================== Filename Content ========================================= ===================================== - desc-optcomAccepted_bold.nii.gz High-Kappa time series. - desc-optcomRejected_bold.nii.gz Low-Kappa time series. - desc-optcomDenoised_bold.nii.gz Denoised time series. + desc-denoised_bold.nii.gz Denoised time series. desc-ICA_components.nii.gz Spatial component maps for all components. - desc-ICAAccepted_components.nii.gz Spatial component maps for accepted - components. - desc-ICAAccepted_stat-z_components.nii.gz Z-normalized spatial component maps - for accepted components. ========================================= ===================================== See Also -------- tedana.io.write_split_ts: Writes out time series files """ - acc = comptable[comptable.classification == "accepted"].index.values write_split_ts(ts, mmix, mask, comptable, io_generator) - ts_B = get_coeffs(ts, mmix, mask) - fout = io_generator.save_file(ts_B, "ICA components img") - LGR.info("Writing full ICA coefficient feature set: {}".format(fout)) - - if len(acc) != 0: - fout = io_generator.save_file(ts_B[:, acc], "ICA accepted components img") - LGR.info("Writing denoised ICA coefficient feature set: {}".format(fout)) - - # write feature versions of components - feats = computefeats2(split_ts(ts, mmix, mask, comptable)[0], mmix[:, acc], mask) - feats = utils.unmask(feats, mask) - fname = io_generator.save_file(feats, "z-scored ICA accepted components img") - LGR.info("Writing Z-normalized spatial component maps: {}".format(fname)) + component_weights = get_coeffs(ts, mmix, mask) + fout = io_generator.save_file(component_weights, "ICA components img") + LGR.info(f"Writing full ICA coefficient feature set: {fout}") def writeresults_echoes(catd, mmix, mask, comptable, io_generator): - """ - Saves individually denoised echos to disk + """Save individually denoised echos to disk. Parameters ---------- @@ -524,23 +484,18 @@ def writeresults_echoes(catd, mmix, mask, comptable, io_generator): comptable : (C x X) :obj:`pandas.DataFrame` Component metric table. One row for each component, with a column for each metric. The index should be the component number. - ref_img : :obj:`str` or img_like + io_generator : :obj:`tedana.io.OutputGenerator` Reference image to dictate how outputs are saved to disk Notes ----- This function writes out several files: - ===================================== =================================== + ===================================== ============================================= Filename Content - ===================================== =================================== - echo-[echo]_desc-Accepted_bold.nii.gz High-Kappa timeseries for echo - number ``echo``. - echo-[echo]_desc-Rejected_bold.nii.gz Low-Kappa timeseries for echo - number ``echo``. - echo-[echo]_desc-Denoised_bold.nii.gz Denoised timeseries for echo - number ``echo``. - ===================================== =================================== + ===================================== ============================================= + echo-[echo]_desc-denoised_bold.nii.gz Denoised timeseries for echo number ``echo``. + ===================================== ============================================= See Also -------- From b56c8364c922d48afa4201e7ace76445b34d53b5 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:18:16 -0400 Subject: [PATCH 03/21] Update integration test outputs. --- .../tests/data/cornell_three_echo_outputs.txt | 6 +---- tedana/tests/data/fiu_four_echo_outputs.txt | 26 +++++-------------- .../data/nih_five_echo_outputs_verbose.txt | 26 +++++-------------- 3 files changed, 13 insertions(+), 45 deletions(-) diff --git a/tedana/tests/data/cornell_three_echo_outputs.txt b/tedana/tests/data/cornell_three_echo_outputs.txt index 70198576f..6e0fbf5db 100644 --- a/tedana/tests/data/cornell_three_echo_outputs.txt +++ b/tedana/tests/data/cornell_three_echo_outputs.txt @@ -1,8 +1,6 @@ S0map.nii.gz T2starmap.nii.gz dataset_description.json -desc-ICAAccepted_components.nii.gz -desc-ICAAccepted_stat-z_components.nii.gz desc-ICA_components.nii.gz desc-ICA_decomposition.json desc-tedana_metrics.json @@ -15,9 +13,7 @@ desc-PCA_metrics.tsv desc-PCA_mixing.tsv desc-PCA_stat-z_components.nii.gz desc-adaptiveGoodSignal_mask.nii.gz -desc-optcomAccepted_bold.nii.gz -desc-optcomDenoised_bold.nii.gz -desc-optcomRejected_bold.nii.gz +desc-denoised_bold.nii.gz desc-optcom_bold.nii.gz report.txt tedana_report.html diff --git a/tedana/tests/data/fiu_four_echo_outputs.txt b/tedana/tests/data/fiu_four_echo_outputs.txt index 7e9ce1169..c2374ae80 100644 --- a/tedana/tests/data/fiu_four_echo_outputs.txt +++ b/tedana/tests/data/fiu_four_echo_outputs.txt @@ -1,9 +1,6 @@ S0map.nii.gz T2starmap.nii.gz dataset_description.json -desc-ICAAcceptedMIRDenoised_components.nii.gz -desc-ICAAccepted_components.nii.gz -desc-ICAAccepted_stat-z_components.nii.gz desc-ICAAveragingWeights_components.nii.gz desc-ICAMIRDenoised_mixing.tsv desc-ICA_components.nii.gz @@ -24,51 +21,40 @@ desc-globalSignal_map.nii.gz desc-globalSignal_timeseries.tsv desc-limited_S0map.nii.gz desc-limited_T2starmap.nii.gz -desc-optcomAcceptedMIRDenoised_bold.nii.gz -desc-optcomAccepted_bold.nii.gz -desc-optcomDenoised_bold.nii.gz -desc-optcomMIRDenoised_bold.nii.gz +desc-denoised_bold.nii.gz +desc-MIRDenoised_bold.nii.gz desc-optcomNoGlobalSignal_bold.nii.gz desc-optcomPCAReduced_bold.nii.gz -desc-optcomRejected_bold.nii.gz desc-optcomWithGlobalSignal_bold.nii.gz desc-optcom_bold.nii.gz -echo-1_desc-Accepted_bold.nii.gz -echo-1_desc-Denoised_bold.nii.gz +echo-1_desc-denoised_bold.nii.gz echo-1_desc-ICAT2ModelPredictions_components.nii.gz echo-1_desc-ICAS0ModelPredictions_components.nii.gz echo-1_desc-ICA_components.nii.gz echo-1_desc-PCAT2ModelPredictions_components.nii.gz echo-1_desc-PCAS0ModelPredictions_components.nii.gz echo-1_desc-PCA_components.nii.gz -echo-1_desc-Rejected_bold.nii.gz -echo-2_desc-Accepted_bold.nii.gz -echo-2_desc-Denoised_bold.nii.gz +echo-2_desc-denoised_bold.nii.gz echo-2_desc-ICAT2ModelPredictions_components.nii.gz echo-2_desc-ICAS0ModelPredictions_components.nii.gz echo-2_desc-ICA_components.nii.gz echo-2_desc-PCAT2ModelPredictions_components.nii.gz echo-2_desc-PCAS0ModelPredictions_components.nii.gz echo-2_desc-PCA_components.nii.gz -echo-2_desc-Rejected_bold.nii.gz -echo-3_desc-Accepted_bold.nii.gz -echo-3_desc-Denoised_bold.nii.gz +echo-3_desc-denoised_bold.nii.gz echo-3_desc-ICAT2ModelPredictions_components.nii.gz echo-3_desc-ICAS0ModelPredictions_components.nii.gz echo-3_desc-ICA_components.nii.gz echo-3_desc-PCAT2ModelPredictions_components.nii.gz echo-3_desc-PCAS0ModelPredictions_components.nii.gz echo-3_desc-PCA_components.nii.gz -echo-3_desc-Rejected_bold.nii.gz -echo-4_desc-Accepted_bold.nii.gz -echo-4_desc-Denoised_bold.nii.gz +echo-4_desc-denoised_bold.nii.gz echo-4_desc-ICAT2ModelPredictions_components.nii.gz echo-4_desc-ICAS0ModelPredictions_components.nii.gz echo-4_desc-ICA_components.nii.gz echo-4_desc-PCAT2ModelPredictions_components.nii.gz echo-4_desc-PCAS0ModelPredictions_components.nii.gz echo-4_desc-PCA_components.nii.gz -echo-4_desc-Rejected_bold.nii.gz report.txt tedana_report.html figures diff --git a/tedana/tests/data/nih_five_echo_outputs_verbose.txt b/tedana/tests/data/nih_five_echo_outputs_verbose.txt index 907b4ec49..7811bfaf4 100644 --- a/tedana/tests/data/nih_five_echo_outputs_verbose.txt +++ b/tedana/tests/data/nih_five_echo_outputs_verbose.txt @@ -1,8 +1,6 @@ S0map.nii.gz T2starmap.nii.gz dataset_description.json -desc-ICAAccepted_components.nii.gz -desc-ICAAccepted_stat-z_components.nii.gz desc-ICAAveragingWeights_components.nii.gz desc-ICAOrth_mixing.tsv desc-ICA_components.nii.gz @@ -20,56 +18,44 @@ desc-PCA_stat-z_components.nii.gz desc-adaptiveGoodSignal_mask.nii.gz desc-limited_S0map.nii.gz desc-limited_T2starmap.nii.gz -desc-optcomAccepted_bold.nii.gz -desc-optcomDenoised_bold.nii.gz +desc-denoised_bold.nii.gz desc-optcomPCAReduced_bold.nii.gz -desc-optcomRejected_bold.nii.gz desc-optcom_bold.nii.gz -echo-1_desc-Accepted_bold.nii.gz -echo-1_desc-Denoised_bold.nii.gz +echo-1_desc-denoised_bold.nii.gz echo-1_desc-ICAT2ModelPredictions_components.nii.gz echo-1_desc-ICAS0ModelPredictions_components.nii.gz echo-1_desc-ICA_components.nii.gz echo-1_desc-PCAT2ModelPredictions_components.nii.gz echo-1_desc-PCAS0ModelPredictions_components.nii.gz echo-1_desc-PCA_components.nii.gz -echo-1_desc-Rejected_bold.nii.gz -echo-2_desc-Accepted_bold.nii.gz -echo-2_desc-Denoised_bold.nii.gz +echo-2_desc-denoised_bold.nii.gz echo-2_desc-ICAT2ModelPredictions_components.nii.gz echo-2_desc-ICAS0ModelPredictions_components.nii.gz echo-2_desc-ICA_components.nii.gz echo-2_desc-PCAT2ModelPredictions_components.nii.gz echo-2_desc-PCAS0ModelPredictions_components.nii.gz echo-2_desc-PCA_components.nii.gz -echo-2_desc-Rejected_bold.nii.gz -echo-3_desc-Accepted_bold.nii.gz -echo-3_desc-Denoised_bold.nii.gz +echo-3_desc-denoised_bold.nii.gz echo-3_desc-ICAT2ModelPredictions_components.nii.gz echo-3_desc-ICAS0ModelPredictions_components.nii.gz echo-3_desc-ICA_components.nii.gz echo-3_desc-PCAT2ModelPredictions_components.nii.gz echo-3_desc-PCAS0ModelPredictions_components.nii.gz echo-3_desc-PCA_components.nii.gz -echo-3_desc-Rejected_bold.nii.gz -echo-4_desc-Accepted_bold.nii.gz -echo-4_desc-Denoised_bold.nii.gz +echo-4_desc-denoised_bold.nii.gz echo-4_desc-ICAT2ModelPredictions_components.nii.gz echo-4_desc-ICAS0ModelPredictions_components.nii.gz echo-4_desc-ICA_components.nii.gz echo-4_desc-PCAT2ModelPredictions_components.nii.gz echo-4_desc-PCAS0ModelPredictions_components.nii.gz echo-4_desc-PCA_components.nii.gz -echo-4_desc-Rejected_bold.nii.gz -echo-5_desc-Accepted_bold.nii.gz -echo-5_desc-Denoised_bold.nii.gz +echo-5_desc-denoised_bold.nii.gz echo-5_desc-ICAT2ModelPredictions_components.nii.gz echo-5_desc-ICAS0ModelPredictions_components.nii.gz echo-5_desc-ICA_components.nii.gz echo-5_desc-PCAT2ModelPredictions_components.nii.gz echo-5_desc-PCAS0ModelPredictions_components.nii.gz echo-5_desc-PCA_components.nii.gz -echo-5_desc-Rejected_bold.nii.gz report.txt tedana_report.html figures From b980089b351e58190cdcc1b3dd741878f0c88f7c Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:18:22 -0400 Subject: [PATCH 04/21] Remove unused parameter. --- tedana/workflows/tedana.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tedana/workflows/tedana.py b/tedana/workflows/tedana.py index b290a17c6..cc9079d62 100644 --- a/tedana/workflows/tedana.py +++ b/tedana/workflows/tedana.py @@ -771,7 +771,6 @@ def tedana_workflow( mask=mask_denoise, comptable=comptable, mmix=mmix, - n_vols=n_vols, io_generator=io_generator, ) From ba9cda0583baf60f4abee7f4179b54dc493564dc Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:23:16 -0400 Subject: [PATCH 05/21] Update outputs documentation. --- docs/outputs.rst | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 4eefb884e..1beac3300 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -27,12 +27,8 @@ S0map.nii.gz Full S0 3D map. the S0 estimate from the first two echoes, while the limited map has a NaN. desc-optcom_bold.nii.gz Optimally combined time series. -desc-optcomDenoised_bold.nii.gz Denoised optimally combined time series. Recommended +desc-denoised_bold.nii.gz Denoised optimally combined time series. Recommended dataset for analysis. -desc-optcomRejected_bold.nii.gz Combined time series from rejected components. -desc-optcomAccepted_bold.nii.gz High-kappa time series. This dataset does not - include thermal noise or low variance components. - Not the recommended dataset for analysis. desc-adaptiveGoodSignal_mask.nii.gz Integer-valued mask used in the workflow, where each voxel's value corresponds to the number of good echoes to be used for T2\*/S0 estimation. @@ -67,8 +63,6 @@ desc-tedana_metrics.tsv TEDICA component table. A BI decomposition. desc-tedana_metrics.json Metadata about the metrics in ``desc-tedana_metrics.tsv``. -desc-ICAAccepted_components.nii.gz High-kappa ICA coefficient feature set -desc-ICAAcceptedZ_components.nii.gz Z-normalized spatial component maps report.txt A summary report for the workflow with relevant citations. tedana_report.html The interactive HTML report. @@ -101,9 +95,7 @@ desc-[PCA|ICA]AveragingWeights_components.nii.gz Component-wise a calculation. desc-optcomPCAReduced_bold.nii.gz Optimally combined data after dimensionality reduction with PCA. This is the input to the ICA. -echo-[echo]_desc-Accepted_bold.nii.gz High-Kappa time series for echo number ``echo`` -echo-[echo]_desc-Rejected_bold.nii.gz Low-Kappa time series for echo number ``echo`` -echo-[echo]_desc-Denoised_bold.nii.gz Denoised time series for echo number ``echo`` +echo-[echo]_desc-denoised_bold.nii.gz Denoised time series for echo number ``echo`` ============================================================== ===================================================== If ``gscontrol`` includes 'gsr': @@ -120,16 +112,14 @@ desc-optcomNoGlobalSignal_bold.nii.gz Optimally combined time seri removed. ================================================ ===================================================== -If ``gscontrol`` includes 't1c': +If ``gscontrol`` includes 'mir': ================================================ ===================================================== Filename Content ================================================ ===================================================== desc-T1likeEffect_min.nii.gz T1-like effect -desc-optcomAcceptedT1cDenoised_bold.nii.gz T1-corrected high-kappa time series by regression -desc-optcomT1cDenoised_bold.nii.gz T1-corrected denoised time series -desc-TEDICAAcceptedT1cDenoised_components.nii.gz T1-GS corrected high-kappa components -desc-TEDICAT1cDenoised_mixing.tsv T1-GS corrected mixing matrix +desc-MIRDenoised_bold.nii.gz T1-corrected denoised time series +desc-ICAMIRDenoised_mixing.tsv T1-GS corrected mixing matrix ================================================ ===================================================== From 9097e9aff6966ee811cba10fadf3b23c2250fc25 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:42:44 -0400 Subject: [PATCH 06/21] Update gscontrol.py --- tedana/gscontrol.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tedana/gscontrol.py b/tedana/gscontrol.py index 33d184f57..d3644d77a 100644 --- a/tedana/gscontrol.py +++ b/tedana/gscontrol.py @@ -166,9 +166,7 @@ def minimum_image_regression(optcom_ts, mmix, mask, comptable, io_generator): Filename Content ====================== ================================================= sphis_hik.nii T1-like effect - hik_ts_OC_MIR.nii T1-corrected BOLD (high-Kappa) time series dn_ts_OC_MIR.nii Denoised version of T1-corrected time series - betas_hik_OC_MIR.nii T1 global signal-corrected components meica_mix_MIR.1D T1 global signal-corrected mixing matrix ====================== ================================================= @@ -221,8 +219,6 @@ def minimum_image_regression(optcom_ts, mmix, mask, comptable, io_generator): mehk_noT1gs = mehk_ts - np.dot( np.linalg.lstsq(glob_sig.T, mehk_ts.T, rcond=None)[0].T, glob_sig ) - hik_ts = mehk_noT1gs * optcom_std # rescale - io_generator.save_file(utils.unmask(hik_ts, mask), "ICA accepted mir denoised img") # Make denoised version of T1-corrected time series medn_ts = optcom_mean + ((mehk_noT1gs + resid) * optcom_std) @@ -235,11 +231,6 @@ def minimum_image_regression(optcom_ts, mmix, mask, comptable, io_generator): (np.atleast_2d(np.ones(max(glob_sig.shape))), glob_sig, mmix_noT1gs_z) ) - # Write T1-corrected components and mixing matrix - comp_pes_norm = np.linalg.lstsq(mmix_noT1gs_z.T, optcom_z.T, rcond=None)[0].T - io_generator.save_file( - utils.unmask(comp_pes_norm[:, 2:], mask), - "ICA accepted mir component weights img", - ) + # Write T1-corrected mixing matrix mixing_df = pd.DataFrame(data=mmix_noT1gs.T, columns=comptable["Component"].values) io_generator.save_file(mixing_df, "ICA MIR mixing tsv") From 3c5cb38110de19c62f3c6daa3993a5fadaececc6 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:44:27 -0400 Subject: [PATCH 07/21] Update gscontrol.py --- tedana/gscontrol.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tedana/gscontrol.py b/tedana/gscontrol.py index d3644d77a..b2c121a1a 100644 --- a/tedana/gscontrol.py +++ b/tedana/gscontrol.py @@ -226,10 +226,6 @@ def minimum_image_regression(optcom_ts, mmix, mask, comptable, io_generator): # Orthogonalize mixing matrix w.r.t. T1-GS mmix_noT1gs = mmix.T - np.dot(np.linalg.lstsq(glob_sig.T, mmix, rcond=None)[0].T, glob_sig) - mmix_noT1gs_z = stats.zscore(mmix_noT1gs, axis=-1) - mmix_noT1gs_z = np.vstack( - (np.atleast_2d(np.ones(max(glob_sig.shape))), glob_sig, mmix_noT1gs_z) - ) # Write T1-corrected mixing matrix mixing_df = pd.DataFrame(data=mmix_noT1gs.T, columns=comptable["Component"].values) From c7d8bc09275479c2fc5816a994d5553e3c69b9a1 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 22 Oct 2021 14:55:27 -0400 Subject: [PATCH 08/21] Fix failing test. --- tedana/tests/test_io.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tedana/tests/test_io.py b/tedana/tests/test_io.py index 26183e130..8090a5d1c 100644 --- a/tedana/tests/test_io.py +++ b/tedana/tests/test_io.py @@ -144,9 +144,8 @@ def test_smoke_write_split_ts(): me.write_split_ts(data, mmix, mask, comptable, io_generator) - # TODO: midk_ts.nii is never generated? fn = io_generator.get_name - split = ("high kappa ts img", "low kappa ts img", "denoised ts img") + split = ("denoised ts img",) fnames = [fn(f) for f in split] for filename in fnames: # remove all files generated From 1b1e34a8bb4661b672de847711539e95ca9f51af Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 11:19:23 -0500 Subject: [PATCH 09/21] Add links to gscontrol docs. --- docs/approach.rst | 2 +- docs/outputs.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/approach.rst b/docs/approach.rst index eb05cc49e..d5151e6c3 100644 --- a/docs/approach.rst +++ b/docs/approach.rst @@ -346,7 +346,7 @@ yielding a denoised timeseries, which is saved as **desc-optcomDenoised_bold.nii Removal of spatially diffuse noise (optional) ********************************************* -:func:`tedana.gscontrol.gscontrol_raw`, :func:`tedana.gscontrol.gscontrol_mmix` +:func:`tedana.gscontrol.gscontrol_raw`, :func:`tedana.gscontrol.minimum_image_regression` Due to the constraints of ICA, TEDICA is able to identify and remove spatially localized noise components, but it cannot identify components that are spread diff --git a/docs/outputs.rst b/docs/outputs.rst index 1beac3300..75623782c 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -98,7 +98,7 @@ desc-optcomPCAReduced_bold.nii.gz Optimally combin echo-[echo]_desc-denoised_bold.nii.gz Denoised time series for echo number ``echo`` ============================================================== ===================================================== -If ``gscontrol`` includes 'gsr': +If ``gscontrol`` includes 'gsr' (see :func:`tedana.gscontrol.gscontrol_raw`): ================================================ ===================================================== Filename Content @@ -112,7 +112,7 @@ desc-optcomNoGlobalSignal_bold.nii.gz Optimally combined time seri removed. ================================================ ===================================================== -If ``gscontrol`` includes 'mir': +If ``gscontrol`` includes 'mir' (see :func:`tedana.gscontrol.minimum_image_regression`): ================================================ ===================================================== Filename Content From c6f09d32fd26547249c9ae8febb6c5e3c4800970 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 11:19:30 -0500 Subject: [PATCH 10/21] Add warning about GSR to docstring. --- tedana/gscontrol.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tedana/gscontrol.py b/tedana/gscontrol.py index b2c121a1a..894c71679 100644 --- a/tedana/gscontrol.py +++ b/tedana/gscontrol.py @@ -46,6 +46,12 @@ def gscontrol_raw(catd, optcom, n_echos, io_generator, dtrank=4): Input `catd` with global signal removed from time series dm_optcom : (S x T) array_like Input `optcom` with global signal removed from time series + + Warning + ------- + This GSR approach is rather dissimilar to the more common approach of extracting global signal + using a gray matter or whole brain mask, and regressing the mean of that signal from the rest + of the brain. """ LGR.info("Applying amplitude-based T1 equilibration correction") RepLGR.info( From 996b16c18996d99c2506d682eb397b1b67447e09 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 11:48:13 -0500 Subject: [PATCH 11/21] Try documenting old version in table. --- docs/outputs.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/outputs.rst b/docs/outputs.rst index 75623782c..44fb92928 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -32,6 +32,8 @@ desc-denoised_bold.nii.gz Denoised optimally combined desc-adaptiveGoodSignal_mask.nii.gz Integer-valued mask used in the workflow, where each voxel's value corresponds to the number of good echoes to be used for T2\*/S0 estimation. + + **Original name**: adaptive_mask.nii.gz desc-PCA_mixing.tsv Mixing matrix (component time series) from PCA decomposition in a tab-delimited file. Each column is a different component, and the column name is the From 280771c1abc54f6e0415a921cfd70b77a64388bc Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 12:04:05 -0500 Subject: [PATCH 12/21] Add bidsv1.6.0 convention. --- docs/outputs.rst | 4 + tedana/io.py | 12 ++- tedana/resources/config/outputs.json | 114 ++++++++++++++++++--------- tedana/workflows/tedana.py | 16 +++- 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 44fb92928..fb34df7e2 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -20,6 +20,10 @@ T2starmap.nii.gz Full estimated T2* 3D map. only one echo contains good data, the full map uses the T2* estimate from the first two echoes, while the limited map has a NaN. + + **Original name**: t2svG.nii.gz + + **Before version 0.0.11**: desc-full_T2starmap.nii.gz S0map.nii.gz Full S0 3D map. The difference between the limited and full maps is that, for voxels affected by dropout where diff --git a/tedana/io.py b/tedana/io.py index 81bace695..62ad37dff 100644 --- a/tedana/io.py +++ b/tedana/io.py @@ -27,12 +27,16 @@ class OutputGenerator: """A class for managing tedana outputs. + .. versionchanged:: 0.0.12 + + * Default naming convention changed from bidsv1.5.0 to bidsv1.6.0. + Parameters ---------- reference_img : img_like The reference image which defines affine, shape, etc. of output images. - convention : {"bidsv1.5.0", "orig", or other str}, optional - Default is "bidsv1.5.0". Must correspond to a key in ``config``. + convention : {"bidsv1.6.0", "bidsv1.5.0", "orig", :obj:`str`}, optional + Default is "bidsv1.6.0". Must correspond to a key in ``config``. out_dir : str, optional Output directory. Default is current working directory ("."). prefix : None or str, optional @@ -65,7 +69,7 @@ class OutputGenerator: def __init__( self, reference_img, - convention="bidsv1.5.0", + convention="bidsv1.6.0", out_dir=".", prefix="", config="auto", @@ -78,7 +82,7 @@ def __init__( if convention == "bids": # modify to update default bids convention number - convention = "bidsv1.5.0" + convention = "bidsv1.6.0" config = load_json(config) diff --git a/tedana/resources/config/outputs.json b/tedana/resources/config/outputs.json index 605650dc7..a49e88cf9 100644 --- a/tedana/resources/config/outputs.json +++ b/tedana/resources/config/outputs.json @@ -1,154 +1,192 @@ { "adaptive mask img": { "orig": "adaptive_mask", - "bidsv1.5.0": "desc-adaptiveGoodSignal_mask" + "bidsv1.5.0": "desc-adaptiveGoodSignal_mask", + "bidsv1.6.0": "desc-adaptiveGoodSignal_mask" }, "t2star img": { "orig": "t2svG", - "bidsv1.5.0": "T2starmap" + "bidsv1.5.0": "desc-full_T2starmap", + "bidsv1.6.0": "T2starmap" }, "s0 img": { "orig": "s0vG", - "bidsv1.5.0": "S0map" + "bidsv1.5.0": "desc-full_S0map", + "bidsv1.6.0": "S0map" }, "combined img": { "orig": "ts_OC", - "bidsv1.5.0": "desc-optcom_bold" + "bidsv1.5.0": "desc-optcom_bold", + "bidsv1.6.0": "desc-optcom_bold" }, "ICA components img": { "orig": "ica_components", - "bidsv1.5.0": "desc-ICA_components" + "bidsv1.5.0": "desc-ICA_components", + "bidsv1.6.0": "desc-ICA_components" }, "z-scored PCA components img": { "orig": "pca_components", - "bidsv1.5.0": "desc-PCA_stat-z_components" + "bidsv1.5.0": "desc-PCA_stat-z_components", + "bidsv1.6.0": "desc-PCA_stat-z_components" }, "z-scored ICA components img": { "orig": "betas_OC", - "bidsv1.5.0": "desc-ICA_stat-z_components" + "bidsv1.5.0": "desc-ICA_stat-z_components", + "bidsv1.6.0": "desc-ICA_stat-z_components" }, "denoised ts img": { "orig": "dn_ts_OC", - "bidsv1.5.0": "desc-denoised_bold" + "bidsv1.5.0": "desc-optcomDenoised_bold", + "bidsv1.6.0": "desc-denoised_bold" }, "limited t2star img": { "orig": "t2sv", - "bidsv1.5.0": "desc-limited_T2starmap" + "bidsv1.5.0": "T2starmap", + "bidsv1.6.0": "desc-limited_T2starmap" }, "limited s0 img": { "orig": "s0v", - "bidsv1.5.0": "desc-limited_S0map" + "bidsv1.5.0": "S0map", + "bidsv1.6.0": "desc-limited_S0map" }, "whitened img": { "orig": "ts_OC_whitened", - "bidsv1.5.0": "desc-optcomPCAReduced_bold" + "bidsv1.5.0": "desc-optcomPCAReduced_bold", + "bidsv1.6.0": "desc-optcomPCAReduced_bold" }, "echo weight PCA map split img": { "orig": "e{echo}_PCA_comp", - "bidsv1.5.0": "echo-{echo}_desc-PCA_components" + "bidsv1.5.0": "echo-{echo}_desc-PCA_components", + "bidsv1.6.0": "echo-{echo}_desc-PCA_components" }, "echo T2 PCA split img": { "orig": "e{echo}_PCA_T2", - "bidsv1.5.0": "echo-{echo}_desc-PCAT2ModelPredictions_components" + "bidsv1.5.0": "echo-{echo}_desc-PCAT2ModelPredictions_components", + "bidsv1.6.0": "echo-{echo}_desc-PCAT2ModelPredictions_components" }, "echo S0 PCA split img": { "orig": "e{echo}_PCA_S0", - "bidsv1.5.0": "echo-{echo}_desc-PCAS0ModelPredictions_components" + "bidsv1.5.0": "echo-{echo}_desc-PCAS0ModelPredictions_components", + "bidsv1.6.0": "echo-{echo}_desc-PCAS0ModelPredictions_components" }, "PCA component weights img": { "orig": "pca_weights", - "bidsv1.5.0": "desc-PCAAveragingWeights_components" + "bidsv1.5.0": "desc-PCAAveragingWeights_components", + "bidsv1.6.0": "desc-PCAAveragingWeights_components" }, "PCA reduced img": { "orig": "oc_reduced", - "bidsv1.5.0": "desc-optcomPCAReduced_bold" + "bidsv1.5.0": "desc-optcomPCAReduced_bold", + "bidsv1.6.0": "desc-optcomPCAReduced_bold" }, "echo weight ICA map split img": { "orig": "e{echo}_ICA_comp", - "bidsv1.5.0": "echo-{echo}_desc-ICA_components" + "bidsv1.5.0": "echo-{echo}_desc-ICA_components", + "bidsv1.6.0": "echo-{echo}_desc-ICA_components" }, "echo T2 ICA split img": { "orig": "e{echo}_ICA_T2", - "bidsv1.5.0": "echo-{echo}_desc-ICAT2ModelPredictions_components" + "bidsv1.5.0": "echo-{echo}_desc-ICAT2ModelPredictions_components", + "bidsv1.6.0": "echo-{echo}_desc-ICAT2ModelPredictions_components" }, "echo S0 ICA split img": { "orig": "e{echo}_ICA_S0", - "bidsv1.5.0": "echo-{echo}_desc-ICAS0ModelPredictions_components" + "bidsv1.5.0": "echo-{echo}_desc-ICAS0ModelPredictions_components", + "bidsv1.6.0": "echo-{echo}_desc-ICAS0ModelPredictions_components" }, "ICA component weights img": { "orig": "ica_weights", - "bidsv1.5.0": "desc-ICAAveragingWeights_components" + "bidsv1.5.0": "desc-ICAAveragingWeights_components", + "bidsv1.6.0": "desc-ICAAveragingWeights_components" }, "denoised ts split img": { "orig": "dn_ts_e{echo}", - "bidsv1.5.0": "echo-{echo}_desc-denoised_bold" + "bidsv1.5.0": "echo-{echo}_desc-Denoised_bold", + "bidsv1.6.0": "echo-{echo}_desc-denoised_bold" }, "gs img": { "orig": "T1gs", - "bidsv1.5.0": "desc-globalSignal_map" + "bidsv1.5.0": "desc-globalSignal_map", + "bidsv1.6.0": "desc-globalSignal_map" }, "has gs combined img": { "orig": "tsoc_orig", - "bidsv1.5.0": "desc-optcomWithGlobalSignal_bold" + "bidsv1.5.0": "desc-optcomWithGlobalSignal_bold", + "bidsv1.6.0": "desc-optcomWithGlobalSignal_bold" }, "removed gs combined img": { "orig": "tsoc_nogs", - "bidsv1.5.0": "desc-optcomNoGlobalSignal_bold" + "bidsv1.5.0": "desc-optcomNoGlobalSignal_bold", + "bidsv1.6.0": "desc-optcomNoGlobalSignal_bold" }, "t1 like img": { "orig": "sphis_hik", - "bidsv1.5.0": "desc-T1likeEffect_min" + "bidsv1.5.0": "desc-T1likeEffect_min", + "bidsv1.6.0": "desc-T1likeEffect_min" }, "mir denoised img": { "orig": "dn_ts_OC_MIR", - "bidsv1.5.0": "desc-MIRDenoised_bold" + "bidsv1.5.0": "desc-optcomMIRDenoised_bold", + "bidsv1.6.0": "desc-MIRDenoised_bold" }, "data description json": { "orig": "dataset_description", - "bidsv1.5.0": "dataset_description" + "bidsv1.5.0": "dataset_description", + "bidsv1.6.0": "dataset_description" }, "PCA decomposition json": { "orig": "pca_decomposition", - "bidsv1.5.0": "desc-PCA_decomposition" + "bidsv1.5.0": "desc-PCA_decomposition", + "bidsv1.6.0": "desc-PCA_decomposition" }, "PCA metrics json": { "orig": "pca_metrics", - "bidsv1.5.0": "desc-PCA_metrics" + "bidsv1.5.0": "desc-PCA_metrics", + "bidsv1.6.0": "desc-PCA_metrics" }, "ICA decomposition json": { "orig": "ica_decomposition", - "bidsv1.5.0": "desc-ICA_decomposition" + "bidsv1.5.0": "desc-ICA_decomposition", + "bidsv1.6.0": "desc-ICA_decomposition" }, "ICA metrics json": { "orig": "ica_metrics", - "bidsv1.5.0": "desc-tedana_metrics" + "bidsv1.5.0": "desc-tedana_metrics", + "bidsv1.6.0": "desc-tedana_metrics" }, "PCA mixing tsv": { "orig": "pca_mixing", - "bidsv1.5.0": "desc-PCA_mixing" + "bidsv1.5.0": "desc-PCA_mixing", + "bidsv1.6.0": "desc-PCA_mixing" }, "PCA metrics tsv": { "orig": "pca_metrics", - "bidsv1.5.0": "desc-PCA_metrics" + "bidsv1.5.0": "desc-PCA_metrics", + "bidsv1.6.0": "desc-PCA_metrics" }, "ICA mixing tsv": { "orig": "ica_mixing", - "bidsv1.5.0": "desc-ICA_mixing" + "bidsv1.5.0": "desc-ICA_mixing", + "bidsv1.6.0": "desc-ICA_mixing" }, "ICA metrics tsv": { "orig": "ica_metrics", - "bidsv1.5.0": "desc-tedana_metrics" + "bidsv1.5.0": "desc-tedana_metrics", + "bidsv1.6.0": "desc-tedana_metrics" }, "global signal time series tsv": { "orig": "global_signal_ts", - "bidsv1.5.0": "desc-globalSignal_timeseries" + "bidsv1.5.0": "desc-globalSignal_timeseries", + "bidsv1.6.0": "desc-globalSignal_timeseries" }, "ICA MIR mixing tsv": { "orig": "ica_mir_mixing", - "bidsv1.5.0": "desc-ICAMIRDenoised_mixing" + "bidsv1.5.0": "desc-ICAMIRDenoised_mixing", + "bidsv1.6.0": "desc-ICAMIRDenoised_mixing" }, "ICA orthogonalized mixing tsv": { "orig": "ica_orth_mixing", - "bidsv1.5.0": "desc-ICAOrth_mixing" + "bidsv1.5.0": "desc-ICAOrth_mixing", + "bidsv1.6.0": "desc-ICAOrth_mixing" } } diff --git a/tedana/workflows/tedana.py b/tedana/workflows/tedana.py index cc9079d62..eb1cdb944 100644 --- a/tedana/workflows/tedana.py +++ b/tedana/workflows/tedana.py @@ -107,8 +107,15 @@ def _get_parser(): "--convention", dest="convention", action="store", - choices=["orig", "bids"], - help=("Filenaming convention. bids will use the latest BIDS derivatives version."), + choices=["bids", "bidsv1.5.0", "orig"], + help=( + "Filenaming convention. " + "'bids' will use the latest BIDS derivatives version. " + "'bidsv1.5.0' will use the BIDS derivatives naming convention applied before tedana " + "version 0.0.12. " + "'orig' will use the non-BIDS-compatible naming convention originally used in the " + "meica.py." + ), default="bids", ) optional.add_argument( @@ -358,6 +365,11 @@ def tedana_workflow( spatially aligned with `data`. If an explicit mask is not provided, then Nilearn's compute_epi_mask function will be used to derive a mask from the first echo's data. + convention : {"bids", "bidsv1.5.0", "orig"}, optional + Filenaming convention. 'bids' will use the latest BIDS derivatives version. + 'bidsv1.5.0' will use the BIDS derivatives naming convention applied before tedana + version 0.0.12. + 'orig' will use the non-BIDS-compatible naming convention originally used in the meica.py. fittype : {'loglin', 'curvefit'}, optional Monoexponential fitting method. 'loglin' uses the the default linear fit to the log of the data. 'curvefit' uses a monoexponential fit to From 9ad7143e6c3390eb050d14a808ad19b9127a3648 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 12:12:57 -0500 Subject: [PATCH 13/21] Improve table. --- docs/outputs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index fb34df7e2..53e5cdd6b 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -23,7 +23,7 @@ T2starmap.nii.gz Full estimated T2* 3D map. **Original name**: t2svG.nii.gz - **Before version 0.0.11**: desc-full_T2starmap.nii.gz + **v0.0.11 - v0.0.11**: desc-full_T2starmap.nii.gz S0map.nii.gz Full S0 3D map. The difference between the limited and full maps is that, for voxels affected by dropout where From a90dcbcd2cf93870e86232272f873da1c5b4ff0d Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 16 Nov 2021 12:57:45 -0500 Subject: [PATCH 14/21] Update outputs.rst --- docs/outputs.rst | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 53e5cdd6b..34f1f3fbe 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -9,9 +9,9 @@ Outputs of tedana Outputs of the tedana workflow ****************************** -================================================ ===================================================== +================================================ ======================================================================= Filename Content -================================================ ===================================================== +================================================ ======================================================================= dataset_description.json Top-level metadata for the workflow. T2starmap.nii.gz Full estimated T2* 3D map. Values are in seconds. @@ -21,23 +21,35 @@ T2starmap.nii.gz Full estimated T2* 3D map. the T2* estimate from the first two echoes, while the limited map has a NaN. - **Original name**: t2svG.nii.gz + **meica.py - v.0.0.10** (``orig``): t2svG.nii.gz - **v0.0.11 - v0.0.11**: desc-full_T2starmap.nii.gz + **v0.0.11 - v0.0.11** (``bidsv1.5.0``): desc-full_T2starmap.nii.gz + + **v0.0.12 -** (``bidsv1.6.0``): T2starmap.nii.gz S0map.nii.gz Full S0 3D map. The difference between the limited and full maps is that, for voxels affected by dropout where only one echo contains good data, the full map uses the S0 estimate from the first two echoes, while the limited map has a NaN. + + **meica.py - v.0.0.10** (``orig``): s0vG.nii.gz + + **v0.0.11 - v0.0.11** (``bidsv1.5.0``): desc-full_S0map.nii.gz + + **v0.0.12 -** (``bidsv1.6.0``): S0map.nii.gz desc-optcom_bold.nii.gz Optimally combined time series. + + **meica.py - v.0.0.10** (``orig``): ts_OC.nii.gz + + **v0.0.11 -** (``bidsv1.5.0``, ``bidsv1.6.0``): desc-optcom_bold.nii.gz desc-denoised_bold.nii.gz Denoised optimally combined time series. Recommended dataset for analysis. desc-adaptiveGoodSignal_mask.nii.gz Integer-valued mask used in the workflow, where each voxel's value corresponds to the number of good echoes to be used for T2\*/S0 estimation. - **Original name**: adaptive_mask.nii.gz + **meica.py - v.0.0.10**: adaptive_mask.nii.gz desc-PCA_mixing.tsv Mixing matrix (component time series) from PCA decomposition in a tab-delimited file. Each column is a different component, and the column name is the From 3d14f7ba3f38bfd64236af18d0d0b85251f97a5b Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 19 Nov 2021 12:45:42 -0500 Subject: [PATCH 15/21] Get MIR carpets working again. --- tedana/reporting/static_figures.py | 33 ++++++++++++++++++++++-------- tedana/workflows/tedana.py | 7 ++----- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/tedana/reporting/static_figures.py b/tedana/reporting/static_figures.py index 65a946a66..921068048 100644 --- a/tedana/reporting/static_figures.py +++ b/tedana/reporting/static_figures.py @@ -6,6 +6,7 @@ import matplotlib import numpy as np +import pandas as pd matplotlib.use("AGG") import matplotlib.pyplot as plt @@ -42,15 +43,21 @@ def _trim_edge_zeros(arr): return arr[bounding_box] -def carpet_plot(optcom_ts, denoised_ts, hikts, lowkts, mask, io_generator, gscontrol=None): +def carpet_plot(optcom_ts, mask, comptable, mixing, io_generator, gscontrol=None): """Generate a set of carpet plots for the combined and denoised data. Parameters ---------- - optcom_ts, denoised_ts, hikts, lowkts : (S x T) array_like - Different types of data to plot. + optcom_ts : (S x T) array_like + Optimally combined data. mask : (S,) array-like Binary mask used to apply to the data. + comptable : (C x X) :obj:`pandas.DataFrame` + Component metric table. One row for each component, with a column for + each metric. The index should be the component number. + mixing : (C x T) array_like + Mixing matrix for converting input data to component space, where `C` + is components and `T` is the same as in `data`. io_generator : :obj:`tedana.io.OutputGenerator` The output generator for this workflow gscontrol : {None, 'mir', 'gsr'} or :obj:`list`, optional @@ -59,11 +66,13 @@ def carpet_plot(optcom_ts, denoised_ts, hikts, lowkts, mask, io_generator, gscon pertinent outputs from those steps. Default is None. """ + denoised_ts, high_kappa_ts, rejected_ts = io.denoise_ts(optcom_ts, mixing, mask, comptable) + mask_img = io.new_nii_like(io_generator.reference_img, mask.astype(int)) optcom_img = io.new_nii_like(io_generator.reference_img, optcom_ts) dn_img = io.new_nii_like(io_generator.reference_img, denoised_ts) - hik_img = io.new_nii_like(io_generator.reference_img, hikts) - lowk_img = io.new_nii_like(io_generator.reference_img, lowkts) + hik_img = io.new_nii_like(io_generator.reference_img, high_kappa_ts) + lowk_img = io.new_nii_like(io_generator.reference_img, rejected_ts) # Carpet plots fig, ax = plt.subplots(figsize=(14, 7)) @@ -124,10 +133,17 @@ def carpet_plot(optcom_ts, denoised_ts, hikts, lowkts, mask, io_generator, gscon fig.savefig(os.path.join(io_generator.out_dir, "figures", "carpet_optcom_nogsr.svg")) if (gscontrol is not None) and ("mir" in gscontrol): - mir_denoised_img = io_generator.get_name("mir denoised img") + mixing_mir_file = io_generator.get_name("ICA MIR mixing tsv") + mixing_mir = pd.read_table(mixing_mir_file, index_col="component").values + denoised_ts_mir, high_kappa_ts_mir, _ = io.denoise_ts( + optcom_ts, mixing_mir, mask, comptable + ) + denoised_img_mir = io.new_nii_like(io_generator.reference_img, denoised_ts_mir) + high_kappa_img_mir = io.new_nii_like(io_generator.reference_img, high_kappa_ts_mir) + fig, ax = plt.subplots(figsize=(14, 7)) plotting.plot_carpet( - mir_denoised_img, + denoised_img_mir, mask_img, figure=fig, axes=ax, @@ -136,10 +152,9 @@ def carpet_plot(optcom_ts, denoised_ts, hikts, lowkts, mask, io_generator, gscon fig.tight_layout() fig.savefig(os.path.join(io_generator.out_dir, "figures", "carpet_denoised_mir.svg")) - mir_denoised_img = io_generator.get_name("ICA accepted mir denoised img") fig, ax = plt.subplots(figsize=(14, 7)) plotting.plot_carpet( - mir_denoised_img, + high_kappa_img_mir, mask_img, figure=fig, axes=ax, diff --git a/tedana/workflows/tedana.py b/tedana/workflows/tedana.py index eb1cdb944..0c99a7f6e 100644 --- a/tedana/workflows/tedana.py +++ b/tedana/workflows/tedana.py @@ -871,14 +871,11 @@ def tedana_workflow( if not no_reports: LGR.info("Making figures folder with static component maps and timecourse plots.") - dn_ts, hikts, lowkts = io.denoise_ts(data_oc, mmix, mask_denoise, comptable) - reporting.static_figures.carpet_plot( optcom_ts=data_oc, - denoised_ts=dn_ts, - hikts=hikts, - lowkts=lowkts, mask=mask_denoise, + comptable=comptable, + mixing=mmix, io_generator=io_generator, gscontrol=gscontrol, ) From aa705ded4d080f1bc84fe8c8488fc7a69de4549d Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 19 Nov 2021 12:50:20 -0500 Subject: [PATCH 16/21] Add text about outputs tables. --- docs/outputs.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/outputs.rst b/docs/outputs.rst index 34f1f3fbe..91c355fa6 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -9,10 +9,20 @@ Outputs of tedana Outputs of the tedana workflow ****************************** +In the following tables, we describe each file that the ``tedana`` workflow will generate, +depending on the settings used. +The base filename does not include a user-provided prefix or output directory. + +.. important:: + Some of the filenames in the following tables may have changed across tedana versions. + In the content column, we have annotated each file with any past filenames and the tedana versions which generated them. + ================================================ ======================================================================= Filename Content ================================================ ======================================================================= dataset_description.json Top-level metadata for the workflow. + + Added in **v0.0.11** T2starmap.nii.gz Full estimated T2* 3D map. Values are in seconds. The difference between the limited and full maps From d2c2643be551fd08971d72a3f564271372391251 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 19 Nov 2021 13:05:39 -0500 Subject: [PATCH 17/21] Fix formatting issues. --- docs/outputs.rst | 2 +- tedana/decomposition/pca.py | 50 +++++++++++++++---------------------- tedana/io.py | 2 +- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 91c355fa6..3885070e5 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -94,7 +94,7 @@ desc-tedana_metrics.json Metadata about the metrics i report.txt A summary report for the workflow with relevant citations. tedana_report.html The interactive HTML report. -================================================ ===================================================== +================================================ ======================================================================= If ``verbose`` is set to True: diff --git a/tedana/decomposition/pca.py b/tedana/decomposition/pca.py index 8cc2efe55..6d431d0f1 100644 --- a/tedana/decomposition/pca.py +++ b/tedana/decomposition/pca.py @@ -119,62 +119,52 @@ def tedpca( Notes ----- - ====================== ================================================= + ====================== =================================================================== Notation Meaning - ====================== ================================================= - :math:`\\kappa` Component pseudo-F statistic for TE-dependent - (BOLD) model. - :math:`\\rho` Component pseudo-F statistic for TE-independent - (artifact) model. + ====================== =================================================================== + :math:`\\kappa` Component pseudo-F statistic for TE-dependent (BOLD) model. + :math:`\\rho` Component pseudo-F statistic for TE-independent (artifact) model. :math:`v` Voxel :math:`V` Total number of voxels in mask :math:`\\zeta` Something :math:`c` Component :math:`p` Something else - ====================== ================================================= + ====================== =================================================================== Steps: - 1. Variance normalize either multi-echo or optimally combined data, - depending on settings. + 1. Variance normalize either multi-echo or optimally combined data, depending on settings. 2. Decompose normalized data using PCA or SVD. - 3. Compute :math:`{\\kappa}` and :math:`{\\rho}`: + 3. Compute :math:`{\\kappa}` and :math:`{\\rho}`. - .. math:: - {\\kappa}_c = \\frac{\\sum_{v}^V {\\zeta}_{c,v}^p * \ - F_{c,v,R_2^*}}{\\sum {\\zeta}_{c,v}^p} + .. math:: + {\\kappa}_c = \\frac{\\sum_{v}^V {\\zeta}_{c,v}^p * \ + F_{c,v,R_2^*}}{\\sum {\\zeta}_{c,v}^p} - {\\rho}_c = \\frac{\\sum_{v}^V {\\zeta}_{c,v}^p * \ - F_{c,v,S_0}}{\\sum {\\zeta}_{c,v}^p} + {\\rho}_c = \\frac{\\sum_{v}^V {\\zeta}_{c,v}^p * \ + F_{c,v,S_0}}{\\sum {\\zeta}_{c,v}^p} 4. Some other stuff. Something about elbows. - 5. Classify components as thermal noise if they meet both of the - following criteria: + 5. Classify components as thermal noise if they meet both of the following criteria. - Nonsignificant :math:`{\\kappa}` and :math:`{\\rho}`. - Nonsignificant variance explained. - Outputs: - This function writes out several files: - =========================== ============================================= + + =========================== ====================================================== Default Filename Content - =========================== ============================================= + =========================== ====================================================== desc-PCA_metrics.tsv PCA component table - desc-PCA_metrics.json Metadata sidecar file describing the - component table + desc-PCA_metrics.json Metadata sidecar file describing the component table desc-PCA_mixing.tsv PCA mixing matrix desc-PCA_components.nii.gz Component weight maps - desc-PCA_decomposition.json Metadata sidecar file describing the PCA - decomposition - =========================== ============================================= + desc-PCA_decomposition.json Metadata sidecar file describing the PCA decomposition + =========================== ====================================================== See Also -------- - :func:`tedana.utils.make_adaptive_mask` : The function used to create - the ``adaptive_mask` parameter. - :py:mod:`tedana.constants` : The module describing the filenames for - various naming conventions + :func:`tedana.utils.make_adaptive_mask` : The function used to create the ``adaptive_mask``. """ if algorithm == "kundu": alg_str = "followed by the Kundu component selection decision tree (Kundu et al., 2013)" diff --git a/tedana/io.py b/tedana/io.py index 62ad37dff..d1e3b689f 100644 --- a/tedana/io.py +++ b/tedana/io.py @@ -457,7 +457,7 @@ def writeresults(ts, mask, comptable, mmix, io_generator): ========================================= ===================================== Filename Content ========================================= ===================================== - desc-denoised_bold.nii.gz Denoised time series. + desc-denoised_bold.nii.gz Denoised time series. desc-ICA_components.nii.gz Spatial component maps for all components. ========================================= ===================================== From 8e07e4da4b8b437e306317271ed0790a74d17b60 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 19 Nov 2021 13:06:56 -0500 Subject: [PATCH 18/21] No index_col. --- tedana/reporting/static_figures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tedana/reporting/static_figures.py b/tedana/reporting/static_figures.py index 921068048..4bed21add 100644 --- a/tedana/reporting/static_figures.py +++ b/tedana/reporting/static_figures.py @@ -134,7 +134,7 @@ def carpet_plot(optcom_ts, mask, comptable, mixing, io_generator, gscontrol=None if (gscontrol is not None) and ("mir" in gscontrol): mixing_mir_file = io_generator.get_name("ICA MIR mixing tsv") - mixing_mir = pd.read_table(mixing_mir_file, index_col="component").values + mixing_mir = pd.read_table(mixing_mir_file).values denoised_ts_mir, high_kappa_ts_mir, _ = io.denoise_ts( optcom_ts, mixing_mir, mask, comptable ) From 1849a26a7f26fce7a072939f5b4e93ab5c6be3a7 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Thu, 2 Dec 2021 12:58:29 -0500 Subject: [PATCH 19/21] Add note for https://github.com/ME-ICA/tedana/issues/146#issuecomment-982676687. --- docs/outputs.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 3885070e5..8916ce1c0 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -4,6 +4,7 @@ Outputs of tedana ################# +On this page, we describe the files that may be generated by ``tedana`` workflows, depending on the settings used. ****************************** Outputs of the tedana workflow @@ -11,7 +12,10 @@ Outputs of the tedana workflow In the following tables, we describe each file that the ``tedana`` workflow will generate, depending on the settings used. -The base filename does not include a user-provided prefix or output directory. + +.. warning:: + The base filename does not include a user-provided prefix or output directory. + If you run ``tedana`` multiple times without varying the prefix or output directory, you will overwrite files from previous runs. .. important:: Some of the filenames in the following tables may have changed across tedana versions. From 6d6abce746cdb6c85f3672557971fabb7f15b342 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Thu, 15 Jun 2023 12:25:01 -0400 Subject: [PATCH 20/21] Update. --- docs/outputs.rst | 12 +----------- tedana/resources/config/outputs.json | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/outputs.rst b/docs/outputs.rst index 5a1803860..9814b2b6c 100644 --- a/docs/outputs.rst +++ b/docs/outputs.rst @@ -107,14 +107,8 @@ tedana_report.html The status of each component after each node was run. Columns are only added for runs where component statuses can change. -"ICA accepted components img": desc-ICAAccepted_components.nii.gz High-kappa ICA coefficient feature set -"z-scored ICA accepted components img": desc-ICAAcceptedZ_components.nii.gz Z-normalized spatial component maps report.txt A summary report for the workflow with relevant citations. -"low kappa ts img": desc-optcomRejected_bold.nii.gz Combined time series from rejected components. -"high kappa ts img": desc-optcomAccepted_bold.nii.gz High-kappa time series. This dataset does not - include thermal noise or low variance components. - Not the recommended dataset for analysis. references.bib The BibTeX entries for references cited in report.txt. @@ -133,7 +127,7 @@ Key: Filename "limited s0 img": desc-limited_S0map.nii.gz Limited S0 map/time series. Unlike the full S0 maps, if only one 1 echo contains good data the limited map will have NaN -"whitened img": desc-optcom_whitened_bold The optimally combined data after whitening +"whitened img": desc-optcomWhitened_bold The optimally combined data after whitening "echo weight [PCA|ICA] maps split img": echo-[echo]_desc-[PCA|ICA]_components.nii.gz Echo-wise PCA/ICA component weight maps. "echo T2 [PCA|ICA] split img": echo-[echo]_desc-[PCA|ICA]T2ModelPredictions_components.nii.gz Component- and voxel-wise R2-model predictions, separated by echo. @@ -145,8 +139,6 @@ Key: Filename "[PCA|ICA] component F-T2 img": desc-[PCA|ICA]T2_stat-F_statmap.nii.gz F-statistic map for each component, for the T2 model. "PCA reduced img": desc-optcomPCAReduced_bold.nii.gz Optimally combined data after dimensionality reduction with PCA. This is the input to the ICA. -"high kappa ts split img": echo-[echo]_desc-Accepted_bold.nii.gz High-Kappa time series for echo number ``echo`` -"low kappa ts split img": echo-[echo]_desc-Rejected_bold.nii.gz Low-Kappa time series for echo number ``echo`` "denoised ts split img": echo-[echo]_desc-Denoised_bold.nii.gz Denoised time series for echo number ``echo`` ============================================================================================= ===================================================== @@ -187,8 +179,6 @@ Key: Filename "t1 like img": desc-T1likeEffect_min.nii.gz T1-like effect "mir denoised img": desc-optcomMIRDenoised_bold.nii.gz Denoised time series after MIR "ICA MIR mixing tsv": desc-ICAMIRDenoised_mixing.tsv ICA mixing matrix after MIR -"ICA accepted mir component weights img": desc-ICAAcceptedMIRDenoised_components.nii.gz high-kappa components after MIR -"ICA accepted mir denoised img": desc-optcomAcceptedMIRDenoised_bold.nii.gz high-kappa time series after MIR ======================================================================================= ===================================================== .. _classification-output-descriptions: diff --git a/tedana/resources/config/outputs.json b/tedana/resources/config/outputs.json index 2766380ec..f542b2811 100644 --- a/tedana/resources/config/outputs.json +++ b/tedana/resources/config/outputs.json @@ -51,8 +51,8 @@ }, "whitened img": { "orig": "ts_OC_whitened", - "bidsv1.5.0": "desc-optcomPCAReduced_bold", - "bidsv1.6.0": "desc-optcomPCAReduced_bold" + "bidsv1.5.0": "desc-optcomWhitened_bold", + "bidsv1.6.0": "desc-optcomWhitened_bold" }, "echo weight PCA map split img": { "orig": "e{echo}_PCA_comp", From d57a728b402393590f5eefb289679b6b2bd35b4d Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Thu, 15 Jun 2023 12:26:56 -0400 Subject: [PATCH 21/21] Update io.py --- tedana/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tedana/io.py b/tedana/io.py index e2fc97118..306a1b186 100644 --- a/tedana/io.py +++ b/tedana/io.py @@ -498,7 +498,7 @@ def denoise_ts(data, mmix, mask, comptable): # get variance explained by retained components betas = get_coeffs(dmdata.T, mmix, mask=None) - varexpl = (1 - ((dmdata.T - betas.dot(mmix.T)) ** 2.0).sum() / (dmdata ** 2.0).sum()) * 100 + varexpl = (1 - ((dmdata.T - betas.dot(mmix.T)) ** 2.0).sum() / (dmdata**2.0).sum()) * 100 LGR.info(f"Variance explained by decomposition: {varexpl:.02f}%") # create component-based data