GemPy 地质建模数据准备指南
基于开源隐式三维地质建模库 GemPy,介绍从钻孔柱状图数据到 3D 地质模型的完整数据准备流程与基本建模示例。
一、GemPy 简介
GemPy 是一个基于 Python 的开源三维结构地质建模库,采用隐式建模(Implicit Modeling)方法,通过通用协克里金插值构建 3D 标量场。它能够高效地创建包含褶皱、断层、不整合等复杂构造特征的地质模型,并原生支持概率建模与不确定性分析。
二、建模所需的最小数据集
在 GemPy 中构建地质模型,需要两类核心输入数据。这些数据可以从钻孔柱状图、地质剖面图、野外露头测量等资料中提取。
1. 界面点(Surface Points)
界面点是三维空间中标记地质界面(如地层底界面、断层面、不整合面)位置的坐标点。在 GemPy 中,每个界面代表其所赋单元的底界面。
| 字段名 | 类型 | 说明 | 必填 |
|---|---|---|---|
X |
数值 | 东向坐标(与建模范围单位一致) | 是 |
Y |
数值 | 北向坐标 | 是 |
Z |
数值 | 高程/深度(通常地下为负值) | 是 |
formation |
字符串 | 地层/构造单元名称(如 “Sandstone_1″) | 是 |
2. 产状测量(Orientations)
产状数据描述地质界面的空间倾斜方向,用于约束插值的几何形态。每个构造组至少需要一条产状数据。
| 字段名 | 类型 | 说明 | 必填 |
|---|---|---|---|
X, Y, Z |
数值 | 测量点的三维坐标 | 是 |
azimuth |
数值 | 倾向(0–360度) | 是 |
dip |
数值 | 倾角(0–90度) | 是 |
polarity |
数值 | 极性(通常取 1,倒置构造可取 -1) | 是 |
formation |
字符串 | 所属地层/构造单元名称 | 是 |
三、从钻孔柱状图提取数据
钻孔柱状图是地质建模最常见的原始资料。以下是从钻孔柱状图转换为 GemPy 输入数据的完整流程:
步骤 1:收集原始钻孔资料
用户需要提供以下材料:
- 钻孔基本信息表:孔号、孔口坐标(X, Y)、孔口高程(Z)、钻孔深度、钻孔倾角与方位角(若为斜孔)
- 钻孔分层数据表:每层的层底深度、层底高程、地层代号、地层名称、岩性描述
- 地层产状数据:钻孔内或钻孔附近测得的地层倾向与倾角
- 研究区范围:建模的平面范围(X_min, X_max, Y_min, Y_max)与高程范围(Z_min, Z_max)
- 地层序列关系:各地层的沉积顺序、是否存在不整合/侵入关系、断层信息
步骤 2:计算界面点坐标
对每口钻孔的每个地层底界面,计算其三维坐标:
# 直孔示例:孔口坐标 (X0, Y0, Z0),层底深度 D
X = X0
Y = Y0
Z = Z0 - D # 若 Z 向下为负
# 斜孔需根据天顶角 theta 和方位角 alpha 进行换算
# X = X0 + D * sin(theta) * sin(alpha)
# Y = Y0 + D * sin(theta) * cos(alpha)
# Z = Z0 - D * cos(theta)
步骤 3:准备 CSV 文件
将提取的界面点保存为 surface_points.csv:
X,Y,Z,formation
0,0,800,rock3
0,0,450,rock2
0,0,250,rock1
500,0,800,rock3
...
将产状数据保存为 orientations.csv:
X,Y,Z,azimuth,dip,polarity,formation
100,500,650,90,315,1,rock2
100,500,450,90,315,1,rock1
...
四、GemPy 建模基本流程(Demo)
1. 安装 GemPy
# 核心库
pip install gempy
# 可视化模块
pip install gempy-viewer
# 3D 可视化依赖(推荐安装)
pip install pyvista
# 若需 GPU 加速(PyTorch 后端)
pip install torch
2. 从 CSV 导入数据并创建模型
import gempy as gp
import gempy_viewer as gpv
# 数据路径
data_path = "https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/"
path_to_data = data_path + "/data/input_data/video_tutorials_v3/"
# 创建地质模型
geo_model = gp.create_geomodel(
project_name='tutorial_model',
extent=[0, 2500, 0, 1000, 0, 1000],
resolution=[100, 40, 40],
importer_helper=gp.data.ImporterHelper(
path_to_orientations=path_to_data + "tutorial_model_orientations.csv",
path_to_surface_points=path_to_data + "tutorial_model_surface_points.csv"
)
)
3. 定义构造序列与映射关系
# 映射地层到构造组(从年轻到年老排序)
gp.map_stack_to_surfaces(
gempy_model=geo_model,
mapping_object={
"Strat_Series2": ("rock3"),
"Strat_Series1": ("rock2", "rock1")
}
)
4. 计算模型
# 计算地质模型
import os
os.environ["DEFAULT_BACKEND"] = "PYTORCH" # 或 NUMPY
gp.compute_model(geo_model)
5. 可视化结果
# 2D 剖面可视化
gpv.plot_2d(geo_model, cell_number=20, show_data=True)
# 3D 交互式可视化
gpv.plot_3d(geo_model, show_lith=True, show_boundaries=True)
6. 从零手动创建(不依赖 CSV)
# 创建空模型
geo_model = gp.create_geomodel(
project_name='Model1',
extent=[0, 780, -200, 200, -582, 0],
resolution=(50, 50, 50),
structural_frame=gp.data.StructuralFrame.initialize_default_structure()
)
# 手动添加界面点
gp.add_surface_points(
geo_model=geo_model,
x=[225, 460, 617],
y=[0, 0, 0],
z=[-95, -100, -10],
elements_names=['Limestone', 'Limestone', 'Limestone']
)
# 手动添加产状
gp.add_orientations(
geo_model=geo_model,
x=[350], y=[0], z=[-120],
elements_names=['Limestone'],
pole_vector=[[0, 0, 1]] # 水平层理,法向量朝上
)
# 计算并可视化
gp.compute_model(geo_model)
gpv.plot_2d(geo_model)
五、完整数据需求清单
为使用 GemPy 成功建立三维地质模型,请确保提供以下资料:
| 材料 | 格式 | 必要性 | 说明 |
|---|---|---|---|
| 钻孔坐标与孔口高程 | Excel / CSV | 必需 | 每口孔的 X, Y, Z 坐标 |
| 钻孔分层数据 | Excel / CSV | 必需 | 每层底深、地层名称、岩性 |
| 地层产状测量 | Excel / CSV | 必需 | 倾向、倾角及测量位置坐标 |
| 研究区范围 | 文本说明 | 必需 | X/Y/Z 的最小最大值 |
| 地层序列关系 | 文本/图表 | 必需 | 新老关系、不整合、侵入体 |
| 断层数据 | Excel / CSV | 可选 | 断层面产状、断距、延伸范围 |
| 地形数据 | DEM / GeoTIFF | 可选 | 研究区数字高程模型 |
| 地质剖面图 | 图片 / CAD | 可选 | 辅助验证模型合理性 |
六、官方文档与帮助链接
GemPy Geological Modeling Data Preparation Guide
A comprehensive guide to preparing borehole log data for 3D structural geological modeling using the open-source implicit modeling library GemPy.
1. Introduction to GemPy
GemPy is an open-source Python library for 3D structural geological modeling. It uses an implicit modeling approach based on universal cokriging to construct 3D scalar fields, enabling fast creation of complex models including folds, faults, and unconformities. It also natively supports probabilistic modeling and uncertainty analysis.
2. Minimum Required Datasets
To build a geological model in GemPy, two core input data types are required. These can be extracted from borehole logs, geological cross-sections, and outcrop measurements.
2.1 Surface Points
Surface points are 3D coordinates marking geological interfaces (e.g., layer boundaries, fault planes, unconformities). In GemPy, each surface represents the bottom of the unit it is assigned to.
| Field | Type | Description | Required |
|---|---|---|---|
X |
Numeric | Easting coordinate | Yes |
Y |
Numeric | Northing coordinate | Yes |
Z |
Numeric | Elevation / depth (negative for subsurface) | Yes |
formation |
String | Formation / structural element name | Yes |
2.2 Orientation Measurements
Orientation data describes the spatial dip of geological interfaces, constraining the geometry of interpolation. At least one orientation per structural group is required.
| Field | Type | Description | Required |
|---|---|---|---|
X, Y, Z |
Numeric | Measurement location coordinates | Yes |
azimuth |
Numeric | Dip direction (0–360 degrees) | Yes |
dip |
Numeric | Dip angle (0–90 degrees) | Yes |
polarity |
Numeric | Polarity (usually 1; -1 for inverted structures) | Yes |
formation |
String | Associated formation / element name | Yes |
3. Extracting Data from Borehole Logs
Borehole logs are the most common source of data for geological modeling. Below is the complete workflow to convert borehole data into GemPy inputs:
Step 1: Collect Raw Borehole Materials
The user should provide the following:
- Borehole location table: Borehole ID, collar coordinates (X, Y), collar elevation (Z), total depth, inclination and azimuth (for deviated holes)
- Stratigraphic interval table: Bottom depth of each layer, bottom elevation, formation code, formation name, lithology description
- Structural orientation data: Dip direction and dip angle measured within or near the borehole
- Study area extent: X/Y/Z minimum and maximum values defining the modeling domain
- Stratigraphic sequence: Depositional order, presence of unconformities or intrusions, fault information
Step 2: Compute Surface Point Coordinates
For each layer bottom in each borehole, calculate the 3D coordinates:
# Vertical borehole example: collar (X0, Y0, Z0), layer bottom depth D
X = X0
Y = Y0
Z = Z0 - D # if Z is negative downward
# Deviated borehole conversion using zenith angle theta and azimuth alpha:
# X = X0 + D * sin(theta) * sin(alpha)
# Y = Y0 + D * sin(theta) * cos(alpha)
# Z = Z0 - D * cos(theta)
Step 3: Prepare CSV Files
Save extracted surface points as surface_points.csv:
X,Y,Z,formation
0,0,800,rock3
0,0,450,rock2
0,0,250,rock1
500,0,800,rock3
...
Save orientation data as orientations.csv:
X,Y,Z,azimuth,dip,polarity,formation
100,500,650,90,315,1,rock2
100,500,450,90,315,1,rock1
...
4. Basic GemPy Modeling Workflow (Demo)
4.1 Install GemPy
# Core library
pip install gempy
# Visualization module
pip install gempy-viewer
# 3D visualization dependency (recommended)
pip install pyvista
# For GPU acceleration (PyTorch backend)
pip install torch
4.2 Import Data from CSV and Create Model
import gempy as gp
import gempy_viewer as gpv
# Data paths
data_path = "https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/"
path_to_data = data_path + "/data/input_data/video_tutorials_v3/"
# Create geological model
geo_model = gp.create_geomodel(
project_name='tutorial_model',
extent=[0, 2500, 0, 1000, 0, 1000],
resolution=[100, 40, 40],
importer_helper=gp.data.ImporterHelper(
path_to_orientations=path_to_data + "tutorial_model_orientations.csv",
path_to_surface_points=path_to_data + "tutorial_model_surface_points.csv"
)
)
4.3 Define Structural Sequence
# Map formations to structural groups (youngest to oldest)
gp.map_stack_to_surfaces(
gempy_model=geo_model,
mapping_object={
"Strat_Series2": ("rock3"),
"Strat_Series1": ("rock2", "rock1")
}
)
4.4 Compute the Model
import os
os.environ["DEFAULT_BACKEND"] = "PYTORCH" # or "NUMPY"
gp.compute_model(geo_model)
4.5 Visualize Results
# 2D cross-section
gpv.plot_2d(geo_model, cell_number=20, show_data=True)
# 3D interactive visualization
gpv.plot_3d(geo_model, show_lith=True, show_boundaries=True)
4.6 Create from Scratch (Without CSV)
# Create empty model
geo_model = gp.create_geomodel(
project_name='Model1',
extent=[0, 780, -200, 200, -582, 0],
resolution=(50, 50, 50),
structural_frame=gp.data.StructuralFrame.initialize_default_structure()
)
# Add surface points manually
gp.add_surface_points(
geo_model=geo_model,
x=[225, 460, 617],
y=[0, 0, 0],
z=[-95, -100, -10],
elements_names=['Limestone', 'Limestone', 'Limestone']
)
# Add orientation manually
gp.add_orientations(
geo_model=geo_model,
x=[350], y=[0], z=[-120],
elements_names=['Limestone'],
pole_vector=[[0, 0, 1]] # Horizontal bedding, normal vector up
)
# Compute and visualize
gp.compute_model(geo_model)
gpv.plot_2d(geo_model)
5. Complete Data Requirements Checklist
To successfully build a 3D geological model with GemPy, please ensure the following materials are provided:
| Material | Format | Required | Notes |
|---|---|---|---|
| Borehole coordinates & collar elevation | Excel / CSV | Required | X, Y, Z for each borehole |
| Stratigraphic interval data | Excel / CSV | Required | Bottom depth, formation name, lithology |
| Structural orientation measurements | Excel / CSV | Required | Dip direction, dip angle, measurement location |
| Study area extent | Text description | Required | X/Y/Z min and max values |
| Stratigraphic sequence | Text / Diagram | Required | Age relations, unconformities, intrusions |
| Fault data | Excel / CSV | Optional | Fault plane orientation, displacement, extent |
| Topography data | DEM / GeoTIFF | Optional | Digital elevation model of the study area |
| Geological cross-sections | Image / CAD | Optional | For model validation |
