{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Shift\n\nThis example shows how to use the :py:class:`pylops.signalprocessing.Shift`\noperator to apply fractional delay to an input signal. Whilst this operator\nacts on 1D signals it can also be applied on any multi-dimensional signal on\na specific direction of it.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport pylops\n\nplt.close(\"all\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's start with a 1D example. Define the input parameters: number of samples\nof input signal (``nt``), sampling step (``dt``) as well as the input\nsignal which will be equal to a ricker wavelet:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nt = 127\ndt = 0.004\nt = np.arange(nt) * dt\nntwav = 41\n\nwav = pylops.utils.wavelets.ricker(t[:ntwav], f0=20)[0]\nwav = np.pad(wav, [0, nt - len(wav)])\nWAV = np.fft.rfft(wav, n=nt)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can shift this wavelet by $5.5\\mathrm{dt}$:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "shift = 5.5 * dt\nOp = pylops.signalprocessing.Shift(nt, shift, sampling=dt, real=True, dtype=np.float64)\nwavshift = Op * wav\nwavshiftback = Op.H * wavshift\n\nplt.figure(figsize=(10, 3))\nplt.plot(t, wav, \"k\", lw=2, label=\"Original\")\nplt.plot(t, wavshift, \"r\", lw=2, label=\"Shifted\")\nplt.plot(t, wavshiftback, \"--b\", lw=2, label=\"Adjoint\")\nplt.axvline(t[ntwav - 1], color=\"k\")\nplt.axvline(t[ntwav - 1] + shift, color=\"r\")\nplt.xlim(0, 0.3)\nplt.legend()\nplt.title(\"1D Shift\")\nplt.tight_layout()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can repeat the same exercise for a 2D signal and perform the shift\nalong the first and second dimensions.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "shift = 10.5 * dt\n\n# 1st axis\nwav2d = np.outer(wav, np.ones(10))\nOp = pylops.signalprocessing.Shift(\n    (nt, 10), shift, axis=0, sampling=dt, real=True, dtype=np.float64\n)\nwav2dshift = Op * wav2d\nwav2dshiftback = Op.H * wav2dshift\n\nfig, axs = plt.subplots(1, 3, figsize=(10, 3))\naxs[0].imshow(wav2d, cmap=\"gray\")\naxs[0].axis(\"tight\")\naxs[0].set_title(\"Original\")\naxs[1].imshow(wav2dshift, cmap=\"gray\")\naxs[1].set_title(\"Shifted\")\naxs[1].axis(\"tight\")\naxs[2].imshow(wav2dshiftback, cmap=\"gray\")\naxs[2].set_title(\"Adjoint\")\naxs[2].axis(\"tight\")\nfig.tight_layout()\n\n# 2nd axis\nwav2d = np.outer(wav, np.ones(10)).T\nOp = pylops.signalprocessing.Shift(\n    (10, nt), shift, axis=1, sampling=dt, real=True, dtype=np.float64\n)\nwav2dshift = Op * wav2d\nwav2dshiftback = Op.H * wav2dshift\n\nfig, axs = plt.subplots(1, 3, figsize=(10, 3))\naxs[0].imshow(wav2d, cmap=\"gray\")\naxs[0].axis(\"tight\")\naxs[0].set_title(\"Original\")\naxs[1].imshow(wav2dshift, cmap=\"gray\")\naxs[1].set_title(\"Shifted\")\naxs[1].axis(\"tight\")\naxs[2].imshow(wav2dshiftback, cmap=\"gray\")\naxs[2].set_title(\"Adjoint\")\naxs[2].axis(\"tight\")\nfig.tight_layout()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally we consider a more generic case where we apply a trace varying shift\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "shift = dt * np.arange(10)\n\nwav2d = np.outer(wav, np.ones(10))\nOp = pylops.signalprocessing.Shift(\n    (nt, 10), shift, axis=0, sampling=dt, real=True, dtype=np.float64\n)\nwav2dshift = Op * wav2d\nwav2dshiftback = Op.H * wav2dshift\n\nfig, axs = plt.subplots(1, 3, figsize=(10, 3))\naxs[0].imshow(wav2d, cmap=\"gray\")\naxs[0].axis(\"tight\")\naxs[0].set_title(\"Original\")\naxs[1].imshow(wav2dshift, cmap=\"gray\")\naxs[1].set_title(\"Shifted\")\naxs[1].axis(\"tight\")\naxs[2].imshow(wav2dshiftback, cmap=\"gray\")\naxs[2].set_title(\"Adjoint\")\naxs[2].axis(\"tight\")\nfig.tight_layout()"
      ]
    }
  ],
  "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.9.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}