From 8bcf22bfd3b43d0bfb111f0cf5ddb16f9e2747c8 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 1 Jul 2022 08:39:02 +0200 Subject: [PATCH 01/54] new relperm plugin --- .../_relative_permeability/__init__.py | 2 + .../plugins/_relative_permeability/_error.py | 0 .../plugins/_relative_permeability/_plugin.py | 49 ++++ .../_relative_permeability/_plugin_ids.py | 20 ++ .../shared_settings/__init__.py | 0 .../shared_settings/_filter.py | 211 ++++++++++++++++++ .../view_elements/__init__.py | 1 + .../view_elements/_graph.py | 25 +++ .../_relative_permeability/views/__init__.py | 0 .../views/relperm_cappres/__init__.py | 0 .../views/relperm_cappres/_relcap.py | 170 ++++++++++++++ 11 files changed, 478 insertions(+) create mode 100644 webviz_subsurface/plugins/_relative_permeability/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/_error.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/_plugin.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/views/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py diff --git a/webviz_subsurface/plugins/_relative_permeability/__init__.py b/webviz_subsurface/plugins/_relative_permeability/__init__.py new file mode 100644 index 000000000..9b56906e9 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/__init__.py @@ -0,0 +1,2 @@ +from ._plugin import RelpermCappres + diff --git a/webviz_subsurface/plugins/_relative_permeability/_error.py b/webviz_subsurface/plugins/_relative_permeability/_error.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py new file mode 100644 index 000000000..ab11b4b7f --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -0,0 +1,49 @@ +# import from python +from typing import Type +from pathlib import Path + +# packages from installed stuff +from dash.development.base_component import Component +import pandas as pd +from webviz_config import WebvizPluginABC + +# own imports +from ._error import error +from ._plugin_ids import PlugInIDs # importing the namespace +from .shared_settings import Filter + +class RelativePermeability(WebvizPluginABC): + def __init__(self, path_to_relpermfile: Path ) -> None: + super().__init__(stretch=True) # super refer to class inhereted from, init from ABC + + # set a member, self first for all + self.error_message = "" + + # when reading from file must check that these are the keywords, if not raise ValueError + + try: + self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame + except PermissionError: + self.error_message = ( + f"Access to file '{path_to_relpermfile}' denied. " + f"Please check your path for '{path_to_relpermfile}' and make sure you have access to it." + ) + return + except FileNotFoundError: + self.error_message = ( + f"The file {path_to_relpermfile}' not found." + "Please check you path" + ) + return + except pd.errors.ParserError: + self.error_message = ( + f"The file '{path_to_relpermfile}' is not a valid csv file." + ) + except pd.errors.EmptyDataError: + self.error_message = ( + f"The file '{path_to_relpermfile}' is an empty file." + ) + except Exception: + self.error_message = ( + f"Unknown exception when trying to read '{path_to_relpermfile}" + ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py new file mode 100644 index 000000000..a0940369d --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py @@ -0,0 +1,20 @@ +class PlugInIDs: + class Stores: + class Selectors: + SATURATION_AXIS = "saturation-axis" + COLOR_BY = "color-by" + ENSAMBLES = "ensambles" + CURVES = "curves" + SATNUM = "satnum" # should we change to saturation number? or someting? + class Visualization: + LINE_TRACES = "line-traces" + Y_AXIS = "y-axis" + class SCALRecomendation: + SHOW_SCAL = "show-SCAL" # doesn't work? + + class RelCapViewGroup: + GROUP_NAME = "relcap" + RELCAP = "relcapview" + + class SharedSettings: + FILTER = "filter" diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py new file mode 100644 index 000000000..15f5dcbb3 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -0,0 +1,211 @@ +from typing import List + +from dash import callback, Input, Output +from dash.development.base_component import Component +import pandas as pd +from webviz_config.webviz_plugin_subclasses import SettingsGroupABC +import webviz_core_components as wcc + +from .._plugin_ids import PlugInIDs + +class Filter(SettingsGroupABC): + """ + Added by MoNezhadali 06.22 + """ + class Ids: + class Selectors: + SATURATION_AXIS="saturation-axis" + COLOR_BY="color-by" + ENSEMBLES="ensembles" + CURVES="curves" + SATNUM="satnum" + class Visualization: + LINE_TRACES="line-traces" + Y_AXIS="y-axis" + class SCALRecommendation: + SHOW_SCAL="show-scal" + + ## todo: the selectors will be defined here after getting to know the data + + class Selectors: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("Selectors") + + def layout(self) -> List(Component): + return [ + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), + label="Saturation axis", + options=[{"label":i, "value":i} for i in range(self.sat_axes)], + value=self.sat_axes[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), + label="Color by", + options=[{"label":i, "value":i} for i in range(self.color_options)], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), + label="Ensembles", + options=[{"label":i, "value":i} for i in range(self.ensembles)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + # This needs to be checked + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), + label="Curves", + options=[{"label":i, "value":i} for i in range(self.curves)], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), + label="Satnum", + options=[{"label":i, "value":i} for i in range(self.satnums)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + ), + ) + def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: + return saturation_axis + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + ), + ) + def _set_color_by(color_by: List[str]) -> List[str]: + return color_by + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", + ), + ) + def _set_ensembles(ensembles: List[str]) -> List[str]: + return ensembles + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", + ), + ) + def _set_curves(curves: List[str]) -> List[str]: + return curves + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", + ), + ) + def _set_saturation_axis(satnum: List[str]) -> List[str]: + return satnum + + + class Visualization: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("Visualization") + def layout(self) -> List(Component): + return [ + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), + label="Line traces", + options=[ + {"label":"Individual realization","value":"individual-realization"}, + {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, + ], + value="statistical-fanchart", + ), + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), + label="Y-axis", + options=[ + {"label":"Linear","value":"linear"}, + {"label":"Log", "value":"log"}, + ], + value="linear", + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", + ), + ) + def _set_line_traces(line_traces: List[str]) -> List[str]: + return line_traces + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", + ), + ) + def _set_y_axis(y_axis: List[str]) -> List[str]: + return y_axis + + + class Scal_recommendation: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("SCAL recommendation") + def layout(self) -> List(Component): + return [ + wcc.Checklist( + id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), + label="", + options=[ + { + "label": "Show SCAL", + "value": "show_scal", + }, + ] + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", + ), + ) + def _set_line_traces(line_traces: List[str]) -> List[str]: + return line_traces + + + \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py new file mode 100644 index 000000000..94087a9c5 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py @@ -0,0 +1 @@ +from ._graph import Graph \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py new file mode 100644 index 000000000..0352ce468 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py @@ -0,0 +1,25 @@ +from typing import Type +from dash.development.base_component import Component + +from webviz_config.webviz_plugin_subclasses import ViewElementABC +from webviz_core_components import Graph as WccGraph + +class Graph(ViewElementABC): + class IDs: + #pylint: disable=too-few-public-methods + GRAPH = "graph" + + def __init__(self,height : str = "43vh", both : bool = True) -> None: + super().__init__() + + + if both: + self.height = height + else: + self.height = "88vh" + + def inner_layout(self) -> Type[Component]: + return WccGraph( + id = self.register_component_unique_id(Graph.IDs.GRAPH), + style = {"height": self.height, "min-height": "300px"} + ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py new file mode 100644 index 000000000..750f2c7c1 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -0,0 +1,170 @@ +from typing import List, Tuple, Optional, Union +from pathlib import Path + +from dash import callback, Input, Output, State +import pandas as pd +import plotly.colors +from webviz_config.webviz_plugin_subclasses import ViewABC + +from ..._plugin_ids import PlugInIDs +from ...view_elements import Graph + +class RelpermCappres(ViewABC): + '''Add comment descibring the plugin''' + class IDs: + '''Different curves to be shown in the view''' + #pylint: disable=too-few-public-methods + # en ID pr view element; ett eller to view element? + # tror jeg går for to view elements + RELATIVE_PERMEABILIY = "reative-permeability" + CAPILAR_PRESSURE = "capilar-pressure" + + # don't think I need these + '''KRW = "KRW" + KROW = "KROW" + POW = "POW" + + class Saturations: + SW = "SW" + SO = "SO" + SG = "SG" + SL = "SL" + class RelpermFamilies: # the possible keywords in the data files needed in list + SWOF = "SWOF" + SGOF = "SGOF" + SLGOF = "SLGOF" + SWFN = "SWFN" + SGFN = "SGFN" + SOF3 = "SOF3"''' + + # maybe need to add a create csv file in the main class to create one csv file + + SATURATIONS = ["SW", "SO", "SG", "SL"] + RELPERM_FAMILIES = ["SWOF", "SGOF", "SLGOF","SWFN", "SGFN", "SOF3"] + ENSAMBLES = ["iter-0","iter-3"] + GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] + + # må ha en utvidet csv fil som har realization og ensamble kolonne + valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + SATURATIONS + GRAPHS) + + + # stat types; should include al so it works on all data (copied) + SATURATIONS = ["SW", "SO", "SG", "SL"] # only sw and sg are used so far + RELPERM_FAMILIES = { + 1: ["SWOF", "SGOF", "SLGOF"], # only SWOF and SGOF re use in test data + 2: ["SWFN", "SGFN", "SOF3"], + } + SCAL_COLORMAP = { + "Missing": "#ffff00", # using yellow if the curve could not be found + "KRW": "#0000aa", + "KRG": "#ff0000", + "KROG": "#00aa00", + "KROW": "#00aa00", + "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) + "PCOG": "#555555", + } + + + def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: + # scalfile: Path = None; sets the scal file to be used, if any + # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate + super().__init__("Relatve permeability") + + ''' Data funksjonaliteter + + Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) + -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) + -> Sat ax Sg: kan velge mellom KRG, KROG og POG + Alle disse har felles instilliner + + Gruppene er + -> KRW: Relative permeability to water + -> KRG: Rlative permeability to gas + -> KROW: Relative permeability of oil in prescence of water + -> KROG: Relative permeability of oil in prescence of gas afo liwuid saturation + -> POW/G: Pressure of Water/Gas + + Colr by: velger hvordan man skal fordele dataen innad i de tre gruppene -> ensamble, curve og satnum + -> Ensamble: velger hvilke og hvor mange iter du skal ha med og velger en satnum. plotter for hver iter + -> Curve: velger en iter og en satnum, plotter for hver gruppe/kurve + -> Satnum: velger en iter og en eler flere satnum, plotte for hver satnum + Men alle har alltid mulighet til velge hvilke(n) gruppe(r) man ønsker å inludere + + De tre ulike gruppene er hver sin graph i viewen; + KRx og KROx er plottet sammen mot samme y akse, alle har samme y akse + -> KROx: oppe fra venstre og ned til høyre + -> KRx: nede fra venstre og opp til høyre + -> POx: + ''' + ''' Data i fil + Filene er sortert etter realization; + each realization has iter-0 and iter-3 + share -> results -> relperm.csv + velger realization (99 ulike) og iter (2 uliker pr realization) -> totalt 198 filer + + I hver fil er dataen grupert nedover ettter satnum (og keyword?) + Så er det listet data først for SW og å for SG or alle satnums + + X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 + ''' + + # extracte the data for the different graphs from the data source relperm_df + self.relperm_df = relperm_df # sets the data frame + + # er det egt flere som kan kunne plottes, men siden det kuner tatt ensyn til sg og sw foreløpig er det bare disse? + # skal vi inludere for utvidelse eller bare markere hvor det kan legges inn? + + # df for SW og SG + self.df_SW = self.relperm_df[relperm_df["KEYWORD"] == "SGOF"] + self.df_SG = self.relperm_df[relperm_df["KEYWORD"] == "SWOF"] + + + self.satnum1 = self.relperm_df[self.relperm_df["SATNUM"] == 1] # dette er velidg ueffektivt, er 12 satnum + + + # creating the columns and row to define the setup of the view + column = self.add_column() + + first_row = column.make_row() + first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) + # change something in Graph() ot be able to get them in the same plot, or add them as on view element? + # need the height of the Graph() to vary wether we are suppoed to show to graphs or not + + second_row = column.make_row() + second_row.add_view_element(Graph(),RelpermCappres.IDs.CAPILAR_PRESSURE) + + # define the callbacks of the view + def set_callbacks(self) -> None: + # callback for the graphs + @callback( + Output(self.get_unique_id(Graph(),"figure")), # need to be changed + Input(self.uuid("color_by"), "value"), + Input(self.uuid("visualization"), "value"), + Input(self.uuid("ensemble"), "value"), + Input(self.uuid("curve"), "value"), + Input(self.uuid("satnum"), "value"), + Input(self.uuid("sataxis"), "value"), + Input(self.uuid("linlog"), "value"), + Input(self.uuid("scal"), "value"), + ) + def _update_graph(color_by, visualization, ensembles, curves, satnums, sataxis, linlog, scal) -> dict: + colors = plotly.colors.DEFAULT_PLOTLY_COLORS + + + # callback function for the ensamble selector + @callback( + Output(self.uuid("ensemble"), "multi"), + Output(self.uuid("ensemble"), "value"), + Input(self.uuid("color_by"), "value"), + State(self.uuid("stored_ensemble"), "data") #need to fin out how this works + ) + def _set_ensamble_selector(color_by, stored_ensemble): + """If ensemble is selected as color by, set the ensemble + selector to allow multiple selections, else use stored_ensemble + """ + + # callback function for the curve selector + @callback( + + ) + def _set_curve_selector() \ No newline at end of file From bc9f597de2b47f495f6a19bca62595575187e210 Mon Sep 17 00:00:00 2001 From: "Mohammad Nezhadali (OG SUB RPE)" Date: Tue, 5 Jul 2022 13:12:14 +0200 Subject: [PATCH 02/54] Add filter, update relperm plugin files --- setup.py | 1 + webviz_subsurface/plugins/__init__.py | 2 + .../_relative_permeability_new/__init__.py | 2 + .../_relative_permeability_new/_error.py | 4 + .../_relative_permeability_new/_plugin.py | 334 ++++++++++++++++++ .../_relative_permeability_new/_plugin_ids.py | 23 ++ .../shared_settings/__init__.py | 1 + .../shared_settings/_filter.py | 249 +++++++++++++ .../view_elements/__init__.py | 1 + .../view_elements/_graph.py | 25 ++ .../views/__init__.py | 0 .../views/relperm_cappres/__init__.py | 0 .../views/relperm_cappres/_relcap.py | 170 +++++++++ 13 files changed, 812 insertions(+) create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_error.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_plugin.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py diff --git a/setup.py b/setup.py index ed8716629..acd5f6359 100644 --- a/setup.py +++ b/setup.py @@ -57,6 +57,7 @@ "PropertyStatistics = webviz_subsurface.plugins:PropertyStatistics", "PvtPlot = webviz_subsurface.plugins:PvtPlot", "RelativePermeability = webviz_subsurface.plugins:RelativePermeability", + "RelativePermeabilityNew = webviz_subsurface.plugins:RelativePermeabilityNew", "ReservoirSimulationTimeSeries = webviz_subsurface.plugins:ReservoirSimulationTimeSeries", "ReservoirSimulationTimeSeriesOneByOne = webviz_subsurface.plugins:ReservoirSimulationTimeSeriesOneByOne", "ReservoirSimulationTimeSeriesRegional = webviz_subsurface.plugins:ReservoirSimulationTimeSeriesRegional", diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index 27a8548ac..b2f608245 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -65,3 +65,5 @@ from ._well_cross_section import WellCrossSection from ._well_cross_section_fmu import WellCrossSectionFMU from ._well_log_viewer import WellLogViewer + +from ._relative_permeability_new import RelativePermeabilityNew \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py new file mode 100644 index 000000000..18d0ad15c --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py @@ -0,0 +1,2 @@ +from ._plugin import RelativePermeabilityNew + diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_error.py b/webviz_subsurface/plugins/_relative_permeability_new/_error.py new file mode 100644 index 000000000..81d1380ac --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/_error.py @@ -0,0 +1,4 @@ +from dash import html + +def error(error_message: str) -> html.Div: + return html.Div(children=error_message, style={"color": "red"}) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py new file mode 100644 index 000000000..738c1ffa7 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -0,0 +1,334 @@ +# import from python builtin +from typing import Type, Optional, Union +from pathlib import Path + +# packages from installed packages +from dash.development.base_component import Component +import pandas as pd +from webviz_config import WebvizPluginABC, WebvizSettings +from webviz_config.common_cache import CACHE +from webviz_config.webviz_assets import WEBVIZ_ASSETS +from webviz_config.webviz_plugin_subclasses import ViewABC + +import webviz_subsurface + +# own imports +from ._error import error +from ._plugin_ids import PlugInIDs # importing the namespace +from .shared_settings import Filter, Selectors, Visualization , Scal_recommendation +from ..._datainput.fmu_input import load_csv +from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation + +class TestView(ViewABC): + class Ids: + # pylint: disable=too-few-public-methods + TestViewID = "test-view-id" + + def __init__(self, population_df: pd.DataFrame) -> None: + super().__init__("Population indicators") +""" +class RelativePermeabilityNew(WebvizPluginABC): + + ''' + def __init__( + self, + webviz_settings: WebvizSettings, + ensembles: list, + relpermfile: str = None, + scalfile: Path = None, + sheet_name: Optional[Union[str, int, list]] = None, + ): + ''' + def __init__(self, webviz_settings: WebvizSettings,relpermfile: str, ensembles: list, scalfile: Path = None,) -> None: + + + super().__init__() # super refer to class inhereted from, init from ABC + + # set a member, self first for all + self.error_message = "" + + WEBVIZ_ASSETS.add( + Path(webviz_subsurface.__file__).parent + / "_assets" + / "css" + / "block_options.css" + ) + + # when reading from file must check that these are the keywords, if not raise ValueError + + try: + #self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame + self.ens_paths = { + ens: WebvizSettings.shared_settings["scratch_ensembles"][ens] + for ens in ensembles + } + if relpermfile is not None: + self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) + except PermissionError: + self.error_message = ( + f"Access to file '{relpermfile}' denied. " + f"Please check your path for '{relpermfile}' and make sure you have access to it." + ) + return + except FileNotFoundError: + self.error_message = ( + f"The file {relpermfile}' not found." + "Please check you path" + ) + return + except pd.errors.ParserError: + self.error_message = ( + f"The file '{relpermfile}' is not a valid csv file." + ) + except pd.errors.EmptyDataError: + self.error_message = ( + f"The file '{relpermfile}' is an empty file." + ) + except Exception: + self.error_message = ( + f"Unknown exception when trying to read '{relpermfile}" + ) + + @property + def layout(self) -> Type[Component]: + return error(self.error_message) + ''' + """ + + +class RelativePermeabilityNew(WebvizPluginABC): + """Visualizes relative permeability and capillary pressure curves for FMU ensembles. + +--- + +* **`ensembles`:** Which ensembles in `shared_settings` to visualize. +* **`relpermfile`:** Local path to a csvfile in each realization with dumped relperm data. +* **`scalfile`:** Path to a reference file with SCAL recommendationed data. \ + Path to a single file, **not** per realization/ensemble. The path can be absolute or \ + relative to the `webviz` configuration. +* **`sheet_name`:** Which sheet to use for the `scalfile`, only relevant if `scalfile` is an \ + `xlsx` file (recommended to use csv files with `webviz`). + +--- +The minimum requirement is to define `ensembles`. + +If no `relpermfile` is defined, the relative permeability data will be extracted automatically +from the simulation decks of individual realizations using `fmu-ensemble`and `ecl2df` behind the +scenes. Note that this method can be very slow for larger data decks, and is therefore not +recommended unless you have a very simple model/data deck. + +`relpermfile` is a path to a file stored per realization (e.g. in \ +`share/results/tables/relperm.csv`). `relpermfile` columns: +* One column named `KEYWORD` or `TYPE`: with Flow/Eclipse style keywords (e.g. `SWOF` and `SGOF`). +* One column named `SATNUM` with integer `SATNUM` regions. +* One column **per** saturation (e.g. `SG` and `SW`). +* One column **per** relative permeability curve (e.g. `KRW`, `KROW` and `KRG`) +* One column **per** capillary pressure curve (e.g. `PCOW`). + +The `relpermfile` file can e.g. be dumped to disk per realization by a forward model in ERT that +wraps the command `ecl2csv satfunc input_file -o output_file` (requires that you have `ecl2df` +installed). A typical example could be: +`ecl2csv satfunc eclipse/include/props/relperm.inc -o share/results/tables/relperm.csv`. +[Link to ecl2csv satfunc documentation.](https://equinor.github.io/ecl2df/scripts.html#satfunc) + + +`scalfile` is a path to __a single file of SCAL recommendations__ (for all +realizations/ensembles). The file has to be compatible with +[pyscal's](https://equinor.github.io/pyscal/pyscal.html#pyscal.\ +factory.PyscalFactory.load_relperm_df) input format. Including this file adds reference cases +`Pess`, `Base` and `Opt` to the plots. This file is typically a result of a SCAL study. + +`sheet_name` defines the sheet to use in the `scalfile`. Only relevant if `scalfile` is an +`xlsx` file (it is recommended to use `csv` and not `xlsx` for `Webviz`). + +* [Example of relpermfile](https://github.com/equinor/webviz-subsurface-testdata/blob/master/\ +reek_history_match/realization-0/iter-0/share/results/tables/relperm.csv). +* [Example of scalfile](https://github.com/equinor/\ +webviz-subsurface-testdata/blob/master/reek_history_match/share/scal/scalreek.csv). +""" + class PlotOptions: + SATURATIONS = ["SW", "SO", "SG", "SL"] + RELPERM_FAMILIES = { + 1: ["SWOF", "SGOF", "SLGOF"], + 2: ["SWFN", "SGFN", "SOF3"], + } + SCAL_COLORMAP = { + "Missing": "#ffff00", # using yellow if the curve could not be found + "KRW": "#0000aa", + "KRG": "#ff0000", + "KROG": "#00aa00", + "KROW": "#00aa00", + "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) + "PCOG": "#555555", + } + + def __init__( + self, + webviz_settings: WebvizSettings, + ensembles: list, + relpermfile: str = None, + scalfile: Path = None, + sheet_name: Optional[Union[str, int, list]] = None, + ): + + super().__init__() + + WEBVIZ_ASSETS.add( + Path(webviz_subsurface.__file__).parent + / "_assets" + / "css" + / "block_options.css" + ) + try: + # self.ens_paths = { + # ens: webviz_settings.shared_settings["scratch_ensembles"][ens] + # for ens in ensembles + # } + # if relpermfile is not None: + # self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) + self.ens_paths = { + ens: webviz_settings.shared_settings["scratch_ensembles"][ens] + for ens in ensembles + } + self.plotly_theme = webviz_settings.theme.plotly_theme + self.relpermfile = relpermfile + if self.relpermfile is not None: + self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) + self.satfunc = self.satfunc.rename(str.upper, axis="columns").rename( + columns={"TYPE": "KEYWORD"} + ) + if "KEYWORD" not in self.satfunc.columns: + raise ValueError( + "There has to be a KEYWORD or TYPE column with corresponding Eclipse keyword: " + "e.g SWOF, SGOF and etc." + ) + valid_columns = ( + ["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + + self.PlotOptions.SATURATIONS + + [ + key + for key in self.PlotOptions.SCAL_COLORMAP + if key != "Missing" + ] + ) + self.satfunc = self.satfunc[ + [col for col in self.satfunc.columns if col in valid_columns] + ] + else: + self.satfunc = load_satfunc(self.ens_paths) + + if any( + keyword in self.PlotOptions.RELPERM_FAMILIES[1] + for keyword in self.satfunc["KEYWORD"].unique() + ): + self.family = 1 + if any( + keyword in self.PlotOptions.RELPERM_FAMILIES[2] + for keyword in self.satfunc["KEYWORD"].unique() + ): + warnings.warn( + ( + "Mix of keyword family 1 and 2, currently only support one family at the " + "time. Dropping all data of family 2 ('SWFN', 'SGFN', 'SGWFN', 'SOF2', " + "'SOF3', 'SOF32D') and continues with family 1 ('SWOF', 'SGOF', 'SLGOF')." + ), + ) + self.satfunc = self.satfunc[ + self.satfunc["KEYWORD"].isin( + self.PlotOptions.RELPERM_FAMILIES["fam1"] + ) + ] + if "SGOF" in self.satfunc["KEYWORD"].unique(): + if "SLGOF" in self.satfunc["KEYWORD"].unique(): + warnings.warn( + ( + "Mix of 'SGOF' and 'SLGOF' in ensembles, resulting in non-unique " + "horizontal axis ('SG' and 'SL') for 'KRG', 'KROG' and 'PCOG'. " + "Dropping all data with 'SLGOF'." + ), + ) + self.satfunc = self.satfunc[self.satfunc["KEYWORD"] != "SLGOF"] + self.sat_axes_maps = { + "SW": ["KRW", "KROW", "PCOW"], + "SG": ["KRG", "KROG", "PCOG"], + } + else: + self.sat_axes_maps = { + "SW": ["KRW", "KROW", "PCOW"], + "SL": ["KRG", "KROG", "PCOG"], + } + elif not all( + keyword in self.PlotOptions.RELPERM_FAMILIES[2] + for keyword in self.satfunc["KEYWORD"].unique() + ): + raise ValueError( + "Unrecognized saturation table keyword in data. This should not occur unless " + "there has been changes to ecl2df. Update of this plugin might be required." + ) + else: + self.family = 2 + self.sat_axes_maps = { + "SW": ["KRW", "PCOW"], + "SG": ["KRG", "PCOG"], + "SO": ["KROW", "KROG"], + } + self.scalfile = scalfile + self.sheet_name = sheet_name + self.scal = ( + load_scal_recommendation(self.scalfile, self.sheet_name) + if self.scalfile is not None + else None + ) + + + except PermissionError: + self.error_message = ( + f"Access to file '{relpermfile}' denied. " + f"Please check your path for '{relpermfile}' and make sure you have access to it." + ) + return + except FileNotFoundError: + self.error_message = ( + f"The file {relpermfile}' not found." + "Please check you path" + ) + return + except pd.errors.ParserError: + self.error_message = ( + f"The file '{relpermfile}' is not a valid csv file." + ) + except pd.errors.EmptyDataError: + self.error_message = ( + f"The file '{relpermfile}' is an empty file." + ) + except Exception: + self.error_message = ( + f"Unknown exception when trying to read '{relpermfile}" + ) + + self.add_store(PlugInIDs.Stores.Selectors.SATURATION_AXIS,WebvizPluginABC.StorageType.SESSION) + self.add_store(PlugInIDs.Stores.Selectors.COLOR_BY,WebvizPluginABC.StorageType.SESSION) + self.add_store(PlugInIDs.Stores.Selectors.ENSAMBLES,WebvizPluginABC.StorageType.SESSION) + self.add_store(PlugInIDs.Stores.Selectors.CURVES,WebvizPluginABC.StorageType.SESSION) + self.add_store(PlugInIDs.Stores.Selectors.SATNUM,WebvizPluginABC.StorageType.SESSION) + self.add_shared_settings_group(Selectors(self.satfunc,self.plotly_theme,self.sat_axes_maps), + PlugInIDs.SharedSettings.SELECTORS) + + + self.add_store(PlugInIDs.Stores.Visualization.LINE_TRACES,WebvizPluginABC.StorageType.SESSION) + self.add_store(PlugInIDs.Stores.Visualization.Y_AXIS,WebvizPluginABC.StorageType.SESSION) + self.add_shared_settings_group(Visualization(self.satfunc),PlugInIDs.SharedSettings.VISUALIZATION) + ''' + self.add_store(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL,WebvizPluginABC.StorageType.SESSION) + self.add_shared_settings_group(Scal_recommendation(self.satfunc),PlugInIDs.SharedSettings.SCAL_RECOMMENDATION) + ''' + self.add_view(TestView(self.satfunc),PlugInIDs.RelCapViewGroup.RELCAP,PlugInIDs.RelCapViewGroup.GROUP_NAME) + + + + + @property + def layout(self) -> Type[Component]: + return error(self.error_message) + + \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py new file mode 100644 index 000000000..4321fde00 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py @@ -0,0 +1,23 @@ +class PlugInIDs: + class Stores: + class Selectors: + SATURATION_AXIS = "saturation-axis" + COLOR_BY = "color-by" + ENSAMBLES = "ensambles" + CURVES = "curves" + SATNUM = "satnum" # should we change to saturation number? or someting? + class Visualization: + LINE_TRACES = "line-traces" + Y_AXIS = "y-axis" + class SCALRecomendation: + SHOW_SCAL = "show-SCAL" # doesn't work? + + class RelCapViewGroup: + GROUP_NAME = "relcap" + RELCAP = "relcapview" + + class SharedSettings: + FILTER = "filter" + SELECTORS="selectors" + VISUALIZATION="visualization" + SCAL_RECOMMENDATION="scal_recommendation" diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py new file mode 100644 index 000000000..29db3ca48 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py @@ -0,0 +1 @@ +from ._filter import Filter, Selectors, Visualization, Scal_recommendation \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py new file mode 100644 index 000000000..d2ed85613 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -0,0 +1,249 @@ +from typing import List + +from dash import callback, Input, Output +from dash.development.base_component import Component +import pandas as pd +from webviz_config.webviz_plugin_subclasses import SettingsGroupABC +import webviz_core_components as wcc + +from .._plugin_ids import PlugInIDs + +class Filter(SettingsGroupABC): + """ + Added by MoNezhadali 06.22 + """ + def __init__(self, relperm_df: pd.DataFrame) -> None: + super().__init__("Filter") + class Ids: + class Selectors: + SATURATION_AXIS="saturation-axis" + COLOR_BY="color-by" + ENSEMBLES="ensembles" + CURVES="curves" + SATNUM="satnum" + class Visualization: + LINE_TRACES="line-traces" + Y_AXIS="y-axis" + class SCALRecommendation: + SHOW_SCAL="show-scal" + + ## todo: the selectors will be defined here after getting to know the data + +class Selectors(Filter): + def __init__(self, relperm_df: pd.DataFrame,plotly_theme,sat_axes_maps) -> None: + super().__init__("Selectors") + self.satfunc=relperm_df + self.plotly_theme = plotly_theme + self.sat_axes_maps=sat_axes_maps + + @property + def sat_axes(self): + """List of all possible saturation axes in dataframe""" + return [sat for sat in self.sat_axes_maps if sat in self.satfunc.columns] + + @property + def ensembles(self): + return list(self.satfunc["ENSEMBLE"].unique()) + + @property + def satnums(self): + return list(self.satfunc["SATNUM"].unique()) + + @property + def color_options(self): + """Options to color by""" + return ["ENSEMBLE", "CURVE", "SATNUM"] + + @property + def ens_colors(self): + return { + ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] + for ens in self.ensembles + } + + @property + def satnum_colors(self): + return { + satnum: self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum)] + for satnum in self.satnums + } + + def layout(self) -> List[Component]: + return [ + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), + label="Saturation axis", + options=[{"label":i, "value":i} for i in (self.sat_axes)], + value=self.sat_axes[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), + label="Color by", + options=[{"label":i, "value":i} for i in (self.color_options)], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), + label="Ensembles", + options=[{"label":i, "value":i} for i in (self.ensembles)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + # This needs to be checked + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), + label="Curves", + options=[{"label":i, "value":i} for i in (self.sat_axes_maps["SW"])], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), + label="Satnum", + options=[{"label":i, "value":i} for i in (self.satnums)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + ), + ) + def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: + return saturation_axis + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + ), + ) + def _set_color_by(color_by: List[str]) -> List[str]: + return color_by + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", + ), + ) + def _set_ensembles(ensembles: List[str]) -> List[str]: + return ensembles + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", + ), + ) + def _set_curves(curves: List[str]) -> List[str]: + return curves + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", + ), + ) + def _set_saturation_axis(satnum: List[str]) -> List[str]: + return satnum + + +class Visualization(Filter): + def __init__(self, relperm_df: pd.DataFrame) -> None: + super().__init__("Visualization") + def layout(self) -> List[Component]: + return [ + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), + label="Line traces", + options=[ + {"label":"Individual realization","value":"individual-realization"}, + {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, + ], + value="statistical-fanchart", + ), + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), + label="Y-axis", + options=[ + {"label":"Linear","value":"linear"}, + {"label":"Log", "value":"log"}, + ], + value="linear", + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", + ), + ) + def _set_line_traces(line_traces: List[str]) -> List[str]: + return line_traces + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", + ), + ) + def _set_y_axis(y_axis: List[str]) -> List[str]: + return y_axis + +class Scal_recommendation(Filter): + ''' + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("SCAL recommendation") + ''' + def layout(self) -> List[Component]: + return [ + wcc.Checklist( + id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), + label="", + options=[ + { + "label": "Show SCAL", + "value": "show_scal", + }, + ] + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", + ), + ) + def _set_scal_recommendation(scal_recommendation: List[str]) -> List[str]: + return scal_recommendation + + + \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py new file mode 100644 index 000000000..94087a9c5 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py @@ -0,0 +1 @@ +from ._graph import Graph \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py new file mode 100644 index 000000000..0352ce468 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py @@ -0,0 +1,25 @@ +from typing import Type +from dash.development.base_component import Component + +from webviz_config.webviz_plugin_subclasses import ViewElementABC +from webviz_core_components import Graph as WccGraph + +class Graph(ViewElementABC): + class IDs: + #pylint: disable=too-few-public-methods + GRAPH = "graph" + + def __init__(self,height : str = "43vh", both : bool = True) -> None: + super().__init__() + + + if both: + self.height = height + else: + self.height = "88vh" + + def inner_layout(self) -> Type[Component]: + return WccGraph( + id = self.register_component_unique_id(Graph.IDs.GRAPH), + style = {"height": self.height, "min-height": "300px"} + ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py new file mode 100644 index 000000000..750f2c7c1 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -0,0 +1,170 @@ +from typing import List, Tuple, Optional, Union +from pathlib import Path + +from dash import callback, Input, Output, State +import pandas as pd +import plotly.colors +from webviz_config.webviz_plugin_subclasses import ViewABC + +from ..._plugin_ids import PlugInIDs +from ...view_elements import Graph + +class RelpermCappres(ViewABC): + '''Add comment descibring the plugin''' + class IDs: + '''Different curves to be shown in the view''' + #pylint: disable=too-few-public-methods + # en ID pr view element; ett eller to view element? + # tror jeg går for to view elements + RELATIVE_PERMEABILIY = "reative-permeability" + CAPILAR_PRESSURE = "capilar-pressure" + + # don't think I need these + '''KRW = "KRW" + KROW = "KROW" + POW = "POW" + + class Saturations: + SW = "SW" + SO = "SO" + SG = "SG" + SL = "SL" + class RelpermFamilies: # the possible keywords in the data files needed in list + SWOF = "SWOF" + SGOF = "SGOF" + SLGOF = "SLGOF" + SWFN = "SWFN" + SGFN = "SGFN" + SOF3 = "SOF3"''' + + # maybe need to add a create csv file in the main class to create one csv file + + SATURATIONS = ["SW", "SO", "SG", "SL"] + RELPERM_FAMILIES = ["SWOF", "SGOF", "SLGOF","SWFN", "SGFN", "SOF3"] + ENSAMBLES = ["iter-0","iter-3"] + GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] + + # må ha en utvidet csv fil som har realization og ensamble kolonne + valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + SATURATIONS + GRAPHS) + + + # stat types; should include al so it works on all data (copied) + SATURATIONS = ["SW", "SO", "SG", "SL"] # only sw and sg are used so far + RELPERM_FAMILIES = { + 1: ["SWOF", "SGOF", "SLGOF"], # only SWOF and SGOF re use in test data + 2: ["SWFN", "SGFN", "SOF3"], + } + SCAL_COLORMAP = { + "Missing": "#ffff00", # using yellow if the curve could not be found + "KRW": "#0000aa", + "KRG": "#ff0000", + "KROG": "#00aa00", + "KROW": "#00aa00", + "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) + "PCOG": "#555555", + } + + + def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: + # scalfile: Path = None; sets the scal file to be used, if any + # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate + super().__init__("Relatve permeability") + + ''' Data funksjonaliteter + + Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) + -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) + -> Sat ax Sg: kan velge mellom KRG, KROG og POG + Alle disse har felles instilliner + + Gruppene er + -> KRW: Relative permeability to water + -> KRG: Rlative permeability to gas + -> KROW: Relative permeability of oil in prescence of water + -> KROG: Relative permeability of oil in prescence of gas afo liwuid saturation + -> POW/G: Pressure of Water/Gas + + Colr by: velger hvordan man skal fordele dataen innad i de tre gruppene -> ensamble, curve og satnum + -> Ensamble: velger hvilke og hvor mange iter du skal ha med og velger en satnum. plotter for hver iter + -> Curve: velger en iter og en satnum, plotter for hver gruppe/kurve + -> Satnum: velger en iter og en eler flere satnum, plotte for hver satnum + Men alle har alltid mulighet til velge hvilke(n) gruppe(r) man ønsker å inludere + + De tre ulike gruppene er hver sin graph i viewen; + KRx og KROx er plottet sammen mot samme y akse, alle har samme y akse + -> KROx: oppe fra venstre og ned til høyre + -> KRx: nede fra venstre og opp til høyre + -> POx: + ''' + ''' Data i fil + Filene er sortert etter realization; + each realization has iter-0 and iter-3 + share -> results -> relperm.csv + velger realization (99 ulike) og iter (2 uliker pr realization) -> totalt 198 filer + + I hver fil er dataen grupert nedover ettter satnum (og keyword?) + Så er det listet data først for SW og å for SG or alle satnums + + X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 + ''' + + # extracte the data for the different graphs from the data source relperm_df + self.relperm_df = relperm_df # sets the data frame + + # er det egt flere som kan kunne plottes, men siden det kuner tatt ensyn til sg og sw foreløpig er det bare disse? + # skal vi inludere for utvidelse eller bare markere hvor det kan legges inn? + + # df for SW og SG + self.df_SW = self.relperm_df[relperm_df["KEYWORD"] == "SGOF"] + self.df_SG = self.relperm_df[relperm_df["KEYWORD"] == "SWOF"] + + + self.satnum1 = self.relperm_df[self.relperm_df["SATNUM"] == 1] # dette er velidg ueffektivt, er 12 satnum + + + # creating the columns and row to define the setup of the view + column = self.add_column() + + first_row = column.make_row() + first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) + # change something in Graph() ot be able to get them in the same plot, or add them as on view element? + # need the height of the Graph() to vary wether we are suppoed to show to graphs or not + + second_row = column.make_row() + second_row.add_view_element(Graph(),RelpermCappres.IDs.CAPILAR_PRESSURE) + + # define the callbacks of the view + def set_callbacks(self) -> None: + # callback for the graphs + @callback( + Output(self.get_unique_id(Graph(),"figure")), # need to be changed + Input(self.uuid("color_by"), "value"), + Input(self.uuid("visualization"), "value"), + Input(self.uuid("ensemble"), "value"), + Input(self.uuid("curve"), "value"), + Input(self.uuid("satnum"), "value"), + Input(self.uuid("sataxis"), "value"), + Input(self.uuid("linlog"), "value"), + Input(self.uuid("scal"), "value"), + ) + def _update_graph(color_by, visualization, ensembles, curves, satnums, sataxis, linlog, scal) -> dict: + colors = plotly.colors.DEFAULT_PLOTLY_COLORS + + + # callback function for the ensamble selector + @callback( + Output(self.uuid("ensemble"), "multi"), + Output(self.uuid("ensemble"), "value"), + Input(self.uuid("color_by"), "value"), + State(self.uuid("stored_ensemble"), "data") #need to fin out how this works + ) + def _set_ensamble_selector(color_by, stored_ensemble): + """If ensemble is selected as color by, set the ensemble + selector to allow multiple selections, else use stored_ensemble + """ + + # callback function for the curve selector + @callback( + + ) + def _set_curve_selector() \ No newline at end of file From 748f38dc2661cf435c352b1c0643f7e08d720b76 Mon Sep 17 00:00:00 2001 From: Viktoria Vahlin <107865041+vvahlin@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:18:07 +0200 Subject: [PATCH 03/54] Delete _relative_permeability --- .../_relative_permeability/__init__.py | 2 - .../plugins/_relative_permeability/_error.py | 0 .../plugins/_relative_permeability/_plugin.py | 49 ---- .../_relative_permeability/_plugin_ids.py | 20 -- .../shared_settings/__init__.py | 0 .../shared_settings/_filter.py | 211 ------------------ .../view_elements/__init__.py | 1 - .../view_elements/_graph.py | 25 --- .../_relative_permeability/views/__init__.py | 0 .../views/relperm_cappres/__init__.py | 0 .../views/relperm_cappres/_relcap.py | 170 -------------- 11 files changed, 478 deletions(-) delete mode 100644 webviz_subsurface/plugins/_relative_permeability/__init__.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/_error.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/_plugin.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/views/__init__.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py delete mode 100644 webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py diff --git a/webviz_subsurface/plugins/_relative_permeability/__init__.py b/webviz_subsurface/plugins/_relative_permeability/__init__.py deleted file mode 100644 index 9b56906e9..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from ._plugin import RelpermCappres - diff --git a/webviz_subsurface/plugins/_relative_permeability/_error.py b/webviz_subsurface/plugins/_relative_permeability/_error.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py deleted file mode 100644 index ab11b4b7f..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ /dev/null @@ -1,49 +0,0 @@ -# import from python -from typing import Type -from pathlib import Path - -# packages from installed stuff -from dash.development.base_component import Component -import pandas as pd -from webviz_config import WebvizPluginABC - -# own imports -from ._error import error -from ._plugin_ids import PlugInIDs # importing the namespace -from .shared_settings import Filter - -class RelativePermeability(WebvizPluginABC): - def __init__(self, path_to_relpermfile: Path ) -> None: - super().__init__(stretch=True) # super refer to class inhereted from, init from ABC - - # set a member, self first for all - self.error_message = "" - - # when reading from file must check that these are the keywords, if not raise ValueError - - try: - self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame - except PermissionError: - self.error_message = ( - f"Access to file '{path_to_relpermfile}' denied. " - f"Please check your path for '{path_to_relpermfile}' and make sure you have access to it." - ) - return - except FileNotFoundError: - self.error_message = ( - f"The file {path_to_relpermfile}' not found." - "Please check you path" - ) - return - except pd.errors.ParserError: - self.error_message = ( - f"The file '{path_to_relpermfile}' is not a valid csv file." - ) - except pd.errors.EmptyDataError: - self.error_message = ( - f"The file '{path_to_relpermfile}' is an empty file." - ) - except Exception: - self.error_message = ( - f"Unknown exception when trying to read '{path_to_relpermfile}" - ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py deleted file mode 100644 index a0940369d..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py +++ /dev/null @@ -1,20 +0,0 @@ -class PlugInIDs: - class Stores: - class Selectors: - SATURATION_AXIS = "saturation-axis" - COLOR_BY = "color-by" - ENSAMBLES = "ensambles" - CURVES = "curves" - SATNUM = "satnum" # should we change to saturation number? or someting? - class Visualization: - LINE_TRACES = "line-traces" - Y_AXIS = "y-axis" - class SCALRecomendation: - SHOW_SCAL = "show-SCAL" # doesn't work? - - class RelCapViewGroup: - GROUP_NAME = "relcap" - RELCAP = "relcapview" - - class SharedSettings: - FILTER = "filter" diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py deleted file mode 100644 index 15f5dcbb3..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ /dev/null @@ -1,211 +0,0 @@ -from typing import List - -from dash import callback, Input, Output -from dash.development.base_component import Component -import pandas as pd -from webviz_config.webviz_plugin_subclasses import SettingsGroupABC -import webviz_core_components as wcc - -from .._plugin_ids import PlugInIDs - -class Filter(SettingsGroupABC): - """ - Added by MoNezhadali 06.22 - """ - class Ids: - class Selectors: - SATURATION_AXIS="saturation-axis" - COLOR_BY="color-by" - ENSEMBLES="ensembles" - CURVES="curves" - SATNUM="satnum" - class Visualization: - LINE_TRACES="line-traces" - Y_AXIS="y-axis" - class SCALRecommendation: - SHOW_SCAL="show-scal" - - ## todo: the selectors will be defined here after getting to know the data - - class Selectors: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("Selectors") - - def layout(self) -> List(Component): - return [ - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), - label="Saturation axis", - options=[{"label":i, "value":i} for i in range(self.sat_axes)], - value=self.sat_axes[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), - label="Color by", - options=[{"label":i, "value":i} for i in range(self.color_options)], - value=self.color_options[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), - label="Ensembles", - options=[{"label":i, "value":i} for i in range(self.ensembles)], - value=self.ensembles[0], - multi=True, - size=min(5,len(self.ensembles)), - ), - # This needs to be checked - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), - label="Curves", - options=[{"label":i, "value":i} for i in range(self.curves)], - value=self.color_options[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), - label="Satnum", - options=[{"label":i, "value":i} for i in range(self.satnums)], - value=self.ensembles[0], - multi=True, - size=min(5,len(self.ensembles)), - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", - ), - ) - def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: - return saturation_axis - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", - ), - ) - def _set_color_by(color_by: List[str]) -> List[str]: - return color_by - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", - ), - ) - def _set_ensembles(ensembles: List[str]) -> List[str]: - return ensembles - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", - ), - ) - def _set_curves(curves: List[str]) -> List[str]: - return curves - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", - ), - ) - def _set_saturation_axis(satnum: List[str]) -> List[str]: - return satnum - - - class Visualization: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("Visualization") - def layout(self) -> List(Component): - return [ - wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), - label="Line traces", - options=[ - {"label":"Individual realization","value":"individual-realization"}, - {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, - ], - value="statistical-fanchart", - ), - wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), - label="Y-axis", - options=[ - {"label":"Linear","value":"linear"}, - {"label":"Log", "value":"log"}, - ], - value="linear", - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", - ), - ) - def _set_line_traces(line_traces: List[str]) -> List[str]: - return line_traces - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", - ), - ) - def _set_y_axis(y_axis: List[str]) -> List[str]: - return y_axis - - - class Scal_recommendation: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("SCAL recommendation") - def layout(self) -> List(Component): - return [ - wcc.Checklist( - id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), - label="", - options=[ - { - "label": "Show SCAL", - "value": "show_scal", - }, - ] - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", - ), - ) - def _set_line_traces(line_traces: List[str]) -> List[str]: - return line_traces - - - \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py deleted file mode 100644 index 94087a9c5..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from ._graph import Graph \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py deleted file mode 100644 index 0352ce468..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import Type -from dash.development.base_component import Component - -from webviz_config.webviz_plugin_subclasses import ViewElementABC -from webviz_core_components import Graph as WccGraph - -class Graph(ViewElementABC): - class IDs: - #pylint: disable=too-few-public-methods - GRAPH = "graph" - - def __init__(self,height : str = "43vh", both : bool = True) -> None: - super().__init__() - - - if both: - self.height = height - else: - self.height = "88vh" - - def inner_layout(self) -> Type[Component]: - return WccGraph( - id = self.register_component_unique_id(Graph.IDs.GRAPH), - style = {"height": self.height, "min-height": "300px"} - ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py deleted file mode 100644 index 750f2c7c1..000000000 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ /dev/null @@ -1,170 +0,0 @@ -from typing import List, Tuple, Optional, Union -from pathlib import Path - -from dash import callback, Input, Output, State -import pandas as pd -import plotly.colors -from webviz_config.webviz_plugin_subclasses import ViewABC - -from ..._plugin_ids import PlugInIDs -from ...view_elements import Graph - -class RelpermCappres(ViewABC): - '''Add comment descibring the plugin''' - class IDs: - '''Different curves to be shown in the view''' - #pylint: disable=too-few-public-methods - # en ID pr view element; ett eller to view element? - # tror jeg går for to view elements - RELATIVE_PERMEABILIY = "reative-permeability" - CAPILAR_PRESSURE = "capilar-pressure" - - # don't think I need these - '''KRW = "KRW" - KROW = "KROW" - POW = "POW" - - class Saturations: - SW = "SW" - SO = "SO" - SG = "SG" - SL = "SL" - class RelpermFamilies: # the possible keywords in the data files needed in list - SWOF = "SWOF" - SGOF = "SGOF" - SLGOF = "SLGOF" - SWFN = "SWFN" - SGFN = "SGFN" - SOF3 = "SOF3"''' - - # maybe need to add a create csv file in the main class to create one csv file - - SATURATIONS = ["SW", "SO", "SG", "SL"] - RELPERM_FAMILIES = ["SWOF", "SGOF", "SLGOF","SWFN", "SGFN", "SOF3"] - ENSAMBLES = ["iter-0","iter-3"] - GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] - - # må ha en utvidet csv fil som har realization og ensamble kolonne - valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + SATURATIONS + GRAPHS) - - - # stat types; should include al so it works on all data (copied) - SATURATIONS = ["SW", "SO", "SG", "SL"] # only sw and sg are used so far - RELPERM_FAMILIES = { - 1: ["SWOF", "SGOF", "SLGOF"], # only SWOF and SGOF re use in test data - 2: ["SWFN", "SGFN", "SOF3"], - } - SCAL_COLORMAP = { - "Missing": "#ffff00", # using yellow if the curve could not be found - "KRW": "#0000aa", - "KRG": "#ff0000", - "KROG": "#00aa00", - "KROW": "#00aa00", - "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) - "PCOG": "#555555", - } - - - def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: - # scalfile: Path = None; sets the scal file to be used, if any - # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate - super().__init__("Relatve permeability") - - ''' Data funksjonaliteter - - Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) - -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) - -> Sat ax Sg: kan velge mellom KRG, KROG og POG - Alle disse har felles instilliner - - Gruppene er - -> KRW: Relative permeability to water - -> KRG: Rlative permeability to gas - -> KROW: Relative permeability of oil in prescence of water - -> KROG: Relative permeability of oil in prescence of gas afo liwuid saturation - -> POW/G: Pressure of Water/Gas - - Colr by: velger hvordan man skal fordele dataen innad i de tre gruppene -> ensamble, curve og satnum - -> Ensamble: velger hvilke og hvor mange iter du skal ha med og velger en satnum. plotter for hver iter - -> Curve: velger en iter og en satnum, plotter for hver gruppe/kurve - -> Satnum: velger en iter og en eler flere satnum, plotte for hver satnum - Men alle har alltid mulighet til velge hvilke(n) gruppe(r) man ønsker å inludere - - De tre ulike gruppene er hver sin graph i viewen; - KRx og KROx er plottet sammen mot samme y akse, alle har samme y akse - -> KROx: oppe fra venstre og ned til høyre - -> KRx: nede fra venstre og opp til høyre - -> POx: - ''' - ''' Data i fil - Filene er sortert etter realization; - each realization has iter-0 and iter-3 - share -> results -> relperm.csv - velger realization (99 ulike) og iter (2 uliker pr realization) -> totalt 198 filer - - I hver fil er dataen grupert nedover ettter satnum (og keyword?) - Så er det listet data først for SW og å for SG or alle satnums - - X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 - ''' - - # extracte the data for the different graphs from the data source relperm_df - self.relperm_df = relperm_df # sets the data frame - - # er det egt flere som kan kunne plottes, men siden det kuner tatt ensyn til sg og sw foreløpig er det bare disse? - # skal vi inludere for utvidelse eller bare markere hvor det kan legges inn? - - # df for SW og SG - self.df_SW = self.relperm_df[relperm_df["KEYWORD"] == "SGOF"] - self.df_SG = self.relperm_df[relperm_df["KEYWORD"] == "SWOF"] - - - self.satnum1 = self.relperm_df[self.relperm_df["SATNUM"] == 1] # dette er velidg ueffektivt, er 12 satnum - - - # creating the columns and row to define the setup of the view - column = self.add_column() - - first_row = column.make_row() - first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) - # change something in Graph() ot be able to get them in the same plot, or add them as on view element? - # need the height of the Graph() to vary wether we are suppoed to show to graphs or not - - second_row = column.make_row() - second_row.add_view_element(Graph(),RelpermCappres.IDs.CAPILAR_PRESSURE) - - # define the callbacks of the view - def set_callbacks(self) -> None: - # callback for the graphs - @callback( - Output(self.get_unique_id(Graph(),"figure")), # need to be changed - Input(self.uuid("color_by"), "value"), - Input(self.uuid("visualization"), "value"), - Input(self.uuid("ensemble"), "value"), - Input(self.uuid("curve"), "value"), - Input(self.uuid("satnum"), "value"), - Input(self.uuid("sataxis"), "value"), - Input(self.uuid("linlog"), "value"), - Input(self.uuid("scal"), "value"), - ) - def _update_graph(color_by, visualization, ensembles, curves, satnums, sataxis, linlog, scal) -> dict: - colors = plotly.colors.DEFAULT_PLOTLY_COLORS - - - # callback function for the ensamble selector - @callback( - Output(self.uuid("ensemble"), "multi"), - Output(self.uuid("ensemble"), "value"), - Input(self.uuid("color_by"), "value"), - State(self.uuid("stored_ensemble"), "data") #need to fin out how this works - ) - def _set_ensamble_selector(color_by, stored_ensemble): - """If ensemble is selected as color by, set the ensemble - selector to allow multiple selections, else use stored_ensemble - """ - - # callback function for the curve selector - @callback( - - ) - def _set_curve_selector() \ No newline at end of file From 8e7abd4358f6ec1e20097cf383445851331a76df Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 13:20:34 +0200 Subject: [PATCH 04/54] edit the view --- .../_relative_permeability_new/__init__.py | 1 + .../_relative_permeability_new/_error.py | 0 .../_relative_permeability_new/_plugin.py | 49 ++ .../_relative_permeability_new/_plugin_ids.py | 20 + .../shared_settings/__init__.py | 1 + .../shared_settings/_filter.py | 211 +++++++ .../view_elements/__init__.py | 1 + .../view_elements/_graph.py | 19 + .../views/__init__.py | 0 .../views/relperm_cappres/__init__.py | 0 .../views/relperm_cappres/_relcap.py | 586 ++++++++++++++++++ 11 files changed, 888 insertions(+) create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_error.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_plugin.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py create mode 100644 webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py new file mode 100644 index 000000000..ce9a0f660 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py @@ -0,0 +1 @@ +from ._plugin import RelativePermeabilityNew diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_error.py b/webviz_subsurface/plugins/_relative_permeability_new/_error.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py new file mode 100644 index 000000000..007b91af1 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -0,0 +1,49 @@ +# import from python +from typing import Type +from pathlib import Path + +# packages from installed stuff +from dash.development.base_component import Component +import pandas as pd +from webviz_config import WebvizPluginABC + +# own imports +#from ._error import error +from ._plugin_ids import PlugInIDs # importing the namespace +from .shared_settings import Filter + +class RelativePermeabilityNew(WebvizPluginABC): + def __init__(self, path_to_relpermfile: Path ) -> None: + super().__init__(stretch=True) # super refer to class inhereted from, init from ABC + + # set a member, self first for all + self.error_message = "" + + # when reading from file must check that these are the keywords, if not raise ValueError + + try: + self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame + except PermissionError: + self.error_message = ( + f"Access to file '{path_to_relpermfile}' denied. " + f"Please check your path for '{path_to_relpermfile}' and make sure you have access to it." + ) + return + except FileNotFoundError: + self.error_message = ( + f"The file {path_to_relpermfile}' not found." + "Please check you path" + ) + return + except pd.errors.ParserError: + self.error_message = ( + f"The file '{path_to_relpermfile}' is not a valid csv file." + ) + except pd.errors.EmptyDataError: + self.error_message = ( + f"The file '{path_to_relpermfile}' is an empty file." + ) + except Exception: + self.error_message = ( + f"Unknown exception when trying to read '{path_to_relpermfile}" + ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py new file mode 100644 index 000000000..a0940369d --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py @@ -0,0 +1,20 @@ +class PlugInIDs: + class Stores: + class Selectors: + SATURATION_AXIS = "saturation-axis" + COLOR_BY = "color-by" + ENSAMBLES = "ensambles" + CURVES = "curves" + SATNUM = "satnum" # should we change to saturation number? or someting? + class Visualization: + LINE_TRACES = "line-traces" + Y_AXIS = "y-axis" + class SCALRecomendation: + SHOW_SCAL = "show-SCAL" # doesn't work? + + class RelCapViewGroup: + GROUP_NAME = "relcap" + RELCAP = "relcapview" + + class SharedSettings: + FILTER = "filter" diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py new file mode 100644 index 000000000..c3bf56ef3 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py @@ -0,0 +1 @@ +from ._filter import Filter \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py new file mode 100644 index 000000000..15f5dcbb3 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -0,0 +1,211 @@ +from typing import List + +from dash import callback, Input, Output +from dash.development.base_component import Component +import pandas as pd +from webviz_config.webviz_plugin_subclasses import SettingsGroupABC +import webviz_core_components as wcc + +from .._plugin_ids import PlugInIDs + +class Filter(SettingsGroupABC): + """ + Added by MoNezhadali 06.22 + """ + class Ids: + class Selectors: + SATURATION_AXIS="saturation-axis" + COLOR_BY="color-by" + ENSEMBLES="ensembles" + CURVES="curves" + SATNUM="satnum" + class Visualization: + LINE_TRACES="line-traces" + Y_AXIS="y-axis" + class SCALRecommendation: + SHOW_SCAL="show-scal" + + ## todo: the selectors will be defined here after getting to know the data + + class Selectors: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("Selectors") + + def layout(self) -> List(Component): + return [ + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), + label="Saturation axis", + options=[{"label":i, "value":i} for i in range(self.sat_axes)], + value=self.sat_axes[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), + label="Color by", + options=[{"label":i, "value":i} for i in range(self.color_options)], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), + label="Ensembles", + options=[{"label":i, "value":i} for i in range(self.ensembles)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + # This needs to be checked + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), + label="Curves", + options=[{"label":i, "value":i} for i in range(self.curves)], + value=self.color_options[0], + multi=False, + size=1, + ), + wcc.SelectWithLabel( + id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), + label="Satnum", + options=[{"label":i, "value":i} for i in range(self.satnums)], + value=self.ensembles[0], + multi=True, + size=min(5,len(self.ensembles)), + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + ), + ) + def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: + return saturation_axis + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + ), + ) + def _set_color_by(color_by: List[str]) -> List[str]: + return color_by + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", + ), + ) + def _set_ensembles(ensembles: List[str]) -> List[str]: + return ensembles + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", + ), + ) + def _set_curves(curves: List[str]) -> List[str]: + return curves + + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", + ), + ) + def _set_saturation_axis(satnum: List[str]) -> List[str]: + return satnum + + + class Visualization: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("Visualization") + def layout(self) -> List(Component): + return [ + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), + label="Line traces", + options=[ + {"label":"Individual realization","value":"individual-realization"}, + {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, + ], + value="statistical-fanchart", + ), + wcc.RadioItems( + id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), + label="Y-axis", + options=[ + {"label":"Linear","value":"linear"}, + {"label":"Log", "value":"log"}, + ], + value="linear", + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", + ), + ) + def _set_line_traces(line_traces: List[str]) -> List[str]: + return line_traces + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", + ), + ) + def _set_y_axis(y_axis: List[str]) -> List[str]: + return y_axis + + + class Scal_recommendation: + def __init__(self, rel_perm_df: pd.DataFrame) -> None: + self.super().__init__("SCAL recommendation") + def layout(self) -> List(Component): + return [ + wcc.Checklist( + id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), + label="", + options=[ + { + "label": "Show SCAL", + "value": "show_scal", + }, + ] + ), + ] + def set_callbacks(self) -> None: + @callback( + Output( + self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value + ), + Input( + self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", + ), + ) + def _set_line_traces(line_traces: List[str]) -> List[str]: + return line_traces + + + \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py new file mode 100644 index 000000000..94087a9c5 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py @@ -0,0 +1 @@ +from ._graph import Graph \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py new file mode 100644 index 000000000..ae1e4c6f4 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py @@ -0,0 +1,19 @@ +from typing import Type +from dash.development.base_component import Component + +from webviz_config.webviz_plugin_subclasses import ViewElementABC +from webviz_core_components import Graph as WccGraph + +class Graph(ViewElementABC): + class IDs: + #pylint: disable=too-few-public-methods + GRAPH = "graph" + + def __init__(self,height : str = "88vh") -> None: + super().__init__() + + def inner_layout(self) -> Type[Component]: + return WccGraph( + id = self.register_component_unique_id(Graph.IDs.GRAPH), + style = {"height": self.height, "min-height": "300px"} + ) \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py new file mode 100644 index 000000000..aa390ed69 --- /dev/null +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -0,0 +1,586 @@ +from fcntl import LOCK_WRITE +from pydoc import doc +from typing import List, Tuple, Optional, Union +from pathlib import Path + +from dash import callback, Input, Output, State +from matplotlib.pyplot import figure +import pandas as pd +import numpy as np +import plotly.colors +from dash.exceptions import PreventUpdate +from webviz_config.webviz_plugin_subclasses import ViewABC + +from ..._plugin_ids import PlugInIDs +from ...view_elements import Graph +from ....._utils.fanchart_plotting import FanchartData, FreeLineData, LowHighData, MinMaxData, get_fanchart_traces + +class RelpermCappres(ViewABC): + '''Add comment descibring the plugin''' + class IDs: + '''Different curves to be shown in the view''' + #pylint: disable=too-few-public-methods + # en ID pr view element; ett eller to view element? + # tror jeg går for to view elements + RELATIVE_PERMEABILIY = "reative-permeability" + CAPILAR_PRESSURE = "capilar-pressure" + + # don't think I need these + '''KRW = "KRW" + KROW = "KROW" + POW = "POW" + + class Saturations: + SW = "SW" + SO = "SO" + SG = "SG" + SL = "SL" + class RelpermFamilies: # the possible keywords in the data files needed in list + SWOF = "SWOF" + SGOF = "SGOF" + SLGOF = "SLGOF" + SWFN = "SWFN" + SGFN = "SGFN" + SOF3 = "SOF3"''' + + # maybe need to add a create csv file in the main class to create one csv file + + SATURATIONS = ["SW", "SO", "SG", "SL"] + RELPERM_FAMILIES = ["SWOF", "SGOF", "SLGOF","SWFN", "SGFN", "SOF3"] + ENSAMBLES = ["iter-0","iter-3"] + GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] + + # må ha en utvidet csv fil som har realization og ensamble kolonne + valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + SATURATIONS + GRAPHS) + + + def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: + # scalfile: Path = None; sets the scal file to be used, if any + # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate + super().__init__("Relatve permeability") + + ''' Data funksjonaliteter + + Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) + -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) + -> Sat ax Sg: kan velge mellom KRG, KROG og POG + Alle disse har felles instilliner + + Gruppene er + -> KRW: Relative permeability to water + -> KRG: Rlative permeability to gas + -> KROW: Relative permeability of oil in prescence of water + -> KROG: Relative permeability of oil in prescence of gas afo liwuid saturation + -> POW/G: Pressure of Water/Gas + + Colr by: velger hvordan man skal fordele dataen innad i de tre gruppene -> ensamble, curve og satnum + -> Ensamble: velger hvilke og hvor mange iter du skal ha med og velger en satnum. plotter for hver iter + -> Curve: velger en iter og en satnum, plotter for hver gruppe/kurve + -> Satnum: velger en iter og en eler flere satnum, plotte for hver satnum + Men alle har alltid mulighet til velge hvilke(n) gruppe(r) man ønsker å inludere + + De tre ulike gruppene er hver sin graph i viewen; + KRx og KROx er plottet sammen mot samme y akse, alle har samme y akse + -> KROx: oppe fra venstre og ned til høyre + -> KRx: nede fra venstre og opp til høyre + -> POx: + ''' + ''' Data i fil + Filene er sortert etter realization; + each realization has iter-0 and iter-3 + share -> results -> relperm.csv + velger realization (99 ulike) og iter (2 uliker pr realization) -> totalt 198 filer + + I hver fil er dataen grupert nedover ettter satnum (og keyword?) + Så er det listet data først for SW og å for SG or alle satnums + + X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 + ''' + + # extracte the data for the different graphs from the data source relperm_df + self.relperm_df = relperm_df + # file with columns: ['ENSEMBLE', 'REAL', 'SW', 'KRW', 'KROW', 'PCOW', 'SATNUM', 'KEYWORD','SG', 'KRG', 'KROG', 'PCOG'] + # all these columns will be in the file input to the class RelpermCappres (change name to end with view to distinguish?) + + # the first setting that ou have to choose is between gaas and water, you never have both so can split the dataset in two? + self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SWOF"] + self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SGOF"] + + # creating the columns and row to define the setup of the view + column = self.add_column() + + first_row = column.make_row() + first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) + # change something in Graph() to be able to get them in the same plot, or add them as on view element? + # need the height of the Graph() to vary wether we are suppoed to show to graphs or not + + # define the callbacks of the view + def set_callbacks(self) -> None: + # callback for the graphs + @callback( + Output(self.view_element(RelpermCappres.IDs.RELATIVE_PERMEABILIY).component_unique_id(Graph.IDs.GRAPH).to_string(),"figure"), + + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data"), + + Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS),"data"), + + Input(self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL),"data"), + ) + def _update_graph(sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], + line_traces : List[str], y_axis : List[str], scal : List[str]) -> dict: + ensemble_colors = {"iter-0":"#285d93","iter-3":"#e48c16"} + curve_colors = {"KRW":"#0000aa","KRG":"#ff0000","KROG":"#00aa00","KROW":"#00aa00","PCOW":"#555555","PCOG":"#555555"} + satnum_colors = { + "1": "#285d93", + "2": "#e48c16", + "3": "#00aa00", + "4": "#cc0000", + "5": "#9f66bb", + "6": "#b17750", + "7": "#d59bc5", + "8": "#555555", + "9": "#b9c15b", + "10": "#5bf2e6", + "11": "#ff0000", + "12": "#45f03a" + } + colors = {"ensemble": ensemble_colors, "curve": curve_colors, "satnum": satnum_colors} + + if not curves or not satnums: # Curve and satnum has to be defined + raise PreventUpdate + if ensembles is None: # Allowing no ensembles to plot only SCAL data + ensembles = [] + + df = self.SG_df if sataxis[0].upper() == "SG" else self.SW_df + + nplots = ( + 2 + if any(curve.startswith("PC") for curve in curves) + and any(curve.startswith("KR") for curve in curves) + else 1 + ) + + layout = plot_layout(nplots,curves,sataxis,color_by,y_axis) + + if line_traces[0].lower() == "individual realization" and not df.empty: + data = realization_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) + elif line_traces[0].lower() == "statistical fanchart" and not df.empty: + data = statistic_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) + + if self.scal is not None and "show_scal" in scal: + scal_df = filter_scal_df(self.scal, curves, satnums, sataxis[0]) + data.extend(add_scal_traces(scal_df, curves, sataxis[0], nplots)) + + return {"data": data, "layout": layout} + + + + + + def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], + curves : List[str], satnums : List[str], line_traces : List[str], y_axis : List[str], + scal : List[str], colorslist : dict, nplots : int) -> List: + realizatoins = df["REAL"].unique() # list of all possible realizations + # traces = [i for i in range(len(realizatoins))] + colors = colorslist[color_by[0].lower()] + + # my version + ''' + if color_by[0].lower() == "ensemble": + data = [ + { + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]].loc[df["SATNUM"] == satnums[0]] + .dropna(axis = "columns", how = "all")[curves[curve]].values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]] + .loc[df["SATNUM"] == satnums[0]].dropna(axis = "columns", how = "all")[sataxis[0]].values.tolist()), # must include for linear or loganithmic + "type" : "line", + "legendgroup": iter, + "color" : colors[iter], + "showlegend": realization_iter == 0 and curvenum == 0, + } + for realization_iter,realization in enumerate(realizatoins) + for iter in ensembles + for curvenum,curve in enumerate(curves) + ] + layout = plot_layout(nplots,curves,sataxis,color_by,y_axis), + elif color_by[0].lower() == "curve": + data = [ + { # trenger man tolist() og list? og må man ha med [0] + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] + [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] + [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), + "type" : "line", + "legendgroup": curve, + "color" : colors[curve], + "showlegend": realization_iter == 0, + } + for realization_iter,realization in enumerate(realizatoins) + for curve in curves + ] + else: + data = [ + { + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] + [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] + [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), + "type" : "line", + "legendgroup": curve, + "color" : colors[satnum], + "showlegend": realization_iter == 0 and curvenum == 0, + } + for satnumiter,satnum in enumerate(satnums) + for realization_iter,realization in enumerate(realizatoins) + for curvenum,curve in enumerate(curves) + ] + ''' + + data = [] + + for curve_no, curve in enumerate(curves): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + if color_by == "CURVE": + satnum = df["SATNUM"].iloc[0] + ensemble = df["ENSEMBLE"].iloc[0] + + data.extend( + [ + { + "type": "scatter", + "x": real_df[sataxis[0]], + "y": real_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: {satnum[0]}
" + f"Realization: {real}, Ensemble: {ensemble}" + ), + "name": curve, + "legendgroup": curve, + "marker": { + "color": colors.get(curve, colors[list(colors.keys())[0]]) + }, + "showlegend": real_no == 0, + } + for real_no, (real, real_df) in enumerate(df.groupby("REAL")) + ] + ) + else: + constant_group = ( + df["SATNUM"].iloc[0] + if color_by == "ENSEMBLE" + else df["ENSEMBLE"].iloc[0] + ) + data.extend( + [ + { + "type": "scatter", + "x": real_df[sataxis[0]], + "y": real_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: " + f"{group if color_by[0].upper() == 'SATNUM' else constant_group}
" + f"Realization: {real}, Ensemble: " + f"{group if color_by[0].upper() == 'ENSEMBLE' else constant_group}" + ), + "name": group, + "legendgroup": group, + "marker": { + "color": colors.get(group, colors[list(colors.keys())[-1]]) + }, + "showlegend": real_no == 0 and curve_no == 0, + } + for (group, grouped_df) in df.groupby(color_by[0]) + for real_no, (real, real_df) in enumerate( + grouped_df.groupby("REAL") + ) + ] + ) + return data + + def statistic_traces(df : pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], + line_traces : List[str], y_axis : List[str], scal : List[str], colorslist: dict, nplots : int) -> List: + # Switched P10 and P90 due to convetion in petroleum industry + def p10(x): + return np.nanpercentile(x, q=90) + + def p90(x): + return np.nanpercentile(x, q=10) + + data = [] # str #pd.Dataframe + for ensemble_no, (ensemble, ensemble_df) in enumerate( + df[["ENSEMBLE", "SATNUM"] + [sataxis[0]] + curves].groupby(["ENSEMBLE"]) + ): # int + for satnum_no, (satnum, satnum_df) in enumerate(ensemble_df.groupby("SATNUM")): + df_stat = ( + satnum_df.groupby(sataxis[0]) + .agg([np.nanmean, np.nanmin, np.nanmax, p10, p90]) + .stack() + .swaplevel() + ) + for curve_no, curve in enumerate(curves): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + legend_group = ( + curve + if color_by[0].upper() == "CURVE" + else ensemble + if color_by[0].upper() == "ENSEMBLE" + else satnum + ) + show_legend = ( + bool(color_by == "CURVE" and ensemble_no == 0 and satnum_no == 0) + or bool(color_by == "ENSEMBLE" and curve_no == 0 and satnum_no == 0) + or bool(color_by == "SATNUM" and curve_no == 0 and ensemble_no == 0) + ) + color = ( + colorslist[color_by[0].lower()][ensemble] + if color_by[0].upper() == "ENSEMBLE" + else colorslist[color_by[0].lower()][curve] + if color_by[0].upper() == "ENSEMBLE" + else colorslist[color_by[0].lower()][satnum] + ) + data.extend( + _get_fanchart_traces( + df_stat[curve], + color, # str + xaxis, + yaxis, + legend_group, + show_legend, + curve, # str + ensemble, # str + satnum, # int + ) + ) + + return data + + def _get_fanchart_traces(curve_stats :pd.DataFrame, color : str, xaxis : str, yaxis : str, + legend_group: str, show_legend: bool, curve : str, ensemble : str, satnum : int) -> List : + """Renders a fanchart""" + + # Retrieve indices from one of the keys in series + x = curve_stats["nanmax"].index.tolist() + data = FanchartData( + samples=x, + low_high=LowHighData( + low_data=curve_stats["p90"].values, + low_name="P90", + high_data=curve_stats["p10"].values, + high_name="P10", + ), + minimum_maximum=MinMaxData( + minimum=curve_stats["nanmin"].values, + maximum=curve_stats["nanmax"].values, + ), + free_line=FreeLineData("Mean", curve_stats["nanmean"].values), + ) + + hovertemplate = f"{curve}
" f"Ensemble: {ensemble}, Satnum: {satnum}" + + return get_fanchart_traces( + data=data, + hex_color=color, + legend_group=legend_group, + xaxis=xaxis, + yaxis=yaxis, + hovertext=hovertemplate, + show_legend=show_legend, + ) + + def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by : List[str], y_axis : List[str]): + """ + Constructing plot layout from scratch as it is more responsive than plotly subplots package. + """ + titles = ( + ["Relative Permeability", "Capillary Pressure"] + if nplots == 2 + else ["Relative Permeability"] + if any(curve.startswith("KR") for curve in curves) + else ["Capillary Pressure"] + ) + layout = { + "hovermode": "closest", + "uirevision": f"sa:{sataxis}_{y_axis[0]}_curves:{'_'.join(sorted(curves))}", + } + # create subplots + layout.update( + { + "annotations": [ + { + "showarrow": False, + "text": titles[0], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 1.0, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + } + ], + } + if nplots == 1 + else { + "annotations": [ + { + "showarrow": False, + "text": titles[0], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 1.0, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + }, + { + "showarrow": False, + "text": titles[1], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 0.475, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + }, + ], + } + if nplots == 2 + else {} + ) + + layout["legend"] = {"title": {"text": color_by[0].lower().capitalize()}} + # format axes + if nplots == 1: + layout.update( + { + "xaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "range": [0, 1], + "anchor": "y", + "domain": [0.0, 1.0], + "title": {"text": sataxis[0].lower().capitalize(), "standoff": 15}, + "showgrid": False, + "tickmode": "auto", + }, + "yaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x", + "domain": [0.0, 1.0], + "type": y_axis[0], + "showgrid": False, + }, + "margin": {"t": 20, "b": 0}, + } + ) + if any(curve.startswith("KR") for curve in curves): + layout["yaxis"].update({"title": {"text": "kr"}}) + else: + layout["yaxis"].update({"title": {"text": "Pc"}}) + + elif nplots == 2: + layout.update( + { + "xaxis": { + "automargin": True, + "zeroline": False, + "anchor": "y", + "domain": [0.0, 1.0], + "matches": "x2", + "showticklabels": False, + "showgrid": False, + }, + "xaxis2": { + "automargin": True, + "ticks": "", + "showticklabels": True, + "zeroline": False, + "range": [0, 1], + "anchor": "y2", + "domain": [0.0, 1.0], + "title": {"text": sataxis[0].lower().capitalize()}, + "showgrid": False, + }, + "yaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x", + "domain": [0.525, 1.0], + "title": {"text": "kr"}, + "type": y_axis[0], + "showgrid": False, + }, + "yaxis2": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x2", + "domain": [0.0, 0.475], + "title": {"text": "Pc"}, + "type": y_axis[0], + "showgrid": False, + }, + "margin": {"t": 20, "b": 0}, + } + ) + return layout + + def filter_scal_df(df : pd.DataFrame, curves : List[str], satnums : List[str], sataxis : str): + df = df.copy() + df = df.loc[df["SATNUM"].isin(satnums)] + columns = ( + ["SATNUM", "CASE"] + + [sataxis] + + [curve for curve in curves if curve in df.columns] + ) + return df[columns].dropna() + + def add_scal_traces(df : pd.DataFrame, curves : List[str], sataxis : str, nplots : int): + """Renders scal recommendation traces""" + traces = [] + for curve_no, curve in enumerate( + [curve for curve in curves if curve in df.columns] + ): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + traces.extend( + [ + { + "type": "scatter", + "x": case_df[sataxis], + "y": case_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: {satnum}
" f"{case.lower().capitalize()}" + ), + "name": "SCAL", + "legendgroup": "SCAL", + "marker": { + "color": "black", + }, + "line": {"dash": "dash"}, + "showlegend": curve_no == 0 and satnum_no == 0 and case_no == 0, + } + for satnum_no, (satnum, satnum_df) in enumerate(df.groupby("SATNUM")) + for case_no, (case, case_df) in enumerate(satnum_df.groupby("CASE")) + ] + ) + return traces \ No newline at end of file From 9f6624866014e03893de3d55077ead764c9319ea Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 13:26:57 +0200 Subject: [PATCH 05/54] added postfix New --- webviz_subsurface/plugins/__init__.py | 1 + webviz_subsurface/plugins/_relative_permeability.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index 27a8548ac..3d87718b9 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -40,6 +40,7 @@ from ._property_statistics import PropertyStatistics from ._pvt_plot import PvtPlot from ._relative_permeability import RelativePermeability +from ._relative_permeability_new import RelativePermeabilityNew from ._reservoir_simulation_timeseries import ReservoirSimulationTimeSeries from ._reservoir_simulation_timeseries_onebyone import ( ReservoirSimulationTimeSeriesOneByOne, diff --git a/webviz_subsurface/plugins/_relative_permeability.py b/webviz_subsurface/plugins/_relative_permeability.py index b94c7cb03..ea36e8101 100644 --- a/webviz_subsurface/plugins/_relative_permeability.py +++ b/webviz_subsurface/plugins/_relative_permeability.py @@ -113,10 +113,10 @@ def __init__( for ens in ensembles } self.plotly_theme = webviz_settings.theme.plotly_theme - self.relpermfile = relpermfile + self.relpermfile = relpermfile # str if self.relpermfile is not None: - self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) - self.satfunc = self.satfunc.rename(str.upper, axis="columns").rename( + self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) # csv file + self.satfunc = self.satfunc.rename(str.upper, axis="columns").rename( # redefining the csv file (still csv file) columns={"TYPE": "KEYWORD"} ) if "KEYWORD" not in self.satfunc.columns: @@ -133,7 +133,7 @@ def __init__( if key != "Missing" ] ) - self.satfunc = self.satfunc[ + self.satfunc = self.satfunc[ # taking out the valid columns [col for col in self.satfunc.columns if col in valid_columns] ] else: From 12d52c51ee42403b3ebcfd2a3a7d8e96d7deec40 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 13:47:26 +0200 Subject: [PATCH 06/54] edit filter --- .../shared_settings/_filter.py | 88 ------------------- 1 file changed, 88 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py index 74c79aad1..06617e758 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -12,11 +12,8 @@ class Filter(SettingsGroupABC): """ Added by MoNezhadali 06.22 """ -<<<<<<< HEAD -======= def __init__(self, relperm_df: pd.DataFrame) -> None: super().__init__("Filter") ->>>>>>> origin/relperm class Ids: class Selectors: SATURATION_AXIS="saturation-axis" @@ -32,90 +29,6 @@ class SCALRecommendation: ## todo: the selectors will be defined here after getting to know the data -<<<<<<< HEAD - class Selectors: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("Selectors") - - def layout(self) -> List(Component): - return [ - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), - label="Saturation axis", - options=[{"label":i, "value":i} for i in range(self.sat_axes)], - value=self.sat_axes[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), - label="Color by", - options=[{"label":i, "value":i} for i in range(self.color_options)], - value=self.color_options[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), - label="Ensembles", - options=[{"label":i, "value":i} for i in range(self.ensembles)], - value=self.ensembles[0], - multi=True, - size=min(5,len(self.ensembles)), - ), - # This needs to be checked - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), - label="Curves", - options=[{"label":i, "value":i} for i in range(self.curves)], - value=self.color_options[0], - multi=False, - size=1, - ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), - label="Satnum", - options=[{"label":i, "value":i} for i in range(self.satnums)], - value=self.ensembles[0], - multi=True, - size=min(5,len(self.ensembles)), - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", - ), - ) - def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: - return saturation_axis - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", - ), - ) - def _set_color_by(color_by: List[str]) -> List[str]: - return color_by - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", - ), - ) - def _set_ensembles(ensembles: List[str]) -> List[str]: - return ensembles - - @callback( Output( self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" ), @@ -430,6 +343,5 @@ def set_callbacks(self) -> None: def _set_scal_recommendation(scal_recommendation: List[str]) -> List[str]: return scal_recommendation ->>>>>>> origin/relperm \ No newline at end of file From 4cb283f32db30ad079ee845b60a75244d85bf6d4 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 14:02:35 +0200 Subject: [PATCH 07/54] try again --- .../_relative_permeability_new/__init__.py | 4 - .../_relative_permeability_new/_plugin.py | 48 -- .../shared_settings/__init__.py | 4 - .../views/relperm_cappres/_relcap.py | 572 ++++++++++++++++-- 4 files changed, 514 insertions(+), 114 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py index 16918a14d..ce9a0f660 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py @@ -1,5 +1 @@ from ._plugin import RelativePermeabilityNew -<<<<<<< HEAD -======= - ->>>>>>> origin/relperm diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index 92cc8d6cd..1be8b159b 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -1,25 +1,3 @@ -<<<<<<< HEAD -# import from python -from typing import Type -from pathlib import Path - -# packages from installed stuff -from dash.development.base_component import Component -import pandas as pd -from webviz_config import WebvizPluginABC - -# own imports -#from ._error import error -from ._plugin_ids import PlugInIDs # importing the namespace -from .shared_settings import Filter - -class RelativePermeabilityNew(WebvizPluginABC): - def __init__(self, path_to_relpermfile: Path ) -> None: - super().__init__(stretch=True) # super refer to class inhereted from, init from ABC - - # set a member, self first for all - self.error_message = "" -======= # import from python builtin from typing import Type, Optional, Union from pathlib import Path @@ -75,18 +53,10 @@ def __init__(self, webviz_settings: WebvizSettings,relpermfile: str, ensembles: / "css" / "block_options.css" ) ->>>>>>> origin/relperm # when reading from file must check that these are the keywords, if not raise ValueError try: -<<<<<<< HEAD - self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame - except PermissionError: - self.error_message = ( - f"Access to file '{path_to_relpermfile}' denied. " - f"Please check your path for '{path_to_relpermfile}' and make sure you have access to it." -======= #self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame self.ens_paths = { ens: WebvizSettings.shared_settings["scratch_ensembles"][ens] @@ -315,33 +285,16 @@ def __init__( self.error_message = ( f"Access to file '{relpermfile}' denied. " f"Please check your path for '{relpermfile}' and make sure you have access to it." ->>>>>>> origin/relperm ) return except FileNotFoundError: self.error_message = ( -<<<<<<< HEAD - f"The file {path_to_relpermfile}' not found." -======= f"The file {relpermfile}' not found." ->>>>>>> origin/relperm "Please check you path" ) return except pd.errors.ParserError: self.error_message = ( -<<<<<<< HEAD - f"The file '{path_to_relpermfile}' is not a valid csv file." - ) - except pd.errors.EmptyDataError: - self.error_message = ( - f"The file '{path_to_relpermfile}' is an empty file." - ) - except Exception: - self.error_message = ( - f"Unknown exception when trying to read '{path_to_relpermfile}" - ) -======= f"The file '{relpermfile}' is not a valid csv file." ) except pd.errors.EmptyDataError: @@ -379,4 +332,3 @@ def layout(self) -> Type[Component]: return error(self.error_message) ->>>>>>> origin/relperm diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py index 90bfefea3..4ff5ac9e5 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py @@ -1,5 +1 @@ -<<<<<<< HEAD -from ._filter import Filter -======= from ._filter import Filter, Selectors, Visualization, Scal_recommendation ->>>>>>> origin/relperm diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py index 750f2c7c1..834eda703 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -1,23 +1,27 @@ +from fcntl import LOCK_WRITE +from pydoc import doc from typing import List, Tuple, Optional, Union from pathlib import Path from dash import callback, Input, Output, State +from matplotlib.pyplot import figure import pandas as pd +import numpy as np import plotly.colors +from dash.exceptions import PreventUpdate from webviz_config.webviz_plugin_subclasses import ViewABC +from webviz_config import WebvizPluginABC, WebvizSettings from ..._plugin_ids import PlugInIDs from ...view_elements import Graph +from ....._utils.fanchart_plotting import FanchartData, FreeLineData, LowHighData, MinMaxData, get_fanchart_traces class RelpermCappres(ViewABC): '''Add comment descibring the plugin''' class IDs: '''Different curves to be shown in the view''' #pylint: disable=too-few-public-methods - # en ID pr view element; ett eller to view element? - # tror jeg går for to view elements RELATIVE_PERMEABILIY = "reative-permeability" - CAPILAR_PRESSURE = "capilar-pressure" # don't think I need these '''KRW = "KRW" @@ -37,21 +41,10 @@ class RelpermFamilies: # the possible keywords in the data files needed in list SGFN = "SGFN" SOF3 = "SOF3"''' - # maybe need to add a create csv file in the main class to create one csv file SATURATIONS = ["SW", "SO", "SG", "SL"] - RELPERM_FAMILIES = ["SWOF", "SGOF", "SLGOF","SWFN", "SGFN", "SOF3"] - ENSAMBLES = ["iter-0","iter-3"] - GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] - - # må ha en utvidet csv fil som har realization og ensamble kolonne - valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + SATURATIONS + GRAPHS) - - - # stat types; should include al so it works on all data (copied) - SATURATIONS = ["SW", "SO", "SG", "SL"] # only sw and sg are used so far RELPERM_FAMILIES = { - 1: ["SWOF", "SGOF", "SLGOF"], # only SWOF and SGOF re use in test data + 1: ["SWOF", "SGOF", "SLGOF"], 2: ["SWFN", "SGFN", "SOF3"], } SCAL_COLORMAP = { @@ -63,9 +56,14 @@ class RelpermFamilies: # the possible keywords in the data files needed in list "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) "PCOG": "#555555", } + + # this might change when there is a different dataset + ''' ENSAMBLES = ["iter-0","iter-3"] + GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] ''' - def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: + def __init__(self, relperm_df: pd.DataFrame, webviz_settings : WebvizSettings) -> None: + # scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: # scalfile: Path = None; sets the scal file to be used, if any # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate super().__init__("Relatve permeability") @@ -108,63 +106,521 @@ def __init__(self,ensambles: List, relperm_df: pd.DataFrame, scalfile: Path = No X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 ''' - # extracte the data for the different graphs from the data source relperm_df - self.relperm_df = relperm_df # sets the data frame - - # er det egt flere som kan kunne plottes, men siden det kuner tatt ensyn til sg og sw foreløpig er det bare disse? - # skal vi inludere for utvidelse eller bare markere hvor det kan legges inn? + self.relperm_df = relperm_df + # file with columns: ['ENSEMBLE', 'REAL', 'SW', 'KRW', 'KROW', 'PCOW', 'SATNUM', 'KEYWORD','SG', 'KRG', 'KROG', 'PCOG'] - # df for SW og SG - self.df_SW = self.relperm_df[relperm_df["KEYWORD"] == "SGOF"] - self.df_SG = self.relperm_df[relperm_df["KEYWORD"] == "SWOF"] - - - self.satnum1 = self.relperm_df[self.relperm_df["SATNUM"] == 1] # dette er velidg ueffektivt, er 12 satnum + self.plotly_theme = webviz_settings.theme.plotly_theme + # the first setting that ou have to choose is between gaas and water, you never have both so can split the dataset in two + self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SWOF"] + self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SGOF"] # creating the columns and row to define the setup of the view column = self.add_column() first_row = column.make_row() first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) - # change something in Graph() ot be able to get them in the same plot, or add them as on view element? - # need the height of the Graph() to vary wether we are suppoed to show to graphs or not + + @property + def sat_axes(self): + """List of all possible saturation axes in dataframe""" + return [sat for sat in self.sat_axes_maps if sat in self.satfunc.columns] + + @property + def ensembles(self): + '''List of al possible unique ensembles''' + return list(self.satfunc["ENSEMBLE"].unique()) + + @property + def satnums(self): + '''List of all posible satnums''' + return list(self.satfunc["SATNUM"].unique()) - second_row = column.make_row() - second_row.add_view_element(Graph(),RelpermCappres.IDs.CAPILAR_PRESSURE) + @property + def color_options(self): + """Options to color by""" + return ["ENSEMBLE", "CURVE", "SATNUM"] + + @property + def ens_colors(self): + return { + ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] + for ens in self.ensembles + } + + @property + def satnum_colors(self): + return { + satnum: self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum)] + for satnum in self.satnums + } - # define the callbacks of the view def set_callbacks(self) -> None: - # callback for the graphs + '''Defines the callbacks for the view element''' @callback( - Output(self.get_unique_id(Graph(),"figure")), # need to be changed - Input(self.uuid("color_by"), "value"), - Input(self.uuid("visualization"), "value"), - Input(self.uuid("ensemble"), "value"), - Input(self.uuid("curve"), "value"), - Input(self.uuid("satnum"), "value"), - Input(self.uuid("sataxis"), "value"), - Input(self.uuid("linlog"), "value"), - Input(self.uuid("scal"), "value"), - ) - def _update_graph(color_by, visualization, ensembles, curves, satnums, sataxis, linlog, scal) -> dict: - colors = plotly.colors.DEFAULT_PLOTLY_COLORS + Output(self.view_element(RelpermCappres.IDs.RELATIVE_PERMEABILIY).component_unique_id(Graph.IDs.GRAPH).to_string(),"figure"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data"), - # callback function for the ensamble selector - @callback( - Output(self.uuid("ensemble"), "multi"), - Output(self.uuid("ensemble"), "value"), - Input(self.uuid("color_by"), "value"), - State(self.uuid("stored_ensemble"), "data") #need to fin out how this works + Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES),"data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS),"data"), + + Input(self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL),"data"), ) - def _set_ensamble_selector(color_by, stored_ensemble): - """If ensemble is selected as color by, set the ensemble - selector to allow multiple selections, else use stored_ensemble + def _update_graph(sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], + line_traces : List[str], y_axis : List[str], scal : List[str]) -> dict: + ensemble_colors = {"iter-0":"#285d93","iter-3":"#e48c16"} + curve_colors = {"KRW":"#0000aa","KRG":"#ff0000","KROG":"#00aa00","KROW":"#00aa00","PCOW":"#555555","PCOG":"#555555"} + satnum_colors = { + "1": "#285d93", + "2": "#e48c16", + "3": "#00aa00", + "4": "#cc0000", + "5": "#9f66bb", + "6": "#b17750", + "7": "#d59bc5", + "8": "#555555", + "9": "#b9c15b", + "10": "#5bf2e6", + "11": "#ff0000", + "12": "#45f03a" + } + colors = {"ensemble": ensemble_colors, "curve": curve_colors, "satnum": satnum_colors} + + if not curves or not satnums: # Curve and satnum has to be defined + raise PreventUpdate + if ensembles is None: # Allowing no ensembles to plot only SCAL data + ensembles = [] + + df = self.SG_df if sataxis[0].upper() == "SG" else self.SW_df + + nplots = ( + 2 + if any(curve.startswith("PC") for curve in curves) + and any(curve.startswith("KR") for curve in curves) + else 1 + ) + + layout = plot_layout(nplots,curves,sataxis,color_by,y_axis) + + if line_traces[0].lower() == "individual realization" and not df.empty: + data = realization_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) + elif line_traces[0].lower() == "statistical fanchart" and not df.empty: + data = statistic_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) + + if self.scal is not None and "show_scal" in scal: + scal_df = filter_scal_df(self.scal, curves, satnums, sataxis[0]) + data.extend(add_scal_traces(scal_df, curves, sataxis[0], nplots)) + + return {"data": data, "layout": layout} + + + + + + def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], + curves : List[str], satnums : List[str], line_traces : List[str], y_axis : List[str], + scal : List[str], colorslist : dict, nplots : int) -> List: + realizatoins = df["REAL"].unique() # list of all possible realizations + # traces = [i for i in range(len(realizatoins))] + colors = colorslist[color_by[0].lower()] + + # my version + ''' + if color_by[0].lower() == "ensemble": + data = [ + { + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]].loc[df["SATNUM"] == satnums[0]] + .dropna(axis = "columns", how = "all")[curves[curve]].values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]] + .loc[df["SATNUM"] == satnums[0]].dropna(axis = "columns", how = "all")[sataxis[0]].values.tolist()), # must include for linear or loganithmic + "type" : "line", + "legendgroup": iter, + "color" : colors[iter], + "showlegend": realization_iter == 0 and curvenum == 0, + } + for realization_iter,realization in enumerate(realizatoins) + for iter in ensembles + for curvenum,curve in enumerate(curves) + ] + layout = plot_layout(nplots,curves,sataxis,color_by,y_axis), + elif color_by[0].lower() == "curve": + data = [ + { # trenger man tolist() og list? og må man ha med [0] + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] + [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] + [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), + "type" : "line", + "legendgroup": curve, + "color" : colors[curve], + "showlegend": realization_iter == 0, + } + for realization_iter,realization in enumerate(realizatoins) + for curve in curves + ] + else: + data = [ + { + "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] + [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), + "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] + [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), + "type" : "line", + "legendgroup": curve, + "color" : colors[satnum], + "showlegend": realization_iter == 0 and curvenum == 0, + } + for satnumiter,satnum in enumerate(satnums) + for realization_iter,realization in enumerate(realizatoins) + for curvenum,curve in enumerate(curves) + ] + ''' + + data = [] + + for curve_no, curve in enumerate(curves): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + if color_by == "CURVE": + satnum = df["SATNUM"].iloc[0] + ensemble = df["ENSEMBLE"].iloc[0] + + data.extend( + [ + { + "type": "scatter", + "x": real_df[sataxis[0]], + "y": real_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: {satnum[0]}
" + f"Realization: {real}, Ensemble: {ensemble}" + ), + "name": curve, + "legendgroup": curve, + "marker": { + "color": colors.get(curve, colors[list(colors.keys())[0]]) + }, + "showlegend": real_no == 0, + } + for real_no, (real, real_df) in enumerate(df.groupby("REAL")) + ] + ) + else: + constant_group = ( + df["SATNUM"].iloc[0] + if color_by == "ENSEMBLE" + else df["ENSEMBLE"].iloc[0] + ) + data.extend( + [ + { + "type": "scatter", + "x": real_df[sataxis[0]], + "y": real_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: " + f"{group if color_by[0].upper() == 'SATNUM' else constant_group}
" + f"Realization: {real}, Ensemble: " + f"{group if color_by[0].upper() == 'ENSEMBLE' else constant_group}" + ), + "name": group, + "legendgroup": group, + "marker": { + "color": colors.get(group, colors[list(colors.keys())[-1]]) + }, + "showlegend": real_no == 0 and curve_no == 0, + } + for (group, grouped_df) in df.groupby(color_by[0]) + for real_no, (real, real_df) in enumerate( + grouped_df.groupby("REAL") + ) + ] + ) + return data + + def statistic_traces(df : pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], + line_traces : List[str], y_axis : List[str], scal : List[str], colorslist: dict, nplots : int) -> List: + # Switched P10 and P90 due to convetion in petroleum industry + def p10(x): + return np.nanpercentile(x, q=90) + + def p90(x): + return np.nanpercentile(x, q=10) + + data = [] # str #pd.Dataframe + for ensemble_no, (ensemble, ensemble_df) in enumerate( + df[["ENSEMBLE", "SATNUM"] + [sataxis[0]] + curves].groupby(["ENSEMBLE"]) + ): # int + for satnum_no, (satnum, satnum_df) in enumerate(ensemble_df.groupby("SATNUM")): + df_stat = ( + satnum_df.groupby(sataxis[0]) + .agg([np.nanmean, np.nanmin, np.nanmax, p10, p90]) + .stack() + .swaplevel() + ) + for curve_no, curve in enumerate(curves): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + legend_group = ( + curve + if color_by[0].upper() == "CURVE" + else ensemble + if color_by[0].upper() == "ENSEMBLE" + else satnum + ) + show_legend = ( + bool(color_by == "CURVE" and ensemble_no == 0 and satnum_no == 0) + or bool(color_by == "ENSEMBLE" and curve_no == 0 and satnum_no == 0) + or bool(color_by == "SATNUM" and curve_no == 0 and ensemble_no == 0) + ) + color = ( + colorslist[color_by[0].lower()][ensemble] + if color_by[0].upper() == "ENSEMBLE" + else colorslist[color_by[0].lower()][curve] + if color_by[0].upper() == "ENSEMBLE" + else colorslist[color_by[0].lower()][satnum] + ) + data.extend( + _get_fanchart_traces( + df_stat[curve], + color, # str + xaxis, + yaxis, + legend_group, + show_legend, + curve, # str + ensemble, # str + satnum, # int + ) + ) + + return data + + def _get_fanchart_traces(curve_stats :pd.DataFrame, color : str, xaxis : str, yaxis : str, + legend_group: str, show_legend: bool, curve : str, ensemble : str, satnum : int) -> List : + """Renders a fanchart""" + + # Retrieve indices from one of the keys in series + x = curve_stats["nanmax"].index.tolist() + data = FanchartData( + samples=x, + low_high=LowHighData( + low_data=curve_stats["p90"].values, + low_name="P90", + high_data=curve_stats["p10"].values, + high_name="P10", + ), + minimum_maximum=MinMaxData( + minimum=curve_stats["nanmin"].values, + maximum=curve_stats["nanmax"].values, + ), + free_line=FreeLineData("Mean", curve_stats["nanmean"].values), + ) + + hovertemplate = f"{curve}
" f"Ensemble: {ensemble}, Satnum: {satnum}" + + return get_fanchart_traces( + data=data, + hex_color=color, + legend_group=legend_group, + xaxis=xaxis, + yaxis=yaxis, + hovertext=hovertemplate, + show_legend=show_legend, + ) + + def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by : List[str], y_axis : List[str]): + """ + Constructing plot layout from scratch as it is more responsive than plotly subplots package. """ + titles = ( + ["Relative Permeability", "Capillary Pressure"] + if nplots == 2 + else ["Relative Permeability"] + if any(curve.startswith("KR") for curve in curves) + else ["Capillary Pressure"] + ) + layout = { + "hovermode": "closest", + "uirevision": f"sa:{sataxis}_{y_axis[0]}_curves:{'_'.join(sorted(curves))}", + } + # create subplots + layout.update( + { + "annotations": [ + { + "showarrow": False, + "text": titles[0], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 1.0, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + } + ], + } + if nplots == 1 + else { + "annotations": [ + { + "showarrow": False, + "text": titles[0], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 1.0, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + }, + { + "showarrow": False, + "text": titles[1], + "x": 0.5, + "xanchor": "center", + "xref": "paper", + "y": 0.475, + "yanchor": "bottom", + "yref": "paper", + "font": {"size": 16}, + }, + ], + } + if nplots == 2 + else {} + ) - # callback function for the curve selector - @callback( + layout["legend"] = {"title": {"text": color_by[0].lower().capitalize()}} + # format axes + if nplots == 1: + layout.update( + { + "xaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "range": [0, 1], + "anchor": "y", + "domain": [0.0, 1.0], + "title": {"text": sataxis[0].lower().capitalize(), "standoff": 15}, + "showgrid": False, + "tickmode": "auto", + }, + "yaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x", + "domain": [0.0, 1.0], + "type": y_axis[0], + "showgrid": False, + }, + "margin": {"t": 20, "b": 0}, + } + ) + if any(curve.startswith("KR") for curve in curves): + layout["yaxis"].update({"title": {"text": "kr"}}) + else: + layout["yaxis"].update({"title": {"text": "Pc"}}) - ) - def _set_curve_selector() \ No newline at end of file + elif nplots == 2: + layout.update( + { + "xaxis": { + "automargin": True, + "zeroline": False, + "anchor": "y", + "domain": [0.0, 1.0], + "matches": "x2", + "showticklabels": False, + "showgrid": False, + }, + "xaxis2": { + "automargin": True, + "ticks": "", + "showticklabels": True, + "zeroline": False, + "range": [0, 1], + "anchor": "y2", + "domain": [0.0, 1.0], + "title": {"text": sataxis[0].lower().capitalize()}, + "showgrid": False, + }, + "yaxis": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x", + "domain": [0.525, 1.0], + "title": {"text": "kr"}, + "type": y_axis[0], + "showgrid": False, + }, + "yaxis2": { + "automargin": True, + "ticks": "", + "zeroline": False, + "anchor": "x2", + "domain": [0.0, 0.475], + "title": {"text": "Pc"}, + "type": y_axis[0], + "showgrid": False, + }, + "margin": {"t": 20, "b": 0}, + } + ) + return layout + + def filter_scal_df(df : pd.DataFrame, curves : List[str], satnums : List[str], sataxis : str): + df = df.copy() + df = df.loc[df["SATNUM"].isin(satnums)] + columns = ( + ["SATNUM", "CASE"] + + [sataxis] + + [curve for curve in curves if curve in df.columns] + ) + return df[columns].dropna() + + def add_scal_traces(df : pd.DataFrame, curves : List[str], sataxis : str, nplots : int): + """Renders scal recommendation traces""" + traces = [] + for curve_no, curve in enumerate( + [curve for curve in curves if curve in df.columns] + ): + yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" + xaxis = "x" if yaxis == "y" else "x2" + traces.extend( + [ + { + "type": "scatter", + "x": case_df[sataxis], + "y": case_df[curve], + "xaxis": xaxis, + "yaxis": yaxis, + "hovertext": ( + f"{curve}, Satnum: {satnum}
" f"{case.lower().capitalize()}" + ), + "name": "SCAL", + "legendgroup": "SCAL", + "marker": { + "color": "black", + }, + "line": {"dash": "dash"}, + "showlegend": curve_no == 0 and satnum_no == 0 and case_no == 0, + } + for satnum_no, (satnum, satnum_df) in enumerate(df.groupby("SATNUM")) + for case_no, (case, case_df) in enumerate(satnum_df.groupby("CASE")) + ] + ) + return traces \ No newline at end of file From f07279d095c83877bc3bea881f73661d1a3a5462 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 15:40:34 +0200 Subject: [PATCH 08/54] fix filter.py --- .../shared_settings/_filter.py | 98 ------------------- 1 file changed, 98 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py index 06617e758..d2ed85613 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -29,104 +29,6 @@ class SCALRecommendation: ## todo: the selectors will be defined here after getting to know the data - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", - ), - ) - def _set_curves(curves: List[str]) -> List[str]: - return curves - - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" - ), - Input( - self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", - ), - ) - def _set_saturation_axis(satnum: List[str]) -> List[str]: - return satnum - - - class Visualization: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("Visualization") - def layout(self) -> List(Component): - return [ - wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), - label="Line traces", - options=[ - {"label":"Individual realization","value":"individual-realization"}, - {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, - ], - value="statistical-fanchart", - ), - wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), - label="Y-axis", - options=[ - {"label":"Linear","value":"linear"}, - {"label":"Log", "value":"log"}, - ], - value="linear", - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", - ), - ) - def _set_line_traces(line_traces: List[str]) -> List[str]: - return line_traces - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", - ), - ) - def _set_y_axis(y_axis: List[str]) -> List[str]: - return y_axis - - - class Scal_recommendation: - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("SCAL recommendation") - def layout(self) -> List(Component): - return [ - wcc.Checklist( - id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), - label="", - options=[ - { - "label": "Show SCAL", - "value": "show_scal", - }, - ] - ), - ] - def set_callbacks(self) -> None: - @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value - ), - Input( - self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", - ), - ) - def _set_line_traces(line_traces: List[str]) -> List[str]: - return line_traces - -======= class Selectors(Filter): def __init__(self, relperm_df: pd.DataFrame,plotly_theme,sat_axes_maps) -> None: super().__init__("Selectors") From 6124699ed920c6eb2cd3e8bad4b04907b57b4408 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Tue, 5 Jul 2022 16:00:52 +0200 Subject: [PATCH 09/54] Added imports for the view --- webviz_subsurface/plugins/_relative_permeability_new/_plugin.py | 1 + .../plugins/_relative_permeability_new/views/__init__.py | 1 + .../_relative_permeability_new/views/relperm_cappres/__init__.py | 1 + 3 files changed, 3 insertions(+) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index 1be8b159b..588c79aaa 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -18,6 +18,7 @@ from .shared_settings import Filter, Selectors, Visualization , Scal_recommendation from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation +from .views import RelpermCappres class TestView(ViewABC): class Ids: diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py index e69de29bb..a4031e567 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py @@ -0,0 +1 @@ +from .relperm_cappres import RelpermCappres \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py index e69de29bb..06715b8b2 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py @@ -0,0 +1 @@ +from ._relcap import RelpermCappres \ No newline at end of file From 24031ee80ee865838f384c3b26185f9f6d44b206 Mon Sep 17 00:00:00 2001 From: "Mohammad Nezhadali (OG SUB RPE)" Date: Thu, 7 Jul 2022 10:33:14 +0200 Subject: [PATCH 10/54] Not finalized filter --- .../shared_settings/_filter.py | 82 ++++++++++++++++--- 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py index d2ed85613..b8917783c 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -1,6 +1,6 @@ -from typing import List +from typing import List, Tuple, Dict -from dash import callback, Input, Output +from dash import callback, Input, Output, State from dash.development.base_component import Component import pandas as pd from webviz_config.webviz_plugin_subclasses import SettingsGroupABC @@ -29,7 +29,7 @@ class SCALRecommendation: ## todo: the selectors will be defined here after getting to know the data -class Selectors(Filter): +class Selectors(SettingsGroupABC): def __init__(self, relperm_df: pd.DataFrame,plotly_theme,sat_axes_maps) -> None: super().__init__("Selectors") self.satfunc=relperm_df @@ -135,16 +135,32 @@ def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: def _set_color_by(color_by: List[str]) -> List[str]: return color_by + @callback( + Output( + self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(),"multi" + ), + Output( + self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(),"value" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + ), + ) + def _set_ensembles_interaction(color_by:str) -> Tuple[bool, List[str]]: + if color_by=="ENSEMBLE": + return [True, self.ensembles] + return [False, self.ensembles[0]] + @callback( Output( self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" ), Input( self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", - ), + ), ) - def _set_ensembles(ensembles: List[str]) -> List[str]: - return ensembles + def _set_ensembles(stored_ensemble: List[str]) -> List[str]: + return stored_ensemble @callback( Output( @@ -154,8 +170,31 @@ def _set_ensembles(ensembles: List[str]) -> List[str]: self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", ), ) - def _set_curves(curves: List[str]) -> List[str]: + def _set_curves(curves: str) -> List[str]: return curves + + @callback( + Output( + self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(),"value" + ), + Output( + self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(),"options" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + ), + ) + def _set_curves_interactions(sataxis: str) -> Tuple[List[str],List[Dict]]: + return ( + self.sat_axes_maps[sataxis], + [ + { + "label": i, + "value": i, + } + for i in self.sat_axes_maps[sataxis] + ], + ) @callback( Output( @@ -165,11 +204,30 @@ def _set_curves(curves: List[str]) -> List[str]: self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", ), ) - def _set_saturation_axis(satnum: List[str]) -> List[str]: - return satnum + def _set_saturation_axis(stored_satnum: List[str]) -> List[str]: + return stored_satnum + + @callback( + Output( + self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(),"multi" + ), + Output( + self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(),"value" + ), + Input( + self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + ), + ) + def _set_saturation_axis_interactions(color_by: str) -> Tuple[bool, List[str]]: + if color_by == "SATNUM": + return [True, self.satnums] + + return [ + False, self.satnums[0], + ] -class Visualization(Filter): +class Visualization(SettingsGroupABC): def __init__(self, relperm_df: pd.DataFrame) -> None: super().__init__("Visualization") def layout(self) -> List[Component]: @@ -215,7 +273,9 @@ def _set_line_traces(line_traces: List[str]) -> List[str]: def _set_y_axis(y_axis: List[str]) -> List[str]: return y_axis -class Scal_recommendation(Filter): +class Scal_recommendation(SettingsGroupABC): + def __init__(self, relperm_df: pd.DataFrame) -> None: + super().__init__("SCAL Recommendation") ''' def __init__(self, rel_perm_df: pd.DataFrame) -> None: self.super().__init__("SCAL recommendation") From f766d4a9285219870f28334cf9e5099fcc6c8bbf Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 08:30:59 +0200 Subject: [PATCH 11/54] finished view --- .../_relative_permeability_new/_plugin.py | 114 +++-- .../view_elements/_graph.py | 16 +- .../views/relperm_cappres/__init__.py | 2 +- .../views/relperm_cappres/_relcap.py | 462 ++++++++++++------ 4 files changed, 377 insertions(+), 217 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index 588c79aaa..a6e3f2012 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -14,12 +14,13 @@ # own imports from ._error import error -from ._plugin_ids import PlugInIDs # importing the namespace -from .shared_settings import Filter, Selectors, Visualization , Scal_recommendation +from ._plugin_ids import PlugInIDs # importing the namespace +from .shared_settings import Filter, Selectors, Visualization, Scal_recommendation from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from .views import RelpermCappres + class TestView(ViewABC): class Ids: # pylint: disable=too-few-public-methods @@ -27,6 +28,8 @@ class Ids: def __init__(self, population_df: pd.DataFrame) -> None: super().__init__("Population indicators") + + """ class RelativePermeabilityNew(WebvizPluginABC): @@ -147,6 +150,7 @@ class RelativePermeabilityNew(WebvizPluginABC): * [Example of scalfile](https://github.com/equinor/\ webviz-subsurface-testdata/blob/master/reek_history_match/share/scal/scalreek.csv). """ + class PlotOptions: SATURATIONS = ["SW", "SO", "SG", "SL"] RELPERM_FAMILIES = { @@ -170,7 +174,7 @@ def __init__( relpermfile: str = None, scalfile: Path = None, sheet_name: Optional[Union[str, int, list]] = None, - ): + ): # må sjekke at disse inputsene er rett (samme som ols) super().__init__() @@ -188,13 +192,15 @@ def __init__( # if relpermfile is not None: # self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) self.ens_paths = { - ens: webviz_settings.shared_settings["scratch_ensembles"][ens] - for ens in ensembles + ens: webviz_settings.shared_settings["scratch_ensembles"][ens] + for ens in ensembles } self.plotly_theme = webviz_settings.theme.plotly_theme self.relpermfile = relpermfile if self.relpermfile is not None: - self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) + self.satfunc = load_csv( + ensemble_paths=self.ens_paths, csv_file=relpermfile + ) self.satfunc = self.satfunc.rename(str.upper, axis="columns").rename( columns={"TYPE": "KEYWORD"} ) @@ -217,16 +223,16 @@ def __init__( ] else: self.satfunc = load_satfunc(self.ens_paths) - + if any( - keyword in self.PlotOptions.RELPERM_FAMILIES[1] - for keyword in self.satfunc["KEYWORD"].unique() - ): + keyword in self.PlotOptions.RELPERM_FAMILIES[1] + for keyword in self.satfunc["KEYWORD"].unique() + ): self.family = 1 if any( keyword in self.PlotOptions.RELPERM_FAMILIES[2] for keyword in self.satfunc["KEYWORD"].unique() - ): + ): warnings.warn( ( "Mix of keyword family 1 and 2, currently only support one family at the " @@ -259,8 +265,8 @@ def __init__( "SL": ["KRG", "KROG", "PCOG"], } elif not all( - keyword in self.PlotOptions.RELPERM_FAMILIES[2] - for keyword in self.satfunc["KEYWORD"].unique() + keyword in self.PlotOptions.RELPERM_FAMILIES[2] + for keyword in self.satfunc["KEYWORD"].unique() ): raise ValueError( "Unrecognized saturation table keyword in data. This should not occur unless " @@ -280,7 +286,6 @@ def __init__( if self.scalfile is not None else None ) - except PermissionError: self.error_message = ( @@ -290,46 +295,63 @@ def __init__( return except FileNotFoundError: self.error_message = ( - f"The file {relpermfile}' not found." - "Please check you path" + f"The file {relpermfile}' not found." "Please check you path" ) return except pd.errors.ParserError: - self.error_message = ( - f"The file '{relpermfile}' is not a valid csv file." - ) + self.error_message = f"The file '{relpermfile}' is not a valid csv file." except pd.errors.EmptyDataError: - self.error_message = ( - f"The file '{relpermfile}' is an empty file." - ) + self.error_message = f"The file '{relpermfile}' is an empty file." except Exception: - self.error_message = ( - f"Unknown exception when trying to read '{relpermfile}" - ) - - self.add_store(PlugInIDs.Stores.Selectors.SATURATION_AXIS,WebvizPluginABC.StorageType.SESSION) - self.add_store(PlugInIDs.Stores.Selectors.COLOR_BY,WebvizPluginABC.StorageType.SESSION) - self.add_store(PlugInIDs.Stores.Selectors.ENSAMBLES,WebvizPluginABC.StorageType.SESSION) - self.add_store(PlugInIDs.Stores.Selectors.CURVES,WebvizPluginABC.StorageType.SESSION) - self.add_store(PlugInIDs.Stores.Selectors.SATNUM,WebvizPluginABC.StorageType.SESSION) - self.add_shared_settings_group(Selectors(self.satfunc,self.plotly_theme,self.sat_axes_maps), - PlugInIDs.SharedSettings.SELECTORS) + self.error_message = f"Unknown exception when trying to read '{relpermfile}" - - self.add_store(PlugInIDs.Stores.Visualization.LINE_TRACES,WebvizPluginABC.StorageType.SESSION) - self.add_store(PlugInIDs.Stores.Visualization.Y_AXIS,WebvizPluginABC.StorageType.SESSION) - self.add_shared_settings_group(Visualization(self.satfunc),PlugInIDs.SharedSettings.VISUALIZATION) - ''' - self.add_store(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL,WebvizPluginABC.StorageType.SESSION) - self.add_shared_settings_group(Scal_recommendation(self.satfunc),PlugInIDs.SharedSettings.SCAL_RECOMMENDATION) - ''' - self.add_view(TestView(self.satfunc),PlugInIDs.RelCapViewGroup.RELCAP,PlugInIDs.RelCapViewGroup.GROUP_NAME) + self.add_store( + PlugInIDs.Stores.Selectors.SATURATION_AXIS, + WebvizPluginABC.StorageType.SESSION, + ) + self.add_store( + PlugInIDs.Stores.Selectors.COLOR_BY, WebvizPluginABC.StorageType.SESSION + ) + self.add_store( + PlugInIDs.Stores.Selectors.ENSAMBLES, WebvizPluginABC.StorageType.SESSION + ) + self.add_store( + PlugInIDs.Stores.Selectors.CURVES, WebvizPluginABC.StorageType.SESSION + ) + self.add_store( + PlugInIDs.Stores.Selectors.SATNUM, WebvizPluginABC.StorageType.SESSION + ) + self.add_shared_settings_group( + Selectors(self.satfunc, self.plotly_theme, self.sat_axes_maps), + PlugInIDs.SharedSettings.SELECTORS, + ) - + self.add_store( + PlugInIDs.Stores.Visualization.LINE_TRACES, + WebvizPluginABC.StorageType.SESSION, + ) + self.add_store( + PlugInIDs.Stores.Visualization.Y_AXIS, WebvizPluginABC.StorageType.SESSION + ) + self.add_shared_settings_group( + Visualization(self.satfunc), PlugInIDs.SharedSettings.VISUALIZATION + ) + + self.add_store( + PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL, + WebvizPluginABC.StorageType.SESSION, + ) + self.add_shared_settings_group( + Scal_recommendation(self.satfunc), + PlugInIDs.SharedSettings.SCAL_RECOMMENDATION, + ) + + self.add_view( + RelpermCappres(self.satfunc, webviz_settings, self.scal), + PlugInIDs.RelCapViewGroup.RELCAP, + PlugInIDs.RelCapViewGroup.GROUP_NAME, + ) - @property def layout(self) -> Type[Component]: return error(self.error_message) - - diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py index 0352ce468..111db9fd9 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py @@ -2,24 +2,24 @@ from dash.development.base_component import Component from webviz_config.webviz_plugin_subclasses import ViewElementABC -from webviz_core_components import Graph as WccGraph +from webviz_core_components import Graph as WccGraph + class Graph(ViewElementABC): class IDs: - #pylint: disable=too-few-public-methods + # pylint: disable=too-few-public-methods GRAPH = "graph" - def __init__(self,height : str = "43vh", both : bool = True) -> None: + def __init__(self, height: str = "88vh", both: bool = True) -> None: super().__init__() - if both: self.height = height else: self.height = "88vh" - def inner_layout(self) -> Type[Component]: + def inner_layout(self) -> Type[Component]: return WccGraph( - id = self.register_component_unique_id(Graph.IDs.GRAPH), - style = {"height": self.height, "min-height": "300px"} - ) \ No newline at end of file + id=self.register_component_unique_id(Graph.IDs.GRAPH), + style={"height": self.height, "min-height": "300px"}, + ) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py index 06715b8b2..4b481cefc 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py @@ -1 +1 @@ -from ._relcap import RelpermCappres \ No newline at end of file +from ._relcap import RelpermCappres diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py index 834eda703..b5a17273c 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -1,4 +1,5 @@ from fcntl import LOCK_WRITE +from logging import Filter from pydoc import doc from typing import List, Tuple, Optional, Union from pathlib import Path @@ -14,34 +15,29 @@ from ..._plugin_ids import PlugInIDs from ...view_elements import Graph -from ....._utils.fanchart_plotting import FanchartData, FreeLineData, LowHighData, MinMaxData, get_fanchart_traces +from ....._utils.fanchart_plotting import ( + FanchartData, + FreeLineData, + LowHighData, + MinMaxData, + get_fanchart_traces, +) +from ...shared_settings._filter import ( + Filter, + Selectors, + Scal_recommendation, + Visualization, +) + class RelpermCappres(ViewABC): - '''Add comment descibring the plugin''' + """Add comment descibring the plugin""" + class IDs: - '''Different curves to be shown in the view''' - #pylint: disable=too-few-public-methods + # pylint: disable=too-few-public-methods RELATIVE_PERMEABILIY = "reative-permeability" - # don't think I need these - '''KRW = "KRW" - KROW = "KROW" - POW = "POW" - - class Saturations: - SW = "SW" - SO = "SO" - SG = "SG" - SL = "SL" - class RelpermFamilies: # the possible keywords in the data files needed in list - SWOF = "SWOF" - SGOF = "SGOF" - SLGOF = "SLGOF" - SWFN = "SWFN" - SGFN = "SGFN" - SOF3 = "SOF3"''' - - + # må sjekke om jeg egt trenger disse SATURATIONS = ["SW", "SO", "SG", "SL"] RELPERM_FAMILIES = { 1: ["SWOF", "SGOF", "SLGOF"], @@ -56,19 +52,16 @@ class RelpermFamilies: # the possible keywords in the data files needed in list "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) "PCOG": "#555555", } - - # this might change when there is a different dataset - ''' ENSAMBLES = ["iter-0","iter-3"] - GRAPHS = ["KRW","KRG","KROG","KROW","PCOW","PCOG"] ''' - - def __init__(self, relperm_df: pd.DataFrame, webviz_settings : WebvizSettings) -> None: - # scalfile: Path = None,sheet_name: Optional[Union[str, int, list]] = None) -> None: - # scalfile: Path = None; sets the scal file to be used, if any - # sheet_name: Optional[Union[str, int, list]] = None which shet to use for the scalfile if it is xlsx formate + def __init__( + self, + relperm_df: pd.DataFrame, + webviz_settings: WebvizSettings, + scal: pd.DataFrame, + ) -> None: super().__init__("Relatve permeability") - ''' Data funksjonaliteter + """ Data funksjonaliteter Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) @@ -93,8 +86,8 @@ def __init__(self, relperm_df: pd.DataFrame, webviz_settings : WebvizSettings) - -> KROx: oppe fra venstre og ned til høyre -> KRx: nede fra venstre og opp til høyre -> POx: - ''' - ''' Data i fil + """ + """ Data i fil Filene er sortert etter realization; each realization has iter-0 and iter-3 share -> results -> relperm.csv @@ -104,45 +97,44 @@ def __init__(self, relperm_df: pd.DataFrame, webviz_settings : WebvizSettings) - Så er det listet data først for SW og å for SG or alle satnums X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 - ''' - + """ + self.relperm_df = relperm_df # file with columns: ['ENSEMBLE', 'REAL', 'SW', 'KRW', 'KROW', 'PCOW', 'SATNUM', 'KEYWORD','SG', 'KRG', 'KROG', 'PCOG'] self.plotly_theme = webviz_settings.theme.plotly_theme - # the first setting that ou have to choose is between gaas and water, you never have both so can split the dataset in two - self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SWOF"] - self.SW_df = self.relperm_df[self.relperm_df["KEYWORD"] == "SGOF"] + self.scal = scal # creating the columns and row to define the setup of the view column = self.add_column() first_row = column.make_row() - first_row.add_view_element(Graph(),RelpermCappres.IDs.RELATIVE_PERMEABILIY) - + first_row.add_view_element(Graph(), RelpermCappres.IDs.RELATIVE_PERMEABILIY) + + # nå er disse her og i filter, burde kanskje flyttes til plugin.py? også ha de felles? @property - def sat_axes(self): - """List of all possible saturation axes in dataframe""" - return [sat for sat in self.sat_axes_maps if sat in self.satfunc.columns] + def sat_axes(self) -> List[str]: + """List of all saturation axes in the dataframe""" + return [sat for sat in self.sat_axes_maps if sat in self.relperm_df.columns] @property def ensembles(self): - '''List of al possible unique ensembles''' - return list(self.satfunc["ENSEMBLE"].unique()) + """List of all ensembles in the dataframe""" + return list(self.relperm_df["ENSEMBLE"].unique()) @property def satnums(self): - '''List of all posible satnums''' - return list(self.satfunc["SATNUM"].unique()) + """List of all satnums in the dataframe""" + return list(self.relperm_df["SATNUM"].unique()) @property - def color_options(self): + def color_options(self) -> List[str]: """Options to color by""" return ["ENSEMBLE", "CURVE", "SATNUM"] @property - def ens_colors(self): + def ens_colors(self) -> dict: return { ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] for ens in self.ensembles @@ -151,52 +143,91 @@ def ens_colors(self): @property def satnum_colors(self): return { - satnum: self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum)] + satnum: ( + self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum) % 10] + # if self.satnums.index(satnum) < 10 + # else self.plotly_theme["layout"]["colorway"][ + # self.satnums.index(satnum) - 10 + # ] + ) + # self.plotly_theme har bare 10 farger, trenger minst to til...? for satnum in self.satnums } def set_callbacks(self) -> None: - '''Defines the callbacks for the view element''' - @callback( - Output(self.view_element(RelpermCappres.IDs.RELATIVE_PERMEABILIY).component_unique_id(Graph.IDs.GRAPH).to_string(),"figure"), - - Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data"), - Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data"), - Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data"), - Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data"), - Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data"), - - Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES),"data"), - Input(self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS),"data"), - - Input(self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL),"data"), + """Defines the callback for the view element""" + + @callback( + Output( + self.view_element(RelpermCappres.IDs.RELATIVE_PERMEABILIY) + .component_unique_id(Graph.IDs.GRAPH) + .to_string(), + "figure", + ), + Input( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS), + "data", + ), + Input( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY), "data" + ), + Input( + self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES), "data" + ), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES), "data"), + Input(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM), "data"), + Input( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), + "data", + ), + Input( + self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" + ), + Input( + self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), + "data", + ), ) - def _update_graph(sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], - line_traces : List[str], y_axis : List[str], scal : List[str]) -> dict: - ensemble_colors = {"iter-0":"#285d93","iter-3":"#e48c16"} - curve_colors = {"KRW":"#0000aa","KRG":"#ff0000","KROG":"#00aa00","KROW":"#00aa00","PCOW":"#555555","PCOG":"#555555"} - satnum_colors = { - "1": "#285d93", - "2": "#e48c16", - "3": "#00aa00", - "4": "#cc0000", - "5": "#9f66bb", - "6": "#b17750", - "7": "#d59bc5", - "8": "#555555", - "9": "#b9c15b", - "10": "#5bf2e6", - "11": "#ff0000", - "12": "#45f03a" - } - colors = {"ensemble": ensemble_colors, "curve": curve_colors, "satnum": satnum_colors} + def _update_graph( + sataxis: str, + color_by: List[str], + ensembles: List[str], + curves: List[str], + satnums: List[int], + line_traces: List[str], + y_axis: str, + scal: List[str], # kanskje ikke list? + ) -> dict: + + # sataxis = "SG" + # color_by = "SATNUM" + # ensembles = ["iter-0"] + # curves = ["KRG", "KROG", "PCOG"] + # satnums = [1, 2, 3, 4, 5] + # line_traces = "individual-realizations" + # y_axis = "linear" if not curves or not satnums: # Curve and satnum has to be defined raise PreventUpdate if ensembles is None: # Allowing no ensembles to plot only SCAL data ensembles = [] - - df = self.SG_df if sataxis[0].upper() == "SG" else self.SW_df + if not isinstance(ensembles, list): + ensembles = [ensembles] + if not isinstance(curves, list): + curves = [curves] + if not isinstance(satnums, list): + satnums = [satnums] + if not isinstance(sataxis, str): + sataxis = sataxis[0] + + df = filter_df(self.relperm_df, ensembles, curves, satnums, sataxis) + + if color_by == "ENSEMBLE": + colors = self.ens_colors + elif color_by == "SATNUM": + colors = self.satnum_colors + else: + colors = RelpermCappres.SCAL_COLORMAP nplots = ( 2 @@ -205,32 +236,77 @@ def _update_graph(sataxis : List[str], color_by : List[str], ensembles : List[st else 1 ) - layout = plot_layout(nplots,curves,sataxis,color_by,y_axis) + layout = plot_layout( + nplots, curves, sataxis, color_by, y_axis, self.plotly_theme["layout"] + ) - if line_traces[0].lower() == "individual realization" and not df.empty: - data = realization_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) - elif line_traces[0].lower() == "statistical fanchart" and not df.empty: - data = statistic_traces(df, sataxis, color_by, ensembles, curves, satnums, line_traces, y_axis, scal, colors, nplots) + if line_traces.lower() == "individual-realizations" and not df.empty: + data = realization_traces( + df, + sataxis, + color_by, + ensembles, + curves, + satnums, + line_traces, + y_axis, + scal, + colors, + nplots, + ) + elif line_traces.lower() == "statistical-fanchart" and not df.empty: + data = statistic_traces( + df, + sataxis, + color_by, + ensembles, + curves, + satnums, + line_traces, + y_axis, + scal, + colors, + nplots, + ) + else: + data = [] if self.scal is not None and "show_scal" in scal: - scal_df = filter_scal_df(self.scal, curves, satnums, sataxis[0]) - data.extend(add_scal_traces(scal_df, curves, sataxis[0], nplots)) + scal_df = filter_scal_df(self.scal, curves, satnums, sataxis) + data.extend(add_scal_traces(scal_df, curves, sataxis, nplots)) return {"data": data, "layout": layout} - - - - - def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], - curves : List[str], satnums : List[str], line_traces : List[str], y_axis : List[str], - scal : List[str], colorslist : dict, nplots : int) -> List: - realizatoins = df["REAL"].unique() # list of all possible realizations - # traces = [i for i in range(len(realizatoins))] - colors = colorslist[color_by[0].lower()] - + def filter_df( + df: pd.DataFrame, + ensembles: List[str], + curves: List[str], + # det er feil i filter.py hvor options er feil liste + satnums: List[int], + sataxis: str, + ): + df = df.copy() + df = df.loc[df["ENSEMBLE"].isin(ensembles)] + df = df.loc[df["SATNUM"].isin(satnums)] + columns = ["ENSEMBLE", "REAL", "SATNUM"] + [sataxis] + curves + # nå e sataxis en liste med et element eller av og til er det en str?? hmm.. + return df[columns].dropna(axis="columns", how="all") + + def realization_traces( + df: pd.DataFrame, + sataxis: str, + color_by: List[str], + ensembles: List[str], + curves: List[str], + satnums: List[str], + line_traces: List[str], + y_axis: List[str], + scal: List[str], + colors, + nplots: int, + ) -> List: # my version - ''' + """ if color_by[0].lower() == "ensemble": data = [ { @@ -247,7 +323,7 @@ def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[st for iter in ensembles for curvenum,curve in enumerate(curves) ] - layout = plot_layout(nplots,curves,sataxis,color_by,y_axis), + layout = plot_layout(nplots,curves,sataxis,color_by,y_axis), elif color_by[0].lower() == "curve": data = [ { # trenger man tolist() og list? og må man ha med [0] @@ -279,7 +355,7 @@ def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[st for realization_iter,realization in enumerate(realizatoins) for curvenum,curve in enumerate(curves) ] - ''' + """ data = [] @@ -294,22 +370,26 @@ def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[st [ { "type": "scatter", - "x": real_df[sataxis[0]], + "x": real_df[sataxis], "y": real_df[curve], "xaxis": xaxis, "yaxis": yaxis, "hovertext": ( - f"{curve}, Satnum: {satnum[0]}
" + f"{curve}, Satnum: {satnum}
" f"Realization: {real}, Ensemble: {ensemble}" ), "name": curve, "legendgroup": curve, "marker": { - "color": colors.get(curve, colors[list(colors.keys())[0]]) + "color": colors.get( + curve, colors[list(colors.keys())[0]] + ) }, "showlegend": real_no == 0, } - for real_no, (real, real_df) in enumerate(df.groupby("REAL")) + for real_no, (real, real_df) in enumerate( + df.groupby("REAL") + ) ] ) else: @@ -322,24 +402,26 @@ def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[st [ { "type": "scatter", - "x": real_df[sataxis[0]], + "x": real_df[sataxis], "y": real_df[curve], "xaxis": xaxis, "yaxis": yaxis, "hovertext": ( f"{curve}, Satnum: " - f"{group if color_by[0].upper() == 'SATNUM' else constant_group}
" + f"{group if color_by.upper() == 'SATNUM' else constant_group}
" f"Realization: {real}, Ensemble: " - f"{group if color_by[0].upper() == 'ENSEMBLE' else constant_group}" + f"{group if color_by.upper() == 'ENSEMBLE' else constant_group}" ), "name": group, "legendgroup": group, "marker": { - "color": colors.get(group, colors[list(colors.keys())[-1]]) + "color": colors.get( + group, colors[list(colors.keys())[-1]] + ) }, "showlegend": real_no == 0 and curve_no == 0, } - for (group, grouped_df) in df.groupby(color_by[0]) + for (group, grouped_df) in df.groupby(color_by) for real_no, (real, real_df) in enumerate( grouped_df.groupby("REAL") ) @@ -347,8 +429,19 @@ def realization_traces(df: pd.DataFrame, sataxis : List[str], color_by : List[st ) return data - def statistic_traces(df : pd.DataFrame, sataxis : List[str], color_by : List[str], ensembles : List[str], curves : List[str], satnums : List[str], - line_traces : List[str], y_axis : List[str], scal : List[str], colorslist: dict, nplots : int) -> List: + def statistic_traces( + df: pd.DataFrame, + sataxis: str, + color_by: List[str], + ensembles: List[str], + curves: List[str], + satnums: List[str], + line_traces: List[str], + y_axis: List[str], + scal: List[str], + colors, + nplots: int, + ) -> List: # Switched P10 and P90 due to convetion in petroleum industry def p10(x): return np.nanpercentile(x, q=90) @@ -356,13 +449,17 @@ def p10(x): def p90(x): return np.nanpercentile(x, q=10) - data = [] # str #pd.Dataframe + data = ( + [] + ) # dataen her gir fine x-verdier, men bare nan på y-verdiene for alle for ensemble_no, (ensemble, ensemble_df) in enumerate( - df[["ENSEMBLE", "SATNUM"] + [sataxis[0]] + curves].groupby(["ENSEMBLE"]) - ): # int - for satnum_no, (satnum, satnum_df) in enumerate(ensemble_df.groupby("SATNUM")): + df[["ENSEMBLE", "SATNUM"] + [sataxis] + curves].groupby(["ENSEMBLE"]) + ): + for satnum_no, (satnum, satnum_df) in enumerate( + ensemble_df.groupby("SATNUM") + ): df_stat = ( - satnum_df.groupby(sataxis[0]) + satnum_df.groupby(sataxis) .agg([np.nanmean, np.nanmin, np.nanmax, p10, p90]) .stack() .swaplevel() @@ -372,45 +469,63 @@ def p90(x): xaxis = "x" if yaxis == "y" else "x2" legend_group = ( curve - if color_by[0].upper() == "CURVE" + if color_by.upper() == "CURVE" else ensemble - if color_by[0].upper() == "ENSEMBLE" + if color_by.upper() == "ENSEMBLE" else satnum ) show_legend = ( - bool(color_by == "CURVE" and ensemble_no == 0 and satnum_no == 0) - or bool(color_by == "ENSEMBLE" and curve_no == 0 and satnum_no == 0) - or bool(color_by == "SATNUM" and curve_no == 0 and ensemble_no == 0) - ) - color = ( - colorslist[color_by[0].lower()][ensemble] - if color_by[0].upper() == "ENSEMBLE" - else colorslist[color_by[0].lower()][curve] - if color_by[0].upper() == "ENSEMBLE" - else colorslist[color_by[0].lower()][satnum] + bool( + color_by == "CURVE" + and ensemble_no == 0 + and satnum_no == 0 + ) + or bool( + color_by == "ENSEMBLE" + and curve_no == 0 + and satnum_no == 0 + ) + or bool( + color_by == "SATNUM" + and curve_no == 0 + and ensemble_no == 0 + ) ) + data.extend( _get_fanchart_traces( df_stat[curve], - color, # str + colors.get( + legend_group, colors[list(colors.keys())[0]] + ), xaxis, yaxis, legend_group, show_legend, - curve, # str - ensemble, # str - satnum, # int + curve, # str + ensemble, # str + satnum, # int ) ) - + return data - def _get_fanchart_traces(curve_stats :pd.DataFrame, color : str, xaxis : str, yaxis : str, - legend_group: str, show_legend: bool, curve : str, ensemble : str, satnum : int) -> List : + def _get_fanchart_traces( + curve_stats: pd.DataFrame, + color: str, + xaxis: str, + yaxis: str, + legend_group: str, + show_legend: bool, + curve: str, + ensemble: str, + satnum: int, + ) -> List: """Renders a fanchart""" # Retrieve indices from one of the keys in series x = curve_stats["nanmax"].index.tolist() + # over tar ut x-verdier som er verdien for SG data = FanchartData( samples=x, low_high=LowHighData( @@ -438,10 +553,15 @@ def _get_fanchart_traces(curve_stats :pd.DataFrame, color : str, xaxis : str, ya show_legend=show_legend, ) - def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by : List[str], y_axis : List[str]): - """ - Constructing plot layout from scratch as it is more responsive than plotly subplots package. - """ + def plot_layout( + nplots: int, + curves: List[str], + sataxis: str, + color_by: List[str], + y_axis: str, + theme, + ): + titles = ( ["Relative Permeability", "Capillary Pressure"] if nplots == 2 @@ -449,10 +569,14 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by if any(curve.startswith("KR") for curve in curves) else ["Capillary Pressure"] ) - layout = { + layout = {} + layout.update(theme) + layout.update( + { "hovermode": "closest", - "uirevision": f"sa:{sataxis}_{y_axis[0]}_curves:{'_'.join(sorted(curves))}", + "uirevision": f"sa:{sataxis}_{y_axis}_curves:{'_'.join(sorted(curves))}", } + ) # create subplots layout.update( { @@ -501,7 +625,7 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by else {} ) - layout["legend"] = {"title": {"text": color_by[0].lower().capitalize()}} + layout["legend"] = {"title": {"text": color_by.lower().capitalize()}} # format axes if nplots == 1: layout.update( @@ -513,7 +637,10 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by "range": [0, 1], "anchor": "y", "domain": [0.0, 1.0], - "title": {"text": sataxis[0].lower().capitalize(), "standoff": 15}, + "title": { + "text": sataxis.lower().capitalize(), + "standoff": 15, + }, "showgrid": False, "tickmode": "auto", }, @@ -523,7 +650,7 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by "zeroline": False, "anchor": "x", "domain": [0.0, 1.0], - "type": y_axis[0], + "type": y_axis, # her tror jeg ikke [0] er nødvendig "showgrid": False, }, "margin": {"t": 20, "b": 0}, @@ -554,7 +681,7 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by "range": [0, 1], "anchor": "y2", "domain": [0.0, 1.0], - "title": {"text": sataxis[0].lower().capitalize()}, + "title": {"text": sataxis.lower().capitalize()}, "showgrid": False, }, "yaxis": { @@ -564,7 +691,7 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by "anchor": "x", "domain": [0.525, 1.0], "title": {"text": "kr"}, - "type": y_axis[0], + "type": y_axis, "showgrid": False, }, "yaxis2": { @@ -574,7 +701,7 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by "anchor": "x2", "domain": [0.0, 0.475], "title": {"text": "Pc"}, - "type": y_axis[0], + "type": y_axis, "showgrid": False, }, "margin": {"t": 20, "b": 0}, @@ -582,7 +709,9 @@ def plot_layout(nplots : int, curves : List[str], sataxis : List[str], color_by ) return layout - def filter_scal_df(df : pd.DataFrame, curves : List[str], satnums : List[str], sataxis : str): + def filter_scal_df( + df: pd.DataFrame, curves: List[str], satnums: List[str], sataxis: str + ): df = df.copy() df = df.loc[df["SATNUM"].isin(satnums)] columns = ( @@ -592,7 +721,9 @@ def filter_scal_df(df : pd.DataFrame, curves : List[str], satnums : List[str], s ) return df[columns].dropna() - def add_scal_traces(df : pd.DataFrame, curves : List[str], sataxis : str, nplots : int): + def add_scal_traces( + df: pd.DataFrame, curves: List[str], sataxis: str, nplots: int + ): """Renders scal recommendation traces""" traces = [] for curve_no, curve in enumerate( @@ -609,7 +740,8 @@ def add_scal_traces(df : pd.DataFrame, curves : List[str], sataxis : str, nplots "xaxis": xaxis, "yaxis": yaxis, "hovertext": ( - f"{curve}, Satnum: {satnum}
" f"{case.lower().capitalize()}" + f"{curve}, Satnum: {satnum}
" + f"{case.lower().capitalize()}" ), "name": "SCAL", "legendgroup": "SCAL", @@ -617,10 +749,16 @@ def add_scal_traces(df : pd.DataFrame, curves : List[str], sataxis : str, nplots "color": "black", }, "line": {"dash": "dash"}, - "showlegend": curve_no == 0 and satnum_no == 0 and case_no == 0, + "showlegend": curve_no == 0 + and satnum_no == 0 + and case_no == 0, } - for satnum_no, (satnum, satnum_df) in enumerate(df.groupby("SATNUM")) - for case_no, (case, case_df) in enumerate(satnum_df.groupby("CASE")) + for satnum_no, (satnum, satnum_df) in enumerate( + df.groupby("SATNUM") + ) + for case_no, (case, case_df) in enumerate( + satnum_df.groupby("CASE") + ) ] ) - return traces \ No newline at end of file + return traces From a4f509d1c3561aca961342ac081a9de575946d19 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:06:33 +0200 Subject: [PATCH 12/54] working plugin --- .../_relative_permeability_new/_plugin.py | 101 +------ .../shared_settings/__init__.py | 2 +- .../shared_settings/_filter.py | 281 +++++++++--------- .../views/relperm_cappres/_relcap.py | 231 ++++---------- 4 files changed, 205 insertions(+), 410 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index a6e3f2012..44183cecb 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -1,8 +1,7 @@ -# import from python builtin from typing import Type, Optional, Union from pathlib import Path +import warnings -# packages from installed packages from dash.development.base_component import Component import pandas as pd from webviz_config import WebvizPluginABC, WebvizSettings @@ -12,94 +11,14 @@ import webviz_subsurface -# own imports from ._error import error -from ._plugin_ids import PlugInIDs # importing the namespace -from .shared_settings import Filter, Selectors, Visualization, Scal_recommendation +from ._plugin_ids import PlugInIDs +from .shared_settings import Selectors, Visualization, SCALRecommendation from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from .views import RelpermCappres -class TestView(ViewABC): - class Ids: - # pylint: disable=too-few-public-methods - TestViewID = "test-view-id" - - def __init__(self, population_df: pd.DataFrame) -> None: - super().__init__("Population indicators") - - -""" -class RelativePermeabilityNew(WebvizPluginABC): - - ''' - def __init__( - self, - webviz_settings: WebvizSettings, - ensembles: list, - relpermfile: str = None, - scalfile: Path = None, - sheet_name: Optional[Union[str, int, list]] = None, - ): - ''' - def __init__(self, webviz_settings: WebvizSettings,relpermfile: str, ensembles: list, scalfile: Path = None,) -> None: - - - super().__init__() # super refer to class inhereted from, init from ABC - - # set a member, self first for all - self.error_message = "" - - WEBVIZ_ASSETS.add( - Path(webviz_subsurface.__file__).parent - / "_assets" - / "css" - / "block_options.css" - ) - - # when reading from file must check that these are the keywords, if not raise ValueError - - try: - #self.relperm_df = pd.read_csv(path_to_relpermfile) # df = data frame - self.ens_paths = { - ens: WebvizSettings.shared_settings["scratch_ensembles"][ens] - for ens in ensembles - } - if relpermfile is not None: - self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) - except PermissionError: - self.error_message = ( - f"Access to file '{relpermfile}' denied. " - f"Please check your path for '{relpermfile}' and make sure you have access to it." - ) - return - except FileNotFoundError: - self.error_message = ( - f"The file {relpermfile}' not found." - "Please check you path" - ) - return - except pd.errors.ParserError: - self.error_message = ( - f"The file '{relpermfile}' is not a valid csv file." - ) - except pd.errors.EmptyDataError: - self.error_message = ( - f"The file '{relpermfile}' is an empty file." - ) - except Exception: - self.error_message = ( - f"Unknown exception when trying to read '{relpermfile}" - ) - - @property - def layout(self) -> Type[Component]: - return error(self.error_message) - ''' - """ - - class RelativePermeabilityNew(WebvizPluginABC): """Visualizes relative permeability and capillary pressure curves for FMU ensembles. @@ -174,7 +93,7 @@ def __init__( relpermfile: str = None, scalfile: Path = None, sheet_name: Optional[Union[str, int, list]] = None, - ): # må sjekke at disse inputsene er rett (samme som ols) + ): super().__init__() @@ -185,12 +104,6 @@ def __init__( / "block_options.css" ) try: - # self.ens_paths = { - # ens: webviz_settings.shared_settings["scratch_ensembles"][ens] - # for ens in ensembles - # } - # if relpermfile is not None: - # self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) self.ens_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] for ens in ensembles @@ -322,7 +235,7 @@ def __init__( PlugInIDs.Stores.Selectors.SATNUM, WebvizPluginABC.StorageType.SESSION ) self.add_shared_settings_group( - Selectors(self.satfunc, self.plotly_theme, self.sat_axes_maps), + Selectors(self.satfunc, self.sat_axes_maps), PlugInIDs.SharedSettings.SELECTORS, ) @@ -334,7 +247,7 @@ def __init__( PlugInIDs.Stores.Visualization.Y_AXIS, WebvizPluginABC.StorageType.SESSION ) self.add_shared_settings_group( - Visualization(self.satfunc), PlugInIDs.SharedSettings.VISUALIZATION + Visualization(), PlugInIDs.SharedSettings.VISUALIZATION ) self.add_store( @@ -342,7 +255,7 @@ def __init__( WebvizPluginABC.StorageType.SESSION, ) self.add_shared_settings_group( - Scal_recommendation(self.satfunc), + SCALRecommendation(), PlugInIDs.SharedSettings.SCAL_RECOMMENDATION, ) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py index 4ff5ac9e5..4ad3fa2d6 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py @@ -1 +1 @@ -from ._filter import Filter, Selectors, Visualization, Scal_recommendation +from ._filter import Selectors, Visualization, SCALRecommendation diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py index b8917783c..34197901a 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py @@ -3,188 +3,175 @@ from dash import callback, Input, Output, State from dash.development.base_component import Component import pandas as pd +from webviz_config import WebvizPluginABC from webviz_config.webviz_plugin_subclasses import SettingsGroupABC import webviz_core_components as wcc +from dash import dcc from .._plugin_ids import PlugInIDs -class Filter(SettingsGroupABC): - """ - Added by MoNezhadali 06.22 - """ - def __init__(self, relperm_df: pd.DataFrame) -> None: - super().__init__("Filter") - class Ids: - class Selectors: - SATURATION_AXIS="saturation-axis" - COLOR_BY="color-by" - ENSEMBLES="ensembles" - CURVES="curves" - SATNUM="satnum" - class Visualization: - LINE_TRACES="line-traces" - Y_AXIS="y-axis" - class SCALRecommendation: - SHOW_SCAL="show-scal" - - ## todo: the selectors will be defined here after getting to know the data class Selectors(SettingsGroupABC): - def __init__(self, relperm_df: pd.DataFrame,plotly_theme,sat_axes_maps) -> None: + """Settings group for Selectors""" + + class IDs: + # pylint: disable=too.few-public-methods + SATURATION_AXIS = "saturation-axis" + COLOR_BY = "color-by" + ENSEMBLES = "ensembles" + CURVES = "curves" + SATNUM = "satnum" + + def __init__(self, relperm_df: pd.DataFrame, sat_axes_maps) -> None: super().__init__("Selectors") - self.satfunc=relperm_df - self.plotly_theme = plotly_theme - self.sat_axes_maps=sat_axes_maps + self.satfunc = relperm_df + self.sat_axes_maps = sat_axes_maps @property - def sat_axes(self): + def sat_axes(self) -> List[str]: """List of all possible saturation axes in dataframe""" return [sat for sat in self.sat_axes_maps if sat in self.satfunc.columns] @property - def ensembles(self): + def ensembles(self) -> List[str]: + """List of all possible ensembles in dataframe""" return list(self.satfunc["ENSEMBLE"].unique()) @property - def satnums(self): + def satnums(self) -> List[str]: + """List of all possible satnums in dataframe""" return list(self.satfunc["SATNUM"].unique()) @property - def color_options(self): + def color_options(self) -> List[str]: """Options to color by""" return ["ENSEMBLE", "CURVE", "SATNUM"] - @property - def ens_colors(self): - return { - ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] - for ens in self.ensembles - } - - @property - def satnum_colors(self): - return { - satnum: self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum)] - for satnum in self.satnums - } - + # Defining all setting elements in Selectors-section def layout(self) -> List[Component]: return [ - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS), + wcc.Dropdown( + id=self.register_component_unique_id(Selectors.IDs.SATURATION_AXIS), label="Saturation axis", - options=[{"label":i, "value":i} for i in (self.sat_axes)], + options=[{"label": i, "value": i} for i in (self.sat_axes)], value=self.sat_axes[0], multi=False, - size=1, + clearable=False, ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.COLOR_BY), + wcc.Dropdown( + id=self.register_component_unique_id(Selectors.IDs.COLOR_BY), label="Color by", - options=[{"label":i, "value":i} for i in (self.color_options)], + options=[ + {"label": i.lower().capitalize(), "value": i} + for i in (self.color_options) + ], value=self.color_options[0], multi=False, - size=1, + clearable=False, ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.ENSEMBLES), + wcc.Dropdown( + id=self.register_component_unique_id(Selectors.IDs.ENSEMBLES), label="Ensembles", - options=[{"label":i, "value":i} for i in (self.ensembles)], + options=[{"label": i, "value": i} for i in (self.ensembles)], value=self.ensembles[0], multi=True, - size=min(5,len(self.ensembles)), ), - # This needs to be checked - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.CURVES), + wcc.Dropdown( + id=self.register_component_unique_id(Selectors.IDs.CURVES), label="Curves", - options=[{"label":i, "value":i} for i in (self.sat_axes_maps["SW"])], - value=self.color_options[0], - multi=False, - size=1, + clearable=False, + multi=True, + value=self.sat_axes_maps[self.sat_axes[0]], ), - wcc.SelectWithLabel( - id=self.register_component_unique_id(Filter.Ids.Selectors.SATNUM), + wcc.Dropdown( + id=self.register_component_unique_id(Selectors.IDs.SATNUM), label="Satnum", - options=[{"label":i, "value":i} for i in (self.satnums)], + options=[{"label": i, "value": i} for i in (self.satnums)], value=self.ensembles[0], - multi=True, - size=min(5,len(self.ensembles)), + multi=False, + clearable=False, ), ] + def set_callbacks(self) -> None: @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS),"data" + self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATURATION_AXIS), + "data", ), Input( - self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + self.component_unique_id(Selectors.IDs.SATURATION_AXIS).to_string(), + "value", ), ) def _set_saturation_axis(saturation_axis: List[str]) -> List[str]: return saturation_axis - + @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY),"data" + self.get_store_unique_id(PlugInIDs.Stores.Selectors.COLOR_BY), "data" ), Input( - self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + self.component_unique_id(Selectors.IDs.COLOR_BY).to_string(), + "value", ), ) def _set_color_by(color_by: List[str]) -> List[str]: return color_by - + @callback( Output( - self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(),"multi" + self.component_unique_id(Selectors.IDs.ENSEMBLES).to_string(), "multi" ), Output( - self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(),"value" + self.component_unique_id(Selectors.IDs.ENSEMBLES).to_string(), "value" ), Input( - self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + self.component_unique_id(Selectors.IDs.COLOR_BY).to_string(), + "value", ), ) - def _set_ensembles_interaction(color_by:str) -> Tuple[bool, List[str]]: - if color_by=="ENSEMBLE": + def _set_ensembles_interaction(color_by: str) -> Tuple[bool, List[str]]: + """If ensemble is selected as color by, set the ensemble + selector to allow multiple selections, else use stored_ensemble + """ + if color_by == "ENSEMBLE": return [True, self.ensembles] return [False, self.ensembles[0]] - + @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES),"data" + self.get_store_unique_id(PlugInIDs.Stores.Selectors.ENSAMBLES), "data" ), Input( - self.component_unique_id(Filter.Ids.Selectors.ENSEMBLES).to_string(), "value", - ), + self.component_unique_id(Selectors.IDs.ENSEMBLES).to_string(), + "value", + ), ) def _set_ensembles(stored_ensemble: List[str]) -> List[str]: return stored_ensemble @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES),"data" - ), + Output(self.get_store_unique_id(PlugInIDs.Stores.Selectors.CURVES), "data"), Input( - self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(), "value", + self.component_unique_id(Selectors.IDs.CURVES).to_string(), + "value", ), ) def _set_curves(curves: str) -> List[str]: return curves @callback( + Output(self.component_unique_id(Selectors.IDs.CURVES).to_string(), "value"), Output( - self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(),"value" - ), - Output( - self.component_unique_id(Filter.Ids.Selectors.CURVES).to_string(),"options" + self.component_unique_id(Selectors.IDs.CURVES).to_string(), "options" ), Input( - self.component_unique_id(Filter.Ids.Selectors.SATURATION_AXIS).to_string(), "value", + self.component_unique_id(Selectors.IDs.SATURATION_AXIS).to_string(), + "value", ), ) - def _set_curves_interactions(sataxis: str) -> Tuple[List[str],List[Dict]]: + def _set_curves_interactions(sataxis: str) -> Tuple[List[str], List[Dict]]: return ( self.sat_axes_maps[sataxis], [ @@ -195,115 +182,139 @@ def _set_curves_interactions(sataxis: str) -> Tuple[List[str],List[Dict]]: for i in self.sat_axes_maps[sataxis] ], ) - + @callback( - Output( - self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM),"data" - ), + Output(self.get_store_unique_id(PlugInIDs.Stores.Selectors.SATNUM), "data"), Input( - self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(), "value", + self.component_unique_id(Selectors.IDs.SATNUM).to_string(), + "value", ), ) def _set_saturation_axis(stored_satnum: List[str]) -> List[str]: return stored_satnum - + @callback( - Output( - self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(),"multi" - ), - Output( - self.component_unique_id(Filter.Ids.Selectors.SATNUM).to_string(),"value" - ), + Output(self.component_unique_id(Selectors.IDs.SATNUM).to_string(), "multi"), + Output(self.component_unique_id(Selectors.IDs.SATNUM).to_string(), "value"), Input( - self.component_unique_id(Filter.Ids.Selectors.COLOR_BY).to_string(), "value", + self.component_unique_id(Selectors.IDs.COLOR_BY).to_string(), + "value", ), ) def _set_saturation_axis_interactions(color_by: str) -> Tuple[bool, List[str]]: + """If satnum is selected as color by, set the satnum + selector to allow multiple selections, else use stored_satnum + """ if color_by == "SATNUM": return [True, self.satnums] return [ - False, self.satnums[0], + False, + self.satnums[0], ] - - + + class Visualization(SettingsGroupABC): - def __init__(self, relperm_df: pd.DataFrame) -> None: + """Settings group for Visualizations""" + + class IDs: + # pylint: disable=too.few-public-methods + LINE_TRACES = "line-traces" + Y_AXIS = "y-axis" + + def __init__(self) -> None: super().__init__("Visualization") + + # Defining all setting elements in Visualization-section def layout(self) -> List[Component]: return [ wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.LINE_TRACES), + id=self.register_component_unique_id(Visualization.IDs.LINE_TRACES), label="Line traces", options=[ - {"label":"Individual realization","value":"individual-realization"}, - {"label":"Satatistical fanchart", "value":"statistical-fanchart"}, - ], - value="statistical-fanchart", + { + "label": "Individual realizations", + "value": "individual-realizations", + }, + {"label": "Satatistical fanchart", "value": "statistical-fanchart"}, + ], + value="individual-realizations", ), wcc.RadioItems( - id=self.register_component_unique_id(Filter.Ids.Visualization.Y_AXIS), + id=self.register_component_unique_id(Visualization.IDs.Y_AXIS), label="Y-axis", options=[ - {"label":"Linear","value":"linear"}, - {"label":"Log", "value":"log"}, - ], + {"label": "Linear", "value": "linear"}, + {"label": "Log", "value": "log"}, + ], value="linear", ), ] + def set_callbacks(self) -> None: @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), "data" # Check here might be value + self.get_store_unique_id(PlugInIDs.Stores.Visualization.LINE_TRACES), + "data", ), Input( - self.component_unique_id(Filter.Ids.Visualization.LINE_TRACES).to_string(), "value", + self.component_unique_id(Visualization.IDs.LINE_TRACES).to_string(), + "value", ), ) def _set_line_traces(line_traces: List[str]) -> List[str]: return line_traces + @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), "data" # Check here might be value + self.get_store_unique_id(PlugInIDs.Stores.Visualization.Y_AXIS), + "data", ), Input( - self.component_unique_id(Filter.Ids.Visualization.Y_AXIS).to_string(), "value", + self.component_unique_id(Visualization.IDs.Y_AXIS).to_string(), + "value", ), ) def _set_y_axis(y_axis: List[str]) -> List[str]: return y_axis -class Scal_recommendation(SettingsGroupABC): - def __init__(self, relperm_df: pd.DataFrame) -> None: + +class SCALRecommendation(SettingsGroupABC): + """Settings group for SCAL Recomendations""" + + class IDs: + # pylint: disable=too.few-public-methods + SHOW_SCAL = "show-scal" + + def __init__(self) -> None: super().__init__("SCAL Recommendation") - ''' - def __init__(self, rel_perm_df: pd.DataFrame) -> None: - self.super().__init__("SCAL recommendation") - ''' + + # Defining SCAL recomendation setting element def layout(self) -> List[Component]: return [ wcc.Checklist( - id=self.register_component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL), + id=self.register_component_unique_id(SCALRecommendation.IDs.SHOW_SCAL), label="", options=[ { "label": "Show SCAL", "value": "show_scal", }, - ] + ], + value="", ), ] + def set_callbacks(self) -> None: @callback( Output( - self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), "data" # Check here might be value + self.get_store_unique_id(PlugInIDs.Stores.SCALRecomendation.SHOW_SCAL), + "data", ), Input( - self.component_unique_id(Filter.Ids.SCALRecommendation.SHOW_SCAL).to_string(), "value", + self.component_unique_id(SCALRecommendation.IDs.SHOW_SCAL).to_string(), + "value", ), ) - def _set_scal_recommendation(scal_recommendation: List[str]) -> List[str]: + def _set_scal_recommendation(scal_recommendation: List[str]) -> str: return scal_recommendation - - - \ No newline at end of file diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py index b5a17273c..469aff302 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -1,17 +1,13 @@ -from fcntl import LOCK_WRITE -from logging import Filter -from pydoc import doc -from typing import List, Tuple, Optional, Union -from pathlib import Path +from typing import List -from dash import callback, Input, Output, State +from dash import callback, Input, Output from matplotlib.pyplot import figure import pandas as pd import numpy as np import plotly.colors from dash.exceptions import PreventUpdate from webviz_config.webviz_plugin_subclasses import ViewABC -from webviz_config import WebvizPluginABC, WebvizSettings +from webviz_config import WebvizSettings from ..._plugin_ids import PlugInIDs from ...view_elements import Graph @@ -22,29 +18,17 @@ MinMaxData, get_fanchart_traces, ) -from ...shared_settings._filter import ( - Filter, - Selectors, - Scal_recommendation, - Visualization, -) class RelpermCappres(ViewABC): - """Add comment descibring the plugin""" + """View for the Relative Permeability plugin""" class IDs: # pylint: disable=too-few-public-methods RELATIVE_PERMEABILIY = "reative-permeability" - # må sjekke om jeg egt trenger disse - SATURATIONS = ["SW", "SO", "SG", "SL"] - RELPERM_FAMILIES = { - 1: ["SWOF", "SGOF", "SLGOF"], - 2: ["SWFN", "SGFN", "SOF3"], - } SCAL_COLORMAP = { - "Missing": "#ffff00", # using yellow if the curve could not be found + "Missing": "#ffff00", # Using yellow if the curve could not be found "KRW": "#0000aa", "KRG": "#ff0000", "KROG": "#00aa00", @@ -61,71 +45,28 @@ def __init__( ) -> None: super().__init__("Relatve permeability") - """ Data funksjonaliteter - - Dataen er fordelt mellom de som er saturated in w og g (guess water and gass) - -> Sat ax Sw: kan velge mellom KRW, KROW og POW (tre grupper) - -> Sat ax Sg: kan velge mellom KRG, KROG og POG - Alle disse har felles instilliner - - Gruppene er - -> KRW: Relative permeability to water - -> KRG: Rlative permeability to gas - -> KROW: Relative permeability of oil in prescence of water - -> KROG: Relative permeability of oil in prescence of gas afo liwuid saturation - -> POW/G: Pressure of Water/Gas - - Colr by: velger hvordan man skal fordele dataen innad i de tre gruppene -> ensamble, curve og satnum - -> Ensamble: velger hvilke og hvor mange iter du skal ha med og velger en satnum. plotter for hver iter - -> Curve: velger en iter og en satnum, plotter for hver gruppe/kurve - -> Satnum: velger en iter og en eler flere satnum, plotte for hver satnum - Men alle har alltid mulighet til velge hvilke(n) gruppe(r) man ønsker å inludere - - De tre ulike gruppene er hver sin graph i viewen; - KRx og KROx er plottet sammen mot samme y akse, alle har samme y akse - -> KROx: oppe fra venstre og ned til høyre - -> KRx: nede fra venstre og opp til høyre - -> POx: - """ - """ Data i fil - Filene er sortert etter realization; - each realization has iter-0 and iter-3 - share -> results -> relperm.csv - velger realization (99 ulike) og iter (2 uliker pr realization) -> totalt 198 filer - - I hver fil er dataen grupert nedover ettter satnum (og keyword?) - Så er det listet data først for SW og å for SG or alle satnums - - X-aksen til plottene er definer ut ifra SG og SW som går fra 0 til 1 - """ - self.relperm_df = relperm_df - # file with columns: ['ENSEMBLE', 'REAL', 'SW', 'KRW', 'KROW', 'PCOW', 'SATNUM', 'KEYWORD','SG', 'KRG', 'KROG', 'PCOG'] - self.plotly_theme = webviz_settings.theme.plotly_theme - self.scal = scal - # creating the columns and row to define the setup of the view + # Creating the column and row for the setup of the view column = self.add_column() - first_row = column.make_row() first_row.add_view_element(Graph(), RelpermCappres.IDs.RELATIVE_PERMEABILIY) - # nå er disse her og i filter, burde kanskje flyttes til plugin.py? også ha de felles? @property def sat_axes(self) -> List[str]: - """List of all saturation axes in the dataframe""" + """List of all possible saturation axes in dataframe""" return [sat for sat in self.sat_axes_maps if sat in self.relperm_df.columns] @property - def ensembles(self): - """List of all ensembles in the dataframe""" + def ensembles(self) -> List[str]: + """List of all possible ensembles in dataframe""" return list(self.relperm_df["ENSEMBLE"].unique()) @property - def satnums(self): - """List of all satnums in the dataframe""" + def satnums(self) -> List[int]: + """List of all possible satnums in dataframe""" return list(self.relperm_df["SATNUM"].unique()) @property @@ -135,27 +76,27 @@ def color_options(self) -> List[str]: @property def ens_colors(self) -> dict: + """Colors for graphs filteres by ensemble""" return { ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] for ens in self.ensembles } @property - def satnum_colors(self): + def satnum_colors(self) -> dict: + """Colors for graphs filtered by satnum""" return { satnum: ( - self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum) % 10] - # if self.satnums.index(satnum) < 10 - # else self.plotly_theme["layout"]["colorway"][ - # self.satnums.index(satnum) - 10 - # ] + self.plotly_theme["layout"]["colorway"][ + self.satnums.index(satnum) + % len(self.plotly_theme["layout"]["colorway"]) + ] ) - # self.plotly_theme har bare 10 farger, trenger minst to til...? for satnum in self.satnums } def set_callbacks(self) -> None: - """Defines the callback for the view element""" + """Defines the callback for changing the graphs""" @callback( Output( @@ -190,27 +131,22 @@ def set_callbacks(self) -> None: ) def _update_graph( sataxis: str, - color_by: List[str], + color_by: str, ensembles: List[str], curves: List[str], satnums: List[int], line_traces: List[str], y_axis: str, - scal: List[str], # kanskje ikke list? + scal: str, ) -> dict: - - # sataxis = "SG" - # color_by = "SATNUM" - # ensembles = ["iter-0"] - # curves = ["KRG", "KROG", "PCOG"] - # satnums = [1, 2, 3, 4, 5] - # line_traces = "individual-realizations" - # y_axis = "linear" + """Updating graphs according to chosen settings""" if not curves or not satnums: # Curve and satnum has to be defined raise PreventUpdate if ensembles is None: # Allowing no ensembles to plot only SCAL data ensembles = [] + + # Ensuring correct types for the variables if not isinstance(ensembles, list): ensembles = [ensembles] if not isinstance(curves, list): @@ -219,7 +155,10 @@ def _update_graph( satnums = [satnums] if not isinstance(sataxis, str): sataxis = sataxis[0] + if not isinstance(color_by, str): + color_by = color_by[0] + # Filtering dataframe df = filter_df(self.relperm_df, ensembles, curves, satnums, sataxis) if color_by == "ENSEMBLE": @@ -236,21 +175,18 @@ def _update_graph( else 1 ) + # Creating the layout of graphs layout = plot_layout( nplots, curves, sataxis, color_by, y_axis, self.plotly_theme["layout"] ) + # Creating the graphs if line_traces.lower() == "individual-realizations" and not df.empty: data = realization_traces( df, sataxis, color_by, - ensembles, curves, - satnums, - line_traces, - y_axis, - scal, colors, nplots, ) @@ -259,12 +195,7 @@ def _update_graph( df, sataxis, color_by, - ensembles, curves, - satnums, - line_traces, - y_axis, - scal, colors, nplots, ) @@ -281,84 +212,27 @@ def filter_df( df: pd.DataFrame, ensembles: List[str], curves: List[str], - # det er feil i filter.py hvor options er feil liste satnums: List[int], sataxis: str, - ): + ) -> pd.DataFrame: + """Filters dataframe according to chosen settings""" df = df.copy() df = df.loc[df["ENSEMBLE"].isin(ensembles)] df = df.loc[df["SATNUM"].isin(satnums)] columns = ["ENSEMBLE", "REAL", "SATNUM"] + [sataxis] + curves - # nå e sataxis en liste med et element eller av og til er det en str?? hmm.. return df[columns].dropna(axis="columns", how="all") def realization_traces( df: pd.DataFrame, sataxis: str, color_by: List[str], - ensembles: List[str], curves: List[str], - satnums: List[str], - line_traces: List[str], - y_axis: List[str], - scal: List[str], - colors, + colors: dict, nplots: int, ) -> List: - # my version - """ - if color_by[0].lower() == "ensemble": - data = [ - { - "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]].loc[df["SATNUM"] == satnums[0]] - .dropna(axis = "columns", how = "all")[curves[curve]].values.tolist()), - "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == iter]] - .loc[df["SATNUM"] == satnums[0]].dropna(axis = "columns", how = "all")[sataxis[0]].values.tolist()), # must include for linear or loganithmic - "type" : "line", - "legendgroup": iter, - "color" : colors[iter], - "showlegend": realization_iter == 0 and curvenum == 0, - } - for realization_iter,realization in enumerate(realizatoins) - for iter in ensembles - for curvenum,curve in enumerate(curves) - ] - layout = plot_layout(nplots,curves,sataxis,color_by,y_axis), - elif color_by[0].lower() == "curve": - data = [ - { # trenger man tolist() og list? og må man ha med [0] - "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] - [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), - "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnums[0]] - [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), - "type" : "line", - "legendgroup": curve, - "color" : colors[curve], - "showlegend": realization_iter == 0, - } - for realization_iter,realization in enumerate(realizatoins) - for curve in curves - ] - else: - data = [ - { - "x" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] - [curves[curve]].dropna(axis = "columns", how = "all").values.tolist()), - "y" : list(df.loc[df["REAL" == realization]].loc[df["ENSEMBLE" == ensembles[0]]].loc[df["SATNUM"] == satnum] - [sataxis[0]].dropna(axis = "columns", how = "all").values.tolist()), - "type" : "line", - "legendgroup": curve, - "color" : colors[satnum], - "showlegend": realization_iter == 0 and curvenum == 0, - } - for satnumiter,satnum in enumerate(satnums) - for realization_iter,realization in enumerate(realizatoins) - for curvenum,curve in enumerate(curves) - ] - """ + """Creating graphs in the case of statistcal traces""" data = [] - for curve_no, curve in enumerate(curves): yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" xaxis = "x" if yaxis == "y" else "x2" @@ -433,15 +307,11 @@ def statistic_traces( df: pd.DataFrame, sataxis: str, color_by: List[str], - ensembles: List[str], curves: List[str], - satnums: List[str], - line_traces: List[str], - y_axis: List[str], - scal: List[str], - colors, + colors: dict, nplots: int, ) -> List: + """Creating graphs in the case of statistcal traces""" # Switched P10 and P90 due to convetion in petroleum industry def p10(x): return np.nanpercentile(x, q=90) @@ -449,9 +319,7 @@ def p10(x): def p90(x): return np.nanpercentile(x, q=10) - data = ( - [] - ) # dataen her gir fine x-verdier, men bare nan på y-verdiene for alle + data = [] for ensemble_no, (ensemble, ensemble_df) in enumerate( df[["ENSEMBLE", "SATNUM"] + [sataxis] + curves].groupby(["ENSEMBLE"]) ): @@ -502,9 +370,9 @@ def p90(x): yaxis, legend_group, show_legend, - curve, # str - ensemble, # str - satnum, # int + curve, + ensemble, + satnum, ) ) @@ -525,7 +393,6 @@ def _get_fanchart_traces( # Retrieve indices from one of the keys in series x = curve_stats["nanmax"].index.tolist() - # over tar ut x-verdier som er verdien for SG data = FanchartData( samples=x, low_high=LowHighData( @@ -559,9 +426,9 @@ def plot_layout( sataxis: str, color_by: List[str], y_axis: str, - theme, - ): - + theme: dict, + ) -> dict: + """Creating the layout around the graphs""" titles = ( ["Relative Permeability", "Capillary Pressure"] if nplots == 2 @@ -569,6 +436,7 @@ def plot_layout( if any(curve.startswith("KR") for curve in curves) else ["Capillary Pressure"] ) + layout = {} layout.update(theme) layout.update( @@ -577,7 +445,8 @@ def plot_layout( "uirevision": f"sa:{sataxis}_{y_axis}_curves:{'_'.join(sorted(curves))}", } ) - # create subplots + + # Create subplots layout.update( { "annotations": [ @@ -626,7 +495,8 @@ def plot_layout( ) layout["legend"] = {"title": {"text": color_by.lower().capitalize()}} - # format axes + + # Format axes if nplots == 1: layout.update( { @@ -650,7 +520,7 @@ def plot_layout( "zeroline": False, "anchor": "x", "domain": [0.0, 1.0], - "type": y_axis, # her tror jeg ikke [0] er nødvendig + "type": y_axis, "showgrid": False, }, "margin": {"t": 20, "b": 0}, @@ -711,7 +581,8 @@ def plot_layout( def filter_scal_df( df: pd.DataFrame, curves: List[str], satnums: List[str], sataxis: str - ): + ) -> pd.DataFrame: + """Filters dataframe when using SCAL recomendation""" df = df.copy() df = df.loc[df["SATNUM"].isin(satnums)] columns = ( @@ -723,7 +594,7 @@ def filter_scal_df( def add_scal_traces( df: pd.DataFrame, curves: List[str], sataxis: str, nplots: int - ): + ) -> List: """Renders scal recommendation traces""" traces = [] for curve_no, curve in enumerate( From 494a509192909e440cabcc6d839ef8e11e9d4c1d Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:13:04 +0200 Subject: [PATCH 13/54] remove old plugin --- .../plugins/_relative_permeability.py | 980 ------------------ 1 file changed, 980 deletions(-) delete mode 100644 webviz_subsurface/plugins/_relative_permeability.py diff --git a/webviz_subsurface/plugins/_relative_permeability.py b/webviz_subsurface/plugins/_relative_permeability.py deleted file mode 100644 index ea36e8101..000000000 --- a/webviz_subsurface/plugins/_relative_permeability.py +++ /dev/null @@ -1,980 +0,0 @@ -import warnings -from pathlib import Path -from typing import Optional, Union - -import numpy as np -import webviz_core_components as wcc -from dash import Input, Output, State, dcc -from dash.exceptions import PreventUpdate -from webviz_config import WebvizPluginABC, WebvizSettings -from webviz_config.common_cache import CACHE -from webviz_config.webviz_assets import WEBVIZ_ASSETS - -import webviz_subsurface - -from .._datainput.fmu_input import load_csv -from .._datainput.relative_permeability import load_satfunc, load_scal_recommendation -from .._utils.fanchart_plotting import ( - FanchartData, - FreeLineData, - LowHighData, - MinMaxData, - get_fanchart_traces, -) - - -class RelativePermeability(WebvizPluginABC): - """Visualizes relative permeability and capillary pressure curves for FMU ensembles. - ---- - -* **`ensembles`:** Which ensembles in `shared_settings` to visualize. -* **`relpermfile`:** Local path to a csvfile in each realization with dumped relperm data. -* **`scalfile`:** Path to a reference file with SCAL recommendationed data. \ - Path to a single file, **not** per realization/ensemble. The path can be absolute or \ - relative to the `webviz` configuration. -* **`sheet_name`:** Which sheet to use for the `scalfile`, only relevant if `scalfile` is an \ - `xlsx` file (recommended to use csv files with `webviz`). - ---- -The minimum requirement is to define `ensembles`. - -If no `relpermfile` is defined, the relative permeability data will be extracted automatically -from the simulation decks of individual realizations using `fmu-ensemble`and `ecl2df` behind the -scenes. Note that this method can be very slow for larger data decks, and is therefore not -recommended unless you have a very simple model/data deck. - -`relpermfile` is a path to a file stored per realization (e.g. in \ -`share/results/tables/relperm.csv`). `relpermfile` columns: -* One column named `KEYWORD` or `TYPE`: with Flow/Eclipse style keywords (e.g. `SWOF` and `SGOF`). -* One column named `SATNUM` with integer `SATNUM` regions. -* One column **per** saturation (e.g. `SG` and `SW`). -* One column **per** relative permeability curve (e.g. `KRW`, `KROW` and `KRG`) -* One column **per** capillary pressure curve (e.g. `PCOW`). - -The `relpermfile` file can e.g. be dumped to disk per realization by a forward model in ERT that -wraps the command `ecl2csv satfunc input_file -o output_file` (requires that you have `ecl2df` -installed). A typical example could be: -`ecl2csv satfunc eclipse/include/props/relperm.inc -o share/results/tables/relperm.csv`. -[Link to ecl2csv satfunc documentation.](https://equinor.github.io/ecl2df/scripts.html#satfunc) - - -`scalfile` is a path to __a single file of SCAL recommendations__ (for all -realizations/ensembles). The file has to be compatible with -[pyscal's](https://equinor.github.io/pyscal/pyscal.html#pyscal.\ -factory.PyscalFactory.load_relperm_df) input format. Including this file adds reference cases -`Pess`, `Base` and `Opt` to the plots. This file is typically a result of a SCAL study. - -`sheet_name` defines the sheet to use in the `scalfile`. Only relevant if `scalfile` is an -`xlsx` file (it is recommended to use `csv` and not `xlsx` for `Webviz`). - -* [Example of relpermfile](https://github.com/equinor/webviz-subsurface-testdata/blob/master/\ -reek_history_match/realization-0/iter-0/share/results/tables/relperm.csv). -* [Example of scalfile](https://github.com/equinor/\ -webviz-subsurface-testdata/blob/master/reek_history_match/share/scal/scalreek.csv). -""" - - SATURATIONS = ["SW", "SO", "SG", "SL"] - RELPERM_FAMILIES = { - 1: ["SWOF", "SGOF", "SLGOF"], - 2: ["SWFN", "SGFN", "SOF3"], - } - SCAL_COLORMAP = { - "Missing": "#ffff00", # using yellow if the curve could not be found - "KRW": "#0000aa", - "KRG": "#ff0000", - "KROG": "#00aa00", - "KROW": "#00aa00", - "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) - "PCOG": "#555555", - } - - def __init__( - self, - app, - webviz_settings: WebvizSettings, - ensembles: list, - relpermfile: str = None, - scalfile: Path = None, - sheet_name: Optional[Union[str, int, list]] = None, - ): - - super().__init__() - - WEBVIZ_ASSETS.add( - Path(webviz_subsurface.__file__).parent - / "_assets" - / "css" - / "block_options.css" - ) - - self.ens_paths = { - ens: webviz_settings.shared_settings["scratch_ensembles"][ens] - for ens in ensembles - } - self.plotly_theme = webviz_settings.theme.plotly_theme - self.relpermfile = relpermfile # str - if self.relpermfile is not None: - self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) # csv file - self.satfunc = self.satfunc.rename(str.upper, axis="columns").rename( # redefining the csv file (still csv file) - columns={"TYPE": "KEYWORD"} - ) - if "KEYWORD" not in self.satfunc.columns: - raise ValueError( - "There has to be a KEYWORD or TYPE column with corresponding Eclipse keyword: " - "e.g SWOF, SGOF and etc." - ) - valid_columns = ( - ["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] - + RelativePermeability.SATURATIONS - + [ - key - for key in RelativePermeability.SCAL_COLORMAP - if key != "Missing" - ] - ) - self.satfunc = self.satfunc[ # taking out the valid columns - [col for col in self.satfunc.columns if col in valid_columns] - ] - else: - self.satfunc = load_satfunc(self.ens_paths) - if any( - keyword in RelativePermeability.RELPERM_FAMILIES[1] - for keyword in self.satfunc["KEYWORD"].unique() - ): - self.family = 1 - if any( - keyword in RelativePermeability.RELPERM_FAMILIES[2] - for keyword in self.satfunc["KEYWORD"].unique() - ): - warnings.warn( - ( - "Mix of keyword family 1 and 2, currently only support one family at the " - "time. Dropping all data of family 2 ('SWFN', 'SGFN', 'SGWFN', 'SOF2', " - "'SOF3', 'SOF32D') and continues with family 1 ('SWOF', 'SGOF', 'SLGOF')." - ), - ) - self.satfunc = self.satfunc[ - self.satfunc["KEYWORD"].isin( - RelativePermeability.RELPERM_FAMILIES["fam1"] - ) - ] - if "SGOF" in self.satfunc["KEYWORD"].unique(): - if "SLGOF" in self.satfunc["KEYWORD"].unique(): - warnings.warn( - ( - "Mix of 'SGOF' and 'SLGOF' in ensembles, resulting in non-unique " - "horizontal axis ('SG' and 'SL') for 'KRG', 'KROG' and 'PCOG'. " - "Dropping all data with 'SLGOF'." - ), - ) - self.satfunc = self.satfunc[self.satfunc["KEYWORD"] != "SLGOF"] - self.sat_axes_maps = { - "SW": ["KRW", "KROW", "PCOW"], - "SG": ["KRG", "KROG", "PCOG"], - } - else: - self.sat_axes_maps = { - "SW": ["KRW", "KROW", "PCOW"], - "SL": ["KRG", "KROG", "PCOG"], - } - elif not all( - keyword in RelativePermeability.RELPERM_FAMILIES[2] - for keyword in self.satfunc["KEYWORD"].unique() - ): - raise ValueError( - "Unrecognized saturation table keyword in data. This should not occur unless " - "there has been changes to ecl2df. Update of this plugin might be required." - ) - else: - self.family = 2 - self.sat_axes_maps = { - "SW": ["KRW", "PCOW"], - "SG": ["KRG", "PCOG"], - "SO": ["KROW", "KROG"], - } - self.scalfile = scalfile - self.sheet_name = sheet_name - self.scal = ( - load_scal_recommendation(self.scalfile, self.sheet_name) - if self.scalfile is not None - else None - ) - self.set_callbacks(app) - - @property - def sat_axes(self): - """List of all possible saturation axes in dataframe""" - return [sat for sat in self.sat_axes_maps if sat in self.satfunc.columns] - - @property - def ensembles(self): - return list(self.satfunc["ENSEMBLE"].unique()) - - @property - def satnums(self): - return list(self.satfunc["SATNUM"].unique()) - - @property - def color_options(self): - """Options to color by""" - return ["ENSEMBLE", "CURVE", "SATNUM"] - - @property - def ens_colors(self): - return { - ens: self.plotly_theme["layout"]["colorway"][self.ensembles.index(ens)] - for ens in self.ensembles - } - - @property - def satnum_colors(self): - return { - satnum: self.plotly_theme["layout"]["colorway"][self.satnums.index(satnum)] - for satnum in self.satnums - } - - @property - def tour_steps(self): - return [ - { - "id": self.uuid("layout"), - "content": "Dashboard displaying relative permeability and capillary pressure" - "data.", - }, - { - "id": self.uuid("graph"), - "content": ( - "Visualization of curves. " - "Different options can be set in the menu to the left." - "You can also toggle data on/off by clicking at the legend." - ), - }, - { - "id": self.uuid("sataxis"), - "content": ( - "Choose saturation type for your x-axis. Will automatically change available " - "options in 'Curves'." - ), - }, - { - "id": self.uuid("color_by"), - "content": ("Choose basis for your colormap."), - }, - { - "id": self.uuid("ensemble"), - "content": ("Select ensembles."), - }, - { - "id": self.uuid("curve_selector"), - "content": ( - "Choose curves. Capillary pressures and relative permeabilities will be shown" - " in separate plots." - ), - }, - { - "id": self.uuid("satnum"), - "content": ("Choose SATNUM regions."), - }, - { - "id": self.uuid("visualization"), - "content": ( - "Choose between different visualizations. 1. Show time series as " - "individual lines per realization. 2. Show statistical fanchart per ensemble." - ), - }, - { - "id": self.uuid("linlog"), - "content": ("Switch between linear and logarithmic y-axis."), - }, - { - "id": self.uuid("scal_selector"), - "content": ( - "Switch on/off SCAL reference data (requires that the optional scalfile is" - " defined)." - ), - }, - ] - - @staticmethod - def set_grid_layout(columns, padding=0): - return { - "display": "grid", - "alignContent": "space-around", - "justifyContent": "space-between", - "gridTemplateColumns": f"{columns}", - "padding": f"{padding}px", - } - - @property - def layout(self): - return wcc.FlexBox( - id=self.uuid("layout"), - children=[ - wcc.Frame( - id=self.uuid("filters"), - style={"flex": "1", "height": "90vh"}, - children=[ - wcc.Selectors( - label="Selectors", - children=[ - wcc.Dropdown( - label="Saturation axis", - id=self.uuid("sataxis"), - clearable=False, - options=[ - { - "label": i.lower().capitalize(), - "value": i, - } - for i in self.sat_axes - ], - value=self.sat_axes[0], - ), - wcc.Dropdown( - label="Color by", - id=self.uuid("color_by"), - clearable=False, - options=[ - { - "label": i.lower().capitalize(), - "value": i, - } - for i in self.color_options - ], - value=self.color_options[0], - ), - dcc.Store( - id=self.uuid("stored_ensemble"), - storage_type="session", - data={}, - ), - wcc.Dropdown( - label="Ensembles", - id=self.uuid("ensemble"), - clearable=False, - multi=True, - options=[ - {"label": i, "value": i} for i in self.ensembles - ], - value=self.ensembles[0], - ), - wcc.Dropdown( - label="Curves", - id=self.uuid("curve"), - clearable=False, - multi=True, - ), - dcc.Store( - id=self.uuid("stored_satnum"), - storage_type="session", - data={}, - ), - wcc.Dropdown( - label="Satnum", - id=self.uuid("satnum"), - clearable=False, - multi=True, - options=[ - {"label": i, "value": i} for i in self.satnums - ], - value=self.satnums[0], - ), - ], - ), - wcc.Selectors( - label="Visualization", - children=[ - wcc.RadioItems( - label="Line traces", - id=self.uuid("visualization"), - className="block-options", - options=[ - { - "label": "Individual realizations", - "value": "realizations", - }, - { - "label": "Statistical fanchart", - "value": "statistics", - }, - ], - value="statistics", - ), - wcc.RadioItems( - label="Y-axis", - id=self.uuid("linlog"), - className="block-options", - options=[ - { - "label": "Linear", - "value": "linear", - }, - { - "label": "Log", - "value": "log", - }, - ], - value="linear", - ), - ], - ), - wcc.Selectors( - style={"display": "block"} - if self.scal is not None - else {"display": "none"}, - id=self.uuid("scal_selector"), - label="SCAL recommendation", - children=[ - wcc.Checklist( - id=self.uuid("scal"), - options=[ - { - "label": "Show SCAL", - "value": "show_scal", - }, - ], - value=["show_scal"] - if self.scal is not None - else [], - ), - ], - ), - ], - ), - wcc.Frame( - color="white", - highlight=False, - style={"flex": "4", "height": "90vh"}, - children=wcc.Graph(style={"height": "88vh"}, id=self.uuid("graph")), - ), - ], - ) - - def set_callbacks(self, app): - @app.callback( - Output(self.uuid("graph"), "figure"), - [ - Input(self.uuid("color_by"), "value"), - Input(self.uuid("visualization"), "value"), - Input(self.uuid("ensemble"), "value"), - Input(self.uuid("curve"), "value"), - Input(self.uuid("satnum"), "value"), - Input(self.uuid("sataxis"), "value"), - Input(self.uuid("linlog"), "value"), - Input(self.uuid("scal"), "value"), - ], - ) - def _update_graph( - color_by, visualization, ensembles, curves, satnums, sataxis, linlog, scal - ): - if not curves or not satnums: # Curve and satnum has to be defined - raise PreventUpdate - if ensembles is None: # Allowing no ensembles to plot only SCAL data - ensembles = [] - if not isinstance(ensembles, list): - ensembles = [ensembles] - if not isinstance(curves, list): - curves = [curves] - if not isinstance(satnums, list): - satnums = [satnums] - df = filter_df(self.satfunc, ensembles, curves, satnums, sataxis) - if color_by == "ENSEMBLE": - colors = self.ens_colors - elif color_by == "SATNUM": - colors = self.satnum_colors - else: - colors = RelativePermeability.SCAL_COLORMAP - nplots = ( - 2 - if any(curve.startswith("PC") for curve in curves) - and any(curve.startswith("KR") for curve in curves) - else 1 - ) - layout = plot_layout( - nplots, curves, sataxis, color_by, linlog, self.plotly_theme["layout"] - ) - if visualization == "realizations" and not df.empty: - traces = add_realization_traces( - df, color_by, curves, sataxis, colors, nplots - ) - elif visualization == "statistics" and not df.empty: - traces = add_statistic_traces( - df, color_by, curves, sataxis, colors, nplots - ) - else: - traces = [] - - if self.scal is not None and "show_scal" in scal: - scal_df = filter_scal_df(self.scal, curves, satnums, sataxis) - traces.extend(add_scal_traces(scal_df, curves, sataxis, nplots)) - return {"data": traces, "layout": layout} - - @app.callback( - [ - Output(self.uuid("ensemble"), "multi"), - Output(self.uuid("ensemble"), "value"), - ], - [Input(self.uuid("color_by"), "value")], - [State(self.uuid("stored_ensemble"), "data")], - ) - def _set_ensemble_selector(color_by, stored_ensemble): - """If ensemble is selected as color by, set the ensemble - selector to allow multiple selections, else use stored_ensemble - """ - - if color_by == "ENSEMBLE": - return True, self.ensembles - - return ( - False, - stored_ensemble.get("ENSEMBLE", self.ensembles[0]), - ) - - @app.callback( - [ - Output(self.uuid("satnum"), "multi"), - Output(self.uuid("satnum"), "value"), - ], - [Input(self.uuid("color_by"), "value")], - [State(self.uuid("stored_satnum"), "data")], - ) - def _set_satnum_selector(color_by, stored_satnum): - """If satnum is selected as color by, set the satnum - selector to allow multiple selections, else use stored_satnum - """ - - if color_by == "SATNUM": - return True, self.satnums - - return ( - False, - stored_satnum.get("SATNUM", self.satnums[0]), - ) - - @app.callback( - [ - Output(self.uuid("curve"), "value"), - Output(self.uuid("curve"), "options"), - ], - [Input(self.uuid("sataxis"), "value")], - ) - def _set_curve_selector(sataxis): - """If satnum is selected as color by, set the satnum - selector to allow multiple selections, else use stored_satnum - """ - return ( - self.sat_axes_maps[sataxis], - [ - { - "label": i, - "value": i, - } - for i in self.sat_axes_maps[sataxis] - ], - ) - - def add_webvizstore(self): - return [ - ( - load_satfunc, - [ - { - "ensemble_paths": self.ens_paths, - "ensemble_set_name": "EnsembleSet", - } - ], - ) - if self.relpermfile is None - else ( - load_csv, - [ - { - "ensemble_paths": self.ens_paths, - "csv_file": self.relpermfile, - "ensemble_set_name": "EnsembleSet", - } - ], - ) - ] + ( - [] - if self.scalfile is None - else [ - ( - load_scal_recommendation, - [{"scalfile": self.scalfile, "sheet_name": self.sheet_name}], - ) - ] - ) - - -# Caching should be safe here with DataFrame as it is always the same for an instance of the plugin. -@CACHE.memoize(timeout=CACHE.TIMEOUT) -def filter_df(df, ensembles, curves, satnums, sataxis): - df = df.copy() - df = df.loc[df["ENSEMBLE"].isin(ensembles)] - df = df.loc[df["SATNUM"].isin(satnums)] - columns = ["ENSEMBLE", "REAL", "SATNUM"] + [sataxis] + curves - return df[columns].dropna() - - -# Caching should be safe here with DataFrame as it is always the same for an instance of the plugin. -@CACHE.memoize(timeout=CACHE.TIMEOUT) -def filter_scal_df(df, curves, satnums, sataxis): - df = df.copy() - df = df.loc[df["SATNUM"].isin(satnums)] - columns = ( - ["SATNUM", "CASE"] - + [sataxis] - + [curve for curve in curves if curve in df.columns] - ) - return df[columns].dropna() - - -def add_realization_traces(df, color_by, curves, sataxis, colors, nplots): - """Renders line traces for individual realizations""" - traces = [] - - for curve_no, curve in enumerate(curves): - yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" - xaxis = "x" if yaxis == "y" else "x2" - if color_by == "CURVE": - satnum = df["SATNUM"].iloc[0] - ensemble = df["ENSEMBLE"].iloc[0] - - traces.extend( - [ - { - "type": "scatter", - "x": real_df[sataxis], - "y": real_df[curve], - "xaxis": xaxis, - "yaxis": yaxis, - "hovertext": ( - f"{curve}, Satnum: {satnum}
" - f"Realization: {real}, Ensemble: {ensemble}" - ), - "name": curve, - "legendgroup": curve, - "marker": { - "color": colors.get(curve, colors[list(colors.keys())[0]]) - }, - "showlegend": real_no == 0, - } - for real_no, (real, real_df) in enumerate(df.groupby("REAL")) - ] - ) - else: - constant_group = ( - df["SATNUM"].iloc[0] - if color_by == "ENSEMBLE" - else df["ENSEMBLE"].iloc[0] - ) - traces.extend( - [ - { - "type": "scatter", - "x": real_df[sataxis], - "y": real_df[curve], - "xaxis": xaxis, - "yaxis": yaxis, - "hovertext": ( - f"{curve}, Satnum: " - f"{group if color_by == 'SATNUM' else constant_group}
" - f"Realization: {real}, Ensemble: " - f"{group if color_by == 'ENSEMBLE' else constant_group}" - ), - "name": group, - "legendgroup": group, - "marker": { - "color": colors.get(group, colors[list(colors.keys())[-1]]) - }, - "showlegend": real_no == 0 and curve_no == 0, - } - for (group, grouped_df) in df.groupby(color_by) - for real_no, (real, real_df) in enumerate( - grouped_df.groupby("REAL") - ) - ] - ) - return traces - - -def add_scal_traces(df, curves, sataxis, nplots): - """Renders scal recommendation traces""" - traces = [] - for curve_no, curve in enumerate( - [curve for curve in curves if curve in df.columns] - ): - yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" - xaxis = "x" if yaxis == "y" else "x2" - traces.extend( - [ - { - "type": "scatter", - "x": case_df[sataxis], - "y": case_df[curve], - "xaxis": xaxis, - "yaxis": yaxis, - "hovertext": ( - f"{curve}, Satnum: {satnum}
" f"{case.lower().capitalize()}" - ), - "name": "SCAL", - "legendgroup": "SCAL", - "marker": { - "color": "black", - }, - "line": {"dash": "dash"}, - "showlegend": curve_no == 0 and satnum_no == 0 and case_no == 0, - } - for satnum_no, (satnum, satnum_df) in enumerate(df.groupby("SATNUM")) - for case_no, (case, case_df) in enumerate(satnum_df.groupby("CASE")) - ] - ) - return traces - - -# pylint: disable=too-many-locals -def add_statistic_traces(df, color_by, curves, sataxis, colors, nplots): - """Calculate statistics and call fanchart rendering""" - # Switched P10 and P90 due to convetion in petroleum industry - def p10(x): - return np.nanpercentile(x, q=90) - - def p90(x): - return np.nanpercentile(x, q=10) - - traces = [] - for ens_no, (ens, ens_df) in enumerate( - df[["ENSEMBLE", "SATNUM"] + [sataxis] + curves].groupby(["ENSEMBLE"]) - ): - for satnum_no, (satnum, satnum_df) in enumerate(ens_df.groupby("SATNUM")): - df_stat = ( - satnum_df.groupby(sataxis) - .agg([np.nanmean, np.nanmin, np.nanmax, p10, p90]) - .stack() - .swaplevel() - ) - for curve_no, curve in enumerate(curves): - yaxis = "y" if nplots == 1 or curve.startswith("KR") else "y2" - xaxis = "x" if yaxis == "y" else "x2" - legend_group = ( - curve - if color_by == "CURVE" - else ens - if color_by == "ENSEMBLE" - else satnum - ) - show_legend = ( - bool(color_by == "CURVE" and ens_no == 0 and satnum_no == 0) - or bool(color_by == "ENSEMBLE" and curve_no == 0 and satnum_no == 0) - or bool(color_by == "SATNUM" and curve_no == 0 and ens_no == 0) - ) - traces.extend( - _get_fanchart_traces( - df_stat[curve], - colors.get(legend_group, colors[list(colors.keys())[0]]), - xaxis, - yaxis, - legend_group, - show_legend, - curve, - ens, - satnum, - ) - ) - return traces - - -# pylint: disable=too-many-arguments -def _get_fanchart_traces( - curve_stats, - color, - xaxis, - yaxis, - legend_group: str, - show_legend: bool, - curve, - ens, - satnum, -): - """Renders a fanchart""" - - # Retrieve indices from one of the keys in series - x = curve_stats["nanmax"].index.tolist() - data = FanchartData( - samples=x, - low_high=LowHighData( - low_data=curve_stats["p90"].values, - low_name="P90", - high_data=curve_stats["p10"].values, - high_name="P10", - ), - minimum_maximum=MinMaxData( - minimum=curve_stats["nanmin"].values, - maximum=curve_stats["nanmax"].values, - ), - free_line=FreeLineData("Mean", curve_stats["nanmean"].values), - ) - - hovertemplate = f"{curve}
" f"Ensemble: {ens}, Satnum: {satnum}" - - return get_fanchart_traces( - data=data, - hex_color=color, - legend_group=legend_group, - xaxis=xaxis, - yaxis=yaxis, - hovertext=hovertemplate, - show_legend=show_legend, - ) - - -@CACHE.memoize(timeout=CACHE.TIMEOUT) -def plot_layout(nplots, curves, sataxis, color_by, linlog, theme): - """ - Constructing plot layout from scratch as it is more responsive than plotly subplots package. - """ - titles = ( - ["Relative Permeability", "Capillary Pressure"] - if nplots == 2 - else ["Relative Permeability"] - if any(curve.startswith("KR") for curve in curves) - else ["Capillary Pressure"] - ) - layout = {} - layout.update(theme) - layout.update( - { - "hovermode": "closest", - "uirevision": f"sa:{sataxis}_{linlog}_curves:{'_'.join(sorted(curves))}", - } - ) - # create subplots - layout.update( - { - "annotations": [ - { - "showarrow": False, - "text": titles[0], - "x": 0.5, - "xanchor": "center", - "xref": "paper", - "y": 1.0, - "yanchor": "bottom", - "yref": "paper", - "font": {"size": 16}, - } - ], - } - if nplots == 1 - else { - "annotations": [ - { - "showarrow": False, - "text": titles[0], - "x": 0.5, - "xanchor": "center", - "xref": "paper", - "y": 1.0, - "yanchor": "bottom", - "yref": "paper", - "font": {"size": 16}, - }, - { - "showarrow": False, - "text": titles[1], - "x": 0.5, - "xanchor": "center", - "xref": "paper", - "y": 0.475, - "yanchor": "bottom", - "yref": "paper", - "font": {"size": 16}, - }, - ], - } - if nplots == 2 - else {} - ) - - layout["legend"] = {"title": {"text": color_by.lower().capitalize()}} - # format axes - if nplots == 1: - layout.update( - { - "xaxis": { - "automargin": True, - "ticks": "", - "zeroline": False, - "range": [0, 1], - "anchor": "y", - "domain": [0.0, 1.0], - "title": {"text": sataxis.lower().capitalize(), "standoff": 15}, - "showgrid": False, - "tickmode": "auto", - }, - "yaxis": { - "automargin": True, - "ticks": "", - "zeroline": False, - "anchor": "x", - "domain": [0.0, 1.0], - "type": linlog, - "showgrid": False, - }, - "margin": {"t": 20, "b": 0}, - } - ) - if any(curve.startswith("KR") for curve in curves): - layout["yaxis"].update({"title": {"text": "kr"}}) - else: - layout["yaxis"].update({"title": {"text": "Pc"}}) - - elif nplots == 2: - layout.update( - { - "xaxis": { - "automargin": True, - "zeroline": False, - "anchor": "y", - "domain": [0.0, 1.0], - "matches": "x2", - "showticklabels": False, - "showgrid": False, - }, - "xaxis2": { - "automargin": True, - "ticks": "", - "showticklabels": True, - "zeroline": False, - "range": [0, 1], - "anchor": "y2", - "domain": [0.0, 1.0], - "title": {"text": sataxis.lower().capitalize()}, - "showgrid": False, - }, - "yaxis": { - "automargin": True, - "ticks": "", - "zeroline": False, - "anchor": "x", - "domain": [0.525, 1.0], - "title": {"text": "kr"}, - "type": linlog, - "showgrid": False, - }, - "yaxis2": { - "automargin": True, - "ticks": "", - "zeroline": False, - "anchor": "x2", - "domain": [0.0, 0.475], - "title": {"text": "Pc"}, - "type": linlog, - "showgrid": False, - }, - "margin": {"t": 20, "b": 0}, - } - ) - return layout From 0209d70178a2ff7d99f0444c405c9b1c42bd67a9 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:14:27 +0200 Subject: [PATCH 14/54] remove new in plugin name --- webviz_subsurface/plugins/__init__.py | 5 +---- .../plugins/_relative_permeability_new/__init__.py | 2 +- .../plugins/_relative_permeability_new/_plugin.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index d8f0c802f..ff3eaf906 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -39,8 +39,7 @@ from ._prod_misfit import ProdMisfit from ._property_statistics import PropertyStatistics from ._pvt_plot import PvtPlot -from ._relative_permeability import RelativePermeability -from ._relative_permeability_new import RelativePermeabilityNew +from ._relative_permeability_new import RelativePermeability from ._reservoir_simulation_timeseries import ReservoirSimulationTimeSeries from ._reservoir_simulation_timeseries_onebyone import ( ReservoirSimulationTimeSeriesOneByOne, @@ -66,5 +65,3 @@ from ._well_cross_section import WellCrossSection from ._well_cross_section_fmu import WellCrossSectionFMU from ._well_log_viewer import WellLogViewer - -from ._relative_permeability_new import RelativePermeabilityNew diff --git a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py index ce9a0f660..25427ac4f 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/__init__.py @@ -1 +1 @@ -from ._plugin import RelativePermeabilityNew +from ._plugin import RelativePermeability diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index 44183cecb..e2456e452 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -19,7 +19,7 @@ from .views import RelpermCappres -class RelativePermeabilityNew(WebvizPluginABC): +class RelativePermeability(WebvizPluginABC): """Visualizes relative permeability and capillary pressure curves for FMU ensembles. --- From 2c07290bf6f56c345d3717620cb4f6476dfea398 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:25:53 +0200 Subject: [PATCH 15/54] saving changes removing new --- .../plugins/_relative_permeability_new/_plugin.py | 2 +- .../_relative_permeability_new/_plugin_ids.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py index e2456e452..f701d708c 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py @@ -82,7 +82,7 @@ class PlotOptions: "KRG": "#ff0000", "KROG": "#00aa00", "KROW": "#00aa00", - "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) + "PCOW": "#555555", # Reserving #000000 for the reference envelope (scal rec) "PCOG": "#555555", } diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py index 4321fde00..964fec21e 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py @@ -5,12 +5,14 @@ class Selectors: COLOR_BY = "color-by" ENSAMBLES = "ensambles" CURVES = "curves" - SATNUM = "satnum" # should we change to saturation number? or someting? + SATNUM = "satnum" # should we change to saturation number? or someting? + class Visualization: LINE_TRACES = "line-traces" Y_AXIS = "y-axis" + class SCALRecomendation: - SHOW_SCAL = "show-SCAL" # doesn't work? + SHOW_SCAL = "show-SCAL" # doesn't work? class RelCapViewGroup: GROUP_NAME = "relcap" @@ -18,6 +20,6 @@ class RelCapViewGroup: class SharedSettings: FILTER = "filter" - SELECTORS="selectors" - VISUALIZATION="visualization" - SCAL_RECOMMENDATION="scal_recommendation" + SELECTORS = "selectors" + VISUALIZATION = "visualization" + SCAL_RECOMMENDATION = "scal_recommendation" From a39fd982895dd1c74cff3bb9ad2b708b6510dbe7 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:27:42 +0200 Subject: [PATCH 16/54] trying again --- .../_relative_permeability_new/views/relperm_cappres/_relcap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py index 469aff302..eb451511a 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py @@ -28,7 +28,7 @@ class IDs: RELATIVE_PERMEABILIY = "reative-permeability" SCAL_COLORMAP = { - "Missing": "#ffff00", # Using yellow if the curve could not be found + "Missing": "#ffff00", # Using yellow if the curve couldn't be found "KRW": "#0000aa", "KRG": "#ff0000", "KROG": "#00aa00", From 01401250a1d451a494f7978af55c7956dbae2a95 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:35:33 +0200 Subject: [PATCH 17/54] removing comments --- .../plugins/_relative_permeability_new/_plugin_ids.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py index 964fec21e..af055a5da 100644 --- a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py +++ b/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py @@ -5,14 +5,14 @@ class Selectors: COLOR_BY = "color-by" ENSAMBLES = "ensambles" CURVES = "curves" - SATNUM = "satnum" # should we change to saturation number? or someting? + SATNUM = "satnum" class Visualization: LINE_TRACES = "line-traces" Y_AXIS = "y-axis" class SCALRecomendation: - SHOW_SCAL = "show-SCAL" # doesn't work? + SHOW_SCAL = "show-SCAL" class RelCapViewGroup: GROUP_NAME = "relcap" From a9928d6402f1c8fb463788d247b80d3d34016104 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:41:33 +0200 Subject: [PATCH 18/54] removed _new from folder name --- .../__init__.py | 0 .../_error.py | 0 .../_plugin.py | 0 .../_plugin_ids.py | 0 .../shared_settings/__init__.py | 0 .../shared_settings/_filter.py | 0 .../view_elements/__init__.py | 0 .../view_elements/_graph.py | 0 .../views/__init__.py | 0 .../views/relperm_cappres/__init__.py | 0 .../views/relperm_cappres/_relcap.py | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/__init__.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/_error.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/_plugin.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/_plugin_ids.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/shared_settings/__init__.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/shared_settings/_filter.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/view_elements/__init__.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/view_elements/_graph.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/views/__init__.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/views/relperm_cappres/__init__.py (100%) rename webviz_subsurface/plugins/{_relative_permeability_new => _relative_permeability}/views/relperm_cappres/_relcap.py (100%) diff --git a/webviz_subsurface/plugins/_relative_permeability_new/__init__.py b/webviz_subsurface/plugins/_relative_permeability/__init__.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/__init__.py rename to webviz_subsurface/plugins/_relative_permeability/__init__.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_error.py b/webviz_subsurface/plugins/_relative_permeability/_error.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/_error.py rename to webviz_subsurface/plugins/_relative_permeability/_error.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/_plugin.py rename to webviz_subsurface/plugins/_relative_permeability/_plugin.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/_plugin_ids.py rename to webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/shared_settings/__init__.py rename to webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/shared_settings/_filter.py rename to webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/view_elements/__init__.py rename to webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/view_elements/_graph.py rename to webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/__init__.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/views/__init__.py rename to webviz_subsurface/plugins/_relative_permeability/views/__init__.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/__init__.py rename to webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/__init__.py diff --git a/webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py similarity index 100% rename from webviz_subsurface/plugins/_relative_permeability_new/views/relperm_cappres/_relcap.py rename to webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py From ef8cb002a700dcee950c2cbc84b0574d9c889ff9 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:44:39 +0200 Subject: [PATCH 19/54] Remove New from plugin name --- setup.py | 1 - webviz_subsurface/plugins/__init__.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index acd5f6359..ed8716629 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,6 @@ "PropertyStatistics = webviz_subsurface.plugins:PropertyStatistics", "PvtPlot = webviz_subsurface.plugins:PvtPlot", "RelativePermeability = webviz_subsurface.plugins:RelativePermeability", - "RelativePermeabilityNew = webviz_subsurface.plugins:RelativePermeabilityNew", "ReservoirSimulationTimeSeries = webviz_subsurface.plugins:ReservoirSimulationTimeSeries", "ReservoirSimulationTimeSeriesOneByOne = webviz_subsurface.plugins:ReservoirSimulationTimeSeriesOneByOne", "ReservoirSimulationTimeSeriesRegional = webviz_subsurface.plugins:ReservoirSimulationTimeSeriesRegional", diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index ff3eaf906..27a8548ac 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -39,7 +39,7 @@ from ._prod_misfit import ProdMisfit from ._property_statistics import PropertyStatistics from ._pvt_plot import PvtPlot -from ._relative_permeability_new import RelativePermeability +from ._relative_permeability import RelativePermeability from ._reservoir_simulation_timeseries import ReservoirSimulationTimeSeries from ._reservoir_simulation_timeseries_onebyone import ( ReservoirSimulationTimeSeriesOneByOne, From 44e5e47c964c364891dd33fc46e2228ed3627d56 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Fri, 8 Jul 2022 15:58:05 +0200 Subject: [PATCH 20/54] black fix --- webviz_subsurface/plugins/_relative_permeability/_error.py | 3 ++- .../plugins/_relative_permeability/view_elements/__init__.py | 2 +- .../plugins/_relative_permeability/views/__init__.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_error.py b/webviz_subsurface/plugins/_relative_permeability/_error.py index 81d1380ac..bc998f235 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_error.py +++ b/webviz_subsurface/plugins/_relative_permeability/_error.py @@ -1,4 +1,5 @@ from dash import html + def error(error_message: str) -> html.Div: - return html.Div(children=error_message, style={"color": "red"}) \ No newline at end of file + return html.Div(children=error_message, style={"color": "red"}) diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py index 94087a9c5..d4648650f 100644 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/__init__.py @@ -1 +1 @@ -from ._graph import Graph \ No newline at end of file +from ._graph import Graph diff --git a/webviz_subsurface/plugins/_relative_permeability/views/__init__.py b/webviz_subsurface/plugins/_relative_permeability/views/__init__.py index a4031e567..c4eaa44e8 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/__init__.py @@ -1 +1 @@ -from .relperm_cappres import RelpermCappres \ No newline at end of file +from .relperm_cappres import RelpermCappres From eb597fd192a71e452de04bee9db1c9d406da9658 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 08:18:07 +0200 Subject: [PATCH 21/54] Add pylint disable ... --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 3 +-- .../plugins/_relative_permeability/_plugin_ids.py | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index f701d708c..7bc4d22c7 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -71,6 +71,7 @@ class RelativePermeability(WebvizPluginABC): """ class PlotOptions: + # pylint: disable=too-few-public-methods SATURATIONS = ["SW", "SO", "SG", "SL"] RELPERM_FAMILIES = { 1: ["SWOF", "SGOF", "SLGOF"], @@ -215,8 +216,6 @@ def __init__( self.error_message = f"The file '{relpermfile}' is not a valid csv file." except pd.errors.EmptyDataError: self.error_message = f"The file '{relpermfile}' is an empty file." - except Exception: - self.error_message = f"Unknown exception when trying to read '{relpermfile}" self.add_store( PlugInIDs.Stores.Selectors.SATURATION_AXIS, diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py index af055a5da..ae7c4370e 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py @@ -1,6 +1,8 @@ class PlugInIDs: class Stores: + # pylint: disable=too-few-public-methods class Selectors: + # pylint: disable=too-few-public-methods SATURATION_AXIS = "saturation-axis" COLOR_BY = "color-by" ENSAMBLES = "ensambles" @@ -8,17 +10,21 @@ class Selectors: SATNUM = "satnum" class Visualization: + # pylint: disable=too-few-public-methods LINE_TRACES = "line-traces" Y_AXIS = "y-axis" class SCALRecomendation: + # pylint: disable=too-few-public-methods SHOW_SCAL = "show-SCAL" class RelCapViewGroup: + # pylint: disable=too-few-public-methods GROUP_NAME = "relcap" RELCAP = "relcapview" class SharedSettings: + # pylint: disable=[too-few-public-methods] FILTER = "filter" SELECTORS = "selectors" VISUALIZATION = "visualization" From 5d6d4433b26e76ca321028bdc855394d12e81360 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 08:28:19 +0200 Subject: [PATCH 22/54] pylint changes vol 1 --- .../plugins/_relative_permeability/_plugin.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 7bc4d22c7..30c581af3 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -83,7 +83,7 @@ class PlotOptions: "KRG": "#ff0000", "KROG": "#00aa00", "KROW": "#00aa00", - "PCOW": "#555555", # Reserving #000000 for the reference envelope (scal rec) + "PCOW": "#555555", # Reserving #000000 for reference envelope (scal rec) "PCOG": "#555555", } @@ -95,6 +95,7 @@ def __init__( scalfile: Path = None, sheet_name: Optional[Union[str, int, list]] = None, ): + # pylint: disable=too-many-statements super().__init__() @@ -120,8 +121,8 @@ def __init__( ) if "KEYWORD" not in self.satfunc.columns: raise ValueError( - "There has to be a KEYWORD or TYPE column with corresponding Eclipse keyword: " - "e.g SWOF, SGOF and etc." + "There has to be a KEYWORD or TYPE column with " + "corresponding Eclipse keyword: e.g SWOF, SGOF and etc." ) valid_columns = ( ["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] @@ -149,9 +150,10 @@ def __init__( ): warnings.warn( ( - "Mix of keyword family 1 and 2, currently only support one family at the " - "time. Dropping all data of family 2 ('SWFN', 'SGFN', 'SGWFN', 'SOF2', " - "'SOF3', 'SOF32D') and continues with family 1 ('SWOF', 'SGOF', 'SLGOF')." + "Mix of keyword family 1 and 2, currently only support " + "one family at the time. Dropping all data of family 2 " + "('SWFN', 'SGFN', 'SGWFN', 'SOF2', 'SOF3', 'SOF32D') " + "and continues with family 1 ('SWOF', 'SGOF', 'SLGOF')." ), ) self.satfunc = self.satfunc[ From 8922e12ad56c9972bb5555d6b35cfd51250a04c9 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 08:32:57 +0200 Subject: [PATCH 23/54] pylint changes vol 2 --- .../plugins/_relative_permeability/_plugin.py | 3 --- .../plugins/_relative_permeability/_plugin_ids.py | 1 + .../_relative_permeability/shared_settings/_filter.py | 10 ++++------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 30c581af3..59ef52782 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -5,10 +5,7 @@ from dash.development.base_component import Component import pandas as pd from webviz_config import WebvizPluginABC, WebvizSettings -from webviz_config.common_cache import CACHE from webviz_config.webviz_assets import WEBVIZ_ASSETS -from webviz_config.webviz_plugin_subclasses import ViewABC - import webviz_subsurface from ._error import error diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py index ae7c4370e..aa4950040 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin_ids.py @@ -1,4 +1,5 @@ class PlugInIDs: + # pylint: disable=too-few-public-methods class Stores: # pylint: disable=too-few-public-methods class Selectors: diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index 34197901a..df46932f9 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,12 +1,10 @@ from typing import List, Tuple, Dict -from dash import callback, Input, Output, State +from dash import callback, Input, Output from dash.development.base_component import Component import pandas as pd -from webviz_config import WebvizPluginABC from webviz_config.webviz_plugin_subclasses import SettingsGroupABC import webviz_core_components as wcc -from dash import dcc from .._plugin_ids import PlugInIDs @@ -15,7 +13,7 @@ class Selectors(SettingsGroupABC): """Settings group for Selectors""" class IDs: - # pylint: disable=too.few-public-methods + # pylint: disable=too-few-public-methods SATURATION_AXIS = "saturation-axis" COLOR_BY = "color-by" ENSEMBLES = "ensembles" @@ -218,7 +216,7 @@ class Visualization(SettingsGroupABC): """Settings group for Visualizations""" class IDs: - # pylint: disable=too.few-public-methods + # pylint: disable=too-few-public-methods LINE_TRACES = "line-traces" Y_AXIS = "y-axis" @@ -283,7 +281,7 @@ class SCALRecommendation(SettingsGroupABC): """Settings group for SCAL Recomendations""" class IDs: - # pylint: disable=too.few-public-methods + # pylint: disable=too-few-public-methods SHOW_SCAL = "show-scal" def __init__(self) -> None: From e23bccf56b7ddca3a71ea93c31ffb9b3c7c8fb26 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 08:45:51 +0200 Subject: [PATCH 24/54] pylint changes vol 3 --- .../plugins/_relative_permeability/_plugin.py | 4 +++- .../views/relperm_cappres/_relcap.py | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 59ef52782..57f5b4847 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -258,7 +258,9 @@ def __init__( ) self.add_view( - RelpermCappres(self.satfunc, webviz_settings, self.scal), + RelpermCappres( + self.satfunc, webviz_settings, self.scal, self.sat_axes_maps + ), PlugInIDs.RelCapViewGroup.RELCAP, PlugInIDs.RelCapViewGroup.GROUP_NAME, ) diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index eb451511a..2986fe0b7 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,14 +1,12 @@ from typing import List from dash import callback, Input, Output -from matplotlib.pyplot import figure import pandas as pd import numpy as np -import plotly.colors -from dash.exceptions import PreventUpdate from webviz_config.webviz_plugin_subclasses import ViewABC from webviz_config import WebvizSettings +from dash.exceptions import PreventUpdate from ..._plugin_ids import PlugInIDs from ...view_elements import Graph from ....._utils.fanchart_plotting import ( @@ -42,12 +40,14 @@ def __init__( relperm_df: pd.DataFrame, webviz_settings: WebvizSettings, scal: pd.DataFrame, + sat_axes_maps: dict, ) -> None: super().__init__("Relatve permeability") self.relperm_df = relperm_df self.plotly_theme = webviz_settings.theme.plotly_theme self.scal = scal + self.sat_axes_maps = sat_axes_maps # Creating the column and row for the setup of the view column = self.add_column() @@ -267,7 +267,7 @@ def realization_traces( ] ) else: - constant_group = ( + const_group = ( df["SATNUM"].iloc[0] if color_by == "ENSEMBLE" else df["ENSEMBLE"].iloc[0] @@ -282,9 +282,9 @@ def realization_traces( "yaxis": yaxis, "hovertext": ( f"{curve}, Satnum: " - f"{group if color_by.upper() == 'SATNUM' else constant_group}
" + f"{group if color_by.upper() == 'SATNUM' else const_group}
" f"Realization: {real}, Ensemble: " - f"{group if color_by.upper() == 'ENSEMBLE' else constant_group}" + f"{group if color_by.upper() == 'ENSEMBLE' else const_group}" ), "name": group, "legendgroup": group, @@ -311,6 +311,7 @@ def statistic_traces( colors: dict, nplots: int, ) -> List: + # pylint: disable=too-local-variables """Creating graphs in the case of statistcal traces""" # Switched P10 and P90 due to convetion in petroleum industry def p10(x): @@ -389,6 +390,7 @@ def _get_fanchart_traces( ensemble: str, satnum: int, ) -> List: + # pylint: disable=too-many-arguments """Renders a fanchart""" # Retrieve indices from one of the keys in series From a3b458cd52d08ccfc284bddcd8527d44537bd2c5 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 08:53:26 +0200 Subject: [PATCH 25/54] pylint change svol 4 --- .../_relative_permeability/views/relperm_cappres/_relcap.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 2986fe0b7..c62afa200 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -5,8 +5,8 @@ import numpy as np from webviz_config.webviz_plugin_subclasses import ViewABC from webviz_config import WebvizSettings - from dash.exceptions import PreventUpdate + from ..._plugin_ids import PlugInIDs from ...view_elements import Graph from ....._utils.fanchart_plotting import ( @@ -97,6 +97,7 @@ def satnum_colors(self) -> dict: def set_callbacks(self) -> None: """Defines the callback for changing the graphs""" + # pylint: disable=too-many-statements @callback( Output( @@ -311,7 +312,7 @@ def statistic_traces( colors: dict, nplots: int, ) -> List: - # pylint: disable=too-local-variables + # pylint: disable=[too-many-local-variables,too-many-arguments] """Creating graphs in the case of statistcal traces""" # Switched P10 and P90 due to convetion in petroleum industry def p10(x): From 0b8ee5496c8b7f664116e01f54475c762081941b Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:03:03 +0200 Subject: [PATCH 26/54] pylint changes vl 5 --- .../_relative_permeability/views/relperm_cappres/_relcap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index c62afa200..ba9cf0fae 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,11 +1,11 @@ from typing import List +from dash.exceptions import PreventUpdate from dash import callback, Input, Output import pandas as pd import numpy as np from webviz_config.webviz_plugin_subclasses import ViewABC from webviz_config import WebvizSettings -from dash.exceptions import PreventUpdate from ..._plugin_ids import PlugInIDs from ...view_elements import Graph @@ -312,7 +312,7 @@ def statistic_traces( colors: dict, nplots: int, ) -> List: - # pylint: disable=[too-many-local-variables,too-many-arguments] + # pylint: disable=too-many-locals """Creating graphs in the case of statistcal traces""" # Switched P10 and P90 due to convetion in petroleum industry def p10(x): From 2ee941868c56430e2cb39231be67992e85450937 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:21:00 +0200 Subject: [PATCH 27/54] sort imports vol 1 --- .../plugins/_relative_permeability/_plugin.py | 10 +++++----- .../_relative_permeability/shared_settings/__init__.py | 2 +- .../_relative_permeability/shared_settings/_filter.py | 4 ++-- .../_relative_permeability/view_elements/_graph.py | 4 ++-- .../views/relperm_cappres/_relcap.py | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 57f5b4847..560cf75bd 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -1,19 +1,19 @@ -from typing import Type, Optional, Union from pathlib import Path +from typing import Type, Optional, Union import warnings -from dash.development.base_component import Component import pandas as pd +import webviz_subsurface +from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS -import webviz_subsurface from ._error import error from ._plugin_ids import PlugInIDs -from .shared_settings import Selectors, Visualization, SCALRecommendation +from .shared_settings import Selectors, SCALRecommendation, Visualization +from .views import RelpermCappres from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation -from .views import RelpermCappres class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py index 4ad3fa2d6..d0268c88b 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py @@ -1 +1 @@ -from ._filter import Selectors, Visualization, SCALRecommendation +from ._filter import Selectors, SCALRecommendation, Visualization diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index df46932f9..52cb38578 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,10 +1,10 @@ from typing import List, Tuple, Dict +import pandas as pd +import webviz_core_components as wcc from dash import callback, Input, Output from dash.development.base_component import Component -import pandas as pd from webviz_config.webviz_plugin_subclasses import SettingsGroupABC -import webviz_core_components as wcc from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py index 111db9fd9..8c3f4cb42 100644 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py @@ -1,8 +1,8 @@ -from typing import Type from dash.development.base_component import Component +from typing import Type -from webviz_config.webviz_plugin_subclasses import ViewElementABC from webviz_core_components import Graph as WccGraph +from webviz_config.webviz_plugin_subclasses import ViewElementABC class Graph(ViewElementABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index ba9cf0fae..46b5d86dc 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,20 +1,20 @@ from typing import List -from dash.exceptions import PreventUpdate -from dash import callback, Input, Output import pandas as pd import numpy as np -from webviz_config.webviz_plugin_subclasses import ViewABC +from dash.exceptions import PreventUpdate +from dash import callback, Input, Output from webviz_config import WebvizSettings +from webviz_config.webviz_plugin_subclasses import ViewABC from ..._plugin_ids import PlugInIDs from ...view_elements import Graph from ....._utils.fanchart_plotting import ( FanchartData, FreeLineData, + get_fanchart_traces, LowHighData, MinMaxData, - get_fanchart_traces, ) From b301943122780d48edfc5905a543273ccd442ab2 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:27:49 +0200 Subject: [PATCH 28/54] sort imports vol 2 --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- .../plugins/_relative_permeability/view_elements/_graph.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 560cf75bd..cc0aaad27 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -3,10 +3,10 @@ import warnings import pandas as pd -import webviz_subsurface from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS +import webviz_subsurface from ._error import error from ._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py index 8c3f4cb42..4a5508968 100644 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py @@ -1,6 +1,7 @@ -from dash.development.base_component import Component from typing import Type +from dash.development.base_component import Component + from webviz_core_components import Graph as WccGraph from webviz_config.webviz_plugin_subclasses import ViewElementABC From dad537a8fc04a199bc70b014d97684026a9a6c09 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:33:35 +0200 Subject: [PATCH 29/54] test sort order in graph.py --- .../plugins/_relative_permeability/view_elements/_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py index 4a5508968..3c3f85508 100644 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py @@ -2,8 +2,8 @@ from dash.development.base_component import Component -from webviz_core_components import Graph as WccGraph from webviz_config.webviz_plugin_subclasses import ViewElementABC +from webviz_core_components import Graph as WccGraph class Graph(ViewElementABC): From 8f04c89d3bb69bd5d48c03e2362e52e66729b5a3 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:38:52 +0200 Subject: [PATCH 30/54] sort imports vol 3 --- .../plugins/_relative_permeability/_plugin.py | 8 ++++---- .../_relative_permeability/shared_settings/__init__.py | 2 +- .../_relative_permeability/shared_settings/_filter.py | 4 ++-- .../_relative_permeability/view_elements/_graph.py | 1 - .../views/relperm_cappres/_relcap.py | 6 +++--- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index cc0aaad27..cf050c207 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -2,18 +2,18 @@ from typing import Type, Optional, Union import warnings -import pandas as pd from dash.development.base_component import Component +import pandas as pd from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS import webviz_subsurface +from ..._datainput.fmu_input import load_csv +from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error from ._plugin_ids import PlugInIDs -from .shared_settings import Selectors, SCALRecommendation, Visualization +from .shared_settings import SCALRecommendation, Selectors, Visualization from .views import RelpermCappres -from ..._datainput.fmu_input import load_csv -from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py index d0268c88b..491b4b1a8 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/__init__.py @@ -1 +1 @@ -from ._filter import Selectors, SCALRecommendation, Visualization +from ._filter import SCALRecommendation, Selectors, Visualization diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index 52cb38578..70f31d4c6 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,9 +1,9 @@ from typing import List, Tuple, Dict -import pandas as pd -import webviz_core_components as wcc from dash import callback, Input, Output from dash.development.base_component import Component +import pandas as pd +import webviz_core_components as wcc from webviz_config.webviz_plugin_subclasses import SettingsGroupABC from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py index 3c3f85508..72b372e8d 100644 --- a/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py +++ b/webviz_subsurface/plugins/_relative_permeability/view_elements/_graph.py @@ -1,7 +1,6 @@ from typing import Type from dash.development.base_component import Component - from webviz_config.webviz_plugin_subclasses import ViewElementABC from webviz_core_components import Graph as WccGraph diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 46b5d86dc..f6cf69572 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,14 +1,13 @@ from typing import List -import pandas as pd -import numpy as np from dash.exceptions import PreventUpdate from dash import callback, Input, Output +import pandas as pd +import numpy as np from webviz_config import WebvizSettings from webviz_config.webviz_plugin_subclasses import ViewABC from ..._plugin_ids import PlugInIDs -from ...view_elements import Graph from ....._utils.fanchart_plotting import ( FanchartData, FreeLineData, @@ -16,6 +15,7 @@ LowHighData, MinMaxData, ) +from ...view_elements import Graph class RelpermCappres(ViewABC): From ea9cee35cb97bfa325c98682ae380241741adb66 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 09:47:36 +0200 Subject: [PATCH 31/54] sort imports vol 4 --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- .../plugins/_relative_permeability/shared_settings/_filter.py | 2 +- .../_relative_permeability/views/relperm_cappres/_relcap.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index cf050c207..177f71960 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Type, Optional, Union +from typing import Optional, Type, Union import warnings from dash.development.base_component import Component diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index 70f31d4c6..df46932f9 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -3,8 +3,8 @@ from dash import callback, Input, Output from dash.development.base_component import Component import pandas as pd -import webviz_core_components as wcc from webviz_config.webviz_plugin_subclasses import SettingsGroupABC +import webviz_core_components as wcc from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index f6cf69572..536747ddc 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,7 +1,7 @@ from typing import List -from dash.exceptions import PreventUpdate from dash import callback, Input, Output +from dash.exceptions import PreventUpdate import pandas as pd import numpy as np from webviz_config import WebvizSettings From 3a489a22e3a6d4285acb7fdd6328183afe562b60 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:05:23 +0200 Subject: [PATCH 32/54] import sort vol 1000 --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 4 ++-- .../_relative_permeability/views/relperm_cappres/_relcap.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 177f71960..993882952 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -8,12 +8,12 @@ from webviz_config.webviz_assets import WEBVIZ_ASSETS import webviz_subsurface -from ..._datainput.fmu_input import load_csv -from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error from ._plugin_ids import PlugInIDs from .shared_settings import SCALRecommendation, Selectors, Visualization from .views import RelpermCappres +from ..._datainput.fmu_input import load_csv +from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 536747ddc..46a3fd506 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -2,8 +2,8 @@ from dash import callback, Input, Output from dash.exceptions import PreventUpdate -import pandas as pd import numpy as np +import pandas as pd from webviz_config import WebvizSettings from webviz_config.webviz_plugin_subclasses import ViewABC From 6a4a142f524f3ead317f81e7106864aaf3395af8 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:12:05 +0200 Subject: [PATCH 33/54] import sort test filter --- .../plugins/_relative_permeability/shared_settings/_filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index df46932f9..742796deb 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,4 +1,4 @@ -from typing import List, Tuple, Dict +from typing import Dict, List, Tuple from dash import callback, Input, Output from dash.development.base_component import Component From 116f5049e7c1cb0685b019f42aff806e514c873f Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:18:43 +0200 Subject: [PATCH 34/54] sort import after type relcap --- .../_relative_permeability/views/relperm_cappres/_relcap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 46a3fd506..744d3e866 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,6 +1,6 @@ from typing import List -from dash import callback, Input, Output +from dash import Input, Output, callback from dash.exceptions import PreventUpdate import numpy as np import pandas as pd @@ -11,9 +11,9 @@ from ....._utils.fanchart_plotting import ( FanchartData, FreeLineData, - get_fanchart_traces, LowHighData, MinMaxData, + get_fanchart_traces, ) from ...view_elements import Graph From 551e35fdc92a4e407e8909e1773aa7e1ab58d312 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:28:08 +0200 Subject: [PATCH 35/54] test filter sort import --- .../_relative_permeability/shared_settings/_filter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index 742796deb..f3fc5496f 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,10 +1,10 @@ -from typing import Dict, List, Tuple +from typing import Tuple, Dict, List -from dash import callback, Input, Output -from dash.development.base_component import Component import pandas as pd -from webviz_config.webviz_plugin_subclasses import SettingsGroupABC import webviz_core_components as wcc +from dash import Input, Output, callback +from dash.development.base_component import Component +from webviz_config.webviz_plugin_subclasses import SettingsGroupABC from .._plugin_ids import PlugInIDs From f3e5ee8990a02d52a158739ae74ac65cb1f549c7 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:39:28 +0200 Subject: [PATCH 36/54] test sorting using isort --- .../plugins/_relative_permeability/_plugin.py | 12 +++++++----- .../shared_settings/_filter.py | 6 +++--- .../views/relperm_cappres/_relcap.py | 18 +++++++----------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 993882952..4e2f7d46a 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -1,19 +1,21 @@ -from pathlib import Path -from typing import Optional, Type, Union import warnings +from pathlib import Path -from dash.development.base_component import Component import pandas as pd +from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS + import webviz_subsurface +from typing import Optional, Type, Union +from ..._datainput.fmu_input import load_csv +from ..._datainput.relative_permeability import (load_satfunc, + load_scal_recommendation) from ._error import error from ._plugin_ids import PlugInIDs from .shared_settings import SCALRecommendation, Selectors, Visualization from .views import RelpermCappres -from ..._datainput.fmu_input import load_csv -from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index f3fc5496f..ed97da85c 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,11 +1,11 @@ -from typing import Tuple, Dict, List - import pandas as pd -import webviz_core_components as wcc from dash import Input, Output, callback from dash.development.base_component import Component from webviz_config.webviz_plugin_subclasses import SettingsGroupABC +import webviz_core_components as wcc +from typing import Dict, List, Tuple + from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 744d3e866..bcd3c24aa 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,20 +1,16 @@ -from typing import List - -from dash import Input, Output, callback -from dash.exceptions import PreventUpdate import numpy as np import pandas as pd +from dash import Input, Output, callback +from dash.exceptions import PreventUpdate from webviz_config import WebvizSettings from webviz_config.webviz_plugin_subclasses import ViewABC +from typing import List + +from ....._utils.fanchart_plotting import (FanchartData, FreeLineData, + LowHighData, MinMaxData, + get_fanchart_traces) from ..._plugin_ids import PlugInIDs -from ....._utils.fanchart_plotting import ( - FanchartData, - FreeLineData, - LowHighData, - MinMaxData, - get_fanchart_traces, -) from ...view_elements import Graph From f01b4dffc94acc3819870918b6675790e9dc4f4b Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:45:06 +0200 Subject: [PATCH 37/54] black changes --- .../plugins/_relative_permeability/_plugin.py | 3 +-- .../views/relperm_cappres/_relcap.py | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 4e2f7d46a..69e6cd8b4 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -10,8 +10,7 @@ from typing import Optional, Type, Union from ..._datainput.fmu_input import load_csv -from ..._datainput.relative_permeability import (load_satfunc, - load_scal_recommendation) +from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error from ._plugin_ids import PlugInIDs from .shared_settings import SCALRecommendation, Selectors, Visualization diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index bcd3c24aa..726f276ab 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -7,9 +7,13 @@ from typing import List -from ....._utils.fanchart_plotting import (FanchartData, FreeLineData, - LowHighData, MinMaxData, - get_fanchart_traces) +from ....._utils.fanchart_plotting import ( + FanchartData, + FreeLineData, + LowHighData, + MinMaxData, + get_fanchart_traces, +) from ..._plugin_ids import PlugInIDs from ...view_elements import Graph From 2776a5458a6433ddcec1fc3b713dd138fa50b5a5 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:53:32 +0200 Subject: [PATCH 38/54] formating changes --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 5 ++--- .../_relative_permeability/shared_settings/_filter.py | 4 ++-- .../_relative_permeability/views/relperm_cappres/_relcap.py | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 69e6cd8b4..74f151004 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -1,14 +1,13 @@ import warnings from pathlib import Path +from typing import Optional, Type, Union import pandas as pd +import webviz_subsurface from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS -import webviz_subsurface -from typing import Optional, Type, Union - from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index ed97da85c..b88101382 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,10 +1,10 @@ +from typing import Dict, List, Tuple + import pandas as pd from dash import Input, Output, callback from dash.development.base_component import Component from webviz_config.webviz_plugin_subclasses import SettingsGroupABC - import webviz_core_components as wcc -from typing import Dict, List, Tuple from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index 726f276ab..cc0d5f85b 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -1,3 +1,5 @@ +from typing import List + import numpy as np import pandas as pd from dash import Input, Output, callback @@ -5,8 +7,6 @@ from webviz_config import WebvizSettings from webviz_config.webviz_plugin_subclasses import ViewABC -from typing import List - from ....._utils.fanchart_plotting import ( FanchartData, FreeLineData, From 9ba369b5e4fe1412b9b880a2d01110ea5cdca1ee Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 10:59:09 +0200 Subject: [PATCH 39/54] formating changes again --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 74f151004..b32ec19fe 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -3,11 +3,11 @@ from typing import Optional, Type, Union import pandas as pd -import webviz_subsurface from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS +import webviz_subsurface from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error From c4b21d6246b1f7a3037d146ce42d07ae6f1fac48 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 11:12:03 +0200 Subject: [PATCH 40/54] import moving --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index b32ec19fe..c19cff060 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -6,8 +6,8 @@ from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS - import webviz_subsurface + from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation from ._error import error From ba6ba4c044cdf730efbdd9a4b4a11b880d255b6c Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 11:20:25 +0200 Subject: [PATCH 41/54] =?UTF-8?q?pr=C3=B8ver=20=5F=20under=20bokstaver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...parameter_correlation.py => _parameter_correlation_old.py} | 0 webviz_subsurface/plugins/_relative_permeability/_plugin.py | 4 ++-- .../plugins/_relative_permeability/shared_settings/_filter.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename webviz_subsurface/plugins/{_parameter_correlation.py => _parameter_correlation_old.py} (100%) diff --git a/webviz_subsurface/plugins/_parameter_correlation.py b/webviz_subsurface/plugins/_parameter_correlation_old.py similarity index 100% rename from webviz_subsurface/plugins/_parameter_correlation.py rename to webviz_subsurface/plugins/_parameter_correlation_old.py diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index c19cff060..fdd1318e4 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -10,10 +10,10 @@ from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation -from ._error import error -from ._plugin_ids import PlugInIDs from .shared_settings import SCALRecommendation, Selectors, Visualization from .views import RelpermCappres +from ._error import error +from ._plugin_ids import PlugInIDs class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index b88101382..8100a23de 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Tuple +from typing import Tuple, Dict, List import pandas as pd from dash import Input, Output, callback From c769cf6364d2173f3915ceb1bd26aceb81c53a7b Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 11:26:44 +0200 Subject: [PATCH 42/54] comment out parameter correlation, next plugin, not working yet --- webviz_subsurface/plugins/__init__.py | 3 ++- webviz_subsurface/plugins/_parameter_correlation/__init__.py | 0 webviz_subsurface/plugins/_parameter_correlation/_error.py | 0 webviz_subsurface/plugins/_parameter_correlation/_plugin.py | 0 .../plugins/_parameter_correlation/_plugin_ids.py | 0 .../plugins/_parameter_correlation/shared_settings/__init__.py | 0 .../plugins/_parameter_correlation/shared_settings/_filter.py | 0 7 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 webviz_subsurface/plugins/_parameter_correlation/__init__.py create mode 100644 webviz_subsurface/plugins/_parameter_correlation/_error.py create mode 100644 webviz_subsurface/plugins/_parameter_correlation/_plugin.py create mode 100644 webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py create mode 100644 webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py create mode 100644 webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index 27a8548ac..0829d00e2 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -32,7 +32,8 @@ from ._map_viewer_fmu import MapViewerFMU from ._morris_plot import MorrisPlot from ._parameter_analysis import ParameterAnalysis -from ._parameter_correlation import ParameterCorrelation + +# from ._parameter_correlation import ParameterCorrelation from ._parameter_distribution import ParameterDistribution from ._parameter_parallel_coordinates import ParameterParallelCoordinates from ._parameter_response_correlation import ParameterResponseCorrelation diff --git a/webviz_subsurface/plugins/_parameter_correlation/__init__.py b/webviz_subsurface/plugins/_parameter_correlation/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_parameter_correlation/_error.py b/webviz_subsurface/plugins/_parameter_correlation/_error.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_parameter_correlation/_plugin.py b/webviz_subsurface/plugins/_parameter_correlation/_plugin.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py b/webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py b/webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py b/webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py new file mode 100644 index 000000000..e69de29bb From a2b758f1f4508cba03dc032a877c992c8c41680e Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 12:26:14 +0200 Subject: [PATCH 43/54] sort using isort --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 5 +++-- .../_relative_permeability/shared_settings/_filter.py | 4 ++-- .../_relative_permeability/views/relperm_cappres/_relcap.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index fdd1318e4..752c3b0c7 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -6,14 +6,15 @@ from dash.development.base_component import Component from webviz_config import WebvizPluginABC, WebvizSettings from webviz_config.webviz_assets import WEBVIZ_ASSETS + import webviz_subsurface from ..._datainput.fmu_input import load_csv from ..._datainput.relative_permeability import load_satfunc, load_scal_recommendation -from .shared_settings import SCALRecommendation, Selectors, Visualization -from .views import RelpermCappres from ._error import error from ._plugin_ids import PlugInIDs +from .shared_settings import SCALRecommendation, Selectors, Visualization +from .views import RelpermCappres class RelativePermeability(WebvizPluginABC): diff --git a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py index 8100a23de..85839c5ca 100644 --- a/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py +++ b/webviz_subsurface/plugins/_relative_permeability/shared_settings/_filter.py @@ -1,10 +1,10 @@ -from typing import Tuple, Dict, List +from typing import Dict, List, Tuple import pandas as pd +import webviz_core_components as wcc from dash import Input, Output, callback from dash.development.base_component import Component from webviz_config.webviz_plugin_subclasses import SettingsGroupABC -import webviz_core_components as wcc from .._plugin_ids import PlugInIDs diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index cc0d5f85b..af96cafc3 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -26,7 +26,7 @@ class IDs: RELATIVE_PERMEABILIY = "reative-permeability" SCAL_COLORMAP = { - "Missing": "#ffff00", # Using yellow if the curve couldn't be found + "Missing": "#ffff00", # Using yellow if the curve can't be found "KRW": "#0000aa", "KRG": "#ff0000", "KROG": "#00aa00", From 03b78c0b4f20b1ff7460714a3199f2fe8bf38282 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 13:02:38 +0200 Subject: [PATCH 44/54] edit test --- .../integration_tests/plugin_tests/test_relative_permeability.py | 1 - .../{_parameter_correlation_old.py => _parameter_correlation.py} | 0 2 files changed, 1 deletion(-) rename webviz_subsurface/plugins/{_parameter_correlation_old.py => _parameter_correlation.py} (100%) diff --git a/tests/integration_tests/plugin_tests/test_relative_permeability.py b/tests/integration_tests/plugin_tests/test_relative_permeability.py index 968ce033e..08692f5dd 100644 --- a/tests/integration_tests/plugin_tests/test_relative_permeability.py +++ b/tests/integration_tests/plugin_tests/test_relative_permeability.py @@ -4,7 +4,6 @@ def test_relative_permeability(dash_duo, app, shared_settings) -> None: plugin = RelativePermeability( - app, shared_settings["HM_SETTINGS"], ensembles=shared_settings["HM_ENSEMBLES"], relpermfile="share/results/tables/relperm.csv", diff --git a/webviz_subsurface/plugins/_parameter_correlation_old.py b/webviz_subsurface/plugins/_parameter_correlation.py similarity index 100% rename from webviz_subsurface/plugins/_parameter_correlation_old.py rename to webviz_subsurface/plugins/_parameter_correlation.py From b8fb1e9be245ff7d91044c71cad494d11b53da91 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 13:33:09 +0200 Subject: [PATCH 45/54] uncomment comment in init import --- webviz_subsurface/plugins/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/__init__.py b/webviz_subsurface/plugins/__init__.py index 0829d00e2..27a8548ac 100644 --- a/webviz_subsurface/plugins/__init__.py +++ b/webviz_subsurface/plugins/__init__.py @@ -32,8 +32,7 @@ from ._map_viewer_fmu import MapViewerFMU from ._morris_plot import MorrisPlot from ._parameter_analysis import ParameterAnalysis - -# from ._parameter_correlation import ParameterCorrelation +from ._parameter_correlation import ParameterCorrelation from ._parameter_distribution import ParameterDistribution from ._parameter_parallel_coordinates import ParameterParallelCoordinates from ._parameter_response_correlation import ParameterResponseCorrelation From ca3dc60bfec8e2a603f9bc8fbe4232bb2c43ce09 Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 13:41:11 +0200 Subject: [PATCH 46/54] removed the new plugin forlder becoause it was creating issue --- webviz_subsurface/plugins/_parameter_correlation/__init__.py | 0 webviz_subsurface/plugins/_parameter_correlation/_error.py | 0 webviz_subsurface/plugins/_parameter_correlation/_plugin.py | 0 webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py | 0 .../plugins/_parameter_correlation/shared_settings/__init__.py | 0 .../plugins/_parameter_correlation/shared_settings/_filter.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/__init__.py delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/_error.py delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/_plugin.py delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py delete mode 100644 webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py diff --git a/webviz_subsurface/plugins/_parameter_correlation/__init__.py b/webviz_subsurface/plugins/_parameter_correlation/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_parameter_correlation/_error.py b/webviz_subsurface/plugins/_parameter_correlation/_error.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_parameter_correlation/_plugin.py b/webviz_subsurface/plugins/_parameter_correlation/_plugin.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py b/webviz_subsurface/plugins/_parameter_correlation/_plugin_ids.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py b/webviz_subsurface/plugins/_parameter_correlation/shared_settings/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py b/webviz_subsurface/plugins/_parameter_correlation/shared_settings/_filter.py deleted file mode 100644 index e69de29bb..000000000 From dcef27712fcaff853e8cdf5ef3be33a06d9d528f Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 14:01:44 +0200 Subject: [PATCH 47/54] remocing indent before layout --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 752c3b0c7..85c70ba2a 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -266,6 +266,6 @@ def __init__( PlugInIDs.RelCapViewGroup.GROUP_NAME, ) - @property - def layout(self) -> Type[Component]: - return error(self.error_message) + @property + def layout(self) -> Type[Component]: + return error(self.error_message) From 059c46e002e80b3eac30e5e5f774e0e546e4268a Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Mon, 11 Jul 2022 14:18:44 +0200 Subject: [PATCH 48/54] fixing the class --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 85c70ba2a..546ddab41 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -103,6 +103,9 @@ def __init__( / "css" / "block_options.css" ) + + self.error_message = "" + try: self.ens_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] From 87aea44ff41b87d12d102644c1001dcf8b991c58 Mon Sep 17 00:00:00 2001 From: Viktoria Vahlin <107865041+vvahlin@users.noreply.github.com> Date: Thu, 4 Aug 2022 08:28:20 +0200 Subject: [PATCH 49/54] Addd webviz store --- .../plugins/_relative_permeability/_plugin.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 546ddab41..dd5be33cc 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -272,3 +272,36 @@ def __init__( @property def layout(self) -> Type[Component]: return error(self.error_message) + + def add_webvizstore(self): + return [ + ( + load_satfunc, + [ + { + "ensemble_paths": self.ens_paths, + "ensemble_set_name": "EnsembleSet", + } + ], + ) + if self.relpermfile is None + else ( + load_csv, + [ + { + "ensemble_paths": self.ens_paths, + "csv_file": self.relpermfile, + "ensemble_set_name": "EnsembleSet", + } + ], + ) + ] + ( + [] + if self.scalfile is None + else [ + ( + load_scal_recommendation, + [{"scalfile": self.scalfile, "sheet_name": self.sheet_name}], + ) + ] + ) From 18090574a93401b29a6ba0c5d92abf99f26bd21b Mon Sep 17 00:00:00 2001 From: Viktoria Vahlin <107865041+vvahlin@users.noreply.github.com> Date: Thu, 4 Aug 2022 08:53:59 +0200 Subject: [PATCH 50/54] Remove accidental space indent --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index dd5be33cc..b48c37226 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -273,7 +273,7 @@ def __init__( def layout(self) -> Type[Component]: return error(self.error_message) - def add_webvizstore(self): + def add_webvizstore(self): return [ ( load_satfunc, From 08c7e997a2f1afdd03fa618fff0b958eb18257af Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Thu, 4 Aug 2022 09:27:10 +0200 Subject: [PATCH 51/54] added tour --- .../plugins/_relative_permeability/_plugin.py | 70 ++++++++++++++++++- .../views/relperm_cappres/_relcap.py | 3 +- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 546ddab41..76ec4187b 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -1,6 +1,6 @@ import warnings from pathlib import Path -from typing import Optional, Type, Union +from typing import List, Optional, Type, Union import pandas as pd from dash.development.base_component import Component @@ -272,3 +272,71 @@ def __init__( @property def layout(self) -> Type[Component]: return error(self.error_message) + + @property + def tour_steps(self) -> List[dict]: + """Tour of the plugin""" + return [ + { + "id": self.view(PlugInIDs.RelCapViewGroup.RELCAP) + .layout_element(RelpermCappres.IDs.MAIN_COLUMN) + .get_unique_id(), + "content": ( + "Dashboard displaying relative permeability and capillary pressure. " + "Different options can be set in the menu to the left." + "You can also toggle data on/off by clicking at the legend." + ), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) + .component_unique_id(Selectors.IDs.SATURATION_AXIS), + "content": ( + "Choose saturation type for your x-axis. Will automatically change available " + "options in 'Curves'." + ), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) + .component_unique_id(Selectors.IDs.COLOR_BY), + "content": ("Choose basis for your colormap."), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) + .component_unique_id(Selectors.IDs.ENSEMBLES), + "content": ("Select ensembles."), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) + .component_unique_id(Selectors.IDs.CURVES), + "content": ( + "Choose curves. Capillary pressures and relative permeabilities will be shown" + " in separate plots." + ), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) + .component_unique_id(Selectors.IDs.SATNUM), + "content": ("Choose SATNUM regions."), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.VISUALIZATION) + .component_unique_id(Visualization.IDs.LINE_TRACES), + "content": ( + "Choose between different visualizations. 1. Show time series as " + "individual lines per realization. 2. Show statistical fanchart per ensemble." + ), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.VISUALIZATION) + .component_unique_id(Visualization.IDs.Y_AXIS), + "content": ("Switch between linear and logarithmic y-axis."), + }, + { + "id": self.shared_settings_group(PlugInIDs.SharedSettings.SCAL_RECOMMENDATION) + .component_unique_id(SCALRecommendation.IDs.SHOW_SCAL), + "content": ( + "Switch on/off SCAL reference data (requires that the optional scalfile is" + " defined)." + ), + }, + ] diff --git a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py index af96cafc3..edb74eb2f 100644 --- a/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py +++ b/webviz_subsurface/plugins/_relative_permeability/views/relperm_cappres/_relcap.py @@ -24,6 +24,7 @@ class RelpermCappres(ViewABC): class IDs: # pylint: disable=too-few-public-methods RELATIVE_PERMEABILIY = "reative-permeability" + MAIN_COLUMN = "main-column" SCAL_COLORMAP = { "Missing": "#ffff00", # Using yellow if the curve can't be found @@ -50,7 +51,7 @@ def __init__( self.sat_axes_maps = sat_axes_maps # Creating the column and row for the setup of the view - column = self.add_column() + column = self.add_column(RelpermCappres.IDs.MAIN_COLUMN) first_row = column.make_row() first_row.add_view_element(Graph(), RelpermCappres.IDs.RELATIVE_PERMEABILIY) From 2b62274267b2263329248f993d0eaaefc732a7fd Mon Sep 17 00:00:00 2001 From: "Viktoria Christine Vahlin (OG SUB RPE)" Date: Thu, 4 Aug 2022 09:31:16 +0200 Subject: [PATCH 52/54] indent --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 8a4061278..7410a8be0 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -341,7 +341,7 @@ def tour_steps(self) -> List[dict]: }, ] - def add_webvizstore(self): + def add_webvizstore(self): return [ ( load_satfunc, From bf12f36a752659b9a54c9e16aa5847857539bb62 Mon Sep 17 00:00:00 2001 From: Viktoria Vahlin <107865041+vvahlin@users.noreply.github.com> Date: Thu, 4 Aug 2022 10:09:29 +0200 Subject: [PATCH 53/54] reformate black --- .../plugins/_relative_permeability/_plugin.py | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index 7410a8be0..cee343f66 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -288,52 +288,60 @@ def tour_steps(self) -> List[dict]: ), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) - .component_unique_id(Selectors.IDs.SATURATION_AXIS), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SELECTORS + ).component_unique_id(Selectors.IDs.SATURATION_AXIS), "content": ( "Choose saturation type for your x-axis. Will automatically change available " "options in 'Curves'." ), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) - .component_unique_id(Selectors.IDs.COLOR_BY), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SELECTORS + ).component_unique_id(Selectors.IDs.COLOR_BY), "content": ("Choose basis for your colormap."), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) - .component_unique_id(Selectors.IDs.ENSEMBLES), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SELECTORS + ).component_unique_id(Selectors.IDs.ENSEMBLES), "content": ("Select ensembles."), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) - .component_unique_id(Selectors.IDs.CURVES), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SELECTORS + ).component_unique_id(Selectors.IDs.CURVES), "content": ( "Choose curves. Capillary pressures and relative permeabilities will be shown" " in separate plots." ), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SELECTORS) - .component_unique_id(Selectors.IDs.SATNUM), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SELECTORS + ).component_unique_id(Selectors.IDs.SATNUM), "content": ("Choose SATNUM regions."), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.VISUALIZATION) - .component_unique_id(Visualization.IDs.LINE_TRACES), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.VISUALIZATION + ).component_unique_id(Visualization.IDs.LINE_TRACES), "content": ( "Choose between different visualizations. 1. Show time series as " "individual lines per realization. 2. Show statistical fanchart per ensemble." ), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.VISUALIZATION) - .component_unique_id(Visualization.IDs.Y_AXIS), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.VISUALIZATION + ).component_unique_id(Visualization.IDs.Y_AXIS), "content": ("Switch between linear and logarithmic y-axis."), }, { - "id": self.shared_settings_group(PlugInIDs.SharedSettings.SCAL_RECOMMENDATION) - .component_unique_id(SCALRecommendation.IDs.SHOW_SCAL), + "id": self.shared_settings_group( + PlugInIDs.SharedSettings.SCAL_RECOMMENDATION + ).component_unique_id(SCALRecommendation.IDs.SHOW_SCAL), "content": ( "Switch on/off SCAL reference data (requires that the optional scalfile is" " defined)." From e1ea63aa93b3acc58aec797b80cc5bcb86098419 Mon Sep 17 00:00:00 2001 From: Viktoria Vahlin <107865041+vvahlin@users.noreply.github.com> Date: Thu, 4 Aug 2022 12:22:38 +0200 Subject: [PATCH 54/54] Stretch=True --- webviz_subsurface/plugins/_relative_permeability/_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webviz_subsurface/plugins/_relative_permeability/_plugin.py b/webviz_subsurface/plugins/_relative_permeability/_plugin.py index cee343f66..800da40e3 100644 --- a/webviz_subsurface/plugins/_relative_permeability/_plugin.py +++ b/webviz_subsurface/plugins/_relative_permeability/_plugin.py @@ -95,7 +95,7 @@ def __init__( ): # pylint: disable=too-many-statements - super().__init__() + super().__init__(stretch=True) WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent