Skip to content
12 changes: 6 additions & 6 deletions lib/mancoreg/mancoregCallbacks.m
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand All @@ -135,7 +135,7 @@ function toggleOn()

function resetTransformationMatrix()

global st mancoregvar;
global st mancoregvar

set(mancoregvar.hpitch, 'Value', 0);
set(mancoregvar.hroll, 'Value', 0);
Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -218,7 +218,7 @@ function applyTransformationMatrix()

function plotMat

global mancoregvar;
global mancoregvar

angl_pitch = get(mancoregvar.hpitch, 'Value');
angl_roll = get(mancoregvar.hroll, 'Value');
Expand Down
68 changes: 58 additions & 10 deletions src/batches/setBatchImageCalculation.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function matlabbatch = setBatchImageCalculation(matlabbatch, input, output, outDir, expression)
function matlabbatch = setBatchImageCalculation(varargin)
%
% Set a batch for a image calculation
%
Expand All @@ -16,22 +16,70 @@
% :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:
%
% (C) Copyright 2020 CPP_SPM developers

printBatchName('image calculation');

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;
allowedDataType = {'uint8', ...
'int16', ...
'int32', ...
'float32', ...
'float64', ...
'int8', ...
'uint16', ...
'uint32'};

defaultDataType = 'float32';

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));
errorStruct.identifier = [mfilename ':invalidDatatype'];
errorStruct.message = 'dataType must be one of the type mentionned above.';
error(errorStruct);
end

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
15 changes: 12 additions & 3 deletions tests/test_setBatchImageCalculation.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 3 additions & 1 deletion tests/test_setBatchMeanAnatAndMask.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function test_setBatchMeanAnatAndMaskBasic()
opt = setOptions('vismotion');
opt.subjects = {'01', '02'};

matlabbatch = [];
matlabbatch = {};
matlabbatch = setBatchMeanAnatAndMask(matlabbatch, opt, funcFWHM, pwd);

%
Expand All @@ -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;

Expand All @@ -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;

Expand Down
119 changes: 54 additions & 65 deletions tests/test_setBatchSkullStripping.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,85 +18,74 @@ function test_setBatchSkullStrippingBasic()

opt.orderBatches.segment = 2;

matlabbatch = [];
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';

expectedAnatDataDir = fullfile(fileparts(mfilename('fullpath')), ...
'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);
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')];
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