From 051cd976dbf011a84328716f19555375c3c80dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Therese=20Natter=C3=B8y?= <61694854+tnatt@users.noreply.github.com> Date: Thu, 3 Aug 2023 10:35:33 +0200 Subject: [PATCH] Add filter linking in `SimulationTimeseriesOneByOne` (#1227) * Add filter linking in SimulationTimeseriesOneByOne * changelog --- CHANGELOG.md | 5 +++ ...mulation_time_series_onebyone_datamodel.py | 6 ++++ .../_settings/_sensitivity_filter.py | 21 +++++++++++- .../_views/_onebyone_view/_view.py | 34 +++++++++++++++++-- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bd120f44..73143c29e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [UNRELEASED] - YYYY-MM-DD +### Added +- [#1227](https://github.com/equinor/webviz-subsurface/pull/1227) - New functionality in `SimulationTimeSeriesOneByOne`: option to use the sensitivity filter on all visualisations, not only the timeseries. + +## [0.2.20] - 2023-06-26 + ### Added - [#1217](https://github.com/equinor/webviz-subsurface/pull/1217) - New plugin `SimulationTimeSeriesOneByOne`, meant to replace the old `ReservoirSimulationTimeSeriesOneByOne`. Uses the `.arrow` summary provider and is implemented with WLF (Webviz Layout Framework). diff --git a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_utils/_simulation_time_series_onebyone_datamodel.py b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_utils/_simulation_time_series_onebyone_datamodel.py index 360c9a09b..efb1e749c 100644 --- a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_utils/_simulation_time_series_onebyone_datamodel.py +++ b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_utils/_simulation_time_series_onebyone_datamodel.py @@ -148,6 +148,12 @@ def get_tornado_reference(sensitivities: List[str], existing_reference: str) -> return "rms_seed" return sensitivities[0] + @staticmethod + def get_realizations_for_sensitivies( + sens_df: pd.DataFrame, sensitivities: List[str] + ) -> List[int]: + return list(sens_df[sens_df["SENSNAME"].isin(sensitivities)]["REAL"].unique()) + def create_tornado_figure( self, tornado_data: TornadoData, diff --git a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_settings/_sensitivity_filter.py b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_settings/_sensitivity_filter.py index 4a624adcc..423127ada 100644 --- a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_settings/_sensitivity_filter.py +++ b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_settings/_sensitivity_filter.py @@ -1,6 +1,7 @@ from typing import List import webviz_core_components as wcc +from dash import html from dash.development.base_component import Component from webviz_config.utils import StrEnum from webviz_config.webviz_plugin_subclasses import SettingsGroupABC @@ -9,6 +10,7 @@ class SensitivityFilter(SettingsGroupABC): class Ids(StrEnum): SENSITIVITY_FILTER = "sensitivity-filter" + SENSITIVITY_FILTER_LINK = "sensitivity-filter-link" def __init__(self, sensitivities: List[str]) -> None: super().__init__("Sensitivity Filter") @@ -16,10 +18,27 @@ def __init__(self, sensitivities: List[str]) -> None: def layout(self) -> List[Component]: return [ + html.Div( + style={"margin-bottom": "10px"}, + children=[ + wcc.Checklist( + id=self.register_component_unique_id( + self.Ids.SENSITIVITY_FILTER_LINK + ), + options=[ + { + "label": "Apply filter only on timeseries", + "value": "no link", + } + ], + value=[], + ), + ], + ), wcc.SelectWithLabel( id=self.register_component_unique_id(self.Ids.SENSITIVITY_FILTER), options=[{"label": i, "value": i} for i in self._sensitivities], value=self._sensitivities, size=min(20, len(self._sensitivities)), - ) + ), ] diff --git a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_view.py b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_view.py index 43e7eea72..73f7f2f55 100644 --- a/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_view.py +++ b/webviz_subsurface/plugins/_simulation_time_series_onebyone/_views/_onebyone_view/_view.py @@ -123,7 +123,7 @@ def _update_options(option_values: list, options_id: List[dict]) -> dict: def _update_realization_store(sensitivites: list, ensemble: str) -> List[int]: """Update graph with line coloring, vertical line and title""" df = self._data_model.get_sensitivity_dataframe_for_ensemble(ensemble) - return list(df[df["SENSNAME"].isin(sensitivites)]["REAL"].unique()) + return self._data_model.get_realizations_for_sensitivies(df, sensitivites) @callback( Output( @@ -469,6 +469,19 @@ def _update_timeseries_figure( ), "data", ), + Input( + self.settings_group_unique_id( + self.Ids.SETTINGS, GeneralSettings.Ids.REAL_STORE + ), + "data", + ), + Input( + self.settings_group_unique_id( + self.Ids.SENSITIVITY_FILTER, + SensitivityFilter.Ids.SENSITIVITY_FILTER_LINK, + ), + "value", + ), State( self.settings_group_unique_id( self.Ids.SELECTIONS, Selections.Ids.ENSEMBLE @@ -478,18 +491,35 @@ def _update_timeseries_figure( ) @callback_typecheck def _update_tornadoplot( - date: str, selections: dict, vector: str, ensemble: str + date: str, + selections: dict, + vector: str, + realizations: List[int], + sensfilter_only_timeseries: list, + ensemble: str, ) -> tuple: if selections is None or selections[ "Reference" ] not in self._data_model.get_unique_sensitivities_for_ensemble(ensemble): raise PreventUpdate + sens_df = self._data_model.get_sensitivity_dataframe_for_ensemble(ensemble) + + # make sure the tornado reference is included if sensitivity filter is used + if not sensfilter_only_timeseries: + reference_realizations = ( + self._data_model.get_realizations_for_sensitivies( + sens_df, sensitivities=[selections["Reference"]] + ) + ) + realizations = list(set(reference_realizations + realizations)) + # Get dataframe with vectors and dataframe with parameters and merge vector_df = self._data_model.get_vectors_df( ensemble=ensemble, date=date_from_str(date), vector_names=[vector], + realizations=realizations if not sensfilter_only_timeseries else None, ) data = merge_dataframes_on_realization( dframe1=vector_df,