Skip to content

Commit 8bdc383

Browse files
committed
extract transparent plotting
1 parent 4f38947 commit 8bdc383

File tree

4 files changed

+156
-133
lines changed

4 files changed

+156
-133
lines changed

demos/MoAE/moae_01_bids_app.m

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,14 @@
119119

120120
VERBOSITY = 3;
121121

122-
bidspm(bids_dir, output_dir, 'subject', ...
123-
'participant_label', {subject_label}, ...
124-
'action', 'preprocess', ...
125-
'task', 'auditory', ...
126-
'ignore', {'unwarp', 'slicetiming'}, ...
127-
'space', {'IXI549Space'}, ...
128-
'fwhm', 6, ...
129-
'verbosity', VERBOSITY);
122+
% bidspm(bids_dir, output_dir, 'subject', ...
123+
% 'participant_label', {subject_label}, ...
124+
% 'action', 'preprocess', ...
125+
% 'task', 'auditory', ...
126+
% 'ignore', {'unwarp', 'slicetiming'}, ...
127+
% 'space', {'IXI549Space'}, ...
128+
% 'fwhm', 6, ...
129+
% 'verbosity', VERBOSITY);
130130

131131
% ## Stats
132132

@@ -164,7 +164,7 @@
164164

165165
bidspm(bids_dir, output_dir, 'subject', ...
166166
'participant_label', {subject_label}, ...
167-
'action', 'stats', ...
167+
'action', 'results', ...
168168
'preproc_dir', preproc_dir, ...
169169
'model_file', model_file, ...
170170
'space', {'IXI549Space'}, ...

demos/MoAE/moae_03_slice_display.m

Lines changed: 1 addition & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -20,137 +20,14 @@
2020

2121
opt.pipeline.type = 'stats';
2222

23-
opt.dir.raw = fullfile(this_dir, 'inputs', 'raw');
2423
opt.dir.derivatives = fullfile(this_dir, 'outputs', 'derivatives');
2524
opt.dir.preproc = fullfile(opt.dir.derivatives, 'bidspm-preproc');
2625

27-
opt.dir.roi = fullfile(opt.dir.derivatives, 'bidspm-roi');
28-
opt.dir.stats = fullfile(opt.dir.derivatives, 'bidspm-stats');
29-
3026
opt.model.file = fullfile(this_dir, 'models', 'model-MoAE_smdl.json');
3127

3228
opt.subjects = {'01'};
3329

3430
% read the model
3531
opt = checkOptions(opt);
3632

37-
% TODO loop over noce and subjects
38-
39-
overwrite = true;
40-
41-
color_map_folder = fullfile(returnRootDir(), 'lib', 'brain_colours', 'mat_maps');
42-
43-
node = opt.model.bm.Nodes{1};
44-
45-
if any(strcmp(node.Level, {'Run', 'Subject'}))
46-
47-
for iSub = 1:numel(opt.subjects)
48-
49-
subLabel = opt.subjects{iSub};
50-
51-
ffxDir = getFFXdir(subLabel, opt);
52-
load(fullfile(ffxDir, 'SPM.mat'))
53-
54-
for iRes = 1:numel(node.Model.Software.bidspm.Results)
55-
56-
opt.results = node.Model.Software.bidspm.Results{iRes};
57-
58-
if ~isfield(opt.results, 'montage') || ~opt.results.montage.do
59-
continue
60-
end
61-
62-
% set defaults
63-
[opt, ~] = checkMontage(opt, iRes, node, struct([]), subLabel);
64-
opt = checkOptions(opt);
65-
opt.results(iRes).montage = setMontage(opt.results(iRes));
66-
67-
for i_name =1:numel(opt.results.name)
68-
69-
if opt.results(iRes).binary
70-
layers = sd_config_layers('init', {'truecolor', 'dual', 'contour'});
71-
else
72-
layers = sd_config_layers('init', {'truecolor', 'dual'});
73-
end
74-
75-
%% Layer 1: Anatomical map
76-
layers(1) = setFields(layers(1), opt.results(iRes).sdConfig.layers{1}, overwrite);
77-
78-
layers(1).color.file = opt.results(iRes).montage.background{1};
79-
80-
hdr = spm_vol(layers(1).color.file);
81-
[max_val, min_val] = slover('volmaxmin', hdr);
82-
layers(1).color.range = [0 max_val];
83-
84-
%% Layer 2: Dual-coded layer
85-
86-
% - contrast estimates color-coded;
87-
layers(2) = setFields(layers(2), opt.results(iRes).sdConfig.layers{2}, overwrite);
88-
89-
name = opt.results.name{i_name};
90-
tmp = struct('name', name);
91-
contrastNb = getContrastNb(tmp, opt, SPM);
92-
93-
% keep track if this is a t test or F test
94-
stat = SPM.xCon(contrastNb).STAT;
95-
96-
contrastNb = sprintf('%04.0f', contrastNb);
97-
98-
if strcmp(stat, 'T')
99-
colorFile = spm_select('FPList', ffxDir, ['^con_' contrastNb '.nii$']);
100-
else
101-
colorFile = spm_select('FPList', ffxDir, ['^ess_' contrastNb '.nii$']);
102-
end
103-
layers(2).color.file = colorFile;
104-
105-
title = strrep(name, '_', ' ');
106-
layers(2).color.label = [title ' (a.u.)'];
107-
108-
% - statistics opacity-coded
109-
if strcmp(stat, 'T')
110-
opacityFile = spm_select('FPList', ffxDir, ['^spmT_' contrastNb '.nii$']);
111-
112-
layers(2).opacity.label = '| t |';
113-
114-
load(fullfile(color_map_folder, 'diverging_bwr_iso.mat'));
115-
layers(2).color.map = diverging_bwr;
116-
else
117-
opacityFile = spm_select('FPList', ffxDir, ['^spmF_' contrastNb '.nii$']);
118-
119-
layers(2).opacity.label = 'F';
120-
121-
load(fullfile(color_map_folder, '1hot_iso.mat'));
122-
layers(2).color.map = hot;
123-
124-
hdr = spm_vol(opacityFile);
125-
[max_val, min_val] = slover('volmaxmin', hdr);
126-
layers(2).color.range = [0 max_val];
127-
128-
layers(2).opacity.range = [0 5];
129-
end
130-
layers(2).opacity.file = opacityFile;
131-
132-
%% Contour
133-
if opt.results(iRes).binary
134-
layers(3) = setFields(layers(3), opt.results(iRes).sdConfig.layers{3}, overwrite);
135-
contour = spm_select('FPList', ffxDir, ['^sub.*' contrastNb '.*_mask.nii']);
136-
layers(3).color.file = contour;
137-
end
138-
139-
%% Settings
140-
settings = opt.results(iRes).sdConfig.settings;
141-
142-
% we reuse the details for the SPM montage
143-
settings.slice.disp_slices = opt.results(1).montage.slices;
144-
settings.slice.orientation = opt.results(1).montage.orientation;
145-
146-
settings.fig_specs.title = title;
147-
148-
%% Display the layers
149-
[settings, p] = sd_display(layers, settings);
150-
151-
end
152-
153-
end
154-
155-
end
156-
end
33+
transparentMontage(opt)
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
2+
function transparentMontage(opt)
3+
%
4+
% Generate montage with transparent plotting
5+
%
6+
% USAGE::
7+
%
8+
% transparentMontage(opt)
9+
%
10+
%
11+
12+
% (C) Copyright 2025 bidspm developers
13+
14+
overwrite = true;
15+
16+
color_map_folder = fullfile(returnRootDir(), 'lib', 'brain_colours', 'mat_maps');
17+
18+
for i_node = 1:numel(opt.model.bm.Nodes)
19+
20+
node = opt.model.bm.Nodes{i_node};
21+
22+
if any(strcmp(node.Level, {'Run', 'Subject'}))
23+
24+
for iSub = 1:numel(opt.subjects)
25+
26+
subLabel = opt.subjects{iSub};
27+
28+
ffxDir = getFFXdir(subLabel, opt);
29+
load(fullfile(ffxDir, 'SPM.mat'))
30+
31+
for iRes = 1:numel(node.Model.Software.bidspm.Results)
32+
33+
opt.results = node.Model.Software.bidspm.Results{iRes};
34+
35+
if ~isfield(opt.results, 'montage') || ~opt.results.montage.do
36+
continue
37+
end
38+
39+
% set defaults
40+
[opt, ~] = checkMontage(opt, iRes, node, struct([]), subLabel);
41+
opt = checkOptions(opt);
42+
opt.results(iRes).montage = setMontage(opt.results(iRes));
43+
44+
for i_name =1:numel(opt.results.name)
45+
46+
if opt.results(iRes).binary
47+
layers = sd_config_layers('init', {'truecolor', 'dual', 'contour'});
48+
else
49+
layers = sd_config_layers('init', {'truecolor', 'dual'});
50+
end
51+
52+
%% Layer 1: Anatomical map
53+
layers(1) = setFields(layers(1), opt.results(iRes).sdConfig.layers{1}, overwrite);
54+
55+
layers(1).color.file = opt.results(iRes).montage.background{1};
56+
57+
hdr = spm_vol(layers(1).color.file);
58+
[max_val, ~] = slover('volmaxmin', hdr);
59+
layers(1).color.range = [0 max_val];
60+
61+
%% Layer 2: Dual-coded layer
62+
63+
% - contrast estimates color-coded;
64+
layers(2) = setFields(layers(2), opt.results(iRes).sdConfig.layers{2}, overwrite);
65+
66+
name = opt.results.name{i_name};
67+
tmp = struct('name', name);
68+
contrastNb = getContrastNb(tmp, opt, SPM);
69+
70+
% keep track if this is a t test or F test
71+
stat = SPM.xCon(contrastNb).STAT;
72+
73+
contrastNb = sprintf('%04.0f', contrastNb);
74+
75+
if strcmp(stat, 'T')
76+
colorFile = spm_select('FPList', ffxDir, ['^con_' contrastNb '.nii$']);
77+
else
78+
colorFile = spm_select('FPList', ffxDir, ['^ess_' contrastNb '.nii$']);
79+
end
80+
layers(2).color.file = colorFile;
81+
82+
title = strrep(name, '_', ' ');
83+
layers(2).color.label = [title ' (a.u.)'];
84+
85+
% - statistics opacity-coded
86+
if strcmp(stat, 'T')
87+
opacityFile = spm_select('FPList', ffxDir, ['^spmT_' contrastNb '.nii$']);
88+
89+
layers(2).opacity.label = '| t |';
90+
91+
load(fullfile(color_map_folder, 'diverging_bwr_iso.mat')); %#ok<*LOAD>
92+
layers(2).color.map = diverging_bwr;
93+
else
94+
opacityFile = spm_select('FPList', ffxDir, ['^spmF_' contrastNb '.nii$']);
95+
96+
layers(2).opacity.label = 'F';
97+
98+
load(fullfile(color_map_folder, '1hot_iso.mat'));
99+
layers(2).color.map = hot;
100+
101+
hdr = spm_vol(opacityFile);
102+
[max_val, ~] = slover('volmaxmin', hdr);
103+
layers(2).color.range = [0 max_val];
104+
105+
layers(2).opacity.range = [0 5];
106+
end
107+
layers(2).opacity.file = opacityFile;
108+
109+
%% Contour
110+
if opt.results(iRes).binary
111+
layers(3) = setFields(layers(3), opt.results(iRes).sdConfig.layers{3}, overwrite);
112+
contour = spm_select('FPList', ffxDir, ['^sub.*' contrastNb '.*_mask.nii']);
113+
layers(3).color.file = contour;
114+
end
115+
116+
%% Settings
117+
settings = opt.results(iRes).sdConfig.settings;
118+
119+
% we reuse the details for the SPM montage
120+
settings.slice.disp_slices = opt.results(1).montage.slices;
121+
settings.slice.orientation = opt.results(1).montage.orientation;
122+
123+
settings.fig_specs.title = title;
124+
125+
%% Display the layers
126+
[~, ~, h_figure] = sd_display(layers, settings);
127+
128+
outputFile = fullfile(ffxDir, [contrastNb '_' name '.png']);
129+
print(h_figure, outputFile, '-dpng');
130+
close(h_figure)
131+
132+
% TODO
133+
% rename file
134+
135+
136+
end
137+
138+
end
139+
140+
end
141+
end
142+
end
143+
144+
end

src/workflows/stats/bidsResults.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@
271271

272272
cleanUpWorkflow(opt);
273273

274+
transparentMontage(opt)
275+
274276
end
275277

276278
function [opt, listNodeLevels] = keepRequestedNodes(opt, nodeName, analysisLevel)

0 commit comments

Comments
 (0)