{
 "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 * nS, LOW: 0.25 * nS, OFF: 0 * nS}\n",
    "    INHIBITORY_NOISE_VARIANCE = {HIGH: 1.25 * 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.56318 s (4%) simulated in 10s, estimated 3m 23s remaining.\n",
      "1.14354 s (9%) simulated in 20s, estimated 3m 10s remaining.\n",
      "1.71849 s (14%) simulated in 30s, estimated 2m 59s remaining.\n",
      "2.23633 s (18%) simulated in 40s, estimated 2m 55s remaining.\n",
      "2.77594 s (23%) simulated in 50s, estimated 2m 46s remaining.\n",
      "3.29432 s (27%) simulated in 1m 0s, estimated 2m 39s remaining.\n",
      "3.83497 s (31%) simulated in 1m 10s, estimated 2m 29s remaining.\n",
      "4.37602 s (36%) simulated in 1m 20s, estimated 2m 19s remaining.\n",
      "4.91325 s (40%) simulated in 1m 30s, estimated 2m 10s remaining.\n",
      "5.4433 s (45%) simulated in 1m 40s, estimated 2m 0s remaining.\n",
      "5.98222 s (49%) simulated in 1m 50s, estimated 1m 51s remaining.\n",
      "6.48817 s (54%) simulated in 2m 0s, estimated 1m 42s remaining.\n",
      "7.00727 s (58%) simulated in 2m 10s, estimated 1m 33s remaining.\n",
      "7.54267 s (62%) simulated in 2m 20s, estimated 1m 23s remaining.\n",
      "8.0788 s (67%) simulated in 2m 30s, estimated 1m 13s remaining.\n",
      "8.60315 s (71%) simulated in 2m 40s, estimated 1m 3s remaining.\n",
      "9.12369 s (76%) simulated in 2m 50s, estimated 54s remaining.\n",
      "9.65205 s (80%) simulated in 3m 0s, estimated 44s remaining.\n",
      "10.18565 s (84%) simulated in 3m 10s, estimated 34s remaining.\n",
      "10.71432 s (89%) simulated in 3m 20s, estimated 24s remaining.\n",
      "11.24537 s (93%) simulated in 3m 30s, estimated 14s remaining.\n",
      "11.77302 s (98%) simulated in 3m 40s, estimated 4s remaining.\n",
      "12. s (100%) simulated in 3m 44s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.collections.EventCollection at 0x1fba2444880>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba245f280>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2470a30>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2482310>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2491c70>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24a3610>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24b1e50>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24c27c0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24d60d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24e4af0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba24f53d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2503ca0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25165b0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2526eb0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2538790>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba254a0d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2558910>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba256a100>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2577a30>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba258a430>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2599d60>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25aa5e0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25b8d30>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25ca640>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25daf10>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25ec880>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba25fe220>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba260cac0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba261f3a0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba262dca0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba263f520>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba264cdc0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2660700>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba266ef40>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba267f850>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2693130>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26a19a0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26b3310>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26c1c40>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26d34c0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26e1d90>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba26f4790>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba27070d0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2714910>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2726250>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2735bb0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba27474c0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2754dc0>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2769640>,\n",
       " <matplotlib.collections.EventCollection at 0x1fba2776d90>]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\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.LOW, 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 = 100 * 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
}