Skip to content

Commit

Permalink
Bug fixes for geoh5py and dataclasses
Browse files Browse the repository at this point in the history
* fix: update matplotlib cmap for deprecation

* fix: geoh5py block model was flipped

* fix: changing dataclasses to use default factory to prevent shared objects

* ci: changing lint rules

* style: style fixes by ruff and autoformatting by black

---------

Co-authored-by: lachlangrose <7371904+lachlangrose@users.noreply.github.com>
  • Loading branch information
lachlangrose and lachlangrose authored Feb 3, 2025
1 parent a743ac7 commit dc4158b
Show file tree
Hide file tree
Showing 17 changed files with 56 additions and 55 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: "✅ Linter"

on:
push:
branches:
- master
paths:
- '**.py'

Expand Down Expand Up @@ -47,6 +45,6 @@ jobs:
ruff check ${{env.PROJECT_FOLDER}} --fix
- uses: stefanzweifel/git-auto-commit-action@v5
with:
push_options: --force
push_options:
commit_message: "style: style fixes by ruff and autoformatting by black"

14 changes: 7 additions & 7 deletions LoopStructural/datatypes/_point.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
import numpy as np

from typing import Optional, Union
Expand All @@ -10,9 +10,9 @@

@dataclass
class ValuePoints:
locations: np.ndarray
values: np.ndarray
name: str
locations: np.ndarray = field(default_factory=lambda: np.array([[0, 0, 0]]))
values: np.ndarray = field(default_factory=lambda: np.array([0]))
name: str = "unnamed"
properties: Optional[dict] = None

def to_dict(self):
Expand Down Expand Up @@ -108,9 +108,9 @@ def from_dict(cls, d, flatten=False):

@dataclass
class VectorPoints:
locations: np.ndarray
vectors: np.ndarray
name: str
locations: np.ndarray = field(default_factory=lambda: np.array([[0, 0, 0]]))
vectors: np.ndarray = field(default_factory=lambda: np.array([[0, 0, 0]]))
name: str = "unnamed"
properties: Optional[dict] = None

def to_dict(self):
Expand Down
14 changes: 7 additions & 7 deletions LoopStructural/datatypes/_structured_grid.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
from typing import Dict
import numpy as np
from dataclasses import dataclass
from dataclasses import dataclass, field
from LoopStructural.utils import getLogger

logger = getLogger(__name__)


@dataclass
class StructuredGrid:
origin: np.ndarray
step_vector: np.ndarray
nsteps: np.ndarray
cell_properties: Dict[str, np.ndarray]
properties: Dict[str, np.ndarray]
name: str
origin: np.ndarray = field(default_factory=lambda: np.array([0, 0, 0]))
step_vector: np.ndarray = field(default_factory=lambda: np.array([1, 1, 1]))
nsteps: np.ndarray = field(default_factory=lambda: np.array([10, 10, 10]))
cell_properties: Dict[str, np.ndarray] = field(default_factory=dict)
properties: Dict[str, np.ndarray] = field(default_factory=dict)
name: str = "default_grid"

def to_dict(self):
return {
Expand Down
6 changes: 3 additions & 3 deletions LoopStructural/datatypes/_surface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import Optional
import numpy as np
import io
Expand All @@ -9,8 +9,8 @@

@dataclass
class Surface:
vertices: np.ndarray
triangles: np.ndarray
vertices: np.ndarray = field(default_factory=lambda: np.array([[0, 0, 0]]))
triangles: np.ndarray = field(default_factory=lambda: np.array([[0, 0, 0]]))
normals: Optional[np.ndarray] = None
name: str = 'surface'
values: Optional[np.ndarray] = None
Expand Down
6 changes: 4 additions & 2 deletions LoopStructural/export/geoh5.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ def add_structured_grid_to_geoh5(filename, structured_grid, overwrite=True, grou
if structured_grid.cell_properties is not None:
for k, v in structured_grid.cell_properties.items():
data[k] = {
'association': "CELL",
"values": np.rot90(v.reshape(structured_grid.nsteps - 1, order="F")).flatten(),
"association": "CELL",
"values": np.flipud(
np.rot90(v.reshape(structured_grid.nsteps - 1, order="F"), 1)
).flatten(),
}
block = geoh5py.objects.BlockModel.create(
workspace,
Expand Down
1 change: 1 addition & 0 deletions LoopStructural/interpolators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,5 @@ class InterpolatorType(IntEnum):

from ._interpolator_factory import InterpolatorFactory
from ._interpolator_builder import InterpolatorBuilder

# from ._api import LoopInterpolator
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
"""
""" """

import numpy as np
from typing import Optional
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
"""
""" """

import numpy as np
from typing import Optional
Expand Down
4 changes: 1 addition & 3 deletions LoopStructural/modelling/features/fold/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
"""
""" """

from ._fold import FoldEvent
from ._svariogram import SVariogram
Expand Down
6 changes: 4 additions & 2 deletions LoopStructural/modelling/input/process_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def __init__(
self.contacts = contacts
self._contact_orientations = None
self.contact_orientations = contact_orientations
self._fault_orientations = pd.DataFrame(columns=["X", "Y", "Z", "gx", "gy", "gz", "coord", "feature_name"])
self._fault_orientations = pd.DataFrame(
columns=["X", "Y", "Z", "gx", "gy", "gz", "coord", "feature_name"]
)
self.fault_orientations = fault_orientations
self._fault_locations = None
self.fault_locations = fault_locations
Expand Down Expand Up @@ -313,7 +315,7 @@ def fault_properties(self, fault_properties):
pts = self.fault_orientations.loc[
self.fault_orientations["feature_name"] == fname, ["gx", "gy", "gz"]
]
if len(pts)>0:
if len(pts) > 0:
fault_properties.loc[
fname,
["avgNormalEasting", "avgNormalNorthing", "avgNormalAltitude"],
Expand Down
2 changes: 1 addition & 1 deletion LoopStructural/utils/_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def fit(
self,
values: Optional[Union[list, int, float]],
name: Optional[Union[List[str], str]] = None,
local=False
local=False,
) -> surface_list:
"""Extract isosurfaces from the interpolator
Expand Down
4 changes: 3 additions & 1 deletion LoopStructural/utils/colours.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ def random_colour(n: int = 1, cmap='tab20'):
List of colours in the form of (r,g,b,a) tuples
"""
from matplotlib import colormaps as cm

colours = []
for _i in range(n):
colours.append(cm.get_cmap(cmap)(rng.random()))

return colours


def random_hex_colour(n: int = 1, cmap='tab20'):
"""
Generate a list of random colours
Expand All @@ -46,4 +48,4 @@ def random_hex_colour(n: int = 1, cmap='tab20'):
for _i in range(n):
colours.append(cm.get_cmap(cmap)(rng.random()))

return [f'#{int(c[0]*255):02x}{int(c[1]*255):02x}{int(c[2]*255):02x}' for c in colours]
return [f'#{int(c[0]*255):02x}{int(c[1]*255):02x}{int(c[2]*255):02x}' for c in colours]
6 changes: 3 additions & 3 deletions examples/1_basic/plot_3_model_visualisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
1c. Visualising models
===============================
The following tutorial will demonstrate how to use the Loop structural visualisation module.
The following tutorial will demonstrate how to use the Loop structural visualisation module.
This module provides a wrapper for the lavavu model that is written by
Owen Kaluza.
Owen Kaluza.
Lavavu allows for interactive visualisation of 3D models within a jupyter
notebook environment.
notebook environment.
"""

Expand Down
2 changes: 1 addition & 1 deletion examples/3_fault/fault_network.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
3b. Modelling a fault network in LoopStructural
===============================================
Uses GeologicalModel, ProcessInputData and Loop3DView from LoopStructural library.
Uses GeologicalModel, ProcessInputData and Loop3DView from LoopStructural library.
Also using geopandas to read a shapefile, pandas, matplotlib and numpy."""

import LoopStructural
Expand Down
10 changes: 5 additions & 5 deletions examples/4_advanced/_5_using_logging.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
1e. Using logging
===============================
LoopStructural has a number of levels of logging incorporated in the code to allow
LoopStructural has a number of levels of logging incorporated in the code to allow
for recording and debugging the models.
The python logging module allows for 5 levels of messages to be returned to the user:
1. Debug messages
Expand All @@ -11,14 +11,14 @@
5. Critical messages
LoopStructural uses all of these logging levels to report the various aspects of the model
building process.
Generally, the user only needs to be aware of the warning and error messages.
building process.
Generally, the user only needs to be aware of the warning and error messages.
By default the warning, error and critical messages are returned to the console and will appear to
the user.
the user.
All messages except for debug are recorded to a file :code:`default-loop-structural-logfile.log`.
Lets have a look at the logging from the Claudius model.
Lets have a look at the logging from the Claudius model.
"""

from LoopStructural import GeologicalModel
Expand Down
6 changes: 3 additions & 3 deletions examples/4_advanced/_7_local_weights.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""
============================
1f. Local data weighting
1f. Local data weighting
============================
LoopStructural primarily uses discrete interpolation methods (e.g. finite differences on a regular grid,
or linear/quadratic on tetrahedral meshes). The interpolation is determined by combining a regularisation
term and the data weights. The default behaviour is for every data point to be weighted equally, however
it is also possible to vary these weights per datapoint.
term and the data weights. The default behaviour is for every data point to be weighted equally, however
it is also possible to vary these weights per datapoint.
"""

Expand Down
20 changes: 10 additions & 10 deletions examples/4_advanced/_model_from_geological_map.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""
4.a Building a model using the ProcessInputData
===============================================
There is a disconnect between the input data required by 3D modelling software and a geological map.
In LoopStructural the geological model is a collection of implicit functions that can be mapped to
the distribution of stratigraphic units and the location of fault surfaces. Each implicit function
is approximated from the observations of the stratigraphy, this requires grouping conformable geological
units together as a singla implicit function, mapping the different stratigraphic horizons to a value of
the implicit function and determining the relationship with geological structures such as faults.
In this tutorial the **ProcessInputData** class will be used to convert geologically meaningful datasets to input for LoopStructural.
There is a disconnect between the input data required by 3D modelling software and a geological map.
In LoopStructural the geological model is a collection of implicit functions that can be mapped to
the distribution of stratigraphic units and the location of fault surfaces. Each implicit function
is approximated from the observations of the stratigraphy, this requires grouping conformable geological
units together as a singla implicit function, mapping the different stratigraphic horizons to a value of
the implicit function and determining the relationship with geological structures such as faults.
In this tutorial the **ProcessInputData** class will be used to convert geologically meaningful datasets to input for LoopStructural.
The **ProcessInputData** class uses:
* stratigraphic contacts* stratigraphic orientations* stratigraphic thickness* stratigraphic order
To build a model of stratigraphic horizons and:* fault locations* fault orientations * fault properties* fault edges
To use incorporate faults into the geological model. """
* stratigraphic contacts* stratigraphic orientations* stratigraphic thickness* stratigraphic order
To build a model of stratigraphic horizons and:* fault locations* fault orientations * fault properties* fault edges
To use incorporate faults into the geological model."""

##############################
# Imports
Expand Down

0 comments on commit dc4158b

Please sign in to comment.