コード例 #1
0
class PixelSpace(ImageView):
    def __init__(self, *args, **kwargs):
        # Add axes
        self.axesItem = PlotItem()
        self.axesItem.axes["left"]["item"].setZValue(10)
        self.axesItem.axes["top"]["item"].setZValue(10)
        if "view" not in kwargs:
            kwargs["view"] = self.axesItem

        self._transform = QTransform()
        self._raw_image = None

        super(PixelSpace, self).__init__(*args, **kwargs)

        self.imageItem.sigImageChanged.connect(self.updateAxes)

    def transform(self, img=None):
        # Build Quads
        shape = img.shape
        a = [(0, shape[-2] - 1), (shape[-1] - 1, shape[-2] - 1), (shape[-1] - 1, 0), (0, 0)]

        b = [(0, 1), (shape[-1] - 1, 1), (shape[-1] - 1, shape[-2]), (0, shape[-2])]

        quad1 = QPolygonF()
        quad2 = QPolygonF()
        for p, q in zip(a, b):
            quad1.append(QPointF(*p))
            quad2.append(QPointF(*q))

        transform = QTransform()
        QTransform.quadToQuad(quad1, quad2, transform)

        for item in self.view.items:
            if isinstance(item, ImageItem):
                item.setTransform(transform)
        self._transform = transform
        return img, transform

    def setImage(self, img, *args, **kwargs):
        if img is None:
            return

        if getattr(self, "displaymode", DisplayMode.raw) == DisplayMode.raw:
            self._raw_image = img

        if not kwargs.get("transform", None):
            img, transform = self.transform(img)
            self.updateAxes()
            super(PixelSpace, self).setImage(img, *args, transform=transform, **kwargs)

        else:
            super(PixelSpace, self).setImage(img, *args, **kwargs)

    def setTransform(self):
        self.setImage(self._raw_image)  # this should loop back around to the respective transforms

    def updateAxes(self):
        self.axesItem.setLabel("bottom", "x (px)")  # , units='s')
        self.axesItem.setLabel("left", "z (px)")
コード例 #2
0
class XArrayView(ImageView):
    def __init__(self, *args, **kwargs):
        # Add axes
        self.axesItem = PlotItem()
        self.axesItem.axes["left"]["item"].setZValue(10)
        self.axesItem.axes["top"]["item"].setZValue(10)

        if "view" not in kwargs:
            kwargs["view"] = self.axesItem

        super(XArrayView, self).__init__(*args, **kwargs)

        self.view.invertY(False)

    def setImage(self, img, **kwargs):

        if hasattr(img, 'coords'):

            if 'transform' not in kwargs:

                xvals = img.coords[img.dims[-2]]
                yvals = img.coords[img.dims[-1]]
                xmin = float(xvals.min())
                xmax = float(xvals.max())
                ymin = float(yvals.min())
                ymax = float(yvals.max())

                # Position the image according to coords
                shape = img.shape
                a = [(0, shape[-2]), (shape[-1] - 1, shape[-2]),
                     (shape[-1] - 1, 1), (0, 1)]

                b = [(ymin, xmin), (ymax, xmin), (ymax, xmax), (ymin, xmax)]

                quad1 = QPolygonF()
                quad2 = QPolygonF()
                for p, q in zip(a, b):
                    quad1.append(QPointF(*p))
                    quad2.append(QPointF(*q))

                transform = QTransform()
                QTransform.quadToQuad(quad1, quad2, transform)

                kwargs['transform'] = transform

            if 'xvals' not in kwargs:
                kwargs['xvals'] = np.asarray(img.coords[img.dims[0]])

            # Set the timeline axis label from dims
            self.ui.roiPlot.setLabel('bottom', img.dims[0])

            # Label the image axes
            self.axesItem.setLabel('left', img.dims[-2])
            self.axesItem.setLabel('bottom', img.dims[-1])

            # Add a bit more size
            self.ui.roiPlot.setMinimumSize(QSize(0, 70))

        # Bind coords from the xarray to the timeline axis
        super(XArrayView, self).setImage(img, **kwargs)

    def updateImage(self, autoHistogramRange=True):
        if hasattr(self.image, 'dims'):
            ## Redraw image on screen
            if self.image is None:
                return

            image = self.getProcessedImage()

            if autoHistogramRange:
                self.ui.histogram.setHistogramRange(self.levelMin,
                                                    self.levelMax)

            # Transpose image into order expected by ImageItem
            if self.imageItem.axisOrder == 'col-major':
                axorder = ['t', 'x', 'y', 'c']
            else:
                axorder = ['t', 'y', 'x', 'c']
            axorder = [
                self.axes[ax] for ax in axorder if self.axes[ax] is not None
            ]
            ax_swap = [image.dims[ax_index] for ax_index in axorder]
            image = image.transpose(*ax_swap)

            # Select time index
            if self.axes['t'] is not None:
                self.ui.roiPlot.show()
                image = image[self.currentIndex]

            self.imageItem.updateImage(np.asarray(image))

        else:
            super(XArrayView, self).updateImage(autoHistogramRange)

    def quickMinMax(self, data):
        """
        Estimate the min/max values of *data* by subsampling. MODIFIED TO USE THE 99TH PERCENTILE instead of max.
        """
        if data is None:
            return 0, 0

        sl = slice(None, None, max(1, int(data.size // 1e6)))
        data = np.asarray(data[sl])

        levels = (np.nanmin(data),
                  np.nanpercentile(
                      np.where(data < np.nanmax(data), data, np.nanmin(data)),
                      99))

        return [levels]
コード例 #3
0
class SAXSViewerPlugin(DynImageView, QWidgetPlugin):
    def __init__(self,
                 header: NonDBHeader = None,
                 field: str = 'primary',
                 toolbar: QToolBar = None,
                 *args,
                 **kwargs):

        # Add q axes
        self.axesItem = PlotItem()
        self.axesItem.setLabel('bottom', u'q (Å⁻¹)')  # , units='s')
        self.axesItem.setLabel('left', u'q (Å⁻¹)')
        self.axesItem.axes['left']['item'].setZValue(10)
        self.axesItem.axes['top']['item'].setZValue(10)
        if 'view' not in kwargs: kwargs['view'] = self.axesItem

        super(SAXSViewerPlugin, self).__init__(**kwargs)
        self.axesItem.invertY(False)

        # Setup axes reset button
        self.resetAxesBtn = QPushButton('Reset Axes')
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.resetAxesBtn.sizePolicy().hasHeightForWidth())
        self.resetAxesBtn.setSizePolicy(sizePolicy)
        self.resetAxesBtn.setObjectName("resetAxes")
        self.ui.gridLayout.addWidget(self.resetAxesBtn, 2, 1, 1, 1)
        self.resetAxesBtn.clicked.connect(self.autoRange)

        # Setup LUT reset button
        self.resetLUTBtn = QPushButton('Reset LUT')
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.resetLUTBtn.sizePolicy().hasHeightForWidth())
        # self.resetLUTBtn.setSizePolicy(sizePolicy)
        # self.resetLUTBtn.setObjectName("resetLUTBtn")
        self.ui.gridLayout.addWidget(self.resetLUTBtn, 3, 1, 1, 1)
        self.resetLUTBtn.clicked.connect(self.autoLevels)

        # Hide ROI button and rearrange
        self.ui.roiBtn.setParent(None)
        self.ui.gridLayout.addWidget(self.ui.menuBtn, 1, 1, 1, 1)
        self.ui.gridLayout.addWidget(self.ui.graphicsView, 0, 0, 3, 1)

        # Setup coordinates label
        self.coordinatesLbl = QLabel('--COORDINATES WILL GO HERE--')
        self.ui.gridLayout.addWidget(self.coordinatesLbl,
                                     3,
                                     0,
                                     1,
                                     1,
                                     alignment=Qt.AlignHCenter)

        # Setup mask layer
        self.maskimage = pg.ImageItem(opacity=.25)
        self.view.addItem(self.maskimage)

        # Setup calibration layer
        self.calibrantimage = pg.ImageItem(opacity=.25)
        self.view.addItem(self.calibrantimage)

        # Empty ROI for later use
        self.maskROI = pg.PolyLineROI([],
                                      closed=True,
                                      movable=False,
                                      pen=pg.mkPen(color='r', width=2))
        self.maskROI.handlePen = pg.mkPen(color='r', width=2)
        self.maskROI.handleSize = 10
        self.view.addItem(self.maskROI)

        # Connect toolbar handlers
        self.toolbar = toolbar
        if self.toolbar:
            self.toolbar.modegroup.triggered.connect(self.redraw)

        # Setup results cache
        self.results = []

        # Set header
        if header: self.setHeader(header, field)

    def setHeader(self, header: NonDBHeader, field: str, *args, **kwargs):
        self.header = header
        self.field = field
        # make lazy array from document
        data = None
        try:
            data = header.meta_array(field)
        except IndexError:
            msg.logMessage(
                'Header object contained no frames with field '
                '{field}'
                '.', msg.ERROR)

        if data:
            kwargs['transform'] = QTransform(0, -1, 1, 0, 0, data.shape[-2])
            super(SAXSViewerPlugin, self).setImage(img=data, *args, **kwargs)

    def setMaskImage(self, mask):
        if mask is not None:
            self.maskimage.setImage(mask,
                                    lut=np.array([[0, 0, 0, 0],
                                                  [255, 0, 0, 255]]))
            self.maskimage.setTransform(
                QTransform(0, -1, 1, 0, 0, mask.shape[-2]))
        else:
            self.maskimage.clear()

    def setCalibrantImage(self, data):
        if data is not None:
            self.calibrantimage.setImage(data, lut=calibrantlut)
            self.calibrantimage.setTransform(QTransform(0, 1, 1, 0, 0, 0))
        else:
            self.calibrantimage.clear()

    def redraw(self):
        if not self.parent().currentWidget() == self:
            return  # Don't redraw when not shown

        for result in self.results:
            try:
                if self.toolbar.cakeaction.isChecked():
                    self.setImage(result['cake'].value)
                    break
                elif self.toolbar.remeshaction.isChecked():
                    self.setImage(result['remesh'].value
                                  )  # TODO: add checkbox to toolbar
                    break
                elif 'inpaint' in result:
                    self.setImage(result['inpaint'].value)
                    break

            except TypeError:
                continue
        else:  # if self.toolbar.rawaction.isChecked():
            self.setHeader(self.header, self.field)

    def setResults(self, results):
        self.results = results
        self.redraw()
コード例 #4
0
class EFIViewerPlugin(Crosshair, QCoordinates, DynImageView, QWidgetPlugin):
    def __init__(self,
                 header: NonDBHeader = None,
                 field: str = 'primary',
                 toolbar: QToolBar = None,
                 *args,
                 **kwargs):

        # Add axes
        self.axesItem = PlotItem()
        # self.axesItem.setLabel('bottom', u'q ()')  # , units='s')
        # self.axesItem.setLabel('bottom', u'q ()')  # , units='s')
        # self.axesItem.setLabel('left', u'q ()')
        self.axesItem.axes['left']['item'].setZValue(10)
        self.axesItem.axes['top']['item'].setZValue(10)
        if 'view' not in kwargs: kwargs['view'] = self.axesItem

        super(EFIViewerPlugin, self).__init__(**kwargs)
        self.axesItem.invertY(True)

        # Setup axes reset button
        self.resetAxesBtn = QPushButton('Reset Axes')
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.resetAxesBtn.sizePolicy().hasHeightForWidth())
        self.resetAxesBtn.setSizePolicy(sizePolicy)
        self.resetAxesBtn.setObjectName("resetAxes")
        self.ui.gridLayout.addWidget(self.resetAxesBtn, 2, 1, 1, 1)
        self.resetAxesBtn.clicked.connect(self.autoRange)

        # Setup LUT reset button
        self.resetLUTBtn = QPushButton('Reset LUT')
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.resetLUTBtn.sizePolicy().hasHeightForWidth())
        # self.resetLUTBtn.setSizePolicy(sizePolicy)
        # self.resetLUTBtn.setObjectName("resetLUTBtn")
        self.ui.gridLayout.addWidget(self.resetLUTBtn, 3, 1, 1, 1)
        self.resetLUTBtn.clicked.connect(self.autoLevels)

        # Hide ROI button and rearrange
        # self.ui.roiBtn.setParent(None)
        # self.ui.gridLayout.addWidget(self.ui.menuBtn, 1, 1, 1, 1)
        # self.ui.gridLayout.addWidget(self.ui.graphicsView, 0, 0, 3, 1)

        # Setup coordinates label
        # self.coordinatesLbl = QLabel('--COORDINATES WILL GO HERE--')
        # self.ui.gridLayout.addWidget(self.coordinatesLbl, 3, 0, 1, 1, alignment=Qt.AlignHCenter)

        # Set header
        if header: self.setHeader(header, field)

    def setHeader(self, header: NonDBHeader, field: str, *args, **kwargs):
        self.header = header
        self.field = field
        # make lazy array from document
        data = None
        try:
            data = header.meta_array(field)
        except IndexError:
            msg.logMessage(
                f'Header object contained no frames with field {field}.',
                msg.ERROR)

        for ii in header:
            msg.logMessage('header types = '.format(type(ii)))

        if data:
            # data = np.squeeze(data) #test for 1D spectra
            if data.ndim > 1:
                # kwargs['transform'] = QTransform(0, -1, 1, 0, 0, data.shape[-2])
                # NOTE PAE: for setImage:
                #   use setImage(xVals=timeVals) to set the values on the slider for 3D data
                try:
                    # Retrieve the metadata for pixel scale and units
                    descriptorsTee = itertools.tee(
                        header.descriptors,
                        1)[0]  # tee the descriptors generator once
                    _ = next(descriptorsTee)  # start document
                    headerTitle, md = next(
                        descriptorsTee)  # descriptor document with metadata
                    scale0 = (md['PhysicalSizeX'], md['PhysicalSizeY'])
                    units0 = (md['PhysicalSizeXUnit'], md['PhysicalSizeYUnit'])
                except:
                    scale0 = (1, 1)
                    units0 = ('', '')
                    msg.logMessage(
                        'EFIviewer: No pixel size or units detected')
                super(EFIViewerPlugin, self).setImage(img=data,
                                                      scale=scale0,
                                                      *args,
                                                      **kwargs)
                self.axesItem.setLabel('bottom', text='X', units=units0[0])
                self.axesItem.setLabel('left', text='Y', units=units0[1])