
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/04_rotated_blockmodel.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_04_rotated_blockmodel.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_04_rotated_blockmodel.py:


Rotated Blockmodel
==================

Minimal example of a **rotated** block model using the new ijk‑first
geometry design.

The key idea is:

* ijk indices and ``shape`` define the canonical dense grid.
* Rotation is represented via the orthonormal basis vectors
  ``axis_u, axis_v, axis_w`` on :class:`parq_blockmodel.geometry.RegularGeometry`.
* World coordinates ``(x, y, z)`` are a *derived view* of
  ``(i, j, k) + geometry``. Changing the axes rotates the xyz centroids
  without changing ijk.

This example:

1. Constructs a small ``RegularGeometry`` with a 30° azimuth rotation.
2. Builds a canonical ``.pbm`` file from that geometry using
   :meth:`ParquetBlockModel.from_geometry`.
3. Derives a simple scalar ``z_centroid`` from the rotated xyz and
   visualises it using :meth:`ParquetBlockModel.plot`.

.. GENERATED FROM PYTHON SOURCE LINES 25-36

.. code-block:: Python


    import tempfile

    from pathlib import Path

    import pyvista as pv

    from parq_blockmodel import ParquetBlockModel, RegularGeometry
    from parq_blockmodel.utils.geometry_utils import angles_to_axes









.. GENERATED FROM PYTHON SOURCE LINES 37-39

Define a small rotated RegularGeometry
--------------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 39-58

.. code-block:: Python

    corner = (0.0, 0.0, 0.0)
    block_size = (1.0, 1.0, 1.0)
    shape = (3, 3, 3)

    axis_u, axis_v, axis_w = angles_to_axes(
        axis_azimuth=30.0,
        axis_dip=0.0,
        axis_plunge=0.0,
    )

    geometry = RegularGeometry(
        corner=corner,
        block_size=block_size,
        shape=shape,
        axis_u=axis_u,
        axis_v=axis_v,
        axis_w=axis_w,
    )








.. GENERATED FROM PYTHON SOURCE LINES 59-61

Materialise a canonical .pbm from geometry only
-----------------------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 61-77

.. code-block:: Python

    temp_dir: Path = Path(tempfile.gettempdir()) / "rotated_block_model_example"
    temp_dir.mkdir(parents=True, exist_ok=True)
    pbm_path = temp_dir / "rotated_block_model.pbm"

    pbm = ParquetBlockModel.from_geometry(geometry=geometry, path=pbm_path)

    print("Block Model Path:", pbm.blockmodel_path)
    print("Name:", pbm.name)
    print("Shape (ijk):", pbm.geometry.shape)
    print("Corner:", pbm.geometry.corner)
    print("Block size (local i/j/k spacing):", pbm.geometry.block_size)
    print("Axis U:", pbm.geometry.axis_u)
    print("Axis V:", pbm.geometry.axis_v)
    print("Axis W:", pbm.geometry.axis_w)
    print("Rotated centroids (head):\n", pbm.geometry.to_dataframe_xyz().head())





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Block Model Path: /tmp/rotated_block_model_example/rotated_block_model.pbm
    Name: rotated_block_model
    Shape (ijk): (3, 3, 3)
    Corner: (0.0, 0.0, 0.0)
    Block size (local i/j/k spacing): (1.0, 1.0, 1.0)
    Axis U: (0.8660254037844387, 0.49999999999999994, 0.0)
    Axis V: (-0.49999999999999994, 0.8660254037844387, 0.0)
    Axis W: (0.0, 0.0, 1.0)
    Rotated centroids (head):
               x         y    z
    0  0.183013  0.683013  0.5
    1  0.183013  0.683013  1.5
    2  0.183013  0.683013  2.5
    3 -0.316987  1.549038  0.5
    4 -0.316987  1.549038  1.5




.. GENERATED FROM PYTHON SOURCE LINES 78-81

Derive a simple scalar from rotated xyz centroids
-------------------------------------------------
For visualisation we use the rotated Z centroid as a scalar field.

.. GENERATED FROM PYTHON SOURCE LINES 81-96

.. code-block:: Python


    df = pbm.read(index="xyz", dense=True)
    df["z_centroid"] = df.index.get_level_values("z")

    # Persist the derived scalar back to the pbm Parquet file so that
    # ParquetBlockModel.plot can see it as an attribute.
    df.to_parquet(pbm.blockmodel_path)

    # Refresh the ParquetBlockModel's view of available columns/attributes
    # now that we've updated the underlying file.
    import pyarrow.parquet as pq
    pbm.columns = pq.read_schema(pbm.blockmodel_path).names
    pbm.attributes = [col for col in pbm.columns if col not in ["x", "y", "z"]]
    pbm.attributes





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    ['block_id', 'world_id', 'z_centroid', '__index_level_0__', '__index_level_1__', '__index_level_2__']



.. GENERATED FROM PYTHON SOURCE LINES 97-99

Plot
----

.. GENERATED FROM PYTHON SOURCE LINES 99-104

.. code-block:: Python


    plotter: pv.Plotter = pbm.plot(scalar="z_centroid", grid_type="image")
    plotter.show()





.. image-sg:: /auto_examples/images/sphx_glr_04_rotated_blockmodel_001.png
   :alt: 04 rotated blockmodel
   :srcset: /auto_examples/images/sphx_glr_04_rotated_blockmodel_001.png
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.596 seconds)


.. _sphx_glr_download_auto_examples_04_rotated_blockmodel.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: 04_rotated_blockmodel.ipynb <04_rotated_blockmodel.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: 04_rotated_blockmodel.py <04_rotated_blockmodel.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: 04_rotated_blockmodel.zip <04_rotated_blockmodel.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
