Skip to content

Commit

Permalink
Add tab to run browser for viewing area detector frames (#380)
Browse files Browse the repository at this point in the history
* Re-structured the AD viewer layout.

* Frames tab in run browser can now plot external datasets.

* Added ROI support into the run browser's frames tab.

* Added defaults and formatting to the run browser's "before" filter.

* Run browser's Lineplot view can now plot with markers.

* Enabled the aggregator checkbox in the run browser's lineplot view.

* Black, isort, and flake8.

* Reverted to black background for pyqtgraph.

* Added a check to make sure the framesetview time signal matches the dataset shape.
  • Loading branch information
canismarko authored Feb 28, 2025
1 parent 4ccd861 commit 34bb033
Show file tree
Hide file tree
Showing 17 changed files with 1,009 additions and 653 deletions.
8 changes: 8 additions & 0 deletions src/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from ophyd import DynamicDeviceComponent as DCpt
from ophyd import Kind
from ophyd.sim import instantiate_fake_device, make_fake_device
from tiled.adapters.array import ArrayAdapter
from tiled.adapters.mapping import MapAdapter
from tiled.adapters.table import TableAdapter
from tiled.client import Context, from_context
Expand Down Expand Up @@ -344,6 +345,13 @@ async def filters(sim_registry):
"events": TableAdapter.from_pandas(run1),
}
),
"external": MapAdapter(
{
"ge_8element": ArrayAdapter.from_array(
np.ones(shape=(100, 512, 1024))
),
}
),
},
metadata={"hints": hints, "data_keys": data_keys},
),
Expand Down
6 changes: 3 additions & 3 deletions src/firefly/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import httpx
import pydm
import pyqtgraph as pg
import qtawesome as qta
from ophyd_async.core import NotConnected
from ophydregistry import Registry
Expand Down Expand Up @@ -37,8 +36,9 @@
plans_dir = ui_dir / "plans"


pg.setConfigOption("background", (252, 252, 252))
pg.setConfigOption("foreground", (0, 0, 0))
# # Light-mode for plotting. Disabled temporarily to make all plots visible
# pg.setConfigOption("background", (252, 252, 252))
# pg.setConfigOption("foreground", (0, 0, 0))


class FireflyController(QtCore.QObject):
Expand Down
2 changes: 1 addition & 1 deletion src/firefly/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def customize_ui(self):
def update_queue_status(self, status):
pass

def show_message(self, message, timeout=0):
def show_message(self, message: str, timeout: int = 0):
"""Display a message in the status bar."""
self.status_message_changed.emit(str(message), timeout)

Expand Down
2 changes: 1 addition & 1 deletion src/firefly/run_browser/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ async def dataset(
arrays = OrderedDict()
for run in self.selected_runs:
# Get data from the database
arr = await run.dataset(dataset_name, stream=stream)
arr = await run.external_dataset(dataset_name, stream=stream)
arrays[run.uid] = arr
return arrays

Expand Down
30 changes: 18 additions & 12 deletions src/firefly/run_browser/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from typing import Mapping, Optional, Sequence

import httpx
import numpy as np
import qtawesome as qta
from ophyd import Device as ThreadedDevice
from ophyd_async.core import Device
Expand Down Expand Up @@ -61,6 +60,7 @@ class RunBrowserDisplay(display.FireflyDisplay):
data_keys_changed = Signal(ChainMap, set, set)
data_frames_changed = Signal(dict)
metadata_changed = Signal(dict)
datasets_changed = Signal(dict)

export_dialog: Optional[ExportDialog] = None

Expand Down Expand Up @@ -96,26 +96,26 @@ async def change_catalog(self, catalog_name: str):
)

@asyncSlot(str)
async def retrieve_dataset(
self, dataset_name: str, callback, task_name: str
) -> np.ndarray:
async def fetch_datasets(self, dataset_name: str):
"""Retrieve a dataset from disk, and provide it to the slot.
Parameters
==========
dataset_name
The name in the Tiled catalog of the dataset to retrieve.
callback
Will be called with the retrieved dataset.
task_name
For handling parallel database tasks.
Emits
=====
datasets_changed
Emitted with the new datasets as a dictionary.
"""
# Retrieve data from the database
data = await self.db_task(
self.db.dataset(dataset_name, stream=self.stream), task_name
self.db.dataset(dataset_name, stream=self.stream),
name="retrieve_dataset",
)
# Pass it back to the slot
callback(data)
self.datasets_changed.emit(data)

def db_task(self, coro, name="default task"):
"""Executes a co-routine as a database task. Existing database
Expand Down Expand Up @@ -184,6 +184,9 @@ def reset_default_filters(self):
last_week = dt.datetime.now().astimezone() - dt.timedelta(days=7)
last_week = QDateTime.fromTime_t(int(last_week.timestamp()))
self.ui.filter_after_datetimeedit.setDateTime(last_week)
next_week = dt.datetime.now().astimezone() + dt.timedelta(days=7)
next_week = QDateTime.fromTime_t(int(next_week.timestamp()))
self.ui.filter_before_datetimeedit.setDateTime(next_week)

async def update_combobox_items(self):
""""""
Expand Down Expand Up @@ -229,10 +232,13 @@ def customize_ui(self):
self.data_keys_changed.connect(self.ui.multiplot_view.update_signal_widgets)
self.data_keys_changed.connect(self.ui.lineplot_view.update_signal_widgets)
self.data_keys_changed.connect(self.ui.gridplot_view.update_signal_widgets)
self.data_keys_changed.connect(self.ui.xrf_view.update_signal_widgets)
self.data_keys_changed.connect(self.ui.frameset_tab.update_signal_widgets)
self.data_frames_changed.connect(self.ui.multiplot_view.plot_multiples)
self.data_frames_changed.connect(self.ui.lineplot_view.plot)
self.data_frames_changed.connect(self.ui.gridplot_view.plot)
self.data_frames_changed.connect(self.ui.frameset_tab.stash_data_frames)
self.datasets_changed.connect(self.ui.frameset_tab.plot_datasets)
self.ui.frameset_tab.dataset_selected.connect(self.fetch_datasets)
# Create a new export dialog for saving files
self.ui.export_button.clicked.connect(self.export_runs)
self.export_dialog = ExportDialog(parent=self)
Expand Down
Loading

0 comments on commit 34bb033

Please sign in to comment.