Skip to content

Commit

Permalink
[FIX] Fix FMAP logic in function create_file from adni_utils.py (#…
Browse files Browse the repository at this point in the history
…1178)

* Restore loops in create_file

* Simplify code using list comprehension

* Adapt tests in create_files to fmap modality + add specific subject to conversion_errors list
  • Loading branch information
AliceJoubert authored May 15, 2024
1 parent c30d69e commit 0871d35
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def compute_fmap_path(
("016_S_6802", "bl"),
("016_S_6816", "bl"),
("126_S_4891", "m84"),
("177_S_6448", "m24"),
# Multiple images
("029_S_2395", "m72"),
]
Expand Down
226 changes: 121 additions & 105 deletions clinica/iotools/converters/adni_to_bids/adni_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,132 +1476,148 @@ def create_file(

generate_json = modality_specific[modality]["json"]
zip_image = "n" if modality_specific[modality]["to_center"] else "y"
file_without_extension = output_path / output_filename
output_image = file_without_extension.with_suffix(".nii.gz")

if modality == "fmap":
fmap_path = Path(image_path).parent # All images in the visit will be converted
fmap_image_ids = os.listdir(fmap_path)
for id in fmap_image_ids:
fmap_image_path = fmap_path / id
run_dcm2niix(
input_dir=fmap_image_path,
output_dir=output_path,
output_fmt=output_filename,
compress=True if zip_image == "y" else False,
bids_sidecar=True if generate_json == "y" else False,
if image.Is_Dicom:
if modality == "fmap":
success = all(
[
run_dcm2niix(
input_dir=fmap_image_path,
output_dir=output_path,
output_fmt=output_filename,
compress=True if zip_image == "y" else False,
bids_sidecar=True if generate_json == "y" else False,
)
for fmap_image_path in Path(image_path).parent.iterdir()
if not fmap_image_path.name.startswith(".")
]
)
else:
file_without_extension = output_path / output_filename
output_image = file_without_extension.with_suffix(".nii.gz")

if image.Is_Dicom:
else:
success = run_dcm2niix(
input_dir=image_path,
output_dir=output_path,
output_fmt=output_filename,
compress=True if zip_image == "y" else False,
bids_sidecar=True if generate_json == "y" else False,
)
if not success:
cprint(
f"Error converting image {image_path} for subject {subject} and session {session}",
lvl="warning",
)
# If "_t" - the trigger delay time - exists in dcm2niix output filename, we remove it
for trigger_time in output_path.glob(f"{output_filename}_t[0-9]*"):
res = re.search(r"_t\d+\.", str(trigger_time))
no_trigger_time = str(trigger_time).replace(
trigger_time[res.start() : res.end()], "."
)
os.rename(trigger_time, no_trigger_time)

# Removing images with unsupported suffixes if generated by dcm2niix
for suffix in ("ADC", "real", "imaginary"):
file_with_bad_suffix = output_path / f"{output_filename}_{suffix}"
if any(
[
file_with_bad_suffix.with_suffix(s).exists()
for s in (".nii", ".nii.gz")
]
):
cprint(
f"Image with bad suffix {suffix} was generated by dcm2niix "
f"for subject {subject} and session {session} : "
f"{file_with_bad_suffix.with_suffix('.nii.gz')}. This image will NOT "
"be converted as the suffix is not supported by Clinica.",
lvl="warning",
)
for file_to_delete in output_path.glob(
f"{output_filename}_{suffix}*"
):
cprint(f"Deleting file {file_to_delete}.", lvl="info")
os.remove(file_to_delete)

# Conditions to check if output NIFTI files exists,
# and, if DWI, if .bvec and .bval files are also present
nifti_exists = (
file_without_extension.with_suffix(".nii").is_file()
or output_image.is_file()
if not success:
cprint(
f"Error converting image {image_path} for subject {subject} and session {session}",
lvl="warning",
)
dwi_bvec_and_bval_exist = not (modality == "dwi") or (
file_without_extension.with_suffix(".bvec").is_file()
and file_without_extension.with_suffix(".bval").is_file()

# If "_t" - the trigger delay time - exists in dcm2niix output filename, we remove it
for trigger_time in output_path.glob(f"{output_filename}_t[0-9]*"):
res = re.search(r"_t\d+\.", str(trigger_time))
no_trigger_time = str(trigger_time).replace(
trigger_time[res.start() : res.end()], "."
)
os.rename(trigger_time, no_trigger_time)

# Check if conversion worked (output files exist)
if not nifti_exists or not dwi_bvec_and_bval_exist:
# Removing images with unsupported suffixes if generated by dcm2niix
for suffix in ("ADC", "real", "imaginary"):
file_with_bad_suffix = output_path / f"{output_filename}_{suffix}"
if any(
[
file_with_bad_suffix.with_suffix(s).exists()
for s in (".nii", ".nii.gz")
]
):
cprint(
msg=f"Conversion with dcm2niix failed for subject {subject} and session {session}",
f"Image with bad suffix {suffix} was generated by dcm2niix "
f"for subject {subject} and session {session} : "
f"{file_with_bad_suffix.with_suffix('.nii.gz')}. This image will NOT "
"be converted as the suffix is not supported by Clinica.",
lvl="warning",
)
return np.nan
for file_to_delete in output_path.glob(f"{output_filename}_{suffix}*"):
cprint(f"Deleting file {file_to_delete}.", lvl="info")
os.remove(file_to_delete)

# Conditions to check if output NIFTI files exists,
# and, if DWI, if .bvec and .bval files are also present
nifti_exists = (
file_without_extension.with_suffix(".nii").is_file()
or output_image.is_file()
)
if modality == "fmap":
nifti_exists = nifti_exists or any(
[
file_without_extension.with_name(
f"{file_without_extension.name}_{suffix}.nii.gz"
).is_file()
for suffix in {"ph", "e2", "e1", "e2_ph", "e1_ph"}
]
)
dwi_bvec_and_bval_exist = not (modality == "dwi") or (
file_without_extension.with_suffix(".bvec").is_file()
and file_without_extension.with_suffix(".bval").is_file()
)

# Case when JSON file was expected, but not generated by dcm2niix
elif (
generate_json == "y"
and not file_without_extension.with_suffix(".json").exists()
):
# Check if conversion worked (output files exist)
if not nifti_exists or not dwi_bvec_and_bval_exist:
cprint(
msg=f"Conversion with dcm2niix failed for subject {subject} and session {session}",
lvl="warning",
)
return np.nan

# Case when JSON file was expected, but not generated by dcm2niix
json_exists = file_without_extension.with_suffix(".json").exists()

if modality == "fmap":
json_exists = json_exists or any(
[
file_without_extension.with_name(
f"{file_without_extension.name}_{suffix}.json"
).is_file()
for suffix in {"ph", "e2", "e1", "e2_ph", "e1_ph"}
]
)

if generate_json == "y" and not json_exists:
cprint(
msg=f"JSON file not generated by dcm2niix for subject {subject} and session {session}",
lvl="warning",
)

if modality_specific[modality]["to_center"]:
output_image, error_msg = center_nifti_origin(
file_without_extension.with_suffix(".nii"), output_image
)
if error_msg:
cprint(msg=error_msg, lvl="error")
raise ValueError(error_msg)
file_without_extension.with_suffix(".nii").unlink()

else:
if modality_specific[modality]["to_center"]:
try:
output_image, error_msg = center_nifti_origin(image_path, output_image)
except Exception:
cprint(
msg=f"JSON file not generated by dcm2niix for subject {subject} and session {session}",
lvl="warning",
msg=(f"No output image specified."),
lvl="error",
)

if modality_specific[modality]["to_center"]:
output_image, error_msg = center_nifti_origin(
file_without_extension.with_suffix(".nii"), output_image
output_image = ""
error_msg = False
if error_msg:
cprint(
msg=(
f"For subject {subject} in session {session}, "
f"an error occurred whilst recentering Nifti image: {image_path}"
f"The error is: {error_msg}"
),
lvl="error",
)
if error_msg:
cprint(msg=error_msg, lvl="error")
raise ValueError(error_msg)
file_without_extension.with_suffix(".nii").unlink()

else:
if modality_specific[modality]["to_center"]:
try:
output_image, error_msg = center_nifti_origin(
image_path, output_image
)
except Exception:
cprint(
msg=(f"No output image specified."),
lvl="error",
)
output_image = ""
error_msg = False
if error_msg:
cprint(
msg=(
f"For subject {subject} in session {session}, "
f"an error occurred whilst recentering Nifti image: {image_path}"
f"The error is: {error_msg}"
),
lvl="error",
)
else:
shutil.copy(image_path, output_image)
shutil.copy(image_path, output_image)

# Check if there is still the folder tmp_dcm_folder and remove it
remove_tmp_dmc_folder(bids_dir, image_id)
return output_image
# Check if there is still the folder tmp_dcm_folder and remove it
remove_tmp_dmc_folder(bids_dir, image_id)
return output_image


def load_clinical_csv(clinical_dir: str, filename: str) -> pd.DataFrame:
Expand Down

0 comments on commit 0871d35

Please sign in to comment.