diff --git a/.ipynb_checkpoints/multi-area-model-checkpoint.ipynb b/.ipynb_checkpoints/multi-area-model-checkpoint.ipynb index ca06226bdef60d7f794a8fe162ad87ae7d43b7bd..ab7ae2504ea3bb423670a84480ecde42ea785b26 100644 --- a/.ipynb_checkpoints/multi-area-model-checkpoint.ipynb +++ b/.ipynb_checkpoints/multi-area-model-checkpoint.ipynb @@ -23,10 +23,16 @@ "* [S2. Multi-area model instantiation and simulation](#section_2)\n", " * [2.1. Insantiate a multi-area model](#section_2_1)\n", " * [2.2. Predict firing rates from theory](#section_2_2)\n", - " * [2.3. Extract connectivity](#section_2_3)\n", + " * [2.3. Extract interarea connectivity](#section_2_3)\n", " * [2.4. Run the simulation](#section_2_4)\n", - "* [S3. Data processing and simulation results analysis](#section_3)\n", - "* [S4. Simulation results visualization](#section_4) " + "* [S3. Simulation results analysis and data processing](#section_3)\n", + "* [S4. Simulation results visualization](#section_4) \n", + " * [4.1. Instantaneous firing rate and mean firing rate](#section_4_1)\n", + " * [4.2. Raster plot of spiking activity for single area](#section_4_2)\n", + " * [4.3. Population-averaged firing rate](#section_4_3)\n", + " * [4.4. Average pairwise correlation coefficients of spiking activity](#section_4_4)\n", + " * [4.5. Irregularity of spiking activity](#section_4_5)\n", + " * [4.6. Time series of population- and area-averaged firing rates](#section_4_6)" ] }, { @@ -50,34 +56,12 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "96517739", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " -- N E S T --\n", - " Copyright (C) 2004 The NEST Initiative\n", - "\n", - " Version: 3.4\n", - " Built: May 17 2023 20:48:31\n", - "\n", - " This program is provided AS IS and comes with\n", - " NO WARRANTY. See the file LICENSE for details.\n", - "\n", - " Problems or suggestions?\n", - " Visit https://www.nest-simulator.org\n", - "\n", - " Type 'nest.help()' to find out more about NEST.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# Import dependencies\n", "%matplotlib inline\n", @@ -89,12 +73,13 @@ "\n", "# Import the MultiAreaModel class\n", "from multiarea_model import MultiAreaModel\n", + "from multiarea_model import Analysis\n", "from config import base_path" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "2dd47c64", "metadata": {}, "outputs": [], @@ -112,48 +97,22 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "7e07b0d0", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: nested_dict in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (1.61)\n", - "Requirement already satisfied: dicthash in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (0.0.2)\n", - "Requirement already satisfied: future in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (from dicthash) (0.18.2)\n" - ] - } - ], + "outputs": [], "source": [ "!pip install nested_dict dicthash" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "1d440c07-9b69-4e52-8573-26b13493bc5a", "metadata": { "tags": [] }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "<style>\n", - "table {float:left}\n", - "</style>\n" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Jupyter notebook display format setting\n", "style = \"\"\"\n", @@ -184,6 +143,7 @@ "cell_type": "markdown", "id": "df83f5ea-1c4b-44d3-9926-01786aa46e14", "metadata": { + "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ @@ -217,20 +177,20 @@ "metadata": {}, "source": [ "1. `scale_down_to` <br>\n", - "`scale_down_to` is the down-scaling factor which defines the the ratio of the full scale multi-area model being down-scaled to a model with fewer neurons and indegrees so as to be simulated on machines with lower computational ability and the simulation results can be obtained within relative shorter period of time. <br> Its deafualt value if 1. meaning full scale simulation. <br> In the pre-set downscale version, it's set as 0.005, where the numer of neurons and indegrees are both scaled down to 0.5% of its full scale amount, where the model can usually be simulated on a local machine. <br> **Warning**: This will not yield reasonable dynamical results from the network and is only meant to demonstrate the simulation workflow <br> \n", + "`scale_down_to` is the down-scaling factor which defines the the ratio of the full scale multi-area model being down-scaled to a model with fewer neurons and indegrees so as to be simulated on machines with lower computational ability and the simulation results can be obtained within relative shorter period of time. <br> Its deafualt value if `1.` meaning full scale simulation. <br> In the pre-set downscale version, it's set as `0.005`, where the numer of neurons and indegrees are both scaled down to 0.5% of its full scale amount, where the model can usually be simulated on a local machine. <br> **Warning**: This will not yield reasonable dynamical results from the network and is only meant to demonstrate the simulation workflow <br> \n", "2. `cc_weights_factor` <br>\n", - "This scaling factor controls the cortico-cortical synaptic strength. <br> By default it's set as 1.0, where the inter-area synaptic strength is the same as the intra-areal. <br> **Important**: This factor changes the network activity from ground state to metastable state. <br>\n", + "This scaling factor controls the cortico-cortical synaptic strength. <br> By default it's set as `1.0`, where the inter-area synaptic strength is the same as the intra-areal. <br> **Important**: This factor changes the network activity from ground state to metastable state. <br>\n", "3. `areas_simulated` <br>\n", "This parameter specifies the cortical areas included in the simulation process. Its default value is `complete_area_list` meaning all the areas in the complete_area_list will be actually simulated. <br>\n", "complete_area_list = ['V1', 'V2', 'VP', 'V3', 'V3A', 'MT', 'V4t', 'V4', 'VOT', 'MSTd', 'PIP', 'PO', 'DP', 'MIP', 'MDP', 'VIP', 'LIP', 'PITv', 'PITd', 'MSTl', 'CITv', 'CITd', 'FEF', 'TF', 'AITv', 'FST', '7a', 'STPp', 'STPa', '46', 'AITd', 'TH'] <br>\n", - "The value assigned to simulation_areas can be any sublist of the `compete_area_list` specifying areas a user want to include in his/her simulation. <br>\n", + "The value assigned to simulation_areas can be any sublist of the compete_area_list specifying areas a user want to include in his/her simulation. <br>\n", "4. `replace_non_simulated_areas` <br>\n", - "The paramter `replace_non_simulated_areas` defines how non-simulated areas will be replaced. <br> It's set as None by default when the parameter areas_simulated is set as full_area_list where all areas will be simulated so that no areas need to be replaced. <br> Other options are: 'hom_poisson_stat', 'het_poisson_stat', and 'het_current_nonstat'. 'hom_poisson_stat' is a manually set parameter which can be tuned. When it's set as 'het_poisson_stat' or 'het_current_nonstat', the data to replace the cortico-cortical input is loaded from 'replace_cc_input_source' which is the firing rates of our full scale simulation results. The differenc between 'het_poisson_stat' and 'het_current_nonstat' is that 'het_poisson_stat' is the mean of the time-series firing rate so that it's static, yet 'het_current_nonstat' is time-varying specific current, which is varying by time. " + "The paramter `replace_non_simulated_areas` defines how non-simulated areas will be replaced. <br> It's set as `None` by default when the parameter areas_simulated is set as full_area_list where all areas will be simulated so that no areas need to be replaced. <br> Other options are: `'hom_poisson_stat'`, `'het_poisson_stat'`, and `'het_current_nonstat'`. `'hom_poisson_stat'` is a manually set parameter which can be tuned. When it's set as 'het_poisson_stat' or 'het_current_nonstat', the data to replace the cortico-cortical input is loaded from 'replace_cc_input_source' which is the firing rates of our full scale simulation results. The differenc between 'het_poisson_stat' and 'het_current_nonstat' is that 'het_poisson_stat' is the mean of the time-series firing rate so that it's static, yet 'het_current_nonstat' is time-varying specific current, which is varying by time. " ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "60265d52", "metadata": {}, "outputs": [], @@ -259,53 +219,56 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "6e4bed8d", "metadata": {}, "outputs": [], "source": [ - "# Connection parameters (conn_params)\n", + "# Connection parameters\n", "conn_params = {\n", - " # # It defines how non-simulated areas will be replaced\n", - " # Whether to replace non-simulated areas by Poisson sources with the same global rate rate_ext ('hom_poisson_stat') or by specific rates ('het_poisson_stat') or by time-varying specific current ('het_current_nonstat'). In the two latter cases, the data to replace the cortico-cortical input is loaded from `replace_cc_input_source`\n", - " 'replace_non_simulated_areas': 'het_poisson_stat', \n", - "\n", - " 'g': -11.,\n", - " 'K_stable': 'K_stable.npy',\n", - " # Increase the external input to 2/3E and 5E in area TH\n", - " 'fac_nu_ext_TH': 1.2,\n", - " # Increase the external Poisson indegree onto 5E\n", - " 'fac_nu_ext_5E': 1.125,\n", - " # Increase the external Poisson indegree onto 6E\n", - " 'fac_nu_ext_6E': 1.41666667,\n", - " # Adjust the average indegree in V1 based on monkey data\n", - " 'av_indegree_V1': 3950.\n", + " 'replace_non_simulated_areas': 'het_poisson_stat', # Whether to replace non-simulated areas by Poisson sources with the same global rate, by default: None\n", + " 'g': -11., # It sets the relative inhibitory synaptic strength, by default: -16.\n", + " 'K_stable': 'K_stable.npy', # Whether to apply the stabilization method of Schuecker, Schmidt et al. (2017), by default: None\n", + " 'fac_nu_ext_TH': 1.2, # Increase the external input to 2/3E and 5E in area TH\n", + " 'fac_nu_ext_5E': 1.125, # Increase the external Poisson indegree onto 5E\n", + " 'fac_nu_ext_6E': 1.41666667, # Increase the external Poisson indegree onto 6E\n", + " 'av_indegree_V1': 3950. # Adjust the average indegree in V1 based on monkey data\n", "}\n", "\n", - "# Input parameters (input_params)\n", - "input_params = {'rate_ext': 10.}\n", + "# Input parameters\n", + "input_params = {\n", + " 'rate_ext': 10. # Rate of the Poissonian spike generator (in spikes/s)\n", + "} \n", "\n", - "# Neuron parameters (neuron_params)\n", - "neuron_params = {'V0_mean': -150.,\n", - " 'V0_sd': 50.}\n", + "# Neuron parameters\n", + "neuron_params = {\n", + " 'V0_mean': -150., # Mean for the distribution of initial membrane potentials, by default: -100.\n", + " 'V0_sd': 50.} # Standard deviation for the distribution of initial membrane potentials, by default: 50.\n", "\n", - "# Network parameters (network_params)\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", + "# Network parameters\n", + "network_params = {\n", + " 'N_scaling': scale_down_to, # Scaling of population sizes, by default: 1.\n", + " 'K_scaling': scale_down_to, # Scaling of indegrees, by default: 1.\n", + " 'fullscale_rates': 'tests/fullscale_rates.json', # Absolute path to the file holding full-scale rates for scaling synaptic weights, by default: None\n", + " 'input_params': input_params, # Input parameters\n", + " 'connection_params': conn_params, # Connection parameters\n", + " 'neuron_params': neuron_params # Neuron parameters\n", + "} \n", "\n", - "# Simulation parameters (sim_params)\n", - "sim_params = {'t_sim': 2000.,\n", - " 'num_processes': 1,\n", - " 'local_num_threads': 1,\n", - " 'recording_dict': {'record_vm': False},\n", - " 'rng_seed': 1} # global random seed\n", + "# Simulation parameters\n", + "sim_params = {\n", + " 'areas_simulated': areas_simulated,\n", + " 't_sim': 2000., # Simulated time (in ms), by default: 10.0\n", + " 'num_processes': 1, # The number of MPI processes, by default: 1\n", + " 'local_num_threads': 1, # The number of threads per MPI process, by default: 1\n", + " 'recording_dict': {'record_vm': False},\n", + " 'rng_seed': 1 # global random seed\n", + "}\n", "\n", "# Theory paramters (theory_params)\n", - "theory_params = {'dt': 0.1}" + "theory_params = {\n", + " 'dt': 0.1 # The time step of the mean-field theory integration, by default: 0.01\n", + "} " ] }, { @@ -327,7 +290,10 @@ { "cell_type": "markdown", "id": "de4a6703", - "metadata": {}, + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, "source": [ "## S2. Multi-area model instantiation and simulation <a class=\"anchor\" id=\"section_2\"></a>" ] @@ -342,72 +308,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "ab25f9f8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initializing network from dictionary.\n", - "RAND_DATA_LABEL 3497\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/core/fromnumeric.py:3440: RuntimeWarning:Mean of empty slice.\n", - "/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/core/_methods.py:189: RuntimeWarning:invalid value encountered in double_scalars\n", - "Error in library(\"aod\") : there is no package called ‘aod’\n", - "Execution halted\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "No R installation or IndexError, taking hard-coded SLN fit parameters.\n", - "\n", - "\n", - "========================================\n", - "Customized parameters\n", - "--------------------\n", - "{'K_scaling': 0.005,\n", - " 'N_scaling': 0.005,\n", - " 'connection_params': {'K_stable': 'K_stable.npy',\n", - " 'av_indegree_V1': 3950.0,\n", - " 'fac_nu_ext_5E': 1.125,\n", - " 'fac_nu_ext_6E': 1.41666667,\n", - " 'fac_nu_ext_TH': 1.2,\n", - " 'g': -11.0,\n", - " 'replace_non_simulated_areas': 'het_poisson_stat'},\n", - " 'fullscale_rates': 'tests/fullscale_rates.json',\n", - " 'input_params': {'rate_ext': 10.0},\n", - " 'neuron_params': {'V0_mean': -150.0, 'V0_sd': 50.0}}\n", - "========================================\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/view/lib/python3.8/site-packages/dicthash/dicthash.py:47: UserWarning:Float too small for safe conversion tointeger. Rounding down to zero.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Simulation label: 27d81076e6d6e9e591684be053078477\n", - "Copied files.\n", - "Initialized simulation class.\n" - ] - } - ], - "source": [ - "M = MultiAreaModel(network_params, simulation=True,\n", + "outputs": [], + "source": [ + "M = MultiAreaModel(network_params, \n", + " simulation=True,\n", " sim_spec=sim_params,\n", " theory=True,\n", " theory_spec=theory_params)" @@ -423,23 +330,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "6a7ddf0e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Iteration: 0\n", - "Mean-field theory predicts an average rate of 29.588 spikes/s across all populations.\n" - ] - } - ], + "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])))" + " \"firing rate of {0:.3f} spikes/s across all populations.\".format(np.mean(r[:, -1])))" ] }, { @@ -447,7 +345,7 @@ "id": "2062ddf3", "metadata": {}, "source": [ - "### 2.3. Extract connectivity <a class=\"anchor\" id=\"section_2_3\"></a>" + "### 2.3. Extract interarea connectivity <a class=\"anchor\" id=\"section_2_3\"></a>" ] }, { @@ -455,9 +353,7 @@ "id": "8a7c09e0", "metadata": {}, "source": [ - "The connectivity and neuron numbers are stored in the attributes of the model class. Neuron numbers are stored in `M.N` as a dictionary (and in `M.N_vec` as an array), indegrees in `M.K` as a dictionary (and in `M.K_matrix` as an array). Number of synapses can also be access via `M.synapses` (and in `M.syn_matrix` as an array). <br>\n", - "\n", - "**Warning**: memory explosion" + "The connectivity and neuron numbers are stored in the attributes of the model class. Neuron numbers are stored in `M.N` as a dictionary (and in `M.N_vec` as an array), indegrees in `M.K` as a dictionary (and in `M.K_matrix` as an array). Number of synapses can also be access via `M.synapses` (and in `M.syn_matrix` as an array). <br>" ] }, { @@ -470,7 +366,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "6316ac24", "metadata": {}, "outputs": [], @@ -490,7 +386,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "445a722a", "metadata": {}, "outputs": [], @@ -526,85 +422,10 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "15778e9c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Prepared simulation in 0.00 seconds.\n", - "Rank 0: created area V1 with 0 local nodes\n", - "Memory after V1 : 1912.20 MB\n", - "Rank 0: created area V2 with 0 local nodes\n", - "Memory after V2 : 1938.80 MB\n", - "Rank 0: created area VP with 0 local nodes\n", - "Memory after VP : 1967.95 MB\n", - "Rank 0: created area V3 with 0 local nodes\n", - "Memory after V3 : 1996.29 MB\n", - "Rank 0: created area V3A with 0 local nodes\n", - "Memory after V3A : 2016.27 MB\n", - "Rank 0: created area MT with 0 local nodes\n", - "Memory after MT : 2041.77 MB\n", - "Rank 0: created area V4t with 0 local nodes\n", - "Memory after V4t : 2066.75 MB\n", - "Rank 0: created area V4 with 0 local nodes\n", - "Memory after V4 : 2093.70 MB\n", - "Rank 0: created area VOT with 0 local nodes\n", - "Memory after VOT : 2119.05 MB\n", - "Rank 0: created area MSTd with 0 local nodes\n", - "Memory after MSTd : 2140.52 MB\n", - "Rank 0: created area PIP with 0 local nodes\n", - "Memory after PIP : 2161.88 MB\n", - "Rank 0: created area PO with 0 local nodes\n", - "Memory after PO : 2183.38 MB\n", - "Rank 0: created area DP with 0 local nodes\n", - "Memory after DP : 2203.54 MB\n", - "Rank 0: created area MIP with 0 local nodes\n", - "Memory after MIP : 2225.19 MB\n", - "Rank 0: created area MDP with 0 local nodes\n", - "Memory after MDP : 2246.54 MB\n", - "Rank 0: created area VIP with 0 local nodes\n", - "Memory after VIP : 2268.48 MB\n", - "Rank 0: created area LIP with 0 local nodes\n", - "Memory after LIP : 2292.54 MB\n", - "Rank 0: created area PITv with 0 local nodes\n", - "Memory after PITv : 2317.88 MB\n", - "Rank 0: created area PITd with 0 local nodes\n", - "Memory after PITd : 2343.10 MB\n", - "Rank 0: created area MSTl with 0 local nodes\n", - "Memory after MSTl : 2364.56 MB\n", - "Rank 0: created area CITv with 0 local nodes\n", - "Memory after CITv : 2383.62 MB\n", - "Rank 0: created area CITd with 0 local nodes\n", - "Memory after CITd : 2402.95 MB\n", - "Rank 0: created area FEF with 0 local nodes\n", - "Memory after FEF : 2424.42 MB\n", - "Rank 0: created area TF with 0 local nodes\n", - "Memory after TF : 2440.07 MB\n", - "Rank 0: created area AITv with 0 local nodes\n", - "Memory after AITv : 2462.74 MB\n", - "Rank 0: created area FST with 0 local nodes\n", - "Memory after FST : 2479.47 MB\n", - "Rank 0: created area 7a with 0 local nodes\n", - "Memory after 7a : 2500.68 MB\n", - "Rank 0: created area STPp with 0 local nodes\n", - "Memory after STPp : 2519.40 MB\n", - "Rank 0: created area STPa with 0 local nodes\n", - "Memory after STPa : 2538.59 MB\n", - "Rank 0: created area 46 with 0 local nodes\n", - "Memory after 46 : 2553.95 MB\n", - "Rank 0: created area AITd with 0 local nodes\n", - "Memory after AITd : 2576.51 MB\n", - "Rank 0: created area TH with 0 local nodes\n", - "Memory after TH : 2589.22 MB\n", - "Created areas and internal connections in 2.15 seconds.\n", - "Created cortico-cortical connections in 22.44 seconds.\n", - "Simulated network in 59.50 seconds.\n" - ] - } - ], + "outputs": [], "source": [ "# run the simulation, depending on the model parameter and downscale ratio, the running time varies largely.\n", "M.simulation.simulate()" @@ -629,9 +450,12 @@ { "cell_type": "markdown", "id": "28e071f8", - "metadata": {}, + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, "source": [ - "## S3. Data processing and simulation results analysis <a class=\"anchor\" id=\"section_3\"></a>" + "## S3. Simulation results analysis <a class=\"anchor\" id=\"section_3\"></a>" ] }, { @@ -639,21 +463,18 @@ "id": "89c7b7cf", "metadata": {}, "source": [ - "The following instructions will work when the `simulate` parameter is set to `True` during the creation of the MultiAreaModel object, and the `M.simulation.simulate()` method is executed." + "### 3.1 Test if the correct number of synapses has been created" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "dc3b1820", "metadata": {}, "outputs": [], "source": [ - "# Uncomment the lines in this code cell below to test if the number of synapses created by NEST matches the expected values\n", + "# # Uncomment the lines in this code cell below to test if the number of synapses created by NEST matches the expected values\n", "\n", - "# \"\"\"\n", - "# Test if the correct number of synapses has been created.\n", - "# \"\"\"\n", "# print(\"Testing synapse numbers\")\n", "# for target_area_name in M.area_list:\n", "# target_area = M.simulation.areas[M.simulation.areas.index(target_area_name)]\n", @@ -674,12 +495,14 @@ "id": "57401110", "metadata": {}, "source": [ + "### 3.2 Extract connections information\n", + "**Warning**: Memory explosion <br>\n", "To obtain the connections information, you can extract the lists of connected sources and targets. Moreover, you can access additional synaptic details, such as synaptic weights and delays." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "e7eb052e", "metadata": {}, "outputs": [], @@ -702,7 +525,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "902f2800", "metadata": {}, "outputs": [], @@ -718,110 +541,129 @@ }, { "cell_type": "markdown", - "id": "8726a93d", + "id": "b1320ab1", "metadata": {}, "source": [ - "### 1. Load spike data" + "Go back to [Notebook structure](#toc)" ] }, { - "cell_type": "code", - "execution_count": 15, - "id": "cb8e3edd", + "cell_type": "markdown", + "id": "529b1ade", "metadata": {}, - "outputs": [], "source": [ - "data = np.loadtxt(M.simulation.data_dir + '/recordings/' + M.simulation.label + \"-spikes-1-0.dat\", skiprows=3)" + "<br>" ] }, { "cell_type": "markdown", - "id": "8793e033", + "id": "57ff902c-d6ce-4f96-9e4f-8e3e7166ab66", "metadata": {}, "source": [ - "### 2. Compute instantaneous rate per neuron across all populations" + "## S4. Data processing and simulation results visualization <a class=\"anchor\" id=\"section_4\"></a>" ] }, { "cell_type": "code", - "execution_count": 16, - "id": "9590223b", + "execution_count": null, + "id": "6806564b-d5d4-47d4-afa9-5da0df83e025", "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)" + "from config import data_path\n", + "label_spikes = M.simulation.label\n", + "label = M.simulation.label" ] }, { - "cell_type": "markdown", - "id": "b1320ab1", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "id": "7997d893-252d-4295-a22a-1e510f8424ae", + "metadata": { + "tags": [] + }, + "outputs": [], "source": [ - "Go back to [Notebook structure](#toc)" + "\"\"\"\n", + "Analysis class.\n", + "An instance of the analysis class for the given network and simulation.\n", + "Can be created as a member class of a multiarea_model instance or standalone.\n", + "\n", + "Parameters\n", + "----------\n", + "network : MultiAreaModel\n", + " An instance of the multiarea_model class that specifies\n", + " the network to be analyzed.\n", + "simulation : Simulation\n", + " An instance of the simulation class that specifies\n", + " the simulation to be analyzed.\n", + "data_list : list of strings {'spikes', vm'}, optional\n", + " Specifies which type of data is to load. Defaults to ['spikes'].\n", + "load_areas : list of strings with area names, optional\n", + " Specifies the areas for which data is to be loaded.\n", + " Default value is None and leads to loading of data for all\n", + " simulated areas.\n", + "\"\"\"\n", + "A = Analysis(network=M, \n", + " simulation=M.simulation, \n", + " data_list=['spikes'],\n", + " load_areas=None)" ] }, { - "cell_type": "markdown", - "id": "529b1ade", + "cell_type": "code", + "execution_count": null, + "id": "da58921f-713b-424c-8fa1-80d9755558f3", "metadata": {}, + "outputs": [], "source": [ - "<br>" + "\"\"\"\n", + "Loads simulation data of the requested type either from hdf5 files.\n", + "\n", + "Parameters\n", + "----------\n", + "\n", + "data_list : list\n", + " list of observables to be loaded. Can contain 'spikes' and 'vm'\n", + "\"\"\"\n", + "A.load_data(data_list=['spikes'])" ] }, { "cell_type": "markdown", - "id": "57ff902c-d6ce-4f96-9e4f-8e3e7166ab66", - "metadata": {}, + "id": "38ddd973", + "metadata": { + "tags": [] + }, "source": [ - "## S4. Simulation results visualization <a class=\"anchor\" id=\"section_4\"></a>" + "### 4.1. Instantaneous firing rate and mean firing rate <a class=\"anchor\" id=\"section_4_1\"></a>" ] }, { - "cell_type": "markdown", - "id": "38ddd973", + "cell_type": "code", + "execution_count": null, + "id": "56e368b6-72a2-43fb-b02e-f70ad6770e40", "metadata": {}, + "outputs": [], "source": [ - "### 4.1. Instantaneous and mean rate\n", - "avaerage over all areas" + "data = np.loadtxt(M.simulation.data_dir + '/recordings/' + M.simulation.label + \"-spikes-1-0.dat\", skiprows=3)\n", + "tsteps, spikecount = np.unique(data[:,1], return_counts=True)\n", + "rate = spikecount / M.simulation.params['dt'] * 1e3 / np.sum(M.N_vec)" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "bea30fc8", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "<matplotlib.legend.Legend at 0x7fbae4abbfa0>" - ] - }, - "execution_count": 17, - "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" - } - ], + "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_title('Instantaneous firing rate across all populations')\n", "ax.set_xlabel('time (ms)')\n", - "ax.set_ylabel('rate (spikes / s)')\n", + "ax.set_ylabel('Firing rate (spikes / s)')\n", "ax.set_xlim(0, sim_params['t_sim'])\n", "ax.set_ylim(0, 50)\n", "ax.legend()" @@ -830,90 +672,171 @@ { "cell_type": "markdown", "id": "ae19bcc3", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ - "### 4.2 Raster plot of spiking activity for single area\n", + "### 4.2 Raster plot of spiking activity for single area <a class=\"anchor\" id=\"section_4_2\"></a>\n", "Raster plot of spiking activity of 3% of the neurons in area V1 (A), V2 (B), and FEF (C). Blue: excitatory neurons, red: inhibitory neurons. (D-F) Spiking statistics across all 32 areas for the respective populations shown as area-averaged box plots. Crosses: medians, boxes: interquartile range (IQR), whiskers extend to the most extremeobservat ions within 1.5×IQR beyond the IQR." ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, + "id": "c47e82ec-32f3-4de1-a32e-8f6b500787e0", + "metadata": {}, + "outputs": [], + "source": [ + "areas = ['V1', 'V2', 'FEF']\n", + "labels = ['A', 'B', 'C']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4066f042-995f-4987-bac2-7d7c61addbd0", + "metadata": {}, + "outputs": [], + "source": [ + "# spike data \n", + "spike_data = {}\n", + "for area in areas:\n", + " spike_data[area] = {}\n", + " for pop in M.structure[area]:\n", + " spike_data[area][pop] = np.load(os.path.join(M.simulation.data_dir,\n", + " 'recordings',\n", + " '{}-spikes-{}-{}.npy'.format(label_spikes, area, pop)))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, "id": "1da18fee", "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'MultiAreaModel' object has no attribute 'analysis'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [18]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 20\u001b[0m area \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mV1\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 21\u001b[0m frac_neurons \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.03\u001b[39m\n\u001b[0;32m---> 22\u001b[0m \u001b[43mM\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43manalysis\u001b[49m\u001b[38;5;241m.\u001b[39msingle_dot_display(area, frac_neurons, t_min\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m500.\u001b[39m, t_max\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mT\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 24\u001b[0m area \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mV2\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 25\u001b[0m frac_neurons \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.03\u001b[39m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'MultiAreaModel' object has no attribute 'analysis'" - ] - } - ], + "outputs": [], "source": [ - "\"\"\"\n", - "Create raster display of a single area with populations stacked\n", - "onto each other. Excitatory neurons in blue, inhibitory\n", - "neurons in red.\n", + "# \"\"\"\n", + "# Create raster display of a single area with populations stacked onto each other. Excitatory neurons in blue, inhibitory neurons in red.\n", "\n", - "Parameters\n", - "----------\n", - "area : string {area}\n", - " Area to be plotted.\n", - "frac_neurons : float, [0,1]\n", - " Fraction of cells to be considered.\n", - "t_min : float, optional\n", - " Minimal time in ms of spikes to be shown. Defaults to 0 ms.\n", - "t_max : float, optional\n", - " Minimal time in ms of spikes to be shown. Defaults to simulation time.\n", - "output : {'pdf', 'png', 'eps'}, optional\n", - " If given, the function stores the plot to a file of the given format.\n", + "# Parameters\n", + "# ----------\n", + "# area : string {area}\n", + "# Area to be plotted.\n", + "# frac_neurons : float, [0,1]\n", + "# Fraction of cells to be considered.\n", + "# t_min : float, optional\n", + "# Minimal time in ms of spikes to be shown. Defaults to 0 ms.\n", + "# t_max : float, optional\n", + "# Minimal time in ms of spikes to be shown. Defaults to simulation time.\n", + "# output : {'pdf', 'png', 'eps'}, optional\n", + "# If given, the function stores the plot to a file of the given format.\n", "\n", - "\"\"\"\n", + "# \"\"\"\n", + "# t_min = 0.\n", + "# t_max = 500.\n", "\n", - " def init_analysis(self, ana_spec):\n", - " assert(hasattr(self, 'simulation'))\n", - " if 'load_areas' in ana_spec:\n", - " load_areas = ana_spec['load_areas']\n", - " else:\n", - " load_areas = None\n", - " if 'data_list' in ana_spec:\n", - " data_list = ana_spec['data_list']\n", - " else:\n", - " data_list = ['spikes']\n", - " self.analysis = Analysis(self, self.simulation,\n", - " data_list=data_list,\n", - " load_areas=load_areas)\n", - " \n", - "area = 'V1'\n", - "frac_neurons = 0.03\n", - "M.analysis.single_dot_display(area, frac_neurons, t_min=500., t_max='T')\n", + "# # Draw V1\n", + "# area = 'V1'\n", + "# frac_neurons = 1.\n", + "# A.single_dot_display(area, frac_neurons, t_min, t_max)\n", "\n", - "area = 'V2'\n", - "frac_neurons = 0.03\n", - "M.analysis.single_dot_display(area, frac_neurons, t_min=500., t_max='T')\n", + "# # Draw V2\n", + "# area = 'V2'\n", + "# frac_neurons = 1.\n", + "# A.single_dot_display(area, frac_neurons, t_min, t_max)\n", + "\n", + "# # Draw FEF\n", + "# area = 'FEF'\n", + "# frac_neurons = 1.\n", + "# A.single_dot_display(area, frac_neurons, t_min, t_max)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73ca1021-0f0a-45bb-a3d5-51381d1357c3", + "metadata": {}, + "outputs": [], + "source": [ + "for area, label in zip(areas, labels):\n", + " label_pos = [-0.2, 1.01]\n", + " pl.text(label_pos[0], label_pos[1], r'\\bfseries{}' + label + ': ' + area,\n", + " fontdict={'fontsize': 10, 'weight': 'bold',\n", + " 'horizontalalignment': 'left', 'verticalalignment':\n", + " 'bottom'}, transform=axes[label].transAxes)\n", + "print(\"Raster plots\")\n", + "\n", + "t_min = 3000.\n", + "t_max = 3500.\n", + "\n", + "icolor = myred\n", + "ecolor = myblue\n", "\n", - "area = 'FEF'\n", "frac_neurons = 0.03\n", - "M.analysis.single_dot_display(area, frac_neurons, t_min=500., t_max='T')" + "\n", + "for i, area in enumerate(areas):\n", + " ax = axes[labels[i]]\n", + "\n", + " if area in spike_data:\n", + " n_pops = len(spike_data[area])\n", + " # Determine number of neurons that will be plotted for this area (for\n", + " # vertical offset)\n", + " offset = 0\n", + " n_to_plot = {}\n", + " for pop in M.structure[area]:\n", + " n_to_plot[pop] = int(M.N[area][pop] * frac_neurons)\n", + " offset = offset + n_to_plot[pop]\n", + " y_max = offset + 1\n", + " prev_pop = ''\n", + " yticks = []\n", + " yticklocs = []\n", + " for jj, pop in enumerate(M.structure[area]):\n", + " if pop[0:-1] != prev_pop:\n", + " prev_pop = pop[0:-1]\n", + " yticks.append('L' + population_labels[jj][0:-1])\n", + " yticklocs.append(offset - 0.5 * n_to_plot[pop])\n", + " ind = np.where(np.logical_and(\n", + " spike_data[area][pop][:, 1] <= t_max, spike_data[area][pop][:, 1] >= t_min))\n", + " pop_data = spike_data[area][pop][ind]\n", + " pop_neurons = np.unique(pop_data[:, 0])\n", + " neurons_to_ = np.arange(np.min(spike_data[area][pop][:, 0]), np.min(\n", + " spike_data[area][pop][:, 0]) + n_to_plot[pop], 1)\n", + "\n", + " if pop.find('E') > (-1):\n", + " pcolor = ecolor\n", + " else:\n", + " pcolor = icolor\n", + "\n", + " for kk in range(n_to_plot[pop]):\n", + " spike_times = pop_data[pop_data[:, 0] == neurons_to_[kk], 1]\n", + "\n", + " _ = ax.plot(spike_times, np.zeros(len(spike_times)) +\n", + " offset - kk, '.', color=pcolor, markersize=1)\n", + " offset = offset - n_to_plot[pop]\n", + " y_min = offset\n", + " ax.set_xlim([t_min, t_max])\n", + " ax.set_ylim([y_min, y_max])\n", + " ax.set_yticklabels(yticks)\n", + " ax.set_yticks(yticklocs)\n", + " ax.set_xlabel('Time (s)', labelpad=-0.1)\n", + " ax.set_xticks([t_min, t_min + 250., t_max])\n", + " ax.set_xticklabels([r'$3.$', r'$3.25$', r'$3.5$'])" ] }, { "cell_type": "markdown", "id": "019d805e", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ - "### 4.3 Population-averaged firing rates" + "### 4.3 Population-averaged firing rate <a class=\"anchor\" id=\"section_4_3\"></a>" ] }, { "cell_type": "code", "execution_count": null, - "id": "95c57114", + "id": "c05412f6-c842-415f-888a-b7604b795912", "metadata": {}, "outputs": [], "source": [ @@ -942,39 +865,273 @@ " If set to 'complete', all populations the respective areas\n", " are included. Defaults to 'complete'.\n", "\"\"\"\n", - "M.analysis.create_pop_rates(t_min=1000.)\n", - "# M.analysis.save()" + "A.create_pop_rates(t_min=0)\n", + "print(\"Computing population rates done!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "721d1f03-df25-468d-8075-a807025a9c58", + "metadata": {}, + "outputs": [], + "source": [ + "# stationary firing rates\n", + "fn = os.path.join(data_path, label, 'Analysis', 'pop_rates.json')\n", + "with open(fn, 'r') as f:\n", + " pop_rates = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ba5ca35-7f90-47c8-a057-7cb02ee7be02", + "metadata": {}, + "outputs": [], + "source": [ + "def set_boxplot_props(d):\n", + " for i in range(len(d['boxes'])):\n", + " if i % 2 == 0:\n", + " d['boxes'][i].set_facecolor(icolor)\n", + " d['boxes'][i].set_color(icolor)\n", + " else:\n", + " d['boxes'][i].set_facecolor(ecolor)\n", + " d['boxes'][i].set_color(ecolor)\n", + " pl.setp(d['whiskers'], color='k')\n", + " pl.setp(d['fliers'], color='k', markerfacecolor='k', marker='+')\n", + " pl.setp(d['medians'], color='none')\n", + " pl.setp(d['caps'], color='k')\n", + " pl.setp(d['means'], marker='x', color='k',\n", + " markerfacecolor='k', markeredgecolor='k', markersize=3.)\n", + " \n", + "print(\"plotting Population rates\")\n", + "\n", + "rates = np.zeros((len(M.area_list), 8))\n", + "for i, area in enumerate(M.area_list):\n", + " for j, pop in enumerate(M.structure[area][::-1]):\n", + " rate = pop_rates[area][pop][0]\n", + " if rate == 0.0:\n", + " rate = 1e-5\n", + " if area == 'TH' and j > 3: # To account for missing layer 4 in TH\n", + " rates[i][j + 2] = rate\n", + " else:\n", + " rates[i][j] = rate\n", + "\n", + "\n", + "rates = np.transpose(rates)\n", + "masked_rates = np.ma.masked_where(rates < 1e-4, rates)\n", + "\n", + "ax = axes['D']\n", + "d = ax.boxplot(np.transpose(rates), vert=False,\n", + " patch_artist=True, whis=1.5, showmeans=True)\n", + "set_boxplot_props(d)\n", + "\n", + "ax.plot(np.mean(rates, axis=1), np.arange(\n", + " 1., len(M.structure['V1']) + 1., 1.), 'x', color='k', markersize=3)\n", + "ax.set_yticklabels(population_labels[::-1], size=8)\n", + "ax.set_yticks(np.arange(1., len(M.structure['V1']) + 1., 1.))\n", + "ax.set_ylim((0., len(M.structure['V1']) + .5))\n", + "\n", + "x_max = 220.\n", + "ax.set_xlim((-1., x_max))\n", + "ax.set_xlabel(r'Rate (spikes/s)', labelpad=-0.1)\n", + "ax.set_xticks([0., 50., 100.])" ] }, { "cell_type": "markdown", "id": "06a595de", + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, + "source": [ + "### 4.4 Average pairwise correlation coefficients of spiking activity <a class=\"anchor\" id=\"section_4_4\"></a>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "84d1689c", "metadata": {}, + "outputs": [], "source": [ - "### 4.4 Average pairwise correlation coefficients of spiking activity" + "compute_corrcoeff.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8e77836-4c37-4b78-b7c4-5e11bc67b4fa", + "metadata": {}, + "outputs": [], + "source": [ + "# correlation coefficients\n", + "fn = os.path.join(data_path, label, 'Analysis', 'corrcoeff.json')\n", + "with open(fn, 'r') as f:\n", + " corrcoeff = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "218367da-82ef-47b6-bf15-083ef3d43013", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"plotting Synchrony\")\n", + "\n", + "syn = np.zeros((len(M.area_list), 8))\n", + "for i, area in enumerate(M.area_list):\n", + " for j, pop in enumerate(M.structure[area][::-1]):\n", + " value = corrcoeff[area][pop]\n", + " if value == 0.0:\n", + " value = 1e-5\n", + " if area == 'TH' and j > 3: # To account for missing layer 4 in TH\n", + " syn[i][j + 2] = value\n", + " else:\n", + " syn[i][j] = value\n", + "\n", + "\n", + "syn = np.transpose(syn)\n", + "masked_syn = np.ma.masked_where(syn < 1e-4, syn)\n", + "\n", + "ax = axes['E']\n", + "d = ax.boxplot(np.transpose(syn), vert=False,\n", + " patch_artist=True, whis=1.5, showmeans=True)\n", + "set_boxplot_props(d)\n", + "\n", + "ax.plot(np.mean(syn, axis=1), np.arange(\n", + " 1., len(M.structure['V1']) + 1., 1.), 'x', color='k', markersize=3)\n", + "\n", + "ax.set_yticklabels(population_labels[::-1], size=8)\n", + "ax.set_yticks(np.arange(1., len(M.structure['V1']) + 1., 1.))\n", + "ax.set_ylim((0., len(M.structure['V1']) + .5))\n", + "ax.set_xticks(np.arange(0.0, 0.601, 0.2))\n", + "ax.set_xlabel('Correlation coefficient', labelpad=-0.1)" ] }, { "cell_type": "markdown", "id": "a3847e67", + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, + "source": [ + "### 4.5 Irregularity of spiking activity <a class=\"anchor\" id=\"section_4_5\"></a>\n", + "Irregularity is measured by revised local variation LvR averaged across neurons" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c41c7d1-c39a-4c56-bda7-daa515cbaef7", "metadata": {}, + "outputs": [], "source": [ - "### 4.5 Irregularity measured by revised local variation LvR averaged across neurons" + "\"\"\"\n", + "Calculate poulation-averaged LvR (see Shinomoto et al. 2009) and\n", + "store as member pop_LvR. Uses helper function LvR.\n", + "\n", + "Parameters\n", + "----------\n", + "t_min : float, optional\n", + " Minimal time in ms of the simulation to take into account\n", + " for the calculation. Defaults to 500 ms.\n", + "t_max : float, optional\n", + " Maximal time in ms of the simulation to take into account\n", + " for the calculation. Defaults to the simulation time.\n", + "areas : list, optional\n", + " Which areas to include in the calculcation.\n", + " Defaults to all loaded areas.\n", + "pops : list or {'complete'}, optional\n", + " Which populations to include in the calculation.\n", + " If set to 'complete', all populations the respective areas\n", + " are included. Defaults to 'complete'.\n", + "\"\"\"\n", + "A.create_pop_cv_isi()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65377033-f3c0-4f90-be13-70594cfda292", + "metadata": {}, + "outputs": [], + "source": [ + "# local variance revised (LvR)\n", + "fn = os.path.join(data_path, label, 'Analysis', 'pop_LvR.json')\n", + "with open(fn, 'r') as f:\n", + " pop_LvR = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7480a9b", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"plotting Irregularity\")\n", + "\n", + "LvR = np.zeros((len(M.area_list), 8))\n", + "for i, area in enumerate(M.area_list):\n", + " for j, pop in enumerate(M.structure[area][::-1]):\n", + " value = pop_LvR[area][pop]\n", + " if value == 0.0:\n", + " value = 1e-5\n", + " if area == 'TH' and j > 3: # To account for missing layer 4 in TH\n", + " LvR[i][j + 2] = value\n", + " else:\n", + " LvR[i][j] = value\n", + "\n", + "LvR = np.transpose(LvR)\n", + "masked_LvR = np.ma.masked_where(LvR < 1e-4, LvR)\n", + "\n", + "ax = axes['F']\n", + "d = ax.boxplot(np.transpose(LvR), vert=False,\n", + " patch_artist=True, whis=1.5, showmeans=True)\n", + "set_boxplot_props(d)\n", + "\n", + "ax.plot(np.mean(LvR, axis=1), np.arange(\n", + " 1., len(M.structure['V1']) + 1., 1.), 'x', color='k', markersize=3)\n", + "ax.set_yticklabels(population_labels[::-1], size=8)\n", + "ax.set_yticks(np.arange(1., len(M.structure['V1']) + 1., 1.))\n", + "ax.set_ylim((0., len(M.structure['V1']) + .5))\n", + "\n", + "\n", + "x_max = 2.9\n", + "ax.set_xlim((0., x_max))\n", + "ax.set_xlabel('Irregularity', labelpad=-0.1)\n", + "ax.set_xticks([0., 1., 2.])\n", + "\n", + "axes['G'].spines['right'].set_color('none')\n", + "axes['G'].spines['left'].set_color('none')\n", + "axes['G'].spines['top'].set_color('none')\n", + "axes['G'].spines['bottom'].set_color('none')\n", + "axes['G'].yaxis.set_ticks_position(\"none\")\n", + "axes['G'].xaxis.set_ticks_position(\"none\")\n", + "axes['G'].set_xticks([])\n", + "axes['G'].set_yticks([])" ] }, { "cell_type": "markdown", "id": "90ae8f4c", - "metadata": {}, + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, "source": [ - "### 4.6 Time series of population- and area-averaged firing rates\n", + "### 4.6 Time series of population- and area-averaged firing rates <a class=\"anchor\" id=\"section_4_6\"></a>\n", "Area-averaged firing rates, shown as raw binned spike histograms with 1ms bin width (gray) and convolved histograms, with aGaussian kernel (black) of optimal width" ] }, { "cell_type": "code", "execution_count": null, - "id": "bd9d4912", + "id": "94b0b0c4-d70b-4c49-8b5d-e1ca75f0ccf4", "metadata": {}, "outputs": [], "source": [ @@ -1010,10 +1167,94 @@ " - 'alpha_time_window' : time constant of the alpha function\n", " - 'rect_time_window' : width of the moving rectangular function\n", "\"\"\"\n", - "M.analysisi.create_rate_time_series(t_max=1000.)\n", + "A.create_rate_time_series(t_max=1000.)\n", "# M.analysis.save()" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "28796b50-2500-4944-97ae-fbb506a557fb", + "metadata": {}, + "outputs": [], + "source": [ + "# time series of firing rates\n", + "rate_time_series = {}\n", + "for area in areas:\n", + " fn = os.path.join(data_path, label,\n", + " 'Analysis',\n", + " 'rate_time_series_full',\n", + " 'rate_time_series_full_{}.npy'.format(area))\n", + " rate_time_series[area] = np.load(fn)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65e4be2d-5e8b-4daa-a37c-07f1be629f80", + "metadata": {}, + "outputs": [], + "source": [ + "# time series of firing rates convolved with a kernel\n", + "rate_time_series_auto_kernel = {}\n", + "for area in areas:\n", + " fn = os.path.join(data_path, label,\n", + " 'Analysis',\n", + " 'rate_time_series_auto_kernel',\n", + " 'rate_time_series_auto_kernel_{}.npy'.format(area))\n", + " rate_time_series_auto_kernel[area] = np.load(fn)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4460d823-543a-482b-8ef1-a049e5837af4", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Plotting rate time series\")\n", + "pos = axes['G'].get_position()\n", + "ax = []\n", + "h = pos.y1 - pos.y0\n", + "w = pos.x1 - pos.x0\n", + "ax.append(pl.axes([pos.x0, pos.y0, w, 0.28 * h]))\n", + "ax.append(pl.axes([pos.x0, pos.y0 + 0.33 * h, w, 0.28 * h]))\n", + "ax.append(pl.axes([pos.x0, pos.y0 + 0.67 * h, w, 0.28 * h]))\n", + "\n", + "colors = ['0.5', '0.3', '0.0']\n", + "\n", + "t_min = 500.\n", + "t_max = 10500.\n", + "time = np.arange(500., t_max)\n", + "for i, area in enumerate(areas[::-1]):\n", + " ax[i].spines['right'].set_color('none')\n", + " ax[i].spines['top'].set_color('none')\n", + " ax[i].yaxis.set_ticks_position(\"left\")\n", + " ax[i].xaxis.set_ticks_position(\"none\")\n", + "\n", + " binned_spikes = rate_time_series[area][np.where(\n", + " np.logical_and(time >= t_min, time < t_max))]\n", + " ax[i].plot(time, binned_spikes, color=colors[0], label=area)\n", + " rate = rate_time_series_auto_kernel[area]\n", + " ax[i].plot(time, rate, color=colors[2], label=area)\n", + " ax[i].set_xlim((500., t_max))\n", + "\n", + " ax[i].text(0.8, 0.7, area, transform=ax[i].transAxes)\n", + "\n", + " if i > 0:\n", + " ax[i].spines['bottom'].set_color('none')\n", + " ax[i].set_xticks([])\n", + " ax[i].set_yticks([0., 30.])\n", + " else:\n", + " ax[i].set_xticks([1000., 5000., 10000.])\n", + " ax[i].set_xticklabels([r'$1.$', r'$5.$', r'$10.$'])\n", + " ax[i].set_yticks([0., 5.])\n", + " if i == 1:\n", + " ax[i].set_ylabel(r'Rate (spikes/s)')\n", + "\n", + "ax[0].set_xlabel('Time (s)', labelpad=-0.05)" + ] + }, { "cell_type": "markdown", "id": "ef74ca3e-98dc-49c9-a4a0-2c640e29b1d9", diff --git a/multi-area-model.ipynb b/multi-area-model.ipynb index a6bd1d2362f552da2f0418e0240e1cf4fe6efd6c..ab7ae2504ea3bb423670a84480ecde42ea785b26 100644 --- a/multi-area-model.ipynb +++ b/multi-area-model.ipynb @@ -56,34 +56,12 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "96517739", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " -- N E S T --\n", - " Copyright (C) 2004 The NEST Initiative\n", - "\n", - " Version: 3.4\n", - " Built: May 17 2023 20:48:31\n", - "\n", - " This program is provided AS IS and comes with\n", - " NO WARRANTY. See the file LICENSE for details.\n", - "\n", - " Problems or suggestions?\n", - " Visit https://www.nest-simulator.org\n", - "\n", - " Type 'nest.help()' to find out more about NEST.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# Import dependencies\n", "%matplotlib inline\n", @@ -101,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "2dd47c64", "metadata": {}, "outputs": [], @@ -119,48 +97,22 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "7e07b0d0", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: nested_dict in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (1.61)\n", - "Requirement already satisfied: dicthash in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (0.0.2)\n", - "Requirement already satisfied: future in /srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/._view/6axslmv6jvf4v2nte3uwlayg4vhsjoha/lib/python3.8/site-packages (from dicthash) (0.18.2)\n" - ] - } - ], + "outputs": [], "source": [ "!pip install nested_dict dicthash" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "1d440c07-9b69-4e52-8573-26b13493bc5a", "metadata": { "tags": [] }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "<style>\n", - "table {float:left}\n", - "</style>\n" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Jupyter notebook display format setting\n", "style = \"\"\"\n", @@ -238,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "60265d52", "metadata": {}, "outputs": [], @@ -267,7 +219,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "6e4bed8d", "metadata": {}, "outputs": [], @@ -356,70 +308,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "ab25f9f8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initializing network from dictionary.\n", - "RAND_DATA_LABEL 8510\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/core/fromnumeric.py:3440: RuntimeWarning:Mean of empty slice.\n", - "/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/core/_methods.py:189: RuntimeWarning:invalid value encountered in double_scalars\n", - "Error in library(\"aod\") : there is no package called ‘aod’\n", - "Execution halted\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "No R installation or IndexError, taking hard-coded SLN fit parameters.\n", - "\n", - "\n", - "========================================\n", - "Customized parameters\n", - "--------------------\n", - "{'K_scaling': 0.005,\n", - " 'N_scaling': 0.005,\n", - " 'connection_params': {'K_stable': 'K_stable.npy',\n", - " 'av_indegree_V1': 3950.0,\n", - " 'fac_nu_ext_5E': 1.125,\n", - " 'fac_nu_ext_6E': 1.41666667,\n", - " 'fac_nu_ext_TH': 1.2,\n", - " 'g': -11.0,\n", - " 'replace_non_simulated_areas': 'het_poisson_stat'},\n", - " 'fullscale_rates': 'tests/fullscale_rates.json',\n", - " 'input_params': {'rate_ext': 10.0},\n", - " 'neuron_params': {'V0_mean': -150.0, 'V0_sd': 50.0}}\n", - "========================================\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/srv/main-spack-instance-2302/spack/var/spack/environments/ebrains-23-02/.spack-env/view/lib/python3.8/site-packages/dicthash/dicthash.py:47: UserWarning:Float too small for safe conversion tointeger. Rounding down to zero.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Simulation label: 27d81076e6d6e9e591684be053078477\n", - "Copied files.\n", - "Initialized simulation class.\n" - ] - } - ], + "outputs": [], "source": [ "M = MultiAreaModel(network_params, \n", " simulation=True,\n", @@ -438,19 +330,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "6a7ddf0e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Iteration: 0\n", - "Mean-field theory predicts an average firing rate of 29.588 spikes/s across all populations.\n" - ] - } - ], + "outputs": [], "source": [ "p, r = M.theory.integrate_siegert()\n", "print(\"Mean-field theory predicts an average \"\n", @@ -483,7 +366,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "6316ac24", "metadata": {}, "outputs": [], @@ -503,7 +386,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "445a722a", "metadata": {}, "outputs": [], @@ -539,85 +422,10 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": null, "id": "15778e9c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Prepared simulation in 0.00 seconds.\n", - "Rank 0: created area V1 with 0 local nodes\n", - "Memory after V1 : 3156.15 MB\n", - "Rank 0: created area V2 with 0 local nodes\n", - "Memory after V2 : 3156.15 MB\n", - "Rank 0: created area VP with 0 local nodes\n", - "Memory after VP : 3156.15 MB\n", - "Rank 0: created area V3 with 0 local nodes\n", - "Memory after V3 : 3156.15 MB\n", - "Rank 0: created area V3A with 0 local nodes\n", - "Memory after V3A : 3156.15 MB\n", - "Rank 0: created area MT with 0 local nodes\n", - "Memory after MT : 3156.15 MB\n", - "Rank 0: created area V4t with 0 local nodes\n", - "Memory after V4t : 3156.15 MB\n", - "Rank 0: created area V4 with 0 local nodes\n", - "Memory after V4 : 3156.15 MB\n", - "Rank 0: created area VOT with 0 local nodes\n", - "Memory after VOT : 3156.15 MB\n", - "Rank 0: created area MSTd with 0 local nodes\n", - "Memory after MSTd : 3156.15 MB\n", - "Rank 0: created area PIP with 0 local nodes\n", - "Memory after PIP : 3156.15 MB\n", - "Rank 0: created area PO with 0 local nodes\n", - "Memory after PO : 3156.15 MB\n", - "Rank 0: created area DP with 0 local nodes\n", - "Memory after DP : 3156.15 MB\n", - "Rank 0: created area MIP with 0 local nodes\n", - "Memory after MIP : 3156.15 MB\n", - "Rank 0: created area MDP with 0 local nodes\n", - "Memory after MDP : 3156.15 MB\n", - "Rank 0: created area VIP with 0 local nodes\n", - "Memory after VIP : 3156.15 MB\n", - "Rank 0: created area LIP with 0 local nodes\n", - "Memory after LIP : 3156.15 MB\n", - "Rank 0: created area PITv with 0 local nodes\n", - "Memory after PITv : 3156.15 MB\n", - "Rank 0: created area PITd with 0 local nodes\n", - "Memory after PITd : 3156.15 MB\n", - "Rank 0: created area MSTl with 0 local nodes\n", - "Memory after MSTl : 3156.15 MB\n", - "Rank 0: created area CITv with 0 local nodes\n", - "Memory after CITv : 3156.15 MB\n", - "Rank 0: created area CITd with 0 local nodes\n", - "Memory after CITd : 3156.15 MB\n", - "Rank 0: created area FEF with 0 local nodes\n", - "Memory after FEF : 3156.15 MB\n", - "Rank 0: created area TF with 0 local nodes\n", - "Memory after TF : 3156.15 MB\n", - "Rank 0: created area AITv with 0 local nodes\n", - "Memory after AITv : 3156.15 MB\n", - "Rank 0: created area FST with 0 local nodes\n", - "Memory after FST : 3156.15 MB\n", - "Rank 0: created area 7a with 0 local nodes\n", - "Memory after 7a : 3156.15 MB\n", - "Rank 0: created area STPp with 0 local nodes\n", - "Memory after STPp : 3156.15 MB\n", - "Rank 0: created area STPa with 0 local nodes\n", - "Memory after STPa : 3156.15 MB\n", - "Rank 0: created area 46 with 0 local nodes\n", - "Memory after 46 : 3156.15 MB\n", - "Rank 0: created area AITd with 0 local nodes\n", - "Memory after AITd : 3156.15 MB\n", - "Rank 0: created area TH with 0 local nodes\n", - "Memory after TH : 3156.15 MB\n", - "Created areas and internal connections in 2.19 seconds.\n", - "Created cortico-cortical connections in 23.77 seconds.\n", - "Simulated network in 69.93 seconds.\n" - ] - } - ], + "outputs": [], "source": [ "# run the simulation, depending on the model parameter and downscale ratio, the running time varies largely.\n", "M.simulation.simulate()" @@ -660,18 +468,10 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": null, "id": "dc3b1820", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Testing synapse numbers\n" - ] - } - ], + "outputs": [], "source": [ "# # Uncomment the lines in this code cell below to test if the number of synapses created by NEST matches the expected values\n", "\n", @@ -702,7 +502,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": null, "id": "e7eb052e", "metadata": {}, "outputs": [], @@ -725,7 +525,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": null, "id": "902f2800", "metadata": {}, "outputs": [], @@ -765,7 +565,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "id": "6806564b-d5d4-47d4-afa9-5da0df83e025", "metadata": {}, "outputs": [], @@ -777,20 +577,12 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "7997d893-252d-4295-a22a-1e510f8424ae", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "loading spikes\n" - ] - } - ], + "outputs": [], "source": [ "\"\"\"\n", "Analysis class.\n", @@ -820,18 +612,10 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "id": "da58921f-713b-424c-8fa1-80d9755558f3", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "loading spikes\n" - ] - } - ], + "outputs": [], "source": [ "\"\"\"\n", "Loads simulation data of the requested type either from hdf5 files.\n", @@ -857,7 +641,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "id": "56e368b6-72a2-43fb-b02e-f70ad6770e40", "metadata": {}, "outputs": [], @@ -869,33 +653,10 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": null, "id": "bea30fc8", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "<matplotlib.legend.Legend at 0x7f437f596100>" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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arkUpaLj6yxQu1VQiGWjKzbG9LTthR9hdZ/zgd8bY7b7KYdSpaiO5Y3UBstW/yHWXARFUcqBr2YoW1n0NMZscRx7Amuwd6iIDMLyOHnANyEURVGUcpMKM9QFWMsxYH9fmAIZFEVRlBjwu2exikNulK8YY14VkR22z3YgzHZjTAOXa28CbgLIqplz7DEdj/RNTkVRlMrIjBkzthhjmkQPGR2/lUVzY8w626d/HJb72RdelIWThq07mG2/LvZNTkVRlMqIiMwwxvRMRFy+mqGMMevs701YHim9gY0ikguW5wrWukWKoihKGuObshCR2oGlCOzZi2dgLRfwBdby0tjfI/2SQVEURUkMfrrONgM+t5Z6IQsYbowZIyK/AB+LyPVY+xFc6qMMiqIoSgLwTVkYazvCY1yObwX6+5WuoihVk6KiItasWcO+fftSLUrSyc7OpmXLllSr5rqAcELQrRkVRakUrFmzhpycHPLy8rAtGlUCYwxbt25lzZo1tGnTxrd0dLkPRVEqBfv27aNRo0ZVSlEAiAiNGjXyvUelykJRlEpDVVMUAZJx36osFEVRlKioslAURVGiUiGUhe64oSiKkloqhLJQFEVJd/Lz8+nQoQM33HADnTt35oorruDbb7+lT58+tG/fnmnTprF7926uu+46evXqRffu3Rk5cmTptSeddBI9evSgR48e/PijtQnlxIkT6devH5dccgkdOnTgiiuuIFUb1qnrrKIolY+vB8GGeYmN87AucPbQiEGWL1/OJ598wquvvkqvXr0YPnw4kydP5osvvmDIkCF07NiR0047jTfffJMdO3bQu3dvBgwYQNOmTRk3bhzZ2dksW7aMyy+/nOnTpwMwa9YsFixYQPPmzenTpw9Tpkyhb9++ib03D6iyUBRFSRBt2rShS5cuAHTq1In+/fsjInTp0oX8/HzWrFnDF198wVNPPQVY7r6//fYbzZs354477mD27NlkZmaydOnS0jh79+5Ny5YtAejWrRv5+fmqLBRFURJClB6AX9SoUaP0d0ZGRun/jIwMiouLyczMZMSIERx11FFB1w0ePJhmzZoxZ84cSkpKyM7Odo0zMzOT4uJin+/CHR2zUBRFSRJnnnkmL7zwQum4w6xZswAoKCggNzeXjIwM3n33XQ4ePJhKMV1RZaEoipIkHnnkEYqKiujatSudO3fmkUceAeC2225j2LBhHH/88SxdupTatWunWNKy+Lr5UaJo0LqD2a6bHymKEoFFixZx9NFHp1qMlOF2/xVm8yNFURSlcqDKQlEURYmKKgtFUSoNFcGs7gfJuG9VFoqiVAqys7PZunVrlVMYgf0snO62fqDzLBRFqRS0bNmSNWvWsHnz5lSLknQCO+X5iSoLRVEqBdWqVfN1p7iqjpqhFEVRlKioslAURVGiospCURRFiYoqC0VRFCUqqiwURVGUqKiyUBRFUaKiykJRFEWJiioLRVEUJSqqLBRFUZSoqLJQFEVRoqLKQlEURYmKKgtFURQlKqosFEVRlKioslAURVGiospCURRFiYoqC0VRFCUqvisLEckUkVki8qX9v6GIjBORZfZ3A79lUBRFUcpHMnoWdwGLHP8HAeONMe2B8fZ/RVEUJY3xVVmISEtgIPC64/AFwDD79zDgQj9lUBRFUcqP3z2L54D7gRLHsWbGmPUA9ndTtwtF5CYRmS4i04uKin0WU1EURYmEb8pCRM4FNhljZsRzvTHmVWNMT2NMz2rVshIsnaIoihILftbCfYDzReQcIBuoKyLvARtFJNcYs15EcoFNPsqgKIqiJADfehbGmAeNMS2NMXnAZcB3xpgrgS+Aq+1gVwMj/ZJBURRFSQypmGcxFDhdRJYBp9v/FUVRlDQmKYMBxpiJwET791agfzLSVRRFURKDzuBWFEVRoqLKQlEURYmKKgtFURQlKqosFEVRlKioslAURVGiospCURRFiYoqC0VRFCUqnpWFiNQWkUw/hVEURVHSk7DKQkQyROSPIjJaRDYBi4H1IrJARJ4UkfbJE1NRFEVJJZF6FhOAtsCDwGHGmFbGmKbAScBUYKiIXJkEGTEmGakoiqIo4Yi03McAY0xR6EFjzDZgBDBCRKr5JpmiKIqSNoTtWQQUhYi0FZEa9u9+InKniNR3hlEURVEqN14GuEcAB0WkHfAG0AYY7qtUiqIoSlrhRVmUGGOKgYuA54wxfwFy/RVLURRFSSe8KIsiEbkca6OiL+1jOlahKIpShfCiLK4FTgD+aYxZJSJtgPf8FUtRFEVJJ8RUAL/U+od3MDt+W5xqMRRFUSoUIjLDGNMzEXHpch+KoihKVFRZKIqiKFGJtNzHgyLSPZnCKBZ7DxxkzuodqRZDURSllEg9i1XAXSIyS0TeFpE/iEiDZAlWlbnv0zlc8NIUNhfuT7UoiqIoQITlPowxHwIfAtg9jLOAz+yVZ78FxhhjpiVFyirG3DUFAOw5UAzUSK0wiqIoRF4bqhRjzCxgFvC4iNQFTgduAFRZKIqiVAE8KQsnxpid2AsJJl4cJdHsOVBMzWqZiEiqRVEUpQKj3lBpiCExc19WbdlNx7+N5ePpqxMSn6IoVRdVFmmMUL7ewLKNhQCMW7gpEeIoilKFiaosRKSPiNS2f18pIs+ISGv/RVMSR/rP0lcUJb3x0rN4GdgjIscA9wO/Au/4KpWSEHScQlGUROFFWRQbawGpC4DnjTHPAzn+iqUkkgqw/JeiKGmOF2+oQhF5EPg/4CR7noUuUV4BCPQrVFcoilJevPQs/gDsB64zxmwAWgBP+iqVkhDUCqUoSqKIqixsBTGCQ1OJtwCf+ymUklgqwjL0iqKkN168oW4EPgVesQ+1AP7no0xKgtCeRfL5JX8b/5m4PNViKErC8WKGuh3oA+wEMMYsA5r6KVRVJ9EdAe1XJI9L//sTT4xZkmoxFCXheFEW+40xBwJ/RCQLD/WPiGSLyDQRmSMiC0TkUft4QxEZJyLL7O9KsZLt21NWsXrbnoTGWd6eQXkn9Snpw+i565nx6/ZUi6FUYbwoi+9F5CGgpoicDnwCjPJw3X7gNGPMMUA34CwROR4YBIw3xrQHxtv/KzQFe4oYPGohV7z+c6pFUSoptw+fye9e/jHVYihVGC/KYhCwGZgH3Ax8ZYx5ONpFxmKX/bea/QnM1xhmHx8GXBijzGnHQdtuVLivKMWSKKGs27GXcQs3Jj3dbbsPRA+kKBUIL8pisDHmNWPMpcaYS4A3ReR9L5GLSKaIzAY2AeOMMT8DzYwx6wHsb9fxDxG5SUSmi8j04uJiTzeTKtLd2yjNxfOV81+cwo3vTE96uje/m/w0FcVPvCiLw+1JeYhIdeAzYJmXyI0xB40x3YCWQG8R6exVMGPMq8aYnsaYnllZMa+knhLSbnkNW5ytu/czu4pu07plV2p2G1y3Y19K0lXSn227DzDrt4o3/uRFWVwLdLEVxpfARGPM4FgSMcbsACZi7ba3UURyAezvCr8karo23AOqa/7anVz40pSUyqIoisUl//2Ri/5T8cafwioLEekhIj2A7sDzWDO5l2ENePeIFrGINBGR+vbvmsAAYDHwBXC1HexqYGR5biDRlJQYFm/YGdM1ATNPmvUrKgWrt+1hpz0WtHLzLvYVHfQlnfwtu+1tbBNDunUylfRh5ebdvsW9dGMhxQdLfIk7Us/iacdnKLAd6Gj/f8pD3LnABBGZC/yCNWbxpR3X6SKyDGt71qHxi5943pi8irOe+yEuN8V0qyDSziwWByc9MYGB//6BfUUHOe3p77nrw1m+pNPvqYkpGdtQlESRv2U3Zzw7iSfG+jPPJ+xggDHm1PJEbIyZi9UrCT2+FehfnrhD2Vd0kIMlhto1yj+2MXdtAQBrtu/h2NbepoBE29mupMSwdsdemuTUILtaZvT4IkRXuK+IapkZnuKpLKzetpcDdmvpx+VbfUtnSgLjrgR6WqlgBMbn/JqPE7Z2FZErjTHvicjdbueNMc/4IlEcnPD4eLbvKSJ/6MAUS+JeQ7zw3XKe/XYpOdlZzBt8ZrlS6DL4G45sVodv/nJKnNIooazbsTfhceqESKWyEakpXtv+Tvu9K7bvSfH8higj3N8usvz8C/clxia+dOOu6IEUz6wvUM8lRYlG2DELY8wr9vejbp/kiVhx8GJ6WL6pkLxBo/nWMVFsxeZd5A0azTcLNiRdnqrOY18ujDoz+h+jFpI3aDSv/7DSc7zpnvffL91M3qDRLFofmzNHRWTrrv3kDRrNu1N/9SX+d3/KJ2/Q6Eo/EdPLqrNHiMgoEdksIptEZKSIHJEM4SoKgY6Fl/ph5m87ABjjUAxz7DkQX89PrLJQovP65FVRw7w5xQrzhoewFYVAw2R6FVhvas12y8z4yfTVvsT/kR3v2u2JN2emE17mWQwHPsbybmqOtTbUB34KlUriaRCWus6GudjtuJdZ1bF651zw0hRuHz4zarjlm6yezPy1BZz61EQe/GxeTOmUh31FB8kbNJqPf1ldKse8NZZTQee/j+WZcUuTJks4bh8+s9zzUn7duocflm32HP7at6Zx+atTPYfv9+QEHvrc23Pbua+IvEGjGT13vef4IzFh8SbyBo1ma8iEx/em/kreoNG+uW6G8v7PVnpFUdIrzzyov3w0m7Of/8H1XN6g0bw6aUU5Yk8sfs/38qIsxBjzrjGm2P68lwS5UkY8NxbNGypeFm8ojCn8nNU7giqEcIOs4+0xlC/mrGPVlt18MO23+IWMkUBX/dlvlzrkWAvArv3F/Hu8p8UBfGX03PWuM95jbUi8+5N3s8eEJZv5aaV3b6z8rXsY/rO35/brFms15Je/T8w+G4Ee1sIQE9a/vl4MwB6f5sKEUprefm/pxdMQ/HzW2oimuiFfLY4jVn/xywLqRVlMEJFBIpInIq1F5H5gtL3UeEOf5Eor/vjaVE8VarjKOdrDc/YyDhSXsNYH7xywWkIFSXQGuPL1n3n/50MV5oaCfZw49LvS/4Ee19s/5nPd27+UuT6aPd0Yw/kvTk5Yi7k8fLNgA2c9Nyno2PjFsS9OsGt/bE4QJz3xXcwLWK7aspv3PSqaAP+ZuLxMr/WxLxfxt5Hzy4T1ay2yTTv3ccLj41mxOb0cPIqK47vhqSu3cupTE2OaaHrl6z/z7k/5nPXcpKBxT4AVm6x82ezTEjde9+C+GZiAtWTHrcB1wAygSsxi+nHF1oSZaqIpjg0J9MxxM385W69+L4A4efkWHv78UGUycvZa13BFBw3fuVSs/5lYtovvlLjEwNw1Bfzpg+imN7+5++M5ZXqCB0tiz9+5Ma7htXrb3tJxsHCE9nyH/Zgfm1DAE2OWlCrlQHxLNhbyjrP35POg/tfzN7C+YF9c8vvJpkLrnY3VwvCPUQtZtWU3yzd5V36Tl2/hkZELWLyhkPtHzA06Fxhb+3VrYvfVCeBlD+42ET6VbqA7WnnfvvsAN787PaiFvqXQMq3sdmkVjpqzjjm2TR5gy66yHhNePWfC2fPHL9rI0994n7UZSK/oYGqtieF6Yn/+cBZFB0vKrcxmxrFY27RV20p/fzFnXdC5SDPiw8k6Yckm/jUmtaaKQCUfae7HTyu28uioBezYc4Bb3p3B+oK93PreDDbu9MeteM+BYm59b0ZCGkd/+nAWv0WoINNhVei8QaO595M5vsX/+aw1QS71ew4Uc9v7MxKahhdvqEtFJMf+/VcR+UxEyszMriq8PnklYxds5N2p+aXHnrft7IUuyuJPHwQvT/Hid/Hb5MPZ868fNp0Xvitrj46mg6bGYCNPBKGvbLi693+z1zHXoWCDrokhvYvjWKzt96/8VPr7zpBnFw/XvvULL7v0kMLiQ+v8lUnRXX4vf20qb03J580p+YxZsIHf/edHvp6/IaZGSCke6uYv567n6/kbeCqe+EOYtHQzj7iYw8qIk2J/5k9nrPEt7r98FKyIvpq3ga/mJda70osZ6hFjTKGI9AXOxNqw6L8JlcInCvYUcfdHs7npnem8NCExg3vuuL8dkQrHiJlrWL5pF09/syTIxhtrec7f4r4o2YaCfa49Eae9N9oA+quTVrBso7dB9glLNvHl3HXRA3pk+M+/McthXnnmG+teEtlG/NiDK+VSx/2vKzg0lnSwxDD068WlHkHR5Nq4cx9PjV3C6z+s5LwXJocN99nMtZSUGLoOHsspT04oXUQxgDEmagU+as46Ji4pa9abt7aA10IUx9j5G0odDdwwBn7d6m3hu8Ck0/en/cqPK7bwz9ELXe3xSzYUxjRnBaxZ9s9+u7RUpnAsWr8zyMV5/KKNjHW4pP+2dQ//Hr8s5t7G6c98z90fzQ5rSgV4cuySUpOUF0Lf9ZISwxNjFrO50H3MYc127+YlP3pTXhZTCjztgcDLxpiRIjI44ZL4wJCvFvHZLOvhfrNwI1efmEedBKwfFUq45+LW7XQGHfDM9wBcc2Je3Glf9eY01+N3fjjL1Yf+ybFLePico6PGa4xhyFeLeXbcMhb9v7Oihr/2LWuA+tyuzaOGDRDJrDNiZrCifdvFTh3LC7FzXxF1s6sFHbv/07lhQh/ijGcPDVo7k/t+6Sb++/0KVm/bw0tX9Ig6qHvXh7OYuvKQiWv77gM0qF0dCB7b+HTGGi7v3Yqd+4rZua+Yp8cu4dELDm0DM29tgWsv0kmgN+u2/M0/v1oUVN4mL9/C5OVbyoQLPBsDXB2mjDlxTkh7YswhZdagdnVu69cuKOy5L/wQswn0juEz2eHBOSPg5np93zbW97DgYdVr357Gis27+d2xLWlRv6bn9Jdt2sWyTbv4bNZaLujWwjXMD8u2cO8nc3nnut6e43UydeVW/jNxBYs3FPLmNb3KnL/53cSalWLFS89irYi8Avwe+EpEani8LuUciOB/XbC3iHd/ymfpxkLGLtjAOz/lM2rOujJ2aideupGrt+2J2PpwIzDWUeJS4+zeX8zbU1aVqRgDreLftrm3NiJ5WAQWS3Ty1bz1PPblQrbbL32gAtsboxvkm5NXUVJiXCvyREw63LW/mLOem+TqWz9u4UaWxOhuHA8zft3G5GWWCW9/sSVHtMHNvUXB8n74S/hejfPWhv30K/Mdz+v1H8pODPx85pqw61vNXbOjzLFIvdeCPcFjasYEl4GCvUVlFlycsGQT81zKFECxi1JwKooF6w55vD38+TzOfHYSq7bsLvMeug3iOxsbXrYVEGCf/Rz8GsfYH8P7Erj3NyavYsG6gtL3I+DsMWf1Du79ZE5pjyLcO/2xS1ny4+68NLN/j7Vp0VPGmB32hkX3+SBLUnno83kxu1ze+8kcrjqhdZnjzgdz4UtT2Lr7QNjWhxuf2Epo7IIN3HvGUUHnHhu9kA+mraZ1o9pBx+//dC79jmriXXgHo1wU4m3vWx5Fyzfv4u1rewfNMI+Ff3y5kGZ1s2lat0bpsYI9RdSrVa10pjpYlVC8FuTFGwp5cuwS7j8zOK8Ckxj9XlDydy//5PhnPf1odU9o5fSvMYsZ2CWXwxvVKhM2tDI/12G2cmvM/G/2Omat3sH395VdKPr8F2ObXDjM9m4Kp1DcJgIGepXx4HSPDrjznvrURADOP8bqpa4McZV1U8wbd6ZmR0Qof8X8+ay1fD4ruIG5ZvseLrAnhk5auplpDw9wvXbjzn1lvKL8ItLmR3UAjDF7jDGfGWOW2f/XG2O+cYZJNss2FrJwXfiWxMzftrN62x7XymjX/mLGzF8ft29+oMW9dfcBptjdd2dFsLUc68PsKyop40O+fbfV9XZr4UdyzdxzIL6JUYGehdOza0yMPYJ1O/YGtYLcekwbdu4r13jj9t0HYnpJ12zb69vSzV5wG7BfuL6ARet38tW88s8T2eRSWc4P09r3QmCJjNCKebsP6x/NW1PgOv9nzPz17Cs6GNFCEInQcZs5a3YEzWFauG4nb05eFfM9rd2xl5vCrK7w86ptXPPWtLA9l3lhHDdCcZbVTfYYhtvrHm4cY+fexM+nitSzGCkis7F2spthjNkN1lpRwKlYPY7XgE8TLlUUTrftyOFakAEvmIu7l23d3/PxbMYuCD+gF43A83prSj5vTcknf+jAhHb5rglppcVToS7ZUBiT73Y0bnlvBh/edDzHH9HIU/h/frUoyG4bLn+SOZnunH9btmy/eh3xlIFb3nOfH1JUHHvl6NaYODfCQHo6cd6Lk+ndpuz83lvem8k1J+ZxWe9WrtdFMiXt2HOgzLvkDG7MoTIxcvZaRt7Rt0wc4ZRtH8fE0tB4ASYu2cwL3y3nzv7ty1x73ovensldH84uc2yVizNLcC/3EI+NXuQpnViItOpsf2A81oS8BSJSICJbgfeAw4CrjTFJVxRORs5ey4J1sbWe3DK8POzcV8TSJNjJYzGxlmv1y8DAZkh6O0Js2Us2FJbx1HHiXI49XC+wvIvYOb10YtkStWBPUVLGNuJlSxqtXlp00ASZeLa6zBOKhLMc7Ss6GLYCXhGmcbPGZXE+L+/CgSgK1zkHZ8Xm3RwoLmHumh0cKC4pNZdGKt9OClxa8avtscRtuw8kZMb5Jp/mu8RCxDELY8xXwFdJkiVm3LRvEFL2r9dKN1y4BSGFvevgb7xFGCeBnkUss0MfHbUg4XKEdoHPfG4SnZrXZfSdJ7mGdy4NceUbPzNv8BkJl2nAM4c8lWKZE3H+S5MTP8s1gd3LRMzvSBSh41tLPLpSu3Hfp3Ndx8ugfObbeHDWHbv2F/PoqAW8//NvnHJkE75fupnv7om+uVgkAsWh/9MTE7LfTu8h48sdR3mpEF5N8eLmieHWCgjHuh17y4wLeB1IS9Tua7siLJIWrpUX6wKETgL6NTTn1u3YW2Y10QURxo1CidbSKy/OXsqB4pLSll0om3buK5eiCDV9TP91O/lbdsdtV08F63ckt5W6oWAfRQdLmBXHjHo39hw4yPbdByK6Xsc64P2Nvc7S90utlYKn/7o9IQ0APzdmcxsL9JPETzpIIXsOFFOr+qFbcvMc2RRmwksoG3Zai97d2q9tXLKcGGLXDBDr851kF1636/y0SYem99joRazZvpfB53fyLc1YiJSNxw35NuxLWt4WWqjL6449RfSzvXcqCvF6usXD7gPFHP/4eC7r5T7uEA9u3kOheB0bCBA6Ee7+T+cy/IbjYpYtmXiZd5JIKlXPYn9R5NZdtHXvnQRapmNDPIFinXcQSrytgWS1IQKNtf3FZe8z4F3i9HQ6UFziacG8gwluBTmjKwlxw/WzNTc9P303C9pzoDimFUyTQcCrbsyCDb6tRpuOVMZ79dSzsJf6aG+MeUtEmgB1jDFlZwelmGjPp9s/xnmOK+DzvTJkQDwWM5Yb++M0xyRrgGvtdsvt9dFRC8ucM1jmKGev6ci/fu3qyRKKcyZ0Igid4Z2sfdjTYVG6cHT829hUi1CGQONjx54ialeP3ZARSwMvnUi2iSgZeFlI8O/AA8CD9qFqWB5RaUc6v8jlJZwNPtFsKtzvunouWK0lt7WonCu1hiPZXWa/qLwlLD3ZW3Qw4mq56UpxHMvTpzteVP1FQHdgJoAxZl1gFVoleQyLYde18rI+wrLRle8ViI3K3CDxm3g29Zq2apvn3vzdH82OOf5I/PH1n+O+dtScdWE9vyoqXsYsDhjrDTEAIlI7SnilghNp7kpVrysrYYMx7Qm3/lkon0UZ9FbKh5eexcf2QoL1ReRGrF3yXvdXrPi479O5Cd1prqrywIjwuwJ+Nsu/NfkrApEWmlTK8t7U8u/v7uemQYp3oioLY8xTInI6sBM4CvibMcb7SHEScduaU0ksn83U1puiVEWiKgsR+Zcx5gFgnMsxpQrh1RygKErlw8uYxekux85OtCCKoihK+hK2ZyEitwK3AUeIiHPB9BwgtkXyFUVRlApNJDPUcOBr4HFgkON4oTEmumO9oiiKUmkIqyyMMQVAAXA5gIg0BbKBOiJSxxhTfjcHRVEUpULgZQb3eSKyDFgFfA/kY/U4FEVRlCqClwHux4DjgaXGmDZAf1I4ZlGis6IURVGSjhdlUWSM2QpkiEiGMWYC0M1fscLz8fTV0QMpiqIoCcWLstghInWAScD7IvI8EHUPSxFpJSITRGSRiCwQkbvs4w1FZJyILLO/G8Qi8JQVW2MJriiKoiQAL8riAmAP8BdgDLACOM/DdcXAPcaYo7HMWLeLSEcsz6rxxpj2WHt8D4oQRxkq2+JciqIoFYGIM7hFJBMYaYwZAJQAw7xGbIxZD6y3fxeKyCKgBZby6WcHGwZMxFoCXVEURUlTIvYsjDEHgT0iUq88iYhIHtYy5z8DzWxFElAoTcNcc5OITBeR6UXFUa1eiqIoio94WXV2HzBPRMYBpTvfGGPu9JKAPd4xAvizMWZnpE3WnRhjXgVeBah3eAd1gVIURUkhXpTFaPsTMyJSDUtRvG+M+cw+vFFEco0x60UkF9ClYhVFUdIcL0uUex6ncCJWF+INYJEx5hnHqS+Aq4Gh9vfIeOJXFEVRkkfsO6h7pw/wf1gmrNn2sYewlMTHInI98BtwqY8yKIqiKAnAN2VhjJkMYXda7+9XuoqiKEri8TLPQlEURanieNkpbxQQ6o1UAEwHXjHG+L7ptWDgYBEAWdEnjyuKoigJxosZaiXQBPjA/v8HYCNwJPAa1riEr7QrXg7/rzEAy7P9Tk1RFKVy4G2igje8KIvuxpiTHf9HicgkY8zJIrIggbKEZWtGIzjtPp4cuzQZySmKolQSXk9YTF6URRMROTyw2ZGIHA40ts8dSJgkEdiW0RBOvo+XvopruoeiKEoVJbnK4h5gsoiswOrVtAFuE5HaxLBWlKIoilJx8TIp7ysRaQ90wFIWix2D2s/5KJuiKIqSJnidZ3EskGeH7yoiGGPe8U0qRVEUJa3w4jr7LtAWmA0ctA8bQJWFoihKFcFLz6In0NEYoyu/KoqiVFG8zOCeDxzmtyCKoihK+uKlZ9EYWCgi04D9gYPGmPN9k0pRFEVJK7woi8F+C6EoiqKkN15cZ79PhiCKoihK+hJWWYjIZGNMXxEpJHghQQGMMaau79IpiqIoaUFYZWGM6Wt/5yRPHEVRFCUdiegNJSIZIjI/WcIoiqIo6UlEZWGMKQHm2IsHKoqiKFUUL95QucAC23V2d+Cgus4qiqJUHbwoi0d9l0JRFEVJa9R1VlGUIFo1rMnqbXtTLYaSZoQdsxCRyfZ3oYjsdHwKRWRn8kSsmhydq57JSmr406ntUy2CkoZEGuC+AizXWWNMXccnR+dY+M9b1/RKtQhVmuv6tEm1CKkjkRs3K0mnW6v6vsQbSVl8HvghIiN8SV0Jy2H1slMtQpXmxLaNUi1CysiUyqUt6tTwum1P+nP/WUdFDfPH3v44r0ZSFs4Sc4QvqStKJeTu04+kfdM6Qce6tqyXImlgyEVdoob54o4+pb8v7N7CT3GiMuqOvgmNr17NagmNL5Uc07J+1DDN6mVz6lFNEp52JGVhwvyu9FTP9LJye8WhcZ0a5A8dmGoxqgx39m9P2ybByuLMTslf5T9/6EDyhw7kj8dFb2l2dVRCmRmp7Vl0SaFiTTWnd2wW8byXTp8Afx5wZGIEchCpVjwmMKCNtZWqDnCH4do+eb7E+58rengO++/Lu3PLKW1dz917RuILjhvDbzwuKekkmgfP7lDmWLItMSccUdbsdXnvwxl2Xe+Y4rm4R2p7BelIRdm37Zwuh5EVRVEf27qBp7g6Nq/LWQluoIRVFsaYTMeAdlZVGuAu8VC4erdpWPr77+d18kWOc7rkeg57/jHNGeRS6QE0r18TgMt6tSpzznkf5eXEto0TFleiieRddnMYJZtMTj6yrNng8Yu7cIrL8Ui0alArIfLcfXpyGhjJoGKoCnjq0mPKNFLq1wo2odXIyowajwhUy8zgv/93bCLF87RTXpXA2f3zUrjuPSP6QFNVZGAMCs7JxUm2k191QuuI58vbs7jt1EMKqE6NLM4/pnn5IkwyF8X4PI6J0XR052ntYgpfHvzoWPzt3I4AHFb3kCPKg2d3oG+7xlHLViRuPaUdDWtXL/0/9OLo403JQpWFzXmOlzlatzV/6MCILfIVQ84hf+hAfnl4AACN61QPGzYRDDja3c7Zt13yW/ovXdEjrvGRPx53OD0Or594gcJw1Ql5CY3v+cu6Bf3v2rJ+6ZjB/EfPpFVDby3+m09JD18SN3nzhw6kVnX3lm2D2t7KeL2a1cgfOpC7HY2tRIyn9e/QtNxxxMJ1fduQP3QgUx/qX3rs5lPa8t4Nx/GPCzrHHW+XlvWY+cjppf/P6hy58dUrz5tZKhFUDGXhUz8yXCVe3uRCzY6xtmz+EuPg1BXHuw9gGvtOIrWSr4sw3lItM/yF8ba8w7Ww24V4DwFccmzL+BJx4ahmofEbBnbNpW2T2gB0OCyHMxy9S4lxsoEXL5VImAQVcq+xOBVzwLZ9a7+2YW3mgZ6Dsyxf1qtVacs61c62/cM0mCBy3rqVu4rE9X3LzgfqcJg/owQVQ1kkgDv7ty/jkte+aQ7ndrU0t7M3UZ5ua/7QgYhdk8Zbod41wH0G7RF2xRbKqUdFblW5VXzVMzPIHzowYsulZjX3VmTLBjW56vj4utrX9snjgbOCx1b+OvBo6tcKVty92zTk8TBd8BPbNuJwu+U78d5+pXL+vwvDt+jq16pepgX70h97MP6efgCM+fPJvHpVT9drlz52dtTWb9O6NSKed8NtPMLtWR3n0ot1ytPCHpPyyohbT+Cz2/pwZiergr2wu6XAHzirA8uHnON6zUj73XFWvEN/15V/XhR/K9qNSPkc6dyRZRoDwTSuYz2faQ/3Dzp+yyltubN/4mesf3XnSZ7Dlsf77KzOuaWN04BFo0lO7GXRC5VeWQRaTX3aNqJ5fasV5DTbiEuNHmo/j5T5gdboH3qWHTwOEE73dDgs8ftKXdDNaU4LPuc2iArQPMwEwMDloRPUymPPd+Z3R3vQuVeeVRn+ztGTuLBbi7CTw5z3JRJfq7xJncRPeozHtz2eyX81ssK/tn08xOe1MZRdzUqntsP0VBJy7ZHNrDJ8nscxmUhl5/LeZd+hcGYvJ9f1aVPaeHDD7X5z7Il6XVvW88VcmxvDpNpA775anC7715xo9S787t1VnqmNLqwYcg4ZYhXwgPZeMeQcflqxlW8XbQxbcK8+MY/PZq0FYOWQcxA7jrYPfRUULnAOYOjvupRpCUd7eJ1b1GPxhkIev7gLD342L/oNOQr9mZ2aMXbBxjJBnrikKyNnrwuaKxKQ0c09E6Bj83qsK9jHg2d34PGvFx9Kzk5v0NkdmLZqG4+NXhRWtJdD3HxXDjmHEmNo9/DXYa85qX1jRv2pb+mz+WPvw/l9z1ZkiJAhlmI5t2suX85dHzYOJ7G8LPVqRZmo5YjMizIShDev6eWpIn7j6p5cP2w6Bnj/huMwBl7+fkX4uB2yrHRp+QfOT7y3H3mN3XufTgIiRpN14aNnYQjJ15BrWjWsxYoh55CZIUxduZWPp68pE8871/WmQ24Ovf85PmxaznfJyfzBZ3LQmIizyh8592hEhAu7Ned/s9dFvikT/E4Hyt41J+bx9o/5gFVHON/1uYPP4KKXprBi8263GF1pULs6K4acw3FDxrNl1/6w4QKyPHj20WTE2MMIlIVHzj2avw6M/fpY8a1nISJvisgm5057ItJQRMaJyDL729fRmcwMQUSCunmZGRLVlu98HzJc4gg9Z8UlZR5WreqWLg43IStgXjg6ty5HNYutl5ERRvjASzWwa25pTyJgpnBeMrDrIfPTSe2tllXomjIBn/2mOdlBPYImdWrQMy/YNNI2xPabkSFkubSUMpw9AQnugosI1TIzSp9buPs86cjGpd5rXmfnevVPLw9uZcCNNnaF3rddozLXBG7X2Qt0/s7IKJtGoNL3as4oqyTcr8vIsMq9M71zu5Y1WwbSDTfOc3jDWtTNtp7T2Z3d3wXnuxR6vFpmRsR8LS0rYcKE3q7bO+10WAnNx+ysTLIyDpXlwPsSjcwMKXO/3UOcOAKyxFLRB8aJAtfEen28+NmzeBt4EXjHcWwQMN4YM1REBtn/HyhvQt/f1496Natx/otT+G3bHs/XhSvcXuZZeKFm9Uym/3UA9WtW44NpvwEw7aH+9B5itbAuObYlpxzZhKZ1sxl5Rx86PDImbFwzHzmdS17+MWqaWZkZzPjrAOrWrEZWhnBx9xY0rVu2S/zEJV1Lf191QmvO7nwYTetm88vDA6hXsxoFe4toVLs6d5zWjqY5wdcfVi+b845pzj++XMjmwv28cXXPUnNEKB0Oy2HxhsLS/4KUVlaxDiIHuOXkthgse7NzrCPw1Pp3aMpjF3VmwuLNPPT5PLq2rOfZTHJITv84okkdpj3UP6x5c+Yjp1O7xiHzy62ntOWJMUsSln55Jqn965Kupb1uL/z04Gnk1rMaKzP+OiBhS2/88vAAev3z29gvDPNgz+mSy6T7TnWVr7rD7PfBjcfTo3V9z8n9/byO3DWgPT0f+7b0+tcmreTpcUs9x3Fx9xZ8Nmst951peZBNuLcfBw6WeL4+UfjWszDGTAK2hRy+ABhm/x4GXJiItFo3qk39WtUj2i2DZTv0u1Nzy27uHCQsCTXMloPGdWqUtrCPaFI7qOIWkdL/2WEGkwM0rF3dtXXsNrDXqE4NqmVmBMUPhyrnutlZQfZRZ7gmOTWonpVBk5waZGRIGUUB0Km55RkTaDWFUxRuOCcZeVq6ICRMm8a1S1u84SrberWqkVuvJl1aWHKeFqNbZU7IwnPhenGR5AxHwKuoad3g3lrAK6tdkzo0rF09aPKVW4s7GpEWz2tkD/Z2tvMnFvt6oNy0bFB2UN1NzICiCKTr1tt0I9pYRZOcGvQO6d12DDPx0qtuPLxRrbDmyR72u5fXuFaZiXGRlgfKyswoHVwH6z3vEWMvt66twAKOHDWrZ6Zkvatkj1k0M8asBzDGrBeRsG+xiNwE3ARQKzf8DFtnizHwoP943OHcFcHDIVB2ROCmk46gb7vGpS8OlB3ESwQT7+1Hw3LOt3jsos7k1svm398tR8RqYTTyeQ5HKL3zGnKrPeP5rwM7cnnvwz3NIfjgxuPZunu/5/kGAQIv+sPnHE3nFvXo2Ny7W2CXlvX48k99Y9ob5If7T6VOjSzmri0ArMH/QAX5w/2nUrC3iHNfmOz9BhyMv+cUmoZRcGd1zmXUHX3p3KL8bo+Be3DjqztPKnUXvf3UdpzWoWlQ2ffCxHv7eZ5XES+THziN3fuLyxz/5eEBFNmt6reu7cX6gn2l567r04bjj2jE9j0H+L83prlHHOe7/ej5nbjqhNZByi/A1If6u8rqZPpfB7C/2JK7T7vGPPuHYzyvFxZQwomyeMRL2npDGWNeNcb0NMb0zMrMYtvuA67hejsmpQR6Fud2yaWZi+klQH1bK+c1slqpoS9LTnbidWhe49qldtt4qZGVyQn2khqtGtaiTYxxZtnzJuLxww5Ucmd0alZqH62elRG1Ig5UTM3rZ3NuV0uxB8wgsbSXm+TU4IS2jSK3qFxeps4t6sXkmtiqYS0a1K5eWkac/vutGtYKW7F6afy3bVKHnAjPq0vLenH1IkIvCdyDk9aNrHfDqWwzXcq+F/Ia13Z9Dm69jXhpWLu6a8OiSU6N0uVratfICponEXiXAxV6YB7Vkc3qlHtGfqSyHk5WJ43r1AiyXlzUvWXpmGY04jXXJppk9yw2ikiu3avIBTZ5vTB/a7AnwvV9rVaEc+bmXwYcSa+8BpwYxRXumFb1eeuaXpzYzt07KJ13qTuhbSPeuLpnWDfYSNSukcXwG4+jU27sFcS5XXPJrpYZs0nniUu68vuerWjd6JCXTumYRRxmqGQRKCMnRHFFffmKHjQIMRsliy//1Jf6tarxh1emRg074tYTyd/i3ZsnHm45pS3//m45B4pL+McFnaK+R6Pv7FvuBlQk6mZX49+Xdadzy3r0f7pi7Q79/X392Ft0MNViBJFsZfEFcDUw1P4e6fXCDY7uJlg22dDlfKtnZXBah8hL/AY4NcnLAySSSLNVoxHvYn8iEnX5ZDdqVc8qo9hKzYAeWkyBdXIi2bCN066YQLyUkWb1sulxePKWXHASS6+gcZ0aQbZzP8jKzGDA0U35at4GGtWuUTp/JhyBsa9E4ywGgYZjbr1sNhfuT/ny615xNq4a1rYUaqo3cfItdRH5AOgHNBaRNcDfsZTExyJyPfAbcKnX+H5YtsUPMYN457repTvUfX7bib7ZCN+4umep+6STf17UmR17inxJMx3xUrc/cFYH2jWtE5ei8ovx95zCgnU72XugmO4+bWEZyri/nMy6kAZTgEq2sZ0vvHF1L35csaV0cD8a3959MgOemeSzVN646eS21KtVnUsjTPxNBr4pC2PM5WFO9Q9zPLb4ExFJCM4WcHcfW4vhegZXHBf/apUViVh0cHa1zJjzxW8bb9smdcpsbuQ37Zvl0D7GuThVHWcxa5JTgwu6eV9Jt13T9Mnr6lkZ/F+cy+skkgo0g7uirEqvRKN0UmSK5VAqJ4kqVx/ddDybCsPPvq5qVBhlUaY1WkF2v1LK4tcYQ1UvE+l0+4laRbdcMpQzQ44LszxOVaXCKAsnjWpX54aT02Pdf795+YoebA3jNlxROTTAnRhG3Hoio+asK/VIqmo2/Lev7cV7U3+jVcPEua7Gy+DzOrk6nySTeNyPlehUGGVRsPfQwO+Tl3b11eUunTg7zp3nKgKJeqc7t6hH5xb1+Hj66sREWMFo1zSHwef7s7VvrDStm80TlxyTajEUH6gwyuLr+RtSLQIXd29B9yQsSFfZubx3K8bMX88fXPYELw9ndGzG683qcGu/1O+praSOlg1q0q1V/TL7pijlo8Ioi3TgmT90S7UIlYLcejX55i+nJDze+rWq+xKvUrGolpnB/27vk2oxKh1pu9yHoiiKkj6oslAURVGiospCURRFiYoqC0VRFCUqFVJZtGmc3KUWlMrDMUlay0lRKhsV0hvKbRE+RfHCJzefQHFJ8rekVJSKToVUFooSL9WzMqheMTvUipJS9K1RFEVRoqLKQlEURYmKKgtFURQlKqosFEVRlKioslAURVGiospCURRFiYoqC0VRFCUqFUJZ6CQqRVGU1FJBlMWhvXR1uQZFUZTkUyGUhZPqmbq/rqIoSrKpcMpCUGWhKIqSbCqcslAURVGST4VTFgYTPZCiKIqSUCqeslBdoSiKknQqnLK4/bR2qRZBURSlylHhlMWpRzVNtQiKoihVjgqnLBRFUZTko8pCURRFiYoqC0VRFCUqqiwURVGUqKiyUBRFUaKiykJRFEWJSkqUhYicJSJLRGS5iAxKhQyKoiiKd5KuLEQkE3gJOBvoCFwuIh29XPvxzSf4KZqiKIoShqwUpNkbWG6MWQkgIh8CFwALw13QpUU9pg8dmCTxFEVRlFBSoSxaAKsd/9cAx4UGEpGbgJvsv/tFZH4SZCsvjYEtqRbCAypn4qgIMoLKmWgqipxHJSqiVCgLtw0pyiwPaIx5FXgVQESmG2N6+i1YeVE5E0tFkLMiyAgqZ6KpSHImKq5UDHCvAVo5/rcE1qVADkVRFMUjqVAWvwDtRaSNiFQHLgO+SIEciqIoikeSboYyxhSLyB3AWCATeNMYsyDKZa/6L1lCUDkTS0WQsyLICCpnoqlycorR3YQURVGUKOgMbkVRFCUqqiwURVGUqKS1skinZUFEpJWITBCRRSKyQETuso8PFpG1IjLb/pzjuOZBW/YlInJmEmXNF5F5tjzT7WMNRWSciCyzvxukUk4ROcqRZ7NFZKeI/Dkd8lNE3hSRTc65PfHkn4gcaz+H5SLybxFxcxtPtJxPishiEZkrIp+LSH37eJ6I7HXk63+TIWcYGWN+xinKy48cMuaLyGz7eEry0o4/XD3kf/k0xqTlB2vwewVwBFAdmAN0TKE8uUAP+3cOsBRruZLBwL0u4TvaMtcA2tj3kpkkWfOBxiHHngAG2b8HAf9KtZwhz3oD0Dod8hM4GegBzC9P/gHTgBOw5hZ9DZydBDnPALLs3/9yyJnnDBcSj29yhpEx5mecirwMOf808LdU5qUdf7h6yPfymc49i9JlQYwxB4DAsiApwRiz3hgz0/5dCCzCmo0ejguAD40x+40xq4DlWPeUKi4Ahtm/hwEXOo6nWs7+wApjzK8RwiRNTmPMJGCbS/qe809EcoG6xpifjPVmvuO4xjc5jTHfGGOK7b9TseYxhcVvOcPkZTjSKi8D2C3u3wMfRIojSXKGq4d8L5/prCzclgWJVDknDRHJA7oDP9uH7rC7/W86un+plN8A34jIDLGWTQFoZoxZD1aBA5qmgZwBLiP4RUy3/ITY86+F/Tv0eDK5DqvFGKCNiMwSke9F5CT7WKrkjOUZpzovTwI2GmOWOY6lPC9D6iHfy2c6KwtPy4IkGxGpA4wA/myM2Qm8DLQFugHrsbqrkFr5+xhjemCt7Hu7iJwcIWxK81msiZnnA5/Yh9IxPyMRTq5U5+vDQDHwvn1oPXC4MaY7cDcwXETqkho5Y33GqX72lxPcmEl5XrrUQ2GDhpEpZlnTWVmk3bIgIlIN6wG9b4z5DMAYs9EYc9AYUwK8xiHTSMrkN8ass783AZ/bMm20u56B7vKmVMtpczYw0xizEdIzP21izb81BJuAkiaviFwNnAtcYZsYsM0QW+3fM7Bs10emQs44nnEq8zILuBj4KHAs1XnpVg+RhPKZzsoirZYFse2WbwCLjDHPOI7nOoJdBAS8Kb4ALhORGiLSBmiPNaDkt5y1RSQn8BtrwHO+Lc/VdrCrgZGplNNBUKst3fLTQUz5Z5sCCkXkeLvsXOW4xjdE5CzgAeB8Y8wex/EmYu0lg4gcYcu5MhVyxvqMU5WXNgOAxcaYUpNNKvMyXD1EMspnIkfqE/0BzsEa7V8BPJxiWfpiddPmArPtzznAu8A8+/gXQK7jmodt2ZeQYK+ICHIegeX9MAdYEMg3oBEwHlhmfzdMpZx2urWArUA9x7GU5yeW8loPFGG1wK6PJ/+AnlgV4QrgRewVE3yWczmWjTpQRv9rh/2dXR7mADOB85IhZxgZY37GqchL+/jbwC0hYVOSl3b84eoh38unLvehKIqiRCWdzVCKoihKmqDKQlEURYmKKgtFURQlKqosFEVRlKioslAURVGiospCqdSISH0Ruc3xv7mIfOpTWheKyN8SEM9TInJaImRSlEShrrNKpcZeP+dLY0znJKT1I9ZkuC3ljKc18Jox5ozESKYo5Ud7FkplZyjQVqx9B54Uay+C+QAico2I/E9ERonIKhG5Q0TutheImyoiDe1wbUVkjL0w4w8i0iE0ERE5EtgfUBQi8raIvCzW3gMrReQUe9G8RSLyth0m0w43X6x9Bf4CYKzVdxuJyGHJySJFiU5WqgVQFJ8ZBHQ2xnSD0p6Gk85YK3dmY81+fsAY011EnsVaAuE5rE3vbzHGLBOR44D/AKFmoj5Ys3mdNLDDnQ+MssPcAPwiIt2w9vFoEej1iL1Rkc1MO/yIOO5ZURKOKgulqjPBWPsCFIpIAValDtZyFF3t1T1PBD6RQxuJ1XCJJxfYHHJslDHGiMg8rCWu5wGIyAKsDXS+B44QkReA0cA3jms3Ac3Le3OKkihUWShVnf2O3yWO/yVY70cGsCPQM4nAXqBemLid8ZbGbYzZLiLHAGcCt2NtsHOdHSbbjlNR0gIds1AqO4VY20/GhbH2ClglIpeCteqnXcGHsghoF0vcItIYyDDGjAAewdrWM8CRHFqNVVFSjioLpVJjrH0HptiDyE/GGc0VwPUiEljJ121730lAd5Eom94H0wKYKCKzsVY3fRBK9ytoB0yPU15FSTjqOqsoCUJEnscap/i2nPFcBPQwxjySGMkUpfxoz0JREscQrD06yksWh7YaVZS0QHsWiqIoSlS0Z6EoiqJERZWFoiiKEhVVFoqiKEpUVFkoiqIoUVFloSiKokTl/wPrm6n/proIsgAAAABJRU5ErkJggg==\n", - "text/plain": [ - "<Figure size 432x288 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "ax.plot(tsteps, rate)\n", @@ -921,7 +682,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "id": "c47e82ec-32f3-4de1-a32e-8f6b500787e0", "metadata": {}, "outputs": [], @@ -932,24 +693,10 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "id": "4066f042-995f-4987-bac2-7d7c61addbd0", "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "Object arrays cannot be loaded when allow_pickle=False", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [30]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m spike_data[area] \u001b[38;5;241m=\u001b[39m {}\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m pop \u001b[38;5;129;01min\u001b[39;00m M\u001b[38;5;241m.\u001b[39mstructure[area]:\n\u001b[0;32m----> 6\u001b[0m spike_data[area][pop] \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpath\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mM\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdata_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mrecordings\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m-spikes-\u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m-\u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m.npy\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabel_spikes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43marea\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpop\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/lib/npyio.py:440\u001b[0m, in \u001b[0;36mload\u001b[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)\u001b[0m\n\u001b[1;32m 438\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mformat\u001b[39m\u001b[38;5;241m.\u001b[39mopen_memmap(file, mode\u001b[38;5;241m=\u001b[39mmmap_mode)\n\u001b[1;32m 439\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_array\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfid\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mallow_pickle\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mallow_pickle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 441\u001b[0m \u001b[43m \u001b[49m\u001b[43mpickle_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpickle_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 442\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 443\u001b[0m \u001b[38;5;66;03m# Try a pickle\u001b[39;00m\n\u001b[1;32m 444\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m allow_pickle:\n", - "File \u001b[0;32m/srv/main-spack-instance-2302/spack/opt/spack/linux-ubuntu20.04-x86_64/gcc-10.3.0/py-numpy-1.21.6-6fewtq7oarp3vtwlxrrcofz5sxwt55s7/lib/python3.8/site-packages/numpy/lib/format.py:743\u001b[0m, in \u001b[0;36mread_array\u001b[0;34m(fp, allow_pickle, pickle_kwargs)\u001b[0m\n\u001b[1;32m 740\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dtype\u001b[38;5;241m.\u001b[39mhasobject:\n\u001b[1;32m 741\u001b[0m \u001b[38;5;66;03m# The array contained Python objects. We need to unpickle the data.\u001b[39;00m\n\u001b[1;32m 742\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m allow_pickle:\n\u001b[0;32m--> 743\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mObject arrays cannot be loaded when \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 744\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mallow_pickle=False\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 745\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m pickle_kwargs \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 746\u001b[0m pickle_kwargs \u001b[38;5;241m=\u001b[39m {}\n", - "\u001b[0;31mValueError\u001b[0m: Object arrays cannot be loaded when allow_pickle=False" - ] - } - ], + "outputs": [], "source": [ "# spike data \n", "spike_data = {}\n", @@ -1088,19 +835,10 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "id": "c05412f6-c842-415f-888a-b7604b795912", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Computing population rates\n", - "Computing population rates done!\n" - ] - } - ], + "outputs": [], "source": [ "\"\"\"\n", "Calculate time-averaged population rates and store them in member pop_rates.\n", @@ -1133,22 +871,10 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "id": "721d1f03-df25-468d-8075-a807025a9c58", "metadata": {}, - "outputs": [ - { - "ename": "FileNotFoundError", - "evalue": "[Errno 2] No such file or directory: '/opt/app-root/src/MAM2EBRAINS/simulations/27d81076e6d6e9e591684be053078477/Analysis/pop_rates.json'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [34]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# stationary firing rates\u001b[39;00m\n\u001b[1;32m 2\u001b[0m fn \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(data_path, label, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAnalysis\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpop_rates.json\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mr\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m f:\n\u001b[1;32m 4\u001b[0m pop_rates \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mload(f)\n", - "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/opt/app-root/src/MAM2EBRAINS/simulations/27d81076e6d6e9e591684be053078477/Analysis/pop_rates.json'" - ] - } - ], + "outputs": [], "source": [ "# stationary firing rates\n", "fn = os.path.join(data_path, label, 'Analysis', 'pop_rates.json')\n", @@ -1158,29 +884,10 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": null, "id": "9ba5ca35-7f90-47c8-a057-7cb02ee7be02", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plotting Population rates\n" - ] - }, - { - "ename": "NameError", - "evalue": "name 'pop_rates' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [95]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, area \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(M\u001b[38;5;241m.\u001b[39marea_list):\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m j, pop \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(M\u001b[38;5;241m.\u001b[39mstructure[area][::\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]):\n\u001b[0;32m---> 21\u001b[0m rate \u001b[38;5;241m=\u001b[39m \u001b[43mpop_rates\u001b[49m[area][pop][\u001b[38;5;241m0\u001b[39m]\n\u001b[1;32m 22\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m rate \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0.0\u001b[39m:\n\u001b[1;32m 23\u001b[0m rate \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1e-5\u001b[39m\n", - "\u001b[0;31mNameError\u001b[0m: name 'pop_rates' is not defined" - ] - } - ], + "outputs": [], "source": [ "def set_boxplot_props(d):\n", " for i in range(len(d['boxes'])):\n",