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

.. only:: html

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

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

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

.. _sphx_glr_gallery_02_writing_files_p01_writing_simple_datasets.py:


Writing Simple Datasets
=======================

Write 1D, 2D, and 3D arrays to PSI-style HDF5 or HDF4 files.

This example demonstrates the basics of writing PSI-style HDF files using
:func:`~psi_io.psi_io.write_hdf_data` for generic n-dimensional datasets, and
:func:`~psi_io.psi_io.wrhdf_1d`, :func:`~psi_io.psi_io.wrhdf_2d`,
:func:`~psi_io.psi_io.wrhdf_3d` for dimensionality-specific writing.

.. GENERATED FROM PYTHON SOURCE LINES 12-18

.. code-block:: Python


    import tempfile
    from pathlib import Path
    import numpy as np
    from psi_io import write_hdf_data, wrhdf_1d, wrhdf_2d, wrhdf_3d, read_hdf_data








.. GENERATED FROM PYTHON SOURCE LINES 19-23

Construct a simple 3D dataset representing a hypothetical scalar field on a
rectilinear (r, θ, φ) grid. Following PSI's Fortran ordering convention, the
data array is C-ordered as (nφ, nθ, nr) while the scales are supplied in
physical dimension order (r, θ, φ):

.. GENERATED FROM PYTHON SOURCE LINES 23-30

.. code-block:: Python


    nr, nt, np_ = 10, 20, 30
    r = np.linspace(1.0, 5.0, nr, dtype=np.float32)
    t = np.linspace(0.0, np.pi, nt, dtype=np.float32)
    p = np.linspace(0.0, 2*np.pi, np_, dtype=np.float32)
    f3d = np.random.default_rng(0).random((np_, nt, nr)).astype(np.float32)








.. GENERATED FROM PYTHON SOURCE LINES 31-33

Write the dataset to an HDF5 file with :func:`~psi_io.psi_io.write_hdf_data`.
Scales are passed as positional arguments in physical dimension order (r, θ, φ):

.. GENERATED FROM PYTHON SOURCE LINES 33-45

.. code-block:: Python


    with tempfile.TemporaryDirectory() as tmpdir:
        out_h5 = Path(tmpdir) / "output.h5"
        write_hdf_data(out_h5, f3d, r, t, p)

        f_back, r_back, t_back, p_back = read_hdf_data(out_h5)
        print(f"Data shape (read back) : {f_back.shape}")
        print(f"r scale : shape={r_back.shape}, range=[{r_back[0]:.2f}, {r_back[-1]:.2f}]")
        print(f"t scale : shape={t_back.shape}, range=[{t_back[0]:.4f}, {t_back[-1]:.4f}]")
        print(f"p scale : shape={p_back.shape}, range=[{p_back[0]:.4f}, {p_back[-1]:.4f}]")
        print(f"Round-trip exact match : {np.array_equal(f3d, f_back)}")





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

 .. code-block:: none

    Data shape (read back) : (30, 20, 10)
    r scale : shape=(10,), range=[1.00, 5.00]
    t scale : shape=(20,), range=[0.0000, 3.1416]
    p scale : shape=(30,), range=[0.0000, 6.2832]
    Round-trip exact match : True




.. GENERATED FROM PYTHON SOURCE LINES 46-48

Writing to an HDF4 file uses the identical call – only the file extension changes.
Dispatch to the correct backend is handled automatically based on the extension:

.. GENERATED FROM PYTHON SOURCE LINES 48-57

.. code-block:: Python


    with tempfile.TemporaryDirectory() as tmpdir:
        out_hdf = Path(tmpdir) / "output.hdf"
        write_hdf_data(out_hdf, f3d, r, t, p)

        f_back_h4 = read_hdf_data(out_hdf, return_scales=False)
        print(f"HDF4 data shape (read back) : {f_back_h4.shape}")
        print(f"Round-trip exact match      : {np.array_equal(f3d, f_back_h4)}")





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

 .. code-block:: none

    HDF4 data shape (read back) : (30, 20, 10)
    Round-trip exact match      : True




.. GENERATED FROM PYTHON SOURCE LINES 58-60

For 1D and 2D datasets the same conventions apply – the scale(s) precede the
data in the positional argument list:

.. GENERATED FROM PYTHON SOURCE LINES 60-76

.. code-block:: Python


    x = np.linspace(0.0, 2*np.pi, 64, dtype=np.float32)
    f1d = np.sin(x)

    y = np.linspace(0.0, np.pi, 32, dtype=np.float32)
    f2d = np.outer(np.sin(x), np.cos(y)).astype(np.float32)

    with tempfile.TemporaryDirectory() as tmpdir:
        write_hdf_data(Path(tmpdir) / "out1d.h5", f1d, x)
        write_hdf_data(Path(tmpdir) / "out2d.h5", f2d, x, y)

        r1d = read_hdf_data(Path(tmpdir) / "out1d.h5")
        r2d = read_hdf_data(Path(tmpdir) / "out2d.h5")
        print(f"1D : data={r1d[0].shape}, scale={r1d[1].shape}")
        print(f"2D : data={r2d[0].shape}, x={r2d[1].shape}, y={r2d[2].shape}")





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

 .. code-block:: none

    1D : data=(64,), scale=(64,)
    2D : data=(64, 32), x=(64,), y=(32,)




.. GENERATED FROM PYTHON SOURCE LINES 77-87

The legacy dimension-specific writers (:func:`~psi_io.psi_io.wrhdf_1d`,
:func:`~psi_io.psi_io.wrhdf_2d`, :func:`~psi_io.psi_io.wrhdf_3d`) provide a
backward-compatible interface for existing PSI codes.

.. attention::
   The argument order of these writers differs from :func:`~psi_io.psi_io.write_hdf_data`:
   scales are interleaved between the filename and the data array
   (*filename*, *x*, [*y*, [*z*,]] *f*). They also default to ``sync_dtype=True``,
   which silently casts scale arrays to match the data dtype, and always write to
   PSI's standard dataset identifiers (``'Data-Set-2'`` for HDF4, ``'Data'`` for HDF5).

.. GENERATED FROM PYTHON SOURCE LINES 87-96

.. code-block:: Python


    with tempfile.TemporaryDirectory() as tmpdir:
        wrhdf_1d(Path(tmpdir) / "legacy1d.h5", x, f1d)
        wrhdf_2d(Path(tmpdir) / "legacy2d.h5", x, y, f2d)
        wrhdf_3d(Path(tmpdir) / "legacy3d.h5", r, t, p, f3d)

        rl3d = read_hdf_data(Path(tmpdir) / "legacy3d.h5")
        print(f"Legacy 3D : data={rl3d[0].shape}, r={rl3d[1].shape}, t={rl3d[2].shape}, p={rl3d[3].shape}")
        print(f"Round-trip exact match : {np.array_equal(f3d, rl3d[0])}")




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

 .. code-block:: none

    Legacy 3D : data=(30, 20, 10), r=(10,), t=(20,), p=(30,)
    Round-trip exact match : True





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

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


.. _sphx_glr_download_gallery_02_writing_files_p01_writing_simple_datasets.py:

.. only:: html

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

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

      :download:`Download Jupyter notebook: p01_writing_simple_datasets.ipynb <p01_writing_simple_datasets.ipynb>`

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

      :download:`Download Python source code: p01_writing_simple_datasets.py <p01_writing_simple_datasets.py>`

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

      :download:`Download zipped: p01_writing_simple_datasets.zip <p01_writing_simple_datasets.zip>`


.. only:: html

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

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