Skip to content

Commit a0de38c

Browse files
committed
Fix surface output
1 parent 39b61ef commit a0de38c

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

CorpusCallosum/fastsurfer_cc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ def _orig2midslab_vox2vox(additional_context: int = 0) -> AffineMatrix4x4:
805805
logger.info(f"Processing slices with selection mode: {slice_selection}")
806806
slice_results, slice_io_futures = recon_cc_surf_measures_multi(
807807
segmentation=cc_fn_seg_labels,
808+
upright_affine_header=(fsavg_vox2ras, orig.header),
808809
slice_selection=slice_selection,
809810
fsavg_vox2ras=fsavg_vox2ras,
810811
midslices=midslices,

CorpusCallosum/shape/mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ def snap_cc_picture(
520520
overlay_file : Path, str, optional
521521
Path to a FreeSurfer overlay file to use for the snapshot.
522522
If None, the mesh is saved to a temporary file.
523-
ref_image : Path, str, optional
523+
ref_image : Path, str, nibabelImage, optional
524524
Path to reference image to use for tkr creation. If None, ignores the file for saving.
525525
526526
Raises

CorpusCallosum/shape/postprocessing.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
from CorpusCallosum.shape.thickness import cc_thickness, convert_to_ras
3737
from CorpusCallosum.utils.types import CCMeasuresDict, ContourThickness, Points2dType, SliceSelection, SubdivisionMethod
3838
from 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
4041
from FastSurferCNN.utils.common import SubjectDirectory, update_docstring
4142
from 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])
7576
def 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

Comments
 (0)