Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulation metadata #323

Merged
merged 1 commit into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
{
"METRIC":
{
"SM3": "Sm³",
"METRIC": {
"M": "m",
"M3": "m³",
"RM3": "m³",
"SECONDS": "seconds",
"DAYS": "days",
"YEARS": "years",
"KG/M3": "kg/m³",
"BARSA": "bara",
"bars": "bar",
"K": "K",
"C": "\u00B0C",
"CP": "cP",
"MD": "mD",
"SM3": "Sm³",
"RM3": "Rm³",
"SM3/DAY": "Sm³/day",
"RM3/DAY": "m³/day",
"RM3/DAY": "Rm³/day",
"CPR3/DAY/BARS": "Rm³\u00D7cP/day/bar",
"MDM": "mD\u00D7m",
"KG": "kg",
"KG/DAY": "kg/day",
"SM3/SM3": "Sm³/Sm³",
"RM3/SM3": "m³/Sm³",
"BARSA": "bara",
"BARS": "barg",
"RM3/SM3": "Rm³/Sm³",
"SM3/RM3": "Sm³/Rm³",
"SM3/DAY/BARS": "Sm³/day/bar",
"SM3/D/B": "Sm³/day/bar",
"SECONDS": "s",
"DAYS": "days"
}
"KJ": "kJ",
"KJ/DAY": "kJ/day",
"SEC/D": "seconds/day"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
"RECOVERABLE_GAS": {"label": "Recoverable volume (gas zone)", "unit": "Sm³"},
"RECOVERABLE_TOTAL": {"label": "Recoverable volume (total)", "unit": "Sm³"}
}

32 changes: 21 additions & 11 deletions webviz_subsurface/_abbreviations/number_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,33 @@
import json
import pathlib
import warnings
from typing import Optional, Union
from typing import Optional, Union, List


_DATA_PATH = pathlib.Path(__file__).parent.absolute() / "abbreviation_data"

SI_PREFIXES = json.loads((_DATA_PATH / "si_prefixes.json").read_text())

TABLE_STATISTICS_BASE = [
(
i,
{
"type": "numeric",
"format": {"locale": {"symbol": ["", "unit_insert"]}, "specifier": "$.4s",},
},
)
for i in ["Mean", "Stddev", "Minimum", "P90", "P10", "Maximum"]
]

def table_statistics_base() -> List[tuple]:
return [
(
i,
{
"type": "numeric",
"format": {"locale": {"symbol": ["", ""]}, "specifier": "$.4s",},
},
)
if i != "Stddev"
else (
i,
{
"type": "numeric",
"format": {"locale": {"symbol": ["", ""]}, "specifier": "$.3s",},
},
)
for i in ["Mean", "Stddev", "Minimum", "P90", "P10", "Maximum"]
]


def si_prefixed(
Expand Down
54 changes: 50 additions & 4 deletions webviz_subsurface/_abbreviations/reservoir_simulation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import json
import pathlib
import warnings
from typing import Optional

import pandas as pd


_DATA_PATH = pathlib.Path(__file__).parent.absolute() / "abbreviation_data"
Expand All @@ -14,7 +17,7 @@
)


def simulation_unit_reformat(ecl_unit: str, unit_set: str = "METRIC"):
def simulation_unit_reformat(ecl_unit: str, unit_set: str = "METRIC") -> str:
"""Returns the simulation unit in a different, more human friendly, format if possible,
otherwise returns the simulation unit.
* `ecl_unit`: Reservoir simulation vector unit to reformat
Expand All @@ -23,15 +26,14 @@ def simulation_unit_reformat(ecl_unit: str, unit_set: str = "METRIC"):
return RESERVOIR_SIMULATION_UNIT_TERMINOLOGY[unit_set].get(ecl_unit, ecl_unit)


def simulation_vector_base(vector: str):
def simulation_vector_base(vector: str) -> str:
"""Returns base name of simulation vector
E.g. WOPR for WOPR:OP_1 and ROIP for ROIP_REG:1
"""

return vector.split(":", 1)[0].split("_", 1)[0]


def simulation_vector_description(vector: str):
def simulation_vector_description(vector: str) -> str:
"""Returns a more human friendly description of the simulation vector if possible,
otherwise returns the input as is.
"""
Expand Down Expand Up @@ -71,3 +73,47 @@ def simulation_vector_description(vector: str):
)

return description


def historical_vector(
vector: str,
smry_meta: Optional[pd.DataFrame] = None,
asnyv marked this conversation as resolved.
Show resolved Hide resolved
return_historical: Optional[bool] = True,
):
"""This function is trying to make a best guess on converting between historical and
non-historical vector names.

`vector`: An Eclipse-format vector string
`smry_meta`: Note: Not activate avaiting https://github.com/equinor/libecl/issues/708
A pandas DataFrame with vector metadata on the format returned by
`load_smry_meta` in `../_datainput/fmu_input.py`. Here the field is_historical is
used to check if a vector is a historical vector.
`return_historical`: If return_historical is `True`, the corresponding guessed historical
vector name is returned if the guessed vector is thought to be a
historical vector, else None is returned. If `False` the corresponding
non-historical vector name is returned, if the input vector is thought to
be a historical vector, else None is returned.
"""
smry_meta = None # Temp deactivation waiting on https://github.com/equinor/libecl/issues/708
parts = vector.split(":", 1)
if return_historical:
parts[0] += "H"
hist_vec = ":".join(parts)
return (
None
if historical_vector(hist_vec, smry_meta=smry_meta, return_historical=False)
is None
else hist_vec
)

if smry_meta is None:
if parts[0].endswith("H") and parts[0].startswith(("F", "G", "W")):
parts[0] = parts[0][:-1]
return ":".join(parts)
return None

try:
is_hist = smry_meta.is_historical[vector]
except KeyError:
is_hist = False
return parts[0][:-1] if is_hist else None
18 changes: 18 additions & 0 deletions webviz_subsurface/_datainput/fmu_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ def load_smry(
)


@CACHE.memoize(timeout=CACHE.TIMEOUT)
@webvizstore
def load_smry_meta(
ensemble_paths: dict,
ensemble_set_name: str = "EnsembleSet",
column_keys: Optional[list] = None,
) -> pd.DataFrame:
"""Finds metadata for the summary vectors in the ensemble set.
Note that we assume the same units for all ensembles.
(meaning that we update/overwrite when checking the next ensemble)
"""
ensemble_set = load_ensemble_set(ensemble_paths, ensemble_set_name)
smry_meta = {}
for ensname in ensemble_set.ensemblenames:
smry_meta.update(ensemble_set[ensname].get_smry_meta(column_keys=column_keys))
return pd.DataFrame(smry_meta).transpose()


@CACHE.memoize(timeout=CACHE.TIMEOUT)
@webvizstore
def get_realizations(
Expand Down
Empty file.
38 changes: 38 additions & 0 deletions webviz_subsurface/_utils/simulation_timeseries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import warnings
from typing import Optional

import pandas as pd


def set_simulation_line_shape_fallback(line_shape_fallback: str) -> str:
"""
Defines a Plotly line_shape to use if a vector is not thought to be a rate or a total.
"""
line_shape_fallback = line_shape_fallback.lower()
if line_shape_fallback in ("backfilled", "backfill"):
return "vh"
if line_shape_fallback in ["hv", "vh", "hvh", "vhv", "spline", "linear"]:
return line_shape_fallback
warnings.warn(
f"{line_shape_fallback}, is not a valid line_shape option, will use linear."
)
return "linear"


def get_simulation_line_shape(
line_shape_fallback: str, vector: str, smry_meta: Optional[pd.DataFrame] = None
) -> str:
"""Get simulation time series line shape, smry_meta is a pd.DataFrame on the format given
by `load_smry_meta` in `../_datainput/fmu_input.py`.
"""

if smry_meta is None:
return line_shape_fallback
try:
if smry_meta.is_rate[vector]:
return "vh"
if smry_meta.is_total[vector]:
return "linear"
except (AttributeError, KeyError):
pass
return line_shape_fallback
Loading