mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 07:00:17 -05:00
#14612 Simulator Events: Remove Orion project naming
This commit is contained in:
1 parent
1fc5e424e4
commit
71c5b5a97d
13 files changed
+620
-589
No files matched your search
@@ -33,7 +33,7 @@ const std::vector<RiaExperimentalFeatures::Feature>& RiaExperimentalFeatures::av
|
||||
{ "osdu-well-logs", "OSDU Well Logs", "Enable import of well logs from OSDU." },
|
||||
{ "undo-redo-view", "Undo/Redo View", "Show the command undo/redo history view." },
|
||||
{ "oil-volume-result", "Oil Volume Result", "Compute the derived oil volume cell result." },
|
||||
{ "orion-events-import", "Orion Events Import", "Enable import of Orion well events from file." },
|
||||
{ "simulator-events-import", "Simulator Events Import", "Enable import of simulator events from file." },
|
||||
{ "remember-dialog-size",
|
||||
"Remember Dialog Size",
|
||||
"Remember the size of property and preferences dialogs between sessions and restore it the next time they "
|
||||
|
||||
@@ -17,7 +17,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewPolylineTargetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeletePolylineTargetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportWellMeasurementsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportOrionEventsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportSimulatorEventsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathLateralAtDepthFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathLateralFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicPasteModeledWellPathFeature.cpp
|
||||
|
||||
+12
-12
@@ -16,7 +16,7 @@
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicImportOrionEventsFeature.h"
|
||||
#include "RicImportSimulatorEventsFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaGuiApplication.h"
|
||||
@@ -30,12 +30,12 @@
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicImportOrionEventsFeature, "RicImportOrionEventsFeature" );
|
||||
CAF_CMD_SOURCE_INIT( RicImportSimulatorEventsFeature, "RicImportSimulatorEventsFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportOrionEventsFeature::onActionTriggered( bool isChecked )
|
||||
void RicImportSimulatorEventsFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
// The import runs as a Python child process which applies the events to this instance through
|
||||
// gRPC, so both the script server and a Python interpreter must be available.
|
||||
@@ -43,7 +43,7 @@ void RicImportOrionEventsFeature::onActionTriggered( bool isChecked )
|
||||
if ( !app->activeGrpcPortNumber() )
|
||||
{
|
||||
QMessageBox::warning( Riu3DMainWindowTools::mainWindowWidget(),
|
||||
"Import Orion Events",
|
||||
"Import Simulator Events",
|
||||
"The Python script server is not running. Enable it in Preferences -> Scripting and restart ResInsight." );
|
||||
return;
|
||||
}
|
||||
@@ -51,19 +51,19 @@ void RicImportOrionEventsFeature::onActionTriggered( bool isChecked )
|
||||
if ( app->pythonPath().isEmpty() )
|
||||
{
|
||||
QMessageBox::warning( Riu3DMainWindowTools::mainWindowWidget(),
|
||||
"Import Orion Events",
|
||||
"Import Simulator Events",
|
||||
"No Python executable is configured in Preferences -> Scripting." );
|
||||
return;
|
||||
}
|
||||
|
||||
QString defaultDir = app->lastUsedDialogDirectory( "ORION_EVENTS_DIR" );
|
||||
QString defaultDir = app->lastUsedDialogDirectory( "SIMULATOR_EVENTS_DIR" );
|
||||
QString fileName = RiuFileDialogTools::getOpenFileName( Riu3DMainWindowTools::mainWindowWidget(),
|
||||
"Import Orion Events",
|
||||
"Import Simulator Events",
|
||||
defaultDir,
|
||||
"Orion Events Files (*.orion);;All Files (*.*)" );
|
||||
"Simulator Events Files (*.events);;All Files (*.*)" );
|
||||
if ( fileName.isEmpty() ) return;
|
||||
|
||||
app->setLastUsedDialogDirectory( "ORION_EVENTS_DIR", QFileInfo( fileName ).absolutePath() );
|
||||
app->setLastUsedDialogDirectory( "SIMULATOR_EVENTS_DIR", QFileInfo( fileName ).absolutePath() );
|
||||
|
||||
// Show the process monitor so the report and any errors from the child process are visible.
|
||||
RiuMainWindow* mainWindow = RiuMainWindow::instance();
|
||||
@@ -75,7 +75,7 @@ void RicImportOrionEventsFeature::onActionTriggered( bool isChecked )
|
||||
|
||||
// Unbuffered output ("-u") so the report streams into the process monitor promptly. The child
|
||||
// process finds this instance through the RESINSIGHT_GRPC_PORT environment variable.
|
||||
QStringList arguments = { "-u", "-m", "rips.orion_events", "--apply", fileName };
|
||||
QStringList arguments = { "-u", "-m", "rips.simulator_events", "--apply", fileName };
|
||||
if ( !app->launchProcess( app->pythonPath(), arguments, app->pythonProcessEnvironment() ) )
|
||||
{
|
||||
RiaLogging::error( "Failed to launch the Python interpreter. Another script may already be running." );
|
||||
@@ -85,8 +85,8 @@ void RicImportOrionEventsFeature::onActionTriggered( bool isChecked )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportOrionEventsFeature::setupActionLook( QAction* actionToSetup )
|
||||
void RicImportSimulatorEventsFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "Import Orion Events" );
|
||||
actionToSetup->setText( "Import Simulator Events" );
|
||||
actionToSetup->setIcon( QIcon( ":/Well.svg" ) );
|
||||
}
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicImportOrionEventsFeature : public caf::CmdFeature
|
||||
class RicImportSimulatorEventsFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
@@ -351,9 +351,9 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder.addSeparator();
|
||||
menuBuilder << "RicWellPathImportPerforationIntervalsFeature";
|
||||
menuBuilder << "RicImportWellMeasurementsFeature";
|
||||
if ( RiaPreferencesSystem::current()->isFeatureEnabled( "orion-events-import" ) )
|
||||
if ( RiaPreferencesSystem::current()->isFeatureEnabled( "simulator-events-import" ) )
|
||||
{
|
||||
menuBuilder << "RicImportOrionEventsFeature";
|
||||
menuBuilder << "RicImportSimulatorEventsFeature";
|
||||
}
|
||||
menuBuilder.subMenuEnd();
|
||||
menuBuilder.addSeparator();
|
||||
|
||||
@@ -766,11 +766,11 @@ TEST( RifEventKeywordFormatterTest, BuildKeywordOverridesWellName )
|
||||
wellItem.setItemName( "WELL" );
|
||||
wellItem.setStringValue( "WellPathA" );
|
||||
|
||||
auto keyword = RifEventKeywordFormatter::buildKeyword( "WCONHIST", { &wellItem }, QString( "ORION_EXPORT_ALIAS" ) );
|
||||
auto keyword = RifEventKeywordFormatter::buildKeyword( "WCONHIST", { &wellItem }, QString( "SIMULATOR_EVENTS_EXPORT_ALIAS" ) );
|
||||
|
||||
ASSERT_TRUE( keyword.has_value() );
|
||||
ASSERT_EQ( keyword->size(), 1 );
|
||||
EXPECT_EQ( keyword->getRecord( 0 ).getItem( "WELL" ).getTrimmedString( 0 ), "ORION_EXPORT_ALIAS" );
|
||||
EXPECT_EQ( keyword->getRecord( 0 ).getItem( "WELL" ).getTrimmedString( 0 ), "SIMULATOR_EVENTS_EXPORT_ALIAS" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -140,9 +140,9 @@ void RiuMenuBarBuildTools::addImportMenuForMainWindow( QObject* parent, QMenu* m
|
||||
importWellMenu->addAction( cmdFeatureMgr->action( "RicWellLogsImportFileFeature" ) );
|
||||
importWellMenu->addAction( cmdFeatureMgr->action( "RicWellPathFormationsImportFileFeature" ) );
|
||||
importWellMenu->addAction( cmdFeatureMgr->action( "RicImportWellMeasurementsFeature" ) );
|
||||
if ( RiaPreferencesSystem::current()->isFeatureEnabled( "orion-events-import" ) )
|
||||
if ( RiaPreferencesSystem::current()->isFeatureEnabled( "simulator-events-import" ) )
|
||||
{
|
||||
importWellMenu->addAction( cmdFeatureMgr->action( "RicImportOrionEventsFeature" ) );
|
||||
importWellMenu->addAction( cmdFeatureMgr->action( "RicImportSimulatorEventsFeature" ) );
|
||||
}
|
||||
|
||||
importMenu->addSeparator();
|
||||
|
||||
+14
-14
@@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Example: import an ORIONEVENTS well-event-timeline file into ResInsight.
|
||||
Example: import a SIMEVENTS well-event-timeline file into ResInsight.
|
||||
|
||||
This example shows how to:
|
||||
1. Parse an ORIONEVENTS text file into a structured document
|
||||
1. Parse a SIMEVENTS text file into a structured document
|
||||
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
|
||||
@@ -12,9 +12,9 @@ This example shows how to:
|
||||
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
|
||||
rips/example_input_files/well_events.orion.
|
||||
The SIMEVENTS format is a compact, human-authored description of dated well
|
||||
events. See rips/simulator_events.py for the grammar. A sample input file ships at
|
||||
rips/example_input_files/simulator_events.events.
|
||||
|
||||
The well names in the file ("55_33-A-1", ...) must match well paths that exist
|
||||
in the open project, so this example assumes a project with matching wells and
|
||||
@@ -26,22 +26,22 @@ result raises before any event is applied.
|
||||
import os
|
||||
|
||||
import rips
|
||||
import rips.orion_events
|
||||
import rips.simulator_events
|
||||
|
||||
|
||||
def main():
|
||||
resinsight = rips.Instance.find()
|
||||
project = resinsight.project
|
||||
|
||||
print("Import ORIONEVENTS Example")
|
||||
print("Import SIMEVENTS Example")
|
||||
print("=" * 50)
|
||||
|
||||
# Locate the sample ORIONEVENTS file shipped alongside the rips package.
|
||||
orion_file = os.path.join(
|
||||
os.path.dirname(rips.__file__), "example_input_files", "well_events.orion"
|
||||
# Locate the sample SIMEVENTS file shipped alongside the rips package.
|
||||
simulator_events_file = os.path.join(
|
||||
os.path.dirname(rips.__file__), "example_input_files", "simulator_events.events"
|
||||
)
|
||||
print(f"\n1. Parsing: {orion_file}")
|
||||
document = rips.orion_events.parse_orion_events_file(orion_file)
|
||||
print(f"\n1. Parsing: {simulator_events_file}")
|
||||
document = rips.simulator_events.parse_simulator_events_file(simulator_events_file)
|
||||
print(f" Version: {document.version}, units: {document.unit_system}")
|
||||
print(f" Wells: {[w.well_name for w in document.wells]}")
|
||||
print(
|
||||
@@ -51,7 +51,7 @@ def main():
|
||||
# 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)
|
||||
normalized = rips.simulator_events.coalesce_simulator_events_document(document)
|
||||
source_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
for well in document.wells
|
||||
@@ -94,7 +94,7 @@ def main():
|
||||
well_path_coll = project.descendants(rips.WellPathCollection)[0]
|
||||
timeline = well_path_coll.event_timeline()
|
||||
|
||||
report = rips.orion_events.apply_orion_document(
|
||||
report = rips.simulator_events.apply_simulator_events_document(
|
||||
document, timeline, project, case=case, on_unknown_well="warn"
|
||||
)
|
||||
print(f" Events applied: {report.events_applied}")
|
||||
+19
-17
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Example: the well_event_schedule.py timeline expressed as an ORIONEVENTS file.
|
||||
Example: the well_event_schedule.py timeline expressed as a SIMEVENTS file.
|
||||
|
||||
This is the ORIONEVENTS counterpart to well_event_schedule.py: instead of
|
||||
This is the SIMEVENTS counterpart to well_event_schedule.py: instead of
|
||||
calling the WellEventTimeline API methods one by one, the same events are
|
||||
written as ORIONEVENTS 2.0 text (see rips/orion_events.py for the grammar) and
|
||||
applied in one go with rips.orion_events.apply_orion_document().
|
||||
written as SIMEVENTS 1.0 text (see rips/simulator_events.py for the grammar) and
|
||||
applied in one go with rips.simulator_events.apply_simulator_events_document().
|
||||
|
||||
It demonstrates the full event coverage of the format:
|
||||
1. SEGMENT, PERFORATION (incl. a time-of-day date), VALVE and STATE completion
|
||||
@@ -29,7 +29,7 @@ It demonstrates the full event coverage of the format:
|
||||
generate_schedule_text(additional_dates=...) as summary-report triggers
|
||||
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 SIMEVENTS 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
|
||||
works with any project that has at least one well path. Applying a FILTER needs
|
||||
a loaded Eclipse case (to resolve the result name and own the created filter),
|
||||
@@ -37,10 +37,10 @@ so the FILTER parts are included only when the project has a case.
|
||||
"""
|
||||
|
||||
import rips
|
||||
import rips.orion_events
|
||||
import rips.simulator_events
|
||||
|
||||
|
||||
def build_orion_text(well_name, with_filter):
|
||||
def build_simulator_events_text(well_name, with_filter):
|
||||
# 'static.PORO' restricts the result lookup to STATIC_NATIVE results; an
|
||||
# unqualified name would search STATIC_NATIVE, DYNAMIC_NATIVE, GENERATED.
|
||||
filter_decl = 'FILTER HIPORO = "static.PORO > 0.15"\n' if with_filter else ""
|
||||
@@ -51,7 +51,7 @@ def build_orion_text(well_name, with_filter):
|
||||
)
|
||||
filter_ref = " FILTER=HIPORO" if with_filter else ""
|
||||
return f"""\
|
||||
ORIONEVENTS 2.0
|
||||
SIMEVENTS 1.0
|
||||
UNIT METRIC
|
||||
|
||||
# Typed declarations
|
||||
@@ -63,7 +63,7 @@ WELL W1 = "{well_name}"
|
||||
WELL W1
|
||||
# WELSPECS updates completion export settings and emits WELSPECS. Attributes
|
||||
# are optional: the second event inherits GROUP from the first event.
|
||||
2024-01-05 WELSPECS GROUP="ORION_GROUP" CROSSFLOW=True REFDEPTH=1002 PHASE=WATER
|
||||
2024-01-05 WELSPECS GROUP="SIMULATOR_EVENTS_GROUP" CROSSFLOW=True REFDEPTH=1002 PHASE=WATER
|
||||
2024-04-15 WELSPECS CROSSFLOW=False REFDEPTH=1000 PHASE=OIL
|
||||
|
||||
# COMMENT is stored on the event and safely emitted as a schedule comment.
|
||||
@@ -110,7 +110,7 @@ SCHEDULE
|
||||
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 /
|
||||
'{well_name}' 'SIMULATOR_EVENTS_TRACER' 1.0 /
|
||||
/
|
||||
END_RAW_TEXT
|
||||
|
||||
@@ -125,7 +125,7 @@ def main():
|
||||
resinsight = rips.Instance.find()
|
||||
project = resinsight.project
|
||||
|
||||
print("Well Event Schedule (ORIONEVENTS) Example")
|
||||
print("Well Event Schedule (SIMEVENTS) Example")
|
||||
print("=" * 50)
|
||||
|
||||
print("\n1. Finding well")
|
||||
@@ -142,10 +142,12 @@ def main():
|
||||
if case is None:
|
||||
print(" No Eclipse case loaded - FILTER parts are left out.")
|
||||
|
||||
print("\n2. Parsing ORIONEVENTS text...")
|
||||
orion_text = build_orion_text(well_path.name, with_filter=case is not None)
|
||||
print(orion_text)
|
||||
document = rips.orion_events.parse_orion_events(orion_text)
|
||||
print("\n2. Parsing SIMEVENTS text...")
|
||||
simulator_events_text = build_simulator_events_text(
|
||||
well_path.name, with_filter=case is not None
|
||||
)
|
||||
print(simulator_events_text)
|
||||
document = rips.simulator_events.parse_simulator_events(simulator_events_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(
|
||||
@@ -153,7 +155,7 @@ def main():
|
||||
for well in document.wells
|
||||
for event in well.events
|
||||
)
|
||||
normalized = rips.orion_events.coalesce_orion_document(document)
|
||||
normalized = rips.simulator_events.coalesce_simulator_events_document(document)
|
||||
merged_well_event_count = sum(len(w.events) for w in normalized.wells)
|
||||
merged_perforation_count = sum(
|
||||
event.event_type == "PERFORATION"
|
||||
@@ -172,7 +174,7 @@ def main():
|
||||
print("\n3. Applying events to the timeline...")
|
||||
well_path_coll = project.descendants(rips.WellPathCollection)[0]
|
||||
timeline = well_path_coll.event_timeline()
|
||||
report = rips.orion_events.apply_orion_document(
|
||||
report = rips.simulator_events.apply_simulator_events_document(
|
||||
document, timeline, project, case=case
|
||||
)
|
||||
print(f" Events applied: {report.events_applied}")
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Example ORIONEVENTS well-event-timeline file (version 2.0).
|
||||
# Parsed by rips.orion_events; see that module's docstring for the grammar.
|
||||
# Validate with: python3 -m rips.orion_events well_events.orion
|
||||
# Example SIMEVENTS well-event-timeline file (version 1.0).
|
||||
# Parsed by rips.simulator_events; see that module's docstring for the grammar.
|
||||
# Validate with: python3 -m rips.simulator_events simulator_events.events
|
||||
|
||||
ORIONEVENTS 2.0
|
||||
SIMEVENTS 1.0
|
||||
UNIT METRIC
|
||||
|
||||
# Typed declarations: dates, whole-day durations, well-name aliases, and
|
||||
@@ -32,7 +32,7 @@ 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 /
|
||||
'55_33-A-1' 'SIMULATOR_EVENTS_TRACER' 1.0 /
|
||||
/
|
||||
END_RAW_TEXT
|
||||
|
||||
+178
-172
File diff suppressed because it is too large.
Load diff
+366
-342
File diff suppressed because it is too large.
Load diff
@@ -1,28 +1,28 @@
|
||||
# ORIONEVENTS File Format — Version 2.0
|
||||
# SIMEVENTS File Format — Version 1.0
|
||||
|
||||
## Overview
|
||||
|
||||
ORIONEVENTS is a compact, human-authored text format describing dated well events (completions and Eclipse schedule keywords) over time. ResInsight reads it through the pure-Python parser in `GrpcInterface/Python/rips/orion_events.py` and applies the events to a project via the `WellEventTimeline` API, from which Eclipse schedule text (COMPDAT, WELSEGS, WCONHIST, ...) can be generated.
|
||||
SIMEVENTS is a compact, human-authored text format describing dated well events (completions and Eclipse schedule keywords) over time. ResInsight reads it through the pure-Python parser in `GrpcInterface/Python/rips/simulator_events.py` and applies the events to a project via the `WellEventTimeline` API, from which Eclipse schedule text (COMPDAT, WELSEGS, WCONHIST, ...) can be generated.
|
||||
|
||||
The implementation has two independent layers:
|
||||
|
||||
| Layer | Entry points | Needs ResInsight? |
|
||||
|---|---|---|
|
||||
| A — parser | `rips.orion_events.parse_orion_events(text)` / `parse_orion_events_file(path)` | No |
|
||||
| B — applier | `rips.orion_events.apply_orion_document(document, timeline, project)` / `apply_orion_events_file(path, timeline, project)` | Yes |
|
||||
| A — parser | `rips.simulator_events.parse_simulator_events(text)` / `parse_simulator_events_file(path)` | No |
|
||||
| B — applier | `rips.simulator_events.apply_simulator_events_document(document, timeline, project)` / `apply_simulator_events_file(path, timeline, project)` | Yes |
|
||||
|
||||
A standalone validator runs Layer A only:
|
||||
|
||||
```
|
||||
python3 -m rips.orion_events myfile.orion
|
||||
python3 -m rips.simulator_events myfile.events
|
||||
```
|
||||
|
||||
Runnable examples: `rips/PythonExamples/experimental/import_orion_events.py` (reads the shipped sample `rips/example_input_files/well_events.orion`) and `well_event_schedule_orion.py` (full event coverage, generates schedule text).
|
||||
Runnable examples: `rips/PythonExamples/experimental/import_simulator_events.py` (reads the shipped sample `rips/example_input_files/simulator_events.events`) and `well_event_schedule_simulator_events.py` (full event coverage, generates schedule text).
|
||||
|
||||
## Quick example
|
||||
|
||||
```
|
||||
ORIONEVENTS 2.0
|
||||
SIMEVENTS 1.0
|
||||
UNIT METRIC
|
||||
|
||||
# Typed declarations
|
||||
@@ -55,7 +55,7 @@ SCHEDULE # schedule-level keywords, not tied to a well
|
||||
|
||||
```
|
||||
document = header , { statement } ;
|
||||
header = "ORIONEVENTS" , "2.0" ; (* first meaningful line *)
|
||||
header = "SIMEVENTS" , "1.0" ; (* first meaningful line *)
|
||||
statement = unit_directive | declaration | report_line | well_block_open
|
||||
| group_block_open | schedule_block_open | event_line ;
|
||||
unit_directive = "UNIT" , ( "METRIC" | "FIELD" | "LAB" ) ;
|
||||
@@ -100,7 +100,7 @@ The format is line-oriented. Every non-blank line is dispatched on its first tok
|
||||
|
||||
| First token | Meaning |
|
||||
|---|---|
|
||||
| `ORIONEVENTS` | Header with version; must be the first meaningful line, exactly once |
|
||||
| `SIMEVENTS` | Header with version; must be the first meaningful line, exactly once |
|
||||
| `UNIT` | Unit system: `METRIC`, `FIELD` or `LAB` (default `METRIC`) |
|
||||
| `DATE` | Declare a typed date variable |
|
||||
| `DURATION` | Declare a typed whole-day duration variable |
|
||||
@@ -251,10 +251,10 @@ When applied, each used filter becomes a case-level **combined data filter** (un
|
||||
|
||||
## Diagnostics
|
||||
|
||||
The parser recovers per line and reports **all** errors in one pass. The raised `OrionParseError` carries one `ParseIssue` (message + source line) per problem, and unknown names get difflib-based "did you mean" suggestions:
|
||||
The parser recovers per line and reports **all** errors in one pass. The raised `SimulatorEventsParseError` carries one `ParseIssue` (message + source line) per problem, and unknown names get difflib-based "did you mean" suggestions:
|
||||
|
||||
```
|
||||
Line 3: SET is ORIONEVENTS 1.x syntax; declare a typed variable instead, e.g. DATE NAME = 2018-01-01
|
||||
Line 3: SET is not supported; declare a typed variable instead, e.g. DATE NAME = 2018-01-01
|
||||
Line 5: Malformed WELL line: 'WELL 55_33-A-2' (well names containing special characters must be double-quoted, e.g. WELL "55_33-A-1")
|
||||
Line 6: Unknown variable 'A1_STRTUP'; did you mean 'A1_STARTUP'?
|
||||
Line 7: Variable 'RAMP' is a DURATION (declared line 3) but a DATE is required here
|
||||
@@ -263,8 +263,8 @@ Line 7: Variable 'RAMP' is a DURATION (declared line 3) but a DATE is required
|
||||
The validator CLI prints these and exits non-zero:
|
||||
|
||||
```
|
||||
$ python3 -m rips.orion_events well_events.orion
|
||||
well_events.orion: OK (ORIONEVENTS 2.0, units METRIC)
|
||||
$ python3 -m rips.simulator_events simulator_events.events
|
||||
simulator_events.events: OK (SIMEVENTS 1.0, units METRIC)
|
||||
4 variable(s), 2 well block(s), 8 well event(s), 0 schedule event(s)
|
||||
```
|
||||
|
||||
@@ -279,8 +279,8 @@ project = resinsight.project
|
||||
well_path_coll = project.descendants(rips.WellPathCollection)[0]
|
||||
timeline = well_path_coll.event_timeline()
|
||||
|
||||
report = rips.orion_events.apply_orion_events_file(
|
||||
"well_events.orion", timeline, project, case=case, on_unknown_well="warn"
|
||||
report = rips.simulator_events.apply_simulator_events_file(
|
||||
"simulator_events.events", timeline, project, case=case, on_unknown_well="warn"
|
||||
)
|
||||
print(report.events_applied, report.events_skipped, report.warnings, report.errors)
|
||||
|
||||
@@ -290,7 +290,7 @@ schedule_text = timeline.generate_schedule_text(
|
||||
)
|
||||
```
|
||||
|
||||
`apply_orion_document` / `apply_orion_events_file` accept an optional `case` — the `rips.Case` used to resolve filter result names and to own the created combined filters. It is only needed when the document uses `FILTER` and defaults to the project's first case; a `RipsError` is raised if a filter is used and no case is available, or if a filter references a result missing from the case (checked before any event is applied).
|
||||
`apply_simulator_events_document` / `apply_simulator_events_file` accept an optional `case` — the `rips.Case` used to resolve filter result names and to own the created combined filters. It is only needed when the document uses `FILTER` and defaults to the project's first case; a `RipsError` is raised if a filter is used and no case is available, or if a filter references a result missing from the case (checked before any event is applied).
|
||||
|
||||
They also accept two policies, each `"warn"` (default), `"error"` or `"skip"`:
|
||||
|
||||
@@ -303,5 +303,4 @@ The returned `ApplyReport` carries `events_applied`, `events_skipped`, `warnings
|
||||
|
||||
## Version history
|
||||
|
||||
- **2.0** — current: typed `DATE`/`DURATION`/`WELL`/`FILTER` declarations, `WELL`/`SCHEDULE` blocks, signed day-offset chains, ISO datetimes, built-in completion events (including `SEGMENT` custom intervals and pressure components) plus generic keyword pass-through, perforation data filters, multi-error diagnostics, validator CLI.
|
||||
- **1.x** — unsupported. Files using `SET` variables and single-quoted well names are rejected with a migration message pointing at this grammar.
|
||||
- **1.0** — current: typed `DATE`/`DURATION`/`WELL`/`FILTER` declarations, `WELL`/`SCHEDULE` blocks, signed day-offset chains, ISO datetimes, built-in completion events (including `SEGMENT` custom intervals and pressure components) plus generic keyword pass-through, perforation data filters, multi-error diagnostics, validator CLI.
|
||||
Reference in new issue
Block a user