Skip to content

Commit c5de9dc

Browse files
committed
migrate bids importer from str to path
1 parent 5017156 commit c5de9dc

File tree

12 files changed

+102
-92
lines changed

12 files changed

+102
-92
lines changed

python/lib/imaging_lib/bids/dataset.py

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
import re
33
from collections.abc import Iterator
44
from functools import cached_property
5+
from pathlib import Path
56

67
from bids import BIDSLayout
78

89
from lib.imaging_lib.bids.dataset_description import BidsDatasetDescription
910
from lib.imaging_lib.bids.tsv_participants import BidsTsvParticipant, read_bids_participants_tsv_file
1011
from lib.imaging_lib.bids.tsv_scans import BidsTsvScan, read_bids_scans_tsv_file
11-
from lib.imaging_lib.nifti import find_dir_nifti_names
12+
from lib.imaging_lib.nifti import find_dir_nifti_files
1213
from lib.util.fs import replace_file_extension, search_dir_file_with_regex
1314
from lib.util.iter import find
1415

@@ -18,10 +19,10 @@
1819

1920

2021
class BIDSDataset:
21-
path: str
22+
path: Path
2223
validate: bool
2324

24-
def __init__(self, bids_path: str, validate: bool):
25+
def __init__(self, bids_path: Path, validate: bool):
2526
self.path = bids_path
2627
self.validate = validate
2728

@@ -68,8 +69,8 @@ def get_dataset_description(self) -> 'BidsDatasetDescription | None':
6869
does contains incorrect data.
6970
"""
7071

71-
dataset_description_path = os.path.join(self.path, 'dataset_description.json')
72-
if not os.path.exists(dataset_description_path):
72+
dataset_description_path = self.path / 'dataset_description.json'
73+
if not dataset_description_path.exists():
7374
return None
7475

7576
return BidsDatasetDescription(dataset_description_path)
@@ -81,8 +82,8 @@ def tsv_participants(self) -> dict[str, BidsTsvParticipant] | None:
8182
present. This property might raise an exception if the file is present but incorrect.
8283
"""
8384

84-
tsv_participants_path = os.path.join(self.path, 'participants.tsv')
85-
if not os.path.exists(tsv_participants_path):
85+
tsv_participants_path = self.path / 'participants.tsv'
86+
if not tsv_participants_path.exists():
8687
return None
8788

8889
return read_bids_participants_tsv_file(tsv_participants_path)
@@ -143,13 +144,13 @@ def layout(self) -> BIDSLayout:
143144

144145
class BIDSSubject:
145146
root_dataset: BIDSDataset
147+
path: Path
146148
label: str
147-
path: str
148149

149150
def __init__(self, root_dataset: BIDSDataset, label: str):
150151
self.root_dataset = root_dataset
151152
self.label = label
152-
self.path = os.path.join(self.root_dataset.path, f'sub-{self.label}')
153+
self.path = self.root_dataset.path / f'sub-{self.label}'
153154

154155
@property
155156
def data_types(self) -> Iterator['BIDSDataType']:
@@ -195,23 +196,19 @@ def get_session(self, session_label: str) -> 'BIDSSession | None':
195196

196197
class BIDSSession:
197198
subject: BIDSSubject
199+
path: Path
198200
label: str | None
199-
path: str
200-
tsv_scans_path: str | None
201+
tsv_scans_path: Path | None
201202

202203
def __init__(self, subject: BIDSSubject, label: str | None):
203204
self.subject = subject
204205
self.label = label
205-
if label is None:
206-
self.path = self.subject.path
206+
if label is not None:
207+
self.path = subject.path / f'ses-{self.label}'
207208
else:
208-
self.path = os.path.join(self.subject.path, f'ses-{self.label}')
209+
self.path = subject.path
209210

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
211+
self.tsv_scans_path = search_dir_file_with_regex(self.path, r'scans.tsv$')
215212

216213
@property
217214
def root_dataset(self) -> BIDSDataset:
@@ -264,13 +261,15 @@ def get_tsv_scan(self, file_name: str) -> 'BidsTsvScan | None':
264261

265262
class BIDSDataType:
266263
session: BIDSSession
267-
name: str
268-
path: str
264+
path: Path
269265

270266
def __init__(self, session: BIDSSession, name: str):
271267
self.session = session
272-
self.name = name
273-
self.path = os.path.join(self.session.path, self.name)
268+
self.path = session.path / name
269+
270+
@property
271+
def name(self) -> str:
272+
return self.path.name
274273

275274
@property
276275
def root_dataset(self) -> BIDSDataset:
@@ -288,29 +287,31 @@ def niftis(self) -> list['BIDSNifti']:
288287

289288
niftis: list[BIDSNifti] = []
290289

291-
for nifti_name in find_dir_nifti_names(self.path):
292-
niftis.append(BIDSNifti(self, nifti_name))
290+
for nifti_path in find_dir_nifti_files(self.path):
291+
niftis.append(BIDSNifti(self, nifti_path.name))
293292

294293
return niftis
295294

296295

297296
class BIDSNifti:
298297
data_type: BIDSDataType
299-
name: str
300-
path: str
298+
path: Path
301299
suffix: str | None
302300

303301
def __init__(self, data_type: BIDSDataType, name: str):
304302
self.data_type = data_type
305-
self.path = os.path.join(self.data_type.path, name)
306-
self.name = name
303+
self.path = data_type.path / name
307304

308305
suffix_match = re.search(r'_([a-zA-Z0-9]+)\.nii(\.gz)?$', self.name)
309306
if suffix_match is not None:
310307
self.suffix = suffix_match.group(1)
311308
else:
312309
self.suffix = None
313310

311+
@property
312+
def name(self) -> str:
313+
return self.path.name
314+
314315
@property
315316
def root_dataset(self) -> BIDSDataset:
316317
return self.data_type.root_dataset
@@ -323,38 +324,38 @@ def subject(self) -> BIDSSubject:
323324
def session(self) -> BIDSSession:
324325
return self.data_type.session
325326

326-
def get_json_path(self) -> str | None:
327+
def get_json_path(self) -> Path | None:
327328
"""
328329
Get the JSON sidecar file path of this NIfTI file if it exists.
329330
"""
330331

331332
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):
333+
json_path = self.data_type.path / json_name
334+
if not json_path.exists():
334335
return None
335336

336337
return json_path
337338

338-
def get_bval_path(self) -> str | None:
339+
def get_bval_path(self) -> Path | None:
339340
"""
340341
Get the BVAL file path of this NIfTI file if it exists.
341342
"""
342343

343344
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):
345+
bval_path = self.data_type.path / bval_name
346+
if not bval_path.exists():
346347
return None
347348

348349
return bval_path
349350

350-
def get_bvec_path(self) -> str | None:
351+
def get_bvec_path(self) -> Path | None:
351352
"""
352353
Get the BVEC file path of this NIfTI file if it exists.
353354
"""
354355

355356
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):
357+
bvec_path = self.data_type.path / bvec_name
358+
if not bvec_path.exists():
358359
return None
359360

360361
return bvec_path

python/lib/imaging_lib/bids/dataset_description.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from pathlib import Path
23
from typing import Any
34

45

@@ -31,7 +32,7 @@ class BidsDatasetDescription:
3132
The BIDS dataset description JSON data.
3233
"""
3334

34-
def __init__(self, dataset_descrption_path: str):
35+
def __init__(self, dataset_descrption_path: Path):
3536
"""
3637
Read a BIDS dataset description file, or raise an exception if that file contains incorrect
3738
data.

python/lib/imaging_lib/bids/json.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from pathlib import Path
23
from typing import Any
34

45
from lib.config import get_patient_id_dicom_header_config
@@ -41,7 +42,7 @@ def get_bids_json_session_info(env: Env, bids_json: dict[str, Any]) -> SessionIn
4142
return get_session_info(env, patient_id, scanner_info)
4243

4344

44-
def add_bids_json_file_parameters(env: Env, bids_json_path: str, rel_json_path: str, file_parameters: dict[str, Any]):
45+
def add_bids_json_file_parameters(env: Env, bids_json_path: Path, rel_json_path: str, file_parameters: dict[str, Any]):
4546
"""
4647
Read a BIDS JSON sidecar file and add its parameters to a LORIS file parameters dictionary.
4748
"""

python/lib/imaging_lib/bids/tsv_participants.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import csv
22
import re
33
from dataclasses import dataclass
4+
from pathlib import Path
45

56
from dateutil.parser import ParserError, parse
67

@@ -21,7 +22,7 @@ class BidsTsvParticipant:
2122
project: str | None = None
2223

2324

24-
def read_bids_participants_tsv_file(participants_tsv_path: str) -> dict[str, BidsTsvParticipant]:
25+
def read_bids_participants_tsv_file(participants_tsv_path: Path) -> dict[str, BidsTsvParticipant]:
2526
"""
2627
Read the `participants.tsv` file of a BIDS dataset and get the participant rows indexed by
2728
participant ID. Raise an exception if the `participants.tsv` file is incorrect.
@@ -42,7 +43,7 @@ def read_bids_participants_tsv_file(participants_tsv_path: str) -> dict[str, Bid
4243

4344
def read_bids_participants_tsv_row(
4445
tsv_participant_row: dict[str, str],
45-
participants_tsv_path: str,
46+
participants_tsv_path: Path,
4647
) -> BidsTsvParticipant:
4748
"""
4849
Read a `participants.tsv` row, or raise an exception if that row is incorrect.
@@ -70,7 +71,7 @@ def read_bids_participants_tsv_row(
7071
)
7172

7273

73-
def write_bids_participants_tsv_file(tsv_participants: dict[str, BidsTsvParticipant], participants_file_path: str):
74+
def write_bids_participants_tsv_file(tsv_participants: dict[str, BidsTsvParticipant], participants_file_path: Path):
7475
"""
7576
Write the `participants.tsv` file based from a set of participant rows.
7677
"""

python/lib/imaging_lib/bids/tsv_scans.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import csv
22
from dataclasses import dataclass
33
from datetime import datetime
4+
from pathlib import Path
45
from typing import Any
56

67
from dateutil.parser import ParserError, parse
@@ -19,7 +20,7 @@ class BidsTsvScan:
1920
age_at_scan : str | None
2021

2122

22-
def read_bids_scans_tsv_file(scans_tsv_path: str) -> dict[str, BidsTsvScan]:
23+
def read_bids_scans_tsv_file(scans_tsv_path: Path) -> dict[str, BidsTsvScan]:
2324
"""
2425
Read a `scans.tsv` file of a BIDS dataset and get the scan rows indexed by file name. Raise an
2526
exception if the `scans.tsv` file is incorrect.
@@ -38,7 +39,7 @@ def read_bids_scans_tsv_file(scans_tsv_path: str) -> dict[str, BidsTsvScan]:
3839
return tsv_scans
3940

4041

41-
def read_bids_scans_tsv_row(tsv_scan_row: dict[str, str], scans_tsv_path: str) -> BidsTsvScan:
42+
def read_bids_scans_tsv_row(tsv_scan_row: dict[str, str], scans_tsv_path: Path) -> BidsTsvScan:
4243
"""
4344
Read a `scans.tsv` row, or raise an exception if that row is incorrect.
4445
"""
@@ -57,7 +58,7 @@ def read_bids_scans_tsv_row(tsv_scan_row: dict[str, str], scans_tsv_path: str) -
5758
)
5859

5960

60-
def write_bids_scans_tsv_file(tsv_scans: dict[str, BidsTsvScan], scans_tsv_path: str):
61+
def write_bids_scans_tsv_file(tsv_scans: dict[str, BidsTsvScan], scans_tsv_path: Path):
6162
"""
6263
Write the `scans.tsv` file from a set of scan rows.
6364
"""
@@ -115,7 +116,7 @@ def _read_age_at_scan(tsv_scan_row: dict[str, str]) -> str | None:
115116
return None
116117

117118

118-
def add_scan_tsv_file_parameters(scan_tsv: BidsTsvScan, scans_tsv_path: str, file_parameters: dict[str, Any]):
119+
def add_scan_tsv_file_parameters(scan_tsv: BidsTsvScan, scans_tsv_path: Path, file_parameters: dict[str, Any]):
119120
"""
120121
Add a scans.tsv file and row parameters to a LORIS file parameters dictionary.
121122
"""

python/lib/imaging_lib/nifti.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import os
21
from collections.abc import Iterator
2+
from pathlib import Path
33
from typing import Any, cast
44

55
import nibabel as nib
66

77

8-
def add_nifti_file_parameters(nifti_path: str, nifti_file_hash: str, file_parameters: dict[str, Any]):
8+
def add_nifti_file_parameters(nifti_path: Path, nifti_file_hash: str, file_parameters: dict[str, Any]):
99
"""
1010
Read a NIfTI image and add some of its properties to the file parameters.
1111
"""
@@ -34,11 +34,11 @@ def add_nifti_file_parameters(nifti_path: str, nifti_file_hash: str, file_parame
3434
file_parameters['file_blake2b_hash'] = nifti_file_hash
3535

3636

37-
def find_dir_nifti_names(dir_path: str) -> Iterator[str]:
37+
def find_dir_nifti_files(dir_path: Path) -> Iterator[Path]:
3838
"""
39-
Iterate over the names of the NIfTI files found in a directory.
39+
Iterate over the Path objects of the NIfTI files found in a directory.
4040
"""
4141

42-
for file_name in os.listdir(dir_path):
43-
if file_name.endswith(('.nii', '.nii.gz')):
44-
yield file_name
42+
for item_path in dir_path.iterdir():
43+
if item_path.name.endswith(('.nii', '.nii.gz')):
44+
yield item_path

python/lib/import_bids_dataset/env.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from dataclasses import dataclass
2+
from pathlib import Path
23

34

45
@dataclass
@@ -7,15 +8,15 @@ class BidsImportEnv:
78
Pipeline-specific variables of the BIDS dataset import pipeline.
89
"""
910

10-
data_dir_path : str
11-
loris_bids_path : str | None
11+
data_dir_path : Path
12+
loris_bids_path : Path | None
1213
total_files_count : int
1314
imported_files_count : int
1415
ignored_files_count : int
1516
failed_files_count : int
1617
unknown_scan_types : list[str]
1718

18-
def __init__(self, data_dir_path: str, loris_bids_path: str | None, total_files_count: int):
19+
def __init__(self, data_dir_path: Path, loris_bids_path: Path | None, total_files_count: int):
1920
self.data_dir_path = data_dir_path
2021
self.loris_bids_path = loris_bids_path
2122
self.total_files_count = total_files_count

python/lib/import_bids_dataset/events.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import os
3+
from pathlib import Path
34
from typing import Any
45

56
import lib.utilities
@@ -17,7 +18,7 @@ def get_events_metadata(
1718
args: Args,
1819
bids: BIDSDataset,
1920
legacy_db: Database,
20-
loris_bids_path: str | None,
21+
loris_bids_path: Path | None,
2122
project_id: int,
2223
) -> dict[Any, Any]:
2324
"""

0 commit comments

Comments
 (0)