Skip to content

Commit cba8893

Browse files
committed
add deformation field in sources for norlaized images
1 parent 9ec4d4a commit cba8893

File tree

10 files changed

+123
-52
lines changed

10 files changed

+123
-52
lines changed

init_spm_2_bids.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353

5454
end
5555

56-
% TODO check if bids-matlab is there ?
5756
add_dependencies();
5857

5958
disp('Correct matlab/octave verions and added to the path!');

miss_hit.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ copyright_entity: "spm_2_bids developers"
1717
# metric for code quality
1818
metric "cnest": limit 5
1919
metric "file_length": limit 500
20-
metric "cyc": limit 16
20+
metric "cyc": limit 20
2121
metric "parameters": limit 6

src/defaults/check_cfg.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@
6666

6767
SPM_SPACE = 'IXI549Space';
6868

69+
% TODO DARTEL uses
70+
% MNI152NLin2009[a-c][Sym|Asym]
71+
%
72+
% See section: standard-template-identifiers of
73+
% https://bids-specification.readthedocs.io/en/latest/99-appendices/08-coordinate-systems.html
74+
6975
fields_to_set.space = SPM_SPACE;
7076

7177
% just to keep track of all the BIDS entities in the cfg

src/spm_2_bids.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@
141141

142142
json = bids.derivatives_json(bf.filename);
143143

144-
json.content.RawSources{1} = identify_rawsources(file, verbose);
145-
json.content.Sources{1} = identify_sources(file, map, verbose);
144+
json.content.RawSources = identify_rawsources(file, verbose);
145+
json.content.Sources = identify_sources(file, map, verbose);
146146

147147
end
148148

src/utils/identify_rawsources.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@
4343

4444
bf.prefix = '';
4545

46-
rawsource = fullfile(bf.bids_path, bf.filename);
46+
rawsource{1} = fullfile(bf.bids_path, bf.filename);
4747

4848
end

src/utils/identify_sources.m

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,39 @@
1919
% 'sra'
2020
% 'wr'
2121
% 'wra'
22+
% those will throw warnings
2223

23-
% TODO mean may involve several files from the source (across runs
24-
% and sessions
25-
% prefixes = {
26-
% 'mean'
27-
% 'meanu'
28-
% 'meanua'
29-
% 'wmeanu'
30-
% };
24+
% TODO
25+
% functional to anatomical coregistration
26+
% anatomical to functional coregistration
3127

3228
sources = '';
3329

3430
prefix_based = true;
3531

32+
add_deformation_field = false;
33+
deformation_field = 'TODO: add deformation field';
34+
35+
% TODO? grab all the anat suffixes from BIDS schema?
36+
covered_suffixes = {'T1w', ...
37+
'T2w', ...
38+
'PDw', ...
39+
'T2starw', ...
40+
'inplaneT1', ...
41+
'inplaneT2', ...
42+
'PD', ...
43+
'PDT2', ...
44+
'T2star', ...
45+
'FLASH', ...
46+
'T1map', ...
47+
'T2map', ...
48+
'T2starmap', ...
49+
'R1map', ...
50+
'R2map', ...
51+
'R2starmap', ...
52+
'PDmap', ...
53+
'UNIT1'};
54+
3655
if nargin < 1 || isempty(derivatives)
3756
return
3857
end
@@ -63,6 +82,7 @@
6382
bf = bids.File(derivatives, 'verbose', verbose, 'use_schema', false);
6483

6584
if prefix_based
85+
6686
if numel(bf.prefix) < 2
6787

6888
% needs at least 2 characters for this file to have some provenance in the
@@ -76,8 +96,12 @@
7696
else
7797
% remove the prefix of the last step
7898

79-
if startsWith(bf.prefix, 's') || startsWith(bf.prefix, 'w')
99+
if startsWith(bf.prefix, 's') || startsWith(bf.prefix, 'u')
100+
bf.prefix = bf.prefix(2:end);
101+
102+
elseif startsWith(bf.prefix, 'w')
80103
bf.prefix = bf.prefix(2:end);
104+
add_deformation_field = true;
81105

82106
elseif startsWith(bf.prefix, 'rp_a')
83107
bf.prefix = bf.prefix(4:end);
@@ -102,8 +126,29 @@
102126
end
103127

104128
% call spm_2_bids what is the filename from the previous step
105-
[new_filename] = spm_2_bids(bf.filename, map, verbose);
129+
new_filename = spm_2_bids(bf.filename, map, verbose);
130+
131+
sources{1, 1} = fullfile(bf.bids_path, new_filename);
132+
133+
if add_deformation_field
134+
135+
% for anatomical data we assume that
136+
% the deformation field comes from the anatomical file itself
137+
if (~isempty(bf.modality) && ismember(bf.modality, {'anat'})) || ...
138+
(~isempty(bf.suffix) && ismember(bf.suffix, covered_suffixes))
106139

107-
sources = fullfile(bf.bids_path, new_filename);
140+
bf.prefix = 'y_';
141+
bf = bf.update;
142+
new_filename = spm_2_bids(bf.filename, map, verbose);
143+
deformation_field = fullfile(bf.bids_path, new_filename);
144+
145+
% otherwise we can't guess it just from the file name
146+
else
147+
148+
end
149+
150+
sources{2, 1} = deformation_field;
151+
152+
end
108153

109154
end

tests/test_identify_rawsources.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function test_identify_rawsources_suffix()
1919

2020
rawsource = identify_rawsources(input_output{i, 1}, verbose);
2121

22-
assertEqual(rawsource, ['sub-01/' input_output{i, 2}]);
22+
assertEqual(rawsource, {['sub-01/' input_output{i, 2}]});
2323

2424
end
2525

@@ -50,7 +50,7 @@ function test_identify_rawsources_anat()
5050

5151
rawsource = identify_rawsources(fullfile(pwd, 'sub-01', file), verbose);
5252

53-
assertEqual(rawsource, 'sub-01/sub-01_T1w.nii');
53+
assertEqual(rawsource, {'sub-01/sub-01_T1w.nii'});
5454

5555
end
5656

@@ -89,7 +89,7 @@ function test_identify_rawsources_func()
8989

9090
rawsource = identify_rawsources(file, verbose);
9191

92-
assertEqual(rawsource, 'sub-01/ses-02/sub-01_ses-02_task-foo_bold.nii');
92+
assertEqual(rawsource, {'sub-01/ses-02/sub-01_ses-02_task-foo_bold.nii'});
9393

9494
end
9595

tests/test_identify_sources.m

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,69 +8,69 @@
88
initTestSuite;
99
end
1010

11-
function test_identify_sources_mean()
11+
function test_identify_sources_func()
1212

1313
func_file = 'sub-01_task-auditory_bold.nii';
1414

1515
prefix_output = {
16-
'wmeanua', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
17-
'wmeanu', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
18-
'wmeanau', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
16+
'ua', 'sub-01_task-auditory_space-individual_desc-stc_bold.nii'
17+
'rp_a', 'sub-01_task-auditory_space-individual_desc-stc_bold.nii'
18+
'wua', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
19+
'wu', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
20+
'sw', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
21+
'swua', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
22+
'swu', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
23+
'swr', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
24+
'swra', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
25+
'sua', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
26+
'su', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
1927
};
2028

2129
for i = 1:size(prefix_output, 1)
2230

2331
sources = identify_sources([prefix_output{i, 1} func_file], [], false);
2432

25-
assertEqual(sources, fullfile('sub-01', prefix_output{i, 2}));
33+
assertEqual(sources{1}, fullfile('sub-01', prefix_output{i, 2}));
2634

2735
end
2836

2937
end
3038

31-
function test_identify_sources_anat()
39+
function test_identify_sources_mean()
3240

33-
anat_file = 'sub-01_T1w.nii';
41+
func_file = 'sub-01_task-auditory_bold.nii';
3442

35-
prefix_output = {'wm', 'sub-01/sub-01_space-individual_desc-biascor_T1w.nii'
36-
'wc1', 'sub-01/sub-01_space-individual_label-GM_probseg.nii'
37-
'wc2', 'sub-01/sub-01_space-individual_label-WM_probseg.nii'
38-
'wc3', 'sub-01/sub-01_space-individual_label-CSF_probseg.nii'
43+
prefix_output = {
44+
'wmeanua', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
45+
'wmeanu', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
46+
'wmeanau', 'sub-01_task-auditory_space-individual_desc-mean_bold.nii'
3947
};
4048

4149
for i = 1:size(prefix_output, 1)
4250

43-
sources = identify_sources([prefix_output{i, 1} anat_file], [], false);
51+
sources = identify_sources([prefix_output{i, 1} func_file], [], false);
4452

45-
assertEqual(sources, prefix_output{i, 2});
53+
assertEqual(sources{1}, fullfile('sub-01', prefix_output{i, 2}));
4654

4755
end
4856

4957
end
5058

51-
function test_identify_sources_func()
59+
function test_identify_sources_anat()
5260

53-
func_file = 'sub-01_task-auditory_bold.nii';
61+
anat_file = 'sub-01_T1w.nii';
5462

55-
prefix_output = {
56-
'rp_a', 'sub-01_task-auditory_space-individual_desc-stc_bold.nii'
57-
'wua', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
58-
'wu', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
59-
'sw', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
60-
'swua', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
61-
'swu', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
62-
'swr', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
63-
'swra', 'sub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii'
64-
'sua', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
65-
'su', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
66-
'su', 'sub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii'
63+
prefix_output = {'wm', 'sub-01/sub-01_space-individual_desc-biascor_T1w.nii'
64+
'wc1', 'sub-01/sub-01_space-individual_label-GM_probseg.nii'
65+
'wc2', 'sub-01/sub-01_space-individual_label-WM_probseg.nii'
66+
'wc3', 'sub-01/sub-01_space-individual_label-CSF_probseg.nii'
6767
};
6868

6969
for i = 1:size(prefix_output, 1)
7070

71-
sources = identify_sources([prefix_output{i, 1} func_file], [], false);
71+
sources = identify_sources([prefix_output{i, 1} anat_file], [], false);
7272

73-
assertEqual(sources, fullfile('sub-01', prefix_output{i, 2}));
73+
assertEqual(sources{1}, prefix_output{i, 2});
7474

7575
end
7676

@@ -87,7 +87,7 @@ function test_identify_sources_suffix()
8787

8888
sources = identify_sources(input_output{i, 1}, [], false);
8989

90-
assertEqual(sources, ['sub-01/' input_output{i, 2}]);
90+
assertEqual(sources{1}, ['sub-01/' input_output{i, 2}]);
9191

9292
end
9393

tests/test_spm_2_bids.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function test_spm_2_bids_order_entities()
1818

1919
function test_spm_2_bids_suffix()
2020

21-
input_output = {'sub-01_T1w_seg8.mat', 'sub-01_label-T1w_segparam.mat'
21+
input_output = {'sub-01_T1w_seg8.mat', 'sub-01_label-T1w_segparam.mat'
2222
'sub-01_task-foo_bold_uw.mat', 'sub-01_task-foo_label-bold_unwarpparam.mat'};
2323

2424
for i = 1:numel(size(input_output, 1))

tests/test_spm_2_bids_metadata.m

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,35 @@
88
initTestSuite;
99
end
1010

11-
function test_spm_2_bids_metadata_basic()
11+
function test_spm_2_bids_metadata_anat()
1212

1313
file = 'wmsub-01_T1w.nii';
1414

1515
[~, ~, json] = spm_2_bids(file, [], false);
1616

1717
assertEqual(fieldnames(json), {'filename'; 'content'});
1818
assertEqual(json.content.RawSources{1}, 'sub-01/sub-01_T1w.nii');
19-
assertEqual(json.content.Sources{1}, 'sub-01/sub-01_space-individual_desc-biascor_T1w.nii');
19+
assertEqual(json.content.Sources{1}, ...
20+
'sub-01/sub-01_space-individual_desc-biascor_T1w.nii');
21+
assertEqual(json.content.Sources{2}, ...
22+
'sub-01/sub-01_from-T1w_to-IXI549Space_mode-image_xfm.nii');
23+
24+
% bids.util.jsonencode(json.filename, json.content);
25+
26+
end
27+
28+
function test_spm_2_bids_metadata_func()
29+
30+
file = 'wuasub-01_task-foo_bold.nii';
31+
32+
[~, ~, json] = spm_2_bids(file, [], false);
33+
34+
assertEqual(fieldnames(json), {'filename'; 'content'});
35+
assertEqual(json.content.RawSources{1}, 'sub-01/sub-01_task-foo_bold.nii');
36+
assertEqual(json.content.Sources{1}, ...
37+
'sub-01/sub-01_task-foo_space-individual_desc-realignUnwarp_bold.nii');
38+
assertEqual(json.content.Sources{2}, 'TODO: add deformation field');
39+
40+
% bids.util.jsonencode(json.filename, json.content);
2041

2142
end

0 commit comments

Comments
 (0)