def compute_initial_figure(self):
        # Scale results to keep same aspect ratio (matplotlib apsect='equal' is broken in 3d...)
        xmin, xmax, ymin, ymax, zmin, zmax = None, None, None, None, None, None
        for offset, ax in enumerate(self.axes):
            treeIdx = self.firstTree + offset
            treeModel = self.treeModels[treeIdx]
            x, y, z = treeModel.worldCoordPoints(treeModel.flattenPoints())
            if xmin is None:
                xmin, xmax = np.min(x), np.max(x)
                ymin, ymax = np.min(y), np.max(y)
                zmin, zmax = np.min(z), np.max(z)
            else:
                xmin, xmax = min(xmin, np.min(x)), max(xmax, np.max(x))
                ymin, ymax = min(ymin, np.min(y)), max(ymax, np.max(y))
                zmin, zmax = min(zmin, np.min(z)), max(zmax, np.max(z))

        r = (0.5 * max(xmax - xmin, ymax - ymin, zmax - zmin)) * 1.1
        xM, yM, zM = (xmax + xmin) / 2, (ymax + ymin) / 2, (zmax + zmin) / 2

        for offset, ax in enumerate(self.axes):
            treeIdx = self.firstTree + offset
            treeModel = self.treeModels[treeIdx]
            ax.set_title(util.createTitle(treeIdx, self.filePaths[treeIdx]),
                         color='white')
            ax.set_xlim3d(xM - r, xM + r)
            ax.set_ylim3d(yM - r, yM + r)
            ax.set_zlim3d(zM - r, zM + r)
            self.drawSingleTree3D(ax, treeIdx, treeModel)
Exemple #2
0
    def drawSingleTreeChanges(self, ax, isFirstTree):
        changeColor = GONE_COLOR if isFirstTree else ADDED_COLOR

        treeIdx = self.firstTree + (0 if isFirstTree else 1)
        otherTreeIdx = self.firstTree + (1 if isFirstTree else 0)
        treeModel = self.treeModels[treeIdx]
        otherTreeModel = self.treeModels[otherTreeIdx]

        ax.set_title(util.createTitle(treeIdx, self.filePaths[treeIdx]),
                     color='w')

        # Draw lines for each branch:
        for branch in treeModel.branches:
            if branch.parentPoint is None:
                continue
            points = [branch.parentPoint] + branch.points
            x, y, z = treeModel.worldCoordPoints(points)
            ax.plot(x, y, z, c=GREY_COLOUR,
                    lw=1)  # TODO - draw axon differently?

        # Split points by keep/new status:
        somaColor = None
        otherPointIDs = set([p.id for p in otherTreeModel.flattenPoints()])
        keptPoints, newPoints = [], []
        for p in treeModel.flattenPoints():
            newPoint = p.id not in otherPointIDs
            if p.isRoot():
                somaColor = changeColor if newPoint else KEPT_COLOR
            else:
                toAppend = newPoints if newPoint else keptPoints
                toAppend.append(p)

        # Draw the points by keep/remove:
        self.drawPointsOneColor(ax, treeModel, keptPoints, KEPT_COLOR)
        self.drawPointsOneColor(ax, treeModel, newPoints, changeColor)
        self.drawPointsOneColor(ax,
                                treeModel, [treeModel.rootPoint],
                                somaColor,
                                s=350)  # Big soma

        # Make equal aspect ratio:
        x, y, z = treeModel.worldCoordPoints(treeModel.flattenPoints())
        xmin, xmax = np.min(x), np.max(x)
        ymin, ymax = np.min(y), np.max(y)
        zmin, zmax = np.min(z), np.max(z)
        r = (0.5 * max(xmax - xmin, ymax - ymin, zmax - zmin)) * 1.1
        xM, yM, zM = (xmax + xmin) / 2, (ymax + ymin) / 2, (zmax + zmin) / 2
        ax.set_xlim3d(xM - r, xM + r)
        ax.set_ylim3d(yM - r, yM + r)
        ax.set_zlim3d(zM - r, zM + r)
Exemple #3
0
    def _addItem(self, idx, filePath, stackHidden, isFirst, isLast):
        """Adds a single row into the list, and attaches events."""
        title = util.createTitle(idx, filePath)

        # Build the widget itself.
        container = QtWidgets.QWidget()
        wText = QtWidgets.QLabel(title)
        bViz = cursorPointer(
            QtWidgets.QPushButton("Show" if stackHidden else "Hide"))
        bDel = cursorPointer(QtWidgets.QPushButton("Delete"))
        bUp = cursorPointer(QtWidgets.QPushButton("▲"))
        bDn = cursorPointer(QtWidgets.QPushButton("▼"))
        for b in [bUp, bDn]:
            b.setMaximumWidth(20)
        l = QtWidgets.QHBoxLayout()
        l.addWidget(wText)
        l.addWidget(bViz)
        l.addWidget(bDel)
        l.addWidget(bUp)
        l.addWidget(bDn)
        l.addStretch()
        l.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
        container.setLayout(l)

        if isFirst:
            bUp.setEnabled(False)
        if isLast:
            bDn.setEnabled(False)

        # Build the list item, and add the widget:
        itemN = QtWidgets.QListWidgetItem()
        itemN.setSizeHint(container.sizeHint())
        self.list.addItem(itemN)
        self.list.setItemWidget(itemN, container)

        # Attach events:
        bViz.clicked.connect(lambda: self._handleVizChange(idx))
        bDel.clicked.connect(lambda: self._handleDelete(idx, title))
        bUp.clicked.connect(lambda: self._handleUp(idx))
        bDn.clicked.connect(lambda: self._handleDn(idx))
Exemple #4
0
 def updateTitle(self):
     self.setWindowTitle(util.createTitle(self.windowIndex, self.imagePath))
Exemple #5
0
    def compute_initial_figure(self):
        SZ_FACTOR = self.sizeFactor

        xminD, xmaxD, yminD, ymaxD = 0, 0, 0, 0
        if self.dendrogram:
            allX = [x for treeX in self.dendrogramX for x in treeX.values()]
            allY = [y for treeY in self.dendrogramY for y in treeY.values()]
            xminD, xmaxD = np.min(allX), np.max(allX)
            yminD, ymaxD = np.min(allY), np.max(allY)

        # Update colors to be white on black:
        print ("")
        for offset, ax in enumerate(self.axes):
            treeIdx = self.firstTree + offset
            treeModel = self.treeModels[treeIdx]
            denX, denY = self.dendrogramX[treeIdx], self.dendrogramY[treeIdx]
            ax.set_title(util.createTitle(treeIdx, self.filePaths[treeIdx]))
            ax.set_facecolor("white")
            if self.dendrogram:
                ax.margins(0.1)
                ax.set_xticklabels([])
                ax.set_yticklabels([])
            else:
                ax.w_xaxis.set_pane_color((1.0,1.0,1.0,1.0))
                ax.w_yaxis.set_pane_color((1.0,1.0,1.0,1.0))
                ax.w_zaxis.set_pane_color((1.0,1.0,1.0,1.0))
                ax.w_xaxis._axinfo['grid'].update({'linewidth':0.25,'color':'gray'})
                ax.w_yaxis._axinfo['grid'].update({'linewidth':0.25,'color':'gray'})
                ax.w_zaxis._axinfo['grid'].update({'linewidth':0.25,'color':'gray'})

            # Draw lines for each branch:
            for branch in treeModel.branches:
                if branch.parentPoint is None:
                    continue
                points = [branch.parentPoint] + branch.points
                if self.dendrogram:
                    x = [denX[p.id] for p in points]
                    y = [denY[p.id] for p in points]
                    ax.plot(x, y, c=TREE_COLOUR)
                else:
                    x, y, z = treeModel.worldCoordPoints(points)
                    ax.plot(x, y, z, c=TREE_COLOUR) # TODO - draw axon differently?

            # Draw filo for each branch:
            if treeIdx > 0:
                oldTreeModel = self.treeModels[treeIdx - 1]
                oldDenX, oldDenY = self.dendrogramX[treeIdx - 1], self.dendrogramY[treeIdx - 1]

                # For debugging puposes, maybe remove?
                growCount, shrinkCount = 0, 0

                for branch in treeModel.branches:
                    branchIdx = self.branchIDList.index(branch.id)

                    plot = True
                    if self.added[treeIdx-1][branchIdx]:
                        color, sz = ADDED_COLOR, self.filoLengths[treeIdx][branchIdx] * SZ_FACTOR
                    elif self.transitioned[treeIdx-1][branchIdx]:
                        color, sz = TRANS_COLOR, self.filoLengths[treeIdx][branchIdx] * SZ_FACTOR
                        plot = False # Don't draw transitions ?!
                    else:
                        mot = self.motility[treeIdx-1][branchIdx]
                        if abs(mot) >= self.options.minMotilityDist and len(branch.points) > 0:
                            color = GROW_COLOR if mot > 0 else SHRINK_COLOR
                            if mot > 0:
                                growCount += 1
                            else:
                                shrinkCount += 1
                            sz = abs(mot) * SZ_FACTOR
                        else:
                            plot = False
                    if plot:
                        if len(branch.points) != 0:
                            if self.dendrogram:
                                x = [denX[branch.points[-1].id]]
                                y = [denY[branch.points[-1].id]]
                                ax.scatter(x, y, c=[color], s=sz)
                            else:
                                x, y, z = treeModel.worldCoordPoints([branch.points[-1]])
                                ax.scatter(x, y, z, c=[color], s=sz)

                    # Show removed branches from last point:
                    branchInLast = self.treeModels[treeIdx - 1].getBranchByID(branch.id)
                    if branchInLast is not None:
                        for childPoint in branchInLast.points:
                            retracted = 0
                            for childBranch in childPoint.children:
                                if childBranch is None or len(childBranch.points) == 0:
                                    continue
                                childBranchIdx = self.branchIDList.index(childBranch.id)

                                firstPointID = childBranch.points[0].id
                                inCurrentTree = self.treeModels[treeIdx].getPointByID(firstPointID) is not None
                                if not inCurrentTree:
                                    retracted += self.filoLengths[treeIdx - 1][childBranchIdx]
                            if retracted > 0:
                                # print ("extra retraction: " + str(retracted))
                                if self.dendrogram:
                                    # Not really correct...
                                    pass
                                else:
                                    x, y, z = oldTreeModel.worldCoordPoints([childPoint])
                                    childPointInNew = treeModel.getPointByID(childPoint.id)
                                    if childPointInNew is not None:
                                        x, y, z = treeModel.worldCoordPoints([childPointInNew])
                                    ax.scatter(x, y, z, c=[RETRACT_COLOR], s=(retracted * SZ_FACTOR))

                # Subtractions do not appear in tree, so find by looking at last tree
                for branchIdx, branchId in enumerate(self.branchIDList):
                    if not self.subtracted[treeIdx - 1][branchIdx]:
                        continue
                    branchInLast = self.treeModels[treeIdx - 1].getBranchByID(branchId)
                    if branchInLast is None:
                        continue
                    # Draw at the parent of the subtracted branch, not the end point.
                    drawAt = branchInLast.parentPoint
                    if drawAt is not None:
                        # Walk up the old tree until a point exists in the new
                        # tree to connect the removal to.
                        drawAtInNew = treeModel.getPointByID(drawAt.id)
                        while drawAtInNew is None and drawAt is not None:
                            drawAt = drawAt.nextPointInBranch(delta=-1)
                            if drawAt is not None:
                                drawAtInNew = treeModel.getPointByID(drawAt.id)
                        if drawAt is None or drawAtInNew is None:
                            continue

                        sz = self.filoLengths[treeIdx-1][branchIdx] * SZ_FACTOR
                        if self.dendrogram:
                            x = [denX[drawAtInNew.id]]
                            y = [denY[drawAtInNew.id]]
                            ax.scatter(x, y, c=[GONE_COLOR], s=sz)
                        else:
                            x, y, z = treeModel.worldCoordPoints([drawAtInNew])
                            ax.scatter(x, y, z, c=[GONE_COLOR], s=sz)

                # For debugging puposes, maybe remove?
                print ("Stack #%d -> #%d" % (treeIdx, treeIdx + 1))
                print ("  - #Added        = %d" % np.sum(self.added[treeIdx-1]))
                print ("  - #Subtracted   = %d" % np.sum(self.subtracted[treeIdx-1]))
                print ("  - #Transitioned = %d" % np.sum(self.transitioned[treeIdx-1]))
                print ("  - #Extensions   = %d" % growCount)
                print ("  - #Retractions  = %d" % shrinkCount)

            # And finally draw the soma as a big sphere (if present):
            if treeModel.rootPoint is not None:
                if not self.dendrogram:
                    x, y, z = treeModel.worldCoordPoints([treeModel.rootPoint])
                    ax.scatter(x, y, z, c=[TREE_COLOUR], s=350)

            # Make equal aspect ratio:
            if not self.dendrogram:
                x, y, z = treeModel.worldCoordPoints(treeModel.flattenPoints())
                xmin, xmax = np.min(x), np.max(x)
                ymin, ymax = np.min(y), np.max(y)
                zmin, zmax = np.min(z), np.max(z)
                r = (0.5 * max(xmax - xmin, ymax - ymin, zmax - zmin)) * 1.1
                xM, yM, zM = (xmax + xmin) / 2, (ymax + ymin) / 2, (zmax + zmin) / 2
                ax.set_xlim3d(xM - r, xM + r)
                ax.set_ylim3d(yM - r, yM + r)
                ax.set_zlim3d(zM - r, zM + r)
            else:
                xM, yM = (xmaxD + xminD) / 2, (ymaxD + yminD) / 2
                xR, yR = (0.5 * (xmaxD - xminD) * 1.1), (0.5 * (ymaxD - yminD) * 1.1)
                ax.set_xlim(xM - xR, xM + xR)
                ax.set_ylim(yM - yR, yM + yR)