{ "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` and `holoviews` 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 rendered plots).\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. As an example, we use a three-dimensional field." ] }, { "cell_type": "code", "execution_count": 1, "id": "756dbabb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "Field\n", "" ], "text/plain": [ "Field(Mesh(Region(pmin=[0.0, 0.0, 0.0], pmax=[1e-08, 1e-08, 1e-08], dims=['x', 'y', 'z'], units=['m', 'm', 'm']), n=[2, 2, 2]), nvdim=3, vdims: (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, nvdim=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, vdims: 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",
       "  * vdims    (vdims) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    units:             None\n",
       "    cell:              [5.e-09 5.e-09 5.e-09]\n",
       "    pmin:              [0. 0. 0.]\n",
       "    pmax:              [1.e-08 1.e-08 1.e-08]\n",
       "    nvdim:             3\n",
       "    tolerance_factor:  1e-12
" ], "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", " * vdims (vdims) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'field' (y: 2, z: 2, vdims: 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",
       "  * vdims    (vdims) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    units:             None\n",
       "    cell:              [5.e-09 5.e-09 5.e-09]\n",
       "    pmin:              [0. 0. 0.]\n",
       "    pmax:              [1.e-08 1.e-08 1.e-08]\n",
       "    nvdim:             3\n",
       "    tolerance_factor:  1e-12
" ], "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", " * vdims (vdims) \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",
       "    vdims    <U1 'z'\n",
       "Attributes:\n",
       "    units:             None\n",
       "    cell:              [5.e-09 5.e-09 5.e-09]\n",
       "    pmin:              [0. 0. 0.]\n",
       "    pmax:              [1.e-08 1.e-08 1.e-08]\n",
       "    nvdim:             3\n",
       "    tolerance_factor:  1e-12
" ], "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", " vdims \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",
       "    vdims    <U1 'z'\n",
       "Attributes:\n",
       "    units:             None\n",
       "    cell:              [5.e-09 5.e-09 5.e-09]\n",
       "    pmin:              [0. 0. 0.]\n",
       "    pmax:              [1.e-08 1.e-08 1.e-08]\n",
       "    nvdim:             3\n",
       "    tolerance_factor:  1e-12
" ], "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", " vdims " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "xarray.sel(vdims=\"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 `unit` 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 primary example, 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", "
      • pmin = [0.0, 0.0, 0.0]
      • \n", "
      • pmax = [1e-08, 1e-08, 1e-08]
      • \n", "
      • dims = ['x', 'y', 'z']
      • \n", "
      • units = ['m', 'm', 'm']
      • \n", "
    • \n", "
    • n = [2, 2, 2]
    • \n", "
  • \n", "
  • nvdim = 3
  • \n", "
  • vdims:\n", "
    • x
    • \n", "
    • y
    • \n", "
    • z
    • \n", "
    \n", "
  • \n", "
" ], "text/plain": [ "Field(Mesh(Region(pmin=[0.0, 0.0, 0.0], pmax=[1e-08, 1e-08, 1e-08], dims=['x', 'y', 'z'], units=['m', 'm', 'm']), n=[2, 2, 2]), nvdim=3, vdims: (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, vdims: 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",
       "  * vdims    (vdims) <U1 'x' 'y' 'z'\n",
       "Attributes:\n",
       "    nvdim:    3\n",
       "    cell:     [5e-09, 5e-09, 5e-09]\n",
       "    pmin:     [0.0, 0.0, 0.0]\n",
       "    pmax:     [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", " * vdims (vdims) Field\n", "
    \n", " \n", "
  • Mesh\n", "
      \n", "
    • Region\n", "
        \n", "
      • pmin = [0.0, 0.0, 0.0]
      • \n", "
      • pmax = [1e-08, 1e-08, 1e-08]
      • \n", "
      • dims = ['x', 'y', 'z']
      • \n", "
      • units = ['m', 'm', 'm']
      • \n", "
    • \n", "
    • n = [2, 2, 2]
    • \n", "
  • \n", "
  • nvdim = 3
  • \n", "
  • vdims:\n", "
    • x
    • \n", "
    • y
    • \n", "
    • z
    • \n", "
    \n", "
  • \n", "
" ], "text/plain": [ "Field(Mesh(Region(pmin=[0.0, 0.0, 0.0], pmax=[1e-08, 1e-08, 1e-08], dims=['x', 'y', 'z'], units=['m', 'm', 'm']), n=[2, 2, 2]), nvdim=3, vdims: (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`. Further, the input `xarray.DataArray` must have following properties in order to obtain a `discretisedfield.Field`:\n", "1. The attributes must have an `nvdim` entry equal to one for scalar fields and greater than one for vector fields. Further the value of `nvdim` must be an integer.\n", "2. There must be a dimension `vdims` if `nvdim` is greater than one.\n", "3. The coordinates of the geometric dimensions must be equally spaced.\n", "\n", "Lastly, **it is strongly advised that the input `xarray.DataArray` should have `pmin`, `pmax`, 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.10.12" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }