Skip to content

Commit

Permalink
Merge pull request #172 from bids-standard/beliy-dependencies
Browse files Browse the repository at this point in the history
Improvements on dependencies calculations
  • Loading branch information
Remi-Gau authored Apr 16, 2021
2 parents 5f6b991 + 6bfd46f commit 61fd910
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 390 deletions.
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
%
% __________________________________________________________________________
%
% 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

0 comments on commit 61fd910

Please sign in to comment.