Skip to content

Commit 57ceb77

Browse files
committed
Merge branch 'master' of github.com:Loop3D/loopresources
2 parents 5d7f802 + 271f67d commit 57ceb77

File tree

6 files changed

+126
-27
lines changed

6 files changed

+126
-27
lines changed

.github/workflows/pypi.yml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
1-
name: "📦 PyPI "
1+
name: Deploy to PYPI
2+
23
on:
34
workflow_dispatch:
4-
55
jobs:
6-
make_sdist:
7-
name: Make SDist
6+
7+
sdist:
8+
name: Build sdist
89
runs-on: ubuntu-latest
910
steps:
1011
- uses: actions/checkout@v4
11-
12-
- name: Build SDist
12+
- uses: actions/setup-python@v5
13+
- name: Install dependencies
1314
run: |
15+
python -m pip install --upgrade pip
1416
pip install build
15-
python -m build
16-
17+
- name: Build sdist
18+
run: python -m build --sdist
1719
- uses: actions/upload-artifact@v4
1820
with:
1921
name: dist
20-
path: dist/
21-
22-
upload_to_pypi:
23-
needs: ["make_sdist"]
24-
runs-on: "ubuntu-latest"
22+
path: ./dist/*.tar.gz
2523

24+
publish:
25+
name: Publish wheels to pypi
26+
runs-on: ubuntu-latest
27+
permissions:
28+
# IMPORTANT: this permission is mandatory for trusted publishing
29+
id-token: write
30+
needs: sdist
2631
steps:
2732
- uses: actions/download-artifact@v4
2833
with:
2934
name: dist
3035
path: dist
36+
- name: copy to wheelhouse
37+
run: |
38+
# cp -r wheelhouse/*/*.whl dist
3139
- uses: pypa/gh-action-pypi-publish@release/v1
3240
with:
33-
skip_existing: true
41+
skip-existing: true
3442
verbose: true
35-
user: ${{ secrets.PYPI_USERNAME }}
36-
password: ${{ secrets.PYPI_PASSWORD }}
43+
packages-dir: dist/

docs/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"examples_dirs": "../../examples", # path to your example scripts
5656
"gallery_dirs": "auto_examples", # path to where to save gallery generated output
5757
"filename_pattern": "/plot_", # pattern to match example files
58-
"ignore_pattern": "__init__\.py", # ignore __init__.py files
58+
"ignore_pattern": "__init__.py", # ignore __init__.py files
5959
"download_all_examples": False,
6060
"min_reported_time": 0,
6161
"thumbnail_size": (200, 200),
@@ -71,7 +71,7 @@
7171
"icon_links": [
7272
{
7373
"name": "GitHub",
74-
"url": "https://github.com/loop3d/LoopStructural",
74+
"url": "https://github.com/loop3d/loopresources",
7575
"icon": "fab fa-github-square",
7676
},
7777
{

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ The library has three main goals:
8383
.. toctree::
8484
:hidden:
8585

86-
auto_examples/index
86+
_auto_examples/index
8787
tutorials/index
8888

8989
.. toctree::
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
# 1 - Desurveying Drillholes
22

3-
Desurveying converts downhole survey measurements into 3D spatial coordinates along the drillhole path. This is critical for accurate subsurface modeling and resource estimation.
3+
Desurveying converts downhole survey measurements into 3D spatial coordinates along the drillhole path.
44

5-
### **Assumptions**
5+
### Assumptions
66

77
* **Azimuth**: Angle measured clockwise from **true north** (degrees).
88
* **Dip**: Angle from **horizontal**, where **negative values indicate downward inclination**.
99
* **Depth**: Measured along the drillhole from the collar.
1010

1111

1212

13-
### **Methods**
13+
### Methods
1414

1515
* **Minimum Curvature**
1616
Applied when more than two survey points exist. This method assumes a smooth arc between points, minimizing deviation from true curvature.
1717
* **Tangent Method**
1818
Used when only two points exist (collar and one survey), assuming a straight line between them.
1919

20-
### **Resampling**
20+
### Resampling
2121

2222
Drillhole paths can be resampled into smaller intervals for modelling or interpolation.
2323

24-
* Loopresources uses **Slerp (Spherical Linear Interpolation)** to interpolate orientations smoothly between survey points, preserving directional accuracy.
24+
* Loopresources uses **Slerp (Spherical Linear Interpolation)** to interpolate orientations smoothly between survey points, preserving directional accuracy and then performs minimum curvature desurveying on these interpolated points.
2525

26-
***
27-
28-
Would you like me to **extend this with a code snippet showing how to call your desurvey function**, or **add a diagram illustrating azimuth/dip conventions and curvature vs tangent paths**?
26+
### Mapping properties
27+
LoopResouces allows mapping of additional properties (e.g., lithology, assay, structure) along the drillhole path during desurveying. This can either be done by desurveying the
28+
mid point of each interval, or the to and from depths of each interval. Or by resampling the property
2929

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
Find Drillhole intersection
3+
=============================
4+
5+
This example demonstrates the basic usage of the DrillholeDatabase class
6+
for a single drillhole and finding the intersection with a LoopStructural function
7+
and visualising the model, drillhole and intersection point using Loop3DView/Pyvista
8+
"""
9+
10+
import pandas as pd
11+
from loopresources import DrillholeDatabase
12+
import pyvista as pv
13+
import numpy as np
14+
from LoopStructural import GeologicalModel
15+
from LoopStructural.utils import strikedip2vector
16+
from LoopStructural.visualisation import Loop3DView
17+
18+
#############################################################################
19+
# Create our LoopStrutural Model
20+
# -----------------------------
21+
model = GeologicalModel([0, 0, 0], [10, 10, 10])
22+
data = pd.DataFrame(
23+
{
24+
"X": [1, 2, 3, 4, 5],
25+
"Y": [5, 5, 5, 5, 5],
26+
"Z": [10, 10, 10, 10, 10],
27+
"val": [0] * 5,
28+
"nx": [4.32978028e-17] * 5,
29+
"ny": [-7.07106781e-01] * 5,
30+
"nz": [7.07106781e-01] * 5,
31+
'feature_name': ['fault'] * 5,
32+
}
33+
)
34+
model.create_and_add_fault('fault', displacement=1.0, data=data)
35+
36+
#############################################################################
37+
# Create Drillhole Data
38+
# -----------------------------
39+
collar = pd.DataFrame(
40+
{
41+
"HOLEID": ["DH1"],
42+
"EAST": [0],
43+
"NORTH": [0],
44+
"RL": [10],
45+
"DEPTH": [5],
46+
}
47+
)
48+
survey = pd.DataFrame(
49+
{
50+
"HOLEID": ["DH1", "DH1", "DH1"],
51+
"DEPTH": [0, 2, 5],
52+
"AZIMUTH": [0, 0, 0],
53+
"DIP": [-60, -62, -50],
54+
}
55+
)
56+
57+
dhdb = DrillholeDatabase(survey=survey, collar=collar)
58+
59+
#############################################################################
60+
# Find Intersection
61+
# -----------------------------
62+
# Find intersection of drillhole with geological model fault
63+
# LoopStructural uses a global and local coordinate system, we need to ensure that
64+
# the implicit functions are evaluated using the global coordinates.
65+
# To do this we can use the model.evaluate_feature_value(feature_name, coords) method
66+
# The `find_implicit_function_intersection` method of the DrillHole class can be used to find the intersection.
67+
# It requires a function that takes coords as an input and returns the implicit function value.
68+
# We can use a lambda function to wrap the model's method.
69+
#
70+
71+
pts = dhdb["DH1"].find_implicit_function_intersection(
72+
lambda xyz: model.evaluate_feature_value('fault', xyz)
73+
)
74+
print(f"\nIntersection points: \n {pts}")
75+
76+
viewer = Loop3DView(model)
77+
viewer.plot_surface(model['fault'], 0.0)
78+
viewer.add_mesh(model.bounding_box.vtk().outline(), color='black')
79+
viewer.add_mesh(dhdb['DH1'].vtk())
80+
viewer.add_points(pts[['x', 'y', 'z']].values, color='blue', point_size=10)
81+
viewer.show()
82+
83+
#############################################################################
84+
# We can also calculate the orientation of the implicit function at the intersection points
85+
86+
normals = model.evaluate_feature_gradient('fault', pts[['x', 'y', 'z']].values)
87+
print(f"\nIntersection normals: \n {normals}")

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ optional-dependencies.dev = [
5858
"sphinx",
5959
"sphinx-rtd-theme",
6060
]
61+
optional-dependencies.docs = [
62+
"sphinx",
63+
"sphinx-rtd-theme",
64+
"sphinx-gallery",
65+
]
6166
optional-dependencies.loop = [ "loopstructural>=1.6.21" ]
6267
optional-dependencies.vtk = [ "pyvista" ]
6368

0 commit comments

Comments
 (0)