#14571 Orion Events: Preserve post-processed events during merge

This commit is contained in:
Kristian Bendiksen
2026-08-24 13:26:19 +02:00
parent 64317dfad7
commit 41b7df5a20
2 changed files with 43 additions and 8 deletions
+21 -8
View File
@@ -1238,13 +1238,25 @@ def apply_orion_events_file(
return apply_orion_document(document, timeline, project, case=case, **options)
def coalesce_orion_document(document: OrionDocument) -> OrionDocument:
"""Return a copy with same-owner/type/timestamp events merged.
_NON_COALESCING_EVENT_TYPES = {
"MEMBER",
"PERFORATION",
"RAW_TEXT",
"RESTART",
"SEGMENT",
"STATE",
"VALVE",
"WELSPECS",
}
The first event retains its position. Attributes from later matching events
are applied in source order, adding missing values and overriding repeated
values. Owners are matched by well name, group name, or the global SCHEDULE
scope.
def coalesce_orion_document(document: OrionDocument) -> OrionDocument:
"""Return a copy with matching keyword events merged.
Keyword events with the same owner, type and timestamp are merged. The first
event retains its position, and attributes from later matching events are
applied in source order. Events that create or expand domain objects are
kept separate so, for example, same-date perforation intervals are not lost.
"""
result = copy.deepcopy(document)
@@ -1254,11 +1266,12 @@ def coalesce_orion_document(document: OrionDocument) -> OrionDocument:
Tuple[Union[datetime.date, datetime.datetime], str], OrionEvent
] = {}
for event in events:
if event.event_type.upper() == "RAW_TEXT":
event_type = event.event_type.upper()
if event_type in _NON_COALESCING_EVENT_TYPES:
merged.append(event)
continue
key = (event.event_date, event.event_type.upper())
key = (event.event_date, event_type)
existing = by_key.get(key)
if existing is None:
by_key[key] = event
@@ -974,6 +974,28 @@ class TestApplying:
assert timeline.keyword_calls[0]["keyword_data"]["ORAT"] == 100
assert timeline.keyword_calls[0]["keyword_data"]["CMODE"] == "ORAT"
def test_same_date_perforations_are_not_merged(self):
text = (
"ORIONEVENTS 2.0\n"
'WELL "55_33-A-1"\n'
" @2018-01-01 PERFORATION MDSTART=1000 MDEND=1100 COMPLETION_NUMBER=1\n"
" @2018-01-01 PERFORATION MDSTART=1200 MDEND=1300 COMPLETION_NUMBER=2\n"
)
document = parse_orion_events(text)
merged = coalesce_orion_document(document)
assert len(merged.wells[0].events) == 2
timeline, report = self._apply(text)
assert report.events_applied == 2
assert report.events_skipped == 0
assert [(call["start_md"], call["end_md"]) for call in timeline.perf_calls] == [
(1000.0, 1100.0),
(1200.0, 1300.0),
]
assert [call["completion_number"] for call in timeline.perf_calls] == [1, 2]
def test_group_and_schedule_events_merge_only_within_owner(self):
text = (
"ORIONEVENTS 2.0\n"