{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Optical flow\n\nThis tutorial offers a short overview of the optical flow routines available in \npysteps and it will cover how to compute and plot the motion field from a \nsequence of radar images.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from datetime import datetime\nfrom pprint import pprint\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom pysteps import io, motion, rcparams\nfrom pysteps.utils import conversion, transformation\nfrom pysteps.visualization import plot_precip_field, quiver"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Read the radar input images\n\nFirst, we will import the sequence of radar composites.\nYou need the pysteps-data archive downloaded and the pystepsrc file\nconfigured with the data_source paths pointing to data folders.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Selected case\ndate = datetime.strptime(\"201505151630\", \"%Y%m%d%H%M\")\ndata_source = rcparams.data_sources[\"mch\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Load the data from the archive\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "root_path = data_source[\"root_path\"]\npath_fmt = data_source[\"path_fmt\"]\nfn_pattern = data_source[\"fn_pattern\"]\nfn_ext = data_source[\"fn_ext\"]\nimporter_name = data_source[\"importer\"]\nimporter_kwargs = data_source[\"importer_kwargs\"]\ntimestep = data_source[\"timestep\"]\n\n# Find the input files from the archive\nfns = io.archive.find_by_date(\n    date, root_path, path_fmt, fn_pattern, fn_ext, timestep=5, num_prev_files=9\n)\n\n# Read the radar composites\nimporter = io.get_method(importer_name, \"importer\")\nR, quality, metadata = io.read_timeseries(fns, importer, **importer_kwargs)\n\ndel quality  # Not used"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Preprocess the data\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Convert to mm/h\nR, metadata = conversion.to_rainrate(R, metadata)\n\n# Store the reference frame\nR_ = R[-1, :, :].copy()\n\n# Log-transform the data [dBR]\nR, metadata = transformation.dB_transform(R, metadata, threshold=0.1, zerovalue=-15.0)\n\n# Nicely print the metadata\npprint(metadata)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Lucas-Kanade (LK)\n\nThe Lucas-Kanade optical flow method implemented in pysteps is a local\ntracking approach that relies on the OpenCV package.\nLocal features are tracked in a sequence of two or more radar images. The\nscheme includes a final interpolation step in order to produce a smooth\nfield of motion vectors.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "oflow_method = motion.get_method(\"LK\")\nV1 = oflow_method(R[-3:, :, :])\n\n# Plot the motion field on top of the reference frame\nplot_precip_field(R_, geodata=metadata, title=\"LK\")\nquiver(V1, geodata=metadata, step=25)\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Variational echo tracking (VET)\n\nThis module implements the VET algorithm presented\nby Laroche and Zawadzki (1995) and used in the McGill Algorithm for\nPrediction by Lagrangian Extrapolation (MAPLE) described in\nGermann and Zawadzki (2002).\nThe approach essentially consists of a global optimization routine that seeks\nat minimizing a cost function between the displaced and the reference image.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "oflow_method = motion.get_method(\"VET\")\nV2 = oflow_method(R[-3:, :, :])\n\n# Plot the motion field\nplot_precip_field(R_, geodata=metadata, title=\"VET\")\nquiver(V2, geodata=metadata, step=25)\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Dynamic and adaptive radar tracking of storms (DARTS)\n\nDARTS uses a spectral approach to optical flow that is based on the discrete\nFourier transform (DFT) of a temporal sequence of radar fields.\nThe level of truncation of the DFT coefficients controls the degree of\nsmoothness of the estimated motion field, allowing for an efficient\nmotion estimation. DARTS requires a longer sequence of radar fields for\nestimating the motion, here we are going to use all the available 10 fields.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "oflow_method = motion.get_method(\"DARTS\")\nR[~np.isfinite(R)] = metadata[\"zerovalue\"]\nV3 = oflow_method(R)  # needs longer training sequence\n\n# Plot the motion field\nplot_precip_field(R_, geodata=metadata, title=\"DARTS\")\nquiver(V3, geodata=metadata, step=25)\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Anisotropic diffusion method (Proesmans et al 1994)\n\nThis module implements the anisotropic diffusion method presented in Proesmans\net al. (1994), a robust optical flow technique which employs the notion of\ninconsitency during the solution of the optical flow equations.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "oflow_method = motion.get_method(\"proesmans\")\nR[~np.isfinite(R)] = metadata[\"zerovalue\"]\nV4 = oflow_method(R[-2:, :, :])\n\n# Plot the motion field\nplot_precip_field(R_, geodata=metadata, title=\"Proesmans\")\nquiver(V4, geodata=metadata, step=25)\nplt.show()\n\n# sphinx_gallery_thumbnail_number = 1"
      ]
    }
  ],
  "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.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}