📄 rri_multiblock_perm.m
字号:
%RRI_MULTIBLOCK_PERM Apply Behavioral or Task PLS test and permutation test
% on RRI scan.
%
% See also PLS_PERM_TEST, PLS_DEVIATION_PERM_TEST, BEHAVPLS_PERM, TASKPLS_PERM
%
% I (ismean) - 1 if using grand mean deviation;
% I (ishelmert) - 1 if using helmert matrix;
% I (iscontrast) - 1 if using contrast data;
% I (isbehav) - 1 if using behavior data;
% I (newdata_lst) - A group list of datamat files;
% I (num_cond_lst) - A group list of condition numbers;
% I (num_subj_lst) - A group list of subject numbers;
% I (behavdata_lst) - A group list of behav data with selected columns;
% I (helmertdata_lst) - A group list of helmert matrix with selected columns;
% I (contrastdata_lst) - A group list of contrast data with selected columns;
% contrastdata_lst has been orthchecked in
% erp_get_common function
% I (num_perm) - Number of Permutation;
% I (posthoc) - posthoc data;
%
% O (brainlv) - Left singular value vector. It is LV for the brain dimension.
% O (s) - Singular values vector.
% O (behavlv) - Right singular vector. It is LV for the behavior OR contrast
% dimension for each scan.
% O (brainscores) - The brain score.
% O (behavscores) - If use GRAND_MEAN method, behavscores = behavlv, then
% expand each condition for all the subjects. If not, it is
% calculated for each set of condition, then stack together.
% O (lvcorrs) - Correlates brain scores with behavior data for multiple scans,
% return [] if for Task PLS or if use GRAND_MEAN method.
% O (origpost) - posthoc result.
% O (perm_result) - A Structure array containing the permutation result data.
%
% Created on 03-OCT-2002 by Jimmy Shen for PLS test
% Modified on 24-OCT-2002 by Jimmy Shen to add permutation test
% Modified Jan 10,03 to add contrast & helmert
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [brainlv,s,designlv,behavlv,brainscores,designscores,behavscores, ...
lvcorrs, origpost, perm_result, datamatcorrs_lst, b_scores, ...
behav_row_idx, behavdata_lst] = ...
rri_multiblock_perm(ismean, ishelmert, iscontrast, isbehav, ...
newdata_lst,num_cond_lst,num_subj_lst, ...
behavdata_lst, helmertdata_lst, contrastdata_lst, ...
num_perm, posthoc, bscan);
% Init
%
brainlv = [];
s = [];
designlv = [];
behavlv = [];
brainscores = [];
designscores = [];
behavscores = [];
lvcorrs = [];
origpost = [];
b_scores = [];
datamatcorrs_lst = {};
stacked_behavdata = [];
stacked_helmertdata = [];
stacked_contrastdata = [];
stacked_TBdatamatcorrs = [];
stacked_datamatcorrs = [];
stacked_datamat = [];
stacked_mask = [];
perm_result = [];
num_groups = length(newdata_lst);
progress_hdl = rri_progress_ui('initialize');
msg = 'Working on PLS ...';
rri_progress_ui(progress_hdl, '', msg);
k = num_cond_lst(1);
kk = length(bscan);
row_idx = [];
% loop accross the groups, and
% calculate datamatcorrs for each group
%
for i = 1:num_groups
n = num_subj_lst(i);
datamat = newdata_lst{i};
rri_progress_ui(progress_hdl,'',2/10+5/10*(i-1)/(num_groups)+1/(10*num_groups));
% compute task mean
%
Tdatamatcorrs = rri_task_mean(datamat,n)-ones(k,1)*mean(datamat);
% compute correlation or covariance
%
Bdatamatcorrs = rri_corr_maps_notall(behavdata_lst{i}, datamat, n, bscan);
datamatcorrs_lst = [datamatcorrs_lst, {Bdatamatcorrs}];
rri_progress_ui(progress_hdl,'',2/10+5/10*(i-1)/(num_groups)+3/(10*num_groups));
% stack task and behavior - keep un-normalize data that will be
% used to recover the normalized one
%
TBdatamatcorrs = [Tdatamatcorrs; Bdatamatcorrs];
% stack task and behavior - normalize to unit length to reduce
% scaling difference
%
datamatcorrs = [normalize(Tdatamatcorrs,2); normalize(Bdatamatcorrs,2)];
stacked_TBdatamatcorrs = [stacked_TBdatamatcorrs; TBdatamatcorrs];
stacked_behavdata = [stacked_behavdata; behavdata_lst{i}];
stacked_datamat = [stacked_datamat; datamat];
stacked_datamatcorrs = [stacked_datamatcorrs; datamatcorrs];
tmp_row_idx = reshape(1:size(stacked_behavdata,2)*k, [size(stacked_behavdata,2) k]);
tmp_row_idx = tmp_row_idx(:,bscan);
row_idx = [row_idx tmp_row_idx(:)+size(stacked_behavdata,2)*k*(i-1)];
rri_progress_ui(progress_hdl,'',2/10+5/10*(i-1)/(num_groups)+5/(10*num_groups));
end % for
if ~isempty(posthoc)
row_idx = row_idx(:);
posthoc = posthoc(row_idx,:);
end
% actually, all the groups must have the same condition number
%
num_cond = num_cond_lst(1);
% Singular Value Decomposition
%
[r c] = size(stacked_datamatcorrs);
if r <= c
% transpose datamatcorrs to ensure SVD operation will be
% on smallest of RxC dimension
%
[brainlv,s,v] = svd(stacked_datamatcorrs',0);
else
[v,s,brainlv] = svd(stacked_datamatcorrs,0);
end
s = diag(s);
original_v = v * diag(s);
rri_progress_ui(progress_hdl,'',9/10);
% Since the 2 matrices that went into the SVD were unit normal, we should
% go backwards from the total Singular value Sum of Squares (SSQ)
% Calculate total SSQ
%
total_s = sum(stacked_TBdatamatcorrs(:).^2);
% Calculate distribution of normalized SSQ across LVs
%
per = s.^2 / sum(s.^2);
% Re-calculate singular value based on the distribution of SSQ
% across normalized LVs
%
org_s = sqrt(per * total_s);
% Re-scale v (block LV) with singular value
%
org_v = v * diag(org_s);
% Separate v into 2 parts: designlv and behavlv
%
designlv = [];
behavlv = [];
for g = 1:num_groups
t = size(stacked_behavdata, 2);
designlv = [designlv; v((g-1)*k+(g-1)*kk*t+1 : (g-1)*k+(g-1)*kk*t+k,:)];
behavlv = [behavlv; v((g-1)*k+(g-1)*kk*t+k+1 : (g-1)*k+(g-1)*kk*t+k+kk*t,:)];
end
num_col = size(designlv, 2);
% expand the num_subj for each row (cond)
% did the samething as testvec
%
designscores = [];
row_idx = [];
last = 0;
for g = 1:num_groups
n = num_subj_lst(g);
tmp = reshape(designlv((g-1)*k+1:(g-1)*k+k,:),[1, num_col*k]);
tmp = repmat(tmp, [n, 1]); % expand to num_subj
tmp = reshape(tmp, [n*k, num_col]);
designscores = [designscores; tmp]; % stack by groups
% take this advantage (having g & n) to get row_idx
%
tmp = 1:n*k;
tmp = reshape(tmp, [n k]);
tmp = tmp(:, bscan);
behavdata_lst{g} = behavdata_lst{g}(tmp(:),:);
row_idx = [row_idx ; tmp(:) + last];
last = last + n*k;
end
behav_row_idx = row_idx;
% calculate behav scores
%
b_scores = stacked_datamat * brainlv;
behav = stacked_behavdata;
[brainscores, behavscores, lvcorrs] = ...
rri_get_behavscores(stacked_datamat(row_idx,:), ...
stacked_behavdata(row_idx,:), ...
brainlv, behavlv, kk, num_subj_lst);
% lvcorrs = original_v;
if ~isempty(posthoc)
origpost = rri_xcor(posthoc,behavlv);
porigpost = zeros(size(origpost));
else
origpost = [];
end
rri_progress_ui(progress_hdl,'',1);
% Begin permutation loop
%
sp = zeros(size(s));
dp = zeros(size(v));
Treorder = rri_perm_order(num_subj_lst, k, num_perm);
rand('state',sum(100*clock));
for p = 1:num_perm
Breorder(:,p) = [randperm(size(stacked_datamat,1))'];
end
for p = 1:num_perm
msg = ['Working on Permutation: ',num2str(p),' out of ',num2str(num_perm)];
rri_progress_ui(progress_hdl, '', msg);
rri_progress_ui(progress_hdl,'',p/num_perm);
data_p = stacked_datamat(Treorder(:,p),:);
behav_p = stacked_behavdata(Breorder(:,p),:);
stacked_TBdata = [];
stacked_data = [];
for g=1:num_groups
k = num_cond_lst(g);
n = num_subj_lst(g);
span = sum(num_subj_lst(1:g-1)) * num_cond;
if num_groups == 1
Tdata = rri_task_mean(data_p,n)-ones(k,1)*mean(data_p);
else
Tdata = rri_task_mean(data_p(1+span:n*k+span,:),n)-ones(k,1)*mean(data_p(1+span:n*k+span,:));
end
if 1
% Check for upcoming NaN and re-sample if necessary.
% this only happened on behavior analysis, because the
% 'xcor' inside of 'rri_corr_maps' contains a 'stdev', which
% is a divident. If it is 0, it will cause divided by 0
% problem.
% since this happend very rarely, so the speed will not
% be affected that much.
%
min1 = min(std(behav_p(1+span:n*k+span,:)));
while (min1 == 0)
Breorder(:,p) = [randperm(size(stacked_datamat,1))'];
behav_p = stacked_behavdata(Breorder(:,p),:);
min1 = min(std(behav_p(1+span:n*k+span,:)));
count = count + 1;
if count > 100
msg = 'Please check your behavior data, and make ';
msg = [msg 'sure none of the columns are all the '];
msg = [msg 'same for each group'];
uiwait(msgbox(msg, 'Program can not proceed', 'modal'));
brainlv = [];
return;
end
end
% Notice here that stacked_datamat is used, instead of
% boot_p. This is only for behavpls_perm.
%
if num_groups == 1
Bdata = rri_corr_maps_notall(behav_p, stacked_datamat, n, bscan);
else
Bdata = rri_corr_maps_notall(behav_p(1+span:n*k+span,:), ...
stacked_datamat(1+span:n*k+span,:), n, bscan);
end
end
TBdata = [Tdata; Bdata];
data = [normalize(Tdata,2); normalize(Bdata,2)];
stacked_TBdata = [stacked_TBdata; TBdata];
stacked_data = [stacked_data; data];
end % for num_groups
% Singular Value Decomposition
%
[r c] = size(stacked_data);
if r <= c
% transpose datamatcorrs to ensure SVD operation will be
% on smallest of RxC dimension
%
[pbrainlv, sperm, pv] = svd(stacked_data',0);
else
[pv, sperm, pbrainlv] = svd(stacked_data,0);
end
rotatemat = rri_bootprocrust(v,pv);
pv = pv * sperm * rotatemat;
sperm = sqrt(sum(pv.^2));
ptotal_s = sum(stacked_TBdata(:).^2);
per = diag(sperm).^2 / sum(diag(sperm).^2);
sperm = sqrt(per * ptotal_s);
pv = normalize(pv) * diag(sperm);
sp = sp + (sperm>=org_s);
dp = dp + (abs(pv) >= abs(org_v));
Bpv = [];
for g = 1:num_groups
t = size(stacked_behavdata, 2);
Bpv = [Bpv; pv((g-1)*k+(g-1)*kk*t+k+1 : (g-1)*k+(g-1)*kk*t+k+kk*t,:)];
end
if ~isempty(posthoc)
tmp = rri_xcor(posthoc, Bpv);
porigpost = porigpost + (abs(tmp) >= abs(origpost));
end
end % for num_perm
if num_perm ~= 0
perm_result.sprob = sp ./ (num_perm + 1);
% perm_result.dprob = dp ./ num_perm;
perm_result.vprob = dp ./ (num_perm + 1);
perm_result.num_perm = num_perm;
perm_result.Tpermsamp = Treorder;
perm_result.Bpermsamp = Breorder;
perm_result.sp = sp;
% perm_result.dp = dp;
if ~isempty(posthoc)
perm_result.posthoc_prob = porigpost / num_perm;
end
end
return; % rri_multiblock_perm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% load_contrast_file: turn the contrast file into a contrast matrix,
% which is used for behavdata or design data.
%
% I (contrast_file) - filespec of the contrast file
% I (num_subj) - number of subjects in each condition
% O (contrasts) - contrast matrix
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function contrasts = load_contrast_file(contrast_file, num_subj)
load(contrast_file);
num_contrasts = length(pls_contrasts);
num_conditions = length(pls_contrasts(1).value);
contrasts = zeros(num_conditions,num_contrasts);
for i=1:num_contrasts
contrasts(:,i) = pls_contrasts(i).value';
end
% expand each row of condition for all the subjects
%
tmp = contrasts(:)';
tmp = repmat(tmp,num_subj,1);
contrasts = reshape(tmp, num_subj*num_conditions, num_contrasts);
return; % load_contrast_file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -