Skip to content

Well log viewer - implement layer system #936

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
09bfc04
Renamed getStratigraphicUnits to getStratigraphicUnitsForCase. Added …
Anders2303 Feb 25, 2025
f2d48ba
Added abstract implementation of Layer interface
Anders2303 Feb 25, 2025
27be743
WIP: Implemented well-picks layer for well-log-viewer
Anders2303 Feb 25, 2025
6bd6977
WIP -- Deleted old layer implementations
Anders2303 Apr 3, 2025
c6ed660
WIP: implement well-picks and basic plot configs
Anders2303 Apr 4, 2025
5d36286
Added duplicate curve-name example to drogon curve data. Added clarif…
Anders2303 Apr 7, 2025
13ab61a
WIP -- Made manager actions group dependent
Anders2303 Apr 7, 2025
2426bdb
Added handling of duplicate curve names
Anders2303 Apr 7, 2025
5922b48
Merge branch 'main' into well-log/implement_layer_system
Anders2303 Apr 9, 2025
d0d81bf
WIP -- Bug in manager init
Anders2303 Apr 9, 2025
fbc72f4
Fixed product to well log viewer prop conversion
Anders2303 Apr 10, 2025
f4bcd51
Merge branch 'main' into well-log/implement_layer_system
Anders2303 Apr 10, 2025
1268a4e
Added discrete tracks
Anders2303 Apr 11, 2025
d5c5f12
Added color setting to plots
Anders2303 Apr 11, 2025
9039a81
Merge branch 'main' into well-log/implement_layer_system
Anders2303 Apr 14, 2025
e2b5423
Added drogon example of text curve
Anders2303 Apr 14, 2025
0d01e4f
Exposed "step" prop in input component
Anders2303 Apr 14, 2025
68f9db7
Added stacked plot provider for discrete tracks
Anders2303 Apr 14, 2025
989b5e1
Cleaned up some continuous track stuff
Anders2303 Apr 14, 2025
971dcc7
Split Well log viewer logic into distinct wrappers
Anders2303 Apr 15, 2025
c9ae730
WIP -- Implemented diff curve plot provider
Anders2303 Apr 15, 2025
a21f56f
Cleaned up old setting code
Anders2303 Apr 15, 2025
5eed7f2
Cleaned tests
Anders2303 Apr 15, 2025
bfbfb77
Moved visualization hook to /hooks folder
Anders2303 Apr 15, 2025
61741fc
Upgraded well-log viewer package
Anders2303 Apr 16, 2025
73b279e
Added movement checks provider manager
Anders2303 Apr 16, 2025
1fae9c9
Fixed plot provider names
Anders2303 Apr 16, 2025
bd43412
Added temporary workaround for accessing unkown settings
Anders2303 Apr 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions backend_py/primary/primary/routers/surface/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ async def get_realization_surfaces_metadata(
surf_meta_task = tg.create_task(access.get_realization_surfaces_metadata_async())
surf_meta_task.add_done_callback(lambda _: perf_metrics.record_lap_no_reset("get-meta"))

strat_units_task = tg.create_task(_get_stratigraphic_units_for_case_async(authenticated_user, case_uuid))
strat_units_task = tg.create_task(
_get_stratigraphic_units_for_strat_column_async(authenticated_user, case_uuid)
)
strat_units_task.add_done_callback(lambda _: perf_metrics.record_lap_no_reset("get-strat"))

perf_metrics.reset_lap_timer()
Expand Down Expand Up @@ -106,7 +108,9 @@ async def get_observed_surfaces_metadata(
surf_meta_task = tg.create_task(access.get_observed_surfaces_metadata_async())
surf_meta_task.add_done_callback(lambda _: perf_metrics.record_lap_no_reset("get-meta"))

strat_units_task = tg.create_task(_get_stratigraphic_units_for_case_async(authenticated_user, case_uuid))
strat_units_task = tg.create_task(
_get_stratigraphic_units_for_strat_column_async(authenticated_user, case_uuid)
)
strat_units_task.add_done_callback(lambda _: perf_metrics.record_lap_no_reset("get-strat"))

perf_metrics.reset_lap_timer()
Expand Down Expand Up @@ -314,8 +318,8 @@ async def get_wellbore_stratigraphic_columns(
return [converters.to_api_stratigraphic_column(col) for col in strat_columns]


@router.get("/stratigraphic_units")
async def get_stratigraphic_units(
@router.get("/stratigraphic_units_for_case")
async def get_stratigraphic_units_for_case(
# fmt:off
response: Response,
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
Expand All @@ -324,23 +328,41 @@ async def get_stratigraphic_units(
) -> list[schemas.StratigraphicUnit]:
perf_metrics = ResponsePerfMetrics(response)

strat_units = await _get_stratigraphic_units_for_case_async(authenticated_user, case_uuid)
case_inspector = CaseInspector.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
strat_column_identifier = await case_inspector.get_stratigraphic_column_identifier_async()
perf_metrics.record_lap("get-strat-ident")

strat_units = await _get_stratigraphic_units_for_strat_column_async(authenticated_user, strat_column_identifier)
api_strat_units = [converters.to_api_stratigraphic_unit(strat_unit) for strat_unit in strat_units]

LOGGER.info(f"Got stratigraphic units in: {perf_metrics.to_string()}")

return api_strat_units


@router.get("/stratigraphic_units_for_strat_column")
async def get_stratigraphic_units_for_strat_column(
# fmt:off
response: Response,
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
strat_column: Annotated[str, Query(description="SMDA stratigraphic column identifier")],
# fmt:on
) -> list[schemas.StratigraphicUnit]:
perf_metrics = ResponsePerfMetrics(response)

strat_units = await _get_stratigraphic_units_for_strat_column_async(authenticated_user, strat_column)
api_strat_units = [converters.to_api_stratigraphic_unit(strat_unit) for strat_unit in strat_units]

LOGGER.info(f"Got stratigraphic units in: {perf_metrics.to_string()}")

return api_strat_units


async def _get_stratigraphic_units_for_case_async(
authenticated_user: AuthenticatedUser, case_uuid: str
async def _get_stratigraphic_units_for_strat_column_async(
authenticated_user: AuthenticatedUser, strat_column_identifier: str
) -> list[StratigraphicUnit]:
perf_metrics = PerfMetrics()

case_inspector = CaseInspector.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
strat_column_identifier = await case_inspector.get_stratigraphic_column_identifier_async()
perf_metrics.record_lap("get-strat-ident")

smda_access: SmdaAccess | DrogonSmdaAccess
if is_drogon_identifier(strat_column_identifier=strat_column_identifier):
smda_access = DrogonSmdaAccess()
Expand Down
5 changes: 2 additions & 3 deletions backend_py/primary/primary/routers/well/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,13 @@ async def get_log_curve_data(
# Handle DROGON
if is_drogon_identifier(wellbore_uuid=wellbore_uuid):
well_access_drogon = DrogonWellAccess(authenticated_user.get_ssdl_access_token())
curve_data = await well_access_drogon.get_log_curve_data_async(wellbore_uuid, curve_name)
curve_data = await well_access_drogon.get_log_curve_data_async(wellbore_uuid, curve_name, log_name)

return converters.convert_wellbore_log_curve_data_to_schema(curve_data)

if source == schemas.WellLogCurveSourceEnum.SSDL_WELL_LOG:
# Note that log name is not used on SSDL; but afaik curve names are not unique across all logs...
well_access = SsdlWellAccess(authenticated_user.get_ssdl_access_token())
log_curve = await well_access.get_log_curve_data_async(wellbore_uuid, curve_name)
log_curve = await well_access.get_log_curve_data_async(wellbore_uuid, curve_name, log_name)

return converters.convert_wellbore_log_curve_data_to_schema(log_curve)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

well_log_headers_2 = [
types.WellboreLogCurveHeader(curve_name="BS", curve_unit="IN", log_name="DROGON_CONTINUOUS"),
types.WellboreLogCurveHeader(curve_name="BS", curve_unit="IN", log_name="DROGON_CONTINUOUS_2"),
types.WellboreLogCurveHeader(curve_name="DROGON_COMMENTS", curve_unit="UNITLESS", log_name="DROGON_DISCRETE"),
]


Expand Down Expand Up @@ -151,4 +153,61 @@
(1000, None),
],
),
# Curve name is *not* unique across all logs in a well, since some log runs might present the same data.
# This is an example of such a curve.
"BS_2": types.WellboreLogCurveData(
name="BS",
log_name="DROGON_CONTINUOUS_2",
index_min=100,
index_max=1000,
index_unit="m",
unit="IN",
curve_alias=None,
curve_description=None,
curve_unit_desc=None,
min_curve_value=200,
max_curve_value=1000,
no_data_value=None,
DataPoints=[
(100, 100),
(150, 200),
(250, 200),
(300, 300),
(350, 300),
(400, 400),
(450, 400),
(500, 500),
(550, 600),
(600, 600),
(650, 700),
(700, 700),
(750, 800),
(800, 800),
(850, 900),
(900, 900),
(950, 600),
(1000, 600),
],
),
"DROGON_COMMENTS": types.WellboreLogCurveData(
name="DROGON_COMMENTS",
log_name="DROGON_DISCRETE",
index_min=100,
index_max=1000,
index_unit="m",
unit="UNITLESS",
curve_alias="TEXT",
curve_description=None,
curve_unit_desc=None,
min_curve_value=None,
max_curve_value=None,
no_data_value=None,
DataPoints=[
(150, "High quality"),
(200, "Good quality"),
(600, "No seal"),
(800, "High quality"),
(1000, "High quality"),
],
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ async def get_log_curve_headers_for_field_async(self, field_uuid: str) -> list[t
raise NotImplementedError

# pylint: disable=unused-argument
async def get_log_curve_data_async(self, wellbore_uuid: str, curve_name: str) -> types.WellboreLogCurveData:
async def get_log_curve_data_async(
self, wellbore_uuid: str, curve_name: str, log_name: str
) -> types.WellboreLogCurveData:
if wellbore_uuid == "drogon_vertical":
return _drogon_well_data.well_log_data_map_1[curve_name]
if wellbore_uuid == "drogon_horizontal":
return _drogon_well_data.well_log_data_map_2[curve_name]
for curve in _drogon_well_data.well_log_data_map_2.values():
if curve.name == curve_name and curve.log_name == log_name:
return curve
raise ValueError(f"No curve {curve_name=} found for log {log_name=}!")

raise ValueError(f"Unexpected drogon well name: {wellbore_uuid=}!")
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ async def get_log_curve_headers_for_field_async(self, field_uuid: str) -> List[t
raise InvalidDataError(f"Invalid log curve headers for field {field_uuid}", Service.SSDL) from error
return result

async def get_log_curve_data_async(self, wellbore_uuid: str, curve_name: str) -> types.WellboreLogCurveData:
params = {"normalized_data": False}
async def get_log_curve_data_async(
self, wellbore_uuid: str, curve_name: str, log_name: str
) -> types.WellboreLogCurveData:
# ! Note: SSDL does not actually take the curve name into account when fetching data, but curve names are not unique across
# ! all logs, and there's no documentation about how one should specify the log, when picking curves. For now, I'm including
# ! log name as an argument, since we should fix that at some point in the future.
params = {"normalized_data": False, "log_name": log_name}
endpoint = f"WellLog/{wellbore_uuid}/{curve_name}"
ssdl_data = await ssdl_get_request_async(access_token=self._ssdl_token, endpoint=endpoint, params=params)
try:
Expand Down
Loading
Loading