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)
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()
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()
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])