webviz-subsurface 0.2.39__py3-none-any.whl → 0.2.41__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/_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_impl_arrow.py +3 -1
- webviz_subsurface/_utils/dataframe_utils.py +1 -1
- webviz_subsurface/_version.py +34 -0
- webviz_subsurface/plugins/_bhp_qc/views/_view_functions.py +5 -5
- webviz_subsurface/plugins/_co2_migration/__init__.py +1 -0
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_plugin.py +86 -46
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/callbacks.py +53 -30
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/co2volume.py +283 -40
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/color_tables.py +1 -1
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/containment_data_provider.py +6 -4
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/containment_info.py +6 -0
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/ensemble_well_picks.py +1 -1
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/generic.py +59 -6
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/initialization.py +73 -10
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/polygon_handler.py +1 -1
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/summary_graphs.py +20 -18
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/surface_publishing.py +18 -20
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/unsmry_data_provider.py +8 -8
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/views/mainview/mainview.py +98 -44
- webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/views/mainview/settings.py +7 -5
- 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/layout.py +2 -1
- webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py +1 -1
- webviz_subsurface/plugins/_parameter_analysis/_utils/_parameters_model.py +5 -5
- 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.41.dist-info/METADATA +822 -0
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info}/RECORD +51 -102
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info}/WHEEL +1 -1
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info}/entry_points.txt +1 -1
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info}/top_level.txt +0 -1
- tests/integration_tests/test_parameter_filter.py +0 -28
- tests/integration_tests/test_surface_selector.py +0 -53
- 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 -130
- 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/plugins/_co2_leakage/__init__.py +0 -1
- webviz_subsurface/plugins/_co2_leakage/_utilities/__init__.py +0 -0
- webviz_subsurface/plugins/_co2_leakage/views/__init__.py +0 -0
- webviz_subsurface/plugins/_co2_leakage/views/mainview/__init__.py +0 -0
- webviz_subsurface-0.2.39.dist-info/METADATA +0 -147
- /webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_error.py +0 -0
- /webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_types.py +0 -0
- {tests/integration_tests → webviz_subsurface/plugins/_co2_migration/_utilities}/__init__.py +0 -0
- /webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/_misc.py +0 -0
- /webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/fault_polygons_handler.py +0 -0
- /webviz_subsurface/plugins/{_co2_leakage → _co2_migration}/_utilities/plume_extent.py +0 -0
- {tests/unit_tests → webviz_subsurface/plugins/_co2_migration/views}/__init__.py +0 -0
- {tests/unit_tests/abbreviations_tests → webviz_subsurface/plugins/_co2_migration/views/mainview}/__init__.py +0 -0
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info/licenses}/LICENSE +0 -0
- {webviz_subsurface-0.2.39.dist-info → webviz_subsurface-0.2.41.dist-info/licenses}/LICENSE.chromedriver +0 -0
|
@@ -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)
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
import pytest
|
|
5
|
-
import xtgeo
|
|
6
|
-
|
|
7
|
-
from webviz_subsurface._models import WellSetModel
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@pytest.mark.usefixtures("app")
|
|
11
|
-
def test_well_set_model(testdata_folder: Path) -> None:
|
|
12
|
-
wellfiles = [
|
|
13
|
-
testdata_folder / "reek_test_data" / "observed_data" / "wells" / well
|
|
14
|
-
for well in ["OP_1.w", "OP_2.w", "OP_3.w", "OP_4.w", "OP_5.w", "OP_6.w"]
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
wmodel = WellSetModel(wellfiles=wellfiles)
|
|
18
|
-
assert set(wmodel.well_names) == set(
|
|
19
|
-
["OP_1", "OP_2", "OP_3", "OP_4", "OP_5", "OP_6"]
|
|
20
|
-
)
|
|
21
|
-
for name, well in wmodel.wells.items():
|
|
22
|
-
assert isinstance(name, str)
|
|
23
|
-
assert isinstance(well, xtgeo.Well)
|
|
24
|
-
op_6 = wmodel.get_well("OP_6")
|
|
25
|
-
assert isinstance(op_6, xtgeo.Well)
|
|
26
|
-
assert op_6.name == "OP_6"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@pytest.mark.usefixtures("app")
|
|
30
|
-
def test_logs(testdata_folder: Path) -> None:
|
|
31
|
-
wmodel = WellSetModel(
|
|
32
|
-
wellfiles=[
|
|
33
|
-
testdata_folder / "reek_test_data" / "observed_data" / "wells" / "OP_6.w"
|
|
34
|
-
],
|
|
35
|
-
zonelog="Zonelog",
|
|
36
|
-
)
|
|
37
|
-
well = wmodel.get_well("OP_6")
|
|
38
|
-
assert well.zonelogname == "Zonelog"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.mark.usefixtures("app")
|
|
42
|
-
def test_tvd_truncation(testdata_folder: Path) -> None:
|
|
43
|
-
wmodel = WellSetModel(
|
|
44
|
-
wellfiles=[
|
|
45
|
-
testdata_folder / "reek_test_data" / "observed_data" / "wells" / "OP_6.w"
|
|
46
|
-
],
|
|
47
|
-
tvdmin=1000,
|
|
48
|
-
tvdmax=1500,
|
|
49
|
-
)
|
|
50
|
-
well = wmodel.get_well("OP_6")
|
|
51
|
-
assert well.dataframe["Z_TVDSS"].min() >= 1000
|
|
52
|
-
assert well.dataframe["Z_TVDSS"].max() <= 1501
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@pytest.mark.usefixtures("app")
|
|
56
|
-
def test_get_fence(testdata_folder: Path) -> None:
|
|
57
|
-
wmodel = WellSetModel(
|
|
58
|
-
wellfiles=[
|
|
59
|
-
testdata_folder / "reek_test_data" / "observed_data" / "wells" / "OP_6.w"
|
|
60
|
-
],
|
|
61
|
-
zonelog="Zonelog",
|
|
62
|
-
)
|
|
63
|
-
fence = wmodel.get_fence("OP_6")
|
|
64
|
-
assert isinstance(fence, np.ndarray)
|
|
65
|
-
# Test horizontal length
|
|
66
|
-
assert int(fence[:, 3].min()) == -40
|
|
67
|
-
assert int(fence[:, 3].max()) == 2713
|
|
68
|
-
# Test tvd
|
|
69
|
-
assert int(fence[:, 2].min()) == 0
|
|
70
|
-
assert int(fence[:, 2].max()) == 1643
|
|
File without changes
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import List, Tuple
|
|
4
|
-
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import pytest
|
|
7
|
-
from _pytest.fixtures import SubRequest
|
|
8
|
-
|
|
9
|
-
from webviz_subsurface._providers import EnsembleSummaryProvider
|
|
10
|
-
from webviz_subsurface._providers.ensemble_summary_provider._provider_impl_arrow_presampled import (
|
|
11
|
-
ProviderImplArrowPresampled,
|
|
12
|
-
)
|
|
13
|
-
from webviz_subsurface.plugins._group_tree._utils._ensemble_group_tree_data import (
|
|
14
|
-
add_nodetype,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
ADD_NODETYPE_CASES = [
|
|
18
|
-
# Group leaf nodes:
|
|
19
|
-
# NODE1 has summary data>0 and will be classified as prod and inj
|
|
20
|
-
# NODE2 has summary data==0 and will be classified as other
|
|
21
|
-
# NODE3 has no summary data and will be classified as other
|
|
22
|
-
# FIELD and TMPL are classified as all three types
|
|
23
|
-
(
|
|
24
|
-
pd.DataFrame(
|
|
25
|
-
columns=["DATE", "CHILD", "KEYWORD", "PARENT"],
|
|
26
|
-
data=[
|
|
27
|
-
["2000-01-01", "FIELD", "GRUPTREE", None],
|
|
28
|
-
["2000-01-01", "TMPL", "GRUPTREE", "FIELD"],
|
|
29
|
-
["2000-01-01", "NODE1", "GRUPTREE", "TMPL"],
|
|
30
|
-
["2000-01-01", "NODE2", "GRUPTREE", "TMPL"],
|
|
31
|
-
["2000-01-01", "NODE3", "GRUPTREE", "TMPL"],
|
|
32
|
-
],
|
|
33
|
-
),
|
|
34
|
-
pd.DataFrame(
|
|
35
|
-
columns=[
|
|
36
|
-
"DATE",
|
|
37
|
-
"REAL",
|
|
38
|
-
"GGPR:NODE1",
|
|
39
|
-
"GGIR:NODE1",
|
|
40
|
-
"GGPR:NODE2",
|
|
41
|
-
"GGIR:NODE2",
|
|
42
|
-
],
|
|
43
|
-
data=[
|
|
44
|
-
[datetime.date(2000, 1, 1), 0, 1, 1, 0, 0],
|
|
45
|
-
],
|
|
46
|
-
),
|
|
47
|
-
pd.DataFrame(
|
|
48
|
-
columns=[
|
|
49
|
-
"DATE",
|
|
50
|
-
"CHILD",
|
|
51
|
-
"KEYWORD",
|
|
52
|
-
"PARENT",
|
|
53
|
-
"IS_PROD",
|
|
54
|
-
"IS_INJ",
|
|
55
|
-
"IS_OTHER",
|
|
56
|
-
],
|
|
57
|
-
data=[
|
|
58
|
-
["2000-01-01", "FIELD", "GRUPTREE", None, True, True, True],
|
|
59
|
-
["2000-01-01", "TMPL", "GRUPTREE", "FIELD", True, True, True],
|
|
60
|
-
["2000-01-01", "NODE1", "GRUPTREE", "TMPL", True, True, False],
|
|
61
|
-
["2000-01-01", "NODE2", "GRUPTREE", "TMPL", False, False, True],
|
|
62
|
-
["2000-01-01", "NODE3", "GRUPTREE", "TMPL", False, False, True],
|
|
63
|
-
],
|
|
64
|
-
),
|
|
65
|
-
),
|
|
66
|
-
# Well leaf nodes:
|
|
67
|
-
# WELL1 has WSTAT==1 and will be classified as producer
|
|
68
|
-
# WELL2 has WSTAT==2 and will be classified as injector
|
|
69
|
-
# WELL3 has first WSTAT==1 and then WSTAT==2 and will be classified as both
|
|
70
|
-
# WELL4 has WSTAT==0 and will be classified as other
|
|
71
|
-
# TMPL_A is classified as prod and inj
|
|
72
|
-
# TMPL_B is classified as other
|
|
73
|
-
(
|
|
74
|
-
pd.DataFrame(
|
|
75
|
-
columns=["DATE", "CHILD", "KEYWORD", "PARENT"],
|
|
76
|
-
data=[
|
|
77
|
-
["2000-01-01", "FIELD", "GRUPTREE", None],
|
|
78
|
-
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD"],
|
|
79
|
-
["2000-01-01", "TMPL_B", "GRUPTREE", "FIELD"],
|
|
80
|
-
["2000-01-01", "WELL1", "WELSPECS", "TMPL_A"],
|
|
81
|
-
["2000-01-01", "WELL2", "WELSPECS", "TMPL_A"],
|
|
82
|
-
["2000-01-01", "WELL3", "WELSPECS", "TMPL_A"],
|
|
83
|
-
["2000-01-01", "WELL4", "WELSPECS", "TMPL_B"],
|
|
84
|
-
],
|
|
85
|
-
),
|
|
86
|
-
pd.DataFrame(
|
|
87
|
-
columns=[
|
|
88
|
-
"DATE",
|
|
89
|
-
"REAL",
|
|
90
|
-
"WSTAT:WELL1",
|
|
91
|
-
"WSTAT:WELL2",
|
|
92
|
-
"WSTAT:WELL3",
|
|
93
|
-
"WSTAT:WELL4",
|
|
94
|
-
],
|
|
95
|
-
data=[
|
|
96
|
-
[datetime.date(2000, 1, 1), 0, 1, 2, 1, 0],
|
|
97
|
-
[datetime.date(2000, 2, 1), 0, 1, 2, 2, 0],
|
|
98
|
-
],
|
|
99
|
-
),
|
|
100
|
-
pd.DataFrame(
|
|
101
|
-
columns=[
|
|
102
|
-
"DATE",
|
|
103
|
-
"CHILD",
|
|
104
|
-
"KEYWORD",
|
|
105
|
-
"PARENT",
|
|
106
|
-
"IS_PROD",
|
|
107
|
-
"IS_INJ",
|
|
108
|
-
"IS_OTHER",
|
|
109
|
-
],
|
|
110
|
-
data=[
|
|
111
|
-
["2000-01-01", "FIELD", "GRUPTREE", None, True, True, True],
|
|
112
|
-
["2000-01-01", "TMPL_A", "GRUPTREE", "FIELD", True, True, False],
|
|
113
|
-
["2000-01-01", "TMPL_B", "GRUPTREE", "FIELD", False, False, True],
|
|
114
|
-
["2000-01-01", "WELL1", "WELSPECS", "TMPL_A", True, False, False],
|
|
115
|
-
["2000-01-01", "WELL2", "WELSPECS", "TMPL_A", False, True, False],
|
|
116
|
-
["2000-01-01", "WELL3", "WELSPECS", "TMPL_A", True, True, False],
|
|
117
|
-
["2000-01-01", "WELL4", "WELSPECS", "TMPL_B", False, False, True],
|
|
118
|
-
],
|
|
119
|
-
),
|
|
120
|
-
),
|
|
121
|
-
]
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
@pytest.fixture(
|
|
125
|
-
name="testdata",
|
|
126
|
-
params=ADD_NODETYPE_CASES,
|
|
127
|
-
)
|
|
128
|
-
def fixture_provider(
|
|
129
|
-
request: SubRequest, tmp_path: Path
|
|
130
|
-
) -> Tuple[pd.DataFrame, EnsembleSummaryProvider, pd.DataFrame]:
|
|
131
|
-
input_py = request.param
|
|
132
|
-
storage_dir = tmp_path
|
|
133
|
-
gruptree_df = input_py[0]
|
|
134
|
-
smry_df = input_py[1]
|
|
135
|
-
expected_df = input_py[2]
|
|
136
|
-
|
|
137
|
-
ProviderImplArrowPresampled.write_backing_store_from_ensemble_dataframe(
|
|
138
|
-
storage_dir, "dummy_key", smry_df
|
|
139
|
-
)
|
|
140
|
-
new_provider = ProviderImplArrowPresampled.from_backing_store(
|
|
141
|
-
storage_dir, "dummy_key"
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
if not new_provider:
|
|
145
|
-
raise ValueError("Failed to create EnsembleSummaryProvider")
|
|
146
|
-
|
|
147
|
-
return gruptree_df, new_provider, expected_df
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def test_add_nodetype(
|
|
151
|
-
testdata: Tuple[pd.DataFrame, EnsembleSummaryProvider, pd.DataFrame]
|
|
152
|
-
) -> None:
|
|
153
|
-
"""Test functionality for the add_nodetype function"""
|
|
154
|
-
gruptree_df = testdata[0]
|
|
155
|
-
provider = testdata[1]
|
|
156
|
-
expected_df = testdata[2]
|
|
157
|
-
|
|
158
|
-
columns_to_check = [
|
|
159
|
-
"DATE",
|
|
160
|
-
"CHILD",
|
|
161
|
-
"KEYWORD",
|
|
162
|
-
"PARENT",
|
|
163
|
-
"IS_PROD",
|
|
164
|
-
"IS_INJ",
|
|
165
|
-
"IS_OTHER",
|
|
166
|
-
]
|
|
167
|
-
|
|
168
|
-
wells: List[str] = gruptree_df[gruptree_df["KEYWORD"] == "WELSPECS"][
|
|
169
|
-
"CHILD"
|
|
170
|
-
].unique()
|
|
171
|
-
|
|
172
|
-
output = add_nodetype(gruptree_df, provider, wells, "FIELD")
|
|
173
|
-
pd.testing.assert_frame_equal(
|
|
174
|
-
output[columns_to_check], expected_df[columns_to_check]
|
|
175
|
-
)
|
|
File without changes
|
|
File without changes
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
from typing import List, Optional, Sequence
|
|
2
|
-
|
|
3
|
-
import pandas as pd
|
|
4
|
-
|
|
5
|
-
from webviz_subsurface._providers import Frequency
|
|
6
|
-
|
|
7
|
-
from ....mocks.ensemble_summary_provider_dummy import EnsembleSummaryProviderDummy
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class EnsembleSummaryProviderMock(EnsembleSummaryProviderDummy):
|
|
11
|
-
"""Mock implementation of EnsembleSummaryProvider for testing derived
|
|
12
|
-
ensemble vectors accessor.
|
|
13
|
-
|
|
14
|
-
Implements necessary methods for obtaining wanted test data
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
def __init__(self, df: pd.DataFrame) -> None:
|
|
18
|
-
super().__init__()
|
|
19
|
-
self._df = df
|
|
20
|
-
self._vectors: List[str] = [
|
|
21
|
-
elm for elm in df.columns if elm not in ["DATE", "REAL"]
|
|
22
|
-
]
|
|
23
|
-
self._realizations: List[int] = list(df["REAL"]) if "REAL" in df.columns else []
|
|
24
|
-
|
|
25
|
-
#####################################
|
|
26
|
-
#
|
|
27
|
-
# Override methods
|
|
28
|
-
#
|
|
29
|
-
#####################################
|
|
30
|
-
def supports_resampling(self) -> bool:
|
|
31
|
-
return False
|
|
32
|
-
|
|
33
|
-
def realizations(self) -> List[int]:
|
|
34
|
-
return self._realizations
|
|
35
|
-
|
|
36
|
-
def vector_names(self) -> List[str]:
|
|
37
|
-
return self._vectors
|
|
38
|
-
|
|
39
|
-
def get_vectors_df(
|
|
40
|
-
self,
|
|
41
|
-
vector_names: Sequence[str],
|
|
42
|
-
__resampling_frequency: Optional[Frequency],
|
|
43
|
-
realizations: Optional[Sequence[int]] = None,
|
|
44
|
-
) -> pd.DataFrame:
|
|
45
|
-
for elm in vector_names:
|
|
46
|
-
if elm not in self._vectors:
|
|
47
|
-
raise ValueError(
|
|
48
|
-
f'Requested vector "{elm}" not among provider vectors!'
|
|
49
|
-
)
|
|
50
|
-
if realizations:
|
|
51
|
-
# Note: Reset index as providers reset index counter when filtering
|
|
52
|
-
# realization query.
|
|
53
|
-
output = (
|
|
54
|
-
self._df[["DATE", "REAL"] + list(vector_names)]
|
|
55
|
-
.loc[self._df["REAL"].isin(realizations)]
|
|
56
|
-
.reset_index()
|
|
57
|
-
)
|
|
58
|
-
output.drop("index", inplace=True, axis=1)
|
|
59
|
-
return output
|
|
60
|
-
return self._df[["DATE", "REAL"] + list(vector_names)]
|
|
File without changes
|