{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0b85a598",
   "metadata": {},
   "outputs": [],
   "source": [
    "from brian2 import *\n",
    "\n",
    "from adex_sine import *\n",
    "\n",
    "defaultclock.dt = 10 * us\n",
    "\n",
    "\n",
    "class Model:\n",
    "    # Model type flags\n",
    "    SINE = 0\n",
    "    EXP2SYN = 1\n",
    "\n",
    "    # Noise flags\n",
    "    HIGH = 0\n",
    "    LOW = 1\n",
    "    OFF = -1\n",
    "\n",
    "    # Noise parameters\n",
    "    EXCITATORY_NOISE_VARIANCE = {HIGH: 0.5*2 * nS, LOW: 0.25 * nS, OFF: 0 * nS}\n",
    "    INHIBITORY_NOISE_VARIANCE = {HIGH: 1.25*2 * nS, LOW: 0.625 * nS, OFF: 0 * nS}\n",
    "\n",
    "    # Noise mean conductance\n",
    "    EXCITATORY_CONDUCTANCE = 1 * nS\n",
    "    INHIBITORY_CONDUCTANCE = 4 * nS\n",
    "\n",
    "    DEFAULT_PARAMETERS = {\n",
    "        \"sigma_flux\" : 6.75*pA,     \n",
    "        \"c\": 85 * pF,\n",
    "        \"tau_w\": 18 * ms,\n",
    "        \"b\": 0.25 * nA,\n",
    "        \"a\": 1.3 * nS,\n",
    "        \"v_T\": -45 * mV,\n",
    "        \"v_thresh\": 0 * mV,\n",
    "        \"DeltaT\": 0.2 * mV,\n",
    "        # EQUILIBRIUM POTENTIAL\n",
    "        \"e_l\": -65 * mV,\n",
    "        \"e_ex\": 0 * mV,\n",
    "        \"e_in\": -70 * mV,\n",
    "        # CONDUCTANCES\n",
    "        \"g_l\": 3 * nS,\n",
    "        \"mu_ex\": 0 * nS,\n",
    "        \"mu_in\": 0 * nS,\n",
    "        # EXCITATORY NOISE\n",
    "        \"sigma_ex\": 0 * nS,\n",
    "        \"tau_noise_ex\": 3 * ms,\n",
    "        # INHIBITORY NOISE\n",
    "        \"sigma_in\": 0 * nS,\n",
    "        \"tau_noise_in\": 10 * ms,\n",
    "        # SINE INPUT\n",
    "        \"f\": 100 * Hz,\n",
    "        \"A\": 0 * pA,\n",
    "        \"i_injected\": 0 * pA,\n",
    "        \"v_reset\": -70 * mV,\n",
    "        # m current\n",
    "        \"g_adapt\": 10 * nS,\n",
    "        \"e_k\": -90*mV,\n",
    "        \"beta_z\": -35*mV,\n",
    "        \"gamma_z\": 4*mV,     #5\n",
    "        \"tau_z\": 100*ms,\n",
    "    }\n",
    "\n",
    "    def __init__(\n",
    "        self, n, *, stim=None, noise=None, resistance=None, additional_vars=()\n",
    "    ):\n",
    "        if resistance is None:\n",
    "            raise ValueError(\"Resistance must be specified\")\n",
    "\n",
    "        if noise is None:\n",
    "            raise ValueError(\"Noise must be specified\")\n",
    "\n",
    "        self.stim_type = stim\n",
    "        self._input_resistance = None\n",
    "        self._noise_level = None\n",
    "        self._duration = 0\n",
    "        self.recorded_vars = (\"v\",) + additional_vars\n",
    "\n",
    "        self.neurons = self.set_default(n_neuron=n)\n",
    "        self.set_resistance(resistance)\n",
    "        self.set_noise(noise)\n",
    "\n",
    "        self.spikes = None\n",
    "        self.spiker = None\n",
    "        self.synapses = None\n",
    "        self.inhib_synapses = None\n",
    "        self.smon = None\n",
    "        self.network = None\n",
    "        self.build_network()\n",
    "\n",
    "    def create_model(self):\n",
    "        return ADEX_MODEL, self.DEFAULT_PARAMETERS\n",
    "\n",
    "    def set_default(self, n_neuron):\n",
    "        model, parameters = self.create_model()\n",
    "\n",
    "        neurons = NeuronGroup(\n",
    "            n_neuron,\n",
    "            model=model,\n",
    "            method=\"Euler\",\n",
    "            name=\"neurons\",\n",
    "            threshold=\"v > v_thresh\",\n",
    "            reset=\"v = v_reset; w += b\",\n",
    "        )\n",
    "\n",
    "        for parameter, value in parameters.items():\n",
    "            neurons.__setattr__(parameter, value)\n",
    "\n",
    "        neurons.v = neurons.e_l  # remove most of transient\n",
    "\n",
    "        return neurons\n",
    "\n",
    "    def set_resistance(self, level):\n",
    "        if level == self.LOW:\n",
    "            exc_conductance = self.EXCITATORY_CONDUCTANCE\n",
    "            inhib_conductance = self.INHIBITORY_CONDUCTANCE\n",
    "\n",
    "        else:\n",
    "            exc_conductance = inhib_conductance = 0\n",
    "\n",
    "        self._input_resistance = level\n",
    "        self._set_variable(\"mu_ex\", exc_conductance)\n",
    "        self._set_variable(\"mu_in\", inhib_conductance)\n",
    "\n",
    "    def set_noise(self, level):\n",
    "        if level == self.HIGH or level == self.LOW:\n",
    "            exc_noise = self.EXCITATORY_NOISE_VARIANCE[level]\n",
    "            inhib_noise = self.INHIBITORY_NOISE_VARIANCE[level]\n",
    "\n",
    "        else:\n",
    "            exc_noise = inhib_noise = 0\n",
    "\n",
    "        self._noise_level = level\n",
    "        self._set_variable(\"sigma_ex\", exc_noise)\n",
    "        self._set_variable(\"sigma_in\", inhib_noise)\n",
    "\n",
    "    def set_injected_current(self, amplitude):\n",
    "        self._set_variable(\"i_injected\", amplitude)\n",
    "        self._set_variable(\"A\", 0 * pA)\n",
    "\n",
    "    def set_stimulus_current(self, amplitude):\n",
    "        self._set_variable(\"A\", amplitude)\n",
    "        self._set_variable(\"i_injected\", 0 * pA)\n",
    "\n",
    "    @property\n",
    "    def f(self):\n",
    "        return self.neurons.f\n",
    "\n",
    "    @f.setter\n",
    "    def f(self, new_f):\n",
    "        self._set_variable(\"f\", new_f)  # this will reset smon\n",
    "        if self.stim_type == self.EXP2SYN:\n",
    "            self.spiker.T = 1 / new_f\n",
    "\n",
    "    def run(self, duration, report=\"stdout\"):\n",
    "        self._duration = duration\n",
    "        self.network.run(duration, report=report)\n",
    "\n",
    "    def build_network(self):\n",
    "        self.smon = StateMonitor(\n",
    "            self.neurons, self.recorded_vars, record=True, name=\"smon\"\n",
    "        )\n",
    "        self.spikes = SpikeMonitor(self.neurons, name=\"spikes\")\n",
    "\n",
    "        self.network = Network(self.neurons, self.smon, self.spikes)\n",
    "\n",
    "    def _set_variable(self, name, value):\n",
    "        self.neurons.__setattr__(name, value)\n",
    "        self.reset_recording()\n",
    "\n",
    "    def reset_recording(self):\n",
    "        try:\n",
    "            self.network\n",
    "        except AttributeError:\n",
    "            return  # network not yet initialized\n",
    "\n",
    "        self.network.remove(self.smon, self.spikes)\n",
    "\n",
    "        self.smon = StateMonitor(\n",
    "            self.neurons, self.recorded_vars, record=True, name=\"smon\"\n",
    "        )\n",
    "        self.spikes = SpikeMonitor(self.neurons, name=\"spikes\")\n",
    "\n",
    "        self.network.add(self.smon, self.spikes)\n",
    "\n",
    "    @property\n",
    "    def spike_train(self):\n",
    "        return self.spikes.spike_trains()\n",
    "\n",
    "    @property\n",
    "    def firing_rate(self):\n",
    "        return self.spikes.count / self.duration\n",
    "\n",
    "    @property\n",
    "    def duration(self):\n",
    "        return self._duration\n",
    "\n",
    "    @property\n",
    "    def input_resistance(self):\n",
    "        if self._input_resistance == self.HIGH:\n",
    "            return \"HIGH\"\n",
    "        else:\n",
    "            return \"LOW\"\n",
    "\n",
    "    @property\n",
    "    def noise_level(self):\n",
    "        if self._noise_level == self.HIGH:\n",
    "            return \"HIGH\"\n",
    "        elif self._noise_level == self.LOW:\n",
    "            return \"LOW\"\n",
    "        else:\n",
    "            return \"NO\"\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"{self.neurons.N} Neurons with {self.input_resistance} input resistance and {self.noise_level} noise\"\n",
    "\n",
    "    def __str__(self):\n",
    "        return self.__repr__()\n",
    "\n",
    "    def store(self, name):\n",
    "        self.network.store(name)\n",
    "\n",
    "    def restore(self, name):\n",
    "        self.network.restore(name)\n",
    "\n",
    "    @property\n",
    "    def v(self):\n",
    "        return self.smon.v\n",
    "\n",
    "    @property\n",
    "    def t(self):\n",
    "        return self.smon.t\n",
    "\n",
    "    @property\n",
    "    def injected_current(self):\n",
    "        return self.neurons.i_injected\n",
    "\n",
    "    @property\n",
    "    def stimulus_amplitude(self):\n",
    "        return self.neurons.A\n",
    "\n",
    "\n",
    "class CurrentModel(Model):\n",
    "    def __init__(self, **kwargs):\n",
    "        super().__init__(stim=self.SINE, **kwargs)\n",
    "\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        model += CURRENT_INPUT\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "\n",
    "class SineModel(CurrentModel):\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        model += SINE_INPUT\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "\n",
    "class SawModel(CurrentModel):\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        model += SAW_INPUT\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "\n",
    "class SynapticModel(Model):\n",
    "    def __init__(self, **kwargs):\n",
    "        super().__init__(stim=self.EXP2SYN, **kwargs)\n",
    "\n",
    "    SYNAPTIC_PARAMETERS = {\n",
    "        \"tau_input_1\": 0.4 * ms,\n",
    "        \"tau_input_2\": 4 * ms,\n",
    "        \"offset_A\": 1.48793507e-11,\n",
    "        \"offset_B\": -2.66359562e-08,\n",
    "        \"offset_C\": 1.77538800e-05,\n",
    "        \"offset_D\": -8.05925810e-04,\n",
    "        \"offset_E\": -3.51463644e-02,\n",
    "        \"offset_switch\": 0,\n",
    "    }\n",
    "\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        model += EXP2SYN_WAVEFORM + SUMMATION_OFFSET\n",
    "        parameters = {**parameters, **self.SYNAPTIC_PARAMETERS}\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "    def build_network(self):\n",
    "        super().build_network()\n",
    "        self.spiker = NeuronGroup(\n",
    "            self.neurons.N,\n",
    "            \"\"\"T : second (constant)\n",
    "                                     lastspike : second\"\"\",\n",
    "            threshold=\"timestep(t-lastspike, dt)>=timestep(T, dt)\",\n",
    "            reset=\"lastspike=t\",\n",
    "        )\n",
    "        self.spiker.T = 1 / self.neurons.f\n",
    "        self.synapses = Synapses(\n",
    "            self.spiker, self.neurons, on_pre=\"input_aux += 1\"\n",
    "        )  # connect input to neurons\n",
    "        self.synapses.connect(\"i==j\")  # one synapse goes to one neuron\n",
    "\n",
    "        self.network.add(self.spiker, self.synapses)\n",
    "\n",
    "\n",
    "class SynapticCurrentModel(SynapticModel):\n",
    "    def __init__(self, offset=True, **kwargs):\n",
    "        self.offset = 1 if offset else 0\n",
    "        super().__init__(**kwargs)\n",
    "\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        model += CURRENT_INPUT + SYNAPTIC_INPUT_CURRENT\n",
    "        parameters = {**parameters, **{\"offset_switch\": self.offset}}\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "\n",
    "class SynapticConductanceModel(SynapticModel):\n",
    "    FLAT = 0\n",
    "    ACTIVE = 1\n",
    "\n",
    "    CONDUCTANCE_PARAMETERS = {\n",
    "        \"A\": 0 * nS,  # overwrite A to be conductance\n",
    "        \"g_i\": 1 * nS,\n",
    "    }\n",
    "\n",
    "    INHIBITION_PARAMETERS = {\n",
    "        \"tau_inhibition_1\": 1 * ms,\n",
    "        \"tau_inhibition_2\": 10 * ms,\n",
    "    }\n",
    "\n",
    "    def __init__(self, offset=ACTIVE, **kwargs):\n",
    "        self.offset = offset\n",
    "        super().__init__(**kwargs)\n",
    "\n",
    "    def create_model(self):\n",
    "        model, parameters = super().create_model()\n",
    "        if self.offset == self.FLAT:\n",
    "            model += CONDUCTANCE_INPUT + SYNAPTIC_CONDUCTANCE_FLAT\n",
    "            parameters = {\n",
    "                **parameters,\n",
    "                **self.SYNAPTIC_PARAMETERS,\n",
    "                **self.CONDUCTANCE_PARAMETERS,\n",
    "                **{\"offset_switch\": 1},\n",
    "            }\n",
    "\n",
    "        elif self.offset == self.ACTIVE:\n",
    "            model += CONDUCTANCE_INPUT + SYNAPTIC_CONDUCTANCE_STIM\n",
    "            parameters = {\n",
    "                **parameters,\n",
    "                **self.SYNAPTIC_PARAMETERS,\n",
    "                **self.CONDUCTANCE_PARAMETERS,\n",
    "                **self.INHIBITION_PARAMETERS,\n",
    "            }\n",
    "\n",
    "        return model, parameters\n",
    "\n",
    "    def build_network(self):\n",
    "        super().build_network()\n",
    "        if self.offset != self.ACTIVE:\n",
    "            return\n",
    "\n",
    "        self.inhib_synapses = Synapses(\n",
    "            self.spiker, self.neurons, on_pre=\"input_inhib_aux += 1\", delay=2 * ms\n",
    "        )  # connect input to neurons\n",
    "        self.inhib_synapses.connect(\"i==j\")  # one synapse goes to one neuron\n",
    "\n",
    "        self.network.add(self.inhib_synapses)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c82769f2",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING    Cannot use Cython, a test compilation failed: Microsoft Visual C++ 14.0 or greater is required. Get it with \"Microsoft C++ Build Tools\": https://visualstudio.microsoft.com/visual-cpp-build-tools/ (DistutilsPlatformError) [brian2.codegen.runtime.cython_rt.cython_rt.failed_compile_test]\n",
      "INFO       Cannot use compiled code, falling back to the numpy code generation target. Note that this will likely be slower than using compiled code. Set the code generation to numpy manually to avoid this message:\n",
      "prefs.codegen.target = \"numpy\" [brian2.devices.device.codegen_fallback]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting simulation at t=0. s for a duration of 12. s\n",
      "0.32297 s (2%) simulated in 10s, estimated 6m 2s remaining.\n",
      "0.65316 s (5%) simulated in 20s, estimated 5m 47s remaining.\n",
      "0.99935 s (8%) simulated in 30s, estimated 5m 30s remaining.\n",
      "1.34356 s (11%) simulated in 40s, estimated 5m 17s remaining.\n",
      "1.69267 s (14%) simulated in 50s, estimated 5m 5s remaining.\n",
      "2.04654 s (17%) simulated in 1m 0s, estimated 4m 52s remaining.\n",
      "2.39682 s (19%) simulated in 1m 10s, estimated 4m 41s remaining.\n",
      "2.75138 s (22%) simulated in 1m 20s, estimated 4m 29s remaining.\n",
      "3.09878 s (25%) simulated in 1m 30s, estimated 4m 19s remaining.\n",
      "3.45202 s (28%) simulated in 1m 40s, estimated 4m 8s remaining.\n",
      "3.80945 s (31%) simulated in 1m 50s, estimated 3m 57s remaining.\n",
      "4.15021 s (34%) simulated in 2m 0s, estimated 3m 47s remaining.\n",
      "4.50012 s (37%) simulated in 2m 10s, estimated 3m 37s remaining.\n",
      "4.8459 s (40%) simulated in 2m 20s, estimated 3m 27s remaining.\n",
      "5.19325 s (43%) simulated in 2m 30s, estimated 3m 17s remaining.\n",
      "5.54313 s (46%) simulated in 2m 40s, estimated 3m 6s remaining.\n",
      "5.89266 s (49%) simulated in 2m 50s, estimated 2m 56s remaining.\n",
      "6.24985 s (52%) simulated in 3m 0s, estimated 2m 46s remaining.\n",
      "6.5997 s (54%) simulated in 3m 10s, estimated 2m 35s remaining.\n",
      "6.93114 s (57%) simulated in 3m 20s, estimated 2m 26s remaining.\n",
      "7.27192 s (60%) simulated in 3m 30s, estimated 2m 17s remaining.\n",
      "7.65359 s (63%) simulated in 3m 40s, estimated 2m 5s remaining.\n",
      "8.02211 s (66%) simulated in 3m 50s, estimated 1m 54s remaining.\n",
      "8.41923 s (70%) simulated in 4m 0s, estimated 1m 42s remaining.\n",
      "8.84993 s (73%) simulated in 4m 10s, estimated 1m 29s remaining.\n",
      "9.2818 s (77%) simulated in 4m 20s, estimated 1m 16s remaining.\n",
      "9.71325 s (80%) simulated in 4m 30s, estimated 1m 4s remaining.\n",
      "10.14361 s (84%) simulated in 4m 40s, estimated 51s remaining.\n",
      "10.56934 s (88%) simulated in 4m 50s, estimated 39s remaining.\n",
      "10.9938 s (91%) simulated in 5m 0s, estimated 27s remaining.\n",
      "11.4228 s (95%) simulated in 5m 10s, estimated 16s remaining.\n",
      "11.8475 s (98%) simulated in 5m 20s, estimated 4s remaining.\n",
      "12. s (100%) simulated in 5m 24s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.collections.EventCollection at 0x202300b4670>,\n",
       " <matplotlib.collections.EventCollection at 0x202300ce5e0>,\n",
       " <matplotlib.collections.EventCollection at 0x202300e2400>,\n",
       " <matplotlib.collections.EventCollection at 0x202300f42b0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230104e20>,\n",
       " <matplotlib.collections.EventCollection at 0x20230116c40>,\n",
       " <matplotlib.collections.EventCollection at 0x20230129a30>,\n",
       " <matplotlib.collections.EventCollection at 0x2023013c850>,\n",
       " <matplotlib.collections.EventCollection at 0x2023014f5b0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230161340>,\n",
       " <matplotlib.collections.EventCollection at 0x20230170fa0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230183f10>,\n",
       " <matplotlib.collections.EventCollection at 0x20230196a30>,\n",
       " <matplotlib.collections.EventCollection at 0x202301a9850>,\n",
       " <matplotlib.collections.EventCollection at 0x202301bc5b0>,\n",
       " <matplotlib.collections.EventCollection at 0x202301ce1f0>,\n",
       " <matplotlib.collections.EventCollection at 0x202301dde80>,\n",
       " <matplotlib.collections.EventCollection at 0x202301f1e20>,\n",
       " <matplotlib.collections.EventCollection at 0x20230203bb0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230216940>,\n",
       " <matplotlib.collections.EventCollection at 0x20230229670>,\n",
       " <matplotlib.collections.EventCollection at 0x2023023c5b0>,\n",
       " <matplotlib.collections.EventCollection at 0x2023024e100>,\n",
       " <matplotlib.collections.EventCollection at 0x2023025dc40>,\n",
       " <matplotlib.collections.EventCollection at 0x202302709d0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230283520>,\n",
       " <matplotlib.collections.EventCollection at 0x20230294220>,\n",
       " <matplotlib.collections.EventCollection at 0x202302a3ee0>,\n",
       " <matplotlib.collections.EventCollection at 0x202302b7e20>,\n",
       " <matplotlib.collections.EventCollection at 0x202302cbdf0>,\n",
       " <matplotlib.collections.EventCollection at 0x202302dcbb0>,\n",
       " <matplotlib.collections.EventCollection at 0x202302efa00>,\n",
       " <matplotlib.collections.EventCollection at 0x20230304730>,\n",
       " <matplotlib.collections.EventCollection at 0x20230316520>,\n",
       " <matplotlib.collections.EventCollection at 0x20230327370>,\n",
       " <matplotlib.collections.EventCollection at 0x2023033b2b0>,\n",
       " <matplotlib.collections.EventCollection at 0x202303500a0>,\n",
       " <matplotlib.collections.EventCollection at 0x2023035dc10>,\n",
       " <matplotlib.collections.EventCollection at 0x2023036fa00>,\n",
       " <matplotlib.collections.EventCollection at 0x202303826a0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230396370>,\n",
       " <matplotlib.collections.EventCollection at 0x202303a4fa0>,\n",
       " <matplotlib.collections.EventCollection at 0x202303b7ca0>,\n",
       " <matplotlib.collections.EventCollection at 0x202303c8b20>,\n",
       " <matplotlib.collections.EventCollection at 0x202303dd910>,\n",
       " <matplotlib.collections.EventCollection at 0x202303f16d0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230403610>,\n",
       " <matplotlib.collections.EventCollection at 0x202304143d0>,\n",
       " <matplotlib.collections.EventCollection at 0x20230429190>,\n",
       " <matplotlib.collections.EventCollection at 0x20230438e50>]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXEAAAD4CAYAAAAaT9YAAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAnaElEQVR4nO2df4ym13XXvwdv4tRpl3jJ2hriiEmQZbGqRVKGKEtQZeq6DiWqAyIkESmLMNgSIKUUqVmTP9j+VTegqkKVqK02aClpuqZNsGUKW8uthSpZTsZqGjtru3bbbWIy1NMsqpuutHTbyx/z3NmzZ86999znfWd27uT7kVbzvve5P865z32v9v3e855HUkoghBAyJn/uWhtACCFkPtzECSFkYLiJE0LIwHATJ4SQgeEmTgghA3NoLwd761vfmlZXV/dySEIIGZ5nn332D1JKR71re7qJr66uYn19fS+HJISQ4RGR3ytdo5xCCCEDw02cEEIGhps4IYQMDDdxQggZGG7ihBAyMKHoFBE5D+CPAPwpgMsppTUROQLgDIBVAOcB/IOU0v/dHTMJIYR49PxP/G+llN6VUlqb3p8E8GRK6VYAT07vCSGE7CGLyCn3ADg9vT4N4IMLW0MIIaSL6CaeAPyKiDwrIvdNZTenlDYAYPp7k9dQRO4TkXURWd/c3FzcYkIIIdtEf7H5vpTS10XkJgBPiMiL0QFSSg8DeBgA1tbW+AQKQghZIqFNPKX09envayLyeQDvAfD7IrKSUtoQkRUAr+2infjwQ08DAM5tvI6Lly5jbfXIVdfPbby+/frYyuHtMv1aUyq31y5euowbrj+EYyuH3f6OrRzGmfuPb9vnoevq9xcvXQYArK0e2dGHHqvWj2dPRvd55v7jALbm0bar+VCbQ+t/5B7Y+az1E71HkfLSNTvHLf+91+vnLxTXiPda993jl54/r27Nv546Xnm0Tr7+3Km7AWDH/dTX7VrU81JaD/rzr6/X7nuJnvmy9zjSt/f52w2acoqIvFlEviO/BvB9AJ4H8BiAE1O1EwAe3S0jCSGE+ET+J34zgM+LSK7/8yml/ykiXwTwiIjcC+CrAD60e2YSQgjxaG7iKaXfAfBXnfJvALhzN4wihBASQ/byafdra2tpTipaTyfNRMrt65pOaDXlPL59H+0nqtfVtO1SPyWNsUVLC6yNbbFaqKd127H0NauTW/9qeru2oeSjvm7nKPd/+6mzO2yP3I+WfzUi2r3Grr1If54/Xp1IO63vlj5b+pp39lE7f7D6cel8KLIOWtq5p6V7fdTe57LWeZCtOxcReVb9Rucq+LN7QggZGG7ihBAyMNzECSFkYIbTxCPMiZeN6sRRfS5T0ySPrRzejj/NcbXa315dvKY5RmKWIzHNrXMAq3FbzVDHxut+avZH9EZdt/U7Ak3pvkTnoHaeYnVdz8eWxls7bwD8+exdq/be6blrrd/a+1wWieeOnHN49QAU+4+eS9mY7kgb66+NJwewPZc2dn4O1MQJIeSAwk2cEEIGhps4IYQMzBCaOLBTF+/RtG29VpxtLb62FWcKoBg7WsoNsn7+AgC4OTEiurjni41/9nwA2nHHtl0r7rjUjzd3Xh3rg6crl9r16K2tOHBLqU1tnjOR/Ds9frTOA0q5VebQOhdo0dLUW9p1VFPXY5TOi2pnGtq2kj212PfW3rRo7hRq4oQQckDhJk4IIQPDTZwQQgZmCE28pC/baz0xsa3Xlt42rZjtXKfULuvkNtd4S9uPEImJr+mQ1rdoruUeLTiiNdbaRM4qPM20FZcdIaqT2jqttiUfStdq9tX0c2/uInMS9bFmVy2nfCu+3ebfacXke/c+EnMe8be0/uZCTZwQQg4o3MQJIWRguIkTQsjADKOJZ3riQ3UeiB4dz8tt3KPreUTae3HjUS3Oapy63NpV8zWTfa7l5tD9teKJo3G1PXHJNt+77cP2V+urV6tu6a2LXPPGzmWlnOiRZ5xa+yNnEZEzgtaar50P1T5fEb2/5L9H9Aymp8/cT+2eMU6cEEJIEW7ihBAyMEPIKUD5Z/eZaLjfXKmk92u29zPdntA+7VfJZ+tDVOaYE8rXOx8ZL/wwEq5Z6791DyNtWyGlNb+1VFf7mq9p+Rddz3lNlR7HF713tdSruqzWZySEz6ZjLUl8HjpNcymtryeb9ob+eb5Zej4TXt+LSiqUUwgh5IDCTZwQQgaGmzghhAzMEJp46+ffvbpgJIQoEn6kyXrX7afOhtOB1uyI/nw4anOpvadRtuZG67JAOwTUs1ET+Yl/62wg14nqtDYUM9ftTRtb87Mn9M0L74yED9r3c88bvOveo8Y8ausp9xfRxKN6tmdj7dxJ03ves+heoUNDF4GaOCGEHFC4iRNCyMBwEyeEkIEZUhNv0YoP9h6zpOvmPqJx59pGrx+vTesnxF49q+m2tNzex5uV5qUnftjTE/P86PaReN2Srl+LMy7ZVrLVxhnXbGzZVppfqy3b8xI7ZuuMwPO/J+bf03l7YqttWeu3CnpceybRqh/9Wb5t6xG5Z6X+9WP49FlQzS7Pl7lQEyeEkAMKN3FCCBmY8CYuIteJyG+IyOPT+yMi8oSIvDz9vXH3zCSEEOIR1sRF5IcBrAE4nFL6gIh8CsCFlNKDInISwI0ppU/U+lh2nLilpSfauh5RjSvaV0vHX0Tra+mYdi5KscjRGN7ouJ7NVh/fjfhhfd3m2yjRo6Fbf7x+FrE/68UAdqRQ7tFzvbMIq+lG8/O01oPnV0kjb53R1Hyxv7/Q1+esX++3Hl690jVbp3XedM01cRG5BcDfAfAzqvgeAKen16cBfHC2hYQQQmYRlVN+EsCPAPgzVXZzSmkDAKa/N3kNReQ+EVkXkfXNzc1FbCWEEGJobuIi8gEAr6WUnp0zQErp4ZTSWkpp7ejRo3O6IIQQUqCpiYvIjwH4QQCXAbwJwGEAnwPw1wHckVLaEJEVAE+llG6r9bVMTbwVu5rLMtEYWkstL0I050ckLrc1lu27Fis8167euNvSPNV8sW0iccC1uOTaWK1Y5prPtXtmibTJj9yL5r2249n46nzdWxPenET8L+UE6sn/Unp0nJ2rHh9s254Y/Wi5dz1yphY5K9LM1cUX0sRTSg+klG5JKa0C+AiAX00pfQzAYwBOTNVOAHh0lnWEEEJms0ic+IMA7hKRlwHcNb0nhBCyhxxqV7lCSukpAE9Nr78B4M7lm0QIISTKMLlTNCWdrTeWVqPrlWJ1W22jcaWRWPae53O2WDReN6rVez56NuhnJ+b435JW7MWAe3MS1cytTx5Rzb02T5F2Vi/P93vu+LrfnmeJerr0suas5xmrdpzWuirZbCmdZwForhM9bo6zL51J1XK/5+tzYe4UQgg5oHATJ4SQgeEmTgghAzOMJl7TY7082FFNzr6vxRbnsbR+q/XzUs7yjNXKarZHdDrPB5272qtvbSlpzt582PatuNiaBlvTNj3/Sv54unm+R63Y6IjGX4u3rtGjKUe039q5QWTMVly6XY/W3lost32+rJ37ku/e/ak9M9Prw/usRfYAz36dZ8bzJ9fpXUN2nDlQEyeEkAMKN3FCCBkYbuKEEDIwQ2jiQD2eM6I11vRA+74Vq1vrs6WZ9tiR3/doorX47NKc1TRpLwe555M3bjTevjfGtzUHtbJIvHzrPs6Jw7b9l/zpefZly7+eucnoHC+le+/dbwA7tGVL5DOlqc1zVN+vPTvVOwsonWF5ucw9H7z5X1QPB6iJE0LIgYWbOCGEDMwQckrk65QmWs+r773XZZme/rxrtp9aee/X/pbM0/r6XStrSSIRmSEqj/RKCV64Zmlc/V776RGdD+1/KVTOjjVnrkt9tKSnuRKQlaB6HpVWk6ai0k/P5z76ebDj9spQLTtLts2FcgohhBxQuIkTQsjAcBMnhJCBGVYTt0S01UwrnMvWs2W1sUtovfC5U3cXU8H2hqvVynpCukp6pq4fPSuoabq10K+aLfa1V9fzqWR/ZB4jvvXq+xa7Fktj5XBN+3i20hh2nnvPcHrOhbI+nte1LS+tp9pYrfJSWGCu35pv3W80bLN1PlA7i8r150JNnBBCDijcxAkhZGC4iRNCyMAMo4kD/s96e+NcdZveOqU2VgOzNuo+vXFq2mEr5lvb5I1XmhNd5j2qytLSZCPnApbe84YeHbu2Lrx4aWvDssdt+dMT49xzLtBizn3z/GjZ7q2z6PlPptV3Ka1t7QyqNqZ+JJvXhz2DsO1Ln7M5UBMnhJADCjdxQggZGG7ihBAyMMNp4jVdKpdZrM6l+8ipN2uPd6rpbq3xWraV6nu6txcbW9K9S2O3zgF6NdJWPLHWFb04ZgBuDg7P9tr4Xt1ajHkpNtv6tAyt27OrNF7Ldm8daq1Vz3WpvSU6rle3lReldrZk23px3zoHDXD158LGp2sNHMCOMjs3PXNk58ubDy/1sv0szIWaOCGEHFC4iRNCyMBwEyeEkIEZQhMHdsaWlohouZFYXd1fNIa8NkZvnmPv8Vd2rN44W4uNo/X0RwDb+SGy1mdzZXv+RjTYUpxtJM9Gtq/02LDWWUE0b0apTq3PXiI22PFa5zNRv7K2rO8tgGJOkh5/LFHdPFo/0keJVpx+63yshM6nYrVxauKEEEJ2wE2cEEIGprmJi8ibROQLIvKbIvIVEfnRqfyIiDwhIi9Pf2/cfXMJIYRompq4iAiAN6eUvikibwDw6wA+DuDvAbiQUnpQRE4CuDGl9IlaX8vIJ97zDMeM1bWs9mvr6X5qenUtXtTLr6z78WJz7XMLWxpgxH+reXqatTcfPZqxjo8tnSnU9Gs7Zs1/S02rbGn3pb5K9tTa956beHqsztNhn2MZ7b8n3tna1Yq5b5W1fndQum5zqtTyhOe17J0Zlc6dbE7vnhz7tTnyPrMlrqkmnrb45vT2DdO/BOAeAKen8tMAPjjbQkIIIbMIaeIicp2IfAnAawCeSCk9A+DmlNIGAEx/byq0vU9E1kVkfXNzc0lmE0IIAYKbeErpT1NK7wJwC4D3iMh3RgdIKT2cUlpLKa0dPXp0ppmEEEI8uuPEReTfAvhjAP8MwB0ppQ0RWQHwVErptlrbReLErV4IlPMoz8l9Maed1cl1fGhNe2vFOutxe2LJe+bC0yJLfvXGI9fK87VaXHhvnHYkzrg3BrmkLddi0mtx6qVxPNtKNpb6szpyr13ReSzZXstvn8vs+VB0jS36ubF22DmzzyCdew4TOT+4Zpq4iBwVkbdMr78NwPcCeBHAYwBOTNVOAHh0toWEEEJm0T5WBVYAnBaR67C16T+SUnpcRJ4G8IiI3AvgqwA+tIt2EkIIcWhu4imlLwN4t1P+DQB37oZRhBBCYgyRO0XrZS2NzYsNtvTE7trx9XXvdWsM71pLh+vRiCM5WiJ48bX6LMLm2FhUoyzlltb3uTVOSevsia1vabGlOrV59GKfo5qrV27tKLWzz25t2VzT5qNj2+tzz39aMeeeb7mP0h7hEfls9caSe9euqSZOCCFk/8JNnBBCBmYoOSWjv5p4j1wC2iF60a/WvVJHqQ/vkVqtVLPWXy8drydDAOVHRNkxFpUaanOiackg0XQK+qu0d02/9uywcoudk56QSW9eamkHgJ1ruda/LS9JCFH7dLm2U8sP2kZPqsrteyQlO3YrvE9LdZ4v0TWr59yTWfU68lIctD7/NV+8fiinEEII2QE3cUIIGRhu4oQQMjBDaOKAr9MBdf2qFjJl9cVenToT1cQ9m1phWtaXWjhj5GfV3ri1OfL88GyKaoI1otp4z/3uCbPs0cJb11s6rXeOY7X+nrC22poAyhp3KW1D1KfauUZtrjSts6LaWu21xfZfexRjdNyIn/bMZA7UxAkh5IDCTZwQQgaGmzghhAzMUJp4phbDCqD6eCegrSm2fv7bg9ZBa5pn62fGkTY1GyNack98eDRuulXfnk/o+rUUp9GxAT9GXevFvfNm69fuXcnW6OPFPKKaeK1O9F7V5rHWzv5ewc6FPkexKRzseF772vlJ7XzLzpP2wfPDq9fzGdJtGSdOCCFkB9zECSFkYLiJE0LIwAyhide0w5IeOTfPQ02XrcWf6n6jscXa5holHyPzYPuvaZ+R/iI6da9trZjoZcTAe7lC7FnKsmLFa2cVVn+Nps3tta2mLbfmyFvHOjVwptWnPYPoWau9+nPpnCPr7bXHsNXstf7V7p83F9a2uVATJ4SQAwo3cUIIGRhu4oQQMjDDaOItXRcox9lGYmAjOmlPXoWo5hu1s5bnwY7t9dd6VFdLl/Z8s7Z4Gq/XPjJ2T1x5pvZovtp9qum1tn5tPiL+ev3V+tA+lWyZE0+vr5V8LtlqWcbaieQtqq0xO57XzzLOG6LryNalJk4IIcSFmzghhAwMN3FCCBmYYTbxYyuHt/8BO7Wscxuvb2tqx1YO47lTd19VH9h6hqDWpqzWlevavxHdNv+z5fqv9SHiV6aWU8OObfsDtuJks6aor5+5/7irk3s+WtutDcCV5yLmfkv26f7zPcnlFy9d3m7jjaefvZjbntt4fcczGe1Y5zZex/r5C1Vf7L0s2XHm/uPba0zXse9zXLW3FvTfbJcuA/zcI9YnrSWXNGdvTXmfIW2ntsnD+tvC1tV/c451Xa7XkO7jhusP7Zhz2zYT0aK9z45do/mvXm+6DXDleb96XWRKeVyWwTCbOCGEkJ1wEyeEkIHhJk4IIQMzTJw44OdMKWm5mYhW5+H1r/W1yDM/Pbt64lW9uNhSP9ZuXa/kW8aLr9b+1uLTra2tsRaJxbX1bRxuNL9Kq1/bNhqHHY2Xrq2ZaN+eT/b5kd6zPCP21cpa10qfm9rnpZVXpea/jjMHdn4u81xkouOUaMWV71asOOPECSHkgNLcxEXk7SLyayLygoh8RUQ+PpUfEZEnROTl6e+Nu28uIYQQTeR/4pcB/OuU0l8B8F4A/0JEjgE4CeDJlNKtAJ6c3hNCCNlDujVxEXkUwE9N/+5IKW2IyAqAp1JKt9XaLit3isXTxOx14IqGZXNv1HKEZ+w1L9dD1q/t8yI9e0t9e/a2+irp5iXbc5nXr5eXpKST9/TraZ+tea/ldG5p4JE8Ol47TWT+W33rMi9/Ta1dTUvW9WrnEhHtOuJf6WynNHbpfKdmZ2k92HaRM4Sa3aVx89nQc6fuDu85up211fq/LzRxEVkF8G4AzwC4OaW0AQDT35tmW0gIIWQW4U1cRL4dwC8B+KGUUjjkQ0TuE5F1EVnf3NycYyMhhJACITlFRN4A4HEAZ1NKPzGVvYQ9klMAP8xQ44UcRb6K2vKWnFB63/OVNBIyZ8fwQsai/er3tv+WH9EQsJotNXsi0kpECgBQDTMr+ef5WJuTaCheSXKz9ni0wih122Mrh4uPINN9lcau2a7XW6Rdzf7S3JRS7UZkFC1ReTbNuYclWqGhFy9dBuDfA+3zXBaSU0REAPwsgBfyBj7xGIAT0+sTAB6dbSEhhJBZHGpXwfsA/CCA50TkS1PZvwHwIIBHROReAF8F8KFdsZAQQkiR5iaeUvp1AFK4fOdyzSGEENLDMD+779W2PXrbR3W/UllLk52j0/WE+FlbojpxKyyuprPma1mn1W1tGKQXclj6qXiJyD2bq9OX2kQf5+bp4pF1XPItYnfN54g+XrvHtXDO3vtm+ys9cq0UmqjHzW0joYief7msFFrYq6HX7J0Lf3ZPCCEHFG7ihBAyMNzECSFkYIbdxD1N6tjK4e14TXvd08cuXrp8lVZ1bGXno56sDlZ6JJcm2+DZp9uVNDLPDuCKhnz7qbM7xta6nme7nRN93aub66+tHtl+XJqnDea2tq8brj+0/Ui43NcN1x+66pFfNobavn/u1N07bPMej2X9K90Xby48X2pnIec2Xr9q/u0c2D7+8gP/fft8II/b0kZr98Nbe946tfPg2arr53Vj+6zZkfFSIwBb98reL21DaZ176M91bnP7qbPba9TOh50DO+fat1xXP95Rr1vtt8XzK9fVj/DbTYbdxAkhhHATJ4SQoeEmTgghAzNMnHimFYMdzYGRr9lYU6+uF6vaiuktaXKtR4iVYn8jMcylenaOauPoMktP3HIt10vUn14/e9tH7mlPjHktBtnWAfzY6FbMd9aGc76QUhuvXqT/Uh3Px0j92lg9811q69kTifeOxpCX5sX+fqL1OVokRhxgnDghhBxYuIkTQsjAcBMnhJCBiWQx3BeUtGGriXmPTLPxqLqPrNta7bAWY+3ZU4sFzePYOlbD9+Jme7VxT9cr5aH2cpcA5TOIlrat23z4oaeL9W1ZS1ttXSv5XYsdLvlRykNvx+85u/Aeneetl4iu7j36L4+lteDS+U7LBk3pcXIWPT5Qz+tj29VofaZsPW9N67re56TWt+5Xx7YDV/aLns/Dorp4Cf5PnBBCBoabOCGEDAw3cUIIGZhhNnGtbUZjt3NuFA9PE/P0yFosa84poq/l957+ZfXlVl5q66/Oi3Lx0uXtnBy5Py9PQ9bjPc3dq5fPCGrzoccqxdZ6vnhz4V0vxQDXdMzW/GXO3H+8Ogf2PEDrqfbe2z5LGmwtVtuOUfLF2unpy/k+e2PZcb2+7Lg6902uazV//f7DDz29PX96rVr0fNl/2R6vvY4Dz+vP+lTSw71zsdKasfmRSn57ds+5n4syzCZOCCFkJ9zECSFkYLiJE0LIwAyTO6UWO2xpxaj2tmvFApfiq3W9Uq6FUv2an7W6ns+tGGvdTttaG9v6ZPu3mr+mFH/cioFv6eolnzKePZ6dJTta9tm2Nbs9u+x1bVdtzvJ1+5zJEtH47B7fetZkaX3muciUPk8lPyLrMtfz7rl3H2ybbFfkXE73x9wphBBCXLiJE0LIwHATJ4SQgRlGEy9h9cP18xdww/WHrsoj4elxXj/AFX0u92M1SF2npdNFtcWI5l3TbrOtgJ+nI2KTxdP79LWS3t3yMapBlmyN6K75utX2S5p4aQzAz6VSsrfld0sXjuZtqc1DaV6j6753rfTo0LW+vM+w99mzfbXG9/zO+nTrOQLWR/u61H+JRXRxauKEEHJA4SZOCCEDM5ScUkszCbS/ste+TpdohU5p8nilr2k2fKolLcz52tgjFXhfOSMhfXNCGG24JQBX9olIVb2+Ruz0QshK9uv3QDlEsPS6R0aqSVeRdeP1V5oDO36tT1tPhzla2/Vj+vR8RUMVW5KU7tPSU8+bg4icGZXKFoFyCiGEHFC4iRNCyMA0N3ER+bSIvCYiz6uyIyLyhIi8PP29cXfNJIQQ4tHUxEXkuwF8E8B/Til951T2KQAXUkoPishJADemlD7RGmyZIYa9eqgt69HUdXpWG8Lnae694Yk6RDDX6QnFK9ke8bWE50MtDK5EK+SsRClETNtlbeyZq1bIWEmT12GLXnqC3nODOes04kvknnvX7Jx6P/eP9GNtz+cgNi1vqb/I+m2FuZbmwUuBMTe806650r24ppp4Sul/Abhgiu8BcHp6fRrABxcxkBBCyDzmauI3p5Q2AGD6e1OpoojcJyLrIrK+ubk5czhCCCEeu36wmVJ6OKW0llJaO3r06G4PRwgh31KE4sRFZBXA40oTfwnAHSmlDRFZAfBUSum2Vj+LauKlWNT8GqjrnbZM/zS/lOrTa1fTiXOZZ19v3HKrXaYWT9yyr4QXo57nDNgZ517Cu2e5jb5Wi4XusbXUJtJPa9yIdttKZ+q1y9e8+Sxp815ce02rLvkV1eq9WOtoGzsH9rqXytnzv7X+rX0e3pzV4tbzIxBbe471M5cvqoVndiNO/DEAJ6bXJwA8OrMfQgghCxAJMfwsgKcB3CYir4rIvQAeBHCXiLwM4K7pPSGEkD1mZ7yPIaX00cKlO5dsCyGEkE6Gyp0CtPNMaDzNsqTHeflOPFr6V0S/15TydSxDgy/Zruendb01p96c9NhgbSnZGDkHaGnzuZ/aPPXEaNv6tevWbs+30hmK19b6Ncem1v2zRMeqfeZ65ilie2nMnj6iZxlA7DygFtc+F+ZOIYSQAwo3cUIIGRhu4oQQMjBDb+JZY9PaW/6Xr3ttAGzXu/3U2e3cKDle2Wtj2wHYzgeRx9Y5VoCtPBG6vtbI9PgtfXv9/AUcWzm8HaN9+6mzOzQ527dnu73+3Km7t6/b+Wtpi2fuP+7Oidb+9Nh6DDsHeayaZuqNk+fPxk1bP0rzqsfV82vn3psrD3utND+2jZ5jXdf63aPRW5v1a7vGS/Nkbbl46TIuXrpcnAPdNq8Pe2/tfHs+6Xot7Nr17m2trvfZtW3tPOi1r9vkMdbPX7jKlmXGi3sMvYkTQsi3OtzECSFkYLiJE0LIwAwbJ16Kp43kBc4alX72XyTmORpn3Yq/1u1rMai9MbbW5qzn2lzlrWcctvzx/IrkbYnG+Jb6asV6l+J9a/XObfQ/87P2OjJ3kXkozWFpLmrz1GqjxwZ23ksv/3bUfltuPws6f3mmdY5Ru9Y7t7Xzs1bfrfd2fMaJE0II2QE3cUIIGRhu4oQQMjBDaeIlfU/TKrdEYm+9+rmN1gtz2Rw91PYdfeaf52dLFyxp5a0xalpfLZ+Ets277mnJnj8lSucV0ftQ0tK9eiV7I3r43HOHOecNPecDHhGt2qLnEqjnA9K5/HN5z2cpqpFHr1kfS+NEsZ/lRaEmTgghBxRu4oQQMjDcxAkhZGCG0sQ1c+JFW/p5j1bpjV16tl9Jk/XKIznIPVs9HTIatx7RWm3dHt1S66vRGNuI1t7SvT1fPZ9L7VoxxLpeNHd8r0Y9Ny5a+2Gvt/oq2ef1VXo2baQvPR+le12y2VsT0XOQyHg1/3p09WVp49TECSHkgMJNnBBCBmaYTVx/Rclfm/JXnPXzF7Z/Oq1TYAI7QwLzP33Nvo98RdVpSzP565keo4ZOxZn7zOlrPTtK/Z7beB0ffujp7a+meW60vbas1N+5javTu3rzYH9CrMPGPBlhbfWIO7ct2Uf7o8fO2NSxJT+tv3mNeHOUfcgSSV5XJZvzax2uqX3R89T6+l5bd7V7r9vmv9pu66M3nr6nViqy/uoUzDokUPdfkjuAK/ct39/18xe215zu2wtvzG1zHX2/StKRt+61rFVbO2urR7bH1HuOnb/S2gC21gBT0RJCCHHhJk4IIQPDTZwQQgZmmBDD6M+SW6Fr9qe9mmW2iVAKeYqEPEZCqaLXekPLau9r4VZRovb3hCXaPrxwUC/lq+3fe99qOyeM0Nqa0ybbn6t7/ZR87Fkrc0IXPd+AcjhfZB1Fwigj/bVsj4ZilsJl7efXWw8MMSSEELIDbuKEEDIw3MQJIWRghtDEgZ0/J9dxo5Gfz2Zqenf0Z7WZmiamr9s+cjys/pm2V690bY7GF9X8rKan7ejp05ujHns8SjZGNEuP1jhe/agO3avfRuyYox23zih0TLz38/lcJ6cvto+w0/1Gbek5w2hp+6V1lddB3h88e3X9kj+Rxwtaez0fF4WaOCGEHFC4iRNCyMAstImLyPtF5CUReUVETi7LKEIIITFma+Iich2A3wJwF4BXAXwRwEdTSudKbZYdJx6J4/W0r5LeVUslG9WUAT/laNYcS3G+1ua5cbpevZ6+e+J/a+j2OR+GzS/SonVPPPuiOvdcDTkyZjTGubRe81qJjBeJUa6h60dSBpfsrtUp2RTVxCPjl+L0Mz3rJTLPno81f/drnPh7ALySUvqdlNL/A/ALAO5ZoD9CCCGdLLKJvw3A19T7V6eyqxCR+0RkXUTWNzc3FxiOEEKIZZFNXJyyHdpMSunhlNJaSmnt6NGjCwxHCCHEsogmfhzAqZTS3dP7BwAgpfRjpTaLxIkTQsi3KruliX8RwK0i8g4ReSOAjwB4bIH+CCGEdNIXLqBIKV0WkX8J4CyA6wB8OqX0laVZRgghpMnsTRwAUkq/DOCXl2QLIYSQTviLTUIIGRhu4oQQMjDcxAkhZGC4iRNCyMBwEyeEkIHhJk4IIQPDTZwQQgaGmzghhAzMnj5jU0Q2AfzezOZvBfAHSzTnWnJQfDkofgD0Zb9CX7b4SyklN4Pgnm7iiyAi66UEMKNxUHw5KH4A9GW/Ql/aUE4hhJCB4SZOCCEDM9Im/vC1NmCJHBRfDoofAH3Zr9CXBsNo4oQQQnYy0v/ECSGEGLiJE0LIwOz7TVxE3i8iL4nIKyJy8lrb4yEibxeRXxORF0TkKyLy8an8iIg8ISIvT39vVG0emHx6SUTuVuV/TUSem679BxHxHki92/5cJyK/ISKPD+7HW0TkF0XkxeneHB/Yl381ra3nReSzIvKmUXwRkU+LyGsi8rwqW5rtInK9iJyZyp8RkdU99uXfTWvsyyLyeRF5y576klLat/+w9di33wbwTgBvBPCbAI5da7scO1cAfNf0+jsA/BaAYwA+BeDkVH4SwI9Pr49NvlwP4B2Tj9dN174A4DgAAfA/APzta+DPDwP4eQCPT+9H9eM0gH86vX4jgLeM6AuAtwH4XQDfNr1/BMA/HsUXAN8N4LsAPK/KlmY7gH8O4Ken1x8BcGaPffk+AIem1z++177s6YdqxoQdB3BWvX8AwAPX2q6A3Y8CuAvASwBWprIVAC95fmDrOaXHpzovqvKPAnhoj22/BcCTAL4HVzbxEf04jK2NT0z5iL68DcDXABzB1iMVH582jmF8AbBqNr6l2Z7rTK8PYetXkbJXvphrfxfAZ/bSl/0up+TFm3l1Ktu3TF9/3g3gGQA3p5Q2AGD6e9NUreTX26bXtnwv+UkAPwLgz1TZiH68E8AmgP80SUM/IyJvxoC+pJT+N4B/D+CrADYA/GFK6VcwoC+KZdq+3SaldBnAHwL4C7tmeZ1/gq3/WV9l18Su+LLfN3FPr9u3MZEi8u0AfgnAD6WUXq9VdcpSpXxPEJEPAHgtpfRstIlTds39mDiEra+9/zGl9G4Af4ytr+0l9q0vk158D7a+kv9FAG8WkY/Vmjhl+8KXAHNs3xd+icgnAVwG8Jlc5FRbui/7fRN/FcDb1ftbAHz9GtlSRUTegK0N/DMppc9Nxb8vIivT9RUAr03lJb9enV7b8r3ifQB+QETOA/gFAN8jIv8F4/mByYZXU0rPTO9/EVub+oi+fC+A300pbaaU/gTA5wD8DYzpS2aZtm+3EZFDAP48gAu7ZrmDiJwA8AEA/zBNWgj2yJf9vol/EcCtIvIOEXkjtoT+x66xTTuYTpZ/FsALKaWfUJceA3Bien0CW1p5Lv/IdBL9DgC3AvjC9LXyj0TkvVOf/0i12XVSSg+klG5JKa1ia65/NaX0sdH8mHz5PwC+JiK3TUV3AjiHAX3BlozyXhG5YbLhTgAvYExfMsu0Xff197G1bvfyG+z7AXwCwA+klC6qS3vjy14caix4iPD92Ir2+G0An7zW9hRs/JvY+srzZQBfmv59P7a0rCcBvDz9PaLafHLy6SWoCAEAawCen679FHbxgKbh0x24crA5pB8A3gVgfbov/w3AjQP78qMAXpzs+DlsRTwM4QuAz2JLy/8TbP1P895l2g7gTQD+K4BXsBX18c499uUVbOnY+bP/03vpC392TwghA7Pf5RRCCCEVuIkTQsjAcBMnhJCB4SZOCCEDw02cEEIGhps4IYQMDDdxQggZmP8P8rOSnncXgPQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#from models import Model, SynapticConductanceModel\n",
    "from brian2 import *\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "model = SynapticConductanceModel(resistance=Model.LOW, # Model.LOW, Model.HIGH\n",
    "                                 noise=Model.HIGH, n=50, # Model.OFF, Model.LOW, Model,HIGH\n",
    "                                 offset=SynapticConductanceModel.ACTIVE)\n",
    "\n",
    "\n",
    "# model = SineModel(resistance=Model.LOW, # Model.LOW, Model.HIGH\n",
    "#                                   noise=Model.OFF, n=1, # Model.OFF, Model.LOW, Model,HIGH\n",
    "#                                 )\n",
    "\n",
    "\n",
    "model.f = 200 * Hz\n",
    "model.set_stimulus_current(400 * nS) # current should be scaled by 100x for Active Offset so (500nS is actually 5nS)\n",
    "model._set_variable(\"i_injected\", 90 * pA)\n",
    "\n",
    "\n",
    "model.run(12*second)\n",
    "\n",
    "spike_times = [s/ms for s in model.spike_train.values()]\n",
    "\n",
    "plt.eventplot(spike_times)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7f22e21e",
   "metadata": {},
   "outputs": [],
   "source": [
    "#print(spike_times)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "20e3191c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.io\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "file_path = 'data0.mat'\n",
    "scipy.io.savemat(file_path, {'data0': spike_times[0]})\n",
    "\n",
    "file_path = 'data1.mat'\n",
    "scipy.io.savemat(file_path, {'data1': spike_times[1]})\n",
    "\n",
    "file_path = 'data2.mat'\n",
    "scipy.io.savemat(file_path, {'data2': spike_times[2]})\n",
    "\n",
    "file_path = 'data3.mat'\n",
    "scipy.io.savemat(file_path, {'data3': spike_times[3]})\n",
    "\n",
    "file_path = 'data4.mat'\n",
    "scipy.io.savemat(file_path, {'data4': spike_times[4]})\n",
    "\n",
    "file_path = 'data5.mat'\n",
    "scipy.io.savemat(file_path, {'data5': spike_times[5]})\n",
    "\n",
    "file_path = 'data6.mat'\n",
    "scipy.io.savemat(file_path, {'data6': spike_times[6]})\n",
    "\n",
    "file_path = 'data7.mat'\n",
    "scipy.io.savemat(file_path, {'data7': spike_times[7]})\n",
    "\n",
    "file_path = 'data8.mat'\n",
    "scipy.io.savemat(file_path, {'data8': spike_times[8]})\n",
    "\n",
    "file_path = 'data9.mat'\n",
    "scipy.io.savemat(file_path, {'data9': spike_times[9]})\n",
    "\n",
    "file_path = 'data10.mat'\n",
    "scipy.io.savemat(file_path, {'data10': spike_times[10]})\n",
    "\n",
    "file_path = 'data11.mat'\n",
    "scipy.io.savemat(file_path, {'data11': spike_times[11]})\n",
    "\n",
    "file_path = 'data12.mat'\n",
    "scipy.io.savemat(file_path, {'data12': spike_times[12]})\n",
    "\n",
    "file_path = 'data13.mat'\n",
    "scipy.io.savemat(file_path, {'data13': spike_times[13]})\n",
    "\n",
    "file_path = 'data14.mat'\n",
    "scipy.io.savemat(file_path, {'data14': spike_times[14]})\n",
    "\n",
    "file_path = 'data15.mat'\n",
    "scipy.io.savemat(file_path, {'data15': spike_times[15]})\n",
    "\n",
    "file_path = 'data16.mat'\n",
    "scipy.io.savemat(file_path, {'data16': spike_times[16]})\n",
    "\n",
    "file_path = 'data17.mat'\n",
    "scipy.io.savemat(file_path, {'data17': spike_times[17]})\n",
    "\n",
    "file_path = 'data18.mat'\n",
    "scipy.io.savemat(file_path, {'data18': spike_times[18]})\n",
    "\n",
    "file_path = 'data19.mat'\n",
    "scipy.io.savemat(file_path, {'data19': spike_times[19]})\n",
    "\n",
    "file_path = 'data20.mat'\n",
    "scipy.io.savemat(file_path, {'data20': spike_times[20]})\n",
    "\n",
    "file_path = 'data21.mat'\n",
    "scipy.io.savemat(file_path, {'data21': spike_times[21]})\n",
    "\n",
    "file_path = 'data22.mat'\n",
    "scipy.io.savemat(file_path, {'data22': spike_times[22]})\n",
    "\n",
    "file_path = 'data23.mat'\n",
    "scipy.io.savemat(file_path, {'data23': spike_times[23]})\n",
    "\n",
    "file_path = 'data24.mat'\n",
    "scipy.io.savemat(file_path, {'data24': spike_times[24]})\n",
    "\n",
    "file_path = 'data25.mat'\n",
    "scipy.io.savemat(file_path, {'data25': spike_times[25]})\n",
    "\n",
    "file_path = 'data26.mat'\n",
    "scipy.io.savemat(file_path, {'data26': spike_times[26]})\n",
    "\n",
    "file_path = 'data27.mat'\n",
    "scipy.io.savemat(file_path, {'data27': spike_times[27]})\n",
    "\n",
    "file_path = 'data28.mat'\n",
    "scipy.io.savemat(file_path, {'data28': spike_times[28]})\n",
    "\n",
    "file_path = 'data29.mat'\n",
    "scipy.io.savemat(file_path, {'data29': spike_times[29]})\n",
    "\n",
    "file_path = 'data30.mat'\n",
    "scipy.io.savemat(file_path, {'data30': spike_times[30]})\n",
    "\n",
    "file_path = 'data31.mat'\n",
    "scipy.io.savemat(file_path, {'data31': spike_times[31]})\n",
    "\n",
    "file_path = 'data32.mat'\n",
    "scipy.io.savemat(file_path, {'data32': spike_times[32]})\n",
    "\n",
    "file_path = 'data33.mat'\n",
    "scipy.io.savemat(file_path, {'data33': spike_times[33]})\n",
    "\n",
    "file_path = 'data34.mat'\n",
    "scipy.io.savemat(file_path, {'data34': spike_times[34]})\n",
    "\n",
    "file_path = 'data35.mat'\n",
    "scipy.io.savemat(file_path, {'data35': spike_times[35]})\n",
    "\n",
    "file_path = 'data36.mat'\n",
    "scipy.io.savemat(file_path, {'data36': spike_times[36]})\n",
    "\n",
    "file_path = 'data37.mat'\n",
    "scipy.io.savemat(file_path, {'data37': spike_times[37]})\n",
    "\n",
    "file_path = 'data38.mat'\n",
    "scipy.io.savemat(file_path, {'data38': spike_times[38]})\n",
    "\n",
    "file_path = 'data39.mat'\n",
    "scipy.io.savemat(file_path, {'data39': spike_times[39]})\n",
    "\n",
    "file_path = 'data40.mat'\n",
    "scipy.io.savemat(file_path, {'data40': spike_times[40]})\n",
    "\n",
    "file_path = 'data41.mat'\n",
    "scipy.io.savemat(file_path, {'data41': spike_times[41]})\n",
    "\n",
    "file_path = 'data42.mat'\n",
    "scipy.io.savemat(file_path, {'data42': spike_times[42]})\n",
    "\n",
    "file_path = 'data43.mat'\n",
    "scipy.io.savemat(file_path, {'data43': spike_times[43]})\n",
    "\n",
    "file_path = 'data44.mat'\n",
    "scipy.io.savemat(file_path, {'data44': spike_times[44]})\n",
    "\n",
    "file_path = 'data45.mat'\n",
    "scipy.io.savemat(file_path, {'data45': spike_times[45]})\n",
    "\n",
    "file_path = 'data46.mat'\n",
    "scipy.io.savemat(file_path, {'data46': spike_times[46]})\n",
    "\n",
    "file_path = 'data47.mat'\n",
    "scipy.io.savemat(file_path, {'data47': spike_times[47]})\n",
    "\n",
    "file_path = 'data48.mat'\n",
    "scipy.io.savemat(file_path, {'data48': spike_times[48]})\n",
    "\n",
    "file_path = 'data49.mat'\n",
    "scipy.io.savemat(file_path, {'data49': spike_times[49]})\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d353eff4",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}