{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ipfml import processing\n",
    "from ipfml import utils\n",
    "from ipfml import metrics\n",
    "from PIL import Image\n",
    "from scipy import signal\n",
    "from skimage import color\n",
    "import scipy.stats as stats\n",
    "import seaborn as sns\n",
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "\n",
    "from sklearn.decomposition import FastICA\n",
    "\n",
    "from pylab import *\n",
    "from skimage import data, io, color"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_folder = \"../fichiersSVD_light\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SVD Scene analysis on Synthesis Images "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Utils functions definition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_images_path(dict_data):\n",
    "    \n",
    "    all_images_path = []\n",
    "    for cur_dict in dict_data:\n",
    "        scene = cur_dict['name']\n",
    "        prefix = cur_dict['prefix']\n",
    "        indices = cur_dict['indices']\n",
    "\n",
    "        scene_images_path = []\n",
    "        for index in indices:\n",
    "            path = os.path.join(data_folder, os.path.join(scene, prefix + index + \".png\"))\n",
    "            scene_images_path.append(path)\n",
    "            \n",
    "        all_images_path.append(scene_images_path)\n",
    "            \n",
    "    return all_images_path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def display_sv_data(dict_data, interval, all_images_path):\n",
    "    \n",
    "    sv_values = []\n",
    "    plt.figure(figsize=(25, 20))\n",
    "    begin, end = interval\n",
    "    \n",
    "    for id_dict, cur_dict in enumerate(dict_data):\n",
    "        \n",
    "        scene_name = cur_dict['name']\n",
    "        image_indices = cur_dict['indices']\n",
    "        scene_sv_values = []\n",
    "    \n",
    "        for id_img, img_path in enumerate(all_images_path[id_dict]):\n",
    "            img = Image.open(img_path)\n",
    "            print(img_path)\n",
    "            \n",
    "            blocks = processing.divide_in_blocks(img, (200, 200))\n",
    "            block = np.array(blocks[0])\n",
    "            \n",
    "            if block.ndim == 3:\n",
    "                U, s, V = processing.get_LAB_L_SVD(block)\n",
    "            else:\n",
    "                U, s, V = metrics.get_SVD(block)\n",
    "                \n",
    "            data = s[begin:end]\n",
    "            plt.plot(data, label=scene_name + '_' + str(image_indices[id_img]))\n",
    "            scene_sv_values.append(data)\n",
    "            \n",
    "        sv_values.append(scene_sv_values)\n",
    "\n",
    "    plt.legend(fontsize=18)\n",
    "    plt.show()\n",
    "    return sv_values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Scenes zones data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# start 00020 - ref 00900 - step 10\n",
    "dict_appart = {'name': 'Appart1opt02', \n",
    "               'prefix': 'appartAopt_', \n",
    "               'indices': [\"00020\", \"00200\", \"00900\"]}\n",
    "\n",
    "# start 00050 - ref 01200 - step 10\n",
    "dict_cuisine = {'name': 'Cuisine01', \n",
    "               'prefix': 'cuisine01_', \n",
    "               'indices': [\"00050\", \"00400\", \"01200\"]}\n",
    "\n",
    "# start 00020 - ref 00950 - step 10\n",
    "dict_sdb_c = {'name': 'SdbCentre', \n",
    "               'prefix': 'SdB2_', \n",
    "               'indices': [\"00020\", \"00400\", \"00950\"]}\n",
    "\n",
    "# start 00020 - ref 00950 - step 10\n",
    "dict_sdb_d = {'name': 'SdbDroite', \n",
    "               'prefix': 'SdB2_D_', \n",
    "               'indices': [\"00020\", \"00400\", \"00950\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_dicts = [dict_appart, dict_cuisine, dict_sdb_c, dict_sdb_d]\n",
    "interval = (30, 200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "../fichiersSVD_light/Appart1opt02/appartAopt_00020.png\n",
      "../fichiersSVD_light/Appart1opt02/appartAopt_00200.png\n",
      "../fichiersSVD_light/Appart1opt02/appartAopt_00900.png\n",
      "../fichiersSVD_light/Cuisine01/cuisine01_00050.png\n",
      "../fichiersSVD_light/Cuisine01/cuisine01_00400.png\n",
      "../fichiersSVD_light/Cuisine01/cuisine01_01200.png\n",
      "../fichiersSVD_light/SdbCentre/SdB2_00020.png\n",
      "../fichiersSVD_light/SdbCentre/SdB2_00400.png\n",
      "../fichiersSVD_light/SdbCentre/SdB2_00950.png\n",
      "../fichiersSVD_light/SdbDroite/SdB2_D_00020.png\n",
      "../fichiersSVD_light/SdbDroite/SdB2_D_00400.png\n",
      "../fichiersSVD_light/SdbDroite/SdB2_D_00950.png\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 265000 characters]\n",
      "text/plain": [
       "<Figure size 1800x1440 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_images_path = compute_images_path(all_dicts)\n",
    "sv_values = display_sv_data(all_dicts, interval, all_images_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Use of ICA dimension reduction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-16-6bff981aaad2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     18\u001b[0m         \u001b[0mica_end\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mFastICA\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_components\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m150\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     19\u001b[0m         \u001b[0;31m# run ICA on image\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m         \u001b[0mica_end\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcurrent_image\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     21\u001b[0m         \u001b[0;31m# reconstruct image with independent components\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     22\u001b[0m         \u001b[0mimage_ica_end\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mica\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_transform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcurrent_image\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.pyenv/versions/thesis-venv/lib/python3.6/site-packages/sklearn/decomposition/fastica_.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, X, y)\u001b[0m\n\u001b[1;32m    551\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    552\u001b[0m         \"\"\"\n\u001b[0;32m--> 553\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcompute_sources\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    554\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    555\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.pyenv/versions/thesis-venv/lib/python3.6/site-packages/sklearn/decomposition/fastica_.py\u001b[0m in \u001b[0;36m_fit\u001b[0;34m(self, X, compute_sources)\u001b[0m\n\u001b[1;32m    503\u001b[0m             \u001b[0mmax_iter\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax_iter\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtol\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtol\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mw_init\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mw_init\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    504\u001b[0m             \u001b[0mrandom_state\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandom_state\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreturn_X_mean\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 505\u001b[0;31m             compute_sources=compute_sources, return_n_iter=True)\n\u001b[0m\u001b[1;32m    506\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    507\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwhiten\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.pyenv/versions/thesis-venv/lib/python3.6/site-packages/sklearn/decomposition/fastica_.py\u001b[0m in \u001b[0;36mfastica\u001b[0;34m(X, n_components, algorithm, whiten, fun, fun_args, max_iter, tol, w_init, random_state, return_X_mean, compute_sources, return_n_iter)\u001b[0m\n\u001b[1;32m    342\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    343\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0malgorithm\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'parallel'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 344\u001b[0;31m         \u001b[0mW\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_ica_par\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    345\u001b[0m     \u001b[0;32melif\u001b[0m \u001b[0malgorithm\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'deflation'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    346\u001b[0m         \u001b[0mW\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_ica_def\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.pyenv/versions/thesis-venv/lib/python3.6/site-packages/sklearn/decomposition/fastica_.py\u001b[0m in \u001b[0;36m_ica_par\u001b[0;34m(***failed resolving arguments***)\u001b[0m\n\u001b[1;32m    107\u001b[0m     \u001b[0mp_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    108\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mii\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mmoves\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmax_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 109\u001b[0;31m         \u001b[0mgwtx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg_wtx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mW\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfun_args\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    110\u001b[0m         W1 = _sym_decorrelation(np.dot(gwtx, X.T) / p_\n\u001b[1;32m    111\u001b[0m                                 - g_wtx[:, np.newaxis] * W)\n",
      "\u001b[0;32m~/.pyenv/versions/thesis-venv/lib/python3.6/site-packages/sklearn/decomposition/fastica_.py\u001b[0m in \u001b[0;36m_logcosh\u001b[0;34m(x, fun_args)\u001b[0m\n\u001b[1;32m    134\u001b[0m     \u001b[0;31m# XXX compute in chunks to avoid extra allocation\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    135\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgx_i\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m  \u001b[0;31m# please don't vectorize.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 136\u001b[0;31m         \u001b[0mg_x\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0malpha\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mgx_i\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    137\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mgx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg_x\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    138\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "all_ica_images_path = []\n",
    "\n",
    "for scene_path in all_images_path:\n",
    "    \n",
    "    scene_images_path = []\n",
    "\n",
    "    for sample_level_path in scene_path:\n",
    "        current_image = io.imread(sample_level_path)\n",
    "        current_image = metrics.get_LAB_L(current_image)\n",
    "       \n",
    "        ica = FastICA(n_components = 50)\n",
    "        # run ICA on image\n",
    "        ica.fit(current_image)\n",
    "        # reconstruct image with independent components\n",
    "        image_ica = ica.fit_transform(current_image)\n",
    "        image_restored = ica.inverse_transform(image_ica)\n",
    "        \n",
    "        ica_end = FastICA(n_components = 150)\n",
    "        # run ICA on image\n",
    "        ica_end.fit(current_image)\n",
    "        # reconstruct image with independent components\n",
    "        image_ica_end = ica.fit_transform(current_image)\n",
    "        image_restored_end = ica.inverse_transform(image_ica_end)\n",
    "        \n",
    "        Image.fromarray(np.array(image_restored_end - image_restored, 'uint8')).show()\n",
    "            \n",
    "        # show image to screen\n",
    "        final_image = utils.normalize_2D_arr(image_restored)\n",
    "        \n",
    "        img_saved_path = \"tmp_images/ica_\" + sample_level_path.split('/')[-1]\n",
    "        \n",
    "        Image.fromarray(np.array(final_image * 255, 'uint8')).save(img_saved_path)\n",
    "        scene_images_path.append(img_saved_path)\n",
    "            \n",
    "    all_ica_images_path.append(scene_images_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tmp_images/ica_appartAopt_00020.png\n",
      "tmp_images/ica_appartAopt_00200.png\n",
      "tmp_images/ica_appartAopt_00900.png\n",
      "tmp_images/ica_cuisine01_00050.png\n",
      "tmp_images/ica_cuisine01_00400.png\n",
      "tmp_images/ica_cuisine01_01200.png\n",
      "tmp_images/ica_SdB2_00020.png\n",
      "tmp_images/ica_SdB2_00400.png\n",
      "tmp_images/ica_SdB2_00950.png\n",
      "tmp_images/ica_SdB2_D_00020.png\n",
      "tmp_images/ica_SdB2_D_00400.png\n",
      "tmp_images/ica_SdB2_D_00950.png\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 178320 characters]\n",
      "text/plain": [
       "<Figure size 1800x1440 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sv_ica_values = display_sv_data(all_dicts, interval, all_ica_images_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Essayer de garder uniquement les composantes faibles et comparer avec ICA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 450988 characters]\n",
      "text/plain": [
       "<Figure size 1800x1440 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "final_sv_values = []\n",
    "\n",
    "plt.figure(figsize=(25, 20))\n",
    "interval = (30, 170)\n",
    "begin, end = interval\n",
    "\n",
    "for id_dict, cur_dict in enumerate(all_dicts):\n",
    "\n",
    "    scene_name = cur_dict['name']\n",
    "    image_indices = cur_dict['indices']\n",
    "    scene_sv_values = []\n",
    "\n",
    "    for id_img, img_path in enumerate(all_images_path[id_dict]):\n",
    "        \n",
    "        sv_norm = utils.normalize_arr(sv_values[id_dict][id_img][begin:end])\n",
    "        sv_ica_norm = utils.normalize_arr(sv_ica_values[id_dict][id_img][begin:end])\n",
    "\n",
    "        diff = abs(np.array(sv_norm) - np.array(sv_ica_norm))\n",
    "        \n",
    "        plt.plot(diff, label=scene_name + '_' + str(image_indices[id_img]))\n",
    "        scene_sv_values.append(data)\n",
    "\n",
    "    sv_values.append(scene_sv_values)\n",
    "\n",
    "plt.legend(fontsize=18)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "thesis-venv",
   "language": "python",
   "name": "thesis-venv"
  },
  "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.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
