Skip to content

Commit 661ee86

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent f88d03e commit 661ee86

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

monailabel/datastore/utils/convert_htj2k.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,9 +1049,13 @@ def convert_single_frame_dicom_series_to_multiframe(
10491049
# Save ImageOrientationPatient and ImagePositionPatient BEFORE creating output_ds
10501050
# The shallow copy + delattr will affect the original datasets objects
10511051
# Save these values now so we can use them in functional groups later
1052-
original_image_orientation = datasets[0].ImageOrientationPatient if hasattr(datasets[0], "ImageOrientationPatient") else None
1053-
original_image_positions = [ds.ImagePositionPatient if hasattr(ds, "ImagePositionPatient") else None for ds in datasets]
1054-
1052+
original_image_orientation = (
1053+
datasets[0].ImageOrientationPatient if hasattr(datasets[0], "ImageOrientationPatient") else None
1054+
)
1055+
original_image_positions = [
1056+
ds.ImagePositionPatient if hasattr(ds, "ImagePositionPatient") else None for ds in datasets
1057+
]
1058+
10551059
# Create SIMPLE multi-frame DICOM file (like the user's example)
10561060
# Use first dataset as template, keeping its metadata
10571061
logger.info(f" Creating simple multi-frame DICOM from {total_frame_count} frames...")
@@ -1108,19 +1112,28 @@ def convert_single_frame_dicom_series_to_multiframe(
11081112
# CRITICAL: Remove top-level ImagePositionPatient and ImageOrientationPatient
11091113
# Working files (that display correctly in OHIF MPR) have NEITHER at top level
11101114
# These should ONLY exist in functional groups for Enhanced CT
1111-
1115+
11121116
if hasattr(output_ds, "ImagePositionPatient"):
11131117
delattr(output_ds, "ImagePositionPatient")
11141118
logger.info(f" ✓ Removed top-level ImagePositionPatient (use per-frame only)")
1115-
1119+
11161120
if hasattr(output_ds, "ImageOrientationPatient"):
11171121
delattr(output_ds, "ImageOrientationPatient")
11181122
logger.info(f" ✓ Removed top-level ImageOrientationPatient (use SharedFunctionalGroupsSequence only)")
11191123
# Set correct SOPClassUID for multi-frame (Enhanced/Multiframe) conversion
11201124
sopclass_map = {
1121-
"1.2.840.10008.5.1.4.1.1.2": ("1.2.840.10008.5.1.4.1.1.2.1", "Enhanced CT Image Storage"), # CT -> Enhanced CT
1122-
"1.2.840.10008.5.1.4.1.1.4": ("1.2.840.10008.5.1.4.1.1.4.1", "Enhanced MR Image Storage"), # MR -> Enhanced MR
1123-
"1.2.840.10008.5.1.4.1.1.6.1": ("1.2.840.10008.5.1.4.1.1.3.1", "Ultrasound Multi-frame Image Storage"), # US -> Ultrasound Multi-frame
1125+
"1.2.840.10008.5.1.4.1.1.2": (
1126+
"1.2.840.10008.5.1.4.1.1.2.1",
1127+
"Enhanced CT Image Storage",
1128+
), # CT -> Enhanced CT
1129+
"1.2.840.10008.5.1.4.1.1.4": (
1130+
"1.2.840.10008.5.1.4.1.1.4.1",
1131+
"Enhanced MR Image Storage",
1132+
), # MR -> Enhanced MR
1133+
"1.2.840.10008.5.1.4.1.1.6.1": (
1134+
"1.2.840.10008.5.1.4.1.1.3.1",
1135+
"Ultrasound Multi-frame Image Storage",
1136+
), # US -> Ultrasound Multi-frame
11241137
}
11251138

11261139
original_sopclass = getattr(datasets[0], "SOPClassUID", None)
@@ -1186,7 +1199,9 @@ def convert_single_frame_dicom_series_to_multiframe(
11861199
else:
11871200
# If missing, use default (0,0,frame_idx * spacing)
11881201
# This shouldn't happen for valid CT series, but ensures MPR compatibility
1189-
default_spacing = float(output_ds.SpacingBetweenSlices) if hasattr(output_ds, 'SpacingBetweenSlices') else 1.0
1202+
default_spacing = (
1203+
float(output_ds.SpacingBetweenSlices) if hasattr(output_ds, "SpacingBetweenSlices") else 1.0
1204+
)
11901205
plane_pos_item.ImagePositionPatient = [0.0, 0.0, frame_idx * default_spacing]
11911206
logger.warning(f" Frame {frame_idx} missing ImagePositionPatient, using default")
11921207
frame_item.PlanePositionSequence = Sequence([plane_pos_item])

tests/unit/datastore/test_convert_htj2k.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,9 @@ def test_transcode_dicom_to_htj2k_multiframe_metadata(self):
786786
first_original = original_datasets[0]
787787

788788
# Check ImagePositionPatient is NOT there at top level DICOM file
789-
self.assertFalse(hasattr(ds_multiframe, "ImagePositionPatient"), "Should not have ImagePositionPatient at top level")
789+
self.assertFalse(
790+
hasattr(ds_multiframe, "ImagePositionPatient"), "Should not have ImagePositionPatient at top level"
791+
)
790792

791793
# Check PixelSpacing
792794
self.assertTrue(hasattr(ds_multiframe, "PixelSpacing"), "Should have PixelSpacing")
@@ -812,31 +814,31 @@ def test_transcode_dicom_to_htj2k_multiframe_metadata(self):
812814
# Check SOPClassUID conversion to Enhanced/Multi-frame
813815
self.assertTrue(hasattr(ds_multiframe, "SOPClassUID"), "Should have SOPClassUID")
814816
self.assertTrue(hasattr(first_original, "SOPClassUID"), "Original should have SOPClassUID")
815-
817+
816818
# Map of single-frame to enhanced/multi-frame SOPClassUIDs
817819
sopclass_map = {
818-
"1.2.840.10008.5.1.4.1.1.2": "1.2.840.10008.5.1.4.1.1.2.1", # CT -> Enhanced CT
819-
"1.2.840.10008.5.1.4.1.1.4": "1.2.840.10008.5.1.4.1.1.4.1", # MR -> Enhanced MR
820-
"1.2.840.10008.5.1.4.1.1.6.1": "1.2.840.10008.5.1.4.1.1.3.1", # US -> Ultrasound Multi-frame
820+
"1.2.840.10008.5.1.4.1.1.2": "1.2.840.10008.5.1.4.1.1.2.1", # CT -> Enhanced CT
821+
"1.2.840.10008.5.1.4.1.1.4": "1.2.840.10008.5.1.4.1.1.4.1", # MR -> Enhanced MR
822+
"1.2.840.10008.5.1.4.1.1.6.1": "1.2.840.10008.5.1.4.1.1.3.1", # US -> Ultrasound Multi-frame
821823
}
822-
824+
823825
original_sopclass = str(first_original.SOPClassUID)
824826
multiframe_sopclass = str(ds_multiframe.SOPClassUID)
825-
827+
826828
if original_sopclass in sopclass_map:
827829
expected_sopclass = sopclass_map[original_sopclass]
828830
self.assertEqual(
829831
multiframe_sopclass,
830832
expected_sopclass,
831-
f"SOPClassUID should be converted from {original_sopclass} to {expected_sopclass}"
833+
f"SOPClassUID should be converted from {original_sopclass} to {expected_sopclass}",
832834
)
833835
print(f"✓ SOPClassUID converted: {original_sopclass} -> {multiframe_sopclass}")
834836
else:
835837
# If not in map, should remain unchanged
836838
self.assertEqual(
837839
multiframe_sopclass,
838840
original_sopclass,
839-
"SOPClassUID should remain unchanged if not in conversion map"
841+
"SOPClassUID should remain unchanged if not in conversion map",
840842
)
841843
print(f"✓ SOPClassUID unchanged: {multiframe_sopclass}")
842844

0 commit comments

Comments
 (0)