Skip to content

Commit c344dbb

Browse files
authored
Merge pull request #622 from cpp-lln-lab/olf
[ENH] add neuromorphometrics label to bidsResults output when in MNI space
2 parents 23b05f7 + 677445a commit c344dbb

File tree

5 files changed

+129
-1
lines changed

5 files changed

+129
-1
lines changed

src/utils/labelActivations.m

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
function tsvFile = labelActivations(varargin)
2+
%
3+
% Adds MNI labels to a csv output file from SPM
4+
%
5+
% USAGE::
6+
%
7+
% tsvFile = labelActivations(csvFile)
8+
%
9+
% :param csvFile:
10+
% :type csvFile: path
11+
%
12+
% :returns: - :tsvFile: (path)
13+
%
14+
% (C) Copyright 2022 CPP_SPM developers
15+
16+
% The code goes below
17+
18+
args = inputParser;
19+
20+
addRequired(args, 'csvFile', @ischar);
21+
22+
parse(args, varargin{:});
23+
24+
csvFile = args.Results.csvFile;
25+
26+
%% renaming headers to have only one row
27+
% combine 1rst and 2nd row
28+
CSV = bids.util.tsvread(csvFile);
29+
30+
headers = fieldnames(CSV);
31+
32+
columnIdx = @(x) find(~cellfun('isempty', regexp(headers, ['^' x '.*'], 'match')));
33+
coerce = @(x) regexprep(x, '[^a-zA-Z0-9_]', '_');
34+
35+
set = columnIdx('set');
36+
for i = 1:numel(set)
37+
newCSV.(['set_' coerce(CSV.(headers{set(i)}){1})]) = CSV.(headers{set(i)})(2:end);
38+
end
39+
40+
cluster = columnIdx('cluster');
41+
for i = 1:numel(cluster)
42+
newCSV.(['cluster_' coerce(CSV.(headers{cluster(i)}){1})]) = CSV.(headers{cluster(i)})(2:end);
43+
end
44+
45+
peak = columnIdx('peak');
46+
for i = 1:numel(peak)
47+
newCSV.(['peak_' coerce(CSV.(headers{peak(i)}){1})]) = CSV.(headers{peak(i)})(2:end);
48+
end
49+
50+
coordinates = columnIdx('x');
51+
label = {'x', 'y', 'z'};
52+
for i = 1:numel(coordinates)
53+
newCSV.(label{i}) = str2double(CSV.(headers{coordinates(i)})(2:end));
54+
end
55+
56+
%% add MNI label
57+
% L = spm_atlas('list');
58+
xA = spm_atlas('load', 'Neuromorphometrics');
59+
60+
for i = 1:numel(newCSV.x)
61+
newCSV.neuromorphometric_label{i} = spm_atlas('query', xA, [newCSV.x(i), ...
62+
newCSV.y(i), ...
63+
newCSV.z(i)]');
64+
end
65+
66+
tsvFile = bids.internal.file_utils(csvFile, 'ext', '.tsv');
67+
bids.util.tsvwrite(tsvFile, newCSV);
68+
69+
end

src/workflows/stats/bidsResults.m

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,12 @@
481481
end
482482

483483
function renameOutputResults(results)
484+
%
484485
% we create new name for the nifti output by removing the
485486
% spmT_XXXX prefix and using the XXXX as label- for the file
487+
%
488+
% also rename PNG and labels activations
489+
%
486490

487491
for i = 1:numel(results)
488492

@@ -510,13 +514,24 @@ function renameOutputResults(results)
510514

511515
renamePng(result.dir);
512516

517+
if result.csv && isMni(result.space)
518+
519+
csvFiles = spm_select('FPList', result.dir, '^spm_.*[0-9].csv$');
520+
521+
for iFile = 1:size(csvFiles, 1)
522+
source = deblank(csvFiles(iFile, :));
523+
labelActivations(source);
524+
end
525+
526+
end
527+
513528
end
514529

515530
end
516531

517532
function renameNidm(opt, result, subLabel)
518533
%
519-
% removes the _XXX suffix before the PNG extension.
534+
% removes the _XXX suffix before the nidm extension.
520535

521536
nidmFiles = spm_select('FPList', result.dir, '^spm_[0-9]{4}.nidm.zip$');
522537

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
set,set,cluster,cluster,cluster,cluster,peak,peak,peak,peak,peak,,,
2+
p,c,p(FWE-corr),p(FDR-corr),equivk,p(unc),p(FWE-corr),p(FDR-corr),T,equivZ,p(unc),x,y,z {mm}
3+
0.000,4,0.000,0.000,218,0.000,0.000,0.000, 12.15, Inf,0.000, 57,-22, 11
4+
,,,,,,0.000,0.000, 11.38, Inf,0.000, 66,-13, -4
5+
,,,,,,0.000,0.003, 7.02, 6.05,0.000, 60,-37, 5
6+
,,0.000,0.000,401,0.000,0.000,0.000, 12.11, Inf,0.000,-63,-28, 11
7+
,,,,,,0.000,0.000, 11.31, Inf,0.000,-45,-34, 11
8+
,,,,,,0.000,0.000, 10.10, 7.84,0.000,-66,-10, -1
9+
,,0.001,0.016,5,0.012,0.005,0.161, 5.86, 5.24,0.000, 69,-25, -4
10+
,,0.015,0.219,1,0.219,0.032,0.684, 5.40, 4.90,0.000, 51, 5, -7
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
set_p set_c cluster_p_FWE_corr_ cluster_p_FDR_corr_ cluster_equivk cluster_p_unc_ peak_p_FWE_corr_ peak_p_FDR_corr_ peak_T peak_equivZ peak_p_unc_ x y z neuromorphometric_label
2+
0.000 4 0.000 0.000 218 0.000 0.000 0.000 12.15 Inf 0.000 57 -22 11 Right PT planum temporale
3+
n/a n/a n/a n/a n/a n/a 0.000 0.000 11.38 Inf 0.000 66 -13 -4 Right STG superior temporal gyrus
4+
n/a n/a n/a n/a n/a n/a 0.000 0.003 7.02 6.05 0.000 60 -37 5 Right MTG middle temporal gyrus
5+
n/a n/a 0.000 0.000 401 0.000 0.000 0.000 12.11 Inf 0.000 -63 -28 11 Left PT planum temporale
6+
n/a n/a n/a n/a n/a n/a 0.000 0.000 11.31 Inf 0.000 -45 -34 11 Left PT planum temporale
7+
n/a n/a n/a n/a n/a n/a 0.000 0.000 10.10 7.84 0.000 -66 -10 -1 Left STG superior temporal gyrus
8+
n/a n/a 0.001 0.016 5 0.012 0.005 0.161 5.86 5.24 0.000 69 -25 -4 Right MTG middle temporal gyrus
9+
n/a n/a 0.015 0.219 1 0.219 0.032 0.684 5.40 4.90 0.000 51 5 -7 Right PP planum polare
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function test_suite = test_labelActivations %#ok<*STOUT>
2+
% (C) Copyright 2022 CPP_SPM developers
3+
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
4+
test_functions = localfunctions(); %#ok<*NASGU>
5+
catch % no problem; early Matlab versions can use initTestSuite fine
6+
end
7+
initTestSuite;
8+
end
9+
10+
function test_labelActivations_basic()
11+
12+
csvFile = fullfile(getDummyDataDir(), 'tsv_files', 'moae_results_table.csv');
13+
14+
tsvFile = labelActivations(csvFile);
15+
16+
assertEqual(exist(tsvFile, 'file'), 2);
17+
18+
expectedFile = fullfile(getDummyDataDir(), 'tsv_files', 'moae_results_table.tsv');
19+
expectedContent = bids.util.tsvread(expectedFile);
20+
21+
content = bids.util.tsvread(tsvFile);
22+
23+
assertEqual(content, expectedContent);
24+
25+
end

0 commit comments

Comments
 (0)