Skip to content

储量估算

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)算法

  1. 从矿体模型提取 Shell 三角网顶点
  2. 体素降采样,消除顶点密度不均
  3. 迭代计算恰好包裹所有顶点的最小椭球
  4. 从椭球轴方向矩阵分解出 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}")