From b3629eceae1102434906f31728c5f5046b9c6e37 Mon Sep 17 00:00:00 2001 From: Ceren Date: Mon, 26 Apr 2021 17:53:24 +0200 Subject: [PATCH 1/8] related to the issue #365 --- src/batches/setBatchImageCalculation.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/batches/setBatchImageCalculation.m b/src/batches/setBatchImageCalculation.m index e350d6b6..bcacfeb8 100644 --- a/src/batches/setBatchImageCalculation.m +++ b/src/batches/setBatchImageCalculation.m @@ -27,6 +27,7 @@ matlabbatch{end}.spm.util.imcalc.output = output; matlabbatch{end}.spm.util.imcalc.outdir = { outDir }; matlabbatch{end}.spm.util.imcalc.expression = expression; + matlabbatch{end}.spm.util.imcalc.options.dtype = 16; % matlabbatch{1}.spm.util.imcalc.var = struct('name', {}, 'value', {}); % matlabbatch{1}.spm.util.imcalc.options.dmtx = 0; From b6e6c4f800b577f5778bc0c0b6dfd48b00619f5f Mon Sep 17 00:00:00 2001 From: CerenB Date: Sun, 4 Jul 2021 17:09:34 +0200 Subject: [PATCH 2/8] Update setBatchSkullStripping.m --- src/batches/setBatchSkullStripping.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/batches/setBatchSkullStripping.m b/src/batches/setBatchSkullStripping.m index 1af84b30..e279af60 100644 --- a/src/batches/setBatchSkullStripping.m +++ b/src/batches/setBatchSkullStripping.m @@ -121,7 +121,6 @@ matlabbatch{end}.spm.util.imcalc.expression = sprintf( ... '(i2+i3+i4)>%f', ... opt.skullstrip.threshold); - matlabbatch{end}.spm.util.imcalc.output = maskOutput; - + matlabbatch{end}.spm.util.imcalc.output = maskOutput; end From e0aecfe117f684a4bc8e666249a3ba28e7f8d043 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Aug 2021 08:04:38 +0000 Subject: [PATCH 3/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- lib/mancoreg/mancoregCallbacks.m | 12 ++++++------ src/batches/setBatchSkullStripping.m | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/mancoreg/mancoregCallbacks.m b/lib/mancoreg/mancoregCallbacks.m index c92167bf..40593bd5 100644 --- a/lib/mancoreg/mancoregCallbacks.m +++ b/lib/mancoreg/mancoregCallbacks.m @@ -64,7 +64,7 @@ function mancoregCallbacks(operation) function moveImage() - global st mancoregvar; + global st mancoregvar angl_pitch = get(mancoregvar.hpitch, 'Value'); angl_roll = get(mancoregvar.hroll, 'Value'); @@ -96,7 +96,7 @@ function moveImage() function toggleOff() - global st mancoregvar; + global st mancoregvar if get(mancoregvar.htoggle_off, 'value') == 0 % Source is to be displayed @@ -114,7 +114,7 @@ function toggleOff() function toggleOn() - global st mancoregvar; + global st mancoregvar if get(mancoregvar.htoggle_on, 'value') == 0 % Source is to be displayed @@ -135,7 +135,7 @@ function toggleOn() function resetTransformationMatrix() - global st mancoregvar; + global st mancoregvar set(mancoregvar.hpitch, 'Value', 0); set(mancoregvar.hroll, 'Value', 0); @@ -165,7 +165,7 @@ function resetTransformationMatrix() function applyTransformationMatrix() - global st mancoregvar; + global st mancoregvar angl_pitch = get(mancoregvar.hpitch, 'Value'); angl_roll = get(mancoregvar.hroll, 'Value'); @@ -218,7 +218,7 @@ function applyTransformationMatrix() function plotMat - global mancoregvar; + global mancoregvar angl_pitch = get(mancoregvar.hpitch, 'Value'); angl_roll = get(mancoregvar.hroll, 'Value'); diff --git a/src/batches/setBatchSkullStripping.m b/src/batches/setBatchSkullStripping.m index e279af60..8383f8d1 100644 --- a/src/batches/setBatchSkullStripping.m +++ b/src/batches/setBatchSkullStripping.m @@ -121,6 +121,6 @@ matlabbatch{end}.spm.util.imcalc.expression = sprintf( ... '(i2+i3+i4)>%f', ... opt.skullstrip.threshold); - matlabbatch{end}.spm.util.imcalc.output = maskOutput; + matlabbatch{end}.spm.util.imcalc.output = maskOutput; end From 1fcbb033b4af2df69f8eeae030c330ca63b3b35d Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 7 Aug 2021 10:38:48 +0200 Subject: [PATCH 4/8] add data type argin to setBatchImageCalculation --- src/batches/setBatchImageCalculation.m | 40 ++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/batches/setBatchImageCalculation.m b/src/batches/setBatchImageCalculation.m index bcacfeb8..b15c2b81 100644 --- a/src/batches/setBatchImageCalculation.m +++ b/src/batches/setBatchImageCalculation.m @@ -1,4 +1,4 @@ -function matlabbatch = setBatchImageCalculation(matlabbatch, input, output, outDir, expression) +function matlabbatch = setBatchImageCalculation(varargin) % % Set a batch for a image calculation % @@ -16,6 +16,22 @@ % :type outDir: string % :param expression: mathematical expression to apply (for example '(i1+i2)>3') % :type expression: string + % :param expression: data type that must be one of the following: + % - 'uint8' + % - 'int16' (default) + % - 'int32' + % - 'float32' + % - 'float64' + % - 'int8' + % - 'uint16' + % - 'uint32' + % :type expression: string + % + % See ``spm_cfg_imcalc.m`` for more information:: + % + % ``edit(fullfile(spm('dir'), 'config', 'spm_cfg_imcalc.m'))`` + % + % % % :returns: - :matlabbatch: % @@ -23,11 +39,31 @@ printBatchName('image calculation'); + [matlabbatch, input, output, outDir, expression, dataType] = deal(varargin{:}); + + if isempty(dataType) + dataType = 'int16'; + end + + allowedDataType = {'uint8', ... + 'int16', ... + 'int32', ... + 'float32', ... + 'float64', ... + 'int8', ... + 'uint16', ... + 'uint32'}; + + if ~ismember(dataType, allowedDataType) + fprintf(1, '\t%s\n', string(allowedDataType)); + error('dataType must be one of the type mentionned above.'); + end + matlabbatch{end + 1}.spm.util.imcalc.input = input; matlabbatch{end}.spm.util.imcalc.output = output; matlabbatch{end}.spm.util.imcalc.outdir = { outDir }; matlabbatch{end}.spm.util.imcalc.expression = expression; - matlabbatch{end}.spm.util.imcalc.options.dtype = 16; + matlabbatch{end}.spm.util.imcalc.options.dtype = spm_type(dataType); % matlabbatch{1}.spm.util.imcalc.var = struct('name', {}, 'value', {}); % matlabbatch{1}.spm.util.imcalc.options.dmtx = 0; From ce8ed4a63a4e218ae525615d8ddbe6c9c32aa6ba Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 7 Aug 2021 11:10:51 +0200 Subject: [PATCH 5/8] add input parser and refactor to setBatchImageCalculation --- src/batches/setBatchImageCalculation.m | 47 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/batches/setBatchImageCalculation.m b/src/batches/setBatchImageCalculation.m index b15c2b81..c127060d 100644 --- a/src/batches/setBatchImageCalculation.m +++ b/src/batches/setBatchImageCalculation.m @@ -39,12 +39,6 @@ printBatchName('image calculation'); - [matlabbatch, input, output, outDir, expression, dataType] = deal(varargin{:}); - - if isempty(dataType) - dataType = 'int16'; - end - allowedDataType = {'uint8', ... 'int16', ... 'int32', ... @@ -54,21 +48,38 @@ 'uint16', ... 'uint32'}; - if ~ismember(dataType, allowedDataType) + defaultDataType = 'int16'; + + p = inputParser; + + addRequired(p, 'matlabbatch', @iscell); + addRequired(p, 'input'); + addRequired(p, 'output', @ischar); + addRequired(p, 'outDir', @ischar); + addRequired(p, 'expression', @ischar); + addOptional(p, 'dataType', defaultDataType, @ischar); + + parse(p, varargin{:}); + + if ~ismember(p.Results.dataType, allowedDataType) fprintf(1, '\t%s\n', string(allowedDataType)); - error('dataType must be one of the type mentionned above.'); + errorStruct.identifier = [mfilename ':invalidDatatype']; + errorStruct.message = 'dataType must be one of the type mentionned above.'; + error(errorStruct); end - matlabbatch{end + 1}.spm.util.imcalc.input = input; - matlabbatch{end}.spm.util.imcalc.output = output; - matlabbatch{end}.spm.util.imcalc.outdir = { outDir }; - matlabbatch{end}.spm.util.imcalc.expression = expression; - matlabbatch{end}.spm.util.imcalc.options.dtype = spm_type(dataType); + imcalc.input = p.Results.input; + imcalc.output = p.Results.output; + imcalc.outdir = { p.Results.outDir }; + imcalc.expression = p.Results.expression; + imcalc.options.dtype = spm_type(p.Results.dataType); + + % imcalc.var = struct('name', {}, 'value', {}); + % imcalc.options.dmtx = 0; + % imcalc.options.mask = 0; + % imcalc.options.interp = 1; - % matlabbatch{1}.spm.util.imcalc.var = struct('name', {}, 'value', {}); - % matlabbatch{1}.spm.util.imcalc.options.dmtx = 0; - % matlabbatch{1}.spm.util.imcalc.options.mask = 0; - % matlabbatch{1}.spm.util.imcalc.options.interp = 1; - % matlabbatch{1}.spm.util.imcalc.options.dtype = 4; + matlabbatch = p.Results.matlabbatch; + matlabbatch{end + 1}.spm.util.imcalc = imcalc; end From 031e1a651d3c692d80a1bef17bbcc7d98fe23069 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 7 Aug 2021 11:11:11 +0200 Subject: [PATCH 6/8] update tests --- tests/test_setBatchImageCalculation.m | 15 ++++++++++++--- tests/test_setBatchMeanAnatAndMask.m | 4 +++- tests/test_setBatchSkullStripping.m | 5 ++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/test_setBatchImageCalculation.m b/tests/test_setBatchImageCalculation.m index 0e70d94c..a5ba9663 100644 --- a/tests/test_setBatchImageCalculation.m +++ b/tests/test_setBatchImageCalculation.m @@ -13,16 +13,25 @@ function test_setBatchImageCalculationBasic() input = {'sub-01_ses-01_T1w.nii'}; output = 'sub-01_ses-01_T1w_thres.nii'; outDir = pwd; - expression = 'i1 > 10'; + exp = 'i1 > 10'; - matlabbatch = []; - matlabbatch = setBatchImageCalculation(matlabbatch, input, output, outDir, expression); + matlabbatch = {}; + matlabbatch = setBatchImageCalculation(matlabbatch, input, output, outDir, exp, 'uint8'); expectedBatch{1}.spm.util.imcalc.input{1} = 'sub-01_ses-01_T1w.nii'; expectedBatch{end}.spm.util.imcalc.output = 'sub-01_ses-01_T1w_thres.nii'; expectedBatch{end}.spm.util.imcalc.outdir{1} = pwd; expectedBatch{end}.spm.util.imcalc.expression = 'i1 > 10'; + expectedBatch{end}.spm.util.imcalc.options.dtype = 2; assertEqual(matlabbatch, expectedBatch); + assertExceptionThrown( ... + @()setBatchImageCalculation(matlabbatch, ... + input, ... + output, ... + outDir, ... + exp, ... + 'test'), ... + 'setBatchImageCalculation:invalidDatatype'); end diff --git a/tests/test_setBatchMeanAnatAndMask.m b/tests/test_setBatchMeanAnatAndMask.m index 6b15f9fd..b466469e 100644 --- a/tests/test_setBatchMeanAnatAndMask.m +++ b/tests/test_setBatchMeanAnatAndMask.m @@ -15,7 +15,7 @@ function test_setBatchMeanAnatAndMaskBasic() opt = setOptions('vismotion'); opt.subjects = {'01', '02'}; - matlabbatch = []; + matlabbatch = {}; matlabbatch = setBatchMeanAnatAndMask(matlabbatch, opt, funcFWHM, pwd); % @@ -33,6 +33,7 @@ function test_setBatchMeanAnatAndMaskBasic() imcalc.output = 'meanAnat.nii'; imcalc.outdir{1} = pwd; imcalc.expression = '(i1+i2)/2'; + imcalc.options.dtype = 4; expectedBatch{1}.spm.util.imcalc = imcalc; @@ -50,6 +51,7 @@ function test_setBatchMeanAnatAndMaskBasic() imcalc.output = 'meanMask.nii'; imcalc.outdir{1} = pwd; imcalc.expression = '(i1+i2)>0.75*2'; + imcalc.options.dtype = 4; expectedBatch{2}.spm.util.imcalc = imcalc; diff --git a/tests/test_setBatchSkullStripping.m b/tests/test_setBatchSkullStripping.m index 921c227f..673b9e09 100644 --- a/tests/test_setBatchSkullStripping.m +++ b/tests/test_setBatchSkullStripping.m @@ -18,7 +18,7 @@ function test_setBatchSkullStrippingBasic() opt.orderBatches.segment = 2; - matlabbatch = []; + matlabbatch = {}; matlabbatch = setBatchSkullStripping(matlabbatch, BIDS, opt, subLabel); expectedBatch = returnExpectedBatch(opt); @@ -89,6 +89,8 @@ function test_setBatchSkullStrippingBasic() 'i1.*((i2+i3+i4)>%f)', ... opt.skullstrip.threshold); + expectedBatch{end}.spm.util.imcalc.options.dtype = 4; + % add a batch to output the mask expectedBatch{end + 1} = expectedBatch{end}; expectedBatch{end}.spm.util.imcalc.expression = sprintf( ... @@ -98,5 +100,6 @@ function test_setBatchSkullStrippingBasic() expectedFileName, ... '.nii', ... '_mask.nii')]; + expectedBatch{end}.spm.util.imcalc.options.dtype = 4; end From 3c40283b1099fe9550e54496c06c2dee45dc094c Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 7 Aug 2021 11:17:40 +0200 Subject: [PATCH 7/8] refactor test setBatchSkullStripping --- tests/test_setBatchSkullStripping.m | 120 ++++++++++++---------------- 1 file changed, 53 insertions(+), 67 deletions(-) diff --git a/tests/test_setBatchSkullStripping.m b/tests/test_setBatchSkullStripping.m index 673b9e09..d261a053 100644 --- a/tests/test_setBatchSkullStripping.m +++ b/tests/test_setBatchSkullStripping.m @@ -21,13 +21,13 @@ function test_setBatchSkullStrippingBasic() matlabbatch = {}; matlabbatch = setBatchSkullStripping(matlabbatch, BIDS, opt, subLabel); - expectedBatch = returnExpectedBatch(opt); + expected_batch = returnExpectedBatch(opt); - assertEqual(matlabbatch, expectedBatch); + assertEqual(matlabbatch, expected_batch); end -function expectedBatch = returnExpectedBatch(opt) +function expected_batch = returnExpectedBatch(opt) expectedFileName = 'sub-01_ses-01_T1w.nii'; @@ -35,71 +35,57 @@ function test_setBatchSkullStrippingBasic() 'dummyData', 'derivatives', 'cpp_spm', ... 'sub-01', 'ses-01', 'anat'); - expectedBatch = []; - expectedBatch{end + 1}.spm.util.imcalc.input(1) = ... - cfg_dep( ... - 'Segment: Bias Corrected (1)', ... - substruct( ... - '.', 'val', '{}', {2}, ... - '.', 'val', '{}', {1}, ... - '.', 'val', '{}', {1}), ... - substruct( ... - '.', 'channel', '()', {1}, ... - '.', 'biascorr', '()', {':'})); - - expectedBatch{end}.spm.util.imcalc.input(2) = ... - cfg_dep( ... - 'Segment: c1 Images', ... - substruct( ... - '.', 'val', '{}', {2}, ... - '.', 'val', '{}', {1}, ... - '.', 'val', '{}', {1}), ... - substruct( ... - '.', 'tiss', '()', {1}, ... - '.', 'c', '()', {':'})); - - expectedBatch{end}.spm.util.imcalc.input(3) = ... - cfg_dep( ... - 'Segment: c2 Images', ... - substruct( ... - '.', 'val', '{}', {2}, ... - '.', 'val', '{}', {1}, ... - '.', 'val', '{}', {1}), ... - substruct( ... - '.', 'tiss', '()', {2}, ... - '.', 'c', '()', {':'})); - expectedBatch{end}.spm.util.imcalc.input(4) = ... - cfg_dep( ... - 'Segment: c3 Images', ... - substruct( ... - '.', 'val', '{}', {2}, ... - '.', 'val', '{}', {1}, ... - '.', 'val', '{}', {1}), ... - substruct( ... - '.', 'tiss', '()', {3}, ... - '.', 'c', '()', {':'})); - - expectedBatch{end}.spm.util.imcalc.output = ['m' strrep( ... - expectedFileName, ... - '.nii', ... - '_skullstripped.nii')]; - expectedBatch{end}.spm.util.imcalc.outdir = {expectedAnatDataDir}; - - expectedBatch{end}.spm.util.imcalc.expression = sprintf( ... - 'i1.*((i2+i3+i4)>%f)', ... - opt.skullstrip.threshold); - - expectedBatch{end}.spm.util.imcalc.options.dtype = 4; + imcalc.input(1) = cfg_dep( ... + 'Segment: Bias Corrected (1)', ... + substruct( ... + '.', 'val', '{}', {2}, ... + '.', 'val', '{}', {1}, ... + '.', 'val', '{}', {1}), ... + substruct( ... + '.', 'channel', '()', {1}, ... + '.', 'biascorr', '()', {':'})); + + imcalc.input(2) = cfg_dep( ... + 'Segment: c1 Images', ... + substruct( ... + '.', 'val', '{}', {2}, ... + '.', 'val', '{}', {1}, ... + '.', 'val', '{}', {1}), ... + substruct( ... + '.', 'tiss', '()', {1}, ... + '.', 'c', '()', {':'})); + + imcalc.input(3) = cfg_dep( ... + 'Segment: c2 Images', ... + substruct( ... + '.', 'val', '{}', {2}, ... + '.', 'val', '{}', {1}, ... + '.', 'val', '{}', {1}), ... + substruct( ... + '.', 'tiss', '()', {2}, ... + '.', 'c', '()', {':'})); + imcalc.input(4) = cfg_dep( ... + 'Segment: c3 Images', ... + substruct( ... + '.', 'val', '{}', {2}, ... + '.', 'val', '{}', {1}, ... + '.', 'val', '{}', {1}), ... + substruct( ... + '.', 'tiss', '()', {3}, ... + '.', 'c', '()', {':'})); + + imcalc.output = ['m' strrep(expectedFileName, '.nii', '_skullstripped.nii')]; + imcalc.outdir = {expectedAnatDataDir}; + imcalc.expression = sprintf('i1.*((i2+i3+i4)>%f)', opt.skullstrip.threshold); + imcalc.options.dtype = 4; + + expected_batch = {}; + expected_batch{end + 1}.spm.util.imcalc = imcalc; % add a batch to output the mask - expectedBatch{end + 1} = expectedBatch{end}; - expectedBatch{end}.spm.util.imcalc.expression = sprintf( ... - '(i2+i3+i4)>%f', ... - opt.skullstrip.threshold); - expectedBatch{end}.spm.util.imcalc.output = ['m' strrep( ... - expectedFileName, ... - '.nii', ... - '_mask.nii')]; - expectedBatch{end}.spm.util.imcalc.options.dtype = 4; + imcalc.expression = sprintf('(i2+i3+i4)>%f', opt.skullstrip.threshold); + imcalc.output = ['m' strrep(expectedFileName, '.nii', '_mask.nii')]; + + expected_batch{end + 1}.spm.util.imcalc = imcalc; end From bf8d5be2d08d4d3305201745d9a5e6002123b6e8 Mon Sep 17 00:00:00 2001 From: Ceren Date: Fri, 13 Aug 2021 16:21:36 +0200 Subject: [PATCH 8/8] default value change in setBatchImageCalculation --- src/batches/setBatchImageCalculation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/batches/setBatchImageCalculation.m b/src/batches/setBatchImageCalculation.m index c127060d..8db1efd6 100644 --- a/src/batches/setBatchImageCalculation.m +++ b/src/batches/setBatchImageCalculation.m @@ -48,7 +48,7 @@ 'uint16', ... 'uint32'}; - defaultDataType = 'int16'; + defaultDataType = 'float32'; p = inputParser;