Skip to content

Commit 025b75e

Browse files
authored
Migrate the DICOM study importer to pathlib.Path (path PR 1) (#1349)
1 parent 9990c24 commit 025b75e

File tree

11 files changed

+77
-65
lines changed

11 files changed

+77
-65
lines changed

python/lib/config.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from pathlib import Path
23
from typing import Literal
34

45
from lib.db.queries.config import try_get_config_with_setting_name
@@ -26,15 +27,15 @@ def get_patient_id_dicom_header_config(env: Env) -> Literal['PatientID', 'Patien
2627
return patient_id_dicom_header
2728

2829

29-
def get_data_dir_path_config(env: Env) -> str:
30+
def get_data_dir_path_config(env: Env) -> Path:
3031
"""
3132
Get the LORIS base data directory path from the in-database configuration, or exit the program
3233
with an error if that configuration value does not exist or is incorrect.
3334
"""
3435

35-
data_dir_path = os.path.normpath(_get_config_value(env, 'dataDirBasepath'))
36+
data_dir_path = Path(_get_config_value(env, 'dataDirBasepath'))
3637

37-
if not os.path.isdir(data_dir_path):
38+
if not data_dir_path.is_dir():
3839
log_error_exit(
3940
env,
4041
(
@@ -52,20 +53,20 @@ def get_data_dir_path_config(env: Env) -> str:
5253
return data_dir_path
5354

5455

55-
def get_dicom_archive_dir_path_config(env: Env) -> str:
56+
def get_dicom_archive_dir_path_config(env: Env) -> Path:
5657
"""
5758
Get the LORIS DICOM archive directory path from the in-database configuration, or exit the
5859
program with an error if that configuration value does not exist or is incorrect.
5960
"""
6061

61-
dicom_archive_dir_path = os.path.normpath(_get_config_value(env, 'tarchiveLibraryDir'))
62+
dicom_archive_dir_path = Path(_get_config_value(env, 'tarchiveLibraryDir'))
6263

63-
if not os.path.isdir(dicom_archive_dir_path):
64+
if not dicom_archive_dir_path.is_dir():
6465
log_error_exit(
6566
env,
6667
(
6768
f"The LORIS DICOM archive directory path configuration value '{dicom_archive_dir_path}' does not refer"
68-
" to an existing diretory."
69+
" to an existing directory."
6970
),
7071
)
7172

python/lib/dcm2bids_imaging_pipeline_lib/nifti_insertion_pipeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ def _create_pic_image(self):
689689
"""
690690
file_info = {
691691
'cand_id': self.session.candidate.cand_id,
692-
'data_dir_path': self.data_dir,
692+
'data_dir_path': str(self.data_dir),
693693
'file_rel_path': self.assembly_nifti_rel_path,
694694
'is_4D_dataset': self.json_file_dict['time'] is not None,
695695
'file_id': self.file_id

python/lib/import_dicom_study/dicom_database.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from functools import cmp_to_key
3+
from pathlib import Path
34

45
from sqlalchemy.orm import Session as Database
56

@@ -17,14 +18,14 @@ def insert_dicom_archive(
1718
db: Database,
1819
dicom_summary: DicomStudySummary,
1920
dicom_import_log: DicomStudyImportLog,
20-
archive_location: str,
21+
archive_path: Path,
2122
):
2223
"""
2324
Insert a DICOM archive in the database.
2425
"""
2526

2627
dicom_archive = DbDicomArchive()
27-
populate_dicom_archive(dicom_archive, dicom_summary, dicom_import_log, archive_location)
28+
populate_dicom_archive(dicom_archive, dicom_summary, dicom_import_log, archive_path)
2829
dicom_archive.date_first_archived = datetime.now()
2930
db.add(dicom_archive)
3031
db.commit()
@@ -37,7 +38,7 @@ def update_dicom_archive(
3738
dicom_archive: DbDicomArchive,
3839
dicom_summary: DicomStudySummary,
3940
dicom_import_log: DicomStudyImportLog,
40-
archive_location: str,
41+
archive_path: Path,
4142
):
4243
"""
4344
Update a DICOM archive in the database.
@@ -47,7 +48,7 @@ def update_dicom_archive(
4748
delete_dicom_archive_file_series(db, dicom_archive)
4849

4950
# Update the database record with the new DICOM information.
50-
populate_dicom_archive(dicom_archive, dicom_summary, dicom_import_log, archive_location)
51+
populate_dicom_archive(dicom_archive, dicom_summary, dicom_import_log, archive_path)
5152
db.commit()
5253

5354
# Insert the new DICOM files and series.
@@ -58,7 +59,7 @@ def populate_dicom_archive(
5859
dicom_archive: DbDicomArchive,
5960
dicom_summary: DicomStudySummary,
6061
dicom_import_log: DicomStudyImportLog,
61-
archive_location: str,
62+
archive_path: Path,
6263
):
6364
"""
6465
Populate a DICOM archive database object with information from its DICOM summary and DICOM
@@ -83,8 +84,8 @@ def populate_dicom_archive(
8384
dicom_archive.creating_user = dicom_import_log.creator_name
8485
dicom_archive.sum_type_version = dicom_import_log.summary_version
8586
dicom_archive.tar_type_version = dicom_import_log.archive_version
86-
dicom_archive.source_location = dicom_import_log.source_path
87-
dicom_archive.archive_location = archive_location
87+
dicom_archive.source_location = str(dicom_import_log.source_path)
88+
dicom_archive.archive_location = str(archive_path)
8889
dicom_archive.scanner_manufacturer = dicom_summary.info.scanner.manufacturer or ''
8990
dicom_archive.scanner_model = dicom_summary.info.scanner.model or ''
9091
dicom_archive.scanner_serial_number = dicom_summary.info.scanner.serial_number or ''

python/lib/import_dicom_study/import_log.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import socket
44
from dataclasses import dataclass
55
from datetime import datetime
6+
from pathlib import Path
67

78
from lib.import_dicom_study.text_dict import DictWriter
89

@@ -13,8 +14,8 @@ class DicomStudyImportLog:
1314
Information about the past import of a DICOM study.
1415
"""
1516

16-
source_path: str
17-
target_path: str
17+
source_path: Path
18+
target_path: Path
1819
creator_host: str
1920
creator_os: str
2021
creator_name: str
@@ -32,8 +33,8 @@ def write_dicom_study_import_log_to_string(import_log: DicomStudyImportLog):
3233
"""
3334

3435
return DictWriter([
35-
("Taken from dir", import_log.source_path),
36-
("Archive target location", import_log.target_path),
36+
("Taken from dir", str(import_log.source_path)),
37+
("Archive target location", str(import_log.target_path)),
3738
("Name of creating host", import_log.creator_host),
3839
("Name of host OS", import_log.creator_os),
3940
("Created by user", import_log.creator_name),
@@ -46,7 +47,7 @@ def write_dicom_study_import_log_to_string(import_log: DicomStudyImportLog):
4647
]).write()
4748

4849

49-
def write_dicom_study_import_log_to_file(import_log: DicomStudyImportLog, file_path: str):
50+
def write_dicom_study_import_log_to_file(import_log: DicomStudyImportLog, file_path: Path):
5051
"""
5152
Serialize a DICOM study import log into a text file.
5253
"""
@@ -56,7 +57,7 @@ def write_dicom_study_import_log_to_file(import_log: DicomStudyImportLog, file_p
5657
file.write(string)
5758

5859

59-
def make_dicom_study_import_log(source: str, target: str, tarball_md5_sum: str, zipball_md5_sum: str):
60+
def make_dicom_study_import_log(source: Path, target: Path, tarball_md5_sum: str, zipball_md5_sum: str):
6061
"""
6162
Create a DICOM study import log from the provided arguments about a DICOM study, as well as the
6263
current execution environment.

python/lib/import_dicom_study/summary_get.py

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

34
import pydicom
45
import pydicom.errors
@@ -17,7 +18,7 @@
1718
from lib.util.fs import iter_all_dir_files
1819

1920

20-
def get_dicom_study_summary(dicom_study_dir_path: str, verbose: bool):
21+
def get_dicom_study_summary(dicom_study_dir_path: Path, verbose: bool):
2122
"""
2223
Get information about a DICOM study by reading the files in the DICOM study directory.
2324
"""
@@ -31,7 +32,7 @@ def get_dicom_study_summary(dicom_study_dir_path: str, verbose: bool):
3132
if verbose:
3233
print(f"Processing file '{file_rel_path}' ({i}/{len(file_rel_paths)})")
3334

34-
file_path = os.path.join(dicom_study_dir_path, file_rel_path)
35+
file_path = dicom_study_dir_path / file_rel_path
3536

3637
try:
3738
dicom = pydicom.dcmread(file_path) # type: ignore
@@ -112,13 +113,13 @@ def get_dicom_file_info(dicom: pydicom.Dataset) -> DicomStudyDicomFile:
112113
)
113114

114115

115-
def get_other_file_info(file_path: str) -> DicomStudyOtherFile:
116+
def get_other_file_info(file_path: Path) -> DicomStudyOtherFile:
116117
"""
117118
Get information about a non-DICOM file within a DICOM study.
118119
"""
119120

120121
return DicomStudyOtherFile(
121-
os.path.basename(file_path),
122+
file_path.name,
122123
compute_file_md5_hash(file_path),
123124
)
124125

python/lib/import_dicom_study/summary_write.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from functools import cmp_to_key
3+
from pathlib import Path
34

45
from lib.import_dicom_study.summary_type import (
56
DicomStudyDicomFile,
@@ -14,14 +15,14 @@
1415
from lib.util.iter import count, flatten
1516

1617

17-
def write_dicom_study_summary_to_file(dicom_summary: DicomStudySummary, filename: str):
18+
def write_dicom_study_summary_to_file(dicom_summary: DicomStudySummary, file_path: Path):
1819
"""
1920
Serialize a DICOM study summary object into a text file.
2021
"""
2122

22-
string = write_dicom_study_summary(dicom_summary)
23-
with open(filename, 'w') as file:
24-
file.write(string)
23+
summary = write_dicom_study_summary(dicom_summary)
24+
with open(file_path, 'w') as file:
25+
file.write(summary)
2526

2627

2728
def write_dicom_study_summary(dicom_summary: DicomStudySummary) -> str:

python/lib/import_dicom_study/text.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
different types of values.
44
"""
55

6-
import os
76
from datetime import date, datetime
7+
from pathlib import Path
88

99
from lib.util.crypto import compute_file_md5_hash
1010

@@ -66,9 +66,9 @@ def read_float_none(string: str | None):
6666
return float(string)
6767

6868

69-
def compute_md5_hash_with_name(path: str):
69+
def compute_md5_hash_with_name(path: Path):
7070
"""
7171
Get the MD5 sum hash of a file with the filename appended.
7272
"""
7373

74-
return f'{compute_file_md5_hash(path)} {os.path.basename(path)}'
74+
return f'{compute_file_md5_hash(path)} {path.name}'

python/lib/util/crypto.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import hashlib
2+
from pathlib import Path
23

34

4-
def compute_file_blake2b_hash(file_path: str) -> str:
5+
def compute_file_blake2b_hash(file_path: Path | str) -> str:
56
"""
67
Compute the BLAKE2b hash of a file.
78
"""
@@ -15,7 +16,7 @@ def compute_file_blake2b_hash(file_path: str) -> str:
1516
return hash.hexdigest()
1617

1718

18-
def compute_file_md5_hash(file_path: str) -> str:
19+
def compute_file_md5_hash(file_path: Path | str) -> str:
1920
"""
2021
Compute the MD5 hash of a file.
2122
"""

python/lib/util/fs.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import tempfile
66
from collections.abc import Iterator
77
from datetime import datetime
8+
from pathlib import Path
89

910
import lib.exitcode
1011
from lib.env import Env
@@ -26,16 +27,17 @@ def extract_archive(env: Env, tar_path: str, prefix: str, dir_path: str) -> str:
2627
return extract_path
2728

2829

29-
def iter_all_dir_files(dir_path: str) -> Iterator[str]:
30+
def iter_all_dir_files(dir_path: Path) -> Iterator[Path]:
3031
"""
3132
Iterate through all the files in a directory recursively, and yield the path of each file
3233
relative to that directory.
3334
"""
3435

35-
for sub_dir_path, _, file_names in os.walk(dir_path):
36-
for file_name in file_names:
37-
file_path = os.path.join(sub_dir_path, file_name)
38-
yield os.path.relpath(file_path, start=dir_path)
36+
for item_path in dir_path.iterdir():
37+
if item_path.is_dir():
38+
yield from iter_all_dir_files(item_path)
39+
elif item_path.is_file():
40+
yield item_path.relative_to(dir_path)
3941

4042

4143
def remove_directory(env: Env, path: str):

0 commit comments

Comments
 (0)