Reputation: 48936
For the class below, I'm getting this exception:
AttributeError: LineIntensityProfileLogic instance has no attribute 'probeVolume'
How can I solve this issue? Thanks
class LineIntensityProfileLogic(ScriptedLoadableModuleLogic):
"""This class should implement all the actual
computation done by your module. The interface
should be such that other python code can import
this class and make use of the functionality without
requiring an instance of the Widget.
Uses ScriptedLoadableModuleLogic base class, available at:
https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
"""
def hasImageData(self,volumeNode):
"""This is a dummy logic method that
returns true if the passed in volume
node has valid image data
"""
if not volumeNode:
print('no volume node')
return False
if volumeNode.GetImageData() == None:
print('no image data')
return False
return True
def takeScreenshot(self,name,description,type=-1):
# show the message even if not taking a screen shot
self.delayDisplay(description)
if self.enableScreenshots == 0:
return
lm = slicer.app.layoutManager()
# switch on the type to get the requested window
widget = 0
if type == slicer.qMRMLScreenShotDialog.FullLayout:
# full layout
widget = lm.viewport()
elif type == slicer.qMRMLScreenShotDialog.ThreeD:
# just the 3D window
widget = lm.threeDWidget(0).threeDView()
elif type == slicer.qMRMLScreenShotDialog.Red:
# red slice window
widget = lm.sliceWidget("Red")
elif type == slicer.qMRMLScreenShotDialog.Yellow:
# yellow slice window
widget = lm.sliceWidget("Yellow")
elif type == slicer.qMRMLScreenShotDialog.Green:
# green slice window
widget = lm.sliceWidget("Green")
else:
# default to using the full window
widget = slicer.util.mainWindow()
# reset the type so that the node is set correctly
type = slicer.qMRMLScreenShotDialog.FullLayout
# grab and convert to vtk image data
qpixMap = qt.QPixmap().grabWidget(widget)
qimage = qpixMap.toImage()
imageData = vtk.vtkImageData()
slicer.qMRMLUtils().qImageToVtkImageData(qimage,imageData)
annotationLogic = slicer.modules.annotations.logic()
annotationLogic.CreateSnapShot(name, description, type, self.screenshotScaleFactor, imageData)
def run(self,volumeNode1,volumeNode2,rulerNode,enableScreenshots=0,screenshotScaleFactor=1):
"""
Run the actual algorithm
"""
print('LineIntensityProfileLogic run() called')
"""
1. get the list(s) of intensity samples along the ruler
2. set up quantitative layout
3. use the chart view to plot the intensity sampless
"""
"""
1. get the list of samples
"""
if not rulerNode or (not volumeNode1 and not volumeNode2):
print('Inputs are not initialized')
return
volumeSamples1 = None
volumeSamples2 = None
if volumeNode1:
volumeSamples1 = self.probeVolume(volumeNode1, rulerNode)
if volumeNode2:
volumeSamples2 = self.probeVolume(volumeNode2, rulerNode)
print('volumeSamples1 = '+str(volumeSamples1))
print('volumeSamples2 = '+str(volumeSamples2))
imageSamples = [volumeSamples1, volumeSamples2]
legendNames = [volumeNode1.GetName()+' - '+rulerNode.GetName(), volumeNode2.GetName+' - '+rulerNode.GetName()]
self.showChart(imageSamples, legendNames)
self.delayDisplay('Running the aglorithm')
self.enableScreenshots = enableScreenshots
self.screenshotScaleFactor = screenshotScaleFactor
self.takeScreenshot('LineIntensityProfile-Start','Start',-1)
return True
def probeVolume(self,volumeNode,rulerNode):
# get ruler endpoints coordinates in RAS
p0ras = rulerNode.GetPolyData().GetPoint(0)+(1,)
p1ras = rulerNode.GetPolyData().GetPoint(1)+(1,)
# Convert RAS to IJK coordinates of the vtkImageData
ras2ijk = vtk.vtkMatrix4x4()
volumeNode.GetRASToIJKMatrix(ras2ijk)
p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]]
p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]]
# Create VTK line that will be used for sampling
line = vtk.vtkLineSource()
line.SetResolution(100)
line.SetPoint1(p0ijk[0],p0ijk[1],p0ijk[2])
line.SetPoint2(p1ijk[0],p1ijk[1],p1ijk[2])
# Create VTK probe filter and sample the image
probe = vtk.vtkProbeFilter()
probe.SetInputConnection(line.GetOutputPort())
probe.SetSourceData(volumeNode.GetImageData())
probe.Update()
# return VTK array
return probe.GetOutput().GetPointData().GetArray('ImageScalars')
def showChart(self, samples, names):
print("Logic showing chart")
# Switch to a layout containing a chart viewer
lm = slicer.app.layoutManager()
lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpQuantitativeView)
# Initialize double array MRML node for each sample list since this is ,
# what chart view MRML node needs
doubleArrays = []
for sample in samples:
arrayNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLDoubleArrayNode())
array = arrayNode.GetArray()
nDataPoints = sample.GetNumberOfTuples()
array.SetNumberOfTuples(nDataPoints)
array.SetNumberOfComponents(3)
for i in range(nDataPoints):
array.SetComponent(i, 0, i)
array.SetComponent(i, 1, sample.GetTuple(i))
array.SetComponent(i, 2, 0)
doubleArrays.append(arrayNode)
# Get the chart view MRML node
cvNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLChartViewNode')
cvNodes.SetReferenceCount(cvNodes.GetReferenceCount()-1)
cvNodes.InitTraversal()
cvNode = cvNodes.GetNextItemAsObject()
# Create a new chart node
chartNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLChartNode())
for pairs in zip(names, doubleArrays):
chartNode.AddArray(pairs[0], pairs[1], GetID())
cvNode.SetChartNodeID(chartNode.GetID())
return
Upvotes: 0
Views: 801
Reputation: 90979
You seem to be using 2 spaces for indentation.
But for the function - probeVolume
, it is indented 4 spaces , which caused it to be inside function run
, are you sure that indentation is correct?
Not just probeVolume
, function - showChart
is also indented 4 spaces,
Upvotes: 1