Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/bids_validator/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ def walk_back(
yield file_group
elif len(file_group) == 1:
yield file_group[0]
else:
raise ValidationError('Multiple matching files.')
elif file_group:
raise ValidationError(f'Multiple matching files: {file_group}')


def _walk_back(
Expand All @@ -230,19 +230,19 @@ def _walk_back(
target_suffix: str | None,
target_entities: tuple[str, ...],
) -> Generator[list[FileTree, ...]]:
file_parts = FileParts.from_file(source.relative_path)
file_parts = FileParts.from_file(source)

if target_suffix is None:
target_suffix = file_parts.suffix

tree = source.parent
while tree:
matches = []
for child in tree.children:
for child in tree.children.values():
if child.is_dir:
continue
parts = FileParts.from_file(child.relative_path)
if parts.extension != target_extensions:
parts = FileParts.from_file(child)
if parts.extension not in target_extensions:
continue
if parts.suffix != target_suffix:
continue
Expand Down Expand Up @@ -270,7 +270,7 @@ class FileParts:
extension: str | None

@classmethod
def from_file(cls, file: FileTree, schema: Namespace) -> t.Self:
def from_file(cls, file: FileTree, schema: Namespace | None = None) -> t.Self:
"""Parse file parts from FileTree object."""
stem, _, extension = file.name.partition('.')

Expand All @@ -280,7 +280,7 @@ def from_file(cls, file: FileTree, schema: Namespace) -> t.Self:
extension = f'{extension}/'

datatype = None
if file.parent:
if file.parent and schema:
if any(file.parent.name == dtype.value for dtype in schema.objects.datatypes.values()):
datatype = file.parent.name

Expand Down
51 changes: 31 additions & 20 deletions tests/test_context.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import pytest

from bids_validator import context
from bids_validator.types.files import FileTree

import pytest

def test_load(examples, schema):
tree = FileTree.read_from_filesystem(examples / 'synthetic')
ds = context.Dataset(tree, schema)
@pytest.fixture
def synthetic_dataset(examples):
return FileTree.read_from_filesystem(examples / 'synthetic')


def test_load(synthetic_dataset, schema):
ds = context.Dataset(synthetic_dataset, schema)

assert ds.dataset_description.Name.startswith('Synthetic dataset')
assert ds.subjects.participant_id == [f'sub-{i:02d}' for i in range(1, 6)]
assert sorted(ds.subjects.sub_dirs) == [f'sub-{i:02d}' for i in range(1, 6)]
assert sorted(ds.datatypes) == ["anat", "beh", "func"]
assert sorted(ds.modalities) == ["beh", "mri"]


@pytest.mark.parametrize(
"depth, expected",
[
(2, {"anat", "beh", "func"}),
(1, set())
])
def test_find_datatypes(examples, schema, depth, expected):
tree = FileTree.read_from_filesystem(examples / 'synthetic')
assert sorted(ds.datatypes) == ['anat', 'beh', 'func']
assert sorted(ds.modalities) == ['beh', 'mri']


@pytest.mark.parametrize(('depth', 'expected'), [(2, {'anat', 'beh', 'func'}), (1, set())])
def test_find_datatypes(synthetic_dataset, schema, depth, expected):
datatypes = schema.objects.datatypes

result = context.find_datatypes(tree, datatypes, max_depth=depth)
result = context.find_datatypes(synthetic_dataset, datatypes, max_depth=depth)

assert result == expected

def test_fileparts(examples, schema):
tree = FileTree.read_from_filesystem(examples / 'synthetic')

T1w = tree / 'sub-01' / 'ses-01' / 'anat' / 'sub-01_ses-01_T1w.nii'
def test_fileparts(synthetic_dataset, schema):
T1w = synthetic_dataset / 'sub-01' / 'ses-01' / 'anat' / 'sub-01_ses-01_T1w.nii'
parts = context.FileParts.from_file(T1w, schema)
assert parts == context.FileParts(
path='/sub-01/ses-01/anat/sub-01_ses-01_T1w.nii',
Expand All @@ -41,3 +39,16 @@ def test_fileparts(examples, schema):
suffix='T1w',
extension='.nii',
)


def test_walkback(synthetic_dataset, schema):
bold = (
synthetic_dataset
/ 'sub-01'
/ 'ses-01'
/ 'func'
/ 'sub-01_ses-01_task-nback_run-01_bold.nii'
)
sidecars = list(context.walk_back(bold, inherit=True))
assert len(sidecars) == 1
assert sidecars[0] is synthetic_dataset / 'task-nback_bold.json'
Loading