mirror of
https://github.com/OPM/ResInsight.git
synced 2026-09-03 20:53:13 -05:00
#14571 Orion Events: Expand Python usage examples
This commit is contained in:
@@ -5,10 +5,12 @@ Example: import an ORIONEVENTS well-event-timeline file into ResInsight.
|
||||
|
||||
This example shows how to:
|
||||
1. Parse an ORIONEVENTS text file into a structured document
|
||||
2. Apply its events to the well event timeline (perforations, WCONHIST, WELTARG),
|
||||
2. Normalize matching keyword events while retaining same-date perforations
|
||||
3. Apply its events to the well event timeline (perforations, WCONHIST, WELTARG),
|
||||
materializing FILTER declarations as case-level combined data filters
|
||||
attached to the perforations
|
||||
3. Generate Eclipse schedule text from the resulting timeline
|
||||
4. Insert multiline RAW_TEXT at a selected position in the generated schedule
|
||||
5. Generate Eclipse schedule text from the resulting timeline
|
||||
|
||||
The ORIONEVENTS format is a compact, human-authored description of dated well
|
||||
events. See rips/orion_events.py for the grammar. A sample input file ships at
|
||||
@@ -46,6 +48,36 @@ def main():
|
||||
f" Variables: { {k: f'{v.kind} {v.value}' for k, v in document.variables.items()} }"
|
||||
)
|
||||
|
||||
# Normalization merges matching keyword events, but events that create or
|
||||
# expand domain objects remain separate. The sample has three perforations
|
||||
# at A1_STARTUP; all three are retained.
|
||||
normalized = rips.orion_events.coalesce_orion_document(document)
|
||||
source_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
for well in document.wells
|
||||
for event in well.events
|
||||
)
|
||||
normalized_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
for well in normalized.wells
|
||||
for event in well.events
|
||||
)
|
||||
print(
|
||||
" Perforations retained during normalization: "
|
||||
f"{source_perforation_count} -> {normalized_perforation_count}"
|
||||
)
|
||||
|
||||
# RAW_TEXT bodies bypass keyword parsing and formatting. Placement and an
|
||||
# optional anchor control where each block appears in the generated schedule.
|
||||
raw_text_events = [
|
||||
event for event in document.schedule_events if event.event_type == "RAW_TEXT"
|
||||
]
|
||||
for event in raw_text_events:
|
||||
print(
|
||||
f" RAW_TEXT: {event.raw_placement} {event.raw_anchor or ''} "
|
||||
f"(priority {event.raw_priority})"
|
||||
)
|
||||
|
||||
# The sample file uses FILTER declarations, so a case is needed to resolve
|
||||
# the referenced result names and to own the created combined filters.
|
||||
cases = project.cases()
|
||||
|
||||
@@ -17,15 +17,16 @@ It demonstrates the full event coverage of the format:
|
||||
materialized as a case-level combined data filter
|
||||
4. COMMENT attributes preserved on timeline events and emitted before their
|
||||
generated schedule keywords
|
||||
5. Same-owner/type/date WCONHIST lines merged into one event, with later
|
||||
attributes extending or overriding earlier attributes
|
||||
5. Same-owner/type/date WCONHIST lines merged into one event, while same-date
|
||||
perforations remain separate
|
||||
6. Well keyword events: WCONHIST and WELTARG (with attribute translation) and
|
||||
WRFTPLT (generic Eclipse well keyword pass-through)
|
||||
7. A GROUP-level MEMBER event expanded to one GRUPTREE record per member
|
||||
8. SCHEDULE-level keyword events not tied to a well: RPTRST, GRUPTREE, TUNING
|
||||
9. REPORT dates, passed to generate_schedule_text(additional_dates=...) so
|
||||
9. Multiline RAW_TEXT inserted at a chosen position without parsing its contents
|
||||
10. REPORT dates, passed to generate_schedule_text(additional_dates=...) so
|
||||
they appear as bare DATES keywords (summary-report triggers)
|
||||
10. Schedule metadata, COMPORD generation and aligned-column output
|
||||
11. Schedule metadata, COMPORD generation and aligned-column output
|
||||
|
||||
The ORIONEVENTS text is built inline with the name of the first well path in
|
||||
the project (like well_event_schedule.py, which uses wells[0]), so the example
|
||||
@@ -67,9 +68,10 @@ WELL W1
|
||||
# COMMENT is stored on the event and safely emitted as a schedule comment.
|
||||
@STARTUP SEGMENT MDSTART=0 MDEND=2500 INNER_DIAMETER=0.15 ROUGHNESS=1.0e-5 PRESSURE_COMPONENTS=HFA COMMENT="Install production segment"
|
||||
|
||||
# Perforations; COMPLETION_NUMBER groups connections for COMPLUMP.{filter_comment}
|
||||
# Perforations; COMPLETION_NUMBER groups connections for COMPLUMP. Same-date
|
||||
# perforations are kept as separate events during normalization.{filter_comment}
|
||||
@STARTUP + RAMP PERFORATION MDSTART=2000 MDEND=2200 RADIUS=0.05 SKIN=0.5 COMPLETION_NUMBER=1{filter_ref} COMMENT="Open high-priority interval"
|
||||
@2024-04-01 PERFORATION MDSTART=2400 MDEND=2600 RADIUS=0.05 SKIN=0.3 COMPLETION_NUMBER=2
|
||||
@STARTUP + RAMP PERFORATION MDSTART=2400 MDEND=2600 RADIUS=0.05 SKIN=0.3 COMPLETION_NUMBER=2
|
||||
|
||||
# Time-of-day is preserved and emitted as the TIME field of DATES
|
||||
@2024-05-15T14:45:30.500 PERFORATION MDSTART=2300 MDEND=2350 RADIUS=0.05 SKIN=0.4 COMPLETION_NUMBER=3
|
||||
@@ -97,6 +99,15 @@ SCHEDULE
|
||||
@STARTUP GRUPTREE CHILD_GROUP=OP PARENT_GROUP=FIELD
|
||||
@STARTUP TUNING TSINIT=1 TSMAXZ=30 TMAXWC=1 NEWTMX=12 NEWTMN=1 LITMAX=50 LITMIN=1 MXWSIT=50 MXWPIT=50
|
||||
|
||||
# RAW_TEXT preserves its body verbatim. This block is emitted after RPTRST;
|
||||
# PRIORITY orders multiple raw blocks sharing the same placement and anchor.
|
||||
@STARTUP RAW_TEXT PLACEMENT=AFTER_KEYWORD ANCHOR=RPTRST PRIORITY=10
|
||||
-- Custom schedule text not modeled by the timeline API
|
||||
WTRACER
|
||||
'{well_name}' 'ORION_TRACER' 1.0 /
|
||||
/
|
||||
END_RAW_TEXT
|
||||
|
||||
# Report dates: emitted as bare DATES keywords so Eclipse/Flow writes a
|
||||
# summary report at these dates even though no events fall on them.
|
||||
REPORT 2024-07-01
|
||||
@@ -131,10 +142,24 @@ def main():
|
||||
document = rips.orion_events.parse_orion_events(orion_text)
|
||||
print(f" Wells: {[w.well_name for w in document.wells]}")
|
||||
source_well_event_count = sum(len(w.events) for w in document.wells)
|
||||
source_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
for well in document.wells
|
||||
for event in well.events
|
||||
)
|
||||
normalized = rips.orion_events.coalesce_orion_document(document)
|
||||
merged_well_event_count = sum(len(w.events) for w in normalized.wells)
|
||||
merged_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
for well in normalized.wells
|
||||
for event in well.events
|
||||
)
|
||||
print(f" Source well-event lines: {source_well_event_count}")
|
||||
print(f" Events after same-date merge: {merged_well_event_count}")
|
||||
print(
|
||||
" Perforations retained during merge: "
|
||||
f"{source_perforation_count} -> {merged_perforation_count}"
|
||||
)
|
||||
print(f" Groups: {[group.group_name for group in document.groups]}")
|
||||
print(f" Schedule events: {len(document.schedule_events)}")
|
||||
|
||||
@@ -207,6 +232,7 @@ def main():
|
||||
"RPTRST",
|
||||
"GRUPTREE",
|
||||
"TUNING",
|
||||
"WTRACER",
|
||||
]
|
||||
found = [kw for kw in expected_keywords if kw in schedule_text]
|
||||
print(f"\n Keywords found: {', '.join(found)}")
|
||||
|
||||
@@ -24,6 +24,17 @@ WELL A1 = "55_33-A-1"
|
||||
REPORT 2018-07-01
|
||||
REPORT A2_STARTUP + 90
|
||||
|
||||
# Raw schedule text is preserved verbatim. This block is inserted immediately
|
||||
# after the date declaration; lower priorities are emitted first when multiple
|
||||
# blocks use the same placement.
|
||||
SCHEDULE
|
||||
@A1_STARTUP + RAMP RAW_TEXT PLACEMENT=AFTER_DATE PRIORITY=10
|
||||
-- Custom schedule text not modeled by the timeline API
|
||||
WTRACER
|
||||
'55_33-A-1' 'ORION_TRACER' 1.0 /
|
||||
/
|
||||
END_RAW_TEXT
|
||||
|
||||
WELL A1
|
||||
@A1_STARTUP PERFORATION MDSTART=1644.49 MDEND=1664.28 RADIUS=0.12065 SKIN=5 COMPLETION_NUMBER=1 FILTER=POROPERM
|
||||
@A1_STARTUP PERFORATION MDSTART=1664.28 MDEND=1674.18 RADIUS=0.12065 SKIN=5 COMPLETION_NUMBER=2 FILTER=POROPERM
|
||||
|
||||
Reference in New Issue
Block a user