Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structural uncertainty #564

Merged
merged 50 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
5ef3453
Structural uncertainty
HansKallekleiv Nov 29, 2023
4ae32f7
reorganize a bit
HansKallekleiv Jan 22, 2024
d6f3f98
black
HansKallekleiv Jan 24, 2024
b88cf34
lint
HansKallekleiv Jan 24, 2024
531f0d9
lint
HansKallekleiv Jan 24, 2024
79fc8ad
Cleaned up whitespace in order to diff file
sigurdp Jan 27, 2024
4c43665
Added dockerfiles for dev and prod, hot reload should now be working …
sigurdp Jan 28, 2024
d96c957
Refactored intersectSurface endpoint in primary backend and establish…
sigurdp Jan 28, 2024
c432918
Added PerfTimer
sigurdp Jan 29, 2024
44990f3
Fixed indentation in radixconfig
sigurdp Jan 29, 2024
3e03de1
Logging of num CPUs and GOMAXPROCS
sigurdp Jan 29, 2024
77376cd
Renamed component
sigurdp Jan 29, 2024
48e1431
Renamed go service to surface-query in radixconfig and docker compose
sigurdp Jan 29, 2024
66860d1
Use prod dockerfile and force GOMAXPROCS to 2
sigurdp Jan 29, 2024
10332c5
Set user 1234 explicitly
sigurdp Jan 29, 2024
26bef9c
Added missing numeric user
sigurdp Jan 29, 2024
c1a5132
Separated and restructured go code, take one
sigurdp Jan 29, 2024
0bb448e
Tryy out automaxprocs and adjust radix scaling and limits
sigurdp Jan 29, 2024
ffc4a8a
Experiment with setting CPU limits
sigurdp Jan 29, 2024
46a7c45
Set back to 2 cpus
sigurdp Jan 29, 2024
e6b9abd
Try and hardcode GOMAXPROCS to 4
sigurdp Jan 29, 2024
4e8937e
Renamed folder from surface_intersect to surface_query
sigurdp Feb 1, 2024
898873b
Use doubles for coords. Cleanup consts
HansKallekleiv Feb 1, 2024
20cca8e
Use doubles for coords. Cleanup consts
HansKallekleiv Feb 1, 2024
3bf4f22
fix go test
HansKallekleiv Feb 1, 2024
1b1d877
Merge branch 'main' into struct-unc-fast2
HansKallekleiv Feb 5, 2024
9f99d6d
Cleanup
HansKallekleiv Feb 6, 2024
355acf9
Merge branch 'struct-unc-fast2' of github.com:hanskallekleiv/webviz i…
HansKallekleiv Feb 6, 2024
9134b76
cleanup
HansKallekleiv Feb 6, 2024
dcc8c46
Merge remote-tracking branch 'upstream/main' into struct-unc-fast2
HansKallekleiv Feb 6, 2024
1f5e3f8
Cleanup
HansKallekleiv Feb 9, 2024
25f8843
Various frontend fixes
HansKallekleiv Feb 9, 2024
4f4c598
cleanup
HansKallekleiv Feb 9, 2024
b369872
cleanup
HansKallekleiv Feb 9, 2024
88fb822
cleanup
HansKallekleiv Feb 9, 2024
b8b10fa
cleanup
HansKallekleiv Feb 9, 2024
f258e6e
Merge remote-tracking branch 'upstream/main' into struct-unc-fast2
HansKallekleiv Feb 9, 2024
686e389
cleanup
HansKallekleiv Feb 9, 2024
e10589b
cleanup
HansKallekleiv Feb 9, 2024
575872e
cleanup
HansKallekleiv Feb 9, 2024
4645bcd
cleanup
HansKallekleiv Feb 9, 2024
8860edd
Removed old/stale dockerfile
sigurdp Feb 12, 2024
94813eb
Set keepalive_timeout back to 65 and removed proxy_read_timeout
sigurdp Feb 12, 2024
7fbf5a0
Removed websocketfriendly ingressConfiguration from radixconfig.yml
sigurdp Feb 12, 2024
6fb8e83
Moved specification of URL for surface query to config.py
sigurdp Feb 12, 2024
1cf8a4d
rename type
HansKallekleiv Feb 12, 2024
7884035
Fix selectedSurfaceNames
HansKallekleiv Feb 12, 2024
e36c3e1
Merge branch 'struct-unc-fast2' of github.com:hanskallekleiv/webviz i…
HansKallekleiv Feb 12, 2024
f53a645
Remove console
HansKallekleiv Feb 12, 2024
625f4eb
Renamed and moved the interface file for surface query service
sigurdp Feb 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/webviz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ jobs:
run: |
pytest ./tests/unit

go:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: "1.21.x"
- name: Install dependencies
working-directory: ./backend_go/surface_query
run: |
go get .
- name: Test with Go
working-directory: ./backend_go/surface_query
run: |
go test ./...

build_docker_images:
runs-on: ubuntu-latest

Expand Down
41 changes: 40 additions & 1 deletion backend/src/backend/primary/routers/surface/router.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from typing import List, Union, Optional

from fastapi import APIRouter, Body, Depends, HTTPException, Query, Response
from fastapi import APIRouter, Depends, HTTPException, Query, Response, Body

from src.services.sumo_access.surface_access import SurfaceAccess
from src.services.smda_access.stratigraphy_access import StratigraphyAccess
Expand All @@ -13,10 +13,13 @@
from src.backend.auth.auth_helper import AuthHelper
from src.backend.utils.perf_metrics import PerfMetrics
from src.services.sumo_access._helpers import SumoCase
from src.services.surface_query_service.surface_query_service import batch_sample_surface_in_points_async
from src.services.surface_query_service.surface_query_service import RealizationSampleResult

from . import converters
from . import schemas


LOGGER = logging.getLogger(__name__)

router = APIRouter()
Expand Down Expand Up @@ -236,3 +239,39 @@ async def post_get_surface_intersection(
surface_intersection_response = converters.to_api_surface_intersection(surface_intersection)

return surface_intersection_response


@router.post("/sample_surface_in_points")
async def post_sample_surface_in_points(
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
surface_name: str = Query(description="Surface name"),
surface_attribute: str = Query(description="Surface attribute"),
realization_nums: List[int] = Query(description="Realization numbers"),
sample_points: schemas.PointSetXY = Body(embed=True),
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
) -> List[schemas.SurfaceRealizationSampleValues]:

sumo_access_token = authenticated_user.get_sumo_access_token()

result_arr: List[RealizationSampleResult] = await batch_sample_surface_in_points_async(
sumo_access_token=sumo_access_token,
case_uuid=case_uuid,
iteration_name=ensemble_name,
surface_name=surface_name,
surface_attribute=surface_attribute,
realizations=realization_nums,
x_coords=sample_points.x_points,
y_coords=sample_points.y_points,
)

intersections: List[schemas.SurfaceRealizationSampleValues] = []
for res in result_arr:
intersections.append(
schemas.SurfaceRealizationSampleValues(
realization=res.realization,
sampled_values=res.sampledValues,
)
)

return intersections
10 changes: 10 additions & 0 deletions backend/src/backend/primary/routers/surface/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,13 @@ class SurfaceIntersectionCumulativeLengthPolyline(BaseModel):
x_points: List[float]
y_points: List[float]
cum_lengths: List[float]


class SurfaceRealizationSampleValues(BaseModel):
realization: int
sampled_values: list[float]


class PointSetXY(BaseModel):
x_points: list[float]
y_points: list[float]
2 changes: 2 additions & 0 deletions backend/src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
GRAPH_SCOPES = ["User.Read", "User.ReadBasic.All"]
VDS_HOST_ADDRESS = os.environ["WEBVIZ_VDS_HOST_ADDRESS"]

SURFACE_QUERY_URL = "http://surface-query:5001"

RESOURCE_SCOPES_DICT = {
"sumo": [f"api://{sumo_app_reg[SUMO_ENV]['RESOURCE_ID']}/access_as_user"],
"smda": [SMDA_RESOURCE_SCOPE],
Expand Down
9 changes: 0 additions & 9 deletions backend/src/services/sumo_access/surface_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,3 @@ def _make_intersection(surface: xtgeo.RegularSurface, xtgeo_fencespec: np.ndarra
zval=line[:, 1].tolist(),
)
return intersection


def _make_intersections(
surfaces: List[xtgeo.RegularSurface], xtgeo_fencespec: np.ndarray
) -> List[XtgeoSurfaceIntersectionResult]:
if len(surfaces) == 0:
return []

return [_make_intersection(surface, xtgeo_fencespec) for surface in surfaces]
149 changes: 149 additions & 0 deletions backend/src/services/surface_query_service/surface_query_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import logging
from typing import Dict, List, Optional, Tuple

import httpx
import numpy as np
import requests
from fmu.sumo.explorer._utils import Utils as InternalExplorerUtils
from fmu.sumo.explorer.objects import CaseCollection
from pydantic import BaseModel
from sumo.wrapper import SumoClient

from src import config
from src.services.service_exceptions import AuthorizationError, Service

LOGGER = logging.getLogger(__name__)


class RealizationSampleResult(BaseModel):
realization: int
sampledValues: list[float]


class _RealizationObjectId(BaseModel):
realization: int
objectUuid: str


class _PointSamplingRequestBody(BaseModel):
sasToken: str
blobStoreBaseUri: str
objectIds: List[_RealizationObjectId]
xCoords: List[float]
yCoords: List[float]


class _PointSamplingResponseBody(BaseModel):
sampleResultArr: List[RealizationSampleResult]
undefLimit: float


# URL of the Go server endpoint
SERVICE_ENDPOINT = f"{config.SURFACE_QUERY_URL}/sample_in_points"

SUMO_BASE_URI = f"https://main-sumo-{config.SUMO_ENV}.radix.equinor.com/api/v1"


async def batch_sample_surface_in_points_async(
sumo_access_token: str,
case_uuid: str,
iteration_name: str,
surface_name: str,
surface_attribute: str,
realizations: Optional[List[int]],
x_coords: list[float],
y_coords: list[float],
) -> List[RealizationSampleResult]:
realization_object_ids = await _get_object_uuids_for_surface_realizations(
sumo_access_token=sumo_access_token,
case_uuid=case_uuid,
iteration_name=iteration_name,
surface_name=surface_name,
surface_attribute=surface_attribute,
realizations=realizations,
)

sas_token, blob_store_base_uri = _get_sas_token_and_blob_store_base_uri_for_case(sumo_access_token, case_uuid)

request_body = _PointSamplingRequestBody(
sasToken=sas_token,
blobStoreBaseUri=blob_store_base_uri,
objectIds=realization_object_ids,
xCoords=x_coords,
yCoords=y_coords,
)

async with httpx.AsyncClient(timeout=300) as client:
LOGGER.info(f"Running async go point sampling for surface: {surface_name}")
response: httpx.Response = await client.post(url=SERVICE_ENDPOINT, json=request_body.model_dump())

json_data: bytes = response.content
response_body = _PointSamplingResponseBody.model_validate_json(json_data)

# Replace values above the undefLimit with np.nan
for res in response_body.sampleResultArr:
values_np = np.asarray(res.sampledValues)
res.sampledValues = np.where((values_np < response_body.undefLimit), values_np, np.nan).tolist()

return response_body.sampleResultArr


async def _get_object_uuids_for_surface_realizations(
sumo_access_token: str,
case_uuid: str,
iteration_name: str,
surface_name: str,
surface_attribute: str,
realizations: Optional[List[int]],
) -> List[_RealizationObjectId]:
sumo_client = SumoClient(env=config.SUMO_ENV, token=sumo_access_token, interactive=False)
case_collection = CaseCollection(sumo_client).filter(uuid=case_uuid)
case = await case_collection.getitem_async(0)

# What about time here??
surface_collection = case.surfaces.filter(
iteration=iteration_name,
name=surface_name,
tagname=surface_attribute,
realization=realizations,
)

# Is this the right way to get hold of the object uuids?
internal_explorer_utils = InternalExplorerUtils(sumo_client)
# pylint: disable=protected-access
object_meta_list: List[Dict] = await internal_explorer_utils.get_objects_async(
500, surface_collection._query, ["_id", "fmu.realization.id"]
)

ret_list: List[_RealizationObjectId] = []
for obj_meta in object_meta_list:
ret_list.append(
_RealizationObjectId(
realization=obj_meta["_source"]["fmu"]["realization"]["id"], objectUuid=obj_meta["_id"]
)
)

return ret_list


def _get_sas_token_and_blob_store_base_uri_for_case(sumo_access_token: str, case_uuid: str) -> Tuple[str, str]:
"""
Get a SAS token and a base URI that allows reading of all children of case_uuid
The returned base uri looks something like this:
https://xxxsumoxxx.blob.core.windows.net/{case_uuid}

To actually fetch data for a blob belonging to this case, you need to form a SAS URI:
{blob_store_base_uri}/{my_blob_id}?{sas_token}
"""

req_url = f"{SUMO_BASE_URI}/objects('{case_uuid}')/authtoken"
req_headers = {"Authorization": f"Bearer {sumo_access_token}"}
res = requests.get(url=req_url, headers=req_headers, timeout=60)
if res.status_code != 200:
raise AuthorizationError(f"Failed to get SAS token for case {case_uuid}", Service.GENERAL)

body = res.json()
sas_token = body["auth"]
blob_store_base_uri = body["baseuri"].removesuffix("/")

return sas_token, blob_store_base_uri
26 changes: 26 additions & 0 deletions backend_go/surface-query-dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

FROM golang:1.21

RUN useradd --create-home --uid 1234 appuser
USER 1234

RUN go install github.com/githubnemo/CompileDaemon@latest

# This is where we'll write the compiled binary to
RUN mkdir /home/appuser/gobuild

# This step is not strictly necessary, the eventual 'go mod download' will prefill the module cache
RUN mkdir /home/appuser/goscratch
WORKDIR /home/appuser/goscratch
COPY ./backend_go/surface_query/go.mod ./
COPY ./backend_go/surface_query/go.sum ./
RUN go mod download

WORKDIR /home/appuser/backend_go/surface_query

# The build flag sets how to build after a change has been detected in the source code
# The command flag sets how to run the app after it has been built
#
# The -race flag can be added to the build option, ie "go build -race -o /x/y/z main.go" to detect race conditions
# Beware that performance will suffer quite a bit, so don't leave it in there
CMD CompileDaemon -build="go build -o /home/appuser/gobuild/ main.go" -include=go.mod -command="/home/appuser/gobuild/main" -verbose -color
35 changes: 35 additions & 0 deletions backend_go/surface-query-prod.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

FROM golang:1.21 AS build-stage

RUN useradd --create-home --uid 1234 appuser
USER 1234

WORKDIR /home/appuser/gosrc
COPY --chown=appuser ./backend_go/surface_query/ .

RUN go mod download
RUN go mod verify

RUN pwd
RUN ls -slatr

RUN mkdir /home/appuser/gobuild
RUN go build -o /home/appuser/gobuild/ main.go

WORKDIR /home/appuser/gobuild
RUN pwd
RUN ls -slatr


# Which image should we use for deployment?
FROM golang:1.21 AS runtime-stage

RUN useradd --create-home --uid 1234 appuser
USER 1234

ENV GIN_MODE=release

WORKDIR /home/appuser
COPY --from=build-stage /home/appuser/gobuild/main ./

CMD ./main
37 changes: 37 additions & 0 deletions backend_go/surface_query/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module surface_query

go 1.21

require (
github.com/gin-gonic/gin v1.9.1
github.com/lmittmann/tint v1.0.4
go.uber.org/automaxprocs v1.5.3
)

require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading