From 67d014f07106100aa157fd696f9c07375658ddd1 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 7 Apr 2024 10:33:06 +0200 Subject: [PATCH 1/3] create valid participants and sessions tsv during dataset init --- +bids/+util/create_participants_tsv.m | 8 +- +bids/+util/create_sessions_tsv.m | 2 +- tests/test_bids_init.m | 83 +++++++++++-------- .../test_create_participants_tsv.m | 11 ++- tests/tests_utils/test_create_sessions_tsv.m | 16 ++-- 5 files changed, 68 insertions(+), 52 deletions(-) diff --git a/+bids/+util/create_participants_tsv.m b/+bids/+util/create_participants_tsv.m index 754aaef6..cc9a0a38 100644 --- a/+bids/+util/create_participants_tsv.m +++ b/+bids/+util/create_participants_tsv.m @@ -64,12 +64,12 @@ % in case the query returns empty in case no file was indexed if isempty(subjects_list) && ~use_schema subjects_list = cellstr(bids.internal.file_utils('List', layout.pth, 'dir', '^sub-.*$')); + output_structure = struct('participant_id', {subjects_list}); + else + subjects_list = [repmat('sub-', numel(subjects_list), 1), char(subjects_list')]; + output_structure = struct('participant_id', subjects_list); end - subjects_list = [repmat('sub-', numel(subjects_list), 1), char(subjects_list')]; - - output_structure = struct('participant_id', subjects_list); - output_filename = fullfile(layout.pth, 'participants.tsv'); bids.util.tsvwrite(fullfile(layout.pth, 'participants.tsv'), output_structure); diff --git a/+bids/+util/create_sessions_tsv.m b/+bids/+util/create_sessions_tsv.m index e1551466..463e3f80 100644 --- a/+bids/+util/create_sessions_tsv.m +++ b/+bids/+util/create_sessions_tsv.m @@ -89,7 +89,7 @@ fullfile(layout.pth, ... ['sub-' subjects_list{i_sub}]), ... 'dir', ... - '^sub-.*$')); + '^ses-.*$')); sessions_list = regexprep(sessions_list, 'ses-', ''); end diff --git a/tests/test_bids_init.m b/tests/test_bids_init.m index 7fc30590..2babe8e3 100644 --- a/tests/test_bids_init.m +++ b/tests/test_bids_init.m @@ -11,17 +11,16 @@ function test_basic() set_test_cfg(); - dataset_description = fullfile(pwd, 'dummy_ds', 'dataset_description.json'); + output_dir = fullfile(temp_dir(), 'dummy_ds'); - bids.init('dummy_ds'); - assertEqual(exist(fullfile(pwd, 'dummy_ds'), 'dir'), 7); + bids.init(output_dir); + assertEqual(exist(output_dir, 'dir'), 7); + dataset_description = fullfile(output_dir, 'dataset_description.json'); assertEqual(exist(dataset_description, 'file'), 2); ds_metadata = bids.util.jsondecode(dataset_description); assertEqual(ds_metadata.DatasetType, 'raw'); - clean_up(); - end function test_no_folder_smoke_test() @@ -30,23 +29,44 @@ function test_no_folder_smoke_test() bids.init('dummy_ds', 'folders', struct(), 'is_derivative', true); - clean_up(); +end + +function test_valid_tsv() + set_test_cfg(); + + output_dir = fullfile(temp_dir(), 'dummy_ds'); + folders.subjects = 'a'; + folders.sessions = '1'; + folders.modalities = 'beh'; + + bids.init(output_dir, 'folders', folders); + assertEqual(exist(fullfile(output_dir, 'sub-a', 'ses-1', 'beh'), 'dir'), 7); + assertEqual(exist(fullfile(output_dir, 'sub-a', 'sub-a_sessions.tsv'), 'file'), 2); + + participants = bids.util.tsvread(fullfile(output_dir, 'participants.tsv')); + assertEqual(participants.participant_id, {'sub-a'}); + + sessions = bids.util.tsvread(fullfile(output_dir, 'sub-a', 'sub-a_sessions.tsv')); + assertEqual(sessions.session_id, {'ses-1'}); end function test_folders() set_test_cfg(); + output_dir = fullfile(temp_dir(), 'dummy_ds'); + folders.subjects = {'01', '02'}; folders.sessions = {'test', 'retest', ''}; folders.modalities = {'anat', 'func', 'fizz', ''}; - bids.init('dummy_ds', 'folders', folders); - assertEqual(exist(fullfile(pwd, 'dummy_ds', 'sub-02', 'ses-retest', 'func'), 'dir'), 7); - assertEqual(exist(fullfile(pwd, 'dummy_ds', 'sub-02', 'sub-02_sessions.tsv'), 'file'), 2); + bids.init(output_dir, 'folders', folders); + assertEqual(exist(fullfile(output_dir, 'sub-02', 'ses-retest', 'func'), 'dir'), 7); + assertEqual(exist(fullfile(output_dir, 'sub-02', 'sub-02_sessions.tsv'), 'file'), 2); - clean_up(); + sessions = bids.util.tsvread(fullfile(output_dir, 'sub-01', 'sub-01_sessions.tsv')); + assertEqual(sessions.session_id, {'ses-retest'; 'ses-test'}); end @@ -54,14 +74,17 @@ function test_folders_no_session() set_test_cfg(); + output_dir = fullfile(temp_dir(), 'dummy_ds'); + folders.subjects = {'01', '02'}; folders.modalities = {'anat', 'func'}; - bids.init('dummy_ds', 'folders', folders); - assertEqual(exist(fullfile(pwd, 'dummy_ds', 'sub-02', 'func'), 'dir'), 7); - assertEqual(exist(fullfile(pwd, 'dummy_ds', 'sub-02', 'sub-02_sessions.tsv'), 'file'), 0); + bids.init(output_dir, 'folders', folders); + assertEqual(exist(fullfile(output_dir, 'sub-02', 'func'), 'dir'), 7); + assertEqual(exist(fullfile(output_dir, 'sub-02', 'sub-02_sessions.tsv'), 'file'), 0); - clean_up(); + participants = bids.util.tsvread(fullfile(output_dir, 'participants.tsv')); + assertEqual(participants.participant_id, {'sub-01'; 'sub-02'}); end @@ -69,63 +92,53 @@ function test_validate() set_test_cfg(); + output_dir = fullfile(temp_dir(), 'dummy_ds'); + folders.subjects = {'01-bla', '02_foo'}; folders.sessions = {'te-st', 'ret$est'}; folders.modalities = {'a#nat', 'fu*nc', '45^['}; - assertExceptionThrown(@() bids.init('dummy_ds', 'folders', folders), ... + assertExceptionThrown(@() bids.init(output_dir, 'folders', folders), ... 'init:nonAlphaNumFodler'); folders.subjects = {'01', '02'}; folders.sessions = {'te-st', 'ret$est'}; folders.modalities = {'a#nat', 'fu*nc', '45^['}; - assertExceptionThrown(@() bids.init('dummy_ds', 'folders', folders), ... + assertExceptionThrown(@() bids.init(output_dir, 'folders', folders), ... 'init:nonAlphaNumFodler'); folders.subjects = {'01', '02'}; folders.sessions = {'test', 'retest'}; folders.modalities = {'a#nat', 'fu*nc', '45^['}; - assertExceptionThrown(@() bids.init('dummy_ds', 'folders', folders), ... + assertExceptionThrown(@() bids.init(output_dir, 'folders', folders), ... 'init:nonAlphaNumFodler'); - clean_up(); - end function test_derivatives() set_test_cfg(); + output_dir = fullfile(temp_dir(), 'dummy_ds'); + folders.subjects = {'01', '02'}; folders.sessions = {'test', 'retest'}; folders.modalities = {'anat', 'func'}; - dataset_description = fullfile(pwd, 'dummy_ds', 'dataset_description.json'); + dataset_description = fullfile(output_dir, 'dataset_description.json'); - bids.init('dummy_ds', 'folders', folders, 'is_derivative', true); - assertEqual(exist(fullfile(pwd, 'dummy_ds', 'sub-02', 'ses-retest', 'func'), 'dir'), 7); + bids.init(output_dir, 'folders', folders, 'is_derivative', true); + assertEqual(exist(fullfile(output_dir, 'sub-02', 'ses-retest', 'func'), 'dir'), 7); ds_metadata = bids.util.jsondecode(dataset_description); assertEqual(ds_metadata.DatasetType, 'derivative'); % smoke test - bids.init('dummy_ds', ... + bids.init(output_dir, ... 'folders', folders, ... 'is_derivative', true, ... 'is_datalad_ds', true); - clean_up(); - -end - -function clean_up() - - pause(0.5); - - if isdir(fullfile(pwd, 'dummy_ds')) - rmdir(fullfile(pwd, 'dummy_ds'), 's'); - end - end diff --git a/tests/tests_utils/test_create_participants_tsv.m b/tests/tests_utils/test_create_participants_tsv.m index 5f3a14c1..140fa193 100644 --- a/tests/tests_utils/test_create_participants_tsv.m +++ b/tests/tests_utils/test_create_participants_tsv.m @@ -8,12 +8,17 @@ function test_create_participants_tsv_basic() - bids_path = fullfile(get_test_data_dir(), 'asl001'); + bids_path = temp_dir(); + + copyfile(fullfile(get_test_data_dir(), 'asl001'), bids_path); validate_dataset(bids_path); output_filename = bids.util.create_participants_tsv(bids_path, 'verbose', false); + participants = bids.util.tsvread(output_filename); + assertEqual(participants.participant_id, {'sub-Sub103'}); + validate_dataset(bids_path); delete(output_filename); @@ -24,7 +29,9 @@ function test_create_participants_tsv_already_exist() skip_if_octave('mixed-string-concat warning thrown'); - bids_path = fullfile(get_test_data_dir(), 'ds210'); + bids_path = temp_dir(); + + copyfile(fullfile(get_test_data_dir(), 'ds210'), bids_path); output_filename = bids.util.create_participants_tsv(bids_path); diff --git a/tests/tests_utils/test_create_sessions_tsv.m b/tests/tests_utils/test_create_sessions_tsv.m index bc41f9c2..ea7e2a50 100644 --- a/tests/tests_utils/test_create_sessions_tsv.m +++ b/tests/tests_utils/test_create_sessions_tsv.m @@ -8,7 +8,9 @@ function test_create_sessions_tsv_no_session() - bids_path = fullfile(get_test_data_dir(), 'ds210'); + bids_path = temp_dir(); + + copyfile(fullfile(get_test_data_dir(), 'ds210'), bids_path); validate_dataset(bids_path); @@ -27,7 +29,9 @@ function test_create_sessions_tsv_no_session() function test_create_sessions_tsv_basic() - bids_path = fullfile(get_test_data_dir(), 'ieeg_epilepsy'); + bids_path = temp_dir(); + + copyfile(fullfile(get_test_data_dir(), 'ieeg_epilepsy'), bids_path); validate_dataset(bids_path); @@ -41,12 +45,4 @@ function test_create_sessions_tsv_basic() validate_dataset(bids_path); - teardown(bids_path, output_filenames); - -end - -function teardown(pth, filelist) - for i = 1:numel(filelist) - delete(fullfile(pth, filelist{i})); - end end From 94e695180b51862fc783fc83cf17c1988215b0d4 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 7 Apr 2024 10:34:57 +0200 Subject: [PATCH 2/3] update changelog --- docs/source/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/changelog.md b/docs/source/changelog.md index 49529ab9..3917b43e 100644 --- a/docs/source/changelog.md +++ b/docs/source/changelog.md @@ -33,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* [FIX] Create valid participants and sessions tsv during dataset init #688 by @Remi-Gau + ### Security From 13d97975a2b69be1eac7a1169513ba04204df15b Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 7 Apr 2024 17:57:11 +0200 Subject: [PATCH 3/3] fix tests for octave --- tests/tests_utils/test_create_participants_tsv.m | 8 ++++++++ tests/tests_utils/test_create_sessions_tsv.m | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/tests_utils/test_create_participants_tsv.m b/tests/tests_utils/test_create_participants_tsv.m index 140fa193..715a4910 100644 --- a/tests/tests_utils/test_create_participants_tsv.m +++ b/tests/tests_utils/test_create_participants_tsv.m @@ -12,6 +12,10 @@ function test_create_participants_tsv_basic() copyfile(fullfile(get_test_data_dir(), 'asl001'), bids_path); + if bids.internal.is_octave + bids_path = fullfile(bids_path, 'asl001'); + end + validate_dataset(bids_path); output_filename = bids.util.create_participants_tsv(bids_path, 'verbose', false); @@ -33,6 +37,10 @@ function test_create_participants_tsv_already_exist() copyfile(fullfile(get_test_data_dir(), 'ds210'), bids_path); + if bids.internal.is_octave + bids_path = fullfile(bids_path, 'ds210'); + end + output_filename = bids.util.create_participants_tsv(bids_path); validate_dataset(bids_path); diff --git a/tests/tests_utils/test_create_sessions_tsv.m b/tests/tests_utils/test_create_sessions_tsv.m index ea7e2a50..287d614c 100644 --- a/tests/tests_utils/test_create_sessions_tsv.m +++ b/tests/tests_utils/test_create_sessions_tsv.m @@ -12,6 +12,10 @@ function test_create_sessions_tsv_no_session() copyfile(fullfile(get_test_data_dir(), 'ds210'), bids_path); + if bids.internal.is_octave + bids_path = fullfile(bids_path, 'ds210'); + end + validate_dataset(bids_path); output_filenames = bids.util.create_sessions_tsv(bids_path, 'verbose', false); @@ -33,6 +37,10 @@ function test_create_sessions_tsv_basic() copyfile(fullfile(get_test_data_dir(), 'ieeg_epilepsy'), bids_path); + if bids.internal.is_octave + bids_path = fullfile(bids_path, 'ieeg_epilepsy'); + end + validate_dataset(bids_path); output_filenames = bids.util.create_sessions_tsv(bids_path, 'verbose', false);