Skip to content

Commit

Permalink
Inplace meta. first attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKallekleiv committed Jul 1, 2024
1 parent fe38425 commit de81ad7
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 42 deletions.
10 changes: 5 additions & 5 deletions backend_py/primary/primary/routers/inplace_volumetrics/router.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List

from fastapi import APIRouter, Depends, Query, Body
from primary.services.sumo_access.inplace_volumetrics_access import InplaceVolumetricsAccess


# from primary.services.sumo_access.inplace_volumetrics_access import InplaceVolumetricsAccess
from primary.services.inplace_volumetrics_provider.inplace_volumetrics_provider import InplaceVolumetricsProvider
from primary.services.sumo_access.inplace_volumetrics_acces_NEW import InplaceVolumetricsAccess
from primary.services.utils.authenticated_user import AuthenticatedUser
from primary.auth.auth_helper import AuthHelper

Expand All @@ -21,11 +21,11 @@ async def get_table_definitions(
ensemble_name: str = Query(description="Ensemble name"),
) -> List[schemas.InplaceVolumetricsTableDefinition]:
"""Get the volumetric tables definitions for a given ensemble."""

access = await InplaceVolumetricsAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
table_names = await access.get_inplace_volumetrics_table_definitions_async()
provider = InplaceVolumetricsProvider(access)
table_names = await provider.get_volumetric_table_metadata()
return table_names


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import List, Union, Optional
from enum import Enum
from enum import Enum,StrEnum

from pydantic import BaseModel

Expand All @@ -18,14 +18,19 @@ class InplaceVolumetricsIndex(BaseModel):
index_name: InplaceVolumetricsIndexNames
values: List[Union[str, int]]

class FluidZone(StrEnum):
OIL = "Oil"
GAS = "Gas"
Water = "Water" # TODO: Remove or keep?

class InplaceVolumetricsTableDefinition(BaseModel):
"""Definition of a volumetric table"""

name: str
indexes: List[InplaceVolumetricsIndex]
table_name: str
fluid_zones: List[FluidZone]
result_names: List[str]

indexes: List[InplaceVolumetricsIndex]


class InplaceVolumetricDataEntry(BaseModel):
result_values: List[float]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Any, Dict, List, Sequence

import asyncio
from pydantic import BaseModel
import pyarrow as pa
import pyarrow.compute as pc

Expand All @@ -23,6 +24,15 @@
# - InplaceVolumetricsConstructor
# - InplaceVolumetricsFabricator
# - InplaceVolumetricsDataManufacturer

class InplaceVolumetricsTableDefinition(BaseModel):
"""Definition of a volumetric table"""

table_name: str
fluid_zones: List[FluidZone]
result_names: List[str]
indexes: List[InplaceVolumetricsIndex]

class InplaceVolumetricsProvider:
"""
This class provides an interface for interacting with definitions used in front-end for assembling and providing
Expand All @@ -47,24 +57,48 @@ def __init__(self, inplace_volumetrics_access: InplaceVolumetricsAccess):
# TODO: When having metadata, provide all column names, and the get the possible properties from the response names
# Provide the available properties from metadata, without suffix and provide possible FluidZones
async def get_volumetric_table_metadata(self) -> Any:
raw_volumetric_column_names = await self._inplace_volumetrics_access.get_volumetric_column_names_async()

fluid_zones = get_fluid_zones(raw_volumetric_column_names)
volume_names = get_volume_names_from_raw_volumetric_column_names(raw_volumetric_column_names)
available_property_names = get_available_properties_from_volume_names(volume_names)
responses = list(set([volume_names+available_property_names]))
vol_table_names = await self._inplace_volumetrics_access.get_inplace_volumetrics_table_names_async()

async def get_named_inplace_volumetrics_table_async(table_name:str) -> Dict[str, pa.Table]:
return {table_name: await self._inplace_volumetrics_access.get_inplace_volumetrics_table_async(table_name)}

tasks = [asyncio.create_task(get_named_inplace_volumetrics_table_async(vol_table_name)) for vol_table_name in vol_table_names]
tables = await asyncio.gather(*tasks)
print(tables, len(tables))


tables_info: List[InplaceVolumetricsTableDefinition] = []
for table_result in tables:
table_name, table = list(table_result.items())[0]

# Get raw volume names without index columns
raw_volumetric_column_names = [column_name for column_name in table.column_names if column_name not in self._inplace_volumetrics_access._expected_index_columns+ ["REAL"]]


fluid_zones = get_fluid_zones(raw_volumetric_column_names)
volume_names = get_volume_names_from_raw_volumetric_column_names(raw_volumetric_column_names)

available_property_names = get_available_properties_from_volume_names(volume_names)
result_names = volume_names + available_property_names
indexes = []
for index_name in self._inplace_volumetrics_access._expected_index_columns:
if index_name in table.column_names:
indexes.append(InplaceVolumetricsIndex(index_name=index_name, values=table[index_name].unique().to_pylist()))
tables_info.append(InplaceVolumetricsTableDefinition(table_name=table_name, fluid_zones=fluid_zones, result_names=result_names, indexes=indexes))
return tables_info

# TODO: Consider
# responses_info: Dict[str, List[FluidZone]] = {}
# I.e.: responses_info["STOIIP"] = [FluidZone.OIL], etc.

return {
"name": "INSERT TABLE NAME",
"fluid_zones": fluid_zones,
"responses": responses,
}
return [{
"name": "Geogrid",
"fluid_zones": ["OIL","GAS","WATER"],
"responses": ["BULK","NET","STOIIP","SW","BO"],
"index": [{"ZONE":["A","B"],"REGION":["NORTH","SOUTH"],"FACIES":["SAND","SHALE"],"LICENSE":["LIC1","LIC2"]}],
}]


async def get_aggregated_volumetric_table_data_async(
self,
table_name: str,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ async def from_case_uuid_async(
case: Case = await create_sumo_case_async(client=sumo_client, case_uuid=case_uuid, want_keepalive_pit=False)
return InplaceVolumetricsAccess(case=case, case_uuid=case_uuid, iteration_name=iteration_name)

async def get_inplace_volumetrics_table_names_async(
self) -> List[str]:
vol_table_collection = self._case.tables.filter(
aggregation="collection",
tagname=["vol", "volumes", "inplace"],
iteration=self._iteration_name,
)
table_names = await vol_table_collection.names_async
return table_names
async def get_inplace_volumetrics_table_no_throw_async(
self, table_name: str, column_names: Optional[set[str]] = None
) -> Optional[pa.Table]:
Expand Down Expand Up @@ -97,31 +106,33 @@ async def get_inplace_volumetrics_table_async(
# Expected columns
# NOTE: "REAL" is not an index in metadata, but is an expected column in the tables from collection
expected_table_index_columns = set(["ZONE", "REGION", "FACIES", "REAL"])
all_expected_columns = expected_table_index_columns + column_names
all_expected_columns = expected_table_index_columns
if column_names is not None:
all_expected_columns+column_names

# Find column names not among collection columns
collection_columns = await vol_table_collection.columns_async
if set(collection_columns) != all_expected_columns:
missing_result_names = all_expected_columns - set(collection_columns)
raise InvalidDataError(
f"Missing results: {missing_result_names}, in the volumetric table {self._case_uuid}, {table_name}",
Service.SUMO,
)
# if set(collection_columns) != all_expected_columns:
# missing_result_names = all_expected_columns - set(collection_columns)
# raise InvalidDataError(
# f"Missing results: {missing_result_names}, in the volumetric table {self._case_uuid}, {table_name}",
# Service.SUMO,
# )

# Assemble tables into a single table
vol_table: pa.Table = await self._assemble_volumetrics_table_collection_into_single_table_async(
vol_table_collection=vol_table_collection,
table_name=table_name,
column_names=column_names,
)

# Validate the table columns
if set(vol_table.column_names) != all_expected_columns:
missing_columns = all_expected_columns - set(vol_table.column_names)
raise InvalidDataError(
f"Missing columns: {missing_columns}, in the volumetric table {self._case_uuid}, {table_name}",
Service.SUMO,
)
# if set(vol_table.column_names) != all_expected_columns:
# missing_columns = all_expected_columns - set(vol_table.column_names)
# raise InvalidDataError(
# f"Missing columns: {missing_columns}, in the volumetric table {self._case_uuid}, {table_name}",
# Service.SUMO,
# )

return vol_table

Expand Down Expand Up @@ -173,7 +184,7 @@ async def _assemble_volumetrics_table_collection_into_single_table_async(
)

response_name = list(response_name_set)[0]
if response_name not in column_names:
if column_names and response_name not in column_names:
raise InvalidDataError(
f"Table {response_table.name} returns response {response_name}, which is not among columns of interest: {column_names}",
Service.SUMO,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from enum import Enum
from io import BytesIO
from typing import Dict, List, Optional, Sequence, Union, Tuple
from typing import Dict, List, Optional, Sequence, Union

import asyncio
import pyarrow as pa
Expand All @@ -18,8 +18,11 @@
MultipleDataMatchesError,
)

from ._helpers import SumoEnsemble

from fmu.sumo.explorer.objects import Case


from ._helpers import create_sumo_client, create_sumo_case_async

# Allowed categories (index column names) for the volumetric tables
ALLOWED_INDEX_COLUMN_NAMES = ["ZONE", "REGION", "FACIES"] # , "LICENSE"]
Expand Down Expand Up @@ -109,7 +112,17 @@ class InplaceVolumetricData(BaseModel):
LOGGER = logging.getLogger(__name__)


class InplaceVolumetricsAccess(SumoEnsemble):
class InplaceVolumetricsAccess:
def __init__(self, case: Case, case_uuid: str):
self._case: Case = case
self._case_uuid: str = case_uuid

@classmethod
async def from_case_uuid_async(cls, access_token: str, case_uuid: str) -> "InplaceVolumetricsAccess":
sumo_client = create_sumo_client(access_token)
case: Case = await create_sumo_case_async(client=sumo_client, case_uuid=case_uuid, want_keepalive_pit=False)
return cls(case=case, case_uuid=case_uuid)

async def get_inplace_volumetrics_table_definitions_async(self) -> List[InplaceVolumetricsTableDefinition]:
"""Retrieve the table definitions for the volumetric tables"""

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/modules/registerAllModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import "./3DViewer/registerModule";
import "./DistributionPlot/registerModule";
import "./FlowNetwork/registerModule";
// import "./Grid3DVTK/registerModule";
import "./InplaceVolumetrics/registerModule";
import "./InplaceVolumetricsTable/registerModule";
// import "./InplaceVolumetrics/registerModule";
// import "./InplaceVolumetricsTable/registerModule";
import "./Intersection/registerModule";
import "./Map/registerModule";
import "./ParameterDistributionMatrix/registerModule";
Expand Down

0 comments on commit de81ad7

Please sign in to comment.