Пример #1
0
    def test_calc_potential_from_multi_dipoles01(self):
        neuron.h('forall delete_section()')
        soma = neuron.h.Section(name='soma')
        dend1 = neuron.h.Section(name='dend1')
        dend2 = neuron.h.Section(name='dend2')
        dend1.connect(soma(0.5), 0)
        dend2.connect(dend1(1.0), 0)
        morphology = neuron.h.SectionList()
        morphology.wholetree()
        radii = [300, 400, 500, 600]
        sigmas = [0.3, 1.5, 0.015, 0.3]
        electrode_locs = np.array([[0., 0., 290.], [10., 90., 300.],
                                   [-90, 50., 400.], [110.3, -100., 500.]])
        cell = cell_w_synapse_from_sections(morphology)
        t_point = -1

        MD_4s = LFPy.FourSphereVolumeConductor(radii, sigmas, electrode_locs)
        dipoles, dipole_locs = cell.get_multi_current_dipole_moments()
        p = dipoles[:, t_point, :]
        Np = p.shape[0]
        Nt = 1
        Ne = electrode_locs.shape[0]
        pot_MD = MD_4s.calc_potential_from_multi_dipoles(cell)[:, t_point]
        pot_sum = np.zeros((Ne, Nt))
        for i in range(Np):
            dip = np.array([p[i]])
            dip_loc = dipole_locs[i]
            fs = LFPy.FourSphereVolumeConductor(radii, sigmas, electrode_locs)
            pot = fs.calc_potential(dip, dip_loc)
            pot_sum += pot
        pot_sum = pot_sum.reshape(4)
        np.testing.assert_almost_equal(pot_MD, pot_sum)
        np.testing.assert_allclose(pot_MD, pot_sum, rtol=1E-4)
Пример #2
0
    def test_calc_potential_from_multi_dipoles00(self):
        """test comparison between multi-dipoles and single dipole approach"""
        neuron.h('forall delete_section()')
        soma = neuron.h.Section(name='soma')
        dend1 = neuron.h.Section(name='dend1')
        dend2 = neuron.h.Section(name='dend2')
        dend1.connect(soma(0.5), 0)
        dend2.connect(dend1(1.0), 0)
        morphology = neuron.h.SectionList()
        morphology.wholetree()
        radii = [300, 400, 500, 600]
        sigmas = [0.3, 1.5, 0.015, 0.3]
        electrode_locs = np.array([[0., 0., 290.], [10., 90., 300.],
                                   [-90, 50., 400.], [110.3, -100., 500.]])
        cell = cell_w_synapse_from_sections(morphology)
        cell.set_pos(x=0, y=0, z=100)
        t_point = [1, 100, -1]

        MD_4s = LFPy.FourSphereVolumeConductor(radii, sigmas, electrode_locs)
        p, dipole_locs = cell.get_multi_current_dipole_moments(t_point)
        Np, Nt, Nd = p.shape
        Ne = electrode_locs.shape[0]
        pot_MD = MD_4s.calc_potential_from_multi_dipoles(cell, t_point)

        pot_sum = np.zeros((Ne, Nt))
        for i in range(Np):
            dip = p[i]
            dip_loc = dipole_locs[i]
            fs = LFPy.FourSphereVolumeConductor(radii, sigmas, electrode_locs)
            pot = fs.calc_potential(dip, dip_loc)
            pot_sum += pot

        np.testing.assert_almost_equal(pot_MD, pot_sum)
        np.testing.assert_allclose(pot_MD, pot_sum, rtol=1E-4)
Пример #3
0
 def test_check_params02(self):
     '''Test that ValueError is raised if electrode outside head'''
     radii = [1., 2., 4., 10.]
     sigmas = [1., 2., 4., 8.]
     r_el1 = np.array([[0., 0., 15.]])
     r_el2 = np.array([[0., 0., 1.5], [12., 0., 0.]])
     with np.testing.assert_raises(ValueError):
         LFPy.FourSphereVolumeConductor(radii, sigmas, r_el1)
     with np.testing.assert_raises(ValueError):
         LFPy.FourSphereVolumeConductor(radii, sigmas, r_el2)
Пример #4
0
 def test_check_params01(self):
     '''Test that Error is raised if invalid entries in sigmas'''
     radii = [1., 2., 4., 10.]
     sigmas1 = [1., 'str', 4., 8.]
     sigmas2 = [-1., 2., 4., 8.]
     sigmas3 = [1., 2., -4., 8.]
     sigmas4 = [1., 2., 4., -8.]
     r_el = np.array([[0., 0., 1.5]])
     with np.testing.assert_raises(ValueError):
         LFPy.FourSphereVolumeConductor(radii, sigmas1, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii, sigmas2, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii, sigmas3, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii, sigmas4, r_el)
Пример #5
0
 def test_check_params00(self):
     '''Test that invalid radius values raises RuntimeError'''
     radii1 = [-1., 2., 4., 8.]
     radii2 = [1., .5, 4., 8.]
     radii3 = [1., 2., 1.1, 8.]
     radii4 = [1., 2., 4., 1.]
     sigmas = [1., 2., 4., 8.]
     r_el = np.array([[0., 0., 1.5]])
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii1, sigmas, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii2, sigmas, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii3, sigmas, r_el)
     with np.testing.assert_raises(RuntimeError):
         LFPy.FourSphereVolumeConductor(radii4, sigmas, r_el)
Пример #6
0
def make_class_object(rz, r_el):
    '''Return class object fs'''
    radii = [79., 80., 85., 90.]
    sigmas = [0.3, 0.015, 15, 0.3]
    fs = LFPy.FourSphereVolumeConductor(radii, sigmas, r_el)
    fs._rz_params(rz)
    return fs
Пример #7
0
def return_eeg(cell, radii, sigmas, eeg_coords, morph_type):
    # compute current dipole moment
    P = cell.current_dipole_moment
    # set dipole position
    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)
    if morph_type == 'l5i':
        somapos = np.array([0., 0., radii[0] - 1200])
    else:
        somapos = np.array([0., 0., radii[0] - np.max(cell.zend) - 50])
    dipole_pos = r_mid + somapos
    cell.set_pos(x=somapos[0], y=somapos[1], z=somapos[2])

    # multi_dipoles, dipole_locs = cell.get_multi_current_dipole_moments()
    # t_point = 800
    # P_from_multi_dipoles = np.sum(multi_dipoles[:,t_point,:],axis=0)
    # print('single dipole:', P[t_point])
    # print('sum of multi-dipoles', P_from_multi_dipoles)
    # compute eeg with 4S model
    fs_eeg = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords)
    eeg = fs_eeg.calc_potential(P, dipole_pos)
    eeg_multidip = fs_eeg.calc_potential_from_multi_dipoles(cell)

    eeg_avg = np.average(eeg, axis=0)
    eeg_multidip_avg = np.average(eeg_multidip, axis=0)
    # convert from mV to pV:
    eeg_avg = eeg_avg * 1e9
    eeg_multidip_avg = eeg_multidip_avg * 1e9

    return eeg_avg, eeg_multidip_avg
Пример #8
0
    def test_calc_potential02(self):
        '''Test radial and tangential parts of dipole sums to dipole'''
        radii = [88000, 90000, 95000, 100000]
        sigmas = [0.3, 1.5, 0.015, 0.3]

        dips = np.array([[[1000., 0., 0.]], [[-1000., 0., 0.]],
                         [[0., 1000., 0.]], [[0., -1000., 0.]],
                         [[0., 0., 1000.]], [[0., 0., -1000.]]])

        p_locs = np.array([[87000., 0., 0.], [-87000., 0.,
                                              0.], [0., 87000., 0.],
                           [0., -87000., 0.], [0., 0., 87000],
                           [0., 0., -87000]])

        el_locs = np.array([[[99000., 0., 0.]], [[-99000., 0., 0.]],
                            [[0., 99000., 0.]], [[0., -99000., 0.]],
                            [[0., 0., 99000.]], [[0., 0., -99000.]]])

        for i in range(len(p_locs)):
            fs = LFPy.FourSphereVolumeConductor(radii, sigmas, el_locs[i])
            phi = fs.calc_potential(dips[i], p_locs[i])
            if i == 0:
                phi0 = phi[0][0]
            else:
                np.testing.assert_equal(phi0, phi[0][0])
Пример #9
0
def make_simple_class_object():
    '''Return class object fs'''
    radii = [1., 2., 4., 8.]
    sigmas = [1., 2., 4., 8.]
    rz1 = np.array([0., 0., .9])
    r_el = np.array([[0., 0., 1.5]])
    fs = LFPy.FourSphereVolumeConductor(radii, sigmas, r_el)
    fs._rz_params(rz1)
    return fs
def loadResults(experiment_id, filename, population_sizes, Z, tstop, dt,
                individual_EEG):

    print("\nLoading results...")

    # Summed current dipole moments and EEG
    summed_EEG_top = np.zeros(int(tstop / dt + 1))
    if individual_EEG == False:
        summed_dipole = np.zeros((int(tstop / dt + 1), 3))

    # CDM / EEG
    if individual_EEG:
        summed_EEG_top = pickle.load(open(
            '../multicompartment_network/results/' + experiment_id + "/" +
            filename + "_EEG", "rb"),
                                     encoding='latin1')
        summed_dipole = []
    else:
        summed_dipole = np.array(
            pickle.load(open(
                '../multicompartment_network/results/' + experiment_id + "/" +
                filename + "_CDM", "rb"),
                        encoding='latin1'))
        # Backward compatibility
        if len(summed_dipole[0]) > 3:
            summed_dipole = np.transpose(summed_dipole)

    # tvec
    tvec = pickle.load(open(
        '../multicompartment_network/results/' + experiment_id + "/" +
        filename + "tvec", "rb"),
                       encoding='latin1')

    # Sum all CDMs and compute the EEG
    if individual_EEG == False:
        import LFPy
        print("\nComputing EEG...")

        # Simulation parameters
        sim_params = pickle.load(open(  '../multicompartment_network/results/'+\
                                        experiment_id+"/"+filename+str(0),"rb") ,encoding='latin1')

        # EEG: four_sphere parameters
        radii = sim_params["radii"]
        sigmas = sim_params["sigmas"]
        rad_tol = sim_params["rad_tol"]

        r_mid = np.array([0., 0., 8500])
        eeg_coords_top = np.array([[0., 0., radii[3] - rad_tol]])
        four_sphere_top = LFPy.FourSphereVolumeConductor(
            radii, sigmas, eeg_coords_top)
        pot_db_4s_top = four_sphere_top.calc_potential(summed_dipole, r_mid)
        summed_EEG_top = (np.array(pot_db_4s_top) * 1e6)[0]

    # Return results
    return [summed_dipole, summed_EEG_top, tvec]
Пример #11
0
    def test_rz_params(self):
        radii = [1., 2., 4., 8.]
        sigmas = [1., 2., 4., 8.]
        r_el = np.array([[1., 0., 7.]])
        fs = LFPy.FourSphereVolumeConductor(radii, sigmas, r_el)

        rz1 = np.array([0., 0., 0.])
        with np.testing.assert_raises(RuntimeError):
            fs._rz_params(rz1)
        rz2 = np.array([0., 0., 1.])
        with np.testing.assert_raises(RuntimeError):
            fs._rz_params(rz2)
        rz3 = np.array([0., 0., 1.2])
        with np.testing.assert_raises(RuntimeError):
            fs._rz_params(rz3)
Пример #12
0
    def test_calc_potential(self):
        '''test comparison between four-sphere model and model for
        infinite homogeneous space
        when sigma is constant and r4 goes to infinity'''
        sigmas = [0.3, 0.3, 0.3 + 1e-16, 0.3]
        radii = [10., 20 * 1e6, 30. * 1e6, 40. * 1e6]
        rz = np.array([0., 0., 3.])
        p = np.array([[0., 0., 100.], [50., 50., 0.]])
        r_elec = np.array([[0., 0., 9.], [0., 0., 15.], [0., 0., 25.],
                           [0., 0., 40.], [0., 9., 0.], [0., 15., 0.],
                           [0., 25., 0.], [0., 40., 0.]])
        four_s = LFPy.FourSphereVolumeConductor(radii, sigmas, r_elec)
        pots_4s = four_s.calc_potential(p, rz)
        inf_s = LFPy.InfiniteVolumeConductor(0.3)
        pots_inf = inf_s.get_dipole_potential(p, r_elec - rz)

        np.testing.assert_allclose(pots_4s, pots_inf, rtol=1e-6)
Пример #13
0
 def test_decompose_dipole02(self):
     '''Test radial and tangential parts of dipole sums to dipole'''
     radii = [88000, 90000, 95000, 100000]
     sigmas = [0.3, 1.5, 0.015, 0.3]
     ps = np.array([[1000., 0., 0.], [-1000., 0., 0.], [0., 1000., 0.],
                    [0., -1000., 0.], [0., 0., 1000.], [0., 0., -1000.],
                    [10., 20., 30.], [-10., -20., -30.]])
     p_locs = np.array([[87000., 0., 0.], [-87000., 0.,
                                           0.], [0., 87000., 0.],
                        [0., -87000., 0.], [0., 0., 87000.],
                        [0., 0., -87000.], [80000., 2000., 3000.],
                        [-2000., -80000., -3000.]])
     el_locs = np.array([[90000., 5000., -5000.]])
     fs = LFPy.FourSphereVolumeConductor(radii, sigmas, el_locs)
     for p_loc in p_locs:
         fs._rz_params(p_loc)
         p_rads, p_tans = fs._decompose_dipole(ps)
         np.testing.assert_equal(p_rads + p_tans, ps)
Пример #14
0
    def test_calc_potential01(self):
        '''test comparison between analytical 4S-model and FEM simulation'''
        # load data
        fem_sim = np.load(
            os.path.join(LFPy.__path__[0], 'test', 'fem_mix_dip.npz'))
        pot_fem = fem_sim['pot_fem']  # [µV]
        p = fem_sim['p']  # [nAµm]
        rz = fem_sim['rz']  # [µm]
        radii = fem_sim['radii']  # [µm]
        sigmas = fem_sim['sigmas']  # [S/cm]
        ele_coords = fem_sim['ele_coords']  # [µm]

        fs = LFPy.FourSphereVolumeConductor(radii, sigmas, ele_coords)
        k_mV_to_muV = 1e3
        pot_analytical = fs.calc_potential(p, rz).reshape(
            (len(ele_coords), )).reshape(pot_fem.shape) * k_mV_to_muV
        global_error = np.abs(pot_analytical - pot_fem) / (np.max(
            np.abs(pot_fem)))
        np.testing.assert_array_less(global_error, 0.01)
Пример #15
0
    def test_calc_phi02(self):
        '''Test phi: azimuthal angle between rx and rxy,
           check that theta is not NaN, due to round-off errors'''
        radii = [79000., 80000., 85000., 100000.]
        sigmas = [0.3, 0.015, 15, 0.3]
        rz = np.array([0., 0., 76500.])
        r_el = np.array([[1e-5, 0, 99999.], [0, 0.000123, 99998.9],
                         [-5.59822325e3, -9.69640709e3, -9.93712111e4],
                         [99990., 0., 0.001]])

        fs = LFPy.FourSphereVolumeConductor(radii, sigmas, r_el)
        fs._rz_params(rz)

        P1 = np.array([[0., 0., 123456789.], [0., 0., 0.05683939],
                       [89892340., 0., -123456789],
                       [0.00004, 0.002, .0987654321], [0., 0., 0.05683939],
                       [0.0003, 0.001, 123456789.], [1e-11, 1e-12, 1000.],
                       [1e-15, 0, 1000.]])
        p_rad, p_tan = fs._decompose_dipole(P1)
        phi = fs.calc_phi(p_tan)

        np.testing.assert_equal(np.isnan(phi).any(), False)
Пример #16
0
    def test_get_transformation_matrix_00(self):
        '''Test radial and tangential parts of dipole sums to dipole'''
        radii = [88000, 90000, 95000, 100000]
        sigmas = [0.3, 1.5, 0.015, 0.3]

        dips = np.array([[[1000., 0., 0.]], [[-1000., 0., 0.]],
                         [[0., 1000., 0.]], [[0., -1000., 0.]],
                         [[0., 0., 1000.]], [[0., 0., -1000.]]])

        p_locs = np.array([[87000., 0., 0.], [-87000., 0.,
                                              0.], [0., 87000., 0.],
                           [0., -87000., 0.], [0., 0., 87000],
                           [0., 0., -87000]])

        el_locs = np.array([[[99000., 0., 0.]], [[-99000., 0., 0.]],
                            [[0., 99000., 0.]], [[0., -99000., 0.]],
                            [[0., 0., 99000.]], [[0., 0., -99000.]]])

        for i in range(len(p_locs)):
            fs = LFPy.FourSphereVolumeConductor(el_locs[i], radii, sigmas)
            phi = fs.get_dipole_potential(dips[i].T, p_locs[i])

            M = fs.get_transformation_matrix(p_locs[i])
            np.testing.assert_allclose(M @ dips[i].T, phi)
Пример #17
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()')
Пример #18
0
    # if x >= 0:
    #     ax3.text(x, z+5000, r'${}\pi$'.format(theta / np.pi))
    # else:
    #     ax3.text(x, z+5000, r'${}\pi$'.format(theta / np.pi), ha='right')
    ax3.text(x, z + 2500, r'{}'.format(i + 1), ha='center')

# dipole location
ax3.plot([0], [dipole_position[-1]], 'k.', label='dipole site')
ax3.axis('equal')
ax3.set_xticks(np.r_[-np.array(foursphereParams['radii']), 0,
                     foursphereParams['radii']])
ax3.set_xticklabels([])
ax3.legend(loc=(0.25, 0.15), frameon=False)

# four-sphere volume conductor
sphere = LFPy.FourSphereVolumeConductor(**foursphereParams)
phi_p = sphere.calc_potential(cell.current_dipole_moment, rz=dipole_position)

# import example_parallel_network_plotting as plotting
vlimround = draw_lineplot(
    ax=ax4,
    data=phi_p * 1E9,
    unit=r'pV',  #mV -> pV unit conversion
    dt=cell.dt,
    ztransform=False,
    T=(0, cell.tstop),
    color='k',
    scalebarbasis='log10')
# ax4.set_xticklabels([])
ax4.set_yticklabels([r'{}'.format(i + 1) for i in range(phi_p.shape[0])])
ax4.set_ylabel('position')
Пример #19
0
    'record_current': True  # syn. current record
}
synapse = LFPy.Synapse(cell, **synapseParameters)
synapse.set_spike_times(np.array([1.]))
cell.set_pos(z=somapos[2])
cell.simulate(rec_imem=True, rec_vmem=True, rec_current_dipole_moment=True)

# Setting up recording positions
elec_z = np.array(
    [radii[0], (radii[0] + radii[1]) / 2, radii[1], radii[1] + 500])

elec_x = np.zeros(elec_z.shape)
elec_y = np.zeros(elec_x.shape)
eeg_coords = np.array([elec_x.flatten(), elec_y.flatten(), elec_z.flatten()]).T

MD_4s = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords)
phi = MD_4s.calc_potential_from_multi_dipoles(cell) * 1e6  # from mV to nV

# Plotting results
plt.close('all')
fig = plt.figure(figsize=[8, 10])
fig.subplots_adjust(left=0.02, hspace=0.5, right=0.98, top=0.95)

ax = fig.add_subplot(111,
                     aspect=1,
                     frameon=False,
                     xlim=xlim,
                     ylim=ylim,
                     xticks=[],
                     yticks=[])
Пример #20
0
import LFPy
from plotting_convention import simplify_axes

sim_folder = "evoked_cdm"

populations = [f for f in os.listdir(join(sim_folder, "cdm"))
               if os.path.isdir(join(sim_folder, "cdm", f))]

# four_sphere properties
# From Huang et al. (2013): 10.1088/1741-2560/10/6/066004
sigmas = [0.276, 1.65, 0.01, 0.465]
radii = [89000., 90000., 95000., 100000.]
rad_tol = 1e-2

eeg_coords_top = np.array([[0., 0., radii[3] - rad_tol]])
four_sphere_top = LFPy.FourSphereVolumeConductor(eeg_coords_top, radii, sigmas)


plt.close("all")
fig = plt.figure(figsize=[4, 4])
fig.subplots_adjust(hspace=0.4, top=0.8, left=0.2, bottom=0.15, right=0.98)
ax1 = fig.add_subplot(111, xlabel="Time (ms)",
                      xlim=[875, 950], ylim=[-0.7, 0.7])
ax1.set_ylabel("$\mu$V", labelpad=-3)
ax1.axvline(900, color='gray', lw=0.2)
dominating_pops = ["p5(L56)", "p5(L23)",
                   "p6(L4)", "p6(L56)",
                   "p4",
                   "p23"
                   ]
sub_pop_groups_dict = {"L5E": ["p5(L56)", "p5(L23)"],
Пример #21
0
    synapse = LFPy.Synapse(cell, **synapse_params)
    synapse.set_spike_times(np.array([5.]))

    cell.simulate(rec_imem=True,
                  rec_current_dipole_moment=True)

    # compute dipole
    P = cell.current_dipole_moment

    somapos = np.array([0., 0., 77500])
    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(radii, sigmas, eeg_coords_top)
    pot_db_4s_top = four_sphere_top.calc_potential(P, r_mid)
    eeg_top = np.array(pot_db_4s_top) * 1e9

    #measurement points
    # for nice plot use theta_step = 1 and phi_step = 1. NB: Long computation time.
    theta_step = 5
    phi_step = 5
    theta, phi_angle = np.mgrid[0.:180.:theta_step, 0.:360.+phi_step:phi_step]

    num_theta = theta.shape[0]
    num_phi = theta.shape[1]
    theta = theta.flatten()
    phi_angle = phi_angle.flatten()

    theta_r = np.deg2rad(theta)
Пример #22
0
def generate_eegs_nyh_n_4s(dip_loc):

    # get population dipole from hybrid simulation:
    cdm_file = join('..', "hybrid_EEG_evoked", "evoked_cdm", "summed_cdm.npy")
    # Only interested in time around evoked potential (875 - 951 ms)
    P = np.load(cdm_file).T[:, 875:951]

    # Load New York Head model
    nyh = LFPy.NYHeadModel()
    # place dipole and find normal vector
    P_loc_nyh = nyh.dipole_pos_dict[dip_loc]
    nyh.set_dipole_pos(dipole_pos=P_loc_nyh)
    P_loc_idx = nyh.return_closest_idx(P_loc_nyh)
    norm_vec = nyh.cortex_normals[:, P_loc_idx]

    # set four-sphere properties
    # From Huang et al. (2013): 10.1088/1741-2560/10/6/066004
    sigmas = [0.276, 1.65, 0.01, 0.465]
    radii = [89000., 90000., 95000., 100000.]
    rad_tol = 1e-2
    x_eeg, y_eeg, z_eeg = return_equidistal_xyz(224, r=radii[-1] - rad_tol)
    eeg_coords_4s = np.array([x_eeg, y_eeg, z_eeg]).T
    # Place the dipole 1000 µm down into cortex
    dipole_radial_pos = radii[0] - 1000

    # find location on 4S
    # want to find position on brain, such that the location vector is
    # parallel to norm_vec from nyh.
    dipole_loc_4s = norm_vec*dipole_radial_pos
    # Rotate dipole to be aligned with cortex normal
    P_rot = nyh.rotate_dipole_to_surface_normal(P)

    elec_dists_4s = np.sqrt(np.sum((eeg_coords_4s - dipole_loc_4s)**2, axis=1))
    elec_dists_4s *= 1e-3 # convert from um to mm
    min_dist_idx = np.argmin(elec_dists_4s)
    print("Minimum 4o distance {:2.02f} mm".format(elec_dists_4s[min_dist_idx]))

    time_idx = np.argmax(np.linalg.norm(P_rot, axis=0))

    four_sphere = LFPy.FourSphereVolumeConductor(eeg_coords_4s, radii, sigmas)
    start_4s = time.time()
    eeg_4s = four_sphere.get_dipole_potential(P_rot, dipole_loc_4s)
    end_4s = time.time()
    time_4s = end_4s - start_4s
    print('execution time 4S:', time_4s)
    # subtract DC-component
    dc_comp_4s = np.mean(eeg_4s[:, 0:25], axis=1)
    dc_comp_4s = np.expand_dims(dc_comp_4s, 1)
    eeg_4s -= dc_comp_4s
    eeg_4s *= 1e3  # from mV to uV

    # calculate EEGs with NYHeadModel
    start_nyh = time.time()
    eeg_nyh = nyh.get_transformation_matrix() @ P_rot # pV
    end_nyh = time.time()
    time_nyh = end_nyh - start_nyh
    print('execution time NYH:', time_nyh)
    # subtract DC-component
    dc_comp_nyh = np.mean(eeg_nyh[:, 0:25], axis=1)
    dc_comp_nyh = np.expand_dims(dc_comp_nyh, 1)
    eeg_nyh -= dc_comp_nyh
     # from mV to uV
    eeg_nyh *= 1e3
    elec_dists_nyh = (np.sqrt(np.sum((np.array(nyh.dipole_pos)[:, None] -
                                      np.array(nyh.elecs[:3, :]))**2, axis=0)))
    eeg_coords_nyh = nyh.elecs

    dist, closest_elec_idx = nyh.find_closest_electrode()
    print("Closest electrode to dipole: {:1.2f} mm".format(dist))

    tvec = np.arange(P.shape[1]) + 875

    np.savez('../data/figure7_%s.npz' % dip_loc,
        radii = radii,
        p_rot = P_rot,
        p_loc_4s = dipole_loc_4s,
        p_loc_nyh = P_loc_nyh,
        eeg_coords_4s = eeg_coords_4s,
        eeg_coords_nyh = eeg_coords_nyh,
        elec_dists_4s = elec_dists_4s,
        elec_dists_nyh = elec_dists_nyh,
        eeg_4s = eeg_4s,
        eeg_nyh = eeg_nyh,
        time_idx = time_idx,
        tvec= tvec,
    )
Пример #23
0
def make_data(morphology, cell_model, rot, rz, radii, sigmas, electrode_locs,
              syn_idcs, spiking, syn_input_time):
    # set cell and synapse parameters
    cell_parameters, synapse_parameters = set_parameters(
        morphology, cell_model, spiking)
    [xrot, yrot, zrot] = rot
    # create four-sphere class instance
    fs = LFPy.FourSphereVolumeConductor(electrode_locs,
                                        radii=radii,
                                        sigmas=sigmas)
    # lists for storing data:
    p_list = []
    t_max_list = []
    p_loc_list = []
    lfp_single_dip_list = []
    lfp_multi_dip_list = []
    RE_list = []
    synlocs = []
    pz_traces = []
    # get data from num_syns simulations
    num_syns = len(syn_idcs)
    for j in range(num_syns):

        cell = create_cell(cell_parameters,
                           active=spiking,
                           x_rot=xrot,
                           y_rot=yrot,
                           z_rot=zrot)
        ## if you know synidx:
        syn_idx = syn_idcs[j]
        # if you only know synapse location:
        # syn_loc = syn_idcs[j]
        # syn_idx = cell.get_closest_idx(x=syn_loc[0], y=syn_loc[1], z=syn_loc[2])
        #        print('syn_idx:', syn_idx)
        cell, synapse = simulate(cell, synapse_parameters, [syn_idx],
                                 syn_input_time)
        # print('cell simulated')

        cell.set_pos(x=rz[0], y=rz[1], z=rz[2])
        syn_loc = (cell.x[syn_idx].mean(), cell.y[syn_idx].mean(),
                   cell.z[syn_idx].mean())
        synlocs.append((syn_loc[0], syn_loc[1], syn_loc[2]))

        # compute current dipole moment and subtract DC-component
        cdm = LFPy.CurrentDipoleMoment(cell)
        dipoles = cdm.get_transformation_matrix() @ cell.imem
        input_idx_before_input = np.argmin(
            np.abs(cell.tvec - syn_input_time)) - 1
        p_dc = dipoles[:, input_idx_before_input]
        dipoles -= p_dc[:, None]

        pz_traces.append(dipoles[2, :])
        # compute timepoint with biggest dipole
        timemax = [np.argmax(np.linalg.norm(np.abs(dipoles), axis=0))]
        t_max_list.append(timemax)
        p = dipoles[:, timemax]
        # compute LFP with single dipole
        # dip_loc = get_mass_center(cell, timemax)
        dip_loc = get_dipole_loc(rz, syn_loc)

        lfp_single_dip = fs.get_transformation_matrix(dip_loc) @ p
        # print('pot from single dip computed')
        # compute LFP with multi-dipole

        # subtract DC-component
        multi_p_319, multi_p_locs = cell.get_multi_current_dipole_moments(
            [input_idx_before_input])
        multi_p_dc = multi_p_319
        multi_p, multi_p_locs = cell.get_multi_current_dipole_moments(timemax)
        multi_p -= multi_p_dc

        Ni, Nd, Nt = multi_p.shape
        lfp_multi_dip = np.zeros((len(electrode_locs), Nt))
        for num in range(Ni):

            pot = fs.get_transformation_matrix(
                multi_p_locs[num]) @ multi_p[num]
            # fs.calc_potential(multi_p[num], multi_p_locs[num])
            lfp_multi_dip += pot

        # print('pot from multi dip computed')
        # compute relative errors
        RE = np.abs((lfp_single_dip - lfp_multi_dip) / lfp_multi_dip)
        print('syn number: {}; syn dist from soma: {}; RE_EEG: {}'.format(
            syn_idx, syn_loc[2] - rz[2], RE[-1]))
        #add data to lists for storage
        p_list.append(p)
        p_loc_list.append(dip_loc)
        lfp_single_dip_list.append(lfp_single_dip)
        lfp_multi_dip_list.append(lfp_multi_dip)
        RE_list.append(RE)

    # Do this for only one cell for plotting
    zips = []
    for x, z in cell.get_idx_polygons():
        zips.append(list(zip(x, z)))
    zmax = np.max(cell.z)
    soma_vmem = cell.vmem[0]
    tvec = cell.tvec

    return (p_list, pz_traces, lfp_multi_dip_list, lfp_single_dip_list,
            synlocs, zips, zmax, tvec, soma_vmem)
Пример #24
0
def generate_eegs_nyh_n_4s(dip_loc):
    # set 4S properties
    # From Huang et al. (2013): 10.1088/1741-2560/10/6/066004
    sigmas = [0.276, 1.65, 0.01, 0.465]
    radii = [89000., 90000., 95000., 100000.]

    print('sigmas:', sigmas)
    rad_tol = 1e-2

    P_loc_4s_length = radii[0] - 1000
    x_eeg, y_eeg, z_eeg = return_equidistal_xyz(224, r=radii[-1] - rad_tol)
    eeg_coords_4s = np.array([x_eeg, y_eeg, z_eeg]).T

    # get population dipole
    nyh = NYHeadModel()
    # hybrid current dipole moment
    nyh.load_hybrid_current_dipole()
    P = nyh.dipole_moment.T[875:951, :]
    # place dipole and find normal vector
    P_loc_nyh = nyh.dipole_pos_dict[dip_loc]

    nyh.set_dipole_pos(dipole_pos_0=P_loc_nyh)
    P_loc_idx = nyh.return_closest_idx(P_loc_nyh)
    norm_vec = nyh.cortex_normals[:, P_loc_idx]
    # find location on 4S
    # want to find position on brain, such that the location vector is
    # parallel to norm_vec from nyh.
    # length of position vector
    P_loc_4s = norm_vec * P_loc_4s_length
    P_rot = nyh.rotate_dipole_moment().T[875:951, :]
    # use this when comparing execution times

    elec_dists_4s = np.sqrt(np.sum((eeg_coords_4s - P_loc_4s)**2, axis=1))
    elec_dists_4s *= 1e-3  # convert from um to mm
    min_dist_idx = np.argmin(elec_dists_4s)
    print("Minimum 4o distance {:2.02f} mm".format(
        elec_dists_4s[min_dist_idx]))

    time_idx = np.argmax(np.linalg.norm(P_rot, axis=1))
    # if execution times:
    # time_idx = np.argmax(np.linalg.norm(P_rot[875:951,:], axis=1))

    # potential in 4S with db

    four_sphere = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords_4s)
    start_4s = time.time()
    eeg_4s = four_sphere.calc_potential(P_rot, P_loc_4s)  #[:,0]
    end_4s = time.time()
    time_4s = end_4s - start_4s
    # when comparing execution times:
    # eeg_4s = eeg_4s[:, 875:951]
    print('execution time 4S:', time_4s)
    # subtract DC-component
    dc_comp_4s = np.mean(eeg_4s[:, 0:25], axis=1)
    dc_comp_4s = np.expand_dims(dc_comp_4s, 1)
    eeg_4s -= dc_comp_4s
    eeg_4s *= 1e3  # from mV to uV

    # calculate EEGs with NYHeadModel
    start_nyh = time.time()
    nyh.calculate_eeg_signal(normal=True)
    end_nyh = time.time()
    time_nyh = end_nyh - start_nyh
    print('execution time NYH:', time_nyh)
    eeg_nyh = nyh.eeg[:, 875:951]  # pV
    # subtract DC-component
    dc_comp_nyh = np.mean(eeg_nyh[:, 0:25], axis=1)
    dc_comp_nyh = np.expand_dims(dc_comp_nyh, 1)
    eeg_nyh -= dc_comp_nyh
    # from pV to uV
    eeg_nyh *= 1e-6
    elec_dists_nyh = (np.sqrt(
        np.sum((np.array(nyh.dipole_pos)[:, None] -
                np.array(nyh.elecs[:3, :]))**2,
               axis=0)))
    eeg_coords_nyh = nyh.elecs
    # some info
    # max_eeg = np.max(np.abs(eeg_nyh[:, time_idx]))
    # max_eeg_idx = np.argmax(np.abs(eeg_nyh[:, time_idx]))
    # max_eeg_pos = eeg_coords_nyh[:3, max_eeg_idx]

    dist, closest_elec_idx = nyh.find_closest_electrode()
    print("Closest electrode to dipole: {:1.2f} mm".format(dist))

    tvec = np.arange(P.shape[0]) + 875

    np.savez(
        '../data/figure7_%s.npz' % dip_loc,
        radii=radii,
        p_rot=P_rot,
        p_loc_4s=P_loc_4s,
        p_loc_nyh=P_loc_nyh,
        eeg_coords_4s=eeg_coords_4s,
        eeg_coords_nyh=eeg_coords_nyh,
        elec_dists_4s=elec_dists_4s,
        elec_dists_nyh=elec_dists_nyh,
        eeg_4s=eeg_4s,
        eeg_nyh=eeg_nyh,
        time_idx=time_idx,
        tvec=tvec,
    )