1212
1313import matplotlib .pyplot as plt
1414import numpy as np
15+ import pydicom
1516from scipy import ndimage
16- import pydicom
1717
1818# from totalsegmentator.libs import (
1919# download_pretrained_weights,
@@ -34,9 +34,9 @@ def __init__(self):
3434
3535 def __call__ (self , inference_pipeline ):
3636 # check if kernels are allowed if agatston is used
37- if inference_pipeline .args .threshold == ' agatston' :
37+ if inference_pipeline .args .threshold == " agatston" :
3838 self .reconKernelChecker (inference_pipeline .dcm )
39-
39+
4040 # inference_pipeline.dicom_series_path = self.input_path
4141 self .output_dir = inference_pipeline .output_dir
4242 self .output_dir_segmentations = os .path .join (self .output_dir , "segmentations/" )
@@ -115,27 +115,63 @@ def reconKernelChecker(self, dcm):
115115 ge_kernels = ["standard" , "md stnd" ]
116116 philips_kernels = ["a" , "b" , "c" , "sa" , "sb" ]
117117 canon_kernels = ["fc08" , "fc18" ]
118- siemens_kernels = ["b20s" , "b20f" , "b30f" , "b31s" , "b31f" , "br34f" , "b35f" , "bf37f" , "br38f" , "b41f" ,
119- "qr40" , "qr40d" , "br36f" , "br40" , "b40f" , "br40d" , "i30f" , "i31f" , "i26f" , "i31s" ,
120- "i40f" , "b30s" , "br36d" , "bf39f" , "b41s" , "br40f" ]
118+ siemens_kernels = [
119+ "b20s" ,
120+ "b20f" ,
121+ "b30f" ,
122+ "b31s" ,
123+ "b31f" ,
124+ "br34f" ,
125+ "b35f" ,
126+ "bf37f" ,
127+ "br38f" ,
128+ "b41f" ,
129+ "qr40" ,
130+ "qr40d" ,
131+ "br36f" ,
132+ "br40" ,
133+ "b40f" ,
134+ "br40d" ,
135+ "i30f" ,
136+ "i31f" ,
137+ "i26f" ,
138+ "i31s" ,
139+ "i40f" ,
140+ "b30s" ,
141+ "br36d" ,
142+ "bf39f" ,
143+ "b41s" ,
144+ "br40f" ,
145+ ]
121146 toshiba_kernels = ["fc01" , "fc02" , "fc07" , "fc08" , "fc13" , "fc18" ]
122147
123- all_kernels = ge_kernels + philips_kernels + canon_kernels + siemens_kernels + toshiba_kernels
124-
125- conv_kernel_raw = dcm ['ConvolutionKernel' ].value
126-
148+ all_kernels = (
149+ ge_kernels
150+ + philips_kernels
151+ + canon_kernels
152+ + siemens_kernels
153+ + toshiba_kernels
154+ )
155+
156+ conv_kernel_raw = dcm ["ConvolutionKernel" ].value
157+
127158 if isinstance (conv_kernel_raw , pydicom .multival .MultiValue ):
128159 conv_kernel = conv_kernel_raw [0 ].lower ()
129- recon_kernel_extra = str (conv_kernel_raw )
160+ str (conv_kernel_raw )
130161 else :
131162 conv_kernel = conv_kernel_raw .lower ()
132- recon_kernel_extra = 'n/a'
133-
163+
134164 if conv_kernel in all_kernels :
135165 return True
136- else :
137- raise ValueError ('Reconstruction kernel not allowed, found: ' + conv_kernel + '\n '
138- + 'Allowed kernels are: ' + str (all_kernels ))
166+ else :
167+ raise ValueError (
168+ "Reconstruction kernel not allowed, found: "
169+ + conv_kernel
170+ + "\n "
171+ + "Allowed kernels are: "
172+ + str (all_kernels )
173+ )
174+
139175
140176class AorticCalciumSegmentation (InferenceClass ):
141177 """Segmentaiton of aortic calcium"""
@@ -168,10 +204,10 @@ def __init__(self):
168204 47 : "vertebrae_C4" ,
169205 48 : "vertebrae_C3" ,
170206 49 : "vertebrae_C2" ,
171- 50 : "vertebrae_C1" }
172-
173- self .vertebrae_name = {v : k for k , v in self .vertebrae_num .items ()}
207+ 50 : "vertebrae_C1" ,
208+ }
174209
210+ self .vertebrae_name = {v : k for k , v in self .vertebrae_num .items ()}
175211
176212 def __call__ (self , inference_pipeline ):
177213
@@ -194,15 +230,21 @@ def __call__(self, inference_pipeline):
194230 os .makedirs (os .path .join (self .output_dir , "metrics/" ))
195231
196232 inference_pipeline .ct = inference_pipeline .medical_volume .get_fdata ()
197- inference_pipeline .aorta_mask = (inference_pipeline .segmentation .get_fdata ().round ().astype (np .int8 ) == 52 )
198- inference_pipeline .spine_mask = inference_pipeline .spine_segmentation .get_fdata ().round ().astype (np .uint8 )
199-
233+ inference_pipeline .aorta_mask = (
234+ inference_pipeline .segmentation .get_fdata ().round ().astype (np .int8 ) == 52
235+ )
236+ inference_pipeline .spine_mask = (
237+ inference_pipeline .spine_segmentation .get_fdata ().round ().astype (np .uint8 )
238+ )
239+
200240 # convert to the index of TotalSegmentator
201- if inference_pipeline .spine_model_name == ' stanford_spine_v0.0.1' :
241+ if inference_pipeline .spine_model_name == " stanford_spine_v0.0.1" :
202242 tmp_mask = inference_pipeline .spine_mask > 0
203- inference_pipeline .spine_mask [tmp_mask ] = inference_pipeline .spine_mask [tmp_mask ] + 11
243+ inference_pipeline .spine_mask [tmp_mask ] = (
244+ inference_pipeline .spine_mask [tmp_mask ] + 11
245+ )
204246 del tmp_mask
205-
247+
206248 spine_mask_bin = inference_pipeline .spine_mask > 0
207249
208250 # Determine the target number of pixels
@@ -220,7 +262,7 @@ def __call__(self, inference_pipeline):
220262 inference_pipeline .aorta_mask ,
221263 exclude_mask = spine_mask_bin ,
222264 remove_size = 3 ,
223- return_dilated_mask = True ,
265+ return_dilated_mask = True ,
224266 return_eroded_aorta = True ,
225267 threshold = inference_pipeline .args .threshold ,
226268 dilation_iteration = target_aorta_dil ,
@@ -240,15 +282,15 @@ def __call__(self, inference_pipeline):
240282 "calcium_segmentations.nii.gz" ,
241283 ),
242284 )
243-
285+
244286 inference_pipeline .saveArrToNifti (
245287 calcification_results ["dilated_mask" ],
246288 os .path .join (
247289 inference_pipeline .output_dir_segmentation_masks ,
248290 "dilated_aorta_mask.nii.gz" ,
249291 ),
250292 )
251-
293+
252294 inference_pipeline .saveArrToNifti (
253295 calcification_results ["aorta_eroded" ],
254296 os .path .join (
@@ -263,7 +305,7 @@ def __call__(self, inference_pipeline):
263305 inference_pipeline .output_dir_segmentation_masks , "spine_mask.nii.gz"
264306 ),
265307 )
266-
308+
267309 inference_pipeline .saveArrToNifti (
268310 inference_pipeline .aorta_mask ,
269311 os .path .join (
@@ -647,7 +689,7 @@ def getSmallestArraySlice(self, input_mask, margin=0):
647689 )
648690
649691 return (slice (x_start , x_end ), slice (y_start , y_end ), slice (z_start , z_end ))
650-
692+
651693
652694class AorticCalciumMetrics (InferenceClass ):
653695 """Calculate metrics for the aortic calcifications"""
@@ -659,7 +701,7 @@ def __call__(self, inference_pipeline):
659701 calc_mask = inference_pipeline .calc_mask
660702 spine_mask = inference_pipeline .spine_mask
661703 aorta_mask = inference_pipeline .aorta_mask
662-
704+
663705 t12_level = np .where ((spine_mask == 32 ).sum (axis = (0 , 1 )))[0 ]
664706 l1_level = np .where ((spine_mask == 31 ).sum (axis = (0 , 1 )))[0 ]
665707
@@ -686,7 +728,7 @@ def __call__(self, inference_pipeline):
686728 ),
687729 )
688730 inference_pipeline .t12_plane = planes
689-
731+
690732 inference_pipeline .pix_dims = inference_pipeline .medical_volume .header [
691733 "pixdim"
692734 ][1 :4 ]
@@ -741,10 +783,11 @@ def __call__(self, inference_pipeline):
741783 metrics ["volume_total" ] = calc_vol
742784
743785 metrics ["num_calc" ] = num_lesions
744-
786+
745787 # percent of the aorta calcificed
746- metrics ['perc_calcified' ] = (calc_mask_region .sum () / aorta_mask_region .sum ()) * 100
747-
788+ metrics ["perc_calcified" ] = (
789+ calc_mask_region .sum () / aorta_mask_region .sum ()
790+ ) * 100
748791
749792 if inference_pipeline .args .threshold == "agatston" :
750793 if num_lesions == 0 :
0 commit comments