Source code for portpy.photon.utils.view_in_slicer_jupyter

import numpy as np


[docs]def view_in_slicer_jupyter(my_plan, dose_1d: np.ndarray = None, sol: dict = None, ct_name: str = 'ct', dose_name: str = 'dose', struct_set_name: str = 'rt_struct', show_ct: bool = True, show_dose: bool = True, show_structs: bool = True): """ This method helps to visualize CT, Dose and Rt struct in 3d slicer :param my_plan: object of class plan :param dose_1d: dose in 1d :param sol: solution dictionary :param ct_name: Default to 'ct'. name of the ct node in 3D slicer :param dose_name: Default to 'dose'. name of the dose node in 3D slicer :param struct_set_name: name of the rtstruct :param show_structs: default to True. If false, will not create structure node :param show_dose: default to True. If false, will not create dose node :param show_ct:default to True. If false, will not create ct node :return: visualize in slicer jupyter """ try: import slicer except ImportError: print('Please use slicer kernel before using this method') if show_ct: slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", ct_name) ct_node = slicer.util.getNode(ct_name) ct_node.SetOrigin(list(np.array(my_plan.ct['origin_xyz_mm']) * np.array( [-1, -1, 1]))) # convert to RAS origin. -ve in x and y direction ct_node.SetSpacing(my_plan.ct['resolution_xyz_mm']) ct_node.SetIJKToRASDirections(np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]])) # set itk to RAS direction slicer.util.updateVolumeFromArray(ct_node, my_plan.ct['ct_hu_3d'][0]) slicer.util.setSliceViewerLayers(background=ct_node) # Another way to push simple itk image # import sitkUtils # ct = sitk.GetImageFromArray(my_plan.ct['ct_hu_3d'][0]) # ct.SetOrigin(my_plan.ct['origin_xyz_mm']) # ct.SetSpacing(my_plan.ct['resolution_xyz_mm']) # sitkUtils.PushVolumeToSlicer(ct, targetNode='ct') # plot dose if show_dose: if dose_1d is not None: dose_arr = my_plan.inf_matrix.dose_1d_to_3d(dose_1d=dose_1d) else: dose_1d = sol['inf_matrix'].A * sol['optimal_intensity'] * my_plan.get_num_of_fractions() dose_arr = sol['inf_matrix'].dose_1d_to_3d(dose_1d=dose_1d) slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", dose_name) dose_node = slicer.util.getNode(dose_name) dose_node.SetOrigin(list(np.array(my_plan.ct['origin_xyz_mm']) * np.array([-1, -1, 1]))) dose_node.SetSpacing(my_plan.ct['resolution_xyz_mm']) dose_node.SetIJKToRASDirections(np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]])) slicer.util.updateVolumeFromArray(dose_node, dose_arr) slicer.util.setSliceViewerLayers(foreground=dose_node) slicer.util.setSliceViewerLayers(foregroundOpacity=0.4) # dose_node.GetVolumeDisplayNode. # plot structures if show_structs: structure_node = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode", struct_set_name) for i, struct_name in enumerate(my_plan.structures.structures_dict['name']): print('Importing structure : ' + struct_name) slicer.util.addVolumeFromArray(my_plan.structures.structures_dict['structure_mask_3d'][i] * (i + 1), name=struct_name, nodeClassName="vtkMRMLLabelMapVolumeNode") lmap = slicer.util.getNode(struct_name) lmap.SetOrigin(list(np.array(my_plan.ct['origin_xyz_mm']) * np.array([-1, -1, 1]))) lmap.SetSpacing(my_plan.ct['resolution_xyz_mm']) lmap.SetIJKToRASDirections(np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]])) slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode(lmap, structure_node) slicer.mrmlScene.RemoveNode(lmap) segId = structure_node.GetSegmentation().GetNthSegment(i) segId.SetName(struct_name)