コード例 #1
0
 def test_position_generator(self):
     n_neurons = 5
     label = "pop_1"
     sim.setup(timestep=1.0)
     pop_1 = sim.Population(n_neurons, sim.IF_curr_exp(), label=label,
                            structure=RandomStructure(Sphere(5.0)))
     try:
         gen = pop_1.position_generator
         print(gen(0))
     except NotImplementedError:
         msg = "Depends on https://github.com/SpiNNakerManchester" \
               "/sPyNNaker8/pull/73"
         raise SkipTest(msg)
     sim.end()
コード例 #2
0
def scenario4(sim):
    """
    Network with spatial structure
    """
    init_logging(logfile=None, debug=True)
    sim.setup()
    rng = NumpyRNG(seed=76454, parallel_safe=False)

    input_layout = RandomStructure(boundary=Cuboid(width=500.0, height=500.0, depth=100.0),
                                   origin=(0, 0, 0), rng=rng)
    inputs = sim.Population(100, sim.SpikeSourcePoisson(rate=RandomDistribution('uniform', [3.0, 7.0], rng=rng)),
                            structure=input_layout, label="inputs")
    output_layout = Grid3D(aspect_ratioXY=1.0, aspect_ratioXZ=5.0, dx=10.0, dy=10.0, dz=10.0,
                           x0=0.0, y0=0.0, z0=200.0)
    outputs = sim.Population(200, sim.EIF_cond_exp_isfa_ista(),
                             initial_values = {'v': RandomDistribution('normal', [-65.0, 5.0], rng=rng),
                                               'w': RandomDistribution('normal', [0.0, 1.0], rng=rng)},
                             structure=output_layout, # 10x10x2 grid
                             label="outputs")
    logger.debug("Output population positions:\n %s", outputs.positions)
    DDPC = sim.DistanceDependentProbabilityConnector
    input_connectivity = DDPC("0.5*exp(-d/100.0)", rng=rng)
    recurrent_connectivity = DDPC("sin(pi*d/250.0)**2", rng=rng)
    depressing = sim.TsodyksMarkramSynapse(weight=RandomDistribution('normal', (0.1, 0.02), rng=rng),
                                           delay="0.5 + d/100.0",
                                           U=0.5, tau_rec=800.0, tau_facil=0.0)
    facilitating = sim.TsodyksMarkramSynapse(weight=0.05,
                                             delay="0.2 + d/100.0",
                                             U=0.04, tau_rec=100.0,
                                             tau_facil=1000.0)
    input_connections = sim.Projection(inputs, outputs, input_connectivity,
                                       receptor_type='excitatory',
                                       synapse_type=depressing,
                                       space=Space(axes='xy'),
                                       label="input connections")
    recurrent_connections = sim.Projection(outputs, outputs, recurrent_connectivity,
                                           receptor_type='inhibitory',
                                           synapse_type=facilitating,
                                           space=Space(periodic_boundaries=((-100.0, 100.0), (-100.0, 100.0), None)), # should add "calculate_boundaries" method to Structure classes
                                           label="recurrent connections")
    outputs.record('spikes')
    outputs.sample(10, rng=rng).record('v')
    sim.run(1000.0)
    data = outputs.get_data()
    sim.end()
    return data
def runNetwork(Be, 
               Bi, 
               nn_stim, 
               show_gui=True,
               dt = defaultParams.dt, 
               N_rec_v = 5, 
               save=False, 
               simtime = defaultParams.Tpost+defaultParams.Tstim+defaultParams.Tblank+defaultParams.Ttrans, 
               extra = {},
               kernelseed = 123):
    
    exec("from pyNN.%s import *" % simulator_name) in globals()
    
    timer = Timer()

    rec_conn={'EtoE':1, 'EtoI':1, 'ItoE':1, 'ItoI':1}

    print('####################')
    print('### (Be, Bi, nn_stim): ', Be, Bi, nn_stim)
    print('####################')

    Bee, Bei = Be, Be
    Bie, Bii = Bi, Bi

    N = defaultParams.N
    NE = defaultParams.NE
    NI = defaultParams.NI

    print('\n # -----> Num cells: %s, size of pert. inh: %s; base rate %s; pert rate %s'% (N, nn_stim, defaultParams.r_bkg, defaultParams.r_stim))

    r_extra = np.zeros(N)
    r_extra[NE:NE+nn_stim] = defaultParams.r_stim

    rr1 = defaultParams.r_bkg*np.random.uniform(.75,1.25, N)
    rr2 = rr1 + r_extra
    
    rank = setup(timestep=dt, max_delay=defaultParams.delay_default, reference='ISN', save_format='hdf5', **extra)
    
    print("rank =", rank)
    nump = num_processes()
    print("num_processes =", nump)
    import socket
    host_name = socket.gethostname()
    print("Host #%d is on %s" % (rank+1, host_name))

    if 'threads' in extra:
        print("%d Initialising the simulator with %d threads..." % (rank, extra['threads']))
    else:
        print("%d Initialising the simulator with single thread..." % rank)
        
        
    timer.start()  # start timer on construction
    
    print("%d Setting up random number generator using seed %s" % (rank, kernelseed))
    
    ks = open('kernelseed','w')
    ks.write('%i'%kernelseed)
    ks.close()
    
    rng = NumpyRNG(kernelseed, parallel_safe=True)
    
    
    nesp = defaultParams.neuron_params_default
    cell_parameters = {
        'cm':         nesp['C_m']/1000,   # Capacitance of the membrane in nF
        'tau_refrac': nesp['t_ref'],     # Duration of refractory period in ms.
        'v_spike':    0.0 ,     # Spike detection threshold in mV.   https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp
        'v_reset':    nesp['V_reset'],     # Reset value for V_m after a spike. In mV.
        'v_rest':     nesp['E_L'],     # Resting membrane potential (Leak reversal potential) in mV.
        'tau_m':      nesp['C_m']/nesp['g_L'],  # Membrane time constant in ms = cm/tau_m*1000.0, C_m/g_L
        'i_offset':   nesp['I_e']/1000,     # Offset current in nA
        'a':          0,     # Subthreshold adaptation conductance in nS.
        'b':          0,  # Spike-triggered adaptation in nA
        'delta_T':    2 ,     # Slope factor in mV. See https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp
        'tau_w':      144.0,     # Adaptation time constant in ms. See https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp
        'v_thresh':   nesp['V_th'],     # Spike initiation threshold in mV
        'e_rev_E':    nesp['E_ex'],     # Excitatory reversal potential in mV.
        'tau_syn_E':  nesp['tau_syn_ex'],     # Rise time of excitatory synaptic conductance in ms (alpha function).
        'e_rev_I':    nesp['E_in'],     # Inhibitory reversal potential in mV.
        'tau_syn_I':  nesp['tau_syn_in'],     # Rise time of the inhibitory synaptic conductance in ms (alpha function).
    }

    print("%d Creating population with %d neurons." % (rank, N))
    celltype = EIF_cond_alpha_isfa_ista(**cell_parameters)
    celltype.default_initial_values['v'] = cell_parameters['v_rest'] # Setting default init v, useful for NML2 export
    
    layer_volume = Cuboid(1000,100,1000)
    layer_structure = RandomStructure(layer_volume, origin=(0,0,0))
    
    layer_structure_input = RandomStructure(layer_volume, origin=(0,-150,0))
             
    default_cell_radius = 15
    stim_cell_radius = 10
    
    #EI_pop = Population(N, celltype, structure=layer_structure, label="EI")
    E_pop = Population(NE, celltype, structure=layer_structure, label='E_pop')
    E_pop.annotate(color='1 0 0')
    E_pop.annotate(radius=default_cell_radius)
    E_pop.annotate(type='E') # temp indicator to use for connection arrowhead
    #print("%d Creating pop %s." % (rank, E_pop))
    I_pop = Population(NI, celltype, structure=layer_structure, label='I_pop')
    I_pop.annotate(color='0 0 .9')
    I_pop.annotate(radius=default_cell_radius)
    I_pop.annotate(type='I') # temp indicator to use for connection arrowhead
    #print("%d Creating pop %s." % (rank, I_pop))
    
    I_pert_pop = PopulationView(I_pop, np.array(range(0,nn_stim)),label='I_pert_pop')
    I_nonpert_pop = PopulationView(I_pop, np.array(range(nn_stim,NI)),label='I_nonpert_pop')
    
    p_rate = defaultParams.r_bkg
    print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate))
    source_typeA_E = SpikeSourcePoisson(rate=p_rate, start=0,duration=defaultParams.Ttrans+defaultParams.Tblank+defaultParams.Tstim+defaultParams.Tpost)
    expoissonA_E = Population(NE, source_typeA_E, structure=layer_structure_input, label="stim_E")
    
    print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate))
    source_typeA_I = SpikeSourcePoisson(rate=p_rate, start=0,duration=defaultParams.Ttrans+defaultParams.Tblank)
    expoissonA_I = Population(NI, source_typeA_I, structure=layer_structure_input, label="pre_pert_stim_I")
    
    print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate))
    source_typeB = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank,duration=defaultParams.Tstim+defaultParams.Tpost)
    #expoissonB_E = Population(NE, source_typeB, label="non_pert_stim_E")
    expoissonB_I = Population(len(I_nonpert_pop), source_typeB, structure=layer_structure_input, label="non_pert_stim_I")
    
    p_rate = defaultParams.r_bkg+defaultParams.r_stim
    print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate))
    source_typeC = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank, duration=defaultParams.Tstim)
    expoissonC = Population(nn_stim, source_typeC, structure=layer_structure_input, label="pert_stim")

    p_rate = defaultParams.r_bkg
    print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate))
    source_typeD = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank+defaultParams.Tstim, duration=defaultParams.Tpost)
    expoissonD = Population(nn_stim, source_typeD, structure=layer_structure_input, label="pert_poststim")
    
    for p in [expoissonA_E,expoissonA_I,expoissonB_I,expoissonC,expoissonD]:
        p.annotate(color='0.8 0.8 0.8')
        p.annotate(radius=stim_cell_radius)

    progress_bar = ProgressBar(width=20)
    connector_E = FixedProbabilityConnector(0.15, rng=rng, callback=progress_bar)
    connector_I = FixedProbabilityConnector(1, rng=rng, callback=progress_bar)
    
    EE_syn = StaticSynapse(weight=0.001*Bee, delay=defaultParams.delay_default)
    EI_syn = StaticSynapse(weight=0.001*Bei, delay=defaultParams.delay_default)
    II_syn = StaticSynapse(weight=0.001*Bii, delay=defaultParams.delay_default)
    IE_syn = StaticSynapse(weight=0.001*Bie, delay=defaultParams.delay_default)
    
    #I_syn = StaticSynapse(weight=JI, delay=delay)
    ext_Connector = OneToOneConnector(callback=progress_bar)
    ext_syn_bkg = StaticSynapse(weight=0.001*defaultParams.Be_bkg, delay=defaultParams.delay_default)
    ext_syn_stim = StaticSynapse(weight=0.001*defaultParams.Be_stim, delay=defaultParams.delay_default)
    
    
    E_to_E = Projection(E_pop, E_pop, connector_E, EE_syn, receptor_type="excitatory")
    print("E --> E\t\t", len(E_to_E), "connections")
    E_to_I = Projection(E_pop, I_pop, connector_E, EI_syn, receptor_type="excitatory")
    print("E --> I\t\t", len(E_to_I), "connections")
    I_to_I = Projection(I_pop, I_pop, connector_I, II_syn, receptor_type="inhibitory")
    print("I --> I\t\t", len(I_to_I), "connections")
    I_to_E = Projection(I_pop, E_pop, connector_I, IE_syn, receptor_type="inhibitory")
    print("I --> E\t\t", len(I_to_E), "connections")
    
    
    input_A_E = Projection(expoissonA_E, E_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory")
    print("input --> %s cells pre pert\t"%len(E_pop), len(input_A_E), "connections")
    input_A_I = Projection(expoissonA_I, I_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory")
    print("input --> %s cells pre pert\t"%len(I_pop), len(input_A_I), "connections")
    
    ##input_B_E = Projection(expoissonB_E, E_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory")
    ##print("input --> %s cells post pert\t"%len(E_pop), len(input_B_E), "connections")
    
    input_B_I = Projection(expoissonB_I, I_nonpert_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory")
    print("input --> %s cells post pert\t"%len(I_nonpert_pop), len(input_B_I), "connections")
    
    
    input_C = Projection(expoissonC, I_pert_pop, ext_Connector, ext_syn_stim, receptor_type="excitatory")
    print("input --> %s cells pre pert\t"%len(I_pert_pop), len(input_C), "connections")
    
    input_D = Projection(expoissonD, I_pert_pop, ext_Connector, ext_syn_stim, receptor_type="excitatory")
    print("input --> %s cells pre pert\t"%len(I_pert_pop), len(input_D), "connections")
    
    # Can't be used for connections etc. as NeuroML export not (yet) supported
    EI_pop = Assembly(E_pop, I_pop, label='EI')
    
    # Record spikes
    print("%d Setting up recording in excitatory population." % rank)
    EI_pop.record('spikes')
    if N_rec_v>0:
        EI_pop[0:min(N,N_rec_v)].record('v')
    
    
    # read out time used for building
    buildCPUTime = timer.elapsedTime()
    # === Run simulation ===========================================================

    # run, measure computer time
    timer.start()  # start timer on construction
    print("%d Running simulation in %s for %g ms (dt=%sms)." % (rank, simulator_name, simtime, dt))
    run(simtime)
    print("Done")
    simCPUTime = timer.elapsedTime()
    
    # write data to file
    if save and not simulator_name=='neuroml':
        for pop in [EI_pop]:
            filename="ISN-%s-%s-%i.gdf"%(simulator_name, pop.label, rank)
            ff = open(filename, 'w')
            spikes =  pop.get_data('spikes', gather=False)
            spiketrains = spikes.segments[0].spiketrains
            print('Saving data recorded for %i spiketrains in pop %s, indices: %s, ids: %s to %s'% \
                (len(spiketrains),
                 pop.label, 
                 [s.annotations['source_index'] for s in spiketrains], 
                 [s.annotations['source_id'] for s in spiketrains], 
                 filename))
                 
            for spiketrain_i in range(len(spiketrains)):
                spiketrain = spiketrains[spiketrain_i]
                source_id = spiketrain.annotations['source_id']
                source_index = spiketrain.annotations['source_index']
                #print("Writing spike data for cell %s[%s] (gid: %i): %i spikes: [%s,...,%s] "%(pop.label,source_index, source_id, len(spiketrain),spiketrain[0],spiketrain[-1]))
                for t in spiketrain:
                    ff.write('%s\t%i\n'%(t.magnitude,spiketrain_i))
            ff.close()
                
            vs =  pop.get_data('v', gather=False)
            for segment in vs.segments:
                for i in range(len(segment.analogsignals[0].transpose())):
                    filename="ISN-%s-%s-cell%i.dat"%(simulator_name, pop.label, i)
                    print('Saving cell %i in %s to %s'%(i,pop.label,filename))
                    vm = segment.analogsignals[0].transpose()[i]
                    tt = np.array([t*dt/1000. for t in range(len(vm))])
                    times_vm = np.array([tt, vm/1000.]).transpose()
                    np.savetxt(filename, times_vm , delimiter = '\t', fmt='%s')
            
    spike_data = {}
    spike_data['senders'] = []
    spike_data['times'] = []
    index_offset = 1
    for pop in [EI_pop]:
        if rank == 0:
            spikes =  pop.get_data('spikes', gather=False)
            #print(spikes.segments[0].all_data)
            num_rec = len(spikes.segments[0].spiketrains)
            print("Extracting spike info (%i) for %i cells in %s"%(num_rec,pop.size,pop.label))
            #assert(num_rec==len(spikes.segments[0].spiketrains))
            for i in range(num_rec):
                ss = spikes.segments[0].spiketrains[i]
                for s in ss:
                    index = i+index_offset
                    #print("Adding spike at %s in %s[%i] (cell %i)"%(s,pop.label,i,index))
                    spike_data['senders'].append(index)
                    spike_data['times'].append(s)
            index_offset+=pop.size


    print("Build time         : %g s" % buildCPUTime)
    print("Simulation time    : %g s" % simCPUTime)

    # === Clean up and quit ========================================================

    end()
コード例 #4
0
cortical_type = EIF_cond_exp_isfa_ista(**ctx_parameters)

# names and default
IF_cond_exp.get_parameter_names()
print(IF_cond_exp.default_parameters)
'''
populations
'''
#tec_cells=create(thalamocortical_type,n=100)
#tc_cells = Population(100, thalamocortical_type)
#ctx_cells = Population(500, cortical_type)

from pyNN.space import Grid2D, RandomStructure, Sphere
tc_cells = Population(100,
                      thalamocortical_type,
                      structure=RandomStructure(boundary=Sphere(radius=200.0)),
                      initial_values={'v': -70.0},
                      label="Thalamocortical neurons")
from pyNN.random import RandomDistribution
v_init = RandomDistribution('uniform', (-70.0, -60.0))
ctx_cells = Population(500,
                       cortical_type,
                       structure=Grid2D(dx=10.0, dy=10.0),
                       initial_values={'v': v_init},
                       label="Cortical neurons")
'''
view
'''
id = ctx_cells[47]  # the 48th neuron in a Population
view = ctx_cells[:80]  # the first eighty neurons
view = ctx_cells[::2]  # every second neuron
コード例 #5
0
    def setup(self, sim) :
        # Create matrix of synaptic weights
        self.w = create_weight_matrix()
        model = getattr(sim, 'IF_curr_exp')
        script_rng = NumpyRNG(seed=6508015, parallel_safe=parallel_safe)
        distr = RandomDistribution('normal', [V0_mean, V0_sd], rng=script_rng)

        # Create cortical populations
        self.pops = {}
        layer_structures = {}
        total_cells = 0 
        
        x_dim_scaled = x_dimension * math.sqrt(N_scaling)
        z_dim_scaled = z_dimension * math.sqrt(N_scaling)
        
        default_cell_radius = 10 # for visualisation 
        default_input_radius = 5 # for visualisation 
        
        for layer in layers:
            self.pops[layer] = {}
            for pop in pops:
                
                y_offset = 0
                if layer == 'L6': y_offset = layer_thicknesses['L6']/2
                if layer == 'L5': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']/2
                if layer == 'L4': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']+layer_thicknesses['L4']/2
                if layer == 'L23': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']+layer_thicknesses['L4']+layer_thicknesses['L23']/2
                
                layer_volume = Cuboid(x_dim_scaled,layer_thicknesses[layer],z_dim_scaled)
                layer_structures[layer] = RandomStructure(layer_volume, origin=(0,y_offset,0))
                
                self.pops[layer][pop] = sim.Population(int(N_full[layer][pop] * \
                    N_scaling), model, cellparams=neuron_params, \
                    structure=layer_structures[layer], label='%s_%s'%(layer,pop))
                    
                    
                self.pops[layer][pop].initialize(v=distr)
                # Store whether population is inhibitory or excitatory
                self.pops[layer][pop].annotate(type=pop)
                
                self.pops[layer][pop].annotate(radius=default_cell_radius)
                self.pops[layer][pop].annotate(structure=str(layer_structures[layer]))
                
                this_pop = self.pops[layer][pop]
                color='0 0 0'
                radius = 10
                try:
                    import opencortex.utils.color as occ
                    if layer == 'L23':
                        if pop=='E': color = occ.L23_PRINCIPAL_CELL
                        if pop=='I': color = occ.L23_INTERNEURON
                    if layer == 'L4':
                        if pop=='E': color = occ.L4_PRINCIPAL_CELL
                        if pop=='I': color = occ.L4_INTERNEURON
                    if layer == 'L5':
                        if pop=='E': color = occ.L5_PRINCIPAL_CELL
                        if pop=='I': color = occ.L5_INTERNEURON
                    if layer == 'L6':
                        if pop=='E': color = occ.L6_PRINCIPAL_CELL
                        if pop=='I': color = occ.L6_INTERNEURON
                            
                    self.pops[layer][pop].annotate(color=color)
                except:
                    # Don't worry about it, it's just metadata
                    pass
                print("Created population %s with %i cells (color: %s)"%(this_pop.label,this_pop.size, color))

                
                total_cells += this_pop.size
                # Spike recording
                if record_fraction:
                    num_spikes = int(round(this_pop.size * frac_record_spikes))
                else:
                    num_spikes = n_record
                this_pop[0:num_spikes].record('spikes')

                # Membrane potential recording
                if record_v:
                    if record_fraction:
                        num_v = int(round(this_pop.size * frac_record_v))

                    else:
                        num_v = n_record_v
                    this_pop[0:num_v].record('v')

        print("Finished creating all cell populations (%i cells)"%total_cells)
        # Create thalamic population
        if thalamic_input:
            
            print("Adding thalamic input")
            layer_volume = Cuboid(x_dimension,layer_thicknesses['thalamus'],z_dimension)
            layer_structure = RandomStructure(layer_volume, origin=(0,thalamus_offset,0))
            self.thalamic_population = sim.Population(
                    thal_params['n_thal'],
                    sim.SpikeSourcePoisson,
                    {'rate': thal_params['rate'],
                     'start': thal_params['start'],
                     'duration': thal_params['duration']},
                     structure=layer_structure,
                     label='thalamic_input')

        # Compute DC input before scaling
        if input_type == 'DC':
            self.DC_amp = {}
            for target_layer in layers:
                self.DC_amp[target_layer] = {}
                for target_pop in pops:
                    self.DC_amp[target_layer][target_pop] = bg_rate * \
                    K_ext[target_layer][target_pop] * w_mean * neuron_params['tau_syn_E'] / 1000.
        else:
            self.DC_amp = {'L23': {'E': 0., 'I': 0.},
                           'L4' : {'E': 0., 'I': 0.},
                           'L5' : {'E': 0., 'I': 0.},
                           'L6' : {'E': 0., 'I': 0.}}

        # Scale and connect

        # In-degrees of the full-scale model
        K_full = scaling.get_indegrees()

        if K_scaling != 1 :
            self.w, self.w_ext, self.K_ext, self.DC_amp = scaling.adjust_w_and_ext_to_K(K_full, K_scaling, self.w, self.DC_amp)
        else:
            self.w_ext = w_ext
            self.K_ext = K_ext

        if sim.rank() == 0:
            print('w: %s' % self.w)
        
        net_generation_rng = NumpyRNG(12345, parallel_safe=True)

        for target_layer in layers :
            for target_pop in pops :
                target_index = structure[target_layer][target_pop]
                this_pop = self.pops[target_layer][target_pop]
                # External inputs
                if input_type == 'DC' or K_scaling != 1 :
                    this_pop.set(i_offset=self.DC_amp[target_layer][target_pop])
                if input_type == 'poisson':
                    poisson_generator = sim.Population(this_pop.size,
                                                       sim.SpikeSourcePoisson, 
                                                       {'rate': bg_rate * self.K_ext[target_layer][target_pop]},
                                                       structure=layer_structures[target_layer],
                                                       label='input_%s_%s'%(target_layer,target_pop))
                                                       
                    poisson_generator.annotate(color='0.5 0.5 0')
                    poisson_generator.annotate(radius=default_input_radius)
                    
                    conn = sim.OneToOneConnector()
                    syn = sim.StaticSynapse(weight=self.w_ext)
                    sim.Projection(poisson_generator, this_pop, conn, syn, receptor_type='excitatory')
                if thalamic_input:
                    # Thalamic inputs
                    if sim.rank() == 0 :
                        print('Creating thalamic connections to %s%s' % (target_layer, target_pop))
                    C_thal=thal_params['C'][target_layer][target_pop]
                    n_target=N_full[target_layer][target_pop]
                    K_thal=round(np.log(1 - C_thal) / np.log((n_target * thal_params['n_thal'] - 1.) /
                             (n_target * thal_params['n_thal']))) / n_target
                    FixedTotalNumberConnect(sim, self.thalamic_population,
                                            this_pop, K_thal, w_ext, w_rel * w_ext,
                                            d_mean['E'], d_sd['E'], rng=net_generation_rng)
                # Recurrent inputs
                for source_layer in layers :
                    for source_pop in pops :
                        source_index=structure[source_layer][source_pop]
                        if sim.rank() == 0:
                            print('Creating connections from %s%s to %s%s' % (source_layer, source_pop, target_layer, target_pop))
                        weight=self.w[target_index][source_index]
                        if source_pop == 'E' and source_layer == 'L4' and target_layer == 'L23' and target_pop == 'E':
                            w_sd=weight * w_rel_234
                        else:
                            w_sd=abs(weight * w_rel)
                        FixedTotalNumberConnect(sim, self.pops[source_layer][source_pop],
                                                self.pops[target_layer][target_pop],\
                                                K_full[target_index][source_index] * K_scaling,
                                                weight, w_sd,
                                                d_mean[source_pop], d_sd[source_pop], rng=net_generation_rng)