
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "gallery/02_writing_files/p04_annotating_and_converting_br.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_p04_annotating_and_converting_br.py>`
        to download the full example code.

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

.. _sphx_glr_gallery_02_writing_files_p04_annotating_and_converting_br.py:


Annotating and Converting the Radial Magnetic Field
=====================================================

Read the radial magnetic field dataset from HDF4, attach physically meaningful
metadata, and produce a PSI-convention HDF5 file.

This example walks through a realistic data-preparation workflow:

1. Read the radial magnetic field (Br) data and its coordinate scales from the
   example HDF4 file.
2. Attach attributes that describe the physical quantity, coordinate system, and
   units using types compatible with both HDF4 and HDF5.
3. Write an annotated HDF4 file.
4. Convert that file to HDF5 using :func:`~psi_io.psi_io.convert_psih4_to_psih5`,
   which preserves the attached attributes in the output.

.. note::
   This example can be amended to include additional or domain-specific metadata
   once the basic pipeline is confirmed to work end-to-end.

.. GENERATED FROM PYTHON SOURCE LINES 22-28

.. code-block:: Python


    import tempfile
    from pathlib import Path
    import numpy as np
    from psi_io import read_hdf_data, write_hdf_data, read_hdf_meta, convert_psih4_to_psih5, data








.. GENERATED FROM PYTHON SOURCE LINES 29-33

**Step 1 – Read the source HDF4 file**

Fetch the example radial magnetic field file and load the primary dataset
together with its (r, θ, φ) coordinate scales:

.. GENERATED FROM PYTHON SOURCE LINES 33-43

.. code-block:: Python


    br_filepath = data.get_3d_data(hdf=".hdf")
    print(f"Source file : {Path(br_filepath).name}")

    br_data, r, t, p = read_hdf_data(br_filepath)
    print(f"\nData shape : {br_data.shape}  (nφ × nθ × nr, Fortran-ordered)")
    print(f"r scale    : {r.shape},  range = [{r[0]:.4f},  {r[-1]:.4f}]  R☉")
    print(f"θ scale    : {t.shape},  range = [{t[0]:.4f},  {t[-1]:.4f}]  rad")
    print(f"φ scale    : {p.shape},  range = [{p[0]:.4f}, {p[-1]:.4f}]  rad")





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

 .. code-block:: none

    Source file : br.hdf

    Data shape : (181, 100, 151)  (nφ × nθ × nr, Fortran-ordered)
    r scale    : (151,),  range = [0.9996,  30.5116]  R☉
    θ scale    : (100,),  range = [0.0000,  3.1416]  rad
    φ scale    : (181,),  range = [0.0000, 6.2832]  rad




.. GENERATED FROM PYTHON SOURCE LINES 44-52

**Step 2 – Define the attributes**

All attribute values are chosen to be compatible with HDF4's SDC type system:
``float32`` and ``int32`` scalars for numeric quantities, and plain Python
strings for descriptive fields. ``float16``, ``int64``, and ``uint64`` are
**not** supported by HDF4 and must be avoided (see the
:ref:`sphx_glr_gallery_02_writing_files_p02_writing_datasets_with_attributes.py`
example for a full discussion of type restrictions):

.. GENERATED FROM PYTHON SOURCE LINES 52-63

.. code-block:: Python


    br_attrs = dict(
        variable="br",
        long_name="Radial Magnetic Field",
        coord_system="Carrington",
        r_units="R_sun",
        angle_units="radians",
        b_scale=np.float32(2.2047),     # reference field scale [Gauss]
        cr_number=np.int32(2190),       # Carrington rotation number
    )








.. GENERATED FROM PYTHON SOURCE LINES 64-70

**Step 3 – Write an annotated HDF4 file**

Pass the attributes as keyword arguments to :func:`~psi_io.psi_io.write_hdf_data`.
The dataset identifier is omitted so the PSI-standard name ``'Data-Set-2'`` is
used, which is required by :func:`~psi_io.psi_io.convert_psih4_to_psih5` in
the next step:

.. GENERATED FROM PYTHON SOURCE LINES 70-78

.. code-block:: Python


    _tmp = tempfile.TemporaryDirectory()
    tmpdir = Path(_tmp.name)

    annotated_hdf = tmpdir / "br_annotated.hdf"
    write_hdf_data(annotated_hdf, br_data, r, t, p, **br_attrs)
    print(f"Annotated HDF4 written : {annotated_hdf.name}")





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

 .. code-block:: none

    Annotated HDF4 written : br_annotated.hdf




.. GENERATED FROM PYTHON SOURCE LINES 79-83

**Step 4 – Convert to PSI-convention HDF5**

:func:`~psi_io.psi_io.convert_psih4_to_psih5` reads ``'Data-Set-2'`` from the
HDF4 file, remaps it to ``'Data'``, and carries over the attached attributes:

.. GENERATED FROM PYTHON SOURCE LINES 83-88

.. code-block:: Python


    annotated_h5 = tmpdir / "br_annotated.h5"
    convert_psih4_to_psih5(annotated_hdf, annotated_h5)
    print(f"Converted to HDF5      : {annotated_h5.name}")





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

 .. code-block:: none

    Converted to HDF5      : br_annotated.h5




.. GENERATED FROM PYTHON SOURCE LINES 89-93

**Step 5 – Verify the round-trip**

Confirm that the dataset, scales, and all attributes survived the write-and-convert
pipeline intact:

.. GENERATED FROM PYTHON SOURCE LINES 93-107

.. code-block:: Python


    meta = read_hdf_meta(annotated_h5)
    print(f"\nDataset : {meta[0].name!r}  shape={meta[0].shape}  dtype={meta[0].type}")

    print("\nAttributes:")
    for key, val in meta[0].attr.items():
        print(f"  {key:<16}: {val!r}")

    print("\nScales:")
    for s in meta[0].scales:
        print(f"  {s.name!r:<8} shape={s.shape}  "
              f"range=[{s.imin:.4f}, {s.imax:.4f}]")

    _tmp.cleanup()




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

 .. code-block:: none


    Dataset : 'Data'  shape=(181, 100, 151)  dtype=float32

    Attributes:
      DIMENSION_LABELS: array(['dim1', 'dim2', 'dim3'], dtype=object)
      DIMENSION_LIST  : array([array([<HDF5 object reference>], dtype=object),
           array([<HDF5 object reference>], dtype=object),
           array([<HDF5 object reference>], dtype=object)], dtype=object)
      angle_units     : 'radians'
      b_scale         : np.float64(2.204699993133545)
      coord_system    : 'Carrington'
      cr_number       : np.int64(2190)
      long_name       : 'Radial Magnetic Field'
      r_units         : 'R_sun'
      variable        : 'br'

    Scales:
      'dim1'   shape=(151,)  range=[0.9996, 30.5116]
      'dim2'   shape=(100,)  range=[0.0000, 3.1416]
      'dim3'   shape=(181,)  range=[0.0000, 6.2832]





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

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


.. _sphx_glr_download_gallery_02_writing_files_p04_annotating_and_converting_br.py:

.. only:: html

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

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

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

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

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

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

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


.. only:: html

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

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