Skip to content

Commit 432838a

Browse files
committed
add tnsr and util detrend functions
1 parent 08ac263 commit 432838a

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
function stats = fmrwhy_qc_calculate_tSNR(bids_dir, sub, functional_fn, options)
2+
% function stats = fmrwhy_qc_calculate_tSNR(bids_dir, sub, ses, task, run)
3+
% Function to calculate temporal SNR from single run of (masked) fMRI timeseries data
4+
5+
% First access and reshape the functional data: 4D to 2D
6+
nii = nii_tool('load', functional_fn);
7+
data_4D = double(nii.img);
8+
[Ni, Nj, Nk, Nt] = size(data_4D);
9+
data_2D = reshape(data_4D, Ni * Nj * Nk, Nt); % [voxels, time]
10+
data_2D = data_2D'; % [time, voxels]
11+
12+
% Get masks
13+
masks = fmrwhy_util_loadMasks(bids_dir, sub, options);
14+
15+
% Remove linear and quadratic trend per voxel
16+
data_2D_detrended = fmrwhy_util_detrend(data_2D, 2); % [time, voxels]
17+
18+
% Calculate mean
19+
data_2D_mean = nanmean(data_2D_detrended); % [1, voxels]
20+
21+
% Remove mean
22+
data_2D_demeaned = data_2D_detrended - data_2D_mean; % [time, voxels]
23+
24+
% Calculate standard deviation
25+
data_2D_stddev = std(data_2D_detrended); % [1, voxels]
26+
27+
% Calculate Z-statistic
28+
data_2D_zstat = data_2D_demeaned ./ data_2D_stddev;
29+
data_2D_zstat(isnan(data_2D_zstat)) = 0;
30+
data_2D_zstat_ts = nanmean(abs(data_2D_zstat), 2); % perhaps this should only be done within brain mask?
31+
Zstat_mean = nanmean(data_2D_zstat_ts); % perhaps this should only be done within brain mask?
32+
33+
% Calculate variance
34+
% data_2D_var = var(data_2D_detrended);
35+
36+
% Calculate percentage signal change: [I(t) - mean(I)]/mean(I)*100
37+
data_2D_psc = 100 * (data_2D_detrended ./ data_2D_mean) - 100;
38+
data_2D_psc(isnan(data_2D_psc)) = 0;
39+
40+
% Calculate tSNR
41+
tSNR_2D = data_2D_mean ./ data_2D_stddev;
42+
tSNR_mean_brain = nanmean(tSNR_2D(masks.brain_mask_I));
43+
tSNR_mean_GM = nanmean(tSNR_2D(masks.GM_mask_I));
44+
tSNR_mean_WM = nanmean(tSNR_2D(masks.WM_mask_I));
45+
tSNR_mean_CSF = nanmean(tSNR_2D(masks.CSF_mask_I));
46+
47+
% Prepare 3D and 4D images
48+
% data_3D_mean = reshape(data_2D_mean, Ni, Nj, Nk);
49+
% data_3D_var = reshape(data_2D_var, Ni, Nj, Nk);
50+
% data_3D_stddev = reshape(data_2D_stddev, Ni, Nj, Nk);
51+
% tSNR_3D = reshape(tSNR_2D, Ni, Nj, Nk);
52+
53+
data_4D_psc = reshape(data_2D_psc', Ni, Nj, Nk, Nt);
54+
data_4D_detrended = reshape(data_2D_detrended', Ni, Nj, Nk, Nt);
55+
data_4D_demeaned = reshape(data_2D_demeaned', Ni, Nj, Nk, Nt);
56+
57+
stats = struct;
58+
% Single values
59+
stats.tSNR_mean_brain = tSNR_mean_brain;
60+
stats.tSNR_mean_GM = tSNR_mean_GM;
61+
stats.tSNR_mean_WM = tSNR_mean_WM;
62+
stats.tSNR_mean_CSF = tSNR_mean_CSF;
63+
stats.Zstat_mean = Zstat_mean;
64+
% Single parameter timeseries
65+
stats.data_2D_zstat_ts = data_2D_zstat_ts;
66+
% % 3D images
67+
% stats.data_3D_mean = data_3D_mean;
68+
% stats.data_3D_var = data_3D_var;
69+
% stats.data_3D_stddev = data_3D_stddev;
70+
% stats.data_3D_tsnr = tSNR_3D;
71+
% 4D image timeseries
72+
stats.data_4D_psc = data_4D_psc;
73+
stats.data_4D_detrended = data_4D_detrended;
74+
stats.data_4D_demeaned = data_4D_demeaned;
75+
76+
%% Display metrics in command window
77+
% disp(['Mean Zscore: ' num2str(Zstat_mean)])
78+
% disp(['tSNR (brain): ' num2str(tSNR_brain)])
79+
% disp(['tSNR (GM): ' num2str(tSNR_GM)])
80+
% disp(['tSNR (WM): ' num2str(tSNR_WM)])
81+
% disp(['tSNR (CSF): ' num2str(tSNR_CSF)])

demos/tSNR/fmrwhy_util_detrend.m

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function out_data = fmrwhy_util_detrend(data, order)
2+
% Removes linear and/or quadratic trends from timeseries data
3+
%
4+
% INPUT:
5+
% data - R x C matrix; R = rows = time points;
6+
% C = columns = variables/parameters
7+
% order - order (1,2) of regressors in design matrix
8+
% order = 1: linear trend
9+
% order = 2: linear trend + quadratic trend
10+
%
11+
% OUTPUT:
12+
% out_data
13+
% __________________________________________________________________________
14+
% Copyright (C) Stephan Heunis 2018
15+
16+
% Define variables
17+
[r, c] = size(data);
18+
% Create design matrix with model regressors
19+
if order == 1
20+
X = (1:r)';
21+
else
22+
X = [(1:r)' ((1:r)').^2];
23+
end
24+
% Remove mean from design matrix
25+
X = X - repmat(mean(X, 1), r, 1);
26+
% Add constant regressor
27+
X = [ones(r, 1) X];
28+
% Solve system of linear equations
29+
b = pinv(X) * data;
30+
% Detrend data
31+
data = data - X(:, 2:end) * b(2:end, :);
32+
out_data = data;

0 commit comments

Comments
 (0)