Exemple #1
0
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
Exemple #2
0
 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)))
Exemple #3
0
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))
Exemple #4
0
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)
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #12
0
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)