diff --git a/figures/MAM2EBRAINS/M2E_visualize_fc.py b/figures/MAM2EBRAINS/M2E_visualize_fc.py index cb38740b58de4d64393f30a1fe92f8ce90fb9f13..3e939ff541b1281b7d3e78667824a0cfaa5ca957 100644 --- a/figures/MAM2EBRAINS/M2E_visualize_fc.py +++ b/figures/MAM2EBRAINS/M2E_visualize_fc.py @@ -185,6 +185,6 @@ def visualize_fc(M, data_path): area_string += ' ' area_string += area - pl.text(0.00, 0.15, r'Order of cortical areas:', transform=fig.transFigure, fontsize=13, fontweight='bold') + pl.text(0.00, 0.15, r'Order of cortical areas from top to bottom and left to right:', transform=fig.transFigure, fontsize=13, fontweight='bold') pl.text(0.00, 0.1, area_string, transform=fig.transFigure, fontsize=11) diff --git a/figures/MAM2EBRAINS/M2E_visualize_interareal_connectivity.py b/figures/MAM2EBRAINS/M2E_visualize_interareal_connectivity.py index bb111c2cd7535efe4a7577aa2cf739e9154ad568..28740e0d9f9b48e1d6c743617df5437e771ac11e 100644 --- a/figures/MAM2EBRAINS/M2E_visualize_interareal_connectivity.py +++ b/figures/MAM2EBRAINS/M2E_visualize_interareal_connectivity.py @@ -12,7 +12,7 @@ from multiarea_model import MultiAreaModel def visualize_interareal_connectivity(M): """ - Visualize inter-area connectivity for a comparison of the full-scale model and the down-scaled model + Visualize inter-area connectivity for a comparison of the full-scale model and the downscaled model Parameters: - M ((MultiAreaModel)): Object containing simulation data. @@ -35,7 +35,7 @@ def visualize_interareal_connectivity(M): pl.rcParams['figure.figsize'] = (width, height) fig = pl.figure() - fig.suptitle('Area-level connectivity of the full-scale and down-scaled MAM expressed as relative indegrees for each target area', fontsize=15, x=0.5, y=1.05) + fig.suptitle('Area-level connectivity of the full-scale and downscaled MAM expressed as relative indegrees for each target area', fontsize=15, x=0.5, y=1.05) axes = {} gs1 = gridspec.GridSpec(1, 2) @@ -47,7 +47,7 @@ def visualize_interareal_connectivity(M): pos2 = axes['D'].get_position() labels = ['B', 'D'] - labels_display = ['Full-scale model', 'Down-scaled model'] + labels_display = ['Full-scale model', 'Downscaled model'] for i in range(len(labels)): label = labels[i] label_display = labels_display[i] @@ -100,7 +100,7 @@ def visualize_interareal_connectivity(M): cbar.set_alpha(0.) """ - Panel D: Interareal connectivity of down-scaling multi-area model + Panel D: Interareal connectivity of downscaling multi-area model """ conn_matrix_down_scale = np.zeros((32, 32)) for i, area1 in enumerate(area_list[::-1]): diff --git a/multi-area-model.ipynb b/multi-area-model.ipynb index b08687ce6932c9eeb460b91d0cfc7187941bb661..d05a844633f2a4b85ad21e4ad20e1ad4bd1d2401 100644 --- a/multi-area-model.ipynb +++ b/multi-area-model.ipynb @@ -7,7 +7,7 @@ "tags": [] }, "source": [ - "# Down-scaled multi-area model" + "# Downscaled multi-area model" ] }, { @@ -23,7 +23,7 @@ "id": "f4a649cc-3b68-49e4-b2b6-6f29f13a6d9c", "metadata": {}, "source": [ - "The code in this notebook implements the down-scaled version of spiking network model of macaque visual cortex developed at the Institute of Neuroscience and Medicine (INM-6), Research Center Jülich. The full-scale model has been documented in the following publications:\n", + "The code in this notebook implements the downscaled version of spiking network model of macaque visual cortex developed at the Institute of Neuroscience and Medicine (INM-6), Research Center Jülich. The full-scale model has been documented in the following publications:\n", "\n", "1. Schmidt M, Bakker R, Hilgetag CC, Diesmann M & van Albada SJ\n", " Multi-scale account of the network structure of macaque visual cortex\n", @@ -164,7 +164,7 @@ "id": "9daf88e5-0d45-4529-a228-70c33900b05e", "metadata": {}, "source": [ - "The values assigned for the following parameters are kept the same as in the paper except for the `scale_down_to` which is set as 0.006 enabling to simulate a down-scaled multi-area model with 2GB RAM. By default, it is set to 1.0 for simulating the full-scale model." + "The values assigned for the following parameters are kept the same as in the paper except for the `scale_down_to` which is set as 0.006 enabling to simulate a downscaled multi-area model with 2GB RAM. By default, it is set to 1.0 for simulating the full-scale model." ] }, { @@ -187,9 +187,9 @@ "id": "a2161477", "metadata": {}, "source": [ - "1. `scale_down_to` is the down-scaling factor that defines the ratio by which the full-scale multi-area model is reduced to a model with fewer neurons and indegrees. This reduction is essential to enable simulation on machines with limited computational power, ensuring that simulation results can be obtained in a relatively shorter timeframe. <br> If the value is `scale_down_to = 1.`, the full-scale network will be simulated. <br> In the pre-set down-scaled version, `scale_down_to = 0.006`. This setting reduces the number of neurons and indegrees to 0.6 % of their full-scale counterparts, facilitating simulation on a typical local machine. <br> **Warning**: This may not yield reasonable results from the network dynamics and is only meant to demonstrate the simulation workflow! <br> \n", + "1. `scale_down_to` is the downscaling factor that defines the ratio by which the full-scale multi-area model is reduced to a model with fewer neurons and indegrees. This reduction is essential to enable simulation on machines with limited computational power, ensuring that simulation results can be obtained in a relatively shorter timeframe. <br> If the value is `scale_down_to = 1.`, the full-scale network will be simulated. <br> In the pre-set downscaled version, `scale_down_to = 0.006`. This setting reduces the number of neurons and indegrees to 0.6 % of their full-scale counterparts, facilitating simulation on a typical local machine. <br> **Warning**: This may not yield reasonable results for the network dynamics and is only meant to demonstrate the simulation workflow! <br> \n", "\n", - "2. `cc_weights_factor` is the scaling factor that controls the cortico-cortical synaptic strength. <br> By default it is set to `1.9`, keeping the same value for producing the metastable state as in the original paper. <br> **Important**: This factor plays a crucial role in transitioning the network activity from the ground to the metastable state. In the full-scale network, the ground state and metastable state activities are achieved when this parameter is set to `1.0` and `1.9`, respectively. In the down-scaled multi-area model, a similar metastable state may not be achieved or achieved with a different value. <br>\n", + "2. `cc_weights_factor` is the scaling factor that controls the cortico-cortical synaptic strength. <br> By default it is set to `1.9`, keeping the same value for producing the metastable state as in the original paper. <br> **Important**: This factor plays a crucial role in transitioning the network activity from the ground to the metastable state. In the full-scale network, the ground state and metastable state activities are achieved when this parameter is set to `1.0` and `1.9`, respectively. In the downscaled multi-area model, a similar metastable state may not be achieved or achieved with a different value. <br>\n", "\n", "3. `areas_simulated` specifies the cortical areas to be included in the simulation process. Its default value is `complete_area_list` meaning all the areas in the complete_area_list will be simulated.\n", "```python\n", @@ -197,7 +197,7 @@ "```\n", "The value assigned to `areas_simulated` can be any sublist of complete_area_list.\n", "\n", - "4. `replace_non_simulated_areas` defines how non-simulated areas will be replaced. <br> When all areas are included, it is set as `None` by default. <br> Other options are: `'hom_poisson_stat'`, `'het_poisson_stat'`, and `'het_current_nonstat'`.<br> `'hom_poisson_stat'` replaces the non-simulated areas by Poisson sources with the same global rate `rate_ext`. The `'het_poisson_stat'` and `'het_current_nonstat'` options use the loaded specific rates from `'replace_cc_input_source'`, which contains the area-specific firing rates of our full-scale simulation results. The difference is that `'het_poisson_stat'` replaces the non-simulated areas by Poisson spike trains and `'het_current_nonstat'` replaces it with a time-varying current input.\n", + "4. `replace_non_simulated_areas` defines how non-simulated areas will be replaced. <br> When all areas are included, it is set as `None` by default. <br> Other options are: `'hom_poisson_stat'`, `'het_poisson_stat'`, and `'het_current_nonstat'`.<br> `'hom_poisson_stat'` replaces the non-simulated areas by Poisson sources with the same global rate `rate_ext`. The `'het_poisson_stat'` and `'het_current_nonstat'` options use the loaded specific rates from `'replace_cc_input_source'`, which contains the area-specific firing rates of our full-scale simulation results. The difference is that `'het_poisson_stat'` replaces the non-simulated areas by Poisson spike trains and `'het_current_nonstat'` replaces them with a time-varying current input.\n", "\n", "5. `g` defines the relative inhibitory synaptic strength (in relative units to the excitatory synaptic strength). By default: `-11.0`, as used in the full-scale network. `g = -1.0` means equal excitatory and inhibitory strengths, and `g < -1.0` results in stronger inhibition than excitation.\n", "\n", @@ -218,7 +218,7 @@ "# Scaling factor for cortico-cortical connections (Chi) \n", "# value range/options: [1., 2.5], \n", "# a weight factor of 1.0 produces Ground state activity.\n", - "# 1.9 was assigned to produce results in Schmidt et al. (2018).\n", + "# 1.9 was assigned to produce the metastable results in Schmidt et al. (2018).\n", "cc_weights_factor = 1.9\n", "\n", "# Cortical areas included in the simulation\n", @@ -275,9 +275,7 @@ "id": "56e2b6f6-d67a-4a74-973b-c8507a975bf8", "metadata": {}, "source": [ - "We try our best not to confuse users with too many parameters. So, the few parameters tunned will be automatically assigned in this section to properly run the simulation. \n", - "\n", - "However, if you want to explore the model, you can alter other parameters related to the network or simulation configuration by passing them in the `network_params` and `sim_params` dictionaries below. If this is not the case, you can execute the cell the way it is." + "The cell below assigns the parameters defined in the previous section. If you want to explore the model, you can alter network or simulation configuration parameters in the `network_params` and `sim_params` dictionaries below." ] }, { @@ -299,6 +297,13 @@ " raise Exception(\"'hom_poisson_stat', 'het_poisson_stat', or 'het_current_nonstat' should be assigned to replace_non_simulated_areas when not all areas are simulated!\")\n", "\n", "# Determine cc_weights_I_factor from cc_weights_factor\n", + "# This additional factor scales the cortico-cortical weights targeting inhibitory populations.\n", + "# In this case, the cc_weights_factor is multiplied by the cc_weights_I_factor.\n", + "# For example:\n", + "# - If cc_weights_I_factor is 1.0, cortico-cortical connections have the same synaptic weight\n", + "# for both excitatory and inhibitory targets.\n", + "# - If cc_weights_I_factor > 1.0, cortico-cortical connections targeting inhibitory neurons are stronger.\n", + "# The conditions below are based on the results in Schmidt et al. (2018).\n", "if cc_weights_factor == 1.0: # For ground state with cc_weights_factor as 1., \n", " cc_weights_I_factor = 1.0 # cc_weights_I_factor is set to 1.\n", "elif cc_weights_factor > 1.0: # For cc_weights_factor larger than 1.0,\n", @@ -368,35 +373,6 @@ " theory=True)" ] }, - { - "cell_type": "markdown", - "id": "91649c30", - "metadata": {}, - "source": [ - "### 2.3. Predict firing rates from theory <a class=\"anchor\" id=\"section_2_3\"></a>" - ] - }, - { - "cell_type": "markdown", - "id": "07cc84bf-dbcf-4ac3-b76e-ebe0886b4012", - "metadata": {}, - "source": [ - "Note: the prediction may differ from the simulation results, especially in the presence of synchrony." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a7ddf0e", - "metadata": {}, - "outputs": [], - "source": [ - "p, r = M.theory.integrate_siegert()\n", - "\n", - "print(\"Mean-field theory predicts an average \"\n", - " \"firing rate of {0:.3f} spikes/s across all populations.\".format(np.mean(r[:, -1])))" - ] - }, { "cell_type": "markdown", "id": "c361fa92-4f50-4519-9592-60a39888a12b", @@ -410,7 +386,7 @@ "id": "2062ddf3", "metadata": {}, "source": [ - "### 2.4. Extract and visualize inter-areal connectivity <a class=\"anchor\" id=\"section_2_4\"></a>" + "### 2.3. Extract and visualize inter-areal connectivity <a class=\"anchor\" id=\"section_2_4\"></a>" ] }, { @@ -422,11 +398,11 @@ "- Neuron numbers of all populations in each area are stored in `M.N` as a dictionary (and in `M.N_vec` as an array).\n", "\n", "- Indegrees are stored in `M.K` as a dictionary (and in `M.K_matrix` as an array).<br>\n", - " Dictionary of nodes indegrees organized as:<br>\n", + " Dictionary of indegrees organized as:<br>\n", " `{<target_area>: {<target_pop>: {<source_area>: {<source_pop>: indegree_values}}}}`\n", "\n", - "- Number of synapses can be accessed via `M.synapses` (and in `M.syn_matrix` as an array). <br>\n", - " Dictionary of synapses that target neurons receive, it is organized as:<br>\n", + "- Numbers of synapses can be accessed via `M.synapses` (and in `M.syn_matrix` as an array). <br>\n", + " Dictionary of synapses that target neurons receive organized as:<br>\n", " `{<target_area>: {<target_pop>: {<source_area>: {<source_pop>: number_of_synapses}}}}`" ] }, @@ -435,7 +411,9 @@ "id": "6b473f0e-ceca-47e1-9563-a613574497c4", "metadata": {}, "source": [ - "The figure below shows the inter-areal connectivity of the model expressed as the relative indegrees of each target area. The relative indegree of a target area from a specific source area is calculated by dividing its indegree by the sum of indegrees that the target area receives from all sources." + "The figure below shows the inter-areal connectivity of the model expressed as the relative indegrees of each target area. The relative indegree of a target area from a specific source area is calculated by dividing its indegree by the sum of indegrees that the target area receives from all sources.\n", + "\n", + "The relative indegrees of the full-scale and downscaled models are the same apart from potential differences due to rounding." ] }, { @@ -474,7 +452,7 @@ "id": "0c1cad59-81d0-4e24-ac33-13c4ca8c6dec", "metadata": {}, "source": [ - "### 2.5. Run a simulation <a class=\"anchor\" id=\"section_2_5\"></a>" + "### 2.4. Run a simulation <a class=\"anchor\" id=\"section_2_5\"></a>" ] }, { @@ -493,7 +471,7 @@ "id": "72a89aeb-78b9-4642-be0d-6de4d6c8f817", "metadata": {}, "source": [ - "**Reminder**: The spike trains of simulated results are saved to the folder with path `./simulations/<simulation_label>/recordings` where the `<simulation_label>` is displayed in the output of 2.2. All statistics describing network dynamics are computed from the saved spike trains." + "**Note**: The spike trains of simulated results are saved to the folder with path `./simulations/<simulation_label>/recordings` where the `<simulation_label>` is displayed in the output of 2.2. All statistics describing network dynamics are computed from the saved spike trains." ] }, { @@ -634,7 +612,7 @@ "outputs": [], "source": [ "# Choose at most 3 areas from the areas_simulated to show their spiking activities\n", - "# By default, the list is ['V1', 'V2', 'FEF'] when all areas from complete_area_list are simulated\n", + "# By default, the list is ['V1', 'V2', 'FEF']\n", "raster_areas = ['V1', 'V2', 'FEF']\n", "\n", "from M2E_visualize_dynamics import visual_dynamics\n", @@ -654,7 +632,7 @@ "id": "013adaf8-af8b-470e-94f0-b69121d1ca2c", "metadata": {}, "source": [ - "Comparison of area-level functional connectivity (FC) between the down-scaled MAM and macaque experimental data. (A) Simulated FC measured by the zero-time-lag correlation coefficient of synaptic input currents. (B) FC of macaque resting-state fMRI (see Materials and methods)." + "Comparison of area-level functional connectivity (FC) between the downscaled MAM and macaque experimental data. (A) Simulated FC measured by the zero-time-lag correlation coefficient of synaptic input currents. (B) FC of macaque resting-state fMRI (see Materials and methods in Schmidt et al. 2018)." ] }, { @@ -694,7 +672,7 @@ "1. Simulation data <br>\n", "The spike data of all simulated populations for all simulations are saved in `./simulations/<simulation_label>/recordings` where `<simulation_label>` can be accessed in the output of 2.2. Or users can see their latest simulation by checking the column \"Last Modified\" and find the folder with the latest change.\n", "2. Statistics <br>\n", - "The statistics of network dynamics computed from the spike trains can be found in `./simulations/<simulation_label>/Analysis`. You may also find more statistics defined in `./multiarea_model/analysis.py` to explore more about network dynamics.\n", + "The statistics of network dynamics computed from the spike trains can be found in `./simulations/<simulation_label>/Analysis`. You may also find more statistics defined in `./multiarea_model/analysis.py` to further explore the network dynamics.\n", "3. Scripts for visualizing network dynamics <br>\n", "The scripts for computing statistics and plotting the figures in S3 can be found in `./figures/MAM2EBRAINS`." ] diff --git a/multiarea_model/simulation.py b/multiarea_model/simulation.py index 9c0f5cf2c29cbb987da3d197fa38e591ef8ad5a0..ce7c6899bcfa517c194e11a52fedc9c5e4e03851 100644 --- a/multiarea_model/simulation.py +++ b/multiarea_model/simulation.py @@ -199,7 +199,7 @@ class Simulation: for area_name in self.areas_simulated: a = Area(self, self.network, area_name) self.areas.append(a) - print("Memory after {0} : {1:.2f} MB".format(area_name, self.memory() / 1024.)) + print("Memory after the creation of area {0} : {1:.2f} MB".format(area_name, self.memory() / 1024.)) def cortico_cortical_input(self): """ @@ -419,9 +419,8 @@ class Area: self.create_populations() self.connect_devices() self.connect_populations() - print("Rank {}: created area {} with {} local nodes".format(nest.Rank(), - self.name, - self.num_local_nodes)) + print() + print("Created area {}.".format(self.name)) def __str__(self): s = "Area {} with {} neurons.".format(