{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "3e2afcda",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "083ab84b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "import numpy as np\nfrom scipy.signal import find_peaks, peak_prominences\nimport matplotlib.pyplot as plt",
            "outputs": []
        },
        {
            "id": "ec1f4b70",
            "cell_type": "markdown",
            "source": "Create a test signal with two overlaid harmonics\n",
            "metadata": {}
        },
        {
            "id": "fe558b85",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "x = np.linspace(0, 6 * np.pi, 1000)\nx = np.sin(x) + 0.6 * np.sin(2.6 * x)",
            "outputs": []
        },
        {
            "id": "29b42a3e",
            "cell_type": "markdown",
            "source": "Find all peaks and calculate prominences\n",
            "metadata": {}
        },
        {
            "id": "f8baa82d",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "peaks, _ = find_peaks(x)\nprominences = peak_prominences(x, peaks)[0]\nprominences",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([1.24159486, 0.47840168, 0.28470524, 3.10716793, 0.284603  ,\n       0.47822491, 2.48340261, 0.47822491])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "93985e68",
            "cell_type": "markdown",
            "source": "Calculate the height of each peak's contour line and plot the results\n",
            "metadata": {}
        },
        {
            "id": "6f905906",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "contour_heights = x[peaks] - prominences\nplt.plot(x)\nplt.plot(peaks, x[peaks], \"x\")\nplt.vlines(x=peaks, ymin=contour_heights, ymax=x[peaks])\nplt.show()",
            "outputs": []
        },
        {
            "id": "81bd1436",
            "cell_type": "markdown",
            "source": "Let's evaluate a second example that demonstrates several edge cases for\none peak at index 5.\n",
            "metadata": {}
        },
        {
            "id": "18157e78",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "x = np.array([0, 1, 0, 3, 1, 3, 0, 4, 0])\npeaks = np.array([5])\nplt.plot(x)\nplt.plot(peaks, x[peaks], \"x\")\nplt.show()",
            "outputs": []
        },
        {
            "id": "30ba7eb5",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "peak_prominences(x, peaks)  # -> (prominences, left_bases, right_bases)",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "(array([3.]), array([2]), array([6]))"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "47ae46de",
            "cell_type": "markdown",
            "source": "Note how the peak at index 3 of the same height is not considered as a\nborder while searching for the left base. Instead, two minima at 0 and 2\nare found in which case the one closer to the evaluated peak is always\nchosen. On the right side, however, the base must be placed at 6 because the\nhigher peak represents the right border to the evaluated area.\n",
            "metadata": {}
        },
        {
            "id": "c8d8fd0b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "peak_prominences(x, peaks, wlen=3.1)",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "(array([2.]), array([4]), array([6]))"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "d77db96b",
            "cell_type": "markdown",
            "source": "Here, we restricted the algorithm to a window from 3 to 7 (the length is 5\nsamples because `wlen` was rounded up to the next odd integer). Thus, the\nonly two candidates in the evaluated area are the two neighboring samples\nand a smaller prominence is calculated.\n",
            "metadata": {}
        }
    ]
}