@@ -41,18 +41,25 @@ class DICOMSeriesToVolumeOperator(Operator):
4141
4242 # Use constants instead of enums in monai to avoid dependency at this level.
4343 MONAI_UTIL_ENUMS_SPACEKEYS_RAS = "RAS"
44+ MONAI_UTIL_ENUMS_SPACEKEYS_LPS = "LPS"
4445 MONAI_TRANSFORMS_SPATIAL_METADATA_NAME = "space"
4546 METADATA_SPACE_RAS = {MONAI_TRANSFORMS_SPATIAL_METADATA_NAME : MONAI_UTIL_ENUMS_SPACEKEYS_RAS }
47+ METADATA_SPACE_LPS = {MONAI_TRANSFORMS_SPATIAL_METADATA_NAME : MONAI_UTIL_ENUMS_SPACEKEYS_LPS }
48+ ATTRIBUTE_NIFTI_AFFINE = "nifti_affine_transform"
49+ ATTRIBUTE_DICOM_AFFINE = "dicom_affine_transform"
4650
47- def __init__ (self , fragment : Fragment , * args , ** kwargs ):
51+ def __init__ (self , fragment : Fragment , * args , affine_lps_to_ras : bool = True , ** kwargs ):
4852 """Create an instance for a containing application object.
4953
5054 Args:
5155 fragment (Fragment): An instance of the Application class which is derived from Fragment.
56+ affine_lps_to_ras (bool): If true, the affine transform in the image metadata is RAS oriented,
57+ otherwise it is LPS oriented. Default is True.
5258 """
5359
5460 self .input_name_series = "study_selected_series_list"
5561 self .output_name_image = "image"
62+ self .affine_lps_to_ras = affine_lps_to_ras
5663 # Need to call the base class constructor last
5764 super ().__init__ (fragment , * args , ** kwargs )
5865
@@ -89,18 +96,16 @@ def convert_to_image(self, study_selected_series_list: List[StudySelectedSeries]
8996 metadata .update (self ._get_instance_properties (study_selected_series .study ))
9097 selection_metadata = {"selection_name" : selection_name }
9198 metadata .update (selection_metadata )
92- # Add the metadata to specify LPS.
93- # Previously, this was set in ImageReader class, but moving it here allows other loaders
94- # to determine this value on its own, e.g. NIfTI loader but it does not set this
95- # resulting in the MONAI Orientation transform to default the labels to RAS.
96- # It is assumed that the ImageOrientationPatient will be set accordingly if the
97- # PatientPosition is other than HFS.
98- # NOTE: This value is properly parsed by MONAI Orientation transform from v1.5.1 onwards.
99- # Some early MONAI model inference configs incorrectly specify orientation to RAS
100- # due part to previous MONAI versions did not correctly parse this metadata from
101- # the input MetaTensor and defaulting to RAS. Now with LPS properly set, the inference
102- # configs then need to be updated to specify LPS, to achieve the same result.
103- metadata .update (self .METADATA_SPACE_RAS )
99+ # The affine transform and the coordinate space are set based on the flag affine_lps_to_ras.
100+ # If the flag is true, the NIFTI affine (RAS) is used, otherwise the DICOM affine (LPS) is used.
101+ if self .affine_lps_to_ras :
102+ if hasattr (dicom_series , self .ATTRIBUTE_NIFTI_AFFINE ):
103+ metadata ["affine" ] = getattr (dicom_series , self .ATTRIBUTE_NIFTI_AFFINE )
104+ metadata .update (self .METADATA_SPACE_RAS )
105+ else :
106+ if hasattr (dicom_series , self .ATTRIBUTE_DICOM_AFFINE ):
107+ metadata ["affine" ] = getattr (dicom_series , self .ATTRIBUTE_DICOM_AFFINE )
108+ metadata .update (self .METADATA_SPACE_LPS )
104109
105110 voxel_data = self .generate_voxel_data (dicom_series )
106111 image = self .create_volumetric_image (voxel_data , metadata )
@@ -366,7 +371,7 @@ def compute_affine_transform(self, s_1, s_n, n, series):
366371 zn = 0.0
367372
368373 ip1 = None
369- ip2 = None
374+ ipn = None
370375 try :
371376 ip1_de = s_1 [0x0020 , 0x0032 ]
372377 ipn_de = s_n [0x0020 , 0x0032 ]
@@ -404,7 +409,7 @@ def compute_affine_transform(self, s_1, s_n, n, series):
404409 m1 [3 , 2 ] = 0
405410 m1 [3 , 3 ] = 1
406411
407- series . dicom_affine_transform = m1
412+ setattr ( series , self . ATTRIBUTE_DICOM_AFFINE , m1 )
408413
409414 m2 [0 , 0 ] = - rx * vr
410415 m2 [0 , 1 ] = - cx * vc
@@ -426,7 +431,7 @@ def compute_affine_transform(self, s_1, s_n, n, series):
426431 m2 [3 , 2 ] = 0
427432 m2 [3 , 3 ] = 1
428433
429- series . nifti_affine_transform = m2
434+ setattr ( series , self . ATTRIBUTE_NIFTI_AFFINE , m2 )
430435
431436 def create_metadata (self , series ) -> Dict :
432437 """Collects all relevant metadata from the DICOM Series and creates a dictionary.
0 commit comments