|
| 1 | +% Lindquist (under review): You should not sequentially apply high-pass |
| 2 | +% filtering and nuisance regression. Combine them into one step. |
| 3 | +% This is an example of how to do that. |
| 4 | + |
| 5 | +% Use SPM to get a filter |
| 6 | +TR = 2; |
| 7 | +n_timepoints = 300; |
| 8 | +hpf = 128; % 128 is high pass filter length in sec, 1/hz |
| 9 | +[S,KL,KH] = use_spm_filter(TR, n_timepoints,'none','specify',hpf); |
| 10 | + |
| 11 | +% KH is the high-pass filter regressors |
| 12 | + |
| 13 | +% Define functions that get the Smoothing matrix S. |
| 14 | +% --------------------------------------------------- |
| 15 | +get_hat = @(X) X * pinv(X); % |
| 16 | +get_S = @(H) eye(size(H)) - H; |
| 17 | + |
| 18 | +% S is the residual-forming matrix such that SY is Y' where Y' has |
| 19 | +% regressors KH removed. |
| 20 | +% H is the "Hat matrix" that produces fitted responses |
| 21 | +% S is the residual-forming matrix that produces residuals |
| 22 | + |
| 23 | + |
| 24 | +% Use functions to reconstruct S, call it S_prime |
| 25 | +H = get_hat(KH); |
| 26 | +S_prime = get_S(H); |
| 27 | + |
| 28 | +figure; imagesc(S); colorbar |
| 29 | + |
| 30 | +% Sanity check : whether we can reconstruct the matrix S manually, using our |
| 31 | +% functions |
| 32 | +% --------------------------------------------------- |
| 33 | +% Check whether S = S_prime |
| 34 | +% if zero, matrices are identical |
| 35 | +max(abs(S(:) - S_prime(:))) |
| 36 | +isequal(S, S_prime) |
| 37 | + |
| 38 | + |
| 39 | +% Add nuisance covs and re-construct filter matrix S |
| 40 | +% intercept(s) for runs, too. |
| 41 | +% This is what we would use on the real data. |
| 42 | +% --------------------------------------------------- |
| 43 | + |
| 44 | +% N = simulated nuisance covariates, for this example |
| 45 | +% Movement params, spikes, initial images, outliers with high mahal dist |
| 46 | +N = randn(n_timepoints, 6); |
| 47 | + |
| 48 | +% Simulated intercepts, say for example we have 3 runs |
| 49 | +I = intercept_model([n_timepoints/3 n_timepoints/3 n_timepoints/3]); |
| 50 | + |
| 51 | +% construct an overall set of nuisance covs with all the stuff we want to |
| 52 | +% remove. |
| 53 | + |
| 54 | +X = [KH N I]; |
| 55 | + |
| 56 | +H = get_hat(X); |
| 57 | +S_prime = get_S(H); |
| 58 | + |
| 59 | +% Generate a simulated time series and filter it |
| 60 | +% --------------------------------------------------- |
| 61 | + |
| 62 | +y = repmat([ones(15, 1); zeros(15, 1)], 10, 1); % a real signal, simulated |
| 63 | +n = noise_arp(n_timepoints, [.7 .3]); |
| 64 | +intercept_noise = I * randn(3, 1); |
| 65 | +y_obs = y + n + intercept_noise; |
| 66 | +figure; plot(y_obs) |
| 67 | + |
| 68 | +% This does the filtering and nuisance cov removal: |
| 69 | +y_filtered = S_prime * y_obs; |
| 70 | + |
| 71 | +figure; plot(y_filtered); |
| 72 | +hold on; plot(y - .5, 'r', 'Linewidth', 2); |
| 73 | +corr(y, y_filtered) |
| 74 | +corr(y, y_obs) |
0 commit comments