{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55633802",
   "metadata": {},
   "outputs": [],
   "source": [
    "import h5py\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "from matplotlib.patches import Rectangle\n",
    "from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n",
    "\n",
    "import vbn_utils\n",
    "import decoding_utils as du\n",
    "from analysis_utils import exponential_convolve\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7360610b",
   "metadata": {},
   "source": [
    "## Data loading"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1af58383",
   "metadata": {},
   "outputs": [],
   "source": [
    "#Paths to all of the useful supplemental tables and tensors\n",
    "active_tensor_file = \"/Volumes/programs/mindscope/workgroups/np-behavior/vbn_data_release/supplemental_tables/vbnAllUnitSpikeTensor.hdf5\"\n",
    "\n",
    "stim_table_file = \"/Volumes/programs/mindscope/workgroups/np-behavior/vbn_data_release/supplemental_tables/master_stim_table_no_filter.csv\"\n",
    "unit_table_file = \"/Volumes/programs/mindscope/workgroups/np-behavior/vbn_data_release/supplemental_tables/master_units_with_responsiveness.csv\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f82e1604",
   "metadata": {},
   "outputs": [],
   "source": [
    "units = pd.read_csv(unit_table_file)\n",
    "units['cortical_layer'] = units['cortical_layer'].replace('3-Feb','2/3') # 2/3 sometimes gets incorrectly reformatted as a date\n",
    "\n",
    "stim_table = pd.read_csv(stim_table_file)\n",
    "stim_table = stim_table.drop(columns='Unnamed: 0')\n",
    "\n",
    "active_tensor = h5py.File(active_tensor_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a4d1adb",
   "metadata": {},
   "outputs": [],
   "source": [
    "structure_tree = pd.read_csv(\"/Volumes/programs/mindscope/workgroups/np-behavior/vbn_data_release/supplemental_tables/ccf_structure_tree_2017.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da17ee74",
   "metadata": {},
   "source": [
    "## Omission responses by cluster, cell type, and layer"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc2d3edc",
   "metadata": {},
   "source": [
    "### By cluster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1bacec57",
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "def plot_omission_psth_by_group(values, filter_kwargs_fn, title_fn,\n",
    "                                inset_loc_fn=None, ylim_fn=None):\n",
    "    fig, axes = plt.subplots(len(values), 1)\n",
    "    fig.set_size_inches(7, 2.5 * len(values))\n",
    "    session_list = list(active_tensor.keys())\n",
    "    time = np.arange(-750, 750, 1)\n",
    "\n",
    "    for ax, value in zip(np.atleast_1d(axes), values):\n",
    "        unit_ids = vbn_utils.get_unit_ids(\n",
    "            units, 'VISall', clustering='new', **filter_kwargs_fn(value)\n",
    "        )\n",
    "\n",
    "        omission_responses, _ = vbn_utils.unit_averaged_psth(\n",
    "            active_tensor_file, stim_table, session_list, unit_ids,\n",
    "            'omitted', baseline_length=750, resp_window_length=750,\n",
    "        )\n",
    "\n",
    "        all_responses = np.array([\n",
    "            exponential_convolve(ors, tau=3, symmetrical=True)\n",
    "            for oresps in omission_responses for ors in oresps\n",
    "        ])\n",
    "\n",
    "        ax.set_title(title_fn(value), fontsize=16, pad=12, loc='right')\n",
    "        vbn_utils.mean_sem_plot(all_responses * 1000, ax, time, color='k')\n",
    "\n",
    "        if ylim_fn is not None and ylim_fn(value) is not None:\n",
    "            ax.set_ylim(*ylim_fn(value))\n",
    "\n",
    "        rect_h = (ax.get_ylim()[1] - ax.get_ylim()[0]) * 0.05\n",
    "        ax.add_patch(Rectangle((-750, ax.get_ylim()[1]), 250, rect_h,\n",
    "                               color='gray', alpha=1, clip_on=False))\n",
    "        ax.add_patch(Rectangle((0, ax.get_ylim()[1]), 250, rect_h,\n",
    "                               edgecolor='gray', facecolor='none',\n",
    "                               linewidth=2, clip_on=False))\n",
    "        baseline = all_responses.mean(axis=0)[0] * 1000\n",
    "        ax.axhline(baseline, color='k', linestyle='--', linewidth=1)\n",
    "        ax.set_xlim(-750, 750)\n",
    "        vbn_utils.formatFigure(fig, ax)\n",
    "\n",
    "        loc, borderpad = inset_loc_fn(value) if inset_loc_fn else ('upper right', 0.5)\n",
    "        inset_ax = inset_axes(ax, width=\"20%\", height=\"40%\", loc=loc, borderpad=borderpad)\n",
    "        vbn_utils.mean_sem_plot(all_responses[:, 600:1100] * 1000, inset_ax,\n",
    "                                time[600:1100], color='k')\n",
    "        inset_ax.axhline(baseline, color='k', linestyle='--', linewidth=1)\n",
    "        vbn_utils.formatFigure(fig, inset_ax)\n",
    "\n",
    "    plt.tight_layout()\n",
    "    return fig"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33493fee",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_omission_psth_by_group(\n",
    "    values=np.arange(1, 9),\n",
    "    filter_kwargs_fn=lambda c: dict(cell_types='all', clusters=c),\n",
    "    title_fn=lambda c: f'Cluster {c}',\n",
    "    inset_loc_fn=lambda c: ('lower right', 1.5) if c == 5 else ('upper right', 0.5),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4985683",
   "metadata": {},
   "source": [
    "### By cell type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3504ebe",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_omission_psth_by_group(\n",
    "    values=['RS', 'FS', 'SST', 'VIP'],\n",
    "    filter_kwargs_fn=lambda ct: dict(cell_types=ct, clusters='all', experience='all'),\n",
    "    title_fn=lambda ct: f'Cell Type {ct}',\n",
    "    inset_loc_fn=lambda ct: ('lower right', 1.5) if ct == 'VIP' else ('upper right', 0.5),\n",
    "    ylim_fn=lambda ct: (-3, 15) if ct == 'VIP' else None,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7085931",
   "metadata": {},
   "source": [
    "### By cortical layer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eab304fd",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_omission_psth_by_group(\n",
    "    values=['2/3', '4', '5', '6'],\n",
    "    filter_kwargs_fn=lambda l: dict(cell_types='all', clusters='all', layers=l),\n",
    "    title_fn=lambda l: f'Layer {l} RS',\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "vbn_manuscript",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
