{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# testing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os,sys,time,glob,math\n",
    "from importlib import reload\n",
    "import subprocess\n",
    "from collections import OrderedDict\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "pd.set_option('display.width', 120)\n",
    "pd.set_option('max_colwidth', 80)\n",
    "%matplotlib inline\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import epitopepredict as ep\n",
    "from epitopepredict import base, sequtils, peptutils, utilities, tepitope, web, plotting, mhclearn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['basicmhc1', 'tepitope', 'netmhciipan', 'netmhcpan', 'mhcflurry', 'mhcnuggets', 'iedbmhc1', 'iedbmhc2']\n"
     ]
    }
   ],
   "source": [
    "print (base.predictors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "seqs = ['MRRVILPTAPPEYMEAIYPVRSNSTIARGGNSNTGFLTPESVNGDTPSNPLRPIADDTIDHASHTPGSVSSA',\n",
    "         'FILEAMVNVISGPKVLMKQIPIWLPLGVADQKTYSFDSTTAAIMLASYTITHFGKATNPLVRVNRLGPGIPDHP',\n",
    "         'LRLLRIGNQAFLQEFVLPPVQLPQYFTFDLTALKLITQPLPAATWTDDTPTGSNGALRPGISFHPKLRPILLPN',\n",
    "         'KSGKKGNSADLTSPEKIQAIMTSLQDFKIVPIDPTKNIMGIEVPETLVHKLTGKKVTSKNGQPIIPVLLPKYIGL',\n",
    "         'DPVAPGDLTMVITQDCDTCHSPASLPAVIEK']\n",
    "#prots=sequtils.fasta_to_dataframe('../tempseq.fa')\n",
    "prots = sequtils.genbank_to_dataframe('../MTB-H37Rv.gb',cds=True)\n",
    "seqs = peptutils.create_random_sequences(5000)\n",
    "m2alleles = base.get_preset_alleles('mhc2_supertypes')\n",
    "m1alleles = base.get_preset_alleles('mhc1_supertypes')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "basicmhc1 predictor\n",
      "basicmhc1 ['HLA-A*02:01', 'HLA-A*02:03', 'HLA-A*02:06', 'HLA-A*03:01', 'HLA-A*68:02', 'HLA-A*11:01']\n",
      "tepitope predictor\n",
      "tepitope ['HLA-DRB1*1601', 'HLA-DRB1*0101', 'HLA-DRB1*0102', 'HLA-DRB1*0103', 'HLA-DRB1*0104', 'HLA-DRB1*0105']\n",
      "netmhciipan predictor\n",
      "netmhciipan ['DRB1_0101', 'DRB1_0102', 'DRB1_0103', 'DRB1_0104', 'DRB1_0105', 'DRB1_0106']\n",
      "netmhcpan predictor\n",
      "netmhcpan ['BoLA-100901', 'BoLA-100902', 'BoLA-101901', 'BoLA-102001', 'BoLA-102101', 'BoLA-102301']\n",
      "mhcflurry predictor\n",
      "mhcflurry ['BoLA-6*13:01', 'Eqca-1*01:01', 'H-2-Db', 'H-2-Dd', 'H-2-Kb', 'H-2-Kd']\n",
      "mhcnuggets predictor\n",
      "mhcnuggets ['BoLA-208:01', 'BoLA-212:01', 'BoLA-613:01', 'BoLA-641:01', 'BoLA-A11:01', 'BoLA-DRB302:01']\n",
      "iedbmhc1 predictor\n",
      "iedbmhc1 ['BoLA-AW10', 'BoLA-D18.4', 'BoLA-HD6', 'BoLA-JSP.1', 'BoLA-T2C', 'BoLA-T2a']\n",
      "iedbmhc2 predictor\n",
      "iedbmhc2 ['H2-IAb', 'H2-IAd', 'HLA-DPA1*01/DPB1*04:01', 'HLA-DPA1*01:03/DPB1*02:01', 'HLA-DPA1*02:01/DPB1*01:01', 'HLA-DPA1*02:01/DPB1*05:01']\n"
     ]
    }
   ],
   "source": [
    "reload(base)\n",
    "for p in base.predictors:\n",
    "    P=base.get_predictor(p)\n",
    "    print (P)\n",
    "    x=P.get_alleles()[:6]\n",
    "    print (p,x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "reload(sequtils)\n",
    "\n",
    "def benchmark_cpus(P, seqs, alleles, c=5):\n",
    "    procs=range(1,c)\n",
    "    tt=[]\n",
    "    for c in procs:\n",
    "        st=time.time()\n",
    "        P.predict_peptides(seqs, alleles=alleles, cpus=c)\n",
    "        #P.predictProteins(prots[:20], alleles=m2alleles, cpus=c)\n",
    "        t=time.time()-st\n",
    "        tt.append(t)\n",
    "    plt.plot(procs,tt)\n",
    "    plt.xlabel('cpus')\n",
    "    \n",
    "def benchmark_seqs(P, seqs, alleles, n=4):\n",
    "    tt=[]\n",
    "    n=len(seqs)/n\n",
    "    x=range(n,len(seqs)+1,n)\n",
    "    print n,x\n",
    "    for i in x:\n",
    "        s=seqs[:i]        \n",
    "        st=time.time()\n",
    "        P.predict_peptides(s, alleles=alleles)\n",
    "        #P.predictProteins(s, alleles=m2alleles, cpus=c)\n",
    "        t=time.time()-st\n",
    "        tt.append(t)\n",
    "    print ([i[1]/i[0] for i in zip(x,tt)])\n",
    "    plt.plot(x,tt)\n",
    "    plt.xlabel('peptides')\n",
    "    plt.ylabel('time')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### basic tests MHC-I"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "trained model: HLA-A*24:02 1668 9\n",
      "trained model: HLA-A*24:02 456 10\n",
      "trained model: HLA-B*44:03 570 9\n",
      "trained model: HLA-B*44:03 439 10\n",
      "10.746431350708008\n"
     ]
    }
   ],
   "source": [
    "reload(base)\n",
    "reload(mhclearn)\n",
    "seqs = peptutils.create_random_sequences(10)\n",
    "#df = pd.DataFrame(seqs,columns=['peptide'])\n",
    "#P = ep.get_predictor('iedbmhc1')\n",
    "#P = ep.get_predictor('netmhcpan')\n",
    "#P = ep.get_predictor('mhcflurry')\n",
    "#P = ep.get_predictor('mhcnuggets')\n",
    "P=base.get_predictor('basicmhc1')\n",
    "st=t=time.time()\n",
    "res=P.predict_peptides(seqs, alleles=m1alleles, cpus=1)\n",
    "print (time.time()-st)\n",
    "#print (res)\n",
    "#print (P.promiscuous_binders(n=1))#cutoff_method='score',cutoff=1000))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### basic tests MHC-II"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a     2.5\n",
       "b    55.0\n",
       "Name: 0.5, dtype: float64"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame(np.array([[1, 1], [2, 10], [3, 100], [4, 100]]),\n",
    "                      columns=['a', 'b'])\n",
    "df.quantile(.5,interpolation='linear')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'DRB1_0101'"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def allele_mapping(allele):\n",
    "    if allele.startswith('HLA-DQA'):\n",
    "        return allele.replace('*','').replace(':','')\n",
    "    else:\n",
    "        return allele.replace('*','_').replace(':','').replace('HLA-DRB','DRB')\n",
    "allele_mapping('HLA-DRB1*01:01')\n",
    "#allele_mapping('HLA-DQA1*03:02-DQB1*03:02')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "netmhciipan predictor\n",
      "netMHCIIpan -f /tmp/tmpi2vf_oo7.pep -inptype 1 -a HLA-DQA10302-DQB10302\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>peptide</th>\n",
       "      <th>pos</th>\n",
       "      <th>1-log50k(aff)</th>\n",
       "      <th>Affinity</th>\n",
       "      <th>core</th>\n",
       "      <th>allele</th>\n",
       "      <th>name</th>\n",
       "      <th>score</th>\n",
       "      <th>rank</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>IDWIHAYEHAAIINC</td>\n",
       "      <td>4</td>\n",
       "      <td>0.336</td>\n",
       "      <td>1322.92</td>\n",
       "      <td>HAYEHAAII</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>1322.92</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>RDFSCTTAKSQQLPL</td>\n",
       "      <td>8</td>\n",
       "      <td>0.244</td>\n",
       "      <td>3576.98</td>\n",
       "      <td>CTTAKSQQL</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>3576.98</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>IDEPSCNTHVWADIS</td>\n",
       "      <td>2</td>\n",
       "      <td>0.233</td>\n",
       "      <td>4026.28</td>\n",
       "      <td>NTHVWADIS</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>4026.28</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>DNSLVMPILHRYARE</td>\n",
       "      <td>3</td>\n",
       "      <td>0.221</td>\n",
       "      <td>4587.52</td>\n",
       "      <td>DNSLVMPIL</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>4587.52</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>VSIVRKVSEWEHVGI</td>\n",
       "      <td>9</td>\n",
       "      <td>0.209</td>\n",
       "      <td>5201.73</td>\n",
       "      <td>IVRKVSEWE</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>5201.73</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>RNMMCETWNPIMHCP</td>\n",
       "      <td>0</td>\n",
       "      <td>0.190</td>\n",
       "      <td>6376.22</td>\n",
       "      <td>ETWNPIMHC</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>6376.22</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>GHHQQMANGDGMYKH</td>\n",
       "      <td>7</td>\n",
       "      <td>0.152</td>\n",
       "      <td>9700.81</td>\n",
       "      <td>QMANGDGMY</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>9700.81</td>\n",
       "      <td>7.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>KGQLKCEDAHCLHYR</td>\n",
       "      <td>5</td>\n",
       "      <td>0.141</td>\n",
       "      <td>10889.96</td>\n",
       "      <td>LKCEDAHCL</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>10889.96</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>GWDDAWPGSSGRRVS</td>\n",
       "      <td>6</td>\n",
       "      <td>0.127</td>\n",
       "      <td>12602.80</td>\n",
       "      <td>WDDAWPGSS</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>12602.80</td>\n",
       "      <td>9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>HLIHMFKHFHHGDER</td>\n",
       "      <td>1</td>\n",
       "      <td>0.114</td>\n",
       "      <td>14525.20</td>\n",
       "      <td>FKHFHHGDE</td>\n",
       "      <td>HLA-DQA1*0302-DQB1*0302</td>\n",
       "      <td>temp</td>\n",
       "      <td>14525.20</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           peptide  pos  1-log50k(aff)  Affinity       core                   allele  name     score  rank\n",
       "0  IDWIHAYEHAAIINC    4          0.336   1322.92  HAYEHAAII  HLA-DQA1*0302-DQB1*0302  temp   1322.92   1.0\n",
       "1  RDFSCTTAKSQQLPL    8          0.244   3576.98  CTTAKSQQL  HLA-DQA1*0302-DQB1*0302  temp   3576.98   2.0\n",
       "2  IDEPSCNTHVWADIS    2          0.233   4026.28  NTHVWADIS  HLA-DQA1*0302-DQB1*0302  temp   4026.28   3.0\n",
       "3  DNSLVMPILHRYARE    3          0.221   4587.52  DNSLVMPIL  HLA-DQA1*0302-DQB1*0302  temp   4587.52   4.0\n",
       "4  VSIVRKVSEWEHVGI    9          0.209   5201.73  IVRKVSEWE  HLA-DQA1*0302-DQB1*0302  temp   5201.73   5.0\n",
       "5  RNMMCETWNPIMHCP    0          0.190   6376.22  ETWNPIMHC  HLA-DQA1*0302-DQB1*0302  temp   6376.22   6.0\n",
       "6  GHHQQMANGDGMYKH    7          0.152   9700.81  QMANGDGMY  HLA-DQA1*0302-DQB1*0302  temp   9700.81   7.0\n",
       "7  KGQLKCEDAHCLHYR    5          0.141  10889.96  LKCEDAHCL  HLA-DQA1*0302-DQB1*0302  temp  10889.96   8.0\n",
       "8  GWDDAWPGSSGRRVS    6          0.127  12602.80  WDDAWPGSS  HLA-DQA1*0302-DQB1*0302  temp  12602.80   9.0\n",
       "9  HLIHMFKHFHHGDER    1          0.114  14525.20  FKHFHHGDE  HLA-DQA1*0302-DQB1*0302  temp  14525.20  10.0"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reload(base)\n",
    "P = base.get_predictor('netmhciipan')\n",
    "#P = base.get_predictor('iedbmhc2')\n",
    "print (P)\n",
    "allele='HLA-DQA1*0302-DQB1*0302'\n",
    "seqs = peptutils.create_random_sequences(10,length=15)\n",
    "r=P.predict_peptides(seqs, alleles=allele, show_cmd=True, cpus=1)\n",
    "r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=pd.read_csv('../epitopepredict/mhcdata/iedb_mhc2_alleles.csv').allele\n",
    "for i in a.sort_values().unique():\n",
    "    print i"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### create quantiles/cutoffs for each predictor "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#%reset out\n",
    "\n",
    "reload(base)\n",
    "#p='tepitope'\n",
    "#p='mhcflurry'\n",
    "p='netmhciipan'\n",
    "#p='basicmhc1'\n",
    "savepath='../standard/%s/' %p\n",
    "df = sequtils.fasta_to_dataframe('../epitopepredict/mhcdata/immunogens.faa')\n",
    "P = base.get_predictor(p)\n",
    "print (P)\n",
    "#print P.get_alleles()\n",
    "all_alleles=P.get_alleles()[1500:1700]\n",
    "test_alleles=['HLA-DQA10303-DQB10303','HLA-DQA10501-DQB10501','HLA-DPA10201-DPB10201','HLA-DPA10103-DPB10101']\n",
    "print (len(all_alleles))\n",
    "res = pd.read_csv('../epitopepredict/mhcdata/quantiles_%s.csv' %p,index_col=0)\n",
    "print (len(res))\n",
    "\n",
    "P.predict_sequences(df,alleles=all_alleles, path=savepath, cpus=8, length=11)#, verbose=True)\n",
    "#P.predict_sequences(df,alleles=['HLA-C*02:02'], path=savepath, cpus=4)\n",
    "P.load(savepath)\n",
    "#print (P.data)\n",
    "new=base.get_quantiles(P)\n",
    "print (new)\n",
    "\n",
    "new.to_csv('quantiles_%s.csv' %p,float_format='%.3f')\n",
    "\n",
    "#f,ax=plt.subplots(1,1,figsize=(18,5))\n",
    "#ax.pcolor(res,cmap='coolwarm')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mhcnuggets\n",
    "spath='/usr/local/lib/python2.7/dist-packages/mhcnuggets/saves/production/'\n",
    "tmp=subprocess.check_output('ls %s' %spath, shell=True)\n",
    "x=[i[:-3] for i in tmp.split('\\n')]\n",
    "for i in x:\n",
    "    print i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "netMHCpan appears to be installed\n",
      "BoLA-1:00901    1166.9\n",
      "BoLA-1:00902     298.3\n",
      "BoLA-1:01901      66.9\n",
      "BoLA-1:02001     714.7\n",
      "BoLA-1:02101     919.5\n",
      "BoLA-1:02301     534.3\n",
      "BoLA-1:02801     481.7\n",
      "BoLA-1:02901    1673.3\n",
      "BoLA-1:03101     377.3\n",
      "BoLA-1:03102     449.0\n",
      "BoLA-1:04201    1696.4\n",
      "BoLA-1:04901     647.5\n",
      "BoLA-1:06101     947.3\n",
      "Name: 0.99, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "reload(base)\n",
    "p='netmhcpan'\n",
    "P=base.get_predictor(p)\n",
    "P.check_install()\n",
    "print P.get_allele_cutoffs(.99)[:13]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## iedb mhc2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iedbmhc2 predictor\n",
      "predictions done for 2 sequences in 4 alleles\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pos</th>\n",
       "      <th>allele</th>\n",
       "      <th>seq_num</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "      <th>core_peptide</th>\n",
       "      <th>peptide</th>\n",
       "      <th>ic50</th>\n",
       "      <th>percentile_rank</th>\n",
       "      <th>core</th>\n",
       "      <th>name</th>\n",
       "      <th>method</th>\n",
       "      <th>score</th>\n",
       "      <th>rank</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>HLA-DRB1*01:01</td>\n",
       "      <td>1</td>\n",
       "      <td>177</td>\n",
       "      <td>191</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>KNFLNFLQTNGLNAI</td>\n",
       "      <td>5.2</td>\n",
       "      <td>0.97</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>Bla-g-1</td>\n",
       "      <td>nn_align</td>\n",
       "      <td>5.2</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>HLA-DRB1*01:01</td>\n",
       "      <td>1</td>\n",
       "      <td>365</td>\n",
       "      <td>379</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>KNFLNFLQTNGLNAI</td>\n",
       "      <td>5.2</td>\n",
       "      <td>0.97</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>Bla-g-1</td>\n",
       "      <td>nn_align</td>\n",
       "      <td>5.2</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>HLA-DRB1*01:01</td>\n",
       "      <td>1</td>\n",
       "      <td>179</td>\n",
       "      <td>193</td>\n",
       "      <td>FLQTNGLNA</td>\n",
       "      <td>FLNFLQTNGLNAIEF</td>\n",
       "      <td>6.1</td>\n",
       "      <td>1.81</td>\n",
       "      <td>FLQTNGLNA</td>\n",
       "      <td>Bla-g-1</td>\n",
       "      <td>nn_align</td>\n",
       "      <td>6.1</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>HLA-DRB1*01:01</td>\n",
       "      <td>1</td>\n",
       "      <td>367</td>\n",
       "      <td>381</td>\n",
       "      <td>FLQTNGLNA</td>\n",
       "      <td>FLNFLQTNGLNAIEF</td>\n",
       "      <td>6.1</td>\n",
       "      <td>1.81</td>\n",
       "      <td>FLQTNGLNA</td>\n",
       "      <td>Bla-g-1</td>\n",
       "      <td>nn_align</td>\n",
       "      <td>6.1</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>HLA-DRB1*01:01</td>\n",
       "      <td>1</td>\n",
       "      <td>178</td>\n",
       "      <td>192</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>NFLNFLQTNGLNAIE</td>\n",
       "      <td>6.3</td>\n",
       "      <td>1.99</td>\n",
       "      <td>LNFLQTNGL</td>\n",
       "      <td>Bla-g-1</td>\n",
       "      <td>nn_align</td>\n",
       "      <td>6.3</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pos          allele  seq_num  start  end core_peptide          peptide  ic50  percentile_rank       core     name  \\\n",
       "0    0  HLA-DRB1*01:01        1    177  191    LNFLQTNGL  KNFLNFLQTNGLNAI   5.2             0.97  LNFLQTNGL  Bla-g-1   \n",
       "1    1  HLA-DRB1*01:01        1    365  379    LNFLQTNGL  KNFLNFLQTNGLNAI   5.2             0.97  LNFLQTNGL  Bla-g-1   \n",
       "2    2  HLA-DRB1*01:01        1    179  193    FLQTNGLNA  FLNFLQTNGLNAIEF   6.1             1.81  FLQTNGLNA  Bla-g-1   \n",
       "3    3  HLA-DRB1*01:01        1    367  381    FLQTNGLNA  FLNFLQTNGLNAIEF   6.1             1.81  FLQTNGLNA  Bla-g-1   \n",
       "4    4  HLA-DRB1*01:01        1    178  192    LNFLQTNGL  NFLNFLQTNGLNAIE   6.3             1.99  LNFLQTNGL  Bla-g-1   \n",
       "\n",
       "     method  score  rank  \n",
       "0  nn_align    5.2   1.0  \n",
       "1  nn_align    5.2   1.0  \n",
       "2  nn_align    6.1   3.0  \n",
       "3  nn_align    6.1   3.0  \n",
       "4  nn_align    6.3   5.0  "
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reload(base)\n",
    "prots = ep.fasta_to_dataframe('cockroach_allergens.fa')\n",
    "P = base.get_predictor('iedbmhc2')\n",
    "#P = base.get_predictor('netmhciipan')\n",
    "print (P)\n",
    "b = P.predict_sequences(prots[:2], alleles=m2alleles[:4], cpus=1, method='nn_align') # show_cmd=True,\n",
    "b.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div class=\"bk-root\">\n",
       "        <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
       "        <span id=\"ddfdaafa-1736-46a5-913b-0be2a8082215\">Loading BokehJS ...</span>\n",
       "    </div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "\n",
       "(function(root) {\n",
       "  function now() {\n",
       "    return new Date();\n",
       "  }\n",
       "\n",
       "  var force = true;\n",
       "\n",
       "  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n",
       "    root._bokeh_onload_callbacks = [];\n",
       "    root._bokeh_is_loading = undefined;\n",
       "  }\n",
       "\n",
       "  var JS_MIME_TYPE = 'application/javascript';\n",
       "  var HTML_MIME_TYPE = 'text/html';\n",
       "  var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
       "  var CLASS_NAME = 'output_bokeh rendered_html';\n",
       "\n",
       "  /**\n",
       "   * Render data to the DOM node\n",
       "   */\n",
       "  function render(props, node) {\n",
       "    var script = document.createElement(\"script\");\n",
       "    node.appendChild(script);\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when an output is cleared or removed\n",
       "   */\n",
       "  function handleClearOutput(event, handle) {\n",
       "    var cell = handle.cell;\n",
       "\n",
       "    var id = cell.output_area._bokeh_element_id;\n",
       "    var server_id = cell.output_area._bokeh_server_id;\n",
       "    // Clean up Bokeh references\n",
       "    if (id !== undefined) {\n",
       "      Bokeh.index[id].model.document.clear();\n",
       "      delete Bokeh.index[id];\n",
       "    }\n",
       "\n",
       "    if (server_id !== undefined) {\n",
       "      // Clean up Bokeh references\n",
       "      var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
       "      cell.notebook.kernel.execute(cmd, {\n",
       "        iopub: {\n",
       "          output: function(msg) {\n",
       "            var element_id = msg.content.text.trim();\n",
       "            Bokeh.index[element_id].model.document.clear();\n",
       "            delete Bokeh.index[element_id];\n",
       "          }\n",
       "        }\n",
       "      });\n",
       "      // Destroy server and session\n",
       "      var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
       "      cell.notebook.kernel.execute(cmd);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when a new output is added\n",
       "   */\n",
       "  function handleAddOutput(event, handle) {\n",
       "    var output_area = handle.output_area;\n",
       "    var output = handle.output;\n",
       "\n",
       "    // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
       "    if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
       "      return\n",
       "    }\n",
       "\n",
       "    var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
       "\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
       "      toinsert[0].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
       "      // store reference to embed id on output_area\n",
       "      output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
       "    }\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
       "      var bk_div = document.createElement(\"div\");\n",
       "      bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
       "      var script_attrs = bk_div.children[0].attributes;\n",
       "      for (var i = 0; i < script_attrs.length; i++) {\n",
       "        toinsert[0].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
       "      }\n",
       "      // store reference to server id on output_area\n",
       "      output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
       "    }\n",
       "  }\n",
       "\n",
       "  function register_renderer(events, OutputArea) {\n",
       "\n",
       "    function append_mime(data, metadata, element) {\n",
       "      // create a DOM node to render to\n",
       "      var toinsert = this.create_output_subarea(\n",
       "        metadata,\n",
       "        CLASS_NAME,\n",
       "        EXEC_MIME_TYPE\n",
       "      );\n",
       "      this.keyboard_manager.register_events(toinsert);\n",
       "      // Render to node\n",
       "      var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
       "      render(props, toinsert[0]);\n",
       "      element.append(toinsert);\n",
       "      return toinsert\n",
       "    }\n",
       "\n",
       "    /* Handle when an output is cleared or removed */\n",
       "    events.on('clear_output.CodeCell', handleClearOutput);\n",
       "    events.on('delete.Cell', handleClearOutput);\n",
       "\n",
       "    /* Handle when a new output is added */\n",
       "    events.on('output_added.OutputArea', handleAddOutput);\n",
       "\n",
       "    /**\n",
       "     * Register the mime type and append_mime function with output_area\n",
       "     */\n",
       "    OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
       "      /* Is output safe? */\n",
       "      safe: true,\n",
       "      /* Index of renderer in `output_area.display_order` */\n",
       "      index: 0\n",
       "    });\n",
       "  }\n",
       "\n",
       "  // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
       "  if (root.Jupyter !== undefined) {\n",
       "    var events = require('base/js/events');\n",
       "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
       "\n",
       "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
       "      register_renderer(events, OutputArea);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  \n",
       "  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
       "    root._bokeh_timeout = Date.now() + 5000;\n",
       "    root._bokeh_failed_load = false;\n",
       "  }\n",
       "\n",
       "  var NB_LOAD_WARNING = {'data': {'text/html':\n",
       "     \"<div style='background-color: #fdd'>\\n\"+\n",
       "     \"<p>\\n\"+\n",
       "     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
       "     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
       "     \"</p>\\n\"+\n",
       "     \"<ul>\\n\"+\n",
       "     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
       "     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
       "     \"</ul>\\n\"+\n",
       "     \"<code>\\n\"+\n",
       "     \"from bokeh.resources import INLINE\\n\"+\n",
       "     \"output_notebook(resources=INLINE)\\n\"+\n",
       "     \"</code>\\n\"+\n",
       "     \"</div>\"}};\n",
       "\n",
       "  function display_loaded() {\n",
       "    var el = document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\");\n",
       "    if (el != null) {\n",
       "      el.textContent = \"BokehJS is loading...\";\n",
       "    }\n",
       "    if (root.Bokeh !== undefined) {\n",
       "      if (el != null) {\n",
       "        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
       "      }\n",
       "    } else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(display_loaded, 100)\n",
       "    }\n",
       "  }\n",
       "\n",
       "\n",
       "  function run_callbacks() {\n",
       "    try {\n",
       "      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
       "    }\n",
       "    finally {\n",
       "      delete root._bokeh_onload_callbacks\n",
       "    }\n",
       "    console.info(\"Bokeh: all callbacks have finished\");\n",
       "  }\n",
       "\n",
       "  function load_libs(js_urls, callback) {\n",
       "    root._bokeh_onload_callbacks.push(callback);\n",
       "    if (root._bokeh_is_loading > 0) {\n",
       "      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
       "      return null;\n",
       "    }\n",
       "    if (js_urls == null || js_urls.length === 0) {\n",
       "      run_callbacks();\n",
       "      return null;\n",
       "    }\n",
       "    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
       "    root._bokeh_is_loading = js_urls.length;\n",
       "    for (var i = 0; i < js_urls.length; i++) {\n",
       "      var url = js_urls[i];\n",
       "      var s = document.createElement('script');\n",
       "      s.src = url;\n",
       "      s.async = false;\n",
       "      s.onreadystatechange = s.onload = function() {\n",
       "        root._bokeh_is_loading--;\n",
       "        if (root._bokeh_is_loading === 0) {\n",
       "          console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
       "          run_callbacks()\n",
       "        }\n",
       "      };\n",
       "      s.onerror = function() {\n",
       "        console.warn(\"failed to load library \" + url);\n",
       "      };\n",
       "      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
       "      document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "    }\n",
       "  };var element = document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\");\n",
       "  if (element == null) {\n",
       "    console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'ddfdaafa-1736-46a5-913b-0be2a8082215' but no matching script tag was found. \")\n",
       "    return false;\n",
       "  }\n",
       "\n",
       "  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.12.14.min.js\"];\n",
       "\n",
       "  var inline_js = [\n",
       "    function(Bokeh) {\n",
       "      Bokeh.set_log_level(\"info\");\n",
       "    },\n",
       "    \n",
       "    function(Bokeh) {\n",
       "      \n",
       "    },\n",
       "    function(Bokeh) {\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n",
       "    }\n",
       "  ];\n",
       "\n",
       "  function run_inline_js() {\n",
       "    \n",
       "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
       "      for (var i = 0; i < inline_js.length; i++) {\n",
       "        inline_js[i].call(root, root.Bokeh);\n",
       "      }if (force === true) {\n",
       "        display_loaded();\n",
       "      }} else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(run_inline_js, 100);\n",
       "    } else if (!root._bokeh_failed_load) {\n",
       "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
       "      root._bokeh_failed_load = true;\n",
       "    } else if (force !== true) {\n",
       "      var cell = $(document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\")).parents('.cell').data().cell;\n",
       "      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
       "    }\n",
       "\n",
       "  }\n",
       "\n",
       "  if (root._bokeh_is_loading === 0) {\n",
       "    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
       "    run_inline_js();\n",
       "  } else {\n",
       "    load_libs(js_urls, function() {\n",
       "      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
       "      run_inline_js();\n",
       "    });\n",
       "  }\n",
       "}(window));"
      ],
      "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n\n  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n    root._bokeh_onload_callbacks = [];\n    root._bokeh_is_loading = undefined;\n  }\n\n  \n\n  \n  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  var NB_LOAD_WARNING = {'data': {'text/html':\n     \"<div style='background-color: #fdd'>\\n\"+\n     \"<p>\\n\"+\n     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n     \"</p>\\n\"+\n     \"<ul>\\n\"+\n     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n     \"</ul>\\n\"+\n     \"<code>\\n\"+\n     \"from bokeh.resources import INLINE\\n\"+\n     \"output_notebook(resources=INLINE)\\n\"+\n     \"</code>\\n\"+\n     \"</div>\"}};\n\n  function display_loaded() {\n    var el = document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\");\n    if (el != null) {\n      el.textContent = \"BokehJS is loading...\";\n    }\n    if (root.Bokeh !== undefined) {\n      if (el != null) {\n        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(display_loaded, 100)\n    }\n  }\n\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n    }\n    finally {\n      delete root._bokeh_onload_callbacks\n    }\n    console.info(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(js_urls, callback) {\n    root._bokeh_onload_callbacks.push(callback);\n    if (root._bokeh_is_loading > 0) {\n      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls == null || js_urls.length === 0) {\n      run_callbacks();\n      return null;\n    }\n    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    root._bokeh_is_loading = js_urls.length;\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      var s = document.createElement('script');\n      s.src = url;\n      s.async = false;\n      s.onreadystatechange = s.onload = function() {\n        root._bokeh_is_loading--;\n        if (root._bokeh_is_loading === 0) {\n          console.log(\"Bokeh: all BokehJS libraries loaded\");\n          run_callbacks()\n        }\n      };\n      s.onerror = function() {\n        console.warn(\"failed to load library \" + url);\n      };\n      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.getElementsByTagName(\"head\")[0].appendChild(s);\n    }\n  };var element = document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\");\n  if (element == null) {\n    console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'ddfdaafa-1736-46a5-913b-0be2a8082215' but no matching script tag was found. \")\n    return false;\n  }\n\n  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.12.14.min.js\"];\n\n  var inline_js = [\n    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    \n    function(Bokeh) {\n      \n    },\n    function(Bokeh) {\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n    }\n  ];\n\n  function run_inline_js() {\n    \n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }if (force === true) {\n        display_loaded();\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    } else if (force !== true) {\n      var cell = $(document.getElementById(\"ddfdaafa-1736-46a5-913b-0be2a8082215\")).parents('.cell').data().cell;\n      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n    }\n\n  }\n\n  if (root._bokeh_is_loading === 0) {\n    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n    run_inline_js();\n  } else {\n    load_libs(js_urls, function() {\n      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n      run_inline_js();\n    });\n  }\n}(window));"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<div class=\"bk-root\">\n",
       "    <div class=\"bk-plotdiv\" id=\"e30f2dee-07a8-4d4f-bfc7-706fd290e390\"></div>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "(function(root) {\n",
       "  function embed_document(root) {\n",
       "    \n",
       "  var docs_json = {\"9de9c6b9-bd0f-4a1b-9182-e33093286a6e\":{\"roots\":{\"references\":[{\"attributes\":{},\"id\":\"99fab858-1b78-44af-afcc-487d4900934f\",\"type\":\"LinearScale\"},{\"attributes\":{\"minor_grid_line_alpha\":{\"value\":0.1},\"minor_grid_line_color\":{\"value\":\"gray\"},\"plot\":{\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"fddc5522-a94d-419f-96ad-1b72ccea32ac\",\"type\":\"BasicTicker\"}},\"id\":\"37fc5350-fc9b-4c5f-ac38-f0fd7e69fb7b\",\"type\":\"Grid\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.8},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"field\":\"width\",\"units\":\"data\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"bcfbe77a-c98d-4e29-a961-9caabdb56689\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"0e62de0e-fc30-408c-b12a-415df8462b1c\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"98c1d55b-4972-4134-9ac0-42d0bece4e90\",\"type\":\"BasicTicker\"},{\"attributes\":{\"dimensions\":\"width\"},\"id\":\"8deecc3c-7ac3-476b-b9cf-ae70414e6e13\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"2c81cd79-add4-4611-8410-619b0f2bc851\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"eced9f4b-c9e5-4ae4-b1f1-ef5584bbfa18\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"bounds\":\"auto\",\"callback\":null,\"end\":492},\"id\":\"f33cd89c-fedc-40d1-af95-6b0692cf5066\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"b11f1b47-80eb-4f09-842c-30c2a44b589b\",\"type\":\"SaveTool\"},{\"attributes\":{\"dimensions\":\"width\"},\"id\":\"0f991fa7-613e-4bbc-9e41-371877874f8d\",\"type\":\"PanTool\"},{\"attributes\":{\"callback\":null,\"end\":8},\"id\":\"f3ec0f81-8c5c-49ab-b285-413b7f0bb22e\",\"type\":\"Range1d\"},{\"attributes\":{\"background_fill_alpha\":{\"value\":0.5},\"background_fill_color\":{\"value\":\"#fafaf4\"},\"below\":[{\"id\":\"35f09d30-d919-41e1-882d-db28f393b1b2\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"5ffb87c7-832e-4d27-a593-9f370b6324bd\",\"type\":\"LinearAxis\"}],\"min_border\":10,\"plot_height\":190,\"plot_width\":800,\"renderers\":[{\"id\":\"35f09d30-d919-41e1-882d-db28f393b1b2\",\"type\":\"LinearAxis\"},{\"id\":\"37fc5350-fc9b-4c5f-ac38-f0fd7e69fb7b\",\"type\":\"Grid\"},{\"id\":\"5ffb87c7-832e-4d27-a593-9f370b6324bd\",\"type\":\"LinearAxis\"},{\"id\":\"ebd3b7bf-93aa-4162-a7b4-d37d93454197\",\"type\":\"Grid\"},{\"id\":\"3464de4c-73b6-4bbe-ae07-5a9ff99a0738\",\"type\":\"Legend\"},{\"id\":\"54730553-b59e-44d4-bf1f-9855e471816d\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"cf83196d-91cf-44e6-982a-3bfea98f81db\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"834770bc-1f06-48e1-85cc-ce4932762a4e\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"f33cd89c-fedc-40d1-af95-6b0692cf5066\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"0e62de0e-fc30-408c-b12a-415df8462b1c\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"f3ec0f81-8c5c-49ab-b285-413b7f0bb22e\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"99fab858-1b78-44af-afcc-487d4900934f\",\"type\":\"LinearScale\"}},\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"fddc5522-a94d-419f-96ad-1b72ccea32ac\",\"type\":\"BasicTicker\"},{\"attributes\":{\"callback\":null,\"column_names\":[\"x\",\"y\",\"allele\",\"peptide\",\"width\",\"color\",\"predictor\",\"position\",\"score\"],\"data\":{\"allele\":[\"HLA-DRB1*01:01\",\"HLA-DRB1*01:01\",\"HLA-DRB1*03:01\",\"HLA-DRB1*03:01\",\"HLA-DRB1*04:01\",\"HLA-DRB1*04:01\",\"HLA-DRB1*07:01\",\"HLA-DRB1*07:01\"],\"color\":[\"#f781bf\",\"#f781bf\",\"#f781bf\",\"#f781bf\",\"#f781bf\",\"#f781bf\",\"#f781bf\",\"#f781bf\"],\"peptide\":[\"KNFLNFLQTNGLNAI\",\"KALYDAIRSPEFQSI\",\"IFNIVRDTRGLPEDL\",\"NIVRDTRGLPEDLQD\",\"FKNFLNFLQTNGLNA\",\"PEFKNFLNFLQTNGL\",\"KNFLNFLQTNGLNAI\",\"PEFKNFLNFLQTNGL\"],\"position\":[0,10,0,10,0,10,0,10],\"predictor\":[\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\",\"iedbmhc2\"],\"score\":[5.2,7.0,14.5,45.1,28.4,50.4,10.7,31.8],\"width\":[15,15,15,15,15,15,15,15],\"x\":[7.5,17.5,7.5,17.5,7.5,17.5,7.5,17.5],\"y\":[3.5,3.5,4.5,4.5,5.5,5.5,6.5,6.5]}},\"id\":\"6979ea7e-a3fc-4c89-8983-a02b24ace526\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"6979ea7e-a3fc-4c89-8983-a02b24ace526\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4d171006-8fb7-49b5-8fb7-0b9fa9f8c2d8\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"bcfbe77a-c98d-4e29-a961-9caabdb56689\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"047badd1-2ae7-4512-ac25-c6e3399e203b\",\"type\":\"CDSView\"}},\"id\":\"54730553-b59e-44d4-bf1f-9855e471816d\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"logo\":null,\"tools\":[{\"id\":\"0f991fa7-613e-4bbc-9e41-371877874f8d\",\"type\":\"PanTool\"},{\"id\":\"8deecc3c-7ac3-476b-b9cf-ae70414e6e13\",\"type\":\"WheelZoomTool\"},{\"id\":\"20668c8c-e393-470b-bcec-efe40032cbd5\",\"type\":\"HoverTool\"},{\"id\":\"fedac034-429e-4728-93d3-7efdf34276b3\",\"type\":\"ResetTool\"},{\"id\":\"b11f1b47-80eb-4f09-842c-30c2a44b589b\",\"type\":\"SaveTool\"}]},\"id\":\"834770bc-1f06-48e1-85cc-ce4932762a4e\",\"type\":\"Toolbar\"},{\"attributes\":{\"label\":{\"field\":\"predictor\"},\"renderers\":[{\"id\":\"54730553-b59e-44d4-bf1f-9855e471816d\",\"type\":\"GlyphRenderer\"}]},\"id\":\"9fb538ac-dd46-4d16-8192-6f656def5ed9\",\"type\":\"LegendItem\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.7},\"fill_color\":{\"field\":\"color\"},\"height\":{\"units\":\"data\",\"value\":0.8},\"line_alpha\":{\"value\":0.7},\"line_color\":{\"value\":\"gray\"},\"width\":{\"field\":\"width\",\"units\":\"data\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4d171006-8fb7-49b5-8fb7-0b9fa9f8c2d8\",\"type\":\"Rect\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"cf83196d-91cf-44e6-982a-3bfea98f81db\",\"type\":\"Title\"},{\"attributes\":{\"source\":{\"id\":\"6979ea7e-a3fc-4c89-8983-a02b24ace526\",\"type\":\"ColumnDataSource\"}},\"id\":\"047badd1-2ae7-4512-ac25-c6e3399e203b\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"tooltips\":[[\"allele\",\"@allele\"],[\"position\",\"@position\"],[\"peptide\",\"@peptide\"],[\"score\",\"@score\"],[\"predictor\",\"@predictor\"]]},\"id\":\"20668c8c-e393-470b-bcec-efe40032cbd5\",\"type\":\"HoverTool\"},{\"attributes\":{\"dimension\":1,\"grid_line_color\":{\"value\":null},\"plot\":{\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"98c1d55b-4972-4134-9ac0-42d0bece4e90\",\"type\":\"BasicTicker\"}},\"id\":\"ebd3b7bf-93aa-4162-a7b4-d37d93454197\",\"type\":\"Grid\"},{\"attributes\":{\"items\":[{\"id\":\"9fb538ac-dd46-4d16-8192-6f656def5ed9\",\"type\":\"LegendItem\"}],\"location\":\"bottom_right\",\"orientation\":\"horizontal\",\"plot\":{\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"3464de4c-73b6-4bbe-ae07-5a9ff99a0738\",\"type\":\"Legend\"},{\"attributes\":{\"axis_label\":\"allele\",\"formatter\":{\"id\":\"2c81cd79-add4-4611-8410-619b0f2bc851\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"0pt\"},\"plot\":{\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"98c1d55b-4972-4134-9ac0-42d0bece4e90\",\"type\":\"BasicTicker\"}},\"id\":\"5ffb87c7-832e-4d27-a593-9f370b6324bd\",\"type\":\"LinearAxis\"},{\"attributes\":{\"formatter\":{\"id\":\"eced9f4b-c9e5-4ae4-b1f1-ef5584bbfa18\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"9pt\"},\"major_label_text_font_style\":\"bold\",\"plot\":{\"id\":\"48c13719-3330-406a-b75b-f0892fceed20\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"fddc5522-a94d-419f-96ad-1b72ccea32ac\",\"type\":\"BasicTicker\"}},\"id\":\"35f09d30-d919-41e1-882d-db28f393b1b2\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"fedac034-429e-4728-93d3-7efdf34276b3\",\"type\":\"ResetTool\"}],\"root_ids\":[\"48c13719-3330-406a-b75b-f0892fceed20\"]},\"title\":\"Bokeh Application\",\"version\":\"0.12.14\"}};\n",
       "  var render_items = [{\"docid\":\"9de9c6b9-bd0f-4a1b-9182-e33093286a6e\",\"elementid\":\"e30f2dee-07a8-4d4f-bfc7-706fd290e390\",\"modelid\":\"48c13719-3330-406a-b75b-f0892fceed20\"}];\n",
       "  root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "\n",
       "  }\n",
       "  if (root.Bokeh !== undefined) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (root.Bokeh !== undefined) {\n",
       "        embed_document(root);\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "      attempts++;\n",
       "      if (attempts > 100) {\n",
       "        console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\")\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "    }, 10, root)\n",
       "  }\n",
       "})(window);"
      ],
      "application/vnd.bokehjs_exec.v0+json": ""
     },
     "metadata": {
      "application/vnd.bokehjs_exec.v0+json": {
       "id": "48c13719-3330-406a-b75b-f0892fceed20"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "reload(plotting)\n",
    "from bokeh.io import show, output_notebook\n",
    "output_notebook()\n",
    "p = plotting.bokeh_plot_tracks([P],name='Bla-g-1',cutoff=.95,n=2,width=800)\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        peptide  pos      name  alleles   score      mean  median_rank       core\n",
      "3   ATVVQQQTIAS   93  ZEBOVgp2        7  4.7800  3.821451          4.0  VVQQQTIAS\n",
      "2   ALIQITKRVPI  275  ZEBOVgp2        6  7.0000  4.093070          5.5  IQITKRVPI\n",
      "29  LVQVICKLGKD  241  ZEBOVgp2        5  4.1000  3.585800          4.0  VQVICKLGK\n",
      "17  IHIRSRGDIPR  294  ZEBOVgp2        4  4.5487  4.255150          1.0  IHIRSRGDI\n",
      "6   DLLVMTTGRAT  142  ZEBOVgp2        4  4.0000  2.504830          8.5  LVMTTGRAT\n",
      "1   AFNNLNSTTSL  198  ZEBOVgp2        3  3.7000  2.830000          4.0  FNNLNSTTS\n",
      "56  YDLLVMTTGRA  141  ZEBOVgp2        3  4.0000  2.976440         10.0  LLVMTTGRA\n",
      "14  GWVCVFQLQDG  322  ZEBOVgp2        2  2.8000  2.400000          7.0  WVCVFQLQD\n",
      "34  PVYDMAKTISS  119  ZEBOVgp2        2  2.7800  2.590000          7.0  YDMAKTISS\n",
      "10  EVVQTLASLAT   84  ZEBOVgp2        2  4.0000  2.300000         10.0  VQTLASLAT\n",
      "ZEBOVgp2 tepitope 329 11 340\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f83db00e1d0>"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f83df83df50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f83d88b9a10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "reload(base)\n",
    "P=base.get_predictor('tepitope')\n",
    "path='../zaire_test/tepitope/'\n",
    "fname = '../zaire_test/tepitope/ZEBOVgp2.csv'\n",
    "P.load(path=fname)\n",
    "\n",
    "#b = P.get_binders(cutoff=.95, name='ZEBOVgp2')\n",
    "b = P.get_binders(cutoff=.95, cutoff_method='default')\n",
    "x=P.promiscuous_binders(b, n=2)\n",
    "print x\n",
    "\n",
    "plotting.plot_tracks([P],name='ZEBOVgp2',cutoff=.95,n=2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "498\n",
      "         allele  pos  start  end  length      peptide               method  percentile_rank  ann_ic50  ann_rank  \\\n",
      "1   HLA-A*01:01    1     65   75      11  NWMAQLGPWNY  Consensus (ann/smm)             2.00   2283.88       0.7   \n",
      "0   HLA-A*01:01    1     66   76      11  WMAQLGPWNYA  Consensus (ann/smm)             1.90   7181.33       0.7   \n",
      "2   HLA-A*01:01    1     45   55      11  LIWLMVFQLAA  Consensus (ann/smm)             2.40  13708.56       1.9   \n",
      "3   HLA-A*01:01    1     47   57      11  WLMVFQLAAIG  Consensus (ann/smm)             7.30  21147.59       6.6   \n",
      "4   HLA-A*01:01    1     44   54      11  GLIWLMVFQLA  Consensus (ann/smm)             8.35  24855.69      14.0   \n",
      "5   HLA-A*01:01    1     41   51      11  MLIGLIWLMVF  Consensus (ann/smm)             9.15  20987.35       6.3   \n",
      "6   HLA-A*01:01    1     42   52      11  LIGLIWLMVFQ  Consensus (ann/smm)            11.10  26368.89      17.0   \n",
      "7   HLA-A*01:01    1     40   50      11  LMLIGLIWLMV  Consensus (ann/smm)            13.35  20288.49       5.7   \n",
      "8   HLA-A*01:01    1     32   42      11  WFVSLFIGLML  Consensus (ann/smm)            15.10  18366.00       4.2   \n",
      "18  HLA-A*01:01    1     70   80      11  LGPWNYAIAFA  Consensus (ann/smm)            25.90  33383.30      45.0   \n",
      "13  HLA-A*01:01    1     68   78      11  AQLGPWNYAIA  Consensus (ann/smm)            24.00  31220.70      34.0   \n",
      "10  HLA-A*01:01    1     76   86      11  AIAFAFMITGL  Consensus (ann/smm)            18.50  25431.88      15.0   \n",
      "9   HLA-A*01:01    1     78   88      11  AFAFMITGLLL  Consensus (ann/smm)            16.95  19558.44       4.9   \n",
      "11  HLA-A*01:01    1     39   49      11  GLMLIGLIWLM  Consensus (ann/smm)            19.00  25539.96      15.0   \n",
      "24  HLA-A*01:01    1     10   20      11  NDFTVSAVSRT  Consensus (ann/smm)            30.00  32713.58      41.0   \n",
      "\n",
      "        smm_ic50  smm_rank         core     name          ic50         score  rank  \n",
      "1    1918.757101       3.3  NWMAQLGPWNY  Rv0011c   2101.318550   2101.318550   1.0  \n",
      "0    1774.271187       3.1  WMAQLGPWNYA  Rv0011c   4477.800594   4477.800594   2.0  \n",
      "2    1610.719810       2.9  LIWLMVFQLAA  Rv0011c   7659.639905   7659.639905   3.0  \n",
      "3    4853.108490       8.0  WLMVFQLAAIG  Rv0011c  13000.349245  13000.349245   4.0  \n",
      "4    1548.887946       2.7  GLIWLMVFQLA  Rv0011c  13202.288973  13202.288973   5.0  \n",
      "5    6486.643050      12.0  MLIGLIWLMVF  Rv0011c  13736.996525  13736.996525   6.0  \n",
      "6    3221.217130       5.2  LIGLIWLMVFQ  Rv0011c  14795.053565  14795.053565   7.0  \n",
      "7   12942.554427      21.0  LMLIGLIWLMV  Rv0011c  16615.522214  16615.522214   8.0  \n",
      "8   17539.612729      26.0  WFVSLFIGLML  Rv0011c  17952.806364  17952.806364   9.0  \n",
      "18   4168.885815       6.8  LGPWNYAIAFA  Rv0011c  18776.092907  18776.092907  10.0  \n",
      "13   7852.717969      14.0  AQLGPWNYAIA  Rv0011c  19536.708984  19536.708984  11.0  \n",
      "10  14093.537001      22.0  AIAFAFMITGL  Rv0011c  19762.708500  19762.708500  12.0  \n",
      "9   20750.090729      29.0  AFAFMITGLLL  Rv0011c  20154.265365  20154.265365  13.0  \n",
      "11  15206.175552      23.0  GLMLIGLIWLM  Rv0011c  20373.067776  20373.067776  14.0  \n",
      "24  11376.796767      19.0  NDFTVSAVSRT  Rv0011c  22045.188384  22045.188384  15.0  \n",
      "        peptide  pos     name  alleles         ic50         mean  median_rank         core\n",
      "6   GPWNYAIAFAF    1  Rv0011c        2  1464.115691  1517.820942          1.0  GPWNYAIAFAF\n",
      "11  MLIGLIWLMVF    1  Rv0011c        2   465.893130  3007.641921          4.0  MLIGLIWLMVF\n",
      "2   FMITGLLLTMR    1  Rv0011c        2   855.544546  1952.471828          4.0  FMITGLLLTMR\n",
      "18  TVSAVSRTPMK    1  Rv0011c        2  3472.691529  5601.765903          4.0  TVSAVSRTPMK\n",
      "Rv0011c iedbmhc1 1 11 12\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f83d7d2f250>"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f83d7ddf750>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nmg5N18ybm9rbGt8zzQj3Bu5v/y7NzMzMGs87tsA1jpP0cqGtZwdjTACuj4gNwGJJTwBjgOl1jL1P\n0htAL2AbYFpEXAcgaVfgq8BuwEPAUklzgPMi4jFJh6drD24n/n8ArwP/006f5cBfcsdNwKpCn1Vk\nSx+2i4hXU34HkhWp25LNsp5QKKjfJGkiMBGgqamJ1tbWdtIxMzMz6162RNE6Hzir0DaMbMa0pvSA\n1onA4bnmmWTF5PTUZw5wRDq3LCLy6z5PAR4hK1gPAL4t6YWIOB/YHbgnImZJaomIKZKGAPtK+jPZ\nDOqnI2J1ldwOBs4FhkREVLuHiPhUPffahsfICuadgZOAayV9uK3CNSKmAdMABg0aFM3NzRt5STMz\nM7Py2RJF6ysRsSTfIKl/B8afSjbTuCD30L+AHpL2jYjHgTOA7dK54prSFbnrPyJpIPAVSRdGxGNk\nheGbImIRsEjSYKAZ+Fnuuj1S/q8D+5EVyrsDy3N9egKXSzovIpqr3NNKoF+hrR/wUmWWNeWyHqjk\nvlDSULIi+TNV4pqZmZk1pC1RtG6qCcDlvH0pwJVkuwCcHxFPdyDeBrL77gWsqzRGxIhCv0eBAwtt\nFwM7khWOK8hmYttamzoDuKadHO4HRhfajqL2etUewDtr9DEzMzNrOGUqWg+UtDZ3HGQzqkOA0yLi\n0XxnSbOAKZImR8Tr7cR9l6Qmsns9kKzgnB8RL7WXTESsA96yJ6ykF9O5Svtz6ZPv8xqwMs3iVtqu\nA56OiC+kpu8B50j6OvBD4EjgZODY3JhLgDlk62F3JJtxHgHkt8UyMzMz2yqUqWi9u3C8Afgu8HCx\nYE1uAaaSzVje2k7cykzoBrKHoX5BtlfrljQAeKNyEBFPSjoW+AZZEf0UcEZEzM2N2R24jmyP2TXA\n74GjI+LOLZa1mZmZWUmoneeHrJsaNGhQ/P73v+/qNMzMzMxqkrQwIg6p1a+77NNqZmZmZlsxF61m\nZmZmVnouWs3MzMys9Fy0mpmZmVnpuWg1MzMzs9Jz0WpmZmZmpVemfVrNuqW99tqL1atXd3UaZmZm\nDc1Fq9kmWr16Ne8dehi79m3q6lTMzMy6nTtvvLaufi5azTaDXfs2Mf78i7s6DTMzs26n3qLVa1rN\nzMzMrPRctJqZmZlZ6bloNTMzM7PSc9FqZmZmZqXnotXMzMzMSs9Fq5mZmZmVnotWMzMzMyu9Ti1a\nJU2XNLuN9hGSQtIu+e81YvWXtF7S4jqv3ZziVj7rJS2RNFmS2ujfUiXOGEmPSlon6Q+SRhfOR5XP\nv9fIb4SkRZL+lvIaVzj/BUkPSFor6RlJsyXtV8+9m5mZmTWa7jTTOg64EdhJ0rAOjBsFvBvYB/gS\ncAFwOoCkfSWNzXeWNETScen7cGAWcDXwfmA2MFvSAbkh7y58TgcC+Em1hCTtBdwGzAcGA98ErpJ0\ndK7bh4HvAB8EjgK2Ae6Q1LsD925mZmbWELrFG7HSzOh44GzgKWACsKDO4c9FxMr0fZmk8cAQskJ0\nNTBS0onALpIuAoYBn0v9zwVuj4jL0vEXJR0FnAOcCZCLXcn1E8D8iHiinZzOBJ6MiEnp+BFJh6fr\nzk1xjynEHQc8AxwM3F3nvZuZmZk1hO4y0zoS2B6YB8wExm7MjKOkQ8iKvgUAEfF8RHwmxT0IGBgR\nR0fEw2nIoelc3tzU3lb8fsCxZAVxvr1F0vRcU4fiJjunv8+308fMzMysIW2JmdbjJL1caOvZwRgT\ngOsjYgOwWNITwBhgeh1j75P0BtCL7Cf2aRFxHYCkXYGvArsBDwFLJc0BzouIx4AmYFUh3qrU3pb/\nC6wF/l+hfTnwl9xxtbg7SdouIl7Nn5DUg2wJwb0R0eaaXkkTgYkATU1NtLa2VknRNreRI0ey98Bm\ner78bFenYmZm1rC2RNE6Hzir0DaMbMa0pvSA1onA4bnmmWSF7PTUZw5wRDq3LCL2z/U9BXiErGA9\nAPi2pBci4nxgd+CeiJglqSUipkgaAuwLPFb/Lb7pdOBHEbEu3xgRn9qIWHnfSbkfXq1DREwDpgEM\nGjQompubN/GSVq/58+ezbrs+DNuhb1enYmZm1rC2RNH6SkQsyTdI6t+B8acC2wILcg/9C+ghad+I\neBw4A9gunXutMH5F7vqPSBoIfEXShWk29S3FaUQsAhalw5VAv0K8fqn9LSQdAexHViTXUi3uS23M\nsk4FjgM+FBFP1RHbzMzMrOF0hzWtE4DLyZ6yr3wOAu4h7QIQEU9HxJL0WVYj3gayYr1XvjEiRrTR\n937gI4W2o1J7W3kujIiHaly/rrjKTAVOAI6MiCfriGtmZmbWkMq0e8CBktbmjoNsRnUIcFpEPJrv\nLGkWMEXS5Ih4vZ2475LURHavB5LtCDA/Il6qI6dvAXdJmkS2RdVY4BDS2tFcLjuRrbGd9LYI2fnr\ngKcj4gup6XvAOZK+DvwQOBI4mewhrorvkM0yfwJYm+4BYE1xNtbMzMys0ZWpaC1u47QB+C7wcLFg\nTW4BpgKjgVvbiVt5Sn8D2cNQvyDbq7WmiLhP0qnAxcDXgD8Bx7fxMNRYsgJ7VpVQA4A3cnGflHQs\n8A2yIvop4IyImJsbU1kH3FKINZ76HkAzMzMzaxidWrRGxLgq7S1kRR5kRdnb3lBVR+yVtLMLQUS0\nbkzcNuLcBNxUo8+bD0FVOT+ijbYWshcWVBuzybmbmZmZNYrusKbVzMzMzLZyLlrNzMzMrPRctJqZ\nmZlZ6bloNTMzM7PSc9FqZmZmZqXnotXMzMzMSq9M+7SadUuvvPIKzz+7kmsundzVqZiZmTUsF61m\nm8Fv75oH8ta6ZmZmncVFq9km6tu3LweN+BgTzr+4q1MxMzPrdsYO2bOufl7TamZmZmal56LVzMzM\nzErPRauZmZmZlZ6LVjMzMzMrPRetZmZmZlZ6LlrNzMzMrPRctJqZmZlZ6bloNTMzM7PS69SiVdJ0\nSbPbaB8hKSTtkv9eI1Z/SeslLd6IPOZK2iBpaDt9Wtpo+4KkByStlfSMpNmS9qsyXpLmpHs5vo6c\nxkh6VNI6SX+QNDp3bhtJ/5XaX5H0Z0nXSfqHOm/ZzMzMrKF0p5nWccCNwE6ShtU7SNIAYDgwFTi9\ncO4wSaMKbaMkDU+HHwa+A3wQOArYBrhDUu82LnUeEHXmNByYBVwNvB+YDcyWdEDqsj0wBPhK+nsi\nsB9waz3xzczMzBpNt3iNqyQB44GzgaeACcCCOoePB34OfBf4taTPR8Sr6dxy4ApJJwI7SroS2A2Y\nBBARxxTyGAc8AxwM3J1rH5zGHAL8pY6czgVuj4jL0vEXJR0FnAOcGRFryIrk/LXPAX4jaUBELK/z\n3s3MzMwaQneZaR1JNvs4D5gJjK0y2/kWuWJ3ZkQ8CiwBTqqcj4gVETEGWEM2o/liRJwcESuqhNw5\n/X0+d43tgR8Dn42IlVXyaJV0Ya7p0HQveXNTezU7k83kvthOHzMzM7OGtCVmWo+T9HKhrWcHY0wA\nro+IDcBiSU8AY4DpNcaNIit256bjmSnWDABJewCXAy8Ai4BdJV0PTIqIp/OBJPUAvgncGxH5dbXf\nAO6LiJ+2k8dSYHXuuAlYVeizKrW/jaRtgf8CZkXES1X6TAQmAjQ1NdHa2tpOOrY5HXHEEfQf2EzP\nl5/t6lTMzMwa1pYoWucDZxXahpEVkDWlB7ROBA7PNVeKz+mpzxzgiHRuWUTsn76fDtwQEa+n41nA\nZZIGRsRSoBm4KiLmSWqJiLPSGtdm4C1FK9na1gPyeUj6OHAk2brUqiLiI/Xca1skbUO2lle8/d8x\nf41pwDSAQYMGRXNz88Ze0jronnvu4aCeO3DoDn27OhUzM7OGVXfRKulwYJ+IuEZSX2CHiHiyjqGv\nRMSSQqz+HcjxVGBbYEH2a38WAughad+IeBw4A9gunXstXaMPcAKwjaR8sdeTrJi9ICLuLV4sIoo/\n2yNpKnAc8KGIeCp36khgIPBiLjeAn0i6JyJGVLmnlUC/Qlu/1J6/bqVgfQ9wZLVZVjMzM7NGV1fR\nKulLZA8Z7QdcQ/YU/UzgsM5L7U0TyH7Cn15ov5Ks+Dy/+FN+chrZQ1vF7ac+CkySNCUtNwCgrQIz\nrYn9NlnxO6KNIv1S4KpC2x+AzwE/q35L3A98hGy5QcVRqb1y7UrBug8wMiKeayeemZmZWUOrd6b1\nBLKfwBcBRMSfJe24mXM5UNLa3HGQzagOAU5LD1K9SdIsYIqkybmf//MmADcX1p8iaQVwCXAMcFuN\nnL5DNtP7CWCtpMqa0zUR8Wp68Ko4OwqwPF/gSvolcEtETE1N3wLukjQp5TCW7P8UTEz9twFuTvd+\nHNAzd+3nI2J9jbzNzMzMGkq9uwesj4gg7UNaz5P7G+Fu4Le5z0KywvPhYsGa3ALsDowunpB0MHAQ\n8JPiubSd1C9T7FrOIntqv4VsK6vK55Q6xuYNJNtKq5LDfWTF8ETgIbIdDY7PFdh7AB8H+gO/K1x7\nOGZmZmZbmXpnWm+U9H1gF0mfJvtZ/ge1BkXEuCrtLWSzqJAVhGqrX43YK6myC0FELGwvZkS8rdCt\n0m9j8nrbmIhobqPtJuCmKjFa2Yh/EzMzM7NGVVfRGhH/nTa/f4lsXeuUiLizUzMzMzMzM0vq3j0g\nFakuVM3MzMxsi2u3aE0PRkVbp4CIiJ06JSszMzMzs5x2i9aI2Nw7BJiZmZmZdVi9uwcg6XBJ49P3\n3STt1XlpmZmZmZn93ca+XKAXW+7lAmal9uKLL/L8syu5+tLJXZ2KmZlZwyrTywXMuiVJPPSr+fTo\nUfcPF2ZmZtZB9Rat6yMiJHXmywXMuqW9996bAQd9kDPO/0pXp2JmZtbtjBncv65+9U4NFV8uMI86\nXi5gZmZmZrY5+OUCZmZmZlZ6frmAmZmZmZWeXy5gZmZmZqXnlwuYmZmZWenVmmnt0975iHh+86Zj\nZmZmZvZ2tda0LiRbHqBcW+U4gL07KS8zMzMzszfVWh7w5qta06zrPsC2nZ2UmZmZmVleXfu0SjoD\nuAu4Hbgw/Z1Sx7jpkma30T5CUkjaJf+9Rqz+ktZLWlxPzoWxcyVtkDS0nT4tVdo/K6lV0jpJCyR9\noHD++5KWSnpV0rOSfirpvXXkNEbSoynuHySNLpw/UdIdkp5L/z6D67xdMzMzs4ZT78sFzgWGAssi\nYiTZK13XdFpWbRsH3AjsJGlYvYMkDQCGA1OB0wvnDpM0qtA2StLw9P0U4Argy8AQ4CFgrqTdc0MW\nAuOB9wFHky2duENSz3ZyGg7MAq4m+7ecDcyWdECuW2/gV8B/1HuvZmZmZo2q3qJ1XUSsA5D0zoh4\nlOwlA1uEJJEVhjOAHwMTOjB8PPBz4LvAv0raLnduOfAZSVcCO6a/E4EV6fzngR9ExDUR8TBwJvBX\ncsVvREyLiLsjojUiFgGTgT2B5nZyOhe4PSIui4hHIuKLwCLgnFzcGRFxEdnbx8zMzMy2avUWrU+l\nn+9nA3dK+imwrPPSepuRwPZkBdxMYKyk3rUG5YrdmanQXgKcVDkfESsiYgzZrPEQ4MWIODkiVkjq\nBRxMrmiMiDfS8aFVrtc7Xe9J/l74kpYXXJjreihvL0bnVotrZmZmtrWr9zWuJ6SvF0qaD+xMtq61\nHsdJernQVvWn8yomANdHxAZgsaQngDHA9BrjRpEVu3PT8cwUawaApD2Ay4EXyGY6d5V0PTCJbHeE\nnsCqQsxVwFvWrEo6G/g62U/6jwFHRcT6XJelwOrccVOVuE017qcqSRPJZolpamqitbV1Y0NZBw0d\nOpQ+e74HrX22q1MxMzNrWHW/xrUiIu7q4JD5wFmFtmFkBWRNaYb3RODwXHOl+Jye+swBjkjnlkXE\n/un76cANEfF6Op4FXCZpYEQsJfsJ/6qImCepJSLOSmtcm8lmS+v1I7JX3L4b+DfgRkmHVZZURMRH\nOhBro0TENGAawKBBg6K5ubmzL2nJAw88wID1PTlsx75dnYqZmVnD6nDRuhFeiYgl+QZJ/Tsw/lSy\nbbYWZL/2ZyGAHpL2jYjHgTOAylrV19I1+gAnANtIyhfNPcmK2Qsi4t7ixSJiXhrfC9gA9Ct06Qes\nLIxZQ7bE4E+Sfk02c3sCWZHclpX1xDUzMzOzTL1rWrvSBLKf8AfnPgcB95AeiIqIpyNiSfpU1tqe\nBjyV+ubHTgLGFZ/uj4gRheP1ZDsDvDlLKqlHOr6/nXyVPu9sp8/9+bjJUTXimpmZmW21tsRMa70O\nlLQ2d1x589YQ4LT0INWbJM0CpkianPv5P28CcHNELC6MWwFcAhwD3FYjpyuAayU9CPwGOI9s3eo1\nKdbewCnAHcCzQH/gfOBV4Be5a/4SuCUipqambwF3SZqUchgLHEJak5rG9AEGAP+QmvZLM80rI8Iz\nsmZmZrZVKdNM693Ab3OfhWSF58PFgjW5BdgdGF08IelgshnWnxTPpZ/yf0kd22ZFxA1ka1QvAn5H\nNlN7TERUHqJaR7aW9hdkOxPcAKwFhkfEM7lQA4HdcnHvI1v2MJFs79eTgOMLBfbHyf4dKoX19en4\nzFp5m5mZmTWaTp1pjYhxVdpbyGZRAfLfOxJ7JVV2IYiIhe3FjIi3Fbrt9J1K9mKCts79mTaK5jb6\nNbfRdhNwUztjplN7dwQzMzOzrUKZZlrNzMzMzNrkotXMzMzMSs9Fq5mZmZmVnotWMzMzMys9F61m\nZmZmVnpl2qfVrFt65JFH2L7fAL7/1f/s6lTMzMwalotWs83gj7/5FT16+n9OZmZmncX/lTXbDI44\n7iTGn39xV6dhZmbW7Zw6ZM+6+nlNq5mZmZmVnotWMzMzMys9F61mZmZmVnouWs3MzMys9Fy0mpmZ\nmVnpuWg1MzMzs9Jz0WpmZmZmpeei1czMzMxKr1OLVknTJc1uo32EpJC0S/57jVj9Ja2XtHgj8pgr\naYOkoe30aanS/llJrZLWSVog6QO5c30kfVvSY5JelbRc0v9I2rmOnMZIejTF/YOk0YXzJ0q6Q9Jz\n6d9ncAdu2czMzKyhdKeZ1nHAjcBOkobVO0jSAGA4MBU4vXDuMEmjCm2jJA1P308BrgC+DAwBHgLm\nSto9df+H9Pk34ICU4zHA1TVyGg7MSv3eD8wGZks6INetN/Ar4D/qvVczMzOzRtUtilZJAsYDM4Af\nAxM6MHw88HPgu8C/Stoud2458BlJVwI7pr8TgRXp/OeBH0TENRHxMHAm8FdS8RsRiyPiXyLiZxGx\nNCL+F7gA+GdJ7b0i91zg9oi4LCIeiYgvAouAcyodImJGRFwEzOvAvZqZmZk1pG5RtAIjge3JCriZ\nwFhJvWsNyhW7MyPiUWAJcFLlfESsiIgxwBqymdQXI+LkiFghqRdwMLmiMSLeSMeHtnPZnYGXIuL1\nXB6tki7M9TmUtxejc2vENTMzM9tqtTcbuLkcJ+nlQlvPDsaYAFwfERuAxZKeAMYA02uMG0VW7M5N\nxzNTrBkAkvYALgdeIJvp3FXS9cAkIFKeqwoxVwHvbetiknYDvghMK5xaCqzOHTdVidtU436qkjSR\nbJaYpqYmWltbNzaUddBHP/pR3jewmZ4vP9vVqZiZmTWsLVG0zgfOKrQNIysga0oPaJ0IHJ5rrhSf\n01OfOcAR6dyyiNg/fT8duCE36zkLuEzSwIhYCjQDV0XEPEktEXFWWuPaDDxZ9x1mOewE3AY8DFyY\nPxcRH+lIrI0REdNIxfKgQYOiubm5sy9pyR133EHs8m6G7dC3q1MxMzNrWFuiaH0lIpbkGyT178D4\nU4FtgQXZr/1ZCKCHpH0j4nHgDKCyVvW1dI0+wAnANpLyRXNPsmL2goi4t3ixiJiXxvcCNgD9Cl36\nASsL97MjcDuwFjghIl6rcU8r64lrZmZmZpnusKZ1AtlP+INzn4OAe/j7A1FPR8SS9FmWxp0GPJX6\n5sdOAsZJessShYgYUTheDywE3pwlldQjHd+fa9sJuANYD3w8ItbVcU/35+MmR+XjmpmZmdnfbYmZ\n1nodKGlt7jjIZlSHAKelB6neJGkWMEXS5PxDTzkTgJsjYnFh3ArgErKtqW6rkdMVwLWSHgR+A5xH\nthXVNSlWpWDdHvgk2XZcO6Wxz6Y1uEj6JXBLRExN574F3CVpUsphLHAIaU1qGtMHGEC2pRbAfmmm\neWVEeEbWzMzMtiplKlrvLhxvINum6uFiwZrcQrb36mjg1vwJSQeTzbB+ujgoItakInICNYrWiLhB\nUl/gIrKHpH4HHBMRlYeohpCtz4VsZ4K8vYDW9H0gsFsu7n2STgUuBr4G/Ak4vlBgf5xUHCfXp79f\nprBm1szMzKzRdWrRGhHjqrS3kM2iAuS/dyT2SqrsQhARC9uLGRGjq51ro+9UsuK4rXMt7V0n16+5\njbabgJvaGTOd2rsjmJmZmW0VusOaVjMzMzPbyrloNTMzM7PSc9FqZmZmZqXnotXMzMzMSs9Fq5mZ\nmZmVnotWMzMzMyu9Mu3TatZtPf/sSq65dHJXp2FmZtawXLSabQYL58/t6hTMzMwamotWs030vve9\njwEHfZAzzv9KV6diZmbW7YwZ3L+ufl7TamZmZmal56LVzMzMzErPRauZmZmZlZ6LVjMzMzMrPRet\nZmZmZlZ6LlrNzMzMrPRctJqZmZlZ6XVq0SppuqTZbbSPkBSSdsl/rxGrv6T1khZvRB5zJW2QNLSd\nPi1V2j8rqVXSOkkLJH2gcH6qbx2JAAAFiklEQVSipBZJL9VzH7lxIyQtkvQ3SUskjSuc/5Ckn0n6\nc4p7fD1xzczMzBpRd5ppHQfcCOwkaVi9gyQNAIYDU4HTC+cOkzSq0DZK0vD0/RTgCuDLwBDgIWCu\npN1zQ7YHbge+1oGc9gJuA+YDg4FvAldJOjrXrXe63mfrjWtmZmbWqLrFG7EkCRgPnA08BUwAFtQ5\nfDzwc+C7wK8lfT4iXk3nlgNXSDoR2FHSlcBuwKR0/vPADyLimpTHmcCxZMXvpQAR8c10bkQHbulM\n4MmIqFznEUmHA58D5qa4c4A5KXYHQpuZmZk1nu4y0zqSbEZzHjATGCupd61BuWJ3ZkQ8CiwBTqqc\nj4gVETEGWEM2k/piRJwcESsk9QIOTtes9H8jHR/akeTT8oHpuaZD83GTuR2Na2ZmZra12BIzrcdJ\nernQ1rODMSYA10fEBmCxpCeAMcD0GuNGkRW7c9PxzBRrBoCkPYDLgReARcCukq4nm2mNlOeqQsxV\nwHs7mP9y4C+546YqcXeStF1uJrhukiYCEwGamppobW3taAjbSEOHDqXPnu9Ba5/t6lTMzMwa1pYo\nWucDZxXahpEVkDWlB5tOBA7PNVeKz+mpzxzgiHRuWUTsn76fDtwQEa+n41nAZZIGRsRSoBm4KiLm\nSWqJiLPSGtdm4Mm677CGiPjU5orVzjWmAdMABg0aFM3NzZ19SUseeOABBqzvyWE79u3qVMzMzBrW\nlihaX4mIJfkGSf07MP5UYFtgQW5tp4AekvaNiMeBM4Dt0rnX0jX6ACcA20jKF809yYrZCyLi3uLF\nImJeGt8L2AD0K3TpB6zsQP5tWVkl7ksbM8tqZmZm1ui6w5rWCWQ/4Q/OfQ4C7iHtBhART0fEkvRZ\nlsadRvbQ1kGFsZOAcZLeskQhIkYUjtcDC4GPVNok9UjH92/iPd2fj5sctRnimpmZmTWkMu0ecKCk\ntbnjIJtRHQKclh6kepOkWcAUSZNzP//nTQBujojFhXErgEuAY8i2nWrPFcC1kh4EfgOcR7YV1TW5\neE1ka1T/sXAfyyPi+dTnOuDpiPhC6vM94BxJXwd+CBwJnEy2M0El7g65mAB7SRoMPB8Ry2vkbWZm\nZtZQylS03l043kC2TdXDxYI1uYVs79XRwK35E5IOJpth/XRxUESskfRLsqK23aI1Im6Q1Be4iKww\n/R1wTETkH6I6E/hSG/cxnr8/KDYAeCMX90lJxwLfAM4lmxE+IyLm5uIcQrYeuOKK9Pdasj1rzczM\nzLYanVq0RsS4Ku0tZLOoAPnvHYm9kiq7EETEwvZiRsToDlxnKllxXO38hcCFNWKMaKOtBXh/O2Na\n2Ih/FzMzM7NG1B3WtJqZmZnZVs5Fq5mZmZmVnotWMzMzMys9F61mZmZmVnouWs3MzMys9Fy0mpmZ\nmVnplWmfVrNu6/lVf+GqS7/Y1WmYmZk1LEVEV+dgm1l6I9djXZ2HmZmZWR3eExF9a3XyTGtjeiwi\nDunqJMzMzMw2F69pNTMzM7PSc9FqZmZmZqXnorUxTevqBMzMzMw2Jz+IZWZmZmal55lWMzMzMys9\nF60NRtIxkh6TtETS+V2dj5mZmdnm4OUBDURST+Bx4CjgKeAB4F8j4uEuTczMzMxsE3mmtbF8AFgS\nEU9ExHrgeuATXZyTmZmZ2SZz0dpY9gBW5I6fSm1mZmZm3ZqLVjMzMzMrPRetjeVpYM/ccf/UZmZm\nZtatuWhtLA8A+0jaS1IvYCxwaxfnZGZmZrbJ3tHVCdjmExGvSzoHmAv0BH4YEX/s4rTMzMzMNpm3\nvDIzMzOz0vPyADMzMzMrPRetZmZmZlZ6LlrNzMzMrPRctJqZmZlZ6bloNTMzM7PSc9FqZmZmZqXn\notXMzMzMSs9Fq5mZmZmV3v8HsEdqULizkWEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f83d7d257d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "reload(base)\n",
    "#check we can still get binders using path only\n",
    "#p='tepitope'\n",
    "p='iedbmhc1'\n",
    "path='../mtb_results/%s/' %p\n",
    "P=base.get_predictor(p)\n",
    "fname = '../results/%s/Rv0011c.csv' %p\n",
    "P.load(path=fname)\n",
    "print len(P.data)\n",
    "print P.data[:15]\n",
    "b = P.get_binders(cutoff=.95)\n",
    "x=P.promiscuous_binders(b, n=2)\n",
    "print x\n",
    "\n",
    "plotting.plot_tracks([P],name='Rv0011c',cutoff=.95,n=2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "path='../zaire_test/tepitope/'\n",
    "files = glob.glob(os.path.join(path, '*.csv'))\n",
    "P=base.get_predictor('tepitope')\n",
    "tempdata = base.results_from_csv(path, file_limit=100)\n",
    "cuts = P.get_allele_cutoffs(tempdata, 5.0)\n",
    "\n",
    "P=base.get_predictor('tepitope')\n",
    "P.load(path=path)\n",
    "res1 = P.get_binders(cutoff_method='score', cutoff=6  )\n",
    "print res1[40:50]\n",
    "P=base.get_predictor('tepitope')\n",
    "res2 = P.get_binders(path=path, cutoff_method='score', cutoff=6 )\n",
    "print res2[40:50]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2607\n"
     ]
    }
   ],
   "source": [
    "def results_to_hdf(files):\n",
    "    for f in files:\n",
    "        df=pd.read_csv(f,index_col=0).reset_index()\n",
    "        n=os.path.splitext(os.path.basename(f))[0]\n",
    "        #print n\n",
    "        df.to_hdf('test.hdf5', key='results', mode='a') \n",
    "\n",
    "#results_to_hdf(files[:1000])\n",
    "\n",
    "df=pd.read_hdf('test.hdf5','results')\n",
    "print len(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cached file found\n",
      "cached file found\n",
      "tepitope\n",
      "         name  score  binders\n",
      "188    Rv0194   4.75       78\n",
      "2007  Rv2048c   4.85       76\n",
      "977    Rv0987   4.80       69\n",
      "3727  Rv3823c   5.20       67\n",
      "196   Rv0202c   5.12       67\n",
      "3807   Rv3910   4.76       66\n",
      "500    Rv0507   5.10       63\n",
      "3700   Rv3795   4.40       62\n",
      "669   Rv0676c   5.05       62\n",
      "95     Rv0101   4.60       60\n",
      "mhcflurry\n",
      "        name        score  binders\n",
      "90    Rv0194  1125.729577        8\n",
      "245  Rv1258c   570.995621        7\n",
      "282  Rv2048c  1077.257869        6\n",
      "113  Rv0236c   630.997108        5\n",
      "457   Rv3158  1311.639817        5\n",
      "456   Rv3157   540.972151        5\n",
      "35    Rv0083   490.419022        5\n",
      "47    Rv0102  1759.127012        5\n",
      "21    Rv0051  1876.516231        5\n",
      "98   Rv0206c   774.351574        5\n"
     ]
    }
   ],
   "source": [
    "reload(base)\n",
    "\n",
    "path='../mtb_results'\n",
    "name = 'Rv0019c'\n",
    "\n",
    "def get_summary_tables(path, limit=None, **kwargs):\n",
    "    \"\"\"Get binder results summary for all proteins in path.\n",
    "    Args:\n",
    "        path: path to results\n",
    "    \"\"\"\n",
    "\n",
    "    data = web.get_results_tables(path, view='promiscuous', **kwargs)\n",
    "    for i in data:\n",
    "        #seqs = web.get_sequences(P)\n",
    "        print i\n",
    "        x = data[i].groupby('name').agg({'peptide':np.size,'score':np.median}).reset_index()\n",
    "        x = x.rename(columns={'peptide':'binders'})\n",
    "        #x['binder_density'] = x.length/x.\n",
    "        x = x.sort_values(by='binders',ascending=False)\n",
    "        print x[:10]\n",
    "    return data\n",
    "\n",
    "d = get_summary_tables(path, n=3, cutoff=.95)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "predictions done for 5 sequences in 8 alleles\n",
      "        peptide       core  pos  score  name         allele  rank\n",
      "0   MRRVILPTAPP  MRRVILPTA    0  -0.08     0  HLA-DRB1*0101   1.0\n",
      "17  YPVRSNSTIAR  VRSNSTIAR   17  -0.16     0  HLA-DRB1*0101   2.0\n",
      "18  PVRSNSTIARG  VRSNSTIAR   18  -0.16     0  HLA-DRB1*0101   2.0\n"
     ]
    }
   ],
   "source": [
    "reload(tepitope)\n",
    "reload(base)\n",
    "seqs = peptutils.create_random_sequences(500, length=11)\n",
    "#for i in seqs[:100]:\n",
    "#    print i\n",
    "\n",
    "m2alleles = base.get_preset_alleles('mhc2_supertypes')\n",
    "P = ep.get_predictor('tepitope')\n",
    "#x1 = P.predict_peptides(seqs[:20], alleles=m2alleles)\n",
    "x=P.predict_proteins(prots, alleles=m2alleles)\n",
    "print x[:3]\n",
    "#x2 = P._predict_peptides(seqs[:20], alleles=m2alleles)\n",
    "#print len(x1), len(x2)\n",
    "#print x1.equals(x2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "halleles=['HLA-A*23:01']\n",
    "seqs = peptutils.create_random_sequences(10)\n",
    "P = base.get_predictor('iedbmhc1')\n",
    "print P.method\n",
    "st=time.time()\n",
    "df=sequtils.fasta_to_dataframe('Rv0011c.fa')\n",
    "r=P.predict_sequences(df, alleles=halleles, show_cmd=True)\n",
    "#P.predict_peptides(seqs, alleles=halleles, show_cmd=True, method='smm',cpus=4)\n",
    "print time.time()-st\n",
    "#print P.data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "netMHCpan -BA -f /tmp/tmp8Eakrg.pep -inptype 1 -a HLA-A02:07\n",
      "netMHCpan -BA -f /tmp/tmpWjyIOT.pep -inptype 1 -a HLA-A01:01\n",
      "netMHCpan -BA -f /tmp/tmpdiMav7.pep -inptype 1 -a HLA-B02:01\n",
      "netMHCpan -BA -f /tmp/tmpTqd_5a.pep -inptype 1 -a HLA-C02:02\n",
      "predictions done for 1 sequences in 4 alleles\n",
      "        peptide  pos                      name  alleles    score      mean  median_rank       core\n",
      "10  IAFAFMITGLL   76  NC_000962.3:c13995-13714        2   7105.3  13083.45          9.0  IAFAFMITL\n",
      "6   FTVSAVSRTPM   11  NC_000962.3:c13995-13714        1   1275.0   1275.00          1.0  FTVSAVSPM\n",
      "18  SLFIGLMLIGL   34  NC_000962.3:c13995-13714        1   7135.8   7135.80          1.0  SLFIGLMGL\n",
      "17  NWMAQLGPWNY   64  NC_000962.3:c13995-13714        1   8165.8   8165.80          1.0  WMAQGPWNY\n",
      "7   FVSLFIGLMLI   32  NC_000962.3:c13995-13714        1   7562.5   7562.50          2.0  FLFIGLMLI\n",
      "9   GLMLIGLIWLM   38  NC_000962.3:c13995-13714        1   8355.4   8355.40          3.0  GLMGLIWLM\n",
      "0   AAIGSQAPTAL   53  NC_000962.3:c13995-13714        1   9127.2   9127.20          3.0  AAIGAPTAL\n",
      "15  MAQLGPWNYAI   66  NC_000962.3:c13995-13714        1   8754.3   8754.30          4.0  MLGPWNYAI\n",
      "1   AFAFMITGLLL   77  NC_000962.3:c13995-13714        1  10382.0  10382.00          4.0  FAFMTGLLL\n",
      "14  LMLIGLIWLMV   39  NC_000962.3:c13995-13714        1   9955.3   9955.30          5.0  MLIGLIWLV\n",
      "4   FAFMITGLLLT   78  NC_000962.3:c13995-13714        1  11339.8  11339.80          6.0  FMITGLLLT\n",
      "19  SVWFVSLFIGL   29  NC_000962.3:c13995-13714        1  12472.0  12472.00          7.0  SVWSLFIGL\n",
      "2   AFMITGLLLTM   79  NC_000962.3:c13995-13714        1  13400.5  13400.50          8.0  FMITGLLLM\n",
      "13  IWLMVFQLAAI   45  NC_000962.3:c13995-13714        1  13481.2  13481.20          9.0  IMVFQLAAI\n",
      "20  WMAQLGPWNYA   65  NC_000962.3:c13995-13714        1  16403.9  16403.90         11.0  WMLGPWNYA\n",
      "11  IGLIWLMVFQL   42  NC_000962.3:c13995-13714        1  17213.4  17213.40         13.0  IIWLMVFQL\n",
      "12  IGLMLIGLIWL   37  NC_000962.3:c13995-13714        1  18541.5  18541.50         14.0  IMLIGLIWL\n",
      "3   AIAFAFMITGL   75  NC_000962.3:c13995-13714        1  18721.9  18721.90         15.0  AIAFAFMGL\n",
      "8   GLIWLMVFQLA   43  NC_000962.3:c13995-13714        1  20355.6  20355.60         17.0  GLIWVFQLA\n"
     ]
    }
   ],
   "source": [
    "reload(base)\n",
    "halleles=['HLA-A*02:07','HLA-A*01:01','HLA-B*02:01','HLA-C*02:02']\n",
    "#seqs = peptutils.create_random_sequences(20)\n",
    "P = base.get_predictor('netmhcpan')\n",
    "#P.predict_peptides(seqs, alleles=halleles)\n",
    "df=sequtils.fasta_to_dataframe('Rv0011c.fa')\n",
    "r=P.predict_sequences(df, alleles=halleles, show_cmd=True)\n",
    "#print P.data\n",
    "print P.promiscuous_binders(cutoff=.95)\n",
    "#benchmark_seqs(P, seqs, halleles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "halleles=['HLA-A*02:07']\n",
    "#seqs = peptutils.create_random_sequences(500)\n",
    "P = base.get_predictor('mhcflurry')\n",
    "res1=P.predict_peptides(seqs, alleles=halleles)\n",
    "#P.predictProteins(prots, alleles=halleles)\n",
    "\n",
    "#benchmark_seqs(P, seqs, halleles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "#seqs = peptutils.create_random_sequences(500)\n",
    "P=base.get_predictor('mhcnuggets')\n",
    "P.path = '/local/mhcnuggets'\n",
    "res2=P.predict_peptides(seqs, alleles=halleles, show_cmd=True)\n",
    "print len(res2)\n",
    "#benchmark_seqs(P, seqs, halleles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reload(base)\n",
    "def compare_predictors(p1, p2, allele, n=20, cpus=1, **kwargs):\n",
    "    seqs = peptutils.create_random_sequences(n)\n",
    "    P1 = ep.get_predictor(p1)\n",
    "    P2 = ep.get_predictor(p2)\n",
    "    res1=P1.predict_peptides(seqs, alleles=allele, cpus=cpus)   \n",
    "    res2=P2.predict_peptides(seqs, alleles=allele, cpus=cpus, **kwargs)    \n",
    "    x=res1.merge(res2,on='peptide')\n",
    "    f,ax=plt.subplots(1,2,figsize=(12,5))\n",
    "    ax=ax.flat\n",
    "    x.plot(P1.scorekey,P2.scorekey,kind='scatter',c='black',alpha=.7,ax=ax[0])\n",
    "    ax[0].set_xlabel(P1.name)\n",
    "    ax[0].set_ylabel(P2.name)\n",
    "    b1=P1.get_binders()#cutoff_method='score', cutoff=500)\n",
    "    b2=P2.get_binders()#cutoff_method='score', cutoff=500)\n",
    "    f = utilities.venndiagram([b1.peptide, b2.peptide],[P1.name,P2.name],colors=('y','b'),ax=ax[1])\n",
    "    return \n",
    "\n",
    "compare_predictors('mhcflurry', 'mhcnuggets', 'HLA-A*30:02', 100, cpus=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#df = pd.pivot_table(P.data, index='allele',values='score',columns=['pos','peptide'])\n",
    "#sns.heatmap(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure, show\n",
    "from bokeh.io import  output_notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div class=\"bk-root\">\n",
       "        <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
       "        <span id=\"60d656a7-2304-46ad-a2f6-6a4fd6018614\">Loading BokehJS ...</span>\n",
       "    </div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "\n",
       "(function(root) {\n",
       "  function now() {\n",
       "    return new Date();\n",
       "  }\n",
       "\n",
       "  var force = true;\n",
       "\n",
       "  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n",
       "    root._bokeh_onload_callbacks = [];\n",
       "    root._bokeh_is_loading = undefined;\n",
       "  }\n",
       "\n",
       "  var JS_MIME_TYPE = 'application/javascript';\n",
       "  var HTML_MIME_TYPE = 'text/html';\n",
       "  var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
       "  var CLASS_NAME = 'output_bokeh rendered_html';\n",
       "\n",
       "  /**\n",
       "   * Render data to the DOM node\n",
       "   */\n",
       "  function render(props, node) {\n",
       "    var script = document.createElement(\"script\");\n",
       "    node.appendChild(script);\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when an output is cleared or removed\n",
       "   */\n",
       "  function handleClearOutput(event, handle) {\n",
       "    var cell = handle.cell;\n",
       "\n",
       "    var id = cell.output_area._bokeh_element_id;\n",
       "    var server_id = cell.output_area._bokeh_server_id;\n",
       "    // Clean up Bokeh references\n",
       "    if (id !== undefined) {\n",
       "      Bokeh.index[id].model.document.clear();\n",
       "      delete Bokeh.index[id];\n",
       "    }\n",
       "\n",
       "    if (server_id !== undefined) {\n",
       "      // Clean up Bokeh references\n",
       "      var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
       "      cell.notebook.kernel.execute(cmd, {\n",
       "        iopub: {\n",
       "          output: function(msg) {\n",
       "            var element_id = msg.content.text.trim();\n",
       "            Bokeh.index[element_id].model.document.clear();\n",
       "            delete Bokeh.index[element_id];\n",
       "          }\n",
       "        }\n",
       "      });\n",
       "      // Destroy server and session\n",
       "      var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
       "      cell.notebook.kernel.execute(cmd);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when a new output is added\n",
       "   */\n",
       "  function handleAddOutput(event, handle) {\n",
       "    var output_area = handle.output_area;\n",
       "    var output = handle.output;\n",
       "\n",
       "    // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
       "    if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
       "      return\n",
       "    }\n",
       "\n",
       "    var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
       "\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
       "      toinsert[0].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
       "      // store reference to embed id on output_area\n",
       "      output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
       "    }\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
       "      var bk_div = document.createElement(\"div\");\n",
       "      bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
       "      var script_attrs = bk_div.children[0].attributes;\n",
       "      for (var i = 0; i < script_attrs.length; i++) {\n",
       "        toinsert[0].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
       "      }\n",
       "      // store reference to server id on output_area\n",
       "      output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
       "    }\n",
       "  }\n",
       "\n",
       "  function register_renderer(events, OutputArea) {\n",
       "\n",
       "    function append_mime(data, metadata, element) {\n",
       "      // create a DOM node to render to\n",
       "      var toinsert = this.create_output_subarea(\n",
       "        metadata,\n",
       "        CLASS_NAME,\n",
       "        EXEC_MIME_TYPE\n",
       "      );\n",
       "      this.keyboard_manager.register_events(toinsert);\n",
       "      // Render to node\n",
       "      var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
       "      render(props, toinsert[0]);\n",
       "      element.append(toinsert);\n",
       "      return toinsert\n",
       "    }\n",
       "\n",
       "    /* Handle when an output is cleared or removed */\n",
       "    events.on('clear_output.CodeCell', handleClearOutput);\n",
       "    events.on('delete.Cell', handleClearOutput);\n",
       "\n",
       "    /* Handle when a new output is added */\n",
       "    events.on('output_added.OutputArea', handleAddOutput);\n",
       "\n",
       "    /**\n",
       "     * Register the mime type and append_mime function with output_area\n",
       "     */\n",
       "    OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
       "      /* Is output safe? */\n",
       "      safe: true,\n",
       "      /* Index of renderer in `output_area.display_order` */\n",
       "      index: 0\n",
       "    });\n",
       "  }\n",
       "\n",
       "  // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
       "  if (root.Jupyter !== undefined) {\n",
       "    var events = require('base/js/events');\n",
       "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
       "\n",
       "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
       "      register_renderer(events, OutputArea);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  \n",
       "  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
       "    root._bokeh_timeout = Date.now() + 5000;\n",
       "    root._bokeh_failed_load = false;\n",
       "  }\n",
       "\n",
       "  var NB_LOAD_WARNING = {'data': {'text/html':\n",
       "     \"<div style='background-color: #fdd'>\\n\"+\n",
       "     \"<p>\\n\"+\n",
       "     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
       "     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
       "     \"</p>\\n\"+\n",
       "     \"<ul>\\n\"+\n",
       "     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
       "     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
       "     \"</ul>\\n\"+\n",
       "     \"<code>\\n\"+\n",
       "     \"from bokeh.resources import INLINE\\n\"+\n",
       "     \"output_notebook(resources=INLINE)\\n\"+\n",
       "     \"</code>\\n\"+\n",
       "     \"</div>\"}};\n",
       "\n",
       "  function display_loaded() {\n",
       "    var el = document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\");\n",
       "    if (el != null) {\n",
       "      el.textContent = \"BokehJS is loading...\";\n",
       "    }\n",
       "    if (root.Bokeh !== undefined) {\n",
       "      if (el != null) {\n",
       "        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
       "      }\n",
       "    } else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(display_loaded, 100)\n",
       "    }\n",
       "  }\n",
       "\n",
       "\n",
       "  function run_callbacks() {\n",
       "    try {\n",
       "      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
       "    }\n",
       "    finally {\n",
       "      delete root._bokeh_onload_callbacks\n",
       "    }\n",
       "    console.info(\"Bokeh: all callbacks have finished\");\n",
       "  }\n",
       "\n",
       "  function load_libs(js_urls, callback) {\n",
       "    root._bokeh_onload_callbacks.push(callback);\n",
       "    if (root._bokeh_is_loading > 0) {\n",
       "      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
       "      return null;\n",
       "    }\n",
       "    if (js_urls == null || js_urls.length === 0) {\n",
       "      run_callbacks();\n",
       "      return null;\n",
       "    }\n",
       "    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
       "    root._bokeh_is_loading = js_urls.length;\n",
       "    for (var i = 0; i < js_urls.length; i++) {\n",
       "      var url = js_urls[i];\n",
       "      var s = document.createElement('script');\n",
       "      s.src = url;\n",
       "      s.async = false;\n",
       "      s.onreadystatechange = s.onload = function() {\n",
       "        root._bokeh_is_loading--;\n",
       "        if (root._bokeh_is_loading === 0) {\n",
       "          console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
       "          run_callbacks()\n",
       "        }\n",
       "      };\n",
       "      s.onerror = function() {\n",
       "        console.warn(\"failed to load library \" + url);\n",
       "      };\n",
       "      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
       "      document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "    }\n",
       "  };var element = document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\");\n",
       "  if (element == null) {\n",
       "    console.log(\"Bokeh: ERROR: autoload.js configured with elementid '60d656a7-2304-46ad-a2f6-6a4fd6018614' but no matching script tag was found. \")\n",
       "    return false;\n",
       "  }\n",
       "\n",
       "  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.12.14.min.js\"];\n",
       "\n",
       "  var inline_js = [\n",
       "    function(Bokeh) {\n",
       "      Bokeh.set_log_level(\"info\");\n",
       "    },\n",
       "    \n",
       "    function(Bokeh) {\n",
       "      \n",
       "    },\n",
       "    function(Bokeh) {\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n",
       "    }\n",
       "  ];\n",
       "\n",
       "  function run_inline_js() {\n",
       "    \n",
       "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
       "      for (var i = 0; i < inline_js.length; i++) {\n",
       "        inline_js[i].call(root, root.Bokeh);\n",
       "      }if (force === true) {\n",
       "        display_loaded();\n",
       "      }} else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(run_inline_js, 100);\n",
       "    } else if (!root._bokeh_failed_load) {\n",
       "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
       "      root._bokeh_failed_load = true;\n",
       "    } else if (force !== true) {\n",
       "      var cell = $(document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\")).parents('.cell').data().cell;\n",
       "      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
       "    }\n",
       "\n",
       "  }\n",
       "\n",
       "  if (root._bokeh_is_loading === 0) {\n",
       "    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
       "    run_inline_js();\n",
       "  } else {\n",
       "    load_libs(js_urls, function() {\n",
       "      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
       "      run_inline_js();\n",
       "    });\n",
       "  }\n",
       "}(window));"
      ],
      "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n\n  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n    root._bokeh_onload_callbacks = [];\n    root._bokeh_is_loading = undefined;\n  }\n\n  \n\n  \n  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  var NB_LOAD_WARNING = {'data': {'text/html':\n     \"<div style='background-color: #fdd'>\\n\"+\n     \"<p>\\n\"+\n     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n     \"</p>\\n\"+\n     \"<ul>\\n\"+\n     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n     \"</ul>\\n\"+\n     \"<code>\\n\"+\n     \"from bokeh.resources import INLINE\\n\"+\n     \"output_notebook(resources=INLINE)\\n\"+\n     \"</code>\\n\"+\n     \"</div>\"}};\n\n  function display_loaded() {\n    var el = document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\");\n    if (el != null) {\n      el.textContent = \"BokehJS is loading...\";\n    }\n    if (root.Bokeh !== undefined) {\n      if (el != null) {\n        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(display_loaded, 100)\n    }\n  }\n\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n    }\n    finally {\n      delete root._bokeh_onload_callbacks\n    }\n    console.info(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(js_urls, callback) {\n    root._bokeh_onload_callbacks.push(callback);\n    if (root._bokeh_is_loading > 0) {\n      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls == null || js_urls.length === 0) {\n      run_callbacks();\n      return null;\n    }\n    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    root._bokeh_is_loading = js_urls.length;\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      var s = document.createElement('script');\n      s.src = url;\n      s.async = false;\n      s.onreadystatechange = s.onload = function() {\n        root._bokeh_is_loading--;\n        if (root._bokeh_is_loading === 0) {\n          console.log(\"Bokeh: all BokehJS libraries loaded\");\n          run_callbacks()\n        }\n      };\n      s.onerror = function() {\n        console.warn(\"failed to load library \" + url);\n      };\n      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.getElementsByTagName(\"head\")[0].appendChild(s);\n    }\n  };var element = document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\");\n  if (element == null) {\n    console.log(\"Bokeh: ERROR: autoload.js configured with elementid '60d656a7-2304-46ad-a2f6-6a4fd6018614' but no matching script tag was found. \")\n    return false;\n  }\n\n  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.12.14.min.js\"];\n\n  var inline_js = [\n    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    \n    function(Bokeh) {\n      \n    },\n    function(Bokeh) {\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.14.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.14.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.12.14.min.css\");\n    }\n  ];\n\n  function run_inline_js() {\n    \n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }if (force === true) {\n        display_loaded();\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    } else if (force !== true) {\n      var cell = $(document.getElementById(\"60d656a7-2304-46ad-a2f6-6a4fd6018614\")).parents('.cell').data().cell;\n      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n    }\n\n  }\n\n  if (root._bokeh_is_loading === 0) {\n    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n    run_inline_js();\n  } else {\n    load_libs(js_urls, function() {\n      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n      run_inline_js();\n    });\n  }\n}(window));"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "output_notebook()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds=['tepitope','netmhciipan','mhcflurry']\n",
    "for p in preds[:1]:\n",
    "    P=base.get_predictor(p)    \n",
    "    fname = '../mtb_results/%s/Rv0011c.csv' %p\n",
    "    P.load(path=fname)        \n",
    "    d=P.data\n",
    "    b=P.get_binders(cutoff=.96)\n",
    "       \n",
    "    #pl=bokeh_plot_grid(P,name='Rv0019c',palette='Blues',width=800, cutoff=.95) \n",
    "    #show(pl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_bokeh_colors(palette='Set1'):\n",
    "\n",
    "    from bokeh.palettes import brewer\n",
    "    n = len(base.predictors)\n",
    "    pal = brewer[palette][n]\n",
    "    i=0\n",
    "    clrs={}\n",
    "    for m in base.predictors:\n",
    "        clrs[m] = pal[i]\n",
    "        i+=1\n",
    "    return clrs\n",
    "\n",
    "\n",
    "def bokeh_summary_plot(df, savepath=None):\n",
    "    \"\"\"Summary plot\"\"\"\n",
    "\n",
    "    from bokeh.plotting import figure\n",
    "    from bokeh.layouts import column\n",
    "    from bokeh.models import ColumnDataSource,Range1d,HoverTool,TapTool,CustomJS,OpenURL\n",
    "\n",
    "    TOOLS = \"pan,wheel_zoom,hover,tap,reset,save\"\n",
    "\n",
    "    colors = get_bokeh_colors()\n",
    "    df=df.rename(columns={'level_0':'predictor'})\n",
    "    df['color'] = [colors[x] for x in df['predictor']]\n",
    "    p = figure(title = \"Summary\", tools=TOOLS, width=500, height=500)\n",
    "    p.xaxis.axis_label = 'binder_density'\n",
    "    p.yaxis.axis_label = 'binders'\n",
    "\n",
    "    #make metric for point sizes\n",
    "    #df['point_size'] = df.binder_density\n",
    "    source = ColumnDataSource(data=df)\n",
    "    \n",
    "    p.circle(x='binder_density', y='binders', line_color='black', fill_color='color',\n",
    "             fill_alpha=0.4, size=10, source=source, legend='predictor')\n",
    "    hover = p.select(dict(type=HoverTool))\n",
    "    hover.tooltips = OrderedDict([\n",
    "        (\"name\", \"@name\"),       \n",
    "        (\"length\", \"@length\"), \n",
    "        (\"binders\", \"@binders\"),\n",
    "        (\"binder_density\", \"@binder_density\"),\n",
    "        (\"top_peptide\", \"@top_peptide\"), \n",
    "        (\"max_score\", \"@max_score\"),        \n",
    "    ])\n",
    "    p.toolbar.logo = None\n",
    "    if savepath != None:\n",
    "        url = \"http://localhost:8000/sequence?savepath=%s&name=@name\" %savepath\n",
    "        taptool = p.select(type=TapTool)\n",
    "        taptool.callback = OpenURL(url=url)\n",
    "    \n",
    "    callback = CustomJS(args=dict(source=source), code=\"\"\"\n",
    "        var data = source.data;\n",
    "        var f = cb_obj.value\n",
    "\n",
    "        data['x'] = f\n",
    "        source.trigger('change');\n",
    "        source.change.emit();\n",
    "    \"\"\")\n",
    "\n",
    "    from bokeh.layouts import widgetbox\n",
    "    from bokeh.models.widgets import Select\n",
    "    menu = [(i,i) for i in df.columns]\n",
    "    select = Select(title='X', value='A', options=list(df.columns), width=8)\n",
    "    select.js_on_change('value', callback)\n",
    "    \n",
    "    #layout = column(p, select, sizing_mode='scale_width')\n",
    "    return p\n",
    "\n",
    "reload(web)\n",
    "data = web.get_summary_tables('../listeria')\n",
    "df = pd.concat(data).reset_index()\n",
    "\n",
    "p=bokeh_summary_plot(df, 'listeria')\n",
    "show(p)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index([u'level_0', u'level_1', u'name', u'max_score', u'top_peptide', u'binders', u'clusters', u'locus_tag',\n",
      "       u'translation', u'description', u'type', u'length', u'binder_density'],\n",
      "      dtype='object')\n",
      "[4.37186576 0.         0.         0.         0.         0.\n",
      " 0.         1.60730359 0.         0.         0.         0.\n",
      " 0.         0.         0.73293044 0.         0.         0.\n",
      " 0.         0.         0.         0.20573486 0.         0.\n",
      " 0.         0.         0.         0.         0.14144272 0.\n",
      " 0.         0.         0.         0.         0.         0.05143371\n",
      " 0.         0.         0.         0.         0.         0.\n",
      " 0.02571686 0.         0.         0.         0.         0.\n",
      " 0.         0.00642921]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<div class=\"bk-root\">\n",
       "    <div class=\"bk-plotdiv\" id=\"0fa12371-a2f5-495a-a78a-c083df4ad110\"></div>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "(function(root) {\n",
       "  function embed_document(root) {\n",
       "    \n",
       "  var docs_json = {\"88392572-1749-4b9f-bd43-e969565a3a51\":{\"roots\":{\"references\":[{\"attributes\":{\"bottom\":{\"value\":0},\"fill_color\":{\"value\":\"#036564\"},\"left\":{\"field\":\"left\"},\"line_color\":{\"value\":\"#033649\"},\"right\":{\"field\":\"right\"},\"top\":{\"field\":\"top\"}},\"id\":\"2c25c402-49a9-44f2-b973-0ad29fa719df\",\"type\":\"Quad\"},{\"attributes\":{},\"id\":\"c30e7921-b789-4993-a61a-45282d5350b3\",\"type\":\"SaveTool\"},{\"attributes\":{\"formatter\":{\"id\":\"a056482e-1794-4f81-b21f-f1e26320383e\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"caa1646e-0909-4241-a3f7-007de59ddbe4\",\"type\":\"BasicTicker\"}},\"id\":\"85a3fe6b-2a6b-4d25-8cf6-6541962c49e9\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"a056482e-1794-4f81-b21f-f1e26320383e\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"plot\":null,\"text\":\"Summary\"},\"id\":\"6acf074b-f243-4a30-b876-f5bc93169394\",\"type\":\"Title\"},{\"attributes\":{\"callback\":null,\"column_names\":[\"right\",\"top\",\"left\"],\"data\":{\"left\":{\"__ndarray__\":\"AAAAAAAA8D8+CtejcD3yP3sUrkfhevQ/uB6F61G49j/2KFyPwvX4PzQzMzMzM/s/cT0K16Nw/T+uR+F6FK7/P/YoXI/C9QBAFa5H4XoUAkA0MzMzMzMDQFK4HoXrUQRAcT0K16NwBUCQwvUoXI8GQK5H4XoUrgdAzczMzMzMCEDsUbgehesJQAvXo3A9CgtAKlyPwvUoDEBI4XoUrkcNQGdmZmZmZg5AhutRuB6FD0BSuB6F61EQQOJ6FK5H4RBAcT0K16NwEUAAAAAAAAASQJDC9ShcjxJAH4XrUbgeE0CuR+F6FK4TQD4K16NwPRRAzczMzMzMFEBdj8L1KFwVQOxRuB6F6xVAexSuR+F6FkAL16NwPQoXQJqZmZmZmRdAKlyPwvUoGEC5HoXrUbgYQEjhehSuRxlA2KNwPQrXGUBnZmZmZmYaQPYoXI/C9RpAhutRuB6FG0AVrkfhehQcQKRwPQrXoxxANDMzMzMzHUDD9Shcj8IdQFO4HoXrUR5A4noUrkfhHkBxPQrXo3AfQA==\",\"dtype\":\"float64\",\"shape\":[50]},\"right\":{\"__ndarray__\":\"PgrXo3A98j97FK5H4Xr0P7gehetRuPY/9ihcj8L1+D80MzMzMzP7P3E9CtejcP0/rkfhehSu/z/2KFyPwvUAQBWuR+F6FAJANDMzMzMzA0BSuB6F61EEQHE9CtejcAVAkML1KFyPBkCuR+F6FK4HQM3MzMzMzAhA7FG4HoXrCUAL16NwPQoLQCpcj8L1KAxASOF6FK5HDUBnZmZmZmYOQIbrUbgehQ9AUrgehetREEDiehSuR+EQQHE9CtejcBFAAAAAAAAAEkCQwvUoXI8SQB+F61G4HhNArkfhehSuE0A+CtejcD0UQM3MzMzMzBRAXY/C9ShcFUDsUbgehesVQHsUrkfhehZAC9ejcD0KF0CamZmZmZkXQCpcj8L1KBhAuR6F61G4GEBI4XoUrkcZQNijcD0K1xlAZ2ZmZmZmGkD2KFyPwvUaQIbrUbgehRtAFa5H4XoUHECkcD0K16McQDQzMzMzMx1Aw/UoXI/CHUBTuB6F61EeQOJ6FK5H4R5AcT0K16NwH0AAAAAAAAAgQA==\",\"dtype\":\"float64\",\"shape\":[50]},\"top\":{\"__ndarray__\":\"KIaUYMp8EUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGAXH3g7f5PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADL5jYcqdOc/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEb70FYVVyj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQhh/yxrCPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOK99BWFVao/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEb70FYVVmj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARvvQVhVV6Pw==\",\"dtype\":\"float64\",\"shape\":[50]}}},\"id\":\"3067b73c-85d1-4d7d-80ef-2596c701c1ea\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null},\"id\":\"72c28451-c4c3-469c-b2d0-3a3df205c0c5\",\"type\":\"TapTool\"},{\"attributes\":{\"formatter\":{\"id\":\"2e9c6b47-1213-4105-9622-814766fc1f39\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"5c52cff0-cc57-4b8f-b46b-7f3404b738b0\",\"type\":\"BasicTicker\"}},\"id\":\"300b3eda-6db8-41a9-9571-6d3580e6348c\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"5c52cff0-cc57-4b8f-b46b-7f3404b738b0\",\"type\":\"BasicTicker\"},{\"attributes\":{\"below\":[{\"id\":\"300b3eda-6db8-41a9-9571-6d3580e6348c\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"85a3fe6b-2a6b-4d25-8cf6-6541962c49e9\",\"type\":\"LinearAxis\"}],\"plot_height\":300,\"plot_width\":400,\"renderers\":[{\"id\":\"300b3eda-6db8-41a9-9571-6d3580e6348c\",\"type\":\"LinearAxis\"},{\"id\":\"6a2fb9d2-d68c-4bef-814f-30fbd250771a\",\"type\":\"Grid\"},{\"id\":\"85a3fe6b-2a6b-4d25-8cf6-6541962c49e9\",\"type\":\"LinearAxis\"},{\"id\":\"7ea8c42f-edc5-4d75-a6ed-a9ab89195c7f\",\"type\":\"Grid\"},{\"id\":\"b31d785a-5705-450e-a3ed-cb03e8fc5a2f\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"6acf074b-f243-4a30-b876-f5bc93169394\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"e6bdd75f-2ba9-421f-ac05-6e8e9caac575\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"6b603dc7-4a65-44d0-91ef-3226dff10d27\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"301fd490-ccf5-4b24-b4d8-7bbafc916744\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"c1bd4287-76ce-448e-98b1-94b09759cbc7\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"aceda83b-745b-4a73-a835-e514fbe12607\",\"type\":\"LinearScale\"}},\"id\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"callback\":null},\"id\":\"c1bd4287-76ce-448e-98b1-94b09759cbc7\",\"type\":\"DataRange1d\"},{\"attributes\":{\"plot\":{\"id\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"5c52cff0-cc57-4b8f-b46b-7f3404b738b0\",\"type\":\"BasicTicker\"}},\"id\":\"6a2fb9d2-d68c-4bef-814f-30fbd250771a\",\"type\":\"Grid\"},{\"attributes\":{\"callback\":null},\"id\":\"6b603dc7-4a65-44d0-91ef-3226dff10d27\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"2e9c6b47-1213-4105-9622-814766fc1f39\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"acdef115-5b62-4286-9e95-f8bd50ce4f25\",\"type\":\"PanTool\"},{\"attributes\":{\"data_source\":{\"id\":\"3067b73c-85d1-4d7d-80ef-2596c701c1ea\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2c25c402-49a9-44f2-b973-0ad29fa719df\",\"type\":\"Quad\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"df96cab2-c612-41e6-9a17-c0843732a84f\",\"type\":\"Quad\"},\"selection_glyph\":null,\"view\":{\"id\":\"3a363625-f15c-4758-b487-a48684faaa4e\",\"type\":\"CDSView\"}},\"id\":\"b31d785a-5705-450e-a3ed-cb03e8fc5a2f\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"aceda83b-745b-4a73-a835-e514fbe12607\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"e514aa1a-5179-44c7-afb6-008c16658b47\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"caa1646e-0909-4241-a3f7-007de59ddbe4\",\"type\":\"BasicTicker\"},{\"attributes\":{\"source\":{\"id\":\"3067b73c-85d1-4d7d-80ef-2596c701c1ea\",\"type\":\"ColumnDataSource\"}},\"id\":\"3a363625-f15c-4758-b487-a48684faaa4e\",\"type\":\"CDSView\"},{\"attributes\":{\"bottom\":{\"value\":0},\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"left\":{\"field\":\"left\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"field\":\"right\"},\"top\":{\"field\":\"top\"}},\"id\":\"df96cab2-c612-41e6-9a17-c0843732a84f\",\"type\":\"Quad\"},{\"attributes\":{},\"id\":\"301fd490-ccf5-4b24-b4d8-7bbafc916744\",\"type\":\"LinearScale\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"caa1646e-0909-4241-a3f7-007de59ddbe4\",\"type\":\"BasicTicker\"}},\"id\":\"7ea8c42f-edc5-4d75-a6ed-a9ab89195c7f\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"f170dbc8-07fd-4ba6-a594-c1f9a7168d6e\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"acdef115-5b62-4286-9e95-f8bd50ce4f25\",\"type\":\"PanTool\"},{\"id\":\"f170dbc8-07fd-4ba6-a594-c1f9a7168d6e\",\"type\":\"WheelZoomTool\"},{\"id\":\"8c7d575e-c231-47fb-b790-23898110b98c\",\"type\":\"HoverTool\"},{\"id\":\"72c28451-c4c3-469c-b2d0-3a3df205c0c5\",\"type\":\"TapTool\"},{\"id\":\"e514aa1a-5179-44c7-afb6-008c16658b47\",\"type\":\"ResetTool\"},{\"id\":\"c30e7921-b789-4993-a61a-45282d5350b3\",\"type\":\"SaveTool\"}]},\"id\":\"e6bdd75f-2ba9-421f-ac05-6e8e9caac575\",\"type\":\"Toolbar\"},{\"attributes\":{\"callback\":null},\"id\":\"8c7d575e-c231-47fb-b790-23898110b98c\",\"type\":\"HoverTool\"}],\"root_ids\":[\"e6e29b5b-486d-40f9-a49a-517722ecb304\"]},\"title\":\"Bokeh Application\",\"version\":\"0.12.14\"}};\n",
       "  var render_items = [{\"docid\":\"88392572-1749-4b9f-bd43-e969565a3a51\",\"elementid\":\"0fa12371-a2f5-495a-a78a-c083df4ad110\",\"modelid\":\"e6e29b5b-486d-40f9-a49a-517722ecb304\"}];\n",
       "  root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "\n",
       "  }\n",
       "  if (root.Bokeh !== undefined) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (root.Bokeh !== undefined) {\n",
       "        embed_document(root);\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "      attempts++;\n",
       "      if (attempts > 100) {\n",
       "        console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\")\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "    }, 10, root)\n",
       "  }\n",
       "})(window);"
      ],
      "application/vnd.bokehjs_exec.v0+json": ""
     },
     "metadata": {
      "application/vnd.bokehjs_exec.v0+json": {
       "id": "e6e29b5b-486d-40f9-a49a-517722ecb304"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def bokeh_summary2(df, savepath=None):\n",
    "    \"\"\"Summary plot\"\"\"\n",
    "\n",
    "    from bokeh.plotting import figure\n",
    "    from bokeh.layouts import column\n",
    "    from bokeh.models import ColumnDataSource,Range1d,HoverTool,TapTool,CustomJS,OpenURL\n",
    "\n",
    "    TOOLS = \"pan,wheel_zoom,hover,tap,reset,save\"\n",
    "    p = figure(title = \"Summary\", tools=TOOLS, width=400, height=300)\n",
    "    source = ColumnDataSource(data=df)    \n",
    "    hist, edges = np.histogram(df.binders, density=True, bins=50)\n",
    "    print hist    \n",
    "    p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],\n",
    "        fill_color=\"#036564\", line_color=\"#033649\")\n",
    "    \n",
    "    return p\n",
    "\n",
    "data = web.get_summary_tables('../listeria')\n",
    "df = pd.concat(data).reset_index()\n",
    "print df.columns\n",
    "p=bokeh_summary2(df)\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### getting peptides from clusters - standardise and add to workflow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       peptide  pos      name  alleles  score      mean  median_rank       core locus_tag gene  start  end  \\\n",
      "0  CRFNTTLISKI  245  ZEBOVgp7        9   7.20  5.041358          1.0  CRFNTTLIS  ZEBOVgp7    L    245  256   \n",
      "1  FRLMRTNFLIK  200  ZEBOVgp1        9   7.52  4.584448          7.0  FRLMRTNFL  ZEBOVgp1   NP    200  211   \n",
      "\n",
      "                  n-mer  hydro  net_charge  \n",
      "0  KDLITCRFNTTLISKIAEIE   0.40           0  \n",
      "1  HMMVIFRLMRTNFLIKFLLI   0.55           3  \n"
     ]
    }
   ],
   "source": [
    "reload(analysis)\n",
    "P=base.get_predictor(p)    \n",
    "path = '../listeria/tepitope/'\n",
    "path = '../zaire_test/tepitope/'\n",
    "P.load(path) \n",
    "pb = P.promiscuous_binders(n=3,cutoff=.98)\n",
    "\n",
    "#print cl\n",
    "genome = sequtils.genbank_to_dataframe('../epitopepredict/testing/zaire-ebolavirus.gb',cds=True)\n",
    "\n",
    "#cl = analysis.find_clusters(pb)\n",
    "x = analysis.get_nmer(pb, genome, how='split', length=20)\n",
    "x=analysis.peptide_properties(x, 'n-mer')\n",
    "print x[:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xcl=[]\n",
    "for c in np.arange(.93,.99,.01):\n",
    "    pb = P.promiscuous_binders(n=2,cutoff=c)\n",
    "    cl = analysis.find_clusters(pb)\n",
    "    xcl.append((c,len(cl)))\n",
    "    \n",
    "plt.plot(*zip(*xcl))"
   ]
  }
 ],
 "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.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}