{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# PPG pipeline\n\n<div class=\"alert alert-danger\"><h4>Warning</h4><p>Include code to show how to create a pipeline to\n             clean an ecg signal. It is probably in one of the\n             jupyter notebooks (maybe ecg_qc.ipynb).</p></div>\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Load the data\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# First, lets load the data (ppg sample data)\n\n# Libraries\nimport pandas as pd\n\n# Load data\n#data = pd.read_csv(path)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Preprocessing\n\nWearable devices need some time to pick up stable signals. For this reason,\nit is a common practice to trim the data. In the following example, the f\nfirst and last 5 minutes of each recording are trimmed to exclude unstable\nsignals.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Trim data\n#data = trim(data, start=5, end=5)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now, lets remove the following noise:\n\n  - ``PLETH`` is 0 or unchanged values for xxx time\n  - ``SpO2`` < 80\n  - ``Pulse`` > 200 bpm or ``Pulse`` < 40 bpm\n  - ``Perfusion`` < 0.2\n  - ``Lost connection``: sampling rate reduced due to (possible) Bluetooth connection\n    lost. Timestamp column shows missing timepoints. If the missing duration is\n    larger than 1 cycle (xxx ms), recording is split. If not, missing timepoints\n    are interpolated.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Remove invalid PLETH\n#idxs_1 = data.PLETH == 0\n#idxs_2 = unchanged(period=xxxx)\n#data = data[~(idxs_1 | idxs_2)]\n\n# Remove invalid ranges\n#data = data[data.SpO2>=80]\n#data = data[data.Pulse.between(40, 200)]\n#data = data[data.Perfusion>=0.2]\n\n# Remove lost connection\n#data = data[lost_connection(min_fs, max_fs) ??\n\n# The recording is then split into files."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Lets filter the data with a band pass filter; high pass filter (cut off at 1Hz)\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Lets detrend the signal\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Lets split the data\n#4.1. Cut data by time domain. Split data into sub segments of 30 seconds\n#4.2. Apply the peak and trough detection methods in peak_approaches.py to get single PPG cycles in each segment\n#4.3. Shift baseline above 0 and tapering each single PPG cycle to compute the mean template\n#Notes: the described process is implemented in split_to_segments.py"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## SQI scores\n\nLets compute the SQI scores\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Visualization\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Final notes\nInitially, it might have a lot of code. If the library\ngrows, as Stefan mentioned it might be possible to\ncreate a generalised pipeline from sub-methods or\nclasses. Or allow the user to configure the process\nand then automate all the run.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Create steps\n#step1 = Trim(start=5, end=5)\n#step2 = Unchanged(param1=x, param2=y)\n#step3 = LostConnection(param1=20, param2=30)\n\n# Create pipeline\n#pipe = Pipeline(steps=[('step1', step1),\n#                       ('step2', step2),\n#                       ('step3', step3))\n\n# Data\n#data = pipe.fit_transform(data)"
      ]
    }
  ],
  "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.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}