Commit Graph
347 Commits
Author SHA1 Message Date
Kristian Bendiksen 74ffc822f2 #14538 Well path: Preserve renamed file well name
The renamed well path name is serialized correctly, but reopening the project reloads the source well path file and overwrites the saved name with the name from that file. The reload flag only protected the completion export name, despite the loader also updating the displayed well path name.

Only initialize the well path and export names from the source file during first import. Subsequent data reloads preserve the names stored in the project while continuing to refresh geometry and metadata.

Add an RMS well round-trip test that renames an imported well, saves and reopens the project, and verifies that the custom name is retained.
2026-08-25 08:25:20 +02:00
Kristian Bendiksen 565d7b7819 #14571 Orion Events: Expand Python usage examples 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 41b7df5a20 #14571 Orion Events: Preserve post-processed events during merge 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 64317dfad7 #14575 Orion Events: Rename WELLSPEC event to WELSPECS 2026-08-24 13:26:19 +02:00
Kristian Bendiksen da6eb2062c Orion Events: Align imported schedule output in example code 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 0adf471a5d #14514 Orion Events: Include report dates in schedule 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 15adbeb9a1 #14575 Orion Events: Add context to validation errors 2026-08-24 13:26:19 +02:00
Kristian Bendiksen e1b192ff86 #14570 Orion Events: Fix schedule user metadata 2026-08-24 13:26:19 +02:00
Kristian Bendiksen d6878ea562 #14513 Orion Events: Add raw schedule text events 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 1803c636a5 Python: Fix keyword event example rendering 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 2ef4814257 #13672 Python: Add APIs to arrange and link views 2026-08-24 12:43:44 +02:00
Kristian Bendiksen 51aa090668 Python: Restore WellTypeForExport enum export 2026-08-21 11:42:34 +02:00
Kristian Bendiksen ce12272721 #14557 Orion Events: Rename tubing event to segment 2026-08-20 11:02:55 +02:00
Kristian Bendiksen db1c1f1f13 #14554 Orion Events: Add WELLSPEC event 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 3947e5ee4e Orion Events: Expand experimental schedule example 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 27b45353ea Orion Events: Add restart schedule cutoff 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 1278ee2404 Orion Events: Add group member events 2026-08-20 11:02:55 +02:00
Kristian Bendiksen c94d00a02a Orion Events: Merge matching dated events 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 61f615ac4c Orion Events: Preserve event comments 2026-08-20 11:02:55 +02:00
Kristian Bendiksen c41e74b706 Orion Events: Verify aligned schedule columns 2026-08-20 11:02:55 +02:00
Kristian Bendiksen a362f868c3 Orion Events: Generate COMPORD for new wells 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 0b7ce2252c Orion Events: Add schedule generation metadata 2026-08-20 11:02:55 +02:00
Kristian Bendiksen d57abe525d #14533 Orion events: Add group sections 2026-08-19 10:28:35 +02:00
Kristian Bendiksen 3932ac4519 #14535 Orion events: Parse boolean keyword values 2026-08-19 10:28:35 +02:00
Kristian Bendiksen 98147c5c9a #14535 Orion events: Validate keyword field names 2026-08-19 10:28:35 +02:00
Kristian Bendiksen afb13508dc #14514 Remove PERFID and DSHIFT from the ORIONEVENTS format
They are not planned as part of the file format. PERFID on a completion event is now an unknown-attribute error like any other unrecognized key, and DSHIFT on keyword events is forwarded unchanged instead of being stripped with a warning. FILTER keeps its ignore-with-warning behavior outside PERFORATION events.
2026-08-19 10:28:35 +02:00
Kristian Bendiksen b3d0256941 #14514 Add option to include list of dates into schedule file
GenerateSchedule gains an AdditionalDates parameter (ISO date strings). The dates are merged, deduplicated and sorted with the event dates and each becomes a DATES keyword even when no events fall on it, ensuring a summary report at that date in Eclipse/Flow. They are deliberately not filtered by the last applied timestamp.

The ORIONEVENTS 2.0 format gains a top-level REPORT <date-expr> directive (date variables and day arithmetic supported). Parsed dates are collected on OrionDocument.report_dates and surfaced by the applier as sorted ISO strings on ApplyReport.report_dates, ready to pass to generate_schedule_text(additional_dates=...).
2026-08-19 10:28:35 +02:00
Kristian Bendiksen 8c3df6076d #14366 Python: Add per-view surface controls 2026-08-19 10:14:59 +02:00
Kristian Bendiksen 56fb7a660b #14367 Python: Add per-view polygon visibility API 2026-08-19 10:14:59 +02:00
Kristian Bendiksen 450d567ab1 #14484 Python: Add FILTER to the well_event_schedule_orion example
Declare FILTER HIPORO with a qualified result name (static.PORO) and
reference it from the first perforation, passing case= to the applier
and printing the attached filter per materialized perforation interval.
The FILTER parts are included only when the project has a loaded case,
so the example keeps working in caseless projects.
2026-08-10 14:41:36 +02:00
Kristian Bendiksen aec899cf34 #14484 Python: Demonstrate FILTER usage in the ORIONEVENTS example
Add a FILTER declaration (referenced by two perforations) and an inline
filter expression to the shipped well_events.orion sample, and extend
import_orion_events.py to pass case= to the applier and list the
combined data filters created from the declarations. Skip schedule
generation gracefully when no events were applied, and give FilterExpr
a __str__ returning the raw expression so variable listings stay
readable.
2026-08-10 14:41:36 +02:00
Kristian Bendiksen a95c3f7ab9 #14484 Orion Events: parse and apply data filter
Add a typed FILTER declaration to the ORIONEVENTS 2.0 grammar, e.g.
FILTER POROPERM = "PORO > 0.4 AND PERMX > 100.0". A PERFORATION event
references it with FILTER=POROPERM or supplies an inline quoted
expression. When applied, each used filter is materialized as a
case-level combined data filter (one property filter per term, one-sided
inclusive bounds, AND/OR combine mode) and attached to the perforation.

Unqualified result names are searched in STATIC_NATIVE, DYNAMIC_NATIVE
then GENERATED results; a TYPE. qualifier restricts the search. Missing
results raise before any event is applied. apply_orion_document gains an
optional case= parameter defaulting to the project's first case.

RimWellEventPerf carries a RimCellFilter ptr-field with scriptable
AddFilter/cell_filter methods, and the filter is copied onto the
RimPerforationInterval when the timeline materializes completions.
2026-08-10 14:41:36 +02:00
Magne Sjaastad 94da54c4f5 Remove AsyncPdmObjectVectorDeleter and delete PDM objects synchronously
Deleting PDM objects on a worker thread is not safe. PdmObjectHandle::prepareForDelete()
mutates state owned by other objects, it nulls the guarded pointers held by other objects
and clears m_pointersReferencingMe, an unsynchronised std::set that every PdmPointer
construction and destruction touches. Destroying an object off the main thread therefore
races with the main thread on the shared object graph. See issue 14491.

Profiling a summary ensemble teardown shows the mechanism does not pay for itself. Releasing
397 Drogon realizations takes 0.24 s sequentially and 0.24 s in parallel, and for a heavy
case the parallel release is slower than the sequential one, because free() is serialised
inside the allocator. The PDM bookkeeping itself is 0.4 to 2.8 percent of the teardown.

Remove the class and deleteChildrenAsync(), and delete synchronously instead. The call sites
that used clearWithoutDelete() and a manual delete loop to work around the race can now call
deleteChildren() directly. Add caf::PdmObjectHandleTools::deleteObjects() for the case where
the objects are no longer owned by a child array field.

The observer disconnection from issue 12262 does not depend on clearWithoutDelete(). ~Signal()
unregisters itself from every observer, so a deleted child detaches itself. That fix addressed
the async race, where ~Signal() mutated the observer list from a worker thread. The unit test
is updated to assert the observed signal count directly instead of relying on a crash.
2026-08-10 09:40:33 +02:00
Kristian Bendiksen 1b64f1f8da Python: Move ORIONEVENTS examples to PythonExamples/experimental
Relocate import_orion_events.py and well_event_schedule_orion.py from
wells_and_fractures to a new experimental folder, and update the doc
reference in docs/orionEvents.md accordingly.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen 7ec34e905a Python: Import rips.orion_events explicitly in examples
Roll back the __getattr__ lazy-import hook in rips/__init__.py. The hook
existed only so that a plain import rips would expose rips.orion_events
as an attribute; that eager exposure is also what triggered runpy's
found in sys.modules warning under python -m rips.orion_events.

Instead do not auto-expose the submodule from the package and have the
two examples import rips.orion_events explicitly, which is idiomatic and
warning-free.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen de942cc8aa Python: Extend ORIONEVENTS with completion events, SCHEDULE block and datetimes
Extend the 2.0 format to cover the full WellEventTimeline API demonstrated
by well_event_schedule.py.

Add built-in TUBING, VALVE and STATE event types mapping to
add_tubing_event, add_valve_event (including the AICD parameters) and
add_state_event, validated with the same required/unknown-attribute
handling as PERFORATION.

Pass any other event type inside a WELL block through generically as an
Eclipse well keyword via add_well_keyword_event with the well name
injected, so WRFTPLT, WCONPROD and the rest work without enumeration.
Event types that closely resemble a misspelled built-in are handled by
the on_unknown_event policy with a did-you-mean hint instead of being
passed through.

Add a SCHEDULE block: a bare SCHEDULE line opens a block of well-less
keyword events (RPTRST, GRUPTREE, TUNING, ...) applied through
add_keyword_event; completion events in a SCHEDULE block are rejected.
Parsed schedule events live in OrionDocument.schedule_events.

Accept ISO datetimes in event dates (@2024-05-15T14:45:30.500); the
time-of-day survives into the generated DATES keyword's TIME field with
millisecond precision. Day-offset arithmetic applies to datetimes too.

Ship well_event_schedule_orion.py, an ORIONEVENTS counterpart to
well_event_schedule.py, and extend the test suite from 55 to 70 tests
including an integration test that applies every event kind and verifies
the generated schedule text.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen 03236ee737 Python: Redesign ORIONEVENTS grammar as version 2.0 with typed declarations
Replace the 1.0 grammar with a version 2.0 designed to be easier to parse
and easier to write. Variables are now typed: DATE, DURATION (whole days)
and WELL alias declarations replace the untyped SET, and using a variable
of the wrong type produces an error citing both the use and declaration
site. Well blocks open with an explicit WELL keyword (alias or
double-quoted literal name), quoting is double quotes throughout, and
date arithmetic accepts signed chains of integers and DURATION variables
such as @START + RAMP - 2. ORIONEVENTS 1.x headers are rejected with a
migration message.

FILTER and PERFID are no longer parse errors; any KEY=VALUE attribute
parses and the applier warns and ignores the not-yet-supported keys
(FILTER, PERFID, DSHIFT) while still applying the rest of the event.

The parser now recovers per line and reports every error in one pass via
OrionParseError.errors, unknown variables, event types and keywords get
difflib-based did-you-mean hints, and a stdlib-only validator CLI runs as
python3 -m rips.orion_events <file>. The eager orion_events import in
rips/__init__.py is replaced by a PEP 562 lazy import so the -m entry
point does not trigger runpy's double-import warning.

Update the shipped sample file and example script to the 2.0 syntax and
extend the test suite from 27 to 55 tests covering typed declarations,
offset arithmetic, alias resolution, multi-error diagnostics and the CLI.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen 1f346d28fd Python: Add ORIONEVENTS well-event-timeline parser
Add a pure-Python parser (rips.orion_events) that reads an ORIONEVENTS
text file into a structured representation, plus an applier that drives
the existing WellEventTimeline API to create perforation, WCONHIST and
WELTARG events.

The parser is split into a stdlib-only Layer A (parse_orion_events ->
OrionDocument) that is unit-testable without a running ResInsight, and a
Layer B applier (apply_orion_document) that maps the document onto
add_perf_event/add_well_keyword_event and resolves well names via the
project. RADIUS is mapped to diameter, dated SET variables support '+ N'
day arithmetic, and FILTER/PERFID are reserved but currently raise a
located error while DSHIFT is ignored with a warning.

Ship a documented grammar in the module docstring, a clean sample input
(example_input_files/well_events.orion), a runnable example
(import_orion_events.py), and tests covering parsing, mapping and an
end-to-end integration test against a loaded case.
2026-08-07 14:34:35 +02:00
Magne Sjaastad ebf75c09a1 #14411 Enforce name uniqueness for surfaces, polygons and folders
* #14411 Enforce name uniqueness for surfaces, polygons and folders

Names must be unique among siblings sharing the same parent folder. Items in different folders may keep identical names, and comparison is case sensitive.

Siblings are the objects held by the same caf::PdmChildArrayField. Items and folders live in two distinct child arrays in caf::PdmNestedCollection, so a folder and an item may share a name under the same parent.

The Python API gets an OnNameConflict flag on AddFolder, CreatePolygon, ImportSurface and NewRegularSurface, supporting FAIL (default), AUTO_RENAME and OVERWRITE. NewSurface is left out, as grid case surfaces derive their tree label from the case and K index and carry no name of their own.
2026-08-07 08:34:58 +02:00
Jon Jenssen 4f270603eb Update python test and example 2026-06-17 13:55:32 +02:00
Jon Jenssen ec9feff950 Whatever 2026-06-17 13:55:32 +02:00
Jon Jenssen 18cf162ce0 Some cleanup 2026-06-17 13:55:32 +02:00
Jon Jenssen a88d0824b0 Whatever 2026-06-17 13:55:32 +02:00
jonjenssen 52df6fd283 Snapshot work in progress 2026-06-17 13:55:32 +02:00
Kristian Bendiksen 8c17130714 #14223 Calculate geometry grid properties when creating grid from python API
Compute the depth related geometry properties (DEPTH, DX, DY, DZ, TOPS, BOTTOM) in RimCornerPointCase::createFromCoordinatesArray and replaceGridFromCoordinatesArray, matching the behavior when importing a grid from file. The computation is guarded by the same autoComputeDepthRelatedProperties preference used by the file importers.
2026-06-15 15:29:33 +02:00
Kristian Bendiksen a4fe22508a #14192 Python: Update discrete property color legend in place instead of delete/create
Address review feedback on #14199: deleting and recreating the legend left
views bound to the old legend pointing at a deleted object. Add
RimColorLegendCollection::updateColorLegend and a matching UpdateColorLegend
scriptable method that mutate the existing custom legend (name and items) so
referring views keep their binding and are notified once. A new legend is only
created when none is registered for the result or the registered legend is a
standard legend.

set_discrete_property_category_names now performs a single atomic call instead
of delete + create + per-item appends. The empty-dict removal path still uses
DeleteColorLegend.
2026-06-10 18:02:07 +02:00
Kristian Bendiksen 5a083331b0 #14192 Python: Fix duplicate discrete property legend on repeated category-name calls
RimColorLegendCollection::deleteColorLegend erased the default-legend map
entry before looking the legend up, so findDefaultLegendForResult always
returned null and the old legend was never removed from m_customColorLegends.
Each set_discrete_property_category_names call for the same property left an
orphaned legend behind and appended a new one.

Look up the legend before erasing the map key, and guard against deleting a
standard legend that may have been registered as a default.
2026-06-10 18:02:07 +02:00
Magne Sjaastad 714dda1aff #14188 GrpcInterface: Handle copyPdmObjectFromRipsToCaf result in CallPdmObjectMethod
The return value of copyPdmObjectFromRipsToCaf was discarded when copying method parameters in CallPdmObjectMethod. Check the std::expected result and return a gRPC INVALID_ARGUMENT status (with telemetry and logging) when parameter validation fails, instead of silently proceeding to execute the method.
2026-06-10 12:34:59 +02:00
Magne Sjaastad 76d0ff3d3c #14188 GrpcInterface: Propagate parameter validation errors in command service
Make RiaGrpcCommandService::assignPdmObjectValues return std::expected<void, QString> so the result of copyPdmObjectFromRipsToCaf is no longer discarded. Validation failures are now propagated up and returned to the client as a gRPC INVALID_ARGUMENT status instead of being silently ignored. This also resolves the C4834 [[nodiscard]] build warning.
2026-06-10 12:34:59 +02:00
Kristian Bendiksen c2b4f83643 #14101 Rename RimFaultDistanceResult/Collection classes and files to RimFaultDistance/RimFaultDistanceCollection
Carries the "Fault Distance" rename through to the C++ class names, file
names, PDM/scriptable keywords and the Python API (add_fault_distance,
class FaultDistance). The RicNewFaultDistanceResultFeature command class
keeps its name.
2026-06-08 21:42:19 +02:00