Exemple #1
0
    def produce_vm_LFP_correlation(self,
                                   trial=0,
                                   start=600,
                                   duration=1000,
                                   dt=0.1):
        """
        Calculates the correlation between the Vm of the closest neuron to the (first) electrode and the LFP signal
        recorded at this electrode.
        Returns the correlation and the corresponding lag (in ms).
        The relevant data is supposed to be 1s long.
        """
        start_index = int(start / dt)
        duration_index = int(duration / dt)

        vm = self.get_membrane_potential(trial=trial)
        neuron_positions = self.get_positions()

        num_electrodes = self.electrode_positions.shape[0]
        inv_dist = nf.electrode_neuron_inv_dist(num_electrodes,
                                                self.num_neurons,
                                                self.electrode_positions,
                                                neuron_positions, self.reach,
                                                self.dimensionnality)[0, :]
        closest_neuron = np.argmax(inv_dist)
        selected_vm = np.reshape(
            vm[start_index:start_index + duration_index + 1, closest_neuron],
            (duration_index + 1, ))
        selected_LFP = np.reshape(
            self.produce_local_field_potential(
                trial=trial)[0, start_index:start_index + duration_index + 1],
            (duration_index + 1, ))

        corr = crsscorr.constwindowcorrelation(selected_vm, selected_LFP)
        corr_time_points = np.arange(-duration / 2, duration / 2 + dt, dt)
        return corr, corr_time_points
Exemple #2
0
    def produce_local_field_potential(self, trial=0):
        """
        Calculates and returns the 2D-array of the LFP.
        The first dimension corresponds to the electrodes.
        """
        vm = self.get_membrane_potential(trial=trial)
        gsyn = self.get_conductance(trial=trial)
        neuron_positions = self.get_positions()

        num_time_points = vm.shape[0]
        num_electrodes = self.electrode_positions.shape[0]

        ones_array = np.ones((num_electrodes, num_time_points, num_neurons))

        current_array = np.multiply(vm, gsyn)
        inv_dist = nf.electrode_neuron_inv_dist(num_electrodes, num_neurons,
                                                self.electrode_positions,
                                                neuron_positions, self.reach,
                                                self.dimensionnality)

        big_current_array = np.multiply(ones_array, current_array)
        big_inv_dist_array = np.multiply(ones_array, inv_dist)

        LFP = np.sum(big_current_array, big_inv_dist_array,
                     axis=2) / (4 * np.pi * self.sigma)

        return LFP
Exemple #3
0
    def produce_vm_LFP_zerolagcorrelations(self,
                                           start=600,
                                           duration=1000,
                                           dt=0.1,
                                           trial_average=True,
                                           trial=0,
                                           withinreach=True):
        """
        Calculates the zero-lag correlations between the neurons' membrane potentials and the LFP.
        Interesting plots to do with this data can be:
        - histogram of the correlation distribution;
        - confrontation of the correlation values between a non-stimulated and stimulated state (for the same neurons).
        The trial_average boolean tells if the correlations have to be averaged over the trials.
        If not, the chosen trial is trial.
        """
        start_index = int(start / dt)
        duration_index = int(duration / dt)

        if trial_average == True:
            trials = self.num_trials
        else:
            trials = trial

        self.get_positions()  #just to initiate the value of self.num_neurons
        zerolagcorrelations_array = np.zeros((trials, self.num_neurons))
        for iteration_trial in range(trials):
            vm = self.get_membrane_potential(trial=iteration_trial)
            vm = vm[start_index:start_index + duration_index, :]
            LFP = np.reshape(
                self.produce_local_field_potential(
                    trial=iteration_trial)[0, start_index:start_index +
                                           duration_index],
                (duration_index + 1, ))

            def zerolagtcorrelationtoLFP(v):
                return crsscorr.zerolagcorrelation(v, LFP)

            ### ELIMINATION OF THE CONTRIBUTION OF NEURONS THAT ARE OUT OF THE REACH ZONE
            if withinreach:
                num_electrodes = self.electrode_positions.shape[0]
                neuron_positions = self.get_positions()
                inv_dist = nf.electrode_neuron_inv_dist(
                    num_electrodes, self.num_neurons, self.electrode_positions,
                    neuron_positions, self.reach, self.dimensionnality)[0, :]
                valid_dist_neurons = np.heaviside(
                    inv_dist - 1. / self.reach,
                    1)  #array of neurons that are within the reach
                vm = np.multiply(
                    vm, valid_dist_neurons
                )  #vms of neurons that are out of the reach are null

            zerolagcorrelations_array[
                iteration_trial, :] = np.apply_along_axis(
                    zerolagtcorrelationtoLFP, axis=0, arr=vm)

        zerolagcorrelations = np.average(zerolagcorrelations_array, axis=0)

        return zerolagcorrelations  #if withinreach==True, neurons that are out of the reach zone have a null correlation with the LFP
Exemple #4
0
    def produce_vm_LFP_meancoherence(self,
                                     trial=0,
                                     withinreach=True,
                                     start=29,
                                     duration=1000,
                                     dt=0.1):
        """
        Calculates the mean coherence between the neurons' membrane potentials and the LFP.
        returns the mean coherence, the corresponding frequencies (in Hz) and the standard deviation error for each
        coherence value.
        The relevant data is supposed to be 1s long.
        """
        start_index = int(start / dt)
        duration_index = int(duration / dt)

        vm = self.get_membrane_potential(trial=trial)
        vm = vm[start_index:start_index + duration_index, :]
        LFP = np.reshape(
            self.produce_local_field_potential(
                trial=trial)[0, start_index:start_index + duration_index],
            (duration_index + 1, ))

        ### ELIMINATION OF THE CONTRIBUTION OF NEURONS THAT ARE OUT OF THE REACH ZONE
        if withinreach:
            num_electrodes = self.electrode_positions.shape[0]
            neuron_positions = self.get_positions()
            inv_dist = nf.electrode_neuron_inv_dist(
                num_electrodes, self.num_neurons, self.electrode_positions,
                neuron_positions, self.reach, self.dimensionnality)[0, :]
            valid_dist_neurons = np.heaviside(
                inv_dist - 1. / self.reach,
                1)  #array of neurons that are within the reach
            vm = np.multiply(
                vm, valid_dist_neurons
            )  #vms of neurons that are out of the reach are null

        f, coherence_array = coherence(LFP,
                                       vm,
                                       axis=0,
                                       nperseg=int(2**12),
                                       fs=1000. / dt)
        meancoherence_array = np.average(coherence_array, axis=1)
        coherencestd_array = np.std(coherence_array, axis=1)
        return meancoherence_array, f, coherencestd_array
Exemple #5
0
    plt.figure()
    plt.title("Excitatory neurons")
    plt.xlabel("Time intervals (ms)")
    plt.ylabel("Number of neurons")
    plt.scatter(s_time_points, s_heights, marker="x")

###########
### LFP ###
###########

print('Computation of the distances...')
positions_exc = network_width * (np.random.rand(num_sig, dimensionnality) -
                                 0.5)
inv_distances_exc = electrode_neuron_inv_dist(num_electrodes, num_sig,
                                              electrode_position,
                                              positions_exc, reach,
                                              dimensionnality)[0, :]

print('Computation of the excitatory LFP...')
current_array = np.multiply(vm_exc, gsyn_exc)
indiv_LFP = np.multiply(current_array,
                        inv_distances_exc)  #*(quant.mV)*(quant.uS)/quant.m
LFP_exc = np.sum(indiv_LFP, axis=1) / (4 * np.pi * sigma)

#=================================================================================================================
#=================================================================================================================

print("\nINHIBITORY NEURONS\n")

PyNN_file = open(
    "./Results/20190718/VAbenchmarks_COBA_inh_neuron_np1_20190718-201157.pkl",
Exemple #6
0
    def produce_spike_triggered_LFP(self,
                                    start=500,
                                    duration=1000,
                                    dt=0.1,
                                    window_width=200,
                                    trial_average=True,
                                    trial=0):
        """
        Calculates the spike-triggered average of the LFP (stLFP) and arranges the results relative to the distance
        from the electrode. The distances discriminating the neurons are (in mm): 0.4, 0.8, 1.2, 1.4 and 1.6.
        Returns the stLFP for each distance interval and in a time interval around the spikes.
        The stLFP is a 2D-array with the first dimension corresponding to the distance and the second, the time.
        """
        discrim_dist = np.array([4e-4, 8e-4, 1.2e-3, 1.6e-3])
        discrim_inv_dist = np.append(np.inf, np.power(discrim_dist, -1))
        discrim_inv_dist = np.append(discrim_dist, 0.)

        num_electrodes = self.electrode_positions.shape[0]
        neuron_positions = self.get_positions()
        inv_dist = nf.electrode_neuron_inv_dist(num_electrodes,
                                                self.num_neurons,
                                                self.electrode_positions,
                                                neuron_positions, self.reach,
                                                self.dimensionnality)[0, :]

        discrim_indexes = [[], [], [], [], []]
        num_dist_intervals = 5
        for i in range(num_dist_intervals):
            i_normalized_inv_dist = mf.door(inv_dist, discrim_inv_dist[i + 1],
                                            discrim_inv_dist[i])
            i_indexes = np.argwhere(i_normalized_inv_dist == 1)
            discrim_indexes[i].append(i_indexes.flatten().tolist())
        '''
        Now I have discriminated the neurons according to their distance from the electrode (information stored in
        their indexes in the list discrim_indexes), I can separate the stLFPs according to this criteria.
        '''

        if trial_average:
            trials = self.num_trials
        else:
            trials = trial

        window_index = int(window_width / dt)
        window = np.arange(-window_width / 2, window_width / 2 + dt, dt)
        stLFP_array = np.zeros((trials, num_dist_intervals, window_index + 1))

        for iteration_trial in range(trials):
            ### LOOP ON THE TRIALS
            spiketrains = self.get_spike_trains(trial=iteration_trial)
            LFP = self.produce_local_field_potential(
                trial=iteration_trial)[0, :]

            for interval_index in range(num_dist_intervals):
                ### LOOP ON THE DISTANCE INTERVALS
                average_counter = 0
                for neuron_index in discrim_indexes[interval_index]:
                    ### LOOP ON THE NEURONS WITHIN A DISTANCE INTERVAL
                    for t_s in spiketrains[
                            neuron_index]:  #maybe I can get rid of this loop... I don't like it...
                        ### LOOP ON THE SPIKES OF A GIVEN NEURON
                        t_s_index = int(t_s / dt)
                        average_counte += 1
                        stLFP_array[iteration_trial,
                                    interval_index, :] = np.add(
                                        stLFP_array[iteration_trial,
                                                    interval_index, :],
                                        LFP[t_s - window_index // 2:t_s_index +
                                            window_index // 2 + 1])
                stLFP_array[iteration_trial,
                            interval_index, :] /= average_counter

        stLFP = np.average(stLFP_array, axis=0)  #trial-average computation
        return stLFP, window