Skip to content

Commit

Permalink
Merge remote-tracking branch 'equinor/main' into new-2d-viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Oct 22, 2024
2 parents 51d0164 + 65d6fd3 commit 27d38a2
Show file tree
Hide file tree
Showing 46 changed files with 1,795 additions and 1,096 deletions.
48 changes: 48 additions & 0 deletions backend_py/primary/primary/routers/vfp/converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from primary.services.sumo_access.vfp_types import VfpProdTable, VfpInjTable, VfpType

from . import schemas


def to_api_table_definitions(
vfp_table: VfpProdTable | VfpInjTable,
) -> schemas.VfpProdTable | schemas.VfpInjTable:
"""Converts the vfp table definitions from the sumo service to the API format"""
if isinstance(vfp_table, VfpProdTable):
return schemas.VfpProdTable(
tableNumber=vfp_table.table_number,
datum=vfp_table.datum,
thpType=vfp_table.thp_type,
wfrType=vfp_table.wfr_type,
gfrType=vfp_table.gfr_type,
alqType=vfp_table.alq_type,
flowRateType=vfp_table.flow_rate_type,
unitType=vfp_table.unit_type,
tabType=vfp_table.tab_type,
thpValues=vfp_table.thp_values,
wfrValues=vfp_table.wfr_values,
gfrValues=vfp_table.gfr_values,
alqValues=vfp_table.alq_values,
flowRateValues=vfp_table.flow_rate_values,
bhpValues=vfp_table.bhp_values,
flowRateUnit=vfp_table.flow_rate_unit,
thpUnit=vfp_table.thp_unit,
wfrUnit=vfp_table.wfr_unit,
gfrUnit=vfp_table.gfr_unit,
alqUnit=vfp_table.alq_unit,
bhpUnit=vfp_table.bhp_unit,
)
if isinstance(vfp_table, VfpInjTable):
return schemas.VfpInjTable(
tableNumber=vfp_table.table_number,
datum=vfp_table.datum,
flowRateType=vfp_table.flow_rate_type,
unitType=vfp_table.unit_type,
tabType=vfp_table.tab_type,
thpValues=vfp_table.thp_values,
flowRateValues=vfp_table.flow_rate_values,
bhpValues=vfp_table.bhp_values,
flowRateUnit=vfp_table.flow_rate_unit,
thpUnit=vfp_table.thp_unit,
bhpUnit=vfp_table.bhp_unit,
)
raise ValueError("Unhandled VFP table type when converting to schema")
12 changes: 6 additions & 6 deletions backend_py/primary/primary/routers/vfp/router.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import logging
from typing import List

from fastapi import APIRouter, Depends, Query, Response, HTTPException

from primary.auth.auth_helper import AuthHelper
from primary.utils.response_perf_metrics import ResponsePerfMetrics
from primary.services.sumo_access.vfp_access import VfpAccess
from primary.services.sumo_access.vfp_types import VfpProdTable
from primary.services.sumo_access.vfp_types import VfpProdTable, VfpInjTable
from primary.services.utils.authenticated_user import AuthenticatedUser

from . import schemas
from . import converters

LOGGER = logging.getLogger(__name__)

Expand All @@ -25,7 +25,7 @@ async def get_vfp_table_names(
ensemble_name: str = Query(description="Ensemble name"),
realization: int = Query(description="Realization"),
# fmt:on
) -> List[str]:
) -> list[str]:
perf_metrics = ResponsePerfMetrics(response)

vfp_access = await VfpAccess.from_case_uuid_async(
Expand All @@ -49,15 +49,15 @@ async def get_vfp_table(
realization: int = Query(description="Realization"),
vfp_table_name: str = Query(description="VFP table name")
# fmt:on
) -> VfpProdTable:
) -> schemas.VfpProdTable | schemas.VfpInjTable:
perf_metrics = ResponsePerfMetrics(response)

vfp_access = await VfpAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
perf_metrics.record_lap("get-access")
try:
vfp_table: VfpProdTable = await vfp_access.get_vfpprod_table_from_tagname(
vfp_table: VfpProdTable | VfpInjTable = await vfp_access.get_vfp_table_from_tagname(
tagname=vfp_table_name, realization=realization
)
except NotImplementedError as ex:
Expand All @@ -66,4 +66,4 @@ async def get_vfp_table(
perf_metrics.record_lap("get-vfp-table")
LOGGER.info(f"VFP table loaded in: {perf_metrics.to_string()}")

return vfp_table
return converters.to_api_table_definitions(vfp_table)
43 changes: 43 additions & 0 deletions backend_py/primary/primary/routers/vfp/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from pydantic import BaseModel

from primary.services.sumo_access.vfp_types import THP, WFR, GFR, ALQ, FlowRateType, UnitType, TabType


class VfpProdTable(BaseModel):
isProdTable: bool = True
tableNumber: int
datum: float
thpType: THP
wfrType: WFR
gfrType: GFR
alqType: ALQ
flowRateType: FlowRateType
unitType: UnitType
tabType: TabType
thpValues: list[float]
wfrValues: list[float]
gfrValues: list[float]
alqValues: list[float]
flowRateValues: list[float]
bhpValues: list[float]
flowRateUnit: str
thpUnit: str
wfrUnit: str
gfrUnit: str
alqUnit: str
bhpUnit: str


class VfpInjTable(BaseModel):
isInjTable: bool = True
tableNumber: int
datum: float
flowRateType: FlowRateType
unitType: UnitType
tabType: TabType
thpValues: list[float]
flowRateValues: list[float]
bhpValues: list[float]
flowRateUnit: str
thpUnit: str
bhpUnit: str
41 changes: 41 additions & 0 deletions backend_py/primary/primary/routers/well_completions/converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from primary.services.sumo_access.well_completions_types import (
Completions,
WellCompletionsData,
WellCompletionsUnitInfo,
WellCompletionsUnits,
WellCompletionsWell,
WellCompletionsZone,
)

from . import schemas


def convert_completions_to_schema(completions: Completions) -> schemas.Completions:
return schemas.Completions(
sortedCompletionDateIndices=completions.sorted_completion_date_indices,
open=completions.open,
shut=completions.shut,
khMean=completions.kh_mean,
khMin=completions.kh_min,
khMax=completions.kh_max,
)


def convert_well_to_schema(well: WellCompletionsWell) -> schemas.WellCompletionsWell:
completions = {k: convert_completions_to_schema(v) for k, v in well.completions.items()}
return schemas.WellCompletionsWell(name=well.name, attributes=well.attributes, completions=completions)


def convert_unit_info_to_schema(unit_info: WellCompletionsUnitInfo) -> schemas.WellCompletionsUnitInfo:
return schemas.WellCompletionsUnitInfo(unit=unit_info.unit, decimalPlaces=unit_info.decimalPlaces)


def convert_units_to_schema(units: WellCompletionsUnits) -> schemas.WellCompletionsUnits:
return schemas.WellCompletionsUnits(kh=convert_unit_info_to_schema(units.kh))


def convert_zone_to_schema(zone: WellCompletionsZone) -> schemas.WellCompletionsZone:
return schemas.WellCompletionsZone(
name=zone.name,
subzones=[convert_zone_to_schema(subzone) for subzone in zone.subzones] if zone.subzones else None,
)
47 changes: 37 additions & 10 deletions backend_py/primary/primary/routers/well_completions/router.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,58 @@
from typing import Optional
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query

from primary.auth.auth_helper import AuthHelper
from primary.services.utils.authenticated_user import AuthenticatedUser

from primary.services.sumo_access.well_completions_access import WellCompletionsAccess
from primary.services.sumo_access.well_completions_types import WellCompletionsData
from primary.services.well_completions_assembler.well_completions_assembler import WellCompletionsAssembler

from . import converters
from . import schemas

router = APIRouter()


@router.get("/well_completions_data/")
async def get_well_completions_data(
# fmt:off
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
realization: Optional[int] = Query(None, description="Optional realization to include. If not specified, all realizations will be returned."),
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")],
realization: Annotated[int | list[int] | None, Query( description="Optional realizations to include. Provide single realization or list of realizations. If not specified, all realizations will be returned.")] = None,
# fmt:on
) -> WellCompletionsData:
) -> schemas.WellCompletionsData:
access = await WellCompletionsAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
well_completions_data = access.get_well_completions_data(realization=realization)

if not well_completions_data:
well_completions_assembler = WellCompletionsAssembler(well_completions_access=access)

# Fetch and initialize table data
if isinstance(realization, int):
await well_completions_assembler.fetch_and_initialize_well_completions_single_realization_table_data_async(
realization=realization
)
elif realization is not None and len(realization) == 1:
await well_completions_assembler.fetch_and_initialize_well_completions_single_realization_table_data_async(
realization=realization[0]
)
else:
await well_completions_assembler.fetch_and_initialize_well_completions_table_data_async(
realizations=realization
)

# Create well completions data object
data = well_completions_assembler.create_well_completions_data()

if not data:
raise HTTPException(status_code=404, detail="Well completions data not found")

return well_completions_data
return schemas.WellCompletionsData(
version=data.version,
units=converters.convert_units_to_schema(data.units),
zones=[converters.convert_zone_to_schema(zone) for zone in data.zones],
sortedCompletionDates=data.sorted_completion_dates,
wells=[converters.convert_well_to_schema(well) for well in data.wells],
)
42 changes: 42 additions & 0 deletions backend_py/primary/primary/routers/well_completions/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from pydantic import BaseModel

from primary.services.sumo_access.well_completions_types import WellCompletionsAttributeType


class Completions(BaseModel):
sortedCompletionDateIndices: list[int]
open: list[float]
shut: list[float]
khMean: list[float]
khMin: list[float]
khMax: list[float]


class WellCompletionsWell(BaseModel):
name: str
attributes: dict[str, WellCompletionsAttributeType]
completions: dict[str, Completions]


class WellCompletionsZone(BaseModel):
name: str
subzones: list["WellCompletionsZone"] | None = None


class WellCompletionsUnitInfo(BaseModel):
unit: str
decimalPlaces: int


class WellCompletionsUnits(BaseModel):
kh: WellCompletionsUnitInfo


class WellCompletionsData(BaseModel):
"""Type definition for well completions data"""

version: str
units: WellCompletionsUnits
zones: list[WellCompletionsZone]
sortedCompletionDates: list[str]
wells: list[WellCompletionsWell]
Loading

0 comments on commit 27d38a2

Please sign in to comment.