diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 466d846..728af5b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.18 +current_version = 0.1.19 commit = True tag = True diff --git a/pyproject.toml b/pyproject.toml index f20d70a..c81fbf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "quickview" -version = "0.1.18" +version = "0.1.19" description = "An application to explore/analyze data for atmosphere component for E3SM" authors = [ {name = "Kitware Inc."}, diff --git a/quickview/__init__.py b/quickview/__init__.py index 36b772c..80a133e 100644 --- a/quickview/__init__.py +++ b/quickview/__init__.py @@ -1,5 +1,5 @@ """QuickView: Visual Analysis for E3SM Atmosphere Data.""" -__version__ = "0.1.18" +__version__ = "0.1.19" __author__ = "Kitware Inc." __license__ = "Apache-2.0" diff --git a/quickview/interface.py b/quickview/interface.py index d1d0937..00d793c 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -721,7 +721,7 @@ def ui(self) -> SinglePageWithDrawerLayout: ( html.Img( src=f"data:image/png;base64,{LOGO_BASE64}", - style="height: 40px; width: 80px; border-radius: 4px; margin-bottom: 2px;", + style="height: 30px; width: 60px; border-radius: 4px; margin-bottom: 2px;", ), ) html.Span( diff --git a/quickview/plugins/eam_reader.py b/quickview/plugins/eam_reader.py index b832810..1e5a594 100644 --- a/quickview/plugins/eam_reader.py +++ b/quickview/plugins/eam_reader.py @@ -349,36 +349,24 @@ def _get_cached_area(self, vardata): def _load_2d_variable(self, vardata, varmeta, timeInd): """Load 2D variable data with optimized operations.""" # Get data without unnecessary copy - data = vardata[varmeta.name][timeInd] - # Reshape instead of flatten to avoid copy when possible - data = data.reshape(-1) - # Create a copy only if we need to modify values - if varmeta.fillval is not None: - data = data.copy() # Only copy when needed - mask = data == varmeta.fillval - data[mask] = np.nan + data = vardata[varmeta.name][:].data[timeInd].flatten() + data = np.where(data == varmeta.fillval, np.nan, data) return data def _load_3d_slice(self, vardata, varmeta, timeInd, start_idx, end_idx): """Load a slice of 3D variable data with optimized operations.""" # Load full 3D data for time step - data = vardata[varmeta.name][timeInd] - - if varmeta.transpose: - # Only transpose if needed - data = data.T - - # Reshape to 2D (levels, ncells) and extract slice - data_reshaped = data.reshape(data.shape[0], -1) - slice_data = data_reshaped.flat[start_idx:end_idx] - - # Create a copy for fill value replacement - if varmeta.fillval is not None: - slice_data = slice_data.copy() - mask = slice_data == varmeta.fillval - slice_data[mask] = np.nan - - return slice_data + if not varmeta.transpose: + data = vardata[varmeta.name][:].data[timeInd].flatten()[start_idx:end_idx] + else: + data = ( + vardata[varmeta.name][:] + .data[timeInd] + .transpose() + .flatten()[start_idx:end_idx] + ) + data = np.where(data == varmeta.fillval, np.nan, data) + return data def _get_enabled_arrays(self, var_list, selection_obj): """Get list of enabled variable names from selection object.""" @@ -477,7 +465,15 @@ def _populate_variable_metadata(self): elif varmeta.type == VarType._3Di: self._interface_vars.append(varmeta) self._interface_selection.AddArray(name) - + try: + fillval = info.getncattr("_FillValue") + varmeta.fillval = fillval + except Exception: + try: + fillval = info.getncattr("missing_value") + varmeta.fillval = fillval + except Exception: + pass self._surface_selection.DisableAllArrays() self._interface_selection.DisableAllArrays() self._midpoint_selection.DisableAllArrays() diff --git a/quickview/ui/toolbar.py b/quickview/ui/toolbar.py index 630cc43..22a94a1 100644 --- a/quickview/ui/toolbar.py +++ b/quickview/ui/toolbar.py @@ -292,6 +292,12 @@ def __init__( ): v2.VIcon("mdi-upload") html.Span("Load State") + v2.VProgressCircular( + bg_color="rgba(0,0,0,0)", + indeterminate=("trame__busy",), + color="primary", + width=3, + ) v2.VDivider(vertical=True, classes="mx-2") with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): diff --git a/quickview/view_manager.py b/quickview/view_manager.py index 6ae9cb5..b4a7c7e 100644 --- a/quickview/view_manager.py +++ b/quickview/view_manager.py @@ -11,7 +11,6 @@ GetColorTransferFunction, AddCameraLink, Render, - GetActiveView, ) from quickview.pipeline import EAMVisSource @@ -218,6 +217,7 @@ def update_views_for_timestep(self): return data = sm.Fetch(self.source.views["atmosphere_data"]) + first_view = None for var, context in self.registry.items(): varavg = self.compute_average(var, vtkdata=data) # Directly set average in trame state @@ -233,8 +233,12 @@ def update_views_for_timestep(self): self.sync_color_config_to_state(context.index, context) self.generate_colorbar_image(context.index) - view = GetActiveView() - view.ResetCamera(True, 0.9) + # Track the first view for camera fitting + if first_view is None and context.state.view_proxy: + first_view = context.state.view_proxy + + if first_view is not None: + first_view.ResetCamera(True, 0.9) def refresh_view_display(self, context: ViewContext): if not context.config.override_range: diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9216547..fa96a91 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "app" -version = "0.1.18" +version = "0.1.19" description = "QuickView: Visual Analyis for E3SM Atmosphere Data" authors = ["Kitware"] license = "" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 19b2ec1..358f3f9 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ }, "package": { "productName": "QuickView", - "version": "0.1.18" + "version": "0.1.19" }, "tauri": { "allowlist": {