diff --git a/shapeout2/gui/quick_view/qv_main.py b/shapeout2/gui/quick_view/qv_main.py
index 482b172..d9aa910 100644
--- a/shapeout2/gui/quick_view/qv_main.py
+++ b/shapeout2/gui/quick_view/qv_main.py
@@ -133,6 +133,19 @@ def __init__(self, *args, **kwargs):
levels=(0, 255),
)
+ self.img_info = {
+ "image": {"view_event": self.imageView_image,
+ "view_poly": self.imageView_image_poly,
+ "cmap": pg.colormap.get('CET-L1')},
+ "qpi_pha": {"view_event": self.imageView_image_pha,
+ "view_poly": self.imageView_image_poly_pha,
+ "cmap": pg.colormap.get('CET-D1A')},
+ "qpi_amp": {
+ "view_event": self.imageView_image_amp,
+ "view_poly": self.imageView_image_poly_amp,
+ "cmap": pg.colormap.get('CET-L1')},
+ }
+
# set initial empty dataset
self._rtdc_ds = None
self.slot = None
@@ -201,7 +214,7 @@ def __setstate__(self, state):
self.checkBox_image_contour.setChecked(event["image contour"])
self.checkBox_image_zoom.setChecked(event["image zoom"])
self.checkBox_image_background.setChecked(
- event["image background"])
+ event["image background"])
self.spinBox_event.setValue(event["index"])
self.checkBox_trace_raw.setChecked(event["trace raw"])
self.checkBox_trace_legend.setChecked(event["trace legend"])
@@ -250,28 +263,47 @@ def rtdc_ds(self, rtdc_ds):
contains_bg_feat = "image_bg" in rtdc_ds
self.checkBox_image_background.setVisible(contains_bg_feat)
- def get_event_image(self, ds, event):
+ def get_event_image(self, ds, event, feat):
state = self.__getstate__()
imkw = self.imkw.copy()
- cellimg = ds["image"][event]
- # apply background correction
- if "image_bg" in ds:
- if state["event"]["image background"]:
- bgimg = ds["image_bg"][event].astype(np.int16)
- cellimg = cellimg.astype(np.int16)
- cellimg = cellimg - bgimg + int(np.mean(bgimg))
- # automatic contrast
- if state["event"]["image auto contrast"]:
- vmin, vmax = cellimg.min(), cellimg.max()
- cellimg = (cellimg - vmin) / (vmax - vmin) * 255
- # convert to RGB
- cellimg = cellimg.reshape(
- cellimg.shape[0], cellimg.shape[1], 1)
- cellimg = np.repeat(cellimg, 3, axis=2)
- # clip and convert to int
- cellimg = np.clip(cellimg, 0, 255)
- cellimg = np.require(cellimg, np.uint8, 'C')
+ cellimg = ds[feat][event]
+
+ if feat == "image":
+ # apply background correction
+ if "image_bg" in ds:
+ if state["event"]["image background"]:
+ bgimg = ds["image_bg"][event].astype(np.int16)
+ cellimg = cellimg.astype(np.int16)
+ cellimg = cellimg - bgimg + int(np.mean(bgimg))
+ # automatic contrast
+ if state["event"]["image auto contrast"]:
+ vmin, vmax = cellimg.min(), cellimg.max()
+ cellimg = (cellimg - vmin) / (vmax - vmin) * 255
+ elif "qpi" in feat:
+ if "qpi_pha" in feat:
+ imkw["levels"] = (-3, 3)
+ elif "qpi_amp" in feat:
+ imkw["levels"] = (0, 2)
+ else:
+ raise ValueError(f"Options for `feat` are 'image', "
+ f"'qpi_pha' and 'qpi_amp', got {feat}")
+
+ if feat == "image":
+ # convert to RGB
+ cellimg = cellimg.reshape(
+ cellimg.shape[0], cellimg.shape[1], 1)
+ cellimg = np.repeat(cellimg, 3, axis=2)
+
+ # clip and convert to int
+ cellimg = np.clip(cellimg, 0, 255)
+ cellimg = np.require(cellimg, np.uint8, 'C')
+ cellimg = self.display_contour(ds, event, state, cellimg, feat, imkw)
+
+ return cellimg, imkw
+
+ @staticmethod
+ def display_contour(ds, event, state, cellimg, feat, imkw):
# Only load contour data if there is an image column.
# We don't know how big the images should be so we
# might run into trouble displaying random contours.
@@ -283,9 +315,18 @@ def get_event_image(self, ds, event):
# https://github.com/DC-analysis/dclab/issues/76
cont = mask ^ binary_erosion(mask)
# set red contour pixel values in original image
- cellimg[cont, 0] = int(255*.7)
- cellimg[cont, 1] = 0
- cellimg[cont, 2] = 0
+ red_pix = ((imkw["levels"][1] - imkw["levels"][0])
+ * 0.7) - np.abs(imkw["levels"][0])
+ if feat == "image":
+ cellimg[cont, 0] = int(
+ red_pix) if imkw["levels"][1] == 255 else red_pix
+ cellimg[cont, 1] = int(imkw["levels"][0])
+ cellimg[cont, 2] = int(imkw["levels"][0])
+ else:
+ # just 2D images (not RGB)
+ cellimg[cont] = int(
+ red_pix) if imkw["levels"][1] == 255 else red_pix
+
if state["event"]["image zoom"]:
xv, yv = np.where(mask)
idminx = xv.min() - 5
@@ -298,7 +339,7 @@ def get_event_image(self, ds, event):
idmaxx = idmaxx if idmaxx < shx else shx
idmaxy = idmaxy if idmaxy < shy else shy
cellimg = cellimg[idminx:idmaxx, idminy:idmaxy]
- return cellimg, imkw
+ return cellimg
def get_statistics(self):
if self.rtdc_ds is not None:
@@ -334,25 +375,43 @@ def on_event_scatter_clicked(self, plot, point):
ds_idx = np.where(plotted)[0][point.index()]
self.show_event(ds_idx)
+ def display_img(self, feat, view, cellimg, **imkw):
+ self.img_info[feat][view].setImage(cellimg, **imkw)
+ self.img_info[feat][view].setColorMap(self.img_info[feat]["cmap"])
+ self.img_info[feat][view].show()
+
def on_event_scatter_hover(self, pos):
"""Update the image view in the polygon widget """
if self.rtdc_ds is not None and self.toolButton_poly.isChecked():
+ ds = self.rtdc_ds
# plotted events
plotted = self.widget_scatter.events_plotted
spos = self.widget_scatter.scatter.mapFromView(pos)
point = self.widget_scatter.scatter.pointAt(spos)
# get corrected index
event = np.where(plotted)[0][point.index()]
- if "image" in self.rtdc_ds:
- try:
- cellimg, imkw = self.get_event_image(self.rtdc_ds, event)
- except IndexError:
- # the plot got updated, and we still have the old data
- cellimg, imkw = self.get_event_image(self.rtdc_ds, 0)
+
+ view = "view_poly"
+ for key in self.img_info.keys():
+ self.img_info[key][view].hide()
+
+ try:
+ # if we have qpi data, image might be a different shape
+ if "qpi_pha" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "qpi_pha")
+ self.display_img("qpi_pha", view, cellimg, **imkw)
+ if "qpi_amp" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "qpi_amp")
+ self.display_img("qpi_amp", view, cellimg, **imkw)
+ elif "image" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "image")
+ self.display_img("image", view, cellimg, **imkw)
+
+ except IndexError:
+ # the plot got updated, and we still have the old data
+ cellimg, imkw = self.get_event_image(self.rtdc_ds, 0, "image")
self.imageView_image_poly.setImage(cellimg, **imkw)
- self.imageView_image_poly.show()
- else:
- self.imageView_image_poly.hide()
+ self.display_img("image", view, cellimg, **imkw)
def on_event_scatter_spin(self, event):
"""Sping control for event selection changed"""
@@ -494,8 +553,8 @@ def on_tool(self, collapse=False):
else:
# keep everything as-is but update the sizes
show_event = self.stackedWidget.currentWidget() is self.page_event
- show_settings = self.stackedWidget.currentWidget() \
- is self.page_settings
+ show_settings = (
+ self.stackedWidget.currentWidget() is self.page_settings)
show_poly = self.stackedWidget.currentWidget() is self.page_poly
# toolbutton checked
@@ -606,12 +665,25 @@ def show_event(self, event):
if self.tabWidget_event.currentIndex() == 0:
# update image
state = self.__getstate__()
- if "image" in ds:
- cellimg, imkw = self.get_event_image(ds, event)
- self.imageView_image.setImage(cellimg, **imkw)
- self.groupBox_image.show()
- else:
- self.groupBox_image.hide()
+ self.groupBox_image.hide()
+
+ view = "view_event"
+ for key in self.img_info.keys():
+ self.img_info[key][view].hide()
+
+ # if we have qpi data, image might be a different shape
+ if "qpi_pha" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "qpi_pha")
+ self.display_img("qpi_pha", view, cellimg, **imkw)
+ if "qpi_amp" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "qpi_amp")
+ self.display_img("qpi_amp", view, cellimg, **imkw)
+ elif "image" in ds:
+ cellimg, imkw = self.get_event_image(ds, event, "image")
+ self.display_img("image", view, cellimg, **imkw)
+
+ self.groupBox_image.show()
+
if "trace" in ds:
# remove legend items
for item in reversed(self.legend_trace.items):
@@ -650,8 +722,9 @@ def show_event(self, event):
range_t[1] = flpos + 1.5 * flwidth
range_t[2] = flmax
# set legend name
- ln = "{} {}".format(self.slot.fl_name_dict[
- "FL-{}".format(key[2])], key[4:])
+ ln = "{} {}".format(
+ self.slot.fl_name_dict[
+ "FL-{}".format(key[2])], key[4:])
self.legend_trace.addItem(self.trace_plots[key], ln)
self.legend_trace.update()
else:
diff --git a/shapeout2/gui/quick_view/qv_main.ui b/shapeout2/gui/quick_view/qv_main.ui
index 7607660..f901103 100644
--- a/shapeout2/gui/quick_view/qv_main.ui
+++ b/shapeout2/gui/quick_view/qv_main.ui
@@ -714,17 +714,53 @@
-
-
-
-
- 300
- 100
-
+
+
+ QLayout::SetNoConstraint
-
- background-color:transparent
+
+ 0
-
+
-
+
+
+
+ 300
+ 100
+
+
+
+ background-color:transparent
+
+
+
+ -
+
+
+
+ 300
+ 100
+
+
+
+ background-color:transparent
+
+
+
+ -
+
+
+
+ 300
+ 100
+
+
+
+ background-color:transparent
+
+
+
+
@@ -1039,17 +1075,71 @@
-
-
-
-
- 0
- 0
-
+
+
+ QLayout::SetNoConstraint
-
- opacity: 0
+
+ 0
-
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 100
+
+
+
+ opacity: 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 100
+
+
+
+ opacity: 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 100
+
+
+
+ opacity: 0
+
+
+
+
-