Skip to content

Commit 008be37

Browse files
authored
729 allow unequal identifiers for inplace volumetrics (#872)
1 parent cd742ed commit 008be37

31 files changed

+363
-170
lines changed

backend_py/primary/primary/services/inplace_volumetrics_assembler/inplace_volumetrics_assembler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ async def _get_volume_df_per_fluid_selection_and_categorized_result_names_async(
257257
258258
Calculation of volume names and properties, and creation of the results is handled outside this function.
259259
"""
260-
# Check for empty identifier selections
260+
# Check for empty identifier selection lists
261261
has_empty_identifier_selection = any(
262262
not identifier_with_values.values for identifier_with_values in identifiers_with_values
263263
)

backend_py/primary/primary/services/sumo_access/inplace_volumetrics_types.py

+22-23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from enum import StrEnum
22
from dataclasses import dataclass
3-
from typing import Dict, List, Union
43

54

65
# NOTE:
@@ -88,57 +87,57 @@ class CategorizedResultNames:
8887
Class to hold categorized result names
8988
9089
Attributes:
91-
- volume_names: List[str] - Basic volume names among result names
92-
- calculated_volume_names: List[str] - Calculated volume names among result names (STOIIP_TOTAL, GIIP_TOTAL)
93-
- property_names: List[str] - Property names among result names
90+
- volume_names: list[str] - Basic volume names among result names
91+
- calculated_volume_names: list[str] - Calculated volume names among result names (STOIIP_TOTAL, GIIP_TOTAL)
92+
- property_names: list[str] - Property names among result names
9493
"""
9594

96-
volume_names: List[str]
97-
calculated_volume_names: List[str]
98-
property_names: List[str]
95+
volume_names: list[str]
96+
calculated_volume_names: list[str]
97+
property_names: list[str]
9998

10099

101100
@dataclass
102101
class InplaceVolumetricsIdentifierWithValues:
103102
"""
104-
Unique values for an identifier column in an inplace volumetrics table
103+
Unique values for an identifier column in an inplace volumetric table
105104
106105
NOTE: Ideally all values should be strings, but it is possible that some values are integers - especially for REGION
107106
"""
108107

109108
identifier: InplaceVolumetricsIdentifier
110-
values: List[Union[str, int]] # List of values: str or int
109+
values: list[str | int] # list of values: str or int
111110

112111

113112
@dataclass
114113
class InplaceVolumetricsTableDefinition:
115114
"""Definition of a volumetric table"""
116115

117116
table_name: str
118-
identifiers_with_values: List[InplaceVolumetricsIdentifierWithValues]
119-
result_names: List[str]
120-
fluid_zones: List[FluidZone]
117+
identifiers_with_values: list[InplaceVolumetricsIdentifierWithValues]
118+
result_names: list[str]
119+
fluid_zones: list[FluidZone]
121120

122121

123122
@dataclass
124123
class RepeatedTableColumnData:
125124
"""Definition of a column with repeated column data"""
126125

127126
column_name: str
128-
unique_values: List[str | int] # ["Valysar", "Therys", "Volon"]
129-
indices: List[int] # [0, 1, 1, 1, 2, 2, 2]. Length = number of rows in the table
127+
unique_values: list[str | int] # ["Valysar", "Therys", "Volon"]
128+
indices: list[int] # [0, 1, 1, 1, 2, 2, 2]. Length = number of rows in the table
130129

131130

132131
@dataclass
133132
class TableColumnData:
134133
column_name: str
135-
values: List[float] # Column values Length = number of rows in the table
134+
values: list[float] # Column values Length = number of rows in the table
136135

137136

138137
@dataclass
139138
class TableColumnStatisticalData:
140139
column_name: str
141-
statistic_values: Dict[Statistic, List[float]] # Statistics values Length = number of rows in the table
140+
statistic_values: dict[Statistic, list[float]] # Statistics values Length = number of rows in the table
142141

143142

144143
@dataclass
@@ -148,10 +147,10 @@ class InplaceVolumetricTableData:
148147
Contains data for a single fluid zone, e.g. Oil, Gas, Water, or sum of fluid zones
149148
"""
150149

151-
# fluid_zones: List[FluidZone] # Oil, Gas, Water or "Oil + Gas", etc.
150+
# fluid_zones: list[FluidZone] # Oil, Gas, Water or "Oil + Gas", etc.
152151
fluid_selection_name: str # Oil, Gas, Water or "Oil + Gas", etc.
153-
selector_columns: List[RepeatedTableColumnData] # Index columns and realizations
154-
result_columns: List[TableColumnData]
152+
selector_columns: list[RepeatedTableColumnData] # Index columns and realizations
153+
result_columns: list[TableColumnData]
155154

156155

157156
@dataclass
@@ -163,8 +162,8 @@ class InplaceStatisticalVolumetricTableData:
163162
"""
164163

165164
fluid_selection_name: str # Oil, Gas, Water or "Oil + Gas", etc.
166-
selector_columns: List[RepeatedTableColumnData] # Index columns and realizations
167-
result_column_statistics: List[TableColumnStatisticalData]
165+
selector_columns: list[RepeatedTableColumnData] # Index columns and realizations
166+
result_column_statistics: list[TableColumnStatisticalData]
168167

169168

170169
@dataclass
@@ -175,7 +174,7 @@ class InplaceVolumetricTableDataPerFluidSelection:
175174
Fluid selection can be single fluid zones, e.g. Oil, Gas, Water, or sum of fluid zones - Oil + Gas + Water
176175
"""
177176

178-
table_data_per_fluid_selection: List[InplaceVolumetricTableData]
177+
table_data_per_fluid_selection: list[InplaceVolumetricTableData]
179178

180179

181180
@dataclass
@@ -186,4 +185,4 @@ class InplaceStatisticalVolumetricTableDataPerFluidSelection:
186185
Fluid selection can be single fluid zones, e.g. Oil, Gas, Water, or sum of fluid zones - Oil + Gas + Water
187186
"""
188187

189-
table_data_per_fluid_selection: List[InplaceStatisticalVolumetricTableData]
188+
table_data_per_fluid_selection: list[InplaceStatisticalVolumetricTableData]

frontend/src/framework/WorkbenchServices.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { isEqual } from "lodash";
66

77
import { RegularEnsembleIdent } from "./RegularEnsembleIdent";
88
import { Workbench } from "./Workbench";
9-
import { InplaceVolumetricsFilter } from "./types/inplaceVolumetricsFilter";
9+
import { InplaceVolumetricsFilterSettings } from "./types/inplaceVolumetricsFilterSettings";
1010
import { Intersection } from "./types/intersection";
1111
import { Viewport } from "./types/viewport";
1212
import { Wellbore } from "./types/wellbore";
@@ -38,7 +38,7 @@ export type GlobalTopicDefinitions = {
3838
"global.syncValue.intersection": Intersection;
3939
"global.syncValue.cameraPositionIntersection": Viewport;
4040
"global.syncValue.verticalScale": number;
41-
"global.syncValue.inplaceVolumetricsFilter": InplaceVolumetricsFilter;
41+
"global.syncValue.inplaceVolumetricsFilterSettings": InplaceVolumetricsFilterSettings;
4242
"global.syncValue.inplaceVolumetricsResultName": string;
4343
};
4444

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { FluidZone_api, InplaceVolumetricsIdentifierWithValues_api } from "@api";
22
import { RegularEnsembleIdent } from "@framework/RegularEnsembleIdent";
33

4-
export type InplaceVolumetricsFilter = {
4+
export type InplaceVolumetricsFilterSettings = {
55
ensembleIdents: RegularEnsembleIdent[];
66
tableNames: string[];
77
fluidZones: FluidZone_api[];
88
identifiersValues: InplaceVolumetricsIdentifierWithValues_api[];
9+
allowIdentifierValuesIntersection: boolean;
910
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from "react";
2+
3+
import { resolveClassNames } from "@lib/utils/resolveClassNames";
4+
5+
export type ErrorWrapperProps = {
6+
isError?: boolean;
7+
message?: string;
8+
children: React.ReactNode;
9+
};
10+
11+
export const ErrorWrapper: React.FC<ErrorWrapperProps> = (props) => {
12+
return (
13+
<div
14+
className={resolveClassNames("relative rounded", {
15+
"outline outline-red-100 outline-offset-2": props.isError ?? false,
16+
})}
17+
>
18+
{props.isError && props.message && (
19+
<div className="absolute left-0 right-0 w-full h-full bg-white bg-opacity-80 flex items-center justify-center z-10 p-4 text-center backdrop-blur-sm">
20+
{props.message}
21+
</div>
22+
)}
23+
{props.children}
24+
</div>
25+
);
26+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { ErrorWrapper } from "./errorWrapper";

frontend/src/lib/utils/fixupUserSelection.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
1+
export enum FixupSelection {
2+
SELECT_NONE = "SELECT_NONE",
3+
SELECT_ALL = "SELECT_ALL",
4+
SELECT_FIRST = "SELECT_FIRST",
5+
}
6+
17
export function fixupUserSelection<TSelection>(
28
userSelection: TSelection[],
39
validOptions: TSelection[],
4-
selectAll: boolean = false
10+
fixupSelection: FixupSelection = FixupSelection.SELECT_FIRST
511
): TSelection[] {
612
const newSelections = userSelection.filter((selection) => validOptions.includes(selection));
713
if (newSelections.length === 0 && validOptions.length > 0) {
8-
if (selectAll) {
14+
if (fixupSelection === FixupSelection.SELECT_ALL) {
915
return validOptions;
1016
}
17+
if (fixupSelection === FixupSelection.SELECT_NONE) {
18+
return [];
19+
}
20+
21+
// Fall back to selecting the first valid option
1122
newSelections.push(validOptions[0]);
1223
}
1324

frontend/src/modules/InplaceVolumetricsPlot/interfaces.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { InplaceVolumetricResultName_api } from "@api";
22
import { InterfaceInitialization } from "@framework/UniDirectionalModuleComponentsInterface";
3-
import { InplaceVolumetricsFilter } from "@framework/types/inplaceVolumetricsFilter";
43
import { SelectorColumn, SourceAndTableIdentifierUnion } from "@modules/_shared/InplaceVolumetrics/types";
54

65
import { userSelectedPlotTypeAtom } from "./settings/atoms/baseAtoms";
@@ -17,17 +16,16 @@ import {
1716
selectedSubplotByAtom,
1817
selectedTableNamesAtom,
1918
} from "./settings/atoms/derivedAtoms";
20-
import { PlotType } from "./typesAndEnums";
19+
import { InplaceVolumetricsFilterSelections, PlotType } from "./typesAndEnums";
2120

2221
export type SettingsToViewInterface = {
23-
filter: InplaceVolumetricsFilter;
22+
filter: InplaceVolumetricsFilterSelections;
2423
resultName: InplaceVolumetricResultName_api | null;
2524
resultName2: InplaceVolumetricResultName_api | null;
2625
selectorColumn: SelectorColumn | null;
2726
subplotBy: SourceAndTableIdentifierUnion;
2827
colorBy: SourceAndTableIdentifierUnion;
2928
plotType: PlotType;
30-
areSelectedTablesComparable: boolean;
3129
areTableDefinitionSelectionsValid: boolean;
3230
};
3331

@@ -42,6 +40,7 @@ export const settingsToViewInterfaceInitialization: InterfaceInitialization<Sett
4240
tableNames: get(selectedTableNamesAtom),
4341
fluidZones: get(selectedFluidZonesAtom),
4442
identifiersValues: get(selectedIdentifiersValuesAtom),
43+
areSelectedTablesComparable: get(areSelectedTablesComparableAtom),
4544
};
4645
},
4746
resultName: (get) => get(selectedResultNameAtom),
@@ -50,6 +49,5 @@ export const settingsToViewInterfaceInitialization: InterfaceInitialization<Sett
5049
subplotBy: (get) => get(selectedSubplotByAtom),
5150
colorBy: (get) => get(selectedColorByAtom),
5251
plotType: (get) => get(userSelectedPlotTypeAtom),
53-
areSelectedTablesComparable: (get) => get(areSelectedTablesComparableAtom),
5452
areTableDefinitionSelectionsValid: (get) => get(areTableDefinitionSelectionsValidAtom),
5553
};

frontend/src/modules/InplaceVolumetricsPlot/settings/atoms/baseAtoms.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { FluidZone_api, InplaceVolumetricResultName_api, InplaceVolumetricsIdentifierWithValues_api } from "@api";
22
import { RegularEnsembleIdent } from "@framework/RegularEnsembleIdent";
33
import { PlotType } from "@modules/InplaceVolumetricsPlot/typesAndEnums";
4+
import { IdentifierValueCriteria } from "@modules/_shared/InplaceVolumetrics/TableDefinitionsAccessor";
45
import {
56
SelectorColumn,
67
SourceAndTableIdentifierUnion,
@@ -19,3 +20,7 @@ export const userSelectedSelectorColumnAtom = atom<SelectorColumn | null>(null);
1920
export const userSelectedSubplotByAtom = atom<SourceAndTableIdentifierUnion>(SourceIdentifier.ENSEMBLE);
2021
export const userSelectedPlotTypeAtom = atom<PlotType>(PlotType.HISTOGRAM);
2122
export const userSelectedColorByAtom = atom<SourceAndTableIdentifierUnion>(SourceIdentifier.TABLE_NAME);
23+
24+
export const selectedIdentifierValueCriteriaAtom = atom<IdentifierValueCriteria>(
25+
IdentifierValueCriteria.REQUIRE_EQUALITY
26+
);

frontend/src/modules/InplaceVolumetricsPlot/settings/atoms/derivedAtoms.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FluidZone_api, InplaceVolumetricResultName_api, InplaceVolumetricsIdentifierWithValues_api } from "@api";
22
import { EnsembleSetAtom } from "@framework/GlobalAtoms";
33
import { fixupRegularEnsembleIdents } from "@framework/utils/ensembleUiHelpers";
4-
import { fixupUserSelection } from "@lib/utils/fixupUserSelection";
4+
import { FixupSelection, fixupUserSelection } from "@lib/utils/fixupUserSelection";
55
import { fixupUserSelectedIdentifierValues } from "@modules/_shared/InplaceVolumetrics/fixupUserSelectedIdentifierValues";
66
import { RealSelector, SelectorColumn, SourceAndTableIdentifierUnion } from "@modules/_shared/InplaceVolumetrics/types";
77
import {
@@ -12,6 +12,7 @@ import {
1212
import { atom } from "jotai";
1313

1414
import {
15+
selectedIdentifierValueCriteriaAtom,
1516
userSelectedColorByAtom,
1617
userSelectedEnsembleIdentsAtom,
1718
userSelectedFluidZonesAtom,
@@ -49,8 +50,13 @@ export const selectedEnsembleIdentsAtom = atom((get) => {
4950
export const tableDefinitionsAccessorAtom = atom<TableDefinitionsAccessor>((get) => {
5051
const selectedTableNames = get(selectedTableNamesAtom);
5152
const tableDefinitions = get(tableDefinitionsQueryAtom);
53+
const selectedIdentifierValueCriteria = get(selectedIdentifierValueCriteriaAtom);
5254

53-
return new TableDefinitionsAccessor(tableDefinitions.isLoading ? [] : tableDefinitions.data, selectedTableNames);
55+
return new TableDefinitionsAccessor(
56+
tableDefinitions.isLoading ? [] : tableDefinitions.data,
57+
selectedTableNames,
58+
selectedIdentifierValueCriteria
59+
);
5460
});
5561

5662
export const areTableDefinitionSelectionsValidAtom = atom<boolean>((get) => {
@@ -121,7 +127,11 @@ export const selectedFluidZonesAtom = atom<FluidZone_api[]>((get) => {
121127
return tableDefinitionsAccessor.getFluidZonesIntersection();
122128
}
123129

124-
return fixupUserSelection(userSelectedFluidZones, tableDefinitionsAccessor.getFluidZonesIntersection(), true);
130+
return fixupUserSelection(
131+
userSelectedFluidZones,
132+
tableDefinitionsAccessor.getFluidZonesIntersection(),
133+
FixupSelection.SELECT_ALL
134+
);
125135
});
126136

127137
export const selectedResultNameAtom = atom<InplaceVolumetricResultName_api | null>((get) => {
@@ -174,7 +184,7 @@ export const selectedSelectorColumnAtom = atom<SelectorColumn | null>((get) => {
174184

175185
const possibleSelectorColumns = [
176186
RealSelector.REAL,
177-
...tableDefinitionsAccessor.getIdentifiersWithIntersectionValues().map((ident) => ident.identifier),
187+
...tableDefinitionsAccessor.getCommonIdentifiersWithValues().map((ident) => ident.identifier),
178188
];
179189
if (!userSelectedSelectorColumn) {
180190
return possibleSelectorColumns[0];
@@ -192,13 +202,12 @@ export const selectedIdentifiersValuesAtom = atom<InplaceVolumetricsIdentifierWi
192202
const userSelectedIdentifierValues = get(userSelectedIdentifiersValuesAtom);
193203
const tableDefinitionsAccessor = get(tableDefinitionsAccessorAtom);
194204

195-
const uniqueIdentifierValues = tableDefinitionsAccessor.getIdentifiersWithIntersectionValues();
196-
const selectAllOnFixup = true;
205+
const uniqueIdentifierValues = tableDefinitionsAccessor.getCommonIdentifiersWithValues();
197206

198207
const fixedUpIdentifierValues: InplaceVolumetricsIdentifierWithValues_api[] = fixupUserSelectedIdentifierValues(
199208
userSelectedIdentifierValues,
200209
uniqueIdentifierValues,
201-
selectAllOnFixup
210+
FixupSelection.SELECT_ALL
202211
);
203212

204213
return fixedUpIdentifierValues;

0 commit comments

Comments
 (0)