Skip to content

Commit 44ba1d9

Browse files
authored
Implement Well-log viewer module MVP (#794)
1 parent 7e96080 commit 44ba1d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+3558
-176
lines changed

backend_py/primary/primary/routers/well/converters.py

+6
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ def convert_wellbore_perforation_to_schema(
123123
def convert_wellbore_log_curve_header_to_schema(
124124
wellbore_log_curve_header: WellboreLogCurveHeader,
125125
) -> schemas.WellboreLogCurveHeader:
126+
if wellbore_log_curve_header.log_name is None:
127+
raise AttributeError("Missing log name is not allowed")
128+
126129
return schemas.WellboreLogCurveHeader(
127130
logName=wellbore_log_curve_header.log_name,
128131
curveName=wellbore_log_curve_header.curve_name,
@@ -134,6 +137,9 @@ def convert_wellbore_log_curve_data_to_schema(
134137
wellbore_log_curve_data: WellboreLogCurveData,
135138
) -> schemas.WellboreLogCurveData:
136139
return schemas.WellboreLogCurveData(
140+
name=wellbore_log_curve_data.name,
141+
unit=wellbore_log_curve_data.unit,
142+
curveUnitDesc=wellbore_log_curve_data.curve_unit_desc,
137143
indexMin=wellbore_log_curve_data.index_min,
138144
indexMax=wellbore_log_curve_data.index_max,
139145
minCurveValue=wellbore_log_curve_data.min_curve_value,

backend_py/primary/primary/routers/well/router.py

+2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ async def get_wellbore_log_curve_headers(
212212
return [
213213
converters.convert_wellbore_log_curve_header_to_schema(wellbore_log_curve_header)
214214
for wellbore_log_curve_header in wellbore_log_curve_headers
215+
# Missing log name implies garbage data, so we simply drop them
216+
if wellbore_log_curve_header.log_name is not None
215217
]
216218

217219

backend_py/primary/primary/routers/well/schemas.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,19 @@ class WellborePerforation(BaseModel):
106106
class WellboreLogCurveHeader(BaseModel):
107107
logName: str
108108
curveName: str
109-
curveUnit: str
109+
curveUnit: str | None
110110

111111

112112
class WellboreLogCurveData(BaseModel):
113+
name: str
113114
indexMin: float
114115
indexMax: float
115116
minCurveValue: float
116117
maxCurveValue: float
117-
dataPoints: list[list[float | None]]
118-
curveAlias: str
119-
curveDescription: str
118+
curveAlias: str | None
119+
curveDescription: str | None
120120
indexUnit: str
121-
noDataValue: float
121+
noDataValue: float | None
122+
unit: str
123+
curveUnitDesc: str | None
124+
dataPoints: list[list[float | None]]

backend_py/primary/primary/services/ssdl_access/types.py

+29-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
from pydantic import BaseModel
23

34

@@ -34,18 +35,40 @@ class WellborePerforation(BaseModel):
3435

3536

3637
class WellboreLogCurveHeader(BaseModel):
37-
log_name: str
38+
log_name: str | None
3839
curve_name: str
39-
curve_unit: str
40+
curve_unit: str | None
41+
42+
# Defining a hash-function to facilitate usage in Sets
43+
def __hash__(self) -> int:
44+
# No globally unique field, but curve-name should be unique (per wellbore)
45+
return hash(self.curve_name + (self.log_name or "N/A"))
46+
47+
def __eq__(self, other: Any) -> bool:
48+
if not isinstance(other, WellboreLogCurveHeader):
49+
# delegate to the other item in the comparison
50+
return NotImplemented
51+
52+
return (self.curve_name, self.log_name) == (other.curve_name, other.log_name)
4053

4154

4255
class WellboreLogCurveData(BaseModel):
56+
name: str
4357
index_min: float
4458
index_max: float
4559
min_curve_value: float
4660
max_curve_value: float
47-
DataPoints: list[list[float | None]]
48-
curve_alias: str
49-
curve_description: str
61+
curve_alias: str | None
62+
curve_description: str | None
5063
index_unit: str
51-
no_data_value: float
64+
no_data_value: float | None
65+
unit: str
66+
curve_unit_desc: str | None
67+
68+
# This field has weird casing. This is just how SSDL has decided to return this object, so we leave it as is to make model validation
69+
DataPoints: list[list[float | None]]
70+
71+
@property
72+
def data_points(self) -> list[list[float | None]]:
73+
# Utility property to "DataPoint" with proper casing
74+
return self.DataPoints

backend_py/primary/primary/services/ssdl_access/well_access.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ async def get_log_curve_headers_for_wellbore(self, wellbore_uuid: str) -> List[t
5151
endpoint = f"WellLog/{wellbore_uuid}"
5252
ssdl_data = await ssdl_get_request(access_token=self._ssdl_token, endpoint=endpoint, params=None)
5353
try:
54-
result = [types.WellboreLogCurveHeader.model_validate(log_curve) for log_curve in ssdl_data]
54+
# This endpoint is a bit weird, and MIGHT return duplicates which, as far as I can tell, are the exact same. Using a set to drop duplicates. See data model for comparator
55+
result_set = {types.WellboreLogCurveHeader.model_validate(log_curve) for log_curve in ssdl_data}
56+
5557
except ValidationError as error:
5658
raise InvalidDataError(f"Invalid log curve headers for wellbore {wellbore_uuid}", Service.SSDL) from error
57-
return result
59+
return list(result_set)
5860

5961
async def get_log_curve_headers_for_field(self, field_uuid: str) -> List[types.WellboreLogCurveHeader]:
6062
endpoint = f"WellLog/field/{field_uuid}"

frontend/package-lock.json

+31
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@tanstack/react-query-devtools": "^5.4.2",
2929
"@types/geojson": "^7946.0.14",
3030
"@webviz/group-tree-plot": "^1.1.14",
31+
"@webviz/well-log-viewer": "^1.12.7",
3132
"@webviz/subsurface-viewer": "^1.1.1",
3233
"@webviz/well-completions-plot": "^1.5.11",
3334
"animate.css": "^4.1.1",

frontend/src/api/models/WellboreLogCurveData.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
/* tslint:disable */
44
/* eslint-disable */
55
export type WellboreLogCurveData = {
6+
name: string;
67
indexMin: number;
78
indexMax: number;
89
minCurveValue: number;
910
maxCurveValue: number;
10-
dataPoints: Array<Array<(number | null)>>;
11-
curveAlias: string;
12-
curveDescription: string;
11+
curveAlias: (string | null);
12+
curveDescription: (string | null);
1313
indexUnit: string;
14-
noDataValue: number;
14+
noDataValue: (number | null);
15+
unit: string;
16+
curveUnitDesc: (string | null);
17+
dataPoints: Array<Array<(number | null)>>;
1518
};
1619

frontend/src/api/models/WellboreLogCurveHeader.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
export type WellboreLogCurveHeader = {
66
logName: string;
77
curveName: string;
8-
curveUnit: string;
8+
curveUnit: (string | null);
99
};
1010

0 commit comments

Comments
 (0)