Skip to content

Commit e639a50

Browse files
committed
added pybids compatability layer
1 parent c1d67b2 commit e639a50

10 files changed

Lines changed: 1215 additions & 1 deletion

File tree

bids2table/pybids/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
__all__ = [
2+
"BIDSLayout",
3+
"BIDSFile",
4+
"Query",
5+
"listify"
6+
]
7+
8+
from ._layout import BIDSLayout
9+
from ._bidsfile import BIDSFile
10+
from ._utils import (
11+
Query,
12+
listify,
13+
)
14+

bids2table/pybids/_bidsfile.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
"""
2+
BIDSFile wrapper for file paths with entity access.
3+
4+
Provides a PyBIDS-compatible file object that can parse and cache
5+
BIDS entities from file paths.
6+
"""
7+
8+
from pathlib import Path
9+
from typing import Dict, Any, Optional
10+
11+
from .._entities import parse_bids_entities
12+
13+
14+
class BIDSFile:
15+
"""
16+
Wrapper around a BIDS file path with entity parsing.
17+
18+
Provides PyBIDS-compatible interface for accessing file entities.
19+
Entities are lazily parsed and cached on first access.
20+
21+
Example:
22+
>>> from bids2table_compat import BIDSFile
23+
>>> f = BIDSFile('sub-01/func/sub-01_task-rest_bold.nii.gz')
24+
>>> entities = f.get_entities()
25+
>>> print(entities)
26+
{'sub': '01', 'task': 'rest', 'suffix': 'bold', 'ext': '.nii.gz'}
27+
"""
28+
29+
def __init__(self, path: str):
30+
"""
31+
Initialize BIDSFile.
32+
33+
Args:
34+
path: Path to BIDS file (absolute or relative)
35+
"""
36+
self.path = str(path)
37+
self._entities: Optional[Dict[str, Any]] = None
38+
39+
def get_entities(self) -> Dict[str, Any]:
40+
"""
41+
Parse and return BIDS entities from filename.
42+
43+
Entities are cached after first parse for performance.
44+
45+
Returns:
46+
Dictionary of BIDS entities (e.g., {'sub': '01', 'task': 'rest'})
47+
"""
48+
if self._entities is None:
49+
self._entities = parse_bids_entities(self.path)
50+
return self._entities
51+
52+
def __str__(self) -> str:
53+
"""String representation showing file path."""
54+
return self.path
55+
56+
def __repr__(self) -> str:
57+
"""Developer-friendly representation."""
58+
return f"BIDSFile('{self.path}')"
59+
60+
def __eq__(self, other) -> bool:
61+
"""Equality based on path."""
62+
if isinstance(other, BIDSFile):
63+
return self.path == other.path
64+
return False
65+
66+
def __hash__(self) -> int:
67+
"""Allow use in sets/dicts."""
68+
return hash(self.path)
69+
70+
def __lt__(self, other) -> bool:
71+
"""Less-than comparison based on path (for sorting)."""
72+
if isinstance(other, BIDSFile):
73+
return self.path < other.path
74+
return NotImplemented
75+
76+
def __le__(self, other) -> bool:
77+
"""Less-than-or-equal comparison based on path."""
78+
if isinstance(other, BIDSFile):
79+
return self.path <= other.path
80+
return NotImplemented
81+
82+
def __gt__(self, other) -> bool:
83+
"""Greater-than comparison based on path."""
84+
if isinstance(other, BIDSFile):
85+
return self.path > other.path
86+
return NotImplemented
87+
88+
def __ge__(self, other) -> bool:
89+
"""Greater-than-or-equal comparison based on path."""
90+
if isinstance(other, BIDSFile):
91+
return self.path >= other.path
92+
return NotImplemented
93+
94+
def __contains__(self, item) -> bool:
95+
"""Check if substring is in the file path (for 'in' operator)."""
96+
return item in self.path

0 commit comments

Comments
 (0)