From 49a9f35e555d4ffc3966e46fabfdcf679d1d443f Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 13 Jun 2025 20:34:00 +0200 Subject: [PATCH] GUI: Minor improvements to grid scan result display --- common/src/aaredaqlib/raster_grid.py | 2 + gui/src/aaregui/main_window.py | 2 + .../aaregui/panels/raster_data_collection.py | 16 ++++-- .../aaregui/scan_logic/raster_grid_manager.py | 55 +++++++++++++++++-- gui/src/aaregui/threads/daq_worker.py | 1 + gui/src/aaregui/widgets/camera_image.py | 13 ++++- 6 files changed, 77 insertions(+), 12 deletions(-) diff --git a/common/src/aaredaqlib/raster_grid.py b/common/src/aaredaqlib/raster_grid.py index 3a4f900b..fa57801e 100644 --- a/common/src/aaredaqlib/raster_grid.py +++ b/common/src/aaredaqlib/raster_grid.py @@ -35,6 +35,8 @@ class RasterGridRequest(BaseModel): class CompletedRasterGrid(BaseModel): request: RasterGridRequest + filename: str | None = None + image_number: List[int] bkg_estimate: List[float] spot_count: List[int] indexed: List[int] diff --git a/gui/src/aaregui/main_window.py b/gui/src/aaregui/main_window.py index 643a0a10..21200703 100644 --- a/gui/src/aaregui/main_window.py +++ b/gui/src/aaregui/main_window.py @@ -197,6 +197,8 @@ class MainWindow(QMainWindow): self.data_collection.raster.transmission_updated.connect(self.raster.update_transmission) self.data_collection.raster.dtz_updated.connect(self.raster.update_dtz) self.data_collection.raster.grid_metric_updated.connect(self.raster.metric) + self.data_collection.raster.raster_alpha_changed.connect(self.camera_image.raster_alpha) + self.raster.grid_scan.connect(self.daq.raster_scan) self.data_collection.screening.rotation_scan.connect(self.daq.standard_scan) diff --git a/gui/src/aaregui/panels/raster_data_collection.py b/gui/src/aaregui/panels/raster_data_collection.py index 68ad6b02..c85f07dc 100644 --- a/gui/src/aaregui/panels/raster_data_collection.py +++ b/gui/src/aaregui/panels/raster_data_collection.py @@ -1,6 +1,6 @@ from PySide6.QtCore import Signal, Slot, Qt from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QSizePolicy, QSpacerItem, QPushButton, QHBoxLayout, \ - QComboBox + QComboBox, QSlider from aaredaqlib.diffraction_geometry import DiffractionGeometry from aaregui.panels.scan_settings_panel import ScanSettingsPanel @@ -13,6 +13,7 @@ class RasterDataCollectionPanel(ScanSettingsPanel): exp_time_updated = Signal(float) evaluate_grid = Signal() grid_metric_updated = Signal(RasterGridMetric) + raster_alpha_changed = Signal(int) def __init__(self, raster_mgr :RasterGridManager, diffraction: DiffractionGeometry, @@ -83,19 +84,26 @@ class RasterDataCollectionPanel(ScanSettingsPanel): self.metric_combo.addItem("Mosaicity", RasterGridMetric.MOS) self.metric_combo.addItem("B-factor", RasterGridMetric.BFACTOR) + self.metric_combo.currentIndexChanged.connect(self.metric_changed) + self._layout.addWidget(self.metric_combo, 7, 1, 1, 3) - self.metric_combo.currentIndexChanged.connect(self.metric_changed) + self._layout.addWidget(QLabel("Transparency", parent=self), 8, 0) + slider = QSlider(orientation=Qt.Orientation.Horizontal, parent=self) + slider.setRange(0, 255) + slider.setValue(127) + slider.valueChanged.connect(lambda: self.raster_alpha_changed.emit(slider.value())) + self._layout.addWidget(slider, 8, 1, 1, 3) horizontal_spacer = QSpacerItem( 40, 20, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding ) - self._layout.addItem(horizontal_spacer, 8, 0, 1, 4) + self._layout.addItem(horizontal_spacer, 9, 0, 1, 4) self.start_button = QPushButton("Evaluate grid") self.start_button.setStyleSheet("color: rgb(78, 154, 6);") self.start_button.clicked.connect(self.evaluate_grid) - self._layout.addWidget(self.start_button, 9, 0, 1, 5) + self._layout.addWidget(self.start_button, 10, 0, 1, 5) self.update_grid_scan_size() diff --git a/gui/src/aaregui/scan_logic/raster_grid_manager.py b/gui/src/aaregui/scan_logic/raster_grid_manager.py index 37cb41e5..70b67ddf 100644 --- a/gui/src/aaregui/scan_logic/raster_grid_manager.py +++ b/gui/src/aaregui/scan_logic/raster_grid_manager.py @@ -177,6 +177,46 @@ class RasterGridManager(QObject): 0 <= delta.y < self.__active_grid.n_y * self.__active_grid.grid_size_mm.y ) + def is_part_of_completed_grid(self, point: QPointF) -> str: + for grid in self.__completed_grids: + if self._is_grid_visible(grid.request): + point_bl = self.__geom.picture_to_sample(Coordinate(x=point.x(), y=point.y())) + + delta = point_bl - self.__geom.smargon_to_beamline(grid.request.smargon.sh_mm) + + n_x = grid.request.n_x + n_y = grid.request.n_y + elem_x = grid.request.grid_size_mm.x + elem_y = grid.request.grid_size_mm.y + + cell_x = math.floor(delta.x / elem_x) + cell_y = math.floor(delta.y / elem_y) + if 0 <= cell_x < n_x and 0 <= cell_y < n_y: + cell = cell_y * n_x + cell_x + txt = "" + + if cell < len(grid.image_number): + txt += f"Image {grid.image_number[cell]}
" + + if cell < len(grid.bkg_estimate): + txt += f"Background estimate {grid.bkg_estimate[cell]:.2f}
" + + if cell < len(grid.spot_count): + txt += f"Spot count {grid.spot_count[cell]}
" + + if cell < len(grid.indexed) and grid.indexed[cell] > 0: + txt += "Indexed
" + + if cell < len(grid.b_factor) and grid.b_factor[cell] >= 0: + txt += f"B-factor {grid.b_factor[cell]:.2f}
" + + if cell < len(grid.mosaicity) and grid.mosaicity[cell] >= 0: + txt += f"Mosaicity {grid.mosaicity[cell]:.2f}" + + return txt + return "" + + @Slot(float, float) def update_grid_size(self, grid_size_mm_x: float, grid_size_mm_y: float): if (grid_size_mm_x <= 0) or (grid_size_mm_y <= 0): @@ -199,7 +239,7 @@ class RasterGridManager(QObject): self.__active_grid.n_x = 0 self.__active_grid.n_y = 0 - def draw_grid(self, painter: QPainter): + def draw_grid(self, painter: QPainter, alpha: int = 127): self._draw_grid(painter, self.__active_grid) for i in self.__completed_grids: v = None @@ -214,11 +254,14 @@ class RasterGridManager(QObject): v = i.mosaicity case RasterGridMetric.BFACTOR: v = i.b_factor - self._draw_grid(painter, i.request, v) + self._draw_grid(painter, i.request, v, alpha) - def _draw_grid(self, painter: QPainter, grid: RasterGridRequest, values: List[float] | List[int] | None = None): + def _draw_grid(self, painter: QPainter, grid: RasterGridRequest, values: List[float] | List[int] | None = None, + alpha : int = 127): if not self._is_grid_visible(grid): return + if alpha < 0 or alpha > 255: + return if values is not None: painter.setPen(Qt.PenStyle.NoPen) @@ -234,12 +277,12 @@ class RasterGridManager(QObject): for x in range(grid.n_x): for y in range(grid.n_y): pxl = x + y * grid.n_x - if values is None or len(values) <= pxl or math.isnan(values[pxl]): + if values is None or len(values) <= pxl or math.isnan(values[pxl]) or values[pxl] < 0: painter.setBrush(Qt.BrushStyle.NoBrush) else: - painter.setBrush(QBrush(float_to_viridis_brush((values[pxl] - min_value) / (max_value - min_value), alpha=127))) + painter.setBrush(QBrush(float_to_viridis_brush((values[pxl] - min_value) / (max_value - min_value), alpha=alpha))) c = self.__geom.sample_to_picture(c0 + Coordinate(x=x * grid.grid_size_mm.x, y=y * grid.grid_size_mm.y)) - painter.drawRect(QRect(int(c.x), int(c.y), int(g.x), int(g.y))) + painter.drawRect(QRect(round(c.x), round(c.y), round(g.x), round(g.y))) painter.setBrush(Qt.BrushStyle.NoBrush) diff --git a/gui/src/aaregui/threads/daq_worker.py b/gui/src/aaregui/threads/daq_worker.py index 8f7ec07b..e28631ff 100644 --- a/gui/src/aaregui/threads/daq_worker.py +++ b/gui/src/aaregui/threads/daq_worker.py @@ -209,6 +209,7 @@ class DAQWorker(QObject): new_copy = copy.deepcopy(r) reply = CompletedRasterGrid(request=new_copy, + image_number= [i for i in range(image_number)], bkg_estimate=[random.gauss(3.0, 0.1) for _ in range(image_number)], spot_count=[random.randint(0, 250) for _ in range(image_number)], indexed=[random.randint(0, 1) for _ in range(image_number)], diff --git a/gui/src/aaregui/widgets/camera_image.py b/gui/src/aaregui/widgets/camera_image.py index cbb62406..5e2ae737 100644 --- a/gui/src/aaregui/widgets/camera_image.py +++ b/gui/src/aaregui/widgets/camera_image.py @@ -68,6 +68,7 @@ class SampleCameraImageLabel(QGraphicsView): self.__show_coords = False self.__helical_start = SmargonCoordinate() self.__helical_end = SmargonCoordinate() + self.__raster_alpha = 127 self.start_point = None # Starting point of the rectangle self.end_point = None # Ending point of the rectangle @@ -103,7 +104,7 @@ class SampleCameraImageLabel(QGraphicsView): def drawForeground(self, painter, rect): self.__draw_beam_center(painter) - self.__raster_mgr.draw_grid(painter) + self.__raster_mgr.draw_grid(painter, self.__raster_alpha) self.__draw_helical(painter) def resizeEvent(self, event): @@ -141,7 +142,10 @@ class SampleCameraImageLabel(QGraphicsView): def mouseMoveEvent(self, event): mouse_pos = self.mapToScene(event.pos()) - if self.__show_coords: + txt = self.__raster_mgr.is_part_of_completed_grid(mouse_pos) + if txt != "": + QToolTip.showText(self.mapToGlobal(event.pos()), txt, self) + elif self.__show_coords: x, y = mouse_pos.x(), mouse_pos.y() QToolTip.showText( self.mapToGlobal(event.pos()), f"{x:.0f}, {y:.0f} pxl", self @@ -373,6 +377,11 @@ class SampleCameraImageLabel(QGraphicsView): self.__helical_end = pos self.update() + @Slot(int) + def raster_alpha(self, value: int): + if 0 <= value <= 255: + self.__raster_alpha = value + def keyPressEvent(self, event): mouse_global_pos = QCursor.pos() mouse_view_pos = self.mapFromGlobal(mouse_global_pos)