omf¶
Version: 2.0.0a0
API library for Open Mining Format, a new standard for mining data backed by the Global Mining Guidelines Group.
Warning
Pre-Release Notice
Version 2 of the Open Mining Format (OMF) and the associated Python API is under active development, and subject to backwards-incompatible changes at any time. The latest stable release of Version 1 is available on PyPI.
Why?¶
An open-source serialization format and API library to support data interchange across the entire mining community.
Scope¶
This library provides an abstracted object-based interface to the underlying OMF serialization format, which enables rapid development of the interface while allowing for future changes under the hood.
Goals¶
- The goal of Open Mining Format is to standardize data formats across the mining community and promote collaboration
- The goal of the API library is to provide a well-documented, object-based interface for serializing OMF files
Alternatives¶
OMF is intended to supplement the many alternative closed-source file formats used in the mining community.
Connections¶
This library makes use of the properties open-source project, which is designed and publicly supported by Seequent.
Installation¶
To install the repository, ensure that you have pip installed and run:
pip install --pre omf
Or from github:
git clone https://github.com/gmggroup/omf.git
cd omf
pip install -e .
3D Visualization¶
To easily visualize OMF project files and data objects in a pure Python environment, check out omfvista which provides a module for loading OMF datasets into PyVista mesh objects for 3D visualization and analysis.
Contents:
OMF API Index¶
The OMF API contains tools for creating Projects and adding PointSets, LineSets, Surfaces, Block Models, and Composites. These different elements may have Attributes or image Textures.
Projects¶
Projects contain a list of PointSets, LineSets, Surfaces,
Block Models, and Composites. Projects can be serialized and
deserialized to file using omf.fileio.save()
and omf.fileio.load()
.
For more details on how to build a project, see the OMF API Example.
PointSets¶

Element¶

Attributes¶
Attributes is a list of attributes. For PointSets, only
location='vertices'
is valid.
LineSets¶

Element¶

Attributes¶
Attributes is a list of attributes. For LineSets,
location='vertices'
and location='segments'
are valid.
Surfaces¶

Attributes¶
Attributes is a list of attributes. For Surfaces,
location='vertices'
and location='faces'
are valid.
Block Models¶

Element¶

Attributes¶
Attributes is a list of attributes. For block models,
location='parent_blocks'
and location='sub_blocks'
are valid.
Composites¶
Composites are used to compose multiple other elements into a single, more complex, grouped object.
Element¶
Attributes¶
Attributes is a list of attributes. For Composite Elements,
only location='elements'
is valid. However, attributes may also be
defined on the child elements
Attributes¶
ProjectElements include a list of ProjectElementAttribute. These specify mesh location (‘vertices’, ‘faces’, etc.) as well as the array, name, and description. See class descriptions below for specific types of Attributes.
Mapping attribute array values to a mesh is straightforward for unstructured meshes (those defined by vertices, segments, triangles, etc); the order of the attribute array corresponds to the order of the associated mesh parameter. For grid meshes, however, mapping 1D attribute array to the 2D or 3D grid requires correctly ordered ijk unwrapping.
NumericAttribute¶
VectorAttribute¶
StringAttribute¶
CategoryAttribute¶
ContinuousColormap¶
DiscreteColormap¶
CategoryColormap¶
Textures¶
Projected Texture¶
Projected textures are images that exist in space and are mapped to their corresponding elements. Unlike attributes, they do not need to correspond to mesh nodes or cell centers. This image shows how textures are mapped to a surface. Their position is defined by a corner and axis vectors then they are mapped laterally to the element position.

Like attributes, multiple textures can be applied to a element; simply provide a list of textures. Each of these textures provides a corner point and two extent vectors for the plane defining where images rests. The axis_* properties define the extent of that image out from the corner. Given a rectangular PNG image, the corner is the bottom left, corner + axis_u is the bottom right, and corner + axis_v is the top left. This allows the image to be rotated and/or skewed. These values are independent of the corresponding Surface; in fact, there is nothing requiring the image to actually align with the Surface.
UV Mapped Textures¶
Rather than being projected onto points or a surface, UV Mapped Textures are given normalized UV coordinates which correspond to element vertices. This allows arbitrary mapping of images to surfaces.
Image¶
OMF API Example¶
This (very impractical) example shows usage of the OMF API.
Also, this example builds elements all at once. They can also be initialized with no arguments, and properties can be set one-by-one (see code snippet at bottom of page).
import datetime
import numpy as np
import os
import png
import omf
# setup sample files
dir = os.getcwd()
png_file = os.path.join(dir, "example.png")
omf_file = os.path.join(dir, "example.omf")
for f in (png_file, omf_file):
if os.path.exists(f):
os.remove(f)
img = ["110010010011", "101011010100", "110010110101", "100010010011"]
img = [[int(val) for val in value] for value in img]
writer = png.Writer(len(img[0]), len(img), greyscale=True, bitdepth=16)
with open(png_file, "wb") as file:
writer.write(file, img)
proj = omf.Project(
name="Test project",
description="Just some assorted elements",
)
pts = omf.PointSet(
name="Random Points",
description="Just random points",
vertices=np.random.rand(100, 3),
attributes=[
omf.NumericAttribute(
name="rand attr",
array=np.random.rand(100),
location="vertices",
),
omf.NumericAttribute(
name="More rand attr",
array=np.random.rand(100),
location="vertices",
),
],
textures=[
omf.ProjectedTexture(
name="test image",
image=png_file,
origin=[0, 0, 0],
axis_u=[1, 0, 0],
axis_v=[0, 1, 0],
),
omf.ProjectedTexture(
name="test image",
image=png_file,
origin=[0, 0, 0],
axis_u=[1, 0, 0],
axis_v=[0, 0, 1],
),
],
metadata={
"color": "green",
},
)
lin = omf.LineSet(
name="Random Line",
vertices=np.random.rand(100, 3),
segments=np.floor(np.random.rand(50, 2) * 100).astype(int),
attributes=[
omf.NumericAttribute(
name="rand vert attr",
array=np.random.rand(100),
location="vertices",
),
omf.NumericAttribute(
name="rand segment attr",
array=np.random.rand(50),
location="segments",
),
],
metadata={
"color": "#0000FF",
},
)
surf = omf.Surface(
name="trisurf",
vertices=np.random.rand(100, 3),
triangles=np.floor(np.random.rand(50, 3) * 100).astype(int),
attributes=[
omf.NumericAttribute(
name="rand vert attr",
array=np.random.rand(100),
location="vertices",
),
omf.NumericAttribute(
name="rand face attr",
array=np.random.rand(50),
location="faces",
),
],
metadata={
"color": [100, 200, 200],
},
)
grid = omf.TensorGridSurface(
name="gridsurf",
tensor_u=np.ones(10).astype(float),
tensor_v=np.ones(15).astype(float),
origin=[50.0, 50.0, 50.0],
axis_u=[1.0, 0, 0],
axis_v=[0, 0, 1.0],
offset_w=np.random.rand(11 * 16),
attributes=[
omf.NumericAttribute(
name="rand vert attr",
array=np.random.rand(11 * 16),
location="vertices",
),
omf.NumericAttribute(
name="rand face attr",
array=np.random.rand(10 * 15),
location="faces",
),
],
textures=[
omf.ProjectedTexture(
name="test image",
image=png_file,
origin=[2.0, 2.0, 2.0],
axis_u=[5.0, 0, 0],
axis_v=[0, 2.0, 5.0],
),
],
)
vol = omf.TensorGridBlockModel(
name="vol",
tensor_u=np.ones(10).astype(float),
tensor_v=np.ones(15).astype(float),
tensor_w=np.ones(20).astype(float),
origin=[10.0, 10.0, -10],
attributes=[
omf.NumericAttribute(
name="random attr", location="cells", array=np.random.rand(10 * 15 * 20)
),
],
)
proj.elements = [pts, lin, surf, grid, vol]
proj.metadata = {
"coordinate_reference_system": "epsg 3857",
"date_created": datetime.datetime.utcnow(),
"version": "v1.3",
"revision": "10",
}
assert proj.validate()
omf.save(proj, omf_file)
Piecewise building example:
...
pts = omf.PointSet()
pts.name = 'Random Points',
pts.vertices = np.random.rand(100, 3)
...