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

Improvements on dependencies calculations #172

Merged
merged 14 commits into from
Apr 16, 2021
4 changes: 2 additions & 2 deletions +bids/+internal/append_to_layout.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function subject = append_to_layout(file, subject, modality, schema)
function [subject, p] = append_to_layout(file, subject, modality, schema)
%
% appends a file to the BIDS layout by parsing it according to the provided schema
%
Expand Down Expand Up @@ -40,7 +40,7 @@
p = bids.internal.parse_filename(file, entities);

% do not index json files when using the schema
if ~isempty(p) && strcmp(p.ext, '.json')
if isempty(p) || (~isempty(p) && strcmp(p.ext, '.json'))
return
end

Expand Down
23 changes: 23 additions & 0 deletions +bids/+internal/ends_with.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function res = ends_with(str, pattern)
%
% Checks id character array 'str' ends with 'pat'
%
% USAGE res = bids.internal.endsWith(str, pat)
%
% str - character array
% pat - character array
Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
%
% __________________________________________________________________________
%
% Based on spm_file.m and spm_select.m from SPM12.
% __________________________________________________________________________

% Copyright (C) 2011-2018 Guillaume Flandin, Wellcome Centre for Human Neuroimaging
res = false;
l_pat = length(pattern);
if l_pat > length(str)
return
end
res = strcmp(str(end - l_pat + 1:end), pattern);

end
82 changes: 82 additions & 0 deletions +bids/+internal/get_meta_list.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
function metalist = get_meta_list(filename, pattern)
%
% Read a BIDS's file metadata according to the inheritance principle
%
% USAGE::
%
% meta = bids.internal.get_metadata(filename, pattern = '^.*%s\\.json$')
%
% :param filename: fullpath name of file following BIDS standard
% :type filename: string
% :param pattern: Regular expression matching the metadata file (default is ``'^.*%s\\.json$'``)
% If provided, it must at least be ``'%s'``.
% :type pattern: string
%
%
% metalist - list of paths to metafiles
% __________________________________________________________________________

% Copyright (C) 2016-2018, Guillaume Flandin, Wellcome Centre for Human Neuroimaging
% Copyright (C) 2018--, BIDS-MATLAB developers

if nargin == 1
pattern = '^.*%s\\.json$';
end

pth = fileparts(filename);
p = bids.internal.parse_filename(filename);
metalist = {};

N = 3;

% -There is a session level in the hierarchy
if isfield(p.entities, 'ses') && ~isempty(p.entities.ses)
N = N + 1;
end

% -Loop from the directory where the file of interest is back to the
% top level of the BIDS hierarchy
for n = 1:N

% -List the potential metadata files associated with this file suffix type
% Default is to assume it is a JSON file
metafile = bids.internal.file_utils('FPList', pth, sprintf(pattern, p.suffix));

if isempty(metafile)
metafile = {};
else
metafile = cellstr(metafile);
end

% -For all those files we find which one is potentially associated with
% the file of interest
for i = 1:numel(metafile)

p2 = bids.internal.parse_filename(metafile{i});
entities = {};
if isfield(p2, 'entities')
entities = fieldnames(p2.entities);
end

% -Check if this metadata file contains the same entity-label pairs as its
% data file counterpart
ismeta = true;
for j = 1:numel(entities)
if ~isfield(p.entities, entities{j}) || ...
~strcmp(p.entities.(entities{j}), p2.entities.(entities{j}))
ismeta = false;
break
end
end

% append path to list
if ismeta
metalist{end + 1, 1} = metafile{i}; %#ok<AGROW>
end

end

% -Go up to the parent folder
pth = fullfile(pth, '..');
end
end
85 changes: 14 additions & 71 deletions +bids/+internal/get_metadata.m
Original file line number Diff line number Diff line change
@@ -1,94 +1,37 @@
function meta = get_metadata(filename, pattern)
function meta = get_metadata(metafile)
%
% Read a BIDS's file metadata according to the inheritance principle
%
% USAGE::
%
% meta = bids.internal.get_metadata(filename, pattern = '^.*%s\\.json$')
% meta = bids.internal.get_metadata(metafile)
%
% :param filename: fullpath name of file following BIDS standard
% :type filename: string
% :param pattern: Regular expression matching the metadata file (default is ``'^.*%s\\.json$'``)
% If provided, it must at least be ``'%s'``.
% :type pattern: string
% :param metafile: list of fullpath names of metadata files.
% :type metafile: string or array of strings
%
% :returns: - :meta: metadata structure
%
% meta - metadata structure
% .. todo
%
% add explanation on how the inheritance principle is implemented.
% __________________________________________________________________________

% Copyright (C) 2016-2018, Guillaume Flandin, Wellcome Centre for Human Neuroimaging
% Copyright (C) 2018--, BIDS-MATLAB developers

if nargin == 1
pattern = '^.*%s\\.json$';
end

pth = fileparts(filename);
p = bids.internal.parse_filename(filename);

meta = struct();
metafile = cellstr(metafile);

N = 3;

% -There is a session level in the hierarchy
if isfield(p.entities, 'ses') && ~isempty(p.entities.ses)
N = N + 1;
end

% -Loop from the directory where the file of interest is back to the
% top level of the BIDS hierarchy
for n = 1:N

% -List the potential metadata files associated with this file suffix type
% Default is to assume it is a JSON file
metafile = bids.internal.file_utils('FPList', pth, sprintf(pattern, p.suffix));

if isempty(metafile)
metafile = {};
for i = 1:numel(metafile)
if bids.internal.ends_with(metafile{i}, '.json')
meta = update_metadata(meta, bids.util.jsondecode(metafile{i}), metafile{i});
else
metafile = cellstr(metafile);
meta.filename = metafile{i};
end

% -For all those files we find which one is potentially associated with
% the file of interest
for i = 1:numel(metafile)

p2 = bids.internal.parse_filename(metafile{i});
entities = {};
if isfield(p2, 'entities')
entities = fieldnames(p2.entities);
end

% -Check if this metadata file contains the same entity-label pairs as its
% data file counterpart
ismeta = true;
for j = 1:numel(entities)
if ~isfield(p.entities, entities{j}) || ...
~strcmp(p.entities.(entities{j}), p2.entities.(entities{j}))
ismeta = false;
break
end
end

% -Read the content of the metadata file if it is a JSON file and update
% the metadata concerning the file of interest otherwise store the filename
if ismeta
if strcmp(p2.ext, '.json')
meta = update_metadata(meta, bids.util.jsondecode(metafile{i}), metafile{i});
else
meta.filename = metafile{i};
end
end

end

% -Go up to the parent folder
pth = fullfile(pth, '..');

end

if isempty(meta)
warning('No metadata for %s', filename);
warning('No metadata for %s', metafile);
end

end
Expand Down
23 changes: 23 additions & 0 deletions +bids/+internal/starts_with.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function res = starts_with(str, pattern)
%
% Checks id character array 'str' starts with 'pat'
%
% USAGE res = bids.internal.startsWith(str, pat)
%
% str - character array
% pat - character array
%
% __________________________________________________________________________
%
% Based on spm_file.m and spm_select.m from SPM12.
% __________________________________________________________________________

% Copyright (C) 2011-2018 Guillaume Flandin, Wellcome Centre for Human Neuroimaging
res = false;
l_pat = length(pattern);
if l_pat > length(str)
return
end
res = strcmp(str(1:l_pat), pattern);

end
Loading