-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdistance_to_well.py
139 lines (105 loc) · 5.07 KB
/
distance_to_well.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# -*- coding: utf-8 -*-
"""
Uncertainty estimation and quantification is increasingly important in geo-
scientific and geotechnical applications. One approach is to quantify
uncertainty in terms of the distance to the next source of information (e.g,
outcrop, well, geophysical profile etc.).
Given a set of wells, this code computes and visualizes a raster that contains
information about the distances from each raster point to the next well.
Author: Dr. Georg H. Erharter
First version released: 24. October 2021
Update 1: 19. December 2024
License: MIT License (license file in repository)
"""
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
import numpy as np
###############################################################################
# function definitions
def compute_raster_extent(well_dict: dict, DIST: float) -> list:
''' computes the extent of the distance raster beyond the wells'''
coords = np.array(list(well_dict.values()))
x_coords, y_coords = coords[:, 0], coords[:, 1]
# ll = lower left corner, ur = upper right corner
ll = np.array([x_coords.min()-DIST, y_coords.min()-DIST])
ur = np.array([x_coords.max()+DIST, y_coords.max()+DIST])
return ll, ur
def compute_raster_coords(ll, ur, RESOLUTION) -> list:
''' computes the coordinates of the raster points '''
xs = np.linspace(ll[0], ur[0], num=int((ur[0] - ll[0]) / RESOLUTION))
ys = np.linspace(ll[1], ur[1], num=int((ur[1] - ll[1]) / RESOLUTION))
xs, ys = np.meshgrid(xs, ys)
# return coordinates and shape of raster
return xs, ys
def distance(x: float, y: float, well: list) -> float:
''' computes the distance between x-y coordinates and a well '''
dist_x = np.abs(x - well[0])
dist_y = np.abs(y - well[1])
return np.sqrt(dist_x**2 + dist_y**2)
###############################################################################
# static variables / constants and well dictionary
DIST = 30 # [m] extend of raster beyond wells
RASTER_RESOLUTION = 1 # [m] resolution of raster
GRID_RESOLUTION = 50 # [m] resolution of grid over map
SAVE_RASTER = False # whether or not a .csv raster should be saved
SAVE_IMAGE = True # whether or not an image of the distances should be saved
# dictionary with drillings: keys= drilling names, values= drilling coordinates
# exemplary drillings
WELLS = {'ED0': [110, 220],
'ED1': [130, 230],
'ED2': [100, 260],
'ED3': [120, 270],
'ED4': [105, 310],
'ED5': [240, 225],
'ED6': [130, 200],
'ED7': [220, 300]}
###############################################################################
# computation of distances
ll, ur = compute_raster_extent(WELLS, DIST)
extent_x, extent_y = ur[0] - ll[0], ur[1] - ll[1]
xs, ys = compute_raster_coords(ll, ur, RASTER_RESOLUTION)
# compute min distance between each raster point and all wells
dists = [distance(xs, ys, well) for well in list(WELLS.values())]
distance_raster = np.dstack(dists).min(axis=2)
# eventually save result as coordinates with scalar values
if SAVE_RASTER is True:
distance_raster = np.vstack((xs.flatten(), ys.flatten(),
distance_raster.flatten())).T
np.savetxt(r'distance_raster.csv', distance_raster, delimiter=',')
###############################################################################
# result visualization
fig, ax = plt.subplots(figsize=(6, 5))
# add raster image to plot
im = ax.imshow(distance_raster, cmap='Greys', origin='lower',
extent=(ll[0]-RASTER_RESOLUTION/2, ur[0]+RASTER_RESOLUTION/2,
ll[1]-RASTER_RESOLUTION/2, ur[1]+RASTER_RESOLUTION/2))
# add distance contour lines to plot
CS = ax.contour(xs, ys, distance_raster, levels=np.arange(0, 1000, 15),
colors='black', alpha=0.5, origin='lower', linewidths=.5,
extent=(ll[0]-RASTER_RESOLUTION/2, ur[0]+RASTER_RESOLUTION/2,
ll[1]-RASTER_RESOLUTION/2, ur[1]+RASTER_RESOLUTION/2))
ax.clabel(CS, CS.levels, inline=True, fmt='%d')
# add well positions to plot
for i, d in enumerate(list(WELLS.values())):
ax.scatter(d[0], d[1], color='grey', edgecolor='black', marker='D')
ax.annotate(list(WELLS.keys())[i], (d[0]+1, d[1]+1))
ax.set_aspect('equal')
# draw grid over map
ax.set_xticks(np.arange(start=ll[0], stop=ur[0], step=GRID_RESOLUTION))
ax.set_yticks(np.arange(start=ll[1], stop=ur[1], step=GRID_RESOLUTION))
ax.grid(alpha=0.5)
ax.xaxis.set_ticklabels([])
ax.yaxis.set_ticklabels([])
ax.set_xlabel(f'{extent_x} m')
ax.set_ylabel(f'{extent_y} m')
# add colorbar to plot
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cbar = plt.colorbar(im, cax=cax)
cbar.set_label('distance to drillings [m]')
# add title to plot
# ax.set_title('exploratory drilling-distance uncertainty estimation')
plt.tight_layout()
# eventually save a visualization of the distance map
if SAVE_IMAGE is True:
plt.savefig('distance_to_drilling.pdf')