diff --git a/gemviz/bluesky_runs_catalog.py b/gemviz/bluesky_runs_catalog.py index a6bd3dc..338d0da 100644 --- a/gemviz/bluesky_runs_catalog.py +++ b/gemviz/bluesky_runs_catalog.py @@ -242,6 +242,8 @@ def doRunSelectedSlot(self, run): logger.info(f"Refreshing active run {run.uid[:7]} to get latest data") # Note: is_active refreshes metadata + self.selected_run_uid = run.get_run_md("start", "uid") + run_md = run.run_md self.brc_run_viz.setMetadata(yaml.dump(dict(run_md), indent=4)) try: @@ -252,7 +254,6 @@ def doRunSelectedSlot(self, run): ) return self.setStatus(run.summary()) - self.selected_run_uid = run.get_run_md("start", "uid") # Clear reference to old widget (if any) self.current_field_widget = None @@ -291,6 +292,8 @@ def doRunDoubleClickSlot(self, run): logger.info(f"Refreshing active run {run.uid[:7]} to get latest data") # Note: is_active refreshes metadata + self.selected_run_uid = run.get_run_md("start", "uid") + run_md = run.run_md self.brc_run_viz.setMetadata(yaml.dump(dict(run_md), indent=4)) try: @@ -301,7 +304,6 @@ def doRunDoubleClickSlot(self, run): ) return self.setStatus(run.summary()) - self.selected_run_uid = run.get_run_md("start", "uid") # Clear reference to old widget (if any) self.current_field_widget = None diff --git a/gemviz/bluesky_runs_catalog_table_view.py b/gemviz/bluesky_runs_catalog_table_view.py index 5e6fe92..40b8a02 100644 --- a/gemviz/bluesky_runs_catalog_table_view.py +++ b/gemviz/bluesky_runs_catalog_table_view.py @@ -217,6 +217,14 @@ def updateModelData(self): # Send the page of runs to the model now. self.model.setRuns(page) + # Restore selection based on selected_run_uid + selected_uid = self.parent.selected_run_uid + if selected_uid and selected_uid in page: + row_index = list(page.keys()).index(selected_uid) + self.tableView.selectRow(row_index) + elif selected_uid: + self.tableView.clearSelection() + def setPagerStatus(self, text=None): if text is None: total = self.catalogLength() # filtered catalog diff --git a/gemviz/select_stream_fields.py b/gemviz/select_stream_fields.py index 59dfc82..4d14e87 100644 --- a/gemviz/select_stream_fields.py +++ b/gemviz/select_stream_fields.py @@ -84,9 +84,29 @@ def setStream(self, stream_name): x_names = self.analysis["plot_axes"] y_name = self.analysis["plot_signal"] + # Check if we have an existing table with fields + has_existing_table = ( + self.table_view is not None + and hasattr(self.table_view, "tableView") + and self.table_view.tableView.model() is not None + and len(self.table_view.tableView.model().fields()) > 0 + ) + # describe the data fields for the dialog. - sdf = self.run.stream_data_fields(stream_name) - # print(f"{__name__}.{__class__.__name__}: {sdf=}") + try: + sdf = self.run.stream_data_fields(stream_name) + # print(f"{__name__}.{__class__.__name__}: {sdf=}") + except Exception as exc: + # If we can't get fields and we have an existing table, skip rebuild + if has_existing_table: + logger.debug( + f"Could not get fields for {stream_name}: {exc}, " + "skipping rebuild to avoid empty flash" + ) + return + # If no existing table, we need to try building one + sdf = [] + fields = [] for field_name in sdf: selection = None @@ -107,6 +127,18 @@ def setStream(self, stream_name): fields.append(field) logger.debug("fields=%s", fields) + # Check if any fields have valid (non-empty) shapes + # If all fields have empty shapes, they're not readable yet (Container objects) + has_readable_fields = any(len(field.shape) > 0 for field in fields) + + # If no readable fields AND we have an existing table, skip rebuild + if not has_readable_fields and has_existing_table: + logger.debug( + f"No readable fields available for {stream_name} (all have empty shapes), " + "skipping rebuild to avoid empty flash" + ) + return + # build the view of this stream view = SelectFieldsTableView(self) self.table_view = view @@ -142,6 +174,7 @@ def refreshFieldData(self): saved = {} # Rebuild the table for the current stream using fresh data. + # setStream() will check if fields are readable before rebuilding current_stream = self.stream_name self.setStream(current_stream) diff --git a/gemviz/tapi.py b/gemviz/tapi.py index 152c116..a5201cb 100644 --- a/gemviz/tapi.py +++ b/gemviz/tapi.py @@ -16,7 +16,7 @@ import numpy import tiled import tiled.queries -from httpx import HTTPStatusError +from httpx import ConnectError, HTTPStatusError logger = logging.getLogger(__name__) @@ -254,6 +254,9 @@ def stream_data(self, stream_name): else: logger.error(f"Failed to read stream data for {stream_name}: {exc}") raise + except ConnectError as exc: + logger.warning(f"Connection error reading stream {stream_name}: {exc}") + raise except Exception as exc: logger.error(f"Error reading stream data for {stream_name}: {exc}") raise @@ -366,7 +369,7 @@ def _read_stream_arrays(self, stream_name): data = data_node[field].read() except (KeyError, AttributeError) as exc: # Field doesn't exist yet - skip it - logger.warning( + logger.debug( f"Field {field} not yet available for {stream_name}: {exc}" ) continue