Skip to content

Commit 61375c2

Browse files
authored
[Bug Fixes] Metadata Import Error and Better Handling of Missing Dicom Images (#349)
Fixed bugs and added better handling for missing dicoms. * update how metadata import works * raise error if missing images detected by dcm2niix * bump version
1 parent 505fe26 commit 61375c2

File tree

10 files changed

+66
-38
lines changed

10 files changed

+66
-38
lines changed

pypet2bids/poetry.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pypet2bids/pypet2bids/dcm2niix4pet.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def __init__(
176176
silent=False,
177177
tempdir_location=None,
178178
ezbids=False,
179+
ignore_dcm2niix_errors=False,
179180
):
180181
"""
181182
This class is a simple wrapper for dcm2niix and contains methods to do the following in order:
@@ -223,7 +224,7 @@ def __init__(
223224
"dcm2niix not found, this module depends on it for conversions, exiting."
224225
)
225226
sys.exit(1)
226-
227+
self.ignore_dcm2niix_errors = ignore_dcm2niix_errors
227228
# check for the version of dcm2niix
228229
minimum_version = "v1.0.20220720"
229230
version_string = subprocess.run([self.dcm2niix_path, "-v"], capture_output=True)
@@ -486,15 +487,23 @@ def run_dcm2niix(self):
486487
}
487488
self.telemetry_data.update(count_output_files(self.tempdir_location))
488489

489-
if convert.returncode != 0:
490+
if (
491+
convert.returncode != 0
492+
or "error" in convert.stderr.decode("utf-8").lower()
493+
) and not self.ignore_dcm2niix_errors:
490494
print(
491495
"Check output .nii files, dcm2iix returned these errors during conversion:"
492496
)
497+
# raise error if missing images is found
498+
if "missing images" in convert.stderr.decode("utf8").lower():
499+
error_message = convert.stderr.decode("utf8").replace("Error:", "")
500+
error_message = f"{error_message}for dicoms in {image_folder}"
501+
raise FileNotFoundError(error_message)
493502
if (
494503
bytes("Skipping existing file name", "utf-8") not in convert.stdout
495504
or convert.stderr
496505
):
497-
print(convert.stderr)
506+
print(convert.stderr.decode("utf-8"))
498507
elif (
499508
convert.returncode != 0
500509
and bytes("Error: Check sorted order", "utf-8") in convert.stdout
@@ -1174,6 +1183,13 @@ def cli():
11741183
help="Add fields to json output that are useful for ezBIDS or other conversion software. This will de-anonymize"
11751184
" pet2bids output and add AcquisitionDate an AcquisitionTime into the output json.",
11761185
)
1186+
parser.add_argument(
1187+
"--ignore-dcm2niix-errors",
1188+
action="store_true",
1189+
default=False,
1190+
help="Accept any NifTi produced by dcm2niix even if it contains errors. This flag should only be used for "
1191+
"batch processing and only if you're performing robust QC after the fact.",
1192+
)
11771193
return parser
11781194

11791195

@@ -1341,6 +1357,7 @@ def main():
13411357
tempdir_location=cli_args.tempdir,
13421358
silent=cli_args.silent,
13431359
ezbids=cli_args.ezbids,
1360+
ignore_dcm2niix_errors=cli_args.ignore_dcm2niix_errors,
13441361
)
13451362

13461363
if cli_args.trc:

pypet2bids/pypet2bids/helper_functions.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,14 @@
4242
import importlib
4343

4444
try:
45-
import metadata
45+
from importlib import metadata
4646
except ImportError:
47-
from pypet2bids import metadata
48-
49-
parent_dir = pathlib.Path(__file__).parent.resolve()
50-
project_dir = parent_dir.parent.parent
51-
if "PET2BIDS" not in project_dir.parts:
52-
project_dir = parent_dir
47+
import importlib_metadata as metadata
5348

49+
try:
50+
import pet_metadata as metadata
51+
except ImportError:
52+
import pypet2bids.pet_metadata as metadata
5453

5554
# load bids schema
5655
schema = metadata.schema
@@ -287,14 +286,13 @@ def get_version():
287286
"""
288287
# this scripts directory path
289288
scripts_dir = pathlib.Path(os.path.dirname(__file__))
290-
291-
# first try using importlib.metadata.version to determine version
292-
293-
version = importlib.metadata.version("pypet2bids")
289+
try:
290+
version = metadata.version("pypet2bids")
291+
except Exception:
292+
version = None
294293

295294
if not version:
296295
tomlfile = {}
297-
298296
try:
299297
# if this is bundled as a package look next to this file for the pyproject.toml
300298
toml_path = os.path.join(scripts_dir, "pyproject.toml")

pypet2bids/pypet2bids/is_pet.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@
1515
import helper_functions
1616
import ecat
1717
import dcm2niix4pet
18-
import metadata
18+
import pet_metadata
1919
except ModuleNotFoundError:
2020
import pypet2bids.helper_functions as helper_functions
2121
import pypet2bids.ecat as ecat
2222
import pypet2bids.dcm2niix4pet as dcm2niix4pet
23-
import pypet2bids.metadata
23+
import pypet2bids.pet_metadata as pet_metadata
2424

2525

2626
def spread_sheet_check_for_pet(sourcefile: Union[str, Path], **kwargs):
2727
# load data from spreadsheet
2828
data = helper_functions.open_meta_data(sourcefile)
2929

3030
try:
31-
pet_field_requirements = metadata.PET_metadata
31+
pet_field_requirements = pet_metadata.PET_metadata
3232
except:
3333
pet_field_requirements = {}
3434

pypet2bids/pypet2bids/metadata_spreadsheet_example_reader.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
try:
77
import helper_functions
8-
import metadata
8+
import pet_metadata
99
except ModuleNotFoundError:
1010
import pypet2bids.helper_functions as helper_functions
11-
import pypet2bids.metadata as metadata
11+
import pypet2bids.pet_metadata as pet_metadata
1212

1313

1414
parent_dir = pathlib.Path(__file__).parent.resolve()

pypet2bids/pypet2bids/multiple_spreadsheets.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
try:
1111
import pypet2bids.helper_functions as helper_functions
12-
import pypet2bids.metadata as metadata
12+
import pypet2bids.pet_metadata as pet_metadata
1313
except ModuleNotFoundError:
1414
import helper_functions
15-
import metadata
15+
import pet_metadata
1616

1717

1818
def read_multi_subject_spreadsheets(
@@ -43,7 +43,7 @@ def read_multi_subject_spreadsheets(
4343
4444
"""
4545

46-
required_fields = metadata.PET_metadata
46+
required_fields = pet_metadata.PET_metadata
4747

4848
if (
4949
general_metadata_spreadsheet.is_file()

pypet2bids/pypet2bids/metadata.py renamed to pypet2bids/pypet2bids/pet_metadata.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import sys
2+
from types import SimpleNamespace
3+
14
blood_metadata = {
25
"mandatory": [
36
"PlasmaAvail",
@@ -10708,3 +10711,13 @@
1070810711
"whole_blood_radioactivity",
1070910712
],
1071010713
}
10714+
10715+
sys.modules[__name__] = SimpleNamespace(
10716+
blood_metadata=blood_metadata,
10717+
dicom2bids=dicom2bids,
10718+
PET_reconstruction_filters=PET_reconstruction_filters,
10719+
definitions=definitions,
10720+
PET_reconstruction_methods=PET_reconstruction_methods,
10721+
schema=schema,
10722+
PET_metadata=PET_metadata,
10723+
)

pypet2bids/pypet2bids/single_spreadsheet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
try:
99
import helper_functions
10-
import metadata
10+
import pet_metadata as metadata
1111
except ModuleNotFoundError:
1212
import pypet2bids.helper_functions as helper_functions
13-
import pypet2bids.metadata as metadata
13+
import pypet2bids.pet_metadata as metadata
1414

1515
# from pypet2bids.helper_functions import single_spreadsheet_reader, \
1616
# collect_bids_part, open_meta_data, load_pet_bids_requirements_json, ParseKwargs

pypet2bids/pypet2bids/update_json_pet_file.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
try:
1515
import helper_functions
1616
import is_pet
17-
import metadata
17+
import pet_metadata as metadata
1818
except ModuleNotFoundError:
1919
import pypet2bids.helper_functions as helper_functions
2020
import pypet2bids.is_pet as is_pet
21-
import pypet2bids.metadata as metadata
21+
import pypet2bids.pet_metadata as metadata
2222

2323
# import logging
2424
logger = helper_functions.logger("pypet2bids")
@@ -51,7 +51,7 @@ def check_json(
5151
:type spreadsheet_metadata:
5252
:param path_to_json: path to a json file e.g. a BIDS sidecar file created after running dcm2niix
5353
:param items_to_check: a dictionary with items to check for within that json. If None is supplied defaults to the
54-
PET_metadata imported from metadata.PET_metadata
54+
PET_metadata imported from pet_metadata.PET_metadata
5555
:param silent: Raises warnings or errors to stdout if this flag is set to True
5656
:return: dictionary of items existence and value state, if key is True/False there exists/(does not exist) a
5757
corresponding entry in the json the same can be said of value
@@ -181,7 +181,7 @@ def update_json_with_dicom_value(
181181
# purely to clean up the generated read the docs page from sphinx, otherwise the entire json appears in the
182182
# read the docs page.
183183
if dicom2bids_json is None:
184-
dicom2bids_json = metadata_dictionaries["dicom2bids.json"]
184+
dicom2bids_json = metadata_dictionaries["dicom2bids"]
185185

186186
# Units gets written as Unit in older versions of dcm2niix here we check for missing Units and present Unit entity
187187
units = missing_values.get("Units", None)

pypet2bids/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "pypet2bids"
3-
version = "1.4.2"
3+
version = "1.4.3"
44
description = "A python library for converting PET imaging and blood data to BIDS."
55
authors = ["anthony galassi <[email protected]>"]
66
license = "MIT"

0 commit comments

Comments
 (0)