webviz-subsurface 0.2.38__py3-none-any.whl → 0.2.40__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webviz_subsurface/_components/tornado/_tornado_bar_chart.py +31 -11
- webviz_subsurface/_components/tornado/_tornado_data.py +20 -2
- webviz_subsurface/_figures/timeseries_figure.py +1 -1
- webviz_subsurface/_providers/ensemble_summary_provider/_provider_impl_arrow_lazy.py +3 -1
- webviz_subsurface/_providers/ensemble_summary_provider/_provider_impl_arrow_presampled.py +3 -1
- webviz_subsurface/_providers/ensemble_table_provider/ensemble_table_provider_factory.py +4 -0
- webviz_subsurface/_providers/ensemble_table_provider/ensemble_table_provider_impl_arrow.py +3 -1
- webviz_subsurface/_utils/dataframe_utils.py +1 -1
- webviz_subsurface/_utils/design_matrix.py +36 -0
- webviz_subsurface/_version.py +34 -0
- webviz_subsurface/plugins/_bhp_qc/views/_view_functions.py +5 -5
- webviz_subsurface/plugins/_co2_leakage/_utilities/co2volume.py +1 -1
- webviz_subsurface/plugins/_disk_usage.py +19 -8
- webviz_subsurface/plugins/_line_plotter_fmu/controllers/build_figure.py +4 -4
- webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py +1 -1
- webviz_subsurface/plugins/_parameter_analysis/_types.py +1 -0
- webviz_subsurface/plugins/_parameter_analysis/_utils/_parameters_model.py +15 -7
- webviz_subsurface/plugins/_parameter_analysis/_views/_parameter_distributions_view/_settings/_visualization_type.py +2 -1
- webviz_subsurface/plugins/_property_statistics/property_statistics.py +1 -1
- webviz_subsurface/plugins/_relative_permeability.py +6 -6
- webviz_subsurface/plugins/_reservoir_simulation_timeseries_regional.py +12 -12
- webviz_subsurface/plugins/_running_time_analysis_fmu.py +6 -1
- webviz_subsurface/plugins/_seismic_misfit.py +2 -3
- webviz_subsurface/plugins/_simulation_time_series/_views/_subplot_view/_utils/vector_statistics.py +4 -4
- webviz_subsurface/plugins/_structural_uncertainty/views/intersection_and_map.py +1 -1
- webviz_subsurface/plugins/_swatinit_qc/_business_logic.py +1 -1
- webviz_subsurface-0.2.40.dist-info/METADATA +822 -0
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info}/RECORD +33 -83
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info}/WHEEL +1 -1
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info}/top_level.txt +0 -1
- tests/integration_tests/__init__.py +0 -0
- tests/integration_tests/test_parameter_filter.py +0 -28
- tests/integration_tests/test_surface_selector.py +0 -53
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/abbreviations_tests/__init__.py +0 -0
- tests/unit_tests/abbreviations_tests/test_reservoir_simulation.py +0 -94
- tests/unit_tests/data_input/__init__.py +0 -0
- tests/unit_tests/data_input/test_calc_from_cumulatives.py +0 -178
- tests/unit_tests/data_input/test_image_processing.py +0 -11
- tests/unit_tests/mocks/__init__.py +0 -0
- tests/unit_tests/mocks/ensemble_summary_provider_dummy.py +0 -67
- tests/unit_tests/model_tests/__init__.py +0 -0
- tests/unit_tests/model_tests/test_ensemble_model.py +0 -176
- tests/unit_tests/model_tests/test_ensemble_set_model.py +0 -105
- tests/unit_tests/model_tests/test_gruptree_model.py +0 -89
- tests/unit_tests/model_tests/test_property_statistics_model.py +0 -42
- tests/unit_tests/model_tests/test_surface_set_model.py +0 -48
- tests/unit_tests/model_tests/test_well_attributes_model.py +0 -110
- tests/unit_tests/model_tests/test_well_set_model.py +0 -70
- tests/unit_tests/plugin_tests/__init__.py +0 -0
- tests/unit_tests/plugin_tests/test_grouptree.py +0 -175
- tests/unit_tests/plugin_tests/test_simulation_time_series/__init__.py +0 -0
- tests/unit_tests/plugin_tests/test_simulation_time_series/mocks/__init__.py +0 -0
- tests/unit_tests/plugin_tests/test_simulation_time_series/mocks/derived_vectors_accessor_ensemble_summary_provider_mock.py +0 -60
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/__init__.py +0 -0
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_create_vector_traces_utils.py +0 -530
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_dataframe_utils.py +0 -119
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_datetime_utils.py +0 -51
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_delta_ensemble_utils.py +0 -222
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_derived_delta_ensemble_vectors_accessor_impl.py +0 -319
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_derived_ensemble_vectors_accessor_impl.py +0 -271
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_derived_ensemble_vectors_accessor_utils.py +0 -78
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_derived_vector_accessor.py +0 -57
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_ensemble_summary_provider_set_utils.py +0 -213
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_from_timeseries_cumulatives.py +0 -322
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_history_vectors.py +0 -201
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_trace_line_shape.py +0 -56
- tests/unit_tests/plugin_tests/test_simulation_time_series/test_utils/test_vector_statistics.py +0 -171
- tests/unit_tests/plugin_tests/test_tornado_data.py +0 -121
- tests/unit_tests/plugin_tests/test_well_completions.py +0 -158
- tests/unit_tests/provider_tests/__init__.py +0 -0
- tests/unit_tests/provider_tests/test_ensemble_summary_provider.py +0 -255
- tests/unit_tests/provider_tests/test_ensemble_summary_provider_impl_arrow_lazy.py +0 -388
- tests/unit_tests/provider_tests/test_ensemble_summary_provider_impl_arrow_presampled.py +0 -160
- tests/unit_tests/provider_tests/test_ensemble_summary_provider_resampling.py +0 -320
- tests/unit_tests/provider_tests/test_ensemble_table_provider.py +0 -190
- tests/unit_tests/utils_tests/__init__.py +0 -0
- tests/unit_tests/utils_tests/test_dataframe_utils.py +0 -281
- tests/unit_tests/utils_tests/test_ensemble_summary_provider_set/__init__.py +0 -0
- tests/unit_tests/utils_tests/test_ensemble_summary_provider_set/test_ensemble_summary_provider_set.py +0 -306
- tests/unit_tests/utils_tests/test_formatting.py +0 -10
- tests/unit_tests/utils_tests/test_simulation_timeseries.py +0 -51
- webviz_subsurface-0.2.38.dist-info/METADATA +0 -147
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info}/entry_points.txt +0 -0
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info/licenses}/LICENSE +0 -0
- {webviz_subsurface-0.2.38.dist-info → webviz_subsurface-0.2.40.dist-info/licenses}/LICENSE.chromedriver +0 -0
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
|
|
3
|
-
from webviz_subsurface._datainput.image_processing import array_to_png
|
|
4
|
-
|
|
5
|
-
with open("tests/data/surface_png.txt", "r") as file:
|
|
6
|
-
BASE64_SURFACE = file.read()
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def test_array_to_png() -> None:
|
|
10
|
-
data = np.loadtxt("tests/data/surface_zarr.np.gz")
|
|
11
|
-
assert array_to_png(data) == BASE64_SURFACE
|
|
File without changes
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
from typing import List, Optional, Sequence
|
|
3
|
-
|
|
4
|
-
import pandas as pd
|
|
5
|
-
|
|
6
|
-
from webviz_subsurface._providers import (
|
|
7
|
-
EnsembleSummaryProvider,
|
|
8
|
-
Frequency,
|
|
9
|
-
VectorMetadata,
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class EnsembleSummaryProviderDummy(EnsembleSummaryProvider):
|
|
14
|
-
"""Class for EnsembleSummaryProvider mock implementations
|
|
15
|
-
|
|
16
|
-
Creates dummy class implementing all methods in EnsembleSummaryProvider with
|
|
17
|
-
NotImplementedError. Derived class is responsible to override necessary methods
|
|
18
|
-
to obtain wanted functionality
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
#####################################################e
|
|
22
|
-
#
|
|
23
|
-
# Interface methods raise NotImplementedError
|
|
24
|
-
#
|
|
25
|
-
#####################################################
|
|
26
|
-
|
|
27
|
-
def vector_names(self) -> List[str]:
|
|
28
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
29
|
-
|
|
30
|
-
def realizations(self) -> List[int]:
|
|
31
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
32
|
-
|
|
33
|
-
def vector_metadata(self, vector_name: str) -> Optional[VectorMetadata]:
|
|
34
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
35
|
-
|
|
36
|
-
def vector_names_filtered_by_value(
|
|
37
|
-
self,
|
|
38
|
-
exclude_all_values_zero: bool = False,
|
|
39
|
-
exclude_constant_values: bool = False,
|
|
40
|
-
) -> List[str]:
|
|
41
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
42
|
-
|
|
43
|
-
def dates(
|
|
44
|
-
self,
|
|
45
|
-
resampling_frequency: Optional[Frequency],
|
|
46
|
-
realizations: Optional[Sequence[int]] = None,
|
|
47
|
-
) -> List[datetime.datetime]:
|
|
48
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
49
|
-
|
|
50
|
-
def supports_resampling(self) -> bool:
|
|
51
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
52
|
-
|
|
53
|
-
def get_vectors_df(
|
|
54
|
-
self,
|
|
55
|
-
vector_names: Sequence[str],
|
|
56
|
-
resampling_frequency: Optional[Frequency],
|
|
57
|
-
realizations: Optional[Sequence[int]] = None,
|
|
58
|
-
) -> pd.DataFrame:
|
|
59
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
60
|
-
|
|
61
|
-
def get_vectors_for_date_df(
|
|
62
|
-
self,
|
|
63
|
-
date: datetime.datetime,
|
|
64
|
-
vector_names: Sequence[str],
|
|
65
|
-
realizations: Optional[Sequence[int]] = None,
|
|
66
|
-
) -> pd.DataFrame:
|
|
67
|
-
raise NotImplementedError("Method not implemented for mock!")
|
|
File without changes
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import numpy as np
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
|
-
from webviz_subsurface._models.ensemble_model import EnsembleModel
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@pytest.mark.usefixtures("app")
|
|
11
|
-
def test_ensemble_set_init(testdata_folder):
|
|
12
|
-
emodel = EnsembleModel(
|
|
13
|
-
ensemble_name="iter-0",
|
|
14
|
-
ensemble_path=Path(testdata_folder)
|
|
15
|
-
/ "01_drogon_ahm"
|
|
16
|
-
/ "realization-*"
|
|
17
|
-
/ "iter-0",
|
|
18
|
-
)
|
|
19
|
-
assert emodel.ens_folder == {"iter-0": f"{testdata_folder}/01_drogon_ahm/"}
|
|
20
|
-
assert not emodel.webviz_store
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.usefixtures("app")
|
|
24
|
-
def test_bad_ensemble_path():
|
|
25
|
-
emodel = EnsembleModel(ensemble_name="iter-0", ensemble_path="some_path")
|
|
26
|
-
with pytest.raises(ValueError) as exception:
|
|
27
|
-
emodel.load_ensemble()
|
|
28
|
-
assert (
|
|
29
|
-
exception.value.args[0]
|
|
30
|
-
== "No realizations found for ensemble iter-0, located at 'some_path'. Aborting..."
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@pytest.mark.usefixtures("app")
|
|
35
|
-
def test_smry_load(testdata_folder):
|
|
36
|
-
emodel = EnsembleModel(
|
|
37
|
-
ensemble_name="iter-0",
|
|
38
|
-
ensemble_path=Path(testdata_folder)
|
|
39
|
-
/ "01_drogon_ahm"
|
|
40
|
-
/ "realization-*"
|
|
41
|
-
/ "iter-0",
|
|
42
|
-
)
|
|
43
|
-
smry = emodel.load_smry()
|
|
44
|
-
assert len(smry.columns) == 933
|
|
45
|
-
assert len(smry["DATE"].unique()) == 2369
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@pytest.mark.usefixtures("app")
|
|
49
|
-
def test_smry_load_filter_and_dtypes(testdata_folder):
|
|
50
|
-
emodel = EnsembleModel(
|
|
51
|
-
ensemble_name="iter-0",
|
|
52
|
-
ensemble_path=Path(testdata_folder)
|
|
53
|
-
/ "01_drogon_ahm"
|
|
54
|
-
/ "realization-*"
|
|
55
|
-
/ "iter-0",
|
|
56
|
-
)
|
|
57
|
-
smry = emodel.load_smry(column_keys=["FO*"], time_index="yearly")
|
|
58
|
-
assert set(smry.columns) == set(
|
|
59
|
-
[
|
|
60
|
-
"DATE",
|
|
61
|
-
"REAL",
|
|
62
|
-
"FOPRF",
|
|
63
|
-
"FOPRS",
|
|
64
|
-
"FOPRH",
|
|
65
|
-
"FOPTH",
|
|
66
|
-
"FOPR",
|
|
67
|
-
"FOPTS",
|
|
68
|
-
"FOPTF",
|
|
69
|
-
"FOPT",
|
|
70
|
-
"FOIP",
|
|
71
|
-
"FOPP",
|
|
72
|
-
]
|
|
73
|
-
)
|
|
74
|
-
assert set(smry["DATE"].unique()) == set(
|
|
75
|
-
[
|
|
76
|
-
datetime.date(2021, 1, 1),
|
|
77
|
-
datetime.date(2019, 1, 1),
|
|
78
|
-
datetime.date(2020, 1, 1),
|
|
79
|
-
datetime.date(2018, 1, 1),
|
|
80
|
-
]
|
|
81
|
-
)
|
|
82
|
-
assert smry["DATE"].dtype == np.dtype("O")
|
|
83
|
-
assert smry["REAL"].dtype == np.dtype("int64")
|
|
84
|
-
assert all(
|
|
85
|
-
np.issubdtype(dtype, np.number)
|
|
86
|
-
for dtype in smry.drop(["REAL", "DATE"], axis=1).dtypes
|
|
87
|
-
)
|
|
88
|
-
smry = emodel.load_smry(column_keys=["F[OGW]P?", "FOIP"], time_index="yearly")
|
|
89
|
-
assert set(smry.columns) == set(
|
|
90
|
-
[
|
|
91
|
-
"REAL",
|
|
92
|
-
"DATE",
|
|
93
|
-
"FGPP",
|
|
94
|
-
"FGPR",
|
|
95
|
-
"FGPT",
|
|
96
|
-
"FOPP",
|
|
97
|
-
"FOPR",
|
|
98
|
-
"FOPT",
|
|
99
|
-
"FWPP",
|
|
100
|
-
"FWPR",
|
|
101
|
-
"FWPT",
|
|
102
|
-
"FOIP",
|
|
103
|
-
]
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@pytest.mark.usefixtures("app")
|
|
108
|
-
def test_smry_meta(testdata_folder):
|
|
109
|
-
emodel = EnsembleModel(
|
|
110
|
-
ensemble_name="iter-0",
|
|
111
|
-
ensemble_path=Path(testdata_folder)
|
|
112
|
-
/ "01_drogon_ahm"
|
|
113
|
-
/ "realization-*"
|
|
114
|
-
/ "iter-0",
|
|
115
|
-
)
|
|
116
|
-
smeta = emodel.load_smry_meta()
|
|
117
|
-
assert set(smeta.columns) == set(
|
|
118
|
-
["unit", "is_total", "is_rate", "is_historical", "keyword", "wgname", "get_num"]
|
|
119
|
-
)
|
|
120
|
-
assert len(smeta) == 931
|
|
121
|
-
assert "FOPT" in smeta.index
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
@pytest.mark.usefixtures("app")
|
|
125
|
-
def test_parameter_loading(testdata_folder):
|
|
126
|
-
emodel = EnsembleModel(
|
|
127
|
-
ensemble_name="iter-0",
|
|
128
|
-
ensemble_path=Path(testdata_folder)
|
|
129
|
-
/ "01_drogon_ahm"
|
|
130
|
-
/ "realization-*"
|
|
131
|
-
/ "iter-0",
|
|
132
|
-
)
|
|
133
|
-
parameters = emodel.load_parameters()
|
|
134
|
-
assert "REAL" in parameters.columns
|
|
135
|
-
assert parameters["REAL"].dtype == np.dtype("int64")
|
|
136
|
-
assert len(parameters.columns) == 55
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
@pytest.mark.usefixtures("app")
|
|
140
|
-
def test_load_csv(testdata_folder):
|
|
141
|
-
emodel = EnsembleModel(
|
|
142
|
-
ensemble_name="iter-0",
|
|
143
|
-
ensemble_path=Path(testdata_folder)
|
|
144
|
-
/ "01_drogon_ahm"
|
|
145
|
-
/ "realization-*"
|
|
146
|
-
/ "iter-0",
|
|
147
|
-
)
|
|
148
|
-
dframe = emodel.load_csv(Path("share") / "results" / "tables" / "rft.csv")
|
|
149
|
-
assert "REAL" in dframe.columns
|
|
150
|
-
assert dframe["REAL"].dtype == np.dtype("int64")
|
|
151
|
-
assert len(dframe.columns) == 14
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
@pytest.mark.usefixtures("app")
|
|
155
|
-
def test_webviz_store(testdata_folder):
|
|
156
|
-
emodel = EnsembleModel(
|
|
157
|
-
ensemble_name="iter-0",
|
|
158
|
-
ensemble_path=Path(testdata_folder)
|
|
159
|
-
/ "01_drogon_ahm"
|
|
160
|
-
/ "realization-*"
|
|
161
|
-
/ "iter-0",
|
|
162
|
-
)
|
|
163
|
-
emodel.load_parameters()
|
|
164
|
-
assert len(emodel.webviz_store) == 1
|
|
165
|
-
emodel.load_smry()
|
|
166
|
-
assert len(emodel.webviz_store) == 2
|
|
167
|
-
emodel.load_smry(column_keys=["FOIP"])
|
|
168
|
-
assert len(emodel.webviz_store) == 3
|
|
169
|
-
emodel.load_smry(time_index="raw")
|
|
170
|
-
assert len(emodel.webviz_store) == 4
|
|
171
|
-
emodel.load_smry_meta()
|
|
172
|
-
assert len(emodel.webviz_store) == 5
|
|
173
|
-
emodel.load_smry_meta(column_keys=["R*", "GW?T*"])
|
|
174
|
-
assert len(emodel.webviz_store) == 6
|
|
175
|
-
emodel.load_csv(Path("share") / "results" / "tables" / "rft.csv")
|
|
176
|
-
assert len(emodel.webviz_store) == 7
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
import pytest
|
|
5
|
-
|
|
6
|
-
from webviz_subsurface._models.ensemble_set_model import EnsembleSetModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@pytest.mark.usefixtures("app")
|
|
10
|
-
def test_single_ensemble(testdata_folder):
|
|
11
|
-
emodel = EnsembleSetModel(
|
|
12
|
-
ensemble_paths={
|
|
13
|
-
"iter-0": str(
|
|
14
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-0")
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
)
|
|
18
|
-
assert emodel.ens_folders == {"iter-0": Path(testdata_folder) / "01_drogon_ahm"}
|
|
19
|
-
smry = emodel.get_or_load_smry_cached()
|
|
20
|
-
assert len(smry.columns) == 934
|
|
21
|
-
assert len(smry["DATE"].unique()) == 2369
|
|
22
|
-
assert smry["ENSEMBLE"].unique() == ["iter-0"]
|
|
23
|
-
assert smry["ENSEMBLE"].dtype == np.dtype("O")
|
|
24
|
-
assert all(
|
|
25
|
-
np.issubdtype(dtype, np.number)
|
|
26
|
-
for dtype in smry.drop(["REAL", "ENSEMBLE", "DATE"], axis=1).dtypes
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
parameters = emodel.load_parameters()
|
|
30
|
-
assert all(col in parameters.columns for col in ["ENSEMBLE", "REAL"])
|
|
31
|
-
assert parameters["ENSEMBLE"].dtype == np.dtype("O")
|
|
32
|
-
assert parameters["REAL"].dtype == np.dtype("int64")
|
|
33
|
-
assert len(parameters.columns) == 56
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@pytest.mark.usefixtures("app")
|
|
37
|
-
def test_smry_load_multiple_ensembles(testdata_folder):
|
|
38
|
-
emodel = EnsembleSetModel(
|
|
39
|
-
ensemble_paths={
|
|
40
|
-
"iter-0": str(
|
|
41
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-0")
|
|
42
|
-
),
|
|
43
|
-
"iter-3": str(
|
|
44
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-3")
|
|
45
|
-
),
|
|
46
|
-
}
|
|
47
|
-
)
|
|
48
|
-
smry = emodel.get_or_load_smry_cached()
|
|
49
|
-
assert len(smry.columns) == 934
|
|
50
|
-
assert len(smry["DATE"].unique()) == 4167
|
|
51
|
-
assert set(smry["ENSEMBLE"].unique()) == set(["iter-0", "iter-3"])
|
|
52
|
-
assert smry["ENSEMBLE"].dtype == np.dtype("O")
|
|
53
|
-
# assert smry["DATE"].dtype == np.dtype("O") # Fails due to wrong input data?
|
|
54
|
-
assert smry["REAL"].dtype == np.dtype("int64")
|
|
55
|
-
assert all(
|
|
56
|
-
np.issubdtype(dtype, np.number)
|
|
57
|
-
for dtype in smry.drop(["REAL", "ENSEMBLE", "DATE"], axis=1).dtypes
|
|
58
|
-
)
|
|
59
|
-
smeta = emodel.load_smry_meta()
|
|
60
|
-
assert set(smeta.columns) == set(
|
|
61
|
-
["unit", "is_total", "is_rate", "is_historical", "keyword", "wgname", "get_num"]
|
|
62
|
-
)
|
|
63
|
-
assert len(smeta) == 931
|
|
64
|
-
assert "FOPT" in smeta.index
|
|
65
|
-
|
|
66
|
-
parameters = emodel.load_parameters()
|
|
67
|
-
assert all(col in parameters.columns for col in ["ENSEMBLE", "REAL"])
|
|
68
|
-
assert parameters["ENSEMBLE"].dtype == np.dtype("O")
|
|
69
|
-
assert parameters["REAL"].dtype == np.dtype("int64")
|
|
70
|
-
assert len(parameters.columns) == 56
|
|
71
|
-
|
|
72
|
-
dframe = emodel.load_csv(Path("share") / "results" / "tables" / "rft.csv")
|
|
73
|
-
assert "ENSEMBLE" in dframe.columns
|
|
74
|
-
assert dframe["ENSEMBLE"].dtype == np.dtype("O")
|
|
75
|
-
assert len(dframe["ENSEMBLE"].unique()) == 2
|
|
76
|
-
assert len(dframe.columns) == 15
|
|
77
|
-
|
|
78
|
-
with pytest.raises(KeyError) as exc:
|
|
79
|
-
emodel.load_csv("some_path")
|
|
80
|
-
assert (
|
|
81
|
-
exc.value.args[0]
|
|
82
|
-
== "No data found for load_csv with arguments: {'csv_file': 'some_path'}"
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@pytest.mark.usefixtures("app")
|
|
87
|
-
def test_webvizstore(testdata_folder):
|
|
88
|
-
emodel = EnsembleSetModel(
|
|
89
|
-
ensemble_paths={
|
|
90
|
-
"iter-0": str(
|
|
91
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-0")
|
|
92
|
-
),
|
|
93
|
-
"iter-3": str(
|
|
94
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-3")
|
|
95
|
-
),
|
|
96
|
-
}
|
|
97
|
-
)
|
|
98
|
-
emodel.load_parameters()
|
|
99
|
-
assert len(emodel.webvizstore) == 2
|
|
100
|
-
emodel.get_or_load_smry_cached()
|
|
101
|
-
assert len(emodel.webvizstore) == 4
|
|
102
|
-
emodel.load_smry_meta()
|
|
103
|
-
assert len(emodel.webvizstore) == 6
|
|
104
|
-
emodel.load_csv(Path("share") / "results" / "tables" / "rft.csv")
|
|
105
|
-
assert len(emodel.webvizstore) == 8
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import pytest
|
|
7
|
-
from pandas._testing import assert_frame_equal
|
|
8
|
-
|
|
9
|
-
from webviz_subsurface._models.gruptree_model import GruptreeModel, TreeType
|
|
10
|
-
|
|
11
|
-
CHECK_COLUMNS = ["DATE", "CHILD", "KEYWORD", "PARENT"]
|
|
12
|
-
ENSEMBLE = "01_drogon_ahm"
|
|
13
|
-
GRUPTREE_FILE = "share/results/tables/gruptree.csv"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@pytest.fixture(name="gruptree_model")
|
|
17
|
-
def fixture_model(testdata_folder) -> GruptreeModel:
|
|
18
|
-
ens_path = Path(testdata_folder) / ENSEMBLE / "realization-*" / "iter-0"
|
|
19
|
-
return GruptreeModel(
|
|
20
|
-
ens_name="iter-0",
|
|
21
|
-
ens_path=ens_path,
|
|
22
|
-
gruptree_file=GRUPTREE_FILE,
|
|
23
|
-
tree_type="GRUPTREE",
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Mock class that loads local csv file
|
|
28
|
-
class MockGruptreeModel(GruptreeModel):
|
|
29
|
-
# pylint: disable=super-init-not-called
|
|
30
|
-
def __init__(self, tree_type: Optional[TreeType] = None):
|
|
31
|
-
self._tree_type = tree_type
|
|
32
|
-
df_files = pd.DataFrame([{"REAL": 0, "FULLPATH": "tests/data/gruptree.csv"}])
|
|
33
|
-
self._dataframe = self.read_ensemble_gruptree(df_files=df_files)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@pytest.mark.usefixtures("app")
|
|
37
|
-
def test_gruptree_model_init(testdata_folder, gruptree_model: GruptreeModel):
|
|
38
|
-
# Check that there is only one REAL (means that the gruptree is
|
|
39
|
-
# the same for all realizations)
|
|
40
|
-
assert gruptree_model.dataframe["REAL"].nunique() == 1
|
|
41
|
-
|
|
42
|
-
# Load gruptree table from realization-0 and compare with
|
|
43
|
-
# the dataframe from the gruptree_model
|
|
44
|
-
r0_path = f"{testdata_folder}/{ENSEMBLE}/realization-0/iter-0/{GRUPTREE_FILE}"
|
|
45
|
-
exp_df = pd.read_csv(r0_path)
|
|
46
|
-
exp_df["DATE"] = pd.to_datetime(exp_df["DATE"])
|
|
47
|
-
exp_df = exp_df.where(pd.notnull(exp_df), None)
|
|
48
|
-
|
|
49
|
-
assert_frame_equal(gruptree_model.dataframe[CHECK_COLUMNS], exp_df[CHECK_COLUMNS])
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@pytest.mark.usefixtures("app")
|
|
53
|
-
def test_get_filtered_dataframe(gruptree_model: GruptreeModel):
|
|
54
|
-
# Test the get_filtered_dataframe function with terminal node different than FIELD
|
|
55
|
-
filtered_df = gruptree_model.get_filtered_dataframe(terminal_node="OP")
|
|
56
|
-
filtered_df = filtered_df[
|
|
57
|
-
filtered_df["DATE"] == filtered_df["DATE"].max()
|
|
58
|
-
].reset_index()
|
|
59
|
-
exp_filtered_df = pd.DataFrame(
|
|
60
|
-
columns=["DATE", "CHILD", "KEYWORD", "PARENT"],
|
|
61
|
-
data=[
|
|
62
|
-
[datetime.datetime(year=2018, month=11, day=17), "OP", "GRUPTREE", "FIELD"],
|
|
63
|
-
[datetime.datetime(year=2018, month=11, day=17), "A1", "WELSPECS", "OP"],
|
|
64
|
-
[datetime.datetime(year=2018, month=11, day=17), "A2", "WELSPECS", "OP"],
|
|
65
|
-
[datetime.datetime(year=2018, month=11, day=17), "A3", "WELSPECS", "OP"],
|
|
66
|
-
[datetime.datetime(year=2018, month=11, day=17), "A4", "WELSPECS", "OP"],
|
|
67
|
-
],
|
|
68
|
-
)
|
|
69
|
-
assert_frame_equal(filtered_df[CHECK_COLUMNS], exp_filtered_df)
|
|
70
|
-
|
|
71
|
-
# Test excl_wells_startswith and excl_wells_endswith
|
|
72
|
-
assert set(
|
|
73
|
-
gruptree_model.get_filtered_dataframe(
|
|
74
|
-
excl_well_startswith=["R_"],
|
|
75
|
-
excl_well_endswith=["3", "5"],
|
|
76
|
-
)["CHILD"].unique()
|
|
77
|
-
) == {"FIELD", "OP", "RFT", "WI", "A1", "A2", "A4", "A6"}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def test_tree_type_filtering():
|
|
81
|
-
mock_model = MockGruptreeModel(tree_type=TreeType.GRUPTREE)
|
|
82
|
-
assert "BRANPROP" not in mock_model.dataframe["KEYWORD"].unique()
|
|
83
|
-
|
|
84
|
-
mock_model = MockGruptreeModel(tree_type=TreeType.BRANPROP)
|
|
85
|
-
assert "GRUPTREE" not in mock_model.dataframe["KEYWORD"].unique()
|
|
86
|
-
|
|
87
|
-
# If tree_type is defaulted then the BRANPROP tree is selected
|
|
88
|
-
mock_model = MockGruptreeModel()
|
|
89
|
-
assert "GRUPTREE" not in mock_model.dataframe["KEYWORD"].unique()
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pandas as pd
|
|
4
|
-
from webviz_config.themes import default_theme
|
|
5
|
-
|
|
6
|
-
from webviz_subsurface.plugins._property_statistics.models.property_statistics_model import (
|
|
7
|
-
PropertyStatisticsModel,
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def get_data_df(testdata_folder: Path) -> pd.DataFrame:
|
|
12
|
-
return pd.read_csv(
|
|
13
|
-
testdata_folder
|
|
14
|
-
/ "reek_test_data"
|
|
15
|
-
/ "aggregated_data"
|
|
16
|
-
/ "property_statistics.csv"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def test_init(testdata_folder: Path) -> None:
|
|
21
|
-
data_df = get_data_df(testdata_folder)
|
|
22
|
-
model = PropertyStatisticsModel(dataframe=data_df, theme=default_theme)
|
|
23
|
-
assert set(model.dataframe.columns) == set(
|
|
24
|
-
[
|
|
25
|
-
"PROPERTY",
|
|
26
|
-
"ZONE",
|
|
27
|
-
"REGION",
|
|
28
|
-
"FACIES",
|
|
29
|
-
"Avg",
|
|
30
|
-
"Avg_Weighted",
|
|
31
|
-
"Max",
|
|
32
|
-
"Min",
|
|
33
|
-
"P10",
|
|
34
|
-
"P90",
|
|
35
|
-
"Stddev",
|
|
36
|
-
"SOURCE",
|
|
37
|
-
"ID",
|
|
38
|
-
"REAL",
|
|
39
|
-
"ENSEMBLE",
|
|
40
|
-
"label",
|
|
41
|
-
]
|
|
42
|
-
)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
import xtgeo
|
|
5
|
-
|
|
6
|
-
from webviz_subsurface._datainput.fmu_input import find_surfaces
|
|
7
|
-
from webviz_subsurface._models.surface_set_model import SurfaceSetModel
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@pytest.mark.usefixtures("app")
|
|
11
|
-
def test_surface_set_model(testdata_folder):
|
|
12
|
-
ensemble_paths = {
|
|
13
|
-
"iter-0": str(
|
|
14
|
-
Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-0")
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
surface_table = find_surfaces(ensemble_paths)
|
|
19
|
-
surface_table = surface_table.drop("ENSEMBLE", axis=1)
|
|
20
|
-
|
|
21
|
-
smodel = SurfaceSetModel(surface_table)
|
|
22
|
-
assert set(smodel.attributes) == set(
|
|
23
|
-
[
|
|
24
|
-
"ds_extract_postprocess",
|
|
25
|
-
"amplitude_mean",
|
|
26
|
-
"ds_extract_geogrid",
|
|
27
|
-
"amplitude_rms",
|
|
28
|
-
"oilthickness",
|
|
29
|
-
]
|
|
30
|
-
)
|
|
31
|
-
assert set(smodel.names_in_attribute("ds_extract_postprocess")) == set(
|
|
32
|
-
["basevolantis", "topvolantis", "toptherys", "topvolon"]
|
|
33
|
-
)
|
|
34
|
-
real_surf = smodel.get_realization_surface(
|
|
35
|
-
attribute="ds_extract_postprocess", name="topvolon", realization=0
|
|
36
|
-
)
|
|
37
|
-
assert isinstance(real_surf, xtgeo.RegularSurface)
|
|
38
|
-
assert real_surf.values.mean() == pytest.approx(1735.42, 0.00001)
|
|
39
|
-
stat_surf = smodel.calculate_statistical_surface(
|
|
40
|
-
attribute="ds_extract_postprocess", name="topvolon"
|
|
41
|
-
)
|
|
42
|
-
assert isinstance(stat_surf, xtgeo.RegularSurface)
|
|
43
|
-
assert stat_surf.values.mean() == pytest.approx(1741.04, 0.00001)
|
|
44
|
-
|
|
45
|
-
stat_surf = smodel.calculate_statistical_surface(
|
|
46
|
-
attribute="ds_extract_postprocess", name="topvolon", realizations=[0, 1]
|
|
47
|
-
)
|
|
48
|
-
assert stat_surf.values.mean() == pytest.approx(1741.04, 0.00001)
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import json
|
|
3
|
-
|
|
4
|
-
import numpy as np
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
from webviz_subsurface._models.well_attributes_model import WellAttributesModel
|
|
9
|
-
|
|
10
|
-
LOAD_DATA_FUNCTION = (
|
|
11
|
-
"webviz_subsurface._models.well_attributes_model.WellAttributesModel._load_data"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_simplest_possible_input(mocker):
|
|
16
|
-
mocker.patch(
|
|
17
|
-
LOAD_DATA_FUNCTION,
|
|
18
|
-
lambda self: io.BytesIO(json.dumps({"version": "0.1", "wells": []}).encode()),
|
|
19
|
-
)
|
|
20
|
-
well_attr = WellAttributesModel("ens_name", "ens_path", "file_name")
|
|
21
|
-
assert well_attr.data == {}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def test_not_implemented_version(mocker):
|
|
25
|
-
mocker.patch(
|
|
26
|
-
LOAD_DATA_FUNCTION,
|
|
27
|
-
lambda self: io.BytesIO(json.dumps({"version": "0.2", "wells": []}).encode()),
|
|
28
|
-
)
|
|
29
|
-
with pytest.raises(NotImplementedError):
|
|
30
|
-
WellAttributesModel("ens_name", "ens_path", "file_name")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_object_properties(mocker):
|
|
34
|
-
mock_data = {
|
|
35
|
-
"version": "0.1",
|
|
36
|
-
"wells": [
|
|
37
|
-
{
|
|
38
|
-
"alias": {"eclipse": "OP_1"},
|
|
39
|
-
"attributes": {
|
|
40
|
-
"attr1": "value1",
|
|
41
|
-
"attr2": "value2",
|
|
42
|
-
},
|
|
43
|
-
"name": "OP_1",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"alias": {"eclipse": "OP_2"},
|
|
47
|
-
"attributes": {
|
|
48
|
-
"attr1": "value1",
|
|
49
|
-
},
|
|
50
|
-
"name": "OP_2",
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
}
|
|
54
|
-
mocker.patch(
|
|
55
|
-
LOAD_DATA_FUNCTION,
|
|
56
|
-
lambda self: io.BytesIO(json.dumps(mock_data).encode()),
|
|
57
|
-
)
|
|
58
|
-
well_attr = WellAttributesModel("ens_name", "ens_path", "file_name")
|
|
59
|
-
|
|
60
|
-
# Test categories
|
|
61
|
-
assert set(well_attr.categories) == {"attr1", "attr2"}
|
|
62
|
-
|
|
63
|
-
# Test data
|
|
64
|
-
assert well_attr.data == {
|
|
65
|
-
"OP_1": {
|
|
66
|
-
"attr1": "value1",
|
|
67
|
-
"attr2": "value2",
|
|
68
|
-
},
|
|
69
|
-
"OP_2": {
|
|
70
|
-
"attr1": "value1",
|
|
71
|
-
},
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
# Test category_dict (This will replace nan with Undefined)
|
|
75
|
-
assert well_attr.category_dict == {
|
|
76
|
-
"attr1": ["value1"],
|
|
77
|
-
"attr2": ["value2", "Undefined"],
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
# Test dataframe
|
|
81
|
-
pd.testing.assert_frame_equal(
|
|
82
|
-
well_attr.dataframe,
|
|
83
|
-
pd.DataFrame(
|
|
84
|
-
columns=["WELL", "attr1", "attr2"],
|
|
85
|
-
data=[["OP_1", "value1", "value2"], ["OP_2", "value1", np.nan]],
|
|
86
|
-
),
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
# Test melted dataframe
|
|
90
|
-
df_melted = well_attr.dataframe_melted
|
|
91
|
-
assert df_melted.shape[0] == 4
|
|
92
|
-
assert df_melted.shape[1] == 3
|
|
93
|
-
assert set(df_melted["WELL"]) == {"OP_1", "OP_2"}
|
|
94
|
-
assert set(df_melted["CATEGORY"]) == {"attr1", "attr2"}
|
|
95
|
-
assert set(df_melted["VALUE"]) == {"value1", "value2", np.nan}
|
|
96
|
-
|
|
97
|
-
# This is the expected dataframe, but I'm not able to test it with
|
|
98
|
-
# assert_frame_equal because the row order of the melted dataframe is
|
|
99
|
-
# randomly changing.
|
|
100
|
-
#
|
|
101
|
-
# exp_df_melted = pd.DataFrame(
|
|
102
|
-
# columns=["WELL", "CATEGORY", "VALUE"],
|
|
103
|
-
# data=[
|
|
104
|
-
# ["OP_1", "attr1", "value1"],
|
|
105
|
-
# ["OP_2", "attr1", "value1"],
|
|
106
|
-
# ["OP_1", "attr2", "value2"],
|
|
107
|
-
# ["OP_2", "attr2", np.nan],
|
|
108
|
-
# ],
|
|
109
|
-
# )
|
|
110
|
-
# pd.testing.assert_frame_equal(df, exp_df, check_like=True)
|