API Reference#
- class parq_blockmodel.LocalGeometry(corner, block_size, shape)[source]#
Local dense grid geometry with C-order indexing.
This class models the logical/local lattice only (local corner/origin, block size, shape). It has no rotation, CRS, or world-frame meaning.
- corner#
Local (u0, v0, w0) corner of the (i=0, j=0, k=0) block.
- Type:
Point
- block_size#
Block dimensions
(dx, dy, dz)along the locali/j/k(u/v/w) axes.- Type:
BlockSize
- shape#
Grid shape (ni, nj, nk) - number of blocks along each axis.
- Type:
Shape3D
- property centroids_uvw: ndarray#
Compute local centroids as a (3, N) array in C-order.
- class parq_blockmodel.ParquetBlockModel(blockmodel_path, name=None, geometry=None)[source]#
A class to represent a regular Parquet block model.
Canonical on-disk representation:
We treat
.pbmfiles as ParquetBlockModel containers:The extension must be
.pbm.The content is a Parquet table with embedded geometry metadata under the
"parq-blockmodel"key, describing a regularparq_blockmodel.geometry.RegularGeometrygrid.
The geometry is ijk-first: logical indices
(i, j, k)enumerate the dense grid, and centroid coordinates(x, y, z)are derived from those indices plus geometry (corner, block size, axis orientation). In non-rotated models the grid axes align with the global X, Y, Z directions; in rotated models they do not.Parquet storage order follows NumPy C-order with respect to ijk:
ivaries fastest, thenj, thenk. This aligns withnumpy.ravel(order="C")and howRegularGeometrycomputes row indices. For xyz-defined, non-rotated models this corresponds to an increasing lexicographic ordering in(x, y, z), but callers should treat ijk + geometry as the canonical view.- blockmodel_path#
Path to the canonical
.pbmfile backing this block model.- Type:
Path
- name#
The name of the block model, derived from the file name.
- Type:
str
- geometry#
Geometry of the block model, loaded from Parquet metadata or inferred from centroid columns.
- Type:
- property centroid_index: MultiIndex#
Get the centroid index of the block model as
(x, y, z).This index is built from the centroid columns
x,y,zstored in the underlying.pbmParquet file. It is primarily a backwards-compatibility view for xyz-first workflows which treat world-space centroids as the primary index.Canonical ordering is defined by the C-order ijk layout in
RegularGeometry, not by lexicographic sorting of(x, y, z). We therefore require this index to be unique but do not enforce global monotonicity in xyz.- Returns:
The MultiIndex representing centroid coordinates
(x, y, z).- Return type:
pd.MultiIndex
- property corner: tuple[float, float, float] | list[float]#
Backward-compatible access to the local grid corner.
- classmethod create_demo_block_model(filename, **demo_kwargs)[source]#
Convenience helper used in tests to write a demo Parquet file and wrap it as a ParquetBlockModel.
- Parameters:
filename (Path) – Target
.parquetfile to hold the raw demo data. The canonical blockmodel file will be written alongside it with a.pbmsuffix viafrom_parquet().**demo_kwargs – Additional keyword arguments forwarded to
parq_blockmodel.utils.demo_block_model.create_demo_blockmodel(), for exampleshapeorblock_size. This allows tests and examples to control the logical grid used for the demo model.
- Return type:
- create_heatmap_from_threshold(attribute, threshold, axis='z', return_array=False)[source]#
Create a 2D heatmap from a 3D block model at a specified attribute threshold.
- Parameters:
attribute (str) – The name of the attribute to threshold.
threshold (float) – The threshold value for the attribute.
axis (str) – The axis to view from (‘x’, ‘y’, or ‘z’). Defaults to ‘z’.
return_array (bool) – If True, returns the heatmap as a NumPy array. Defaults to False.
- Returns:
A 2D heatmap as a PyVista ImageData object or a NumPy array.
- Return type:
Union[pv.ImageData, np.ndarray]
- create_report(columns=None, column_batch_size=10, show_progress=True, open_in_browser=False)[source]#
Create a ydata-profiling report for the block model. The report will be of the same name as the block model, with a ‘.html’ extension.
- Parameters:
columns (
Optional[list[str]]) – List of column names to include in the profile. If None, all columns are used.column_batch_size (
int) – The number of columns to process in each batch. If None, processes all columns at once.show_progress (
bool) – bool: If True, displays a progress bar during profiling.open_in_browser (
bool) – bool: If True, opens the report in a web browser after generation.
- Return type:
Path
- Returns
Path: The path to the generated profile report.
- classmethod create_toy_blockmodel(filename, shape=(3, 3, 3), block_size=(1, 1, 1), corner=(-0.5, -0.5, -0.5), axis_azimuth=0.0, axis_dip=0.0, axis_plunge=0.0, deposit_bearing=20.0, deposit_dip=30.0, deposit_plunge=10.0, grade_name='grade', grade_min=50.0, grade_max=65.0, deposit_center=(10.0, 7.5, 5.0), deposit_radii=(8.0, 5.0, 3.0), noise_std=0.0, noise_rel=None, noise_seed=None)[source]#
Create a synthetic toy block model.
The toy model is generated on a regular ijk grid with the specified
shapeandblock_size, anchored atcornerin world coordinates. A simple ellipsoidal grade distribution is created in xyz space and stored undergrade_namealongside any supporting attributes.- Parameters:
filename (Path) – Path to the source
.parquetfile to hold the raw toy data. A canonical.pbmfile will be written alongside it with the same stem.shape (tuple of int, default
(3, 3, 3)) – Number of blocks along the logical ijk axes.block_size (tuple of float, default
(1, 1, 1)) – Block dimensions along each logical axis.corner (tuple of float, default
(-0.5, -0.5, -0.5)) – World‑space coordinates of the block with indices(i=0, j=0, k=0)lower corner.axis_azimuth (float, default 0.0) – Rotation angles defining orientation of the logical ijk axes relative to the world xyz frame. These are converted to an orthonormal basis
(axis_u, axis_v, axis_w)used byRegularGeometry.axis_dip (float, default 0.0) – Rotation angles defining orientation of the logical ijk axes relative to the world xyz frame. These are converted to an orthonormal basis
(axis_u, axis_v, axis_w)used byRegularGeometry.axis_plunge (float, default 0.0) – Rotation angles defining orientation of the logical ijk axes relative to the world xyz frame. These are converted to an orthonormal basis
(axis_u, axis_v, axis_w)used byRegularGeometry.deposit_bearing (float) – Orientation of the synthetic deposit in degrees.
deposit_dip (float) – Orientation of the synthetic deposit in degrees.
deposit_plunge (float) – Orientation of the synthetic deposit in degrees.
grade_name (str, default
"grade") – Name of the column storing the simulated grade values.grade_min (float) – Minimum and maximum grade values for the toy distribution.
grade_max (float) – Minimum and maximum grade values for the toy distribution.
deposit_center (tuple of float) – Center of the ellipsoidal deposit in world xyz coordinates.
deposit_radii (tuple of float) – Semi‑axes of the deposit ellipsoid in world units.
noise_std (float, default 0.0) – Absolute standard deviation of Gaussian noise added to grades.
noise_rel (float, optional) – Relative standard deviation expressed as a fraction of
(grade_max - grade_min). Mutually exclusive withnoise_std.noise_seed (int, optional) – Seed used for reproducible Gaussian noise.
- Returns:
A
ParquetBlockModelbacked by a canonical.pbmfile with the generated toy data and geometry metadata.- Return type:
Notes
For rotated geometries (non‑zero rotation angles), xyz centroids will appear rotated in world coordinates relative to the ijk axes of the grid. Geometry validation is skipped in this case to avoid imposing axis‑aligned assumptions on the rotated layout.
- downsample(new_block_size, aggregation_config)[source]#
Downsample the block model to a coarser grid with specified aggregation methods for each attribute. This function supports downsampling of both categorical and numeric attributes. :type new_block_size: :param new_block_size: tuple of floats (dx, dy, dz) for the new block size. :type aggregation_config: :param aggregation_config: dict mapping attribute names to aggregation methods.
Example
- aggregation_config = {
‘grade’: {‘method’: ‘weighted_mean’, ‘weight’: ‘dry_mass’}, ‘density’: {‘method’: ‘weighted_mean’, ‘weight’: ‘volume’}, ‘dry_mass’: {‘method’: ‘sum’}, ‘volume’: {‘method’: ‘sum’}, ‘rock_type’: {‘method’: ‘mode’}
}
- Returns:
A new ParquetBlockModel instance with the downsampled grid.
- Return type:
- classmethod from_dataframe(dataframe, filename, geometry=None, name=None, overwrite=False, axis_azimuth=0.0, axis_dip=0.0, axis_plunge=0.0, chunk_size=1000000)[source]#
Create a
ParquetBlockModelfrom a pandas DataFrame.This constructor is oriented towards xyz-indexed DataFrames, where the index is a centroid MultiIndex with levels
("x", "y", "z")in world coordinates.The DataFrame is written to a sibling
.pbmfile (replacing the.parquetsuffix offilename) with embeddedRegularGeometrymetadata. Geometry is either supplied explicitly or inferred from the xyz centroids viaRegularGeometry.from_multi_index().- Parameters:
dataframe (pandas.DataFrame) – Block model data indexed by centroid coordinates with
dataframe.index.names == ["x", "y", "z"].filename (Path) – Path to the source
.parquetfile which will be used as the basis for the sibling.pbmcontainer.geometry (RegularGeometry, optional) – Geometry of the logical ijk grid. If omitted, it is inferred from the centroid MultiIndex, using the optional rotation angles to define the ijk axis orientation.
name (str, optional) – Optional name for the resulting
ParquetBlockModel. Defaults tofilename.stem.overwrite (bool, default False) – If True, allows overwriting an existing
.pbmfile at the derived path.axis_azimuth (float, default 0.0) – Optional rotation angle used when inferring geometry from the xyz centroids. Defines the orientation of the logical ijk axes relative to the world coordinate frame.
axis_dip (float, default 0.0) – Optional rotation angle. See
axis_azimuth.axis_plunge (float, default 0.0) – Optional rotation angle. See
axis_azimuth.chunk_size (int, default 1_000_000) – Batch size for writing Parquet data.
- Returns:
A block model backed by the newly written
.pbmfile.- Return type:
Note
New ijk-first workflows are encouraged to construct a
RegularGeometryexplicitly and useParquetBlockModel.from_geometry()orParquetBlockModel.from_parquet(). This helper remains for backwards compatibility with xyz-indexed DataFrames.
- classmethod from_geometry(geometry, path, name=None)[source]#
Create a
ParquetBlockModelfrom a geometry only.This constructor materialises a dense ijk grid defined by a
RegularGeometryinto a Parquet file with xyz centroid columns but no additional attributes. It is useful for creating an empty block model skeleton that can be joined with external attribute data.- Parameters:
geometry (RegularGeometry) – Geometry of the logical ijk grid.
path (Path) – Path to the target
.pbmfile. The file will contain a row for every ijk block with derived xyz centroid columns and embedded geometry metadata.name (str, optional) – Optional name for the resulting
ParquetBlockModel.
- Returns:
A block model with geometry defined but no attribute columns.
- Return type:
- classmethod from_parquet(parquet_path, columns=None, overwrite=False, axis_azimuth=0.0, axis_dip=0.0, axis_plunge=0.0, chunk_size=1000000)[source]#
Create a
ParquetBlockModelfrom a source Parquet file.This helper promotes a source
.parquetfile (typically xyz-centric) into a canonical.pbmcontainer with embeddedRegularGeometrymetadata.The input Parquet is expected to contain centroid columns
x,y,zdescribing block centroids in world coordinates.RegularGeometryis reconstructed from those centroids and/or any existing"parq-blockmodel"metadata viaRegularGeometry.from_parquet(). Geometry becomes the authoritative description of the dense ijk grid; xyz centroids are treated as a derived view.- Parameters:
parquet_path (Path) – Path to the source Parquet file. If the suffix is
.pbmandoverwriteis False, aValueErroris raised to avoid mutating an existing canonical container.columns (list[str], optional) – Optional subset of columns to copy from the source file into the resulting
.pbmfile. IfNone, all columns are copied.overwrite (bool, default False) – If True, allows overwriting an existing
.pbmfile at the target location.axis_azimuth (float, default 0.0) – Optional rotation angle used by
RegularGeometry.from_parquet()to define the orientation of the logical ijk axes in world coordinates when inferring geometry. In the common case geometry is read directly from existing metadata and this parameter is 0.axis_dip (float, default 0.0) – Optional rotation angle. See
axis_azimuth.axis_plunge (float, default 0.0) – Optional rotation angle. See
axis_azimuth.chunk_size (int, default 1_000_000) – Batch size for reading Parquet data.
- Returns:
- A block model backed by a newly written
.pbmfile located alongside
parquet_path.
- A block model backed by a newly written
- Return type:
- property index_c: ndarray#
Zero-based C-order indices for the dense ijk grid.
The returned array has length
ni * nj * nkand corresponds to linearised logical indices(i, j, k)using NumPy C‑order:r = i + ni * (j + nj * k).This is mainly a low‑level helper for downstream APIs that need a stable mapping between a flat row index and ijk; most callers should use
read()withindex="ijk"instead.
- property index_f: ndarray#
Zero-based Fortran-order indices for the dense ijk grid.
Uses the same ijk logical grid as :pyattr:`index_c`, but flattened with
order="F". This is useful when interacting with tools (such as some VTK/PyVista paths) that expect F‑order layouts.
- property origin: tuple[float, float, float] | list[float]#
Backward-compatible access to the world-frame origin.
- plot(scalar, grid_type='image', frame='world', threshold=True, show_edges=True, show_axes=True, enable_picking=False, picked_attributes=None)[source]#
Plot the block model using PyVista.
- Parameters:
scalar (
str) – The name of the scalar attribute to visualize.grid_type (
Literal['image','structured','unstructured']) – The type of grid to use for plotting. Options are “image”, “structured”, or “unstructured”.frame (
Literal['world','local']) – Coordinate frame for image grids."world"applies geometry axis vectors;"local"uses axis-aligned local ijk orientation. Only supported forgrid_type="image".threshold (
bool) – The thresholding option for the mesh. If True, applies a threshold to the scalar values.show_edges (
bool) – Show edges of the mesh.show_axes (
bool) – Show the axes in the plot.enable_picking (
bool) – If True, enables picking mode to interactively select cells in the plot.picked_attributes (
Optional[list[str]]) – A list of attributes that will be returned in picking mode. If None, all attributes are returned.
- Return type:
Plotter
Returns:
- plot_heatmap(attribute, threshold, axis='z', title=None)[source]#
Create a 2D heatmap plotly figure from a 3D block model at a specified attribute threshold.
- Parameters:
attribute (str) – The name of the attribute to threshold.
threshold (float) – The threshold value for the attribute.
axis (str) – The axis to view from (‘x’, ‘y’, or ‘z’). Defaults to ‘z’.
title (Optional[str]) – The title of the heatmap. If None, a default title is used.
- Returns:
A Plotly figure containing the heatmap.
- Return type:
go.Figure
- read(columns=None, index='xyz', dense=False)[source]#
Read the Parquet file and return a DataFrame.
Notes
Current behaviour (for backwards compatibility):
index="xyz"(the default) returns a DataFrame indexed by centroid coordinates(x, y, z). This matches the original design where xyz are treated as canonical.index="ijk"returns a DataFrame whose index is derived fromRegularGeometryviato_ijk_multi_index.
Option B design (future change, not yet enforced):
The canonical in-memory representation will become an
(i, j, k)MultiIndex with attributes-only columns.xyz (centroid) coordinates will be treated as a derived view computed from
(i, j, k)+ geometry, exposed via a helper such asas_xyz()or via pandas accessors that read geometry fromdf.attrs["parq-blockmodel"].Plotting helpers (PyVista, Plotly) will consume ijk + geometry and compute xyz internally when needed, so they do not rely on xyz being persisted as data columns.
Until that refactor is complete, this method preserves the existing xyz-first semantics so that external callers continue to work.
- Parameters:
columns (
Optional[list[str]]) – List of column names to read. If None, all columns are read.index (
Literal['xyz','ijk',None]) – The index type to use for the DataFrame. Options are"xyz"for centroid coordinates,"ijk"for block indices, orNonefor no index.dense (
bool) – If True, reads/reindexes to the full dense grid. If False, returns the sparse layout in the underlying file.
- Returns:
The DataFrame containing the block model data.
- Return type:
pd.DataFrame
Notes
index="xyz"is preserved as the default for backwards compatibility with earlier versions ofparq_blockmodelthat treated centroid coordinates as canonical. New code is encouraged to passindex="ijk"explicitly and work in terms of logical grid indices plus geometry.
- to_dense_parquet(filepath, chunk_size=100000, show_progress=False)[source]#
Export the block model as a dense xyz-indexed Parquet file.
The underlying
.pbmmay be sparse with respect to the dense ijk grid encoded bygeometry. This helper iterates over the on‑disk data in chunks, reindexes each chunk to the full dense centroid MultiIndexgeometry.to_multi_index_xyz()and writes the result tofilepath.- Parameters:
filepath (Path) – Target path for the exported Parquet file.
chunk_size (int, default 100_000) – Number of rows to process per chunk when reading from the backing
.pbmfile.show_progress (bool, default False) – If True, display a progress bar while exporting.
- Return type:
None
Notes
This export is primarily intended for interoperability with tools that expect a fully populated xyz grid. The canonical representation of the block model remains the
.pbmfile with embeddedRegularGeometrymetadata.
- to_glb(output_path, attributes=None, texture_attribute=None, colormap='viridis', surface_only=True, sparse=None)[source]#
Export the block model as a GLB (glTF 2.0 binary) mesh.
GLB is a derived format for external visualization in 3D viewers. Optionally applies vertex colors based on a scalar attribute (e.g., grade, density). Geometry metadata is embedded in the glTF extras field for reference.
- Parameters:
output_path (str or Path) – Target GLB file path.
attributes (list[str], optional) – Block attributes to include (stored in glTF extensions).
texture_attribute (str, optional) – Attribute name to use for vertex coloring (e.g., “grade”). Must be numeric. If None, uses default gray material.
colormap (str, default "viridis") – Matplotlib colormap name for mapping texture_attribute to colors. Examples: “viridis”, “plasma”, “coolwarm”, “Greys”.
surface_only (bool, default True) – If True, export only exterior surface faces.
sparse (bool, optional) – If True, export only existing blocks. If None, infer from model sparsity.
- Returns:
The output file path (pathlib.Path).
- Return type:
Path
Notes
GLB format is optimized for visualization and may lose some precision compared to PLY. For scientific workflows requiring lossless data preservation, prefer
to_ply().The texture_attribute is normalized to [0, 1] and mapped to the specified colormap. NaN values are rendered as transparent.
Examples
>>> pbm = ParquetBlockModel(Path("model.pbm")) >>> pbm.to_glb("model.glb", texture_attribute="grade", colormap="viridis")
- to_ply(output_path, attributes=None, surface_only=True, sparse=None, binary=False)[source]#
Export the block model as a PLY (Polygon File Format) mesh.
PLY is the canonical format for mesh storage, supporting lossless round-tripping of all geometry and attribute data. The output file includes: - Vertex coordinates in world space - Face connectivity (triangles) - Per-vertex and per-face attributes (grades, rock type, etc.) - Block logical indices (i, j, k) for traceability - Geometry metadata (corner, block_size, shape, axes, CRS)
- Parameters:
output_path (str or Path) – Target PLY file path.
attributes (list[str], optional) – Block attributes to include. If None, only geometry is exported.
surface_only (bool, default True) – If True, export only exterior surface faces.
sparse (bool, optional) – If True, export only existing blocks. If None, infer from model sparsity.
binary (bool, default False) – If True, write binary PLY (smaller file, less readable). If False, write ASCII PLY (larger, human-readable).
- Returns:
The output file path (pathlib.Path).
- Return type:
Path
Notes
Units and coordinate system are inherited from
geometry. For rotated geometries, world-space coordinates reflect the rotation.Examples
>>> pbm = ParquetBlockModel(Path("model.pbm")) >>> pbm.to_ply("model.ply", attributes=["grade", "density"])
- triangulate(attributes=None, surface_only=True, sparse=None)[source]#
Generate a triangulated mesh from the block model.
Creates a triangle mesh representation of the block model geometry, optionally including block attributes (grades, rock types, etc.) as vertex or face attributes.
- Parameters:
attributes (list[str], optional) – List of attribute columns to include in the mesh. If None, only geometry is included (no attributes). Attributes must be in
self.attributes.surface_only (bool, default True) – If True, include only exterior surface faces. If False, include all interior faces as well. Useful for sparse models.
sparse (bool, optional) – If True (or None and sparse model detected), include only blocks that exist in the data. If False, generate mesh for full dense grid.
- Returns:
Triangle mesh with vertices, faces, and optional attributes.
- Return type:
Notes
The mesh uses right-handed coordinates in world space, with rotation applied via
geometryaxis vectors. Attributes are preserved as per-vertex or per-face properties. For sparse models, only surface faces are typically needed (surface_only=True).Examples
>>> pbm = ParquetBlockModel(Path("model.pbm")) >>> mesh = pbm.triangulate(attributes=["grade", "density"], surface_only=True) >>> print(f"Mesh: {mesh.n_vertices} vertices, {mesh.n_faces} faces")
- upsample(new_block_size, interpolation_config)[source]#
Upsample the block model to a finer grid with specified interpolation methods for each attribute. This function supports upsampling of both categorical and numeric attributes. :type new_block_size: :param new_block_size: tuple of floats (dx, dy, dz) for the new block size. :type interpolation_config: :param interpolation_config: dict mapping attribute names to interpolation methods.
Example
- interpolation_config = {
‘grade’: {‘method’: ‘linear’}, ‘density’: {‘method’: ‘nearest’}, ‘dry_mass’: {‘method’: ‘linear’}, ‘volume’: {‘method’: ‘linear’}, ‘rock_type’: {‘method’: ‘nearest’}
}
- Returns:
A new ParquetBlockModel instance with the upsampled grid.
- Return type:
- class parq_blockmodel.RegularGeometry(local=None, world=None, schema_version='1.0', world_id_encoding=None, corner=None, block_size=None, shape=None, axis_u=None, axis_v=None, axis_w=None, srs=None)[source]#
Dense, metadata-defined block model geometry (C-order canonical).
This class describes all block model geometry in parq-blockmodel. It does not store x, y, z or i, j, k per block. All coordinates are derived from metadata + implicit row ordering.
- local#
The local lattice geometry (corner, block_size, shape, C-order).
- Type:
- world#
The world embedding with origin, axes, and CRS.
- Type:
- schema_version#
Version of the metadata schema. Default: “1.0”
- Type:
str
- world_id_encoding#
Encoding for world IDs.
- Type:
dict, optional
Note
Internal Storage Ordering (C-order canonical)
parq-blockmodel uses NumPy C-order as its canonical definition of block ordering:
i varies fastest
j varies next
k varies slowest
r = i + ni * (j + nj * k)
This matches:
Parquet row-oriented storage naturally
NumPy operations (ravel, reshape)
Efficient dense arrays
Our metadata-based geometry model
This does NOT match lexicographic MultiIndex sorting (.sort_index([“x”, “y”, “z”])) which yields x slowest, z fastest. MultiIndex lexicographic sorting must NOT define canonical storage.
F-order is NOT used (even though OMF/VTK are sometimes described this way). PyVista accepts C-order 1D arrays perfectly fine.
Canonical = C-order. Do not switch to F-order.
- property axis_u: tuple[float, float, float] | list[float] | ndarray[Any, dtype[floating]]#
Backward-compatible access to U-axis.
- property axis_v: tuple[float, float, float] | list[float] | ndarray[Any, dtype[floating]]#
Backward-compatible access to V-axis.
- property axis_w: tuple[float, float, float] | list[float] | ndarray[Any, dtype[floating]]#
Backward-compatible access to W-axis.
- property block_size: tuple[float, float, float]#
Backward-compatible access to local-axis block spacing
(dx, dy, dz).
- property corner: tuple[float, float, float] | list[float]#
Backward-compatible access to local corner.
- classmethod create(corner=(0.0, 0.0, 0.0), block_size=(1.0, 1.0, 1.0), shape=(1, 1, 1), axis_u=(1.0, 0.0, 0.0), axis_v=(0.0, 1.0, 0.0), axis_w=(0.0, 0.0, 1.0), srs=None)[source]#
Convenience factory for creating RegularGeometry with keyword arguments.
This is the recommended way to construct geometries when you have individual parameters rather than pre-built LocalGeometry and WorldFrame.
- Parameters:
corner (Point, optional) – Local corner
(u₀, v₀, w₀)of block(i=0, j=0, k=0). Defaults to(0, 0, 0).block_size (BlockSize, optional) – Block dimensions
(dx, dy, dz)along the locali/j/k(u/v/w) axes. Defaults to(1, 1, 1).shape (Shape3D, optional) – Number of blocks (nᵢ, nⱼ, nₖ). Defaults to (1, 1, 1).
axis_u (Vector, optional) – Orthonormal U-axis for world embedding. Defaults to (1, 0, 0).
axis_v (Vector, optional) – Orthonormal V-axis for world embedding. Defaults to (0, 1, 0).
axis_w (Vector, optional) – Orthonormal W-axis for world embedding. Defaults to (0, 0, 1).
srs (str, optional) – Spatial reference system identifier.
- Returns:
New geometry instance.
- Return type:
- property extents: tuple[float, float, float, float, float, float]#
Return the axis-aligned bounding box (xmin, xmax, ymin, ymax, zmin, zmax).
For unrotated geometries this is derived directly from corner, block_size, and shape. For rotated geometries, we conservatively compute extents from the centroid cloud.
- classmethod from_attrs(attrs, key='parq-blockmodel')[source]#
Reconstruct geometry from a
DataFrame.attrs-style mapping.attrs[key]is expected to contain the dict produced byto_metadata_dict()(or a compatible future schema thatfrom_metadata()can consume).- Return type:
- classmethod from_multi_index(index, axis_azimuth=0.0, axis_dip=0.0, axis_plunge=0.0)[source]#
Infer geometry from an xyz centroid MultiIndex.
Convenience constructor used by
ParquetBlockModel.from_dataframe()when no explicit geometry is provided. The index must have levels("x", "y", "z")in world coordinates.- Parameters:
index (pd.MultiIndex) – Centroid coordinates with names
["x", "y", "z"].axis_azimuth (float) – Optional rotation angles (degrees) defining the orientation of the logical ijk axes in world space.
axis_dip (float) – Optional rotation angles (degrees) defining the orientation of the logical ijk axes in world space.
axis_plunge (float) – Optional rotation angles (degrees) defining the orientation of the logical ijk axes in world space.
- Return type:
- classmethod from_parquet(filepath, axis_azimuth=0.0, axis_dip=0.0, axis_plunge=0.0, chunk_size=1000000)[source]#
Reconstruct geometry from a Parquet file.
Preferred path is to read geometry metadata from the Parquet key_value_metadata under the reserved key
"parq-blockmodel". If that key is missing, fall back to centroid-based inference usingx, y, zcolumns and provided rotation angles. :rtype:RegularGeometryTodo
Consider efficiency gains by staying in numpy versus using python sets.
- classmethod from_parquet_metadata(metadata, key='parq-blockmodel')[source]#
Reconstruct geometry from Parquet file metadata.
- Parameters:
metadata (
Any) – Either apyarrow.parquet.FileMetaDatainstance or a mapping of key-value metadata (usuallydict[str, str]).key (
str) – Metadata key under which the geometry payload is stored.
- Returns:
The reconstructed geometry.
- Return type:
- Raises:
KeyError – If the key is not present in the provided metadata.
TypeError – If metadata is not a valid type.
ValueError – If the payload cannot be interpreted as valid geometry metadata.
- ijk_from_xyz(x, y, z, tol=1e-06)[source]#
Map world-space centroid coordinates to integer logical ijk indices.
- Return type:
tuple[ndarray,ndarray,ndarray]
- property is_rotated: bool#
Return True if axes differ from the identity orientation.
- property origin: tuple[float, float, float] | list[float]#
Backward-compatible access to world origin.
- row_index_from_xyz(x, y, z, tol=1e-06)[source]#
Map world-space centroid coordinates directly to C-order row indices.
- Return type:
ndarray
- property shape: tuple[int, int, int] | list[float]#
Backward-compatible access to grid shape.
- property srs: str | None#
Backward-compatible access to spatial reference system.
- to_dataframe()[source]#
Backward-compatible alias for
to_dataframe_xyz().- Return type:
DataFrame
- to_dataframe_xyz()[source]#
Return a DataFrame of XYZ centroids for export/inspection.
- Return type:
DataFrame
- to_multi_index_ijk()[source]#
Export (i, j, k) indices as a MultiIndex in C‑order.
- Return type:
MultiIndex
- to_multi_index_xyz()[source]#
Return XYZ centroid coordinates as a MultiIndex. :rtype:
MultiIndexNote
This MultiIndex preserves C‑order row layout. If you want lexicographic (‘x slowest, z fastest’), sort it explicitly:
mi = geom.to_multi_index_xyz().sort_index()
- to_pyvista(*, frame='world')[source]#
Return a
pyvista.ImageDatarepresenting the dense grid.- Parameters:
frame (str, optional) – Coordinate frame used for the returned grid. -
"world"(default): apply world orientation fromaxis_u/v/w. -"local": return axis-aligned local grid (no rotation).- Returns:
The grid representation.
- Return type:
pyvista.ImageData
Note
In
"world"mode, rotation is encoded using the ImageData direction matrix, so plotting reflects geometry orientation.
- class parq_blockmodel.WorldFrame(origin=(0.0, 0.0, 0.0), axis_u=(1.0, 0.0, 0.0), axis_v=(0.0, 1.0, 0.0), axis_w=(0.0, 0.0, 1.0), srs=None)[source]#
World embedding for local geometry.
Holds world origin, orthonormal axes, and optional CRS. It is responsible for local<->world coordinate transforms.
- origin#
World origin coordinates (x0, y0, z0).
- Type:
Point
- axis_u#
Unit vector for U-axis in world coordinates.
- Type:
Vector
- axis_v#
Unit vector for V-axis in world coordinates.
- Type:
Vector
- axis_w#
Unit vector for W-axis in world coordinates.
- Type:
Vector
- srs#
Spatial reference system (CRS) identifier.
- Type:
str, optional
- local_to_world(local_points)[source]#
Map local 3xN points into world coordinates.
- Return type:
ndarray
- property rotation_matrix: ndarray#
Return matrix whose columns are world axes (u, v, w).
- parq_blockmodel.create_demo_blockmodel(shape=(3, 3, 3), block_size=(1.0, 1.0, 1.0), corner=(0.0, 0.0, 0.0), azimuth=0.0, dip=0.0, plunge=0.0, parquet_filepath=None, index_type='block_index')[source]#
Create a synthetic block model DataFrame or Parquet file.
This function generates a rectilinear block model defined in logical index space (i, j, k), together with world–space centroids and optional rotation. The function is intended for testing, exploration, and examples.
───────────────────────────────────────────────────────────────────────────── BLOCK MODEL INDEXING :rtype:
DataFrame|Path───────────────────────────────────────────────────────────────────────────── Logical indices:
(i, j, k) represent block indices along the x, y, and z axes.
- Sorting by (i, j, k) gives the canonical logical block‑model order:
i varies slowest j varies next k varies fastest
This ordering is purely logical and independent of how NumPy stores the data in memory.
- Canonical block id:
- block_id:
Canonical linear id obtained by flattening logical (i,j,k) coordinates in NumPy C-order. This is frame-invariant and remains stable regardless of world-space rotation.
───────────────────────────────────────────────────────────────────────────── WORLD COORDINATES ───────────────────────────────────────────────────────────────────────────── World centroids are computed using:
x = corner_x + (i + 0.5) * dx y = corner_y + (j + 0.5) * dy z = corner_z + (k + 0.5) * dz
If azimuth, dip, or plunge are non‑zero, the world positions are rotated about the origin after centroid generation.
───────────────────────────────────────────────────────────────────────────── DEPTH INFORMATION ───────────────────────────────────────────────────────────────────────────── - depth:
Computed as (maximum z centroid + dz/2) − z.
- depth_category:
Categorical split into ‘shallow’ and ‘deep’.
───────────────────────────────────────────────────────────────────────────── DATAFRAME INDEXING OPTION ───────────────────────────────────────────────────────────────────────────── index_type:
“block_index”: the DataFrame is indexed by (i, j, k).
“world_centroids”: indexed by (x, y, z).
“block_id”: indexed by canonical block_id.
───────────────────────────────────────────────────────────────────────────── ATTRIBUTES ───────────────────────────────────────────────────────────────────────────── The DataFrame is assigned lightweight geometry metadata under:
- df.attrs[“geometry”] = {
“shape”: (nx, ny, nz), “block_size”: (dx, dy, dz), “corner”: (corner_x, corner_y, corner_z), “rotation”: { “azimuth”: …, “dip”: …, “plunge”: … }, “geometry_type”: “rectilinear_blockmodel”, “canonical_identity”: “block_id”, “index_type”: index_type
}
These attrs are intentionally simpler than the full “parq‑blockmodel” production schema, but pseudo‑compatible and useful for testing.
───────────────────────────────────────────────────────────────────────────── PARAMETERS ───────────────────────────────────────────────────────────────────────────── shape : tuple[int, int, int]
Logical block model size (nx, ny, nz).
- block_sizetuple[float, float, float]
Block dimensions (dx, dy, dz).
- cornertuple[float, float, float]
World‑space minimum corner of the unrotated model.
- azimuth, dip, plungefloat
Rotation angles applied to world centroids.
- parquet_filepathPath | None
If supplied, the DataFrame is written to Parquet.
- index_type{“block_index”, “world_centroids”, “block_id”}
Specifies which index is assigned to the returned DataFrame.
───────────────────────────────────────────────────────────────────────────── RETURNS ───────────────────────────────────────────────────────────────────────────── DataFrame or Path
The block model DataFrame, or the Parquet path if saved.
blockmodel.py |
|