Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tedana/decomposition/ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def r_ica(data, n_components, fixed_seed, n_robust_runs, max_it):
robust_ica = RobustICA(
n_components=n_components,
robust_runs=n_robust_runs,
whiten="arbitrary-variance",
whiten="unit-variance",
max_iter=max_it,
random_state=fixed_seed,
robust_dimreduce=False,
Expand Down Expand Up @@ -320,6 +320,7 @@ def f_ica(data, n_components, fixed_seed, maxit, maxrestart):
n_components=n_components,
algorithm="parallel",
fun="logcosh",
whiten="unit-variance",
max_iter=maxit,
random_state=fixed_seed,
)
Expand Down
22 changes: 18 additions & 4 deletions tedana/decomposition/pca.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def tedpca(
kdaw=10.0,
rdaw=1.0,
low_mem=False,
mean_center_only=False,
):
r"""Use principal components analysis (PCA) to identify and remove thermal noise from data.

Expand Down Expand Up @@ -104,6 +105,9 @@ def tedpca(
Whether to use incremental PCA (for low-memory systems) or not.
This is only compatible with the "kundu" or "kundu-stabilize" algorithms.
Default: False
mean_center_only : :obj:`bool`, optional
Only center the mean time series to 0 instead of also scaling the variance
Default: False

Returns
-------
Expand Down Expand Up @@ -210,8 +214,13 @@ def tedpca(
)
data = data_optcom[mask, :]

data_z = ((data.T - data.T.mean(axis=0)) / data.T.std(axis=0)).T # var normalize ts
data_z = (data_z - data_z.mean()) / data_z.std() # var normalize everything
if mean_center_only:
LGR.info("Mean centering data before PCA")
data_z = data - data.mean(axis=1, keepdims=True) # mean normalize ts
else:
LGR.info("Z scaling data before PCA")
data_z = ((data.T - data.T.mean(axis=0)) / data.T.std(axis=0)).T # var normalize ts
data_z = (data_z - data_z.mean()) / data_z.std() # var normalize everything

if algorithm in ["mdl", "aic", "kic"]:
data_img = io.new_nii_like(io_generator.reference_img, utils.unmask(data, mask))
Expand Down Expand Up @@ -450,7 +459,12 @@ def tedpca(
voxel_kept_comp_weighted = voxel_comp_weights[:, acc] * varex[None, acc]
kept_data = np.dot(voxel_kept_comp_weighted, comp_ts[:, acc].T)

kept_data = stats.zscore(kept_data, axis=1) # variance normalize time series
kept_data = stats.zscore(kept_data, axis=None) # variance normalize everything
if mean_center_only:
LGR.info("Mean centering data before ICA")
kept_data = kept_data - np.mean(kept_data, axis=1, keepdims=True)
else:
LGR.info("Z scaling data before ICA")
kept_data = stats.zscore(kept_data, axis=1) # variance normalize time series
kept_data = stats.zscore(kept_data, axis=None) # variance normalize everything

return kept_data, n_components
14 changes: 14 additions & 0 deletions tedana/workflows/tedana.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,15 @@ def _get_parser():
default=None,
)

optional.add_argument(
"--mean_center_only",
"--mean-center-only",
dest="mean_center_only",
action="store_false",
help="Only mean center fMRI time series before PCA and ICA. Do not scale by stdev.",
default=False,
)

optional.add_argument(
"--quiet", dest="quiet", help=argparse.SUPPRESS, action="store_true", default=False
)
Expand Down Expand Up @@ -431,6 +440,7 @@ def tedana_workflow(
t2smap=None,
mixing_file=None,
tedana_command=None,
mean_center_only=False,
):
"""Run the "canonical" TE-Dependent ANAlysis workflow.

Expand Down Expand Up @@ -549,6 +559,9 @@ def tedana_workflow(
mixing_file : :obj:`str` or None, optional
File containing mixing matrix, to be used when re-running the workflow.
If not provided, ME-PCA and ME-ICA are done. Default is None.
mean_center_only : :obj:`bool`, optional
Only center the mean time series to 0 instead of also scaling the variance
Default: False
quiet : :obj:`bool`, optional
If True, suppresses logging/printing of messages. Default is False.
overwrite : :obj:`bool`, optional
Expand Down Expand Up @@ -840,6 +853,7 @@ def tedana_workflow(
kdaw=10.0,
rdaw=1.0,
low_mem=low_mem,
mean_center_only=mean_center_only,
)
if verbose:
io_generator.save_file(utils.unmask(data_reduced, mask_clf), "whitened img")
Expand Down