Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Remi-Gau committed Jul 29, 2024
1 parent 71ea4d4 commit 5884be4
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/bids_model/getDummyContrastsList.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

case 'run'

dummyContrastsList = node.Model.X;
dummyContrastsList = node.Model.HRF.Variables;

case {'session', 'subject'}

Expand Down
157 changes: 86 additions & 71 deletions tests/tests_stats/subject_level/test_specifyContrasts.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
end

function test_specifyContrasts_bug_854()
% no error when no contrast to build

% GIVEN
subLabel = '01';
Expand All @@ -29,8 +30,8 @@ function test_specifyContrasts_bug_854()
spmMatFile = cellstr(fullfile(ffxDir, 'SPM.mat'));
load(spmMatFile{1}, 'SPM');

% WHEN
contrasts = specifyContrasts(opt.model.bm, SPM);
assertWarning(@()specifyContrasts(opt.model.bm, SPM), ...
'specifyContrasts:noContrast');

end

Expand Down Expand Up @@ -62,6 +63,80 @@ function test_specifyContrasts_bug_815()

end

function test_specifyContrasts_subject_level()

taskName = 'motion';

% GIVEN
DummyContrasts{1} = 'motion';
DummyContrasts{2} = 'static';

Contrasts.Name = 'motion_gt_static';
Contrasts.ConditionList = {'motion', 'static'};
Contrasts.Weights = [1, -1];
Contrasts.Test = 't';

model = BidsModel('init', true);

model.Input.task = taskName;

model.Nodes{1, 1}.DummyContrasts.Contrasts = DummyContrasts;
model.Nodes{1, 1}.Contrasts{1} = Contrasts;
model.Nodes{1, 1}.GroupBy = {'run', 'subject'};
model.Nodes{1, 1}.Model.HRF.Variables = {'motion', 'static'};

model.Nodes{2, 1} = BidsModel.empty_node('subject');
model.Nodes{2, 1}.GroupBy = {'subject', 'contrast'};
model.Nodes{2, 1}.DummyContrasts = struct('Test', 't');
model.Nodes{2, 1} = rmfield(model.Nodes{2}, 'Contrasts');
model.Nodes{2, 1}.Model.X = 1;

SPM.Sess(1).col = [1, 2];
% skip Sess 2 to make sure contrast naming is based on the Sess number
SPM.Sess(3).col = [3, 4];
SPM.Sess(4).col = [5, 6];

SPM.xX.name = { ...
' motion*bf(1)'
' static*bf(1)'
' motion*bf(1)'
' static*bf(1)'
' motion*bf(1)'
' static*bf(1)'
};

SPM.xX.X = ones(1, numel(SPM.xX.name));

% WHEN
contrasts = specifyContrasts(model, SPM);

% THEN
names_contrast = { ...
'motion_1', [1 0 0 0 0 0]
'motion_3', [0 0 1 0 0 0]
'motion_4', [0 0 0 0 1 0]
'static_1', [0 1 0 0 0 0]
'static_3', [0 0 0 1 0 0]
'static_4', [0 0 0 0 0 1]
'motion_gt_static_1', [1 -1 0 0 0 0]
'motion_gt_static_3', [0 0 1 -1 0 0]
'motion_gt_static_4', [0 0 0 0 1 -1]
'motion', [1 0 1 0 1 0]
'static', [0 1 0 1 0 1]
'motion_gt_static', [1 -1 1 -1 1 -1]
};

assertEqual(numel(contrasts), size(names_contrast, 1));

for i = 1:size(names_contrast, 1)
expected(i).name = names_contrast{i, 1};
expected(i).C = names_contrast{i, 2};
expected(i).type = 't';
assertEqual(contrasts(i), expected(i));
end

end

function test_specifyContrasts_subject_level_select_node()

taskName = 'motion';
Expand Down Expand Up @@ -132,6 +207,7 @@ function test_specifyContrasts_run_level_dummy_contrast_from_X()
model.Input.task = taskName;
model.Nodes = [];
model.Nodes{1}.Model.X = {'motion', 'static'};
model.Nodes{1}.Model.HRF.Variables = {'motion', 'static'};
model.Nodes{1}.Name = 'run_level';
model.Nodes{1}.Level = 'Run';
model.Nodes{1}.DummyContrasts = struct('Test', 't');
Expand Down Expand Up @@ -188,8 +264,12 @@ function test_specifyContrasts_missing_condition_for_dummy_contrasts()
model.Input.task = taskName;
model.Nodes = [];
model.Nodes{1}.Level = 'Run';
model.Nodes{1}.Name = 'Run';
model.Nodes{1}.GroupBy = {'run', 'subject'};
model.Nodes{1}.DummyContrasts.Contrasts = DummyContrasts;
model.Nodes{1}.DummyContrasts.Test = 't';
model.Nodes{1}.Model = struct('X', {{'foo', 'bar'}}, ...
'HRF', struct('Variables', {{'foo', 'bar'}}));

SPM.Sess(1).col = [1, 2];

Expand Down Expand Up @@ -247,75 +327,6 @@ function test_specifyContrasts_missing_condition()

end

function test_specifyContrasts_subject_level()

taskName = 'motion';

% GIVEN
DummyContrasts{1} = 'motion';
DummyContrasts{2} = 'static';

Contrasts.Name = 'motion_gt_static';
Contrasts.ConditionList = {'motion', 'static'};
Contrasts.Weights = [1, -1];
Contrasts.Test = 't';

model = BidsModel('init', true);
model.Nodes{2, 1} = BidsModel.empty_node('subject');
model.Input.task = taskName;
model.Nodes{1, 1}.DummyContrasts.Contrasts = DummyContrasts;
model.Nodes{1, 1}.Contrasts{1} = Contrasts;
model.Nodes{2, 1}.GroupBy = {'subject', 'contrast'};
model.Nodes{2, 1}.DummyContrasts = struct('Test', 't');
model.Nodes{2, 1} = rmfield(model.Nodes{2}, 'Contrasts');
model.Nodes{2, 1}.Model.X = 1;

SPM.Sess(1).col = [1, 2];
% skip Sess 2 to make sure contrast naming is based on the Sess number
SPM.Sess(3).col = [3, 4];
SPM.Sess(4).col = [5, 6];

SPM.xX.name = { ...
' motion*bf(1)'
' static*bf(1)'
' motion*bf(1)'
' static*bf(1)'
' motion*bf(1)'
' static*bf(1)'
};

SPM.xX.X = ones(1, numel(SPM.xX.name));

% WHEN
contrasts = specifyContrasts(model, SPM);

% THEN
names_contrast = { ...
'motion_1', [1 0 0 0 0 0]
'motion_3', [0 0 1 0 0 0]
'motion_4', [0 0 0 0 1 0]
'static_1', [0 1 0 0 0 0]
'static_3', [0 0 0 1 0 0]
'static_4', [0 0 0 0 0 1]
'motion_gt_static_1', [1 -1 0 0 0 0]
'motion_gt_static_3', [0 0 1 -1 0 0]
'motion_gt_static_4', [0 0 0 0 1 -1]
'motion', [1 0 1 0 1 0]
'static', [0 1 0 1 0 1]
'motion_gt_static', [1 -1 1 -1 1 -1]
};

assertEqual(numel(contrasts), size(names_contrast, 1));

for i = 1:size(names_contrast, 1)
expected(i).name = names_contrast{i, 1};
expected(i).C = names_contrast{i, 2};
expected(i).type = 't';
assertEqual(contrasts(i), expected(i));
end

end

function test_specifyContrasts_complex()
%
% to test the generation of contrasts when there are several runs
Expand All @@ -338,6 +349,10 @@ function test_specifyContrasts_complex()
model.Nodes{1}.DummyContrasts.Contrasts = DummyContrasts;
model.Nodes{1}.Contrasts{1} = Contrasts;
model.Nodes{1}.Level = 'Run';
model.Nodes{1}.Name = 'Run';
model.Nodes{1}.Model = struct('X', {{'motion', 'static'}}, ...
'HRF', struct('Variables', {{'motion', 'static'}}));
model.Nodes{1}.GroupBy = {'run', 'subject'};

SPM.Sess(1).col = [1, 2];
% skip Sess 2 to make sure contrast naming is based on the Sess number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,6 @@ function test_specifyDummyContrasts_subselect_contrasts()

contrasts = specifyDummyContrasts(model, node, contrasts, counter);

assertEqual(numel({contrasts.name}), 8);
assertEqual(numel({contrasts.name}), 20);

end
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ function test_specifyDummyContrasts_session()
model.SPM = SPM;

model.Nodes{1}.DummyContrasts.Contrasts{1} = 'sign_Stim1F';
model.Nodes{1}.GroupBy = {'run', 'subject'};
model.Nodes{1}.Model.X = {'sign_Stim1F', 'sign_Stim2F', 'no_resp'};
model.Nodes{1}.Model.HRF.Variables = {'sign_Stim1F', 'sign_Stim2F', 'no_resp'};

model.Nodes{2, 1} = model.Nodes{1};
model.Nodes{end}.Name = 'Session';
Expand All @@ -71,7 +74,7 @@ function test_specifyDummyContrasts_session()
contrasts = struct('C', [], 'name', []);
counter = 0;
contrasts = specifyDummyContrasts(model, node, contrasts, counter);
assertEqual(numel({contrasts.name}), 5);
assertEqual(numel({contrasts.name}), 11);

node = model.Nodes{2};
contrasts = struct('C', [], 'name', []);
Expand Down

0 comments on commit 5884be4

Please sign in to comment.