def test_dipole(): """Test dipole object.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') dpl_out_fname = '/tmp/dpl1.txt' params = read_params(params_fname) times = np.random.random(6000) data = np.random.random((6000, 3)) dipole = Dipole(times, data) dipole.baseline_renormalize(params) dipole.convert_fAm_to_nAm() dipole.scale(params['dipole_scalefctr']) dipole.smooth(params['dipole_smooth_win'] / params['dt']) dipole.plot(show=False) viz.plot_dipole([dipole, dipole], show=False) dipole.write(dpl_out_fname) dipole_read = read_dipole(dpl_out_fname) assert_allclose(dipole_read.times, dipole.times, rtol=0, atol=0.00051) for dpl_key in dipole.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole.data[dpl_key], rtol=0, atol=0.000051) # average two identical dipole objects dipole_avg = average_dipoles([dipole, dipole_read]) for dpl_key in dipole_avg.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole_avg.data[dpl_key], rtol=0, atol=0.000051) with pytest.raises(ValueError, match="Dipole at index 0 was already an " "average of 2 trials"): dipole_avg = average_dipoles([dipole_avg, dipole_read])
def test_dipole(tmpdir, run_hnn_core_fixture): """Test dipole object.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') dpl_out_fname = tmpdir.join('dpl1.txt') params = read_params(params_fname) times = np.random.random(6000) data = np.random.random((6000, 3)) dipole = Dipole(times, data) dipole.baseline_renormalize(params['N_pyr_x'], params['N_pyr_y']) dipole.convert_fAm_to_nAm() dipole.scale(params['dipole_scalefctr']) dipole.smooth(params['dipole_smooth_win'] / params['dt']) dipole.plot(show=False) plot_dipole([dipole, dipole], show=False) dipole.write(dpl_out_fname) dipole_read = read_dipole(dpl_out_fname) assert_allclose(dipole_read.times, dipole.times, rtol=0, atol=0.00051) for dpl_key in dipole.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole.data[dpl_key], rtol=0, atol=0.000051) # average two identical dipole objects dipole_avg = average_dipoles([dipole, dipole_read]) for dpl_key in dipole_avg.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole_avg.data[dpl_key], rtol=0, atol=0.000051) with pytest.raises(ValueError, match="Dipole at index 0 was already an " "average of 2 trials"): dipole_avg = average_dipoles([dipole_avg, dipole_read]) # test postproc dpls_raw, net = run_hnn_core_fixture(backend='joblib', n_jobs=1, reduced=True, record_isoma=True, record_vsoma=True, postproc=False) dpls, _ = run_hnn_core_fixture(backend='joblib', n_jobs=1, reduced=True, record_isoma=True, record_vsoma=True, postproc=True) with pytest.raises(AssertionError): assert_allclose(dpls[0].data['agg'], dpls_raw[0].data['agg']) dpls_raw[0].post_proc(net.params['N_pyr_x'], net.params['N_pyr_y'], net.params['dipole_smooth_win'] / net.params['dt'], net.params['dipole_scalefctr']) assert_allclose(dpls_raw[0].data['agg'], dpls[0].data['agg'])
def test_dipole(): """Test dipole object.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') dpl_out_fname = '/tmp/dpl1.txt' params = read_params(params_fname) times = np.random.random(6000) data = np.random.random((6000, 3)) dipole = Dipole(times, data) dipole.baseline_renormalize(params) dipole.convert_fAm_to_nAm() dipole.scale(params['dipole_scalefctr']) dipole.smooth(params['dipole_smooth_win'] / params['dt']) dipole.plot(show=False) viz.plot_dipole([dipole, dipole], show=False) dipole.write(dpl_out_fname) dipole_read = read_dipole(dpl_out_fname) assert_allclose(dipole_read.times, dipole.times, rtol=0, atol=0.00051) for dpl_key in dipole.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole.data[dpl_key], rtol=0, atol=0.000051)
def test_dipole_visualization(): """Test dipole visualisations.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') params = read_params(params_fname) params.update({'N_pyr_x': 3, 'N_pyr_y': 3, 'tstop': 100.}) net = Network(params) weights_ampa_p = {'L2_pyramidal': 5.4e-5, 'L5_pyramidal': 5.4e-5} syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.} net.add_bursty_drive( 'beta_prox', tstart=0., burst_rate=25, burst_std=5, numspikes=1, spike_isi=0, repeats=11, location='proximal', weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, seedcore=14) dpls = simulate_dipole(net, n_trials=2, postproc=False) fig = dpls[0].plot() # plot the first dipole alone axes = fig.get_axes()[0] dpls[0].copy().smooth(window_len=10).plot(ax=axes) # add smoothed versions dpls[0].copy().savgol_filter(h_freq=30).plot(ax=axes) # on top # test decimation options plot_dipole(dpls[0], decim=2) for dec in [-1, [2, 2.]]: with pytest.raises(ValueError, match='each decimation factor must be a positive'): plot_dipole(dpls[0], decim=dec) # test plotting multiple dipoles as overlay fig = plot_dipole(dpls) # multiple TFRs get averaged fig = plot_tfr_morlet(dpls, freqs=np.arange(23, 26, 1.), n_cycles=3) with pytest.raises(RuntimeError, match="All dipoles must be scaled equally!"): plot_dipole([dpls[0].copy().scale(10), dpls[1].copy().scale(20)]) with pytest.raises(RuntimeError, match="All dipoles must be scaled equally!"): plot_psd([dpls[0].copy().scale(10), dpls[1].copy().scale(20)]) with pytest.raises(RuntimeError, match="All dipoles must be sampled equally!"): dpl_sfreq = dpls[0].copy() dpl_sfreq.sfreq /= 10 plot_psd([dpls[0], dpl_sfreq])
# explicit use of the :meth:`~hnn_core.dipole.Dipole.smooth` and # :meth:`~hnn_core.dipole.Dipole.scale` methods instead. Note that both methods # operate in-place, i.e., the objects are modified. window_len, scaling_factor = 30, 3000 for dpl in dpls: dpl.smooth(window_len).scale(scaling_factor) ############################################################################### # Plot the amplitudes of the simulated aggregate dipole moments over time import matplotlib.pyplot as plt fig, axes = plt.subplots(2, 1, sharex=True, figsize=(6, 6), constrained_layout=True) plot_dipole(dpls, ax=axes[0], layer='agg', show=False) net.cell_response.plot_spikes_hist(ax=axes[1], spike_types=['evprox', 'evdist']) ############################################################################### # Now, let us try to make the exogenous driving inputs to the cells # synchronous and see what happens. This is achieved by setting # ``n_drive_cells=1`` and ``cell_specific=False`` when adding each drive. net_sync = jones_2009_model() n_drive_cells = 1 cell_specific = False net_sync.add_evoked_drive('evdist1', mu=63.53,
# included in our biophysical model. We can confirm that what we simulate is # indeed 10 Hz activity by plotting the power spectral density (PSD). import matplotlib.pyplot as plt from hnn_core.viz import plot_dipole, plot_psd fig, axes = plt.subplots(2, 1, constrained_layout=True) tmin, tmax = 10, 300 # exclude the initial burn-in period from the plots # We'll make a copy of the dipole before smoothing in order to compare window_len = 20 # convolve with a 20 ms-long Hamming window dpl_smooth = dpl[trial_idx].copy().smooth(window_len) # Overlay the traces for comparison. The function plot_dipole can plot a list # of dipoles at once dpl_list = [dpl[trial_idx], dpl_smooth] plot_dipole(dpl_list, tmin=tmin, tmax=tmax, ax=axes[0], show=False) axes[0].set_xlim((1, 399)) axes[0].legend(['orig', 'smooth']) plot_psd(dpl[trial_idx], fmin=1., fmax=1e3, tmin=tmin, ax=axes[1], show=False) axes[1].set_xscale('log') plt.tight_layout() ############################################################################### # The next step is to add a simultaneous 10 Hz :term:`distal` drive with a # lower within-burst spread of spike times (``burst_std``) compared with the # proximal one. The different arrival times of spikes at opposite ends of # the pyramidal cells will tend to produce bursts of 15-30 Hz power known # as beta frequency events. location = 'distal' burst_std = 15 weights_ampa_d = {'L2_pyramidal': 5.4e-5, 'L5_pyramidal': 5.4e-5}
def test_dipole(tmpdir, run_hnn_core_fixture): """Test dipole object.""" hnn_core_root = op.dirname(hnn_core.__file__) params_fname = op.join(hnn_core_root, 'param', 'default.json') dpl_out_fname = tmpdir.join('dpl1.txt') params = read_params(params_fname) times = np.arange(0, 6000 * params['dt'], params['dt']) data = np.random.random((6000, 3)) dipole = Dipole(times, data) dipole._baseline_renormalize(params['N_pyr_x'], params['N_pyr_y']) dipole._convert_fAm_to_nAm() # test smoothing and scaling dipole_raw = dipole.copy() dipole.scale(params['dipole_scalefctr']) dipole.smooth(window_len=params['dipole_smooth_win']) with pytest.raises(AssertionError): assert_allclose(dipole.data['agg'], dipole_raw.data['agg']) assert_allclose( dipole.data['agg'], (params['dipole_scalefctr'] * dipole_raw.smooth(params['dipole_smooth_win']).data['agg'])) dipole.plot(show=False) plot_dipole([dipole, dipole], show=False) # Test IO dipole.write(dpl_out_fname) dipole_read = read_dipole(dpl_out_fname) assert_allclose(dipole_read.times, dipole.times, rtol=0, atol=0.00051) for dpl_key in dipole.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole.data[dpl_key], rtol=0, atol=0.000051) # average two identical dipole objects dipole_avg = average_dipoles([dipole, dipole_read]) for dpl_key in dipole_avg.data.keys(): assert_allclose(dipole_read.data[dpl_key], dipole_avg.data[dpl_key], rtol=0, atol=0.000051) with pytest.raises(ValueError, match="Dipole at index 0 was already an " "average of 2 trials"): dipole_avg = average_dipoles([dipole_avg, dipole_read]) # average an n_of_1 dipole list single_dpl_avg = average_dipoles([dipole]) for dpl_key in single_dpl_avg.data.keys(): assert_allclose(dipole_read.data[dpl_key], single_dpl_avg.data[dpl_key], rtol=0, atol=0.000051) # average dipole list with one dipole object and a zero dipole object n_times = len(dipole_read.data['agg']) dpl_null = Dipole(np.zeros(n_times, ), np.zeros((n_times, 3))) dpl_1 = [dipole, dpl_null] dpl_avg = average_dipoles(dpl_1) for dpl_key in dpl_avg.data.keys(): assert_allclose(dpl_1[0].data[dpl_key] / 2., dpl_avg.data[dpl_key]) # Test experimental dipole dipole_exp = Dipole(times, data[:, 1]) dipole_exp.write(dpl_out_fname) dipole_exp_read = read_dipole(dpl_out_fname) assert_allclose(dipole_exp.data['agg'], dipole_exp_read.data['agg'], rtol=1e-2) dipole_exp_avg = average_dipoles([dipole_exp, dipole_exp]) assert_allclose(dipole_exp.data['agg'], dipole_exp_avg.data['agg']) # XXX all below to be deprecated in 0.3 dpls_raw, net = run_hnn_core_fixture(backend='joblib', n_jobs=1, reduced=True, record_isoma=True, record_vsoma=True) # test deprecation of postproc with pytest.warns(DeprecationWarning, match='The postproc-argument is deprecated'): dpls, _ = run_hnn_core_fixture(backend='joblib', n_jobs=1, reduced=True, record_isoma=True, record_vsoma=True, postproc=True) with pytest.raises(AssertionError): assert_allclose(dpls[0].data['agg'], dpls_raw[0].data['agg']) dpls_raw[0]._post_proc(net._params['dipole_smooth_win'], net._params['dipole_scalefctr']) assert_allclose(dpls_raw[0].data['agg'], dpls[0].data['agg'])
############################################################################### # By inspecting the activity during the beta event, we can see that spiking # occurs exclusively at 50 ms, the peak of the gaussian distributed proximal # and distal inputs. This spiking activity leads to sustained GABAb mediated # inhibition of the L2 and L5 pyrmaidal cells. One effect of this inhibition # is an assymetric beta event with a long positive tail. import matplotlib.pyplot as plt import numpy as np fig, axes = plt.subplots(4, 1, sharex=True, figsize=(7, 7), constrained_layout=True) net_beta.cell_response.plot_spikes_hist(ax=axes[0], show=False) axes[0].set_title('Beta Event Generation') plot_dipole(dpls_beta, ax=axes[1], layer='agg', tmin=1.0, show=False) net_beta.cell_response.plot_spikes_raster(ax=axes[2], show=False) axes[2].set_title('Spike Raster') # Create a fixed-step tiling of frequencies from 1 to 40 Hz in steps of 1 Hz freqs = np.arange(10., 60., 1.) dpls_beta[0].plot_tfr_morlet(freqs, n_cycles=7, ax=axes[3]) ############################################################################### # Next we will inspect what happens when a sensory stimulus is delivered 75 ms # after a beta event. Note that the delay time for a tactile stimulus at the # hand to arrive at the cortex is roughly 25 ms, which means the first proximal # input to the cortical column occurs ~100 ms after the beta event. dpls_beta_erp[0].smooth(45) fig, axes = plt.subplots(3, 1,
dpls_beta = simulate_dipole(net, n_trials=1) trial_idx = 0 decim = [10, 10] # decimate by a factor of 100 fig, axes = plt.subplots(4, 1, sharex=True, figsize=(6, 8), gridspec_kw={'height_ratios': [1, 1, 2, 4]}) net.cell_response.plot_spikes_hist(ax=axes[0], spike_types=['beta_dist'], show=False) net.cell_response.plot_spikes_hist(ax=axes[1], spike_types=['beta_prox'], show=False) plot_dipole(dpls_beta[trial_idx], ax=axes[2], decim=decim, show=False) freqs = np.arange(5., 40., 1.) n_cycles = 7 plot_tfr_morlet(dpls_beta[trial_idx], freqs=freqs, n_cycles=n_cycles, decim=decim, ax=axes[3]) ############################################################################### # Reproduce Law 2019, Figure 4 ############################################################################### # Values to be changed relative to default parameters are given in # Supplemental Table 1 [2] # Cell parameters