Skip to content

Commit c92fc61

Browse files
committed
Merge branch 'olf_blind' into dev
2 parents d7c3a88 + 282d8b4 commit c92fc61

18 files changed

+431
-93
lines changed

.gitignore

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
21
.DS_Store
32

43
*.nii
5-
4+
*.xml
5+
*.log
66
*.asv
77
*.m~
88
*.mat
99

10-
<<<<<<< HEAD
10+
*.html
11+
1112
# files in the demo folder related to running the demo analysis
1213
# demos/roi
13-
=======
14+
1415
atlas/visual_topography_probability_atlas/
15-
>>>>>>> 4a2a3830905dfad9b61804bf99e2941a49e4e2fa
1616

1717
# test folder and dummy data
1818

@@ -28,3 +28,5 @@ envs/*
2828
demos/*/*.json
2929
demos/*/*/*.json
3030
demos/*/derivatives
31+
32+
atlas/*.json

README.md

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1-
<!-- lint disable -->
2-
3-
**Documentation**
4-
5-
**Code quality and style**
6-
7-
**Unit tests and coverage**
8-
9-
**How to cite**
10-
11-
**Contributors**
12-
131
# CPP ROI
142

15-
## :warning: :warning: :warning:
3+
---
4+
5+
## :warning:
166

17-
**This code is fairly unstable (:boom:) and might still change a lot.**
7+
**This code is fairly unstable and might still change.**
188

19-
Also this code currently has 0% test coverage...
9+
So make sure you "pin" which version or commit you are using for a given
10+
project, if you don't want your code to break in the future.
2011

2112
---
2213

@@ -57,8 +48,7 @@ as a submodule, and intitialized when running `initCppSpm`.
5748

5849
### Dependencies
5950

60-
=======
61-
TODO
51+
======= TODO
6252

6353
| Dependencies | Used version |
6454
| ---------------------------------------------------------- | ------------ |
@@ -98,8 +88,4 @@ TODO
9888
Also includes:
9989

10090
- Yeo's 7 networks "atlas"
101-
- add REF and URL
102-
103-
## Contributing
104-
105-
## Contributors
91+
<!-- add REF and URL -->

demos/roi/step_7_get_ROI_PSC.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
% This script will run through the ROIs made for each subject fo a ROI
22
% based anaylisis using MarsBar to get a time course of the activations and
33
% a percent signal change for each ROI and subject
4+
%
5+
% (C) Copyright 2020 CPP ROI developers
46

57
clc;
68

demos/roi/step_8_plot_PSC.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
% This script will run through the ROIs made for each subject fo a ROI
22
% based anaylisis using MarsBar to get a time course of the activations and
33
% a percent signal change for each ROI and subject
4+
%
5+
% (C) Copyright 2020 CPP ROI developers
46

57
% TODO
68
% - refactor

initCppRoi.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ function initCppRoi()
1212

1313
pathSep = ':';
1414
if ~isunix
15-
pathSep = ';';
15+
pathSep = ';';
1616
end
1717
% we add all the subfunctions that are in the sub directories
1818
CPP_ROI_PATHS = genpath(fullfile(thisDirectory, 'src'));
1919
CPP_ROI_PATHS = cat(2, CPP_ROI_PATHS, pathSep, ...
20-
fullfile(thisDirectory, 'lib', 'marsbar-0.44'));
20+
fullfile(thisDirectory, 'lib', 'marsbar-0.44'));
2121
addpath(CPP_ROI_PATHS, '-begin');
22-
22+
2323
marsbar('on');
2424
try
2525
marsbar('splash');
2626
catch
2727
end
28-
28+
2929
CPP_ROI_INITIALIZED = true();
3030

3131
else

src/atlas/labelClusters.m

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,59 @@
1-
function outputImage = labelClusters(sourceImage, peakThreshold, extendThreshold)
1+
function outputImage = labelClusters(varargin)
2+
%
3+
% Returns a binary mask for an image after applying voxel wise threshold and
4+
% an optional cluster size threshold
5+
%
6+
% USAGE::
7+
%
8+
% outputImage = thresholdToMask(inputImage, peakThreshold, clusterSize)
9+
%
10+
% :param inputImage:
11+
% :type inputImage: path
12+
% :param peakThreshold:
13+
% :type peakThreshold: float
14+
% :param clusterSize:
15+
% :type clusterSize: integer >= 0 (Default: 0)
16+
%
17+
% :returns: - :outputImage: (string)
18+
%
19+
% See also getClusters, sortAndLabelClusters
220
%
321
% Adapted from:
422
% https://en.wikibooks.org/wiki/SPM/How-to#How_to_remove_clusters_under_a_certain_size_in_a_binary_mask?
523
%
624
% (C) Copyright 2021 CPP ROI developers
725

8-
hdr = spm_vol(sourceImage);
26+
default_clusterSize = 0;
27+
28+
isFile = @(x) exists(x, 'file') == 2;
29+
isPositive = @(x) isinteger(x) && X >= 0;
30+
31+
p = inputParser;
32+
33+
addRequired(p, 'inputImage', isFile);
34+
addRequired(p, 'peakThreshold', @isnumeric);
35+
addOptional(p, 'clusterSize', default_clusterSize, isPositive);
36+
37+
parse(p, varargin{:});
938

10-
[l2, num] = getClusters(hdr, peakThreshold);
39+
inputImage = p.Results.inputImage;
40+
peakThreshold = p.Results.peakThreshold;
41+
clusterSize = p.Results.clusterSize;
42+
43+
[l2, num] = getClusters(inputImage, peakThreshold);
1144

1245
if ~num
1346
warning('No clusters found.');
1447
return
1548
end
1649

17-
vol = sortAndLabelClusters(l2, num, extendThreshold);
50+
vol = sortAndLabelClusters(l2, num, clusterSize);
1851

1952
% Write new image with cluster laebelled with their voxel size
20-
p = bids.internal.parse_filename(sourceImage);
53+
p = bids.internal.parse_filename(inputImage);
2154
p.suffix = 'dseg'; % discrete segmentation
2255

56+
hdr = spm_vol(inputImage);
2357
bidsFile = bids.File(p);
2458
hdr.fname = spm_file(hdr.fname, 'filename', bidsFile.filename);
2559

@@ -31,29 +65,3 @@
3165
bids.util.jsonencode(json.filename, json.content);
3266

3367
end
34-
35-
function [l2, num] = getClusters(hdr, peakThreshold)
36-
data = spm_read_vols(hdr);
37-
[l2, num] = spm_bwlabel(double(data > peakThreshold), 26);
38-
end
39-
40-
function vol = sortAndLabelClusters(l2, num, extendThreshold)
41-
42-
% Extent threshold, and sort clusters by their extent
43-
% Label corresponds to their rank
44-
[n, ni] = sort(histc(l2(:), 0:num), 1, 'descend');
45-
vol = zeros(size(l2));
46-
n = n(2:end);
47-
ni = ni(2:end) - 1;
48-
ni = ni(n >= extendThreshold);
49-
n = n(n >= extendThreshold);
50-
for i = 1:length(n)
51-
vol(l2 == ni(i)) = i;
52-
end
53-
54-
fprintf('Selected %d clusters (out of %d) in image.\n', length(n), num);
55-
for i = 1:length(n)
56-
fprintf('Cluster label %i ; size: %i voxels\n', i, n(i));
57-
end
58-
59-
end

src/atlas/returnAtlasDir.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
%
1111
% (C) Copyright 2021 CPP ROI developers
1212

13-
atlasDir = fullfile(fileparts(mfilename('fullpath')), '..', '..', 'atlas');
13+
atlasDir = fullfile(rootDir(), 'atlas');
1414

1515
if nargin > 0
1616

src/roi/get_ROI_Coordinates.m

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
function mni = get_ROI_Coordinates
2+
% This function gets the individual subject coordniates of the highest peak
3+
% within a specified Region of interest (usually coming from the group level univariate analysis)
4+
5+
% Critical t-value for each experimental condition or mask file
6+
CriticalTs = 1; % Critical t-value for visual condition in L-V5 and R-V5 and bilateral PT
7+
8+
%% load the data structure
9+
WD = pwd;
10+
11+
%% group of subjects to analyze
12+
opt.groups = {'EB', 'SCa', 'SCv'}; % {'EB','SCa','SCv'};
13+
% suject to run in each group
14+
opt.subjects = {[1:13], [1:10], [1:6]}; % {[1:13],[1:10],[1:6]};
15+
16+
%%
17+
smoothing = '6';
18+
19+
%% Regions that will be used to extract the highest t-value within that mask
20+
maskFn = { 'face_lFFA.nii'
21+
'face_rFFA.nii'
22+
};
23+
24+
CriticalTs = ones(1, length(maskFn)) * CriticalTs;
25+
26+
%% Location of the data
27+
data_path = '/Volumes/SanDisk/Oli_Data/Categs_BIDS/derivatives';
28+
29+
% create an mni cell with dimensions (1x number of masks)
30+
mni = cell(1, length(maskFn));
31+
SubNames = {};
32+
33+
% for each mask
34+
for iMask = 1:length(maskFn)
35+
36+
fprintf('Running Mask %.0f \n\n', iMask);
37+
CriticalT = CriticalTs(iMask); % get the critical t
38+
39+
subCounter = 0;
40+
for iGroup = 1:length(opt.groups)
41+
for iSub = 1:length(opt.subjects{iGroup})
42+
43+
fprintf('Running Subject %.0f \n', iSub);
44+
45+
SubName = ['sub-', opt.groups{iGroup}, ...
46+
sprintf('%02d', opt.subjects{iGroup}(iSub))];
47+
48+
fprintf('%s \n', SubName);
49+
subCounter = subCounter + 1;
50+
SubNames{subCounter, iMask} = SubName(5:end);
51+
52+
%% the first 4 masks are for the FACE condition, the other 4
53+
% are from the SCENE condition
54+
if iMask <= 2
55+
result_file = [data_path, '/', SubName, '/stats/ffx_visMotion/ffx_', smoothing, '/spmT_0013.nii']; % HUMAN > BIG_ENV
56+
else
57+
result_file = [data_path, '/', SubName, '/stats/ffx_audMotion/ffx_', smoothing, '/spmT_0014.nii']; % BIG_ENV > HUMAN
58+
end
59+
60+
%%
61+
mask_path = fullfile(WD, 'Kanwisher_ROIs', maskFn{iMask});
62+
63+
r = load_nii(result_file);
64+
m = load_nii(mask_path);
65+
66+
r.img(~m.img) = nan;
67+
68+
maxVal = max(r.img(:));
69+
maxVals(subCounter, iMask) = maxVal;
70+
71+
if maxVal > CriticalT %|| maxVal < CriticalT
72+
73+
% Get the location of the higest t-value in slice space
74+
voxel_idx = find(r.img == maxVal);
75+
76+
disp(maxVal);
77+
[x, y, z] = ind2sub(size(r.img), voxel_idx);
78+
79+
% convert space from slice number to mni
80+
mni{1, iMask}(subCounter, :) = cor2mni([x y z], mask_path);
81+
% mni{1,iMask}(iSub,1) = mni{1,iMask}(iSub,1)* -1; % If masks created from AFNI or FSL,
82+
% the x coordinate could be flipped (multiplied x -1). If this is the case, multiply x with -1.
83+
84+
mni{1, iMask}(subCounter, :);
85+
86+
else
87+
mni{1, iMask}(subCounter, 1:3) = nan;
88+
end
89+
90+
end
91+
end
92+
end
93+
94+
save('mni_coordinates.mat', 'mni', 'maskFn', 'opt', 'maxVals', 'SubNames');
95+
end
96+
97+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98+
%%% cor2mni
99+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100+
function mni = cor2mni(cor, nifti_image)
101+
% function mni = cor2mni(cor, T)
102+
% convert matrix coordinate to mni coordinate
103+
%
104+
% cor: an Nx3 matrix
105+
% T: (optional) rotation matrix
106+
% mni is the returned coordinate in mni space
107+
%
108+
% caution: if T is not given, the default T is
109+
% T = ...
110+
% [-4 0 0 84;...
111+
% 0 4 0 -116;...
112+
% 0 0 4 -56;...
113+
% 0 0 0 1];
114+
%
115+
% xu cui
116+
% 2004-8-18
117+
% last revised: 2005-04-30
118+
119+
% if nargin == 1
120+
% T = ...
121+
% [-4 0 0 84;...
122+
% 0 4 0 -116;...
123+
% 0 0 4 -56;...
124+
% 0 0 0 1];
125+
% end
126+
127+
V = spm_vol(nifti_image);
128+
T = V.mat;
129+
130+
cor = round(cor);
131+
mni = T * [cor(:, 1) cor(:, 2) cor(:, 3) ones(size(cor, 1), 1)]';
132+
mni = mni';
133+
mni(:, 4) = [];
134+
end

0 commit comments

Comments
 (0)