{
 "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\" : 0*pA,\n",
    "        \"c\": 85 * pF,\n",
    "        \"tau_w\": 17.3695* 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": {},
   "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 3. s\n",
      "0.92722 s (30%) simulated in 10s, estimated 22s remaining.\n",
      "1.77367 s (59%) simulated in 20s, estimated 14s remaining.\n",
      "2.632 s (87%) simulated in 30s, estimated 4s remaining.\n",
      "3. s (100%) simulated in 34s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.collections.EventCollection at 0x26e2ad0dca0>]"
      ]
     },
     "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.OFF, n=1, # 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(50 * pA) # current should be scaled by 100x for Active Offset so (500nS is actually 5nS)\n",
    "model._set_variable(\"i_injected\", 120 * pA)\n",
    "\n",
    "\n",
    "model.run(3*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": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([  12.76,   62.87,  113.74,  164.23,  214.56,  264.81,  315.01,\n",
      "        365.19,  415.37,  465.58,  515.94,  572.54,  624.36,  675.12,\n",
      "        725.68,  782.36,  834.35,  885.17,  935.83,  992.64, 1044.44,\n",
      "       1095.23, 1145.94, 1202.72, 1254.46, 1305.22, 1355.86, 1412.65,\n",
      "       1464.44, 1515.22, 1565.88, 1622.67, 1674.44, 1725.21, 1775.85,\n",
      "       1832.64, 1884.43, 1935.2 , 1985.83, 2042.62, 2094.42, 2145.19,\n",
      "       2195.81, 2252.6 , 2304.42, 2355.2 , 2405.84, 2462.64, 2514.44,\n",
      "       2565.22, 2615.88, 2672.67, 2724.44, 2775.21, 2825.85, 2882.64,\n",
      "       2934.43, 2985.2 ])]\n"
     ]
    }
   ],
   "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 = 'data9.mat'\n",
    "scipy.io.savemat(file_path, {'data9': spike_times[0]})\n",
    "\n",
    "# file_path = 'data1.mat'\n",
    "# scipy.io.savemat(file_path, {'data1': spike_times[0]})\n",
    "\n",
    "# file_path = 'data2.mat'\n",
    "# scipy.io.savemat(file_path, {'data2': spike_times[0]})\n",
    "\n",
    "# file_path = 'data3.mat'\n",
    "# scipy.io.savemat(file_path, {'data3': spike_times[0]})\n",
    "\n",
    "# file_path = 'data4.mat'\n",
    "# scipy.io.savemat(file_path, {'data4': spike_times[0]})\n",
    "\n",
    "# file_path = 'data5.mat'\n",
    "# scipy.io.savemat(file_path, {'data5': spike_times[0]})\n",
    "\n",
    "# file_path = 'data6.mat'\n",
    "# scipy.io.savemat(file_path, {'data6': spike_times[0]})\n",
    "\n",
    "# file_path = 'data7.mat'\n",
    "# scipy.io.savemat(file_path, {'data7': spike_times[0]})\n",
    "\n",
    "# file_path = 'data8.mat'\n",
    "# scipy.io.savemat(file_path, {'data8': spike_times[0]})\n",
    "\n",
    "# file_path = 'data9.mat'\n",
    "# scipy.io.savemat(file_path, {'data9': spike_times[0]})\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
}