Beispiel #1
0
 def convert_to_log(self, incoming_image):
     self.transform_offset = 0.0
     transform_image = incoming_image
     image_min = incoming_image.min()
     if image_min <= 0.0:
         image_min = -1.0 * image_min
         self.transform_offset = 0.001 + image_min
         transform_image = self.transform_offset + incoming_image
     scale_min = transform_image.min()
     scale_max = transform_image.max()
     if scale_min == scale_max:
         scale_min = scale_min - 0.5 * scale_min
         scale_max = scale_max + 0.5 * scale_min
     self.dimap = ImageScaler(1, 256, scale_min, scale_max, True)
     _dprint(3, 'doing log transform of ', transform_image)
     temp_image = self.dimap.iTransform(transform_image)
     _dprint(3, 'log transformed image ', temp_image)
     return temp_image
 def convert_to_log(self, incoming_image):
   self.transform_offset = 0.0
   transform_image = incoming_image
   image_min = incoming_image.min()
   if image_min <= 0.0:
     image_min = -1.0 * image_min
     self.transform_offset = 0.001 + image_min
     transform_image = self.transform_offset + incoming_image
   scale_min = transform_image.min()
   scale_max = transform_image.max()
   if scale_min == scale_max:
    scale_min = scale_min - 0.5 * scale_min
    scale_max = scale_max + 0.5 * scale_min
   self.dimap = ImageScaler(1, 256, scale_min, scale_max, True)
   _dprint(3, 'doing log transform of ', transform_image)
   temp_image = self.dimap.iTransform(transform_image)
   _dprint(3, 'log transformed image ', temp_image)
   return temp_image
    def setData(self, data_array, xScale = None, yScale = None):
        '*** setting data **** '
        self.complex = False
        shape = data_array.shape
        _dprint(3, 'array shape is ', shape)
        shape0 = shape[0]
        if data_array.dtype == numpy.complex64 or data_array.dtype == numpy.complex128:
          self.complex = True
          shape0 = 2 * shape[0]
        if xScale:
            self.xMap = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            self.xMap_draw = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            temp_scale = (xScale[0],xScale[1])
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, *temp_scale)
            _dprint(3, 'xScale is ', xScale)
        else:
            self.xMap = ImageScaler(0, shape0, 0, shape0 )
            self.xMap_draw = ImageScaler(0, shape0, 0, shape0 )
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, shape0)
        if yScale:
            _dprint(3, 'yScale is ', yScale)
            _dprint(3, 'self.log_y_scale is ', self.log_y_scale)

            self.yMap = ImageScaler(0, shape[1]-1, yScale[0], yScale[1],self.log_y_scale)
            self.yMap_draw = ImageScaler(0, shape[1]-1, yScale[0], yScale[1],self.log_y_scale)
            temp_scale = (yScale[0],yScale[1])
            _dprint(3, 'Called setAxisScale(Qwt.QwtPlot.yLeft) with ', temp_scale)
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, *temp_scale)
        else:
            self.yMap = ImageScaler(0, shape[1], 0, shape[1])
            self.yMap_draw = ImageScaler(0, shape[1], 0, shape[1])
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, shape[1])
        if self.display_type == "brentjens":
          self.setBrentjensImage(data_array)
        else:
          self.setImage(data_array)
        self.raw_image = data_array
Beispiel #4
0
    def setData(self, data_array, xScale=None, yScale=None):
        '*** setting data **** '
        self.complex = False
        shape = data_array.shape
        _dprint(3, 'array shape is ', shape)
        shape0 = shape[0]
        if data_array.dtype == numpy.complex64 or data_array.dtype == numpy.complex128:
            self.complex = True
            shape0 = 2 * shape[0]
        if xScale:
            self.xMap = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            self.xMap_draw = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            temp_scale = (xScale[0], xScale[1])
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, *temp_scale)
            _dprint(3, 'xScale is ', xScale)
        else:
            self.xMap = ImageScaler(0, shape0, 0, shape0)
            self.xMap_draw = ImageScaler(0, shape0, 0, shape0)
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, shape0)
        if yScale:
            _dprint(3, 'yScale is ', yScale)
            _dprint(3, 'self.log_y_scale is ', self.log_y_scale)

            self.yMap = ImageScaler(0, shape[1] - 1, yScale[0], yScale[1],
                                    self.log_y_scale)
            self.yMap_draw = ImageScaler(0, shape[1] - 1, yScale[0], yScale[1],
                                         self.log_y_scale)
            temp_scale = (yScale[0], yScale[1])
            _dprint(3, 'Called setAxisScale(Qwt.QwtPlot.yLeft) with ',
                    temp_scale)
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, *temp_scale)
        else:
            self.yMap = ImageScaler(0, shape[1], 0, shape[1])
            self.yMap_draw = ImageScaler(0, shape[1], 0, shape[1])
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, shape[1])
        if self.display_type == "brentjens":
            self.setBrentjensImage(data_array)
        else:
            self.setImage(data_array)
        self.raw_image = data_array
Beispiel #5
0
class QwtPlotImage(Qwt.QwtPlotItem):
    def __init__(self, parent, title=Qwt.QwtText()):
        Qwt.QwtPlotItem.__init__(self)
        self.plot = parent
        self.display_type = "hippo"
        self.ValueAxis = None
        self.ComplexColorMap = None
        self._flags_array = None
        self._nan_flags_array = None
        self._image_for_display = None
        self._display_flags = False
        self.Qimage = None
        self.r_cmax = None
        self.r_cmin = None
        self.i_cmax = None
        self.i_cmin = None
        self.raw_image = None
        self.dimap = None
        self.complex = False
        self.log_scale = False
        self.log_y_scale = False
        self.transform_offset = 0.0
        self.flag_colour = 0
        self.nan_colour = 255
        self.lock_image_real = False
        self.lock_image_imag = False
        if not isinstance(title, Qwt.QwtText):
            self.title = Qwt.QwtText(str(title))
        else:
            self.title = title
        self.setItemAttribute(Qwt.QwtPlotItem.Legend)

    # __init__()

    def updateLegend(self, legend):
        Qwt.QwtPlotItem.updateLegend(self, legend)
        legend.find(self).setText(self.title)

    def setDisplayType(self, display_type):
        self.display_type = display_type
        #     _dprint(2,'display type set to ', self.display_type);
        if self.display_type == "brentjens" and self.ValueAxis == None:
            self.ValueAxis = UVPAxis()
            self.ComplexColorMap = ComplexColorMap(256)

    # setDisplayType

    def setFlagColour(self, flag_colour):
        self.flag_colour = flag_colour

    def setLockImage(self, real=True, lock_image=False):
        if real:
            self.lock_image_real = lock_image
        else:
            self.lock_image_imag = lock_image

    # When set to True, the log_scale parameter will cause
    # the displayed image to be scaled logarithmically.
    def setLogScale(self, log_scale=True):
        self.log_scale = log_scale
        if self.log_scale == False:
            self.dimap = None
            self.transform_offset = 0.0

    # When set to True, the log_y_scale parameter will cause
    # the output Y coordinate axis to be scaled properly for a Log plot
    # (used by QwtColorBar.py)
    def setLogYScale(self, log_y_scale=True):
        self.log_y_scale = log_y_scale

    def setFlagsArray(self, flags_array):
        self._flags_array = flags_array

    def setNanFlagsArray(self, flags_array):
        self._nan_flags_array = flags_array

    def setDisplayFlag(self, display_flags):
        self._display_flags = display_flags

    # setDisplayFlag

    def removeFlags(self):
        self._flags_array = None
        self._nan_flags_array = None

    # removeFlags

    def getRealImageRange(self):
        try:
            if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
                real_array = self.raw_image.real
            else:
                real_array = self.raw_image
            return (self.r_cmin, self.r_cmax, real_array.min(),
                    real_array.max())
        except:
            return (self.r_cmin, self.r_cmax, None, None)

    # getRealImageRange

    def getImagImageRange(self):
        try:
            if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
                imag_array = self.raw_image.imag
            return (self.i_cmin, self.i_cmax, imag_array.min(),
                    imag_array.max())
        except:
            return (self.i_cmin, self.i_cmax, None, None)

    # getRealImageRange

    def defineImageRange(self, limits, real=True):
        min = limits[0]
        max = limits[1]
        if abs(max - min) < 0.00005:
            if max == 0.0 or min == 0.0:
                min = -0.1
                max = 0.1
            else:
                min = 0.9 * min
                max = 1.1 * max
        if min > max:
            temp = max
            max = min
            min = temp
        if real:
            if not self.lock_image_real:
                self.r_cmin = min
                self.r_cmax = max
        else:
            if not self.lock_image_imag:
                self.i_cmin = min
                self.i_cmax = max

    def setImageRange(self, image):
        self.raw_image = image
        if image.dtype == numpy.complex64 or image.dtype == numpy.complex128:
            self.complex = True
            imag_array = image.imag
            real_array = image.real
            try:
                min = real_array.min()
                max = real_array.max()
            except:
                min = 0.0
                max = 0.0
            if abs(max - min) < 0.00005:
                if max == 0.0 or min == 0.0:
                    min = -0.1
                    max = 0.1
                else:
                    min = 0.9 * min
                    max = 1.1 * max
            if min > max:
                temp = max
                max = min
                min = temp
            if not self.lock_image_real:
                self.r_cmin = min
                self.r_cmax = max

            try:
                min = imag_array.min()
                max = imag_array.max()
            except:
                min = 0.0
                max = 0.0
            if abs(max - min) < 0.00005:
                if max == 0.0 or min == 0.0:
                    min = -0.1
                    max = 0.1
                else:
                    min = 0.9 * min
                    max = 1.1 * max
            if min > max:
                temp = max
                max = min
                min = temp
            if not self.lock_image_imag:
                self.i_cmin = min
                self.i_cmax = max
        else:
            self.complex = False
            try:
                min = image.min()
                max = image.max()
            except:
                min = 0.0
                max = 0.0
            if abs(max - min) < 0.00005:
                if max == 0.0 or min == 0.0:
                    min = -0.1
                    max = 0.1
                else:
                    min = 0.9 * min
                    max = 1.1 * max
            if min > max:
                temp = max
                max = min
                min = temp
            if not self.lock_image_real:
                self.r_cmin = min
                self.r_cmax = max

    # setImageRange

    def updateImage(self, image):
        self.setImage(image)
        self.raw_image = image

    def setFlaggedImageRange(self):
        (nx, ny) = self.raw_image.shape
        num_elements = nx * ny
        if self._flags_array is None:
            if not self._nan_flags_array is None:
                flags_array = self._nan_flags_array.copy()
            else:
                flags_array = numpy.zeros((nx, ny), int)
        else:
            flags_array = self._flags_array.copy()
            if not self._nan_flags_array is None:
                flags_array = flags_array + self._nan_flags_array
        flattened_flags = numpy.reshape(flags_array, (num_elements, ))
        if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
            real_array = self.raw_image.real
            imag_array = self.raw_image.imag
            flattened_real_array = numpy.reshape(real_array.copy(),
                                                 (num_elements, ))
            flattened_imag_array = numpy.reshape(imag_array.copy(),
                                                 (num_elements, ))
            real_flagged_array = numpy.compress(flattened_flags == 0,
                                                flattened_real_array)
            imag_flagged_array = numpy.compress(flattened_flags == 0,
                                                flattened_imag_array)
            flagged_image = numpy.zeros(shape=real_flagged_array.shape,
                                        dtype=self.raw_image.dtype)
            flagged_image.real = real_flagged_array
            flagged_image.imag = imag_flagged_array
        else:
            flattened_array = numpy.reshape(self.raw_image.copy(),
                                            (num_elements, ))
            flagged_image = numpy.compress(flattened_flags == 0,
                                           flattened_array)
        self.setImageRange(flagged_image)

    # setFlaggedImageRange

    def convert_to_log(self, incoming_image):
        self.transform_offset = 0.0
        transform_image = incoming_image
        image_min = incoming_image.min()
        if image_min <= 0.0:
            image_min = -1.0 * image_min
            self.transform_offset = 0.001 + image_min
            transform_image = self.transform_offset + incoming_image
        scale_min = transform_image.min()
        scale_max = transform_image.max()
        if scale_min == scale_max:
            scale_min = scale_min - 0.5 * scale_min
            scale_max = scale_max + 0.5 * scale_min
        self.dimap = ImageScaler(1, 256, scale_min, scale_max, True)
        _dprint(3, 'doing log transform of ', transform_image)
        temp_image = self.dimap.iTransform(transform_image)
        _dprint(3, 'log transformed image ', temp_image)
        return temp_image

    def getTransformOffset(self):
        return self.transform_offset

    def convert_limits(self, limits):
        if not self.dimap is None:
            first_limit = self.dimap.transform(self.transform_offset +
                                               limits[0])
            second_limit = self.dimap.transform(self.transform_offset +
                                                limits[1])
        else:
            first_limit = None
            second_limit = None
        return [first_limit, second_limit]

    def to_QImage(self, image):
        # convert to 8 bit image
        image_for_display = None
        if image.dtype == numpy.complex64 or image.dtype == numpy.complex128:
            self.complex = True
            real_array = image.real
            if self.log_scale:
                temp_array = self.convert_to_log(real_array)
                temp_array = self.convert_to_log(real_array)
                if not self.r_cmin is None and not self.r_cmax is None:
                    limits = self.convert_limits([self.r_cmin, self.r_cmax])
                else:
                    limits = [self.r_cmin, self.r_cmax]
                byte_image = bytescale(temp_array, limits)
            else:
                limits = [self.r_cmin, self.r_cmax]
                byte_image = bytescale(real_array, limits)
            (nx, ny) = real_array.shape
            image_for_display = numpy.empty(shape=(nx * 2, ny),
                                            dtype=byte_image.dtype)
            image_for_display[:nx, :] = byte_image
            imag_array = image.imag
            if self.log_scale:
                temp_array = self.convert_to_log(imag_array)
                if not self.i_cmin is None and not self.i_cmax is None:
                    limits = self.convert_limits([self.i_cmin, self.i_cmax])
                else:
                    limits = [self.i_cmin, self.i_cmax]
                byte_image = bytescale(temp_array, limits)
            else:
                limits = [self.i_cmin, self.i_cmax]
                byte_image = bytescale(imag_array, limits)
            image_for_display[nx:, :] = byte_image
        else:
            if self.log_scale:
                temp_array = self.convert_to_log(image)
                if not self.r_cmin is None and not self.r_cmax is None:
                    limits = self.convert_limits([self.r_cmin, self.r_cmax])
                else:
                    limits = [self.r_cmin, self.r_cmax]
                #print 'to_QImage log limits = ', limits
                image_for_display = bytescale(temp_array, limits)
            else:
                limits = [self.r_cmin, self.r_cmax]
                #print 'to_QImage real limits = ', limits
                image_for_display = bytescale(image, limits)
        # turn image into a QImage, and return result
        if not self._nan_flags_array is None:
            if self.complex:
                image_for_display[:nx, :] = numpy.where(
                    self._nan_flags_array, 1, image_for_display[:nx, :])
                image_for_display[nx:, :] = numpy.where(
                    self._nan_flags_array, 1, image_for_display[nx:, :])
            else:
                image_for_display = numpy.where(self._nan_flags_array, 1,
                                                image_for_display)
        self._image_for_display = image_for_display
        #     result = Qwt.toQImage(image_for_display).mirrored(0, 1)
        result = convertToQImage(image_for_display, True).mirrored(0, 1)
        # always suppress NaNs
        if not self._nan_flags_array is None:
            result.setColor(
                1, Qt.qRgb(self.nan_colour, self.nan_colour, self.nan_colour))
        return result

    def toGrayScale(self, Qimage):
        for i in range(0, 256):
            Qimage.setColor(i, Qt.qRgb(i, i, i))

    def toHippo(self, Qimage):
        dv = 255.0
        vmin = 1.0
        for i in range(2, 256):
            r = 1.0
            g = 1.0
            b = 1.0
            v = 1.0 * i
            if (v < (vmin + 0.25 * dv)):
                r = 0
                if dv != 0:
                    g = 4 * (v - vmin) / dv
            elif (v < (vmin + 0.5 * dv)):
                r = 0
                if dv != 0:
                    b = 1 + 4 * (vmin + 0.25 * dv - v) / dv
            elif (v < (vmin + 0.75 * dv)):
                b = 0
                if dv != 0:
                    r = 4 * (v - vmin - 0.5 * dv) / dv
            else:
                b = 0
                if dv != 0:
                    g = 1 + 4 * (vmin + 0.75 * dv - v) / dv
                else:
                    r = 0
            red = int(r * 255.)
            green = int(g * 255.)
            blue = int(b * 255.)
            # the following call will use the previous computations to
            # set up a hippo-like color display
            Qimage.setColor(i, Qt.qRgb(red, green, blue))

    def setImage(self, image):
        # convert to QImage
        self.Qimage = self.to_QImage(image)
        # set color scale a la HippoDraw Scale
        if self.display_type == "hippo":
            self.toHippo(self.Qimage)

# set color scale to Grayscale
        if self.display_type == "grayscale":
            self.toGrayScale(self.Qimage)

# compute flagged image if required
        if not self._flags_array is None or not self._nan_flags_array is None:
            self.setFlagQimage()

    def setFlagQimage(self):
        (nx, ny) = self._image_for_display.shape
        image_for_display = self._image_for_display.copy()
        if not self._flags_array is None:
            if self.complex:
                image_for_display[:nx / 2, :] = numpy.where(
                    self._flags_array, 0, self._image_for_display[:nx / 2, :])
                image_for_display[nx / 2:, :] = numpy.where(
                    self._flags_array, 0, self._image_for_display[nx / 2:, :])
            else:
                image_for_display = numpy.where(self._flags_array, 0,
                                                self._image_for_display)

        if not self._nan_flags_array is None:
            if self.complex:
                image_for_display[:nx / 2, :] = numpy.where(
                    self._nan_flags_array, 1, image_for_display[:nx / 2, :])
                image_for_display[nx / 2:, :] = numpy.where(
                    self._nan_flags_array, 1, image_for_display[nx / 2:, :])
            else:
                image_for_display = numpy.where(self._nan_flags_array, 1,
                                                image_for_display)

#     self.flags_Qimage = Qwt.toQImage(image_for_display).mirrored(0, 1)
        self.flags_Qimage = convertToQImage(image_for_display,
                                            True).mirrored(0, 1)

        # set color scale a la HippoDraw Scale
        if self.display_type == "hippo":
            self.toHippo(self.flags_Qimage)

# set color scale to Grayscale
        if self.display_type == "grayscale":
            self.toGrayScale(self.flags_Qimage)

# set zero to black to display flag image pixels in black
        self.flags_Qimage.setColor(
            0, Qt.qRgb(self.flag_colour, self.flag_colour, self.flag_colour))
        self.flags_Qimage.setColor(
            1, Qt.qRgb(self.nan_colour, self.nan_colour, self.nan_colour))

    def setBrentjensImage(self, image):
        absmin = abs(image.min())
        MaxAbs = abs(image.max())
        if (absmin > MaxAbs):
            MaxAbs = absmin
        self.ValueAxis.calcTransferFunction(
            -MaxAbs, MaxAbs, 0,
            self.ComplexColorMap.getNumberOfColors() - 1)

        if image.min() != image.max():
            # get real and imaginary arrays
            real_image = image.real
            imag_image = image.imag
            shape = image.shape
            Ncol = self.ComplexColorMap.getNumberOfColors()
            bits_per_pixel = 32
            self.Qimage = QImage(shape[0], shape[1], bits_per_pixel, Ncol)
            for i in range(shape[0]):
                for j in range(shape[1]):
                    colre = int(self.ValueAxis.worldToAxis(real_image[i, j]))
                    colim = int(self.ValueAxis.worldToAxis(imag_image[i, j]))
                    if (colre < Ncol and colim < Ncol):
                        value = self.ComplexColorMap.get_color_value(
                            colre, colim)
                        self.Qimage.setPixel(i, j, value)
                    else:
                        _dprint(2, "*************************************")
                        _dprint(2, "colre: ", colre)
                        _dprint(2, "colim: ", colim)
                        _dprint(2, "real : ", real_image[i, j])
                        _dprint(2, "imag : ", imag_image[i, j])
                        _dprint(2, "Ncol: ", Ncol)
                        _dprint(2, "*************************************")
            self.Qimage.mirror(0, 1)

    def setData(self, data_array, xScale=None, yScale=None):
        '*** setting data **** '
        self.complex = False
        shape = data_array.shape
        _dprint(3, 'array shape is ', shape)
        shape0 = shape[0]
        if data_array.dtype == numpy.complex64 or data_array.dtype == numpy.complex128:
            self.complex = True
            shape0 = 2 * shape[0]
        if xScale:
            self.xMap = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            self.xMap_draw = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            temp_scale = (xScale[0], xScale[1])
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, *temp_scale)
            _dprint(3, 'xScale is ', xScale)
        else:
            self.xMap = ImageScaler(0, shape0, 0, shape0)
            self.xMap_draw = ImageScaler(0, shape0, 0, shape0)
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, shape0)
        if yScale:
            _dprint(3, 'yScale is ', yScale)
            _dprint(3, 'self.log_y_scale is ', self.log_y_scale)

            self.yMap = ImageScaler(0, shape[1] - 1, yScale[0], yScale[1],
                                    self.log_y_scale)
            self.yMap_draw = ImageScaler(0, shape[1] - 1, yScale[0], yScale[1],
                                         self.log_y_scale)
            temp_scale = (yScale[0], yScale[1])
            _dprint(3, 'Called setAxisScale(Qwt.QwtPlot.yLeft) with ',
                    temp_scale)
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, *temp_scale)
        else:
            self.yMap = ImageScaler(0, shape[1], 0, shape[1])
            self.yMap_draw = ImageScaler(0, shape[1], 0, shape[1])
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, shape[1])
        if self.display_type == "brentjens":
            self.setBrentjensImage(data_array)
        else:
            self.setImage(data_array)
        self.raw_image = data_array

    # setData()

    def update_yMap_draw(self, d1, d2):
        self.yMap_draw.setDblRange(d1, d2, self.log_y_scale)

    def update_xMap_draw(self, d1, d2):
        self.xMap_draw.setDblRange(d1, d2, self.log_y_scale)

    def get_xMap_draw_coords(self):
        return (self.xMap_draw.d1(), self.xMap_draw.d2())

    def get_yMap_draw_coords(self):
        return (self.yMap_draw.d1(), self.yMap_draw.d2())

    def draw(self, painter, xMap, yMap, rect):
        """Paint image to zooming to xMap, yMap

        Calculate (x1, y1, x2, y2) so that it contains at least 1 pixel,
        and copy the visible region to scale it to the canvas.

        NOTE: we ignore the system-provided Maps and use our own 
        'draw' maps
        """
        if self.Qimage is None:
            return

        _dprint(3, 'incoming x map ranges ', xMap.s1(), ' ', xMap.s2())
        _dprint(3, 'incoming y map ranges ', yMap.s1(), ' ', yMap.s2())
        #       print 'incoming x map ranges ',xMap.s1(), ' ', xMap.s2()
        #       print 'incoming y map ranges ',yMap.s1(), ' ', yMap.s2()
        #       print 'incoming x map draw ranges ',self.xMap_draw.d1(), ' ', self.xMap_draw.d2()
        #       print 'incoming y map draw ranges ',self.yMap_draw.d1(), ' ', self.yMap_draw.d2()
        #       print 'incoming self x map ranges ',self.xMap.d1(), ' ', self.xMap.d2()
        #       print 'incoming self y map ranges ',self.yMap.d1(), ' ', self.yMap.d2()

        # calculate y1, y2
        y1 = y2 = self.Qimage.height()
        _dprint(3, 'image height ', self.Qimage.height())
        #        y1 = y2 = self.Qimage.height() - 1
        #       print 'starting image height ', y1
        y1 *= (self.yMap.d2() - self.yMap_draw.d2())
        y1 /= (self.yMap.d2() - self.yMap.d1())
        #       y1 = max(0, int(y1-0.5))
        y1 = max(0, (y1 - 0.5))
        _dprint(3, 'float y1 ', y1)
        y1 = int(y1 + 0.5)
        y2 *= (self.yMap.d2() - self.yMap_draw.d1())
        y2 /= (self.yMap.d2() - self.yMap.d1())
        _dprint(3, 'float y2 ', y2)
        #       y2 = min(self.Qimage.height(), int(y2+0.5))
        y2 = min(self.Qimage.height(), (y2 + 0.5))
        y2 = int(y2)
        _dprint(3, 'int y1, y2 ', y1, ' ', y2)
        # calculate x1, x2 - these are OK
        x1 = x2 = self.Qimage.width()
        #       print 'starting image width ', x1
        x1 *= (xMap.s1() - self.xMap.d1())
        x1 /= (self.xMap.d2() - self.xMap.d1())
        _dprint(3, 'float x1 ', x1)
        #       x1 = max(0, int(x1-0.5))
        x1 = max(0, int(x1))
        x2 *= (self.xMap_draw.d2() - self.xMap.d1())
        x2 /= (self.xMap.d2() - self.xMap.d1())
        _dprint(3, 'float x2 ', x2)
        x2 = min(self.Qimage.width(), int(x2 + 0.5))
        _dprint(3, 'int x1, x2 ', x1, ' ', x2)
        # copy
        xdelta = x2 - x1
        ydelta = y2 - y1
        #       print 'xdelta ydelta ', xdelta, ' ', ydelta
        #       print 'x1 y1 ', x1, ' ', y1
        # these tests seem necessary for the dummy 'scalar' displays
        if xdelta < 0:
            xdelta = self.Qimage.height()
        if ydelta < 0:
            ydelta = self.Qimage.height()
        image = None
        if self._display_flags:
            image = self.flags_Qimage.copy(x1, y1, xdelta, ydelta)
        else:
            image = self.Qimage.copy(x1, y1, xdelta, ydelta)
        # zoom
        image = image.scaled(xMap.p2() - xMap.p1() + 1,
                             yMap.p1() - yMap.p2() + 1)
        # draw
        painter.drawImage(xMap.p1(), yMap.p2(), image)
class QwtPlotImage(Qwt.QwtPlotItem):

    def __init__(self, parent, title = Qwt.QwtText()):
        Qwt.QwtPlotItem.__init__(self)
        self.plot = parent
        self.display_type = "hippo"
        self.ValueAxis =  None
        self.ComplexColorMap = None
        self._flags_array = None
        self._nan_flags_array = None
        self._image_for_display = None
	self._display_flags = False
        self.Qimage = None
        self.r_cmax = None
        self.r_cmin = None
        self.i_cmax = None
        self.i_cmin = None
        self.raw_image = None
        self.dimap = None
        self.complex = False
        self.log_scale = False
        self.log_y_scale = False
        self.transform_offset = 0.0
        self.flag_colour = 0
        self.nan_colour = 255
        self.lock_image_real = False
        self.lock_image_imag = False
        if not isinstance(title, Qwt.QwtText):
          self.title = Qwt.QwtText(str(title))
        else:
          self.title = title
        self.setItemAttribute(Qwt.QwtPlotItem.Legend);
    # __init__()
    
    def updateLegend(self, legend):
        Qwt.QwtPlotItem.updateLegend(self, legend)
        legend.find(self).setText(self.title)

    def setDisplayType(self, display_type):
      self.display_type = display_type
#     _dprint(2,'display type set to ', self.display_type);
      if self.display_type == "brentjens" and self.ValueAxis == None:
        self.ValueAxis =  UVPAxis()
        self.ComplexColorMap = ComplexColorMap(256)
    # setDisplayType

    def setFlagColour(self, flag_colour):
      self.flag_colour = flag_colour

    def setLockImage(self, real = True, lock_image=False):
      if real:
        self.lock_image_real = lock_image
      else:
        self.lock_image_imag = lock_image

    # When set to True, the log_scale parameter will cause
    # the displayed image to be scaled logarithmically.
    def setLogScale(self, log_scale = True):
      self.log_scale = log_scale
      if self.log_scale == False:
        self.dimap = None
        self.transform_offset = 0.0

    # When set to True, the log_y_scale parameter will cause
    # the output Y coordinate axis to be scaled properly for a Log plot
    # (used by QwtColorBar.py)
    def setLogYScale(self, log_y_scale = True):
      self.log_y_scale = log_y_scale

    def setFlagsArray(self, flags_array):
      self._flags_array = flags_array
      
    def setNanFlagsArray(self, flags_array):
      self._nan_flags_array = flags_array

    def setDisplayFlag(self, display_flags):
        self._display_flags = display_flags
    # setDisplayFlag

    def removeFlags(self):
      self._flags_array = None
      self._nan_flags_array = None
    # removeFlags

    def getRealImageRange(self):
      try:
        if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
          real_array =  self.raw_image.real
        else:
          real_array = self.raw_image
        return (self.r_cmin, self.r_cmax, real_array.min(),real_array.max())
      except:
        return (self.r_cmin, self.r_cmax, None, None)
    # getRealImageRange

    def getImagImageRange(self):
      try:
        if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
          imag_array =  self.raw_image.imag
        return (self.i_cmin, self.i_cmax,imag_array.min(), imag_array.max())
      except:
        return (self.i_cmin, self.i_cmax, None, None)
    # getRealImageRange


    
    def defineImageRange(self, limits, real=True):
       min = limits[0]
       max = limits[1]
       if abs(max - min) < 0.00005:
         if max == 0.0 or min == 0.0:
           min = -0.1
           max = 0.1
         else:
           min = 0.9 * min
           max = 1.1 * max
       if min > max:
         temp = max
         max = min
         min = temp
       if real:
         if not self.lock_image_real:
           self.r_cmin = min
           self.r_cmax = max
       else:
         if not self.lock_image_imag:
           self.i_cmin = min
           self.i_cmax = max

    def setImageRange(self, image):
      self.raw_image = image
      if image.dtype == numpy.complex64 or image.dtype == numpy.complex128:
        self.complex = True
        imag_array =  image.imag
        real_array =  image.real
        try:
          min = real_array.min()
          max = real_array.max()
        except:
          min = 0.0
          max = 0.0
        if abs(max - min) < 0.00005:
          if max == 0.0 or min == 0.0:
            min = -0.1
            max = 0.1
          else:
            min = 0.9 * min
            max = 1.1 * max
        if min > max:
          temp = max
          max = min
          min = temp
        if not self.lock_image_real:
          self.r_cmin = min
          self.r_cmax = max

        try:
          min = imag_array.min()
          max = imag_array.max()
        except:
          min = 0.0
          max = 0.0
        if abs(max - min) < 0.00005:
          if max == 0.0 or min == 0.0:
            min = -0.1
            max = 0.1
          else:
            min = 0.9 * min
            max = 1.1 * max
        if min > max:
          temp = max
          max = min
          min = temp
        if not self.lock_image_imag:
          self.i_cmin = min
          self.i_cmax = max
      else:
        self.complex = False
        try:
          min = image.min()
          max = image.max()
        except:
          min = 0.0
          max = 0.0
        if abs(max - min) < 0.00005:
          if max == 0.0 or min == 0.0:
            min = -0.1
            max = 0.1
          else:
            min = 0.9 * min
            max = 1.1 * max
        if min > max:
          temp = max
          max = min
          min = temp
        if not self.lock_image_real:
          self.r_cmin = min
          self.r_cmax = max
    # setImageRange

    def updateImage(self, image):
        self.setImage(image)
        self.raw_image = image

    def setFlaggedImageRange(self):
      (nx,ny) = self.raw_image.shape
      num_elements = nx * ny
      if self._flags_array is None:
        if not self._nan_flags_array is None:
          flags_array = self._nan_flags_array.copy()
        else:
          flags_array = numpy.zeros((nx,ny),int);
      else:
        flags_array = self._flags_array.copy()
        if not self._nan_flags_array is None:
          flags_array = flags_array + self._nan_flags_array
      flattened_flags = numpy.reshape(flags_array,(num_elements,))
      if self.raw_image.dtype == numpy.complex64 or self.raw_image.dtype == numpy.complex128:
        real_array =  self.raw_image.real
        imag_array =  self.raw_image.imag
        flattened_real_array = numpy.reshape(real_array.copy(),(num_elements,))
        flattened_imag_array = numpy.reshape(imag_array.copy(),(num_elements,))
        real_flagged_array = numpy.compress(flattened_flags == 0, flattened_real_array)
        imag_flagged_array = numpy.compress(flattened_flags == 0, flattened_imag_array)
        flagged_image = numpy.zeros(shape=real_flagged_array.shape,dtype=self.raw_image.dtype)
        flagged_image.real = real_flagged_array
        flagged_image.imag = imag_flagged_array
      else:
        flattened_array = numpy.reshape(self.raw_image.copy(),(num_elements,))
        flagged_image = numpy.compress(flattened_flags == 0, flattened_array)
      self.setImageRange(flagged_image)
    # setFlaggedImageRange

    def convert_to_log(self, incoming_image):
      self.transform_offset = 0.0
      transform_image = incoming_image
      image_min = incoming_image.min()
      if image_min <= 0.0:
        image_min = -1.0 * image_min
        self.transform_offset = 0.001 + image_min
        transform_image = self.transform_offset + incoming_image
      scale_min = transform_image.min()
      scale_max = transform_image.max()
      if scale_min == scale_max:
       scale_min = scale_min - 0.5 * scale_min
       scale_max = scale_max + 0.5 * scale_min
      self.dimap = ImageScaler(1, 256, scale_min, scale_max, True)
      _dprint(3, 'doing log transform of ', transform_image)
      temp_image = self.dimap.iTransform(transform_image)
      _dprint(3, 'log transformed image ', temp_image)
      return temp_image

    def getTransformOffset(self):
      return self.transform_offset

    def convert_limits(self, limits):
      if not self.dimap is None:
        first_limit = self.dimap.transform(self.transform_offset + limits[0])
        second_limit = self.dimap.transform(self.transform_offset + limits[1])
      else:
        first_limit = None
        second_limit = None
      return [first_limit, second_limit]


    def to_QImage(self, image):
# convert to 8 bit image
      image_for_display = None
      if image.dtype == numpy.complex64 or image.dtype == numpy.complex128:
        self.complex = True
        real_array =  image.real
        if self.log_scale:
          temp_array = self.convert_to_log(real_array)
          temp_array = self.convert_to_log(real_array)
          if not self.r_cmin is None and not self.r_cmax is None:
            limits = self.convert_limits([self.r_cmin,self.r_cmax])
          else:
            limits = [self.r_cmin, self.r_cmax] 
          byte_image = bytescale(temp_array,limits)
        else:
          limits = [self.r_cmin,self.r_cmax]
          byte_image = bytescale(real_array,limits)
        (nx,ny) = real_array.shape
        image_for_display = numpy.empty(shape=(nx*2,ny),dtype=byte_image.dtype);
        image_for_display[:nx,:] = byte_image
        imag_array =  image.imag
        if self.log_scale:
          temp_array = self.convert_to_log(imag_array)
          if not self.i_cmin is None and not self.i_cmax is None:
            limits = self.convert_limits([self.i_cmin,self.i_cmax])
          else:
            limits = [self.i_cmin, self.i_cmax] 
          byte_image = bytescale(temp_array,limits)
        else:
          limits = [self.i_cmin,self.i_cmax]
          byte_image = bytescale(imag_array,limits)
        image_for_display[nx:,:] = byte_image
      else:
        if self.log_scale:
          temp_array = self.convert_to_log(image)
          if not self.r_cmin is None and not self.r_cmax is None:
            limits = self.convert_limits([self.r_cmin,self.r_cmax])
          else:
            limits = [self.r_cmin, self.r_cmax] 
          #print 'to_QImage log limits = ', limits
          image_for_display = bytescale(temp_array,limits)
        else:
          limits = [self.r_cmin,self.r_cmax]
          #print 'to_QImage real limits = ', limits
          image_for_display = bytescale(image,limits)
      # turn image into a QImage, and return result   
      if not self._nan_flags_array is None:
        if self.complex:
          image_for_display[:nx,:] = numpy.where(self._nan_flags_array,1,image_for_display[:nx,:])
          image_for_display[nx:,:] = numpy.where(self._nan_flags_array,1,image_for_display[nx:,:])
        else:
          image_for_display = numpy.where(self._nan_flags_array,1,image_for_display)
      self._image_for_display = image_for_display
#     result = Qwt.toQImage(image_for_display).mirrored(0, 1)
      result = convertToQImage(image_for_display,True).mirrored(0, 1)
      # always suppress NaNs
      if not self._nan_flags_array is None:
        result.setColor(1, Qt.qRgb(self.nan_colour, self.nan_colour, self.nan_colour))
      return result

    def toGrayScale(self, Qimage):
      for i in range(0, 256):
        Qimage.setColor(i, Qt.qRgb(i, i, i))

    def toHippo(self, Qimage):
      dv = 255.0
      vmin = 1.0
      for i in range(2, 256):
        r = 1.0
        g = 1.0
        b = 1.0
        v = 1.0 * i
        if (v < (vmin + 0.25 * dv)):
          r = 0;
          if dv != 0:
            g = 4 * (v - vmin) / dv;
        elif (v < (vmin + 0.5 * dv)):
          r = 0;
          if dv != 0:
            b = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
        elif (v < (vmin + 0.75 * dv)):
          b = 0;
          if dv != 0:
            r = 4 * (v - vmin - 0.5 * dv) / dv;
        else: 
          b = 0;
          if dv != 0:
            g = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
          else:
            r = 0
        red   = int ( r * 255. )
        green = int ( g * 255. )
        blue  = int ( b * 255. )
# the following call will use the previous computations to
# set up a hippo-like color display
        Qimage.setColor(i, Qt.qRgb(red, green, blue))

    def setImage(self, image):
# convert to QImage
      self.Qimage = self.to_QImage(image)
# set color scale a la HippoDraw Scale
      if self.display_type == "hippo":
        self.toHippo(self.Qimage)

# set color scale to Grayscale
      if self.display_type == "grayscale":
        self.toGrayScale(self.Qimage)

# compute flagged image if required
      if not self._flags_array is None or not self._nan_flags_array is None:
        self.setFlagQimage()

    def setFlagQimage(self):
      (nx,ny) = self._image_for_display.shape
      image_for_display = self._image_for_display.copy()
      if not self._flags_array is None:
        if self.complex:
          image_for_display[:nx/2,:] = numpy.where(self._flags_array,0,self._image_for_display[:nx/2,:])
          image_for_display[nx/2:,:] = numpy.where(self._flags_array,0,self._image_for_display[nx/2:,:])
        else:
          image_for_display = numpy.where(self._flags_array,0,self._image_for_display)

      if not self._nan_flags_array is None:
        if self.complex:
          image_for_display[:nx/2,:] = numpy.where(self._nan_flags_array,1,image_for_display[:nx/2,:])
          image_for_display[nx/2:,:] = numpy.where(self._nan_flags_array,1,image_for_display[nx/2:,:])
        else:
          image_for_display = numpy.where(self._nan_flags_array,1,image_for_display)

#     self.flags_Qimage = Qwt.toQImage(image_for_display).mirrored(0, 1)
      self.flags_Qimage = convertToQImage(image_for_display,True).mirrored(0, 1)

# set color scale a la HippoDraw Scale
      if self.display_type == "hippo":
        self.toHippo(self.flags_Qimage)

# set color scale to Grayscale
      if self.display_type == "grayscale":
        self.toGrayScale(self.flags_Qimage)

# set zero to black to display flag image pixels in black 
      self.flags_Qimage.setColor(0, Qt.qRgb(self.flag_colour, self.flag_colour, self.flag_colour))
      self.flags_Qimage.setColor(1, Qt.qRgb(self.nan_colour, self.nan_colour, self.nan_colour))

    def setBrentjensImage(self, image):
      absmin = abs(image.min())
      MaxAbs = abs(image.max())
      if (absmin > MaxAbs):
        MaxAbs = absmin
      self.ValueAxis.calcTransferFunction(-MaxAbs, MaxAbs, 0, self.ComplexColorMap.getNumberOfColors()-1)

      if image.min() != image.max():
# get real and imaginary arrays
        real_image = image.real
        imag_image = image.imag
        shape = image.shape
        Ncol = self.ComplexColorMap.getNumberOfColors()
        bits_per_pixel = 32
        self.Qimage = QImage(shape[0], shape[1], bits_per_pixel, Ncol)
        for i in range(shape[0]):
          for j in range(shape[1]):
            colre = int(self.ValueAxis.worldToAxis(real_image[i,j]))
            colim = int(self.ValueAxis.worldToAxis(imag_image[i,j]))
            if(colre < Ncol and colim < Ncol): 
              value = self.ComplexColorMap.get_color_value(colre,colim)
              self.Qimage.setPixel(i,j,value)
            else:
              _dprint(2, "*************************************");
              _dprint(2, "colre: ", colre);
              _dprint(2, "colim: ", colim);
              _dprint(2, "real : ", real_image[i,j]);
              _dprint(2, "imag : ", imag_image[i,j]);
              _dprint(2, "Ncol: ", Ncol);
              _dprint(2, "*************************************");
        self.Qimage.mirror(0,1)

    def setData(self, data_array, xScale = None, yScale = None):
        '*** setting data **** '
        self.complex = False
        shape = data_array.shape
        _dprint(3, 'array shape is ', shape)
        shape0 = shape[0]
        if data_array.dtype == numpy.complex64 or data_array.dtype == numpy.complex128:
          self.complex = True
          shape0 = 2 * shape[0]
        if xScale:
            self.xMap = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            self.xMap_draw = ImageScaler(0, shape0 - 1, xScale[0], xScale[1])
            temp_scale = (xScale[0],xScale[1])
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, *temp_scale)
            _dprint(3, 'xScale is ', xScale)
        else:
            self.xMap = ImageScaler(0, shape0, 0, shape0 )
            self.xMap_draw = ImageScaler(0, shape0, 0, shape0 )
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, shape0)
        if yScale:
            _dprint(3, 'yScale is ', yScale)
            _dprint(3, 'self.log_y_scale is ', self.log_y_scale)

            self.yMap = ImageScaler(0, shape[1]-1, yScale[0], yScale[1],self.log_y_scale)
            self.yMap_draw = ImageScaler(0, shape[1]-1, yScale[0], yScale[1],self.log_y_scale)
            temp_scale = (yScale[0],yScale[1])
            _dprint(3, 'Called setAxisScale(Qwt.QwtPlot.yLeft) with ', temp_scale)
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, *temp_scale)
        else:
            self.yMap = ImageScaler(0, shape[1], 0, shape[1])
            self.yMap_draw = ImageScaler(0, shape[1], 0, shape[1])
            self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, shape[1])
        if self.display_type == "brentjens":
          self.setBrentjensImage(data_array)
        else:
          self.setImage(data_array)
        self.raw_image = data_array
    # setData()    

    def update_yMap_draw(self, d1, d2):
      self.yMap_draw.setDblRange(d1, d2, self.log_y_scale)

    def update_xMap_draw(self, d1, d2):
      self.xMap_draw.setDblRange(d1, d2, self.log_y_scale)

    def get_xMap_draw_coords(self):
      return (self.xMap_draw.d1(), self.xMap_draw.d2())

    def get_yMap_draw_coords(self):
      return (self.yMap_draw.d1(), self.yMap_draw.d2())

    def draw(self, painter, xMap, yMap,rect):
        """Paint image to zooming to xMap, yMap

        Calculate (x1, y1, x2, y2) so that it contains at least 1 pixel,
        and copy the visible region to scale it to the canvas.

        NOTE: we ignore the system-provided Maps and use our own 
        'draw' maps
        """
        if self.Qimage is None:
          return

        _dprint(3, 'incoming x map ranges ',xMap.s1(), ' ', xMap.s2())
        _dprint(3, 'incoming y map ranges ',yMap.s1(), ' ', yMap.s2())
#       print 'incoming x map ranges ',xMap.s1(), ' ', xMap.s2()
#       print 'incoming y map ranges ',yMap.s1(), ' ', yMap.s2()
#       print 'incoming x map draw ranges ',self.xMap_draw.d1(), ' ', self.xMap_draw.d2()
#       print 'incoming y map draw ranges ',self.yMap_draw.d1(), ' ', self.yMap_draw.d2()
#       print 'incoming self x map ranges ',self.xMap.d1(), ' ', self.xMap.d2()
#       print 'incoming self y map ranges ',self.yMap.d1(), ' ', self.yMap.d2()

        # calculate y1, y2
        y1 = y2 = self.Qimage.height()
        _dprint(3, 'image height ', self.Qimage.height())
#        y1 = y2 = self.Qimage.height() - 1
#       print 'starting image height ', y1
        y1 *= (self.yMap.d2() - self.yMap_draw.d2())
        y1 /= (self.yMap.d2() - self.yMap.d1())
#       y1 = max(0, int(y1-0.5))
        y1 = max(0, (y1-0.5))
        _dprint(3, 'float y1 ', y1)
        y1 = int(y1 + 0.5)
        y2 *= (self.yMap.d2() - self.yMap_draw.d1())
        y2 /= (self.yMap.d2() - self.yMap.d1())
        _dprint(3, 'float y2 ', y2)
#       y2 = min(self.Qimage.height(), int(y2+0.5))
        y2 = min(self.Qimage.height(), (y2+0.5))
        y2 = int(y2)
        _dprint(3, 'int y1, y2 ', y1, ' ',y2)
        # calculate x1, x2 - these are OK
        x1 = x2 = self.Qimage.width() 
#       print 'starting image width ', x1
        x1 *= (xMap.s1() - self.xMap.d1())
        x1 /= (self.xMap.d2() - self.xMap.d1())
        _dprint(3, 'float x1 ', x1)
#       x1 = max(0, int(x1-0.5))
        x1 = max(0, int(x1))
        x2 *= (self.xMap_draw.d2() - self.xMap.d1())
        x2 /= (self.xMap.d2() - self.xMap.d1())
        _dprint(3, 'float x2 ', x2)
        x2 = min(self.Qimage.width(), int(x2+0.5))
        _dprint(3, 'int x1, x2 ', x1, ' ',x2)
        # copy
        xdelta = x2-x1
        ydelta = y2-y1
#       print 'xdelta ydelta ', xdelta, ' ', ydelta
#       print 'x1 y1 ', x1, ' ', y1
        # these tests seem necessary for the dummy 'scalar' displays
        if xdelta < 0:
          xdelta = self.Qimage.height()
        if ydelta < 0:
          ydelta = self.Qimage.height()
	image = None
        if self._display_flags:
          image = self.flags_Qimage.copy(x1, y1, xdelta, ydelta)
        else:
          image = self.Qimage.copy(x1, y1, xdelta, ydelta)
        # zoom
        image = image.scaled(xMap.p2()-xMap.p1()+1, yMap.p1()-yMap.p2()+1)
        # draw
        painter.drawImage(xMap.p1(), yMap.p2(), image)