Skip to content

Commit d451553

Browse files
committed
Fix warning about missing response bug
The bug was that wildcards were not handled correctly. Only complete wildcards were handled in the original implementation. This bugfix contains utilization of fntools to match wildcards in substrings to avoid manual implementation to try to cope with this. Also, the assertion strategy was changed in some rft tests to be more similar to other tests. (cherry picked from commit 0f9dcba)
1 parent 0e1e498 commit d451553

4 files changed

Lines changed: 170 additions & 30 deletions

File tree

src/ert/config/rft_config.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import os
77
import re
88
from collections import defaultdict
9-
from copy import copy
109
from dataclasses import InitVar, dataclass
1110
from functools import lru_cache
1211
from pathlib import Path
@@ -296,26 +295,17 @@ def _warn_about_missing_rft_responses(
296295
for well, time_dict in self.data_to_read.items()
297296
for time in time_dict
298297
}
299-
well_times_with_response = {(well, time.isoformat()) for well, time in rft_data}
300-
301-
well_times_to_warn: set[tuple[str, str]] = well_times - well_times_with_response
302-
303-
# Given well / time wildcard, only warn if there are no responses for
304-
# the corresponding well / time value
305-
wells_with_responses = {well for well, time in well_times_with_response}
306-
times_with_responses = {time for well, time in well_times_with_response}
307-
for well, time in copy(well_times_to_warn):
308-
if well == "*" and time in times_with_responses:
309-
well_times_to_warn.remove((well, time))
310-
if time == "*" and well in wells_with_responses:
311-
well_times_to_warn.remove((well, time))
312-
313-
# Only warn about wildcard well and time if there are no responses
314-
if (wildcard_well_time := ("*", "*")) in well_times and len(
315-
well_times_with_response
316-
) > 0:
317-
well_times_to_warn.remove(wildcard_well_time)
318-
298+
well_times_with_response = {
299+
f"{well}:{time.isoformat()}" for well, time in rft_data
300+
}
301+
well_times_to_warn: set[tuple[str, str]] = {
302+
(well, time)
303+
for well, time in well_times
304+
if not fnmatch.filter(
305+
well_times_with_response,
306+
f"{well}:{time}",
307+
)
308+
}
319309
formatted_items = [
320310
f"{well=} : {time=}" for well, time in sorted(well_times_to_warn)
321311
]

src/ert/config/summary_config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import fnmatch
34
import logging
45
from typing import Any, Literal
56

@@ -34,7 +35,9 @@ def dedupe_and_sort_keys(cls, keys: list[str]) -> list[str]:
3435
def _warn_about_missing_summary_responses(
3536
self, response_keys: list[str], filename: str
3637
) -> None:
37-
keys_missing_responses = sorted(set(self.keys) - set(response_keys) - {"*"})
38+
keys_missing_responses = [
39+
key for key in self.keys if not fnmatch.filter(response_keys, key)
40+
]
3841
_warn_about_missing_responses(keys_missing_responses, "key(s)", filename)
3942

4043
def read_from_file(self, run_path: str, iens: int, iter_: int) -> pl.DataFrame:

tests/ert/unit_tests/config/test_rft_config.py

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,17 +1526,88 @@ def test_that_wildcard_well_with_wildcard_time_without_any_response_is_warned_ab
15261526
assert any(all(e_w in str(w) for e_w in expected_warnings) for w in warnings)
15271527

15281528

1529-
def test_that_wildcard_well_with_wildcard_time_with_any_response_is_not_warned_about(
1530-
setup_mock_resfo_file,
1531-
):
1529+
def _collect_rft_response_warnings(
1530+
well: str, time: str
1531+
) -> list[warnings.WarningMessage]:
15321532
rft_config = RFTConfig(
15331533
input_files=["BASE.RFT"],
15341534
data_to_read={
1535-
"*": {"*": ["PRESSURE", "SWAT"]},
1535+
well: {time: ["PRESSURE", "SWAT"]},
15361536
},
15371537
)
1538-
with warnings.catch_warnings():
1539-
warnings.simplefilter( # Asserts no PostExperimentWarnings were raised
1540-
"error", PostExperimentWarning
1541-
)
1538+
with warnings.catch_warnings(record=True) as w:
15421539
rft_config.read_from_file("/tmp/does_not_exist", 1, 1)
1540+
1541+
return w
1542+
1543+
1544+
def test_that_wildcard_well_with_wildcard_time_with_any_response_is_not_warned_about(
1545+
setup_mock_resfo_file,
1546+
):
1547+
warnings = _collect_rft_response_warnings(well="*", time="*")
1548+
1549+
no_warnings = len(warnings) == 0
1550+
assert no_warnings
1551+
1552+
1553+
def test_that_partly_wildcard_well_name_with_response_does_not_warn(
1554+
setup_mock_resfo_file,
1555+
):
1556+
warnings = _collect_rft_response_warnings(well="WE*", time="*")
1557+
1558+
no_warnings = len(warnings) == 0
1559+
assert no_warnings
1560+
1561+
1562+
def test_that_partly_wildcard_times_with_response_does_not_warn(
1563+
setup_mock_resfo_file,
1564+
):
1565+
warnings = _collect_rft_response_warnings(well="*", time="2000*")
1566+
1567+
no_warnings = len(warnings) == 0
1568+
assert no_warnings
1569+
1570+
1571+
def test_that_well_with_multiple_wildcard_with_response_does_not_warn(
1572+
setup_mock_resfo_file,
1573+
):
1574+
warnings = _collect_rft_response_warnings(well="W*L*", time="*")
1575+
1576+
no_warnings = len(warnings) == 0
1577+
assert no_warnings
1578+
1579+
1580+
def test_that_well_and_time_with_multiple_wildcard_with_response_does_not_warn(
1581+
setup_mock_resfo_file,
1582+
):
1583+
warnings = _collect_rft_response_warnings(well="W*L*", time="2*00*01")
1584+
1585+
no_warnings = len(warnings) == 0
1586+
assert no_warnings
1587+
1588+
1589+
def test_that_time_with_partial_wildcard_without_response_at_time_does_warn(
1590+
setup_mock_resfo_file,
1591+
):
1592+
warnings = _collect_rft_response_warnings(well="WELL", time="1999*")
1593+
1594+
does_warn = len(warnings) > 0
1595+
assert does_warn
1596+
1597+
1598+
def test_that_well_with_partial_wildcard_without_response_does_warn(
1599+
setup_mock_resfo_file,
1600+
):
1601+
warnings = _collect_rft_response_warnings(well="NOT_A_W*", time="*")
1602+
1603+
does_warn = len(warnings) > 0
1604+
assert does_warn
1605+
1606+
1607+
def test_that_well_and_time_with_partial_wildcard_without_response_does_warn(
1608+
setup_mock_resfo_file,
1609+
):
1610+
warnings = _collect_rft_response_warnings(well="NOT_A_W*", time="1999*")
1611+
1612+
does_warn = len(warnings) > 0
1613+
assert does_warn

tests/ert/unit_tests/config/test_summary_config.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import re
2+
import warnings
23
from contextlib import suppress
34
from datetime import datetime
45
from pathlib import Path
@@ -269,3 +270,78 @@ def mock_read_summary(*args):
269270
WWCT:OP1"""
270271
)
271272
assert warning == expected_warning
273+
274+
275+
def _collect_summary_response_warnings(
276+
response_key: str, simulated_response_key: str
277+
) -> list[warnings.WarningMessage]:
278+
summary_config = SummaryConfig(keys=[response_key])
279+
with warnings.catch_warnings(record=True) as w:
280+
summary_config._warn_about_missing_summary_responses(
281+
response_keys=[simulated_response_key], filename="foo"
282+
)
283+
return w
284+
285+
286+
def test_that_key_with_wildcard_with_response_is_not_warned_about():
287+
w = _collect_summary_response_warnings(
288+
response_key="WGOR*", simulated_response_key="WGOR:OP1"
289+
)
290+
291+
no_warnings = len(w) == 0
292+
assert no_warnings
293+
294+
295+
def test_that_key_with_multiple_wildcards_with_responses_is_not_warned_about():
296+
w = _collect_summary_response_warnings(
297+
response_key="W*:OP*", simulated_response_key="WGOR:OP1"
298+
)
299+
300+
no_warnings = len(w) == 0
301+
assert no_warnings
302+
303+
304+
def test_that_identical_key_containing_wildcard_with_response_is_not_warned_about():
305+
w = _collect_summary_response_warnings(
306+
response_key="W*OPR:OP1", simulated_response_key="WOPR:OP1"
307+
)
308+
309+
no_warnings = len(w) == 0
310+
assert no_warnings
311+
312+
313+
def test_that_key_with_partial_wildcard_without_response_is_warned_about():
314+
w = _collect_summary_response_warnings(
315+
response_key="F*", simulated_response_key="WOPR:OP1"
316+
)
317+
318+
did_warn = len(w) > 0
319+
assert did_warn
320+
321+
322+
def test_that_keys_with_preceding_wildcard_without_responses_is_not_warned_about():
323+
w = _collect_summary_response_warnings(
324+
response_key="*OP1", simulated_response_key="WOPR:OP1"
325+
)
326+
327+
no_warnings = len(w) == 0
328+
assert no_warnings
329+
330+
331+
def test_that_key_with_multiple_wildcards_without_response_is_warned_about():
332+
w = _collect_summary_response_warnings(
333+
response_key="W*OR:OP*", simulated_response_key="WOPR:OP1"
334+
)
335+
336+
did_warn = len(w) > 0
337+
assert did_warn
338+
339+
340+
def test_that_wildcard_key_without_response_is_warned_about():
341+
summary_config = SummaryConfig(keys=["*"])
342+
with warnings.catch_warnings(record=True) as w:
343+
summary_config._warn_about_missing_summary_responses(
344+
response_keys=[], filename="foo"
345+
)
346+
did_warn = len(w) > 0
347+
assert did_warn

0 commit comments

Comments
 (0)