def generate_network(population=None, gids=None, method="intersection", intersection_proba=1.): """ Create the """ try: import nngt except ImportError: raise RuntimeError("This function requires the NNGT library to work. " "Please install it by refering to the install " "section of the documentation: http://nngt." "readthedocs.org/en/latest/.") if gids is None: neurons, gids = population, population.gids else: gids, neurons = population.get_gid(gids) positions = np.array([neuron.position for neuron in neurons]) axons = [neuron.axon for neuron in neurons] dendrites_s = [neuron.dendrites for neuron in neurons] num_neurons = len(neurons) graph = nngt.SpatialGraph(nodes=num_neurons, positions=positions) if method is "intersection": intersections, synapses, liste = Intersections(gids, axons, dendrites_s, intersection_proba) for node_out, nodes_in in intersections.items(): edges = np.zeros((len(nodes_in), 2), dtype=int) edges[:, 0] = node_out edges[:, 1] = nodes_in graph.new_edges(edges) return graph, intersections, synapses, liste
def test_new_node_attr(self): ''' Test node creation with attributes. ''' shape = nngt.geometry.Shape.rectangle(1000., 1000.) g = nngt.SpatialGraph(100, shape=shape, name="new_node_spatial") self.assertTrue( g.node_nb() == 100, '''Error on graph {}: invalid initial nodes ({} vs {} expected). '''.format(g.name, g.node_nb(), 100)) n = g.new_node(positions=[(0, 0)]) self.assertTrue( np.all(np.isclose(g.get_positions(n), (0, 0), self.tolerance)), '''Error on graph {}: last position is ({}, {}) vs (0, 0) expected. '''.format(g.name, *g.get_positions(n)))
def test_new_node_attr(): ''' Test node creation with attributes. ''' shape = nngt.geometry.Shape.rectangle(1000., 1000.) g = nngt.SpatialGraph(100, shape=shape, name="new_node_spatial") assert g.node_nb() == 100, \ "Error on '{}': invalid initial nodes ({} vs {} expected).".format( g.name, g.node_nb(), 100) n = g.new_node(positions=[(0, 0)]) assert np.all(np.isclose(g.get_positions(n), (0, 0), tolerance)), \ "Error on '{}': last position is ({}, {}) vs (0, 0) expected.".format( g.name, *g.get_positions(n))
def test_group_plot(): ''' Test plotting with a Network and group colors ''' gsize = 5 g1 = nngt.Group(gsize) g2 = nngt.Group(gsize) s = nngt.Structure.from_groups({"1": g1, "2": g2}) positions = np.concatenate((nngt._rng.uniform(-5, -2, size=(gsize, 2)), nngt._rng.uniform(2, 5, size=(gsize, 2)))) g = nngt.SpatialGraph(2 * gsize, structure=s, positions=positions) nngt.generation.connect_groups(g, g1, g1, "erdos_renyi", edges=5) nngt.generation.connect_groups(g, g1, g2, "erdos_renyi", edges=5) nngt.generation.connect_groups(g, g2, g2, "erdos_renyi", edges=5) nngt.generation.connect_groups(g, g2, g1, "erdos_renyi", edges=5) g.new_edge(6, 6, self_loop=True) nplt.draw_network(g, ncolor="group", ecolor="group", show_environment=False, fast=True, show=False) nplt.draw_network(g, ncolor="group", ecolor="group", max_nsize=0.4, esize=0.3, show_environment=False, show=False) nplt.draw_network(g, ncolor="group", ecolor="group", max_nsize=0.4, esize=0.3, show_environment=False, curved_edges=True, show=False)
def test_spatial(): from nngt.geometry import Shape shape = Shape.disk(100, default_properties={"plop": 0.2, "height": 1.}) area = Shape.rectangle(10, 10, default_properties={"height": 10.}) shape.add_area(area, name="center") g = nngt.SpatialGraph(20, shape=shape) for fmt in formats: g.to_file(gfilename, fmt=fmt) h = nngt.load_from_file(gfilename, fmt=fmt) assert np.all(np.isclose(g.get_positions(), h.get_positions())) assert g.shape.normalize().almost_equals(h.shape.normalize(), 1e-5) for name, area in g.shape.areas.items(): assert area.normalize().almost_equals( h.shape.areas[name].normalize(), 1e-5) assert area.properties == h.shape.areas[name].properties
def test_plot_spatial_alpha(): ''' Test positional layout and alpha parameters ''' num_nodes = 4 pos = [(1, 1), (0, -1), (-1, -1), (-1, 1)] g = nngt.SpatialGraph(num_nodes, positions=pos) g.new_edges([(0, 1), (0, 2), (1, 3), (3, 2)]) for fast in (True, False): nplt.draw_network(g, nsize=0.02 + 30 * fast, ealpha=1, esize=0.1 + fast, fast=fast) nplt.draw_network(g, layout=[(y, x) for (x, y) in pos], show_environment=False, nsize=0.02 + 30 * fast, nalpha=0.5, esize=0.1 + 3 * fast, fast=fast)
def distance_rule(scale, rule="exp", shape=None, neuron_density=1000., max_proba=-1., nodes=0, density=-1., edges=-1, avg_deg=-1., unit='um', weighted=True, directed=True, multigraph=False, name="DR", positions=None, population=None, from_graph=None, **kwargs): """ Create a graph using a 2D distance rule to create the connection between neurons. Available rules are linear and exponential. Parameters ---------- scale : float Characteristic scale for the distance rule. E.g for linear distance- rule, :math:`P(i,j) \propto (1-d_{ij}/scale))`, whereas for the exponential distance-rule, :math:`P(i,j) \propto e^{-d_{ij}/scale}`. rule : string, optional (default: 'exp') Rule that will be apply to draw the connections between neurons. Choose among "exp" (exponential), "gaussian" (Gaussian), or "lin" (linear). shape : :class:`~nngt.geometry.Shape`, optional (default: None) Shape of the neurons' environment. If not specified, a square will be created with the appropriate dimensions for the number of neurons and the neuron spatial density. neuron_density : float, optional (default: 1000.) Density of neurons in space (:math:`neurons \cdot mm^{-2}`). nodes : int, optional (default: None) The number of nodes in the graph. p : float, optional Normalization factor for the distance rule; it is equal to the probability of connection when testing a node at zero distance. density: double, optional Structural density given by `edges` / (`nodes` * `nodes`). edges : int, optional The number of edges between the nodes avg_deg : double, optional Average degree of the neurons given by `edges` / `nodes`. unit : string (default: 'um') Unit for the length `scale` among 'um' (:math:`\mu m`), 'mm', 'cm', 'dm', 'm'. weighted : bool, optional (default: True) @todo Whether the graph edges have weights. directed : bool, optional (default: True) Whether the graph is directed or not. multigraph : bool, optional (default: False) Whether the graph can contain multiple edges between two nodes. name : string, optional (default: "DR") Name of the created graph. positions : :class:`numpy.ndarray`, optional (default: None) A 2D (N, 2) or 3D (N, 3) shaped array containing the positions of the neurons in space. population : :class:`~nngt.NeuralPop`, optional (default: None) Population of neurons defining their biological properties (to create a :class:`~nngt.Network`). from_graph : :class:`Graph` or subclass, optional (default: None) Initial graph whose nodes are to be connected. """ distance = [] # convert neuronal density in (mu m)^2 neuron_density *= conversion_magnitude(unit, 'mm')**2 # set node number and library graph graph_dr = from_graph if graph_dr is not None: nodes = graph_dr.node_nb() graph_dr.clear_all_edges() else: nodes = population.size if population is not None else nodes # check shape if shape is None: h = w = np.sqrt(float(nodes) / neuron_density) shape = nngt.geometry.Shape.rectangle(h, w) if graph_dr is None: graph_dr = nngt.SpatialGraph(name=name, nodes=nodes, directed=directed, shape=shape, positions=positions, **kwargs) else: Graph.make_spatial(graph_dr, shape, positions=positions) positions = np.array(graph_dr.get_positions().T, dtype=np.float32) # set options (graph has already been made spatial) _set_options(graph_dr, population, None, None) # add edges ia_edges = None conversion_factor = conversion_magnitude(shape.unit, unit) if unit != shape.unit: positions = np.multiply(conversion_factor, positions, dtype=np.float32) if nodes > 1: ids = np.arange(0, nodes, dtype=np.uint) ia_edges = _distance_rule(ids, ids, density, edges, avg_deg, scale, rule, max_proba, shape, positions, directed, multigraph, distance=distance, **kwargs) attr = {'distance': distance} # check for None if MPI if ia_edges is not None: graph_dr.new_edges(ia_edges, attributes=attr) graph_dr._graph_type = "{}_distance_rule".format(rule) return graph_dr
def no_obstacles(shape): ''' Network generation and simulation without obsacle Input: shape : nngt spatial shape object to embed the neuron Output: net : nngt network Create a Spatial network and seed neurons Neurons are spread proportionaly to the area ''' total_area = shape.area num_neurons = int(density * total_area) num_excitatory = int(fraction_excitatory * num_neurons) num_inhibitory = num_neurons - num_excitatory print("Total number of neurons : {}".format(num_neurons)) print("Excitatory neurons : {}".format(num_excitatory)) print("Inhibitory neurons : {}".format(num_inhibitory)) pop = nngt.NeuralPop(num_neurons, with_model=True) # # Instruction si on ne veut pas de modèle # pop.set_model(None) pop.create_group(num_excitatory, "excitatory", neuron_model="aeif_psc_alpha", neuron_param=params1) pop.create_group(num_inhibitory, "inhibitory", neuron_type=-1, neuron_model="aeif_psc_alpha", neuron_param=params1) # make the graph net = nngt.SpatialGraph(shape=shape, population=pop) # seed neurons excitatory_pos = shape.seed_neurons(num_excitatory, on_area=shape.default_areas, soma_radius=15) excitatory_neurons = np.array(net.new_node(num_excitatory, positions=excitatory_pos, groups="excitatory"), dtype=int) inhibitory_pos = shape.seed_neurons(num_inhibitory, on_area=shape.default_areas, soma_radius=15) inhibitory_neurons = np.array(net.new_node(num_inhibitory, positions=inhibitory_pos, groups="inhibitory", neuron_type=-1), dtype=int) # Establishment of the connectivity # Scale for the connectivity distance function. connectivity_scale = 100 print("\n----------\n Connectivity") print( "Connectivity characteristic distance {0}".format(connectivity_scale)) print(" (NB: the scale for bottom with obstacles is 100)") # base connectivity probability connectivity_proba = 3. print("Connectivity basic probability {0}".format(connectivity_proba)) print("(Identical between any types of neurons)") # connect bottom area for name, area in shape.default_areas.items(): # excitatory to excitatory print('E > E') nngt.generation.connect_nodes(net, excitatory_neurons, excitatory_neurons, "distance_rule", scale=connectivity_scale, max_proba=connectivity_proba) # excitatory to inhibitory print('E > I') nngt.generation.connect_nodes(net, excitatory_neurons, inhibitory_neurons, "distance_rule", scale=connectivity_scale, max_proba=connectivity_proba) # inhibitory to inhibitory print('I > I') nngt.generation.connect_nodes(net, inhibitory_neurons, inhibitory_neurons, "distance_rule", scale=connectivity_scale, max_proba=connectivity_proba) # inhibitory to excitatory print('I > E') nngt.generation.connect_nodes(net, inhibitory_neurons, excitatory_neurons, "distance_rule", scale=connectivity_scale, max_proba=connectivity_proba) # Here we set the synaptic weigth. By default synapses are static in net net.set_weights(synaptic_weigth) # Graphs output print('Graphs output') output_graphs(net, inhibitory_neurons, excitatory_neurons, [("excitatory", "excitatory"), ("inhibitory", "excitatory"), ("inhibitory", "inhibitory"), ("excitatory", "inhibitory")], "inhibitory neurons", "excitatory neurons") # Simulate with NEST print('Activity simulation') activity_simulation(net, pop)
def with_obstacles_EI(shape, params={ "height": 250., "width": 250. }, filling_fraction=0.4): ''' Network generation and simulation with obstacles and inhibitory neurons ----------------------------------------------------------------------- Input : shape : nngt defined spatial shape params : dictionary with obstacles specifications filling_fraction : float, fraction of the embedding shape filled with obstacles Output: nngt network of neurons ''' ''' Create obstacles within the shape''' shape.random_obstacles(filling_fraction, form="rectangle", params=params, heights=30., etching=20.) ''' Create a Spatial network and seed neurons on top/bottom areas ''' # neurons are reparted proportionaly to the area total_area = shape.area bottom_area = np.sum([a.area for a in shape.default_areas.values()]) num_bottom = int(density * bottom_area) num_bottom_E = int(fraction_excitatory * num_bottom) num_bottom_I = num_bottom - num_bottom_E # compute number of neurons in each top obstacle according to its area num_top_list = [] # list for the number of neurons on each top obsatacle # list for the number of excitatory of neurons on each top obsatacle num_top_list_E = [] # list for the number of inhibitoryneurons on each top obsatacle num_top_list_I = [] num_top_total = 0 # count total number of neurons in top obstacles num_top_E = 0 # count total number of neurons in top obstacles num_top_I = 0 # count total number of neurons in top obstacles for name, top_area in shape.non_default_areas.items(): num_top = int(density * top_area.area) num_excitatory = int(fraction_excitatory * num_top) num_inhibitory = num_top - num_excitatory num_top_list.append(num_top) num_top_list_E.append(num_excitatory) num_top_list_I.append(num_inhibitory) num_top_total += num_top num_top_E += num_excitatory num_top_I += num_inhibitory num_neurons = num_bottom + num_top_total # Total number of neurons num_neurons_E = num_bottom_E + num_top_E # Total number excitatory neurons num_neurons_I = num_bottom_I + num_top_I # Total number inhibitory neurons print("Total number of neurons : {0}".format(num_neurons)) print("Bottom neurons : {0}".format(num_bottom)) print("Top neurons : {0}".format(num_top_total)) print("Total number of excitatory neurons : {0}".format(num_neurons_E)) print("Bottom excitatory neurons : {0}".format(num_bottom_E)) print("Top excitatory neurons : {0}".format(num_top_E)) print("Total number of inhibitory neurons : {0}".format(num_neurons_I)) print("Bottom inhibitory neurons : {0}".format(num_bottom_I)) print("Top inhibitory neurons : {0}".format(num_top_I)) pop = nngt.NeuralPop(num_neurons, with_model=True) # # Instruction si on ne veut pas de modèle # pop.set_model(None) # create groups for excitatory and inhibitory bottom neurons pop.create_group(num_bottom_E, "bottom_E", neuron_model="aeif_psc_alpha", neuron_param=params1) pop.create_group(num_bottom_I, "bottom_I", neuron_model="aeif_psc_alpha", neuron_param=params1) # Create groups at the top def create_top_groups(num_top_list, group_name_prefix, model, params): ''' Creation of neurons groups on the top of obstacles''' for num_top, (name, top_area) in\ zip(num_top_list, shape.non_default_areas.items()): # num_top = int(density * top_area.area) group_name = group_name_prefix + name if num_top: pop.create_group(num_top, group_name, neuron_model=model, neuron_param=params) # Create groups for excitatory neurons on each top area create_top_groups(num_top_list_E, "top_E_", "aeif_psc_alpha", params1) # Create groups for inhibitory neurons on each top are create_top_groups(num_top_list_I, "top_I_", "aeif_psc_alpha", params1) # make the graph net = nngt.SpatialGraph(shape=shape, population=pop) # seed neurons def seed_bottom_neurons(num_bottom, group_name, neuron_type): ''' Seed botoom neurons''' bottom_pos = shape.seed_neurons(num_bottom, on_area=shape.default_areas, soma_radius=15) bottom_neurons = np.array(net.new_node(num_bottom, positions=bottom_pos, groups=group_name, neuron_type=neuron_type), dtype=int) return bottom_pos, bottom_neurons print("Seeding bottom neurons") bottom_pos_E, bottom_neurons_E = seed_bottom_neurons(num_bottom_E, "bottom_E", neuron_type=1) bottom_pos_I, bottom_neurons_I = seed_bottom_neurons(num_bottom_I, "bottom_I", neuron_type=-1) bottom_neurons = [] bottom_neurons.append(list(bottom_neurons_E)) bottom_neurons.append(list(bottom_neurons_I)) bottom_neurons = bottom_neurons[0] def seed_top_neurons(grp_name_prefix, ntype): ''' Seed top neurons ntype : neuron type +1 excitatory, -1 inhibitory ''' top_pos = [] top_neurons = [] top_grp_name_list = [] for name, top_area in shape.non_default_areas.items(): grp_name = grp_name_prefix + name if grp_name in pop: # print("Seeding group {}".format(grp_name)) # number of neurons in the top group num_top = pop[grp_name].size # print("of size :{0}".format(num_top)) # locate num_top neurons in the group area top_pos_tmp = top_area.seed_neurons(num_top, soma_radius=15) top_pos.extend(top_pos_tmp) seeded_neurons = net.new_node(num_top, positions=top_pos_tmp, groups=grp_name, neuron_type=ntype) # print seeded_neurons # previous method return an int, not a list, in case of a # single node, for extension of top_neurons list we need a list if type(seeded_neurons) is not list: seeded_neurons = [seeded_neurons] top_neurons.extend(seeded_neurons) top_grp_name_list.append(grp_name) top_pos = np.array(top_pos) top_neurons = np.array(top_neurons, dtype=int) return top_neurons, top_pos, top_grp_name_list print("Seeding top neurons") # top_pos_E = [] # top_neurons_E = [] # top_groups_name_list_E = [] top_neurons_E,\ top_pos_E,\ top_groups_name_list_E = seed_top_neurons("top_E_", ntype=1) # top_pos_I = [] # top_neurons_I = [] # top_groups_name_list_I = [] top_neurons_I,\ top_pos_I,\ top_groups_name_list_I = seed_top_neurons("top_I_", ntype=-1) # total top neurons groups list top_groups_name_list = [] top_groups_name_list.append(list(top_groups_name_list_E)) top_groups_name_list.append(list(top_groups_name_list_I)) top_groups_name_list = top_groups_name_list[0] top_neurons = [] top_neurons.append(list(top_neurons_E)) top_neurons.append(list(top_neurons_I)) top_neurons = top_neurons[0] # Establishment of the connectivity # scales for the connectivity distance function. top_scale = 200. # between top neurons bottom_scale = 100. # between bottom neurons mixed_scale = 150. # between top and bottom neurons both ways print("\n----------\n Connectivity") print("top neurons connectivity characteristic distance {0}".format( top_scale)) print("bottom neurons connectivity characteristic distance {0}".format( bottom_scale)) print("mixed neurons connectivity characteristic distance {0}".format( mixed_scale)) # base connectivity probability base_proba = 3. p_up = 0.6 # modulation for connection bottom to top p_down = 0.9 # modulation for connection top to bottom p_other_up = p_down**2 # modulation connection top to top at the bottom print("Connectivity basic probability {0}".format(base_proba)) print("Up connexion probability on one shape {0}".format(p_up)) print("Down connexion probability {0}".format(p_down)) print("Between two different up shapes connexion probability {0}".format( p_other_up)) # connect neurons in bottom areas print("\nConnect bottom areas") def connect_bottom(neurons_out, pos_out, neurons_in, pos_in, scale=bottom_scale, max_proba=base_proba): ''' Connect bottom neurons connections are only established within continuously connected areas ''' for name, area in shape.default_areas.items(): contained = area.contains_neurons(pos_out) neurons_o = neurons_out[contained] #print("Neurons out: {}".format(neurons_o)) contained = area.contains_neurons(pos_in) neurons_i = neurons_in[contained] #print("Neurons in: {}".format(neurons_i)) nngt.generation.connect_nodes(net, neurons_o, neurons_i, "distance_rule", scale=scale, max_proba=max_proba) # Connect bottom excitatory to bottom excitatory print("Connect bottom E -> bottom E") connect_bottom(bottom_neurons_E, bottom_pos_E, bottom_neurons_E, bottom_pos_E) # Connect bottom excitatory to bottom inhibitory print("Connect bottom E -> bottom I") connect_bottom(bottom_neurons_E, bottom_pos_E, bottom_neurons_I, bottom_pos_I) # Connect bottom inhibitory to bottom excitatory print("Connect bottom I -> bottom E") connect_bottom(bottom_neurons_I, bottom_pos_I, bottom_neurons_E, bottom_pos_E) # Connect bottom inhibitory to bottom inhibitory print("Connect bottom I -> bottom I") connect_bottom(bottom_neurons_I, bottom_pos_I, bottom_neurons_I, bottom_pos_I) # connect top areas print("\nConnect top to top") def connect_top(top_pos_out, top_neurons_out, top_pos_in, top_neurons_in): '''Connect top areas''' for name, area in shape.non_default_areas.items(): print("Connexion out of : {}".format(name)) contained = area.contains_neurons(top_pos_out) neurons_o = top_neurons_out[contained] print("Neurons out: {}".format(neurons_o)) contained = area.contains_neurons(top_pos_in) neurons_i = top_neurons_in[contained] print("Neurons in: {}".format(neurons_i)) other_top_in = [n for n in top_neurons_in if n not in neurons_i] #print("other_top_in: {}".format(other_top_in)) OO = other_top_in # other_top_in is not as vriable name recognized below !! if np.any(neurons_o): # connect intra-area nngt.generation.connect_nodes(net, neurons_o, neurons_i, "distance_rule", scale=top_scale, max_proba=base_proba) # connect between top areas (do it?) # These are connection between top neurons seeded on # different obstacles. Occur probably at the bottom, when # both neurons' neurites descended. nngt.generation.connect_nodes(net, neurons_o, OO, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_other_up) # Connect top excitatory to top excitatory print("Connect top E -> top E") connect_top(top_pos_E, top_neurons_E, top_pos_E, top_neurons_E) # Connect top excitatory to top inhibitory print("Connect top E -> top I") connect_top(top_pos_E, top_neurons_E, top_pos_I, top_neurons_I) # Connect top inhibotory to top excitatory print("Connect top I -> top E") connect_top(top_pos_I, top_neurons_I, top_pos_E, top_neurons_E) # Connect top inhibitory to top inhibitory print("Connect top I -> top I") connect_top(top_pos_I, top_neurons_I, top_pos_I, top_neurons_I) # Connect bottom neurons and top neurons print("Connect top and bottom") def connect_top_bottom(top_pos, top_neurons, bottom_neurons): '''Connect top and bottom areas''' for name, area in shape.non_default_areas.items(): contained = area.contains_neurons(top_pos) neurons_top = top_neurons[contained] print(name) # print(neurons) if np.any(neurons_top): # connect intra-area # connect the area top neurons to bottom and vice versa # Connect top to bottom excitatory nngt.generation.connect_nodes(net, neurons_top, bottom_neurons, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_down) # Connect bottom to top nngt.generation.connect_nodes(net, bottom_neurons, neurons_top, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_up) # Connect top excitatory to bottom excitatory print("Connect top E -> bottom E") connect_top_bottom(top_pos_E, top_neurons_E, bottom_neurons_E) # Connect top excitatory to bottom inhibitory print("\nConnect top E -> bottom I") connect_top_bottom(top_pos_E, top_neurons_E, bottom_neurons_I) # Connect top inhibitory to bottom excitatory print("\nConnect top I -> bottom E") connect_top_bottom(top_pos_I, top_neurons_I, bottom_neurons_E) # Connect top inhibitory to bottom inhibitory print("\nConnect top I -> bottom I") connect_top_bottom(top_pos_I, top_neurons_I, bottom_neurons_I) # By default synapses are static in net # Here we set the synaptic weigth net.set_weights(synaptic_weigth) # Graphs output # Define the list of connectivity maps to be plotted # each tuple of the list contains a list with the groups names of # neurons for outgoing links and a list of the groups containing # the neurons towards which the source neurons connect. # #restrict = [(top_groups_name_list_E, top_groups_name_list_E)] restrict = [(top_groups_name_list_E, top_groups_name_list_E), ("bottom_E", top_groups_name_list_E), (top_groups_name_list_E, "bottom_E"), ("bottom_E", "bottom_E")] output_graphs(net, top_neurons, bottom_neurons, restrict, "Top neurons", "Bottom neurons") # Simulate with NEST activity_simulation(net, pop, sim_duration)
def with_obstacles(shape, params={ "height": 250., "width": 250. }, filling_fraction=0.4): ''' Network generation and simulation with obsactles ------------------------------------------------ Input : shape : nngt defined spatial shape params : dictionary with obstacles specifications filling_fraction : float, fraction of the embedding shape filled with obstacles Output: nngt network of neurons ''' ''' Create obstacles within the shape''' shape.random_obstacles(filling_fraction, form="rectangle", params=params, heights=30., etching=20.) ''' Create a Spatial network and seed neurons on top/bottom areas ''' # neurons are reparted proportionaly to the area total_area = shape.area bottom_area = np.sum([a.area for a in shape.default_areas.values()]) num_bottom = int(density * bottom_area) # compute number of neurons in each top obstacle according to its area num_top_list = [] # list for the number of neurons on each top obsatacle num_top_total = 0 # count tiotal number of neurons in top obstacles for name, top_area in shape.non_default_areas.items(): num_top = int(density * top_area.area) num_top_list.append(num_top) num_top_total += num_top num_neurons = num_bottom + num_top_total # Total number of neurons print("Total number of neurons : {0}".format(num_neurons)) print("Bottom neurons : {0}".format(num_bottom)) print("Top neurons : {0}".format(num_top_total)) pop = nngt.NeuralPop(num_neurons, with_model=True) # # Instruction si on ne veut pas de modèle # pop.set_model(None) pop.create_group("bottom", num_bottom, neuron_model="aeif_psc_alpha", neuron_param=params1) # Create one group on each top area for num_top, (name, top_area) in zip(num_top_list, shape.non_default_areas.items()): # num_top = int(density * top_area.area) group_name = "top_" + name if num_top: pop.create_group(group_name, num_top, neuron_model="aeif_psc_alpha", neuron_param=params1) # make the graph net = nngt.SpatialGraph(shape=shape, population=pop) # seed neurons bottom_pos = shape.seed_neurons(num_bottom, on_area=shape.default_areas, soma_radius=15) bottom_neurons = np.array(net.new_node(num_bottom, positions=bottom_pos, groups="bottom"), dtype=int) top_pos = [] top_neurons = [] top_groups_name_list = [] for name, top_area in shape.non_default_areas.items(): group_name = "top_" + name if group_name in pop: num_top = pop[group_name].size # number of neurons in top group # locate num_top neurons in the group area top_pos_tmp = top_area.seed_neurons(num_top, soma_radius=15) top_pos.extend(top_pos_tmp) top_neurons.extend( net.new_node(num_top, positions=top_pos_tmp, groups=group_name)) top_groups_name_list.append(group_name) top_pos = np.array(top_pos) top_neurons = np.array(top_neurons, dtype=int) # Establishment of the connectivity # scales for the connectivity distance function. top_scale = 200. # between top neurons bottom_scale = 100. # between bottom neurons mixed_scale = 150. # between top and bottom neurons both ways print("\n----------\n Connectivity") print("top neurons connectivity characteristic distance {0}".format( top_scale)) print("bottom neurons connectivity characteristic distance {0}".format( bottom_scale)) print("mixed neurons connectivity characteristic distance {0}".format( mixed_scale)) # base connectivity probability base_proba = 3. p_up = 0.6 p_down = 0.9 p_other_up = p_down**2 print("Connectivity basic probability {0}".format(base_proba)) print("Up connexion probability on one shape {0}".format(p_up)) print("Down connexion probability {0}".format(p_down)) print("Between two different up shapes connexion probability {0}".format( p_other_up)) # connect bottom area for name, area in shape.default_areas.items(): contained = area.contains_neurons(bottom_pos) neurons = bottom_neurons[contained] # 2018 03 51 I think the use of "bottom_neurons" below is erroneous # it should be "neurons" as defined above, the neurons in the contained # area. # Indeed shape.default_areas.items() is a list with diferent disjoint # we want to prevent connections between non communicating areas # at the bottom bottom areas # nngt.generation.connect_nodes(net, bottom_neurons, bottom_neurons, # "distance_rule", scale=bottom_scale, # max_proba=base_proba) nngt.generation.connect_nodes(net, neurons, neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) # connect top areas print("Connect top areas") for name, area in shape.non_default_areas.items(): contained = area.contains_neurons(top_pos) neurons = top_neurons[contained] other_top = [n for n in top_neurons if n not in neurons] print(name) # print(neurons) if np.any(neurons): # connect intra-area nngt.generation.connect_nodes(net, neurons, neurons, "distance_rule", scale=top_scale, max_proba=base_proba) # connect between top areas (do it?) nngt.generation.connect_nodes(net, neurons, other_top, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_other_up) # connect top to bottom nngt.generation.connect_nodes(net, neurons, bottom_neurons, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_down) # connect bottom to top nngt.generation.connect_nodes(net, bottom_neurons, neurons, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_up) # By default synapses are static in net # Here we set the synaptic weigth net.set_weights(synaptic_weigth) # Graphs output # Define the list of connectivity maps to be plotted # each tuple of the list contains a list with the groups names of # neurons for outgoing links and a list of the groups containing # the neurons towards which the ource neurons connect. # restrict = [(top_groups_name_list, top_groups_name_list), ("bottom", top_groups_name_list), (top_groups_name_list, "bottom"), ("bottom", "bottom")] output_graphs(net, top_neurons, bottom_neurons, restrict, "Top neurons", "Bottom neurons") # Simulate with NEST activity_simulation(net, pop, sim_duration)
def no_obstacles(shape): ''' Network generation and simulation without obsacles Input: shape : nngt spatial shape object to embed the neurons Output: net : nngt network ''' ''' Create a Spatial network and seed neurons on top/bottom areas ''' # neurons are reparted proportionaly to the area total_area = shape.area pop = nngt.NeuralPop(num_neurons, with_model=True) # # Instruction si on ne veut pas de modèle # pop.set_model(None) pop.create_group("excitatory", num_excitatory, neuron_model="aeif_psc_alpha", neuron_param=params1) pop.create_group("inhibitory", num_inhibitory, neuron_model="aeif_psc_alpha", neuron_param=params1) # make the graph net = nngt.SpatialGraph(shape=shape, population=pop) # seed neurons excitatory_pos = shape.seed_neurons(num_excitatory, on_area=shape.default_areas, soma_radius=15) excitatory_neurons = np.array(net.new_node(num_excitatory, positions=excitatory_pos, groups="excitatory"), dtype=int) inhibitory_pos = shape.seed_neurons(num_inhibitory, on_area=shape.non_default_areas, soma_radius=15) inhibitory_neurons = np.array(net.new_node(num_inhibitory, positions=inhibitory_pos, groups="inhibitory", ntype=-1), dtype=int) ''' Make the connectivity ''' #top_scale = 200. bottom_scale = 100. #mixed_scale = 150. base_proba = 3. p_up = 0.6 p_down = 0.9 p_other_up = p_down**2 # connect bottom area for name, area in shape.default_areas.items(): # non_default_areas.items() >>.default_areas.items() contained = area.contains_neurons(excitatory_pos) neurons = excitatory_neurons[contained] nngt.generation.connect_nodes(net, excitatory_neurons, excitatory_neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) nngt.generation.connect_nodes(net, excitatory_neurons, inhibitory_neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) nngt.generation.connect_nodes(net, inhibitory_neurons, inhibitory_neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) nngt.generation.connect_nodes(net, inhibitory_neurons, excitatory_neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) # By default synapses are static in net # Here we set the synaptic weigth net.set_weights(50.0) if plot_distribution is True: ''' Check the degree distribution ''' nngt.plot.degree_distribution(net, ["in", "out"], num_bins='bayes', nodes=inhibitory_neurons, show=False) nngt.plot.degree_distribution(net, ["in", "out"], num_bins='bayes', nodes=excitatory_neurons, show=True) if plot_graphs is True: ''' Plot the resulting network and subnetworks ''' restrict = [("excitatory", "excitatory"), ("inhibitory", "excitatory"), ("inhibitory", "inhibitory"), ("excitatory", "inhibitory")] for r_source, r_target in restrict: nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, restrict_sources=r_source, restrict_targets=r_target, show=False) fig, axis = plt.subplots() count = 0 for r_source, r_target in restrict: show_env = (count == 0) nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, restrict_sources=r_source, restrict_targets=r_target, show_environment=show_env, axis=axis, show=False) count += 1 # ~ nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, show=True) # ------------------ # # Simulate with NEST # # ------------------ # if simulate_activity is True: print("Activity simulation") ''' Send the network to NEST, monitor and simulate ''' activity_simulation(net, pop)
def with_obstacles(shape, params={ "height": 250., "width": 250. }, filling_fraction=0.4): ''' Network generation and simulation with obsactles ------------------------------------------------ Input : shape : nngt defined spatial shape params : dictionary with obstacles specifications filling_fraction : float, fraction of the embedding shape filled with obstacles Output: nngt network of neurons ''' ''' Create obstacles within the shape''' shape.random_obstacles(filling_fraction, form="rectangle", params=params, heights=30., etching=20.) ''' Create a Spatial network and seed neurons on top/bottom areas ''' # neurons are reparted proportionaly to the area total_area = shape.area bottom_area = np.sum([a.area for a in shape.default_areas.values()]) density = 300e-6 num_bottom = int(density * bottom_area) pop = nngt.NeuralPop(num_neurons, with_model=True) # # Instruction si on ne veut pas de modèle # pop.set_model(None) pop.create_group("bottom", num_bottom, neuron_model="aeif_psc_alpha", neuron_param=params1) # Create one group on each top area for name, top_area in shape.non_default_areas.items(): num_top = int(density * top_area.area) group_name = "top_" + name if num_top: pop.create_group(group_name, num_top, neuron_model="aeif_psc_alpha", neuron_param=params1) # make the graph net = nngt.SpatialGraph(shape=shape, population=pop) # seed neurons bottom_pos = shape.seed_neurons(num_bottom, on_area=shape.default_areas, soma_radius=15) bottom_neurons = np.array(net.new_node(num_bottom, positions=bottom_pos, groups="bottom"), dtype=int) top_pos = [] top_neurons = [] for name, top_area in shape.non_default_areas.items(): group_name = "top_" + name if group_name in pop: num_top = pop[group_name].size top_pos_tmp = top_area.seed_neurons(num_top, soma_radius=15) top_pos.extend(top_pos_tmp) top_neurons.extend( net.new_node(num_top, positions=top_pos_tmp, groups=group_name)) top_pos = np.array(top_pos) top_neurons = np.array(top_neurons, dtype=int) ''' Make the connectivity ''' top_scale = 200. bottom_scale = 100. mixed_scale = 150. base_proba = 3. p_up = 0.6 p_down = 0.9 p_other_up = p_down**2 # connect bottom area for name, area in shape.default_areas.items(): # non_default_areas.items() >>.default_areas.items() contained = area.contains_neurons(bottom_pos) neurons = bottom_neurons[contained] nngt.generation.connect_nodes(net, bottom_neurons, bottom_neurons, "distance_rule", scale=bottom_scale, max_proba=base_proba) # connect top areas for name, area in shape.non_default_areas.items(): contained = area.contains_neurons(top_pos) neurons = top_neurons[contained] other_top = [n for n in top_neurons if n not in neurons] print(name) #print(neurons) if np.any(neurons): # connect intra-area nngt.generation.connect_nodes(net, neurons, neurons, "distance_rule", scale=top_scale, max_proba=base_proba) # connect between top areas (do it?) nngt.generation.connect_nodes(net, neurons, other_top, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_other_up) # connect top to bottom nngt.generation.connect_nodes(net, neurons, bottom_neurons, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_down) # connect bottom to top nngt.generation.connect_nodes(net, bottom_neurons, neurons, "distance_rule", scale=mixed_scale, max_proba=base_proba * p_up) # By default synapses are static in net # Here we set the synaptic weigth net.set_weights(80.0) if plot_distribution is True: ''' Check the degree distribution ''' nngt.plot.degree_distribution(net, ["in", "out"], num_bins='bayes', nodes=top_neurons, show=False) nngt.plot.degree_distribution(net, ["in", "out"], num_bins='bayes', nodes=bottom_neurons, show=True) if plot_graphs is True: ''' Plot the resulting network and subnetworks ''' restrict = [("bottom", "bottom"), ("top", "bottom"), ("top", "top"), ("bottom", "top")] for r_source, r_target in restrict: nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, restrict_sources=r_source, restrict_targets=r_target, show=False) fig, axis = plt.subplots() count = 0 for r_source, r_target in restrict: show_env = (count == 0) nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, restrict_sources=r_source, restrict_targets=r_target, show_environment=show_env, axis=axis, show=False) count += 1 # ~ nngt.plot.draw_network(net, nsize=7.5, ecolor="groups", ealpha=0.5, show=True) # ------------------ # # Simulate with NEST # # ------------------ # if simulate_activity is True: print("Activity simulation") ''' Send the network to NEST, monitor and simulate ''' activity_simulation(net, pop)