Example #1
0
 def getAdjacentElements(self,seg,skelctxt):
     els = seg.getElements()
     if len(els) > 1:
         msobj=skelctxt.getMicrostructure()
         where = msobj.getRepresentativePixel(
             els[0].dominantPixel(msobj))
         grpnames1 = pixelgroup.pixelGroupNames(msobj, where)
         where = msobj.getRepresentativePixel(
             els[1].dominantPixel(msobj))
         grpnames2 = pixelgroup.pixelGroupNames(msobj, where)
         if self.left!=NO_PIXELGROUP and \
                 self.right!=NO_PIXELGROUP:
             if (self.left in grpnames1 and \
                     self.right in grpnames2):
                 return AdjacentElements(els[0],els[1])
             if (self.left in grpnames2 and \
                     self.right in grpnames1):
                 return AdjacentElements(els[1],els[0])
         elif self.left!=NO_PIXELGROUP:
             if (self.left in grpnames1 and \
                     len(grpnames2)==0):
                 return AdjacentElements(els[0],els[1])
             if (self.left in grpnames2 and \
                     len(grpnames1)==0):
                 return AdjacentElements(els[1],els[0])
         elif self.right!=NO_PIXELGROUP:
             if (self.right in grpnames1 and \
                     len(grpnames2)==0):
                 return AdjacentElements(els[1],els[0])
             if (self.right in grpnames2 and \
                     len(grpnames1)==0):
                 return AdjacentElements(els[0],els[1])
     else:
         #Determine on which external boundary the segment lies
         n0=seg.get_nodes()[0].position()
         n1=seg.get_nodes()[1].position()
         xmax=skelctxt.getMicrostructure().size().x
         ymax=skelctxt.getMicrostructure().size().y
         if n0.y==ymax and n1.y==ymax:
             compass=NORTH #golden
         elif n0.y==0.0 and n1.y==0.0:
             compass=SOUTH
         elif n0.x==xmax and n1.x==xmax:
             compass=EAST
         #elif n0.x==0.0 and n1.x==0.0:
         else:
             compass=WEST
         #
         msobj=skelctxt.getMicrostructure()
         where = msobj.getRepresentativePixel(
             els[0].dominantPixel(msobj))
         grpnames = pixelgroup.pixelGroupNames(msobj, where)
         if self.left==compass and \
                ((self.right in grpnames) or self.right==ANY):
             return AdjacentElements(None,els[0])
         if self.right==compass and \
                ((self.left in grpnames) or self.left==ANY):
             return AdjacentElements(els[0],None)
     return AdjacentElements()
Example #2
0
def _auto_group(menuitem, skeleton):
    skelc = whoville.getClass('Skeleton')[skeleton]
    groupset = getattr(skelc, menuitem.data)
    ms = skelc.getMicrostructure()      # ms object, not context
    mscontext = microstructure.microStructures[ms.name()]
    mscontext.begin_reading()
    # gdict is a dict of lists of objects to add to each group, keyed
    # by group name
    gdict = {}
    try:
        # Create groups
        groupnames = ms.groupNames()    # all pixel group names in ms
        newgrps = [name for name in groupnames if not groupset.isGroup(name)]
        groupset.addGroup(*newgrps)
        # Find objects to add to groups
        for obj in menuitem.iterator(skelc.getObject().sheriffSkeleton()):
            cat = obj.dominantPixel(ms) # dominant pxl category
            repPix = ms.getRepresentativePixel(cat) # representative pixel
            # grplist contains all pixel group names at the repr. pixel
            grplist = pixelgroup.pixelGroupNames(ms, repPix)
            for name in grplist:
                gdict.setdefault(name, []).append(obj)

        # Actually add objects to groups
        groupset.addToGroup(**gdict)
    finally:
        mscontext.end_reading()
Example #3
0
 def contains(self, pt):
     ipt = self.ms.pixelFromPoint(pt)
     if self.pixels == placeholder.selection:
         return self.ms.pixelselection.getObject().isSelected(ipt)
     elif self.pixels == placeholder.every:
         return True
     else:
         groups = pixelgroup.pixelGroupNames(self.ms, ipt)
         return self.pixels in groups
Example #4
0
    def updateSomething(self, container):
        debug.subthreadTest()
        element = container.object
        skeleton = container.skeleton

        container.context.begin_reading()
        try:
            etype = `element.type()`[1:-1] # strip quotes
            eindex = `element.getIndex()`

            if config.dimension() == 2:
                self.updateNodeListAngle(self.nodes, element)
            elif config.dimension() == 3:
                self.updateNodeList(self.nodes, element.nodes)
            # Clear the selection in the list of nodes if there's
            # nothing in the peeker.
            self.syncPeeker(self.nodes, "Node")

            esegs = element.getSegments(skeleton)
            self.updateSegmentList(self.segs, esegs)
            # Clear the selection in the list of segments if there's
            # nothing in the peeker.
            self.syncPeeker(self.segs, "Segment")

            if config.dimension() == 2:
                earea = "%s" % element.area()
            elif config.dimension() == 3:
                earea = "%s" % element.volume()

            if not element.illegal():
                domCat = element.dominantPixel(skeleton.MS)
                repPix = skeleton.MS.getRepresentativePixel(domCat)
                pixGrp = pixelgroup.pixelGroupNames(skeleton.MS, repPix)
                pixgrps = string.join(pixGrp, ", ")
                ehom = "%f" % element.homogeneity(skeleton.MS)
                eshape = "%f" % element.energyShape()

                mat = element.material(container.context)
                if mat:
                    matname = mat.name()
                else:
                    matname = "<No material>"
            else:                           # illegal element
                pixgrps = "???"
                ehom = "???"
                eshape = "???"
                matname = "???"
            self.updateGroup(element)
        finally:
            container.context.end_reading()
        mainthread.runBlock(self.updateSomething_thread,
                            (etype, eindex, earea, pixgrps, ehom, eshape,
                             matname))
Example #5
0
 def update_thread(self, where):
     debug.subthreadTest()
     microstructure = self.toolbox.findMicrostructure()
     if microstructure and where is not None:
         mscntxt = ooflib.common.microstructure.getMSContextFromMS(
             microstructure)
         msname = microstructure.name()
         mscntxt.begin_reading()
         try:
             names = pixelgroup.pixelGroupNames(microstructure, where)
         finally:
             mscntxt.end_reading()
         grpnames = '\n'.join(names)
     else:
         msname = '(No microstructure)'
         grpnames = ''
     mainthread.runBlock(self.reallyupdate, (msname, grpnames))
Example #6
0
def parallel_skel_info_query(menuitem, targetname, position, skeleton):
    debug.fmsg()
    skelcontext = skeletoncontext.skeletonContexts[skeleton]        
    skelobj = skelcontext.getObject()
    skelcontext.begin_reading()
    try:
        if targetname=="Node":
            node = skelobj.nearestNode(position)
            nodeindex=-1
            reportstring=""
            distance2=-1
            if node:
                nodeindex=node.getIndex()
                distance2=(node.position()-position)**2
                if node.movable_x() and node.movable_y():
                    nmob = "free"
                elif node.movable_x() and not node.movable_y():
                    nmob = "x only"
                elif not node.movable_x() and node.movable_y():
                    nmob = "y only"
                elif node.pinned():
                    nmob = "pinned"
                else:
                    nmob = "fixed"
                nneighborelements="None"
                if node.neighborElements(skelobj):
                    nneighborelements=string.join(["Element %d" % obj.index
                                                   for obj in node.neighborElements(skelobj)],",")
                reportstring="""
    index=%d
    position=(%g,%g)
    mobility=%s
    neighborelements=%s""" % (nodeindex,
                                node.position().x,node.position().y,
                                nmob,
                                nneighborelements)

            if _rank==0:
                #Get list of squares of distance of node to the click point
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=-1
                dmin_proc=-1
                msg="Skeleton Info Query Node IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                    #msg+="From process %d:%s\n" % (proc,reportstringlist[proc])
                #Find closest node among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="The closest node to the point clicked at (%g,%g) is from process %d:%s\n" % \
                    (position.x,position.y,dmin_proc,reportstringlist[dmin_proc])
                reporter.report(msg)
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2,0)
        ################################################################################
        elif targetname=="Segment":
            # Function to calculate the distance squared between a point and
            # a segment (the perpendicular distance or distance from endpoints),
            # taken from skeleton.py.
            def segdistance(pt, segment):
                nodes = segment.nodes()
                p0 = nodes[0].position()
                p1 = nodes[1].position()
                a = pt-p0
                b = p1-p0
                seglength2 = b**2
                f = ((a*b)/seglength2)
                if f < 0:
                    alpha = -f
                    r = pt - p0
                elif f > 1:
                    alpha = f-1
                    r = pt - p1
                else:
                    r = a-f*b
                    alpha = 0
                return (r**2, alpha*alpha*seglength2)

            sgmt = skelobj.nearestSgmt(position)
            reportstring=""
            distance2=(-1,-1)
            if sgmt:
                distance2=segdistance(position,sgmt)
                sindex = `sgmt.getIndex()`
                length = `sgmt.length()`
                homogval = sgmt.homogeneity(skelobj.MS)
                if 0.9999 < homogval < 1.0:
                    homog = "1 - (%e)" % (1.0-homogval)
                else:
                    homog = `homogval`

                reportstring="""
    index=%s
    nodes=%s
    elements=%s
    length=%s
    homogeneity=%s""" % (sindex,
                         string.join(["Node %d at (%g, %g)" % (obj.index,
                                                               obj.position().x,
                                                               obj.position().y)
                                      for obj in sgmt.get_nodes()],","),
                         string.join(["Element %d" % obj.index for obj in sgmt.getElements()],","),
                         length,
                         homogval)

            if _rank==0:
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=(-1,-1)
                dmin_proc=-1
                msg="Skeleton Info Query Segment IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append((mpitools.Recv_Double(proc),mpitools.Recv_Double(proc)))
                    if distance2list[proc][0]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                #Find closest segment among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc][0]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="From process %d:" % dmin_proc
                    msg+=reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No segment found!\n")
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2[0],0)
                mpitools.Send_Double(distance2[1],0)
        ################################################################################
        elif targetname=="Element":
            #This gets the element closest to the clicked point.
            #If the point is not within the microstructure then the point
            #is moved to the boundaries of the microstructure.
            elem = skelobj.enclosingElement(position)
            reportstring=""
            distance2=-1
            if elem:
                distance2=(elem.center()-position)**2
                etype = `elem.type()`[1:-1] # strip quotes
                eindex = `elem.getIndex()`
                earea = "%g" % elem.area()

                if not elem.illegal():
                    domCat = elem.dominantPixel(skelobj.MS)
                    repPix = skelobj.MS.getRepresentativePixel(domCat)
                    pixGrp = pixelgroup.pixelGroupNames(skelobj.MS, repPix)
                    pixgrps = string.join(pixGrp, ", ")
                    ehom = "%f" % elem.homogeneity(skelobj.MS)
                    eshape = "%f" % elem.energyShape()

                    mat = elem.material(skelobj)
                    if mat:
                        matname = mat.name()
                    else:
                        matname = "<No material>"
                else:                           # illegal element
                    pixgrps = "???"
                    ehom = "???"
                    eshape = "???"
                    matname = "???"

                reportstring="""
    index=%s
    type=%s
    nodes=%s
    segments=%s
    area=%s
    dominant pixel=%s
    homogeneity=%s
    shape energy=%s
    material=%s""" % (eindex,
                      etype,
                      string.join(["Node %d at (%g, %g)" % (obj.index,
                                                            obj.position().x,
                                                            obj.position().y)
                                   for obj in elem.nodes],","),
                      string.join(["Segment %d, nodes (%d, %d) (length: %g)" %
                                   (obj.index, obj.nodes()[0].index, obj.nodes()[1].index,
                                    obj.length())
                                   for obj in elem.getSegments(skelobj)],","),
                      earea,
                      pixgrps,
                      ehom,
                      eshape,
                      matname)

            if _rank==0:
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=-1
                dmin_proc=-1
                msg="Skeleton Info Query Element IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                #Find closest element among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="From process %d:" % dmin_proc
                    msg+=reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No enclosing element found!\n")
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2,0)
    finally:
        skelcontext.end_reading()
Example #7
0
 def getAdjacentElements(self,seg,skelctxt):
     els = seg.getElements()
     if len(els) > 1:
         msobj=skelctxt.getMicrostructure()
         where = msobj.getRepresentativePixel(
             els[0].dominantPixel(msobj))
         grpnames1 = pixelgroup.pixelGroupNames(msobj, where)
         where = msobj.getRepresentativePixel(
             els[1].dominantPixel(msobj))
         grpnames2 = pixelgroup.pixelGroupNames(msobj, where)
         if self.left!=NO_PIXELGROUP:
             if (self.left in grpnames1 and \
                 self.left not in grpnames2):
                 return AdjacentElements(els[0],els[1])
             if (self.left in grpnames2 and \
                 self.left not in grpnames1):
                 return AdjacentElements(els[1],els[0])
         else:
             if (len(grpnames1)>0 and len(grpnames2)==0):
                 return AdjacentElements(els[1],els[0])
             if (len(grpnames2)>0 and len(grpnames1)==0):
                 return AdjacentElements(els[0],els[1])
     else:
         if self.left==NORTH:
             n0=seg.get_nodes()[0].position()
             n1=seg.get_nodes()[1].position()
             ymax=skelctxt.getMicrostructure().size().y
             if n0.y==ymax and n1.y==ymax:
                 return AdjacentElements(None,els[0])
             else:
                 return AdjacentElements()
         if self.left==SOUTH:
             n0=seg.get_nodes()[0].position()
             n1=seg.get_nodes()[1].position()
             if n0.y==0.0 and n1.y==0.0:
                 return AdjacentElements(None,els[0])
             else:
                 return AdjacentElements()
         if self.left==EAST:
             n0=seg.get_nodes()[0].position()
             n1=seg.get_nodes()[1].position()
             xmax=skelctxt.getMicrostructure().size().x
             if n0.x==xmax and n1.x==xmax:
                 return AdjacentElements(None,els[0])
             else:
                 return AdjacentElements()
         if self.left==WEST:
             n0=seg.get_nodes()[0].position()
             n1=seg.get_nodes()[1].position()
             if n0.x==0.0 and n1.x==0.0:
                 return AdjacentElements(None,els[0])
             else:
                 return AdjacentElements()
         msobj=skelctxt.getMicrostructure()
         where = msobj.getRepresentativePixel(
             els[0].dominantPixel(msobj))
         grpnames = pixelgroup.pixelGroupNames(msobj, where)
         if self.left in grpnames:
             return AdjacentElements(els[0],None)
     # Default, obviously.
     return AdjacentElements()
Example #8
0
def _writeData(self, dfile, microstructure, pixel):
    grpnames = pixelgroup.pixelGroupNames(microstructure, pixel)
    if grpnames:
        dfile.argument('groups', grpnames)
        return 1
    return 0
Example #9
0
def _writeData(self, dfile, microstructure, pixel):
    grpnames = pixelgroup.pixelGroupNames(microstructure, pixel)
    if grpnames:
        dfile.argument('groups', grpnames)
        return 1
    return 0
Example #10
0
    def update(self, indx):
        debug.subthreadTest()
        skelctxt = self.getContext()
        if not skelctxt:
            return
        skeleton = skelctxt.getObject()
        if indx is not None and 0 <= indx < skeleton.nelements():
            skelctxt.begin_reading()
            try:
                microstructure = skeleton.getMicrostructure()
                # If the user typed the index, instead of clicking on
                # an element, it could be invalid.
                if indx < 0 or indx >= skeleton.nelements():
                    return

                element = skeleton.getElement(indx)
                assert element is not None

                if config.dimension() == 3:
                    self.updateFaceList(self.faces,
                                        skeleton.getElementFaces(element))
                self.updateSegmentList(self.segs,
                                       skeleton.getElementSegments(element))
                self.updateNodeList(self.nodes, element.getNodes(), element)

                eid = ` indx `
                etype = skeleton.getElementType(element.getIndex())
                if config.dimension() == 3:
                    earea = "%g" % element.volume()
                elif config.dimension() == 2:
                    earea = "%g" % element.area()
                if not element.illegal():
                    domCat = element.dominantPixel(microstructure)
                    pixGrp = pixelgroup.pixelGroupNames(microstructure, domCat)
                    pixgrps = ", ".join(pixGrp)
                    hom = "%f" % element.homogeneity(microstructure)
                    eshape = "%f" % element.energyShape()
                    mat = element.material(skeleton)
                    egrps = ','.join(element.groupNames())
                    if mat:
                        matname = mat.name()
                    else:
                        matname = "<No material>"
                else:  # illegal element
                    pixgrps = "???"
                    egrps = "???"
                    hom = "???"
                    eshape = "???"
                    matname = "???"
                mainthread.runBlock(self.update_thread,
                                    (etype, eid, earea, ` domCat
                                     `, egrps, hom, eshape, matname))
                # mainthread.runBlock(self.update_thread,
                #                     (etype, eid, earea, pixgrps, egrps, hom,
                #                      eshape, matname))
                return
            finally:
                skelctxt.end_reading()
        # end if indx is not None
        # Nothing to display -- no element or no indx.
        mainthread.runBlock(self.update_thread,
                            ("", "", "", "", "", "", "", ""))
        mainthread.runBlock(self.clearObjLists)
Example #11
0
def parallel_skel_info_query(menuitem, targetname, position, skeleton):
    debug.fmsg()
    skelcontext = skeletoncontext.skeletonContexts[skeleton]
    skelobj = skelcontext.getObject()
    skelcontext.begin_reading()
    try:
        if targetname == "Node":
            node = skelobj.nearestNode(position)
            nodeindex = -1
            reportstring = ""
            distance2 = -1
            if node:
                nodeindex = node.getIndex()
                distance2 = (node.position() - position) ** 2
                if node.movable_x() and node.movable_y():
                    nmob = "free"
                elif node.movable_x() and not node.movable_y():
                    nmob = "x only"
                elif not node.movable_x() and node.movable_y():
                    nmob = "y only"
                elif node.pinned():
                    nmob = "pinned"
                else:
                    nmob = "fixed"
                nneighborelements = "None"
                if node.neighborElements(skelobj):
                    nneighborelements = string.join(
                        ["Element %d" % obj.index for obj in node.neighborElements(skelobj)], ","
                    )
                reportstring = """
    index=%d
    position=(%g,%g)
    mobility=%s
    neighborelements=%s""" % (
                    nodeindex,
                    node.position().x,
                    node.position().y,
                    nmob,
                    nneighborelements,
                )

            if _rank == 0:
                # Get list of squares of distance of node to the click point
                distance2list = [distance2]
                # Get list of reportstring(s) from each process
                reportstringlist = [reportstring]
                dmin = -1
                dmin_proc = -1
                msg = "Skeleton Info Query Node IPC/MPI:\n"
                # Get report from other processes
                for proc in range(_size):
                    if proc != 0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc] >= 0:
                        dmin = distance2list[proc]
                        dmin_proc = proc
                    # msg+="From process %d:%s\n" % (proc,reportstringlist[proc])
                # Find closest node among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc] >= 0:
                        if distance2list[proc] < dmin:
                            dmin = distance2list[proc]
                            dmin_proc = proc
                if dmin_proc != -1:
                    msg += "The closest node to the point clicked at (%g,%g) is from process %d:%s\n" % (
                        position.x,
                        position.y,
                        dmin_proc,
                        reportstringlist[dmin_proc],
                    )
                reporter.report(msg)
            else:
                # Backend sends report to front end
                mpitools.Send_String(reportstring, 0)
                mpitools.Send_Double(distance2, 0)
        ################################################################################
        elif targetname == "Segment":
            # Function to calculate the distance squared between a point and
            # a segment (the perpendicular distance or distance from endpoints),
            # taken from skeleton.py.
            def segdistance(pt, segment):
                nodes = segment.nodes()
                p0 = nodes[0].position()
                p1 = nodes[1].position()
                a = pt - p0
                b = p1 - p0
                seglength2 = b ** 2
                f = (a * b) / seglength2
                if f < 0:
                    alpha = -f
                    r = pt - p0
                elif f > 1:
                    alpha = f - 1
                    r = pt - p1
                else:
                    r = a - f * b
                    alpha = 0
                return (r ** 2, alpha * alpha * seglength2)

            sgmt = skelobj.nearestSgmt(position)
            reportstring = ""
            distance2 = (-1, -1)
            if sgmt:
                distance2 = segdistance(position, sgmt)
                sindex = ` sgmt.getIndex() `
                length = ` sgmt.length() `
                homogval = sgmt.homogeneity(skelobj.MS)
                if 0.9999 < homogval < 1.0:
                    homog = "1 - (%e)" % (1.0 - homogval)
                else:
                    homog = ` homogval `

                reportstring = """
    index=%s
    nodes=%s
    elements=%s
    length=%s
    homogeneity=%s""" % (
                    sindex,
                    string.join(
                        [
                            "Node %d at (%g, %g)" % (obj.index, obj.position().x, obj.position().y)
                            for obj in sgmt.get_nodes()
                        ],
                        ",",
                    ),
                    string.join(["Element %d" % obj.index for obj in sgmt.getElements()], ","),
                    length,
                    homogval,
                )

            if _rank == 0:
                distance2list = [distance2]
                # Get list of reportstring(s) from each process
                reportstringlist = [reportstring]
                dmin = (-1, -1)
                dmin_proc = -1
                msg = "Skeleton Info Query Segment IPC/MPI:\n"
                # Get report from other processes
                for proc in range(_size):
                    if proc != 0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append((mpitools.Recv_Double(proc), mpitools.Recv_Double(proc)))
                    if distance2list[proc][0] >= 0:
                        dmin = distance2list[proc]
                        dmin_proc = proc
                # Find closest segment among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc][0] >= 0:
                        if distance2list[proc] < dmin:
                            dmin = distance2list[proc]
                            dmin_proc = proc
                if dmin_proc != -1:
                    msg += "From process %d:" % dmin_proc
                    msg += reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No segment found!\n")
            else:
                # Backend sends report to front end
                mpitools.Send_String(reportstring, 0)
                mpitools.Send_Double(distance2[0], 0)
                mpitools.Send_Double(distance2[1], 0)
        ################################################################################
        elif targetname == "Element":
            # This gets the element closest to the clicked point.
            # If the point is not within the microstructure then the point
            # is moved to the boundaries of the microstructure.
            elem = skelobj.enclosingElement(position)
            reportstring = ""
            distance2 = -1
            if elem:
                distance2 = (elem.center() - position) ** 2
                etype = ` elem.type() `[1:-1]  # strip quotes
                eindex = ` elem.getIndex() `
                earea = "%g" % elem.area()

                if not elem.illegal():
                    domCat = elem.dominantPixel(skelobj.MS)
                    repPix = skelobj.MS.getRepresentativePixel(domCat)
                    pixGrp = pixelgroup.pixelGroupNames(skelobj.MS, repPix)
                    pixgrps = string.join(pixGrp, ", ")
                    ehom = "%f" % elem.homogeneity(skelobj.MS)
                    eshape = "%f" % elem.energyShape()

                    mat = elem.material(skelobj)
                    if mat:
                        matname = mat.name()
                    else:
                        matname = "<No material>"
                else:  # illegal element
                    pixgrps = "???"
                    ehom = "???"
                    eshape = "???"
                    matname = "???"

                reportstring = """
    index=%s
    type=%s
    nodes=%s
    segments=%s
    area=%s
    dominant pixel=%s
    homogeneity=%s
    shape energy=%s
    material=%s""" % (
                    eindex,
                    etype,
                    string.join(
                        ["Node %d at (%g, %g)" % (obj.index, obj.position().x, obj.position().y) for obj in elem.nodes],
                        ",",
                    ),
                    string.join(
                        [
                            "Segment %d, nodes (%d, %d) (length: %g)"
                            % (obj.index, obj.nodes()[0].index, obj.nodes()[1].index, obj.length())
                            for obj in elem.getSegments(skelobj)
                        ],
                        ",",
                    ),
                    earea,
                    pixgrps,
                    ehom,
                    eshape,
                    matname,
                )

            if _rank == 0:
                distance2list = [distance2]
                # Get list of reportstring(s) from each process
                reportstringlist = [reportstring]
                dmin = -1
                dmin_proc = -1
                msg = "Skeleton Info Query Element IPC/MPI:\n"
                # Get report from other processes
                for proc in range(_size):
                    if proc != 0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc] >= 0:
                        dmin = distance2list[proc]
                        dmin_proc = proc
                # Find closest element among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc] >= 0:
                        if distance2list[proc] < dmin:
                            dmin = distance2list[proc]
                            dmin_proc = proc
                if dmin_proc != -1:
                    msg += "From process %d:" % dmin_proc
                    msg += reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No enclosing element found!\n")
            else:
                # Backend sends report to front end
                mpitools.Send_String(reportstring, 0)
                mpitools.Send_Double(distance2, 0)
    finally:
        skelcontext.end_reading()