Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Add change suffix workflow #516

Merged
merged 1 commit into from
Feb 8, 2022
Merged
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
139 changes: 139 additions & 0 deletions src/workflows/bidsChangeSuffix.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
function bidsChangeSuffix(varargin)
marcobarilari marked this conversation as resolved.
Show resolved Hide resolved
%
% USAGE::
%
% bidsChangeSuffix(opt, newSuffix, 'filter', struct([]), 'force', false)
%
% :param opt: BIDS input dataset must be defined in ``opt.dir.input``;
% To test the output, set ``opt.dryRun`` to ``true``.
% :type opt: structure
%
% :param newSuffix: TODO: add checks on newSuffix to make sure it only contains [a-zA-Z0-9]
% :type newSuffix: string
%
% :param filter: structure to decide which files to include. Default:
% ``struct([])`` for no filter
% :type filter: structure
%
% :param force: If set to ``true`` it will overwrite already existing files. Default: ``false``
% :type force: boolean
%
%
% EXAMPLE::
%
% opt.dir.input = path_to_dataset;
marcobarilari marked this conversation as resolved.
Show resolved Hide resolved
% opt.dryRun = true;
%
% newSuffix = 'vaso';
%
% filter = struct('suffix', 'bold');
%
% bidsChangeSuffix(opt, newSuffix, ...
% 'filter', filter, ...
% 'force', false)
%
%
% (C) Copyright 2022 CPP_SPM developers

p = inputParser;

addRequired(p, 'opt', @isstruct);
addRequired(p, 'newSuffix', @ischar);
addParameter(p, 'filter', struct([]), @isstruct);
addParameter(p, 'force', false, @islogical);

parse(p, varargin{:});

opt = p.Results.opt;
newSuffix = p.Results.newSuffix;
filter = p.Results.filter;
force = p.Results.force;

[BIDS, opt] = setUpWorkflow(opt, 'changing suffix', opt.dir.input);

if isempty(filter)
data = bids.query(BIDS, 'data');
else
data = bids.query(BIDS, 'data', filter);
end

createdFiles = {};

for iFile = 1:size(data, 1)

specification.suffix = newSuffix;
% FYI renameFile was part of CPP ROI
% Will be replaced by some yet to come bids matlab function
[newName, outputFile] = renameFile(data{iFile}, specification);

msg = sprintf('%s --> %s\n', spm_file(data{iFile}, 'filename'), newName);
printToScreen(msg, opt);

if exist(outputFile, 'file') || ismember(newName, createdFiles)

msg = sprintf('This file already exists.\n\t%s\n', newName);
errorHandling(mfilename(), 'fileAlreadyExist', msg, true, opt.verbosity);

if ~opt.dryRun && force
movefile(data{iFile}, outputFile);
end

elseif ~opt.dryRun
movefile(data{iFile}, outputFile);

end

createdFiles{end + 1, 1} = newName;

end

cleanUpWorkflow(opt);

end

function [newName, outputFile] = renameFile(inputFile, specification)
%
% Renames a BIDS valid file into another BIDS valid file given some
% specificationification.
%
% USAGE::
%
% [newName, outputFile] = renameFile(inputFile, specificationification)
%
% :param inputFile: better if fullfile path
% :type inputFile: string
% :param specificationification: structure specificationifying the details of the new name
% The structure content must resemble that of the
% output of bids.internal.parse_filename
% :type specificationification: structure
%
% (C) Copyright 2021 CPP ROI developers

bf = bids.File(inputFile, 'use_schema', false);

if isfield(specification, 'prefix')
bf.suffix = specification.prefix;
end
if isfield(specification, 'suffix')
bf.suffix = specification.suffix;
end
if isfield(specification, 'ext')
bf.extension = specification.ext;
end
if isfield(specification, 'entities')
entities = fieldnames(specification.entities);
for i = 1:numel(entities)
bf = bf.set_entity(entities{i}, ...
bids.internal.camel_case(specification.entities.(entities{i})));
end
end
if isfield(specification, 'entity_order')
bf = bf.reorder_entities(specification.entity_order);
end

bf = bf.update;

newName = bf.filename;
outputFile = spm_file(inputFile, 'filename', newName);

end