{ "cells": [ { "cell_type": "markdown", "id": "8d04a175", "metadata": {}, "source": [ "# Importing/Exporting field from/to `xarray.DataArray`\n", "\n", "[`xarray`](https://docs.xarray.dev/en/stable/) provides a convenient method to handle *labeled* multi-dimensional arrays. It integrates well with `numpy` and `pandas` for fast array manipulation, as well as `matplotlib` for visualization. This makes it a good candidate to carry `discretisedfield.Field` data and additional metadata such as field name and unit (which appear in the plots rendered by `matplotlib`).\n", "\n", "## Exporting `discretisedfield.Field` to `xarray.DataArray`\n", "\n", "`to_xarray` method of the `discretisedfield.Field` object is utilised to export the field data to a DataArray." ] }, { "cell_type": "code", "execution_count": 1, "id": "756dbabb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "Field\n", "" ], "text/plain": [ "Field(Mesh(Region(p1=(0, 0, 0), p2=(1e-08, 1e-08, 1e-08)), n=(2, 2, 2), attributes: (unit: m, fourierspace: False, isplane: False)), dim=3, components: (x, y, z))" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import discretisedfield as df\n", "\n", "p1 = (0, 0, 0)\n", "p2 = (10e-9, 10e-9, 10e-9)\n", "cell = (5e-9, 5e-9, 5e-9)\n", "\n", "mesh = df.Mesh(p1=p1, p2=p2, cell=cell)\n", "field = df.Field(mesh=mesh, dim=3, value=(0, 0, 1))\n", "field" ] }, { "cell_type": "code", "execution_count": 2, "id": "705c72bc", "metadata": { "tags": [ "nbval-ignore-output" ] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'field' (x: 2, y: 2, z: 2, comp: 3)>\n",
       "array([[[[0., 0., 1.],\n",
       "         [0., 0., 1.]],\n",
       "\n",
       "        [[0., 0., 1.],\n",
       "         [0., 0., 1.]]],\n",
       "\n",
       "\n",
       "       [[[0., 0., 1.],\n",
       "         [0., 0., 1.]],\n",
       "\n",
       "        [[0., 0., 1.],\n",
       "         [0., 0., 1.]]]])\n",
       "Coordinates:\n",
       "  * x        (x) float64 2.5e-09 7.5e-09\n",
       "  * y        (y) float64 2.5e-09 7.5e-09\n",
       "  * z        (z) float64 2.5e-09 7.5e-09\n",
       "  * comp     (comp) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    units:    None\n",
       "    cell:     (5e-09, 5e-09, 5e-09)\n",
       "    p1:       (0, 0, 0)\n",
       "    p2:       (1e-08, 1e-08, 1e-08)
" ], "text/plain": [ "\n", "array([[[[0., 0., 1.],\n", " [0., 0., 1.]],\n", "\n", " [[0., 0., 1.],\n", " [0., 0., 1.]]],\n", "\n", "\n", " [[[0., 0., 1.],\n", " [0., 0., 1.]],\n", "\n", " [[0., 0., 1.],\n", " [0., 0., 1.]]]])\n", "Coordinates:\n", " * x (x) float64 2.5e-09 7.5e-09\n", " * y (y) float64 2.5e-09 7.5e-09\n", " * z (z) float64 2.5e-09 7.5e-09\n", " * comp (comp) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'field' (y: 2, z: 2, comp: 3)>\n",
       "array([[[0., 0., 1.],\n",
       "        [0., 0., 1.]],\n",
       "\n",
       "       [[0., 0., 1.],\n",
       "        [0., 0., 1.]]])\n",
       "Coordinates:\n",
       "    x        float64 2.5e-09\n",
       "  * y        (y) float64 2.5e-09 7.5e-09\n",
       "  * z        (z) float64 2.5e-09 7.5e-09\n",
       "  * comp     (comp) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    units:    None\n",
       "    cell:     (5e-09, 5e-09, 5e-09)\n",
       "    p1:       (0, 0, 0)\n",
       "    p2:       (1e-08, 1e-08, 1e-08)
" ], "text/plain": [ "\n", "array([[[0., 0., 1.],\n", " [0., 0., 1.]],\n", "\n", " [[0., 0., 1.],\n", " [0., 0., 1.]]])\n", "Coordinates:\n", " x float64 2.5e-09\n", " * y (y) float64 2.5e-09 7.5e-09\n", " * z (z) float64 2.5e-09 7.5e-09\n", " * comp (comp) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'field' (x: 2, y: 2, z: 2)>\n",
       "array([[[1., 1.],\n",
       "        [1., 1.]],\n",
       "\n",
       "       [[1., 1.],\n",
       "        [1., 1.]]])\n",
       "Coordinates:\n",
       "  * x        (x) float64 2.5e-09 7.5e-09\n",
       "  * y        (y) float64 2.5e-09 7.5e-09\n",
       "  * z        (z) float64 2.5e-09 7.5e-09\n",
       "    comp     <U1 'z'\n",
       "Attributes:\n",
       "    units:    None\n",
       "    cell:     (5e-09, 5e-09, 5e-09)\n",
       "    p1:       (0, 0, 0)\n",
       "    p2:       (1e-08, 1e-08, 1e-08)
" ], "text/plain": [ "\n", "array([[[1., 1.],\n", " [1., 1.]],\n", "\n", " [[1., 1.],\n", " [1., 1.]]])\n", "Coordinates:\n", " * x (x) float64 2.5e-09 7.5e-09\n", " * y (y) float64 2.5e-09 7.5e-09\n", " * z (z) float64 2.5e-09 7.5e-09\n", " comp \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'field' (y: 2, z: 2)>\n",
       "array([[1., 1.],\n",
       "       [1., 1.]])\n",
       "Coordinates:\n",
       "    x        float64 2.5e-09\n",
       "  * y        (y) float64 2.5e-09 7.5e-09\n",
       "  * z        (z) float64 2.5e-09 7.5e-09\n",
       "    comp     <U1 'z'\n",
       "Attributes:\n",
       "    units:    None\n",
       "    cell:     (5e-09, 5e-09, 5e-09)\n",
       "    p1:       (0, 0, 0)\n",
       "    p2:       (1e-08, 1e-08, 1e-08)
" ], "text/plain": [ "\n", "array([[1., 1.],\n", " [1., 1.]])\n", "Coordinates:\n", " x float64 2.5e-09\n", " * y (y) float64 2.5e-09 7.5e-09\n", " * z (z) float64 2.5e-09 7.5e-09\n", " comp " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "xarray.sel(comp=\"z\").sel(x=2e-9, method=\"nearest\").plot();" ] }, { "cell_type": "markdown", "id": "fafc118b", "metadata": {}, "source": [ "Notice that proper units and labels on the plot are displayed by default. The full list of `xarray.DataArray` methods can be found in the [API reference](https://docs.xarray.dev/en/stable/api.html)." ] }, { "cell_type": "markdown", "id": "fac0b5cc", "metadata": {}, "source": [ "### `to_xarray` exceptions\n", "\n", "The `to_xarray` method raises `TypeError` if either `name` or `units` arguments are not `str`." ] }, { "cell_type": "markdown", "id": "7d7623ea", "metadata": {}, "source": [ "\n", "## Importing `discretisedfield.Field` from `xarray.DataArray`" ] }, { "cell_type": "markdown", "id": "a7a16de3", "metadata": {}, "source": [ "It is possible to create a `discretisedfield.Field` from an `xarray.DataArray` with the help of class method `from_xarray`. As a first step, we convert the `xarray.DataArray` created by `to_xarray` method to a new `discretisedfield.Field`." ] }, { "cell_type": "code", "execution_count": 9, "id": "3953428f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "Field\n", "
    \n", " \n", "
  • Mesh\n", "
      \n", "
    • Region\n", "
        \n", "
      • p1 = (0, 0, 0)
      • \n", "
      • p2 = (1e-08, 1e-08, 1e-08)
      • \n", "
    • \n", "
    • n = (2, 2, 2)
    • \n", "
    • attributes:\n", "
        \n", "
      • unit: m
      • \n", "
      • fourierspace: False
      • \n", "
      • isplane: False
      • \n", "
      \n", "
    • \n", "
  • \n", "
  • dim = 3
  • \n", "
  • components:\n", "
    • x
    • \n", "
    • y
    • \n", "
    • z
    • \n", "
    \n", "
  • \n", "
" ], "text/plain": [ "Field(Mesh(Region(p1=(0, 0, 0), p2=(1e-08, 1e-08, 1e-08)), n=(2, 2, 2), attributes: (unit: m, fourierspace: False, isplane: False)), dim=3, components: (x, y, z))" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "field_new = df.Field.from_xarray(xarray)\n", "field_new" ] }, { "cell_type": "markdown", "id": "97a32e8c", "metadata": {}, "source": [ "One can also first define an `xarray.DataArray` and then convert it to `discretisedfield.Field`." ] }, { "cell_type": "markdown", "id": "6db802ff", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": 10, "id": "7dc09fa2", "metadata": { "tags": [ "nbval-ignore-output" ] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'mag' (x: 2, y: 2, z: 2, comp: 3)>\n",
       "array([[[[1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.]]]])\n",
       "Coordinates:\n",
       "  * x        (x) float64 2.5e-09 7.5e-09\n",
       "  * y        (y) float64 2.5e-09 7.5e-09\n",
       "  * z        (z) float64 2.5e-09 7.5e-09\n",
       "  * comp     (comp) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    cell:     [5e-09, 5e-09, 5e-09]\n",
       "    p1:       [0.0, 0.0, 0.0]\n",
       "    p2:       [1e-08, 1e-08, 1e-08]
" ], "text/plain": [ "\n", "array([[[[1., 1., 1.],\n", " [1., 1., 1.]],\n", "\n", " [[1., 1., 1.],\n", " [1., 1., 1.]]],\n", "\n", "\n", " [[[1., 1., 1.],\n", " [1., 1., 1.]],\n", "\n", " [[1., 1., 1.],\n", " [1., 1., 1.]]]])\n", "Coordinates:\n", " * x (x) float64 2.5e-09 7.5e-09\n", " * y (y) float64 2.5e-09 7.5e-09\n", " * z (z) float64 2.5e-09 7.5e-09\n", " * comp (comp) Field\n", "
    \n", " \n", "
  • Mesh\n", "
      \n", "
    • Region\n", "
        \n", "
      • p1 = (0.0, 0.0, 0.0)
      • \n", "
      • p2 = (1e-08, 1e-08, 1e-08)
      • \n", "
    • \n", "
    • n = (2, 2, 2)
    • \n", "
    • attributes:\n", "
        \n", "
      • unit: m
      • \n", "
      • fourierspace: False
      • \n", "
      • isplane: False
      • \n", "
      \n", "
    • \n", "
  • \n", "
  • dim = 3
  • \n", "
  • components:\n", "
    • x
    • \n", "
    • y
    • \n", "
    • z
    • \n", "
    \n", "
  • \n", "
" ], "text/plain": [ "Field(Mesh(Region(p1=(0.0, 0.0, 0.0), p2=(1e-08, 1e-08, 1e-08)), n=(2, 2, 2), attributes: (unit: m, fourierspace: False, isplane: False)), dim=3, components: (x, y, z))" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "field_xdr = df.Field.from_xarray(xdr)\n", "field_xdr" ] }, { "cell_type": "markdown", "id": "c040b8a9", "metadata": {}, "source": [ "### `from_xarray` exceptions and expected properties of input `xarray.DataArray`\n", "\n", "The input argument of `from_xarray` must be an `xarray.DataArray`, otherwise a `TypeError` is raised. Further, the input `xarray.DataArray` must have following properties in order to obtain a `discretisedfield.Field`:\n", "1. The dimensions must be either three or four depending on whether the field is scalar or vector. If not, a `ValueError` is raised.\n", "2. The name of the dimensions must be `x`, `y`, `z`, and `comp` (if a vector field). If not, a `ValueError` is raised.\n", "3. The coordinates of the `x`, `y`, and `z` dimensions must be equally spaced. If not, a `ValueError` is raised.\n", "\n", "Lastly, **it is strongly advised that the input `xarray.DataArray` should have `p1`, `p2`, and `cell` attributes** required for the reconstruction of the mesh. The `xarray.DataArray` in the [above example](#good_xarray) has all these properties." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.12" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }