Skip to content

Commit 22e2599

Browse files
authored
Merge pull request #728 from cpp-lln-lab/dev
[REL] v2.1.0
2 parents eeb9a71 + 8ec594d commit 22e2599

38 files changed

+486
-192
lines changed

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cff-version: 1.2.0
22

33
title: "CPP SPM"
44

5-
version: 2.0.0
5+
version: 2.1.0
66

77
abstract: CPP_SPM is a set pipelines and tools for Octave/MATLAB to process and analyze BIDS data sets using SPM.
88

demos/MoAE/moae_01_bids_app.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@
9898
opt.results(1).montage.slices = -4:2:16;
9999
opt.results(1).nidm = true();
100100

101+
opt.results(2).nodeName = 'run_level';
102+
opt.results(2).name = {'listening_inf_baseline'};
103+
opt.results(2).p = 0.01;
104+
opt.results(2).k = 10;
105+
opt.results(2).MC = 'none';
106+
opt.results(2).csv = true;
107+
opt.results(2).atlas = 'AAL';
108+
101109
cpp_spm(bids_dir, output_dir, 'subject', ...
102110
'participant_label', {subject_label}, ...
103111
'action', 'stats', ...

demos/lesion_detection/run_lesion.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222

2323
bidsCopyInputFolder(opt);
2424

25-
% Step 1: segmentation
25+
%% Step 1: segmentation
2626
bidsLesionSegmentation(opt);
2727

28-
% % Step 2: lesion abnormalities
28+
%% Step 2: lesion abnormalities
2929
bidsLesionAbnormalitiesDetection(opt);
3030

3131
% % Step 3: overlap map

docs/cpp_spm-manual.pdf

502 KB
Binary file not shown.

src/IO/renameSegmentParameter.m

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,17 @@ function renameSegmentParameter(BIDS, subLabel, opt)
88
%
99
% (C) Copyright 2020 CPP_SPM developers
1010

11+
opt = set_spm_2_bids_defaults(opt);
12+
1113
[anatImage, anatDataDir] = getAnatFilename(BIDS, opt, subLabel);
1214

1315
segmentParam = spm_select('FPList', anatDataDir, ['^.*', ...
1416
spm_file(anatImage, 'basename'), ...
1517
'_seg8.mat$']);
1618

17-
bf = bids.File(anatImage);
18-
bf.entities.label = bf.suffix;
19-
20-
bf.suffix = 'segparam';
21-
bf.extension = '.mat';
19+
newFilename = spm_2_bids(segmentParam, opt.spm_2_bids);
2220

23-
newName = spm_file(segmentParam, 'filename', bf.filename);
21+
newName = spm_file(segmentParam, 'filename', newFilename);
2422

2523
if ~isempty(segmentParam)
2624
movefile(segmentParam, newName);

src/IO/renameUnwarpParameter.m

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,21 @@ function renameUnwarpParameter(BIDS, subLabel, opt)
1212
return
1313
end
1414

15+
opt = set_spm_2_bids_defaults(opt);
16+
1517
for iTask = 1:numel(opt.taskName)
1618

1719
unwarpParam = spm_select('FPListRec', BIDS.pth, ...
1820
['^.*sub-' subLabel '.*_task-' opt.taskName{iTask} '.*_bold_uw.mat$']);
1921

2022
for iFile = 1:size(unwarpParam, 1)
2123

22-
inputFilename = strrep(unwarpParam(iFile, :), '_uw.', '.');
23-
24-
bf = bids.File(inputFilename);
25-
bf.entities.label = bf.suffix;
26-
bf.suffix = 'unwarpparam';
27-
bf.extension = '.mat';
24+
newFilename = spm_2_bids(unwarpParam(iFile, :), opt.spm_2_bids);
2825

29-
newName = spm_file(unwarpParam(iFile, :), 'filename', bf.filename);
26+
outputFile = spm_file(unwarpParam(iFile, :), 'filename', newFilename);
3027

3128
if ~isempty(unwarpParam(iFile, :))
32-
movefile(unwarpParam(iFile, :), newName);
29+
movefile(unwarpParam(iFile, :), outputFile);
3330
end
3431

3532
end

src/batches/lesion/setBatchLesionAbnormalitiesDetection.m

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

2222
outliers_detection = opt.toolbox.ALI.outliers_detection;
2323

24+
outliers_detection.step3mask{1} = resizeAliMask(opt);
25+
2426
for i = 1:size(images, 1)
2527

2628
% 1. Define smoothed segmented tissue images of patients

src/batches/lesion/setBatchLesionSegmentation.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@
2121

2222
[anatImage, anatDataDir] = getAnatFilename(BIDS, opt, subLabel);
2323

24-
hdr = spm_vol(fullfile(anatDataDir, anatImage));
25-
voxRes = diag(hdr.mat);
26-
voxRes = min(voxRes(1:3));
27-
unified_segmentation.step1vox = abs(voxRes);
24+
% TODO
25+
% this needs to be changed
26+
% - to be consistent across subject
27+
% - to reslice the size of the mask that is then used for lesion detection
28+
%
29+
% hdr = spm_vol(fullfile(anatDataDir, anatImage));
30+
% voxRes = diag(hdr.mat);
31+
% voxRes = min(voxRes(1:3));
32+
% unified_segmentation.step1vox = abs(voxRes);
33+
2834
unified_segmentation.step1data{1} = fullfile(anatDataDir, anatImage);
2935

3036
matlabbatch{end + 1}.spm.tools.ali.unified_segmentation = unified_segmentation;

src/defaults/ALI_my_defaults.m

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
%
77
% defaults = ALI_my_defaults()
88
%
9-
% This is where we set the defautls we want to use for the ALE (lesion) toolbox.
9+
% This is where we set the defautls we want to use for the ALI (lesion) toolbox.
1010
% These will overide the spm defaults.
1111
% When "not enough" information is specified in the batch files, SPM falls
1212
% back on the defaults to fill in the blanks. This allows to make the
@@ -21,8 +21,11 @@
2121
spmDir = spm('dir');
2222

2323
% specify Prior EXTRA class (lesion prior map)
24-
lesionPriorMap = fullfile(spmDir, 'toolbox', 'ALI', ...
25-
'Priors_extraClass', 'wc4prior0.nii');
24+
lesionPriorMap = fullfile(spmDir, ...
25+
'toolbox', ...
26+
'ALI', ...
27+
'Priors_extraClass', ...
28+
'wc4prior0.nii');
2629

2730
defaults.toolbox.ALI.unified_segmentation.step1prior = {lesionPriorMap};
2831

@@ -51,10 +54,6 @@
5154
% Specify lambda parameter
5255
defaults.toolbox.ALI.outliers_detection.step3tissue.step3Lambda = -4;
5356

54-
% specify lesion mask
55-
defaults.toolbox.ALI.lesionMask = fullfile(spmDir, 'toolbox', 'ALI', ...
56-
'Mask_image', 'mask_controls_vox2mm.nii');
57-
5857
% threshold for the mask
5958
defaults.toolbox.ALI.outliers_detection.step3mask_thr = 0;
6059
% binary lesion: threshold U

src/defaults/checkOptions.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,12 @@
204204

205205
% validate content of opt.results
206206

207-
defaultContrast = defaultResultsStructure();
207+
defaultResults = defaultResultsStructure();
208208

209-
fields = fieldnames(defaultContrast);
209+
fields = fieldnames(defaultResults);
210210

211211
if ~isfield(opt, 'results')
212-
opt.results = defaultContrast;
212+
opt.results = defaultResults;
213213
return
214214
end
215215

@@ -226,12 +226,12 @@
226226
end
227227

228228
% add missing fields
229-
thisResult = setFields(thisResult, defaultContrast);
229+
thisResult = setFields(thisResult, defaultResults);
230230

231231
% fill in empty fields
232232
for i = 1:numel(fields)
233233
if isempty(thisResult.(fields{i}))
234-
thisResult.(fields{i}) = defaultContrast.(fields{i});
234+
thisResult.(fields{i}) = defaultResults.(fields{i});
235235
end
236236
end
237237

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
function contrast = defaultResultsStructure()
1+
function result = defaultResultsStructure()
22
%
33
% (C) Copyright 2019 CPP_SPM developers
44

5-
contrast = defaultContrastsStructure;
5+
result = defaultContrastsStructure;
66

7-
contrast.png = true();
7+
result.png = true();
88

9-
contrast.csv = true();
9+
result.csv = true();
10+
result.atlas = 'Neuromorphometrics';
1011

11-
contrast.threshSpm = false();
12+
result.threshSpm = false();
1213

13-
contrast.binary = false();
14+
result.binary = false();
1415

15-
contrast.montage = struct('do', false(), ...
16-
'slices', [], ...
17-
'orientation', 'axial', ...
18-
'background', fullfile(spm('dir'), ...
19-
'canonical', ...
20-
'avg152T1.nii'));
16+
result.montage = struct('do', false(), ...
17+
'slices', [], ...
18+
'orientation', 'axial', ...
19+
'background', fullfile(spm('dir'), ...
20+
'canonical', ...
21+
'avg152T1.nii'));
2122

22-
contrast.nidm = true();
23+
result.nidm = true();
2324

2425
end

src/defaults/setRenamingConfig.m

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
function opt = setRenamingConfig(opt, workflowName)
2+
%
3+
% set default map for renaming for a specific workflow
4+
%
5+
% USAGE::
6+
%
7+
% opt = setRenamingConfig(opt, workflowName)
8+
%
9+
%
10+
% (C) Copyright 2021 CPP_SPM developers
11+
12+
opt = set_spm_2_bids_defaults(opt);
13+
14+
map = opt.spm_2_bids;
15+
16+
switch lower(workflowName)
17+
18+
case 'spatialprepro'
19+
20+
if ~opt.realign.useUnwarp
21+
map = map.add_mapping('prefix', map.realign, ...
22+
'name_spec', map.cfg.preproc);
23+
24+
map = map.add_mapping('prefix', [map.realign 'mean'], ...
25+
'name_spec', map.cfg.mean);
26+
end
27+
28+
case 'realignreslice'
29+
30+
map = map.add_mapping('prefix', map.realign, ...
31+
'name_spec', map.cfg.preproc);
32+
33+
map = map.add_mapping('prefix', [map.realign 'mean'], ...
34+
'name_spec', map.cfg.mean);
35+
36+
case 'reslicetpmtofunc'
37+
38+
name_spec.entities.res = 'bold';
39+
map = map.add_mapping('prefix', map.realign, ...
40+
'name_spec', name_spec);
41+
42+
case 'lesionsegmentation'
43+
44+
res = opt.toolbox.ALI.unified_segmentation.step1vox;
45+
res = ['r' convertToStr(res)];
46+
fwhm = opt.toolbox.ALI.unified_segmentation.step1fwhm;
47+
48+
nameSpec = map.cfg.segment.gm;
49+
nameSpec.entities.res = res;
50+
prefix = [map.realign 'c1'];
51+
map = replaceMapping(map, prefix, nameSpec);
52+
53+
nameSpec = map.cfg.segment.wm;
54+
nameSpec.entities.res = res;
55+
prefix = [map.realign 'c2'];
56+
map = replaceMapping(map, prefix, nameSpec);
57+
58+
nameSpec = map.cfg.segment.csf;
59+
nameSpec.entities.res = res;
60+
prefix = [map.realign 'c3'];
61+
map = replaceMapping(map, prefix, nameSpec);
62+
63+
nameSpec = map.cfg.segment.gm;
64+
nameSpec.entities.label = 'PRIOR';
65+
nameSpec.entities.res = res;
66+
idx = map.find_mapping('prefix', [map.realign 'c4']);
67+
map = map.rm_mapping(idx);
68+
map = map.add_mapping('prefix', [map.realign 'c4'], ...
69+
'name_spec', nameSpec);
70+
71+
nameSpec = map.cfg.segment.gm_norm;
72+
nameSpec.entities.label = 'PRIOR';
73+
nameSpec.entities.res = res;
74+
idx = map.find_mapping('prefix', [map.norm 'c4']);
75+
map = map.rm_mapping(idx);
76+
map = map.add_mapping('prefix', [map.norm 'c4'], ...
77+
'name_spec', nameSpec);
78+
79+
nbIteration = opt.toolbox.ALI.unified_segmentation.step1niti;
80+
for i = 1:(nbIteration - 1)
81+
% 4th class prior next iteration
82+
nameSpec = map.cfg.segment.gm_norm;
83+
nameSpec.entities.label = 'PRIOR';
84+
nameSpec.entities.res = 'r1pt5';
85+
nameSpec.entities.desc = sprintf('nextIte%i', i);
86+
map = map.add_mapping('prefix', sprintf('%sc4prior%i', map.norm, i), ...
87+
'name_spec', nameSpec);
88+
89+
% 4th class at previous iteration
90+
nameSpec = map.cfg.segment.gm_norm;
91+
nameSpec.entities.label = 'PRIOR';
92+
nameSpec.entities.res = 'r1pt5';
93+
nameSpec.entities.desc = sprintf('prevIte%i', i);
94+
map = map.add_mapping('prefix', sprintf('%sc4previous%i', map.norm, i), ...
95+
'name_spec', nameSpec);
96+
end
97+
98+
nameSpec = map.cfg.segment.gm_norm;
99+
nameSpec.entities.res = res;
100+
nameSpec.entities.desc = ['smth' num2str(fwhm)];
101+
prefix = [map.smooth map.norm 'c1'];
102+
map = replaceMapping(map, prefix, nameSpec);
103+
104+
nameSpec = map.cfg.segment.wm_norm;
105+
nameSpec.entities.res = res;
106+
nameSpec.entities.desc = ['smth' num2str(fwhm)];
107+
prefix = [map.smooth map.norm 'c2'];
108+
map = replaceMapping(map, prefix, nameSpec);
109+
110+
end
111+
112+
map = map.flatten_mapping();
113+
114+
opt.spm_2_bids = map;
115+
116+
end
117+
118+
function map = replaceMapping(map, prefix, nameSpec)
119+
idx = map.find_mapping('prefix', prefix);
120+
map = map.rm_mapping(idx);
121+
map = map.add_mapping('prefix', prefix, ...
122+
'name_spec', nameSpec);
123+
end
124+
125+
function out = convertToStr(in)
126+
out = num2str(in);
127+
out = strrep(out, '.', 'pt');
128+
end

src/defaults/set_spm_2_bids_defaults.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
function opt = set_spm_2_bids_defaults(opt)
22
%
3-
% set default map for renaming for cpp_bids
3+
% set default map for renaming for cpp_spm
44
%
55
% USAGE::
66
%

src/infra/resizeAliMask.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function aliMask = resizeAliMask(opt)
2+
%
3+
% USAGE::
4+
%
5+
% aliMask = resizeAliMask(opt)
6+
%
7+
%
8+
% (C) Copyright 2022 CPP_SPM developers
9+
aliMask = fullfile(spm('dir'), 'toolbox', 'ALI', 'Mask_image', 'mask_controls_vox2mm.nii');
10+
11+
if opt.toolbox.ALI.unified_segmentation.step1vox ~= 2
12+
13+
voxdim = repmat(opt.toolbox.ALI.unified_segmentation.step1vox, [3, 1]);
14+
bb = nan(2, 3);
15+
ismask = true;
16+
resize_img(aliMask, voxdim, bb, ismask);
17+
18+
aliMask = fullfile(spm('dir'), ...
19+
'toolbox', ...
20+
'ALI', ...
21+
'Mask_image', ...
22+
['mask_controls_vox' num2str(voxdim(1)) 'mm.nii']);
23+
24+
movefile(fullfile(spm('dir'), 'toolbox', 'ALI', 'Mask_image', 'rmask_controls_vox2mm.nii'), ...
25+
aliMask);
26+
end
27+
28+
end

0 commit comments

Comments
 (0)