Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 65 additions & 0 deletions geoapps_utils/modelling/plates.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
# '
# '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

import warnings
from typing import Self

import numpy as np
from geoh5py import Workspace
from geoh5py.objects import Octree, Surface
from geoh5py.objects.maxwell_plate import MaxwellPlate, PlateGeometry, PlatePosition
from geoh5py.shared.utils import fetch_active_workspace
from pydantic import BaseModel, ConfigDict, Field

Expand Down Expand Up @@ -55,6 +58,44 @@ class PlateModel(BaseModel):
direction: float = Field(default=0.0, alias="dip_direction")
dip: float = 0.0

@classmethod
def from_maxwell_plate_geometry(cls, geometry: PlateGeometry) -> Self:
"""Construct a PlateModel from geoh5py MaxwellPlate geometry."""

if geometry.rotation != 0.0:
warnings.warn(
"Plunging plate models are not yet implemented. "
"Ignoring the maxwell plate geometry rotation.",
category=UserWarning,
stacklevel=2,
)

return cls(
strike_length=geometry.length,
dip_length=geometry.width,
width=geometry.thickness,
easting=geometry.position.x,
northing=geometry.position.y,
elevation=geometry.position.z,
direction=geometry.dip_direction,
dip=geometry.dip,
)
Comment thread
benk-mira marked this conversation as resolved.

def to_maxwell_plate_geometry(self) -> PlateGeometry:
"""Convert the PlateModel to geoh5py PlateGeometry object."""
return PlateGeometry(
position=PlatePosition(
x=self.easting,
y=self.northing,
z=self.elevation,
),
dip=self.dip,
dip_direction=self.direction,
length=self.strike_length,
width=self.dip_length,
thickness=self.width,
)

@property
def origin(self) -> tuple[float, float, float]:
return (self.easting, self.northing, self.elevation)
Expand All @@ -70,6 +111,30 @@ class Plate:
def __init__(self, params: PlateModel):
self.params = params

@classmethod
def from_maxwell_plate(cls, plate: MaxwellPlate) -> Self:
"""
Construct a Plate from geoh5py MaxwellPlate object.

:param plate: Maxwell plate object to construct the Plate from.
"""
if plate.geometry is None:
raise ValueError("Maxwell plate must have its geometry set.")
return cls(PlateModel.from_maxwell_plate_geometry(plate.geometry))

def to_maxwell_plate(self, workspace: Workspace, **plate_kwargs) -> MaxwellPlate:
"""
Save the Plate as a MaxwellPlate entity in the provided workspace.

:param workspace: Workspace to save the MaxwellPlate in.
:param plate_kwargs: Arguments passed on to the MaxwellPlate instantiation.
"""
with fetch_active_workspace(workspace) as ws:
plate = MaxwellPlate.create(
ws, geometry=self.params.to_maxwell_plate_geometry(), **plate_kwargs
)
return plate

def mask(self, mesh: Octree) -> np.ndarray:
"""
Return a mask for generating models with a plate anomaly.
Expand Down
27 changes: 27 additions & 0 deletions tests/plates_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
from __future__ import annotations

import numpy as np
import pytest
from geoh5py import Workspace
from geoh5py.objects import BlockModel

from geoapps_utils.modelling.plates import (
Plate,
PlateModel,
bounding_box,
inside_plate,
Expand Down Expand Up @@ -224,3 +226,28 @@ def test_plate_alias():
)
assert plate.direction == 90
assert "dip_direction" in plate.model_dump(by_alias=True)


def test_maxwell_plate_integration(tmp_path):

plate = Plate(
PlateModel(
strike_length=100,
dip_length=300,
width=20,
easting=100.0,
northing=0.0,
elevation=0.0,
dip_direction=90,
dip=45,
)
)
with Workspace(tmp_path / "test.geoh5") as workspace:
maxwell_plate = plate.to_maxwell_plate(workspace)
assert maxwell_plate.geometry is not None
maxwell_plate.geometry.rotation = 10.0

with pytest.warns(UserWarning, match="Plunging plate"):
new_plate = Plate.from_maxwell_plate(maxwell_plate)

assert new_plate.params == plate.params
Loading