3636from CorpusCallosum .shape .thickness import cc_thickness , convert_to_ras
3737from CorpusCallosum .utils .types import CCMeasuresDict , ContourThickness , Points2dType , SliceSelection , SubdivisionMethod
3838from CorpusCallosum .utils .visualization import plot_contours
39- from FastSurferCNN .utils import AffineMatrix4x4 , Image3d , Mask2d , ScalarType , Shape2d , Shape3d , Vector2d
39+ from FastSurferCNN .utils import AffineMatrix4x4 , Image3d , Mask2d , ScalarType , Shape2d , Shape3d , Vector2d , nibabelImage , \
40+ nibabelHeader
4041from FastSurferCNN .utils .common import SubjectDirectory , update_docstring
4142from FastSurferCNN .utils .parallel import process_executor , thread_executor
4243
@@ -74,6 +75,7 @@ def create_sag_slice_vox2vox(slice_idx: int, fsaverage_middle: float) -> AffineM
7475@update_docstring (SubdivisionMethod = str (get_args (SubdivisionMethod ))[1 :- 1 ])
7576def recon_cc_surf_measures_multi (
7677 segmentation : np .ndarray [Shape3d , np .dtype [np .int_ ]],
78+ upright_affine_header : tuple [AffineMatrix4x4 , nibabelHeader ],
7779 slice_selection : SliceSelection ,
7880 fsavg_vox2ras : AffineMatrix4x4 ,
7981 midslices : Image3d ,
@@ -92,6 +94,8 @@ def recon_cc_surf_measures_multi(
9294 ----------
9395 segmentation : np.ndarray
9496 3D segmentation array.
97+ upright_affine_header : tuple[AffineMatrix4x4, nibabelHeader]
98+ A tuple of the vox2ras matrix and the header of the upright image.
9599 slice_selection : str
96100 Which slices to process ('middle', 'all', or slice number).
97101 fsavg_vox2ras : np.ndarray
@@ -164,6 +168,7 @@ def recon_cc_surf_measures_multi(
164168 cc_contours = []
165169
166170 run = thread_executor ().submit
171+ wants_output = subject_dir .has_attribute
167172 for i , (slice_idx , _results ) in enumerate (zip (slices_to_recon , per_slice_recon , strict = True )):
168173 progress = f" ({ i + 1 } of { num_slices } )" if num_slices > 1 else ""
169174 logger .info (f"Calculating CC measurements for slice { slice_idx + 1 } { progress } " )
@@ -182,7 +187,7 @@ def recon_cc_surf_measures_multi(
182187 slice_cc_measures .append (cc_measures )
183188 is_debug = logger .getEffectiveLevel () <= logging .DEBUG
184189 is_midslice = slice_idx == num_slices // 2
185- if subject_dir . has_attribute ("cc_qc_image" ) and (is_debug or is_midslice ):
190+ if wants_output ("cc_qc_image" ) and (is_debug or is_midslice ):
186191 qc_imgs : list [Path ] = [subject_dir .filename_by_attribute ("cc_qc_image" )]
187192 if is_debug :
188193 qc_slice_img = qc_imgs [0 ].with_suffix (f".slice_{ slice_idx } .png" )
@@ -207,7 +212,7 @@ def recon_cc_surf_measures_multi(
207212 )
208213
209214
210- if subject_dir . has_attribute ("save_template_dir" ):
215+ if wants_output ("save_template_dir" ):
211216 template_dir = subject_dir .filename_by_attribute ("save_template_dir" )
212217 # ensure directory exists
213218 template_dir .mkdir (parents = True , exist_ok = True )
@@ -221,36 +226,41 @@ def recon_cc_surf_measures_multi(
221226 io_futures .append (run (cc_contours [j ].save_thickness_values , template_dir / f"thickness_values_{ j } .txt" ))
222227
223228 mesh_outputs = ("html" , "mesh" , "thickness_overlay" , "surf" , "thickness_image" )
224- if len (cc_contours ) > 1 and any (subject_dir . has_attribute (f"cc_{ n } " ) for n in mesh_outputs ):
229+ if len (cc_contours ) > 1 and any (wants_output (f"cc_{ n } " ) for n in mesh_outputs ):
225230 _cc_contours = thread_executor ().map (_resample_thickness , cc_contours )
226231 cc_mesh = CCMesh .from_contours (list (_cc_contours ), smooth = 1 )
227- if subject_dir . has_attribute ("cc_html" ):
232+ if wants_output ("cc_html" ):
228233 logger .info (f"Saving CC 3D visualization to { subject_dir .filename_by_attribute ('cc_html' )} " )
229234 io_futures .append (run (
230235 cc_mesh .plot_mesh ,output_path = subject_dir .filename_by_attribute ("cc_html" )),
231236 )
232237
233- if subject_dir . has_attribute ("cc_mesh" ):
238+ if wants_output ("cc_mesh" ):
234239 vtk_file_path = subject_dir .filename_by_attribute ("cc_mesh" )
235240 logger .info (f"Saving vtk file to { vtk_file_path } " )
236241 io_futures .append (run (cc_mesh .write_vtk , vtk_file_path ))
237242
238- # the mesh is generated in upright coordinates, so we need to also transform to orig coordinates
239- cc_mesh = cc_mesh .to_fs_coordinates (lr_offset = FSAVERAGE_MIDDLE / vox_size [0 ])
240- if subject_dir .has_attribute ("cc_thickness_overlay" ):
243+ if wants_output ("cc_thickness_overlay" ):
241244 overlay_file_path = subject_dir .filename_by_attribute ("cc_thickness_overlay" )
242245 logger .info (f"Saving overlay file to { overlay_file_path } " )
243246 io_futures .append (run (cc_mesh .write_morph_data , overlay_file_path ))
244247
245- if subject_dir .has_attribute ("cc_surf" ):
248+ if any (wants_output (f"cc_{ n } " ) for n in ("thickness_image" , "cc_surf" )):
249+ import nibabel as nib
250+ upright_img = nib .MGHImage (np .zeros (() * 3 , dtype = np .uint8 ))
251+
252+ # the mesh is generated in upright coordinates, so we need to also transform to orig coordinates
253+ cc_mesh = cc_mesh .to_fs_coordinates (lr_offset = FSAVERAGE_MIDDLE / vox_size [0 ])
254+ if wants_output ("cc_surf" ):
246255 surf_file_path = subject_dir .filename_by_attribute ("cc_surf" )
247256 logger .info (f"Saving surf file to { surf_file_path } " )
248- io_futures .append (run (cc_mesh .write_fssurf , str (surf_file_path ), str (subject_dir .conf_name )))
257+ cc_mesh .write_fssurf (str (surf_file_path ), image = upright_img )
258+ # io_futures.append(run(cc_mesh.write_fssurf, str(surf_file_path), image=orig))
249259
250- if subject_dir . has_attribute ("cc_thickness_image" ):
260+ if wants_output ("cc_thickness_image" ):
251261 thickness_image_path = subject_dir .filename_by_attribute ("cc_thickness_image" )
252262 logger .info (f"Saving thickness image to { thickness_image_path } " )
253- cc_mesh .snap_cc_picture (thickness_image_path , subject_dir . conf_name )
263+ cc_mesh .snap_cc_picture (thickness_image_path , ref_image = upright_img )
254264
255265 if not slice_cc_measures :
256266 logger .error ("Error: No valid slices were found for postprocessing" )
0 commit comments