New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add_drives_from_params vs add_evoked_drive #454
Comments
@mkhalil8 do you mind pointing to where 18 is subtracted from I suspect there is a deeper seeding discrepancy, but there may be a more obvious explanation that @jasmainak or @rythorpe remember from when we developed the drives API. I do recall that there were some awkward workarounds to deal with the old param seeding/format. |
Hi Nicholas and Happy New Year :) The 18 is subtracted from event_seed at : def _extract_drive_specs_from_hnn_params(params, cellname_list):
223 drive['event_seed'] = par['prng_seedcore'] - 18 |
The
Or is this for IO? I think @rythorpe at some point figured that subtracting 18 maintained backward compatibility with previous versions in GUI |
It was leftover from when we were originally planning to replace the model in all examples with # Remove params argument after updating examples
# (only relevant for Jones 2009 model)
def calcium_model(params=None, add_drives_from_params=False): As of right now the main reason to keep it is compatibility with HNN-GUI. It is still the standard way people are introduced to HNN and is important to show that they produce identical results. Until we have a GUI running hnn-core I think we will be stuck with param files for a bit longer. |
I think I came across the same issue @mkhalil8 has encountered when I was putting together the hnn_core gamma tutorial but forgot to follow up. I found that the order in which drives are added is important when trying to match the results of automatically added drives from a param file.
The -18 applied to the seed core is important for maintaining continuity with HNN-GUI, but I can’t recall the details off the top of my head. I’m away from my computer but will follow up sometime in the next few days.
… On Jan 2, 2022, at 10:45 AM, Nick Tolley ***@***.***> wrote:
It was leftover from when we were originally planning to replace the model in all examples with calcium_model:
# Remove params argument after updating examples
# (only relevant for Jones 2009 model)
def calcium_model(params=None, add_drives_from_params=False):
As of right now the main reason to keep it is compatibility with HNN-GUI. It is still the standard way people are introduced to HNN and is important to show that they produce identical results. Until we have a GUI running hnn-core I think we will be stuck with param files for a bit longer.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you were mentioned.
|
@mkhalil8 is the parameter file you send me supposed to only add a single proximal drive, or was that just a small example from the code above? Using the params = read_params('L_Contra.param')
net_params = calcium_model(params, add_drives_from_params = True)
print(net_params.external_drives.keys())
|
@ntolley Yes it does add these drives but the weights of all these drives (except the evoked) are Zeros, so I guess they don't end up affecting the network. |
@ntolley when comparing the two methods of adding drives I get this result (one trial simulation for each method with the same seed) |
Do you mind sharing the full code you're using for manually adding the evoked drives? It seems like there should be a distal drive as well since they have non-zero weights. |
Yes there are p1, d1, p2 #code for manually adding drives
net_ev = hnn_core.calcium_model(params, add_drives_from_params=False)
net1 = hnn_core.calcium_model(params, add_drives_from_params=False)
# p1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722, 'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247, 'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net1.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal', event_seed =4, synaptic_delays=synaptic_delays_prox)
# d1 drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.25807}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net1.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal', event_seed = 4, synaptic_delays = synaptic_delays_d1)
# p2 drive
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454, 'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 , 'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net1.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal', event_seed = 4)
dpls_ev = simulate_dipole(net1, tstop=250, n_trials=1)
dpl_ev = dpls_ev[0]
dpl_ev.smooth(30).scale(1500) |
@mkhalil8 I've figured out that manually adding the blank bursty drives that are added by the #code for manually adding drives
net_manual = calcium_model(params, add_drives_from_params=False)
# Add empty bursty drives
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net_manual.add_bursty_drive(
'bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,
spike_isi=10, n_drive_cells=10, location=location,
weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_manual.add_bursty_drive(
'bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,
spike_isi=10, n_drive_cells=10, location=location,
weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# d1 drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.25807}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_manual.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal', synaptic_delays = synaptic_delays_d1, event_seed=-14)
# p1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722, 'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247, 'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_manual.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal', synaptic_delays=synaptic_delays_prox, event_seed=-14)
# p2 drive
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454, 'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 , 'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_manual.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal', event_seed=-14) It's a bit fishy that the waveforms don't match exactly despite identical driving inputs. This may be an artifact of running two simulations back to back, and global variables aren't being cleared properly. I'll discuss with the dev team this week and report back. |
@rythorpe Thanks Ryan, in what manner do the order of adding drives matter? shall I in the case of ERP add drives with the following order: |
@ntolley Thanks a lot Nick, I believe this answers the question for now, will wait for any updates on the waveforms!! |
@ntolley So we don't need to add the extgauss or extpois, right? Do you mind also pointing out where in the code does adding the burst drive updates the RNG? just to make sure I understood :) |
do we need to expose Lines 842 to 844 in 1c2662c
|
But is calcium model implemented in the GUI? |
@jasmainak Yes sure will share the param file later. |
@ntolley have you explicitly verified that the spike times are exactly the same when the drives are automatically vs manually added? I suspect that somewhere there is a very minor difference.... |
@rythorpe they actually match exactly using a |
@jasmainak the param file I used from Kohl simulation: https://github.com/kohl-carmen/HNN-AEF/blob/main/HNN_Parameters/L_Contra.param |
@ntolley Nick how is the order of adding the evoked drives makes a difference in the dipole? I shuffled their order and got different results. |
Sorry the delay @mkhalil8! I've been swamped the past few days but have some time this week to dig into this a bit deeper. At the end of the day the difference in the dipole all comes from seeding. When you instantiate a drive, a random seed is used with the random number generator to produce the spike times (distributed according to the type of drive). A different seed produces different spike times. I didn't write this part of the code base so I need to look into this more carefully before pointing you to the correct sections. In any case, the desired behavior is that every time a drive is added, the seed for the random number generator is incremented. This to avoid weird behavior like two proximal and distal drives having completely coincident spike times. |
This brings up a more general question @jasmainak , when we say our code is reproducible should that include the order in which steps are performed? Or should it be reproducible when the calls used to construct the network occur in different order. |
yes our code should be reproducible no matter what order you add the drives because it's the same network @mkhalil8 I'd need a small script that demos this to investigate further |
@mkhalil8 I can't import that from hnn_core import read_params
params = read_params('L_contra.param') Did you make any modifications to it? |
@jasmainak I think the text export messed up, you have to remove the blank lines |
@jasmainak @ntolley I was originally running batch simulations varying the synchronization of the drives but got mixed results, So I used this code below to experiment and figure out where the error is coming from. In the code below I instantiated new network with different name for each simulation(just to make sure this is not the culprit for the error) and changed the order of the drives while exploring the effect of differential synchronization between drives. I will post down two sets of code each with two different orders of drives added to the network. The first one: d1, p1,p2. The second one is : p1,p2,d1. The first script: adding d1, p1,p2:## simulating contrl
import os.path as op
from itertools import product
import numpy as np
from joblib import Parallel, delayed
import hnn_core
from hnn_core import simulate_dipole, jones_2009_model, average_dipoles
from hnn_core import read_params
from hnn_core.viz import plot_dipole
import json
from hnn_core import JoblibBackend
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'L_Contra.param')
params = read_params(params_fname)
net = hnn_core.calcium_model(params,add_drives_from_params= False)
n_drive_cells = 1
cell_specific = False
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
dpl = simulate_dipole(net, tstop=250, n_trials= 1)
dpl_cntrl= dpl[0]
dpl_cntrl.smooth(30).scale(1500)
## sync d1
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'L_Contra.param')
params = read_params(params_fname)
net_d = hnn_core.calcium_model(params,add_drives_from_params= False)
n_drive_cells = 1
cell_specific = False
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net_d.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_d.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_d.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_d.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_d.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
dpls_sync_d1 = simulate_dipole(net_d, tstop=250, n_trials= 1)
dpl_sync_d1= dpls_sync_d1[0]
dpl_sync_d1.smooth(30).scale(1500)
# n_drive_cells = n_drive_cells, cell_specific = cell_specific
## sync p1, d1
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'L_Contra.param')
params = read_params(params_fname)
net_p = hnn_core.calcium_model(params,add_drives_from_params= False)
n_drive_cells = 1
cell_specific = False
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net_p.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_p.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_p.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_p.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_p.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
dpls_sync_p1_d1 = simulate_dipole(net_p, tstop=250, n_trials= 1)
dpl_sync_p1_d1= dpls_sync_p1_d1[0]
dpl_sync_p1_d1.smooth(30).scale(1500)
##all_drives synchronized
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'L_Contra.param')
params = read_params(params_fname)
net_all = hnn_core.calcium_model(params,add_drives_from_params= False)
n_drive_cells = 1
cell_specific = False
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net_all.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_all.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_all.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_all.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_all.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14,n_drive_cells = n_drive_cells, cell_specific = cell_specific)
dpls_all = simulate_dipole(net_all, tstop = 250, n_trials=1)
dpl_sync_all = dpls_all[0]
dpl_sync_all.smooth(30).scale(1500)
# plotting after adding them
import matplotlib.pyplot as plt
plt.ion()
fig, axes = plt.subplots(1, 1, sharex=True, figsize=(6, 6),constrained_layout=True)
axes.plot(dpl_cntrl.times,dpl_cntrl.data['agg'], label ='cntrl')
axes.plot(dpl_sync_d1.times,dpl_sync_d1.data['agg'], label ='d1_sync')
axes.plot(dpl_sync_p1_d1.times,dpl_sync_p1_d1.data['agg'], label ='p1_d1_sync')
axes.plot(dpl_sync_all.times, dpl_sync_all.data['agg'], label= 'all_sync')
plt.legend()
axes.legend()
axes.grid()
axes.set_xlabel("time (ms)")
axes.set_ylabel("nAm x scaling factor")
fig.savefig('/storage/work/mzk5905/Batch hnn_core/data/experimenting_kohl/all_manual_shuffle2_d1p1p2_cntrlunsync_d1sync_p1d1sync_allsync.png') |
The second script: adding p1,p2,d1 (while varying synchronization the same way as above):
|
@jasmainak @ntolley I have noticed also that syncrhonizing d1 affect p50 making it stronger, although d1 takes effect around 80 msec in time !!!. I tried narrowing the sigma but it still gave the same effect |
@mkhalil8 would you mind simplifying these scripts a bit? It's a little too much to look for the problem in this. Ideally a script that plots two dipoles comparing the original and permuted addition order. You can also use loops/functions or just show for one case. Scripts shorter than 30 lines is preferable but I can live with something less than 50 lines ;-) |
@jasmainak sorry Mainak for the long script. This is a shorter one of only two simulations. The only difference between both is the order of the drives (d1 is synchronized in both). it is 86 lines long (sorry the best I could do)
|
Thanks! Okay I confirm I can reproduce and it's very strange. Will investigate and get back |
sorry for the delay in responding here @mkhalil8 . I have been "vacation busy". So I figured out the issue. Let me give you a bit of historical context and we can decide what's the best solution moving forward. The spiking events of the external drives were made such that every cell ID has a separate seed for the events. For example, if you provided A simple solution that comes to mind is to sort |
another idea is to use |
@jasmainak I hope you had nice vacation and sorry for my delay in response also :) So for now, should keeping the order of the drives similar among different networks mitigate the problem? till we work on the solution? import os.path as op
from itertools import product
import numpy as np
from joblib import Parallel, delayed
import hnn_core
from hnn_core import simulate_dipole, jones_2009_model, average_dipoles
from hnn_core import read_params
from hnn_core.viz import plot_dipole
import json
from hnn_core import JoblibBackend
### network 1 unsync
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'L_Contra.param')
params = read_params(params_fname)
net_d = hnn_core.calcium_model(params,add_drives_from_params= False)
n_drive_cells = 1
cell_specific = False
location = 'proximal'
burst_std = 20
weights_ampa_p = {'L2_pyramidal': 0, 'L5_pyramidal': 0}
syn_delays_p = {'L2_pyramidal': 0.1, 'L5_pyramidal': 1.}
net_d.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_d.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_d.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_d.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_d.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
dpls_sync_d1 = simulate_dipole(net_d, tstop=250, n_trials= 1)
dpl_sync_d1= dpls_sync_d1[0]
dpl_sync_d1.smooth(30).scale(1500)
##################################################################
## network 2 d1 sync
net_s = hnn_core.calcium_model(params,add_drives_from_params= False)
net_s.add_bursty_drive('bursty1', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2, spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
net_s.add_bursty_drive('bursty2', tstart=50., burst_rate=10, burst_std=burst_std, numspikes=2,spike_isi=10, n_drive_cells=10, location=location,weights_ampa=weights_ampa_p, synaptic_delays=syn_delays_p, event_seed=-14)
# Proximal 1 drive
weights_ampa_p1 = {'L2_basket': 0.997291, 'L2_pyramidal':0.990722,'L5_basket':0.614932, 'L5_pyramidal': 0.004153}
weights_nmda_p1 = {'L2_basket': 0.984337, 'L2_pyramidal':1.714247,'L5_basket':0.061868, 'L5_pyramidal': 0.010042}
synaptic_delays_prox = {'L2_basket': 0.1, 'L2_pyramidal': 0.1,'L5_basket': 1., 'L5_pyramidal': 1.}
net_s.add_evoked_drive('evprox1', mu=54.897936, sigma=5.401034, numspikes=1, weights_ampa=weights_ampa_p1, weights_nmda=weights_nmda_p1, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
# Distal drive
weights_ampa_d1 = {'L2_basket': 0.624131, 'L2_pyramidal': 0.606619, 'L5_pyramidal':0.258}
weights_nmda_d1 = {'L2_basket': 0.95291, 'L2_pyramidal': 0.242383, 'L5_pyramidal': 0.156725}
synaptic_delays_d1 = {'L2_basket': 0.1, 'L2_pyramidal': 0.1, 'L5_pyramidal': 0.1}
net_s.add_evoked_drive('evdist1', mu=82.9915, sigma=13.208408, numspikes=1, weights_ampa=weights_ampa_d1,weights_nmda=weights_nmda_d1, location='distal',synaptic_delays=synaptic_delays_d1, event_seed=-14, n_drive_cells = n_drive_cells, cell_specific = cell_specific)
# Second proximal evoked drive.
weights_ampa_p2 = {'L2_basket': 0.758537, 'L2_pyramidal': 0.854454,'L5_basket': 0.979846, 'L5_pyramidal': 0.012483}
weights_nmda_p2 = {'L2_basket': 0.851444, 'L2_pyramidal':0.067491 ,'L5_basket': 0.901834, 'L5_pyramidal': 0.003818}
net_s.add_evoked_drive('evprox2', mu=161.306837, sigma=19.843986, numspikes=1, weights_ampa=weights_ampa_p2,weights_nmda= weights_nmda_p2, location='proximal',synaptic_delays=synaptic_delays_prox, event_seed=-14)
dpls_sync_d1_s = simulate_dipole(net_s, tstop=250, n_trials= 1)
dpl_sync_d1_s= dpls_sync_d1_s[0]
dpl_sync_d1_s.smooth(30).scale(1500)
import matplotlib.pyplot as plt
plt.ion()
fig, axes = plt.subplots(1, 1, sharex=True, figsize=(6, 6),constrained_layout=True)
axes.plot(dpl_sync_d1.times,dpl_sync_d1.data['agg'], label ='no_drives_synchronized')
axes.plot(dpl_sync_d1_s.times,dpl_sync_d1_s.data['agg'], label ='d1_only_sync')
plt.legend()
axes.legend()
axes.grid()
axes.set_xlabel("time (ms)")
axes.set_ylabel("nAm x scaling factor")
fig.savefig(".........") |
@mkhalil8 I think the best way to ensure your results are not an artifact of drive order is to run multiple trials of each simulation `simulate_dipole(..., n_trials=>1). This will change the random seed for the spike times and allow you to see what parts of the simulation are consistent. In this specific example, I think the reason you're seeing the P50 peak change is because its final amplitude is determined by the balance of proximal and distal drives. Excitatory distal inputs do indeed produce a more negative dipole (due to the direction of current flow in the apical dendrite). However, synchronizing distal drive means that this effect is exclusively observed at the time the single distal artificial cell fires. The end result is that that early proximal drive has nothing to oppose it at t=50, producing the larger peak. When the distal drives are not synchronized, then distal inputs occurring earlier will pull the P50 peak down (this is speculation, definitely confirm this by looking at the spike times/histograms for the drives). |
@ntolley. Thanks Nick, yes it makes sense.I will run multiple trials as you suggested and look at the spiking pattern. |
@ntolley @mkhalil8 would it make sense to document some "best practices" for running HNN simulations? I can see two points coming out of this discussion:
Could one of you take the initiative in adding this? |
@jasmainak yes sure Mainak I would like to do that. which part of the documentation will this be part of? I can make it under title of adding drives automatically vs manually for example, shall I make a draft and send to you for editing? |
@mkhalil8 try making a pull request following the contribution guidelines. Are you familiar with git workflow? Otherwise I'll update the contributing guideline with that information. I would add this information in all the evoked example. You can use the "..warning" directive in sphinx if you want to be more emphatic. |
@jasmainak yes sure I am familiar with git workflow, will start working on that. |
@jasmainak which branch shall I push the modified plot_simulate_evoked.rst file to? |
@mkhalil8 you should push to a branch on your fork (not main or master) and make a "pull request" from that branch |
@jasmainak what I did was making a branch called bestpractice then tried the following: |
Am I doing it the wrong way? |
what you call origin is typically called upstream. You should rename your current origin to be upstream and add a new origin: $ git remote rename origin upstream
$ git remote add origin https://github.com/mkhalil8/hnn-core/ |
Hi,
I am trying to use the same parameters to run a simulation with two different methods but not getting the same result.
The first method is where I add the drives from params:
The second method I add the drives manually (using same parameters from the param file:
I am not getting the same results from both, the dipole is different between both. I tracked the add_drives_from_params function and I found that it substract 18 from the event seed so I adjusted that. The rest appears to be the same, not sure where the problem
The text was updated successfully, but these errors were encountered: