Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
40 changes: 30 additions & 10 deletions src/batches/setBatchSTC.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
function matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel)
function matlabbatch = setBatchSTC(varargin)
%
% Creates batch for slice timing correction
%
% USAGE::
%
% matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subID)
% matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel)
%
% :param BIDS: BIDS layout returned by ``getData``.
% :type BIDS: structure
Expand All @@ -30,6 +30,24 @@
%
% (C) Copyright 2019 CPP_SPM developers

p = inputParser;

addRequired(p, 'matlabbatch', @iscell);
addRequired(p, 'BIDS', @isstruct);
addRequired(p, 'opt', @isstruct);
addRequired(p, 'subLabel', @ischar);

parse(p, varargin{:});

matlabbatch = p.Results.matlabbatch;
BIDS = p.Results.BIDS;
opt = p.Results.opt;
subLabel = p.Results.subLabel;

if opt.stc.skip
return
end

% get slice order
sliceOrder = getSliceOrder(opt, 1);
if isempty(sliceOrder)
Expand All @@ -55,10 +73,10 @@

maxSliceTime = max(sliceOrder);
minSliceTime = min(sliceOrder);
if isempty(opt.STC_referenceSlice)
if isempty(opt.stc.referenceSlice)
referenceSlice = (maxSliceTime - minSliceTime) / 2;
else
referenceSlice = opt.STC_referenceSlice;
referenceSlice = opt.stc.referenceSlice;
end
if TA >= TR || referenceSlice > TA || any(sliceOrder > TA)

Expand All @@ -80,11 +98,11 @@
error(errorStruct);
end

matlabbatch{end + 1}.spm.temporal.st.nslices = nbSlices;
matlabbatch{end}.spm.temporal.st.tr = TR;
matlabbatch{end}.spm.temporal.st.ta = TA;
matlabbatch{end}.spm.temporal.st.so = sliceOrder * 1000;
matlabbatch{end}.spm.temporal.st.refslice = referenceSlice * 1000;
temporal.st.nslices = nbSlices;
temporal.st.tr = TR;
temporal.st.ta = TA;
temporal.st.so = sliceOrder * 1000;
temporal.st.refslice = referenceSlice * 1000;

[sessions, nbSessions] = getInfo(BIDS, subLabel, opt, 'Sessions');

Expand All @@ -106,7 +124,7 @@
file = validationInputFile(subFuncDataDir, fileName);

% add the file to the list
matlabbatch{end}.spm.temporal.st.scans{runCounter} = {file};
temporal.st.scans{runCounter} = {file};

runCounter = runCounter + 1;

Expand All @@ -116,6 +134,8 @@

end

matlabbatch{end + 1}.spm.temporal = temporal;

% The following lines are commented out because those parameters
% can be set in the spm_my_defaults.m
% matlabbatch{1}.spm.temporal.st.prefix = spm_get_defaults('slicetiming.prefix');
Expand Down
4 changes: 2 additions & 2 deletions src/batches/setBatchSubjectLevelGLMSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@
% If no reference slice is given for STC, then STC took the mid-volume
% time point to do the correction.
% When no STC was done, this is usually a good way to do it too.
if isempty(opt.STC_referenceSlice)
if isempty(opt.stc.referenceSlice)
refBin = floor(nbTimeBins / 2);
else
refBin = opt.STC_referenceSlice / opt.metadata.RepetitionTime;
refBin = opt.stc.referenceSlice / opt.metadata.RepetitionTime;
end
matlabbatch{end}.spm.stats.fmri_spec.timing.fmri_t0 = refBin;

Expand Down
16 changes: 9 additions & 7 deletions src/defaults/checkOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@
% will be included in the mask.
% - ``opt.funcVoxelDims = []`` - Voxel dimensions to use for resampling of functional data
% at normalization.
% - ``opt.STC_referenceSlice = []`` - reference slice for the slice timing correction.
% - ``opt.stc.skip = false`` - boolean flag to skip slice time correction or not.
% - ``opt.stc.referenceSlice = []`` - reference slice for the slice timing correction.
% If left emtpy the mid-volume acquisition time point will be selected at run time.
% - ``opt.sliceOrder = []`` - To be used if SPM can't extract slice info. NOT RECOMMENDED,
% - ``opt.stc.sliceOrder = []`` - To be used if SPM can't extract slice info. NOT RECOMMENDED,
% if you know the order in which slices were acquired, you should be able to recompute
% slice timing and add it to the json files in your BIDS data set.
% - ``opt.glm.roibased.do``
Expand Down Expand Up @@ -112,8 +113,9 @@

%% Options for slice time correction
% all in seconds
fieldsToSet.STC_referenceSlice = [];
fieldsToSet.sliceOrder = [];
fieldsToSet.stc.referenceSlice = [];
fieldsToSet.stc.sliceOrder = [];
fieldsToSet.stc.skip = false;

%% Options for realign
fieldsToSet.realign.useUnwarp = true;
Expand Down Expand Up @@ -173,13 +175,13 @@ function checkFields(opt)

end

if ~isempty (opt.STC_referenceSlice) && length(opt.STC_referenceSlice) > 1
if ~isempty (opt.stc.referenceSlice) && length(opt.stc.referenceSlice) > 1

errorStruct.identifier = 'checkOptions:refSliceNotScalar';
errorStruct.message = sprintf( ...
['options.STC_referenceSlice should be a scalar.' ...
['options.stc.referenceSlice should be a scalar.' ...
'\nCurrent value is: %d'], ...
opt.STC_referenceSlice);
opt.stc.referenceSlice);
error(errorStruct);

end
Expand Down
7 changes: 4 additions & 3 deletions src/getPrefix.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,10 @@
function prefix = prefixForSTC(prefix, opt)
% Check the slice timing information is not in the metadata and not added
% manually in the opt variable.
if (isfield(opt.metadata, 'SliceTiming') && ...
~isempty(opt.metadata.SliceTiming)) || ...
~isempty(opt.sliceOrder)
if ~opt.stc.skip && ...
((isfield(opt.metadata, 'SliceTiming') && ...
~isempty(opt.metadata.SliceTiming)) || ...
~isempty(opt.stc.sliceOrder))
prefix = [spm_get_defaults('slicetiming.prefix') prefix];
end
end
4 changes: 2 additions & 2 deletions src/getSliceOrder.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
% If slice timing information is not in the metadata, you have the option
% to add the slice order manually in the "opt" in the "getOptions"
% function
if ~isempty(opt.sliceOrder)
sliceOrder = opt.sliceOrder;
if ~isempty(opt.stc.sliceOrder)
sliceOrder = opt.stc.sliceOrder;

msg{end + 1} = ' SLICE TIMING INFORMATION EXTRACTED FROM OPTIONS.\n\n';

Expand Down
2 changes: 1 addition & 1 deletion tests/test_checkOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function test_checkOptionsErrorGroup()

function test_checkOptionsErrorRefSlice()

opt.STC_referenceSlice = [1:10];
opt.stc.referenceSlice = [1:10];
opt.taskName = 'testTask';

assertExceptionThrown( ...
Expand Down
57 changes: 37 additions & 20 deletions tests/test_setBatchSTC.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@
initTestSuite;
end

function test_setBatchSTCSkip()

subLabel = '02';

opt = setOptions('vislocalizer', subLabel);

[BIDS, opt] = getData(opt);

opt.stc.skip = true;

matlabbatch = {};
matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel);
assertEqual(matlabbatch, {});

end

function test_setBatchSTCEmpty()

subLabel = '02';
Expand All @@ -16,11 +32,11 @@ function test_setBatchSTCEmpty()

[BIDS, opt] = getData(opt);

matlabbatch = [];
matlabbatch = {};
matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel);

% no slice timing info for this run so nothing should be returned.
assertEqual(matlabbatch, []);
assertEqual(matlabbatch, {});

end

Expand All @@ -31,19 +47,19 @@ function test_setBatchSTCForce()
opt = setOptions('vislocalizer', subLabel);

% we give it some slice timing value to force slice timing to happen
opt.sliceOrder = linspace(0, 1.6, 10);
opt.sliceOrder(end - 1:end) = [];
opt.STC_referenceSlice = 1.6 / 2;
opt.stc.sliceOrder = linspace(0, 1.6, 10);
opt.stc.sliceOrder(end - 1:end) = [];
opt.stc.referenceSlice = 1.6 / 2;

opt = checkOptions(opt);

[BIDS, opt] = getData(opt);

matlabbatch = [];
matlabbatch = {};
matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel);

TR = 1.55;
expectedBatch = returnExpectedBatch(opt.sliceOrder, opt.STC_referenceSlice, TR);
expectedBatch = returnExpectedBatch(opt.stc.sliceOrder, opt.stc.referenceSlice, TR);

runCounter = 1;
for iSes = 1:2
Expand All @@ -69,17 +85,17 @@ function test_setBatchSTCBasic()

[BIDS, opt] = getData(opt);

matlabbatch = [];
matlabbatch = {};
matlabbatch = setBatchSTC(matlabbatch, BIDS, opt, subLabel);

TR = 1.5;
sliceOrder = repmat([ ...
0.5475, 0, 0.3825, 0.055, 0.4375, 0.11, 0.4925, 0.22, 0.6025, ...
0.275, 0.6575, ...
0.3275, 0.71, 0.165], 1, 3)';
STC_referenceSlice = 0.355;
referenceSlice = 0.355;

expectedBatch = returnExpectedBatch(sliceOrder, STC_referenceSlice, TR);
expectedBatch = returnExpectedBatch(sliceOrder, referenceSlice, TR);

runCounter = 1;
for iSes = 1:2
Expand All @@ -106,14 +122,13 @@ function test_setBatchSTCErrorInvalidInputTime()

opt = setOptions('vislocalizer', subLabel);

opt.sliceOrder = linspace(0, 1.6, 10);
opt.sliceOrder(end) = [];
opt.STC_referenceSlice = 2; % impossible reference value
opt.stc.sliceOrder = linspace(0, 1.6, 10);
opt.stc.sliceOrder(end) = [];
opt.stc.referenceSlice = 2; % impossible reference value

[BIDS, opt] = getData(opt);

matlabbatch = [];

matlabbatch = {};
assertExceptionThrown( ...
@()setBatchSTC(matlabbatch, BIDS, opt, subLabel), ...
'setBatchSTC:invalidInputTime');
Expand All @@ -126,10 +141,12 @@ function test_setBatchSTCErrorInvalidInputTime()
TA = TR - (TR / nbSlices);
TA = ceil(TA * 1000) / 1000;

expectedBatch{1}.spm.temporal.st.nslices = nbSlices;
expectedBatch{1}.spm.temporal.st.tr = TR;
expectedBatch{1}.spm.temporal.st.ta = TA;
expectedBatch{1}.spm.temporal.st.so = sliceOrder * 1000;
expectedBatch{1}.spm.temporal.st.refslice = referenceSlice * 1000;
temporal.st.nslices = nbSlices;
temporal.st.tr = TR;
temporal.st.ta = TA;
temporal.st.so = sliceOrder * 1000;
temporal.st.refslice = referenceSlice * 1000;

expectedBatch{1}.spm.temporal = temporal;

end
Loading