diff --git a/backend_py/primary/poetry.lock b/backend_py/primary/poetry.lock index 23b7a2c27..c0f418289 100644 --- a/backend_py/primary/poetry.lock +++ b/backend_py/primary/poetry.lock @@ -793,13 +793,13 @@ files = [ [[package]] name = "fmu-sumo" -version = "1.2.2" +version = "1.2.4" description = "Python package for interacting with Sumo in an FMU setting" optional = false python-versions = ">=3.8" files = [ - {file = "fmu_sumo-1.2.2-py3-none-any.whl", hash = "sha256:51d72b145cc1d9db6f7a4fb41de67ceddd75ba3c2285b776358aa63aaa145a54"}, - {file = "fmu_sumo-1.2.2.tar.gz", hash = "sha256:54b2ede5db007f99a37a47c60d7f5fb91417fb604388299db7d3002f04516041"}, + {file = "fmu_sumo-1.2.4-py3-none-any.whl", hash = "sha256:d76ce6de25fe1009a78fcbbe6bf9b4cfd3c410398a81d9f4c073bd3a8b29d6a5"}, + {file = "fmu_sumo-1.2.4.tar.gz", hash = "sha256:a9b422e08af271dca4e6293ae94b343329d59f302bbd44c8430a670e0b4be5c7"}, ] [package.dependencies] @@ -3513,4 +3513,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "0b37065931c0e13b53edfaab07550535df47242b20f989cac83cfbaff515d2a2" +content-hash = "9c20526602b7ab84f5102041476f2af5da6763caba9935954c67db132b3a38ba" diff --git a/backend_py/primary/primary/routers/group_tree/schemas.py b/backend_py/primary/primary/routers/group_tree/schemas.py index 49c6e4dbb..d1372d1c3 100644 --- a/backend_py/primary/primary/routers/group_tree/schemas.py +++ b/backend_py/primary/primary/routers/group_tree/schemas.py @@ -1,6 +1,7 @@ from typing import List from enum import Enum -from primary.services.sumo_access.group_tree_types import GroupTreeMetadata, DatedTree +from primary.services.sumo_access.group_tree_types import DatedTree, GroupTreeMetadata + from pydantic import BaseModel diff --git a/backend_py/primary/primary/services/group_tree_assembler/group_tree_assembler.py b/backend_py/primary/primary/services/group_tree_assembler/group_tree_assembler.py index 7ac40a249..7d6c0082a 100644 --- a/backend_py/primary/primary/services/group_tree_assembler/group_tree_assembler.py +++ b/backend_py/primary/primary/services/group_tree_assembler/group_tree_assembler.py @@ -11,6 +11,7 @@ from primary.services.sumo_access.group_tree_access import GroupTreeAccess from primary.services.sumo_access.group_tree_types import ( DataType, + DataTypeToStringLabelMap, DatedTree, EdgeOrNode, GroupTreeMetadata, @@ -654,17 +655,7 @@ def _create_leaf_node_classification_map( def _get_label(datatype: DataType) -> str: """Returns a more readable label for the summary datatypes""" - labels = { - DataType.OILRATE: "Oil Rate", - DataType.GASRATE: "Gas Rate", - DataType.WATERRATE: "Water Rate", - DataType.WATERINJRATE: "Water Inj Rate", - DataType.GASINJRATE: "Gas Inj Rate", - DataType.PRESSURE: "Pressure", - DataType.BHP: "BHP", - DataType.WMCTL: "WMCTL", - } - label = labels.get(datatype) + label = DataTypeToStringLabelMap.get(datatype) if label is None: raise ValueError(f"Label for datatype {datatype.value} not implemented.") return label diff --git a/backend_py/primary/primary/services/sumo_access/queries/grid3d.py b/backend_py/primary/primary/services/sumo_access/queries/grid3d.py index 3d0b51e14..f9f4ab2cb 100644 --- a/backend_py/primary/primary/services/sumo_access/queries/grid3d.py +++ b/backend_py/primary/primary/services/sumo_access/queries/grid3d.py @@ -78,23 +78,23 @@ async def get_grid_geometry_and_property_blob_ids_async( { "bool": { "must": [ - {"match": {"_sumo.parent_object.keyword": case_id}}, - {"match": {"class": "cpgrid"}}, - {"match": {"fmu.iteration.name": iteration}}, - {"match": {"fmu.realization.id": realization}}, - {"match": {"data.name.keyword": grid_name}}, + {"term": {"_sumo.parent_object.keyword": case_id}}, + {"term": {"class.keyword": "cpgrid"}}, + {"term": {"fmu.iteration.name.keyword": iteration}}, + {"term": {"fmu.realization.id": realization}}, + {"term": {"data.name.keyword": grid_name}}, ] } }, { "bool": { "must": [ - {"match": {"_sumo.parent_object.keyword": case_id}}, - {"match": {"class": "cpgrid_property"}}, - {"match": {"fmu.iteration.name": iteration}}, - {"match": {"fmu.realization.id": realization}}, - {"match": {"data.name.keyword": parameter_name}}, - {"match": {"data.tagname.keyword": grid_name}}, + {"term": {"_sumo.parent_object.keyword": case_id}}, + {"term": {"class.keyword": "cpgrid_property"}}, + {"term": {"fmu.iteration.name.keyword": iteration}}, + {"term": {"fmu.realization.id": realization}}, + {"term": {"data.name.keyword": parameter_name}}, + {"term": {"data.tagname.keyword": grid_name}}, ] } }, @@ -102,7 +102,6 @@ async def get_grid_geometry_and_property_blob_ids_async( "minimum_should_match": 1, } } - time_filter = get_time_filter(parameter_time_or_interval_str) if time_filter.time_type != TimeType.NONE: @@ -118,7 +117,6 @@ async def get_grid_geometry_and_property_blob_ids_async( result = response.json() hits = result["hits"]["hits"] - if len(hits) != 2: raise InvalidDataError(f"Expected 2 hits, got {len(hits)}", service=Service.SUMO) diff --git a/backend_py/primary/pyproject.toml b/backend_py/primary/pyproject.toml index b2ce7e7f4..5d4d11e2e 100644 --- a/backend_py/primary/pyproject.toml +++ b/backend_py/primary/pyproject.toml @@ -20,7 +20,7 @@ numpy = "^1.24.1" orjson = "^3.8.10" pandas = {version = "2.0.1", extras = ["performance"]} httpx = "^0.24.0" -fmu-sumo = "1.2.2" +fmu-sumo = "1.2.4" sumo-wrapper-python = "1.0.9" azure-monitor-opentelemetry = "^1.1.0" requests-toolbelt = "^1.0.0" diff --git a/frontend/src/framework/GlobalAtoms.ts b/frontend/src/framework/GlobalAtoms.ts index 8b6a45214..501932bf7 100644 --- a/frontend/src/framework/GlobalAtoms.ts +++ b/frontend/src/framework/GlobalAtoms.ts @@ -11,7 +11,7 @@ import { atomWithCompare } from "./utils/atomUtils"; export const EnsembleSetAtom = atomWithCompare(new EnsembleSet([]), isEqual); export const EnsembleRealizationFilterFunctionAtom = atom((get) => { - const realizationFilterSet = get(RealizationFilterSetAtom); + const realizationFilterSet = get(RealizationFilterSetAtom)?.filterSet; if (!realizationFilterSet) { return null; @@ -21,19 +21,8 @@ export const EnsembleRealizationFilterFunctionAtom = atom( - null, - areRealizationFilterSetsEqual -); +// RealizationFilterSetAtom needs to be packed into an object such that we can shallow-compare it with its previous value +// as the class instance of RealizationFilterSet will never change in the lifetime of the application. +export const RealizationFilterSetAtom = atom<{ + filterSet: RealizationFilterSet; +} | null>(null); diff --git a/frontend/src/framework/internal/WorkbenchSessionPrivate.ts b/frontend/src/framework/internal/WorkbenchSessionPrivate.ts index 97877ca6e..1bc9f6575 100644 --- a/frontend/src/framework/internal/WorkbenchSessionPrivate.ts +++ b/frontend/src/framework/internal/WorkbenchSessionPrivate.ts @@ -26,6 +26,9 @@ export class WorkbenchSessionPrivate extends WorkbenchSession { } notifyAboutEnsembleRealizationFilterChange(): void { + this._atomStoreMaster.setAtomValue(RealizationFilterSetAtom, { + filterSet: this._realizationFilterSet, + }); this.notifySubscribers(WorkbenchSessionEvent.RealizationFilterSetChanged); } } diff --git a/frontend/src/modules/FlowNetwork/settings/atoms/derivedAtoms.ts b/frontend/src/modules/FlowNetwork/settings/atoms/derivedAtoms.ts index 3b3d83102..166298583 100644 --- a/frontend/src/modules/FlowNetwork/settings/atoms/derivedAtoms.ts +++ b/frontend/src/modules/FlowNetwork/settings/atoms/derivedAtoms.ts @@ -89,16 +89,23 @@ export const selectedDateTimeAtom = atom((get) => { return userSelectedDateTime; }); -export const availableEdgeKeysAtom = atom((get) => { +export const edgeMetadataListAtom = atom((get) => { const groupTreeQueryResult = get(groupTreeQueryResultAtom); - return groupTreeQueryResult.data?.edge_metadata_list.map((item) => item.key) ?? []; + + const data = groupTreeQueryResult.data; + if (!data) { + return []; + } + + return data.edge_metadata_list.map((elm) => ({ key: elm.key, label: elm.label })); }); export const selectedEdgeKeyAtom = atom((get) => { - const availableEdgeKeys = get(availableEdgeKeysAtom); + const availableEdgesMetadataList = get(edgeMetadataListAtom); + const availableEdgeKeys = availableEdgesMetadataList.map((item) => item.key); const userSelectedEdgeKey = get(userSelectedEdgeKeyAtom); - if (availableEdgeKeys.length === 0) { + if (availableEdgesMetadataList.length === 0) { return null; } if (!userSelectedEdgeKey || !availableEdgeKeys.includes(userSelectedEdgeKey)) { @@ -108,16 +115,23 @@ export const selectedEdgeKeyAtom = atom((get) => { return userSelectedEdgeKey; }); -export const availableNodeKeysAtom = atom((get) => { +export const nodeMetadataListAtom = atom((get) => { const groupTreeQueryResult = get(groupTreeQueryResultAtom); - return groupTreeQueryResult.data?.node_metadata_list.map((item) => item.key) ?? []; + + const data = groupTreeQueryResult.data; + if (!data) { + return []; + } + + return data.node_metadata_list.map((elm) => ({ key: elm.key, label: elm.label })); }); export const selectedNodeKeyAtom = atom((get) => { - const availableNodeKeys = get(availableNodeKeysAtom); + const availableNodesMetadataList = get(nodeMetadataListAtom); + const availableNodeKeys = availableNodesMetadataList.map((item) => item.key); const userSelectedNodeKey = get(userSelectedNodeKeyAtom); - if (availableNodeKeys.length === 0) { + if (availableNodesMetadataList.length === 0) { return null; } if (!userSelectedNodeKey || !availableNodeKeys.includes(userSelectedNodeKey)) { @@ -127,17 +141,13 @@ export const selectedNodeKeyAtom = atom((get) => { return userSelectedNodeKey; }); -export const edgeMetadataListAtom = atom((get) => { +export const datedTreesAtom = atom((get) => { const groupTreeQueryResult = get(groupTreeQueryResultAtom); - return groupTreeQueryResult.data?.edge_metadata_list ?? []; -}); -export const nodeMetadataListAtom = atom((get) => { - const groupTreeQueryResult = get(groupTreeQueryResultAtom); - return groupTreeQueryResult.data?.node_metadata_list ?? []; -}); + const data = groupTreeQueryResult.data; + if (!data) { + return []; + } -export const datedTreesAtom = atom((get) => { - const groupTreeQueryResult = get(groupTreeQueryResultAtom); - return groupTreeQueryResult.data?.dated_trees ?? []; + return data.dated_trees; }); diff --git a/frontend/src/modules/FlowNetwork/settings/settings.tsx b/frontend/src/modules/FlowNetwork/settings/settings.tsx index 47e1e6637..056f2c959 100644 --- a/frontend/src/modules/FlowNetwork/settings/settings.tsx +++ b/frontend/src/modules/FlowNetwork/settings/settings.tsx @@ -29,9 +29,9 @@ import { } from "./atoms/baseAtoms"; import { availableDateTimesAtom, - availableEdgeKeysAtom, - availableNodeKeysAtom, + edgeMetadataListAtom, groupTreeQueryResultAtom, + nodeMetadataListAtom, selectedDateTimeAtom, selectedEdgeKeyAtom, selectedEnsembleIdentAtom, @@ -47,8 +47,8 @@ export function Settings({ workbenchSession, settingsContext }: ModuleSettingsPr const statusWriter = useSettingsStatusWriter(settingsContext); const availableDateTimes = useAtomValue(availableDateTimesAtom); - const availableEdgeKeys = useAtomValue(availableEdgeKeysAtom); - const availableNodeKeys = useAtomValue(availableNodeKeysAtom); + const edgeMetadataList = useAtomValue(edgeMetadataListAtom); + const nodeMetadataList = useAtomValue(nodeMetadataListAtom); const [selectedResamplingFrequency, setSelectedResamplingFrequency] = useAtom(selectedResamplingFrequencyAtom); const [selectedNodeTypes, setSelectedNodeTypes] = useAtom(selectedNodeTypesAtom); @@ -191,8 +191,8 @@ export function Settings({ workbenchSession, settingsContext }: ModuleSettingsPr