Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKallekleiv committed Nov 17, 2023
1 parent 5ac7e95 commit e9636cb
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 137 deletions.
108 changes: 27 additions & 81 deletions backend/src/backend/primary/routers/surface/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,18 @@ async def get_surface_directory(
)
sumo_surf_dir = await surface_access.get_surface_directory_async()

case_inspector = await SumoCase.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid
)
case_inspector = await SumoCase.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
strat_column_identifier = await case_inspector.get_stratigraphic_column_identifier()
strat_access: Union[
StratigraphyAccess, _mocked_stratigraphy_access.StratigraphyAccess
]
strat_access: Union[StratigraphyAccess, _mocked_stratigraphy_access.StratigraphyAccess]

if strat_column_identifier == "DROGON_HAS_NO_STRATCOLUMN":
strat_access = _mocked_stratigraphy_access.StratigraphyAccess(
authenticated_user.get_smda_access_token()
)
strat_access = _mocked_stratigraphy_access.StratigraphyAccess(authenticated_user.get_smda_access_token())
else:
strat_access = StratigraphyAccess(authenticated_user.get_smda_access_token())
strat_units = await strat_access.get_stratigraphic_units(strat_column_identifier)
sorted_stratigraphic_surfaces = sort_stratigraphic_names_by_hierarchy(strat_units)

return converters.to_api_surface_directory(
sumo_surf_dir, sorted_stratigraphic_surfaces
)
return converters.to_api_surface_directory(sumo_surf_dir, sorted_stratigraphic_surfaces)


@router.get("/realization_surface_data/")
Expand All @@ -71,15 +63,11 @@ async def get_realization_surface_data(
realization_num: int = Query(description="Realization number"),
name: str = Query(description="Surface name"),
attribute: str = Query(description="Surface attribute"),
time_or_interval: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceData:
perf_metrics = PerfMetrics(response)

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
xtgeo_surf = await access.get_realization_surface_data_async(
real_num=realization_num,
name=name,
Expand All @@ -105,24 +93,16 @@ async def get_statistical_surface_data(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
statistic_function: schemas.SurfaceStatisticFunction = Query(
description="Statistics to calculate"
),
statistic_function: schemas.SurfaceStatisticFunction = Query(description="Statistics to calculate"),
name: str = Query(description="Surface name"),
attribute: str = Query(description="Surface attribute"),
time_or_interval: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceData:
perf_metrics = PerfMetrics(response)

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)

service_stat_func_to_compute = StatisticFunction.from_string_value(
statistic_function
)
service_stat_func_to_compute = StatisticFunction.from_string_value(statistic_function)
if service_stat_func_to_compute is None:
raise HTTPException(status_code=404, detail="Invalid statistic requested")

Expand All @@ -137,9 +117,7 @@ async def get_statistical_surface_data(
if not xtgeo_surf:
raise HTTPException(status_code=404, detail="Could not find or compute surface")

surf_data_response: schemas.SurfaceData = converters.to_api_surface_data_as_float32(
xtgeo_surf
)
surf_data_response: schemas.SurfaceData = converters.to_api_surface_data_as_float32(xtgeo_surf)
perf_metrics.record_lap("convert")

LOGGER.debug(f"Calculated statistical surface in: {perf_metrics.to_string()}")
Expand All @@ -156,15 +134,11 @@ async def get_realization_surface_data_as_png(
realization_num: int = Query(description="Realization number"),
name: str = Query(description="Surface name"),
attribute: str = Query(description="Surface attribute"),
time_or_interval: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceDataPng:
perf_metrics = PerfMetrics(response)

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
xtgeo_surf = await access.get_realization_surface_data_async(
real_num=realization_num,
name=name,
Expand All @@ -190,24 +164,16 @@ async def get_statistical_surface_data_as_png(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
statistic_function: schemas.SurfaceStatisticFunction = Query(
description="Statistics to calculate"
),
statistic_function: schemas.SurfaceStatisticFunction = Query(description="Statistics to calculate"),
name: str = Query(description="Surface name"),
attribute: str = Query(description="Surface attribute"),
time_or_interval: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceDataPng:
perf_metrics = PerfMetrics(response)

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)

service_stat_func_to_compute = StatisticFunction.from_string_value(
statistic_function
)
service_stat_func_to_compute = StatisticFunction.from_string_value(statistic_function)
if service_stat_func_to_compute is None:
raise HTTPException(status_code=404, detail="Invalid statistic requested")

Expand Down Expand Up @@ -243,15 +209,11 @@ async def get_property_surface_resampled_to_static_surface(
realization_num_property: int = Query(description="Realization number"),
name_property: str = Query(description="Surface name"),
attribute_property: str = Query(description="Surface attribute"),
time_or_interval_property: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval_property: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceData:
perf_metrics = PerfMetrics(response)

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
xtgeo_surf_mesh = await access.get_realization_surface_data_async(
real_num=realization_num_mesh, name=name_mesh, attribute=attribute_mesh
)
Expand All @@ -268,14 +230,10 @@ async def get_property_surface_resampled_to_static_surface(
if not xtgeo_surf_mesh or not xtgeo_surf_property:
raise HTTPException(status_code=404, detail="Surface not found")

resampled_surface = converters.resample_property_surface_to_mesh_surface(
xtgeo_surf_mesh, xtgeo_surf_property
)
resampled_surface = converters.resample_property_surface_to_mesh_surface(xtgeo_surf_mesh, xtgeo_surf_property)
perf_metrics.record_lap("resample")

surf_data_response: schemas.SurfaceData = converters.to_api_surface_data_as_float32(
resampled_surface
)
surf_data_response: schemas.SurfaceData = converters.to_api_surface_data_as_float32(resampled_surface)
perf_metrics.record_lap("convert")

LOGGER.debug(f"Loaded property surface in: {perf_metrics.to_string()}")
Expand All @@ -288,26 +246,18 @@ async def get_property_surface_resampled_to_statistical_static_surface(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
statistic_function: schemas.SurfaceStatisticFunction = Query(
description="Statistics to calculate"
),
statistic_function: schemas.SurfaceStatisticFunction = Query(description="Statistics to calculate"),
name_mesh: str = Query(description="Surface name"),
attribute_mesh: str = Query(description="Surface attribute"),
# statistic_function_property: schemas.SurfaceStatisticFunction = Query(description="Statistics to calculate"),
name_property: str = Query(description="Surface name"),
attribute_property: str = Query(description="Surface attribute"),
time_or_interval_property: Optional[str] = Query(
None, description="Time point or time interval string"
),
time_or_interval_property: Optional[str] = Query(None, description="Time point or time interval string"),
) -> schemas.SurfaceData:
timer = PerfTimer()

access = await SurfaceAccess.from_case_uuid(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
service_stat_func_to_compute = StatisticFunction.from_string_value(
statistic_function
)
access = await SurfaceAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name)
service_stat_func_to_compute = StatisticFunction.from_string_value(statistic_function)
if service_stat_func_to_compute is not None:
xtgeo_surf_mesh = await access.get_statistical_surface_data_async(
statistic_function=service_stat_func_to_compute,
Expand All @@ -324,14 +274,10 @@ async def get_property_surface_resampled_to_statistical_static_surface(
if not xtgeo_surf_mesh or not xtgeo_surf_property:
raise HTTPException(status_code=404, detail="Surface not found")

resampled_surface = converters.resample_property_surface_to_mesh_surface(
xtgeo_surf_mesh, xtgeo_surf_property
)
resampled_surface = converters.resample_property_surface_to_mesh_surface(xtgeo_surf_mesh, xtgeo_surf_property)

surf_data_response = converters.to_api_surface_data_as_float32(resampled_surface)

LOGGER.debug(
f"Loaded property surface and created image, total time: {timer.elapsed_ms()}ms"
)
LOGGER.debug(f"Loaded property surface and created image, total time: {timer.elapsed_ms()}ms")

return surf_data_response
24 changes: 6 additions & 18 deletions backend/src/services/sumo_access/surface_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ async def get_realization_surface_data_async(
else:
timestamp_arr = time_or_interval_str.split("/", 1)
if len(timestamp_arr) == 0 or len(timestamp_arr) > 2:
raise ValueError(
"time_or_interval_str must contain a single timestamp or interval"
)
raise ValueError("time_or_interval_str must contain a single timestamp or interval")
if len(timestamp_arr) == 1:
time_filter = TimeFilter(
TimeType.TIMESTAMP,
Expand Down Expand Up @@ -121,9 +119,7 @@ async def get_realization_surface_data_async(
LOGGER.warning(f"No realization surface found in Sumo for {addr_str}")
return None
if surf_count > 1:
LOGGER.warning(
f"Multiple ({surf_count}) surfaces found in Sumo for: {addr_str}. Returning first surface."
)
LOGGER.warning(f"Multiple ({surf_count}) surfaces found in Sumo for: {addr_str}. Returning first surface.")

sumo_surf: Surface = await surface_collection.getitem_async(0)
et_locate_ms = timer.lap_ms()
Expand Down Expand Up @@ -165,9 +161,7 @@ async def get_statistical_surface_data_async(
else:
timestamp_arr = time_or_interval_str.split("/", 1)
if len(timestamp_arr) == 0 or len(timestamp_arr) > 2:
raise ValueError(
"time_or_interval_str must contain a single timestamp or interval"
)
raise ValueError("time_or_interval_str must contain a single timestamp or interval")
if len(timestamp_arr) == 1:
time_filter = TimeFilter(
TimeType.TIMESTAMP,
Expand Down Expand Up @@ -200,15 +194,11 @@ async def get_statistical_surface_data_async(
realizations = await surface_collection.realizations_async
et_collect_reals_ms = timer.lap_ms()

xtgeo_surf = await _compute_statistical_surface_async(
statistic_function, surface_collection
)
xtgeo_surf = await _compute_statistical_surface_async(statistic_function, surface_collection)
et_calc_stat_ms = timer.lap_ms()

if not xtgeo_surf:
LOGGER.warning(
f"Could not calculate statistical surface using Sumo for {addr_str}"
)
LOGGER.warning(f"Could not calculate statistical surface using Sumo for {addr_str}")
return None

LOGGER.debug(
Expand All @@ -221,9 +211,7 @@ async def get_statistical_surface_data_async(

return xtgeo_surf

def _make_addr_str(
self, real_num: int, name: str, attribute: str, date_str: Optional[str]
) -> str:
def _make_addr_str(self, real_num: int, name: str, attribute: str, date_str: Optional[str]) -> str:
addr_str = f"R:{real_num}__N:{name}__A:{attribute}__D:{date_str}__I:{self._iteration_name}__C:{self._case_uuid}"
return addr_str

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { EnsembleIdent } from "@framework/EnsembleIdent";
import { EnsembleSet } from "@framework/EnsembleSet";
import { Dropdown } from "@lib/components/Dropdown";
import { IconButton } from "@lib/components/IconButton";
import { useValidState } from "@lib/hooks/useValidState";
import ArrowCircleLeftIcon from "@mui/icons-material/ArrowCircleLeft";
import ArrowCircleRightIcon from "@mui/icons-material/ArrowCircleRight";

Expand All @@ -16,9 +15,6 @@ export type EnsembleIdentSelectWithButtonsProps = {
onChange?: (values: EnsembleIdent | null) => void;
};
export const EnsembleIdentSelectWithButtons: React.FC<EnsembleIdentSelectWithButtonsProps> = (props) => {
const selectedEnsemble = props.ensembleSet
.getEnsembleArr()
.filter((ensemble) => ensemble.getIdent().equals(props.value));
// Check if ensembleIdents are in in ensembleSet
const availableEnsembles = props.ensembleSet
.getEnsembleArr()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from "react";
import { SurfaceAttributeType_api } from "@api";
import { Dropdown } from "@lib/components/Dropdown";
import { Label } from "@lib/components/Label";
import { RadioGroup } from "@lib/components/RadioGroup";
import { TimeType } from "@modules/_shared/Surface";

const SurfaceAttributeTypeToStringMapping = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from "react";
import { SurfaceAttributeType_api, SurfaceStatisticFunction_api } from "@api";
import { EnsembleIdent } from "@framework/EnsembleIdent";
import { EnsembleSet } from "@framework/EnsembleSet";
import { WorkbenchSession, useEnsembleSet } from "@framework/WorkbenchSession";
import { IconButton } from "@lib/components/IconButton";
import { SurfaceDirectory, TimeType } from "@modules/_shared/Surface";
import { Remove } from "@mui/icons-material";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { apiService } from "@framework/ApiService";
import { EnsembleIdent } from "@framework/EnsembleIdent";
import { UseQueryResult, useQueries } from "@tanstack/react-query";

import { filter } from "lodash";

const STALE_TIME = 60 * 1000;
const CACHE_TIME = 60 * 1000;
type EnsembleSurfaceMetas = {
Expand All @@ -15,29 +13,25 @@ export type EnsembleSetSurfaceMetas = {
data: EnsembleSurfaceMetas[];
isFetching: boolean;
};
function intersectSurfaceMetas(ensembleSurfaceMetas: EnsembleSurfaceMetas[]): EnsembleSurfaceMetas[] {
function intersectEnsembleSetSurfaceMetas(ensembleSurfaceMetas: EnsembleSurfaceMetas[]): EnsembleSurfaceMetas[] {
if (!ensembleSurfaceMetas || ensembleSurfaceMetas.length === 0) {
return [];
}

// Create a map to store the count of each surfaceMeta across ensembles
const surfaceMetaCountMap = new Map<string, number>();

// Populate the map with counts
for (const ensembleSurfaceMeta of ensembleSurfaceMetas) {
for (const surfaceMeta of ensembleSurfaceMeta.surfaceMetas ?? []) {
const key = `${surfaceMeta.name}-${surfaceMeta.attribute_name}-${surfaceMeta.iso_date_or_interval}`;
surfaceMetaCountMap.set(key, (surfaceMetaCountMap.get(key) ?? 0) + 1);
}
}

// Filter the surfaceMetas that are present in all ensembles
const filteredSurfaceMetas = ensembleSurfaceMetas[0].surfaceMetas?.filter((surfaceMeta) => {
const key = `${surfaceMeta.name}-${surfaceMeta.attribute_name}-${surfaceMeta.iso_date_or_interval}`;
return surfaceMetaCountMap.get(key) === ensembleSurfaceMetas.length;
});

// Return the new array with filtered surfaceMetas
return ensembleSurfaceMetas
.map((ensembleSurfaceMeta) => ({
ensembleIdent: ensembleSurfaceMeta.ensembleIdent,
Expand All @@ -62,7 +56,7 @@ export function useEnsembleSetSurfaceMetaQuery(ensembleIdents: EnsembleIdent[]):
enabled: Boolean(ensembleIdent),
})),
combine: (results: UseQueryResult<Array<SurfaceMeta_api>>[]) => ({
data: intersectSurfaceMetas(
data: intersectEnsembleSetSurfaceMetas(
results.map((result, index) => ({
ensembleIdent: ensembleIdents[index],
surfaceMetas: result.data,
Expand Down
Loading

0 comments on commit e9636cb

Please sign in to comment.