diff --git a/README.md b/README.md index 9c82bec131843f334d01b194a2003da007826087..b8cb421ba43b447ae1fef2a2ff40797fc46c8265 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,17 @@ The SLN fit in `multiarea_model/data_multiarea/VisualCortex_Data.py` and `figure The calculation of BOLD signals from the simulated firing rates for Fig. 8 of [3] requires an installation of R and the R library `neuRosim` (<https://cran.r-project.org/web/packages/neuRosim/index.html>). +## Testing on EBRAINS + +The Jupyter Notebook `multi-area-model.ipynb` illustrates the simulation workflow with a down-scaled version of the multi-area model. This notebook can be explored and executed online in the Jupyter Lab provided by EBRAINS without the need to install any software yourself. + +1. Create a fork of this repository. Copy the address of your fork by clicking on `Code`, `HTTPS`, and then the copy icon. +2. Go to https://lab.de.ebrains.eu, log in, and select a computing center from the given list. +3. In the Jupyter Lab, click on the `Git Clone` icon and paste the address of your fork. +4. Enter the folder `multi-area-model` with the cloned repository and open the notebook `multi-area-model.ipynb`. Make sure that the kernel (top right) is set to `EBRAINS_experimental_release`. +5. Run the notebook! +6. You can also modify the code, do git commits, and push your changes to your own fork. + ## Contributors All authors of the publications [1-3] made contributions to the diff --git a/multi-area-model.ipynb b/multi-area-model.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..765111899f6ff1ab91d8a16bcea30fd4976735d1 --- /dev/null +++ b/multi-area-model.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b1331599", + "metadata": {}, + "source": [ + "# Down-scaled multi-area model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96517739", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e07b0d0", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install nested_dict dicthash" + ] + }, + { + "cell_type": "markdown", + "id": "0c6b6a3c", + "metadata": {}, + "source": [ + "Create config file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72c170e4", + "metadata": {}, + "outputs": [], + "source": [ + "with open('config.py', 'w') as fp:\n", + " fp.write(\n", + "'''import os\n", + "base_path = os.path.abspath(\".\")\n", + "data_path = os.path.abspath(\"simulations\")\n", + "jobscript_template = \"python {base_path}/run_simulation.py {label}\"\n", + "submit_cmd = \"bash -c\"\n", + "''')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2784f76b", + "metadata": {}, + "outputs": [], + "source": [ + "from multiarea_model import MultiAreaModel" + ] + }, + { + "cell_type": "markdown", + "id": "2cedd26b", + "metadata": {}, + "source": [ + "Neurons and indegrees are both scaled down to 0.5%.\n", + "Can usually be simulated on a local machine.\n", + "\n", + "**Warning: This will not yield reasonable dynamical results from the\n", + "network and is only meant to demonstrate the simulation workflow.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e940bb6b", + "metadata": {}, + "outputs": [], + "source": [ + "scale_down_to = 0.005" + ] + }, + { + "cell_type": "markdown", + "id": "d53f1eab", + "metadata": {}, + "source": [ + "Specify model and simulation parameters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7af3a191", + "metadata": {}, + "outputs": [], + "source": [ + "conn_params = {'replace_non_simulated_areas': 'het_poisson_stat',\n", + " 'g': -11.,\n", + " \n", + " 'K_stable': 'K_stable.npy',\n", + " 'fac_nu_ext_TH': 1.2,\n", + " 'fac_nu_ext_5E': 1.125,\n", + " 'fac_nu_ext_6E': 1.41666667,\n", + " 'av_indegree_V1': 3950.}\n", + "input_params = {'rate_ext': 10.}\n", + "neuron_params = {'V0_mean': -150.,\n", + " 'V0_sd': 50.}\n", + "network_params = {'N_scaling': scale_down_to,\n", + " 'K_scaling': scale_down_to,\n", + " 'fullscale_rates': 'tests/fullscale_rates.json',\n", + " 'input_params': input_params,\n", + " 'connection_params': conn_params,\n", + " 'neuron_params': neuron_params}\n", + "\n", + "sim_params = {'t_sim': 2000.,\n", + " 'num_processes': 1,\n", + " 'local_num_threads': 1,\n", + " 'recording_dict': {'record_vm': False}}\n", + "\n", + "theory_params = {'dt': 0.1}" + ] + }, + { + "cell_type": "markdown", + "id": "de4a6703", + "metadata": {}, + "source": [ + "Instantiate a multi-area model, predict firing rates from theroy, and run the simulation. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d409be95", + "metadata": {}, + "outputs": [], + "source": [ + "M = MultiAreaModel(network_params, simulation=True,\n", + " sim_spec=sim_params,\n", + " theory=True,\n", + " theory_spec=theory_params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "918d907f", + "metadata": {}, + "outputs": [], + "source": [ + "p, r = M.theory.integrate_siegert()\n", + "print(\"Mean-field theory predicts an average \"\n", + " \"rate of {0:.3f} spikes/s across all populations.\".format(np.mean(r[:, -1])))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15778e9c", + "metadata": {}, + "outputs": [], + "source": [ + "M.simulation.simulate()" + ] + }, + { + "cell_type": "markdown", + "id": "8726a93d", + "metadata": {}, + "source": [ + "Load spike data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb8e3edd", + "metadata": {}, + "outputs": [], + "source": [ + "data = np.loadtxt(M.simulation.data_dir + '/recordings/' + M.simulation.label + \"-spikes-1-0.dat\", skiprows=3)" + ] + }, + { + "cell_type": "markdown", + "id": "8793e033", + "metadata": {}, + "source": [ + "Compute instantaneous rate per neuron across all populations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9590223b", + "metadata": {}, + "outputs": [], + "source": [ + "tsteps, spikecount = np.unique(data[:,1], return_counts=True)\n", + "rate = spikecount / M.simulation.params['dt'] * 1e3 / np.sum(M.N_vec)" + ] + }, + { + "cell_type": "markdown", + "id": "38ddd973", + "metadata": {}, + "source": [ + "Plot instantaneous and mean rate." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bea30fc8", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.plot(tsteps, rate)\n", + "ax.plot(tsteps, np.average(rate)*np.ones(len(tsteps)), label='mean')\n", + "ax.set_title('instantaneous rate across all populations')\n", + "ax.set_xlabel('time (ms)')\n", + "ax.set_ylabel('rate (spikes / s)')\n", + "ax.set_xlim(0, sim_params['t_sim'])\n", + "ax.set_ylim(0, 50)\n", + "ax.legend()" + ] + } + ], + "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.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/multiarea_model/data_multiarea/VisualCortex_Data.py b/multiarea_model/data_multiarea/VisualCortex_Data.py index bc84ee5c63c2740dda3e77f87f08f5baa4a4dcab..d5c866ea52bcd1588bec24a6a959ccad0891114e 100644 --- a/multiarea_model/data_multiarea/VisualCortex_Data.py +++ b/multiarea_model/data_multiarea/VisualCortex_Data.py @@ -1325,8 +1325,8 @@ def process_raw_data(): out = proc.communicate()[0].decode('utf-8') R_fit = [float(out.split('\n')[1].split(' ')[1]), float(out.split('\n')[1].split(' ')[3])] - except OSError: - print("No R installation, taking hard-coded SLN fit parameters.") + except (OSError, IndexError): + print("No R installation or IndexError, taking hard-coded SLN fit parameters.") R_fit = [-0.1516142, -1.5343200] """