From 6126316a856d2a961719165826aa66ed88b581e7 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 24 Jun 2022 18:50:17 +0200 Subject: [PATCH 1/3] improve diagnostic to be able to split by suffix --- +bids/+internal/plot_diagnostic_table.m | 51 ++++++++++++++----- +bids/diagnostic.m | 67 +++++++++++++++++++------ 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/+bids/+internal/plot_diagnostic_table.m b/+bids/+internal/plot_diagnostic_table.m index 3dbbaa8c..f6d716fa 100644 --- a/+bids/+internal/plot_diagnostic_table.m +++ b/+bids/+internal/plot_diagnostic_table.m @@ -15,16 +15,7 @@ function plot_diagnostic_table(diagnostic_table, headers, yticklabel, fig_name) end - % prepare x tick labels - for col = 1:numel(headers) - xticklabel{col} = [headers{col}.modality]; - if isfield(headers{col}, 'task') - xticklabel{col} = sprintf('%s - task: %s', headers{col}.modality, headers{col}.task); - end - if length(xticklabel{col}) > 43 - xticklabel{col} = [xticklabel{col}(1:40) '...']; - end - end + xticklabel = create_x_tick_label(headers); nb_rows = size(diagnostic_table, 1); nb_cols = size(diagnostic_table, 2); @@ -52,9 +43,7 @@ function plot_diagnostic_table(diagnostic_table, headers, yticklabel, fig_name) % y axis set(gca, 'yTick', 1:nb_rows); - if nb_rows < 50 - set(gca, 'yTickLabel', yticklabel); - end + set(gca, 'yTickLabel', yticklabel); box(gca, 'on'); @@ -111,3 +100,39 @@ function plot_diagnostic_table(diagnostic_table, headers, yticklabel, fig_name) title(fig_name); end + +function xticklabel = create_x_tick_label(headers) + + for col = 1:numel(headers) + + if iscell(headers{col}.modality) + xticklabel{col} = headers{col}.modality{1}; + else + xticklabel{col} = headers{col}.modality; + end + + xticklabel = append_entity_to_label(headers, xticklabel, col, 'task'); + + xticklabel = append_entity_to_label(headers, xticklabel, col, 'suffix'); + + if length(xticklabel{col}) > 43 + xticklabel{col} = [xticklabel{col}(1:40) '...']; + end + + end + +end + +function label = append_entity_to_label(headers, label, col, entity) + + if isfield(headers{col}, entity) + + if iscell(headers{col}.(entity)) + headers{col}.(entity) = headers{col}.(entity){1}; + end + + label{col} = sprintf(['%s - ' entity ': %s'], label{col}, headers{col}.(entity)); + + end + +end diff --git a/+bids/diagnostic.m b/+bids/diagnostic.m index 4f2ea00a..1c577c38 100644 --- a/+bids/diagnostic.m +++ b/+bids/diagnostic.m @@ -41,7 +41,7 @@ % (C) Copyright 2021 BIDS-MATLAB developers default_BIDS = pwd; - default_schema = true; + default_schema = false; default_filter = struct(); default_split = {''}; default_output_path = ''; @@ -65,11 +65,9 @@ subjects = bids.query(BIDS, 'subjects', filter); - modalities = bids.query(BIDS, 'modalities', filter); - - headers = get_headers(BIDS, modalities, filter, args.Results.split_by); + headers = get_headers(BIDS, filter, args.Results.split_by); - diagnostic_table = nan(numel(subjects), numel(modalities)); + diagnostic_table = nan(numel(subjects), numel(headers)); % events_table = nan(numel(subjects), numel(tasks)); row = 1; @@ -102,6 +100,9 @@ if isfield(headers{i_col}, 'task') this_filter.task = headers{i_col}.task; end + if isfield(headers{i_col}, 'suffix') + this_filter.suffix = headers{i_col}.suffix; + end files = bids.query(BIDS, 'data', this_filter); @@ -141,28 +142,49 @@ end -function headers = get_headers(BIDS, modalities, filter, split_by) +function headers = get_headers(BIDS, filter, split_by) % % Get the headers to include in the output table % + % TODO will probably need to use a recursive way to build the header list + headers = {}; + + modalities = bids.query(BIDS, 'modalities', filter); + for i_modality = 1:numel(modalities) - if ismember('task', split_by) && ... - ismember(modalities(i_modality), {'func', 'eeg', 'meg', 'ieeg', 'pet', 'beh'}) + this_filter = filter; + this_filter.modality = modalities(i_modality); - this_filter = filter; - this_filter.modality = modalities(i_modality); - tasks = bids.query(BIDS, 'tasks', this_filter); + this_header = struct('modality', {modalities(i_modality)}); + + if ismember('suffix', split_by) + + suffixes = bids.query(BIDS, 'suffixes', this_filter); + + for i_suffix = 1:numel(suffixes) + + this_filter.suffix = suffixes(i_suffix); + + this_header.suffix = suffixes(i_suffix); + + if ismember('task', split_by) + headers = add_task_based_headers(BIDS, headers, this_filter, this_header, split_by); + else + headers{end + 1} = this_header; + end - for i_task = 1:numel(tasks) - headers{end + 1} = struct('modality', modalities(i_modality), ... - 'task', tasks(i_task)); end else - headers{end + 1} = struct('modality', modalities(i_modality)); + + if ismember('task', split_by) + headers = add_task_based_headers(BIDS, headers, this_filter, this_header, split_by); + else + headers{end + 1} = this_header; + end end @@ -177,3 +199,18 @@ this_filter.ses = ses; end end + +function headers = add_task_based_headers(BIDS, headers, this_filter, this_header, split_by) + + if ismember('task', split_by) + + tasks = bids.query(BIDS, 'tasks', this_filter); + + for i_task = 1:numel(tasks) + this_header.task = tasks(i_task); + headers{end + 1} = this_header; + end + + end + +end From 9bf91f5069c45b258c1a1ae3aec780ddf4ed0b58 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 24 Jun 2022 19:02:54 +0200 Subject: [PATCH 2/3] improve query performance --- +bids/query.m | 20 ++++++++++---------- tests/test_diagnostic.m | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/+bids/query.m b/+bids/query.m index 73ed6a5e..b509b6c1 100644 --- a/+bids/query.m +++ b/+bids/query.m @@ -159,7 +159,7 @@ bids.internal.error_handling(mfilename(), 'unknownQuery', msg, false, true); end - bids_entities = schema_entities(); +% bids_entities = schema_entities(); BIDS = bids.layout(BIDS); @@ -175,7 +175,7 @@ % Get optional target option for metadata query [target, options] = get_target(query, options); - result = perform_query(BIDS, query, options, subjects, modalities, target, bids_entities); + result = perform_query(BIDS, query, options, subjects, modalities, target); %% Postprocessing output variable switch query @@ -341,7 +341,7 @@ case cat(2, {'suffixes', 'suffixes', 'extensions', 'prefixes'}, valid_entity_qu end -function result = perform_query(BIDS, query, options, subjects, modalities, target, bids_entities) +function result = perform_query(BIDS, query, options, subjects, modalities, target) % Initialise output variable result = {}; @@ -366,13 +366,13 @@ case cat(2, {'suffixes', 'suffixes', 'extensions', 'prefixes'}, valid_entity_qu end result = update_result(query, options, result, this_subject, ... - this_modality, target, bids_entities); + this_modality, target); end end - result = update_result_with_root_content(query, options, result, BIDS, bids_entities); + result = update_result_with_root_content(query, options, result, BIDS); end @@ -387,7 +387,6 @@ case cat(2, {'suffixes', 'suffixes', 'extensions', 'prefixes'}, valid_entity_qu this_subject = varargin{4}; this_modality = varargin{5}; target = varargin{6}; - bids_entities = varargin{7}; d = this_subject.(this_modality); @@ -441,7 +440,7 @@ case cat(2, {'suffixes', 'suffixes', 'extensions', 'prefixes'}, valid_entity_qu case valid_entity_queries() - result = update_if_entity(query, result, d(k), bids_entities); + result = update_if_entity(query, result, d(k)); case {'suffixes', 'prefixes'} field = query(1:end - 2); @@ -459,7 +458,7 @@ case valid_entity_queries() end end -function result = update_result_with_root_content(query, options, result, BIDS, bids_entities) +function result = update_result_with_root_content(query, options, result, BIDS) d = BIDS.root; @@ -493,7 +492,7 @@ case valid_entity_queries() case valid_entity_queries() - result = update_if_entity(query, result, d(k), bids_entities); + result = update_if_entity(query, result, d(k)); case {'suffixes', 'prefixes'} field = query(1:end - 2); @@ -513,7 +512,7 @@ case valid_entity_queries() value = schema.content.objects.entities; end -function result = update_if_entity(query, result, dk, bids_entities) +function result = update_if_entity(query, result, dk) if ismember(query, short_valid_entity_queries()) field = query(1:end - 1); @@ -522,6 +521,7 @@ case valid_entity_queries() field = 'atlas'; elseif ismember(query, long_valid_entity_queries()) + bids_entities = schema_entities(); field = bids_entities.(query(1:end - 1)).entity; else diff --git a/tests/test_diagnostic.m b/tests/test_diagnostic.m index 1a09cda8..2ab91352 100644 --- a/tests/test_diagnostic.m +++ b/tests/test_diagnostic.m @@ -22,7 +22,9 @@ function test_diagnostic_basic() BIDS = bids.layout(deblank(examples(i, :))); diagnostic_table = bids.diagnostic(BIDS, 'output_path', pwd); + diagnostic_table = bids.diagnostic(BIDS, 'split_by', {'suffix'}, 'output_path', pwd); diagnostic_table = bids.diagnostic(BIDS, 'split_by', {'task'}, 'output_path', pwd); + diagnostic_table = bids.diagnostic(BIDS, 'split_by', {'task', 'suffix'}, 'output_path', pwd); end From 650b32f945d1a86d909d51381b36564247636bf4 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 24 Jun 2022 19:13:58 +0200 Subject: [PATCH 3/3] return more argument for diagnostic --- +bids/diagnostic.m | 2 +- +bids/query.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/+bids/diagnostic.m b/+bids/diagnostic.m index 1c577c38..0086a061 100644 --- a/+bids/diagnostic.m +++ b/+bids/diagnostic.m @@ -1,4 +1,4 @@ -function diagnostic_table = diagnostic(varargin) +function [diagnostic_table, sub_ses, headers] = diagnostic(varargin) % % Creates a summary figure listing the number of files for each subject / session and % and imaging modality (possiblty split by task) diff --git a/+bids/query.m b/+bids/query.m index b509b6c1..f5fd1221 100644 --- a/+bids/query.m +++ b/+bids/query.m @@ -159,7 +159,7 @@ bids.internal.error_handling(mfilename(), 'unknownQuery', msg, false, true); end -% bids_entities = schema_entities(); + % bids_entities = schema_entities(); BIDS = bids.layout(BIDS);