Beispiel #1
0
class TestArrayCalibration(unittest.TestCase):
    def setUp(self):
        self.arr = numpy.array([45.2, 25.3, 666., -8.])
        self.calib = ArrayCalibration(self.arr)
        self.affine_calib = ArrayCalibration([0.1, 0.2, 0.3])

    def testIsAffine(self):
        self.assertFalse(self.calib.is_affine())
        self.assertTrue(self.affine_calib.is_affine())

    def testSlope(self):
        with self.assertRaises(AttributeError):
            self.calib.get_slope()
        self.assertEqual(self.affine_calib.get_slope(),
                         0.1)

    def testYIntercept(self):
        self.assertEqual(self.calib(0),
                         self.arr[0])

    def testCall(self):
        with self.assertRaises(ValueError):
            # X is an array with a different shape
            self.calib(X)

        with self.assertRaises(ValueError):
            # floats are not valid indices
            self.calib(3.14)

        self.assertTrue(
            numpy.array_equal(self.calib([1, 2, 3, 4]),
                              self.arr))

        for idx, value in enumerate(self.arr):
            self.assertEqual(self.calib(idx), value)
Beispiel #2
0
    def _updateImage(self):
        selection = self._selector.selection()
        auxSigIdx = self._auxSigSlider.value()

        legend = self.__signals_names[auxSigIdx]

        images = [img[selection] for img in self.__signals]
        image = images[auxSigIdx]

        x_axis = self.__x_axis
        y_axis = self.__y_axis

        if x_axis is None and y_axis is None:
            xcalib = NoCalibration()
            ycalib = NoCalibration()
        else:
            if x_axis is None:
                # no calibration
                x_axis = numpy.arange(image.shape[1])
            elif numpy.isscalar(x_axis) or len(x_axis) == 1:
                # constant axis
                x_axis = x_axis * numpy.ones((image.shape[1], ))
            elif len(x_axis) == 2:
                # linear calibration
                x_axis = x_axis[0] * numpy.arange(image.shape[1]) + x_axis[1]

            if y_axis is None:
                y_axis = numpy.arange(image.shape[0])
            elif numpy.isscalar(y_axis) or len(y_axis) == 1:
                y_axis = y_axis * numpy.ones((image.shape[0], ))
            elif len(y_axis) == 2:
                y_axis = y_axis[0] * numpy.arange(image.shape[0]) + y_axis[1]

            xcalib = ArrayCalibration(x_axis)
            ycalib = ArrayCalibration(y_axis)

        self._plot.remove(kind=(
            "scatter",
            "image",
        ))
        if xcalib.is_affine() and ycalib.is_affine():
            # regular image
            xorigin, xscale = xcalib(0), xcalib.get_slope()
            yorigin, yscale = ycalib(0), ycalib.get_slope()
            origin = (xorigin, yorigin)
            scale = (xscale, yscale)

            self._plot.addImage(image,
                                legend=legend,
                                origin=origin,
                                scale=scale)
        else:
            scatterx, scattery = numpy.meshgrid(x_axis, y_axis)
            # fixme: i don't think this can handle "irregular" RGBA images
            self._plot.addScatter(numpy.ravel(scatterx),
                                  numpy.ravel(scattery),
                                  numpy.ravel(image),
                                  legend=legend)

        title = ""
        if self.__title:
            title += self.__title
        if not title.strip().endswith(self.__signals_names[auxSigIdx]):
            title += "\n" + self.__signals_names[auxSigIdx]
        self._plot.setGraphTitle(title)
        self._plot.getXAxis().setLabel(self.__x_axis_name)
        self._plot.getYAxis().setLabel(self.__y_axis_name)
        self._plot.resetZoom()
Beispiel #3
0
    def addDataObject(self, dataObject, legend=None):
        if legend is None:
            legend = dataObject.info['legend']

        nItemsBefore = len(self.getSceneWidget().getItems())
        # we need to remove existing items with the same legend
        to_be_removed = []
        for it in self.getSceneWidget().getItems():
            if it.getLabel() == legend:
                to_be_removed.append(it)
        for _i in range(len(to_be_removed)):
            self.getSceneWidget().removeItem(to_be_removed.pop())

        if dataObject.m is None or dataObject.m == []:
            data = dataObject.y[0]
        else:
            # I would have to check for the presence of zeros in monitor
            data = dataObject.y[0] / dataObject.m[0]

        if dataObject.x is None:
            # note: this does not seem to be possible if data is sent from the main selector,
            #       at least 2 axs must be selected for the data to be sent to this widget
            if len(data.shape) == 3:
                item3d = self.getSceneWidget().add3DScalarField(data)
                item3d.addIsosurface(mean_isolevel, "blue")
                for cp in item3d.getCutPlanes():
                    cp.setColormap(Colormap(name="temperature"))
            elif len(data.shape) == 2:
                item3d = self.getSceneWidget().addImage(data)
                item3d.setColormap(Colormap(name="temperature"))
            else:
                raise NotImplementedError(
                    "case dataObject.x is None and ndim not in [2, 3]")
                # item3d = self.getSceneWidget().mesh(data)
            item3d.setLabel(legend)
            if (not nItemsBefore) or \
               (len(self.getSceneWidget().getItems()) == 1):
                self.getSceneWidget().centerScene()
            return

        ndata = numpy.prod(data.shape)

        xDimList = []
        for dataset in dataObject.x:
            xdim = numpy.prod(dataset.shape)
            xDimList.append(xdim)

        # case with one axis per signal dimension
        if len(dataObject.x) == len(data.shape) and \
                numpy.prod(xDimList) == ndata:
            for axis_dim, data_dim in zip(xDimList, data.shape):
                if axis_dim != data_dim:
                    text = "Dimensions mismatch: axes %s, data %s" % (
                        xDimList, data.shape)
                    raise ValueError(text)

            if len(data.shape) == 3:
                _logger.debug("CASE 1: 3D data with 3 axes")
                # 3D scalar field convention is ZYX
                zcal = ArrayCalibration(dataObject.x[0])
                ycal = ArrayCalibration(dataObject.x[1])
                xcal = ArrayCalibration(dataObject.x[2])

                item3d = self.getSceneWidget().add3DScalarField(data)
                scales = [1., 1., 1.]
                origins = [0., 0., 0.]
                for i, cal in enumerate((xcal, ycal, zcal)):
                    arr = cal.calibration_array
                    origins[i] = arr[0]
                    if not cal.is_affine() and len(arr) > 1:
                        _logger.warning("axis is not linear. "
                                        "deltaX will be estimated")
                        scales[i] = (arr[-1] - arr[0]) / (len(arr) - 1)
                    else:
                        scales[i] = cal.get_slope()
                        # todo: check != 0
                item3d.setScale(*scales)
                item3d.setTranslation(*origins)
                item3d.addIsosurface(mean_isolevel, "blue")
                for cp in item3d.getCutPlanes():
                    cp.setColormap(Colormap(name="temperature"))
            elif len(data.shape) == 2:
                _logger.debug("CASE 2: 2D data with 2 axes")
                ycal = ArrayCalibration(dataObject.x[0])
                xcal = ArrayCalibration(dataObject.x[1])

                item3d = self.getSceneWidget().addImage(data)
                origins = [xcal(0), ycal(0)]
                scales = [1., 1.]
                for i, cal in enumerate((xcal, ycal)):
                    arr = cal.calibration_array
                    if not cal.is_affine() and len(arr) > 1:
                        _logger.warning("axis is not linear. "
                                        "deltaX will be estimated")
                        scales[i] = (arr[-1] - arr[0]) / (
                            len(arr) - 1
                        )  # TODO: do a scatter instead with numpy.meshgrid
                    else:
                        scales[i] = cal.get_slope()
                item3d.setTranslation(*origins)
                item3d.setScale(*scales)
                item3d.setColormap(Colormap(name="temperature"))

            elif len(data.shape) == 1:
                _logger.debug("CASE 3: 1D scatter (x and values)")
                item3d = self.getSceneWidget().add3DScatter(
                    value=data,
                    x=dataObject.x[0],
                    y=numpy.zeros_like(data),
                    z=data)
                item3d.setColormap(Colormap(name="temperature"))
            else:
                # this case was ignored in the original code,
                # so it probably cannot happen
                raise TypeError("Could not understand data dimensionality")
            item3d.setLabel(legend)
            if (not nItemsBefore) or \
               (len(self.getSceneWidget().getItems()) == 1):
                self.getSceneWidget().centerScene()
            return
        elif len(data.shape) == 3 and len(xDimList) == 2:
            _logger.warning("Assuming last dimension")
            _logger.debug("CASE 1.1")
            if list(xDimList) != list(data.shape[0:1]):
                text = "Wrong dimensions:"
                text += " %dx%d != (%d, %d, %d)" % (
                    xDimList[0], xDimList[1], data.shape[0], data.shape[1],
                    data.shape[2])
                raise ValueError(text)
            item3d = self.getSceneWidget().add3DScalarField(data)
            zcal = ArrayCalibration(dataObject.x[0])
            ycal = ArrayCalibration(dataObject.x[1])
            scales = [1., 1., 1.]
            origins = [0., 0., 0.]
            for i, cal in enumerate((ycal, zcal)):
                arr = cal.calibration_array
                origins[i + 1] = arr[0]
                if not cal.is_affine() and len(arr) > 1:
                    _logger.warning("axis is not linear. "
                                    "deltaX will be estimated")
                    scales[i + 1] = (arr[-1] - arr[0]) / (len(arr) - 1)
                else:
                    scales[i + 1] = cal.get_slope()
            item3d.setScale(*scales)
            item3d.setTranslation(*origins)
            item3d.setLabel(legend)
            item3d.addIsosurface(mean_isolevel, "blue")
            for cp in item3d.getCutPlanes():
                cp.setColormap(Colormap(name="temperature"))
            if (not nItemsBefore) or \
               (len(self.getSceneWidget().getItems()) == 1):
                self.getSceneWidget().centerScene()
            return

        # I have to assume all the x are of 1 element or of as many elements as data
        axes = [
            numpy.zeros_like(data),
            numpy.zeros_like(data),
            numpy.zeros_like(data)
        ]
        # overwrite initialized axes, if provided
        for xdataCounter, xdata in enumerate(dataObject.x):
            assert xdataCounter <= 2, \
                "Wrong scatter dimensionality (more than 3 axes)"
            if numpy.prod(xdata.shape) == 1:
                axis = xdata * numpy.ones(ndata)
            else:
                axis = xdata
            axes[xdataCounter] = axis

        if len(dataObject.x) == 2:
            item3d = self.getSceneWidget().add2DScatter(x=axes[0],
                                                        y=axes[1],
                                                        value=data)
            item3d.setColormap(Colormap(name="temperature"))
            item3d.setVisualization("solid")
            # item3d.setHeightMap(True)
        else:
            # const_axes_indices = []
            # for i, axis in axes:
            #     if numpy.all(axis == axis[0]):
            #         const_axes_indices.append(i)
            # if len(const_axes_indices) == 1:
            #     item3d = self.getSceneWidget().add2DScatter(x=axes[0],  ????? TODO
            #                                                 y=axes[1],  ?????
            #                                                 value=data)
            #     # TODO: rotate adequately
            # else:
            item3d = self.getSceneWidget().add3DScatter(x=axes[0],
                                                        y=axes[1],
                                                        z=axes[2],
                                                        value=data)
            item3d.setColormap(Colormap(name="temperature"))
        item3d.setLabel(legend)
        if (not nItemsBefore) or \
           (len(self.getSceneWidget().getItems()) == 1):
            self.getSceneWidget().centerScene()
Beispiel #4
0
 def setUp(self):
     self.arr = numpy.array([45.2, 25.3, 666., -8.])
     self.calib = ArrayCalibration(self.arr)
     self.affine_calib = ArrayCalibration([0.1, 0.2, 0.3])