Skip to content

Commit

Permalink
Adjustments to backend (and related required changes to frontend) in …
Browse files Browse the repository at this point in the history
…preparation of 2D viewer (#808)

Co-authored-by: Hans Kallekleiv <[email protected]>
  • Loading branch information
rubenthoms and HansKallekleiv authored Dec 3, 2024
1 parent a028574 commit 20542c9
Show file tree
Hide file tree
Showing 64 changed files with 1,122 additions and 881 deletions.
3 changes: 3 additions & 0 deletions backend_py/primary/primary/routers/explore.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class EnsembleInfo(BaseModel):
class EnsembleDetails(BaseModel):
name: str
field_identifier: str
stratigraphic_column_identifier: str
case_name: str
case_uuid: str
realizations: Sequence[int]
Expand Down Expand Up @@ -91,6 +92,7 @@ async def get_ensemble_details(
case_name = await case_inspector.get_case_name_async()
realizations = await case_inspector.get_realizations_in_iteration_async(ensemble_name)
field_identifiers = await case_inspector.get_field_identifiers_async()
stratigraphic_column_identifier = await case_inspector.get_stratigraphic_column_identifier_async()

if len(field_identifiers) != 1:
raise NotImplementedError("Multiple field identifiers not supported")
Expand All @@ -101,4 +103,5 @@ async def get_ensemble_details(
case_uuid=case_uuid,
realizations=realizations,
field_identifier=field_identifiers[0],
stratigraphic_column_identifier=stratigraphic_column_identifier,
)
13 changes: 7 additions & 6 deletions backend_py/primary/primary/routers/polygons/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from webviz_pkg.core_utils.perf_timer import PerfTimer

from primary.auth.auth_helper import AuthHelper
from primary.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access
from primary.services.smda_access.stratigraphy_access import StratigraphyAccess
from primary.services.smda_access.drogon import DrogonSmdaAccess
from primary.services.smda_access import SmdaAccess
from primary.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy
from primary.services.sumo_access.case_inspector import CaseInspector
from primary.services.sumo_access.polygons_access import PolygonsAccess
Expand Down Expand Up @@ -34,14 +34,15 @@ async def get_polygons_directory(
polygons_dir = await access.get_polygons_directory_async()

case_inspector = CaseInspector.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
field_identifiers = await case_inspector.get_field_identifiers_async()
strat_column_identifier = await case_inspector.get_stratigraphic_column_identifier_async()
strat_access: Union[StratigraphyAccess, _mocked_stratigraphy_access.StratigraphyAccess]
smda_access: Union[SmdaAccess, DrogonSmdaAccess]

if strat_column_identifier == "DROGON_HAS_NO_STRATCOLUMN":
strat_access = _mocked_stratigraphy_access.StratigraphyAccess(authenticated_user.get_smda_access_token())
smda_access = DrogonSmdaAccess()
else:
strat_access = StratigraphyAccess(authenticated_user.get_smda_access_token())
strat_units = await strat_access.get_stratigraphic_units(strat_column_identifier)
smda_access = SmdaAccess(authenticated_user.get_smda_access_token(), field_identifier=field_identifiers[0])
strat_units = await smda_access.get_stratigraphic_units(strat_column_identifier)
sorted_stratigraphic_surfaces = sort_stratigraphic_names_by_hierarchy(strat_units)

return converters.to_api_polygons_directory(polygons_dir, sorted_stratigraphic_surfaces)
Expand Down
1 change: 1 addition & 0 deletions backend_py/primary/primary/routers/polygons/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PolygonsAttributeType(str, Enum):
PINCHOUT = "pinchout" # Values are pinchouts
SUBCROP = "subcrop" # Values are subcrops
FAULT_LINES = "fault_lines" # Values are fault lines
NAMED_AREA = "named_area" # Values are named areas, e.g. CCS containment polygons


class PolygonsMeta(BaseModel):
Expand Down
50 changes: 50 additions & 0 deletions backend_py/primary/primary/routers/seismic/converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from typing import List

import orjson
import numpy as np
import xtgeo

from . import schemas


def surface_to_float32_array(values: np.ndarray) -> List[float]:
values = values.astype(np.float32)
np.ma.set_fill_value(values, np.nan)
values = np.ma.filled(values)

# Rotate 90 deg left.
# This will cause the width of to run along the X axis
# and height of along Y axis (starting from bottom.)
values = np.rot90(values)

return values.flatten().tolist()


def to_api_surface_data(
xtgeo_surf: xtgeo.RegularSurface, property_values: np.ndarray
) -> schemas.SurfaceMeshAndProperty:
"""
Create API SurfaceData from xtgeo regular surface
"""
float32_mesh = surface_to_float32_array(xtgeo_surf.values)
float32_property = surface_to_float32_array(property_values)

return schemas.SurfaceMeshAndProperty(
x_ori=xtgeo_surf.xori,
y_ori=xtgeo_surf.yori,
x_count=xtgeo_surf.ncol,
y_count=xtgeo_surf.nrow,
x_inc=xtgeo_surf.xinc,
y_inc=xtgeo_surf.yinc,
x_min=xtgeo_surf.xmin,
x_max=xtgeo_surf.xmax,
y_min=xtgeo_surf.ymin,
y_max=xtgeo_surf.ymax,
mesh_value_min=xtgeo_surf.values.min(),
mesh_value_max=xtgeo_surf.values.max(),
property_value_min=property_values.min(),
property_value_max=property_values.max(),
rot_deg=xtgeo_surf.rotation,
mesh_data=orjson.dumps(float32_mesh).decode("utf-8"), # pylint: disable=maybe-no-member
property_data=orjson.dumps(float32_property).decode("utf-8"), # pylint: disable=maybe-no-member
)
20 changes: 20 additions & 0 deletions backend_py/primary/primary/routers/seismic/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,23 @@ class SeismicFenceData(BaseModel):
num_samples_per_trace: int
min_fence_depth: float
max_fence_depth: float


class SurfaceMeshAndProperty(BaseModel):
x_ori: float
y_ori: float
x_count: int
y_count: int
x_inc: float
y_inc: float
x_min: float
x_max: float
y_min: float
y_max: float
mesh_value_min: float
mesh_value_max: float
property_value_min: float
property_value_max: float
rot_deg: float
mesh_data: str
property_data: str
20 changes: 20 additions & 0 deletions backend_py/primary/primary/routers/surface/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from primary.services.utils.surface_intersect_with_polyline import XtgeoSurfaceIntersectionResult
from primary.services.utils.surface_to_float32 import surface_to_float32_numpy_array
from primary.services.utils.surface_to_png import surface_to_png_bytes_optimized
from primary.services.smda_access import StratigraphicUnit

from . import schemas

Expand Down Expand Up @@ -174,3 +175,22 @@ def to_api_surface_intersection(
z_points=xtgeo_surface_intersection.zval,
cum_lengths=xtgeo_surface_intersection.distance,
)


def to_api_stratigraphic_unit(
stratigraphic_unit: StratigraphicUnit,
) -> schemas.StratigraphicUnit:
return schemas.StratigraphicUnit(
identifier=stratigraphic_unit.identifier,
top=stratigraphic_unit.top,
base=stratigraphic_unit.base,
stratUnitLevel=stratigraphic_unit.strat_unit_level,
stratUnitType=stratigraphic_unit.strat_unit_type,
topAge=stratigraphic_unit.top_age,
baseAge=stratigraphic_unit.base_age,
stratUnitParent=stratigraphic_unit.strat_unit_parent,
colorR=stratigraphic_unit.color_r,
colorG=stratigraphic_unit.color_g,
colorB=stratigraphic_unit.color_b,
lithologyType=stratigraphic_unit.lithology_type,
)
31 changes: 25 additions & 6 deletions backend_py/primary/primary/routers/surface/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

from primary.services.sumo_access.case_inspector import CaseInspector
from primary.services.sumo_access.surface_access import SurfaceAccess
from primary.services.smda_access.stratigraphy_access import StratigraphyAccess, StratigraphicUnit
from primary.services.smda_access import SmdaAccess, StratigraphicUnit
from primary.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy
from primary.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access
from primary.services.smda_access.drogon import DrogonSmdaAccess
from primary.services.utils.statistic_function import StatisticFunction
from primary.services.utils.surface_intersect_with_polyline import intersect_surface_with_polyline
from primary.services.utils.authenticated_user import AuthenticatedUser
Expand Down Expand Up @@ -295,22 +295,41 @@ async def get_misfit_surface_data(
raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED)


@router.get("/stratigraphic_units")
async def get_stratigraphic_units(
# fmt:off
response: Response,
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
case_uuid: Annotated[str, Query(description="Sumo case uuid")],
# fmt:on
) -> list[schemas.StratigraphicUnit]:
perf_metrics = ResponsePerfMetrics(response)

strat_units = await _get_stratigraphic_units_for_case_async(authenticated_user, case_uuid)
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
) -> list[StratigraphicUnit]:
perf_metrics = PerfMetrics()

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

strat_access: StratigraphyAccess | _mocked_stratigraphy_access.StratigraphyAccess
smda_access: SmdaAccess | DrogonSmdaAccess
if strat_column_identifier == "DROGON_HAS_NO_STRATCOLUMN":
strat_access = _mocked_stratigraphy_access.StratigraphyAccess(authenticated_user.get_smda_access_token())
smda_access = DrogonSmdaAccess()
else:
strat_access = StratigraphyAccess(authenticated_user.get_smda_access_token())
smda_access = SmdaAccess(authenticated_user.get_smda_access_token(), field_identifier=field_identifiers[0])

strat_units = await strat_access.get_stratigraphic_units(strat_column_identifier)
strat_units = await smda_access.get_stratigraphic_units(strat_column_identifier)
perf_metrics.record_lap("get-strat-units")

LOGGER.info(f"Got stratigraphic units for case in : {perf_metrics.to_string()}")
Expand Down
15 changes: 15 additions & 0 deletions backend_py/primary/primary/routers/surface/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,18 @@ class SurfaceRealizationSampleValues(BaseModel):
class PointSetXY(BaseModel):
x_points: list[float]
y_points: list[float]


class StratigraphicUnit(BaseModel):
identifier: str
top: str
base: str
stratUnitLevel: int
stratUnitType: str
topAge: int | float
baseAge: int | float
stratUnitParent: str | None
colorR: int
colorG: int
colorB: int
lithologyType: int | float | str = "unknown"
3 changes: 3 additions & 0 deletions backend_py/primary/primary/routers/well/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def convert_wellbore_pick_to_schema(wellbore_pick: WellborePick) -> schemas.Well
md=wellbore_pick.md,
mdMsl=wellbore_pick.md_msl,
uniqueWellboreIdentifier=wellbore_pick.unique_wellbore_identifier,
wellboreUuid=wellbore_pick.wellbore_uuid,
pickIdentifier=wellbore_pick.pick_identifier,
confidence=wellbore_pick.confidence,
depthReferencePoint=wellbore_pick.depth_reference_point,
Expand Down Expand Up @@ -57,6 +58,8 @@ def convert_wellbore_header_to_schema(
wellNorthing=drilled_wellbore_header.well_northing,
depthReferencePoint=drilled_wellbore_header.depth_reference_point,
depthReferenceElevation=drilled_wellbore_header.depth_reference_elevation,
wellborePurpose=(drilled_wellbore_header.wellbore_purpose if drilled_wellbore_header.wellbore_purpose else ""),
wellboreStatus=drilled_wellbore_header.wellbore_status if drilled_wellbore_header.wellbore_status else "",
)


Expand Down
Loading

0 comments on commit 20542c9

Please sign in to comment.