{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8b364bbf-2aeb-43bb-b29f-3fc7620434d4",
   "metadata": {},
   "source": [
    "# Exercise Session 1: Getting Started with Python "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd82f787-bd3d-42c1-b977-ffe62a238c8c",
   "metadata": {},
   "source": [
    "The goals of this exercise are:\n",
    "* Getting started with Python\n",
    "* Getting familiar with the basic time-series manipulation functions\n",
    "* Implementing some simple real-world anomaly dection algorithms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "705b0495-e1b1-40d4-af13-9e9727097611",
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import librosa\n",
    "import librosa.display\n",
    "\n",
    "import scipy.stats as stats\n",
    "from scipy.stats import kurtosis\n",
    "from scipy.stats import skew\n",
    "\n",
    "from IPython.display import Audio\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "plt.rcParams['figure.figsize'] = (10, 3)\n",
    "plt.rcParams['image.cmap'] = 'gray'\n",
    "\n",
    "MACHINE =\"slider\" #fan or slider\n",
    "MACHINE_NAME = '_anomaly' # '_1' or '_2' or '_anomaly'\n",
    "REP =\"spec\" \n",
    "PATH = './'\n",
    "SR = 16000\n",
    "\n",
    "epsilon = 1e-6"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aea700f1-5f87-469f-ac19-f9cc5e604e53",
   "metadata": {},
   "source": [
    "## Exercise 1: Read and plot time-series"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "881124ab-1553-4390-a80f-ead599e1983a",
   "metadata": {},
   "source": [
    "Many real-word data are represented as time series. One intuitive example is Audio signal, defined by a specific sampling rate. \n",
    "\n",
    "* Read and display the sigal \"slider_1.wav\" or \"fan_1.wav\"  using e.g. function ```librosa.load()```.Visualize the results using ```plt.plot()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65722050-317f-4c52-bd1f-8a55b8cdce66",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function for reading an audio file \n",
    "def load_data(path,machine):\n",
    "    y = ...\n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be3d49d9-5c09-49c8-a1d8-7e68ca141f55",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_raw_signal(y,key):\n",
    "    Fs = 1 / SR # sampling frequency\n",
    "    t = np.arange(0, 10, Fs)\n",
    "\n",
    "    fig, axs = plt.subplots()\n",
    "    axs.set_title(f'Signal: {key}')\n",
    "    axs.plot(t, y, color='C0')\n",
    "    axs.set_xlabel(\"Time\")\n",
    "    axs.set_ylabel(\"Amplitude\")\n",
    "    plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "900d10c5-04eb-465a-8c62-7b98e381e940",
   "metadata": {},
   "outputs": [],
   "source": [
    "y = load_data(PATH,MACHINE+MACHINE_NAME)\n",
    "plot_raw_signal(y,MACHINE_NAME)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "83a2ed62-e8e1-42c4-b5b5-40b726e9f2d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "Audio(data=y,rate=SR)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09e06107-5890-4551-acfd-552436a7ec09",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Short Time Fourier Transform (STFT)\n",
    "\n",
    "Another represention of a time series can be on the Fourrier domain.\n",
    "(Reminder : The Fourier transform (FT) is a mathematical transform that decomposes functions depending on time into functions depending on temporal frequency)\n",
    "\n",
    "The Short Time Fourier Transform (STFT) is a method used to analyze the frequency content of signals that vary over time. Unlike the Fourier Transform, which provides a global representation of the signal in the frequency domain, the STFT offers a time-localized frequency representation. This attribute makes it particularly useful for examining non-stationary signals, where the frequency content changes over time.\n",
    "\n",
    "## Key Concepts of STFT\n",
    "\n",
    "- **Windowing:** The signal is multiplied by a window function (e.g., Hamming or Hanning window) of a certain length. This window is slid across the signal to produce overlapping segments, allowing the analysis of the signal in small chunks.\n",
    "  \n",
    "- **Fourier Transform:** For each windowed segment, the Fourier Transform is computed, yielding a frequency spectrum for that segment. This process is repeated across the signal to capture the varying frequency content over time.\n",
    "\n",
    "- **Time-Frequency Representation:** The result of the STFT is a 2D representation, where one axis represents time (based on the position of the window) and the other represents frequency. The magnitude or power of the result indicates the strength of each frequency component at each point in time.\n",
    "\n",
    "## Parameters\n",
    "\n",
    "1. **Window Length:** Determines the size of the window. A longer window provides better frequency resolution but poorer time resolution, and vice versa.\n",
    "   \n",
    "2. **Hop Length (or Overlap):** The amount by which the window is shifted for the next segment. A common practice is to have a 50% overlap between consecutive windows.\n",
    "\n",
    "3. **Window Function:** The shape of the window used to segment the signal. Common window functions include Hanning, Hamming, Blackman, etc. The choice of window affects the leakage and sidelobe properties of the resulting spectrum.\n",
    "\n",
    "## Computing STFT with `librosa`\n",
    "\n",
    "To compute the STFT using `librosa`, you can use the `librosa.stft()` function, which applies these principles and returns the time-frequency representation of the signal.\n",
    "\n",
    "* Compute the short time fourier transform of \"y\" using e.g. function ```librosa.stft()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "603547ea-9b9f-47ea-9608-44d59af28868",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function for ploting the Spectrogram using the short fourier transform of an audio file \n",
    "def plot_spectrogram(y,key, n_fft=1600, hop_length=1600):\n",
    "    x = ...\n",
    "    fig, axs = plt.subplots()\n",
    "    librosa.display.specshow(20*np.log10(np.abs(x)+epsilon),sr=SR,hop_length=hop_length,x_axis=\"time\",y_axis=\"linear\",ax=axs)\n",
    "    axs.set_title(f'Spectrogram: {key}')\n",
    "    plt.show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd12a0ef-cff4-4d6a-b786-d9c2206a7a58",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_spectrogram(y,MACHINE_NAME)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d28b1dce-74a7-4e81-ab76-039f561b2aaa",
   "metadata": {},
   "source": [
    "# Mel Spectrogram Representation\n",
    "\n",
    "Another representation of a time series in the Fourier domain is through the Mel spectrogram representation. This visual representation of the frequency content of a signal varies with time, but it incorporates the Mel scale, a perceptual scale of pitches that approximates the human ear's response to different frequencies.\n",
    "\n",
    "## Mel Scale\n",
    "\n",
    "The human ear perceives frequencies in a non-linear manner, with a greater resolution at lower frequencies than at higher frequencies. The Mel scale was developed to mimic this perceptual characteristic, making it particularly useful for audio analysis and processing tasks where human hearing perception is relevant.\n",
    "\n",
    "## Mel Spectrogram\n",
    "\n",
    "To compute a Mel spectrogram, you start by calculating the spectrogram of a signal. Then, the frequencies of this spectrogram are grouped into Mel frequency bands. This grouping effectively warps the frequency scale to align more closely with human hearing.\n",
    "\n",
    "## Computing Mel Spectrogram with `librosa`\n",
    "\n",
    "The `librosa.feature.melspectrogram()` function is used to compute the Mel spectrogram of an audio signal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c2184f1b-e02c-4114-85ad-1083594ee5fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function for ploting the MEL-Spectrogram \n",
    "def plot_mel_spectrogram(y,key, n_fft=1600, hop_length=1600):\n",
    "    x = ... \n",
    "    fig, axs = plt.subplots()\n",
    "    librosa.display.specshow(20*np.log10(np.abs(x)+epsilon),sr=SR,hop_length=hop_length,x_axis=\"time\",y_axis=\"mel\",ax=axs)\n",
    "    axs.set_title(f'Mel-Spectrogram: {key}')\n",
    "    plt.show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad00d641-d2ee-41a3-a7fc-094cd482d67d",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_mel_spectrogram(y,MACHINE_NAME)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67e18d69-2da7-48ab-846c-e8b2291694d1",
   "metadata": {},
   "source": [
    "## Exercise 2: Compute some statistics of the signal"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbb3ff7a-edb8-46f5-892d-4801e7cc2c25",
   "metadata": {},
   "source": [
    "A signal can be summarize by some statistical moments. These set of features could be usefull for machine-learning."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62f2924f-65ad-45c2-adab-32dfb11f3dbf",
   "metadata": {},
   "source": [
    "* Computer the mean of \"y\" using e.g. function ```np.mean()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "582d62cf-0897-47e7-b29c-946640705c8b",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function to return the mean of the signal\n",
    "def mean_signal(y):\n",
    "    mean = ...\n",
    "    return mean"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d35e5d65-c71f-4fda-9eef-9fc3bd65d2c7",
   "metadata": {},
   "source": [
    "* Computer the standard-deviation of \"y\" using e.g. function ```np.std()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db9d3db2-b1d3-40f3-82e9-bdb87d9e9619",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function to return the mean of the signal\n",
    "def std_signal(y):\n",
    "    std = ...\n",
    "    return std"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9cdbbed-5d06-4c19-89b2-5346a6f8a89a",
   "metadata": {},
   "source": [
    "* Computer the pic to pic variation of \"y\" using e.g. function ```np.min()```  and ```np.max()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbdeb1a0-bcfb-4114-99dc-0e66dcc481b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function to get the distance between the min and max value of the signal\n",
    "def pic_2_pic_signal(y):\n",
    "    min_value = ...\n",
    "    max_value = ...\n",
    "    pic_2_pic = ...\n",
    "    return pic_2_pic"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c9d43f5-297a-4fda-aa7b-6ce23f8abc7b",
   "metadata": {},
   "source": [
    "* Computer the third moment of \"y\" using e.g. function ```scipy.stats.skew()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10de2f8d-a32e-4eb7-86d3-5c47cfeff382",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function to return the third moment of the signal\n",
    "def asymetry_signal(y):\n",
    "    asymetry = ...\n",
    "    return asymetry"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "776b9fb6-f4e5-4290-b92e-c30bc93658cf",
   "metadata": {},
   "source": [
    "* Computer the fourth moment of \"y\" using e.g. function ```scipy.stats.kurtosis()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3e57e5c3-57d4-4755-b6b7-ec1a52814198",
   "metadata": {},
   "outputs": [],
   "source": [
    "##complete the function to return the fourth moment of the signal\n",
    "def kurtosis_signal(y):\n",
    "    kurt = ...\n",
    "    return kurt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b345582-ca11-45a1-86a6-26348609e257",
   "metadata": {},
   "source": [
    "* Computer and plot the histogram of \"y\" using e.g. function ```plt.hist()``` function.</li>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffa41a14-d24b-493d-a8e1-e7f621c92b48",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_hist_signal(y,key):\n",
    "    fig, axs = plt.subplots()\n",
    "    axs.set_title(f'Histogram: {key}')\n",
    "    ...\n",
    "    axs.set_xlabel(\"Bins\")\n",
    "    axs.set_ylabel(\"Count\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "138b7ec4-fff1-48da-bd9f-2972151b473b",
   "metadata": {},
   "source": [
    "## Exercise 3: Connected Components"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0c20562-5a6f-442e-82ca-3f4d4e06b3a7",
   "metadata": {},
   "source": [
    "Computing some statistical moments of a signal is also often a first step for the further analysis. Here our goal is to compute the different sifnal properties in order to distinguish the normal signals from abnormal signal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf0fc92d-b4d6-4249-8f65-0ff341acf189",
   "metadata": {},
   "outputs": [],
   "source": [
    "data =  {\"1\":load_data(PATH,MACHINE+'_1'),\"2\":load_data(PATH,MACHINE+'_2'),\n",
    "              \"anomaly\":load_data(PATH,MACHINE+'_anomaly')}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fe3c6dc-e9dc-4595-ad00-5a91a8037593",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    plot_raw_signal(data[key],key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0019dfc1-3c75-4985-b7c1-9ebb7bdc9ff3",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    plot_spectrogram(data[key],key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e0fac8dd-75c8-44e6-9bbe-93c74a547ffd",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    plot_mel_spectrogram(data[key],key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "630a2da1-2fcb-4b13-bf5e-31da45c424a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    print(f'Mean signal_{key}')\n",
    "    print(mean_signal(data[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "611707b5-bb62-4a0a-8bcd-d9d2235f8c15",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    print(f'Std signal_{key}')\n",
    "    print(std_signal(data[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9abaa98e-181f-4d1f-a0b8-16c2a80e08a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    print(f'Pic to pic signal_{key}')\n",
    "    print(pic_2_pic_signal(data[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a69edc1d-517e-470a-8e4c-d95f4e96dee1",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    print(f'Kurtosis signal_{key}')\n",
    "    print(kurtosis_signal(data[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "684b814a-b21b-4259-bdc7-e923ce4f30b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    print(f'Asymetry signal_{key}')\n",
    "    print(asymetry_signal(data[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43be4fb4-0eb6-4293-bd06-572b8c618b5f",
   "metadata": {},
   "outputs": [],
   "source": [
    "for key in (data.keys()):\n",
    "    plot_hist_signal(data[key],key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cad813b2-1ff1-487d-9c1e-191e216e4821",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
