Skip to content

Commit 1faff9b

Browse files
authored
[ENH] add electrodes and optodes as group dependencies (#586)
* add electrodes and optodes as dependencies * inline function * fix
1 parent 07897c5 commit 1faff9b

16 files changed

+138
-126
lines changed

+bids/layout.m

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@
391391

392392
file_list = return_file_list(modality, subject, schema);
393393

394+
electrode_tsv = list_electrodes(modality, file_list);
395+
394396
% dependency previous file
395397
previous = struct('group', struct('index', 0, 'base', '', 'len', 1), ...
396398
'data', struct('index', 0, 'base', '', 'len', 1), ...
@@ -440,6 +442,9 @@
440442

441443
subject.(modality)(end) = manage_M0(subject.perf(end), pth, verbose);
442444

445+
case {'eeg', 'ieeg', 'nirs'}
446+
subject = appent_electrodes(subject, modality, electrode_tsv);
447+
443448
end
444449

445450
end
@@ -450,6 +455,39 @@
450455

451456
end
452457

458+
function electrode_tsv = list_electrodes(modality, file_list)
459+
460+
electrode_tsv = {};
461+
462+
switch modality
463+
case {'eeg', 'ieeg'}
464+
suffix = 'electrodes';
465+
case {'nirs'}
466+
suffix = 'optodes';
467+
otherwise
468+
return
469+
end
470+
471+
is_electrode_tsv = ~cellfun('isempty', ...
472+
strfind(file_list, ['_' suffix '.tsv']));
473+
has_electrode_tsv = any(is_electrode_tsv);
474+
if has_electrode_tsv
475+
electrode_tsv = file_list(is_electrode_tsv);
476+
end
477+
478+
end
479+
480+
function subject = appent_electrodes(subject, modality, electrode_tsv)
481+
for i = 1:numel(electrode_tsv)
482+
pth = fullfile(subject.path, modality);
483+
fullpath_filename = fullfile(pth, electrode_tsv{i});
484+
if ~ismember(fullpath_filename, ...
485+
subject.(modality)(end).dependencies.group)
486+
subject.(modality)(end).dependencies.group{end + 1, 1} = fullpath_filename;
487+
end
488+
end
489+
end
490+
453491
function BIDS = validate_description(BIDS, tolerant, verbose)
454492

455493
if ~exist(fullfile(BIDS.pth, 'dataset_description.json'), 'file')
@@ -578,6 +616,8 @@
578616
% This groups file that logically need each other,
579617
% like functional mri and events tabular file.
580618
% It also takes care of fmap magnitude1/2 and phasediff.
619+
% This will also include files that are shared across
620+
% several runs (i.e electrodes.tsv)
581621

582622
pth = fullfile(subject.path, modality);
583623
fullpath_filename = fullfile(pth, file);

tests/tests_query/test_bids_query.m

Lines changed: 24 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,19 @@
88

99
function test_query_participants()
1010

11-
pth_bids_example = get_test_data_dir();
12-
13-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet002'));
11+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet002'));
1412

1513
participants = bids.query(BIDS, 'participants');
1614

17-
BIDS = bids.layout(fullfile(pth_bids_example, 'asl001'));
15+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'asl001'));
1816

1917
participants = bids.query(BIDS, 'participants');
2018

2119
end
2220

2321
function test_query_impossible_suffix_should_return_empty()
2422

25-
pth_bids_example = get_test_data_dir();
26-
27-
BIDS = bids.layout(fullfile(pth_bids_example, 'synthetic'));
23+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'synthetic'));
2824

2925
% no suffix bold in anat
3026
filter = struct('sub', '01', ...
@@ -40,14 +36,12 @@ function test_query_impossible_suffix_should_return_empty()
4036

4137
function test_query_suffixes()
4238

43-
pth_bids_example = get_test_data_dir();
44-
45-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet002'));
39+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet002'));
4640

4741
suffixes = {'T1w', 'pet'};
4842
assertEqual(bids.query(BIDS, 'suffixes'), suffixes);
4943

50-
BIDS = bids.layout(fullfile(pth_bids_example, 'synthetic'));
44+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'synthetic'));
5145

5246
suffixes = {'T1w'};
5347
assertEqual(bids.query(BIDS, 'suffixes', 'modality', 'anat'), suffixes);
@@ -56,9 +50,7 @@ function test_query_suffixes()
5650

5751
function test_query_subjects()
5852

59-
pth_bids_example = get_test_data_dir();
60-
61-
BIDS = bids.layout(fullfile(pth_bids_example, 'ieeg_visual'));
53+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'ieeg_visual'));
6254

6355
subjs = arrayfun(@(x) sprintf('%02d', x), 1:2, 'UniformOutput', false);
6456
assertEqual(bids.query(BIDS, 'subjects'), subjs);
@@ -93,9 +85,7 @@ function test_query_regex_subjects_no_regex_by_default()
9385

9486
function test_query_regex_subjects()
9587

96-
pth_bids_example = get_test_data_dir();
97-
98-
BIDS = bids.layout(fullfile(pth_bids_example, 'ds000247'));
88+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'ds000247'));
9989

10090
data = bids.query(BIDS, 'data', 'sub', '.*', 'suffix', 'T1w');
10191

@@ -109,9 +99,7 @@ function test_query_regex_subjects()
10999

110100
function test_query_with_indices()
111101

112-
pth_bids_example = get_test_data_dir();
113-
114-
BIDS = bids.layout(fullfile(pth_bids_example, 'ds105'));
102+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'ds105'));
115103

116104
data_1 = bids.query(BIDS, 'data', 'sub', '1', 'run', {3, 5, '7', '01'}, 'suffix', 'bold');
117105
data_2 = bids.query(BIDS, 'data', 'sub', '1', 'run', 1:2:7, 'suffix', 'bold');
@@ -122,9 +110,7 @@ function test_query_with_indices()
122110

123111
function test_query_entities()
124112

125-
pth_bids_example = get_test_data_dir();
126-
127-
BIDS = bids.layout(fullfile(pth_bids_example, 'qmri_qsm'));
113+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'qmri_qsm'));
128114

129115
entities = bids.query(BIDS, 'entities');
130116

@@ -134,7 +120,7 @@ function test_query_entities()
134120
assertEqual(entities, expected);
135121

136122
%%
137-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet002'));
123+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet002'));
138124

139125
entities = bids.query(BIDS, 'entities', 'suffix', 'pet');
140126

@@ -147,24 +133,20 @@ function test_query_entities()
147133

148134
function test_query_events_tsv_in_root()
149135

150-
pth_bids_example = get_test_data_dir();
151-
152-
BIDS = bids.layout(fullfile(pth_bids_example, 'synthetic'));
136+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'synthetic'));
153137

154138
data = bids.query(BIDS, 'data', 'sub', '01', 'ses', '01', 'task', 'nback', 'suffix', 'events');
155139

156140
assertEqual(data, ...
157-
{bids.internal.file_utils(fullfile(pth_bids_example, ...
141+
{bids.internal.file_utils(fullfile(get_test_data_dir(), ...
158142
'synthetic', ...
159143
'task-nback_events.tsv'), 'cpath')});
160144

161145
end
162146

163147
function test_query_exclude_entity()
164148

165-
pth_bids_example = get_test_data_dir();
166-
167-
BIDS = bids.layout(fullfile(pth_bids_example, 'ds000246'));
149+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'ds000246'));
168150

169151
filter = struct('sub', '0001');
170152
assertEqual(bids.query(BIDS, 'modalities', filter), {'anat', 'meg'});
@@ -183,9 +165,7 @@ function test_query_exclude_entity()
183165

184166
function test_query_basic()
185167

186-
pth_bids_example = get_test_data_dir();
187-
188-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet005'));
168+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet005'));
189169

190170
tasks = {'eyes'};
191171
assertEqual(bids.query(BIDS, 'tasks'), tasks);
@@ -200,9 +180,7 @@ function test_query_basic()
200180

201181
function test_query_data_filter()
202182

203-
pth_bids_example = get_test_data_dir();
204-
205-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet005'));
183+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet005'));
206184

207185
% make sure that query can work with filter
208186
filters = {'sub', {'01'}; ...
@@ -223,9 +201,7 @@ function test_query_data_filter()
223201

224202
function test_query_extension()
225203

226-
pth_bids_example = get_test_data_dir();
227-
228-
BIDS = bids.layout(fullfile(pth_bids_example, 'qmri_tb1tfl'));
204+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'qmri_tb1tfl'));
229205

230206
extensions = bids.query(BIDS, 'extensions');
231207

@@ -244,9 +220,7 @@ function test_query_extension()
244220

245221
function test_query_metadata()
246222

247-
pth_bids_example = get_test_data_dir();
248-
249-
BIDS = bids.layout(fullfile(pth_bids_example, 'qmri_tb1tfl'));
223+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'qmri_tb1tfl'));
250224

251225
md = bids.query(BIDS, 'metadata', ...
252226
'sub', '01', ...
@@ -260,9 +234,7 @@ function test_query_metadata()
260234

261235
function test_query_modalities()
262236

263-
pth_bids_example = get_test_data_dir();
264-
265-
BIDS = bids.layout(fullfile(pth_bids_example, 'pet002'));
237+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'pet002'));
266238

267239
modalities = {'anat', 'pet'};
268240

@@ -274,9 +246,7 @@ function test_query_modalities()
274246

275247
function test_query_tsv_content()
276248

277-
pth_bids_example = get_test_data_dir();
278-
279-
BIDS = bids.layout(fullfile(pth_bids_example, 'eeg_ds003645s_hed_inheritance'));
249+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'eeg_ds003645s_hed_inheritance'));
280250

281251
tsv_content = bids.query(BIDS, 'tsv_content', 'suffix', 'events');
282252

@@ -297,34 +267,28 @@ function test_query_tsv_content()
297267

298268
function test_query_tsv_content_error()
299269

300-
pth_bids_example = get_test_data_dir();
301-
302-
BIDS = bids.layout(fullfile(pth_bids_example, 'qmri_tb1tfl'));
270+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'qmri_tb1tfl'));
303271
assertExceptionThrown(@()bids.query(BIDS, 'tsv_content', 'extension', '.nii.gz'), ...
304272
'query:notJustTsvFiles');
305273

306274
end
307275

308276
function test_query_sessions()
309277

310-
pth_bids_example = get_test_data_dir();
311-
312-
BIDS = bids.layout(fullfile(pth_bids_example, 'synthetic'));
278+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'synthetic'));
313279
sessions = {'01', '02'};
314280
assertEqual(bids.query(BIDS, 'sessions'), sessions);
315281
assertEqual(bids.query(BIDS, 'sessions', 'sub', '02'), sessions);
316282

317-
BIDS = bids.layout(fullfile(pth_bids_example, 'qmri_tb1tfl'));
283+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'qmri_tb1tfl'));
318284

319285
assert(isempty(bids.query(BIDS, 'sessions')));
320286

321287
end
322288

323289
function test_query_sessions_tsv()
324290

325-
pth_bids_example = get_test_data_dir();
326-
327-
BIDS = bids.layout(fullfile(pth_bids_example, 'synthetic'));
291+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'synthetic'));
328292

329293
suffixes = bids.query(BIDS, 'suffixes');
330294
assert(ismember('sessions', suffixes));
@@ -366,9 +330,7 @@ function test_query_sessions_tsv()
366330

367331
function test_query_scans_tsv()
368332

369-
pth_bids_example = get_test_data_dir();
370-
371-
BIDS = bids.layout(fullfile(pth_bids_example, 'motion_spotrotation'));
333+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'motion_spotrotation'));
372334

373335
suffixes = bids.query(BIDS, 'suffixes');
374336
assert(ismember('scans', suffixes));

tests/tests_query/test_bids_query_asl.m

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
function test_bids_query_asl_basic_asl002()
1010

11-
pth_bids_example = get_test_data_dir();
12-
13-
BIDS = bids.layout(fullfile(pth_bids_example, 'asl002'));
11+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'asl002'));
1412

1513
modalities = {'anat', 'perf'};
1614
assertEqual(bids.query(BIDS, 'modalities'), modalities);
@@ -37,9 +35,7 @@ function test_bids_query_asl_basic_asl002()
3735

3836
function test_bids_query_asl_basic_asl001()
3937

40-
pth_bids_example = get_test_data_dir();
41-
42-
BIDS = bids.layout(fullfile(pth_bids_example, 'asl001'));
38+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'asl001'));
4339

4440
modalities = {'anat', 'perf'};
4541
assertEqual(bids.query(BIDS, 'modalities'), modalities);
@@ -68,9 +64,7 @@ function test_bids_query_asl_basic_asl001()
6864

6965
function test_bids_query_asl_basic_asl003()
7066

71-
pth_bids_example = get_test_data_dir();
72-
73-
BIDS = bids.layout(fullfile(pth_bids_example, 'asl003'));
67+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'asl003'));
7468

7569
modalities = {'anat', 'perf'};
7670
assertEqual(bids.query(BIDS, 'modalities'), modalities);
@@ -82,9 +76,7 @@ function test_bids_query_asl_basic_asl003()
8276

8377
function test_bids_query_asl_basic_asl004()
8478

85-
pth_bids_example = get_test_data_dir();
86-
87-
BIDS = bids.layout(fullfile(pth_bids_example, 'asl004'));
79+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'asl004'));
8880

8981
modalities = {'anat', 'fmap', 'perf'};
9082
assertEqual(bids.query(BIDS, 'modalities'), modalities);

tests/tests_query/test_bids_query_derivatives.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
function test_bids_query_derivatives_basic()
1010

11-
pth_bids_example = get_test_data_dir();
12-
13-
BIDS = bids.layout(fullfile(pth_bids_example, 'ds000001-fmriprep'), ...
11+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'ds000001-fmriprep'), ...
1412
'use_schema', false);
1513

1614
spaces = bids.query(BIDS, 'spaces');

tests/tests_query/test_bids_query_dwi.m

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ function test_bids_query_dwi_basic()
1010
%
1111
% dwi queries
1212
%
13-
14-
pth_bids_example = get_test_data_dir();
15-
1613
%%
17-
BIDS = bids.layout(fullfile(pth_bids_example, 'eeg_rest_fmri'));
14+
BIDS = bids.layout(fullfile(get_test_data_dir(), 'eeg_rest_fmri'));
1815

1916
modalities = {'anat', 'dwi', 'eeg', 'func'};
2017
assertEqual(bids.query(BIDS, 'modalities'), modalities);

0 commit comments

Comments
 (0)