Skip to content

Commit 931340a

Browse files
committed
change demo to get peak coordinates into a function
1 parent f03c5ec commit 931340a

File tree

4 files changed

+149
-150
lines changed

4 files changed

+149
-150
lines changed

demos/WIP/get_ROI_Coordinates.m

Lines changed: 0 additions & 150 deletions
This file was deleted.

src/roi/checkRoiOrientation.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
%
77
% :param referenceImage: better if fullfile path
88
% :type referenceImage: string
9+
%
910
% :param imagesToCheck: better if fullfile path
1011
% :type imagesToCheck: string
1112
%

src/roi/getPeakCoordinates.m

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
function [worldCoord, voxelCoord, maxVal] = getPeakCoordinates(varargin)
2+
%
3+
% This function gets the coordinates of a peak within a specified region of
4+
% interest.
5+
%
6+
% [worldCoord, voxelCoord, maxVal] = getPeakCoordinates(dataImage, roiImage, criticalT)
7+
%
8+
%
9+
% (C) Copyright 2021 CPP ROI developers
10+
11+
isFile = @(x) exist(x, 'file') == 2;
12+
13+
args = inputParser;
14+
15+
args.addRequired('dataImage', isFile);
16+
args.addRequired('roiImage', isFile);
17+
args.addOptional('criticalT', 0, @isnumeric);
18+
19+
args.parse(varargin{:});
20+
21+
dataImage = args.Results.dataImage;
22+
roiImage = args.Results.roiImage;
23+
criticalT = args.Results.criticalT;
24+
25+
voxelCoord = nan(1, 3);
26+
worldCoord = nan(1, 3);
27+
28+
maxVal = spm_summarise(spm_vol(dataImage), roiImage, @max);
29+
30+
if ~checkRoiOrientation(dataImage, roiImage)
31+
return
32+
end
33+
34+
if maxVal < criticalT
35+
warning('getPeakCoordinates:noMaxBeyondThreshold', ...
36+
'No max value found beyond threshold %f in image:\n %s\n', ...
37+
dataImage, ...
38+
criticalT);
39+
return
40+
end
41+
42+
data = spm_read_vols(spm_vol(dataImage));
43+
mask = spm_read_vols(spm_vol(roiImage));
44+
45+
data(~mask) = nan(1, sum(~mask(:)));
46+
47+
% Get the location of the higest t-value in slice space
48+
voxeIdx = find(data == maxVal);
49+
if numel(voxeIdx) > 1
50+
% TODO return list of all maximums?
51+
warning('getPeakCoordinates:severalMaxBeyondThreshold', ...
52+
'Several equal max value found beyond threshold %f in image:\n %s\n', ...
53+
dataImage, ...
54+
criticalT);
55+
return
56+
end
57+
58+
[x, y, z] = ind2sub(size(data), voxeIdx);
59+
voxelCoord = [x, y, z];
60+
61+
% convert space from slice number to world coordinate
62+
worldCoord = cor2mni(voxelCoord, roiImage);
63+
64+
% TODO
65+
% world_coord(1) = world_coord(1) * -1;
66+
% If masks created from AFNI or FSL,
67+
% the x coordinate could be flipped (multiplied x -1).
68+
% If this is the case, multiply x with -1.
69+
70+
end
71+
72+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73+
%%% cor2mni
74+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75+
function mni = cor2mni(cor, nifti_image)
76+
% function mni = cor2mni(cor, T)
77+
% convert matrix coordinate to mni coordinate
78+
%
79+
% cor: an Nx3 matrix
80+
% T: (optional) rotation matrix
81+
% mni is the returned coordinate in mni space
82+
%
83+
% caution: if T is not given, the default T is
84+
% T = ...
85+
% [-4 0 0 84;...
86+
% 0 4 0 -116;...
87+
% 0 0 4 -56;...
88+
% 0 0 0 1];
89+
%
90+
% xu cui
91+
% 2004-8-18
92+
% last revised: 2005-04-30
93+
94+
% if nargin == 1
95+
% T = ...
96+
% [-4 0 0 84;...
97+
% 0 4 0 -116;...
98+
% 0 0 4 -56;...
99+
% 0 0 0 1];
100+
% end
101+
102+
V = spm_vol(nifti_image);
103+
T = V.mat;
104+
105+
cor = round(cor);
106+
mni = T * [cor(:, 1) cor(:, 2) cor(:, 3) ones(size(cor, 1), 1)]';
107+
mni = mni';
108+
mni(:, 4) = [];
109+
end

tests/test_getPeakCoordinates.m

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
% (C) Copyright 2020 CPP ROI developers
2+
3+
function test_suite = test_getPeakCoordinates %#ok<*STOUT>
4+
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
5+
test_functions = localfunctions(); %#ok<*NASGU>
6+
catch % no problem; early Matlab versions can use initTestSuite fine
7+
end
8+
initTestSuite;
9+
end
10+
11+
function test_getPeakCoordinates_basic()
12+
13+
roiImage = extractRoiFromAtlas(pwd, 'wang', 'V1v', 'L');
14+
15+
dataImage = fullfile(demoDir(), 'TStatistic.nii');
16+
17+
reslicedImages = resliceRoiImages(dataImage, roiImage);
18+
19+
[worldCoord, voxelCoord, maxVal] = getPeakCoordinates(dataImage, reslicedImages);
20+
21+
assertEqual(worldCoord, [-3 -91 -1]);
22+
assertEqual(voxelCoord, [28 8 24]);
23+
assertElementsAlmostEqual(maxVal, 1.6212, 'absolute', 1e-3);
24+
25+
end
26+
27+
function value = thisDir()
28+
value = fullfile(fileparts(mfilename('fullpath')));
29+
end
30+
31+
function value = demoDir()
32+
33+
value = fullfile(thisDir(), '..', 'demos', 'roi', 'inputs');
34+
35+
if exist(fullfile(value, 'TStatistic.nii'), 'file') == 0
36+
gunzip(fullfile(value, '*.gz'));
37+
end
38+
39+
end

0 commit comments

Comments
 (0)