Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plot figure mask glm #1316

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions miss_hit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ copyright_entity: "Wellcome Trust Centre for Neuroimaging"
tab_width: 2

# metrics limit for the code quality (https://florianschanda.github.io/miss_hit/metrics.html)
metric "cnest": limit 5
metric "cnest": limit 4
metric "file_length": limit 1000
metric "cyc": limit 22
metric "parameters": limit 7
metric "cyc": limit 20
metric "parameters": limit 6
135 changes: 135 additions & 0 deletions src/plotting/createMontage.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
function montage = createMontage(varargin)
%
% USAGE
%
% montage = createMontage(img, ...
% 'columns', 9, ...
% 'rotate', true, ...
% 'cmap', 'gray', ...
% 'visibility', 'on', ...
% 'shape', 'max', ...
% 'cxs', [0 255])
%
%
% Simple function to create a montage /
% mosaic of multiple slices from a single 3D
% image matrix.
%
% INPUT:
% img - 3D (x,y,z) image matrix
% columns - number of columns in montage
% (rows are calculated accordingly)
% rotate - rotate images 90 deg clockwise? yes = 1; no = 0.
% cmap - figure colormap
% visibility - show figure?
%
% OUTPUT:
% output - structure with montage data

% (C) Copyright 2022 bidspm developers

% TODO: Needs improvement i.t.o RAS/LAS orientation specification
% and image layout...

args = inputParser;

Check warning on line 34 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L34

Added line #L34 was not covered by tests

addRequired(args, 'img');
addParameter(args, 'columns', 9, @isnumeric);
addParameter(args, 'rotate', true, @islogical);
addParameter(args, 'cmap', 'gray', @ischar);
addParameter(args, 'visibility', 'on', @ischar);
addParameter(args, 'shape', 'max', @ischar); % max or square
addParameter(args, 'cxs', 'auto');

Check warning on line 42 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L36-L42

Added lines #L36 - L42 were not covered by tests

parse(args, varargin{:});

Check warning on line 44 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L44

Added line #L44 was not covered by tests

img = args.Results.img;
columns = args.Results.columns;
rotate = args.Results.rotate;
cmap = args.Results.cmap;
visibility = args.Results.visibility;
shape = args.Results.shape;
cxs = args.Results.cxs;

Check warning on line 52 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L46-L52

Added lines #L46 - L52 were not covered by tests

montage = struct;
[Ni, Nj, Nk] = size(img);

Check warning on line 55 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L54-L55

Added lines #L54 - L55 were not covered by tests

% Rotate image slices if required
if rotate
img_orig = img;
clear img;
for p = 1:Nk
img(:, :, p) = rot90(img_orig(:, :, p));

Check warning on line 62 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L58-L62

Added lines #L58 - L62 were not covered by tests
end
end

% Determine amount of rows and filler slices
rows = floor(Nk / columns);
if rows == 0
rows = 1;

Check warning on line 69 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L67-L69

Added lines #L67 - L69 were not covered by tests
end
fill = mod(Nk, columns);
if fill == 0
N_fill = 0;

Check warning on line 73 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L71-L73

Added lines #L71 - L73 were not covered by tests
else
N_fill = columns - mod(Nk, columns);

Check warning on line 75 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L75

Added line #L75 was not covered by tests
end
if rotate
filler = zeros(Nj, Ni);

Check warning on line 78 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L77-L78

Added lines #L77 - L78 were not covered by tests
else
filler = zeros(Ni, Nj);

Check warning on line 80 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L80

Added line #L80 was not covered by tests
end

montage.rows = rows;
montage.columns = columns;
montage.N_fill = N_fill;

Check warning on line 85 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L83-L85

Added lines #L83 - L85 were not covered by tests

parts = {};

Check warning on line 87 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L87

Added line #L87 was not covered by tests
% 1 - Concatenate slices together horizontally, per row (except last).
% 2 - Concatenate rows together vertically
for i = 1:rows
for j = 1:columns
if j == 1
parts{i} = img(:, :, columns * (i - 1) + j);

Check warning on line 93 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L90-L93

Added lines #L90 - L93 were not covered by tests
else
parts{i} = cat(2, parts{i}, img(:, :, columns * (i - 1) + j));

Check warning on line 95 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L95

Added line #L95 was not covered by tests
end
end
if i == 1
whole = parts{i};

Check warning on line 99 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L98-L99

Added lines #L98 - L99 were not covered by tests
else
whole = cat(1, whole, parts{i});

Check warning on line 101 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L101

Added line #L101 was not covered by tests
end
end

% 1 - Concatenate filler slices to last row, if required.
% 2 - Concatenate last row to whole matrix, if required.
if N_fill ~= 0

Check warning on line 107 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L107

Added line #L107 was not covered by tests
% last row
last_parts = img(:, :, rows * columns + 1);
for k = (rows * columns + 2):Nk
last_parts = cat(2, last_parts, img(:, :, k));

Check warning on line 111 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L109-L111

Added lines #L109 - L111 were not covered by tests
end
for m = 1:N_fill
last_parts = cat(2, last_parts, filler);

Check warning on line 114 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L113-L114

Added lines #L113 - L114 were not covered by tests
end
montage.whole_img = cat(1, whole, last_parts);

Check warning on line 116 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L116

Added line #L116 was not covered by tests
else
montage.whole_img = whole;

Check warning on line 118 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L118

Added line #L118 was not covered by tests
end

f = initMontageFigure(shape, visibility);

Check warning on line 121 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L121

Added line #L121 was not covered by tests

ax = subplot(1, 1, 1);
im = imagesc(ax, montage.whole_img);

Check warning on line 124 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L123-L124

Added lines #L123 - L124 were not covered by tests

colormap(cmap);
if ~isempty(cxs)
caxis(ax, cxs);

Check warning on line 128 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L126-L128

Added lines #L126 - L128 were not covered by tests
end

montage.im = im;
montage.f = f;
montage.ax = ax;

Check warning on line 133 in src/plotting/createMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createMontage.m#L131-L133

Added lines #L131 - L133 were not covered by tests

end
133 changes: 133 additions & 0 deletions src/plotting/createOverlayMontage.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
function output = createOverlayMontage(varargin)

% (C) Copyright 2024 bidspm developers

% fmrwhy_util_createOverlayMontage(tsnr_img{i}, overlayImg, 9, 1, '', ...
% 'hot', 'off', 'max', [0 250], [33, 168, 10], tsnr_saveAss{i});

% Function to create montages of images/rois overlaid on a template image

rgbcolors = [255, 255, 191; ...

Check warning on line 10 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L10

Added line #L10 was not covered by tests
215, 25, 28; ...
253, 174, 97; ...
171, 217, 233; ...
44, 123, 182];

args = inputParser;

Check warning on line 16 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L16

Added line #L16 was not covered by tests

addRequired(args, 'templateImg');
addRequired(args, 'overlayImg');
addParameter(args, 'columns', 9, @isnumeric);
addParameter(args, 'rotate', true, @islogical);
addParameter(args, 'cmap', 'gray', @ischar);
addParameter(args, 'visibility', 'on', @ischar);
addParameter(args, 'shape', 'max', @ischar); % max or square
addParameter(args, 'cxs', 'auto');
addParameter(args, 'rgbcolors', rgbcolors);
addParameter(args, 'saveAs', '');

Check warning on line 27 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L18-L27

Added lines #L18 - L27 were not covered by tests

parse(args, varargin{:});

Check warning on line 29 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L29

Added line #L29 was not covered by tests

templateImg = args.Results.templateImg;
overlayImg = args.Results.overlayImg;
columns = args.Results.columns;
rotate = args.Results.rotate;
cmap = args.Results.cmap;
visibility = args.Results.visibility;
shape = args.Results.shape;
cxs = args.Results.cxs;
rgbcolors = args.Results.rgbcolors;
saveAs = args.Results.saveAs;

Check warning on line 40 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L31-L40

Added lines #L31 - L40 were not covered by tests

% Structure to save output
output = struct;
alpha = 0.2;
plot_contour = 1;
rgbcolors = rgbcolors / 255;

Check warning on line 46 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L43-L46

Added lines #L43 - L46 were not covered by tests

% Create background montage
montage_template = createMontage(templateImg, ...

Check warning on line 49 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L49

Added line #L49 was not covered by tests
'columns', columns, ...
'rotate', rotate, ...
'cmap', cmap, ...
'visibility', 'off', ...
'shape', shape, ...
'cxs', cxs);

% Create figures with background montage and overlaid masks
f = initMontageFigure(shape, visibility);
imagesc(montage_template.whole_img);
colormap(cmap);
if ~isempty(cxs)
caxis(cxs);

Check warning on line 62 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L58-L62

Added lines #L58 - L62 were not covered by tests
end
ax = gca;
outerpos = ax.OuterPosition;
ti = ax.TightInset;
left = outerpos(1) + ti(1);
bottom = outerpos(2) + ti(2);
ax_width = outerpos(3) - ti(1) - ti(3);
ax_height = outerpos(4) - ti(2) - ti(4);
ax.Position = [left bottom ax_width ax_height];
hold(ax, 'on');
[Nimx, Nimy] = size(montage_template.whole_img);
oo = ones(Nimx, Nimy);

Check warning on line 74 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L64-L74

Added lines #L64 - L74 were not covered by tests

if iscell(overlayImg)
for i = 1:numel(overlayImg)
montage_overlay{i} = createMontage(overlayImg{i}, ...

Check warning on line 78 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L76-L78

Added lines #L76 - L78 were not covered by tests
'columns', columns, ...
'rotate', rotate, ...
'cmap', cmap, ...
'visibility', 'off', ...
'shape', shape, ...
'cxs', 'auto');
end
else
montage_overlay = {};
montage_overlay{1} = createMontage(overlayImg, ...

Check warning on line 88 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L87-L88

Added lines #L87 - L88 were not covered by tests
'columns', columns, ...
'rotate', rotate, ...
'cmap', cmap, ...
'visibility', 'off', ...
'shape', shape, ...
'cxs', 'auto');
end

for i = 1:numel(montage_overlay)
rbgclr = rgbcolors(i, :);
clr = cat(3, rbgclr(1) * oo, rbgclr(2) * oo, rbgclr(3) * oo);
imC = imagesc(ax, clr);
set(imC, 'AlphaData', alpha * montage_overlay{i}.whole_img);
if plot_contour
bound_whole_bin = bwboundaries(montage_overlay{i}.whole_img);
Nblobs_bin = numel(bound_whole_bin);
for b = 1:Nblobs_bin
p = plot(ax, bound_whole_bin{b, 1}(:, 2), bound_whole_bin{b, 1}(:, 1), ...

Check warning on line 106 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L97-L106

Added lines #L97 - L106 were not covered by tests
'color', rbgclr, 'LineWidth', 1);
end
end
end

hold(ax, 'off');
set(ax, 'xtick', []);
set(ax, 'xticklabel', []);
set(ax, 'ytick', []);
set(ax, 'yticklabel', []);
set(ax, 'ztick', []);
set(ax, 'zticklabel', []);

Check warning on line 118 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L112-L118

Added lines #L112 - L118 were not covered by tests

output.ax = ax;
output.f = f;

Check warning on line 121 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L120-L121

Added lines #L120 - L121 were not covered by tests

if saveAs ~= 0
print(f, saveAs, '-dpng', '-r0');

Check warning on line 124 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L123-L124

Added lines #L123 - L124 were not covered by tests
end
% Close necessary figure handles
close(montage_template.f);
for i = 1:numel(montage_overlay)
close(montage_overlay{i}.f);

Check warning on line 129 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L127-L129

Added lines #L127 - L129 were not covered by tests
end
if strcmp(visibility, 'off')
close(f);

Check warning on line 132 in src/plotting/createOverlayMontage.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/createOverlayMontage.m#L131-L132

Added lines #L131 - L132 were not covered by tests
end
24 changes: 24 additions & 0 deletions src/plotting/initMontageFigure.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function f = initMontageFigure(shape, visibility)
% (C) Copyright 2024 bidspm developers

scr_size = get(0, 'ScreenSize');
dist = scr_size(4);
if scr_size(3) < dist
dist = scr_size(3);

Check warning on line 7 in src/plotting/initMontageFigure.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/initMontageFigure.m#L4-L7

Added lines #L4 - L7 were not covered by tests
end
% Create figure - outerposition = [left bottom width height]

if strcmp(shape, 'max')
f = figure('visible', visibility, ...

Check warning on line 12 in src/plotting/initMontageFigure.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/initMontageFigure.m#L11-L12

Added lines #L11 - L12 were not covered by tests
'units', 'normalized', ...
'outerposition', [0 0 1 1]);
elseif strcmp(shape, 'square')
f = figure('visible', visibility, ...

Check warning on line 16 in src/plotting/initMontageFigure.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/initMontageFigure.m#L16

Added line #L16 was not covered by tests
'units', 'pixels', ...
'outerposition', [0 0 dist dist]);
else
f = figure('visible', visibility, ...

Check warning on line 20 in src/plotting/initMontageFigure.m

View check run for this annotation

Codecov / codecov/patch

src/plotting/initMontageFigure.m#L20

Added line #L20 was not covered by tests
'units', 'pixels', ...
'outerposition', [0 0 dist dist]);
end
end
24 changes: 24 additions & 0 deletions untitled.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
% (C) Copyright 2022 bidspm developers
close all;

bidspm_dir = '/home/remi/github/cpp-lln-lab/bidspm';

demos_dir = fullfile(bidspm_dir, 'demos/MoAE/outputs/derivatives/');

overlay_img = fullfile(demos_dir, ...
'bidspm-stats/sub-01/task-auditory_space-MNI152NLin6Asym_FWHM-8/mask.nii');

template_img = fullfile( ...
demos_dir, ...
'bidspm-preproc', 'sub-01', 'func', ...
'sub-01_task-auditory_space-MNI152NLin6Asym_desc-smth8_bold.nii');

template_hdr = spm_vol(template_img);
template = spm_read_vols(template_hdr(1));

mask_hdr = spm_vol(overlay_img);
mask = spm_read_vols(mask_hdr);

% createMontage(template, 'shape', 'square');
createOverlayMontage(template, mask, 'rgbcolors', [255, 0, 0], ...
'shape', 'square');