Cortical Connections
In the same vein that the post before this one we will show here how to construct the connections between the cortical layers. In order to do so we will construct a function that works in general for any arbitrary connectivity, we describe in the following its structure. First, as in the thalamo-cortical connectivity, we have again the same structure of a function that loops over the target population extracting the relevant parameters that characterize these neurons. Furthermore we have another function that loops over the source population creating the corresponding tuples for the connection list. Is in this last function where the particular connectivity rule is implemented.
In the particular case of the Troyer model the connectivity between the cortical cells is determined by the correlation between the receptive fields of the neurons, the receptive fields here being Gabor functions. In more detail the neurons whose receptive fields are more correlated will be the ones more likely to have excitatory connections between them. On the other hand the ones whose receptive fields are less correlated will be more likely to receive inhibitory connections. In this post we show two schemes that accomplish this connectivity. The first one uses the fact the parameters of the receptive field to calculate a connectivity and the second one uses the receptive fields directly to calculate the correlations. We present the determining functions in the stated order down here.
Now we present the function that creates the connectivity for a given neuron par. The circular distance between the orientation and phases are calculated as a proxy to estimate how similar the receptive fields of the neurons are. After that, the distance between them is weighted and normalized with a normal function in order to obtain a value that we can interpret as a probability value. Finally in order to calculate the connectivity we sample n_pick times with the given probability value to see hwo strong a particular connection should be.
def cortical_to_cortical_connection(target_neuron_index, connections, source_population, n_pick, g, delay, source_orientations, source_phases, orientation_sigma, phase_sigma, target_neuron_orientation, target_neuron_phase, target_type): """ Creates the connections from the source population to the target neuron """ for source_neuron in source_population: # Extract index, orientation and phase of the target source_neuron_index = source_population.id_to_index(source_neuron) source_neuron_orientation = source_orientations[source_neuron_index] source_neuron_phase = source_phases[source_neuron_index] # Now calculate phase and orientation distances or_distance = circular_dist(target_neuron_orientation, source_neuron_orientation, 180) if target_type: phase_distance = circular_dist(target_neuron_phase, source_neuron_phase, 360) else: phase_distance = 180 - circular_dist(target_neuron_phase, source_neuron_phase, 360) # Now calculate the gaussian function or_gauss = normal_function(or_distance, mean=0, sigma=orientation_sigma) phase_gauss = normal_function(phase_distance, mean=0, sigma=phase_sigma) # Now normalize by guassian in zero or_gauss = or_gauss / normal_function(0, mean=0, sigma=orientation_sigma) phase_gauss = phase_gauss / normal_function(0, mean=0, sigma=phase_sigma) # Probability is the product probability = or_gauss * phase_gauss probability = np.sum(np.random.rand(n_pick) < probability) # Samples synaptic_weight = (g / n_pick) * probability if synaptic_weight > 0: connections.append((source_neuron_index, target_neuron_index, synaptic_weight, delay)) return connections
Note that the overall strength is weighted by the conductivity value g that is passed as an argument. Furthermore a delay that is also passed as an argument is added to the list as the last element of the tuple.
Secondly we present the full correlation scheme. In this scheme we utilize the kernels directly to calculate the spatial correlation between them. In particular after we have flattened our kernels Z to have a series instead of a matrix we use the function perasonr from scipy.stats to calculate the correlation. Again as in the case above we use this probability to sample n_pick times and then calculate the relative connectivity strength with this.
def cortical_to_cortical_connection_corr(target_neuron_index, connections, source_population, n_pick, g, delay, source_orientations, source_phases, target_neuron_orientation, target_neuron_phase, Z1, lx, dx, ly, dy, sigma, gamma, w, target_type): """ Creates the connections from the source population to the target neuron """ for source_neuron in source_population: # Extract index, orientation and phase of the target x_source, y_source = source_neuron.position[0:2] source_neuron_index = source_population.id_to_index(source_neuron) source_neuron_orientation = source_orientations[source_neuron_index] source_neuron_phase = source_phases[source_neuron_index] Z2 = gabor_kernel(lx, dx, ly, dy, sigma, gamma, source_neuron_phase, w, source_neuron_orientation, x_source, y_source) if target_type: probability = pearsonr(Z1.flat, Z2.flat)[0] else: probability = (-1) * pearsonr(Z1.flat, Z2.flat)[0] probability = np.sum(np.random.rand(n_pick) < probability) # Samples synaptic_weight = (g / n_pick) * probability if synaptic_weight > 0: connections.append((source_neuron_index, target_neuron_index, synaptic_weight, delay)) return connections
Note that the overall strength is weighted by the conductivity value g that is passed as an argument. Furthermore a delay that is also passed as an argument is added to the list as the last element of the tuple.
We now show how a plot that illustrates how the probabilities change when the parameters that determined the gabor function are changed for each scheme.
In the figure above we have int he upper part how the probability for the first scheme a neuron with phase 0 and orientation 0 change as we vary the phase (left) and orientation (right). In the two graphs bellow we have the same for the second scheme we presented