储量估算
lib.prospecting 模块提供完整的储量估算工具链:从钻孔数据处理、块段模型创建、搜索椭球体参数计算,到距离幂/克里格估值和储量计算。
前置条件:
- 环境变量 DIMINE_HOME 指向包含 DmPyBindInterface.pyd 的目录
- Python >= 3.12
一、估算流程概览
钻孔数据库(.dmd) 矿体模型(.dmf)
│ │
▼ │
① 样品组合(样长/台阶) │
│ │
▼ │
② 特高品位处理 │
│ │
▼ ▼
③ 创建空块段模型 ←── 矿体包围盒范围
│
▼
④ 搜索椭球体参数 ←── 矿体模型顶点
│
▼
⑤ 品位估值(距离幂 / 克里格)
│
▼
⑥ 储量计算
二、搜索椭球体参数计算
搜索椭球体是品位估值的核心配置,由 3 个轴长和 3 个角度共 6 个参数定义。
2.1 为什么需要搜索椭球体
品位估值时,每个待估块段会搜索周围的样品点。椭球体决定了:
| 参数类别 | 作用 |
|---|---|
| 形状参数(3 轴长) | 决定搜索范围是"长条形"还是"圆胖形",匹配矿体实际形态 |
| 方位参数(3 角度) | 决定搜索框在三维空间中的朝向,与矿体走向/倾向/厚度对齐 |
如果椭球体参数设置不当(如走向方向偏了 30°),估值结果会引入系统性偏差。
2.2 自动计算 vs 手动配置
传统方式需要地质人员根据经验反复试调 6 个参数。SDK 提供 compute_search_ellipsoid_from_dmf() 从矿体模型自动计算:
from dimine_python_sdk.lib.prospecting.ellipsoid import (
compute_search_ellipsoid_from_dmf,
)
# 从矿体模型自动计算
ellipsoid = compute_search_ellipsoid_from_dmf(
"约束_矿体.dmf",
voxel_size=5.0,
)
print(f"主轴半径: {ellipsoid.main_radius:.1f} m")
print(f"方位角: {ellipsoid.angle_main:.1f}°")
print(f"倾伏角: {ellipsoid.angle_second:.1f}°")
print(f"倾角: {ellipsoid.angle_short:.1f}°")
2.3 算法原理
采用 Khachiyan 最小体积包围椭球(MVEE)算法:
- 从矿体模型提取 Shell 三角网顶点
- 体素降采样,消除顶点密度不均
- 迭代计算恰好包裹所有顶点的最小椭球
- 从椭球轴方向矩阵分解出 3 个地质角度
与 PCA(主成分分析)相比,MVEE 直接给出几何包络,轴长即紧贴矿体的半轴。
2.4 三个角度的含义
椭球体姿态由 Z-Y-X 欧拉角序列定义:
R = Rz(90° − angle_main) × Ry(angle_second) × Rx(angle_short)
| 参数 | 字段 | 说明 | 典型值 |
|---|---|---|---|
| 方位角 | angle_main |
主轴在水平面上的投影方向,0°=正北,90°=正东 | 0–360° |
| 倾伏角 | angle_second |
主轴与水平面的夹角,正值=向下 | 0°(水平层状)~ 90°(直立脉状) |
| 倾角 | angle_short |
椭球体绕主轴的旋转角,控制厚度方向的侧倾 | 多数简单矿体接近 0° |
2.5 参数调优
| 参数 | 默认值 | 建议 |
|---|---|---|
voxel_size |
5.0 m | 大型矿体(>500m)用 10–20m;小型矿体用 2–5m |
2.6 直接映射到估值参数
from dimine_python_sdk.lib.prospecting.models import BlockModelDistancePowerParams
eval_params = BlockModelDistancePowerParams(
**ellipsoid.to_block_model_params(),
# 展开为: main_radius, second_main_rate, short_main_rate,
# angle_main, angle_second, angle_short
sample_file="样品_组合.dmg",
variables="CU",
extra_attributes="样品点数目,到样品点平均距离",
power=2,
)
三、样品组合
估值前的必要预处理,将不等长样品统一到标准长度。
3.1 样长组合
from dimine_python_sdk.lib.prospecting import drill_conn
from dimine_python_sdk.lib.prospecting.models import SampleLengthCombineParam
with drill_conn("钻孔数据.dmd") as db:
params = SampleLengthCombineParam(
input_file="原始样品.dmg",
combine_length=2.0, # 组合长度 2m
combine_percent=0.75, # 最小覆盖率 75%
)
result = db.process_samples(params)
# 输出文件: 原始样品_combined.dmg
3.2 台阶组合
适用于露天矿山,按开采台阶高程对样品进行组合:
from dimine_python_sdk.lib.prospecting.models import StepCombineParam
params = StepCombineParam(
input_file="原始样品.dmg",
step_height=10.0, # 台阶高度 10m
start_height=0.0,
end_height=300.0,
)
result = db.process_steps(params)
四、特高品位处理
特高品位(离群高值)会严重拉高局部估值,需要在估值前处理。
from dimine_python_sdk.lib.prospecting.models import HighGradeProcessParam
params = HighGradeProcessParam(
input_file="样品_组合.dmg",
grade_field="CU",
process_mode=0, # 0=国内标准
average_multiple=6, # 6 倍平均值阈值
frequency=0.95, # 累积频率 95%
replace_method=2, # 2=相邻样品平均值替换
)
result = db.process_high_grade(params)
replace_method 枚举:
| 值 | 方式 | 适用场景 |
|---|---|---|
| 0 | 剔除法 | 样品充足时 |
| 1 | 给定值 | 有经验阈值时 |
| 2 | 相邻样品平均值 | 通用推荐 |
| 3 | 矿体平均品位法 | 矿体品位稳定时 |
| 4 | 单一工程法 | 钻孔独立性强时 |
| 5 | 截止品位法 | 有工业指标时 |
五、创建块段模型
根据矿体包围盒创建空块段模型,定义块段尺寸和属性字段。
from dimine_python_sdk.lib.prospecting import DmBlockData
from dimine_python_sdk.lib.prospecting.models import (
CreateBlockModelParams,
FieldDefinition,
)
params = CreateBlockModelParams(
file_name="块段模型.dmb",
origin_x=100.0, # 包围盒最小 X
origin_y=200.0, # 包围盒最小 Y
origin_z=0.0, # 包围盒最小 Z
size_x=5.0, # 单元块 X 尺寸
size_y=5.0, # 单元块 Y 尺寸
size_z=5.0, # 单元块 Z 尺寸
length_x=500.0, # X 方向总长度
length_y=400.0, # Y 方向总长度
length_z=300.0, # Z 方向总长度
field_definition=[
FieldDefinition(field_name="岩石类型", field_type="字节型"),
FieldDefinition(field_name="体重", field_type="浮点型"),
FieldDefinition(field_name="CU", field_type="浮点型"),
FieldDefinition(field_name="样品点数目", field_type="整型"),
FieldDefinition(field_name="到样品点平均距离", field_type="浮点型"),
],
)
result = DmBlockData.create_block_model(params)
print(f"创建结果: {result}")
六、品位估值
6.1 距离幂估值
from dimine_python_sdk.lib.prospecting import BlockModelEvaluator
from dimine_python_sdk.lib.prospecting.models import (
BlockModelDistancePowerParams,
EntityConstraint,
)
from dimine_python_sdk.lib.prospecting.ellipsoid import (
compute_search_ellipsoid_from_dmf,
)
# 1. 计算搜索椭球体
ellipsoid = compute_search_ellipsoid_from_dmf("约束_矿体.dmf")
# 2. 配置估值参数
eval_params = BlockModelDistancePowerParams(
**ellipsoid.to_block_model_params(),
sample_file="样品_组合.dmg",
variables="CU",
extra_attributes="样品点数目,到样品点平均距离",
power=2, # 距离幂次
octant_max=0, # 八分圆限制(0=不限制)
project_count_min=2, # 最少工程数
single_project_sample_max=5, # 单工程最多样品数
min_value=0.0001,
max_value=9999,
)
# 3. 配置约束(实体内部估值)
constraint = EntityConstraint(
file="约束_矿体.dmf",
range=0, # 0=内部,1=外部
)
# 4. 执行估值
evaluator = BlockModelEvaluator()
result = evaluator.distance_power_evaluation(
"块段模型.dmb",
constraint_params=[constraint],
evaluation_params=eval_params,
overwrite_result=True,
)
print(f"估值完成: {result['message']}")
6.2 克里格估值
from dimine_python_sdk.lib.prospecting.models import BlockModelKrigingParams
krig_params = BlockModelKrigingParams(
**ellipsoid.to_block_model_params(),
sample_file="样品_组合.dmg",
variables="CU",
extra_attributes="样品点数目,到样品点平均距离",
krig_type=1, # 1=普通克里格
variational_function=[
{"type": 0, "range": 22, "cc": 0.162586},
],
)
result = evaluator.kriging_evaluation(
"块段模型.dmb",
constraint_params=[constraint],
evaluation_params=krig_params,
overwrite_result=True,
)
6.3 估值参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
power |
2 | 距离幂次,常用 1–3 |
octant_max |
0 | 八分圆最大样品数,0=不限制 |
project_count_min |
0 | 最少工程数(保证空间代表性) |
single_project_sample_max |
0 | 单工程最大样品数(避免单孔主导) |
min_value / max_value |
0.0001 / 9999 | 估值范围截断 |
sub_block_main/second/short |
1 | 子块离散数,>1 可提高精度 |
七、储量计算
估值完成后,根据品位和体重计算储量。
from dimine_python_sdk.lib.prospecting.models import ReservesCalculateParam
reserve_params = ReservesCalculateParam(
weight_field="体重",
default_weight=2.76, # 默认体重 (t/m³)
main_field="CU", # 主统计字段
other_fields=["样品点数目", "到样品点平均距离"],
)
result = evaluator.calculate_reserves(
"块段模型.dmb",
constraint_params=[constraint],
reserve_params=reserve_params,
)
print(f"储量计算完成: {result}")
八、完整管线示例
以下是一个端到端的储量估算脚本:
"""
储量估算完整管线:样品组合 → 特高品位处理 → 创建块模型 →
搜索椭球体 → 距离幂估值 → 储量计算
"""
from dimine_python_sdk.lib.prospecting import (
DrillDBManager,
DmBlockData,
BlockModelEvaluator,
)
from dimine_python_sdk.lib.prospecting.ellipsoid import (
compute_search_ellipsoid_from_dmf,
)
from dimine_python_sdk.lib.prospecting.models import (
SampleLengthCombineParam,
HighGradeProcessParam,
CreateBlockModelParams,
FieldDefinition,
BlockModelDistancePowerParams,
EntityConstraint,
ReservesCalculateParam,
)
def run_estimation_pipeline(
drill_db_path: str,
orebody_dmf: str,
sample_dmg: str,
output_dmb: str,
element: str = "CU",
):
"""
执行完整的储量估算管线。
Args:
drill_db_path: 钻孔数据库 .dmd 路径
orebody_dmf: 矿体约束 .dmf 路径
sample_dmg: 原始样品 .dmg 路径
output_dmb: 输出块段模型 .dmb 路径
element: 估值元素
"""
db = DrillDBManager(drill_db_path)
evaluator = BlockModelEvaluator()
# === 第1步:样长组合(2m) ===
print("[1/6] 样长组合...")
combine_params = SampleLengthCombineParam(
input_file=sample_dmg,
combine_length=2.0,
combine_percent=0.75,
)
combine_result = db.process_samples(combine_params)
combined_dmg = combine_result.get("output_file", sample_dmg.replace(".dmg", "_combined.dmg"))
print(f" 输出: {combined_dmg}")
# === 第2步:特高品位处理 ===
print("[2/6] 特高品位处理...")
hg_params = HighGradeProcessParam(
input_file=combined_dmg,
grade_field=element,
average_multiple=6,
replace_method=2,
)
hg_result = db.process_high_grade(hg_params)
print(f" 处理结果: {hg_result}")
# === 第3步:创建空块段模型 ===
print("[3/6] 创建块段模型...")
block_params = CreateBlockModelParams(
file_name=output_dmb,
origin_x=100.0, origin_y=200.0, origin_z=0.0,
size_x=5.0, size_y=5.0, size_z=5.0,
length_x=500.0, length_y=400.0, length_z=300.0,
field_definition=[
FieldDefinition(field_name="岩石类型", field_type="字节型"),
FieldDefinition(field_name="体重", field_type="浮点型"),
FieldDefinition(field_name=element, field_type="浮点型"),
FieldDefinition(field_name="样品点数目", field_type="整型"),
FieldDefinition(field_name="到样品点平均距离", field_type="浮点型"),
],
)
DmBlockData.create_block_model(block_params)
# === 第4步:计算搜索椭球体 ===
print("[4/6] 计算搜索椭球体参数...")
ellipsoid = compute_search_ellipsoid_from_dmf(orebody_dmf, voxel_size=5.0)
print(f" 主轴={ellipsoid.main_radius:.1f}m "
f"方位角={ellipsoid.angle_main:.1f}° "
f"倾伏角={ellipsoid.angle_second:.1f}° "
f"倾角={ellipsoid.angle_short:.1f}°")
# === 第5步:距离幂估值 ===
print("[5/6] 距离幂估值...")
eval_params = BlockModelDistancePowerParams(
**ellipsoid.to_block_model_params(),
sample_file=combined_dmg,
variables=element,
extra_attributes="样品点数目,到样品点平均距离",
power=2,
project_count_min=2,
single_project_sample_max=5,
)
constraint = EntityConstraint(file=orebody_dmf, range=0)
eval_result = evaluator.distance_power_evaluation(
output_dmb,
constraint_params=[constraint],
evaluation_params=eval_params,
)
print(f" 估值完成: {eval_result['message']}")
# === 第6步:储量计算 ===
print("[6/6] 储量计算...")
reserve_params = ReservesCalculateParam(
weight_field="体重",
default_weight=2.76,
main_field=element,
)
reserve_result = evaluator.calculate_reserves(
output_dmb,
constraint_params=[constraint],
reserve_params=reserve_params,
)
print(f" 储量计算完成: {reserve_result}")
db.close()
print("\n=== 储量估算管线完成 ===")
if __name__ == "__main__":
run_estimation_pipeline(
drill_db_path="钻孔数据.dmd",
orebody_dmf="约束_矿体.dmf",
sample_dmg="原始样品.dmg",
output_dmb="块段模型.dmb",
element="CU",
)
九、异常处理
储量估算各环节有统一的异常体系:
from dimine_python_sdk.lib.prospecting import (
DrillDBError, # 钻孔数据库异常基类
DrillDBLoadError, # 加载失败
DrillDBProcessError, # 处理失败(可携带响应字典)
BlockDataError, # 块段模型异常基类
BlockModelCreateError, # 创建失败
BlockModelEvaluationError, # 估值失败
ReservesCalculateError, # 储量计算失败
)
try:
result = evaluator.distance_power_evaluation(...)
except BlockModelEvaluationError as e:
print(f"估值失败: {e}")
if e.response:
print(f"服务器响应: {e.response}")