Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions backend_py/primary/primary/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from primary.routers.parameters.router import router as parameters_router
from primary.routers.polygons.router import router as polygons_router
from primary.routers.pvt.router import router as pvt_router
from primary.routers.relperm.router import router as relperm_router
from primary.routers.rft.router import router as rft_router
from primary.routers.seismic.router import router as seismic_router
from primary.routers.surface.router import router as surface_router
Expand Down Expand Up @@ -97,6 +98,7 @@ async def shutdown_event_async() -> None:
app.include_router(grid3d_router, prefix="/grid3d", tags=["grid3d"])
app.include_router(flow_network_router, prefix="/flow_network", tags=["flow_network"])
app.include_router(pvt_router, prefix="/pvt", tags=["pvt"])
app.include_router(relperm_router, prefix="/relperm", tags=["relperm"])
app.include_router(well_completions_router, prefix="/well_completions", tags=["well_completions"])
app.include_router(well_router, prefix="/well", tags=["well"])
app.include_router(seismic_router, prefix="/seismic", tags=["seismic"])
Expand Down
75 changes: 75 additions & 0 deletions backend_py/primary/primary/routers/relperm/converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from primary.services.relperm_assembler.relperm_assembler import (
RelPermTableInfo,
RelPermSaturationAxis,
RelPermRealizationData,
CurveData,
RelPermStatisticalData,
StatisticalCurveData,
)

from . import schemas


def to_api_relperm_table_info(table_info: RelPermTableInfo) -> schemas.RelPermTableInfo:

return schemas.RelPermTableInfo(
table_name=table_info.table_name,
saturation_axes=[to_api_relperm_saturation_axis(axis) for axis in table_info.saturation_axes],
satnums=table_info.satnums,
)


def to_api_relperm_saturation_axis(axis: RelPermSaturationAxis) -> schemas.RelPermSaturationAxis:

return schemas.RelPermSaturationAxis(
saturation_name=axis.saturation_name,
relperm_curve_names=axis.relperm_curve_names,
capillary_pressure_curve_names=axis.capillary_pressure_curve_names,
)


def to_api_curve_data(data: CurveData) -> schemas.CurveData:

return schemas.CurveData(
curve_name=data.curve_name,
curve_values=data.curve_values.tolist(),
)


def to_api_relperm_realization_data(
data: RelPermRealizationData,
) -> schemas.RelPermRealizationData:

return schemas.RelPermRealizationData(
curve_data_arr=[to_api_curve_data(curve_data) for curve_data in data.curve_data_arr],
realization_id=data.realization_id,
saturation_name=data.saturation_name,
saturation_values=data.saturation_values.tolist(),
saturation_number=data.saturation_number,
)


def to_api_statistical_curve_data(
data: StatisticalCurveData,
) -> schemas.StatisticalCurveData:

return schemas.StatisticalCurveData(
curve_name=data.curve_name,
mean_values=data.mean_values.tolist(),
min_values=data.min_values.tolist(),
max_values=data.max_values.tolist(),
p10_values=data.p10_values.tolist(),
p90_values=data.p90_values.tolist(),
)


def to_api_relperm_statistical_data(
data: RelPermStatisticalData,
) -> schemas.RelPermStatisticalData:

return schemas.RelPermStatisticalData(
saturation_number=data.saturation_number,
saturation_name=data.saturation_name,
saturation_values=data.saturation_values.tolist(),
curve_statistics=[to_api_statistical_curve_data(stat) for stat in data.curve_statistics],
)
102 changes: 102 additions & 0 deletions backend_py/primary/primary/routers/relperm/router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import logging
from typing import Annotated, List

from fastapi import APIRouter, Depends, Query

from primary.auth.auth_helper import AuthHelper
from primary.services.sumo_access.relperm_access import RelPermAccess
from primary.services.relperm_assembler.relperm_assembler import RelPermAssembler
from primary.services.utils.authenticated_user import AuthenticatedUser
from primary.utils.query_string_utils import decode_uint_list_str

from . import schemas
from . import converters

LOGGER = logging.getLogger(__name__)

router = APIRouter()


@router.get("/relperm_table_names")
async def get_relperm_table_names(
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
case_uuid: Annotated[str, Query(description="Sumo case uuid")],
ensemble_name: Annotated[str, Query(description="Ensemble name")],
) -> List[str]:
access = RelPermAccess.from_iteration_name(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
return await access.get_relperm_table_names_async()


@router.get("/relperm_table_info")
async def get_relperm_table_info(
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
case_uuid: Annotated[str, Query(description="Sumo case uuid")],
ensemble_name: Annotated[str, Query(description="Ensemble name")],
table_name: Annotated[str, Query(description="Table name")],
) -> schemas.RelPermTableInfo:
access = RelPermAccess.from_iteration_name(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
assembler = RelPermAssembler(access)
relperm_table_info = await assembler.get_relperm_table_info_async(table_name)

return converters.to_api_relperm_table_info(relperm_table_info)


@router.get("/relperm_realizations_curve_data")
async def get_relperm_realizations_curve_data(
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
case_uuid: Annotated[str, Query(description="Sumo case uuid")],
ensemble_name: Annotated[str, Query(description="Ensemble name")],
table_name: Annotated[str, Query(description="Table name")],
saturation_axis_name: Annotated[str, Query(description="Saturation axis name")],
curve_names: Annotated[List[str], Query(description="Curve names")],
satnum: Annotated[int, Query(description="Satnum")],
realizations_encoded_as_uint_list_str: Annotated[
str | None,
Query(
description="Optional list of realizations encoded as string to include. If not specified, all realizations will be included."
),
] = None,
) -> List[schemas.RelPermRealizationData]:
realizations: list[int] | None = None
if realizations_encoded_as_uint_list_str:
realizations = decode_uint_list_str(realizations_encoded_as_uint_list_str)

access = RelPermAccess.from_iteration_name(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
assembler = RelPermAssembler(access)
relperm_data = await assembler.get_relperm_realization_data_async(
table_name, saturation_axis_name, curve_names, satnum, realizations
)

return [converters.to_api_relperm_realization_data(data) for data in relperm_data]


# Same syntax as above including realizations , but for statistical data
@router.get("/relperm_statistical_curve_data")
async def get_relperm_statistical_curve_data(
authenticated_user: Annotated[AuthenticatedUser, Depends(AuthHelper.get_authenticated_user)],
case_uuid: Annotated[str, Query(description="Sumo case uuid")],
ensemble_name: Annotated[str, Query(description="Ensemble name")],
table_name: Annotated[str, Query(description="Table name")],
saturation_axis_name: Annotated[str, Query(description="Saturation axis name")],
curve_names: Annotated[List[str], Query(description="Curve names")],
satnum: Annotated[int, Query(description="Satnum")],
realizations_encoded_as_uint_list_str: Annotated[
str | None,
Query(
description="Optional list of realizations encoded as string to include. If not specified, all realizations will be included."
),
] = None,
) -> schemas.RelPermStatisticalData | None:
realizations: list[int] | None = None
if realizations_encoded_as_uint_list_str:
realizations = decode_uint_list_str(realizations_encoded_as_uint_list_str)

access = RelPermAccess.from_iteration_name(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
assembler = RelPermAssembler(access)
stat_data = await assembler.get_relperm_statistical_data_async(
table_name, saturation_axis_name, curve_names, satnum, realizations
)

if stat_data is None:
return None
return converters.to_api_relperm_statistical_data(stat_data)
45 changes: 45 additions & 0 deletions backend_py/primary/primary/routers/relperm/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from enum import StrEnum
from typing import List, Dict

from pydantic import BaseModel


class RelPermSaturationAxis(BaseModel):
saturation_name: str
relperm_curve_names: List[str]
capillary_pressure_curve_names: List[str]


class RelPermTableInfo(BaseModel):
table_name: str
saturation_axes: List[RelPermSaturationAxis]
satnums: List[int]


class CurveData(BaseModel):
curve_name: str
curve_values: List[float]


class RelPermRealizationData(BaseModel):
curve_data_arr: List[CurveData]
realization_id: int
saturation_name: str
saturation_values: List[float]
saturation_number: int


class StatisticalCurveData(BaseModel):
curve_name: str
mean_values: list[float]
min_values: list[float]
max_values: list[float]
p10_values: list[float]
p90_values: list[float]


class RelPermStatisticalData(BaseModel):
saturation_number: int
saturation_name: str
saturation_values: list[float]
curve_statistics: List[StatisticalCurveData]
Loading
Loading