{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "de91e174",
   "metadata": {},
   "source": [
    "# Traitement du Signal - Examen blanc : Partie Manipulation\n",
    "\n",
    "## Préambule de l'examen blanc\n",
    "\n",
    "L'examen pratique sera divisé en 2 parties, sur **2 Notebooks différents** :\n",
    "- Un exercice de manipulation : un exercice pas à pas où vous devez juste appliquer ce qu'on vous demande, et qui reprend une bonne partie de ce que vous avez vu durant les précédents TPs.\n",
    "- Un exercice de réflexion : un exercice où vous avez une problématique décrite, et c'est à vous de proposer et de justifier les bons outils permettant d'atteindre l'objectif demandé, tout en faisant une analyse critique de vos résultats obtenus.\n",
    "\n",
    "Avec ces deux exercices, vous avez quelques ressources supplémentaires :\n",
    "- un fichier *utils.py*, avec des fonctions développées durant les TPs qui ne sont pas disponibles dans les packages NumPy ou SciPy\n",
    "- un fichier *index* qui recense tous les noms des fonctions NumPy/SciPy que nous avons utilisé durant les précédents TPs (sans précision cependant sur leur fonctionnement)\n",
    "- Les documentations *Python / NumPy / Scipy / Matplotlib* disponibles via Firefox\n",
    "\n",
    "Chacun des notebooks de cet examen blanc décrira les modalités d'évaluations de chacune des parties"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "627a7516",
   "metadata": {},
   "source": [
    "## Préambule de l'exercice de manipulation\n",
    "\n",
    "L'exercice de manipulation a pour objectif d'évaluer vos capacités techniques en TDS (maîtrise en Python/NumPy/Matplotlib, connaissances des bases de TDS). Chaque manipulation demandée se fait pas à pas. A certains endroits, vous aurez :\n",
    "- des checkups : des cellules déjà écrites vérifiant que le résultat obtenu est correct (via la comparaison avec le résultat que vous devriez théoriquement obtenir)\n",
    "- des backups : des cellules permettant de charger le résultat que vous devriez normalement avoir, pour qu'un échec sur une question n'affecte pas la suite de l'exercice\n",
    "\n",
    "Les questions demandées ne sont globalement pas compliquées (vous avez déjà vu tout ce qui sera demandé durant le semestre en TP), mais le correcteur aura une vigilance accrue sur la **précision** des résultats obtenus/affichés. \n",
    "\n",
    "*Exemple: lorsque vous affichez un signal, si l'axe temporel/fréquentiel n'est pas défini en abcisses, vous perdrez bêtement des points*\n",
    "\n",
    "Vous n'avez pas besoin d'utiliser les fonctions disponibles dans le fichier *utils.py*.\n",
    "\n",
    "A vous de jouer, bon courage :D"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba61ec29",
   "metadata": {},
   "source": [
    "## Exercice de manipulation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6387966",
   "metadata": {},
   "source": [
    "**0)** Chargez les libraries nécessaires pour cet exercice : *NumPy* (**np**), *Scipy* et le sous-package *Pyplot* de *Matplotlib* (**plt**)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "72ad45ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Chargement des librairies Numpy (np), Scipy et Pyplot de Matplotlib (plt)\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import scipy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42ae01a9",
   "metadata": {},
   "source": [
    "**1)** Construisez un signal carré défini de la manière suivante:\n",
    "\n",
    "\\begin{equation*}\n",
    "    s(t) = \\begin{cases}\n",
    "                1 & \\text{si t} \\in [0,1[\\\\\n",
    "                0 & \\text{si t} \\in [1,2]\n",
    "                \\end{cases}\n",
    "\\end{equation*}\n",
    "\n",
    "Le signal sera défini pour $t$ allant de 0 à 2 secondes, avec un temps d'échantillonnage $T_e = 0.02$ secondes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21b03658",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création du signal carré\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d1dec5e",
   "metadata": {},
   "source": [
    "Affichez le signal $s(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c1d65f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du signal s(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e920d3a",
   "metadata": {},
   "source": [
    "**CHECKUP 1**\n",
    "\n",
    "**Exécutez la cellule ci-dessous pour vérifier votre résultat précédent**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc246223",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# CHECKUP 1\n",
    "\n",
    "def check_array_equal(a,b,signal_name):\n",
    "    # Vérification des tailles\n",
    "    assert a.shape == b.shape, (\n",
    "        f\"Erreur : {signal_name} n'est pas de la bonne taille \"\n",
    "        f\"{a.shape} != {b.shape}\"\n",
    "    )\n",
    "    # Vérification des valeurs\n",
    "    assert np.array_equal(a, b), (f\"Erreur : {signal_name} est incorrect :\\n\"\n",
    "                                f\"Ce que vous devriez obtenir : {b}\\n\"\n",
    "                                f\"Votre signal : {a}\\n\")\n",
    "\n",
    "# Mettez ici vos variables correspondant au signal et à son axe temporel\n",
    "s = ... # Signal s(t)\n",
    "t_s = ... # Axe temporel de s(t)\n",
    "\n",
    "backup_1_s = np.load(\"backup/1_s.npy\")\n",
    "backup_1_t_s = np.load(\"backup/1_t_s.npy\")\n",
    "\n",
    "check_array_equal(s,backup_1_s,\"le signal s\")\n",
    "check_array_equal(t_s,backup_1_t_s,\"l'axe temporel de s\")\n",
    "\n",
    "print(\"Checkup 1 validé\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc2752ae",
   "metadata": {},
   "source": [
    "**BACKUP 1**\n",
    "\n",
    "**Décommentez et exécutez la cellule ci-dessous si vous n'avez pas validez la cellule précédente**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7a069b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# BACKUP 1\n",
    "#s = np.load(\"backup/1_s.npy\")\n",
    "#t_s = np.load(\"backup/1_t_s.npy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e720f08",
   "metadata": {},
   "source": [
    "**2)** Créez le signal *h(t)*, une réponse impulsionnelle qui permettra ensuite de calculer $x(t) = s(t) \\ast h(t)$ tel que $x(t)$ soit un signal périodique évoluant durant 10 secondes avec une période de $s(t)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "17c16d4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création de h(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74765fce",
   "metadata": {},
   "source": [
    "Affichez le signal $h(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "290f192b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage de h(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43964cb8",
   "metadata": {},
   "source": [
    "**3)** Calculez maintenant $x(t) = s(t) \\ast h(t)$, ainsi que son axe temporel\n",
    "\n",
    "*Note : modifiez également x(t) afin qu'il évolue bien entre 0 et 10 secondes*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f800dcd9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Calcul de x(t)\n",
    "...\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "595d22db",
   "metadata": {},
   "source": [
    "Affichez le signal $x(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be080b49",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage de x(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c488f51",
   "metadata": {},
   "source": [
    "**CHECKUP 2**\n",
    "\n",
    "**Exécutez la cellule ci-dessous pour vérifier votre résultat précédent**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c1eb2ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# CHECKUP 2\n",
    "\n",
    "# Mettez ici vos variables correspondant au signal et à son axe temporel\n",
    "x = ... # Signal x(t)\n",
    "t_x = ... # Axe temporel de x(t)\n",
    "\n",
    "backup_2_x = np.load(\"backup/2_x.npy\")\n",
    "backup_2_t_x = np.load(\"backup/2_t_x.npy\")\n",
    "\n",
    "check_array_equal(x,backup_2_x,\"le signal x\")\n",
    "check_array_equal(t_x,backup_2_t_x,\"l'axe temporel de x\")\n",
    "\n",
    "print(\"Checkup 2 validé\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34baaaca",
   "metadata": {},
   "source": [
    "**BACKUP 2**\n",
    "\n",
    "**Décommentez et exécutez la cellule ci-dessous si vous n'avez pas validez la cellule précédente**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "06aa918d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# BACKUP 2\n",
    "#x = np.load(\"backup/2_x.npy\")\n",
    "#t_x = np.load(\"backup/2_t_x.npy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94f0ef3e",
   "metadata": {},
   "source": [
    "**4)** Calculez $X(f)$, la transformée de Fourier réelle de $x(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6f08031",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Transformée de Fourier réelle de x(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d71fb2d",
   "metadata": {},
   "source": [
    "Affichez le spectre d'amplitude de $X(f)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a3c1d56c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du spectre d'amplitude de X(f)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1aa1803",
   "metadata": {},
   "source": [
    "**5)** Effectuez un filtre passe-bas idéal sur $X(f)$ avec une fréquence de coupure $f_c$ = 15 Hz."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82f697e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Filtre passe-bas idéal de X(f)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf23737a",
   "metadata": {},
   "source": [
    "Affichez le spectre d'amplitude après application du filtre passe-bas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb1d7291",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du spectre d'amplitude après application du filtre passe-bas\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca37d0c7",
   "metadata": {},
   "source": [
    "**6)** Modifiez $X(f)$ afin que la fréquence d'échantillonnage du signal $f_e$ = 40 Hz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d253f40b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Modification de X(f) afin d'avoir une fréquence d'échantillonnage de 40 Hz\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c38f260c",
   "metadata": {},
   "source": [
    "Affichez le spectre d'amplitude après ré-échantillonnage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a14cf51c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du spectre d'amplitude après ré-échantillonnage\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03b3b859",
   "metadata": {},
   "source": [
    "**7)** Effectuez la transformée de Fourier réelle inverse pour obtenir votre nouveau signal $x(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "baffaa49",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Transformée de Fourier réelle inverse de X(f)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df408d96",
   "metadata": {},
   "source": [
    "Affichez le nouveau signal $x(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49bd1df7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage de x(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfa002b5",
   "metadata": {},
   "source": [
    "**CHECKUP 3**\n",
    "\n",
    "**Exécutez la cellule ci-dessous pour vérifier votre résultat précédent**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "713cd0cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# CHECKUP 3\n",
    "\n",
    "# Mettez ici vos variables correspondant au signal et à son axe temporel\n",
    "x = ... # Signal x(t)\n",
    "t_x = ... # Axe temporel de x(t)\n",
    "\n",
    "backup_3_x = np.load(\"backup/3_x.npy\")\n",
    "backup_3_t_x = np.load(\"backup/3_t_x.npy\")\n",
    "\n",
    "check_array_equal(x,backup_3_x,\"le signal x\")\n",
    "check_array_equal(t_x,backup_3_t_x,\"l'axe temporel de x\")\n",
    "\n",
    "print(\"Checkup 3 validé\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a447d5d1",
   "metadata": {},
   "source": [
    "**BACKUP 3**\n",
    "\n",
    "**Décommentez et exécutez la cellule ci-dessous si vous n'avez pas validez la cellule précédente**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b19f172",
   "metadata": {},
   "outputs": [],
   "source": [
    "# BACKUP 3\n",
    "#x = np.load(\"backup/3_x.npy\")\n",
    "#t_x = np.load(\"backup/3_t_x.npy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce708ca8",
   "metadata": {},
   "source": [
    "**8)** Créez un filtre de Butterworth passe-haut d'ordre 15 avec $f_{c}$ = 5 Hz et affichez les coefficients"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "856c833a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création d'un filtre de Butterworth passe-haut\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "942b78ab",
   "metadata": {},
   "source": [
    "Appliquez le filtre de Butterworth créé sur le signal $x(t)$ avec la fonction *scipy.signal.lfilter*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b61a4c10",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Application du filtre de Butterworth sur x(t)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fc1b1d1",
   "metadata": {},
   "source": [
    "Affichez le signal filtré"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ba613f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du signal filtré\n",
    "..."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "deep",
   "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.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
