1- import os
21import re
32from collections .abc import Iterator
43from functools import cached_property
4+ from pathlib import Path
55
66from bids import BIDSLayout
77
88from lib .imaging_lib .bids .dataset_description import BidsDatasetDescription
99from lib .imaging_lib .bids .tsv_participants import BidsTsvParticipant , read_bids_participants_tsv_file
1010from lib .imaging_lib .bids .tsv_scans import BidsTsvScan , read_bids_scans_tsv_file
11- from lib .imaging_lib .nifti import find_dir_nifti_names
11+ from lib .imaging_lib .nifti import find_dir_nifti_files
1212from lib .util .fs import replace_file_extension , search_dir_file_with_regex
1313from lib .util .iter import find
1414
1818
1919
2020class BIDSDataset :
21- path : str
21+ path : Path
2222 validate : bool
2323
24- def __init__ (self , bids_path : str , validate : bool ):
24+ def __init__ (self , bids_path : Path , validate : bool ):
2525 self .path = bids_path
2626 self .validate = validate
2727
@@ -48,12 +48,12 @@ def subjects(self) -> list['BIDSSubject']:
4848
4949 subjects : list [BIDSSubject ] = []
5050
51- for file in os . scandir ( self .path ):
51+ for file in self .path . iterdir ( ):
5252 subject_match = re .match (r'sub-([a-zA-Z0-9]+)' , file .name )
5353 if subject_match is None :
5454 continue
5555
56- if not os . path . isdir ( file ):
56+ if not file . is_dir ( ):
5757 continue
5858
5959 subject_label = subject_match .group (1 )
@@ -68,8 +68,8 @@ def get_dataset_description(self) -> 'BidsDatasetDescription | None':
6868 does contains incorrect data.
6969 """
7070
71- dataset_description_path = os . path . join ( self .path , 'dataset_description.json' )
72- if not os . path . exists (dataset_description_path ):
71+ dataset_description_path = self .path / 'dataset_description.json'
72+ if not dataset_description_path . exists ():
7373 return None
7474
7575 return BidsDatasetDescription (dataset_description_path )
@@ -81,8 +81,8 @@ def tsv_participants(self) -> dict[str, BidsTsvParticipant] | None:
8181 present. This property might raise an exception if the file is present but incorrect.
8282 """
8383
84- tsv_participants_path = os . path . join ( self .path , 'participants.tsv' )
85- if not os . path . exists (tsv_participants_path ):
84+ tsv_participants_path = self .path / 'participants.tsv'
85+ if not tsv_participants_path . exists ():
8686 return None
8787
8888 return read_bids_participants_tsv_file (tsv_participants_path )
@@ -143,13 +143,13 @@ def layout(self) -> BIDSLayout:
143143
144144class BIDSSubject :
145145 root_dataset : BIDSDataset
146+ path : Path
146147 label : str
147- path : str
148148
149149 def __init__ (self , root_dataset : BIDSDataset , label : str ):
150150 self .root_dataset = root_dataset
151151 self .label = label
152- self .path = os . path . join ( self .root_dataset .path , f'sub-{ self .label } ' )
152+ self .path = self .root_dataset .path / f'sub-{ self .label } '
153153
154154 @property
155155 def data_types (self ) -> Iterator ['BIDSDataType' ]:
@@ -169,8 +169,8 @@ def sessions(self) -> list['BIDSSession']:
169169
170170 sessions : list [BIDSSession ] = []
171171
172- for file in os . scandir ( self .path ):
173- if not os . path . isdir ( file ):
172+ for file in self .path . iterdir ( ):
173+ if not file . is_dir ( ):
174174 continue
175175
176176 session_match = re .match (r'ses-([a-zA-Z0-9]+)' , file .name )
@@ -195,23 +195,19 @@ def get_session(self, session_label: str) -> 'BIDSSession | None':
195195
196196class BIDSSession :
197197 subject : BIDSSubject
198+ path : Path
198199 label : str | None
199- path : str
200- tsv_scans_path : str | None
200+ tsv_scans_path : Path | None
201201
202202 def __init__ (self , subject : BIDSSubject , label : str | None ):
203203 self .subject = subject
204204 self .label = label
205- if label is None :
206- self .path = self . subject .path
205+ if label is not None :
206+ self .path = subject .path / f'ses- { self . label } '
207207 else :
208- self .path = os . path . join ( self . subject .path , f'ses- { self . label } ' )
208+ self .path = subject .path
209209
210- tsv_scans_name = search_dir_file_with_regex (self .path , r'scans.tsv$' )
211- if tsv_scans_name is not None :
212- self .tsv_scans_path = os .path .join (self .path , tsv_scans_name )
213- else :
214- self .tsv_scans_path = None
210+ self .tsv_scans_path = search_dir_file_with_regex (self .path , r'scans.tsv$' )
215211
216212 @property
217213 def root_dataset (self ) -> BIDSDataset :
@@ -230,8 +226,8 @@ def data_types(self) -> list['BIDSDataType']:
230226
231227 data_types : list [BIDSDataType ] = []
232228
233- for file in os . scandir ( self .path ):
234- if not os . path . isdir ( file ):
229+ for file in self .path . iterdir ( ):
230+ if not file . is_dir ( ):
235231 continue
236232
237233 data_types .append (BIDSDataType (self , file .name ))
@@ -264,13 +260,15 @@ def get_tsv_scan(self, file_name: str) -> 'BidsTsvScan | None':
264260
265261class BIDSDataType :
266262 session : BIDSSession
267- name : str
268- path : str
263+ path : Path
269264
270265 def __init__ (self , session : BIDSSession , name : str ):
271266 self .session = session
272- self .name = name
273- self .path = os .path .join (self .session .path , self .name )
267+ self .path = session .path / name
268+
269+ @property
270+ def name (self ) -> str :
271+ return self .path .name
274272
275273 @property
276274 def root_dataset (self ) -> BIDSDataset :
@@ -288,29 +286,31 @@ def niftis(self) -> list['BIDSNifti']:
288286
289287 niftis : list [BIDSNifti ] = []
290288
291- for nifti_name in find_dir_nifti_names (self .path ):
292- niftis .append (BIDSNifti (self , nifti_name ))
289+ for nifti_path in find_dir_nifti_files (self .path ):
290+ niftis .append (BIDSNifti (self , nifti_path . name ))
293291
294292 return niftis
295293
296294
297295class BIDSNifti :
298296 data_type : BIDSDataType
299- name : str
300- path : str
297+ path : Path
301298 suffix : str | None
302299
303300 def __init__ (self , data_type : BIDSDataType , name : str ):
304301 self .data_type = data_type
305- self .path = os .path .join (self .data_type .path , name )
306- self .name = name
302+ self .path = data_type .path / name
307303
308304 suffix_match = re .search (r'_([a-zA-Z0-9]+)\.nii(\.gz)?$' , self .name )
309305 if suffix_match is not None :
310306 self .suffix = suffix_match .group (1 )
311307 else :
312308 self .suffix = None
313309
310+ @property
311+ def name (self ) -> str :
312+ return self .path .name
313+
314314 @property
315315 def root_dataset (self ) -> BIDSDataset :
316316 return self .data_type .root_dataset
@@ -323,38 +323,38 @@ def subject(self) -> BIDSSubject:
323323 def session (self ) -> BIDSSession :
324324 return self .data_type .session
325325
326- def get_json_path (self ) -> str | None :
326+ def get_json_path (self ) -> Path | None :
327327 """
328328 Get the JSON sidecar file path of this NIfTI file if it exists.
329329 """
330330
331331 json_name = replace_file_extension (self .name , 'json' )
332- json_path = os . path . join ( self .data_type .path , json_name )
333- if not os . path . exists (json_path ):
332+ json_path = self .data_type .path / json_name
333+ if not json_path . exists ():
334334 return None
335335
336336 return json_path
337337
338- def get_bval_path (self ) -> str | None :
338+ def get_bval_path (self ) -> Path | None :
339339 """
340340 Get the BVAL file path of this NIfTI file if it exists.
341341 """
342342
343343 bval_name = replace_file_extension (self .name , 'bval' )
344- bval_path = os . path . join ( self .data_type .path , bval_name )
345- if not os . path . exists (bval_path ):
344+ bval_path = self .data_type .path / bval_name
345+ if not bval_path . exists ():
346346 return None
347347
348348 return bval_path
349349
350- def get_bvec_path (self ) -> str | None :
350+ def get_bvec_path (self ) -> Path | None :
351351 """
352352 Get the BVEC file path of this NIfTI file if it exists.
353353 """
354354
355355 bvec_name = replace_file_extension (self .name , 'bvec' )
356- bvec_path = os . path . join ( self .data_type .path , bvec_name )
357- if not os . path . exists (bvec_path ):
356+ bvec_path = self .data_type .path / bvec_name
357+ if not bvec_path . exists ():
358358 return None
359359
360360 return bvec_path
0 commit comments