Skip to content

Commit bab04e4

Browse files
kousueffigies
authored andcommitted
Backport gh-791
Fixup #746 This line seems to have been forgotten when pathlib was introduced. Without this patch, this BIDSLayout is unusable: ```python with importlib.resources.path(spinegeneric.config, 'bids_specs.json') as path_sg_layout_config: layout = BIDSLayout(data_path,indexer=BIDSLayoutIndexer(config_filename=path_sg_layout_config),validate=False) ``` hits ``` File ".../site-packages/bids/layout/models.py", line 156, in load result = session.query(Config).filter_by(name=config['name']).first() TypeError: 'PosixPath' object is not subscriptable ``` e.g. https://github.com/spine-generic/data-multi-subject/pull/96/checks#step:13:9 Test BIDSLayout can take custom config_filenames Test that the entities *defined* by config_filename are respected. Update bids/layout/tests/test_layout.py Update bids/layout/tests/test_layout.py TEST: Pass config to layout, check both str and Path work FIX: Normalize Paths when storing in databases
1 parent bc0ea9a commit bab04e4

File tree

3 files changed

+119
-1
lines changed

3 files changed

+119
-1
lines changed

bids/layout/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ def _sanitize_init_args(self, kwargs):
5959
if 'root' in kwargs:
6060
kwargs['root'] = str(Path(kwargs['root']).absolute())
6161

62+
if isinstance(kwargs.get('config'), os.PathLike):
63+
kwargs['config'] = str(Path(kwargs['config']).absolute())
64+
6265
# Get abspaths
6366
if kwargs.get('derivatives') not in (None, True, False):
6467
kwargs['derivatives'] = [
@@ -141,7 +144,7 @@ def load(self, config, session=None):
141144
A Config instance.
142145
"""
143146

144-
if isinstance(config, str):
147+
if isinstance(config, (str, Path)):
145148
config_paths = get_option('config_paths')
146149
if config in config_paths:
147150
config = config_paths[config]

bids/layout/tests/test_layout.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ def test_index_metadata(index_metadata, query, result, mock_config):
4848
assert metadata.get('RepetitionTime') == result
4949

5050

51+
52+
@pytest.mark.parametrize('config_type', [str, Path])
53+
def test_config_filename(config_type):
54+
data_path = Path(get_test_data_path())
55+
# Use custom config that replaces session with oligarchy
56+
config_path = data_path.parent / 'bids_specs_with_oligarchy.json'
57+
layout = BIDSLayout(data_path / "7t_trt", config=config_type(config_path))
58+
# Validate that we are using the desired configuration
59+
assert 'oligarchy' in layout.get_entities()
60+
61+
5162
def test_layout_repr(layout_7t_trt):
5263
assert "Subjects: 10 | Sessions: 20 | Runs: 20" in str(layout_7t_trt)
5364

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
{
2+
"name": "bids",
3+
"entities": [
4+
{
5+
"name": "subject",
6+
"pattern": "[/\\\\]+sub-([a-zA-Z0-9]+)",
7+
"directory": "{subject}"
8+
},
9+
{
10+
"name": "oligarchy",
11+
"pattern": "[_/\\\\]+ses-([a-zA-Z0-9]+)",
12+
"mandatory": false,
13+
"directory": "{subject}{oligarchy}"
14+
},
15+
{
16+
"name": "task",
17+
"pattern": "[_/\\\\]+task-([a-zA-Z0-9]+)"
18+
},
19+
{
20+
"name": "acquisition",
21+
"pattern": "[_/\\\\]+acq-([a-zA-Z0-9]+)"
22+
},
23+
{
24+
"name": "ceagent",
25+
"pattern": "[_/\\\\]+ce-([a-zA-Z0-9]+)"
26+
},
27+
{
28+
"name": "reconstruction",
29+
"pattern": "[_/\\\\]+rec-([a-zA-Z0-9]+)"
30+
},
31+
{
32+
"name": "direction",
33+
"pattern": "[_/\\\\]+dir-([a-zA-Z0-9]+)"
34+
},
35+
{
36+
"name": "run",
37+
"pattern": "[_/\\\\]+run-0*(\\d+)",
38+
"dtype": "int"
39+
},
40+
{
41+
"name": "proc",
42+
"pattern": "[_/\\\\]+proc-([a-zA-Z0-9]+)"
43+
},
44+
{
45+
"name": "modality",
46+
"pattern": "[_/\\\\]+mod-([a-zA-Z0-9]+)"
47+
},
48+
{
49+
"name": "echo",
50+
"pattern": "[_/\\\\]+echo-([0-9]+)"
51+
},
52+
{
53+
"name": "recording",
54+
"pattern": "[_/\\\\]+recording-([a-zA-Z0-9]+)"
55+
},
56+
{
57+
"name": "space",
58+
"pattern": "[_/\\\\]+space-([a-zA-Z0-9]+)"
59+
},
60+
{
61+
"name": "suffix",
62+
"pattern": "[._]*([a-zA-Z0-9]*?)\\.[^/\\\\]+$"
63+
},
64+
{
65+
"name": "scans",
66+
"pattern": "(.*\\_scans.tsv)$"
67+
},
68+
{
69+
"name": "fmap",
70+
"pattern": "(phasediff|magnitude[1-2]|phase[1-2]|fieldmap|epi)\\.nii"
71+
},
72+
{
73+
"name": "datatype",
74+
"pattern": "[/\\\\]+(func|anat|fmap|dwi|meg|eeg)[/\\\\]+"
75+
},
76+
{
77+
"name": "extension",
78+
"pattern": "[._]*[a-zA-Z0-9]*?(\\.[^/\\\\]+)$"
79+
}
80+
],
81+
82+
"default_path_patterns": [
83+
"sub-{subject}[/ses-{oligarchy}]/{datatype<anat>|anat}/sub-{subject}[_ses-{oligarchy}][_acq-{acquisition}][_ce-{ceagent}][_rec-{reconstruction}]_{suffix<T1w|T2w|T1rho|T1map|T2map|T2star|FLAIR|FLASH|PDmap|PD|PDT2|inplaneT[12]|angio|MTS>}{extension<.nii|.nii.gz|.json>|.nii.gz}",
84+
"sub-{subject}[/ses-{oligarchy}]/{datatype<anat>|anat}/sub-{subject}[_ses-{oligarchy}][_acq-{acquisition}][_ce-{ceagent}][_rec-{reconstruction}][_mod-{modality}]_{suffix<defacemask>}{extension<.nii|.nii.gz|.json>|.nii.gz}",
85+
"sub-{subject}[/ses-{oligarchy}]/{datatype<func>|func}/sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}][_ce-{ceagent}][_dir-{direction}][_rec-{reconstruction}][_run-{run}][_echo-{echo}]_{suffix<bold|cbv|phase|sbref>}{extension<.nii|.nii.gz|.json>|.nii.gz}",
86+
"sub-{subject}[/ses-{oligarchy}]/{datatype<dwi>|dwi}/sub-{subject}[_ses-{oligarchy}][_acq-{acquisition}]_{suffix<dwi>}{extension<.bval|.bvec|.json|.nii.gz|.nii>|.nii.gz}",
87+
"sub-{subject}[/ses-{oligarchy}]/{datatype<fmap>|fmap}/sub-{subject}[_ses-{oligarchy}][_acq-{acquisition}][_dir-{direction}][_run-{run}]_{fmap<phasediff|magnitude[12]|phase[12]|fieldmap>}{extension<.nii|.nii.gz|.json>|.nii.gz}",
88+
"sub-{subject}[/ses-{oligarchy}]/{datatype<fmap>|fmap}/sub-{subject}[_ses-{oligarchy}][_acq-{acquisition}][_ce-{ceagent}]_dir-{direction}[_run-{run}]_{fmap<epi>}{extension<.nii|.nii.gz|.json>|.nii.gz}",
89+
"sub-{subject}[/ses-{oligarchy}]/[{datatype<func|meg|beh>|func}/]sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<events>}{extension<.tsv|.json>|.tsv}",
90+
"sub-{subject}[/ses-{oligarchy}]/[{datatype<func|beh>|func}/]sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<physio|stim>}{extension<.tsv.gz|.json>|.tsv.gz}",
91+
"sub-{subject}[/ses-{oligarchy}]/{datatype<meg>|meg}/sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}][_run-{run}][_proc-{proc}]_{suffix<meg>}{extension}",
92+
"sub-{subject}[/ses-{oligarchy}]/{datatype<meg>|meg}/sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}][_run-{run}][_proc-{proc}]_{suffix<channels>}{extension<.tsv|.json>|.tsv}",
93+
"sub-{subject}[/ses-{oligarchy}]/{datatype<meg>|meg}/sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}]_{suffix<coordsystem>}{extension<.json>|.json}",
94+
"sub-{subject}[/ses-{oligarchy}]/{datatype<meg>|meg}/sub-{subject}[_ses-{oligarchy}]_task-{task}[_acq-{acquisition}]_{suffix<photo>}{extension<.jpg>|.jpg}",
95+
"[acq-{acquisition}_][ce-{ceagent}_][rec-{reconstruction}_]{suffix<T1w|T2w|T1rho|T1map|T2map|T2star|FLAIR|FLASH|PDmap|PD|PDT2|inplaneT[12]|angio|MTS>}{extension<.json>|.json}",
96+
"[acq-{acquisition}_][ce-{ceagent}_][rec-{reconstruction}_][mod-{modality}_]{suffix<defacemask>}{extension<.json>|.json}",
97+
"task-{task}[_acq-{acquisition}][_ce-{ceagent}][_dir-{direction}][_rec-{reconstruction}][_run-{run}][_echo-{echo}]_{suffix<bold|cbv|phase|sbref>}{extension<.json>|.json}",
98+
"[acq-{acquisition}_]{suffix<dwi>}{extension<.json>|.json}",
99+
"[acq-{acquisition}_][dir-{direction}_][run-{run}_]{fmap<phasediff|magnitude[1-2]|phase[1-2]|fieldmap>}{extension<.json>|.json}",
100+
"[acq-{acquisition}_][ce-{ceagent}_]dir-{direction}[_run-{run}]_{fmap<epi>}{extension<.json>|.json}",
101+
"task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<events>}{extension<.json>|.json}",
102+
"task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<physio|stim>}{extension<.json>}"
103+
]
104+
}

0 commit comments

Comments
 (0)