{
 "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.57689 s (4%) simulated in 10s, estimated 3m 18s remaining.\n",
      "1.17271 s (9%) simulated in 20s, estimated 3m 5s remaining.\n",
      "1.71148 s (14%) simulated in 30s, estimated 3m 0s remaining.\n",
      "2.24713 s (18%) simulated in 40s, estimated 2m 54s remaining.\n",
      "2.77117 s (23%) simulated in 50s, estimated 2m 47s remaining.\n",
      "3.30573 s (27%) simulated in 1m 0s, estimated 2m 38s remaining.\n",
      "3.84666 s (32%) simulated in 1m 10s, estimated 2m 28s remaining.\n",
      "4.3903 s (36%) simulated in 1m 20s, estimated 2m 19s remaining.\n",
      "4.92931 s (41%) simulated in 1m 30s, estimated 2m 9s remaining.\n",
      "5.47275 s (45%) simulated in 1m 40s, estimated 1m 59s remaining.\n",
      "6.01733 s (50%) simulated in 1m 50s, estimated 1m 49s remaining.\n",
      "6.55359 s (54%) simulated in 2m 0s, estimated 1m 40s remaining.\n",
      "7.09743 s (59%) simulated in 2m 10s, estimated 1m 30s remaining.\n",
      "7.64482 s (63%) simulated in 2m 20s, estimated 1m 20s remaining.\n",
      "8.19022 s (68%) simulated in 2m 30s, estimated 1m 10s remaining.\n",
      "8.73651 s (72%) simulated in 2m 40s, estimated 1m 0s remaining.\n",
      "9.28207 s (77%) simulated in 2m 50s, estimated 50s remaining.\n",
      "9.82707 s (81%) simulated in 3m 0s, estimated 40s remaining.\n",
      "10.37374 s (86%) simulated in 3m 10s, estimated 30s remaining.\n",
      "10.91463 s (90%) simulated in 3m 20s, estimated 20s remaining.\n",
      "11.45617 s (95%) simulated in 3m 30s, estimated 10s remaining.\n",
      "12. s (100%) simulated in 3m 40s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.collections.EventCollection at 0x1adab6d2610>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab6ec250>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab6fce50>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab70fd00>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab722910>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab735520>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7470a0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab756d30>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab769ac0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab77b790>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab78e760>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7a0490>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7b5220>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7c3f70>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7d5ac0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7e76a0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab7fc3d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab80e0a0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab81cd90>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab82fb50>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8427c0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab854610>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab868400>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab87b0d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab88ad30>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab89dac0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8ae7c0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8c1460>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8d52b0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8e4eb0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab8f6af0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab907730>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab91c370>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab92f0d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab93dc70>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab950880>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab963430>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab975280>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab989070>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab995df0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab9abc40>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab9bdaf0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab9cf790>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab9e1280>,\n",
       " <matplotlib.collections.EventCollection at 0x1adab9f0eb0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adaba05af0>,\n",
       " <matplotlib.collections.EventCollection at 0x1adaba16790>,\n",
       " <matplotlib.collections.EventCollection at 0x1adaba28490>,\n",
       " <matplotlib.collections.EventCollection at 0x1adaba3c190>,\n",
       " <matplotlib.collections.EventCollection at 0x1adaba50040>]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXEAAAD4CAYAAAAaT9YAAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAms0lEQVR4nO2dbYxex1XH/4e4dUnBNKZOtDQVbqUowqKihaWqKUKBEFygIgVR0oqCEYFEAqTyIlGHfsB8angRQggJEkHBglIcoCVRBIQoECGkKO1GlDrNC0khtKELWWpEgEgFw/Bh7zizZ8+ZOXOfZ9c7y/8nWXufufNyztz7jPz859xzJaUEQgghY/J5l9oAQggh8+EiTgghA8NFnBBCBoaLOCGEDAwXcUIIGZgDuznYK1/5ynT06NHdHJIQQobnkUce+ZeU0hHr3K4u4kePHsXa2tpuDkkIIcMjIv/gnaOcQgghA8NFnBBCBoaLOCGEDAwXcUIIGRgu4oQQMjCh6BQReQbAvwP4HwAXUkqrInIYwFkARwE8A+C7Ukr/ujNmEkIIsej5n/jXp5Ren1JanT6fAvBASukaAA9MnwkhhOwii8gpNwI4Mx2fAfC2ha0hhBDSRXQRTwD+TEQeEZFbprKrUkrrADD9vdJqKCK3iMiaiKxtbGwsbjEhhJCLRJ/YfHNK6TMiciWA+0XkiegAKaU7AdwJAKurq3wDBSGELJHQIp5S+sz09zkR+TCANwL4ZxFZSSmti8gKgOd20E7cdMdDF48fW3/erHNs5dC2OudOn8BNdzy0pU2up/vR5WV/0XFr6H5rNpWfX/jcBQDA6tHDAIC1Z87j8oMHLvqm25X96ralLbUxMmvPnHfbl7afvfX4tnn2zpXjludLW/J41pzrNlY9PW7rWkbvCQ/tkx4rl+X5vPzggaovNXusua75592fc9t718SzvXW/R8+X41vzZvlXu361MbSv3hy0/C5tPHvrcdfWRWjKKSLychH5wnwM4JsAPArgHgAnp2onAdy9IxYSQghxifxP/CoAHxaRXP93U0p/KiIfBXCXiNwM4FMA3r5zZhJCCLFoLuIppb8D8BVG+WcBXL8TRhFCCIkhu/m2+9XV1TQnFa2lfUZ0txq19tG+s/6sNdxW+1JfK/XNrEtffvBASMvLtLT6iD6ayXq7tb9Q6u35uHfetX3Z/3Lcmob9wucuVO3z/O25rrptOY6n57f2XFqaqlXu7XNYY3j3VK1uz/6Ftq/ma+u8pxUv8j1v7b207I1o3lYfPXr+Ipq4iDxSPKOzBT52TwghA8NFnBBCBoaLOCGEDMxwmriOW47oXeW5TE0L9+oA2/VGPUZE3yvLW7qr5Zs+9rTTSHyw5YNlb3S+IvsHOUZa92d9zmW9Om/N9x67NdFxIxquZ29vHLh1XlMbvxWHPScG37pH9X5G634py3va1HyP2Nrbd2RfYNEYcWrihBCyT+EiTgghA8NFnBBCBmY4TTyiYUU0z/y5zGXRG/9p6YJW3oTe2PPauF5ZK2+DNVaN3v50zHwkfrrn2tX2Ilp2ZzybWnsK0T2Ns7cex+tO3+c+N1Ci88VY49d8i+6/tL4vPbHy5Xi6fta7z50+cbGstndUG9OqE/Gn9/7Sz2iUzym07PXuSa1/l99/xokTQgjZBhdxQggZGC7ihBAyMENo4gBMbbmmZ2q8mGdLX1xEw470VWun8yNb8bWaVkxrxJ+oFu/53toTqNGKWS7r6X0GL/647NfKy2LdNz16ce1+yNf/dafv21LX86s1D54WHd0/0PVa+0C6v9Zxaz68epau39p3qZXVfI9+R8r7Kdez1otcpt9X0LqGc6EmTggh+xQu4oQQMjBcxAkhZGCG08RLtI7sxc3O1TbL8khsa1mv9W7KiHbZKo/YEYlxrs1LJpKzRlPTQVt6ca8e34pL1+8Qje5PRPTyiFasfavp3J7eqv2vPYdgja1taNnsxdpnu/NnPU+ta1G7BywtueajnhM9ho7Tju55Wfe/lce+tg8DbH+X6lyoiRNCyD6FizghhAzMEHKKF16YjwE7tC9TC6PKRKSWVtjcHAmjFSYZkQFq/deIhEqVfdfGtXzRtMK8AFsSs8apfc5lLbmqxy5dPyrRReax9nPfGjPSV3m+9rm8v6xQOmu81veiFmZXe2Q/k+9Fy/da/7W5qT0i70m1PT5bdXRfeQ7mQDmFEEL2KVzECSFkYLiIE0LIwAyhiQPxdJu6Tklv6FJEeyvHi4YI1mz0xtfl5ePBEa3eSwVg2W9pmTrFag65KrX0Xo3ResTaukbeWN7clP2V86XP1/y36mofrXFq9bzH3fV8RDRWr+9aSGuuZ4XKWfbXzkX2Plphj154Yi38tBzDsqP2vdDzVtaN2OfNoxeKqfd1GGJICCFkG1zECSFkYLiIE0LIwAyjiWdN1krJWtMMex/Brel4PbGzZdusvZV6pdbudJ817U33X7Pdq1t+jvhSe7zYS5Nba1/rV89XdM/D8qmsX9NYW/HpEa3U0ng93bX22HlZ5l1za450O29u9XFpk56DaNx5yx7tn+WTN3/lsRVz3Updq4nG11t2tXT+sq9cp3xl3VyoiRNCyD6FizghhAxMeBEXkctE5K9F5N7p82ERuV9Enpr+XrFzZhJCCLEIa+Ii8uMAVgEcSim9VUR+DsD5lNLtInIKwBUppffU+lgkd0qmFZPbig8v6dG9I9qzpYFGY9lrccI1ez0bo357RPV1nXKzZp/Xb8SXHlp6cuScdz3KmHkr3rs2VvReaNnr3e89ezsteyw8Pd2yt9bWy3Hkta89pxC1uzVn2s6ab5G9AKvtJY0TF5GrAXwrgF8vim8EcGY6PgPgbbMtJIQQMouonPJLAH4SwP8WZVellNYBYPp7pdVQRG4RkTURWdvY2FjEVkIIIYrmIi4ibwXwXErpkTkDpJTuTCmtppRWjxw5MqcLQgghDk1NXETeB+B7AFwA8DIAhwB8CMBXA7gupbQuIisAHkwpXVvraxmaeKY3LtqKyY7ohVZdbxwPS1P34l97Y9WtHA2WH5H4bKAvLl2Xl5pjzlPdioNv2bvIdfFst9p68x8Zb46+XYvZ9tp4RPdzWmWR8aP3ulVfj1F+J2vfAa09W98d73ugx47cd9581fZDansX+XmAReLFF9LEU0q3pZSuTikdBfAOAH+eUnoXgHsAnJyqnQRw92wLCSGEzGKROPHbAdwgIk8BuGH6TAghZBc50K7yIimlBwE8OB1/FsD1yzeJEEJIlCFyp5T5fwFbC7O0XWB7fuVMJFbUiwPt1Zlr2ms0h0skNtiipfVGdWFLv41qzDW7yra671rua4+afVb7nucDvHa1viIx2L3jlH7me7OW49zL227l1rbu8zKfe6aWQz5yDUr79TMGul0rR4rVRs9BrY1nh+5P34/WXlvt2jOfOCGEkG1wESeEkIHhIk4IIQMzhCYObM+z4GlxtXc8tt5h2NKhazqoprdOxMaWDuuN5+msLXt0fa0JtmLUc1tPO/Tsz+XRXBda341es+h113V69PAIrTkAUM2po+ei/Oy9Q7J3D8VrrzXfVp6j1pi1+jV9P6Kv93wny+ccav1kajHvpe1zoSZOCCH7FC7ihBAyMFzECSFkYIbUxHvjsTWe1p3p0cy9MfQ4Xt9Wuc6fHM2PAmzXg2t51lttLVradUQPjmrK1pi917qHVpy+NUaPL16sd82O6LlIXL81ts5932qnxyttiT5DYNnbkwMoEtuvbYreU7Xrbu1RRO8LauKEEEJMuIgTQsjADCGnRB4Njvz8ybRCCEta8oT3c85qr+0r8R7lbYVVWtTCwCwbvTnR9SNyQOt6aN8jUlYkpK4ntK8mAVmhZdrO6D1R+7kfvS+8c7Xr1DMfPVJU5L6y6msi8mTtO6TH8CRLawzLtohEErk+FotIKCWUUwghZJ/CRZwQQgaGizghhAzMEJp4Jvo4fS4H6lp5K8Sw1r8ex2pbqzPnUeBWP1HNMqqtt+gJ+7Lq17RMbzzLt9o9kc97j/1bbVrXxEv3AGDLq7h6HpWvhel59kTCSSP7ITmdQtnGCo9spU7w5sjzqSclQOT+svpo3aNe6GA5D8CL19OjFsaZ2y8CNXFCCNmncBEnhJCB4SJOCCEDM4Qm7mnhJT0xuhatx3CBrTqf1ge9PiOaXB5Tx8HrMaP0aKlWWysev9V/eS6nDSj7K9uVKW0jOn0rTnoZexgtzTqavsDTtqNx8x7ahhzPrp+ZqKWuXdZzA/m8TgvR+2yAl9o4ugek+2vZXsZse/H1ug9rDL3/Ydnv7RPMhZo4IYTsU7iIE0LIwHARJ4SQgRlGE8/MyTUR0SEjmpin9dba1/JklPS8Xiziq6bsS2uR5XkvvreMe+7JcdFzLbzxarTyXET3SGrPD0TuufK81vznxNBH7a/NyzJyq9T8XsS2Vt3ImFZfZZ+teyN/to7zZ50WWteN7uWU+xVzoCZOCCH7FC7ihBAyMFzECSFkYIbRxHt0Vk/jarW1+iqJ5FSoxddGffDsiGrwGSuXesSWWllrbltxyi3dWY+l82t4tulzpZ+eNmntQXjjzDnO/WaNXO8rlOcBXIy5jryar/SvnPtWfHwtBrs2txHtuLWXUI4V3Rvwcn3rOc2Uc2nRusctWjq617euQ02cEELINriIE0LIwDQXcRF5mYh8RET+RkQ+ISI/M5UfFpH7ReSp6e8VO28uIYSQkqYmLiIC4OUppf8QkZcA+CsA7wbwHQDOp5RuF5FTAK5IKb2n1teimnhPfgcvNrOlr5dY/Wrmau5A7P2bNT1Z2+n56PkUiZtvxRPPiTuO+GXF6Jb0xnFb906Zf8Tbv2jtbXjj1vZWLB8AbHsOwRuv5WurTi1Ou7W/ZNllxcPXbOix3bIxn689W5Gvr3XfWP2XtL6Xte9wzZ9LpomnTf5j+viS6V8CcCOAM1P5GQBvm20hIYSQWYQ0cRG5TEQ+BuA5APenlB4GcFVKaR0Apr9XOm1vEZE1EVnb2NhYktmEEEKA4CKeUvqflNLrAVwN4I0i8uXRAVJKd6aUVlNKq0eOHJlpJiGEEIvuOHER+WkA/wngBwFcl1JaF5EVAA+mlK6ttV2WJt6TAyKSh8LTvSNx5+U4PblDyjGsep4Prc9lHC2Abe9E7NHkdax21MeWPy3fPK2zZ050vUhfZZ1Ma68kqnlHde258d6RePjcJr/vMbofk+cl05PLSPtT3kt6PySPU7u/vL2UXKb71360Yrk9H1rfkdZ9dkk1cRE5IiKvmI4/H8A3AngCwD0ATk7VTgK4e7aFhBBCZnGgXQUrAM6IyGXYXPTvSindKyIPAbhLRG4G8CkAb99BOwkhhBg0F/GU0scBvMEo/yyA63fCKEIIITGGzJ1SEtUnNRFNsaxX1o305dlqtavRG4ddi5m32vbGVnv6u6dDztkL8HRyoB7nb+mtLd9a7Xq0dytXjad3W3OqicZee9fJ2vModXFP29ZzUhu/tk8S2XOx9HDtR21PquzDyuPeyunSs7ehY89bMeeWVj4X5k4hhJB9ChdxQggZmGHklEwtPKw8X5MCWn1FwvOssWo/v3NZmWI0P1KeU61Gfu55/UZCIeeGN0bC7iLjRMay7NJEZI7IT+mePlvHlq8Rn6062XbrVYDR0E2r79LGqA+WjKBT59ZePdgjT0XnWNvpne95TZ7lu0bbntM2WLJTTRKcA+UUQgjZp3ARJ4SQgeEiTgghAzOMJh4NXwLqj9GXdSM6XKmr6X60LeX5nhC7VntLl/Rs0XNQCw3T7SNzk8nzUrZbRCPu0Xot/T+iSVpY+q9uXwu3a9nvjevRq1dnovdgJFTTK2vp2dY9Gvku1u5Vy++yjhf259H6HgL+6wzL1MWebbX7gJo4IYSQbXARJ4SQgeEiTgghAzOMJp6paZg1XRuAq5v16Li9dbx2rZSZZd1o3LWl21tatRVPvkgM/DLnK5fPSesLxPdDyrqefuk9Mm7FdNfq9ryGT9ur7fLa9cRg9/RZzof3XIOu29oTsu6/Ft593notYySlb3Ru9LXsjXGnJk4IIWQbXMQJIWRguIgTQsjADKOJa62pzFsA2DlKrJwkEV2r7MfTDHV8qpWO1aKls1l1amW1/CCttlbdsl8gFk9cI6I9RuzxtNVW/Lc1R97rwFrXv3bsxStH9hpqc1HzvZyb8n63+m/tJ/T6X+tjzpxmrOcyrP4Bf68sz4V+DV3Nl7JNq76VutjT+amJE0IIqcJFnBBCBoaLOCGEDMwQmjiApmaciWikum00DlvX1bqx1lt1O0v79uKaa+3LczV/o7qthzVXOo9IPq/zStR0+bkxutq/Wr8tP3rmzRsvf9Yae46n1vm2W/q2trnUUMvc4patnv3eHPTuT0TmX+fXrsXhW33V6tTG7bnu1rnWnlkrrj1yDfT17IWaOCGE7FO4iBNCyMBwESeEkIEZRhMvdUatUfVo2hatWO1F47Y9Fom/1u1afevY2pZe2dLivbr581xd1dInS7s9Py29uScevaXBl+fOnT6x5X4sz7dyj7c01rnaf0tnnrPvUxurFQte1gPsmO7WPonXX+25iKj2X859GRvu+diy19pv0uXUxAkhhGyDizghhAwMF3FCCBmYITTxVm6QkpZeGImVrulokVwlrX6iduaynthlrcP16K96bB33q8eMvsdT9+vNQ6R+rX2tzBsrGreu+8nx4Pmzp8GWOU0szdQisufgjev13bqX9RxZNkXuwbIsa806r1AtLrtlg/ZBU3t2o6Wte+P1xIFrfy3b5kBNnBBC9inNRVxEXi0ifyEij4vIJ0Tk3VP5YRG5X0Semv5esfPmEkIIKYn8T/wCgJ9IKX0ZgDcB+GEROQbgFIAHUkrXAHhg+kwIIWQX6dbEReRuAL8y/bsupbQuIisAHkwpXVtru9OaeKlBRXNIl+1auqrOD1L2lVk0ZtXTrvU7DufGlZd2lPa3YnU1EW2+dq4Ve26NU1Lqj8DWa1L2Z/kdiSevnc/lWfvUeautXPeeht6yoxWv3PKtnI+opt0ar3WfWFq7ztdd2tXyofZ9Kfuu3Vee3XOvfc9eWj63JzRxETkK4A0AHgZwVUppHQCmv1fOtpAQQsgswou4iHwBgD8E8KMppfB//0TkFhFZE5G1jY2NOTYSQghxCMkpIvISAPcCuC+l9ItT2ZPYZTklE/05WQtdqj3OHZUoamNafbXsjp4v++75eec9HlzW7wlZ02Va2mjNeyTczPPDmydtnydTefNqyR5RuW3Oz3VNT/2aZFir69nfsqt2/0R8LyUFyxbvFYfRee2tV/pm2ecRDfnUPlwyOUVEBMBvAHg8L+AT9wA4OR2fBHD3bAsJIYTM4kC7Ct4M4HsAnBORj01lPwXgdgB3icjNAD4F4O07YiEhhBCX5iKeUvorAOKcvn655hBCCOlhiMfuge2pLKP6cCQUzwoZ88IaIxq2pRu2dF3vsV1LK9ahjlb9sl9Pq7Z811p4dB49nbFW19Kjo/sfXl1Pn7Touaa96RZK/TOyL9Pqq/ZYeu9ct/qJ7MPMTTHrzaMOQfT2tiIhjd79YeGNW6ZLyH164aOl7yV6n2JPhBgSQgjZW3ARJ4SQgeEiTgghAzOcJh6NI87H5WO+tbjasn6OE/YeEbZ0b12npKXJlo8NezG/Ee03f/Z0uEhMsdYdvbjxGpFHlrXP3hi6TO8HtGLFAXt+ta+Rfjz7opp0z7naeWsfoTzu0e2tvabavV2eb6UorsV9e3Zb94XH3OvozWFkD6XVZy2Onpo4IYSQbXARJ4SQgeEiTgghAzOEJu7lfKjFC5d19HEmEtda1tN1W+OVRDS7qF1en7U44DmvUovG23q6aJk6t6xnxa1H9F/rvGeD1x6o5xEpNffemPPaXkZEZ/c0autY291zD+v5mavv13xaVJ/XfXrje/H4Xv/ePPY8o2CV6T04L0Z+LtTECSFkn8JFnBBCBoaLOCGEDMwQmnhGxz63NDdPE/b031ZZJmu6ZW6FcrxoTHBtTMuX2iu+LFqaeVnWytfSo79b5a1c0Zqadt/Ko53HArbnwMj9WfG8Lf3ZGzfybEDknui5By1dOKpBW/5kWnHaUb09qtf37GlZ5z3fyvPWHPX6o/uPvMJuWXlTAGrihBCyb+EiTgghA8NFnBBCBmYITdyKnY2+M9A71xPvXYtj1XZFjr28EaUNZb+lfTqmdxm6pNZEy5wZnu7rxURHYtVr9bXdtbJW/VrOa22btkfT8i2Xe/mpLeZou179qL5s2R7d1/D2nCJ9ezZG91asc5ExInsotT2xReLHSxgnTgghxISLOCGEDAwXcUIIGZghNfGSiNarY59zn5YuF8mDYI2tbbI09Jq+XNLSSMt6NY2vlccjoldG4utb+VUicfyWPa1ztXmv6eOR+dX6pdZUc5mHnsOcR0bn6M5j1e7H8tjKge/FdGufdBs9hq7TskXX1fWtz5ZdOma/LK/ZadnrEd1/sMbW4+hrauVVt/qnJk4IIWQbXMQJIWRguIgTQsjADKWJW9piJM9BSa7vvasxEu+a25Y5OXpjbK1zliZb06NzG0t/13224tyt3CleudYwF81FYc2J9sPyNaIJe20tIvpuLe+1jhGP+JDP17TkXi261Zfe52g9e9Bq79kzJxe91QdQzwvT+u7p8tq43v3dml9vzajts/RATZwQQvYpXMQJIWRghpFTvJ9ImejPzrKP1k9XXb93rDk/VSNje76UoU96/NpYLZnAs8WzyfO9ZUfEX6sPr2yOnNMaI5e3wkXnSB/RMLeodOeF8S3yGjjdr0XtO1fzw7PHskH33UoTbI0VfaTeK4+sMeWrCCmnEEII2QYXcUIIGZjmIi4i7xeR50Tk0aLssIjcLyJPTX+v2FkzCSGEWET+J/5bAN6iyk4BeCCldA2AB6bPO8qxlUM4d/rEljKtRT22/vzFslILK//lPsq2ZTs9Zlk3/z13+sQWfSu3z2OU5bksovO1NMeztx7f4ouF1rXPnT6xpX45VmlT1tHLc57+Z53PY+V/up1lgxWapfuu6aYtfdK7riX6/tDkOS/rrj1zfst8af/K8YEXr4H2J/uvbVx75vyW8L/yX1QPt+pcfvAAHlt//qLtnkarbdJjZ/usOhE9vPRT+6zr6/sil+nv2U13PISztx6/eO/lz7U9lvK7Un5Py3H1mmFd51xHX+PH1p/H5QcPbHs94LJpLuIppb8EcF4V3wjgzHR8BsDblmsWIYSQCHM18atSSusAMP290qsoIreIyJqIrG1sbMwcjhBCiMWOb2ymlO5MKa2mlFaPHDmy08MRQsj/K0Jx4iJyFMC9KaUvnz4/CeC6lNK6iKwAeDCldG2rn2XEiQP2Y+8lVtxzNE55Dq3xrPqeLpz7KeNLS7Q2WT4S3/KtNq6uZ32u+daax974e2usVgyvxpuTWsrdPKcZ/Zq1cizdphY/3Xv/9ca8956vfW7Z593vVioLbxwvzUOJda9GbNXfndZ9VevTmquyTeT7VM7ZXHYiTvweACen45MA7p7ZDyGEkAWIhBh+EMBDAK4VkWdF5GYAtwO4QUSeAnDD9JkQQsgu04x9SSm90zl1/ZJtIYQQ0skQuVOA7flT9HFLh7JSWVpaqI4/zf2UlDG8lj2RnAy1z6XmX/atXxcXTQkaHVd/js6zNZ6eQ88eq9waN6d5BeC+Esu7Tq3rYV3zsl4rZr0keu1r+UvKfiy7ansJ3nUp5yyi+7bi0S27dD/lmJYG3spvEv1e1+YosqeiiezfaJapf1swdwohhOxTuIgTQsjAcBEnhJCBGUITr73iydPgMjX9z6tTizteVmyz58uir7TSdQBUtXNr/jJag7eo7TOUdbQmq8eOxE5bbXryoFvj9MT59syntsO6N3tstezQ47b2f7y468i45RiRe8nqtzVO1AZrjEW+Ny2dP2J367WBezFOnBBCyB6AizghhAwMF3FCCBmYYTTxTE/sdS7L753Umq9mrh7p2eO1K9vXzll9etqa9V7NXj3eGze6h9Crjbbi3KN1rLKa/ttjY+lz2V/PvdBjt4Vljxdn3rtHUJZ5bWt9ef2V57xrYfnbo7lHNfVFdHirfmRvIaPvlbm6ODVxQgjZp3ARJ4SQgeEiTgghAzOMJt6jkWVq2mUrtrQVC1r27+l4tTFqWu4Ln7uwJRey1aZX0y21OC+3hzVH1niedqvbW7T002g+dUu/benB3vzkvB45Lj7avuZbRN8ur3XetynPeX1ac9CKd++NwW7tYdR8r5WV53piuzO1daCsY/nTk/O/tBHYugZF9yOsPYe5UBMnhJB9ChdxQggZGC7ihBAyMPtGE++JBa1p2MB2jXRuPHempcV5Wmqup9/zqNt5dpR6a1SXL8utdxXWfLX0UO89oPoaeHHYLQ23FYNs9aXt1rmpvTjx1n6Hdy8BW98HW9NVvfEtatez532XPTpzpF0tjlq3tz5748/R8q2+gO1532tzXV6rViz9MnXwEmrihBCyT+EiTgghAzOMnAL4jxqXx5HXY3llPUR+bmabSx90m8jPck+O8X7KlmlP8/g5fM2SiKLhjy1/W/30/kS36nrnvPDMiMw152d8zeeeVLWWHS25oUeqsuy1ZMNMr3RZjplTW+iwUD2fuU5LdtF41867d6Lz0CsnlvVadug5mgvlFEII2adwESeEkIHhIk4IIQMzjCZu6WfnTp/YpsN5YWT5XKYWMtijK1rtI2Po/qz+td5We6zc05trNrf0XktztebCw2tnafiWjq198cbu8b3WJqKXaht0n717LC1frbr6Wnlz2NLae+xrXZdo314IYhkS6b1mzhq3Zmct7NEKAa2FfrbCdHV9fQzMT0MLUBMnhJB9CxdxQggZGC7ihBAyMEMt4llfOrZyCMdWDuGmOx7CsZVDuPzggaYuWT6KrOuUxy987gIeW39+ix5X09g8G/XY3rHXT7ah/Py60/dtq3/21uM4tnIIa8+cx2Prz+Psrccvluk6LY6tHNoSM/zJ933rxbHPnT6BYyuHLs6h9qWcp/I4tyvb5PP5uBwnl2d/yjk/d/oEzp0+cfF8LtfzVo7vkfv2dNNMec9Y7ctz5eeyfrbdmh8L63xt7wLYmrI3+3LTHQ9tufbaXu+a5ePWHoGu05p7qzzPy+UHD1z04XWn79tyr9e+JyVZc9Z1tQau561MiZC/9/q+KL+Len7KsXvsXRZDLeKEEEK2wkWcEEIGZqFFXETeIiJPisjTInJqWUYRQgiJMTtOXEQuA/C3AG4A8CyAjwJ4Z0rpMa/NorlTgHm5LCysfspYVSuutCfuVuuJtXhpi1r8acQXq24r/ase38oLUY7ZqtuK47b8rcWE1+J1F+lDa5uez15a2Z69Ek/TtsYv63mvYrPaZnrj3b163vzUiMaUZ9+A7c+DaB+0X148uX6+wbtvWvdCaXftWmm7vLZ7MU78jQCeTin9XUrpvwD8HoAbF+iPEEJIJ4ss4q8C8Oni87NT2RZE5BYRWRORtY2NjQWGI4QQollkERejbJs2k1K6M6W0mlJaPXLkyALDEUII0SyiiR8HcDqldGL6fBsApJTe57WZq4kTQsj/Z3ZKE/8ogGtE5DUi8lIA7wBwzwL9EUII6eRAu4pNSumCiPwIgPsAXAbg/SmlTyzNMkIIIU1mL+IAkFL6YwB/vCRbCCGEdMInNgkhZGC4iBNCyMBwESeEkIHhIk4IIQPDRZwQQgaGizghhAwMF3FCCBkYLuKEEDIws3OnzBpMZAPAP8xs/koA/7JEcy4l+8WX/eIHQF/2KvRlky9NKZkZBHd1EV8EEVnzEsCMxn7xZb/4AdCXvQp9aUM5hRBCBoaLOCGEDMxIi/idl9qAJbJffNkvfgD0Za9CXxoMo4kTQgjZzkj/EyeEEKLgIk4IIQOz5xdxEXmLiDwpIk+LyKlLbY+FiLxaRP5CRB4XkU+IyLun8sMicr+IPDX9vaJoc9vk05MicqIo/yoROTed+2URsV5IvdP+XCYify0i9w7uxytE5A9E5Inp2hwf2Jcfm+6tR0XkgyLyslF8EZH3i8hzIvJoUbY020XkoIicncofFpGju+zLz0/32MdF5MMi8opd9SWltGf/YfO1b58E8FoALwXwNwCOXWq7DDtXAHzldPyFAP4WwDEAPwfg1FR+CsDPTsfHJl8OAnjN5ONl07mPADgOQAD8CYBvvgT+/DiA3wVw7/R5VD/OAPiB6filAF4xoi8AXgXg7wF8/vT5LgDfN4ovAL4OwFcCeLQoW5rtAH4IwK9Nx+8AcHaXffkmAAem45/dbV929Us1Y8KOA7iv+HwbgNsutV0Bu+8GcAOAJwGsTGUrAJ60/MDme0qPT3WeKMrfCeCOXbb9agAPAPgGvLiIj+jHIWwufKLKR/TlVQA+DeAwNl+peO+0cAzjC4CjauFbmu25znR8AJtPRcpu+aLOfTuAD+ymL3tdTsk3b+bZqWzPMv38eQOAhwFclVJaB4Dp75VTNc+vV03Hunw3+SUAPwngf4uyEf14LYANAL85SUO/LiIvx4C+pJT+EcAvAPgUgHUA/5ZS+jMM6EvBMm2/2CaldAHAvwH44h2zvM73Y/N/1lvsmtgRX/b6Im7pdXs2JlJEvgDAHwL40ZTS87WqRlmqlO8KIvJWAM+llB6JNjHKLrkfEwew+bP3V1NKbwDwn9j82e6xZ32Z9OIbsfmT/EsAvFxE3lVrYpTtCV8CzLF9T/glIu8FcAHAB3KRUW3pvuz1RfxZAK8uPl8N4DOXyJYqIvISbC7gH0gpfWgq/mcRWZnOrwB4bir3/Hp2Otblu8WbAXybiDwD4PcAfIOI/A7G8wOTDc+mlB6ePv8BNhf1EX35RgB/n1LaSCn9N4APAfgajOlLZpm2X2wjIgcAfBGA8ztmuYGInATwVgDfnSYtBLvky15fxD8K4BoReY2IvBSbQv89l9imbUw7y78B4PGU0i8Wp+4BcHI6PolNrTyXv2PaiX4NgGsAfGT6WfnvIvKmqc/vLdrsOCml21JKV6eUjmJzrv88pfSu0fyYfPknAJ8WkWunousBPIYBfcGmjPImEbl8suF6AI9jTF8yy7S97Os7sXnf7uYv2LcAeA+Ab0spvVCc2h1fdmNTY8FNhG/BZrTHJwG891Lb49j4tdj8yfNxAB+b/n0LNrWsBwA8Nf09XLR57+TTkygiBACsAnh0Ovcr2MENmoZP1+HFjc0h/QDwegBr03X5IwBXDOzLzwB4YrLjt7EZ8TCELwA+iE0t/7+x+T/Nm5dpO4CXAfh9AE9jM+rjtbvsy9PY1LHzd//XdtMXPnZPCCEDs9flFEIIIRW4iBNCyMBwESeEkIHhIk4IIQPDRZwQQgaGizghhAwMF3FCCBmY/wNIc7zYRbcByAAAAABJRU5ErkJggg==\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 = 400 * 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
}