diff options
Diffstat (limited to 'silx/gui/plot/items/complex.py')
-rw-r--r-- | silx/gui/plot/items/complex.py | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/silx/gui/plot/items/complex.py b/silx/gui/plot/items/complex.py index 0e492a0..abb64ad 100644 --- a/silx/gui/plot/items/complex.py +++ b/silx/gui/plot/items/complex.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2017-2020 European Synchrotron Radiation Facility +# Copyright (c) 2017-2021 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -184,18 +184,18 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn): def setComplexMode(self, mode): changed = super(ImageComplexData, self).setComplexMode(mode) if changed: + self._valueDataChanged() + # Backward compatibility self._updated(ItemChangedType.VISUALIZATION_MODE) - # Send data updated as value returned by getData has changed - self._updated(ItemChangedType.DATA) - # Update ColormapMixIn colormap colormap = self._colormaps[self.getComplexMode()] if colormap is not super(ImageComplexData, self).getColormap(): super(ImageComplexData, self).setColormap(colormap) - self._setColormappedData(self.getData(copy=False), copy=False) + # Send data updated as value returned by getData has changed + self._updated(ItemChangedType.DATA) return changed def _setAmplitudeRangeInfo(self, max_=None, delta=2): @@ -263,10 +263,32 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn): 'Image is not complex, converting it to complex to plot it.') data = numpy.array(data, dtype=numpy.complex64) - self._dataByModesCache = {} - self._setColormappedData(self.getData(copy=False), copy=False) + # Compute current mode data and set colormap data + mode = self.getComplexMode() + dataForMode = self.__convertComplexData(data, self.getComplexMode()) + self._dataByModesCache = {mode: dataForMode} + super().setData(data) + def _updated(self, event=None, checkVisibility=True): + # Synchronizes colormapped data if changed + # ItemChangedType.COMPLEX_MODE triggers ItemChangedType.DATA + # No need to handle it twice. + if event in (ItemChangedType.DATA, ItemChangedType.MASK): + # Color-mapped data is NOT the `getValueData` for some modes + if self.getComplexMode() in ( + self.ComplexMode.AMPLITUDE_PHASE, + self.ComplexMode.LOG10_AMPLITUDE_PHASE): + data = self.getData(copy=False, mode=self.ComplexMode.PHASE) + mask = self.getMaskData(copy=False) + if mask is not None: + data = numpy.copy(data) + data[mask != 0] = numpy.nan + else: + data = self.getValueData(copy=False) + self._setColormappedData(data, copy=False) + super()._updated(event=event, checkVisibility=checkVisibility) + def getComplexData(self, copy=True): """Returns the image complex data @@ -276,6 +298,31 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn): """ return super().getData(copy=copy) + def __convertComplexData(self, data, mode): + """Convert complex data to given mode. + + :param numpy.ndarray data: + :param Union[ComplexMode,str] mode: + :rtype: numpy.ndarray of float + """ + if mode is self.ComplexMode.PHASE: + return numpy.angle(data) + elif mode is self.ComplexMode.REAL: + return numpy.real(data) + elif mode is self.ComplexMode.IMAGINARY: + return numpy.imag(data) + elif mode in (self.ComplexMode.ABSOLUTE, + self.ComplexMode.LOG10_AMPLITUDE_PHASE, + self.ComplexMode.AMPLITUDE_PHASE): + return numpy.absolute(data) + elif mode is self.ComplexMode.SQUARE_AMPLITUDE: + return numpy.absolute(data) ** 2 + else: + _logger.error( + 'Unsupported conversion mode: %s, fallback to absolute', + str(mode)) + return numpy.absolute(data) + def getData(self, copy=True, mode=None): """Returns the image data corresponding to (current) mode. @@ -295,27 +342,8 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn): mode = self.ComplexMode.from_value(mode) if mode not in self._dataByModesCache: - # Compute data for mode and store it in cache - complexData = self.getComplexData(copy=False) - if mode is self.ComplexMode.PHASE: - data = numpy.angle(complexData) - elif mode is self.ComplexMode.REAL: - data = numpy.real(complexData) - elif mode is self.ComplexMode.IMAGINARY: - data = numpy.imag(complexData) - elif mode in (self.ComplexMode.ABSOLUTE, - self.ComplexMode.LOG10_AMPLITUDE_PHASE, - self.ComplexMode.AMPLITUDE_PHASE): - data = numpy.absolute(complexData) - elif mode is self.ComplexMode.SQUARE_AMPLITUDE: - data = numpy.absolute(complexData) ** 2 - else: - _logger.error( - 'Unsupported conversion mode: %s, fallback to absolute', - str(mode)) - data = numpy.absolute(complexData) - - self._dataByModesCache[mode] = data + self._dataByModesCache[mode] = self.__convertComplexData( + self.getComplexData(copy=False), mode) return numpy.array(self._dataByModesCache[mode], copy=copy) |