示例#1
0
 def testOrthoZ(self):
     grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
     plane = OrthoSlice(grid, ZAXIS, SLICEPOS)
     self.assertEquals(tuple(plane.origin), (0, 0, SLICEPOS))
     self.assertEquals(len(plane.basis), 2)
     self.assertTrue((0, 1, 0) in plane.basis)
     self.assertTrue((1, 0, 0) in plane.basis)
示例#2
0
    def testOrthoReversed(self):
        grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
        plane = OrthoSlice(grid, YAXIS, SLICEPOS)

        # Invert Z axis
        affine = np.array([[1, 0, 0, 0], [0, 1, 0, 0],
                           [0, 0, -1, GRIDSIZE - 1], [0, 0, 0, 1]])
        datagrid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), affine)
        YD, XD, ZD = np.meshgrid(range(GRIDSIZE), range(GRIDSIZE),
                                 range(GRIDSIZE))

        xdata, _, _, _ = NumpyData(XD, name="test",
                                   grid=datagrid).slice_data(plane)
        ydata, _, _, _ = NumpyData(YD, name="test",
                                   grid=datagrid).slice_data(plane)
        zdata, _, transv, offset = NumpyData(ZD, name="test",
                                             grid=datagrid).slice_data(plane)

        # Reversal is reflected in the transformation
        self.assertTrue(np.all(transv == [[1, 0], [0, -1]]))

        self.assertTrue(np.all(ydata == SLICEPOS))
        for x in range(GRIDSIZE):
            self.assertTrue(np.all(xdata[x, :] == x))
            self.assertTrue(np.all(zdata[:, x] == x))
示例#3
0
    def update(self):
        """
        Update the ortho view
        """
        if not self.isVisible():
            return

        # Get the current position and slice
        self.focus_pos = self.ivl.focus()

        # Adjust axis scaling to that of the viewing grid
        spacing = self.ivl.grid.spacing
        self.vb.setAspectLocked(True,
                                ratio=(spacing[self.xaxis] /
                                       spacing[self.yaxis]))

        self._update_labels()
        self._update_crosshairs()
        self._update_arrows()

        if self.force_redraw or self.focus_pos[
                self.
                zaxis] != self.slice_z or self.slice_vol != self.focus_pos[3]:
            self.slice_z = self.focus_pos[self.zaxis]
            self.slice_vol = self.focus_pos[3]
            self.slice_plane = OrthoSlice(self.ivl.grid, self.zaxis,
                                          self.focus_pos[self.zaxis])
            self.force_redraw = False
            for view in self._data_views:
                view.redraw(self.vb, self.slice_plane, self.slice_vol)
示例#4
0
 def _update_slice(self):
     self._slicez = self._ivl.focus()[self.zaxis]
     self._vol = self._ivl.focus()[3]
     self._plane = OrthoSlice(self._ivl.grid, self.zaxis, self._slicez)
     for view in self._data_views.values():
         view.plane = self._plane
         view.vol = self._vol
     self.debug("set slice: %f %i", self._slicez, self._vol)
示例#5
0
 def testHighRes(self):
     grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
     plane = OrthoSlice(grid, YAXIS, SLICEPOS)
     data = np.random.rand(GRIDSIZE * 2, GRIDSIZE * 2, GRIDSIZE * 2)
     datagrid = DataGrid((GRIDSIZE * 2, GRIDSIZE * 2, GRIDSIZE * 2),
                         np.identity(4) / 2)
     qpd = NumpyData(data, name="test", grid=datagrid)
     qpd.slice_data(plane)
示例#6
0
    def testOrthoY(self):
        grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
        YD, XD, ZD = np.meshgrid(range(GRIDSIZE), range(GRIDSIZE),
                                 range(GRIDSIZE))

        plane = OrthoSlice(grid, YAXIS, SLICEPOS)
        self.assertEquals(tuple(plane.origin), (0, SLICEPOS, 0))
        self.assertEquals(len(plane.basis), 2)
        self.assertTrue((1, 0, 0) in plane.basis)
        self.assertTrue((0, 0, 1) in plane.basis)
示例#7
0
    def testGenericZ(self):
        trans = np.array([[0.3, 0.2, 1.7, 0], [0.1, 2.1, 0.11, 0],
                          [2.2, 0.7, 0.3, 0], [0, 0, 0, 1]])

        grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), trans)
        origin = list(SLICEPOS * trans[:3, 2])
        plane = OrthoSlice(grid, ZAXIS, SLICEPOS)
        self.assertAlmostEquals(list(plane.origin), origin)
        self.assertEquals(len(plane.basis), 2)
        self.assertTrue(tuple(trans[:3, 0]) in plane.basis)
        self.assertTrue(tuple(trans[:3, 1]) in plane.basis)
示例#8
0
    def testOrtho(self):
        grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
        YD, XD, ZD = np.meshgrid(range(GRIDSIZE), range(GRIDSIZE),
                                 range(GRIDSIZE))

        plane = OrthoSlice(grid, YAXIS, SLICEPOS)
        xdata, _, _, _ = NumpyData(XD, name="test",
                                   grid=grid).slice_data(plane)
        ydata, _, _, _ = NumpyData(YD, name="test",
                                   grid=grid).slice_data(plane)
        zdata, _, _, _ = NumpyData(ZD, name="test",
                                   grid=grid).slice_data(plane)

        self.assertTrue(np.all(ydata == SLICEPOS))
        for x in range(GRIDSIZE):
            self.assertTrue(np.all(xdata[x, :] == x))
            self.assertTrue(np.all(zdata[:, x] == x))
示例#9
0
    def testOrthoOffset(self):
        grid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), np.identity(4))
        plane = OrthoSlice(grid, YAXIS, SLICEPOS)

        # Offset X axis
        affine = np.array([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0],
                           [0, 0, 0, 1]])
        datagrid = DataGrid((GRIDSIZE, GRIDSIZE, GRIDSIZE), affine)
        YD, XD, ZD = np.meshgrid(range(GRIDSIZE), range(GRIDSIZE),
                                 range(GRIDSIZE))

        xdata, _, _, _ = NumpyData(XD, name="test",
                                   grid=datagrid).slice_data(plane)
        ydata, _, _, _ = NumpyData(YD, name="test",
                                   grid=datagrid).slice_data(plane)
        zdata, _, transv, offset = NumpyData(ZD, name="test",
                                             grid=datagrid).slice_data(plane)

        self.assertTrue(np.all(ydata == SLICEPOS))
        for x in range(GRIDSIZE):
            self.assertTrue(np.all(xdata[x, :] == x))
            self.assertTrue(np.all(zdata[:, x] == x))
示例#10
0
    def run(self, options):
        data_name = options.pop('data', None)
        output_name = options.pop('output-name', None)
        if data_name is None:
            data_items = self.ivm.data.keys()
        elif isinstance(data_name, six.string_types):
            data_items = [
                data_name,
            ]
            if output_name is None:
                output_name = "%s_stats" % data_name
        else:
            data_items = data_name
        data_items = [self.ivm.data[name] for name in data_items]
        if output_name is None:
            output_name = "stats"

        roi_name = options.pop('roi', None)
        roi = None
        if roi_name is not None:
            roi = self.ivm.rois[roi_name]

        slice_dir = options.pop('slice-dir', None)
        slice_pos = options.pop('slice-pos', 0)
        sl = None
        if slice_dir is not None:
            sl = OrthoSlice(self.ivm.main.grid, slice_dir, slice_pos)

        vol = options.pop('vol', None)

        no_extra = options.pop('no-extras', False)
        exact_median = options.pop('exact-median', False)

        self.model.clear()
        self.model.setVerticalHeaderItem(0, QtGui.QStandardItem("Mean"))
        self.model.setVerticalHeaderItem(1, QtGui.QStandardItem("Median"))
        self.model.setVerticalHeaderItem(2, QtGui.QStandardItem("STD"))
        self.model.setVerticalHeaderItem(3, QtGui.QStandardItem("Min"))
        self.model.setVerticalHeaderItem(4, QtGui.QStandardItem("Max"))

        col = 0
        for data in data_items:
            stats, roi_labels = self.get_summary_stats(
                data, roi, slice_loc=sl, vol=vol, exact_median=exact_median)
            for ii in range(len(stats['mean'])):
                self.model.setHorizontalHeaderItem(
                    col,
                    QtGui.QStandardItem("%s\n%s" %
                                        (data.name, roi_labels[ii])))
                self.model.setItem(0, col,
                                   QtGui.QStandardItem(sf(stats['mean'][ii])))
                self.model.setItem(
                    1, col, QtGui.QStandardItem(sf(stats['median'][ii])))
                self.model.setItem(2, col,
                                   QtGui.QStandardItem(sf(stats['std'][ii])))
                self.model.setItem(3, col,
                                   QtGui.QStandardItem(sf(stats['min'][ii])))
                self.model.setItem(4, col,
                                   QtGui.QStandardItem(sf(stats['max'][ii])))
                col += 1

        if not no_extra:
            self.ivm.add_extra(output_name,
                               table_to_extra(self.model, output_name))
示例#11
0
    def __init__(self, ivl, ivm, ax_map, ax_labels):
        """
        :param ivl: Viewer
        :param ivm: ImageVolumeManagement
        :param ax_map: Sequence defining the x, y, z axis of the slice viewer
                       in terms of RAS axis sequence indexes
        :param ax_labels: Sequence of labels for the RAS axes
        """
        LogSource.__init__(self)
        pg.GraphicsView.__init__(self)
        self._ivl = ivl
        self.ivm = ivm
        self.xaxis, self.yaxis, self.zaxis = ax_map
        self._slicez = 0
        self._vol = 0
        self._plane = OrthoSlice(self._ivl.grid, self.zaxis, self._slicez)
        self._main_view = None
        self._dragging = False
        self._arrow_items = []
        self._data_views = {}
        self.debug("axes=%i, %i, %i", self.xaxis, self.yaxis, self.zaxis)

        # View box to display graphics items
        self._viewbox = pg.ViewBox(name="view%i" % self.zaxis,
                                   border=pg.mkPen((0x6c, 0x6c, 0x6c),
                                                   width=2.0))
        self._viewbox.setAspectLocked(True)
        self._viewbox.setBackgroundColor([0, 0, 0])
        self._viewbox.enableAutoRange()
        self.setCentralItem(self._viewbox)

        # Crosshairs
        self._vline = pg.InfiniteLine(angle=90, movable=False)
        self._vline.setZValue(2 * MAX_NUM_DATA_SETS)
        self._vline.setPen(
            pg.mkPen((0, 255, 0), width=1.0, style=QtCore.Qt.DashLine))

        self._hline = pg.InfiniteLine(angle=0, movable=False)
        self._hline.setZValue(2 * MAX_NUM_DATA_SETS)
        self._hline.setPen(
            pg.mkPen((0, 255, 0), width=1.0, style=QtCore.Qt.DashLine))

        self._viewbox.addItem(self._vline, ignoreBounds=True)
        self._viewbox.addItem(self._hline, ignoreBounds=True)

        # Dummy image item which enables us to translate click co-ordinates
        # into image space co-ordinates even when there is no data in the view
        self._dummy = pg.ImageItem()
        self._dummy.setVisible(False)
        self._viewbox.addItem(self._dummy, ignoreBounds=True)

        # Static labels for the view directions
        self._labels = []
        for axis in [self.xaxis, self.yaxis]:
            self._labels.append(QtGui.QLabel(ax_labels[axis][0], parent=self))
            self._labels.append(QtGui.QLabel(ax_labels[axis][1], parent=self))
        for label in self._labels:
            label.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self._grid_changed(self._ivl.grid)
        self._focus_changed(self._ivl.focus())
        self._update_crosshairs()
        self._update_orientation()

        # Connect to signals from the parent viewer
        self._ivl.sig_grid_changed.connect(self._grid_changed)
        self._ivl.sig_focus_changed.connect(self._focus_changed)
        self._ivl.sig_arrows_changed.connect(self._arrows_changed)
        self._ivl.opts.sig_changed.connect(self._view_opts_changed)

        # Connect to data change signals
        self.ivm.sig_all_data.connect(self._data_changed)
        self.ivm.sig_main_data.connect(self._main_data_changed)

        # Need to intercept the default resize event
        # FIXME why can't call superclass method normally?
        self.resizeEventOrig = self.resizeEvent
        self.resizeEvent = self._window_resized