Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Apr 29, 2024
1 parent ce0d50b commit 303a5f1
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type InteractionUpdateWrapperProps = {
wellboreUuid: string | null;
intersectionReferenceSystem?: IntersectionReferenceSystem;
workbenchServices: WorkbenchServices;
viewContext: ViewContext<any, any>;
viewContext: ViewContext<any, any, any, any>;
} & SubsurfaceViewerWrapperProps;

export function InteractionUpdateWrapper(props: InteractionUpdateWrapperProps): React.ReactNode {
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/modules/Intersection/loadModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import { MODULE_NAME } from "./registerModule";
import { Settings } from "./settings/settings";
import { SettingsToViewInterface, interfaceInitialization } from "./settingsToViewInterface";
import { State } from "./state";
import { ViewAtoms, viewAtomsInitialization } from "./view/atoms/atomDefinitions";
import { View } from "./view/view";

const module = ModuleRegistry.initModule<State, SettingsToViewInterface>(MODULE_NAME, {}, {}, interfaceInitialization);
const module = ModuleRegistry.initModule<State, SettingsToViewInterface, Record<string, never>, ViewAtoms>(
MODULE_NAME,
{},
{},
interfaceInitialization,
undefined,
viewAtomsInitialization
);

module.viewFC = View;
module.settingsFC = Settings;
22 changes: 22 additions & 0 deletions frontend/src/modules/Intersection/queryDataTransforms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SeismicFenceData_api } from "@api";
import { b64DecodeFloatArrayToFloat32 } from "@modules_shared/base64";

// Data structure for transformed data
// Remove the base64 encoded data and replace with a Float32Array
export type SeismicFenceData_trans = Omit<SeismicFenceData_api, "fence_traces_b64arr"> & {
fenceTracesFloat32Arr: Float32Array;
};

export function transformSeismicFenceData(apiData: SeismicFenceData_api): SeismicFenceData_trans {
const startTS = performance.now();

const { fence_traces_b64arr, ...untransformedData } = apiData;
const dataFloat32Arr = b64DecodeFloatArrayToFloat32(fence_traces_b64arr);

console.debug(`transformSurfaceData() took: ${(performance.now() - startTS).toFixed(1)}ms`);

return {
...untransformedData,
fenceTracesFloat32Arr: dataFloat32Arr,
};
}
3 changes: 2 additions & 1 deletion frontend/src/modules/Intersection/registerModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { SyncSettingKey } from "@framework/SyncSettings";
import { preview } from "./preview";
import { SettingsToViewInterface } from "./settingsToViewInterface";
import { State } from "./state";
import { ViewAtoms } from "./view/atoms/atomDefinitions";

export const MODULE_NAME = "Intersection";

ModuleRegistry.registerModule<State, SettingsToViewInterface>({
ModuleRegistry.registerModule<State, SettingsToViewInterface, Record<string, never>, ViewAtoms>({
moduleName: MODULE_NAME,
defaultTitle: "Intersection",
description: "Intersection",
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/modules/Intersection/settings/atoms/derivedAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SeismicDataType, SeismicSurveyType } from "@modules/Intersection/typesA
import { atom } from "jotai";

import {
userSelectedCustomIntersectionPolylineIdAtom,
userSelectedGridModelNameAtom,
userSelectedGridModelParameterDateOrIntervalAtom,
userSelectedGridModelParameterNameAtom,
Expand Down Expand Up @@ -253,3 +254,21 @@ export const selectedSeismicDateOrIntervalStringAtom = atom((get) => {

return userSelectedSeismicDateOrIntervalString;
});

export const selectedCustomIntersectionPolylineIdAtom = atom((get) => {
const userSelectedCustomIntersectionPolylineId = get(userSelectedCustomIntersectionPolylineIdAtom);
const customIntersectionPolylines = get(IntersectionPolylinesAtom);

if (!customIntersectionPolylines.length) {
return null;
}

if (
!userSelectedCustomIntersectionPolylineId ||
!customIntersectionPolylines.some((el) => el.id === userSelectedCustomIntersectionPolylineId)
) {
return customIntersectionPolylines[0].id;
}

return userSelectedCustomIntersectionPolylineId;
});
11 changes: 7 additions & 4 deletions frontend/src/modules/Intersection/settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
availableSeismicAttributesAtom,
availableSeismicDateOrIntervalStringsAtom,
availableUserCreatedIntersectionPolylinesAtom,
selectedCustomIntersectionPolylineIdAtom,
selectedGridModelNameAtom,
selectedGridModelParameterDateOrIntervalAtom,
selectedGridModelParameterNameAtom,
Expand All @@ -54,8 +55,6 @@ import {
import { SettingsToViewInterface } from "../settingsToViewInterface";
import {
addCustomIntersectionPolylineEditModeActiveAtom,
intersectionTypeAtom,
selectedCustomIntersectionPolylineIdAtom,
selectedEnsembleIdentAtom,
selectedWellboreAtom,
} from "../sharedAtoms/sharedAtoms";
Expand All @@ -66,8 +65,11 @@ import {
SeismicSurveyType,
SeismicSurveyTypeToStringMapping,
} from "../typesAndEnums";
import { ViewAtoms } from "../view/atoms/atomDefinitions";

export function Settings(props: ModuleSettingsProps<State, SettingsToViewInterface>): JSX.Element {
export function Settings(
props: ModuleSettingsProps<State, SettingsToViewInterface, Record<string, never>, ViewAtoms>
): JSX.Element {
const ensembleSet = props.workbenchSession.getEnsembleSet();
const statusWriter = useSettingsStatusWriter(props.settingsContext);

Expand All @@ -88,7 +90,8 @@ export function Settings(props: ModuleSettingsProps<State, SettingsToViewInterfa

const polylineAddModeActive = useAtomValue(addCustomIntersectionPolylineEditModeActiveAtom);

const [intersectionType, setIntersectionType] = useAtom(intersectionTypeAtom);
const [intersectionType, setIntersectionType] =
props.settingsContext.useSettingsToViewInterfaceState("intersectionType");

const selectedEnsembleIdent = useAtomValue(selectedEnsembleIdentAtom);
const setSelectedEnsembleIdent = useSetAtom(userSelectedEnsembleIdentAtom);
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/modules/Intersection/settingsToViewInterface.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { BoundingBox3d_api } from "@api";
import { EnsembleIdent } from "@framework/EnsembleIdent";
import { InterfaceInitialization } from "@framework/UniDirectionalSettingsToViewInterface";
import { IntersectionType } from "@framework/types/intersection";

import { userSelectedSeismicDataTypeAtom } from "./settings/atoms/baseAtoms";
import {
selectedCustomIntersectionPolylineIdAtom,
selectedGridModelBoundingBox3dAtom,
selectedGridModelNameAtom,
selectedGridModelParameterDateOrIntervalAtom,
Expand All @@ -12,6 +14,7 @@ import {
selectedSeismicAttributeAtom,
selectedSeismicDateOrIntervalStringAtom,
} from "./settings/atoms/derivedAtoms";
import { selectedEnsembleIdentAtom } from "./sharedAtoms/sharedAtoms";
import { SeismicDataType } from "./typesAndEnums";

export type SettingsToViewInterface = {
Expand All @@ -20,9 +23,11 @@ export type SettingsToViewInterface = {
gridLayer: number;
zFactor: number;
intersectionExtensionLength: number;
intersectionType: IntersectionType;
curveFittingEpsilon: number;
};
derivedStates: {
ensembleIdent: EnsembleIdent | null;
realization: number | null;
gridModelName: string | null;
gridModelBoundingBox3d: BoundingBox3d_api | null;
Expand All @@ -31,6 +36,7 @@ export type SettingsToViewInterface = {
seismicAttribute: string | null;
seismicDateOrIntervalString: string | null;
seismicDataType: SeismicDataType;
selectedCustomIntersectionPolylineId: string | null;
};
};

Expand All @@ -40,9 +46,13 @@ export const interfaceInitialization: InterfaceInitialization<SettingsToViewInte
gridLayer: 1,
zFactor: 1,
intersectionExtensionLength: 1000,
intersectionType: IntersectionType.WELLBORE,
curveFittingEpsilon: 5,
},
derivedStates: {
ensembleIdent: (get) => {
return get(selectedEnsembleIdentAtom);
},
realization: (get) => {
return get(selectedRealizationAtom);
},
Expand All @@ -67,5 +77,8 @@ export const interfaceInitialization: InterfaceInitialization<SettingsToViewInte
seismicDataType: (get) => {
return get(userSelectedSeismicDataTypeAtom);
},
selectedCustomIntersectionPolylineId: (get) => {
return get(selectedCustomIntersectionPolylineIdAtom);
},
},
};
19 changes: 0 additions & 19 deletions frontend/src/modules/Intersection/sharedAtoms/sharedAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,7 @@ export const selectedWellboreAtom = atom((get) => {
};
});

export const intersectionTypeAtom = atom<IntersectionType>(IntersectionType.WELLBORE);
export const addCustomIntersectionPolylineEditModeActiveAtom = atom<boolean>(false);
export const editCustomIntersectionPolylineEditModeActiveAtom = atom<boolean>(false);

export const currentCustomIntersectionPolylineAtom = atom<number[][]>([]);

export const selectedCustomIntersectionPolylineIdAtom = atom((get) => {
const userSelectedCustomIntersectionPolylineId = get(userSelectedCustomIntersectionPolylineIdAtom);
const customIntersectionPolylines = get(IntersectionPolylinesAtom);

if (!customIntersectionPolylines.length) {
return null;
}

if (
!userSelectedCustomIntersectionPolylineId ||
!customIntersectionPolylines.some((el) => el.id === userSelectedCustomIntersectionPolylineId)
) {
return customIntersectionPolylines[0].id;
}

return userSelectedCustomIntersectionPolylineId;
});
160 changes: 160 additions & 0 deletions frontend/src/modules/Intersection/view/atoms/atomDefinitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { IntersectionReferenceSystem } from "@equinor/esv-intersection";
import { apiService } from "@framework/ApiService";
import { ModuleAtoms } from "@framework/Module";
import { UniDirectionalSettingsToViewInterface } from "@framework/UniDirectionalSettingsToViewInterface";
import { IntersectionType } from "@framework/types/intersection";
import { IntersectionPolylinesAtom } from "@framework/userCreatedItems/IntersectionPolylines";
import { transformSeismicFenceData } from "@modules/Intersection/queryDataTransforms";
import { SettingsToViewInterface } from "@modules/Intersection/settingsToViewInterface";
import { SeismicDataType } from "@modules/Intersection/typesAndEnums";
import { SeismicFenceData_trans } from "@modules/SeismicIntersection/utils/queryDataTransforms";
import { calcExtendedSimplifiedWellboreTrajectoryInXYPlane } from "@modules/_shared/utils/wellbore";
import { QueryObserverResult } from "@tanstack/react-query";

import { atom } from "jotai";
import { atomWithQuery } from "jotai-tanstack-query";

import { wellboreTrajectoryQueryAtom } from "./queryAtoms";

export type ViewAtoms = {
seismicFenceDataQueryAtom: QueryObserverResult<SeismicFenceData_trans>;
intersectionReferenceSystemAtom: IntersectionReferenceSystem | null;
};

const STALE_TIME = 60 * 1000;
const CACHE_TIME = 60 * 1000;

export function viewAtomsInitialization(
settingsToViewInterface: UniDirectionalSettingsToViewInterface<SettingsToViewInterface>
): ModuleAtoms<ViewAtoms> {
const selectedCustomIntersectionPolylineAtom = atom((get) => {
const customIntersectionPolylineId = get(
settingsToViewInterface.getAtom("selectedCustomIntersectionPolylineId")
);
const customIntersectionPolylines = get(IntersectionPolylinesAtom);

return customIntersectionPolylines.find((el) => el.id === customIntersectionPolylineId);
});

const intersectionReferenceSystemAtom = atom((get) => {
const wellboreTrajectoryQuery = get(wellboreTrajectoryQueryAtom);
const customIntersectionPolyline = get(selectedCustomIntersectionPolylineAtom);
const intersectionType = get(settingsToViewInterface.getAtom("intersectionType"));

if (intersectionType === IntersectionType.WELLBORE) {
if (!wellboreTrajectoryQuery.data) {
return null;
}

const wellboreTrajectory = wellboreTrajectoryQuery.data;

if (wellboreTrajectoryQuery) {
const path: number[][] = [];
for (const [index, northing] of wellboreTrajectory.northing_arr.entries()) {
const easting = wellboreTrajectory.easting_arr[index];
const tvd_msl = wellboreTrajectory.tvd_msl_arr[index];

path.push([easting, northing, tvd_msl]);
}
const offset = wellboreTrajectory.tvd_msl_arr[0];

const referenceSystem = new IntersectionReferenceSystem(path);
referenceSystem.offset = offset;

return referenceSystem;
}
} else if (intersectionType === IntersectionType.CUSTOM_POLYLINE && customIntersectionPolyline) {
if (customIntersectionPolyline.points.length < 2) {
return null;
}
const referenceSystem = new IntersectionReferenceSystem(
customIntersectionPolyline.points.map((point) => [point[0], point[1], 0])
);
referenceSystem.offset = 0;

return referenceSystem;
}

return null;
});

const polylineAtom = atom((get) => {
const intersectionType = get(settingsToViewInterface.getAtom("intersectionType"));
const intersectionExtensionLength = get(settingsToViewInterface.getAtom("intersectionExtensionLength"));
const curveFittingEpsilon = get(settingsToViewInterface.getAtom("curveFittingEpsilon"));
const selectedCustomIntersectionPolyline = get(selectedCustomIntersectionPolylineAtom);
const intersectionReferenceSystem = get(intersectionReferenceSystemAtom);

const polylineUtmXy: number[] = [];

if (intersectionReferenceSystem) {
if (intersectionType === IntersectionType.WELLBORE) {
const path = intersectionReferenceSystem.path;
polylineUtmXy.push(
...calcExtendedSimplifiedWellboreTrajectoryInXYPlane(
path,
intersectionExtensionLength,
curveFittingEpsilon
).flat()
);
} else if (intersectionType === IntersectionType.CUSTOM_POLYLINE && selectedCustomIntersectionPolyline) {
for (const point of selectedCustomIntersectionPolyline.points) {
polylineUtmXy.push(point[0], point[1]);
}
}
}

return polylineUtmXy;
});

const seismicFenceDataQueryAtom = atomWithQuery((get) => {
const ensembleIdent = get(settingsToViewInterface.getAtom("ensembleIdent"));
const realizationNum = get(settingsToViewInterface.getAtom("realization"));
const seismicAttribute = get(settingsToViewInterface.getAtom("seismicAttribute"));
const timeOrIntervalStr = get(settingsToViewInterface.getAtom("seismicDateOrIntervalString"));
const observed = get(settingsToViewInterface.getAtom("seismicDataType")) === SeismicDataType.OBSERVED;
const polyline = get(polylineAtom);

const caseUuid = ensembleIdent?.getCaseUuid();
const ensembleName = ensembleIdent?.getEnsembleName();

const xPoints: number[] = [];
const yPoints: number[] = [];
for (let i = 0; i < polyline.length; i += 2) {
xPoints.push(polyline[i]);
yPoints.push(polyline[i + 1]);
}

return {
queryKey: [
"postGetSeismicFence",
caseUuid,
ensembleName,
realizationNum,
seismicAttribute,
timeOrIntervalStr,
observed,
polyline,
],
queryFn: () =>
apiService.seismic.postGetSeismicFence(
caseUuid ?? "",
ensembleName ?? "",
realizationNum ?? 0,
seismicAttribute ?? "",
timeOrIntervalStr ?? "",
observed ?? false,
{ polyline: { x_points: xPoints, y_points: yPoints } }
),
select: transformSeismicFenceData,
staleTime: STALE_TIME,
gcTime: CACHE_TIME,
enabled: !!(caseUuid && ensembleName && realizationNum !== null && seismicAttribute && timeOrIntervalStr),
};
});

return {
seismicFenceDataQueryAtom,
intersectionReferenceSystemAtom,
};
}
Loading

0 comments on commit 303a5f1

Please sign in to comment.