def TestSection_1_RunPlastimatchProtonDoseEngine(self): logging.info('Test section 1: Run Plastimatch proton dose engine') engineLogic = slicer.qSlicerDoseEngineLogic() engineLogic.setMRMLScene(slicer.mrmlScene) # Get input ctVolumeNode = slicer.util.getNode('TinyPatient_CT') segmentationNode = slicer.util.getNode('TinyPatient_Structures') self.assertIsNotNone(ctVolumeNode) self.assertIsNotNone(segmentationNode) # Create node for output dose totalDoseVolumeNode = slicer.vtkMRMLScalarVolumeNode() totalDoseVolumeNode.SetName('TotalDose') slicer.mrmlScene.AddNode(totalDoseVolumeNode) # Setup plan planNode = slicer.vtkMRMLRTPlanNode() planNode.SetName('TestProtonPlan') slicer.mrmlScene.AddNode(planNode) planNode.SetAndObserveReferenceVolumeNode(ctVolumeNode); planNode.SetAndObserveSegmentationNode(segmentationNode); planNode.SetAndObserveOutputTotalDoseVolumeNode(totalDoseVolumeNode); planNode.SetTargetSegmentID("Tumor_Contour"); planNode.SetIsocenterToTargetCenter(); planNode.SetDoseEngineName(self.plastimatchProtonDoseEngineName) # Add first beam firstBeamNode = engineLogic.createBeamInPlan(planNode) firstBeamNode.SetX1Jaw(-50.0) firstBeamNode.SetX2Jaw(50.0) firstBeamNode.SetY1Jaw(-50.0) firstBeamNode.SetY2Jaw(75.0) #TODO: For some reason the instance() function cannot be called as a class function although it's static engineHandler = slicer.qSlicerDoseEnginePluginHandler() engineHandlerSingleton = engineHandler.instance() plastimatchProtonEngine = engineHandlerSingleton.doseEngineByName(self.plastimatchProtonDoseEngineName) plastimatchProtonEngine.setParameter(firstBeamNode, 'EnergyResolution', 4.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'RangeCompensatorSmearingRadius', 0.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'ProximalMargin', 0.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'DistalMargin', 0.0) # Calculate dose import time startTime = time.time() errorMessage = engineLogic.calculateDose(planNode) self.assertEqual(errorMessage, "") calculationTime = time.time() - startTime logging.info('Dose computation time: ' + str(calculationTime) + ' s') # Check computed output imageAccumulate = vtk.vtkImageAccumulate() imageAccumulate.SetInputConnection(totalDoseVolumeNode.GetImageDataConnection()) imageAccumulate.Update() doseMax = imageAccumulate.GetMax()[0] doseMean = imageAccumulate.GetMean()[0] doseStdDev = imageAccumulate.GetStandardDeviation()[0] doseVoxelCount = imageAccumulate.GetVoxelCount() logging.info("Dose volume properties:\n Max=" + str(doseMax) + ", Mean=" + str(doseMean) + ", StdDev=" + str(doseStdDev) + ", NumberOfVoxels=" + str(doseVoxelCount)) self.assertTrue(self.isEqualWithTolerance(doseMax, 1.09556)) self.assertTrue(self.isEqualWithTolerance(doseMean, 0.01670)) self.assertTrue(self.isEqualWithTolerance(doseStdDev, 0.12670)) self.assertTrue(self.isEqualWithTolerance(doseVoxelCount, 1000))
def TestSection_1_RunPlastimatchProtonDoseEngine(self): logging.info('Test section 1: Run Plastimatch proton dose engine') engineLogic = slicer.qSlicerDoseEngineLogic() engineLogic.setMRMLScene(slicer.mrmlScene) # Get input ctVolumeNode = slicer.util.getNode('TinyPatient_CT') segmentationNode = slicer.util.getNode('TinyPatient_Structures') self.assertIsNotNone(ctVolumeNode) self.assertIsNotNone(segmentationNode) # Create node for output dose totalDoseVolumeNode = slicer.vtkMRMLScalarVolumeNode() totalDoseVolumeNode.SetName('TotalDose') slicer.mrmlScene.AddNode(totalDoseVolumeNode) # Setup plan planNode = slicer.vtkMRMLRTPlanNode() planNode.SetName('TestProtonPlan') slicer.mrmlScene.AddNode(planNode) planNode.SetAndObserveReferenceVolumeNode(ctVolumeNode); planNode.SetAndObserveSegmentationNode(segmentationNode); planNode.SetAndObserveOutputTotalDoseVolumeNode(totalDoseVolumeNode); planNode.SetTargetSegmentID("Tumor_Contour"); planNode.SetIsocenterToTargetCenter(); planNode.SetDoseEngineName("Plastimatch proton") # Add first beam firstBeamNode = engineLogic.createBeamInPlan(planNode) firstBeamNode.SetX1Jaw(-50.0) firstBeamNode.SetX2Jaw(50.0) firstBeamNode.SetY1Jaw(-50.0) firstBeamNode.SetY2Jaw(75.0) #TODO: For some reason the instance() function cannot be called as a class function although it's static engineHandler = slicer.qSlicerDoseEnginePluginHandler() engineHandlerSingleton = engineHandler.instance() plastimatchProtonEngine = engineHandlerSingleton.doseEngineByName('Plastimatch proton') plastimatchProtonEngine.setParameter(firstBeamNode, 'EnergyResolution', 4.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'RangeCompensatorSmearingRadius', 0.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'ProximalMargin', 0.0) plastimatchProtonEngine.setParameter(firstBeamNode, 'DistalMargin', 0.0) # Calculate dose import time startTime = time.time() errorMessage = engineLogic.calculateDose(planNode) self.assertNotEqual(errorMessage, "") calculationTime = time.time() - startTime logging.info('Dose computation time: ' + str(calculationTime) + ' s') # Check computed output imageAccumulate = vtk.vtkImageAccumulate() imageAccumulate.SetInputConnection(totalDoseVolumeNode.GetImageDataConnection()) imageAccumulate.Update() doseMax = imageAccumulate.GetMax()[0] doseMean = imageAccumulate.GetMean()[0] doseStdDev = imageAccumulate.GetStandardDeviation()[0] doseVoxelCount = imageAccumulate.GetVoxelCount() logging.info("Dose volume properties:\n Max=" + str(doseMax) + ", Mean=" + str(doseMean) + ", StdDev=" + str(doseStdDev) + ", NumberOfVoxels=" + str(doseVoxelCount)) self.assertTrue(self.isEqualWithTolerance(doseMax, 1.05797)) self.assertTrue(self.isEqualWithTolerance(doseMean, 0.0251127)) self.assertTrue(self.isEqualWithTolerance(doseStdDev, 0.144932)) self.assertTrue(self.isEqualWithTolerance(doseVoxelCount, 1000))