Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/enh/complex_realimag' into prod
Browse files Browse the repository at this point in the history
  • Loading branch information
bpinsard committed Nov 30, 2024
2 parents 17fdfb4 + 19666a9 commit 430900a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
42 changes: 29 additions & 13 deletions heudiconv/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,20 @@ def prep_conversion(
)


IMAGETYPE_TO_PARTS = {
"M": "mag",
"MAGNITUDE": "mag",
"P": "phase",
"PHASE": "phase",
"REAL": "real",
"IMAGINARY": "imag",
}


def update_complex_name(metadata: dict[str, Any], filename: str) -> str:
"""
Insert `_part-<mag|phase>` entity into filename if data are from a
sequence with magnitude/phase part.
Insert `_part-<mag|phase|real|imag>` entity into filename if data are from a
sequence with magnitude/phase/real/imaginary part.
Parameters
----------
Expand Down Expand Up @@ -330,20 +340,27 @@ def update_complex_name(metadata: dict[str, Any], filename: str) -> str:
if any(ut in filename for ut in unsupported_types):
return filename

# Check to see if it is magnitude or phase part:
img_type = cast(List[str], metadata.get("ImageType", []))
if "M" in img_type:
mag_or_phase = "mag"
elif "P" in img_type:
mag_or_phase = "phase"

present_parts = set(
IMAGETYPE_TO_PARTS[tp] for tp in img_type if tp in IMAGETYPE_TO_PARTS
)
if not present_parts:
raise RuntimeError(
f"Data type could not be inferred from the ImageType={img_type}. Known types are: {sorted(IMAGETYPE_TO_PARTS)}"
)
elif len(present_parts) == 1:
part = present_parts.pop()
else:
raise RuntimeError("Data type could not be inferred from the metadata.")
raise RuntimeError(
f"Data type could not be inferred from the ImageType={img_type}. Multiple BIDS parts matched: {present_parts}"
)

# Determine scan suffix
filetype = "_" + filename.split("_")[-1]

# Insert part label
if not ("_part-%s" % mag_or_phase) in filename:
if not ("_part-%s" % part) in filename:
# If "_part-" is specified, prepend the 'mag_or_phase' value.
if "_part-" in filename:
raise BIDSError(
Expand All @@ -368,7 +385,7 @@ def update_complex_name(metadata: dict[str, Any], filename: str) -> str:
]
for label in entities_after_part:
if (label == filetype) or (label in filename):
filename = filename.replace(label, "_part-%s%s" % (mag_or_phase, label))
filename = filename.replace(label, "_part-%s%s" % (part, label))
break

return filename
Expand Down Expand Up @@ -984,9 +1001,8 @@ def save_converted_files(
is_uncombined = (
len(set(filter(bool, channel_names))) > 1
) # Check for uncombined data
is_complex = (
"M" in image_types and "P" in image_types
) # Determine if data are complex (magnitude + phase)
# Determine if data are complex (magnitude + phase or real + imag or all-4)
is_complex = len(set(IMAGETYPE_TO_PARTS.keys()).intersection(image_types))
echo_times_lst = sorted(echo_times) # also converts to list
channel_names_lst = sorted(channel_names) # also converts to list

Expand Down
9 changes: 9 additions & 0 deletions heudiconv/dicoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ def create_seqinfo(
else:
sequence_name = ""

# GE data
# see https://github.com/rordenlab/dcm2niix/tree/master/GE#complex-image-component
if dcminfo.get([0x43, 0x102F]):
GE_CPLX_CODING = ["MAGNITUDE", "PHASE", "REAL", "IMAGINARY"]
cplx_idx = int(dcminfo.get([0x43, 0x102F]).value)
part = GE_CPLX_CODING[cplx_idx]
if part not in image_type:
image_type = image_type + (part,)

# initialized in `group_dicoms_to_seqinfos`
global total_files
total_files += len(series_files)
Expand Down

0 comments on commit 430900a

Please sign in to comment.