Skip to content

Commit

Permalink
Use view annotations in deckgl-based plugins (#1193)
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKallekleiv authored Feb 21, 2023
1 parent d65e805 commit 53ef4eb
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/subsurface.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
- name: 🕵️ Check code style & linting
run: |
black --check webviz_subsurface tests setup.py
# pylint webviz_subsurface tests setup.py
pylint webviz_subsurface tests setup.py
bandit -r -c ./bandit.yml webviz_subsurface tests setup.py
isort --check-only webviz_subsurface tests setup.py
mypy --package webviz_subsurface
Expand All @@ -92,7 +92,7 @@ jobs:
git clone --depth 1 --branch $TESTDATA_REPO_BRANCH https://github.com/$TESTDATA_REPO_OWNER/webviz-subsurface-testdata.git
# Copy any clientside script to the test folder before running tests
mkdir ./tests/assets && cp ./webviz_subsurface/_assets/js/* ./tests/assets
# pytest ./tests --headless --forked --testdata-folder ./webviz-subsurface-testdata
pytest ./tests --headless --forked --testdata-folder ./webviz-subsurface-testdata
rm -rf ./tests/assets
webviz docs --portable ./docs_build --skip-open
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def encode_partial_url(

def _setup_url_rule(self, app: Dash) -> None:
@app.server.route(_ROOT_URL_PATH + "/<full_surf_address_str>")
def _handle_surface_request(full_surf_address_str: str) -> flask.Response:
def _handle_surface_array_request(full_surf_address_str: str) -> flask.Response:
LOGGER.debug(
f"Handling surface_request: "
f"full_surf_address_str={full_surf_address_str} "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def encode_partial_url(

def _setup_url_rule(self, app: Dash) -> None:
@app.server.route(_ROOT_URL_PATH + "/<full_surf_address_str>")
def _handle_surface_request(full_surf_address_str: str) -> flask.Response:
def _handle_surface_image_request(full_surf_address_str: str) -> flask.Response:
LOGGER.debug(
f"Handling surface_request: "
f"full_surf_address_str={full_surf_address_str} "
Expand Down
21 changes: 15 additions & 6 deletions webviz_subsurface/plugins/_co2_leakage/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from webviz_subsurface._providers import FaultPolygonsServer, SurfaceImageServer
from webviz_subsurface.plugins._co2_leakage._utilities.callbacks import (
SurfaceData,
create_map_annotations,
create_map_layers,
create_map_viewports,
derive_surface_address,
get_plume_polygon,
property_origin,
Expand Down Expand Up @@ -124,18 +126,18 @@ def __init__(
self._error_message = f"Plugin initialization failed: {err}"
raise

color_tables = co2leakage_color_tables()
self._color_tables = co2leakage_color_tables()
self.add_shared_settings_group(
ViewSettings(
self._ensemble_paths,
self._ensemble_surface_providers,
initial_surface,
self._map_attribute_names,
[c["name"] for c in color_tables], # type: ignore
[c["name"] for c in self._color_tables], # type: ignore
),
self.Ids.MAIN_SETTINGS,
)
self.add_view(MainView(color_tables), self.Ids.MAIN_VIEW)
self.add_view(MainView(self._color_tables), self.Ids.MAIN_VIEW)

@property
def layout(self) -> html.Div:
Expand Down Expand Up @@ -213,6 +215,8 @@ def toggle_date_slider(attribute: str) -> Dict[str, str]:
# pylint: disable=too-many-arguments,too-many-locals
@callback(
Output(self._view_component(MapViewElement.Ids.DECKGL_MAP), "layers"),
Output(self._view_component(MapViewElement.Ids.DECKGL_MAP), "children"),
Output(self._view_component(MapViewElement.Ids.DECKGL_MAP), "views"),
Input(self._settings_component(ViewSettings.Ids.PROPERTY), "value"),
Input(self._view_component(MapViewElement.Ids.DATE_SLIDER), "value"),
Input(self._settings_component(ViewSettings.Ids.FORMATION), "value"),
Expand Down Expand Up @@ -241,7 +245,7 @@ def update_map_attribute(
plume_threshold: Optional[float],
plume_smoothing: Optional[float],
ensemble: str,
) -> List[Dict[str, Any]]:
) -> Tuple[List[Dict[Any, Any]], List[Any], Dict[Any, Any]]:
attribute = MapAttribute(attribute)
if len(realization) == 0:
raise PreventUpdate
Expand Down Expand Up @@ -302,5 +306,10 @@ def update_map_attribute(
well_pick_provider=self._well_pick_provider,
plume_extent_data=plume_polygon,
)

return layers
annotations = create_map_annotations(
formation=formation,
surface_data=surf_data,
colortables=self._color_tables,
)
viewports = create_map_viewports()
return (layers, annotations, viewports)
49 changes: 49 additions & 0 deletions webviz_subsurface/plugins/_co2_leakage/_utilities/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import geojson
import numpy as np
import webviz_subsurface_components as wsc

from webviz_subsurface._providers import (
EnsembleSurfaceProvider,
Expand Down Expand Up @@ -166,6 +167,54 @@ def get_plume_polygon(
)


def create_map_annotations(
formation: str,
surface_data: Optional[SurfaceData],
colortables: List[Dict[str, Any]],
) -> List[wsc.ViewAnnotation]:
annotations = []
if surface_data is not None:
annotations.append(
wsc.ViewAnnotation(
id="1_view",
children=[
wsc.WebVizColorLegend(
min=surface_data.color_map_range[0],
max=surface_data.color_map_range[1],
colorName=surface_data.color_map_name,
cssLegendStyles={"top": "0", "right": "0"},
openColorSelector=False,
legendScaleSize=0.1,
legendFontSize=30,
colorTables=colortables,
),
wsc.ViewFooter(children=formation),
],
)
)
return annotations


def create_map_viewports() -> Dict:
return {
"layout": [1, 1],
"viewports": [
{
"id": "1_view",
"show3D": False,
"isSync": True,
"layerIds": [
"colormap-layer",
"fault-polygons-layer",
"license-boundary-layer",
"well-picks-layer",
"plume-polygon-layer",
],
}
],
}


def create_map_layers(
formation: str,
surface_data: Optional[SurfaceData],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dash.development.base_component import Component
from webviz_config.utils import StrEnum
from webviz_config.webviz_plugin_subclasses import ViewABC, ViewElementABC
from webviz_subsurface_components import DeckGLMap
from webviz_subsurface_components import DashSubsurfaceViewer


class MainView(ViewABC):
Expand Down Expand Up @@ -41,14 +41,13 @@ def inner_layout(self) -> Component:
children=[
html.Div(
[
DeckGLMap(
DashSubsurfaceViewer(
id=self.register_component_unique_id(
self.Ids.DECKGL_MAP
),
layers=[],
coords={"visible": True},
scale={"visible": True},
toolbar={"visible": True},
coordinateUnit="m",
colorTables=self._color_scales,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import jwt
import numpy as np
import webviz_subsurface_components as wsc
from dash import Input, Output, State, callback, html, no_update
from webviz_config.utils import StrEnum
from webviz_config.webviz_plugin_subclasses import ViewABC
Expand Down Expand Up @@ -191,9 +192,9 @@ def _set_geometry_and_scalar(
else:
value_range = None

layers[1]["pointsUrl"] = f"/grid/points/{geometry_token}"
layers[1]["polysUrl"] = f"/grid/polys/{geometry_token}"
layers[1]["propertiesUrl"] = f"/grid/scalar/{geometry_and_property_token}"
layers[1]["pointsData"] = f"/grid/points/{geometry_token}"
layers[1]["polysData"] = f"/grid/polys/{geometry_token}"
layers[1]["propertiesData"] = f"/grid/scalar/{geometry_and_property_token}"
layers[1]["colorMapRange"] = value_range
layers[1]["colorMapName"] = colormap
return layers, bounds
Expand All @@ -219,6 +220,10 @@ def _toggle_manual_color(enabled: List[str]) -> Tuple[bool, bool]:

@callback(
Output(self._view_id(VTKView3D.Ids.INFOBOX), "children"),
Output(
self._view_id(VTKView3D.Ids.VIEW),
"children",
),
Input(
self._data_settings_id(DataSettings.Ids.PROPERTIES),
"value",
Expand All @@ -236,6 +241,10 @@ def _toggle_manual_color(enabled: List[str]) -> Tuple[bool, bool]:
"layers",
),
Input(self.get_store_unique_id(ElementIds.IJK_CROP_STORE), "data"),
Input(
self._color_scale_id(ColorScale.Ids.COLORMAP),
"value",
),
State(
self._data_settings_id(DataSettings.Ids.STATIC_DYNAMIC),
"value",
Expand All @@ -247,8 +256,9 @@ def update_infobox(
realizations: List[int],
layers: List[dict],
grid_range: List[List[int]],
colormap: str,
proptype: str,
) -> list:
) -> Tuple[List, List]:
"""Updates the information box with information on the visualized data."""
if PROPERTYTYPE(proptype) == PROPERTYTYPE.STATIC:
property_spec = PropertySpec(prop_name=properties[0], prop_date=None)
Expand Down Expand Up @@ -284,7 +294,22 @@ def update_infobox(
color_range = layers[1].get("colorMapRange")
if color_range is None:
color_range = actual_value_range

children = [
wsc.ViewAnnotation(
id="view_1",
children=[
wsc.WebVizColorLegend(
min=color_range[0],
max=color_range[1],
colorName=colormap,
cssLegendStyles={"top": "0", "right": "0"},
openColorSelector=False,
legendScaleSize=0.1,
legendFontSize=30,
),
],
)
]
return [
html.Div([html.B("Property: "), html.Label(properties[0])]),
html.Div(
Expand All @@ -305,4 +330,4 @@ def update_infobox(
),
]
),
]
], children
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from dash.development.base_component import Component
from webviz_config.utils import StrEnum
from webviz_config.webviz_plugin_subclasses import ViewElementABC
from webviz_subsurface_components import DeckGLMap
from webviz_subsurface_components import DashSubsurfaceViewer


class VTKView3D(ViewElementABC):
Expand Down Expand Up @@ -45,7 +45,7 @@ def inner_layout(self) -> Component:
html.Div(
style={"position": "absolute", "width": "100%", "height": "90%"},
children=[
DeckGLMap(
DashSubsurfaceViewer(
id=self.register_component_unique_id(VTKView3D.Ids.VIEW),
layers=[
{
Expand All @@ -64,11 +64,7 @@ def inner_layout(self) -> Component:
"@@type": "Grid3DLayer",
"id": "Grid3DLayer",
"material": True,
"colorMapName": "Physics reverse",
"scaleZ": 1,
"pointsUrl": "/grid/points/test",
"polysUrl": "/grid/polys/test",
"propertiesUrl": "/grid/scalar/test",
},
],
views={
Expand Down
67 changes: 46 additions & 21 deletions webviz_subsurface/plugins/_map_viewer_fmu/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Union

import numpy as np
import webviz_subsurface_components as wsc
from dash import ALL, MATCH, Input, Output, State, callback, callback_context, no_update
from dash.exceptions import PreventUpdate
from webviz_config import EncodedFile
Expand Down Expand Up @@ -306,6 +307,7 @@ def _update_color_store(
Output({"id": get_uuid(LayoutElements.DECKGLMAP), "tab": MATCH}, "layers"),
# Output({"id": get_uuid(LayoutElements.DECKGLMAP), "tab": MATCH}, "bounds"),
Output({"id": get_uuid(LayoutElements.DECKGLMAP), "tab": MATCH}, "views"),
Output({"id": get_uuid(LayoutElements.DECKGLMAP), "tab": MATCH}, "children"),
Input(
{"id": get_uuid(LayoutElements.VERIFIED_VIEW_DATA), "tab": MATCH}, "data"
),
Expand Down Expand Up @@ -417,29 +419,52 @@ def _update_map(
)
},
)
viewports = []
view_annotations = []
for idx, data in enumerate(surface_elements):
view_annotations.append(
wsc.ViewAnnotation(
id=f"{idx}_view",
children=[
wsc.WebVizColorLegend(
min=data["color_range"][0],
max=data["color_range"][1],
colorName=data["colormap"],
cssLegendStyles={"top": "0", "right": "0"},
openColorSelector=False,
legendScaleSize=0.1,
legendFontSize=30,
),
wsc.ViewFooter(
children=make_viewport_label(
surface_elements[idx], tab_name, multi
)
),
],
)
)
viewports.append(
{
"id": f"{idx}_view",
"show3D": False,
"isSync": True,
"layerIds": [
f"{LayoutElements.MAP3D_LAYER}-{idx}",
f"{LayoutElements.FAULTPOLYGONS_LAYER}-{idx}",
f"{LayoutElements.WELLS_LAYER}-{idx}",
],
"name": make_viewport_label(surface_elements[idx], tab_name, multi),
}
)
views = {
"layout": view_layout(len(surface_elements), view_columns),
"showLabel": True,
"viewports": viewports,
}
return (
layer_model.layers,
# viewport_bounds if surface_elements else no_update,
{
"layout": view_layout(len(surface_elements), view_columns),
"showLabel": True,
"viewports": [
{
"id": f"{view}_view",
"show3D": False,
"isSync": True,
"layerIds": [
f"{LayoutElements.MAP3D_LAYER}-{view}",
f"{LayoutElements.FAULTPOLYGONS_LAYER}-{view}",
f"{LayoutElements.WELLS_LAYER}-{view}",
],
"name": make_viewport_label(
surface_elements[view], tab_name, multi
),
}
for view in range(len(surface_elements))
],
},
views,
view_annotations,
)

@callback(
Expand Down
Loading

0 comments on commit 53ef4eb

Please sign in to comment.