{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nHow to use Xarray accessor\n==========================\n\nThis example shows how to use the SpatialData accessor to extend the\ncapabilities of xarray.\n\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "To extend xarray.DataArray you need only to load also pymepps with\n\"import pymepps\". The extensions could be used with the property\nxarray.DataArray.pp\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport xarray as xr\nimport pymepps"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "To use the full power of pymepps, you have to set a grid. If you load\nthe data with the xarray functions you have to set the grid afterwards.\nSo the next step is to load a NetCDF model file with xarray. There are\nalso pymepps functions to load model data. These are shown in another\nexample.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "ds = xr.open_dataset('../data/model/GFS_Global_0p25deg_20161219_0600.nc')\nt2m_max = ds['Maximum_temperature_height_above_ground_Mixed_intervals_Maximum']\nprint(t2m_max)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The grid definition is inspired by the climate data operators. So you\ncould either generate your own grid (done in this example), or you could\nload a cdo-conform grid file.\n\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We could see that the grid is a structured latitude and longitude grid\nwith a resolution of 0.25 degree.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "grid_dict = dict(\n    gridtype='lonlat',\n    xsize=t2m_max['lon'].size,\n    ysize=t2m_max['lat'].size,\n    xfirst=t2m_max['lon'].values[0],\n    xinc=0.25,\n    yfirst=t2m_max['lat'].values[0],\n    yinc=-0.25,\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We created our grid dict with the information. Now we have to build the\ngrid. In pymepps you could use the GridBuilder to build the grid with\ngiven grid\\_dict.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "builder = pymepps.GridBuilder(grid_dict)\ngrid = builder.build_grid()\nprint(grid)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The next step is to set the grid for our dataset. For this we could use\nthe set\\_grid method of the SpatialAccessor.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t2m_max = t2m_max.pp.set_grid(grid)\nprint(t2m_max.pp.grid)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now we set the grid. It is also possible to normalize the coordinates to\nallow a consistent processing of the model data.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Before normalization\nprint('Before:\\n{0:s}\\n'.format(str(t2m_max)))\n\nt2m_max = t2m_max.pp.normalize_coords()\n# After normalization\nprint('After:\\n{0:s}'.format(str(t2m_max)))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We could see that the height\\_above\\_ground and the time variable are\nrenamed to a more common name. The ensemble member is set to the default\nvalue 'det', while the runtime is set to the missing value None. Now\nlets plot the data with the xarray internal plot method.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t2m_max.plot()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Lets make use of the SpatialAccessor to slice an area over germany. We\nwould also transform the temperature unit to degree celsius. For this we\ncould use the normal xarray.DataArray mathematical operations. After the\ntransformation lets plot the temperature.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# sphinx_gallery_thumbnail_number = 2\nger_t2m_max = t2m_max.pp.sellonlatbox([5, 55, 15, 45])\n# K to deg C\nger_t2m_max -= 273.15\nger_t2m_max.plot()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "If we use a xarray.DataArray method where the DataArray instance is\ncopied, we have to set a new grid. This behaviour coud seen in the\nfollowing code block.\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "stacked_array = t2m_max.stack(stacked=('runtime', 'validtime'))\n# we have to catch the error for sphinx documentation\ntry:\n    print(stacked_array.pp.grid)\nexcept TypeError:\n    print('This DataArray has no grid defined!')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This seen behavior arises from the fact that the grid is depending on\nthe grid coordinates of the DataArray and they could be changed with a\nxarray.DataArray method.\n\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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.6.1"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}