Skip to content

Commit 9d8418a

Browse files
committed
Merge branch 'quickview'
2 parents 003f269 + 92a800c commit 9d8418a

10 files changed

Lines changed: 147 additions & 68 deletions

File tree

docs/setup/for_app_developers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ pip install -e .
3333

3434
To launch the EAM QuickView GUI in its dedicated window, use
3535
```
36-
python -m quickview.app --data /path/to/your/data.nc --conn /path/to/connectivity.nc
36+
quickview -data /path/to/your/data.nc --con /path/to/connectivity.nc
3737
```
3838

3939
To launch server only (no browser popup), use
4040
```
41-
python -m quickview.app --data /path/to/your/data.nc --conn /path/to/connectivity.nc --server
41+
quickview -df /path/to/your/data.nc -cf /path/to/connectivity.nc --server
4242
```
4343

4444
----

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ tauri = [
4040
vue2 = [
4141
"trame-grid-layout>=1.0.3",
4242
]
43+
jupyter = [
44+
"jupyter-server-proxy>=4.0.0",
45+
]
4346

4447

4548
[build-system]
@@ -53,6 +56,7 @@ include = [
5356
"/src/e3sm_quickview/data/**",
5457
"/src/e3sm_quickview/assets/**",
5558
"/src/e3sm_quickview/module/**",
59+
"/src/e3sm_quickview/jupyter/**",
5660
]
5761

5862
[tool.hatch.build.targets.wheel]
@@ -64,6 +68,9 @@ packages = [
6468
quickview-vue2 = "e3sm_quickview.app:main"
6569
quickview = "e3sm_quickview.app:main"
6670

71+
[project.entry-points."jupyter_serverproxy_servers"]
72+
quickview = "e3sm_quickview.jupyter:setup_quickview"
73+
6774
[tool.ruff.lint.per-file-ignores]
6875
# Ignore star import issues in ParaView plugins
6976
"e3sm_quickview/plugins/*.py" = ["F403", "F405"]

src/e3sm_quickview/app.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import asyncio
2-
import json
32
import datetime
3+
import json
44
import os
5-
65
from pathlib import Path
76

87
from trame.app import TrameApp, asynchronous, file_upload
8+
from trame.decorators import change, controller, life_cycle, trigger
99
from trame.ui.vuetify3 import VAppLayout
10-
from trame.widgets import vuetify3 as v3, client, html, dataclass, trame as tw, tauri
11-
from trame.decorators import controller, change, trigger, life_cycle
10+
from trame.widgets import client, dataclass, html, tauri
11+
from trame.widgets import trame as tw
12+
from trame.widgets import vuetify3 as v3
1213

1314
from e3sm_quickview import module as qv_module
1415
from e3sm_quickview.assets import ASSETS
15-
from e3sm_quickview.components import doc, file_browser, css, toolbars, dialogs, drawers
16+
from e3sm_quickview.components import css, dialogs, doc, drawers, file_browser, toolbars
1617
from e3sm_quickview.pipeline import EAMVisSource
17-
from e3sm_quickview.utils import compute, cli
18+
from e3sm_quickview.utils import cli, compute
1819
from e3sm_quickview.view_manager import ViewManager
1920

20-
2121
v3.enable_lab()
2222

2323

@@ -138,7 +138,7 @@ def _build_ui(self, **_):
138138
UploadState="utils.get('document').querySelector('#fileUpload').click()",
139139
ToggleHelp="compact_drawer = !compact_drawer",
140140
) as mt:
141-
mt.bind(["r"], "ResetCamera")
141+
mt.bind(["z"], "ResetCamera")
142142
mt.bind(["alt+0", "0"], "SizeAuto")
143143
mt.bind(["alt+1", "1"], "Size1")
144144
mt.bind(["alt+2", "2"], "Size2")
@@ -147,17 +147,17 @@ def _build_ui(self, **_):
147147
mt.bind(["alt+6", "6"], "Size6")
148148
mt.bind(["="], "SizeFlow")
149149

150-
mt.bind("e", "ProjectionEquidistant")
151-
mt.bind("b", "ProjectionRobinson")
150+
mt.bind("c", "ProjectionEquidistant")
151+
mt.bind("r", "ProjectionRobinson")
152152
mt.bind("m", "ProjectionMollweide")
153153

154154
mt.bind("f", "FileOpen")
155155
mt.bind("d", "SaveState")
156156
mt.bind("u", "UploadState")
157157
mt.bind("h", "ToggleHelp")
158158

159-
mt.bind("l", "ToolbarLayout")
160-
mt.bind("c", "ToolbarCrop")
159+
mt.bind("p", "ToolbarLayout")
160+
mt.bind("l", "ToolbarCrop")
161161
mt.bind("s", "ToolbarSelect")
162162
mt.bind("a", "ToolbarAnimation")
163163
mt.bind("g", "ToggleGroups")
@@ -388,7 +388,7 @@ async def data_loading_open(self, simulation_files, connectivity):
388388
*(
389389
{
390390
"name": var.name,
391-
"type": str(var.dimensions),
391+
"type": ", ".join(var.dimensions),
392392
"id": f"{var.name}",
393393
}
394394
for _, var in self.source.varmeta.items()
@@ -399,7 +399,10 @@ async def data_loading_open(self, simulation_files, connectivity):
399399
from e3sm_quickview.utils.colors import get_type_color
400400

401401
dim_types = sorted(
402-
set(str(var.dimensions) for var in self.source.varmeta.values())
402+
set(
403+
", ".join(var.dimensions)
404+
for var in self.source.varmeta.values()
405+
)
403406
)
404407
self.state.variable_types = [
405408
{"name": t, "color": get_type_color(i)}

src/e3sm_quickview/components/doc.py

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from trame.widgets import vuetify3 as v3, html
2-
from e3sm_quickview.assets import ASSETS
1+
from trame.widgets import html
2+
from trame.widgets import vuetify3 as v3
33

4+
from e3sm_quickview.assets import ASSETS
45

56
# -----------------------------------------------------------------------------
67
# Tools
@@ -22,7 +23,7 @@ def __init__(self, icon, title, description):
2223
class ToolFileLoading(Tool):
2324
def __init__(self):
2425
super().__init__(
25-
icon="mdi-file-document-outline",
26+
icon="mdi-file-upload-outline",
2627
title="File loading",
2728
description="Load files to explore. Those could be simulation and connectivity files or even a state file pointing to those files.",
2829
)
@@ -34,9 +35,9 @@ class ToolFieldSelection(Tool):
3435
def __init__(self):
3536
super().__init__(
3637
icon="mdi-list-status",
37-
title="Fields selection",
38+
title="Variable selection",
3839
description="""
39-
Select the variables to visualize. You need to load files prior any field selection.
40+
Select the variables to visualize. You need to load files prior any variable selection.
4041
""",
4142
)
4243
with self, v3.Template(v_slot_append=True):
@@ -46,12 +47,12 @@ def __init__(self):
4647
class ToolResetCamera(Tool):
4748
def __init__(self):
4849
super().__init__(
49-
icon="mdi-crop-free",
50-
title="Reset camera",
50+
icon="mdi-fit-to-page-outline",
51+
title="Auto zoom",
5152
description="Recenter the visualizations to the full data.",
5253
)
5354
with self, v3.Template(v_slot_append=True):
54-
v3.VHotkey(keys="r", variant="contained", inline=True)
55+
v3.VHotkey(keys="z", variant="contained", inline=True)
5556

5657

5758
class ToolStateImportExport(Tool):
@@ -74,31 +75,31 @@ def __init__(self):
7475
description="Select projection to use for the visualizations. (Cylindrical Equidistant, Robinson, Mollweide)",
7576
)
7677
with self, v3.Template(v_slot_append=True):
77-
v3.VHotkey(keys="e", variant="contained", inline=True)
78-
v3.VHotkey(keys="b", variant="contained", inline=True)
78+
v3.VHotkey(keys="c", variant="contained", inline=True)
79+
v3.VHotkey(keys="r", variant="contained", inline=True)
7980
v3.VHotkey(keys="m", variant="contained", inline=True)
8081

8182

8283
class ToolLayoutManagement(Tool):
8384
def __init__(self):
8485
super().__init__(
8586
icon="mdi-collage",
86-
title="Layout management",
87-
description="Toggle layout toolbar for adjusting aspect-ratio, width and grouping options.",
87+
title="Viewport layout",
88+
description="Toggle viewport layout toolbar for adjusting aspect-ratio, width and grouping options.",
8889
)
8990
with self, v3.Template(v_slot_append=True):
90-
v3.VHotkey(keys="l", variant="contained", inline=True)
91+
v3.VHotkey(keys="p", variant="contained", inline=True)
9192

9293

9394
class ToolCropping(Tool):
9495
def __init__(self):
9596
super().__init__(
96-
icon="mdi-crop",
97+
icon="mdi-web",
9798
title="Lat/Long cropping",
9899
description="Toggle cropping toolbar for adjusting spacial bounds.",
99100
)
100101
with self, v3.Template(v_slot_append=True):
101-
v3.VHotkey(keys="c", variant="contained", inline=True)
102+
v3.VHotkey(keys="l", variant="contained", inline=True)
102103

103104

104105
class ToolDataSelection(Tool):
@@ -115,7 +116,7 @@ def __init__(self):
115116
class ToolAnimation(Tool):
116117
def __init__(self):
117118
super().__init__(
118-
icon="mdi-movie-open-cog-outline",
119+
icon="mdi-video",
119120
title="Animation controls",
120121
description="Toggle animation toolbar.",
121122
)
@@ -184,7 +185,7 @@ def __init__(self):
184185
{Bold("EAM QuickView")} is an open-source, interactive visualization
185186
tool designed for scientists working with the atmospheric component
186187
of the {Link("Energy Exascale Earth System Model (E3SM)", "https://e3sm.org/")},
187-
known as the E3SM Atmosphere Model (EAM).
188+
known as the E3SM Atmosphere Model (EAM).
188189
Its Python- and {Link("Trame", "https://www.kitware.com/trame/")}-based
189190
Graphical User Interface (GUI) provides intuitive access to {Link("ParaView's", "https://www.paraview.org/")} powerful analysis
190191
and visualization capabilities, without the steep learning curve.
@@ -221,9 +222,9 @@ def __init__(self):
221222
v3.VHotkey(keys="h", variant="contained", inline=True)
222223

223224
with v3.VRow(classes="ma-0 pb-4"):
224-
v3.VLabel("Reset Camera")
225+
v3.VLabel("Auto zoom")
225226
v3.VSpacer()
226-
v3.VHotkey(keys="r", variant="contained", inline=True)
227+
v3.VHotkey(keys="z", variant="contained", inline=True)
227228

228229
with v3.VRow(classes="ma-0 pb-4"):
229230
v3.VLabel("Toggle view interaction lock")
@@ -250,13 +251,13 @@ def __init__(self):
250251
v3.VDivider(classes="mb-4")
251252

252253
with v3.VRow(classes="ma-0 pb-4"):
253-
v3.VLabel("Toggle Layout management toolbar")
254+
v3.VLabel("Toggle viewport layout toolbar")
254255
v3.VSpacer(classes="mt-2")
255-
v3.VHotkey(keys="l", variant="contained", inline=True)
256+
v3.VHotkey(keys="p", variant="contained", inline=True)
256257
with v3.VRow(classes="ma-0 pb-4"):
257258
v3.VLabel("Toggle Lat/Long cropping toolbar")
258259
v3.VSpacer()
259-
v3.VHotkey(keys="c", variant="contained", inline=True)
260+
v3.VHotkey(keys="l", variant="contained", inline=True)
260261
with v3.VRow(classes="ma-0 pb-4"):
261262
v3.VLabel("Toggle Slice selection toolbar")
262263
v3.VSpacer()
@@ -292,10 +293,10 @@ def __init__(self):
292293
with v3.VList(density="compact", classes="pa-0 ma-0"):
293294
with v3.VListItem(subtitle="Cylindrical Equidistant"):
294295
with v3.Template(v_slot_append="True"):
295-
v3.VHotkey(keys="e", variant="contained", inline=True)
296+
v3.VHotkey(keys="c", variant="contained", inline=True)
296297
with v3.VListItem(subtitle="Robinson"):
297298
with v3.Template(v_slot_append="True"):
298-
v3.VHotkey(keys="b", variant="contained", inline=True)
299+
v3.VHotkey(keys="r", variant="contained", inline=True)
299300
with v3.VListItem(subtitle="Mollweide"):
300301
with v3.Template(v_slot_append="True"):
301302
v3.VHotkey(keys="m", variant="contained", inline=True)
@@ -334,7 +335,7 @@ def __init__(self):
334335
"""
335336
QuickView has been developed using EAM's history output on
336337
the physics grids (pg2 grids) written by EAMv2, v3, and an
337-
intermediate version towards v4 (EAMxx).
338+
intermediate version towards v4 (EAMxx).
338339
Those sample output files can be found on Zenodo.
339340
"""
340341
)

src/e3sm_quickview/components/drawers.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from trame.decorators import change
2-
from trame.widgets import html, vuetify3 as v3
2+
from trame.widgets import html
3+
from trame.widgets import vuetify3 as v3
34

45
from e3sm_quickview import __version__ as quickview_version
56
from e3sm_quickview.components import css, tools
6-
from e3sm_quickview.utils import js, constants
7+
from e3sm_quickview.utils import constants, js
78

89

910
class Tools(v3.VNavigationDrawer):
@@ -24,24 +25,28 @@ def __init__(self, reset_camera=None):
2425
v_model_selected=("active_tools", ["load-data"]),
2526
):
2627
tools.AppLogo()
27-
tools.OpenFile()
28-
tools.FieldSelection()
29-
tools.MapProjection()
3028
tools.ResetCamera(click=reset_camera)
3129

3230
v3.VDivider(classes="my-1") # ---------------------
3331

34-
tools.LayoutManagement()
35-
tools.Cropping()
32+
tools.StateImportExport()
33+
tools.OpenFile()
34+
35+
v3.VDivider(classes="my-1") # ---------------------
36+
37+
tools.FieldSelection()
3638
tools.DataSelection()
3739
tools.Animation()
3840

3941
v3.VDivider(classes="my-1") # ---------------------
4042

41-
tools.StateImportExport()
43+
tools.LayoutManagement()
44+
tools.MapProjection()
45+
tools.Cropping()
4246

4347
# dev add-on ui reload
4448
if self.server.hot_reload:
49+
v3.VDivider(classes="my-1") # ---------------------
4550
tools.ActionButton(
4651
compact="compact_drawer",
4752
title="Refresh UI",
@@ -112,7 +117,8 @@ def __init__(self, load_variables=None):
112117
hide_details=True,
113118
)
114119

115-
with v3.VCardActions(classes="px-2"):
120+
# with v3.VCardActions(classes="px-2"):
121+
with v3.VCardActions(classes="pb-0", style="min-height: 0;"):
116122
v3.VBtn(
117123
classes="text-none",
118124
color="primary",
@@ -126,6 +132,27 @@ def __init__(self, load_variables=None):
126132
"variables_selected.length === 0 || variables_loaded",
127133
),
128134
click=load_variables,
135+
block=True,
136+
)
137+
with v3.VCardActions(
138+
key="variables_selected.length",
139+
classes="flex-wrap py-1",
140+
style="overflow-y: auto; max-height: 100px; min-height: 42px;",
141+
):
142+
v3.VChip(
143+
"{{ variables_selected.filter(id => variables_listing.find(v => v.id === id)?.type === vtype.name).length }} {{ vtype.name }}",
144+
v_for="(vtype, idx) in variable_types",
145+
key="idx",
146+
color=("vtype.color",),
147+
v_show=(
148+
"variables_selected.filter(id => variables_listing.find(v => v.id === id)?.type === vtype.name).length",
149+
),
150+
size="small",
151+
closable=True,
152+
click_close=(
153+
"variables_selected = variables_selected.filter(id => variables_listing.find(v => v.id === id)?.type !== vtype.name)"
154+
),
155+
classes="ma-1",
129156
)
130157

131158
v3.VTextField(

0 commit comments

Comments
 (0)