Ejemplo n.º 1
0
grid_electrode_parameters_tensor = {
    'sigma': sigma_tensor,  # extracellular conductivity
    'x': X.flatten(),  # electrode requires 1d vector of positions
    'y': Y.flatten(),
    'z': Z.flatten(),
    'method': 'root_as_point'
}

# Run simulation, electrode object argument in cell.simulate
print("running simulation...")

cell.simulate(rec_imem=True)

# Create electrode objects

grid_electrode = LFPy.RecExtElectrode(cell, **grid_electrode_parameters)
grid_electrode.data = grid_electrode.get_transformation_matrix() @ cell.imem

grid_electrode_tensor = LFPy.RecExtElectrode(
    cell, **grid_electrode_parameters_tensor)
grid_electrode_tensor.data = \
    grid_electrode_tensor.get_transformation_matrix() @ cell.imem

fig = plt.figure(figsize=[10, 5])

ax = fig.add_subplot(121,
                     aspect='equal',
                     xlabel='x ($\\mu$m)',
                     ylabel='z ($\\mu$m)',
                     title="Sigma: %s S/m" % str(sigma),
                     ylim=[np.min(grid_electrode.z),
Ejemplo n.º 2
0
    def test_cell_with_recextelectrode_01(self):
        stickParams = {
            'morphology':
            os.path.join(LFPy.__path__[0], 'test', 'stick.hoc'),
            'templatefile':
            os.path.join(LFPy.__path__[0], 'test', 'stick_template.hoc'),
            'templatename':
            'stick_template',
            'templateargs':
            None,
            'cm':
            1,
            'Ra':
            150,
            'v_init':
            -65,
            'passive':
            True,
            'passive_parameters': {
                'g_pas': 1. / 30000,
                'e_pas': -65
            },
            'tstart':
            -100,
            'tstop':
            100,
            'dt':
            2**-4,
            'nsegs_method':
            'lambda_f',
            'lambda_f':
            100,
        }

        electrodeParams = {
            'sigma': 0.3,
            'x': np.ones(11) * 100.,
            'y': np.zeros(11),
            'z': np.linspace(1000, 0, 11),
            'method': 'pointsource'
        }

        stimParams = {
            'pptype': 'SinSyn',
            'delay': 0.,
            'dur': 1000.,
            'pkamp': 1.,
            'freq': 100.,
            'phase': 0,
            'bias': 0.,
            'record_current': False
        }

        stick = LFPy.TemplateCell(**stickParams)
        synapse = LFPy.StimIntElectrode(stick,
                                        stick.get_closest_idx(0, 0, 1000),
                                        **stimParams)
        electrode = LFPy.RecExtElectrode(**electrodeParams)
        stick.simulate(electrode, rec_imem=True)

        electrode1 = LFPy.RecExtElectrode(cell=stick, **electrodeParams)
        electrode1.calc_lfp()

        np.testing.assert_allclose(electrode.LFP, electrode1.LFP)
Ejemplo n.º 3
0
def simulate_laminar_LFP():
    # DEPRECATED, and not updated for LFPy2.2 and newer
    dt = 2**-5
    cell_name = 'hay'

    elec_z = np.linspace(-200, 1200, 15)
    elec_x = np.ones(len(elec_z)) * 50
    elec_y = np.zeros(len(elec_z))

    h = np.abs(elec_z[1] - elec_z[0])

    electrode_parameters = {
        'sigma': 0.3,  # extracellular conductivity
        'x': elec_x,  # x,y,z-coordinates of contact points
        'y': elec_y,
        'z': elec_z
    }

    elec_clr = lambda idx: plt.cm.viridis(idx / len(elec_z))

    num_sims = 10

    cells = []

    summed_LFP = []
    summed_cdm = []

    for sim in range(num_sims):
        print(sim + 1, "/", num_sims)
        cell_wca, idx_clr, plot_idxs = run_cell_simulation_distributed_input(
            dt=dt, cell_name=cell_name)
        cells.append([cell_wca, idx_clr, plot_idxs])
    for sim in range(num_sims):
        cell_wca, idx_clr, plot_idxs = cells[sim]
        fig = plt.figure(figsize=[7, 7])
        fig.subplots_adjust(hspace=0.5,
                            left=0.0,
                            wspace=0.4,
                            right=0.96,
                            top=0.97,
                            bottom=0.1)

        ax_m = fig.add_axes([-0.01, 0.05, 0.3, 0.97],
                            aspect=1,
                            frameon=False,
                            xlim=[-350, 350],
                            xticks=[],
                            yticks=[])
        [
            ax_m.plot([cell_wca.xstart[idx], cell_wca.xend[idx]],
                      [cell_wca.zstart[idx], cell_wca.zend[idx]],
                      c='k') for idx in range(cell_wca.totnsegs)
        ]
        [
            ax_m.plot(cell_wca.xmid[idx],
                      cell_wca.zmid[idx],
                      'o',
                      c=idx_clr[idx],
                      ms=13) for idx in plot_idxs
        ]

        [
            ax_m.plot(cell_wca.xmid[idx], cell_wca.zmid[idx], 'rd')
            for idx in cell_wca.synidx
        ]

        ax_top = 0.98
        ax_h = 0.25
        h_space = 0.1
        ax_w = 0.17
        ax_left = 0.4
        cell = cell_wca

        elec = LFPy.RecExtElectrode(cell, **electrode_parameters)
        elec.calc_lfp()

        ax_vm = fig.add_axes([ax_left, ax_top - ax_h, ax_w, ax_h],
                             ylim=[-80, 50],
                             xlim=[0, 80],
                             xlabel="Time (ms)")

        ax_eap = fig.add_axes([ax_left + 0.3, 0.1, ax_w, 0.8],
                              xlim=[0, 80],
                              xlabel="Time (ms)")
        ax_cdm = fig.add_axes(
            [ax_left, 0.2, ax_w, ax_h],
            xlabel="Time (ms)",
            ylim=[-0.5, 1],
            xlim=[0, 80],
        )

        ax_vm.set_ylabel("Membrane\npotential\n(mV)", labelpad=-3)
        ax_eap.set_ylabel("Extracellular potential ($\mu$V)", labelpad=-3)
        ax_cdm.set_ylabel("Curent dipole\nmoment\n($\mu$A$\cdot \mu$m)",
                          labelpad=-3)

        [
            ax_vm.plot(cell.tvec, cell.vmem[idx], c=idx_clr[idx])
            for idx in plot_idxs
        ]

        elec.LFP -= elec.LFP[:, 0, None]
        cell.current_dipole_moment -= cell.current_dipole_moment[0, :]
        summed_LFP.append(elec.LFP)
        summed_cdm.append(cell.current_dipole_moment)

        normalize = np.max(np.abs(elec.LFP))
        for idx in range(len(elec_x)):
            ax_eap.plot(cell.tvec,
                        elec.LFP[idx] / normalize * h + elec_z[idx],
                        c=elec_clr(idx))
            ax_m.plot(elec_x[idx], elec_z[idx], c=elec_clr(idx), marker='D')

        ax_cdm.plot(cell.tvec, 1e-3 * cell.current_dipole_moment[:, 2], c='k')

        mark_subplots([ax_m], xpos=0.1, ypos=0.95)
        simplify_axes(fig.axes)

        plt.savefig(
            join("figures",
                 'laminar_LFP_ca_spike_{}_{}.png'.format(cell_name, sim)))
        # plt.savefig(join("figures", 'hay_ca_spike.pdf'))
        plt.close("all")

    summed_LFP = np.sum(summed_LFP, axis=0)
    summed_cdm = np.sum(summed_cdm, axis=0)
    normalize = np.max(np.abs(summed_LFP))
    plt.subplot(121)
    for idx in range(len(elec_x)):
        plt.plot(cell.tvec,
                 summed_LFP[idx] / normalize * h + elec_z[idx],
                 c=elec_clr(idx))

    plt.subplot(122)
    plt.plot(cell.tvec, summed_cdm[:, 2])

    plt.savefig(
        join("figures",
             'summed_LFP_CDM_{}_num:{}.png'.format(cell_name, num_sims)))
Ejemplo n.º 4
0
    def simulate_network(self,filename,COMM,SIZE,RANK):

        filename = filename # to load data from the LIF network

        # XY cell positions: randomly placed within a circle
        if RANK == 0:
            x_cell_pos = [[],[]]
            y_cell_pos = [[],[]]

            for cell in range(sum(self.simulation_params["population_sizes"])):
                r = np.random.rand()*self.simulation_params["radius"]
                angle = np.random.rand()*(2*np.pi)
                x = r * np.cos(angle)
                y = r * np.sin(angle)

                if cell < self.simulation_params["population_sizes"][0]:
                    x_cell_pos[0].append(x)
                    y_cell_pos[0].append(y)
                else:
                    x_cell_pos[1].append(x)
                    y_cell_pos[1].append(y)

        else:
            x_cell_pos = None
            y_cell_pos = None

        x_cell_pos = COMM.bcast(x_cell_pos, root=0)
        y_cell_pos = COMM.bcast(y_cell_pos, root=0)

        # Resync MPI threads
        COMM.Barrier()

        # Z positions
        z_cell_pos = [self.simulation_params["z_cell_pos"],
                      self.simulation_params["z_cell_pos"]]

        # XYZ cell rotations
        xyz_rotations = [self.simulation_params["xyz_rotations"][0],
                         self.simulation_params["xyz_rotations"][1]]

        # Synapse parameters
        synapse_parameters = {}

        # Recurrent connections
        synapse_parameters['exc_exc']={
            'e' : 0.0,                   # reversal potential (mV)
            'tau1' : 0.4,                # rise time constant (ms)
            'tau2' : 2.0,                # decay time constant (ms)
            'weight' : self.simulation_params["weight_factor"]*\
                       0.178*10**(-3),   # syn. weight (uS)
            'position_parameters' : {
                'z_min': self.simulation_params["AMPA_syn_position"]["z_min"],
                'z_max': self.simulation_params["AMPA_syn_position"]["z_max"]}
        }

        synapse_parameters['inh_exc']={
            'e' : -80.,
            'tau1' : 0.25,
            'tau2' : 5.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       2.01*10**(-3),
            'position_parameters' : {
                'z_min': self.simulation_params["GABA_syn_position"]["z_min"],
                'z_max': self.simulation_params["GABA_syn_position"]["z_max"]}
        }

        synapse_parameters['exc_inh']={
            'e' : 0.,
            'tau1' : 0.2,
            'tau2' : 1.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       0.233*10**(-3),
            'position_parameters' : {
                'z_min': -10**6,
                'z_max':  10**6}
        }

        synapse_parameters['inh_inh']={
            'e' : -80.,
            'tau1' : 0.25,
            'tau2' : 5.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       2.70*10**(-3),
            'position_parameters' : {
                'z_min': -10**6,
                'z_max':  10**6}
        }

        # External inputs
        synapse_parameters['th_exc']={
            'e' : 0.0,
            'tau1' : 0.4,
            'tau2' : 2.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       0.234*10**(-3),
            'position_parameters' : {
                'z_min': self.simulation_params["AMPA_syn_position"]["z_min"],
                'z_max': self.simulation_params["AMPA_syn_position"]["z_max"]}
        }

        synapse_parameters['th_inh']={
            'e' : 0.0,
            'tau1' : 0.2,
            'tau2' : 1.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       0.317*10**(-3),
            'position_parameters' : {
                'z_min': -10**6,
                'z_max':  10**6}
        }

        synapse_parameters['cc_exc']={
            'e' : 0.0,
            'tau1' : 0.4,
            'tau2' : 2.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       0.187*10**(-3),
            'position_parameters' : {
                'z_min': self.simulation_params["AMPA_syn_position"]["z_min"],
                'z_max': self.simulation_params["AMPA_syn_position"]["z_max"]}
        }

        synapse_parameters['cc_inh']={
            'e' : 0.0,
            'tau1' : 0.2,
            'tau2' : 1.0,
            'weight' : self.simulation_params["weight_factor"]*\
                       0.254*10**(-3),
            'position_parameters' : {
                'z_min': -10**6,
                'z_max':  10**6}
        }

        # Define electrode parameters
        Z = self.simulation_params["Z_electrode"]
        X = self.simulation_params["X_electrode"]

        electrode_parameters = {
            'sigma' : 0.3,      # extracellular conductivity
            'z' : Z,
            'x' : X,
            'y' : np.zeros(Z.size),
        }

        # EEG: four_sphere parameters
        # Dimensions that approximate those of a rat head model
        radii = [9000.,9500.,10000.,10500.]
        sigmas = [0.3, 1.5, 0.015, 0.3]
        rad_tol = 1e-2

        # Summed LFPs
        if RANK==0:
            summed_LFP = np.zeros(  (self.simulation_params["Z_size"],
                                    int(self.cell_params_ex["tstop"] /\
                                    self.cell_params_ex["dt"] + 1)) )

            if self.simulation_params["individual_EEG"]:
                summed_EEG_top = np.zeros(int(self.cell_params_ex["tstop"] /\
                                        self.cell_params_ex["dt"] + 1))
            else:
                summed_dipole = np.zeros((int(self.cell_params_ex["tstop"] /\
                                        self.cell_params_ex["dt"] + 1),3))

        # Load presynaptic spike times and connection matrix of the LIF network
        spike_times = tools.loadLIFData(self.simulation_params["experiment_id_LIF"],
                                           filename,'.spikes')
        connection_matrix = tools.loadLIFData(self.simulation_params["experiment_id_LIF"],
                                           filename,'.connections')

        # Start timer
        if RANK==0:
            start_c = time.time()

        # Iterate over cells in populations
        for j,pop_size in enumerate(self.simulation_params["population_sizes"]):
            for cell_id in range(pop_size):
                sys.stdout.write("\r" + "Simulating cell %s " % (cell_id+\
                                j*self.simulation_params["population_sizes"][0]))
                sys.stdout.flush()

                if cell_id % SIZE == RANK:
                    # Initialize cell instance, using the LFPy.TemplateCell class
                    if j==0:
                        post_cell = LFPy.TemplateCell(**self.cell_params_ex)
                        # Position and rotation of the cell
                        post_cell.set_rotation(**xyz_rotations[0])
                        post_cell.set_pos(x = x_cell_pos[0][cell_id],
                                          y = y_cell_pos[0][cell_id],
                                          z = z_cell_pos[0])
                    else:
                        post_cell = LFPy.TemplateCell(**self.cell_params_in)
                        # Position and rotation of the cell
                        post_cell.set_rotation(**xyz_rotations[1])
                        post_cell.set_pos(x = x_cell_pos[1][cell_id],
                                          y = y_cell_pos[1][cell_id],
                                          z = z_cell_pos[1])

                    # Search for presynaptic connections
                    for conn,pre_cell in enumerate(connection_matrix[cell_id+\
                            j*self.simulation_params["population_sizes"][0]]):
                        # Recurrent: Exc. -> Exc.
                        if j==0 and pre_cell < self.simulation_params["population_sizes"][0]:
                            dict_syn = synapse_parameters['exc_exc']
                        # Recurrent: Exc. -> Inh.
                        elif j==1 and pre_cell < self.simulation_params["population_sizes"][0]:
                            dict_syn = synapse_parameters['exc_inh']
                        # Recurrent: Inh. -> Exc.
                        elif j==0 and pre_cell >= self.simulation_params["population_sizes"][0] and\
                        pre_cell < sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['inh_exc']
                        # Recurrent: Inh. -> Inh.
                        elif j==1 and pre_cell >= self.simulation_params["population_sizes"][0] and\
                        pre_cell < sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['inh_inh']
                        # External: Th. -> Exc.
                        elif j==0 and pre_cell >= sum(self.simulation_params["population_sizes"]) and\
                        pre_cell < 2*sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['th_exc']
                        # External: Th. -> Inh.
                        elif j==1 and pre_cell >= sum(self.simulation_params["population_sizes"]) and\
                        pre_cell < 2*sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['th_inh']
                        # External: CC. -> Exc.
                        elif j==0 and pre_cell >= 2*sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['cc_exc']
                        # External: CC. -> Inh.
                        elif j==1 and pre_cell >= 2*sum(self.simulation_params["population_sizes"]):
                            dict_syn = synapse_parameters['cc_inh']

                        # Segment indices to locate the connection
                        pos = dict_syn["position_parameters"]
                        idx = post_cell.get_rand_idx_area_norm(section=['dend','apic','soma'],nidx=1,**pos)

                        # Make a synapse and set the spike times
                        for i in idx:
                            syn = LFPy.Synapse(cell=post_cell, idx=i, syntype='Exp2Syn',
                                          weight=dict_syn['weight'],delay=1.0,
                                          **dict(tau1=dict_syn['tau1'], tau2=dict_syn['tau2'],
                                           e=dict_syn['e']))
                            syn.set_spike_times(np.array(spike_times[int(pre_cell)]))

                    # Create spike-detecting NetCon object attached to the cell's soma
                    # midpoint
                    if self.simulation_params["record_all"]:
                        for sec in post_cell.somalist:
                            post_cell.netconlist.append(neuron.h.NetCon(sec(0.5)._ref_v,
                                                        None,sec=sec))
                            post_cell.netconlist[-1].threshold = -52.0 # as in the LIF net.
                            post_cell.netconlist[-1].weight[0] = 0.0
                            post_cell.netconlist[-1].delay = 0.0

                    # record spike events
                    if self.simulation_params["record_all"]:
                        spikes = neuron.h.Vector()
                        post_cell.netconlist[-1].record(spikes)

                    # Simulate
                    post_cell.simulate(rec_imem=True,
                                       rec_current_dipole_moment=True)

                    # Compute dipole
                    P = post_cell.current_dipole_moment

                    # Compute EEG
                    eeg_top = []
                    if self.simulation_params["individual_EEG"]:
                        somapos = np.array([x_cell_pos[j][cell_id],
                                            y_cell_pos[j][cell_id],
                                            8500])
                        r_soma_syns = [post_cell.get_intersegment_vector(idx0=0,
                                      idx1=i) for i in post_cell.synidx]
                        r_mid = np.average(r_soma_syns, axis=0)
                        r_mid = somapos + r_mid/2.

                        # Change position of the EEG electrode
                        # print("Warning: The EEG electrode is not at the top!!!")
                        # theta_r = np.pi * 0.5
                        # phi_angle_r = 0.0
                        # x_eeg = (radii[3] - rad_tol) * np.sin(theta_r) * np.cos(phi_angle_r)
                        # y_eeg = (radii[3] - rad_tol) * np.sin(theta_r) * np.sin(phi_angle_r)
                        # z_eeg = (radii[3] - rad_tol) * np.cos(theta_r)
                        # eeg_coords = np.vstack((x_eeg, y_eeg, z_eeg)).T

                        # EEG electrode at the top
                        eeg_coords = np.array([[0., 0., radii[3] - rad_tol]])

                        # Four-Sphere method
                        four_sphere_top = LFPy.FourSphereVolumeConductor(radii,
                                                        sigmas, eeg_coords)
                        pot_db_4s_top = four_sphere_top.calc_potential(P, r_mid)
                        eeg_top = (np.array(pot_db_4s_top) * 1e6)[0]
                        P = []

                    # Set up the extracellular electrode
                    grid_electrode = LFPy.RecExtElectrode(post_cell,
                                                           **electrode_parameters)
                    # Compute LFP
                    grid_electrode.calc_lfp()

                    # send LFP/EEG of this cell to RANK 0
                    if RANK != 0:
                        if self.simulation_params["individual_EEG"]:
                            COMM.send([grid_electrode.LFP,eeg_top], dest=0)
                        else:
                            COMM.send([grid_electrode.LFP,P], dest=0)
                    else:
                        summed_LFP += grid_electrode.LFP
                        if self.simulation_params["individual_EEG"]:
                            if len(np.argwhere(np.isnan(eeg_top))) == 0:
                                summed_EEG_top += eeg_top
                        else:
                            summed_dipole += P

                    # Synapses
                    if self.simulation_params["record_all"]:
                        syns = []
                        for s in post_cell.synapses:
                            syns.append([s.x,s.y,s.z,s.kwargs['e']])

                # collect single LFP/EEG contributions on RANK 0
                if RANK == 0:
                    if cell_id % SIZE != RANK:
                        data = COMM.recv(source = cell_id % SIZE)
                        summed_LFP += data[0]

                        if self.simulation_params["individual_EEG"]:
                            if len(np.argwhere(np.isnan(data[1]))) == 0:
                                summed_EEG_top += data[1]
                        else:
                            summed_dipole += data[1]

                # Save results to file
                if cell_id % SIZE == RANK:
                    if self.simulation_params["record_all"]:
                        if cell_id == 0:
                            # Create dict
                            results_dict = {
                            "somav":post_cell.somav,
                            "spikes":spikes,
                            "syns":syns,
                            "xyz_rotations":xyz_rotations,
                            "x_cell_pos":x_cell_pos,
                            "y_cell_pos":y_cell_pos,
                            "z_cell_pos":z_cell_pos,
                            "cell_params_ex":self.cell_params_ex,
                            "cell_params_in": self.cell_params_in,
                            "radii":radii,
                            "sigmas":sigmas,
                            "rad_tol":rad_tol
                            }
                        else:
                            # Create dict
                            results_dict = {
                            "somav":post_cell.somav,
                            "spikes":spikes,
                            "syns":syns,
                            }

                        pickle.dump(results_dict,
                            open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                            filename+str(cell_id+j*self.simulation_params["population_sizes"][0]),
                            "wb"))

                    else:
                        if cell_id == 0:
                            # Create dict
                            results_dict = {
                            "cell_params_ex":self.cell_params_ex,
                            "cell_params_in": self.cell_params_in,
                            "radii":radii,
                            "sigmas":sigmas,
                            "rad_tol":rad_tol
                            }

                            pickle.dump(results_dict,
                                open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                                filename+str(cell_id+j*self.simulation_params["population_sizes"][0]),
                                "wb"))

        # Resync MPI threads
        COMM.Barrier()

        if RANK == 0:
            # Save time vector
            pickle.dump(post_cell.tvec,
                        open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                             filename+"tvec","wb"))
            # Save LFP,EEG,CDM
            if self.simulation_params["decimate"]:
                data_tofile = tools.decimate(summed_LFP,10)
            else:
                data_tofile = summed_LFP

            pickle.dump(data_tofile,
                        open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                             filename+"_LFP","wb"))

            if self.simulation_params["individual_EEG"]:
                if self.simulation_params["decimate"]:
                    data_tofile = tools.decimate(summed_EEG_top,10)
                else:
                    data_tofile = summed_EEG_top

                pickle.dump(data_tofile,
                            open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                                 filename+"_EEG","wb"))
            else:
                if self.simulation_params["decimate"]:
                    data_tofile = tools.decimate(np.transpose(np.array(summed_dipole)),10)
                else:
                    data_tofile = np.transpose(np.array(summed_dipole))

                pickle.dump(data_tofile,
                            open('../results/'+self.simulation_params["experiment_id_3D"]+"/"+\
                                 filename+"_CDM","wb"))

            # Print computation time
            end_c = time.time()
            print("\n\ntime elapsed: %s min" % str((end_c - start_c)/60.0))

        # Cleanup of object references. It will allow the script
        # to be run in successive fashion
        post_cell = None
        grid_electrode = None
        syn = None
        four_sphere_top = None
        neuron.h('forall delete_section()')
Ejemplo n.º 5
0
for popName in dipole_names:
    dipole_recorders[popName] = []
    for cell in getattr(h, popName):
        for dipole in cell.bd:
            dipole_recorders[popName].append(h.Vector().record(
                dipole._ref_Qsum))

# Define grid recording electrode
gridLims = {'x': [-400, 1100], 'y': [-300, 1400]}
X, Y = np.mgrid[gridLims['x'][0]:gridLims['x'][1]:25,
                gridLims['y'][0]:gridLims['y'][1]:25]
Z = np.zeros(X.shape)
grid_electrode = LFPy.RecExtElectrode(
    **{
        'sigma': 0.3,  # extracellular conductivity
        'x': X.flatten(),  # electrode requires 1d vector of positions
        'y': Y.flatten(),
        'z': Z.flatten()
    })

# ----------------------------------------------------
# Run model!
# ----------------------------------------------------
h('run()')

# ----------------------------------------------------
# Create dummy cell and LFP/dipole information
# ----------------------------------------------------

# Get segment positions in xyz space
xyz_starts, xyz_ends = np.zeros(shape=(0, 3)), np.zeros(shape=(0, 3))
Ejemplo n.º 6
0
def simulate_spike_current_dipole_moment():

    dt = 2**-5
    cell_name = 'hay'

    jitter_std = 10
    num_trials = 1000

    # Create a grid of measurement locations, in (mum)
    grid_x, grid_z = np.mgrid[-750:751:25, -750:1301:25]
    # grid_x, grid_z = np.mgrid[-75:76:50, -75:76:50]
    # grid_x, grid_z = np.mgrid[-75:76:50, -75:251:50]
    grid_y = np.zeros(grid_x.shape)

    # Define electrode parameters
    grid_elec_params = {
        'sigma': 0.3,  # extracellular conductivity
        'x': grid_x.flatten(),  # electrode requires 1d vector of positions
        'y': grid_y.flatten(),
        'z': grid_z.flatten()
    }

    elec_x = np.array([
        30,
    ])
    elec_y = np.array([
        0,
    ])
    elec_z = np.array([
        0,
    ])

    electrode_parameters = {
        'sigma': 0.3,  # extracellular conductivity
        'x': elec_x,  # x,y,z-coordinates of contact points
        'y': elec_y,
        'z': elec_z
    }

    elec_clr = 'r'

    cell_woca, idx_clr, plot_idxs = run_cell_simulation(make_ca_spike=False,
                                                        dt=dt,
                                                        cell_name=cell_name)
    cell_wca, idx_clr, plot_idxs = run_cell_simulation(make_ca_spike=True,
                                                       dt=dt,
                                                       cell_name=cell_name)

    fig = plt.figure(figsize=[8, 7])
    fig.subplots_adjust(hspace=0.5,
                        left=0.0,
                        wspace=0.4,
                        right=0.96,
                        top=0.97,
                        bottom=0.1)

    ax_m = fig.add_axes([-0.01, 0.05, 0.25, 0.97],
                        aspect=1,
                        frameon=False,
                        xticks=[],
                        yticks=[])
    [
        ax_m.plot([cell_wca.xstart[idx], cell_wca.xend[idx]],
                  [cell_wca.zstart[idx], cell_wca.zend[idx]],
                  c='k') for idx in range(cell_wca.totnsegs)
    ]
    [
        ax_m.plot(cell_wca.xmid[idx],
                  cell_wca.zmid[idx],
                  'o',
                  c=idx_clr[idx],
                  ms=13) for idx in plot_idxs
    ]
    ax_m.plot(elec_x, elec_z, elec_clr, marker='D')

    ax_top = 0.98
    ax_h = 0.15
    h_space = 0.1
    ax_w = 0.17
    ax_left = 0.37

    num = 11
    levels = np.logspace(-2.5, 0, num=num)
    scale_max = 100.

    levels_norm = scale_max * np.concatenate((-levels[::-1], levels))
    bwr_cmap = plt.cm.get_cmap('bwr_r')  # rainbow, spectral, RdYlBu

    colors_from_map = [
        bwr_cmap(i * np.int(255 / (len(levels_norm) - 2)))
        for i in range(len(levels_norm) - 1)
    ]
    colors_from_map[num - 1] = (1.0, 1.0, 1.0, 1.0)

    spike_plot_time_idxs = [1030, 1151]
    summed_cdm_max = np.zeros(2)
    for plot_row, cell in enumerate([cell_woca, cell_wca]):
        ax_left += plot_row * 0.25

        elec = LFPy.RecExtElectrode(cell, **electrode_parameters)
        elec.calc_lfp()

        elec.LFP -= elec.LFP[:, 0, None]

        time_idx = spike_plot_time_idxs[plot_row]
        print(cell.tvec[time_idx])

        grid_electrode = LFPy.RecExtElectrode(cell, **grid_elec_params)
        grid_electrode.calc_lfp()
        grid_LFP = 1e3 * grid_electrode.LFP

        grid_LFP -= grid_LFP[:, 0, None]

        grid_LFP_ = grid_LFP[:, time_idx].reshape(grid_x.shape)
        ax_ = fig.add_axes([0.75, 0.55 - plot_row * 0.46, 0.3, 0.45],
                           xticks=[],
                           yticks=[],
                           aspect=1,
                           frameon=False)
        mark_subplots(ax_, [["D"], ["E"]][plot_row], ypos=0.95, xpos=0.35)
        [
            ax_.plot([cell_wca.xstart[idx], cell_wca.xend[idx]],
                     [cell.zstart[idx], cell.zend[idx]],
                     c='k') for idx in range(cell_wca.totnsegs)
        ]
        ep_intervals = ax_.contourf(grid_x,
                                    grid_z,
                                    grid_LFP_,
                                    zorder=-2,
                                    colors=colors_from_map,
                                    levels=levels_norm,
                                    extend='both')

        ax_.contour(grid_x,
                    grid_z,
                    grid_LFP_,
                    colors='k',
                    linewidths=(1),
                    zorder=-2,
                    levels=levels_norm)

        if plot_row == 1:
            cax = fig.add_axes([0.82, 0.12, 0.16, 0.01])
            cbar = fig.colorbar(ep_intervals,
                                cax=cax,
                                orientation='horizontal',
                                format='%.0E',
                                extend='max')

            cbar.set_ticks(
                np.array([-1, -0.1, -0.01, 0, 0.01, 0.1, 1]) * scale_max)
            cax.set_xticklabels(np.array(
                np.array([-1, -0.1, -0.01, 0, 0.01, 0.1, 1]) * scale_max,
                dtype=int),
                                fontsize=11,
                                rotation=45)
            cbar.set_label('$\phi$ ($\mu$V)', labelpad=-5)
        cell.current_dipole_moment -= cell.current_dipole_moment[0, :]

        sum_tvec, summed_cdm = sum_jittered_cdm(
            cell.current_dipole_moment[:, 2], dt, jitter_std, num_trials)

        summed_cdm_max[plot_row] = np.max(np.abs(summed_cdm))

        ax_vm = fig.add_axes(
            [ax_left, ax_top - ax_h, ax_w, ax_h],
            ylim=[-80, 50],
            xlim=[0, 100],  #xlabel="Time (ms)"
        )

        ax_eap = fig.add_axes(
            [ax_left, ax_top - 2 * ax_h - h_space, ax_w, ax_h],
            ylim=[-120, 40],
            xlim=[0, 100],
            #xlabel="Time (ms)"
        )
        ax_cdm = fig.add_axes(
            [ax_left, ax_top - 3 * ax_h - 2 * h_space, ax_w, ax_h],
            #xlabel="Time (ms)",
            ylim=[-0.5, 1],
            xlim=[0, 100],
        )

        ax_cdm_sum = fig.add_axes(
            [ax_left, ax_top - 4 * ax_h - 3 * h_space, ax_w, ax_h],
            ylim=[-250, 100],
            xlabel="Time (ms)",
            xlim=[0, 140])
        if plot_row == 0:
            ax_vm.set_ylabel("Membrane\npotential\n(mV)", labelpad=-3)
            ax_eap.set_ylabel("Extracellular\npotential\n($\mu$V)",
                              labelpad=-3)
            ax_cdm.set_ylabel("Curent dipole\nmoment\n($\mu$A$\cdot \mu$m)",
                              labelpad=-3)
            ax_cdm_sum.set_ylabel("Jittered sum\n($\mu$A$\cdot \mu$m)",
                                  labelpad=-3)
        elif plot_row == 1:
            ax_vm.text(65, -5, "Ca$^{2+}$ spike", fontsize=11, color='orange')
            ax_vm.arrow(80, -10, -10, -18, color='orange', head_width=4)

        mark_subplots(ax_vm, [["B1"], ["C1"]][plot_row], xpos=-0.3, ypos=0.93)
        mark_subplots(ax_eap, [["B2"], ["C2"]][plot_row], xpos=-0.3, ypos=0.93)
        mark_subplots(ax_cdm, [["B3"], ["C3"]][plot_row],
                      xpos=-0.35,
                      ypos=0.97)
        mark_subplots(ax_cdm_sum, [["B4"], ["C4"]][plot_row],
                      xpos=-0.3,
                      ypos=0.93)
        [
            ax_vm.plot(cell.tvec, cell.vmem[idx], c=idx_clr[idx])
            for idx in plot_idxs
        ]
        ax_vm.axvline(cell.tvec[time_idx], ls='--', c='gray')

        # ax_cdm_sum = fig.add_subplot(524, ylim=[-1.1, 1.1], xlim=[0, 80],
        #                       ylabel="Membrane\ncurrents\n(normalized)")
        # [ax_cdm_sum.plot(cell.tvec, cell.imem[idx] / np.max(np.abs(cell.imem[idx])), c=idx_clr[idx])
        #  for idx in plot_idxs]

        [
            ax_eap.plot(cell.tvec, 1000 * elec.LFP[idx], c=elec_clr)
            for idx in range(len(elec_x))
        ]

        ax_cdm.plot(cell.tvec, 1e-3 * cell.current_dipole_moment[:, 2], c='k')
        ax_cdm_sum.plot(sum_tvec, 1e-3 * summed_cdm, c='k')

    print(
        "Summed CDM max (abs), ratio",
        summed_cdm_max * 1e-3,
    )

    mark_subplots([ax_m], xpos=0.1, ypos=0.95)
    simplify_axes(fig.axes)

    # plt.savefig(join("figures", 'ca_spike_{}_resim.png'.format(cell_name)))
    plt.savefig(join("figures", 'Figure5.pdf'))
Ejemplo n.º 7
0
def simulate_cells_serially(stimolo,
                            cell_ids,
                            data_name,
                            population_parameters,
                            cell_parameters,
                            synapse_parameters,
                            synapse_position_parameters,
                            electrode_parameters):

    print('input' + str(stimolo))

    # Load emitted spikes, 1st column: spike time, 2nd column: pre cell id
#    print "Loading locally emitted spikes"
    local_spikes_filename = population_parameters['input_dir'] + \
        'spiketimes_' + str(stimolo) + '.1.out'
    local_spikes = np.loadtxt(local_spikes_filename)
    local_sp_times = local_spikes[:, 0]
    local_sp_ids = local_spikes[:, 1]

    # Load connectivity, 1st column post id, 2nd column pre id
    connectivity_filename = population_parameters['input_dir'] \
        + 'Cmatrix_' + str(stimolo) + '.1.out'
    connectivity_file = open(connectivity_filename, "r")
    lines = connectivity_file.readlines()
    incoming_connections = []
    for line in lines:
        incoming_connections.append(np.array(line.split(), dtype='int'))
    connectivity_file.close()

    pre_cells = {}
    pre_cells['exc_exc'] = population_parameters['exc_ids']
    pre_cells['exc_inh'] = population_parameters['exc_ids']
    pre_cells['inh_exc'] = population_parameters['inh_ids']
    pre_cells['inh_inh'] = population_parameters['inh_ids']

    # n_thalamic_synapses = population_parameters['n_thalamic_synapses']
    # n_external_synapses = population_parameters['n_external_synapses']

    # setup data dictionary

    output_data = {}
    output_data['somav'] = {}
    output_data['LFP'] = {}
    output_data['somapos'] = {}
    output_data['tot_isyn'] = {}

    for i_cell, cell_id in enumerate(cell_ids):

        if cell_id in population_parameters['exc_ids']:
            print(str(cell_id))
            cell_parameters.update({'morphology': 'pyr1.hoc'})
            cell_parameters['passive_parameters'].update(
                {'g_pas': 1. / 20000.})

        elif cell_id in population_parameters['inh_ids']:
            indin = int(cell_id - max(population_parameters['exc_ids']))
            print(str(indin))
            cell_parameters.update({'morphology': 'int1.hoc'})
            cell_parameters['passive_parameters'].update(
                {'g_pas': 1. / 10000.})

        print("Setting up cell " + str(cell_id))

        cell_seed = population_parameters['global_seed'] + cell_id

        print("Setting random seed: " + str(cell_seed))

        np.random.seed(cell_seed)

        neuron.h('forall delete_section()')  # new
        cell = LFPy.Cell(**cell_parameters)  # new

        # load true position
        if cell_id in population_parameters['exc_ids']:
            cell_pos = np.loadtxt('PCsXYZ.txt')
            x, y, z = cell_pos[cell_id]

        elif cell_id in population_parameters['inh_ids']:
            cell_pos = np.loadtxt('INTsXYZ.txt')
            x, y, z = cell_pos[int(cell_id -
                                   int(min(population_parameters['inh_ids'])))]

        cell.set_pos(x=x, y=y, z=z)

        if cell_id in population_parameters['exc_ids']:
            local_synapse_types = ['exc_exc', 'inh_exc']
            # thalamic_synapse_type = 'thalamic_exc'
            # external_synapse_type = 'external_exc'

        elif cell_id in population_parameters['inh_ids']:
            local_synapse_types = ['exc_inh', 'inh_inh']
            # thalamic_synapse_type = 'thalamic_inh'
            # external_synapse_type = 'external_inh'

        for synapse_type in local_synapse_types:

            print("Setting up local synapses: ", synapse_type)

            pre_ids = incoming_connections[cell_id]
            # n_synapses = len(pre_ids)

            for i_synapse, pre_id in enumerate(pre_ids):
                if pre_id in pre_cells[synapse_type]:
                    syn_idx = int(cell.get_rand_idx_area_norm(
                        **synapse_position_parameters[synapse_type]))
                    synapse_parameters[synapse_type].update({'idx': syn_idx})
                    synapse = LFPy.Synapse(cell,
                                           **synapse_parameters[synapse_type])
                    spike_times =\
                        local_sp_times[np.where(local_sp_ids == pre_id)[0]]
                    synapse.set_spike_times(spike_times)

        print("Setting up thalamic synapses")

        # Load thalamic input spike times, 1st column time,
        # 2nd column post cell id
        #   print "Loading thalamic input spikes"
#         thalamic_spikes_filename = population_parameters['input_dir'] \
#              +'ths/th_'+str(stimolo)+'_'+str(cell_id)+'.out'

#         print thalamic_spikes_filename
#
#         thalamic_spike_times = np.loadtxt(thalamic_spikes_filename)

#         synapse_ids =\
#                  np.random.randint(0,n_thalamic_synapses,len(thalamic_spike_times))

#         for i_synapse in xrange(n_thalamic_synapses):
#             syn_idx = int(cell.get_rand_idx_area_norm(\
#                         **synapse_position_parameters[thalamic_synapse_type]))
#             synapse_parameters[thalamic_synapse_type].update({'idx':syn_idx})
#             synapse = LFPy.Synapse(cell, \
#                             **synapse_parameters[thalamic_synapse_type])
#             spike_times = \
#                     thalamic_spike_times[np.where(synapse_ids==i_synapse)[0]]
#             synapse.set_spike_times(spike_times)

        print("Setting up external synapses")

        # Load external cortico-cortical input rate
        #  print "Loading external input spikes"
#         external_spikes_filename = population_parameters['input_dir'] \
#              + 'ccs/cc_'+str(stimolo)+'_'+str(cell_id)+'.out'
#         external_spike_times = np.loadtxt(external_spikes_filename)
#
#         synapse_ids =\
#              np.random.randint(0,n_external_synapses,len(external_spike_times))
#
#         for i_synapse in xrange(n_external_synapses):
#             syn_idx = int(cell.get_rand_idx_area_norm(\
#                         **synapse_position_parameters[external_synapse_type]))
#
#             synapse_parameters[external_synapse_type].update({'idx':syn_idx})
#             synapse = LFPy.Synapse(cell,\
#                             **synapse_parameters[external_synapse_type])
#             spike_times =\
#                 external_spike_times[np.where(synapse_ids==i_synapse)[0]]
#             synapse.set_spike_times(spike_times)

        # Run simulation
        print("Running simulation...")
        cell.simulate(rec_imem=True)

        # Calculate LFP
        print("Calculating LFP")
        electrode = LFPy.RecExtElectrode(cell, **electrode_parameters)
        electrode.calc_lfp()

        # Store data
        print("Storing data")
        output_data['LFP'][cell_id] = electrode.LFP
        output_data['somav'][cell_id] = cell.somav
        output_data['somapos'][cell_id] = cell.somapos

    output_data['tvec'] = cell.tvec

    print("Saving data to file")

    if not os.path.isdir(population_parameters['save_to_dir']):
        os.mkdir(population_parameters['save_to_dir'])
    print(output_data)
    pickle.dump(output_data, open(
        population_parameters['save_to_dir'] + data_name + str(stimolo), "wb"))
Ejemplo n.º 8
0
#define parameters for extracellular recording electrode, using optional method
electrodeParameters = {
    'sigma': 0.3,  # extracellular conductivity
    'x': X.flatten(),  # x,y,z-coordinates of contact points
    'y': Y.flatten(),
    'z': Z.flatten(),
    'method': 'soma_as_point',  #treat soma segment as sphere source
}

################################################################################
# Main simulation procedure, setting up extracellular electrode, cell, synapse
################################################################################

#create extracellular electrode object
electrode = LFPy.RecExtElectrode(**electrodeParameters)

#Initialize cell instance, using the LFPy.Cell class
cell = LFPy.Cell(**cellParameters)
#set the position of midpoint in soma to Origo (not needed, this is the default)
cell.set_pos(x=0, y=0, z=0)
#rotate the morphology 90 degrees around z-axis
cell.set_rotation(z=np.pi / 2)

#attach synapse with parameters and set spike time
synapse = LFPy.Synapse(cell, **synapseParameters)
synapse.set_spike_times(np.array([1]))

#perform NEURON simulation, results saved as attributes in the cell instance
cell.simulate(electrode=electrode)
Ejemplo n.º 9
0
def compute_h(L_dend, r_dend, r_soma, cellParams, synParams, electrodeParams, section='soma'):
    # create ball soma and stick dendrite model
    soma = neuron.h.Section(name='soma')
    soma.diam = r_soma*2
    soma.L = r_soma*2
    # NOTE: Consider setting soma diameter and length by preserving
    # input impedance from network point neurons for a fixed width and length
    # dendrite section.
    
    dend = neuron.h.Section(name='dend')
    dend.diam = r_dend*2.
    dend.L = L_dend
    
    # connect
    dend.connect(soma(1.), 0.)
    
    # define SectionList
    morphology=neuron.h.SectionList()
    morphology.append(sec=soma)
    morphology.append(sec=dend)
    
    # instantiate LFPy.Cell class
    cell = LFPy.Cell(morphology=morphology, **cellParams)
    cell.set_pos(0, 0, 0)
    cell.set_rotation(y=-np.pi/2)
        
    # instantiate LFPy.Synapse class
    try:
        assert(hasattr(neuron.h, 'AlphaISyn'))
    except AttributeError:
        raise AttributeError('no AlphaISyn mech found, run nrnivmodl inside this folder')
    
    # create synapses, distribute across entire section so we divide
    # the total synapse input by number of segments in section
    idx = cell.get_idx(section=section)
    weight = synParams.pop('weight')
    for i in idx:
        syn = LFPy.Synapse(cell, idx=i, weight=weight / idx.size,
                           **synParams)
        syn.set_spike_times(np.array([lag]))
    
    # run simulation of extracellular potentials
    cell.simulate(rec_imem=True)
    
    # instantiate RexExtElectrode class and compute the electrode signals    
    electrode = LFPy.RecExtElectrode(cell=cell, **electrodeParams)
    electrode.calc_lfp()
    
    
    if test_plots:
        from  matplotlib.animation import FuncAnimation
        
        electrode_xz = LFPy.RecExtElectrode(cell=cell, **electrodeParams_xz)
        electrode_xz.calc_lfp()
        
        absmax = abs(electrode_xz.LFP).max() / 2.
        
        fig, ax = plt.subplots(1,1)
        fig.suptitle(section)
        im = ax.imshow(electrode_xz.LFP[:, 250].reshape(X_xz.shape), cmap='PRGn', vmin=-absmax, vmax=absmax, interpolation='nearest', origin='lower',
                  extent=[electrode_xz.x.min(), electrode_xz.x.max(), electrode_xz.z.min(), electrode_xz.z.max()])
        plt.colorbar(im)
        def animate(i):
            im.set_data(electrode_xz.LFP[:, 250+i].reshape(X_xz.shape))
            return im,
        
        anim = FuncAnimation(fig, animate,
                             frames=100, interval=20)
        plt.show()
        electrode_xz.cell = None
        
    # clean up namespace, delete all section references
    electrode.cell = None
    syn = None
    cell = None
    morphology = None
    dend = None
    soma = None
    
    return electrode.LFP
Ejemplo n.º 10
0
# Define electrode parameters
MEA_electrode_parameters = {
    'sigma_T': 0.3,  # extracellular conductivity
    'sigma_G': 0.0,  # MEA glass electrode plate conductivity
    'sigma_S': 1.5,  # Saline bath conductivity
    'x': X.flatten(),  # electrode requires 1d vector of positions
    'y': Y.flatten(),
    'z': Z.flatten(),
    "method": "soma_as_point",
    'N': np.array([[0, 0, 1]] * X.size),  #surface normals
    'r': 50,  # contact site radius
    'n': 100,  # datapoints for averaging,
    'h': 300,
    "seedvalue": 12,
    "squeeze_cell_factor": 0.6,
}

# Run simulation, electrode object argument in cell.simulate
print("running simulation...")
cell.simulate(rec_imem=True, rec_vmem=True)

# Create electrode objects
electrode = LFPy.RecExtElectrode(cell, **grid_electrode_parameters)
MEA = LFPy.RecMEAElectrode(cell, **MEA_electrode_parameters)

# Calculate LFPs
MEA.calc_lfp()
electrode.calc_lfp()
plot_results(cell, synapse, MEA, electrode)
plt.show()
Ejemplo n.º 11
0
Ny = hstep.shape

x_elec = np.tile(hstep, N)
y_elec = np.sort(np.tile(vstep, Ny))[::-1]
z_elec = np.zeros(x_elec.shape)


meshgrid = {
        'sigma':0.33,
        'x': x_elec,
        'y': y_elec, 
        'z': z_elec,
        }

# Electrodes initialization
meshgrid_electrodes = LFPy.RecExtElectrode(cell, **meshgrid)  
meshgrid_electrodes.calc_lfp()
                
                
                
# =============================================================================
# ================================= plot and save  ===============================
# =============================================================================
                
timeind = (cell.tvec > np.argmax(cell.somav)*st-3) & (cell.tvec <= np.argmax(cell.somav)*st+5)


fileout="Vlfpy_BS"+"_LA"+LA+"_DA"+DA+"_LD"+LD+"_DD"+DD+"demo.txt"
np.savetxt(fileout,meshgrid_electrodes.LFP.T[timeind])

fileout2="Vm_BS"+"_LA"+LA+"_DA"+DA+"_LD"+LD+"_DD"+DD+"demo.txt"
Ejemplo n.º 12
0
def test_white_noise_input():

    input = 'apic'
    timeres = 2**-4
    cut_off = 0
    tstopms = 1000
    tstartms = 0
    cellname = 'c12861'
    holding_potential = -60
    model_path = cellname
    use_channels = ['Im']
    lambda_f = 100

    cell_params = {
        'morphology': join(model_path, '%s.hoc' % cellname),
        #'rm' : 30000,               # membrane resistance
        #'cm' : 1.0,                 # membrane capacitance
        #'Ra' : 100,                 # axial resistance
        'v_init': holding_potential,             # initial crossmembrane potential
        'passive': False,           # switch on passive mechs
        'nsegs_method': 'lambda_f',  # method for setting number of segments,
        'lambda_f': lambda_f,           # segments are isopotential at this frequency
        'timeres_NEURON': timeres,   # dt of LFP and NEURON simulation.
        'timeres_python': timeres,
        'tstartms': tstartms,          # start time, recorders start at t=0
        'tstopms': tstopms,
        'custom_fun': [active_declarations],  # will execute this function
        'custom_fun_args': [{'use_channels': use_channels,
                             'cellname': cellname,
                             'hold_potential': holding_potential}],
    }

    cell = LFPy.Cell(**cell_params)

    apic_idx = cell.get_closest_idx(x=0, y=0, z=350)
    soma_idx = 0

    if input is 'apic':
        input_idx = apic_idx
    else:
        input_idx = soma_idx
    plt.seed(1234)
    print input_idx, holding_potential
    sim_params = {'rec_vmem': True,
                  'rec_imem': True}
    import aLFP
    num_elecs = 5
    electrode_parameters = {
            'sigma': 0.3,
            'x': np.ones(num_elecs) * 100,
            'y': np.zeros(num_elecs),
            'z': np.linspace(-200, 600, num_elecs)
    }
    electrode = LFPy.RecExtElectrode(**electrode_parameters)
    elec_clr = ['cyan', 'orange', 'pink', 'g', 'y']

    cell, syn, noise_vec = _make_white_noise_stimuli(cell, input_idx)
    cell.simulate(electrode=electrode, **sim_params)

    freqs, [psd_s] = aLFP.return_freq_and_psd(cell.tvec, cell.imem[soma_idx, :])
    freqs, [psd_a] = aLFP.return_freq_and_psd(cell.tvec, cell.imem[apic_idx, :])
    freqs, psd_e = aLFP.return_freq_and_psd(cell.tvec, electrode.LFP)

    plt.subplot(121, title="Number of compartments: %d" % cell.totnsegs)
    [plt.plot([cell.xstart[idx], cell.xend[idx]], [cell.zstart[idx], cell.zend[idx]], c='k') for idx in xrange(cell.totnsegs)]
    plt.plot(cell.xmid[soma_idx], cell.zmid[soma_idx], 'rD')
    plt.plot(cell.xmid[apic_idx], cell.zmid[apic_idx], 'bD')
    [plt.plot(electrode.x[idx], electrode.z[idx], 'o', c=elec_clr[idx]) for idx in xrange(num_elecs)]

    plt.subplot(322, xlim=[1, 1000], title='Soma imem psd', ylim=[1e-8, 1e-4])
    plt.loglog(freqs, psd_s)
    plt.grid(True)

    plt.subplot(324, xlim=[1, 1000], title='Apic imem psd', ylim=[1e-8, 1e-3])
    plt.loglog(freqs, psd_a)
    plt.grid(True)

    plt.subplot(326, xlim=[1, 1000], title='LFP', ylim=[1e-10, 1e-5])
    [plt.loglog(freqs, psd_e[idx], c=elec_clr[idx]) for idx in xrange(num_elecs)]
    plt.grid(True)

    plt.savefig('wn_test_Im_apic_whole.png')
Ejemplo n.º 13
0
                cell.set_pos(x=x_loc,
                             y=y_loc,
                             z=np.random.normal(
                                 loc=parameters['heights']['soma'], scale=50))
                insert_synapses(parameters['synapse_parameters'],
                                synapse_positions[k], parameters['n_syn'],
                                parameters['heights'], cell)
                cell.simulate(rec_imem=True,
                              rec_vmem=True,
                              rec_current_dipole_moment=True)

                v.append(cell.vmem[0])  #storing vmem in soma, not used
                im.append(cell.imem)  #storing all imem, not used

                #calculate LFP
                elec = LFPy.RecExtElectrode(cell, **electrodeParameters)
                elec.calc_lfp()
                cell_LFP.append(elec.LFP)

                #calculate EEG (using 4-sphere)
                P = cell.current_dipole_moment
                somapos = np.array(
                    [cell.xmid[0], cell.ymid[0], radii[0] + cell.zmid[0]])
                r_soma_syns = [
                    cell.get_intersegment_vector(idx0=0, idx1=i)
                    for i in cell.synidx
                ]
                r_mid = np.average(r_soma_syns, axis=0)
                r_mid = somapos + r_mid / 2.
                eeg_coords_top = np.array([[0., 0., radii[3] - rad_tol]])
                four_sphere_top = LFPy.FourSphereVolumeConductor(
Ejemplo n.º 14
0
laminar_elec_params = {
    'sigma': 0.3,      # extracellular conductivity
    'x': laminar_x,  # electrode requires 1d vector of positions
    'y': laminar_y,
    'z': laminar_z
}

# Run simulation, electrode object argument in cell.simulate
print("running simulation...")
cell.simulate(rec_imem=True, rec_vmem=True)





laminar_electrode = LFPy.RecExtElectrode(cell, **laminar_elec_params)
laminar_electrode.calc_lfp()
laminar_LFP = 1e3 * laminar_electrode.LFP

grid_electrode = LFPy.RecExtElectrode(cell, **grid_elec_params)
grid_electrode.calc_lfp()
grid_LFP = 1e3 * grid_electrode.LFP

grid_LFP -= grid_LFP[:, 0, None]

max_elec, max_time_idx = np.unravel_index(np.abs(laminar_LFP).argmax(), grid_LFP.shape)

# plot_EAP(cell, grid_LFP, laminar_LFP, None,
#                             grid_x, grid_z, laminar_elec_params,  sim_name, savefolder)

plot_spatial_time_traces(cell, grid_LFP, grid_elec_params,  sim_name, savefolder)
            total_conncount += conncount
            total_syncount += syncount
    
    # tic-toc
    if RANK == 0:
        create_connections_time = time() - tic
        print('Network build finished with {} connections and {} synapses in {} seconds'.format(
            total_conncount, total_syncount, create_connections_time))
    tic = time()


    ############################################################################
    # Set up extracellular electrode
    ############################################################################
    if PSET.COMPUTE_LFP:
        electrode = LFPy.RecExtElectrode(**PSET.electrodeParams)
    else:
        electrode = None
    
    if PSET.COMPUTE_ECOG:
        ecog_electrode = LFPy.RecMEAElectrode(**PSET.ecogParameters)
        electrode = [electrode, ecog_electrode]


    ############################################################################
    # Recording of additional variables
    ############################################################################
    if RANK == 0:
        network.t = neuron.h.Vector()
        network.t.record(neuron.h._ref_t)
    else:
Ejemplo n.º 16
0
def return_extracellular_spike(cell, cell_name, model_type,\
                            electrode_parameters, limits, rotation, pos=None):
    """    Calculate extracellular spike on MEA 
           at random position relative to cell

    Parameters:
    -----------
    cell: object
        cell object from LFPy
    cell_name: string
        name of cell model
    electrode_parameters: dict
        parameters to initialize LFPy.RecExtElectrode
    limits: array_like
        boundaries for neuron locations, shape=(3,2)
    rotation: string 
        random rotation to apply to the neuron ('Norot', '3drot', 'physrot')
    pos: array_like, (optional, default None)
        Can be used to set the cell soma to a specific position. If ``None``,
        the random position is used.
    Returns:
    --------
    Extracellular spike for each MEA contact site
    """
    def get_xyz_angles(R):
        ''' Get rotation angles for each axis from rotation matrix
        
        Parameters;
        -----------
        R : matrix
            3x3 rotation matrix

        Returns:
        --------
        R_z : float
        R_y : float
        R_x : float
            Three angles for rotations around axis, defined by R = R_z.R_y.R_x
        '''
        rot_x = np.arctan2(R[2, 1], R[2, 2])
        rot_y = np.arcsin(-R[2, 0])
        rot_z = np.arctan2(R[1, 0], R[0, 0])
        return rot_x, rot_y, rot_z

    def get_rnd_rot_Arvo():
        """ Generate uniformly distributed random rotation matrices
        see: 'Fast Random Rotation Matrices' by Arvo (1992)
        
        Returns:
        --------
        R : 3x3 matrix
            random rotation matrix
        """
        gamma = np.random.uniform(0, 2. * np.pi)
        rotation_z = np.matrix([[np.cos(gamma), -np.sin(gamma), 0],
                                [np.sin(gamma),
                                 np.cos(gamma), 0], [0, 0, 1]])
        x = np.random.uniform(size=2)
        v = np.array([
            np.cos(2. * np.pi * x[0]) * np.sqrt(x[1]),
            np.sin(2. * np.pi * x[0]) * np.sqrt(x[1]),
            np.sqrt(1 - x[1])
        ])
        H = np.identity(3) - 2. * np.outer(v, v)
        M = -np.dot(H, rotation_z)
        return M

    def check_solidangle(matrix, pre, post, polarlim):
        """ Check whether a matrix rotates the vector 'pre' into a region
            defined by 'polarlim' around the vector 'post'

        Parameters:
        -----------
        matrix : matrix
            3x3 rotation matrix
        pre : array_like
            3-dim vector to be rotated
        post : array_like
            axis of the cones defining the post-rotation region
        polarlim : [float,float]
            Angles specifying the opening of the inner and outer cone 
            (aperture = 2*polarlim),
            i.e. the angle between rotated pre vector and post vector has to ly 
            within these polar limits.  

        Returns:
        --------
        test : bool
            True if the vector np.dot(matrix,pre) lies inside the specified region.
        """
        postest = np.dot(matrix, pre)
        c = np.dot(post / np.linalg.norm(post),
                   postest / np.linalg.norm(postest))
        if np.cos(np.deg2rad(polarlim[1])) <= c <= np.cos(
                np.deg2rad(polarlim[0])):
            return True
        else:
            return False

    electrodes = LFPy.RecExtElectrode(cell, **electrode_parameters)
    '''Rotate neuron'''
    if rotation == 'Norot':
        # orientate cells in z direction
        if model_type == 'bbp':
            x_rot = np.pi / 2.
            y_rot = 0
            z_rot = 0
    elif rotation == '3drot':
        if model_type == 'bbp':
            x_rot_offset = np.pi / 2.  # align neuron with z axis
            y_rot_offset = 0  # align neuron with z axis
            z_rot_offset = 0  # align neuron with z axis

        x_rot, y_rot, z_rot = get_xyz_angles(np.array(get_rnd_rot_Arvo()))
        x_rot = x_rot + x_rot_offset
        y_rot = y_rot + y_rot_offset
        z_rot = z_rot + z_rot_offset

    elif rotation == 'physrot':
        polarlim, pref_orient = get_physrot_specs(cell_name, model_type)
        if model_type == 'bbp':
            x_rot_offset = np.pi / 2.  # align neuron with z axis
            y_rot_offset = 0  # align neuron with z axis
            z_rot_offset = 0  # align neuron with z axis
        while True:
            R = np.array(get_rnd_rot_Arvo())
            if polarlim is None or pref_orient is None:
                valid = True
            else:
                valid = check_solidangle(R, [0., 0., 1.], pref_orient,
                                         polarlim)
            if valid:
                x_rot, y_rot, z_rot = get_xyz_angles(R)
                x_rot = x_rot + x_rot_offset
                y_rot = y_rot + y_rot_offset
                z_rot = z_rot + z_rot_offset
                break
    else:
        x_rot = 0
        y_rot = 0
        z_rot = 0
    '''Move neuron randomly'''
    x_rand = np.random.uniform(limits[0][0], limits[0][1])
    y_rand = np.random.uniform(limits[1][0], limits[1][1])
    z_rand = np.random.uniform(limits[2][0], limits[2][1])

    if pos == None:
        cell.set_pos(x_rand, y_rand, z_rand)
    else:
        cell.set_pos(pos[0], pos[1], pos[2])
    cell.set_rotation(x=x_rot, y=y_rot, z=z_rot)
    pos = [x_rand, y_rand, z_rand]
    rot = [x_rot, y_rot, z_rot]

    electrodes.calc_lfp()

    # Reverse rotation to bring cell back into initial rotation state
    rev_rot = [-rot[e] for e in range(len(rot))]
    cell.set_rotation(rev_rot[0], rev_rot[1], rev_rot[2], rotation_order='zyx')

    return 1000 * electrodes.LFP, pos, rot, electrodes.offsets
Ejemplo n.º 17
0
def run_cell_simulation(make_ca_spike, dt, cell_name, grid_elec_params,
                        elec_params):

    T = 100

    if cell_name == 'almog':
        model_folder = join('cell_models', 'almog')

        neuron.load_mechanisms(model_folder)
        os.chdir(model_folder)
        cell_parameters = {
            'morphology': join('A140612.hoc'),
            'v_init': -62,
            'passive': False,
            'nsegs_method': None,
            'dt': dt,  # [ms] Should be a power of 2
            'tstart': -200,  # [ms] Simulation start time
            'tstop': T,  # [ms] Simulation end time
            'custom_code':
            [join('cell_model.hoc')]  # Loads model specific code
        }

        cell = LFPy.Cell(**cell_parameters)
        os.chdir(join('..', '..'))
        cell.set_rotation(x=np.pi / 2, y=0.1)
    elif cell_name == 'hay':

        model_folder = join('cell_models', 'hay', 'L5bPCmodelsEH')
        neuron.load_mechanisms(join(model_folder, "mod"))

        ##define cell parameters used as input to cell-class
        cellParameters = {
            'morphology':
            join(model_folder, "morphologies", "cell1.asc"),
            'templatefile': [
                join(model_folder, "models", "L5PCbiophys3.hoc"),
                join(model_folder, "models", "L5PCtemplate.hoc")
            ],
            'templatename':
            'L5PCtemplate',
            'templateargs':
            join(model_folder, "morphologies", "cell1.asc"),
            'passive':
            False,
            'nsegs_method':
            None,
            'dt':
            dt,
            'tstart':
            -200,
            'tstop':
            T,
            'v_init':
            -60,
            'celsius':
            34,
            'pt3d':
            True,
        }
        cell = LFPy.TemplateCell(**cellParameters)
        cell.set_rotation(x=np.pi / 2, y=0.1)

    plot_idxs = [cell.somaidx[0], cell.get_closest_idx(z=500)]
    idx_clr = {idx: ['b', 'orange'][num] for num, idx in enumerate(plot_idxs)}

    if cell_name == 'hay':
        weights = [0.07, 0.15]
    elif cell_name == 'almog':
        weights = [0.05, 0.15]

    delay = 30
    synapse_s = LFPy.Synapse(cell,
                             idx=cell.get_closest_idx(z=0),
                             syntype='Exp2Syn',
                             weight=weights[0],
                             tau1=0.1,
                             tau2=1.)
    synapse_s.set_spike_times(np.array([delay]))

    synapse_a = None
    if make_ca_spike:
        synapse_a = LFPy.Synapse(cell,
                                 idx=cell.get_closest_idx(z=400),
                                 syntype='Exp2Syn',
                                 weight=weights[1],
                                 tau1=0.1,
                                 tau2=10.)
        synapse_a.set_spike_times(np.array([delay]))
    cell.simulate(rec_imem=True, rec_vmem=True)
    print("MAX |I_mem(soma, apic)|: ",
          np.max(np.abs(cell.imem[plot_idxs]), axis=1))

    elec = LFPy.RecExtElectrode(cell, **elec_params)
    elec_LFP = 1e3 * elec.get_transformation_matrix() @ cell.imem
    elec_LFP -= elec_LFP[:, 0, None]

    grid_electrode = LFPy.RecExtElectrode(cell, **grid_elec_params)
    grid_LFP = 1e3 * grid_electrode.get_transformation_matrix() @ cell.imem
    grid_LFP -= grid_LFP[:, 0, None]

    cdm = LFPy.CurrentDipoleMoment(cell)
    cdm = cdm.get_transformation_matrix() @ cell.imem
    cdm -= cdm[:, 0, None]

    cell_data_dict = {
        "vmem": cell.vmem.copy(),
        "tvec": cell.tvec.copy(),
        "elec_LFP": elec_LFP.copy(),
        "grid_LFP": grid_LFP.copy(),
        "cdm": cdm.copy(),
        "cell_x": cell.x.copy(),
        "cell_z": cell.z.copy(),
    }
    synapse_s = None
    synapse_a = None
    cell.__del__()
    return cell_data_dict, idx_clr, plot_idxs
Ejemplo n.º 18
0
                                     templatename=templatename,
                                     templateargs=1 if add_synapses else 0,
                                     tstop=tstop,
                                     dt=dt,
                                     nsegs_method=None)

            #set view as in most other examples
            cell.set_rotation(x=np.pi / 2)

            pointProcess = LFPy.StimIntElectrode(cell, **PointProcParams)

            electrode = LFPy.RecExtElectrode(x=np.array([-40, 40., 0, 0]),
                                             y=np.array([0, 0, -40, 40]),
                                             z=np.zeros(4),
                                             sigma=0.3,
                                             r=5,
                                             n=50,
                                             N=np.array([[1, 0, 0], [1, 0, 0],
                                                         [1, 0, 0], [1, 0,
                                                                     0]]),
                                             method='soma_as_point')

            #run simulation
            cell.simulate(electrode=electrode)

            #electrode.calc_lfp()
            LFP = electrode.LFP
            if apply_filter:
                LFP = ss.filtfilt(b, a, LFP, axis=-1)

            #detect action potentials from intracellular trace
            AP_train = np.zeros(cell.somav.size, dtype=int)
Ejemplo n.º 19
0
def animate_ca_spike():
    # Deprecated, and not updated for LFPy2.2 and newer
    dt = 2**-5
    cell_name = 'hay'

    jitter_std = 10
    num_trials = 1000

    # Create a grid of measurement locations, in (mum)
    grid_x, grid_z = np.mgrid[-750:751:25, -750:1301:25]
    grid_y = np.zeros(grid_x.shape)

    # Define electrode parameters
    grid_elec_params = {
        'sigma': 0.3,  # extracellular conductivity
        'x': grid_x.flatten(),  # electrode requires 1d vector of positions
        'y': grid_y.flatten(),
        'z': grid_z.flatten()
    }

    elec_x = np.array([
        30,
    ])
    elec_y = np.array([
        0,
    ])
    elec_z = np.array([
        0,
    ])

    num = 11
    levels = np.logspace(-2.5, 0, num=num)
    scale_max = 100.

    levels_norm = scale_max * np.concatenate((-levels[::-1], levels))
    bwr_cmap = plt.cm.get_cmap('bwr_r')  # rainbow, spectral, RdYlBu

    colors_from_map = [
        bwr_cmap(i * np.int(255 / (len(levels_norm) - 2)))
        for i in range(len(levels_norm) - 1)
    ]
    colors_from_map[num - 1] = (1.0, 1.0, 1.0, 1.0)

    cell, idx_clr, plot_idxs = run_cell_simulation(make_ca_spike=False,
                                                   dt=dt,
                                                   cell_name=cell_name)
    grid_electrode = LFPy.RecExtElectrode(cell, **grid_elec_params)
    grid_electrode.calc_lfp()
    grid_LFP = 1e3 * grid_electrode.LFP

    grid_LFP -= grid_LFP[:, 0, None]
    for time_idx in range(len(cell.tvec))[2000:]:
        plt.close("all")
        fig = plt.figure(figsize=[5, 4])
        fig.text(0.5,
                 0.95,
                 "T={:1.1f} ms".format(cell.tvec[time_idx]),
                 ha="center")
        ax_ = fig.add_axes([0.4, 0.14, 0.6, 0.88],
                           xticks=[],
                           yticks=[],
                           aspect=1,
                           frameon=False)
        cax = fig.add_axes([0.5, 0.15, 0.4, 0.01])
        ax_vm = fig.add_axes([0.25, 0.65, 0.2, 0.3],
                             ylabel="membrane\npotential\n(mV)",
                             xlabel="time (ms)")
        ax_cdm = fig.add_axes([0.25, 0.2, 0.2, 0.3],
                              ylabel="current dipole\nmoment\n(µA$\cdot$µm)",
                              xlabel="time (ms)")
        grid_LFP_ = grid_LFP[:, time_idx].reshape(grid_x.shape)
        [
            ax_.plot([cell.xstart[idx], cell.xend[idx]],
                     [cell.zstart[idx], cell.zend[idx]],
                     c='gray') for idx in range(cell.totnsegs)
        ]
        ax_.plot([350, 350], [-540, -640], c='k', lw=2)
        ax_.text(360, -590, "100 $\mu$m", va='center')
        ep_intervals = ax_.contourf(grid_x,
                                    grid_z,
                                    grid_LFP_,
                                    zorder=-2,
                                    colors=colors_from_map,
                                    levels=levels_norm,
                                    extend='both')

        ax_.contour(grid_x,
                    grid_z,
                    grid_LFP_,
                    colors='k',
                    linewidths=(1),
                    zorder=-2,
                    levels=levels_norm)

        cbar = fig.colorbar(ep_intervals,
                            cax=cax,
                            orientation='horizontal',
                            format='%.0E',
                            extend='max')

        cbar.set_ticks(
            np.array([-1, -0.1, -0.01, 0, 0.01, 0.1, 1]) * scale_max)
        cax.set_xticklabels(np.array(
            np.array([-1, -0.1, -0.01, 0, 0.01, 0.1, 1]) * scale_max,
            dtype=int),
                            fontsize=7,
                            rotation=45)
        cbar.set_label('$\phi$ (µV)', labelpad=-5)
        [
            ax_vm.plot(cell.tvec, cell.vmem[idx], c=idx_clr[idx])
            for idx in plot_idxs
        ]
        ax_cdm.plot(cell.tvec, cell.current_dipole_moment[:, 2], c='k')
        ax_vm.axvline(cell.tvec[time_idx], c='gray', lw=1, ls='--')
        ax_cdm.axvline(cell.tvec[time_idx], c='gray', lw=1, ls='--')
        simplify_axes([ax_vm, ax_cdm])
        anim_fig_folder = "anim_no_ca"
        os.makedirs(anim_fig_folder, exist_ok=True)
        plt.savefig(
            join(anim_fig_folder, "cell_ca_cont_{:04d}.png".format(time_idx)))
Ejemplo n.º 20
0
        #Have to position and rotate the cells!
        cell.set_rotation(z=z_rotation[cell_id], **xy_rotations)
        cell.set_pos(x=x_cell_pos[cell_id])

        for i_syn in range(n_synapses):
            syn_idx = cell.get_rand_idx_area_norm()
            synapse_parameters.update({'idx': syn_idx})
            synapse = LFPy.Synapse(cell, **synapse_parameters)
            synapse.set_spike_times(pre_syn_sptimes[pre_syn_ids[cell_id %
                                                                SIZE][i_syn]])

        #run the cell simulation
        cell.simulate(rec_imem=True)

        #set up the extracellular device
        point_electrode = LFPy.RecExtElectrode(cell,
                                               **point_electrode_parameters)
        point_electrode.calc_lfp()

        # sum LFP on this RANK
        summed_LFP += point_electrode.LFP[0]

        # send LFP of this cell to RANK 0
        if RANK != 0:
            COMM.send(point_electrode.LFP[0], dest=0)
        else:
            single_LFPs += [point_electrode.LFP[0]]

    # collect single LFP contributions on RANK 0
    if RANK == 0:
        if cell_id % SIZE != RANK:
            single_LFPs += [COMM.recv(source=cell_id % SIZE)]
Ejemplo n.º 21
0
def calc_extracellular(cell_model_folder,
                       load_sim_folder,
                       save_sim_folder=None,
                       seed=0,
                       verbose=False,
                       position=None,
                       save=True,
                       custom_return_cell_function=None,
                       **kwargs):
    """
    Loads data from previous cell simulation, and use results to generate
    arbitrary number of spikes above a certain noise level.

    Parameters:
    -----------
    cell_model_folder : string
        Path to folder where cell model is saved.
    model_type : string
        Cell model type (e.g. 'bbp')
    load_sim_folder : string
        Path to folder from which NEURON simulation results (currents, membrane potential) are loaded
    save_sim_folder : string
        Path to folder where to save EAP data
    position : array
        3D position of the soma (optional, default is None and the cell is randomly located within specified limits)
    custom_return_cell_function : function
        Python function to to return an LFPy cell from the cell_model_folder
    save : bool
        If True eaps are saved in the 'save_sim_folder'. If False eaps, positions, and rotations are returned as arrays
    **kwargs: keyword arguments
        Template generation parameters (use mr.get_default_template_parameters() to retrieve the arguments)

    Returns:
    --------
        nothing, but saves the result
    """
    LFPy, neuron = import_LFPy_neuron()
    cell_model_folder = Path(cell_model_folder)
    cell_name = cell_model_folder.parts[-1]
    cell_save_name = cell_name
    load_sim_folder = Path(load_sim_folder)
    np.random.seed(seed)

    T = kwargs['sim_time'] * 1000
    dt = kwargs['dt']
    rotation = kwargs['rot']
    nobs = kwargs['n']
    ncontacts = kwargs['ncontacts']
    overhang = kwargs['overhang']
    x_lim = kwargs['xlim']
    y_lim = kwargs['ylim']
    z_lim = kwargs['zlim']
    min_amp = kwargs['min_amp']
    MEAname = kwargs['probe']
    drifting = kwargs['drifting']
    if drifting:
        max_drift = kwargs['max_drift']
        min_drift = kwargs['min_drift']
        drift_steps = kwargs['drift_steps']
        drift_x_lim = kwargs['drift_xlim']
        drift_y_lim = kwargs['drift_ylim']
        drift_z_lim = kwargs['drift_zlim']

    if custom_return_cell_function is None:
        return_function = return_bbp_cell
        model_type = 'bbp'
    else:
        return_function = custom_return_cell_function
        model_type = 'custom'

    cuts = kwargs['cut_out']
    cut_out = [int(cuts[0] / dt), int(cuts[1] / dt)]

    cell = return_function(cell_model_folder, end_T=T, dt=dt, start_T=0)

    # Load data from previous cell simulation
    imem_file = [
        f for f in load_sim_folder.iterdir()
        if cell_name in f.name and 'imem' in f.name
    ][0]
    vmem_file = [
        f for f in load_sim_folder.iterdir()
        if cell_name in f.name and 'vmem' in f.name
    ][0]
    i_spikes = np.load(str(imem_file))
    v_spikes = np.load(str(vmem_file))
    cell.tvec = np.arange(i_spikes.shape[-1]) * dt

    save_spikes = []
    save_pos = []
    save_rot = []
    save_offs = []
    target_num_spikes = int(nobs)

    # load MEA info
    elinfo = mu.return_mea_info(electrode_name=MEAname)

    # Create save folder
    if save:
        assert save_sim_folder is not None, "Specify 'save_sim_folder' argument!"
        save_sim_folder = Path(save_sim_folder)
        sim_folder = save_sim_folder / rotation
        save_folder = sim_folder / f'tmp_{target_num_spikes}_{MEAname}'

        if not save_folder.is_dir():
            os.makedirs(str(save_folder))

    if verbose:
        print(f'Cell {cell_save_name} extracellular spikes to be simulated')

    mea = mu.return_mea(MEAname)
    if ncontacts > 1:
        electrodes = LFPy.RecExtElectrode(cell, probe=mea, n=ncontacts)
    else:
        electrodes = LFPy.RecExtElectrode(cell, probe=mea)
    pos = mea.positions
    elec_x = pos[:, 0]
    elec_y = pos[:, 1]
    elec_z = pos[:, 2]

    if x_lim is None:
        x_lim = [
            float(np.min(elec_x) - overhang),
            float(np.max(elec_x) + overhang)
        ]
    if y_lim is None:
        y_lim = [
            float(np.min(elec_y) - overhang),
            float(np.max(elec_y) + overhang)
        ]
    if z_lim is None:
        z_lim = [
            float(np.min(elec_z) - overhang),
            float(np.max(elec_z) + overhang)
        ]

    ignored = 0
    saved = 0
    i = 0

    while len(save_spikes) < target_num_spikes:
        if i > 1000 * target_num_spikes:
            if verbose:
                print("Gave up finding spikes above noise level for %s" %
                      cell_name)
            break
        spike_idx = np.random.randint(
            0,
            i_spikes.shape[0])  # Each cell has several spikes to choose from
        cell.imem = i_spikes[spike_idx, :, :]
        cell.somav = v_spikes[spike_idx, :]

        if not drifting:
            espikes, pos, rot, offs = return_extracellular_spike(
                cell=cell,
                cell_name=cell_name,
                model_type=model_type,
                electrodes=electrodes,
                limits=[x_lim, y_lim, z_lim],
                rotation=rotation,
                pos=position)
            # Method of Images for semi-infinite planes
            if elinfo['type'] == 'mea':
                espikes = espikes * 2

            if check_espike(espikes, min_amp):
                espikes = center_espike(espikes, cut_out)
                save_spikes.append(espikes)
                save_pos.append(pos)
                save_rot.append(rot)
                save_offs.append(offs)
                plot_spike = False
                if verbose:
                    print('Cell: ' + cell_name + ' Progress: [' +
                          str(len(save_spikes)) + '/' +
                          str(target_num_spikes) + ']')
                saved += 1
        else:
            espikes, pos, rot, offs = return_extracellular_spike(
                cell=cell,
                cell_name=cell_name,
                model_type=model_type,
                electrodes=electrodes,
                limits=[x_lim, y_lim, z_lim],
                rotation=rotation,
                pos=position)

            # Method of Images for semi-infinite planes
            if elinfo['type'] == 'mea':
                espikes = espikes * 2

            if x_lim[0] < pos[0] - drift_x_lim[0] < x_lim[1] and \
                    y_lim[0] < pos[1] - drift_y_lim[0] < y_lim[1] and \
                    z_lim[0] < pos[2] - drift_z_lim[0] < z_lim[1]:
                if check_espike(espikes, min_amp):
                    drift_ok = False
                    # fix rotation while drifting
                    cell.set_rotation(rot[0], rot[1], rot[2])
                    max_trials = 100
                    tr = 0
                    while not drift_ok and tr < max_trials:
                        init_pos = pos
                        # find drifting final position within drift limits
                        x_rand = np.random.uniform(
                            init_pos[0] + drift_x_lim[0],
                            init_pos[0] + drift_x_lim[1])
                        y_rand = np.random.uniform(
                            init_pos[1] + drift_y_lim[0],
                            init_pos[1] + drift_y_lim[1])
                        z_rand = np.random.uniform(
                            init_pos[2] + drift_z_lim[0],
                            init_pos[2] + drift_z_lim[1])
                        final_pos = [x_rand, y_rand, z_rand]
                        drift_dist = np.linalg.norm(
                            np.array(init_pos) - np.array(final_pos))

                        # check location and boundaries
                        if max_drift > drift_dist > min_drift and \
                                x_lim[0] < x_rand < x_lim[1] and \
                                y_lim[0] < y_rand < y_lim[1] and \
                                z_lim[0] < z_rand < z_lim[1]:
                            espikes, pos, rot_, offs = return_extracellular_spike(
                                cell=cell,
                                cell_name=cell_name,
                                model_type=model_type,
                                electrodes=electrodes,
                                limits=[x_lim, y_lim, z_lim],
                                rotation=None,
                                pos=final_pos)
                            # check final position spike amplitude
                            if check_espike(espikes, min_amp):
                                if verbose:
                                    print('Found final drifting position')
                                drift_ok = True
                            else:
                                tr += 1
                                pass
                        else:
                            tr += 1
                            pass

                    # now compute drifting templates
                    if drift_ok:
                        drift_spikes = []
                        drift_pos = []
                        drift_rot = []
                        drift_dist = np.linalg.norm(
                            np.array(init_pos) - np.array(final_pos))
                        drift_dir = np.array(final_pos) - np.array(init_pos)
                        for i, dp in enumerate(np.linspace(0, 1, drift_steps)):
                            pos_drift = init_pos + dp * drift_dir
                            espikes, pos, r_, offs = return_extracellular_spike(
                                cell=cell,
                                cell_name=cell_name,
                                model_type=model_type,
                                electrodes=electrodes,
                                limits=[x_lim, y_lim, z_lim],
                                rotation=None,
                                pos=pos_drift)
                            espikes = center_espike(espikes, cut_out)
                            drift_spikes.append(espikes)
                            drift_pos.append(pos)
                            drift_rot.append(rot)

                        # reverse rotation
                        rev_rot = [-r for r in rot]
                        cell.set_rotation(rev_rot[0],
                                          rev_rot[1],
                                          rev_rot[2],
                                          rotation_order='zyx')

                        drift_spikes = np.array(drift_spikes)
                        drift_pos = np.array(drift_pos)
                        if verbose:
                            print('Drift done from ', init_pos, ' to ',
                                  final_pos, ' with ', drift_steps, ' steps')

                        save_spikes.append(drift_spikes)
                        save_pos.append(drift_pos)
                        save_rot.append(rot)
                        save_offs.append(offs)
                        if verbose:
                            print('Cell: ' + cell_name + ' Progress: [' +
                                  str(len(save_spikes)) + '/' +
                                  str(target_num_spikes) + ']')
                        saved += 1
                    else:
                        if verbose:
                            print('Discarded for trials')
                else:
                    pass
            else:
                if verbose:
                    print('Discarded position: ', pos)
        i += 1

    save_spikes = np.array(save_spikes)
    save_pos = np.array(save_pos)
    save_rot = np.array(save_rot)

    if save:
        np.save(str(save_folder / f'eap-{cell_save_name}'), save_spikes)
        np.save(str(save_folder / f'pos-{cell_save_name}'), save_pos)
        np.save(str(save_folder / f'rot-{cell_save_name}'), save_rot)
    else:
        return save_spikes, save_pos, save_rot