Ejemplo n.º 1
0
    def __init__(self, fname, objectnum=-1, keyname='', newsuffix="_edited"):
        self.fname = fname
        #self.efile = file(fname+".error","w")
        #self.stderr = sys.stderr
        #f = file(fname)
        #self.data = cPickle.load(f)
        self.data = readGraphs(fname)
        #f.close()
        if (objectnum == -1 or keyname == ''):
            self.key = getOrderedGraphKeys(self.data['orderedGraphs'])
        else:
            self.key = (objectnum, keyname)
        self.sg = SkeletonGraph()
        self.sg.orderedGraphs = self.data['orderedGraphs']
        self.sg.roots = self.data['roots']
        if ("root" not in self.sg.orderedGraphs[self.key].graph):
            self.sg.orderedGraphs[self.key].graph["root"] = self.sg.roots[
                self.key]

        #self.picker = self.figure.scene.get()['picker']
        #self.figure.scene.picker.pointpicker.add_observer('EndPickEvent',self.picker_callback)
        self._setGraphData()
        # Decrease the tolerance, so that we can more easily select a precise
        # point.
        self.editnum = 1
        # create a new key and copy of graph
        newKey = (self.key[0], "%s%s" % (
            self.key[1],
            newsuffix,
        ))
        self.sg.orderedGraphs[newKey] = self.sg.orderedGraphs[self.key].copy()
        self.key = newKey
        self.deleteNode = None
Ejemplo n.º 2
0
    def __init__(self,fname, objectnum = -1, keyname = '', img='',lvalue=1):
        self.fname = fname
        self.lvalue = lvalue
        self.data = utils.readGraphs(fname)
        self.imgfile = img
        if( objectnum == -1 or keyname == ''):
            self.key = getOrderedGraphKeys(self.data['orderedGraphs'])
        else:
            self.key = (objectnum,keyname)
        self.sg = SkeletonGraph()
        self.sg.orderedGraphs = self.data['orderedGraphs']
        self.sg.roots = self.data['roots']
        if("root" not in self.sg.orderedGraphs[self.key].graph):
            self.sg.orderedGraphs[self.key].graph["root"] = self.sg.roots[self.key]

        self._setGraphData()    
        # create a new key and copy of graph
        newKey = (self.key[0],"%s_volume"%(self.key[1],))
        self.sg.orderedGraphs[newKey] = self.sg.orderedGraphs[self.key].copy()
        self.key = newKey
Ejemplo n.º 3
0
def main():
    parser = getParser()
    options = parser.parse_args()
    itkimg = sitk.ReadImage(options.skel_img)
    simg = sitk.GetArrayFromImage(itkimg)
    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                       spacing=itkimg.GetSpacing(),
                       origin=itkimg.GetOrigin(),
                       orientation=itkimg.GetDirection(),
                       label=options.skel_img)

    print(sg.spacing, sg.origin, sg.orientation)
    oimg = sitk.GetArrayFromImage(sitk.ReadImage(options.orig_img))

    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    root = sg.selectSeedFromDFE()
    #sg.viewGraph()
    #raw_input('continue')
    sg.setRoot(root, key="mp_graphs")
    sg.traceEndpoints(key='mp_graphs')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey, options.prune_length)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
    print("Define orthogonal planes")
    sg.defineOrthogonalPlanes(ogkey)
    # Now get surface points of original image to map to the centerlines
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(
        dfe == 1, 1, 0))[::-1]).transpose().astype(np.int32)
    print("mapVoxelsToGraph")
    sg.mapVoxelsToGraph(points_toMap, ogkey, verbose=True)
    print("assignMappedPointsToPlanes")
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(options.graph_file)
Ejemplo n.º 4
0
def main():
    simg, descr = readImage(sys.argv[1])

    pool = mp.Pool(mp.cpu_count())

    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                       spacing=descr['scale'],
                       origin=descr['origin'],
                       orientation=descr['orientation'],
                       label=sys.argv[1],
                       pool=pool)

    ##print descr
    #print sg.spacing, sg.origin, sg.orientation

    oimg, tmp = readImage(sys.argv[2])
    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=True)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    print("set root")
    root = rootRMS(sg.cg)
    #sg.viewGraph()
    sg.setRoot(root, key="og_rms")
    print("trace endpoints")
    sg.traceEndpoints(key='og_rms')
    ogkey = sg.getLargestOrderedGraphKey()
    print("prune tree")
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    print("fit edges")
    sg.fitEdges(key=ogkey)
    print("Define orthogonal planes")
    sg.defineOrthogonalPlanes(ogkey)
    print("Now get surface points of original image to map to the centerlines")
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(
        dfe == 1, 1, 0))[::-1]).transpose().astype(np.int32)
    print("mapVoxelsToGraph")
    sg.mapVoxelsToGraph(points_toMap, ogkey)
    print("assignMappedPointsToPlanes")
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(sys.argv[3])
Ejemplo n.º 5
0
def main():
    parser = getParser()
    options = parser.parse_args()
    itkimg = sitk.ReadImage(options.skel_img)
    simg = sitk.GetArrayFromImage(itkimg)
    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                    spacing=itkimg.GetSpacing(),
                    origin=itkimg.GetOrigin(),
                    orientation=itkimg.GetDirection(),
                    label = options.skel_img)

    print(sg.spacing, sg.origin, sg.orientation)
    oimg = sitk.GetArrayFromImage(sitk.ReadImage(options.orig_img))

    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    root = sg.selectSeedFromDFE()
#sg.viewGraph()
#raw_input('continue')
    sg.setRoot(root,key="mp_graphs")
    sg.traceEndpoints(key='mp_graphs')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey,options.prune_length)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
    print("Define orthogonal planes")
    sg.defineOrthogonalPlanes(ogkey)
# Now get surface points of original image to map to the centerlines
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(dfe==1,1,0))[::-1]).transpose().astype(np.int32)
    print("mapVoxelsToGraph")
    sg.mapVoxelsToGraph(points_toMap,ogkey, verbose=True)
    print("assignMappedPointsToPlanes")
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(options.graph_file)
Ejemplo n.º 6
0
def main():
    simg,descr = readImage( sys.argv[1] )

    pool = mp.Pool(mp.cpu_count())

    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                    spacing=descr['scale'],
                    origin=descr['origin'],
                    orientation=descr['orientation'],
                    label = sys.argv[1],
                    pool = pool)

##print descr
#print sg.spacing, sg.origin, sg.orientation

    oimg,tmp = readImage( sys.argv[2])
    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=True)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    print("set root")
    root = rootRMS(sg.cg)
#sg.viewGraph()
    sg.setRoot(root,key="og_rms")
    print("trace endpoints")
    sg.traceEndpoints(key='og_rms')
    ogkey = sg.getLargestOrderedGraphKey()
    print("prune tree")
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    print("fit edges")
    sg.fitEdges(key=ogkey)
    print("Define orthogonal planes")
    sg.defineOrthogonalPlanes(ogkey)
    print("Now get surface points of original image to map to the centerlines")
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(dfe==1,1,0))[::-1]).transpose().astype(np.int32)
    print("mapVoxelsToGraph")
    sg.mapVoxelsToGraph(points_toMap,ogkey)
    print("assignMappedPointsToPlanes")
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(sys.argv[3])
Ejemplo n.º 7
0
def main():
    simg, descr = readImage(sys.argv[1])

    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                       spacing=descr['scale'],
                       origin=descr['origin'],
                       orientation=descr['orientation'],
                       label=sys.argv[1])

    ##print descr
    #print sg.spacing, sg.origin, sg.orientation

    oimg, tmp = readImage(sys.argv[2])
    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    endp = [n for n in sg.cg.nodes() if sg.cg.degree(n) == 1]
    endpa = np.array(endp)
    medianx = np.median(endpa[:, 0])
    endp.sort(key=lambda n: abs(n[0] - medianx))
    root = endp[0]
    #sg.viewGraph()
    sg.setRoot(root, key="og_medianx")
    sg.traceEndpoints(key='og_medianx')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
    #print "Define orthogonal planes"
    sg.defineOrthogonalPlanes(ogkey)
    # Now get surface points of original image to map to the centerlines
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(
        dfe == 1, 1, 0))[::-1]).transpose().astype(np.int32)
    #print "mapVoxelsToGraph"
    sg.mapVoxelsToGraph(points_toMap, ogkey)
    #print "assignMappedPointsToPlanes"
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(sys.argv[3])
Ejemplo n.º 8
0
class VolumeGrabber(object):
    def __init__(self,fname, objectnum = -1, keyname = '', img='',lvalue=1):
        self.fname = fname
        self.lvalue = lvalue
        self.data = utils.readGraphs(fname)
        self.imgfile = img
        if( objectnum == -1 or keyname == ''):
            self.key = getOrderedGraphKeys(self.data['orderedGraphs'])
        else:
            self.key = (objectnum,keyname)
        self.sg = SkeletonGraph()
        self.sg.orderedGraphs = self.data['orderedGraphs']
        self.sg.roots = self.data['roots']
        if("root" not in self.sg.orderedGraphs[self.key].graph):
            self.sg.orderedGraphs[self.key].graph["root"] = self.sg.roots[self.key]

        self._setGraphData()    
        # create a new key and copy of graph
        newKey = (self.key[0],"%s_volume"%(self.key[1],))
        self.sg.orderedGraphs[newKey] = self.sg.orderedGraphs[self.key].copy()
        self.key = newKey
   
    def readImage(self):
        sitkimg = sitk.ReadImage(self.imgfile)
        self.simg = sitk.GetArrayFromImage(sitkimg)
        self.dfe = ndi.distance_transform_cdt(self.simg)
        cg = self.sg.orderedGraphs[self.key]
        self.sg.spacing=cg.graph["spacing"]
        self.sg.origin=cg.graph["origin"]
        self.points_toMap = np.array(np.nonzero(np.where(self.simg==self.lvalue,1,0))[::-1]).transpose().astype(np.int32)

    def mapVolumePoints(self,key="volumePoints"):
        #print "in grabVolumes",self.points_toMap
        self.sg.mapVoxelsToGraph(self.points_toMap,self.key,mp_key=key, verbose=True)

    def computeVolumeMeasures(self, key="volumePoints"):
        cg = self.sg.orderedGraphs[self.key]
        edges = cg.edges(data=True)
        for e in edges:
            try:
                mask = np.zeros(cg.graph["imgSize"],np.uint8)
                worldVolume = e[2][key]
# now we need to transform the worldVolume coordinates back to image coordinates
                ivi = ((worldVolume-cg.graph["origin"])/cg.graph["spacing"]).astype(np.int32)
                mask[ivi[:,2],ivi[:,1],ivi[:,0]] = 1
                surface = mask - ndi.binary_erosion(mask)
# now we've got img indicies we can grab the surface based on dfe values
                sinds =  np.nonzero(surface)
                dfeVals = self.dfe[sinds]
                edgeSurface = np.nonzero(dfeVals==1)
                surface_to_volume = float(sinds[0].size)/float(ivi[:,0].size)
                exterior_to_surface = float(edgeSurface[0].size)/float(sinds[0].size)
                e[2]["surface2volume"] = surface_to_volume
                e[2]["exterior2surface"] = exterior_to_surface
            except ValueError:
                e[2]['surface2volume'] = None
                e[2]['exterior2surface'] = None

    def saveModifiedData(self):
        print("saving modified data")
        self.data['orderedGraphs'] = self.sg.orderedGraphs
        f = file(self.fname,"wb")
        pickle.dump(self.data,f)
    def _setGraphData(self):
        self.og = self.sg.orderedGraphs[self.key]
        self.edges = self.og.edges(data=True)
        self.nodes = self.og.nodes(data=True)
Ejemplo n.º 9
0
def main():
    dcm = dicom.read_file(sys.argv[1])
    img = dcm.pixel_array
    sg = SkeletonGraph(img)
    arg2 = dicom.read_file(sys.argv[2])
    img2 = arg2.pixel_array
    sg.setOriginalImage(img2)
    #sg.setOriginalImage(fname=sys.argv[2])
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    root = sg.selectSeedFromDFE()
    #sg.viewGraph()
    #raw_input('continue')
    sg.setRoot(root, key="test")
    sg.traceEndpoints(key='test')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
    og = sg.orderedGraphs[ogkey]
    sg.viewGraph(og)
    sg.saveGraphs(sys.argv[3])
Ejemplo n.º 10
0
def main():
    simg,descr = readImage( sys.argv[1] )

    try:
        simg
    except:
        sys.exit("read of skeleton image failed")

    sg = SkeletonGraph(img=simg,
                    spacing=descr['scale'],
                    origin=descr['origin'],
                    orientation=descr['orientation'],
                    label = sys.argv[1])

##print descr
#print sg.spacing, sg.origin, sg.orientation

    oimg,tmp = readImage( sys.argv[2])
    try:
        oimg
    except:
        sys.exit("read of mask image failed")
    sg.setOriginalImage(oimg)
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    endp = [n for n in sg.cg.nodes() if sg.cg.degree(n)==1]
    endpa = np.array(endp)
    medianx = np.median(endpa[:,0])
    endp.sort(key=lambda n: abs(n[0]-medianx))
    root = endp[0]
#sg.viewGraph()
    sg.setRoot(root,key="og_medianx")
    sg.traceEndpoints(key='og_medianx')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
#print "Define orthogonal planes"
    sg.defineOrthogonalPlanes(ogkey)
# Now get surface points of original image to map to the centerlines
    dfe = ndi.distance_transform_cdt(oimg)
    points_toMap = np.array(np.nonzero(np.where(dfe==1,1,0))[::-1]).transpose().astype(np.int32)
#print "mapVoxelsToGraph"
    sg.mapVoxelsToGraph(points_toMap,ogkey)
#print "assignMappedPointsToPlanes"
    sg.assignMappedPointsToPlanes(ogkey)
    sg.saveCompressedGraphs(sys.argv[3])
Ejemplo n.º 11
0
def main():
    dcm = dicom.read_file(sys.argv[1])
    img=dcm.pixel_array
    sg = SkeletonGraph(img)
    arg2 = dicom.read_file(sys.argv[2])
    img2 = arg2.pixel_array
    sg.setOriginalImage(img2)
#sg.setOriginalImage(fname=sys.argv[2])
    sg.getGraphsFromSkeleton(verbose=False)
    sg.setLargestGraphToCurrentGraph()
    list(sg.graphs.keys())
    sg.findEndpointsBifurcations()
    root = sg.selectSeedFromDFE()
#sg.viewGraph()
#raw_input('continue')
    sg.setRoot(root,key="test")
    sg.traceEndpoints(key='test')
    ogkey = sg.getLargestOrderedGraphKey()
    sg.deleteDegree2Nodes(ogkey)
    sg.prunePaths(ogkey)
    sg.deleteDegree2Nodes(ogkey)
    sg.fitEdges(key=ogkey)
    og = sg.orderedGraphs[ogkey]
    sg.viewGraph(og)
    sg.saveGraphs(sys.argv[3])
Ejemplo n.º 12
0
class GraphViewer(object):
    def __init__(self, fname, objectnum=-1, keyname='', newsuffix="_edited"):
        self.fname = fname
        #self.efile = file(fname+".error","w")
        #self.stderr = sys.stderr
        #f = file(fname)
        #self.data = cPickle.load(f)
        self.data = readGraphs(fname)
        #f.close()
        if (objectnum == -1 or keyname == ''):
            self.key = getOrderedGraphKeys(self.data['orderedGraphs'])
        else:
            self.key = (objectnum, keyname)
        self.sg = SkeletonGraph()
        self.sg.orderedGraphs = self.data['orderedGraphs']
        self.sg.roots = self.data['roots']
        if ("root" not in self.sg.orderedGraphs[self.key].graph):
            self.sg.orderedGraphs[self.key].graph["root"] = self.sg.roots[
                self.key]

        #self.picker = self.figure.scene.get()['picker']
        #self.figure.scene.picker.pointpicker.add_observer('EndPickEvent',self.picker_callback)
        self._setGraphData()
        # Decrease the tolerance, so that we can more easily select a precise
        # point.
        self.editnum = 1
        # create a new key and copy of graph
        newKey = (self.key[0], "%s%s" % (
            self.key[1],
            newsuffix,
        ))
        self.sg.orderedGraphs[newKey] = self.sg.orderedGraphs[self.key].copy()
        self.key = newKey
        self.deleteNode = None

    def saveModifiedData(self):
        print("saving modified data")
        self.data['orderedGraphs'] = self.sg.orderedGraphs
        #f = file(self.fname,"wb")
        writeGraphs(self.data, self.fname)

    def _setGraphData(self):
        self.og = self.sg.orderedGraphs[self.key]
        self.edges = self.og.edges(data=True)
        self.nodes = self.og.nodes(data=True)

    def _clearGraphDrawables(self):
        self.npts = 0
        self.node_points = 0
        self.surfaces = 0
        self.lines = 0
        self.crds = 0

    def drawGraph(self):
        self.figure = mlab.figure(self.editnum,
                                  fgcolor=(0, 0, 0),
                                  bgcolor=(1, 1, 1))
        self.gcf = mlab.gcf()
        #mlab.clf()
        self.picker = self.figure.on_mouse_pick(self.picker_callback)
        self.picker.tolerance = 0.01
        self.figure.scene.disable_render = True
        #self.gcf.scene.picker.pointpicker.add_observer("EndPickEvent",self.picker_callback)
        node_color = []
        self.crds = {}

        # create drawables for bifurcations and endpoints
        self.narray = np.zeros((len(self.nodes), 3), dtype=np.float32)
        s = np.zeros((len(self.nodes), ))
        for i in range(self.narray.shape[0]):
            n = self.nodes[i]
            self.narray[i, :] = n[1]['wcrd']
            dg = self.og.degree(n[0])
            if (dg == 1):
                wc = n[1]['wcrd']
                txt = "(%d,%d,%d)" % (n[0][0], n[0][1], n[0][2])

                #self.crds[n[0]] = mlab.text3d(wc[0],wc[1],wc[2],
                #                         "this is a text", color=(0,0,0), scale=2.0)
                s[i] = 1.0
            else:
                s[i] = 0.5
        self.npts = mlab.points3d(self.narray[:, 0],
                                  self.narray[:, 1],
                                  self.narray[:, 2],
                                  s,
                                  colormap="gray",
                                  scale_factor=4.0)
        self.node_points = self.npts.glyph.glyph_source.glyph_source.output.points.to_array(
        )

        # now draw

        self.surfaces = {}
        self.lines = {}
        colors = ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1,
                                                                          1))
        counter = 0
        for e in self.edges:
            try:
                clr = colors[counter % len(colors)]
                counter += 1
                mp = e[2][
                    "mappedPoints"]  #np.concatenate((mp,e[2]["mappedPoints"]),axis=0)
                sp = e[2]['d0']

                x = mp[::4, 0]
                y = mp[::4, 1]
                z = mp[::4, 2]
                #Visualize the points
                pts = mlab.points3d(x,
                                    y,
                                    z,
                                    scale_mode='none',
                                    scale_factor=0.2,
                                    opacity=0.0)

                # Create and visualize the mesh
                # redirect sys.stderr for this step
                #sys.stderr = self.efile
                mesh = mlab.pipeline.delaunay3d(pts)
                self.surfaces[(e[0],
                               e[1])] = mlab.pipeline.surface(mesh,
                                                              color=clr,
                                                              opacity=0.1)
                #sys.stderr = self.stderr
                pts = 0
                if (sp):
                    self.lines[(e[0], e[1])] = mlab.plot3d(sp[0],
                                                           sp[1],
                                                           sp[2],
                                                           color=clr,
                                                           tube_radius=1.0)
            except KeyError as error:
                print("KeyError", error)
            except IndexError as error:
                print("IndexError", error)
        #mlab.view(47, 57, 8.2, (0.1, 0.15, 0.14))
        self.figure.scene.disable_render = False
        print("ready for editing")
        mlab.show()

    def picker_callback(self, pckr):
        # currently this callback gets disconnected when I clear the figure
        # so I am compensating by creating a new figure to draw on with each call
        print("in picker_callback3")
        delta = 2
        surfaceKeys = list(self.surfaces.keys())
        for sk in surfaceKeys:
            try:
                if (pckr.actor in self.surfaces[sk].actor.actors):
                    print("we picked a surface")
                    print(sk)
                    newNode = sk[1]
                    if (self.sg.orderedGraphs[self.key].degree(newNode) == 1):
                        if (self.deleteNode == newNode):
                            #mlab.clf(self.editnum)
                            self.sg.pruneSpecifiedDegreeOneNode(
                                self.key, self.deleteNode)
                            self.sg.remapVoxelsToGraph(self.key)
                            self.editnum += 1
                            self.saveModifiedData()
                            self._setGraphData()
                            self._clearGraphDrawables()
                            self.drawGraph()
                            self.deleteNode = None

                        else:
                            self.deleteNode = newNode
                            wcrd = self.sg.orderedGraphs[
                                self.key].node[newNode]['wcrd']
                            outline = mlab.outline(line_width=3)
                            outline.outline_mode = 'cornered'
                            outline.bounds = (wcrd[0] - delta, wcrd[0] + delta,
                                              wcrd[1] - delta, wcrd[1] + delta,
                                              wcrd[2] - delta, wcrd[2] + delta)
                    else:
                        print("This is not a degree 1 node. Degree = %s" %
                              self.sg.orderedGraphs[self.key].degree(newNode))
            except KeyError:
                pass