Skip to content

Commit

Permalink
[FIX] Reduce warnings (#1125)
Browse files Browse the repository at this point in the history
* do not create dir when returning subject level glm dir name

* get all data in circle ci

* change octache templates

* update bids matlab

* reduce warnings in test

* reuce warnings

* fix tests

* reduce number of model to select in bms

* Update demos/MoAE/test_moae.m

* improve warning

* override opt.space with arguments

* toggle
  • Loading branch information
Remi-Gau authored Aug 12, 2023
1 parent b7ebdc9 commit 35397c0
Show file tree
Hide file tree
Showing 31 changed files with 214 additions and 111 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ jobs:
datalad get sub-0[1-2]/anat/*MNI*mask.nii.gz \
sub-0[1-2]/anat/*MNI*T1w.nii.gz \
sub-0[1-2]/func/*MNI*desc-preproc*bold.nii.gz \
sub-0[1-2]/func/*MNI*mask.nii.gz \
sub-*/func/*tsv \
sub-*/func/*json -J 12
datalad status
Expand Down
16 changes: 15 additions & 1 deletion demos/bayes/ds000114_run.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

models_dir = fullfile(root_dir, 'models');

participant_label = {'[0-9]*'};
participant_label = {'[0-9]*'}; %#ok<*NASGU>
if TESTING
participant_label = {'^0[12]$'};
end
Expand Down Expand Up @@ -56,6 +56,14 @@
mutliverse.wm_csf = {'none', 'basic', 'full'};
mutliverse.non_steady_state = [false, true];

if TESTING
mutliverse.strategy = {'motion', 'wm_csf', 'scrub', 'non_steady_state'};
mutliverse.motion = {'none', 'basic'};
mutliverse.scrub = [false, true];
mutliverse.wm_csf = {'none'};
mutliverse.non_steady_state = false;
end

create_model_families(models_dir, default_model_file, mutliverse);

%% Statistics
Expand Down Expand Up @@ -92,6 +100,12 @@ function create_model_families(models_dir, default_model_file, mutliverse)
% TODO incorporate into bidspm

% TODO add support for 12 motion regressors
strategyToSkip = fieldnames(mutliverse);
idxStrategyToSkip = ~ismember(fieldnames(mutliverse), mutliverse.strategy);
strategyToSkip = strategyToSkip(idxStrategyToSkip);
for i = 1:numel(strategyToSkip)
mutliverse.(strategyToSkip{i}) = {''};
end

for i = 1:numel(mutliverse.motion)
for j = 1:numel(mutliverse.scrub)
Expand Down
2 changes: 1 addition & 1 deletion lib/bids-matlab
Submodule bids-matlab updated 1 files
+5 −1 +bids/query.m
31 changes: 22 additions & 9 deletions src/batches/preproc/setBatchSmoothingFunc.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function [matlabbatch, allRT] = setBatchSmoothingFunc(matlabbatch, BIDS, opt, subLabel)
function [matlabbatch, srcMetadata] = setBatchSmoothingFunc(matlabbatch, BIDS, opt, subLabel)
%
% Creates a batch to smooth the bold files of a subject
%
Expand Down Expand Up @@ -42,7 +42,7 @@
[sessions, nbSessions] = getInfo(BIDS, subLabel, opt, 'Sessions');

allFiles = [];
allRT = [];
srcMetadata = struct('RepetitionTime', [], 'SliceTimingCorrected', []);

for iSes = 1:nbSessions

Expand All @@ -66,15 +66,10 @@
for iFile = 1:size(fileName, 1)
files{iFile, 1} = validationInputFile(subFuncDataDir(iFile, :), ...
fileName(iFile, :)); %#ok<*AGROW>

if isfield(metadata{iFile}, 'RepetitionTime')
allRT(end + 1) = metadata{iFile}.RepetitionTime;
else
allRT(end + 1) = nan;
end

end

srcMetadata = collectSrcMetadata(srcMetadata, metadata);

% add the files to list
allFilesTemp = cellstr(char(files));
allFiles = [allFiles; allFilesTemp];
Expand All @@ -91,3 +86,21 @@
num2str(opt.fwhm.func)]);

end

function srcMetadata = collectSrcMetadata(srcMetadata, metadata)
for iFile = 1:numel(metadata)

if isfield(metadata{iFile}, 'RepetitionTime')
srcMetadata.RepetitionTime(end + 1) = metadata{iFile}.RepetitionTime;
else
srcMetadata.RepetitionTime(end + 1) = nan;
end

if isfield(metadata{iFile}, 'SliceTimingCorrected')
srcMetadata.SliceTimingCorrected(end + 1) = metadata{iFile}.SliceTimingCorrected;
else
srcMetadata.SliceTimingCorrected(end + 1) = false;
end

end
end
9 changes: 7 additions & 2 deletions src/bids/getAnatFilename.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,14 @@
end

if numel(anat) > nbImgToReturn
tmp = bids.internal.format_path(anat(1:nbImgToReturn));
msg = sprintf('More than %i anat file. Found: %i.\n\nTaking the first %i:%s\n', ...

tmp = anat(1:nbImgToReturn);
tmp = strrep(tmp, [BIDS.pth filesep], '');
tmp = bids.internal.format_path(tmp);
msg = sprintf(['More than %i anat file in:\n%s.', ...
'\n\nFound: %i.\nTaking the first %i:%s'], ...
nbImgToReturn, ...
bids.internal.format_path(BIDS.pth), ...
numel(anat), ...
nbImgToReturn, ...
bids.internal.create_unordered_list(tmp));
Expand Down
41 changes: 36 additions & 5 deletions src/bids/getAndCheckSliceOrder.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@

% TODO support for DelayTime and AcquisitionDuration

warning('OFF', 'query:unknowMetadata');

filter.target = 'SliceTimingCorrected';
sliceTimingCorrected = bids.query(BIDS, 'metadata', filter);
stCorrected = areAllSliceTimeCorrected(sliceTimingCorrected);

% for GLM if data is not slice time corrected
% we will rely on the number of slices
% to figure out the temporal resolution
% to do convolution at.
if strcmp(opt.pipeline.type, 'stats') && ~stCorrected
sliceOrder = [];
warning('ON', 'query:unknowMetadata');
return
end

filter.target = 'SliceTiming';
sliceTiming = bids.query(BIDS, 'metadata', filter);

Expand All @@ -48,23 +64,20 @@
id = 'noSliceTimingFound';
logger('WARNING', msg, 'id', id, 'filename', mfilename(), 'options', opt);

warning('ON', 'query:unknowMetadata');
return

end

sliceTimingLengths = cellfun('length', sliceTiming);
if length(unique(sliceTimingLengths)) > 1

sliceOrder = [];
warning('ON', 'query:unknowMetadata');

msg = sprintf(['Inconsistent slice timing found for filter:\n%s.\n\n', ...
'Number of slice per volume seems different across bold files.'], ...
bids.internal.create_unordered_list(filter));
id = 'inconsistentSliceTimingLength';
logger('ERROR', msg, 'id', id, 'filename', mfilename(), 'options', opt);

return

end

% all slice timing should be the same,
Expand All @@ -82,6 +95,7 @@
id = 'inconsistentSliceTimingValues';
logger('WARNING', msg, 'id', id, 'filename', mfilename(), 'options', opt);

warning('ON', 'query:unknowMetadata');
return
end

Expand All @@ -90,4 +104,21 @@
msg = ' SLICE TIMING INFORMATION EXTRACTED FROM METADATA.';
logger('INFO', msg, 'options', opt, 'filename', mfilename());

warning('ON', 'query:unknowMetadata');

end

function stCorrected = areAllSliceTimeCorrected(values)
if isempty(values) || ...
(~iscell(values) && ~values)
stCorrected = false;
return
end
if iscell(values) && any(cellfun('isempty', values))
stCorrected = false;
return
end

stCorrected = all(values{1});

end
12 changes: 7 additions & 5 deletions src/bids_model/getInclusiveMask.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@
file = file{1};

elseif numel(file) > 1
file = bids.internal.format_path(file);
msg = sprintf(['More than 1 mask image found for %s.\n\n' ...
'Taking the first one:\n\t%s\n\nfrom:%s\n\n'], ...
tmp = strrep(file, [BIDS.pth, filesep], '');
tmp = bids.internal.format_path(tmp);
msg = sprintf(['More than 1 mask image found in:\n %s\nfor filter: %s.\n\n' ...
'Taking the first one:\n\t%s\n\nfrom:%s'], ...
BIDS.pth, ...
bids.internal.create_unordered_list(mask), ...
file{1}, ...
bids.internal.create_unordered_list(file));
tmp{1}, ...
bids.internal.create_unordered_list(tmp));
id = 'tooManyMasks';
logger('WARNING', msg, 'id', id, 'options', opt, 'filename', mfilename());
file = file{1};
Expand Down
7 changes: 4 additions & 3 deletions src/cli/getOptionsFromCliArgument.m
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,15 @@
if ~isfield(args.Results, 'space')
return
end
if ~isempty(args.Results.space)
if isfield(opt, 'space') && ~all(ismember(args.Results.space, opt.space))

if isfield(opt, 'space') && ~all(ismember(args.Results.space, opt.space))
if ~isempty(args.Results.space)
overrideMsg('space', convertToString(args.Results.space), ...
'space', convertToString(opt.space), ...
opt);
end
opt.space = args.Results.space;
end
opt.space = args.Results.space;
end

function output = convertToString(input)
Expand Down
4 changes: 2 additions & 2 deletions src/reports/boilerplate_preprocess.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ The (f)MRI data were pre-processed with {{>computing_environment}}.
{{! TODO mention which task were processed}}

The preprocessing of the functional images was performed in the following order:
{{#dummy_scans}}- removing of dummy scans
{{/dummy_scans}}
{{#dummyScans}}- removing of dummy scans
{{/dummyScans}}
{{#stc}}- slice timing correction
{{/stc}}
- realignment{{#unwarp}} and unwarping{{/unwarp}}
Expand Down
4 changes: 2 additions & 2 deletions src/reports/partials/remove_dummies.mustache
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
{{#dummy_scans}}{{nb}} dummy scans were removed to allow for signal stabilization.
{{/dummy_scans}}
{{#dummyScans}}{{nb}} dummy scans were removed to allow for signal stabilization.
{{/dummyScans}}
3 changes: 3 additions & 0 deletions src/stats/subject_level/createAndReturnCounfoundMatFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
opt.query.task = opt.taskName;

ffxDir = getFFXdir(bf.entities.sub, opt);
if exist(ffxDir, 'dir') == 0
spm_mkdir(ffxDir);
end
counfoundFile = fullfile(ffxDir, bf.filename);

if isempty(names) || isempty(R)
Expand Down
4 changes: 1 addition & 3 deletions src/stats/subject_level/getFFXdir.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function ffxDir = getFFXdir(subLabel, opt)
%
% Sets the name the FFX directory and creates it if it does not exist
% Sets the name the FFX directory
%
% USAGE::
%
Expand Down Expand Up @@ -39,8 +39,6 @@
ffxDir = [ffxDir '_roi'];
end

spm_mkdir(ffxDir);

end

function string = deregexify(string)
Expand Down
34 changes: 25 additions & 9 deletions src/workflows/preproc/bidsSmoothing.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function bidsSmoothing(opt)
function srcMetadata = bidsSmoothing(opt)
%
% This performs smoothing to the functional data using a full width
% half maximum smoothing kernel of size "opt.fwhm.func".
Expand Down Expand Up @@ -33,7 +33,7 @@ function bidsSmoothing(opt)
opt.taskName = bids.query(BIDS, 'tasks');
end

allRT = {};
srcMetadata = struct('RepetitionTime', [], 'SliceTimingCorrected', []);
unRenamedFiles = {};

for iSub = 1:numel(opt.subjects)
Expand All @@ -49,10 +49,10 @@ function bidsSmoothing(opt)
switch modality
case 'func'
matlabbatch = {};
[matlabbatch, allRT{iSub}] = setBatchSmoothingFunc(matlabbatch, ...
BIDS, ...
opt, ...
subLabel);
[matlabbatch, srcMetadata(iSub)] = setBatchSmoothingFunc(matlabbatch, ...
BIDS, ...
opt, ...
subLabel);
[~, unRenamedFiles{iSub}] = saveAndRunWorkflow(matlabbatch, ...
['smoothing_FWHM-', ...
num2str(opt.fwhm.func)], ...
Expand Down Expand Up @@ -81,25 +81,41 @@ function bidsSmoothing(opt)
opt.query.space = opt.space;
createdFiles = bidsRename(opt);

transferMetadata(opt, createdFiles, unRenamedFiles, srcMetadata);

end

function transferMetadata(opt, createdFiles, unRenamedFiles, srcMetadata)
% add Repetition Time to smoothed files metadata

metadataToTransfer = fieldnames(srcMetadata);

for iSub = 1:numel(opt.subjects)

subLabel = opt.subjects{iSub};

for iFile = 1:numel(createdFiles)

bf = bids.File(createdFiles{iFile});
if ~strcmp(bf.suffix, 'bold') || ~strcmp(bf.entities.sub, subLabel)
continue
end

jsonFile = spm_file(createdFiles{iFile}, 'ext', '.json');
if exist(jsonFile, 'file')

metadata = bids.util.jsondecode(jsonFile);
idx = ~cellfun('isempty', ...
strfind(unRenamedFiles{iSub}{1}.files, ...
metadata.SpmFilename));
rt = allRT{iSub}(idx);
metadata.RepetitionTime = rt;

for i = 1:numel(metadataToTransfer)
metadata.(metadataToTransfer{i}) = srcMetadata(iSub).(metadataToTransfer{i})(idx);
end

bids.util.jsonencode(jsonFile, metadata);
end

end
end

end
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"SliceThickness": 3,
"FlipAngle": 54,
"NumberOfVolumesDiscardedByUser": 4,
"TaskName": "vislocalizer"
"TaskName": "vislocalizer",
"SliceTimingCorrected": false
}
21 changes: 11 additions & 10 deletions tests/data/derivatives/bidspm-preproc/task-vismotion_bold.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
"ImageType": "ORIGINAL\\PRIMARY\\M\\ND\\MOSAIC",
"Modality": "MR",
"TotalReadoutTime": 1.0035123,
"SliceTimingCorrected": true,
"RepetitionTime": 1.5,
"PhaseEncodingDirection": "j-",
"EffectiveEchoSpacing": 0.00024499812,
"EchoTime": 0.03,
"SliceThickness": 3,
"FlipAngle": 54,
"NumberOfVolumesDiscardedByUser": 8,
"TaskName": "vismotion",
"PixelBandwidth": 15.873,
"SliceTiming": [
0.5475,
0,
Expand Down Expand Up @@ -45,14 +55,5 @@
0.3275,
0.71,
0.165
],
"RepetitionTime": 1.5,
"PhaseEncodingDirection": "j-",
"EffectiveEchoSpacing": 0.00024499812,
"EchoTime": 0.03,
"SliceThickness": 3,
"FlipAngle": 54,
"NumberOfVolumesDiscardedByUser": 8,
"TaskName": "vismotion",
"PixelBandwidth": 15.873
]
}
Loading

0 comments on commit 35397c0

Please sign in to comment.